From b54c578e17e9bcbd74aa30ea75e25e955b9a6205 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 5 Feb 2020 02:31:44 +0000 Subject: [PATCH] Security-59306.11.20.tar.gz --- .gitignore | 7 + .swiftlint.yml | 33 + Analytics/Clients/LocalKeychainAnalytics.h | 13 + Analytics/Clients/LocalKeychainAnalytics.m | 78 +- Analytics/NSDate+SFAnalytics.h | 38 + Analytics/NSDate+SFAnalytics.m | 49 + Analytics/SFAnalytics.h | 95 +- Analytics/SFAnalytics.m | 232 +- Analytics/SFAnalytics.plist | 20 + Analytics/SFAnalyticsActivityTracker.h | 9 + Analytics/SFAnalyticsActivityTracker.m | 15 +- Analytics/SFAnalyticsDefines.h | 10 +- Analytics/SFAnalyticsMultiSampler.h | 1 + Analytics/SFAnalyticsMultiSampler.m | 1 + Analytics/SFAnalyticsSQLiteStore.h | 4 +- Analytics/SFAnalyticsSQLiteStore.m | 43 +- Analytics/SFAnalyticsSampler.h | 1 + Analytics/SFAnalyticsSampler.m | 2 + Analytics/SQLite/SFObjCType.h | 4 + Analytics/SQLite/SFSQLite.h | 6 +- Analytics/SQLite/SFSQLite.m | 21 +- Analytics/SQLite/SFSQLiteStatement.h | 6 +- Analytics/SQLite/SFSQLiteStatement.m | 2 +- {libsecurity_smime/lib => CMS}/CMSDecoder.h | 134 +- {libsecurity_smime/lib => CMS}/CMSEncoder.h | 188 +- {OSX/libsecurity_cms/lib => CMS}/CMSPrivate.h | 21 +- {OSX/sec/Security => CMS}/SecCMS.h | 18 +- .../lib => CMS}/SecCmsBase.h | 93 +- CMS/SecCmsContentInfo.h | 337 + .../lib => CMS}/SecCmsDecoder.h | 85 +- .../lib => CMS}/SecCmsDigestContext.h | 37 +- .../lib => CMS}/SecCmsDigestedData.h | 20 +- .../lib => CMS}/SecCmsEncoder.h | 73 +- .../lib => CMS}/SecCmsEncryptedData.h | 14 +- .../lib => CMS}/SecCmsEnvelopedData.h | 22 +- .../lib => CMS}/SecCmsMessage.h | 58 +- .../lib => CMS}/SecCmsRecipientInfo.h | 63 +- .../lib => CMS}/SecCmsSignedData.h | 49 +- .../lib => CMS}/SecCmsSignerInfo.h | 207 +- {OSX/libsecurity_smime/lib => CMS}/SecSMIME.h | 12 +- CircleJoinRequested/Applicant.h | 2 +- CircleJoinRequested/CircleJoinRequested.m | 145 +- CircleJoinRequested/PersistentState.h | 4 +- KVSKeychainSyncingProxy/CKDKVSProxy.h | 4 - KVSKeychainSyncingProxy/CKDKVSProxy.m | 32 +- KVSKeychainSyncingProxy/cloudkeychainproxy.m | 9 +- KeychainCircle/KCAESGCMDuplexSession.h | 16 +- KeychainCircle/KCAESGCMDuplexSession.m | 32 +- .../KCInitialMessageData.proto | 13 +- .../KCJoiningAcceptSession+Internal.h | 38 + KeychainCircle/KCJoiningAcceptSession.m | 284 +- KeychainCircle/KCJoiningMessages.h | 11 +- KeychainCircle/KCJoiningMessages.m | 121 +- .../KCJoiningRequestCircleSession.m | 332 + ...sion.m => KCJoiningRequestSecretSession.m} | 259 +- .../KCJoiningRequestSession+Internal.h | 44 + KeychainCircle/KCJoiningSession.h | 14 +- KeychainCircle/PairingChannel.h | 29 +- KeychainCircle/PairingChannel.m | 647 +- KeychainCircle/Tests/FakeSOSControl.h | 43 + KeychainCircle/Tests/FakeSOSControl.m | 331 + KeychainCircle/Tests/KCJoiningSessionTest.m | 4 +- KeychainCircle/Tests/KCPairingTest.m | 431 +- .../generated_source/KCInitialMessageData.h | 35 + .../generated_source/KCInitialMessageData.m | 124 + .../Base.lproj/Main.storyboard | 693 - KeychainEntitledTestApp_mac/Info.plist | 2 - ...KeychainSyncAccountNotification-Info.plist | 1 + .../KeychainSyncAccountNotification.m | 110 +- Modules/Security.macOS.private.modulemap | 4 + .../ClientInfoByNotification.m | 295 - .../DeviceSimulator-Entitlements.plist | 64 - .../DeviceSimulator/DeviceSimulator.h | 17 - .../DeviceSimulator/DeviceSimulatorMain.m | 489 - .../DeviceSimulator/DeviceSimulatorProtocol.h | 44 - .../MultiDeviceNetworking.h | 24 - .../MultiDeviceNetworking.m | 295 - .../MultiDeviceNetworkingProtocol.h | 26 - .../MultiDeviceSimulatorTests.m | 547 - OCMockUmbrella/Info.plist | 22 + OCMockUmbrella/OCMockUmbrella.h | 8 + .../KNAppDelegate.m | 523 +- .../SecurityTests-Entitlements.plist | 2 + OSX/SecurityTestsOSX/testlist.h | 1 - OSX/authd/agent.c | 3 +- OSX/authd/authd-Entitlements.plist | 2 - OSX/authd/authdb.c | 6 +- OSX/authd/authorization.plist | 157 +- OSX/authd/authtoken.c | 50 +- OSX/authd/authtoken.h | 3 - OSX/authd/ccaudit.c | 5 - OSX/authd/com.apple.authd.sb | 12 +- OSX/authd/engine.c | 80 +- OSX/authd/process.c | 39 +- OSX/authd/process.h | 5 +- OSX/authd/server.c | 13 + OSX/authd/tests/authdtestlist.h | 1 + OSX/authd/tests/authdtests.m | 145 +- OSX/config/lib.xcconfig | 7 +- OSX/config/security_framework_macos.xcconfig | 11 +- OSX/config/security_macos.xcconfig | 4 +- OSX/lib/Security.order | 1 - .../en.lproj/authorization.buttons.strings | 1 + ...ings => authorization.dfr.prompts.strings} | 2 + .../en.lproj/authorization.prompts.strings | 6 + OSX/lib/framework.sb | 4 +- OSX/lib/generateErrStrings.pl | 4 +- OSX/libsecurity_apple_csp/lib/AppleCSP.cpp | 28 - OSX/libsecurity_apple_csp/lib/AppleCSP.h | 4 - .../lib/AppleCSPSession.h | 6 - .../lib/BlockCryptor.cpp | 4 +- .../lib/YarrowConnection.cpp | 18 +- OSX/libsecurity_apple_csp/lib/algmaker.cpp | 333 - .../lib/bsafeAsymmetric.cpp | 87 - .../lib/bsafeContext.cpp | 448 - OSX/libsecurity_apple_csp/lib/bsafeKeyGen.cpp | 461 - OSX/libsecurity_apple_csp/lib/bsafePKCS1.cpp | 137 - OSX/libsecurity_apple_csp/lib/bsafePKCS1.h | 73 - .../lib/bsafeSymmetric.cpp | 289 - OSX/libsecurity_apple_csp/lib/bsafecsp.h | 58 - OSX/libsecurity_apple_csp/lib/bsafecspi.h | 463 - OSX/libsecurity_apple_csp/lib/bsobjects.h | 64 - OSX/libsecurity_apple_csp/lib/desContext.cpp | 2 + OSX/libsecurity_apple_csp/lib/memory.cpp | 53 - .../lib/miscAlgFactory.cpp | 18 - .../lib/miscalgorithms.cpp | 152 - OSX/libsecurity_apple_csp/lib/opensshWrap.cpp | 5 +- .../lib/DecodedExtensions.h | 1 + .../lib/DecodedItem.cpp | 2 +- .../lib/TPCertInfo.cpp | 2 +- .../lib/TPDatabase.cpp | 2 +- .../lib/TPNetwork.cpp | 2 +- .../lib/ocspRequest.cpp | 6 +- .../lib/tpCredRequest.cpp | 4 +- OSX/libsecurity_apple_x509_tp/lib/tpTime.c | 56 +- OSX/libsecurity_apple_x509_tp/lib/tpTime.h | 22 +- OSX/libsecurity_asn1/lib/SecAsn1Types.h | 15 +- OSX/libsecurity_asn1/lib/SecNssCoder.cpp | 2 +- OSX/libsecurity_asn1/lib/asn1Templates.h | 2 + OSX/libsecurity_asn1/lib/csrTemplates.h | 12 +- OSX/libsecurity_asn1/lib/keyTemplates.h | 12 +- OSX/libsecurity_asn1/lib/secasn1e.c | 1951 +- .../lib/Authorization.c | 58 +- .../lib/AuthorizationPlugin.h | 17 +- .../lib/AuthorizationPriv.h | 58 + .../lib/AuthorizationTags.h | 7 + .../lib/AuthorizationTagsPriv.h | 3 + .../lib/AuthorizationTrampolinePriv.h | 59 + .../lib/trampolineClient.cpp | 591 +- .../lib/trampolineServer.cpp | 2 + .../lib/cssmaclpod.cpp | 9 +- .../lib/cssmalloc.cpp | 9 +- .../lib/uniformrandom.h | 56 - OSX/libsecurity_cdsa_utils/lib/cuTimeStr.cpp | 72 +- OSX/libsecurity_cdsa_utils/lib/cuTimeStr.h | 52 +- OSX/libsecurity_cms/lib/CMSDecoder.cpp | 10 +- OSX/libsecurity_cms/lib/CMSDecoder.h | 382 - OSX/libsecurity_cms/lib/CMSEncoder.cpp | 8 +- OSX/libsecurity_cms/lib/CMSEncoder.h | 428 - .../libsecurity_cms.xcodeproj/project.pbxproj | 406 - .../regressions/cms-trust-settings-test.c | 2 + .../regressions/cms-trust-settings-test.h | 2 - .../regressions/cms_regressions.h | 2 + .../CodeSigningHelper.entitlements | 10 + OSX/libsecurity_codesigning/lib/Code.cpp | 6 +- .../lib/RequirementKeywords.h | 1 + .../lib/RequirementLexer.cpp | 35 +- .../lib/RequirementParser.cpp | 44 +- .../lib/RequirementParser.hpp | 4 +- .../lib/RequirementParserTokenTypes.hpp | 77 +- .../lib/RequirementParserTokenTypes.txt | 77 +- .../lib/SecAssessment.cpp | 50 +- .../lib/SecAssessment.h | 2 + OSX/libsecurity_codesigning/lib/SecCode.cpp | 1 + OSX/libsecurity_codesigning/lib/SecCode.h | 4 +- .../lib/SecCodeHost.cpp | 46 +- OSX/libsecurity_codesigning/lib/SecCodeHost.h | 205 +- .../lib/SecCodeHostLib.c | 124 - .../lib/SecCodeHostLib.h | 110 - OSX/libsecurity_codesigning/lib/SecCodePriv.h | 14 +- .../lib/SecRequirement.cpp | 12 +- .../lib/SecRequirementPriv.h | 3 + .../lib/SecStaticCode.cpp | 1 + .../lib/StaticCode.cpp | 28 +- .../lib/bundlediskrep.cpp | 11 +- .../lib/bundlediskrep.h | 1 + OSX/libsecurity_codesigning/lib/csgeneric.cpp | 217 - OSX/libsecurity_codesigning/lib/csgeneric.h | 82 - OSX/libsecurity_codesigning/lib/csprocess.cpp | 8 +- OSX/libsecurity_codesigning/lib/csprocess.h | 9 +- OSX/libsecurity_codesigning/lib/diskrep.h | 2 + .../lib/evaluationmanager.cpp | 30 +- .../lib/legacydevid.cpp | 173 + OSX/libsecurity_codesigning/lib/legacydevid.h | 37 + .../lib/notarization.cpp | 2 +- OSX/libsecurity_codesigning/lib/policydb.cpp | 62 +- .../lib/policyengine.cpp | 63 +- OSX/libsecurity_codesigning/lib/reqdumper.cpp | 3 + OSX/libsecurity_codesigning/lib/reqinterp.cpp | 5 + OSX/libsecurity_codesigning/lib/requirement.h | 11 +- OSX/libsecurity_codesigning/lib/resources.cpp | 11 +- OSX/libsecurity_codesigning/lib/signer.cpp | 2 +- OSX/libsecurity_codesigning/lib/xar++.cpp | 4 +- OSX/libsecurity_codesigning/lib/xpcengine.cpp | 84 +- OSX/libsecurity_codesigning/lib/xpcengine.h | 1 + .../requirements.grammar | 2 + OSX/libsecurity_cryptkit/ckutils/Makefile | 21 - .../ckutils/Makefile.common | 88 - .../ckutils/atomTime/Makefile | 53 - .../ckutils/atomTime/atomTime.c | 662 - .../ckutils/badsig/Makefile | 51 - .../ckutils/badsig/badsig.c | 475 - .../ckutils/blobtest/Makefile | 51 - .../ckutils/blobtest/blobtest.c | 358 - .../ckutils/cfileTest/Makefile | 51 - .../ckutils/cfileTest/cfileTest.c | 589 - .../ckutils/ckutilsPlatform.h | 106 - .../ckutils/giantAsmBench/Makefile | 51 - .../ckutils/giantAsmBench/giantAsmBench.c | 229 - .../ckutils/giantBench/Makefile | 51 - .../ckutils/giantBench/giantBench.c | 273 - .../ckutils/giantDvt/Makefile | 51 - .../ckutils/giantDvt/giantDvt.c | 549 - .../ckutils/sigTime/Makefile | 55 - .../ckutils/sigTime/sigTime.cpp | 269 - OSX/libsecurity_cryptkit/lib/CipherFileDES.c | 586 - OSX/libsecurity_cryptkit/lib/CipherFileDES.h | 67 - OSX/libsecurity_cryptkit/lib/CipherFileFEED.c | 460 - OSX/libsecurity_cryptkit/lib/CipherFileFEED.h | 69 - .../lib/CipherFileTypes.h | 83 - OSX/libsecurity_cryptkit/lib/Crypt.h | 21 - OSX/libsecurity_cryptkit/lib/CryptKitAsn1.h | 3 - OSX/libsecurity_cryptkit/lib/CryptKitDER.cpp | 3 +- OSX/libsecurity_cryptkit/lib/CryptKitDER.h | 3 - OSX/libsecurity_cryptkit/lib/ECDSA_Profile.h | 3 - .../lib/ECDSA_Verify_Prefix.h | 6 - OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.c | 3 - OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.h | 4 - OSX/libsecurity_cryptkit/lib/ckDES.c | 545 - OSX/libsecurity_cryptkit/lib/ckDES.h | 70 - OSX/libsecurity_cryptkit/lib/ckMD5.c | 365 - OSX/libsecurity_cryptkit/lib/ckMD5.h | 43 - OSX/libsecurity_cryptkit/lib/ckSHA1.c | 148 - OSX/libsecurity_cryptkit/lib/ckSHA1_priv.c | 321 - OSX/libsecurity_cryptkit/lib/ckSHA1_priv.h | 60 - OSX/libsecurity_cryptkit/lib/ckconfig.h | 73 +- OSX/libsecurity_cryptkit/lib/ckutilities.c | 41 - .../lib/curveParamDataOld.h | 350 - OSX/libsecurity_cryptkit/lib/curveParams.c | 372 +- OSX/libsecurity_cryptkit/lib/elliptic.c | 5 +- OSX/libsecurity_cryptkit/lib/ellipticProj.c | 3 - OSX/libsecurity_cryptkit/lib/ellipticProj.h | 3 - OSX/libsecurity_cryptkit/lib/engineNSA127.c | 542 - OSX/libsecurity_cryptkit/lib/feeCipherFile.c | 280 - OSX/libsecurity_cryptkit/lib/feeCipherFile.h | 164 - .../lib/feeCipherFileAtom.c | 400 - OSX/libsecurity_cryptkit/lib/feeDES.c | 529 - OSX/libsecurity_cryptkit/lib/feeDES.h | 141 - .../lib/feeDigitalSignature.c | 81 +- OSX/libsecurity_cryptkit/lib/feeECDSA.c | 47 +- OSX/libsecurity_cryptkit/lib/feeECDSA.h | 4 - OSX/libsecurity_cryptkit/lib/feeFEED.c | 3 - OSX/libsecurity_cryptkit/lib/feeFEED.h | 4 - OSX/libsecurity_cryptkit/lib/feeFEEDExp.c | 3 - OSX/libsecurity_cryptkit/lib/feeFEEDExp.h | 4 - OSX/libsecurity_cryptkit/lib/feeFunctions.h | 16 - OSX/libsecurity_cryptkit/lib/feeHash.c | 3 - OSX/libsecurity_cryptkit/lib/feeHash.h | 4 - OSX/libsecurity_cryptkit/lib/feePublicKey.c | 261 +- OSX/libsecurity_cryptkit/lib/feePublicKey.h | 67 - OSX/libsecurity_cryptkit/lib/feeRandom.c | 1 + OSX/libsecurity_cryptkit/lib/feeTypes.h | 42 - OSX/libsecurity_cryptkit/lib/giantIntegers.c | 256 - OSX/libsecurity_cryptkit/lib/giantIntegers.h | 27 - .../lib/giantPortCommon.h | 9 - OSX/libsecurity_cryptkit/lib/giantPort_PPC.c | 236 - OSX/libsecurity_cryptkit/lib/giantPort_PPC.h | 119 - .../lib/giantPort_PPC_Gnu.h | 83 - .../lib/giantPort_PPC_Gnu.s | 300 - OSX/libsecurity_cryptkit/lib/giantPort_i486.h | 126 - OSX/libsecurity_cryptkit/lib/platform.c | 39 +- OSX/libsecurity_cssm/lib/cssmapplePriv.h | 4 +- OSX/libsecurity_cssm/lib/cssmtype.h | 10 +- OSX/libsecurity_cssm/lib/x509defs.h | 13 +- OSX/libsecurity_filedb/lib/AtomicFile.cpp | 5 +- OSX/libsecurity_keychain/lib/ACL.cpp | 9 +- OSX/libsecurity_keychain/lib/Access.cpp | 10 +- OSX/libsecurity_keychain/lib/Certificate.cpp | 2 +- .../lib/CertificateValues.cpp | 5 +- OSX/libsecurity_keychain/lib/Identity.cpp | 2 +- .../lib/IdentityCursor.cpp | 2 +- OSX/libsecurity_keychain/lib/Item.cpp | 33 +- OSX/libsecurity_keychain/lib/KCCursor.cpp | 2 +- OSX/libsecurity_keychain/lib/KCExceptions.h | 2 +- OSX/libsecurity_keychain/lib/KCUtilities.h | 2 +- OSX/libsecurity_keychain/lib/KeyItem.cpp | 6 +- OSX/libsecurity_keychain/lib/KeyItem.h | 11 +- OSX/libsecurity_keychain/lib/SecACL.h | 10 +- OSX/libsecurity_keychain/lib/SecAccess.cpp | 4 +- OSX/libsecurity_keychain/lib/SecAccess.h | 32 +- OSX/libsecurity_keychain/lib/SecAccessPriv.h | 16 +- OSX/libsecurity_keychain/lib/SecBase.cpp | 4 +- OSX/libsecurity_keychain/lib/SecBridge.h | 2 +- .../lib/SecCertificate.cpp | 6 +- .../lib/SecFDERecoveryAsymmetricCrypto.cpp | 8 +- .../lib/SecImportExport.c | 9 +- .../lib/SecImportExportCrypto.cpp | 8 +- .../lib/SecImportExportPkcs8.cpp | 7 +- .../lib/SecImportExportUtils.cpp | 4 +- OSX/libsecurity_keychain/lib/SecItem.cpp | 138 +- OSX/libsecurity_keychain/lib/SecKey.cpp | 93 +- OSX/libsecurity_keychain/lib/SecKeychain.cpp | 11 +- OSX/libsecurity_keychain/lib/SecKeychain.h | 115 +- .../lib/SecKeychainItem.cpp | 4 +- .../lib/SecKeychainItem.h | 38 +- .../lib/SecKeychainItemExtendedAttributes.h | 74 +- .../lib/SecKeychainItemPriv.h | 44 +- .../lib/SecKeychainPriv.h | 16 +- .../lib/SecKeychainSearch.h | 6 +- .../lib/SecKeychainSearchPriv.h | 2 +- .../lib/SecNetscapeTemplates.h | 1 + OSX/libsecurity_keychain/lib/SecPassword.h | 24 +- OSX/libsecurity_keychain/lib/SecRandomP.h | 5 +- OSX/libsecurity_keychain/lib/SecTrust.cpp | 115 +- .../lib/SecTrustOSXEntryPoints.cpp | 199 +- .../lib/SecTrustSettings.cpp | 7 +- .../lib/SecTrustedApplication.h | 18 +- .../lib/SecTrustedApplicationPriv.h | 32 +- .../lib/SecWrappedKeys.cpp | 6 +- .../lib/StorageManager.cpp | 6 +- OSX/libsecurity_keychain/lib/TokenLogin.cpp | 16 +- .../lib/TrustAdditions.cpp | 6 +- .../lib/TrustSettings.cpp | 7 +- OSX/libsecurity_keychain/lib/TrustSettings.h | 4 +- OSX/libsecurity_keychain/lib/cssmdatetime.cpp | 2 +- OSX/libsecurity_keychain/lib/defaultcreds.h | 2 +- .../regressions/kc-20-item-delete-stress.c | 2 +- .../regressions/kc-41-sececkey.m | 16 +- .../regressions/kc-42-trust-revocation.c | 436 +- .../regressions/kc-43-seckey-interop.m | 50 +- .../regressions/kc-45-change-password.c | 6 +- .../regressions/si-34-one-true-keychain.c | 2 +- OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.cpp | 4 +- OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.h | 4 +- OSX/libsecurity_pkcs12/lib/pkcs12Utils.cpp | 7 +- ...rity_smime.plist => libsecurity_cms.plist} | 0 ...security_smime.txt => libsecurity_cms.txt} | 0 OSX/libsecurity_smime/lib/SecCMS.c | 6 +- OSX/libsecurity_smime/lib/SecCMS.h | 172 - OSX/libsecurity_smime/lib/SecCmsContentInfo.h | 212 - OSX/libsecurity_smime/lib/SecCmsDecoder.h | 143 - .../lib/SecCmsDigestContext.h | 78 - OSX/libsecurity_smime/lib/SecCmsEncoder.h | 129 - .../lib/SecCmsEncryptedData.h | 76 - .../lib/SecCmsRecipientInfo.h | 81 - OSX/libsecurity_smime/lib/SecCmsSignedData.h | 197 - OSX/libsecurity_smime/lib/cert.c | 62 +- OSX/libsecurity_smime/lib/cert.h | 12 +- OSX/libsecurity_smime/lib/cmsattr.c | 2 + OSX/libsecurity_smime/lib/cmscinfo.c | 6 +- OSX/libsecurity_smime/lib/cmscipher.c | 10 +- OSX/libsecurity_smime/lib/cmsdecode.c | 192 +- OSX/libsecurity_smime/lib/cmspubkey.c | 12 +- OSX/libsecurity_smime/lib/cmsrecinfo.c | 2 +- OSX/libsecurity_smime/lib/cmsreclist.c | 44 +- OSX/libsecurity_smime/lib/cmssigdata.c | 4 +- OSX/libsecurity_smime/lib/cmssiginfo.c | 38 +- OSX/libsecurity_smime/lib/secitem.c | 1 + OSX/libsecurity_smime/lib/tsaSupport.c | 8 +- OSX/libsecurity_smime/lib/tsaSupport.h | 2 +- OSX/libsecurity_smime/lib/tsaTemplates.c | 13 +- .../project.pbxproj | 714 - .../regressions/cms-01-basic.c | 2 +- .../regressions/smime-cms-test.c | 8 +- OSX/libsecurity_ssl/lib/CipherSuite.h | 27 +- OSX/libsecurity_ssl/lib/SecureTransport.h | 1513 +- OSX/libsecurity_ssl/lib/SecureTransportPriv.h | 43 + OSX/libsecurity_ssl/lib/sslCipherSpecs.c | 258 +- OSX/libsecurity_ssl/lib/sslContext.c | 30 +- OSX/libsecurity_ssl/lib/sslContext.h | 6 - OSX/libsecurity_ssl/lib/sslCrypto.c | 49 +- OSX/libsecurity_ssl/lib/sslCrypto.h | 13 - OSX/libsecurity_ssl/lib/sslKeychain.c | 4 +- OSX/libsecurity_ssl/lib/sslMemory.c | 65 - OSX/libsecurity_ssl/lib/sslMemory.h | 5 - OSX/libsecurity_ssl/lib/sslTransport.c | 2 +- .../STLegacyTests+ciphers.m | 172 +- .../STLegacyTests+clientauth.m | 70 +- .../STLegacyTests+clientauth41.m | 5 + .../STLegacyTests+crashes.m | 28 +- .../SecureTransportTests/STLegacyTests+dhe.m | 106 +- .../STLegacyTests+falsestart.m | 101 +- .../STLegacyTests+noconn.m | 5 +- .../STLegacyTests+renegotiate.m | 5 + .../STLegacyTests+session.m | 235 + .../STLegacyTests+sessioncache.m | 41 +- .../STLegacyTests+sessionstate.m | 80 +- .../SecureTransportTests/STLegacyTests+sni.m | 77 +- .../STLegacyTests+split.m | 26 +- .../STLegacyTests+sslciphers.m | 46 +- .../STLegacyTests+tls12.m | 61 +- .../regressions/ssl-42-ciphers.c | 1 + .../regressions/ssl-43-ciphers.c | 1 + .../regressions/ssl-44-crashes.c | 1 + .../regressions/ssl-48-split.c | 1 + OSX/libsecurity_ssl/regressions/ssl-49-sni.c | 1 + .../regressions/ssl-53-clientauth.c | 1 + OSX/libsecurity_ssl/regressions/ssl-54-dhe.c | 1 + .../regressions/ssl-55-sessioncache.c | 1 + .../regressions/ssl-56-renegotiate.c | 1 + OSX/libsecurity_ssl/regressions/ssl-utils.c | 9 +- OSX/libsecurity_ssl/regressions/ssl-utils.h | 3 - .../regressions/ssl_regressions.h | 4 +- OSX/libsecurity_transform/100-sha2.m | 352 - OSX/libsecurity_transform/custom.mm | 5118 --- OSX/libsecurity_utilities/lib/alloc.cpp | 6 +- OSX/libsecurity_utilities/lib/cfmunge.cpp | 14 +- OSX/libsecurity_utilities/lib/cfutilities.cpp | 4 +- OSX/libsecurity_utilities/lib/devrandom.cpp | 74 - OSX/libsecurity_utilities/lib/devrandom.h | 64 - OSX/libsecurity_utilities/lib/mach_notify.c | 552 - .../lib/mach_notify.defs | 101 + OSX/libsecurity_utilities/lib/mach_notify.h | 141 - .../lib/machrunloopserver.cpp | 111 - .../lib/machrunloopserver.h | 80 - OSX/libsecurity_utilities/lib/machserver.cpp | 22 +- OSX/libsecurity_utilities/lib/powerwatch.cpp | 93 +- OSX/libsecurity_utilities/lib/powerwatch.h | 18 +- OSX/libsecurity_utilities/lib/seccfobject.h | 4 +- .../lib/security_utilities.h | 3 - OSX/libsecurity_utilities/lib/streams.cpp | 144 - OSX/libsecurity_utilities/lib/streams.h | 192 - OSX/libsecurity_utilities/lib/vproc++.cpp | 62 - OSX/libsecurity_utilities/lib/vproc++.h | 63 - OSX/libsecurityd/lib/ssclient.cpp | 9 +- OSX/libsecurityd/lib/ssclient.h | 23 +- OSX/libsecurityd/lib/transition.cpp | 72 +- OSX/libsecurityd/mig/cshosting.defs | 56 - OSX/libsecurityd/mig/ucsp.defs | 33 +- OSX/macos_tapi_hacks.h | 10 +- OSX/regressions/test/testenv.m | 2 +- OSX/sec/ProjectHeaders/SOSCircle/Tool | 1 - OSX/sec/ProjectHeaders/Security/CKBridge | 1 - .../ProjectHeaders/Security/SecureObjectSync | 1 - OSX/sec/ProjectHeaders/Security/Tool | 1 - OSX/sec/ProjectHeaders/SecurityTool | 1 - .../SOSCircle/Regressions/sc-25-soskeygen.c | 110 - .../SecureObjectSync/SOSAccountGhost.h | 18 - .../SecureObjectSync/SOSAccountGhost.m | 149 - .../SecureObjectSync/SOSAccountLog.h | 29 - .../SecureObjectSync/SOSAuthKitHelpers.h | 25 - .../SecureObjectSync/SOSSysdiagnose.m | 199 - OSX/sec/SOSCircle/Tool/keychain_log.m | 267 - .../Regressions/Security_regressions.h | 2 +- .../Regressions/crypto/padding-00-mmcs.c | 6 +- .../Security/Regressions/otr/otr-packetdata.c | 2 +- .../Security/Regressions/rk_01_recoverykey.m | 6 +- .../Regressions/secitem/si-15-certificate.c | 1265 - .../secitem/si-16-ec-certificate.c | 1193 - .../secitem/si-18-certificate-parse.m | 191 - .../Regressions/secitem/si-20-sectrust.c | 987 - .../Regressions/secitem/si-20-sectrust.h | 2141 -- .../Regressions/secitem/si-22-sectrust-iap.c | 60 +- .../Regressions/secitem/si-22-sectrust-iap.h | 128 +- .../Regressions/secitem/si-23-sectrust-ocsp.c | 144 +- .../Regressions/secitem/si-23-sectrust-ocsp.h | 380 +- .../Regressions/secitem/si-24-sectrust-nist.c | 29 - .../secitem/si-27-sectrust-exceptions.c | 35 +- .../secitem/si-29-cms-chain-mode.h | 213 + .../secitem/si-29-cms-chain-mode.m | 294 + .../secitem/si-29-sectrust-sha1-deprecation.h | 430 - .../secitem/si-29-sectrust-sha1-deprecation.m | 185 - .../secitem/si-33-keychain-backup.c | 29 +- .../Regressions/secitem/si-34-cms-timestamp.m | 8 +- .../secitem/si-35-cms-expiration-time.m | 4 +- .../Security/Regressions/secitem/si-60-cms.c | 20 +- .../Security/Regressions/secitem/si-63-scep.m | 2 +- .../Regressions/secitem/si-64-ossl-cms.c | 1 + .../secitem/si-70-sectrust-unified.c | 25 +- .../secitem/si-85-sectrust-ssl-policy.c | 163 - .../secitem/si-85-sectrust-ssl-policy.h | 89 - .../secitem/si-87-sectrust-name-constraints.m | 383 - .../secitem/si-89-cms-hash-agility.m | 1 + .../Regressions/secitem/si-95-cms-basic.c | 2 +- .../secitem/si_77_SecAccessControl.c | 14 +- OSX/sec/Security/SecAccessControl.m | 22 +- .../Security/SecAccessControlExports.exp-in | 1 + OSX/sec/Security/SecAccessControlPriv.h | 3 + OSX/sec/Security/SecBackupKeybagEntry.m | 17 +- OSX/sec/Security/SecCMS.c | 4 +- OSX/sec/Security/SecCTKKey.m | 63 +- OSX/sec/Security/SecCertificate.c | 456 +- OSX/sec/Security/SecCertificateInternal.h | 73 +- OSX/sec/Security/SecCertificateRequest.c | 4 +- OSX/sec/Security/SecDH.c | 16 +- OSX/sec/Security/SecDigest.c | 16 +- OSX/sec/Security/SecECKey.m | 69 +- OSX/sec/Security/SecExports.exp-in | 267 +- OSX/sec/Security/SecFramework.c | 17 - OSX/sec/Security/SecFramework.h | 23 +- OSX/sec/Security/SecFrameworkStrings.h | 19 +- OSX/sec/Security/SecIdentity.c | 2 +- OSX/sec/Security/SecImportExport.c | 8 +- OSX/sec/Security/SecItem.c | 53 +- OSX/sec/Security/SecItem.m | 32 + OSX/sec/Security/SecItemBackup.c | 2 +- OSX/sec/Security/SecItemConstants.c | 6 +- OSX/sec/Security/SecItemInternal.h | 2 +- OSX/sec/Security/SecItemShim.h | 7 + OSX/sec/Security/{SecKey.c => SecKey.m} | 406 +- OSX/sec/Security/SecKeyAdaptors.m | 149 +- OSX/sec/Security/SecKeyInternal.h | 5 + OSX/sec/Security/SecOTRSession.c | 6 +- OSX/sec/Security/SecOnOSX.h | 2 +- OSX/sec/Security/SecPolicy.c | 225 +- OSX/sec/Security/SecPolicy.list | 146 +- OSX/sec/Security/SecPolicyChecks.list | 26 +- OSX/sec/Security/SecPolicyLeafCallbacks.c | 55 +- OSX/sec/Security/SecRSAKey.c | 38 +- OSX/sec/Security/SecRecoveryKey.h | 1 - OSX/sec/Security/SecRecoveryKey.m | 11 +- OSX/sec/Security/SecSCEP.c | 2 + OSX/sec/Security/SecServerEncryptionSupport.c | 4 +- OSX/sec/Security/SecSharedCredential.c | 12 +- .../SecSignatureVerificationSupport.c | 8 +- .../SecSignatureVerificationSupport.h | 4 +- OSX/sec/Security/SecTrust.c | 379 +- OSX/sec/Security/SecTrustInternal.h | 2 +- OSX/sec/Security/SecTrustStatusCodes.c | 81 +- OSX/sec/Security/SecTrustStore.c | 63 +- OSX/sec/Security/SecuritydXPC.c | 12 +- OSX/sec/Security/ios_tapi_hacks.h | 4 + OSX/sec/Security/oids.c | 448 - OSX/sec/Security/p12import.c | 2 +- OSX/sec/SharedWebCredential/swcagent.m | 6 +- OSX/sec/ipc/SecdWatchdog.h | 8 + OSX/sec/ipc/SecdWatchdog.m | 136 +- OSX/sec/ipc/client.c | 143 +- .../ipc/com.apple.recovery_securityd.plist | 31 + OSX/sec/ipc/com.apple.secd.plist | 2 +- OSX/sec/ipc/com.apple.secitemd.plist | 33 + OSX/sec/ipc/com.apple.securityd.plist | 14 +- OSX/sec/ipc/securityd_client.h | 114 +- OSX/sec/ipc/server.c | 556 +- OSX/sec/ipc/server_endpoint.m | 18 +- OSX/sec/ipc/server_entitlement_helpers.c | 21 +- OSX/sec/ipc/server_entitlement_helpers.h | 2 +- OSX/sec/ipc/server_security_helpers.c | 120 - OSX/sec/ipc/server_security_helpers.h | 4 +- OSX/sec/ipc/server_security_helpers.m | 147 + OSX/sec/ipc/server_xpc.m | 55 +- protocol/SecProtocol.h => OSX/sec/ipc/util.h | 18 +- .../custom.h => sec/ipc/util.m} | 19 +- OSX/sec/os_log/com.apple.securityd.plist | 22 +- OSX/sec/securityd/AsymKeybagBackup.m | 147 - OSX/sec/securityd/CheckV12DevEnabled.h | 14 + OSX/sec/securityd/CheckV12DevEnabled.m | 33 + OSX/sec/securityd/OTATrustUtilities.h | 40 +- OSX/sec/securityd/OTATrustUtilities.m | 756 +- OSX/sec/securityd/PolicyReporter.h | 33 + OSX/sec/securityd/PolicyReporter.m | 339 + .../securityd/Regressions/SOSAccountTesting.h | 24 +- .../Regressions/SOSTransportTestTransports.h | 4 +- .../Regressions/SOSTransportTestTransports.m | 22 +- .../Regressions/SecdTestKeychainUtilities.c | 22 +- .../Regressions/SecdTestKeychainUtilities.h | 1 + OSX/sec/securityd/Regressions/secd-01-items.m | 26 +- .../secd-02-upgrade-while-locked.m | 17 +- .../Regressions/secd-100-initialsync.m | 64 +- .../Regressions/secd-130-other-peer-views.m | 12 +- .../secd-155-otr-negotiation-monitor.m | 21 +- .../Regressions/secd-20-keychain_upgrade.m | 15 +- .../securityd/Regressions/secd-200-logstate.m | 13 +- .../securityd/Regressions/secd-201-coders.m | 14 +- .../Regressions/secd-21-transmogrify.m | 7 +- .../Regressions/secd-230-keybagtable.m | 10 +- .../Regressions/secd-31-keychain-bad.m | 118 - .../Regressions/secd-33-keychain-backup.m | 636 + .../Regressions/secd-33-keychain-ctk.m | 168 +- .../Regressions/secd-34-backup-der-parse.m | 3 +- .../secd-35-keychain-migrate-inet.m | 17 +- .../Regressions/secd-36-ks-encrypt.m | 8 +- .../secd-37-pairing-initial-sync.m | 3 +- .../securityd/Regressions/secd-49-manifests.m | 6 +- .../securityd/Regressions/secd-50-account.m | 10 +- .../securityd/Regressions/secd-50-message.m | 6 +- .../Regressions/secd-51-account-inflate.m | 11 +- .../Regressions/secd-52-account-changed.m | 11 +- .../secd-52-offering-gencount-reset.m | 13 +- .../Regressions/secd-55-account-circle.m | 12 +- .../secd-55-account-incompatibility.m | 12 +- .../Regressions/secd-56-account-apply.m | 12 +- .../secd-57-1-account-last-standing.m | 15 +- .../Regressions/secd-57-account-leave.m | 15 +- .../Regressions/secd-58-password-change.m | 11 +- .../Regressions/secd-59-account-cleanup.m | 15 +- .../secd-60-account-cloud-identity.m | 27 +- ...d-61-account-leave-not-in-kansas-anymore.m | 14 +- .../Regressions/secd-62-account-backup.m | 46 +- .../secd-63-account-resurrection.m | 14 +- .../Regressions/secd-64-circlereset.m | 14 +- .../secd-65-account-retirement-reset.m | 14 +- .../Regressions/secd-66-account-recovery.m | 36 +- .../securityd/Regressions/secd-668-ghosts.m | 14 +- .../Regressions/secd-70-engine-corrupt.m | 12 +- .../Regressions/secd-70-engine-smash.m | 2 +- .../securityd/Regressions/secd-70-engine.m | 14 +- .../Regressions/secd-70-otr-remote.m | 8 +- .../Regressions/secd-71-engine-save.m | 8 +- .../Regressions/secd-74-engine-beer-servers.m | 2 +- .../Regressions/secd-75-engine-views.m | 4 +- .../Regressions/secd-80-views-alwayson.m | 10 +- .../Regressions/secd-80-views-basic.m | 24 +- .../Regressions/secd-81-item-acl-stress.m | 6 +- .../securityd/Regressions/secd-81-item-acl.m | 9 +- .../Regressions/secd-95-escrow-persistence.m | 10 +- .../secd60-account-cloud-exposure.m | 18 +- .../securityd/Regressions/secd_regressions.h | 8 +- OSX/sec/securityd/SFKeychainControlManager.m | 10 +- OSX/sec/securityd/SFKeychainServer.m | 6 +- OSX/sec/securityd/SOSCloudCircleServer.h | 10 +- OSX/sec/securityd/SOSCloudCircleServer.m | 349 +- OSX/sec/securityd/SecAKSObjCWrappers.h | 49 + OSX/sec/securityd/SecAKSObjCWrappers.m | 46 + OSX/sec/securityd/SecCertificateServer.c | 53 +- OSX/sec/securityd/SecCertificateServer.h | 5 +- OSX/sec/securityd/SecCertificateSource.c | 18 +- .../SecDbBackupRecoverySet.proto | 40 + .../generated_source/SecDbBackupBag.h | 42 + .../generated_source/SecDbBackupBag.m | 177 + .../generated_source/SecDbBackupBagIdentity.h | 40 + .../generated_source/SecDbBackupBagIdentity.m | 159 + .../SecDbBackupKeyClassSigningKey.h | 58 + .../SecDbBackupKeyClassSigningKey.m | 279 + .../SecDbBackupMetadataClassKey.h | 44 + .../SecDbBackupMetadataClassKey.m | 174 + .../generated_source/SecDbBackupRecoverySet.h | 63 + .../generated_source/SecDbBackupRecoverySet.m | 297 + OSX/sec/securityd/SecDbBackupManager.h | 98 + OSX/sec/securityd/SecDbBackupManager.m | 1055 + .../securityd/SecDbBackupManager_Internal.h | 72 + OSX/sec/securityd/SecDbItem.c | 25 +- OSX/sec/securityd/SecDbItem.h | 8 +- OSX/sec/securityd/SecDbKeychainItem.h | 2 + OSX/sec/securityd/SecDbKeychainItem.m | 48 +- OSX/sec/securityd/SecDbKeychainItemV7.h | 19 +- OSX/sec/securityd/SecDbKeychainItemV7.m | 504 +- .../securityd/SecDbKeychainMetadataKeyStore.h | 53 + .../securityd/SecDbKeychainMetadataKeyStore.m | 370 + ...ecDbKeychainSerializedAKSWrappedKey.proto} | 0 .../SecDbKeychainSerializedSecretData.proto | 1 + .../SecDbKeychainSerializedAKSWrappedKey.h | 2 +- .../SecDbKeychainSerializedAKSWrappedKey.m | 8 +- .../SecDbKeychainSerializedItemV7.h | 2 +- .../SecDbKeychainSerializedItemV7.m | 2 +- .../SecDbKeychainSerializedMetadata.h | 2 +- .../SecDbKeychainSerializedMetadata.m | 2 +- .../SecDbKeychainSerializedSecretData.h | 6 +- .../SecDbKeychainSerializedSecretData.m | 37 +- OSX/sec/securityd/SecDbQuery.c | 4 +- OSX/sec/securityd/SecDbQuery.h | 4 +- OSX/sec/securityd/SecItemBackupServer.c | 4 +- OSX/sec/securityd/SecItemDataSource.c | 4 +- OSX/sec/securityd/SecItemDataSource.h | 2 +- OSX/sec/securityd/SecItemDb.c | 166 +- OSX/sec/securityd/SecItemSchema.c | 392 +- OSX/sec/securityd/SecItemServer.c | 398 +- OSX/sec/securityd/SecItemServer.h | 14 +- OSX/sec/securityd/SecKeybagSupport.c | 59 +- OSX/sec/securityd/SecKeybagSupport.h | 26 +- OSX/sec/securityd/SecLogSettingsServer.m | 4 +- OSX/sec/securityd/SecOCSPCache.c | 3 - OSX/sec/securityd/SecOCSPCache.h | 4 +- OSX/sec/securityd/SecOCSPResponse.h | 2 +- OSX/sec/securityd/SecOTRRemote.m | 2 +- OSX/sec/securityd/SecPinningDb.m | 11 +- OSX/sec/securityd/SecPolicyServer.c | 454 +- OSX/sec/securityd/SecPolicyServer.h | 8 +- OSX/sec/securityd/SecRevocationDb.c | 912 +- OSX/sec/securityd/SecRevocationDb.h | 13 +- OSX/sec/securityd/SecRevocationNetworking.m | 2 - OSX/sec/securityd/SecRevocationServer.c | 470 +- OSX/sec/securityd/SecRevocationServer.h | 7 - .../securityd/SecTrustExceptionResetCount.h | 14 + .../securityd/SecTrustExceptionResetCount.m | 194 + OSX/sec/securityd/SecTrustServer.c | 160 +- OSX/sec/securityd/SecTrustServer.h | 36 +- OSX/sec/securityd/SecTrustStoreServer.c | 2 +- OSX/sec/securityd/SecTrustStoreServer.h | 2 +- OSX/sec/securityd/SecTrustStoreServer.m | 85 +- OSX/sec/securityd/com.apple.secd.sb | 42 +- OSX/sec/securityd/entitlements.plist | 22 + OSX/sec/securityd/iCloudTrace.c | 42 +- OSX/sec/securityd/iCloudTrace.h | 20 - OSX/sec/securityd/nameconstraints.c | 98 - OSX/sec/securityd/spi.c | 98 +- OSX/sec/securityd/spi.h | 2 +- OSX/sectests/SecurityTests-Entitlements.plist | 2 + OSX/sectests/testlist.h | 1 - OSX/shared_regressions/shared_regressions.h | 13 +- .../parse_fail_length_63.cer | Bin .../parse_fail_tag_27.cer | Bin .../parse_fail_tag_28.cer | Bin .../parse_fail_tag_32.cer | Bin .../parse_fail_tag_36.cer | Bin .../parse_fail_keyusage_extra_bit.cer | Bin .../TODOFailureCerts/TODODescriptions.txt | 18 +- .../PinningPolicyTrustTest.plist | 400 + ...ca-serial+invalid+policysmime+complete.cer | Bin 0 -> 1102 bytes ...d-ca-serial+invalid+policyssl+complete.cer | Bin 0 -> 1099 bytes ...nvalid+policysmime+complete-clientauth.cer | Bin 0 -> 1208 bytes ...+invalid+policysmime+complete-codesign.cer | Bin 0 -> 1207 bytes ...ial+invalid+policysmime+complete-smime.cer | Bin 0 -> 1251 bytes ...erial+invalid+policysmime+complete-ssl.cer | Bin 0 -> 1242 bytes ...invalid+policysmime+complete-timestamp.cer | Bin 0 -> 1208 bytes ...+invalid+policyssl+complete-clientauth.cer | Bin 0 -> 1203 bytes ...al+invalid+policyssl+complete-codesign.cer | Bin 0 -> 1200 bytes ...erial+invalid+policyssl+complete-smime.cer | Bin 0 -> 1244 bytes ...-serial+invalid+policyssl+complete-ssl.cer | Bin 0 -> 1235 bytes ...l+invalid+policyssl+complete-timestamp.cer | Bin 0 -> 1202 bytes .../Valid-root.cer | Bin 0 -> 987 bytes .../si-20-sectrust-policies-data/caldav.cer | Bin 3802 -> 3822 bytes .../si-20-sectrust-policies-data/ids_prod.cer | Bin 1930 -> 0 bytes .../si-20-sectrust-policies.m | 442 - OSX/shared_regressions/si-44-seckey-aks.m | 42 +- OSX/shared_regressions/si-44-seckey-ies.m | 30 +- OSX/shared_regressions/si-44-seckey-skv.m | 68 + .../si-82-seccertificate-ct.c | 212 - OSX/shared_regressions/si-82-sectrust-ct.m | 1446 - OSX/shared_regressions/si-88-sectrust-valid.m | 65 +- OSX/trustd/iOS/entitlements.plist | 2 +- OSX/trustd/macOS/SecTrustOSXEntryPoints.h | 13 - OSX/trustd/macOS/com.apple.trustd.sb | 6 +- OSX/trustd/macOS/entitlements.plist | 2 +- OSX/trustd/trustd-Info.plist | 5 + OSX/trustd/trustd.c | 257 +- OSX/trustd/trustd_spi.c | 96 + OSX/trustd/trustd_spi.h | 36 + OSX/utilities/{src => }/NSURL+SOSPlistStore.h | 0 OSX/utilities/{src => }/NSURL+SOSPlistStore.m | 0 OSX/utilities/{src => }/SecADWrapper.c | 10 +- OSX/utilities/{src => }/SecADWrapper.h | 0 OSX/utilities/{src => }/SecAKSWrappers.c | 62 +- OSX/utilities/{src => }/SecAKSWrappers.h | 61 +- OSX/utilities/{src => }/SecAppleAnchor.c | 0 OSX/utilities/{src => }/SecAppleAnchorPriv.h | 0 OSX/utilities/{src => }/SecAutorelease.h | 0 OSX/utilities/{src => }/SecAutorelease.m | 0 OSX/utilities/{src => }/SecBuffer.c | 0 OSX/utilities/{src => }/SecBuffer.h | 0 OSX/utilities/{src => }/SecCFCCWrappers.c | 0 OSX/utilities/{src => }/SecCFCCWrappers.h | 0 OSX/utilities/{src => }/SecCFError.c | 0 OSX/utilities/{src => }/SecCFError.h | 2 +- OSX/utilities/{src => }/SecCFRelease.h | 0 OSX/utilities/{src => }/SecCFWrappers.c | 0 OSX/utilities/{src => }/SecCFWrappers.h | 22 +- OSX/utilities/SecCoreAnalytics.h | 39 + OSX/utilities/SecCoreAnalytics.m | 52 + OSX/utilities/{src => }/SecCoreCrypto.c | 0 OSX/utilities/{src => }/SecCoreCrypto.h | 0 OSX/utilities/{src => }/SecDb.c | 243 +- OSX/utilities/{src => }/SecDb.h | 10 +- OSX/utilities/{src => }/SecDispatchRelease.h | 0 OSX/utilities/{src => }/SecFileLocations.c | 53 +- OSX/utilities/{src => }/SecFileLocations.h | 13 +- OSX/utilities/{src => }/SecIOFormat.h | 0 OSX/utilities/{src => }/SecInternalRelease.c | 0 .../{src => }/SecInternalReleasePriv.h | 0 OSX/utilities/{src => }/SecNSAdditions.h | 0 OSX/utilities/{src => }/SecNSAdditions.m | 0 OSX/utilities/{src => }/SecPLWrappers.h | 0 OSX/utilities/{src => }/SecPLWrappers.m | 9 +- .../{src => }/SecPaddingConfigurations.c | 2 +- .../{src => }/SecPaddingConfigurationsPriv.h | 0 OSX/utilities/{src => }/SecSCTUtils.c | 0 OSX/utilities/{src => }/SecSCTUtils.h | 0 OSX/utilities/SecTapToRadar.h | 56 + OSX/utilities/SecTapToRadar.m | 225 + OSX/utilities/{src => }/SecTrace.c | 0 OSX/utilities/{src => }/SecTrace.h | 0 OSX/utilities/{src => }/SecXPCError.c | 0 OSX/utilities/{src => }/SecXPCError.h | 0 OSX/utilities/SecXPCHelper.h | 27 + OSX/utilities/SecXPCHelper.m | 183 + OSX/utilities/{src => }/array_size.h | 0 OSX/utilities/{src => }/debugging.c | 45 - OSX/utilities/{src => }/debugging.h | 8 - OSX/utilities/{src => }/debugging_test.h | 0 OSX/utilities/{src => }/der_array.c | 0 OSX/utilities/{src => }/der_boolean.c | 0 OSX/utilities/{src => }/der_data.c | 0 OSX/utilities/{src => }/der_date.c | 0 OSX/utilities/{src => }/der_date.h | 0 OSX/utilities/{src => }/der_dictionary.c | 0 OSX/utilities/{src => }/der_null.c | 0 OSX/utilities/{src => }/der_number.c | 0 OSX/utilities/{src => }/der_plist.c | 0 OSX/utilities/{src => }/der_plist.h | 0 OSX/utilities/{src => }/der_plist_internal.c | 0 OSX/utilities/{src => }/der_plist_internal.h | 0 OSX/utilities/{src => }/der_set.c | 0 OSX/utilities/{src => }/der_set.h | 0 OSX/utilities/{src => }/der_string.c | 0 OSX/utilities/{src => }/fileIo.c | 0 OSX/utilities/{src => }/fileIo.h | 0 OSX/utilities/iCloudKeychainTrace.c | 30 + .../iCloudKeychainTrace.h} | 11 +- OSX/utilities/{src => }/iOSforOSX-SecAttr.c | 2 +- OSX/utilities/{src => }/iOSforOSX-SecRandom.c | 2 +- OSX/utilities/{src => }/iOSforOSX.c | 2 +- OSX/utilities/{src => }/iOSforOSX.h | 4 +- OSX/utilities/{src => }/sec_action.c | 0 OSX/utilities/{src => }/sec_action.h | 0 OSX/utilities/{src => }/simulate_crash.c | 23 +- OSX/utilities/{src => }/sqlutils.h | 0 OSX/utilities/src/iCloudKeychainTrace.c | 428 - OSX/utilities/src/iCloudKeychainTrace.h | 54 - OSX/utilities/test/Info.plist | 22 + OSX/utilities/test/SecTapToRadarTests.m | 108 + OSX/utilities/test/SecXPCHelperTests.m | 127 + OSX/utilities/utilities | 1 - README | 28 +- README-TRIESTE.md | 38 + RegressionTests/Security.plist | 86 +- RegressionTests/SecurityLocalKeychain.plist | 77 + RegressionTests/manifeststresstest/Keychain.m | 4 +- RegressionTests/secbackuptest/secbackuptest.m | 2 +- .../secitemcanarytest/secitemcanarytest.m | 10 +- .../secitemfunctionality.m | 30 +- .../secitemstresstest/secitemstresstest.m | 15 +- .../seckeychainnetworkextensionstest/main.m | 8 +- .../main.m | 4 +- .../main.m | 4 +- SOSCCAuthPlugin/SOSCCAuthPlugin.m | 11 +- SecExperiment/SecExperiment.m | 322 + SecExperiment/SecExperimentInternal.h | 34 + SecExperiment/SecExperimentPriv.h | 120 + SecExperiment/TLSAssets/Info.plist | 23 + SecExperiment/TLSAssets/Makefile | 35 + SecExperiment/TLSAssets/TLSConfig.plist | 30 + SecExperiment/test/SecExperimentTests.m | 77 + Security.exp-in | 190 +- Security.xcodeproj/project.pbxproj | 27105 ++++++++++------ ...B3656633-AB83-4153-B404-DE14DBDC5ED6.plist | 52 - .../Info.plist | 33 - .../xcshareddata/xcschemes/CKKSTests.xcscheme | 5 +- .../xcschemes/OctagonTests.xcscheme | 72 + .../xcschemes/TrustTests_ios.xcscheme | 117 + .../xcschemes/TrustTests_macos.xcscheme | 117 + .../xcschemes/TrustedPeers.xcscheme | 4 +- .../xcschemes/ios - Debug.xcscheme | 84 +- .../xcschemes/ios - Release.xcscheme | 60 +- .../xcschemes/ios - secdtests.xcscheme | 6 +- .../xcschemes/osx - World.xcscheme | 112 +- .../xcschemes/osx - secdtests.xcscheme | 108 +- .../xcschemes/secdmockaks.xcscheme | 56 + SecurityTests/NOTE.txt | 7 +- .../SecurityTests-Entitlements.plist | 6 +- .../SSL Trust Policy Test CA certificates.pem | 23 - ...L Trust Policy Test CA.certAuthorityConfig | 112 - .../ssl-policy-certs/SSLTrustPolicyTest.plist | 4 +- .../ssl-policy-certs/SSLTrustPolicyTestCA.p12 | Bin 1498 -> 0 bytes .../ssl-policy-certs/TestDescriptions.txt | 10 +- SecurityTests/testlist.h | 2 +- SecurityTool/APPLE_LICENSE | 335 - .../macOS}/APPLE_LICENSE | 0 SecurityTool/{ => macOS}/access_utils.c | 0 SecurityTool/{ => macOS}/access_utils.h | 0 SecurityTool/{ => macOS}/authz.c | 0 SecurityTool/{ => macOS}/authz.h | 0 SecurityTool/{ => macOS}/cmsutil.c | 0 SecurityTool/{ => macOS}/cmsutil.h | 0 SecurityTool/{ => macOS}/createFVMaster.c | 0 SecurityTool/{ => macOS}/createFVMaster.h | 0 SecurityTool/{ => macOS}/db_commands.cpp | 0 SecurityTool/{ => macOS}/db_commands.h | 0 SecurityTool/{ => macOS}/display_error_code.c | 0 SecurityTool/{ => macOS}/display_error_code.h | 0 SecurityTool/{ => macOS}/identity_find.h | 0 SecurityTool/{ => macOS}/identity_find.m | 38 +- SecurityTool/{ => macOS}/identity_prefs.c | 38 +- SecurityTool/{ => macOS}/identity_prefs.h | 0 SecurityTool/{ => macOS}/key_create.c | 0 SecurityTool/{ => macOS}/key_create.h | 0 SecurityTool/{ => macOS}/keychain_add.c | 102 +- SecurityTool/{ => macOS}/keychain_add.h | 0 SecurityTool/{ => macOS}/keychain_create.c | 0 SecurityTool/{ => macOS}/keychain_create.h | 0 SecurityTool/{ => macOS}/keychain_delete.c | 2 +- SecurityTool/{ => macOS}/keychain_delete.h | 0 SecurityTool/{ => macOS}/keychain_export.h | 0 SecurityTool/{ => macOS}/keychain_export.m | 0 SecurityTool/{ => macOS}/keychain_find.c | 94 +- SecurityTool/{ => macOS}/keychain_find.h | 0 SecurityTool/{ => macOS}/keychain_import.c | 0 SecurityTool/{ => macOS}/keychain_import.h | 0 SecurityTool/{ => macOS}/keychain_list.c | 0 SecurityTool/{ => macOS}/keychain_list.h | 0 SecurityTool/{ => macOS}/keychain_lock.c | 0 SecurityTool/{ => macOS}/keychain_lock.h | 0 SecurityTool/{ => macOS}/keychain_recode.c | 0 SecurityTool/{ => macOS}/keychain_recode.h | 0 .../{ => macOS}/keychain_set_settings.c | 0 .../{ => macOS}/keychain_set_settings.h | 0 SecurityTool/{ => macOS}/keychain_show_info.c | 0 SecurityTool/{ => macOS}/keychain_show_info.h | 0 SecurityTool/{ => macOS}/keychain_unlock.c | 0 SecurityTool/{ => macOS}/keychain_unlock.h | 0 SecurityTool/{ => macOS}/keychain_utilities.c | 66 +- SecurityTool/{ => macOS}/keychain_utilities.h | 11 +- SecurityTool/{ => macOS}/leaks.c | 0 SecurityTool/{ => macOS}/leaks.h | 0 SecurityTool/{ => macOS}/mds_install.cpp | 0 SecurityTool/{ => macOS}/mds_install.h | 0 SecurityTool/{ => macOS}/readline.c | 0 SecurityTool/{ => macOS}/readline_cssm.h | 0 SecurityTool/{ => macOS}/requirement.c | 3 +- SecurityTool/{ => macOS}/requirement.h | 0 SecurityTool/{ => macOS}/security.1 | 47 +- SecurityTool/{ => macOS}/security.c | 33 +- SecurityTool/{ => macOS}/security_tool.h | 0 SecurityTool/{ => macOS}/smartcards.h | 0 SecurityTool/{ => macOS}/smartcards.m | 0 SecurityTool/{ => macOS}/srCdsaUtils.cpp | 0 SecurityTool/{ => macOS}/srCdsaUtils.h | 0 SecurityTool/{ => macOS}/translocate.c | 0 SecurityTool/{ => macOS}/translocate.h | 0 .../{ => macOS}/trust_settings_impexp.c | 0 .../{ => macOS}/trust_settings_impexp.h | 0 SecurityTool/{ => macOS}/trusted_cert_add.c | 63 +- SecurityTool/{ => macOS}/trusted_cert_add.h | 0 SecurityTool/{ => macOS}/trusted_cert_dump.c | 21 - SecurityTool/{ => macOS}/trusted_cert_dump.h | 0 .../macOS/trusted_cert_ssl.h | 38 +- SecurityTool/macOS/trusted_cert_ssl.m | 518 + SecurityTool/{ => macOS}/trusted_cert_utils.c | 98 +- SecurityTool/{ => macOS}/trusted_cert_utils.h | 10 +- .../{ => macOS}/user_trust_enable.cpp | 0 SecurityTool/{ => macOS}/user_trust_enable.h | 0 SecurityTool/{ => macOS}/verify_cert.c | 74 +- SecurityTool/{ => macOS}/verify_cert.h | 0 .../sharedTool}/KeychainCheck.h | 0 .../sharedTool}/KeychainCheck.m | 26 + .../sharedTool}/NSFileHandle+Formatting.h | 0 .../sharedTool}/NSFileHandle+Formatting.m | 0 .../sharedTool}/SecurityCommands.h | 16 +- .../sharedTool}/SecurityTool.c | 4 +- .../sharedTool}/SecurityTool.h | 0 .../sharedTool}/add_internet_password.c | 2 +- .../sharedTool}/builtin_commands.h | 7 +- .../sharedTool}/codesign.c | 4 +- .../sharedTool}/ct_exceptions.m | 0 .../sharedTool}/digest_calc.c | 6 +- .../{ => sharedTool/iOS}/entitlements.plist | 14 +- .../sharedTool/iOS}/security.1 | 6 +- .../sharedTool}/keychain_add.c | 8 +- .../sharedTool}/keychain_backup.c | 8 +- .../sharedTool}/keychain_find.m | 124 +- .../sharedTool}/keychain_util.c | 4 +- .../sharedTool}/keychain_util.h | 0 .../sharedTool}/leaks.c | 1 - .../sharedTool}/leaks.h | 0 .../sharedTool}/log_control.c | 2 +- .../sharedTool/macOS}/entitlements.plist | 24 +- .../sharedTool/macOS}/security2.1 | 0 .../sharedTool}/not_on_this_platorm.c | 0 .../sharedTool}/pkcs12_util.c | 6 +- .../sharedTool/policy_dryrun.h | 22 +- SecurityTool/sharedTool/policy_dryrun.m | 272 + .../sharedTool}/print_cert.c | 0 .../sharedTool}/print_cert.h | 0 .../sharedTool}/readline.c | 0 .../sharedTool}/readline.h | 0 .../Tool => SecurityTool/sharedTool}/scep.c | 36 +- .../{ => sharedTool}/security_tool_commands.c | 14 +- .../sharedTool}/security_tool_commands.h | 2 +- .../security_tool_commands_table.h | 4 +- .../sharedTool}/show_certificates.c | 10 +- .../sharedTool}/sos.m | 132 +- .../Tool => SecurityTool/sharedTool}/spc.c | 4 +- SecurityTool/{ => sharedTool}/sub_commands.h | 12 +- .../sharedTool}/syncbubble.m | 2 - .../sharedTool}/tool_errors.h | 2 +- .../sharedTool}/trust_update.m | 36 +- .../sharedTool}/verify_cert.c | 0 .../sharedTool}/whoami.m | 0 SharedMocks/NSXPCConnectionMock.h | 18 + SharedMocks/NSXPCConnectionMock.m | 34 + .../SWCViewController.m | 29 +- base/SecBase.h | 256 +- base/Security.h | 1 - ckcdiagnose/ckcdiagnose.sh | 161 - cssm/certextensions.h | 18 +- dtlsEcho/dtlsEchoClient.c | 5 + dtlsEcho/dtlsEchoServer.c | 5 + featureflags/Info.plist | 26 + featureflags/Security.plist | 41 + header_symlinks/Security/CKKSControl.h | 1 + .../Security/CKKSControlProtocol.h | 1 + header_symlinks/Security/CMSDecoder.h | 1 + header_symlinks/Security/CMSEncoder.h | 1 + header_symlinks/Security/CMSPrivate.h | 1 + header_symlinks/Security/CSCommonPriv.h | 1 - header_symlinks/Security/CipherSuite.h | 1 + .../Security/LocalKeychainAnalytics.h | 1 + header_symlinks/Security/OTClique.h | 1 + header_symlinks/Security/OTControl.h | 1 + header_symlinks/Security/OTControlProtocol.h | 1 + .../Security/OTJoiningConfiguration.h | 1 + header_symlinks/Security/SFAnalytics.h | 1 + .../Security/SFAnalyticsActivityTracker.h | 1 + header_symlinks/Security/SFAnalyticsDefines.h | 1 + .../Security/SFAnalyticsMultiSampler.h | 1 + .../Security/SFAnalyticsSQLiteStore.h | 1 + header_symlinks/Security/SFAnalyticsSampler.h | 1 + header_symlinks/Security/SFSQLite.h | 1 + header_symlinks/Security/SOSAnalytics.h | 1 + header_symlinks/Security/SOSControlHelper.h | 1 + header_symlinks/Security/SecAccessControl.h | 1 + .../Security/SecAccessControlPriv.h | 1 + header_symlinks/Security/SecAsn1Coder.h | 1 + header_symlinks/Security/SecAsn1Templates.h | 1 + header_symlinks/Security/SecAsn1Types.h | 1 + header_symlinks/Security/SecBase64.h | 1 + header_symlinks/Security/SecCFAllocator.h | 1 + header_symlinks/Security/SecCMS.h | 1 + header_symlinks/Security/SecCmsBase.h | 1 + header_symlinks/Security/SecCmsContentInfo.h | 1 + header_symlinks/Security/SecCmsDecoder.h | 1 + .../Security/SecCmsDigestContext.h | 1 + header_symlinks/Security/SecCmsDigestedData.h | 1 + header_symlinks/Security/SecCmsEncoder.h | 1 + .../Security/SecCmsEncryptedData.h | 1 + .../Security/SecCmsEnvelopedData.h | 1 + header_symlinks/Security/SecCmsMessage.h | 1 + .../Security/SecCmsRecipientInfo.h | 1 + header_symlinks/Security/SecCmsSignedData.h | 1 + header_symlinks/Security/SecCmsSignerInfo.h | 1 + header_symlinks/Security/SecCodeHost.h | 1 - header_symlinks/Security/SecCodeSigner.h | 1 - header_symlinks/Security/SecDH.h | 1 + header_symlinks/Security/SecECKey.h | 1 + header_symlinks/Security/SecEntitlements.h | 1 + header_symlinks/Security/SecExperimentPriv.h | 1 + header_symlinks/Security/SecFramework.h | 1 + .../Security/SecImportExportPriv.h | 1 + .../Security/SecInternalReleasePriv.h | 1 + header_symlinks/Security/SecItemBackup.h | 1 + header_symlinks/Security/SecLogging.h | 1 + header_symlinks/Security/SecOTR.h | 1 + header_symlinks/Security/SecOTRSession.h | 1 + .../Security/SecPaddingConfigurationsPriv.h | 1 + .../Security/SecPasswordGenerate.h | 1 + header_symlinks/Security/SecProtocol.h | 1 - .../Security/SecProtocolConfiguration.h | 1 + header_symlinks/Security/SecProtocolPriv.h | 1 + header_symlinks/Security/SecRecoveryKey.h | 1 + header_symlinks/Security/SecRequirementPriv.h | 1 - header_symlinks/Security/SecSMIME.h | 1 + .../Security/SecServerEncryptionSupport.h | 1 + header_symlinks/Security/SecStaticCodePriv.h | 1 - header_symlinks/Security/SecTaskPriv.h | 1 + header_symlinks/Security/SecXPCError.h | 1 + .../SecureObjectSync/SOSBackupSliceKeyBag.h | 1 + .../SecureObjectSync/SOSCloudCircle.h | 1 + .../SecureObjectSync/SOSCloudCircleInternal.h | 1 + .../Security/SecureObjectSync/SOSPeerInfo.h | 1 + .../Security/SecureObjectSync/SOSTypes.h | 1 + .../Security/SecureObjectSync/SOSViews.h | 1 + header_symlinks/Security/SecureTransport.h | 1 + .../Security/SecureTransportPriv.h | 1 + header_symlinks/Security/X509Templates.h | 2 +- .../Security/certExtensionTemplates.h | 1 + header_symlinks/Security/der_plist.h | 1 + header_symlinks/Security/keyTemplates.h | 1 - header_symlinks/Security/nameTemplates.h | 2 +- header_symlinks/Security/ocspTemplates.h | 1 + header_symlinks/Security/oidsalg.h | 1 + header_symlinks/Security/oidsattr.h | 1 - header_symlinks/Security/secasn1t.h | 1 + header_symlinks/Security/sslTypes.h | 1 + header_symlinks/iOS/Security/NtlmGenerator.h | 1 + .../iOS/Security/SecCertificateInternal.h | 1 + header_symlinks/iOS/Security/SecECKeyPriv.h | 1 + header_symlinks/iOS/Security/SecEMCSPriv.h | 1 + header_symlinks/iOS/Security/SecOTRDHKey.h | 1 + header_symlinks/iOS/Security/SecOTRErrors.h | 1 + header_symlinks/iOS/Security/SecOTRMath.h | 1 + .../iOS/Security/SecOTRPacketData.h | 1 + header_symlinks/iOS/Security/SecOTRPackets.h | 1 + .../iOS/Security/SecOTRSessionPriv.h | 1 + header_symlinks/iOS/Security/SecPBKDF.h | 1 + header_symlinks/iOS/Security/SecRSAKey.h | 1 + header_symlinks/iOS/Security/SecSCEP.h | 1 + header_symlinks/iOS/Security/SecTrustStore.h | 1 + .../Security/SecureObjectSync/SOSPeerInfoV2.h | 1 + header_symlinks/iOS/Security/oidsbase.h | 1 - header_symlinks/iOS/Security/oidsocsp.h | 1 + header_symlinks/iOS/Security/osxcode.h | 1 - header_symlinks/iOS/Security/pbkdf2.h | 1 + header_symlinks/iOS/Security/vmdh.h | 1 + header_symlinks/macOS/Security/CMSDecoder.h | 1 - header_symlinks/macOS/Security/CMSEncoder.h | 1 - header_symlinks/macOS/Security/CMSPrivate.h | 1 - header_symlinks/macOS/Security/CSCommonPriv.h | 1 + header_symlinks/macOS/Security/CipherSuite.h | 1 - header_symlinks/macOS/Security/SecASN1Coder.h | 1 - .../macOS/Security/SecASN1Templates.h | 1 - .../macOS/Security/SecAccessControl.h | 1 - header_symlinks/macOS/Security/SecAsn1Types.h | 1 - .../macOS/Security/SecAssessment.h | 1 + .../macOS/Security/SecBreadcrumb.h | 1 + header_symlinks/macOS/Security/SecCmsBase.h | 1 - .../macOS/Security/SecCmsContentInfo.h | 1 - .../macOS/Security/SecCmsDecoder.h | 1 - .../macOS/Security/SecCmsDigestContext.h | 1 - .../macOS/Security/SecCmsDigestedData.h | 1 - .../macOS/Security/SecCmsEncoder.h | 1 - .../macOS/Security/SecCmsEncryptedData.h | 1 - .../macOS/Security/SecCmsEnvelopedData.h | 1 - .../macOS/Security/SecCmsMessage.h | 1 - .../macOS/Security/SecCmsRecipientInfo.h | 1 - .../macOS/Security/SecCmsSignedData.h | 1 - .../macOS/Security/SecCmsSignerInfo.h | 1 - header_symlinks/macOS/Security/SecCodeHost.h | 1 + .../macOS/Security/SecCodeSigner.h | 1 + .../Security/SecExternalSourceTransform.h | 1 + .../Security/SecFDERecoveryAsymmetricCrypto.h | 1 + .../SecKeychainItemExtendedAttributes.h | 1 + header_symlinks/macOS/Security/SecManifest.h | 1 + .../macOS/Security/SecNullTransform.h | 1 + header_symlinks/macOS/Security/SecPassword.h | 1 + header_symlinks/macOS/Security/SecRandomP.h | 1 + .../macOS/Security/SecRecoveryPassword.h | 1 + .../macOS/Security/SecRequirementPriv.h | 1 + header_symlinks/macOS/Security/SecSMIME.h | 1 - .../macOS/Security/SecStaticCodePriv.h | 1 + .../macOS/Security/SecTransformInternal.h | 1 + .../macOS/Security/SecTranslocate.h | 1 + .../macOS/Security/SecureDownload.h | 1 + .../macOS/Security/SecureDownloadInternal.h | 1 + .../macOS/Security/SecureTransport.h | 1 - .../macOS/Security/asn1Templates.h | 1 + .../macOS/Security/certExtensionTemplates.h | 1 - header_symlinks/macOS/Security/eisl.h | 1 + header_symlinks/macOS/Security/keyTemplates.h | 1 + .../macOS/Security/ocspTemplates.h | 1 - header_symlinks/macOS/Security/oids.h | 1 - header_symlinks/macOS/Security/oidsalg.h | 1 - header_symlinks/macOS/Security/oidsattr.h | 1 + header_symlinks/macOS/Security/secasn1t.h | 1 - header_symlinks/macOS/Security/tsaSupport.h | 1 + keychain/CoreDataKeychain/SecCDKeychain.h | 4 + keychain/CoreDataKeychain/SecCDKeychain.m | 22 +- .../KeychainDataclassOwner.m | 4 +- keychain/KeychainSettings/Info.plist | 26 + keychain/KeychainSettings/KeychainSettings.h | 21 + keychain/KeychainSettings/KeychainSettings.m | 372 + .../KeychainSettings/KeychainSettings.plist | 95 + .../KeychainSettingsCKKSViews.plist | 17 + .../KeychainSettingsOctagonPeers.plist | 7 +- keychain/SecAccessControl.h | 22 +- keychain/SecIdentityPriv.h | 8 +- keychain/SecImportExport.h | 13 +- keychain/SecImportExportPriv.h | 21 + keychain/SecItem.h | 31 +- keychain/SecItemPriv.h | 47 +- keychain/SecKey.h | 4 +- keychain/SecKeyPriv.h | 39 +- .../CKBridge/SOSCloudKeychainClient.c | 217 +- .../CKBridge/SOSCloudKeychainClient.h | 8 +- .../CKBridge/SOSCloudKeychainConstants.c | 2 +- .../CKBridge/SOSCloudKeychainConstants.h | 2 +- .../SecureObjectSync/CKDSimulatedStore.h | 0 .../SecureObjectSync/CKDSimulatedStore.m | 0 .../Regressions/CKDSimulatedAccount.h | 0 .../Regressions/CKDSimulatedAccount.m | 0 .../Regressions/SOSCircle_regressions.h | 0 .../Regressions/SOSRegressionUtilities.h | 2 +- .../Regressions/SOSRegressionUtilities.m | 15 +- .../Regressions/SOSTestDataSource.c | 4 +- .../Regressions/SOSTestDataSource.h | 2 +- .../Regressions/SOSTestDevice.c | 4 +- .../Regressions/SOSTestDevice.h | 2 +- .../Regressions/sc-130-resignationticket.c | 6 +- .../Regressions/sc-150-backupkeyderivation.c | 4 +- .../Regressions/sc-150-ring.m | 10 +- .../Regressions/sc-153-backupslicekeybag.c | 10 +- .../Regressions/sc-20-keynames.m | 8 +- .../Regressions/sc-25-soskeygen.c | 289 + .../Regressions/sc-30-peerinfo.c | 10 +- .../Regressions/sc-31-peerinfo-simplefuzz.c | 10 +- .../Regressions/sc-40-circle.c | 8 +- .../Regressions/sc-42-circlegencount.c | 6 +- .../Regressions/sc-45-digestvector.c | 2 +- .../Regressions/sc-kvstool.m | 0 .../SecureObjectSync/SOSARCDefines.h | 0 .../SecureObjectSync/SOSAccount.h | 23 +- .../SecureObjectSync/SOSAccount.m | 342 +- .../SecureObjectSync/SOSAccountBackup.m | 193 +- .../SecureObjectSync/SOSAccountCircles.m | 20 +- .../SOSAccountCloudParameters.m | 4 +- .../SecureObjectSync/SOSAccountCredentials.m | 34 +- .../SecureObjectSync/SOSAccountDer.m | 2 +- .../SecureObjectSync/SOSAccountFullPeerInfo.m | 19 +- .../SecureObjectSync/SOSAccountGetSet.m | 4 +- keychain/SecureObjectSync/SOSAccountGhost.h | 36 + keychain/SecureObjectSync/SOSAccountGhost.m | 336 + keychain/SecureObjectSync/SOSAccountLog.h | 29 + .../SecureObjectSync/SOSAccountLog.m | 8 +- .../SecureObjectSync/SOSAccountPeers.m | 10 +- .../SecureObjectSync/SOSAccountPersistence.m | 18 +- .../SecureObjectSync/SOSAccountPriv.h | 45 +- .../SecureObjectSync/SOSAccountRecovery.m | 165 +- .../SecureObjectSync/SOSAccountRingUpdate.m | 12 +- .../SecureObjectSync/SOSAccountRings.m | 9 +- .../SecureObjectSync/SOSAccountSync.m | 174 +- .../SecureObjectSync/SOSAccountTransaction.h | 2 +- .../SecureObjectSync/SOSAccountTransaction.m | 142 +- .../SecureObjectSync/SOSAccountTrust.h | 6 +- .../SecureObjectSync/SOSAccountTrust.m | 4 +- .../SOSAccountTrustClassic+Circle.h | 5 +- .../SOSAccountTrustClassic+Circle.m | 555 +- .../SOSAccountTrustClassic+Expansion.h | 5 +- .../SOSAccountTrustClassic+Expansion.m | 428 +- .../SOSAccountTrustClassic+Identity.h | 2 +- .../SOSAccountTrustClassic+Identity.m | 43 +- .../SOSAccountTrustClassic+Retirement.h | 4 +- .../SOSAccountTrustClassic+Retirement.m | 8 +- .../SecureObjectSync/SOSAccountTrustClassic.h | 10 +- .../SecureObjectSync/SOSAccountTrustClassic.m | 152 +- .../SecureObjectSync/SOSAccountUpdate.m | 20 +- .../SecureObjectSync/SOSAccountViewSync.m | 77 +- keychain/SecureObjectSync/SOSAuthKitHelpers.h | 33 + .../SecureObjectSync/SOSAuthKitHelpers.m | 218 +- .../SecureObjectSync/SOSBackupEvent.c | 2 +- .../SecureObjectSync/SOSBackupEvent.h | 0 .../SecureObjectSync/SOSBackupInformation.h | 2 +- .../SecureObjectSync/SOSBackupInformation.m | 0 .../SecureObjectSync/SOSBackupSliceKeyBag.h | 5 + .../SecureObjectSync/SOSBackupSliceKeyBag.m | 69 +- .../SecureObjectSync/SOSChangeTracker.c | 10 +- .../SecureObjectSync/SOSChangeTracker.h | 2 +- .../SecureObjectSync/SOSCircle.c | 62 +- .../SecureObjectSync/SOSCircle.h | 15 +- .../SecureObjectSync/SOSCircleDer.c | 12 +- .../SecureObjectSync/SOSCircleDer.h | 0 .../SecureObjectSync/SOSCirclePriv.h | 2 +- .../SecureObjectSync/SOSCircleRings.h | 0 .../SecureObjectSync/SOSCircleV2.c | 0 .../SecureObjectSync/SOSCircleV2.h | 0 .../SecureObjectSync/SOSCloudCircle.h | 20 +- .../SecureObjectSync/SOSCloudCircle.m | 134 +- .../SecureObjectSync/SOSCloudCircleInternal.h | 0 .../SecureObjectSync/SOSCoder.c | 9 +- .../SecureObjectSync/SOSCoder.h | 2 +- .../SecureObjectSync/SOSConcordanceTrust.h | 0 .../SecureObjectSync/SOSControlHelper.h | 0 .../SecureObjectSync/SOSControlHelper.m | 7 +- .../SecureObjectSync/SOSControlServer.h | 10 + .../SecureObjectSync/SOSControlServer.m | 91 +- .../SecureObjectSync/SOSDataSource.h | 12 +- .../SecureObjectSync/SOSDigestVector.c | 14 +- .../SecureObjectSync/SOSDigestVector.h | 0 .../SecureObjectSync/SOSECWrapUnwrap.c | 2 +- .../SecureObjectSync/SOSEngine.c | 97 +- .../SecureObjectSync/SOSEngine.h | 6 +- .../SecureObjectSync/SOSEnginePriv.h | 2 +- .../SecureObjectSync/SOSEnsureBackup.h | 0 .../SecureObjectSync/SOSEnsureBackup.m | 2 +- .../SecureObjectSync/SOSExports.exp-in | 42 +- .../SecureObjectSync/SOSFullPeerInfo.h | 2 +- .../SecureObjectSync/SOSFullPeerInfo.m | 34 +- .../SecureObjectSync/SOSGenCount.c | 0 .../SecureObjectSync/SOSGenCount.h | 0 .../SecureObjectSync/SOSInternal.h | 9 +- .../SecureObjectSync/SOSInternal.m | 17 +- .../SecureObjectSync/SOSKVSKeys.h | 6 +- .../SecureObjectSync/SOSKVSKeys.m | 4 +- .../SOSKeyedPubKeyIdentifier.c | 2 +- .../SOSKeyedPubKeyIdentifier.h | 0 .../SecureObjectSync/SOSManifest.c | 4 +- .../SecureObjectSync/SOSManifest.h | 0 .../SecureObjectSync/SOSMessage.c | 8 +- .../SecureObjectSync/SOSMessage.h | 4 +- .../SecureObjectSync/SOSPeer.h | 6 +- .../SecureObjectSync/SOSPeer.m | 16 +- .../SecureObjectSync/SOSPeerCoder.h | 6 +- .../SecureObjectSync/SOSPeerCoder.m | 34 +- .../SecureObjectSync/SOSPeerInfo.h | 32 +- .../SecureObjectSync/SOSPeerInfo.m | 137 +- .../SecureObjectSync/SOSPeerInfoCollections.c | 6 +- .../SecureObjectSync/SOSPeerInfoCollections.h | 0 .../SecureObjectSync/SOSPeerInfoDER.h | 0 .../SecureObjectSync/SOSPeerInfoDER.m | 30 +- .../SecureObjectSync/SOSPeerInfoInternal.h | 0 .../SecureObjectSync/SOSPeerInfoPriv.h | 0 .../SecureObjectSync/SOSPeerInfoRingState.h | 8 +- .../SecureObjectSync/SOSPeerInfoRingState.m | 0 .../SecureObjectSync/SOSPeerInfoV2.h | 0 .../SecureObjectSync/SOSPeerInfoV2.m | 13 +- .../SecureObjectSync/SOSPeerOTRTimer.h | 0 .../SecureObjectSync/SOSPeerOTRTimer.m | 24 +- .../SecureObjectSync/SOSPeerRateLimiter.h | 2 +- .../SecureObjectSync/SOSPeerRateLimiter.m | 4 +- .../SecureObjectSync/SOSPersist.h | 0 .../SecureObjectSync/SOSPiggyback.h | 3 +- .../SecureObjectSync/SOSPiggyback.m | 35 +- .../SecureObjectSync/SOSPlatform.h | 0 .../SecureObjectSync/SOSRecoveryKeyBag.h | 0 .../SecureObjectSync/SOSRecoveryKeyBag.m | 20 +- .../SecureObjectSync/SOSRing.h | 7 +- .../SecureObjectSync/SOSRingBackup.h | 0 .../SecureObjectSync/SOSRingBackup.m | 8 +- .../SecureObjectSync/SOSRingBasic.h | 0 .../SecureObjectSync/SOSRingBasic.m | 8 +- .../SOSRingConcordanceTrust.c | 10 +- .../SOSRingConcordanceTrust.h | 0 .../SecureObjectSync/SOSRingDER.c | 10 +- .../SecureObjectSync/SOSRingDER.h | 0 .../SecureObjectSync/SOSRingPeerInfoUtils.c | 10 +- .../SecureObjectSync/SOSRingPeerInfoUtils.h | 0 .../SecureObjectSync/SOSRingRecovery.h | 2 +- .../SecureObjectSync/SOSRingRecovery.m | 10 +- .../SecureObjectSync/SOSRingTypes.h | 4 +- .../SecureObjectSync/SOSRingTypes.m | 20 +- .../SecureObjectSync/SOSRingUtils.c | 12 +- .../SecureObjectSync/SOSRingUtils.h | 3 +- .../SecureObjectSync/SOSRingV0.h | 0 .../SecureObjectSync/SOSRingV0.m | 10 +- .../SecureObjectSync/SOSTransport.h | 8 +- .../SecureObjectSync/SOSTransport.m | 28 +- .../SecureObjectSync/SOSTransportBackupPeer.h | 2 +- .../SecureObjectSync/SOSTransportBackupPeer.m | 2 +- .../SecureObjectSync/SOSTransportCircle.h | 2 +- .../SecureObjectSync/SOSTransportCircle.m | 4 +- .../SecureObjectSync/SOSTransportCircleCK.h | 0 .../SecureObjectSync/SOSTransportCircleCK.m | 4 +- .../SecureObjectSync/SOSTransportCircleKVS.h | 0 .../SecureObjectSync/SOSTransportCircleKVS.m | 16 +- .../SOSTransportKeyParameter.h | 2 +- .../SOSTransportKeyParameter.m | 19 +- .../SecureObjectSync/SOSTransportMessage.h | 6 +- .../SecureObjectSync/SOSTransportMessage.m | 113 +- .../SecureObjectSync/SOSTransportMessageKVS.h | 4 +- .../SecureObjectSync/SOSTransportMessageKVS.m | 23 +- .../SOSTrustedDeviceAttributes.h | 27 + .../SOSTrustedDeviceAttributes.m | 27 + .../SecureObjectSync/SOSTypes.h | 18 +- .../SecureObjectSync/SOSUserKeygen.h | 0 .../SecureObjectSync/SOSUserKeygen.m | 61 +- .../SecureObjectSync/SOSViews.exp-in | 4 +- .../SecureObjectSync/SOSViews.h | 0 .../SecureObjectSync/SOSViews.m | 58 +- .../Tool/accountCirclesViewsPrint.h | 0 .../Tool/accountCirclesViewsPrint.m | 52 +- .../SecureObjectSync}/Tool/keychain_log.h | 2 +- keychain/SecureObjectSync/Tool/keychain_log.m | 134 + .../SecureObjectSync}/Tool/keychain_sync.h | 2 +- .../SecureObjectSync}/Tool/keychain_sync.m | 15 +- .../Tool/keychain_sync_test.h | 2 +- .../Tool/keychain_sync_test.m | 0 .../SecureObjectSync}/Tool/recovery_key.h | 2 +- .../SecureObjectSync}/Tool/recovery_key.m | 0 .../SecureObjectSync}/Tool/secToolFileIO.c | 0 .../SecureObjectSync}/Tool/secToolFileIO.h | 0 .../SecureObjectSync}/Tool/secViewDisplay.c | 2 +- .../SecureObjectSync}/Tool/secViewDisplay.h | 0 .../SecureObjectSync}/Tool/syncbackup.h | 2 +- .../SecureObjectSync}/Tool/syncbackup.m | 6 +- .../SecureObjectSync/ViewList.list | 28 +- .../SecurityUnitTests}/Info.plist | 0 keychain/SecurityUnitTests/SecItemTests.m | 157 + .../SecurityUnitTests/SecKeyTests.m | 4 +- .../SecurityUnitTests.entitlements | 10 + keychain/Signin Metrics/SFSignInAnalytics.m | 39 +- .../tests/SFSignInAnalyticsTests.m | 4 +- .../Trieste/OctagonTestHarness/Info.plist | 22 + .../OctagonTestHarness/OctagonTestHarness.exp | 4 + .../OctagonTestHarness/OctagonTestHarness.h | 23 + .../OctagonTestHarness/OctagonTestHarness.m | 18 + .../Entitlements.plist | 12 + .../OctagonTestHarnessXPCService}/Info.plist | 6 +- .../OctagonTestHarnessXPCService.h | 7 + .../OctagonTestHarnessXPCService.m | 58 + .../OctagonTestHarnessXPCServiceDelegate.h | 12 + .../OctagonTestHarnessXPCServiceDelegate.m | 29 + .../SecRemoteDevice.h | 30 + .../SecRemoteDevice.m | 262 +- .../SecRemoteDeviceProtocol.h | 87 + .../OctagonTestHarnessXPCService/main.m | 38 + .../Info.plist | 22 + .../Package.swift | 15 + .../OctagonTestHarnessXPCServiceProtocol.m | 5 + .../OctagonTestHarnessXPCServiceProtocol.h | 10 + .../Trieste/OctagonTriesteTests/Package.swift | 28 + .../OctagonTriesteTests/Package.xcconfig | 4 + .../Sources/OctagonTrieste/Octagon.swift | 3 + .../OctagonTriesteTests/OctagonTests.swift | 283 + .../remake-local-project.sh | 3 + .../BottledPeer/BottledPeer.swift | 280 + .../BottledPeer/EscrowKeys.swift | 381 + keychain/TrustedPeersHelper/Client.swift | 617 + keychain/TrustedPeersHelper/Container.swift | 3926 +++ .../TrustedPeersHelper/ContainerMap.swift | 233 + .../Container_MachineIDs.swift | 373 + .../CuttlefishAPIHelpers.swift | 55 + .../TrustedPeersHelper/CuttlefishErrors.swift | 32 + keychain/TrustedPeersHelper/Decrypter.swift | 32 + keychain/TrustedPeersHelper/Info.plist | 29 + .../TrustedPeersHelper/OctagonPeerKeys.swift | 57 + keychain/TrustedPeersHelper/Policy.swift | 456 + .../RecoveryKey/RecoverKeySet.swift | 346 + .../RecoveryKey/RecoveryKey.swift | 84 + .../SetValueTransformer.swift | 38 + .../TrustedPeersHelper/TPHObjcTranslation.h | 24 + .../TrustedPeersHelper/TPHObjcTranslation.m | 61 + .../TrustedPeersHelper-Bridging-Header.h | 57 + .../TrustedPeersHelper-entitlements.plist | 39 + .../.xccurrentversion | 8 + .../TrustedPeersHelper.xcdatamodel/contents | 65 + .../TrustedPeersHelper_2.xcdatamodel/contents | 75 + .../TrustedPeersHelperProtocol.h | 348 + .../TrustedPeersHelperProtocol.m | 300 + keychain/TrustedPeersHelper/Utils.swift | 60 + .../OTAuthenticatedCiphertext+SF.h | 4 +- .../OTAuthenticatedCiphertext+SF.m | 3 - .../categories}/OTPrivateKey+SF.h | 7 +- .../categories}/OTPrivateKey+SF.m | 23 +- keychain/TrustedPeersHelper/main.swift | 69 + .../proto/OTAuthenticatedCiphertext.proto | 0 .../proto/OTBottle.proto | 2 +- .../proto/OTBottleContents.proto | 0 .../proto/OTPrivateKey.proto | 0 .../TrustedPeersHelper/proto/OTRecovery.proto | 38 + .../OTAuthenticatedCiphertext.h | 0 .../OTAuthenticatedCiphertext.m | 0 .../proto/generated_source}/OTBottle.h | 6 +- .../proto/generated_source}/OTBottle.m | 36 +- .../generated_source}/OTBottleContents.h | 0 .../generated_source}/OTBottleContents.m | 0 .../proto/generated_source}/OTPrivateKey.h | 0 .../proto/generated_source}/OTPrivateKey.m | 0 .../proto/generated_source/OTRecovery.h | 45 + .../proto/generated_source/OTRecovery.m | 194 + .../proto/generated_source/Recovery.h | 45 + .../proto/generated_source/Recovery.m | 194 + .../ContainerSync.swift | 374 + .../FakeCuttlefish.swift | 758 + .../TrustedPeersHelperUnitTests}/Info.plist | 0 .../MockCuttlefish.swift | 169 + ...ustedPeersHelperUnitTests-BridgingHeader.h | 23 + .../TrustedPeersHelperUnitTests.swift | 2409 ++ keychain/analytics/C2Metric.proto | 186 + .../analytics/C2Metric/SECC2MPCloudKitInfo.h | 94 + .../analytics/C2Metric/SECC2MPCloudKitInfo.m | 644 + .../SECC2MPCloudKitOperationGroupInfo.h | 47 + .../SECC2MPCloudKitOperationGroupInfo.m | 209 + .../C2Metric/SECC2MPCloudKitOperationInfo.h | 53 + .../C2Metric/SECC2MPCloudKitOperationInfo.m | 259 + .../analytics/C2Metric/SECC2MPDeviceInfo.h | 81 + .../analytics/C2Metric/SECC2MPDeviceInfo.m | 502 + keychain/analytics/C2Metric/SECC2MPError.h | 53 + keychain/analytics/C2Metric/SECC2MPError.m | 262 + .../analytics/C2Metric/SECC2MPGenericEvent.h | 95 + .../analytics/C2Metric/SECC2MPGenericEvent.m | 369 + .../C2Metric/SECC2MPGenericEventMetric.h | 42 + .../C2Metric/SECC2MPGenericEventMetric.m | 177 + .../C2Metric/SECC2MPGenericEventMetricValue.h | 54 + .../C2Metric/SECC2MPGenericEventMetricValue.m | 277 + .../C2Metric/SECC2MPInternalTestConfig.h | 40 + .../C2Metric/SECC2MPInternalTestConfig.m | 159 + keychain/analytics/C2Metric/SECC2MPMetric.h | 149 + keychain/analytics/C2Metric/SECC2MPMetric.m | 562 + .../analytics/C2Metric/SECC2MPNetworkEvent.h | 263 + .../analytics/C2Metric/SECC2MPNetworkEvent.m | 1992 ++ .../analytics/C2Metric/SECC2MPServerInfo.h | 48 + .../analytics/C2Metric/SECC2MPServerInfo.m | 229 + keychain/analytics/CKKSLaunchSequence.h | 34 + keychain/analytics/CKKSLaunchSequence.m | 227 + keychain/analytics/CKKSPowerCollection.h | 1 + keychain/analytics/CKKSPowerCollection.m | 1 + keychain/analytics/SecC2DeviceInfo.h | 35 + keychain/analytics/SecC2DeviceInfo.m | 205 + keychain/analytics/SecEventMetric.h | 61 + keychain/analytics/SecEventMetric.m | 169 + keychain/analytics/SecEventMetric_private.h | 38 + keychain/analytics/SecMetrics.h | 39 + keychain/analytics/SecMetrics.m | 288 + .../TestResourceUsage.h} | 12 +- keychain/analytics/TestResourceUsage.m | 109 + .../analytics/Tests/CKKSLaunchSequenceTests.m | 59 + keychain/ckks/CKKS.h | 26 +- keychain/ckks/CKKS.m | 184 +- keychain/ckks/CKKSAPSReceiver.m | 206 - ...ateTracker.h => CKKSAccountStateTracker.h} | 69 +- ...ateTracker.m => CKKSAccountStateTracker.m} | 464 +- keychain/ckks/CKKSAnalytics.h | 118 +- keychain/ckks/CKKSAnalytics.m | 141 +- keychain/ckks/CKKSCloudKitClassDependencies.h | 40 + keychain/ckks/CKKSCloudKitClassDependencies.m | 44 + keychain/ckks/CKKSConstants.m | 172 + keychain/ckks/CKKSControl.h | 10 +- keychain/ckks/CKKSControl.m | 60 +- keychain/ckks/CKKSControlProtocol.h | 2 +- keychain/ckks/CKKSControlProtocol.m | 2 - keychain/ckks/CKKSCurrentItemPointer.h | 6 +- keychain/ckks/CKKSCurrentItemPointer.m | 19 +- keychain/ckks/CKKSCurrentKeyPointer.h | 48 +- keychain/ckks/CKKSCurrentKeyPointer.m | 83 +- keychain/ckks/CKKSDeviceStateEntry.h | 6 +- keychain/ckks/CKKSDeviceStateEntry.m | 62 +- .../CKKSFetchAllRecordZoneChangesOperation.h | 7 +- .../CKKSFetchAllRecordZoneChangesOperation.m | 248 +- keychain/ckks/CKKSFixups.h | 12 +- keychain/ckks/CKKSFixups.m | 123 +- keychain/ckks/CKKSGroupOperation.h | 4 + keychain/ckks/CKKSGroupOperation.m | 29 +- keychain/ckks/CKKSHealKeyHierarchyOperation.h | 4 + keychain/ckks/CKKSHealKeyHierarchyOperation.m | 33 +- keychain/ckks/CKKSHealTLKSharesOperation.h | 3 + keychain/ckks/CKKSHealTLKSharesOperation.m | 48 +- keychain/ckks/CKKSIncomingQueueEntry.m | 14 +- keychain/ckks/CKKSIncomingQueueOperation.h | 6 + keychain/ckks/CKKSIncomingQueueOperation.m | 145 +- keychain/ckks/CKKSItem.m | 36 +- keychain/ckks/CKKSKey.h | 103 +- keychain/ckks/CKKSKey.m | 680 +- keychain/ckks/CKKSKeychainBackedKey.h | 155 + keychain/ckks/CKKSKeychainBackedKey.m | 801 + keychain/ckks/CKKSKeychainView.h | 107 +- keychain/ckks/CKKSKeychainView.m | 1478 +- keychain/ckks/CKKSListenerCollection.h | 19 + keychain/ckks/CKKSListenerCollection.m | 75 + keychain/ckks/CKKSLocalSynchronizeOperation.h | 2 + keychain/ckks/CKKSLocalSynchronizeOperation.m | 15 +- keychain/ckks/CKKSLockStateTracker.h | 3 + keychain/ckks/CKKSLockStateTracker.m | 85 +- keychain/ckks/CKKSManifest.m | 54 +- keychain/ckks/CKKSManifestLeafRecord.m | 29 +- keychain/ckks/CKKSMirrorEntry.h | 4 + keychain/ckks/CKKSMirrorEntry.m | 29 +- keychain/ckks/CKKSNearFutureScheduler.h | 5 +- keychain/ckks/CKKSNearFutureScheduler.m | 52 +- keychain/ckks/CKKSNewTLKOperation.h | 9 +- keychain/ckks/CKKSNewTLKOperation.m | 221 +- keychain/ckks/CKKSOutgoingQueueEntry.h | 5 +- keychain/ckks/CKKSOutgoingQueueEntry.m | 20 +- keychain/ckks/CKKSOutgoingQueueOperation.h | 4 + keychain/ckks/CKKSOutgoingQueueOperation.m | 108 +- keychain/ckks/CKKSPeer.h | 41 +- keychain/ckks/CKKSPeer.m | 137 +- .../ckks/CKKSProcessReceivedKeysOperation.h | 24 +- .../ckks/CKKSProcessReceivedKeysOperation.m | 309 +- keychain/ckks/CKKSProvideKeySetOperation.h | 33 + keychain/ckks/CKKSProvideKeySetOperation.m | 48 + keychain/ckks/CKKSRateLimiter.h | 2 +- keychain/ckks/CKKSRateLimiter.m | 29 +- keychain/ckks/CKKSReachabilityTracker.h | 19 +- keychain/ckks/CKKSReachabilityTracker.m | 131 +- keychain/ckks/CKKSRecordHolder.h | 6 +- keychain/ckks/CKKSRecordHolder.m | 2 +- .../CKKSReencryptOutgoingItemsOperation.h | 4 + .../CKKSReencryptOutgoingItemsOperation.m | 13 +- keychain/ckks/CKKSResultOperation.m | 54 +- keychain/ckks/CKKSSIV.h | 31 +- keychain/ckks/CKKSSIV.m | 50 +- keychain/ckks/CKKSSQLDatabaseObject.h | 27 +- keychain/ckks/CKKSSQLDatabaseObject.m | 118 +- keychain/ckks/CKKSScanLocalItemsOperation.h | 3 + keychain/ckks/CKKSScanLocalItemsOperation.m | 54 +- keychain/ckks/CKKSSynchronizeOperation.h | 2 + keychain/ckks/CKKSSynchronizeOperation.m | 71 +- keychain/ckks/CKKSTLKShare.h | 93 +- keychain/ckks/CKKSTLKShare.m | 556 +- keychain/ckks/CKKSTLKShareRecord.h | 98 + keychain/ckks/CKKSTLKShareRecord.m | 475 + .../CKKSUpdateCurrentItemPointerOperation.m | 22 +- .../ckks/CKKSUpdateDeviceStateOperation.h | 3 + .../ckks/CKKSUpdateDeviceStateOperation.m | 37 +- keychain/ckks/CKKSViewManager.h | 71 +- keychain/ckks/CKKSViewManager.m | 696 +- keychain/ckks/CKKSZone.h | 36 +- keychain/ckks/CKKSZone.m | 300 +- keychain/ckks/CKKSZoneChangeFetcher.m | 135 +- keychain/ckks/CKKSZoneModifier.h | 65 + keychain/ckks/CKKSZoneModifier.m | 310 + keychain/ckks/CKKSZoneStateEntry.h | 21 +- keychain/ckks/CKKSZoneStateEntry.m | 20 +- keychain/ckks/CloudKitCategories.h | 3 + keychain/ckks/CloudKitCategories.m | 25 + keychain/ckks/CloudKitDependencies.h | 20 +- keychain/ckks/NSOperationCategories.h | 6 +- keychain/ckks/NSOperationCategories.m | 9 +- ...CKKSAPSReceiver.h => OctagonAPSReceiver.h} | 21 +- keychain/ckks/OctagonAPSReceiver.m | 376 + keychain/ckks/RateLimiter.h | 4 +- keychain/ckks/RateLimiter.m | 38 +- .../CKKSSerializedKey.h | 0 .../CKKSSerializedKey.m | 0 .../ckks/tests/CKKSAESSIVEncryptionTests.m | 47 +- keychain/ckks/tests/CKKSAPSHandlingTests.m | 61 +- keychain/ckks/tests/CKKSCloudKitTests.m | 22 +- .../ckks/tests/CKKSDeviceStateUploadTests.m | 132 +- keychain/ckks/tests/CKKSFetchTests.m | 194 + keychain/ckks/tests/CKKSLoggerTests.m | 41 +- keychain/ckks/tests/CKKSMockOctagonAdapter.h | 44 + keychain/ckks/tests/CKKSMockOctagonAdapter.m | 133 + .../ckks/tests/CKKSMockSOSPresentAdapter.h | 32 + .../ckks/tests/CKKSMockSOSPresentAdapter.m | 135 + .../ckks/tests/CKKSNearFutureSchedulerTests.m | 69 + keychain/ckks/tests/CKKSOperationTests.m | 3 +- keychain/ckks/tests/CKKSRateLimiterTests.m | 16 +- keychain/ckks/tests/CKKSSOSTests.m | 449 +- keychain/ckks/tests/CKKSSQLTests.m | 48 +- .../tests/CKKSTLKSharingEncryptionTests.m | 55 +- keychain/ckks/tests/CKKSTLKSharingTests.m | 478 +- keychain/ckks/tests/CKKSTests+API.m | 224 +- .../ckks/tests/CKKSTests+CurrentPointerAPI.m | 36 +- .../ckks/tests/CKKSTests+LockStateTracker.m | 109 + keychain/ckks/tests/CKKSTests+MultiZone.h | 58 + keychain/ckks/tests/CKKSTests+MultiZone.m | 693 + keychain/ckks/tests/CKKSTests.h | 1 + keychain/ckks/tests/CKKSTests.m | 974 +- .../tests/CloudKitKeychainSyncingFixupTests.m | 90 +- .../tests/CloudKitKeychainSyncingMockXCTest.h | 39 +- .../tests/CloudKitKeychainSyncingMockXCTest.m | 304 +- .../tests/CloudKitKeychainSyncingTestsBase.h | 9 +- .../tests/CloudKitKeychainSyncingTestsBase.m | 32 +- keychain/ckks/tests/CloudKitMockXCTest.h | 41 +- keychain/ckks/tests/CloudKitMockXCTest.m | 168 +- keychain/ckks/tests/MockCloudKit.h | 33 +- keychain/ckks/tests/MockCloudKit.m | 95 +- ...eiverTests.h => OctagonAPSReceiverTests.h} | 2 +- ...eiverTests.m => OctagonAPSReceiverTests.m} | 29 +- keychain/ckks/tests/RateLimiterTests.m | 29 +- .../ckks/tests/testrunner/KeychainCKKS.plist | 4 + keychain/ckksctl/ckksctl.m | 226 +- .../escrowrequest/EscrowRequestController.h | 29 + .../escrowrequest/EscrowRequestController.m | 227 + keychain/escrowrequest/EscrowRequestServer.h | 26 + keychain/escrowrequest/EscrowRequestServer.m | 295 + .../EscrowRequestServerHelpers.h | 10 + .../EscrowRequestServerHelpers.m | 21 + .../escrowrequest/EscrowRequestXPCProtocol.h | 32 + .../escrowrequest/EscrowRequestXPCProtocol.m | 53 + .../escrowrequest/EscrowRequestXPCServer.h | 30 + .../escrowrequest/EscrowRequestXPCServer.m | 76 + .../Framework/SecEscrowRequest.h | 45 + .../Framework/SecEscrowRequest.m | 248 + .../SecEscrowPendingRecord+KeychainSupport.h | 21 + .../SecEscrowPendingRecord+KeychainSupport.m | 191 + .../SecEscrowPendingRecord.proto | 34 + .../generated_source/SecEscrowPendingRecord.h | 87 + .../generated_source/SecEscrowPendingRecord.m | 494 + ...scrowRequestInformCloudServicesOperation.h | 19 + ...scrowRequestInformCloudServicesOperation.m | 135 + ...scrowRequestPerformEscrowEnrollOperation.h | 25 + ...scrowRequestPerformEscrowEnrollOperation.m | 184 + .../tests/MockSynchronousEscrowServer.h | 15 + .../tests/MockSynchronousEscrowServer.m | 108 + .../tests/SecEscrowRequestTests.m | 871 + .../tests/SecEscrowRequestsTests-Info.plist | 22 + keychain/ot/OT.h | 7 +- keychain/ot/OT.m | 51 +- keychain/ot/OTAuthKitAdapter.h | 35 + keychain/ot/OTAuthKitAdapter.m | 178 + keychain/ot/OTBottledPeer.m | 39 +- keychain/ot/OTBottledPeerRecord.h | 3 +- keychain/ot/OTBottledPeerRecord.m | 3 +- keychain/ot/OTBottledPeerSigned.m | 7 +- keychain/ot/OTBottledPeerState.h | 59 + keychain/ot/OTBottledPeerState.m | 35 + keychain/ot/OTCheckHealthOperation.h | 61 + keychain/ot/OTCheckHealthOperation.m | 178 + keychain/ot/OTClientStateMachine.h | 83 + keychain/ot/OTClientStateMachine.m | 369 + keychain/ot/OTClientVoucherOperation.h | 64 + keychain/ot/OTClientVoucherOperation.m | 131 + keychain/ot/OTClique.h | 321 + keychain/ot/OTClique.m | 1439 + keychain/ot/OTCloudStore.h | 14 +- keychain/ot/OTCloudStore.m | 39 +- keychain/ot/OTCloudStoreState.m | 18 +- keychain/ot/OTConstants.h | 35 + keychain/ot/OTConstants.m | 159 +- keychain/ot/OTContext.h | 7 +- keychain/ot/OTContext.m | 199 +- keychain/ot/OTContextRecord.h | 2 +- keychain/ot/OTControl.h | 181 +- keychain/ot/OTControl.m | 372 +- keychain/ot/OTControlProtocol.h | 174 +- keychain/ot/OTControlProtocol.m | 87 +- keychain/ot/OTCuttlefishAccountStateHolder.h | 52 + keychain/ot/OTCuttlefishAccountStateHolder.m | 260 + keychain/ot/OTCuttlefishContext.h | 197 + keychain/ot/OTCuttlefishContext.m | 2682 ++ keychain/ot/OTDefines.h | 91 +- keychain/ot/OTDefines.m | 35 + .../OTDetermineHSA2AccountStatusOperation.h | 25 + .../OTDetermineHSA2AccountStatusOperation.m | 97 + keychain/ot/OTDeviceInformation.h | 52 + keychain/ot/OTDeviceInformation.m | 68 + keychain/ot/OTDeviceInformationAdapter.h | 26 + keychain/ot/OTDeviceInformationAdapter.m | 101 + keychain/ot/OTEnsureOctagonKeyConsistency.h | 48 + keychain/ot/OTEnsureOctagonKeyConsistency.m | 140 + keychain/ot/OTEpochOperation.h | 50 + keychain/ot/OTEpochOperation.m | 84 + keychain/ot/OTEscrowKeys.h | 10 + keychain/ot/OTEscrowKeys.m | 136 +- keychain/ot/OTEstablishOperation.h | 47 + keychain/ot/OTEstablishOperation.m | 176 + keychain/ot/OTFetchCKKSKeysOperation.h | 33 + keychain/ot/OTFetchCKKSKeysOperation.m | 119 + keychain/ot/OTFetchViewsOperation.h | 45 + keychain/ot/OTFetchViewsOperation.m | 120 + keychain/ot/OTFollowup.h | 74 + keychain/ot/OTFollowup.m | 162 + keychain/ot/OTIdentity.h | 2 +- keychain/ot/OTIdentity.m | 6 +- keychain/ot/OTJoinWithVoucherOperation.h | 56 + keychain/ot/OTJoinWithVoucherOperation.m | 210 + keychain/ot/OTJoiningConfiguration.h | 69 + keychain/ot/OTJoiningConfiguration.m | 110 + keychain/ot/OTLeaveCliqueOperation.h | 43 + keychain/ot/OTLeaveCliqueOperation.m | 93 + keychain/ot/OTLocalCKKSResetOperation.h | 22 + keychain/ot/OTLocalCKKSResetOperation.m | 65 + keychain/ot/OTLocalCuttlefishReset.h | 45 + keychain/ot/OTLocalCuttlefishReset.m | 93 + keychain/ot/OTLocalStore.m | 20 +- keychain/ot/OTManager.h | 103 +- keychain/ot/OTManager.m | 1502 +- keychain/ot/OTOperationDependencies.h | 44 + keychain/ot/OTOperationDependencies.m | 33 + keychain/ot/OTPrepareOperation.h | 59 + keychain/ot/OTPrepareOperation.m | 195 + keychain/ot/OTRamping.h | 16 +- keychain/ot/OTRamping.m | 110 +- keychain/ot/OTRemovePeersOperation.h | 46 + keychain/ot/OTRemovePeersOperation.m | 90 + .../ot/OTResetCKKSZonesLackingTLKsOperation.h | 21 + .../ot/OTResetCKKSZonesLackingTLKsOperation.m | 132 + keychain/ot/OTResetOperation.h | 45 + keychain/ot/OTResetOperation.m | 95 + keychain/ot/OTSOSAdapter.h | 33 + keychain/ot/OTSOSAdapter.m | 378 + .../ot/OTSOSUpdatePreapprovalsOperation.h | 27 + .../ot/OTSOSUpdatePreapprovalsOperation.m | 125 + keychain/ot/OTSOSUpgradeOperation.h | 30 + keychain/ot/OTSOSUpgradeOperation.m | 436 + keychain/ot/OTSetRecoveryKeyOperation.h | 51 + keychain/ot/OTSetRecoveryKeyOperation.m | 123 + keychain/ot/OTStates.h | 172 + keychain/ot/OTStates.m | 244 + keychain/ot/OTTriggerEscrowUpdateOperation.h | 48 + keychain/ot/OTTriggerEscrowUpdateOperation.m | 85 + keychain/ot/OTUpdateTPHOperation.h | 24 + keychain/ot/OTUpdateTPHOperation.m | 154 + .../ot/OTUpdateTrustedDeviceListOperation.h | 26 + .../ot/OTUpdateTrustedDeviceListOperation.m | 150 + keychain/ot/OTUploadNewCKKSTLKsOperation.h | 23 + keychain/ot/OTUploadNewCKKSTLKsOperation.m | 176 + keychain/ot/OTVouchWithBottleOperation.h | 57 + keychain/ot/OTVouchWithBottleOperation.m | 146 + keychain/ot/OTVouchWithRecoveryKeyOperation.h | 54 + keychain/ot/OTVouchWithRecoveryKeyOperation.m | 140 + keychain/ot/ObjCImprovements.h | 36 + keychain/ot/OctagonCKKSPeerAdapter.h | 30 + keychain/ot/OctagonCKKSPeerAdapter.m | 242 + keychain/ot/OctagonCheckTrustStateOperation.h | 23 + keychain/ot/OctagonCheckTrustStateOperation.m | 214 + keychain/ot/OctagonControlServer.h | 23 + keychain/ot/OctagonControlServer.m | 70 +- keychain/ot/OctagonFlags.h | 37 + keychain/ot/OctagonFlags.m | 63 + keychain/ot/OctagonPendingFlag.h | 34 + keychain/ot/OctagonPendingFlag.m | 50 + keychain/ot/OctagonStateMachine.h | 104 + keychain/ot/OctagonStateMachine.m | 565 + keychain/ot/OctagonStateMachineHelpers.h | 88 + keychain/ot/OctagonStateMachineHelpers.m | 142 + keychain/ot/OctagonStateMachineObservers.h | 63 + keychain/ot/OctagonStateMachineObservers.m | 239 + keychain/ot/SFECPublicKey+SPKI.m | 53 - .../OTAccountMetadataClassC+KeychainSupport.h | 20 + .../OTAccountMetadataClassC+KeychainSupport.m | 163 + .../ot/categories/OctagonEscrowRecoverer.h | 18 + .../ot/proto/OTAccountMetadataClassC.proto | 46 + keychain/ot/proto/OTPairingMessage.proto | 61 + .../OTAccountMetadataClassC.h | 162 + .../OTAccountMetadataClassC.m | 445 + .../OTApplicantToSponsorRound2M1.h | 52 + .../OTApplicantToSponsorRound2M1.m | 264 + .../proto/generated_source/OTPairingMessage.h | 53 + .../proto/generated_source/OTPairingMessage.m | 298 + .../ot/proto/generated_source/OTSOSMessage.h | 48 + .../ot/proto/generated_source/OTSOSMessage.m | 229 + .../OTSponsorToApplicantRound1M2.h | 39 + .../OTSponsorToApplicantRound1M2.m | 139 + .../OTSponsorToApplicantRound2M2.h | 48 + .../OTSponsorToApplicantRound2M2.m | 226 + keychain/ot/proto/source/OTSOSMessage.h | 48 + keychain/ot/proto/source/OTSOSMessage.m | 229 + .../tests/OTBottledPeerUpdateBottlesTests.m | 324 + keychain/ot/tests/OTCliqueTests.m | 238 + keychain/ot/tests/OTCloudStoreTests.m | 13 +- keychain/ot/tests/OTContextTests.m | 2 +- keychain/ot/tests/OTCuttlefishContextTests.m | 103 + keychain/ot/tests/OTEscrowKeyTests.m | 39 + keychain/ot/tests/OTFollowupTests.m | 19 + keychain/ot/tests/OTLocalStoreTests.m | 6 +- .../ot/tests/OTLockStateNetworkingTests.m | 197 +- keychain/ot/tests/OTRampingTests.m | 129 +- keychain/ot/tests/OTTestsBase.h | 35 +- keychain/ot/tests/OTTestsBase.m | 73 +- keychain/ot/tests/gen_test_plist.py | 74 + .../octagon/OctagonDataPersistenceTests.swift | 169 + .../ot/tests/octagon/OctagonTestMocks.swift | 41 + .../ot/tests/octagon/OctagonTests+CKKS.swift | 69 + .../OctagonTests+CloudKitAccount.swift | 186 + .../octagon/OctagonTests+CoreFollowUp.swift | 276 + .../octagon/OctagonTests+DeviceList.swift | 514 + .../octagon/OctagonTests+ErrorHandling.swift | 440 + .../octagon/OctagonTests+EscrowRecovery.swift | 1357 + .../octagon/OctagonTests+HealthCheck.swift | 841 + .../octagon/OctagonTests+RecoveryKey.swift | 1159 + .../ot/tests/octagon/OctagonTests+Reset.swift | 301 + .../ot/tests/octagon/OctagonTests+SOS.swift | 184 + .../octagon/OctagonTests+SOSUpgrade.swift | 1268 + .../octagon/OctagonTests-BridgingHeader.h | 88 + .../ot/tests/octagon/OctagonTests-Info.plist | 22 + keychain/ot/tests/octagon/OctagonTests.swift | 2731 ++ .../octagon/OctagonTestsXPCConnections.swift | 64 + .../OctagonPairingTests+Piggybacking.swift | 830 + ...OctagonPairingTests+ProxMultiClients.swift | 1581 + .../OctagonPairingTests+ProximitySetup.swift | 1954 ++ .../octagon/Pairing/OctagonPairingTests.swift | 334 + .../ot/tests/octagon/TestsObjcTranslation.h | 30 + .../ot/tests/octagon/TestsObjcTranslation.m | 109 + keychain/otctl/EscrowRequestCLI.h | 19 + keychain/otctl/EscrowRequestCLI.m | 90 + keychain/otctl/OTControlCLI.h | 44 + keychain/otctl/OTControlCLI.m | 476 + keychain/otctl/otctl-Entitlements.plist | 2 + keychain/otctl/otctl.1 | 15 + keychain/otctl/otctl.m | 601 +- .../otpaird/Info.plist | 5 +- keychain/otpaird/OTPairingClient.h | 7 + keychain/otpaird/OTPairingClient.m | 60 + keychain/otpaird/OTPairingConstants.h | 40 + keychain/otpaird/OTPairingPacketContext.h | 12 + keychain/otpaird/OTPairingPacketContext.m | 96 + keychain/otpaird/OTPairingService.h | 14 + keychain/otpaird/OTPairingService.m | 456 + keychain/otpaird/OTPairingSession.h | 25 + keychain/otpaird/OTPairingSession.m | 55 + .../com.apple.security.otpaird.iphoneos.plist | 21 + .../com.apple.security.otpaird.watchos.plist | 23 + keychain/otpaird/main.m | 167 + .../otpaird/otpaird.iphoneos.entitlements | 37 + keychain/otpaird/otpaird.watchos.entitlements | 34 + keychain/tpctl/main.swift | 793 + keychain/tpctl/tpctl-bridging-header.h | 17 + keychain/tpctl/tpctl-entitlements.plist | 12 + keychain/tpctl/tpctl-objc.h | 13 + keychain/tpctl/tpctl-objc.m | 55 + keychain/tpctl/tpctl.8 | 28 + keychain/tppolicy/main.m | 93 + libsecurity_smime/lib/CMSDecoder.c | 13 +- libsecurity_smime/lib/CMSEncoder.c | 7 +- libsecurity_smime/lib/SecCmsBase.h | 500 - libsecurity_smime/lib/SecCmsContentInfo.h | 208 - libsecurity_smime/lib/SecCmsDigestedData.h | 77 - libsecurity_smime/lib/SecCmsEnvelopedData.h | 71 - libsecurity_smime/lib/SecCmsMessage.h | 152 - libsecurity_smime/lib/SecCmsSignerInfo.h | 265 - libsecurity_smime/lib/SecSMIME.h | 56 - libsecurity_smime/lib/cert.c | 724 - libsecurity_smime/lib/cert.h | 8 +- libsecurity_smime/lib/cmsattr.c | 2 + libsecurity_smime/lib/cmscipher.c | 2 - libsecurity_smime/lib/cmsdecode.c | 185 +- libsecurity_smime/lib/cmsdigest.c | 6 +- libsecurity_smime/lib/cmspubkey.c | 9 +- libsecurity_smime/lib/cmsrecinfo.c | 303 +- libsecurity_smime/lib/cmssigdata.c | 2 +- libsecurity_smime/lib/cmssiginfo.c | 227 +- libsecurity_smime/lib/crypto-embedded.c | 42 +- libsecurity_smime/lib/cryptohi.c | 548 - libsecurity_smime/libCMS.xcodeproj/.gitignore | 2 - .../libCMS.xcodeproj/project.pbxproj | 966 - ntlm/ntlmBlobPriv.c | 6 + protocol/SecProtocol.c | 1919 +- protocol/SecProtocolConfiguration.h | 174 + protocol/SecProtocolConfiguration.m | 402 + protocol/SecProtocolConfigurationTest.m | 431 + protocol/SecProtocolHelper.m | 339 + protocol/SecProtocolHelperTest.m | 35 + protocol/SecProtocolInternal.h | 135 + protocol/SecProtocolMetadata.h | 77 +- protocol/SecProtocolOptions.h | 224 +- protocol/SecProtocolPriv.h | 1289 +- protocol/SecProtocolTest.m | 1110 + protocol/SecProtocolTypes.h | 171 +- protocol/SecProtocolTypes.m | 511 +- protocol/SecProtocolTypesPriv.h | 127 + protocol/test_data/builtins.json | 46 + protocol/test_data/example1.json | 50 + .../Certificate.strings | Bin 26038 -> 26036 bytes .../CloudKeychain.strings | Bin 11506 -> 11514 bytes .../{English.lproj => en.lproj}/OID.strings | Bin .../SharedWebCredentials.strings | Bin .../{English.lproj => en.lproj}/Trust.strings | Bin 16592 -> 17214 bytes .../Security/SecRandomP.h => rio.yml | 0 secacltests/sec_acl_stress.c | 19 +- secacltests/secacltests-entitlements.plist | 2 + secdtests/secdtests-entitlements.plist | 2 + secdxctests/KeychainAPITests.m | 142 +- secdxctests/KeychainCryptoTests.m | 70 +- secdxctests/KeychainEntitlementsTest.m | 155 +- secdxctests/KeychainXCTest.h | 3 +- secdxctests/KeychainXCTest.m | 38 +- sectask/SecEntitlements.h | 10 + sectask/SecTask.c | 26 +- sectask/SecTask.h | 5 +- sectask/SecTaskPriv.h | 17 +- sectask/regressions/sectask-10-sectask.c | 4 +- sectask/regressions/sectask_regressions.h | 2 +- .../security-sysdiagnose.entitlements.plist | 2 + security-sysdiagnose/security-sysdiagnose.m | 8 +- securityd/doc/securityd.1 | 17 +- securityd/etc/com.apple.securityd.sb | 64 + .../project.pbxproj | 24 +- .../securityd_service/main.c | 21 +- .../securityd_service/service.entitlements | 2 + securityd/src/acl_keychain.cpp | 4 +- securityd/src/agentquery.cpp | 23 +- securityd/src/agentquery.h | 2 +- securityd/src/connection.cpp | 47 +- securityd/src/csproxy.cpp | 586 - securityd/src/csproxy.h | 179 - securityd/src/dbcrypto.cpp | 10 +- securityd/src/kcdatabase.cpp | 38 +- securityd/src/kcdatabase.h | 2 +- securityd/src/main.cpp | 39 +- securityd/src/notifications.cpp | 2 +- securityd/src/process.cpp | 7 +- securityd/src/process.h | 22 +- securityd/src/securityd.entitlements | 12 + securityd/src/securityd.order | 2 - securityd/src/server.cpp | 49 +- securityd/src/server.h | 9 +- securityd/src/session.cpp | 13 +- securityd/src/tokencache.cpp | 3 +- securityd/src/transition.cpp | 104 +- securityd/src/util.h | 36 + securityd/src/util.m | 31 + sslViewer/SSLViewer.c | 36 +- sslViewer/ioSock.c | 6 +- sslViewer/sslAppUtils.cpp | 16 +- sslViewer/sslEcdsa.cpp | 41 +- sslViewer/sslServer.cpp | 87 +- supd/Tests/NSDate+SFAnalyticsTests.m | 41 + supd/Tests/SFAnalyticsTests.m | 108 +- supd/Tests/SupdTests.m | 74 +- supd/main.m | 13 + supd/securityuploadd-Entitlements.plist | 12 +- supd/securityuploadd-sim.plist | 25 + supd/supd.h | 9 + supd/supd.m | 275 +- supd/supdProtocol.h | 2 + supdctl/main.m | 63 +- tests/SecDbBackupTests/Entitlements.plist | 32 + tests/SecDbBackupTests/Info.plist | 22 + tests/SecDbBackupTests/SecDbBackupTests.m | 477 + tests/SecDbBackupTests/SecDbBackupTests.plist | 27 + .../DaemonTests/LoggingServerTests.m | 31 + tests/TrustTests/EvaluationTests/CTTests.m | 1841 ++ .../TrustTests/EvaluationTests/CTTests_data.h | 35 +- tests/TrustTests/EvaluationTests/ECTests.m | 148 + .../TrustTests/EvaluationTests/ECTests_data.h | 1056 + .../EvaluationTests/EvaluationBasicTests.m | 174 + .../EvaluationBasicTests_data.h | 611 + .../TrustTests/EvaluationTests/KeySizeTests.m | 382 + .../EvaluationTests/KeySizeTests_data.h | 1362 + tests/TrustTests/EvaluationTests/NISTTests.m | 52 + .../EvaluationTests/NameConstraintsTests.m | 543 + .../NameConstraintsTests_data.h | 104 +- .../EvaluationTests/PathParseTests.m | 105 + .../EvaluationTests/PathParseTests_data.h | 55 + .../EvaluationTests/PathScoringTests.m | 112 +- .../EvaluationTests/PathScoringTests_data.h | 8 +- .../TrustTests/EvaluationTests/PolicyTests.m | 99 + .../EvaluationTests/SSLPolicyTests.m | 399 + .../EvaluationTests/SSLPolicyTests_data.h | 622 + .../EvaluationTests/SignatureAlgorithmTests.m | 474 + .../SignatureAlgorithmTests_data.h | 1117 + .../EvaluationTests/TrustEvaluationTestCase.h | 50 + .../EvaluationTests/TrustEvaluationTestCase.m | 330 + .../EvaluationTests/VerifyDateTests.m | 412 + .../EvaluationTests/VerifyDateTests_data.h | 828 + tests/TrustTests/EvaluationTests/iAPTests.m | 72 + .../EvaluationTests/iAPTests_data.h | 111 + .../CertificateInterfaceTests.m | 504 + .../CertificateInterfaceTests_data.h | 997 + .../FrameworkTests/CertificateParseTests.m | 132 + .../FrameworkTests/TrustFrameworkTestCase.h | 31 + .../FrameworkTests/TrustFrameworkTestCase.m | 37 + .../FrameworkTests/TrustInterfaceTests.m | 894 + .../FrameworkTests/TrustInterfaceTests_data.h | 537 + .../TrustSettingsInterfaceTests.m | 126 + tests/TrustTests/Info.plist | 22 + ...ownCriticalCertificateExtensionTest2EE.cer | Bin 0 -> 954 bytes .../TestCopyProperties_ios.plist | 771 + .../TrustAnchorRootCertificate.cer | Bin 0 -> 843 bytes .../TestCopyProperties_ios-data/int2048B.cer | Bin 0 -> 1005 bytes .../TestCopyProperties_ios-data/intSHA1.cer | Bin 0 -> 1171 bytes .../TestCopyProperties_ios-data/leaf1024.cer | Bin 0 -> 946 bytes .../TestCopyProperties_ios-data/leaf512.cer | Bin 0 -> 798 bytes .../TestCopyProperties_ios-data/leafMD5.cer | Bin 0 -> 1121 bytes .../TestCopyProperties_ios-data/leafSHA1.cer | Bin 0 -> 1286 bytes .../TestCopyProperties_ios-data/root2048.cer | Bin 0 -> 996 bytes .../rootSHA256.cer | Bin 0 -> 976 bytes .../TestCopyProperties_ios-data/rootSSL.cer | Bin 0 -> 990 bytes .../systemRoot.cer | Bin 0 -> 947 bytes tests/TrustTests/TestMacroConversions.h | 42 + tests/TrustTests/TestRunners/AppDelegate.h | 15 + tests/TrustTests/TestRunners/AppDelegate.m | 49 + .../AppIcon.appiconset/Contents.json | 98 + .../TestRunners/Assets.xcassets/Contents.json | 6 + .../Base.lproj/LaunchScreen.storyboard | 10 +- .../TestRunners}/Base.lproj/Main.storyboard | 12 +- tests/TrustTests/TestRunners/Info.plist | 45 + tests/TrustTests/TestRunners/Main.storyboard | 7 + tests/TrustTests/TestRunners/ViewController.h | 13 + tests/TrustTests/TestRunners/ViewController.m | 21 + tests/TrustTests/TestRunners/appmain.m | 14 + tests/TrustTests/TestRunners/main.m | 219 + .../TestRunners/trusttests_entitlements.plist | 18 + tests/TrustTests/TrustEvaluationTestHelpers.h | 64 + tests/TrustTests/TrustEvaluationTestHelpers.m | 504 + tests/TrustTests/gen_test_plist.py | 51 + tests/secdmockaks/aks_real_witness.c | 36 + tests/secdmockaks/aks_real_witness.h | 9 + tests/secdmockaks/mockaks.h | 42 +- tests/secdmockaks/mockaks.m | 399 +- .../{secdmockaks.m => mockaksKeychain.m} | 218 +- tests/secdmockaks/mockaksWatchDog.m | 44 + tests/secdmockaks/mockaksxcbase.h | 19 + tests/secdmockaks/mockaksxcbase.m | 90 + trust/SecCertificate.h | 11 +- trust/SecCertificatePriv.h | 25 +- trust/SecPolicy.h | 8 +- trust/SecPolicyPriv.h | 76 +- trust/SecTrust.h | 54 +- trust/SecTrustPriv.h | 51 +- trust/SecTrustSettingsPriv.h | 10 +- xcconfig/PlatformFeatures.xcconfig | 40 +- xcconfig/PlatformLibraries.xcconfig | 135 +- xcconfig/Security.xcconfig | 23 +- xcconfig/lib_ios.xcconfig | 11 +- xcconfig/macos_legacy_lib.xcconfig | 2 +- xcconfig/security_framework.xcconfig | 5 + xcconfig/swift_binary.xcconfig | 18 + xcconfig/swift_binary_shim.xcconfig | 6 + 2068 files changed, 149480 insertions(+), 75845 deletions(-) create mode 100644 .swiftlint.yml create mode 100644 Analytics/NSDate+SFAnalytics.h create mode 100644 Analytics/NSDate+SFAnalytics.m rename {libsecurity_smime/lib => CMS}/CMSDecoder.h (76%) rename {libsecurity_smime/lib => CMS}/CMSEncoder.h (72%) rename {OSX/libsecurity_cms/lib => CMS}/CMSPrivate.h (93%) rename {OSX/sec/Security => CMS}/SecCMS.h (97%) rename {OSX/libsecurity_smime/lib => CMS}/SecCmsBase.h (88%) create mode 100644 CMS/SecCmsContentInfo.h rename {libsecurity_smime/lib => CMS}/SecCmsDecoder.h (60%) rename {libsecurity_smime/lib => CMS}/SecCmsDigestContext.h (68%) rename {OSX/libsecurity_smime/lib => CMS}/SecCmsDigestedData.h (87%) rename {libsecurity_smime/lib => CMS}/SecCmsEncoder.h (61%) rename {libsecurity_smime/lib => CMS}/SecCmsEncryptedData.h (91%) rename {OSX/libsecurity_smime/lib => CMS}/SecCmsEnvelopedData.h (84%) rename {OSX/libsecurity_smime/lib => CMS}/SecCmsMessage.h (75%) rename {libsecurity_smime/lib => CMS}/SecCmsRecipientInfo.h (55%) rename {libsecurity_smime/lib => CMS}/SecCmsSignedData.h (79%) rename {OSX/libsecurity_smime/lib => CMS}/SecCmsSignerInfo.h (72%) rename {OSX/libsecurity_smime/lib => CMS}/SecSMIME.h (88%) rename OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h => KeychainCircle/KCInitialMessageData.proto (82%) create mode 100644 KeychainCircle/KCJoiningAcceptSession+Internal.h create mode 100644 KeychainCircle/KCJoiningRequestCircleSession.m rename KeychainCircle/{KCJoiningRequestSession.m => KCJoiningRequestSecretSession.m} (62%) create mode 100644 KeychainCircle/KCJoiningRequestSession+Internal.h create mode 100644 KeychainCircle/Tests/FakeSOSControl.h create mode 100644 KeychainCircle/Tests/FakeSOSControl.m create mode 100644 KeychainCircle/generated_source/KCInitialMessageData.h create mode 100644 KeychainCircle/generated_source/KCInitialMessageData.m delete mode 100644 KeychainEntitledTestApp_mac/Base.lproj/Main.storyboard create mode 100644 Modules/Security.macOS.private.modulemap delete mode 100644 MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m delete mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist delete mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.h delete mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m delete mode 100644 MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorProtocol.h delete mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h delete mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.m delete mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworkingProtocol.h delete mode 100644 MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceSimulatorTests.m create mode 100644 OCMockUmbrella/Info.plist create mode 100644 OCMockUmbrella/OCMockUmbrella.h rename OSX/lib/en.lproj/{authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings => authorization.dfr.prompts.strings} (98%) delete mode 100644 OSX/libsecurity_apple_csp/lib/algmaker.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafeAsymmetric.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafeContext.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafeKeyGen.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafePKCS1.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafePKCS1.h delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafeSymmetric.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafecsp.h delete mode 100644 OSX/libsecurity_apple_csp/lib/bsafecspi.h delete mode 100644 OSX/libsecurity_apple_csp/lib/bsobjects.h delete mode 100644 OSX/libsecurity_apple_csp/lib/memory.cpp delete mode 100644 OSX/libsecurity_apple_csp/lib/miscalgorithms.cpp create mode 100644 OSX/libsecurity_authorization/lib/AuthorizationTrampolinePriv.h delete mode 100644 OSX/libsecurity_cdsa_utilities/lib/uniformrandom.h delete mode 100644 OSX/libsecurity_cms/lib/CMSDecoder.h delete mode 100644 OSX/libsecurity_cms/lib/CMSEncoder.h delete mode 100644 OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj create mode 100644 OSX/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper.entitlements delete mode 100644 OSX/libsecurity_codesigning/lib/SecCodeHostLib.c delete mode 100644 OSX/libsecurity_codesigning/lib/SecCodeHostLib.h delete mode 100644 OSX/libsecurity_codesigning/lib/csgeneric.cpp delete mode 100644 OSX/libsecurity_codesigning/lib/csgeneric.h create mode 100644 OSX/libsecurity_codesigning/lib/legacydevid.cpp create mode 100644 OSX/libsecurity_codesigning/lib/legacydevid.h delete mode 100644 OSX/libsecurity_cryptkit/ckutils/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/Makefile.common delete mode 100644 OSX/libsecurity_cryptkit/ckutils/atomTime/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/atomTime/atomTime.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/badsig/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/badsig/badsig.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/blobtest/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/blobtest/blobtest.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/cfileTest/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/cfileTest/cfileTest.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/ckutilsPlatform.h delete mode 100644 OSX/libsecurity_cryptkit/ckutils/giantAsmBench/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/giantAsmBench/giantAsmBench.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/giantBench/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/giantBench/giantBench.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/giantDvt/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/giantDvt/giantDvt.c delete mode 100644 OSX/libsecurity_cryptkit/ckutils/sigTime/Makefile delete mode 100644 OSX/libsecurity_cryptkit/ckutils/sigTime/sigTime.cpp delete mode 100644 OSX/libsecurity_cryptkit/lib/CipherFileDES.c delete mode 100644 OSX/libsecurity_cryptkit/lib/CipherFileDES.h delete mode 100644 OSX/libsecurity_cryptkit/lib/CipherFileFEED.c delete mode 100644 OSX/libsecurity_cryptkit/lib/CipherFileFEED.h delete mode 100644 OSX/libsecurity_cryptkit/lib/CipherFileTypes.h delete mode 100644 OSX/libsecurity_cryptkit/lib/ECDSA_Verify_Prefix.h delete mode 100644 OSX/libsecurity_cryptkit/lib/ckDES.c delete mode 100644 OSX/libsecurity_cryptkit/lib/ckDES.h delete mode 100644 OSX/libsecurity_cryptkit/lib/ckMD5.c delete mode 100644 OSX/libsecurity_cryptkit/lib/ckSHA1_priv.c delete mode 100644 OSX/libsecurity_cryptkit/lib/ckSHA1_priv.h delete mode 100644 OSX/libsecurity_cryptkit/lib/curveParamDataOld.h delete mode 100644 OSX/libsecurity_cryptkit/lib/engineNSA127.c delete mode 100644 OSX/libsecurity_cryptkit/lib/feeCipherFile.c delete mode 100644 OSX/libsecurity_cryptkit/lib/feeCipherFile.h delete mode 100644 OSX/libsecurity_cryptkit/lib/feeCipherFileAtom.c delete mode 100644 OSX/libsecurity_cryptkit/lib/feeDES.c delete mode 100644 OSX/libsecurity_cryptkit/lib/feeDES.h delete mode 100644 OSX/libsecurity_cryptkit/lib/giantPort_PPC.c delete mode 100644 OSX/libsecurity_cryptkit/lib/giantPort_PPC.h delete mode 100644 OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.h delete mode 100644 OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.s delete mode 100644 OSX/libsecurity_cryptkit/lib/giantPort_i486.h rename OSX/libsecurity_smime/docs/{libsecurity_smime.plist => libsecurity_cms.plist} (100%) rename OSX/libsecurity_smime/docs/{libsecurity_smime.txt => libsecurity_cms.txt} (100%) delete mode 100644 OSX/libsecurity_smime/lib/SecCMS.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsContentInfo.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsDecoder.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsDigestContext.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsEncoder.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsEncryptedData.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h delete mode 100644 OSX/libsecurity_smime/lib/SecCmsSignedData.h delete mode 100644 OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj create mode 100644 OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+session.m delete mode 100644 OSX/libsecurity_transform/100-sha2.m delete mode 100644 OSX/libsecurity_transform/custom.mm delete mode 100644 OSX/libsecurity_utilities/lib/devrandom.cpp delete mode 100644 OSX/libsecurity_utilities/lib/devrandom.h delete mode 100644 OSX/libsecurity_utilities/lib/mach_notify.c create mode 100644 OSX/libsecurity_utilities/lib/mach_notify.defs delete mode 100644 OSX/libsecurity_utilities/lib/mach_notify.h delete mode 100644 OSX/libsecurity_utilities/lib/machrunloopserver.cpp delete mode 100644 OSX/libsecurity_utilities/lib/machrunloopserver.h delete mode 100644 OSX/libsecurity_utilities/lib/streams.cpp delete mode 100644 OSX/libsecurity_utilities/lib/streams.h delete mode 100644 OSX/libsecurity_utilities/lib/vproc++.cpp delete mode 100644 OSX/libsecurity_utilities/lib/vproc++.h delete mode 100644 OSX/libsecurityd/mig/cshosting.defs delete mode 120000 OSX/sec/ProjectHeaders/SOSCircle/Tool delete mode 120000 OSX/sec/ProjectHeaders/Security/CKBridge delete mode 120000 OSX/sec/ProjectHeaders/Security/SecureObjectSync delete mode 120000 OSX/sec/ProjectHeaders/Security/Tool delete mode 120000 OSX/sec/ProjectHeaders/SecurityTool delete mode 100644 OSX/sec/SOSCircle/Regressions/sc-25-soskeygen.c delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.h delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.h delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h delete mode 100644 OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m delete mode 100644 OSX/sec/SOSCircle/Tool/keychain_log.m delete mode 100644 OSX/sec/Security/Regressions/secitem/si-15-certificate.c delete mode 100644 OSX/sec/Security/Regressions/secitem/si-16-ec-certificate.c delete mode 100644 OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m delete mode 100644 OSX/sec/Security/Regressions/secitem/si-20-sectrust.c delete mode 100644 OSX/sec/Security/Regressions/secitem/si-20-sectrust.h delete mode 100644 OSX/sec/Security/Regressions/secitem/si-24-sectrust-nist.c create mode 100644 OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.h create mode 100644 OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.m delete mode 100644 OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.h delete mode 100644 OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m delete mode 100644 OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.c delete mode 100644 OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.h delete mode 100644 OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m rename OSX/sec/Security/{SecKey.c => SecKey.m} (84%) delete mode 100644 OSX/sec/Security/oids.c create mode 100644 OSX/sec/ipc/com.apple.recovery_securityd.plist create mode 100644 OSX/sec/ipc/com.apple.secitemd.plist delete mode 100644 OSX/sec/ipc/server_security_helpers.c create mode 100644 OSX/sec/ipc/server_security_helpers.m rename protocol/SecProtocol.h => OSX/sec/ipc/util.h (80%) rename OSX/{libsecurity_transform/custom.h => sec/ipc/util.m} (81%) delete mode 100644 OSX/sec/securityd/AsymKeybagBackup.m create mode 100644 OSX/sec/securityd/CheckV12DevEnabled.h create mode 100644 OSX/sec/securityd/CheckV12DevEnabled.m create mode 100644 OSX/sec/securityd/PolicyReporter.h create mode 100644 OSX/sec/securityd/PolicyReporter.m delete mode 100644 OSX/sec/securityd/Regressions/secd-31-keychain-bad.m create mode 100644 OSX/sec/securityd/Regressions/secd-33-keychain-backup.m create mode 100644 OSX/sec/securityd/SecAKSObjCWrappers.h create mode 100644 OSX/sec/securityd/SecAKSObjCWrappers.m create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/SecDbBackupRecoverySet.proto create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBag.h create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBag.m create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.h create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.m create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.h create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.m create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.h create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.m create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.h create mode 100644 OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.m create mode 100644 OSX/sec/securityd/SecDbBackupManager.h create mode 100644 OSX/sec/securityd/SecDbBackupManager.m create mode 100644 OSX/sec/securityd/SecDbBackupManager_Internal.h create mode 100644 OSX/sec/securityd/SecDbKeychainMetadataKeyStore.h create mode 100644 OSX/sec/securityd/SecDbKeychainMetadataKeyStore.m rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{SecDbKeychainAKSSerializedWrappedKey.proto => SecDbKeychainSerializedAKSWrappedKey.proto} (100%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedAKSWrappedKey.h (95%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedAKSWrappedKey.m (97%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedItemV7.h (98%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedItemV7.m (98%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedMetadata.h (95%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedMetadata.m (98%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedSecretData.h (83%) rename OSX/sec/securityd/SecDbKeychainV7-protobufs/{ => generated_source}/SecDbKeychainSerializedSecretData.m (76%) create mode 100644 OSX/sec/securityd/SecTrustExceptionResetCount.h create mode 100644 OSX/sec/securityd/SecTrustExceptionResetCount.m rename OSX/shared_regressions/si-18-certificate-parse/{TODOFailureCerts => ExtensionFailureCerts}/parse_fail_length_63.cer (100%) rename OSX/shared_regressions/si-18-certificate-parse/{TODOFailureCerts => ExtensionFailureCerts}/parse_fail_tag_27.cer (100%) rename OSX/shared_regressions/si-18-certificate-parse/{TODOFailureCerts => ExtensionFailureCerts}/parse_fail_tag_28.cer (100%) rename OSX/shared_regressions/si-18-certificate-parse/{TODOFailureCerts => ExtensionFailureCerts}/parse_fail_tag_32.cer (100%) rename OSX/shared_regressions/si-18-certificate-parse/{TODOFailureCerts => ExtensionFailureCerts}/parse_fail_tag_36.cer (100%) rename OSX/shared_regressions/si-18-certificate-parse/{TODOFailureCerts => ParseFailureCerts}/parse_fail_keyusage_extra_bit.cer (100%) create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-ca-serial+invalid+policysmime+complete.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-ca-serial+invalid+policyssl+complete.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-clientauth.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-codesign.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-smime.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-ssl.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-timestamp.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-clientauth.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-codesign.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-smime.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-ssl.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-timestamp.cer create mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/Valid-root.cer delete mode 100644 OSX/shared_regressions/si-20-sectrust-policies-data/ids_prod.cer delete mode 100644 OSX/shared_regressions/si-20-sectrust-policies.m create mode 100644 OSX/shared_regressions/si-44-seckey-skv.m delete mode 100644 OSX/shared_regressions/si-82-seccertificate-ct.c delete mode 100644 OSX/shared_regressions/si-82-sectrust-ct.m create mode 100644 OSX/trustd/trustd_spi.c create mode 100644 OSX/trustd/trustd_spi.h rename OSX/utilities/{src => }/NSURL+SOSPlistStore.h (100%) rename OSX/utilities/{src => }/NSURL+SOSPlistStore.m (100%) rename OSX/utilities/{src => }/SecADWrapper.c (93%) rename OSX/utilities/{src => }/SecADWrapper.h (100%) rename OSX/utilities/{src => }/SecAKSWrappers.c (70%) rename OSX/utilities/{src => }/SecAKSWrappers.h (76%) rename OSX/utilities/{src => }/SecAppleAnchor.c (100%) rename OSX/utilities/{src => }/SecAppleAnchorPriv.h (100%) rename OSX/utilities/{src => }/SecAutorelease.h (100%) rename OSX/utilities/{src => }/SecAutorelease.m (100%) rename OSX/utilities/{src => }/SecBuffer.c (100%) rename OSX/utilities/{src => }/SecBuffer.h (100%) rename OSX/utilities/{src => }/SecCFCCWrappers.c (100%) rename OSX/utilities/{src => }/SecCFCCWrappers.h (100%) rename OSX/utilities/{src => }/SecCFError.c (100%) rename OSX/utilities/{src => }/SecCFError.h (99%) rename OSX/utilities/{src => }/SecCFRelease.h (100%) rename OSX/utilities/{src => }/SecCFWrappers.c (100%) rename OSX/utilities/{src => }/SecCFWrappers.h (98%) create mode 100644 OSX/utilities/SecCoreAnalytics.h create mode 100644 OSX/utilities/SecCoreAnalytics.m rename OSX/utilities/{src => }/SecCoreCrypto.c (100%) rename OSX/utilities/{src => }/SecCoreCrypto.h (100%) rename OSX/utilities/{src => }/SecDb.c (90%) rename OSX/utilities/{src => }/SecDb.h (95%) rename OSX/utilities/{src => }/SecDispatchRelease.h (100%) rename OSX/utilities/{src => }/SecFileLocations.c (85%) rename OSX/utilities/{src => }/SecFileLocations.h (86%) rename OSX/utilities/{src => }/SecIOFormat.h (100%) rename OSX/utilities/{src => }/SecInternalRelease.c (100%) rename OSX/utilities/{src => }/SecInternalReleasePriv.h (100%) rename OSX/utilities/{src => }/SecNSAdditions.h (100%) rename OSX/utilities/{src => }/SecNSAdditions.m (100%) rename OSX/utilities/{src => }/SecPLWrappers.h (100%) rename OSX/utilities/{src => }/SecPLWrappers.m (94%) rename OSX/utilities/{src => }/SecPaddingConfigurations.c (98%) rename OSX/utilities/{src => }/SecPaddingConfigurationsPriv.h (100%) rename OSX/utilities/{src => }/SecSCTUtils.c (100%) rename OSX/utilities/{src => }/SecSCTUtils.h (100%) create mode 100644 OSX/utilities/SecTapToRadar.h create mode 100644 OSX/utilities/SecTapToRadar.m rename OSX/utilities/{src => }/SecTrace.c (100%) rename OSX/utilities/{src => }/SecTrace.h (100%) rename OSX/utilities/{src => }/SecXPCError.c (100%) rename OSX/utilities/{src => }/SecXPCError.h (100%) create mode 100644 OSX/utilities/SecXPCHelper.h create mode 100644 OSX/utilities/SecXPCHelper.m rename OSX/utilities/{src => }/array_size.h (100%) rename OSX/utilities/{src => }/debugging.c (92%) rename OSX/utilities/{src => }/debugging.h (93%) rename OSX/utilities/{src => }/debugging_test.h (100%) rename OSX/utilities/{src => }/der_array.c (100%) rename OSX/utilities/{src => }/der_boolean.c (100%) rename OSX/utilities/{src => }/der_data.c (100%) rename OSX/utilities/{src => }/der_date.c (100%) rename OSX/utilities/{src => }/der_date.h (100%) rename OSX/utilities/{src => }/der_dictionary.c (100%) rename OSX/utilities/{src => }/der_null.c (100%) rename OSX/utilities/{src => }/der_number.c (100%) rename OSX/utilities/{src => }/der_plist.c (100%) rename OSX/utilities/{src => }/der_plist.h (100%) rename OSX/utilities/{src => }/der_plist_internal.c (100%) rename OSX/utilities/{src => }/der_plist_internal.h (100%) rename OSX/utilities/{src => }/der_set.c (100%) rename OSX/utilities/{src => }/der_set.h (100%) rename OSX/utilities/{src => }/der_string.c (100%) rename OSX/utilities/{src => }/fileIo.c (100%) rename OSX/utilities/{src => }/fileIo.h (100%) create mode 100644 OSX/utilities/iCloudKeychainTrace.c rename OSX/{libsecurity_smime/regressions/smime_regressions.h => utilities/iCloudKeychainTrace.h} (82%) rename OSX/utilities/{src => }/iOSforOSX-SecAttr.c (97%) rename OSX/utilities/{src => }/iOSforOSX-SecRandom.c (94%) rename OSX/utilities/{src => }/iOSforOSX.c (97%) rename OSX/utilities/{src => }/iOSforOSX.h (93%) rename OSX/utilities/{src => }/sec_action.c (100%) rename OSX/utilities/{src => }/sec_action.h (100%) rename OSX/utilities/{src => }/simulate_crash.c (81%) rename OSX/utilities/{src => }/sqlutils.h (100%) delete mode 100644 OSX/utilities/src/iCloudKeychainTrace.c delete mode 100644 OSX/utilities/src/iCloudKeychainTrace.h create mode 100644 OSX/utilities/test/Info.plist create mode 100644 OSX/utilities/test/SecTapToRadarTests.m create mode 100644 OSX/utilities/test/SecXPCHelperTests.m delete mode 120000 OSX/utilities/utilities create mode 100644 README-TRIESTE.md create mode 100644 RegressionTests/SecurityLocalKeychain.plist create mode 100644 SecExperiment/SecExperiment.m create mode 100644 SecExperiment/SecExperimentInternal.h create mode 100644 SecExperiment/SecExperimentPriv.h create mode 100644 SecExperiment/TLSAssets/Info.plist create mode 100644 SecExperiment/TLSAssets/Makefile create mode 100644 SecExperiment/TLSAssets/TLSConfig.plist create mode 100644 SecExperiment/test/SecExperimentTests.m delete mode 100644 Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/B3656633-AB83-4153-B404-DE14DBDC5ED6.plist delete mode 100644 Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/Info.plist create mode 100644 Security.xcodeproj/xcshareddata/xcschemes/OctagonTests.xcscheme create mode 100644 Security.xcodeproj/xcshareddata/xcschemes/TrustTests_ios.xcscheme create mode 100644 Security.xcodeproj/xcshareddata/xcschemes/TrustTests_macos.xcscheme create mode 100644 Security.xcodeproj/xcshareddata/xcschemes/secdmockaks.xcscheme delete mode 100644 SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA certificates.pem delete mode 100644 SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA.certAuthorityConfig delete mode 100644 SecurityTests/ssl-policy-certs/SSLTrustPolicyTestCA.p12 delete mode 100644 SecurityTool/APPLE_LICENSE rename {OSX/libsecurity_cms => SecurityTool/macOS}/APPLE_LICENSE (100%) rename SecurityTool/{ => macOS}/access_utils.c (100%) rename SecurityTool/{ => macOS}/access_utils.h (100%) rename SecurityTool/{ => macOS}/authz.c (100%) rename SecurityTool/{ => macOS}/authz.h (100%) rename SecurityTool/{ => macOS}/cmsutil.c (100%) rename SecurityTool/{ => macOS}/cmsutil.h (100%) rename SecurityTool/{ => macOS}/createFVMaster.c (100%) rename SecurityTool/{ => macOS}/createFVMaster.h (100%) rename SecurityTool/{ => macOS}/db_commands.cpp (100%) rename SecurityTool/{ => macOS}/db_commands.h (100%) rename SecurityTool/{ => macOS}/display_error_code.c (100%) rename SecurityTool/{ => macOS}/display_error_code.h (100%) rename SecurityTool/{ => macOS}/identity_find.h (100%) rename SecurityTool/{ => macOS}/identity_find.m (95%) rename SecurityTool/{ => macOS}/identity_prefs.c (89%) rename SecurityTool/{ => macOS}/identity_prefs.h (100%) rename SecurityTool/{ => macOS}/key_create.c (100%) rename SecurityTool/{ => macOS}/key_create.h (100%) rename SecurityTool/{ => macOS}/keychain_add.c (90%) rename SecurityTool/{ => macOS}/keychain_add.h (100%) rename SecurityTool/{ => macOS}/keychain_create.c (100%) rename SecurityTool/{ => macOS}/keychain_create.h (100%) rename SecurityTool/{ => macOS}/keychain_delete.c (99%) rename SecurityTool/{ => macOS}/keychain_delete.h (100%) rename SecurityTool/{ => macOS}/keychain_export.h (100%) rename SecurityTool/{ => macOS}/keychain_export.m (100%) rename SecurityTool/{ => macOS}/keychain_find.c (96%) rename SecurityTool/{ => macOS}/keychain_find.h (100%) rename SecurityTool/{ => macOS}/keychain_import.c (100%) rename SecurityTool/{ => macOS}/keychain_import.h (100%) rename SecurityTool/{ => macOS}/keychain_list.c (100%) rename SecurityTool/{ => macOS}/keychain_list.h (100%) rename SecurityTool/{ => macOS}/keychain_lock.c (100%) rename SecurityTool/{ => macOS}/keychain_lock.h (100%) rename SecurityTool/{ => macOS}/keychain_recode.c (100%) rename SecurityTool/{ => macOS}/keychain_recode.h (100%) rename SecurityTool/{ => macOS}/keychain_set_settings.c (100%) rename SecurityTool/{ => macOS}/keychain_set_settings.h (100%) rename SecurityTool/{ => macOS}/keychain_show_info.c (100%) rename SecurityTool/{ => macOS}/keychain_show_info.h (100%) rename SecurityTool/{ => macOS}/keychain_unlock.c (100%) rename SecurityTool/{ => macOS}/keychain_unlock.h (100%) rename SecurityTool/{ => macOS}/keychain_utilities.c (94%) rename SecurityTool/{ => macOS}/keychain_utilities.h (92%) rename SecurityTool/{ => macOS}/leaks.c (100%) rename SecurityTool/{ => macOS}/leaks.h (100%) rename SecurityTool/{ => macOS}/mds_install.cpp (100%) rename SecurityTool/{ => macOS}/mds_install.h (100%) rename SecurityTool/{ => macOS}/readline.c (100%) rename SecurityTool/{ => macOS}/readline_cssm.h (100%) rename SecurityTool/{ => macOS}/requirement.c (97%) rename SecurityTool/{ => macOS}/requirement.h (100%) rename SecurityTool/{ => macOS}/security.1 (97%) rename SecurityTool/{ => macOS}/security.c (96%) rename SecurityTool/{ => macOS}/security_tool.h (100%) rename SecurityTool/{ => macOS}/smartcards.h (100%) rename SecurityTool/{ => macOS}/smartcards.m (100%) rename SecurityTool/{ => macOS}/srCdsaUtils.cpp (100%) rename SecurityTool/{ => macOS}/srCdsaUtils.h (100%) rename SecurityTool/{ => macOS}/translocate.c (100%) rename SecurityTool/{ => macOS}/translocate.h (100%) rename SecurityTool/{ => macOS}/trust_settings_impexp.c (100%) rename SecurityTool/{ => macOS}/trust_settings_impexp.h (100%) rename SecurityTool/{ => macOS}/trusted_cert_add.c (92%) rename SecurityTool/{ => macOS}/trusted_cert_add.h (100%) rename SecurityTool/{ => macOS}/trusted_cert_dump.c (94%) rename SecurityTool/{ => macOS}/trusted_cert_dump.h (100%) rename OSX/sec/securityd/AsymKeybagBackup.h => SecurityTool/macOS/trusted_cert_ssl.h (60%) create mode 100644 SecurityTool/macOS/trusted_cert_ssl.m rename SecurityTool/{ => macOS}/trusted_cert_utils.c (81%) rename SecurityTool/{ => macOS}/trusted_cert_utils.h (85%) rename SecurityTool/{ => macOS}/user_trust_enable.cpp (100%) rename SecurityTool/{ => macOS}/user_trust_enable.h (100%) rename SecurityTool/{ => macOS}/verify_cert.c (85%) rename SecurityTool/{ => macOS}/verify_cert.h (100%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/KeychainCheck.h (100%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/KeychainCheck.m (83%) rename {OSX/sec/SOSCircle/Tool => SecurityTool/sharedTool}/NSFileHandle+Formatting.h (100%) rename {OSX/sec/SOSCircle/Tool => SecurityTool/sharedTool}/NSFileHandle+Formatting.m (100%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/SecurityCommands.h (95%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/SecurityTool.c (98%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/SecurityTool.h (100%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/add_internet_password.c (99%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/builtin_commands.h (88%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/codesign.c (99%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/ct_exceptions.m (100%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/digest_calc.c (97%) rename SecurityTool/{ => sharedTool/iOS}/entitlements.plist (79%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool/iOS}/security.1 (99%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/keychain_add.c (94%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/keychain_backup.c (95%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/keychain_find.m (86%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/keychain_util.c (99%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/keychain_util.h (100%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/leaks.c (99%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/leaks.h (100%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/log_control.c (99%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool/macOS}/entitlements.plist (70%) rename {OSX/security2 => SecurityTool/sharedTool/macOS}/security2.1 (100%) rename {OSX/utilities/SecurityTool => SecurityTool/sharedTool}/not_on_this_platorm.c (100%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/pkcs12_util.c (98%) rename OSX/libsecurity_cdsa_utilities/lib/uniformrandom.cpp => SecurityTool/sharedTool/policy_dryrun.h (77%) create mode 100644 SecurityTool/sharedTool/policy_dryrun.m rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/print_cert.c (100%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/print_cert.h (100%) rename {OSX/utilities/SecurityTool => SecurityTool/sharedTool}/readline.c (100%) rename {OSX/utilities/SecurityTool => SecurityTool/sharedTool}/readline.h (100%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/scep.c (95%) rename SecurityTool/{ => sharedTool}/security_tool_commands.c (73%) rename {OSX/utilities/SecurityTool => SecurityTool/sharedTool}/security_tool_commands.h (97%) rename {OSX/utilities/SecurityTool => SecurityTool/sharedTool}/security_tool_commands_table.h (95%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/show_certificates.c (98%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/sos.m (67%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/spc.c (99%) rename SecurityTool/{ => sharedTool}/sub_commands.h (75%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/syncbubble.m (99%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/tool_errors.h (97%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/trust_update.m (69%) rename {OSX/sec/Security/Tool => SecurityTool/sharedTool}/verify_cert.c (100%) rename {OSX/sec/SecurityTool => SecurityTool/sharedTool}/whoami.m (100%) create mode 100644 SharedMocks/NSXPCConnectionMock.h create mode 100644 SharedMocks/NSXPCConnectionMock.m delete mode 100755 ckcdiagnose/ckcdiagnose.sh create mode 100644 featureflags/Info.plist create mode 100644 featureflags/Security.plist create mode 120000 header_symlinks/Security/CKKSControl.h create mode 120000 header_symlinks/Security/CKKSControlProtocol.h create mode 120000 header_symlinks/Security/CMSDecoder.h create mode 120000 header_symlinks/Security/CMSEncoder.h create mode 120000 header_symlinks/Security/CMSPrivate.h delete mode 120000 header_symlinks/Security/CSCommonPriv.h create mode 120000 header_symlinks/Security/CipherSuite.h create mode 120000 header_symlinks/Security/LocalKeychainAnalytics.h create mode 120000 header_symlinks/Security/OTClique.h create mode 120000 header_symlinks/Security/OTControl.h create mode 120000 header_symlinks/Security/OTControlProtocol.h create mode 120000 header_symlinks/Security/OTJoiningConfiguration.h create mode 120000 header_symlinks/Security/SFAnalytics.h create mode 120000 header_symlinks/Security/SFAnalyticsActivityTracker.h create mode 120000 header_symlinks/Security/SFAnalyticsDefines.h create mode 120000 header_symlinks/Security/SFAnalyticsMultiSampler.h create mode 120000 header_symlinks/Security/SFAnalyticsSQLiteStore.h create mode 120000 header_symlinks/Security/SFAnalyticsSampler.h create mode 120000 header_symlinks/Security/SFSQLite.h create mode 120000 header_symlinks/Security/SOSAnalytics.h create mode 120000 header_symlinks/Security/SOSControlHelper.h create mode 120000 header_symlinks/Security/SecAccessControl.h create mode 120000 header_symlinks/Security/SecAccessControlPriv.h create mode 120000 header_symlinks/Security/SecAsn1Coder.h create mode 120000 header_symlinks/Security/SecAsn1Templates.h create mode 120000 header_symlinks/Security/SecAsn1Types.h create mode 120000 header_symlinks/Security/SecBase64.h create mode 120000 header_symlinks/Security/SecCFAllocator.h create mode 120000 header_symlinks/Security/SecCMS.h create mode 120000 header_symlinks/Security/SecCmsBase.h create mode 120000 header_symlinks/Security/SecCmsContentInfo.h create mode 120000 header_symlinks/Security/SecCmsDecoder.h create mode 120000 header_symlinks/Security/SecCmsDigestContext.h create mode 120000 header_symlinks/Security/SecCmsDigestedData.h create mode 120000 header_symlinks/Security/SecCmsEncoder.h create mode 120000 header_symlinks/Security/SecCmsEncryptedData.h create mode 120000 header_symlinks/Security/SecCmsEnvelopedData.h create mode 120000 header_symlinks/Security/SecCmsMessage.h create mode 120000 header_symlinks/Security/SecCmsRecipientInfo.h create mode 120000 header_symlinks/Security/SecCmsSignedData.h create mode 120000 header_symlinks/Security/SecCmsSignerInfo.h delete mode 120000 header_symlinks/Security/SecCodeHost.h delete mode 120000 header_symlinks/Security/SecCodeSigner.h create mode 120000 header_symlinks/Security/SecDH.h create mode 120000 header_symlinks/Security/SecECKey.h create mode 120000 header_symlinks/Security/SecEntitlements.h create mode 120000 header_symlinks/Security/SecExperimentPriv.h create mode 120000 header_symlinks/Security/SecFramework.h create mode 120000 header_symlinks/Security/SecImportExportPriv.h create mode 120000 header_symlinks/Security/SecInternalReleasePriv.h create mode 120000 header_symlinks/Security/SecItemBackup.h create mode 120000 header_symlinks/Security/SecLogging.h create mode 120000 header_symlinks/Security/SecOTR.h create mode 120000 header_symlinks/Security/SecOTRSession.h create mode 120000 header_symlinks/Security/SecPaddingConfigurationsPriv.h create mode 120000 header_symlinks/Security/SecPasswordGenerate.h delete mode 120000 header_symlinks/Security/SecProtocol.h create mode 120000 header_symlinks/Security/SecProtocolConfiguration.h create mode 120000 header_symlinks/Security/SecProtocolPriv.h create mode 120000 header_symlinks/Security/SecRecoveryKey.h delete mode 120000 header_symlinks/Security/SecRequirementPriv.h create mode 120000 header_symlinks/Security/SecSMIME.h create mode 120000 header_symlinks/Security/SecServerEncryptionSupport.h delete mode 120000 header_symlinks/Security/SecStaticCodePriv.h create mode 120000 header_symlinks/Security/SecTaskPriv.h create mode 120000 header_symlinks/Security/SecXPCError.h create mode 120000 header_symlinks/Security/SecureObjectSync/SOSBackupSliceKeyBag.h create mode 120000 header_symlinks/Security/SecureObjectSync/SOSCloudCircle.h create mode 120000 header_symlinks/Security/SecureObjectSync/SOSCloudCircleInternal.h create mode 120000 header_symlinks/Security/SecureObjectSync/SOSPeerInfo.h create mode 120000 header_symlinks/Security/SecureObjectSync/SOSTypes.h create mode 120000 header_symlinks/Security/SecureObjectSync/SOSViews.h create mode 120000 header_symlinks/Security/SecureTransport.h create mode 120000 header_symlinks/Security/SecureTransportPriv.h create mode 120000 header_symlinks/Security/certExtensionTemplates.h create mode 120000 header_symlinks/Security/der_plist.h delete mode 120000 header_symlinks/Security/keyTemplates.h create mode 120000 header_symlinks/Security/ocspTemplates.h create mode 120000 header_symlinks/Security/oidsalg.h delete mode 120000 header_symlinks/Security/oidsattr.h create mode 120000 header_symlinks/Security/secasn1t.h create mode 120000 header_symlinks/Security/sslTypes.h create mode 120000 header_symlinks/iOS/Security/NtlmGenerator.h create mode 120000 header_symlinks/iOS/Security/SecCertificateInternal.h create mode 120000 header_symlinks/iOS/Security/SecECKeyPriv.h create mode 120000 header_symlinks/iOS/Security/SecEMCSPriv.h create mode 120000 header_symlinks/iOS/Security/SecOTRDHKey.h create mode 120000 header_symlinks/iOS/Security/SecOTRErrors.h create mode 120000 header_symlinks/iOS/Security/SecOTRMath.h create mode 120000 header_symlinks/iOS/Security/SecOTRPacketData.h create mode 120000 header_symlinks/iOS/Security/SecOTRPackets.h create mode 120000 header_symlinks/iOS/Security/SecOTRSessionPriv.h create mode 120000 header_symlinks/iOS/Security/SecPBKDF.h create mode 120000 header_symlinks/iOS/Security/SecRSAKey.h create mode 120000 header_symlinks/iOS/Security/SecSCEP.h create mode 120000 header_symlinks/iOS/Security/SecTrustStore.h create mode 120000 header_symlinks/iOS/Security/SecureObjectSync/SOSPeerInfoV2.h delete mode 120000 header_symlinks/iOS/Security/oidsbase.h create mode 120000 header_symlinks/iOS/Security/oidsocsp.h delete mode 120000 header_symlinks/iOS/Security/osxcode.h create mode 120000 header_symlinks/iOS/Security/pbkdf2.h create mode 120000 header_symlinks/iOS/Security/vmdh.h delete mode 120000 header_symlinks/macOS/Security/CMSDecoder.h delete mode 120000 header_symlinks/macOS/Security/CMSEncoder.h delete mode 120000 header_symlinks/macOS/Security/CMSPrivate.h create mode 120000 header_symlinks/macOS/Security/CSCommonPriv.h delete mode 120000 header_symlinks/macOS/Security/CipherSuite.h delete mode 120000 header_symlinks/macOS/Security/SecASN1Coder.h delete mode 120000 header_symlinks/macOS/Security/SecASN1Templates.h delete mode 120000 header_symlinks/macOS/Security/SecAccessControl.h delete mode 120000 header_symlinks/macOS/Security/SecAsn1Types.h create mode 120000 header_symlinks/macOS/Security/SecAssessment.h create mode 120000 header_symlinks/macOS/Security/SecBreadcrumb.h delete mode 120000 header_symlinks/macOS/Security/SecCmsBase.h delete mode 120000 header_symlinks/macOS/Security/SecCmsContentInfo.h delete mode 120000 header_symlinks/macOS/Security/SecCmsDecoder.h delete mode 120000 header_symlinks/macOS/Security/SecCmsDigestContext.h delete mode 120000 header_symlinks/macOS/Security/SecCmsDigestedData.h delete mode 120000 header_symlinks/macOS/Security/SecCmsEncoder.h delete mode 120000 header_symlinks/macOS/Security/SecCmsEncryptedData.h delete mode 120000 header_symlinks/macOS/Security/SecCmsEnvelopedData.h delete mode 120000 header_symlinks/macOS/Security/SecCmsMessage.h delete mode 120000 header_symlinks/macOS/Security/SecCmsRecipientInfo.h delete mode 120000 header_symlinks/macOS/Security/SecCmsSignedData.h delete mode 120000 header_symlinks/macOS/Security/SecCmsSignerInfo.h create mode 120000 header_symlinks/macOS/Security/SecCodeHost.h create mode 120000 header_symlinks/macOS/Security/SecCodeSigner.h create mode 120000 header_symlinks/macOS/Security/SecExternalSourceTransform.h create mode 120000 header_symlinks/macOS/Security/SecFDERecoveryAsymmetricCrypto.h create mode 120000 header_symlinks/macOS/Security/SecKeychainItemExtendedAttributes.h create mode 120000 header_symlinks/macOS/Security/SecManifest.h create mode 120000 header_symlinks/macOS/Security/SecNullTransform.h create mode 120000 header_symlinks/macOS/Security/SecPassword.h create mode 120000 header_symlinks/macOS/Security/SecRandomP.h create mode 120000 header_symlinks/macOS/Security/SecRecoveryPassword.h create mode 120000 header_symlinks/macOS/Security/SecRequirementPriv.h delete mode 120000 header_symlinks/macOS/Security/SecSMIME.h create mode 120000 header_symlinks/macOS/Security/SecStaticCodePriv.h create mode 120000 header_symlinks/macOS/Security/SecTransformInternal.h create mode 120000 header_symlinks/macOS/Security/SecTranslocate.h create mode 120000 header_symlinks/macOS/Security/SecureDownload.h create mode 120000 header_symlinks/macOS/Security/SecureDownloadInternal.h delete mode 120000 header_symlinks/macOS/Security/SecureTransport.h create mode 120000 header_symlinks/macOS/Security/asn1Templates.h delete mode 120000 header_symlinks/macOS/Security/certExtensionTemplates.h create mode 120000 header_symlinks/macOS/Security/eisl.h create mode 120000 header_symlinks/macOS/Security/keyTemplates.h delete mode 120000 header_symlinks/macOS/Security/ocspTemplates.h delete mode 120000 header_symlinks/macOS/Security/oids.h delete mode 120000 header_symlinks/macOS/Security/oidsalg.h create mode 120000 header_symlinks/macOS/Security/oidsattr.h delete mode 120000 header_symlinks/macOS/Security/secasn1t.h create mode 120000 header_symlinks/macOS/Security/tsaSupport.h create mode 100644 keychain/KeychainSettings/Info.plist create mode 100644 keychain/KeychainSettings/KeychainSettings.h create mode 100644 keychain/KeychainSettings/KeychainSettings.m create mode 100644 keychain/KeychainSettings/KeychainSettings.plist create mode 100644 keychain/KeychainSettings/KeychainSettingsCKKSViews.plist rename OSX/libsecurity_cms/Info-security_cms.plist => keychain/KeychainSettings/KeychainSettingsOctagonPeers.plist (65%) create mode 100644 keychain/SecImportExportPriv.h rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/CKBridge/SOSCloudKeychainClient.c (81%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/CKBridge/SOSCloudKeychainClient.h (95%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/CKBridge/SOSCloudKeychainConstants.c (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/CKBridge/SOSCloudKeychainConstants.h (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/CKDSimulatedStore.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/CKDSimulatedStore.m (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/CKDSimulatedAccount.h (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/CKDSimulatedAccount.m (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSCircle_regressions.h (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSRegressionUtilities.h (98%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSRegressionUtilities.m (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSTestDataSource.c (99%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSTestDataSource.h (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSTestDevice.c (99%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/SOSTestDevice.h (98%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-130-resignationticket.c (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-150-backupkeyderivation.c (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-150-ring.m (96%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-153-backupslicekeybag.c (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-20-keynames.m (96%) create mode 100644 keychain/SecureObjectSync/Regressions/sc-25-soskeygen.c rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-30-peerinfo.c (95%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-31-peerinfo-simplefuzz.c (89%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-40-circle.c (97%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-42-circlegencount.c (92%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-45-digestvector.c (99%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Regressions/sc-kvstool.m (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSARCDefines.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccount.h (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccount.m (91%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountBackup.m (79%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountCircles.m (60%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountCloudParameters.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountCredentials.m (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountDer.m (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountFullPeerInfo.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountGetSet.m (94%) create mode 100644 keychain/SecureObjectSync/SOSAccountGhost.h create mode 100644 keychain/SecureObjectSync/SOSAccountGhost.m create mode 100644 keychain/SecureObjectSync/SOSAccountLog.h rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountLog.m (82%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountPeers.m (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountPersistence.m (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountPriv.h (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountRecovery.m (57%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountRingUpdate.m (72%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountRings.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountSync.m (61%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTransaction.h (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTransaction.m (73%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrust.h (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrust.m (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Circle.h (86%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Circle.m (57%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Expansion.h (89%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Expansion.m (62%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Identity.h (93%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Identity.m (88%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Retirement.h (83%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic+Retirement.m (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic.h (89%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountTrustClassic.m (85%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountUpdate.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAccountViewSync.m (84%) create mode 100644 keychain/SecureObjectSync/SOSAuthKitHelpers.h rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSAuthKitHelpers.m (50%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSBackupEvent.c (99%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSBackupEvent.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSBackupInformation.h (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSBackupInformation.m (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSBackupSliceKeyBag.h (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSBackupSliceKeyBag.m (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSChangeTracker.c (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSChangeTracker.h (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircle.c (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircle.h (93%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircleDer.c (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircleDer.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCirclePriv.h (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircleRings.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircleV2.c (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCircleV2.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCloudCircle.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCloudCircle.m (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCloudCircleInternal.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCoder.c (99%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSCoder.h (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSConcordanceTrust.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSControlHelper.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSControlHelper.m (90%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSControlServer.h (50%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSControlServer.m (70%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSDataSource.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSDigestVector.c (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSDigestVector.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSECWrapUnwrap.c (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSEngine.c (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSEngine.h (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSEnginePriv.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSEnsureBackup.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSEnsureBackup.m (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSExports.exp-in (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSFullPeerInfo.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSFullPeerInfo.m (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSGenCount.c (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSGenCount.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSInternal.h (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSInternal.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSKVSKeys.h (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSKVSKeys.m (99%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSKeyedPubKeyIdentifier.c (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSKeyedPubKeyIdentifier.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSManifest.c (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSManifest.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSMessage.c (99%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSMessage.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeer.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeer.m (99%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerCoder.h (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerCoder.m (86%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfo.h (91%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfo.m (88%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoCollections.c (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoCollections.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoDER.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoDER.m (85%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoInternal.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoPriv.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoRingState.h (72%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoRingState.m (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoV2.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerInfoV2.m (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerOTRTimer.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerOTRTimer.m (91%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerRateLimiter.h (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPeerRateLimiter.m (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPersist.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPiggyback.h (93%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPiggyback.m (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSPlatform.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRecoveryKeyBag.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRecoveryKeyBag.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRing.h (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingBackup.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingBackup.m (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingBasic.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingBasic.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingConcordanceTrust.c (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingConcordanceTrust.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingDER.c (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingDER.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingPeerInfoUtils.c (71%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingPeerInfoUtils.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingRecovery.h (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingRecovery.m (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingTypes.h (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingTypes.m (94%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingUtils.c (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingUtils.h (98%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingV0.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSRingV0.m (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransport.h (85%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransport.m (97%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportBackupPeer.h (91%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportBackupPeer.m (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportCircle.h (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportCircle.m (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportCircleCK.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportCircleCK.m (92%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportCircleKVS.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportCircleKVS.m (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportKeyParameter.h (95%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportKeyParameter.m (87%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportMessage.h (89%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportMessage.m (82%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportMessageKVS.h (86%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTransportMessageKVS.m (91%) create mode 100644 keychain/SecureObjectSync/SOSTrustedDeviceAttributes.h create mode 100644 keychain/SecureObjectSync/SOSTrustedDeviceAttributes.m rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSTypes.h (80%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSUserKeygen.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSUserKeygen.m (88%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSViews.exp-in (89%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSViews.h (100%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/SOSViews.m (92%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/accountCirclesViewsPrint.h (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/accountCirclesViewsPrint.m (91%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/keychain_log.h (96%) create mode 100644 keychain/SecureObjectSync/Tool/keychain_log.m rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/keychain_sync.h (98%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/keychain_sync.m (98%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/keychain_sync_test.h (86%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/keychain_sync_test.m (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/recovery_key.h (96%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/recovery_key.m (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/secToolFileIO.c (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/secToolFileIO.h (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/secViewDisplay.c (98%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/secViewDisplay.h (100%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/syncbackup.h (95%) rename {OSX/sec/SOSCircle => keychain/SecureObjectSync}/Tool/syncbackup.m (96%) rename {OSX/sec/SOSCircle => keychain}/SecureObjectSync/ViewList.list (87%) rename {MultiDeviceSimulator/MultiDeviceSimulatorTests => keychain/SecurityUnitTests}/Info.plist (100%) create mode 100644 keychain/SecurityUnitTests/SecItemTests.m rename SecurityUnitTests/SecurityUnitTests.m => keychain/SecurityUnitTests/SecKeyTests.m (96%) create mode 100644 keychain/SecurityUnitTests/SecurityUnitTests.entitlements create mode 100644 keychain/Trieste/OctagonTestHarness/Info.plist create mode 100644 keychain/Trieste/OctagonTestHarness/OctagonTestHarness.exp create mode 100644 keychain/Trieste/OctagonTestHarness/OctagonTestHarness.h create mode 100644 keychain/Trieste/OctagonTestHarness/OctagonTestHarness.m create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/Entitlements.plist rename {MultiDeviceSimulator/DeviceSimulator => keychain/Trieste/OctagonTestHarnessXPCService}/Info.plist (87%) create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.h create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.m create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.h create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.m create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.h rename MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m => keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.m (50%) create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDeviceProtocol.h create mode 100644 keychain/Trieste/OctagonTestHarnessXPCService/main.m create mode 100644 keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Info.plist create mode 100644 keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Package.swift create mode 100644 keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/OctagonTestHarnessXPCServiceProtocol.m create mode 100644 keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/include/OctagonTestHarnessXPCServiceProtocol.h create mode 100644 keychain/Trieste/OctagonTriesteTests/Package.swift create mode 100644 keychain/Trieste/OctagonTriesteTests/Package.xcconfig create mode 100644 keychain/Trieste/OctagonTriesteTests/Sources/OctagonTrieste/Octagon.swift create mode 100644 keychain/Trieste/OctagonTriesteTests/Tests/OctagonTriesteTests/OctagonTests.swift create mode 100755 keychain/Trieste/OctagonTriesteTests/remake-local-project.sh create mode 100644 keychain/TrustedPeersHelper/BottledPeer/BottledPeer.swift create mode 100644 keychain/TrustedPeersHelper/BottledPeer/EscrowKeys.swift create mode 100644 keychain/TrustedPeersHelper/Client.swift create mode 100644 keychain/TrustedPeersHelper/Container.swift create mode 100644 keychain/TrustedPeersHelper/ContainerMap.swift create mode 100644 keychain/TrustedPeersHelper/Container_MachineIDs.swift create mode 100644 keychain/TrustedPeersHelper/CuttlefishAPIHelpers.swift create mode 100644 keychain/TrustedPeersHelper/CuttlefishErrors.swift create mode 100644 keychain/TrustedPeersHelper/Decrypter.swift create mode 100644 keychain/TrustedPeersHelper/Info.plist create mode 100644 keychain/TrustedPeersHelper/OctagonPeerKeys.swift create mode 100644 keychain/TrustedPeersHelper/Policy.swift create mode 100644 keychain/TrustedPeersHelper/RecoveryKey/RecoverKeySet.swift create mode 100644 keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift create mode 100644 keychain/TrustedPeersHelper/SetValueTransformer.swift create mode 100644 keychain/TrustedPeersHelper/TPHObjcTranslation.h create mode 100644 keychain/TrustedPeersHelper/TPHObjcTranslation.m create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelper-entitlements.plist create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/.xccurrentversion create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper.xcdatamodel/contents create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper_2.xcdatamodel/contents create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h create mode 100644 keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.m create mode 100644 keychain/TrustedPeersHelper/Utils.swift rename keychain/{ot => TrustedPeersHelper/categories}/OTAuthenticatedCiphertext+SF.h (93%) rename keychain/{ot => TrustedPeersHelper/categories}/OTAuthenticatedCiphertext+SF.m (98%) rename keychain/{ot => TrustedPeersHelper/categories}/OTPrivateKey+SF.h (89%) rename keychain/{ot => TrustedPeersHelper/categories}/OTPrivateKey+SF.m (64%) create mode 100644 keychain/TrustedPeersHelper/main.swift rename keychain/{ot => TrustedPeersHelper}/proto/OTAuthenticatedCiphertext.proto (100%) rename keychain/{ot => TrustedPeersHelper}/proto/OTBottle.proto (98%) rename keychain/{ot => TrustedPeersHelper}/proto/OTBottleContents.proto (100%) rename keychain/{ot => TrustedPeersHelper}/proto/OTPrivateKey.proto (100%) create mode 100644 keychain/TrustedPeersHelper/proto/OTRecovery.proto rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTAuthenticatedCiphertext.h (100%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTAuthenticatedCiphertext.m (100%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTBottle.h (95%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTBottle.m (94%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTBottleContents.h (100%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTBottleContents.m (100%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTPrivateKey.h (100%) rename keychain/{ot/proto/source => TrustedPeersHelper/proto/generated_source}/OTPrivateKey.m (100%) create mode 100644 keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.h create mode 100644 keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.m create mode 100644 keychain/TrustedPeersHelper/proto/generated_source/Recovery.h create mode 100644 keychain/TrustedPeersHelper/proto/generated_source/Recovery.m create mode 100644 keychain/TrustedPeersHelperUnitTests/ContainerSync.swift create mode 100644 keychain/TrustedPeersHelperUnitTests/FakeCuttlefish.swift rename {SecurityUnitTests => keychain/TrustedPeersHelperUnitTests}/Info.plist (100%) create mode 100644 keychain/TrustedPeersHelperUnitTests/MockCuttlefish.swift create mode 100644 keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests-BridgingHeader.h create mode 100644 keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests.swift create mode 100644 keychain/analytics/C2Metric.proto create mode 100644 keychain/analytics/C2Metric/SECC2MPCloudKitInfo.h create mode 100644 keychain/analytics/C2Metric/SECC2MPCloudKitInfo.m create mode 100644 keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.h create mode 100644 keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.m create mode 100644 keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.h create mode 100644 keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.m create mode 100644 keychain/analytics/C2Metric/SECC2MPDeviceInfo.h create mode 100644 keychain/analytics/C2Metric/SECC2MPDeviceInfo.m create mode 100644 keychain/analytics/C2Metric/SECC2MPError.h create mode 100644 keychain/analytics/C2Metric/SECC2MPError.m create mode 100644 keychain/analytics/C2Metric/SECC2MPGenericEvent.h create mode 100644 keychain/analytics/C2Metric/SECC2MPGenericEvent.m create mode 100644 keychain/analytics/C2Metric/SECC2MPGenericEventMetric.h create mode 100644 keychain/analytics/C2Metric/SECC2MPGenericEventMetric.m create mode 100644 keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.h create mode 100644 keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.m create mode 100644 keychain/analytics/C2Metric/SECC2MPInternalTestConfig.h create mode 100644 keychain/analytics/C2Metric/SECC2MPInternalTestConfig.m create mode 100644 keychain/analytics/C2Metric/SECC2MPMetric.h create mode 100644 keychain/analytics/C2Metric/SECC2MPMetric.m create mode 100644 keychain/analytics/C2Metric/SECC2MPNetworkEvent.h create mode 100644 keychain/analytics/C2Metric/SECC2MPNetworkEvent.m create mode 100644 keychain/analytics/C2Metric/SECC2MPServerInfo.h create mode 100644 keychain/analytics/C2Metric/SECC2MPServerInfo.m create mode 100644 keychain/analytics/CKKSLaunchSequence.h create mode 100644 keychain/analytics/CKKSLaunchSequence.m create mode 100644 keychain/analytics/SecC2DeviceInfo.h create mode 100644 keychain/analytics/SecC2DeviceInfo.m create mode 100644 keychain/analytics/SecEventMetric.h create mode 100644 keychain/analytics/SecEventMetric.m create mode 100644 keychain/analytics/SecEventMetric_private.h create mode 100644 keychain/analytics/SecMetrics.h create mode 100644 keychain/analytics/SecMetrics.m rename keychain/{ot/SFPublicKey+SPKI.h => analytics/TestResourceUsage.h} (81%) create mode 100644 keychain/analytics/TestResourceUsage.m create mode 100644 keychain/analytics/Tests/CKKSLaunchSequenceTests.m delete mode 100644 keychain/ckks/CKKSAPSReceiver.m rename keychain/ckks/{CKKSCKAccountStateTracker.h => CKKSAccountStateTracker.h} (64%) rename keychain/ckks/{CKKSCKAccountStateTracker.m => CKKSAccountStateTracker.m} (51%) create mode 100644 keychain/ckks/CKKSCloudKitClassDependencies.h create mode 100644 keychain/ckks/CKKSCloudKitClassDependencies.m create mode 100644 keychain/ckks/CKKSConstants.m create mode 100644 keychain/ckks/CKKSKeychainBackedKey.h create mode 100644 keychain/ckks/CKKSKeychainBackedKey.m create mode 100644 keychain/ckks/CKKSListenerCollection.h create mode 100644 keychain/ckks/CKKSListenerCollection.m create mode 100644 keychain/ckks/CKKSProvideKeySetOperation.h create mode 100644 keychain/ckks/CKKSProvideKeySetOperation.m create mode 100644 keychain/ckks/CKKSTLKShareRecord.h create mode 100644 keychain/ckks/CKKSTLKShareRecord.m create mode 100644 keychain/ckks/CKKSZoneModifier.h create mode 100644 keychain/ckks/CKKSZoneModifier.m rename keychain/ckks/{CKKSAPSReceiver.h => OctagonAPSReceiver.h} (75%) create mode 100644 keychain/ckks/OctagonAPSReceiver.m rename keychain/ckks/proto/{source => generated_source}/CKKSSerializedKey.h (100%) rename keychain/ckks/proto/{source => generated_source}/CKKSSerializedKey.m (100%) create mode 100644 keychain/ckks/tests/CKKSFetchTests.m create mode 100644 keychain/ckks/tests/CKKSMockOctagonAdapter.h create mode 100644 keychain/ckks/tests/CKKSMockOctagonAdapter.m create mode 100644 keychain/ckks/tests/CKKSMockSOSPresentAdapter.h create mode 100644 keychain/ckks/tests/CKKSMockSOSPresentAdapter.m create mode 100644 keychain/ckks/tests/CKKSTests+LockStateTracker.m create mode 100644 keychain/ckks/tests/CKKSTests+MultiZone.h create mode 100644 keychain/ckks/tests/CKKSTests+MultiZone.m rename keychain/ckks/tests/{CKKSAPSReceiverTests.h => OctagonAPSReceiverTests.h} (95%) rename keychain/ckks/tests/{CKKSAPSReceiverTests.m => OctagonAPSReceiverTests.m} (88%) create mode 100644 keychain/escrowrequest/EscrowRequestController.h create mode 100644 keychain/escrowrequest/EscrowRequestController.m create mode 100644 keychain/escrowrequest/EscrowRequestServer.h create mode 100644 keychain/escrowrequest/EscrowRequestServer.m create mode 100644 keychain/escrowrequest/EscrowRequestServerHelpers.h create mode 100644 keychain/escrowrequest/EscrowRequestServerHelpers.m create mode 100644 keychain/escrowrequest/EscrowRequestXPCProtocol.h create mode 100644 keychain/escrowrequest/EscrowRequestXPCProtocol.m create mode 100644 keychain/escrowrequest/EscrowRequestXPCServer.h create mode 100644 keychain/escrowrequest/EscrowRequestXPCServer.m create mode 100644 keychain/escrowrequest/Framework/SecEscrowRequest.h create mode 100644 keychain/escrowrequest/Framework/SecEscrowRequest.m create mode 100644 keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h create mode 100644 keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.m create mode 100644 keychain/escrowrequest/SecEscrowPendingRecord.proto create mode 100644 keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h create mode 100644 keychain/escrowrequest/generated_source/SecEscrowPendingRecord.m create mode 100644 keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h create mode 100644 keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.m create mode 100644 keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h create mode 100644 keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.m create mode 100644 keychain/escrowrequest/tests/MockSynchronousEscrowServer.h create mode 100644 keychain/escrowrequest/tests/MockSynchronousEscrowServer.m create mode 100644 keychain/escrowrequest/tests/SecEscrowRequestTests.m create mode 100644 keychain/escrowrequest/tests/SecEscrowRequestsTests-Info.plist create mode 100644 keychain/ot/OTAuthKitAdapter.h create mode 100644 keychain/ot/OTAuthKitAdapter.m create mode 100644 keychain/ot/OTBottledPeerState.h create mode 100644 keychain/ot/OTBottledPeerState.m create mode 100644 keychain/ot/OTCheckHealthOperation.h create mode 100644 keychain/ot/OTCheckHealthOperation.m create mode 100644 keychain/ot/OTClientStateMachine.h create mode 100644 keychain/ot/OTClientStateMachine.m create mode 100644 keychain/ot/OTClientVoucherOperation.h create mode 100644 keychain/ot/OTClientVoucherOperation.m create mode 100644 keychain/ot/OTClique.h create mode 100644 keychain/ot/OTClique.m create mode 100644 keychain/ot/OTCuttlefishAccountStateHolder.h create mode 100644 keychain/ot/OTCuttlefishAccountStateHolder.m create mode 100644 keychain/ot/OTCuttlefishContext.h create mode 100644 keychain/ot/OTCuttlefishContext.m create mode 100644 keychain/ot/OTDefines.m create mode 100644 keychain/ot/OTDetermineHSA2AccountStatusOperation.h create mode 100644 keychain/ot/OTDetermineHSA2AccountStatusOperation.m create mode 100644 keychain/ot/OTDeviceInformation.h create mode 100644 keychain/ot/OTDeviceInformation.m create mode 100644 keychain/ot/OTDeviceInformationAdapter.h create mode 100644 keychain/ot/OTDeviceInformationAdapter.m create mode 100644 keychain/ot/OTEnsureOctagonKeyConsistency.h create mode 100644 keychain/ot/OTEnsureOctagonKeyConsistency.m create mode 100644 keychain/ot/OTEpochOperation.h create mode 100644 keychain/ot/OTEpochOperation.m create mode 100644 keychain/ot/OTEstablishOperation.h create mode 100644 keychain/ot/OTEstablishOperation.m create mode 100644 keychain/ot/OTFetchCKKSKeysOperation.h create mode 100644 keychain/ot/OTFetchCKKSKeysOperation.m create mode 100644 keychain/ot/OTFetchViewsOperation.h create mode 100644 keychain/ot/OTFetchViewsOperation.m create mode 100644 keychain/ot/OTFollowup.h create mode 100644 keychain/ot/OTFollowup.m create mode 100644 keychain/ot/OTJoinWithVoucherOperation.h create mode 100644 keychain/ot/OTJoinWithVoucherOperation.m create mode 100644 keychain/ot/OTJoiningConfiguration.h create mode 100644 keychain/ot/OTJoiningConfiguration.m create mode 100644 keychain/ot/OTLeaveCliqueOperation.h create mode 100644 keychain/ot/OTLeaveCliqueOperation.m create mode 100644 keychain/ot/OTLocalCKKSResetOperation.h create mode 100644 keychain/ot/OTLocalCKKSResetOperation.m create mode 100644 keychain/ot/OTLocalCuttlefishReset.h create mode 100644 keychain/ot/OTLocalCuttlefishReset.m create mode 100644 keychain/ot/OTOperationDependencies.h create mode 100644 keychain/ot/OTOperationDependencies.m create mode 100644 keychain/ot/OTPrepareOperation.h create mode 100644 keychain/ot/OTPrepareOperation.m create mode 100644 keychain/ot/OTRemovePeersOperation.h create mode 100644 keychain/ot/OTRemovePeersOperation.m create mode 100644 keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h create mode 100644 keychain/ot/OTResetCKKSZonesLackingTLKsOperation.m create mode 100644 keychain/ot/OTResetOperation.h create mode 100644 keychain/ot/OTResetOperation.m create mode 100644 keychain/ot/OTSOSAdapter.h create mode 100644 keychain/ot/OTSOSAdapter.m create mode 100644 keychain/ot/OTSOSUpdatePreapprovalsOperation.h create mode 100644 keychain/ot/OTSOSUpdatePreapprovalsOperation.m create mode 100644 keychain/ot/OTSOSUpgradeOperation.h create mode 100644 keychain/ot/OTSOSUpgradeOperation.m create mode 100644 keychain/ot/OTSetRecoveryKeyOperation.h create mode 100644 keychain/ot/OTSetRecoveryKeyOperation.m create mode 100644 keychain/ot/OTStates.h create mode 100644 keychain/ot/OTStates.m create mode 100644 keychain/ot/OTTriggerEscrowUpdateOperation.h create mode 100644 keychain/ot/OTTriggerEscrowUpdateOperation.m create mode 100644 keychain/ot/OTUpdateTPHOperation.h create mode 100644 keychain/ot/OTUpdateTPHOperation.m create mode 100644 keychain/ot/OTUpdateTrustedDeviceListOperation.h create mode 100644 keychain/ot/OTUpdateTrustedDeviceListOperation.m create mode 100644 keychain/ot/OTUploadNewCKKSTLKsOperation.h create mode 100644 keychain/ot/OTUploadNewCKKSTLKsOperation.m create mode 100644 keychain/ot/OTVouchWithBottleOperation.h create mode 100644 keychain/ot/OTVouchWithBottleOperation.m create mode 100644 keychain/ot/OTVouchWithRecoveryKeyOperation.h create mode 100644 keychain/ot/OTVouchWithRecoveryKeyOperation.m create mode 100644 keychain/ot/ObjCImprovements.h create mode 100644 keychain/ot/OctagonCKKSPeerAdapter.h create mode 100644 keychain/ot/OctagonCKKSPeerAdapter.m create mode 100644 keychain/ot/OctagonCheckTrustStateOperation.h create mode 100644 keychain/ot/OctagonCheckTrustStateOperation.m create mode 100644 keychain/ot/OctagonFlags.h create mode 100644 keychain/ot/OctagonFlags.m create mode 100644 keychain/ot/OctagonPendingFlag.h create mode 100644 keychain/ot/OctagonPendingFlag.m create mode 100644 keychain/ot/OctagonStateMachine.h create mode 100644 keychain/ot/OctagonStateMachine.m create mode 100644 keychain/ot/OctagonStateMachineHelpers.h create mode 100644 keychain/ot/OctagonStateMachineHelpers.m create mode 100644 keychain/ot/OctagonStateMachineObservers.h create mode 100644 keychain/ot/OctagonStateMachineObservers.m delete mode 100644 keychain/ot/SFECPublicKey+SPKI.m create mode 100644 keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h create mode 100644 keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.m create mode 100644 keychain/ot/categories/OctagonEscrowRecoverer.h create mode 100644 keychain/ot/proto/OTAccountMetadataClassC.proto create mode 100644 keychain/ot/proto/OTPairingMessage.proto create mode 100644 keychain/ot/proto/generated_source/OTAccountMetadataClassC.h create mode 100644 keychain/ot/proto/generated_source/OTAccountMetadataClassC.m create mode 100644 keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h create mode 100644 keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.m create mode 100644 keychain/ot/proto/generated_source/OTPairingMessage.h create mode 100644 keychain/ot/proto/generated_source/OTPairingMessage.m create mode 100644 keychain/ot/proto/generated_source/OTSOSMessage.h create mode 100644 keychain/ot/proto/generated_source/OTSOSMessage.m create mode 100644 keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h create mode 100644 keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.m create mode 100644 keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h create mode 100644 keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.m create mode 100644 keychain/ot/proto/source/OTSOSMessage.h create mode 100644 keychain/ot/proto/source/OTSOSMessage.m create mode 100644 keychain/ot/tests/OTBottledPeerUpdateBottlesTests.m create mode 100644 keychain/ot/tests/OTCliqueTests.m create mode 100644 keychain/ot/tests/OTCuttlefishContextTests.m create mode 100644 keychain/ot/tests/OTFollowupTests.m create mode 100644 keychain/ot/tests/gen_test_plist.py create mode 100644 keychain/ot/tests/octagon/OctagonDataPersistenceTests.swift create mode 100644 keychain/ot/tests/octagon/OctagonTestMocks.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+CKKS.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+CloudKitAccount.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+CoreFollowUp.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+DeviceList.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+ErrorHandling.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+EscrowRecovery.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+HealthCheck.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+RecoveryKey.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+Reset.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+SOS.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests+SOSUpgrade.swift create mode 100644 keychain/ot/tests/octagon/OctagonTests-BridgingHeader.h create mode 100644 keychain/ot/tests/octagon/OctagonTests-Info.plist create mode 100644 keychain/ot/tests/octagon/OctagonTests.swift create mode 100644 keychain/ot/tests/octagon/OctagonTestsXPCConnections.swift create mode 100644 keychain/ot/tests/octagon/Pairing/OctagonPairingTests+Piggybacking.swift create mode 100644 keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProxMultiClients.swift create mode 100644 keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProximitySetup.swift create mode 100644 keychain/ot/tests/octagon/Pairing/OctagonPairingTests.swift create mode 100644 keychain/ot/tests/octagon/TestsObjcTranslation.h create mode 100644 keychain/ot/tests/octagon/TestsObjcTranslation.m create mode 100644 keychain/otctl/EscrowRequestCLI.h create mode 100644 keychain/otctl/EscrowRequestCLI.m create mode 100644 keychain/otctl/OTControlCLI.h create mode 100644 keychain/otctl/OTControlCLI.m create mode 100644 keychain/otctl/otctl.1 rename OSX/libsecurity_cryptkit/Info-security_cryptkit.plist => keychain/otpaird/Info.plist (65%) create mode 100644 keychain/otpaird/OTPairingClient.h create mode 100644 keychain/otpaird/OTPairingClient.m create mode 100644 keychain/otpaird/OTPairingConstants.h create mode 100644 keychain/otpaird/OTPairingPacketContext.h create mode 100644 keychain/otpaird/OTPairingPacketContext.m create mode 100644 keychain/otpaird/OTPairingService.h create mode 100644 keychain/otpaird/OTPairingService.m create mode 100644 keychain/otpaird/OTPairingSession.h create mode 100644 keychain/otpaird/OTPairingSession.m create mode 100644 keychain/otpaird/com.apple.security.otpaird.iphoneos.plist create mode 100644 keychain/otpaird/com.apple.security.otpaird.watchos.plist create mode 100644 keychain/otpaird/main.m create mode 100644 keychain/otpaird/otpaird.iphoneos.entitlements create mode 100644 keychain/otpaird/otpaird.watchos.entitlements create mode 100644 keychain/tpctl/main.swift create mode 100644 keychain/tpctl/tpctl-bridging-header.h create mode 100644 keychain/tpctl/tpctl-entitlements.plist create mode 100644 keychain/tpctl/tpctl-objc.h create mode 100644 keychain/tpctl/tpctl-objc.m create mode 100644 keychain/tpctl/tpctl.8 create mode 100644 keychain/tppolicy/main.m delete mode 100644 libsecurity_smime/lib/SecCmsBase.h delete mode 100644 libsecurity_smime/lib/SecCmsContentInfo.h delete mode 100644 libsecurity_smime/lib/SecCmsDigestedData.h delete mode 100644 libsecurity_smime/lib/SecCmsEnvelopedData.h delete mode 100644 libsecurity_smime/lib/SecCmsMessage.h delete mode 100644 libsecurity_smime/lib/SecCmsSignerInfo.h delete mode 100644 libsecurity_smime/lib/SecSMIME.h delete mode 100644 libsecurity_smime/lib/cert.c delete mode 100644 libsecurity_smime/lib/cryptohi.c delete mode 100644 libsecurity_smime/libCMS.xcodeproj/.gitignore delete mode 100644 libsecurity_smime/libCMS.xcodeproj/project.pbxproj create mode 100644 protocol/SecProtocolConfiguration.h create mode 100644 protocol/SecProtocolConfiguration.m create mode 100644 protocol/SecProtocolConfigurationTest.m create mode 100644 protocol/SecProtocolHelper.m create mode 100644 protocol/SecProtocolHelperTest.m create mode 100644 protocol/SecProtocolInternal.h create mode 100644 protocol/SecProtocolTest.m create mode 100644 protocol/SecProtocolTypesPriv.h create mode 100644 protocol/test_data/builtins.json create mode 100644 protocol/test_data/example1.json rename resources/{English.lproj => en.lproj}/Certificate.strings (98%) rename resources/{English.lproj => en.lproj}/CloudKeychain.strings (98%) rename resources/{English.lproj => en.lproj}/OID.strings (100%) rename resources/{English.lproj => en.lproj}/SharedWebCredentials.strings (100%) rename resources/{English.lproj => en.lproj}/Trust.strings (96%) rename header_symlinks/Security/SecRandomP.h => rio.yml (100%) create mode 100644 securityd/etc/com.apple.securityd.sb delete mode 100644 securityd/src/csproxy.cpp delete mode 100644 securityd/src/csproxy.h create mode 100644 securityd/src/securityd.entitlements create mode 100644 securityd/src/util.h create mode 100644 securityd/src/util.m create mode 100644 supd/Tests/NSDate+SFAnalyticsTests.m create mode 100644 supd/securityuploadd-sim.plist create mode 100644 tests/SecDbBackupTests/Entitlements.plist create mode 100644 tests/SecDbBackupTests/Info.plist create mode 100644 tests/SecDbBackupTests/SecDbBackupTests.m create mode 100644 tests/SecDbBackupTests/SecDbBackupTests.plist create mode 100644 tests/TrustTests/DaemonTests/LoggingServerTests.m create mode 100644 tests/TrustTests/EvaluationTests/CTTests.m rename OSX/shared_regressions/si-82-sectrust-ct.h => tests/TrustTests/EvaluationTests/CTTests_data.h (71%) create mode 100644 tests/TrustTests/EvaluationTests/ECTests.m create mode 100644 tests/TrustTests/EvaluationTests/ECTests_data.h create mode 100644 tests/TrustTests/EvaluationTests/EvaluationBasicTests.m create mode 100644 tests/TrustTests/EvaluationTests/EvaluationBasicTests_data.h create mode 100644 tests/TrustTests/EvaluationTests/KeySizeTests.m create mode 100644 tests/TrustTests/EvaluationTests/KeySizeTests_data.h create mode 100644 tests/TrustTests/EvaluationTests/NISTTests.m create mode 100644 tests/TrustTests/EvaluationTests/NameConstraintsTests.m rename OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h => tests/TrustTests/EvaluationTests/NameConstraintsTests_data.h (83%) create mode 100644 tests/TrustTests/EvaluationTests/PathParseTests.m create mode 100644 tests/TrustTests/EvaluationTests/PathParseTests_data.h rename OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.m => tests/TrustTests/EvaluationTests/PathScoringTests.m (76%) rename OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.h => tests/TrustTests/EvaluationTests/PathScoringTests_data.h (99%) create mode 100644 tests/TrustTests/EvaluationTests/PolicyTests.m create mode 100644 tests/TrustTests/EvaluationTests/SSLPolicyTests.m create mode 100644 tests/TrustTests/EvaluationTests/SSLPolicyTests_data.h create mode 100644 tests/TrustTests/EvaluationTests/SignatureAlgorithmTests.m create mode 100644 tests/TrustTests/EvaluationTests/SignatureAlgorithmTests_data.h create mode 100644 tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.h create mode 100644 tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.m create mode 100644 tests/TrustTests/EvaluationTests/VerifyDateTests.m create mode 100644 tests/TrustTests/EvaluationTests/VerifyDateTests_data.h create mode 100644 tests/TrustTests/EvaluationTests/iAPTests.m create mode 100644 tests/TrustTests/EvaluationTests/iAPTests_data.h create mode 100644 tests/TrustTests/FrameworkTests/CertificateInterfaceTests.m create mode 100644 tests/TrustTests/FrameworkTests/CertificateInterfaceTests_data.h create mode 100644 tests/TrustTests/FrameworkTests/CertificateParseTests.m create mode 100644 tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.h create mode 100644 tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.m create mode 100644 tests/TrustTests/FrameworkTests/TrustInterfaceTests.m create mode 100644 tests/TrustTests/FrameworkTests/TrustInterfaceTests_data.h create mode 100644 tests/TrustTests/FrameworkTests/TrustSettingsInterfaceTests.m create mode 100644 tests/TrustTests/Info.plist create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/InvalidUnknownCriticalCertificateExtensionTest2EE.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/TestCopyProperties_ios.plist create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/TrustAnchorRootCertificate.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/int2048B.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/intSHA1.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/leaf1024.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/leaf512.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/leafMD5.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/leafSHA1.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/root2048.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/rootSHA256.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/rootSSL.cer create mode 100644 tests/TrustTests/TestData/TestCopyProperties_ios-data/systemRoot.cer create mode 100644 tests/TrustTests/TestMacroConversions.h create mode 100644 tests/TrustTests/TestRunners/AppDelegate.h create mode 100644 tests/TrustTests/TestRunners/AppDelegate.m create mode 100644 tests/TrustTests/TestRunners/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 tests/TrustTests/TestRunners/Assets.xcassets/Contents.json rename {KeychainEntitledTestApp_ios => tests/TrustTests/TestRunners}/Base.lproj/LaunchScreen.storyboard (73%) rename {KeychainEntitledTestApp_ios => tests/TrustTests/TestRunners}/Base.lproj/Main.storyboard (69%) create mode 100644 tests/TrustTests/TestRunners/Info.plist create mode 100644 tests/TrustTests/TestRunners/Main.storyboard create mode 100644 tests/TrustTests/TestRunners/ViewController.h create mode 100644 tests/TrustTests/TestRunners/ViewController.m create mode 100644 tests/TrustTests/TestRunners/appmain.m create mode 100644 tests/TrustTests/TestRunners/main.m create mode 100644 tests/TrustTests/TestRunners/trusttests_entitlements.plist create mode 100644 tests/TrustTests/TrustEvaluationTestHelpers.h create mode 100644 tests/TrustTests/TrustEvaluationTestHelpers.m create mode 100644 tests/TrustTests/gen_test_plist.py create mode 100644 tests/secdmockaks/aks_real_witness.c create mode 100644 tests/secdmockaks/aks_real_witness.h rename tests/secdmockaks/{secdmockaks.m => mockaksKeychain.m} (75%) create mode 100644 tests/secdmockaks/mockaksWatchDog.m create mode 100644 tests/secdmockaks/mockaksxcbase.h create mode 100644 tests/secdmockaks/mockaksxcbase.m create mode 100644 xcconfig/security_framework.xcconfig create mode 100644 xcconfig/swift_binary.xcconfig create mode 100644 xcconfig/swift_binary_shim.xcconfig diff --git a/.gitignore b/.gitignore index 50a93dee..7af1223e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,10 @@ cscope.out xcuserdata ._* build + +# Swift Package Manager noise +.build +Package.resolved + +# Not adding the SPM-generated .xcodeproj to the repo +keychain/Trieste/OctagonTriesteTests/OctagonTrieste.xcodeproj diff --git a/.swiftlint.yml b/.swiftlint.yml new file mode 100644 index 00000000..43c689e8 --- /dev/null +++ b/.swiftlint.yml @@ -0,0 +1,33 @@ +indentation: 4 +disabled_rules: + - file_length + - function_body_length + - function_parameter_count + - identifier_name + - line_length + - todo + - type_body_length +opt_in_rules: + - anyobject_protocol + - array_init + - attributes + #- closure_end_indentation ## commented as --format removes option + - closure_spacing + - conditional_returns_on_newline + - empty_count + - explicit_init + - implicit_return + - joined_default_parameter + #- literal_expression_end_indentation ## commented as --format removes option + - operator_usage_whitespace + - redundant_nil_coalescing + - redundant_type_annotation + - sorted_imports + - trailing_closure + - unneeded_parentheses_in_closure_argument + - untyped_error_in_catch +trailing_comma: + mandatory_comma: true +excluded: + - keychain/trust/cuttlefish/ + - keychain/Trieste/OctagonTriesteTests/.build diff --git a/Analytics/Clients/LocalKeychainAnalytics.h b/Analytics/Clients/LocalKeychainAnalytics.h index 13800cf2..f3344093 100644 --- a/Analytics/Clients/LocalKeychainAnalytics.h +++ b/Analytics/Clients/LocalKeychainAnalytics.h @@ -21,15 +21,28 @@ typedef enum { LKAKeychainUpgradeOutcomePhase2, } LKAKeychainUpgradeOutcome; +typedef enum { + LKAKeychainBackupTypeNeither, + LKAKeychainBackupTypeBag, + LKAKeychainBackupTypeCode, + LKAKeychainBackupTypeBagAndCode, + LKAKeychainBackupTypeEMCS, +} LKAKeychainBackupType; + void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome); void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error); +void LKABackupReportStart(bool hasKeybag, bool hasPasscode, bool isEMCS); +void LKABackupReportEnd(bool hasBackup, CFErrorRef error); + #if __OBJC2__ #import #import typedef NSString* LKAnalyticsFailableEvent NS_STRING_ENUM; +typedef NSString* LKAnalyticsMetric NS_STRING_ENUM; + extern LKAnalyticsFailableEvent const LKAEventUpgrade; @interface LocalKeychainAnalytics : SFAnalytics diff --git a/Analytics/Clients/LocalKeychainAnalytics.m b/Analytics/Clients/LocalKeychainAnalytics.m index 64d5334d..8d97a540 100644 --- a/Analytics/Clients/LocalKeychainAnalytics.m +++ b/Analytics/Clients/LocalKeychainAnalytics.m @@ -1,7 +1,5 @@ #include "LocalKeychainAnalytics.h" -#if __OBJC2__ - #import "Security/SFAnalyticsDefines.h" #include @@ -26,20 +24,27 @@ } @end -// Public consts +// Approved event types // rdar://problem/41745059 SFAnalytics: collect keychain upgrade outcome information LKAnalyticsFailableEvent const LKAEventUpgrade = (LKAnalyticsFailableEvent)@"LKAEventUpgrade"; +// SFAnalytics: collect keychain backup success rates and duration +LKAnalyticsFailableEvent const LKAEventBackup = (LKAnalyticsFailableEvent)@"LKAEventBackup"; +LKAnalyticsMetric const LKAMetricBackupDuration = (LKAnalyticsMetric)@"LKAMetricBackupDuration"; + // Internal consts NSString* const LKAOldSchemaKey = @"oldschema"; NSString* const LKANewSchemaKey = @"newschema"; NSString* const LKAUpgradeOutcomeKey = @"upgradeoutcome"; +NSString* const LKABackupLastSuccessDate = @"backupLastSuccess"; @implementation LocalKeychainAnalytics { BOOL _probablyInClassD; NSMutableArray* _pendingReports; dispatch_queue_t _queue; int _notificationToken; + NSDate* _backupStartTime; + LKAKeychainBackupType _backupType; } - (instancetype __nullable)init { @@ -126,26 +131,75 @@ NSString* const LKAUpgradeOutcomeKey = @"upgradeoutcome"; } } +- (void)reportKeychainBackupStartWithType:(LKAKeychainBackupType)type { + _backupStartTime = [NSDate date]; + _backupType = type; +} + +// Don't attempt to add to pending reports, this should not happen in Class D +- (void)reportKeychainBackupEnd:(bool)hasBackup error:(NSError*)error { + NSDate* backupEndTime = [NSDate date]; + + // Get duration in milliseconds rounded to 100ms. + NSInteger backupDuration = (int)(([backupEndTime timeIntervalSinceDate:_backupStartTime] + 0.05) * 10) * 100; + + // Generate statistics on backup duration separately so we know what the situation is in the field even when succeeding + [self logMetric:@(backupDuration) withName:LKAMetricBackupDuration]; + + if (hasBackup) { + [self setDateProperty:backupEndTime forKey:LKABackupLastSuccessDate]; + [self logSuccessForEventNamed:LKAEventBackup timestampBucket:SFAnalyticsTimestampBucketHour]; + } else { + NSInteger daysSinceSuccess = [SFAnalytics fuzzyDaysSinceDate:[self datePropertyForKey:LKABackupLastSuccessDate]]; + [self logResultForEvent:LKAEventBackup + hardFailure:YES + result:error + withAttributes:@{@"daysSinceSuccess" : @(daysSinceSuccess), + @"duration" : @(backupDuration), + @"type" : @(_backupType), + } + timestampBucket:SFAnalyticsTimestampBucketHour]; + } +} + @end // MARK: C Bridging void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome) { - [[LocalKeychainAnalytics logger] reportKeychainUpgradeFrom:fromversion to:toversion outcome:outcome error:NULL]; + @autoreleasepool { + [[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]; + @autoreleasepool { + [[LocalKeychainAnalytics logger] reportKeychainUpgradeFrom:fromversion to:toversion outcome:outcome error:(__bridge NSError*)error]; + } } -#else // not __OBJC2__ +void LKABackupReportStart(bool hasKeybag, bool hasPasscode, bool isEMCS) { + LKAKeychainBackupType type; + if (isEMCS) { + type = LKAKeychainBackupTypeEMCS; + } else if (hasKeybag && hasPasscode) { + type = LKAKeychainBackupTypeBagAndCode; + } else if (hasKeybag) { + type = LKAKeychainBackupTypeBag; + } else if (hasPasscode) { + type = LKAKeychainBackupTypeCode; + } else { + type = LKAKeychainBackupTypeNeither; + } -void LKAReportKeychainUpgradeOutcome(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome) { - // nothing to do on 32 bit + // Keep track of backup type and start time + @autoreleasepool { + [[LocalKeychainAnalytics logger] reportKeychainBackupStartWithType:type]; + } } -void LKAReportKeychainUpgradeOutcomeWithError(int fromversion, int toversion, LKAKeychainUpgradeOutcome outcome, CFErrorRef error) { - // nothing to do on 32 bit +void LKABackupReportEnd(bool hasBackup, CFErrorRef error) { + @autoreleasepool { + [[LocalKeychainAnalytics logger] reportKeychainBackupEnd:hasBackup error:(__bridge NSError*)error]; + } } - -#endif // __OBJC2__ diff --git a/Analytics/NSDate+SFAnalytics.h b/Analytics/NSDate+SFAnalytics.h new file mode 100644 index 00000000..9d902e2e --- /dev/null +++ b/Analytics/NSDate+SFAnalytics.h @@ -0,0 +1,38 @@ +/* + * 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@ + */ + +#ifndef NSDate_SFAnalytics_h +#define NSDate_SFAnalytics_h + +#import +#import "SFAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface NSDate (SFAnalytics) +- (NSTimeInterval)timeIntervalSince1970WithBucket:(SFAnalyticsTimestampBucket)bucket; +@end + +NS_ASSUME_NONNULL_END + +#endif /* NSDate_SFAnalytics_h */ diff --git a/Analytics/NSDate+SFAnalytics.m b/Analytics/NSDate+SFAnalytics.m new file mode 100644 index 00000000..c9979e8a --- /dev/null +++ b/Analytics/NSDate+SFAnalytics.m @@ -0,0 +1,49 @@ +/* + * 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 "NSDate+SFAnalytics.h" + +@implementation NSDate (SFAnalytics) + +- (NSTimeInterval)bucketToRoundingFactor:(SFAnalyticsTimestampBucket)bucket +{ + switch (bucket) { + case SFAnalyticsTimestampBucketSecond: + return 1; + case SFAnalyticsTimestampBucketMinute: + return 60; + case SFAnalyticsTimestampBucketHour: + return 60 * 60; + } +} + +- (NSTimeInterval)timeIntervalSince1970WithBucket:(SFAnalyticsTimestampBucket)bucket +{ + NSTimeInterval mask = [self bucketToRoundingFactor:bucket]; + NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; + return (NSTimeInterval)(now + (mask - ((long)now % (long)mask))); +} + +@end + diff --git a/Analytics/SFAnalytics.h b/Analytics/SFAnalytics.h index 9a135bd2..55d35ba6 100644 --- a/Analytics/SFAnalytics.h +++ b/Analytics/SFAnalytics.h @@ -30,54 +30,118 @@ #import "SFAnalyticsMultiSampler.h" #import "SFAnalyticsActivityTracker.h" +NS_ASSUME_NONNULL_BEGIN + // this sampling interval will cause the sampler to run only at data reporting time extern const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport; -@interface SFAnalytics : NSObject +typedef NS_ENUM(uint32_t, SFAnalyticsTimestampBucket) { + SFAnalyticsTimestampBucketSecond = 0, + SFAnalyticsTimestampBucketMinute = 1, + SFAnalyticsTimestampBucketHour = 2, +}; + +@protocol SFAnalyticsProtocol ++ (id _Nullable)logger; + +- (void)logResultForEvent:(NSString*)eventName + hardFailure:(bool)hardFailure + result:(NSError* _Nullable)eventResultError; +- (void)logResultForEvent:(NSString*)eventName + hardFailure:(bool)hardFailure + result:(NSError* _Nullable)eventResultError + withAttributes:(NSDictionary* _Nullable)attributes; + +- (SFAnalyticsMultiSampler* _Nullable)AddMultiSamplerForName:(NSString *)samplerName + withTimeInterval:(NSTimeInterval)timeInterval + block:(NSDictionary *(^)(void))block; + +- (SFAnalyticsActivityTracker* _Nullable)logSystemMetricsForActivityNamed:(NSString*)eventName + withAction:(void (^ _Nullable)(void))action; +- (SFAnalyticsActivityTracker* _Nullable)startLogSystemMetricsForActivityNamed:(NSString *)eventName; +@end + +@interface SFAnalytics : NSObject -+ (instancetype)logger; ++ (instancetype _Nullable)logger; + (NSInteger)fuzzyDaysSinceDate:(NSDate*)date; + (void)addOSVersionToEvent:(NSMutableDictionary*)event; // Help for the subclass to pick a prefered location + (NSString *)defaultAnalyticsDatabasePath:(NSString *)basename; +- (void)dailyCoreAnalyticsMetrics:(NSString *)eventName; + // 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 - (void)logSuccessForEventNamed:(NSString*)eventName; -- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; -- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes; +- (void)logSuccessForEventNamed:(NSString*)eventName timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; + +- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary* _Nullable)attributes; +- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary* _Nullable)attributes timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; + +- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary* _Nullable)attributes; +- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary* _Nullable)attributes timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; + // or just log an event if it is not failable - (void)noteEventNamed:(NSString*)eventName; - -- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError; -- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError withAttributes:(NSDictionary*)attributes; +- (void)noteEventNamed:(NSString*)eventName timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; + +- (void)logResultForEvent:(NSString*)eventName + hardFailure:(bool)hardFailure + result:(NSError* _Nullable)eventResultError; +- (void)logResultForEvent:(NSString*)eventName + hardFailure:(bool)hardFailure + result:(NSError* _Nullable)eventResultError + timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; +- (void)logResultForEvent:(NSString*)eventName + hardFailure:(bool)hardFailure + result:(NSError* _Nullable)eventResultError + withAttributes:(NSDictionary* _Nullable)attributes; +- (void)logResultForEvent:(NSString*)eventName + hardFailure:(bool)hardFailure + result:(NSError* _Nullable)eventResultError + withAttributes:(NSDictionary* _Nullable)attributes + timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; // Track the state of a named value over time -- (SFAnalyticsSampler*)addMetricSamplerForName:(NSString*)samplerName withTimeInterval:(NSTimeInterval)timeInterval block:(NSNumber* (^)(void))block; -- (SFAnalyticsSampler*)existingMetricSamplerForName:(NSString*)samplerName; +- (SFAnalyticsSampler* _Nullable)addMetricSamplerForName:(NSString*)samplerName + withTimeInterval:(NSTimeInterval)timeInterval + block:(NSNumber* (^)(void))block; +- (SFAnalyticsSampler* _Nullable)existingMetricSamplerForName:(NSString*)samplerName; - (void)removeMetricSamplerForName:(NSString*)samplerName; // Same idea, but log multiple named values in a single block -- (SFAnalyticsMultiSampler*)AddMultiSamplerForName:(NSString*)samplerName withTimeInterval:(NSTimeInterval)timeInterval block:(NSDictionary* (^)(void))block; +- (SFAnalyticsMultiSampler* _Nullable)AddMultiSamplerForName:(NSString*)samplerName + withTimeInterval:(NSTimeInterval)timeInterval + block:(NSDictionary* (^)(void))block; - (SFAnalyticsMultiSampler*)existingMultiSamplerForName:(NSString*)samplerName; - (void)removeMultiSamplerForName:(NSString*)samplerName; // Log measurements of arbitrary things // System metrics measures how much time it takes to complete the action - possibly more in the future. The return value can be ignored if you only need to execute 1 block for your activity -- (SFAnalyticsActivityTracker*)logSystemMetricsForActivityNamed:(NSString*)eventName withAction:(void (^)(void))action; -- (void)logMetric:(NSNumber*)metric withName:(NSString*)metricName; +- (SFAnalyticsActivityTracker* _Nullable)logSystemMetricsForActivityNamed:(NSString*)eventName + withAction:(void (^ _Nullable)(void))action; + +// Same as above, but automatically starts the tracker, since you haven't given it any action to perform +- (SFAnalyticsActivityTracker* _Nullable)startLogSystemMetricsForActivityNamed:(NSString *)eventName; +- (void)logMetric:(NSNumber*)metric withName:(NSString*)metricName; // -------------------------------- // Things below are for subclasses // Override to create a concrete logger instance -@property (readonly, class) NSString* databasePath; +@property (readonly, class, nullable) NSString* databasePath; // Storing dates -- (void)setDateProperty:(NSDate*)date forKey:(NSString*)key; -- (NSDate*)datePropertyForKey:(NSString*)key; +- (void)setDateProperty:(NSDate* _Nullable)date forKey:(NSString*)key; +- (NSDate* _Nullable)datePropertyForKey:(NSString*)key; + +- (void)incrementIntegerPropertyForKey:(NSString*)key; +- (void)setNumberProperty:(NSNumber* _Nullable)number forKey:(NSString*)key; +- (NSNumber * _Nullable)numberPropertyForKey:(NSString*)key; + // -------------------------------- // Things below are for unit testing @@ -86,5 +150,6 @@ extern const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport; @end +NS_ASSUME_NONNULL_END #endif #endif diff --git a/Analytics/SFAnalytics.m b/Analytics/SFAnalytics.m index 5f2d531a..4f6933a4 100644 --- a/Analytics/SFAnalytics.m +++ b/Analytics/SFAnalytics.m @@ -29,18 +29,23 @@ #import "SFAnalyticsSampler+Internal.h" #import "SFAnalyticsMultiSampler+Internal.h" #import "SFAnalyticsSQLiteStore.h" +#import "NSDate+SFAnalytics.h" #import "utilities/debugging.h" #import #import #import #import +#include +#include + +#import // SFAnalyticsDefines constants NSString* const SFAnalyticsTableSuccessCount = @"success_count"; NSString* const SFAnalyticsTableHardFailures = @"hard_failures"; NSString* const SFAnalyticsTableSoftFailures = @"soft_failures"; NSString* const SFAnalyticsTableSamples = @"samples"; -NSString* const SFAnalyticsTableAllEvents = @"all_events"; +NSString* const SFAnalyticsTableNotes = @"notes"; NSString* const SFAnalyticsColumnSuccessCount = @"success_count"; NSString* const SFAnalyticsColumnHardFailureCount = @"hard_failure_count"; @@ -50,45 +55,54 @@ NSString* const SFAnalyticsColumnSampleName = @"name"; NSString* const SFAnalyticsEventTime = @"eventTime"; NSString* const SFAnalyticsEventType = @"eventType"; +NSString* const SFAnalyticsEventTypeErrorEvent = @"errorEvent"; +NSString* const SFAnalyticsEventErrorDestription = @"errorDescription"; NSString* const SFAnalyticsEventClassKey = @"eventClass"; NSString* const SFAnalyticsAttributeErrorUnderlyingChain = @"errorChain"; NSString* const SFAnalyticsAttributeErrorDomain = @"errorDomain"; NSString* const SFAnalyticsAttributeErrorCode = @"errorCode"; +NSString* const SFAnalyticsAttributeLastUploadTime = @"lastUploadTime"; + NSString* const SFAnalyticsUserDefaultsSuite = @"com.apple.security.analytics"; char* const SFAnalyticsFireSamplersNotification = "com.apple.security.sfanalytics.samplers"; +NSString* const SFAnalyticsTopicCloudServices = @"CloudServicesTopic"; NSString* const SFAnalyticsTopicKeySync = @"KeySyncTopic"; -NSString* const SFAnaltyicsTopicTrust = @"TrustTopic"; +NSString* const SFAnalyticsTopicTrust = @"TrustTopic"; +NSString* const SFAnalyticsTopicTransparency = @"TransparencyTopic"; NSString* const SFAnalyticsTableSchema = @"CREATE TABLE IF NOT EXISTS hard_failures (\n" @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" @"timestamp REAL," @"data BLOB\n" @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_hard_failures AFTER INSERT ON hard_failures\n" + @"DROP TRIGGER IF EXISTS maintain_ring_buffer_hard_failures;\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_hard_failures_v2 AFTER INSERT ON hard_failures\n" @"BEGIN\n" - @"DELETE FROM hard_failures WHERE id != NEW.id AND id % 1000 = NEW.id % 1000;\n" + @"DELETE FROM hard_failures WHERE id <= NEW.id - 1000;\n" @"END;\n" @"CREATE TABLE IF NOT EXISTS soft_failures (\n" @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" @"timestamp REAL," @"data BLOB\n" @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_soft_failures AFTER INSERT ON soft_failures\n" + @"DROP TRIGGER IF EXISTS maintain_ring_buffer_soft_failures;\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_soft_failures_v2 AFTER INSERT ON soft_failures\n" @"BEGIN\n" - @"DELETE FROM soft_failures WHERE id != NEW.id AND id % 1000 = NEW.id % 1000;\n" + @"DELETE FROM soft_failures WHERE id <= NEW.id - 1000;\n" @"END;\n" - @"CREATE TABLE IF NOT EXISTS all_events (\n" + @"CREATE TABLE IF NOT EXISTS notes (\n" @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" @"timestamp REAL," @"data BLOB\n" @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_all_events AFTER INSERT ON all_events\n" + @"DROP TRIGGER IF EXISTS maintain_ring_buffer_notes;\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_notes_v2 AFTER INSERT ON notes\n" @"BEGIN\n" - @"DELETE FROM all_events WHERE id != NEW.id AND id % 10000 = NEW.id % 10000;\n" + @"DELETE FROM notes WHERE id <= NEW.id - 1000;\n" @"END;\n" @"CREATE TABLE IF NOT EXISTS samples (\n" @"id INTEGER PRIMARY KEY AUTOINCREMENT,\n" @@ -96,16 +110,18 @@ NSString* const SFAnalyticsTableSchema = @"CREATE TABLE IF NOT EXISTS hard_fa @"name STRING,\n" @"value REAL\n" @");\n" - @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_samples AFTER INSERT ON samples\n" + @"DROP TRIGGER IF EXISTS maintain_ring_buffer_samples;\n" + @"CREATE TRIGGER IF NOT EXISTS maintain_ring_buffer_samples_v2 AFTER INSERT ON samples\n" @"BEGIN\n" - @"DELETE FROM samples WHERE id != NEW.id AND id % 1000 = NEW.id % 1000;\n" + @"DELETE FROM samples WHERE id <= NEW.id - 1000;\n" @"END;\n" @"CREATE TABLE IF NOT EXISTS success_count (\n" @"event_type STRING PRIMARY KEY,\n" @"success_count INTEGER,\n" @"hard_failure_count INTEGER,\n" @"soft_failure_count INTEGER\n" - @");\n"; + @");\n" + @"DROP TABLE IF EXISTS all_events;\n"; NSUInteger const SFAnalyticsMaxEventsToReport = 1000; @@ -114,6 +130,7 @@ NSString* const SFAnalyticsErrorDomain = @"com.apple.security.sfanalytics"; // Local constants NSString* const SFAnalyticsEventBuild = @"build"; NSString* const SFAnalyticsEventProduct = @"product"; +NSString* const SFAnalyticsEventInternal = @"internal"; const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; @interface SFAnalytics () @@ -131,10 +148,6 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; + (instancetype)logger { -#if TARGET_OS_SIMULATOR - return nil; -#else - if (self == [SFAnalytics class]) { secerror("attempt to instatiate abstract class SFAnalytics"); return nil; @@ -151,7 +164,6 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; [logger database]; // For unit testing so there's always a database. DB shouldn't be nilled in production though return logger; -#endif } + (NSString*)databasePath @@ -261,16 +273,60 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; return result; } + +- (void)incrementIntegerPropertyForKey:(NSString*)key +{ + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf == nil) { + return; + } + NSInteger integer = [[strongSelf.database propertyForKey:key] integerValue]; + [strongSelf.database setProperty:[NSString stringWithFormat:@"%ld", (long)integer + 1] forKey:key]; + }); +} + +- (void)setNumberProperty:(NSNumber* _Nullable)number forKey:(NSString*)key +{ + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + [strongSelf.database setProperty:[number stringValue] forKey:key]; + } + }); +} + +- (NSNumber* _Nullable)numberPropertyForKey:(NSString*)key +{ + __block NSNumber* result = nil; + __weak __typeof(self) weakSelf = self; + dispatch_sync(_queue, ^{ + __strong __typeof(self) strongSelf = weakSelf; + if (strongSelf) { + NSString *property = [strongSelf.database propertyForKey:key]; + if (property) { + result = [NSNumber numberWithInteger:[property integerValue]]; + } + } + }); + return result; +} + + + (void)addOSVersionToEvent:(NSMutableDictionary*)eventDict { static dispatch_once_t onceToken; static NSString *build = NULL; static NSString *product = NULL; + static BOOL internal = NO; dispatch_once(&onceToken, ^{ NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); if (version == NULL) return; build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; + internal = os_variant_has_internal_diagnostics("com.apple.security"); }); if (build) { eventDict[SFAnalyticsEventBuild] = build; @@ -278,6 +334,9 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; if (product) { eventDict[SFAnalyticsEventProduct] = product; } + if (internal) { + eventDict[SFAnalyticsEventInternal] = @YES; + } } - (instancetype)init @@ -292,29 +351,93 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; return self; } +- (NSDictionary *)coreAnalyticsKeyFilter:(NSDictionary *)info +{ + NSMutableDictionary *filtered = [NSMutableDictionary dictionary]; + [info enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + filtered[[key stringByReplacingOccurrencesOfString:@"-" withString:@"_"]] = obj; + }]; + return filtered; +} + +// Daily CoreAnalytics metrics +// Call this once per say if you want to have the once per day sampler collect their data and submit it + +- (void)dailyCoreAnalyticsMetrics:(NSString *)eventName +{ + NSMutableDictionary *dailyMetrics = [NSMutableDictionary dictionary]; + __block NSDictionary* multisamplers; + __block NSDictionary* samplers; + + dispatch_sync(_queue, ^{ + multisamplers = [self->_multisamplers copy]; + samplers = [self->_samplers copy]; + }); + + [multisamplers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, SFAnalyticsMultiSampler * _Nonnull obj, BOOL * _Nonnull stop) { + if (obj.oncePerReport == FALSE) { + return; + } + NSDictionary *samples = [obj sampleNow]; + if (samples == nil) { + return; + } + [dailyMetrics addEntriesFromDictionary:samples]; + }]; + + [samplers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, SFAnalyticsSampler * _Nonnull obj, BOOL * _Nonnull stop) { + if (obj.oncePerReport == FALSE) { + return; + } + dailyMetrics[key] = [obj sampleNow]; + }]; + + [SecCoreAnalytics sendEvent:eventName event:[self coreAnalyticsKeyFilter:dailyMetrics]]; +} + // MARK: Event logging +- (void)logSuccessForEventNamed:(NSString*)eventName timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassSuccess attributes:nil timestampBucket:timestampBucket]; +} + - (void)logSuccessForEventNamed:(NSString*)eventName { - [self logEventNamed:eventName class:SFAnalyticsEventClassSuccess attributes:nil]; + [self logSuccessForEventNamed:eventName timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + +- (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassHardFailure attributes:attributes timestampBucket:timestampBucket]; } - (void)logHardFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes { - [self logEventNamed:eventName class:SFAnalyticsEventClassHardFailure attributes:attributes]; + [self logHardFailureForEventNamed:eventName withAttributes:attributes timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + +- (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassSoftFailure attributes:attributes timestampBucket:timestampBucket]; } - (void)logSoftFailureForEventNamed:(NSString*)eventName withAttributes:(NSDictionary*)attributes { - [self logEventNamed:eventName class:SFAnalyticsEventClassSoftFailure attributes:attributes]; + [self logSoftFailureForEventNamed:eventName withAttributes:attributes timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + +- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket +{ + [self logResultForEvent:eventName hardFailure:hardFailure result:eventResultError withAttributes:nil timestampBucket:SFAnalyticsTimestampBucketSecond]; } - (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError { - [self logResultForEvent:eventName hardFailure:hardFailure result:eventResultError withAttributes:nil]; + [self logResultForEvent:eventName hardFailure:hardFailure result:eventResultError timestampBucket:SFAnalyticsTimestampBucketSecond]; } -- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError withAttributes:(NSDictionary*)attributes +- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError withAttributes:(NSDictionary*)attributes timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket { if(!eventResultError) { [self logSuccessForEventNamed:eventName]; @@ -351,12 +474,22 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; } } +- (void)logResultForEvent:(NSString*)eventName hardFailure:(bool)hardFailure result:(NSError*)eventResultError withAttributes:(NSDictionary*)attributes +{ + [self logResultForEvent:eventName hardFailure:hardFailure result:eventResultError withAttributes:attributes timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + +- (void)noteEventNamed:(NSString*)eventName timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket +{ + [self logEventNamed:eventName class:SFAnalyticsEventClassNote attributes:nil timestampBucket:timestampBucket]; +} + - (void)noteEventNamed:(NSString*)eventName { - [self logEventNamed:eventName class:SFAnalyticsEventClassNote attributes:nil]; + [self noteEventNamed:eventName timestampBucket:SFAnalyticsTimestampBucketSecond]; } -- (void)logEventNamed:(NSString*)eventName class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attributes +- (void)logEventNamed:(NSString*)eventName class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attributes timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket { if (!eventName) { secerror("SFAnalytics: attempt to log an event with no name"); @@ -370,29 +503,44 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; return; } - NSDictionary* eventDict = [self eventDictForEventName:eventName withAttributes:attributes eventClass:class]; - [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableAllEvents]; - + [strongSelf.database begin]; + + NSDictionary* eventDict = [self eventDictForEventName:eventName withAttributes:attributes eventClass:class timestampBucket:timestampBucket]; + if (class == SFAnalyticsEventClassHardFailure) { - [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableHardFailures]; + [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableHardFailures timestampBucket:timestampBucket]; [strongSelf.database incrementHardFailureCountForEventType:eventName]; } else if (class == SFAnalyticsEventClassSoftFailure) { - [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableSoftFailures]; + [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableSoftFailures timestampBucket:timestampBucket]; [strongSelf.database incrementSoftFailureCountForEventType:eventName]; } - else if (class == SFAnalyticsEventClassSuccess || class == SFAnalyticsEventClassNote) { + else if (class == SFAnalyticsEventClassNote) { + [strongSelf.database addEventDict:eventDict toTable:SFAnalyticsTableNotes timestampBucket:timestampBucket]; [strongSelf.database incrementSuccessCountForEventType:eventName]; } + else if (class == SFAnalyticsEventClassSuccess) { + [strongSelf.database incrementSuccessCountForEventType:eventName]; + } + + [strongSelf.database end]; }); } -- (NSDictionary*)eventDictForEventName:(NSString*)eventName withAttributes:(NSDictionary*)attributes eventClass:(SFAnalyticsEventClass)eventClass +- (void)logEventNamed:(NSString*)eventName class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attributes +{ + [self logEventNamed:eventName class:class attributes:attributes timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + +- (NSDictionary*) eventDictForEventName:(NSString*)eventName withAttributes:(NSDictionary*)attributes eventClass:(SFAnalyticsEventClass)eventClass timestampBucket:(NSTimeInterval)timestampBucket { NSMutableDictionary* eventDict = attributes ? attributes.mutableCopy : [NSMutableDictionary dictionary]; eventDict[SFAnalyticsEventType] = eventName; + + NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970WithBucket:timestampBucket]; + // our backend wants timestamps in milliseconds - eventDict[SFAnalyticsEventTime] = @([[NSDate date] timeIntervalSince1970] * 1000); + eventDict[SFAnalyticsEventTime] = @(timestamp * 1000); eventDict[SFAnalyticsEventClassKey] = @(eventClass); [SFAnalytics addOSVersionToEvent:eventDict]; @@ -500,11 +648,14 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; __weak __typeof(self) weakSelf = self; dispatch_async(_queue, ^{ + os_transaction_t transaction = os_transaction_create("com.apple.security.sfanalytics.samplerGC"); __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 [strongSelf->_samplers removeObjectForKey:samplerName]; } + (void)transaction; + transaction = nil; }); } @@ -517,11 +668,14 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; __weak __typeof(self) weakSelf = self; dispatch_async(_queue, ^{ + os_transaction_t transaction = os_transaction_create("com.apple.security.sfanalytics.samplerGC"); __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 [strongSelf->_multisamplers removeObjectForKey:samplerName]; } + (void)transaction; + transaction = nil; }); } @@ -538,6 +692,17 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; return tracker; } +- (SFAnalyticsActivityTracker*)startLogSystemMetricsForActivityNamed:(NSString *)eventName +{ + if (![eventName isKindOfClass:[NSString class]]) { + secerror("Cannot log system metrics without name"); + return nil; + } + SFAnalyticsActivityTracker* tracker = [[SFAnalyticsActivityTracker alloc] initWithName:eventName clientClass:[self class]]; + [tracker start]; + return tracker; +} + - (void)logMetric:(NSNumber *)metric withName:(NSString *)metricName { [self logMetric:metric withName:metricName oncePerReport:NO]; @@ -552,6 +717,7 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; __weak __typeof(self) weakSelf = self; dispatch_async(_queue, ^{ + os_transaction_t transaction = os_transaction_create("com.apple.security.sfanalytics.samplerGC"); __strong __typeof(self) strongSelf = weakSelf; if (strongSelf && !strongSelf->_disableLogging) { if (once) { @@ -559,6 +725,8 @@ const NSTimeInterval SFAnalyticsSamplerIntervalOncePerReport = -1.0; } [strongSelf.database addSample:metric forName:metricName]; } + (void)transaction; + transaction = nil; }); } diff --git a/Analytics/SFAnalytics.plist b/Analytics/SFAnalytics.plist index 964747db..76b0892b 100644 --- a/Analytics/SFAnalytics.plist +++ b/Analytics/SFAnalytics.plist @@ -11,6 +11,17 @@ splunk_bagURL https://xp.apple.com/config/1/report/xp_sear_keysync + CloudServicesTopic + + splunk_allowInsecureCertificate + + splunk_topic + xp_coreos_securebackup + splunk_bagURL + https://xp.apple.com/config/1/report/xp_coreos_securebackup + splunk_uploadURL + https://xp.apple.com/report/2/xp_coreos_securebackup + TrustTopic splunk_allowInsecureCertificate @@ -22,5 +33,14 @@ disableClientId + TransparencyTopic + + splunk_allowInsecureCertificate + + splunk_topic + TransparencyAnalytics + splunk_bagURL + https://metrics-config.icloud.com/config/TransparencyAnalytics + diff --git a/Analytics/SFAnalyticsActivityTracker.h b/Analytics/SFAnalyticsActivityTracker.h index 5f5c9360..7a58f5a4 100644 --- a/Analytics/SFAnalyticsActivityTracker.h +++ b/Analytics/SFAnalyticsActivityTracker.h @@ -27,8 +27,12 @@ #import +NS_ASSUME_NONNULL_BEGIN + @interface SFAnalyticsActivityTracker : NSObject +@property (readonly, nullable) NSNumber * measurement; + - (instancetype)init NS_UNAVAILABLE; - (void)performAction:(void (^)(void))action; - (void)cancel; @@ -36,7 +40,12 @@ - (void)start; - (void)stop; +- (void)stopWithEvent:(NSString*)eventName + result:(NSError* _Nullable)eventResultError; + @end +NS_ASSUME_NONNULL_END + #endif #endif diff --git a/Analytics/SFAnalyticsActivityTracker.m b/Analytics/SFAnalyticsActivityTracker.m index 4d1379bd..07c954dd 100644 --- a/Analytics/SFAnalyticsActivityTracker.m +++ b/Analytics/SFAnalyticsActivityTracker.m @@ -29,15 +29,20 @@ #import #import "utilities/debugging.h" +@interface SFAnalyticsActivityTracker () +@property (readwrite) NSNumber * measurement; +@end + @implementation SFAnalyticsActivityTracker { dispatch_queue_t _queue; NSString* _name; Class _clientClass; - NSNumber* _measurement; uint64_t _start; BOOL _canceled; } +@synthesize measurement = _measurement; + - (instancetype)initWithName:(NSString*)name clientClass:(Class)className { if (![name isKindOfClass:[NSString class]] || ![className isSubclassOfClass:[SFAnalytics class]] ) { secerror("Cannot instantiate SFActivityTracker without name and client class"); @@ -92,6 +97,14 @@ _start = 0; } +- (void)stopWithEvent:(NSString*)eventName + result:(NSError* _Nullable)eventResultError +{ + [self stop]; + + [[_clientClass logger] logResultForEvent:eventName hardFailure:false result:eventResultError]; +} + - (void)cancel { _canceled = YES; diff --git a/Analytics/SFAnalyticsDefines.h b/Analytics/SFAnalyticsDefines.h index 53d8420f..2291ca02 100644 --- a/Analytics/SFAnalyticsDefines.h +++ b/Analytics/SFAnalyticsDefines.h @@ -30,7 +30,7 @@ extern NSString* const SFAnalyticsTableSuccessCount; extern NSString* const SFAnalyticsTableHardFailures; extern NSString* const SFAnalyticsTableSoftFailures; extern NSString* const SFAnalyticsTableSamples; -extern NSString* const SFAnalyticsTableAllEvents; +extern NSString* const SFAnalyticsTableNotes; extern NSString* const SFAnalyticsColumnSuccessCount; extern NSString* const SFAnalyticsColumnHardFailureCount; @@ -40,6 +40,8 @@ extern NSString* const SFAnalyticsColumnSampleName; extern NSString* const SFAnalyticsEventTime; extern NSString* const SFAnalyticsEventType; +extern NSString* const SFAnalyticsEventTypeErrorEvent; +extern NSString* const SFAnalyticsEventErrorDestription; extern NSString* const SFAnalyticsEventClassKey; // Helpers for logging NSErrors @@ -47,13 +49,17 @@ extern NSString* const SFAnalyticsAttributeErrorUnderlyingChain; extern NSString* const SFAnalyticsAttributeErrorDomain; extern NSString* const SFAnalyticsAttributeErrorCode; +extern NSString* const SFAnalyticsAttributeLastUploadTime; + extern NSString* const SFAnalyticsUserDefaultsSuite; extern char* const SFAnalyticsFireSamplersNotification; /* Internal Topic Names */ +extern NSString* const SFAnalyticsTopicCloudServices; extern NSString* const SFAnalyticsTopicKeySync; -extern NSString* const SFAnaltyicsTopicTrust; +extern NSString* const SFAnalyticsTopicTrust; +extern NSString* const SFAnalyticsTopicTransparency; typedef NS_ENUM(NSInteger, SFAnalyticsEventClass) { SFAnalyticsEventClassSuccess, diff --git a/Analytics/SFAnalyticsMultiSampler.h b/Analytics/SFAnalyticsMultiSampler.h index 93284f06..3eb8a627 100644 --- a/Analytics/SFAnalyticsMultiSampler.h +++ b/Analytics/SFAnalyticsMultiSampler.h @@ -31,6 +31,7 @@ @property (nonatomic) NSTimeInterval samplingInterval; @property (nonatomic, readonly) NSString* name; +@property (nonatomic, readonly) BOOL oncePerReport; - (instancetype)init NS_UNAVAILABLE; - (NSDictionary*)sampleNow; diff --git a/Analytics/SFAnalyticsMultiSampler.m b/Analytics/SFAnalyticsMultiSampler.m index 638f338f..fed390ec 100644 --- a/Analytics/SFAnalyticsMultiSampler.m +++ b/Analytics/SFAnalyticsMultiSampler.m @@ -43,6 +43,7 @@ @synthesize name = _name; @synthesize samplingInterval = _samplingInterval; +@synthesize oncePerReport = _oncePerReport; - (instancetype)initWithName:(NSString*)name interval:(NSTimeInterval)interval block:(MultiSamplerDictionary (^)(void))block clientClass:(Class)clientClass { diff --git a/Analytics/SFAnalyticsSQLiteStore.h b/Analytics/SFAnalyticsSQLiteStore.h index 3cecef1e..16531fa5 100644 --- a/Analytics/SFAnalyticsSQLiteStore.h +++ b/Analytics/SFAnalyticsSQLiteStore.h @@ -23,7 +23,8 @@ #if __OBJC2__ -#import "SFSQLite.h" +#import "Analytics/SQLite/SFSQLite.h" +#import "SFAnalytics.h" @interface SFAnalyticsSQLiteStore : SFSQLite @@ -43,6 +44,7 @@ - (NSInteger)hardFailureCountForEventType:(NSString*)eventType; - (NSInteger)softFailureCountForEventType:(NSString*)eventType; - (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table; +- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table timestampBucket:(SFAnalyticsTimestampBucket)timestampBucket; - (void)addSample:(NSNumber*)value forName:(NSString*)name; - (void)removeAllSamplesForName:(NSString*)name; - (void)clearAllData; diff --git a/Analytics/SFAnalyticsSQLiteStore.m b/Analytics/SFAnalyticsSQLiteStore.m index 76b4c43f..872b0d2b 100644 --- a/Analytics/SFAnalyticsSQLiteStore.m +++ b/Analytics/SFAnalyticsSQLiteStore.m @@ -24,8 +24,9 @@ #if __OBJC2__ #import "SFAnalyticsSQLiteStore.h" -#import "SFAnalyticsDefines.h" -#import "debugging.h" +#import "NSDate+SFAnalytics.h" +#import "Analytics/SFAnalyticsDefines.h" +#import "utilities/debugging.h" NSString* const SFAnalyticsColumnEventType = @"event_type"; NSString* const SFAnalyticsColumnDate = @"timestamp"; @@ -196,7 +197,31 @@ NSString* const SFAnalyticsUploadDate = @"upload_date"; if (![self tryToOpenDatabase]) { return [NSArray new]; } - return [self deserializedRecords:[self select:@[SFAnalyticsColumnData] from:SFAnalyticsTableAllEvents]]; + + [self begin]; + + NSMutableArray *all = [NSMutableArray new]; + + NSArray *hard = [self select:@[SFAnalyticsColumnDate, SFAnalyticsColumnData] from:SFAnalyticsTableHardFailures]; + [all addObjectsFromArray:hard]; + hard = nil; + + NSArray *soft = [self select:@[SFAnalyticsColumnDate, SFAnalyticsColumnData] from:SFAnalyticsTableSoftFailures]; + [all addObjectsFromArray:soft]; + soft = nil; + + NSArray *notes = [self select:@[SFAnalyticsColumnDate, SFAnalyticsColumnData] from:SFAnalyticsTableNotes]; + [all addObjectsFromArray:notes]; + notes = nil; + + [self end]; + + [all sortUsingComparator:^NSComparisonResult(NSDictionary *_Nonnull obj1, NSDictionary *_Nonnull obj2) { + NSDate *date1 = obj1[SFAnalyticsColumnDate]; + NSDate *date2 = obj2[SFAnalyticsColumnDate]; + return [date1 compare:date2]; + }]; + return [self deserializedRecords:all]; } - (NSArray*)samples @@ -207,21 +232,28 @@ NSString* const SFAnalyticsUploadDate = @"upload_date"; return [self select:@[SFAnalyticsColumnSampleName, SFAnalyticsColumnSampleValue] from:SFAnalyticsTableSamples]; } -- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table +- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table timestampBucket:(SFAnalyticsTimestampBucket)bucket { if (![self tryToOpenDatabase]) { return; } + + NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970WithBucket:bucket]; NSError* error = nil; NSData* serializedRecord = [NSPropertyListSerialization dataWithPropertyList:eventDict format:NSPropertyListBinaryFormat_v1_0 options:0 error:&error]; if(!error && serializedRecord) { - [self insertOrReplaceInto:table values:@{SFAnalyticsColumnDate : @([[NSDate date] timeIntervalSince1970]), SFAnalyticsColumnData : serializedRecord}]; + [self insertOrReplaceInto:table values:@{SFAnalyticsColumnDate : @(timestamp), SFAnalyticsColumnData : serializedRecord}]; } if(error && !serializedRecord) { secerror("Couldn't serialize failure record: %@", error); } } +- (void)addEventDict:(NSDictionary*)eventDict toTable:(NSString*)table +{ + [self addEventDict:eventDict toTable:table timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + - (void)addSample:(NSNumber*)value forName:(NSString*)name { if (![self tryToOpenDatabase]) { @@ -263,7 +295,6 @@ NSString* const SFAnalyticsUploadDate = @"upload_date"; [self deleteFrom:SFAnalyticsTableHardFailures where:@"id >= 0" bindings:nil]; [self deleteFrom:SFAnalyticsTableSoftFailures where:@"id >= 0" bindings:nil]; [self deleteFrom:SFAnalyticsTableSamples where:@"id >= 0" bindings:nil]; - [self deleteFrom:SFAnalyticsTableAllEvents where:@"id >= 0" bindings:nil]; } @end diff --git a/Analytics/SFAnalyticsSampler.h b/Analytics/SFAnalyticsSampler.h index 3844d8f4..ddfb75f3 100644 --- a/Analytics/SFAnalyticsSampler.h +++ b/Analytics/SFAnalyticsSampler.h @@ -31,6 +31,7 @@ @property (nonatomic) NSTimeInterval samplingInterval; @property (nonatomic, readonly) NSString* name; +@property (nonatomic, readonly) BOOL oncePerReport; - (instancetype)init NS_UNAVAILABLE; - (NSNumber*)sampleNow; diff --git a/Analytics/SFAnalyticsSampler.m b/Analytics/SFAnalyticsSampler.m index bd887abf..034efc30 100644 --- a/Analytics/SFAnalyticsSampler.m +++ b/Analytics/SFAnalyticsSampler.m @@ -43,6 +43,8 @@ @synthesize name = _name; @synthesize samplingInterval = _samplingInterval; +@synthesize oncePerReport = _oncePerReport; + - (instancetype)initWithName:(NSString*)name interval:(NSTimeInterval)interval block:(NSNumber* (^)(void))block clientClass:(Class)clientClass { diff --git a/Analytics/SQLite/SFObjCType.h b/Analytics/SQLite/SFObjCType.h index 50400597..adafb7a2 100644 --- a/Analytics/SQLite/SFObjCType.h +++ b/Analytics/SQLite/SFObjCType.h @@ -21,6 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ +#ifndef SECURITY_SFSQL_OBJCTYPE_H +#define SECURITY_SFSQL_OBJCTYPE_H 1 + #if __OBJC2__ #import @@ -90,3 +93,4 @@ typedef NS_ENUM(NSInteger, SFObjCTypeFlag) { @end #endif +#endif /* SECURITY_SFSQL_OBJCTYPE_H */ diff --git a/Analytics/SQLite/SFSQLite.h b/Analytics/SQLite/SFSQLite.h index 6ec9d0f8..0ced9471 100644 --- a/Analytics/SQLite/SFSQLite.h +++ b/Analytics/SQLite/SFSQLite.h @@ -23,6 +23,9 @@ // Header exposed for unit testing only +#ifndef SECURITY_SFSQL_H +#define SECURITY_SFSQL_H 1 + #if __OBJC2__ #import @@ -149,4 +152,5 @@ typedef NS_ENUM(NSInteger, SFSQLiteSynchronousMode) { @end -#endif +#endif /* __OBJC2__ */ +#endif /* SECURITY_SFSQL_H */ diff --git a/Analytics/SQLite/SFSQLite.m b/Analytics/SQLite/SFSQLite.m index 48aec13c..fcde86f7 100644 --- a/Analytics/SQLite/SFSQLite.m +++ b/Analytics/SQLite/SFSQLite.m @@ -27,7 +27,7 @@ #import "SFSQLiteStatement.h" #include #include -#import "debugging.h" +#import "utilities/debugging.h" #include #define kSFSQLiteBusyTimeout (5*60*1000) @@ -64,6 +64,7 @@ NSArray *SFSQLiteJournalSuffixes() { @property (nonatomic, assign) BOOL corrupt; @property (nonatomic, readonly, strong) NSMutableDictionary *statementsBySQL; @property (nonatomic, strong) NSDateFormatter *dateFormatter; +@property (nonatomic, strong) NSDateFormatter *oldDateFormatter; @end @@ -226,6 +227,7 @@ allDone: @synthesize corrupt = _corrupt; @synthesize statementsBySQL = _statementsBySQL; @synthesize dateFormatter = _dateFormatter; +@synthesize oldDateFormatter = _oldDateFormatter; #if DEBUG @synthesize unitTestOverrides = _unitTestOverrides; #endif @@ -628,16 +630,29 @@ done: - (NSDateFormatter *)dateFormatter { if (!_dateFormatter) { NSDateFormatter* dateFormatter = [NSDateFormatter new]; - dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZZZZZ"; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"; _dateFormatter = dateFormatter; } return _dateFormatter; } +- (NSDateFormatter *)oldDateFormatter { + if (!_oldDateFormatter) { + NSDateFormatter* dateFormatter = [NSDateFormatter new]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ssZZZZZ"; + _oldDateFormatter = dateFormatter; + } + return _oldDateFormatter; +} + - (NSDate *)datePropertyForKey:(NSString *)key { NSString *dateStr = [self propertyForKey:key]; if (dateStr.length) { - return [self.dateFormatter dateFromString:dateStr]; + NSDate *date = [self.dateFormatter dateFromString:dateStr]; + if (date == NULL) { + date = [self.oldDateFormatter dateFromString:dateStr]; + } + return date; } return nil; } diff --git a/Analytics/SQLite/SFSQLiteStatement.h b/Analytics/SQLite/SFSQLiteStatement.h index cdace807..01ae854f 100644 --- a/Analytics/SQLite/SFSQLiteStatement.h +++ b/Analytics/SQLite/SFSQLiteStatement.h @@ -21,6 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ +#ifndef SECURITY_SFSQLSTATEMENT_H +#define SECURITY_SFSQLSTATEMENT_H 1 + #if __OBJC2__ #import @@ -73,4 +76,5 @@ @end -#endif +#endif /* __OBJC2__ */ +#endif /* SECURITY_SFSQLSTATEMENT_H */ diff --git a/Analytics/SQLite/SFSQLiteStatement.m b/Analytics/SQLite/SFSQLiteStatement.m index bbc58697..ecc9269a 100644 --- a/Analytics/SQLite/SFSQLiteStatement.m +++ b/Analytics/SQLite/SFSQLiteStatement.m @@ -27,7 +27,7 @@ #import "SFSQLite.h" #import "SFSQLiteStatement.h" #import "SFObjCType.h" -#import "debugging.h" +#import "utilities/debugging.h" @interface SFSQLiteStatement () @property (nonatomic, strong) NSMutableArray *temporaryBoundObjects; diff --git a/libsecurity_smime/lib/CMSDecoder.h b/CMS/CMSDecoder.h similarity index 76% rename from libsecurity_smime/lib/CMSDecoder.h rename to CMS/CMSDecoder.h index bc6d689f..031ad4a4 100644 --- a/libsecurity_smime/lib/CMSDecoder.h +++ b/CMS/CMSDecoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -34,8 +34,6 @@ #include #include #include -#include -#include #include #include @@ -55,7 +53,7 @@ CFTypeID CMSDecoderGetTypeID(void); /* * Status of signature and signer information in a signed message. */ -typedef CF_ENUM(int32_t, CMSSignerStatus) { +typedef CF_ENUM(uint32_t, CMSSignerStatus) { kCMSSignerUnsigned = 0, /* message was not signed */ kCMSSignerValid, /* message was signed and signature verify OK */ kCMSSignerNeedsDetachedContent, /* message was signed but needs detached content @@ -70,7 +68,7 @@ typedef CF_ENUM(int32_t, CMSSignerStatus) { * Create a CMSDecoder. Result must eventually be freed via CFRelease(). */ OSStatus CMSDecoderCreate(CMSDecoderRef * __nonnull CF_RETURNS_RETAINED cmsDecoderOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Feed raw bytes of the message to be decoded into the decoder. Can be called @@ -82,7 +80,7 @@ OSStatus CMSDecoderUpdateMessage( CMSDecoderRef cmsDecoder, const void *msgBytes, size_t msgBytesLen) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; @@ -91,7 +89,7 @@ OSStatus CMSDecoderUpdateMessage( * message. */ OSStatus CMSDecoderFinalizeMessage(CMSDecoderRef cmsDecoder) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * A signed CMS message optionally includes the data which was signed. If the @@ -107,7 +105,7 @@ OSStatus CMSDecoderFinalizeMessage(CMSDecoderRef cmsDecoder) OSStatus CMSDecoderSetDetachedContent( CMSDecoderRef cmsDecoder, CFDataRef detachedContent) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the detached content specified in CMSDecoderSetDetachedContent(). @@ -117,7 +115,18 @@ OSStatus CMSDecoderSetDetachedContent( OSStatus CMSDecoderCopyDetachedContent( CMSDecoderRef cmsDecoder, CFDataRef * __nonnull CF_RETURNS_RETAINED detachedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); + +#if SEC_OS_OSX +/* + * This function no longer affects the behavior of the CMS Decoder. Please + * discontinue use. + */ +OSStatus CMSDecoderSetSearchKeychain( + CMSDecoderRef cmsDecoder, + CFTypeRef keychainOrArray) + API_DEPRECATED_WITH_REPLACEMENT("SecKeychainSetSearchList",macos(10.5, 10.13)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); +#endif // SEC_OS_OSX /* * Obtain the number of signers of a message. A result of zero indicates that @@ -127,7 +136,7 @@ OSStatus CMSDecoderCopyDetachedContent( OSStatus CMSDecoderGetNumSigners( CMSDecoderRef cmsDecoder, size_t *numSignersOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the status of a CMS message's signature. A CMS message can @@ -211,7 +220,7 @@ OSStatus CMSDecoderCopySignerStatus( CMSSignerStatus * __nullable signerStatusOut, /* optional; RETURNED */ SecTrustRef * __nullable CF_RETURNS_RETAINED secTrustOut, /* optional; RETURNED */ OSStatus * __nullable certVerifyResultCodeOut) /* optional; RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the email address of signer 'signerIndex' of a CMS message, if @@ -226,7 +235,7 @@ OSStatus CMSDecoderCopySignerEmailAddress( CMSDecoderRef cmsDecoder, size_t signerIndex, CFStringRef * __nonnull CF_RETURNS_RETAINED signerEmailAddressOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the certificate of signer 'signerIndex' of a CMS message, if @@ -241,7 +250,7 @@ OSStatus CMSDecoderCopySignerCert( CMSDecoderRef cmsDecoder, size_t signerIndex, SecCertificateRef * __nonnull CF_RETURNS_RETAINED signerCertOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not. @@ -253,7 +262,7 @@ OSStatus CMSDecoderCopySignerCert( OSStatus CMSDecoderIsContentEncrypted( CMSDecoderRef cmsDecoder, Boolean *isEncryptedOut) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if @@ -265,7 +274,7 @@ OSStatus CMSDecoderIsContentEncrypted( OSStatus CMSDecoderCopyEncapsulatedContentType( CMSDecoderRef cmsDecoder, CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain an array of all of the certificates in a message. Elements of the @@ -278,7 +287,7 @@ OSStatus CMSDecoderCopyEncapsulatedContentType( OSStatus CMSDecoderCopyAllCerts( CMSDecoderRef cmsDecoder, CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the actual message content (payload), if any. If the message was @@ -289,7 +298,7 @@ OSStatus CMSDecoderCopyAllCerts( OSStatus CMSDecoderCopyContent( CMSDecoderRef cmsDecoder, CFDataRef * __nonnull CF_RETURNS_RETAINED contentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the signing time of signer 'signerIndex' of a CMS message, if @@ -305,9 +314,8 @@ OSStatus CMSDecoderCopySignerSigningTime( CMSDecoderRef cmsDecoder, size_t signerIndex, CFAbsoluteTime *signingTime) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_11_0); + __API_AVAILABLE(macos(10.8)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); -#if TIMESTAMPING_SUPPORTED /* * Obtain the timestamp of signer 'signerIndex' of a CMS message, if * present. This timestamp is an authenticated timestamp provided by @@ -322,7 +330,7 @@ OSStatus CMSDecoderCopySignerTimestamp( CMSDecoderRef cmsDecoder, size_t signerIndex, CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* * Obtain the timestamp of signer 'signerIndex' of a CMS message, if @@ -339,7 +347,7 @@ OSStatus CMSDecoderCopySignerTimestampWithPolicy( CFTypeRef __nullable timeStampPolicy, size_t signerIndex, /* usually 0 */ CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); + API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* * Obtain an array of the certificates in a timestamp response. Elements of the @@ -357,89 +365,7 @@ OSStatus CMSDecoderCopySignerTimestampCertificates( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ CFArrayRef * __nonnull CF_RETURNS_RETAINED certificateRefs) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); -#endif - -/* - * Obtain the SecCmsMessageRef associated with a CMSDecoderRef. Intended - * to be called after decoding the message (i.e., after - * CMSDecoderFinalizeMessage() to gain finer access to the contents of the - * SecCmsMessageRef than is otherwise available via the CMSDecoder interface. - * Returns a NULL SecCmsMessageRef if CMSDecoderFinalizeMessage() has not been - * called. - * - * The CMSDecoder retains ownership of the returned SecCmsMessageRef. - */ -OSStatus CMSDecoderGetCmsMessage( - CMSDecoderRef cmsDecoder, - SecCmsMessageRef _Nullable * _Nonnull cmsMessage); /* RETURNED */ - - -/* - * Optionally specify a SecCmsDecoderRef to use with a CMSDecoderRef. - * If this is called, it must be called before the first call to - * CMSDecoderUpdateMessage(). The CMSDecoderRef takes ownership of the - * incoming SecCmsDecoderRef. - */ -OSStatus CMSDecoderSetDecoder( - CMSDecoderRef cmsDecoder, - SecCmsDecoderRef decoder); - -/* - * Obtain the SecCmsDecoderRef associated with a CMSDecoderRef. - * Returns a NULL SecCmsDecoderRef if neither CMSDecoderSetDecoder() nor - * CMSDecoderUpdateMessage() has been called. - * The CMSDecoderRef retains ownership of the SecCmsDecoderRef. - */ -OSStatus CMSDecoderGetDecoder( - CMSDecoderRef cmsDecoder, - SecCmsDecoderRef _Nullable * _Nonnull decoder); /* RETURNED */ - -/* - * Obtain the Hash Agility attribute value of signer 'signerIndex' - * of a CMS message, if present. - * - * 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 CMSDecoderCopySignerAppleCodesigningHashAgility( - CMSDecoderRef cmsDecoder, - size_t signerIndex, /* usually 0 */ - 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' - * of a CMS message, if present. V2 encodes the hash agility values using DER. - * - * 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 CMSDecoderCopySignerAppleCodesigningHashAgilityV2( - CMSDecoderRef cmsDecoder, - size_t signerIndex, /* usually 0 */ - 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)); - + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); CF_ASSUME_NONNULL_END diff --git a/libsecurity_smime/lib/CMSEncoder.h b/CMS/CMSEncoder.h similarity index 72% rename from libsecurity_smime/lib/CMSEncoder.h rename to CMS/CMSEncoder.h index d91fa1da..276b72ef 100644 --- a/libsecurity_smime/lib/CMSEncoder.h +++ b/CMS/CMSEncoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -42,11 +42,13 @@ #define _CMS_ENCODER_H_ #include -#include -#include -#include #include #include +#include + +#if SEC_OS_OSX +#include +#endif __BEGIN_DECLS @@ -60,13 +62,13 @@ CF_ASSUME_NONNULL_BEGIN typedef struct CF_BRIDGED_TYPE(id) _CMSEncoder *CMSEncoderRef; CFTypeID CMSEncoderGetTypeID(void) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Create a CMSEncoder. Result must eventually be freed via CFRelease(). */ OSStatus CMSEncoderCreate(CMSEncoderRef * __nonnull CF_RETURNS_RETAINED cmsEncoderOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); extern const CFStringRef kCMSEncoderDigestAlgorithmSHA1; extern const CFStringRef kCMSEncoderDigestAlgorithmSHA256; @@ -74,7 +76,7 @@ extern const CFStringRef kCMSEncoderDigestAlgorithmSHA256; OSStatus CMSEncoderSetSignerAlgorithm( CMSEncoderRef cmsEncoder, CFStringRef digestAlgorithm) - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_11_0); + __API_AVAILABLE(macos(10.11)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Specify signers of the CMS message; implies that the message will be signed. @@ -89,7 +91,7 @@ OSStatus CMSEncoderSetSignerAlgorithm( OSStatus CMSEncoderAddSigners( CMSEncoderRef cmsEncoder, CFTypeRef signerOrArray) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain an array of signers as specified in CMSEncoderSetSigners(). @@ -99,7 +101,7 @@ OSStatus CMSEncoderAddSigners( OSStatus CMSEncoderCopySigners( CMSEncoderRef cmsEncoder, CFArrayRef * __nonnull CF_RETURNS_RETAINED signersOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Specify recipients of the message. Implies that the message will @@ -115,7 +117,7 @@ OSStatus CMSEncoderCopySigners( OSStatus CMSEncoderAddRecipients( CMSEncoderRef cmsEncoder, CFTypeRef recipientOrArray) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain an array of recipients as specified in CMSEncoderSetRecipients(). @@ -126,7 +128,7 @@ OSStatus CMSEncoderAddRecipients( OSStatus CMSEncoderCopyRecipients( CMSEncoderRef cmsEncoder, CFArrayRef * __nonnull CF_RETURNS_RETAINED recipientsOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * A signed message optionally includes the data to be signed. If the message @@ -142,7 +144,7 @@ OSStatus CMSEncoderCopyRecipients( OSStatus CMSEncoderSetHasDetachedContent( CMSEncoderRef cmsEncoder, Boolean detachedContent) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain a Boolean indicating whether the current message will have detached @@ -153,7 +155,26 @@ OSStatus CMSEncoderSetHasDetachedContent( OSStatus CMSEncoderGetHasDetachedContent( CMSEncoderRef cmsEncoder, Boolean *detachedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); + +#if SEC_OS_OSX +/* + * Optionally specify an eContentType OID for the inner EncapsulatedData for + * a signed message. The default eContentType, used if this function is not + * called, is id-data (which is the normal eContentType for applications such + * as SMIME). + * + * If this is called, it must be called before the first call to + * CMSEncoderUpdateContent(). + * + * NOTE: This function is deprecated in Mac OS X 10.7 and later; + * please use CMSEncoderSetEncapsulatedContentTypeOID() instead. + */ +OSStatus CMSEncoderSetEncapsulatedContentType( + CMSEncoderRef cmsEncoder, + const CSSM_OID *eContentType) + API_DEPRECATED_WITH_REPLACEMENT("CMSEncoderSetEncapsulatedContentTypeOID", macos(10.5, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); +#endif // SEC_OS_OSX /* * Optionally specify an eContentType OID for the inner EncapsulatedData for @@ -170,7 +191,7 @@ OSStatus CMSEncoderGetHasDetachedContent( OSStatus CMSEncoderSetEncapsulatedContentTypeOID( CMSEncoderRef cmsEncoder, CFTypeRef eContentTypeOID) - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_11_0); + __API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the eContentType OID specified in CMSEncoderSetEncapsulatedContentType(). @@ -183,7 +204,7 @@ OSStatus CMSEncoderSetEncapsulatedContentTypeOID( OSStatus CMSEncoderCopyEncapsulatedContentType( CMSEncoderRef cmsEncoder, CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Signed CMS messages can contain arbitrary sets of certificates beyond those @@ -208,7 +229,7 @@ OSStatus CMSEncoderCopyEncapsulatedContentType( OSStatus CMSEncoderAddSupportingCerts( CMSEncoderRef cmsEncoder, CFTypeRef certOrArray) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain the SecCertificates provided in CMSEncoderAddSupportingCerts(). @@ -219,7 +240,7 @@ OSStatus CMSEncoderAddSupportingCerts( OSStatus CMSEncoderCopySupportingCerts( CMSEncoderRef cmsEncoder, CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Standard signed attributes, optionally specified in @@ -264,7 +285,7 @@ typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) { OSStatus CMSEncoderAddSignedAttributes( CMSEncoderRef cmsEncoder, CMSSignedAttributes signedAttributes) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Specification of what certificates to include in a signed message. @@ -274,7 +295,10 @@ typedef CF_ENUM(uint32_t, CMSCertificateChainMode) { kCMSCertificateSignerOnly, /* only include signer certificate(s) */ kCMSCertificateChain, /* signer certificate chain up to but not * including root certiticate */ - kCMSCertificateChainWithRoot /* signer certificate chain including root */ + kCMSCertificateChainWithRoot, /* signer certificate chain including root */ + kCMSCertificateChainWithRootOrFail, /* signer certificate chain including root + * and if chain not terminated by a self-signed cert, + * fail to create CMS */ }; /* @@ -289,7 +313,7 @@ typedef CF_ENUM(uint32_t, CMSCertificateChainMode) { OSStatus CMSEncoderSetCertificateChainMode( CMSEncoderRef cmsEncoder, CMSCertificateChainMode chainMode) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Obtain indication of which signer certs are to be included @@ -298,7 +322,7 @@ OSStatus CMSEncoderSetCertificateChainMode( OSStatus CMSEncoderGetCertificateChainMode( CMSEncoderRef cmsEncoder, CMSCertificateChainMode *chainModeOut) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Feed content bytes into the encoder. @@ -309,7 +333,7 @@ OSStatus CMSEncoderUpdateContent( CMSEncoderRef cmsEncoder, const void *content, size_t contentLen) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); /* * Finish encoding the message and obtain the encoded result. @@ -318,7 +342,43 @@ OSStatus CMSEncoderUpdateContent( OSStatus CMSEncoderCopyEncodedContent( CMSEncoderRef cmsEncoder, CFDataRef * __nonnull CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_11_0); + __API_AVAILABLE(macos(10.5)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); + +#if TARGET_OS_OSX +/* + * High-level, one-shot encoder function. + * + * Inputs (all except for content optional, though at least one + * of {signers, recipients} must be non-NULL) + * ------------------------------------------------------------ + * signers : signer identities. Either a SecIdentityRef, or a + * CFArray of them. + * recipients : recipient certificates. Either a SecCertificateRef, + * or a CFArray of them. + * eContentType : contentType for inner EncapsulatedData. + * detachedContent : when true, do not include the signed data in the message. + * signedAttributes : Specifies which standard signed attributes are to be + * included in the message. + * content : raw content to be signed and/or encrypted. + * + * Output + * ------ + * encodedContent : the result of the encoding. + * + * NOTE: This function is deprecated in Mac OS X 10.7 and later; + * please use CMSEncodeContent() instead. + */ +OSStatus CMSEncode( + CFTypeRef __nullable signers, + CFTypeRef __nullable recipients, + const CSSM_OID * __nullable eContentType, + Boolean detachedContent, + CMSSignedAttributes signedAttributes, + const void * content, + size_t contentLen, + CFDataRef * __nonnull CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ + API_DEPRECATED_WITH_REPLACEMENT("CMSEncodeContent", macos(10.5, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); +#endif // TARGET_OS_OSX /* * High-level, one-shot encoder function. @@ -350,96 +410,20 @@ OSStatus CMSEncodeContent( const void *content, size_t contentLen, CFDataRef * __nullable CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_11_0); + __API_AVAILABLE(macos(10.7)) SPI_AVAILABLE(ios(11.0), tvos(11.0), watchos(4.0), iosmac(11.0)); -#if TIMESTAMPING_SUPPORTED OSStatus CMSEncoderCopySignerTimestamp( CMSEncoderRef cmsEncoder, size_t signerIndex, /* usually 0 */ CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); OSStatus CMSEncoderCopySignerTimestampWithPolicy( CMSEncoderRef cmsEncoder, CFTypeRef __nullable timeStampPolicy, size_t signerIndex, /* usually 0 */ CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); - -void -CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext); -#endif // TIMESTAMPING_SUPPORTED - -/* - * Obtain the SecCmsMessageRef associated with a CMSEncoderRef. Intended - * to be called after (optionally) setting the encoder's various attributes - * via CMSEncoderAddSigners(), CMSEncoderAddRecipients(), etc. and before - * the first call to CMSEncoderUpdateContent(). The returned SecCmsMessageRef - * will be initialized per the previously specified attributes; the caller - * can manipulate the SecCmsMessageRef prior to proceeding with - * CMSEncoderUpdateContent() calls. - */ -OSStatus CMSEncoderGetCmsMessage( - CMSEncoderRef cmsEncoder, - SecCmsMessageRef _Nullable * _Nonnull cmsMessage); /* RETURNED */ - -/* - * Optionally specify a SecCmsEncoderRef to use with a CMSEncoderRef. - * If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). The CMSEncoderRef takes ownership of the - * incoming SecCmsEncoderRef. - */ -OSStatus CMSEncoderSetEncoder( - CMSEncoderRef cmsEncoder, - SecCmsEncoderRef encoder); - -/* - * Obtain the SecCmsEncoderRef associated with a CMSEncoderRef. - * Returns a NULL SecCmsEncoderRef if neither CMSEncoderSetEncoder nor - * CMSEncoderUpdateContent() has been called. - * The CMSEncoderRef retains ownership of the SecCmsEncoderRef. - */ -OSStatus CMSEncoderGetEncoder( - CMSEncoderRef cmsEncoder, - SecCmsEncoderRef _Nullable * _Nonnull encoder); /* RETURNED */ - -/* - * Set the signing time for a CMSEncoder. - * This is only used if the kCMSAttrSigningTime attribute is included. - */ -OSStatus CMSEncoderSetSigningTime( - CMSEncoderRef cmsEncoder, - CFAbsoluteTime time); - -/* - * Set the hash agility attribute for a CMSEncoder. - * This is only used if the kCMSAttrAppleCodesigningHashAgility attribute - * is included. - */ -OSStatus CMSEncoderSetAppleCodesigningHashAgility( - CMSEncoderRef cmsEncoder, - CFDataRef hashAgilityAttrValue); - -/* - * Set the hash agility attribute for a CMSEncoder. - * This is only used if the kCMSAttrAppleCodesigningHashAgilityV2 attribute - * is included. V2 encodes the hash agility values using DER. - * The dictionary should have CFNumberRef keys, corresponding to SECOidTags - * (from SecCmsBase.h) for digest algorithms, and CFDataRef values, - * corresponding to the digest value for that digest algorithm. - */ -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); - + API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_cms/lib/CMSPrivate.h b/CMS/CMSPrivate.h similarity index 93% rename from OSX/libsecurity_cms/lib/CMSPrivate.h rename to CMS/CMSPrivate.h index d951d912..548a2792 100644 --- a/OSX/libsecurity_cms/lib/CMSPrivate.h +++ b/CMS/CMSPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006,2011-2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -112,8 +112,10 @@ OSStatus CMSEncoderSetAppleExpirationTime( CMSEncoderRef cmsEncoder, CFAbsoluteTime time); + void -CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext); +CmsMessageSetTSAContext(CMSEncoderRef cmsEncoder, CFTypeRef tsaContext) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, tvos, watchos, bridgeos, iosmac); /*** *** Private CMSDecoder routines @@ -166,7 +168,8 @@ OSStatus CMSDecoderGetDecoder( OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ - CFDataRef CF_RETURNS_RETAINED *hashAgilityAttrValue); /* RETURNED */ + CFDataRef CF_RETURNS_RETAINED *hashAgilityAttrValue) /* RETURNED */ + API_AVAILABLE(macos(10.12.4), ios(11.0)); /* * Obtain the Hash Agility v2 attribute value of signer 'signerIndex' @@ -180,7 +183,8 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgility( OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( CMSDecoderRef cmsDecoder, size_t signerIndex, /* usually 0 */ - CFDictionaryRef CF_RETURNS_RETAINED * hashAgilityAttrValues); /* RETURNED */ + CFDictionaryRef CF_RETURNS_RETAINED * hashAgilityAttrValues) /* RETURNED */ + API_AVAILABLE(macos(10.13.4), ios(11.3)); /* * Obtain the expiration time of signer 'signerIndex' of a CMS message, if @@ -192,10 +196,11 @@ OSStatus CMSDecoderCopySignerAppleCodesigningHashAgilityV2( * This cannot be called until after CMSDecoderFinalizeMessage() is called. */ OSStatus CMSDecoderCopySignerAppleExpirationTime( - CMSDecoderRef cmsDecoder, - size_t signerIndex, - CFAbsoluteTime *expirationTime); /* RETURNED */ - + CMSDecoderRef cmsDecoder, + size_t signerIndex, + CFAbsoluteTime *expirationTime) /* RETURNED */ + API_AVAILABLE(macos(10.14), ios(12.0)); + #ifdef __cplusplus } #endif diff --git a/OSX/sec/Security/SecCMS.h b/CMS/SecCMS.h similarity index 97% rename from OSX/sec/Security/SecCMS.h rename to CMS/SecCMS.h index 6ee94941..8670d04e 100644 --- a/OSX/sec/Security/SecCMS.h +++ b/CMS/SecCMS.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2010,2012-2013 Apple Inc. All Rights Reserved. + * Copyright (c) 2008-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -35,7 +35,6 @@ __BEGIN_DECLS -extern const void * kSecCMSBulkEncryptionAlgorithm; extern const void * kSecCMSSignDigest; extern const void * kSecCMSSignDetached; extern const void * kSecCMSSignHashAlgorithm; @@ -48,12 +47,14 @@ extern const void * kSecCMSHashAgility; extern const void * kSecCMSHashAgilityV2; extern const void * kSecCMSExpirationDate; +extern const void * kSecCMSBulkEncryptionAlgorithm; extern const void * kSecCMSEncryptionAlgorithmDESCBC; extern const void * kSecCMSEncryptionAlgorithmAESCBC; -extern const void * kSecCMSHashingAlgorithmMD5 - __IOS_DEPRECATED(__IPHONE_3_1, __IPHONE_10_0, "Disuse this constant in order to upgrade to SHA-1"); + extern const void * kSecCMSCertChainModeNone; +extern const void * kSecCMSHashingAlgorithmMD5 + __API_DEPRECATED("Disuse this constant in order to upgrade to SHA-1", ios(3.1, 10.0), macos(10.15, 10.15)); extern const void * kSecCMSHashingAlgorithmSHA1; extern const void * kSecCMSHashingAlgorithmSHA256; extern const void * kSecCMSHashingAlgorithmSHA384; @@ -91,6 +92,10 @@ OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached OSStatus SecCMSVerify(CFDataRef message, CFDataRef detached_contents, CFTypeRef policy, SecTrustRef *trustref, CFDataRef *attached_contents); +OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents, + CFTypeRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates, + CFDataRef *attached_contents, CFDictionaryRef *message_attributes); + /* Return an array of certificates contained in message, if message is of the type SignedData and has no signers, return NULL otherwise. Not that if @@ -160,7 +165,6 @@ OSStatus SecCMSCreateSignedData(SecIdentityRef identity, CFDataRef data, OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof, CFDictionaryRef params, CFDataRef data, CFMutableDataRef enveloped_data); - /*! @function SecCMSDecryptEnvelopedData @abstract open an enveloped cms blob. expects recipients identity in keychain. @@ -173,10 +177,6 @@ OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof, OSStatus SecCMSDecryptEnvelopedData(CFDataRef message, CFMutableDataRef data, SecCertificateRef *recipient); -OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents, - CFTypeRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates, - CFDataRef *attached_contents, CFDictionaryRef *message_attributes); - __END_DECLS #endif /* !_SECURITY_SECCMS_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsBase.h b/CMS/SecCmsBase.h similarity index 88% rename from OSX/libsecurity_smime/lib/SecCmsBase.h rename to CMS/SecCmsBase.h index 8bc62d4c..44f7eade 100644 --- a/OSX/libsecurity_smime/lib/SecCmsBase.h +++ b/CMS/SecCmsBase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsBase.h - @Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -35,14 +34,17 @@ #ifndef _SECURITY_SECCMSBASE_H_ #define _SECURITY_SECCMSBASE_H_ 1 -#include /* size_t */ +#include +#include #include -#include +#include -#if defined(__cplusplus) -extern "C" { +#if TARGET_OS_OSX +#include #endif +__BEGIN_DECLS + /*! @typedef @discussion XXX We need to remove these from the API and move them back to secoidt.h. @@ -53,13 +55,24 @@ typedef struct SECOidDataStr SECOidData; @typedef @discussion XXX We might want to get rid of this alltogether. */ -typedef CSSM_X509_ALGORITHM_IDENTIFIER SECAlgorithmID DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#if TARGET_OS_OSX +typedef CSSM_X509_ALGORITHM_IDENTIFIER SECAlgorithmID; +#else // !TARGET_OS_OSX +typedef SecAsn1AlgId SECAlgorithmID; +#endif // !TARGET_OS_OSX +#pragma clang diagnostic pop /*! @typedef @discussion XXX This should probably move to SecKey.h */ -typedef SecKeyRef SecSymmetricKeyRef; +#if TARGET_OS_OSX +typedef SecKeyRef SecSymmetricKeyRef API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else +typedef void * SecSymmetricKeyRef API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif /*! @typedef @@ -78,10 +91,12 @@ typedef SecKeyRef SecPrivateKeyRef; */ typedef void(*PK11PasswordFunc)(void); +#if TARGET_OS_OSX /*! - @typedef + @typedef */ typedef struct SecArenaPoolStr *SecArenaPoolRef; +#endif /*! @typedef @@ -155,7 +170,11 @@ 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) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +typedef SecSymmetricKeyRef(*SecCmsGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid) + API_AVAILABLE(macos(10.4), ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop /*! @enum SecCmsVerificationStatus @@ -183,7 +202,8 @@ typedef enum { SecCmsCMNone = 0, SecCmsCMCertOnly = 1, SecCmsCMCertChain = 2, - SecCmsCMCertChainWithRoot = 3 + SecCmsCMCertChainWithRoot = 3, + SecCmsCMCertChainWithRootOrFail = 4, } SecCmsCertChainMode; /*! @@ -462,17 +482,17 @@ typedef enum { SEC_OID_AES_192_KEY_WRAP = 199, SEC_OID_AES_256_KEY_WRAP = 200, - /* eContentType set by client and not understood by this library; treated + /* eContentType set by client and not understood by this library; treated * like SEC_OID_PKCS7_DATA, except the caller's OID is encoded. */ SEC_OID_OTHER = 201, - /* ECDSA */ - SEC_OID_EC_PUBLIC_KEY = 202, - SEC_OID_ECDSA_WithSHA1 = 203, - SEC_OID_DH_SINGLE_STD_SHA1KDF = 204, - SEC_OID_SECP_256_R1 = 205, - SEC_OID_SECP_384_R1 = 206, - SEC_OID_SECP_521_R1 = 207, + /* ECDSA */ + SEC_OID_EC_PUBLIC_KEY = 202, + SEC_OID_ECDSA_WithSHA1 = 203, + SEC_OID_DH_SINGLE_STD_SHA1KDF = 204, + SEC_OID_SECP_256_R1 = 205, + SEC_OID_SECP_384_R1 = 206, + SEC_OID_SECP_521_R1 = 207, /* RFC 3161 Timestamping OIDs */ SEC_OID_PKCS9_ID_CT_TSTInfo = 208, @@ -494,31 +514,30 @@ typedef enum { SEC_OID_TOTAL } SECOidTag; +#if TARGET_OS_OSX /*! - @function - @abstract Create a new SecArenaPool object. - @param chunksize Size of the chunks the pool will use to allocate its underlying storage. - @param outArena pointer to a SecArenaPoolRef to be created. - @result On success return 0 and outArena will contain a newly created SecArenaPoolRef. - @availability 10.4 and later - @updated 2004-04-23 + @function + @abstract Create a new SecArenaPool object. + @param chunksize Size of the chunks the pool will use to allocate its underlying storage. + @param outArena pointer to a SecArenaPoolRef to be created. + @result On success return 0 and outArena will contain a newly created SecArenaPoolRef. + @availability 10.4 and later + @updated 2004-04-23 */ OSStatus SecArenaPoolCreate(size_t chunksize, SecArenaPoolRef *outArena); /*! - @function - @abstract Free a SecArenaPool object and everything in it. - @param arena The SecArenaPool object to free. - @param zero If this is true the arena's memory will be zero filled before it is freed. - @discussion arena will no longer be valid and the memory used by it is returned to the malloc heap. - @availability 10.4 and later - @updated 2004-04-23 + @function + @abstract Free a SecArenaPool object and everything in it. + @param arena The SecArenaPool object to free. + @param zero If this is true the arena's memory will be zero filled before it is freed. + @discussion arena will no longer be valid and the memory used by it is returned to the malloc heap. + @availability 10.4 and later + @updated 2004-04-23 */ void SecArenaPoolFree(SecArenaPoolRef arena, Boolean zero); +#endif // TARGET_OS_OSX - -#if defined(__cplusplus) -} -#endif +__END_DECLS #endif /* _SECURITY_SECCMSBASE_H_ */ diff --git a/CMS/SecCmsContentInfo.h b/CMS/SecCmsContentInfo.h new file mode 100644 index 00000000..c799eb43 --- /dev/null +++ b/CMS/SecCmsContentInfo.h @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2004-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@ + */ + +/*! + @header SecCmsContentInfo.h + + @availability 10.4 and later + @abstract Interfaces of the CMS implementation. + @discussion The functions here implement functions for creating and + accessing ContentInfo objects that are part of Cryptographic + Message Syntax (CMS) objects as described in rfc3369. + */ + +#ifndef _SECURITY_SECCMSCONTENTINFO_H_ +#define _SECURITY_SECCMSCONTENTINFO_H_ 1 + +#include +#include + + +__BEGIN_DECLS + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +/*! @functiongroup ContentInfo accessors */ +/*! + @function + @abstract Get content's contentInfo (if it exists). + @param cinfo A ContentInfo object of which we want to get the child contentInfo. + @result The child ContentInfo object, or NULL if there is none. + @discussion This function requires a ContentInfo object which is usually created by decoding and SecCmsMessage using a SecCmsDecoder. + @availability 10.4 and later + */ +extern SecCmsContentInfoRef +SecCmsContentInfoGetChildContentInfo(SecCmsContentInfoRef cinfo); + +/*! + @function + @abstract Get pointer to inner content + @discussion needs to be casted... + */ +extern void * +SecCmsContentInfoGetContent(SecCmsContentInfoRef cinfo); + +#if TARGET_OS_OSX +/*! + @function + @abstract Get pointer to innermost content + @discussion This is typically only called by SecCmsMessageGetContent(). + */ +extern CSSM_DATA_PTR +SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Get pointer to innermost content + @discussion This is typically only called by SecCmsMessageGetContent(). + */ +extern const SecAsn1Item * +SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +/*! + @function + @abstract Find out and return the inner content type. + */ +extern SECOidTag +SecCmsContentInfoGetContentTypeTag(SecCmsContentInfoRef cinfo); + + +#if TARGET_OS_OSX +/*! + @function + @abstract Find out and return the inner content type. + @discussion Caches pointer to lookup result for future reference. + */ +extern CSSM_OID * +SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Find out and return the inner content type. + @discussion Caches pointer to lookup result for future reference. + */ +extern SecAsn1Oid * +SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +/*! + @function + @abstract Find out and return the content encryption algorithm tag. + */ +extern SECOidTag +SecCmsContentInfoGetContentEncAlgTag(SecCmsContentInfoRef cinfo); + +/*! + @function + @abstract Find out and return the content encryption algorithm. + @discussion Caches pointer to lookup result for future reference. + */ +extern SECAlgorithmID * +SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo) + API_AVAILABLE(macos(10.4), ios(2.0)); + +/*! @functiongroup Message construction */ + +#if TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a Data + @param cmsg A Message object to which the cinfo object belongs. + @param cinfo A ContentInfo object of which we want set the content. + @param data A pointer to a CSSM_DATA object or NULL if data will be provided during SecCmsEncoderUpdate calls. + @param detached True if the content is to be deattched from the CMS message rather than included within it. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object. If the call succeeds the passed in data will be owned by the reciever. The data->Data must have been allocated using the cmsg's SecArenaPool if it is present. + @availability 10.4 through 10.7 + */ +extern OSStatus +SecCmsContentInfoSetContentData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a Data + @param cinfo A ContentInfo object of which we want set the content. + @param data A CFDataRef or NULL if data will be provided during SecCmsEncoderUpdate calls. + @param detached True if the content is to be deattched from the CMS message rather than included within it. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentData(SecCmsContentInfoRef cinfo, CFDataRef data, Boolean detached) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +#if TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a SignedData. + @param cmsg A Message object to which the cinfo object belongs. + @param cinfo A ContentInfo object of which we want set the content. + @param sigd A SignedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a SignedData which can be made by calling SecCmsSignedDataCreate(). If the call succeeds the passed in SignedData object will be owned by the reciever. The Message object of the SignedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentSignedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsSignedDataRef sigd) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a SignedData. + @param cinfo A ContentInfo object of which we want set the content. + @param sigd A SignedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a SignedData which can be made by calling SecCmsSignedDataCreate(). If the call succeeds the passed in SignedData object will be owned by the reciever. The Message object of the SignedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentSignedData(SecCmsContentInfoRef cinfo, SecCmsSignedDataRef sigd) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // TARGET_OS_OSX + +#if TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a EnvelopedData. + @param cmsg A Message object to which the cinfo object belongs. + @param cinfo A ContentInfo object of which we want set the content. + @param envd A EnvelopedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EnvelopedData which can be made by calling SecCmsEnvelopedDataCreate(). If the call succeeds the passed in EnvelopedData object will be owned by the reciever. The Message object of the EnvelopedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentEnvelopedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsEnvelopedDataRef envd) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a EnvelopedData. + @param cinfo A ContentInfo object of which we want set the content. + @param envd A EnvelopedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EnvelopedData which can be made by calling SecCmsEnvelopedDataCreate(). If the call succeeds the passed in EnvelopedData object will be owned by the reciever. The Message object of the EnvelopedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentEnvelopedData(SecCmsContentInfoRef cinfo, SecCmsEnvelopedDataRef envd) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +#if TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a DigestedData. + @param cmsg A Message object to which the cinfo object belongs. + @param cinfo A ContentInfo object of which we want set the content. + @param digd A DigestedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a DigestedData which can be made by calling SecCmsDigestedDataCreate(). If the call succeeds the passed in DigestedData object will be owned by the reciever. The Message object of the DigestedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentDigestedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsDigestedDataRef digd) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a DigestedData. + @param cinfo A ContentInfo object of which we want set the content. + @param digd A DigestedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a DigestedData which can be made by calling SecCmsDigestedDataCreate(). If the call succeeds the passed in DigestedData object will be owned by the reciever. The Message object of the DigestedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentDigestedData(SecCmsContentInfoRef cinfo, SecCmsDigestedDataRef digd) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +#if TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a EncryptedData. + @param cmsg A Message object to which the cinfo object belongs. + @param cinfo A ContentInfo object of which we want set the content. + @param encd A EncryptedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EncryptedData which can be made by calling SecCmsEncryptedDataCreate(). If the call succeeds the passed in EncryptedData object will be owned by the reciever. The Message object of the EncryptedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentEncryptedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsEncryptedDataRef encd) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +/*! + @function + @abstract Set a ContentInfos content to a EncryptedData. + @param cinfo A ContentInfo object of which we want set the content. + @param encd A EncryptedData object to set as the content of the cinfo object. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EncryptedData which can be made by calling SecCmsEncryptedDataCreate(). If the call succeeds the passed in EncryptedData object will be owned by the reciever. The Message object of the EncryptedData object must be the same as cmsg. + @availability 10.4 and later + */ +extern OSStatus +SecCmsContentInfoSetContentEncryptedData(SecCmsContentInfoRef cinfo, SecCmsEncryptedDataRef encd) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +#if TARGET_OS_OSX +OSStatus +SecCmsContentInfoSetContentOther(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached, const CSSM_OID *eContentType) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +OSStatus +SecCmsContentInfoSetContentOther(SecCmsContentInfoRef cinfo, SecAsn1Item *data, Boolean detached, const SecAsn1Oid *eContentType) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +#if TARGET_OS_OSX +extern OSStatus +SecCmsContentInfoSetContentEncAlg(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo, + SECOidTag bulkalgtag, CSSM_DATA_PTR parameters, int keysize) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +extern OSStatus +SecCmsContentInfoSetContentEncAlg(SecCmsContentInfoRef cinfo, + SECOidTag bulkalgtag, const SecAsn1Item *parameters, int keysize) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + +#if TARGET_OS_OSX +extern OSStatus +SecCmsContentInfoSetContentEncAlgID(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo, + SECAlgorithmID *algid, int keysize) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX +extern OSStatus +SecCmsContentInfoSetContentEncAlgID(SecCmsContentInfoRef cinfo, + SECAlgorithmID *algid, int keysize) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !!TARGET_OS_OSX + +/*! + @function + */ +extern void +SecCmsContentInfoSetBulkKey(SecCmsContentInfoRef cinfo, SecSymmetricKeyRef bulkkey) + API_AVAILABLE(macos(10.4),ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); + +/*! + @function + */ +extern SecSymmetricKeyRef +SecCmsContentInfoGetBulkKey(SecCmsContentInfoRef cinfo) + API_AVAILABLE(macos(10.4),ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); + +/*! + @function + */ +extern int +SecCmsContentInfoGetBulkKeySize(SecCmsContentInfoRef cinfo); + +#pragma clang diagnostic pop + +__END_DECLS + +#endif /* _SECURITY_SECCMSCONTENTINFO_H_ */ diff --git a/libsecurity_smime/lib/SecCmsDecoder.h b/CMS/SecCmsDecoder.h similarity index 60% rename from libsecurity_smime/lib/SecCmsDecoder.h rename to CMS/SecCmsDecoder.h index 44ef0708..b1eb50ec 100644 --- a/libsecurity_smime/lib/SecCmsDecoder.h +++ b/CMS/SecCmsDecoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2008,2010,2013 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsDecoder.h - @Copyright (c) 2004,2008,2010,2013 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -37,13 +36,40 @@ #include - -#if defined(__cplusplus) -extern "C" { -#endif - +__BEGIN_DECLS /*! @functiongroup Streaming interface */ + +#if TARGET_OS_OSX +/*! + @function + @abstract Set up decoding of a BER-encoded CMS message. + @param arena An ArenaPool object to use for the resulting message, or NULL if new ArenaPool + should be created. + @param cb callback function for delivery of inner content inner + content will be stored in the message if cb is NULL. + @param cb_arg first argument passed to cb when it is called. + @param pwfn callback function for getting token password for + enveloped data content with a password recipient. + @param pwfn_arg first argument passed to pwfn when it is called. + @param decrypt_key_cb callback function for getting bulk key + for encryptedData content. + @param decrypt_key_cb_arg first argument passed to decrypt_key_cb + when it is called. + @param outDecoder On success will contain a pointer to a newly created SecCmsDecoder. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion Create a SecCmsDecoder(). If this function returns noErr, the caller must dispose of the returned outDecoder by calling SecCmsDecoderDestroy() or SecCmsDecoderFinish(). + @availability 10.4 through 10.7 + */ +extern OSStatus +SecCmsDecoderCreate(SecArenaPoolRef arena, + SecCmsContentCallback cb, void *cb_arg, + PK11PasswordFunc pwfn, void *pwfn_arg, + SecCmsGetDecryptKeyCallback decrypt_key_cb, void + *decrypt_key_cb_arg, + SecCmsDecoderRef *outDecoder) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX /*! @function @abstract Set up decoding of a BER-encoded CMS message. @@ -61,14 +87,15 @@ extern "C" { @result A result code. See "SecCmsBase.h" for possible results. @discussion Create a SecCmsDecoder(). If this function returns errSecSuccess, the caller must dispose of the returned outDecoder by calling SecCmsDecoderDestroy() or SecCmsDecoderFinish(). @availability 10.4 and later - @updated 2004-04-05 */ extern OSStatus SecCmsDecoderCreate(SecCmsContentCallback cb, void *cb_arg, PK11PasswordFunc pwfn, void *pwfn_arg, SecCmsGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SecCmsDecoderRef *outDecoder); + SecCmsDecoderRef *outDecoder) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX /*! @function @@ -105,6 +132,38 @@ extern OSStatus SecCmsDecoderFinish(SecCmsDecoderRef decoder, SecCmsMessageRef *outMessage); /*! @functiongroup One shot interface */ +#if TARGET_OS_OSX +/*! + @function + @abstract Decode a CMS message from BER encoded data. + @discussion This function basically does the same as calling + SecCmsDecoderStart(), SecCmsDecoderUpdate() and SecCmsDecoderFinish(). + @param encodedMessage Pointer to a CSSM_DATA containing the BER encoded cms + message to decode. + @param cb callback function for delivery of inner content inner + content will be stored in the message if cb is NULL. + @param cb_arg first argument passed to cb when it is called. + @param pwfn callback function for getting token password for enveloped + data content with a password recipient. + @param pwfn_arg first argument passed to pwfn when it is called. + @param decrypt_key_cb callback function for getting bulk key for encryptedData content. + @param decrypt_key_cb_arg first argument passed to decrypt_key_cb when it is called. + @param outMessage On success a pointer to a SecCmsMessage containing the decoded message. + @result A result code. See "SecCmsBase.h" for possible results. + @discussion decoder is no longer valid after this function is called. + @availability 10.4 through 10.7 + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern OSStatus +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) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX /*! @function @abstract Decode a CMS message from BER encoded data. @@ -130,11 +189,11 @@ SecCmsMessageDecode(const SecAsn1Item *encodedMessage, SecCmsContentCallback cb, void *cb_arg, PK11PasswordFunc pwfn, void *pwfn_arg, SecCmsGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg, - SecCmsMessageRef *outMessage); + SecCmsMessageRef *outMessage) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX -#if defined(__cplusplus) -} -#endif +__END_DECLS #endif /* _SECURITY_SECCMSDECODER_H_ */ diff --git a/libsecurity_smime/lib/SecCmsDigestContext.h b/CMS/SecCmsDigestContext.h similarity index 68% rename from libsecurity_smime/lib/SecCmsDigestContext.h rename to CMS/SecCmsDigestContext.h index 9b8520b7..159a2827 100644 --- a/libsecurity_smime/lib/SecCmsDigestContext.h +++ b/CMS/SecCmsDigestContext.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2008,2010-2011 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsDigestContext.h - @Copyright (c) 2004,2008,2010-2011 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -35,18 +34,18 @@ #include - -#if defined(__cplusplus) -extern "C" { -#endif - +__BEGIN_DECLS /*! @function @abstract Start digest calculation using all the digest algorithms in "digestalgs" in parallel. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" extern SecCmsDigestContextRef -SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs); +SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs) + API_AVAILABLE(macos(10.4), ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop /*! @function @@ -63,17 +62,31 @@ SecCmsDigestContextUpdate(SecCmsDigestContextRef cmsdigcx, const unsigned char * extern void SecCmsDigestContextCancel(SecCmsDigestContextRef cmsdigcx); +#if TARGET_OS_IPHONE /*! @function @abstract Destroy a SecCmsDigestContextRef. @discussion Cancel a DigestContext created with @link SecCmsDigestContextStartMultiple SecCmsDigestContextStartMultiple function@/link after it has been used in a @link SecCmsSignedDataSetDigestContext SecCmsSignedDataSetDigestContext function@/link. */ extern void -SecCmsDigestContextDestroy(SecCmsDigestContextRef cmsdigcx); +SecCmsDigestContextDestroy(SecCmsDigestContextRef cmsdigcx) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // TARGET_OS_IPHONE +#if TARGET_OS_OSX +/*! + @function + @abstract Finish the digests and put them into an array of CSSM_DATAs (allocated on arena) + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern OSStatus +SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, SecArenaPoolRef arena, + CSSM_DATA_PTR **digestsp) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#endif // TARGET_OS_OSX -#if defined(__cplusplus) -} -#endif +__END_DECLS #endif /* _SECURITY_SECCMSDIGESTCONTEXT_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsDigestedData.h b/CMS/SecCmsDigestedData.h similarity index 87% rename from OSX/libsecurity_smime/lib/SecCmsDigestedData.h rename to CMS/SecCmsDigestedData.h index cc060727..6fc48c99 100644 --- a/OSX/libsecurity_smime/lib/SecCmsDigestedData.h +++ b/CMS/SecCmsDigestedData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsDigestedData.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -38,11 +37,7 @@ #include - -#if defined(__cplusplus) -extern "C" { -#endif - +__BEGIN_DECLS /*! @function @@ -52,8 +47,12 @@ extern "C" { contentInfo must be filled by the user digest will be calculated while encoding */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" extern SecCmsDigestedDataRef -SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg) + API_AVAILABLE(macos(10.4), ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop /*! @function @@ -69,9 +68,6 @@ SecCmsDigestedDataDestroy(SecCmsDigestedDataRef digd); extern SecCmsContentInfoRef SecCmsDigestedDataGetContentInfo(SecCmsDigestedDataRef digd); - -#if defined(__cplusplus) -} -#endif +__END_DECLS #endif /* _SECURITY_SECCMSDIGESTEDDATA_H_ */ diff --git a/libsecurity_smime/lib/SecCmsEncoder.h b/CMS/SecCmsEncoder.h similarity index 61% rename from libsecurity_smime/lib/SecCmsEncoder.h rename to CMS/SecCmsEncoder.h index 7b432b57..102c39af 100644 --- a/libsecurity_smime/lib/SecCmsEncoder.h +++ b/CMS/SecCmsEncoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsEncoder.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract CMS message encoding @@ -40,12 +39,47 @@ #include -#if defined(__cplusplus) -extern "C" { -#endif - +__BEGIN_DECLS /*! @functiongroup Streaming interface */ + +#if TARGET_OS_OSX +/*! + @function + @abstract Set up encoding of a CMS message. + @param outputfn callback function for delivery of BER-encoded output will + not be called if NULL. + @param outputarg first argument passed to outputfn when it is called. + @param dest If non-NULL, pointer to a CSSM_DATA that will hold the + BER-encoded output. + @param destpoolp Pool to allocate BER-encoded output in. + @param pwfn callback function for getting token password for enveloped + data content with a password recipient. + @param pwfn_arg first argument passed to pwfn when it is called. + @param encrypt_key_cb callback function for getting bulk key for encryptedData content. + @param encrypt_key_cb_arg first argument passed to encrypt_key_cb when it is + called. + @param detached_digestalgs digest algorithms in detached_digests + @param detached_digests digests from detached content (one for every element + in detached_digestalgs). + @result On success a pointer to a SecCmsMessage containing the decoded message + is returned. On failure returns NULL. Call PR_GetError() to find out what + went wrong in this case. + @availability 10.4 through 10.7 + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern OSStatus +SecCmsEncoderCreate(SecCmsMessageRef cmsg, + SecCmsContentCallback outputfn, void *outputarg, + CSSM_DATA_PTR dest, SecArenaPoolRef destpoolp, + PK11PasswordFunc pwfn, void *pwfn_arg, + SecCmsGetDecryptKeyCallback encrypt_key_cb, void *encrypt_key_cb_arg, + SECAlgorithmID **detached_digestalgs, CSSM_DATA_PTR *detached_digests, + SecCmsEncoderRef *outEncoder) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX /*! @function @abstract Set up encoding of a CMS message. @@ -72,7 +106,9 @@ SecCmsEncoderCreate(SecCmsMessageRef cmsg, CFMutableDataRef outBer, PK11PasswordFunc pwfn, void *pwfn_arg, SecCmsGetDecryptKeyCallback encrypt_key_cb, void *encrypt_key_cb_arg, - SecCmsEncoderRef *outEncoder); + SecCmsEncoderRef *outEncoder) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX /*! @function @@ -110,6 +146,20 @@ extern OSStatus SecCmsEncoderFinish(SecCmsEncoderRef encoder); /*! @functiongroup One shot interface */ +#if TARGET_OS_OSX +/*! + @function + @abstract BER Encode a CMS message. + @discussion BER Encode a CMS message, with input being the plaintext message and outBer being the output, stored in arena's pool. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern OSStatus +SecCmsMessageEncode(SecCmsMessageRef cmsg, const CSSM_DATA *input, SecArenaPoolRef arena, + CSSM_DATA_PTR outBer) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX /*! @function @abstract BER Encode a CMS message. @@ -121,11 +171,10 @@ SecCmsEncoderFinish(SecCmsEncoderRef encoder); */ extern OSStatus SecCmsMessageEncode(SecCmsMessageRef cmsg, const SecAsn1Item *input, - CFMutableDataRef outBer); - + CFMutableDataRef outBer) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX -#if defined(__cplusplus) -} -#endif +__END_DECLS #endif /* _SECURITY_SECCMSENCODER_H_ */ diff --git a/libsecurity_smime/lib/SecCmsEncryptedData.h b/CMS/SecCmsEncryptedData.h similarity index 91% rename from libsecurity_smime/lib/SecCmsEncryptedData.h rename to CMS/SecCmsEncryptedData.h index 373907ba..b45c3eaa 100644 --- a/libsecurity_smime/lib/SecCmsEncryptedData.h +++ b/CMS/SecCmsEncryptedData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsEnvelopedData.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -37,11 +36,7 @@ #include - -#if defined(__cplusplus) -extern "C" { -#endif - +__BEGIN_DECLS /*! @function @@ -68,9 +63,6 @@ SecCmsEncryptedDataDestroy(SecCmsEncryptedDataRef encd); extern SecCmsContentInfoRef SecCmsEncryptedDataGetContentInfo(SecCmsEncryptedDataRef encd); - -#if defined(__cplusplus) -} -#endif +__END_DECLS #endif /* _SECURITY_SECCMSENCRYPTEDDATA_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsEnvelopedData.h b/CMS/SecCmsEnvelopedData.h similarity index 84% rename from OSX/libsecurity_smime/lib/SecCmsEnvelopedData.h rename to CMS/SecCmsEnvelopedData.h index d19a752a..642dc956 100644 --- a/OSX/libsecurity_smime/lib/SecCmsEnvelopedData.h +++ b/CMS/SecCmsEnvelopedData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsEnvelopedData.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -37,11 +36,7 @@ #include - -#if defined(__cplusplus) -extern "C" { -#endif - +__BEGIN_DECLS /*! @function @@ -64,17 +59,16 @@ SecCmsEnvelopedDataDestroy(SecCmsEnvelopedDataRef edp); extern SecCmsContentInfoRef SecCmsEnvelopedDataGetContentInfo(SecCmsEnvelopedDataRef envd); +#if TARGET_OS_OSX /*! - @function - @abstract Add a recipientinfo to the enveloped data msg. - @discussion Rip must be created on the same pool as edp - this is not enforced, though. + @function + @abstract Add a recipientinfo to the enveloped data msg. + @discussion Rip must be created on the same pool as edp - this is not enforced, though. */ extern OSStatus SecCmsEnvelopedDataAddRecipient(SecCmsEnvelopedDataRef edp, SecCmsRecipientInfoRef rip); - - -#if defined(__cplusplus) -} #endif +__END_DECLS + #endif /* _SECURITY_SECCMSENVELOPEDDATA_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsMessage.h b/CMS/SecCmsMessage.h similarity index 75% rename from OSX/libsecurity_smime/lib/SecCmsMessage.h rename to CMS/SecCmsMessage.h index f9bd38c6..497c4677 100644 --- a/OSX/libsecurity_smime/lib/SecCmsMessage.h +++ b/CMS/SecCmsMessage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsMessage.h - @Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract CMS message object interfaces @@ -40,24 +39,39 @@ #include +__BEGIN_DECLS -#if defined(__cplusplus) -extern "C" { -#endif +#if TARGET_OS_OSX +/*! + @function + @abstract Create a CMS message object. + @param poolp Arena to allocate memory from, or NULL if new arena should + be created. + @result A pointer to a newly created SecCmsMessage. When finished using + this the caller should call SecCmsMessageDestroy(). On failure + returns NULL. In this case call PR_GetError() to find out what went + wrong. + */ +extern SecCmsMessageRef +SecCmsMessageCreate(SecArenaPoolRef poolp) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); + +#else // !TARGET_OS_OSX /*! @function @abstract Create a CMS message object. - @param poolp Arena to allocate memory from, or NULL if new arena should - be created. @result A pointer to a newly created SecCmsMessage. When finished using this the caller should call SecCmsMessageDestroy(). On failure returns NULL. In this case call PR_GetError() to find out what went wrong. */ extern SecCmsMessageRef -SecCmsMessageCreate(SecArenaPoolRef poolp); +SecCmsMessageCreate(void) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); + +#endif // !TARGET_OS_OSX /*! @function @@ -78,12 +92,14 @@ SecCmsMessageDestroy(SecCmsMessageRef cmsg); extern SecCmsMessageRef SecCmsMessageCopy(SecCmsMessageRef cmsg); +#if SEC_OS_OSX /*! @function @abstract Return a pointer to the message's arena pool. */ extern SecArenaPoolRef SecCmsMessageGetArena(SecCmsMessageRef cmsg); +#endif /*! @function @@ -92,14 +108,30 @@ SecCmsMessageGetArena(SecCmsMessageRef cmsg); extern SecCmsContentInfoRef SecCmsMessageGetContentInfo(SecCmsMessageRef cmsg); +#if TARGET_OS_OSX +/*! + @function + @abstract Return a pointer to the actual content. + @discussion In the case of those types which are encrypted, this returns the *plain* content. + In case of nested contentInfos, this descends and retrieves the innermost content. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern CSSM_DATA_PTR +SecCmsMessageGetContent(SecCmsMessageRef cmsg) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX /*! @function @abstract Return a pointer to the actual content. @discussion In the case of those types which are encrypted, this returns the *plain* content. In case of nested contentInfos, this descends and retrieves the innermost content. */ -extern CSSM_DATA_PTR -SecCmsMessageGetContent(SecCmsMessageRef cmsg) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +extern const SecAsn1Item * +SecCmsMessageGetContent(SecCmsMessageRef cmsg) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX /*! @function @@ -153,11 +185,11 @@ SecCmsMessageIsSigned(SecCmsMessageRef cmsg); extern Boolean SecCmsMessageIsContentEmpty(SecCmsMessageRef cmsg, unsigned int minLen); +#if TARGET_OS_OSX extern Boolean SecCmsMessageContainsTSTInfo(SecCmsMessageRef cmsg); - -#if defined(__cplusplus) -} #endif +__END_DECLS + #endif /* _SECURITY_SECCMSMESSAGE_H_ */ diff --git a/libsecurity_smime/lib/SecCmsRecipientInfo.h b/CMS/SecCmsRecipientInfo.h similarity index 55% rename from libsecurity_smime/lib/SecCmsRecipientInfo.h rename to CMS/SecCmsRecipientInfo.h index f8ae7415..f57481fd 100644 --- a/libsecurity_smime/lib/SecCmsRecipientInfo.h +++ b/CMS/SecCmsRecipientInfo.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsRecipientInfo.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -37,39 +36,69 @@ #include +__BEGIN_DECLS -#if defined(__cplusplus) -extern "C" { -#endif - - +#if TARGET_OS_OSX /*! @function @abstract Create a recipientinfo @discussion We currently do not create KeyAgreement recipientinfos with multiple recipientEncryptedKeys - the certificate is supposed to have been verified by the caller + the certificate is supposed to have been verified by the caller */ extern SecCmsRecipientInfoRef -SecCmsRecipientInfoCreate(SecCmsEnvelopedDataRef envd, SecCertificateRef cert); +SecCmsRecipientInfoCreate(SecCmsMessageRef cmsg, SecCertificateRef cert) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); + +#else // !TARGET_OS_OSX /*! @function + @abstract Create a recipientinfo + @discussion We currently do not create KeyAgreement recipientinfos with multiple recipientEncryptedKeys + the certificate is supposed to have been verified by the caller */ extern SecCmsRecipientInfoRef -SecCmsRecipientInfoCreateWithSubjKeyID(SecCmsEnvelopedDataRef envd, +SecCmsRecipientInfoCreate(SecCmsEnvelopedDataRef envd, SecCertificateRef cert) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX + + +#if TARGET_OS_OSX +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern SecCmsRecipientInfoRef +SecCmsRecipientInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, + CSSM_DATA_PTR subjKeyID, + SecPublicKeyRef pubKey) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX +extern SecCmsRecipientInfoRef +SecCmsRecipientInfoCreateWithSubjKeyID(SecCmsEnvelopedDataRef envd, const SecAsn1Item *subjKeyID, - SecPublicKeyRef pubKey); + SecPublicKeyRef pubKey) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX -/*! - @function - */ + +#if TARGET_OS_OSX +extern SecCmsRecipientInfoRef +SecCmsRecipientInfoCreateWithSubjKeyIDFromCert(SecCmsMessageRef cmsg, + SecCertificateRef cert) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#else // !TARGET_OS_OSX extern SecCmsRecipientInfoRef SecCmsRecipientInfoCreateWithSubjKeyIDFromCert(SecCmsEnvelopedDataRef envd, - SecCertificateRef cert); + SecCertificateRef cert) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX -#if defined(__cplusplus) -} +#if TARGET_OS_OSX +extern void +SecCmsRecipientInfoDestroy(SecCmsRecipientInfoRef ri); #endif +__END_DECLS + #endif /* _SECURITY_SECCMSRECIPIENTINFO_H_ */ diff --git a/libsecurity_smime/lib/SecCmsSignedData.h b/CMS/SecCmsSignedData.h similarity index 79% rename from libsecurity_smime/lib/SecCmsSignedData.h rename to CMS/SecCmsSignedData.h index 08fc62b5..f74f89b2 100644 --- a/libsecurity_smime/lib/SecCmsSignedData.h +++ b/CMS/SecCmsSignedData.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecCmsSignedData.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -38,9 +37,7 @@ #include #include -#if defined(__cplusplus) -extern "C" { -#endif +__BEGIN_DECLS /*! @function @@ -80,8 +77,11 @@ SecCmsSignedDataGetSignerInfo(SecCmsSignedDataRef sigd, int i); @function @abstract Retrieve the SignedData's digest algorithm list. */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" extern SECAlgorithmID ** SecCmsSignedDataGetDigestAlgs(SecCmsSignedDataRef sigd); +#pragma clang diagnostic pop /*! @function @@ -155,12 +155,27 @@ SecCmsSignedDataAddCertificate(SecCmsSignedDataRef sigd, SecCertificateRef cert) extern Boolean SecCmsSignedDataContainsCertsOrCrls(SecCmsSignedDataRef sigd); + +#if TARGET_OS_OSX +/*! + @function + @abstract Retrieve the SignedData's certificate list. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern CSSM_DATA_PTR * +SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX /*! @function @abstract Retrieve the SignedData's certificate list. */ extern SecAsn1Item * * -SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd); +SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX /*! @function @@ -173,6 +188,7 @@ SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd); extern SecCmsSignedDataRef SecCmsSignedDataCreateCertsOnly(SecCmsMessageRef cmsg, SecCertificateRef cert, Boolean include_chain); +#if TARGET_OS_IPHONE /*! @function @abstract Finalize the digests in digestContext and apply them to sigd. @@ -183,10 +199,25 @@ SecCmsSignedDataCreateCertsOnly(SecCmsMessageRef cmsg, SecCertificateRef cert, B */ extern OSStatus SecCmsSignedDataSetDigestContext(SecCmsSignedDataRef sigd, - SecCmsDigestContextRef digestContext); + SecCmsDigestContextRef digestContext) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(macos, iosmac); +#endif -#if defined(__cplusplus) -} +#if TARGET_OS_OSX +extern OSStatus +SecCmsSignedDataAddSignerInfo(SecCmsSignedDataRef sigd, + SecCmsSignerInfoRef signerinfo); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern OSStatus +SecCmsSignedDataSetDigests(SecCmsSignedDataRef sigd, + SECAlgorithmID **digestalgs, + CSSM_DATA_PTR *digests) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop #endif +__END_DECLS + #endif /* _SECURITY_SECCMSSIGNEDDATA_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h b/CMS/SecCmsSignerInfo.h similarity index 72% rename from OSX/libsecurity_smime/lib/SecCmsSignerInfo.h rename to CMS/SecCmsSignerInfo.h index da7117e9..f3f80d6e 100644 --- a/OSX/libsecurity_smime/lib/SecCmsSignerInfo.h +++ b/CMS/SecCmsSignerInfo.h @@ -1,15 +1,15 @@ /* - * Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-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,13 +17,12 @@ * 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 SecCmsSignerInfo.h - @Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract Interfaces of the CMS implementation. @@ -40,29 +39,42 @@ #include #include +__BEGIN_DECLS -#if defined(__cplusplus) -extern "C" { -#endif +#if TARGET_OS_OSX +extern SecCmsSignerInfoRef +SecCmsSignerInfoCreate(SecCmsMessageRef cmsg, SecIdentityRef identity, SECOidTag digestalgtag) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); + +#else // !TARGET_OSX -/*! - @function - */ extern SecCmsSignerInfoRef -SecCmsSignerInfoCreate(SecCmsMessageRef cmsg, SecIdentityRef identity, SECOidTag digestalgtag); +SecCmsSignerInfoCreate(SecCmsSignedDataRef sigd, SecIdentityRef identity, SECOidTag digestalgtag) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX -/*! - @function - */ +#if TARGET_OS_OSX +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" extern SecCmsSignerInfoRef -SecCmsSignerInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +SecCmsSignerInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, CSSM_DATA_PTR subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(iosmac); +#pragma clang diagnostic pop +#else // !TARGET_OS_OSX +extern SecCmsSignerInfoRef +SecCmsSignerInfoCreateWithSubjKeyID(SecCmsSignedDataRef sigd, const SecAsn1Item *subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag) + API_AVAILABLE(ios(2.0), tvos(2.0), watchos(1.0)) API_UNAVAILABLE(iosmac); +#endif // !TARGET_OS_OSX +#if TARGET_OS_OSX /*! - @function - @abstract Destroy a SignerInfo data structure. + @function + @abstract Destroy a SignerInfo data structure. */ extern void -SecCmsSignerInfoDestroy(SecCmsSignerInfoRef si); +SecCmsSignerInfoDestroy(SecCmsSignerInfoRef si) + API_AVAILABLE(macos(10.4)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); +#endif /*! @function @@ -70,24 +82,6 @@ SecCmsSignerInfoDestroy(SecCmsSignerInfoRef si); extern SecCmsVerificationStatus SecCmsSignerInfoGetVerificationStatus(SecCmsSignerInfoRef signerinfo); -/*! - @function - */ -extern OSStatus -SecCmsSignerInfoVerifyUnAuthAttrs(SecCmsSignerInfoRef signerinfo); - -/*! - @function - */ -extern OSStatus -SecCmsSignerInfoVerifyUnAuthAttrsWithPolicy(SecCmsSignerInfoRef signerinfo,CFTypeRef timeStampPolicy); - -/*! - @function - */ -extern CSSM_DATA * -SecCmsSignerInfoGetEncDigest(SecCmsSignerInfoRef signerinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - /*! @function */ @@ -106,18 +100,6 @@ SecCmsSignerInfoGetDigestAlgTag(SecCmsSignerInfoRef signerinfo); extern CFArrayRef SecCmsSignerInfoGetCertList(SecCmsSignerInfoRef signerinfo); -/*! - @function - */ -extern CFArrayRef -SecCmsSignerInfoGetTimestampCertList(SecCmsSignerInfoRef signerinfo); - -/*! - @function - */ -extern SecCertificateRef -SecCmsSignerInfoGetTimestampSigningCert(SecCmsSignerInfoRef signerinfo); - /*! @function @abstract Return the signing time, in UTCTime format, of a CMS signerInfo. @@ -129,41 +111,21 @@ extern OSStatus SecCmsSignerInfoGetSigningTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *stime); /*! - @function - @abstract Return the timestamp time, in UTCTime format, of a CMS signerInfo. - @param sinfo SignerInfo data for this signer. - @discussion Returns a pointer to XXXX (what?) - @result A return value of NULL is an error. - */ -OSStatus -SecCmsSignerInfoGetTimestampTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *stime); - -/*! - @function - @abstract Return the timestamp time, in UTCTime format, of a CMS signerInfo. - @param sinfo SignerInfo data for this signer, timeStampPolicy the policy to verify the timestamp signer - @discussion Returns a pointer to XXXX (what?) - @result A return value of NULL is an error. - */ -OSStatus -SecCmsSignerInfoGetTimestampTimeWithPolicy(SecCmsSignerInfoRef sinfo, CFTypeRef timeStampPolicy, CFAbsoluteTime *stime); - -/*! - @function - @abstract Return the data in the signed Codesigning Hash Agility attribute. - @param sinfo SignerInfo data for this signer, pointer to a CFDataRef for attribute value - @discussion Returns a CFDataRef containing the value of the attribute - @result A return value of SECFailure is an error. + @function + @abstract Return the data in the signed Codesigning Hash Agility attribute. + @param sinfo SignerInfo data for this signer, pointer to a CFDataRef for attribute value + @discussion Returns a CFDataRef containing the value of the attribute + @result A return value of SECFailure is an error. */ -OSStatus +extern OSStatus SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFDataRef *sdata); /*! @function @abstract Return the data in the signed Codesigning Hash Agility V2 attribute. @param sinfo SignerInfo data for this signer, pointer to a CFDictionaryRef for attribute values - @discussion Returns a CFDictionaryRef containing the values of the attribute. V2 encodes the hash - agility values using DER. + @discussion Returns a CFDictionaryRef containing the values of the attribute. V2 encodes the + hash agility values using DER. @result A return value of SECFailure is an error. */ extern OSStatus @@ -194,7 +156,7 @@ SecCmsSignerInfoGetSigningCertificate(SecCmsSignerInfoRef signerinfo, SecKeychai @discussion Returns a CFStringRef containing the common name of the signer. @result A return value of NULL is an error. */ -extern CFStringRef +extern CF_RETURNS_RETAINED CFStringRef SecCmsSignerInfoGetSignerCommonName(SecCmsSignerInfoRef sinfo); /*! @@ -204,12 +166,12 @@ SecCmsSignerInfoGetSignerCommonName(SecCmsSignerInfoRef sinfo); @discussion Returns a CFStringRef containing the name of the signer. @result A return value of NULL is an error. */ -extern CFStringRef +extern CF_RETURNS_RETAINED CFStringRef SecCmsSignerInfoGetSignerEmailAddress(SecCmsSignerInfoRef sinfo); /*! @function - @abstract Add the signing time to the authenticated (i.e. signed) attributes of "signerinfo". + @abstract Add the signing time to the authenticated (i.e. signed) attributes of "signerinfo". @discussion This is expected to be included in outgoing signed messages for email (S/MIME) but is likely useful in other situations. @@ -246,13 +208,6 @@ SecCmsSignerInfoAddSMIMEEncKeyPrefs(SecCmsSignerInfoRef signerinfo, SecCertifica OSStatus SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(SecCmsSignerInfoRef signerinfo, SecCertificateRef cert, SecKeychainRef keychainOrArray); -/*! - @function - @abstract Create a timestamp unsigned attribute with a TimeStampToken. - */ -OSStatus -SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - /*! @function @abstract Countersign a signerinfo. @@ -265,9 +220,9 @@ SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, @function @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". @discussion This is expected to be included in outgoing Apple code signatures. - */ - OSStatus - SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue); +*/ +OSStatus +SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue); /*! @function @@ -314,13 +269,13 @@ extern const char * SecCmsUtilVerificationStatusToString(SecCmsVerificationStatus vs); /* - * Preference domain and key for the Microsoft ECDSA compatibility flag. + * Preference domain and key for the Microsoft ECDSA compatibility flag. * Default if not present is TRUE, meaning we generate ECDSA-signed messages - * which are compatible with Microsoft Entourage. FALSE means we adhere to + * which are compatible with Microsoft Entourage. FALSE means we adhere to * the spec (RFC 3278 section 2.1.1). */ -#define kMSCompatibilityDomain "com.apple.security.smime" -#define kMSCompatibilityMode CFSTR("MSCompatibilityMode") +#define kMSCompatibilityDomain "com.apple.security.smime" +#define kMSCompatibilityMode CFSTR("MSCompatibilityMode") /*! @function SecCmsSignerInfoCopyCertFromEncryptionKeyPreference @@ -331,8 +286,66 @@ SecCmsUtilVerificationStatusToString(SecCmsVerificationStatus vs); */ SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo); -#if defined(__cplusplus) -} -#endif +#if TARGET_OS_OSX +/* MARK: Timestamping support */ + +extern OSStatus +SecCmsSignerInfoVerifyUnAuthAttrs(SecCmsSignerInfoRef signerinfo) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +extern OSStatus +SecCmsSignerInfoVerifyUnAuthAttrsWithPolicy(SecCmsSignerInfoRef signerinfo,CFTypeRef timeStampPolicy) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +extern CSSM_DATA * +SecCmsSignerInfoGetEncDigest(SecCmsSignerInfoRef signerinfo) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); +#pragma clang diagnostic pop + +extern CFArrayRef +SecCmsSignerInfoGetTimestampCertList(SecCmsSignerInfoRef signerinfo) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +extern SecCertificateRef +SecCmsSignerInfoGetTimestampSigningCert(SecCmsSignerInfoRef signerinfo) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +/*! + @function + @abstract Return the timestamp time, in UTCTime format, of a CMS signerInfo. + @param sinfo SignerInfo data for this signer. + @discussion Returns a pointer to XXXX (what?) + @result A return value of NULL is an error. + */ +OSStatus +SecCmsSignerInfoGetTimestampTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *stime) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +/*! + @function + @abstract Return the timestamp time, in UTCTime format, of a CMS signerInfo. + @param sinfo SignerInfo data for this signer, timeStampPolicy the policy to verify the timestamp signer + @discussion Returns a pointer to XXXX (what?) + @result A return value of NULL is an error. + */ +OSStatus +SecCmsSignerInfoGetTimestampTimeWithPolicy(SecCmsSignerInfoRef sinfo, CFTypeRef timeStampPolicy, CFAbsoluteTime *stime) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +/*! + @function + @abstract Create a timestamp unsigned attribute with a TimeStampToken. + */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +OSStatus +SecCmsSignerInfoAddTimeStamp(SecCmsSignerInfoRef signerinfo, CSSM_DATA *tstoken) + API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); +#pragma clang diagnostic pop +#endif // TARGET_OS_OSX + +__END_DECLS #endif /* _SECURITY_SECCMSSIGNERINFO_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecSMIME.h b/CMS/SecSMIME.h similarity index 88% rename from OSX/libsecurity_smime/lib/SecSMIME.h rename to CMS/SecSMIME.h index 7027c179..947f145e 100644 --- a/OSX/libsecurity_smime/lib/SecSMIME.h +++ b/CMS/SecSMIME.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2004-2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -23,7 +23,6 @@ /*! @header SecSMIME.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. @availability 10.4 and later @abstract S/MIME Specific routines. @@ -37,9 +36,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif +__BEGIN_DECLS /*! @function @@ -48,9 +45,6 @@ extern "C" { extern OSStatus SecSMIMEFindBulkAlgForRecipients(SecCertificateRef *rcerts, SECOidTag *bulkalgtag, int *keysize); - -#ifdef __cplusplus -} -#endif +__END_DECLS #endif /* _SECURITY_SECSMIME_H_ */ diff --git a/CircleJoinRequested/Applicant.h b/CircleJoinRequested/Applicant.h index f7c76bff..bbb48daa 100644 --- a/CircleJoinRequested/Applicant.h +++ b/CircleJoinRequested/Applicant.h @@ -7,7 +7,7 @@ // #import -#include "SecureObjectSync/SOSPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeerInfo.h" typedef enum { ApplicantWaiting, diff --git a/CircleJoinRequested/CircleJoinRequested.m b/CircleJoinRequested/CircleJoinRequested.m index 4f6ed2e2..2009f377 100644 --- a/CircleJoinRequested/CircleJoinRequested.m +++ b/CircleJoinRequested/CircleJoinRequested.m @@ -36,14 +36,15 @@ #import #import #import +#import #import #import #import #include -#include "SecureObjectSync/SOSCloudCircle.h" -#include "SecureObjectSync/SOSCloudCircleInternal.h" -#include "SecureObjectSync/SOSPeerInfo.h" -#include "SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSCloudCircle.h" +#include "keychain/SecureObjectSync/SOSCloudCircleInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfo.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include #import "Applicant.h" @@ -67,7 +68,7 @@ #import // As long as we are logging the failure use exit code of zero to make launchd happy -#define EXIT_LOGGED_FAILURE(code) xpc_transaction_end(); exit(0) +#define EXIT_LOGGED_FAILURE(code) exit(0) const char *kLaunchLaterXPCName = "com.apple.security.CircleJoinRequestedTick"; CFRunLoopSourceRef currentAlertSource = NULL; @@ -89,6 +90,16 @@ NSString *rejoinICDPUrl = @"prefs:root=APPLE_ACCOUNT&aaaction=CDP&command=re BOOL processRequests(CFErrorRef *error); +static BOOL isErrorFromXPC(CFErrorRef error) +{ + // Error due to XPC failure does not provide information about the circle. + if (error && (CFEqual(sSecXPCErrorDomain, CFErrorGetDomain(error)))) { + secnotice("cjr", "XPC error while checking circle status: \"%@\", not processing events", error); + return YES; + } + return NO; +} + static void PSKeychainSyncIsUsingICDP(void) { ACAccountStore *accountStore = [[ACAccountStore alloc] init]; @@ -116,15 +127,16 @@ static void keybagDidUnlock() secnotice("cjr", "keybagDidUnlock"); CFErrorRef error = NULL; - + if(processApplicantsAfterUnlock){ processRequests(&error); processApplicantsAfterUnlock = false; } SOSCCStatus circleStatus = SOSCCThisDeviceIsInCircle(&error); - if (circleStatus == kSOSCCError && error && CFEqual(sSecXPCErrorDomain, CFErrorGetDomain(error))) { - secnotice("cjr", "unable to determine circle status due to xpc failure: %@", error); + BOOL xpcError = isErrorFromXPC(error); + if(xpcError && circleStatus == kSOSCCError) { + secnotice("cjr", "returning early due to error returned from securityd: %@", error); return; } else if (_isAccountICDP && (circleStatus == kSOSCCError || circleStatus == kSOSCCCircleAbsent || circleStatus == kSOSCCNotInCircle) && _hasPostedFollowupAndStillInError == false) { @@ -746,30 +758,30 @@ static void postKickedOutAlert(enum DepartureReason reason) debugState = @"pKOA Z"; } - static bool processEvents() { debugState = @"processEvents A"; - CFErrorRef error = NULL; - CFErrorRef departError = NULL; - SOSCCStatus circleStatus = SOSCCThisDeviceIsInCircle(&error); + CFErrorRef error = NULL; + CFErrorRef departError = NULL; + SOSCCStatus circleStatus = SOSCCThisDeviceIsInCircleNonCached(&error); enum DepartureReason departureReason = SOSCCGetLastDepartureReason(&departError); - // Error due to XPC failure does not provide information about the circle. - if (circleStatus == kSOSCCError && error && (CFEqual(sSecXPCErrorDomain, CFErrorGetDomain(error)))) { - secnotice("cjr", "XPC error while checking circle status: \"%@\", not processing events", error); + BOOL abortFromError = isErrorFromXPC(error); + if(abortFromError && circleStatus == kSOSCCError) { + secnotice("cjr", "returning from processEvents due to error returned from securityd: %@", error); return true; - } else if (departureReason == kSOSDepartureReasonError && departError && (CFEqual(sSecXPCErrorDomain, CFErrorGetDomain(departError)))) { + } + if (departureReason == kSOSDepartureReasonError && departError && (CFEqual(sSecXPCErrorDomain, CFErrorGetDomain(departError)))) { secnotice("cjr", "XPC error while checking last departure reason: \"%@\", not processing events", departError); return true; } + + NSDate *nowish = [NSDate date]; + PersistentState *state = [PersistentState loadFromStorage]; + secnotice("cjr", "CircleStatus %d -> %d{%d} (s=%p)", state.lastCircleStatus, circleStatus, departureReason, state); - NSDate *nowish = [NSDate date]; - PersistentState *state = [PersistentState loadFromStorage]; - secnotice("cjr", "CircleStatus %d -> %d{%d} (s=%p)", state.lastCircleStatus, circleStatus, departureReason, state); - - // Pending application reminder + // Pending application reminder NSTimeInterval timeUntilApplicationAlert = [state.pendingApplicationReminder timeIntervalSinceDate:nowish]; secnotice("cjr", "Time until pendingApplicationReminder (%@) %f", [state.pendingApplicationReminder debugDescription], timeUntilApplicationAlert); if (circleStatus == kSOSCCRequestPending) { @@ -782,13 +794,33 @@ static bool processEvents() } PSKeychainSyncIsUsingICDP(); - + + // Refresh because sometimes we're fixed elsewhere before we get here. + CFReleaseNull(error); + circleStatus = SOSCCThisDeviceIsInCircleNonCached(&error); + abortFromError = isErrorFromXPC(error); + if(abortFromError && circleStatus == kSOSCCError) { + secnotice("cjr", "returning from processEvents due to error returned from securityd: %@", error); + return true; + } + if(_isAccountICDP){ if((circleStatus == kSOSCCError || circleStatus == kSOSCCCircleAbsent || circleStatus == kSOSCCNotInCircle) && _hasPostedFollowupAndStillInError == false) { - secnotice("cjr", "error from SOSCCThisDeviceIsInCircle: %@", error); - secnotice("cjr", "iCDP: We need to get back into the circle"); - doOnceInMain(^{ - if(_isAccountICDP){ + if(circleStatus == kSOSCCError) { + secnotice("cjr", "error from SOSCCThisDeviceIsInCircle: %@", error); + } + + /* + You would think we could count on not being iCDP if the account was signed out. Evidently that's wrong. + So we'll go based on the artifact that when the account object is reset (like by signing out) the + departureReason will be set to kSOSDepartureReasonError. So we won't push to get back into a circle if that's + the current reason. I've checked code for other ways we could be out. If we boot and can't load the account + we'll end up with kSOSDepartureReasonError. Then too if we end up in kSOSDepartureReasonError and reboot we end up + in the same place. Leave it to cdpd to decide whether the user needs to sign in to an account. + */ + if(departureReason != kSOSDepartureReasonError) { + secnotice("cjr", "iCDP: We need to get back into the circle"); + doOnceInMain(^{ NSError *localError = nil; CDPFollowUpController *cdpd = [[CDPFollowUpController alloc] init]; CDPFollowUpContext *context = [CDPFollowUpContext contextForStateRepair]; @@ -800,13 +832,10 @@ static bool processEvents() secnotice("cjr", "CoreCDP handling follow up"); _hasPostedFollowupAndStillInError = true; } - } - else{ - postKickedOutAlert(kSOSPasswordChanged); - state.lastCircleStatus = kSOSCCError; - [state writeToStorage]; - } - }); + }); + } else { + secnotice("cjr", "iCDP: We appear to not be associated with an iCloud account"); + } state.lastCircleStatus = circleStatus; _executeProcessEventsOnce = true; return false; @@ -821,9 +850,7 @@ static bool processEvents() _executeProcessEventsOnce = true; return false; } - } - else if(circleStatus == kSOSCCError && state.lastCircleStatus != kSOSCCError && (departureReason == kSOSNeverLeftCircle) - && !_isAccountICDP) { + } else if(circleStatus == kSOSCCError && state.lastCircleStatus != kSOSCCError && (departureReason == kSOSNeverLeftCircle)) { secnotice("cjr", "SA: error from SOSCCThisDeviceIsInCircle: %@", error); CFIndex errorCode = CFErrorGetCode(error); if(errorCode == kSOSErrorPublicKeyAbsent){ @@ -909,16 +936,22 @@ static bool processEvents() notify_register_dispatch(kSOSCCCircleChangedNotification, ¬ifyToken, dispatch_get_main_queue(), ^(int token) { if (postedAlert != currentAlert) { secnotice("cjr", "-- CC after original alert gone (currentAlertIsForApplicants %d, pA %p, cA %p -- %@)", - currentAlertIsForApplicants, postedAlert, currentAlert, currentAlert); - notify_cancel(token); - } else { + currentAlertIsForApplicants, postedAlert, currentAlert, currentAlert); + notify_cancel(token); + } else { CFErrorRef localError = NULL; - SOSCCStatus newCircleStatus = SOSCCThisDeviceIsInCircle(&localError); - if (newCircleStatus != kSOSCCRequestPending) { - if (newCircleStatus == kSOSCCError) - secnotice("cjr", "No longer pending (nCS=%d, alert=%@) error: %@", newCircleStatus, currentAlert, localError); - else - secnotice("cjr", "No longer pending (nCS=%d, alert=%@)", newCircleStatus, currentAlert); + SOSCCStatus newCircleStatus = SOSCCThisDeviceIsInCircle(&localError); + BOOL xpcError = isErrorFromXPC(localError); + if(xpcError && newCircleStatus == kSOSCCError) { + secnotice("cjr", "returning from processEvents due to error returned from securityd: %@", localError); + return; + } + + if (newCircleStatus != kSOSCCRequestPending) { + if (newCircleStatus == kSOSCCError) + secnotice("cjr", "No longer pending (nCS=%d, alert=%@) error: %@", newCircleStatus, currentAlert, localError); + else + secnotice("cjr", "No longer pending (nCS=%d, alert=%@)", newCircleStatus, currentAlert); cancelCurrentAlert(true); } else { secnotice("cjr", "Still pending..."); @@ -999,10 +1032,16 @@ static bool processEvents() if (newIds.count == 0) { secnotice("cjr", "All applicants were handled elsewhere"); cancelCurrentAlert(true); - } - SOSCCStatus currentCircleStatus = SOSCCThisDeviceIsInCircle(&circleStatusError); - if (kSOSCCInCircle != currentCircleStatus) { - secnotice("cjr", "Left circle (%d), not handling remaining %lu applicants", currentCircleStatus, (unsigned long)newIds.count); + } + CFErrorRef circleError = NULL; + SOSCCStatus currentCircleStatus = SOSCCThisDeviceIsInCircle(&circleError); + BOOL xpcError = isErrorFromXPC(circleError); + if(xpcError && currentCircleStatus == kSOSCCError) { + secnotice("cjr", "returning early due to error returned from securityd: %@", circleError); + return; + } + if (kSOSCCInCircle != currentCircleStatus) { + secnotice("cjr", "Left circle (%d), not handling remaining %lu applicants", currentCircleStatus, (unsigned long)newIds.count); cancelCurrentAlert(true); } if (needsUpdate) { @@ -1037,9 +1076,8 @@ static bool processEvents() int main (int argc, const char * argv[]) { - - xpc_transaction_begin(); - + os_transaction_t txion = os_transaction_create("com.apple.security.circle-join-requested"); + @autoreleasepool { // NOTE: DISPATCH_QUEUE_PRIORITY_LOW will not actually manage to drain events in a lot of cases (like circleStatus != kSOSCCInCircle) @@ -1078,6 +1116,7 @@ int main (int argc, const char * argv[]) { } secnotice("cjr", "Done"); - xpc_transaction_end(); + (void) txion; // But we really do want this around, compiler... + txion = nil; return(0); } diff --git a/CircleJoinRequested/PersistentState.h b/CircleJoinRequested/PersistentState.h index 29e0ef75..3e473476 100644 --- a/CircleJoinRequested/PersistentState.h +++ b/CircleJoinRequested/PersistentState.h @@ -7,8 +7,8 @@ // #import -#include "SecureObjectSync/SOSCloudCircle.h" -#include "SecureObjectSync/SOSPeerInfo.h" +#include "keychain/SecureObjectSync/SOSCloudCircle.h" +#include "keychain/SecureObjectSync/SOSPeerInfo.h" @interface PersistentState : NSObject +(instancetype)loadFromStorage; diff --git a/KVSKeychainSyncingProxy/CKDKVSProxy.h b/KVSKeychainSyncingProxy/CKDKVSProxy.h index a955f796..aa1d50a2 100644 --- a/KVSKeychainSyncingProxy/CKDKVSProxy.h +++ b/KVSKeychainSyncingProxy/CKDKVSProxy.h @@ -89,10 +89,6 @@ typedef void (^FreshnessResponseBlock)(bool success, NSError *err); @property (atomic) dispatch_queue_t calloutQueue; @property (atomic) dispatch_queue_t ckdkvsproxy_queue; -@property (atomic) dispatch_source_t penaltyTimer; -@property (atomic) bool penaltyTimerScheduled; -@property (retain, atomic) NSMutableDictionary *monitor; -@property (retain, atomic) NSDictionary *queuedMessages; @property (copy, atomic) dispatch_block_t shadowFlushBlock; diff --git a/KVSKeychainSyncingProxy/CKDKVSProxy.m b/KVSKeychainSyncingProxy/CKDKVSProxy.m index 851d4cd2..d586951c 100644 --- a/KVSKeychainSyncingProxy/CKDKVSProxy.m +++ b/KVSKeychainSyncingProxy/CKDKVSProxy.m @@ -37,8 +37,8 @@ #import "CKDSecuritydAccount.h" #import "NSURL+SOSPlistStore.h" -#include -#include +#include "keychain/SecureObjectSync/SOSARCDefines.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include @@ -92,16 +92,13 @@ static NSString *kKeyPendingSyncBackupPeerIDs = @"SyncBackupPeerIDs"; static NSString *kKeyEnsurePeerRegistration = @"EnsurePeerRegistration"; static NSString *kKeyDSID = @"DSID"; -static NSString *kMonitorState = @"MonitorState"; -static NSString *kKeyAccountUUID = @"MonitorState"; +static NSString *kKeyAccountUUID = @"KeyAccountUUID"; 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"; @@ -141,7 +138,7 @@ static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; { secnotice("event", "%@ start", self); -#if !(TARGET_OS_EMBEDDED) +#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR // rdar://problem/26247270 if (geteuid() == 0) { secerror("Cannot run CloudKeychainProxy as root"); @@ -167,18 +164,8 @@ static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; _freshnessCompletions = [NSMutableArray array]; - _monitor = [NSMutableDictionary dictionary]; - [[XPCNotificationDispatcher dispatcher] addListener: self]; - int notificationToken; - notify_register_dispatch(kSecServerKeychainChangedNotification, ¬ificationToken, _ckdkvsproxy_queue, - ^ (int token __unused) - { - secinfo("backoff", "keychain changed, wiping backoff monitor state"); - self->_monitor = [NSMutableDictionary dictionary]; - }); - [self setPersistentData: [self.persistenceURL readPlist]]; _dsid = @""; @@ -261,7 +248,6 @@ static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; kKeyPendingKeys:[_pendingKeys allObjects], kKeyPendingSyncPeerIDs:[_pendingSyncPeerIDs allObjects], kKeyPendingSyncBackupPeerIDs:[_pendingSyncBackupPeerIDs allObjects], - kMonitorState:_monitor, kKeyEnsurePeerRegistration:[NSNumber numberWithBool:_ensurePeerRegistration], kKeyDSID:_dsid, kKeyAccountUUID:_accountUUID @@ -271,6 +257,7 @@ static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; - (void) setPersistentData: (NSDictionary*) interests { _alwaysKeys = [NSMutableSet setWithArray: interests[kKeyAlwaysKeys]]; + [_alwaysKeys addObject:(__bridge NSString*) kSOSKVSKeyParametersKey]; // Make sure KeyParms are always of interest _firstUnlockKeys = [NSMutableSet setWithArray: interests[kKeyFirstUnlockKeys]]; _unlockedKeys = [NSMutableSet setWithArray: interests[kKeyUnlockedKeys]]; @@ -279,20 +266,11 @@ static NSString *kMonitorWroteInTimeSlice = @"TimeSlice"; _pendingSyncPeerIDs = [NSMutableSet setWithArray: interests[kKeyPendingSyncPeerIDs]]; _pendingSyncBackupPeerIDs = [NSMutableSet setWithArray: interests[kKeyPendingSyncBackupPeerIDs]]; - _monitor = interests[kMonitorState]; - if(_monitor == nil) - _monitor = [NSMutableDictionary dictionary]; - _ensurePeerRegistration = [interests[kKeyEnsurePeerRegistration] boolValue]; _dsid = interests[kKeyDSID]; _accountUUID = interests[kKeyAccountUUID]; - - // If we had a sync pending, we kick it off and migrate to sync with these peers - if ([interests[kKeySyncWithPeersPending] boolValue]) { - [self doSyncWithAllPeers]; } -} - (void)persistState { diff --git a/KVSKeychainSyncingProxy/cloudkeychainproxy.m b/KVSKeychainSyncingProxy/cloudkeychainproxy.m index ece3bb25..b0f39a4c 100644 --- a/KVSKeychainSyncingProxy/cloudkeychainproxy.m +++ b/KVSKeychainSyncingProxy/cloudkeychainproxy.m @@ -418,6 +418,13 @@ static void cloudkeychainproxy_event_handler(xpc_connection_t peer) return; } + xpc_object_t ent = xpc_connection_copy_entitlement_value(peer, "com.apple.CloudKeychainProxy.client"); + if (ent == NULL || xpc_get_type(ent) != XPC_TYPE_BOOL || xpc_bool_get_value(ent) != true) { + secnotice(PROXYXPCSCOPE, "cloudkeychainproxy_event_handler: rejected client %d", xpc_connection_get_pid(peer)); + xpc_connection_cancel(peer); + return; + } + xpc_connection_set_target_queue(peer, [SharedProxy() ckdkvsproxy_queue]); xpc_connection_set_event_handler(peer, ^(xpc_object_t event) { @@ -462,7 +469,7 @@ int ckdproxymain(int argc, const char *argv[]) UbiqitousKVSProxy* proxyID = SharedProxy(); if (proxyID) { // nothing bad happened when initializing - xpc_connection_t listener = xpc_connection_create_mach_service(xpcServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); + xpc_connection_t listener = xpc_connection_create_mach_service(kCKPServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); xpc_connection_set_event_handler(listener, ^(xpc_object_t object){ cloudkeychainproxy_event_handler(object); }); // 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. diff --git a/KeychainCircle/KCAESGCMDuplexSession.h b/KeychainCircle/KCAESGCMDuplexSession.h index 0304f1d1..7d6c8f2e 100644 --- a/KeychainCircle/KCAESGCMDuplexSession.h +++ b/KeychainCircle/KCAESGCMDuplexSession.h @@ -10,6 +10,12 @@ NS_ASSUME_NONNULL_BEGIN @interface KCAESGCMDuplexSession : NSObject +// Due to design constraints, this session object is the only thing serialized during piggybacking sessions. +// Therefore, we must add some extra data here, which is not strictly part of a AES GCM session. +@property (retain, nullable) NSString* pairingUUID; +@property uint64_t piggybackingVersion; +@property uint64_t epoch; + - (nullable NSData*) encrypt: (NSData*) data error: (NSError**) error; - (nullable NSData*) decryptAndVerify: (NSData*) data error: (NSError**) error; @@ -24,7 +30,15 @@ NS_ASSUME_NONNULL_BEGIN context: (uint64_t) context; - (nullable instancetype) initWithSecret: (NSData*) sharedSecret context: (uint64_t) context - as: (bool) inverted NS_DESIGNATED_INITIALIZER; + as: (bool) inverted; + +- (nullable instancetype)initWithSecret:(NSData*)sharedSecret + context:(uint64_t)context + as:(bool) sender + pairingUUID:(NSString* _Nullable)pairingUUID + piggybackingVersion:(uint64_t)piggybackingVersion + epoch:(uint64_t)epoch + NS_DESIGNATED_INITIALIZER; - (instancetype) init NS_UNAVAILABLE; diff --git a/KeychainCircle/KCAESGCMDuplexSession.m b/KeychainCircle/KCAESGCMDuplexSession.m index 2f512e16..3bc684cd 100644 --- a/KeychainCircle/KCAESGCMDuplexSession.m +++ b/KeychainCircle/KCAESGCMDuplexSession.m @@ -94,20 +94,29 @@ static bool derive_and_init(const struct ccmode_gcm *mode, ccgcm_ctx* ctx, NSDat static NSString* KCDSSender = @"asSender"; static NSString* KCDSSecret = @"secret"; static NSString* KCDSContext = @"context"; +static NSString* KCDSPairingUUID = @"uuid"; +static NSString* KCDSPiggybackingVersion = @"piggy"; +static NSString* KCDSEpoch= @"epoch"; - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeBool: self.asSender forKey:KCDSSender]; [aCoder encodeObject: self.secret forKey:KCDSSecret]; [aCoder encodeInt64: self.context forKey:KCDSContext]; + [aCoder encodeObject: self.pairingUUID forKey:KCDSPairingUUID]; + [aCoder encodeInt64: self.piggybackingVersion forKey:KCDSPiggybackingVersion]; + [aCoder encodeInt64:self.epoch forKey:KCDSEpoch]; } - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { - bool asSender = [aDecoder decodeBoolForKey:KCDSSender]; NSData* secret = [aDecoder decodeObjectOfClass:[NSData class] forKey:KCDSSecret]; uint64_t context = [aDecoder decodeInt64ForKey:KCDSContext]; - return [self initWithSecret:secret context:context as:asSender]; + NSString* pairingUUID = [aDecoder decodeObjectOfClass:[NSString class] forKey:KCDSPairingUUID]; + uint64_t piggybackingVersion = [aDecoder decodeInt64ForKey:KCDSPiggybackingVersion]; + uint64_t epoch = [aDecoder decodeInt64ForKey:KCDSEpoch]; + + return [self initWithSecret:secret context:context as:asSender pairingUUID:pairingUUID piggybackingVersion:piggybackingVersion epoch:epoch]; } + (BOOL)supportsSecureCoding { @@ -127,6 +136,21 @@ static NSString* KCDSContext = @"context"; - (nullable instancetype) initWithSecret: (NSData*) sharedSecret context: (uint64_t) context as: (bool) sender { + return [self initWithSecret:sharedSecret + context:context + as:sender + pairingUUID:nil + piggybackingVersion:0 + epoch:1]; +} + +- (nullable instancetype)initWithSecret:(NSData*)sharedSecret + context:(uint64_t)context + as:(bool) sender + pairingUUID:(NSString* _Nullable)pairingUUID + piggybackingVersion:(uint64_t)piggybackingVersion + epoch:(uint64_t)epoch +{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ kdfInfoSendToReceive = [NSData dataWithBytesNoCopy: kdfInfoForwardString @@ -146,6 +170,10 @@ static NSString* KCDSContext = @"context"; self.receive = malloc(ccgcm_context_size(ccaes_gcm_decrypt_mode())); self.context = context; + _pairingUUID = pairingUUID; + _piggybackingVersion = piggybackingVersion; + _epoch = epoch; + if (self.send == nil || self.receive == nil) { return nil; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h b/KeychainCircle/KCInitialMessageData.proto similarity index 82% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h rename to KeychainCircle/KCInitialMessageData.proto index 031a4606..db6ffd30 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.h +++ b/KeychainCircle/KCInitialMessageData.proto @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,9 +21,12 @@ * @APPLE_LICENSE_HEADER_END@ */ -#ifndef SOSSysdiagnose_h -#define SOSSysdiagnose_h +syntax = "proto2"; -char *SOSCCSysdiagnose(const char *directoryname); +option objc_class_naming = "extended"; -#endif /* SOSSysdiagnose_h */ +package KC; + +message InitialMessageData { + optional bytes prepareMessage = 1; +} diff --git a/KeychainCircle/KCJoiningAcceptSession+Internal.h b/KeychainCircle/KCJoiningAcceptSession+Internal.h new file mode 100644 index 00000000..ea2c1be2 --- /dev/null +++ b/KeychainCircle/KCJoiningAcceptSession+Internal.h @@ -0,0 +1,38 @@ +/* + * 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 + +#ifndef KCJoiningAcceptSession_Internal_h +#define KCJoiningAcceptSession_Internal_h + +#import +#import "keychain/ot/OTControl.h" +#import "KCJoiningSession.h" + +@interface KCJoiningAcceptSession (Internal) +-(void)setControlObject:(OTControl*)control; +- (void)setConfiguration:(OTJoiningConfiguration *)config; +@end +#endif /* Header_h */ +#endif diff --git a/KeychainCircle/KCJoiningAcceptSession.m b/KeychainCircle/KCJoiningAcceptSession.m index 3c216c0b..743b60e3 100644 --- a/KeychainCircle/KCJoiningAcceptSession.m +++ b/KeychainCircle/KCJoiningAcceptSession.m @@ -13,6 +13,7 @@ #import #import +#import "KCInitialMessageData.h" #include #include @@ -20,6 +21,17 @@ #include #include #include +#include + +#if OCTAGON +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTJoiningConfiguration.h" +#import "KeychainCircle/KCJoiningAcceptSession+Internal.h" +#import "keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h" +#import "keychain/ot/proto/generated_source/OTPairingMessage.h" +#endif typedef enum { kExpectingA, @@ -38,6 +50,12 @@ typedef enum { @property (readwrite) NSData* startMessage; @property (readwrite) NSString *piggy_uuid; @property (readwrite) PiggyBackProtocolVersion piggy_version; +@property (readwrite) NSData* octagon; +#if OCTAGON +@property (nonatomic, strong) OTJoiningConfiguration* joiningConfiguration; +@property (nonatomic, strong) OTControl* otControl; +#endif +@property (nonatomic, strong) NSMutableDictionary *defaults; @end @implementation KCJoiningAcceptSession @@ -72,6 +90,10 @@ typedef enum { } self->_session = [KCAESGCMDuplexSession sessionAsReceiver:key context:self.dsid]; +#if OCTAGON + self.session.pairingUUID = self.joiningConfiguration.pairingUUID; +#endif + self.session.piggybackingVersion = self.piggy_version; return self.session != nil; } @@ -83,6 +105,8 @@ typedef enum { error: (NSError**) error { self = [super init]; + secnotice("accepting", "initWithSecretDelegate"); + NSString* name = [NSString stringWithFormat: @"%llu", dsid]; self->_context = [[KCSRPServerContext alloc] initWithUser: name @@ -95,7 +119,21 @@ typedef enum { self->_state = kExpectingA; self->_dsid = dsid; self->_piggy_uuid = nil; + self->_defaults = [NSMutableDictionary dictionary]; + +#if OCTAGON + self->_otControl = [OTControl controlObject:true error:error]; + self->_piggy_version = KCJoiningOctagonPiggybackingEnabled()? kPiggyV2 : kPiggyV1; + self->_joiningConfiguration = [[OTJoiningConfiguration alloc]initWithProtocolType:@"OctagonPiggybacking" + uniqueDeviceID:@"acceptor-deviceid" + uniqueClientID:@"requester-deviceid" + containerName:nil + contextID:OTDefaultContext + epoch:0 + isInitiator:false]; +#else self->_piggy_version = kPiggyV1; +#endif return self; } @@ -111,7 +149,7 @@ typedef enum { } - (NSString *)description { - return [NSString stringWithFormat: @"", self, self.dsid, [self stateString], self.context]; + return [NSString stringWithFormat: @"", self.dsid, [self stateString], self.context, self.piggy_uuid]; } - (NSData*) copyChallengeMessage: (NSError**) error { @@ -125,20 +163,105 @@ typedef enum { return srpMessage; } +#if OCTAGON +- (BOOL)shouldAcceptOctagonRequests { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + __block BOOL result = NO; + + OTOperationConfiguration* configuration = [[OTOperationConfiguration alloc] init]; + configuration.discretionaryNetwork = TRUE; + + [self.otControl fetchTrustStatus:self.joiningConfiguration.containerName context:self.joiningConfiguration.self.contextID + configuration:configuration + reply:^(CliqueStatus status, + NSString* peerID, + NSNumber * _Nullable numberOfPeersInOctagon, + BOOL isExcluded, NSError* _Nullable error) + { + secerror("octagon haveSelfEgo: status %d: %@ %@ %d: %@", (int)status, + peerID, numberOfPeersInOctagon, isExcluded, error); + + if (status == CliqueStatusIn) { + result = YES; + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { + secerror("octagon: timed out fetching trust status"); + return NO; + } + return result; +} +#endif + - (NSData*) processInitialMessage: (NSData*) initialMessage error: (NSError**) error { - uint64_t version = 0; + __block uint64_t version = 0; NSString *uuid = nil; - - self.startMessage = extractStartFromInitialMessage(initialMessage, &version, &uuid, error); + NSData *octagon = nil; + NSError* localError = nil; + + self.startMessage = extractStartFromInitialMessage(initialMessage, &version, &uuid, &octagon, error); + if (self.startMessage == NULL) { + return nil; + } +#if OCTAGON + if(version == kPiggyV2 && KCJoiningOctagonPiggybackingEnabled()){ + /* before we go ahead with octagon, let see if we are an octagon peer */ + + if (![self shouldAcceptOctagonRequests]) { + secerror("octagon refusing octagon acceptor since we don't have a selfEgo"); + version = kPiggyV1; + } else { + self.octagon = octagon; + } + localError = nil; + } +#endif self.piggy_uuid = uuid; self.piggy_version = (PiggyBackProtocolVersion)version; - - if (self.startMessage == nil) return nil; NSData* srpMessage = [self copyChallengeMessage: error]; - if (srpMessage == nil) return nil; + if (srpMessage == nil) { + return nil; + } self->_state = kExpectingM; +#if OCTAGON + NSString* piggyVersionMessage = [[NSString alloc]initWithData:self.octagon encoding:NSUTF8StringEncoding]; + __block NSError *captureError = nil; + + if(version == kPiggyV2 && KCJoiningOctagonPiggybackingEnabled() && piggyVersionMessage && [piggyVersionMessage isEqualToString:@"o"]) { + __block NSData* next = nil; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + //fetch epoch + [self.otControl rpcEpochWithConfiguration:self.joiningConfiguration reply:^(uint64_t epoch, NSError * _Nullable epochError) { + if(epochError){ + secerror("error retrieving next message! :%@", epochError); + captureError = epochError; + }else{ + OTPairingMessage* responseMessage = [[OTPairingMessage alloc] init]; + responseMessage.epoch = [[OTSponsorToApplicantRound1M2 alloc] init]; + responseMessage.epoch.epoch = epoch; + next = responseMessage.data; + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { + secerror("octagon: timed out fetching epoch"); + return nil; + } + if(error && captureError){ + *error = captureError; + } + return [[KCJoiningMessage messageWithType:kChallenge + data:srpMessage + payload:next + error:error] der]; + } +#endif return [[KCJoiningMessage messageWithType:kChallenge data:srpMessage error:error] der]; @@ -156,7 +279,10 @@ typedef enum { // Find out what kind of error we should send. NSData* errorData = nil; - switch ([self.secretDelegate verificationFailed: error]) { + KCRetryOrNot status = [self.secretDelegate verificationFailed: error]; + secerror("processResponse: handle error: %d", (int)status); + + switch (status) { case kKCRetryError: // We fill in an error if they didn't, but if they did this wont bother. KCJoiningErrorCreate(kInternalError, error, @"Delegate returned error without filling in error: %@", self.secretDelegate); @@ -192,13 +318,9 @@ typedef enum { error:error] der]; } -- (NSData*) processApplication: (KCJoiningMessage*) message error:(NSError**) error { - if ([message type] != kPeerInfo) { - KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected peerInfo!"); - return nil; - } - - NSData* decryptedPayload = [self.session decryptAndVerify:message.firstData error:error]; +- (NSData*) processSOSApplication: (NSData*) message error:(NSError**) error +{ + NSData* decryptedPayload = [self.session decryptAndVerify:message error:error]; if (decryptedPayload == nil) return nil; CFErrorRef cfError = NULL; @@ -216,7 +338,7 @@ typedef enum { } if (joinData == nil) return nil; - + if(self->_piggy_version == kPiggyV1){ //grab iCloud Identities, TLKs secnotice("acceptor", "piggy version is 1"); @@ -225,18 +347,127 @@ typedef enum { if(localV1Error){ secnotice("piggy", "PB v1 threw an error: %@", localV1Error); } - + NSMutableData* growPacket = [[NSMutableData alloc] initWithData:joinData]; [growPacket appendData:initialSyncData]; joinData = growPacket; - + } - + NSData* encryptedOutgoing = [self.session encrypt:joinData error:error]; if (encryptedOutgoing == nil) return nil; + return encryptedOutgoing; +} + +#if OCTAGON +- (OTPairingMessage *)createPairingMessageFromJoiningMessage:(KCJoiningMessage *)message error:(NSError**) error +{ + NSData *decryptInitialMessage = [self.session decryptAndVerify:message.firstData error:error]; + if(!decryptInitialMessage) { + secinfo("KeychainCircle", "Failed to decrypt message first data: %@. Trying legacy OTPairingMessage construction.", error ? *error : @""); + return [[OTPairingMessage alloc] initWithData:message.firstData]; + } else { + KCInitialMessageData *initialMessage = [[KCInitialMessageData alloc] initWithData:decryptInitialMessage]; + if(!initialMessage) { + secerror("Failed to parse InitialMessageData from decrypted message data"); + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Failed to parse InitialMessageData from decrypted message data"); + return nil; + } + + if(!initialMessage.hasPrepareMessage) { + secerror("InitialMessageData does not contain prepare message"); + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected prepare message inside InitialMessageData"); + return nil; + } + + return [[OTPairingMessage alloc] initWithData:initialMessage.prepareMessage]; + } +} +#endif + +- (NSData*) processApplication: (KCJoiningMessage*) message error:(NSError**) error { + if ([message type] != kPeerInfo) { + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected peerInfo!"); + return nil; + } +#if OCTAGON + if(self.piggy_version == kPiggyV2 && KCJoiningOctagonPiggybackingEnabled()){ + __block NSData* next = nil; + __block NSError* localError = nil; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + OTPairingMessage *pairingMessage = [self createPairingMessageFromJoiningMessage:message error:error]; + if(!pairingMessage) { + secerror("octagon, failed to create pairing message from JoiningMessage"); + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Failed to create pairing message from JoiningMessage"); + return nil; + } + + if(!pairingMessage.hasPrepare) { + secerror("octagon, message does not contain prepare message"); + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected prepare message!"); + return nil; + } + OTApplicantToSponsorRound2M1 *prepareMessage = pairingMessage.prepare; + + //handle identity, fetch voucher + [self.otControl rpcVoucherWithConfiguration:self.joiningConfiguration + peerID:prepareMessage.peerID + permanentInfo:prepareMessage.permanentInfo + permanentInfoSig:prepareMessage.permanentInfoSig + stableInfo:prepareMessage.stableInfo + stableInfoSig:prepareMessage.stableInfoSig reply:^(NSData *voucher, + NSData *voucherSig, + NSError *err) { + if(err){ + secerror("error producing octagon voucher: %@", err); + localError = err; + }else{ + OTPairingMessage *pairingResponse = [[OTPairingMessage alloc] init]; + pairingResponse.voucher = [[OTSponsorToApplicantRound2M2 alloc] init]; + pairingResponse.voucher.voucher = voucher; + pairingResponse.voucher.voucherSignature = voucherSig; + next = pairingResponse.data; + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { + secerror("octagon: timed out producing octagon voucher"); + return nil; + } + if (next == NULL) { + if(error && localError){ + *error = localError; + } + return nil; + } + + NSData* encryptedOutgoing = nil; + if (OctagonPlatformSupportsSOS() && message.secondData) { + secnotice("joining", "doing SOS processSOSApplication"); + //note we are stuffing SOS into the payload "secondData" + encryptedOutgoing = [self processSOSApplication: message.secondData error:error]; + } else { + secnotice("joining", "no platform support processSOSApplication, peer sent data: %s", + message.secondData ? "yes" : "no"); + } + + self->_state = kAcceptDone; + + return [[KCJoiningMessage messageWithType:kCircleBlob + data:next + payload:encryptedOutgoing + error:error] der]; + } +#endif + NSData* encryptedOutgoing = [self processSOSApplication: message.firstData error:error]; self->_state = kAcceptDone; + secnotice("joining", "posting kSOSCCCircleOctagonKeysChangedNotification"); + notify_post(kSOSCCCircleOctagonKeysChangedNotification); + return [[KCJoiningMessage messageWithType:kCircleBlob data:encryptedOutgoing error:error] der]; @@ -246,6 +477,8 @@ typedef enum { - (nullable NSData*) processMessage: (NSData*) incomingMessage error: (NSError**) error { NSData* result = nil; + secnotice("acceptor", "processMessages: %@", [self description]); + KCJoiningMessage *message = (self.state != kExpectingA) ? [KCJoiningMessage messageWithDER:incomingMessage error:error] : nil; switch(self.state) { @@ -270,4 +503,17 @@ typedef enum { return self.state == kAcceptDone; } +/* for test*/ +#if OCTAGON +- (void)setControlObject:(OTControl *)control +{ + self.otControl = control; +} + +- (void)setConfiguration:(OTJoiningConfiguration *)config +{ + self.joiningConfiguration = config; +} +#endif + @end diff --git a/KeychainCircle/KCJoiningMessages.h b/KeychainCircle/KCJoiningMessages.h index 827e0e41..a6ad9e38 100644 --- a/KeychainCircle/KCJoiningMessages.h +++ b/KeychainCircle/KCJoiningMessages.h @@ -9,10 +9,11 @@ // Initial messages are versioned and not typed for negotiation. NS_ASSUME_NONNULL_BEGIN -NSData* extractStartFromInitialMessage(NSData* initialMessage, uint64_t* version, NSString* _Nullable * _Nullable uuidString, NSError** error); +NSData* extractStartFromInitialMessage(NSData* initialMessage, uint64_t* version, NSString* _Nullable * _Nullable uuidString, NSData* _Nullable * _Nullable octagon, NSError** error); size_t sizeof_initialmessage(NSData*data); size_t sizeof_initialmessage_version1(NSData*data, uint64_t version1, NSData *uuid); +size_t sizeof_initialmessage_version2(NSData*data, uint64_t version1, NSData *uuid, NSData* octagon); @@ -21,12 +22,19 @@ uint8_t* _Nullable encode_initialmessage(NSData* data, NSError**error, uint8_t* _Nullable encode_initialmessage_version1(NSData* data, NSData* uuidData, uint64_t piggy_version, NSError**error, const uint8_t *der, uint8_t *der_end); +uint8_t* encode_initialmessage_version2(NSData* data, NSData* uuidData, NSData* octagon_version, NSError**error, + const uint8_t *der, uint8_t *der_end); + const uint8_t* _Nullable decode_initialmessage(NSData* _Nonnull * _Nonnull data, NSError** error, const uint8_t* der, const uint8_t *der_end); const uint8_t* _Nullable decode_version1(NSData* _Nonnull* _Nonnull data, NSData* _Nullable* _Nullable uuid, uint64_t * _Nullable piggy_version, NSError** error, const uint8_t* der, const uint8_t *der_end); +const uint8_t* _Nullable decode_version2(NSData* _Nonnull* _Nonnull data, NSData* _Nullable* _Nullable uuid, NSData* _Nullable* _Nullable octagon, uint64_t* _Nullable piggy_version, NSError** error, + const uint8_t* der, const uint8_t *der_end); + + size_t sizeof_seq_data_data(NSData*data1, NSData*data2, NSError** error); uint8_t* _Nullable encode_seq_data_data(NSData* data, NSData*data2, NSError**error, const uint8_t *der, uint8_t *der_end); @@ -90,7 +98,6 @@ typedef enum { @property (readonly) KCJoiningMessageType type; @property (readonly) NSData* firstData; @property (nullable, readonly) NSData* secondData; - @property (readonly) NSData* der; + (nullable instancetype) messageWithDER: (NSData*) message diff --git a/KeychainCircle/KCJoiningMessages.m b/KeychainCircle/KCJoiningMessages.m index 7d83db0f..2eb0c94b 100644 --- a/KeychainCircle/KCJoiningMessages.m +++ b/KeychainCircle/KCJoiningMessages.m @@ -13,7 +13,7 @@ #import #import #import - +#import #include @@ -30,6 +30,13 @@ return [[KCJoiningMessage alloc] initWithType:type data:firstData payload:nil error:error]; } ++ (nullable instancetype) messageWithType: (KCJoiningMessageType) type + data: (NSData*) firstData + secondData: (NSData*) secondData + error: (NSError**) error { + return [[KCJoiningMessage alloc] initWithType:type data:firstData payload:secondData error:error]; +} + + (nullable instancetype) messageWithType: (KCJoiningMessageType) type data: (NSData*) firstData payload: (NSData*) secondData @@ -255,7 +262,7 @@ @end -NSData* extractStartFromInitialMessage(NSData* initialMessage, uint64_t* version, NSString** uuidString, NSError** error) { +NSData* extractStartFromInitialMessage(NSData* initialMessage, uint64_t* version, NSString** uuidString, NSData** octagon, NSError** error) { NSData* result = nil; const uint8_t *der = [initialMessage bytes]; const uint8_t *der_end = der + [initialMessage length]; @@ -267,12 +274,30 @@ NSData* extractStartFromInitialMessage(NSData* initialMessage, uint64_t* version } else if (parse_end != der_end) { NSData *extraStuff = nil; - NSData *uuid = nil; + NSData *uuidData = nil; uint64_t piggy_version = 0; - parse_end = decode_version1(&extraStuff, &uuid, &piggy_version, error, parse_end, der_end); - require_action_quiet(parse_end != NULL, fail, secerror("decoding piggybacking uuid and version failed (v1)")); - *uuidString = [[NSString alloc] initWithData:uuid encoding:NSUTF8StringEncoding]; - *version = piggy_version; + NSData* octagonData = nil; + + parse_end = decode_version2(&extraStuff, &uuidData, &octagonData, &piggy_version, error, parse_end, der_end); + require_action_quiet(parse_end != NULL, fail, secerror("decoding piggybacking message failed for version (%llu)", piggy_version)); + + switch(piggy_version){ + case kPiggyV2: + *octagon = octagonData; + //fall through to pick up v1 + case kPiggyV1:{ + NSUUID *uuid = [[NSUUID alloc]initWithUUIDBytes:uuidData.bytes]; + *uuidString = uuid.UUIDString; + *version = piggy_version; + break; + } + case kPiggyV0: + *version = kPiggyV0; + break; + default: + secerror("unsupported version"); + break; + } } fail: return result; @@ -294,11 +319,12 @@ const uint8_t* decode_version1(NSData** data, NSData** uuid, uint64_t *piggy_ver } if(versionFromBlob == 1){ //decode uuid - size_t payload_size = 0; - const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end); + size_t payloadSize = 0; + const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payloadSize, der, der_end); - *uuid = [NSData dataWithBytes: (void*)payload length: payload_size]; + *uuid = [NSData dataWithBytes: (void*)payload length: payloadSize]; *piggy_version = versionFromBlob; + der = payload + payloadSize; } else{ KCJoiningErrorCreate(kDERUnknownVersion, error, @"Bad version: %llu", versionFromBlob); @@ -307,6 +333,41 @@ const uint8_t* decode_version1(NSData** data, NSData** uuid, uint64_t *piggy_ver return der; } + +const uint8_t* decode_version2(NSData** data, NSData** uuid, NSData** octagon, uint64_t *piggy_version, NSError** error, + const uint8_t* der, const uint8_t *der_end) +{ + const uint8_t* end = nil; + + const uint8_t* parse_version1 = decode_version1(data, uuid, piggy_version, error, der, der_end); + + if(parse_version1 == NULL){ + secerror("error parsing version 1"); + return NULL; + } + else if (parse_version1 == der_end){ + secnotice("octagon", "first message is piggybacking v1, no more data"); + return parse_version1; + } + else{ + end = kcder_decode_data(octagon, error, parse_version1, der_end); + + if(end == NULL){ + secerror("failed to decode v2"); + return NULL; + } + else if(*octagon && [*octagon length] != 0){ + *piggy_version = kPiggyV2; + } + else{ + secerror("no octagon version set"); + return NULL; + } + } + + return end; +} + const uint8_t* decode_initialmessage(NSData** data, NSError** error, const uint8_t* der, const uint8_t *der_end) { @@ -356,7 +417,8 @@ uint8_t* encode_initialmessage(NSData* data, NSError**error, kcder_encode_data(data, error, der, der_end))); } -size_t sizeof_initialmessage_version1(NSData*data, uint64_t version1, NSData *uuid) { +size_t sizeof_initialmessage_version2(NSData*data, uint64_t version1, NSData *uuid, NSData* octagon) +{ size_t version_size = ccder_sizeof_uint64(0); if (version_size == 0) { return 0; @@ -370,9 +432,35 @@ size_t sizeof_initialmessage_version1(NSData*data, uint64_t version1, NSData *uu return 0; } size_t uuid_size = kcder_sizeof_data(uuid, nil); + if (uuid_size == 0) { + return 0; + } + size_t octagon_size = kcder_sizeof_data(octagon, nil); + if (octagon_size == 0) { + return 0; + } + return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, version_size + message_size + + version1_size + uuid_size + + octagon_size); +} + +size_t sizeof_initialmessage_version1(NSData*data, uint64_t version1, NSData *uuid) { + size_t version_size = ccder_sizeof_uint64(0); + if (version_size == 0) { + return 0; + } + size_t message_size = kcder_sizeof_data(data, nil); if (message_size == 0) { return 0; } + size_t version1_size = ccder_sizeof_uint64(version1); + if (version1_size == 0) { + return 0; + } + size_t uuid_size = kcder_sizeof_data(uuid, nil); + if (uuid_size == 0) { + return 0; + } return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, version_size + message_size + version1_size + uuid_size); } @@ -388,6 +476,17 @@ uint8_t* encode_initialmessage_version1(NSData* data, NSData* uuidData, uint64_ } +uint8_t* encode_initialmessage_version2(NSData* data, NSData* uuidData, NSData* octagon_version, NSError**error, + const uint8_t *der, uint8_t *der_end) +{ + + return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, + ccder_encode_uint64(0, der, + kcder_encode_data(data, error, der, + ccder_encode_uint64(kPiggyV1, der, + kcder_encode_data(uuidData, error, der, kcder_encode_data(octagon_version, error, der, der_end)))))); +} + size_t sizeof_seq_data_data(NSData*data1, NSData*data2, NSError**error) { size_t data1_size = kcder_sizeof_data(data1, error); if (data1_size == 0) { diff --git a/KeychainCircle/KCJoiningRequestCircleSession.m b/KeychainCircle/KCJoiningRequestCircleSession.m new file mode 100644 index 00000000..ed9db950 --- /dev/null +++ b/KeychainCircle/KCJoiningRequestCircleSession.m @@ -0,0 +1,332 @@ +// +// KCJoiningRequestCircleSession.m +// Security +// + +#import + +#import + +#import +#import +#import + +#import + +#include +#include "KCInitialMessageData.h" + +#if OCTAGON +#import +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTControlProtocol.h" +#import "keychain/ot/OctagonControlServer.h" +#import "keychain/ot/OTJoiningConfiguration.h" +#import "KeychainCircle/KCJoiningRequestSession+Internal.h" +#import "keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h" +#import "keychain/ot/proto/generated_source/OTPairingMessage.h" +#endif +#import + +typedef enum { + kExpectingCircleBlob, + kRequestCircleDone +} KCJoiningRequestCircleSessionState; + +@interface KCJoiningRequestCircleSession () +@property (readonly) NSObject* circleDelegate; +@property (readonly) KCAESGCMDuplexSession* session; +@property (readwrite) KCJoiningRequestCircleSessionState state; +@property (nonatomic) uint64_t piggy_version; +#if OCTAGON +@property (nonatomic, strong) OTControl *otControl; +@property (nonatomic, strong) OTJoiningConfiguration* joiningConfiguration; +#endif +@end + +@implementation KCJoiningRequestCircleSession + +#if OCTAGON +- (void)setControlObject:(OTControl *)control{ + self.otControl = control; +} +- (void)setJoiningConfigurationObject:(OTJoiningConfiguration *)joiningConfiguration +{ + self.joiningConfiguration = joiningConfiguration; +} + +#endif + +- (nullable NSData*) encryptedPeerInfo: (NSError**) error { + // Get our peer info and send it along: + if (self->_session == nil) { + KCJoiningErrorCreate(kInternalError, error, @"Attempt to encrypt with no session"); + return nil; + } + + SOSPeerInfoRef us = [self.circleDelegate copyPeerInfoError:error]; + if (us == NULL) return nil; + CFErrorRef cfError = NULL; + NSData* piEncoded = (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(us, NULL, &cfError); + if(us) { + CFRelease(us); + us = NULL; + } + + if (piEncoded == nil) { + if (error != nil) { + *error = (__bridge_transfer NSError*) cfError; + } + return nil; + } + + return [self->_session encrypt:piEncoded error:error]; +} + +- (nullable NSData*) encryptedInitialMessage:(NSData*)prepareMessage error:(NSError**) error { + + if (self->_session == nil) { + KCJoiningErrorCreate(kInternalError, error, @"Attempt to encrypt with no session"); + return nil; + } + + KCInitialMessageData *initialMessage = [[KCInitialMessageData alloc] init]; + [initialMessage setPrepareMessage:prepareMessage]; + + return [self->_session encrypt:initialMessage.data error:error]; +} + +- (nullable NSData*) initialMessage: (NSError**) error { + secnotice("joining", "joining: KCJoiningRequestCircleSession initialMessage called"); + +#if OCTAGON + if(KCJoiningOctagonPiggybackingEnabled() && self.piggy_version == kPiggyV2){ + __block NSData* next = nil; + __block NSError* localError = nil; + + if(!self.joiningConfiguration.epoch) { + secerror("octagon: expected epoch! returning from piggybacking."); + return nil; + } + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + //giving securityd the epoch, expecting identity message + [self.otControl rpcPrepareIdentityAsApplicantWithConfiguration:self.joiningConfiguration + reply:^(NSString *peerID, + NSData *permanentInfo, + NSData *permanentInfoSig, + NSData *stableInfo, + NSData *stableInfoSig, + NSError *err) { + if(err){ + secerror("octagon: error preparing identity: %@", err); + localError = err; + } else{ + OTPairingMessage *pairingMessage = [[OTPairingMessage alloc]init]; + OTApplicantToSponsorRound2M1 *prepareMessage = [[OTApplicantToSponsorRound2M1 alloc]init]; + prepareMessage.peerID = peerID; + prepareMessage.permanentInfo = permanentInfo; + prepareMessage.permanentInfoSig = permanentInfoSig; + prepareMessage.stableInfo = stableInfo; + prepareMessage.stableInfoSig = stableInfoSig; + + pairingMessage.prepare = prepareMessage; + next = pairingMessage.data; + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { + secerror("octagon: timed out preparing identity"); + return nil; + } + if(error){ + *error = localError; + } + + NSData* encryptedPi = nil; + if (OctagonPlatformSupportsSOS()) { + secnotice("joining", "doing SOS encryptedPeerInfo"); + encryptedPi = [self encryptedPeerInfo:error]; + if (encryptedPi == nil) return nil; + } else { + secnotice("joining", "no platform support for encryptedPeerInfo"); + } + + self->_state = kExpectingCircleBlob; + NSData *encryptedInitialMessage = [self encryptedInitialMessage:next error:error]; + + return [[KCJoiningMessage messageWithType: kPeerInfo + data:encryptedInitialMessage + payload:encryptedPi + error:error] der]; + } +#endif + + NSData* encryptedPi = [self encryptedPeerInfo:error]; + if (encryptedPi == nil) return nil; + + self->_state = kExpectingCircleBlob; + + return [[KCJoiningMessage messageWithType:kPeerInfo + data:encryptedPi + error:error] der]; + +} + +- (void) attemptSosUpgrade +{ + [self.otControl attemptSosUpgrade:self.joiningConfiguration.containerName context:self.joiningConfiguration.contextID reply:^(NSError *error) { + if(error){ + secerror("pairing: failed to upgrade initiator into Octagon: %@", error); + } + }]; +} + +- (NSData*) handleCircleBlob: (KCJoiningMessage*) message error: (NSError**) error { + secnotice("joining", "joining: KCJoiningRequestCircleSession handleCircleBlob called"); + if ([message type] != kCircleBlob) { + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected CircleBlob!"); + return nil; + } +#if OCTAGON + if(self.piggy_version == kPiggyV2 && KCJoiningOctagonPiggybackingEnabled() && message.firstData != nil){ + __block NSData* nextMessage = nil; + __block NSError* localError = nil; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + OTPairingMessage* pairingMessage = [[OTPairingMessage alloc]initWithData:message.firstData]; + if(!pairingMessage.hasVoucher) { + secerror("octagon: expected voucher! returning from piggybacking."); + return nil; + } + OTSponsorToApplicantRound2M2 *voucher = pairingMessage.voucher; + + //handle voucher message then join octagon + [self.otControl rpcJoinWithConfiguration:self.joiningConfiguration vouchData:voucher.voucher vouchSig:voucher.voucherSignature preapprovedKeys:voucher.preapprovedKeys reply:^(NSError * _Nullable err) { + if(err){ + secerror("octagon: error joining octagon: %@", err); + localError = err; + }else{ + secnotice("octagon", "successfully joined octagon"); + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30)) != 0) { + + secerror("octagon: timed out joining octagon"); + return nil; + } + + if (OctagonPlatformSupportsSOS()) { + secnotice("joining", "doing SOS processCircleJoinData"); + //note we are stuffing SOS into the payload "secondData" + NSData* circleBlob = [self.session decryptAndVerify:message.secondData error:error]; + if (circleBlob == nil) return nil; + + if (![self.circleDelegate processCircleJoinData: circleBlob version:kPiggyV1 error:error]) + return nil; + } else { + secnotice("joining", "platform doesn't support SOS"); + } + + self->_state = kRequestCircleDone; + + NSData* final = nil; + if(nextMessage == nil){ + final = [NSData data]; + } + self->_state = kRequestCircleDone; + return final; + } +#endif + NSData* circleBlob = [self.session decryptAndVerify:message.firstData error:error]; + if (circleBlob == nil) return nil; + + if (![self.circleDelegate processCircleJoinData: circleBlob version:kPiggyV1 error:error]) { + return nil; + } else { + secnotice("joining", "joined the SOS circle!"); + if(OctagonIsEnabled()) { + secnotice("joining", "kicking off SOS Upgrade into Octagon!"); + [self attemptSosUpgrade]; + } + } + self->_state = kRequestCircleDone; + + return [NSData data]; // Success, an empty message. +} + +- (NSData*) processMessage: (NSData*) incomingMessage error: (NSError**) error { + secnotice("joining", "joining: KCJoiningRequestCircleSession processMessage called"); + NSData* result = nil; + KCJoiningMessage* message = [KCJoiningMessage messageWithDER: incomingMessage error: error]; + if (message == nil) return nil; + + switch(self.state) { + case kExpectingCircleBlob: + return [self handleCircleBlob:message error:error]; + case kRequestCircleDone: + KCJoiningErrorCreate(kUnexpectedMessage, error, @"Done, no messages expected."); + break; + } + + return result; +} + +- (bool) isDone { + return self.state = kRequestCircleDone; +} + ++ (instancetype) sessionWithCircleDelegate: (NSObject*) circleDelegate + session: (KCAESGCMDuplexSession*) session + error: (NSError**) error { + return [[KCJoiningRequestCircleSession alloc] initWithCircleDelegate:circleDelegate + session:session + error:error]; +} + +- (instancetype) initWithCircleDelegate: (NSObject*) circleDelegate + session: (KCAESGCMDuplexSession*) session + error: (NSError**) error { + return [self initWithCircleDelegate:circleDelegate + session:session + otcontrol:[OTControl controlObject:true error:error] + error:error]; +} + +- (instancetype)initWithCircleDelegate:(NSObject*)circleDelegate + session:(KCAESGCMDuplexSession*) session + otcontrol:(OTControl*)otcontrol + error:(NSError**) error +{ + secnotice("joining", "joining: KCJoiningRequestCircleSession initWithCircleDelegate called, uuid=%@", session.pairingUUID); + self = [super init]; + + self->_circleDelegate = circleDelegate; + self->_session = session; + self.state = kExpectingCircleBlob; +#if OCTAGON + self->_otControl = otcontrol; + self->_joiningConfiguration = [[OTJoiningConfiguration alloc]initWithProtocolType:@"OctagonPiggybacking" + uniqueDeviceID:@"requester-id" + uniqueClientID:@"requester-id" + pairingUUID:session.pairingUUID + containerName:nil + contextID:OTDefaultContext + epoch:session.epoch + isInitiator:true]; + + self->_piggy_version = session.piggybackingVersion; +#else + self->_piggy_version = kPiggyV1; +#endif + + return self; +} + +@end + diff --git a/KeychainCircle/KCJoiningRequestSession.m b/KeychainCircle/KCJoiningRequestSecretSession.m similarity index 62% rename from KeychainCircle/KCJoiningRequestSession.m rename to KeychainCircle/KCJoiningRequestSecretSession.m index e3be618e..f251465c 100644 --- a/KeychainCircle/KCJoiningRequestSession.m +++ b/KeychainCircle/KCJoiningRequestSecretSession.m @@ -19,9 +19,22 @@ #include #include #include - +#import #include +#if OCTAGON +#import +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTControlProtocol.h" +#import "keychain/ot/OctagonControlServer.h" +#import "keychain/ot/OTJoiningConfiguration.h" +#import "KeychainCircle/KCJoiningRequestSession+Internal.h" + +#import "keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h" +#import "keychain/ot/proto/generated_source/OTPairingMessage.h" +#endif #import typedef enum { @@ -30,10 +43,21 @@ typedef enum { kRequestSecretDone } KCJoiningRequestSecretSessionState; -typedef enum { - kExpectingCircleBlob, - kRequestCircleDone -} KCJoiningRequestCircleSessionState; +#if OCTAGON +static bool KCJoiningOctagonPiggybackingDefault = false; +bool KCSetJoiningOctagonPiggybackingEnabled(bool value) +{ + KCJoiningOctagonPiggybackingDefault = value; + return value; +} + +// defaults write com.apple.security.octagon enable -bool YES +bool KCJoiningOctagonPiggybackingEnabled() { + bool result = KCJoiningOctagonPiggybackingDefault ? KCJoiningOctagonPiggybackingDefault : OctagonIsEnabled(); + secnotice("octagon", "Octagon Piggybacking is %@ ", result ? @"on" : @"off"); + return result; +} +#endif @interface KCJoiningRequestSecretSession () @@ -43,39 +67,68 @@ typedef enum { @property (readonly) KCJoiningRequestSecretSessionState state; @property (readwrite) NSString* piggy_uuid; @property (readwrite) uint64_t piggy_version; +@property (readwrite) uint64_t epoch; @property (readwrite) NSData* challenge; @property (readwrite) NSData* salt; +#if OCTAGON +@property (nonatomic, strong) OTJoiningConfiguration* joiningConfiguration; +@property (nonatomic, strong) OTControl *otControl; +#endif +@property (nonatomic, strong) NSMutableDictionary *defaults; @end -static const uint64_t KCProtocolVersion = kPiggyV1; - @implementation KCJoiningRequestSecretSession : NSObject + +- (nullable NSData*) createUUID +{ + NSUUID *uuid = [NSUUID UUID]; + uuid_t uuidBytes; + + self.piggy_uuid = [uuid UUIDString]; + [uuid getUUIDBytes:uuidBytes]; + NSData *uuidData = [NSData dataWithBytes:uuidBytes length:sizeof(uuid_t)]; + return uuidData; +} + - (nullable NSData*) initialMessage: (NSError**) error { NSData* start = [self->_context copyStart: error]; if (start == nil) return nil; NSMutableData* initialMessage = NULL; - - - if(KCProtocolVersion == kPiggyV1) - { - NSUUID *uuid = [NSUUID UUID]; - uuid_t uuidBytes; + secnotice("joining", "joining: KCJoiningRequestSecretSession initialMessage called"); - self.piggy_uuid = [uuid UUIDString]; - [uuid getUUIDBytes:uuidBytes]; - NSData *uuidData = [NSData dataWithBytes:uuidBytes length:sizeof(uuid_t)]; + if(self.piggy_version == kPiggyV2){ +#if OCTAGON + if(KCJoiningOctagonPiggybackingEnabled()){ + NSData* uuidData = [self createUUID]; - initialMessage = [NSMutableData dataWithLength: sizeof_initialmessage_version1(start, KCProtocolVersion, uuidData)]; + NSString* version = @"o"; + NSData* octagonVersion = [version dataUsingEncoding:kCFStringEncodingUTF8]; - if (NULL == encode_initialmessage_version1(start, uuidData, KCProtocolVersion, error, initialMessage.mutableBytes, initialMessage.mutableBytes + initialMessage.length)) + initialMessage = [NSMutableData dataWithLength: sizeof_initialmessage_version2(start, kPiggyV1, uuidData, octagonVersion)]; + + if (NULL == encode_initialmessage_version2(start, uuidData, octagonVersion, error, initialMessage.mutableBytes, initialMessage.mutableBytes + initialMessage.length)){ + secerror("failed to create version 2 message"); + return nil; + } + } +#endif + } + else if(self.piggy_version == kPiggyV1){ + NSData* uuidData = [self createUUID]; + initialMessage = [NSMutableData dataWithLength: sizeof_initialmessage_version1(start, kPiggyV1, uuidData)]; + + if (NULL == encode_initialmessage_version1(start, uuidData, kPiggyV1, error, initialMessage.mutableBytes, initialMessage.mutableBytes + initialMessage.length)){ + secerror("failed to create version 1 message: %@", *error); return nil; + } } else{ initialMessage = [NSMutableData dataWithLength: sizeof_initialmessage(start)]; - if (NULL == encode_initialmessage(start, error, initialMessage.mutableBytes, initialMessage.mutableBytes + initialMessage.length)) + if (NULL == encode_initialmessage(start, error, initialMessage.mutableBytes, initialMessage.mutableBytes + initialMessage.length)){ return nil; + } } return initialMessage; @@ -94,6 +147,8 @@ static const uint64_t KCProtocolVersion = kPiggyV1; } self->_session = [KCAESGCMDuplexSession sessionAsSender:key context:self.dsid]; + self.session.pairingUUID = self.joiningConfiguration.pairingUUID; + self.session.piggybackingVersion = self.piggy_version; return self.session != nil; } @@ -102,6 +157,8 @@ static const uint64_t KCProtocolVersion = kPiggyV1; salt:(NSData*) salt secret: (NSString*) password error: (NSError**) error { + + secnotice("joining", "joining: KCJoiningRequestSecretSession copyResponseForChallenge called"); NSData* response = [self->_context copyResposeToChallenge:challenge password:password salt:salt @@ -132,6 +189,7 @@ static const uint64_t KCProtocolVersion = kPiggyV1; - (nullable NSData*) handleChallengeData: (NSData*) challengeData secret: (NSString*) password error: (NSError**) error { + secnotice("joining", "joining: KCJoiningRequestSecretSession handleChallengeData called"); NSData* challenge = nil; NSData* salt = nil; @@ -144,13 +202,37 @@ static const uint64_t KCProtocolVersion = kPiggyV1; - (nullable NSData*) handleChallenge: (KCJoiningMessage*) message secret: (NSString*) password error: (NSError**)error { + secnotice("joining", "joining: KCJoiningRequestSecretSession handleChallenge called"); // Parse the challenge message // Salt and Challenge packet if ([message type] != kChallenge) { KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected challenge!"); return nil; } +#if OCTAGON + //handle octagon data if it exists + if(KCJoiningOctagonPiggybackingEnabled()){ + self.piggy_version = [message secondData] ? kPiggyV2 : kPiggyV1; + // The session may or may not exist at this point. If it doesn't, the version will be set at object creation time. + self.session.piggybackingVersion = self.piggy_version; + + if(self.piggy_version == kPiggyV2){ + OTPairingMessage* pairingMessage = [[OTPairingMessage alloc]initWithData: [message secondData]]; + + if(pairingMessage.epoch.epoch){ + secnotice("octagon", "received epoch"); + self.epoch = pairingMessage.epoch.epoch; + } + else{ + secerror("octagon: acceptor did not send its epoch. discontinuing octagon protocol. downgrading to verison 1"); + self.piggy_version = kPiggyV1; + } + } + }else{ + self.piggy_version = kPiggyV1; + } +#endif return [self handleChallengeData:[message firstData] secret:password error:error]; } @@ -162,6 +244,7 @@ static const uint64_t KCProtocolVersion = kPiggyV1; } - (NSData*) handleVerification: (KCJoiningMessage*) message error: (NSError**) error { + secnotice("joining", "joining: KCJoiningRequestSecretSession handleVerification called"); if ([message type] == kError) { bool newCode = [[message firstData] length] == 0; NSString* nextSecret = [self.secretDelegate verificationFailed: newCode]; @@ -204,12 +287,8 @@ static const uint64_t KCProtocolVersion = kPiggyV1; return [NSData data]; } - - - -// [self.delegate processCircleJoinData:circleData error:error]; - - (NSData*) processMessage: (NSData*) incomingMessage error: (NSError**) error { + secnotice("joining", "joining: KCJoiningRequestSecretSession processMessage called"); NSData* result = nil; KCJoiningMessage* message = [KCJoiningMessage messageWithDER: incomingMessage error: error]; if (message == nil) return nil; @@ -258,13 +337,30 @@ static const uint64_t KCProtocolVersion = kPiggyV1; dsid: (uint64_t)dsid rng: (struct ccrng_state *)rng error: (NSError**)error { - + secnotice("joining", "joining: initWithSecretDelegate called"); self = [super init]; self->_secretDelegate = secretDelegate; self->_state = kExpectingB; self->_dsid = dsid; - + self->_defaults = [NSMutableDictionary dictionary]; + +#if OCTAGON + self->_piggy_version = KCJoiningOctagonPiggybackingEnabled() ? kPiggyV2 : kPiggyV1; + self->_otControl = [OTControl controlObject:true error:error]; + self->_joiningConfiguration = [[OTJoiningConfiguration alloc]initWithProtocolType:OTProtocolPiggybacking + uniqueDeviceID:@"requester-id" + uniqueClientID:@"requester-id" + containerName:nil + contextID:OTDefaultContext + epoch:0 + isInitiator:true]; +#else + self->_piggy_version = kPiggyV1; +#endif + + secnotice("joining", "joining: initWithSecretDelegate called, uuid=%@", self.joiningConfiguration.pairingUUID); + NSString* name = [NSString stringWithFormat: @"%llu", dsid]; self->_context = [[KCSRPClientContext alloc] initWithUser: name @@ -287,110 +383,17 @@ static const uint64_t KCProtocolVersion = kPiggyV1; - (NSString *)description { return [NSString stringWithFormat: @"", self, self.dsid, [self stateString], self.context]; } - -@end - -@interface KCJoiningRequestCircleSession () -@property (readonly) NSObject* circleDelegate; -@property (readonly) KCAESGCMDuplexSession* session; -@property (readwrite) KCJoiningRequestCircleSessionState state; -@end - -@implementation KCJoiningRequestCircleSession -- (nullable NSData*) encryptedPeerInfo: (NSError**) error { - // Get our peer info and send it along: - if (self->_session == nil) { - KCJoiningErrorCreate(kInternalError, error, @"Attempt to encrypt with no session"); - return nil; - } - - SOSPeerInfoRef us = [self.circleDelegate copyPeerInfoError:error]; - if (us == NULL) return nil; - CFErrorRef cfError = NULL; - NSData* piEncoded = (__bridge_transfer NSData*) SOSPeerInfoCopyEncodedData(us, NULL, &cfError); - if(us) { - CFRelease(us); - us = NULL; - } - - if (piEncoded == nil) { - if (error != nil) { - *error = (__bridge_transfer NSError*) cfError; - } - return nil; - } - - return [self->_session encrypt:piEncoded error:error]; -} - -- (nullable NSData*) initialMessage: (NSError**) error { - NSData* encryptedPi = [self encryptedPeerInfo:error]; - if (encryptedPi == nil) return nil; - - self->_state = kExpectingCircleBlob; - - return [[KCJoiningMessage messageWithType:kPeerInfo - data:encryptedPi - error:error] der]; - -} - -- (NSData*) handleCircleBlob: (KCJoiningMessage*) message error: (NSError**) error { - if ([message type] != kCircleBlob) { - KCJoiningErrorCreate(kUnexpectedMessage, error, @"Expected CircleBlob!"); - return nil; - } - - NSData* circleBlob = [self.session decryptAndVerify:message.firstData error:error]; - if (circleBlob == nil) return nil; - - if (![self.circleDelegate processCircleJoinData: circleBlob version:kPiggyV1 error:error]) - return nil; - - self->_state = kRequestCircleDone; - - return [NSData data]; // Success, an empty message. -} - -- (NSData*) processMessage: (NSData*) incomingMessage error: (NSError**) error { - NSData* result = nil; - KCJoiningMessage* message = [KCJoiningMessage messageWithDER: incomingMessage error: error]; - if (message == nil) return nil; - - switch(self.state) { - case kExpectingCircleBlob: - return [self handleCircleBlob:message error:error]; - case kRequestCircleDone: - KCJoiningErrorCreate(kUnexpectedMessage, error, @"Done, no messages expected."); - break; - } - - return result; -} - -- (bool) isDone { - return self.state = kRequestCircleDone; +#if OCTAGON +/* for test */ +-(void)setControlObject:(OTControl*)control +{ + self.otControl = control; } -+ (instancetype) sessionWithCircleDelegate: (NSObject*) circleDelegate - session: (KCAESGCMDuplexSession*) session - error: (NSError**) error { - return [[KCJoiningRequestCircleSession alloc] initWithCircleDelegate:circleDelegate - session:session - error:error]; -} - -- (instancetype) initWithCircleDelegate: (NSObject*) circleDelegate - session: (KCAESGCMDuplexSession*) session - error: (NSError**) error { - self = [super init]; - - self->_circleDelegate = circleDelegate; - self->_session = session; - self.state = kExpectingCircleBlob; - - return self; +- (void)setConfiguration:(OTJoiningConfiguration *)config +{ + self.joiningConfiguration = config; } +#endif @end - diff --git a/KeychainCircle/KCJoiningRequestSession+Internal.h b/KeychainCircle/KCJoiningRequestSession+Internal.h new file mode 100644 index 00000000..917529c3 --- /dev/null +++ b/KeychainCircle/KCJoiningRequestSession+Internal.h @@ -0,0 +1,44 @@ +/* + * 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 + +#ifndef KCJoiningRequestSession_Internal_h +#define KCJoiningRequestSession_Internal_h + +#import +#import "keychain/ot/OTControl.h" +#import "KCJoiningSession.h" + +@interface KCJoiningRequestSecretSession (Internal) +- (void)setControlObject:(OTControl*)control; +- (void)setConfiguration:(OTJoiningConfiguration *)config; +@end + +@interface KCJoiningRequestCircleSession (Internal) + +- (void)setControlObject:(OTControl*)control; +- (void)setJoiningConfigurationObject:(OTJoiningConfiguration *)config; +@end +#endif /* Header_h */ +#endif diff --git a/KeychainCircle/KCJoiningSession.h b/KeychainCircle/KCJoiningSession.h index 2eb96b16..f94064a0 100644 --- a/KeychainCircle/KCJoiningSession.h +++ b/KeychainCircle/KCJoiningSession.h @@ -9,6 +9,10 @@ #include #include + +bool KCJoiningOctagonPiggybackingEnabled(void); +bool KCSetJoiningOctagonPiggybackingEnabled(bool value); + NS_ASSUME_NONNULL_BEGIN @protocol KCJoiningRequestCircleDelegate @@ -88,7 +92,7 @@ NS_ASSUME_NONNULL_BEGIN @end - +@class OTControl; @interface KCJoiningRequestCircleSession : NSObject - (bool) isDone; @@ -102,7 +106,13 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype) initWithCircleDelegate: (NSObject*) circleDelegate session: (KCAESGCMDuplexSession*) session - error: (NSError**) error NS_DESIGNATED_INITIALIZER; + error: (NSError**) error; + + +- (instancetype)initWithCircleDelegate:(NSObject*) circleDelegate + session:(KCAESGCMDuplexSession*) session + otcontrol:(OTControl*)otcontrol + error:(NSError**) error NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; @end diff --git a/KeychainCircle/PairingChannel.h b/KeychainCircle/PairingChannel.h index a7c6870f..6f65dd6f 100644 --- a/KeychainCircle/PairingChannel.h +++ b/KeychainCircle/PairingChannel.h @@ -11,16 +11,35 @@ extern NSString *kKCPairingChannelErrorDomain; #define KCPairingErrorNoControlChannel 1 #define KCPairingErrorTooManySteps 2 #define KCPairingErrorAccountCredentialMissing 3 +#define KCPairingErrorOctagonMessageMissing 4 +#define KCPairingErrorTypeConfusion 5 +#define KCPairingErrorNoTrustAvailable 6 +#define KCPairingErrorNoStashedCredential 7 typedef void(^KCPairingChannelCompletion)(BOOL complete, NSData *packet, NSError *error); -@interface KCPairingChannelContext : NSObject +typedef NSString* KCPairingIntent_Type NS_STRING_ENUM; +extern KCPairingIntent_Type KCPairingIntent_Type_None; +extern KCPairingIntent_Type KCPairingIntent_Type_SilentRepair; +extern KCPairingIntent_Type KCPairingIntent_Type_UserDriven; + +@interface KCPairingChannelContext : NSObject @property (strong) NSString *model; @property (strong) NSString *modelVersion; @property (strong) NSString *modelClass; @property (strong) NSString *osVersion; +@property (strong) NSString *uniqueDeviceID; +@property (strong) NSString *uniqueClientID; +@property (strong) KCPairingIntent_Type intent; @end +/** + * Pairing channel provides the channel used in OOBE / D2D and HomePod/AppleTV (TapToFix) setup. + * + * The initiator is the device that wants to get into the circle, the acceptor is the device that is already in. + * The interface require the caller to hold a lock assertion over the whole transaction, both on the initiator and acceptor. +*/ + @interface KCPairingChannel : NSObject @property (assign,readonly) BOOL needInitialSync; @@ -28,13 +47,19 @@ typedef void(^KCPairingChannelCompletion)(BOOL complete, NSData *packet, NSError + (instancetype)pairingChannelInitiator:(KCPairingChannelContext *)peerVersionContext; + (instancetype)pairingChannelAcceptor:(KCPairingChannelContext *)peerVersionContext; -- (instancetype)initAsInitiator:(bool)initator version:(KCPairingChannelContext *)peerVersionContext; +- (instancetype)initAsInitiator:(bool)initiator version:(KCPairingChannelContext *)peerVersionContext; - (void)validateStart:(void(^)(bool result, NSError *error))complete; - (NSData *)exchangePacket:(NSData *)data complete:(bool *)complete error:(NSError **)error; +- (void)exchangePacket:(NSData *)inputCompressedData complete:(KCPairingChannelCompletion)complete; /* async version of above */ /* for tests cases only */ - (void)setXPCConnectionObject:(NSXPCConnection *)connection; +- (void)setControlObject:(id)control; +- (void)setConfiguration:(id)config; +- (void)setSOSMessageFailForTesting:(BOOL)value; +- (void)setOctagonMessageFailForTesting:(BOOL)value; + (bool)isSupportedPlatform; +- (void)setSessionSupportsOctagonForTesting:(bool)value; @end diff --git a/KeychainCircle/PairingChannel.m b/KeychainCircle/PairingChannel.m index b1160b75..e2d2b677 100644 --- a/KeychainCircle/PairingChannel.m +++ b/KeychainCircle/PairingChannel.m @@ -12,31 +12,114 @@ #import #import #import +#import "keychain/ot/OTManager.h" +#import "keychain/ot/OctagonControlServer.h" +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OctagonControlServer.h" +#import "keychain/ot/OTJoiningConfiguration.h" +#import "keychain/ot/proto/generated_source/OTPairingMessage.h" +#import "keychain/ot/proto/generated_source/OTSOSMessage.h" +#import "keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h" +#import "keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h" +#import "keychain/ot/proto/generated_source/OTPairingMessage.h" +#include #import -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #import #endif -#import "SecADWrapper.h" +#import "utilities/SecADWrapper.h" + +KCPairingIntent_Type KCPairingIntent_Type_None = @"none"; +KCPairingIntent_Type KCPairingIntent_Type_SilentRepair = @"repair"; +KCPairingIntent_Type KCPairingIntent_Type_UserDriven = @"userdriven"; typedef void(^KCPairingInternalCompletion)(BOOL complete, NSDictionary *outdict, NSError *error); typedef void(^KCNextState)(NSDictionary *indict, KCPairingInternalCompletion complete); NSString *kKCPairingChannelErrorDomain = @"com.apple.security.kcparingchannel"; +const char* pairingScope = "ot-pairing"; + +typedef void(^OTPairingInternalCompletion)(BOOL complete, NSData * _Nullable outData, NSError * _Nullable error); +typedef void(^OTNextState)(NSData *inData, OTPairingInternalCompletion complete); + @implementation KCPairingChannelContext + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (BOOL)isEqual:(id)object +{ + KCPairingChannelContext *other = (KCPairingChannelContext *)object; + + return [other isMemberOfClass:[self class]] + && ((!self->_model && !other->_model) || [self->_model isEqual:other->_model]) + && ((!self->_modelVersion && !other->_modelVersion) || [self->_modelVersion isEqual:other->_modelVersion]) + && ((!self->_modelClass && !other->_modelClass) || [self->_modelClass isEqual:other->_modelClass]) + && ((!self->_osVersion && !other->_osVersion) || [self->_osVersion isEqual:other->_osVersion]) + && ((!self->_uniqueDeviceID && !other->_uniqueDeviceID) || [self->_uniqueDeviceID isEqual:other->_uniqueDeviceID]) + && ((!self->_uniqueClientID && !other->_uniqueClientID) || [self->_uniqueClientID isEqual:other->_uniqueClientID]) + && ((!self->_intent && !other->_intent) || [self->_intent isEqual:other->_intent]) + ; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:_model forKey:@"model"]; + [coder encodeObject:_modelVersion forKey:@"modelVersion"]; + [coder encodeObject:_modelClass forKey:@"modelClass"]; + [coder encodeObject:_osVersion forKey:@"osVersion"]; + [coder encodeObject:_uniqueDeviceID forKey:@"uniqueDeviceID"]; + [coder encodeObject:_uniqueClientID forKey:@"uniqueClientID"]; + [coder encodeObject:_intent forKey:@"intent"]; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)decoder +{ + self = [super init]; + if (self) { + _model = [decoder decodeObjectOfClass:[NSString class] forKey:@"model"]; + _modelVersion = [decoder decodeObjectOfClass:[NSString class] forKey:@"modelVersion"]; + _modelClass = [decoder decodeObjectOfClass:[NSString class] forKey:@"modelClass"]; + _osVersion = [decoder decodeObjectOfClass:[NSString class] forKey:@"osVersion"]; + _uniqueDeviceID = [decoder decodeObjectOfClass:[NSString class] forKey:@"uniqueDeviceID"]; + _uniqueClientID = [decoder decodeObjectOfClass:[NSString class] forKey:@"uniqueClientID"]; + _intent = [decoder decodeObjectOfClass:[NSString class] forKey:@"intent"]; + + /* validate intent if we have one */ + if (_intent != NULL && + !([_intent isEqualToString:KCPairingIntent_Type_None] || + [_intent isEqualToString:KCPairingIntent_Type_SilentRepair] || + [_intent isEqualToString:KCPairingIntent_Type_UserDriven])) + { + return nil; + } + } + return self; +} + @end @interface KCPairingChannel () @property (assign) KCPairingChannelContext *peerVersionContext; -@property (assign) bool initator; +@property (assign) bool initiator; @property (assign) unsigned counter; @property (assign) bool acceptorWillSendInitialSyncCredentials; @property (strong) NSXPCConnection *connection; - +@property (strong) OTControl *otControl; +@property (strong) NSString* contextID; +@property (strong) OTNextState nextOctagonState; @property (strong) KCNextState nextState; +@property (nonatomic, strong) OTJoiningConfiguration* joiningConfiguration; +@property (nonatomic) bool testFailSOS; +@property (nonatomic) bool testFailOctagon; + +@property (assign) bool sessionSupportsSOS; +@property (assign) bool sessionSupportsOctagon; @end @@ -52,18 +135,20 @@ NSString *kKCPairingChannelErrorDomain = @"com.apple.security.kcparingchannel"; return [[KCPairingChannel alloc] initAsInitiator:false version:peerVersionContext]; } -- (instancetype)initAsInitiator:(bool)initator version:(KCPairingChannelContext *)peerVersionContext +- (instancetype)initAsInitiator:(bool)initiator version:(KCPairingChannelContext *)peerVersionContext { - if (![KCPairingChannel isSupportedPlatform]) + if (![KCPairingChannel isSupportedPlatform]) { + secerror("platform not supported for pairing"); return NULL; + } if (self = [super init]) { __weak typeof(self) weakSelf = self; - _initator = initator; + _initiator = initiator; _peerVersionContext = peerVersionContext; - if (_initator) { + if (_initiator) { _nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ - [weakSelf initatorFirstPacket:nsdata complete:kscomplete]; + [weakSelf initiatorFirstPacket:nsdata complete:kscomplete]; }; } else { _nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ @@ -71,21 +156,30 @@ NSString *kKCPairingChannelErrorDomain = @"com.apple.security.kcparingchannel"; }; } _needInitialSync = true; + _testFailSOS = false; + _contextID = OTDefaultContext; + + /* only apply to acceptor right now */ + _sessionSupportsSOS = OctagonPlatformSupportsSOS(); + _sessionSupportsOctagon = OctagonIsEnabled(); + NSError *localError = nil; + _otControl = [OTControl controlObject:true error:&localError]; + if(localError){ + secerror("could not stand up otcontrol connection"); + } + _joiningConfiguration = [[OTJoiningConfiguration alloc]initWithProtocolType:OTProtocolPairing + uniqueDeviceID:peerVersionContext.uniqueDeviceID + uniqueClientID:peerVersionContext.uniqueClientID + containerName:nil + contextID:OTDefaultContext + epoch:0 + isInitiator:initiator]; } return self; } + (bool)isSupportedPlatform { - CFStringRef deviceClass = NULL; -#if TARGET_OS_EMBEDDED && !RC_HIDE_HARDWARE_WINTER_2017_IOS - deviceClass = MGCopyAnswer(kMGQDeviceClass, NULL); - if (deviceClass && CFEqual(deviceClass, kMGDeviceClassAudioAccessory)){ - CFReleaseNull(deviceClass); - return false; - } -#endif - CFReleaseNull(deviceClass); return true; } @@ -161,117 +255,273 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; //MARK: - Initiator -- (void)initatorFirstPacket:(NSDictionary * __unused)indata complete:(KCPairingInternalCompletion)complete +- (void) attemptSosUpgrade { - secnotice("pairing", "initator packet 1"); + [self.otControl attemptSosUpgrade:nil context:self.contextID reply:^(NSError *error) { + if(error){ + secerror("pairing: failed to upgrade initiator into Octagon: %@", error); + } + }]; +} - if (![self ensureControlChannel]) { +- (void)initiatorFirstPacket:(NSDictionary * __unused)indata complete:(KCPairingInternalCompletion)complete +{ + secnotice("pairing", "initiator packet 1"); + + if (OctagonPlatformSupportsSOS() && ![self ensureControlChannel]) { [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorNoControlChannel userInfo:NULL] complete:complete]; return; } - __weak typeof(self) weakSelf = self; - self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ - [weakSelf initatorSecondPacket:nsdata complete:kscomplete]; - }; - complete(false, @{ @"d" : @YES }, NULL); + if(OctagonIsEnabled() && self.sessionSupportsOctagon && !self.testFailOctagon) { + __weak typeof(self) weakSelf = self; + self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf initiatorSecondPacket:nsdata complete:kscomplete]; + }; + complete(false, @{ @"d" : @YES, @"o" : @{@"v" : @"O"} }, NULL); + } else if (OctagonIsEnabled() && self.testFailOctagon) { + complete(true, nil, NULL); + return; + } else { + __weak typeof(self) weakSelf = self; + self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf initiatorSecondPacket:nsdata complete:kscomplete]; + }; + complete(false, @{ @"d" : @YES }, NULL); + } } -- (void)initatorSecondPacket:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete +- (void)initiatorSecondPacket:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete { - secnotice("pairing", "initator packet 2"); + secnotice("pairing", "initiator packet 2"); + + NSData *octagonData = indata[@"o"]; + + if(octagonData == nil) { + secnotice("pairing", "acceptor didn't send a octagon packet, so skipping all octagon flows"); + self.sessionSupportsOctagon = false; + } NSData *credential = indata[@"c"]; - if (credential == NULL) { - secnotice("pairing", "no credential"); - [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorAccountCredentialMissing userInfo:NULL] complete:complete]; - return; + if (![credential isKindOfClass:[NSData class]]) { + if(!OctagonIsEnabled() && OctagonPlatformSupportsSOS()) { + secnotice("pairing", "no credential"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorAccountCredentialMissing userInfo:NULL] complete:complete]; + return; + } } - if (indata[@"d"]) { + if (OctagonPlatformSupportsSOS() && indata[@"d"]) { secnotice("pairing", "acceptor will send send initial credentials"); self.acceptorWillSendInitialSyncCredentials = true; } - - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - complete(true, NULL, error); - }] stashAccountCredential:credential complete:^(bool success, NSError *error) { - [self setNextStateError:NULL complete:NULL]; - if (!success) { - secnotice("pairing", "failed stash credentials: %@", error); + if(OctagonPlatformSupportsSOS()) { + [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { complete(true, NULL, error); - return; - } - [self initatorCompleteSecondPacket:complete]; - }]; + }] stashAccountCredential:credential complete:^(bool success, NSError *error) { + [self setNextStateError:NULL complete:NULL]; + if (!success || self.testFailSOS) { + secnotice("pairing", "failed stash credentials: %@", error); + if(!OctagonIsEnabled() || !self.sessionSupportsOctagon){ + complete(true, NULL, error); + return; + } else { + [self initiatorCompleteSecondPacketOctagon:indata application:nil complete:complete]; + } + } else{ + [self initiatorCompleteSecondPacketWithSOS:indata complete:complete]; + } + }]; + } else if(OctagonIsEnabled() && self.sessionSupportsOctagon) { + [self initiatorCompleteSecondPacketOctagon:indata application:nil complete:complete]; + return; + } } -- (void)initatorCompleteSecondPacket:(KCPairingInternalCompletion)complete + +- (void)initiatorCompleteSecondPacketWithSOS:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete { + secnotice("pairing", "initiator complete second packet 2"); + __weak typeof(self) weakSelf = self; - secnotice("pairing", "initator complete second packet 2"); [self setNextStateError:NULL complete:NULL]; [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { complete(true, NULL, error); }] myPeerInfo:^(NSData *application, NSError *error) { - if (application) { - complete(false, @{ @"p" : application }, error); + if (application && !self.testFailSOS) { + if(OctagonIsEnabled() && self.sessionSupportsOctagon) { + [self initiatorCompleteSecondPacketOctagon:indata application:application complete:complete]; + } else{ + complete(false, @{ @"p" : application }, error); + weakSelf.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf initiatorThirdPacket:nsdata complete:kscomplete]; + }; + } + } else { + if(OctagonIsEnabled() && self.sessionSupportsOctagon){ + [self initiatorCompleteSecondPacketOctagon:indata application:application complete:complete]; + } else { + secnotice("pairing", "failed getting application: %@", error); + complete(true, @{}, error); + } + } + }]; +} - weakSelf.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ - [weakSelf initatorThirdPacket:nsdata complete:kscomplete]; - }; +- (void)initiatorCompleteSecondPacketOctagon:(NSDictionary*)indata application:(NSData*)application complete:(KCPairingInternalCompletion)complete +{ + secnotice("pairing", "initiator complete second packet 2 with octagon"); + + __weak typeof(self) weakSelf = self; + NSData *octagonData = indata[@"o"]; + if(![octagonData isKindOfClass:[NSData class]]) { + secnotice(pairingScope, "initiatorCompleteSecondPacketOctagon octagonData missing or wrong class"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } + + //handle epoch and create identity message + [self.otControl rpcPrepareIdentityAsApplicantWithConfiguration:self.joiningConfiguration + reply:^(NSString *peerID, + NSData *permanentInfo, + NSData *permanentInfoSig, + NSData *stableInfo, + NSData *stableInfoSig, + NSError *error) { + if (error || self.testFailOctagon) { + secerror("ot-pairing: failed to create %d message: %@", self.counter, error); + complete(true, nil, error); + return; } else { - secnotice("pairing", "failed getting application: %@", error); - complete(true, @{}, error); + OTPairingMessage *octagonMessage = [[OTPairingMessage alloc]init]; + OTApplicantToSponsorRound2M1 *prepare = [[OTApplicantToSponsorRound2M1 alloc] init]; + prepare.peerID = peerID; + prepare.permanentInfo = permanentInfo; + prepare.permanentInfoSig = permanentInfoSig; + prepare.stableInfo = stableInfo; + prepare.stableInfoSig = stableInfoSig; + octagonMessage.prepare = prepare; + if(application){ + secnotice(pairingScope, "initiatorCompleteSecondPacketOctagon returning octagon and sos data"); + complete(false, @{ @"p" : application, @"o" : octagonMessage.data }, nil); + } else { + secnotice(pairingScope, "initiatorCompleteSecondPacketOctagon returning octagon data"); + complete(false, @{ @"o" : octagonMessage.data }, nil); + } + weakSelf.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf initiatorThirdPacket:nsdata complete:kscomplete]; + }; } }]; } -- (void)initatorThirdPacket:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete +- (void)initiatorThirdPacket:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete { __weak typeof(self) weakSelf = self; - secnotice("pairing", "initator packet 3"); + secnotice("pairing", "initiator packet 3"); [self setNextStateError:NULL complete:NULL]; NSData *circleBlob = indata[@"b"]; if (circleBlob == NULL) { - complete(true, NULL, NULL); - return; - } - - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - complete(true, NULL, error); - }] joinCircleWithBlob:circleBlob version:kPiggyV1 complete:^(bool success, NSError *error){ - typeof(self) strongSelf = weakSelf; - secnotice("pairing", "initator cirle join complete, more data: %s: %@", - strongSelf->_acceptorWillSendInitialSyncCredentials ? "yes" : "no", error); - - if (strongSelf->_acceptorWillSendInitialSyncCredentials) { - strongSelf.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ - [weakSelf initatorFourthPacket:nsdata complete:kscomplete]; - }; - - complete(false, @{}, NULL); - } else { + if(!OctagonIsEnabled() && OctagonPlatformSupportsSOS()) { + secnotice("pairing", "no sos circle"); complete(true, NULL, NULL); + return; } - }]; + } else if(OctagonPlatformSupportsSOS()) { + if(![circleBlob isKindOfClass:[NSData class]]) { + complete(true, NULL, [NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorTypeConfusion userInfo:NULL]); + return; + } + + [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + complete(true, NULL, error); + }] joinCircleWithBlob:circleBlob version:kPiggyV1 complete:^(bool success, NSError *error){ + if(error || self.testFailSOS) { + if(OctagonIsEnabled() && self.sessionSupportsOctagon) { + secnotice("pairing", "failed to join circle with blob, continuing to handle octagon protocol"); + } else { + secnotice("pairing", "failed to join circle with blob"); + complete(true, NULL, NULL); + } + } else{ + if(OctagonIsEnabled() && self.sessionSupportsOctagon) { + secnotice("pairing","initiator circle join complete"); + } else { + //kick off SOS ugprade + if(OctagonIsEnabled() && !self.sessionSupportsOctagon) { + [self attemptSosUpgrade]; + } + typeof(self) strongSelf = weakSelf; + secnotice("pairing", "initiator circle join complete, more data: %s: %@", + strongSelf->_acceptorWillSendInitialSyncCredentials ? "yes" : "no", error); + + if (strongSelf->_acceptorWillSendInitialSyncCredentials) { + strongSelf.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf initiatorFourthPacket:nsdata complete:kscomplete]; + }; + + complete(false, @{}, NULL); + } else { + complete(true, NULL, NULL); + } + } + } + }]; + } + if(OctagonIsEnabled() && self.sessionSupportsOctagon){ + NSData *octagonData = indata[@"o"]; + if(![octagonData isKindOfClass:[NSData class]]) { + secnotice(pairingScope, "initiatorThirdPacket octagonData missing or wrong class"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } + OTPairingMessage *pairingMessage = [[OTPairingMessage alloc] initWithData:octagonData]; + if(!pairingMessage.hasVoucher){ + secnotice(pairingScope, "initiatorThirdPacket pairingMessage has no voucher"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } + OTSponsorToApplicantRound2M2 *voucher = pairingMessage.voucher; + + //handle voucher and join octagon + [self.otControl rpcJoinWithConfiguration:self.joiningConfiguration vouchData:voucher.voucher vouchSig:voucher.voucherSignature preapprovedKeys:voucher.preapprovedKeys reply:^(NSError *error) { + if (error || self.testFailOctagon) { + secerror("ot-pairing: failed to create %d message: %@", self.counter, error); + complete(true, NULL, error); + return; + }else{ + secnotice(pairingScope, "initiatorThirdPacket successfully joined Octagon"); + typeof(self) strongSelf = weakSelf; + if(OctagonPlatformSupportsSOS() && strongSelf->_acceptorWillSendInitialSyncCredentials == true) { + strongSelf.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf initiatorFourthPacket:nsdata complete:kscomplete]; + }; + complete(false, @{}, nil); + + } else { + complete(true, nil, nil); + + } + } + }]; + } } -- (void)initatorFourthPacket:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete +- (void)initiatorFourthPacket:(NSDictionary *)indata complete:(KCPairingInternalCompletion)complete { - secnotice("pairing", "initator packet 4"); + secnotice("pairing", "initiator packet 4"); [self setNextStateError:NULL complete:NULL]; NSArray *items = indata[@"d"]; if (![items isKindOfClass:[NSArray class]]) { - secnotice("pairing", "initator no items to import"); + secnotice("pairing", "initiator no items to import"); complete(true, NULL, NULL); return; } @@ -281,10 +531,10 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { complete(true, NULL, error); }] importInitialSyncCredentials:items complete:^(bool success, NSError *error) { - secnotice("pairing", "initator importInitialSyncCredentials: %s: %@", success ? "yes" : "no", error); + secnotice("pairing", "initiator importInitialSyncCredentials: %s: %@", success ? "yes" : "no", error); if (success) self->_needInitialSync = false; - complete(true, NULL, NULL); + complete(true, nil, nil); }]; } @@ -297,42 +547,104 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; __weak typeof(self) weakSelf = self; secnotice("pairing", "acceptor packet 1"); - [self setNextStateError:NULL complete:NULL]; - if (![self ensureControlChannel]) { + if (self.sessionSupportsSOS && ![self ensureControlChannel]) { + secnotice("pairing", "unable to establish a channel to sos control"); [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorNoControlChannel userInfo:NULL] complete:complete]; return; } - if (indata[@"d"]) { + if (self.sessionSupportsSOS && indata[@"d"]) { secnotice("pairing", "acceptor initialSyncCredentials requested"); self.acceptorWillSendInitialSyncCredentials = true; } - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - complete(true, NULL, error); - }] validatedStashedAccountCredential:^(NSData *credential, NSError *error) { - if (!credential) { - secnotice("pairing", "acceptor doesn't have a stashed credential: %@", error); - [self setNextStateError:error complete:complete]; - return; - } + if (indata[@"o"] == nil) { + secnotice("pairing", "initiator didn't send a octagon packet, so skipping all octagon flows"); + self.sessionSupportsOctagon = false; + } + // XXX Before we go here we should check if we are trusted or not, if we are not, there is no point proposing octagon - self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ - [weakSelf acceptorSecondPacket:nsdata complete:kscomplete]; - }; + NSMutableDictionary *reply = [NSMutableDictionary dictionary]; - NSMutableDictionary *reply = [@{ - @"c" : credential, - } mutableCopy]; + if(self.sessionSupportsSOS) { + [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + complete(true, NULL, error); + }] validatedStashedAccountCredential:^(NSData *credential, NSError *error) { + secnotice("pairing", "acceptor validatedStashedAccountCredential: %@ (%@)", credential != NULL ? @"yes" : @"no", error); + if(credential){ + reply[@"c"] = credential; - if (self.acceptorWillSendInitialSyncCredentials) { - reply[@"d"] = @YES; - }; + if (self.acceptorWillSendInitialSyncCredentials) { + reply[@"d"] = @YES; + }; + if(self.sessionSupportsOctagon) { + [self acceptorFirstOctagonPacket:indata reply:reply complete:complete]; + } else { + self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf acceptorSecondPacket:nsdata complete:kscomplete]; + }; + secnotice("pairing", "acceptor reply to packet 1"); + complete(false, reply, NULL); + } + } + else if ((!credential && !self.sessionSupportsOctagon) || self.testFailSOS) { + secnotice("pairing", "acceptor doesn't have a stashed credential: %@", error); + NSError *noStashCredentail = [NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorNoStashedCredential userInfo:NULL]; + [self setNextStateError:noStashCredentail complete:complete]; + return; + } + else if(self.sessionSupportsOctagon) { + [self acceptorFirstOctagonPacket:indata reply:reply complete:complete]; + } + }]; + } else if(self.sessionSupportsOctagon){ + [self acceptorFirstOctagonPacket:indata reply:reply complete:complete]; + } else { + secnotice("pairing", "acceptor neither of octagon nor SOS"); + NSError *notSupported = [NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorNoTrustAvailable userInfo:NULL]; + [self setNextStateError:notSupported complete:complete]; + } +} +- (void)acceptorFirstOctagonPacket:(NSDictionary *)indata reply:(NSMutableDictionary*)reply complete:(KCPairingInternalCompletion)complete +{ + __weak typeof(self) weakSelf = self; + NSDictionary *octagonData = indata[@"o"]; + + if(![octagonData isKindOfClass:[NSDictionary class]]) { + secnotice(pairingScope, "acceptorFirstOctagonPacket octagon data missing"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } + + NSDictionary *unpackedMessage = octagonData; + + if(![unpackedMessage[@"v"] isEqualToString:@"O"]){ + secnotice(pairingScope, "acceptorFirstOctagonPacket 'v' contents wrong"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } - secnotice("pairing", "acceptor reply to packet 1"); - complete(false, reply, NULL); + //handle epoch request and fetch epoch + [self.otControl rpcEpochWithConfiguration:self.joiningConfiguration reply:^(uint64_t epoch, NSError * _Nullable error) { + secnotice("pairing", "acceptor rpcEpochWithConfiguration: %ld (%@)", (long)epoch, error); + if(error || self.testFailOctagon){ + secerror("error acceptor handling packet %d", self.counter); + complete(true, nil, error); + }else{ + secnotice(pairingScope, "acceptor handled packet %d", self.counter); + self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf acceptorSecondPacket:nsdata complete:kscomplete]; + }; + OTPairingMessage *response = [[OTPairingMessage alloc] init]; + response.epoch = [[OTSponsorToApplicantRound1M2 alloc] init]; + response.epoch.epoch = epoch; + reply[@"o"] = response.data; + + secnotice("pairing", "acceptor reply to packet 1"); + complete(false, reply, error); + } }]; } @@ -343,32 +655,96 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; [self setNextStateError:NULL complete:NULL]; secnotice("pairing", "acceptor packet 2"); + __block NSMutableDictionary *reply = [NSMutableDictionary dictionary]; - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - complete(true, NULL, error); - }] circleJoiningBlob:indata[@"p"] complete:^(NSData *blob, NSError *error){ - NSMutableDictionary *reply = [NSMutableDictionary dictionary]; + NSData *peerJoinBlob = indata[@"p"]; + + if(self.sessionSupportsSOS && [peerJoinBlob isKindOfClass:[NSData class]]) { + [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + complete(true, NULL, error); + }] circleJoiningBlob:peerJoinBlob complete:^(NSData *blob, NSError *error){ + + if (blob) { + secnotice("pairing", "acceptor pairing complete (will send: %s): %@", + self.acceptorWillSendInitialSyncCredentials ? "YES" : "NO", + error); + + reply[@"b"] = blob; + } + if(self.sessionSupportsOctagon) { + [self acceptorSecondOctagonPacket:indata reply:reply complete:complete]; + } else { + secnotice("pairing", "posting kSOSCCCircleOctagonKeysChangedNotification"); + notify_post(kSOSCCCircleOctagonKeysChangedNotification); + if (self.acceptorWillSendInitialSyncCredentials) { + self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ + [weakSelf acceptorThirdPacket:nsdata complete:kscomplete]; + }; + + complete(false, reply, NULL); + } else { + complete(true, reply, NULL); + } + secnotice("pairing", "acceptor reply to packet 2"); + } + }]; + } else if(self.sessionSupportsOctagon){ + [self acceptorSecondOctagonPacket:indata reply:reply complete:complete]; + } +} - if (blob) { - secnotice("pairing", "acceptor pairing complete (will send: %s): %@", - self.acceptorWillSendInitialSyncCredentials ? "YES" : "NO", - error); +- (void)acceptorSecondOctagonPacket:(NSDictionary*)indata reply:(NSMutableDictionary*)reply complete:(KCPairingInternalCompletion)complete +{ + __weak typeof(self) weakSelf = self; + NSData *octagonData = indata[@"o"]; + + if(![octagonData isKindOfClass:[NSData class]]) { + secnotice(pairingScope, "acceptorSecondOctagonPacket octagon data missing"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } - reply[@"b"] = blob; + OTPairingMessage *pairingMessage = [[OTPairingMessage alloc] initWithData:octagonData]; + if(!pairingMessage.hasPrepare){ + secerror("ot-pairing: acceptorSecondOctagonPacket: no octagon message"); + [self setNextStateError:[NSError errorWithDomain:kKCPairingChannelErrorDomain code:KCPairingErrorOctagonMessageMissing userInfo:NULL] complete:complete]; + return; + } + OTApplicantToSponsorRound2M1 *prepare = pairingMessage.prepare; + + //handle identity and fetch voucher + [self.otControl rpcVoucherWithConfiguration:self.joiningConfiguration + peerID:prepare.peerID + permanentInfo:prepare.permanentInfo + permanentInfoSig:prepare.permanentInfoSig + stableInfo:prepare.stableInfo + stableInfoSig:prepare.stableInfoSig + reply:^(NSData *voucher, + NSData *voucherSig, + NSError *error) { + if(error || self.testFailOctagon){ + secerror("error acceptor handling octagon packet %d", self.counter); + complete(true, nil, error); + return; + } else { + bool finished = true; - if (self.acceptorWillSendInitialSyncCredentials) { + secnotice(pairingScope, "acceptor handled octagon packet %d", self.counter); + if (OctagonPlatformSupportsSOS() && self.acceptorWillSendInitialSyncCredentials) { self.nextState = ^(NSDictionary *nsdata, KCPairingInternalCompletion kscomplete){ [weakSelf acceptorThirdPacket:nsdata complete:kscomplete]; }; - - complete(false, reply, NULL); - } else { - complete(true, reply, NULL); + finished = false; } - } else { - complete(true, reply, error); + OTPairingMessage *response = [[OTPairingMessage alloc] init]; + response.voucher = [[OTSponsorToApplicantRound2M2 alloc] init]; + response.voucher.voucher = voucher; + response.voucher.voucherSignature = voucherSig; + reply[@"o"] = response.data; + + secnotice("pairing", "acceptor reply to packet 2"); + complete(finished ? true : false, reply, error); } - secnotice("pairing", "acceptor reply to packet 2"); }]; } @@ -406,9 +782,9 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; NSXPCInterface *interface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0]; - if (self.connection == NULL) + if (self.connection == NULL){ return false; - + } self.connection.remoteObjectInterface = interface; [self.connection resume]; @@ -418,7 +794,7 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; - (void)validateStart:(void(^)(bool result, NSError *error))complete { - if (!self.initator) { + if (!self.initiator) { [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { complete(false, error); }] stashedCredentialPublicKey:^(NSData *publicKey, NSError *error) { @@ -434,6 +810,8 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; - (void)exchangePacket:(NSData *)inputCompressedData complete:(KCPairingChannelCompletion)complete { NSDictionary *indict = NULL; + secnotice("pairing", "Exchange packet: %u", self.counter); + self.counter++; if (inputCompressedData) { @@ -466,11 +844,12 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; if (compressedData) { NSString *key = [NSString stringWithFormat:@"com.apple.ckks.pairing.packet-size.%s.%u", - self->_initator ? "initator" : "acceptor", self->_counter]; + self->_initiator ? "initiator" : "acceptor", self->_counter]; SecADClientPushValueForDistributionKey((__bridge CFStringRef)key, [compressedData length]); secnotice("pairing", "pairing packet size %lu", (unsigned long)[compressedData length]); } } + secnotice("pairing", "Exchange packet complete data: %@: %@", outdata ? @"YES" : @"NO", error); complete(completed, compressedData, error); }); } @@ -481,7 +860,6 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; __block NSData *rData = NULL; __block NSError* processingError; [self exchangePacket:data complete:^(BOOL cComplete, NSData *cData, NSError *cError) { - self.counter++; *complete = cComplete; rData = cData; processingError = cError; @@ -498,5 +876,28 @@ const compression_algorithm pairingCompression = COMPRESSION_LZFSE; self.connection = connection; } +- (void)setControlObject:(OTControl *)control +{ + self.otControl = control; +} + +- (void)setConfiguration:(OTJoiningConfiguration *)config +{ + self.joiningConfiguration = config; +} + +- (void)setSOSMessageFailForTesting:(BOOL)value +{ + self.testFailSOS = value; +} +- (void)setOctagonMessageFailForTesting:(BOOL)value +{ + self.testFailOctagon = value; +} + +- (void)setSessionSupportsOctagonForTesting:(bool)value +{ + self.sessionSupportsOctagon = value; +} @end diff --git a/KeychainCircle/Tests/FakeSOSControl.h b/KeychainCircle/Tests/FakeSOSControl.h new file mode 100644 index 00000000..ff3f9992 --- /dev/null +++ b/KeychainCircle/Tests/FakeSOSControl.h @@ -0,0 +1,43 @@ +#ifndef FakeSOSControl_h +#define FakeSOSControl_h + +#import +#import +#import +#import +#import "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#import +#import "utilities/SecCFWrappers.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FCPairingFakeSOSControl : NSObject +@property (assign) SecKeyRef accountPrivateKey; +@property (assign) SecKeyRef accountPublicKey; +@property (assign) SecKeyRef deviceKey; +@property (assign) SecKeyRef octagonSigningKey; +@property (assign) SecKeyRef octagonEncryptionKey; +@property (assign) SOSCircleRef circle; +@property (assign) SOSFullPeerInfoRef fullPeerInfo; +@property (assign) bool application; +- (instancetype)initWithRandomAccountKey:(bool)randomAccountKey circle:(SOSCircleRef)circle; +- (void)dealloc; +- (SOSPeerInfoRef)peerInfo; +- (void)signApplicationIfNeeded; +@end + +@interface FakeNSXPCConnection : NSObject +- (instancetype) initWithControl:(id)control; +- (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler; +@end + +@interface FakeNSXPCConnection () +@property id control; +@end + +NS_ASSUME_NONNULL_END +#endif /* FakeSOSControl_h */ + + diff --git a/KeychainCircle/Tests/FakeSOSControl.m b/KeychainCircle/Tests/FakeSOSControl.m new file mode 100644 index 00000000..e0a2c500 --- /dev/null +++ b/KeychainCircle/Tests/FakeSOSControl.m @@ -0,0 +1,331 @@ + +#import "FakeSOSControl.h" + +@implementation FakeNSXPCConnection +- (instancetype) initWithControl:(id)control +{ + self = [super init]; + if (self) { + _control = control; + } + return self; +} +- (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler +{ + (void)failureHandler; + return _control; +} +@end + +@implementation FCPairingFakeSOSControl + +- (instancetype)initWithRandomAccountKey:(bool)randomAccountKey circle:(SOSCircleRef)circle +{ + if ((self = [super init])) { + SecKeyRef publicKey = NULL; + NSDictionary* parameters = @{ + (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC, + (__bridge NSString*)kSecAttrKeySizeInBits: @(256), + (__bridge NSString*)kSecUseDataProtectionKeychain : @YES, + (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, + (__bridge id)kSecPrivateKeyAttrs : @{ + (__bridge NSString*)kSecAttrLabel : @"delete me test case - private", + (__bridge NSString*)kSecAttrIsPermanent : @YES, + (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, + }, + (__bridge id)kSecPublicKeyAttrs : @{ + (__bridge NSString*)kSecAttrLabel : @"delete me test case - public", + (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, + } + }; + if(SecKeyGeneratePair((__bridge CFDictionaryRef)parameters, &publicKey, &_deviceKey) != 0) { + NSLog(@"failed to create device key"); + return nil; + } + CFReleaseNull(publicKey); + + NSMutableDictionary* octagonParameters = [parameters mutableCopy]; + octagonParameters[(__bridge NSString*)kSecAttrKeySizeInBits] = @(384); + if(SecKeyGeneratePair((__bridge CFDictionaryRef)octagonParameters, &publicKey, &_octagonSigningKey) != 0) { + NSLog(@"failed to create octagon signing key"); + return nil; + } + CFReleaseNull(publicKey); + + if(SecKeyGeneratePair((__bridge CFDictionaryRef)octagonParameters, &publicKey, &_octagonEncryptionKey) != 0) { + NSLog(@"failed to create octagon signing key"); + return nil; + } + CFReleaseNull(publicKey); + + + _circle = (SOSCircleRef)CFRetain(circle); + + CFErrorRef error = NULL; + + CFDictionaryRef gestalt = (__bridge CFDictionaryRef)@{ + @"ComputerName" : @"name", + }; + + _fullPeerInfo = SOSFullPeerInfoCreate(NULL, gestalt, NULL, _deviceKey, _octagonSigningKey, _octagonEncryptionKey, &error); + CFReleaseNull(error); + + if (randomAccountKey) { + + NSDictionary* accountParams = @{ + (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC, + (__bridge NSString*)kSecAttrKeySizeInBits: @(256), + (__bridge NSString*)kSecUseDataProtectionKeychain : @YES, + (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, + }; + + if(SecKeyGeneratePair((__bridge CFDictionaryRef)accountParams, &publicKey, &_accountPrivateKey) != 0) { + NSLog(@"failed to create account signing key"); + return nil; + } + CFReleaseNull(publicKey); + + _accountPublicKey = SecKeyCopyPublicKey(_accountPrivateKey); + + [self signApplicationIfNeeded]; + } + } + return self; +} + +- (void)dealloc +{ + if (_accountPrivateKey) { + SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_accountPrivateKey }); + CFReleaseNull(_accountPrivateKey); + } + if (_deviceKey) { + SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_deviceKey }); + CFReleaseNull(_deviceKey); + } + if (_octagonSigningKey) { + SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_octagonSigningKey }); + CFReleaseNull(_octagonSigningKey); + } + if (_octagonEncryptionKey) { + SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_octagonEncryptionKey }); + CFReleaseNull(_octagonEncryptionKey); + } + CFReleaseNull(_circle); + CFReleaseNull(_fullPeerInfo); +} + +- (SOSPeerInfoRef)peerInfo +{ + return SOSFullPeerInfoGetPeerInfo(_fullPeerInfo); +} + +- (void)signApplicationIfNeeded +{ + CFErrorRef error = NULL; + + _application = SOSFullPeerInfoPromoteToApplication(_fullPeerInfo, _accountPrivateKey, &error); + if (!_application) + abort(); +} + +- (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete +{ + complete(@[], NULL); +} + +- (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete +{ + complete(true, NULL); +} + +- (void)triggerSync:(NSArray *)peers complete:(void(^)(bool success, NSError *))complete +{ + complete(true, NULL); +} + +//MARK - FCPairingFakeSOSControl SOSControlProtocol + +- (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete +{ + complete(false, NULL, NULL); +} + +- (void)performanceCounters:(void(^)(NSDictionary *))complete +{ + complete(@{}); +} +- (void)kvsPerformanceCounters:(void(^)(NSDictionary *))complete +{ + complete(@{}); +} + +- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))complete +{ + complete(@{}); +} +- (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))complete +{ + NSData *publicKey = NULL; + NSError *error = NULL; + if (self.accountPrivateKey) { + publicKey = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(self.accountPrivateKey)); + } else { + error = [NSError errorWithDomain:@"FCPairingFakeSOSControl" code:2 userInfo:NULL]; + } + complete(publicKey, error); +} + +- (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))complete +{ + complete(self.accountPrivateKey != NULL, NULL); +} + +- (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete +{ + NSData *key = NULL; + CFErrorRef error = NULL; + if (self.accountPrivateKey) { + key = CFBridgingRelease(SecKeyCopyExternalRepresentation(self.accountPrivateKey, &error)); + } else { + error = (CFErrorRef)CFBridgingRetain([NSError errorWithDomain:@"FCPairingFakeSOSControl" code:1 userInfo:NULL]); + } + complete(key, (__bridge NSError *)error); + CFReleaseNull(error); +} + +- (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete +{ + SecKeyRef accountPrivateKey = NULL; + CFErrorRef error = NULL; + NSDictionary *attributes = @{ + (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate, + (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC, + }; + + accountPrivateKey = SecKeyCreateWithData((__bridge CFDataRef)credential, (__bridge CFDictionaryRef)attributes, &error); + if (accountPrivateKey == NULL) { + complete(false, (__bridge NSError *)error); + CFReleaseNull(error); + return; + } + + _accountPrivateKey = accountPrivateKey; + _accountPublicKey = SecKeyCopyPublicKey(_accountPrivateKey); + + [self signApplicationIfNeeded]; + + complete(true, NULL); +} + +- (void)myPeerInfo:(void(^)(NSData *application, NSError *error))complete +{ + CFErrorRef error = NULL; + + [self signApplicationIfNeeded]; + + NSData *application = CFBridgingRelease(SOSPeerInfoCopyEncodedData([self peerInfo], NULL, &error)); + complete(application, (__bridge NSError *)error); + + CFReleaseNull(error); +} + +- (void)circleHash:(void (^)(NSString *, NSError *))complete +{ + NSString *data = CFBridgingRelease(SOSCircleCopyHashString(_circle)); + complete(data, NULL); +} + +- (void)circleJoiningBlob:(NSData *)applicantData complete:(void (^)(NSData *blob, NSError *))complete +{ + CFErrorRef error = NULL; + CFDataRef signature = NULL; + SOSCircleRef prunedCircle = SOSCircleCopyCircle(NULL, _circle, &error); + (void)SOSCirclePreGenerationSign(prunedCircle, _accountPublicKey, &error); + + SOSGenCountRef gencount = SOSGenerationIncrementAndCreate(SOSCircleGetGeneration(prunedCircle)); + if (gencount == NULL) + abort(); + + + SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(NULL, &error, (__bridge CFDataRef)applicantData); + if (applicant == NULL) + abort(); + + signature = SOSCircleCopyNextGenSignatureWithPeerAdded(prunedCircle, applicant, _deviceKey, &error); + if(applicant) { + CFRelease(applicant); + applicant = NULL; + } + + NSData *pbblob = CFBridgingRelease(SOSPiggyBackBlobCopyEncodedData(gencount, _deviceKey, signature, &error)); + + CFReleaseNull(signature); + CFReleaseNull(gencount); + CFReleaseNull(prunedCircle); + + complete(pbblob, NULL); +} + +- (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete +{ + SOSGenCountRef gencount = NULL; + SecKeyRef pubKey = NULL; + CFDataRef signature = NULL; + CFErrorRef error = NULL; + bool setInitialSyncTimeoutToV0 = false; + + if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, (__bridge CFDataRef)blob, kPiggyV1, &setInitialSyncTimeoutToV0, &error)) { + complete(true, (__bridge NSError *)error); + CFReleaseNull(error); + return; + } + + (void)SOSCircleAcceptPeerFromHSA2(_circle, + _accountPrivateKey, + gencount, + pubKey, + signature, + _fullPeerInfo, + &error); + + CFReleaseNull(gencount); + CFReleaseNull(pubKey); + CFReleaseNull(signature); + + complete(true, (__bridge NSError *)error); + + CFReleaseNull(error); + +} + +- (void)getWatchdogParameters:(void (^)(NSDictionary*, NSError*))complete +{ + // intentionally left blank + // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into +} + + +- (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError*))complete +{ + // intentionally left blank + // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into +} + +- (void)ghostBust:(SOSAccountGhostBustingOptions)options complete:(void (^)(bool, NSError *))complete { + complete(false, nil); +} + +- (void)ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete{ + complete(false, nil); +} + +- (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { + complete(false, nil); +} + +- (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete { + complete(nil, nil); +} + +@end diff --git a/KeychainCircle/Tests/KCJoiningSessionTest.m b/KeychainCircle/Tests/KCJoiningSessionTest.m index 6d1d06db..a8919e9d 100644 --- a/KeychainCircle/Tests/KCJoiningSessionTest.m +++ b/KeychainCircle/Tests/KCJoiningSessionTest.m @@ -14,8 +14,8 @@ #import #include -#include -#include +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" #include diff --git a/KeychainCircle/Tests/KCPairingTest.m b/KeychainCircle/Tests/KCPairingTest.m index 0d4e7c1b..2196443d 100644 --- a/KeychainCircle/Tests/KCPairingTest.m +++ b/KeychainCircle/Tests/KCPairingTest.m @@ -9,434 +9,63 @@ #import #import #import -#import -#import -#import +#import "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #import #import #import "SecCFWrappers.h" #import "SOSRegressionUtilities.h" - -@interface FakeNSXPCConnection : NSObject -- (instancetype) initWithControl:(id)control; -- (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler; -@end -@interface FakeNSXPCConnection () -@property id control; -@end -@implementation FakeNSXPCConnection -- (instancetype) initWithControl:(id)control -{ - self = [super init]; - if (self) { - _control = control; - } - return self; -} -- (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler -{ - (void)failureHandler; - return _control; -} -@end - +#import "FakeSOSControl.h" @interface KCPairingTest : XCTestCase @end -@interface FCPairingFakeSOSControl : NSObject -@property (assign) SecKeyRef accountPrivateKey; -@property (assign) SecKeyRef accountPublicKey; -@property (assign) SecKeyRef deviceKey; -@property (assign) SecKeyRef octagonSigningKey; -@property (assign) SecKeyRef octagonEncryptionKey; -@property (assign) SOSCircleRef circle; -@property (assign) SOSFullPeerInfoRef fullPeerInfo; -@property (assign) bool application; -@end - -@implementation FCPairingFakeSOSControl - -- (instancetype)initWithRandomAccountKey:(bool)randomAccountKey circle:(SOSCircleRef)circle -{ - if ((self = [super init])) { - SecKeyRef publicKey = NULL; - NSDictionary* parameters = @{ - (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC, - (__bridge NSString*)kSecAttrKeySizeInBits: @(256), - (__bridge NSString*)kSecAttrNoLegacy : @YES, - (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, - (__bridge id)kSecPrivateKeyAttrs : @{ - (__bridge NSString*)kSecAttrLabel : @"delete me test case - private", - (__bridge NSString*)kSecAttrIsPermanent : @YES, - (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, - }, - (__bridge id)kSecPublicKeyAttrs : @{ - (__bridge NSString*)kSecAttrLabel : @"delete me test case - public", - (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, - } - }; - if(SecKeyGeneratePair((__bridge CFDictionaryRef)parameters, &publicKey, &_deviceKey) != 0) { - NSLog(@"failed to create device key"); - return nil; - } - CFReleaseNull(publicKey); - - NSMutableDictionary* octagonParameters = [parameters mutableCopy]; - octagonParameters[(__bridge NSString*)kSecAttrKeySizeInBits] = @(384); - if(SecKeyGeneratePair((__bridge CFDictionaryRef)octagonParameters, &publicKey, &_octagonSigningKey) != 0) { - NSLog(@"failed to create octagon signing key"); - return nil; - } - CFReleaseNull(publicKey); - - if(SecKeyGeneratePair((__bridge CFDictionaryRef)octagonParameters, &publicKey, &_octagonEncryptionKey) != 0) { - NSLog(@"failed to create octagon signing key"); - return nil; - } - CFReleaseNull(publicKey); - - - _circle = (SOSCircleRef)CFRetain(circle); - - CFErrorRef error = NULL; - - CFDictionaryRef gestalt = (__bridge CFDictionaryRef)@{ - @"ComputerName" : @"name", - }; - - _fullPeerInfo = SOSFullPeerInfoCreate(NULL, gestalt, NULL, _deviceKey, _octagonSigningKey, _octagonEncryptionKey, &error); - CFReleaseNull(error); - - if (randomAccountKey) { - - NSDictionary* accountParams = @{ - (__bridge NSString*)kSecAttrKeyType:(__bridge NSString*) kSecAttrKeyTypeEC, - (__bridge NSString*)kSecAttrKeySizeInBits: @(256), - (__bridge NSString*)kSecAttrNoLegacy : @YES, - (__bridge NSString*)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlock, - }; - - if(SecKeyGeneratePair((__bridge CFDictionaryRef)accountParams, &publicKey, &_accountPrivateKey) != 0) { - NSLog(@"failed to create account signing key"); - return nil; - } - CFReleaseNull(publicKey); - - _accountPublicKey = SecKeyCopyPublicKey(_accountPrivateKey); - - [self signApplicationIfNeeded]; - } - } - return self; -} - -- (void)dealloc -{ - if (_accountPrivateKey) { - SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_accountPrivateKey }); - CFReleaseNull(_accountPrivateKey); - } - if (_deviceKey) { - SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_deviceKey }); - CFReleaseNull(_deviceKey); - } - if (_octagonSigningKey) { - SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_octagonSigningKey }); - CFReleaseNull(_octagonSigningKey); - } - if (_octagonEncryptionKey) { - SecItemDelete((__bridge CFTypeRef)@{ (__bridge id)kSecValueRef : (__bridge id)_octagonEncryptionKey }); - CFReleaseNull(_octagonEncryptionKey); - } - CFReleaseNull(_circle); - CFReleaseNull(_fullPeerInfo); -} - -- (SOSPeerInfoRef)peerInfo -{ - return SOSFullPeerInfoGetPeerInfo(_fullPeerInfo); -} - -- (void)signApplicationIfNeeded -{ - CFErrorRef error = NULL; - - _application = SOSFullPeerInfoPromoteToApplication(_fullPeerInfo, _accountPrivateKey, &error); - if (!_application) - abort(); -} - -- (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete -{ - complete(@[], NULL); -} - -- (void)importInitialSyncCredentials:(NSArray *)items complete:(void (^)(bool success, NSError *))complete -{ - complete(true, NULL); -} - -- (void)triggerSync:(NSArray *)peers complete:(void(^)(bool success, NSError *))complete -{ - complete(true, NULL); -} - -//MARK - FCPairingFakeSOSControl SOSControlProtocol - -- (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete -{ - complete(false, NULL, NULL); -} - -- (void)performanceCounters:(void(^)(NSDictionary *))complete -{ - complete(@{}); -} -- (void)kvsPerformanceCounters:(void(^)(NSDictionary *))complete -{ - complete(@{}); -} - -- (void)rateLimitingPerformanceCounters:(void(^)(NSDictionary *))complete -{ - complete(@{}); -} -- (void)stashedCredentialPublicKey:(void(^)(NSData *, NSError *error))complete -{ - NSData *publicKey = NULL; - NSError *error = NULL; - if (self.accountPrivateKey) { - publicKey = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(self.accountPrivateKey)); - } else { - error = [NSError errorWithDomain:@"FCPairingFakeSOSControl" code:2 userInfo:NULL]; - } - complete(publicKey, error); -} - -- (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))complete -{ - complete(self.accountPrivateKey != NULL, NULL); -} - -- (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete -{ - NSData *key = NULL; - CFErrorRef error = NULL; - if (self.accountPrivateKey) { - key = CFBridgingRelease(SecKeyCopyExternalRepresentation(self.accountPrivateKey, &error)); - } else { - error = (CFErrorRef)CFBridgingRetain([NSError errorWithDomain:@"FCPairingFakeSOSControl" code:1 userInfo:NULL]); - } - complete(key, (__bridge NSError *)error); - CFReleaseNull(error); -} - -- (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete -{ - SecKeyRef accountPrivateKey = NULL; - CFErrorRef error = NULL; - NSDictionary *attributes = @{ - (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate, - (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC, - }; - - accountPrivateKey = SecKeyCreateWithData((__bridge CFDataRef)credential, (__bridge CFDictionaryRef)attributes, &error); - if (accountPrivateKey == NULL) { - complete(false, (__bridge NSError *)error); - CFReleaseNull(error); - return; - } - - _accountPrivateKey = accountPrivateKey; - _accountPublicKey = SecKeyCopyPublicKey(_accountPrivateKey); - - [self signApplicationIfNeeded]; - - complete(true, NULL); -} +@implementation KCPairingTest -- (void)myPeerInfo:(void(^)(NSData *application, NSError *error))complete +- (void)checkRoundtrip:(KCPairingChannelContext *)c1 check:(NSString *)check { - CFErrorRef error = NULL; + KCPairingChannelContext *c2; + NSData *data; - [self signApplicationIfNeeded]; + data = [NSKeyedArchiver archivedDataWithRootObject:c1 requiringSecureCoding:TRUE error:NULL]; + XCTAssertNotNil(data, "data should be valid: %@", check); - NSData *application = CFBridgingRelease(SOSPeerInfoCopyEncodedData([self peerInfo], NULL, &error)); - complete(application, (__bridge NSError *)error); + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; + c2 = [unarchiver decodeObjectOfClass:[KCPairingChannelContext class] forKey:NSKeyedArchiveRootObjectKey]; - CFReleaseNull(error); + XCTAssertEqualObjects(c1, c2, "c1 should be same as c2: %@", check); } -- (void)circleJoiningBlob:(NSData *)applicantData complete:(void (^)(NSData *blob, NSError *))complete -{ - CFErrorRef error = NULL; - CFDataRef signature = NULL; - SOSCircleRef prunedCircle = SOSCircleCopyCircle(NULL, _circle, &error); - (void)SOSCirclePreGenerationSign(prunedCircle, _accountPublicKey, &error); - - SOSGenCountRef gencount = SOSGenerationIncrementAndCreate(SOSCircleGetGeneration(prunedCircle)); - if (gencount == NULL) - abort(); +- (void)testPairingChannelContextValid { + KCPairingChannelContext *c; + c = [[KCPairingChannelContext alloc] init]; - SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(NULL, &error, (__bridge CFDataRef)applicantData); - if (applicant == NULL) - abort(); + [self checkRoundtrip:c check:@"empty"]; - signature = SOSCircleCopyNextGenSignatureWithPeerAdded(prunedCircle, applicant, _deviceKey, &error); - if(applicant) { - CFRelease(applicant); - applicant = NULL; - } + c.intent = KCPairingIntent_Type_None; + [self checkRoundtrip:c check:@"with intent"]; - NSData *pbblob = CFBridgingRelease(SOSPiggyBackBlobCopyEncodedData(gencount, _deviceKey, signature, &error)); - - CFReleaseNull(signature); - CFReleaseNull(gencount); - CFReleaseNull(prunedCircle); - - complete(pbblob, NULL); + c.intent = @"invalid"; } -- (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete -{ - SOSGenCountRef gencount = NULL; - SecKeyRef pubKey = NULL; - CFDataRef signature = NULL; - CFErrorRef error = NULL; - bool setInitialSyncTimeoutToV0 = false; - - if (!SOSPiggyBackBlobCreateFromData(&gencount, &pubKey, &signature, (__bridge CFDataRef)blob, kPiggyV1, &setInitialSyncTimeoutToV0, &error)) { - complete(true, (__bridge NSError *)error); - CFReleaseNull(error); - return; - } +- (void)testPairingChannelContextInvalid { + KCPairingChannelContext *c1, *c2; + NSData *data; - (void)SOSCircleAcceptPeerFromHSA2(_circle, - _accountPrivateKey, - gencount, - pubKey, - signature, - _fullPeerInfo, - &error); + c1 = [[KCPairingChannelContext alloc] init]; + c1.intent = @"invalid"; - CFReleaseNull(gencount); - CFReleaseNull(pubKey); - CFReleaseNull(signature); + data = [NSKeyedArchiver archivedDataWithRootObject:c1 requiringSecureCoding:TRUE error:NULL]; + XCTAssertNotNil(data, "data should be valid"); - complete(true, (__bridge NSError *)error); + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; + c2 = [unarchiver decodeObjectOfClass:[KCPairingChannelContext class] forKey:NSKeyedArchiveRootObjectKey]; - CFReleaseNull(error); - -} - -- (void)getWatchdogParameters:(void (^)(NSDictionary*, NSError*))complete -{ - // intentionally left blank - // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into + XCTAssertNil(c2, "c2 should be NULL"); } -- (void)setWatchdogParmeters:(NSDictionary*)parameters complete:(void (^)(NSError*))complete -{ - // intentionally left blank - // these are used by the security/2 tool and are only declared here to make the compiler happy about conforming the protocol we shoved the methods into -} -@end - -@implementation KCPairingTest - -- (void)testSecPairBasicTest -{ - if (![KCPairingChannel isSupportedPlatform]) { - return; - } - - bool sp1compete = false, sp2compete = false; - NSData *sp1data = NULL; - NSData *sp2data = NULL; - SOSCircleRef circle = NULL; - unsigned count = 0; - CFErrorRef cferror = NULL; - KCPairingChannel *sp1, *sp2; - - circle = SOSCircleCreate(NULL, CFSTR("TEST DOMAIN"), NULL); - XCTAssert(circle, "circle"); - - FCPairingFakeSOSControl *fc1 = [[FCPairingFakeSOSControl alloc] initWithRandomAccountKey:false circle:circle]; - XCTAssert(fc1, "create fake soscontrol 1"); - - FCPairingFakeSOSControl *fc2 = [[FCPairingFakeSOSControl alloc] initWithRandomAccountKey:true circle:circle]; - XCTAssert(fc2, "create fake soscontrol 2"); - - - XCTAssert(SOSCircleRequestAdmission(circle, fc2.accountPrivateKey, fc2.fullPeerInfo, &cferror), "SOSCircleRequestAdmission: %@", cferror); - CFReleaseNull(cferror); - - XCTAssert(SOSCircleAcceptRequest(circle, fc2.accountPrivateKey, fc2.fullPeerInfo, [fc2 peerInfo], &cferror), "SOSCircleAcceptRequest device 1: %@", cferror); - CFReleaseNull(cferror); - - XCTAssert(SOSCircleHasPeer(circle, [fc2 peerInfo], &cferror), "HasPeer 2: %@", cferror); - CFReleaseNull(cferror); - - - sp1 = [KCPairingChannel pairingChannelInitiator:NULL]; - [sp1 setXPCConnectionObject:(NSXPCConnection *)[[FakeNSXPCConnection alloc] initWithControl:fc1]]; - - sp2 = [KCPairingChannel pairingChannelAcceptor:NULL]; - [sp2 setXPCConnectionObject:(NSXPCConnection *)[[FakeNSXPCConnection alloc] initWithControl:fc2]] ; - - while(1) { - NSError *error = NULL; - - sp1data = [sp1 exchangePacket:sp2data complete:&sp1compete error:&error]; - - if (sp1compete && sp2compete) { - XCTAssert(sp1data == NULL, "sp1 done, yet there is data"); - break; - } - XCTAssert(!sp2compete, "sp2 completed w/o sp1"); - - XCTAssert(sp1data != NULL, "sp1 not done, yet there is no data: %@", error); - if (sp1data == NULL) - break; - - /* send sp1data to peer : BOB CHANNEL HERE */ - - sp2data = [sp2 exchangePacket:sp1data complete:&sp2compete error:&error]; - XCTAssert(sp2data != NULL, "sp2 didn't return data: %@", error); - if (sp2data == NULL) - break; - - if (sp1compete && sp2compete) - break; - - XCTAssert(!sp1compete, "sp2 completed w/o sp1"); - - count++; - if (count > 10) - abort(); - }; - - XCTAssert(sp1compete && sp2compete, "both parties not completed"); - - XCTAssert(fc1.accountPrivateKey, "no accountPrivateKey in fc1"); - XCTAssert(fc2.accountPrivateKey, "no accountPrivateKey in fc2"); - XCTAssert(CFEqualSafe(fc1.accountPrivateKey, fc2.accountPrivateKey), "no accountPrivateKey not same in both"); - - if (sp1compete && sp2compete) - NSLog(@"pairing complete"); - - XCTAssert(SOSCircleHasPeer(circle, [fc1 peerInfo], &cferror), "HasPeer 1: %@", cferror); - CFReleaseNull(cferror); - XCTAssert(SOSCircleHasPeer(circle, [fc2 peerInfo], &cferror), "HasPeer 2: %@", cferror); - CFReleaseNull(cferror); - - XCTAssert(sp1.needInitialSync == false, "no longer need initial sync"); - - -} - @end diff --git a/KeychainCircle/generated_source/KCInitialMessageData.h b/KeychainCircle/generated_source/KCInitialMessageData.h new file mode 100644 index 00000000..41b4830b --- /dev/null +++ b/KeychainCircle/generated_source/KCInitialMessageData.h @@ -0,0 +1,35 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from KCInitialMessageData.proto + +#import +#import + +#ifdef __cplusplus +#define KCINITIALMESSAGEDATA_FUNCTION extern "C" +#else +#define KCINITIALMESSAGEDATA_FUNCTION extern +#endif + +@interface KCInitialMessageData : PBCodable +{ + NSData *_prepareMessage; +} + + +@property (nonatomic, readonly) BOOL hasPrepareMessage; +@property (nonatomic, retain) NSData *prepareMessage; + +// Performs a shallow copy into other +- (void)copyTo:(KCInitialMessageData *)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:(KCInitialMessageData *)other; + +KCINITIALMESSAGEDATA_FUNCTION BOOL KCInitialMessageDataReadFrom(__unsafe_unretained KCInitialMessageData *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/KeychainCircle/generated_source/KCInitialMessageData.m b/KeychainCircle/generated_source/KCInitialMessageData.m new file mode 100644 index 00000000..1762d809 --- /dev/null +++ b/KeychainCircle/generated_source/KCInitialMessageData.m @@ -0,0 +1,124 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from KCInitialMessageData.proto + +#import "KCInitialMessageData.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 KCInitialMessageData + +- (BOOL)hasPrepareMessage +{ + return _prepareMessage != nil; +} +@synthesize prepareMessage = _prepareMessage; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_prepareMessage) + { + [dict setObject:self->_prepareMessage forKey:@"prepareMessage"]; + } + return dict; +} + +BOOL KCInitialMessageDataReadFrom(__unsafe_unretained KCInitialMessageData *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 /* prepareMessage */: + { + NSData *new_prepareMessage = PBReaderReadData(reader); + self->_prepareMessage = new_prepareMessage; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return KCInitialMessageDataReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* prepareMessage */ + { + if (self->_prepareMessage) + { + PBDataWriterWriteDataField(writer, self->_prepareMessage, 1); + } + } +} + +- (void)copyTo:(KCInitialMessageData *)other +{ + if (_prepareMessage) + { + other.prepareMessage = _prepareMessage; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + KCInitialMessageData *copy = [[[self class] allocWithZone:zone] init]; + copy->_prepareMessage = [_prepareMessage copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + KCInitialMessageData *other = (KCInitialMessageData *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_prepareMessage && !other->_prepareMessage) || [self->_prepareMessage isEqual:other->_prepareMessage]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_prepareMessage hash] + ; +} + +- (void)mergeFrom:(KCInitialMessageData *)other +{ + if (other->_prepareMessage) + { + [self setPrepareMessage:other->_prepareMessage]; + } +} + +@end + diff --git a/KeychainEntitledTestApp_mac/Base.lproj/Main.storyboard b/KeychainEntitledTestApp_mac/Base.lproj/Main.storyboard deleted file mode 100644 index 6f7fdad6..00000000 --- a/KeychainEntitledTestApp_mac/Base.lproj/Main.storyboard +++ /dev/null @@ -1,693 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - Default - - - - - - - Left to Right - - - - - - - Right to Left - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/KeychainEntitledTestApp_mac/Info.plist b/KeychainEntitledTestApp_mac/Info.plist index f16cc068..8a4ebbf1 100644 --- a/KeychainEntitledTestApp_mac/Info.plist +++ b/KeychainEntitledTestApp_mac/Info.plist @@ -22,8 +22,6 @@ 1 LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) - NSMainStoryboardFile - Main NSPrincipalClass NSApplication diff --git a/KeychainSyncAccountNotification/KeychainSyncAccountNotification-Info.plist b/KeychainSyncAccountNotification/KeychainSyncAccountNotification-Info.plist index 40f3f2ea..a1b3b5c7 100644 --- a/KeychainSyncAccountNotification/KeychainSyncAccountNotification-Info.plist +++ b/KeychainSyncAccountNotification/KeychainSyncAccountNotification-Info.plist @@ -27,6 +27,7 @@ ACSupportedAccountTypes com.apple.account.AppleAccount + com.apple.account.idms diff --git a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m index 799decdd..7120509f 100644 --- a/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m +++ b/KeychainSyncAccountNotification/KeychainSyncAccountNotification.m @@ -6,13 +6,11 @@ #import "KeychainSyncAccountNotification.h" #import #import -#if TARGET_OS_IPHONE #import -#else -#import -#endif #import #import +#import +#import #if OCTAGON #import #include @@ -24,26 +22,24 @@ - (bool)accountIsPrimary:(ACAccount *)account { -#if TARGET_OS_IPHONE - return [account aa_isPrimaryAccount]; -#else - return [account icaIsPrimaryAccount]; -#endif + return [account aa_isAccountClass:AAAccountClassPrimary]; } // 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 +// in the future we may bring this logic over to KeychainDataclassOwner 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 { +- (void)account:(ACAccount *)account didChangeWithType:(ACAccountChangeType)changeType inStore:(ACDAccountStore *)store oldAccount:(ACAccount *)oldAccount { - if((changeType == kACAccountChangeTypeAdded) && + if((changeType == kACAccountChangeTypeAdded || changeType == kACAccountChangeTypeModified) && [account.accountType.identifier isEqualToString: ACAccountTypeIdentifierAppleAccount] && [self accountIsPrimary:account]) { + #if OCTAGON - if(SecOTIsEnabled()){ + if(OctagonIsEnabled()){ __block NSError* error = nil; - NSString *dsid = account.accountProperties[@"personID"]; + + NSString* altDSID = [account aa_altDSID]; + OTControl* otcontrol = [OTControl controlObject:&error]; if (nil == otcontrol) { @@ -51,12 +47,11 @@ } else { dispatch_semaphore_t sema = dispatch_semaphore_create(0); - [otcontrol signIn:dsid reply:^(BOOL result, NSError * _Nullable signedInError) { - if(!result || signedInError){ + [otcontrol signIn:altDSID container:nil context:OTDefaultContext reply:^(NSError * _Nullable signedInError) { + if(signedInError) { secerror("octagon: error signing in: %s", [[signedInError description] UTF8String]); - } - else{ - secnotice("octagon", "signed into octagon trust"); + } else { + secnotice("octagon", "account now signed in for octagon operation"); } dispatch_semaphore_signal(sema); @@ -66,11 +61,53 @@ } } }else{ - secerror("Octagon not enabled!"); + secerror("Octagon not enabled; not signing in"); } #endif } + // If there is any change to any AuthKit account's security level, notify octagon + +#if OCTAGON + if([account.accountType.identifier isEqualToString: ACAccountTypeIdentifierIDMS]) { + secnotice("octagon-authkit", "Received an IDMS account modification"); + + AKAccountManager *manager = [AKAccountManager sharedInstance]; + + AKAppleIDSecurityLevel oldSecurityLevel = [manager securityLevelForAccount:oldAccount]; + AKAppleIDSecurityLevel newSecurityLevel = [manager securityLevelForAccount:account]; + + if(oldSecurityLevel != newSecurityLevel) { + NSString* identifier = account.identifier; + secnotice("octagon-authkit", "IDMS security level has now moved to %ld for %@", (unsigned long)newSecurityLevel, identifier); + + __block NSError* error = nil; + OTControl* otcontrol = [OTControl controlObject:&error]; + if(!otcontrol || error) { + secerror("octagon-authkit: Failed to get OTControl: %@", error); + } else { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [otcontrol notifyIDMSTrustLevelChangeForContainer:nil context:OTDefaultContext reply:^(NSError * _Nullable idmsError) { + if(idmsError) { + secerror("octagon-authkit: error with idms trust level change in: %s", [[idmsError description] UTF8String]); + } else { + secnotice("octagon-authkit", "informed octagon of IDMS trust level change"); + } + dispatch_semaphore_signal(sema); + }]; + + if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5))) { + secerror("octagon-authkit: Timed out altering IDMS change in"); + } + } + + } else { + secnotice("octagon-authkit", "No change to IDMS security level"); + } + } +#endif + if ((changeType == kACAccountChangeTypeDeleted) && [oldAccount.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) { NSString *accountIdentifier = oldAccount.identifier; @@ -86,12 +123,37 @@ secerror("Account %@ could not leave the SOS circle: %@", accountIdentifier, removalError); } +#if OCTAGON + if(OctagonIsEnabled()){ + __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:nil context:OTDefaultContext reply:^(NSError * _Nullable signedInError) { + if(signedInError) { + secerror("octagon: error signing out: %s", [[signedInError 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"); + } + } + } else { + secerror("Octagon not enabled; not signing out"); + } +#endif } } } - - - return YES; } @end diff --git a/Modules/Security.macOS.private.modulemap b/Modules/Security.macOS.private.modulemap new file mode 100644 index 00000000..9645c117 --- /dev/null +++ b/Modules/Security.macOS.private.modulemap @@ -0,0 +1,4 @@ +module Security.SecTask [extern_c] { + header "SecTask.h" + export * +} diff --git a/MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m b/MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m deleted file mode 100644 index 88c68f52..00000000 --- a/MultiDeviceSimulator/ClientInfoByNotification/ClientInfoByNotification.m +++ /dev/null @@ -1,295 +0,0 @@ -// -// 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 deleted file mode 100644 index c01f2ad5..00000000 --- a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator-Entitlements.plist +++ /dev/null @@ -1,64 +0,0 @@ - - - - - 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 deleted file mode 100644 index 1ee39db3..00000000 --- a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// 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/DeviceSimulatorMain.m b/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m deleted file mode 100644 index c6e1ab74..00000000 --- a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorMain.m +++ /dev/null @@ -1,489 +0,0 @@ -// -// 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 deleted file mode 100644 index 77e27677..00000000 --- a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulatorProtocol.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// 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/MultiDeviceSimulatorTests/MultiDeviceNetworking.h b/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h deleted file mode 100644 index 65847325..00000000 --- a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// 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 deleted file mode 100644 index d660f6af..00000000 --- a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworking.m +++ /dev/null @@ -1,295 +0,0 @@ -// -// 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 deleted file mode 100644 index 167d5c49..00000000 --- a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceNetworkingProtocol.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// 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 deleted file mode 100644 index c64cd1f6..00000000 --- a/MultiDeviceSimulator/MultiDeviceSimulatorTests/MultiDeviceSimulatorTests.m +++ /dev/null @@ -1,547 +0,0 @@ -// -// 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/OCMockUmbrella/Info.plist b/OCMockUmbrella/Info.plist new file mode 100644 index 00000000..e1fe4cfb --- /dev/null +++ b/OCMockUmbrella/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/OCMockUmbrella/OCMockUmbrella.h b/OCMockUmbrella/OCMockUmbrella.h new file mode 100644 index 00000000..50625776 --- /dev/null +++ b/OCMockUmbrella/OCMockUmbrella.h @@ -0,0 +1,8 @@ + +#import + +//! Project version number for OCMockUmbrella. +FOUNDATION_EXPORT double OCMockUmbrellaVersionNumber; + +//! Project version string for OCMockUmbrella. +FOUNDATION_EXPORT const unsigned char OCMockUmbrellaVersionString[]; diff --git a/OSX/Keychain Circle Notification/KNAppDelegate.m b/OSX/Keychain Circle Notification/KNAppDelegate.m index e9782142..2c913826 100644 --- a/OSX/Keychain Circle Notification/KNAppDelegate.m +++ b/OSX/Keychain Circle Notification/KNAppDelegate.m @@ -31,6 +31,8 @@ #import #import "notify.h" #import +#import +#import #import #import @@ -67,6 +69,15 @@ static NSUserNotificationCenter *appropriateNotificationCenter() type: _NSUserNotificationCenterTypeSystem]; } +static BOOL isErrorFromXPC(CFErrorRef error) +{ + // Error due to XPC failure does not provide information about the circle. + if (error && (CFEqual(sSecXPCErrorDomain, CFErrorGetDomain(error)))) { + return YES; + } + return NO; +} + static void PSKeychainSyncIsUsingICDP(void) { ACAccountStore *accountStore = [[ACAccountStore alloc] init]; @@ -215,10 +226,227 @@ static void PSKeychainSyncIsUsingICDP(void) return 24*60*60; } +- (NSMutableSet *) makeApplicantSet { + KNAppDelegate *me = self; + NSMutableSet *applicantIds = [NSMutableSet new]; + for (KDCirclePeer *applicant in me.circle.applicants) { + [me postForApplicant:applicant]; + [applicantIds addObject:applicant.idString]; + } + return applicantIds; +} + +- (bool) removeAllNotificationsOfType: (NSString *) typeString { + bool didRemove = false; + NSUserNotificationCenter *noteCenter = appropriateNotificationCenter(); + for (NSUserNotification *note in noteCenter.deliveredNotifications) { + if (note.userInfo[typeString]) { + [appropriateNotificationCenter() removeDeliveredNotification: note]; + didRemove = true; + } + } + return didRemove; +} + +static const char *sosCCStatusCString(SOSCCStatus status) { + switch(status) { + case kSOSCCError: return "kSOSCCError"; + case kSOSCCInCircle: return "kSOSCCInCircle"; + case kSOSCCNotInCircle: return "kSOSCCNotInCircle"; + case kSOSCCCircleAbsent: return "kSOSCCCircleAbsent"; + case kSOSCCRequestPending: return "kSOSCCRequestPending"; + default: return "unknown"; + } +} + +static const char *sosDepartureReasonCString(enum DepartureReason departureReason){ + switch(departureReason) { + case kSOSDepartureReasonError: return "kSOSDepartureReasonError"; + case kSOSNeverLeftCircle: return "kSOSNeverLeftCircle"; + case kSOSWithdrewMembership: return "kSOSWithdrewMembership"; + case kSOSMembershipRevoked: return "kSOSMembershipRevoked"; + case kSOSLeftUntrustedCircle: return "kSOSLeftUntrustedCircle"; + case kSOSNeverAppliedToCircle: return "kSOSNeverAppliedToCircle"; + case kSOSDiscoveredRetirement: return "kSOSDiscoveredRetirement"; + case kSOSLostPrivateKey: return "kSOSLostPrivateKey"; + default: return "unknown reason"; + } +} + -#define ICKC_EVENT_DISABLED "com.apple.security.secureobjectsync.disabled" -#define ICKC_EVENT_DEPARTURE_REASON "com.apple.security.secureobjectsync.departurereason" -#define ICKC_EVENT_NUM_PEERS "com.apple.security.secureobjectsync.numcircledevices" +- (void) processCircleState { + CFErrorRef err = NULL; + KNAppDelegate *me = self; + + enum DepartureReason departureReason = SOSCCGetLastDepartureReason(&err); + if (isErrorFromXPC(err)) { + secnotice("kcn", "SOSCCGetLastDepartureReason failed with xpc error: %@", err); + CFReleaseNull(err); + return; + } else if (err) { + secnotice("kcn", "SOSCCGetLastDepartureReason failed with: %@", err); + } + CFReleaseNull(err); + + SOSCCStatus circleStatus = SOSCCThisDeviceIsInCircle(&err); + if (isErrorFromXPC(err)) { + secnotice("kcn", "SOSCCThisDeviceIsInCircle failed with xpc error: %@", err); + CFReleaseNull(err); + return; + } else if (err) { + secnotice("kcn", "SOSCCThisDeviceIsInCircle failed with: %@", err); + } + CFReleaseNull(err); + + NSDate *nowish = [NSDate date]; + me.state = [KNPersistentState loadFromStorage]; + SOSCCStatus lastCircleStatus = me.state.lastCircleStatus; + + PSKeychainSyncIsUsingICDP(); + + secnotice("kcn", "processCircleState starting ICDP: %s SOSCCStatus: %s DepartureReason: %s", + (_isAccountICDP) ? "Enabled": "Disabled", + sosCCStatusCString(circleStatus), + sosDepartureReasonCString(departureReason)); + + if(_isAccountICDP){ + me.state.lastCircleStatus = circleStatus; + [me.state writeToStorage]; + + switch(circleStatus) { + case kSOSCCInCircle: + secnotice("kcn", "iCDP: device is in circle!"); + _hasPostedAndStillInError = false; + break; + case kSOSCCRequestPending: + [me scheduleActivityAt:me.state.pendingApplicationReminder]; + break; + case kSOSCCCircleAbsent: + case kSOSCCNotInCircle: + [me outOfCircleAlert: departureReason]; + secnotice("kcn", "{ChangeCallback} Pending request START"); + me.state.applicationDate = nowish; + me.state.pendingApplicationReminder = [me.state.applicationDate dateByAddingTimeInterval:[me getPendingApplicationReminderInterval]]; + [me.state writeToStorage]; // FIXME: move below? might be needed for scheduleActivityAt... + [me scheduleActivityAt:me.state.pendingApplicationReminder]; + break; + case kSOSCCError: + /* + You would think we could count on not being iCDP if the account was signed out. Evidently that's wrong. + So we'll go based on the artifact that when the account object is reset (like by signing out) the + departureReason will be set to kSOSDepartureReasonError. So we won't push to get back into a circle if that's + the current reason. I've checked code for other ways we could be out. If we boot and can't load the account + we'll end up with kSOSDepartureReasonError. Then too if we end up in kSOSDepartureReasonError and reboot we end up + in the same place. Leave it to cdpd to decide whether the user needs to sign in to an account. + */ + if(departureReason != kSOSDepartureReasonError) { + secnotice("kcn", "ICDP: We need the password to initiate trust"); + [me postRequirePassword]; + _hasPostedAndStillInError = true; + } else { + secnotice("kcn", "iCDP: We appear to not be associated with an iCloud account"); + } + break; + default: + secnotice("kcn", "Bad SOSCCStatus return %d", circleStatus); + break; + } + } else { // SA version + switch(circleStatus) { + case kSOSCCInCircle: + secnotice("kcn", "SA: device is in circle!"); + _hasPostedAndStillInError = false; + break; + case kSOSCCRequestPending: + [me scheduleActivityAt:me.state.pendingApplicationReminder]; + secnotice("kcn", "{ChangeCallback} scheduleActivity %@", me.state.pendingApplicationReminder); + break; + case kSOSCCCircleAbsent: + case kSOSCCNotInCircle: + switch (departureReason) { + case kSOSDiscoveredRetirement: + case kSOSLostPrivateKey: + case kSOSWithdrewMembership: + case kSOSNeverAppliedToCircle: + case kSOSDepartureReasonError: + case kSOSMembershipRevoked: + default: + if(me.state.lastCircleStatus == kSOSCCInCircle) { + secnotice("kcn", "SA: circle status went from in circle to %s: reason: %s", sosCCStatusCString(circleStatus), sosDepartureReasonCString(departureReason)); + } + break; + + case kSOSNeverLeftCircle: + case kSOSLeftUntrustedCircle: + [me outOfCircleAlert: departureReason]; + secnotice("kcn", "{ChangeCallback} Pending request START"); + me.state.applicationDate = nowish; + me.state.pendingApplicationReminder = [me.state.applicationDate dateByAddingTimeInterval:[me getPendingApplicationReminderInterval]]; + [me.state writeToStorage]; // FIXME: move below? might be needed for scheduleActivityAt... + [me scheduleActivityAt:me.state.pendingApplicationReminder]; + break; + } + break; + case kSOSCCError: + if(me.state.lastCircleStatus == kSOSCCInCircle && (departureReason == kSOSNeverLeftCircle)) { + secnotice("kcn", "SA: circle status went from in circle to error - we need the password"); + [me postRequirePassword]; + _hasPostedAndStillInError = true; + } + break; + default: + secnotice("kcn", "Bad SOSCCStatus return %d", circleStatus); + break; + } + } + + + // Circle applications: pending request(s) started / completed + if (lastCircleStatus == kSOSCCRequestPending && circleStatus != kSOSCCRequestPending) { + secnotice("kcn", "Pending request completed"); + me.state.applicationDate = [NSDate distantPast]; + me.state.pendingApplicationReminder = [NSDate distantFuture]; + [me.state writeToStorage]; + + // Remove reminders + if([me removeAllNotificationsOfType: @"ApplicationReminder"]) { + secnotice("kcn", "{ChangeCallback} removed application remoinders"); + } + } + + // Clear out (old) reset notifications + if (circleStatus == kSOSCCInCircle) { + secnotice("kcn", "{ChangeCallback} kSOSCCInCircle"); + if([me removeAllNotificationsOfType: (NSString*) kValidOnlyOutOfCircleKey]) { + secnotice("kcn", "Removed existing notifications now that we're in circle"); + } + if([me removeAllNotificationsOfType: (NSString*) kPasswordChangedOrTrustedDeviceChanged]) { + secnotice("kcn", "Removed existing password notifications now that we're in circle"); + } + + // Applicants + secnotice("kcn", "{ChangeCallback} Applicants"); + NSMutableSet *applicantIds = [me makeApplicantSet]; + // Clear applicant notifications that aren't pending any more + NSUserNotificationCenter *notificationCenter = appropriateNotificationCenter(); + secnotice("kcn", "Checking validity of %lu notes", (unsigned long)notificationCenter.deliveredNotifications.count); + for (NSUserNotification *note in notificationCenter.deliveredNotifications) { + if (note.userInfo[@"applicantId"] && ![applicantIds containsObject:note.userInfo[@"applicantId"]]) { + secnotice("kcn", "No longer an applicant (%@) for %@ (I=%@)", note.userInfo[@"applicantId"], note, [note.userInfo compactDescription]); + [notificationCenter removeDeliveredNotification:note]; + } else { + secnotice("kcn", "Still an applicant (%@) for %@ (I=%@)", note.userInfo[@"applicantId"], note, [note.userInfo compactDescription]); + } + } + } else { // Clear any pending applicant notifications since we aren't in circle or invalid + if([me removeAllNotificationsOfType: (NSString*) @"applicantId"]) { + secnotice("kcn", "Not in circle or invalid - removed applicant notes"); + } + } + + me.state.lastCircleStatus = circleStatus; + [me.state writeToStorage]; +} - (void) applicationDidFinishLaunching: (NSNotification *) aNotification { @@ -231,46 +459,26 @@ static void PSKeychainSyncIsUsingICDP(void) CFErrorRef err = NULL; KNAppDelegate *me = self; SOSCCStatus currentCircleStatus = SOSCCThisDeviceIsInCircle(&err); + + if (isErrorFromXPC(err)) { + secnotice("kcn", "SOSCCThisDeviceIsInCircle failed with: %@", err); + CFReleaseNull(err); + return; + } + CFReleaseNull(err); + me.state = [KNPersistentState loadFromStorage]; secnotice("kcn", "got public key available notification"); - me.state.lastCircleStatus = currentCircleStatus; - [me.state writeToStorage]; }); //register for public key not available notification, if occurs KCN can react notify_register_dispatch(kPublicKeyNotAvailable, &out_taken, dispatch_get_main_queue(), ^(int token) { - CFErrorRef err = NULL; + secnotice("kcn", "got public key not available notification"); KNAppDelegate *me = self; - enum DepartureReason departureReason = SOSCCGetLastDepartureReason(&err); - SOSCCStatus currentCircleStatus = SOSCCThisDeviceIsInCircle(&err); - me.state = [KNPersistentState loadFromStorage]; - - secnotice("kcn", "got public key not available notification, but won't send notification unless circle transition matches"); - secnotice("kcn", "current circle status: %d, current departure reason: %d, last circle status: %d", currentCircleStatus, departureReason, me.state.lastCircleStatus); - - PSKeychainSyncIsUsingICDP(); - - if(_isAccountICDP){ - if((currentCircleStatus == kSOSCCError || currentCircleStatus == kSOSCCCircleAbsent || currentCircleStatus == kSOSCCNotInCircle) && _hasPostedAndStillInError == false) { - secnotice("kcn", "iCDP: device not in circle, posting follow up"); - [self postRequirePassword]; - _hasPostedAndStillInError = true; - } - else if(currentCircleStatus == kSOSCCInCircle){ - secnotice("kcn", "iCDP: device is in circle!"); - _hasPostedAndStillInError = false; - } - } - else if(!_isAccountICDP && currentCircleStatus == kSOSCCError && me.state.lastCircleStatus == kSOSCCInCircle && (departureReason == kSOSNeverLeftCircle)) { - secnotice("kcn", "circle status went from in circle to not in circle"); - [self postRequirePassword]; - } - me.state.lastCircleStatus = currentCircleStatus; - - [me.state writeToStorage]; + [me processCircleState]; }); self.viewedIds = [NSMutableSet new]; @@ -279,206 +487,8 @@ static void PSKeychainSyncIsUsingICDP(void) [self.circle addChangeCallback:^{ secnotice("kcn", "{ChangeCallback}"); - - CFErrorRef err = NULL; - - NSDate *nowish = [NSDate date]; - enum DepartureReason departureReason = SOSCCGetLastDepartureReason(&err); - SOSCCStatus circleStatus = SOSCCThisDeviceIsInCircle(&err); - me.state = [KNPersistentState loadFromStorage]; - secnotice("kcn", "applicationDidFinishLaunching"); - - PSKeychainSyncIsUsingICDP(); - - if(_isAccountICDP){ - if((circleStatus == kSOSCCError || circleStatus == kSOSCCCircleAbsent || circleStatus == kSOSCCNotInCircle) && _hasPostedAndStillInError == false) { - - secnotice("kcn", "ICDP: We need the password to re-validate ourselves - it's changed on another device"); - me.state.lastCircleStatus = circleStatus; - [me.state writeToStorage]; - [me postRequirePassword]; - _hasPostedAndStillInError = true; - } - else if(circleStatus == kSOSCCInCircle){ - secnotice("kcn", "iCDP: device is in circle!"); - _hasPostedAndStillInError = false; - } - } - else if(!_isAccountICDP && circleStatus == kSOSCCError && me.state.lastCircleStatus == kSOSCCInCircle && (departureReason == kSOSNeverLeftCircle)) { - secnotice("kcn", "SA: circle status went from in circle to not in circle"); - [me postRequirePassword]; - } - // Pending application reminder - secnotice("kcn", "{ChangeCallback} scheduleActivity %@", me.state.pendingApplicationReminder); - if (circleStatus == kSOSCCRequestPending) - [me scheduleActivityAt:me.state.pendingApplicationReminder]; - - - // No longer in circle? - if ((me.state.lastCircleStatus == kSOSCCInCircle && (circleStatus == kSOSCCNotInCircle || circleStatus == kSOSCCCircleAbsent)) || - (me.state.lastCircleStatus == kSOSCCCircleAbsent && circleStatus == kSOSCCNotInCircle && me.state.absentCircleWithNoReason) || - me.state.debugLeftReason) { - enum DepartureReason reason = kSOSNeverLeftCircle; - if (me.state.debugLeftReason) { - reason = [me.state.debugLeftReason intValue]; - me.state.debugLeftReason = nil; - [me.state writeToStorage]; - } else { - reason = SOSCCGetLastDepartureReason(&err); - if (reason == kSOSDepartureReasonError) { - secnotice("kcn", "SOSCCGetLastDepartureReason err: %@", err); - } - if (err) CFRelease(err); - } - - if (reason != kSOSDepartureReasonError) { - // Post kick-out alert - - // MessageTracer data to find out how many users were dropped & reset - msgtracer_domain_t domain = msgtracer_domain_new(ICKC_EVENT_DISABLED); - msgtracer_msg_t mt_msg = NULL; - - if (domain != NULL) - mt_msg = msgtracer_msg_new(domain); - - if (mt_msg) { - char s[16]; - - msgtracer_set(mt_msg, kMsgTracerKeySignature, ICKC_EVENT_DEPARTURE_REASON); - snprintf(s, sizeof(s), "%u", reason); - msgtracer_set(mt_msg, kMsgTracerKeyValue, s); - - int64_t num_peers = 0; - CFArrayRef peerList = SOSCCCopyPeerPeerInfo(NULL); - if (peerList) { - num_peers = CFArrayGetCount(peerList); - if (num_peers > 99) { - // Round down # peers to 2 significant digits - int factor; - for (factor = 10; num_peers >= 100*factor; factor *= 10) ; - num_peers = (num_peers / factor) * factor; - } - CFRelease(peerList); - } - msgtracer_set(mt_msg, kMsgTracerKeySignature2, ICKC_EVENT_NUM_PEERS); - snprintf(s, sizeof(s), "%lld", num_peers); - msgtracer_set(mt_msg, kMsgTracerKeyValue2, s); - - msgtracer_set(mt_msg, kMsgTracerKeySummarize, "NO"); - msgtracer_log(mt_msg, ASL_LEVEL_DEBUG, ""); - } - - // FIXME: - // 1. Write here due to [me timerCheck] => [KNPersistentState loadFromStorage] below?!? - // 2. Or change call order of timerCheck, pendingApplication reminder below??? - me.state.absentCircleWithNoReason = (circleStatus == kSOSCCCircleAbsent && reason == kSOSNeverLeftCircle); - [me.state writeToStorage]; - secnotice("kcn", "{ChangeCallback} departure reason %d", reason); - - switch (reason) { - case kSOSDiscoveredRetirement: - case kSOSLostPrivateKey: - case kSOSWithdrewMembership: - case kSOSNeverAppliedToCircle: - break; - - case kSOSNeverLeftCircle: - case kSOSMembershipRevoked: - case kSOSLeftUntrustedCircle: - default: - [me postKickedOutAlert: reason]; - break; - } - } - } - - - // Circle applications: pending request(s) started / completed - if (me.circle.rawStatus != me.state.lastCircleStatus) { - SOSCCStatus lastCircleStatus = me.state.lastCircleStatus; - me.state.lastCircleStatus = circleStatus; - - if (lastCircleStatus != kSOSCCRequestPending && circleStatus == kSOSCCRequestPending) { - secnotice("kcn", "{ChangeCallback} Pending request START"); - me.state.applicationDate = nowish; - me.state.pendingApplicationReminder = [me.state.applicationDate dateByAddingTimeInterval:[me getPendingApplicationReminderInterval]]; - [me.state writeToStorage]; // FIXME: move below? might be needed for scheduleActivityAt... - [me scheduleActivityAt:me.state.pendingApplicationReminder]; - } - - if (lastCircleStatus == kSOSCCRequestPending && circleStatus != kSOSCCRequestPending) { - secnotice("kcn", "Pending request completed"); - me.state.applicationDate = [NSDate distantPast]; - me.state.pendingApplicationReminder = [NSDate distantFuture]; - [me.state writeToStorage]; - - // Remove reminders - NSUserNotificationCenter *noteCenter = appropriateNotificationCenter(); - for (NSUserNotification *note in noteCenter.deliveredNotifications) { - if (note.userInfo[(NSString*) kValidOnlyOutOfCircleKey] && note.userInfo[@"ApplicationReminder"]) { - secnotice("kcn", "{ChangeCallback} Removing notification %@", note); - [appropriateNotificationCenter() removeDeliveredNotification: note]; - } - } - } - } - - - // Clear out (old) reset notifications - if (me.circle.isInCircle) { - secnotice("kcn", "{ChangeCallback} me.circle.isInCircle"); - NSUserNotificationCenter *noteCenter = appropriateNotificationCenter(); - for (NSUserNotification *note in noteCenter.deliveredNotifications) { - if (note.userInfo[(NSString*) kValidOnlyOutOfCircleKey]) { - secnotice("kcn", "Removing existing notification (%@) now that we are in circle", note); - [appropriateNotificationCenter() removeDeliveredNotification: note]; - } - } - } - - //Clear out (old) password changed notifications - if(me.circle.isInCircle){ - secnotice("kcn", "{ChangeCallback} me.circle.isInCircle"); - NSUserNotificationCenter *noteCenter = appropriateNotificationCenter(); - for (NSUserNotification *note in noteCenter.deliveredNotifications) { - if (note.userInfo[(NSString*) kPasswordChangedOrTrustedDeviceChanged]) { - secnotice("kcn", "Removing existing notification (%@) now that we are valid again", note); - [appropriateNotificationCenter() removeDeliveredNotification: note]; - } - } - - } - - // Applicants - secnotice("kcn", "{ChangeCallback} Applicants"); - NSMutableSet *applicantIds = [NSMutableSet new]; - for (KDCirclePeer *applicant in me.circle.applicants) { - if (!me.circle.isInCircle) { - // Don't yammer on about circles we aren't in, and don't announce our own - // join requests as if the user could approve them locally! - break; - } - [me postForApplicant:applicant]; - [applicantIds addObject:applicant.idString]; - } - - - // Update notifications - NSUserNotificationCenter *notificationCenter = appropriateNotificationCenter(); - secnotice("kcn", "Checking validity of %lu notes", (unsigned long)notificationCenter.deliveredNotifications.count); - for (NSUserNotification *note in notificationCenter.deliveredNotifications) { - if (note.userInfo[@"applicantId"] && ![applicantIds containsObject:note.userInfo[@"applicantId"]]) { - secnotice("kcn", "No longer an applicant (%@) for %@ (I=%@)", note.userInfo[@"applicantId"], note, [note.userInfo compactDescription]); - [notificationCenter removeDeliveredNotification:note]; - } else { - secnotice("kcn", "Still an applicant (%@) for %@ (I=%@)", note.userInfo[@"applicantId"], note, [note.userInfo compactDescription]); - } - } - - me.state.lastCircleStatus = circleStatus; - - [me.state writeToStorage]; - }]; + [me processCircleState]; + }]; } @@ -537,7 +547,7 @@ static void PSKeychainSyncIsUsingICDP(void) note.title = [NSString stringWithFormat: (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_APPROVAL_TITLE), applicant.name]; note.informativeText = [KNAppDelegate localisedApprovalBodyWithDeviceTypeFromPeerInfo:applicant.peerObject]; note._displayStyle = _NSUserNotificationDisplayStyleAlert; - note._identityImage = [NSImage bundleImage]; + note._identityImage = [NSImage bundleImageNamed:kAOSUISpyglassAppleID]; note._identityImageStyle = _NSUserNotificationIdentityImageStyleRectangleNoBorder; note.otherButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_DECLINE); note.actionButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_APPROVE); @@ -573,7 +583,18 @@ static void PSKeychainSyncIsUsingICDP(void) - (void) postRequirePassword { - if(!_isAccountICDP){ + SOSCCStatus currentCircleStatus = SOSCCThisDeviceIsInCircle(NULL); + if(currentCircleStatus != kSOSCCError) { + secnotice("kcn", "postRequirePassword when not needed"); + return; + } + + enum DepartureReason departureReason = SOSCCGetLastDepartureReason(NULL); + + if(_isAccountICDP){ + secnotice("kcn","would have posted needs password and then followed up"); + [self startFollowupKitRepair]; + } else if(departureReason == kSOSNeverLeftCircle) { // The only SA case for prompting NSUserNotificationCenter *noteCenter = appropriateNotificationCenter(); for (NSUserNotification *note in noteCenter.deliveredNotifications) { if (note.userInfo[(NSString*) kPasswordChangedOrTrustedDeviceChanged]) { @@ -588,14 +609,14 @@ static void PSKeychainSyncIsUsingICDP(void) NSString *message = CFBridgingRelease(SecCopyCKString(SEC_CK_PWD_REQUIRED_BODY_OSX)); if (os_variant_has_internal_ui("iCloudKeychain")) { - NSString *reason_str = [NSString stringWithFormat:(__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CR_REASON_INTERNAL), @"Device became untrusted or password changed"]; + NSString *reason_str = [NSString stringWithFormat:(__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CR_REASON_INTERNAL), "Device became untrusted or password changed"]; message = [message stringByAppendingString: reason_str]; } NSUserNotification *note = [NSUserNotification new]; note.title = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_PWD_REQUIRED_TITLE); note.informativeText = message; - note._identityImage = [NSImage bundleImage]; + note._identityImage = [NSImage bundleImageNamed:kAOSUISpyglassAppleID]; note._identityImageStyle = _NSUserNotificationIdentityImageStyleRectangleNoBorder; note.otherButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_NOT_NOW); note.actionButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CONTINUE); @@ -609,14 +630,12 @@ static void PSKeychainSyncIsUsingICDP(void) secnotice("kcn", "body=%@", note.informativeText); secnotice("kcn", "About to post #-/%lu (PASSWORD/TRUSTED DEVICE): %@", noteCenter.deliveredNotifications.count, note); [appropriateNotificationCenter() deliverNotification:note]; - } - else{ - secnotice("kcn","would have posted needs password and then followed up"); - [self startFollowupKitRepair]; + } else { + secnotice("kcn", "postRequirePassword when not needed for SA"); } } -- (void) postKickedOutAlert: (int) reason +- (void) outOfCircleAlert: (int) reason { if(!_isAccountICDP){ @@ -634,19 +653,7 @@ static void PSKeychainSyncIsUsingICDP(void) NSString *message = CFBridgingRelease(SecCopyCKString(SEC_CK_PWD_REQUIRED_BODY_OSX)); if (os_variant_has_internal_ui("iCloudKeychain")) { - static const char *departureReasonStrings[] = { - "kSOSDepartureReasonError", - "kSOSNeverLeftCircle", - "kSOSWithdrewMembership", - "kSOSMembershipRevoked", - "kSOSLeftUntrustedCircle", - "kSOSNeverAppliedToCircle", - "kSOSDiscoveredRetirement", - "kSOSLostPrivateKey", - "unknown reason" - }; - int idx = (kSOSDepartureReasonError <= reason && reason <= kSOSLostPrivateKey) ? reason : (kSOSLostPrivateKey + 1); - NSString *reason_str = [NSString stringWithFormat:(__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CR_REASON_INTERNAL), departureReasonStrings[idx]]; + NSString *reason_str = [NSString stringWithFormat:(__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CR_REASON_INTERNAL), sosDepartureReasonCString(reason)]; message = [message stringByAppendingString: reason_str]; } @@ -658,7 +665,7 @@ static void PSKeychainSyncIsUsingICDP(void) NSUserNotification *note = [NSUserNotification new]; note.title = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_PWD_REQUIRED_TITLE); note.informativeText = message; - note._identityImage = [NSImage bundleImage]; + note._identityImage = [NSImage bundleImageNamed:kAOSUISpyglassAppleID]; note._identityImageStyle = _NSUserNotificationIdentityImageStyleRectangleNoBorder; note.otherButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_NOT_NOW); note.actionButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CONTINUE); @@ -676,7 +683,7 @@ static void PSKeychainSyncIsUsingICDP(void) } else{ - secnotice("kcn","postKickedOutAlert starting followup repair"); + secnotice("kcn","outOfCircleAlert starting followup repair"); [self startFollowupKitRepair]; } } @@ -703,7 +710,7 @@ static void PSKeychainSyncIsUsingICDP(void) NSUserNotification *note = [NSUserNotification new]; note.title = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_REMINDER_TITLE_OSX); note.informativeText = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_REMINDER_BODY_OSX); - note._identityImage = [NSImage bundleImage]; + note._identityImage = [NSImage bundleImageNamed:kAOSUISpyglassAppleID]; note._identityImageStyle = _NSUserNotificationIdentityImageStyleRectangleNoBorder; note.otherButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_NOT_NOW); note.actionButtonTitle = (__bridge_transfer NSString *) SecCopyCKString(SEC_CK_CONTINUE); diff --git a/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist b/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist index 9b098817..c1dd8e6c 100644 --- a/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist +++ b/OSX/SecurityTestsOSX/SecurityTests-Entitlements.plist @@ -14,6 +14,8 @@ com.apple.keystore.device + com.apple.private.applecredentialmanager.allow + restore-keychain migrate-keychain diff --git a/OSX/SecurityTestsOSX/testlist.h b/OSX/SecurityTestsOSX/testlist.h index ea6b6579..5c3ef633 100644 --- a/OSX/SecurityTestsOSX/testlist.h +++ b/OSX/SecurityTestsOSX/testlist.h @@ -2,7 +2,6 @@ #include #include #include -#include #include #include #include diff --git a/OSX/authd/agent.c b/OSX/authd/agent.c index 73083533..f6cf1f33 100644 --- a/OSX/authd/agent.c +++ b/OSX/authd/agent.c @@ -139,7 +139,8 @@ agent_create(engine_t engine, mechanism_t mech, auth_token_t auth, process_t pro os_log_debug(AUTHD_LOG, "agent: creating a standard security agent"); } else { // Root session => loginwindow SecurityAgent - agent->agentConnection = xpc_connection_create_mach_service(SECURITYAGENT_LOGINWINDOW_BOOTSTRAP_NAME_BASE, NULL, 0); + agent->agentConnection = xpc_connection_create_mach_service(SECURITYAGENT_LOGINWINDOW_BOOTSTRAP_NAME_BASE, NULL, + XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); xpc_connection_set_instance(agent->agentConnection, sessionUUID); os_log_debug(AUTHD_LOG, "agent: creating a loginwindow security agent"); doSwitchAudit = true; diff --git a/OSX/authd/authd-Entitlements.plist b/OSX/authd/authd-Entitlements.plist index a1885cc8..7ef4f57c 100644 --- a/OSX/authd/authd-Entitlements.plist +++ b/OSX/authd/authd-Entitlements.plist @@ -6,7 +6,5 @@ com.apple.keystore.console - com.apple.security.cs.disable-library-validation - diff --git a/OSX/authd/authdb.c b/OSX/authd/authdb.c index 49967d0e..c10ce840 100644 --- a/OSX/authd/authdb.c +++ b/OSX/authd/authdb.c @@ -511,7 +511,7 @@ authdb_connection_t authdb_connection_acquire(authdb_t db) dbconn = authdb_connection_create(db); #if DEBUG total++; - os_log_debug(AUTHD_LOG, "authdb: no handles available total: %i", total); + os_log_debug(AUTHD_LOG, "authdb: handles count: %i", total); #endif } }); @@ -873,7 +873,7 @@ bool authdb_step(authdb_connection_t dbconn, const char * sql, void (^bind_stmt) break; default: if (_is_busy(rc)) { - os_log_debug(AUTHD_LOG, "authdb: %{public}s", sqlite3_errmsg(dbconn->handle)); + os_log(AUTHD_LOG, "authdb: %{public}s (will try to recover)", sqlite3_errmsg(dbconn->handle)); sleep(AUTHDB_BUSY_DELAY); sqlite3_reset(stmt); } else { @@ -1123,6 +1123,8 @@ static sqlite3 * _create_handle(authdb_t db) chmod(db->db_path, S_IRUSR | S_IWUSR); } + // Let SQLite handle timeouts. + sqlite3_busy_timeout(handle, 5*1000); done: return handle; } diff --git a/OSX/authd/authorization.plist b/OSX/authd/authorization.plist index e9ec5393..2b135078 100644 --- a/OSX/authd/authorization.plist +++ b/OSX/authd/authorization.plist @@ -58,10 +58,22 @@ See remaining rules for examples. allow-root + authenticate-user + class - user - group - admin + rule + k-of-n + 1 + rule + + is-root + is-admin + default + + shared + + version + 1 com.apple.DiskManagement. @@ -663,6 +675,17 @@ See remaining rules for examples. comment For burning media. + system.csfde.requestpassword.weak + + class + rule + comment + Used by CoreStorage Full Disk Encryption to request the user's password, allowing alternative authentication methods. + rule + + authenticate-admin-or-staff-extract-weak + + system.csfde.requestpassword class @@ -1333,18 +1356,23 @@ See remaining rules for examples. system.services.systemconfiguration.network - allow-root - class - user + rule comment For making change to network configuration via System Configuration. + k-of-n + 1 + rule + + is-root + entitled + _mbsetupuser-nonshared + authenticate-admin-nonshared + entitled-group - group - admin version - 1 + 2 vpn-entitled-group @@ -1498,6 +1526,21 @@ See remaining rules for examples. authenticate-admin-30 + com.apple.installassistant.macos + + allow-root + + class + user + comment + Used by Install Assistant + group + admin + shared + + timeout + 300 + com.apple.security.syntheticinput class @@ -1539,6 +1582,23 @@ See remaining rules for examples. authenticate-session-owner-or-admin + com.apple.configurationprofiles.userenrollment.install + + class + user + comment + This right is used by UserManagement to ask user to acquire password from users. + session-owner + + extract-password + + password-only + + shared + + version + 1 + com.apple.safaridriver.allow comment @@ -1595,6 +1655,30 @@ See remaining rules for examples. timeout 60 + com.apple.applepay.reset + + class + user + comment + Used by nfcd. + group + admin + shared + + timeout + 300 + + com.apple.system-extensions.admin + + comment + Authorize a 3rd party application which wants to manipulate system extensions. + class + rule + rule + authenticate-admin-nonshared + shared + + rules @@ -1687,6 +1771,19 @@ See remaining rules for examples. version 1 + _mbsetupuser-nonshared + + class + user + authenticate-user + + comment + Succeeds if user is from _mbsetupuser group. + group + _mbsetupuser + timeout + 30 + authenticate-admin-30 class @@ -1703,6 +1800,36 @@ See remaining rules for examples. timeout 30 + authenticate-admin-extract-weak + + class + user + comment + Authenticate as an administrator + allow password extraction. + extract-password + + group + admin + require-apple-signed + + timeout + 0 + + authenticate-staff-extract-weak + + class + user + comment + Authenticate as group staff + allow password to be extracted. + extract-password + + group + staff + require-apple-signed + + timeout + 0 + authenticate-admin-extract class @@ -1753,6 +1880,18 @@ See remaining rules for examples. localauthentication-context + authenticate-admin-or-staff-extract-weak + + class + rule + k-of-n + 1 + rule + + authenticate-admin-extract-weak + authenticate-staff-extract-weak + + authenticate-admin-or-staff-extract class diff --git a/OSX/authd/authtoken.c b/OSX/authd/authtoken.c index f7ed85b4..6b0568aa 100644 --- a/OSX/authd/authtoken.c +++ b/OSX/authd/authtoken.c @@ -169,7 +169,7 @@ _auth_token_create(const audit_info_s * auditInfo, bool operateAsLeastPrivileged auth->processes = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL); auth->creator_bootstrap_port = MACH_PORT_NULL; - if (sandbox_check(auth->auditInfo.pid, "authorization-right-obtain", SANDBOX_CHECK_NO_REPORT) != 0) + if (sandbox_check_by_audit_token(auth->auditInfo.opaqueToken, "authorization-right-obtain", SANDBOX_CHECK_NO_REPORT) != 0) auth->sandboxed = true; else auth->sandboxed = false; @@ -228,54 +228,6 @@ done: return auth; } -auth_token_t -auth_token_create_with_audit_info(const audit_info_s* info, bool operateAsLeastPrivileged) -{ - OSStatus status = errSecSuccess; - SecCodeRef code_Ref = NULL; - CFURLRef code_url = NULL; - - auth_token_t auth = NULL; - require(info != NULL, done); - - auth = _auth_token_create(info, operateAsLeastPrivileged); - require(auth != NULL, done); - - auth->session = server_find_copy_session(info->asid, true); - if (auth->session == NULL) { - os_log_debug(AUTHD_LOG, "authtoken: failed to create session (PID %d)", auth->auditInfo.pid); - CFReleaseNull(auth); - goto done; - } - - CFMutableDictionaryRef codeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFNumberRef codePid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &auth->auditInfo.pid); - CFDictionarySetValue(codeDict, kSecGuestAttributePid, codePid); - status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &code_Ref); - CFReleaseSafe(codeDict); - CFReleaseSafe(codePid); - - if (status) { - os_log_debug(AUTHD_LOG, "authtoken: failed to create code ref (%d)", (int)status); - CFReleaseNull(auth); - goto done; - } - - if (SecCodeCopyPath(code_Ref, kSecCSDefaultFlags, &code_url) == errSecSuccess) { - auth->code_url = calloc(1u, PATH_MAX+1); - if (auth->code_url) { - CFURLGetFileSystemRepresentation(code_url, true, (UInt8*)auth->code_url, PATH_MAX); - } - } - - os_log_debug(AUTHD_LOG, "authtoken: created for %{public}s", auth->code_url); - -done: - CFReleaseSafe(code_Ref); - CFReleaseSafe(code_url); - return auth; -} - bool auth_token_get_sandboxed(auth_token_t auth) { diff --git a/OSX/authd/authtoken.h b/OSX/authd/authtoken.h index 0ea9990d..3236e4da 100644 --- a/OSX/authd/authtoken.h +++ b/OSX/authd/authtoken.h @@ -20,9 +20,6 @@ extern const CFDictionaryKeyCallBacks kAuthTokenKeyCallBacks; AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED auth_token_t auth_token_create(process_t,bool operateAsLeastPrivileged); - -AUTH_WARN_RESULT AUTH_MALLOC AUTH_NONNULL_ALL AUTH_RETURNS_RETAINED -auth_token_t auth_token_create_with_audit_info(const audit_info_s*,bool operateAsLeastPrivileged); AUTH_NONNULL_ALL bool auth_token_get_sandboxed(auth_token_t); diff --git a/OSX/authd/ccaudit.c b/OSX/authd/ccaudit.c index 2c696ebb..4d53229b 100644 --- a/OSX/authd/ccaudit.c +++ b/OSX/authd/ccaudit.c @@ -11,7 +11,6 @@ AUTHD_DEFINE_LOG - struct _ccaudit_s { __AUTH_BASE_STRUCT_HEADER__; @@ -149,7 +148,6 @@ static bool _subject(ccaudit_t ccaudit) void ccaudit_log_authorization(ccaudit_t ccaudit, const char * right, OSStatus err) { - if (!_open(ccaudit)) { return; } @@ -177,7 +175,6 @@ void ccaudit_log_authorization(ccaudit_t ccaudit, const char * right, OSStatus e void ccaudit_log_success(ccaudit_t ccaudit, credential_t cred, const char * right) { - if (!_open(ccaudit)) { return; } @@ -198,7 +195,6 @@ void ccaudit_log_success(ccaudit_t ccaudit, credential_t cred, const char * righ void ccaudit_log_failure(ccaudit_t ccaudit, const char * credName, const char * right) { - if (!_open(ccaudit)) { return; } @@ -216,7 +212,6 @@ void ccaudit_log_failure(ccaudit_t ccaudit, const char * credName, const char * void ccaudit_log_mechanism(ccaudit_t ccaudit, const char * right, const char * mech, uint32_t status, const char * interrupted) { - if (!_open(ccaudit)) { return; } diff --git a/OSX/authd/com.apple.authd.sb b/OSX/authd/com.apple.authd.sb index 88415cfc..5b94ca8a 100644 --- a/OSX/authd/com.apple.authd.sb +++ b/OSX/authd/com.apple.authd.sb @@ -18,8 +18,8 @@ (literal "/private/var/run/systemkeychaincheck.socket")) (allow mach-lookup - (global-name "com.apple.CoreAuthentication.agent.libxpc") - (global-name "com.apple.CoreAuthentication.daemon.libxpc") + (global-name "com.apple.CoreAuthentication.agent") + (global-name "com.apple.CoreAuthentication.daemon") (global-name "com.apple.CoreServices.coreservicesd") (global-name "com.apple.PowerManagement.control") (global-name "com.apple.security.agent") @@ -28,11 +28,15 @@ (global-name "com.apple.SecurityServer") (global-name "com.apple.system.opendirectoryd.api") (global-name "com.apple.ocspd")) - + (allow ipc-posix-shm (ipc-posix-name "apple.shm.notification_center") (ipc-posix-name "com.apple.AppleDatabaseChanged")) -(allow mach-per-user-lookup) +(allow mach-priv-host-port) + +(allow user-preference-read + (preference-domain "kCFPreferencesAnyApplication") + (preference-domain "com.apple.authd")) (allow system-audit system-sched) diff --git a/OSX/authd/engine.c b/OSX/authd/engine.c index e9f009b0..1e4584db 100644 --- a/OSX/authd/engine.c +++ b/OSX/authd/engine.c @@ -29,7 +29,6 @@ int checkpw_internal( const struct passwd *pw, const char* password ); #include #include - AUTHD_DEFINE_LOG static void _set_process_hints(auth_items_t, process_t); @@ -424,7 +423,6 @@ _evaluate_builtin_mechanism(engine_t engine, mechanism_t mech) return result; } - static bool _extract_password_from_la(engine_t engine) { @@ -872,7 +870,7 @@ _evaluate_class_user(engine_t engine, rule_t rule) return errAuthorizationInteractionNotAllowed; } - if (server_in_dark_wake()) { + if (server_in_dark_wake() && !(engine->flags & kAuthorizationFlagIgnoreDarkWake)) { os_log_error(AUTHD_LOG, "Fatal: authorization denied (DW) (engine %lld)", engine->engine_index); return errAuthorizationDenied; } @@ -952,7 +950,7 @@ _evaluate_class_mechanism(engine_t engine, rule_t rule) mechanisms = rule_get_mechanisms(rule); - if (server_in_dark_wake()) { + if (server_in_dark_wake() && !(engine->flags & kAuthorizationFlagIgnoreDarkWake)) { CFIndex count = CFArrayGetCount(mechanisms); for (CFIndex i = 0; i < count; i++) { if (!mechanism_is_privileged((mechanism_t)CFArrayGetValueAtIndex(mechanisms, i))) { @@ -1005,22 +1003,6 @@ done: return status; } -// TODO: Remove when all clients have adopted entitlement -static bool -enforced_entitlement(void) -{ - bool enforced_enabled = false; - //sudo defaults write /Library/Preferences/com.apple.authd enforceEntitlement -bool true - CFTypeRef enforce = (CFNumberRef)CFPreferencesCopyValue(CFSTR("enforceEntitlement"), CFSTR(SECURITY_AUTH_NAME), kCFPreferencesAnyUser, kCFPreferencesCurrentHost); - if (enforce && CFGetTypeID(enforce) == CFBooleanGetTypeID()) { - enforced_enabled = CFBooleanGetValue((CFBooleanRef)enforce); - os_log_debug(AUTHD_LOG, "enforceEntitlement for extract password: %{public}s", enforced_enabled ? "enabled" : "disabled"); - } - CFReleaseSafe(enforce); - - return enforced_enabled; -} - static OSStatus _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) { @@ -1042,23 +1024,8 @@ _evaluate_rule(engine_t engine, rule_t rule, bool *save_pwd) #endif } } - - if (rule_get_extract_password(rule)) { - // check if process is entitled to extract password - 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 %lld: authorization allowed to extract password", engine->engine_index); - } else { - os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index); - } - CFReleaseSafe(extract_password_entitlement); - } - - // TODO: Remove when all clients have adopted entitlement - if (!enforced_entitlement()) { - *save_pwd |= rule_get_extract_password(rule); - } + + *save_pwd |= rule_get_extract_password(rule); switch (rule_get_class(rule)) { case RC_ALLOW: @@ -1198,7 +1165,7 @@ done: 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)) { + if (sandbox_check_by_audit_token(process_get_audit_info(engine->proc)->opaqueToken, "authorization-right-obtain", SANDBOX_FILTER_RIGHT_NAME, right)) { 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; } @@ -1221,19 +1188,6 @@ OSStatus engine_preauthorize(engine_t engine, auth_items_t credentials) 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 %lld: authorization allowed to extract password", engine->engine_index); - } else { - os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index); - } - CFReleaseSafe(extract_password_entitlement); - - // TODO: Remove when all clients have adopted entitlement - if (!enforced_entitlement()) { - save_password = true; - } engine->flags = kAuthorizationFlagExtendRights; engine->preauthorizing = true; @@ -1385,12 +1339,13 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en 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); + os_log_info(AUTHD_LOG, "Process %{public}s (PID %d) evaluates %ld rights with flags %08x (engine %lld): %{public}@", process_get_code_url(engine->proc), process_get_pid(engine->proc), (long)rights_count, flags, engine->engine_index, rights_list); CFReleaseNull(rights_list); } - if (!auth_token_apple_signed(engine->auth)) { + if (!auth_token_apple_signed(engine->auth) && (flags & kAuthorizationFlagSheet)) { #ifdef NDEBUG + os_log_error(AUTHD_LOG, "engine %lld: extra flags are ommited as creator is not signed by Apple", engine->engine_index); flags &= ~kAuthorizationFlagSheet; #else 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); @@ -1413,20 +1368,6 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en CFReleaseSafe(decrypted_items); if (engine->flags & kAuthorizationFlagSheet) { - 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 %lld: authorization allowed to extract password", engine->engine_index); - } else { - os_log_debug(AUTHD_LOG, "engine %lld: authorization NOT allowed to extract password", engine->engine_index); - } - CFReleaseSafe(extract_password_entitlement); - - // TODO: Remove when all clients have adopted entitlement - if (!enforced_entitlement()) { - save_password = true; - } - // Try to use/update fresh context values from the environment require_action(environment, done, os_log_error(AUTHD_LOG, "Missing environment for sheet authorization (engine %lld)", engine->engine_index); status = errAuthorizationDenied); @@ -1503,7 +1444,6 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en if (!key) return true; - if (!_verify_sandbox(engine, key)) { // _verify_sandbox is already logging failures status = errAuthorizationDenied; return false; @@ -1520,7 +1460,7 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en 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) { + if (engine->flags & kAuthorizationFlagInteractionAllowed || engine->flags & kAuthorizationFlagSheet) { _set_right_hints(engine->hints, key); _set_localization_hints(dbconn, engine->hints, rule); if (!engine->authenticateRule) { @@ -1539,7 +1479,7 @@ OSStatus engine_authorize(engine_t engine, auth_rights_t rights, auth_items_t en switch (status) { case errAuthorizationSuccess: auth_rights_add(engine->grantedRights, key); - auth_rights_set_flags(engine->grantedRights, key, auth_rights_get_flags(rights,key)); + auth_rights_set_flags(engine->grantedRights, key, auth_rights_get_flags(rights, key)); if ((engine->flags & kAuthorizationFlagPreAuthorize) && (rule_get_class(engine->currentRule) == RC_USER) && diff --git a/OSX/authd/process.c b/OSX/authd/process.c index 1cbf78ed..4a245757 100644 --- a/OSX/authd/process.c +++ b/OSX/authd/process.c @@ -26,7 +26,6 @@ struct _process_s { CFMutableSetRef connections; - SecCodeRef codeRef; char code_url[PATH_MAX+1]; char * code_identifier; CFDataRef code_requirement_data; @@ -82,7 +81,6 @@ _process_finalize(CFTypeRef value) CFReleaseNull(proc->authTokens); CFReleaseNull(proc->connections); CFReleaseNull(proc->session); - CFReleaseNull(proc->codeRef); CFReleaseNull(proc->code_requirement); CFReleaseNull(proc->code_requirement_data); CFReleaseNull(proc->code_entitlements); @@ -121,6 +119,7 @@ process_create(const audit_info_s * auditInfo, session_t session) process_t proc = NULL; CFDictionaryRef code_info = NULL; CFURLRef code_url = NULL; + SecCodeRef codeRef = NULL; require(session != NULL, done); require(auditInfo != NULL, done); @@ -141,11 +140,18 @@ process_create(const audit_info_s * auditInfo, session_t session) check(proc->dispatch_queue != NULL); CFMutableDictionaryRef codeDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFNumberRef codePid = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &proc->auditInfo.pid); - CFDictionarySetValue(codeDict, kSecGuestAttributePid, codePid); - status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &proc->codeRef); + CFDataRef auditToken = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8 *)&auditInfo->opaqueToken, sizeof(auditInfo->opaqueToken), kCFAllocatorNull); + if (auditToken) { + CFDictionarySetValue(codeDict, kSecGuestAttributeAudit, auditToken); + CFReleaseNull(auditToken); + } else { + CFReleaseSafe(codeDict); + os_log_error(AUTHD_LOG, "process: PID %d failed to create audit token", proc->auditInfo.pid); + CFReleaseNull(proc); + goto done; + } + status = SecCodeCopyGuestWithAttributes(NULL, codeDict, kSecCSDefaultFlags, &codeRef); CFReleaseSafe(codeDict); - CFReleaseSafe(codePid); if (status) { os_log_error(AUTHD_LOG, "process: PID %d failed to create code ref %d", proc->auditInfo.pid, (int)status); @@ -153,7 +159,7 @@ process_create(const audit_info_s * auditInfo, session_t session) goto done; } - status = SecCodeCopySigningInformation(proc->codeRef, kSecCSRequirementInformation, &code_info); + status = SecCodeCopySigningInformation(codeRef, kSecCSRequirementInformation, &code_info); require_noerr_action(status, done, os_log_debug(AUTHD_LOG, "process: PID %d SecCodeCopySigningInformation failed with %d", proc->auditInfo.pid, (int)status)); CFTypeRef value = NULL; @@ -167,7 +173,7 @@ process_create(const audit_info_s * auditInfo, session_t session) value = NULL; } - if (SecCodeCopyPath(proc->codeRef, kSecCSDefaultFlags, &code_url) == errSecSuccess) { + if (SecCodeCopyPath(codeRef, kSecCSDefaultFlags, &code_url) == errSecSuccess) { CFURLGetFileSystemRepresentation(code_url, true, (UInt8*)proc->code_url, sizeof(proc->code_url)); } @@ -189,15 +195,15 @@ process_create(const audit_info_s * auditInfo, session_t session) // AppStore apps must have resource envelope 2. Check with spctl -a -t exec -vv CFStringRef firstPartyRequirement = CFSTR("anchor apple"); CFStringRef appStoreRequirement = CFSTR("anchor apple generic and certificate leaf[field.1.2.840.113635.100.6.1.9] exists"); - SecRequirementRef secRequirementRef = NULL; + SecRequirementRef secRequirementRef = NULL; status = SecRequirementCreateWithString(firstPartyRequirement, kSecCSDefaultFlags, &secRequirementRef); if (status == errSecSuccess) { - proc->firstPartySigned = process_verify_requirement(proc, secRequirementRef); + proc->firstPartySigned = process_verify_requirement(proc, codeRef, secRequirementRef); CFReleaseNull(secRequirementRef); } status = SecRequirementCreateWithString(appStoreRequirement, kSecCSDefaultFlags, &secRequirementRef); if (status == errSecSuccess) { - proc->appStoreSigned = process_verify_requirement(proc, secRequirementRef); + proc->appStoreSigned = process_verify_requirement(proc, codeRef, secRequirementRef); CFReleaseSafe(secRequirementRef); } os_log_debug(AUTHD_LOG, "process: PID %d created (sid=%i) %{public}s", proc->auditInfo.pid, proc->auditInfo.asid, proc->code_url); @@ -205,6 +211,7 @@ process_create(const audit_info_s * auditInfo, session_t session) done: CFReleaseSafe(code_info); CFReleaseSafe(code_url); + CFReleaseSafe(codeRef); return proc; } @@ -254,12 +261,6 @@ process_get_audit_info(process_t proc) return &proc->auditInfo; } -SecCodeRef -process_get_code(process_t proc) -{ - return proc->codeRef; -} - const char * process_get_code_url(process_t proc) { @@ -466,9 +467,9 @@ process_get_requirement(process_t proc) return proc->code_requirement; } -bool process_verify_requirement(process_t proc, SecRequirementRef requirment) +bool process_verify_requirement(process_t proc, SecCodeRef codeRef, SecRequirementRef requirment) { - OSStatus status = SecCodeCheckValidity(proc->codeRef, kSecCSDefaultFlags, requirment); + OSStatus status = SecCodeCheckValidity(codeRef, kSecCSDefaultFlags, requirment); if (status != errSecSuccess) { os_log_debug(AUTHD_LOG, "process: PID %d code requirement check failed (%d)", proc->auditInfo.pid, (int)status); } diff --git a/OSX/authd/process.h b/OSX/authd/process.h index c4def564..3f2a0284 100644 --- a/OSX/authd/process.h +++ b/OSX/authd/process.h @@ -38,9 +38,6 @@ uint32_t process_get_count(process_t); AUTH_NONNULL_ALL const audit_info_s * process_get_audit_info(process_t); -AUTH_NONNULL_ALL -SecCodeRef process_get_code(process_t); - AUTH_NONNULL_ALL const char * process_get_code_url(process_t); @@ -84,7 +81,7 @@ AUTH_NONNULL_ALL SecRequirementRef process_get_requirement(process_t); AUTH_NONNULL_ALL -bool process_verify_requirement(process_t, SecRequirementRef); +bool process_verify_requirement(process_t, SecCodeRef, SecRequirementRef); AUTH_NONNULL_ALL bool process_apple_signed(process_t proc); diff --git a/OSX/authd/server.c b/OSX/authd/server.c index 1c29b2ec..728ae6e2 100644 --- a/OSX/authd/server.c +++ b/OSX/authd/server.c @@ -14,6 +14,7 @@ #include "debugging.h" #include "engine.h" #include "connection.h" +#include "AuthorizationTags.h" #include #include @@ -648,6 +649,18 @@ authorization_copy_info(connection_t conn, xpc_object_t message, xpc_object_t re os_log_debug(AUTHD_LOG, "server: Dumping requested AuthRef items: %{public}@", items); #endif + if (auth_items_exist(local_items, kAuthorizationEnvironmentPassword)) { + // check if caller is entitled to get the password + CFTypeRef extract_password_entitlement = process_copy_entitlement_value(proc, "com.apple.authorization.extract-password"); + if (extract_password_entitlement && (CFGetTypeID(extract_password_entitlement) == CFBooleanGetTypeID()) && extract_password_entitlement == kCFBooleanTrue) { + os_log_debug(AUTHD_LOG, "server: caller allowed to extract password"); + } else { + os_log_error(AUTHD_LOG, "server: caller NOT allowed to extract password"); + auth_items_remove(local_items, kAuthorizationEnvironmentPassword); + } + CFReleaseSafe(extract_password_entitlement); + } + //reply xpc_object_t outItems = auth_items_export_xpc(local_items); xpc_dictionary_set_value(reply, AUTH_XPC_OUT_ITEMS, outItems); diff --git a/OSX/authd/tests/authdtestlist.h b/OSX/authd/tests/authdtestlist.h index 9f43ceef..1987df61 100644 --- a/OSX/authd/tests/authdtestlist.h +++ b/OSX/authd/tests/authdtestlist.h @@ -3,3 +3,4 @@ ONE_TEST(authd_01_authorizationdb) ONE_TEST(authd_02_basicauthorization) +ONE_TEST(authd_04_executewithprivileges) diff --git a/OSX/authd/tests/authdtests.m b/OSX/authd/tests/authdtests.m index 0e1e034a..c6c45180 100644 --- a/OSX/authd/tests/authdtests.m +++ b/OSX/authd/tests/authdtests.m @@ -12,15 +12,18 @@ void runRaft(NSString *arguments); int authd_03_uiauthorization(int argc, char *const *argv); +bool getCredentials(void); #define AuthorizationFreeItemSetNull(IS) { AuthorizationItemSet *_is = (IS); \ if (_is) { (IS) = NULL; AuthorizationFreeItemSet(_is); } } #define SAMPLE_RIGHT "com.apple.security.syntheticinput" #define SAMPLE_SHARED_RIGHT "system.preferences" +#define SAMPLE_PASSWORD_RIGHT "system.csfde.requestpassword" + +NSString *correctUsername; +NSString *correctPassword; -#define CORRECT_UNAME "bats" -#define CORRECT_PWD "bats" #define INCORRECT_UNAME "fs;lgp-984-25opsdakflasdg" #define INCORRECT_PWD "654sa65gsqihr6hhsfd'lbo[0q2,m23-odasdf" @@ -31,8 +34,8 @@ if (_is) { (IS) = NULL; AuthorizationFreeItemSet(_is); } } #define RAFT_CANCEL @"target.processes()[\"SecurityAgent\"].mainWindow().buttons()[\"Cancel\"].click();quit();" AuthorizationItem validCredentials[] = { - {AGENT_USERNAME, strlen(CORRECT_UNAME), (void *)CORRECT_UNAME, 0}, - {AGENT_PASSWORD, strlen(CORRECT_PWD), (void *)CORRECT_PWD,0} + {AGENT_USERNAME, 0, NULL, 0}, + {AGENT_PASSWORD, 0, NULL, 0} }; AuthorizationItem invalidCredentials[] = { @@ -40,6 +43,29 @@ AuthorizationItem invalidCredentials[] = { {AGENT_PASSWORD, strlen(INCORRECT_PWD), (void *)INCORRECT_PWD,0} }; +bool getCredentials() +{ + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:@"/etc/credentials.plist"]; + correctUsername = dict[@"username"]; + correctPassword = dict[@"password"]; + if (correctUsername) { + validCredentials[0].value = (void *)correctUsername.UTF8String; + if (validCredentials[0].value) { + validCredentials[0].valueLength = strlen(correctUsername.UTF8String); + } + } + if (correctPassword) { + validCredentials[1].value = (void *)correctPassword.UTF8String; + if (validCredentials[1].value) { + validCredentials[1].valueLength = strlen(correctPassword.UTF8String); + } + } + }); + return (correctUsername != nil) && (correctPassword != nil); +} + void runRaft(NSString *arguments) { NSTask *task = [[NSTask alloc] init]; @@ -66,7 +92,10 @@ int authd_01_authorizationdb(int argc, char *const *argv) int authd_02_basicauthorization(int argc, char *const *argv) { - plan_tests(5); + plan_tests(6); + if (!getCredentials()) { + fail("Not able to read credentials for current user!"); + } AuthorizationRef authorizationRef; @@ -96,13 +125,40 @@ int authd_02_basicauthorization(int argc, char *const *argv) ok(status == errAuthorizationSuccess, "Extending authorization rights"); AuthorizationFreeItemSetNull(authorizedRights); - AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights); - return 0; + AuthorizationItem pwdExtractItems = {SAMPLE_PASSWORD_RIGHT, 0, NULL, 0}; + AuthorizationRights pwdExtractRight = {1, &pwdExtractItems}; + + // check that non-entitled process cannot extract password from AuthorizationRef + status = AuthorizationCopyRights(authorizationRef, &pwdExtractRight, &environment, kAuthorizationFlagExtendRights, &authorizedRights); + Boolean passwordFound = false; + if (status == errAuthorizationSuccess) { + AuthorizationItemSet *returnedInfo; + status = AuthorizationCopyInfo(authorizationRef, NULL, &returnedInfo); + if (status == errSecSuccess && returnedInfo) { + for (uint32_t index = 0; index < returnedInfo->count; ++index) { + AuthorizationItem item = returnedInfo->items[index]; + if (strncpy((char *)item.name, kAuthorizationEnvironmentPassword, strlen(kAuthorizationEnvironmentPassword)) == 0) { + passwordFound = true; + } + } + AuthorizationFreeItemSetNull(returnedInfo); + } + } + + ok(status == errAuthorizationSuccess && passwordFound == false, "Extracting password from AuthorizationRef"); + AuthorizationFreeItemSetNull(authorizedRights); + + + AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights); + return 0; } int authd_03_uiauthorization(int argc, char *const *argv) { plan_tests(3); + if (!getCredentials()) { + fail("Not able to read credentials for current user!"); + } AuthorizationRef authorizationRef; @@ -112,7 +168,7 @@ int authd_03_uiauthorization(int argc, char *const *argv) AuthorizationItem myItems = {SAMPLE_RIGHT, 0, NULL, 0}; AuthorizationRights myRights = {1, &myItems}; - NSString *raftFillValid = [NSString stringWithFormat:RAFT_FILL, CORRECT_UNAME, CORRECT_PWD]; + NSString *raftFillValid = [NSString stringWithFormat:RAFT_FILL, correctUsername.UTF8String, correctPassword.UTF8String]; dispatch_semaphore_t sem = dispatch_semaphore_create(0); /* @@ -153,3 +209,76 @@ int authd_03_uiauthorization(int argc, char *const *argv) return 0; } + +int authd_04_executewithprivileges(int argc, char *const *argv) +{ + const int NUMBER_OF_ITERATIONS = 10; + plan_tests(2 + 4 * NUMBER_OF_ITERATIONS); + + if (!getCredentials()) { + fail("Not able to read credentials for current user!"); + } + + AuthorizationRef authorizationRef; + OSStatus status = AuthorizationCreate(NULL, NULL, kAuthorizationFlagDefaults, &authorizationRef); + ok(status == errAuthorizationSuccess, "AuthorizationRef create"); + + AuthorizationItem myItems = { kAuthorizationRightExecute, 0, NULL, 0}; + AuthorizationRights myRights = {1, &myItems}; + AuthorizationRights *authorizedRights = NULL; + AuthorizationEnvironment environment = {sizeof(validCredentials)/sizeof(AuthorizationItem), validCredentials}; + status = AuthorizationCopyRights(authorizationRef, &myRights, &environment, kAuthorizationFlagExtendRights, &authorizedRights); + ok(status == errAuthorizationSuccess, "Standard authorization"); + AuthorizationFreeItemSetNull(authorizedRights); + + for (int i = 0; i < NUMBER_OF_ITERATIONS; ++i) { + NSString *guid = [[NSProcessInfo processInfo] globallyUniqueString]; + static const char *toolArgv[3]; + NSString *arg = [NSString stringWithFormat:@"%s %@", "/usr/bin/whoami && /bin/echo", guid]; + NSString *expected = [NSString stringWithFormat:@"root\n%@", guid]; + toolArgv[0] = "-c"; + toolArgv[1] = arg.UTF8String; + toolArgv[2] = NULL; + FILE *output = NULL; + + status = AuthorizationExecuteWithPrivileges(authorizationRef, "/bin/zsh", 0, (char *const *)toolArgv, &output); + ok(status == errAuthorizationSuccess, "AuthorizationExecuteWithPrivileges call succeess"); + + if (status != 0) { + break; + } + + char buffer[1024]; + size_t bytesRead = 0; + size_t totalBytesRead = 0; + size_t buffSize = sizeof(buffer); + memset(buffer, 0, buffSize); + while ((bytesRead = fread (buffer, 1, buffSize, output) > 0)) { + totalBytesRead += bytesRead; // overwriting buffer is OK since we are reading just a small amount of data + } + + ok(ferror(output) == 0, "Authorized tool pipe closed did not end with ferror"); + if (ferror(output)) { + // test failed, ferror happened + fclose(output); + return 0; + } + + ok(feof(output), "Authorized tool pipe closed with feof"); + if (!feof(output)) { + // test failed, feof not happened + fclose(output); + return 0; + } + + fclose(output); + if (strncmp(buffer, expected.UTF8String, guid.length) == 0) { + pass("Authorized tool output matches"); + } else { + fail("AuthorizationExecuteWithPrivileges output %s does not match %s", buffer, expected.UTF8String); + } + } + + AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights); + return 0; +} diff --git a/OSX/config/lib.xcconfig b/OSX/config/lib.xcconfig index 0a9bbcb5..7c298b95 100644 --- a/OSX/config/lib.xcconfig +++ b/OSX/config/lib.xcconfig @@ -5,11 +5,14 @@ EXECUTABLE_PREFIX = CODE_SIGN_IDENTITY = -HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../ $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/lib $(PROJECT_DIR)/../utilities $(PROJECT_DIR)/../../header_symlinks/macOS $(PROJECT_DIR)/../../header_symlinks/ $(inherited) +USE_HEADERMAP = YES + +HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../ $(PROJECT_DIR)/../include $(BUILT_PRODUCTS_DIR)/derived_src $(BUILT_PRODUCTS_DIR) $(PROJECT_DIR)/lib $(PROJECT_DIR)/../utilities $(inherited) +SYSTEM_HEADER_SEARCH_PATHS = $(PROJECT_DIR)/../../header_symlinks/macOS/ $(PROJECT_DIR)/../../header_symlinks/ SKIP_INSTALL = YES -ALWAYS_SEARCH_USER_PATHS = YES +ALWAYS_SEARCH_USER_PATHS = NO GCC_C_LANGUAGE_STANDARD = gnu99 diff --git a/OSX/config/security_framework_macos.xcconfig b/OSX/config/security_framework_macos.xcconfig index 09b9eb84..6aa60fd8 100644 --- a/OSX/config/security_framework_macos.xcconfig +++ b/OSX/config/security_framework_macos.xcconfig @@ -1,4 +1,5 @@ #include "OSX/config/security_macos.xcconfig" +#include "xcconfig/security_framework.xcconfig" PRODUCT_NAME = Security PRODUCT_BUNDLE_IDENTIFIER = com.apple.security @@ -11,7 +12,7 @@ DYLIB_CURRENT_VERSION = $(CURRENT_PROJECT_VERSION) MODULEMAP_FILE = Modules/Security.macOS.modulemap DEFINES_MODULE = YES -EXPORTED_SYMBOLS_FILE = $(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp +EXPORTED_SYMBOLS_FILE = $(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).exp ORDER_FILE = OSX/lib/Security.order INFOPLIST_FILE = OSX/lib/Info-Security.plist @@ -23,14 +24,12 @@ OTHER_LDFLAGS = -laks -lCrashReporterClient -Wl,-upward_framework,Foundation -Wl SECTORDER_FLAGS = -order_file_statistics APPLY_RULES_IN_COPY_FILES = NO -// Not entirely sure what this is for, but, okay. -INSTALLHDRS_SCRIPT_PHASE = YES - // Adding things here is against the spirit of TAPI. If something is in the framework, it should be in the framework headers. // Don't add things. OTHER_TAPI_FLAGS_TRUST = -extra-private-header $(PROJECT_DIR)/OSX/trustd/macOS/SecTrustOSXEntryPoints.h -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/SecCertificateInternal.h -OTHER_TAPI_FLAGS_USR_LIB_HEADERS = -extra-private-header $(PROJECT_DIR)/OSX/utilities/src/debugging.h -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_USR_LIB_HEADERS = -extra-private-header $(PROJECT_DIR)/OSX/utilities/debugging.h +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 -extra-public-header $(PROJECT_DIR)/OSX/sec/Security/SecItemShim.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) diff --git a/OSX/config/security_macos.xcconfig b/OSX/config/security_macos.xcconfig index a7acee1d..58ed08ab 100644 --- a/OSX/config/security_macos.xcconfig +++ b/OSX/config/security_macos.xcconfig @@ -5,14 +5,14 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES ALWAYS_SEARCH_USER_PATHS = NO -HEADER_SEARCH_PATHS = $(inherited) $(PROJECT_DIR)/include $(PROJECT_DIR)/sec/ProjectHeaders $(PROJECT_DIR)/utilities +HEADER_SEARCH_PATHS = $(inherited) $(PROJECT_DIR)/include $(PROJECT_DIR)/utilities LIBRARY_SEARCH_PATHS = $(inherited) /usr/lib/system STRIP_INSTALLED_PRODUCT = YES DEPLOYMENT_POSTPROCESSING = NO GCC_C_LANGUAGE_STANDARD = gnu99 -SUPPORTED_PLATFORMS = macOS +SUPPORTED_PLATFORMS = macosx GCC_TREAT_WARNINGS_AS_ERRORS = YES GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO diff --git a/OSX/lib/Security.order b/OSX/lib/Security.order index 8ee5844f..2a43b77f 100644 --- a/OSX/lib/Security.order +++ b/OSX/lib/Security.order @@ -1940,7 +1940,6 @@ _SSLProcessServerHello _sslVerifyProtVersion _FindCipherSpec _sslVerifySelectedCipher -_SSLReallocBuffer _SSLProcessCertificate _sslVerifyCertChain _sslPubKeyFromCert diff --git a/OSX/lib/en.lproj/authorization.buttons.strings b/OSX/lib/en.lproj/authorization.buttons.strings index da9a0ee6..1871c226 100644 --- a/OSX/lib/en.lproj/authorization.buttons.strings +++ b/OSX/lib/en.lproj/authorization.buttons.strings @@ -142,3 +142,4 @@ "com.apple.security.sudo" = "Allow"; +"com.apple.configurationprofiles.userenrollment.install" = "Enroll"; diff --git a/OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings b/OSX/lib/en.lproj/authorization.dfr.prompts.strings similarity index 98% rename from OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings rename to OSX/lib/en.lproj/authorization.dfr.prompts.strings index 7cb67dfb..2ee028fd 100644 --- a/OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings +++ b/OSX/lib/en.lproj/authorization.dfr.prompts.strings @@ -165,3 +165,5 @@ "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."; + +"com.apple.applepay.reset" = "Touch ID to Reset Apple Pay and add card."; diff --git a/OSX/lib/en.lproj/authorization.prompts.strings b/OSX/lib/en.lproj/authorization.prompts.strings index 932855d9..7986719b 100644 --- a/OSX/lib/en.lproj/authorization.prompts.strings +++ b/OSX/lib/en.lproj/authorization.prompts.strings @@ -167,3 +167,9 @@ "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."; + +"com.apple.applepay.reset" = "__APPNAME__ is trying to reset Apple Pay and add card."; + +"com.apple.configurationprofiles.userenrollment.install" = "__APPNAME__ is trying to enroll you in a remote management (MDM) service."; + +"com.apple.system-extensions.admin" = "__APPNAME__ is trying to modify a System Extension."; diff --git a/OSX/lib/framework.sb b/OSX/lib/framework.sb index 40425564..e37bf7c4 100644 --- a/OSX/lib/framework.sb +++ b/OSX/lib/framework.sb @@ -1,8 +1,8 @@ ;; allow clients to communicate with secd (allow mach-lookup (global-name "com.apple.secd")) ;; allow clients to communicate with coreauthd -(allow mach-lookup (global-name "com.apple.CoreAuthentication.daemon.libxpc")) -(allow mach-lookup (global-name "com.apple.CoreAuthentication.agent.libxpc")) +(allow mach-lookup (global-name "com.apple.CoreAuthentication.daemon")) +(allow mach-lookup (global-name "com.apple.CoreAuthentication.agent")) ;; allow clients to communicate with ctkd (allow mach-lookup (global-name "com.apple.ctkd.token-client")) diff --git a/OSX/lib/generateErrStrings.pl b/OSX/lib/generateErrStrings.pl index 1aa92e2b..9f9e0614 100644 --- a/OSX/lib/generateErrStrings.pl +++ b/OSX/lib/generateErrStrings.pl @@ -92,7 +92,7 @@ # # The English versions of the error messages can be seen with: # -# cat /System/Library/Frameworks/Security.framework/Resources/English.lproj/SecErrorMessages.strings +# cat /System/Library/Frameworks/Security.framework/Resources/en.lproj/SecErrorMessages.strings # # find -H -X -x . -name "*.h" -print0 2>/dev/null | xargs -0 grep -ri err # ----------------------------------------------------------------------------------- @@ -110,7 +110,7 @@ die "Usage: $0 <.strings file> \n" if ($#A $GENDEBUGSTRINGS=$ARGV[0]; # If "YES", include all strings & don't localize $TMPDIR=$ARGV[1]; # temporary directory for program compile, link, run $TARGETSTR=$ARGV[2]; # path of .strings file, e.g. - # ${DERIVED_SRC}/English.lproj/SecErrorMessages.strings + # ${DERIVED_SRC}/en.lproj/SecErrorMessages.strings @INPUTFILES=@ARGV[3 .. 9999]; # list of input files $#INPUTFILES = $#ARGV - 3; # truncate to actual number of files diff --git a/OSX/libsecurity_apple_csp/lib/AppleCSP.cpp b/OSX/libsecurity_apple_csp/lib/AppleCSP.cpp index db9a4bee..1a32f514 100644 --- a/OSX/libsecurity_apple_csp/lib/AppleCSP.cpp +++ b/OSX/libsecurity_apple_csp/lib/AppleCSP.cpp @@ -26,10 +26,6 @@ #include "cspdebugging.h" #include #include -#ifdef BSAFE_CSP_ENABLE -#include "bsafecsp.h" -#include "bsafecspi.h" -#endif #ifdef CRYPTKIT_CSP_ENABLE #include "cryptkitcsp.h" #include "FEEKeys.h" @@ -51,9 +47,6 @@ AppleCSPPlugin::AppleCSPPlugin() : normAllocator(Allocator::standard(Allocator::normal)), privAllocator(Allocator::standard(Allocator::sensitive)), - #ifdef BSAFE_CSP_ENABLE - bSafe4Factory(new BSafeFactory(&normAllocator, &privAllocator)), - #endif #ifdef CRYPTKIT_CSP_ENABLE cryptKitFactory(new CryptKitFactory(&normAllocator, &privAllocator)), #endif @@ -69,9 +62,6 @@ AppleCSPPlugin::AppleCSPPlugin() : AppleCSPPlugin::~AppleCSPPlugin() { - #ifdef BSAFE_CSP_ENABLE - delete bSafe4Factory; - #endif #ifdef CRYPTKIT_CSP_ENABLE delete cryptKitFactory; #endif @@ -128,9 +118,6 @@ AppleCSPSession::AppleCSPSession( subserviceType, attachFlags, upcalls), - #ifdef BSAFE_CSP_ENABLE - bSafe4Factory(*(dynamic_cast(plug.bSafe4Factory))), - #endif #ifdef CRYPTKIT_CSP_ENABLE cryptKitFactory(*(dynamic_cast(plug.cryptKitFactory))), #endif @@ -178,13 +165,6 @@ void AppleCSPSession::setupContext( * Note we leave the decision as to whether it's OK to * reuse a context to the individual factories. */ - #ifdef BSAFE_CSP_ENABLE - /* Give BSAFE the firsrt shot if it's present */ - if (bSafe4Factory.setup(*this, cspCtx, context)) { - CASSERT(cspCtx != NULL); - return; - } - #endif if (rsaDsaAlgFactory.setup(*this, cspCtx, context)) { CASSERT(cspCtx != NULL); return; @@ -617,14 +597,6 @@ CSPKeyInfoProvider *AppleCSPSession::infoProvider( { CSPKeyInfoProvider *provider = NULL; - #ifdef BSAFE_CSP_ENABLE - /* Give BSAFE first shot, if it's here */ - provider = BSafe::BSafeKeyInfoProvider::provider(key, *this); - if(provider != NULL) { - return provider; - } - #endif - provider = RSAKeyInfoProvider::provider(key, *this); if(provider != NULL) { return provider; diff --git a/OSX/libsecurity_apple_csp/lib/AppleCSP.h b/OSX/libsecurity_apple_csp/lib/AppleCSP.h index 513cba29..43fbcaf3 100644 --- a/OSX/libsecurity_apple_csp/lib/AppleCSP.h +++ b/OSX/libsecurity_apple_csp/lib/AppleCSP.h @@ -68,10 +68,6 @@ public: private: Allocator &normAllocator; Allocator &privAllocator; - #ifdef BSAFE_CSP_ENABLE - AppleCSPAlgorithmFactory *bSafe4Factory; // actually subclasses not visible - // in this header - #endif #ifdef CRYPTKIT_CSP_ENABLE AppleCSPAlgorithmFactory *cryptKitFactory; #endif diff --git a/OSX/libsecurity_apple_csp/lib/AppleCSPSession.h b/OSX/libsecurity_apple_csp/lib/AppleCSPSession.h index c64dbe68..58a7b03f 100644 --- a/OSX/libsecurity_apple_csp/lib/AppleCSPSession.h +++ b/OSX/libsecurity_apple_csp/lib/AppleCSPSession.h @@ -33,9 +33,6 @@ class CSPKeyInfoProvider; /* avoid unnecessary includes.... */ class AppleCSPPlugin; -#ifdef BSAFE_CSP_ENABLE -class BSafeFactory; -#endif #ifdef CRYPTKIT_CSP_ENABLE class CryptKitFactory; #endif @@ -129,9 +126,6 @@ public: Allocator &normAlloc() { return normAllocator; } Allocator &privAlloc() { return privAllocator; } - #ifdef BSAFE_CSP_ENABLE - BSafeFactory &bSafe4Factory; - #endif #ifdef CRYPTKIT_CSP_ENABLE CryptKitFactory &cryptKitFactory; #endif diff --git a/OSX/libsecurity_apple_csp/lib/BlockCryptor.cpp b/OSX/libsecurity_apple_csp/lib/BlockCryptor.cpp index 72e5e058..feed1661 100644 --- a/OSX/libsecurity_apple_csp/lib/BlockCryptor.cpp +++ b/OSX/libsecurity_apple_csp/lib/BlockCryptor.cpp @@ -317,7 +317,7 @@ void BlockCryptor::update( /* * en/decrypt even blocks in (remaining) inp. */ - size_t leftOver = uInSize % mInBlockSize; + size_t leftOver = (mInBlockSize > 0) ? uInSize % mInBlockSize : 0; if((leftOver == 0) && needLeftOver) { /* * Even blocks coming in, but we really need to leave some data @@ -327,7 +327,7 @@ void BlockCryptor::update( leftOver = mInBlockSize; } toMove = uInSize - leftOver; - size_t blocks = toMove / mInBlockSize; + size_t blocks = (mInBlockSize > 0) ? toMove / mInBlockSize : 0; if(mMultiBlockCapable && !doCbc && (blocks != 0)) { /* * Optimization for algorithms that are multi-block capable and that diff --git a/OSX/libsecurity_apple_csp/lib/YarrowConnection.cpp b/OSX/libsecurity_apple_csp/lib/YarrowConnection.cpp index e6a8da60..b83a4cfd 100644 --- a/OSX/libsecurity_apple_csp/lib/YarrowConnection.cpp +++ b/OSX/libsecurity_apple_csp/lib/YarrowConnection.cpp @@ -21,28 +21,16 @@ */ #include "YarrowConnection.h" #include -#include #include - -/* instantiated by C++ runtime at library load/init time */ -class YarrowConnection : public DevRandomGenerator { -public: - YarrowConnection() : DevRandomGenerator(getuid() == 0), writable(getuid() == 0) { } - const bool writable; -}; - -/* the single global thing */ -static ModuleNexus yarrowConnection; - +#include /* and the exported functions */ void cspGetRandomBytes(void *buf, unsigned len) { - yarrowConnection().random(buf, len); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, len, buf)); } +/* Unused, since SecRandomCopyBytes returns from a suitable CSPRNG seeded elsewhere */ void cspAddEntropy(const void *buf, unsigned len) { - if (yarrowConnection().writable) - yarrowConnection().addEntropy(buf, len); } diff --git a/OSX/libsecurity_apple_csp/lib/algmaker.cpp b/OSX/libsecurity_apple_csp/lib/algmaker.cpp deleted file mode 100644 index 9b672903..00000000 --- a/OSX/libsecurity_apple_csp/lib/algmaker.cpp +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// algmaker - algorithm factory for BSafe 4 -// -#include "bsafecspi.h" -#include "bsafecsp.h" -#include "AppleCSPSession.h" - -// -// BSafe's Chooser table. -// These are references to all *BSafe algorithms* we use (and thus must link in) -// -const B_ALGORITHM_METHOD * const BSafe::bsChooser[] = { - // digests - &AM_SHA, - &AM_MD5, - &AM_MD2, - - // organizational - &AM_CBC_ENCRYPT, - &AM_CBC_DECRYPT, - &AM_ECB_ENCRYPT, - &AM_ECB_DECRYPT, - &AM_OFB_ENCRYPT, - &AM_OFB_DECRYPT, - - // DES & variants - &AM_DES_ENCRYPT, - &AM_DES_DECRYPT, - &AM_DESX_ENCRYPT, - &AM_DESX_DECRYPT, - &AM_DES_EDE_ENCRYPT, - &AM_DES_EDE_DECRYPT, - - // RCn stuff - &AM_RC2_CBC_ENCRYPT, - &AM_RC2_CBC_DECRYPT, - &AM_RC2_ENCRYPT, - &AM_RC2_DECRYPT, - &AM_RC4_ENCRYPT, - &AM_RC4_DECRYPT, - &AM_RC5_ENCRYPT, - &AM_RC5_DECRYPT, - &AM_RC5_CBC_ENCRYPT, - &AM_RC5_CBC_DECRYPT, - - // RSA - &AM_RSA_STRONG_KEY_GEN, - &AM_RSA_KEY_GEN, - &AM_RSA_CRT_ENCRYPT_BLIND, - &AM_RSA_CRT_DECRYPT_BLIND, - &AM_RSA_ENCRYPT, - &AM_RSA_DECRYPT, - - // DSA - &AM_DSA_PARAM_GEN, - &AM_DSA_KEY_GEN, - - // signatures - &AM_DSA_SIGN, - &AM_DSA_VERIFY, - - // random number generation - &AM_MD5_RANDOM, - &AM_SHA_RANDOM, - - // sentinel - (B_ALGORITHM_METHOD *)NULL_PTR -}; - - -// -// Makers -// -template -class Maker0 : public BSafe::MakerBase { -public: - Ctx *make(AppleCSPSession &session, const Context &context) const - { return new Ctx(session, context); } -}; - -template -class Maker1 : public BSafe::MakerBase { - Arg arg; -public: - Maker1(Arg a) : arg(a) { } - Ctx *make(AppleCSPSession &session, const Context &context) const - { return new Ctx(session, context, arg); } -}; - -template -class Maker2 : public BSafe::MakerBase { - Arg1 arg1; Arg2 arg2; -public: - Maker2(Arg1 a1, Arg2 a2) : arg1(a1), arg2(a2) { } - Ctx *make(AppleCSPSession &session, const Context &context) const - { return new Ctx(session, context, arg1, arg2); } -}; - -template -class Maker3 : public BSafe::MakerBase { - Arg1 arg1; Arg2 arg2; Arg3 arg3; -public: - Maker3(Arg1 a1, Arg2 a2, Arg3 a3) : - arg1(a1), arg2(a2), arg3(a3) { } - Ctx *make(AppleCSPSession &session, const Context &context) const - { return new Ctx(session, context, arg1, arg2, arg3); } -}; - - -bug_const BSafe::MakerTable BSafe::algorithms[] = { - // signing algorithms - // constructor args: BSafe algorithm, signature size - { - CSSM_ALGID_SHA1WithDSA, - CSSM_ALGCLASS_SIGNATURE, - new Maker2 - (AI_DSAWithSHA1, 48) // max size of 48 bytes - }, - { - CSSM_ALGID_SHA1WithRSA, - CSSM_ALGCLASS_SIGNATURE, - new Maker2 - (AI_SHA1WithRSAEncryption, 0) // size = RSA key size - }, - - { - CSSM_ALGID_MD5WithRSA, - CSSM_ALGCLASS_SIGNATURE, - new Maker2 - (AI_MD5WithRSAEncryption, 0) // size = RSA key size - }, - - { - CSSM_ALGID_MD2WithRSA, - CSSM_ALGCLASS_SIGNATURE, - new Maker2 - (AI_MD2WithRSAEncryption, 0) // size = RSA key size - }, - - // MAC algorithms - // constructor args: BSafe algorithm, signature size - { - CSSM_ALGID_SHA1HMAC, - CSSM_ALGCLASS_MAC, - new Maker2 - (AI_SHA1, 20) - }, - - // symmetric key generation - // constructor args: min/max key size in bits, mustBeByteSized - { - CSSM_ALGID_RC2, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (1*8, 128*8, true) - }, - { - CSSM_ALGID_RC4, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (1*8, 256*8, true) - }, - { - CSSM_ALGID_RC5, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (1*8, 255*8, true) - }, - { - CSSM_ALGID_DES, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (64, 64, true) - }, - { - CSSM_ALGID_DESX, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (192, 192, true) - }, - { - CSSM_ALGID_3DES_3KEY, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (192, 192, true) - }, - { - CSSM_ALGID_SHA1HMAC, - CSSM_ALGCLASS_KEYGEN, - new Maker3 - (160, 2048, true) - }, - - // symmetric encryption algorithms - // constructor arg: block size (1 ==> stream cipher) - { - CSSM_ALGID_DES, - CSSM_ALGCLASS_SYMMETRIC, - new Maker1(8) - }, - { - CSSM_ALGID_DESX, - CSSM_ALGCLASS_SYMMETRIC, - new Maker1(8) - }, - { - CSSM_ALGID_3DES_3KEY_EDE, - CSSM_ALGCLASS_SYMMETRIC, - new Maker1(8) - }, - { - CSSM_ALGID_RC2, - CSSM_ALGCLASS_SYMMETRIC, - new Maker1(8) - }, - { - CSSM_ALGID_RC4, - CSSM_ALGCLASS_SYMMETRIC, - new Maker1(1) - }, - { - CSSM_ALGID_RC5, - CSSM_ALGCLASS_SYMMETRIC, - new Maker1(8) - }, - - // asymmetric encryption algorithms - { - CSSM_ALGID_RSA, - CSSM_ALGCLASS_ASYMMETRIC, - new Maker0() - }, - { - CSSM_ALGID_DSA, - CSSM_ALGCLASS_ASYMMETRIC, - new Maker0() - }, - - // key pair generate algorithms - { - CSSM_ALGID_RSA, - CSSM_ALGCLASS_KEYGEN, - new Maker0() - }, - { - CSSM_ALGID_DSA, - CSSM_ALGCLASS_KEYGEN, - new Maker0() - }, - - // pseudo-random number generators - { - CSSM_ALGID_MD5Random, - CSSM_ALGCLASS_RANDOMGEN, - new Maker1(AI_MD5Random) - }, - { - CSSM_ALGID_SHARandom, - CSSM_ALGCLASS_RANDOMGEN, - new Maker1(AI_SHA1Random) - }, -}; - -const unsigned int BSafe::algorithmCount = sizeof(algorithms) / sizeof(algorithms[0]); - - -// -// BSafeFactory hookup -// -void BSafeFactory::setNormAllocator(Allocator *alloc) -{ - BSafe::setNormAllocator(alloc); -} -void BSafeFactory::setPrivAllocator(Allocator *alloc) -{ - BSafe::setPrivAllocator(alloc); -} - -bool BSafeFactory::setup( - AppleCSPSession &session, - CSPFullPluginSession::CSPContext * &cspCtx, - const Context &context) -{ - return BSafe::setup(session, cspCtx, context); -} - - -// -// Algorithm setup -// -bool BSafe::setup( - AppleCSPSession &session, - CSPFullPluginSession::CSPContext * &cspCtx, - const Context &context) -{ - for (const BSafe::MakerTable *alg = algorithms; - alg < algorithms + algorithmCount; - alg++) { - if ((alg->algorithmId == context.algorithm()) && - (alg->algClass == context.type())) { - if(cspCtx != NULL) { - /* we allow reuse */ - return true; - } - // make new context - cspCtx = alg->maker->make(session, context); - return true; - } - } - /* not ours */ - return false; -} -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/bsafeAsymmetric.cpp b/OSX/libsecurity_apple_csp/lib/bsafeAsymmetric.cpp deleted file mode 100644 index e9b06e93..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafeAsymmetric.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsafeAsymmetric.cpp - asymmetric encrypt/decrypt -// -#include "bsafecspi.h" - -#include // debug - -// -// Public key {en,de}cryption (currently RSA only) -// -// FIXME: -// We really should match the key algorithm to the en/decrypt -// algorithm. Also: verify key usage bits. -void BSafe::PublicKeyCipherContext::init(const Context &context, bool encrypting) -{ - assert(context.algorithm() == CSSM_ALGID_RSA); - - if (reusing(encrypting)) - return; // all set to go - - switch (context.getInt(CSSM_ATTRIBUTE_MODE)) { - case CSSM_ALGMODE_PUBLIC_KEY: - setAlgorithm(AI_PKCS_RSAPublic); - break; - case CSSM_ALGMODE_PRIVATE_KEY: - setAlgorithm(AI_PKCS_RSAPrivate); - break; - case CSSM_ALGMODE_NONE: - { - /* - * None specified (getInt returns zero in that case) - - * infer from key type - */ - CssmKey &key = context.get( - CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY); - B_INFO_TYPE bAlgType; - switch (key.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - bAlgType = AI_PKCS_RSAPublic; - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - bAlgType = AI_PKCS_RSAPrivate; - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - setAlgorithm(bAlgType); - break; - } - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE); - } - - // put it all together - setKeyFromContext(context); // set BSafe key - setRandom(); // some PK cryption algs need random input - cipherInit(); // common cipher init - //@@@ calculate output buffer size -} - -// we assume asymmetric crypto algorithms are one-shot output non-repeating - -size_t BSafe::PublicKeyCipherContext::inputSize(size_t outSize) -{ - return 0xFFFFFFFF; // perhaps not the biggest size_t, but big enough... -} -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/bsafeContext.cpp b/OSX/libsecurity_apple_csp/lib/bsafeContext.cpp deleted file mode 100644 index e69c8bd8..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafeContext.cpp +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsafeContext.cpp - implementation of class BSafe::BSafeContext -// and some of its subclasses -// - -#include "bsafecspi.h" -#include "bsafePKCS1.h" -#include -#include -#include -#include "cspdebugging.h" - -#define DATA(cData) POINTER(cData.data()), cData.length() - -A_SURRENDER_CTX * const BSafe::BSafeContext::bsSurrender = NULL; - - -// -// Construct an algorithm object -// -BSafe::BSafeContext::BSafeContext(AppleCSPSession &session) - : AppleCSPContext(session) -{ - bsAlgorithm = NULL; - bsKey = NULL; - bsBinKey = NULL; - bsRandom = NULL; - initialized = false; - opStarted = false; -#ifdef SAFER - inUpdate = NULL; - inOutUpdate = NULL; - inFinal = NULL; - outFinal = NULL; - outFinalR = NULL; -#endif //SAFER -} - -BSafe::BSafeContext::~BSafeContext() -{ - reset(); -} - -void BSafe::BSafeContext::reset() -{ - B_DestroyAlgorithmObject(&bsAlgorithm); - B_DestroyAlgorithmObject(&bsRandom); - destroyBsKey(); -} - -/* - * Clear key state. We only destroy bsKey if we don't have a - * BinaryKey. - */ -void BSafe::BSafeContext::destroyBsKey() -{ - if(bsBinKey == NULL) { - B_DestroyKeyObject(&bsKey); - } - else { - // bsKey gets destroyed when bsBinKey gets deleted - bsBinKey = NULL; - bsKey = NULL; - } -} - -void BSafe::check(int status, bool isKeyOp) -{ - if(status == 0) { - return; - } - dprintf1("BSAFE Error %d\n", status); - switch (status) { - case BE_ALLOC: - throw std::bad_alloc(); - case BE_SIGNATURE: - CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); - case BE_OUTPUT_LEN: - CssmError::throwMe(CSSMERR_CSP_OUTPUT_LENGTH_ERROR); - case BE_INPUT_LEN: - CssmError::throwMe(CSSMERR_CSP_INPUT_LENGTH_ERROR); - case BE_EXPONENT_EVEN: - case BE_EXPONENT_LEN: - case BE_EXPONENT_ONE: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - case BE_DATA: - case BE_INPUT_DATA: - if(isKeyOp) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - else { - CssmError::throwMe(CSSMERR_CSP_INVALID_DATA); - } - case BE_MODULUS_LEN: - case BE_OVER_32K: - case BE_INPUT_COUNT: - case BE_CANCEL: - //@@@ later... - default: - //@@@ translate BSafe errors intelligently - CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR); - } -} - - -void BSafe::BSafeContext::setAlgorithm( - B_INFO_TYPE bAlgType, - const void *info) -{ - B_DestroyAlgorithmObject(&bsAlgorithm); // clear any old BSafe algorithm - check(B_CreateAlgorithmObject(&bsAlgorithm)); - check(B_SetAlgorithmInfo(bsAlgorithm, bAlgType, POINTER(info))); -} - -/* safely create bsKey */ -void BSafe::BSafeContext::createBsKey() -{ - /* reset to initial key state - some keys can't be reused */ - destroyBsKey(); - check(B_CreateKeyObject(&bsKey)); -} - -/* form of *info varies per bKeyInfo */ -void BSafe::BSafeContext::setKeyAtom( - B_INFO_TYPE bKeyInfo, - const void *info) -{ - /* debug only */ - if((bKeyInfo == KI_RSAPublicBER) || (bKeyInfo == KI_RSAPublic)) { - printf("Aargh! Unhandled KI_RSAPublic!\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - assert(bKeyInfo != KI_RSAPublicBER); // handled elsewhere for now - assert(bKeyInfo != KI_RSAPublic); // handled elsewhere for now - createBsKey(); - check(B_SetKeyInfo(bsKey, bKeyInfo, POINTER(info)), true); -} - -// -// Set outSize for RSA keys. -// -void BSafe::BSafeContext::setRsaOutSize( - bool isPubKey) -{ - assert(bsKey != NULL); - - A_RSA_KEY *keyInfo; - if(isPubKey) { - keyInfo = getKey(bsKey, KI_RSAPublic); - } - else { - keyInfo = getKey(bsKey, KI_RSAPrivate); - } - mOutSize = (B_IntegerBits(keyInfo->modulus.data, - keyInfo->modulus.len) + 7) / 8; -} - -// -// Handle various forms of reference key. Symmetric -// keys are stored as SymmetricBinaryKey, with raw key bytes -// in keyData. Our asymmetric keys are stored as BSafeBinaryKeys, -// with an embedded ready-to-use B_KEY_OBJ. -// -void BSafe::BSafeContext::setRefKey(CssmKey &key) -{ - bool isPubKey = false; - - switch(key.keyClass()) { - case CSSM_KEYCLASS_SESSION_KEY: - { - assert(key.blobFormat() == - CSSM_KEYBLOB_REF_FORMAT_INTEGER); - - BinaryKey &binKey = session().lookupRefKey(key); - // fails if this is not a SymmetricBinaryKey - SymmetricBinaryKey *symBinKey = - dynamic_cast(&binKey); - if(symBinKey == NULL) { - errorLog0("BSafe::setRefKey(1): wrong BinaryKey subclass\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - setKeyFromCssmData(KI_Item, symBinKey->mKeyData); - return; - } - case CSSM_KEYCLASS_PUBLIC_KEY: - isPubKey = true; // and fall thru - case CSSM_KEYCLASS_PRIVATE_KEY: - { - BinaryKey &binKey = session().lookupRefKey(key); - destroyBsKey(); - bsBinKey = dynamic_cast(&binKey); - /* this cast failing means that this is some other - * kind of binary key */ - if(bsBinKey == NULL) { - errorLog0("BSafe::setRefKey(2): wrong BinaryKey subclass\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - assert(bsBinKey->bsKey() != NULL); - bsKey = bsBinKey->bsKey(); - if(key.algorithm() == CSSM_ALGID_RSA) { - setRsaOutSize(isPubKey); - } - return; - } - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } -} - -void BSafe::BSafeContext::setKeyFromContext( - const Context &context, - bool required) -{ - CssmKey &key = - context.get(CSSM_ATTRIBUTE_KEY, CSSMERR_CSP_MISSING_ATTR_KEY); - - switch(key.blobType()) { - case CSSM_KEYBLOB_REFERENCE: - setRefKey(key); - return; - case CSSM_KEYBLOB_RAW: - break; // to main routine - default: - CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT); - } - - bool isPubKey; - switch (key.keyClass()) { - case CSSM_KEYCLASS_SESSION_KEY: - /* symmetric, one format supported for all algs */ - switch (key.blobFormat()) { - case CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING: - setKeyFromCssmKey(KI_Item, key); - return; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - case CSSM_KEYCLASS_PUBLIC_KEY: - isPubKey = true; - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - isPubKey = false; - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - - /* We know it's an asymmetric key; get some info */ - B_INFO_TYPE infoType; - CSSM_KEYBLOB_FORMAT expectedFormat; - - if(!bsafeAlgToInfoType(key.algorithm(), - isPubKey, - infoType, - expectedFormat)) { - /* unknown alg! */ - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - - /* - * Correct format? - * NOTE: if we end up supporting multiple incoming key formats, they'll - * have to be handled here. - */ - if(expectedFormat != key.blobFormat()) { - errorLog1("setKeyFromContext: invalid blob format (%d)\n", - (int)key.blobFormat()); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - - /* - * Most formats can be handled directly by BSAFE. Handle the special cases - * requiring additional processing here. - */ - switch(expectedFormat) { - case CSSM_KEYBLOB_RAW_FORMAT_PKCS1: - /* RSA public keys */ - createBsKey(); - BS_setKeyPkcs1(CssmData::overlay(key.KeyData), bsKey); - break; - default: - setKeyFromCssmKey(infoType, key); - break; - } - - /* - * One more thing - set mOutSize for RSA keys - */ - if(key.algorithm() == CSSM_ALGID_RSA) { - setRsaOutSize(isPubKey); - } -} - -#define BSAFE_RANDSIZE 32 - -void BSafe::BSafeContext::setRandom() -{ - if (bsRandom == NULL) { - check(B_CreateAlgorithmObject(&bsRandom)); - check(B_SetAlgorithmInfo(bsRandom, AI_X962Random_V0, NULL_PTR)); - check(B_RandomInit(bsRandom, chooser(), bsSurrender)); - uint8 seed[BSAFE_RANDSIZE]; - session().getRandomBytes(BSAFE_RANDSIZE, seed); - check(B_RandomUpdate(bsRandom, seed, sizeof(seed), bsSurrender)); - } -} - - -// -// Operational methods of BSafeContext -// -void BSafe::BSafeContext::init(const Context &, bool) -{ - // some algorithms don't need init(), because all is done in the context constructor -} - -// update for input-only block/stream algorithms -void BSafe::BSafeContext::update(const CssmData &data) -{ - opStarted = true; - check(inUpdate(bsAlgorithm, POINTER(data.data()), data.length(), bsSurrender)); -} - -// update for input/output block/stream algorithms -void BSafe::BSafeContext::update(void *inp, size_t &inSize, void *outp, size_t &outSize) -{ - unsigned int length; - opStarted = true; - check(inOutUpdate(bsAlgorithm, POINTER(outp), &length, outSize, - POINTER(inp), inSize, bsRandom, bsSurrender)); - // always eat all input (inSize unchanged) - outSize = length; - - // let the algorithm manager track I/O sizes, if needed - trackUpdate(inSize, outSize); -} - -// output-generating final call -void BSafe::BSafeContext::final(CssmData &out) -{ - unsigned int length; - if (outFinal) { - check(outFinal(bsAlgorithm, - POINTER(out.data()), - &length, - out.length(), - bsSurrender)); - } - else { - check(outFinalR(bsAlgorithm, - POINTER(out.data()), - &length, - out.length(), - bsRandom, - bsSurrender)); - } - out.length(length); - initialized = false; -} - -// verifying final call (takes additional input) -void BSafe::BSafeContext::final(const CssmData &in) -{ - int status; - - /* note sig verify errors can show up as lots of BSAFE statuses; - * munge them all into the appropriate error */ - if (inFinal) { - status = inFinal(bsAlgorithm, - POINTER(in.data()), - in.length(), - bsSurrender); - } - else { - status = inFinalR(bsAlgorithm, - POINTER(in.data()), - in.length(), - bsRandom, - bsSurrender); - } - if(status != 0) { - if((mType == CSSM_ALGCLASS_SIGNATURE) && (mDirection == false)) { - /* yep, sig verify error */ - CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); - } - /* other error, use standard trap */ - check(status); - } - initialized = false; -} - -size_t BSafe::BSafeContext::outputSize(bool final, size_t inSize) -{ - // this default implementation only makes sense for single-output end-loaded algorithms - return final ? mOutSize : 0; -} - -void BSafe::BSafeContext::trackUpdate(size_t, size_t) -{ /* do nothing */ } - -// -// Common features of CipherContexts. -// -void BSafe::CipherContext::cipherInit() -{ - // set handlers - if (encoding) { - inOutUpdate = B_EncryptUpdate; - outFinalR = B_EncryptFinal; - } else { - inOutUpdate = B_DecryptUpdate; - outFinalR = B_DecryptFinal; - } - outFinal = NULL; - - // init the algorithm - check((encoding ? B_EncryptInit : B_DecryptInit) - (bsAlgorithm, bsKey, chooser(), bsSurrender)); - - // buffers start empty - pending = 0; - - // state is now valid - initialized = true; - opStarted = false; -} -#endif /* BSAFE_CSP_ENABLE */ - diff --git a/OSX/libsecurity_apple_csp/lib/bsafeKeyGen.cpp b/OSX/libsecurity_apple_csp/lib/bsafeKeyGen.cpp deleted file mode 100644 index 2e5391ff..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafeKeyGen.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsafeKeyGen.cpp - key generation routines -// -#include "bsafecspi.h" -#include "bsafePKCS1.h" -#include "cspdebugging.h" - -/* - * Stateless, private function to map a CSSM alg and pub/priv state - * to B_INFO_TYPE and format. Returns true on success, false on - * "I don't understand this algorithm". - */ -bool BSafe::bsafeAlgToInfoType( - CSSM_ALGORITHMS alg, - bool isPublic, - B_INFO_TYPE &infoType, // RETURNED - CSSM_KEYBLOB_FORMAT &format) // RETURNED -{ - switch(alg) { - case CSSM_ALGID_RSA: - if(isPublic) { - infoType = RSA_PUB_KEYINFO_TYPE; - format = CSSM_KEYBLOB_RAW_FORMAT_PKCS1; - } - else { - infoType = RSA_PRIV_KEYINFO_TYPE; - format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; - } - return true; - case CSSM_ALGID_DSA: - format = CSSM_KEYBLOB_RAW_FORMAT_FIPS186; - if(isPublic) { - infoType = DSA_PUB_KEYINFO_TYPE; - } - else { - infoType = DSA_PRIV_KEYINFO_TYPE; - } - return true; - default: - return false; - } -} - - -BSafe::BSafeBinaryKey::BSafeBinaryKey( - bool isPub, - uint32 Alg) - : mIsPublic(isPub), - mAlg(Alg) -{ - BSafe::check(B_CreateKeyObject(&mBsKey), true); -} - -BSafe::BSafeBinaryKey::~BSafeBinaryKey() -{ - B_DestroyKeyObject(&mBsKey); -} - -void BSafe::BSafeBinaryKey::generateKeyBlob( - Allocator &allocator, - CssmData &blob, - CSSM_KEYBLOB_FORMAT &format, // input val ignored for now - AppleCSPSession &session, - const CssmKey *paramKey, // optional, unused here - CSSM_KEYATTR_FLAGS &attrFlags) // IN/OUT -{ - assert(mBsKey != NULL); - - B_INFO_TYPE bsType; - if(!bsafeAlgToInfoType(mAlg, mIsPublic, bsType, format)) { - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - if(format == CSSM_KEYBLOB_RAW_FORMAT_PKCS1) { - /* special case, encode the PKCS1 format blob */ - CssmRemoteData rData( - Allocator::standard(Allocator::sensitive), blob); - BS_GetKeyPkcs1(mBsKey, rData); - rData.release(); - } - else { - BSafeItem *info; - BSafe::check( - B_GetKeyInfo((POINTER *)&info, mBsKey, bsType), true); - blob = info->copy(allocator); - } -} - -// -// This is called from CSPFullPluginSession -// -void BSafe::BSafeKeyPairGenContext::generate( - const Context &context, - CssmKey &pubKey, - CssmKey &privKey) -{ - BSafeBinaryKey *pubBinKey = new BSafeBinaryKey(true, - context.algorithm()); - BSafeBinaryKey *privBinKey = new BSafeBinaryKey(false, - context.algorithm()); - - try { - AppleKeyPairGenContext::generate(context, - session(), - pubKey, - pubBinKey, - privKey, - privBinKey); - } - catch (...) { - delete pubBinKey; - delete privBinKey; - throw; - } -} - -// -// Called from AppleKeyPairGenContext -// -void BSafe::BSafeKeyPairGenContext::generate( - const Context &context, - BinaryKey &pubBinKey, // valid on successful return - BinaryKey &privBinKey, // ditto - uint32 &keySize) // ditto -{ - /* these casts throw exceptions if the keys are of the - * wrong classes, which is a major bogon, since we created - * the keys in the above generate() function */ - BSafeBinaryKey &bsPubBinKey = - dynamic_cast(pubBinKey); - BSafeBinaryKey &bsPrivBinKey = - dynamic_cast(privBinKey); - - if (!initialized) { - setupAlgorithm(context, keySize); - check(B_GenerateInit(bsAlgorithm, chooser(), bsSurrender), true); - initialized = true; - } - - setRandom(); - check(B_GenerateKeypair(bsAlgorithm, - bsPubBinKey.bsKey(), - bsPrivBinKey.bsKey(), - bsRandom, - bsSurrender), true); -} - -void BSafe::BSafeKeyPairGenContext::setupAlgorithm( - const Context &context, - uint32 &keySize) -{ - switch(context.algorithm()) { - case CSSM_ALGID_RSA: - { - A_RSA_KEY_GEN_PARAMS genParams; - keySize = genParams.modulusBits = - context.getInt(CSSM_ATTRIBUTE_KEY_LENGTH, - CSSMERR_CSP_INVALID_ATTR_KEY_LENGTH); - if (CssmData *params = - context.get(CSSM_ATTRIBUTE_ALG_PARAMS)) { - genParams.publicExponent = BSafeItem(*params); - } else { - static unsigned char exponent[] = { 1, 0, 1 }; - genParams.publicExponent = BSafeItem(exponent, sizeof(exponent)); - } - /* - * For test purposes, we avoid the 'strong' key generate - * algorithm if a CSSM_ALGMODE_CUSTOM mode atrtribute - * is present in the context. This is not published and - * not supported in the real world. - */ - uint32 mode = context.getInt(CSSM_ATTRIBUTE_MODE); - if(mode == CSSM_ALGMODE_CUSTOM) { - setAlgorithm(AI_RSAKeyGen, &genParams); - } - else { - setAlgorithm(AI_RSAStrongKeyGen, &genParams); - } - } - break; - case CSSM_ALGID_DSA: - { - A_DSA_PARAMS genParams; - genParams.prime = - BSafeItem(context.get( - CSSM_ATTRIBUTE_PRIME, - CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS)); - genParams.subPrime = - BSafeItem(context.get( - CSSM_ATTRIBUTE_SUBPRIME, - CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS)); - genParams.base = - BSafeItem(context.get( - CSSM_ATTRIBUTE_BASE, - CSSMERR_CSP_MISSING_ATTR_ALG_PARAMS)); - setAlgorithm(AI_DSAKeyGen, &genParams); - keySize = B_IntegerBits(genParams.prime.data, genParams.prime.len); - } - break; - default: - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } -} - -// -// DSA Parameter Generation -// -void BSafe::BSafeKeyPairGenContext::generate( - const Context &context, - uint32 bitSize, - CssmData ¶ms, - uint32 &attrCount, - Context::Attr * &attrs) -{ - assert(context.algorithm() == CSSM_ALGID_DSA); - - B_ALGORITHM_OBJ genAlg = NULL; - B_ALGORITHM_OBJ result = NULL; - - try { - check(B_CreateAlgorithmObject(&genAlg)); - - B_DSA_PARAM_GEN_PARAMS genParams; - genParams.primeBits = bitSize; - check(B_SetAlgorithmInfo(genAlg, AI_DSAParamGen, POINTER(&genParams))); - setRandom(); - check(B_GenerateInit(genAlg, chooser(), bsSurrender), true); - check(B_CreateAlgorithmObject(&result)); - check(B_GenerateParameters(genAlg, result, bsRandom, bsSurrender)); - - // get parameters out of algorithm object - A_DSA_PARAMS *kParams = NULL; - check(B_GetAlgorithmInfo((POINTER *)&kParams, result, AI_DSAKeyGen), true); - - // shred them into context attribute form - attrs = normAllocator->alloc(3); - attrs[0] = Context::Attr(CSSM_ATTRIBUTE_PRIME, - *BSafeItem(kParams->prime).copyp(*normAllocator)); - attrs[1] = Context::Attr(CSSM_ATTRIBUTE_SUBPRIME, - *BSafeItem(kParams->subPrime).copyp(*normAllocator)); - attrs[2] = Context::Attr(CSSM_ATTRIBUTE_BASE, - *BSafeItem(kParams->base).copyp(*normAllocator)); - attrCount = 3; - - // clean up - B_DestroyAlgorithmObject(&result); - B_DestroyAlgorithmObject(&genAlg); - } catch (...) { - // clean up - B_DestroyAlgorithmObject(&result); - B_DestroyAlgorithmObject(&genAlg); - throw; - } -} - -/* - * CSPKeyInfoProvider for asymmetric BSAFE keys. - */ -BSafe::BSafeKeyInfoProvider::BSafeKeyInfoProvider( - const CssmKey &cssmKey, - AppleCSPSession &session) : - CSPKeyInfoProvider(cssmKey, session) -{ -} - -CSPKeyInfoProvider *BSafe::BSafeKeyInfoProvider::provider( - const CssmKey &cssmKey, - AppleCSPSession &session) -{ - switch(cssmKey.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - case CSSM_KEYCLASS_PRIVATE_KEY: - break; - default: - return NULL; - } - switch(mKey.algorithm()) { - case CSSM_ALGID_RSA: - case CSSM_ALGID_DSA: - break; - default: - return NULL; - } - /* OK, we'll handle this one */ - return new BSafeKeyInfoProvider(cssmKey, session); -} - -/* cook up a Binary key */ -void BSafe::BSafeKeyInfoProvider::CssmKeyToBinary( - CssmKey *paramKey, // optional, ignored - CSSM_KEYATTR_FLAGS &attrFlags, // IN/OUT - BinaryKey **binKey) -{ - *binKey = NULL; - - const CSSM_KEYHEADER *hdr = &mKey.KeyHeader; - assert(hdr->BlobType == CSSM_KEYBLOB_RAW); - - B_INFO_TYPE bsType; - CSSM_KEYBLOB_FORMAT format; - bool isPub; - - switch(hdr->KeyClass) { - case CSSM_KEYCLASS_PUBLIC_KEY: - isPub = true; - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - isPub = false; - break; - default: - // someone else's key - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - if(!bsafeAlgToInfoType(hdr->AlgorithmId, isPub, bsType, format)) { - // someone else's key - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } - if(hdr->Format != format) { - dprintf0("BSafe::cssmKeyToBinary: format mismatch\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - - BSafeBinaryKey *bsBinKey = new BSafeBinaryKey(isPub, - hdr->AlgorithmId); - - // set up key material as appropriate - if(format == CSSM_KEYBLOB_RAW_FORMAT_PKCS1) { - /* special case, decode the PKCS1 format blob */ - BS_setKeyPkcs1(mKey, bsBinKey->bsKey()); - } - else { - /* normal case, use key blob as is */ - BSafeItem item(mKey.KeyData); - BSafe::check( - B_SetKeyInfo(bsBinKey->bsKey(), bsType, POINTER(&item)), true); - } - *binKey = bsBinKey; -} - -/* - * Obtain key size in bits. - */ -void BSafe::BSafeKeyInfoProvider::QueryKeySizeInBits( - CSSM_KEY_SIZE &keySize) -{ - if(mKey.blobType() != CSSM_KEYBLOB_RAW) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - - /* cook up BSAFE key */ - B_KEY_OBJ bKey; - A_RSA_KEY *rsaKeyInfo = NULL; - A_DSA_PUBLIC_KEY *dsaPubKeyInfo = NULL; - A_DSA_PRIVATE_KEY *dsaPrivKeyInfo = NULL; - ITEM *sizeItem = NULL; - BSafe::check(B_CreateKeyObject(&bKey), true); - B_INFO_TYPE infoType; - - switch(mKey.algorithm()) { - case CSSM_ALGID_RSA: - switch(mKey.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - if(mKey.blobFormat() != - CSSM_KEYBLOB_RAW_FORMAT_PKCS1) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - - /* convert from PKCS1 blob to raw key */ - BS_setKeyPkcs1(mKey, bKey); - infoType = KI_RSAPublic; - /* break to common RSA code */ - break; - case CSSM_KEYCLASS_PRIVATE_KEY: - { - if(mKey.blobFormat() != - CSSM_KEYBLOB_RAW_FORMAT_PKCS8) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - - /* convert from PKCS8 blob to raw key */ - BSafeItem item(mKey.KeyData); - BSafe::check( - B_SetKeyInfo(bKey, KI_PKCS_RSAPrivateBER, - POINTER(&item)), true); - infoType = KI_RSAPrivate; - break; - } - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - rsaKeyInfo = getKey(bKey, infoType); - sizeItem = &rsaKeyInfo->modulus; - break; - - case CSSM_ALGID_DSA: - /* untested as of 9/11/00 */ - if(mKey.blobFormat() != - CSSM_KEYBLOB_RAW_FORMAT_FIPS186) { - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_FORMAT); - } - switch(mKey.keyClass()) { - case CSSM_KEYCLASS_PUBLIC_KEY: - { - BSafeItem item(mKey.KeyData); - BSafe::check(B_SetKeyInfo(bKey, - DSA_PUB_KEYINFO_TYPE, - (POINTER)&item), true); - - /* get the key bits */ - dsaPubKeyInfo = getKey(bKey, - KI_DSAPublic); - sizeItem = &dsaPubKeyInfo->params.prime; - break; - } - case CSSM_KEYCLASS_PRIVATE_KEY: - { - BSafeItem item(mKey.KeyData); - BSafe::check(B_SetKeyInfo(bKey, - DSA_PRIV_KEYINFO_TYPE, - (POINTER)&item), true); - - /* get the key bits */ - dsaPrivKeyInfo = getKey(bKey, - KI_DSAPrivate); - sizeItem = &dsaPrivKeyInfo->params.prime; - break; - } - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS); - } - break; - default: - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - uint32 iSize = B_IntegerBits(sizeItem->data, sizeItem->len); - keySize.LogicalKeySizeInBits = iSize; - keySize.EffectiveKeySizeInBits = iSize; - B_DestroyKeyObject(&bKey); -} - -#endif /* BSAFE_CSP_ENABLE */ - diff --git a/OSX/libsecurity_apple_csp/lib/bsafePKCS1.cpp b/OSX/libsecurity_apple_csp/lib/bsafePKCS1.cpp deleted file mode 100644 index 6eebba27..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafePKCS1.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -/* - * bsafePKCS1.cpp - support for PKCS1 format RSA public key blobs, which for some - * reason, BSAFE doesn't know about. - */ - -#include "bsafePKCS1.h" -#include "bsafecspi.h" -#include "cspdebugging.h" -#include "bsobjects.h" -#include /* for RSAPublicKey */ -#include -#include - -/* - * Simple conversion between BSAFE ITEM and snacc BigIntegerStr - */ -static void BS_ItemToSnaccBigInt( - const ITEM &item, - BigIntegerStr &snaccInt) -{ - snaccInt.Set(reinterpret_cast(item.data), item.len); -} - -/* - * This one doesn't do a malloc - the ITEM is only valid as long as - * snaccInt is! - */ -static void BS_snaccBigIntToItem( - BigIntegerStr &snaccInt, // not const - we're passing a ptr - ITEM &item) -{ - char *cp = snaccInt; - item.data = reinterpret_cast(cp); - item.len = snaccInt.Len(); -} - -/* - * Given a PKCS1-formatted key blob, decode the blob into components and do - * a B_SetKeyInfo on the specified BSAFE key. - */ -void BS_setKeyPkcs1( - const CssmData &pkcs1Blob, - B_KEY_OBJ bsKey) -{ - /* DER-decode the blob */ - RSAPublicKey snaccPubKey; - - try { - SC_decodeAsnObj(pkcs1Blob, snaccPubKey); - } - catch(const CssmError &cerror) { - CSSM_RETURN crtn = cerror.cssmError(); - - errorLog1("BS_setKeyPkcs1: SC_decodeAsnObj returned %s\n", - cssmErrorString(crtn).c_str()); - switch(crtn) { - case CSSMERR_CSSM_MEMORY_ERROR: - crtn = CSSMERR_CSP_MEMORY_ERROR; - break; - case CSSMERR_CSSM_INVALID_INPUT_POINTER: - crtn = CSSMERR_CSP_INVALID_KEY; - default: - break; - } - CssmError::throwMe(crtn); - } - - /* - * Convert BigIntegerStr modulus, publicExponent into - * ITEMS in an A_RSA_KEY. - */ - A_RSA_KEY rsaKey; - BS_snaccBigIntToItem(snaccPubKey.modulus, rsaKey.modulus); - BS_snaccBigIntToItem(snaccPubKey.publicExponent, rsaKey.exponent); - - BSafe::check( - B_SetKeyInfo(bsKey, KI_RSAPublic, POINTER(&rsaKey)), true); -} - -/* - * Obtain public key blob info, PKCS1 format. - */ -void BS_GetKeyPkcs1( - const B_KEY_OBJ bsKey, - CssmOwnedData &pkcs1Blob) -{ - /* get modulus/exponent info from BSAFE */ - A_RSA_KEY *rsaKey; - BSafe::check( - B_GetKeyInfo((POINTER *)&rsaKey, bsKey, KI_RSAPublic), true); - - /* Cook up a snacc-style RSAPublic key */ - RSAPublicKey snaccPubKey; - BS_ItemToSnaccBigInt(rsaKey->modulus, snaccPubKey.modulus); - BS_ItemToSnaccBigInt(rsaKey->exponent, snaccPubKey.publicExponent); - - /* estimate max size, BER-encode */ - size_t maxSize = 2 * (rsaKey->modulus.len + rsaKey->exponent.len); - try { - SC_encodeAsnObj(snaccPubKey, pkcs1Blob, maxSize); - } - catch(const CssmError &cerror) { - CSSM_RETURN crtn = cerror.cssmError(); - - errorLog1("BS_GetKeyPkcs1: SC_encodeAsnObj returned %s\n", - cssmErrorString(crtn).c_str()); - switch(crtn) { - case CSSMERR_CSSM_MEMORY_ERROR: - crtn = CSSMERR_CSP_MEMORY_ERROR; - break; - default: - break; - } - CssmError::throwMe(crtn); - } -} -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/bsafePKCS1.h b/OSX/libsecurity_apple_csp/lib/bsafePKCS1.h deleted file mode 100644 index c65c0130..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafePKCS1.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -/* - * bsafePKCS1.h - support for PKCS1 format RSA public key blobs, which for some - * reason, BSAFE doesn't know about. - */ - -#ifndef _BSAFE_PKCS1_H_ -#define _BSAFE_PKCS1_H_ - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* DER-decode any AsnType object */ -CSSM_RETURN CL_decodeAsnObj( - const CssmData &derEncoded, - AsnType &asnObj); - -/* DER-encode any AsnType object. */ -CSSM_RETURN CL_encodeAsnObj( - AsnType &asnObj, - CssmOwnedData &derEncoded, - size_t maxEncodedSize); - -/* - * Given a PKCS1-formatted key blob, decode the blob into components and do - * a B_SetKeyInfo on the specified BSAFE key. - */ -void BS_setKeyPkcs1( - const CssmData &pkcs1Blob, - B_KEY_OBJ bsKey); - -/* - * Obtain public key blob info, PKCS1 format. - */ -void BS_GetKeyPkcs1( - const B_KEY_OBJ bsKey, - CssmOwnedData &pkcs1Blob); - -#ifdef __cplusplus -} -#endif - -#endif /* _BSAFE_PKCS1_H_ */ - -#endif /* BSAFE_CSP_ENABLE */ - diff --git a/OSX/libsecurity_apple_csp/lib/bsafeSymmetric.cpp b/OSX/libsecurity_apple_csp/lib/bsafeSymmetric.cpp deleted file mode 100644 index 477166bb..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafeSymmetric.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsafeSymmetric.cpp - symmetric encryption contexts and algorithms -// -#include "bsafecspi.h" -#include - -#define bbprintf(args...) secinfo("BSafeBuf", ## args) - -#define VERBOSE_DEBUG 0 -#if VERBOSE_DEBUG -static void dumpBuf( - char *title, - const CSSM_DATA *d, - uint32 maxLen) -{ - unsigned i; - uint32 len; - - if(title) { - printf("%s: ", title); - } - if(d == NULL) { - printf("NO DATA\n"); - return; - } - printf("Total Length: %d\n ", d->Length); - len = maxLen; - if(d->Length < len) { - len = d->Length; - } - for(i=0; iData[i]); - if((i % 16) == 15) { - printf("\n "); - } - } - printf("\n"); -} -#else -#define dumpBuf(t, d, m) -#endif /* VERBOSE_DEBUG */ - -void BSafe::SymmetricKeyGenContext::generate( - const Context &context, - CssmKey &symKey, - CssmKey &dummyKey) -{ - AppleSymmKeyGenContext::generateSymKey( - context, - session(), - symKey); -} - -// FIXME: -// We really should match the key algorithm to the en/decrypt -// algorithm. Also: verify key usage bits. -void BSafe::BlockCipherContext::init( - const Context &context, - bool encrypting) -{ - bool hasIV = false; - bool requirePad = false; - - if (reusing(encrypting)) - return; // all set to go - - cssmAlg = context.algorithm(); - switch(cssmAlg) { - // most are handled below; break here to special cases - case CSSM_ALGID_RC4: - RC4init(context); - return; - case CSSM_ALGID_DES: - case CSSM_ALGID_DESX: - case CSSM_ALGID_3DES_3KEY_EDE: - case CSSM_ALGID_RC5: - case CSSM_ALGID_RC2: - break; - - /* others here... */ - default: - // Should never have gotten this far - assert(0); - CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM); - } - - - // these variables are used in the switch below and need to - // live until after setAlgorithm() - BSafeItem iv; - B_BLK_CIPHER_W_FEEDBACK_PARAMS spec; - A_RC5_PARAMS rc5Params; - A_RC2_PARAMS rc2Params; - - // crypto algorithm - spec.encryptionParams = NULL_PTR; // default, may change - switch (cssmAlg) { - case CSSM_ALGID_DES: - spec.encryptionMethodName = POINTER("des"); - break; - case CSSM_ALGID_DESX: - spec.encryptionMethodName = POINTER("desx"); - break; - case CSSM_ALGID_3DES_3KEY_EDE: - spec.encryptionMethodName = POINTER("des_ede"); - break; - case CSSM_ALGID_RC5: - spec.encryptionMethodName = POINTER("rc5"); - spec.encryptionParams = POINTER(&rc5Params); - rc5Params.version = 0x10; - // FIXME - get this from context attr - rc5Params.rounds = 1; - rc5Params.wordSizeInBits = 32; - break; - case CSSM_ALGID_RC2: - { - spec.encryptionMethodName = POINTER("rc2"); - spec.encryptionParams = POINTER(&rc2Params); - // effective key size in bits - either from Context, - // or the key - uint32 bits = context.getInt(CSSM_ATTRIBUTE_EFFECTIVE_BITS); - if(bits == 0) { - // OK, try the key - CssmKey &key = context.get(CSSM_ATTRIBUTE_KEY, - CSSMERR_CSP_MISSING_ATTR_KEY); - bits = key.KeyHeader.LogicalKeySizeInBits; - } - rc2Params.effectiveKeyBits = bits; - break; - } - } - - // feedback mode - cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE); - switch (cssmMode) { - /* no mode attr --> 0 == CSSM_ALGMODE_NONE, not currently supported */ - case CSSM_ALGMODE_CBCPadIV8: - requirePad = true; - // and fall thru - case CSSM_ALGMODE_CBC_IV8: - { - iv = context.get(CSSM_ATTRIBUTE_INIT_VECTOR, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - spec.feedbackMethodName = POINTER("cbc"); - spec.feedbackParams = POINTER(&iv); - hasIV = true; - break; - } - case CSSM_ALGMODE_OFB_IV8: { - iv = context.get(CSSM_ATTRIBUTE_INIT_VECTOR, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - spec.feedbackMethodName = POINTER("ofb"); - spec.feedbackParams = POINTER(&iv); - hasIV = true; - break; - } - case CSSM_ALGMODE_ECB: { - spec.feedbackMethodName = POINTER("ecb"); - spec.feedbackParams = POINTER(&blockSize); - break; - } - default: - errorLog1("BSafe symmetric init: illegal mode (%d)\n", (int)cssmMode); - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE); - } - - // padding - spec.paddingParams = NULL_PTR; - /* no padding attr --> 0 == PADDING_NONE */ - padEnable = false; - uint32 cssmPadding = context.getInt(CSSM_ATTRIBUTE_PADDING); - if(requirePad) { - switch(cssmPadding) { - case CSSM_PADDING_PKCS1: // for backwards compatibility - case CSSM_PADDING_PKCS5: - case CSSM_PADDING_PKCS7: - spec.paddingMethodName = POINTER("pad"); - padEnable = true; - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); - } - } - else { - if(cssmPadding != CSSM_PADDING_NONE) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); - } - else { - spec.paddingMethodName = POINTER("nopad"); - } - } - - // put it all together - setAlgorithm(AI_FeedbackCipher, &spec); // set BSafe algorithm - setKeyFromContext(context); // set BSafe key - cipherInit(); // common cryption init -} - -void BSafe::BlockCipherContext::RC4init( - const Context &context) -{ - setAlgorithm(AI_RC4, NULL); // set BSafe algorithm - setKeyFromContext(context); // set BSafe key - padEnable = false; - cipherInit(); // common cryption init -} - -void BSafe::BlockCipherContext::trackUpdate(size_t inSize, size_t outSize) -{ - size_t newPending = pending + inSize; - pending = newPending % blockSize; - - /* - * Most of the time, the max size buffered by BSAFE is - * blockSize - 1 bytes. When decrypting and padding is enabled, - * BSAFE buffers up to a full block. - */ - if(!mDirection && //Êdecrypting - padEnable && // padding - (pending == 0) && // mod result was 0 - (newPending > 0)) { // but nonzero total - /* BSAFE is holding a whole block in its buffer */ - pending = blockSize; - } - bbprintf("===trackUpdte: %s; inSize=%d newPending=%d pending=%d", - (mDirection ? "encrypt" : "decrypt"), - inSize, newPending, pending); -} - -size_t BSafe::BlockCipherContext::inputSize(size_t outSize) -{ - // if we have an 'outSize' output buffer, how many input bytes may we feed in? - size_t wholeBlocks = outSize / blockSize; - return wholeBlocks * blockSize - pending + (blockSize - 1); -} - -size_t BSafe::BlockCipherContext::outputSize(bool final, size_t inSize) -{ - // how much output buffer will we need for 'size' input bytes? - - size_t totalToGo = inSize + pending; - // total to go, rounded up to next block - size_t numBlocks = (totalToGo + blockSize - 1) / blockSize; - size_t outSize; - - /* - * encrypting: may get one additional block on final() if padding - * decrypting: outsize always <= insize - */ - if(mDirection && // encrypting - final && // last time - padEnable && // padding enabled - ((totalToGo % blockSize) == 0)) { // even ptext len - numBlocks++; // extra pad block - } - outSize = numBlocks * blockSize; - bbprintf("===outputSize: %s; final=%d inSize=%d pending=%d outSize=%d", - (mDirection ? "encrypt" : "decrypt"), - final, inSize, pending, outSize); - return outSize; -} - -void BSafe::BlockCipherContext::minimumProgress(size_t &inSize, size_t &outSize) -{ - // eat up buffer, proceed one full block - inSize = blockSize - pending; - outSize = blockSize; -} -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/bsafecsp.h b/OSX/libsecurity_apple_csp/lib/bsafecsp.h deleted file mode 100644 index 14d4511f..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafecsp.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsafecsp - top C++ implementation layer for BSafe 4 -// -#ifndef _H_BSAFECSP -#define _H_BSAFECSP - -#include -#include "AppleCSP.h" - -/* Can't include AppleCSPSession.h due to circular dependency */ -class AppleCSPSession; - -// no longer a subclass of AlgorithmFactory due to -// differing setup() methods -class BSafeFactory : public AppleCSPAlgorithmFactory { -public: - - BSafeFactory( - Allocator *normAlloc = NULL, - Allocator *privAlloc = NULL) - { - setNormAllocator(normAlloc); - setPrivAllocator(privAlloc); - } - ~BSafeFactory() { } - - bool setup( - AppleCSPSession &session, - CSPFullPluginSession::CSPContext * &cspCtx, - const Context &context); - - static void setNormAllocator(Allocator *alloc); - static void setPrivAllocator(Allocator *alloc); - -}; - -#endif //_H_BSAFECSP -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/bsafecspi.h b/OSX/libsecurity_apple_csp/lib/bsafecspi.h deleted file mode 100644 index f5d6d4fa..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsafecspi.h +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsafecspi - implementation layer for C++ BSafe 4 interface -// -#ifndef _H_BSAFECSPI -#define _H_BSAFECSPI - -#include -#include "bsobjects.h" -#include "AppleCSPContext.h" -#include "AppleCSPSession.h" -#include -#include - -// -// The BSafe class is more of a namespace than anything else. -// Just think of it as the "static binder" for BSafe's objects. -// Note that we keep a global, static allocator. We have to; BSafe -// doesn't have any state management at that level. -// -class BSafe { - class BSafeContext; friend class BSafeContext; - class BSafeFactory; friend class BSafeFactory; - -public: - static void setNormAllocator(Allocator *alloc) - { assert(!normAllocator); normAllocator = alloc; } - static void setPrivAllocator(Allocator *alloc) - { assert(!privAllocator); privAllocator = alloc; } - - static bool setup( - AppleCSPSession &session, - CSPFullPluginSession::CSPContext * &cspCtx, - const Context &context); - -private: - // BSafe's memory allocators - static Allocator *normAllocator; - static Allocator *privAllocator; - friend POINTER T_malloc(unsigned int); - friend void T_free(POINTER); - friend POINTER T_realloc(POINTER, unsigned int); - - static const B_ALGORITHM_METHOD * const bsChooser[]; - -private: - // BSafe-specific BinaryKey class. - class BSafeBinaryKey : public BinaryKey { - - public: - BSafeBinaryKey( - bool isPub, - uint32 alg); // CSSM_ALGID_{RSA,DSA} - ~BSafeBinaryKey(); - void generateKeyBlob( - Allocator &allocator, - CssmData &blob, - CSSM_KEYBLOB_FORMAT &format, - AppleCSPSession &session, - const CssmKey *paramKey, /* optional, unused here */ - CSSM_KEYATTR_FLAGS &attrFlags); /* IN/OUT */ - - bool isPublic() { return mIsPublic; } - uint32 alg() { return mAlg; } - B_KEY_OBJ bsKey() { return mBsKey; } - - private: - bool mIsPublic; - uint32 mAlg; // CSSM_ALGID_{RSA,DSA} - B_KEY_OBJ mBsKey; - }; - -private: - // - // The BSafeContext class is the parent of all BSafe-used CSPContext objects. - // It implements the CSPContext operation functions (init, update, ...) in terms - // of pointer-to-member fields set by its subclasses. This may not be pretty, but - // it avoids every subclass having to re-implement all CSPContext operations. - // Beyond that, we implement a raftload of utility methods for our children. - // - class BSafeContext : public AppleCSPContext { - friend class BSafe; - public: - BSafeContext(AppleCSPSession &session); - virtual ~BSafeContext(); - - // called by CSPFullPluginSession - void init(const Context &context, bool encoding = true); - void update(const CssmData &data); - void update(void *inp, size_t &inSize, void *outp, size_t &outSize); - void final(CssmData &out); - void final(const CssmData &in); - size_t outputSize(bool final, size_t inSize); - - protected: - // install a BSafe algorithm into bsAlgorithm - void setAlgorithm(B_INFO_TYPE bAlgType, const void *info = NULL); - - // safely create bsKey - void createBsKey(); - - // set bsKey. The different versions are equivalent - void setKeyAtom(B_INFO_TYPE bKeyInfo, const void *info); - void setKeyFromItem(B_INFO_TYPE bKeyInfo, const BSafeItem &item) - { setKeyAtom(bKeyInfo, &item); } - void setKeyFromCssmKey(B_INFO_TYPE bKeyInfo, const CssmKey &key) - { BSafeItem item(key.KeyData); setKeyAtom(bKeyInfo, &item); } - void setKeyFromCssmData(B_INFO_TYPE bKeyInfo, const CssmData &keyData) - { BSafeItem item(keyData); setKeyAtom(bKeyInfo, &item); } - void setKeyFromContext(const Context &context, bool required = true); - - void setRefKey(CssmKey &key); - void setRsaOutSize(bool isPubKey); - - // create mRandom to be a suitable random-generator BSafe object (if it isn't yet) - void setRandom(); - - // trackUpdate is called during crypto-output. Hook it to keep track of data flow - virtual void trackUpdate(size_t in, size_t out); - - // destroy bsAlgorithm and bsKey so we can start over making them - void reset(); - - // clear key state - void destroyBsKey(); - - // determine if we can reuse the current bsAlgorithm - bool reusing(bool encode = true) - { - if (initialized && !opStarted && - (encode == encoding)) return true; - encoding = encode; - return false; - } - - public: - // - // These pointers-to-member are called by the BSafeContext operations - // (update, final). They must be set by a subclasses's init() method. - // Not all members are used by all types of operations - check the - // source when in doubt. - // - int (*inUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *); - int (*inOutUpdate)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int, - POINTER, unsigned int, B_ALGORITHM_OBJ, A_SURRENDER_CTX *); - int (*inFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int, A_SURRENDER_CTX *); - int (*inFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int, - B_ALGORITHM_OBJ, A_SURRENDER_CTX *); - int (*outFinalR)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int, - B_ALGORITHM_OBJ, A_SURRENDER_CTX *); - int (*outFinal)(B_ALGORITHM_OBJ, POINTER, unsigned int *, unsigned int, - A_SURRENDER_CTX *); - - protected: - - // un-consted bsChooser for BSafe's consumption. BSafe's Bad - static B_ALGORITHM_METHOD **chooser() - { return const_cast(bsChooser); } - - // a placeholder for a surrender context. Not currently used - // @@@ should perhaps test for pthread cancel? --> thread abstraction - static A_SURRENDER_CTX * const bsSurrender; - - protected: - B_ALGORITHM_OBJ bsAlgorithm; // BSafe algorithm object or NULL - B_ALGORITHM_OBJ bsRandom; // PRNG algorithm - bool encoding; // encoding direction - bool initialized; // method init() has completed - bool opStarted; // method update() has been called - // generally means that we can't reuse - // the current bsAlgorithm - // - // We have a binKey only if the caller passed in a reference - // key. In that case we avoid deleting bsKey - which is a copy - // of binKey.bsKey - because a BinaryKey is persistent - // relative to this context. - // - BSafeBinaryKey *bsBinKey; - B_KEY_OBJ bsKey; // BSafe key object or NULL - - size_t mOutSize; // simple output size, if applicable - }; /* BSafeContext */ - - // contexts for BSafe digest operations - class DigestContext : public BSafeContext { - public: - // do all work in constructor. We have no directions; thus default init() works fine - DigestContext( - AppleCSPSession &session, - const Context &, - B_INFO_TYPE bAlgInfo, - size_t sz); - }; - - // common context features for BSafe cipher operations (both symmetric and asymmetric) - class CipherContext : public BSafeContext { - public: - CipherContext( - AppleCSPSession &session) : - BSafeContext(session), - pending(0) {} - - protected: - size_t pending; // bytes not eaten still pending (staged only) - public: - void cipherInit(); // common init code (must be called from init()) - }; - - // contexts for block cipher operations using symmetric algorithms - class BlockCipherContext : public CipherContext { - size_t blockSize; - uint32 cssmAlg; - uint32 cssmMode; - bool padEnable; - public: - BlockCipherContext( - AppleCSPSession &session, - const Context &, - size_t sz) : - CipherContext(session), - blockSize(sz) { } - void init(const Context &context, bool encrypting); - size_t inputSize(size_t outSize); - size_t outputSize(bool final, size_t inSize); - void minimumProgress(size_t &in, size_t &out); - void trackUpdate(size_t in, size_t out); - private: - // special case for RC4 - void RC4init(const Context &context); - }; - - // context for generating public/private key pairs - class BSafeKeyPairGenContext : public BSafeContext, - private AppleKeyPairGenContext { - public: - BSafeKeyPairGenContext( - AppleCSPSession &session, - const Context &) : - BSafeContext(session) {} - - // generate alg params, not handled by PublicKeyGenerateContext - // For DSA only. - void generate( - const Context &context, - uint32 bitSize, - CssmData ¶ms, - uint32 &attrCount, - Context::Attr * &attrs); - - // this one is specified in CSPFullPluginSession - void generate( - const Context &context, - CssmKey &pubKey, - CssmKey &privKey); - - // this one in AppleKeyPairGenContext - void generate( - const Context &context, - BinaryKey &pubBinKey, - BinaryKey &privBinKey, - uint32 &keySize); - - private: - void setupAlgorithm( - const Context &context, - uint32 &keySize); - - }; /* BSafeKeyPairGenContext */ - - // public key cipher operations - class PublicKeyCipherContext : public CipherContext { - public: - PublicKeyCipherContext( - AppleCSPSession &session, - const Context &) : - CipherContext(session) { } - void init(const Context &context, bool encrypting); - size_t inputSize(size_t outSize); // unlimited - }; - - // contexts for BSafe signing/verifying operations - class SigningContext : public BSafeContext { - B_INFO_TYPE algorithm; - public: - SigningContext( - AppleCSPSession &session, - const Context &, - B_INFO_TYPE bAlg, - size_t sz) : - BSafeContext(session), - algorithm(bAlg) { mOutSize = sz; } - void init(const Context &context, bool signing); - }; - - // contexts for BSafe MAC generation and verification - class MacContext : public BSafeContext { - B_INFO_TYPE algorithm; - public: - MacContext( - AppleCSPSession &session, - const Context &, - B_INFO_TYPE bAlg, - size_t sz) : - BSafeContext(session), - algorithm(bAlg) { mOutSize = sz; } - void init(const Context &context, bool signing); - void final(const CssmData &in); - }; - - // contexts for BSafe's random number generation - class RandomContext : public BSafeContext { - B_INFO_TYPE algorithm; - public: - RandomContext( - AppleCSPSession &session, - const Context &, - B_INFO_TYPE alg) : - BSafeContext(session), - algorithm(alg) { } - void init(const Context &context, bool); - void final(CssmData &data); - }; - - // symmetric key generation context - class SymmetricKeyGenContext : public BSafeContext, - private AppleSymmKeyGenContext { - public: - SymmetricKeyGenContext( - AppleCSPSession &session, - const Context &ctx, - uint32 minSizeInBits, - uint32 maxSizeInBits, - bool mustBeByteSized) : - BSafeContext(session), - AppleSymmKeyGenContext( - minSizeInBits, - maxSizeInBits, - mustBeByteSized) { } - - void generate( - const Context &context, - CssmKey &symKey, - CssmKey &dummyKey); - - }; - -public: - /* - * Stateless, private function to map a CSSM alg and pub/priv state - * to B_INFO_TYPE and format. Returns true on success, false on - * "I don't understand this algorithm". - */ - static bool bsafeAlgToInfoType( - CSSM_ALGORITHMS alg, - bool isPublic, - B_INFO_TYPE &infoType, // RETURNED - CSSM_KEYBLOB_FORMAT &format); // RETURNED - - /* check result of a BSafe call and throw on error */ - static void check(int status, bool isKeyOp = false); - - /* moved here from BSafeContext - now works on any key */ - template - static KI_Type *getKey(B_KEY_OBJ bKey, B_INFO_TYPE type) - { - POINTER p; - check(B_GetKeyInfo(&p, bKey, type), true); - return reinterpret_cast(p); - } - - - // - // The context generation table - see algmaker.cpp. - // -public: - // Base class for Maker classes - class MakerBase { - public: - virtual ~MakerBase() { } - virtual BSafeContext *make( - AppleCSPSession &session, - const Context &context) const = 0; - }; - - // One entry in Maker table - struct MakerTable { - CSSM_ALGORITHMS algorithmId; - CSSM_CONTEXT_TYPE algClass; - const MakerBase *maker; - ~MakerTable() { delete maker; } - }; - -private: - static bug_const MakerTable algorithms[]; - static const unsigned int algorithmCount; - - /* - * CSPKeyInfoProvider for BSafe keys - */ - class BSafeKeyInfoProvider : public CSPKeyInfoProvider - { -private: - BSafeKeyInfoProvider( - const CssmKey &cssmKey, - AppleCSPSession &session); - public: - static CSPKeyInfoProvider *provider( - const CssmKey &cssmKey, - AppleCSPSession &session); - ~BSafeKeyInfoProvider() { } - void CssmKeyToBinary( - CssmKey *paramKey, // optional - CSSM_KEYATTR_FLAGS &attrFlags, // IN/OUT - BinaryKey **binKey); // RETURNED - void QueryKeySizeInBits( - CSSM_KEY_SIZE &keySize); // RETURNED - }; - -}; /* BSAFE namespace */ - -/* - * BSAFE Key Info types. - */ -#define BLOB_IS_PUB_KEY_INFO 0 - -#if BLOB_IS_PUB_KEY_INFO - -/* X beta values */ -#define RSA_PUB_KEYINFO_TYPE KI_RSAPublicBER -#define RSA_PRIV_KEYINFO_TYPE KI_PKCS_RSAPrivateBER -#define DSA_PUB_KEYINFO_TYPE KI_DSAPublicBER -#define DSA_PRIV_KEYINFO_TYPE KI_DSAPrivateBER - -#else /* BLOB_IS_PUB_KEY_INFO */ - -#define RSA_PUB_KEYINFO_TYPE KI_RSAPublic -#define RSA_PRIV_KEYINFO_TYPE KI_PKCS_RSAPrivateBER -#define DSA_PUB_KEYINFO_TYPE KI_DSAPublicBER -#define DSA_PRIV_KEYINFO_TYPE KI_DSAPrivateBER - -#endif - -#endif //_H_BSAFECSP -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/bsobjects.h b/OSX/libsecurity_apple_csp/lib/bsobjects.h deleted file mode 100644 index 0491af22..00000000 --- a/OSX/libsecurity_apple_csp/lib/bsobjects.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// bsobjects - C++ adaptations of popular BSafe 4 object types -// -#ifndef _H_BSOBJECTS -#define _H_BSOBJECTS - -#include -#include -#include -#include - -// -// A PodWrapper for BSafe's ITEM objects -// -class BSafeItem : public PodWrapper { -public: - BSafeItem() { ((ITEM *)this)->data = NULL; len = 0; } - BSafeItem(void *addr, size_t sz) - { ((ITEM *)this)->data = (unsigned char *)addr; len = sz; } - BSafeItem(const CSSM_DATA &cData) - { ((ITEM *)this)->data = cData.Data; len = cData.Length; } - BSafeItem(const ITEM &cData) - { *(ITEM *)this = cData; } - - void operator = (const CssmData &cData) - { ((ITEM *)this)->data = (unsigned char *)cData.data(); len = cData.length(); } - - void *data() const { return ((ITEM *)this)->data; } - size_t length() const { return len; } - - template - T copy(Allocator &alloc) - { return T(memcpy(alloc.malloc(length()), data(), length()), length()); } - - template - T *copyp(Allocator &alloc) - { return new(alloc) T(copy(alloc)); } - - void *operator new (size_t size, Allocator &alloc) - { return alloc.malloc(size); } -}; - -#endif //_H_BSOBJECTS -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/desContext.cpp b/OSX/libsecurity_apple_csp/lib/desContext.cpp index 43890cfd..22531e09 100644 --- a/OSX/libsecurity_apple_csp/lib/desContext.cpp +++ b/OSX/libsecurity_apple_csp/lib/desContext.cpp @@ -65,6 +65,7 @@ void DESContext::init( if (DesInst != NULL) { CCCryptorRelease(DesInst); + DesInst = NULL; } (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithmDES, ccDefaultPadding, NULL, keyData, kCCKeySizeDES, NULL, 0, 0, 0, &DesInst); @@ -152,6 +153,7 @@ void DES3Context::init( if (DesInst != NULL) { CCCryptorRelease(DesInst); + DesInst = NULL; } (void) CCCryptorCreateWithMode(0, kCCModeECB, kCCAlgorithm3DES, ccDefaultPadding, NULL, keyData, kCCKeySize3DES, NULL, 0, 0, 0, &DesInst); diff --git a/OSX/libsecurity_apple_csp/lib/memory.cpp b/OSX/libsecurity_apple_csp/lib/memory.cpp deleted file mode 100644 index 036db142..00000000 --- a/OSX/libsecurity_apple_csp/lib/memory.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - - -// -// memory - memory functions for BSafe -// -#include -#include -#include "bsafecspi.h" - - -// declared in bsafecspi.h.... -Allocator *BSafe::normAllocator; -Allocator *BSafe::privAllocator; - -// We use the private allocator for all BSAFE-alalocated memory. -// Memory allocated my BSAFE should never be visible by apps. - -POINTER CALL_CONV T_malloc (unsigned int size) -{ - return reinterpret_cast(BSafe::privAllocator->malloc(size)); -} - -POINTER CALL_CONV T_realloc (POINTER p, unsigned int size) -{ - POINTER result; - if ((result = (POINTER)BSafe::privAllocator->realloc(p, size)) == NULL_PTR) - free (p); - return (result); -} - -void CALL_CONV T_free (POINTER p) -{ - BSafe::privAllocator->free(p); -} -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/miscAlgFactory.cpp b/OSX/libsecurity_apple_csp/lib/miscAlgFactory.cpp index 89b81d2c..ae07d293 100644 --- a/OSX/libsecurity_apple_csp/lib/miscAlgFactory.cpp +++ b/OSX/libsecurity_apple_csp/lib/miscAlgFactory.cpp @@ -37,22 +37,6 @@ #include "castContext.h" #include -/* - * These #defines are mainly to facilitate measuring the performance of our own - * implementation vs. the ones in BSafe. This factory gets called first; if - * we disable e.g. DES here the BSAFE version will be used. - */ -#ifdef BSAFE_CSP_ENABLE - -#define MAF_DES_ENABLE 0 -#define MAF_DES3_ENABLE 0 -#define MAF_RC2_ENABLE 0 -#define MAF_RC4_ENABLE 0 -#define MAF_RC5_ENABLE 0 -#define MAF_MAC_ENABLE 0 - -#else /* !BSAFE_CSP_ENABLE, normal case */ - #define MAF_DES_ENABLE 1 #define MAF_DES3_ENABLE 1 #define MAF_RC2_ENABLE 1 @@ -60,8 +44,6 @@ #define MAF_RC5_ENABLE 1 #define MAF_MAC_ENABLE 1 -#endif /* BSAFE_CSP_ENABLE */ - #if (!MAF_DES_ENABLE || !MAF_DES3_ENABLE || !MAF_RC2_ENABLE || !MAF_RC4_ENABLE || \ !MAF_RC5_ENABLE || !MAF_MAC_ENABLE) #warning Internal DES/RC2/RC4/RC5/Mac implementation disabled! diff --git a/OSX/libsecurity_apple_csp/lib/miscalgorithms.cpp b/OSX/libsecurity_apple_csp/lib/miscalgorithms.cpp deleted file mode 100644 index 10832749..00000000 --- a/OSX/libsecurity_apple_csp/lib/miscalgorithms.cpp +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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. - */ - -#ifdef BSAFE_CSP_ENABLE - -// -// miscalgorithms - miscellaneous BSafe context creators and managers -// -#include "bsafecspi.h" - -#include // debug - - -// -// Digest algorithms. -// NOTE: There is no init() method, since BSafe digest algorithms re-initialize -// automatically and there is no directional difference. -// -BSafe::DigestContext::DigestContext( - AppleCSPSession &session, - const Context &, - B_INFO_TYPE bAlgInfo, - size_t sz) - : BSafeContext(session) -{ - mOutSize = sz; - inUpdate = B_DigestUpdate; - outFinal = B_DigestFinal; - setAlgorithm(bAlgInfo); - check(B_DigestInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); - initialized = true; -} - - -// -// Signing/Verifying algorithms -// -// FIXME: -// We really should match the key algorithm to the sign/vfy -// algorithm. Also: verify key usage bits. -void BSafe::SigningContext::init( - const Context &context, - bool signing) -{ - if (reusing(signing)) - return; // all set to go - - setAlgorithm(algorithm, NULL); - setKeyFromContext(context); // may set outSize for some keys - - if (signing) { - check(B_SignInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); - setRandom(); // needed by some signing algorithms - inUpdate = B_SignUpdate; - outFinalR = B_SignFinal; - outFinal = NULL; - } else { - check(B_VerifyInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); - inUpdate = B_VerifyUpdate; - inFinalR = B_VerifyFinal; - inFinal = NULL; - } -} - - -// -// MAC algorithms. -// Note that BSafe treats MACs as digest algorithms - it has no MAC algorithm -// class. Thus, verifying consists of "digesting" followed by comparing the result. -// -// FIXME : what kind of key do we expect here? For now, any old -// symmetric key will work... -// -void BSafe::MacContext::init( - const Context &context, - bool signing) -{ - if (reusing(signing)) - return; // all set to go - - B_DIGEST_SPECIFIER digestSpec; - digestSpec.digestInfoType = algorithm; - digestSpec.digestInfoParams = NULL; - - setAlgorithm(AI_HMAC, &digestSpec); - setKeyFromContext(context); - check(B_DigestInit(bsAlgorithm, bsKey, chooser(), bsSurrender)); - - if (signing) { - inUpdate = B_DigestUpdate; - outFinal = B_DigestFinal; - } else { - inUpdate = B_DigestUpdate; - // need not set xxFinal - we override final(). - } -} - -void BSafe::MacContext::final(const CssmData &in) -{ - // we need to perform a DigestFinal step into a temp buffer and compare to 'in' - void *digest = normAllocator->malloc(in.length()); - unsigned int length; - check(B_DigestFinal(bsAlgorithm, POINTER(digest), &length, in.length(), bsSurrender)); - bool verified = length == in.length() && !memcmp(digest, in.data(), in.length()); - normAllocator->free(digest); - initialized = false; - if (!verified) - CssmError::throwMe(CSSMERR_CSP_VERIFY_FAILED); -} - - -// -// Random-number generation algorithms. -// Note that we don't use bsRandom, since that's our internal fixed "best to use" method, -// not the one the user asked for. -// NOTE: We freeze the output size at init(). -// -void BSafe::RandomContext::init(const Context &context, bool) -{ - reset(); // throw away, we need to re-seed anyway - setAlgorithm(algorithm, NULL); // MD5 generator mode (RSA proprietary) - check(B_RandomInit(bsAlgorithm, chooser(), bsSurrender)); - - // set/freeze output size - mOutSize = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE, CSSMERR_CSP_MISSING_ATTR_OUTPUT_SIZE); - - // seed the PRNG (if specified) - if (const CssmCryptoData *seed = context.get(CSSM_ATTRIBUTE_SEED)) { - const CssmData &seedValue = (*seed)(); - check(B_RandomUpdate(bsAlgorithm, POINTER(seedValue.data()), seedValue.length(), bsSurrender)); - } -} - -void BSafe::RandomContext::final(CssmData &data) -{ - check(B_GenerateRandomBytes(bsAlgorithm, POINTER(data.data()), mOutSize, bsSurrender)); -} -#endif /* BSAFE_CSP_ENABLE */ diff --git a/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp b/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp index 11895ac4..07185bc2 100644 --- a/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp +++ b/OSX/libsecurity_apple_csp/lib/opensshWrap.cpp @@ -31,13 +31,13 @@ #include "AppleCSPUtils.h" #include "AppleCSPKeys.h" #include "RSA_DSA_keys.h" +#include "SecRandom.h" #include "opensshCoding.h" #include "cspdebugging.h" #include #include #include #include -#include #include static const char *authfile_id_string = "SSH PRIVATE KEY FILE FORMAT 1.1\n"; @@ -376,8 +376,7 @@ CSSM_RETURN encodeOpenSSHv1PrivKey( /* [0..3] check bytes */ UInt8 checkBytes[4]; - DevRandomGenerator rng = DevRandomGenerator(); - rng.random(checkBytes, 2); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, 2, checkBytes)) ; checkBytes[2] = checkBytes[0]; checkBytes[3] = checkBytes[1]; CFDataAppendBytes(ptext, checkBytes, 4); diff --git a/OSX/libsecurity_apple_x509_cl/lib/DecodedExtensions.h b/OSX/libsecurity_apple_x509_cl/lib/DecodedExtensions.h index a44f6188..7b7f7589 100644 --- a/OSX/libsecurity_apple_x509_cl/lib/DecodedExtensions.h +++ b/OSX/libsecurity_apple_x509_cl/lib/DecodedExtensions.h @@ -28,6 +28,7 @@ #include #include +#include #include "cldebugging.h" diff --git a/OSX/libsecurity_apple_x509_cl/lib/DecodedItem.cpp b/OSX/libsecurity_apple_x509_cl/lib/DecodedItem.cpp index 0dab4560..79768803 100644 --- a/OSX/libsecurity_apple_x509_cl/lib/DecodedItem.cpp +++ b/OSX/libsecurity_apple_x509_cl/lib/DecodedItem.cpp @@ -86,7 +86,7 @@ const DecodedExten *DecodedItem::findDecodedExt( } } if(rtnExt != NULL) { - /* sucessful return */ + /* successful return */ if(index == 0) { numFields = found; } diff --git a/OSX/libsecurity_apple_x509_tp/lib/TPCertInfo.cpp b/OSX/libsecurity_apple_x509_tp/lib/TPCertInfo.cpp index 62b6f7b8..a7e1a99b 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/TPCertInfo.cpp +++ b/OSX/libsecurity_apple_x509_tp/lib/TPCertInfo.cpp @@ -2036,7 +2036,7 @@ post_trust_setting: * certs' mUsed state. * Also handle Radar 23734683, endless loop of untrusted roots. */ - if(isInGroup(*issuerCert) || gatheredCerts->isInGroup(*issuerCert)) { + if(isInGroup(*issuerCert) || (gatheredCerts && gatheredCerts->isInGroup(*issuerCert))) { tpDebug("buildCertGroup: Multiple instances of cert"); delete issuerCert; issuerCert = NULL; diff --git a/OSX/libsecurity_apple_x509_tp/lib/TPDatabase.cpp b/OSX/libsecurity_apple_x509_tp/lib/TPDatabase.cpp index 3870a8c8..116255a7 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/TPDatabase.cpp +++ b/OSX/libsecurity_apple_x509_tp/lib/TPDatabase.cpp @@ -435,7 +435,7 @@ static CSSM_DB_UNIQUE_RECORD_PTR tpCrlLookup( else { /* right now */ StLock _(tpTimeLock()); - timeAtNowPlus(0, TIME_CSSM, timeStr); + timeAtNowPlus(0, TP_TIME_CSSM, timeStr); } CSSM_DATA timeData; timeData.Data = (uint8 *)timeStr; diff --git a/OSX/libsecurity_apple_x509_tp/lib/TPNetwork.cpp b/OSX/libsecurity_apple_x509_tp/lib/TPNetwork.cpp index bc9cf3fe..0e6cdc13 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/TPNetwork.cpp +++ b/OSX/libsecurity_apple_x509_tp/lib/TPNetwork.cpp @@ -106,7 +106,7 @@ static CSSM_RETURN tpCrlViaNet( /* verifyTime: we want a CRL that's valid right now. */ { StLock _(tpTimeLock()); - timeAtNowPlus(0, TIME_CSSM, cssmTime); + timeAtNowPlus(0, TP_TIME_CSSM, cssmTime); } crtn = tpFetchViaNet(url, issuer, LT_Crl, cssmTime, alloc, crlData); diff --git a/OSX/libsecurity_apple_x509_tp/lib/ocspRequest.cpp b/OSX/libsecurity_apple_x509_tp/lib/ocspRequest.cpp index c609b780..460af75a 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/ocspRequest.cpp +++ b/OSX/libsecurity_apple_x509_tp/lib/ocspRequest.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include @@ -159,8 +159,8 @@ const CSSM_DATA *OCSPRequest::encode() /* one extension - the nonce */ if(mGenNonce) { - DevRandomGenerator drg; - drg.random(nonceBytes, OCSP_NONCE_SIZE); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, OCSP_NONCE_SIZE, nonceBytes)); + nonce = new OCSPNonce(mCoder, false, nonceData); extenArray[0] = nonce->nssExt(); tbs.requestExtensions = extenArray; diff --git a/OSX/libsecurity_apple_x509_tp/lib/tpCredRequest.cpp b/OSX/libsecurity_apple_x509_tp/lib/tpCredRequest.cpp index 3aee72f9..28e9e179 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/tpCredRequest.cpp +++ b/OSX/libsecurity_apple_x509_tp/lib/tpCredRequest.cpp @@ -136,10 +136,10 @@ void AppleTPSession::freeX509Name( */ #define TP_FOUR_DIGIT_YEAR 0 #if TP_FOUR_DIGIT_YEAR -#define TP_TIME_FORMAT TIME_GEN +#define TP_TIME_FORMAT TP_TIME_GEN #define TP_TIME_TAG BER_TAG_GENERALIZED_TIME #else -#define TP_TIME_FORMAT TIME_UTC +#define TP_TIME_FORMAT TP_TIME_UTC #define TP_TIME_TAG BER_TAG_UTC_TIME #endif /* TP_FOUR_DIGIT_YEAR */ diff --git a/OSX/libsecurity_apple_x509_tp/lib/tpTime.c b/OSX/libsecurity_apple_x509_tp/lib/tpTime.c index 7d6cc7a9..058cab00 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/tpTime.c +++ b/OSX/libsecurity_apple_x509_tp/lib/tpTime.c @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2001,2011-2012,2014 Apple Inc. All Rights Reserved. - * + * Copyright (c) 2000-2001,2011-2012,2014-2019 Apple Inc. All Rights Reserved. + * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. - * + * * This 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 @@ -20,7 +20,7 @@ * tpTime.c - cert related time functions * */ - + #include "tpTime.h" #include #include @@ -31,7 +31,7 @@ /* * Given a string containing either a UTC-style or "generalized time" * time string, convert to a CFDateRef. Returns nonzero on - * error. + * error. */ int timeStringToCfDate( const char *str, @@ -49,11 +49,11 @@ int timeStringToCfDate( CFGregorianDate gd; CFTimeZoneRef timeZone; CFTimeInterval gmtOff = 0; - + if((str == NULL) || (len == 0) || (cfDate == NULL)) { return 1; } - + /* tolerate NULL terminated or not */ if(str[len - 1] == '\0') { len--; @@ -77,12 +77,12 @@ int timeStringToCfDate( case LOCALIZED_TIME_STRLEN: // "YYYYMMDDhhmmssThhmm" (where T=[+,-]) isLocal = 1; break; - default: // unknown format + default: // unknown format return 1; } - + cp = (char *)str; - + /* check that all characters except last (or timezone indicator, if localized) are digits */ for(i=0; i<(len - 1); i++) { if ( !(isdigit(cp[i])) ) @@ -101,7 +101,7 @@ int timeStringToCfDate( return 1; } } - + /* YEAR */ szTemp[0] = *cp++; szTemp[1] = *cp++; @@ -111,13 +111,13 @@ int timeStringToCfDate( szTemp[3] = *cp++; szTemp[4] = '\0'; } - else { + else { szTemp[2] = '\0'; } x = atoi( szTemp ); if(isUtc) { - /* - * 2-digit year. + /* + * 2-digit year. * 0 <= year < 50 : assume century 21 * 50 <= year < 70 : illegal per PKIX * ...though we allow this as of 10/10/02...dmitch @@ -133,7 +133,7 @@ int timeStringToCfDate( */ else { /* century 20 */ - x += 1900; + x += 1900; } } gd.year = x; @@ -194,7 +194,7 @@ int timeStringToCfDate( } gd.second = x; } - + if (isLocal) { /* ZONE INDICATOR */ switch(*cp++) { @@ -263,19 +263,19 @@ int compareTimes( * (UTC_TIME_STRLEN+1), (GENERALIZED_TIME_STRLEN+1), or (CSSM_TIME_STRLEN+1) * respectively. Caller must hold tpTimeLock. */ -void timeAtNowPlus(unsigned secFromNow, +void timeAtNowPlus(unsigned secFromNow, TpTimeSpec timeSpec, char *outStr) { struct tm utc; time_t baseTime; - + baseTime = time(NULL); baseTime += (time_t)secFromNow; utc = *gmtime(&baseTime); - + switch(timeSpec) { - case TIME_UTC: + case TP_TIME_UTC: /* UTC - 2 year digits - code which parses this assumes that * (2-digit) years between 0 and 49 are in century 21 */ if(utc.tm_year >= 100) { @@ -285,16 +285,16 @@ void timeAtNowPlus(unsigned secFromNow, utc.tm_year /* + 1900 */, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); break; - case TIME_GEN: + case TP_TIME_GEN: sprintf(outStr, "%04d%02d%02d%02d%02d%02dZ", - /* note year is relative to 1900, hopefully it'll have + /* note year is relative to 1900, hopefully it'll have * four valid digits! */ utc.tm_year + 1900, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); break; - case TIME_CSSM: + case TP_TIME_CSSM: sprintf(outStr, "%04d%02d%02d%02d%02d%02d", - /* note year is relative to 1900, hopefully it'll have + /* note year is relative to 1900, hopefully it'll have * four valid digits! */ utc.tm_year + 1900, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); @@ -306,7 +306,7 @@ void timeAtNowPlus(unsigned secFromNow, * Convert a time string, which can be in any of three forms (UTC, * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller * mallocs the result, which must be at least (CSSM_TIME_STRLEN+1) bytes. - * Returns nonzero if incoming time string is badly formed. + * Returns nonzero if incoming time string is badly formed. */ int tpTimeToCssmTimestring( const char *inStr, // not necessarily NULL terminated @@ -327,8 +327,8 @@ int tpTimeToCssmTimestring( tmp[1] = inStr[1]; tmp[2] = '\0'; year = atoi(tmp); - - /* + + /* * 0 <= year < 50 : assume century 21 * 50 <= year < 70 : illegal per PKIX * 70 < year <= 99 : assume century 20 @@ -353,7 +353,7 @@ int tpTimeToCssmTimestring( case GENERALIZED_TIME_STRLEN: memmove(outTime, inStr, inStrLen - 1); // don't copy the Z break; - + default: return 1; } diff --git a/OSX/libsecurity_apple_x509_tp/lib/tpTime.h b/OSX/libsecurity_apple_x509_tp/lib/tpTime.h index 0c9019a9..90fc8b98 100644 --- a/OSX/libsecurity_apple_x509_tp/lib/tpTime.h +++ b/OSX/libsecurity_apple_x509_tp/lib/tpTime.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved. - * + * Copyright (c) 2000-2001,2011,2014-2019 Apple Inc. All Rights Reserved. + * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. - * + * * This 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 @@ -20,7 +20,7 @@ * tpTime.h - cert related time functions * */ - + #ifndef _TP_TIME_H_ #define _TP_TIME_H_ @@ -36,14 +36,14 @@ extern "C" { #define UTC_TIME_NOSEC_LEN 11 #define UTC_TIME_STRLEN 13 #define CSSM_TIME_STRLEN 14 /* no trailing 'Z' */ -#define GENERALIZED_TIME_STRLEN 15 +#define GENERALIZED_TIME_STRLEN 15 #define LOCALIZED_UTC_TIME_STRLEN 17 #define LOCALIZED_TIME_STRLEN 19 /* * Given a string containing either a UTC-style or "generalized time" * time string, convert to a CFDateRef. Returns nonzero on - * error. + * error. */ extern int timeStringToCfDate( const char *str, @@ -59,7 +59,7 @@ extern int timeStringToCfDate( extern int compareTimes( CFDateRef t1, CFDateRef t2); - + /* * Create a time string, in either UTC (2-digit) or or Generalized (4-digit) * year format. Caller mallocs the output string whose length is at least @@ -67,9 +67,9 @@ extern int compareTimes( * respectively. Caller must hold tpTimeLock. */ typedef enum { - TIME_UTC, - TIME_GEN, - TIME_CSSM + TP_TIME_UTC = 0, + TP_TIME_GEN = 1, + TP_TIME_CSSM = 2 } TpTimeSpec; void timeAtNowPlus(unsigned secFromNow, @@ -80,7 +80,7 @@ void timeAtNowPlus(unsigned secFromNow, * Convert a time string, which can be in any of three forms (UTC, * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller * mallocs the result, which must be at least (CSSM_TIME_STRLEN+1) bytes. - * Returns nonzero if incoming time string is badly formed. + * Returns nonzero if incoming time string is badly formed. */ int tpTimeToCssmTimestring( const char *inStr, // not necessarily NULL terminated diff --git a/OSX/libsecurity_asn1/lib/SecAsn1Types.h b/OSX/libsecurity_asn1/lib/SecAsn1Types.h index 76616d62..78596a4e 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_OSX - -typedef struct { +typedef struct cssm_data { size_t Length; uint8_t * __nullable Data; } SecAsn1Item, SecAsn1Oid; @@ -65,17 +63,6 @@ typedef struct { SecAsn1Item subjectPublicKey; } SecAsn1PubKeyInfo; -#else -#include -#include - -typedef CSSM_DATA SecAsn1Item; -typedef CSSM_OID SecAsn1Oid; -typedef CSSM_X509_ALGORITHM_IDENTIFIER SecAsn1AlgId; -typedef CSSM_X509_SUBJECT_PUBLIC_KEY_INFO SecAsn1PubKeyInfo; - -#endif - CF_ASSUME_NONNULL_BEGIN /* diff --git a/OSX/libsecurity_asn1/lib/SecNssCoder.cpp b/OSX/libsecurity_asn1/lib/SecNssCoder.cpp index 08bac8fb..067fb8d8 100644 --- a/OSX/libsecurity_asn1/lib/SecNssCoder.cpp +++ b/OSX/libsecurity_asn1/lib/SecNssCoder.cpp @@ -25,7 +25,7 @@ */ #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #include "SecNssCoder.h" #include diff --git a/OSX/libsecurity_asn1/lib/asn1Templates.h b/OSX/libsecurity_asn1/lib/asn1Templates.h index ec00625f..9ee99fad 100644 --- a/OSX/libsecurity_asn1/lib/asn1Templates.h +++ b/OSX/libsecurity_asn1/lib/asn1Templates.h @@ -26,7 +26,9 @@ #ifndef _ASN1_TEMPLATES_H_ #define _ASN1_TEMPLATES_H_ +#ifndef SECURITY_PROJECT_TAPI_HACKS #warning This is for backwards compatibility. Please use instead. +#endif // SECURITY_PROJECT_TAPI_HACKS #include diff --git a/OSX/libsecurity_asn1/lib/csrTemplates.h b/OSX/libsecurity_asn1/lib/csrTemplates.h index bedc7e67..2db4197a 100644 --- a/OSX/libsecurity_asn1/lib/csrTemplates.h +++ b/OSX/libsecurity_asn1/lib/csrTemplates.h @@ -37,12 +37,12 @@ extern "C" { * ASN class : CertificationRequestInfo * C struct : NSSCertRequestInfo */ -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { SecAsn1Item version; NSS_Name subject; SecAsn1PubKeyInfo subjectPublicKeyInfo; NSS_Attribute **attributes; -} NSSCertRequestInfo; +} NSSCertRequestInfo DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; extern const SecAsn1Template kSecAsn1CertRequestInfoTemplate[]; @@ -50,11 +50,11 @@ extern const SecAsn1Template kSecAsn1CertRequestInfoTemplate[]; * ASN class : CertificationRequest * C struct : NSSCertRequest */ -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { NSSCertRequestInfo reqInfo; SecAsn1AlgId signatureAlgorithm; SecAsn1Item signature;// BIT STRING, length in bits -} NSSCertRequest; +} NSSCertRequest DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; extern const SecAsn1Template kSecAsn1CertRequestTemplate[]; @@ -62,11 +62,11 @@ extern const SecAsn1Template kSecAsn1CertRequestTemplate[]; * This is what we use use to avoid unnecessary setup and teardown of * a full NSSCertRequest when signing and verifying. */ -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { SecAsn1Item certRequestBlob; // encoded, ASN_ANY SecAsn1AlgId signatureAlgorithm; SecAsn1Item signature;// BIT STRING, length in bits -} NSS_SignedCertRequest; +} NSS_SignedCertRequest DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; extern const SecAsn1Template kSecAsn1SignedCertRequestTemplate[]; diff --git a/OSX/libsecurity_asn1/lib/keyTemplates.h b/OSX/libsecurity_asn1/lib/keyTemplates.h index ce726ff3..1b7c0bbe 100644 --- a/OSX/libsecurity_asn1/lib/keyTemplates.h +++ b/OSX/libsecurity_asn1/lib/keyTemplates.h @@ -71,12 +71,12 @@ extern const SecAsn1Template kSecAsn1SetOfAttributeTemplate[]; * ASN class : PrivateKeyInfo * C struct : NSS_PrivateKeyInfo */ -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { SecAsn1Item version; SecAsn1AlgId algorithm; SecAsn1Item privateKey; NSS_Attribute **attributes; -} NSS_PrivateKeyInfo; +} NSS_PrivateKeyInfo DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; extern const SecAsn1Template kSecAsn1PrivateKeyInfoTemplate[]; @@ -88,10 +88,10 @@ extern const SecAsn1Template kSecAsn1PrivateKeyInfoTemplate[]; * The decrypted encryptedData field is a DER-encoded * NSS_PrivateKeyInfo. */ -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { SecAsn1AlgId algorithm; SecAsn1Item encryptedData; -} NSS_EncryptedPrivateKeyInfo; +} NSS_EncryptedPrivateKeyInfo DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; extern const SecAsn1Template kSecAsn1EncryptedPrivateKeyInfoTemplate[]; @@ -99,10 +99,10 @@ extern const SecAsn1Template kSecAsn1EncryptedPrivateKeyInfoTemplate[]; * ASN class : DigestInfo * C struct : NSS_DigestInfo */ -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { SecAsn1AlgId digestAlgorithm; SecAsn1Item digest; -} NSS_DigestInfo; +} NSS_DigestInfo DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; extern const SecAsn1Template kSecAsn1DigestInfoTemplate[]; diff --git a/OSX/libsecurity_asn1/lib/secasn1e.c b/OSX/libsecurity_asn1/lib/secasn1e.c index e695972f..8a4cbc54 100644 --- a/OSX/libsecurity_asn1/lib/secasn1e.c +++ b/OSX/libsecurity_asn1/lib/secasn1e.c @@ -3,25 +3,25 @@ * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ - * + * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. - * + * * The Original Code is the Netscape security libraries. - * + * * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are + * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. - * + * * Contributor(s): - * + * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and @@ -60,6 +60,14 @@ typedef enum { needBytes } sec_asn1e_parse_status; +typedef enum { + hdr_normal = 0, /* encode header normally */ + hdr_any = 1, /* header already encoded in content */ + hdr_decoder = 2, /* template only used by decoder. skip it. */ + hdr_optional = 3, /* optional component, to be omitted */ + hdr_placeholder = 4 /* place holder for from_buf content */ +} sec_asn1e_hdr_encoding; + typedef struct sec_asn1e_state_struct { SEC_ASN1EncoderContext *top; const SecAsn1Template *theTemplate; @@ -80,16 +88,16 @@ typedef struct sec_asn1e_state_struct { int depth; PRBool explicit, /* we are handling an explicit header */ - indefinite, /* need end-of-contents */ - is_string, /* encoding a simple string or an ANY */ - may_stream, /* when streaming, do indefinite encoding */ - optional, /* omit field if it has no contents */ - ignore_stream /* ignore streaming value of sub-template */ - #ifdef __APPLE__ - , - signedInt /* signed alternate to SEC_ASN1_INTEGER */ - #endif - ; + indefinite, /* need end-of-contents */ + is_string, /* encoding a simple string or an ANY */ + may_stream, /* when streaming, do indefinite encoding */ + optional, /* omit field if it has no contents */ + ignore_stream /* ignore streaming value of sub-template */ +#ifdef __APPLE__ + , + signedInt /* signed alternate to SEC_ASN1_INTEGER */ +#endif + ; } sec_asn1e_state; /* @@ -117,33 +125,34 @@ struct sec_EncoderContext_struct { static sec_asn1e_state * -sec_asn1e_push_state (SEC_ASN1EncoderContext *cx, - const SecAsn1Template *theTemplate, - const void *src, PRBool new_depth) +sec_asn1e_push_state(SEC_ASN1EncoderContext *cx, + const SecAsn1Template *theTemplate, + const void *src, PRBool new_depth) { sec_asn1e_state *state, *new_state; state = cx->current; - new_state = (sec_asn1e_state*)PORT_ArenaZAlloc (cx->our_pool, - sizeof(*new_state)); + new_state = (sec_asn1e_state*)PORT_ArenaZAlloc(cx->our_pool, sizeof(*new_state)); if (new_state == NULL) { - cx->status = encodeError; - return NULL; + cx->status = encodeError; + return NULL; } new_state->top = cx; new_state->parent = state; new_state->theTemplate = theTemplate; new_state->place = notInUse; - if (src != NULL) - new_state->src = (char *)src + theTemplate->offset; + if (src != NULL) { + new_state->src = (char *)src + theTemplate->offset; + } if (state != NULL) { - new_state->depth = state->depth; - if (new_depth) - new_state->depth++; - state->child = new_state; + new_state->depth = state->depth; + if (new_depth) { + new_state->depth++; + } + state->child = new_state; } cx->current = new_state; @@ -152,7 +161,7 @@ sec_asn1e_push_state (SEC_ASN1EncoderContext *cx, static void -sec_asn1e_scrub_state (sec_asn1e_state *state) +sec_asn1e_scrub_state(sec_asn1e_state *state) { /* * Some default "scrubbing". @@ -164,44 +173,45 @@ sec_asn1e_scrub_state (sec_asn1e_state *state) static void -sec_asn1e_notify_before (SEC_ASN1EncoderContext *cx, void *src, int depth) +sec_asn1e_notify_before(SEC_ASN1EncoderContext *cx, void *src, int depth) { - if (cx->notify_proc == NULL) - return; + if (cx->notify_proc == NULL) { + return; + } cx->during_notify = PR_TRUE; - (* cx->notify_proc) (cx->notify_arg, PR_TRUE, src, depth); + (* cx->notify_proc)(cx->notify_arg, PR_TRUE, src, depth); cx->during_notify = PR_FALSE; } static void -sec_asn1e_notify_after (SEC_ASN1EncoderContext *cx, void *src, int depth) +sec_asn1e_notify_after(SEC_ASN1EncoderContext *cx, void *src, int depth) { - if (cx->notify_proc == NULL) - return; + if (cx->notify_proc == NULL) { + return; + } cx->during_notify = PR_TRUE; - (* cx->notify_proc) (cx->notify_arg, PR_FALSE, src, depth); + (* cx->notify_proc)(cx->notify_arg, PR_FALSE, src, depth); cx->during_notify = PR_FALSE; } static sec_asn1e_state * -sec_asn1e_init_state_based_on_template (sec_asn1e_state *state) +sec_asn1e_init_state_based_on_template(sec_asn1e_state *state) { PRBool explicit, is_string, may_stream, optional, universal, ignore_stream; unsigned char tag_modifiers; unsigned long encode_kind, under_kind; unsigned long tag_number; - #ifdef __APPLE__ - PRBool signedInt, dynamic; - #endif +#ifdef __APPLE__ + PRBool signedInt, dynamic; +#endif encode_kind = state->theTemplate->kind; - universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) - ? PR_TRUE : PR_FALSE; + universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) ? PR_TRUE : PR_FALSE; explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_EXPLICIT; @@ -209,7 +219,7 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state) optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_OPTIONAL; - PORT_Assert (!(explicit && universal)); /* bad templates */ + PORT_Assert(!(explicit && universal)); /* bad templates */ may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_MAY_STREAM; @@ -217,104 +227,104 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state) ignore_stream = (encode_kind & SEC_ASN1_NO_STREAM) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_NO_STREAM; - #ifdef __APPLE__ - signedInt = (encode_kind & SEC_ASN1_SIGNED_INT) ? PR_TRUE : PR_FALSE; +#ifdef __APPLE__ + signedInt = (encode_kind & SEC_ASN1_SIGNED_INT) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_SIGNED_INT; - #endif +#endif - #ifdef __APPLE__ - dynamic = (encode_kind & SEC_ASN1_DYNAMIC) ? PR_TRUE : PR_FALSE; - #endif +#ifdef __APPLE__ + dynamic = (encode_kind & SEC_ASN1_DYNAMIC) ? PR_TRUE : PR_FALSE; +#endif encode_kind &= ~SEC_ASN1_DYNAMIC; if( encode_kind & SEC_ASN1_CHOICE ) { - under_kind = SEC_ASN1_CHOICE; - } else - - if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || (!universal - && !explicit)) { - const SecAsn1Template *subt; - void *src; - - PORT_Assert ((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0); - - sec_asn1e_scrub_state (state); - - if (encode_kind & SEC_ASN1_POINTER) { - /* - * XXX This used to PORT_Assert (encode_kind == SEC_ASN1_POINTER); - * but that was too restrictive. This needs to be fixed, - * probably copying what the decoder now checks for, and - * adding a big comment here to explain what the checks mean. - */ - src = *(void **)state->src; - state->place = afterPointer; - if (src == NULL) { - /* - * If this is optional, but NULL, then the field does - * not need to be encoded. In this case we are done; - * we do not want to push a subtemplate. - */ - if (optional) - return state; - - /* - * XXX this is an error; need to figure out - * how to handle this - */ - } - } else { - src = state->src; - if (encode_kind & SEC_ASN1_INLINE) { - /* check that there are no extraneous bits */ - PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); - state->place = afterInline; - } else { - /* - * Save the tag modifiers and tag number here before moving - * on to the next state in case this is a member of a - * SEQUENCE OF - */ - state->tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK - & ~SEC_ASN1_TAGNUM_MASK; - state->tag_number = (unsigned char)encode_kind & SEC_ASN1_TAGNUM_MASK; - - state->place = afterImplicit; - state->optional = optional; - } - } - - subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->src, PR_TRUE, - NULL /* __APPLE__ */, 0 /* __APPLE__ */); - state = sec_asn1e_push_state (state->top, subt, src, PR_FALSE); - if (state == NULL) - return NULL; - - if (universal) { - /* - * This is a POINTER or INLINE; just init based on that - * and we are done. - */ - return sec_asn1e_init_state_based_on_template (state); - } - - /* - * This is an implicit, non-universal (meaning, application-private - * or context-specific) field. This results in a "magic" tag but - * encoding based on the underlying type. We pushed a new state - * that is based on the subtemplate (the underlying type), but - * now we will sort of alias it to give it some of our properties - * (tag, optional status, etc.). - */ - - under_kind = state->theTemplate->kind; - if (under_kind & SEC_ASN1_MAY_STREAM) { - if (!ignore_stream) - may_stream = PR_TRUE; - under_kind &= ~SEC_ASN1_MAY_STREAM; - } + under_kind = SEC_ASN1_CHOICE; + } else if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || + (!universal && !explicit)) { + const SecAsn1Template *subt; + void *src = NULL; + + PORT_Assert((encode_kind & (SEC_ASN1_ANY | SEC_ASN1_SKIP)) == 0); + + sec_asn1e_scrub_state(state); + + if (encode_kind & SEC_ASN1_POINTER) { + /* + * XXX This used to PORT_Assert (encode_kind == SEC_ASN1_POINTER); + * but that was too restrictive. This needs to be fixed, + * probably copying what the decoder now checks for, and + * adding a big comment here to explain what the checks mean. + */ + src = *(void **)state->src; + state->place = afterPointer; + if (src == NULL) { + /* + * If this is optional, but NULL, then the field does + * not need to be encoded. In this case we are done; + * we do not want to push a subtemplate. + */ + if (optional) { + return state; + } + + /* + * XXX this is an error; need to figure out + * how to handle this + */ + } + } else { + src = state->src; + if (encode_kind & SEC_ASN1_INLINE) { + /* check that there are no extraneous bits */ + PORT_Assert(encode_kind == SEC_ASN1_INLINE && !optional); + state->place = afterInline; + } else { + /* + * Save the tag modifiers and tag number here before moving + * on to the next state in case this is a member of a + * SEQUENCE OF + */ + state->tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK; + state->tag_number = (unsigned char)encode_kind & SEC_ASN1_TAGNUM_MASK; + + state->place = afterImplicit; + state->optional = optional; + } + } + + subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->src, PR_TRUE, + NULL /* __APPLE__ */, 0 /* __APPLE__ */); + state = sec_asn1e_push_state(state->top, subt, src, PR_FALSE); + if (state == NULL) { + return NULL; + } + + if (universal) { + /* + * This is a POINTER or INLINE; just init based on that + * and we are done. + */ + return sec_asn1e_init_state_based_on_template(state); + } + + /* + * This is an implicit, non-universal (meaning, application-private + * or context-specific) field. This results in a "magic" tag but + * encoding based on the underlying type. We pushed a new state + * that is based on the subtemplate (the underlying type), but + * now we will sort of alias it to give it some of our properties + * (tag, optional status, etc.). + */ + + under_kind = state->theTemplate->kind; + if (under_kind & SEC_ASN1_MAY_STREAM) { + if (!ignore_stream) { + may_stream = PR_TRUE; + } + under_kind &= ~SEC_ASN1_MAY_STREAM; + } } else { - under_kind = encode_kind; + under_kind = encode_kind; } /* @@ -324,70 +334,69 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state) * XXX is this the right set of bits to test here? (i.e. need to add * or remove any?) */ - PORT_Assert ((under_kind & (/*SEC_ASN1_EXPLICIT | */SEC_ASN1_OPTIONAL - | SEC_ASN1_SKIP | SEC_ASN1_INNER - | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM - | SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0); + PORT_Assert((under_kind & (/*SEC_ASN1_EXPLICIT | */SEC_ASN1_OPTIONAL + | SEC_ASN1_SKIP | SEC_ASN1_INNER + | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM + | SEC_ASN1_INLINE | SEC_ASN1_POINTER)) == 0); if (encode_kind & SEC_ASN1_ANY) { - PORT_Assert (encode_kind == under_kind); - tag_modifiers = 0; - tag_number = 0; - is_string = PR_TRUE; + PORT_Assert(encode_kind == under_kind); + tag_modifiers = 0; + tag_number = 0; + is_string = PR_TRUE; } else { - tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK & - ~SEC_ASN1_TAGNUM_MASK; - /* - * XXX This assumes only single-octet identifiers. To handle - * the HIGH TAG form we would need to do some more work, especially - * in how to specify them in the template, because right now we - * do not provide a way to specify more *tag* bits in encode_kind. - */ - - #ifdef __APPLE__ - /* - * Apple change: if this is a DYNAMIC template, use the tag number - * from the subtemplate's kind - */ - if(dynamic) { - tag_number = state->theTemplate->kind & SEC_ASN1_TAGNUM_MASK; - explicit = (state->theTemplate->kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE; - tag_modifiers |= (state->theTemplate->kind & SEC_ASN1_CONSTRUCTED); - } - else - #endif /* __APPLE__ */ - tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK; - - is_string = PR_FALSE; - switch (under_kind & SEC_ASN1_TAGNUM_MASK) { - case SEC_ASN1_SET: - /* - * XXX A plain old SET (as opposed to a SET OF) is not implemented. - * If it ever is, remove this assert... - */ - PORT_Assert ((under_kind & SEC_ASN1_GROUP) != 0); - /* fallthru */ - case SEC_ASN1_SEQUENCE: - tag_modifiers |= SEC_ASN1_CONSTRUCTED; - break; - case SEC_ASN1_BIT_STRING: - case SEC_ASN1_BMP_STRING: - case SEC_ASN1_GENERALIZED_TIME: - case SEC_ASN1_IA5_STRING: - case SEC_ASN1_OCTET_STRING: - case SEC_ASN1_PRINTABLE_STRING: - case SEC_ASN1_T61_STRING: - case SEC_ASN1_UNIVERSAL_STRING: - case SEC_ASN1_UTC_TIME: - case SEC_ASN1_UTF8_STRING: - case SEC_ASN1_VISIBLE_STRING: - /* - * We do not yet know if we will be constructing the string, - * so we have to wait to do this final tag modification. - */ - is_string = PR_TRUE; - break; - } + tag_modifiers = (unsigned char)encode_kind & SEC_ASN1_TAG_MASK & ~SEC_ASN1_TAGNUM_MASK; + /* + * XXX This assumes only single-octet identifiers. To handle + * the HIGH TAG form we would need to do some more work, especially + * in how to specify them in the template, because right now we + * do not provide a way to specify more *tag* bits in encode_kind. + */ + +#ifdef __APPLE__ + /* + * Apple change: if this is a DYNAMIC template, use the tag number + * from the subtemplate's kind + */ + if (dynamic) { + tag_number = state->theTemplate->kind & SEC_ASN1_TAGNUM_MASK; + explicit = (state->theTemplate->kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE; + tag_modifiers |= (state->theTemplate->kind & SEC_ASN1_CONSTRUCTED); + } + else +#endif /* __APPLE__ */ + tag_number = encode_kind & SEC_ASN1_TAGNUM_MASK; + + is_string = PR_FALSE; + switch (under_kind & SEC_ASN1_TAGNUM_MASK) { + case SEC_ASN1_SET: + /* + * XXX A plain old SET (as opposed to a SET OF) is not implemented. + * If it ever is, remove this assert... + */ + PORT_Assert((under_kind & SEC_ASN1_GROUP) != 0); + /* fallthru */ + case SEC_ASN1_SEQUENCE: + tag_modifiers |= SEC_ASN1_CONSTRUCTED; + break; + case SEC_ASN1_BIT_STRING: + case SEC_ASN1_BMP_STRING: + case SEC_ASN1_GENERALIZED_TIME: + case SEC_ASN1_IA5_STRING: + case SEC_ASN1_OCTET_STRING: + case SEC_ASN1_PRINTABLE_STRING: + case SEC_ASN1_T61_STRING: + case SEC_ASN1_UNIVERSAL_STRING: + case SEC_ASN1_UTC_TIME: + case SEC_ASN1_UTF8_STRING: + case SEC_ASN1_VISIBLE_STRING: + /* + * We do not yet know if we will be constructing the string, + * so we have to wait to do this final tag modification. + */ + is_string = PR_TRUE; + break; + } } state->tag_modifiers = tag_modifiers; @@ -398,25 +407,25 @@ sec_asn1e_init_state_based_on_template (sec_asn1e_state *state) state->is_string = is_string; state->optional = optional; state->ignore_stream = ignore_stream; - #ifdef __APPLE__ - state->signedInt = signedInt; - #endif +#ifdef __APPLE__ + state->signedInt = signedInt; +#endif - sec_asn1e_scrub_state (state); + sec_asn1e_scrub_state(state); return state; } static void -sec_asn1e_write_part (sec_asn1e_state *state, - const char *buf, size_t len, - SEC_ASN1EncodingPart part) +sec_asn1e_write_part(sec_asn1e_state *state, + const char *buf, size_t len, + SEC_ASN1EncodingPart part) { SEC_ASN1EncoderContext *cx; cx = state->top; - (* cx->output_proc) (cx->output_arg, buf, len, state->depth, part); + (* cx->output_proc)(cx->output_arg, buf, len, state->depth, part); } @@ -426,110 +435,107 @@ sec_asn1e_write_part (sec_asn1e_state *state, * teach it to properly encode the special form. */ static void -sec_asn1e_write_identifier_bytes (sec_asn1e_state *state, unsigned char value) +sec_asn1e_write_identifier_bytes(sec_asn1e_state *state, unsigned char value) { char byte; byte = (char) value; - sec_asn1e_write_part (state, &byte, 1, SEC_ASN1_Identifier); + sec_asn1e_write_part(state, &byte, 1, SEC_ASN1_Identifier); } int SEC_ASN1EncodeLength(unsigned char *buf,unsigned long value) { int lenlen; - lenlen = SEC_ASN1LengthLength (value); + lenlen = SEC_ASN1LengthLength(value); if (lenlen == 1) { - buf[0] = value; + buf[0] = value; } else { - int i; - - i = lenlen - 1; - buf[0] = 0x80 | i; - while (i) { - buf[i--] = value; - value >>= 8; - } - PORT_Assert (value == 0); + int i; + + i = lenlen - 1; + buf[0] = 0x80 | i; + while (i) { + buf[i--] = value; + value >>= 8; + } + PORT_Assert(value == 0); } return lenlen; } static void -sec_asn1e_write_length_bytes (sec_asn1e_state *state, unsigned long value, - PRBool indefinite) +sec_asn1e_write_length_bytes(sec_asn1e_state *state, unsigned long value, + PRBool indefinite) { int lenlen; unsigned char buf[sizeof(unsigned long) + 1]; if (indefinite) { - PORT_Assert (value == 0); - buf[0] = 0x80; - lenlen = 1; + PORT_Assert(value == 0); + buf[0] = 0x80; + lenlen = 1; } else { - lenlen = SEC_ASN1EncodeLength(buf,value); + lenlen = SEC_ASN1EncodeLength(buf,value); } - sec_asn1e_write_part (state, (char *) buf, lenlen, SEC_ASN1_Length); + sec_asn1e_write_part(state, (char *) buf, lenlen, SEC_ASN1_Length); } static void -sec_asn1e_write_contents_bytes (sec_asn1e_state *state, - const char *buf, unsigned long len) +sec_asn1e_write_contents_bytes(sec_asn1e_state *state, + const char *buf, unsigned long len) { - sec_asn1e_write_part (state, buf, len, SEC_ASN1_Contents); + sec_asn1e_write_part(state, buf, len, SEC_ASN1_Contents); } static void -sec_asn1e_write_end_of_contents_bytes (sec_asn1e_state *state) +sec_asn1e_write_end_of_contents_bytes(sec_asn1e_state *state) { const char eoc[2] = {0, 0}; - sec_asn1e_write_part (state, eoc, 2, SEC_ASN1_EndOfContents); + sec_asn1e_write_part(state, eoc, 2, SEC_ASN1_EndOfContents); } static int -sec_asn1e_which_choice -( - void *src, - const SecAsn1Template *theTemplate -) +sec_asn1e_which_choice(void *src, const SecAsn1Template *theTemplate) { - int rv; - unsigned int which = *(unsigned int *)src; + int rv; + unsigned int which = *(unsigned int *)src; - for( rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++ ) { - if( which == theTemplate->size ) { - return rv; + for( rv = 1, theTemplate++; theTemplate->kind != 0; rv++, theTemplate++ ) { + if( which == theTemplate->size ) { + return rv; + } } - } - return 0; + return 0; } static unsigned long -sec_asn1e_contents_length (const SecAsn1Template *theTemplate, void *src, - PRBool ignoresubstream, PRBool *noheaderp) +sec_asn1e_contents_length(const SecAsn1Template *theTemplate, void *src, + PRBool ignoresubstream, PRBool insideIndefinite, + sec_asn1e_hdr_encoding *pHdrException) { unsigned long encode_kind, underlying_kind; PRBool explicit, optional, universal, may_stream; unsigned long len; - #ifdef __APPLE__ - PRBool signedInt; - #endif - +#ifdef __APPLE__ + PRBool signedInt; +#endif + /* * This function currently calculates the length in all cases - * except the following: when writing out the contents of a + * except the following: when writing out the contents of a * template that belongs to a state where it was a sub-template * with the SEC_ASN1_MAY_STREAM bit set and it's parent had the * optional bit set. The information that the parent is optional - * and that we should return the length of 0 when that length is + * and that we should return the length of 0 when that length is * present since that means the optional field is no longer present. * So we add the ignoresubstream flag which is passed in when - * writing the contents, but for all recursive calls to + * writing the contents, but for all recursive calls to * sec_asn1e_contents_length, we pass PR_FALSE, because this * function correctly calculates the length for children templates * from that point on. Confused yet? At least you didn't have @@ -537,8 +543,7 @@ sec_asn1e_contents_length (const SecAsn1Template *theTemplate, void *src, */ encode_kind = theTemplate->kind; - universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) - ? PR_TRUE : PR_FALSE; + universal = ((encode_kind & SEC_ASN1_CLASS_MASK) == SEC_ASN1_UNIVERSAL) ? PR_TRUE : PR_FALSE; explicit = (encode_kind & SEC_ASN1_EXPLICIT) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_EXPLICIT; @@ -546,242 +551,253 @@ sec_asn1e_contents_length (const SecAsn1Template *theTemplate, void *src, optional = (encode_kind & SEC_ASN1_OPTIONAL) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_OPTIONAL; - PORT_Assert (!(explicit && universal)); /* bad templates */ + PORT_Assert(!(explicit && universal)); /* bad templates */ may_stream = (encode_kind & SEC_ASN1_MAY_STREAM) ? PR_TRUE : PR_FALSE; encode_kind &= ~SEC_ASN1_MAY_STREAM; /* Just clear this to get it out of the way; we do not need it here */ encode_kind &= ~SEC_ASN1_DYNAMIC; + + if (encode_kind & SEC_ASN1_NO_STREAM) { + ignoresubstream = PR_TRUE; + } encode_kind &= ~SEC_ASN1_NO_STREAM; - if( encode_kind & SEC_ASN1_CHOICE ) { - void *src2; - int indx = sec_asn1e_which_choice(src, theTemplate); - if( 0 == indx ) { - /* XXX set an error? "choice not found" */ - /* state->top->status = encodeError; */ - return 0; - } + if (encode_kind & SEC_ASN1_CHOICE) { + void *src2; + int indx = sec_asn1e_which_choice(src, theTemplate); + if( 0 == indx ) { + /* XXX set an error? "choice not found" */ + /* state->top->status = encodeError; */ + return 0; + } - src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset); + src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset); - return sec_asn1e_contents_length(&theTemplate[indx], src2, - PR_FALSE, noheaderp); + return sec_asn1e_contents_length(&theTemplate[indx], src2, + ignoresubstream, insideIndefinite, + pHdrException); } if ((encode_kind & (SEC_ASN1_POINTER | SEC_ASN1_INLINE)) || !universal) { - /* XXX any bits we want to disallow (PORT_Assert against) here? */ - - theTemplate = SEC_ASN1GetSubtemplate (theTemplate, src, PR_TRUE, - NULL /* __APPLE__ */, 0 /* __APPLE__ */); - - if (encode_kind & SEC_ASN1_POINTER) { - /* - * XXX This used to PORT_Assert (encode_kind == SEC_ASN1_POINTER); - * but that was too restrictive. This needs to be fixed, - * probably copying what the decoder now checks for, and - * adding a big comment here to explain what the checks mean. - * Alternatively, the check here could be omitted altogether - * just letting sec_asn1e_init_state_based_on_template - * do it, since that routine can do better error handling, too. - */ - src = *(void **)src; - if (src == NULL) { - if (optional) - *noheaderp = PR_TRUE; - else - *noheaderp = PR_FALSE; - return 0; - } - } else if (encode_kind & SEC_ASN1_INLINE) { - /* check that there are no extraneous bits */ - PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); - } - - src = (char *)src + theTemplate->offset; - - if (explicit) { - len = sec_asn1e_contents_length (theTemplate, src, PR_FALSE, - noheaderp); - if (len == 0 && optional) { - *noheaderp = PR_TRUE; - } else if (*noheaderp) { - /* Okay, *we* do not want to add in a header, but our caller still does. */ - *noheaderp = PR_FALSE; - } else { - /* if the inner content exists, our length is - * len(identifier) + len(length) + len(innercontent) - * XXX we currently assume len(identifier) == 1; - * to support a high-tag-number this would need to be smarter. - */ - len += 1 + SEC_ASN1LengthLength (len); - } - return len; - } - - underlying_kind = theTemplate->kind; - underlying_kind &= ~SEC_ASN1_MAY_STREAM; - /* XXX Should we recurse here? */ - } else { - underlying_kind = encode_kind; + /* XXX any bits we want to disallow (PORT_Assert against) here? */ + + theTemplate = SEC_ASN1GetSubtemplate(theTemplate, src, PR_TRUE, + NULL /* __APPLE__ */, 0 /* __APPLE__ */); + + if (encode_kind & SEC_ASN1_POINTER) { + /* + * XXX This used to PORT_Assert (encode_kind == SEC_ASN1_POINTER); + * but that was too restrictive. This needs to be fixed, + * probably copying what the decoder now checks for, and + * adding a big comment here to explain what the checks mean. + * Alternatively, the check here could be omitted altogether + * just letting sec_asn1e_init_state_based_on_template + * do it, since that routine can do better error handling, too. + */ + src = *(void **)src; + if (src == NULL) { + *pHdrException = optional ? hdr_optional : hdr_normal; + return 0; + } + } else if (encode_kind & SEC_ASN1_INLINE) { + /* check that there are no extraneous bits */ + PORT_Assert (encode_kind == SEC_ASN1_INLINE && !optional); + } + + src = (char *)src + theTemplate->offset; + + len = sec_asn1e_contents_length(theTemplate, src, + ignoresubstream, insideIndefinite, + pHdrException); + if (len == 0 && optional) { + *pHdrException = hdr_optional; + } else if (explicit) { + if (*pHdrException == hdr_any) { + /* *we* do not want to add in a header, + ** but our caller still does. + */ + *pHdrException = hdr_normal; + } else if (*pHdrException == hdr_normal) { + /* if the inner content exists, our length is + * len(identifier) + len(length) + len(innercontent) + * XXX we currently assume len(identifier) == 1; + * to support a high-tag-number this would need to be smarter. + */ + len += 1 + SEC_ASN1LengthLength(len); + } + } + return len; } - #ifdef __APPLE__ - signedInt = (underlying_kind & SEC_ASN1_SIGNED_INT) ? - PR_TRUE : PR_FALSE; - #endif - + underlying_kind = encode_kind; + +#ifdef __APPLE__ + signedInt = (underlying_kind & SEC_ASN1_SIGNED_INT) ? + PR_TRUE : PR_FALSE; +#endif + /* This is only used in decoding; it plays no part in encoding. */ if (underlying_kind & SEC_ASN1_SAVE) { - /* check that there are no extraneous bits */ - PORT_Assert (underlying_kind == SEC_ASN1_SAVE); - *noheaderp = PR_TRUE; - return 0; + /* check that there are no extraneous bits */ + PORT_Assert (underlying_kind == SEC_ASN1_SAVE); + *pHdrException = hdr_decoder; + return 0; } /* Having any of these bits is not expected here... */ PORT_Assert ((underlying_kind & (SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL - | SEC_ASN1_INLINE | SEC_ASN1_POINTER - | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM - | SEC_ASN1_SAVE | SEC_ASN1_SKIP)) == 0); - - if( underlying_kind & SEC_ASN1_CHOICE ) { - void *src2; - int indx = sec_asn1e_which_choice(src, theTemplate); - if( 0 == indx ) { - /* XXX set an error? "choice not found" */ - /* state->top->status = encodeError; */ - return 0; - } - - src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset); - len = sec_asn1e_contents_length(&theTemplate[indx], src2, PR_FALSE, - noheaderp); - } else - - switch (underlying_kind) { - case SEC_ASN1_SEQUENCE_OF: - case SEC_ASN1_SET_OF: - { - const SecAsn1Template *tmpt; - void *sub_src; - unsigned long sub_len; - void **group; - - len = 0; - - group = *(void ***)src; - if (group == NULL) - break; - - tmpt = SEC_ASN1GetSubtemplate (theTemplate, src, PR_TRUE, - NULL /* __APPLE__ */, 0 /* __APPLE__ */); - - for (; *group != NULL; group++) { - sub_src = (char *)(*group) + tmpt->offset; - sub_len = sec_asn1e_contents_length (tmpt, sub_src, PR_FALSE, - noheaderp); - len += sub_len; - /* - * XXX The 1 below is the presumed length of the identifier; - * to support a high-tag-number this would need to be smarter. - */ - if (!*noheaderp) - len += 1 + SEC_ASN1LengthLength (sub_len); - } - } - break; - - case SEC_ASN1_SEQUENCE: - case SEC_ASN1_SET: - { - const SecAsn1Template *tmpt; - void *sub_src; - unsigned long sub_len; - - len = 0; - for (tmpt = theTemplate + 1; tmpt->kind; tmpt++) { - sub_src = (char *)src + tmpt->offset; - sub_len = sec_asn1e_contents_length (tmpt, sub_src, PR_FALSE, - noheaderp); - len += sub_len; - /* - * XXX The 1 below is the presumed length of the identifier; - * to support a high-tag-number this would need to be smarter. - */ - if (!*noheaderp) - len += 1 + SEC_ASN1LengthLength (sub_len); - } - } - break; - - case SEC_ASN1_BIT_STRING: - /* convert bit length to byte */ - len = (((SecAsn1Item *)src)->Length + 7) >> 3; - /* bit string contents involve an extra octet */ - if (len) - len++; - break; - - case SEC_ASN1_INTEGER: - /* ASN.1 INTEGERs are signed. - * If the source is an unsigned integer, the encoder will need - * to handle the conversion here. - */ - { - unsigned char *buf = ((SecAsn1Item *)src)->Data; - #ifndef __APPLE__ - SecAsn1ItemType integerType = ((SecAsn1Item *)src)->type; - #endif - len = ((SecAsn1Item *)src)->Length; - while (len > 0) { - if (*buf != 0) { - #ifdef __APPLE__ - if (*buf & 0x80 && !signedInt) { - #else - if (*buf & 0x80 && integerType == siUnsignedInteger) { - #endif // __APPLE__ - len++; /* leading zero needed to make number signed */ - } - break; /* reached beginning of number */ - } - if (len == 1) { - break; /* the number 0 */ - } - if (buf[1] & 0x80) { - break; /* leading zero already present */ - } - /* extraneous leading zero, keep going */ - buf++; - len--; - } - } - break; - - default: - len = ((SecAsn1Item *)src)->Length; - if (may_stream && len == 0 && !ignoresubstream) - len = 1; /* if we're streaming, we may have a secitem w/len 0 as placeholder */ - break; - } - - if ((len == 0 && optional) || underlying_kind == SEC_ASN1_ANY) - *noheaderp = PR_TRUE; - else - *noheaderp = PR_FALSE; + | SEC_ASN1_INLINE | SEC_ASN1_POINTER + | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM + | SEC_ASN1_SAVE | SEC_ASN1_SKIP)) == 0); + + if (underlying_kind & SEC_ASN1_CHOICE) { + void *src2; + int indx = sec_asn1e_which_choice(src, theTemplate); + if( 0 == indx ) { + /* XXX set an error? "choice not found" */ + /* state->top->status = encodeError; */ + return 0; + } + + src2 = (void *)((char *)src - theTemplate->offset + theTemplate[indx].offset); + len = sec_asn1e_contents_length(&theTemplate[indx], src2, ignoresubstream, + insideIndefinite, pHdrException); + } else { + switch (underlying_kind) { + case SEC_ASN1_SEQUENCE_OF: + case SEC_ASN1_SET_OF: { + const SecAsn1Template *tmpt; + void *sub_src; + unsigned long sub_len; + void **group; + + len = 0; + + group = *(void ***)src; + if (group == NULL) { + break; + } + + tmpt = SEC_ASN1GetSubtemplate(theTemplate, src, PR_TRUE, + NULL /* __APPLE__ */, 0 /* __APPLE__ */); + + for (; *group != NULL; group++) { + sub_src = (char *)(*group) + tmpt->offset; + sub_len = sec_asn1e_contents_length(tmpt, sub_src, ignoresubstream, + insideIndefinite, pHdrException); + len += sub_len; + /* + * XXX The 1 below is the presumed length of the identifier; + * to support a high-tag-number this would need to be smarter. + */ + if (*pHdrException == hdr_normal) { + len += 1 + SEC_ASN1LengthLength(sub_len); + } + } + } + break; + + case SEC_ASN1_SEQUENCE: + case SEC_ASN1_SET: { + const SecAsn1Template *tmpt; + void *sub_src; + unsigned long sub_len; + + len = 0; + for (tmpt = theTemplate + 1; tmpt->kind; tmpt++) { + sub_src = (char *)src + tmpt->offset; + sub_len = sec_asn1e_contents_length(tmpt, sub_src, ignoresubstream, + insideIndefinite, pHdrException); + len += sub_len; + /* + * XXX The 1 below is the presumed length of the identifier; + * to support a high-tag-number this would need to be smarter. + */ + if (*pHdrException == hdr_normal) { + len += 1 + SEC_ASN1LengthLength (sub_len); + } + } + } + break; + + case SEC_ASN1_BIT_STRING: + /* convert bit length to byte */ + len = (((SecAsn1Item *)src)->Length + 7) >> 3; + /* bit string contents involve an extra octet */ + if (len) { + len++; + } + break; + + case SEC_ASN1_INTEGER: { + /* ASN.1 INTEGERs are signed. + * If the source is an unsigned integer, the encoder will need + * to handle the conversion here. + */ + unsigned char *buf = ((SecAsn1Item *)src)->Data; +#ifndef __APPLE__ + SecAsn1ItemType integerType = ((SecAsn1Item *)src)->type; +#endif + len = ((SecAsn1Item *)src)->Length; + while (len > 0) { + if (*buf != 0) { +#ifdef __APPLE__ + if (*buf & 0x80 && !signedInt) +#else + if (*buf & 0x80 && integerType == siUnsignedInteger) +#endif // __APPLE__ + { + len++; /* leading zero needed to make number signed */ + } + break; /* reached beginning of number */ + } + if (len == 1) { + break; /* the number 0 */ + } + if (buf[1] & 0x80) { + break; /* leading zero already present */ + } + /* extraneous leading zero, keep going */ + buf++; + len--; + } + } + break; + + default: + len = ((SecAsn1Item *)src)->Length; + break; + } /* end switch */ + +#ifndef WHAT_PROBLEM_DOES_THIS_SOLVE + /* if we're streaming, we may have a secitem w/len 0 as placeholder */ + if (!len && insideIndefinite && may_stream && !ignoresubstream) { + len = 1; + } +#endif + } /* end else */ + + if (len == 0 && optional) + *pHdrException = hdr_optional; + else if (underlying_kind == SEC_ASN1_ANY) + *pHdrException = hdr_any; + else + *pHdrException = hdr_normal; return len; } static void -sec_asn1e_write_header (sec_asn1e_state *state) +sec_asn1e_write_header(sec_asn1e_state *state) { unsigned long contents_length; unsigned char tag_number, tag_modifiers; - PRBool noheader; + sec_asn1e_hdr_encoding hdrException = hdr_normal; + PRBool indefinite = PR_FALSE; PORT_Assert (state->place == beforeHeader); @@ -789,89 +805,101 @@ sec_asn1e_write_header (sec_asn1e_state *state) tag_modifiers = state->tag_modifiers; if (state->underlying_kind == SEC_ASN1_ANY) { - state->place = duringContents; - return; + state->place = duringContents; + return; } - if( state->underlying_kind & SEC_ASN1_CHOICE ) { - int indx = sec_asn1e_which_choice(state->src, state->theTemplate); - if( 0 == indx ) { - /* XXX set an error? "choice not found" */ - state->top->status = encodeError; + if (state->underlying_kind & SEC_ASN1_CHOICE) { + int indx = sec_asn1e_which_choice(state->src, state->theTemplate); + if( 0 == indx ) { + /* XXX set an error? "choice not found" */ + state->top->status = encodeError; + return; + } + + state->place = afterChoice; + state = sec_asn1e_push_state(state->top, &state->theTemplate[indx], + (char *)state->src - state->theTemplate->offset, + PR_TRUE); + + if (state) { + /* + * Do the "before" field notification. + */ + sec_asn1e_notify_before (state->top, state->src, state->depth); + (void)sec_asn1e_init_state_based_on_template (state); + } return; - } - - state->place = afterChoice; - state = sec_asn1e_push_state(state->top, &state->theTemplate[indx], - (char *)state->src - state->theTemplate->offset, - PR_TRUE); - - if( (sec_asn1e_state *)NULL != state ) { - /* - * Do the "before" field notification. - */ - sec_asn1e_notify_before (state->top, state->src, state->depth); - state = sec_asn1e_init_state_based_on_template (state); - } - - (void) state; - - return; } + /* The !isString test below is apparently intended to ensure that all + ** constructed types receive indefinite length encoding. + */ + indefinite = (PRBool)(state->top->streaming && state->may_stream && + (state->top->from_buf || !state->is_string)); + /* - * We are doing a definite-length encoding. First we have to + * If we are doing a definite-length encoding, first we have to * walk the data structure to calculate the entire contents length. + * If we are doing an indefinite-length encoding, we still need to + * know if the contents is: + * optional and to be omitted, or + * an ANY (header is pre-encoded), or + * a SAVE or some other kind of template used only by the decoder. + * So, we call this function either way. */ - contents_length = sec_asn1e_contents_length (state->theTemplate, - state->src, - state->ignore_stream, - &noheader); + contents_length = sec_asn1e_contents_length(state->theTemplate, + state->src, + state->ignore_stream, + indefinite, + &hdrException); /* * We might be told explicitly not to put out a header. * But it can also be the case, via a pushed subtemplate, that * sec_asn1e_contents_length could not know that this field is * really optional. So check for that explicitly, too. */ - if (noheader || (contents_length == 0 && state->optional)) { - state->place = afterContents; - if (state->top->streaming && state->may_stream && state->top->from_buf) - /* we did not find an optional indefinite string, so we don't encode it. - * However, if TakeFromBuf is on, we stop here anyway to give our caller - * a chance to intercept at the same point where we would stop if the - * field were present. */ - state->top->status = needBytes; - return; + if (hdrException != hdr_normal || + (contents_length == 0 && state->optional)) { + state->place = afterContents; + if (state->top->streaming && + state->may_stream && + state->top->from_buf) { + /* we did not find an optional indefinite string, so we + * don't encode it. However, if TakeFromBuf is on, we stop + * here anyway to give our caller a chance to intercept at the + * same point where we would stop if the field were present. + */ + state->top->status = needBytes; + } + return; } - if (state->top->streaming && state->may_stream - && (state->top->from_buf || !state->is_string)) { - /* - * We need to put out an indefinite-length encoding. - */ - state->indefinite = PR_TRUE; - /* - * The only universal types that can be constructed are SETs, - * SEQUENCEs, and strings; so check that it is one of those, - * or that it is not universal (e.g. context-specific). - */ - PORT_Assert ((tag_number == SEC_ASN1_SET) - || (tag_number == SEC_ASN1_SEQUENCE) - || ((tag_modifiers & SEC_ASN1_CLASS_MASK) != 0) - || state->is_string); - tag_modifiers |= SEC_ASN1_CONSTRUCTED; - contents_length = 0; + if (indefinite) { + /* + * We need to put out an indefinite-length encoding. + * The only universal types that can be constructed are SETs, + * SEQUENCEs, and strings; so check that it is one of those, + * or that it is not universal (e.g. context-specific). + */ + state->indefinite = PR_TRUE; + PORT_Assert ((tag_number == SEC_ASN1_SET) + || (tag_number == SEC_ASN1_SEQUENCE) + || ((tag_modifiers & SEC_ASN1_CLASS_MASK) != 0) + || state->is_string); + tag_modifiers |= SEC_ASN1_CONSTRUCTED; + contents_length = 0; } - sec_asn1e_write_identifier_bytes (state, (unsigned char)(tag_number | tag_modifiers)); - sec_asn1e_write_length_bytes (state, contents_length, state->indefinite); + sec_asn1e_write_identifier_bytes(state, (unsigned char)(tag_number | tag_modifiers)); + sec_asn1e_write_length_bytes(state, contents_length, state->indefinite); if (contents_length == 0 && !state->indefinite) { - /* - * If no real contents to encode, then we are done with this field. - */ - state->place = afterContents; - return; + /* + * If no real contents to encode, then we are done with this field. + */ + state->place = afterContents; + return; } /* @@ -879,256 +907,251 @@ sec_asn1e_write_header (sec_asn1e_state *state) * written. Now we need to do the inner header and contents. */ if (state->explicit) { - state->place = afterContents; - state = sec_asn1e_push_state (state->top, - SEC_ASN1GetSubtemplate(state->theTemplate, - state->src, - PR_TRUE, - NULL /* __APPLE__ */, 0 /* __APPLE__ */), - state->src, PR_TRUE); - if (state != NULL) - state = sec_asn1e_init_state_based_on_template (state); - - (void) state; - - return; + state->place = afterContents; + const SecAsn1Template *subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->src, PR_TRUE, + NULL /* __APPLE__ */, 0 /* __APPLE__ */); + state = sec_asn1e_push_state(state->top, subt, state->src, PR_TRUE); + if (state != NULL) { + (void)sec_asn1e_init_state_based_on_template(state); + } + return; } switch (state->underlying_kind) { - case SEC_ASN1_SET_OF: - case SEC_ASN1_SEQUENCE_OF: - /* - * We need to push a child to handle each member. - */ - { - void **group; - const SecAsn1Template *subt; - - group = *(void ***)state->src; - if (group == NULL || *group == NULL) { - /* - * Group is empty; we are done. - */ - state->place = afterContents; - return; - } - state->place = duringGroup; - subt = SEC_ASN1GetSubtemplate (state->theTemplate, state->src, - PR_TRUE, NULL /* __APPLE__ */, 0 /* __APPLE__ */); - state = sec_asn1e_push_state (state->top, subt, *group, PR_TRUE); - if (state != NULL) - state = sec_asn1e_init_state_based_on_template (state); - } - break; - - case SEC_ASN1_SEQUENCE: - case SEC_ASN1_SET: - /* - * We need to push a child to handle the individual fields. - */ - state->place = duringSequence; - state = sec_asn1e_push_state (state->top, state->theTemplate + 1, - state->src, PR_TRUE); - if (state != NULL) { - /* - * Do the "before" field notification. - */ - sec_asn1e_notify_before (state->top, state->src, state->depth); - state = sec_asn1e_init_state_based_on_template (state); - } - break; - - default: - /* - * I think we do not need to do anything else. - * XXX Correct? - */ - state->place = duringContents; - break; + case SEC_ASN1_SET_OF: + case SEC_ASN1_SEQUENCE_OF: { + /* + * We need to push a child to handle each member. + */ + void **group; + const SecAsn1Template *subt; + + group = *(void ***)state->src; + if (group == NULL || *group == NULL) { + /* + * Group is empty; we are done. + */ + state->place = afterContents; + return; + } + state->place = duringGroup; + subt = SEC_ASN1GetSubtemplate(state->theTemplate, state->src, + PR_TRUE, NULL /* __APPLE__ */, 0 /* __APPLE__ */); + state = sec_asn1e_push_state(state->top, subt, *group, PR_TRUE); + if (state != NULL) { + (void)sec_asn1e_init_state_based_on_template(state); + } + } + break; + + case SEC_ASN1_SEQUENCE: + case SEC_ASN1_SET: + /* + * We need to push a child to handle the individual fields. + */ + state->place = duringSequence; + state = sec_asn1e_push_state(state->top, state->theTemplate + 1, + state->src, PR_TRUE); + if (state != NULL) { + /* + * Do the "before" field notification. + */ + sec_asn1e_notify_before(state->top, state->src, state->depth); + (void)sec_asn1e_init_state_based_on_template(state); + } + break; + + default: + /* + * I think we do not need to do anything else. + * XXX Correct? + */ + state->place = duringContents; + break; } - - (void) state; } static void -sec_asn1e_write_contents (sec_asn1e_state *state, - const char *buf, unsigned long len) +sec_asn1e_write_contents_from_buf(sec_asn1e_state *state, + const char *buf, unsigned long len) { - PORT_Assert (state->place == duringContents); - - if (state->top->from_buf) { - /* - * Probably they just turned on "take from buf", but have not - * yet given us any bytes. If there is nothing in the buffer - * then we have nothing to do but return and wait. - */ - if (buf == NULL || len == 0) { - state->top->status = needBytes; - return; - } - /* - * We are streaming, reading from a passed-in buffer. - * This means we are encoding a simple string or an ANY. - * For the former, we need to put out a substring, with its - * own identifier and length. For an ANY, we just write it - * out as is (our caller is required to ensure that it - * is a properly encoded entity). - */ - PORT_Assert (state->is_string); /* includes ANY */ - if (state->underlying_kind != SEC_ASN1_ANY) { - unsigned char identifier; - - /* - * Create the identifier based on underlying_kind. We cannot - * use tag_number and tag_modifiers because this can be an - * implicitly encoded field. In that case, the underlying - * substrings *are* encoded with their real tag. - */ - identifier = (unsigned char)state->underlying_kind & SEC_ASN1_TAG_MASK; - /* - * The underlying kind should just be a simple string; there - * should be no bits like CONTEXT_SPECIFIC or CONSTRUCTED set. - */ - PORT_Assert ((identifier & SEC_ASN1_TAGNUM_MASK) == identifier); - /* - * Write out the tag and length for the substring. - */ - sec_asn1e_write_identifier_bytes (state, identifier); - if (state->underlying_kind == SEC_ASN1_BIT_STRING) { - char byte; - /* - * Assume we have a length in bytes but we need to output - * a proper bit string. This interface only works for bit - * strings that are full multiples of 8. If support for - * real, variable length bit strings is needed then the - * caller will have to know to pass in a bit length instead - * of a byte length and then this code will have to - * perform the encoding necessary (length written is length - * in bytes plus 1, and the first octet of string is the - * number of bits remaining between the end of the bit - * string and the next byte boundary). - */ - sec_asn1e_write_length_bytes (state, len + 1, PR_FALSE); - byte = 0; - sec_asn1e_write_contents_bytes (state, &byte, 1); - } else { - sec_asn1e_write_length_bytes (state, len, PR_FALSE); - } - } - sec_asn1e_write_contents_bytes (state, buf, len); - state->top->status = needBytes; - } else { - switch (state->underlying_kind) { - case SEC_ASN1_SET: - case SEC_ASN1_SEQUENCE: - PORT_Assert (0); - break; - - case SEC_ASN1_BIT_STRING: - { - SecAsn1Item *item; - char rem; - - item = (SecAsn1Item *)state->src; - len = (item->Length + 7) >> 3; - rem = (unsigned char)((len << 3) - item->Length); /* remaining bits */ - sec_asn1e_write_contents_bytes (state, &rem, 1); - sec_asn1e_write_contents_bytes (state, (char *) item->Data, - len); - } - break; - - case SEC_ASN1_BMP_STRING: - /* The number of bytes must be divisable by 2 */ - if ((((SecAsn1Item *)state->src)->Length) % 2) { - SEC_ASN1EncoderContext *cx; - - cx = state->top; - cx->status = encodeError; - break; - } - /* otherwise, fall through to write the content */ - goto process_string; - - case SEC_ASN1_UNIVERSAL_STRING: - /* The number of bytes must be divisable by 4 */ - if ((((SecAsn1Item *)state->src)->Length) % 4) { - SEC_ASN1EncoderContext *cx; - - cx = state->top; - cx->status = encodeError; - break; - } - /* otherwise, fall through to write the content */ - goto process_string; - - case SEC_ASN1_INTEGER: - /* ASN.1 INTEGERs are signed. If the source is an unsigned - * integer, the encoder will need to handle the conversion here. - */ - { - size_t blen; - unsigned char *intbuf; - #ifdef __APPLE__ - PRBool signedInt = state->signedInt; - #else - SECItemType integerType = ((SecAsn1Item *)state->src)->type; - #endif - blen = ((SecAsn1Item *)state->src)->Length; - intbuf = ((SecAsn1Item *)state->src)->Data; - while (blen > 0) { - #ifdef __APPLE__ - if (*intbuf & 0x80 && !signedInt) { - #else - if (*intbuf & 0x80 && integerType == siUnsignedInteger) { - #endif - char zero = 0; /* write a leading 0 */ - sec_asn1e_write_contents_bytes(state, &zero, 1); - /* and then the remaining buffer */ - sec_asn1e_write_contents_bytes(state, - (char *)intbuf, blen); - break; - } - /* Check three possibilities: - * 1. No leading zeros, msb of MSB is not 1; - * 2. The number is zero itself; - * 3. Encoding a signed integer with a leading zero, - * keep the zero so that the number is positive. - */ - if (*intbuf != 0 || - blen == 1 || - #ifdef __APPLE__ - (intbuf[1] & 0x80 && signedInt) ) - #else - (intbuf[1] & 0x80 && integerType != siUnsignedInteger) ) - #endif - { - sec_asn1e_write_contents_bytes(state, - (char *)intbuf, blen); - break; - } - /* byte is 0, continue */ - intbuf++; - blen--; - } - } - /* done with this content */ - break; - -process_string: - default: - { - SecAsn1Item *item; - - item = (SecAsn1Item *)state->src; - sec_asn1e_write_contents_bytes (state, (char *) item->Data, - item->Length); - } - break; - } - state->place = afterContents; + PORT_Assert(state->place == duringContents); + PORT_Assert(state->top->from_buf); + PORT_Assert(state->may_stream && !state->ignore_stream); + + /* + * Probably they just turned on "take from buf", but have not + * yet given us any bytes. If there is nothing in the buffer + * then we have nothing to do but return and wait. + */ + if (buf == NULL || len == 0) { + state->top->status = needBytes; + return; + } + /* + * We are streaming, reading from a passed-in buffer. + * This means we are encoding a simple string or an ANY. + * For the former, we need to put out a substring, with its + * own identifier and length. For an ANY, we just write it + * out as is (our caller is required to ensure that it + * is a properly encoded entity). + */ + PORT_Assert(state->is_string); /* includes ANY */ + if (state->underlying_kind != SEC_ASN1_ANY) { + unsigned char identifier; + + /* + * Create the identifier based on underlying_kind. We cannot + * use tag_number and tag_modifiers because this can be an + * implicitly encoded field. In that case, the underlying + * substrings *are* encoded with their real tag. + */ + identifier = (unsigned char)(state->underlying_kind & SEC_ASN1_TAG_MASK); + /* + * The underlying kind should just be a simple string; there + * should be no bits like CONTEXT_SPECIFIC or CONSTRUCTED set. + */ + PORT_Assert((identifier & SEC_ASN1_TAGNUM_MASK) == identifier); + /* + * Write out the tag and length for the substring. + */ + sec_asn1e_write_identifier_bytes(state, identifier); + if (state->underlying_kind == SEC_ASN1_BIT_STRING) { + char byte; + /* + * Assume we have a length in bytes but we need to output + * a proper bit string. This interface only works for bit + * strings that are full multiples of 8. If support for + * real, variable length bit strings is needed then the + * caller will have to know to pass in a bit length instead + * of a byte length and then this code will have to + * perform the encoding necessary (length written is length + * in bytes plus 1, and the first octet of string is the + * number of bits remaining between the end of the bit + * string and the next byte boundary). + */ + sec_asn1e_write_length_bytes(state, len + 1, PR_FALSE); + byte = 0; + sec_asn1e_write_contents_bytes(state, &byte, 1); + } else { + sec_asn1e_write_length_bytes(state, len, PR_FALSE); + } + } + sec_asn1e_write_contents_bytes(state, buf, len); + state->top->status = needBytes; +} + +static void +sec_asn1e_write_contents(sec_asn1e_state *state) +{ + unsigned long len = 0; + + PORT_Assert(state->place == duringContents); + switch (state->underlying_kind) { + case SEC_ASN1_SET: + case SEC_ASN1_SEQUENCE: + PORT_Assert (0); + break; + + case SEC_ASN1_BIT_STRING: { + SecAsn1Item *item; + char rem; + + item = (SecAsn1Item *)state->src; + len = (item->Length + 7) >> 3; + rem = (unsigned char)((len << 3) - item->Length); /* remaining bits */ + sec_asn1e_write_contents_bytes(state, &rem, 1); + sec_asn1e_write_contents_bytes(state, (char *) item->Data, len); + } + break; + + case SEC_ASN1_BMP_STRING: + /* The number of bytes must be divisable by 2 */ + if ((((SecAsn1Item *)state->src)->Length) % 2) { + SEC_ASN1EncoderContext *cx; + + cx = state->top; + cx->status = encodeError; + break; + } + /* otherwise, fall through to write the content */ + goto process_string; + + case SEC_ASN1_UNIVERSAL_STRING: + /* The number of bytes must be divisable by 4 */ + if ((((SecAsn1Item *)state->src)->Length) % 4) { + SEC_ASN1EncoderContext *cx; + + cx = state->top; + cx->status = encodeError; + break; + } + /* otherwise, fall through to write the content */ + goto process_string; + + case SEC_ASN1_INTEGER: { + /* ASN.1 INTEGERs are signed. If the source is an unsigned + * integer, the encoder will need to handle the conversion here. + */ + size_t blen; + unsigned char *intbuf; +#ifdef __APPLE__ + PRBool signedInt = state->signedInt; +#else + SECItemType integerType = ((SecAsn1Item *)state->src)->type; +#endif + blen = ((SecAsn1Item *)state->src)->Length; + intbuf = ((SecAsn1Item *)state->src)->Data; + while (blen > 0) { +#ifdef __APPLE__ + if (*intbuf & 0x80 && !signedInt) +#else + if (*intbuf & 0x80 && integerType == siUnsignedInteger) +#endif + { + char zero = 0; /* write a leading 0 */ + sec_asn1e_write_contents_bytes(state, &zero, 1); + /* and then the remaining buffer */ + sec_asn1e_write_contents_bytes(state, (char *)intbuf, blen); + break; + } + /* Check three possibilities: + * 1. No leading zeros, msb of MSB is not 1; + * 2. The number is zero itself; + * 3. Encoding a signed integer with a leading zero, + * keep the zero so that the number is positive. + */ + if (*intbuf != 0 || + blen == 1 || +#ifdef __APPLE__ + (intbuf[1] & 0x80 && signedInt) ) +#else + (intbuf[1] & 0x80 && integerType != siUnsignedInteger) ) +#endif + { + sec_asn1e_write_contents_bytes(state, (char *)intbuf, blen); + break; + } + /* byte is 0, continue */ + intbuf++; + blen--; + } + } + /* done with this content */ + break; + + process_string: + default: + { + SecAsn1Item *item; + + item = (SecAsn1Item *)state->src; + sec_asn1e_write_contents_bytes(state, (char *) item->Data, item->Length); + } + break; } + state->place = afterContents; } @@ -1136,14 +1159,14 @@ process_string: * We are doing a SET OF or SEQUENCE OF, and have just finished an item. */ static void -sec_asn1e_next_in_group (sec_asn1e_state *state) +sec_asn1e_next_in_group(sec_asn1e_state *state) { sec_asn1e_state *child; void **group; void *member; - PORT_Assert (state->place == duringGroup); - PORT_Assert (state->child != NULL); + PORT_Assert(state->place == duringGroup); + PORT_Assert(state->child != NULL); child = state->child; @@ -1153,27 +1176,28 @@ sec_asn1e_next_in_group (sec_asn1e_state *state) * Find placement of current item. */ member = (char *)(state->child->src) - child->theTemplate->offset; - while (*group != member) - group++; + while (*group != member) { + group++; + } /* * Move forward to next item. */ group++; if (*group == NULL) { - /* - * That was our last one; we are done now. - */ - child->place = notInUse; - state->place = afterContents; - return; + /* + * That was our last one; we are done now. + */ + child->place = notInUse; + state->place = afterContents; + return; } child->src = (char *)(*group) + child->theTemplate->offset; /* * Re-"push" child. */ - sec_asn1e_scrub_state (child); + sec_asn1e_scrub_state(child); state->top->current = child; } @@ -1183,31 +1207,31 @@ sec_asn1e_next_in_group (sec_asn1e_state *state) * (detecting end-of-sequence when it happens). */ static void -sec_asn1e_next_in_sequence (sec_asn1e_state *state) +sec_asn1e_next_in_sequence(sec_asn1e_state *state) { sec_asn1e_state *child; - PORT_Assert (state->place == duringSequence); - PORT_Assert (state->child != NULL); + PORT_Assert(state->place == duringSequence); + PORT_Assert(state->child != NULL); child = state->child; /* * Do the "after" field notification. */ - sec_asn1e_notify_after (state->top, child->src, child->depth); + sec_asn1e_notify_after(state->top, child->src, child->depth); /* * Move forward. */ child->theTemplate++; if (child->theTemplate->kind == 0) { - /* - * We are done with this sequence. - */ - child->place = notInUse; - state->place = afterContents; - return; + /* + * We are done with this sequence. + */ + child->place = notInUse; + state->place = afterContents; + return; } /* @@ -1219,20 +1243,21 @@ sec_asn1e_next_in_sequence (sec_asn1e_state *state) /* * Do the "before" field notification. */ - sec_asn1e_notify_before (state->top, child->src, child->depth); + sec_asn1e_notify_before(state->top, child->src, child->depth); state->top->current = child; - (void) sec_asn1e_init_state_based_on_template (child); + (void)sec_asn1e_init_state_based_on_template(child); } static void sec_asn1e_after_contents (sec_asn1e_state *state) { - PORT_Assert (state->place == afterContents); + PORT_Assert(state->place == afterContents); - if (state->indefinite) - sec_asn1e_write_end_of_contents_bytes (state); + if (state->indefinite) { + sec_asn1e_write_end_of_contents_bytes(state); + } /* * Just make my parent be the current state. It will then clean @@ -1254,68 +1279,72 @@ sec_asn1e_after_contents (sec_asn1e_state *state) * (for now) with the buffer. */ SECStatus -SEC_ASN1EncoderUpdate (SEC_ASN1EncoderContext *cx, - const char *buf, unsigned long len) +SEC_ASN1EncoderUpdate(SEC_ASN1EncoderContext *cx, + const char *buf, unsigned long len) { sec_asn1e_state *state; if (cx->status == needBytes) { - PORT_Assert (buf != NULL && len != 0); - cx->status = keepGoing; + PORT_Assert(buf != NULL && len != 0); + cx->status = keepGoing; } while (cx->status == keepGoing) { - state = cx->current; - switch (state->place) { - case beforeHeader: - sec_asn1e_write_header (state); - break; - case duringContents: - sec_asn1e_write_contents (state, buf, len); - break; - case duringGroup: - sec_asn1e_next_in_group (state); - break; - case duringSequence: - sec_asn1e_next_in_sequence (state); - break; - case afterContents: - sec_asn1e_after_contents (state); - break; - case afterImplicit: - case afterInline: - case afterPointer: - case afterChoice: - /* - * These states are more documentation than anything. - * They just need to force a pop. - */ - PORT_Assert (!state->indefinite); - state->place = afterContents; - break; - case notInUse: - default: - /* This is not an error, but rather a plain old BUG! */ - PORT_Assert (0); - cx->status = encodeError; - break; - } - - if (cx->status == encodeError) - break; - - /* It might have changed, so we have to update our local copy. */ - state = cx->current; - - /* If it is NULL, we have popped all the way to the top. */ - if (state == NULL) { - cx->status = allDone; - break; - } + state = cx->current; + switch (state->place) { + case beforeHeader: + sec_asn1e_write_header(state); + break; + case duringContents: + if (cx->from_buf) + sec_asn1e_write_contents_from_buf(state, buf, len); + else + sec_asn1e_write_contents(state); + break; + case duringGroup: + sec_asn1e_next_in_group(state); + break; + case duringSequence: + sec_asn1e_next_in_sequence(state); + break; + case afterContents: + sec_asn1e_after_contents(state); + break; + case afterImplicit: + case afterInline: + case afterPointer: + case afterChoice: + /* + * These states are more documentation than anything. + * They just need to force a pop. + */ + PORT_Assert(!state->indefinite); + state->place = afterContents; + break; + case notInUse: + default: + /* This is not an error, but rather a plain old BUG! */ + PORT_Assert(0); + cx->status = encodeError; + break; + } + + if (cx->status == encodeError) { + break; + } + + /* It might have changed, so we have to update our local copy. */ + state = cx->current; + + /* If it is NULL, we have popped all the way to the top. */ + if (state == NULL) { + cx->status = allDone; + break; + } } if (cx->status == encodeError) { - return SECFailure; + return SECFailure; } return SECSuccess; @@ -1323,31 +1352,32 @@ SEC_ASN1EncoderUpdate (SEC_ASN1EncoderContext *cx, void -SEC_ASN1EncoderFinish (SEC_ASN1EncoderContext *cx) +SEC_ASN1EncoderFinish(SEC_ASN1EncoderContext *cx) { /* * XXX anything else that needs to be finished? */ - PORT_FreeArena (cx->our_pool, PR_FALSE); + PORT_FreeArena(cx->our_pool, PR_FALSE); } SEC_ASN1EncoderContext * -SEC_ASN1EncoderStart (const void *src, const SecAsn1Template *theTemplate, - SEC_ASN1WriteProc output_proc, void *output_arg) +SEC_ASN1EncoderStart(const void *src, const SecAsn1Template *theTemplate, + SEC_ASN1WriteProc output_proc, void *output_arg) { PRArenaPool *our_pool; SEC_ASN1EncoderContext *cx; - our_pool = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); - if (our_pool == NULL) - return NULL; + our_pool = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); + if (our_pool == NULL) { + return NULL; + } - cx = (SEC_ASN1EncoderContext*)PORT_ArenaZAlloc (our_pool, sizeof(*cx)); + cx = (SEC_ASN1EncoderContext*)PORT_ArenaZAlloc(our_pool, sizeof(*cx)); if (cx == NULL) { - PORT_FreeArena (our_pool, PR_FALSE); - return NULL; + PORT_FreeArena(our_pool, PR_FALSE); + return NULL; } cx->our_pool = our_pool; @@ -1357,13 +1387,13 @@ SEC_ASN1EncoderStart (const void *src, const SecAsn1Template *theTemplate, cx->status = keepGoing; if (sec_asn1e_push_state(cx, theTemplate, src, PR_FALSE) == NULL - || sec_asn1e_init_state_based_on_template (cx->current) == NULL) { - /* - * Trouble initializing (probably due to failed allocations) - * requires that we just give up. - */ - PORT_FreeArena (our_pool, PR_FALSE); - return NULL; + || sec_asn1e_init_state_based_on_template(cx->current) == NULL) { + /* + * Trouble initializing (probably due to failed allocations) + * requires that we just give up. + */ + PORT_FreeArena (our_pool,PR_FALSE); + return NULL; } return cx; @@ -1376,8 +1406,8 @@ SEC_ASN1EncoderStart (const void *src, const SecAsn1Template *theTemplate, void -SEC_ASN1EncoderSetNotifyProc (SEC_ASN1EncoderContext *cx, - SEC_ASN1NotifyProc fn, void *arg) +SEC_ASN1EncoderSetNotifyProc(SEC_ASN1EncoderContext *cx, + SEC_ASN1NotifyProc fn, void *arg) { cx->notify_proc = fn; cx->notify_arg = arg; @@ -1385,7 +1415,7 @@ SEC_ASN1EncoderSetNotifyProc (SEC_ASN1EncoderContext *cx, void -SEC_ASN1EncoderClearNotifyProc (SEC_ASN1EncoderContext *cx) +SEC_ASN1EncoderClearNotifyProc(SEC_ASN1EncoderContext *cx) { cx->notify_proc = NULL; cx->notify_arg = NULL; /* not necessary; just being clean */ @@ -1402,7 +1432,7 @@ SEC_ASN1EncoderAbort(SEC_ASN1EncoderContext *cx, int error) void -SEC_ASN1EncoderSetStreaming (SEC_ASN1EncoderContext *cx) +SEC_ASN1EncoderSetStreaming(SEC_ASN1EncoderContext *cx) { /* XXX is there a way to check that we are "between" fields here? */ @@ -1411,7 +1441,7 @@ SEC_ASN1EncoderSetStreaming (SEC_ASN1EncoderContext *cx) void -SEC_ASN1EncoderClearStreaming (SEC_ASN1EncoderContext *cx) +SEC_ASN1EncoderClearStreaming(SEC_ASN1EncoderContext *cx) { /* XXX is there a way to check that we are "between" fields here? */ @@ -1420,66 +1450,67 @@ SEC_ASN1EncoderClearStreaming (SEC_ASN1EncoderContext *cx) void -SEC_ASN1EncoderSetTakeFromBuf (SEC_ASN1EncoderContext *cx) +SEC_ASN1EncoderSetTakeFromBuf(SEC_ASN1EncoderContext *cx) { - /* + /* * XXX is there a way to check that we are "between" fields here? this * needs to include a check for being in between groups of items in * a SET_OF or SEQUENCE_OF. */ - PORT_Assert (cx->streaming); - + PORT_Assert(cx->streaming); cx->from_buf = PR_TRUE; } void -SEC_ASN1EncoderClearTakeFromBuf (SEC_ASN1EncoderContext *cx) +SEC_ASN1EncoderClearTakeFromBuf(SEC_ASN1EncoderContext *cx) { /* we should actually be taking from buf *now* */ PORT_Assert (cx->from_buf); - if (! cx->from_buf) /* if not, just do nothing */ - return; + if (! cx->from_buf) { /* if not, just do nothing */ + return; + } cx->from_buf = PR_FALSE; if (cx->status == needBytes) { - cx->status = keepGoing; - cx->current->place = afterContents; + cx->status = keepGoing; + cx->current->place = afterContents; } } SECStatus -SEC_ASN1Encode (const void *src, const SecAsn1Template *theTemplate, - SEC_ASN1WriteProc output_proc, void *output_arg) +SEC_ASN1Encode(const void *src, const SecAsn1Template *theTemplate, + SEC_ASN1WriteProc output_proc, void *output_arg) { SEC_ASN1EncoderContext *ecx; SECStatus rv; - ecx = SEC_ASN1EncoderStart (src, theTemplate, output_proc, output_arg); - if (ecx == NULL) - return SECFailure; + ecx = SEC_ASN1EncoderStart(src, theTemplate, output_proc, output_arg); + if (ecx == NULL) { + return SECFailure; + } - rv = SEC_ASN1EncoderUpdate (ecx, NULL, 0); + rv = SEC_ASN1EncoderUpdate(ecx, NULL, 0); - SEC_ASN1EncoderFinish (ecx); + SEC_ASN1EncoderFinish(ecx); return rv; } /* * XXX depth and data_kind are unused; is there a PC way to silence warnings? - * (I mean "politically correct", not anything to do with intel/win platform) + * (I mean "politically correct", not anything to do with intel/win platform) */ void -sec_asn1e_encode_item_count (void *arg, const char *buf, size_t len, - int depth, SEC_ASN1EncodingPart data_kind) +sec_asn1e_encode_item_count(void *arg, const char *buf, size_t len, + int depth, SEC_ASN1EncodingPart data_kind) { size_t *count; count = (unsigned long*)arg; - PORT_Assert (count != NULL); + PORT_Assert(count != NULL); *count += len; } @@ -1487,16 +1518,18 @@ sec_asn1e_encode_item_count (void *arg, const char *buf, size_t len, /* XXX depth and data_kind are unused; is there a PC way to silence warnings? */ void -sec_asn1e_encode_item_store (void *arg, const char *buf, size_t len, - int depth, SEC_ASN1EncodingPart data_kind) +sec_asn1e_encode_item_store(void *arg, const char *buf, size_t len, + int depth, SEC_ASN1EncodingPart data_kind) { SecAsn1Item *dest; dest = (SecAsn1Item*)arg; - PORT_Assert (dest != NULL); + PORT_Assert(dest != NULL); - PORT_Memcpy (dest->Data + dest->Length, buf, len); - dest->Length += len; + if (len > 0) { + PORT_Memcpy(dest->Data + dest->Length, buf, len); + dest->Length += len; + } } @@ -1508,44 +1541,47 @@ sec_asn1e_encode_item_store (void *arg, const char *buf, size_t len, * XXX This seems like a reasonable general-purpose function (for SECITEM_)? */ SecAsn1Item * -sec_asn1e_allocate_item (PRArenaPool *poolp, SecAsn1Item *dest, unsigned long len) +sec_asn1e_allocate_item(PRArenaPool *poolp, SecAsn1Item *dest, unsigned long len) { if (poolp != NULL) { - void *release; - - release = PORT_ArenaMark (poolp); - if (dest == NULL) - dest = (SecAsn1Item*)PORT_ArenaAlloc (poolp, sizeof(SecAsn1Item)); - if (dest != NULL) { - dest->Data = (unsigned char*)PORT_ArenaAlloc (poolp, len); - if (dest->Data == NULL) { - dest = NULL; - } - } - if (dest == NULL) { - /* one or both allocations failed; release everything */ - PORT_ArenaRelease (poolp, release); - } else { - /* everything okay; unmark the arena */ - PORT_ArenaUnmark (poolp, release); - } + void *release; + + release = PORT_ArenaMark(poolp); + if (dest == NULL) { + dest = (SecAsn1Item*)PORT_ArenaAlloc(poolp, sizeof(SecAsn1Item)); + } + if (dest != NULL) { + dest->Data = (unsigned char*)PORT_ArenaAlloc(poolp, len); + if (dest->Data == NULL) { + dest = NULL; + } + } + if (dest == NULL) { + /* one or both allocations failed; release everything */ + PORT_ArenaRelease(poolp, release); + } else { + /* everything okay; unmark the arena */ + PORT_ArenaUnmark(poolp, release); + } } else { - SecAsn1Item *indest; - - indest = dest; - if (dest == NULL) - dest = (SecAsn1Item*)PORT_Alloc (sizeof(SecAsn1Item)); - if (dest != NULL) { - #ifndef __APPLE__ - dest->type = siBuffer; - #endif - dest->Data = (unsigned char*)PORT_Alloc (len); - if (dest->Data == NULL) { - if (indest == NULL) - PORT_Free (dest); - dest = NULL; - } - } + SecAsn1Item *indest; + + indest = dest; + if (dest == NULL) { + dest = (SecAsn1Item*)PORT_Alloc(sizeof(SecAsn1Item)); + } + if (dest != NULL) { +#ifndef __APPLE__ + dest->type = siBuffer; +#endif + dest->Data = (unsigned char*)PORT_Alloc(len); + if (dest->Data == NULL) { + if (indest == NULL) { + PORT_Free(dest); + } + dest = NULL; + } + } } return dest; @@ -1553,40 +1589,43 @@ sec_asn1e_allocate_item (PRArenaPool *poolp, SecAsn1Item *dest, unsigned long le SecAsn1Item * -SEC_ASN1EncodeItem (PRArenaPool *poolp, SecAsn1Item *dest, const void *src, - const SecAsn1Template *theTemplate) +SEC_ASN1EncodeItem(PRArenaPool *poolp, SecAsn1Item *dest, const void *src, + const SecAsn1Template *theTemplate) { unsigned long encoding_length; SECStatus rv; - PORT_Assert (dest == NULL || dest->Data == NULL); + PORT_Assert(dest == NULL || dest->Data == NULL); encoding_length = 0; - rv = SEC_ASN1Encode (src, theTemplate, - sec_asn1e_encode_item_count, &encoding_length); - if (rv != SECSuccess) - return NULL; + rv = SEC_ASN1Encode(src, theTemplate, + sec_asn1e_encode_item_count, &encoding_length); + if (rv != SECSuccess) { + return NULL; + } - dest = sec_asn1e_allocate_item (poolp, dest, encoding_length); - if (dest == NULL) - return NULL; + dest = sec_asn1e_allocate_item(poolp, dest, encoding_length); + if (dest == NULL) { + return NULL; + } /* XXX necessary? This really just checks for a bug in the allocate fn */ - PORT_Assert (dest->Data != NULL); - if (dest->Data == NULL) - return NULL; + PORT_Assert(dest->Data != NULL); + if (dest->Data == NULL) { + return NULL; + } dest->Length = 0; - (void) SEC_ASN1Encode (src, theTemplate, sec_asn1e_encode_item_store, dest); + (void)SEC_ASN1Encode(src, theTemplate, sec_asn1e_encode_item_store, dest); - PORT_Assert (encoding_length == dest->Length); + PORT_Assert(encoding_length == dest->Length); return dest; } static SecAsn1Item * sec_asn1e_integer(PRArenaPool *poolp, SecAsn1Item *dest, unsigned long value, - PRBool make_unsigned) + PRBool make_unsigned) { unsigned long copy; unsigned char sign; @@ -1597,9 +1636,9 @@ sec_asn1e_integer(PRArenaPool *poolp, SecAsn1Item *dest, unsigned long value, */ copy = value; do { - len++; - sign = (unsigned char)(copy & 0x80); - copy >>= 8; + len++; + sign = (unsigned char)(copy & 0x80); + copy >>= 8; } while (copy); /* @@ -1607,25 +1646,27 @@ sec_asn1e_integer(PRArenaPool *poolp, SecAsn1Item *dest, unsigned long value, * byte we counted was set, we need to add one to the length so * we put a high-order zero byte in the encoding. */ - if (sign && make_unsigned) - len++; + if (sign && make_unsigned) { + len++; + } /* * Allocate the item (if necessary) and the data pointer within. */ - dest = sec_asn1e_allocate_item (poolp, dest, len); - if (dest == NULL) - return NULL; + dest = sec_asn1e_allocate_item(poolp, dest, len); + if (dest == NULL) { + return NULL; + } /* * Store the value, byte by byte, in the item. */ dest->Length = len; while (len) { - dest->Data[--len] = (unsigned char)value; - value >>= 8; + dest->Data[--len] = (unsigned char)value; + value >>= 8; } - PORT_Assert (value == 0); + PORT_Assert(value == 0); return dest; } @@ -1634,13 +1675,13 @@ sec_asn1e_integer(PRArenaPool *poolp, SecAsn1Item *dest, unsigned long value, SecAsn1Item * SEC_ASN1EncodeInteger(PRArenaPool *poolp, SecAsn1Item *dest, long value) { - return sec_asn1e_integer (poolp, dest, (unsigned long) value, PR_FALSE); + return sec_asn1e_integer(poolp, dest, (unsigned long) value, PR_FALSE); } extern SecAsn1Item * SEC_ASN1EncodeUnsignedInteger(PRArenaPool *poolp, - SecAsn1Item *dest, unsigned long value) + SecAsn1Item *dest, unsigned long value) { - return sec_asn1e_integer (poolp, dest, value, PR_TRUE); + return sec_asn1e_integer(poolp, dest, value, PR_TRUE); } diff --git a/OSX/libsecurity_authorization/lib/Authorization.c b/OSX/libsecurity_authorization/lib/Authorization.c index 7b7095a7..92e1faf0 100644 --- a/OSX/libsecurity_authorization/lib/Authorization.c +++ b/OSX/libsecurity_authorization/lib/Authorization.c @@ -9,12 +9,26 @@ #include #include #include +#include +#include #include #include #include #include #include #include +#include +#include +#include + +static os_log_t AUTH_LOG_DEFAULT() { + static dispatch_once_t once; + static os_log_t log; + dispatch_once(&once, ^{ log = os_log_create("com.apple.Authorization", "framework"); }); + return log; +}; + +#define AUTH_LOG AUTH_LOG_DEFAULT() static dispatch_queue_t get_authorization_dispatch_queue() @@ -107,7 +121,7 @@ OSStatus AuthorizationCreate(const AuthorizationRights *rights, // Reply reply = xpc_connection_send_message_with_reply_sync(get_authorization_connection(), message); require_action_quiet(reply != NULL, done, status = errAuthorizationInternal); - require_action_quiet(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal); + require_action_quiet(xpc_get_type(reply) != XPC_TYPE_ERROR, done, status = errAuthorizationInternal;); // Status status = (OSStatus)xpc_dictionary_get_int64(reply, AUTH_XPC_STATUS); @@ -338,6 +352,48 @@ OSStatus AuthorizationCopyRights(AuthorizationRef authorization, AuthorizationRights **authorizedRights) { OSStatus status = errAuthorizationInternal; + + if ((flags & kAuthorizationFlagSheet) && environment) { + // check if window ID is present in environment + CGWindowID window = 0; + for (UInt32 i = 0; i < environment->count; ++i) { + if (strncmp(environment->items[i].name, kAuthorizationEnvironmentWindowId, strlen(kAuthorizationEnvironmentWindowId)) == 0 + && (environment->items[i].valueLength = sizeof(window)) && environment->items[i].value) { + window = *(CGWindowID *)environment->items[i].value; + break; + } + } + if (window > 0) { + os_log_debug(AUTH_LOG, "Trying to use sheet version"); + static OSStatus (*sheetAuthorizationWorker)(CGWindowID windowID, AuthorizationRef authorization, + const AuthorizationRights *rights, + const AuthorizationEnvironment *environment, + AuthorizationFlags flags, + AuthorizationRights **authorizedRights, + Boolean *authorizationLaunched) = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + void *handle = dlopen("/System/Library/Frameworks/SecurityInterface.framework/SecurityInterface", RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); + if (handle) { + sheetAuthorizationWorker = dlsym(handle, "sheetAuthorizationWorker"); + } + }); + + if (sheetAuthorizationWorker) { + Boolean authorizationLaunched; + status = sheetAuthorizationWorker(window, authorization, rights, environment, flags, authorizedRights, &authorizationLaunched); + if (authorizationLaunched == true) { + os_log_debug(AUTH_LOG, "Returning sheet result %d", (int)status); + return status; + } + os_log(AUTH_LOG, "Sheet authorization cannot be used this time, falling back to the SecurityAgent UI"); + } else { + os_log_debug(AUTH_LOG, "Failed to find sheet support in SecurityInterface"); + } + // fall back to the standard (windowed) version if sheets are not available + } + } + xpc_object_t message = NULL; require_noerr(status = _AuthorizationCopyRights_prepare_message(authorization, rights, environment, flags, &message), done); diff --git a/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h b/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h index 8700bda6..de083b3f 100644 --- a/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h +++ b/OSX/libsecurity_authorization/lib/AuthorizationPlugin.h @@ -153,7 +153,7 @@ typedef void *AuthorizationSessionId; @constant kAuthorizationResultUndefined the operation failed for some reason and should not be retried for this session. @constant kAuthorizationResultUserCanceled the user has requested that the evaluation be terminated. */ -typedef CF_ENUM(UInt32, AuthorizationResult) { +typedef CF_CLOSED_ENUM(UInt32, AuthorizationResult) { kAuthorizationResultAllow, kAuthorizationResultDeny, kAuthorizationResultUndefined, @@ -176,7 +176,7 @@ enum { interface. */ enum { - kAuthorizationCallbacksVersion = 3 + kAuthorizationCallbacksVersion = 4 }; @@ -197,7 +197,10 @@ enum { @field GetLAContext Returns LAContext which will have LACredentialCTKPIN credential set if PIN is available otherwise context without credentials is returned. LAContext can be used for operations with Tokens which would normally require PIN. Caller owns returned context and is responsible for release. @field GetTokenIdentities Returns array of identities. Caller owns returned array and is reponsible for release. @field GetTKTokenWatcher Returns TKTokenWatcher object. Caller owns returned context and is responsible for release. -*/ + @field RemoveContextValue Removes value from context. + @field RemoveHintValue Removes value from hints. + + */ typedef struct AuthorizationCallbacks { /* Engine callback version. */ @@ -273,6 +276,14 @@ typedef struct AuthorizationCallbacks { Caller is responsible for outValue release */ OSStatus (*GetTKTokenWatcher)(AuthorizationEngineRef inEngine, CFTypeRef __nullable * __nullable outValue) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_NA); + + /* Remove value from hints. */ + OSStatus (*RemoveHintValue)(AuthorizationEngineRef inEngine, + AuthorizationString inKey); + + /* Write value to context. */ + OSStatus (*RemoveContextValue)(AuthorizationEngineRef inEngine, + AuthorizationString inKey); } AuthorizationCallbacks; diff --git a/OSX/libsecurity_authorization/lib/AuthorizationPriv.h b/OSX/libsecurity_authorization/lib/AuthorizationPriv.h index e5389d6f..bd9ec936 100644 --- a/OSX/libsecurity_authorization/lib/AuthorizationPriv.h +++ b/OSX/libsecurity_authorization/lib/AuthorizationPriv.h @@ -56,6 +56,7 @@ enum { kAuthorizationFlagLeastPrivileged = (1 << 5), kAuthorizationFlagSheet = (1 << 6), kAuthorizationFlagIgnorePasswordOnly = (1 << 7), + kAuthorizationFlagIgnoreDarkWake = (1 << 8), }; /*! @@ -210,6 +211,63 @@ OSStatus SessionSetUserPreferences(SecuritySessionId session); */ OSStatus AuthorizationEnableSmartCard(AuthorizationRef _Nonnull authRef, Boolean enable); +/*! + @function AuthorizationExecuteWithPrivilegesInternal + Run an executable tool with enhanced privileges after passing + suitable authorization procedures. Allows better control and communication + with privileged tool. + + @param authorization An authorization reference that is used to authorize + access to the enhanced privileges. It is also passed to the tool for + further access control. + @param pathToTool Full pathname to the tool that should be executed + with enhanced privileges. + @param arguments An argv-style vector of strings to be passed to the tool. + @param newProcessPid (output, optional) PID of privileged process is stored here. + @param uid Desired UID under which privileged tool should be running. + @param stdOut File descriptor of the pipe which should be used to receive stdout from the privileged tool, use -1 if not needed. + @param stdErr File descriptor of the pipe which should be used to receive stderr from the privileged tool, use -1 if not needed. + @param stdIn File descriptor which will contain write-end of the stdin pipe of the privileged tool, use -1 if not needed. + @param processFinished This block is called when privileged process finishes. + */ + OSStatus AuthorizationExecuteWithPrivilegesInternal(const AuthorizationRef _Nonnull authorization, + const char * _Nonnull pathToTool, + const char * _Nonnull const * _Nonnull arguments, + pid_t * _Nullable newProcessPid, + const uid_t uid, + int stdOut, + int stdErr, + int stdIn, + void(^__nullable processFinished)(const int exitStatus)); + +/*! + @function AuthorizationExecuteWithPrivilegesExternalFormInternal + Run an executable tool with enhanced privileges after passing + suitable authorization procedures. Allows better control and communication + with privileged tool. + + @param extAuthorization authorization in external form that is used to authorize + access to the enhanced privileges. It is also passed to the tool for + further access control. + @param pathToTool Full pathname to the tool that should be executed + with enhanced privileges. + @param arguments An argv-style vector of strings to be passed to the tool. + @param newProcessPid (output, optional) PID of privileged process is stored here. + @param uid Desired UID under which privileged tool should be running. + @param stdOut File descriptor of the pipe which should be used to receive stdout from the privileged tool, use -1 if not needed. + @param stdErr File descriptor of the pipe which should be used to receive stderr from the privileged tool, use -1 if not needed. + @param stdIn File descriptor which will contain write-end of the stdin pipe of the privileged tool, use -1 if not needed. + @param processFinished This block is called when privileged process finishes. + */ + OSStatus AuthorizationExecuteWithPrivilegesExternalFormInternal(const AuthorizationExternalForm * _Nonnull extAuthorization, + const char * _Nonnull pathToTool, + const char * _Nullable const * _Nullable arguments, + pid_t * _Nullable newProcessPid, + const uid_t uid, + int stdOut, + int stdErr, + int stdIn, + void(^__nullable processFinished)(const int exitStatus)); #if defined(__cplusplus) } #endif diff --git a/OSX/libsecurity_authorization/lib/AuthorizationTags.h b/OSX/libsecurity_authorization/lib/AuthorizationTags.h index cfba3efa..8f59881c 100644 --- a/OSX/libsecurity_authorization/lib/AuthorizationTags.h +++ b/OSX/libsecurity_authorization/lib/AuthorizationTags.h @@ -76,5 +76,12 @@ */ #define kAuthorizationEnvironmentIcon "icon" +/*! + @define kAuthorizationPamResult + Return code provided by PAM module + */ +#define kAuthorizationPamResult "pam_result" + + #endif /* !_SECURITY_AUTHORIZATIONTAGS_H_ */ diff --git a/OSX/libsecurity_authorization/lib/AuthorizationTagsPriv.h b/OSX/libsecurity_authorization/lib/AuthorizationTagsPriv.h index f062a321..8800d326 100644 --- a/OSX/libsecurity_authorization/lib/AuthorizationTagsPriv.h +++ b/OSX/libsecurity_authorization/lib/AuthorizationTagsPriv.h @@ -356,4 +356,7 @@ /* LocalAuthentication specific */ #define AGENT_CONTEXT_LACONTEXT "la-context" +/* Sheet window ID */ +#define kAuthorizationEnvironmentWindowId "cgwindowid" + #endif /* !_SECURITY_AUTHORIZATIONTAGSPRIV_H_ */ diff --git a/OSX/libsecurity_authorization/lib/AuthorizationTrampolinePriv.h b/OSX/libsecurity_authorization/lib/AuthorizationTrampolinePriv.h new file mode 100644 index 00000000..cec647b3 --- /dev/null +++ b/OSX/libsecurity_authorization/lib/AuthorizationTrampolinePriv.h @@ -0,0 +1,59 @@ +/* + * 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@ + */ + + +/* + * AuthorizationTrampolinePriv.h -- Authorization defines for communication with + * authtrampoline. + * + */ + +#ifndef _SECURITY_AUTHORIZATIONTRAMPOLINEPRIV_H_ +#define _SECURITY_AUTHORIZATIONTRAMPOLINEPRIV_H_ + +#define XPC_REQUEST_CREATE_PROCESS "createp" +#define XPC_REPLY_MSG "rpl" +#define XPC_EVENT_MSG "evt" +#define XPC_REQUEST_ID "req" + +#define XPC_EVENT_TYPE "evtt" +#define XPC_EVENT_TYPE_CHILDEND "ce" + +#define PARAM_TOOL_PATH "tool" // path to the executable +#define PARAM_TOOL_PARAMS "params" // parameters passed to the executable +#define PARAM_ENV "env" // environment +#define PARAM_CWD "cwd" // current working directory +#define PARAM_EUID "requid" // uid under which executable should be running +#define PARAM_AUTHREF "auth" // authorization +#define PARAM_EXITCODE "ec" // exit code of that tool +#define PARAM_STDIN "in" // stdin FD +#define PARAM_STDOUT "out" // stdout FD +#define PARAM_STDERR "err" // stderr FD +#define PARAM_DATA "data" // data to be written to the executable's stdin +#define PARAM_CHILDEND_NEEDED "cen" // indicates client needs to be notified when executable finishes + +#define RETVAL_STATUS "status" +#define RETVAL_CHILD_PID "cpid" + + +#endif /* !_SECURITY_AUTHORIZATIONTRAMPOLINEPRIV_H_ */ diff --git a/OSX/libsecurity_authorization/lib/trampolineClient.cpp b/OSX/libsecurity_authorization/lib/trampolineClient.cpp index 672768f5..b7c5ee85 100644 --- a/OSX/libsecurity_authorization/lib/trampolineClient.cpp +++ b/OSX/libsecurity_authorization/lib/trampolineClient.cpp @@ -32,35 +32,51 @@ #include #include #include -#include -#include #include #include #include -// -// Where is the trampoline itself? -// -#if !defined(TRAMPOLINE) -# define TRAMPOLINE "/usr/libexec/security_authtrampoline" /* fallback */ -#endif - +#include "Security/Authorization.h" +#include "AuthorizationPriv.h" +#include "AuthorizationTrampolinePriv.h" +#include +#include +#include +#include +#include +#include // // A few names for clarity's sake // enum { - READ = 0, // read end of standard UNIX pipe - WRITE = 1 // write end of standard UNIX pipe + READ = 0, // read end of standard UNIX pipe + WRITE = 1 // write end of standard UNIX pipe }; +static os_log_t AUTH_LOG_DEFAULT() { + static dispatch_once_t once; + static os_log_t log; + dispatch_once(&once, ^{ log = os_log_create("com.apple.Authorization", "Trampoline"); }); + return log; +}; + +#define AUTH_LOG AUTH_LOG_DEFAULT() + +// +// Where is the trampoline itself? +// +#if !defined(TRAMPOLINE) +# define TRAMPOLINE "/usr/libexec/security_authtrampoline" /* fallback */ +#endif + // // Local (static) functions // static const char **argVector(const char *trampoline, - const char *tool, const char *commFd, - char *const *arguments); +const char *tool, const char *commFd, +char *const *arguments); OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization, @@ -81,204 +97,393 @@ OSStatus AuthorizationExecuteWithPrivileges(AuthorizationRef authorization, // The public client API function. // OSStatus AuthorizationExecuteWithPrivilegesExternalForm(const AuthorizationExternalForm * extForm, - const char *pathToTool, - AuthorizationFlags flags, - char *const *arguments, - FILE **communicationsPipe) +const char *pathToTool, +AuthorizationFlags flags, +char *const *arguments, +FILE **communicationsPipe) { - if (extForm == NULL) + os_log(AUTH_LOG, "AuthorizationExecuteWithPrivileges and AuthorizationExecuteWithPrivilegesExternalForm are deprecated and functionality will be removed soon - please update your application"); + if (extForm == NULL) return errAuthorizationInvalidPointer; - // report the caller to the authorities - aslmsg m = asl_new(ASL_TYPE_MSG); - asl_set(m, "com.apple.message.domain", "com.apple.libsecurity_authorization.AuthorizationExecuteWithPrivileges"); - asl_set(m, "com.apple.message.signature", getprogname()); - asl_log(NULL, m, ASL_LEVEL_NOTICE, "AuthorizationExecuteWithPrivileges!"); - asl_free(m); - - // flags are currently reserved - if (flags != 0) - return errAuthorizationInvalidFlags; - - // compute the argument vector here because we can't allocate memory once we fork. - - // where is the trampoline? + // report the caller to the authorities + aslmsg m = asl_new(ASL_TYPE_MSG); + asl_set(m, "com.apple.message.domain", "com.apple.libsecurity_authorization.AuthorizationExecuteWithPrivileges"); + asl_set(m, "com.apple.message.signature", getprogname()); + asl_log(NULL, m, ASL_LEVEL_NOTICE, "AuthorizationExecuteWithPrivileges!"); + asl_free(m); + + // flags are currently reserved + if (flags != 0) + return errAuthorizationInvalidFlags; + + // compute the argument vector here because we can't allocate memory once we fork. + + // where is the trampoline? #if defined(NDEBUG) - const char *trampoline = TRAMPOLINE; + const char *trampoline = TRAMPOLINE; #else //!NDEBUG - const char *trampoline = getenv("AUTHORIZATIONTRAMPOLINE"); - if (!trampoline) - trampoline = TRAMPOLINE; + const char *trampoline = getenv("AUTHORIZATIONTRAMPOLINE"); + if (!trampoline) + trampoline = TRAMPOLINE; #endif //NDEBUG - - // make a data exchange pipe - int dataPipe[2]; - if (pipe(dataPipe)) { - secinfo("authexec", "data pipe failure"); - return errAuthorizationToolExecuteFailure; - } - - // make text representation of the pipe handle - char pipeFdText[20]; - snprintf(pipeFdText, sizeof(pipeFdText), "auth %d", dataPipe[READ]); - const char **argv = argVector(trampoline, pathToTool, pipeFdText, arguments); - - // make a notifier pipe - int notify[2]; - if (pipe(notify)) { - close(dataPipe[READ]); close(dataPipe[WRITE]); + + // make a data exchange pipe + int dataPipe[2]; + if (pipe(dataPipe)) { + os_log_error(AUTH_LOG, "data pipe failure"); + return errAuthorizationToolExecuteFailure; + } + + // make text representation of the pipe handle + char pipeFdText[20]; + snprintf(pipeFdText, sizeof(pipeFdText), "auth %d", dataPipe[READ]); + const char **argv = argVector(trampoline, pathToTool, pipeFdText, arguments); + + // make a notifier pipe + int notify[2]; + if (pipe(notify)) { + close(dataPipe[READ]); close(dataPipe[WRITE]); if(argv) { - free(argv); - } - secinfo("authexec", "notify pipe failure"); - return errAuthorizationToolExecuteFailure; + free(argv); + } + os_log_error(AUTH_LOG, "notify pipe failure"); + return errAuthorizationToolExecuteFailure; } - - // make the communications pipe if requested - int comm[2]; - if (communicationsPipe && socketpair(AF_UNIX, SOCK_STREAM, 0, comm)) { - close(notify[READ]); close(notify[WRITE]); - close(dataPipe[READ]); close(dataPipe[WRITE]); + + // make the communications pipe if requested + int comm[2]; + if (communicationsPipe && socketpair(AF_UNIX, SOCK_STREAM, 0, comm)) { + close(notify[READ]); close(notify[WRITE]); + close(dataPipe[READ]); close(dataPipe[WRITE]); if(argv) { - free(argv); - } - secinfo("authexec", "comm pipe failure"); - return errAuthorizationToolExecuteFailure; - } + free(argv); + } + os_log_error(AUTH_LOG, "comm pipe failure"); + return errAuthorizationToolExecuteFailure; + } + + OSStatus status = errSecSuccess; + + // do the standard forking tango... + int delay = 1; + for (int n = 5;; n--, delay *= 2) { + switch (fork()) { + case -1: // error + if (errno == EAGAIN) { + // potentially recoverable resource shortage + if (n > 0) { + os_log(AUTH_LOG, "resource shortage (EAGAIN), delaying %d seconds", delay); + sleep(delay); + continue; + } + } + os_log_error(AUTH_LOG, "fork failed (errno=%d)", errno); + close(notify[READ]); close(notify[WRITE]); + status = errAuthorizationToolExecuteFailure; + goto exit_point; + + default: { // parent + // close foreign side of pipes + close(notify[WRITE]); + if (communicationsPipe) + close(comm[WRITE]); + + close(dataPipe[READ]); + if (write(dataPipe[WRITE], extForm, sizeof(*extForm)) != sizeof(*extForm)) { + os_log_error(AUTH_LOG, "fwrite data failed (errno=%d)", errno); + status = errAuthorizationInternal; + close(notify[READ]); + close(dataPipe[WRITE]); + if (communicationsPipe) { + close(comm[READ]); + } + goto exit_point; + } + // get status notification from child + os_log_debug(AUTH_LOG, "parent waiting for status"); + ssize_t rc = read(notify[READ], &status, sizeof(status)); + status = n2h(status); + switch (rc) { + default: // weird result of read: post error + os_log_error(AUTH_LOG, "unexpected read return value %ld", long(rc)); + status = errAuthorizationToolEnvironmentError; + // fall through + case sizeof(status): // read succeeded: child reported an error + os_log_error(AUTH_LOG, "parent received status=%d", (int)status); + close(notify[READ]); + close(dataPipe[WRITE]); + if (communicationsPipe) { + close(comm[READ]); + close(comm[WRITE]); + } + goto exit_point; + case 0: // end of file: exec succeeded + close(notify[READ]); + close(dataPipe[WRITE]); + if (communicationsPipe) + *communicationsPipe = fdopen(comm[READ], "r+"); + os_log_debug(AUTH_LOG, "parent resumes (no error)"); + status = errSecSuccess; + goto exit_point; + } + } + + case 0: // child + // close foreign side of pipes + close(notify[READ]); + if (communicationsPipe) + close(comm[READ]); + + // close write end of the data PIPE + close(dataPipe[WRITE]); + + // fd 1 (stdout) holds the notify write end + dup2(notify[WRITE], 1); + close(notify[WRITE]); + + // fd 0 (stdin) holds either the comm-link write-end or /dev/null + if (communicationsPipe) { + dup2(comm[WRITE], 0); + close(comm[WRITE]); + } else { + close(0); + open("/dev/null", O_RDWR); + } + + // okay, execute the trampoline + if (argv) + execv(trampoline, (char *const*)argv); + + // execute failed - tell the parent + { + // in case of failure, close read end of the data pipe as well + close(dataPipe[WRITE]); + close(dataPipe[READ]); + OSStatus error = errAuthorizationToolExecuteFailure; + error = h2n(error); + write(1, &error, sizeof(error)); + _exit(1); + } + } + } + +exit_point: + free(argv); + return status; +} - OSStatus status = errSecSuccess; - // do the standard forking tango... - int delay = 1; - for (int n = 5;; n--, delay *= 2) { - switch (fork()) { - case -1: // error - if (errno == EAGAIN) { - // potentially recoverable resource shortage - if (n > 0) { - secinfo("authexec", "resource shortage (EAGAIN), delaying %d seconds", delay); - sleep(delay); - continue; - } - } - secinfo("authexec", "fork failed (errno=%d)", errno); - close(notify[READ]); close(notify[WRITE]); - status = errAuthorizationToolExecuteFailure; - goto exit_point; +// +// Build an argv vector +// +static const char **argVector(const char *trampoline, const char *pathToTool, +const char *mboxFdText, char *const *arguments) +{ + int length = 0; + if (arguments) { + for (char *const *p = arguments; *p; p++) + length++; + } + if (const char **args = (const char **)malloc(sizeof(const char *) * (length + 4))) { + args[0] = trampoline; + args[1] = pathToTool; + args[2] = mboxFdText; + if (arguments) + for (int n = 0; arguments[n]; n++) + args[n + 3] = arguments[n]; + args[length + 3] = NULL; + return args; + } + return NULL; +} - default: { // parent - // close foreign side of pipes - close(notify[WRITE]); - if (communicationsPipe) - close(comm[WRITE]); - close(dataPipe[READ]); - if (write(dataPipe[WRITE], extForm, sizeof(*extForm)) != sizeof(*extForm)) { - secinfo("authexec", "fwrite data failed (errno=%d)", errno); - status = errAuthorizationInternal; - close(notify[READ]); - close(dataPipe[WRITE]); - if (communicationsPipe) { - close(comm[READ]); - close(comm[WRITE]); - } - goto exit_point; - } - close(dataPipe[WRITE]); - // get status notification from child - secinfo("authexec", "parent waiting for status"); - ssize_t rc = read(notify[READ], &status, sizeof(status)); - status = n2h(status); - switch (rc) { - default: // weird result of read: post error - secinfo("authexec", "unexpected read return value %ld", long(rc)); - status = errAuthorizationToolEnvironmentError; - // fall through - case sizeof(status): // read succeeded: child reported an error - secinfo("authexec", "parent received status=%d", (int)status); - close(notify[READ]); - close(dataPipe[WRITE]); - if (communicationsPipe) { - close(comm[READ]); - close(comm[WRITE]); - } - goto exit_point; - case 0: // end of file: exec succeeded - close(notify[READ]); - close(dataPipe[WRITE]); - if (communicationsPipe) - *communicationsPipe = fdopen(comm[READ], "r+"); - secinfo("authexec", "parent resumes (no error)"); - status = errSecSuccess; - goto exit_point; - } + +OSStatus AuthorizationExecuteWithPrivilegesInternal(const AuthorizationRef authorization, + const char * _Nonnull pathToTool, + const char * _Nonnull const * arguments, + pid_t * newProcessPid, + const uid_t uid, + int stdOut, + int stdErr, + int stdIn, + void(^processFinished)(const int exitStatus)) +{ + // externalize the authorization + AuthorizationExternalForm extForm; + if (OSStatus err = AuthorizationMakeExternalForm(authorization, &extForm)) + return err; + + return AuthorizationExecuteWithPrivilegesExternalFormInternal(&extForm, pathToTool, arguments, newProcessPid, uid, stdOut, stdErr, stdIn, processFinished); +} + +OSStatus AuthorizationExecuteWithPrivilegesExternalFormInternal(const AuthorizationExternalForm *extAuthorization, + const char * _Nonnull pathToTool, + const char * _Nullable const * _Nullable arguments, + pid_t * newProcessPid, + const uid_t uid, + int stdOut, + int stdErr, + int stdIn, + void(^processFinished)(const int exitStatus)) +{ + xpc_object_t message; + __block OSStatus retval = errAuthorizationInternal; + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + if (!sema) { + os_log_error(AUTH_LOG, "Unable to create trampoline semaphore"); + return retval; + } + __block xpc_connection_t trampolineConnection = xpc_connection_create_mach_service("com.apple.security.authtrampoline", NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); + + if (!trampolineConnection) { + os_log_error(AUTH_LOG, "Unable to create trampoline mach service"); + dispatch_release(sema); + return retval; + } + + xpc_connection_set_event_handler(trampolineConnection, ^(xpc_object_t event) { + xpc_type_t type = xpc_get_type(event); + + if (type == XPC_TYPE_ERROR) { + if (trampolineConnection) { + xpc_release(trampolineConnection); + trampolineConnection = NULL; + } + if (event == XPC_ERROR_CONNECTION_INTERRUPTED && processFinished) { + os_log_error(AUTH_LOG, "Connection with trampoline was interruped"); + processFinished(134); // simulate killed by SIGABRT + } + } else { + const char *requestId = xpc_dictionary_get_string(event, XPC_REQUEST_ID); + if (requestId && strncmp(XPC_EVENT_MSG, requestId, strlen(XPC_EVENT_MSG)) == 0) { + const char *eventType = xpc_dictionary_get_string(event, XPC_EVENT_TYPE); + if (eventType && strncmp(XPC_EVENT_TYPE_CHILDEND, eventType, strlen(XPC_EVENT_TYPE_CHILDEND)) == 0) { + int exitStatus = (int)xpc_dictionary_get_int64(event, RETVAL_STATUS); + os_log_debug(AUTH_LOG, "Child process ended with exit status %d", exitStatus); + + if (trampolineConnection) { + xpc_connection_cancel(trampolineConnection); + xpc_release(trampolineConnection); + trampolineConnection = NULL; + } + if (processFinished) { + processFinished(exitStatus); + }; + } else { + os_log_error(AUTH_LOG, "Unknown event type [%s] arrived from trampoline", eventType); + } + } else { + os_log_error(AUTH_LOG, "Unknown request [%s] arrived from trampoline", requestId); + } } - - case 0: // child - // close foreign side of pipes - close(notify[READ]); - if (communicationsPipe) - close(comm[READ]); + }); + + xpc_connection_resume(trampolineConnection); + + message = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_string(message, XPC_REQUEST_ID, XPC_REQUEST_CREATE_PROCESS); + + Boolean waitForEndNeeded = (processFinished != NULL); + if (stdIn >= 0) { + xpc_object_t xpcInFd = xpc_fd_create(stdIn); + if (!xpcInFd) { + os_log_error(AUTH_LOG, "Unable to create XPC stdin FD"); + goto finish; + } + xpc_dictionary_set_value(message, PARAM_STDIN, xpcInFd); + xpc_release(xpcInFd); + waitForEndNeeded = true; + } + + if (stdOut >= 0) { + xpc_object_t xpcOutFd = xpc_fd_create(stdOut); + if (!xpcOutFd) { + os_log_error(AUTH_LOG, "Unable to create XPC stdout FD"); + goto finish; + } + xpc_dictionary_set_value(message, PARAM_STDOUT, xpcOutFd); + xpc_release(xpcOutFd); + waitForEndNeeded = true; + } - // close write end of the data PIPE - close(dataPipe[WRITE]); + if (stdErr >= 0) { + xpc_object_t xpcErrFd = xpc_fd_create(stdErr); + if (!xpcErrFd) { + os_log_error(AUTH_LOG, "Unable to create XPC stderr FD"); + goto finish; + } + xpc_dictionary_set_value(message, PARAM_STDERR, xpcErrFd); + xpc_release(xpcErrFd); + waitForEndNeeded = true; + } - // fd 1 (stdout) holds the notify write end - dup2(notify[WRITE], 1); - close(notify[WRITE]); - - // fd 0 (stdin) holds either the comm-link write-end or /dev/null - if (communicationsPipe) { - dup2(comm[WRITE], 0); - close(comm[WRITE]); - } else { - close(0); - open("/dev/null", O_RDWR); - } - - // okay, execute the trampoline - if (argv) - execv(trampoline, (char *const*)argv); + extern char** environ; - // execute failed - tell the parent - { - // in case of failure, close read end of the data pipe as well - close(dataPipe[WRITE]); - close(dataPipe[READ]); - OSStatus error = errAuthorizationToolExecuteFailure; - error = h2n(error); - write(1, &error, sizeof(error)); - _exit(1); - } - } - } + if (environ) { + xpc_object_t envArray = xpc_array_create(NULL, 0); + char **ptr = environ; -exit_point: - free(argv); - return status; -} + while (*ptr) { + xpc_object_t xpcString = xpc_string_create(*ptr++); + xpc_array_append_value(envArray, xpcString); + xpc_release(xpcString); + } + xpc_dictionary_set_value(message, PARAM_ENV, envArray); + xpc_release(envArray); + } + xpc_dictionary_set_string(message, PARAM_TOOL_PATH, pathToTool); + xpc_dictionary_set_uint64(message, PARAM_EUID, uid); + { + const char *cwd = getcwd(NULL, 0); + if (cwd) { + xpc_dictionary_set_string(message, PARAM_CWD, cwd); + } + } + xpc_dictionary_set_bool(message, PARAM_CHILDEND_NEEDED, waitForEndNeeded); -// -// Build an argv vector -// -static const char **argVector(const char *trampoline, const char *pathToTool, - const char *mboxFdText, char *const *arguments) -{ - int length = 0; - if (arguments) { - for (char *const *p = arguments; *p; p++) - length++; - } - if (const char **args = (const char **)malloc(sizeof(const char *) * (length + 4))) { - args[0] = trampoline; - args[1] = pathToTool; - args[2] = mboxFdText; - if (arguments) - for (int n = 0; arguments[n]; n++) - args[n + 3] = arguments[n]; - args[length + 3] = NULL; - return args; - } - return NULL; + if (arguments) { + xpc_object_t paramsArray = xpc_array_create(NULL, 0); + int i = 0; + while (arguments[i] != NULL) { + xpc_object_t xpcString = xpc_string_create(arguments[i++]); + xpc_array_append_value(paramsArray, xpcString); + xpc_release(xpcString); + } + xpc_dictionary_set_value(message, PARAM_TOOL_PARAMS, paramsArray); + xpc_release(paramsArray); + } + xpc_dictionary_set_data(message, PARAM_AUTHREF, extAuthorization, sizeof(*extAuthorization)); + + retval = errAuthorizationToolExecuteFailure; + if (trampolineConnection) { + xpc_connection_send_message_with_reply(trampolineConnection, message, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(xpc_object_t event) { + xpc_type_t type = xpc_get_type(event); + const char *requestId = xpc_dictionary_get_string(event, XPC_REQUEST_ID); + if (type == XPC_TYPE_ERROR) { + os_log_error(AUTH_LOG, "Error when trying to communicate with the trampoline"); + } + else if (requestId && strncmp(XPC_REPLY_MSG, requestId, strlen(XPC_REPLY_MSG)) == 0) { + retval = (OSStatus)xpc_dictionary_get_int64(event, RETVAL_STATUS); + if (newProcessPid && retval == errAuthorizationSuccess) { + *newProcessPid = (OSStatus)xpc_dictionary_get_uint64(event, RETVAL_CHILD_PID); + } + } else { + os_log_error(AUTH_LOG, "Trampoline returned invalid data"); + } + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + } else { + os_log_error(AUTH_LOG, "Unable to establish connection to the trampoline"); + } + dispatch_release(sema); + +finish: + if (message) { + xpc_release(message); + } + return retval; } diff --git a/OSX/libsecurity_authorization/lib/trampolineServer.cpp b/OSX/libsecurity_authorization/lib/trampolineServer.cpp index 139e4756..fc8c0ffd 100644 --- a/OSX/libsecurity_authorization/lib/trampolineServer.cpp +++ b/OSX/libsecurity_authorization/lib/trampolineServer.cpp @@ -30,6 +30,7 @@ #include #include #include +#include // // In a tool launched via AuthorizationCopyPrivilegedReference, retrieve a copy @@ -38,6 +39,7 @@ OSStatus AuthorizationCopyPrivilegedReference(AuthorizationRef *authorization, AuthorizationFlags flags) { + secalert("AuthorizationCopyPrivilegedReference is deprecated and functionality will be removed in macOS 10.14 - please update your application"); // flags are currently reserved if (flags != 0) return errAuthorizationInvalidFlags; diff --git a/OSX/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp b/OSX/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp index 347971db..e80d7213 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp +++ b/OSX/libsecurity_cdsa_utilities/lib/cssmaclpod.cpp @@ -216,11 +216,12 @@ uint32 pinFromAclTag(const char *tag, const char *suffix /* = NULL */) if (tag) { char format[20]; snprintf(format, sizeof(format), "PIN%%d%s%%n", suffix ? suffix : ""); - uint32 pin; - unsigned consumed; - sscanf(tag, format, &pin, &consumed); - if (consumed == strlen(tag)) // complete and sufficient + uint32 pin = 0; + unsigned consumed = 0; + // sscanf does not count %n as a filled value so number of read variables should be just 1 + if (sscanf(tag, format, &pin, &consumed) == 1 && consumed == strlen(tag)) { // complete and sufficient return pin; + } } return 0; } diff --git a/OSX/libsecurity_cdsa_utilities/lib/cssmalloc.cpp b/OSX/libsecurity_cdsa_utilities/lib/cssmalloc.cpp index b2a47672..63d262b2 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/cssmalloc.cpp +++ b/OSX/libsecurity_cdsa_utilities/lib/cssmalloc.cpp @@ -30,6 +30,7 @@ #include #include #include +#include @@ -73,8 +74,12 @@ void *CssmAllocatorMemoryFunctions::relayRealloc(void *mem, size_t size, void *r void *CssmAllocatorMemoryFunctions::relayCalloc(uint32 count, size_t size, void *ref) throw(std::bad_alloc) { // Allocator doesn't have a calloc() method - void *mem = allocator(ref).malloc(size * count); - memset(mem, 0, size * count); + size_t alloc_size = 0; + if (os_mul_overflow(count, size, &alloc_size)) { + return NULL; + } + void *mem = allocator(ref).malloc(alloc_size); + memset(mem, 0, alloc_size); return mem; } diff --git a/OSX/libsecurity_cdsa_utilities/lib/uniformrandom.h b/OSX/libsecurity_cdsa_utilities/lib/uniformrandom.h deleted file mode 100644 index ecbdae36..00000000 --- a/OSX/libsecurity_cdsa_utilities/lib/uniformrandom.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2000-2001,2003-2004,2006,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@ - */ - - -// -// uniformrandom - uniformly distributed random number operators -// -#ifndef _H_UNIFORMRANDOM -#define _H_UNIFORMRANDOM - -#include - - -namespace Security { - - -// -// Uniform binary blob generator. -// This operator deals exclusively in byte arrays. -// -template -class UniformRandomBlobs : public Generator { -public: - using Generator::random; - - template - void random(Object &obj) { random(&obj, sizeof(obj)); } - - void random(CssmData &data) { random(data.data(), data.length()); } -}; - - -}; // end namespace Security - - -#endif //_H_UNIFORMRANDOM diff --git a/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.cpp b/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.cpp index fe246994..4eccabc8 100644 --- a/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.cpp +++ b/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.cpp @@ -1,12 +1,12 @@ /* - * Copyright (c) 2002,2011-2012,2014 Apple Inc. All Rights Reserved. - * + * Copyright (c) 2002,2011-2012,2014-2019 Apple Inc. All Rights Reserved. + * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). * You may not use this file except in compliance with the License. Please obtain * a copy of the License at http://www.apple.com/publicsource and read it before * using this file. - * + * * This 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 @@ -14,11 +14,11 @@ * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the * specific language governing rights and limitations under the License. */ - + /* * cuTimeStr.cpp - time string routines */ -#include "cuTimeStr.h" +#include "cuTimeStr.h" #include "cuCdsaUtils.h" #include #include @@ -29,7 +29,7 @@ /* * Given a string containing either a UTC-style or "generalized time" * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on - * error. + * error. */ int cuTimeStringToTm( const char *str, @@ -46,7 +46,7 @@ int cuTimeStringToTm( if((str == NULL) || (len == 0) || (tmp == NULL)) { return 1; } - + /* tolerate NULL terminated or not */ if(str[len - 1] == '\0') { len--; @@ -61,12 +61,12 @@ int cuTimeStringToTm( break; case GENERALIZED_TIME_STRLEN: // 4-digit year break; - default: // unknown format + default: // unknown format return 1; } - + cp = (char *)str; - + /* check that all characters except last are digits */ for(i=0; i<(len - 1); i++) { if ( !(isdigit(cp[i])) ) { @@ -88,13 +88,13 @@ int cuTimeStringToTm( szTemp[3] = *cp++; szTemp[4] = '\0'; } - else { + else { szTemp[2] = '\0'; } x = atoi( szTemp ); if(isUtc) { - /* - * 2-digit year. + /* + * 2-digit year. * 0 <= year < 50 : assume century 21 * 50 <= year < 70 : illegal per PKIX, though we tolerate * 70 < year <= 99 : assume century 20 @@ -109,7 +109,7 @@ int cuTimeStringToTm( */ else { /* century 20 */ - x += 1900; + x += 1900; } } /* by definition - tm_year is year - 1900 */ @@ -178,25 +178,37 @@ int cuTimeStringToTm( #define MAX_TIME_STR_LEN 30 /* protects time(), gmtime() */ -static pthread_mutex_t timeMutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t timeMutex = PTHREAD_MUTEX_INITIALIZER; -char *cuTimeAtNowPlus(int secFromNow, +char *cuTimeAtNowPlus(int secFromNow, timeSpec spec) { struct tm utc; char *outStr; time_t baseTime; - + pthread_mutex_lock(&timeMutex); baseTime = time(NULL); baseTime += (time_t)secFromNow; utc = *gmtime(&baseTime); pthread_mutex_unlock(&timeMutex); - + outStr = (char *)APP_MALLOC(MAX_TIME_STR_LEN); - + + /* Check for legacy value of 1 */ + if (spec == CU_TIME_LEGACY) { +#if (TIME_UTC == 1) + /* time.h has defined TIME_UTC=1, so legacy caller + actually wants TIME_UTC, not TIME_CSSM. */ + spec = CU_TIME_UTC; +#else + spec = CU_TIME_CSSM; +#endif + } + switch(spec) { - case TIME_UTC: + case CU_TIME_UTC: + case CU_TIME_LEGACY: /* UTC - 2 year digits - code which parses this assumes that * (2-digit) years between 0 and 49 are in century 21 */ if(utc.tm_year >= 100) { @@ -206,16 +218,16 @@ char *cuTimeAtNowPlus(int secFromNow, utc.tm_year /* + 1900 */, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); break; - case TIME_GEN: + case CU_TIME_GEN: sprintf(outStr, "%04d%02d%02d%02d%02d%02dZ", - /* note year is relative to 1900, hopefully it'll + /* note year is relative to 1900, hopefully it'll * have four valid digits! */ utc.tm_year + 1900, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); break; - case TIME_CSSM: + case CU_TIME_CSSM: sprintf(outStr, "%04d%02d%02d%02d%02d%02d", - /* note year is relative to 1900, hopefully it'll have + /* note year is relative to 1900, hopefully it'll have * four valid digits! */ utc.tm_year + 1900, utc.tm_mon + 1, utc.tm_mday, utc.tm_hour, utc.tm_min, utc.tm_sec); @@ -227,17 +239,17 @@ char *cuTimeAtNowPlus(int secFromNow, /* * Convert a CSSM_X509_TIME, which can be in any of three forms (UTC, * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller - * must free() the result. Returns NULL if x509time is badly formed. + * must free() the result. Returns NULL if x509time is badly formed. */ char *cuX509TimeToCssmTimestring( const CSSM_X509_TIME *x509Time, unsigned *rtnLen) // for caller's convenience { int len = (int)x509Time->time.Length; - const char *inStr = (char *)x509Time->time.Data; + const char *inStr = (char *)x509Time->time.Data; // not NULL terminated! char *rtn; - + *rtnLen = 0; if((len == 0) || (inStr == NULL)) { return NULL; @@ -254,8 +266,8 @@ char *cuX509TimeToCssmTimestring( tmp[1] = inStr[1]; tmp[2] = '\0'; year = atoi(tmp); - - /* + + /* * 0 <= year < 50 : assume century 21 * 50 <= year < 70 : illegal per PKIX * 70 < year <= 99 : assume century 20 @@ -281,7 +293,7 @@ char *cuX509TimeToCssmTimestring( case GENERALIZED_TIME_STRLEN: memmove(rtn, inStr, len - 1); // don't copy the Z break; - + default: free(rtn); return NULL; diff --git a/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.h b/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.h index 0eefc56e..77cef334 100644 --- a/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.h +++ b/OSX/libsecurity_cdsa_utils/lib/cuTimeStr.h @@ -1,25 +1,25 @@ /* - * Copyright (c) 2002,2011,2014 Apple Inc. All Rights Reserved. - * + * Copyright (c) 2002,2011,2014-2019 Apple Inc. All Rights Reserved. + * * The contents of this file constitute Original Code as defined in and are * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. + * You may not use this file except in compliance with the License. * Please obtain a copy of the License at http://www.apple.com/publicsource * and read it before using this file. - * + * * This 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, + * 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 + * Please see the License for the specific language governing rights * and limitations under the License. */ - + /* * cuTimeStr.h = Time string utilities. */ - + #ifndef _TIME_STR_H_ #define _TIME_STR_H_ @@ -38,7 +38,7 @@ extern "C" { /* * Given a string containing either a UTC-style or "generalized time" * time string, convert to a struct tm (in GMT/UTC). Returns nonzero on - * error. + * error. */ int cuTimeStringToTm( const char *str, @@ -46,23 +46,45 @@ int cuTimeStringToTm( struct tm *tmp); typedef enum { - TIME_UTC, - TIME_CSSM, - TIME_GEN + CU_TIME_UTC = 0, + CU_TIME_LEGACY = 1, /* do not use; see note below */ + CU_TIME_GEN = 2, + CU_TIME_CSSM = 3 } timeSpec; +/* TIME_UTC was formerly defined in this header with a value of 0. However, + * a newer version of may define it with a value of 1. Clients which + * specify the TIME_UTC constant for a timeSpec parameter will get a value + * of 0 under the old header, and a value of 1 under the newer header. + * The latter conflicts with the old definition of TIME_CSSM. To resolve this, + * we now treat 1 as a legacy value which maps to CU_TIME_UTC if TIME_UTC=1, + * otherwise to CU_TIME_CSSM. + * + * Important: any code which specifies the legacy TIME_CSSM constant must be + * recompiled against this header to ensure the correct timeSpec value is used. + */ +#ifndef TIME_UTC +#define TIME_UTC CU_TIME_UTC /* time.h has not defined TIME_UTC */ +#endif +#ifndef TIME_GEN +#define TIME_GEN CU_TIME_GEN +#endif +#ifndef TIME_CSSM +#define TIME_CSSM CU_TIME_CSSM +#endif + /* * Return an APP_MALLOCd time string, specified format and time relative * to 'now' in seconds. */ char *cuTimeAtNowPlus( - int secFromNow, + int secFromNow, timeSpec spec); /* * Convert a CSSM_X509_TIME, which can be in any of three forms (UTC, * generalized, or CSSM_TIMESTRING) into a CSSM_TIMESTRING. Caller - * must free() the result. Returns NULL if x509time is badly formed. + * must free() the result. Returns NULL if x509time is badly formed. */ char *cuX509TimeToCssmTimestring( const CSSM_X509_TIME *x509Time, diff --git a/OSX/libsecurity_cms/lib/CMSDecoder.cpp b/OSX/libsecurity_cms/lib/CMSDecoder.cpp index a6fb2688..9fe2ecb9 100644 --- a/OSX/libsecurity_cms/lib/CMSDecoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSDecoder.cpp @@ -25,8 +25,8 @@ * CMSDecoder.cpp - Interface for decoding CMS messages. */ -#include "CMSDecoder.h" -#include "CMSPrivate.h" +#include +#include #include "CMSUtils.h" #include <../libsecurity_codesigning/lib/csutilities.h> @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -428,7 +429,7 @@ OSStatus CMSDecoderCopySignerStatus( SecTrustRef *secTrust, /* optional; RETURNED */ OSStatus *certVerifyResultCode) /* optional; RETURNED */ { - if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final) || (!policyOrArray)) { + if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final) || (!policyOrArray) || !signerStatus) { return errSecParam; } @@ -494,8 +495,7 @@ OSStatus CMSDecoderCopySignerStatus( if(secTrust != NULL) { *secTrust = theTrust; /* we'll release our reference at the end */ - if (theTrust) - CFRetain(theTrust); + CFRetainSafe(theTrust); } SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex); diff --git a/OSX/libsecurity_cms/lib/CMSDecoder.h b/OSX/libsecurity_cms/lib/CMSDecoder.h deleted file mode 100644 index 7194f286..00000000 --- a/OSX/libsecurity_cms/lib/CMSDecoder.h +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2006-2013 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@ - */ - -/* - * CMSDecoder.h - decode, decrypt, and/or verify signatures of messages in the - * Cryptographic Message Syntax (CMS), per RFC 3852. - * - * See CMSEncoder.h for general information about CMS messages. - */ - -#ifndef _CMS_DECODER_H_ -#define _CMS_DECODER_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -CF_ASSUME_NONNULL_BEGIN - -/* - * Opaque reference to a CMS decoder object. - * This is a CF object, with standard CF semantics; dispose of it - * with CFRelease(). - */ -typedef struct CF_BRIDGED_TYPE(id) _CMSDecoder *CMSDecoderRef; - -CFTypeID CMSDecoderGetTypeID(void); - -/* - * Status of signature and signer information in a signed message. - */ -typedef CF_ENUM(uint32_t, CMSSignerStatus) { - kCMSSignerUnsigned = 0, /* message was not signed */ - kCMSSignerValid, /* message was signed and signature verify OK */ - kCMSSignerNeedsDetachedContent, /* message was signed but needs detached content - * to verify */ - kCMSSignerInvalidSignature, /* message was signed but had a signature error */ - kCMSSignerInvalidCert, /* message was signed but an error occurred in verifying - * the signer's certificate */ - kCMSSignerInvalidIndex /* specified signer index out of range */ -}; - -/* - * Create a CMSDecoder. Result must eventually be freed via CFRelease(). - */ -OSStatus CMSDecoderCreate( - CMSDecoderRef * __nonnull CF_RETURNS_RETAINED cmsDecoderOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Feed raw bytes of the message to be decoded into the decoder. Can be called - * multiple times. - * Returns errSecUnknownFormat upon detection of improperly formatted CMS - * message. - */ -OSStatus CMSDecoderUpdateMessage( - CMSDecoderRef cmsDecoder, - const void *msgBytes, - size_t msgBytesLen) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Indicate that no more CMSDecoderUpdateMessage() calls are forthcoming; - * finish decoding the message. - * Returns errSecUnknownFormat upon detection of improperly formatted CMS - * message. - */ -OSStatus CMSDecoderFinalizeMessage( - CMSDecoderRef cmsDecoder) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * A signed CMS message optionally includes the data which was signed. If the - * message does not include the signed data, caller specifies the signed data - * (the "detached content") here. - * - * This can be called either before or after the actual decoding of the message - * (via CMSDecoderUpdateMessage() and CMSDecoderFinalizeMessage()); the only - * restriction is that, if detached content is required, this function must - * be called befoere successfully ascertaining the signature status via - * CMSDecoderCopySignerStatus(). - */ -OSStatus CMSDecoderSetDetachedContent( - CMSDecoderRef cmsDecoder, - CFDataRef detachedContent) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the detached content specified in CMSDecoderSetDetachedContent(). - * Returns a NULL detachedContent if no detached content has been specified. - * Caller must CFRelease() the result. - */ -OSStatus CMSDecoderCopyDetachedContent( - CMSDecoderRef cmsDecoder, - CFDataRef * __nonnull CF_RETURNS_RETAINED detachedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * This function no longer affects the behavior of the CMS Decoder. Please - * discontinue use. - */ -OSStatus CMSDecoderSetSearchKeychain( - CMSDecoderRef cmsDecoder, - CFTypeRef keychainOrArray) - __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_5, __MAC_10_13, __IPHONE_NA, __IPHONE_NA, - "To change the search keychains call SecKeychainSetSearchList."); - -/* - * Obtain the number of signers of a message. A result of zero indicates that - * the message was not signed. - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - */ -OSStatus CMSDecoderGetNumSigners( - CMSDecoderRef cmsDecoder, - size_t *numSignersOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the status of a CMS message's signature. A CMS message can - * be signed my multiple signers; this function returns the status - * associated with signer 'n' as indicated by the signerIndex parameter. - * - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - * - * Note that signature and certificate verification of a decoded message - * does *not* occur until this routine is called. - * - * All returned values are optional - pass NULL if you don't need a - * particular parameter. - * - * Note that errors like "bad signature" and "bad cert" do NOT cause this - * routine to return a nonzero error status itself; such errors are reported - * in the various out parameters, listed below. - * - * Inputs: - * ------- - * cmsDecoder : a CMSDecoder which has successfully performed a - * CMSDecoderFinalizeMessage(). - * signerIndex : indicates which of 'n' signers is being examined. - * Range is 0...(numSigners-1). - * policyOrArray : Either a SecPolicyRef or a CFArray of them. - * These policies are used to verify the signer's certificate. - * evaluateSecTrust : When TRUE, causes the SecTrust oebject created for the - * evaluation of the signer cert to actually be evaluated - * via SecTrustEvaluate(). When FALSE, the caller performs - * the SecTrustEvaluate() operation on the SecTrust object - * returned via the secTrust out parameter. - * NOTE: it is hazardous and not recommended to pass in FALSE - * for the evaluateSecTrust parameter as well as NULL for the - * secTrust out parameter, since no evaluation of the signer - * cert can occur in that situation. - * - * Outputs: - * -------- - * signerStatusOut -- An enum indicating the overall status. - * kCMSSignerUnsigned : message was not signed. - * kCMSSignerValid : both signature and signer certificate verified OK. - * kCMSSignerNeedsDetachedContent : a call to CMSDecoderSetDetachedContent() - * is required to ascertain the signature status. - * kCMSSignerInvalidSignature : bad signature. - * kCMSSignerInvalidCert : an error occurred verifying the signer's certificate. - * Further information available via the secTrust and - * certVerifyResultCode parameters. This will never be - * returned if evaluateSecTrust is FALSE. - * kCMSSignerInvalidIndex : specified signerIndex is larger than the number of - * signers (minus 1). - * - * secTrustOut -- The SecTrust object used to verify the signer's - * certificate. Caller must CFRelease this. - * certVerifyResultCodeOut -- The result of the certificate verification. If - * the evaluateSecTrust argument is set to FALSE on - * input, this out parameter is undefined on return. - * - * The certVerifyResultCode value can indicate a large number of errors; some of - * the most common and interesting errors are: - * - * CSSMERR_TP_INVALID_ANCHOR_CERT : The cert was verified back to a - * self-signed (root) cert which was present in the message, but - * that root cert is not a known, trusted root cert. - * CSSMERR_TP_NOT_TRUSTED: The cert could not be verified back to - * a root cert. - * CSSMERR_TP_VERIFICATION_FAILURE: A root cert was found which does - * not self-verify. - * CSSMERR_TP_VERIFY_ACTION_FAILED: Indicates a failure of the requested - * policy action. - * CSSMERR_TP_INVALID_CERTIFICATE: Indicates a bad leaf cert. - * CSSMERR_TP_CERT_EXPIRED: A cert in the chain was expired at the time of - * verification. - * CSSMERR_TP_CERT_NOT_VALID_YET: A cert in the chain was not yet valie at - * the time of verification. - */ -OSStatus CMSDecoderCopySignerStatus( - CMSDecoderRef cmsDecoder, - size_t signerIndex, - CFTypeRef policyOrArray, - Boolean evaluateSecTrust, - CMSSignerStatus * __nullable signerStatusOut, /* optional; RETURNED */ - SecTrustRef * __nullable CF_RETURNS_RETAINED secTrustOut, /* optional; RETURNED */ - OSStatus * __nullable certVerifyResultCodeOut) /* optional; RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the email address of signer 'signerIndex' of a CMS message, if - * present. - * - * 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 CMSDecoderCopySignerEmailAddress( - CMSDecoderRef cmsDecoder, - size_t signerIndex, - CFStringRef * __nonnull CF_RETURNS_RETAINED signerEmailAddressOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the certificate of signer 'signerIndex' of a CMS message, if - * present. - * - * 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 CMSDecoderCopySignerCert( - CMSDecoderRef cmsDecoder, - size_t signerIndex, - SecCertificateRef * __nonnull CF_RETURNS_RETAINED signerCertOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Determine whether a CMS message was encrypted. Returns TRUE if so, FALSE if not. - * Note that if the message was encrypted, and the decoding succeeded, (i.e., - * CMSDecoderFinalizeMessage() returned errSecSuccess), then the message was successfully - * decrypted. - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - */ -OSStatus CMSDecoderIsContentEncrypted( - CMSDecoderRef cmsDecoder, - Boolean *isEncryptedOut) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the eContentType OID for a SignedData's EncapsulatedContentType, if - * present. If the message was not signed this will return NULL. - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - * The returned OID's data is in the same format as a CSSM_OID; i.e., it's - * the encoded content of the OID, not including the tag and length bytes. - */ -OSStatus CMSDecoderCopyEncapsulatedContentType( - CMSDecoderRef cmsDecoder, - CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain an array of all of the certificates in a message. Elements of the - * returned array are SecCertificateRefs. The caller must CFRelease the returned - * array. If a message does not contain any certificates (which is the case for - * a message which is encrypted but not signed), the returned *certs value - * is NULL. The function will return errSecSuccess in this case. - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - */ -OSStatus CMSDecoderCopyAllCerts( - CMSDecoderRef cmsDecoder, - CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the actual message content (payload), if any. If the message was - * signed with detached content this will return NULL. - * Caller must CFRelease the result. - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - */ -OSStatus CMSDecoderCopyContent( - CMSDecoderRef cmsDecoder, - CFDataRef * __nonnull CF_RETURNS_RETAINED contentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the signing time of signer 'signerIndex' of a CMS message, if - * present. This is an unauthenticate time, although it 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 CMSDecoderCopySignerSigningTime( - CMSDecoderRef cmsDecoder, - size_t signerIndex, - 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 - * a timestamping authority. - * - * 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 CMSDecoderCopySignerTimestamp( - CMSDecoderRef cmsDecoder, - size_t signerIndex, - CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); - - /* - * Obtain the timestamp of signer 'signerIndex' of a CMS message, if - * present. This timestamp is an authenticated timestamp provided by - * a timestamping authority. Use the policy provided as a parameter - * - * 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 CMSDecoderCopySignerTimestampWithPolicy( - CMSDecoderRef cmsDecoder, - CFTypeRef __nullable timeStampPolicy, - size_t signerIndex, /* usually 0 */ - CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); - -/* - * Obtain an array of the certificates in a timestamp response. Elements of the - * returned array are SecCertificateRefs. The caller must CFRelease the returned - * array. This timestamp is an authenticated timestamp provided by - * a timestamping authority. - * - * Returns errSecParam if the CMS message was not signed or if signerIndex - * is greater than the number of signers of the message minus one. It returns - * errSecItemNotFound if no certificates were found. - * - * This cannot be called until after CMSDecoderFinalizeMessage() is called. - */ -OSStatus CMSDecoderCopySignerTimestampCertificates( - CMSDecoderRef cmsDecoder, - 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 - -#ifdef __cplusplus -} -#endif - -#endif /* _CMS_DECODER_H_ */ - diff --git a/OSX/libsecurity_cms/lib/CMSEncoder.cpp b/OSX/libsecurity_cms/lib/CMSEncoder.cpp index de3b2c1e..27d6810d 100644 --- a/OSX/libsecurity_cms/lib/CMSEncoder.cpp +++ b/OSX/libsecurity_cms/lib/CMSEncoder.cpp @@ -25,8 +25,8 @@ * CMSEncoder.cpp - encode, sign, and/or encrypt CMS messages. */ -#include "CMSEncoder.h" -#include "CMSPrivate.h" +#include +#include #include "CMSUtils.h" #include #include @@ -468,6 +468,9 @@ static OSStatus cmsSetupForSignedData( case kCMSCertificateChainWithRoot: chainMode = SecCmsCMCertChainWithRoot; break; + case kCMSCertificateChainWithRootOrFail: + chainMode = SecCmsCMCertChainWithRootOrFail; + break; default: break; } @@ -1101,6 +1104,7 @@ OSStatus CMSEncoderSetCertificateChainMode( case kCMSCertificateSignerOnly: case kCMSCertificateChain: case kCMSCertificateChainWithRoot: + case kCMSCertificateChainWithRootOrFail: break; default: return errSecParam; diff --git a/OSX/libsecurity_cms/lib/CMSEncoder.h b/OSX/libsecurity_cms/lib/CMSEncoder.h deleted file mode 100644 index 32ec916a..00000000 --- a/OSX/libsecurity_cms/lib/CMSEncoder.h +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (c) 2006-2012 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@ - */ - -/* - * CMSEncoder.h - encode, sign, and/or encrypt messages in the Cryptographic - * Message Syntax (CMS), per RFC 3852. - * - * A CMS message can be signed, encrypted, or both. A message can be signed by - * an arbitrary number of signers; in this module, signers are expressed as - * SecIdentityRefs. A message can be encrypted for an arbitrary number of - * recipients; recipients are expressed here as SecCertificateRefs. - * - * In CMS terminology, this module performs encryption using the EnvelopedData - * ContentType and signing using the SignedData ContentType. - * - * If the message is both signed and encrypted, it uses "nested ContentInfos" - * in CMS terminology; in this implementation, signed & encrypted messages - * are implemented as an EnvelopedData containing a SignedData. - */ - -#ifndef _CMS_ENCODER_H_ -#define _CMS_ENCODER_H_ - -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -CF_ASSUME_NONNULL_BEGIN - -/* - * Opaque reference to a CMS encoder object. - * This is a CF object, with standard CF semantics; dispose of it - * with CFRelease(). - */ -typedef struct CF_BRIDGED_TYPE(id) _CMSEncoder *CMSEncoderRef; - -CFTypeID CMSEncoderGetTypeID(void) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Create a CMSEncoder. Result must eventually be freed via CFRelease(). - */ -OSStatus CMSEncoderCreate( - CMSEncoderRef * __nonnull CF_RETURNS_RETAINED cmsEncoderOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -extern const CFStringRef kCMSEncoderDigestAlgorithmSHA1; -extern const CFStringRef kCMSEncoderDigestAlgorithmSHA256; - -OSStatus CMSEncoderSetSignerAlgorithm( - CMSEncoderRef cmsEncoder, - CFStringRef digestAlgorithm) - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_NA); - -/* - * Specify signers of the CMS message; implies that the message will be signed. - * - * -- Caller can pass in one signer, as a SecIdentityRef, or an array of - * signers, as a CFArray of SecIdentityRefs. - * -- Can be called multiple times. - * -- If the message is not to be signed, don't call this. - * -- If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). - */ -OSStatus CMSEncoderAddSigners( - CMSEncoderRef cmsEncoder, - CFTypeRef signerOrArray) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain an array of signers as specified in CMSEncoderSetSigners(). - * Returns a NULL signers array if CMSEncoderSetSigners() has not been called. - * Caller must CFRelease the result. - */ -OSStatus CMSEncoderCopySigners( - CMSEncoderRef cmsEncoder, - CFArrayRef * __nonnull CF_RETURNS_RETAINED signersOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Specify recipients of the message. Implies that the message will - * be encrypted. - * - * -- Caller can pass in one recipient, as a SecCertificateRef, or an - * array of recipients, as a CFArray of SecCertificateRefs. - * -- Can be called multiple times. - * -- If the message is not to be encrypted, don't call this. - * -- If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). - */ -OSStatus CMSEncoderAddRecipients( - CMSEncoderRef cmsEncoder, - CFTypeRef recipientOrArray) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain an array of recipients as specified in CMSEncoderSetRecipients(). - * Returns a NULL recipients array if CMSEncoderSetRecipients() has not been - * called. - * Caller must CFRelease the result. - */ -OSStatus CMSEncoderCopyRecipients( - CMSEncoderRef cmsEncoder, - CFArrayRef * __nonnull CF_RETURNS_RETAINED recipientsOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * A signed message optionally includes the data to be signed. If the message - * is *not* to include the data to be signed, call this function with a value - * of TRUE for detachedContent. The default, if this function is not called, - * is detachedContent=FALSE, i.e., the message contains the data to be signed. - * - * -- Encrypted messages can not use detached content. (This restriction - * also applies to messages that are both signed and encrypted.) - * -- If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). - */ -OSStatus CMSEncoderSetHasDetachedContent( - CMSEncoderRef cmsEncoder, - Boolean detachedContent) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain a Boolean indicating whether the current message will have detached - * content. - * Returns the value specified in CMSEncoderHasDetachedContent() if that - * function has been called; else returns the default FALSE. - */ -OSStatus CMSEncoderGetHasDetachedContent( - CMSEncoderRef cmsEncoder, - Boolean *detachedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Optionally specify an eContentType OID for the inner EncapsulatedData for - * a signed message. The default eContentType, used if this function is not - * called, is id-data (which is the normal eContentType for applications such - * as SMIME). - * - * If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). - * - * NOTE: This function is deprecated in Mac OS X 10.7 and later; - * please use CMSEncoderSetEncapsulatedContentTypeOID() instead. - */ -OSStatus CMSEncoderSetEncapsulatedContentType( - CMSEncoderRef cmsEncoder, - const CSSM_OID *eContentType) - API_DEPRECATED_WITH_REPLACEMENT("CMSEncoderSetEncapsulatedContentTypeOID", macos(10.5, 10.7)) API_UNAVAILABLE(ios); - -/* - * Optionally specify an eContentType OID for the inner EncapsulatedData for - * a signed message. The default eContentTypeOID, used if this function is not - * called, is id-data (which is the normal eContentType for applications such - * as SMIME). - * - * The eContentTypeOID parameter may be specified as a CF string, e.g.: - * CFSTR("1.2.840.113549.1.7.1") - * - * If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). - */ -OSStatus CMSEncoderSetEncapsulatedContentTypeOID( - CMSEncoderRef cmsEncoder, - CFTypeRef eContentTypeOID) - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); - -/* - * Obtain the eContentType OID specified in CMSEncoderSetEncapsulatedContentType(). - * If CMSEncoderSetEncapsulatedContentType() has not been called this returns a - * NULL pointer. - * The returned OID's data is in the same format as the data provided to - * CMSEncoderSetEncapsulatedContentType;, i.e., it's the encoded content of - * the OID, not including the tag and length bytes. - */ -OSStatus CMSEncoderCopyEncapsulatedContentType( - CMSEncoderRef cmsEncoder, - CFDataRef * __nonnull CF_RETURNS_RETAINED eContentTypeOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Signed CMS messages can contain arbitrary sets of certificates beyond those - * indicating the identity of the signer(s). This function provides a means of - * adding these other certs. For normal signed messages it is not necessary to - * call this; the signer cert(s) and the intermediate certs needed to verify the - * signer(s) will be included in the message implicitly. - * - * -- Caller can pass in one cert, as a SecCertificateRef, or an array of certs, - * as a CFArray of SecCertificateRefs. - * -- If this is called, it must be called before the first call to - * CMSEncoderUpdateContent(). - * -- There is a "special case" use of CMS messages which involves neither - * signing nor encryption, but does include certificates. This is commonly - * used to transport "bags" of certificates. When constructing such a - * message, all an application needs to do is to create a CMSEncoderRef, - * call CMSEncoderAddSupportingCerts() one or more times, and then call - * CMSEncoderCopyEncodedContent() to get the resulting cert bag. No 'content' - * need be specified. (This is in fact the primary intended use for - * this function.) - */ -OSStatus CMSEncoderAddSupportingCerts( - CMSEncoderRef cmsEncoder, - CFTypeRef certOrArray) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain the SecCertificates provided in CMSEncoderAddSupportingCerts(). - * If CMSEncoderAddSupportingCerts() has not been called this will return a - * NULL value for *certs. - * Caller must CFRelease the result. - */ -OSStatus CMSEncoderCopySupportingCerts( - CMSEncoderRef cmsEncoder, - CFArrayRef * __nonnull CF_RETURNS_RETAINED certsOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Standard signed attributes, optionally specified in - * CMSEncoderAddSignedAttributes(). - */ -typedef CF_OPTIONS(uint32_t, CMSSignedAttributes) { - kCMSAttrNone = 0x0000, - /* - * S/MIME Capabilities - identifies supported signature, encryption, and - * digest algorithms. - */ - kCMSAttrSmimeCapabilities = 0x0001, - /* - * Indicates that a cert is the preferred cert for S/MIME encryption. - */ - kCMSAttrSmimeEncryptionKeyPrefs = 0x0002, - /* - * Same as kCMSSmimeEncryptionKeyPrefs, using an attribute OID preferred - * by Microsoft. - */ - kCMSAttrSmimeMSEncryptionKeyPrefs = 0x0004, - /* - * Include the signing time. - */ - kCMSAttrSigningTime = 0x0008, - /* - * Include the Apple Codesigning Hash Agility. - */ - kCMSAttrAppleCodesigningHashAgility = 0x0010, - kCMSAttrAppleCodesigningHashAgilityV2 = 0x0020, - /* - * Include the expiration time. - */ - kCMSAttrAppleExpirationTime = 0x0040, -}; - -/* - * Optionally specify signed attributes. Only meaningful when creating a - * signed message. If this is called, it must be called before - * CMSEncoderUpdateContent(). - */ -OSStatus CMSEncoderAddSignedAttributes( - CMSEncoderRef cmsEncoder, - CMSSignedAttributes signedAttributes) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Specification of what certificates to include in a signed message. - */ -typedef CF_ENUM(uint32_t, CMSCertificateChainMode) { - kCMSCertificateNone = 0, /* don't include any certificates */ - kCMSCertificateSignerOnly, /* only include signer certificate(s) */ - kCMSCertificateChain, /* signer certificate chain up to but not - * including root certiticate */ - kCMSCertificateChainWithRoot /* signer certificate chain including root */ -}; - -/* - * Optionally specify which certificates, if any, to include in a - * signed CMS message. The default, if this is not called, is - * kCMSCertificateChain, in which case the signer cert plus all CA - * certs needed to verify the signer cert, except for the root - * cert, are included. - * If this is called, it must be called before - * CMSEncoderUpdateContent(). - */ -OSStatus CMSEncoderSetCertificateChainMode( - CMSEncoderRef cmsEncoder, - CMSCertificateChainMode chainMode) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Obtain indication of which signer certs are to be included - * in a signed CMS message. - */ -OSStatus CMSEncoderGetCertificateChainMode( - CMSEncoderRef cmsEncoder, - CMSCertificateChainMode *chainModeOut) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Feed content bytes into the encoder. - * Can be called multiple times. - * No 'setter' routines can be called after this function has been called. - */ -OSStatus CMSEncoderUpdateContent( - CMSEncoderRef cmsEncoder, - const void *content, - size_t contentLen) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * Finish encoding the message and obtain the encoded result. - * Caller must CFRelease the result. - */ -OSStatus CMSEncoderCopyEncodedContent( - CMSEncoderRef cmsEncoder, - CFDataRef * __nonnull CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); - -/* - * High-level, one-shot encoder function. - * - * Inputs (all except for content optional, though at least one - * of {signers, recipients} must be non-NULL) - * ------------------------------------------------------------ - * signers : signer identities. Either a SecIdentityRef, or a - * CFArray of them. - * recipients : recipient certificates. Either a SecCertificateRef, - * or a CFArray of them. - * eContentType : contentType for inner EncapsulatedData. - * detachedContent : when true, do not include the signed data in the message. - * signedAttributes : Specifies which standard signed attributes are to be - * included in the message. - * content : raw content to be signed and/or encrypted. - * - * Output - * ------ - * encodedContent : the result of the encoding. - * - * NOTE: This function is deprecated in Mac OS X 10.7 and later; - * please use CMSEncodeContent() instead. - */ -OSStatus CMSEncode( - CFTypeRef __nullable signers, - CFTypeRef __nullable recipients, - const CSSM_OID * __nullable eContentType, - Boolean detachedContent, - CMSSignedAttributes signedAttributes, - const void * content, - size_t contentLen, - CFDataRef * __nonnull CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ - API_DEPRECATED_WITH_REPLACEMENT("CMSEncodeContent", macos(10.5, 10.7)) API_UNAVAILABLE(ios); - - -/* - * High-level, one-shot encoder function. - * - * Inputs (all except for content optional, though at least one - * of {signers, recipients} must be non-NULL) - * ------------------------------------------------------------ - * signers : signer identities. Either a SecIdentityRef, or a - * CFArray of them. - * recipients : recipient certificates. Either a SecCertificateRef, - * or a CFArray of them. - * eContentTypeOID : contentType OID for inner EncapsulatedData, e.g.: - * CFSTR("1.2.840.113549.1.7.1") - * detachedContent : when true, do not include the signed data in the message. - * signedAttributes : Specifies which standard signed attributes are to be - * included in the message. - * content : raw content to be signed and/or encrypted. - * - * Output - * ------ - * encodedContent : the result of the encoding. - */ -OSStatus CMSEncodeContent( - CFTypeRef __nullable signers, - CFTypeRef __nullable recipients, - CFTypeRef __nullable eContentTypeOID, - Boolean detachedContent, - CMSSignedAttributes signedAttributes, - const void *content, - size_t contentLen, - CFDataRef * __nullable CF_RETURNS_RETAINED encodedContentOut) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); - -OSStatus CMSEncoderCopySignerTimestamp( - CMSEncoderRef cmsEncoder, - size_t signerIndex, /* usually 0 */ - CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_NA); - -OSStatus CMSEncoderCopySignerTimestampWithPolicy( - CMSEncoderRef cmsEncoder, - CFTypeRef __nullable timeStampPolicy, - size_t signerIndex, /* usually 0 */ - CFAbsoluteTime *timestamp) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_NA); - -CF_ASSUME_NONNULL_END - -#ifdef __cplusplus -} -#endif - -#endif /* _CMS_ENCODER_H_ */ - diff --git a/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj b/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj deleted file mode 100644 index 1517e57b..00000000 --- a/OSX/libsecurity_cms/libsecurity_cms.xcodeproj/project.pbxproj +++ /dev/null @@ -1,406 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 052C07EA09894ADA00E7641D /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 052C07E609894ADA00E7641D /* CMSDecoder.h */; settings = {ATTRIBUTES = (); }; }; - 052C07EB09894ADA00E7641D /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 052C07E709894ADA00E7641D /* CMSEncoder.h */; settings = {ATTRIBUTES = (); }; }; - 052C07EC09894ADA00E7641D /* CMSPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 052C07E809894ADA00E7641D /* CMSPrivate.h */; settings = {ATTRIBUTES = (); }; }; - 052C07ED09894ADA00E7641D /* CMSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 052C07E909894ADA00E7641D /* CMSUtils.h */; }; - 052C07F709894AF300E7641D /* CMSDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 052C07F409894AF300E7641D /* CMSDecoder.cpp */; }; - 052C07F809894AF300E7641D /* CMSEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 052C07F509894AF300E7641D /* CMSEncoder.cpp */; }; - 052C07F909894AF300E7641D /* CMSUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 052C07F609894AF300E7641D /* CMSUtils.cpp */; }; - 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 */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 052C07E609894ADA00E7641D /* CMSDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMSDecoder.h; sourceTree = ""; }; - 052C07E709894ADA00E7641D /* CMSEncoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMSEncoder.h; sourceTree = ""; }; - 052C07E809894ADA00E7641D /* CMSPrivate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMSPrivate.h; sourceTree = ""; }; - 052C07E909894ADA00E7641D /* CMSUtils.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CMSUtils.h; sourceTree = ""; }; - 052C07F409894AF300E7641D /* CMSDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMSDecoder.cpp; sourceTree = ""; }; - 052C07F509894AF300E7641D /* CMSEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMSEncoder.cpp; sourceTree = ""; }; - 052C07F609894AF300E7641D /* CMSUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CMSUtils.cpp; sourceTree = ""; }; - 18446177146E984400B12992 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = ""; }; - 18446178146E984400B12992 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = ""; }; - 18446179146E984400B12992 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = ""; }; - 1844617A146E984400B12992 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = ""; }; - 4CA1FEBE052A3C8100F22E42 /* libsecurity_cms.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecurity_cms.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "cms-trust-settings-test.c"; path = "regressions/cms-trust-settings-test.c"; sourceTree = ""; }; - 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; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 4CA1FEBB052A3C8100F22E42 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D4C334591BE2A2B100D8C1EF /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 18446176146E984400B12992 /* config */ = { - isa = PBXGroup; - children = ( - 18446177146E984400B12992 /* base.xcconfig */, - 18446178146E984400B12992 /* debug.xcconfig */, - 18446179146E984400B12992 /* lib.xcconfig */, - 1844617A146E984400B12992 /* release.xcconfig */, - ); - name = config; - path = ../config; - sourceTree = ""; - }; - 4C308388053237100028A8C6 /* lib */ = { - isa = PBXGroup; - children = ( - 052C07F409894AF300E7641D /* CMSDecoder.cpp */, - 052C07F509894AF300E7641D /* CMSEncoder.cpp */, - 052C07F609894AF300E7641D /* CMSUtils.cpp */, - 052C07E609894ADA00E7641D /* CMSDecoder.h */, - 052C07E709894ADA00E7641D /* CMSEncoder.h */, - 052C07E809894ADA00E7641D /* CMSPrivate.h */, - 052C07E909894ADA00E7641D /* CMSUtils.h */, - ); - path = lib; - sourceTree = ""; - }; - 4CA1FEA7052A3C3800F22E42 = { - isa = PBXGroup; - children = ( - D4C334561BE29F1700D8C1EF /* regressions */, - 4C308388053237100028A8C6 /* lib */, - 18446176146E984400B12992 /* config */, - 4CA1FEBF052A3C8100F22E42 /* Products */, - ); - sourceTree = ""; - }; - 4CA1FEBF052A3C8100F22E42 /* Products */ = { - isa = PBXGroup; - children = ( - 4CA1FEBE052A3C8100F22E42 /* libsecurity_cms.a */, - D4C3345C1BE2A2B100D8C1EF /* libsecurity_cms_regressions.a */, - ); - name = Products; - sourceTree = ""; - }; - D4C334561BE29F1700D8C1EF /* regressions */ = { - isa = PBXGroup; - children = ( - D4C334571BE29F5200D8C1EF /* cms_regressions.h */, - D43B9E7C1D064F0B00B9DDDA /* cms-trust-settings-test.c */, - D43B9E7D1D064F0B00B9DDDA /* cms-trust-settings-test.h */, - ); - name = regressions; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 4CA1FEB9052A3C8100F22E42 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 052C07ED09894ADA00E7641D /* CMSUtils.h in Headers */, - 052C07EC09894ADA00E7641D /* CMSPrivate.h in Headers */, - 052C07EA09894ADA00E7641D /* CMSDecoder.h in Headers */, - 052C07EB09894ADA00E7641D /* CMSEncoder.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D4C3345A1BE2A2B100D8C1EF /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - D43B9E7F1D064F0B00B9DDDA /* cms-trust-settings-test.h in Headers */, - D4C334601BE2A2B900D8C1EF /* cms_regressions.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 4CA1FEBD052A3C8100F22E42 /* libsecurity_cms */ = { - isa = PBXNativeTarget; - buildConfigurationList = C263E67509A2971B000043F1 /* Build configuration list for PBXNativeTarget "libsecurity_cms" */; - buildPhases = ( - 4CA1FEB9052A3C8100F22E42 /* Headers */, - 4CA1FEBA052A3C8100F22E42 /* Sources */, - 4CA1FEBB052A3C8100F22E42 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = libsecurity_cms; - productName = libsecurity_cms; - productReference = 4CA1FEBE052A3C8100F22E42 /* libsecurity_cms.a */; - productType = "com.apple.product-type.library.static"; - }; - D4C3345B1BE2A2B100D8C1EF /* libsecurity_cms_regressions */ = { - isa = PBXNativeTarget; - buildConfigurationList = D4C3345D1BE2A2B100D8C1EF /* Build configuration list for PBXNativeTarget "libsecurity_cms_regressions" */; - buildPhases = ( - D4C334581BE2A2B100D8C1EF /* Sources */, - D4C334591BE2A2B100D8C1EF /* Frameworks */, - D4C3345A1BE2A2B100D8C1EF /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = libsecurity_cms_regressions; - productName = libsecurity_cms_regressions; - productReference = D4C3345C1BE2A2B100D8C1EF /* libsecurity_cms_regressions.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 4CA1FEAB052A3C3800F22E42 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1000; - TargetAttributes = { - D4C3345B1BE2A2B100D8C1EF = { - CreatedOnToolsVersion = 7.1; - }; - }; - }; - buildConfigurationList = C263E67909A2971B000043F1 /* Build configuration list for PBXProject "libsecurity_cms" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - en, - ); - mainGroup = 4CA1FEA7052A3C3800F22E42; - productRefGroup = 4CA1FEBF052A3C8100F22E42 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 4CA1FEBD052A3C8100F22E42 /* libsecurity_cms */, - D4C3345B1BE2A2B100D8C1EF /* libsecurity_cms_regressions */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 4CA1FEBA052A3C8100F22E42 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 052C07F709894AF300E7641D /* CMSDecoder.cpp in Sources */, - 052C07F809894AF300E7641D /* CMSEncoder.cpp in Sources */, - 052C07F909894AF300E7641D /* CMSUtils.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - D4C334581BE2A2B100D8C1EF /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D43B9E7E1D064F0B00B9DDDA /* cms-trust-settings-test.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - C263E67609A2971B000043F1 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 18446178146E984400B12992 /* debug.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - COMBINE_HIDPI_IMAGES = YES; - }; - name = Debug; - }; - C263E67809A2971B000043F1 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 1844617A146E984400B12992 /* release.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - COMBINE_HIDPI_IMAGES = YES; - }; - name = Release; - }; - C263E67A09A2971B000043F1 /* Debug */ = { - isa = XCBuildConfiguration; - 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; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - ONLY_ACTIVE_ARCH = YES; - }; - name = Debug; - }; - C263E67C09A2971B000043F1 /* Release */ = { - isa = XCBuildConfiguration; - 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; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - }; - name = Release; - }; - D4C3345E1BE2A2B100D8C1EF /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - D4C3345F1BE2A2B100D8C1EF /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - "ARCHS[sdk=macosx*]" = "$(ARCHS_STANDARD)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNREACHABLE_CODE = YES; - CODE_SIGN_IDENTITY = "-"; - COMBINE_HIDPI_IMAGES = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - C263E67509A2971B000043F1 /* Build configuration list for PBXNativeTarget "libsecurity_cms" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C263E67609A2971B000043F1 /* Debug */, - C263E67809A2971B000043F1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C263E67909A2971B000043F1 /* Build configuration list for PBXProject "libsecurity_cms" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C263E67A09A2971B000043F1 /* Debug */, - C263E67C09A2971B000043F1 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D4C3345D1BE2A2B100D8C1EF /* Build configuration list for PBXNativeTarget "libsecurity_cms_regressions" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D4C3345E1BE2A2B100D8C1EF /* Debug */, - D4C3345F1BE2A2B100D8C1EF /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 4CA1FEAB052A3C3800F22E42 /* Project object */; -} diff --git a/OSX/libsecurity_cms/regressions/cms-trust-settings-test.c b/OSX/libsecurity_cms/regressions/cms-trust-settings-test.c index f15725af..99b457f6 100644 --- a/OSX/libsecurity_cms/regressions/cms-trust-settings-test.c +++ b/OSX/libsecurity_cms/regressions/cms-trust-settings-test.c @@ -21,6 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include #include #include @@ -38,6 +39,7 @@ #define kSystemLoginKeychainPath "/Library/Keychains/System.keychain" #include "regressions/test/testmore.h" +#include "cms_regressions.h" #include "cms-trust-settings-test.h" // See diff --git a/OSX/libsecurity_cms/regressions/cms-trust-settings-test.h b/OSX/libsecurity_cms/regressions/cms-trust-settings-test.h index 10f1021d..31e69a5c 100644 --- a/OSX/libsecurity_cms/regressions/cms-trust-settings-test.h +++ b/OSX/libsecurity_cms/regressions/cms-trust-settings-test.h @@ -26,8 +26,6 @@ #include -int cms_trust_settings_test(int argc, char *const *argv); - unsigned char _cert[] = { 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, diff --git a/OSX/libsecurity_cms/regressions/cms_regressions.h b/OSX/libsecurity_cms/regressions/cms_regressions.h index 11b0febe..3085f6e6 100644 --- a/OSX/libsecurity_cms/regressions/cms_regressions.h +++ b/OSX/libsecurity_cms/regressions/cms_regressions.h @@ -26,3 +26,5 @@ #include ONE_TEST(cms_trust_settings_test) +ONE_TEST(smime_cms_test) +ONE_TEST(cms_01_basic) diff --git a/OSX/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper.entitlements b/OSX/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper.entitlements new file mode 100644 index 00000000..b4e6a353 --- /dev/null +++ b/OSX/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.private.tcc.allow + + kTCCServiceSystemPolicyAllFiles + + + diff --git a/OSX/libsecurity_codesigning/lib/Code.cpp b/OSX/libsecurity_codesigning/lib/Code.cpp index 919ff0bc..712b2ff4 100644 --- a/OSX/libsecurity_codesigning/lib/Code.cpp +++ b/OSX/libsecurity_codesigning/lib/Code.cpp @@ -26,7 +26,6 @@ // #include "Code.h" #include "StaticCode.h" -#include #include "cskernel.h" #include #include @@ -207,8 +206,11 @@ void SecCode::checkValidity(SecCSFlags flags) // check my static state myDisk->validateNonResourceComponents(); // also validates the CodeDirectory - if (flags & kSecCSStrictValidate) + if (flags & kSecCSStrictValidate) { myDisk->diskRep()->strictValidate(myDisk->codeDirectory(), DiskRep::ToleratedErrors(), flags); + } else if (flags & kSecCSStrictValidateStructure) { + myDisk->diskRep()->strictValidateStructure(myDisk->codeDirectory(), DiskRep::ToleratedErrors(), flags); + } // check my own dynamic state SecCodeStatus dynamic_status = this->host()->getGuestStatus(this); diff --git a/OSX/libsecurity_codesigning/lib/RequirementKeywords.h b/OSX/libsecurity_codesigning/lib/RequirementKeywords.h index 55830e14..e0794ed3 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementKeywords.h +++ b/OSX/libsecurity_codesigning/lib/RequirementKeywords.h @@ -13,6 +13,7 @@ "cdhash", "platform", "notarized", + "legacy", "anchor", "apple", "generic", diff --git a/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp b/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp index 2de62d4f..d7f147c3 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp +++ b/OSX/libsecurity_codesigning/lib/RequirementLexer.cpp @@ -53,34 +53,35 @@ RequirementLexer::RequirementLexer(const antlr::LexerSharedInputState& state) void RequirementLexer::initLiterals() { - literals["certificate"] = 26; + literals["certificate"] = 27; literals["always"] = 15; literals["host"] = 6; literals["guest"] = 5; literals["cdhash"] = 20; - literals["entitlement"] = 30; + literals["entitlement"] = 31; literals["library"] = 8; - literals["timestamp"] = 52; + literals["timestamp"] = 53; + literals["legacy"] = 23; literals["never"] = 17; - literals["cert"] = 27; + literals["cert"] = 28; literals["plugin"] = 9; - literals["absent"] = 32; + literals["absent"] = 33; literals["or"] = 10; - literals["leaf"] = 44; - literals["info"] = 29; + literals["leaf"] = 45; + literals["info"] = 30; literals["designated"] = 7; - literals["apple"] = 24; - literals["trusted"] = 28; + literals["apple"] = 25; + literals["trusted"] = 29; literals["true"] = 16; literals["notarized"] = 22; literals["and"] = 11; - literals["root"] = 45; + literals["root"] = 46; literals["platform"] = 21; - literals["anchor"] = 23; + literals["anchor"] = 24; literals["false"] = 18; - literals["generic"] = 25; + literals["generic"] = 26; literals["identifier"] = 19; - literals["exists"] = 31; + literals["exists"] = 32; } antlr::RefToken RequirementLexer::nextToken() @@ -1134,22 +1135,22 @@ const antlr::BitSet RequirementLexer::_tokenSet_1(_tokenSet_1_data_,10); const unsigned long RequirementLexer::_tokenSet_2_data_[] = { 4294967295UL, 4294967291UL, 4026531839UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e -// 0x1f ! # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < +// 0x1f ! # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = const antlr::BitSet RequirementLexer::_tokenSet_2(_tokenSet_2_data_,16); const unsigned long RequirementLexer::_tokenSet_3_data_[] = { 4294966271UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xb 0xc 0xd 0xe 0xf 0x10 0x11 // 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e 0x1f -// ! \" # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < +// ! \" # $ % & \' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = const antlr::BitSet RequirementLexer::_tokenSet_3(_tokenSet_3_data_,16); const unsigned long RequirementLexer::_tokenSet_4_data_[] = { 4294967295UL, 4294934527UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e -// 0x1f ! \" # $ % & \' ( ) * + , - . 0 1 2 3 4 5 6 7 8 9 : ; < +// 0x1f ! \" # $ % & \' ( ) * + , - . 0 1 2 3 4 5 6 7 8 9 : ; < = const antlr::BitSet RequirementLexer::_tokenSet_4(_tokenSet_4_data_,16); const unsigned long RequirementLexer::_tokenSet_5_data_[] = { 4294967295UL, 4294966271UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967295UL, 4294967292UL, 2097151UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL }; // 0x0 0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 0x9 0xa 0xb 0xc 0xd 0xe 0xf 0x10 // 0x11 0x12 0x13 0x14 0x15 0x16 0x17 0x18 0x19 0x1a 0x1b 0x1c 0x1d 0x1e -// 0x1f ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < +// 0x1f ! \" # $ % & \' ( ) + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = const antlr::BitSet RequirementLexer::_tokenSet_5(_tokenSet_5_data_,16); ANTLR_END_NAMESPACE diff --git a/OSX/libsecurity_codesigning/lib/RequirementParser.cpp b/OSX/libsecurity_codesigning/lib/RequirementParser.cpp index 02887a62..28b891eb 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParser.cpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParser.cpp @@ -149,6 +149,7 @@ BlobCore * RequirementParser::autosense() { case LITERAL_cdhash: case LITERAL_platform: case LITERAL_notarized: + case LITERAL_legacy: case LITERAL_anchor: case LITERAL_certificate: case LITERAL_cert: @@ -502,6 +503,12 @@ void RequirementParser::primary( maker.put(opNotarized); break; } + case LITERAL_legacy: + { + match(LITERAL_legacy); + maker.put(opLegacyDevID); + break; + } default: if ((LA(1) == LPAREN) && (_tokenSet_8.member(LA(2)))) { match(LPAREN); @@ -1310,6 +1317,7 @@ const char* RequirementParser::tokenNames[] = { "\"cdhash\"", "\"platform\"", "\"notarized\"", + "\"legacy\"", "\"anchor\"", "\"apple\"", "\"generic\"", @@ -1354,66 +1362,66 @@ 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, 524288UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_1_data_[] = { 992UL, 1048576UL, 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, 524288UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_3_data_[] = { 994UL, 1048576UL, 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_[] = { 268447730UL, 3097094UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_4_data_[] = { 536883186UL, 6194188UL, 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, 2621440UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_5_data_[] = { 9186UL, 5242880UL, 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, 2621440UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_6_data_[] = { 994UL, 5242880UL, 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, 2621440UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_7_data_[] = { 10210UL, 5242880UL, 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_[] = { 1828704256UL, 0UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_8_data_[] = { 3657420800UL, 0UL, 0UL, 0UL }; // LPAREN NOT "always" "true" "never" "false" "identifier" "cdhash" "platform" -// "notarized" "anchor" "certificate" "cert" "info" "entitlement" +// "notarized" "legacy" "anchor" "certificate" "cert" "info" "entitlement" const antlr::BitSet RequirementParser::_tokenSet_8(_tokenSet_8_data_,4); -const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 2621440UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_9_data_[] = { 12258UL, 5242880UL, 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, 538624UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_10_data_[] = { 0UL, 1077248UL, 0UL, 0UL }; // NEG "leaf" "root" INTEGER const antlr::BitSet RequirementParser::_tokenSet_10(_tokenSet_10_data_,4); -const unsigned long RequirementParser::_tokenSet_11_data_[] = { 0UL, 475654UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_11_data_[] = { 0UL, 951308UL, 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, 999424UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_12_data_[] = { 0UL, 1998848UL, 0UL, 0UL }; // HASHCONSTANT DOTKEY STRING PATHNAME INTEGER const antlr::BitSet RequirementParser::_tokenSet_12(_tokenSet_12_data_,4); -const unsigned long RequirementParser::_tokenSet_13_data_[] = { 268435456UL, 475654UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_13_data_[] = { 536870912UL, 951308UL, 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_[] = { 2147495906UL, 3096576UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_14_data_[] = { 12258UL, 6193153UL, 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_[] = { 2147495906UL, 2621943UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_15_data_[] = { 12258UL, 5243887UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // "exists" "absent" 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_[] = { 0UL, 229384UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_16_data_[] = { 0UL, 458768UL, 0UL, 0UL }; // STAR HEXCONSTANT DOTKEY STRING const antlr::BitSet RequirementParser::_tokenSet_16(_tokenSet_16_data_,4); -const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 2621448UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_17_data_[] = { 12258UL, 5242896UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // STAR INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_17(_tokenSet_17_data_,4); -const unsigned long RequirementParser::_tokenSet_18_data_[] = { 12258UL, 2622472UL, 0UL, 0UL }; +const unsigned long RequirementParser::_tokenSet_18_data_[] = { 12258UL, 5244944UL, 0UL, 0UL }; // EOF "guest" "host" "designated" "library" "plugin" "or" "and" RPAREN // STAR RBRACK INTEGER SEMI const antlr::BitSet RequirementParser::_tokenSet_18(_tokenSet_18_data_,4); diff --git a/OSX/libsecurity_codesigning/lib/RequirementParser.hpp b/OSX/libsecurity_codesigning/lib/RequirementParser.hpp index dddc90d7..7f8c1689 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParser.hpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParser.hpp @@ -110,10 +110,10 @@ protected: private: static const char* tokenNames[]; #ifndef NO_STATIC_CONSTS - static const int NUM_TOKENS = 61; + static const int NUM_TOKENS = 62; #else enum { - NUM_TOKENS = 61 + NUM_TOKENS = 62 }; #endif diff --git a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp index 7cf6171f..b95db8cb 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp +++ b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.hpp @@ -32,44 +32,45 @@ struct CUSTOM_API RequirementParserTokenTypes { LITERAL_cdhash = 20, LITERAL_platform = 21, 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, - LITERAL_absent = 32, - EQL = 33, - EQQL = 34, - STAR = 35, - SUBS = 36, - LESS = 37, - GT = 38, - LE = 39, - GE = 40, - LBRACK = 41, - RBRACK = 42, - NEG = 43, - LITERAL_leaf = 44, - LITERAL_root = 45, - HASHCONSTANT = 46, - HEXCONSTANT = 47, - DOTKEY = 48, - STRING = 49, - PATHNAME = 50, - INTEGER = 51, - LITERAL_timestamp = 52, - SEMI = 53, - IDENT = 54, - HEX = 55, - COMMA = 56, - WS = 57, - SHELLCOMMENT = 58, - C_COMMENT = 59, - CPP_COMMENT = 60, + LITERAL_legacy = 23, + LITERAL_anchor = 24, + LITERAL_apple = 25, + LITERAL_generic = 26, + LITERAL_certificate = 27, + LITERAL_cert = 28, + LITERAL_trusted = 29, + LITERAL_info = 30, + LITERAL_entitlement = 31, + LITERAL_exists = 32, + LITERAL_absent = 33, + EQL = 34, + EQQL = 35, + STAR = 36, + SUBS = 37, + LESS = 38, + GT = 39, + LE = 40, + GE = 41, + LBRACK = 42, + RBRACK = 43, + NEG = 44, + LITERAL_leaf = 45, + LITERAL_root = 46, + HASHCONSTANT = 47, + HEXCONSTANT = 48, + DOTKEY = 49, + STRING = 50, + PATHNAME = 51, + INTEGER = 52, + LITERAL_timestamp = 53, + SEMI = 54, + IDENT = 55, + HEX = 56, + COMMA = 57, + WS = 58, + SHELLCOMMENT = 59, + C_COMMENT = 60, + CPP_COMMENT = 61, NULL_TREE_LOOKAHEAD = 3 }; #ifdef __cplusplus diff --git a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt index 052076c1..b22ffae7 100644 --- a/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt +++ b/OSX/libsecurity_codesigning/lib/RequirementParserTokenTypes.txt @@ -19,41 +19,42 @@ LITERAL_identifier="identifier"=19 LITERAL_cdhash="cdhash"=20 LITERAL_platform="platform"=21 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 -LITERAL_absent="absent"=32 -EQL=33 -EQQL=34 -STAR=35 -SUBS=36 -LESS=37 -GT=38 -LE=39 -GE=40 -LBRACK=41 -RBRACK=42 -NEG=43 -LITERAL_leaf="leaf"=44 -LITERAL_root="root"=45 -HASHCONSTANT=46 -HEXCONSTANT=47 -DOTKEY=48 -STRING=49 -PATHNAME=50 -INTEGER=51 -LITERAL_timestamp="timestamp"=52 -SEMI=53 -IDENT=54 -HEX=55 -COMMA=56 -WS=57 -SHELLCOMMENT=58 -C_COMMENT=59 -CPP_COMMENT=60 +LITERAL_legacy="legacy"=23 +LITERAL_anchor="anchor"=24 +LITERAL_apple="apple"=25 +LITERAL_generic="generic"=26 +LITERAL_certificate="certificate"=27 +LITERAL_cert="cert"=28 +LITERAL_trusted="trusted"=29 +LITERAL_info="info"=30 +LITERAL_entitlement="entitlement"=31 +LITERAL_exists="exists"=32 +LITERAL_absent="absent"=33 +EQL=34 +EQQL=35 +STAR=36 +SUBS=37 +LESS=38 +GT=39 +LE=40 +GE=41 +LBRACK=42 +RBRACK=43 +NEG=44 +LITERAL_leaf="leaf"=45 +LITERAL_root="root"=46 +HASHCONSTANT=47 +HEXCONSTANT=48 +DOTKEY=49 +STRING=50 +PATHNAME=51 +INTEGER=52 +LITERAL_timestamp="timestamp"=53 +SEMI=54 +IDENT=55 +HEX=56 +COMMA=57 +WS=58 +SHELLCOMMENT=59 +C_COMMENT=60 +CPP_COMMENT=61 diff --git a/OSX/libsecurity_codesigning/lib/SecAssessment.cpp b/OSX/libsecurity_codesigning/lib/SecAssessment.cpp index 9c40ad59..1db11311 100644 --- a/OSX/libsecurity_codesigning/lib/SecAssessment.cpp +++ b/OSX/libsecurity_codesigning/lib/SecAssessment.cpp @@ -33,18 +33,9 @@ #include #include #include -#include using namespace CodeSigning; - -static void esp_do_check(const char *op, CFDictionaryRef dict) -{ - OSStatus result = __esp_check_ns(op, (void *)(CFDictionaryRef)dict); - if (result != noErr) - MacOSError::throwMe(result); -} - // // CF Objects // @@ -168,11 +159,6 @@ SecAssessmentRef SecAssessmentCreate(CFURLRef path, SYSPOLICY_ASSESS_API(cfString(path).c_str(), int(type), flags); try { - if (__esp_enabled() && (flags & kSecAssessmentFlagDirect)) { - CFTemp dict("{path=%O, flags=%d, context=%O, override=%d}", path, flags, context, overrideAssessment()); - esp_do_check("cs-assessment-evaluate", dict); - } - if (flags & kSecAssessmentFlagDirect) { // ask the engine right here to do its thing SYSPOLICY_ASSESS_LOCAL(); @@ -200,11 +186,6 @@ SecAssessmentRef SecAssessmentCreate(CFURLRef path, cfadd(result, "{%O=#F}", kSecAssessmentAssessmentVerdict); } - if (__esp_enabled() && (flags & kSecAssessmentFlagDirect)) { - CFTemp dict("{path=%O, flags=%d, context=%O, override=%d, result=%O}", path, flags, context, overrideAssessment(), (CFDictionaryRef)result); - __esp_notify_ns("cs-assessment-evaluate", (void *)(CFDictionaryRef)dict); - } - return new SecAssessment(path, type, result.yield()); END_CSAPI_ERRORS1(NULL) @@ -443,13 +424,6 @@ CFDictionaryRef SecAssessmentCopyUpdate(CFTypeRef target, } if (flags & kSecAssessmentFlagDirect) { - if (__esp_enabled()) { - CFTemp dict("{target=%O, flags=%d, context=%O}", target, flags, context); - OSStatus esp_result = __esp_check_ns("cs-assessment-update", (void *)(CFDictionaryRef)dict); - if (esp_result != noErr) - return NULL; - } - // ask the engine right here to do its thing result = gEngine().update(target, flags, ctx); } else { @@ -457,23 +431,18 @@ CFDictionaryRef SecAssessmentCopyUpdate(CFTypeRef target, result = xpcEngineUpdate(target, flags, ctx); } - if (__esp_enabled() && (flags & kSecAssessmentFlagDirect)) { - CFTemp dict("{target=%O, flags=%d, context=%O, outcome=%O}", target, flags, context, (CFDictionaryRef)result); - __esp_notify_ns("cs-assessment-update", (void *)(CFDictionaryRef)dict); - } - traceUpdate(target, context, result); return result.yield(); END_CSAPI_ERRORS1(NULL) } -static void +static Boolean 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); + return SecAssessmentUpdate(NULL, kSecCSDefaultFlags, ctx, errors); } @@ -485,9 +454,6 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e { BEGIN_CSAPI - CFTemp dict("{control=%O}", control); - esp_do_check("cs-assessment-control", dict); - if (CFEqual(control, CFSTR("ui-enable"))) { setAssessment(true); MessageTrace trace("com.apple.security.assessment.state", "enable"); @@ -528,11 +494,13 @@ Boolean SecAssessmentControl(CFStringRef control, void *arguments, CFErrorRef *e return true; } else if (CFEqual(control, CFSTR("ui-enable-notarized"))) { updateAuthority("Notarized Developer ID", true, errors); + updateAuthority("Unnotarized 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); + updateAuthority("Unnotarized Developer ID", false, errors); MessageTrace trace("com.apple.security.assessment.state", "disable-notarized"); trace.send("disable Notarized Developer ID approval"); return true; @@ -611,3 +579,13 @@ Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, END_CSAPI_ERRORS1(false) } +Boolean SecAssessmentLegacyCheck(CFDataRef hash, SecCSDigestAlgorithm hashType, CFStringRef teamID, CFErrorRef *errors) +{ + BEGIN_CSAPI + + xpcEngineLegacyCheck(hash, hashType, teamID); + return true; + + END_CSAPI_ERRORS1(false) +} + diff --git a/OSX/libsecurity_codesigning/lib/SecAssessment.h b/OSX/libsecurity_codesigning/lib/SecAssessment.h index 631b418c..59d5fa8d 100644 --- a/OSX/libsecurity_codesigning/lib/SecAssessment.h +++ b/OSX/libsecurity_codesigning/lib/SecAssessment.h @@ -321,10 +321,12 @@ typedef uint64_t SecAssessmentTicketFlags; enum { kSecAssessmentTicketFlagDefault = 0, // default behavior, offline check kSecAssessmentTicketFlagForceOnlineCheck = 1 << 0, // force an online check + kSecAssessmentTicketFlagLegacyListCheck = 1 << 1, // Check the DeveloperID Legacy list }; Boolean SecAssessmentTicketRegister(CFDataRef ticketData, CFErrorRef *errors); Boolean SecAssessmentRegisterPackageTicket(CFURLRef packageURL, CFErrorRef* errors) API_AVAILABLE(macos(10.14.6)); Boolean SecAssessmentTicketLookup(CFDataRef hash, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date, CFErrorRef *errors); +Boolean SecAssessmentLegacyCheck(CFDataRef hash, SecCSDigestAlgorithm hashType, CFStringRef teamID, CFErrorRef *errors); #ifdef __cplusplus } diff --git a/OSX/libsecurity_codesigning/lib/SecCode.cpp b/OSX/libsecurity_codesigning/lib/SecCode.cpp index dac2376c..2a494dc7 100644 --- a/OSX/libsecurity_codesigning/lib/SecCode.cpp +++ b/OSX/libsecurity_codesigning/lib/SecCode.cpp @@ -233,6 +233,7 @@ OSStatus SecCodeCheckValidityWithErrors(SecCodeRef codeRef, SecCSFlags flags, checkFlags(flags, kSecCSConsiderExpiration | kSecCSStrictValidate + | kSecCSStrictValidateStructure | kSecCSRestrictSidebandData | kSecCSEnforceRevocationChecks ); diff --git a/OSX/libsecurity_codesigning/lib/SecCode.h b/OSX/libsecurity_codesigning/lib/SecCode.h index 5ccfb170..aa53b5ac 100644 --- a/OSX/libsecurity_codesigning/lib/SecCode.h +++ b/OSX/libsecurity_codesigning/lib/SecCode.h @@ -51,9 +51,7 @@ CFTypeID SecCodeGetTypeID(void); Obtains a SecCode object for the code making the call. The calling code is determined in a way that is subject to modification over time, but obeys the following rules. If it is a UNIX process, its process id (pid) - is always used. If it is an active code host that has a dedicated guest, such a guest - is always preferred. If it is a host that has called SecHostSelectGuest, such selection - is considered until revoked. + is always used. @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior. @param self Upon successful return, contains a SecCodeRef representing the caller. diff --git a/OSX/libsecurity_codesigning/lib/SecCodeHost.cpp b/OSX/libsecurity_codesigning/lib/SecCodeHost.cpp index 7de4bf90..b678a71f 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodeHost.cpp +++ b/OSX/libsecurity_codesigning/lib/SecCodeHost.cpp @@ -33,32 +33,13 @@ using namespace CodeSigning; -// -// Munge a CFDictionary into a CssmData representing its plist -// -class DictData : public CFRef { -public: - DictData(CFDictionaryRef dict) : CFRef(makeCFData(dict)) { } - - operator CssmData() const - { - if (*this) - return CssmData::wrap(CFDataGetBytePtr(*this), CFDataGetLength(*this)); - else - return CssmData(); - } -}; - - OSStatus SecHostCreateGuest(SecGuestRef host, uint32_t status, CFURLRef path, CFDictionaryRef attributes, SecCSFlags flags, SecGuestRef *newGuest) { BEGIN_CSAPI - checkFlags(flags, kSecCSDedicatedHost | kSecCSGenerateGuestHash); - CodeSigning::Required(newGuest) = SecurityServer::ClientSession().createGuest(host, - status, cfString(path).c_str(), CssmData(), DictData(attributes), flags); + MacOSError::throwMe(errSecCSNotSupported); END_CSAPI } @@ -67,9 +48,8 @@ OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flag { BEGIN_CSAPI - checkFlags(flags); - SecurityServer::ClientSession().removeGuest(host, guest); - + MacOSError::throwMe(errSecCSNotSupported); + END_CSAPI } @@ -77,9 +57,8 @@ OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags) { BEGIN_CSAPI - checkFlags(flags); - SecurityServer::ClientSession().selectGuest(guestRef); - + MacOSError::throwMe(errSecCSNotSupported); + END_CSAPI } @@ -88,9 +67,8 @@ OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef *guestRef) { BEGIN_CSAPI - checkFlags(flags); - CodeSigning::Required(guestRef) = SecurityServer::ClientSession().selectedGuest(); - + MacOSError::throwMe(errSecCSNotSupported); + END_CSAPI } @@ -100,9 +78,8 @@ OSStatus SecHostSetGuestStatus(SecGuestRef guestRef, { BEGIN_CSAPI - checkFlags(flags); - SecurityServer::ClientSession().setGuestStatus(guestRef, status, DictData(attributes)); - + MacOSError::throwMe(errSecCSNotSupported); + END_CSAPI } @@ -110,8 +87,7 @@ OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags) { BEGIN_CSAPI - checkFlags(flags); - SecurityServer::ClientSession().registerHosting(hostingPort, flags); - + MacOSError::throwMe(errSecCSNotSupported); + END_CSAPI } diff --git a/OSX/libsecurity_codesigning/lib/SecCodeHost.h b/OSX/libsecurity_codesigning/lib/SecCodeHost.h index 7e462af4..ea61aa24 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodeHost.h +++ b/OSX/libsecurity_codesigning/lib/SecCodeHost.h @@ -21,22 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -/*! - @header SecCodeHost - This header provides the hosting API for Code Signing. These are calls - that are (only) made by code that is hosting guests. - In the context of Code Signing, a Host is code that creates and manages other - codes from which it defends its own integrity. As part of that duty, it maintains - state for each of its children, and answers questions about them. - - A Host is externally represented by a SecCodeRef (it is a SecCode object). - So is a Guest. There is no specific API object to represent Hosts or Guests. - Within the Hosting API, guests are identified by simple numeric handles that - are unique and valid only in the context of their specific host. - - The functions in this API always apply to the Host making the API calls. - They cannot be used to (directly) interrogate another host. -*/ #ifndef _H_SECCODEHOST #define _H_SECCODEHOST @@ -48,87 +32,6 @@ extern "C" { CF_ASSUME_NONNULL_BEGIN -/*! - @header SecCodeHost - This header describes the Code Signing Hosting API. These are calls made - by code that wishes to become a Host in the Code Signing Host/Guest infrastructure. - Hosting allows the caller to establish separate, independent code identities - (SecCodeRefs) for parts of itself, usually because it is loading and managing - code in the form of scripts, plugins, etc. - - The Hosting API does not directly connect to the Code Signing Client APIs. - Certain calls in the client API will cause internal queries to hosts about their - guests. The Host side of these queries is managed through this API. The results - will eventually be delivered to client API callers in appropriate form. - - If code never calls any of the Hosting API functions, it is deemed to not have - guests and not act as a Host. This is the default and requires no action. - - Hosting operates in one of two modes, dynamic or proxy. Whichever mode is first - engaged prevails for the lifetime of the caller. There is no way to switch between - the two, and calling an API belonging to the opposite mode will fail. - - In dynamic hosting mode, the caller provides a Mach port that receives direct - queries about its guests. Dynamic mode is engaged by calling SecHostSetHostingPort. - - In proxy hosting mode, the caller provides information about its guests as - guests are created, removed, or change status. The system caches this information - and answers queries about guests from this pool of information. The caller is not - directly involved in answering such queries, and has no way to intervene. -*/ - - -/*! - @function SecHostCreateGuest - Create a new Guest and describe its initial properties. - - This call activates Hosting Proxy Mode. From here on, the system will record - guest information provided through SecHostCreateGuest, SecHostSetGuestStatus, and - SecHostRemoveGuest, and report hosting status to callers directly. This mode - is incompatible with dynamic host mode as established by a call to SecHostSetHostingPort. - - @param host Pass kSecNoGuest to create a guest of the process itself. - To create a guest of another guest (extending the hosting chain), pass the SecGuestRef - of the guest to act as the new guest's host. If host has a dedicated guest, - it will be deemed to be be the actual host, recursively. - @param status The Code Signing status word for the new guest. These are combinations - of the kSecCodeStatus* flags in . Note that the proxy will enforce - the rules for the stickiness of these bits. In particular, if you don't pass the - kSecCodeStatusValid bit during creation, your new guest will be born invalid and will - never have a valid identity. - @param path The canonical path to the guest's code on disk. This is the path you would - pass to SecStaticCodeCreateWithPath to make a static code object reference. You must - use an absolute path. - @param attributes An optional CFDictionaryRef containing attributes that can be used - to locate this particular guest among all of the caller's guests. The "canonical" - attribute is automatically added for the value of guestRef. If you pass NULL, - no other attributes are established for the guest. - While any key can be used in the attributes dictionary, the kSecGuestAttribute* constants - (in SecCode.h) are conventionally used here. - @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior, or - a combination of the flags defined below for special features. - @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in - CSCommon.h or certain other Security framework headers. - @param newGuest Upon successful creation of the new guest, the new SecGuestRef - that should be used to identify the new guest from here on. - - @constant kSecCSDedicatedHost Declares dedicated hosting for the given host. - In dedicated hosting, the host has exactly one guest (the one this call is - introducing), and the host will spend all of its time from here on running - that guest (or on its behalf). This declaration is irreversable for the lifetime - of the host. Note that this is a declaration about the given host, and is not - binding upon other hosts on either side of the hosting chain, though they in turn - may declare dedicated hosting if desired. - It is invalid to declare dedicated hosting if other guests have already been - introduced for this host, and it is invalid to introduce additional guests - for this host after this call. - @constant kSecCSGenerateGuestHash Ask the proxy to generate the binary identifier - (hash of CodeDirectory) from the copy on disk at the path given. This is not optimal - since an attacker with write access may be able to substitute a different copy just - in time, but it is convenient. For optimal security, the host should calculate the - hash from the loaded in-memory signature of its guest and pass the result as an - attribute with key kSecGuestAttributeHash. -*/ CF_ENUM(uint32_t) { kSecCSDedicatedHost = 1 << 0, kSecCSGenerateGuestHash = 1 << 1, @@ -136,104 +39,20 @@ CF_ENUM(uint32_t) { OSStatus SecHostCreateGuest(SecGuestRef host, uint32_t status, CFURLRef path, CFDictionaryRef __nullable attributes, - SecCSFlags flags, SecGuestRef * __nonnull newGuest); - - -/*! - @function SecHostRemoveGuest - Announce that the guest with the given guestRef has permanently disappeared. - It removes all memory of the guest from the hosting system. You cannot remove - a dedicated guest. - - @param host The SecGuestRef that was used to create guest. You cannot specify - a proximate host (host of a host) here. However, the substitution for dedicated - guests described for SecHostCreateGuest also takes place here. - @param guest The handle for a Guest previously created with SecHostCreateGuest - that has not previously been destroyed. This guest is to be destroyed now. - @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior. - @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in - CSCommon.h or certain other Security framework headers. -*/ -OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flags); - - -/*! - @function SecHostSelectGuest - Tell the Code Signing host subsystem that the calling thread will now act - on behalf of the given Guest. This must be a valid Guest previously created - with SecHostCreateGuest. - - @param guestRef The handle for a Guest previously created with SecHostCreateGuest - on whose behalf this thread will act from now on. This setting will be remembered - until it is changed (or the thread terminates). - To indicate that the thread will act on behalf of the Host itself (rather than - any Guest), pass kSecNoGuest. - @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior. - @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in - CSCommon.h or certain other Security framework headers. -*/ -OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags); - - -/*! - @function SecHostSelectedGuest - Retrieve the handle for the Guest currently selected for the calling thread. - - @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior. - @param guestRef Will be assigned the SecGuestRef currently in effect for - the calling thread. If no Guest is active on this thread (i.e. the thread - is acting for the Host), the return value is kSecNoGuest. - @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in - CSCommon.h or certain other Security framework headers. -*/ -OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef * __nonnull guestRef); - - -/*! - @function SecHostSetGuestStatus - Updates the status of a particular guest. - - @param guestRef The handle for a Guest previously created with SecHostCreateGuest - on whose behalf this thread will act from now on. This setting will be remembered - until it is changed (or the thread terminates). - @param status The new Code Signing status word for the guest. The proxy enforces - the restrictions on changes to guest status; in particular, the kSecCodeStatusValid bit can only - be cleared, and the kSecCodeStatusHard and kSecCodeStatusKill flags can only be set. Pass the previous - guest status to indicate that no change is desired. - @param attributes An optional dictionary containing attributes to be used to distinguish - this guest from all guests of the caller. If given, it completely replaces the attributes - specified earlier. If NULL, previously established attributes are retained. - @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior. - @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in - CSCommon.h or certain other Security framework headers. - */ + SecCSFlags flags, SecGuestRef * __nonnull newGuest) +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; +OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flags) +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; +OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags) +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; +OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef * __nonnull guestRef) +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; OSStatus SecHostSetGuestStatus(SecGuestRef guestRef, uint32_t status, CFDictionaryRef __nullable attributes, - SecCSFlags flags); - - -/*! - @function SecHostSetHostingPort - Tells the Code Signing Hosting subsystem that the calling code will directly respond - to hosting inquiries over the given port. - - This API should be the first hosting API call made. With it, the calling code takes - direct responsibility for answering questions about its guests using the hosting IPC - services. The SecHostCreateGuest, SecHostDestroyGuest and SecHostSetGuestStatus calls - are not valid after this. The SecHostSelectGuest and SecHostSelectedGuest calls will - still work, and will use whatever SecGuestRefs the caller has assigned in its internal - data structures. - - This call cannot be undone; once it is made, record-and-forward facilities are - disabled for the lifetime of the calling code. - - @param hostingPort A Mach message port with send rights. This port will be recorded - and handed to parties interested in querying the host about its children. - @param flags Optional flags. Pass kSecCSDefaultFlags for standard behavior. - @result Upon success, errSecSuccess. Upon error, an OSStatus value documented in - CSCommon.h or certain other Security framework headers. - */ -OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags); + SecCSFlags flags) + AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; +OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags) +AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_6; CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_codesigning/lib/SecCodeHostLib.c b/OSX/libsecurity_codesigning/lib/SecCodeHostLib.c deleted file mode 100644 index 44774523..00000000 --- a/OSX/libsecurity_codesigning/lib/SecCodeHostLib.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2007,2011 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 "SecCodeHost.h" -#include "SecCodeHostLib.h" -#include -#include -#include -#include - - -// -// Global state -// -mach_port_t gServerPort; -SecCSFlags gInitFlags; - - -// -// Framing macros and facilities -// -#define UCSP_ARGS gServerPort, mig_get_reply_port(), &securitydCreds, &rcode -#define ATTRDATA(attr) (void *)(attr), (attr) ? strlen((attr)) : 0 - -#define CALL(func) \ - security_token_t securitydCreds; \ - CSSM_RETURN rcode; \ - if (KERN_SUCCESS != func) \ - return errSecCSInternalError; \ - if (securitydCreds.val[0] != 0) \ - return CSSM_ERRCODE_VERIFICATION_FAILURE; \ - return rcode - - - -// -// Mandatory initialization call -// -OSStatus SecHostLibInit(SecCSFlags flags) -{ - if (gServerPort != MACH_PORT_NULL) // re-initialization attempt - return errSecCSInternalError; - - mach_port_t bootstrapPort; - if (KERN_SUCCESS != task_get_bootstrap_port(mach_task_self(), &bootstrapPort)) - return errSecCSInternalError; - static char serverName[BOOTSTRAP_MAX_NAME_LEN] = SECURITYSERVER_BOOTSTRAP_NAME; - if (KERN_SUCCESS != bootstrap_look_up(bootstrapPort, serverName, &gServerPort)) - return errSecCSInternalError; - - ClientSetupInfo info = { 0x1234, SSPROTOVERSION }; - CALL(ucsp_client_setup(UCSP_ARGS, mach_task_self(), info, "?:unspecified")); -} - - -// -// Guest creation. -// At this time, this ONLY supports the creation of (one) dedicated guest. -// -OSStatus SecHostLibCreateGuest(SecGuestRef host, - uint32_t status, const char *path, const char *attributeXML, - SecCSFlags flags, SecGuestRef *newGuest) -{ - return SecHostLibCreateGuest2(host, status, path, "", 0, attributeXML, flags, newGuest); -} - -OSStatus SecHostLibCreateGuest2(SecGuestRef host, - uint32_t status, const char *path, const void *cdhash, size_t cdhashLength, const char *attributeXML, - SecCSFlags flags, SecGuestRef *newGuest) -{ - if (flags != kSecCSDedicatedHost) - return errSecCSInvalidFlags; - - CALL(ucsp_client_createGuest(UCSP_ARGS, host, status, path, - (void *)cdhash, cdhashLength, ATTRDATA(attributeXML), flags, newGuest)); -} - - -// -// Update the status of a guest. -// -OSStatus SecHostLibSetGuestStatus(SecGuestRef guestRef, - uint32_t status, const char *attributeXML, - SecCSFlags flags) -{ - CALL(ucsp_client_setGuestStatus(UCSP_ARGS, guestRef, status, ATTRDATA(attributeXML))); -} - - -// -// Enable dynamic hosting mode. -// -OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags) -{ - CALL(ucsp_client_registerHosting(UCSP_ARGS, hostingPort, flags)); -} - - -// -// Helper for checked incorporation of code. -// -OSStatus SecHostLibCheckLoad(const char *path, SecRequirementType type) -{ - CALL(ucsp_client_helpCheckLoad(UCSP_ARGS, path, type)); -} diff --git a/OSX/libsecurity_codesigning/lib/SecCodeHostLib.h b/OSX/libsecurity_codesigning/lib/SecCodeHostLib.h deleted file mode 100644 index 3cceb306..00000000 --- a/OSX/libsecurity_codesigning/lib/SecCodeHostLib.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2007,2011 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 SecCodeHostLib - This header provides a subset of the hosting API for Code Signing. - This subset functionality is implemented as a static library written - entirely in C, and depends on nothing except the system library and the - C runtime. It is thus suitable to be used by low-level libraries and - other such system facilities. On the other hand, it does not provide the - full functionality of . - - This file is documented as a delta to , which - you should consult as a baseline. -*/ -#ifndef _H_SECCODEHOSTLIB -#define _H_SECCODEHOSTLIB - -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -/*! - @function SecHostLibInit - This function must be called first to use the SecCodeHostLib facility. - */ -OSStatus SecHostLibInit(SecCSFlags flags); - - -/*! - @function SecHostLibCreateGuest - This function declares a code host, engages hosting proxy services for it, - and creates a guest with given attributes and state. - - NOTE: This version of the function currently only supports dedicated hosting. - If you do not pass the kSecCSDedicatedHost flag, the call will fail. - */ -OSStatus SecHostLibCreateGuest(SecGuestRef host, - uint32_t status, const char *path, const char *attributeXML, - SecCSFlags flags, SecGuestRef *newGuest) DEPRECATED_ATTRIBUTE; - -OSStatus SecHostLibCreateGuest2(SecGuestRef host, - uint32_t status, const char *path, const void *cdhash, size_t cdhashLength, const char *attributeXML, - SecCSFlags flags, SecGuestRef *newGuest); - - -/*! - @function SecHostLibSetGuestStatus - This function can change the state or attributes (or both) of a given guest. - It performs all the work of SecHostSetGuestStatus. - */ -OSStatus SecHostLibSetGuestStatus(SecGuestRef guestRef, - uint32_t status, const char *attributeXML, - SecCSFlags flags); - - -/*! - @function SecHostLibSetHostingPort - Register a Mach port to receive hosting queries on. This enables (and locks) - dynamic hosting mode, and is incompatible with all proxy-mode calls. - You still must call SecHostLibInit first. - */ -OSStatus SecHostSetHostingPort(mach_port_t hostingPort, SecCSFlags flags); - - -/* - Functionality from SecCodeHost.h that is genuinely missing here: - -OSStatus SecHostRemoveGuest(SecGuestRef host, SecGuestRef guest, SecCSFlags flags); - -OSStatus SecHostSelectGuest(SecGuestRef guestRef, SecCSFlags flags); - -OSStatus SecHostSelectedGuest(SecCSFlags flags, SecGuestRef *guestRef); - -*/ - - -/*! - */ -OSStatus SecHostLibCheckLoad(const char *path, SecRequirementType type); - - -#ifdef __cplusplus -} -#endif - -#endif //_H_SECCODEHOSTLIB diff --git a/OSX/libsecurity_codesigning/lib/SecCodePriv.h b/OSX/libsecurity_codesigning/lib/SecCodePriv.h index 3bce444b..f4d8e2a7 100644 --- a/OSX/libsecurity_codesigning/lib/SecCodePriv.h +++ b/OSX/libsecurity_codesigning/lib/SecCodePriv.h @@ -145,7 +145,7 @@ OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef code, SecRequirementTyp */ OSStatus SecCodeCreateWithAuditToken(const audit_token_t *audit, SecCSFlags flags, SecCodeRef *process) - AVAILABLE_MAC_OS_X_VERSION_10_14_4_AND_LATER; + AVAILABLE_MAC_OS_X_VERSION_10_15_AND_LATER; /* Deprecated and unsafe, DO NOT USE. */ OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *process) @@ -220,6 +220,18 @@ CFDataRef SecCodeCopyComponent(SecCodeRef code, int slot, CFDataRef hash); */ OSStatus SecCodeValidateFileResource(SecStaticCodeRef code, CFStringRef relativePath, CFDataRef fileData, SecCSFlags flags); + +/* + @constant kSecCSStrictValidateStructure + A subset of the work kSecCSStrictValidate performs, omitting work that + is unnecessary on some platforms. Since the definition of what can be + omitted is in flux, and since we would like to remove that notion + entirely eventually, we makes this a private flag. + */ +CF_ENUM(uint32_t) { + kSecCSStrictValidateStructure = 1 << 13, +}; + #ifdef __cplusplus } #endif diff --git a/OSX/libsecurity_codesigning/lib/SecRequirement.cpp b/OSX/libsecurity_codesigning/lib/SecRequirement.cpp index 7c44fcf6..d89c9240 100644 --- a/OSX/libsecurity_codesigning/lib/SecRequirement.cpp +++ b/OSX/libsecurity_codesigning/lib/SecRequirement.cpp @@ -169,6 +169,8 @@ CFStringRef kSecRequirementKeyEntitlements = CFSTR("requirement:eval:entitlement CFStringRef kSecRequirementKeyIdentifier = CFSTR("requirement:eval:identifier"); CFStringRef kSecRequirementKeyPackageChecksum = CFSTR("requirement:eval:package_checksum"); CFStringRef kSecRequirementKeyChecksumAlgorithm = CFSTR("requirement:eval:package_checksum_algorithm"); +CFStringRef kSecRequirementKeySecureTimestamp = CFSTR("requirement:eval:secure_timestamp"); +CFStringRef kSecRequirementKeyTeamIdentifier = CFSTR("requirement:eval:team_identifier"); OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef, CFArrayRef certificateChain, CFDictionaryRef context, @@ -188,6 +190,12 @@ OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef, } } + const char *teamID = NULL; + if (context && CFDictionaryGetValue(context, kSecRequirementKeyTeamIdentifier)) { + CFStringRef str = (CFStringRef)CFDictionaryGetValue(context, kSecRequirementKeyTeamIdentifier); + teamID = CFStringGetCStringPtr(str, kCFStringEncodingUTF8); + } + Requirement::Context ctx(certificateChain, // mandatory context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyInfoPlist)) : NULL, context ? CFDictionaryRef(CFDictionaryGetValue(context, kSecRequirementKeyEntitlements)) : NULL, @@ -196,7 +204,9 @@ OSStatus SecRequirementEvaluate(SecRequirementRef requirementRef, NULL, // can't specify a CodeDirectory here context ? CFDataRef(CFDictionaryGetValue(context, kSecRequirementKeyPackageChecksum)) : NULL, checksumAlgorithm, - false // can't get forced platform this way + false, // can't get forced platform this way + context ? CFDateRef(CFDictionaryGetValue(context, kSecRequirementKeySecureTimestamp)) : NULL, + teamID ); req->validate(ctx); diff --git a/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h b/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h index 5e80a93b..cc7ebddb 100644 --- a/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h +++ b/OSX/libsecurity_codesigning/lib/SecRequirementPriv.h @@ -166,6 +166,9 @@ extern CFStringRef kSecRequirementKeyEntitlements; extern CFStringRef kSecRequirementKeyIdentifier; extern CFStringRef kSecRequirementKeyPackageChecksum; extern CFStringRef kSecRequirementKeyChecksumAlgorithm; +extern CFStringRef kSecRequirementKeySecureTimestamp; +extern CFStringRef kSecRequirementKeyTeamIdentifier; + /*! @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 5ee92582..b240b4b8 100644 --- a/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp +++ b/OSX/libsecurity_codesigning/lib/SecStaticCode.cpp @@ -117,6 +117,7 @@ OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, Se | kSecCSNoNetworkAccess | kSecCSCheckNestedCode | kSecCSStrictValidate + | kSecCSStrictValidateStructure | kSecCSRestrictSidebandData | kSecCSCheckGatekeeperArchitectures | kSecCSRestrictSymlinks diff --git a/OSX/libsecurity_codesigning/lib/StaticCode.cpp b/OSX/libsecurity_codesigning/lib/StaticCode.cpp index 5b8b37ae..2d5a3e90 100644 --- a/OSX/libsecurity_codesigning/lib/StaticCode.cpp +++ b/OSX/libsecurity_codesigning/lib/StaticCode.cpp @@ -358,6 +358,9 @@ void SecStaticCode::resetValidity() mGotResourceBase = false; mTrust = NULL; mCertChain = NULL; + mNotarizationChecked = false; + mStaplingChecked = false; + mNotarizationDate = NAN; #if TARGET_OS_OSX mEvalDetails = NULL; #endif @@ -1897,6 +1900,10 @@ const Requirement *SecStaticCode::defaultDesignatedRequirement() #if TARGET_OS_OSX // full signature: Gin up full context and let DRMaker do its thing validateDirectory(); // need the cert chain + CFRef secureTimestamp; + if (CFAbsoluteTime time = this->signingTimestamp()) { + secureTimestamp.take(CFDateCreate(NULL, time)); + } Requirement::Context context(this->certificates(), this->infoDictionary(), this->entitlements(), @@ -1904,7 +1911,9 @@ const Requirement *SecStaticCode::defaultDesignatedRequirement() this->codeDirectory(), NULL, kSecCodeSignatureNoHash, - false + false, + secureTimestamp, + this->teamID() ); return DRMaker(context).make(); #else @@ -1937,7 +1946,15 @@ 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(), NULL, kSecCodeSignatureNoHash, mRep->appleInternalForcePlatform()), failure); + CFRef secureTimestamp; + if (CFAbsoluteTime time = this->signingTimestamp()) { + secureTimestamp.take(CFDateCreate(NULL, time)); + } + result = req->validates(Requirement::Context(mCertChain, infoDictionary(), entitlements(), + codeDirectory()->identifier(), codeDirectory(), + NULL, kSecCodeSignatureNoHash, mRep->appleInternalForcePlatform(), + secureTimestamp, teamID()), + failure); return result; } @@ -2235,9 +2252,12 @@ void SecStaticCode::staticValidate(SecCSFlags flags, const SecRequirement *req) this->validateResources(flags); // perform strict validation if desired - if (flags & kSecCSStrictValidate) + if (flags & kSecCSStrictValidate) { mRep->strictValidate(codeDirectory(), mTolerateErrors, mValidationFlags); reportProgress(); + } else if (flags & kSecCSStrictValidateStructure) { + mRep->strictValidateStructure(codeDirectory(), mTolerateErrors, mValidationFlags); + } // allow monitor intervention if (CFRef veto = reportEvent(CFSTR("validated"), NULL)) { @@ -2323,7 +2343,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, NULL, kSecCodeSignatureNoHash, false); + Requirement::Context ctx(certs, NULL, NULL, "", NULL, NULL, kSecCodeSignatureNoHash, false, NULL, ""); return req->requirement()->validates(ctx); } diff --git a/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp b/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp index 1aa31968..7c490970 100644 --- a/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp +++ b/OSX/libsecurity_codesigning/lib/bundlediskrep.cpp @@ -717,6 +717,14 @@ size_t BundleDiskRep::pageSize(const SigningContext &ctx) // Takes an array of CFNumbers of errors to tolerate. // void BundleDiskRep::strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) +{ + strictValidateStructure(cd, tolerated, flags); + + // now strict-check the main executable (which won't be an app-like object) + mExecRep->strictValidate(cd, tolerated, flags & ~kSecCSRestrictToAppLike); +} + +void BundleDiskRep::strictValidateStructure(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) { // scan our metadirectory (_CodeSignature) for unwanted guests if (!(flags & kSecCSQuickCheck)) @@ -736,9 +744,6 @@ void BundleDiskRep::strictValidate(const CodeDirectory* cd, const ToleratedError if (!mAppLike) if (tolerated.find(kSecCSRestrictToAppLike) == tolerated.end()) MacOSError::throwMe(errSecCSNotAppLike); - - // now strict-check the main executable (which won't be an app-like object) - mExecRep->strictValidate(cd, tolerated, flags & ~kSecCSRestrictToAppLike); } void BundleDiskRep::recordStrictError(OSStatus error) diff --git a/OSX/libsecurity_codesigning/lib/bundlediskrep.h b/OSX/libsecurity_codesigning/lib/bundlediskrep.h index 13335055..af3e40e2 100644 --- a/OSX/libsecurity_codesigning/lib/bundlediskrep.h +++ b/OSX/libsecurity_codesigning/lib/bundlediskrep.h @@ -88,6 +88,7 @@ public: size_t pageSize(const SigningContext &ctx); void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); + void strictValidateStructure(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); CFArrayRef allowedResourceOmissions(); void registerStapledTicket(); diff --git a/OSX/libsecurity_codesigning/lib/csgeneric.cpp b/OSX/libsecurity_codesigning/lib/csgeneric.cpp deleted file mode 100644 index e691c4b7..00000000 --- a/OSX/libsecurity_codesigning/lib/csgeneric.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2006-2007,2011-2012 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@ - */ - -// -// csgeneric - generic Code representative -// -#include "csgeneric.h" -#include "cs.h" -#include "StaticCode.h" -#include -#include - -namespace Security { -namespace CodeSigning { - -using MachPlusPlus::Port; - - -// -// Common call-out code for cshosting RPC service -// -#define CALL(host, name, args...) \ - OSStatus result; \ - if (cshosting_client_ ## name (host, mig_get_reply_port(), &result, args)) \ - MacOSError::throwMe(errSecCSNotAHost); \ - MacOSError::check(result); - - -// -// Construct a running process representation -// -GenericCode::GenericCode(SecCode *host, SecGuestRef guestRef) - : SecCode(host), mGuestRef(guestRef) -{ -} - - -// -// Identify a guest by attribute set, and return a new GenericCode representing it. -// This uses cshosting RPCs to ask the host (or its proxy). -// -SecCode *GenericCode::locateGuest(CFDictionaryRef attributes) -{ - if (Port host = hostingPort()) { - CFRef attrData; - void *attrPtr = NULL; size_t attrLength = 0; - if (attributes) { - attrData.take(CFPropertyListCreateXMLData(NULL, attributes)); - attrPtr = (void *)CFDataGetBytePtr(attrData); - attrLength = CFDataGetLength(attrData); - } - GuestChain guestPath; - mach_msg_type_number_t guestPathLength; - mach_port_t subport; - CALL(host, findGuest, guestRef(), attrPtr, (mach_msg_type_number_t)attrLength, - &guestPath, &guestPathLength, &subport); - CODESIGN_GUEST_LOCATE_GENERIC(this, guestPath, guestPathLength, subport); - SecPointer code = this; - for (unsigned n = 0; n < guestPathLength; n++) - code = new GenericCode(code, guestPath[n]); - return code.yield(); - } else - return NULL; // not found, no error -} - - -// -// Identify a guest by returning its StaticCode and running CodeDirectory hash. -// This uses cshosting RPCs to ask the host (or its proxy). -// -SecStaticCode *GenericCode::identifyGuest(SecCode *guest, CFDataRef *cdhashOut) -{ - if (GenericCode *iguest = dynamic_cast(guest)) { - FilePathOut path; - CFRef cdhash; - CFDictionary attributes(errSecCSHostProtocolInvalidAttribute); - identifyGuest(iguest->guestRef(), path, cdhash.aref(), attributes.aref()); - DiskRep::Context ctx; - if (CFNumberRef architecture = attributes.get(kSecGuestAttributeArchitecture)) { - cpu_type_t cpu = cfNumber(architecture); - if (CFNumberRef subarchitecture = attributes.get(kSecGuestAttributeSubarchitecture)) - ctx.arch = Architecture(cpu, cfNumber(subarchitecture)); - else - ctx.arch = Architecture(cpu); - } - SecPointer code = new GenericStaticCode(DiskRep::bestGuess(path, &ctx)); - CODESIGN_GUEST_IDENTIFY_GENERIC(iguest, iguest->guestRef(), code); - if (cdhash) { - CODESIGN_GUEST_CDHASH_GENERIC(iguest, (void *)CFDataGetBytePtr(cdhash), (unsigned)CFDataGetLength(cdhash)); - *cdhashOut = cdhash.yield(); - } - return code.yield(); - } else - MacOSError::throwMe(errSecCSNotAHost); -} - -// helper to drive the identifyGuest hosting IPC and return results as CF objects -void GenericCode::identifyGuest(SecGuestRef guest, char *path, CFDataRef &cdhash, CFDictionaryRef &attributes) -{ - if (Port host = hostingPort()) { - HashDataOut hash; - uint32_t hashLength; - XMLBlobOut attr; - uint32_t attrLength; - CALL(host, identifyGuest, guest, path, hash, &hashLength, &attr, &attrLength); - if (hashLength) - cdhash = makeCFData(hash, hashLength); - if (attrLength) { - CFRef attrData = makeCFData(attr, attrLength); - attributes = makeCFDictionaryFrom(attrData); -#if ROSETTA_TEST_HACK - CFMutableDictionaryRef hattr = makeCFMutableDictionary(attributes); - CFDictionaryAddValue(hattr, kSecGuestAttributeArchitecture, CFTempNumber(CPU_TYPE_POWERPC)); - CFRelease(attributes); - attributes = hattr; -#endif - } - } else - MacOSError::throwMe(errSecCSNotAHost); -} - - -// -// Get the Code Signing Status Word for a Code. -// This uses cshosting RPCs to ask the host (or its proxy). -// -SecCodeStatus GenericCode::getGuestStatus(SecCode *guest) -{ - if (Port host = hostingPort()) { - uint32_t status; - CALL(host, guestStatus, safe_cast(guest)->guestRef(), &status); - return status; - } else - MacOSError::throwMe(errSecCSNotAHost); -} - - -// -// Status changes are transmitted through the cshosting RPCs. -// -void GenericCode::changeGuestStatus(SecCode *iguest, SecCodeStatusOperation operation, CFDictionaryRef arguments) -{ - if (/* GenericCode *guest = */dynamic_cast(iguest)) - switch (operation) { - case kSecCodeOperationNull: - break; - case kSecCodeOperationInvalidate: - case kSecCodeOperationSetHard: - case kSecCodeOperationSetKill: - MacOSError::throwMe(errSecCSUnimplemented); - default: - MacOSError::throwMe(errSecCSUnimplemented); - } - else - MacOSError::throwMe(errSecCSNoSuchCode); -} - - -// -// Return the Hosting Port for this Code. -// May return MACH_PORT_NULL if the code is not a code host. -// Throws if we can't get the hosting port for some reason (and can't positively -// determine that there is none). -// -// Note that we do NOT cache negative outcomes. Being a host is a dynamic property, -// and this Code may not have commenced hosting operations yet. For non- (or not-yet-)hosts -// we simply return NULL. -// -Port GenericCode::hostingPort() -{ - if (!mHostingPort) { - if (staticCode()->codeDirectory()->flags & kSecCodeSignatureHost) { - mHostingPort = getHostingPort(); - CODESIGN_GUEST_HOSTINGPORT(this, mHostingPort); - } - } - return mHostingPort; -} - - -// -// A pure GenericHost has no idea where to get a hosting port from. -// This method must be overridden to get one. -// However, we do handle a contiguous chain of GenericCodes by deferring -// to our next-higher host for it. -// -mach_port_t GenericCode::getHostingPort() -{ - if (GenericCode *genericHost = dynamic_cast(host())) - return genericHost->getHostingPort(); - else - MacOSError::throwMe(errSecCSNotAHost); -} - - -} // CodeSigning -} // Security diff --git a/OSX/libsecurity_codesigning/lib/csgeneric.h b/OSX/libsecurity_codesigning/lib/csgeneric.h deleted file mode 100644 index 0a3a1729..00000000 --- a/OSX/libsecurity_codesigning/lib/csgeneric.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2006,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@ - */ - -// -// csgeneric - generic Code representative -// -#ifndef _H_CSGENERIC -#define _H_CSGENERIC - -#include "Code.h" -#include -#include -#include - -namespace Security { -namespace CodeSigning { - - -// -// A SecCode that represents "generic" code. -// Generic code is, well, generic. It doesn't have any real resources that define it, -// and so it's defined, de facto, by its host. The Code Signing subsystem has no special -// knowledge as to its nature, and so it just asks the host about everything. The asking -// is done via the cshosting Mach RPC protocol, which can be implemented by hosts in whichever -// way they find reasonable. This code doesn't care, as long as someone is answering. -// -// It is all right to subclass GenericCode to inherit access to the cshosting protocol. -// -class GenericCode : public SecCode { -public: - GenericCode(SecCode *host, SecGuestRef guestRef = kSecNoGuest); - - SecCode *locateGuest(CFDictionaryRef attributes); - SecStaticCode *identifyGuest(SecCode *guest, CFDataRef *cdhash); - SecCodeStatus getGuestStatus(SecCode *guest); - void changeGuestStatus(SecCode *guest, SecCodeStatusOperation operation, CFDictionaryRef arguments); - - SecGuestRef guestRef() const { return mGuestRef; } - -protected: - MachPlusPlus::Port hostingPort(); - virtual mach_port_t getHostingPort(); - -private: - void identifyGuest(SecGuestRef guest, char *path, CFDataRef &cdhash, CFDictionaryRef &attributes); - -private: - MachPlusPlus::Port mHostingPort; // cached hosting port for this Code - SecGuestRef mGuestRef; // guest reference -}; - - -// -// We don't need a GenericCode variant of SecStaticCode -// -typedef SecStaticCode GenericStaticCode; - - -} // end namespace CodeSigning -} // end namespace Security - -#endif // !_H_CSGENERIC diff --git a/OSX/libsecurity_codesigning/lib/csprocess.cpp b/OSX/libsecurity_codesigning/lib/csprocess.cpp index 26ee9005..80b58521 100644 --- a/OSX/libsecurity_codesigning/lib/csprocess.cpp +++ b/OSX/libsecurity_codesigning/lib/csprocess.cpp @@ -37,7 +37,7 @@ namespace CodeSigning { // Construct a running process representation // ProcessCode::ProcessCode(pid_t pid, const audit_token_t* token, PidDiskRep *pidDiskRep /*= NULL */) - : GenericCode(KernelCode::active()), mPid(pid), mPidBased(pidDiskRep) + : SecCode(KernelCode::active()), mPid(pid), mPidBased(pidDiskRep) { if (token) mAudit = new audit_token_t(*token); @@ -46,12 +46,6 @@ ProcessCode::ProcessCode(pid_t pid, const audit_token_t* token, PidDiskRep *pidD } -mach_port_t ProcessCode::getHostingPort() -{ - return SecurityServer::ClientSession().hostingPort(pid()); -} - - int ProcessCode::csops(unsigned int ops, void *addr, size_t size) { // pass pid and audit token both if we have it, or just the pid if we don't diff --git a/OSX/libsecurity_codesigning/lib/csprocess.h b/OSX/libsecurity_codesigning/lib/csprocess.h index f26e1c78..b0a370e4 100644 --- a/OSX/libsecurity_codesigning/lib/csprocess.h +++ b/OSX/libsecurity_codesigning/lib/csprocess.h @@ -27,7 +27,7 @@ #ifndef _H_CSPROCESS #define _H_CSPROCESS -#include "csgeneric.h" +#include "Code.h" #include "StaticCode.h" #include "piddiskrep.h" #include @@ -40,10 +40,7 @@ namespace CodeSigning { // A SecCode that represents a running UNIX process. // Processes are identified by pid and audit token. // -// ProcessCode inherits GenericCode's access to the cshosting Mach protocol to -// deal with guests. -// -class ProcessCode : public GenericCode { +class ProcessCode : public SecCode { public: ProcessCode(pid_t pid, const audit_token_t* token, PidDiskRep *pidDiskRep = NULL); ~ProcessCode() throw () { delete mAudit; } @@ -55,8 +52,6 @@ public: int csops(unsigned int ops, void *addr, size_t size); - mach_port_t getHostingPort(); - private: pid_t mPid; audit_token_t* mAudit; diff --git a/OSX/libsecurity_codesigning/lib/diskrep.h b/OSX/libsecurity_codesigning/lib/diskrep.h index 069cb95f..1f1a10c5 100644 --- a/OSX/libsecurity_codesigning/lib/diskrep.h +++ b/OSX/libsecurity_codesigning/lib/diskrep.h @@ -92,6 +92,7 @@ public: virtual size_t pageSize(const SigningContext &ctx); // default main executable page size [infinite, i.e. no paging] virtual void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); // perform strict validation + virtual void strictValidateStructure(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) { }; // perform structural strict validation virtual CFArrayRef allowedResourceOmissions(); // allowed (default) resource omission rules virtual bool appleInternalForcePlatform() const {return false;}; @@ -274,6 +275,7 @@ public: size_t pageSize(const SigningContext &ctx) { return mOriginal->pageSize(ctx); } void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) { mOriginal->strictValidate(cd, tolerated, flags); } + void strictValidateStructure(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) { mOriginal->strictValidateStructure(cd, tolerated, flags); } CFArrayRef allowedResourceOmissions() { return mOriginal->allowedResourceOmissions(); } private: diff --git a/OSX/libsecurity_codesigning/lib/evaluationmanager.cpp b/OSX/libsecurity_codesigning/lib/evaluationmanager.cpp index 2332ca0e..22317b56 100644 --- a/OSX/libsecurity_codesigning/lib/evaluationmanager.cpp +++ b/OSX/libsecurity_codesigning/lib/evaluationmanager.cpp @@ -196,7 +196,8 @@ void EvaluationTask::performEvaluation(SecAssessmentFlags flags, CFDictionaryRef dispatch_semaphore_t startLock = dispatch_semaphore_create(0); // create the assessment block - dispatch_async(mWorkQueue, dispatch_block_create_with_qos_class(DISPATCH_BLOCK_ENFORCE_QOS_CLASS, QOS_CLASS_UTILITY, 0, ^{ + dispatch_block_t assessmentBlock = + dispatch_block_create_with_qos_class(DISPATCH_BLOCK_ENFORCE_QOS_CLASS, QOS_CLASS_UTILITY, 0, ^{ // signal that the assessment is ready to start dispatch_semaphore_signal(startLock); @@ -236,8 +237,12 @@ void EvaluationTask::performEvaluation(SecAssessmentFlags flags, CFDictionaryRef } catch(...) { mExceptionToRethrow = std::current_exception(); } - - })); + + }); + assert(assessmentBlock != NULL); + + dispatch_async(mWorkQueue, assessmentBlock); + Block_release(assessmentBlock); // wait for the assessment to start dispatch_semaphore_wait(startLock, DISPATCH_TIME_FOREVER); @@ -300,12 +305,19 @@ void EvaluationTask::waitForCompletion(SecAssessmentFlags flags, CFMutableDictio // wait for the assessment to complete; our wait block will queue up behind // the assessment and the copy its results - dispatch_sync(mWorkQueue, dispatch_block_create_with_qos_class (DISPATCH_BLOCK_ENFORCE_QOS_CLASS, qos_class, 0, ^{ - // copy the class result back to the caller - cfDictionaryApplyBlock(mResult.get(), ^(const void *key, const void *value){ - CFDictionaryAddValue(result, key, value); - }); - })); + dispatch_block_t wait_block = dispatch_block_create_with_qos_class + (DISPATCH_BLOCK_ENFORCE_QOS_CLASS, + qos_class, 0, + ^{ + // copy the class result back to the caller + cfDictionaryApplyBlock(mResult.get(), + ^(const void *key, const void *value){ + CFDictionaryAddValue(result, key, value); + }); + }); + assert(wait_block != NULL); + dispatch_sync(mWorkQueue, wait_block); + Block_release(wait_block); } diff --git a/OSX/libsecurity_codesigning/lib/legacydevid.cpp b/OSX/libsecurity_codesigning/lib/legacydevid.cpp new file mode 100644 index 00000000..239d73e4 --- /dev/null +++ b/OSX/libsecurity_codesigning/lib/legacydevid.cpp @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2019 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 "legacydevid.h" +#include "SecAssessment.h" +#include "requirement.h" + +#include + +namespace Security { +namespace CodeSigning { + +static const CFStringRef kLegacyPolicyPreferenceDomain = CFSTR("com.apple.security.syspolicy"); +static const CFStringRef kLegacyPolicyAccountCreationCutOff = CFSTR("AccountCreationCutOffDate"); +static const CFStringRef kLegacyPolicySecureTimestampCutOff = CFSTR("SecureTimestampCutOffDate"); +static const CFAbsoluteTime kLegacyPolicyAccountCreationDefaultCutOff = 576374400.0; // seconds from January 1, 2001 to April 7, 2019 GMT +static const CFAbsoluteTime kLegacyPolicySecureTimestampDefaultCutOff = 581040000.0; // seconds from January 1, 2001 to June 1, 2019 GMT + +static CFDateRef +copyCutOffDate(const CFStringRef key, CFAbsoluteTime defaultCutoff) +{ + CFDateRef defaultDate = CFDateCreate(NULL, defaultCutoff); + CFDateRef outputDate = defaultDate; + CFDateRef prefDate = NULL; + + CFTypeRef prefVal = (CFDateRef)CFPreferencesCopyValue(key, + kLegacyPolicyPreferenceDomain, + kCFPreferencesCurrentUser, + kCFPreferencesAnyHost); + if (prefVal && CFGetTypeID(prefVal) == CFDateGetTypeID()) { + prefDate = (CFDateRef)prefVal; + } + + if (prefDate) { + CFComparisonResult res = CFDateCompare(defaultDate, prefDate, NULL); + if (res > 0) { + outputDate = prefDate; + } + } + + CFRetain(outputDate); + + if (prefVal) { + CFRelease(prefVal); + } + if (defaultDate) { + CFRelease(defaultDate); + } + return outputDate; +} + +bool +meetsDeveloperIDLegacyAllowedPolicy(const Requirement::Context *context) +{ + CFRef cd; + CFRef error; + CFRef teamID; + bool meets_legacy_policy = false; + SecCSDigestAlgorithm hashType = kSecCodeSignatureNoHash; + SecCertificateRef cert = NULL; + CFAbsoluteTime accountCreationTime = 0.0; + + if (context == NULL) { + meets_legacy_policy = false; + goto lb_exit; + } + + // First check account creation date in certs + // An account creation date after the cut off must be notarized so it fails the legacy policy. + // No account creation date or an account creation date before the cut off requires additional checking + cert = context->cert(Requirement::leafCert); + if (SecCertificateGetDeveloperIDDate(cert, &accountCreationTime, &error.aref())) { + //There is an account creation date + CFRef accountCreationDate = CFDateCreate(NULL, accountCreationTime); + CFRef accountCreationCutoffDate = copyCutOffDate(kLegacyPolicyAccountCreationCutOff, + kLegacyPolicyAccountCreationDefaultCutOff); + secinfo("meetsDeveloperIDLegacyAllowedPolicy", "Account Creation Date Cutoff: %@", accountCreationCutoffDate.get()); + secinfo("meetsDeveloperIDLegacyAllowedPolicy", "Account Creation date: %@", accountCreationDate.get()); + + CFComparisonResult res = CFDateCompare(accountCreationDate, accountCreationCutoffDate, NULL); + if (res >= 0) { + // The account was created on or after our cut off so it doesn't meet legacy policy + meets_legacy_policy = false; + secinfo("meetsDeveloperIDLegacyAllowedPolicy", "Account creation date %@ is after cut-off %@", accountCreationDate.get(), accountCreationCutoffDate.get()); + goto lb_exit; + } + // Account creation date before the cut off means we fall through + } else { + CFIndex errorCode = CFErrorGetCode(error); + if (errorCode != errSecMissingRequiredExtension) { + secerror("Unexpected error checking account creation date: %ld", errorCode); + meets_legacy_policy = false; + goto lb_exit; + } + // there was no account creation date so fall through + } + + // Next check secure time stamp + if (context->secureTimestamp) { + CFRef secureTimestampCutoffDate = copyCutOffDate(kLegacyPolicySecureTimestampCutOff, + kLegacyPolicySecureTimestampDefaultCutOff); + secinfo("meetsDeveloperIDLegacyAllowedPolicy", "Secure Timestamp Cutoff Date cutoff: %@", secureTimestampCutoffDate.get()); + secinfo("meetsDevleoperIDLegacyAllowedPolicy", "Secure Timestamp: %@", context->secureTimestamp); + CFComparisonResult res = CFDateCompare(context->secureTimestamp, secureTimestampCutoffDate, NULL); + if (res >= 0) { + // Secure timestamp is on or after the cut of so it doesn't meet legacy policy + meets_legacy_policy = false; + secinfo("meetsDeveloperIDLegacyAllowedPolicy", "Secure timestamp %@ is after cut-off %@", context->secureTimestamp, secureTimestampCutoffDate.get()); + } else { + // Secure timestamp is before the cut off so we meet the legacy policy + meets_legacy_policy = true; + } + } + + if (!meets_legacy_policy) { + // Just check against the legacy lists, both by hash and team ID. + 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 the legacy lists + meets_legacy_policy = false; + goto lb_exit; + } + + if (context->teamIdentifier) { + teamID.take(CFStringCreateWithCString(kCFAllocatorDefault, context->teamIdentifier, kCFStringEncodingUTF8)); + } + + secnotice("legacy_list", "checking the legacy list for %d, %@, %@", hashType, cd.get(), teamID.get()); + #if TARGET_OS_OSX + if (SecAssessmentLegacyCheck(cd, hashType, teamID, &error.aref())) { + meets_legacy_policy = true; + } else { + meets_legacy_policy = false; + if (error.get() != NULL) { + secerror("Error checking with notarization daemon: %ld", CFErrorGetCode(error)); + } + } + #endif + } +lb_exit: + secnotice("legacy_list", "meetsDeveloperIDLegacyAllowedPolicy = %d", meets_legacy_policy); + return meets_legacy_policy; +} + +} +} diff --git a/OSX/libsecurity_codesigning/lib/legacydevid.h b/OSX/libsecurity_codesigning/lib/legacydevid.h new file mode 100644 index 00000000..0c1d6b26 --- /dev/null +++ b/OSX/libsecurity_codesigning/lib/legacydevid.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 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_LEGACYLIST +#define H_LEGACYLIST + +#include +#include "requirement.h" + +namespace Security { +namespace CodeSigning { + +bool meetsDeveloperIDLegacyAllowedPolicy(const Requirement::Context *context); + +} // end namespace CodeSigning +} // end namespace Security + +#endif /* H_LEGACYLIST */ diff --git a/OSX/libsecurity_codesigning/lib/notarization.cpp b/OSX/libsecurity_codesigning/lib/notarization.cpp index 91a2c15f..fa75c0d0 100644 --- a/OSX/libsecurity_codesigning/lib/notarization.cpp +++ b/OSX/libsecurity_codesigning/lib/notarization.cpp @@ -22,7 +22,7 @@ */ #include "SecAssessment.h" #include "notarization.h" -#include "unix++.h" +#include typedef struct __attribute__((packed)) _package_trailer { uint8_t magic[4]; diff --git a/OSX/libsecurity_codesigning/lib/policydb.cpp b/OSX/libsecurity_codesigning/lib/policydb.cpp index bfe213e5..92d9cfa2 100644 --- a/OSX/libsecurity_codesigning/lib/policydb.cpp +++ b/OSX/libsecurity_codesigning/lib/policydb.cpp @@ -360,11 +360,55 @@ void PolicyDatabase::upgradeDatabase() migrateReq(this, 3, "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"); }); - // Add simpleFeatureNoTransaction for going from the requirements create above, to add secure timestamps in requirements, here before the commit + simpleFeatureNoTransaction("legacy_devid_v2", ^{ + auto migrateReq = [](auto db, int type, string oldreq, string newreq) { + const string legacy = + " and legacy"; + + SQLite::Statement update(*db, "UPDATE OR IGNORE authority " + "SET requirement = :newreq " + "WHERE requirement = :oldreq " + " AND type = :type " + " AND label = 'Developer ID'"); + update.bind(":oldreq") = oldreq; + update.bind(":type") = type; + update.bind(":newreq") = newreq; + update.execute(); + }; + + // App handling has moved to the sunfish path. The legacy keyword won't work well for apps because we don't collect nested code hashes to whitelist them. + migrateReq(this, 2, + "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 (certificate leaf[timestamp.1.2.840.113635.100.6.1.33] absent or certificate leaf[timestamp.1.2.840.113635.100.6.1.33] < timestamp \"20190408000000Z\")", + "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 legacy"); + migrateReq(this, 3, + "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 (certificate leaf[timestamp.1.2.840.113635.100.6.1.33] absent or certificate leaf[timestamp.1.2.840.113635.100.6.1.33] < timestamp \"20190408000000Z\")", + "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 legacy"); + }); + + simpleFeatureNoTransaction("unnotarized_without_timestamp", ^{ + auto migrateReq = [](auto db, int type, string req) { + const string to_remove = + " and (certificate leaf[timestamp.1.2.840.113635.100.6.1.33] exists and " + "certificate leaf[timestamp.1.2.840.113635.100.6.1.33] >= timestamp \"20190408000000Z\")"; + + SQLite::Statement update(*db, "UPDATE OR IGNORE authority " + "SET requirement = :newreq " + "WHERE requirement = :oldreq " + " AND type = :type " + " AND label = 'Unnotarized Developer ID'"); + update.bind(":oldreq") = req + to_remove; + update.bind(":type") = type; + update.bind(":newreq") = req; + update.execute(); + }; + + migrateReq(this, kAuthorityInstall, "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])"); + migrateReq(this, kAuthorityOpenDoc, "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"); + }); devIdRequirementUpgrades.commit(); } - + simpleFeature("notarized_documents", ^{ SQLite::Statement addNotarizedDocs(*this, "INSERT INTO authority (type, allow, flags, priority, label, requirement) " @@ -372,6 +416,20 @@ void PolicyDatabase::upgradeDatabase() " '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')"); addNotarizedDocs.execute(); }); + + simpleFeature("notarization_priority_fix", ^{ + auto migrateReq = [](auto db, string label, float priority) { + SQLite::Statement update(*db, + "UPDATE OR IGNORE authority " + "SET priority = :newpriority " + "WHERE label = :label"); + update.bind(":newpriority") = priority; + update.bind(":label") = label; + update.execute(); + }; + migrateReq(this, "Developer ID", 4.0); + migrateReq(this, "Unnotarized Developer ID", 0.0); + }); } diff --git a/OSX/libsecurity_codesigning/lib/policyengine.cpp b/OSX/libsecurity_codesigning/lib/policyengine.cpp index f3436493..a2993716 100644 --- a/OSX/libsecurity_codesigning/lib/policyengine.cpp +++ b/OSX/libsecurity_codesigning/lib/policyengine.cpp @@ -45,11 +45,6 @@ #include "SecCodePriv.h" #undef check // Macro! Yech. -extern "C" { -#include -} - - namespace Security { namespace CodeSigning { @@ -64,7 +59,6 @@ enum { static void authorizeUpdate(SecAssessmentFlags flags, CFDictionaryRef context); -static bool codeInvalidityExceptions(SecStaticCodeRef code, CFMutableDictionaryRef result); static CFTypeRef installerPolicy() CF_RETURNS_RETAINED; @@ -403,15 +397,7 @@ void PolicyEngine::evaluateCode(CFURLRef path, AuthorityType type, SecAssessment // deal with a very special case (broken 10.6/10.7 Applet bundles) OSStatus rc = SecStaticCodeCheckValidity(code, validationFlags | kSecCSBasicValidateOnly, NULL); if (rc == errSecCSSignatureFailed) { - if (!codeInvalidityExceptions(code, result)) { // invalidly signed, no exceptions -> error - if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED()) - SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, false); - MacOSError::throwMe(rc); - } - // recognized exception - treat as unsigned - if (SYSPOLICY_ASSESS_OUTCOME_BROKEN_ENABLED()) - SYSPOLICY_ASSESS_OUTCOME_BROKEN(cfString(path).c_str(), type, true); - rc = errSecCSUnsigned; + MacOSError::throwMe(rc); } // ad-hoc sign unsigned code @@ -586,6 +572,7 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi CFRef policy = installerPolicy(); CFRef trust; CFRef checksum; + CFRef teamID; CFRef requirementContext = makeCFMutableDictionary(); MacOSError::check(SecTrustCreateWithCertificates(certs, policy, &trust.aref())); // MacOSError::check(SecTrustSetAnchorCertificates(trust, cfEmptyArray())); // no anchors @@ -623,10 +610,22 @@ void PolicyEngine::evaluateInstall(CFURLRef path, SecAssessmentFlags flags, CFDi MacOSError::throwMe(errSecCSRevokedNotarization); } + // Extract a team identifier from the certificates. This isn't validated and could be spoofed, + // but since the 'legacy' keyword is only used in addition to the Developer ID requirement, + // this is still stafe for now. + SecCertificateRef leaf = SecCertificateRef(CFArrayGetValueAtIndex(certs, 0)); + CFRef orgUnits = SecCertificateCopyOrganizationalUnit(leaf); + if (orgUnits.get() && CFArrayGetCount(orgUnits) == 1) { + teamID = (CFStringRef)CFArrayGetValueAtIndex(orgUnits, 0); + } + // 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 (teamID.get()) { + cfadd(requirementContext, "{%O=%O}", kSecRequirementKeyTeamIdentifier, teamID.get()); + } if (!isnan(notarizationDate)) { CFRef date = CFDateCreate(NULL, notarizationDate); @@ -1187,17 +1186,6 @@ void PolicyEngine::normalizeTarget(CFRef &target, AuthorityType type, } MacOSError::check(rc); case errSecCSSignatureFailed: - // recover certain cases of broken signatures (well, try) - if (codeInvalidityExceptions(code, NULL)) { - // Ad-hoc sign the code in place (requiring a writable subject). This requires root privileges. - CFRef signer; - CFTemp arguments("{%O=#N}", kSecCodeSignerIdentity); - MacOSError::check(SecCodeSignerCreate(arguments, kSecCSSignOpaque, &signer.aref())); - MacOSError::check(SecCodeSignerAddSignature(signer, code, kSecCSDefaultFlags)); - MacOSError::check(SecCodeCopyDesignatedRequirement(code, kSecCSDefaultFlags, (SecRequirementRef *)&target.aref())); - break; - } - MacOSError::check(rc); default: MacOSError::check(rc); } @@ -1217,28 +1205,5 @@ void PolicyEngine::normalizeTarget(CFRef &target, AuthorityType type, } } - -// -// Process special overrides for invalidly signed code. -// This is the (hopefully minimal) concessions we make to keep hurting our customers -// for our own prior mistakes... -// -static bool codeInvalidityExceptions(SecStaticCodeRef code, CFMutableDictionaryRef result) -{ - CFRef info; - MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref())); - if (CFURLRef executable = CFURLRef(CFDictionaryGetValue(info, kSecCodeInfoMainExecutable))) { - SInt32 error; - if (OSAIsRecognizedExecutableURL(executable, &error)) { - if (result) - CFDictionaryAddValue(result, - kSecAssessmentAssessmentAuthorityOverride, CFSTR("ignoring known invalid applet signature")); - return true; - } - } - return false; -} - - } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/reqdumper.cpp b/OSX/libsecurity_codesigning/lib/reqdumper.cpp index ea29bdfe..f0fc8dd5 100644 --- a/OSX/libsecurity_codesigning/lib/reqdumper.cpp +++ b/OSX/libsecurity_codesigning/lib/reqdumper.cpp @@ -248,6 +248,9 @@ void Dumper::expr(SyntaxLevel level) case opNotarized: print("notarized"); break; + case opLegacyDevID: + print("legacy"); + 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 4ea2c53a..4ff17212 100644 --- a/OSX/libsecurity_codesigning/lib/reqinterp.cpp +++ b/OSX/libsecurity_codesigning/lib/reqinterp.cpp @@ -36,6 +36,7 @@ #include #include "csutilities.h" #include "notarization.h" +#include "legacydevid.h" namespace Security { namespace CodeSigning { @@ -191,6 +192,10 @@ bool Requirement::Interpreter::eval(int depth) { return isNotarized(mContext); } + case opLegacyDevID: + { + return meetsDeveloperIDLegacyAllowedPolicy(mContext); + } default: // opcode not recognized - handle generically if possible, fail otherwise if (op & (opGenericFalse | opGenericSkip)) { diff --git a/OSX/libsecurity_codesigning/lib/requirement.h b/OSX/libsecurity_codesigning/lib/requirement.h index 4bb59398..747128be 100644 --- a/OSX/libsecurity_codesigning/lib/requirement.h +++ b/OSX/libsecurity_codesigning/lib/requirement.h @@ -100,13 +100,15 @@ private: class Requirement::Context { protected: Context() - : certs(NULL), info(NULL), entitlements(NULL), identifier(""), directory(NULL), packageChecksum(NULL), packageAlgorithm(kSecCodeSignatureNoHash), forcePlatform(false) { } + : certs(NULL), info(NULL), entitlements(NULL), identifier(""), directory(NULL), packageChecksum(NULL), packageAlgorithm(kSecCodeSignatureNoHash), forcePlatform(false), secureTimestamp(NULL) { } public: Context(CFArrayRef certChain, CFDictionaryRef infoDict, CFDictionaryRef entitlementDict, const std::string &ident, - const CodeDirectory *dir, CFDataRef packageChecksum, SecCSDigestAlgorithm packageAlgorithm, bool force_platform) + const CodeDirectory *dir, CFDataRef packageChecksum, SecCSDigestAlgorithm packageAlgorithm, bool force_platform, CFDateRef secure_timestamp, + const char *teamID) : certs(certChain), info(infoDict), entitlements(entitlementDict), identifier(ident), directory(dir), - packageChecksum(packageChecksum), packageAlgorithm(packageAlgorithm), forcePlatform(force_platform) { } + packageChecksum(packageChecksum), packageAlgorithm(packageAlgorithm), forcePlatform(force_platform), + secureTimestamp(secure_timestamp), teamIdentifier(teamID) { } CFArrayRef certs; // certificate chain CFDictionaryRef info; // Info.plist @@ -116,6 +118,8 @@ public: CFDataRef packageChecksum; // package checksum SecCSDigestAlgorithm packageAlgorithm; // package checksum algorithm bool forcePlatform; + CFDateRef secureTimestamp; + const char *teamIdentifier; // team identifier 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) @@ -167,6 +171,7 @@ enum ExprOp { opPlatform, // platform constraint [integer] opNotarized, // has a developer id+ ticket opCertFieldDate, // extension value as timestamp [cert index; field name; match suffix] + opLegacyDevID, // meets legacy (pre-notarization required) policy exprOpCount // (total opcode count in use) }; diff --git a/OSX/libsecurity_codesigning/lib/resources.cpp b/OSX/libsecurity_codesigning/lib/resources.cpp index 2c8a43ef..221e2984 100644 --- a/OSX/libsecurity_codesigning/lib/resources.cpp +++ b/OSX/libsecurity_codesigning/lib/resources.cpp @@ -138,10 +138,15 @@ static bool findStringEndingNoCase(const char *path, const char * end) void ResourceBuilder::scan(Scanner next) { bool first = true; - + while (FTSENT *ent = fts_read(mFTS)) { static const char ds_store[] = ".DS_Store"; - const char *relpath = ent->fts_path + mRoot.size() + 1; // skip prefix + "/" + const char *relpath = ent->fts_path + mRoot.size(); // skip prefix + + if (strlen(relpath) > 0) { + relpath += 1; // skip "/" + } + std::string rp; if (mRelBase != mRoot) { assert(mRelBase == mRoot + "/Contents"); @@ -183,7 +188,7 @@ void ResourceBuilder::scan(Scanner next) secinfo("rdirenum", "entering %s", ent->fts_path); GKBIS_Num_dirs++; - if (!first) { // skip root directory (relpath invalid) + if (!first) { // skip root directory if (Rule *rule = findRule(relpath)) { if (rule->flags & nested) { if (strchr(ent->fts_name, '.')) { // nested, has extension -> treat as nested bundle diff --git a/OSX/libsecurity_codesigning/lib/signer.cpp b/OSX/libsecurity_codesigning/lib/signer.cpp index b5f07c40..89279238 100644 --- a/OSX/libsecurity_codesigning/lib/signer.cpp +++ b/OSX/libsecurity_codesigning/lib/signer.cpp @@ -787,7 +787,7 @@ CFDataRef SecCodeSigner::Signer::signCodeDirectory(const CodeDirectory *cd, // generate CMS signature CFRef cms; MacOSError::check(CMSEncoderCreate(&cms.aref())); - MacOSError::check(CMSEncoderSetCertificateChainMode(cms, kCMSCertificateChainWithRoot)); + MacOSError::check(CMSEncoderSetCertificateChainMode(cms, kCMSCertificateChainWithRootOrFail)); CMSEncoderAddSigners(cms, state.mSigner); CMSEncoderSetSignerAlgorithm(cms, kCMSEncoderDigestAlgorithmSHA256); MacOSError::check(CMSEncoderSetHasDetachedContent(cms, true)); diff --git a/OSX/libsecurity_codesigning/lib/xar++.cpp b/OSX/libsecurity_codesigning/lib/xar++.cpp index 97ae714f..86941d97 100644 --- a/OSX/libsecurity_codesigning/lib/xar++.cpp +++ b/OSX/libsecurity_codesigning/lib/xar++.cpp @@ -122,7 +122,9 @@ CFDataRef Xar::createPackageChecksum() return NULL; } - return makeCFData(data, length); + // xar_signature_copy_signed_data returns malloc'd data that can be used without copying + // but must be free'd properly later. + return makeCFDataMalloc(data, length); } SecCSDigestAlgorithm Xar::checksumDigestAlgorithm() diff --git a/OSX/libsecurity_codesigning/lib/xpcengine.cpp b/OSX/libsecurity_codesigning/lib/xpcengine.cpp index 63528615..d6e37ed9 100644 --- a/OSX/libsecurity_codesigning/lib/xpcengine.cpp +++ b/OSX/libsecurity_codesigning/lib/xpcengine.cpp @@ -28,6 +28,7 @@ #include #include +#include namespace Security { namespace CodeSigning { @@ -42,20 +43,27 @@ static const char serviceName[] = "com.apple.security.syspolicy"; static dispatch_once_t dispatchInit; // one-time init marker static xpc_connection_t service; // connection to spd static dispatch_queue_t queue; // dispatch queue for service - + +static map *feedbackBlocks; + static void init() { dispatch_once(&dispatchInit, ^void(void) { + feedbackBlocks = new map; const char *name = serviceName; if (const char *env = getenv("SYSPOLICYNAME")) name = env; - queue = dispatch_queue_create("spd-client", 0); + queue = dispatch_queue_create("spd-client", DISPATCH_QUEUE_SERIAL); service = xpc_connection_create_mach_service(name, queue, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); xpc_connection_set_event_handler(service, ^(xpc_object_t msg) { if (xpc_get_type(msg) == XPC_TYPE_DICTIONARY) { const char *function = xpc_dictionary_get_string(msg, "function"); - if (!strcmp(function, "progress")) { - doProgress(msg); + if (strcmp(function, "progress") == 0) { + try { + doProgress(msg); + } catch (...) { + Syslog::error("Discarding progress handler exception"); + } } } }); @@ -116,9 +124,7 @@ static void copyCFDictionary(const void *key, const void *value, void *ctx) if (CFGetTypeID(value) == CFURLGetTypeID()) { CFRef path = CFURLCopyFileSystemPath(CFURLRef(value), kCFURLPOSIXPathStyle); CFDictionaryAddValue(target, key, path); - } else if (CFEqual(key, kSecAssessmentContextKeyFeedback)) { - CFDictionaryAddValue(target, key, CFTempNumber(uint64_t(value))); - } else { + } else if (!CFEqual(key, kSecAssessmentContextKeyFeedback)) { CFDictionaryAddValue(target, key, value); } } @@ -149,13 +155,44 @@ void xpcEngineAssess(CFURLRef path, SecAssessmentFlags flags, CFDictionaryRef co xpc_dictionary_set_string(msg, "path", cfString(path).c_str()); xpc_dictionary_set_uint64(msg, "flags", flags); CFRef ctx = makeCFMutableDictionary(); - if (context) + if (context) { CFDictionaryApplyFunction(context, copyCFDictionary, ctx); + } + + SecAssessmentFeedback feedback = (SecAssessmentFeedback)CFDictionaryGetValue(context, kSecAssessmentContextKeyFeedback); + + /* Map the feedback block to a random number for tracking, because we don't want + * to send over a pointer. */ + uint64_t __block feedbackId = 0; + if (feedback) { + dispatch_sync(queue, ^{ + bool added = false; + while (!added) { + /* Simple sequence number would probably be sufficient, + * but making the id unpredictable is also cheap enough here. */ + arc4random_buf(&feedbackId, sizeof(uint64_t)); + if ((*feedbackBlocks)[feedbackId] == NULL /* extremely certain */) { + (*feedbackBlocks)[feedbackId] = feedback; + added = true; + } + } + }); + CFDictionaryAddValue(ctx, kSecAssessmentContextKeyFeedback, CFTempNumber(feedbackId)); + } + CFRef contextData = makeCFData(CFDictionaryRef(ctx)); xpc_dictionary_set_data(msg, "context", CFDataGetBytePtr(contextData), CFDataGetLength(contextData)); msg.send(); + /* Done, feedback block won't be called anymore, + * so remove the feedback mapping from the global map. */ + if (feedback) { + dispatch_sync(queue, ^{ + feedbackBlocks->erase(feedbackId); + }); + } + if (int64_t error = xpc_dictionary_get_int64(msg, "error")) MacOSError::throwMe((int)error); @@ -172,7 +209,18 @@ static void doProgress(xpc_object_t msg) uint64_t total = xpc_dictionary_get_uint64(msg, "total"); uint64_t ref = xpc_dictionary_get_uint64(msg, "ref"); const char *token = xpc_dictionary_get_string(msg, "token"); - SecAssessmentFeedback feedback = SecAssessmentFeedback(ref); + + SecAssessmentFeedback feedback = NULL; + + // doProgress is called on the queue, so no dispatch_sync here. + try { + feedback = feedbackBlocks->at(ref); + } catch (std::out_of_range) { + // Indicates that syspolicyd gave us something it shouldn't have. + Syslog::error("no feedback block registered with ID %lld", ref); + MacOSError::throwMe(errSecCSInternalError); + } + CFTemp info("{current=%d,total=%d}", current, total); Boolean proceed = feedback(kSecAssessmentFeedbackProgress, info); if (!proceed) { @@ -308,6 +356,24 @@ void xpcEngineTicketLookup(CFDataRef hashData, SecCSDigestAlgorithm hashType, Se } } +void xpcEngineLegacyCheck(CFDataRef hashData, SecCSDigestAlgorithm hashType, CFStringRef teamID) +{ + Message msg("legacy-check"); + xpc_dictionary_set_data(msg, "hashData", CFDataGetBytePtr(hashData), CFDataGetLength(hashData)); + xpc_dictionary_set_uint64(msg, "hashType", hashType); + + // There may not be a team id, so just leave it off if there isn't since xpc_dictionary_set_string + // will return a NULL if the value isn't provided. + if (teamID) { + xpc_dictionary_set_string(msg, "teamID", CFStringGetCStringPtr(teamID, kCFStringEncodingUTF8)); + } + + msg.send(); + + if (int64_t error = xpc_dictionary_get_int64(msg, "error")) { + MacOSError::throwMe((int)error); + } +} } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/lib/xpcengine.h b/OSX/libsecurity_codesigning/lib/xpcengine.h index 34b4a51a..a96b8d79 100644 --- a/OSX/libsecurity_codesigning/lib/xpcengine.h +++ b/OSX/libsecurity_codesigning/lib/xpcengine.h @@ -42,6 +42,7 @@ void xpcEngineCheckNotarized(CFBooleanRef* result); void xpcEngineTicketRegister(CFDataRef ticketData); void xpcEngineTicketLookup(CFDataRef hashData, SecCSDigestAlgorithm hashType, SecAssessmentTicketFlags flags, double *date); +void xpcEngineLegacyCheck(CFDataRef hashData, SecCSDigestAlgorithm hashType, CFStringRef teamID); } // end namespace CodeSigning } // end namespace Security diff --git a/OSX/libsecurity_codesigning/requirements.grammar b/OSX/libsecurity_codesigning/requirements.grammar index 953dd0a3..0481a85c 100644 --- a/OSX/libsecurity_codesigning/requirements.grammar +++ b/OSX/libsecurity_codesigning/requirements.grammar @@ -264,6 +264,8 @@ primary[Maker &maker] { maker.platform(ident); } | "notarized" { maker.put(opNotarized); } + | "legacy" + { maker.put(opLegacyDevID); } | LPAREN { string name; } name=identifierString RPAREN { maker.put(opNamedCode); maker.put(name); } ; diff --git a/OSX/libsecurity_cryptkit/ckutils/Makefile b/OSX/libsecurity_cryptkit/ckutils/Makefile deleted file mode 100644 index e0a50cb5..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# -# Top-level Makefile for ckutils. Allows build or clean -# of all directories in one swoop. -# -SHELL := /bin/zsh - -SUBDIRS= atomTime badsig blobtest cfileTest giantAsmBench giantBench giantDvt - -first: - @foreach i in $(SUBDIRS); \ - echo "=== Making $$i ==="; \ - cd $$i; \ - make || exit; \ - cd ..; \ - end - -clean: - @foreach i in $(SUBDIRS); \ - echo "=== Cleaning $$i ==="; \ - (cd $$i; make clean;) \ - end diff --git a/OSX/libsecurity_cryptkit/ckutils/Makefile.common b/OSX/libsecurity_cryptkit/ckutils/Makefile.common deleted file mode 100644 index 3f83691e..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/Makefile.common +++ /dev/null @@ -1,88 +0,0 @@ -# -# Common makefile fragment for ckutils. -# This is -included from project-specific Makefiles, assumed -# to be one directory down from this file. -# -# Standard binary locations. Assume LOCAL_BUILD_DIR in environment. -# - -LOCAL_BUILD ?= $(shell echo $(LOCAL_BUILD_DIR)) -ifeq "" "$(LOCAL_BUILD)" - LOCAL_BUILD = . -endif - -CRYPTKIT_SRC= ../../lib - -OFILES= $(CSOURCE:%.c=%.o) $(CPPSOURCE:%.cpp=%.o) -ALL_OFILES= $(OFILES) $(CRYPTKIT_LIB_BIN) - -# -# override with recursive make for e.g. debug build -# -VARIANT_SUFFIX= - -# -# override this with a recursive make to test minimal signature build -# -CRYPTKIT_CONFIG=-DCK_STANDALONE_BUILD - -# -# override with recursive make to link against other binary -# -CRYPTKIT_BINARY=CryptKit - -# -# Assume final load with cc, not ld -# -STD_LIBS= -l$(CRYPTKIT_BINARY)$(VARIANT_SUFFIX) -STD_LIBPATH=-L$(LOCAL_BUILD) -ALL_LIBS= $(STD_LIBS) $(PROJ_LIBS) -ALL_LIBPATHS= $(STD_LIBPATH) $(PROJ_LIBPATH) - -# -# Override this from the make command line to add e.g. -lMallocDebug -# -CMDLINE_LDFLAGS= - -STD_FRAMEWORKS= -STD_FRAME_PATH= -F$(LOCAL_BUILD) -F/usr/local/SecurityPieces/Frameworks - -# -ALL_LDFLAGS= $(CMDLINE_LDFLAGS) $(ALL_LIBS) $(ALL_LIBPATHS) $(STD_FRAME_PATH) $(PROJ_LDFLAGS) - -CC= /usr/bin/gcc - -ALL_FRAMEWORKS= $(STD_FRAMEWORKS) $(PROJ_FRAMEWORKS) - -# CryptKit headers accessed via -STD_INCLUDES= -I$(CRYPTKIT_SRC) -I.. -ALL_INCLUDES= $(STD_INCLUDES) $(PROJ_INCLUDES) -CINCLUDES= $(ALL_INCLUDES) - -WFLAGS= -Wno-four-char-constants -Wall -Werror -Wno-format -Wno-deprecated-declarations -STD_CFLAGS= -g $(VERBOSE) $(CRYPTKIT_CONFIG) - -ALL_CFLAGS= $(CINCLUDES) $(STD_CFLAGS) $(PROJ_CFLAGS) $(WFLAGS) $(STD_FRAME_PATH) - -BUILT_TARGET= $(EXECUTABLE) - -first: $(BUILT_TARGET) - -debug: - echo making debug - make "VARIANT_SUFFIX=_debug" - -smallsig: - make "CRYPTKIT_CONFIG=-DCK_MINIMUM_SIG_BUILD" "CRYPTKIT_BINARY=CryptKitSignature" - -clean: - rm -f $(OFILES) $(EXECUTABLE) $(OTHER_TO_CLEAN) - -$(BUILT_TARGET): $(ALL_OFILES) $(PROJ_DEPENDS) - cc -o $(BUILT_TARGET) $(ALL_OFILES) $(ALL_FRAMEWORKS) $(ALL_LDFLAGS) - -.c.o: - $(CC) $(ALL_CFLAGS) -c -o $*.o $< - -.cpp.o: - $(CC) $(ALL_CFLAGS) -c -o $*.o $< diff --git a/OSX/libsecurity_cryptkit/ckutils/atomTime/Makefile b/OSX/libsecurity_cryptkit/ckutils/atomTime/Makefile deleted file mode 100644 index cef23232..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/atomTime/Makefile +++ /dev/null @@ -1,53 +0,0 @@ -# name of executable to build -EXECUTABLE=atomTime -# C source (.c extension) -CSOURCE= atomTime.c - -SHELL := /bin/zsh - -# project-specific libraries, e.g., -lstdc++ -# -PROJ_LIBS= - -# -# Optional lib search paths -# -PROJ_LIBPATH= - -# -# choose one for cc -# -VERBOSE= -#VERBOSE=-v - -# -# non-standard frameworks (e.g., -framework foo) -# -PROJ_FRAMEWORKS= -framework CoreFoundation - -# -# Other files to remove at 'make clean' time -# -OTHER_TO_CLEAN= - -# -# project-specific includes, with leading -I -# -PROJ_INCLUDES= - -# -# Optional C flags (warnings, optimizations, etc.) -# -PROJ_CFLAGS=-O3 - -# -# Optional link flags (using cc, not ld) -# -PROJ_LDFLAGS= - -# -# Optional dependencies -# -PROJ_DEPENDS= - -include ../Makefile.common diff --git a/OSX/libsecurity_cryptkit/ckutils/atomTime/atomTime.c b/OSX/libsecurity_cryptkit/ckutils/atomTime/atomTime.c deleted file mode 100644 index d4eec127..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/atomTime/atomTime.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * atomTime.c - measure performance of mulg, gsquare, feemod, - * gshift{left,right}, elliptic, ellMulProj - */ - -#include "ckconfig.h" -#include "ckutilsPlatform.h" -#include "CryptKitSA.h" -#include "ckutilities.h" /* needs private headers */ -#include "curveParams.h" /* ditto */ -#include "falloc.h" /* ditto */ -#include "elliptic.h" -#include "ellipticProj.h" -#include -#include -#include - -/* default loops for "fast" and "slow" ops respecitively */ -#define LOOPS_DEF_FAST 10000 -#define LOOPS_DEF_SLOW 100 - -#define NUM_BORROW 100 - -/* individual enables - normally all on, disable to zero in on one test */ -#define MULG_ENABLE 1 -#define GSQUARE_ENABLE 1 -#define FEEMOD_ENABLE 1 -#define BORROW_ENABLE 1 -#define SHIFT_ENABLE 1 -#define BINVAUX_ENABLE 1 -#define MAKE_RECIP_ENABLE 1 -#define MODGRECIP_ENABLE 1 -#define KEYGEN_ENABLE 1 -#define ELLIPTIC_ENABLE 1 -#define ELL_SIMPLE_ENABLE 1 - -static void usage(char **argv) -{ - printf("Usage: %s [l=loops_fast] [L=loops_slow] [q(uick)] [D=depth]\n", argv[0]); - exit(1); -} - -/* - * Fill numGiants with random data of length bits. - */ -static void genRandGiants(giant *giants, - unsigned numGiants, - unsigned bits, - feeRand rand) -{ - int i; - giant g; - unsigned char *rdata; - unsigned bytes = (bits + 7) / 8; - giantDigit mask = 0; - unsigned giantMsd = 0; // index of MSD - unsigned log2BitsPerDigit; - unsigned bitsPerDigit; - - /* just to satisfy compiler - make sure it's always called */ - if(giants == NULL) { - return; - } - - log2BitsPerDigit = GIANT_LOG2_BITS_PER_DIGIT; - bitsPerDigit = GIANT_BITS_PER_DIGIT; - - if((bits & 7) != 0) { - /* - * deserializeGiant() has a resolution of one byte. We - * need more resolution - that is, we'll be creating - * giants a little larger than we need, and we'll mask off - * some bits in the giants' m.s. digit. - * This assumes that data fills the giantDigits such - * that if bytes mod GIANT_BYTES_PER_DIGIT != 0, the - * empty byte(s) in the MSD are in the m.s. byte(s). - */ - giantMsd = bits >> log2BitsPerDigit; - mask = (1 << (bits & (bitsPerDigit - 1))) - 1; - } - rdata = fmalloc(bytes); - for(i=0; in[giantMsd] &= mask; - - /* - * We've zeroed out some bits; we might have to - * adjust the sign of the giant as well. Note that - * deserializeGiant always yields positive - * giants.... - */ - for(j=(g->sign - 1); j!=0; j--) { - if(g->n[j] == 0) { - (g->sign)--; - } - else { - break; - } - } - } - } - ffree(rdata); - return; -} - -#if CRYPTKIT_ELL_PROJ_ENABLE -/* - * Assumes the presence of numEllPoints items in *points, and that the - * x coordinate in each point is init'd to a random giant. Uses the x - * coords as seeds to make normalized points of the entire *points array. - */ -static void makePoints(pointProjStruct *points, - unsigned numEllPoints, - curveParams *cp) -{ - int i; - giant seed = newGiant(cp->maxDigits); - - for(i=0; i maxLoops) { - maxLoops = loopsSlow; - } - - /* - * Alloc array of giants big enough for squaring at the largest - * key size, enough of them for 'loops' mulgs - */ - cp = curveParamsForDepth(FEE_DEPTH_LARGEST); - numGiants = maxLoops * 2; // 2 giants per loop - if(loopsSlow > (maxLoops / 4)) { - /* findPointProj needs 4 giants per loop */ - numGiants *= 4; - } - #if CRYPTKIT_ELL_PROJ_ENABLE - numEllGiants = loopsSlow * 2; - numEllPoints = loopsSlow * 2; - #endif - giants = fmalloc(numGiants * sizeof(giant)); - if(giants == NULL) { - printf("malloc failure\n"); - exit(1); - } - for(i=0; imaxDigits); - if(giants[i] == NULL) { - printf("malloc failure\n"); - exit(1); - } - } - freeCurveParams(cp); - - #if CRYPTKIT_ELL_PROJ_ENABLE - /* - * Projective points - two per ellLoop. The giants come from - * giants[]. We reserve an extra giant per point. - * We're assuming that numEllPoints < (4 * numGiants). - */ - points = fmalloc(numEllPoints * sizeof(pointProjStruct)); - if(points == NULL) { - printf("malloc failure\n"); - exit(1); - } - j=0; - for(i=0; icurveType) { - case FCT_Montgomery: - curveType = "FCT_Montgomery"; - break; - case FCT_Weierstrass: - curveType = "FCT_Weierstrass"; - break; - case FCT_General: - curveType = "FCT_General"; - break; - default: - printf("***Unknown curveType!\n"); - exit(1); - } - - switch(cp->primeType) { - case FPT_General: - printf("depth=%d; FPT_General, %s; keysize=%d;\n", - depth, curveType, bitlen(cp->basePrime)); - break; - case FPT_Mersenne: - printf("depth=%d; FPT_Mersenne, %s; q=%d\n", - depth, curveType, cp->q); - break; - default: - printf("depth=%d; FPT_FEE, %s; q=%d k=%d\n", - depth, curveType, cp->q, cp->k); - break; - } - basePrimeLen = bitlen(cp->basePrime); - - /* - * mulg test - * bitlen(giant) <= bitlen(basePrime); - * giants[n+1] *= giants[n] - */ - #if MULG_ENABLE - genRandGiants(giants, numGiants, basePrimeLen, rand); - PLAT_GET_TIME(startTime); - for(i=0; imaxDigits); - } - for(j=0; jbasePrime, giants[i]); - } - PLAT_GET_TIME(endTime); - elapsed = PLAT_GET_US(startTime, endTime); - printf(" binvaux: %12.2f us per op\n", - elapsed / loopsSlow); - #endif /* BINVAUX_ENABLE */ - - /* - * make_recip test - * bitlen(giant) <= bitlen(basePrime); - * make_recip(giants[n], giants[n+1] - */ - #if MAKE_RECIP_ENABLE - genRandGiants(giants, numGiants, basePrimeLen, rand); - PLAT_GET_TIME(startTime); - for(i=0; imaxDigits); - recip = borrowGiant(cp->maxDigits); - genRandGiants(&modGiant, 1, basePrimeLen, rand); - make_recip(modGiant, recip); - - PLAT_GET_TIME(startTime); - for(i=0; imaxDigits); - PLAT_GET_TIME(startTime); - for(i=0; in[0] = 1; - z->sign = 1; - elliptic(giants[i], z, giants[i+1], cp); - } - PLAT_GET_TIME(endTime); - elapsed = PLAT_GET_US(startTime, endTime); - printf(" elliptic: %12.2f us per op\n", - elapsed / (loopsSlow / 2)); - #endif /* ELLIPTIC_ENABLE*/ - - /* - * elliptic_simple test - * bitlen(giant) <= bitlen(basePrime); - * giants[n] *= giants[n+1] (elliptic mult) - */ - #if ELL_SIMPLE_ENABLE - genRandGiants(giants, numGiants, basePrimeLen, rand); - PLAT_GET_TIME(startTime); - for(i=0; icurveType != FCT_Weierstrass) { - goto loopEnd; - } - - #if CRYPTKIT_ELL_PROJ_ENABLE - /* - * ellMulProj test - * bitlen(giant) <= bitlen(basePrime); - * point[n+1] = point[n] * giants[4n+3] - * - * note we're cooking up way more giants than we have to; - * we really only need the x's and k's. But what the heck. - */ - genRandGiants(giants, 4 * numEllPoints, basePrimeLen, rand); - makePoints(points, numEllPoints, cp); - PLAT_GET_TIME(startTime); - for(i=0; i -#import - -static unsigned char *passwdPool; /* all passwords come from here */ -static unsigned char *dataPool; /* plaintext comes from here */ - -#define MAX_DATA_SIZE ((1024 * 1024) + 100) /* bytes */ - -/* - * Defaults. - */ -#define LOOPS_DEF 1 -#define MIN_EXP 2 /* for data size 10**exp */ -#define MAX_EXP 4 -#define PWD_LENGTH 15 /* bytes */ -#define DEPTH_DEFAULT FEE_DEPTH_DEFAULT -#define INCR_DEFAULT 1 /* munge every incr bytes */ - -///#define DEPTH_DEFAULT FEE_DEPTH_5 - -static void usage(char **argv) -{ - printf("usage: %s [options]\n", argv[0]); - printf(" Options:\n"); - printf(" l=loops (default=%d; 0=forever)\n", LOOPS_DEF); - printf(" n=minExp (default=%d)\n", MIN_EXP); - printf(" x=maxExp (default=max=%d)\n", MAX_EXP); - printf(" p=passwdLength (default=%d)\n", PWD_LENGTH); - printf(" D=depth (default=%d)\n", DEPTH_DEFAULT); - printf(" i=increment (default=%d)\n", INCR_DEFAULT); - #if CRYPTKIT_ECDSA_ENABLE - printf(" e (ElGamal only, no ECDSA)\n"); - #endif - printf(" s=seed\n"); - printf(" v(erbose)\n"); - printf(" q(uiet)\n"); - printf(" h(elp)\n"); - exit(1); -} - -/* - * ...min <= return <= max - */ -static int genRand(int min, int max) -{ - - /* note random() only yields a 31-bit number... */ - - if(max == min) /* avoid % 1 ! */ - return(max); - else - return(min + (random() % (max-min+1))); -} - -static unsigned char *genPasswd(unsigned passwdLength) -{ - unsigned *ip = (unsigned *)passwdPool; - unsigned intCount = passwdLength / 4; - int i; - unsigned char *cp; - unsigned residue = passwdLength & 0x3; - - for (i=0; i MAX_ASCII) { - ac = MIN_ASCII; - } - } - break; - case DT_Random: - intCount = size >> 2; - ip = (unsigned *)dataPool; - for(i=0; i MAX_EXP) { - usage(argv); - } - break; - case 'D': - depth = atoi(&argp[2]); - break; - case 'i': - incr = atoi(&argp[2]); - break; - case 's': - seed = atoi(&argp[2]); - seedSpec = 1; - break; - case 'p': - passwdLen = atoi(&argp[2]); - if(passwdLen == 0) { - usage(argv); - } - break; - case 'e': - elGamalOnly = 1; - break; - case 'v': - verbose = 1; - break; - case 'q': - quiet = 1; - break; - case 'h': - default: - usage(argv); - } - } - - if(seedSpec == 0) { - time((long *)(&seed)); - } - srandom(seed); - passwdPool = malloc(passwdLen); - dataPool = malloc(MAX_DATA_SIZE); - - printf("Starting %s test: loops %d seed %d elGamalOnly %d depth %d\n", - argv[0], loops, seed, elGamalOnly, depth); - - #if 0 - /* debug only */ - { - char s[20]; - printf("attach, then CR to continue: "); - gets(s); - } - #endif 0 - - for(loop=1; ; loop++) { - - ptext = genData(minExp, maxExp, DT_Random, &ptextLen); - passwd = genPasswd(passwdLen); - - /* - * Alternate between ECDSA and ElGamal - */ - if(elGamalOnly) { - doECDSA = 0; - doECDSAVfy = 0; - } - else { - if(loop & 1) { - doECDSA = 1; - if(loop & 2) { - doECDSAVfy = 1; - } - else { - doECDSAVfy = 0; - } - } - else { - doECDSA = 0; - doECDSAVfy = 0; - } - } - if(!quiet) { - printf("..loop %d text size %d ECDSA %d ECDSAVfy %d\n", - loop, ptextLen, doECDSA, doECDSAVfy); - } - if(doTest(ptext, ptextLen, passwd, passwdLen, - verbose, quiet, depth, incr, - doECDSA, doECDSAVfy)) { - exit(1); - } - - if(loops && (loop == loops)) { - break; - } - } - if(!quiet) { - printf("%s test complete\n", argv[0]); - } - return 0; -} diff --git a/OSX/libsecurity_cryptkit/ckutils/blobtest/Makefile b/OSX/libsecurity_cryptkit/ckutils/blobtest/Makefile deleted file mode 100644 index c4c789ad..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/blobtest/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# name of executable to build -EXECUTABLE=blobtest -# C source (.c extension) -CSOURCE= blobtest.c - -# project-specific libraries, e.g., -lstdc++ -# -PROJ_LIBS= - -# -# Optional lib search paths -# -PROJ_LIBPATH= - -# -# choose one for cc -# -VERBOSE= -#VERBOSE=-v - -# -# non-standard frameworks (e.g., -framework foo) -# -PROJ_FRAMEWORKS= - -# -# Other files to remove at 'make clean' time -# -OTHER_TO_CLEAN= - -# -# project-specific includes, with leading -I -# -PROJ_INCLUDES= - -# -# Optional C flags (warnings, optimizations, etc.) -# -PROJ_CFLAGS= - -# -# Optional link flags (using cc, not ld) -# -PROJ_LDFLAGS= - -# -# Optional dependencies -# -PROJ_DEPENDS= - -include ../Makefile.common diff --git a/OSX/libsecurity_cryptkit/ckutils/blobtest/blobtest.c b/OSX/libsecurity_cryptkit/ckutils/blobtest/blobtest.c deleted file mode 100644 index 0f678f8b..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/blobtest/blobtest.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (c) 1998,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 "Crypt.h" -#include "falloc.h" -#include -#include -#include -#include "ckutilsPlatform.h" - -#define MIN_PASSWD_LENGTH 4 -#define MAX_PASSWD_LENGTH 20 -#define DEPTH_DEFAULT FEE_DEPTH_DEFAULT - -#undef BOOL -#undef YES -#undef NO -#define BOOL int -#define YES 1 -#define NO 0 - -static unsigned char *passwdPool; - -static unsigned doBlobTest(unsigned minPasswdLen, - unsigned maxPasswdLen, - BOOL verbose, - unsigned depth); -static void usage(char **argv); - -int main(int argc, char **argv) -{ - BOOL seedSpec = NO; // YES ==> user specified - unsigned loopNum; - int arg; - char *argp; - - /* - * User-spec'd variables - */ - unsigned minPasswordLen = MIN_PASSWD_LENGTH; - unsigned maxPasswordLen = MAX_PASSWD_LENGTH; - int seed = 0; - unsigned loops = 1; - BOOL quiet = NO; - BOOL verbose = NO; - unsigned depth = DEPTH_DEFAULT; - - #if macintosh - argc = ccommand(&argv); - #endif - for(arg=1; arg -#include -#include - -static unsigned char *dataPool; /* plaintext comes from here */ - -#undef BOOL -#undef YES -#undef NO -#define BOOL int -#define YES 1 -#define NO 0 - -#define LOOPS_DEF 100 -#define MIN_EXP 2 /* for data size 10**exp */ -#define MAX_EXP 3 /* FEED is very slow with ptext larger than this... */ -#define DEPTH_DEFAULT FEE_DEPTH_DEFAULT -#define MIN_OFFSET 0 -#define MAX_OFFSET 99 - -#define PASSWD_LENGTH 10 - -static void usage(char **argv) -{ - printf("usage: %s [options]\n", argv[0]); - printf("Options:\n"); - printf(" l==loops (default=%d)\n", LOOPS_DEF); - printf(" n=minExp (default=%d)\n", MIN_EXP); - printf(" x=maxExp (default=max=%d)\n", MAX_EXP); - printf(" D=depth (default=%d)\n", DEPTH_DEFAULT); - printf(" N=minOffset (default=%d)\n", MIN_OFFSET); - printf(" q(uiet) v(erbose)\n"); - printf(" h(elp) I(ncrementing offset)\n"); - exit(1); -} - -/* - * ...min <= return <= max - */ -static int genRand(int min, int max) -{ - - /* note random() only yields a 31-bit number... */ - - if(max == min) /* avoid % 1 ! */ - return(max); - else - return(min + (RAND() % (max-min+1))); -} - -/* end of feeLib routines */ - -#define MIN_ASCII ' ' -#define MAX_ASCII '~' - -static void genPasswd(unsigned char *passwd, - unsigned passwdLen, BOOL ascii) -{ - unsigned *ip = (unsigned *)passwd; - unsigned intCount = passwdLen / 4; - int i; - unsigned char *cp; - unsigned residue = passwdLen & 0x3; - char ac; - - if(ascii) { - cp = passwd; - ac = MIN_ASCII; - for(i=0; i MAX_ASCII) { - ac = MIN_ASCII; - } - } - } - else { - for (i=0; i MAX_ASCII) { - ac = MIN_ASCII; - } - } - break; - case DT_Random: - #ifdef __LITTLE_ENDIAN__ - intCount = size >> 2; - ip = (unsigned *)dataPool; - for(i=0; i MAX_OFFSET) { - minOffset = MIN_OFFSET; - } - sizeOffset = minOffset; - break; - case 'x': - maxExp = atoi(&argp[2]); - if(maxExp > MAX_EXP) { - usage(argv); - } - break; - case 's': - seed = atoi(&argp[2]); - seedSpec = YES; - break; - case 'I': - incrOffset = YES; - break; - case 'q': - quiet = YES; - break; - case 'v': - verbose = YES; - break; - case 'h': - default: - usage(argv); - } - } - - if(seedSpec == NO) { - time((unsigned long *)(&seed)); - } - SRAND(seed); - maxSize = dataSizeFromExp(maxExp) + MAX_OFFSET + 8; - dataPool = fmalloc(maxSize); - - printf("Starting cfileTest: loops %d seed %d depth %d\n", - loops, seed, depth); - - for(loop=1; ; loop++) { - - ptext = genData(minExp, maxExp, DT_Random, incrOffset, - minOffset, &ptextLen); - if(!quiet) { - printf("..loop %d plaintext size %d\n", loop, ptextLen); - } - - /* - * Generate a whole bunch of keys - */ - genPasswd(passwd1, PASSWD_LENGTH, NO); // not ascii! - genPasswd(passwd2, PASSWD_LENGTH, NO); - myPrivKey = genPrivKey(passwd1, PASSWD_LENGTH, depth); - theirPrivKey = genPrivKey(passwd2, PASSWD_LENGTH, depth); - myPubKey = genPubKey(myPrivKey); - theirPubKey = genPubKey(theirPrivKey); - - for(encrType=CFE_PublicDES; - encrType<=CFE_FEEDExp; - encrType++) { - - if(verbose) { - printf(" ..%s\n", stringFromEncrType(encrType)); - } - for(doEnc64=0; doEnc64<2; doEnc64++) { - if(verbose) { - printf(" ..doEnc64 %d\n", doEnc64); - } - - if(verbose) { - printf(" ..no sig\n"); - } - doTest(ptext, ptextLen, myPrivKey, myPubKey, - theirPrivKey, theirPubKey, - encrType, doEnc64, SIG_NO, EXPLICIT_NO); - - if(verbose) { - printf(" ..sig, implicit sendPubKey\n"); - } - doTest(ptext, ptextLen, myPrivKey, myPubKey, - theirPrivKey, theirPubKey, - encrType, doEnc64, SIG_YES, EXPLICIT_NO); - - if(verbose) { - printf(" ..sig, explicit sendPubKey\n"); - } - doTest(ptext, ptextLen, myPrivKey, myPubKey, - theirPrivKey, theirPubKey, - encrType, doEnc64, SIG_YES, EXPLICIT_YES); - - if(verbose) { - printf(" ..sig, force error\n"); - } - doTest(ptext, ptextLen, myPrivKey, myPubKey, - theirPrivKey, theirPubKey, - encrType, doEnc64, SIG_YES, EXPLICIT_ERR); - - } /* for doEnc64 */ - } /* for encrType */ - - feePubKeyFree(myPrivKey); - feePubKeyFree(myPubKey); - feePubKeyFree(theirPrivKey); - feePubKeyFree(theirPubKey); - if(loops) { - if(loop == loops) { - break; - } - } - } /* main loop */ - - if(!quiet) { - printf("cfile test complete\n"); - } - return 0; -} diff --git a/OSX/libsecurity_cryptkit/ckutils/ckutilsPlatform.h b/OSX/libsecurity_cryptkit/ckutils/ckutilsPlatform.h deleted file mode 100644 index 66ee7bcb..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/ckutilsPlatform.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Platform-dependent stuff for ckutils - */ - -#ifndef _CKU_PLATFORM_H_ -#define _CKU_PLATFORM_H_ - -#include -#include - -/* use this for linux compatibility testing */ -//#define linux 1 -/* end linux test */ - -/* - * Make sure endianness is defined... - */ -#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) - #if macintosh - #define __BIG_ENDIAN__ 1 - #elif defined(i386) || defined(i486) || defined(__i386__) || defined(__i486__) - #define __LITTLE_ENDIAN__ 1 - #else - #error Platform dependent work needed - #endif -#endif /* endian */ - -#ifdef NeXT - #import - #define SRAND(x) srandom(x) - #define RAND() random() -#else NeXT - /* - * Use stdlib only - */ - #define SRAND(x) srand(x) - #define RAND() rand() - #define bcopy(s, d, l) memmove(d, s, l) - #define bzero(s, l) memset(s, 0, l) - #define bcmp(s, d, l) memcmp(s, d, l) -#endif - -#ifdef CK_NT_C_ONLY - -/* - * Standard I/O redirects for WINNT. - */ -#define open(f, b, c) _open(f, b, c) -#define close(f) _close(f) -#define read(f, b, c) _read(f, b, c) -#define write(f, b, c) _write(f, b, c) -#define fstat(f, b) _fstat(f, b) - -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC - -#endif CK_NT_C_ONLY - -/* - * Platform-dependent timestamp stuff. For now we assume that each platform - * has some kind of struct which maintains a high-resolution clock and - * a function which fills that struct with the current time. - */ -#if macintosh - - #include - - #define PLAT_TIME UnsignedWide - #define PLAT_GET_TIME(pt) Microseconds(&pt) - #define PLAT_GET_US(start,end) (end.lo - start.lo) - -#elif linux - - #include - - #define PLAT_TIME struct timeval - #define PLAT_GET_TIME(pt) gettimeofday(&pt, NULL) - #define PLAT_GET_US(start,end) \ - ( ( ( (end.tv_sec & 0xff) * 1000000) + end.tv_usec) - \ - ( ( (start.tv_sec & 0xff) * 1000000) + start.tv_usec) ) - -#elif NeXT - - #include - - #define PLAT_TIME struct tsval - #define PLAT_GET_TIME(pt) kern_timestamp(&pt) - #define PLAT_GET_US(start,end) (end.low_val - start.low_val) - - -#elif defined(__MACH__) && defined(__APPLE__) - #include - /* time as a double */ - #define PLAT_TIME CFAbsoluteTime - #define PLAT_GET_TIME(pt) pt = CFAbsoluteTimeGetCurrent() - #define PLAT_GET_US(start,end) \ - ((end - start) * 1000000.0) - #define PLAT_GET_NS(start,end) \ - ((end - start) * 1000000000.0) -#else - #error Platform dependent work needed -#endif - -#endif /* _CKU_PLATFORM_H_ */ diff --git a/OSX/libsecurity_cryptkit/ckutils/giantAsmBench/Makefile b/OSX/libsecurity_cryptkit/ckutils/giantAsmBench/Makefile deleted file mode 100644 index e44b24a0..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/giantAsmBench/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# name of executable to build -EXECUTABLE=giantAsmBench -# C source (.c extension) -CSOURCE= giantAsmBench.c - -# project-specific libraries, e.g., -lstdc++ -# -PROJ_LIBS= - -# -# Optional lib search paths -# -PROJ_LIBPATH= - -# -# choose one for cc -# -VERBOSE= -#VERBOSE=-v - -# -# non-standard frameworks (e.g., -framework foo) -# -PROJ_FRAMEWORKS= -framework CoreFoundation - -# -# Other files to remove at 'make clean' time -# -OTHER_TO_CLEAN= - -# -# project-specific includes, with leading -I -# -PROJ_INCLUDES= - -# -# Optional C flags (warnings, optimizations, etc.) -# -PROJ_CFLAGS= -Os - -# -# Optional link flags (using cc, not ld) -# -PROJ_LDFLAGS= - -# -# Optional dependencies -# -PROJ_DEPENDS= - -include ../Makefile.common diff --git a/OSX/libsecurity_cryptkit/ckutils/giantAsmBench/giantAsmBench.c b/OSX/libsecurity_cryptkit/ckutils/giantAsmBench/giantAsmBench.c deleted file mode 100644 index 2f5a0872..00000000 --- a/OSX/libsecurity_cryptkit/ckutils/giantAsmBench/giantAsmBench.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (c) 1998,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 "ckutilsPlatform.h" -#include -#include - -#define LOOPS_DEF 10000 -#define MIN_SIZE_DEF 1 /* mix digits for vectorMultiply test */ -#define MAX_SIZE_DEF 8 /* max digits */ - - -static void usage(char **argv) -{ - printf("usage: %s [options]\n", argv[0]); - printf(" Options:\n"); - printf(" l=loops (default = %d)\n", LOOPS_DEF); - printf(" n=maxDigits (default = %d)\n", MIN_SIZE_DEF); - printf(" x=maxDigits (default = %d)\n", MAX_SIZE_DEF); - printf(" s=seed\n"); - printf(" h(elp)\n"); - exit(1); -} - -/* - * Fill buffer with random data. Assumes giantDigits is native int size. - */ -static void randDigits(unsigned numDigits, - giantDigit *digits) -{ - int i; - - for(i=0; i -#include "ckutilsPlatform.h" -#include -#include - -#define LOOPS_DEF 100 -#define MIN_SIZE_DEF 4 /* min giant size in bytes */ -#define MAX_SIZE_DEF 32 /* max in bytes */ -#define LOOP_NOTIFY 100 - - -static void usage(char **argv) -{ - printf("usage: %s [options]\n", argv[0]); - printf(" Options:\n"); - printf(" l=loops (default = %d)\n", LOOPS_DEF); - printf(" n=maxBytes (default = %d\n", MIN_SIZE_DEF); - printf(" x=maxBytes (default = %d\n", MAX_SIZE_DEF); - printf(" o (use old 16-bit CryptKit\n"); - printf(" s=seed\n"); - printf(" h(elp)\n"); - exit(1); -} - -/* - * Fill buffer with random data. - */ -static void fillData(unsigned bufSize, - unsigned char *buf) -{ - unsigned *ip; - unsigned intCount; - unsigned residue; - unsigned char *cp; - int i; - - intCount = bufSize >> 2; - ip = (unsigned *)buf; - for(i=0; isign = -g->sign; - } - - /* avoid zero data - too many pitfalls with mod and div */ - while(isZero(g)) { - g->sign = 1; - g->n[0] = RAND(); - } -} - -/* - * Init giant arrays with random data. - */ -static void initRandGiants(unsigned numBytes, - unsigned char *buf, - unsigned numGiants, - giant *g1, - giant *g2) -{ - int i; - - for(i=0; i -#include "ckutilsPlatform.h" -#include -#include - -#define LOOPS_DEF 100 -#define MAX_SIZE_DEF 32 -#define LOOP_NOTIFY 100 - -/* quick test to show modg(1,g) broken */ -#define MODG1_TEST_ENABLE 1 - -static void usage(char **argv) -{ - printf("usage: %s [options]\n", argv[0]); - printf(" Options:\n"); - printf(" l=loops (default = %d)\n", LOOPS_DEF); - printf(" x=maxBytes (default = %d)\n", MAX_SIZE_DEF); - printf(" s=seed\n"); - printf(" h(elp)\n"); - exit(1); -} - -/* - * ...min <= return <= max - */ -static int genRand(int min, int max) -{ - - /* note random() only yields a 31-bit number... */ - - if(max == min) /* avoid % 1 ! */ - return(max); - else - return(min + (RAND() % (max-min+1))); -} - -/* - * Fill buffer with random data, random size from 1 to maxSize. - * Returns size of random data generated. - */ -static unsigned fillData(unsigned maxSize, - unsigned char *data, - int evenOnly) -{ - unsigned *ip; - unsigned intCount; - unsigned residue; - unsigned char *cp; - int i; - unsigned size; - - size = genRand(1, maxSize); - if(evenOnly) { - size &= ~1; - if(size == 1) { - size = 2; - } - } - intCount = size >> 2; - ip = (unsigned *)data; - for(i=0; isign = -g->sign; - } - - /* avoid zero data - too many pitfalls with mod and div */ - if(isZero(g)) { - g->sign = 1; - g->n[0] = 0x77; - } - return g; -} - -static int testError() -{ - char resp[100]; - - printf("Attach via debugger for more info.\n"); - printf("a to abort, c to continue: "); - gets(resp); - return (resp[0] != 'c'); -} - -/* g := |g1| */ -static void gabs(giant g) -{ - if(g->sign < 0) { - g->sign = -g->sign; - } -} - -/* - * Individual tests. API is identical for all tests. - * - * g1, g2 : giants with random data, size, and sign. Tests do not modify - * these. - * scr1, scr2 : scratch giants, big enough for all conceivable ops. Can - * be modified at will. - * Return : 0 for sucess, 1 on error. - */ - -static int compTest(giant g1, giant g2, giant scr1, giant scr2) -{ - gtog(g1, scr1); // scr1 := g1 - gtog(scr1, scr2); - if(gcompg(g1, scr2)) { - printf("gtog/gcompg error\n"); - return testError(); - } - return 0; -} - -static int addSubTest(giant g1, giant g2, giant scr1, giant scr2) -{ - gtog(g1, scr1); // scr1 := g1 - addg(g2, scr1); // scr1 := g1 + g2 - subg(g1, scr1); // scr1 := g1 + g2 - g1 =? g2 - if(gcompg(g2, scr1)) { - printf("addg/subg error\n"); - return testError(); - } - return 0; -} - -#define LARGEST_MUL 0xffff - -static int mulTest(giant g1, giant g2, giant scr1, giant scr2) -{ - int randInt = genRand(1, LARGEST_MUL); - int i; - int rtn = 0; - - int_to_giant(randInt, scr1); // scr1 := randInt - gtog(g1, scr2); // scr2 := g1 - mulg(scr1, scr2); // scr2 := g1 * randInt - - /* now do the same thing with multiple adds */ - int_to_giant(0, scr1); // scr1 := 0 - for(i=0; icapacity - abs(g1->sign) - 1) * - GIANT_BITS_PER_DIGIT; - int shiftCnt = genRand(1, maxShift); - giant scr3 = borrowGiant(scr1->capacity); - int rtn = 0; - - gtog(g1, scr1); // scr1 := g1 - gshiftleft(shiftCnt, scr1); // scr1 := (g1 << shiftCnt) - - gtog(g1, scr2); // scr2 := g1 - if(shiftCnt <= 30) { - int multInt = (1 << shiftCnt); - int_to_giant(multInt, scr3); // scr3 := (1 << shiftCnt) - } - else { - int_to_giant(1, scr3); // scr3 := 1; - gshiftleft(shiftCnt, scr3); // scr3 := (1 << shiftCnt) - } - mulg(scr3, scr2); // scr2 := g1 * (1 << shiftCnt); - if(gcompg(scr1, scr2)) { - printf("shiftCnt %d 0x%x\n", shiftCnt, shiftCnt); - printf("g1 : "); printGiantHex(g1); - printf("scr1 : "); printGiantHex(scr1); - printf("scr2 : "); printGiantHex(scr2); - printf("gshiftleft error\n"); - rtn = testError(); - } - returnGiant(scr3); - return rtn; -} - -static int rshiftTest(giant g1, giant g2, giant scr1, giant scr2) -{ - int maxShift = bitlen(g1) - 1; - int shiftCnt; - giant scr3 = borrowGiant(scr1->capacity); - int rtn = 0; - - /* special case, can't have g1 = 1 */ - if(maxShift == 0) { - #if FEE_DEBUG - printf("...rshiftTest: tweaking g1 = 1\n"); - #endif - g1->n[0] = 2; - shiftCnt = 1; - } - else { - shiftCnt = genRand(1, maxShift); - } - gtog(g1, scr1); // scr1 := g1 - gabs(scr1); // scr1 := |g1| - gtog(scr1, scr2); // scr2 := |g1| - gshiftright(shiftCnt, scr1); // scr1 := (|g1| >> shiftCnt) - - if(shiftCnt <= 30) { - int multInt = (1 << shiftCnt); - int_to_giant(multInt, scr3); // scr3 := (1 << shiftCnt) - } - else { - int_to_giant(1, scr3); // scr3 := 1; - gshiftleft(shiftCnt, scr3); // scr3 := (1 << shiftCnt) - } - divg(scr3, scr2); // scr2 := g1 / (1 << shiftCnt); - if(gcompg(scr1, scr2)) { - printf("shiftCnt %d 0x%x\n", shiftCnt, shiftCnt); - printf("g1 : "); printGiantHex(g1); - printf("scr1 : "); printGiantHex(scr1); - printf("scr2 : "); printGiantHex(scr2); - printf("gshiftright error\n"); - rtn = testError(); - } - returnGiant(scr3); - return rtn; -} - -static int divTest(giant g1, giant g2, giant scr1, giant scr2) -{ - gtog(g1, scr1); // scr1 := g1 - mulg(g2, scr1); // scr1 := g1 * g2 - gtog(g2, scr2); // scr2 := g2 - gabs(scr2); // scr2 := |g2| - divg(scr2, scr1); // scr1 := (g1 * g2) / |g2| - - /* weird case - if g2 is negative, this result is -g1! */ - if(g2->sign < 0) { - scr1->sign = -scr1->sign; - } - if(gcompg(scr1, g1)) { - printf("g1 : "); printGiantHex(g1); - printf("g2 : "); printGiantHex(g1); - printf("scr1 : "); printGiantHex(scr1); - printf("divTest error\n"); - return testError(); - } - return 0; -} - -#define LARGEST_MOD_MUL 0x40 - -static int modTest(giant g1, giant g2, giant scr1, giant scr2) -{ - int randInt = genRand(1, LARGEST_MOD_MUL); - giant scr3 = borrowGiant(scr1->capacity); - /* debug only */ - giant scr4 = borrowGiant(scr1->capacity); - /* end debug */ - int rtn = 0; - - int_to_giant(randInt, scr1); // scr1 := rand - gtog(g1, scr2); - gabs(scr2); // scr2 := |g1| - - /* current modg can't deal with g mod 1 ! */ - if((scr2->sign == 1) && (scr2->n[0] == 1)) { - #if MODG1_TEST_ENABLE - /* assume that this is legal... */ - #if FEE_DEBUG - printf("..modTest: g1 = 1, no tweak\n"); - #endif - #else - printf("..modTest: tweaking g1 = 1\n"); - scr2->n[0] = 0x54; - #endif MODG1_TEST_ENABLE - } - /* end modg workaround */ - - gtog(g2, scr3); - gabs(scr3); // scr3 := |g2| - - /* this will only work if randInt < |g1| */ - if(gcompg(scr1, scr2) >= 0) { - #if FEE_DEBUG - printf("..modTest: tweaking rand, > g1 = "); printGiantHex(g1); - printf(" g2 = "); printGiantHex(g2); - printf(" rand = "); printGiantHex(scr1); - #endif - modg(scr2, scr1); // scr1 := rand mod g1 - if(gcompg(scr1, scr2) >= 0) { - printf("simple modg error\n"); - return testError(); - } - } - - mulg(scr2, scr3); // scr3 := |g1 * g2| - addg(scr1, scr3); // scr3 := (|g1 * g2|) + rand - gtog(scr3, scr4); - modg(scr2, scr3); // scr3 := scr3 mod |g1| =? rand - if(gcompg(scr1, scr3)) { - printf("g1 : "); printGiantHex(g1); - printf("g2 : "); printGiantHex(g2); - printf("rand : 0x%x\n", randInt); - printf("randG : "); printGiantHex(scr1); - printf("scr4 : "); printGiantHex(scr4); - printf("mod : "); printGiantHex(scr3); - printf("modTest error\n"); - rtn = testError(); - } - returnGiant(scr3); - returnGiant(scr4); - return rtn; - - -} - -#if MODG1_TEST_ENABLE -/* quickie test to demonstrate failure of modg(1, g). Known failure - * as of 10 Apr 1998. - * modg(1,g) fixed on 13 Apr 1998, so this should now work. - */ -static int modg1Test(giant g1, giant scr1, giant scr2) -{ - /* test mod(x, 1) */ - scr1->n[0] = 1; - scr1->sign = 1; - gtog(g1, scr2); - modg(scr1, scr2); - if(!isZero(scr2)) { - printf("g1 : "); printGiantHex(g1); - printf("g1 mod 1 : "); printGiantHex(scr2); - return testError(); - } - return 0; -} -#endif MODG1_TEST_ENABLE - -static int mulOnesTest(giant g1, giant g2, giant scr1, giant scr2) -{ - int i; - int rtn = 0; - giant gOnes = borrowGiant(scr1->capacity); - - /* set up a giant with all ones data */ - gOnes->sign = abs(g1->sign); - for(i=0; isign; i++) { - gOnes->n[i] = (giantDigit)(-1); - } - - gtog(gOnes, scr1); // scr1 := gOnes - mulg(g1, scr1); // scr1 := gOnes * g1 - - gtog(g1, scr2); - mulg(gOnes, scr2); - - if(gcompg(scr1, scr2)) { - printf("good prod : "); printGiantHex(scr1); - printf("bad prod : "); printGiantHex(scr2); - printf("mulOnesTest error\n"); - rtn = testError(); - } - return rtn; - -} - -int main(int argc, char **argv) -{ - int arg; - char *argp; - giant g1; // init'd randomly - giant g2; // ditto - giant scr1; // scratch - giant scr2; // ditto - unsigned char *buf; - int loop; - - int loops = LOOPS_DEF; - int seedSpec = 0; - unsigned seed = 0; - unsigned maxSize = MAX_SIZE_DEF; - - initCryptKit(); - - #ifdef macintosh - seedSpec = 1; - seed = 0; - argc = 1; - maxSize = 8; - #endif - - for(arg=1; arg -#include -#include - -#define SIGN_LOOPS_DEF 100 -#define VFY_LOOPS_DEF 100 -#define PRIV_KEY_SIZE_BYTES 32 -#define DIGEST_SIZE_BYTES 20 /* e.g., SHA1 */ -#define NUM_KEYS 10 - -static void usage(char **argv) -{ - printf("Usage: %s [option...]\n", argv[0]); - printf("Options:\n"); - printf(" s=signLoops -- default %d\n", SIGN_LOOPS_DEF); - printf(" v=verifyLoops -- default %d\n", VFY_LOOPS_DEF); - printf(" D=depth -- default is ALL\n"); - exit(1); -} - -typedef struct { - unsigned char *data; - unsigned length; -} FeeData; - -/* - * Fill numDatas with random data of length bits. Caller has mallocd referents. - */ -static void genRandData(FeeData *datas, - unsigned numDatas, - unsigned numBytes, - feeRand rand) -{ - unsigned i; - FeeData *fd; - for(i=0; ilength = numBytes; - feeRandBytes(rand, fd->data, numBytes); - } - return; -} - -static void mallocData( - FeeData *fd, - unsigned numBytes) -{ - fd->data = (unsigned char *)fmalloc(numBytes); - fd->length = numBytes; -} - -/* common random callback */ -feeReturn randCallback( - void *ref, - unsigned char *bytes, - unsigned numBytes) -{ - feeRand frand = (feeRand)ref; - feeRandBytes(frand, bytes, numBytes); - return FR_Success; -} - -int main(int argc, char **argv) -{ - int arg; - char *argp; - unsigned sigLoops = SIGN_LOOPS_DEF; - unsigned vfyLoops = VFY_LOOPS_DEF; - unsigned numKeys = NUM_KEYS; // might be less for very small loops - unsigned depth; - feeRand rand; - - feePubKey keys[NUM_KEYS]; - /* sigLoops copies of each of {digestData, sigData} */ - FeeData *digestData; - FeeData *sigData; - - unsigned seed; - unsigned i; - PLAT_TIME startTime; - PLAT_TIME endTime; - double elapsed; - curveParams *cp; - unsigned minDepth = 0; - unsigned maxDepth = FEE_DEPTH_MAX; - unsigned basePrimeLen; - char *curveType; - feeReturn frtn; - - for(arg=1; arg sigLoops) { - numKeys = sigLoops; - } - digestData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops); - sigData = (FeeData *)fmalloc(sizeof(FeeData) * sigLoops); - - /* alloc the data, once, for largest private key or "digest" we'll use */ - for(i=0; icurveType) { - case FCT_Montgomery: - curveType = "FCT_Montgomery"; - break; - case FCT_Weierstrass: - curveType = "FCT_Weierstrass"; - break; - case FCT_General: - curveType = "FCT_General"; - break; - default: - printf("***Unknown curveType!\n"); - exit(1); - } - - switch(cp->primeType) { - case FPT_General: - printf("depth=%d; FPT_General, %s; keysize=%d;\n", - depth, curveType, bitlen(cp->basePrime)); - break; - case FPT_Mersenne: - printf("depth=%d; FPT_Mersenne, %s; q=%d\n", - depth, curveType, cp->q); - break; - default: - printf("depth=%d; FPT_FEE, %s; q=%d k=%d\n", - depth, curveType, cp->q, cp->k); - break; - } - basePrimeLen = bitlen(cp->basePrime); - - /* one set of random data as private keys */ - unsigned privSize = (basePrimeLen + 8) / 8; - genRandData(digestData, numKeys, privSize, rand); - - /* generate the keys (no hash - we've got that covered) */ - for(i=0; idata, digst->length, fkey); - if(frtn) { - printf("***Error %d on feeSigSign\n", (int)frtn); - break; - } - frtn = feeSigData(fs, &sig->data, &sig->length); - if(frtn) { - printf("***Error %d on feeSigData\n", (int)frtn); - break; - } - feeSigFree(fs); - } - PLAT_GET_TIME(endTime); - elapsed = PLAT_GET_US(startTime, endTime); - printf(" sign: %12.2f us per op\n", - elapsed / sigLoops); - - /* - * verify - might be doing more of these than we have - * valid signatures..... - */ - unsigned dex=0; - PLAT_GET_TIME(startTime); - for(i=0; idata, sig->length, &fs); - if(frtn) { - printf("***Error %d on feeSigParse\n", (int)frtn); - break; - } - frtn = feeSigVerify(fs, digst->data, digst->length, fkey); - if(frtn) { - printf("***Error %d on feeSigVerify\n", (int)frtn); - break; - } - feeSigFree(fs); - dex++; - if(dex == sigLoops) { - /* that's all the data we have, recycle */ - dex = 0; - } - } - PLAT_GET_TIME(endTime); - elapsed = PLAT_GET_US(startTime, endTime); - printf(" verify: %12.2f us per op\n", - elapsed / vfyLoops); - - freeCurveParams(cp); - /* possibly limited number of signatures.... */ - for(i=0; i - -/* - * These functions are only called from feeCipherFile.c. - */ -feeReturn createRandDES(feePubKey sendPrivKey, // for sig only - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile) // RETURNED if successful -{ - feeRand frand = NULL; - feeReturn frtn; - unsigned char desKey[FEE_DES_MIN_STATE_SIZE]; - unsigned char *encrDesKey = NULL; // FEED encrypted desKey - unsigned encrDesKeyLen; - feeDES des = NULL; - feeFEEDExp feed = NULL; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - unsigned char *sigData = NULL; - unsigned sigDataLen = 0; - feeCipherFile cfile = NULL; - unsigned char *pubKeyString = NULL; // of sendPrivKey - unsigned pubKeyStringLen = 0; - - if(recvPubKey == NULL) { - return FR_BadPubKey; - } - - /* - * Cons up random DES key and a feeDES object with it - */ - frand = feeRandAlloc(); - if(frand == NULL) { - frtn = FR_Internal; - goto out; - } - feeRandBytes(frand, desKey, FEE_DES_MIN_STATE_SIZE); - des = feeDESNewWithState(desKey, FEE_DES_MIN_STATE_SIZE); - if(des == NULL) { - frtn = FR_Internal; - goto out; - } - - /* - * Encrypt the DES key via FEEDExp - */ - feed = feeFEEDExpNewWithPubKey(recvPubKey, NULL, NULL); - if(feed == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feeFEEDExpEncrypt(feed, - desKey, - FEE_DES_MIN_STATE_SIZE, - &encrDesKey, - &encrDesKeyLen); - if(frtn) { - goto out; - } - - /* - * Encrypt the plaintext via DES - */ - frtn = feeDESEncrypt(des, - plainText, - plainTextLen, - &cipherText, - &cipherTextLen); - if(frtn) { - goto out; - } - - if(genSig) { - /* - * We generate signature on ciphertext by convention. - */ - if(sendPrivKey == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feePubKeyCreateSignature(sendPrivKey, - cipherText, - cipherTextLen, - &sigData, - &sigDataLen); - if(frtn) { - goto out; - } - /* - * Sender's public key string - */ - frtn = feePubKeyCreateKeyString(sendPrivKey, - (char **)&pubKeyString, - &pubKeyStringLen); - if(frtn) { - /* - * Huh? - */ - frtn = FR_BadPubKey; - goto out; - } - } - - /* - * Cons up a cipherfile - */ - cfile = feeCFileNewFromCipherText(CFE_RandDES, - cipherText, - cipherTextLen, - pubKeyString, - pubKeyStringLen, - encrDesKey, - encrDesKeyLen, - sigData, - sigDataLen, - userData); - if(cfile == NULL) { - frtn = FR_Internal; - goto out; - } - -out: - /* free alloc'd stuff */ - - if(cipherText) { - ffree(cipherText); - } - if(feed) { - feeFEEDExpFree(feed); - } - if(frand) { - feeRandFree(frand); - } - if(des) { - feeDESFree(des); - } - if(sigData) { - ffree(sigData); - } - if(encrDesKey) { - ffree(encrDesKey); - } - if(pubKeyString) { - ffree(pubKeyString); - } - memset(desKey, 0, FEE_DES_MIN_STATE_SIZE); - *cipherFile = cfile; - return frtn; - -} - -feeReturn decryptRandDES(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, // optional - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus) // RETURNED -{ - feeReturn frtn = FR_Success; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - feeFEEDExp feed = NULL; // to decrypt desKey - feeDES des = NULL; // to decrypt cipherText - unsigned char *desKey; - unsigned desKeyLen; - unsigned char *encrDesKey = NULL; // FEED encrypted desKey - unsigned encrDesKeyLen; - unsigned char *sigData = NULL; - unsigned sigDataLen; - unsigned char *sendPubKeyStr = NULL; - unsigned sendPubKeyStrLen = 0; - feePubKey parsedSendPubKey = NULL; - - if(feeCFileEncrType(cipherFile) != CFE_RandDES) { - frtn = FR_Internal; - goto out; - } - - /* - * Get ciphertext and encrypted DES key from cipherFile - */ - cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); - if(cipherText == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - encrDesKey = feeCFileOtherKeyData(cipherFile, &encrDesKeyLen); - if(encrDesKey == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - - /* - * FEED decrypt to get DES key - */ - feed = feeFEEDExpNewWithPubKey(recvPrivKey, NULL, NULL); - if(feed == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feeFEEDExpDecrypt(feed, - encrDesKey, - encrDesKeyLen, - &desKey, - &desKeyLen); - if(frtn) { - goto out; - } - - /* - * Now DES decrypt the ciphertext - */ - if(desKeyLen != FEE_DES_MIN_STATE_SIZE) { - frtn = FR_BadCipherFile; - goto out; - } - des = feeDESNewWithState(desKey, desKeyLen); - if(des == NULL) { - frtn = FR_Internal; - goto out; - } - frtn = feeDESDecrypt(des, - cipherText, - cipherTextLen, - plainText, - plainTextLen); - if(frtn) { - goto out; - } - - sigData = feeCFileSigData(cipherFile, &sigDataLen); - if(sigData) { - feeReturn sigFrtn; - - if(sendPubKey == NULL) { - /* - * Obtain sender's public key from cipherfile - */ - sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, - &sendPubKeyStrLen); - if(sendPubKeyStr == NULL) { - /* - * Hmm..shouldn't really happen, but let's - * press on. - */ - *sigStatus = SS_PresentNoKey; - goto out; - } - parsedSendPubKey = feePubKeyAlloc(); - frtn = feePubKeyInitFromKeyString(parsedSendPubKey, - (char *)sendPubKeyStr, sendPubKeyStrLen); - if(frtn) { - dbgLog(("parseRandDES: bad sendPubKeyStr\n")); - *sigStatus = SS_PresentNoKey; - goto out; - } - sendPubKey = parsedSendPubKey; - } - sigFrtn = feePubKeyVerifySignature(sendPubKey, - cipherText, - cipherTextLen, - sigData, - sigDataLen); - switch(sigFrtn) { - case FR_Success: - *sigStatus = SS_PresentValid; - break; - default: - *sigStatus = SS_PresentInvalid; - break; - } - } - else { - *sigStatus = SS_NotPresent; - } -out: - if(cipherText) { - ffree(cipherText); - } - if(feed) { - feeFEEDExpFree(feed); - } - if(des) { - feeDESFree(des); - } - if(desKey) { - memset(desKey, 0, desKeyLen); - ffree(desKey); - } - if(encrDesKey) { - ffree(encrDesKey); - } - if(sigData) { - ffree(sigData); - } - if(parsedSendPubKey) { - feePubKeyFree(parsedSendPubKey); - } - if(sendPubKeyStr) { - ffree(sendPubKeyStr); - } - return frtn; -} - -feeReturn createPubDES(feePubKey sendPrivKey, // required - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile) // RETURNED if successful -{ - feeRand frand = NULL; - feeReturn frtn; - unsigned char *desKey; - unsigned desKeyLen; - feeDES des = NULL; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - unsigned char *sigData = NULL; - unsigned sigDataLen = 0; - feeCipherFile cfile = NULL; - unsigned char *pubKeyString = NULL; - unsigned pubKeyStringLen; - - if((sendPrivKey == NULL) || (recvPubKey == NULL)) { - return FR_BadPubKey; - } - - /* - * Get the public string version of sendPrivKey for embedding in - * cipherfile - */ - frtn = feePubKeyCreateKeyString(sendPrivKey, - (char **)&pubKeyString, - &pubKeyStringLen); - if(frtn) { - goto out; - } - - /* - * Obtain DES key via key exchange and get a feeDES object with it - */ - frtn = feePubKeyCreatePad(sendPrivKey, - recvPubKey, - &desKey, - &desKeyLen); - if(frtn) { - goto out; - } - des = feeDESNewWithState(desKey, desKeyLen); - if(des == NULL) { - frtn = FR_Internal; - goto out; - } - - /* - * Encrypt the plaintext via DES - */ - frtn = feeDESEncrypt(des, - plainText, - plainTextLen, - &cipherText, - &cipherTextLen); - if(frtn) { - goto out; - } - - if(genSig) { - /* - * We generate signature on ciphertext by convention. - */ - frtn = feePubKeyCreateSignature(sendPrivKey, - cipherText, - cipherTextLen, - &sigData, - &sigDataLen); - if(frtn) { - goto out; - } - } - - /* - * Cons up a cipherfile - */ - cfile = feeCFileNewFromCipherText(CFE_PublicDES, - cipherText, - cipherTextLen, - pubKeyString, - pubKeyStringLen, - NULL, // otherKey - 0, - sigData, - sigDataLen, - userData); - if(cfile == NULL) { - frtn = FR_Internal; - goto out; - } - -out: - /* free alloc'd stuff */ - - if(cipherText) { - ffree(cipherText); - } - if(frand) { - feeRandFree(frand); - } - if(des) { - feeDESFree(des); - } - if(desKey) { - ffree(desKey); - } - if(sigData) { - ffree(sigData); - } - if(pubKeyString) { - ffree(pubKeyString); - } - *cipherFile = cfile; - return frtn; - -} - -feeReturn decryptPubDES(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus) // RETURNED -{ - feeReturn frtn = FR_Success; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - feeDES des = NULL; // to decrypt cipherText - unsigned char *desKey; - unsigned desKeyLen; - unsigned char *sigData = NULL; - unsigned sigDataLen; - unsigned char *pubKeyString = NULL; - unsigned pubKeyStringLen; - feePubKey decryptPubKey = NULL; // from cipherfile - - if(feeCFileEncrType(cipherFile) != CFE_PublicDES) { - frtn = FR_Internal; - goto out; - } - - /* - * Get ciphertext and sender's public key from cipherFile - */ - cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); - if(cipherText == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - pubKeyString = feeCFileSendPubKeyData(cipherFile, &pubKeyStringLen); - if(pubKeyString == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - decryptPubKey = feePubKeyAlloc(); - frtn = feePubKeyInitFromKeyString(decryptPubKey, - (char *)pubKeyString, - pubKeyStringLen); - if(frtn) { - goto out; - } - - /* - * key exchange to get DES key - */ - frtn = feePubKeyCreatePad(recvPrivKey, - decryptPubKey, - &desKey, - &desKeyLen); - if(frtn) { - goto out; - } - - /* - * Now DES decrypt the ciphertext - */ - if(desKeyLen < FEE_DES_MIN_STATE_SIZE) { - frtn = FR_BadCipherFile; - goto out; - } - des = feeDESNewWithState(desKey, desKeyLen); - if(des == NULL) { - frtn = FR_Internal; - goto out; - } - frtn = feeDESDecrypt(des, - cipherText, - cipherTextLen, - plainText, - plainTextLen); - if(frtn) { - goto out; - } - - sigData = feeCFileSigData(cipherFile, &sigDataLen); - if(sigData) { - feeReturn sigFrtn; - - if(sendPubKey == NULL) { - /* - * Use key embedded in cipherfile - */ - sendPubKey = decryptPubKey; - } - sigFrtn = feePubKeyVerifySignature(sendPubKey, - cipherText, - cipherTextLen, - sigData, - sigDataLen); - switch(sigFrtn) { - case FR_Success: - *sigStatus = SS_PresentValid; - break; - default: - *sigStatus = SS_PresentInvalid; - break; - } - } - else { - *sigStatus = SS_NotPresent; - } -out: - if(cipherText) { - ffree(cipherText); - } - if(des) { - feeDESFree(des); - } - if(desKey) { - ffree(desKey); - } - if(pubKeyString) { - ffree(pubKeyString); - } - if(sigData) { - ffree(sigData); - } - if(decryptPubKey) { - feePubKeyFree(decryptPubKey); - } - return frtn; -} - -#endif /* CRYPTKIT_CIPHERFILE_ENABLE */ - diff --git a/OSX/libsecurity_cryptkit/lib/CipherFileDES.h b/OSX/libsecurity_cryptkit/lib/CipherFileDES.h deleted file mode 100644 index 78139888..00000000 --- a/OSX/libsecurity_cryptkit/lib/CipherFileDES.h +++ /dev/null @@ -1,67 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * CipherFileDES.h - DES-related cipherfile support - * - * Revision History - * ---------------- - * 18 Feb 97 at Apple - * Created. - */ - -#ifndef _CK_CFILEDES_H_ -#define _CK_CFILEDES_H_ - -#include "ckconfig.h" - -#if CRYPTKIT_CIPHERFILE_ENABLE - -#include "Crypt.h" -#include "feeCipherFile.h" -#include "CipherFileTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -feeReturn createRandDES(feePubKey sendPrivKey, - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile); // RETURNED if successful -feeReturn decryptRandDES(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus); // RETURNED -feeReturn createPubDES(feePubKey sendPrivKey, // required - feePubKey recvPubKey, // required - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile); // RETURNED if successful -feeReturn decryptPubDES(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, // optional - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus); // RETURNED - -#ifdef __cplusplus -} -#endif - -#endif /* CRYPTKIT_CIPHERFILE_ENABLE*/ - -#endif /*_CK_CFILEDES_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/CipherFileFEED.c b/OSX/libsecurity_cryptkit/lib/CipherFileFEED.c deleted file mode 100644 index ce9e075a..00000000 --- a/OSX/libsecurity_cryptkit/lib/CipherFileFEED.c +++ /dev/null @@ -1,460 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * CipherFileFEED.c - FEED and FEEDExp related cipherfile support - * - * Revision History - * ---------------- - * 24 Jun 97 at Apple - * Fixed memory leaks via sigData - * 18 Feb 97 at Apple - * Split off from feeCipherFile.c - */ - -#include "ckconfig.h" - -#if CRYPTKIT_CIPHERFILE_ENABLE - -#include "Crypt.h" -#include "CipherFileFEED.h" -#include "falloc.h" -#include "feeDebug.h" - -feeReturn createFEED(feePubKey sendPrivKey, // required - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile) // RETURNED if successful -{ - feeReturn frtn; - feeFEED feed = NULL; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - unsigned char *sigData = NULL; - unsigned sigDataLen = 0; - feeCipherFile cfile = NULL; - unsigned char *pubKeyString = NULL; // of sendPrivKey - unsigned pubKeyStringLen = 0; - - if((sendPrivKey == NULL) || (recvPubKey == NULL)) { - return FR_BadPubKey; - } - - /* - * FEED encrypt plaintext - */ - feed = feeFEEDNewWithPubKey(sendPrivKey, recvPubKey, FF_ENCRYPT, NULL, NULL); - if(feed == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feeFEEDEncrypt(feed, - plainText, - plainTextLen, - &cipherText, - &cipherTextLen); - if(frtn) { - goto out; - } - - /* - * Sender's public key string - */ - frtn = feePubKeyCreateKeyString(sendPrivKey, - (char **)&pubKeyString, - &pubKeyStringLen); - if(frtn) { - /* - * Huh? - */ - frtn = FR_BadPubKey; - goto out; - } - - if(genSig) { - /* - * We generate signature on ciphertext by convention. - */ - frtn = feePubKeyCreateSignature(sendPrivKey, - cipherText, - cipherTextLen, - &sigData, - &sigDataLen); - if(frtn) { - goto out; - } - } - - /* - * Cons up a cipherfile - */ - cfile = feeCFileNewFromCipherText(CFE_FEED, - cipherText, - cipherTextLen, - pubKeyString, - pubKeyStringLen, - NULL, - 0, - sigData, - sigDataLen, - userData); - if(cfile == NULL) { - frtn = FR_Internal; - goto out; - } - -out: - /* free alloc'd stuff */ - - if(cipherText) { - ffree(cipherText); - } - if(feed) { - feeFEEDFree(feed); - } - if(pubKeyString) { - ffree(pubKeyString); - } - if(sigData) { - ffree(sigData); - } - *cipherFile = cfile; - return frtn; - -} - -feeReturn decryptFEED(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, // optional - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus) // RETURNED -{ - feeReturn frtn = FR_Success; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - feeFEED feed = NULL; - unsigned char *sigData = NULL; - unsigned sigDataLen; - unsigned char *sendPubKeyStr = NULL; - unsigned sendPubKeyStrLen = 0; - feePubKey parsedSendPubKey = NULL; - - if(feeCFileEncrType(cipherFile) != CFE_FEED) { - frtn = FR_Internal; - goto out; - } -//printf("decryptFEED\n"); -//printf("privKey:\n"); printPubKey(recvPrivKey); -//printf("pubKey:\n"); printPubKey(sendPubKey); - /* - * Get ciphertext and sender's public key from cipherFile - */ - cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); - if(cipherText == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, &sendPubKeyStrLen); - if(sendPubKeyStr == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - parsedSendPubKey = feePubKeyAlloc(); - frtn = feePubKeyInitFromKeyString(parsedSendPubKey, - (char *)sendPubKeyStr, - sendPubKeyStrLen); - if(frtn) { - frtn = FR_BadCipherFile; - goto out; - } -//printf("parsedSendPubKey:\n"); printPubKey(parsedSendPubKey); - - /* - * FEED decrypt - */ - feed = feeFEEDNewWithPubKey(recvPrivKey, parsedSendPubKey, FF_DECRYPT, NULL, NULL); - if(feed == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feeFEEDDecrypt(feed, - cipherText, - cipherTextLen, - plainText, - plainTextLen); - if(frtn) { - goto out; - } - - sigData = feeCFileSigData(cipherFile, &sigDataLen); - if(sigData) { - feeReturn sigFrtn; - - if(sendPubKey == NULL) { - /* - * use embedded sender's public key - */ - sendPubKey = parsedSendPubKey; - } - sigFrtn = feePubKeyVerifySignature(sendPubKey, - cipherText, - cipherTextLen, - sigData, - sigDataLen); - switch(sigFrtn) { - case FR_Success: - *sigStatus = SS_PresentValid; - break; - default: - *sigStatus = SS_PresentInvalid; - break; - } - } - else { - *sigStatus = SS_NotPresent; - } -out: - if(cipherText) { - ffree(cipherText); - } - if(feed) { - feeFEEDFree(feed); - } - if(sigData) { - ffree(sigData); - } - if(parsedSendPubKey) { - feePubKeyFree(parsedSendPubKey); - } - if(sendPubKeyStr) { - ffree(sendPubKeyStr); - } - return frtn; -} - -feeReturn createFEEDExp(feePubKey sendPrivKey, // for sig only - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile) // RETURNED if successful -{ - feeReturn frtn; - feeFEEDExp feed = NULL; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - unsigned char *sigData = NULL; - unsigned sigDataLen = 0; - feeCipherFile cfile = NULL; - unsigned char *pubKeyString = NULL; // of sendPrivKey, for sig - unsigned pubKeyStringLen = 0; - - if(recvPubKey == NULL) { - return FR_BadPubKey; - } - - /* - * FEEDExp encrypt plaintext - */ - feed = feeFEEDExpNewWithPubKey(recvPubKey, NULL, NULL); - if(feed == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feeFEEDExpEncrypt(feed, - plainText, - plainTextLen, - &cipherText, - &cipherTextLen); - if(frtn) { - goto out; - } - - if(genSig) { - if(sendPrivKey == NULL) { - frtn = FR_IllegalArg; - goto out; - } - /* - * We generate signature on ciphertext by convention. - */ - frtn = feePubKeyCreateSignature(sendPrivKey, - cipherText, - cipherTextLen, - &sigData, - &sigDataLen); - if(frtn) { - goto out; - } - /* - * Sender's public key string - */ - frtn = feePubKeyCreateKeyString(sendPrivKey, - (char **)&pubKeyString, - &pubKeyStringLen); - if(frtn) { - /* - * Huh? - */ - frtn = FR_BadPubKey; - goto out; - } - } - - /* - * Cons up a cipherfile - */ - cfile = feeCFileNewFromCipherText(CFE_FEEDExp, - cipherText, - cipherTextLen, - pubKeyString, - pubKeyStringLen, - NULL, - 0, - sigData, - sigDataLen, - userData); - if(cfile == NULL) { - frtn = FR_Internal; - goto out; - } - -out: - /* free alloc'd stuff */ - - if(cipherText) { - ffree(cipherText); - } - if(feed) { - feeFEEDExpFree(feed); - } - if(sigData) { - ffree(sigData); - } - if(pubKeyString) { - ffree(pubKeyString); - } - *cipherFile = cfile; - return frtn; - -} - -feeReturn decryptFEEDExp(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, // optional - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus) // RETURNED -{ - feeReturn frtn = FR_Success; - unsigned char *cipherText = NULL; - unsigned cipherTextLen; - feeFEEDExp feed = NULL; - unsigned char *sigData = NULL; - unsigned sigDataLen; - unsigned char *sendPubKeyStr = NULL; - unsigned sendPubKeyStrLen = 0; - feePubKey parsedSendPubKey = NULL; - - if(feeCFileEncrType(cipherFile) != CFE_FEEDExp) { - frtn = FR_Internal; - goto out; - } - - /* - * Get ciphertext from cipherFile - */ - cipherText = feeCFileCipherText(cipherFile, &cipherTextLen); - if(cipherText == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - - /* - * FEEDExp decrypt - */ - feed = feeFEEDExpNewWithPubKey(recvPrivKey, NULL, NULL); - if(feed == NULL) { - frtn = FR_BadPubKey; - goto out; - } - frtn = feeFEEDExpDecrypt(feed, - cipherText, - cipherTextLen, - plainText, - plainTextLen); - if(frtn) { - goto out; - } - - sigData = feeCFileSigData(cipherFile, &sigDataLen); - if(sigData) { - feeReturn sigFrtn; - - if(sendPubKey == NULL) { - /* - * use embedded sender's public key - */ - sendPubKeyStr = feeCFileSendPubKeyData(cipherFile, - &sendPubKeyStrLen); - if(sendPubKeyStr == NULL) { - frtn = FR_BadCipherFile; - goto out; - } - parsedSendPubKey = feePubKeyAlloc(); - frtn = feePubKeyInitFromKeyString(parsedSendPubKey, - (char *)sendPubKeyStr, sendPubKeyStrLen); - if(frtn) { - frtn = FR_BadCipherFile; - goto out; - } - sendPubKey = parsedSendPubKey; - } - sigFrtn = feePubKeyVerifySignature(sendPubKey, - cipherText, - cipherTextLen, - sigData, - sigDataLen); - switch(sigFrtn) { - case FR_Success: - *sigStatus = SS_PresentValid; - break; - default: - *sigStatus = SS_PresentInvalid; - break; - } - } - else { - *sigStatus = SS_NotPresent; - } -out: - if(cipherText) { - ffree(cipherText); - } - if(feed) { - feeFEEDExpFree(feed); - } - if(sigData) { - ffree(sigData); - } - if(parsedSendPubKey) { - feePubKeyFree(parsedSendPubKey); - } - if(sendPubKeyStr) { - ffree(sendPubKeyStr); - } - return frtn; -} - -#endif /* CRYPTKIT_CIPHERFILE_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/CipherFileFEED.h b/OSX/libsecurity_cryptkit/lib/CipherFileFEED.h deleted file mode 100644 index 5e6890bc..00000000 --- a/OSX/libsecurity_cryptkit/lib/CipherFileFEED.h +++ /dev/null @@ -1,69 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * CipherFileFEED.h - FEED and FEEDExp related cipherfile support - * - * Revision History - * ---------------- - * 18 Feb 97 at Apple - * Created. - */ - -#ifndef _CK_CFILEFEED_H_ -#define _CK_CFILEFEED_H_ - -#include "ckconfig.h" - -#if CRYPTKIT_CIPHERFILE_ENABLE - -#include "Crypt.h" -#include "feeCipherFile.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Private functions. - */ -feeReturn createFEED(feePubKey sendPrivKey, - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile); // RETURNED if successful -feeReturn decryptFEED(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus); // RETURNED -feeReturn createFEEDExp(feePubKey sendPrivKey, - feePubKey recvPubKey, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - unsigned userData, // for caller's convenience - feeCipherFile *cipherFile); // RETURNED if successful -feeReturn decryptFEEDExp(feeCipherFile cipherFile, - feePubKey recvPrivKey, - feePubKey sendPubKey, // optional - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus); // RETURNED - -#ifdef __cplusplus -} -#endif - -#endif /* CRYPTKIT_CIPHERFILE_ENABLE */ - -#endif /*_CK_CFILEFEED_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/CipherFileTypes.h b/OSX/libsecurity_cryptkit/lib/CipherFileTypes.h deleted file mode 100644 index e0307dc9..00000000 --- a/OSX/libsecurity_cryptkit/lib/CipherFileTypes.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * CipherFileTypes.h - * - * Revision History - * ---------------- - * 8/24/98 ap - * Added tags around #endif comment. - * 19 Feb 97 at NeXT - * Created. - */ - -#ifndef _CK_CFILETYPES_H_ -#define _CK_CFILETYPES_H_ - -#include "ckconfig.h" - -#if CRYPTKIT_CIPHERFILE_ENABLE - -#include "feeCipherFile.h" - -/* - * Type of encryption used in a CipherFile. - */ -typedef enum { - - /* - * DES encryption using pad created via public key exchange; sender's - * public key is embedded. - */ - CFE_PublicDES = 1, - - /* - * Random DES key used for encryption. The DES key is encrypted via - * FEEDExp using recipient's public key; the result is embedded in the - * CipherFile. Sender's public key is embedded only if - * signature is generated. - */ - CFE_RandDES = 2, - - /* - * 1:1 FEED encryption. Sender's public key is embedded. - */ - CFE_FEED = 3, - - /* - * 2:1 FEED encryption. Sender's public key is embedded only if signature - * is generated. - */ - CFE_FEEDExp = 4, - - /* - * User-defined cipherfile. - */ - CFE_Other = 5 - -} cipherFileEncrType; - - -/* - * Signature status upon decryption of a CipherFile. - */ -typedef enum { - - SS_NotPresent = 0, // Signature not present. - SS_PresentValid = 1, // Signature present and valid. - SS_PresentNoKey = 2, // Signature present, but no public key - // available to validate it. - SS_PresentInvalid = 3 // Signature present and invalid. - -} feeSigStatus; - -#endif /* CRYPTKIT_CIPHERFILE_ENABLE */ - -#endif /* _CK_CFILETYPES_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/Crypt.h b/OSX/libsecurity_cryptkit/lib/Crypt.h index 29a47d58..cabb0421 100644 --- a/OSX/libsecurity_cryptkit/lib/Crypt.h +++ b/OSX/libsecurity_cryptkit/lib/Crypt.h @@ -23,26 +23,7 @@ #ifndef _CK_CRYPT_H_ #define _CK_CRYPT_H_ -#ifdef macintosh - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#else - #include -#include #include #include #include @@ -55,6 +36,4 @@ #include #include -#endif - #endif /* _CK_CRYPT_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/CryptKitAsn1.h b/OSX/libsecurity_cryptkit/lib/CryptKitAsn1.h index a4bfc299..510806fc 100644 --- a/OSX/libsecurity_cryptkit/lib/CryptKitAsn1.h +++ b/OSX/libsecurity_cryptkit/lib/CryptKitAsn1.h @@ -7,7 +7,6 @@ #include "ckconfig.h" -#if CRYPTKIT_DER_ENABLE #include #include @@ -133,6 +132,4 @@ extern const SecAsn1Template FEEPrivateKeyASN1Template[]; } #endif -#endif /* CRYPTKIT_DER_ENABLE */ - #endif /* _CRYPT_KIT_ASN1_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/CryptKitDER.cpp b/OSX/libsecurity_cryptkit/lib/CryptKitDER.cpp index f8cabe31..bb9db996 100644 --- a/OSX/libsecurity_cryptkit/lib/CryptKitDER.cpp +++ b/OSX/libsecurity_cryptkit/lib/CryptKitDER.cpp @@ -24,7 +24,6 @@ #include "ckconfig.h" -#if CRYPTKIT_DER_ENABLE #include #include @@ -37,6 +36,7 @@ #include #include #include +#include #define PRINT_SIG_GIANTS 0 #define PRINT_CURVE_PARAMS 0 @@ -1241,4 +1241,3 @@ feeReturn feeDERDecodePKCS8PrivateKey( return frtn; } -#endif /* CRYPTKIT_DER_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/CryptKitDER.h b/OSX/libsecurity_cryptkit/lib/CryptKitDER.h index 28b6ed03..f193e39b 100644 --- a/OSX/libsecurity_cryptkit/lib/CryptKitDER.h +++ b/OSX/libsecurity_cryptkit/lib/CryptKitDER.h @@ -27,8 +27,6 @@ #include -#if CRYPTKIT_DER_ENABLE - #include #include #include @@ -192,7 +190,6 @@ feeReturn feeDERDecodePKCS8PrivateKey( } #endif -#endif /* CRYPTKIT_DER_ENABLE */ #endif /* _CRYPTKIT_DER_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/ECDSA_Profile.h b/OSX/libsecurity_cryptkit/lib/ECDSA_Profile.h index eb7a7cc9..54149b92 100644 --- a/OSX/libsecurity_cryptkit/lib/ECDSA_Profile.h +++ b/OSX/libsecurity_cryptkit/lib/ECDSA_Profile.h @@ -29,8 +29,6 @@ #include "ckconfig.h" -#if CRYPTKIT_ECDSA_ENABLE - #include "feeDebug.h" #ifdef FEE_DEBUG @@ -86,5 +84,4 @@ extern unsigned vfyStep7; #endif /* ECDSA_PROFILE */ -#endif /* CRYPTKIT_ECDSA_ENABLE */ #endif /* _CK_ECDSA_PROFILE_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/ECDSA_Verify_Prefix.h b/OSX/libsecurity_cryptkit/lib/ECDSA_Verify_Prefix.h deleted file mode 100644 index 3c52bde5..00000000 --- a/OSX/libsecurity_cryptkit/lib/ECDSA_Verify_Prefix.h +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Prefix file for ECDSA Verify build. - * - * This symbol disables features not needed for ECDSA verify. - */ -#define ECDSA_VERIFY_ONLY 1 diff --git a/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.c b/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.c index 83e77619..a24f0438 100644 --- a/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.c +++ b/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.c @@ -24,8 +24,6 @@ #include "ckconfig.h" -#if CRYPTKIT_HMAC_LEGACY - #include "HmacSha1Legacy.h" #include "ckSHA1.h" #include @@ -162,4 +160,3 @@ OSStatus hmacLegacyFinal( return errSecSuccess; } -#endif /* CRYPTKIT_HMAC_LEGACY */ diff --git a/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.h b/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.h index 691ca5bb..733f9118 100644 --- a/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.h +++ b/OSX/libsecurity_cryptkit/lib/HmacSha1Legacy.h @@ -30,8 +30,6 @@ #include #endif -#if CRYPTKIT_HMAC_LEGACY - #include #ifdef __cplusplus @@ -64,6 +62,4 @@ OSStatus hmacLegacyFinal( } #endif -#endif /* CRYPTKIT_HMAC_LEGACY */ - #endif /* __HMAC_SHA1_LEGACY__ */ diff --git a/OSX/libsecurity_cryptkit/lib/ckDES.c b/OSX/libsecurity_cryptkit/lib/ckDES.c deleted file mode 100644 index 983f59e1..00000000 --- a/OSX/libsecurity_cryptkit/lib/ckDES.c +++ /dev/null @@ -1,545 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * DES.c - raw DES encryption engine - * - * Revision History - * ---------------- - * Added braces to static array definition of si[][]. - * 10/06/98 ap - * Changed to compile with C++. - * 28 May 98 at Apple - * Changed to use platform-dependent fmalloc(), ffree() - * 31 Mar 97 at Apple - * Put per-instance data in struct _desInst - * Changed setkey() to dessetkey() to avoid collision with libc version - * 21 Aug 96 at NeXT - * Broke out from NSDESCryptor.m - * 22 Feb 96 at NeXT - * Created. - */ - -#include "ckconfig.h" - -#if CRYPTKIT_SYMMETRIC_ENABLE - -#include "ckDES.h" -#include "falloc.h" -#include - -#ifndef NULL -#define NULL ((void *)0) -#endif /* NULL */ - -#define DES_DEBUG 0 /* enables some printfs */ - -/* Sofware DES functions - * written 12 Dec 1986 by Phil Karn, KA9Q; large sections adapted from - * the 1977 public-domain program by Jim Gillogly - */ - -#ifdef __LITTLE_ENDIAN__ -/* Byte swap a long */ -static unsigned int byteswap(unsigned int x) { - register char *cp,tmp; - - cp = (char *)&x; - tmp = cp[3]; - cp[3] = cp[0]; - cp[0] = tmp; - - tmp = cp[2]; - cp[2] = cp[1]; - cp[1] = tmp; - - return x; -} -#endif - -/* Tables defined in the Data Encryption Standard documents */ - -/* initial permutation IP */ -static const char ip[] = { - 58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7 -}; - -/* final permutation IP^-1 */ -static const char fp[] = { - 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25 -}; - -/* expansion operation matrix - * This is for reference only; it is unused in the code - * as the f() function performs it implicitly for speed - */ -#ifdef notdef -static char ei[] = { - 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1 -}; -#endif - -/* permuted choice table (key) */ -static const char pc1[] = { - 57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4 -}; - -/* number left rotations of pc1 */ -static const char totrot[] = { - 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 -}; - -/* permuted choice key (table) */ -static const char pc2[] = { - 14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32 -}; - -/* The (in)famous S-boxes */ -static const char si[8][64] = { - { - /* S1 */ - 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, - 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, - 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, - 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 - }, - { - /* S2 */ - 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, - 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, - 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, - 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 - }, - { - /* S3 */ - 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, - 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, - 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, - 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 - }, - { - /* S4 */ - 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, - 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, - 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, - 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 - }, - { - /* S5 */ - 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, - 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, - 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, - 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 - }, - { - /* S6 */ - 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, - 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, - 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, - 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 - }, - { - /* S7 */ - 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, - 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, - 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, - 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 - }, - { - /* S8 */ - 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, - 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, - 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, - 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 - } -}; - -/* 32-bit permutation function P used on the output of the S-boxes */ -static const char p32i[] = { - 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25 -}; -/* End of DES-defined tables */ - -/* Lookup tables initialized once only at startup by desinit() */ -static long (*sp)[64]; /* Combined S and P boxes */ - -static char (*iperm)[16][8]; /* Initial and final permutations */ -static char (*fperm)[16][8]; - - -/* bit 0 is left-most in byte */ -static const int bytebit[] = { - 0200,0100,040,020,010,04,02,01 -}; - -static const int nibblebit[] = { - 010,04,02,01 -}; - -/* Allocate space and initialize DES lookup arrays - * mode == 0: standard Data Encryption Algorithm - * mode == 1: DEA without initial and final permutations for speed - * mode == 2: DEA without permutations and with 128-byte key (completely - * independent subkeys for each round) - */ -/* Initialize the lookup table for the combined S and P boxes */ -static void spinit() { - char pbox[32]; - int p,i,s,j,rowcol; - long val; - - /* Compute pbox, the inverse of p32i. - * This is easier to work with - */ - for(p=0;p<32;p++){ - for(i=0;i<32;i++){ - if(p32i[i]-1 == p){ - pbox[p] = i; - break; - } - } - } - for(s = 0; s < 8; s++){ /* For each S-box */ - for(i=0; i<64; i++){ /* For each possible input */ - val = 0; - /* The row number is formed from the first and last - * bits; the column number is from the middle 4 - */ - rowcol = (i & 32) | ((i & 1) ? 16 : 0) | ((i >> 1) & 0xf); - for(j=0;j<4;j++){ /* For each output bit */ - if(si[s][rowcol] & (8 >> j)){ - val |= 1L << (31 - pbox[4*s + j]); - } - } - sp[s][i] = val; - -#if DES_DEBUG - printf("sp[%d][%2d] = %08lx\n",s,i,sp[s][i]); -#endif - } - } -} - -/* initialize a perm array */ -static void perminit(char perm[16][16][8], const char p[64]) { - register int l, j, k; - int i,m; - - /* Clear the permutation array */ - for (i=0; i<16; i++) - for (j=0; j<16; j++) - for (k=0; k<8; k++) - perm[i][j][k]=0; - - for (i=0; i<16; i++) /* each input nibble position */ - for (j = 0; j < 16; j++)/* each possible input nibble */ - for (k = 0; k < 64; k++)/* each output bit position */ - { l = p[k] - 1; /* where does this bit come from*/ - if ((l >> 2) != i) /* does it come from input posn?*/ - continue; /* if not, bit k is 0 */ - if (!(j & nibblebit[l & 3])) - continue; /* any such bit in input? */ - m = k & 07; /* which bit is this in the byte*/ - perm[i][j][k>>3] |= bytebit[m]; - } -} - -int desinit(desInst dinst, int mode) { - dinst->desmode = mode; - - /* - * Remainder only has to be done once. - */ - if(sp != NULL){ - /* Already initialized */ - return 0; - } - if((sp = (long (*)[64])fmalloc(sizeof(long) * 8 * 64)) == NULL){ - return -1; - } - spinit(); - if(mode == 1 || mode == 2) /* No permutations */ - return 0; - - iperm = (char (*)[16][8])fmalloc(sizeof(char) * 16 * 16 * 8); - if(iperm == NULL){ - ffree((char *)sp); - return -1; - } - perminit(iperm,ip); - - fperm = (char (*)[16][8])fmalloc(sizeof(char) * 16 * 16 * 8); - if(fperm == NULL){ - ffree((char *)sp); - ffree((char *)iperm); - return -1; - } - perminit(fperm,fp); - - return 0; -} -/* Free up storage used by DES */ -void desdone(desInst dinst) { -#if 0 - /* - * no per-instance mallocd data - */ - if(sp == NULL) - return; /* Already done */ - - // free((char *)sp); // NO! just free instance data; leave statics - // since these are consts - ffree((char *)dinst->kn); - //if(iperm != NULL) - // free((char *)iperm); - //if(fperm != NULL) - // free((char *)fperm); - - //sp = NULL; - //iperm = NULL; - //fperm = NULL; - dinst->kn = NULL; -#endif /* 0 */ -} -/* Set key (initialize key schedule array) */ -void dessetkey(desInst dinst, char *key) { - char pc1m[56]; /* place to modify pc1 into */ - char pcr[56]; /* place to rotate pc1 into */ - register int i,j,l; - int m; - - /* In mode 2, the 128 bytes of subkey are set directly from the - * user's key, allowing him to use completely independent - * subkeys for each round. Note that the user MUST specify a - * full 128 bytes. - * - * I would like to think that this technique gives the NSA a real - * headache, but I'm not THAT naive. - */ - if(dinst->desmode == 2){ - for(i=0;i<16;i++) - for(j=0;j<8;j++) - dinst->kn[i][j] = *key++; - return; - } - /* Clear key schedule */ - for (i=0; i<16; i++) - for (j=0; j<8; j++) - dinst->kn[i][j]=0; - - for (j=0; j<56; j++) { /* convert pc1 to bits of key */ - l=pc1[j]-1; /* integer bit location */ - m = l & 07; /* find bit */ - pc1m[j]=(key[l>>3] & /* find which key byte l is in */ - bytebit[m]) /* and which bit of that byte */ - ? 1 : 0; /* and store 1-bit result */ - } - for (i=0; i<16; i++) { /* key chunk for each iteration */ - for (j=0; j<56; j++) /* rotate pc1 the right amount */ - pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28]; - /* rotate left and right halves independently */ - for (j=0; j<48; j++){ /* select bits individually */ - /* check bit that goes to dinst->kn[j] */ - if (pcr[pc2[j]-1]){ - /* mask it in if it's there */ - l= j % 6; - dinst->kn[i][j/6] |= bytebit[l] >> 2; - } - } - } -#if DES_DEBUG - for(i=0;i<16;i++) { - printf("dinst->kn[%d] = ", i); - for(j=0;j<8;j++) { - printf("%x ", dinst->kn[i][j]); - } - printf("\n"); - } - -#endif /* 1 */ -} - -/* The nonlinear function f(r,k), the heart of DES */ -static long int f(unsigned long r, unsigned char subkey[8]) { - /* 32 bits */ - /* 48-bit key for this round */ - register unsigned long rval,rt; -#if DES_DEBUG - printf("f(%08lx, %02x %02x %02x %02x %02x %02x %02x %02x) = ", - r, - subkey[0], subkey[1], subkey[2], - subkey[3], subkey[4], subkey[5], - subkey[6], subkey[7]); -#endif - /* Run E(R) ^ K through the combined S & P boxes - * This code takes advantage of a convenient regularity in - * E, namely that each group of 6 bits in E(R) feeding - * a single S-box is a contiguous segment of R. - */ - rt = (r >> 1) | ((r & 1) ? 0x80000000 : 0); - rval = 0; - rval |= sp[0][((rt >> 26) ^ *subkey++) & 0x3f]; - rval |= sp[1][((rt >> 22) ^ *subkey++) & 0x3f]; - rval |= sp[2][((rt >> 18) ^ *subkey++) & 0x3f]; - rval |= sp[3][((rt >> 14) ^ *subkey++) & 0x3f]; - rval |= sp[4][((rt >> 10) ^ *subkey++) & 0x3f]; - rval |= sp[5][((rt >> 6) ^ *subkey++) & 0x3f]; - rval |= sp[6][((rt >> 2) ^ *subkey++) & 0x3f]; - rt = (r << 1) | ((r & 0x80000000) ? 1 : 0); - rval |= sp[7][(rt ^ *subkey) & 0x3f]; -#if DES_DEBUG - printf(" %08lx\n",rval); -#endif - return rval; -} - -/* Do one DES cipher round */ -static void round(desInst dinst, int num, unsigned long int *block) { - /* i.e. the num-th one */ - - /* The rounds are numbered from 0 to 15. On even rounds - * the right half is fed to f() and the result exclusive-ORs - * the left half; on odd rounds the reverse is done. - */ - if(num & 1){ - block[1] ^= f(block[0],dinst->kn[num]); - } else { - block[0] ^= f(block[1],dinst->kn[num]); - } -} - -/* Permute inblock with perm */ -static void permute(char *inblock, char perm[16][16][8], char *outblock) { - /* result into outblock,64 bits */ - /* 2K bytes defining perm. */ - register int i,j; - register char *ib, *ob; /* ptr to input or output block */ - register char *p, *q; - - if(perm == NULL){ - /* No permutation, just copy */ - for(i=8; i!=0; i--) - *outblock++ = *inblock++; - return; - } - /* Clear output block */ - for (i=8, ob = outblock; i != 0; i--) - *ob++ = 0; - - ib = inblock; - for (j = 0; j < 16; j += 2, ib++) { /* for each input nibble */ - ob = outblock; - p = perm[j][(*ib >> 4) & 017]; - q = perm[j + 1][*ib & 017]; - for (i = 8; i != 0; i--){ /* and each output byte */ - *ob++ |= *p++ | *q++; /* OR the masks together*/ - } - } -} -/* In-place encryption of 64-bit block */ -void endes(desInst dinst, char *block) { - register int i; - unsigned long work[2]; /* Working data storage */ - long tmp; - - permute(block,iperm,(char *)work); /* Initial Permutation */ -#ifdef __LITTLE_ENDIAN__ - work[0] = byteswap(work[0]); - work[1] = byteswap(work[1]); -#endif - - /* Do the 16 rounds */ - for (i=0; i<16; i++) - round(dinst,i,work); - - /* Left/right half swap */ - tmp = work[0]; - work[0] = work[1]; - work[1] = tmp; - -#ifdef __LITTLE_ENDIAN__ - work[0] = byteswap(work[0]); - work[1] = byteswap(work[1]); -#endif - permute((char *)work,fperm,block); /* Inverse initial permutation */ -} -/* In-place decryption of 64-bit block */ -void dedes(desInst dinst, char *block) { - register int i; - unsigned long work[2]; /* Working data storage */ - long tmp; - - permute(block,iperm,(char *)work); /* Initial permutation */ - -#ifdef __LITTLE_ENDIAN__ - work[0] = byteswap(work[0]); - work[1] = byteswap(work[1]); -#endif - - /* Left/right half swap */ - tmp = work[0]; - work[0] = work[1]; - work[1] = tmp; - - /* Do the 16 rounds in reverse order */ - for (i=15; i >= 0; i--) - round(dinst,i,work); - -#ifdef __LITTLE_ENDIAN__ - work[0] = byteswap(work[0]); - work[1] = byteswap(work[1]); -#endif - - permute((char *)work,fperm,block); /* Inverse initial permutation */ -} - -#endif /* CRYPTKIT_SYMMETRIC_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/ckDES.h b/OSX/libsecurity_cryptkit/lib/ckDES.h deleted file mode 100644 index 8f1da0a2..00000000 --- a/OSX/libsecurity_cryptkit/lib/ckDES.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * DES.h - raw DES encryption engine interface - * - * Revision History - * ---------------- - * 31 Mar 97 at Apple - * Put per-instance data in struct _desInst - * 21 Aug 96 at NeXT - * Broke out from NSDESCryptor.m - * 22 Feb 96 at NeXT - * Created. - */ - -#ifndef _CK_DES_H_ -#define _CK_DES_H_ - -#include "ckconfig.h" - -#if CRYPTKIT_SYMMETRIC_ENABLE - -#ifdef __cplusplus -extern "C" { -#endif - -#define DES_BLOCK_SIZE_BYTES 8 /* in bytes */ -#define DES_KEY_SIZE_BITS 56 /* effective key size in bits */ -#define DES_KEY_SIZE_BITS_EXTERNAL 64 /* clients actually pass in this much */ -#define DES_KEY_SIZE_BYTES_EXTERNAL (DES_KEY_SIZE_BITS_EXTERNAL / 8) - -#define DES_MODE_STD 0 /* standard Data Encryption Algorithm */ -#define DES_MODE_FAST 1 /* DEA without initial and final */ - /* permutations for speed */ -#define DES_MODE_128 2 /* DEA without permutations and with */ - /* 128-byte key (completely independent */ - /* subkeys for each round) */ - -/* - * Per-instance data. - */ -struct _desInst { - /* 8 16-bit subkeys for each of 16 rounds, initialized by setkey() - */ - unsigned char kn[16][8]; - int desmode; -}; - -typedef struct _desInst *desInst; - -int desinit(desInst dinst, int mode); -void dessetkey(desInst dinst, char *key); -void endes(desInst dinst, char *block); -void dedes(desInst dinst, char *block); -void desdone(desInst dinst); - -#ifdef __cplusplus -} -#endif - -#endif /* CRYPTKIT_SYMMETRIC_ENABLE */ - -#endif /*_CK_DES_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/ckMD5.c b/OSX/libsecurity_cryptkit/lib/ckMD5.c deleted file mode 100644 index 76f61d19..00000000 --- a/OSX/libsecurity_cryptkit/lib/ckMD5.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - File: MD5.c - - Written by: Colin Plumb - - Copyright: Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - - Change History (most recent first): - - <7> 10/06/98 ap Changed to compile with C++. - - To Do: -*/ - -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * MD5.c - */ - -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -/* - * Revision History - * ---------------- - * 06 Feb 1997 at Apple - * Fixed endian-dependent cast in MD5Final() - * Made byteReverse() tolerant of platform-dependent alignment - * restrictions - */ - -#include "ckconfig.h" - -#if CRYPTKIT_MD5_ENABLE && !CRYPTKIT_LIBMD_DIGEST - -#include "ckMD5.h" -#include "platform.h" -#include "byteRep.h" -#include - - -#define MD5_DEBUG 0 - -#if MD5_DEBUG -static inline void dumpCtx(MD5Context *ctx, char *label) -{ - int i; - - printf("%s\n", label); - printf("buf = "); - for(i=0; i<4; i++) { - printf("%x:", ctx->buf[i]); - } - printf("\nbits: %d:%d\n", ctx->bits[0], ctx->bits[1]); - printf("in[]:\n "); - for(i=0; i<64; i++) { - printf("%02x:", ctx->in[i]); - if((i % 16) == 15) { - printf("\n "); - } - } - printf("\n"); -} -#else // MD5_DEBUG -#define dumpCtx(ctx, label) -#endif // MD5_DEBUG - -static void MD5Transform(UINT32 buf[4], UINT32 const in[16]); - -#if __LITTLE_ENDIAN__ -#define byteReverse(buf, len) /* Nothing */ -#else -static void byteReverse(unsigned char *buf, unsigned longs); - -#ifndef ASM_MD5 -/* - * Note: this code is harmless on little-endian machines. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ -#if old_way - /* - * this code is NOT harmless on big-endian machine which require - * natural alignment. - */ - UINT32 t; - do { - t = (UINT32) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(UINT32 *) buf = t; - buf += 4; - } while (--longs); -#else // new_way - - unsigned char t; - do { - t = buf[0]; - buf[0] = buf[3]; - buf[3] = t; - t = buf[1]; - buf[1] = buf[2]; - buf[2] = t; - buf += 4; - } while (--longs); -#endif // old_way -} -#endif // ASM_MD5 -#endif // __LITTLE_ENDIAN__ - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Init(MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned len) -{ - UINT32 t; - - dumpCtx(ctx, "MD5.c update top"); - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((UINT32) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (UINT32 *) ctx->in); - dumpCtx(ctx, "update - return from transform (1)"); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (UINT32 *) ctx->in); - dumpCtx(ctx, "update - return from transform (2)"); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Final(MD5Context *ctx, unsigned char *digest) -{ - unsigned count; - unsigned char *p; - - dumpCtx(ctx, "final top"); - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - #if MD5_DEBUG - printf("in[%d] = %x\n", count, ctx->in[count]); - #endif - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - dumpCtx(ctx, "final, before pad"); - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - bzero(p, count); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (UINT32 *) ctx->in); - - /* Now fill the next block with 56 bytes */ - bzero(ctx->in, 56); - } else { - /* Pad block to 56 bytes */ - bzero(p, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - #if old_way - /* - * On a little endian machine, this writes the l.s. byte of - * the bit count to ctx->in[56] and the m.s byte of the bit count to - * ctx->in[63]. - */ - ((UINT32 *) ctx->in)[14] = ctx->bits[0]; - ((UINT32 *) ctx->in)[15] = ctx->bits[1]; - #else // new_way - intToByteRep(ctx->bits[0], &ctx->in[56]); - intToByteRep(ctx->bits[1], &ctx->in[60]); - #endif // new_way - - dumpCtx(ctx, "last transform"); - MD5Transform(ctx->buf, (UINT32 *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, MD5_DIGEST_SIZE); - dumpCtx(ctx, "final end"); - - bzero(ctx, sizeof(*ctx)); /* In case it's sensitive */ -} - -#ifndef ASM_MD5 - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void MD5Transform(UINT32 buf[4], UINT32 const in[16]) -{ - register UINT32 a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -#endif /* ASM_MD5 */ - -#endif /* CRYPTKIT_MD5_ENABLE && CRYPTKIT_LIBMD_DIGEST */ diff --git a/OSX/libsecurity_cryptkit/lib/ckMD5.h b/OSX/libsecurity_cryptkit/lib/ckMD5.h index a4833b37..9bfb2cf8 100644 --- a/OSX/libsecurity_cryptkit/lib/ckMD5.h +++ b/OSX/libsecurity_cryptkit/lib/ckMD5.h @@ -31,9 +31,6 @@ #include "ckconfig.h" -#if CRYPTKIT_MD5_ENABLE -#if CRYPTKIT_LIBMD_DIGEST - /* * In this case we use the MD5 implementation in libSystem. */ @@ -47,44 +44,4 @@ typedef CC_MD5_CTX MD5Context; #define MD5_DIGEST_SIZE CC_MD5_DIGEST_LENGTH -#else /* ! CRYPTKIT_LIBMD_DIGEST */ - -/* Our own private implementation */ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __alpha -typedef unsigned int UINT32; -#elif defined (macintosh) || defined (__ppc__) -typedef unsigned int UINT32; -#else -typedef unsigned long UINT32; -#endif - -typedef struct { - UINT32 buf[4]; - UINT32 bits[2]; // bits[0] is low 32 bits of bit count - unsigned char in[64]; -} MD5Context; - -#define MD5_DIGEST_SIZE 16 /* in bytes */ - -void MD5Init(MD5Context *context); -void MD5Update(MD5Context *context, unsigned char const *buf, - unsigned len); -void MD5Final(MD5Context *context, unsigned char *digest); - -/* - * This is needed to make RSAREF happy on some MS-DOS compilers. - */ -typedef MD5Context MD5_CTX; - -#ifdef __cplusplus -} -#endif - -#endif /* CRYPTKIT_LIBMD_DIGEST */ -#endif /* CRYPTKIT_MD5_ENABLE */ #endif /*_CK_MD5_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/ckSHA1.c b/OSX/libsecurity_cryptkit/lib/ckSHA1.c index 94a20a6a..ee7ffff0 100644 --- a/OSX/libsecurity_cryptkit/lib/ckSHA1.c +++ b/OSX/libsecurity_cryptkit/lib/ckSHA1.c @@ -22,18 +22,13 @@ #include "feeTypes.h" #include "ckSHA1.h" -#if CRYPTKIT_LIBMD_DIGEST /* * For linking with AppleCSP: use libSystem SHA1 implementation. */ #include -#else -#include "ckSHA1_priv.h" -#endif #include "falloc.h" #include "platform.h" -#if CRYPTKIT_LIBMD_DIGEST /* * Trivial wrapper for SHA_CTX; a sha1Obj is a pointer to this. */ @@ -82,146 +77,3 @@ unsigned sha1DigestLen(void) return CC_SHA1_DIGEST_LENGTH; } -#else /* standalone cryptkit implementation */ - -/* - * Private data for this object. A sha1Obj handle is cast to a pointer - * to one of these. - */ -typedef struct { - SHS_INFO context; - int isDone; - - /* - * For storing partial blocks - */ - BYTE dataBuf[SHS_BLOCKSIZE]; - unsigned bufBytes; // valid bytes in dataBuf[p] -} sha1Inst; - -/* - * Alloc and init an empty sha1 object. - */ -sha1Obj sha1Alloc(void) -{ - sha1Inst *sinst; - - sinst = (sha1Inst *)fmalloc(sizeof(sha1Inst)); - if(sinst == NULL) { - return NULL; - } - shsInit(&sinst->context); - sha1Reinit((sha1Obj)sinst); - return (sha1Obj)sinst; -} - -/* - * Reusable init function. - */ -void sha1Reinit(sha1Obj sha1) -{ - sha1Inst *sinst = (sha1Inst *) sha1; - - shsInit(&sinst->context); - sinst->isDone = 0; - sinst->bufBytes = 0; -} - -/* - * Free an sha1 object. - */ -void sha1Free(sha1Obj sha1) -{ - sha1Inst *sinst = (sha1Inst *) sha1; - - memset(sha1, 0, sizeof(sha1Inst)); - ffree(sinst); -} - -/* - * Add some data to the sha1 object. - */ -void sha1AddData(sha1Obj sha1, - const unsigned char *data, - unsigned dataLen) -{ - sha1Inst *sinst = (sha1Inst *) sha1; - unsigned toMove; - unsigned blocks; - - if(sinst->isDone) { - /* - * Log some kind of error here... - */ - return; - } - - /* - * First deal with partial buffered block - */ - if(sinst->bufBytes != 0) { - toMove = SHS_BLOCKSIZE - sinst->bufBytes; - if(toMove > dataLen) { - toMove = dataLen; - } - memmove(sinst->dataBuf+sinst->bufBytes, data, toMove); - data += toMove; - dataLen -= toMove; - sinst->bufBytes += toMove; - if(sinst->bufBytes == SHS_BLOCKSIZE) { - shsUpdate(&sinst->context, sinst->dataBuf, SHS_BLOCKSIZE); - sinst->bufBytes = 0; - } - } - - /* - * Now the bulk of the data, in a multiple of full blocks - */ - blocks = dataLen / SHS_BLOCKSIZE; - toMove = blocks * SHS_BLOCKSIZE; - if(toMove != 0) { - shsUpdate(&sinst->context, data, toMove); - data += toMove; - dataLen -= toMove; - } - - /* - * Store any remainder in dataBuf - */ - if(dataLen != 0) { - memmove(sinst->dataBuf, data, dataLen); - sinst->bufBytes = dataLen; - } -} - -/* - * Obtain a pointer to completed message digest, and the length of the digest. - */ -unsigned char *sha1Digest(sha1Obj sha1) -{ - sha1Inst *sinst = (sha1Inst *) sha1; - - if(!sinst->isDone) { - /* - * Deal with partial resid block - */ - if(sinst->bufBytes != 0) { - shsUpdate(&sinst->context, sinst->dataBuf, - sinst->bufBytes); - sinst->bufBytes = 0; - } - shsFinal(&sinst->context); - sinst->isDone = 1; - } - /* - * FIXME - should do explicit conversion to char array....? - */ - return (unsigned char *)sinst->context.digest; -} - -unsigned sha1DigestLen(void) -{ - return SHS_DIGESTSIZE; -} - -#endif /* CRYPTKIT_LIBMD_DIGEST */ diff --git a/OSX/libsecurity_cryptkit/lib/ckSHA1_priv.c b/OSX/libsecurity_cryptkit/lib/ckSHA1_priv.c deleted file mode 100644 index 4ea15ae0..00000000 --- a/OSX/libsecurity_cryptkit/lib/ckSHA1_priv.c +++ /dev/null @@ -1,321 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * ckSHA1_priv.c - low-level SHA-1 hash algorithm. - * - * Revision History - * ---------------- - * 05 Jan 1998 at Apple - * Created, based on source by Peter C. Gutmann. - * Mods: made reentrant, added NIST fix to expand(), eliminated - * unnecessary copy to local W[] array. - */ - - -/* NIST proposed Secure Hash Standard. - - Written 2 September 1992, Peter C. Gutmann. - This implementation placed in the public domain. - - Comments to pgut1@cs.aukuni.ac.nz */ - -#include "ckconfig.h" - -#if !CRYPTKIT_LIBMD_DIGEST - -#include "ckSHA1_priv.h" -#include "platform.h" -#include - -/* The SHS f()-functions */ - -#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) /* Rounds 0-19 */ -#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */ -#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) /* Rounds 40-59 */ -#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */ - -/* The SHS Mysterious Constants */ - -#define K1 0x5A827999L /* Rounds 0-19 */ -#define K2 0x6ED9EBA1L /* Rounds 20-39 */ -#define K3 0x8F1BBCDCL /* Rounds 40-59 */ -#define K4 0xCA62C1D6L /* Rounds 60-79 */ - -/* SHS initial values */ - -#define h0init 0x67452301L -#define h1init 0xEFCDAB89L -#define h2init 0x98BADCFEL -#define h3init 0x10325476L -#define h4init 0xC3D2E1F0L - -/* 32-bit rotate - kludged with shifts */ - -#define S(n,X) ( ( X << n ) | ( X >> ( 32 - n ) ) ) - -/* The initial expanding function */ - -/* - * 06 Jan 1998. Added left circular shift per NIST FIPS-180-1 (at - * http://www.nist.gov/itl/div897/pubs/fip180-1.htm). Also see - * B. Schneier, Applied Cryptography, Second Edition, section 18.7 - * for info on this addenda to the original NIST spec. - */ -#define expand(count) { \ - W[count] = W[count - 3] ^ W[count - 8] ^ W[count - 14] ^ W[count - 16]; \ - W[count] = S(1, W[count]); \ -} - -/* The four SHS sub-rounds */ - -#define subRound1(count) \ - { \ - temp = S( 5, A ) + f1( B, C, D ) + E + W[ count ] + K1; \ - E = D; \ - D = C; \ - C = S( 30, B ); \ - B = A; \ - A = temp; \ - } - -#define subRound2(count) \ - { \ - temp = S( 5, A ) + f2( B, C, D ) + E + W[ count ] + K2; \ - E = D; \ - D = C; \ - C = S( 30, B ); \ - B = A; \ - A = temp; \ - } - -#define subRound3(count) \ - { \ - temp = S( 5, A ) + f3( B, C, D ) + E + W[ count ] + K3; \ - E = D; \ - D = C; \ - C = S( 30, B ); \ - B = A; \ - A = temp; \ - } - -#define subRound4(count) \ - { \ - temp = S( 5, A ) + f4( B, C, D ) + E + W[ count ] + K4; \ - E = D; \ - D = C; \ - C = S( 30, B ); \ - B = A; \ - A = temp; \ - } - -/* Initialize the SHS values */ - -void shsInit( SHS_INFO *shsInfo ) - { - /* Set the h-vars to their initial values */ - shsInfo->digest[ 0 ] = h0init; - shsInfo->digest[ 1 ] = h1init; - shsInfo->digest[ 2 ] = h2init; - shsInfo->digest[ 3 ] = h3init; - shsInfo->digest[ 4 ] = h4init; - - /* Initialise bit count */ - shsInfo->countLo = shsInfo->countHi = 0L; - } - -/* Perform the SHS transformation. Note that this code, like MD5, seems to - break some optimizing compilers - it may be necessary to split it into - sections, eg based on the four subrounds */ - -static void shsTransform( SHS_INFO *shsInfo ) -{ - LONG *W, temp; - LONG A, B, C, D, E; - - /* Step A. Copy the data buffer into the local work buffer. */ - /* 07 Jan 1998, dmitch: skip this bogus move, and let the caller - * copy data directly into the W[] array. To minimize changes, - * we'll just increase the size of shsInfo->data[] and make W - * a pointer here. - */ - W = shsInfo->data; - - /* Step B. Expand the 16 words into 64 temporary data words */ - - /* - * Note: I tried optimizing this via a for loop, and for some reason, - * the "optimized" version ran slower on PPC than the original - * unrolled version. The optimized version does run faster on i486 than - * the unrolled version. - * - * Similarly, the set of subRounds, below, runs slower on i486 when - * optimized via 4 'for' loops. The "optimized" version of that is - * a wash on PPC. - * - * Conclusion: leave both of 'em unrolled. We could ifdef per machine, - * but this would get messy once we had more than two architectures. - * We may want to revisit this. --dpm - */ - expand( 16 ); expand( 17 ); expand( 18 ); expand( 19 ); expand( 20 ); - expand( 21 ); expand( 22 ); expand( 23 ); expand( 24 ); expand( 25 ); - expand( 26 ); expand( 27 ); expand( 28 ); expand( 29 ); expand( 30 ); - expand( 31 ); expand( 32 ); expand( 33 ); expand( 34 ); expand( 35 ); - expand( 36 ); expand( 37 ); expand( 38 ); expand( 39 ); expand( 40 ); - expand( 41 ); expand( 42 ); expand( 43 ); expand( 44 ); expand( 45 ); - expand( 46 ); expand( 47 ); expand( 48 ); expand( 49 ); expand( 50 ); - expand( 51 ); expand( 52 ); expand( 53 ); expand( 54 ); expand( 55 ); - expand( 56 ); expand( 57 ); expand( 58 ); expand( 59 ); expand( 60 ); - expand( 61 ); expand( 62 ); expand( 63 ); expand( 64 ); expand( 65 ); - expand( 66 ); expand( 67 ); expand( 68 ); expand( 69 ); expand( 70 ); - expand( 71 ); expand( 72 ); expand( 73 ); expand( 74 ); expand( 75 ); - expand( 76 ); expand( 77 ); expand( 78 ); expand( 79 ); - - /* Step C. Set up first buffer */ - A = shsInfo->digest[ 0 ]; - B = shsInfo->digest[ 1 ]; - C = shsInfo->digest[ 2 ]; - D = shsInfo->digest[ 3 ]; - E = shsInfo->digest[ 4 ]; - - /* Step D. Serious mangling, divided into four sub-rounds */ - subRound1( 0 ); subRound1( 1 ); subRound1( 2 ); subRound1( 3 ); - subRound1( 4 ); subRound1( 5 ); subRound1( 6 ); subRound1( 7 ); - subRound1( 8 ); subRound1( 9 ); subRound1( 10 ); subRound1( 11 ); - subRound1( 12 ); subRound1( 13 ); subRound1( 14 ); subRound1( 15 ); - subRound1( 16 ); subRound1( 17 ); subRound1( 18 ); subRound1( 19 ); - subRound2( 20 ); subRound2( 21 ); subRound2( 22 ); subRound2( 23 ); - subRound2( 24 ); subRound2( 25 ); subRound2( 26 ); subRound2( 27 ); - subRound2( 28 ); subRound2( 29 ); subRound2( 30 ); subRound2( 31 ); - subRound2( 32 ); subRound2( 33 ); subRound2( 34 ); subRound2( 35 ); - subRound2( 36 ); subRound2( 37 ); subRound2( 38 ); subRound2( 39 ); - subRound3( 40 ); subRound3( 41 ); subRound3( 42 ); subRound3( 43 ); - subRound3( 44 ); subRound3( 45 ); subRound3( 46 ); subRound3( 47 ); - subRound3( 48 ); subRound3( 49 ); subRound3( 50 ); subRound3( 51 ); - subRound3( 52 ); subRound3( 53 ); subRound3( 54 ); subRound3( 55 ); - subRound3( 56 ); subRound3( 57 ); subRound3( 58 ); subRound3( 59 ); - subRound4( 60 ); subRound4( 61 ); subRound4( 62 ); subRound4( 63 ); - subRound4( 64 ); subRound4( 65 ); subRound4( 66 ); subRound4( 67 ); - subRound4( 68 ); subRound4( 69 ); subRound4( 70 ); subRound4( 71 ); - subRound4( 72 ); subRound4( 73 ); subRound4( 74 ); subRound4( 75 ); - subRound4( 76 ); subRound4( 77 ); subRound4( 78 ); subRound4( 79 ); - - /* Step E. Build message digest */ - shsInfo->digest[ 0 ] += A; - shsInfo->digest[ 1 ] += B; - shsInfo->digest[ 2 ] += C; - shsInfo->digest[ 3 ] += D; - shsInfo->digest[ 4 ] += E; -} - -/* __LITTLE_ENDIAN__ is in fact #defined on OS X on PPC.... */ -//#ifdef __LITTLE_ENDIAN__ -#if 0 - -/* When run on a little-endian CPU we need to perform byte reversal on an - array of longwords. It is possible to make the code endianness- - independant by fiddling around with data at the byte level, but this - makes for very slow code, so we rely on the user to sort out endianness - at compile time */ - -static void byteReverse( buffer, byteCount ) - LONG *buffer; - int byteCount; - - { - LONG value; - int count; - - byteCount /= sizeof( LONG ); - for( count = 0; count < byteCount; count++ ) - { - value = ( buffer[ count ] << 16 ) | ( buffer[ count ] >> 16 ); - buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 ); - } - } - -#else /* __LITTLE_ENDIAN__ */ - -/* - * Nop for big-endian machines - */ -#define byteReverse( buffer, byteCount ) - -#endif /* __LITTLE_ENDIAN__ */ - - -/* Update SHS for a block of data. This code assumes that the buffer size - is a multiple of SHS_BLOCKSIZE bytes long, which makes the code a lot - more efficient since it does away with the need to handle partial blocks - between calls to shsUpdate() */ - -void shsUpdate( - SHS_INFO *shsInfo, - const BYTE *buffer, - int count) - - { - /* Update bitcount */ - if( ( shsInfo->countLo + ( ( LONG ) count << 3 ) ) < shsInfo->countLo ) - shsInfo->countHi++; /* Carry from low to high bitCount */ - shsInfo->countLo += ( ( LONG ) count << 3 ); - shsInfo->countHi += ( ( LONG ) count >> 29 ); - - /* Process data in SHS_BLOCKSIZE chunks */ - while( count >= SHS_BLOCKSIZE ) - { - memcpy( shsInfo->data, buffer, SHS_BLOCKSIZE ); - byteReverse( shsInfo->data, SHS_BLOCKSIZE ); - shsTransform( shsInfo ); - buffer += SHS_BLOCKSIZE; - count -= SHS_BLOCKSIZE; - } - - /* Handle any remaining bytes of data. This should only happen once - on the final lot of data */ - memcpy( shsInfo->data, buffer, count ); - } - -void shsFinal(SHS_INFO *shsInfo) - { - int count; - LONG lowBitcount = shsInfo->countLo, highBitcount = shsInfo->countHi; - - /* Compute number of bytes mod 64 */ - count = ( int ) ( ( shsInfo->countLo >> 3 ) & 0x3F ); - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - ( ( BYTE * ) shsInfo->data )[ count++ ] = 0x80; - - /* Pad out to 56 mod 64 */ - if( count > 56 ) - { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset( ( BYTE * ) &shsInfo->data + count, 0, 64 - count ); - byteReverse( shsInfo->data, SHS_BLOCKSIZE ); - shsTransform( shsInfo ); - - /* Now fill the next block with 56 bytes */ - memset( &shsInfo->data, 0, 56 ); - } - else - /* Pad block to 56 bytes */ - memset( ( BYTE * ) &shsInfo->data + count, 0, 56 - count ); - byteReverse( shsInfo->data, SHS_BLOCKSIZE ); - - /* Append length in bits and transform */ - shsInfo->data[ 14 ] = highBitcount; - shsInfo->data[ 15 ] = lowBitcount; - - shsTransform( shsInfo ); - byteReverse( shsInfo->data, SHS_DIGESTSIZE ); - } - -#endif /* CRYPTKIT_LIBMD_DIGEST */ diff --git a/OSX/libsecurity_cryptkit/lib/ckSHA1_priv.h b/OSX/libsecurity_cryptkit/lib/ckSHA1_priv.h deleted file mode 100644 index 05cb9cb6..00000000 --- a/OSX/libsecurity_cryptkit/lib/ckSHA1_priv.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * ckSHA1_priv.h - private low-level API for SHA-1 hash algorithm - * - * Revision History - * ---------------- - * 22 Aug 96 at NeXT - * Created. - */ - -/* Useful defines/typedefs */ - -#ifndef _CK_SHA1_PRIV_H_ -#define _CK_SHA1_PRIV_H_ - -#include "ckconfig.h" - -#if !CRYPTKIT_LIBMD_DIGEST - -#ifdef __cplusplus -extern "C" { -#endif - -typedef unsigned char BYTE; -typedef unsigned long LONG; - -/* The SHS block size and message digest sizes, in bytes */ - -#define SHS_BLOCKSIZE 64 -#define SHS_DIGESTSIZE 20 - -/* The structure for storing SHS info */ - -typedef struct { - LONG digest[ 5 ]; /* Message digest */ - LONG countLo, countHi; /* 64-bit bit count */ - LONG data[ 80 ]; /* SHS data buffer */ - } SHS_INFO; - -extern void shsInit(SHS_INFO *shsInfo); -extern void shsUpdate(SHS_INFO *shsInfo, - const BYTE *buffer, - int count); -extern void shsFinal(SHS_INFO *shsInfo); - -#ifdef __cplusplus -} -#endif - -#endif /* !CRYPTKIT_LIBMD_DIGEST */ - -#endif /* _CK_SHA1_PRIV_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/ckconfig.h b/OSX/libsecurity_cryptkit/lib/ckconfig.h index c1737ea6..73662911 100644 --- a/OSX/libsecurity_cryptkit/lib/ckconfig.h +++ b/OSX/libsecurity_cryptkit/lib/ckconfig.h @@ -33,69 +33,30 @@ */ #define DEBUG_ENGINE 0 -#define ENGINE_127_BITS 0 /* hard-coded 127 elliptic() */ - /* - * These flags are set en masse, one set per target in the XCode project file or - * Makefile. They determine what gets compiled into the library. Every flag - * has to be defined for every configureation - preprocessors directives use - * #if, not #ifdef. + * These CK_*_BUILD options used to control feature flags for different build strategies. As we + * only build in Security.framework (AppleCSP) these days, code not needed for this use case has been removed. + * For posterity, the feature flags of CK_SECURITY_BUILD will be described below. */ #ifdef CK_SECURITY_BUILD /* * Standard Security.framework build + +#define CRYPTKIT_DER_ENABLE 1 // DER encoding support +#define CRYPTKIT_LIBMD_DIGEST 1 // use CommonCrypto digests +#define CRYPTKIT_ELL_PROJ_ENABLE 1 // elliptic projection +#define CRYPTKIT_ECDSA_ENABLE 1 // ECDSA (requires ELL_PROJ_ENABLE) +#define CRYPTKIT_CIPHERFILE_ENABLE 0 // cipherfile w/symmetric encryption +#define CRYPTKIT_SYMMETRIC_ENABLE 0 // symmetric encryption +#define CRYPTKIT_ASYMMETRIC_ENABLE 1 // asymmetric encryption +#define CRYPTKIT_MD5_ENABLE 1 // MD5 hash +#define CRYPTKIT_SHA1_ENABLE 1 // SHA1 hash - needed for GHMAX_LEGACY +#define CRYPTKIT_HMAC_LEGACY 1 +#define CRYPTKIT_KEY_EXCHANGE 0 // FEE key exchange +#define CRYPTKIT_HIGH_LEVEL_SIG 0 // high level one-shot signature +#define CRYPTKIT_GIANT_STACK_ENABLE 0 // cache of giants */ -#define CRYPTKIT_DER_ENABLE 1 /* DER encoding support */ -#define CRYPTKIT_LIBMD_DIGEST 1 /* use CommonCrypto digests */ -#define CRYPTKIT_ELL_PROJ_ENABLE 1 /* elliptic projection */ -#define CRYPTKIT_ECDSA_ENABLE 1 /* ECDSA (requires ELL_PROJ_ENABLE) */ -#define CRYPTKIT_CIPHERFILE_ENABLE 0 /* cipherfile w/symmetric encryption */ -#define CRYPTKIT_SYMMETRIC_ENABLE 0 /* symmetric encryption */ -#define CRYPTKIT_ASYMMETRIC_ENABLE 1 /* asymmetric encryption */ -#define CRYPTKIT_MD5_ENABLE 1 /* MD5 hash */ -#define CRYPTKIT_SHA1_ENABLE 1 /* SHA1 hash - needed for GHMAX_LEGACY */ -#define CRYPTKIT_HMAC_LEGACY 1 -#define CRYPTKIT_KEY_EXCHANGE 0 /* FEE key exchange */ -#define CRYPTKIT_HIGH_LEVEL_SIG 0 /* high level one-shot signature */ -#define CRYPTKIT_GIANT_STACK_ENABLE 0 /* cache of giants */ - -#elif defined(CK_STANDALONE_BUILD) -/* - * Standalone library build - */ -#define CRYPTKIT_DER_ENABLE 0 -#define CRYPTKIT_LIBMD_DIGEST 0 -#define CRYPTKIT_ELL_PROJ_ENABLE 1 -#define CRYPTKIT_ECDSA_ENABLE 1 -#define CRYPTKIT_CIPHERFILE_ENABLE 1 -#define CRYPTKIT_SYMMETRIC_ENABLE 1 -#define CRYPTKIT_ASYMMETRIC_ENABLE 1 -#define CRYPTKIT_MD5_ENABLE 1 -#define CRYPTKIT_SHA1_ENABLE 1 -#define CRYPTKIT_HMAC_LEGACY 0 -#define CRYPTKIT_KEY_EXCHANGE 1 -#define CRYPTKIT_HIGH_LEVEL_SIG 1 -#define CRYPTKIT_GIANT_STACK_ENABLE 1 - -#elif defined(CK_MINIMUM_SIG_BUILD) -/* - * Standalone, just ElGamal signature and key generation - */ -#define CRYPTKIT_DER_ENABLE 0 -#define CRYPTKIT_LIBMD_DIGEST 0 -#define CRYPTKIT_ELL_PROJ_ENABLE 0 -#define CRYPTKIT_ECDSA_ENABLE 0 -#define CRYPTKIT_CIPHERFILE_ENABLE 0 -#define CRYPTKIT_SYMMETRIC_ENABLE 0 -#define CRYPTKIT_ASYMMETRIC_ENABLE 0 -#define CRYPTKIT_MD5_ENABLE 1 -/* FIXME convert native ElGamal to use SHA1! */ -#define CRYPTKIT_SHA1_ENABLE 0 -#define CRYPTKIT_HMAC_LEGACY 0 -#define CRYPTKIT_KEY_EXCHANGE 0 -#define CRYPTKIT_HIGH_LEVEL_SIG 0 -#define CRYPTKIT_GIANT_STACK_ENABLE 1 #else diff --git a/OSX/libsecurity_cryptkit/lib/ckutilities.c b/OSX/libsecurity_cryptkit/lib/ckutilities.c index 7ed0beea..6a40a06f 100644 --- a/OSX/libsecurity_cryptkit/lib/ckutilities.c +++ b/OSX/libsecurity_cryptkit/lib/ckutilities.c @@ -86,9 +86,6 @@ static const frtnItem frtnStrings[] = { */ void initCryptKit(void) { - #if GIANTS_VIA_STACK - curveParamsInitGiants(); - #endif } /* @@ -96,9 +93,6 @@ void initCryptKit(void) */ void terminateCryptKit(void) { - #if GIANTS_VIA_STACK - freeGiantStacks(); - #endif } /* @@ -265,41 +259,6 @@ void printCurveParams(const curveParams *p) {} #endif /* FEE_DEBUG */ -#if defined(NeXT) && !defined(WIN32) - -void getpassword(const char *prompt, char *pbuf) -{ - struct sgttyb ttyb; - int flags; - register char *p; - register int c; - FILE *fi; - void (*sig)(int); - - if ((fi = fdopen(open("/dev/tty", 2, 0), "r")) == NULL) - fi = stdin; - else - setbuf(fi, (char *)NULL); - sig = signal(SIGINT, SIG_IGN); - ioctl(fileno(fi), TIOCGETP, &ttyb); - flags = ttyb.sg_flags; - ttyb.sg_flags &= ~ECHO; - ioctl(fileno(fi), TIOCSETP, &ttyb); - fprintf(stderr, "%s", prompt); fflush(stderr); - for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) { - if (p < &pbuf[PHRASELEN-1]) - *p++ = c; - } - *p = '\0'; - fprintf(stderr, "\n"); fflush(stderr); - ttyb.sg_flags = flags; - ioctl(fileno(fi), TIOCSETP, &ttyb); - (void)signal(SIGINT, sig); - if (fi != stdin) - fclose(fi); -} -#endif // NeXT - /* * serialize, deserialize giants's n[] to/from byte stream. * First byte of byte stream is the MS byte of the resulting giant, diff --git a/OSX/libsecurity_cryptkit/lib/curveParamDataOld.h b/OSX/libsecurity_cryptkit/lib/curveParamDataOld.h deleted file mode 100644 index 2b0c6fbf..00000000 --- a/OSX/libsecurity_cryptkit/lib/curveParamDataOld.h +++ /dev/null @@ -1,350 +0,0 @@ -/* - * curveParamDataOld.h - prototype FEE curve parameters (obsolete as of 4/9/2001) - */ -#warning Using obsolete curveParam data! -/* - * q = 31 k = 1, Weierstrass - * a = 7 b = 1 c = 0 - */ -static arrayDigit ga_w31_1_a[] = {1, 7}; -static arrayDigit ga_w31_1_x1Plus[] = - {2,15438,14404}; - /* 943995982 */ -static arrayDigit ga_w31_1_x1Minus[] = - {2, 10400, 19905}; - /* 1304504480 */ -static arrayDigit ga_w31_1_plusOrder[] = - {2, 3848, 32769}; - /* 2147553032 */ -static arrayDigit ga_w31_1_minusOrder[] = - {2, 61688, 32766 }; - /* 2147414264 */ -static arrayDigit ga_w31_1_x1OrderPlus[] = - {2, 8673, 4096}; - /* 268444129 */ -static arrayDigit ga_w31_1_x1OrderMinus[] = - {2, 56863, 4095 }; - /* 268426783 */ -static arrayDigit ga_w31_1_x1OrderPlusRecip[] = - {2, 30845, 16383}; -static arrayDigit ga_w31_1_lesserX1OrderRecip[] = - {2, 8673, 4096}; - -/* - * q = 31 k = 1, Montgomery - * a = 1 b = 0 c = 666 - */ -static arrayDigit ga_m31_1_x1Plus[] = - {2, 61780, 6237}; - /* 408809812 */ -static arrayDigit ga_m31_1_x1Minus[] = - {2,12973,30585}; - /* 2004431533 */ -static arrayDigit ga_m31_1_plusOrder[] = - {2, 25928, 32768 }; - /* 2147509576 */ -static arrayDigit ga_m31_1_minusOrder[] = - {2, 39608, 32767 }; - /* 2147457720 */ -static arrayDigit ga_m31_1_x1OrderPlus[] = - {2, 3241, 4096}; - /* 268438697 */ -static arrayDigit ga_m31_1_x1OrderMinus[] = - {2, 4153, 273}; - /* 17895481 */ -static arrayDigit ga_m31_1_x1OrderPlusRecip[] = - {2, 52572, 16383}; -static arrayDigit ga_m31_1_lesserX1OrderRecip[] = - {2, 759, 960}; - -/* - * q = 31 k = 1, Montgomery, prime curve orders - * a = 5824692 b = 2067311435 c = 0 - */ -static arrayDigit ga_31_1P_x1Plus[] = - {1, 6 }; -static arrayDigit ga_31_1P_x1Minus[] = - {1, 7 }; -static arrayDigit ga_31_1P_plusOrder[] = - {2,59003,32766 }; - /* 2147411579 */ -static arrayDigit ga_31_1P_minusOrder[] = - {2,6533,32769 }; - /* 2147555717 */ -static arrayDigit ga_31_1P_x1OrderPlus[] = - {2,59003,32766}; - /* 2147411579 */ -static arrayDigit ga_31_1P_x1OrderMinus[] = - {2,6533,32769}; - /* 2147555717 */ -static arrayDigit ga_31_1P_x1OrderPlusRecip[] = - {2, 6535, 32769}; - -static arrayDigit ga_31_1P_a[] = - {2,57524,88}; - /* 5824692 */ -static arrayDigit ga_31_1P_b[] = - {2,43851,31544}; - /* 2067311435 */ - -/* - * q = 40 k = 213, Weierstrass - * a = 1627500953 b = 523907505 c = 0 - */ -static arrayDigit ga_40_213_x1Plus[] = - {1, 1 }; -static arrayDigit ga_40_213_x1Minus[] = - {1, 2 }; -static arrayDigit ga_40_213_plusOrder[] = - {3,11655,25,256}; - /* 1099513277831 */ -static arrayDigit ga_40_213_minusOrder[] = - {3,53457,65510,255}; - /* 1099509977297 */ -static arrayDigit ga_40_213_x1OrderPlus[] = - {3,11655,25,256}; - /* 1099513277831 */ -static arrayDigit ga_40_213_x1OrderMinus[] = - {3,53457,65510,255}; - /* 1099509977297 */ -static arrayDigit ga_40_213_x1OrderPlusRecip[] = - {3, 18925, 65435, 1023}; -static arrayDigit ga_40_213_lesserX1OrderRecip[] = - {3, 12081, 25, 256}; - -static arrayDigit ga_40_213_a[] = - {2,45465,24833}; - /* 1627500953 */ -static arrayDigit ga_40_213_b[] = - {2,12721,7994}; - /* 523907505 */ - -/* - * q = 127 k = 1 - * a = 1 b = 0 c = 666 - */ -static arrayDigit ga_127_1_x1Plus[] = - {8, 24044, 39922, 11050, - 24692, 34049, 9793, 1228, 31562}; - /* 163879370753099435779911346846180728300 */ -static arrayDigit ga_127_1_x1Minus[] = - {8,49015,6682,26772,63672,45560,46133,24769,8366}; - /* 43440717976631899041527862406676135799 */ -static arrayDigit ga_127_1_plusOrder[] = - { 8, 14612, 61088, 34331, - 32354, 65535, 65535, 65535, - 32767}; - /* 170141183460469231722347548493196835092 */ -static arrayDigit ga_127_1_minusOrder[] = - { 8, 50924, 4447, 31204, - 33181, 0, 0, 0, - 32768 }; - /* 170141183460469231741027058938571376364 */ -static arrayDigit ga_127_1_x1OrderPlus[] = - {6, 8201, 61942, 37082, - 53787, 49605, 7887 }; - /* 9535713005180210505588285449 */ -static arrayDigit ga_127_1_x1OrderMinus[] = - {6, 14659, 1977,16924, - 7446, 49030, 1}; - /* 2113371777483973234080067 */ -static arrayDigit ga_127_1_x1OrderPlusRecip[] = - {6, 21911, 8615, 0, 40960, 64107, 8507}; -static arrayDigit ga_127_1_lesserX1OrderRecip[] = - {6, 44759, 65533, 17695, 61560, 18883, 2}; - -/* - * This is only used for the FEE_DEPTH_127_GEN (FPT_General) case. - */ -static arrayDigit ga_127_1_bp[] = - {8, 65535, 65535, 65535, 65535, 65535, 65535, 65535, 32767}; - -/* - * q = 127 k = 1, Weierstrass - * a = 666 b = 1 c = 0 - */ -static arrayDigit ga_127_1W_x1Plus[] = - {8, 8152, 12974, 29415, - 29630, 64916, 34821, 65368, - 29317}; - /* 152227746030289977478827896983637598168 */ -static arrayDigit ga_127_1W_x1Minus[] = - {8, 33297, 13207, 15262, - 22815, 21569, 49926, 18455, - 22807}; - /* 118422176668700242826570137796135584273 */ -static arrayDigit ga_127_1W_plusOrder[] = - {8, 7568, 62409, 28235, - 47403, 65534, 65535, 65535, - 32767 }; - /* 170141183460469231708136695161971875216 - = 2 * 2 * 2 * 2 * 11 * 17 * 47 * 103 * 10861 * - 1081540940469355570836125423 */ -static arrayDigit ga_127_1W_minusOrder[] = - {8, 57968, 3126,37300, 18132, 1, 0, 0, 32768 }; - /* 170141183460469231755237912269796336240 - = 2 * 2 * 2 * 2 * 3 * 5 * 19 * 34267 * - 1088851169917897274673487152937 */ -static arrayDigit ga_127_1W_x1OrderPlus[] = - { 6, 46831, 48825, 15584, 56652, 41267, 894 }; - /* 1081540940469355570836125423 */ -static arrayDigit ga_127_1W_x1OrderMinus[] = - {7, 1833, 34556, 10366, 60186, 37860, 48708, 13}; - /* 1088851169917897274673487152937 */ -static arrayDigit ga_127_1W_x1OrderPlusRecip[] = - {6, 48506, 2992, 0, 28160, 5127, 1172}; - -/* - * q = 160 k = 57 - * a = c = 0 b = 3 - */ -static arrayDigit ga_160_57_x1Plus[] = - {10,12520,51433,52060,51310,41288,18467,39861,56172,11574,31757}; - /* 708208703989516599321256243677211664634713026792 */ -static arrayDigit ga_160_57_x1Minus[] = - {10,40240,19544,56125,45242,10556,34052,10700,5155,57632,13213}; - /* 294679357488322649182890242541447794429265485104 */ -static arrayDigit ga_160_57_plusOrder[] = - {11,62853,63609,4196,64365,22452,1,0,0,0,0,1}; - /* 1461501637330902918203686455826517732113793021317 */ -static arrayDigit ga_160_57_minusOrder[] = - {10,2571,1926,61339,1170,43083,65534,65535,65535,65535,65535}; - /* 1461501637330902918203683209606048307198072064523 */ -static arrayDigit ga_160_57_x1OrderPlus[] = - {5,171,21451,35098,934,63868}; - /* 1178156913548056058331307 */ -static arrayDigit ga_160_57_x1OrderMinus[] = - {7,255,39523,10835,12387,25442,37088,9774}; - /* 774420897524543052406523561181439 */ -static arrayDigit ga_160_57_x1OrderPlusRecip[] = - {6, 49805, 35001, 38758, 35853, 1711, 1}; -static arrayDigit ga_160_57_b[] = {1, 3}; /* b = (giant)3 */ - -/* - * This is only used for the FEE_DEPTH_160_GEN (FPT_General) case. - */ -static arrayDigit ga_160_57_bp[] = - {10,65479,65535,65535,65535,65535,65535,65535,65535,65535,65535}; - /* 1461501637330902918203684832716283019655932542919 */ - - -/* - * q = 192 k = 1425 - * a = 0 b = -11 c = 0 - */ -static arrayDigit ga_192_1425_x1Plus[] = - {12, 44344, 60264, 44908, - 24163, 37728, 58781, 45290, - 62313, 45939, 59670, 20046, - 8781}; - /* 841082007613983662909216085212018592355989658924032240952 */ -static arrayDigit ga_192_1425_x1Minus[] = - {12,32855,61817,23700,48262,13770,23791,31597,23825,7973,37638, - 62245,25400}; - /* 2432927643133372385673335524462623851522707126886260637783 */ -static arrayDigit ga_192_1425_plusOrder[] = - {13, 7615, 52517, 60178, - 40906, 43135, 27853, 1, - 0, 0, 0, 0, 0, 1}; - /* 6277101735386680763835789423320567585182165941785488334271 */ -static arrayDigit ga_192_1425_minusOrder[] = - {12, 55073, 13018, 5357, - 24629, 22400, 37682, 65534, - 65535, 65535, 65535, 65535, - 65535}; - /* 6277101735386680763835789423094765247022544947142580688673 */ -static arrayDigit ga_192_1425_x1OrderPlus[] = - {11, 55217, 35908, 19375, - 13869, 14836, 18343, 39323, - 50251, 7215, 49984, 21171}; - /* 30942565846835947234516838572438382480699614724151217 */ -static arrayDigit ga_192_1425_x1OrderMinus[] = - {12, 42525, 5637, 42463, - 55864, 53758, 3234, 41914, - 27439, 9168, 44294, 64393, 2}; - /* 285673405333212613836790125294441598644816135581967901 */ -static arrayDigit ga_192_1425_x1OrderPlusRecip[] = - {11, 31243, 31728, 18067, - 25698, 58801, 65534, 65535, - 65535, 65535, 49151, 50715}; -static arrayDigit ga_192_1425_b[] = {-1, 11}; /* b = (giant)(-11) */ - -/* - * q = 192 k = -529891 - * a = -152 b = 722 c = 0 - */ -static arrayDigit ga_192_M529891_x1Plus[] = - {12, 27752, 118, 22193, - 28093, 63505, 16219, 38086, - 5777, 13552, 56652, 28149, - 56180}; - /* 5381016108938327910020782805833379575685074837329310805096 */ -static arrayDigit ga_192_M529891_x1Minus[] = - {12, 20031, 4376, 4872, - 24519, 24047, 14628, 60533, - 27380, 49464, 20541, 38806, - 59062}; - /* 5657072442654455186533371860713762559076927475376430009919 */ -static arrayDigit ga_192_M529891_plusOrder[] = - {13, 5604, 8, 0, - 0, 0, 0, 2, - 0, 0, 0, 0, - 0, 1}; - /* 6277101735386680763835789423366122741130884119651122943460 */ -static arrayDigit ga_192_M529891_minusOrder[] = - {12, 5604, 8, 0, - 0, 0, 0, 65534, - 65535, 65535, 65535, 65535, - 65535}; - /* 6277101735386680763835789423049210091073826769276947142116 */ -static arrayDigit ga_192_M529891_x1OrderPlus[] = - {12, 28623, 26214, 26214, - 26214, 26214, 58982, 16681, - 4766, 10724, 40513, 58386, - 297}; - /* 28532280615394003471980861015300557914231291452959649743 */ -static arrayDigit ga_192_M529891_x1OrderMinus[] = - {11, 18083, 10335, 12214, - 61896, 30741, 14099, 7255, - 33291, 27015, 23037, 196}; - /* 286968072376896521631921223217092198374509106906787 */ -static arrayDigit ga_192_M529891_x1OrderPlusRecip[] = - {12, 58420, 65535, 65535, - 65535, 65535, 63775, 65535, - 65535, 65535, 65535, 65535, 879}; -static arrayDigit ga_192_M529891_lesserX1OrderRecip[] = - {11, 65535, 65535, 65535, 35223, - 667, 0, 0, 0, 0, 50380, 333}; -static arrayDigit ga_192_M529891_a[] = {-1, 152}; /* a = -152 */ -static arrayDigit ga_192_M529891_b[] = { 1, 722}; /* b = 722 */ - -/* - * FPT_General, 161 bits - */ -static arrayDigit ga_161_gen_bp[] = - {11,41419,58349,36408,14563,25486,9098,29127,50972,7281,8647,1}; - /* baseprime = 1654338658923174831024422729553880293604080853451 */ -static arrayDigit ga_161_gen_x1Plus[] = - {10,59390,38748,49144,50217,32781,46057,53816,62856,18968,55868}; - /* 1245904487553815885170631576005220733978383542270 */ -static arrayDigit ga_161_gen_x1Minus[] = - {10,62588,37264,57758,58571,20023,11302,61317,50155,46534,18610}; - /* 415032703104741702601157337572231150005648422012 */ -static arrayDigit ga_161_gen_plusOrder[] = - {11,41420,58349,36408,14563,25486,9100,29127,50972,7281,8647,1}; - /* 1654338658923174831024425147405519522862430265804 */ -static arrayDigit ga_161_gen_minusOrder[] = - {11,41420,58349,36408,14563,25486,9096,29127,50972,7281,8647,1}; - /* 1654338658923174831024420311702241064345731441100 */ -static arrayDigit ga_161_gen_x1OrderPlus[] = - {8,59671,64703,58305,55887,34170,37971,15627,197}; - /* 1024120625531724089187207582052247831 */ -static arrayDigit ga_161_gen_x1OrderMinus[] = - {10,49675,56911,64364,6281,5543,59511,52057,44604,37151,2}; - /* 57243552211874561627142571339177891499852299 */ -static arrayDigit ga_161_gen_x1OrderPlusRecip[] = - {8, 7566, 37898, 14581, 2404, 52670, 23839, 17554, 332}; - -static arrayDigit ga_161_gen_a[] = {-1, 152}; /* a = -152 */ -static arrayDigit ga_161_gen_b[] = { 1, 722}; /* b = 722 */ - diff --git a/OSX/libsecurity_cryptkit/lib/curveParams.c b/OSX/libsecurity_cryptkit/lib/curveParams.c index 94ec2195..7dd0abe0 100644 --- a/OSX/libsecurity_cryptkit/lib/curveParams.c +++ b/OSX/libsecurity_cryptkit/lib/curveParams.c @@ -100,11 +100,8 @@ static const arrayDigit ga_one[] = {1, 1 }; // (giant)1 * individually.... */ -#if FEE_PROTOTYPE_CURVES -#include "curveParamDataOld.h" -#else #include "curveParamData.h" -#endif + /* * Now the curveParamsStatic structs, which provide templates for creating the @@ -116,257 +113,7 @@ static const arrayDigit ga_one[] = {1, 1 }; // (giant)1 * Note these are stored as an array, an index into which is a feeDepth * parameter. */ -#if FEE_PROTOTYPE_CURVES -static curveParamsStatic curveParamsArray[] = { - { // depth=0 - FPT_Mersenne, - FCT_Weierstrass, - 31, 1, // q=31, k=1 - NULL, // basePrime only used for FPT_General - 1, // m = 1 - ga_w31_1_a, // a = 7 - ga_one, // b = 1 - ga_zero, // c = 0 - ga_w31_1_x1Plus, - NULL, // y1Plus - ga_w31_1_x1Minus, - ga_w31_1_plusOrder, - ga_w31_1_minusOrder, - ga_w31_1_x1OrderPlus, - ga_w31_1_x1OrderMinus, - ga_w31_1_x1OrderPlusRecip, - ga_w31_1_lesserX1OrderRecip - }, - { // depth=1 - FPT_Mersenne, - FCT_Montgomery, - 31, 1, // q=31, k=1 - NULL, - 1, // m = 1 - ga_one, // a = 1 - ga_zero, // b = 0 - ga_666, // c = 666 - ga_m31_1_x1Plus, - NULL, // y1Plus - ga_m31_1_x1Minus, - ga_m31_1_plusOrder, - ga_m31_1_minusOrder, - ga_m31_1_x1OrderPlus, - ga_m31_1_x1OrderMinus, - ga_m31_1_x1OrderPlusRecip, - ga_m31_1_lesserX1OrderRecip - - }, - { // depth=2 - FPT_Mersenne, - FCT_Weierstrass, - 31, 1, // q=31, k=1, prime curve orders - NULL, - 1, // m = 1 - ga_31_1P_a, // a = 5824692 - ga_31_1P_b, // b = 2067311435 - ga_zero, // c = 0 - ga_31_1P_x1Plus, - NULL, // y1Plus - ga_31_1P_x1Minus, - ga_31_1P_plusOrder, - ga_31_1P_minusOrder, - ga_31_1P_x1OrderPlus, - ga_31_1P_x1OrderMinus, - ga_31_1P_x1OrderPlusRecip, - NULL // x1PlusOrder is lesser - - }, - { // depth=3 - FPT_FEE, - FCT_Weierstrass, - 40, 213, // q=40, k=213, prime curve orders - NULL, - 1, // m = 1 - ga_40_213_a, // a = 1627500953 - ga_40_213_b, // b = 523907505 - ga_zero, // c = 0 - ga_40_213_x1Plus, - NULL, // y1Plus - ga_40_213_x1Minus, - ga_40_213_plusOrder, - ga_40_213_minusOrder, - ga_40_213_x1OrderPlus, - ga_40_213_x1OrderMinus, - ga_40_213_x1OrderPlusRecip, - ga_40_213_lesserX1OrderRecip - - }, - { // depth=4 - FPT_Mersenne, - FCT_Montgomery, - 127, 1, - NULL, - 1, // m = 1 - ga_one, // a = 1 - ga_zero, // b = 0 - ga_666, // c = 666 - ga_127_1_x1Plus, - NULL, // y1Plus - ga_127_1_x1Minus, - ga_127_1_plusOrder, - ga_127_1_minusOrder, - ga_127_1_x1OrderPlus, - ga_127_1_x1OrderMinus, - ga_127_1_x1OrderPlusRecip, - ga_127_1_lesserX1OrderRecip - - }, - { // depth=5 - FPT_Mersenne, - FCT_Weierstrass, - 127, 1, // q=127, k=1 Weierstrass - NULL, - 1, // m = 1 - ga_666, // a = 666 - ga_one, // b = 1 - ga_zero, // c = 0 - ga_127_1W_x1Plus, - NULL, // y1Plus - ga_127_1W_x1Minus, - ga_127_1W_plusOrder, - ga_127_1W_minusOrder, - ga_127_1W_x1OrderPlus, - ga_127_1W_x1OrderMinus, - ga_127_1W_x1OrderPlusRecip, - NULL // x1PlusOrder is lesser - - }, - { // depth=6 - FPT_FEE, - FCT_Weierstrass, // also Atkin3 - 160, 57, - NULL, - 1, // m = 1 - ga_zero, // a = 0 - ga_160_57_b, // b = 3 - ga_zero, // c = 0 - ga_160_57_x1Plus, - NULL, // y1Plus - ga_160_57_x1Minus, - ga_160_57_plusOrder, - ga_160_57_minusOrder, - ga_160_57_x1OrderPlus, - ga_160_57_x1OrderMinus, - ga_160_57_x1OrderPlusRecip, - NULL // x1PlusOrder is lesser - }, - { // depth=7 - FPT_FEE, - FCT_Weierstrass, // also Atkin3 - 192, 1425, - NULL, - 1, // m = 1 - ga_zero, // a = 0 - ga_192_1425_b, // b = -11 - ga_zero, // c = 0 - ga_192_1425_x1Plus, - NULL, // y1Plus - ga_192_1425_x1Minus, - ga_192_1425_plusOrder, - ga_192_1425_minusOrder, - ga_192_1425_x1OrderPlus, - ga_192_1425_x1OrderMinus, - ga_192_1425_x1OrderPlusRecip, - NULL // x1PlusOrder is lesser - - }, - { // depth=8 - FPT_FEE, - FCT_Weierstrass, - 192, -529891, - NULL, - 1, // m = 1 - ga_192_M529891_a, // a = -152 - ga_192_M529891_b, // b = 722 - ga_zero, // c = 0 - ga_192_M529891_x1Plus, - NULL, // y1Plus - ga_192_M529891_x1Minus, - ga_192_M529891_plusOrder, - ga_192_M529891_minusOrder, - ga_192_M529891_x1OrderPlus, - ga_192_M529891_x1OrderMinus, - ga_192_M529891_x1OrderPlusRecip, - ga_192_M529891_lesserX1OrderRecip - - }, - /* - * FPT_General curves, currently just copies of known FPT_FEE or FPT_Mersenne - * curves with primeType set to FPT_General. These are just for - * verification the general curve are handled properly. - * We include the q parameter here for use by feeKeyBitsToDepth(). - */ - { // depth=9 - FPT_General, - FCT_General, - 127, 0, - ga_127_1_bp, // explicit basePrime - 1, // m = 1 - ga_one, // a = 1 - ga_zero, // b = 0 - ga_666, // c = 666 - ga_127_1_x1Plus, - NULL, // y1Plus - ga_127_1_x1Minus, - ga_127_1_plusOrder, - ga_127_1_minusOrder, - ga_127_1_x1OrderPlus, - ga_127_1_x1OrderMinus, - ga_127_1_x1OrderPlusRecip, - ga_127_1_lesserX1OrderRecip - - }, - { // depth=10, FPT_General version of q=160 - FPT_General, - FCT_Weierstrass, - 160, 0, // we don't use these... - ga_160_57_bp, // explicit basePrime - 1, // m = 1 - ga_zero, // a = 0 - ga_160_57_b, // b = 3 - ga_zero, - ga_160_57_x1Plus, - NULL, // y1Plus - ga_160_57_x1Minus, - ga_160_57_plusOrder, - ga_160_57_minusOrder, - ga_160_57_x1OrderPlus, - ga_160_57_x1OrderMinus, - ga_160_57_x1OrderPlusRecip, - NULL // x1PlusOrder is lesser - }, - - { // depth=11, FPT_General, 161 bits - FPT_General, - FCT_Weierstrass, - //161, 0, - 161, 0, // for verifying we don't use these... - ga_161_gen_bp, // explicit basePrime - 1, // m = 1 - ga_161_gen_a, // a = -152 - ga_161_gen_b, // b = 722 - ga_zero, // c = 0 - ga_161_gen_x1Plus, - NULL, // y1Plus - ga_161_gen_x1Minus, - ga_161_gen_plusOrder, - ga_161_gen_minusOrder, - ga_161_gen_x1OrderPlus, - ga_161_gen_x1OrderMinus, - ga_161_gen_x1OrderPlusRecip, - NULL // x1PlusOrder is lesser - }, - -}; - -#else /* FEE_PROTOTYPE_CURVES */ static const curveParamsStatic curveParamsArray[] = { { @@ -666,7 +413,6 @@ static const curveParamsStatic curveParamsArray[] = { NULL } }; -#endif /* FEE_PROTOTYPE_CURVES */ /* * Convert the static form of a giant - i.e., an array of arrayDigits, @@ -778,9 +524,7 @@ curveParams *curveParamsForDepth(feeDepth depth) if(depth > FEE_DEPTH_MAX) { return NULL; } - #if GIANTS_VIA_STACK - curveParamsInitGiants(); - #endif + cp = newCurveParams(); cp->primeType = cps->primeType; cp->curveType = cps->curveType; @@ -1017,29 +761,6 @@ giant lesserX1Order(curveParams *cp) } } -#if GIANTS_VIA_STACK - -/* - * Prime the curveParams and giants modules for quick allocs of giants. - */ -static int giantsInitd = 0; - -void curveParamsInitGiants(void) -{ - const curveParamsStatic *cps = &curveParamsArray[FEE_DEPTH_MAX]; - - if(giantsInitd) { - return; - } - - /* - * Figure the max giant size of the largest depth we know about... - */ - initGiantStacks(giantMaxDigits(giantMinBytes(cps->q, cps->k))); - giantsInitd = 1; -} - -#endif // GIANTS_VIA_STACK /* * Infer the following fields from a partially constructed curveParams: @@ -1076,7 +797,6 @@ void curveParamsInferFields(curveParams *cp) } /* y1Plus */ - #if CRYPTKIT_ELL_PROJ_ENABLE if(cp->curveType == FCT_Weierstrass) { if(cp->y1Plus == NULL) { /* ECDSA Curves already have this */ @@ -1094,9 +814,7 @@ void curveParamsInferFields(curveParams *cp) else { cp->y1Plus = newGiant(1); } - #else /* CRYPTKIT_ELL_PROJ_ENABLE */ - cp->y1Plus = newGiant(1); - #endif + if((cp->x1OrderPlusRecip == NULL) || isZero(cp->x1OrderPlusRecip)) { /* @@ -1119,88 +837,6 @@ void curveParamsInferFields(curveParams *cp) */ #define LOG_DEPTH 0 -#if FEE_PROTOTYPE_CURVES -feeReturn feeKeyBitsToDepth(unsigned keySize, - feePrimeType primeType, /* FPT_Fefault means "best one" */ - feeCurveType curveType, /* FCT_Default means "best one" */ - feeDepth *depth) -{ - feeReturn frtn = FR_Success; - switch(keySize) { - case 31: - switch(curveType) { - case FCT_Montgomery: - default: - *depth = FEE_DEPTH_31_1_M; - break; - case FCT_Weierstrass: - *depth = FEE_DEPTH_31_1_P; - break; - } - break; - case 40: - switch(curveType) { - case FCT_Weierstrass: - default: - *depth = FEE_DEPTH_40_213; - break; - case FCT_Montgomery: - return FR_IllegalDepth; - } - break; - case 127: - switch(curveType) { - case FCT_Montgomery: - if(primeType == FPT_General) { - *depth = FEE_DEPTH_127_GEN; - } - else{ - *depth = FEE_DEPTH_127_1; - } - break; - case FCT_Weierstrass: - default: - *depth = FEE_DEPTH_127_1W; - break; - } - break; - case 160: - switch(curveType) { - case FCT_Montgomery: - return FR_IllegalDepth; - case FCT_Weierstrass: - default: - if(primeType == FPT_General) { - *depth = FEE_DEPTH_160_GEN; - } - else { - *depth = FEE_DEPTH_160_57; - } - break; - } - break; - case 192: - switch(curveType) { - case FCT_Montgomery: - *depth = FEE_DEPTH_192_M529891; - case FCT_Weierstrass: - default: - *depth = FEE_DEPTH_192_1425; - break; - } - break; - default: - frtn = FR_IllegalDepth; - break; - } - #if LOG_DEPTH - printf("feeKeyBitsToDepth: depth %d\n", *depth); - #endif - return frtn; -} - -#else /* FEE_PROTOTYPE_CURVES */ - feeReturn feeKeyBitsToDepth(unsigned keySize, feePrimeType primeType, /* FPT_Fefault means "best one" */ feeCurveType curveType, /* FCT_Default means "best one" */ @@ -1374,8 +1010,6 @@ feeReturn feeKeyBitsToDepth(unsigned keySize, return frtn; } -#endif /* FEE_PROTOTYPE_CURVES */ - /* * Obtain depth for specified curveParams */ diff --git a/OSX/libsecurity_cryptkit/lib/elliptic.c b/OSX/libsecurity_cryptkit/lib/elliptic.c index 3f45d199..212df927 100644 --- a/OSX/libsecurity_cryptkit/lib/elliptic.c +++ b/OSX/libsecurity_cryptkit/lib/elliptic.c @@ -351,7 +351,6 @@ void set_priv_key_giant(key k, giant privGiant) curveParams *cp = k->cp; /* elliptiy multiply of initial public point times private key */ - #if CRYPTKIT_ELL_PROJ_ENABLE if((k->twist == CURVE_PLUS) && (cp->curveType == FCT_Weierstrass)) { /* projective */ @@ -374,9 +373,7 @@ void set_priv_key_giant(key k, giant privGiant) freePointProj(pt1); // FIXME - clear the giants } else { - #else - { - #endif /* CRYPTKIT_ELL_PROJ_ENABLE */ + /* FEE */ if(k->twist == CURVE_PLUS) { gtog(cp->x1Plus, k->x); diff --git a/OSX/libsecurity_cryptkit/lib/ellipticProj.c b/OSX/libsecurity_cryptkit/lib/ellipticProj.c index bdb24316..81d4b691 100644 --- a/OSX/libsecurity_cryptkit/lib/ellipticProj.c +++ b/OSX/libsecurity_cryptkit/lib/ellipticProj.c @@ -63,7 +63,6 @@ ***********************************************************/ #include "ckconfig.h" -#if CRYPTKIT_ELL_PROJ_ENABLE #include "ellipticProj.h" #include "falloc.h" @@ -561,5 +560,3 @@ void findPointProj(pointProj pt, giant seed, curveParams *cp) gtog(seed,x); int_to_giant(1, z); } - -#endif /* CRYPTKIT_ELL_PROJ_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/ellipticProj.h b/OSX/libsecurity_cryptkit/lib/ellipticProj.h index c71add72..ce611f73 100644 --- a/OSX/libsecurity_cryptkit/lib/ellipticProj.h +++ b/OSX/libsecurity_cryptkit/lib/ellipticProj.h @@ -23,8 +23,6 @@ #include "ckconfig.h" -#if CRYPTKIT_ELL_PROJ_ENABLE - #include "giantIntegers.h" #include "curveParams.h" @@ -72,5 +70,4 @@ normalizeProj(pointProj pt, curveParams *cp); void /* Find a point (x, y, 1) on the curve. */ findPointProj(pointProj pt, giant seed, curveParams *cp); -#endif /* CRYPTKIT_ELL_PROJ_ENABLE*/ #endif /* _CRYPTKIT_ELLIPTIC_PROJ_H_ */ diff --git a/OSX/libsecurity_cryptkit/lib/engineNSA127.c b/OSX/libsecurity_cryptkit/lib/engineNSA127.c deleted file mode 100644 index 0e8ea4af..00000000 --- a/OSX/libsecurity_cryptkit/lib/engineNSA127.c +++ /dev/null @@ -1,542 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - - CONFIDENTIAL CONFIDENTIAL CONFIDENTIAL - engineNSA.c - - Security Engine code, to be compiled prior to software - distribution. The code performs the - elliptic curve algebra fundamental to the patented FEE - system. - - This Engine is designed to be virtually nonmalleable - with respect to key size. This is achieved herein - via hard-coding of numerical algorithms with respect to - the DEPTH = 4 security level (127 bit Mersenne prime). - - In meetings between the NSA and NeXT Software, Inc. in - 1995-1996, the notion of Security Engine emerged as a - means by which one could discourage disassembly of - FEE compilations, especially when such disassembly - has the sinister goal of modifying encryption depth. - - DO NOT EVEN THINK ABOUT READING THE SOURCE CODE - BELOW UNLESS YOU ARE EXPLICITLY AUTHORIZED TO DO SO - BY NeXT OR ITS DESIGNEE. - - c. 1996, NeXT Software, Inc. - All Rights Reserved. -*/ - -/* This engine requires no initialization. There is one - function to becalled externally, namely elliptic(). - */ - - - - - - - - - - - - - - - - - - - -/* - * Revision History - * ---------------- - * 10/06/98 ap - * Changed to compile with C++. - * 6 Aug 06 at NeXT - * 'a' argument to elliptic() and ell_even() is now a giant. - * 25 Jul 96 at NeXT - * Wrapped ENGINEmul() with gmersennemod(127,.) to guarantee no - * overflow in the hard-coded mul. - * Fixed sign calculation bug in ENGINEmul(). - * 24 Jul 96 at NeXT - * Made conditional on ENGINE_127_BITS. - * Made all functions except for elliptic() static. - * Renamed some giants function calls via #define. - * Deleted use of array of static pseudo-giants. - * Cosmetic changes for debuggability. - * 19 Jun 96 at NeXT - * Created. - */ - -#include "ckconfig.h" - -#if ENGINE_127_BITS -/* - * This file is obsolete as of 8 January 1997. - */ -#error Hey! New curveParam-dependent 127-bit elliptic() needed! -#warning Using NSA-approved 127-bit security engine... - -#include "NSGiantIntegers.h" - -#define D 65536 -#define DM 65535 - -/* - * Size of 127-bit giantstruct n[] array, in shorts. - */ -#define SHORTCOUNT (8 * 2) -#define BORROW_SIZE 0 - - -static void -ENGINEmul(giant a, giant b) { - int a0,a1,a2,a3,a4,a5,a6,a7, - b0,b1,b2,b3,b4,b5,b6,b7; - int asign, bsign; - int i, j, car; - unsigned int prod; - unsigned short mult; - - gmersennemod(127, a); - gmersennemod(127, b); - asign = a->sign; - bsign = b->sign; - - for(j = abs(asign); j < SHORTCOUNT; j++) a->n[j] = 0; - for(j = abs(bsign); j < SHORTCOUNT; j++) b->n[j] = 0; - a0 = a->n[0]; - a1 = a->n[1]; - a2 = a->n[2]; - a3 = a->n[3]; - a4 = a->n[4]; - a5 = a->n[5]; - a6 = a->n[6]; - a7 = a->n[7]; - b0 = b->n[0]; - b1 = b->n[1]; - b2 = b->n[2]; - b3 = b->n[3]; - b4 = b->n[4]; - b5 = b->n[5]; - b6 = b->n[6]; - b7 = b->n[7]; - for(j = 0; j < SHORTCOUNT; j++) b->n[j] = 0; - - i = 0; - mult = b0; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 1; - mult = b1; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 2; - mult = b2; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 3; - mult = b3; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 4; - mult = b4; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 5; - mult = b5; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 6; - mult = b6; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - - i = 7; - mult = b7; - car = 0; - - prod = a0 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a1 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a2 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a3 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a4 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a5 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a6 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - prod = a7 * mult + b->n[i] + car; - b->n[i++] = prod & DM; - car = prod/D; - - b->n[i] = car; - b->sign = abs(b->sign) + abs(a->sign); - for(j = (b->sign)-1; j >= 0; j--) { - if(b->n[j] != 0) { - break; - } - } - b->sign = j+1; - gmersennemod(127,b); -} - -static void -ell_even(giant x1, giant z1, giant x2, giant z2, giant a, int q) -{ - giant t1, t2, t3; - - t1 = borrowGiant(BORROW_SIZE); - t2 = borrowGiant(BORROW_SIZE); - t3 = borrowGiant(BORROW_SIZE); - - gtog(x1, t1); gsquare(t1); gmersennemod(q, t1); - gtog(z1, t2); gsquare(t2); gmersennemod(q, t2); - gtog(x1, t3); ENGINEmul(z1, t3); - gtog(t1, x2); subg(t2, x2); gsquare(x2); gmersennemod(q, x2); - gtog(a, z2); - ENGINEmul(t3, z2); - addg(t1, z2); addg(t2, z2); ENGINEmul(t3, z2); - gshiftleft(2, z2); - gmersennemod(q, z2); - - returnGiant(t1); - returnGiant(t2); - returnGiant(t3); -} - -static void -ell_odd(giant x1, giant z1, giant x2, giant z2, giant xor, giant zor, int q) -{ - giant t1, t2, t3; - - t1 = borrowGiant(BORROW_SIZE); - t2 = borrowGiant(BORROW_SIZE); - t3 = borrowGiant(BORROW_SIZE); - - gtog(x1, t1); subg(z1, t1); - gtog(x2, t2); addg(z2, t2); - ENGINEmul(t1, t2); - gtog(x1, t1); addg(z1, t1); - gtog(x2, t3); subg(z2, t3); - ENGINEmul(t3, t1); - gtog(t2, x2); addg(t1, x2); - gsquare(x2); gmersennemod(q, x2); //? - gtog(t2, z2); subg(t1, z2); - gsquare(z2); gmersennemod(q, z2); //? - ENGINEmul(zor, x2); - ENGINEmul(xor, z2); - - returnGiant(t1); - returnGiant(t2); - returnGiant(t3); -} - -/* Elliptic multiply. - For given curve parameter a and given prime p = 2^q-1, - the point (xx,zz) becomes k * (xx,zz), in place. - */ -void -elliptic(giant xx, giant zz, giant k, giant a, int q) -{ - int len = bitlen(k), pos = len-2; - giant xs; - giant zs; - giant xorg; - giant zorg; - - if(scompg(1,k)) return; - if(scompg(2,k)) { - ell_even(xx, zz, xx, zz, a, q); - return; - } - - zs = borrowGiant(BORROW_SIZE); - xs = borrowGiant(BORROW_SIZE); - zorg = borrowGiant(BORROW_SIZE); - xorg = borrowGiant(BORROW_SIZE); - - gtog(xx, xorg); gtog(zz, zorg); - ell_even(xx, zz, xs, zs, a, q); - do{ - if(bitval(k, pos--)) { - ell_odd(xs, zs, xx, zz, xorg, zorg, q); - ell_even(xs, zs, xs, zs, a, q); - } else { - ell_odd(xx, zz, xs, zs, xorg, zorg, q); - ell_even(xx, zz, xx, zz, a, q); - } - } while(pos >=0); - - returnGiant(xs); - returnGiant(zs); - returnGiant(xorg); - returnGiant(zorg); -} - -#endif /* ENGINE_127_BITS */ diff --git a/OSX/libsecurity_cryptkit/lib/feeCipherFile.c b/OSX/libsecurity_cryptkit/lib/feeCipherFile.c deleted file mode 100644 index 9c79156d..00000000 --- a/OSX/libsecurity_cryptkit/lib/feeCipherFile.c +++ /dev/null @@ -1,280 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * feeCipherFile.c - general cipherfile support - * - * Revision History - * ---------------- - * 05 Feb 97 at Apple - * Added CFE_FEED and CFE_FEEDExp types. - * 24 Oct 96 at NeXT - * Created. - */ - -#include "feeCipherFile.h" -#include "falloc.h" -#include "feeFEEDExp.h" -#include "feeFEED.h" -#include "feeDebug.h" -#include "CipherFileFEED.h" -#include "CipherFileDES.h" - - -/* - * Create a cipherfile of specified cipherFileEncrType. - */ -feeReturn createCipherFile(feePubKey sendPrivKey, - feePubKey recvPubKey, - cipherFileEncrType encrType, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - int doEnc64, // 1 ==> perform enc64 - unsigned userData, // for caller's convenience - unsigned char **cipherFileData, // RETURNED - unsigned *cipherFileDataLen) // RETURNED -{ - feeReturn frtn = FR_Success; - feeCipherFile cipherFile = NULL; - unsigned char *cipherData = NULL; - unsigned cipherDataLen; - - /* - * Dispatch to encrType-specific code. - */ - switch(encrType) { - case CFE_RandDES: - frtn = createRandDES(sendPrivKey, - recvPubKey, - plainText, - plainTextLen, - genSig, - userData, - &cipherFile); - break; - case CFE_PublicDES: - frtn = createPubDES(sendPrivKey, - recvPubKey, - plainText, - plainTextLen, - genSig, - userData, - &cipherFile); - break; - case CFE_FEED: - frtn = createFEED(sendPrivKey, - recvPubKey, - plainText, - plainTextLen, - genSig, - userData, - &cipherFile); - break; - case CFE_FEEDExp: - frtn = createFEEDExp(sendPrivKey, - recvPubKey, - plainText, - plainTextLen, - genSig, - userData, - &cipherFile); - break; - default: - frtn = FR_Unimplemented; - break; - } - - if(frtn) { - goto out; - } - - /* - * Common logic for all encrTypes - */ - - /* - * Get the cipherfile's raw data - */ - frtn = feeCFileDataRepresentation(cipherFile, - (const unsigned char **)&cipherData, - &cipherDataLen); - if(frtn) { - goto out; - } - - /* - * Optionally encode in 64-char ASCII - */ - if(doEnc64) { - *cipherFileData = enc64(cipherData, - cipherDataLen, - cipherFileDataLen); - ffree(cipherData); - if(*cipherFileData == NULL) { - frtn = FR_Internal; - ffree(cipherData); - goto out; - } - } - else { - *cipherFileData = cipherData; - *cipherFileDataLen = cipherDataLen; - } -out: - /* free stuff */ - if(cipherFile) { - feeCFileFree(cipherFile); - } - return frtn; -} - -/* - * Parse a cipherfile. - * - * sendPubKey only needed for cipherFileEncrType CFE_RandDES if signature - * is present. If sendPubKey is present, it will be used for signature - * validation rather than the embedded sender's public key. - */ -feeReturn parseCipherFile(feePubKey recvPrivKey, - feePubKey sendPubKey, - const unsigned char *cipherFileData, - unsigned cipherFileDataLen, - int doDec64, // 1 ==> perform dec64 - cipherFileEncrType *encrType, // RETURNED - unsigned char **plainText, // RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus, // RETURNED - unsigned *userData) // RETURNED -{ - feeReturn frtn; - unsigned char *cipherData = NULL; - unsigned cipherDataLen; - int freeCipherData = 0; - feeCipherFile cipherFile = NULL; - - *plainText = NULL; - *plainTextLen = 0; - - if(recvPrivKey == NULL) { // always required - frtn = FR_BadPubKey; - goto out; - } - - /* - * First, optional dec64() - */ - if(doDec64) { - cipherData = dec64(cipherFileData, - cipherFileDataLen, - &cipherDataLen); - if(cipherData == NULL) { - frtn = FR_BadEnc64; - goto out; - } - else { - freeCipherData = 1; - } - } - else { - cipherData = (unsigned char *)cipherFileData; - cipherDataLen = cipherFileDataLen; - } - - /* - * Cons up a feeCipherFile object. - */ - frtn = feeCFileNewFromDataRep(cipherData, - cipherDataLen, - &cipherFile); - if(frtn) { - goto out; - } - *encrType = feeCFileEncrType(cipherFile); - *userData = feeCFileUserData(cipherFile); - frtn = decryptCipherFile(cipherFile, - recvPrivKey, - sendPubKey, - plainText, - plainTextLen, - sigStatus); - -out: - /* free stuff */ - - if(cipherData && freeCipherData) { - ffree(cipherData); - } - if(cipherFile) { - feeCFileFree(cipherFile); - } - return frtn; -} - -/* - * Decrypt a feeCipherFile obtained via feeCFileNewFromDataRep(). - * recvPrivKey is required in all cases. If sendPubKey is present, - * sendPubKey - rather than the embedded sender's public key - will be - * used for signature validation. - */ -feeReturn decryptCipherFile(feeCipherFile cipherFile, - feePubKey recvPrivKey, // required - feePubKey sendPubKey, // optional, for signature - unsigned char **plainText, // malloc'd & RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus) // RETURNED -{ - cipherFileEncrType encrType = feeCFileEncrType(cipherFile); - feeReturn frtn; - - *plainText = NULL; - *plainTextLen = 0; - - /* - * Dispatch to encrType-specific code. - */ - switch(encrType) { - case CFE_RandDES: - frtn = decryptRandDES(cipherFile, - recvPrivKey, - sendPubKey, - plainText, - plainTextLen, - sigStatus); - break; - case CFE_PublicDES: - frtn = decryptPubDES(cipherFile, - recvPrivKey, - sendPubKey, - plainText, - plainTextLen, - sigStatus); - break; - case CFE_FEED: - frtn = decryptFEED(cipherFile, - recvPrivKey, - sendPubKey, - plainText, - plainTextLen, - sigStatus); - break; - case CFE_FEEDExp: - frtn = decryptFEEDExp(cipherFile, - recvPrivKey, - sendPubKey, - plainText, - plainTextLen, - sigStatus); - break; - default: - frtn = FR_Unimplemented; - break; - } - return frtn; -} diff --git a/OSX/libsecurity_cryptkit/lib/feeCipherFile.h b/OSX/libsecurity_cryptkit/lib/feeCipherFile.h deleted file mode 100644 index a46f3baf..00000000 --- a/OSX/libsecurity_cryptkit/lib/feeCipherFile.h +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * feeCipherFile.h - * - * Revision History - * ---------------- - * 24 Oct 96 at NeXT - * Created. - */ - -#ifndef _CK_FEECIPHERFILE_H_ -#define _CK_FEECIPHERFILE_H_ - -#if !defined(__MACH__) -#include -#include -#include -#include -#else -#include "ckconfig.h" -#include "feeTypes.h" -#include "feePublicKey.h" -#include "CipherFileTypes.h" -#endif - -#if CRYPTKIT_CIPHERFILE_ENABLE - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Opaque cipherfile object. - */ -typedef void *feeCipherFile; - -/* - * Alloc and return a new feeCipherFile object associated with the specified - * data. - */ -feeCipherFile feeCFileNewFromCipherText(cipherFileEncrType encrType, - const unsigned char *cipherText, - unsigned cipherTextLen, - const unsigned char *sendPubKeyData, - unsigned sendPubKeyDataLen, - const unsigned char *otherKeyData, - unsigned otherKeyDataDataLen, - const unsigned char *sigData, // optional; NULL means no signature - unsigned sigDataLen, // 0 if sigData is NULL - unsigned userData); // for caller's convenience - -/* - * Obtain the contents of a feeCipherFile as a byte stream. Caller must free - * the returned data. - */ -feeReturn feeCFileDataRepresentation(feeCipherFile cipherFile, - const unsigned char **dataRep, // RETURNED - unsigned *dataRepLen); // RETURNED - -/* - * Alloc and return a new feeCipherFile object, given a byte stream (originally - * obtained from feeCFDataRepresentation()). - */ -feeReturn feeCFileNewFromDataRep(const unsigned char *dataRep, - unsigned dataRepLen, - feeCipherFile *cipherFile); // RETURNED if sucessful - -/* - * Free a feeCipherFile object. - */ -void feeCFileFree(feeCipherFile cipherFile); - -/* - * Given a feeCipherFile object (typically obtained from - * feeCFileNewFromDataRep()), obtain its constituent parts. - * - * Data returned must be freed by caller. - * feeCFileSigData(), feeCFileSendPubKeyData, and feeCFileOtherKeyData() - * may return NULL, indicating component not present. - */ -cipherFileEncrType feeCFileEncrType(feeCipherFile cipherFile); -unsigned char *feeCFileCipherText(feeCipherFile cipherFile, - unsigned *cipherTextLen); // RETURNED -unsigned char *feeCFileSendPubKeyData(feeCipherFile cipherFile, - unsigned *sendPubKeyDataLen); // RETURNED -unsigned char *feeCFileOtherKeyData(feeCipherFile cipherFile, - unsigned *otherKeyDataLen); // RETURNED -unsigned char *feeCFileSigData(feeCipherFile cipherFile, - unsigned *sigDataLen); // RETURNED -unsigned feeCFileUserData(feeCipherFile cipherFile); - -/* - * High-level feeCipherFile support. - */ - -/* - * Obtain the data representation of a feeCipherFile given the specified - * plainText and cipherFileEncrType. - * Receiver's public key is required for all encrTypes; sender's private - * key is required for signature generation and also for encrType - * CFE_PublicDES and CFE_FEED. - */ -feeReturn createCipherFile(feePubKey sendPrivKey, - feePubKey recvPubKey, - cipherFileEncrType encrType, - const unsigned char *plainText, - unsigned plainTextLen, - int genSig, // 1 ==> generate signature - int doEnc64, // 1 ==> perform enc64 - unsigned userData, // for caller's convenience - unsigned char **cipherFileData, // RETURNED - unsigned *cipherFileDataLen); // RETURNED - -/* - * Parse and decrypt a cipherfile given its data representation. - * - * recvPrivKey is required in all cases. If sendPubKey is present, - * sendPubKey - rather than the embedded sender's public key - will be - * used for signature validation. - */ -feeReturn parseCipherFile(feePubKey recvPrivKey, // required - feePubKey sendPubKey, // optional, for signature - const unsigned char *cipherFileData, - unsigned cipherFileDataLen, - int doDec64, // 1 ==> perform dec64 - cipherFileEncrType *encrType, // RETURNED - unsigned char **plainText, // malloc'd & RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus, // RETURNED - unsigned *userData); // RETURNED - -/* - * Decrypt a feeCipherFile object obtained via feeCFileNewFromDataRep(). - * recvPrivKey is required in all cases. If sendPubKey is present, - * sendPubKey - rather than the embedded sender's public key - will be - * used for signature validation. - * - * Note: this function is used (in conjunction with feeCFileNewFromDataRep()) - * rather than the simpler parseCipherFile(), in case the caller needs - * access to CipherFile fields not returned in parseCipherFile(). For - * example, the caller might want to get the sender's public key data - * via feeCFileSendPubKeyData(). - */ -feeReturn decryptCipherFile(feeCipherFile cipherFile, - feePubKey recvPrivKey, // required - feePubKey sendPubKey, // optional, for signature - unsigned char **plainText, // malloc'd & RETURNED - unsigned *plainTextLen, // RETURNED - feeSigStatus *sigStatus); // RETURNED - -#ifdef __cplusplus -} -#endif - -#endif /* CRYPTKIT_CIPHERFILE_ENABLE */ -#endif /*_CK_FEECIPHERFILE_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/feeCipherFileAtom.c b/OSX/libsecurity_cryptkit/lib/feeCipherFileAtom.c deleted file mode 100644 index 3576551d..00000000 --- a/OSX/libsecurity_cryptkit/lib/feeCipherFileAtom.c +++ /dev/null @@ -1,400 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * feeCipherFile.c - * - * Revision History - * ---------------- - * 10/06/98 ap - * Changed to compile with C++. - * 05 Feb 97 at Apple - * Modified to use portable byte representation. - * 23 Oct 96 at NeXT - * Created. - */ - -#include "feeCipherFile.h" -#include "falloc.h" -#include "platform.h" -#include "feeDebug.h" -#include "byteRep.h" - -#ifndef NULL -#define NULL ((void *)0) -#endif /* NULL */ - -/* - * These must match constants of same name in CipherFileAtom.java. - */ -#define CFILE_MAGIC 0xfeecf111 -#define CFILE_VERSION 1 -#define CFILE_MIN_VERSION 1 - -/* - * Format of a feeCipherFile header. - * Offsets and lengths refer to locations of components in cFileInst.dataRep. - * This struct appears at the start of a feeCipherFile data representation. - */ -typedef struct { - unsigned magic; - unsigned version; - unsigned minVersion; - unsigned totalLength; // equals dataRepLen - cipherFileEncrType encrType; - unsigned cipherTextOffset; // offset of ciphertext - unsigned cipherTextLen; // in bytes - unsigned sendPubKeyDataOffset; // optional - unsigned sendPubKeyDataLen; - unsigned otherKeyDataOffset; // optional - unsigned otherKeyDataLen; - unsigned sigDataOffset; // optional - unsigned sigDataLen; // 0 means no signature - unsigned userData; -} cFileHeader; - -/* - * Private data, represented by a feeCipherFile handle. - */ -typedef struct { - cFileHeader header; - unsigned char *dataRep; // raw data - unsigned dataRepLen; -} cFileInst; - -static unsigned lengthOfByteRepCfileHdr(void); -static unsigned cfileHdrToByteRep(cFileHeader *hdr, - unsigned char *s); -static void byteRepToCfileHdr(const unsigned char *s, - cFileHeader *hdr); - - -/* - * alloc, free cFileInst - */ -static cFileInst *cFileInstAlloc() -{ - cFileInst *cfinst = (cFileInst *) fmalloc(sizeof(cFileInst)); - - bzero(cfinst, sizeof(cFileInst)); - return cfinst; -} - -static void cFileInstFree(cFileInst *cfinst) -{ - if(cfinst->dataRep) { - ffree(cfinst->dataRep); - } - ffree(cfinst); -} - -/* - * Alloc and return a new feeCipherFile object associated with the specified - * data. - */ -feeCipherFile feeCFileNewFromCipherText(cipherFileEncrType encrType, - const unsigned char *cipherText, - unsigned cipherTextLen, - const unsigned char *sendPubKeyData, // optional - unsigned sendPubKeyDataLen, // 0 if sendPubKeyData is NULL - const unsigned char *otherKeyData, // optional - unsigned otherKeyDataLen, // 0 if otherKeyData is NULL - const unsigned char *sigData, // optional; NULL means no signature - unsigned sigDataLen, // 0 if sigData is NULL - unsigned userData) // for caller's convenience -{ - cFileInst *cfinst; - cFileHeader *header; - unsigned char *data; - - if(cipherTextLen == 0) { - return NULL; - } - cfinst = cFileInstAlloc(); - header = &cfinst->header; - - /* - * Init the header. - */ - header->magic = CFILE_MAGIC; - header->version = CFILE_VERSION; - header->minVersion = CFILE_MIN_VERSION; - header->totalLength = lengthOfByteRepCfileHdr() + cipherTextLen + - sendPubKeyDataLen + otherKeyDataLen + - sigDataLen; - header->encrType = encrType; - header->cipherTextOffset = lengthOfByteRepCfileHdr(); - header->cipherTextLen = cipherTextLen; - header->sendPubKeyDataOffset = header->cipherTextOffset + - cipherTextLen; - header->sendPubKeyDataLen = sendPubKeyDataLen; - header->otherKeyDataOffset = header->sendPubKeyDataOffset + - sendPubKeyDataLen; - header->otherKeyDataLen = otherKeyDataLen; - header->sigDataOffset = header->otherKeyDataOffset + - otherKeyDataLen; - header->sigDataLen = sigDataLen; - header->userData = userData; - - /* - * Alloc a data representation, copy various components to it. - */ - cfinst->dataRepLen = header->totalLength; - data = cfinst->dataRep = (unsigned char*) fmalloc(cfinst->dataRepLen); - cfileHdrToByteRep(header, data); - - data = cfinst->dataRep + header->cipherTextOffset; - bcopy(cipherText, data, cipherTextLen); - if(sendPubKeyDataLen) { - data = cfinst->dataRep + header->sendPubKeyDataOffset; - bcopy(sendPubKeyData, data, sendPubKeyDataLen); - } - if(otherKeyDataLen) { - data = cfinst->dataRep + header->otherKeyDataOffset; - bcopy(otherKeyData, data, otherKeyDataLen); - } - if(sigDataLen) { - data = cfinst->dataRep + header->sigDataOffset; - bcopy(sigData, data, sigDataLen); - } - return (feeCipherFile)cfinst; -} - -/* - * Obtain the contents of a feeCipherFile as a byte stream. - */ -feeReturn feeCFileDataRepresentation(feeCipherFile cipherFile, - const unsigned char **dataRep, - unsigned *dataRepLen) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - if(cfinst->dataRepLen == 0) { - *dataRep = NULL; - *dataRepLen = 0; - return FR_BadCipherFile; - } - *dataRep = (unsigned char*) fmallocWithData(cfinst->dataRep, cfinst->dataRepLen); - *dataRepLen = cfinst->dataRepLen; - return FR_Success; -} - -/* - * Alloc and return a new feeCipherFile object, given a byte stream (originally - * obtained from feeCFDataRepresentation()). - */ -feeReturn feeCFileNewFromDataRep(const unsigned char *dataRep, - unsigned dataRepLen, - feeCipherFile *cipherFile) // RETURNED if sucessful -{ - cFileInst *cfinst = cFileInstAlloc(); - cFileHeader *header; - - if(dataRepLen < lengthOfByteRepCfileHdr()) { - dbgLog(("datRep too short\n")); - goto abort; - } - cfinst->dataRep = (unsigned char*) fmallocWithData(dataRep, dataRepLen); - cfinst->dataRepLen = dataRepLen; - header = &cfinst->header; - byteRepToCfileHdr(dataRep, header); - - /* - * As much consistency checking as we can manage here. - */ - if(header->magic != CFILE_MAGIC) { - dbgLog(("Bad cipherFile magic number\n")); - goto abort; - } - if(header->minVersion > CFILE_VERSION) { - dbgLog(("Incompatible cipherFile version\n")); - goto abort; - } - if(header->totalLength != dataRepLen) { - dbgLog(("Bad totalLength in cipherFile header\n")); - goto abort; - } - if(((header->cipherTextOffset + header->cipherTextLen) > - header->totalLength) || - ((header->sendPubKeyDataOffset + header->sendPubKeyDataLen) > - header->totalLength) || - ((header->otherKeyDataOffset + header->otherKeyDataLen) > - header->totalLength) || - ((header->sigDataOffset + header->sigDataLen) > - header->totalLength)) { - dbgLog(("Bad element lengths in cipherFile header\n")); - goto abort; - } - - /* - * OK, looks good. - */ - *cipherFile = (feeCipherFile)cfinst; - return FR_Success; -abort: - cFileInstFree(cfinst); - *cipherFile = NULL; - return FR_BadCipherFile; -} - -/* - * Free a feeCipherFile object. - */ -void feeCFileFree(feeCipherFile cipherFile) -{ - cFileInstFree((cFileInst *)cipherFile); -} - -/* - * Given a feeCipherFile object (typically obtained from - * feeCFileNewFromData()), obtain its constituent parts. - * - * Data returned must be freed by caller. - * feeCFileSigData() may return NULL, indicating no signature present. - */ -cipherFileEncrType feeCFileEncrType(feeCipherFile cipherFile) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - return cfinst->header.encrType; -} - -unsigned char *feeCFileCipherText(feeCipherFile cipherFile, - unsigned *cipherTextLen) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - if(cfinst->header.cipherTextLen) { - *cipherTextLen = cfinst->header.cipherTextLen; - return (unsigned char*) fmallocWithData(cfinst->dataRep + - cfinst->header.cipherTextOffset, *cipherTextLen); - } - else { - dbgLog(("feeCFileCipherText: no cipherText\n")); - *cipherTextLen = 0; - return NULL; - } -} - -unsigned char *feeCFileSendPubKeyData(feeCipherFile cipherFile, - unsigned *sendPubKeyDataLen) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - if(cfinst->header.sendPubKeyDataLen) { - *sendPubKeyDataLen = cfinst->header.sendPubKeyDataLen; - return (unsigned char*) fmallocWithData(cfinst->dataRep + - cfinst->header.sendPubKeyDataOffset, - *sendPubKeyDataLen); - } - else { - *sendPubKeyDataLen = 0; - return NULL; - } -} - -unsigned char *feeCFileOtherKeyData(feeCipherFile cipherFile, - unsigned *otherKeyDataLen) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - if(cfinst->header.otherKeyDataLen) { - *otherKeyDataLen = cfinst->header.otherKeyDataLen; - return (unsigned char*) fmallocWithData(cfinst->dataRep + - cfinst->header.otherKeyDataOffset, *otherKeyDataLen); - } - else { - *otherKeyDataLen = 0; - return NULL; - } -} - -unsigned char *feeCFileSigData(feeCipherFile cipherFile, - unsigned *sigDataLen) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - if(cfinst->header.sigDataLen) { - *sigDataLen = cfinst->header.sigDataLen; - return (unsigned char*) fmallocWithData(cfinst->dataRep + - cfinst->header.sigDataOffset, *sigDataLen); - } - else { - /* - * Not an error - */ - *sigDataLen = 0; - return NULL; - } -} - -unsigned feeCFileUserData(feeCipherFile cipherFile) -{ - cFileInst *cfinst = (cFileInst *)cipherFile; - - return cfinst->header.userData; -} - -/* - * Convert between cFileHeader and portable byte representation. - */ - -/* - * Return size of byte rep of cFileHeader. We just happen to know that - * this is the same size as the header.... - */ -static unsigned lengthOfByteRepCfileHdr(void) -{ - return sizeof(cFileHeader); -} - -static unsigned cfileHdrToByteRep(cFileHeader *hdr, - unsigned char *s) -{ - s += intToByteRep(hdr->magic, s); - s += intToByteRep(hdr->version, s); - s += intToByteRep(hdr->minVersion, s); - s += intToByteRep(hdr->totalLength, s); - s += intToByteRep(hdr->encrType, s); - s += intToByteRep(hdr->cipherTextOffset, s); - s += intToByteRep(hdr->cipherTextLen, s); - s += intToByteRep(hdr->sendPubKeyDataOffset, s); - s += intToByteRep(hdr->sendPubKeyDataLen, s); - s += intToByteRep(hdr->otherKeyDataOffset, s); - s += intToByteRep(hdr->otherKeyDataLen, s); - s += intToByteRep(hdr->sigDataOffset, s); - s += intToByteRep(hdr->sigDataLen, s); - s += intToByteRep(hdr->userData, s); - return sizeof(cFileHeader); -} - -#define DEC_INT(n, b) \ - n = byteRepToInt(b); \ - b += sizeof(int); - -static void byteRepToCfileHdr(const unsigned char *s, - cFileHeader *hdr) -{ - DEC_INT(hdr->magic, s); - DEC_INT(hdr->version, s); - DEC_INT(hdr->minVersion, s); - DEC_INT(hdr->totalLength, s); -// DEC_INT(hdr->encrType, s); - hdr->encrType = (cipherFileEncrType) byteRepToInt(s); - s += sizeof(int); - DEC_INT(hdr->cipherTextOffset, s); - DEC_INT(hdr->cipherTextLen, s); - DEC_INT(hdr->sendPubKeyDataOffset, s); - DEC_INT(hdr->sendPubKeyDataLen, s); - DEC_INT(hdr->otherKeyDataOffset, s); - DEC_INT(hdr->otherKeyDataLen, s); - DEC_INT(hdr->sigDataOffset, s); - DEC_INT(hdr->sigDataLen, s); - DEC_INT(hdr->userData, s); -} diff --git a/OSX/libsecurity_cryptkit/lib/feeDES.c b/OSX/libsecurity_cryptkit/lib/feeDES.c deleted file mode 100644 index 57cc150a..00000000 --- a/OSX/libsecurity_cryptkit/lib/feeDES.c +++ /dev/null @@ -1,529 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * FeeDES.c - generic, portable DES encryption object - * - * Revision History - * ---------------- - * 10/06/98 ap - * Changed to compile with C++. - * 05 Jan 98 at Apple - * Avoid a bcopy() on encrypt/decrypt of each block - * 31 Mar 97 at Apple - * New per-instance API for DES.c - * 26 Aug 96 at NeXT - * Created. - */ - -#include "ckconfig.h" - -#if CRYPTKIT_SYMMETRIC_ENABLE - -#include "feeDES.h" -#include "feeTypes.h" -#include "ckDES.h" -#include "falloc.h" -#include "feeDebug.h" -#include "feeFunctions.h" -#include "platform.h" -#include - -#ifndef NULL -#define NULL ((void *)0) -#endif /* NULL */ - -typedef struct { - int blockMode; /* default = 0 */ - unsigned char lastBlock[DES_BLOCK_SIZE_BYTES]; /* for CBC */ - struct _desInst dinst; -} fdesInst; - -static void feeDESInit(desInst dinst) -{ - desinit(dinst, DES_MODE_STD); // detects redundant calls -} - -/* - * Alloc and init a feeDES object with specified initial state. - * State must be at least 8 bytes; only 8 bytes are used, ignoring - * MSB of each bytes. - */ -feeDES feeDESNewWithState(const unsigned char *state, - unsigned stateLen) -{ - fdesInst *fdinst; - - if(stateLen < FEE_DES_MIN_STATE_SIZE) { - return NULL; - } - fdinst = (fdesInst*) fmalloc(sizeof(fdesInst)); - bzero(fdinst, sizeof(fdesInst)); - feeDESInit(&fdinst->dinst); - feeDESSetState((feeDES)fdinst, state, stateLen); - return fdinst; -} - -void feeDESFree(feeDES des) -{ - memset(des, 0, sizeof(fdesInst)); - ffree(des); -} - -/* - * Set new initial state. - */ -feeReturn feeDESSetState(feeDES des, - const unsigned char *state, - unsigned stateLen) -{ - fdesInst *fdinst = (fdesInst*) des; - char Key[DES_KEY_SIZE_BYTES_EXTERNAL]; - // 'key' causes problems with - // some weird Unix header - unsigned byte; - - if(stateLen < (DES_KEY_SIZE_BYTES_EXTERNAL)) { - return FR_IllegalArg; - } - bzero(fdinst->lastBlock, DES_BLOCK_SIZE_BYTES); - bcopy(state, Key, DES_KEY_SIZE_BYTES_EXTERNAL); - - /* - * Set up parity bits - */ - for(byte=0; bytedinst, Key); - return FR_Success; -} - -void feeDESSetBlockMode(feeDES des) -{ - fdesInst *fdinst = (fdesInst*) des; - - fdinst->blockMode = 1; -} - -void feeDESSetChainMode(feeDES des) -{ - fdesInst *fdinst = (fdesInst*) des; - - fdinst->blockMode = 0; -} - -unsigned feeDESPlainBlockSize(feeDES des) -{ - return DES_BLOCK_SIZE_BYTES; -} - -unsigned feeDESCipherBlockSize(feeDES des) -{ - return DES_BLOCK_SIZE_BYTES; -} - -unsigned feeDESCipherBufSize(feeDES des) -{ - /* - * Normally DES_BLOCK_SIZE, two blocks for finalBlock - */ - return 2 * DES_BLOCK_SIZE_BYTES; -} - -/* - - * Return the size of ciphertext to hold specified size of plaintext. - - */ - -unsigned feeDESCipherTextSize(feeDES des, unsigned plainTextSize) - -{ - - unsigned blocks = (plainTextSize + DES_BLOCK_SIZE_BYTES - 1) / - DES_BLOCK_SIZE_BYTES; - - if((plainTextSize % DES_BLOCK_SIZE_BYTES) == 0) { - /* - * One more block for resid count - */ - blocks++; - } - - return blocks * DES_BLOCK_SIZE_BYTES; - -} - - -/* - * Key size in bits. - */ -unsigned feeDESKeySize(feeDES des) -{ - return DES_KEY_SIZE_BITS; -} - -/* - * Encrypt a block or less of data. Caller malloc's cipherText. - */ -feeReturn feeDESEncryptBlock(feeDES des, - const unsigned char *plainText, - unsigned plainTextLen, - unsigned char *cipherText, - unsigned *cipherTextLen, // RETURNED - int finalBlock) -{ - fdesInst *fdinst = (fdesInst*) des; - feeReturn frtn = FR_Success; - unsigned cipherLen; - - if(plainTextLen > DES_BLOCK_SIZE_BYTES) { - return FR_IllegalArg; - } - if(plainTextLen) { - /* - * We're called with plainTextLen = 0 and finalBlock - * recursively to clean up last block. - */ - bcopy(plainText, cipherText, plainTextLen); - } - if(plainTextLen < DES_BLOCK_SIZE_BYTES) { - if(!finalBlock) { - /* - * odd-size block only legal last time thru - */ - return FR_IllegalArg; - } - - /* - * Last block, final byte = residual length. - */ - cipherText[DES_BLOCK_SIZE_BYTES - 1] = plainTextLen; - } - - if(!fdinst->blockMode) { - /* - * CBC mode; chain in last cipher word - */ - unsigned char *cp = cipherText; - unsigned char *cp1 = fdinst->lastBlock; - int i; - - for(i=0; idinst, (char *)cipherText); /* Encrypt block */ - if(!fdinst->blockMode){ - /* - * Save outgoing ciphertext for chain - */ - bcopy(cipherText, fdinst->lastBlock, DES_BLOCK_SIZE_BYTES); - } - cipherLen = DES_BLOCK_SIZE_BYTES; - - if(finalBlock) { - if(plainTextLen == DES_BLOCK_SIZE_BYTES) { - /* - * Special case: finalBlock true, plainTextLen == blockSize. - * In this case we generate one more block of ciphertext, - * with a resid length of zero. - */ - unsigned moreCipher; // additional cipherLen - - frtn = feeDESEncryptBlock(des, - NULL, // plainText not used - 0, // resid - cipherText + DES_BLOCK_SIZE_BYTES, // append... - &moreCipher, - 1); - if(frtn == FR_Success) { - cipherLen += moreCipher; - } - - } - if(plainTextLen != 0) { - /* - * Reset internal state in prep for next encrypt/decrypt. - * Note we avoid this in the recursive call (plainTextLen = 0). - */ - bzero(fdinst->lastBlock, DES_BLOCK_SIZE_BYTES); - } - } - - if(frtn == FR_Success) { - *cipherTextLen = cipherLen; - } - return frtn; -} - -/* - * Decrypt a block of data. Caller malloc's plainText. Always - * generates DES_BLOCK_SIZE_BYTES bytes or less of plainText. - */ -feeReturn feeDESDecryptBlock(feeDES des, - const unsigned char *cipherText, - unsigned cipherTextLen, - unsigned char *plainText, - unsigned *plainTextLen, // RETURNED - int finalBlock) -{ - fdesInst *fdinst = (fdesInst*) des; - unsigned char work[DES_BLOCK_SIZE_BYTES]; - unsigned char ivtmp[DES_BLOCK_SIZE_BYTES]; - - if(cipherTextLen != DES_BLOCK_SIZE_BYTES) { - /* - * We always generate ciphertext in multiples of block size. - */ - return FR_IllegalArg; - } - - bcopy(cipherText, work, DES_BLOCK_SIZE_BYTES); - if(!fdinst->blockMode && !finalBlock) { - /* - * Save incoming ciphertext for chain - */ - bcopy(cipherText, ivtmp, DES_BLOCK_SIZE_BYTES); - } - dedes(&fdinst->dinst, (char *)work); - if(!fdinst->blockMode){ - /* - * Unchain block using previous block's ciphertext; - * save current ciphertext for next - */ - char *cp = (char *)work; - char *cp1 = (char*)fdinst->lastBlock; - int i; - - for(i=0; ilastBlock, DES_BLOCK_SIZE_BYTES); - } - } - if(finalBlock) { - /* - * deal with residual block; its size is in last byte of - * work[] - */ - unsigned resid = work[DES_BLOCK_SIZE_BYTES-1]; - - if(resid > (DES_BLOCK_SIZE_BYTES-1)) { - return FR_BadCipherText; - } - if(resid > 0) { - bcopy(work, plainText, resid); - } - *plainTextLen = resid; - - /* - * Reset internal state in prep for next encrypt/decrypt. - */ - bzero(fdinst->lastBlock, DES_BLOCK_SIZE_BYTES); - } - else { - bcopy(work, plainText, DES_BLOCK_SIZE_BYTES); - *plainTextLen = DES_BLOCK_SIZE_BYTES; - } - return FR_Success; -} - -/* - * Convenience routines to encrypt & decrypt multi-block data. - */ -feeReturn feeDESEncrypt(feeDES des, - const unsigned char *plainText, - unsigned plainTextLen, - unsigned char **cipherText, // malloc'd and RETURNED - unsigned *cipherTextLen) // RETURNED -{ - const unsigned char *ptext; // per block - unsigned ptextLen; // total to go - unsigned thisPtextLen; // per block - unsigned ctextLen; // per block - unsigned char *ctextResult; // to return - unsigned char *ctextPtr; - unsigned ctextLenTotal; // running total - feeReturn frtn; - int finalBlock; - unsigned ctextMallocd; - - if(plainTextLen == 0) { - dbgLog(("feeDESDecrypt: NULL plainText\n")); - return FR_IllegalArg; - } - - ptext = plainText; - ptextLen = plainTextLen; - ctextMallocd = feeDESCipherTextSize(des, plainTextLen); - ctextResult = (unsigned char*) fmalloc(ctextMallocd); - ctextPtr = ctextResult; - ctextLenTotal = 0; - - while(1) { - if(ptextLen <= DES_BLOCK_SIZE_BYTES) { - finalBlock = 1; - thisPtextLen = ptextLen; - } - else { - finalBlock = 0; - thisPtextLen = DES_BLOCK_SIZE_BYTES; - } - frtn = feeDESEncryptBlock(des, - ptext, - thisPtextLen, - ctextPtr, - &ctextLen, - finalBlock); - if(frtn) { - dbgLog(("feeDESEncrypt: encrypt error: %s\n", - feeReturnString(frtn))); - break; - } - if(ctextLen == 0) { - dbgLog(("feeDESEncrypt: null ciphertext\n")); - frtn = FR_Internal; - break; - } - ctextLenTotal += ctextLen; - if(ctextLenTotal > (plainTextLen + DES_BLOCK_SIZE_BYTES)) { - dbgLog(("feeDESEncrypt: ciphertext overflow\n")); - frtn = FR_Internal; - break; - } - if(finalBlock) { - break; - } - ctextPtr += ctextLen; - ptext += thisPtextLen; - ptextLen -= thisPtextLen; - } - if(frtn) { - ffree(ctextResult); - *cipherText = NULL; - *cipherTextLen = 0; - } - else { - #if FEE_DEBUG - if(ctextLenTotal != ctextMallocd) { - dbgLog(("feeDESEncrypt: ctextLen error\n")); - } - #endif /* FEE_DEBUG */ - *cipherText = ctextResult; - *cipherTextLen = ctextLenTotal; - } - return frtn; - -} - -feeReturn feeDESDecrypt(feeDES des, - const unsigned char *cipherText, - unsigned cipherTextLen, - unsigned char **plainText, // malloc'd and RETURNED - unsigned *plainTextLen) // RETURNED -{ - const unsigned char *ctext; - unsigned ctextLen; // total to go - unsigned ptextLen; // per block - unsigned char *ptextResult; // to return - unsigned char *ptextPtr; - unsigned ptextLenTotal; // running total - feeReturn frtn = FR_Success; - int finalBlock; - - if(cipherTextLen % DES_BLOCK_SIZE_BYTES) { - dbgLog(("feeDESDecrypt: unaligned cipherText\n")); - return FR_BadCipherText; - } - if(cipherTextLen == 0) { - dbgLog(("feeDESDecrypt: NULL cipherText\n")); - return FR_BadCipherText; - } - - ctext = cipherText; - ctextLen = cipherTextLen; - - /* - * Plaintext length always <= cipherTextLen - */ - ptextResult = (unsigned char*) fmalloc(cipherTextLen); - ptextPtr = ptextResult; - ptextLenTotal = 0; - - while(ctextLen) { - if(ctextLen == DES_BLOCK_SIZE_BYTES) { - finalBlock = 1; - } - else { - finalBlock = 0; - } - frtn = feeDESDecryptBlock(des, - ctext, - DES_BLOCK_SIZE_BYTES, - ptextPtr, - &ptextLen, - finalBlock); - if(frtn) { - dbgLog(("feeDESDecrypt decrypt: %s\n", - feeReturnString(frtn))); - break; - } - if(ptextLen == 0) { - /* - * Normal termination case for - * plainTextLen % DES_BLOCK_SIZE_BYTES == 0 - */ - if(!finalBlock) { - dbgLog(("feeDESDecrypt: decrypt sync" - " error!\n")); - frtn = FR_BadCipherText; - break; - } - else { - break; - } - } - else { - ptextPtr += ptextLen; - ptextLenTotal += ptextLen; - } - ctext += DES_BLOCK_SIZE_BYTES; - ctextLen -= DES_BLOCK_SIZE_BYTES; - } - - if(frtn) { - ffree(ptextResult); - *plainText = NULL; - *plainTextLen = 0; - } - else { - *plainText = ptextResult; - *plainTextLen = ptextLenTotal; - } - return frtn; -} - -#endif /* CRYPTKIT_SYMMETRIC_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/feeDES.h b/OSX/libsecurity_cryptkit/lib/feeDES.h deleted file mode 100644 index 07a8da9c..00000000 --- a/OSX/libsecurity_cryptkit/lib/feeDES.h +++ /dev/null @@ -1,141 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * FeeDES.h - generic, portable DES encryption object - * - * Revision History - * ---------------- - * 26 Aug 96 at NeXT - * Created. - */ - -#ifndef _CK_FEEDES_H_ -#define _CK_FEEDES_H_ - -#if !defined(__MACH__) -#include -#include -#else -#include -#include -#endif - -#if CRYPTKIT_SYMMETRIC_ENABLE - -#ifdef __cplusplus -extern "C" { -#endif - -#define FEE_DES_MIN_STATE_SIZE 8 - -/* - * Opaque object handle. - */ -typedef void *feeDES; - -/* - * Alloc and init a feeDES object with specified initial state. - * State must be at least 8 bytes; only 8 bytes are used, ignoring - * MSB of each bytes. - */ -feeDES feeDESNewWithState(const unsigned char *state, - unsigned stateLen); - -void feeDESFree(feeDES des); - -/* - * Set new initial state. - */ -feeReturn feeDESSetState(feeDES des, - const unsigned char *state, - unsigned stateLen); - -/* - * Set block or chain (CBC) mode. CBC is default. - */ -void feeDESSetBlockMode(feeDES des); -void feeDESSetChainMode(feeDES des); - -/* - * Plaintext block size. - */ -unsigned feeDESPlainBlockSize(feeDES des); - -/* - * Ciphertext block size used for decryption. - */ -unsigned feeDESCipherBlockSize(feeDES des); - -/* - * Required size of buffer for ciphertext, upon encrypting one - * block of plaintext. - */ -unsigned feeDESCipherBufSize(feeDES des); - -/* - - * Return the size of ciphertext to hold specified size of plaintext. - - */ - -unsigned feeDESCipherTextSize(feeDES des, unsigned plainTextSize); - - -/* - * Key size in bits. - */ -unsigned feeDESKeySize(feeDES des); - -/* - * Encrypt a block or less of data. Caller malloc's cipherText. Generates - * up to (2 * feeDESBlockSize) bytes of cipherText. If plainTextLen is - * less than feeDESBlockSize, finalBlock must be true. - */ -feeReturn feeDESEncryptBlock(feeDES des, - const unsigned char *plainText, - unsigned plainTextLen, - unsigned char *cipherText, - unsigned *cipherTextLen, // RETURNED - int finalBlock); - -/* - * Decrypt (exactly) a block of data. Caller malloc's plainText. Always - * generates feeDESBlockSize bytes of plainText, unless 'finalBlock' is - * non-zero (in which case feeDESBlockSize or less bytes of plainText are - * generated). - */ -feeReturn feeDESDecryptBlock(feeDES des, - const unsigned char *cipherText, - unsigned cipherTextLen, - unsigned char *plainText, - unsigned *plainTextLen, // RETURNED - int finalBlock); - -/* - * Convenience routines to encrypt & decrypt multi-block data. - */ -feeReturn feeDESEncrypt(feeDES des, - const unsigned char *plainText, - unsigned plainTextLen, - unsigned char **cipherText, // malloc'd and RETURNED - unsigned *cipherTextLen); // RETURNED - -feeReturn feeDESDecrypt(feeDES des, - const unsigned char *cipherText, - unsigned cipherTextLen, - unsigned char **plainText, // malloc'd and RETURNED - unsigned *plainTextLen); // RETURNED - -#ifdef __cplusplus -} -#endif - -#endif /* CRYPTKIT_SYMMETRIC_ENABLE */ -#endif /*_CK_FEEDES_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/feeDigitalSignature.c b/OSX/libsecurity_cryptkit/lib/feeDigitalSignature.c index c2499709..57775255 100644 --- a/OSX/libsecurity_cryptkit/lib/feeDigitalSignature.c +++ b/OSX/libsecurity_cryptkit/lib/feeDigitalSignature.c @@ -41,9 +41,7 @@ #include "platform.h" #include "byteRep.h" #include "feeECDSA.h" -#if CRYPTKIT_DER_ENABLE #include "CryptKitDER.h" -#endif #include #include "ellipticProj.h" @@ -70,10 +68,8 @@ int sigDebug=1; // tweakable at runtime via debugger typedef struct { giant PmX; // m 'o' P1; m = random - #if CRYPTKIT_ELL_PROJ_ENABLE giant PmY; // y-coord of m 'o' P1 if we're // using projective coords - #endif /* CRYPTKIT_ELL_PROJ_ENABLE */ giant u; giant randGiant; // random m as giant - only known @@ -144,8 +140,6 @@ feeSig feeSigNewWithKey( /* PmX := randGiant 'o' P1 */ sinst->PmX = newGiant(cp->maxDigits); - #if CRYPTKIT_ELL_PROJ_ENABLE - if(cp->curveType == FCT_Weierstrass) { pointProjStruct pt0; @@ -177,17 +171,6 @@ feeSig feeSigNewWithKey( #pragma clang diagnostic pop elliptic_simple(sinst->PmX, sinst->randGiant, cp); } - #else /* CRYPTKIT_ELL_PROJ_ENABLE */ - - if(SIG_CURVE == CURVE_PLUS) { - gtog(cp->x1Plus, sinst->PmX); - } - else { - gtog(cp->x1Minus, sinst->PmX); - } - elliptic_simple(sinst->PmX, sinst->randGiant, cp); - - #endif /* CRYPTKIT_ELL_PROJ_ENABLE */ return sinst; } @@ -200,12 +183,12 @@ void feeSigFree(feeSig sig) clearGiant(sinst->PmX); freeGiant(sinst->PmX); } - #if CRYPTKIT_ELL_PROJ_ENABLE + if(sinst->PmY) { clearGiant(sinst->PmY); freeGiant(sinst->PmY); } - #endif /* CRYPTKIT_ELL_PROJ_ENABLE */ + if(sinst->u) { clearGiant(sinst->u); freeGiant(sinst->u); @@ -351,19 +334,8 @@ feeReturn feeSigData(feeSig sig, { sigInst *sinst = (sigInst*) sig; - #if CRYPTKIT_DER_ENABLE return feeDEREncodeElGamalSignature(sinst->u, sinst->PmX, sigData, sigDataLen); - #else - *sigDataLen = lengthOfByteRepSig(sinst->u, sinst->PmX); - *sigData = (unsigned char*) fmalloc(*sigDataLen); - sigToByteRep(FEE_SIG_MAGIC, - FEE_SIG_VERSION, - FEE_SIG_VERSION_MIN, - sinst->u, - sinst->PmX, - *sigData); - return FR_Success; - #endif + } /* @@ -377,43 +349,14 @@ feeReturn feeSigParse(const unsigned char *sigData, { sigInst *sinst = NULL; feeReturn frtn; - #if !CRYPTKIT_DER_ENABLE - int version; - int magic; - int minVersion; - int rtn; - #endif sinst = sinstAlloc(); - #if CRYPTKIT_DER_ENABLE + frtn = feeDERDecodeElGamalSignature(sigData, sigDataLen, &sinst->u, &sinst->PmX); if(frtn) { goto abort; } - #else - rtn = byteRepToSig(sigData, - sigDataLen, - FEE_SIG_VERSION, - &magic, - &version, - &minVersion, - &sinst->u, - &sinst->PmX); - if(rtn == 0) { - frtn = FR_BadSignatureFormat; - goto abort; - } - switch(magic) { - case FEE_ECDSA_MAGIC: - frtn = FR_WrongSignatureType; // ECDSA! - goto abort; - case FEE_SIG_MAGIC: - break; // proceed - default: - frtn = FR_BadSignatureFormat; - goto abort; - } - #endif /* CRYPTKIT_DER_ENABLE */ + #if SIG_DEBUG if(sigDebug) { @@ -441,8 +384,6 @@ abort: #define LOG_BAD_SIG 0 -#if CRYPTKIT_ELL_PROJ_ENABLE - feeReturn feeSigVerifyNoProj(feeSig sig, const unsigned char *data, unsigned dataLen, @@ -549,12 +490,6 @@ feeReturn feeSigVerify(feeSig sig, return frtn; } -#else /* CRYPTKIT_ELL_PROJ_ENABLE */ - -#define feeSigVerifyNoProj(s, d, l, k) feeSigVerify(s, d, l, k) - -#endif /* CRYPTKIT_ELL_PROJ_ENABLE */ - /* * FEE_SIG_USING_PROJ true : this is the "no Weierstrass" case * feeSigVerifyNoProj false : this is redefined to feeSigVerify @@ -671,10 +606,8 @@ feeReturn feeSigSize( if(cp == NULL) { return FR_BadPubKey; } - #if CRYPTKIT_DER_ENABLE + *maxSigLen = feeSizeOfDERSig(cp->basePrime, cp->basePrime); - #else - *maxSigLen = (unsigned)lengthOfByteRepSig(cp->basePrime, cp->basePrime); - #endif + return FR_Success; } diff --git a/OSX/libsecurity_cryptkit/lib/feeECDSA.c b/OSX/libsecurity_cryptkit/lib/feeECDSA.c index 57736073..37382a18 100644 --- a/OSX/libsecurity_cryptkit/lib/feeECDSA.c +++ b/OSX/libsecurity_cryptkit/lib/feeECDSA.c @@ -70,8 +70,6 @@ #include "ckconfig.h" -#if CRYPTKIT_ECDSA_ENABLE - #include "feeTypes.h" #include "feePublicKey.h" #include "feePublicKeyPrivate.h" @@ -90,9 +88,7 @@ #include "feeDigitalSignature.h" #include "ECDSA_Profile.h" #include "ellipticProj.h" -#if CRYPTKIT_DER_ENABLE #include "CryptKitDER.h" -#endif #ifndef ECDSA_VERIFY_ONLY static void ECDSA_encode( @@ -613,22 +609,11 @@ static void ECDSA_encode( unsigned char **sigData, // malloc'd and RETURNED unsigned *sigDataLen) // RETURNED { - #if CRYPTKIT_DER_ENABLE if (format==FSF_RAW) { feeRAWEncodeECDSASignature(groupBytesLen,c, d, sigData, sigDataLen); } else { feeDEREncodeECDSASignature(c, d, sigData, sigDataLen); } - #else - *sigDataLen = lengthOfByteRepSig(c, d); - *sigData = (unsigned char*) fmalloc(*sigDataLen); - sigToByteRep(FEE_ECDSA_MAGIC, - FEE_ECDSA_VERSION, - FEE_ECDSA_VERSION_MIN, - c, - d, - *sigData); - #endif } #endif /* ECDSA_VERIFY_ONLY */ @@ -642,7 +627,6 @@ static feeReturn ECDSA_decode( giant *d, // alloc'd & RETURNED unsigned *sigVersion) // RETURNED { - #if CRYPTKIT_DER_ENABLE feeReturn frtn; if (format==FSF_RAW) { frtn = feeRAWDecodeECDSASignature(groupBytesLen, sigData, sigDataLen, c, d); @@ -653,31 +637,6 @@ static feeReturn ECDSA_decode( *sigVersion = FEE_ECDSA_VERSION; } return frtn; - #else - int magic; - int minVersion; - int rtn; - - rtn = byteRepToSig(sigData, - sigDataLen, - FEE_ECDSA_VERSION, - &magic, - (int *)sigVersion, - &minVersion, - c, - d); - if(rtn == 0) { - return FR_BadSignatureFormat; - } - switch(magic) { - case FEE_ECDSA_MAGIC: - return FR_Success; - case FEE_SIG_MAGIC: // ElGamal sig! - return FR_WrongSignatureType; - default: - return FR_BadSignatureFormat; - } - #endif } /* @@ -696,13 +655,9 @@ feeReturn feeECDSASigSize( if(cp == NULL) { return FR_BadPubKey; } - #if CRYPTKIT_DER_ENABLE + *maxSigLen = feeSizeOfDERSig(cp->basePrime, cp->basePrime); - #else - *maxSigLen = (unsigned)lengthOfByteRepSig(cp->basePrime, cp->basePrime); - #endif return FR_Success; } -#endif /* CRYPTKIT_ECDSA_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/feeECDSA.h b/OSX/libsecurity_cryptkit/lib/feeECDSA.h index fc0cb28b..7a07be32 100644 --- a/OSX/libsecurity_cryptkit/lib/feeECDSA.h +++ b/OSX/libsecurity_cryptkit/lib/feeECDSA.h @@ -35,8 +35,6 @@ */ #define FEE_ECDSA_MAGIC 0xfee00517 -#if CRYPTKIT_ECDSA_ENABLE - #ifdef __cplusplus extern "C" { #endif @@ -79,6 +77,4 @@ feeReturn feeECDSASigSize( } #endif -#endif /* CRYPTKIT_ECDSA_ENABLE */ - #endif /*_CK_FEEECDSA_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/feeFEED.c b/OSX/libsecurity_cryptkit/lib/feeFEED.c index 144f7345..9c6ae1d3 100644 --- a/OSX/libsecurity_cryptkit/lib/feeFEED.c +++ b/OSX/libsecurity_cryptkit/lib/feeFEED.c @@ -32,8 +32,6 @@ */ #include "ckconfig.h" -#if CRYPTKIT_ASYMMETRIC_ENABLE - #include "feeTypes.h" #include "feeFEED.h" #include "feeFEEDExp.h" @@ -1230,4 +1228,3 @@ feeReturn feeFEEDDecrypt(feeFEED feed, } -#endif /* CRYPTKIT_ASYMMETRIC_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/feeFEED.h b/OSX/libsecurity_cryptkit/lib/feeFEED.h index ce84de8a..787dccca 100644 --- a/OSX/libsecurity_cryptkit/lib/feeFEED.h +++ b/OSX/libsecurity_cryptkit/lib/feeFEED.h @@ -29,8 +29,6 @@ #include #endif -#if CRYPTKIT_ASYMMETRIC_ENABLE - #ifdef __cplusplus extern "C" { #endif @@ -135,6 +133,4 @@ feeReturn feeFEEDDecrypt(feeFEED feed, } #endif -#endif /* CRYPTKIT_ASYMMETRIC_ENABLE */ - #endif /*_CK_FEEFEED_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/feeFEEDExp.c b/OSX/libsecurity_cryptkit/lib/feeFEEDExp.c index 673289bb..b112e234 100644 --- a/OSX/libsecurity_cryptkit/lib/feeFEEDExp.c +++ b/OSX/libsecurity_cryptkit/lib/feeFEEDExp.c @@ -32,8 +32,6 @@ #include "ckconfig.h" -#if CRYPTKIT_ASYMMETRIC_ENABLE - #include "feeTypes.h" #include "feeFEEDExp.h" #include "feePublicKey.h" @@ -732,4 +730,3 @@ feeReturn feeFEEDExpDecrypt(feeFEEDExp feed, } -#endif /* CRYPTKIT_ASYMMETRIC_ENABLE */ diff --git a/OSX/libsecurity_cryptkit/lib/feeFEEDExp.h b/OSX/libsecurity_cryptkit/lib/feeFEEDExp.h index aa190379..22e9b257 100644 --- a/OSX/libsecurity_cryptkit/lib/feeFEEDExp.h +++ b/OSX/libsecurity_cryptkit/lib/feeFEEDExp.h @@ -29,8 +29,6 @@ #include #endif -#if CRYPTKIT_ASYMMETRIC_ENABLE - #ifdef __cplusplus extern "C" { #endif @@ -121,6 +119,4 @@ feeReturn feeFEEDExpDecrypt(feeFEEDExp feed, } #endif -#endif /* CRYPTKIT_ASYMMETRIC_ENABLE */ - #endif /*_CK_FEEFEEDEXP_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/feeFunctions.h b/OSX/libsecurity_cryptkit/lib/feeFunctions.h index 928fb5c5..6c41ccfc 100644 --- a/OSX/libsecurity_cryptkit/lib/feeFunctions.h +++ b/OSX/libsecurity_cryptkit/lib/feeFunctions.h @@ -25,11 +25,7 @@ #ifndef _CK_FEEFUNCTIONS_H_ #define _CK_FEEFUNCTIONS_H_ -#ifdef macintosh -#include -#else #include -#endif #ifdef __cplusplus extern "C" { @@ -45,18 +41,6 @@ void initCryptKit(void); */ void terminateCryptKit(void); -#if defined(NeXT) && !defined(WIN32) - -#define PHRASELEN 128 - -/* - * Prompt for password, get it in secure manner. Max password length is - * PHRASELEN. NEXTSTEP only. - */ -extern void getpassword(const char *prompt, char *pbuf); - -#endif /* NeXT */ - /* * obtain a string describing a feeReturn. */ diff --git a/OSX/libsecurity_cryptkit/lib/feeHash.c b/OSX/libsecurity_cryptkit/lib/feeHash.c index b193af24..7f9e773e 100644 --- a/OSX/libsecurity_cryptkit/lib/feeHash.c +++ b/OSX/libsecurity_cryptkit/lib/feeHash.c @@ -20,8 +20,6 @@ #include "ckconfig.h" -#if CRYPTKIT_MD5_ENABLE - #include "feeTypes.h" #include "feeHash.h" #include "ckMD5.h" @@ -107,4 +105,3 @@ unsigned feeHashDigestLen(void) return MD5_DIGEST_SIZE; } -#endif /* CRYPTKIT_MD5_ENABLE*/ diff --git a/OSX/libsecurity_cryptkit/lib/feeHash.h b/OSX/libsecurity_cryptkit/lib/feeHash.h index bcb66398..17134c40 100644 --- a/OSX/libsecurity_cryptkit/lib/feeHash.h +++ b/OSX/libsecurity_cryptkit/lib/feeHash.h @@ -27,8 +27,6 @@ #include #endif -#if CRYPTKIT_MD5_ENABLE - #ifdef __cplusplus extern "C" { #endif @@ -76,6 +74,4 @@ unsigned feeHashDigestLen(void); } #endif -#endif /* CRYPTKIT_MD5_ENABLE */ - #endif /*_CK_FEEHASH_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/feePublicKey.c b/OSX/libsecurity_cryptkit/lib/feePublicKey.c index d15f14d0..ef143536 100644 --- a/OSX/libsecurity_cryptkit/lib/feePublicKey.c +++ b/OSX/libsecurity_cryptkit/lib/feePublicKey.c @@ -60,11 +60,8 @@ #include "feeECDSA.h" #include "platform.h" #include "enc64.h" -#include "feeDES.h" #include "byteRep.h" -#if CRYPTKIT_DER_ENABLE #include "CryptKitDER.h" -#endif #include /* @@ -86,9 +83,7 @@ #define PUBLIC_KEY_BLOB_VERSION 6 #define PUBLIC_KEY_BLOB_MINVERSION 6 -#if CRYPTKIT_DER_ENABLE #define PUBLIC_DER_KEY_BLOB_VERSION 1 -#endif /* * Private data. All "instance" routines are passed a feePubKey (actually @@ -107,9 +102,7 @@ static feeReturn feeGenPrivate(pubKeyInst *pkinst, char hashPasswd); static pubKeyInst *pubKeyInstAlloc(void); static void pubKeyInstFree(pubKeyInst *pkinst); -#if GIANTS_VIA_STACK -static void feePubKeyInitGiants(void); -#endif + static feeReturn createKeyBlob(pubKeyInst *pkinst, int isPrivate, // 0 : public 1 : private unsigned char **keyBlob, // mallocd and RETURNED @@ -127,9 +120,7 @@ feePubKey feePubKeyAlloc(void) { pubKeyInst *pkinst = pubKeyInstAlloc(); - #if GIANTS_VIA_STACK - feePubKeyInitGiants(); - #endif + return pkinst; } @@ -173,12 +164,6 @@ feeReturn feePubKeyInitFromPrivDataDepth(feePubKey pubKey, pubKeyInst *pkinst = (pubKeyInst *) pubKey; feeReturn frtn; - #if ENGINE_127_BITS - if(depth != FEE_DEPTH_127_1) { - dbgLog(("Illegal Depth\n")); - return FR_IllegalDepth; - } - #endif // ENGINE_127_BITS if(depth > FEE_DEPTH_MAX) { dbgLog(("Illegal Depth\n")); return FR_IllegalDepth; @@ -412,229 +397,6 @@ int feePubKeyIsPrivate(feePubKey key) return ((myPkinst->privGiant != NULL) ? 1 : 0); } -#ifndef ECDSA_VERIFY_ONLY - -#if CRYPTKIT_KEY_EXCHANGE - -feeReturn feePubKeyCreatePad(feePubKey myKey, - feePubKey theirKey, - unsigned char **padData, /* RETURNED */ - unsigned *padDataLen) /* RETURNED padData length in bytes */ -{ - pubKeyInst *myPkinst = (pubKeyInst *) myKey; - pubKeyInst *theirPkinst = (pubKeyInst *) theirKey; - giant pad; - unsigned char *result; - unsigned padLen; - key pkey; - - /* - * Do some compatibility checking (myKey, theirKey) here...? - */ - if(DEFAULT_CURVE == CURVE_PLUS) { - pkey = theirPkinst->plus; - } - else { - pkey = theirPkinst->minus; - } - pad = make_pad(myPkinst->privGiant, pkey); - result = mem_from_giant(pad, &padLen); - freeGiant(pad); - - /* - * Ensure we have a the minimum necessary for DES. A bit of a hack, - * to be sure. - */ - if(padLen >= FEE_DES_MIN_STATE_SIZE) { - *padData = result; - *padDataLen = padLen; - } - else { - *padData = (unsigned char*) fmalloc(FEE_DES_MIN_STATE_SIZE); - *padDataLen = FEE_DES_MIN_STATE_SIZE; - bzero(*padData, FEE_DES_MIN_STATE_SIZE); - bcopy(result, *padData, padLen); - ffree(result); - } - return FR_Success; -} - -#endif /* CRYPTKIT_KEY_EXCHANGE */ - -#if CRYPTKIT_HIGH_LEVEL_SIG - -#warning HLS -/* - * Generate digital signature, ElGamal style. - */ -feeReturn feePubKeyCreateSignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - unsigned char **signature, /* fmalloc'd and RETURNED */ - unsigned *signatureLen) /* RETURNED */ -{ - pubKeyInst *pkinst = (pubKeyInst *) pubKey; - feeHash hash; - feeSig sig; - unsigned char *Pm = NULL; - unsigned PmLen; - feeReturn frtn; - - if(pkinst->privGiant == NULL) { - dbgLog(("feePubKeyCreateSignature: Attempt to Sign without" - " private data\n")); - return FR_BadPubKey; - } - hash = feeHashAlloc(); - sig = feeSigNewWithKey(pubKey, NULL, NULL); - if(sig == NULL) { - /* - * Shouldn't happen, but... - */ - feeHashFree(hash); - return FR_BadPubKey; - } - - /* - * Get Pm to salt hash object - */ - Pm = feeSigPm(sig, &PmLen); - feeHashAddData(hash, Pm, PmLen); - - /* - * Now hash the data proper, then sign the hash - */ - feeHashAddData(hash, data, dataLen); - frtn = feeSigSign(sig, - feeHashDigest(hash), - feeHashDigestLen(), - pubKey); - if(frtn == FR_Success) { - frtn = feeSigData(sig, signature, signatureLen); - } - feeHashFree(hash); - feeSigFree(sig); - ffree(Pm); - return frtn; -} - -/* - * Verify digital signature, ElGamal style. If the signature is ECDSA, - * we'll use that format for compatibility. - */ -feeReturn feePubKeyVerifySignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - const unsigned char *signature, - unsigned signatureLen) -{ - feeHash hash; - feeSig sig; - unsigned char *Pm = NULL; - unsigned PmLen; - feeReturn frtn; - - hash = feeHashAlloc(); - frtn = feeSigParse(signature, signatureLen, &sig); - if(frtn) { - feeHashFree(hash); - #if CRYPTKIT_ECDSA_ENABLE - if(frtn == FR_WrongSignatureType) { - return feePubKeyVerifyECDSASignature(pubKey, - data, - dataLen, - signature, - signatureLen); - } - #endif /* CRYPTKIT_ECDSA_ENABLE */ - return frtn; - } - - /* - * Get PM as salt; eat salt, then hash data - */ - Pm = feeSigPm(sig, &PmLen); - feeHashAddData(hash, Pm, PmLen); - feeHashAddData(hash, data, dataLen); - frtn = feeSigVerify(sig, - feeHashDigest(hash), - feeHashDigestLen(), - pubKey); - - feeHashFree(hash); - feeSigFree(sig); - ffree(Pm); - return frtn; -} - -#pragma mark --- ECDSA signature: high level routines --- - -#if CRYPTKIT_ECDSA_ENABLE -/* - * Generate digital signature, ECDSA style. - */ -feeReturn feePubKeyCreateECDSASignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - unsigned char **signature, /* fmalloc'd and RETURNED */ - unsigned *signatureLen) /* RETURNED */ -{ - pubKeyInst *pkinst = (pubKeyInst *) pubKey; - sha1Obj sha1; - feeReturn frtn; - - if(pkinst->privGiant == NULL) { - dbgLog(("feePubKeyCreateECDSASignature: Attempt to Sign " - "without private data\n")); - return FR_BadPubKey; - } - sha1 = sha1Alloc(); - sha1AddData(sha1, data, dataLen); - frtn = feeECDSASign(pubKey, - sha1Digest(sha1), - sha1DigestLen(), - NULL, // randFcn - NULL, - signature, - signatureLen); - sha1Free(sha1); - return frtn; -} -#endif /* CRYPTKIT_ECDSA_ENABLE */ -#endif /* CRYPTKIT_HIGH_LEVEL_SIG */ -#endif /* ECDSA_VERIFY_ONLY */ - -#if CRYPTKIT_HIGH_LEVEL_SIG - -#if CRYPTKIT_ECDSA_ENABLE - -/* - * Verify digital signature, ECDSA style. - */ -feeReturn feePubKeyVerifyECDSASignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - const unsigned char *signature, - unsigned signatureLen) -{ - sha1Obj sha1; - feeReturn frtn; - - sha1 = sha1Alloc(); - sha1AddData(sha1, data, dataLen); - frtn = feeECDSAVerify(signature, - signatureLen, - sha1Digest(sha1), - sha1DigestLen(), - pubKey); - sha1Free(sha1); - return frtn; -} - -#endif /* CRYPTKIT_ECDSA_ENABLE */ - -#endif /* CRYPTKIT_HIGH_LEVEL_SIG */ - #pragma mark --- ECDH --- /* @@ -957,22 +719,6 @@ void printPubKey(feePubKey pubKey) void printPubKey(feePubKey pubKey) {} #endif // FEE_DEBUG -/* - * Prime the curveParams and giants modules for quick allocs of giants. - */ -#if GIANTS_VIA_STACK - -static int giantsInitd = 0; - -static void feePubKeyInitGiants(void) -{ - if(giantsInitd) { - return; - } - curveParamsInitGiants(); - giantsInitd = 1; -} -#endif #pragma mark --- Native (custom) key blob formatting --- @@ -1180,7 +926,6 @@ feeReturn feePubKeyInitFromPrivBlob(feePubKey pubKey, #endif /* ECDSA_VERIFY_ONLY */ -#if CRYPTKIT_DER_ENABLE #ifndef ECDSA_VERIFY_ONLY /* @@ -1481,8 +1226,6 @@ feeReturn feePubKeyInitFromOpenSSLBlob( return frtn; } -#endif /* CRYPTKIT_DER_ENABLE */ - /* * ANSI X9.62/Certicom key support. * Public key is 04 || x || y diff --git a/OSX/libsecurity_cryptkit/lib/feePublicKey.h b/OSX/libsecurity_cryptkit/lib/feePublicKey.h index 6f88fa62..c368a66e 100644 --- a/OSX/libsecurity_cryptkit/lib/feePublicKey.h +++ b/OSX/libsecurity_cryptkit/lib/feePublicKey.h @@ -131,8 +131,6 @@ feeReturn feePubKeyInitFromKeyString(feePubKey pubKey, const char *keyStr, unsigned keyStrLen); -#if CRYPTKIT_DER_ENABLE - /* * DER format support. * Obtain portable public and private DER-encoded key blobs from a key. @@ -196,8 +194,6 @@ feeReturn feePubKeyInitFromOpenSSLBlob( unsigned char *keyBlob, size_t keyBlobLen); -#endif /* CRYPTKIT_DER_ENABLE */ - /* * ANSI X9.62/Certicom key support. * Public key is 04 || x || y @@ -246,69 +242,6 @@ int feePubKeyIsEqual(feePubKey key1, */ int feePubKeyIsPrivate(feePubKey key); -#if CRYPTKIT_KEY_EXCHANGE - -/* - * Generate a pad, for use with symmetric encryption, derived from two keys. - * 'myKey' must be created with private data (via feePubKeyInitFromPrivData() - * or feePubKeyInitFromKey(). - */ -feeReturn feePubKeyCreatePad(feePubKey myKey, - feePubKey theirKey, - unsigned char **padData, /* fmalloc'd & RETURNED */ - unsigned *padDataLen); /* RETURNED padData length in bytes */ - -#endif /* CRYPTKIT_KEY_EXCHANGE */ - -#if CRYPTKIT_HIGH_LEVEL_SIG - -/* - * The following two routines are implemented using primitives in the - * feeHash and feeDigitalSignature objects. - * - * Generate digital signature, ElGamal style. - */ -feeReturn feePubKeyCreateSignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - unsigned char **signature, /* fmalloc'd and RETURNED */ - unsigned *signatureLen); /* RETURNED */ - -/* - * Verify digital signature, ElGamal style. - */ -feeReturn feePubKeyVerifySignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - const unsigned char *signature, - unsigned signatureLen); - -#if CRYPTKIT_ECDSA_ENABLE - -/* - * The following two routines are implemented using primitives in the - * feeHash and feeECDSA objects. - * - * Generate digital signature, ECDSA style. - */ -feeReturn feePubKeyCreateECDSASignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - unsigned char **signature, /* fmalloc'd and RETURNED */ - unsigned *signatureLen); /* RETURNED */ - -/* - * Verify digital signature, ECDSA style. - */ -feeReturn feePubKeyVerifyECDSASignature(feePubKey pubKey, - const unsigned char *data, - unsigned dataLen, - const unsigned char *signature, - unsigned signatureLen); - -#endif /* CRYPTKIT_ECDSA_ENABLE */ - -#endif /* CRYPTKIT_HIGH_LEVEL_SIG */ /* * Diffie-Hellman. Public key is specified either as a feePubKey or diff --git a/OSX/libsecurity_cryptkit/lib/feeRandom.c b/OSX/libsecurity_cryptkit/lib/feeRandom.c index 75a9b266..83ba0a92 100644 --- a/OSX/libsecurity_cryptkit/lib/feeRandom.c +++ b/OSX/libsecurity_cryptkit/lib/feeRandom.c @@ -65,3 +65,4 @@ void feeRandAddEntropy(__attribute__((unused)) feeRand frand, __attribute__((unu { } + diff --git a/OSX/libsecurity_cryptkit/lib/feeTypes.h b/OSX/libsecurity_cryptkit/lib/feeTypes.h index 87db4052..1f31dd04 100644 --- a/OSX/libsecurity_cryptkit/lib/feeTypes.h +++ b/OSX/libsecurity_cryptkit/lib/feeTypes.h @@ -89,47 +89,6 @@ typedef enum { FCT_General /* Other */ } feeCurveType; -/* - * Some commonly used feeDepth values. In these definitions, q and k are - * from the expression (2^q - k), the base modulus of the curve. The case - * k=1 implies a Mersenne prime as the modulus. - */ -#define FEE_PROTOTYPE_CURVES 0 - -#if FEE_PROTOTYPE_CURVES - - /* q k a b c */ - /* ---- ---- ---- ---- ---- */ -#define FEE_DEPTH_31_1_W 0 /* 31 1 7 1 0 */ -#define FEE_DEPTH_31_1_M 1 /* 31 1 1 0 666 */ -#define FEE_DEPTH_31_1_P 2 /* 31 1 5824692 2067311435 0 */ -#define FEE_DEPTH_40_213 3 /* 40 213 1627500953 523907505 0 */ -#define FEE_DEPTH_127_1 4 /* 127 1 1 0 666 */ -#define FEE_DEPTH_127_1W 5 /* 127 1 666 1 0 */ -#define FEE_DEPTH_160_57 6 /* 160 57 0 3 0 */ -#define FEE_DEPTH_192_1425 7 /* 192 1425 0 -11 0 */ -#define FEE_DEPTH_192_M529891 8 /* 192 -529891 -152 722 0 */ - -/* - * The remaining curves are implemented as PT_GENERAL curves; modulo - * arithmetic does not utilize any FEE or Mersenne optimizations. These - * are here for performance measurements and DVT. - */ -#define FEE_DEPTH_127_GEN 9 /* 127 1 1 0 666 */ -#define FEE_DEPTH_160_GEN 10 /* 160 57 0 3 0 */ -#define FEE_DEPTH_161_GEN 11 /* 161 .. -152 722 0 */ - -/* - * The default depth. - */ -#define FEE_DEPTH_DEFAULT FEE_DEPTH_160_57 - -/* - * Last enumerated depth. - */ -#define FEE_DEPTH_MAX FEE_DEPTH_161_GEN - -#else /* FEE_PROTOTYPE_CURVES */ /* * The real curves as of 4/9/2001. @@ -161,7 +120,6 @@ typedef enum { */ #define FEE_DEPTH_MAX FEE_DEPTH_secp521r1 -#endif /* FEE_PROTOTYPE_CURVES */ /* * Random number generator callback function. diff --git a/OSX/libsecurity_cryptkit/lib/giantIntegers.c b/OSX/libsecurity_cryptkit/lib/giantIntegers.c index d5a19537..b67d833b 100644 --- a/OSX/libsecurity_cryptkit/lib/giantIntegers.c +++ b/OSX/libsecurity_cryptkit/lib/giantIntegers.c @@ -185,260 +185,20 @@ static void absg(giant g); /* g := |g|. */ * CryptKit without the giant stacks enabled. */ -#if GIANTS_VIA_STACK -#if LOG_GIANT_STACK -#define gstackDbg(x) printf x -#else // LOG_GIANT_STACK -#define gstackDbg(x) -#endif // LOG_GIANT_STACK - -typedef struct { - unsigned numDigits; // capacity of giants in this stack - unsigned numFree; // number of free giants in stack - unsigned totalGiants; // total number in *stack - giant *stack; -} gstack; - -static gstack *gstacks = NULL; // array of stacks -static unsigned numGstacks = 0; // # of elements in gstacks -static int gstackInitd = 0; // this module has been init'd - -#define INIT_NUM_GIANTS 16 /* initial # of giants / stack */ -#define MIN_GIANT_SIZE 4 /* numDigits for gstack[0] */ -#define GIANT_SIZE_INCR 2 /* in << bits */ - -/* - * Initialize giant stacks, with up to specified max giant size. - */ -void initGiantStacks(unsigned maxDigits) -{ - unsigned curSize = MIN_GIANT_SIZE; - unsigned sz; - unsigned i; - - dblog0("initGiantStacks\n"); - - if(gstackInitd) { - /* - * Shouldn't be called more than once... - */ - printf("multiple initGiantStacks calls\n"); - return; - } - gstackDbg(("initGiantStacks(%d)\n", maxDigits)); - - /* - * How many stacks? - */ - numGstacks = 1; - while(curSize<=maxDigits) { - curSize <<= GIANT_SIZE_INCR; - numGstacks++; - } - - sz = sizeof(gstack) * numGstacks; - gstacks = (gstack*) fmalloc(sz); - bzero(gstacks, sz); - - curSize = MIN_GIANT_SIZE; - for(i=0; inumFree; j++) { - freeGiant(gs->stack[j]); - gs->stack[j] = NULL; - } - /* and the stack itself - may be null if this was never used */ - if(gs->stack != NULL) { - ffree(gs->stack); - gs->stack = NULL; - } - } - ffree(gstacks); - gstacks = NULL; - gstackInitd = 0; -} - -#endif // GIANTS_VIA_STACK giant borrowGiant(unsigned numDigits) { giant result; - - #if GIANTS_VIA_STACK - - unsigned stackNum; - gstack *gs = gstacks; - - #if WARN_ZERO_GIANT_SIZE - if(numDigits == 0) { - printf("borrowGiant(0)\n"); - numDigits = gstacks[numGstacks-1].numDigits; - } - #endif // WARN_ZERO_GIANT_SIZE - - /* - * Find appropriate stack - */ - if(numDigits <= MIN_GIANT_SIZE) - stackNum = 0; - else if (numDigits <= (MIN_GIANT_SIZE << GIANT_SIZE_INCR)) - stackNum = 1; - else if (numDigits <= (MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR))) - stackNum = 2; - else if (numDigits <= (MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR))) - stackNum = 3; - else if (numDigits <= (MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR))) - stackNum = 4; - else - stackNum = numGstacks; - - if(stackNum >= numGstacks) { - /* - * out of bounds; just malloc - */ - #if LOG_GIANT_STACK_OVERFLOW - gstackDbg(("giantFromStack overflow; numDigits %d\n", - numDigits)); - #endif // LOG_GIANT_STACK_OVERFLOW - return newGiant(numDigits); - } - gs = &gstacks[stackNum]; - - #if GIANT_MAC_DEBUG - if((gs->numFree != 0) && (gs->stack == NULL)) { - dblog0("borrowGiant: null stack!\n"); - } - #endif - - if(gs->numFree != 0) { - result = gs->stack[--gs->numFree]; - } - else { - /* - * Stack empty; malloc - */ - result = newGiant(gs->numDigits); - } - - #else /* GIANTS_VIA_STACK */ - result = newGiant(numDigits); - #endif /* GIANTS_VIA_STACK */ - PROF_INCR(numBorrows); return result; } void returnGiant(giant g) { - - #if GIANTS_VIA_STACK - - unsigned stackNum; - gstack *gs; - unsigned cap = g->capacity; - - - #if FEE_DEBUG - if(!gstackInitd) { - CKRaise("returnGiant before stacks initialized!"); - } - #endif // FEE_DEBUG - - #if GIANT_MAC_DEBUG - if(g == NULL) { - dblog0("returnGiant: null g!\n"); - } - #endif - - /* - * Find appropriate stack. Note we expect exact match of - * capacity and stack's giant size. - */ - /* - * Optimized unrolled loop. Just make sure there are enough cases - * to handle all of the stacks. Errors in this case will be flagged - * via LOG_GIANT_STACK_OVERFLOW. - */ - switch(cap) { - case MIN_GIANT_SIZE: - stackNum = 0; - break; - case MIN_GIANT_SIZE << GIANT_SIZE_INCR: - stackNum = 1; - break; - case MIN_GIANT_SIZE << (2 * GIANT_SIZE_INCR): - stackNum = 2; - break; - case MIN_GIANT_SIZE << (3 * GIANT_SIZE_INCR): - stackNum = 3; - break; - case MIN_GIANT_SIZE << (4 * GIANT_SIZE_INCR): - stackNum = 4; - break; - default: - stackNum = numGstacks; - break; - } - - if(stackNum >= numGstacks) { - /* - * out of bounds; just free - */ - #if LOG_GIANT_STACK_OVERFLOW - gstackDbg(("giantToStack overflow; numDigits %d\n", cap)); - #endif // LOG_GIANT_STACK_OVERFLOW - freeGiant(g); - return; - } - gs = &gstacks[stackNum]; - if(gs->numFree == gs->totalGiants) { - if(gs->totalGiants == 0) { - gstackDbg(("Initial alloc of gstack(%d)\n", - gs->numDigits)); - gs->totalGiants = INIT_NUM_GIANTS; - } - else { - gs->totalGiants *= 2; - gstackDbg(("Bumping gstack(%d) to %d\n", - gs->numDigits, gs->totalGiants)); - } - gs->stack = (giantstruct**) frealloc(gs->stack, gs->totalGiants*sizeof(giant)); - } - g->sign = 0; // not sure this is important... - gs->stack[gs->numFree++] = g; - - #if GIANT_MAC_DEBUG - if((gs->numFree != 0) && (gs->stack == NULL)) { - dblog0("borrowGiant: null stack!\n"); - } - #endif - - #else /* GIANTS_VIA_STACK */ - freeGiant(g); - - #endif /* GIANTS_VIA_STACK */ } void freeGiant(giant x) { @@ -453,12 +213,8 @@ giant newGiant(unsigned numDigits) { #if WARN_ZERO_GIANT_SIZE if(numDigits == 0) { printf("newGiant(0)\n"); - #if GIANTS_VIA_STACK - numDigits = gstacks[numGstacks-1].totalGiants; - #else /* HACK */ numDigits = 20; - #endif } #endif // WARN_ZERO_GIANT_SIZE @@ -1529,18 +1285,6 @@ void clearGiant(giant g) g->sign = 0; } -#if ENGINE_127_BITS -/* - * only used by engineNSA127.c, which is obsolete as of 16 Jan 1997 - */ -int -scompg(int n, giant g) { - if((g->sign == 1) && (g->n[0] == n)) return(1); - return(0); -} - -#endif // ENGINE_127_BITS - /* */ diff --git a/OSX/libsecurity_cryptkit/lib/giantIntegers.h b/OSX/libsecurity_cryptkit/lib/giantIntegers.h index 34acf764..cb9082cf 100644 --- a/OSX/libsecurity_cryptkit/lib/giantIntegers.h +++ b/OSX/libsecurity_cryptkit/lib/giantIntegers.h @@ -64,14 +64,6 @@ typedef unsigned short giantDigit; #define MAX_DIGITS ((1<<18)+(1<<17)) /* 2^(16*MAX_DIGITS)-1 will fit into a giant. */ -/* - * The giant stack package is a local cache which allows us to avoid calls - * to malloc() for borrowGiant(). On a 90 Mhz Pentium, enabling the - * giant stack package shows about a 1.35 speedup factor over an identical - * CryptKit without the giant stacks enabled. - */ -#define GIANTS_VIA_STACK CRYPTKIT_GIANT_STACK_ENABLE - typedef struct { int sign; /* number of giantDigits = abs(sign) */ unsigned capacity; /* largest possible number of giantDigits */ @@ -79,25 +71,6 @@ typedef struct { } giantstruct; typedef giantstruct *giant; -#if GIANTS_VIA_STACK -/* - * For giant stack debug only - * Set default giant size (i.e., for newGiant(0) and borrowGiant(0)) - */ -void setGiantSize(unsigned numDigits); - -/* - * Initialize giant stacks, with up to specified max giant size. - */ -void initGiantStacks(unsigned maxDigits); - -/* - * Free giant stacks on shutdown. - */ -void freeGiantStacks(void); - -#endif /* GIANTS_VIA_STACK */ - giant newGiant(unsigned numDigits); giant copyGiant(giant x); void freeGiant(giant x); diff --git a/OSX/libsecurity_cryptkit/lib/giantPortCommon.h b/OSX/libsecurity_cryptkit/lib/giantPortCommon.h index a5d1de92..ca381fd5 100644 --- a/OSX/libsecurity_cryptkit/lib/giantPortCommon.h +++ b/OSX/libsecurity_cryptkit/lib/giantPortCommon.h @@ -27,15 +27,6 @@ * inline C functions */ #include "giantPort_Generic.h" -#elif defined(__ppc__) && defined(__MACH__) -/* Mac OS X, PPC, Gnu compiler */ -#include "giantPort_PPC_Gnu.h" - -#elif defined(__ppc__ ) && defined(macintosh) - -/* Mac OS 9, PPC, Metrowerks */ -#include "giantPort_PPC.h" - #else /* Others */ diff --git a/OSX/libsecurity_cryptkit/lib/giantPort_PPC.c b/OSX/libsecurity_cryptkit/lib/giantPort_PPC.c deleted file mode 100644 index c9b26450..00000000 --- a/OSX/libsecurity_cryptkit/lib/giantPort_PPC.c +++ /dev/null @@ -1,236 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * giantPort_PPC.c - PPC-dependent giant definitions. - * - * Revision History - * ---------------- - * 10/06/98 ap - * Changed to compile with C++. - * 06 Apr 1998 at Apple - * Created. - */ - -#include "feeDebug.h" -#include "platform.h" -#include "giantPort_PPC.h" - -#if !PPC_GIANT_PORT_INLINE - - -/* - * Multiple-precision arithmetic routines/macros. - */ - -asm giantDigit giantAddDigits( - register giantDigit dig1, - register giantDigit dig2, - register giantDigit *carry) /* RETURNED, 0 or 1 */ - -{ - /* - * dig1 : r3 - * dig2 : r4 - * carry : r5 - * sum : r6 - */ - - /* sum = dig1 + dig2 */ - add r6, dig1, dig2; - - /* if((sum < dig1) || (sum < dig2)) */ - cmpl crf0,0,r6,dig1 - bc 12,0,*+12 - cmpl crf0,0,r6,dig2 - bc 4,0,*+16 - - /* *carry = 1; */ - li r7,1 - stw r7, 0(r5) - b *+12 - - /* else *carry = 0; */ - li r7,0 - stw r7, 0(r5) - - /* return sum in r3 */ - mr. r3,r6 - blr -} - -/* - * Add a single digit value to a double digit accumulator in place. - * Carry out of the MSD of the accumulator is not handled. - * This should work any size giantDigits up to unsigned int. - */ -asm void giantAddDouble( - register giantDigit *accLow, /* IN/OUT */ - register giantDigit *accHigh, /* IN/OUT */ - register giantDigit val) -{ - /* - * r3 : accLow - * r4 : accHi - * r5 : val - * r6 : sumLo - * r7 : *accLow - */ - - /* giantDigit sumLo = *accLow + val; */ - lwz r7,0(accLow) - add r6,r7,val - - /* if((sumLo < *accLow) || (sumLo < val)) { */ - cmpl crf0,0,r6,r7 - bc 12,0,*+12 - cmpl crf0,0,r6,val - bc 4,0,*+16 - - /* (*accHigh)++; */ - lwz r7, 0(accHigh) - addi r7,r7,1 - stw r7, 0(accHigh) - - /* *accLow = sumLo; */ - stw r6,0(accLow) - blr -} - -asm giantDigit giantSubDigits( - register giantDigit a, - register giantDigit b, - register giantDigit *borrow) /* RETURNED, 0 or 1 */ - -{ - /* a : r3 - b : r4 - borrow : r5 - diff : r6 */ - - /* giantDigit diff = a - b; */ - subf r6, b, a; - - /* if(a < b) */ - cmpl crf0,0,a,b - bc 4,0,*+16 - - /* *borrow = 1; */ - li r7,1 - stw r7, 0(borrow) - b *+12 - - /* else *borrow = 0; */ - li r7,0 - stw r7, 0(borrow) - - /* return diff in r3 */ - mr. r3,r6 - blr -} - -asm void giantMulDigits( - register giantDigit dig1, - register giantDigit dig2, - register giantDigit *lowProduct, /* RETURNED, low digit */ - register giantDigit *hiProduct) /* RETURNED, high digit */ -{ - /* r3 : dig1 - r4 : dig2 - r5 : lowProduct - r6 : hiProduct */ - - /* dprod = (unsigned long long)dig1 * (unsigned long long)dig2; */ - mullw r7, dig1, dig2 /* r7 = low(dig1 * dig2) */ - mulhwu r8, dig1, dig2 /* r8 - hi(dig1 * dig2) */ - - /* *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); */ - stw r8, 0(hiProduct) - - /* *lowProduct = (giantDigit)dprod; */ - stw r7, 0(lowProduct) - blr -} - -asm giantDigit VectorMultiply( - register giantDigit plierDigit, /* r3 */ - register giantDigit *candVector, /* r4 */ - register unsigned candLength, /* r5 */ - register giantDigit *prodVector) /* r6 */ -{ - register unsigned candDex; /* index into multiplicandVector */ - register giantDigit lastCarry; - register giantDigit prodLo; - register giantDigit prodHi; - register unsigned scr1; - register unsigned sumLo; - - fralloc - - /* giantDigit lastCarry = 0; */ - li lastCarry,0 - - - /* for(candDex=0; candDex scr1 */ - addi candVector,candVector,4 /* candVector++ */ - - mullw prodLo,scr1,plierDigit /* prodLo = low(*candVector * plierDigit) */ - mulhwu prodHi,scr1,plierDigit /* prodHi = high(*candVector * plierDigit) */ - - /* giantAddDouble(&prodLo, &prodHi, *prodVector); */ - lwz scr1,0(prodVector) /* *prodVector --> r9 */ - add sumLo,prodLo,scr1 /* prodLo + *prodVector --> sumLo */ - cmpl crf0,0,sumLo,prodLo /* sumLo < prodLo? */ - bc 12,0,_carry1 - cmpl crf0,0,sumLo,scr1 /* sumLo < *prodVector? */ - bc 4,0,_noCar1 -_carry1: - addi prodHi,prodHi,1 /* prodHi++ */ -_noCar1: - mr. prodLo,sumLo /* prodLo := sumLo */ - - /* giantAddDouble(&prodLo, &prodHi, lastCarry); */ - add sumLo,sumLo,lastCarry /* sumLo += lastCarry */ - cmpl crf0,0,sumLo,prodLo /* sumLo < prodLo? */ - bc 12,0,_carry2 - cmpl crf0,0,sumLo,lastCarry /* sumLo < lastCarry? */ - bc 4,0,_noCar2 -_carry2: - addi prodHi,prodHi,1 /* prodHi++ */ -_noCar2: - mr. prodLo,sumLo /* prodLo := sumLo */ - - /* *(prodVector++) = prodLo; */ - stw prodLo,0(prodVector) /* prodLo --> *prodVector */ - addi prodVector,prodVector,4 /* prodVector++ */ - - /* lastCarry = prodHi; */ - mr. lastCarry,prodHi - - /* } */ - addi candDex,candDex,1 /* candDex++ */ -_endLoop: - cmpl crf0,0,candDex,candLength /* candDex < candLength? */ - bc 12,0,_topLoop - - /* return lastCarry; */ - mr. r3,lastCarry /* return lastCarry in r3 */ - frfree - blr -} - -#endif // PPC_GIANT_PORT_INLINE diff --git a/OSX/libsecurity_cryptkit/lib/giantPort_PPC.h b/OSX/libsecurity_cryptkit/lib/giantPort_PPC.h deleted file mode 100644 index 44ebeb3b..00000000 --- a/OSX/libsecurity_cryptkit/lib/giantPort_PPC.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * giantPort_PPC.h - PPC-dependent giant definitions. - * - * Revision History - * ---------------- - * 10/06/98 ap - * Changed to compile with C++. - * 06 Apr 1998 at Apple - * Created. - */ - -#ifndef _CK_NSGIANT_PORT_PPC_H_ -#define _CK_NSGIANT_PORT_PPC_H_ - -#include "feeDebug.h" -#include "platform.h" -#include "giantIntegers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/**** FIXME - implement asm giant digits! ****/ -/* - * 0 ==> use function declarations from this file and implementation - * in giantPort_PPC.c - * 1 ==> use static inline C function in giantPort_Generic.h - */ -/*@@@ HACK @@@ -#if defined NeXT -#define PPC_GIANT_PORT_INLINE 1 -#else -#define PPC_GIANT_PORT_INLINE 0 -#endif -*/ -#define PPC_GIANT_PORT_INLINE 1 - -#if PPC_GIANT_PORT_INLINE - -#include "giantPort_Generic.h" - -#else // PPC_GIANT_PORT_INLINE - -/* - * We'll be using the compiler's 64-bit long long for these routines. - * - * Mask for upper word. - */ -#define GIANT_UPPER_DIGIT_MASK (~(unsigned long long(GIANT_DIGIT_MASK))) - -/* - * Multiple-precision arithmetic routines/macros. C for now, eventually - * they'll be in assembly. - */ - -/* - * Add two digits, return sum. Carry bit returned as an out parameter. - * This should work any size giantDigits up to unsigned int. - */ -extern giantDigit giantAddDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *carry); /* RETURNED, 0 or 1 */ - -/* - * Add a single digit value to a double digit accumulator in place. - * Carry out of the MSD of the accumulator is not handled. - */ -void giantAddDouble( - giantDigit *accLow, /* IN/OUT */ - giantDigit *accHigh, /* IN/OUT */ - giantDigit val); - - -/* - * Subtract a - b, return difference. Borrow bit returned as an out parameter. - */ -giantDigit giantSubDigits( - giantDigit a, - giantDigit b, - giantDigit *borrow); /* RETURNED, 0 or 1 */ - - -/* - * Multiply two digits, return two digits. - */ -void giantMulDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *lowProduct, /* RETURNED, low digit */ - giantDigit *hiProduct); /* RETURNED, high digit */ - -/* - * Multiply a vector of giantDigits, candVector, by a single giantDigit, - * plierDigit, adding results into prodVector. Returns m.s. digit from - * final multiply; only candLength digits of *prodVector will be written. - */ -giantDigit VectorMultiply( - giantDigit plierDigit, - giantDigit *candVector, - unsigned candLength, - giantDigit *prodVector); - -#ifdef __cplusplus -} -#endif - -#endif /* !PPC_GIANT_PORT_INLINE */ - -#endif /*_CK_NSGIANT_PORT_PPC_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.h b/OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.h deleted file mode 100644 index 3676da99..00000000 --- a/OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * giantPort_PPC_Gnu.h - giant definitions, PPC/GNU version. - */ - -#ifndef _CK_NSGIANT_PORT_PPC_GNU_H_ -#define _CK_NSGIANT_PORT_PPC_GNU_H_ - -#include "feeDebug.h" -#include "platform.h" -#include "giantIntegers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* define this true to disable this module and use generic C versions instead */ -#define PPC_GIANT_PORT_INLINE 0 - -#if PPC_GIANT_PORT_INLINE - -#include "giantPort_Generic.h" - -#else // PPC_GIANT_PORT_INLINE - -/* - * Multiple-precision arithmetic routines/macros implemented in - * giantPort_PPC_Gnu.s - */ - -/* - * Add two digits, return sum. Carry bit returned as an out parameter. - */ -extern giantDigit giantAddDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *carry); /* RETURNED, 0 or 1 */ - -/* - * Add a single digit value to a double digit accumulator in place. - * Carry out of the MSD of the accumulator is not handled. - */ -void giantAddDouble( - giantDigit *accLow, /* IN/OUT */ - giantDigit *accHigh, /* IN/OUT */ - giantDigit val); - - -/* - * Subtract a - b, return difference. Borrow bit returned as an out parameter. - */ -giantDigit giantSubDigits( - giantDigit a, - giantDigit b, - giantDigit *borrow); /* RETURNED, 0 or 1 */ - - -/* - * Multiply two digits, return two digits. - */ -void giantMulDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *lowProduct, /* RETURNED, low digit */ - giantDigit *hiProduct); /* RETURNED, high digit */ - -/* - * Multiply a vector of giantDigits, candVector, by a single giantDigit, - * plierDigit, adding results into prodVector. Returns m.s. digit from - * final multiply; only candLength digits of *prodVector will be written. - */ -giantDigit VectorMultiply( - giantDigit plierDigit, - giantDigit *candVector, - unsigned candLength, - giantDigit *prodVector); - -#ifdef __cplusplus -} -#endif - -#endif /* !PPC_GIANT_PORT_INLINE */ - -#endif /*_CK_NSGIANT_PORT_PPC_GNU_H_*/ diff --git a/OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.s b/OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.s deleted file mode 100644 index 1319b53a..00000000 --- a/OSX/libsecurity_cryptkit/lib/giantPort_PPC_Gnu.s +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (c) 2001,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@ - */ - - -/* - * As of 3/19/2001, using this module results in no change in runtime - * performance compared to using the inline C functions in - * giantPort_Generic.h. Examination of the compiled code shows that - * the GNU C compiler, when configured for -O2, generates almost - * exactly the same code as we have here. - * We'll leave this code in, to protect against changes in gcc, changes - * in CFLAGS, and to serve as an example for other PPC implementations. - */ - -#if defined(__ppc__) && defined(__MACH__) - -/********************************************* - -Add two digits, return sum. Carry bit returned as an out parameter. - -giantDigit giantAddDigits( - register giantDigit dig1, - register giantDigit dig2, - register giantDigit *carry) ...RETURNED, 0 or 1 -**********************************************/ - .text - .align 2 -.globl _giantAddDigits -_giantAddDigits: - /* - * dig1 : r3 - * dig2 : r4 - * carry : r5 - * sum : r6 - */ - - /* sum = dig1 + dig2 */ - add r6, r3, r4; - - /* if((sum < dig1) || (sum < dig2)) */ - cmplw cr0,r6,r3 - blt L1 - cmplw cr0,r6,r4 - bge L2 - -L1: - /* *carry = 1; */ - li r7,1 - stw r7, 0(r5) - b L3 - -L2: - /* else *carry = 0; */ - li r7,0 - stw r7, 0(r5) - -L3: - /* return sum in r3 */ - mr. r3,r6 - blr - -/********************************************* - -Add a single digit value to a double digit accumulator in place. -Carry out of the MSD of the accumulator is not handled. - -void giantAddDouble( - giantDigit *accLow, -- IN/OUT - giantDigit *accHigh, -- IN/OUT - giantDigit val); -**********************************************/ - - .align 2 -.globl _giantAddDouble -_giantAddDouble: - /* - * r3 : accLow - * r4 : accHi - * r5 : val - * r6 : sumLo - * r7 : *accLow - */ - - /* giantDigit sumLo = *accLow + val; */ - lwz r7,0(r3) - add r6,r7,r5 - - /* if((sumLo < *accLow) || (sumLo < val)) { */ - cmplw cr0,r6,r7 - blt L10 - cmplw cr0,r6,r5 - bge L11 - -L10: - /* (*accHigh)++; */ - lwz r7, 0(r4) - addi r7,r7,1 - stw r7, 0(r4) - -L11: - /* *accLow = sumLo; */ - stw r6,0(r3) - blr - -/***************************************************************************** - -Subtract a - b, return difference. Borrow bit returned as an out parameter. - -giantDigit giantSubDigits( - giantDigit a, - giantDigit b, - giantDigit *borrow) -- RETURNED, 0 or 1 - -******************************************************************************/ - - .align 2 -.globl _giantSubDigits -_giantSubDigits: - - /* a : r3 - b : r4 - borrow : r5 - diff : r6 */ - - /* giantDigit diff = a - b; */ - subf r6, r4, r3; - - /* if(a < b) */ - cmplw cr0,r3,r4 - bge L20 - - /* *borrow = 1; */ - li r7,1 - stw r7, 0(r5) - b L21 - -L20: - /* else *borrow = 0; */ - li r7,0 - stw r7, 0(r5) - -L21: - /* return diff in r3 */ - mr. r3,r6 - blr - -/***************************************************************************** - -Multiply two digits, return two digits. - -void giantMulDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *lowProduct, -- RETURNED, low digit - giantDigit *hiProduct) -- RETURNED, high digit - -******************************************************************************/ - - .align 2 -.globl _giantMulDigits -_giantMulDigits: - - /* r3 : dig1 - r4 : dig2 - r5 : lowProduct - r6 : hiProduct */ - - /* dprod = (unsigned long long)dig1 * (unsigned long long)dig2; */ - mullw r7, r3, r4 /* r7 = low(dig1 * dig2) */ - mulhwu r8, r3, r4 /* r8 - hi(dig1 * dig2) */ - - /* *hiProduct = (giantDigit)(dprod >> GIANT_BITS_PER_DIGIT); */ - stw r8, 0(r6) - - /* *lowProduct = (giantDigit)dprod; */ - stw r7, 0(r5) - blr - - -/***************************************************************************** - -Multiply a vector of giantDigits, candVector, by a single giantDigit, -plierDigit, adding results into prodVector. Returns m.s. digit from -final multiply; only candLength digits of *prodVector will be written. - -giantDigit VectorMultiply( - giantDigit plierDigit, - giantDigit *candVector, - unsigned candLength, - giantDigit *prodVector) - -******************************************************************************/ - -/* - * Register definitions - * Input paramters: - */ -#define plierDigit r3 -#define candVector r4 -#define candLength r5 -#define prodVector r6 - -/* - * PPC ABI specifies: - * r3..r10 for parameter passing - * r11, r12 volatile (caller saved, we can write) - * - * We'll use the remainder of the registers normally used for parameter passing - * and also the other volatile register for local variables. - */ -#define candDex r7 -#define lastCarry r8 -#define prodLo r9 -#define prodHi r10 -#define scr1 r11 -#define sumLo r12 - - .align 2 -.globl _VectorMultiply -_VectorMultiply: - - /* giantDigit lastCarry = 0; */ - li lastCarry,0 - - - /* for(candDex=0; candDex scr1 */ - addi candVector,candVector,4 /* candVector++ */ - - mullw prodLo,scr1,plierDigit /* prodLo = low(*candVector * plierDigit) */ - mulhwu prodHi,scr1,plierDigit /* prodHi = high(*candVector * plierDigit) */ - - /* giantAddDouble(&prodLo, &prodHi, *prodVector); */ - lwz scr1,0(prodVector) /* *prodVector --> r9 */ - add sumLo,prodLo,scr1 /* prodLo + *prodVector --> sumLo */ - cmplw cr0,sumLo,prodLo /* sumLo < prodLo? */ - blt L_carry1 - cmplw cr0,sumLo,scr1 /* sumLo < *prodVector? */ - bge L_noCar1 -L_carry1: - addi prodHi,prodHi,1 /* prodHi++ */ -L_noCar1: - mr. prodLo,sumLo /* prodLo := sumLo */ - - /* giantAddDouble(&prodLo, &prodHi, lastCarry); */ - add sumLo,sumLo,lastCarry /* sumLo += lastCarry */ - cmplw cr0,sumLo,prodLo /* sumLo < prodLo? */ - blt L_carry2 - cmplw cr0,sumLo,lastCarry /* sumLo < lastCarry? */ - bge L_noCar2 -L_carry2: - addi prodHi,prodHi,1 /* prodHi++ */ -L_noCar2: - mr. prodLo,sumLo /* prodLo := sumLo */ - - /* *(prodVector++) = prodLo; */ - stw prodLo,0(prodVector) /* prodLo --> *prodVector */ - addi prodVector,prodVector,4 /* prodVector++ */ - - /* lastCarry = prodHi; */ - mr. lastCarry,prodHi - - /* } */ - addi candDex,candDex,1 /* candDex++ */ -L_endLoop: - cmplw cr0,candDex,candLength /* candDex < candLength? */ - blt L_topLoop - - /* return lastCarry; */ - mr. r3,lastCarry /* return lastCarry in r3 */ - blr - -#endif /* defined(__ppc__) && defined(__MACH__) */ diff --git a/OSX/libsecurity_cryptkit/lib/giantPort_i486.h b/OSX/libsecurity_cryptkit/lib/giantPort_i486.h deleted file mode 100644 index b0e74f7b..00000000 --- a/OSX/libsecurity_cryptkit/lib/giantPort_i486.h +++ /dev/null @@ -1,126 +0,0 @@ -/* Copyright (c) 1998,2011,2014 Apple Inc. All Rights Reserved. - * - * NOTICE: USE OF THE MATERIALS ACCOMPANYING THIS NOTICE IS SUBJECT - * TO THE TERMS OF THE SIGNED "FAST ELLIPTIC ENCRYPTION (FEE) REFERENCE - * SOURCE CODE EVALUATION AGREEMENT" BETWEEN APPLE, INC. AND THE - * ORIGINAL LICENSEE THAT OBTAINED THESE MATERIALS FROM APPLE, - * INC. ANY USE OF THESE MATERIALS NOT PERMITTED BY SUCH AGREEMENT WILL - * EXPOSE YOU TO LIABILITY. - *************************************************************************** - * - * giantPorti486.h - OpenStep-dependent giant definitions. - * - * Revision History - * ---------------- - * 06 Apr 1998 at Apple - * Created. - */ - -#ifndef _CK_NSGIANT_PORT_I486_H_ -#define _CK_NSGIANT_PORT_I486_H_ - -#include "giantIntegers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Add two digits, return sum. Carry bit returned as an out parameter. - */ -static inline giantDigit giantAddDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *carry) /* RETURNED, 0 or 1 */ -{ - giantDigit _sum; /* r/w %0 */ - asm volatile( - "movl %2, %0 /* _sum = dig1 */ \n" - "addl %3, %0 /* _sum += dig2 */ \n" - "jc .+9 \n" - "movl $0, %1 /* carry = 0 */ \n" - "jmp .+7 \n" - "movl $1, %1 /* carry = 1 */ \n" - : "=&r" (_sum), "=&r" (*carry) - : "r" (dig1), "r" (dig2)); - return _sum; -} - -/* - * Add a single digit value to a double digit accumulator in place. - * Carry out of the MSD of the accumulator is not handled. - */ -static inline void giantAddDouble( - giantDigit *accLow, /* IN/OUT */ - giantDigit *accHigh, /* IN/OUT */ - giantDigit val) -{ - asm volatile( - "addl %4, %0 /* accLow += val */ \n" - "jnc .+3 \n" - "incl %1 /* accHigh++ */ \n" - : "=&r" (*accLow), "=&r" (*accHigh) - : "0" (*accLow), "1" (*accHigh), "r" (val)); -} - -/* - * Subtract a - b, return difference. Borrow bit returned as an out parameter. - */ -static inline giantDigit giantSubDigits( - giantDigit a, - giantDigit b, - giantDigit *borrow) /* RETURNED, 0 or 1 */ -{ - giantDigit _diff; /* r/w %0 */ - asm volatile( - "movl %2, %0 /* _diff = a */ \n" - "subl %3, %0 /* _diff -= b */ \n" - "jc .+9 \n" - "movl $0, %1 /* borrow = 0 */ \n" - "jmp .+7 \n" - "movl $1, %1 /* borrow = 1 */ \n" - : "=&r" (_diff), "=&r" (*borrow) - : "r" (a), "r" (b)); - return _diff; -} - -/* - * Multiply two digits, return two digits. - */ -static inline void giantMulDigits( - giantDigit dig1, - giantDigit dig2, - giantDigit *lowProduct, // RETURNED, low digit - giantDigit *hiProduct) // RETURNED, high digit - -{ - asm volatile( - "movl %2, %%eax /* eax = dig1 */ \n" - "movl %3, %%edx /* edx = dig2 */ \n" - "mull %%edx /* eax *= dig2 */ \n" - : "=&a" (*lowProduct), "=&d" (*hiProduct) - : "r" (dig1), "r" (dig2) - : "%eax", "%edx" ); -} - -/* - * Multiply a vector of giantDigits, candVector, by a single giantDigit, - * plierDigit, adding results into prodVector. Returns m.s. digit from - * final multiply; only candLength digits of *prodVector will be written. - * - * This one's implemented in a .s file. - */ -extern giantDigit vectorMult_x86( - giantDigit plierDigit, - giantDigit *candVector, - unsigned candLength, - giantDigit *prodVector); - -#define VectorMultiply(pd, cv, cl, pv) vectorMult_x86(pd, cv, cl, pv) - - -#ifdef __cplusplus -} -#endif - -#endif _CK_NSGIANT_PORT_I486_H_ diff --git a/OSX/libsecurity_cryptkit/lib/platform.c b/OSX/libsecurity_cryptkit/lib/platform.c index 30480d86..371d98f1 100644 --- a/OSX/libsecurity_cryptkit/lib/platform.c +++ b/OSX/libsecurity_cryptkit/lib/platform.c @@ -20,33 +20,9 @@ #include #include "feeDebug.h" -#ifdef NeXT - -/* - * OpenStep.... - */ -void CKRaise(const char *reason) { - #if FEE_DEBUG - printf("CryptKit fatal error: %s\n", reason); - #endif - abort(); -} - -#elif WIN32 - -/* - * OpenStep on Windows. - */ - -void CKRaise(const char *reason) { - #if FEE_DEBUG - printf("CryptKit fatal error: %s\n", reason); - #endif - abort(); -} - -#elif __MAC_BUILD__ +#import "feeDebug.h" +#if __MAC_BUILD__ /* * Macintosh, all flavors. */ @@ -66,17 +42,6 @@ void CKRaise(const char *reason) { abort(); } -#elif unix - -/* try for generic UNIX */ - -void CKRaise(const char *reason) { - #if FEE_DEBUG - printf("CryptKit fatal error: %s\n", reason); - #endif - abort(); -} - #else #error platform-specific work needed in security_cryptkit/platform.c diff --git a/OSX/libsecurity_cssm/lib/cssmapplePriv.h b/OSX/libsecurity_cssm/lib/cssmapplePriv.h index 597434fd..c9dbc727 100644 --- a/OSX/libsecurity_cssm/lib/cssmapplePriv.h +++ b/OSX/libsecurity_cssm/lib/cssmapplePriv.h @@ -67,12 +67,12 @@ enum { CSSM_TP_OCSP_REQUIRE_RESP_NONCE = 0x00000080 }; -typedef struct { +typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER { uint32 Version; CSSM_APPLE_TP_OCSP_OPT_FLAGS Flags; CSSM_DATA_PTR LocalResponder; /* URI */ CSSM_DATA_PTR LocalResponderCert; /* X509 DER encoded cert */ -} CSSM_APPLE_TP_OCSP_OPTIONS; +} CSSM_APPLE_TP_OCSP_OPTIONS DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; enum { diff --git a/OSX/libsecurity_cssm/lib/cssmtype.h b/OSX/libsecurity_cssm/lib/cssmtype.h index 0dd97461..246a16c9 100644 --- a/OSX/libsecurity_cssm/lib/cssmtype.h +++ b/OSX/libsecurity_cssm/lib/cssmtype.h @@ -27,6 +27,7 @@ #define _CSSMTYPE_H_ 1 #include +#include /* ========================================================================== W A R N I N G : CDSA has been deprecated starting with 10.7. While the @@ -89,10 +90,8 @@ enum { }; typedef char CSSM_STRING [CSSM_MODULE_STRING_SIZE + 4]; -typedef struct cssm_data { - CSSM_SIZE Length; /* in bytes */ - uint8 *Data; -} CSSM_DATA DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER, *CSSM_DATA_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; +#define CSSM_DATA SecAsn1Item +typedef SecAsn1Item *CSSM_DATA_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef struct cssm_guid { uint32 Data1; @@ -1273,7 +1272,8 @@ typedef CSSM_RETURN (CSSMAPI * CSSM_TP_VERIFICATION_RESULTS_CALLBACK) CSSM_DATA_PTR VerifiedCert) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* From CL */ -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; +#define CSSM_OID SecAsn1Oid +typedef SecAsn1Oid *CSSM_OID_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_field { CSSM_OID FieldOid; diff --git a/OSX/libsecurity_cssm/lib/x509defs.h b/OSX/libsecurity_cssm/lib/x509defs.h index 0f011608..5a5f31e4 100644 --- a/OSX/libsecurity_cssm/lib/x509defs.h +++ b/OSX/libsecurity_cssm/lib/x509defs.h @@ -69,11 +69,8 @@ typedef uint8 CSSM_BER_TAG; /* Data Structures for X.509 Certificates */ - -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; +#define CSSM_X509_ALGORITHM_IDENTIFIER SecAsn1AlgId +typedef SecAsn1AlgId *CSSM_X509_ALGORITHM_IDENTIFIER_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* X509 Distinguished name structure */ typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_type_value_pair { @@ -94,10 +91,8 @@ typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_name { } 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 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; +#define CSSM_X509_SUBJECT_PUBLIC_KEY_INFO SecAsn1PubKeyInfo +typedef SecAsn1PubKeyInfo *CSSM_X509_SUBJECT_PUBLIC_KEY_INFO_PTR DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; typedef struct DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER cssm_x509_time { CSSM_BER_TAG timeType; diff --git a/OSX/libsecurity_filedb/lib/AtomicFile.cpp b/OSX/libsecurity_filedb/lib/AtomicFile.cpp index 9dd9bbfd..6c21d12d 100644 --- a/OSX/libsecurity_filedb/lib/AtomicFile.cpp +++ b/OSX/libsecurity_filedb/lib/AtomicFile.cpp @@ -18,10 +18,10 @@ #include -#include #include #include #include +#include #include #include #include @@ -962,7 +962,6 @@ std::string NetworkFileLocker::unique(mode_t mode) { static const int randomPart = 16; - DevRandomGenerator randomGen; std::string::size_type dirSize = mDir.size(); std::string fullname(dirSize + randomPart + 2, '\0'); fullname.replace(0, dirSize, mDir); @@ -974,7 +973,7 @@ NetworkFileLocker::unique(mode_t mode) for (int retries = 0; retries < 10; ++retries) { /* Make a random filename. */ - randomGen.random(buf, randomPart); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, randomPart, buf)); for (int ix = 0; ix < randomPart; ++ix) { char ch = buf[ix] & 0x3f; diff --git a/OSX/libsecurity_keychain/lib/ACL.cpp b/OSX/libsecurity_keychain/lib/ACL.cpp index 3c328bf4..77beb3ad 100644 --- a/OSX/libsecurity_keychain/lib/ACL.cpp +++ b/OSX/libsecurity_keychain/lib/ACL.cpp @@ -31,8 +31,7 @@ #include #include #include -#include -#include +#include #include @@ -108,7 +107,7 @@ ACL::ACL(Allocator &alloc) mPromptSelector = defaultSelector; // randomize the CSSM handle - UniformRandomBlobs().random(mCssmHandle); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mCssmHandle), (void *)mCssmHandle)); } @@ -129,7 +128,7 @@ ACL::ACL(string description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR &promptSele mPromptSelector = promptSelector; // randomize the CSSM handle - UniformRandomBlobs().random(mCssmHandle); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mCssmHandle), &mCssmHandle)); } @@ -149,7 +148,7 @@ ACL::ACL(const CssmData &digest, Allocator &alloc) //mPromptSelector stays empty // randomize the CSSM handle - UniformRandomBlobs().random(mCssmHandle); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mCssmHandle), &mCssmHandle)); } diff --git a/OSX/libsecurity_keychain/lib/Access.cpp b/OSX/libsecurity_keychain/lib/Access.cpp index 64da867e..032bbb6e 100644 --- a/OSX/libsecurity_keychain/lib/Access.cpp +++ b/OSX/libsecurity_keychain/lib/Access.cpp @@ -27,11 +27,10 @@ #include #include #include "SecBridge.h" -#include -#include +#include #include #include -#include +#include using namespace KeychainCore; using namespace CssmClient; @@ -364,8 +363,9 @@ Access::Maker::Maker(Allocator &alloc, MakerType makerType) { // generate random key mKey.malloc(keySize); - UniformRandomBlobs().random(mKey.get()); - + CssmData data = mKey.get(); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, data.length(), data.data())); + // create entry info for resource creation mInput = AclEntryPrototype(TypedList(allocator, CSSM_ACL_SUBJECT_TYPE_PASSWORD, new(allocator) ListElement(mKey.get()))); diff --git a/OSX/libsecurity_keychain/lib/Certificate.cpp b/OSX/libsecurity_keychain/lib/Certificate.cpp index 81dc8699..2ee5cbc2 100644 --- a/OSX/libsecurity_keychain/lib/Certificate.cpp +++ b/OSX/libsecurity_keychain/lib/Certificate.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include diff --git a/OSX/libsecurity_keychain/lib/CertificateValues.cpp b/OSX/libsecurity_keychain/lib/CertificateValues.cpp index 66470a3f..a2f1ec1b 100644 --- a/OSX/libsecurity_keychain/lib/CertificateValues.cpp +++ b/OSX/libsecurity_keychain/lib/CertificateValues.cpp @@ -49,9 +49,8 @@ extern const CFStringRef __nonnull kSecPropertyTypeData; extern const CFStringRef __nonnull kSecPropertyTypeString; extern const CFStringRef __nonnull kSecPropertyTypeURL; extern const CFStringRef __nonnull kSecPropertyTypeDate; - -CFStringRef kSecPropertyTypeArray = CFSTR("array"); -CFStringRef kSecPropertyTypeNumber = CFSTR("number"); +extern const CFStringRef __nonnull kSecPropertyTypeArray; +extern const CFStringRef __nonnull kSecPropertyTypeNumber; #pragma mark ---------- CertificateValues Implementation ---------- diff --git a/OSX/libsecurity_keychain/lib/Identity.cpp b/OSX/libsecurity_keychain/lib/Identity.cpp index 52be5fec..85b0636d 100644 --- a/OSX/libsecurity_keychain/lib/Identity.cpp +++ b/OSX/libsecurity_keychain/lib/Identity.cpp @@ -61,7 +61,7 @@ Identity::Identity(const StorageManager::KeychainList &keychains, const SecPoint kCFAllocatorNull); // First, try the new iOS keychain. { - const void *keys[] = { kSecClass, kSecAttrKeyClass, kSecAttrApplicationLabel, kSecReturnRef, kSecAttrNoLegacy }; + const void *keys[] = { kSecClass, kSecAttrKeyClass, kSecAttrApplicationLabel, kSecReturnRef, kSecUseDataProtectionKeychain }; const void *values[] = { kSecClassKey, kSecAttrKeyClassPrivate, keyHash, kCFBooleanTrue, kCFBooleanTrue }; CFRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), diff --git a/OSX/libsecurity_keychain/lib/IdentityCursor.cpp b/OSX/libsecurity_keychain/lib/IdentityCursor.cpp index 7a19a2ca..519b47c2 100644 --- a/OSX/libsecurity_keychain/lib/IdentityCursor.cpp +++ b/OSX/libsecurity_keychain/lib/IdentityCursor.cpp @@ -275,7 +275,7 @@ IdentityCursor::~IdentityCursor() throw() { } -CFDataRef +CFDataRef CF_RETURNS_RETAINED IdentityCursor::pubKeyHashForSystemIdentity(CFStringRef domain) { StLock_(mMutex); diff --git a/OSX/libsecurity_keychain/lib/Item.cpp b/OSX/libsecurity_keychain/lib/Item.cpp index bea27fec..474aba73 100644 --- a/OSX/libsecurity_keychain/lib/Item.cpp +++ b/OSX/libsecurity_keychain/lib/Item.cpp @@ -46,9 +46,7 @@ #include #include -#include - -#define SENDACCESSNOTIFICATIONS 1 +#include //%%% schema indexes should be defined in Schema.h #define _kSecAppleSharePasswordItemClass 'ashp' @@ -1415,23 +1413,12 @@ ItemImpl::getContent(SecItemClass *itemClass, SecKeychainAttributeList *attrList { getLocalContent(attrList, length, outData); } - - // Inform anyone interested that we are doing this -#if SENDACCESSNOTIFICATIONS - if (outData) - { - secinfo("kcnotify", "ItemImpl::getContent(%p, %p, %p, %p) retrieved content", - itemClass, attrList, length, outData); - - KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this); - } -#endif } void ItemImpl::freeContent(SecKeychainAttributeList *attrList, void *data) { - Allocator &allocator = Allocator::standard(); // @@@ This might not match the one used originally + Allocator &allocator = Allocator::standard(Allocator::sensitive); // @@@ This might not match the one used originally if (data) allocator.free(data); @@ -1573,13 +1560,6 @@ ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *ite if (length) *length=(UInt32)itemData.length(); itemData.Length=0; - -#if SENDACCESSNOTIFICATIONS - secinfo("kcnotify", "ItemImpl::getAttributesAndData(%p, %p, %p, %p, %p) retrieved data", - info, itemClass, attrList, length, outData); - - KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this); -#endif } } @@ -1587,7 +1567,7 @@ ItemImpl::getAttributesAndData(SecKeychainAttributeInfo *info, SecItemClass *ite void ItemImpl::freeAttributesAndData(SecKeychainAttributeList *attrList, void *data) { - Allocator &allocator = Allocator::standard(); // @@@ This might not match the one used originally + Allocator &allocator = Allocator::standard(Allocator::sensitive); // @@@ This might not match the one used originally if (data) allocator.free(data); @@ -1740,13 +1720,6 @@ ItemImpl::getData(CssmDataContainer& outData) } getContent(NULL, &outData); - -#if SENDACCESSNOTIFICATIONS - secinfo("kcnotify", "ItemImpl::getData retrieved data"); - - //%%% be done elsewhere, but here is good for now - KCEventNotifier::PostKeychainEvent(kSecDataAccessEvent, mKeychain, this); -#endif } SSGroup diff --git a/OSX/libsecurity_keychain/lib/KCCursor.cpp b/OSX/libsecurity_keychain/lib/KCCursor.cpp index a5d25d96..ad7039cf 100644 --- a/OSX/libsecurity_keychain/lib/KCCursor.cpp +++ b/OSX/libsecurity_keychain/lib/KCCursor.cpp @@ -35,7 +35,7 @@ #include "Globals.h" #include "StorageManager.h" #include -#include +#include #include #include diff --git a/OSX/libsecurity_keychain/lib/KCExceptions.h b/OSX/libsecurity_keychain/lib/KCExceptions.h index 4f1fb819..69cf8435 100644 --- a/OSX/libsecurity_keychain/lib/KCExceptions.h +++ b/OSX/libsecurity_keychain/lib/KCExceptions.h @@ -29,7 +29,7 @@ #define _SECURITY_KCEXCEPTIONS_H_ #include -#include +#include #ifdef lock #undef lock #endif diff --git a/OSX/libsecurity_keychain/lib/KCUtilities.h b/OSX/libsecurity_keychain/lib/KCUtilities.h index b0174e5b..b6c0a01d 100644 --- a/OSX/libsecurity_keychain/lib/KCUtilities.h +++ b/OSX/libsecurity_keychain/lib/KCUtilities.h @@ -25,7 +25,7 @@ #define _SECURITY_KCUTILITIES_H_ #include -#include +#include namespace Security { diff --git a/OSX/libsecurity_keychain/lib/KeyItem.cpp b/OSX/libsecurity_keychain/lib/KeyItem.cpp index fed9dae0..6bec5672 100644 --- a/OSX/libsecurity_keychain/lib/KeyItem.cpp +++ b/OSX/libsecurity_keychain/lib/KeyItem.cpp @@ -38,8 +38,8 @@ #include #include "KCEventNotifier.h" #include -#include -#include +#include +#include #include // @@@ This needs to be shared. @@ -81,7 +81,7 @@ KeyItem::operator CFTypeRef() const throw() if (mWeakSecKeyRef != NULL) { if (_CFTryRetain(mWeakSecKeyRef) == NULL) { - StMaybeLock secKeyCDSAMutex(mWeakSecKeyRef->cdsaKeyMutex); + StMaybeLock secKeyCDSAMutex(static_cast(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 a1a6716c..8f048f5c 100644 --- a/OSX/libsecurity_keychain/lib/KeyItem.h +++ b/OSX/libsecurity_keychain/lib/KeyItem.h @@ -164,11 +164,12 @@ private: } // end namespace Security -struct OpaqueSecKeyRef { - CFRuntimeBase _base; - const SecKeyDescriptor *key_class; - SecKeyRef cdsaKey; - Security::KeychainCore::KeyItem *key; +class CDSASecKey : public __SecKey { +public: + static Security::KeychainCore::KeyItem *keyItem(SecKeyRef key) { + CDSASecKey *cdsaKey = static_cast(key); + return static_cast(cdsaKey->key); + } SecCredentialType credentialType; Mutex *cdsaKeyMutex; }; diff --git a/OSX/libsecurity_keychain/lib/SecACL.h b/OSX/libsecurity_keychain/lib/SecACL.h index abc9f814..1bb1101d 100644 --- a/OSX/libsecurity_keychain/lib/SecACL.h +++ b/OSX/libsecurity_keychain/lib/SecACL.h @@ -81,7 +81,7 @@ CF_IMPLICIT_BRIDGING_ENABLED CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector, SecACLRef * __nonnull CF_RETURNS_RETAINED newAcl) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecACLCreateWithSimpleContents @@ -124,7 +124,7 @@ CF_IMPLICIT_BRIDGING_ENABLED CFArrayRef * __nonnull CF_RETURNS_RETAINED applicationList, CFStringRef * __nonnull CF_RETURNS_RETAINED description, CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecACLCopyContents @@ -155,7 +155,7 @@ CF_IMPLICIT_BRIDGING_ENABLED CFArrayRef __nullable applicationList, CFStringRef description, const CSSM_ACL_KEYCHAIN_PROMPT_SELECTOR *promptSelector) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecACLSetContents @@ -186,7 +186,7 @@ CF_IMPLICIT_BRIDGING_ENABLED */ OSStatus SecACLGetAuthorizations(SecACLRef acl, CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 *tagCount) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecACLCopyAuthorizations @@ -209,7 +209,7 @@ CF_IMPLICIT_BRIDGING_ENABLED */ OSStatus SecACLSetAuthorizations(SecACLRef acl, CSSM_ACL_AUTHORIZATION_TAG *tags, uint32 tagCount) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! diff --git a/OSX/libsecurity_keychain/lib/SecAccess.cpp b/OSX/libsecurity_keychain/lib/SecAccess.cpp index 301cf0e5..91680d82 100644 --- a/OSX/libsecurity_keychain/lib/SecAccess.cpp +++ b/OSX/libsecurity_keychain/lib/SecAccess.cpp @@ -21,7 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#include #include #include #include @@ -321,8 +321,6 @@ SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAcce CFRelease(debugStr); #endif - CFIndex rightsSize = numAcls > 0 ? numAcls : 1; - std::vector rights(numAcls); for (CFIndex iCnt = 0; iCnt < numAcls; iCnt++) diff --git a/OSX/libsecurity_keychain/lib/SecAccess.h b/OSX/libsecurity_keychain/lib/SecAccess.h index 4a8340d4..d9e151ce 100644 --- a/OSX/libsecurity_keychain/lib/SecAccess.h +++ b/OSX/libsecurity_keychain/lib/SecAccess.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2002-2004,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, @@ -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@ */ @@ -97,11 +97,11 @@ extern const CFStringRef kSecACLAuthorizationKeychainItemModify __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); extern const CFStringRef kSecACLAuthorizationKeychainItemDelete __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); - -extern const CFStringRef kSecACLAuthorizationChangeACL - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + +extern const CFStringRef kSecACLAuthorizationChangeACL + __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_NA); extern const CFStringRef kSecACLAuthorizationChangeOwner - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_NA); extern const CFStringRef kSecACLAuthorizationPartitionID __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_NA); extern const CFStringRef kSecACLAuthorizationIntegrity @@ -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) API_UNAVAILABLE(ios); +OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef __nullable trustedlist, SecAccessRef * __nonnull CF_RETURNS_RETAINED accessRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecAccessCreateFromOwnerAndACL @@ -140,8 +140,8 @@ OSStatus SecAccessCreate(CFStringRef descriptor, CFArrayRef __nullable trustedli @discussion For 10.7 and later please use the SecAccessCreateWithOwnerAndACL API */ OSStatus SecAccessCreateFromOwnerAndACL(const CSSM_ACL_OWNER_PROTOTYPE *owner, uint32 aclCount, const CSSM_ACL_ENTRY_INFO *acls, SecAccessRef * __nonnull CF_RETURNS_RETAINED accessRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - + CSSM_DEPRECATED; + /*! @function SecAccessCreateWithOwnerAndACL @abstract Creates a new SecAccessRef using either for a user or a group with a list of ACLs @@ -167,8 +167,8 @@ SecAccessRef SecAccessCreateWithOwnerAndACL(uid_t userId, gid_t groupId, SecAcce @discussion For 10.7 and later please use the SecAccessCopyOwnerAndACL API */ OSStatus SecAccessGetOwnerAndACL(SecAccessRef accessRef, CSSM_ACL_OWNER_PROTOTYPE_PTR __nullable * __nonnull owner, uint32 *aclCount, CSSM_ACL_ENTRY_INFO_PTR __nullable * __nonnull acls) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - + CSSM_DEPRECATED; + /*! @function SecAccessCopyOwnerAndACL @abstract Retrieves the owner and the access control list of a given access. @@ -178,7 +178,7 @@ OSStatus SecAccessGetOwnerAndACL(SecAccessRef accessRef, CSSM_ACL_OWNER_PROTOTYP @param ownerType On return, the type of owner for this AccessRef @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 SecAccessCopyOwnerAndACL(SecAccessRef accessRef, uid_t * __nullable userId, gid_t * __nullable groupId, SecAccessOwnerType * __nullable ownerType, CFArrayRef * __nullable CF_RETURNS_RETAINED aclList) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); @@ -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) API_UNAVAILABLE(ios); +OSStatus SecAccessCopyACLList(SecAccessRef accessRef, CFArrayRef * __nonnull CF_RETURNS_RETAINED aclList) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecAccessCopySelectedACLList @@ -201,7 +201,7 @@ OSStatus SecAccessCopyACLList(SecAccessRef accessRef, CFArrayRef * __nonnull CF_ @discussion For 10.7 and later please use the SecAccessCopyMatchingACLList API */ OSStatus SecAccessCopySelectedACLList(SecAccessRef accessRef, CSSM_ACL_AUTHORIZATION_TAG action, CFArrayRef * __nonnull CF_RETURNS_RETAINED aclList) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! diff --git a/OSX/libsecurity_keychain/lib/SecAccessPriv.h b/OSX/libsecurity_keychain/lib/SecAccessPriv.h index cf665b3a..9596f4fc 100644 --- a/OSX/libsecurity_keychain/lib/SecAccessPriv.h +++ b/OSX/libsecurity_keychain/lib/SecAccessPriv.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2002-2004,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, @@ -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@ */ @@ -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") API_UNAVAILABLE(ios); + UInt32 passwordLength, const void *passwordData, SecKeychainItemRef *itemRef) __deprecated_msg("iTools is no longer supported") API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecAccessCreateWithTrustedApplications @@ -50,12 +50,12 @@ OSStatus SecKeychainAddIToolsPassword(SecKeychainRef keychain, UInt32 accountNam @param allowAny Flag that determines allow access to any application. @param returnedAccess On return, a new SecAccessRef. @result A result code. See "Security Error Codes" (SecBase.h). - @discussion The SecAccessCreateWithPList creates a SecAccess with the provided list of trusted applications. + @discussion The SecAccessCreateWithPList creates a SecAccess with the provided list of trusted applications. */ -OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess) API_UNAVAILABLE(ios); +OSStatus SecAccessCreateWithTrustedApplications(CFStringRef trustedApplicationsPListPath, CFStringRef accessLabel, Boolean allowAny, SecAccessRef* returnedAccess) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + - #if defined(__cplusplus) } #endif diff --git a/OSX/libsecurity_keychain/lib/SecBase.cpp b/OSX/libsecurity_keychain/lib/SecBase.cpp index 2f5c1571..2d82dd36 100644 --- a/OSX/libsecurity_keychain/lib/SecBase.cpp +++ b/OSX/libsecurity_keychain/lib/SecBase.cpp @@ -27,7 +27,7 @@ #include #include #include "SecBridge.h" -#include "SecFramework.h" +#include static CFStringRef copyErrorMessageFromBundle(OSStatus status,CFStringRef tableName); @@ -300,7 +300,7 @@ OSStatus SecKeychainErrFromOSStatus(OSStatus osStatus) case CSSMERR_DL_DATASTORE_ALREADY_EXISTS: return errSecDuplicateKeychain; case CSSMERR_APPLEDL_DISK_FULL: - return errSecDskFull; + return errSecDiskFull; case CSSMERR_DL_INVALID_OPEN_PARAMETERS: case CSSMERR_APPLEDL_INVALID_OPEN_PARAMETERS: case CSSMERR_APPLE_DOTMAC_REQ_SERVER_PARAM: diff --git a/OSX/libsecurity_keychain/lib/SecBridge.h b/OSX/libsecurity_keychain/lib/SecBridge.h index ed923939..c52a5b29 100644 --- a/OSX/libsecurity_keychain/lib/SecBridge.h +++ b/OSX/libsecurity_keychain/lib/SecBridge.h @@ -26,7 +26,7 @@ #include #include -#include "SecBasePriv.h" +#include #include #include #include diff --git a/OSX/libsecurity_keychain/lib/SecCertificate.cpp b/OSX/libsecurity_keychain/lib/SecCertificate.cpp index dcd447b4..7c1e40b4 100644 --- a/OSX/libsecurity_keychain/lib/SecCertificate.cpp +++ b/OSX/libsecurity_keychain/lib/SecCertificate.cpp @@ -407,7 +407,7 @@ SecCertificateFindByIssuerAndSN(CFTypeRef keychainOrArray,const CSSM_DATA *issue CFRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(query, kSecClass, kSecClassCertificate); CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue); - CFDictionarySetValue(query, kSecAttrNoLegacy, kCFBooleanTrue); + CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue); CFRef issuerData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)issuer->Data, issuer->Length, kCFAllocatorNull); CFDictionarySetValue(query, kSecAttrIssuer, issuerData); @@ -446,7 +446,7 @@ SecCertificateFindBySubjectKeyID(CFTypeRef keychainOrArray, const CSSM_DATA *sub CFRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(query, kSecClass, kSecClassCertificate); CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue); - CFDictionarySetValue(query, kSecAttrNoLegacy, kCFBooleanTrue); + CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue); CFRef subjectKeyIDData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)subjectKeyID->Data, subjectKeyID->Length, kCFAllocatorNull); CFDictionarySetValue(query, kSecAttrSubjectKeyID, subjectKeyIDData); @@ -481,7 +481,7 @@ SecCertificateFindByEmail(CFTypeRef keychainOrArray, const char *emailAddress, S CFRef query = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); CFDictionarySetValue(query, kSecClass, kSecClassCertificate); CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue); - CFDictionarySetValue(query, kSecAttrNoLegacy, kCFBooleanTrue); + CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue); CFRef emailAddressString = CFStringCreateWithCString(kCFAllocatorDefault, emailAddress, kCFStringEncodingUTF8); CFTypeRef keys[] = { kSecPolicyName }; diff --git a/OSX/libsecurity_keychain/lib/SecFDERecoveryAsymmetricCrypto.cpp b/OSX/libsecurity_keychain/lib/SecFDERecoveryAsymmetricCrypto.cpp index 8d341bf2..187ee9c8 100644 --- a/OSX/libsecurity_keychain/lib/SecFDERecoveryAsymmetricCrypto.cpp +++ b/OSX/libsecurity_keychain/lib/SecFDERecoveryAsymmetricCrypto.cpp @@ -100,9 +100,13 @@ static void encodePrivateKeyHeader(const CssmData &inBlob, CFDataRef certificate passThrough(CSSM_APPLECSP_KEYDIGEST, NULL, &outData); CssmData *cssmData = reinterpret_cast(outData); - assert(cssmData->Length <= sizeof(outHeader.publicKeyHash)); outHeader.publicKeyHashSize = (uint32_t)cssmData->Length; - memcpy(outHeader.publicKeyHash, cssmData->Data, cssmData->Length); + if (outHeader.publicKeyHashSize > sizeof(outHeader.publicKeyHash)) { + secinfo("FDERecovery", "encodePrivateKeyHeader: publicKeyHash too big: %d", outHeader.publicKeyHashSize); + outHeader.publicKeyHashSize = 0; /* failed to copy hash value */ + } else { + memcpy(outHeader.publicKeyHash, cssmData->Data, outHeader.publicKeyHashSize); + } fCSP.allocator().free(cssmData->Data); fCSP.allocator().free(cssmData); diff --git a/OSX/libsecurity_keychain/lib/SecImportExport.c b/OSX/libsecurity_keychain/lib/SecImportExport.c index 38701153..2b8f820d 100644 --- a/OSX/libsecurity_keychain/lib/SecImportExport.c +++ b/OSX/libsecurity_keychain/lib/SecImportExport.c @@ -31,13 +31,15 @@ #include #include #include -#include "SecInternal.h" +#include //#include #include //#include "p12import.h" -#include +#include + +#include const CFStringRef __nonnull kSecImportExportPassphrase = CFSTR("passphrase"); const CFStringRef __nonnull kSecImportExportKeychain = CFSTR("keychain"); @@ -139,6 +141,9 @@ out: OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArrayRef *items) { + if (_CFMZEnabled()) { + return SecPKCS12Import_ios(pkcs12_data, options, items); + } // SecPKCS12Import is implemented on Mac OS X in terms of the existing // SecKeychainItemImport API, which supports importing items into a // specified keychain with initial access control settings for keys. diff --git a/OSX/libsecurity_keychain/lib/SecImportExportCrypto.cpp b/OSX/libsecurity_keychain/lib/SecImportExportCrypto.cpp index f3cf841e..dbdd5875 100644 --- a/OSX/libsecurity_keychain/lib/SecImportExportCrypto.cpp +++ b/OSX/libsecurity_keychain/lib/SecImportExportCrypto.cpp @@ -31,13 +31,12 @@ #include "Keychains.h" #include "Access.h" #include "Item.h" -#include "SecKeyPriv.h" +#include #include "KCEventNotifier.h" #include #include #include #include -#include #include #include #include @@ -395,9 +394,8 @@ OSStatus impExpImportKeyCommon( char *randAscii = (char *)randLabel; uint8 randBinary[SEC_RANDOM_LABEL_LEN / 2]; unsigned randBinaryLen = SEC_RANDOM_LABEL_LEN / 2; - DevRandomGenerator rng; - - rng.random(randBinary, randBinaryLen); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, randBinaryLen, randBinary)); + for(unsigned i=0; i #include #include -#include #include #include #include @@ -828,7 +827,6 @@ OSStatus impExpPkcs8Export( CFMutableDataRef outData, // output appended here const char **pemHeader) { - DevRandomGenerator rng; SecNssCoder coder; impExpPKCS5_PBES2_Params pbes2Params; CSSM_X509_ALGORITHM_IDENTIFIER &keyDeriveAlgId = pbes2Params.keyDerivationFunc; @@ -853,7 +851,8 @@ OSStatus impExpPkcs8Export( impExpPKCS5_PBKDF2_Params pbkdf2Params; memset(&pbkdf2Params, 0, sizeof(pbkdf2Params)); coder.allocItem(pbkdf2Params.salt, PKCS5_V2_SALT_LEN); - rng.random(pbkdf2Params.salt.Data, PKCS5_V2_SALT_LEN); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, PKCS5_V2_SALT_LEN, pbkdf2Params.salt.Data)); + p12IntToData(PKCS5_V2_ITERATIONS, pbkdf2Params.iterationCount, coder); /* leave pbkdf2Params.keyLengthInBytes NULL for default */ /* openssl can't handle this, which is the default value: @@ -871,7 +870,7 @@ OSStatus impExpPkcs8Export( encrScheme.algorithm = CSSMOID_PKCS5_DES_EDE3_CBC; CSSM_DATA rawIv = {0, NULL}; coder.allocItem(rawIv, PKCS5_V2_DES_IV_SIZE); - rng.random(rawIv.Data, PKCS5_V2_DES_IV_SIZE); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, PKCS5_V2_DES_IV_SIZE, rawIv.Data)); coder.encodeItem(&rawIv, kSecAsn1OctetStringTemplate, encrScheme.parameters); diff --git a/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp b/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp index ab2017ec..d89931d8 100644 --- a/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp +++ b/OSX/libsecurity_keychain/lib/SecImportExportUtils.cpp @@ -26,8 +26,8 @@ #include "SecImportExportUtils.h" #include "SecImportExportAgg.h" #include "SecImportExportCrypto.h" -#include "SecIdentityPriv.h" -#include "SecItem.h" +#include +#include #include #include #include diff --git a/OSX/libsecurity_keychain/lib/SecItem.cpp b/OSX/libsecurity_keychain/lib/SecItem.cpp index ad88d453..40122c76 100644 --- a/OSX/libsecurity_keychain/lib/SecItem.cpp +++ b/OSX/libsecurity_keychain/lib/SecItem.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -22,7 +22,7 @@ */ #include "SecBridge.h" -#include "SecInternal.h" +#include #include #include #include @@ -31,11 +31,12 @@ #include #include #include "cssmdatetime.h" -#include "SecItem.h" -#include "SecItemPriv.h" -#include "SecIdentitySearchPriv.h" -#include "SecKeychainPriv.h" -#include "SecCertificatePriv.h" +#include +#include +#include +#include +#include +#include #include "TrustAdditions.h" #include "TrustSettingsSchema.h" #include @@ -587,22 +588,27 @@ _ConvertNewFormatToOldFormat( // now we can make the result array attrList->count = (UInt32)count; - attrList->attr = (count > 0) ? (SecKeychainAttribute*) malloc(sizeof(SecKeychainAttribute) * count) : NULL; - // fill out the array - int resultPointer = 0; - for (i = 0; i < itemsInDictionary; ++i) - { - if (values[i] != NULL) - { - attrList->attr[resultPointer].tag = tags[i]; + if(count == 0) { + attrList->attr = NULL; + } else { + attrList->attr = (SecKeychainAttribute*) malloc(sizeof(SecKeychainAttribute) * count); - // we have to clone the data pointer. The caller will need to make sure to throw these away - // with _FreeAttrList when it is done... - attrList->attr[resultPointer].data = CloneDataByType(types[i], values[i], attrList->attr[resultPointer].length); - resultPointer += 1; - } - } + // fill out the array + int resultPointer = 0; + for (i = 0; i < itemsInDictionary; ++i) + { + if (values[i] != NULL) + { + attrList->attr[resultPointer].tag = tags[i]; + + // we have to clone the data pointer. The caller will need to make sure to throw these away + // with _FreeAttrList when it is done... + attrList->attr[resultPointer].data = CloneDataByType(types[i], values[i], attrList->attr[resultPointer].length); + resultPointer += 1; + } + } + } return errSecSuccess; } @@ -1576,7 +1582,7 @@ _CreateSecKeychainKeyAttributeListFromDictionary( // [5] get the kSecKeyKeyType number if (CFDictionaryGetValueIfPresent(attrDictionary, kSecAttrKeyType, (const void **)&value) && value) { - UInt32 keyAlgValue = _SecAlgorithmTypeFromSecAttrKeyType(kSecAttrKeyType); + UInt32 keyAlgValue = _SecAlgorithmTypeFromSecAttrKeyType(value); if (keyAlgValue != 0) { attrListPtr->attr[attrListPtr->count].data = malloc(sizeof(UInt32)); require_action(attrListPtr->attr[attrListPtr->count].data != NULL, malloc_number_failed, status = errSecBufferTooSmall); @@ -3274,6 +3280,7 @@ _FilterWithPolicy(SecPolicyRef policy, CFDateRef date, SecCertificateRef cert) SecTrustResultType trustResult; Boolean needChain = false; + Boolean needCSEKU = false; OSStatus status; if (!policy || !cert) return errSecParam; @@ -3287,13 +3294,33 @@ _FilterWithPolicy(SecPolicyRef policy, CFDateRef date, SecCertificateRef cert) if(status) goto cleanup; } - /* Check whether this is the X509 Basic policy, which means chain building */ + /* Check whether we can avoid full chain evaluation, based on policy */ props = SecPolicyCopyProperties(policy); if (props) { CFTypeRef oid = (CFTypeRef) CFDictionaryGetValue(props, kSecPolicyOid); if (oid && (CFEqual(oid, kSecPolicyAppleX509Basic) || - CFEqual(oid, kSecPolicyAppleRevocation))) { + CFEqual(oid, kSecPolicyAppleRevocation))) { needChain = true; + } else if (oid && (CFEqual(oid, kSecPolicyAppleCodeSigning))) { + needCSEKU = true; + } + } + + /* If a code signing EKU purpose is needed, filter out certs without it here + to reduce log noise associated with evaluation failures. */ + if (needCSEKU) { + CFDataRef eku = CFDataCreate(kCFAllocatorDefault, + oidExtendedKeyUsageCodeSigning.data, + oidExtendedKeyUsageCodeSigning.length); + if (eku) { + if (!SecPolicyCheckCertExtendedKeyUsage(cert, eku)) { + needCSEKU = false; + } + CFRelease(eku); + } + if (!needCSEKU) { + status = errSecCertificateCannotOperate; + goto cleanup; } } @@ -4011,23 +4038,32 @@ extern "C" Boolean SecKeyIsCDSAKey(SecKeyRef ref); // // Function to find out which keychains are targetted by the query. // -static OSStatus SecItemCategorizeQuery(CFDictionaryRef query, bool &can_target_ios, bool &can_target_osx) +static OSStatus SecItemCategorizeQuery(CFDictionaryRef query, bool &can_target_ios, bool &can_target_osx, bool &useDataProtectionKeychainFlag) { // By default, target both keychain. can_target_osx = can_target_ios = true; + useDataProtectionKeychainFlag = false; // Check no-legacy flag. // it's iOS or bust if we're on MZ! - CFTypeRef noLegacy = NULL; + CFTypeRef useDataProtection = NULL; if (_CFMZEnabled()) { - noLegacy = kCFBooleanTrue; + useDataProtection = kCFBooleanTrue; } else { - noLegacy = CFDictionaryGetValue(query, kSecAttrNoLegacy); + // In case your CFDict is dumb and compares by pointer equality we check both versions of the symbol + if (!CFDictionaryGetValueIfPresent(query, kSecUseDataProtectionKeychain, &useDataProtection)) { + // Ah the irony of ignoring deprecation while checking for a legacy-avoiding attribute +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + useDataProtection = CFDictionaryGetValue(query, kSecAttrNoLegacy); +#pragma clang diagnostic pop + } } - if (noLegacy != NULL) { - can_target_ios = readNumber(noLegacy) != 0; + if (useDataProtection != NULL) { + useDataProtectionKeychainFlag = readNumber(useDataProtection); + can_target_ios = useDataProtectionKeychainFlag; can_target_osx = !can_target_ios; return errSecSuccess; } @@ -4399,7 +4435,7 @@ SecItemCopyParentCertificates_osx(SecCertificateRef certificate, void *context) } /* Cache miss. Query for parents. */ -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX CFDataRef normalizedIssuer = SecCertificateCopyNormalizedIssuerContent(certificate, NULL); #else CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate); @@ -4490,7 +4526,7 @@ SecCertificateRef SecItemCopyStoredCertificate(SecCertificateRef certificate, vo /* Certificates are unique by issuer and serial number. */ CFDataRef serialNumber = SecCertificateCopySerialNumberData(certificate, NULL); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX CFDataRef normalizedIssuer = SecCertificateCopyNormalizedIssuerContent(certificate, NULL); #else CFDataRef normalizedIssuer = SecCertificateGetNormalizedIssuerContent(certificate); @@ -4691,7 +4727,12 @@ SecItemCopyTranslatedAttributes(CFDictionaryRef inOSXDict, CFTypeRef itemClass, } /* This attribute is consumed by the bridge itself. */ + CFDictionaryRemoveValue(result, kSecUseDataProtectionKeychain); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // Also remove deprecated symbol in case your CFDict is derpy CFDictionaryRemoveValue(result, kSecAttrNoLegacy); +#pragma clang diagnostic pop return result; } @@ -4820,8 +4861,8 @@ SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result) OSStatus status_osx = errSecItemNotFound, status_ios = errSecItemNotFound; CFTypeRef result_osx = NULL, result_ios = NULL; - bool can_target_ios, can_target_osx; - OSStatus status = SecItemCategorizeQuery(query, can_target_ios, can_target_osx); + bool can_target_ios, can_target_osx, useDataProtectionKeychainFlag; + OSStatus status = SecItemCategorizeQuery(query, can_target_ios, can_target_osx, useDataProtectionKeychainFlag); if (status != errSecSuccess) { return status; } @@ -4874,8 +4915,8 @@ SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result) secitemshow(attributes, "SecItemAdd attrs:"); CFTypeRef result_osx = NULL, result_ios = NULL; - bool can_target_ios, can_target_osx; - OSStatus status = SecItemCategorizeQuery(attributes, can_target_ios, can_target_osx); + bool can_target_ios, can_target_osx, useDataProtectionKeychainFlag; + OSStatus status = SecItemCategorizeQuery(attributes, can_target_ios, can_target_osx, useDataProtectionKeychainFlag); if (status != errSecSuccess) { return status; } @@ -4924,12 +4965,29 @@ SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate) secitemshow(attributesToUpdate, "SecItemUpdate attrs:"); OSStatus status_osx = errSecItemNotFound, status_ios = errSecItemNotFound; - bool can_target_ios, can_target_osx; - OSStatus status = SecItemCategorizeQuery(query, can_target_ios, can_target_osx); + bool can_target_ios, can_target_osx, useDataProtectionKeychainFlag; + OSStatus status = SecItemCategorizeQuery(query, can_target_ios, can_target_osx, useDataProtectionKeychainFlag); if (status != errSecSuccess) { return status; } + /* + * If the user have explicity opted in to UseDataProtectionKeychain, then don't touch the legacy keychain at all + * ie don't move the item back to legacy keychain if you remove sync=1 or the inverse. + */ + if (useDataProtectionKeychainFlag) { + CFDictionaryRef attrs_ios = SecItemCopyTranslatedAttributes(query, + CFDictionaryGetValue(query, kSecClass), true, true, false, true, true, true); + if (!attrs_ios) { + status_ios = errSecParam; + } else { + status_ios = SecItemUpdate_ios(attrs_ios, attributesToUpdate); + CFRelease(attrs_ios); + } + secitemlog(LOG_NOTICE, "SecItemUpdate(ios only) result: %d", status_ios); + return status_ios; + } + if (can_target_ios) { CFDictionaryRef attrs_ios = SecItemCopyTranslatedAttributes(query, CFDictionaryGetValue(query, kSecClass), true, true, false, true, true, true); @@ -4983,8 +5041,8 @@ SecItemDelete(CFDictionaryRef query) secitemshow(query, "SecItemDelete query:"); OSStatus status_osx = errSecItemNotFound, status_ios = errSecItemNotFound; - bool can_target_ios, can_target_osx; - OSStatus status = SecItemCategorizeQuery(query, can_target_ios, can_target_osx); + bool can_target_ios, can_target_osx, useDataProtectionKeychainFlag; + OSStatus status = SecItemCategorizeQuery(query, can_target_ios, can_target_osx, useDataProtectionKeychainFlag); if (status != errSecSuccess) { return status; } diff --git a/OSX/libsecurity_keychain/lib/SecKey.cpp b/OSX/libsecurity_keychain/lib/SecKey.cpp index 6fb96593..1495ca1d 100644 --- a/OSX/libsecurity_keychain/lib/SecKey.cpp +++ b/OSX/libsecurity_keychain/lib/SecKey.cpp @@ -21,10 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include "SecKey.h" -#include "SecKeyPriv.h" -#include "SecItem.h" -#include "SecItemPriv.h" +#include +#include +#include +#include +#include #include #include #include @@ -57,10 +58,11 @@ static OSStatus SecCDSAKeyInit(SecKeyRef key, const uint8_t *keyData, CFIndex keyDataLength, SecKeyEncoding encoding) { - key->key = const_cast(reinterpret_cast(keyData)); - key->key->initializeWithSecKeyRef(key); - key->credentialType = kSecCredentialTypeDefault; - key->cdsaKeyMutex = new Mutex(); + CDSASecKey *cdsaKey = (CDSASecKey *)key; + cdsaKey->key = const_cast(reinterpret_cast(keyData)); + CDSASecKey::keyItem(key)->initializeWithSecKeyRef(key); + cdsaKey->credentialType = kSecCredentialTypeDefault; + cdsaKey->cdsaKeyMutex = new Mutex(); return errSecSuccess; } @@ -70,14 +72,15 @@ 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); + CDSASecKey *cdsaKey = static_cast(keyRef); + StMaybeLock cdsaMutex(cdsaKey->cdsaKeyMutex); - KeyItem *keyItem = keyRef->key; + KeyItem *keyItem = static_cast(keyRef->key); if (keyItem == NULL) { // KeyImpl::attachSecKeyRef disconnected us from KeyItem instance, there is nothing to do for us. cdsaMutex.unlock(); - delete keyRef->cdsaKeyMutex; + delete cdsaKey->cdsaKeyMutex; return; } @@ -88,7 +91,7 @@ SecCDSAKeyDestroy(SecKeyRef keyRef) { { StMaybeLock _(keyItem->getMutexForObject()); - keyItem = keyRef->key; + keyItem = static_cast(keyRef->key); if (keyItem == NULL) { // Second version of the check above, the definitive one because this one is performed with locked object's mutex, therefore we can be sure that KeyImpl is still connected to this keyRef instance. return; @@ -98,7 +101,7 @@ SecCDSAKeyDestroy(SecKeyRef keyRef) { delete keyItem; } - delete keyRef->cdsaKeyMutex; + delete cdsaKey->cdsaKeyMutex; (void) kc; // Tell the compiler we're actually using this variable. At destruction time, it'll release the keychain. } @@ -109,7 +112,7 @@ SecCDSAKeyGetBlockSize(SecKeyRef key) { CFErrorRef *error = NULL; BEGIN_SECKEYAPI(size_t,0) - const CssmKey::Header keyHeader = key->key->unverifiedKeyHeader(); + const CssmKey::Header keyHeader = CDSASecKey::keyItem(key)->unverifiedKeyHeader(); switch(keyHeader.algorithm()) { case CSSM_ALGID_RSA: @@ -158,7 +161,7 @@ SecCDSAKeyGetAlgorithmId(SecKeyRef key) { BEGIN_SECKEYAPI(CFIndex, 0) result = kSecNullAlgorithmID; - switch (key->key->unverifiedKeyHeader().AlgorithmId) { + switch (CDSASecKey::keyItem(key)->unverifiedKeyHeader().AlgorithmId) { case CSSM_ALGID_RSA: result = kSecRSAAlgorithmID; break; @@ -257,7 +260,7 @@ static OSStatus SecCDSAKeyCopyPublicBytes(SecKeyRef key, CFDataRef *serializatio CFErrorRef *error = NULL; BEGIN_SECKEYAPI(OSStatus, errSecSuccess) - const CssmKey::Header &header = key->key->key().header(); + const CssmKey::Header &header = CDSASecKey::keyItem(key)->key().header(); switch (header.algorithm()) { case CSSM_ALGID_RSA: { switch (header.keyClass()) { @@ -353,7 +356,7 @@ SecCDSAKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) { BEGIN_SECKEYAPI(CFDataRef, NULL) result = NULL; - const CssmKey::Header header = key->key->unverifiedKeyHeader(); + const CssmKey::Header header = CDSASecKey::keyItem(key)->unverifiedKeyHeader(); CFRef keyData; switch (header.algorithm()) { case CSSM_ALGID_RSA: @@ -400,16 +403,16 @@ SecCDSAKeyCopyExternalRepresentation(SecKeyRef key, CFErrorRef *error) { static CFDataRef SecCDSAKeyCopyLabel(SecKeyRef key) { CFDataRef label = NULL; - if (key->key->isPersistent()) { + if (CDSASecKey::keyItem(key)->isPersistent()) { UInt32 tags[] = { kSecKeyLabel }, formats[] = { CSSM_DB_ATTRIBUTE_FORMAT_BLOB }; SecKeychainAttributeInfo info = { 1, tags, formats }; SecKeychainAttributeList *list = NULL; - key->key->getAttributesAndData(&info, NULL, &list, NULL, NULL); + CDSASecKey::keyItem(key)->getAttributesAndData(&info, NULL, &list, NULL, NULL); if (list->count == 1) { SecKeychainAttribute *attr = list->attr; label = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)attr->data, (CFIndex)attr->length); } - key->key->freeAttributesAndData(list, NULL); + CDSASecKey::keyItem(key)->freeAttributesAndData(list, NULL); } return label; } @@ -425,7 +428,7 @@ SecCDSAKeyCopyAttributeDictionary(SecKeyRef key) { CFDictionarySetValue(dict, kSecClass, kSecClassKey); - const CssmKey::Header header = key->key->unverifiedKeyHeader(); + const CssmKey::Header header = CDSASecKey::keyItem(key)->unverifiedKeyHeader(); CFIndex sizeValue = header.LogicalKeySizeInBits; CFRef sizeInBits = CFNumberCreate(NULL, kCFNumberCFIndexType, &sizeValue); CFDictionarySetValue(dict, kSecAttrKeySizeInBits, sizeInBits); @@ -490,7 +493,7 @@ SecCDSAKeyCopyAttributeDictionary(SecKeyRef key) { if (header.algorithm() == CSSM_ALGID_RSA && header.keyClass() == CSSM_KEYCLASS_PUBLIC_KEY && header.blobType() == CSSM_KEYBLOB_RAW) { - const CssmData &keyData = key->key->key()->keyData(); + const CssmData &keyData = CDSASecKey::keyItem(key)->key()->keyData(); DERItem keyItem = { static_cast(keyData.data()), keyData.length() }; DERRSAPubKeyPKCS1 decodedKey; if (DERParseSequence(&keyItem, DERNumRSAPubKeyPKCS1ItemSpecs, @@ -520,7 +523,7 @@ static SecKeyRef SecCDSAKeyCopyPublicKey(SecKeyRef privateKey) { BEGIN_SECKEYAPI(SecKeyRef, NULL) result = NULL; - KeyItem *key = privateKey->key; + KeyItem *key = CDSASecKey::keyItem(privateKey); CFRef label = SecCDSAKeyCopyLabel(privateKey); if (label) { // Lookup public key in the database. @@ -546,7 +549,7 @@ static SecKeyRef SecCDSAKeyCopyPublicKey(SecKeyRef privateKey) { static KeyItem *SecCDSAKeyPrepareParameters(SecKeyRef key, SecKeyOperationType &operation, SecKeyAlgorithm algorithm, CSSM_ALGORITHMS &baseAlgorithm, CSSM_ALGORITHMS &secondaryAlgorithm, CSSM_ALGORITHMS &paddingAlgorithm, CFIndex &inputSizeLimit) { - KeyItem *keyItem = key->key; + KeyItem *keyItem = CDSASecKey::keyItem(key); CSSM_KEYCLASS keyClass = keyItem->key()->header().keyClass(); baseAlgorithm = keyItem->key()->header().algorithm(); switch (baseAlgorithm) { @@ -647,7 +650,7 @@ static KeyItem *SecCDSAKeyPrepareParameters(SecKeyRef key, SecKeyOperationType & static CFDataRef SecCDSAKeyCopyPaddedPlaintext(SecKeyRef key, CFDataRef plaintext, SecKeyAlgorithm algorithm) { - CFIndex blockSize = key->key->key().header().LogicalKeySizeInBits / 8; + CFIndex blockSize = CDSASecKey::keyItem(key)->key().header().LogicalKeySizeInBits / 8; CFIndex plaintextLength = CFDataGetLength(plaintext); if ((algorithm == kSecKeyAlgorithmRSAEncryptionRaw || algorithm == kSecKeyAlgorithmRSASignatureRaw) && plaintextLength < blockSize) { @@ -684,11 +687,12 @@ static CFTypeRef SecCDSAKeyCopyOperationResult(SecKeyRef key, SecKeyOperationTyp } } + CDSASecKey *cdsaKey = static_cast(key); switch (operation) { case kSecKeyOperationTypeSign: { CssmClient::Sign signContext(keyItem->csp(), baseAlgorithm, secondaryAlgorithm); signContext.key(keyItem->key()); - signContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_SIGN, key->credentialType)); + signContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_SIGN, cdsaKey->credentialType)); signContext.add(CSSM_ATTRIBUTE_PADDING, paddingAlgorithm); CFRef input = SecCDSAKeyCopyPaddedPlaintext(key, CFRef::check(in1, errSecParam), algorithm); CssmAutoData signature(signContext.allocator()); @@ -699,7 +703,7 @@ static CFTypeRef SecCDSAKeyCopyOperationResult(SecKeyRef key, SecKeyOperationTyp case kSecKeyOperationTypeVerify: { CssmClient::Verify verifyContext(keyItem->csp(), baseAlgorithm, secondaryAlgorithm); verifyContext.key(keyItem->key()); - verifyContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ANY, key->credentialType)); + verifyContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ANY, cdsaKey->credentialType)); verifyContext.add(CSSM_ATTRIBUTE_PADDING, paddingAlgorithm); CFRef input = SecCDSAKeyCopyPaddedPlaintext(key, CFRef::check(in1, errSecParam), algorithm); verifyContext.verify(CssmData(CFDataRef(input)), CssmData(CFRef::check(in2, errSecParam))); @@ -710,7 +714,7 @@ static CFTypeRef SecCDSAKeyCopyOperationResult(SecKeyRef key, SecKeyOperationTyp CssmClient::Encrypt encryptContext(keyItem->csp(), baseAlgorithm); encryptContext.key(keyItem->key()); encryptContext.padding(paddingAlgorithm); - encryptContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ENCRYPT, key->credentialType)); + encryptContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_ENCRYPT, cdsaKey->credentialType)); CFRef input = SecCDSAKeyCopyPaddedPlaintext(key, CFRef::check(in1, errSecParam), algorithm); CssmAutoData output(encryptContext.allocator()), remainingData(encryptContext.allocator()); size_t length = encryptContext.encrypt(CssmData(CFDataRef(input)), output.get(), remainingData.get()); @@ -724,7 +728,7 @@ static CFTypeRef SecCDSAKeyCopyOperationResult(SecKeyRef key, SecKeyOperationTyp CssmClient::Decrypt decryptContext(keyItem->csp(), baseAlgorithm); decryptContext.key(keyItem->key()); decryptContext.padding(paddingAlgorithm); - decryptContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_DECRYPT, key->credentialType)); + decryptContext.cred(keyItem->getCredentials(CSSM_ACL_AUTHORIZATION_DECRYPT, cdsaKey->credentialType)); CssmAutoData output(decryptContext.allocator()), remainingData(decryptContext.allocator()); size_t length = decryptContext.decrypt(CssmData(CFRef::check(in1, errSecParam)), output.get(), remainingData.get()); @@ -779,7 +783,7 @@ static Boolean SecCDSAKeyIsEqual(SecKeyRef key1, SecKeyRef key2) { CFErrorRef *error = NULL; BEGIN_SECKEYAPI(Boolean, false) - result = key1->key->equal(*key2->key); + result = CDSASecKey::keyItem(key1)->equal(*CDSASecKey::keyItem(key2)); END_SECKEYAPI } @@ -788,7 +792,7 @@ static Boolean SecCDSAKeySetParameter(SecKeyRef key, CFStringRef name, CFPropert BEGIN_SECKEYAPI(Boolean, false) if (CFEqual(name, kSecUseAuthenticationUI)) { - key->credentialType = CFEqual(value, kSecUseAuthenticationUIAllow) ? kSecCredentialTypeDefault : kSecCredentialTypeNoUI; + static_cast(key)->credentialType = CFEqual(value, kSecUseAuthenticationUIAllow) ? kSecCredentialTypeDefault : kSecCredentialTypeNoUI; result = true; } else { result = SecError(errSecUnimplemented, error, CFSTR("Unsupported parameter '%@' for SecKeyCDSASetParameter"), name); @@ -813,7 +817,7 @@ const SecKeyDescriptor kSecCDSAKeyDescriptor = { .isEqual = SecCDSAKeyIsEqual, .setParameter = SecCDSAKeySetParameter, - .extraBytes = (sizeof(struct OpaqueSecKeyRef) > sizeof(struct __SecKey) ? (sizeof(struct OpaqueSecKeyRef) - sizeof(struct __SecKey)) : 0), + .extraBytes = (sizeof(class CDSASecKey) > sizeof(struct __SecKey) ? (sizeof(class CDSASecKey) - sizeof(struct __SecKey)) : 0), }; namespace Security { @@ -828,14 +832,15 @@ namespace Security { return static_cast(key->key); } - if (key->cdsaKey == NULL) { + CFRef cdsaKey = SecKeyCopyAuxilliaryCDSAKeyForKey(key); + if (!cdsaKey) { // Create CDSA key from exported data of existing key. CFRef keyAttributes = SecKeyCopyAttributes(key); if (keyAttributes) { CFRef keyData = SecKeyCopyExternalRepresentation(key, NULL); if (!keyData) { CFTypeRef pubKeyHash = CFDictionaryGetValue(keyAttributes, kSecAttrApplicationLabel); - const void *keys[] = { kSecClass, kSecAttrNoLegacy, kSecReturnRef, kSecMatchLimit }; + const void *keys[] = { kSecClass, kSecUseDataProtectionKeychain, kSecReturnRef, kSecMatchLimit }; const void *values[] = { kSecClassIdentity, kCFBooleanFalse, kCFBooleanTrue, kSecMatchLimitAll }; CFRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), @@ -851,24 +856,28 @@ namespace Security { } CFRef attrs = SecKeyCopyAttributes(privateKey); if (CFEqual(CFDictionaryGetValue(attrs, kSecAttrApplicationLabel), pubKeyHash)) { - key->cdsaKey = privateKey.retain(); + cdsaKey = privateKey; + SecKeySetAuxilliaryCDSAKeyForKey(key, cdsaKey.get()); break; } } } } else { - key->cdsaKey = SecKeyCreateFromData(keyAttributes, keyData, NULL); + cdsaKey = SecKeyCreateFromData(keyAttributes, keyData, NULL); + if (cdsaKey) { + SecKeySetAuxilliaryCDSAKeyForKey(key, cdsaKey.retain()); + } } } } - return (key->cdsaKey != NULL) ? key->cdsaKey->key : NULL; + return cdsaKey ? CDSASecKey::keyItem(cdsaKey.get()) : NULL; } // You need to hold this key's MutexForObject when you run this void KeyItem::attachSecKeyRef() const { SecKeyRef key = SecKeyCreate(NULL, &kSecCDSAKeyDescriptor, reinterpret_cast(this), 0, 0); - key->key->mWeakSecKeyRef = key; + CDSASecKey::keyItem(key)->mWeakSecKeyRef = key; } } @@ -1592,7 +1601,13 @@ SecKeyGeneratePairInternal( forceIOSKey = true; } else { CFTypeRef tokenID = GetAttributeFromParams(parameters, kSecAttrTokenID, NULL); - CFTypeRef noLegacy = GetAttributeFromParams(parameters, kSecAttrNoLegacy, NULL); + CFTypeRef noLegacy = GetAttributeFromParams(parameters, kSecUseDataProtectionKeychain, NULL); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + if (!noLegacy) { // Also lookup via deprecated symbol because we do CFDictionaryGetValue and your CFDict might be an idiot + noLegacy = GetAttributeFromParams(parameters, kSecAttrNoLegacy, NULL); + } +#pragma clang diagnostic pop CFTypeRef sync = GetAttributeFromParams(parameters, kSecAttrSynchronizable, kSecPrivateKeyAttrs); CFTypeRef accessControl = GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPrivateKeyAttrs) ?: GetAttributeFromParams(parameters, kSecAttrAccessControl, kSecPublicKeyAttrs); diff --git a/OSX/libsecurity_keychain/lib/SecKeychain.cpp b/OSX/libsecurity_keychain/lib/SecKeychain.cpp index b13c0357..53265b95 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychain.cpp +++ b/OSX/libsecurity_keychain/lib/SecKeychain.cpp @@ -1595,7 +1595,6 @@ OSStatus SecKeychainStoreUnlockKeyWithPubKeyHash(CFDataRef pubKeyHash, CFStringR AuthorizationItem myItems = {"com.apple.ctk.pair", 0, NULL, 0}; AuthorizationRights myRights = {1, &myItems}; - AuthorizationRights *authorizedRights = NULL; char pathName[PATH_MAX]; UInt32 pathLength = PATH_MAX; @@ -1615,16 +1614,20 @@ OSStatus SecKeychainStoreUnlockKeyWithPubKeyHash(CFDataRef pubKeyHash, CFStringR AuthorizationEnvironment environment = {3, envItems}; AuthorizationFlags flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights; - result = AuthorizationCopyRights(authorizationRef, &myRights, &environment, flags, &authorizedRights); - if (authorizedRights) - AuthorizationFreeItemSet(authorizedRights); + result = AuthorizationCopyRights(authorizationRef, &myRights, &environment, flags, NULL); + secnotice("SecKeychain", "Authorization result: %d", (int)result); if (result == errAuthorizationSuccess) { AuthorizationItemSet *items; result = AuthorizationCopyInfo(authorizationRef, kAuthorizationEnvironmentPassword, &items); + secnotice("SecKeychain", "Items copy result: %d", (int)result); if (result == errAuthorizationSuccess) { + secnotice("SecKeychain", "Items count: %d", items->count); if (items->count > 0) { pwd = CFStringCreateWithCString(kCFAllocatorDefault, (const char *)items->items[0].value, kCFStringEncodingUTF8); + if (pwd) { + secnotice("SecKeychain", "Got kcpass"); + } } AuthorizationFreeItemSet(items); } diff --git a/OSX/libsecurity_keychain/lib/SecKeychain.h b/OSX/libsecurity_keychain/lib/SecKeychain.h index 7aa9b801..b8329154 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychain.h +++ b/OSX/libsecurity_keychain/lib/SecKeychain.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2000-2004,2011,2013-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, @@ -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@ */ @@ -33,6 +33,7 @@ #include #include #include +#include #if defined(__cplusplus) extern "C" { @@ -66,8 +67,8 @@ CF_ENUM(UInt32) @field lockInterval An unsigned 32-bit integer representing the number of seconds before the keychain locks. */ struct SecKeychainSettings -{ - UInt32 version; +{ + UInt32 version; Boolean lockOnSleep; Boolean useLockInterval; UInt32 lockInterval; @@ -80,7 +81,7 @@ typedef struct SecKeychainSettings SecKeychainSettings; @constant kSecAuthenticationTypeNTLM Specifies Windows NT LAN Manager authentication. @constant kSecAuthenticationTypeMSN Specifies Microsoft Network default authentication. @constant kSecAuthenticationTypeDPA Specifies Distributed Password authentication. - @constant kSecAuthenticationTypeRPA Specifies Remote Password authentication. + @constant kSecAuthenticationTypeRPA Specifies Remote Password authentication. @constant kSecAuthenticationTypeHTTPBasic Specifies HTTP Basic authentication. @constant kSecAuthenticationTypeHTTPDigest Specifies HTTP Digest Access authentication. @constant kSecAuthenticationTypeHTMLForm Specifies HTML form based authentication. @@ -111,7 +112,7 @@ typedef CF_ENUM(FourCharCode, SecAuthenticationType) @abstract Defines the protocol type associated with an AppleShare or Internet password. @constant kSecProtocolTypeFTP Indicates FTP. @constant kSecProtocolTypeFTPAccount Indicates FTP Account (client side), usage deprecated. - @constant kSecProtocolTypeHTTP Indicates HTTP. + @constant kSecProtocolTypeHTTP Indicates HTTP. @constant kSecProtocolTypeIRC Indicates IRC. @constant kSecProtocolTypeNNTP Indicates NNTP. @constant kSecProtocolTypePOP3 Indicates POP3. @@ -206,7 +207,7 @@ typedef CF_ENUM(UInt32, SecKeychainEvent) kSecUpdateEvent = 5, kSecPasswordChangedEvent = 6, kSecDefaultChangedEvent = 9, - kSecDataAccessEvent = 10, + kSecDataAccessEvent __API_DEPRECATED("Read events are no longer posted", macos(10.10, 10.15)) = 10, kSecKeychainListChangedEvent = 11, kSecTrustSettingsChangedEvent = 12 }; @@ -222,7 +223,7 @@ typedef CF_ENUM(UInt32, SecKeychainEvent) @constant kSecPasswordChangedEventMask If the bit specified by this mask is set, your callback function will be invoked when the keychain password is changed. @constant kSecDefaultChangedEventMask If the bit specified by this mask is set, your callback function will be invoked when a different keychain is specified as the default. @constant kSecDataAccessEventMask If the bit specified by this mask is set, your callback function will be invoked when a process accesses a keychain item's data. - @constant kSecTrustSettingsChangedEvent If the bit specified by this mask is set, your callback function will be invoked when there is a change in certificate Trust Settings. + @constant kSecTrustSettingsChangedEvent If the bit specified by this mask is set, your callback function will be invoked when there is a change in certificate Trust Settings. @constant kSecEveryEventMask If all the bits are set, your callback function will be invoked whenever any event occurs. */ typedef CF_OPTIONS(UInt32, SecKeychainEventMask) @@ -234,7 +235,7 @@ typedef CF_OPTIONS(UInt32, SecKeychainEventMask) kSecUpdateEventMask = 1 << kSecUpdateEvent, kSecPasswordChangedEventMask = 1 << kSecPasswordChangedEvent, kSecDefaultChangedEventMask = 1 << kSecDefaultChangedEvent, - kSecDataAccessEventMask = 1 << kSecDataAccessEvent, + kSecDataAccessEventMask __API_DEPRECATED("Read events are no longer posted", macos(10.10, 10.15)) = 1 << kSecDataAccessEvent, kSecKeychainListChangedMask = 1 << kSecKeychainListChangedEvent, kSecTrustSettingsChangedEventMask = 1 << kSecTrustSettingsChangedEvent, kSecEveryEventMask = 0xffffffff @@ -242,22 +243,22 @@ typedef CF_OPTIONS(UInt32, SecKeychainEventMask) /*! @typedef SecKeychainCallbackInfo - @abstract Contains information about a keychain event. + @abstract Contains information about a keychain event. @field version The version of this structure. @field item A reference to the keychain item associated with this event, if any. Note that some events do not involve a particular keychain item. @field keychain A reference to the keychain in which the event occurred. @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. + @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 API_UNAVAILABLE(ios) SecKeychainCallbackInfo +struct API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) SecKeychainCallbackInfo { UInt32 version; SecKeychainItemRef __nonnull item; SecKeychainRef __nonnull keychain; pid_t pid; }; -typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo API_UNAVAILABLE(ios); - +typedef struct SecKeychainCallbackInfo SecKeychainCallbackInfo API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + /*! @function SecKeychainGetTypeID @abstract Returns the type identifier of SecKeychain instances. @@ -296,7 +297,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) API_UNAVAILABLE(ios); +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, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainDelete @@ -304,7 +305,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) API_UNAVAILABLE(ios); +OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainSetSettings @@ -313,7 +314,7 @@ OSStatus SecKeychainDelete(SecKeychainRef __nullable keychainOrArray) API_UNAVAI @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainSetSettings(SecKeychainRef __nullable keychain, const SecKeychainSettings *newSettings) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainCopySettings @@ -322,34 +323,34 @@ 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) API_UNAVAILABLE(ios); +OSStatus SecKeychainCopySettings(SecKeychainRef __nullable keychain, SecKeychainSettings *outSettings) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainUnlock @abstract Unlocks the specified keychain. - @param keychain A reference to the keychain to unlock. Pass NULL to specify the default keychain. If you pass NULL and the default keychain is currently locked, the keychain will appear as the default choice. If you pass a locked keychain, SecKeychainUnlock will use the password provided to unlock it. If the default keychain is currently unlocked, SecKeychainUnlock returns errSecSuccess. + @param keychain A reference to the keychain to unlock. Pass NULL to specify the default keychain. If you pass NULL and the default keychain is currently locked, the keychain will appear as the default choice. If you pass a locked keychain, SecKeychainUnlock will use the password provided to unlock it. If the default keychain is currently unlocked, SecKeychainUnlock returns errSecSuccess. @param passwordLength An unsigned 32-bit integer representing the length of the password buffer. @param password A buffer containing the password for the keychain. Pass NULL if the user password is unknown. In this case, SecKeychainUnlock displays the Unlock Keychain dialog box, and the authentication user interface associated with the keychain about to be unlocked. @param usePassword A boolean indicating whether the password parameter is used. You should pass TRUE if it is used or FALSE if it is ignored. @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. + @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainUnlock(SecKeychainRef __nullable keychain, UInt32 passwordLength, const void * __nullable password, Boolean usePassword) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainLock - @abstract Locks the specified keychain. + @abstract Locks the specified keychain. @param keychain A reference to the keychain to lock. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainLock(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios); +OSStatus SecKeychainLock(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainLockAll @abstract Locks all keychains belonging to the current user. @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainLockAll(void) API_UNAVAILABLE(ios); +OSStatus SecKeychainLockAll(void) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainCopyDefault @@ -357,15 +358,15 @@ OSStatus SecKeychainLockAll(void) API_UNAVAILABLE(ios); @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainCopyDefault(SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychain) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainSetDefault - @abstract Sets the default keychain. + @abstract Sets the default keychain. @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainCopySearchList @@ -373,7 +374,7 @@ OSStatus SecKeychainSetDefault(SecKeychainRef __nullable keychain) API_UNAVAILAB @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainCopySearchList(CFArrayRef * __nonnull CF_RETURNS_RETAINED searchList) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainSetSearchList @@ -381,7 +382,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) API_UNAVAILABLE(ios); +OSStatus SecKeychainSetSearchList(CFArrayRef searchList) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* @@ -410,7 +411,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) API_UNAVAILABLE(ios); +OSStatus SecKeychainGetStatus(SecKeychainRef __nullable keychain, SecKeychainStatus *keychainStatus) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainGetPath @@ -420,7 +421,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) API_UNAVAILABLE(ios); +OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLength, char *pathName) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #pragma mark ---- Keychain Item Attribute Information ---- /*! @@ -428,11 +429,11 @@ OSStatus SecKeychainGetPath(SecKeychainRef __nullable keychain, UInt32 *ioPathLe @abstract Obtains tags for all possible attributes for a given item class. @param keychain A keychain reference. @param itemID The relation identifier of the item tags (an itemID is a CSSM_DB_RECORDTYPE defined in cssmapple.h). - @param info On return, a pointer to the keychain attribute information. User should call the SecKeychainFreeAttributeInfo function to release the structure when done with it. + @param info On return, a pointer to the keychain attribute information. User should call the SecKeychainFreeAttributeInfo function to release the structure when done with it. @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainAttributeInfoForItemID(SecKeychainRef __nullable keychain, UInt32 itemID, SecKeychainAttributeInfo * __nullable * __nonnull info) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainFreeAttributeInfo @@ -440,26 +441,26 @@ 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) API_UNAVAILABLE(ios); +OSStatus SecKeychainFreeAttributeInfo(SecKeychainAttributeInfo *info) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #pragma mark ---- Keychain Manager Callbacks ---- - + /*! @typedef SecKeychainCallback @abstract Defines a pointer to a customized callback function. You supply the customized callback function to do a callback tailored to your application's needs. - @param keychainEvent The keychain event that your application wishes to be notified of. See SecKeychainEvent for a description of possible values. The type of event that can trigger your callback depends on the bit mask you passed in the eventMask parameter of the function SecKeychainAddCallback. For more information, see the discussion. - @param info A pointer to a structure of type SecKeychainCallbackInfo. On return, the structure contains information about the keychain event that occurred. The Keychain Manager passes this information to your callback function via the info parameter. + @param keychainEvent The keychain event that your application wishes to be notified of. See SecKeychainEvent for a description of possible values. The type of event that can trigger your callback depends on the bit mask you passed in the eventMask parameter of the function SecKeychainAddCallback. For more information, see the discussion. + @param info A pointer to a structure of type SecKeychainCallbackInfo. On return, the structure contains information about the keychain event that occurred. The Keychain Manager passes this information to your callback function via the info parameter. @param context A pointer to application-defined storage that your application previously passed to the function SecKeychainAddCallback. You can use this value to perform operations like track which instance of a function is operating. @result A result code. See "Security Error Codes" (SecBase.h). @discussion If you name your function MyKeychainEventCallback, you would declare it like this: OSStatus MyKeychainEventCallback ( - SecKeychainEvent keychainEvent, - SecKeychainCallbackInfo *info, + SecKeychainEvent keychainEvent, + SecKeychainCallbackInfo *info, void *context); 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) API_UNAVAILABLE(ios); +typedef OSStatus (*SecKeychainCallback)(SecKeychainEvent keychainEvent, SecKeychainCallbackInfo *info, void * __nullable context) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainAddCallback @@ -469,15 +470,15 @@ 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) API_UNAVAILABLE(ios); +OSStatus SecKeychainAddCallback(SecKeychainCallback callbackFunction, SecKeychainEventMask eventMask, void * __nullable userContext) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainRemoveCallback @abstract Unregisters your keychain event callback function. Once removed, keychain events won't be sent to the owner of the callback. - @param callbackFunction The callback function pointer to remove + @param callbackFunction The callback function pointer to remove @result A result code. See "Security Error Codes" (SecBase.h). */ -OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction) API_UNAVAILABLE(ios); +OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #pragma mark ---- High Level Keychain Manager Calls ---- /*! @@ -494,14 +495,14 @@ OSStatus SecKeychainRemoveCallback(SecKeychainCallback callbackFunction) API_UNA @param path A pointer to a string containing the path associated with this password, or NULL if there is no relevant path string. @param port The TCP/IP port number. If no specific port number is associated with this item, pass 0. @param protocol The protocol associated with this password. See SecProtocolType for a description of possible values. - @param authenticationType The authentication scheme used. See SecAuthenticationType for a description of possible values. Pass the constant kSecAuthenticationTypeDefault to specify the default authentication scheme. + @param authenticationType The authentication scheme used. See SecAuthenticationType for a description of possible values. Pass the constant kSecAuthenticationTypeDefault to specify the default authentication scheme. @param passwordLength The length of the buffer pointed to by passwordData. @param passwordData A pointer to a buffer containing the password data to be stored in the keychain. @param itemRef On return, a reference to the new keychain item. @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. + @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) API_UNAVAILABLE(ios); +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, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainFindInternetPassword @@ -517,14 +518,14 @@ OSStatus SecKeychainAddInternetPassword(SecKeychainRef __nullable keychain, UInt @param path A pointer to a string containing the path. @param port The TCP/IP port number. Pass 0 to ignore the port number. @param protocol The protocol associated with this password. See SecProtocolType for a description of possible values. - @param authenticationType The authentication scheme used. See SecAuthenticationType for a description of possible values. Pass the constant kSecAuthenticationTypeDefault to specify the default authentication scheme. + @param authenticationType The authentication scheme used. See SecAuthenticationType for a description of possible values. Pass the constant kSecAuthenticationTypeDefault to specify the default authentication scheme. @param passwordLength On return, the length of the buffer pointed to by passwordData. @param passwordData On return, a pointer to a data buffer containing the password. Your application must call SecKeychainItemFreeContent(NULL, passwordData) to release this data buffer when it is no longer needed. Pass NULL if you are not interested in retrieving the password data at this time, but simply want to find the item reference. @param itemRef On return, a reference to the keychain item which was found. @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) API_UNAVAILABLE(ios); +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, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainAddGenericPassword @@ -538,9 +539,9 @@ OSStatus SecKeychainFindInternetPassword(CFTypeRef __nullable keychainOrArray, U @param passwordData A pointer to a buffer containing the password data to be stored in the keychain. @param itemRef On return, a reference to the new keychain item. @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. + @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) API_UNAVAILABLE(ios); +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, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainFindGenericPassword @@ -554,9 +555,9 @@ OSStatus SecKeychainAddGenericPassword(SecKeychainRef __nullable keychain, UInt3 @param passwordData On return, a pointer to a data buffer containing the password. Your application must call SecKeychainItemFreeContent(NULL, passwordData) to release this data buffer when it is no longer needed. Pass NULL if you are not interested in retrieving the password data at this time, but simply want to find the item reference. @param itemRef On return, a reference to the keychain item which was found. @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. + @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) API_UNAVAILABLE(ios); +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, watchos, tvos, bridgeos, iosmac); #pragma mark ---- Managing User Interaction ---- /*! @@ -565,7 +566,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) API_UNAVAILABLE(ios); +OSStatus SecKeychainSetUserInteractionAllowed(Boolean state) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainGetUserInteractionAllowed @@ -573,7 +574,7 @@ OSStatus SecKeychainSetUserInteractionAllowed(Boolean state) API_UNAVAILABLE(ios @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainGetUserInteractionAllowed(Boolean *state) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #pragma mark ---- CSSM Bridge Functions ---- /*! @@ -601,7 +602,7 @@ OSStatus SecKeychainGetDLDBHandle(SecKeychainRef __nullable keychain, CSSM_DL_DB #pragma mark ---- Keychain Access Management ---- /*! @function SecKeychainCopyAccess - @abstract Retrieves the access for a keychain. + @abstract Retrieves the access for a keychain. @param keychain A reference to the keychain from which to copy the access. @param access On return, a pointer to the access reference. @result A result code. See "Security Error Codes" (SecBase.h). diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp b/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp index 06261009..6b31ddea 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp +++ b/OSX/libsecurity_keychain/lib/SecKeychainItem.cpp @@ -657,7 +657,7 @@ OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CF } // first, query the iOS keychain { - const void *keys[] = { kSecValueRef, kSecReturnPersistentRef, kSecAttrNoLegacy }; + const void *keys[] = { kSecValueRef, kSecReturnPersistentRef, kSecUseDataProtectionKeychain }; const void *values[] = { itemRef, kCFBooleanTrue, kCFBooleanTrue }; CFRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), @@ -705,7 +705,7 @@ OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, KCThrowParamErrIf_(!persistentItemRef || !itemRef); // first, query the iOS keychain { - const void *keys[] = { kSecValuePersistentRef, kSecReturnRef, kSecAttrNoLegacy}; + const void *keys[] = { kSecValuePersistentRef, kSecReturnRef, kSecUseDataProtectionKeychain}; const void *values[] = { persistentItemRef, kCFBooleanTrue, kCFBooleanTrue }; CFRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys) / sizeof(*keys), diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItem.h b/OSX/libsecurity_keychain/lib/SecKeychainItem.h index cbb51837..764cea36 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItem.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainItem.h @@ -1,14 +1,14 @@ /* * Copyright (c) 2000-2008,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, @@ -16,7 +16,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@ */ @@ -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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemModifyAttributesAndData(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); + SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nullable CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemModifyContent(SecKeychainItemRef itemRef, const SecKeychainAttributeList * __nullable attrList, UInt32 length, const void * __nullable data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCopyContent(SecKeychainItemRef itemRef, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemFreeContent(SecKeychainAttributeList * __nullable attrList, void * __nullable data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCopyAttributesAndData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo * __nullable info, SecItemClass * __nullable itemClass, SecKeychainAttributeList * __nullable * __nullable attrList, UInt32 * __nullable length, void * __nullable * __nullable outData) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemFreeAttributesAndData(SecKeychainAttributeList * __nullable attrList, void * __nullable data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainItemCopyKeychain @@ -247,7 +247,7 @@ OSStatus SecKeychainItemDelete(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCopyKeychain(SecKeychainItemRef itemRef, SecKeychainRef * __nonnull CF_RETURNS_RETAINED keychainRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); + SecAccessRef __nullable initialAccess, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemCopy) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCreatePersistentReference(SecKeychainItemRef itemRef, CFDataRef * __nonnull CF_RETURNS_RETAINED persistentItemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @@ -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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #pragma mark ---- CSSM Bridge Functions ---- @@ -291,7 +291,7 @@ OSStatus SecKeychainItemCopyFromPersistentReference(CFDataRef persistentItemRef, @discussion This API is deprecated for 10.7. It should no longer be needed. */ OSStatus SecKeychainItemGetDLDBHandle(SecKeychainItemRef keyItemRef, CSSM_DL_DB_HANDLE * __nonnull dldbHandle) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecKeychainItemGetUniqueRecordID @@ -302,7 +302,7 @@ OSStatus SecKeychainItemGetDLDBHandle(SecKeychainItemRef keyItemRef, CSSM_DL_DB_ @discussion This API is deprecated for 10.7. It should no longer be needed. */ OSStatus SecKeychainItemGetUniqueRecordID(SecKeychainItemRef itemRef, const CSSM_DB_UNIQUE_RECORD * __nullable * __nonnull uniqueRecordID) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; #pragma mark ---- Keychain Item Access Management ---- /*! @@ -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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCopyAccess(SecKeychainItemRef itemRef, SecAccessRef * __nonnull CF_RETURNS_RETAINED access) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemSetAccess(SecKeychainItemRef itemRef, SecAccessRef access) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h b/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h index 98f8a436..1bd1caea 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2006,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, @@ -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@ */ @@ -25,7 +25,7 @@ * SecKeychainItemExtendedAttributes.h * Created 9/6/06 by dmitch */ - + #ifndef _SEC_KEYCHAIN_ITEM_EXTENDED_ATTRIBUTES_H_ #define _SEC_KEYCHAIN_ITEM_EXTENDED_ATTRIBUTES_H_ @@ -38,50 +38,50 @@ extern "C" { #endif -/* +/* * Extended attributes extend the fixed set of keychain item attribute in a generally * extensible way. A given SecKeychainItemRef can have assigned to it any number * of extended attributes, each consisting of an attribute name (as a CFStringRef) - * and an attribute value (as a CFDataRef). + * and an attribute value (as a CFDataRef). * - * Each extended attribute is a distinct record residing in the same keychain as - * the item to which it refers. In a given keychain, the set of the following properties + * Each extended attribute is a distinct record residing in the same keychain as + * the item to which it refers. In a given keychain, the set of the following properties * of an extended attribute record must be unique: * * -- the type of item to which the extended attribute is bound (kSecPublicKeyItemClass, * kSecPrivateKeyItemClass, etc.) * -- an identifier which uniquely identifies the item to which the extended attribute - * is bound. Currently this is the PrimaryKey blob. + * is bound. Currently this is the PrimaryKey blob. * -- the extended attribute's Attribute Name, specified in this interface as a - * CFString. + * CFString. * - * Thus, e.g., a given item can have at most one extended attribute with + * Thus, e.g., a given item can have at most one extended attribute with * Attribute Name of CFSTR("SomeAttributeName"). */ - -/* + +/* * SecKeychainItemSetExtendedAttribute() - set an extended attribute by name and value. * - * If the extended attribute specified by 'attrName' does not exist, one will be + * If the extended attribute specified by 'attrName' does not exist, one will be * created with the value specified in 'attrValue'. * * If the extended attribute specified by 'attrName already exists, its value will be * replaced by the value specified in 'attrValue'. - * - * If the incoming 'attrValue' is NULL, the extended attribute specified by 'attrName' - * will be deleted if it exists. If the incoming 'attrValue' is NULL and no such - * attribute exists, the function will return errSecNoSuchAttr. + * + * If the incoming 'attrValue' is NULL, the extended attribute specified by 'attrName' + * will be deleted if it exists. If the incoming 'attrValue' is NULL and no such + * attribute exists, the function will return errSecNoSuchAttr. */ OSStatus SecKeychainItemSetExtendedAttribute( SecKeychainItemRef itemRef, - CFStringRef attrName, /* identifies the attribute */ + CFStringRef attrName, /* identifies the attribute */ CFDataRef attrValue) /* value to set; NULL means delete the * attribute */ - API_UNAVAILABLE(ios); - -/* - * SecKeychainItemCopyExtendedAttribute() - Obtain the value of an an extended attribute. - * + API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +/* + * SecKeychainItemCopyExtendedAttribute() - Obtain the value of an an extended attribute. + * * If the extended attribute specified by 'attrName' exists, its value will be returned * via the *attrValue argument. The caller must CFRelease() this returned value. * @@ -91,26 +91,26 @@ OSStatus SecKeychainItemSetExtendedAttribute( OSStatus SecKeychainItemCopyExtendedAttribute( SecKeychainItemRef itemRef, CFStringRef attrName, - CFDataRef *attrValue) API_UNAVAILABLE(ios); /* RETURNED */ - + CFDataRef *attrValue) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* RETURNED */ + /* - * SecKeychainItemCopyAllExtendedAttributes() - obtain all of an item's extended attributes. + * SecKeychainItemCopyAllExtendedAttributes() - obtain all of an item's extended attributes. * * This is used to determine all of the extended attributes associated with a given * SecKeychainItemRef. The Atrribute Names of all of the extended attributes are * returned in the *attrNames argument; on successful return this contains a * CFArray whose elements are CFStringRefs, each of which is an Attribute Name. - * The caller must CFRelease() this array. + * The caller must CFRelease() this array. * - * Optionally, the Attribute Values of all of the extended attributes is returned - * in the *attrValues argument; on successful return this contains a CFArray whose - * elements are CFDataRefs, each of which is an Attribute Value. The positions of - * the elements in this array correspond with the elements in *attrNames; i.e., - * the n'th element in *attrName is the Attribute Name corresponding to the - * Attribute Value found in the n'th element of *attrValues. + * Optionally, the Attribute Values of all of the extended attributes is returned + * in the *attrValues argument; on successful return this contains a CFArray whose + * elements are CFDataRefs, each of which is an Attribute Value. The positions of + * the elements in this array correspond with the elements in *attrNames; i.e., + * the n'th element in *attrName is the Attribute Name corresponding to the + * Attribute Value found in the n'th element of *attrValues. * * Pass in NULL for attrValues if you don't need the Attribute Values. Caller - * must CFRelease the array returned via this argument. + * must CFRelease the array returned via this argument. * * If the item has no extended attributes, this function returns errSecNoSuchAttr. */ @@ -119,7 +119,7 @@ OSStatus SecKeychainItemCopyAllExtendedAttributes( CFArrayRef *attrNames, /* RETURNED, each element is a CFStringRef */ CFArrayRef *attrValues) /* optional, RETURNED, each element is a * CFDataRef */ - API_UNAVAILABLE(ios); + API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #if defined(__cplusplus) } #endif diff --git a/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h b/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h index 4893cff7..96e89d0e 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainItemPriv.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2003-2008,2011,2013 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@ */ @@ -33,19 +33,19 @@ extern "C" { #endif /* Private keychain item attributes */ -enum +enum { kSecClassItemAttr = 'clas', /* Item class (KCItemClass) */ kSecProtectedDataItemAttr = 'prot', /* Item's data is protected (encrypted) (Boolean) */ }; /* Temporary: CRL attributes */ -enum +enum { kSecCrlEncodingItemAttr = 'cren', kSecThisUpdateItemAttr = 'crtu', kSecNextUpdateItemAttr = 'crnu', - kSecUriItemAttr = 'curi', // URI from which it came + kSecUriItemAttr = 'curi', // URI from which it came kSecCrlNumberItemAttr = 'crnm', kSecDeltaCrlNumberItemAttr = 'dlcr' }; @@ -72,23 +72,23 @@ enum { /* also kSecModDateItemAttr from SecKeychainItem.h */ }; -OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCreateNew(SecItemClass itemClass, OSType itemCreator, UInt32 length, const void* data, SecKeychainItemRef* itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemGetData(SecKeychainItemRef itemRef, UInt32 maxLength, void* data, UInt32* actualLength) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemGetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute, UInt32* actualLength) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemSetAttribute(SecKeychainItemRef itemRef, SecKeychainAttribute* attribute) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemAdd(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemAddNoUI(SecKeychainRef keychainRef, SecKeychainItemRef itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemUpdate(SecKeychainItemRef itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemSetData(SecKeychainItemRef itemRef, UInt32 length, const void* data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemFindFirst(SecKeychainRef keychainRef, const SecKeychainAttributeList *attrList, SecKeychainSearchRef *searchRef, SecKeychainItemRef *itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataRef *recordIdentifier) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainItemCopyFromRecordIdentifier @@ -111,7 +111,7 @@ OSStatus SecKeychainItemCopyRecordIdentifier(SecKeychainItemRef itemRef, CFDataR OSStatus SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychain, SecKeychainItemRef *itemRef, - CFDataRef recordIdentifier) API_UNAVAILABLE(ios); + CFDataRef recordIdentifier) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainItemCopyAttributesAndEncryptedData @@ -128,7 +128,7 @@ OSStatus SecKeychainItemCopyFromRecordIdentifier(SecKeychainRef keychain, */ OSStatus SecKeychainItemCopyAttributesAndEncryptedData(SecKeychainItemRef itemRef, SecKeychainAttributeInfo *info, SecItemClass *itemClass, SecKeychainAttributeList **attrList, - UInt32 *length, void **outData) API_UNAVAILABLE(ios); + UInt32 *length, void **outData) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); +OSStatus SecKeychainItemModifyEncryptedData(SecKeychainItemRef itemRef, UInt32 length, const void *data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); + SecKeychainItemRef *itemRef, CFDataRef *itemLocalID) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); + OSStatus SecKeychainItemSetAccessWithPassword(SecKeychainItemRef itemRef, SecAccessRef accessRef, UInt32 passwordLength, const void * password) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #if defined(__cplusplus) } #endif diff --git a/OSX/libsecurity_keychain/lib/SecKeychainPriv.h b/OSX/libsecurity_keychain/lib/SecKeychainPriv.h index 54a6b539..2b035d94 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainPriv.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainPriv.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2003-2004,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, @@ -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@ */ @@ -49,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) - API_DEPRECATED("CSSM_GUID/CSSM_NET_ADDRESS is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); + API_DEPRECATED("CSSM_GUID/CSSM_NET_ADDRESS is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); OSStatus SecKeychainSetBatchMode (SecKeychainRef kcRef, Boolean mode, Boolean rollback) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); @@ -98,11 +98,11 @@ OSStatus SecKeychainCreateWithBlob(const char* fullPathName, CFDataRef dbBlob, S /* Keychain list manipulation */ OSStatus SecKeychainAddDBToKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType) - API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); + API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); OSStatus SecKeychainDBIsInKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType) - API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); + API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); OSStatus SecKeychainRemoveDBFromKeychainList (SecPreferencesDomain domain, const char* dbName, const CSSM_GUID *guid, uint32 subServiceType) - API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios); + API_DEPRECATED("CSSM_GUID is deprecated", macos(10.4,10.14)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* server operation (keychain inhibit) */ void SecKeychainSetServerMode(void) diff --git a/OSX/libsecurity_keychain/lib/SecKeychainSearch.h b/OSX/libsecurity_keychain/lib/SecKeychainSearch.h index f19254ca..fed709fa 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainSearch.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainSearch.h @@ -45,7 +45,7 @@ CF_ASSUME_NONNULL_BEGIN @discussion This API is deprecated in 10.7. The SecKeychainSearchRef type is no longer used. */ CFTypeID SecKeychainSearchGetTypeID(void) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + API_DEPRECATED("SecKeychainSearch is not supported", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainSearchCreateFromAttributes @@ -58,7 +58,7 @@ CFTypeID SecKeychainSearchGetTypeID(void) @discussion This function is deprecated in Mac OS X 10.7 and later; to find keychain items which match specified attributes, please use the SecItemCopyMatching API (see SecItem.h). */ OSStatus SecKeychainSearchCreateFromAttributes(CFTypeRef __nullable keychainOrArray, SecItemClass itemClass, const SecKeychainAttributeList * __nullable attrList, SecKeychainSearchRef * __nonnull CF_RETURNS_RETAINED searchRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + API_DEPRECATED("SecKeychainSearch is not supported", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeychainSearchCopyNext @@ -69,7 +69,7 @@ OSStatus SecKeychainSearchCreateFromAttributes(CFTypeRef __nullable keychainOrAr @discussion This function is deprecated in Mac OS X 10.7 and later; to find keychain items which match specified attributes, please use the SecItemCopyMatching API (see SecItem.h). */ OSStatus SecKeychainSearchCopyNext(SecKeychainSearchRef searchRef, SecKeychainItemRef * __nonnull CF_RETURNS_RETAINED itemRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + API_DEPRECATED("SecKeychainSearch is not supported", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_keychain/lib/SecKeychainSearchPriv.h b/OSX/libsecurity_keychain/lib/SecKeychainSearchPriv.h index 6d907fd9..f64e5c27 100644 --- a/OSX/libsecurity_keychain/lib/SecKeychainSearchPriv.h +++ b/OSX/libsecurity_keychain/lib/SecKeychainSearchPriv.h @@ -48,7 +48,7 @@ extern "C" { to find one or more keychain items which match specified attributes, use the SecItemCopyMatching API (see SecItem.h). */ OSStatus SecKeychainSearchCreateFromAttributesExtended(CFTypeRef keychainOrArray, SecItemClass itemClass, const SecKeychainAttributeList *attrList, CSSM_DB_CONJUNCTIVE dbConjunctive, CSSM_DB_OPERATOR dbOperator, SecKeychainSearchRef *searchRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; #if defined(__cplusplus) } diff --git a/OSX/libsecurity_keychain/lib/SecNetscapeTemplates.h b/OSX/libsecurity_keychain/lib/SecNetscapeTemplates.h index f28f801d..4568df28 100644 --- a/OSX/libsecurity_keychain/lib/SecNetscapeTemplates.h +++ b/OSX/libsecurity_keychain/lib/SecNetscapeTemplates.h @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/OSX/libsecurity_keychain/lib/SecPassword.h b/OSX/libsecurity_keychain/lib/SecPassword.h index 5d9afb93..9be0a79d 100644 --- a/OSX/libsecurity_keychain/lib/SecPassword.h +++ b/OSX/libsecurity_keychain/lib/SecPassword.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2000-2004,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, @@ -17,13 +17,13 @@ * 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 SecPassword - SecPassword implements logic to use the system facilities for acquiring a password, + SecPassword implements logic to use the system facilities for acquiring a password, optionally stored and retrieved from the user's keychain. */ @@ -63,30 +63,30 @@ enum { Use CFRelease on the returned SecPasswordRef when it is no longer needed. @param searchAttrList (in/opt) The list of search attributes for the item. @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. + @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) API_UNAVAILABLE(ios); +OSStatus SecGenericPasswordCreate(SecKeychainAttributeList *searchAttrList, SecKeychainAttributeList *itemAttrList, SecPasswordRef *itemRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecPasswordAction @abstract Get the password for a SecPassword, either from the user or the keychain and return it. Use SecKeychainItemFreeContent to free the data. - + @param itemRef An itemRef previously obtained from SecGenericPasswordCreate. @param message Message to display to the user as a CFString or nil for a default message. (future extension accepts CFDictionary for other hints, icon, secaccess) @param flags (in) The mode of operation. See the flags documentation above. @param length (out) The length of the buffer pointed to by data. @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) API_UNAVAILABLE(ios); +OSStatus SecPasswordAction(SecPasswordRef itemRef, CFTypeRef message, UInt32 flags, UInt32 *length, const void **data) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecPasswordSetInitialAccess - @abstract Set the initial access ref. Only used when a password is first added to the keychain. + @abstract Set the initial access ref. Only used when a password is first added to the keychain. */ -OSStatus SecPasswordSetInitialAccess(SecPasswordRef itemRef, SecAccessRef accessRef) API_UNAVAILABLE(ios); +OSStatus SecPasswordSetInitialAccess(SecPasswordRef itemRef, SecAccessRef accessRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #if defined(__cplusplus) } diff --git a/OSX/libsecurity_keychain/lib/SecRandomP.h b/OSX/libsecurity_keychain/lib/SecRandomP.h index 881c1397..134b9c50 100644 --- a/OSX/libsecurity_keychain/lib/SecRandomP.h +++ b/OSX/libsecurity_keychain/lib/SecRandomP.h @@ -32,11 +32,8 @@ #include #include #include -#if SEC_BUILDER -#include "SecRandom.h" -#else #include -#endif + #if defined(__cplusplus) extern "C" { #endif diff --git a/OSX/libsecurity_keychain/lib/SecTrust.cpp b/OSX/libsecurity_keychain/lib/SecTrust.cpp index f9fa38f6..eb9d2946 100644 --- a/OSX/libsecurity_keychain/lib/SecTrust.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrust.cpp @@ -24,17 +24,17 @@ #include #include -#include "SecTrust.h" -#include "SecTrustPriv.h" +#include +#include #include "Trust.h" -#include "SecBase.h" +#include #include "SecBridge.h" -#include "SecInternal.h" -#include "SecTrustSettings.h" -#include "SecTrustSettingsPriv.h" -#include "SecTrustStatusCodes.h" -#include "SecCertificatePriv.h" -#include "SecPolicyPriv.h" +#include +#include +#include +#include +#include +#include #include #include #include @@ -182,84 +182,19 @@ static uint8_t convertCssmResultToPriority(CSSM_RETURN resultCode) { } } -static bool isSoftwareUpdateDevelopment(SecTrustRef trust) { - bool isPolicy = false, isEKU = false; - CFArrayRef policies = NULL; - - /* Policy used to evaluate was SWUpdateSigning */ - SecTrustCopyPolicies(trust, &policies); - if (policies) { - SecPolicyRef swUpdatePolicy = SecPolicyCreateAppleSWUpdateSigning(); - if (swUpdatePolicy && CFArrayContainsValue(policies, CFRangeMake(0, CFArrayGetCount(policies)), - swUpdatePolicy)) { - isPolicy = true; - } - if (swUpdatePolicy) { CFRelease(swUpdatePolicy); } - CFRelease(policies); - } - if (!isPolicy) { - return false; - } - - /* Only error was EKU on the leaf */ - CFArrayRef details = SecTrustCopyFilteredDetails(trust); - CFIndex ix, count = CFArrayGetCount(details); - bool hasDisqualifyingError = false; - for (ix = 0; ix < count; ix++) { - CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix); - if (ix == 0) { // Leaf - if (CFDictionaryGetCount(detail) != 1 || // One error - CFDictionaryGetValue(detail, CFSTR("ExtendedKeyUsage")) != kCFBooleanFalse) { // kSecPolicyCheckExtendedKeyUsage - hasDisqualifyingError = true; - break; - } - } else { - if (CFDictionaryGetCount(detail) > 0) { // No errors on other certs - hasDisqualifyingError = true; - break; - } - } - } - CFReleaseSafe(details); - if (hasDisqualifyingError) { - return false; - } - - /* EKU on the leaf is the Apple Development Code Signing OID */ - SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0); - CSSM_DATA *fieldValue = NULL; - if (errSecSuccess != SecCertificateCopyFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, &fieldValue)) { - return false; - } - if (fieldValue && fieldValue->Data && fieldValue->Length == sizeof(CSSM_X509_EXTENSION)) { - const CSSM_X509_EXTENSION *ext = (const CSSM_X509_EXTENSION *)fieldValue->Data; - if (ext->format == CSSM_X509_DATAFORMAT_PARSED) { - const CE_ExtendedKeyUsage *ekus = (const CE_ExtendedKeyUsage *)ext->value.parsedValue; - if (ekus && (ekus->numPurposes == 1) && ekus->purposes[0].Data && - (ekus->purposes[0].Length == CSSMOID_APPLE_EKU_CODE_SIGNING_DEV.Length) && - (memcmp(ekus->purposes[0].Data, CSSMOID_APPLE_EKU_CODE_SIGNING_DEV.Data, - ekus->purposes[0].Length) == 0)) { - isEKU = true; - } - } - } - SecCertificateReleaseFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, fieldValue); - return isEKU; -} - // // Retrieve CSSM_LEVEL TP return code // /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result) { - /* bridge to support old functionality */ + /* bridge to support old functionality */ #if SECTRUST_DEPRECATION_WARNINGS syslog(LOG_ERR, "WARNING: SecTrustGetCssmResultCode has been deprecated since 10.7, and will be removed in a future release. Please use SecTrustCopyProperties instead."); #endif - if (!trustRef || !result) { - return errSecParam; - } + if (!trustRef || !result) { + return errSecParam; + } SecTrustResultType trustResult = kSecTrustResultInvalid; (void) SecTrustGetTrustResult(trustRef, &trustResult); @@ -268,15 +203,6 @@ OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result) return errSecSuccess; } - /* Development Software Update certs return a special error code when evaluated - * against the AppleSWUpdateSigning policy. See . */ - if (isSoftwareUpdateDevelopment(trustRef)) { - if (result) { - *result = CSSMERR_APPLETP_CODE_SIGN_DEVELOPMENT; - } - return errSecSuccess; - } - OSStatus cssmResultCode = errSecSuccess; uint8_t resultCodePriority = 0xFF; CFIndex ix, count = SecTrustGetCertificateCount(trustRef); @@ -299,10 +225,10 @@ OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result) if (resultCodePriority == 1) { break; } } - if (result) { - *result = cssmResultCode; - } - return errSecSuccess; + if (result) { + *result = cssmResultCode; + } + return errSecSuccess; } /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ @@ -374,7 +300,12 @@ out: END_SECAPI } -/* We have an iOS-style SecTrustRef, but we need to return a CDSA-based SecKeyRef. +/* + * We have an iOS-style SecTrustRef, but we need to return a CDSA-based SecKeyRef. + * + * If you need a SecKeyRef based of the iOS based SecKey, check certificate chain + * length, get certificate with SecTrustGetCertificateAtIndex(0), use + * SecCertificateCopyKey() to get a iOS based key. */ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust) { diff --git a/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp b/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp index 49b9e324..0ce7406d 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrustOSXEntryPoints.cpp @@ -26,29 +26,17 @@ * Framework. */ -#include "SecTrustOSXEntryPoints.h" +#include "OSX/trustd/macOS/SecTrustOSXEntryPoints.h" #include #include -#include #include -#include #include -#include -#include #include #include -#include -#include -#include -#include #include -#include -#include - - void SecTrustLegacySourcesListenForKeychainEvents(void) { /* Register for CertificateTrustNotification */ int out_token = 0; @@ -62,188 +50,3 @@ void SecTrustLegacySourcesListenForKeychainEvents(void) { }); } - -/* - * MARK: ocspd CRL Interface - */ -/* lengths of time strings without trailing NULL */ -#define CSSM_TIME_STRLEN 14 /* no trailing 'Z' */ -#define GENERALIZED_TIME_STRLEN 15 - -OSStatus SecTrustLegacyCRLStatus(SecCertificateRef cert, CFArrayRef chain, CFURLRef currCRLDP); -OSStatus SecTrustLegacyCRLFetch(CFURLRef currCRLDP, CFAbsoluteTime verifyTime); - -static OSStatus cssmReturnToOSStatus(CSSM_RETURN crtn) { - OSStatus status = errSecInternalComponent; - - switch (crtn) { - case CSSM_OK: - status = errSecSuccess; - break; - case CSSMERR_TP_CERT_REVOKED: - status = errSecCertificateRevoked; - break; - case CSSMERR_APPLETP_NETWORK_FAILURE: - status = errSecNetworkFailure; - break; - case CSSMERR_APPLETP_CRL_NOT_FOUND: - status = errSecCRLNotFound; - break; - default: - status = errSecInternalComponent; - } - return status; -} - -#define PEM_STRING_X509 "CERTIFICATE" -static CFDataRef CF_RETURNS_RETAINED serializedPathToPemSequences(CFArrayRef certs) { - CFMutableDataRef result = NULL; - CFIndex certIX, certCount; - require_quiet(certs, out); - certCount = CFArrayGetCount(certs); - require_quiet(certCount > 0, out); - require_quiet(result = CFDataCreateMutable(NULL, 0), out); - for (certIX = 0; certIX < certCount; certIX++) { - CFDataRef certData = (CFDataRef)CFArrayGetValueAtIndex(certs, certIX); - require_noerr_quiet(impExpPemEncodeExportRep(certData, PEM_STRING_X509, - NULL, result), out); - } -out: - return result; -} - -OSStatus SecTrustLegacyCRLStatus(SecCertificateRef cert, CFArrayRef chain, CFURLRef currCRLDP) { - OSStatus result = errSecParam; - CSSM_RETURN crtn = CSSMERR_TP_INTERNAL_ERROR; - CFDataRef serialData = NULL, pemIssuers = NULL, crlDP = NULL; - CFMutableArrayRef issuersArray = NULL; - - if (!cert || !chain) { - return result; - } - - /* serialNumber is a CSSM_DATA with the value from the TBS Certificate. */ - CSSM_DATA serialNumber = { 0, NULL }; - serialData = SecCertificateCopySerialNumberData(cert, NULL); - if (serialData) { - serialNumber.Data = (uint8_t *)CFDataGetBytePtr(serialData); - serialNumber.Length = CFDataGetLength(serialData); - } - - /* issuers is CSSM_DATA containing pem sequence of all issuers in the chain */ - CSSM_DATA issuers = { 0, NULL }; - issuersArray = CFArrayCreateMutableCopy(NULL, 0, chain); - if (issuersArray) { - CFArrayRemoveValueAtIndex(issuersArray, 0); - pemIssuers = serializedPathToPemSequences(issuersArray); - } - if (pemIssuers) { - issuers.Data = (uint8_t *)CFDataGetBytePtr(pemIssuers); - issuers.Length = CFDataGetLength(pemIssuers); - } - - /* crlUrl is CSSM_DATA with the CRLDP url*/ - CSSM_DATA crlUrl = { 0, NULL }; - crlDP = CFURLCreateData(NULL, currCRLDP, kCFStringEncodingASCII, true); - if (crlDP) { - crlUrl.Data = (uint8_t *)CFDataGetBytePtr(crlDP); - crlUrl.Length = CFDataGetLength(crlDP); - } - - if (serialNumber.Data && issuers.Data && crlUrl.Data) { - crtn = ocspdCRLStatus(serialNumber, issuers, NULL, &crlUrl); - } - - result = cssmReturnToOSStatus(crtn); - - if (serialData) { CFRelease(serialData); } - if (issuersArray) { CFRelease(issuersArray); } - if (pemIssuers) { CFRelease(pemIssuers); } - if (crlDP) { CFRelease(crlDP); } - return result; -} - -static CSSM_RETURN ocspdCRLFetchToCache(const CSSM_DATA &crlURL, - CSSM_TIMESTRING verifyTime) { - Allocator &alloc(Allocator::standard(Allocator::normal)); - CSSM_DATA crlData = { 0, NULL }; - CSSM_RETURN crtn; - - crtn = ocspdCRLFetch(alloc, crlURL, NULL, true, true, verifyTime, crlData); - if (crlData.Data) { alloc.free(crlData.Data); } - return crtn; -} - -static OSStatus fetchCRL(CFURLRef currCRLDP, CFAbsoluteTime verifyTime) { - OSStatus result = errSecParam; - CSSM_RETURN crtn = CSSMERR_TP_INTERNAL_ERROR; - CFDataRef crlDP = NULL; - char *cssmTime = NULL, *genTime = NULL; - - if (!currCRLDP) { - return result; - } - - /* crlUrl is CSSM_DATA with the CRLDP url*/ - CSSM_DATA crlUrl = { 0, NULL }; - crlDP = CFURLCreateData(NULL, currCRLDP, kCFStringEncodingASCII, true); - if (crlDP) { - crlUrl.Data = (uint8_t *)CFDataGetBytePtr(crlDP); - crlUrl.Length = CFDataGetLength(crlDP); - } - - /* determine verification time */ - cssmTime = (char *)malloc(CSSM_TIME_STRLEN + 1); - genTime = (char *)malloc(GENERAL_TIME_STRLEN + 1); - if (cssmTime && genTime) { - if (verifyTime != 0.0) { - cfAbsTimeToGgenTime(verifyTime, genTime); - } else { - cfAbsTimeToGgenTime(CFAbsoluteTimeGetCurrent(), genTime); - } - memmove(cssmTime, genTime, GENERAL_TIME_STRLEN - 1); // don't copy the Z - cssmTime[CSSM_TIME_STRLEN] = '\0'; - } - - if (crlUrl.Data && cssmTime) { - crtn = ocspdCRLFetchToCache(crlUrl, (CSSM_TIMESTRING)cssmTime); - } - - result = cssmReturnToOSStatus(crtn); - - if (crlDP) { CFRelease(crlDP); } - if (cssmTime) { free(cssmTime); } - if (genTime) { free(genTime); } - return result; -} - -/* - * MARK: async_ocspd methods - */ -static void async_ocspd_complete(async_ocspd_t *ocspd) { - if (ocspd->completed) { - ocspd->completed(ocspd); - } -} - -/* Return true, iff we didn't schedule any work, return false if we did. */ -bool SecTrustLegacyCRLFetch(async_ocspd_t *ocspd, - CFURLRef currCRLDP, CFAbsoluteTime verifyTime, - SecCertificateRef cert, CFArrayRef chain) { - ocspd->start_time = mach_absolute_time(); - dispatch_async(ocspd->queue, ^ { - OSStatus status = fetchCRL(currCRLDP, verifyTime); - switch (status) { - case errSecSuccess: - ocspd->response= SecTrustLegacyCRLStatus(cert, chain, currCRLDP); - break; - default: - ocspd->response = status; - break; - } - async_ocspd_complete(ocspd); - if (chain) { CFRelease(chain); } - }); - - return false; /* false -> something was scheduled. */ -} diff --git a/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp b/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp index a198ba56..f4ecc54e 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp +++ b/OSX/libsecurity_keychain/lib/SecTrustSettings.cpp @@ -27,9 +27,9 @@ */ #include "SecBridge.h" -#include "SecCertificatePriv.h" -#include "SecTrustSettings.h" -#include "SecTrustSettingsPriv.h" +#include +#include +#include #include "SecTrustSettingsCertificates.h" #include "SecCFRelease.h" #include "TrustSettingsUtils.h" @@ -303,6 +303,7 @@ static void tsRegisterCallback() static void tsTrustSettingsChanged() { tsPurgeCache(); + SecTrustSettingsPurgeUserAdminCertsCache(); /* The only interesting data is our pid */ NameValueDictionary nvd; diff --git a/OSX/libsecurity_keychain/lib/SecTrustedApplication.h b/OSX/libsecurity_keychain/lib/SecTrustedApplication.h index 9995db4b..b1f37a6e 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustedApplication.h +++ b/OSX/libsecurity_keychain/lib/SecTrustedApplication.h @@ -2,14 +2,14 @@ * Copyright (c) 2002-2004,2011-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, @@ -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@ */ @@ -56,7 +56,9 @@ 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) API_UNAVAILABLE(ios); +OSStatus SecTrustedApplicationCreateFromPath(const char * __nullable path, SecTrustedApplicationRef * __nonnull CF_RETURNS_RETAINED app) + API_DEPRECATED("No longer supported", macos(10.0, 10.15)) + API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecTrustedApplicationCopyData @@ -65,7 +67,9 @@ 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) API_UNAVAILABLE(ios); +OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, CFDataRef * __nonnull CF_RETURNS_RETAINED data) + API_DEPRECATED("No longer supported", macos(10.0, 10.15)) + API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecTrustedApplicationSetData @@ -74,7 +78,9 @@ 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) API_UNAVAILABLE(ios); +OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef, CFDataRef data) + API_DEPRECATED("No longer supported", macos(10.0, 10.15)) + API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h b/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h index ce5d6aa5..1b9911ad 100644 --- a/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h +++ b/OSX/libsecurity_keychain/lib/SecTrustedApplicationPriv.h @@ -1,15 +1,15 @@ /* * Copyright (c) 2003-2004,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, @@ -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@ */ @@ -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) API_UNAVAILABLE(ios); +SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const char *path) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @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) API_UNAVAILABLE(ios); + SecRequirementRef requirement, SecTrustedApplicationRef *app) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecTrustedApplicationCopyRequirement @@ -78,7 +78,7 @@ OSStatus SecTrustedApplicationCreateFromRequirement(const char *description, no SecRequirementRef could be obtained. */ OSStatus SecTrustedApplicationCopyRequirement(SecTrustedApplicationRef appRef, - SecRequirementRef *requirement) API_UNAVAILABLE(ios); + SecRequirementRef *requirement) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @@ -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) API_UNAVAILABLE(ios); + SecCertificateRef anchor, SecTrustedApplicationRef *app) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @@ -117,9 +117,9 @@ OSStatus SecTrustedApplicationCreateApplicationGroup(const char *groupName, @result A result code. See SecBase.h and CSCommon.h. */ OSStatus SecTrustedApplicationCopyExternalRepresentation( - SecTrustedApplicationRef appRef, - CFDataRef *externalRef) API_UNAVAILABLE(ios); - + SecTrustedApplicationRef appRef, + CFDataRef *externalRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + /*! @function SecTrustedApplicationCreateWithExternalRepresentation @abstract Create a SecTrustedApplicationRef from an external data representation @@ -133,7 +133,7 @@ OSStatus SecTrustedApplicationCopyExternalRepresentation( */ OSStatus SecTrustedApplicationCreateWithExternalRepresentation( CFDataRef externalRef, - SecTrustedApplicationRef *appRef) API_UNAVAILABLE(ios); + SecTrustedApplicationRef *appRef) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* @@ -146,10 +146,10 @@ enum { OSStatus SecTrustedApplicationMakeEquivalent(SecTrustedApplicationRef oldRef, - SecTrustedApplicationRef newRef, UInt32 flags) API_UNAVAILABLE(ios); + SecTrustedApplicationRef newRef, UInt32 flags) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); OSStatus -SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags) API_UNAVAILABLE(ios); +SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* @@ -157,7 +157,7 @@ SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 f * pre-emptive code equivalency establishment */ OSStatus -SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path) API_UNAVAILABLE(ios); +SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* @@ -165,7 +165,7 @@ SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path * This is for system update installers (only)! */ OSStatus -SecTrustedApplicationUseAlternateSystem(const char *systemRoot) API_UNAVAILABLE(ios); +SecTrustedApplicationUseAlternateSystem(const char *systemRoot) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); #if defined(__cplusplus) diff --git a/OSX/libsecurity_keychain/lib/SecWrappedKeys.cpp b/OSX/libsecurity_keychain/lib/SecWrappedKeys.cpp index e42f34c2..83b8db37 100644 --- a/OSX/libsecurity_keychain/lib/SecWrappedKeys.cpp +++ b/OSX/libsecurity_keychain/lib/SecWrappedKeys.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include @@ -377,7 +376,6 @@ OSStatus impExpWrappedKeyOpenSslExport( const char **pemHeader, // RETURNED CFArrayRef *pemParamLines) // RETURNED { - DevRandomGenerator rng; SecNssCoder coder; CSSM_CSP_HANDLE cspHand = 0; OSStatus ortn; @@ -405,8 +403,8 @@ OSStatus impExpWrappedKeyOpenSslExport( /* 8 bytes of random IV/salt */ uint8 saltIv[8]; CSSM_DATA saltIvData = { 8, saltIv} ; - rng.random(saltIv, 8); - + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(saltIv), saltIv)); + /* derive wrapping key */ CSSM_KEY wrappingKey; wrappingKey.KeyData.Data = NULL; diff --git a/OSX/libsecurity_keychain/lib/StorageManager.cpp b/OSX/libsecurity_keychain/lib/StorageManager.cpp index c8484cea..efab9b8b 100644 --- a/OSX/libsecurity_keychain/lib/StorageManager.cpp +++ b/OSX/libsecurity_keychain/lib/StorageManager.cpp @@ -51,7 +51,7 @@ #include "TrustSettingsSchema.h" #include #include -#include +#include #include "TokenLogin.h" //%%% add this to AuthorizationTagsPriv.h later @@ -1573,7 +1573,9 @@ void StorageManager::login(UInt32 nameLength, const void *name, } } } - AuthorizationFreeItemSet(returnedInfo); + if(returnedInfo) { + AuthorizationFreeItemSet(returnedInfo); + } } AuthorizationFree(authRef, 0); } diff --git a/OSX/libsecurity_keychain/lib/TokenLogin.cpp b/OSX/libsecurity_keychain/lib/TokenLogin.cpp index bfe91fd5..77b27a02 100644 --- a/OSX/libsecurity_keychain/lib/TokenLogin.cpp +++ b/OSX/libsecurity_keychain/lib/TokenLogin.cpp @@ -35,7 +35,7 @@ #include extern "C" { -#include +#include #include } @@ -297,30 +297,18 @@ OSStatus TokenLoginGetUnlockKey(CFDictionaryRef context, CFDataRef *unlockKey) OSStatus TokenLoginGetLoginData(CFDictionaryRef context, CFDictionaryRef *loginData) { - 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); - os_log(TL_LOG, "stored data %@", storedData.get()); - if (!storedData) { + // this is not an error, might be a normal situation if the value does not exist os_log_debug(TL_LOG, "Failed to read token login plist"); - os_log(TL_LOG, "Failed to read token login plist"); return errSecIO; } diff --git a/OSX/libsecurity_keychain/lib/TrustAdditions.cpp b/OSX/libsecurity_keychain/lib/TrustAdditions.cpp index 4465256b..3fa9aabb 100644 --- a/OSX/libsecurity_keychain/lib/TrustAdditions.cpp +++ b/OSX/libsecurity_keychain/lib/TrustAdditions.cpp @@ -47,9 +47,9 @@ #include #include // for CSSM_APPLE_TP_OCSP_OPTIONS, CSSM_APPLE_TP_OCSP_OPT_FLAGS -#include "SecTrustPriv.h" -#include "SecTrustSettings.h" -#include "SecTrustSettingsPriv.h" +#include +#include +#include // // Macros diff --git a/OSX/libsecurity_keychain/lib/TrustSettings.cpp b/OSX/libsecurity_keychain/lib/TrustSettings.cpp index ceafbb01..7474aca6 100644 --- a/OSX/libsecurity_keychain/lib/TrustSettings.cpp +++ b/OSX/libsecurity_keychain/lib/TrustSettings.cpp @@ -28,7 +28,7 @@ #include "TrustSettings.h" #include "TrustSettingsSchema.h" -#include "SecTrustSettings.h" +#include #include "TrustSettingsUtils.h" #include "TrustKeychains.h" #include "Certificate.h" @@ -1222,10 +1222,10 @@ CFArrayRef TrustSettings::validateApiTrustSettings( OSStatus ortn = errSecSuccess; SecPolicyRef certPolicy; SecTrustedApplicationRef certApp; + CFTypeRef oidData = NULL; /* convert */ for(CFIndex dex=0; dex +#include #include +#include /* * Clarification of the bool arguments to our main constructor. diff --git a/OSX/libsecurity_keychain/lib/cssmdatetime.cpp b/OSX/libsecurity_keychain/lib/cssmdatetime.cpp index dd0378e6..7943e920 100644 --- a/OSX/libsecurity_keychain/lib/cssmdatetime.cpp +++ b/OSX/libsecurity_keychain/lib/cssmdatetime.cpp @@ -36,7 +36,7 @@ #include #include #include -#include +#include namespace Security { diff --git a/OSX/libsecurity_keychain/lib/defaultcreds.h b/OSX/libsecurity_keychain/lib/defaultcreds.h index f16dbd85..a373f1b1 100644 --- a/OSX/libsecurity_keychain/lib/defaultcreds.h +++ b/OSX/libsecurity_keychain/lib/defaultcreds.h @@ -27,7 +27,7 @@ #ifndef _SECURITY_DEFAULTCREDS_H #define _SECURITY_DEFAULTCREDS_H -#include "SecBase.h" +#include #include #include #include diff --git a/OSX/libsecurity_keychain/regressions/kc-20-item-delete-stress.c b/OSX/libsecurity_keychain/regressions/kc-20-item-delete-stress.c index 51130929..befc7e17 100644 --- a/OSX/libsecurity_keychain/regressions/kc-20-item-delete-stress.c +++ b/OSX/libsecurity_keychain/regressions/kc-20-item-delete-stress.c @@ -61,7 +61,7 @@ static void tests() { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, false); UInt32 didGetNotification = 0; - ok_status(SecKeychainAddCallback(callbackFunction, kSecAddEventMask | kSecDeleteEventMask | kSecDataAccessEventMask, &didGetNotification), "add callback"); + ok_status(SecKeychainAddCallback(callbackFunction, kSecAddEventMask | kSecDeleteEventMask, &didGetNotification), "add callback"); // Run the CFRunLoop to mark this run loop as "pumped" CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, false); diff --git a/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m b/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m index 9bbf0759..272e30f3 100644 --- a/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m +++ b/OSX/libsecurity_keychain/regressions/kc-41-sececkey.m @@ -517,7 +517,7 @@ static void testkeyexchange(unsigned long keySizeInBits) (id)kSecAttrKeySizeInBits: @(keySizeInBits), (id)kSecAttrIsPermanent: @NO, (id)kSecAttrLabel: @"sectests:kc-41-sececkey:testkeyexchange", - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(status = SecKeyGeneratePair((CFDictionaryRef)kgp1, &pubKey1, &privKey1), "Generate %ld bit (%ld byte) EC keypair (status = %d)", @@ -540,7 +540,7 @@ static void testkeyexchange(unsigned long keySizeInBits) (id)kSecAttrKeySizeInBits: @(keySizeInBits), (id)kSecAttrIsPermanent: @NO, (id)kSecAttrLabel: @"sectests:kc-41-sececkey:testkeyexchange", - (id)kSecAttrNoLegacy: @NO, + (id)kSecUseDataProtectionKeychain: @NO, }; ok_status(status = SecKeyGeneratePair((CFDictionaryRef)kgp2, &pubKey2, &privKey2), "Generate %ld bit (%ld byte) EC keypair (status = %d)", @@ -585,6 +585,16 @@ static void testkeyexchange(unsigned long keySizeInBits) } } + // Test proper failure modes. + NSError *error; + NSData *res; + res = CFBridgingRelease(SecKeyCopyKeyExchangeResult(privKey1, kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1, pubKey2, (CFDictionaryRef)@{}, (void *)&error)); + is(res, nil, "keyExchange with missing required attributes did not fail"); + res = CFBridgingRelease(SecKeyCopyKeyExchangeResult(privKey1, kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1, pubKey2, (CFDictionaryRef)@{(id)kSecKeyKeyExchangeParameterRequestedSize: @"16"}, (void *)&error)); + is(res, nil, "keyExchange with improper typed attributes did not fail"); + res = CFBridgingRelease(SecKeyCopyKeyExchangeResult(privKey1, kSecKeyAlgorithmECDHKeyExchangeStandardX963SHA1, pubKey2, (CFDictionaryRef)@{(id)kSecKeyKeyExchangeParameterRequestedSize: @16, (id)kSecKeyKeyExchangeParameterSharedInfo: @"sharedInfo"}, (void *)&error)); + is(res, nil, "keyExchange with improper typed attributes did not fail"); + CFReleaseNull(privKey1); CFReleaseNull(pubKey1); CFReleaseNull(privKey2); @@ -628,7 +638,7 @@ static void tests(void) int kc_41_sececkey(int argc, char *const *argv) { - plan_tests(272); + plan_tests(281); tests(); diff --git a/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c b/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c index 7c6d545d..557e5447 100644 --- a/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c +++ b/OSX/libsecurity_keychain/regressions/kc-42-trust-revocation.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2014-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -29,222 +29,220 @@ #include "utilities/SecCFRelease.h" #include "utilities/SecCFWrappers.h" -/* s:/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 */ -/* i:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ -/* SHA1 Fingerprint=BB:20:B0:3F:FB:93:E1:77:FF:23:A7:43:89:49:60:1A:41:AE:C6:1C */ -/* EXPIRES Oct 30 23:59:59 2019 GMT */ - -unsigned char leaf_certificate[1896]={ - 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, +/* subject:/businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=Delaware/serialNumber=3014267/C=US/ST=California/L=San Jose/O=PayPal, Inc./OU=CDN Support/CN=www.paypal.com */ +/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA */ +/* EXPIRES Aug 18 12:00:00 2020 GMT */ + +unsigned char leaf_certificate[2012]={ + 0x30,0x82,0x07,0xD8,0x30,0x82,0x06,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, + 0x5B,0xDA,0x66,0x5F,0xC4,0x4B,0x75,0x17,0xB6,0x88,0x2C,0x1E,0xAB,0xD4,0xDC,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x75, + 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, + 0x34,0x30,0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64, + 0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76, + 0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x38,0x31,0x34,0x30, + 0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x30,0x30,0x38,0x31,0x38,0x31,0x32, + 0x30,0x30,0x30,0x30,0x5A,0x30,0x81,0xDC,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04, + 0x0F,0x0C,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72,0x67,0x61,0x6E, + 0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,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,0x13,0x08,0x44, + 0x65,0x6C,0x61,0x77,0x61,0x72,0x65,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,0x08,0x13, + 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06, + 0x03,0x55,0x04,0x07,0x13,0x08,0x53,0x61,0x6E,0x20,0x4A,0x6F,0x73,0x65,0x31,0x15, + 0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x13,0x0C,0x50,0x61,0x79,0x50,0x61,0x6C,0x2C, + 0x20,0x49,0x6E,0x63,0x2E,0x31,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0B,0x13,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, + 0x03,0x55,0x04,0x03,0x13,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, + 0x02,0x82,0x01,0x01,0x00,0xCE,0xA1,0xFA,0xE0,0x19,0x8B,0xD7,0x8D,0x51,0xC7,0xD5, + 0x62,0x84,0x83,0x13,0xB9,0xD7,0xF6,0xCD,0x93,0xC5,0x70,0xD1,0x69,0x59,0x03,0x2B, + 0xB4,0x8B,0x00,0x14,0x50,0xB6,0x77,0x9A,0xB2,0x3C,0xFB,0x13,0xB0,0x80,0x4E,0x55, + 0x1A,0x08,0x60,0xA1,0x06,0x3D,0x40,0xD2,0x00,0xD2,0x67,0x45,0x3E,0xB1,0x26,0x45, + 0x14,0x00,0x65,0x78,0xAD,0xB3,0x39,0x4B,0xE6,0xCF,0x28,0x92,0xCE,0x3E,0xB4,0x5C, + 0xC1,0x1C,0x7B,0x49,0xA7,0x60,0xFD,0x06,0x2C,0x51,0x2B,0x10,0x11,0x01,0xFA,0x3A, + 0x73,0x9E,0x2D,0xB9,0xF6,0x89,0x52,0xB4,0x32,0x20,0xCC,0x2B,0xDA,0x6A,0x5F,0x6C, + 0xFA,0x31,0xDE,0x96,0xA5,0x90,0xAE,0xD1,0x98,0x77,0x62,0x99,0xC3,0xAA,0xB5,0x48, + 0xE3,0x43,0x24,0xBF,0x59,0xC1,0xF1,0x32,0x4C,0x97,0xDF,0x06,0xBD,0x7B,0x52,0x68, + 0x10,0x1F,0x68,0x7C,0x91,0xAE,0xA4,0xD9,0xC2,0xF7,0x4B,0x86,0x83,0x18,0xA5,0x58, + 0xBB,0xCE,0xB6,0x7F,0xF6,0xEF,0x0E,0x7A,0xA7,0x60,0x18,0x90,0xAA,0x12,0x1A,0x05, + 0xEC,0x35,0x11,0x84,0xE7,0x24,0xB1,0x9E,0xCD,0xB7,0xB1,0x93,0xA8,0xB6,0x04,0x9E, + 0x4D,0x17,0xB5,0xE8,0xAE,0xD7,0xE4,0x9B,0xB3,0x3D,0xC1,0xAD,0x64,0x63,0x11,0xC6, + 0x59,0x15,0x6A,0x06,0x6C,0xAE,0x9F,0x2B,0x36,0xC7,0xF8,0x6A,0xAD,0x30,0x2A,0x40, + 0x63,0x92,0xF5,0x73,0x4A,0xF2,0x53,0x68,0x32,0x52,0x0E,0xA1,0x2D,0x85,0x5F,0x99, + 0xA0,0x64,0x85,0x62,0x9C,0x1A,0x1C,0x0A,0xD5,0x8A,0xBD,0x2C,0x27,0xAD,0xC4,0xFD, + 0xAA,0xB6,0x4D,0xBF,0x7B,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0xFA,0x30,0x82, + 0x03,0xF6,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x3D, + 0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65,0xD3,0x21,0xD4,0xF8, + 0xF8,0xD6,0x0F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xBB,0x3A, + 0xE6,0xA8,0x29,0x00,0x98,0x84,0x32,0x79,0xCE,0x77,0xF0,0x01,0x6D,0x5F,0x0A,0x79, + 0x63,0xB9,0x30,0x81,0xA5,0x06,0x03,0x55,0x1D,0x11,0x04,0x81,0x9D,0x30,0x81,0x9A, 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, + 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,0x15,0x77,0x77,0x77,0x2E,0x70,0x61,0x79,0x70,0x61,0x6C,0x6F, + 0x62,0x6A,0x65,0x63,0x74,0x73,0x2E,0x63,0x6F,0x6D,0x82,0x0E,0x63,0x6D,0x73,0x2E, + 0x70,0x61,0x79,0x70,0x61,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,0x75,0x06,0x03,0x55,0x1D,0x1F, + 0x04,0x6E,0x30,0x6C,0x30,0x34,0xA0,0x32,0xA0,0x30,0x86,0x2E,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,0x68,0x61,0x32,0x2D,0x65,0x76,0x2D,0x73,0x65,0x72, + 0x76,0x65,0x72,0x2D,0x67,0x32,0x2E,0x63,0x72,0x6C,0x30,0x34,0xA0,0x32,0xA0,0x30, + 0x86,0x2E,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,0x68,0x61,0x32,0x2D, + 0x65,0x76,0x2D,0x73,0x65,0x72,0x76,0x65,0x72,0x2D,0x67,0x32,0x2E,0x63,0x72,0x6C, + 0x30,0x4B,0x06,0x03,0x55,0x1D,0x20,0x04,0x44,0x30,0x42,0x30,0x37,0x06,0x09,0x60, + 0x86,0x48,0x01,0x86,0xFD,0x6C,0x02,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,0x07,0x06,0x05,0x67,0x81,0x0C,0x01,0x01,0x30,0x81,0x88, + 0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x7C,0x30,0x7A,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,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, + 0x86,0x46,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,0x45,0x78,0x74,0x65,0x6E,0x64, + 0x65,0x64,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,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,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,0x65,0x3A,0xAE,0x43,0x7C,0x00,0x00,0x04,0x03,0x00, + 0x48,0x30,0x46,0x02,0x21,0x00,0xCB,0xD9,0x94,0x2A,0x60,0x3F,0x6F,0xAF,0xF2,0x01, + 0xFC,0xDB,0x2D,0xCF,0x42,0x83,0x0D,0x55,0x45,0x50,0x34,0x18,0xC6,0xE0,0x36,0x72, + 0xEE,0xA4,0x45,0x06,0x8D,0x09,0x02,0x21,0x00,0x93,0x31,0x1F,0x36,0x47,0x36,0xFC, + 0x1F,0xBC,0xF1,0x54,0x77,0x42,0x3B,0xAD,0x9D,0xA1,0x75,0x42,0x98,0xF4,0x42,0x44, + 0xA8,0x74,0xF1,0x80,0xB4,0x1D,0xFB,0xED,0x45,0x00,0x75,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,0x65, + 0x3A,0xAE,0x43,0xD9,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x70,0x2F, + 0xCD,0xBB,0x18,0x85,0xB3,0x32,0xE6,0x35,0x1A,0xCE,0x3E,0x97,0xDE,0x60,0xCC,0x8E, + 0x3C,0xAB,0xC8,0xDE,0x41,0x33,0x06,0xC3,0x20,0x5B,0xF9,0xF1,0x3F,0x67,0x02,0x20, + 0x71,0xCD,0x42,0x11,0x4D,0xF8,0xFE,0x29,0xEB,0xE9,0xD2,0x69,0x8E,0x39,0xEF,0x6A, + 0xE8,0xAF,0xE4,0x94,0xE5,0x36,0x92,0x54,0x6E,0x56,0x67,0x2C,0xEC,0x6C,0xF0,0xF0, + 0x00,0x76,0x00,0xBB,0xD9,0xDF,0xBC,0x1F,0x8A,0x71,0xB5,0x93,0x94,0x23,0x97,0xAA, + 0x92,0x7B,0x47,0x38,0x57,0x95,0x0A,0xAB,0x52,0xE8,0x1A,0x90,0x96,0x64,0x36,0x8E, + 0x1E,0xD1,0x85,0x00,0x00,0x01,0x65,0x3A,0xAE,0x44,0x68,0x00,0x00,0x04,0x03,0x00, + 0x47,0x30,0x45,0x02,0x21,0x00,0xCB,0xF3,0x70,0x9C,0x39,0x96,0x83,0x9F,0x56,0x70, + 0xCD,0x14,0x4A,0xF8,0xF9,0xCE,0x32,0xFE,0xEB,0x00,0xDA,0x95,0x39,0x33,0xBB,0xE1, + 0x1C,0xD0,0xFA,0xF3,0x4B,0x47,0x02,0x20,0x12,0xA8,0xF7,0x7B,0x29,0x73,0x5A,0x35, + 0x32,0x6C,0x04,0x9F,0x48,0x7C,0x13,0x7A,0x27,0x65,0xF0,0x18,0x98,0xF1,0x71,0xC4, + 0x72,0xF5,0xF2,0x5C,0xF7,0xE5,0x20,0x62,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xA1,0xEB,0x9E,0x7F, + 0xC7,0x17,0x2E,0x28,0x2F,0x4D,0x0B,0x38,0x95,0xBB,0x5B,0xCA,0x9E,0x14,0x38,0x8C, + 0xEC,0xA6,0x23,0x26,0x1F,0x3B,0x6A,0x07,0xDE,0x4E,0x4B,0x41,0x11,0xFE,0xEE,0xFD, + 0xF7,0x94,0x8E,0xD0,0x2D,0x26,0x42,0x3B,0xF2,0x3D,0xE8,0xA9,0xB5,0x0E,0x58,0x87, + 0xEF,0xCE,0x54,0x2A,0x95,0xEA,0x9D,0x99,0xA4,0x19,0x92,0x73,0xE9,0xA7,0xE6,0xDC, + 0xE3,0x3F,0x72,0xDA,0x57,0x1A,0x32,0x8F,0x08,0x21,0x8D,0xAD,0x37,0x98,0xD0,0x57, + 0x3E,0x67,0x64,0x10,0x81,0xBE,0x57,0xBF,0x0E,0xBF,0x98,0x88,0x9B,0xAB,0xF1,0x18, + 0x7D,0x71,0x4A,0x31,0xEC,0xB1,0x5F,0x22,0x5E,0x95,0xA8,0xDE,0x02,0x7E,0xC4,0x7D, + 0xE4,0xAE,0xD6,0x35,0x02,0xD9,0x20,0xDB,0x8D,0xC9,0x83,0x03,0x42,0x23,0x7C,0x60, + 0xA7,0x4D,0x55,0x30,0xB0,0x26,0xBC,0x8B,0xEF,0x4E,0xA9,0x88,0x29,0xE1,0x1D,0xF3, + 0xC5,0x24,0x73,0xA9,0x07,0x71,0x9B,0x04,0x8F,0x1C,0x2D,0x36,0x2B,0xD6,0xC7,0x69, + 0xE5,0xD5,0xCC,0x83,0xBB,0xD0,0x75,0xC0,0x92,0xB4,0x0F,0x93,0x2E,0x20,0x15,0xE0, + 0x6C,0x52,0xA6,0xA9,0x48,0x56,0x94,0x45,0xD1,0x8A,0x6A,0x61,0xBC,0xE3,0x4E,0x24, + 0x67,0x7B,0xD6,0xA4,0xFD,0xE1,0xB4,0xFF,0xF9,0xB8,0x6A,0xDB,0xCA,0x06,0x95,0xE1, + 0xF5,0x95,0xE4,0xEF,0xA9,0xFB,0x74,0x7E,0x3F,0x9E,0xFD,0xAE,0xDE,0x1F,0x1D,0x6E, + 0xDD,0xF6,0x00,0xC4,0xD5,0xA3,0x34,0x02,0x26,0x23,0x1A,0x46,0x53,0x25,0x30,0x49, + 0x5A,0x36,0xF7,0x0F,0xC2,0x61,0x87,0x36,0x71,0x2E,0xBD,0xCB, }; -/* s:/C=US/O=Symantec Corporation/OU=Symantec Trust Network/CN=Symantec Class 3 EV SSL CA - G3 */ -/* i:/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 */ -/* SHA1 Fingerprint=E3:FC:0A:D8:4F:2F:5A:83:ED:6F:86:F5:67:F8:B1:4B:40:DC:BF:12 */ -/* EXPIRES: Oct 30 23:59:59 2023 GMT */ - -unsigned char CA_certificate[1327]={ - 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, +/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA */ +/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ +/* EXPIRES Oct 22 12:00:00 2028 GMT */ + +unsigned char CA_certificate[1210]={ + 0x30,0x82,0x04,0xB6,0x30,0x82,0x03,0x9E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0C, + 0x79,0xA9,0x44,0xB0,0x8C,0x11,0x95,0x20,0x92,0x61,0x5F,0xE2,0x6B,0x1D,0x83,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x6C, + 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, + 0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63, + 0x65,0x20,0x45,0x56,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x33,0x31,0x30,0x32,0x32,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32, + 0x38,0x31,0x30,0x32,0x32,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x75,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,0x34,0x30, + 0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56, + 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,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,0xD7,0x53,0xA4,0x04,0x51,0xF8,0x99,0xA6,0x16,0x48,0x4B,0x67, + 0x27,0xAA,0x93,0x49,0xD0,0x39,0xED,0x0C,0xB0,0xB0,0x00,0x87,0xF1,0x67,0x28,0x86, + 0x85,0x8C,0x8E,0x63,0xDA,0xBC,0xB1,0x40,0x38,0xE2,0xD3,0xF5,0xEC,0xA5,0x05,0x18, + 0xB8,0x3D,0x3E,0xC5,0x99,0x17,0x32,0xEC,0x18,0x8C,0xFA,0xF1,0x0C,0xA6,0x64,0x21, + 0x85,0xCB,0x07,0x10,0x34,0xB0,0x52,0x88,0x2B,0x1F,0x68,0x9B,0xD2,0xB1,0x8F,0x12, + 0xB0,0xB3,0xD2,0xE7,0x88,0x1F,0x1F,0xEF,0x38,0x77,0x54,0x53,0x5F,0x80,0x79,0x3F, + 0x2E,0x1A,0xAA,0xA8,0x1E,0x4B,0x2B,0x0D,0xAB,0xB7,0x63,0xB9,0x35,0xB7,0x7D,0x14, + 0xBC,0x59,0x4B,0xDF,0x51,0x4A,0xD2,0xA1,0xE2,0x0C,0xE2,0x90,0x82,0x87,0x6A,0xAE, + 0xEA,0xD7,0x64,0xD6,0x98,0x55,0xE8,0xFD,0xAF,0x1A,0x50,0x6C,0x54,0xBC,0x11,0xF2, + 0xFD,0x4A,0xF2,0x9D,0xBB,0x7F,0x0E,0xF4,0xD5,0xBE,0x8E,0x16,0x89,0x12,0x55,0xD8, + 0xC0,0x71,0x34,0xEE,0xF6,0xDC,0x2D,0xEC,0xC4,0x87,0x25,0x86,0x8D,0xD8,0x21,0xE4, + 0xB0,0x4D,0x0C,0x89,0xDC,0x39,0x26,0x17,0xDD,0xF6,0xD7,0x94,0x85,0xD8,0x04,0x21, + 0x70,0x9D,0x6F,0x6F,0xFF,0x5C,0xBA,0x19,0xE1,0x45,0xCB,0x56,0x57,0x28,0x7E,0x1C, + 0x0D,0x41,0x57,0xAA,0xB7,0xB8,0x27,0xBB,0xB1,0xE4,0xFA,0x2A,0xEF,0x21,0x23,0x75, + 0x1A,0xAD,0x2D,0x9B,0x86,0x35,0x8C,0x9C,0x77,0xB5,0x73,0xAD,0xD8,0x94,0x2D,0xE4, + 0xF3,0x0C,0x9D,0xEE,0xC1,0x4E,0x62,0x7E,0x17,0xC0,0x71,0x9E,0x2C,0xDE,0xF1,0xF9, + 0x10,0x28,0x19,0x33,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x49,0x30,0x82,0x01, + 0x45,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,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,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,0x4B,0x06,0x03,0x55,0x1D, + 0x1F,0x04,0x44,0x30,0x42,0x30,0x40,0xA0,0x3E,0xA0,0x3C,0x86,0x3A,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,0x48,0x69, + 0x67,0x68,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63,0x65,0x45,0x56,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,0x3D,0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65,0xD3,0x21, + 0xD4,0xF8,0xF8,0xD6,0x0F,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, + 0x80,0x14,0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08, + 0x02,0xEF,0x63,0x64,0x2B,0xC3,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, + 0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9D,0xB6,0xD0,0x90,0x86,0xE1, + 0x86,0x02,0xED,0xC5,0xA0,0xF0,0x34,0x1C,0x74,0xC1,0x8D,0x76,0xCC,0x86,0x0A,0xA8, + 0xF0,0x4A,0x8A,0x42,0xD6,0x3F,0xC8,0xA9,0x4D,0xAD,0x7C,0x08,0xAD,0xE6,0xB6,0x50, + 0xB8,0xA2,0x1A,0x4D,0x88,0x07,0xB1,0x29,0x21,0xDC,0xE7,0xDA,0xC6,0x3C,0x21,0xE0, + 0xE3,0x11,0x49,0x70,0xAC,0x7A,0x1D,0x01,0xA4,0xCA,0x11,0x3A,0x57,0xAB,0x7D,0x57, + 0x2A,0x40,0x74,0xFD,0xD3,0x1D,0x85,0x18,0x50,0xDF,0x57,0x47,0x75,0xA1,0x7D,0x55, + 0x20,0x2E,0x47,0x37,0x50,0x72,0x8C,0x7F,0x82,0x1B,0xD2,0x62,0x8F,0x2D,0x03,0x5A, + 0xDA,0xC3,0xC8,0xA1,0xCE,0x2C,0x52,0xA2,0x00,0x63,0xEB,0x73,0xBA,0x71,0xC8,0x49, + 0x27,0x23,0x97,0x64,0x85,0x9E,0x38,0x0E,0xAD,0x63,0x68,0x3C,0xBA,0x52,0x81,0x58, + 0x79,0xA3,0x2C,0x0C,0xDF,0xDE,0x6D,0xEB,0x31,0xF2,0xBA,0xA0,0x7C,0x6C,0xF1,0x2C, + 0xD4,0xE1,0xBD,0x77,0x84,0x37,0x03,0xCE,0x32,0xB5,0xC8,0x9A,0x81,0x1A,0x4A,0x92, + 0x4E,0x3B,0x46,0x9A,0x85,0xFE,0x83,0xA2,0xF9,0x9E,0x8C,0xA3,0xCC,0x0D,0x5E,0xB3, + 0x3D,0xCF,0x04,0x78,0x8F,0x14,0x14,0x7B,0x32,0x9C,0xC7,0x00,0xA6,0x5C,0xC4,0xB5, + 0xA1,0x55,0x8D,0x5A,0x56,0x68,0xA4,0x22,0x70,0xAA,0x3C,0x81,0x71,0xD9,0x9D,0xA8, + 0x45,0x3B,0xF4,0xE5,0xF6,0xA2,0x51,0xDD,0xC7,0x7B,0x62,0xE8,0x6F,0x0C,0x74,0xEB, + 0xB8,0xDA,0xF8,0xBF,0x87,0x0D,0x79,0x50,0x91,0x90,0x9B,0x18,0x3B,0x91,0x59,0x27, + 0xF1,0x35,0x28,0x13,0xAB,0x26,0x7E,0xD5,0xF7,0x7A, }; unsigned char smime_leaf_certificate[1338]={ @@ -705,9 +703,11 @@ static void tests(void) 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. - is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); + // %%% This is expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked. + // While it is still present in the CRL, we no longer check revocation for it because the root + // "TC TrustCenter Universal CA I" is not system-trusted. Accept either failure mode here. + ok((trust_result == kSecTrustResultRecoverableTrustFailure) || + (trust_result == kSecTrustResultFatalTrustFailure), "trust result failure"); CFReleaseNull(trust); } @@ -726,9 +726,11 @@ static void tests(void) 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. - is_status(trust_result, kSecTrustResultFatalTrustFailure, "trust is kSecTrustResultFatalTrustFailure"); + // %%% This is expected to fail, since the "TC TrustCenter Class 1 L1 CA IX" CA is revoked. + // While it is still present in the CRL, we no longer check revocation for it because the root + // "TC TrustCenter Universal CA I" is not system-trusted. Accept either failure mode here. + ok((trust_result == kSecTrustResultRecoverableTrustFailure) || + (trust_result == kSecTrustResultFatalTrustFailure), "trust result failure"); CFReleaseNull(trust); } diff --git a/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m b/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m index 52cddf2e..a30bb8e6 100644 --- a/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m +++ b/OSX/libsecurity_keychain/regressions/kc-43-seckey-interop.m @@ -52,7 +52,7 @@ static void test_generate_nolegacy() { NSDictionary *query, *params = @{ (id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @1024, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecAttrIsPermanent: @YES, (id)kSecAttrLabel: @"sectests:generate-no-legacy", }; @@ -64,7 +64,7 @@ static void test_generate_nolegacy() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:generate-no-legacy", (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnRef: @YES, }; ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&key)); @@ -75,7 +75,7 @@ static void test_generate_nolegacy() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:generate-no-legacy", (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnRef: @YES, }; ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&key)); @@ -86,7 +86,7 @@ static void test_generate_nolegacy() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:generate-no-legacy", (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPublic, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnRef: @YES, }; ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&key)); @@ -97,7 +97,7 @@ static void test_generate_nolegacy() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:generate-no-legacy", (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnRef: @YES, }; ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&key)); @@ -108,7 +108,7 @@ static void test_generate_nolegacy() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:generate-no-legacy", (id)kSecMatchLimit: (id)kSecMatchLimitAll, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemDelete((__bridge CFDictionaryRef)query)); is_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecItemNotFound); @@ -136,7 +136,7 @@ static void test_generate_access_control() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:generate-access-control", (id)kSecMatchLimit: (id)kSecMatchLimitAll, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL)); @@ -154,7 +154,7 @@ static void test_add_ios_key() { NSDictionary *params = @{ (id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @1024, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecAttrIsPermanent: @NO, }; @@ -170,7 +170,7 @@ static void test_add_ios_key() { NSDictionary *query = @{ (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:add-ios-key", - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnRef: @YES, }; SecKeyRef key = NULL; @@ -182,7 +182,7 @@ static void test_add_ios_key() { (id)kSecClass: (id)kSecClassKey, (id)kSecAttrLabel: @"sectests:add-ios-key", (id)kSecMatchLimit: (id)kSecMatchLimitAll, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemDelete((__bridge CFDictionaryRef)query)); is_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecItemNotFound); @@ -248,14 +248,14 @@ static void test_store_cert_to_ios() { SecItemDelete((CFDictionaryRef)@{ (id)kSecClass: (id)kSecClassCertificate, (id)kSecAttrLabel: @"sectests:store_cert_to_ios", - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }); // Store certificate to modern keychain. NSDictionary *attrs = @{ (id)kSecValueRef: (__bridge id)cert, (id)kSecAttrLabel: @"sectests:store_cert_to_ios", - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnPersistentRef: @YES, }; id persistentRef; @@ -299,7 +299,7 @@ static void test_store_identity_to_ios() { NSDictionary *attrs = @{ (id)kSecValueRef: (__bridge id)identity, (id)kSecAttrLabel: @"sectests:store_identity_to_ios", - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecReturnPersistentRef: @YES, }; id persistentRef; @@ -370,7 +370,7 @@ static void test_convert_key_to_persistent_ref() { NSDictionary *query = @{ (id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @1024, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecAttrIsPermanent: @NO, }; SecKeyRef pubKey = NULL; @@ -383,7 +383,7 @@ static void test_convert_key_to_persistent_ref() { NSDictionary *query = @{ (id)kSecAttrLabel: label, (id)kSecValueRef: (__bridge id)privKey, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemAdd((CFDictionaryRef)query, NULL)); } @@ -395,14 +395,14 @@ static void test_convert_key_to_persistent_ref() { NSDictionary *query = @{ (id)kSecValueRef: (__bridge id)privKey, (id)kSecReturnPersistentRef: @YES, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&queriedPersistentKeyRef)); }{ NSDictionary *query = @{ (id)kSecValuePersistentRef: (__bridge id)queriedPersistentKeyRef, (id)kSecReturnRef: @YES, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&queriedKeyRef)); }{ @@ -450,7 +450,7 @@ static void test_convert_cert_to_persistent_ref() { NSDictionary *query = @{ (id)kSecAttrLabel: label, (id)kSecValueRef: (__bridge id)cert, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemAdd((CFDictionaryRef)query, NULL)); } @@ -462,14 +462,14 @@ static void test_convert_cert_to_persistent_ref() { NSDictionary *query = @{ (id)kSecValueRef: (__bridge id)cert, (id)kSecReturnPersistentRef: @YES, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&queriedPersistentCertRef)); }{ NSDictionary *query = @{ (id)kSecValuePersistentRef: (__bridge id)queriedPersistentCertRef, (id)kSecReturnRef: @YES, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&queriedCertRef)); }{ @@ -527,7 +527,7 @@ static void test_convert_identity_to_persistent_ref() { NSDictionary *query = @{ (id)kSecAttrLabel: label, (id)kSecValueRef: (__bridge id)idnt, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemAdd((CFDictionaryRef)query, NULL)); } @@ -539,14 +539,14 @@ static void test_convert_identity_to_persistent_ref() { NSDictionary *query = @{ (id)kSecValueRef: (__bridge id)idnt, (id)kSecReturnPersistentRef: @YES, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&queriedPersistentIdntRef)); }{ NSDictionary *query = @{ (id)kSecValuePersistentRef: (__bridge id)queriedPersistentIdntRef, (id)kSecReturnRef: @YES, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&queriedIdntRef)); }{ @@ -568,7 +568,7 @@ static void test_convert_identity_to_persistent_ref() { NSDictionary *query = @{ // identities can't be filtered out using 'label', so we will use directly the ValueRef here: (id)kSecValueRef: (__bridge id)idnt, - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, }; ok_status(SecItemDelete((CFDictionaryRef)query)); is_status(SecItemCopyMatching((CFDictionaryRef)query, NULL), errSecItemNotFound); @@ -580,7 +580,7 @@ static void test_cssm_from_ios_key_single(CFTypeRef keyType, int keySize) { NSDictionary *params = @{ (id)kSecAttrKeyType: (__bridge id)keyType, (id)kSecAttrKeySizeInBits: @(keySize), - (id)kSecAttrNoLegacy: @YES, + (id)kSecUseDataProtectionKeychain: @YES, (id)kSecAttrIsPermanent: @NO, (id)kSecAttrLabel: @"sectests:cssm-from-ios-key", }; diff --git a/OSX/libsecurity_keychain/regressions/kc-45-change-password.c b/OSX/libsecurity_keychain/regressions/kc-45-change-password.c index c944f79c..90bebe9d 100644 --- a/OSX/libsecurity_keychain/regressions/kc-45-change-password.c +++ b/OSX/libsecurity_keychain/regressions/kc-45-change-password.c @@ -6,7 +6,7 @@ int kc_45_change_password(int argc, char *const *argv) { - plan_tests(14); + plan_tests(16); initializeKeychainTests(__FUNCTION__); @@ -14,12 +14,12 @@ int kc_45_change_password(int argc, char *const *argv) SecKeychainRef keychain = createNewKeychain("test", "before"); ok_status(SecKeychainLock(keychain), "SecKeychainLock"); - is_status(SecKeychainChangePassword(keychain, 0, NULL, 5, "after"), errSecAuthFailed, "Change PW w/ null pw while locked"); + is_status(SecKeychainChangePassword(keychain, 0, NULL, 5, "after"), errSecInteractionNotAllowed, "Change PW w/ null pw while locked"); // We're not responding to prompt so we can't do stuff while locked + checkPrompts(1, "Prompt to unlock keychain before password change"); is_status(SecKeychainChangePassword(keychain, 5, "badpw", 5, "after"), errSecAuthFailed, "Change PW w/ bad pw while locked"); ok_status(SecKeychainUnlock(keychain, 6, "before", true), "SecKeychainUnlock"); is_status(SecKeychainChangePassword(keychain, 0, NULL, 5, "after"), errSecAuthFailed, "Change PW w/ null pw while unlocked"); is_status(SecKeychainChangePassword(keychain, 5, "badpw", 5, "after"), errSecAuthFailed, "Change PW w/ bad pw while unlocked"); - ok_status(SecKeychainChangePassword(keychain, 6, "before", 7, "between"), "Change PW w/ good pw while unlocked"); ok_status(SecKeychainLock(keychain), "SecKeychainLock"); ok_status(SecKeychainChangePassword(keychain, 7, "between", 7, "after"), "Change PW w/ good pw while locked"); diff --git a/OSX/libsecurity_keychain/regressions/si-34-one-true-keychain.c b/OSX/libsecurity_keychain/regressions/si-34-one-true-keychain.c index 6422576b..ead0ca41 100644 --- a/OSX/libsecurity_keychain/regressions/si-34-one-true-keychain.c +++ b/OSX/libsecurity_keychain/regressions/si-34-one-true-keychain.c @@ -58,7 +58,7 @@ static void tests(void) CFMutableDictionaryRef syncAnyQuery = CFDictionaryCreateMutableCopy(NULL, 0, query); CFMutableDictionaryRef syncQuery = CFDictionaryCreateMutableCopy(NULL, 0, query); - CFDictionaryAddValue(noLegacyQuery, kSecAttrNoLegacy, kCFBooleanTrue); + CFDictionaryAddValue(noLegacyQuery, kSecUseDataProtectionKeychain, kCFBooleanTrue); CFDictionaryAddValue(syncAnyQuery, kSecAttrSynchronizable, kSecAttrSynchronizableAny); CFDictionaryAddValue(syncQuery, kSecAttrSynchronizable, kCFBooleanTrue); diff --git a/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.cpp b/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.cpp index 2725348c..f2e068bc 100644 --- a/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.cpp +++ b/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.cpp @@ -196,7 +196,7 @@ void P12SafeBag::copyAllAttrs( /* getters in CF terms - result is created and returned */ -CFStringRef P12SafeBag::friendlyName() +CFStringRef CF_RETURNS_RETAINED P12SafeBag::friendlyName() { if(mFriendlyName.Data == NULL) { /* not present, no error */ @@ -220,7 +220,7 @@ CFStringRef P12SafeBag::friendlyName() return cstr; } -CFDataRef P12SafeBag::localKeyId() +CFDataRef CF_RETURNS_RETAINED P12SafeBag::localKeyId() { if(mLocalKeyId.Data == NULL) { /* not present, no error */ diff --git a/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.h b/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.h index 7e5a45fe..b91089c8 100644 --- a/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.h +++ b/OSX/libsecurity_pkcs12/lib/pkcs12SafeBag.h @@ -68,8 +68,8 @@ public: ~P12SafeBag(); /* getters in CF terms - result is created and returned */ - CFStringRef friendlyName(); - CFDataRef localKeyId(); + CFStringRef CF_RETURNS_RETAINED friendlyName(); + CFDataRef CF_RETURNS_RETAINED localKeyId(); /* getters in CSSM_DATA terms - result is just a reference */ CSSM_DATA &friendlyNameCssm() { return mFriendlyName; } diff --git a/OSX/libsecurity_pkcs12/lib/pkcs12Utils.cpp b/OSX/libsecurity_pkcs12/lib/pkcs12Utils.cpp index ba1ea6f1..f7e20173 100644 --- a/OSX/libsecurity_pkcs12/lib/pkcs12Utils.cpp +++ b/OSX/libsecurity_pkcs12/lib/pkcs12Utils.cpp @@ -33,7 +33,6 @@ #include "pkcs12Debug.h" #include #include -#include #include #include #include @@ -483,9 +482,8 @@ void p12GenSalt( CSSM_DATA &salt, SecNssCoder &coder) { - DevRandomGenerator rng; coder.allocItem(salt, P12_SALT_LEN); - rng.random(salt.Data, P12_SALT_LEN); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, P12_SALT_LEN, salt.Data)); } /* @@ -498,8 +496,7 @@ void p12GenLabel( { /* first a random uint32 */ uint8 d[4]; - DevRandomGenerator rng; - rng.random(d, 4); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, 4, d)); CSSM_DATA cd = {4, d}; uint32 i; p12DataToInt(cd, i); diff --git a/OSX/libsecurity_smime/docs/libsecurity_smime.plist b/OSX/libsecurity_smime/docs/libsecurity_cms.plist similarity index 100% rename from OSX/libsecurity_smime/docs/libsecurity_smime.plist rename to OSX/libsecurity_smime/docs/libsecurity_cms.plist diff --git a/OSX/libsecurity_smime/docs/libsecurity_smime.txt b/OSX/libsecurity_smime/docs/libsecurity_cms.txt similarity index 100% rename from OSX/libsecurity_smime/docs/libsecurity_smime.txt rename to OSX/libsecurity_smime/docs/libsecurity_cms.txt diff --git a/OSX/libsecurity_smime/lib/SecCMS.c b/OSX/libsecurity_smime/lib/SecCMS.c index 53e74aac..d4e8f780 100644 --- a/OSX/libsecurity_smime/lib/SecCMS.c +++ b/OSX/libsecurity_smime/lib/SecCMS.c @@ -45,11 +45,12 @@ #include "cmstpriv.h" #include "cmspriv.h" -#include +#include CFTypeRef kSecCMSSignDigest = CFSTR("kSecCMSSignDigest"); CFTypeRef kSecCMSSignDetached = CFSTR("kSecCMSSignDetached"); CFTypeRef kSecCMSCertChainMode = CFSTR("kSecCMSCertChainMode"); +CFTypeRef kSecCMSCertChainModeNone = CFSTR("0"); CFTypeRef kSecCMSAdditionalCerts = CFSTR("kSecCMSAdditionalCerts"); CFTypeRef kSecCMSSignedAttributes = CFSTR("kSecCMSSignedAttributes"); CFTypeRef kSecCMSSignDate = CFSTR("kSecCMSSignDate"); @@ -63,6 +64,7 @@ CFTypeRef kSecCMSEncryptionAlgorithmDESCBC = CFSTR("kSecCMSEncryptionAlgorithmDE CFTypeRef kSecCMSEncryptionAlgorithmAESCBC = CFSTR("kSecCMSEncryptionAlgorithmAESCBC"); CFTypeRef kSecCMSSignHashAlgorithm = CFSTR("kSecCMSSignHashAlgorithm"); +CFTypeRef kSecCMSHashingAlgorithmMD5 = CFSTR("kSecCMSHashingAlgorithmMD5"); CFTypeRef kSecCMSHashingAlgorithmSHA1 = CFSTR("kSecCMSHashingAlgorithmSHA1"); CFTypeRef kSecCMSHashingAlgorithmSHA256 = CFSTR("kSecCMSHashingAlgorithmSHA256"); CFTypeRef kSecCMSHashingAlgorithmSHA384 = CFSTR("kSecCMSHashingAlgorithmSHA384"); @@ -409,7 +411,7 @@ static OSStatus SecCMSVerifySignedData_internal(CFDataRef message, CFDataRef det CFDateRef expiration_date = CFDateCreate(NULL, expiration_time); if (expiration_date) { CFDictionarySetValue(attrs, kSecCMSExpirationDate, expiration_date); - CFRetainSafe(expiration_date); + CFReleaseSafe(expiration_date); } } diff --git a/OSX/libsecurity_smime/lib/SecCMS.h b/OSX/libsecurity_smime/lib/SecCMS.h deleted file mode 100644 index 3f6fd394..00000000 --- a/OSX/libsecurity_smime/lib/SecCMS.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2014 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - - -#ifndef libsecurity_smime_SecCMS_h -#define libsecurity_smime_SecCMS_h - -#include -#include -#include - -extern const void * kSecCMSSignDigest; -extern const void * kSecCMSSignDetached; -extern const void * kSecCMSSignHashAlgorithm; -extern const void * kSecCMSCertChainMode; -extern const void * kSecCMSAdditionalCerts; -extern const void * kSecCMSSignedAttributes; -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; -extern const void * kSecCMSHashingAlgorithmSHA384; -extern const void * kSecCMSHashingAlgorithmSHA512; - -extern const void * kSecCMSBulkEncryptionAlgorithm; -extern const void * kSecCMSEncryptionAlgorithmDESCBC; -extern const void * kSecCMSEncryptionAlgorithmAESCBC; - -/* Return an array of certificates contained in message, if message is of the - type SignedData and has no signers, return NULL otherwise. Not that if - the message is properly formed but has no certificates an empty array will - be returned. - Designed to match the sec submodule implementation available for iOS - */ -CFArrayRef SecCMSCertificatesOnlyMessageCopyCertificates(CFDataRef message); - -/* Create a degenerate PKCS#7 containing a cert or a CFArray of certs. */ -CFDataRef SecCMSCreateCertificatesOnlyMessage(CFTypeRef cert_or_array_thereof); -CFDataRef SecCMSCreateCertificatesOnlyMessageIAP(SecCertificateRef cert); - -/*! - @function SecCMSVerifyCopyDataAndAttributes - @abstract verify a signed data cms blob. - @param message the cms message to be parsed - @param detached_contents to pass detached contents (optional) - @param policy specifies policy or array thereof should be used (optional). - if none is passed the blob will **not** be verified and only - the attached contents will be returned. - @param trustref (output/optional) if specified, the trust chain built during - verification will not be evaluated but returned to the caller to do so. - @param attached_contents (output/optional) return a copy of the attached - contents. - @param signed_attributes (output/optional) return a copy of the signed - attributes as a CFDictionary from oids (CFData) to values - (CFArray of CFData). - @result A result code. See "Security Error Codes" (SecBase.h). - errSecDecode not a CMS message we can parse, - errSecAuthFailed bad signature, or untrusted signer if caller doesn't - ask for trustref, - errSecParam garbage in, garbage out. - */ -OSStatus SecCMSVerifyCopyDataAndAttributes(CFDataRef message, CFDataRef detached_contents, - CFTypeRef policy, SecTrustRef *trustref, - CFDataRef *attached_contents, CFDictionaryRef *signed_attributes); - -/*! - @function SecCMSVerify - @abstract same as SecCMSVerifyCopyDataAndAttributes, for binary compatibility. - */ -OSStatus SecCMSVerify(CFDataRef message, CFDataRef detached_contents, - CFTypeRef policy, SecTrustRef *trustref, CFDataRef *attached_contents); - -OSStatus SecCMSVerifySignedData(CFDataRef message, CFDataRef detached_contents, - CFTypeRef policy, SecTrustRef *trustref, CFArrayRef additional_certificates, - CFDataRef *attached_contents, CFDictionaryRef *message_attributes); - -/*! - @function SecCMSSignDataAndAttributes - @abstract create a signed data cms blob. - @param identity signer - @param data message to be signed - @param detached sign detached or not - @param signed_data (output) return signed message. - @param signed_attributes (input/optional) signed attributes to insert - as a CFDictionary from oids (CFData) to value (CFData). - @result A result code. See "Security Error Codes" (SecBase.h). - errSecParam garbage in, garbage out. - */ -OSStatus SecCMSSignDataAndAttributes(SecIdentityRef identity, CFDataRef data, - bool detached, CFMutableDataRef signed_data, CFDictionaryRef signed_attributes); - -/*! - @function SecCMSSignDigestAndAttributes - @abstract create a detached signed data cms blob for a SHA-1 hash. - @param identity signer - @param digest SHA-1 digest of message to be signed - @param signed_data (output) return signed message. - @param signed_attributes (input/optional) signed attributes to insert - as a CFDictionary from oids (CFData) to value (CFData). - @result A result code. See "Security Error Codes" (SecBase.h). - errSecParam garbage in, garbage out. - */ -OSStatus SecCMSSignDigestAndAttributes(SecIdentityRef identity, CFDataRef digest, - CFMutableDataRef signed_data, CFDictionaryRef signed_attributes); - -/*! - @function SecCMSCreateSignedData - @abstract create a signed data cms blob. - @param identity signer - @param data SHA-1 digest or message to be signed - @param parameters (input/optional) specify algorithm, detached, digest - @param signed_attributes (input/optional) signed attributes to insert - as a CFDictionary from oids (CFData) to value (CFData). - @param signed_data (output) return signed message. - @result A result code. See "Security Error Codes" (SecBase.h). - errSecParam garbage in, garbage out. - */ -OSStatus SecCMSCreateSignedData(SecIdentityRef identity, CFDataRef data, - CFDictionaryRef parameters, CFDictionaryRef signed_attributes, - CFMutableDataRef signed_data); - -/*! - @function SecCMSCreateEnvelopedData - @abstract create a enveloped cms blob for recipients - @param recipient_or_cfarray_thereof SecCertificateRef for each recipient - @param params CFDictionaryRef with encryption parameters - @param data Data to be encrypted - @param enveloped_data (output) return enveloped message. - @result A result code. See "Security Error Codes" (SecBase.h). - errSecParam garbage in, garbage out. - */ -OSStatus SecCMSCreateEnvelopedData(CFTypeRef recipient_or_cfarray_thereof, - CFDictionaryRef params, CFDataRef data, CFMutableDataRef enveloped_data); - - -/*! - @function SecCMSDecryptEnvelopedData - @abstract open an enveloped cms blob. expects recipients identity in keychain. - @param message Eveloped message - @param data (output) return decrypted message. - @param recipient (output/optional) return addressed recipient - @result A result code. See "Security Error Codes" (SecBase.h). - errSecParam garbage in, garbage out. - */ -OSStatus SecCMSDecryptEnvelopedData(CFDataRef message, - CFMutableDataRef data, SecCertificateRef *recipient); - -#endif diff --git a/OSX/libsecurity_smime/lib/SecCmsContentInfo.h b/OSX/libsecurity_smime/lib/SecCmsContentInfo.h deleted file mode 100644 index ecc223cf..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsContentInfo.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2004,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@ - */ - -/*! - @header SecCmsContentInfo.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for creating and - accessing ContentInfo objects that are part of Cryptographic - Message Syntax (CMS) objects as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSCONTENTINFO_H_ -#define _SECURITY_SECCMSCONTENTINFO_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! @functiongroup ContentInfo accessors */ -/*! - @function - @abstract Get content's contentInfo (if it exists). - @param cinfo A ContentInfo object of which we want to get the child contentInfo. - @result The child ContentInfo object, or NULL if there is none. - @discussion This function requires a ContentInfo object which is usually created by decoding and SecCmsMessage using a SecCmsDecoder. - @availability 10.4 and later - */ -extern SecCmsContentInfoRef -SecCmsContentInfoGetChildContentInfo(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Get pointer to inner content - @discussion needs to be casted... - */ -extern void * -SecCmsContentInfoGetContent(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Get pointer to innermost content - @discussion This is typically only called by SecCmsMessageGetContent(). - */ -extern CSSM_DATA_PTR -SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Find out and return the inner content type. - */ -extern SECOidTag -SecCmsContentInfoGetContentTypeTag(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Find out and return the inner content type. - @discussion Caches pointer to lookup result for future reference. - */ -extern CSSM_OID * -SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Find out and return the content encryption algorithm tag. - */ -extern SECOidTag -SecCmsContentInfoGetContentEncAlgTag(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Find out and return the content encryption algorithm. - @discussion Caches pointer to lookup result for future reference. - */ -extern SECAlgorithmID * -SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -/*! @functiongroup Message construction */ -/*! - @function - @abstract Set a ContentInfos content to a Data - @param cmsg A Message object to which the cinfo object belongs. - @param cinfo A ContentInfo object of which we want set the content. - @param data A pointer to a CSSM_DATA object or NULL if data will be provided during SecCmsEncoderUpdate calls. - @param detached True if the content is to be deattched from the CMS message rather than included within it. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object. If the call succeeds the passed in data will be owned by the reciever. The data->Data must have been allocated using the cmsg's SecArenaPool if it is present. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, CSSM_DATA_PTR data, Boolean detached) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Set a ContentInfos content to a SignedData. - @param cmsg A Message object to which the cinfo object belongs. - @param cinfo A ContentInfo object of which we want set the content. - @param sigd A SignedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a SignedData which can be made by calling SecCmsSignedDataCreate(). If the call succeeds the passed in SignedData object will be owned by the reciever. The Message object of the SignedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentSignedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsSignedDataRef sigd); - -/*! - @function - @abstract Set a ContentInfos content to a EnvelopedData. - @param cmsg A Message object to which the cinfo object belongs. - @param cinfo A ContentInfo object of which we want set the content. - @param envd A EnvelopedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EnvelopedData which can be made by calling SecCmsEnvelopedDataCreate(). If the call succeeds the passed in EnvelopedData object will be owned by the reciever. The Message object of the EnvelopedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentEnvelopedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsEnvelopedDataRef envd); - -/*! - @function - @abstract Set a ContentInfos content to a DigestedData. - @param cmsg A Message object to which the cinfo object belongs. - @param cinfo A ContentInfo object of which we want set the content. - @param digd A DigestedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a DigestedData which can be made by calling SecCmsDigestedDataCreate(). If the call succeeds the passed in DigestedData object will be owned by the reciever. The Message object of the DigestedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentDigestedData(SecCmsMessageRef cmsg, SecCmsContentInfoRef cinfo, SecCmsDigestedDataRef digd); - -/*! - @function - @abstract Set a ContentInfos content to a EncryptedData. - @param cmsg A Message object to which the cinfo object belongs. - @param cinfo A ContentInfo object of which we want set the content. - @param encd A EncryptedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EncryptedData which can be made by calling SecCmsEncryptedDataCreate(). If the call succeeds the passed in EncryptedData object will be owned by the reciever. The Message object of the EncryptedData object must be the same as cmsg. - @availability 10.4 and later - */ -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) 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) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - */ -extern OSStatus -SecCmsContentInfoSetContentEncAlgID(SecArenaPoolRef pool, SecCmsContentInfoRef cinfo, - SECAlgorithmID *algid, int keysize) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - */ -extern void -SecCmsContentInfoSetBulkKey(SecCmsContentInfoRef cinfo, SecSymmetricKeyRef bulkkey); - -/*! - @function - */ -extern SecSymmetricKeyRef -SecCmsContentInfoGetBulkKey(SecCmsContentInfoRef cinfo); - -/*! - @function - */ -extern int -SecCmsContentInfoGetBulkKeySize(SecCmsContentInfoRef cinfo); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSCONTENTINFO_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsDecoder.h b/OSX/libsecurity_smime/lib/SecCmsDecoder.h deleted file mode 100644 index 81efbf57..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsDecoder.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2004,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@ - */ - -/*! - @header SecCmsDecoder.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSDECODER_H_ -#define _SECURITY_SECCMSDECODER_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! @functiongroup Streaming interface */ -/*! - @function - @abstract Set up decoding of a BER-encoded CMS message. - @param arena An ArenaPool object to use for the resulting message, or NULL if new ArenaPool - should be created. - @param cb callback function for delivery of inner content inner - content will be stored in the message if cb is NULL. - @param cb_arg first argument passed to cb when it is called. - @param pwfn callback function for getting token password for - enveloped data content with a password recipient. - @param pwfn_arg first argument passed to pwfn when it is called. - @param decrypt_key_cb callback function for getting bulk key - for encryptedData content. - @param decrypt_key_cb_arg first argument passed to decrypt_key_cb - when it is called. - @param outDecoder On success will contain a pointer to a newly created SecCmsDecoder. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion Create a SecCmsDecoder(). If this function returns noErr, the caller must dispose of the returned outDecoder by calling SecCmsDecoderDestroy() or SecCmsDecoderFinish(). - @availability 10.4 and later - @updated 2004-04-05 - */ -extern OSStatus -SecCmsDecoderCreate(SecArenaPoolRef arena, - SecCmsContentCallback cb, void *cb_arg, - PK11PasswordFunc pwfn, void *pwfn_arg, - SecCmsGetDecryptKeyCallback decrypt_key_cb, void - *decrypt_key_cb_arg, - SecCmsDecoderRef *outDecoder) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Feed BER-encoded data to decoder. - @param decoder Pointer to a SecCmsDecoderContext created with SecCmsDecoderCreate(). - @param buf Pointer to bytes to be decoded. - @param len number of bytes to decode. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion If a call to this function fails the caller should call SecCmsDecoderDestroy(). - @availability 10.4 and later - */ -extern OSStatus -SecCmsDecoderUpdate(SecCmsDecoderRef decoder, const void *buf, CFIndex len); - -/*! - @function - @abstract Abort a (presumably failed) decoding process. - @param decoder Pointer to a SecCmsDecoderContext created with SecCmsDecoderCreate(). - @availability 10.4 and later - */ -extern void -SecCmsDecoderDestroy(SecCmsDecoderRef decoder); - -/*! - @function - @abstract Mark the end of inner content and finish decoding. - @param decoder Pointer to a SecCmsDecoderContext created with SecCmsDecoderCreate(). - @param outMessage On success a pointer to a SecCmsMessage containing the decoded message. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion decoder is no longer valid after this function is called. - @availability 10.4 and later - */ -extern OSStatus -SecCmsDecoderFinish(SecCmsDecoderRef decoder, SecCmsMessageRef *outMessage); - -/*! @functiongroup One shot interface */ -/*! - @function - @abstract Decode a CMS message from BER encoded data. - @discussion This function basically does the same as calling - SecCmsDecoderStart(), SecCmsDecoderUpdate() and SecCmsDecoderFinish(). - @param encodedMessage Pointer to a CSSM_DATA containing the BER encoded cms - message to decode. - @param cb callback function for delivery of inner content inner - content will be stored in the message if cb is NULL. - @param cb_arg first argument passed to cb when it is called. - @param pwfn callback function for getting token password for enveloped - data content with a password recipient. - @param pwfn_arg first argument passed to pwfn when it is called. - @param decrypt_key_cb callback function for getting bulk key for encryptedData content. - @param decrypt_key_cb_arg first argument passed to decrypt_key_cb when it is called. - @param outMessage On success a pointer to a SecCmsMessage containing the decoded message. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion decoder is no longer valid after this function is called. - @availability 10.4 and later - */ -extern OSStatus -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) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSDECODER_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsDigestContext.h b/OSX/libsecurity_smime/lib/SecCmsDigestContext.h deleted file mode 100644 index a51626d0..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsDigestContext.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2004,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@ - */ - -/*! - @header SecCmsDigestContext.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions calculating digests. - */ - -#ifndef _SECURITY_SECCMSDIGESTCONTEXT_H_ -#define _SECURITY_SECCMSDIGESTCONTEXT_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! - @function - @abstract Start digest calculation using all the digest algorithms in "digestalgs" in parallel. - */ -extern SecCmsDigestContextRef -SecCmsDigestContextStartMultiple(SECAlgorithmID **digestalgs) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Feed more data into the digest machine. - */ -extern void -SecCmsDigestContextUpdate(SecCmsDigestContextRef cmsdigcx, const unsigned char *data, size_t len); - -/*! - @function - @abstract Cancel digesting operation. - @discussion Cancel a DigestContext created with @link SecCmsDigestContextStartMultiple SecCmsDigestContextStartMultiple function@/link. - */ -extern void -SecCmsDigestContextCancel(SecCmsDigestContextRef cmsdigcx); - -/*! - @function - @abstract Finish the digests and put them into an array of CSSM_DATAs (allocated on arena) - */ -extern OSStatus -SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, SecArenaPoolRef arena, - CSSM_DATA_PTR **digestsp) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSDIGESTCONTEXT_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsEncoder.h b/OSX/libsecurity_smime/lib/SecCmsEncoder.h deleted file mode 100644 index a8b43263..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsEncoder.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2004,2011-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@ - */ - -/*! - @header SecCmsEncoder.h - @Copyright (c) 2004,2011-2012,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract CMS message encoding - @discussion The functions here implement functions for encoding - Cryptographic Message Syntax (CMS) objects as described - in rfc3369. - A SecCmsEncoder object is used to encode CMS messages into BER. - */ - -#ifndef _SECURITY_SECCMSENCODER_H_ -#define _SECURITY_SECCMSENCODER_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! @functiongroup Streaming interface */ -/*! - @function - @abstract Set up encoding of a CMS message. - @param outputfn callback function for delivery of BER-encoded output will - not be called if NULL. - @param outputarg first argument passed to outputfn when it is called. - @param dest If non-NULL, pointer to a CSSM_DATA that will hold the - BER-encoded output. - @param destpoolp Pool to allocate BER-encoded output in. - @param pwfn callback function for getting token password for enveloped - data content with a password recipient. - @param pwfn_arg first argument passed to pwfn when it is called. - @param encrypt_key_cb callback function for getting bulk key for encryptedData content. - @param encrypt_key_cb_arg first argument passed to encrypt_key_cb when it is - called. - @param detached_digestalgs digest algorithms in detached_digests - @param detached_digests digests from detached content (one for every element - in detached_digestalgs). - @result On success a pointer to a SecCmsMessage containing the decoded message - is returned. On failure returns NULL. Call PR_GetError() to find out what - went wrong in this case. - @availability 10.4 and later - */ -extern OSStatus -SecCmsEncoderCreate(SecCmsMessageRef cmsg, - SecCmsContentCallback outputfn, void *outputarg, - CSSM_DATA_PTR dest, SecArenaPoolRef destpoolp, - PK11PasswordFunc pwfn, void *pwfn_arg, - SecCmsGetDecryptKeyCallback encrypt_key_cb, void *encrypt_key_cb_arg, - SECAlgorithmID **detached_digestalgs, CSSM_DATA_PTR *detached_digests, - SecCmsEncoderRef *outEncoder) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Take content data delivery from the user - @param encoder encoder context - @param data content data - @param len length of content data - @result On success 0 is returned. On failure returns non zero. Call - PR_GetError() to find out what went wrong in this case. - @availability 10.4 and later - */ -extern OSStatus -SecCmsEncoderUpdate(SecCmsEncoderRef encoder, const void *data, CFIndex len); - -/*! - @function - @abstract Abort a (presumably failed) encoding process. - @param encoder Pointer to a SecCmsEncoderContext created with SecCmsEncoderCreate(). - @availability 10.4 and later - */ -extern void -SecCmsEncoderDestroy(SecCmsEncoderRef encoder); - -/*! - @function - @abstract Signal the end of data. - @discussion Walks down the chain of encoders and the finishes them from the - innermost out. - @param encoder Pointer to a SecCmsEncoder created with SecCmsEncoderCreate(). - @result On success 0 is returned. On failure returns non zero. Call - PR_GetError() to find out what went wrong in this case. - @availability 10.4 and later - */ -extern OSStatus -SecCmsEncoderFinish(SecCmsEncoderRef encoder); - -/*! @functiongroup One shot interface */ -/*! - @function - @abstract BER Encode a CMS message. - @discussion BER Encode a CMS message, with input being the plaintext message and outBer being the output, stored in arena's pool. - */ -extern OSStatus -SecCmsMessageEncode(SecCmsMessageRef cmsg, const CSSM_DATA *input, SecArenaPoolRef arena, - CSSM_DATA_PTR outBer) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSENCODER_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsEncryptedData.h b/OSX/libsecurity_smime/lib/SecCmsEncryptedData.h deleted file mode 100644 index 84ada6c8..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsEncryptedData.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2004,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@ - */ - -/*! - @header SecCmsEnvelopedData.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSENCRYPTEDDATA_H_ -#define _SECURITY_SECCMSENCRYPTEDDATA_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! - @function - @abstract Create an empty EncryptedData object. - @param algorithm Specifies the bulk encryption algorithm to use. - @param keysize is the key size. - @discussion An error results in a return value of NULL and an error set. - (Retrieve specific errors via PORT_GetError()/XP_GetError().) - */ -extern SecCmsEncryptedDataRef -SecCmsEncryptedDataCreate(SecCmsMessageRef cmsg, SECOidTag algorithm, int keysize); - -/*! - @function - @abstract Destroy an encryptedData object. - */ -extern void -SecCmsEncryptedDataDestroy(SecCmsEncryptedDataRef encd); - -/*! - @function - @abstract Return pointer to an EncryptedData object's contentInfo. - */ -extern SecCmsContentInfoRef -SecCmsEncryptedDataGetContentInfo(SecCmsEncryptedDataRef encd); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSENCRYPTEDDATA_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h b/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h deleted file mode 100644 index 6661e7da..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2004,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@ - */ - -/*! - @header SecCmsRecipientInfo.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSRECIPIENTINFO_H_ -#define _SECURITY_SECCMSRECIPIENTINFO_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! - @function - @abstract Create a recipientinfo - @discussion We currently do not create KeyAgreement recipientinfos with multiple recipientEncryptedKeys - the certificate is supposed to have been verified by the caller - */ -extern SecCmsRecipientInfoRef -SecCmsRecipientInfoCreate(SecCmsMessageRef cmsg, SecCertificateRef cert); - -/*! - @function - */ -extern SecCmsRecipientInfoRef -SecCmsRecipientInfoCreateWithSubjKeyID(SecCmsMessageRef cmsg, - CSSM_DATA_PTR subjKeyID, - SecPublicKeyRef pubKey) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - */ -extern SecCmsRecipientInfoRef -SecCmsRecipientInfoCreateWithSubjKeyIDFromCert(SecCmsMessageRef cmsg, - SecCertificateRef cert); - -/*! - @function - */ -extern void -SecCmsRecipientInfoDestroy(SecCmsRecipientInfoRef ri); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSRECIPIENTINFO_H_ */ diff --git a/OSX/libsecurity_smime/lib/SecCmsSignedData.h b/OSX/libsecurity_smime/lib/SecCmsSignedData.h deleted file mode 100644 index a5d9f5b9..00000000 --- a/OSX/libsecurity_smime/lib/SecCmsSignedData.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2004,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@ - */ - -/*! - @header SecCmsSignedData.h - @Copyright (c) 2004,2011,2014 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSSIGNEDDATA_H_ -#define _SECURITY_SECCMSSIGNEDDATA_H_ 1 - -#include -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - @function - @abstract Create a new SecCmsSignedData object. - @param cmsg Pointer to a SecCmsMessage in which this SecCmsSignedData - should be created. - */ -extern SecCmsSignedDataRef -SecCmsSignedDataCreate(SecCmsMessageRef cmsg); - -/*! - @function - */ -extern void -SecCmsSignedDataDestroy(SecCmsSignedDataRef sigd); - -/*! - @function - @abstract Retrieve the SignedData's signer list. - */ -extern SecCmsSignerInfoRef * -SecCmsSignedDataGetSignerInfos(SecCmsSignedDataRef sigd); - -/*! - @function - */ -extern int -SecCmsSignedDataSignerInfoCount(SecCmsSignedDataRef sigd); - -/*! - @function - */ -extern SecCmsSignerInfoRef -SecCmsSignedDataGetSignerInfo(SecCmsSignedDataRef sigd, int i); - -/*! - @function - @abstract Retrieve the SignedData's digest algorithm list. - */ -extern SECAlgorithmID ** -SecCmsSignedDataGetDigestAlgs(SecCmsSignedDataRef sigd) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Return pointer to this signedData's contentinfo. - */ -extern SecCmsContentInfoRef -SecCmsSignedDataGetContentInfo(SecCmsSignedDataRef sigd); - -/*! - @function - @discussion XXX Should be obsoleted. - */ -extern OSStatus -SecCmsSignedDataImportCerts(SecCmsSignedDataRef sigd, SecKeychainRef keychain, - SECCertUsage certusage, Boolean keepcerts); - -/*! - @function - @abstract See if we have digests in place. - */ -extern Boolean -SecCmsSignedDataHasDigests(SecCmsSignedDataRef sigd); - -/*! - @function - @abstract Check the signatures. - @discussion The digests were either calculated during decoding (and are stored in the - signedData itself) or set after decoding using SecCmsSignedDataSetDigests. - - The verification checks if the signing cert is valid and has a trusted chain - for the purpose specified by "policies". - - If trustRef is NULL the cert chain is verified and the VerificationStatus is set accordingly. - Otherwise a SecTrust object is returned for the caller to evaluate using SecTrustEvaluate(). - */ -extern OSStatus -SecCmsSignedDataVerifySignerInfo(SecCmsSignedDataRef sigd, int i, SecKeychainRef keychainOrArray, - CFTypeRef policies, SecTrustRef *trustRef); - -/*! - @function - @abstract Verify the certs in a certs-only message. -*/ -extern OSStatus -SecCmsSignedDataVerifyCertsOnly(SecCmsSignedDataRef sigd, - SecKeychainRef keychainOrArray, - CFTypeRef policies); - -/*! - @function - */ -extern OSStatus -SecCmsSignedDataAddCertList(SecCmsSignedDataRef sigd, CFArrayRef certlist); - -/*! - @function - @abstract Add cert and its entire chain to the set of certs. - */ -extern OSStatus -SecCmsSignedDataAddCertChain(SecCmsSignedDataRef sigd, SecCertificateRef cert); - -/*! - @function - */ -extern OSStatus -SecCmsSignedDataAddCertificate(SecCmsSignedDataRef sigd, SecCertificateRef cert); - -/*! - @function - */ -extern Boolean -SecCmsSignedDataContainsCertsOrCrls(SecCmsSignedDataRef sigd); - -/*! - @function - @abstract Retrieve the SignedData's certificate list. - */ -extern CSSM_DATA_PTR * -SecCmsSignedDataGetCertificateList(SecCmsSignedDataRef sigd) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - */ -extern OSStatus -SecCmsSignedDataAddSignerInfo(SecCmsSignedDataRef sigd, - SecCmsSignerInfoRef signerinfo); - -/*! - @function - */ -extern OSStatus -SecCmsSignedDataSetDigests(SecCmsSignedDataRef sigd, - SECAlgorithmID **digestalgs, - CSSM_DATA_PTR *digests) DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; - -/*! - @function - @abstract Create a certs-only SignedData. - @param cert Base certificate that will be included - @param include_chain If true, include the complete cert chain for cert. - @discussion More certs and chains can be added via AddCertificate and AddCertChain. - @result An error results in a return value of NULL and an error set. - */ -extern SecCmsSignedDataRef -SecCmsSignedDataCreateCertsOnly(SecCmsMessageRef cmsg, SecCertificateRef cert, Boolean include_chain); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSSIGNEDDATA_H_ */ diff --git a/OSX/libsecurity_smime/lib/cert.c b/OSX/libsecurity_smime/lib/cert.c index 2f3bc4ae..8c99fef3 100644 --- a/OSX/libsecurity_smime/lib/cert.c +++ b/OSX/libsecurity_smime/lib/cert.c @@ -242,32 +242,36 @@ PublicKeyHash, kSecPublicKeyHashItemAttr, "PublicKeyHash", 0, NULL, BLOB) endNewClass() */ -CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot) +CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot, Boolean mustIncludeRoot) { SecPolicyRef policy = NULL; CFArrayRef wrappedCert = NULL; SecTrustRef trust = NULL; CFMutableArrayRef certs = NULL; OSStatus status = 0; - SecTrustResultType trustResult = kSecTrustResultInvalid; - if (!cert) - goto loser; + if (!cert) { + goto loser; + } policy = SecPolicyCreateBasicX509(); - if (!policy) + if (!policy) { goto loser; + } wrappedCert = CERT_CertListFromCert(cert); status = SecTrustCreateWithCertificates(wrappedCert, policy, &trust); - if (status) - goto loser; + if (status) { + goto loser; + } /* SecTrustEvaluate will build us the best chain available using its heuristics. * We'll ignore the trust result. */ - status = SecTrustEvaluate(trust, &trustResult); - if (status) - goto loser; + SecTrustResultType result; + status = SecTrustEvaluate(trust, &result); + if (status) { + goto loser; + } CFIndex idx, count = SecTrustGetCertificateCount(trust); /* If we weren't able to build a chain to a self-signed cert, warn. */ @@ -276,29 +280,33 @@ CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Bo if (lastCert && (0 == SecCertificateIsSelfSigned(lastCert, &isSelfSigned)) && !isSelfSigned) { CFStringRef commonName = NULL; (void)SecCertificateCopyCommonName(cert, &commonName); - fprintf(stderr, "Warning: unable to build chain to self-signed root for signer \"%s\"", + fprintf(stderr, "Warning: unable to build chain to self-signed root for signer \"%s\"\n", commonName ? CFStringGetCStringPtr(commonName, kCFStringEncodingUTF8) : ""); if (commonName) { CFRelease(commonName); } + + // we don't have a root, so if the caller required one, fail + if (mustIncludeRoot) { + status = errSecCreateChainFailed; + } } /* We don't drop the root if there is only 1 certificate in the chain. */ - if (!includeRoot && count > 1) { count--; } + if (isSelfSigned && !includeRoot && count > 1) { + count--; + } certs = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); - for(idx = 0; idx < count; idx++) + for(idx = 0; idx < count; idx++) { CFArrayAppendValue(certs, SecTrustGetCertificateAtIndex(trust, idx)); + } loser: - if (policy) - CFRelease(policy); - if (wrappedCert) - CFRelease(wrappedCert); - if (trust) - CFRelease(trust); - if (certs && status) - { - CFRelease(certs); - certs = NULL; + if (policy) { CFRelease(policy); } + if (wrappedCert) { CFRelease(wrappedCert); } + if (trust) { CFRelease(trust); } + if (certs && status) { + CFRelease(certs); + certs = NULL; } return certs; @@ -444,7 +452,7 @@ SecCertificateRef CERT_FindCertByIssuerAndSN (CFTypeRef keychainOrArray, SecCertificateRef CERT_FindCertBySubjectKeyID (CFTypeRef keychainOrArray, CSSM_DATA_PTR *rawCerts, CFArrayRef certList, const SECItem *subjKeyID) { - SecCertificateRef certificate; + SecCertificateRef certificate = NULL; int numRawCerts = SecCmsArrayCount((void **)rawCerts); int dex; OSStatus ortn; @@ -575,7 +583,7 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce SecCmsIssuerAndSN *certIssuerAndSN; SecCertificateRef certRef; SecCertificateRef itemImplRef = NULL; - CSSM_CL_HANDLE clHandle; + CSSM_CL_HANDLE clHandle = 0; CSSM_DATA_PTR serialNumber = 0; CSSM_DATA_PTR issuer = 0; CSSM_DATA certData = {}; @@ -588,9 +596,9 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce /* Retain input cert and get pointer to its data */ certRef = (SecCertificateRef)((cert) ? CFRetain(cert) : NULL); - status = SecCertificateGetData(certRef, &certData); - if (status) + if (!certRef || SecCertificateGetData(certRef, &certData)) { goto loser; + } #if 1 // Convert unified input certRef to itemImpl instance. // note: must not release this instance while we're using its CL handle! diff --git a/OSX/libsecurity_smime/lib/cert.h b/OSX/libsecurity_smime/lib/cert.h index 74d88af0..fa1d785b 100644 --- a/OSX/libsecurity_smime/lib/cert.h +++ b/OSX/libsecurity_smime/lib/cert.h @@ -50,7 +50,7 @@ SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef dbhandle, SecCertificateRef CERT_FindCertByNicknameOrEmailAddr(SecKeychainRef dbhandle, char *name); SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey); -void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey); +void SECKEY_DestroyPublicKey(SecPublicKeyRef CF_CONSUMED pubKey); SecPublicKeyRef SECKEY_CopyPrivateKey(SecPublicKeyRef privKey); void SECKEY_DestroyPrivateKey(SecPublicKeyRef privKey); void CERT_DestroyCertificate(SecCertificateRef cert); @@ -69,14 +69,14 @@ SecCertificateRef CERT_DupCertificate(SecCertificateRef cert); // Generate a certificate chain from a certificate. -CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage,Boolean includeRoot); +CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage,Boolean includeRoot, Boolean mustIncludeRoot); -CFArrayRef CERT_CertListFromCert(SecCertificateRef cert); +CF_RETURNS_RETAINED CFArrayRef CERT_CertListFromCert(SecCertificateRef cert); -CFArrayRef CERT_DupCertList(CFArrayRef oldList); +CF_RETURNS_RETAINED CFArrayRef CERT_DupCertList(CFArrayRef oldList); // Extract a public key object from a SubjectPublicKeyInfo -SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert); +CF_RETURNS_RETAINED SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert); SECStatus CERT_CheckCertUsage (SecCertificateRef cert,unsigned char usage); @@ -125,7 +125,7 @@ SECStatus CERT_VerifyCert(SecKeychainRef keychainOrArray, SecCertificateRef cert const CSSM_DATA_PTR *otherCerts, /* intermediates */ CFTypeRef policies, CFAbsoluteTime stime, SecTrustRef *trustRef); -CFTypeRef CERT_PolicyForCertUsage(SECCertUsage certUsage); +CF_RETURNS_RETAINED CFTypeRef CERT_PolicyForCertUsage(SECCertUsage certUsage); int CERT_CompareCssmData(const CSSM_DATA *d1, const CSSM_DATA *d2); diff --git a/OSX/libsecurity_smime/lib/cmsattr.c b/OSX/libsecurity_smime/lib/cmsattr.c index 8497904b..9730fa19 100644 --- a/OSX/libsecurity_smime/lib/cmsattr.c +++ b/OSX/libsecurity_smime/lib/cmsattr.c @@ -127,6 +127,8 @@ SecCmsAttributeAddValue(PLArenaPool *poolp, SecCmsAttribute *attr, CSSM_DATA_PTR if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) goto loser; + + SecCmsArraySort((void **)(attr->values), SecCmsUtilDERCompare, NULL, NULL); } PORT_ArenaUnmark(poolp, mark); diff --git a/OSX/libsecurity_smime/lib/cmscinfo.c b/OSX/libsecurity_smime/lib/cmscinfo.c index e7fecb2c..1850d4d5 100644 --- a/OSX/libsecurity_smime/lib/cmscinfo.c +++ b/OSX/libsecurity_smime/lib/cmscinfo.c @@ -254,9 +254,9 @@ SecCmsContentInfoSetContentOther(SecCmsMessageRef cmsg, SecCmsContentInfoRef cin void * SecCmsContentInfoGetContent(SecCmsContentInfoRef cinfo) { - SECOidTag tag = (cinfo && cinfo->contentTypeTag) - ? cinfo->contentTypeTag->offset - : cinfo->contentType.Data ? SEC_OID_OTHER : SEC_OID_UNKNOWN; + if (!cinfo) { return NULL; } + SECOidTag tag = (cinfo->contentTypeTag) ? cinfo->contentTypeTag->offset + : ( cinfo->contentType.Data ? SEC_OID_OTHER : SEC_OID_UNKNOWN); switch (tag) { case SEC_OID_PKCS7_DATA: case SEC_OID_PKCS7_SIGNED_DATA: diff --git a/OSX/libsecurity_smime/lib/cmscipher.c b/OSX/libsecurity_smime/lib/cmscipher.c index a0016873..d511920a 100644 --- a/OSX/libsecurity_smime/lib/cmscipher.c +++ b/OSX/libsecurity_smime/lib/cmscipher.c @@ -102,9 +102,11 @@ DER_GetInteger(SECItem *it) unsigned char *cp = it->Data; unsigned long overflow = 0x1ffUL << (((sizeof(ival) - 1) * 8) - 1); unsigned long ofloinit; + bool isNegative = false; - if (*cp & 0x80) - ival = -1L; + if (*cp & 0x80) { + isNegative = true; + } ofloinit = ival & overflow; while (len) { @@ -119,6 +121,10 @@ DER_GetInteger(SECItem *it) ival |= *cp++; --len; } + + if (isNegative) { + ival *= -1L; + } return ival; } diff --git a/OSX/libsecurity_smime/lib/cmsdecode.c b/OSX/libsecurity_smime/lib/cmsdecode.c index fdc69f3f..e8c9b28c 100644 --- a/OSX/libsecurity_smime/lib/cmsdecode.c +++ b/OSX/libsecurity_smime/lib/cmsdecode.c @@ -436,77 +436,77 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx, if (!p7dcx->content.pointer) // might be ExContent?? return; - + cinfo = SecCmsContentGetContentInfo(p7dcx->content.pointer, p7dcx->type); if (cinfo->ciphcx != NULL) { - /* - * we are decrypting. - * - * XXX If we get an error, we do not want to do the digest or callback, - * but we want to keep decoding. Or maybe we want to stop decoding - * altogether if there is a callback, because obviously we are not - * sending the data back and they want to know that. - */ - - CSSM_SIZE outlen = 0; /* length of decrypted data */ - CSSM_SIZE buflen; /* length available for decrypted data */ - - /* find out about the length of decrypted data */ - buflen = SecCmsCipherContextDecryptLength(cinfo->ciphcx, len, final); - - /* - * it might happen that we did not provide enough data for a full - * block (decryption unit), and that there is no output available - */ - - /* no output available, AND no input? */ - if (buflen == 0 && len == 0) - goto loser; /* bail out */ - - /* - * have inner decoder: pass the data on (means inner content type is NOT data) - * no inner decoder: we have DATA in here: either call callback or store - */ - if (buflen != 0) { - /* there will be some output - need to make room for it */ - /* allocate buffer from the heap */ - buf = (unsigned char *)PORT_Alloc(buflen); - if (buf == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } - } + /* + * we are decrypting. + * + * XXX If we get an error, we do not want to do the digest or callback, + * but we want to keep decoding. Or maybe we want to stop decoding + * altogether if there is a callback, because obviously we are not + * sending the data back and they want to know that. + */ + + CSSM_SIZE outlen = 0; /* length of decrypted data */ + CSSM_SIZE buflen; /* length available for decrypted data */ + + /* find out about the length of decrypted data */ + buflen = SecCmsCipherContextDecryptLength(cinfo->ciphcx, len, final); + + /* + * it might happen that we did not provide enough data for a full + * block (decryption unit), and that there is no output available + */ + + /* no output available, AND no input? */ + if (buflen == 0 && len == 0) + goto loser; /* bail out */ + + /* + * have inner decoder: pass the data on (means inner content type is NOT data) + * no inner decoder: we have DATA in here: either call callback or store + */ + if (buflen != 0) { + /* there will be some output - need to make room for it */ + /* allocate buffer from the heap */ + buf = (unsigned char *)PORT_Alloc(buflen); + if (buf == NULL) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } + } - /* - * decrypt incoming data - * buf can still be NULL here (and buflen == 0) here if we don't expect - * any output (see above), but we still need to call SecCmsCipherContextDecrypt to - * keep track of incoming data - */ - rv = SecCmsCipherContextDecrypt(cinfo->ciphcx, buf, &outlen, buflen, - data, len, final); - if (rv != SECSuccess) { - p7dcx->error = PORT_GetError(); + /* + * decrypt incoming data + * buf can still be NULL here (and buflen == 0) here if we don't expect + * any output (see above), but we still need to call SecCmsCipherContextDecrypt to + * keep track of incoming data + */ + rv = SecCmsCipherContextDecrypt(cinfo->ciphcx, buf, &outlen, buflen, + data, len, final); + if (rv != SECSuccess) { + p7dcx->error = PORT_GetError(); PORT_SetError(0); // Clean the thread error since we've returned the error - goto loser; - } + goto loser; + } + + PORT_Assert (final || outlen == buflen); - PORT_Assert (final || outlen == buflen); - - /* swap decrypted data in */ - data = buf; - len = outlen; + /* swap decrypted data in */ + data = buf; + len = outlen; } if (len == 0) - goto done; /* nothing more to do */ + goto done; /* nothing more to do */ /* * Update the running digests with plaintext bytes (if we need to). */ if (cinfo->digcx) - SecCmsDigestContextUpdate(cinfo->digcx, data, len); + SecCmsDigestContextUpdate(cinfo->digcx, data, len); /* at this point, we have the plain decoded & decrypted data */ /* which is either more encoded DER which we need to hand to the child decoder */ @@ -515,52 +515,54 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx, /* pass the content back to our caller or */ /* feed our freshly decrypted and decoded data into child decoder */ if (p7dcx->cb != NULL) { - (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len); + (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len); } #if 1 else #endif - switch(SecCmsContentInfoGetContentTypeTag(cinfo)) { - default: - break; - case SEC_OID_PKCS7_DATA: - case SEC_OID_OTHER: - /* store it in "inner" data item as well */ - /* find the DATA item in the encapsulated cinfo and store it there */ - storage = cinfo->content.data; - - offset = storage->Length; - - /* check for potential overflow */ - if (len >= (size_t)(INT_MAX - storage->Length)) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } - - if (storage->Length == 0) { - dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len); - } else { - dest = (unsigned char *)PORT_ArenaGrow(p7dcx->cmsg->poolp, - storage->Data, - storage->Length, - storage->Length + len); - } - if (dest == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } - - storage->Data = dest; - storage->Length += len; - - /* copy it in */ - PORT_Memcpy(storage->Data + offset, data, len); - } + switch(SecCmsContentInfoGetContentTypeTag(cinfo)) { + default: + break; + case SEC_OID_PKCS7_DATA: + case SEC_OID_OTHER: + /* store it in "inner" data item as well */ + /* find the DATA item in the encapsulated cinfo and store it there */ + storage = cinfo->content.data; + + offset = storage->Length; + + /* check for potential overflow */ + if (len >= (size_t)(INT_MAX - storage->Length)) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } + + if (storage->Length == 0) { + dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len); + } else { + dest = (unsigned char *)PORT_ArenaGrow(p7dcx->cmsg->poolp, + storage->Data, + storage->Length, + storage->Length + len); + } + if (dest == NULL) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } + + storage->Data = dest; + storage->Length += len; + + /* copy it in */ + if (data != NULL) { + PORT_Memcpy(storage->Data + offset, data, len); + } + } done: loser: if (buf) - PORT_Free (buf); + PORT_Free (buf); } /* diff --git a/OSX/libsecurity_smime/lib/cmspubkey.c b/OSX/libsecurity_smime/lib/cmspubkey.c index c4dc0eaa..04a12859 100644 --- a/OSX/libsecurity_smime/lib/cmspubkey.c +++ b/OSX/libsecurity_smime/lib/cmspubkey.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -117,6 +118,7 @@ SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, goto loser; PORT_ArenaUnmark(poolp, mark); + CFReleaseNull(theirKeyAttrs); return SECSuccess; loser: @@ -795,7 +797,7 @@ SecCmsUtilEncryptSymKeyECDH( } /* Generate ephemeral ECDH key */ - const void *keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits, kSecAttrNoLegacy}; + const void *keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits, kSecUseDataProtectionKeychain}; const void *values[] = { keyType, keySizeNum, kCFBooleanTrue }; ourKeyParams = CFDictionaryCreate(NULL, keys, values, 3, &kCFTypeDictionaryKeyCallBacks, @@ -953,7 +955,7 @@ out: if (ourPubKey) { CFRelease(ourPubKey); } if (ourPrivKey) { CFRelease(ourPrivKey); } if (sharedInfoData) { CFRelease(sharedInfoData); } - if (kekLen) { CFRelease(kekLen); } + if (kekLen != NULL) { CFRelease(kekLen); } if (kekParams) { CFRelease(kekParams); } if (kekData) { CFRelease(kekData); } if (error) { CFRelease(error); } @@ -1071,7 +1073,7 @@ SecCmsUtilDecryptSymKeyECDH( theirKeySizeInBits = pubKey->Length; pubKey->Length = (theirKeySizeInBits + 7) >> 3; theirPubData = CFDataCreate(NULL, pubKey->Data, pubKey->Length); - theirKeyLen = CFNumberCreate(NULL, kCFNumberSInt32Type, &theirKeySizeInBits); + theirKeyLen = CFNumberCreate(NULL, kCFNumberSInt64Type, &theirKeySizeInBits); const void *keys[] = { kSecAttrKeyType, kSecAttrKeyClass, kSecAttrKeySizeInBits }; const void *values[] = { kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClassPublic, theirKeyLen}; theirKeyAttrs = CFDictionaryCreate(NULL, keys, values, 3, @@ -1145,11 +1147,11 @@ out: PORT_FreeArena(pool, PR_FALSE); } if (theirPubData) { CFRelease(theirPubData); } - if (theirKeyLen) { CFRelease(theirKeyLen); } + if (theirKeyLen != NULL) { CFRelease(theirKeyLen); } if (theirPubKey) { CFRelease(theirPubKey); } if (theirKeyAttrs) { CFRelease(theirKeyAttrs); } if (sharedInfoData) { CFRelease(sharedInfoData); } - if (kekLen) { CFRelease(kekLen); } + if (kekLen != NULL) { CFRelease(kekLen); } if (kekParams) { CFRelease(kekParams); } if (kekData) { CFRelease(kekData); } if (error) { CFRelease(error); } diff --git a/OSX/libsecurity_smime/lib/cmsrecinfo.c b/OSX/libsecurity_smime/lib/cmsrecinfo.c index f6f5f9a6..da2bce56 100644 --- a/OSX/libsecurity_smime/lib/cmsrecinfo.c +++ b/OSX/libsecurity_smime/lib/cmsrecinfo.c @@ -487,7 +487,7 @@ SecCmsRecipientInfoWrapBulkKey(SecCmsRecipientInfoRef ri, SecSymmetricKeyRef bul PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)) +#if TARGET_OS_OSX rv = SecKeyGetAlgorithmID(extra->pubKey,&algid); #else /* TBD: Unify this code. Currently, iOS has an incompatible diff --git a/OSX/libsecurity_smime/lib/cmsreclist.c b/OSX/libsecurity_smime/lib/cmsreclist.c index ecf3179e..ba7f307a 100644 --- a/OSX/libsecurity_smime/lib/cmsreclist.c +++ b/OSX/libsecurity_smime/lib/cmsreclist.c @@ -196,29 +196,29 @@ nss_cms_FindCertAndKeyByRecipientList(SecCmsRecipient **recipient_list, void *wi for (index = 0; recipient_list[index] != NULL; ++index) { - recipient = recipient_list[index]; - - switch (recipient->kind) - { - case RLIssuerSN: - identity = CERT_FindIdentityByIssuerAndSN(keychainOrArray, recipient->id.issuerAndSN); - break; - case RLSubjKeyID: - identity = CERT_FindIdentityBySubjectKeyID(keychainOrArray, recipient->id.subjectKeyID); - break; - } - - if (identity) - break; + recipient = recipient_list[index]; + + switch (recipient->kind) + { + case RLIssuerSN: + identity = CERT_FindIdentityByIssuerAndSN(keychainOrArray, recipient->id.issuerAndSN); + break; + case RLSubjKeyID: + identity = CERT_FindIdentityBySubjectKeyID(keychainOrArray, recipient->id.subjectKeyID); + break; + } + + if (identity) + break; } if (!recipient) - goto loser; + goto loser; - if (SecIdentityCopyCertificate(identity, &cert)) - goto loser; - if (SecIdentityCopyPrivateKey(identity, &privKey)) - goto loser; + if (!identity || SecIdentityCopyCertificate(identity, &cert)) + goto loser; + if (!identity || SecIdentityCopyPrivateKey(identity, &privKey)) + goto loser; CFRelease(identity); recipient->cert = cert; @@ -228,11 +228,11 @@ nss_cms_FindCertAndKeyByRecipientList(SecCmsRecipient **recipient_list, void *wi loser: if (identity) - CFRelease(identity); + CFRelease(identity); if (cert) - CFRelease(cert); + CFRelease(cert); if (privKey) - CFRelease(privKey); + CFRelease(privKey); return -1; } diff --git a/OSX/libsecurity_smime/lib/cmssigdata.c b/OSX/libsecurity_smime/lib/cmssigdata.c index 3d4dc41a..f63a7f80 100644 --- a/OSX/libsecurity_smime/lib/cmssigdata.c +++ b/OSX/libsecurity_smime/lib/cmssigdata.c @@ -423,7 +423,7 @@ SecCmsSignedDataEncodeAfterData(SecCmsSignedDataRef sigd) SecCmsContentInfoRef cinfo; SECOidTag digestalgtag; OSStatus ret = SECFailure; - OSStatus rv; + OSStatus rv = errSecSuccess; CSSM_DATA_PTR contentType; int certcount; int i, ci, n, rci, si; @@ -873,7 +873,7 @@ SecCmsSignedDataAddCertChain(SecCmsSignedDataRef sigd, SecCertificateRef cert) usage = certUsageEmailSigner; /* do not include root */ - certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE); + certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE, PR_FALSE); if (certlist == NULL) return SECFailure; diff --git a/OSX/libsecurity_smime/lib/cmssiginfo.c b/OSX/libsecurity_smime/lib/cmssiginfo.c index 3c1ff754..470b6098 100644 --- a/OSX/libsecurity_smime/lib/cmssiginfo.c +++ b/OSX/libsecurity_smime/lib/cmssiginfo.c @@ -401,7 +401,7 @@ SecCmsSignerInfoSign(SecCmsSignerInfoRef signerinfo, CSSM_DATA_PTR digest, CSSM_ algID = &freeAlgID; #else -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)) +#if TARGET_OS_OSX if (SecKeyGetAlgorithmID(signerinfo->pubKey,&algID)) { #else /* TBD: Unify this code. Currently, iOS has an incompatible @@ -1230,7 +1230,7 @@ SecCmsSignerInfoGetSignerEmailAddress(SecCmsSignerInfoRef sinfo) SecCertificateGetEmailAddress(signercert, &emailAddress); - return emailAddress; + return CFRetainSafe(emailAddress); } @@ -1844,32 +1844,36 @@ SecCmsSignerInfoSaveSMIMEProfile(SecCmsSignerInfoRef signerinfo) OSStatus SecCmsSignerInfoIncludeCerts(SecCmsSignerInfoRef signerinfo, SecCmsCertChainMode cm, SECCertUsage usage) { - if (signerinfo->cert == NULL) - return SECFailure; + if (signerinfo->cert == NULL) { + return SECFailure; + } /* don't leak if we get called twice */ if (signerinfo->certList != NULL) { - CFRelease(signerinfo->certList); - signerinfo->certList = NULL; + CFRelease(signerinfo->certList); + signerinfo->certList = NULL; } switch (cm) { case SecCmsCMNone: - signerinfo->certList = NULL; - break; + signerinfo->certList = NULL; + break; case SecCmsCMCertOnly: - signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); - break; + signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); + break; case SecCmsCMCertChain: - signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE); - break; + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE, PR_FALSE); + break; case SecCmsCMCertChainWithRoot: - signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE); - break; + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE, PR_FALSE); + break; + case SecCmsCMCertChainWithRootOrFail: + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE, PR_TRUE); + } + + if (cm != SecCmsCMNone && signerinfo->certList == NULL) { + return SECFailure; } - if (cm != SecCmsCMNone && signerinfo->certList == NULL) - return SECFailure; - return SECSuccess; } diff --git a/OSX/libsecurity_smime/lib/secitem.c b/OSX/libsecurity_smime/lib/secitem.c index 1eea11ed..7d83f9de 100644 --- a/OSX/libsecurity_smime/lib/secitem.c +++ b/OSX/libsecurity_smime/lib/secitem.c @@ -38,6 +38,7 @@ #include "secitem.h" #include #include +#include SECItem * SECITEM_AllocItem(PRArenaPool *arena, SECItem *item, size_t len) diff --git a/OSX/libsecurity_smime/lib/tsaSupport.c b/OSX/libsecurity_smime/lib/tsaSupport.c index ac6c155f..9718426c 100644 --- a/OSX/libsecurity_smime/lib/tsaSupport.c +++ b/OSX/libsecurity_smime/lib/tsaSupport.c @@ -482,8 +482,12 @@ static OSStatus checkForNonDERResponse(const unsigned char *resp, size_t respLen strlcpy(respStr, (const char *)resp, respLen); for (ix = 0; ix < badResponseCount; ++ix) - if (strcmp(respStr, badResponses[ix])==0) + if (strcmp(respStr, badResponses[ix])==0) { + if(respStr) { + free(respStr); + } return errSecTimestampServiceNotAvailable; + } xit: if (respStr) @@ -749,7 +753,7 @@ OSStatus SecCmsTSADefaultCallback(CFTypeRef context, void *messageImprintV, uint return paramErr; CFBooleanRef cfnocerts = (CFBooleanRef)CFDictionaryGetValue((CFDictionaryRef)context, kTSAContextKeyNoCerts); - if (cfnocerts) + if (cfnocerts != NULL) { tsaDebug("[TSA] Request noCerts\n"); noCerts = CFBooleanGetValue(cfnocerts); diff --git a/OSX/libsecurity_smime/lib/tsaSupport.h b/OSX/libsecurity_smime/lib/tsaSupport.h index 149381f1..90136f1a 100644 --- a/OSX/libsecurity_smime/lib/tsaSupport.h +++ b/OSX/libsecurity_smime/lib/tsaSupport.h @@ -42,7 +42,7 @@ extern const CFStringRef kTSAContextKeyNoCerts; // CFBooleanRef 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); +CF_RETURNS_RETAINED CFMutableDictionaryRef SecCmsTSAGetDefaultContext(CFErrorRef *error); void SecCmsMessageSetTSAContext(SecCmsMessageRef cmsg, CFTypeRef tsaContext); #if defined(__cplusplus) diff --git a/OSX/libsecurity_smime/lib/tsaTemplates.c b/OSX/libsecurity_smime/lib/tsaTemplates.c index 9fb460ee..342d0341 100644 --- a/OSX/libsecurity_smime/lib/tsaTemplates.c +++ b/OSX/libsecurity_smime/lib/tsaTemplates.c @@ -23,8 +23,8 @@ * tsaTemplates.c - ASN1 templates Time Stamping Authority requests and responses */ -#include /* for kSecAsn1AlgorithmIDTemplate */ -#include +#include /* for kSecAsn1AlgorithmIDTemplate */ +#include #include #include @@ -59,15 +59,6 @@ Accuracy ::= SEQUENCE { millis [0] INTEGER (1..999) OPTIONAL, micros [1] INTEGER (1..999) OPTIONAL } */ - -const SecAsn1Template kSecAsn1SignedIntegerTemplate[] = { - { SEC_ASN1_INTEGER | SEC_ASN1_SIGNED_INT, 0, NULL, sizeof(SecAsn1Item) } -}; - -const SecAsn1Template kSecAsn1UnsignedIntegerTemplate[] = { - { SEC_ASN1_INTEGER, 0, NULL, sizeof(SecAsn1Item) } -}; - const SecAsn1Template kSecAsn1TSAAccuracyTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SecAsn1TSAAccuracy) }, diff --git a/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj b/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj deleted file mode 100644 index c0fd98b1..00000000 --- a/OSX/libsecurity_smime/libsecurity_smime.xcodeproj/project.pbxproj +++ /dev/null @@ -1,714 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXAggregateTarget section */ - 0540498B0A37699A0035F195 /* Copy Open Source Docs */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 054049900A3769AC0035F195 /* Build configuration list for PBXAggregateTarget "Copy Open Source Docs" */; - buildPhases = ( - 0540498A0A37699A0035F195 /* CopyFiles */, - 054049A10A376A130035F195 /* CopyFiles */, - ); - dependencies = ( - ); - name = "Copy Open Source Docs"; - productName = "Copy Open Source Docs"; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 0540498E0A3769AC0035F195 /* libsecurity_smime.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0540498C0A3769AC0035F195 /* libsecurity_smime.plist */; }; - 054049990A376A010035F195 /* libsecurity_smime.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 0540498D0A3769AC0035F195 /* libsecurity_smime.txt */; }; - 0588CB2A0E7084880069D232 /* siginfoUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0588CB290E7084880069D232 /* siginfoUtils.cpp */; }; - 4C14208F0415845900CA2E66 /* cmsdigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */; }; - 4C27421103E9FC6700A80181 /* cmsarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F203E9FC5B00A80181 /* cmsarray.c */; }; - 4C27421303E9FC6900A80181 /* cmsasn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F303E9FC5B00A80181 /* cmsasn1.c */; }; - 4C27421403E9FC6A00A80181 /* cmsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F403E9FC5B00A80181 /* cmsattr.c */; }; - 4C27421503E9FC6C00A80181 /* cmscinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F503E9FC5B00A80181 /* cmscinfo.c */; }; - 4C27421703E9FC6D00A80181 /* cmsdecode.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F703E9FC5B00A80181 /* cmsdecode.c */; }; - 4C27421B03E9FC7000A80181 /* cmsencode.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FB03E9FC5B00A80181 /* cmsencode.c */; }; - 4C27421D03E9FC7100A80181 /* cmslocal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C2741FD03E9FC5B00A80181 /* cmslocal.h */; }; - 4C27421E03E9FC7200A80181 /* cmsmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */; }; - 4C27422103E9FC7500A80181 /* cmsreclist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420103E9FC5B00A80181 /* cmsreclist.c */; }; - 4C27422203E9FC7600A80181 /* cmsreclist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C27420203E9FC5B00A80181 /* cmsreclist.h */; }; - 4C424BE8063F28F600E9831A /* SecSMIMEPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C424BE7063F28F600E9831A /* SecSMIMEPriv.h */; }; - 4C6CA861040308C700CA2E66 /* cmssigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420303E9FC5B00A80181 /* cmssigdata.c */; }; - 4C7183480637153700230DDE /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C7183470637153700230DDE /* SecSMIME.h */; settings = {ATTRIBUTES = (); }; }; - 4C8E166F0438EEE700CA2E66 /* secoid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E166C0438EEE700CA2E66 /* secoid.c */; }; - 4C8E16700438EEE700CA2E66 /* secoid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E166D0438EEE700CA2E66 /* secoid.h */; }; - 4C8E16740438EF5700CA2E66 /* plhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E16720438EF5700CA2E66 /* plhash.c */; }; - 4C8E16750438EF5700CA2E66 /* plhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E16730438EF5700CA2E66 /* plhash.h */; }; - 4C8E16790438EFD700CA2E66 /* secitem.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E16770438EFD700CA2E66 /* secitem.c */; }; - 4C8E167A0438EFD700CA2E66 /* secitem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E16780438EFD700CA2E66 /* secitem.h */; }; - 4CA51CE00420246F00CA2E66 /* cryptohi.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CA51CDF0420246F00CA2E66 /* cryptohi.h */; }; - 4CB42E340421212D00CA2E66 /* cryptohi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB42E330421212D00CA2E66 /* cryptohi.c */; }; - 4CB6AADA040DA84D00CA2E66 /* secalgid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */; }; - 4CCC260E0635F1A200CBF0D4 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC260F0635F1A200CBF0D4 /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26100635F1A200CBF0D4 /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26110635F1A200CBF0D4 /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26120635F1A200CBF0D4 /* SecCmsDigestedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26130635F1A200CBF0D4 /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26140635F1A200CBF0D4 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26150635F1A200CBF0D4 /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26160635F1A200CBF0D4 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26170635F1A200CBF0D4 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */; settings = {ATTRIBUTES = (); }; }; - 4CCC26180635F1A200CBF0D4 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (); }; }; - 4CDA0D5E04200AD600CA2E66 /* cmscipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F603E9FC5B00A80181 /* cmscipher.c */; }; - 4CDA0D6004200AD800CA2E66 /* cmsencdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */; }; - 4CDA0D6104200AD800CA2E66 /* cmsdigest.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F903E9FC5B00A80181 /* cmsdigest.c */; }; - 4CDA0D6204200AD900CA2E66 /* cmsenvdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */; }; - 4CDA0D6304200ADD00CA2E66 /* cmspubkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */; }; - 4CDA0D6404200ADD00CA2E66 /* cmsrecinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */; }; - 4CDA0D6504200ADF00CA2E66 /* cmsutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6D72BC0410298900CA2E66 /* cmsutil.c */; }; - 4CDA0D6604200AE000CA2E66 /* cmssiginfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420403E9FC5B00A80181 /* cmssiginfo.c */; }; - 4CDA0D6704200B0F00CA2E66 /* smimeutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420F03E9FC5B00A80181 /* smimeutil.c */; }; - 4CEC5CDF042A721300CA2E66 /* cmspriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CDE042A721300CA2E66 /* cmspriv.h */; }; - 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */; }; - 4CEDC82106371B1700B7E254 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */; settings = {ATTRIBUTES = (); }; }; - 5232A822150AD71A00E6BB48 /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5232A821150AD71A00E6BB48 /* tsaSupportPriv.h */; }; - 52B609D514F4665700134209 /* tsaTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = 52B609D314F4665700134209 /* tsaTemplates.c */; }; - 52B609D614F4665700134209 /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = 52B609D414F4665700134209 /* tsaTemplates.h */; }; - 52D7A24A15092A0600CF48F7 /* tsaSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = 52D7A24915092A0600CF48F7 /* tsaSupport.c */; }; - 52D7A24D15094B8B00CF48F7 /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 52D7A24C15092AAD00CF48F7 /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; - AC62F5F418B4358B00704BBD /* smime-cms-test.c in Sources */ = {isa = PBXBuildFile; fileRef = ACBEE91018B420BC0021712D /* smime-cms-test.c */; }; - ACA9CE4A18BC4543005AD855 /* SecCMS.h in Headers */ = {isa = PBXBuildFile; fileRef = ACBEE90D18B415B60021712D /* SecCMS.h */; }; - ACBEE90C18B403470021712D /* SecCMS.c in Sources */ = {isa = PBXBuildFile; fileRef = ACBEE90B18B403470021712D /* SecCMS.c */; }; - ACBEE90E18B415B60021712D /* SecCMS.h in Headers */ = {isa = PBXBuildFile; fileRef = ACBEE90D18B415B60021712D /* SecCMS.h */; settings = {ATTRIBUTES = (Private, ); }; }; - D421AF641CA45E8C00A8E512 /* cms-01-basic.c in Sources */ = {isa = PBXBuildFile; fileRef = D421AF601CA45E4900A8E512 /* cms-01-basic.c */; }; - D421AF651CA45E9700A8E512 /* cms-01-basic.h in Headers */ = {isa = PBXBuildFile; fileRef = D421AF611CA45E4900A8E512 /* cms-01-basic.h */; }; - F64399010420118A01CA2DCC /* cert.h in Headers */ = {isa = PBXBuildFile; fileRef = F64398FF0420118A01CA2DCC /* cert.h */; }; - F64399020420118A01CA2DCC /* cert.c in Sources */ = {isa = PBXBuildFile; fileRef = F64399000420118A01CA2DCC /* cert.c */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 0540499A0A376A090035F195 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C2741E803E9FBAF00A80181 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 0540498B0A37699A0035F195; - remoteInfo = "Copy Open Source Docs"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 0540498A0A37699A0035F195 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/local/OpenSourceVersions/; - dstSubfolderSpec = 0; - files = ( - 0540498E0A3769AC0035F195 /* libsecurity_smime.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; - 054049A10A376A130035F195 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/local/OpenSourceLicenses/; - dstSubfolderSpec = 0; - files = ( - 054049990A376A010035F195 /* libsecurity_smime.txt in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 0540498C0A3769AC0035F195 /* libsecurity_smime.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = libsecurity_smime.plist; sourceTree = ""; }; - 0540498D0A3769AC0035F195 /* libsecurity_smime.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = libsecurity_smime.txt; sourceTree = ""; }; - 0588CB290E7084880069D232 /* siginfoUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = siginfoUtils.cpp; sourceTree = ""; }; - 182BB39E146F1A68000BF1F3 /* base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = base.xcconfig; sourceTree = ""; }; - 182BB39F146F1A68000BF1F3 /* debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = debug.xcconfig; sourceTree = ""; }; - 182BB3A0146F1A68000BF1F3 /* lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = lib.xcconfig; sourceTree = ""; }; - 182BB3A1146F1A68000BF1F3 /* release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = ""; }; - 4C2741F203E9FC5B00A80181 /* cmsarray.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsarray.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F303E9FC5B00A80181 /* cmsasn1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsasn1.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F403E9FC5B00A80181 /* cmsattr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsattr.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F503E9FC5B00A80181 /* cmscinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmscinfo.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F603E9FC5B00A80181 /* cmscipher.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmscipher.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F703E9FC5B00A80181 /* cmsdecode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsdecode.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsdigdata.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F903E9FC5B00A80181 /* cmsdigest.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsdigest.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsencdata.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FB03E9FC5B00A80181 /* cmsencode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsencode.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsenvdata.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FD03E9FC5B00A80181 /* cmslocal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cmslocal.h; sourceTree = ""; tabWidth = 8; }; - 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsmessage.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmspubkey.c; sourceTree = ""; tabWidth = 8; }; - 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsrecinfo.c; sourceTree = ""; tabWidth = 8; }; - 4C27420103E9FC5B00A80181 /* cmsreclist.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsreclist.c; sourceTree = ""; tabWidth = 8; }; - 4C27420203E9FC5B00A80181 /* cmsreclist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cmsreclist.h; sourceTree = ""; tabWidth = 8; }; - 4C27420303E9FC5B00A80181 /* cmssigdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmssigdata.c; sourceTree = ""; tabWidth = 8; }; - 4C27420403E9FC5B00A80181 /* cmssiginfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmssiginfo.c; sourceTree = ""; tabWidth = 8; }; - 4C27420F03E9FC5B00A80181 /* smimeutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = smimeutil.c; sourceTree = ""; tabWidth = 8; }; - 4C424BE7063F28F600E9831A /* SecSMIMEPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecSMIMEPriv.h; sourceTree = ""; }; - 4C6D72BC0410298900CA2E66 /* cmsutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsutil.c; sourceTree = ""; tabWidth = 8; }; - 4C7183470637153700230DDE /* SecSMIME.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecSMIME.h; sourceTree = ""; }; - 4C817F8405ED4D7A007975E6 /* libsecurity_smime.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_smime.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 4C8E166C0438EEE700CA2E66 /* secoid.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = secoid.c; sourceTree = ""; }; - 4C8E166D0438EEE700CA2E66 /* secoid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = secoid.h; sourceTree = ""; }; - 4C8E166E0438EEE700CA2E66 /* secoidt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = secoidt.h; sourceTree = ""; }; - 4C8E16720438EF5700CA2E66 /* plhash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = plhash.c; sourceTree = ""; }; - 4C8E16730438EF5700CA2E66 /* plhash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plhash.h; sourceTree = ""; }; - 4C8E16770438EFD700CA2E66 /* secitem.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = secitem.c; sourceTree = ""; }; - 4C8E16780438EFD700CA2E66 /* secitem.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = secitem.h; sourceTree = ""; }; - 4CA51CDF0420246F00CA2E66 /* cryptohi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cryptohi.h; sourceTree = ""; tabWidth = 8; }; - 4CB42E330421212D00CA2E66 /* cryptohi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cryptohi.c; sourceTree = ""; tabWidth = 8; }; - 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = secalgid.c; sourceTree = ""; }; - 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsBase.h; sourceTree = ""; }; - 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsContentInfo.h; sourceTree = ""; }; - 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsDecoder.h; sourceTree = ""; }; - 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestContext.h; sourceTree = ""; }; - 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestedData.h; sourceTree = ""; }; - 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsEncoder.h; sourceTree = ""; }; - 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsEnvelopedData.h; sourceTree = ""; }; - 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsMessage.h; sourceTree = ""; }; - 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsRecipientInfo.h; sourceTree = ""; }; - 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsSignedData.h; sourceTree = ""; }; - 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsSignerInfo.h; sourceTree = ""; }; - 4CEC5CDE042A721300CA2E66 /* cmspriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmspriv.h; sourceTree = ""; }; - 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmstpriv.h; sourceTree = ""; }; - 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsEncryptedData.h; sourceTree = ""; }; - 5232A821150AD71A00E6BB48 /* tsaSupportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsaSupportPriv.h; sourceTree = ""; }; - 52B609D314F4665700134209 /* tsaTemplates.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tsaTemplates.c; sourceTree = ""; }; - 52B609D414F4665700134209 /* tsaTemplates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsaTemplates.h; sourceTree = ""; }; - 52D7A24915092A0600CF48F7 /* tsaSupport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = tsaSupport.c; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; }; - 52D7A24C15092AAD00CF48F7 /* tsaSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tsaSupport.h; sourceTree = ""; }; - AC62F5F018B4356A00704BBD /* libsecurity_smime_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_smime_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; - ACBEE90B18B403470021712D /* SecCMS.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCMS.c; sourceTree = ""; }; - ACBEE90D18B415B60021712D /* SecCMS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCMS.h; sourceTree = ""; }; - ACBEE91018B420BC0021712D /* smime-cms-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "smime-cms-test.c"; sourceTree = ""; }; - ACBEE91318B421890021712D /* smime_regressions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = smime_regressions.h; sourceTree = ""; }; - D421AF601CA45E4900A8E512 /* cms-01-basic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "cms-01-basic.c"; sourceTree = ""; }; - D421AF611CA45E4900A8E512 /* cms-01-basic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cms-01-basic.h"; sourceTree = ""; }; - F64398FF0420118A01CA2DCC /* cert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cert.h; sourceTree = ""; tabWidth = 8; }; - F64399000420118A01CA2DCC /* cert.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cert.c; sourceTree = ""; tabWidth = 8; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 4C2741EB03E9FBF700A80181 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AC62F5ED18B4356A00704BBD /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 054049870A3769830035F195 /* docs */ = { - isa = PBXGroup; - children = ( - 0540498D0A3769AC0035F195 /* libsecurity_smime.txt */, - 0540498C0A3769AC0035F195 /* libsecurity_smime.plist */, - ); - path = docs; - sourceTree = ""; - }; - 182BB39D146F1A68000BF1F3 /* config */ = { - isa = PBXGroup; - children = ( - 182BB39E146F1A68000BF1F3 /* base.xcconfig */, - 182BB39F146F1A68000BF1F3 /* debug.xcconfig */, - 182BB3A0146F1A68000BF1F3 /* lib.xcconfig */, - 182BB3A1146F1A68000BF1F3 /* release.xcconfig */, - ); - name = config; - path = ../config; - sourceTree = ""; - }; - 4C2741E403E9FBAF00A80181 = { - isa = PBXGroup; - children = ( - ACBEE90F18B41FB80021712D /* regressions */, - 4C2741F003E9FC2100A80181 /* lib */, - 182BB39D146F1A68000BF1F3 /* config */, - 054049870A3769830035F195 /* docs */, - 4C2741EF03E9FBF700A80181 /* Products */, - ); - sourceTree = ""; - }; - 4C2741EF03E9FBF700A80181 /* Products */ = { - isa = PBXGroup; - children = ( - 4C817F8405ED4D7A007975E6 /* libsecurity_smime.a */, - AC62F5F018B4356A00704BBD /* libsecurity_smime_regressions.a */, - ); - name = Products; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 4C2741F003E9FC2100A80181 /* lib */ = { - isa = PBXGroup; - children = ( - 5232A821150AD71A00E6BB48 /* tsaSupportPriv.h */, - 52D7A24915092A0600CF48F7 /* tsaSupport.c */, - 52D7A24C15092AAD00CF48F7 /* tsaSupport.h */, - 52B609D314F4665700134209 /* tsaTemplates.c */, - 52B609D414F4665700134209 /* tsaTemplates.h */, - 0588CB290E7084880069D232 /* siginfoUtils.cpp */, - F64399000420118A01CA2DCC /* cert.c */, - F64398FF0420118A01CA2DCC /* cert.h */, - 4C2741F203E9FC5B00A80181 /* cmsarray.c */, - 4C2741F303E9FC5B00A80181 /* cmsasn1.c */, - 4C2741F403E9FC5B00A80181 /* cmsattr.c */, - 4C2741F503E9FC5B00A80181 /* cmscinfo.c */, - 4C2741F603E9FC5B00A80181 /* cmscipher.c */, - 4C2741F703E9FC5B00A80181 /* cmsdecode.c */, - 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */, - 4C2741F903E9FC5B00A80181 /* cmsdigest.c */, - 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */, - 4C2741FB03E9FC5B00A80181 /* cmsencode.c */, - 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */, - 4C2741FD03E9FC5B00A80181 /* cmslocal.h */, - 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */, - 4CEC5CDE042A721300CA2E66 /* cmspriv.h */, - 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */, - 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */, - 4C27420103E9FC5B00A80181 /* cmsreclist.c */, - 4C27420203E9FC5B00A80181 /* cmsreclist.h */, - 4C27420303E9FC5B00A80181 /* cmssigdata.c */, - 4C27420403E9FC5B00A80181 /* cmssiginfo.c */, - 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */, - 4C6D72BC0410298900CA2E66 /* cmsutil.c */, - 4CB42E330421212D00CA2E66 /* cryptohi.c */, - 4CA51CDF0420246F00CA2E66 /* cryptohi.h */, - 4C8E16720438EF5700CA2E66 /* plhash.c */, - 4C8E16730438EF5700CA2E66 /* plhash.h */, - 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */, - 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */, - 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */, - 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */, - 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */, - 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */, - 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */, - 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */, - 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */, - 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */, - 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */, - 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */, - 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */, - 4C8E16770438EFD700CA2E66 /* secitem.c */, - 4C8E16780438EFD700CA2E66 /* secitem.h */, - 4C8E166C0438EEE700CA2E66 /* secoid.c */, - 4C8E166D0438EEE700CA2E66 /* secoid.h */, - 4C8E166E0438EEE700CA2E66 /* secoidt.h */, - 4C7183470637153700230DDE /* SecSMIME.h */, - 4C424BE7063F28F600E9831A /* SecSMIMEPriv.h */, - 4C27420F03E9FC5B00A80181 /* smimeutil.c */, - ACBEE90B18B403470021712D /* SecCMS.c */, - ACBEE90D18B415B60021712D /* SecCMS.h */, - ); - path = lib; - sourceTree = ""; - }; - ACBEE90F18B41FB80021712D /* regressions */ = { - isa = PBXGroup; - children = ( - D421AF601CA45E4900A8E512 /* cms-01-basic.c */, - D421AF611CA45E4900A8E512 /* cms-01-basic.h */, - ACBEE91018B420BC0021712D /* smime-cms-test.c */, - ACBEE91318B421890021712D /* smime_regressions.h */, - ); - path = regressions; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 4C2741E903E9FBF700A80181 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F64399010420118A01CA2DCC /* cert.h in Headers */, - 4C27421D03E9FC7100A80181 /* cmslocal.h in Headers */, - 4CEC5CDF042A721300CA2E66 /* cmspriv.h in Headers */, - 4C27422203E9FC7600A80181 /* cmsreclist.h in Headers */, - 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */, - 5232A822150AD71A00E6BB48 /* tsaSupportPriv.h in Headers */, - 4CA51CE00420246F00CA2E66 /* cryptohi.h in Headers */, - 4C8E16750438EF5700CA2E66 /* plhash.h in Headers */, - 4CCC260E0635F1A200CBF0D4 /* SecCmsBase.h in Headers */, - 4CCC260F0635F1A200CBF0D4 /* SecCmsContentInfo.h in Headers */, - 4CCC26100635F1A200CBF0D4 /* SecCmsDecoder.h in Headers */, - 4CCC26110635F1A200CBF0D4 /* SecCmsDigestContext.h in Headers */, - 4CCC26120635F1A200CBF0D4 /* SecCmsDigestedData.h in Headers */, - 4CCC26130635F1A200CBF0D4 /* SecCmsEncoder.h in Headers */, - 4CEDC82106371B1700B7E254 /* SecCmsEncryptedData.h in Headers */, - 4CCC26140635F1A200CBF0D4 /* SecCmsEnvelopedData.h in Headers */, - 4CCC26150635F1A200CBF0D4 /* SecCmsMessage.h in Headers */, - 4CCC26160635F1A200CBF0D4 /* SecCmsRecipientInfo.h in Headers */, - 4CCC26170635F1A200CBF0D4 /* SecCmsSignedData.h in Headers */, - 4CCC26180635F1A200CBF0D4 /* SecCmsSignerInfo.h in Headers */, - 4C7183480637153700230DDE /* SecSMIME.h in Headers */, - 4C8E167A0438EFD700CA2E66 /* secitem.h in Headers */, - 4C8E16700438EEE700CA2E66 /* secoid.h in Headers */, - 4C424BE8063F28F600E9831A /* SecSMIMEPriv.h in Headers */, - 52D7A24D15094B8B00CF48F7 /* tsaSupport.h in Headers */, - ACBEE90E18B415B60021712D /* SecCMS.h in Headers */, - 52B609D614F4665700134209 /* tsaTemplates.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AC62F5EE18B4356A00704BBD /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - D421AF651CA45E9700A8E512 /* cms-01-basic.h in Headers */, - ACA9CE4A18BC4543005AD855 /* SecCMS.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 4C2741ED03E9FBF700A80181 /* libsecurity_smime */ = { - isa = PBXNativeTarget; - buildConfigurationList = C23B0CD309A298C100B7FCED /* Build configuration list for PBXNativeTarget "libsecurity_smime" */; - buildPhases = ( - 4C2741E903E9FBF700A80181 /* Headers */, - 4C2741EA03E9FBF700A80181 /* Sources */, - 4C2741EB03E9FBF700A80181 /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - 0540499B0A376A090035F195 /* PBXTargetDependency */, - ); - name = libsecurity_smime; - productInstallPath = /usr/local/lib; - productName = libSecurityNssSmime.a; - productReference = 4C817F8405ED4D7A007975E6 /* libsecurity_smime.a */; - productType = "com.apple.product-type.library.static"; - }; - AC62F5EF18B4356A00704BBD /* libsecurity_smime_regressions */ = { - isa = PBXNativeTarget; - buildConfigurationList = AC62F5F318B4356A00704BBD /* Build configuration list for PBXNativeTarget "libsecurity_smime_regressions" */; - buildPhases = ( - AC62F5EC18B4356A00704BBD /* Sources */, - AC62F5ED18B4356A00704BBD /* Frameworks */, - AC62F5EE18B4356A00704BBD /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = libsecurity_smime_regressions; - productName = libsecurity_smime_regressions; - productReference = AC62F5F018B4356A00704BBD /* libsecurity_smime_regressions.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 4C2741E803E9FBAF00A80181 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1000; - }; - buildConfigurationList = C23B0CD909A298C100B7FCED /* Build configuration list for PBXProject "libsecurity_smime" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 4C2741E403E9FBAF00A80181; - productRefGroup = 4C2741EF03E9FBF700A80181 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 4C2741ED03E9FBF700A80181 /* libsecurity_smime */, - 0540498B0A37699A0035F195 /* Copy Open Source Docs */, - AC62F5EF18B4356A00704BBD /* libsecurity_smime_regressions */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - 4C2741EA03E9FBF700A80181 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F64399020420118A01CA2DCC /* cert.c in Sources */, - 4C27421103E9FC6700A80181 /* cmsarray.c in Sources */, - 4C27421303E9FC6900A80181 /* cmsasn1.c in Sources */, - 4C27421403E9FC6A00A80181 /* cmsattr.c in Sources */, - 4C27421503E9FC6C00A80181 /* cmscinfo.c in Sources */, - 4CDA0D5E04200AD600CA2E66 /* cmscipher.c in Sources */, - ACBEE90C18B403470021712D /* SecCMS.c in Sources */, - 4C27421703E9FC6D00A80181 /* cmsdecode.c in Sources */, - 4C14208F0415845900CA2E66 /* cmsdigdata.c in Sources */, - 4CDA0D6104200AD800CA2E66 /* cmsdigest.c in Sources */, - 4CDA0D6004200AD800CA2E66 /* cmsencdata.c in Sources */, - 4C27421B03E9FC7000A80181 /* cmsencode.c in Sources */, - 4CDA0D6204200AD900CA2E66 /* cmsenvdata.c in Sources */, - 4C27421E03E9FC7200A80181 /* cmsmessage.c in Sources */, - 4CDA0D6304200ADD00CA2E66 /* cmspubkey.c in Sources */, - 4CDA0D6404200ADD00CA2E66 /* cmsrecinfo.c in Sources */, - 4C27422103E9FC7500A80181 /* cmsreclist.c in Sources */, - 4C6CA861040308C700CA2E66 /* cmssigdata.c in Sources */, - 4CDA0D6604200AE000CA2E66 /* cmssiginfo.c in Sources */, - 4CDA0D6504200ADF00CA2E66 /* cmsutil.c in Sources */, - 4CB42E340421212D00CA2E66 /* cryptohi.c in Sources */, - 4C8E16740438EF5700CA2E66 /* plhash.c in Sources */, - 4CB6AADA040DA84D00CA2E66 /* secalgid.c in Sources */, - 4C8E16790438EFD700CA2E66 /* secitem.c in Sources */, - 4C8E166F0438EEE700CA2E66 /* secoid.c in Sources */, - 4CDA0D6704200B0F00CA2E66 /* smimeutil.c in Sources */, - 0588CB2A0E7084880069D232 /* siginfoUtils.cpp in Sources */, - 52B609D514F4665700134209 /* tsaTemplates.c in Sources */, - 52D7A24A15092A0600CF48F7 /* tsaSupport.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - AC62F5EC18B4356A00704BBD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D421AF641CA45E8C00A8E512 /* cms-01-basic.c in Sources */, - AC62F5F418B4358B00704BBD /* smime-cms-test.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 0540499B0A376A090035F195 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 0540498B0A37699A0035F195 /* Copy Open Source Docs */; - targetProxy = 0540499A0A376A090035F195 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 054049910A3769AC0035F195 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - }; - name = Debug; - }; - 054049950A3769AC0035F195 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - }; - name = Release; - }; - AC62F5F118B4356A00704BBD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = 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__DUPLICATE_METHOD_MATCH = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = NO; - EXECUTABLE_PREFIX = ""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - AC62F5F218B4356A00704BBD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = 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__DUPLICATE_METHOD_MATCH = YES; - COMBINE_HIDPI_IMAGES = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - EXECUTABLE_PREFIX = ""; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - C23B0CD409A298C100B7FCED /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 182BB39F146F1A68000BF1F3 /* debug.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - COMBINE_HIDPI_IMAGES = YES; - GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; - }; - name = Debug; - }; - C23B0CD809A298C100B7FCED /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 182BB3A1146F1A68000BF1F3 /* release.xcconfig */; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - COMBINE_HIDPI_IMAGES = YES; - GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; - }; - name = Release; - }; - C23B0CDA09A298C100B7FCED /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 182BB3A0146F1A68000BF1F3 /* lib.xcconfig */; - 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; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - ONLY_ACTIVE_ARCH = YES; - }; - name = Debug; - }; - C23B0CDE09A298C100B7FCED /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 182BB3A0146F1A68000BF1F3 /* lib.xcconfig */; - 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; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 054049900A3769AC0035F195 /* Build configuration list for PBXAggregateTarget "Copy Open Source Docs" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 054049910A3769AC0035F195 /* Debug */, - 054049950A3769AC0035F195 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - AC62F5F318B4356A00704BBD /* Build configuration list for PBXNativeTarget "libsecurity_smime_regressions" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - AC62F5F118B4356A00704BBD /* Debug */, - AC62F5F218B4356A00704BBD /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C23B0CD309A298C100B7FCED /* Build configuration list for PBXNativeTarget "libsecurity_smime" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C23B0CD409A298C100B7FCED /* Debug */, - C23B0CD809A298C100B7FCED /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - C23B0CD909A298C100B7FCED /* Build configuration list for PBXProject "libsecurity_smime" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - C23B0CDA09A298C100B7FCED /* Debug */, - C23B0CDE09A298C100B7FCED /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 4C2741E803E9FBAF00A80181 /* Project object */; -} diff --git a/OSX/libsecurity_smime/regressions/cms-01-basic.c b/OSX/libsecurity_smime/regressions/cms-01-basic.c index da6677f2..7af821b7 100644 --- a/OSX/libsecurity_smime/regressions/cms-01-basic.c +++ b/OSX/libsecurity_smime/regressions/cms-01-basic.c @@ -22,7 +22,7 @@ */ #include "cms-01-basic.h" -#include "smime_regressions.h" +#include "cms_regressions.h" #include diff --git a/OSX/libsecurity_smime/regressions/smime-cms-test.c b/OSX/libsecurity_smime/regressions/smime-cms-test.c index 080daa1c..9c9b30e9 100644 --- a/OSX/libsecurity_smime/regressions/smime-cms-test.c +++ b/OSX/libsecurity_smime/regressions/smime-cms-test.c @@ -21,6 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include +#include +#include #include #include @@ -34,10 +37,7 @@ #include #include -#include -#include - -int smime_cms_test(int argc, char *const *argv); +#include "cms_regressions.h" /* Bag Attributes diff --git a/OSX/libsecurity_ssl/lib/CipherSuite.h b/OSX/libsecurity_ssl/lib/CipherSuite.h index 8d352897..0a4ac115 100644 --- a/OSX/libsecurity_ssl/lib/CipherSuite.h +++ b/OSX/libsecurity_ssl/lib/CipherSuite.h @@ -36,12 +36,12 @@ * Defined as enum for debugging, but in the protocol * it is actually exactly two bytes */ -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) -/* 32-bit value on OS X */ -typedef uint32_t SSLCipherSuite; -#else +#if TARGET_OS_IPHONE && !TARGET_OS_IOSMAC /* 16-bit value on iOS */ typedef uint16_t SSLCipherSuite; +#else +/* 32-bit value elsewhere */ +typedef uint32_t SSLCipherSuite; #endif CF_ENUM(SSLCipherSuite) @@ -117,6 +117,13 @@ CF_ENUM(SSLCipherSuite) TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018, TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019, + /* ECDHE_PSK Cipher Suites for Transport Layer Security (TLS), RFC 5489 */ + TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA = 0xC035, + TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA = 0xC036, + + /* ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS), RFC 7905 */ + TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB, + /* TLS 1.2 addenda, RFC 5246 */ /* Initial state. */ @@ -256,4 +263,16 @@ CF_ENUM(SSLCipherSuite) SSL_NO_SUCH_CIPHERSUITE = 0xFFFF }; +/* + * Convenience ciphersuite groups that collate ciphersuites of comparable security + * properties into a single alias. + */ +typedef CF_ENUM(int, SSLCiphersuiteGroup) { + kSSLCiphersuiteGroupDefault, + kSSLCiphersuiteGroupCompatibility, + kSSLCiphersuiteGroupLegacy, + kSSLCiphersuiteGroupATS, + kSSLCiphersuiteGroupATSCompatibility, +}; + #endif /* !_SECURITY_CIPHERSUITE_H_ */ diff --git a/OSX/libsecurity_ssl/lib/SecureTransport.h b/OSX/libsecurity_ssl/lib/SecureTransport.h index 7b4ce804..1bb104a9 100644 --- a/OSX/libsecurity_ssl/lib/SecureTransport.h +++ b/OSX/libsecurity_ssl/lib/SecureTransport.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002,2005-2016 Apple Inc. All Rights Reserved. + * Copyright (c) 1999-2002,2005-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -59,8 +59,10 @@ */ #include +#include #include #include +#include #include #include @@ -71,34 +73,19 @@ extern "C" { CF_ASSUME_NONNULL_BEGIN CF_IMPLICIT_BRIDGING_ENABLED +#define __SECURETRANSPORT_API_DEPRECATED(...) \ + __API_DEPRECATED("No longer supported. Use Network.framework.", __VA_ARGS__) + /*********************** *** Common typedefs *** ***********************/ /* Opaque reference to an SSL session context */ -struct SSLContext; +struct SSLContext; typedef struct CF_BRIDGED_TYPE(id) SSLContext *SSLContextRef; /* Opaque reference to an I/O connection (socket, endpoint, etc.) */ -typedef const void * SSLConnectionRef; - -/* SSL Protocol version */ -typedef CF_ENUM(int, SSLProtocol) { - kSSLProtocolUnknown = 0, /* no protocol negotiated/specified; use default */ - kSSLProtocol3 = 2, /* SSL 3.0 */ - kTLSProtocol1 = 4, /* TLS 1.0 */ - kTLSProtocol11 = 7, /* TLS 1.1 */ - kTLSProtocol12 = 8, /* TLS 1.2 */ - kDTLSProtocol1 = 9, /* DTLS 1.0 */ - kTLSProtocol13 = 10, /* TLS 1.3 */ - - kTLSProtocolMaxSupported = 999, /* Max system-supported version */ - - kSSLProtocol2 = 1, /* SSL 2.0. DEPRECATED on iOS. */ - kSSLProtocol3Only = 3, /* SSL 3.0. DEPRECATED on iOS. */ - kTLSProtocol1Only = 5, /* TLS 1.0 Only. DEPRECATED on iOS. */ - kSSLProtocolAll = 6, /* All TLS supported protocols. DEPRECATED on iOS. */ -}; +typedef const void *SSLConnectionRef; /* SSL session options */ typedef CF_ENUM(int, SSLSessionOption) { @@ -109,62 +96,62 @@ typedef CF_ENUM(int, SSLSessionOption) { * provides an opportunity to perform application-specific server * verification before deciding to continue. */ - kSSLSessionOptionBreakOnServerAuth = 0, + kSSLSessionOptionBreakOnServerAuth CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 0, /* * Set this option to enable returning from SSLHandshake (with a result of * errSSLClientCertRequested) when the server requests a client certificate. */ - kSSLSessionOptionBreakOnCertRequested = 1, + kSSLSessionOptionBreakOnCertRequested CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 1, /* * This option is the same as kSSLSessionOptionBreakOnServerAuth but applies * to the case where SecureTransport is the server and the client has presented * its certificates allowing the server to verify whether these should be * allowed to authenticate. */ - kSSLSessionOptionBreakOnClientAuth = 2, + kSSLSessionOptionBreakOnClientAuth CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 2, /* * Enable/Disable TLS False Start * When enabled, False Start will only be performed if a adequate cipher-suite is * negotiated. */ - kSSLSessionOptionFalseStart = 3, + kSSLSessionOptionFalseStart CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 3, /* * Enable/Disable 1/n-1 record splitting for BEAST attack mitigation. * When enabled, record splitting will only be performed for TLS 1.0 connections * using a block cipher. */ - kSSLSessionOptionSendOneByteRecord = 4, + kSSLSessionOptionSendOneByteRecord CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 4, /* * Allow/Disallow server identity change on renegotiation. Disallow by default * to avoid Triple Handshake attack. */ - kSSLSessionOptionAllowServerIdentityChange = 5, + kSSLSessionOptionAllowServerIdentityChange CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 5, /* * Enable fallback countermeasures. Use this option when retyring a SSL connection * with a lower protocol version because of failure to connect. */ - kSSLSessionOptionFallback = 6, + kSSLSessionOptionFallback CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 6, /* * Set this option to break from a client hello in order to check for SNI */ - kSSLSessionOptionBreakOnClientHello = 7, + kSSLSessionOptionBreakOnClientHello CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 7, /* * Set this option to Allow renegotations. False by default. */ - kSSLSessionOptionAllowRenegotiation = 8, + kSSLSessionOptionAllowRenegotiation CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 8, /* * Set this option to enable session tickets. False by default. */ - kSSLSessionOptionEnableSessionTickets = 9, + kSSLSessionOptionEnableSessionTickets CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) = 9, }; /* State of an SSLSession */ -typedef CF_ENUM(int, SSLSessionState) { - kSSLIdle, /* no I/O performed yet */ - kSSLHandshake, /* SSL handshake in progress */ - kSSLConnected, /* Handshake complete, ready for normal I/O */ - kSSLClosed, /* connection closed normally */ - kSSLAborted /* connection aborted */ +typedef CF_CLOSED_ENUM(int, SSLSessionState) { + kSSLIdle CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* no I/O performed yet */ + kSSLHandshake CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* SSL handshake in progress */ + kSSLConnected CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* Handshake complete, ready for normal I/O */ + kSSLClosed CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* connection closed normally */ + kSSLAborted CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) /* connection aborted */ }; /* @@ -173,33 +160,21 @@ typedef CF_ENUM(int, SSLSessionState) { */ typedef CF_ENUM(int, SSLClientCertificateState) { /* Server hasn't asked for a cert. Client hasn't sent one. */ - kSSLClientCertNone, + kSSLClientCertNone CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* Server has asked for a cert, but client didn't send it. */ - kSSLClientCertRequested, + kSSLClientCertRequested CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* * Server side: We asked for a cert, client sent one, we validated * it OK. App can inspect the cert via * SSLCopyPeerCertificates(). * Client side: server asked for one, we sent it. */ - kSSLClientCertSent, + kSSLClientCertSent CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), /* * Client sent a cert but failed validation. Server side only. * Server app can inspect the cert via SSLCopyPeerCertificates(). */ - 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, + kSSLClientCertRejected CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) }; /* @@ -230,100 +205,6 @@ typedef OSStatus const void *data, size_t *dataLength); /* IN/OUT */ -/************************************************* - *** OSStatus values unique to SecureTransport *** - *************************************************/ - -/* - Note: the comments that appear after these errors are used to create SecErrorMessages.strings. - The comments must not be multi-line, and should be in a form meaningful to an end user. If - a different or additional comment is needed, it can be put in the header doc format, or on a - line that does not start with errZZZ. -*/ - -CF_ENUM(OSStatus) { - errSSLProtocol = -9800, /* SSL protocol error */ - errSSLNegotiation = -9801, /* Cipher Suite negotiation failure */ - errSSLFatalAlert = -9802, /* Fatal alert */ - errSSLWouldBlock = -9803, /* I/O would block (not fatal) */ - errSSLSessionNotFound = -9804, /* attempt to restore an unknown session */ - errSSLClosedGraceful = -9805, /* connection closed gracefully */ - errSSLClosedAbort = -9806, /* connection closed via error */ - errSSLXCertChainInvalid = -9807, /* invalid certificate chain */ - errSSLBadCert = -9808, /* bad certificate format */ - errSSLCrypto = -9809, /* underlying cryptographic error */ - errSSLInternal = -9810, /* Internal error */ - errSSLModuleAttach = -9811, /* module attach failure */ - errSSLUnknownRootCert = -9812, /* valid cert chain, untrusted root */ - errSSLNoRootCert = -9813, /* cert chain not verified by root */ - errSSLCertExpired = -9814, /* chain had an expired cert */ - errSSLCertNotYetValid = -9815, /* chain had a cert not yet valid */ - errSSLClosedNoNotify = -9816, /* server closed session with no notification */ - errSSLBufferOverflow = -9817, /* insufficient buffer provided */ - errSSLBadCipherSuite = -9818, /* bad SSLCipherSuite */ - - /* fatal errors detected by peer */ - errSSLPeerUnexpectedMsg = -9819, /* unexpected message received */ - errSSLPeerBadRecordMac = -9820, /* bad MAC */ - errSSLPeerDecryptionFail = -9821, /* decryption failed */ - errSSLPeerRecordOverflow = -9822, /* record overflow */ - errSSLPeerDecompressFail = -9823, /* decompression failure */ - errSSLPeerHandshakeFail = -9824, /* handshake failure */ - errSSLPeerBadCert = -9825, /* misc. bad certificate */ - errSSLPeerUnsupportedCert = -9826, /* bad unsupported cert format */ - errSSLPeerCertRevoked = -9827, /* certificate revoked */ - errSSLPeerCertExpired = -9828, /* certificate expired */ - errSSLPeerCertUnknown = -9829, /* unknown certificate */ - errSSLIllegalParam = -9830, /* illegal parameter */ - errSSLPeerUnknownCA = -9831, /* unknown Cert Authority */ - errSSLPeerAccessDenied = -9832, /* access denied */ - errSSLPeerDecodeError = -9833, /* decoding error */ - errSSLPeerDecryptError = -9834, /* decryption error */ - errSSLPeerExportRestriction = -9835, /* export restriction */ - errSSLPeerProtocolVersion = -9836, /* bad protocol version */ - errSSLPeerInsufficientSecurity = -9837, /* insufficient security */ - errSSLPeerInternalError = -9838, /* internal error */ - errSSLPeerUserCancelled = -9839, /* user canceled */ - errSSLPeerNoRenegotiation = -9840, /* no renegotiation allowed */ - - /* non-fatal result codes */ - errSSLPeerAuthCompleted = -9841, /* peer cert is valid, or was ignored if verification disabled */ - errSSLClientCertRequested = -9842, /* server has requested a client cert */ - - /* more errors detected by us */ - errSSLHostNameMismatch = -9843, /* peer host name mismatch */ - errSSLConnectionRefused = -9844, /* peer dropped connection before responding */ - errSSLDecryptionFail = -9845, /* decryption failure */ - errSSLBadRecordMac = -9846, /* bad MAC */ - errSSLRecordOverflow = -9847, /* record overflow */ - errSSLBadConfiguration = -9848, /* configuration error */ - errSSLUnexpectedRecord = -9849, /* unexpected (skipped) record in DTLS */ - errSSLWeakPeerEphemeralDHKey = -9850, /* weak ephemeral dh key */ - - /* non-fatal result codes */ - errSSLClientHelloReceived = -9851, /* SNI */ - - /* fatal errors resulting from transport or networking errors */ - errSSLTransportReset = -9852, /* transport (socket) shutdown, e.g., TCP RST or FIN. */ - errSSLNetworkTimeout = -9853, /* network timeout triggered */ - - /* fatal errors resulting from software misconfiguration */ - errSSLConfigurationFailed = -9854, /* TLS configuration failed */ - - /* additional errors */ - errSSLUnsupportedExtension = -9855, /* unsupported TLS extension */ - errSSLUnexpectedMessage = -9856, /* peer rejected unexpected message */ - errSSLDecompressFail = -9857, /* decompression failed */ - errSSLHandshakeFail = -9858, /* handshake failed */ - errSSLDecodeError = -9859, /* decode failed */ - errSSLInappropriateFallback = -9860, /* inappropriate fallback */ - errSSLMissingExtension = -9861, /* missing extension */ - errSSLBadCertificateStatusResponse = -9862, /* bad OCSP response */ - errSSLCertificateRequired = -9863, /* certificate required */ - errSSLUnknownPSKIdentity = -9864, /* unknown PSK identity */ - errSSLUnrecognizedName = -9865, /* unknown or unrecognized name */ -}; - /* DEPRECATED aliases for errSSLPeerAuthCompleted */ #define errSSLServerAuthCompleted errSSLPeerAuthCompleted #define errSSLClientAuthCompleted errSSLPeerAuthCompleted @@ -331,69 +212,69 @@ CF_ENUM(OSStatus) { /* DEPRECATED alias for the end of the error range */ #define errSSLLast errSSLUnexpectedRecord -typedef CF_ENUM(int, SSLProtocolSide) +typedef CF_CLOSED_ENUM(int, SSLProtocolSide) { - kSSLServerSide, - kSSLClientSide + kSSLServerSide CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), + kSSLClientSide CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) }; typedef CF_ENUM(int, SSLConnectionType) { - kSSLStreamType, - kSSLDatagramType + kSSLStreamType CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0), + kSSLDatagramType CF_ENUM_DEPRECATED(10_2, 10_15, 2_0, 13_0) }; /* - * Predefined TLS configurations constants + * Predefined TLS configuration constants */ /* Default configuration (has 3DES, no RC4) */ extern const CFStringRef kSSLSessionConfig_default -__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_13,__IPHONE_5_0,__IPHONE_11_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.13), ios(5.0, 11.0)); /* ATS v1 Config: TLS v1.2, only PFS ciphersuites */ extern const CFStringRef kSSLSessionConfig_ATSv1 -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* ATS v1 Config without PFS: TLS v1.2, include non PFS ciphersuites */ extern const CFStringRef kSSLSessionConfig_ATSv1_noPFS -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* TLS v1.2 to TLS v1.0, with default ciphersuites (no 3DES, no RC4) */ extern const CFStringRef kSSLSessionConfig_standard -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* TLS v1.2 to TLS v1.0, with default ciphersuites + RC4 + 3DES */ extern const CFStringRef kSSLSessionConfig_RC4_fallback -__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_13,__IPHONE_5_0,__IPHONE_11_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.13), ios(5.0, 11.0)); /* TLS v1.0 only, with default ciphersuites + fallback SCSV */ extern const CFStringRef kSSLSessionConfig_TLSv1_fallback -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* TLS v1.0, with default ciphersuites + RC4 + 3DES + fallback SCSV */ extern const CFStringRef kSSLSessionConfig_TLSv1_RC4_fallback -__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_13,__IPHONE_5_0,__IPHONE_11_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.13), ios(5.0, 11.0)); /* TLS v1.2 to TLS v1.0, defaults + RC4 + DHE ciphersuites */ extern const CFStringRef kSSLSessionConfig_legacy -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* TLS v1.2 to TLS v1.0, default + RC4 + DHE ciphersuites */ extern const CFStringRef kSSLSessionConfig_legacy_DHE -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* TLS v1.2, anonymous ciphersuites only */ extern const CFStringRef kSSLSessionConfig_anonymous -__OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* TLS v1.2 to TLS v1.0, has 3DES, no RC4 */ extern const CFStringRef kSSLSessionConfig_3DES_fallback -__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_13,__IPHONE_5_0,__IPHONE_11_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.13), ios(5.0, 11.0)); /* TLS v1.0, with default ciphersuites + 3DES, no RC4 */ extern const CFStringRef kSSLSessionConfig_TLSv1_3DES_fallback -__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_13,__IPHONE_5_0,__IPHONE_11_0); +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.13), ios(5.0, 11.0)); /****************** @@ -414,38 +295,53 @@ __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_13,__IPHONE_5_0,__IPHONE_11_0 */ /* - * Return the CFTypeID for SSLContext objects. + * @function SSLContextGetTypeID + * @abstract Return the CFTypeID for SSLContext objects. + * @return CFTypeId for SSLContext objects. */ CFTypeID SSLContextGetTypeID(void) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Create a new instance of an SSLContextRef using the specified allocator. + * @function SSLCreateContext + * @abstract Create a new instance of an SSLContextRef using the specified allocator. + * @param alloc Allocator to use for memory. + * @param protooclSide Client or server indication. + * @param connectionType Type of connection. + * @return A newly allocated SSLContextRef, or NULL on error. */ __nullable SSLContextRef SSLCreateContext(CFAllocatorRef __nullable alloc, SSLProtocolSide protocolSide, SSLConnectionType connectionType) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX /* - * Create a new session context. + * @function SSLNewContext + * @abstract Create a new session context. + * @note * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== * NOTE: this function is not available on iOS, and should be considered * deprecated on Mac OS X. Your code should use SSLCreateContext instead. + * + * @param isServer Flag indicating if the context is for the server (true) or client (false). + * @param contextPtr Pointer to SSLContextRef where result will be stored. + * @return errSecSuccess on success, alternative error on failure. */ OSStatus SSLNewContext (Boolean isServer, SSLContextRef * __nonnull CF_RETURNS_RETAINED contextPtr) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Dispose of a session context. + * @function SSLDisposeContext + * @abstract Dispose of a session context. + * @note * * ========================== * MAC OS X ONLY (DEPRECATED) @@ -453,134 +349,175 @@ SSLNewContext (Boolean isServer, * NOTE: this function is not available on iOS, and should be considered * deprecated on Mac OS X. Your code should use CFRelease to dispose a session * created with SSLCreateContext. + * + * @param context A SSLContextRef to deallocate and destroy. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLDisposeContext (SSLContextRef context) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); #endif /* MAC OS X */ /* - * Determine the state of an SSL/DTLS session. + * @function SSLGetSessionState + * @abstract Determine the state of an SSL/DTLS session. + * @param context A valid SSLContextRef. + * @param state Output pointer to store the SSLSessionState. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetSessionState (SSLContextRef context, SSLSessionState *state) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Set options for an SSL session. Must be called prior to SSLHandshake(); - * subsequently cannot be called while session is active. + * @function SSLSetSessionOption + * @abstract Set options for an SSL session. Must be called prior to SSLHandshake(); + * subsequently cannot be called while session is active. + * @param context A valid SSLContextRef. + * @param option An option enumeration value. + * @param value Value of the SSLSessionOption. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetSessionOption (SSLContextRef context, SSLSessionOption option, Boolean value) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.6, 10.15), ios(5.0, 13.0)); /* - * Determine current value for the specified option in a given SSL session. + * @function SSLGetSessionOption + * @abstract Determine current value for the specified option in a given SSL session. + * @param context A valid SSLContextRef. + * @param option An option enumeration value. + * @param value Pointer to a Boolean where the SSLSessionOption value is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetSessionOption (SSLContextRef context, SSLSessionOption option, Boolean *value) - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.6, 10.15), ios(5.0, 13.0)); /******************************************************************** *** Session context configuration, common to client and servers. *** ********************************************************************/ /* - * Specify functions which do the network I/O. Must be called prior - * to SSLHandshake(); subsequently cannot be called while a session is - * active. + * @function SSLSetIOFuncs + * @abstract Specify functions which do the network I/O. Must be called prior + * to SSLHandshake(); subsequently cannot be called while a session is + * active. + * @param context A valid SSLContextRef. + * @param readFunc Pointer to a SSLReadFunc. + * @param writeFunc Pointer to a SSLWriteFunc. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetIOFuncs (SSLContextRef context, SSLReadFunc readFunc, SSLWriteFunc writeFunc) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Set a predefined configuration for the SSL Session - * - * This currently affect enabled protocol versions, - * enabled ciphersuites, and the kSSLSessionOptionFallback - * session option. + * @function SSLSetSessionConfig + * @absttact Set a predefined configuration for the SSL Session + * @note This currently affect enabled protocol versions, + * enabled ciphersuites, and the kSSLSessionOptionFallback + * session option. + * @param context A valid SSLContextRef. + * @param config String name of constant TLS handshake configuration, e.g., kSSLSessionConfig_standard. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetSessionConfig(SSLContextRef context, CFStringRef config) - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.12, 10.15), ios(10.0, 13.0)); /* - * Set the minimum SSL protocol version allowed. Optional. - * The default is the lower supported protocol. - * - * This can only be called when no session is active. + * @function SSLSetProtocolVersionMin + * @abstract Set the minimum SSL protocol version allowed. Optional. + * The default is the lower supported protocol. + * @note This can only be called when no session is active. * - * For TLS contexts, legal values for minVersion are : - * kSSLProtocol3 + * For TLS contexts, legal values for minVersion are : + * kSSLProtocol3 * kTLSProtocol1 * kTLSProtocol11 * kTLSProtocol12 * - * For DTLS contexts, legal values for minVersion are : + * For DTLS contexts, legal values for minVersion are : * kDTLSProtocol1 + * @param context A valid SSLContextRef. + * @param minVersion Minimum TLS protocol version. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetProtocolVersionMin (SSLContextRef context, SSLProtocol minVersion) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Get minimum protocol version allowed + * @function SSLGetProtocolVersionMin + * @abstract Get minimum protocol version allowed + * @param context A valid SSLContextRef. + * @param minVersion Pointer to SSLProtocol value where the minimum protocol version is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetProtocolVersionMin (SSLContextRef context, SSLProtocol *minVersion) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Set the maximum SSL protocol version allowed. Optional. - * The default is the highest supported protocol. + * @function SSLSetProtocolVersionMax + * @abstract Set the maximum SSL protocol version allowed. Optional. + * The default is the highest supported protocol. + * @note + * This can only be called when no session is active. * - * This can only be called when no session is active. - * - * For TLS contexts, legal values for maxVersion are : + * For TLS contexts, legal values for maxVersion are : * kSSLProtocol3 * kTLSProtocol1 * kTLSProtocol11 * kTLSProtocol12 * - * For DTLS contexts, legal values for maxVersion are : + * For DTLS contexts, legal values for maxVersion are : * kDTLSProtocol1 + * @param context A valid SSLContextRef. + * @param maxVersion Maximum TLS protocol version. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetProtocolVersionMax (SSLContextRef context, SSLProtocol maxVersion) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Get maximum protocol version allowed + * @function SSLGetProtocolVersionMax + * @abstract Get maximum protocol version allowed + * @param context A valid SSLContextRef. + * @param maxVersion Pointer to SSLProtocol value where the maximum protocol version is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetProtocolVersionMax (SSLContextRef context, SSLProtocol *maxVersion) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX /* - * Set allowed SSL protocol versions. Optional. - * Specifying kSSLProtocolAll for SSLSetProtocolVersionEnabled results in - * specified 'enable' boolean to be applied to all supported protocols. - * The default is "all supported protocols are enabled". - * This can only be called when no session is active. + * @function SSLSetProtocolVersionEnabled + * @abstract Set allowed SSL protocol versions. Optional. + * @discussion Specifying kSSLProtocolAll for SSLSetProtocolVersionEnabled results in + * specified 'enable' boolean to be applied to all supported protocols. + * The default is "all supported protocols are enabled". + * This can only be called when no session is active. * - * Legal values for protocol are : + * Legal values for protocol are : * kSSLProtocol2 * kSSLProtocol3 * kTLSProtocol1 @@ -589,15 +526,19 @@ SSLGetProtocolVersionMax (SSLContextRef context, * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered + * @note this function is not available on iOS, and should be considered * deprecated on Mac OS X. You can use SSLSetProtocolVersionMin and/or * SSLSetProtocolVersionMax to specify which protocols are enabled. + * @param context A valid SSLContextRef. + * @param protocol A SSLProtocol enumerated value. + * @param enable Boolean to enable or disable the designated protocol. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetProtocolVersionEnabled (SSLContextRef context, SSLProtocol protocol, Boolean enable) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* * Obtain a value specified in SSLSetProtocolVersionEnabled. @@ -613,303 +554,415 @@ OSStatus SSLGetProtocolVersionEnabled(SSLContextRef context, SSLProtocol protocol, Boolean *enable) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown, - * in which case the highest possible version is attempted, but a lower - * version is accepted if the peer requires it. - * SSLSetProtocolVersion cannot be called when a session is active. + * @function SSLSetProtocolVersion + * @abstract Get/set SSL protocol version; optional. Default is kSSLProtocolUnknown, + * in which case the highest possible version is attempted, but a lower + * version is accepted if the peer requires it. + * @discussion SSLSetProtocolVersion cannot be called when a session is active. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and deprecated on Mac OS X 10.8. - * Use SSLSetProtocolVersionMin and/or SSLSetProtocolVersionMax to specify - * which protocols are enabled. + * @note this function is not available on iOS, and deprecated on Mac OS X 10.8. + * Use SSLSetProtocolVersionMin and/or SSLSetProtocolVersionMax to specify + * which protocols are enabled. + * @param context A valid SSLContextRef. + * @param protocol A SSLProtocol enumerated value. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetProtocolVersion (SSLContextRef context, SSLProtocol version) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_8,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.8)); /* - * Obtain the protocol version specified in SSLSetProtocolVersion. - * If SSLSetProtocolVersionEnabled() has been called for this session, - * SSLGetProtocolVersion() may return errSecParam if the protocol enable - * state can not be represented by the SSLProtocol enums (e.g., - * SSL2 and TLS1 enabled, SSL3 disabled). + * @function SSLGetProtocolVersion + * @abstract Obtain the protocol version specified in SSLSetProtocolVersion. + * @discussion If SSLSetProtocolVersionEnabled() has been called for this session, + * SSLGetProtocolVersion() may return errSecParam if the protocol enable + * state can not be represented by the SSLProtocol enums (e.g., + * SSL2 and TLS1 enabled, SSL3 disabled). * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and deprecated on Mac OS X 10.8. - * Use SSLGetProtocolVersionMin and/or SSLGetProtocolVersionMax to check - * whether a protocol is enabled. + * @note this function is not available on iOS, and deprecated on Mac OS X 10.8. + * Use SSLGetProtocolVersionMin and/or SSLGetProtocolVersionMax to check + * whether a protocol is enabled. + * @param context A valid SSLContextRef. + * @param protocol A SSLProtocol enumerated value pointer to store the protocol version. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetProtocolVersion (SSLContextRef context, SSLProtocol *protocol) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_8,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.8)); #endif /* MAC OS X */ /* - * Specify this connection's certificate(s). This is mandatory for - * server connections, optional for clients. Specifying a certificate - * for a client enables SSL client-side authentication. The end-entity - * cert is in certRefs[0]. Specifying a root cert is optional; if it's - * not specified, the root cert which verifies the cert chain specified - * here must be present in the system-wide set of trusted anchor certs. + * @function SSLSetCertificate + * @abstract Specify this connection's certificate(s). + * @discussion This is mandatory for server connections,and optional for + * clients. Specifying a certificate for a client enables SSL client-side + * authentication. The end-entity cert is in certRefs[0]. Specifying a root + * cert is optional; if it's not specified, the root cert which verifies the + * cert chain specified here must be present in the system-wide set of trusted + * anchor certs. * - * The certRefs argument is a CFArray containing SecCertificateRefs, - * except for certRefs[0], which is a SecIdentityRef. + * The certRefs argument is a CFArray containing SecCertificateRefs, + * except for certRefs[0], which is a SecIdentityRef. * - * Must be called prior to SSLHandshake(), or immediately after - * SSLHandshake has returned errSSLClientCertRequested (i.e. before the - * handshake is resumed by calling SSLHandshake again.) + * Must be called prior to SSLHandshake(), or immediately after + * SSLHandshake has returned errSSLClientCertRequested (i.e. before the + * handshake is resumed by calling SSLHandshake again.) * - * SecureTransport assumes the following: + * SecureTransport assumes the following: * - * -- The certRef references remain valid for the lifetime of the session. - * -- The certificate specified in certRefs[0] is capable of signing. - * -- The required capabilities of the certRef[0], and of the optional cert - * specified in SSLSetEncryptionCertificate (see below), are highly - * dependent on the application. For example, to work as a server with - * Netscape clients, the cert specified here must be capable of both - * signing and encrypting. + * -- The certRef references remain valid for the lifetime of the session. + * -- The certificate specified in certRefs[0] is capable of signing. + * -- The required capabilities of the certRef[0], and of the optional cert + * specified in SSLSetEncryptionCertificate (see below), are highly + * dependent on the application. For example, to work as a server with + * Netscape clients, the cert specified here must be capable of both + * signing and encrypting. + * @param context A valid SSLContextRef. + * @param certRefs An array of SecCertificateRef instances. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetCertificate (SSLContextRef context, CFArrayRef _Nullable certRefs) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Specify I/O connection - a socket, endpoint, etc., which is - * managed by caller. On the client side, it's assumed that communication - * has been established with the desired server on this connection. - * On the server side, it's assumed that an incoming client request - * has been established. + * @function SSLSetConnection + * @abstract Specify I/O connection - a socket, endpoint, etc., which is + * managed by caller. + * @discussion On the client side, it's assumed that communication + * has been established with the desired server on this connection. + * On the server side, it's assumed that an incoming client request + * has been established. * - * Must be called prior to SSLHandshake(); subsequently can only be - * called when no session is active. + * Must be called prior to SSLHandshake(); subsequently can only be + * called when no session is active. + * @param context A valid SSLContextRef. + * @param connection A SSLConnectionRef. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetConnection (SSLContextRef context, SSLConnectionRef __nullable connection) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); +/* + * @function SSLGetConnection + * @abstract Retrieve the I/O connection managed managed by the caller. + * @param context A valid SSLContextRef. + * @param connection A SSLConnectionRef pointer. + * @result errSecSuccess on success, alternative error on failure. + */ OSStatus SSLGetConnection (SSLContextRef context, SSLConnectionRef * __nonnull CF_RETURNS_NOT_RETAINED connection) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Specify the fully qualified doman name of the peer, e.g., "store.apple.com." - * Optional; used to verify the common name field in peer's certificate. - * Name is in the form of a C string; NULL termination optional, i.e., - * peerName[peerNameLen+1] may or may not have a NULL. In any case peerNameLen - * is the number of bytes of the peer domain name. + * @function SSLSetPeerDomainName + * @abstract Specify the fully qualified doman name of the peer, e.g., "store.apple.com." + * @discussion Optional; used to verify the common name field in peer's certificate. + * Name is in the form of a C string; NULL termination optional, i.e., + * peerName[peerNameLen+1] may or may not have a NULL. In any case peerNameLen + * is the number of bytes of the peer domain name. + * @param context A valid SSLContextRef. + * @param peerName A C string carrying the peer domain name. + * @param peerNameLen Length of the peer domain name string. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetPeerDomainName (SSLContextRef context, const char * __nullable peerName, size_t peerNameLen) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Determine the buffer size needed for SSLGetPeerDomainName(). + * @function SSLGetPeerDomainNameLength + * @abstract Determine the buffer size needed for SSLGetPeerDomainName(). + * @param context A valid SSLContextRef. + * @param peerNameLen Pointer to where the length of the peer domain name string is stored + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetPeerDomainNameLength (SSLContextRef context, size_t *peerNameLen) // RETURNED - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Obtain the value specified in SSLSetPeerDomainName(). + * @function SSLGetPeerDomainName + * @abstract Obtain the value specified in SSLSetPeerDomainName(). + * @param context A valid SSLContextRef. + * @param peerName Pointer to where the peer domain name is stored. + * @param peerNameLen Pointer to where the length of the peer domain name string is stored, + * up to the length specified by peerNameLen (on input). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetPeerDomainName (SSLContextRef context, char *peerName, // returned here size_t *peerNameLen) // IN/OUT - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); - + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Determine the buffer size needed for SSLCopyRequestedPeerNameLength(). + * @function SSLCopyRequestedPeerNameLength + * @abstract [Server Only] obtain the hostname specified by the client in the ServerName extension (SNI) + * @param context A valid SSLContextRef. + * @param peerNameLen Pointer to where the length of the requested peer domain name string + * is stored, up to the length specified by peerNameLen (on input). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus -SSLCopyRequestedPeerName (SSLContextRef context, - char *peerName, - size_t *peerNameLen) - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); +SSLCopyRequestedPeerNameLength (SSLContextRef ctx, + size_t *peerNameLen) + __SECURETRANSPORT_API_DEPRECATED(macos(10.11, 10.15), ios(9.0, 13.0)); /* - * Server Only: obtain the hostname specified by the client in the ServerName extension (SNI) + * @function SSLCopyRequestedPeerName + * @abstract Determine the buffer size needed for SSLCopyRequestedPeerNameLength(). + * @param context A valid SSLContextRef. + * @param peerName Pointer to where the requested peer domain name is stored. + * @param peerNameLen Pointer to where the length of the requested peer domain name string + * is stored, up to the length specified by peerNameLen (on input). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus -SSLCopyRequestedPeerNameLength (SSLContextRef ctx, - size_t *peerNameLen) - __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); +SSLCopyRequestedPeerName (SSLContextRef context, + char *peerName, + size_t *peerNameLen) + __SECURETRANSPORT_API_DEPRECATED(macos(10.11, 10.15), ios(9.0, 13.0)); /* - * Specify the Datagram TLS Hello Cookie. - * This is to be called for server side only and is optional. - * The default is a zero len cookie. The maximum cookieLen is 32 bytes. + * @function SSLSetDatagramHelloCookie + * @abstract Specify the Datagram TLS Hello Cookie. + * @discussion This is to be called for server side only and is optional. + * The default is a zero len cookie. The maximum cookieLen is 32 bytes. + * @param context A valid SSLContextRef. + * @param cookie Pointer to opaque cookie data. + * @param cookieLen Length of cookie data. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetDatagramHelloCookie (SSLContextRef dtlsContext, const void * __nullable cookie, size_t cookieLen) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Specify the maximum record size, including all DTLS record headers. - * This should be set appropriately to avoid fragmentation - * of Datagrams during handshake, as fragmented datagrams may - * be dropped by some network. - * This is for Datagram TLS only + * @function SSLSetMaxDatagramRecordSize + * @abstract Specify the maximum record size, including all DTLS record headers. + * @discussion This should be set appropriately to avoid fragmentation + * of Datagrams during handshake, as fragmented datagrams may + * be dropped by some network. + * @note This is for Datagram TLS only + * @param context A valid SSLContextRef. + * @param maxSize Maximum size of datagram record(s). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetMaxDatagramRecordSize (SSLContextRef dtlsContext, size_t maxSize) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Get the maximum record size, including all Datagram TLS record headers. - * This is for Datagram TLS only + * @function SSLGetMaxDatagramRecordSize + * @abstract Get the maximum record size, including all Datagram TLS record headers. + * @note This is for Datagram TLS only + * @param context A valid SSLContextRef. + * @param maxSize Pointer where maximum size of datagram record(s) is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetMaxDatagramRecordSize (SSLContextRef dtlsContext, size_t *maxSize) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Obtain the actual negotiated protocol version of the active - * session, which may be different that the value specified in - * SSLSetProtocolVersion(). Returns kSSLProtocolUnknown if no - * SSL session is in progress. + * @function SSLGetNegotiatedProtocolVersion + * @abstract Obtain the actual negotiated protocol version of the active + * session, which may be different that the value specified in + * SSLSetProtocolVersion(). Returns kSSLProtocolUnknown if no + * SSL session is in progress. + * @param context A valid SSLContextRef. + * @param protocol Pointer where negotiated SSLProtocol is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetNegotiatedProtocolVersion (SSLContextRef context, SSLProtocol *protocol) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Determine number and values of all of the SSLCipherSuites we support. - * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in - * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow - * will be returned. + * @function SSLGetNumberSupportedCiphers + * @abstract Determine number and values of all of the SSLCipherSuites we support. + * Caller allocates output buffer for SSLGetSupportedCiphers() and passes in + * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow + * will be returned. + * @param context A valid SSLContextRef. + * @param numCiphers Pointer where number of supported ciphers is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetNumberSupportedCiphers (SSLContextRef context, size_t *numCiphers) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); +/* + * @function SSLGetSupportedCiphers + * @abstract Get the supported ciphers. + * @param context A valid SSLContextRef. + * @param ciphers Pointer to array of SSLCipherSuite values where supported ciphersuites + * are stored. This array size is specified by the input value of numCiphers. + * @param numCiphers Pointer where number of supported ciphers is stored. + * @result errSecSuccess on success, alternative error on failure. + */ OSStatus SSLGetSupportedCiphers (SSLContextRef context, SSLCipherSuite *ciphers, /* RETURNED */ size_t *numCiphers) /* IN/OUT */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Specify a (typically) restricted set of SSLCipherSuites to be enabled by - * the current SSLContext. Can only be called when no session is active. Default - * set of enabled SSLCipherSuites is the same as the complete set of supported - * SSLCipherSuites as obtained by SSLGetSupportedCiphers(). + * @function SSLGetNumberEnabledCiphers + * @abstract Determine number and values of all of the SSLCipherSuites currently enabled. + * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in + * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow + * will be returned. + * @param context A valid SSLContextRef. + * @param numCiphers Pointer where number of enabled ciphers is stored. + * @result errSecSuccess on success, alternative error on failure. + */ +OSStatus +SSLGetNumberEnabledCiphers (SSLContextRef context, + size_t *numCiphers) +__SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); + +/* + * @function SSLSetEnabledCiphers + * @abstract Specify a (typically) restricted set of SSLCipherSuites to be enabled by + * the current SSLContext. Can only be called when no session is active. Default + * set of enabled SSLCipherSuites is the same as the complete set of supported + * SSLCipherSuites as obtained by SSLGetSupportedCiphers(). + * @param context A valid SSLContextRef. + * @param ciphers Array of enabled SSLCipherSuite values. This array size is specified + * by the input value of numCiphers. + * @param numCiphers Pointer where number of enabled ciphers is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetEnabledCiphers (SSLContextRef context, const SSLCipherSuite *ciphers, size_t numCiphers) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Determine number and values of all of the SSLCipherSuites currently enabled. - * Caller allocates output buffer for SSLGetEnabledCiphers() and passes in - * its size in *numCiphers. If supplied buffer is too small, errSSLBufferOverflow - * will be returned. + * @function SSLGetEnabledCiphers + * @abstract Get the set of supported ciphersuites. + * @param context A valid SSLContextRef. + * @param ciphers Pointer to array of SSLCipherSuite values where enabled ciphersuites + * are stored. This array size is specified by the input value of numCiphers. + * @param numCiphers Pointer where number of enabled ciphers is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus -SSLGetNumberEnabledCiphers (SSLContextRef context, - size_t *numCiphers) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); - -OSStatus SSLGetEnabledCiphers (SSLContextRef context, SSLCipherSuite *ciphers, /* RETURNED */ size_t *numCiphers) /* IN/OUT */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Forcibly enable or disable session ticket resumption. By default, session tickets - * are disabled. + * @function SSLSetSessionTicketsEnabled + * @abstract Forcibly enable or disable session ticket resumption. + * @note By default, session tickets are disabled. + * @param context A valid SSLContextRef. + * @param enabled Boolean indicating if ticket support is enabled (true) or not (false). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetSessionTicketsEnabled (SSLContextRef context, Boolean enabled) - __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.13, 10.15), ios(11.0, 13.0)); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX /* - * Enable/disable peer certificate chain validation. Default is enabled. - * If caller disables, it is the caller's responsibility to call - * SSLCopyPeerCertificates() upon successful completion of the handshake - * and then to perform external validation of the peer certificate - * chain before proceeding with data transfer. + * @function SSLSetEnableCertVerify + * @abstract Enable/disable peer certificate chain validation. Default is enabled. + * @discussion If caller disables, it is the caller's responsibility to call + * SSLCopyPeerCertificates() upon successful completion of the handshake + * and then to perform external validation of the peer certificate + * chain before proceeding with data transfer. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To disable peer certificate chain validation, you - * can instead use SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth - * to true. This will disable verification and cause SSLHandshake to return with - * an errSSLServerAuthCompleted result when the peer certificates have been - * received; at that time, you can choose to evaluate peer trust yourself, or - * simply call SSLHandshake again to proceed with the handshake. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To disable peer certificate chain validation, you + * can instead use SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth + * to true. This will disable verification and cause SSLHandshake to return with + * an errSSLServerAuthCompleted result when the peer certificates have been + * received; at that time, you can choose to evaluate peer trust yourself, or + * simply call SSLHandshake again to proceed with the handshake. + * @param context A valid SSLContextRef. + * @param enableVerify Boolean indicating if certificate verifiation is enabled (true) or disabled (false). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetEnableCertVerify (SSLContextRef context, Boolean enableVerify) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Check whether peer certificate chain validation is enabled. + * @function SSLGetEnableCertVerify + * @abstract Check whether peer certificate chain validation is enabled. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To check whether peer certificate chain validation - * is enabled in a context, call SSLGetSessionOption to obtain the value of - * the kSSLSessionOptionBreakOnServerAuth session option flag. If the value - * of this option flag is true, then verification is disabled. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To check whether peer certificate chain validation + * is enabled in a context, call SSLGetSessionOption to obtain the value of + * the kSSLSessionOptionBreakOnServerAuth session option flag. If the value + * of this option flag is true, then verification is disabled. + * @param context A valid SSLContextRef. + * @param enableVerify Pointer to Boolean where enable bit is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetEnableCertVerify (SSLContextRef context, Boolean *enableVerify) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Specify the option of ignoring certificates' "expired" times. - * This is a common failure in the real SSL world. Default setting for this - * flag is false, meaning expired certs result in an errSSLCertExpired error. + * @function SSLSetAllowsExpiredCerts + * @abstract Specify the option of ignoring certificates' "expired" times. + * @discussion This is a common failure in the real SSL world. Default setting for this + * flag is false, meaning expired certs result in an errSSLCertExpired error. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To ignore expired certificate errors, first disable - * Secure Transport's automatic verification of peer certificates by calling - * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When - * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, - * your code should obtain the SecTrustRef for the peer's certificates and - * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). - * The SecTrustSetOptions function allows you to specify that the expiration - * status of certificates should be ignored for this evaluation. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To ignore expired certificate errors, first disable + * Secure Transport's automatic verification of peer certificates by calling + * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When + * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, + * your code should obtain the SecTrustRef for the peer's certificates and + * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). + * The SecTrustSetOptions function allows you to specify that the expiration + * status of certificates should be ignored for this evaluation. * * Example: * @@ -953,458 +1006,582 @@ SSLGetEnableCertVerify (SSLContextRef context, * } // errSSLServerAuthCompleted * * } while (status == errSSLWouldBlock); - * + * @param context A valid SSLContextRef. + * @param allowsExpired Boolean indicating if expired certificates are allowed (true) or not (false). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetAllowsExpiredCerts (SSLContextRef context, Boolean allowsExpired) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Obtain the current value of an SSLContext's "allowExpiredCerts" flag. + * @function SSLGetAllowsExpiredCerts + * @abstract Obtain the current value of an SSLContext's "allowExpiredCerts" flag. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. + * @param context A valid SSLContextRef. + * @param allowsExpired Pointer to Boolean where the expired certificate allowance Boolean is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetAllowsExpiredCerts (SSLContextRef context, Boolean *allowsExpired) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Similar to SSLSetAllowsExpiredCerts, SSLSetAllowsExpiredRoots allows the - * option of ignoring "expired" status for root certificates only. - * Default setting is false, i.e., expired root certs result in an - * errSSLCertExpired error. + * @function SSLSetAllowsExpiredRoots + * @abstract Similar to SSLSetAllowsExpiredCerts, SSLSetAllowsExpiredRoots allows the + * option of ignoring "expired" status for root certificates only. + * @discussion Default setting is false, i.e., expired root certs result in an + * errSSLCertExpired error. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To ignore expired certificate errors, first disable - * Secure Transport's automatic verification of peer certificates by calling - * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When - * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, - * your code should obtain the SecTrustRef for the peer's certificates and - * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). - * The SecTrustSetOptions function allows you to specify that the expiration - * status of certificates should be ignored for this evaluation. - * - * See the description of the SSLSetAllowsExpiredCerts function (above) - * for a code example. The kSecTrustOptionAllowExpiredRoot option can be used - * instead of kSecTrustOptionAllowExpired to allow expired roots only. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To ignore expired certificate errors, first disable + * Secure Transport's automatic verification of peer certificates by calling + * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When + * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, + * your code should obtain the SecTrustRef for the peer's certificates and + * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). + * The SecTrustSetOptions function allows you to specify that the expiration + * status of certificates should be ignored for this evaluation. + * + * See the description of the SSLSetAllowsExpiredCerts function (above) + * for a code example. The kSecTrustOptionAllowExpiredRoot option can be used + * instead of kSecTrustOptionAllowExpired to allow expired roots only. + * @param context A valid SSLContextRef. + * @param allowsExpired Boolean indicating if expired roots are allowed. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetAllowsExpiredRoots (SSLContextRef context, Boolean allowsExpired) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Obtain the current value of an SSLContext's "allow expired roots" flag. + * @function SSLGetAllowsExpiredRoots + * @abstract Obtain the current value of an SSLContext's "allow expired roots" flag. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. + * @param context A valid SSLContextRef. + * @param allowsExpired Pointer to Boolean where the expired root certificate allowance + * Boolean is stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetAllowsExpiredRoots (SSLContextRef context, Boolean *allowsExpired) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Specify option of allowing for an unknown root cert, i.e., one which + * @function SSLSetAllowsAnyRoot + * @abstract Specify option of allowing for an unknown root cert, i.e., one which * this software can not verify as one of a list of known good root certs. - * Default for this flag is false, in which case one of the following two - * errors may occur: - * -- The peer returns a cert chain with a root cert, and the chain - * verifies to that root, but the root is not one of our trusted - * roots. This results in errSSLUnknownRootCert on handshake. - * -- The peer returns a cert chain which does not contain a root cert, - * and we can't verify the chain to one of our trusted roots. This - * results in errSSLNoRootCert on handshake. - * - * Both of these error conditions are ignored when the AllowAnyRoot flag is - * true, allowing connection to a totally untrusted peer. + * @discussion Default for this flag is false, in which case one of the following two + * errors may occur: + * -- The peer returns a cert chain with a root cert, and the chain + * verifies to that root, but the root is not one of our trusted + * roots. This results in errSSLUnknownRootCert on handshake. + * -- The peer returns a cert chain which does not contain a root cert, + * and we can't verify the chain to one of our trusted roots. This + * results in errSSLNoRootCert on handshake. + * + * Both of these error conditions are ignored when the AllowAnyRoot flag is + * true, allowing connection to a totally untrusted peer. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To ignore unknown root cert errors, first disable - * Secure Transport's automatic verification of peer certificates by calling - * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When - * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, - * your code should obtain the SecTrustRef for the peer's certificates and - * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). - * - * See the description of the SSLSetAllowsExpiredCerts function (above) - * for a code example. Note that an unknown root certificate will cause - * SecTrustEvaluate to report kSecTrustResultRecoverableTrustFailure as the - * trust result. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To ignore unknown root cert errors, first disable + * Secure Transport's automatic verification of peer certificates by calling + * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When + * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, + * your code should obtain the SecTrustRef for the peer's certificates and + * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). + * + * See the description of the SSLSetAllowsExpiredCerts function (above) + * for a code example. Note that an unknown root certificate will cause + * SecTrustEvaluate to report kSecTrustResultRecoverableTrustFailure as the + * trust result. + * @param context A valid SSLContextRef. + * @param anyRoot Boolean indicating if any root is allowed (true) or not (false). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetAllowsAnyRoot (SSLContextRef context, Boolean anyRoot) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Obtain the current value of an SSLContext's "allow any root" flag. + * @function SSLGetAllowsAnyRoot + * @abstract Obtain the current value of an SSLContext's "allow any root" flag. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. + * @param context A valid SSLContextRef. + * @param anyRoot Pointer to Boolean to store any root allowance Boolean. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetAllowsAnyRoot (SSLContextRef context, Boolean *anyRoot) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Augment or replace the system's default trusted root certificate set - * for this session. If replaceExisting is true, the specified roots will - * be the only roots which are trusted during this session. If replaceExisting - * is false, the specified roots will be added to the current set of trusted - * root certs. If this function has never been called, the current trusted - * root set is the same as the system's default trusted root set. - * Successive calls with replaceExisting false result in accumulation - * of additional root certs. + * @function SSLSetTrustedRoots + * @abstract Augment or replace the system's default trusted root certificate set + * for this session. + * @discussion If replaceExisting is true, the specified roots will + * be the only roots which are trusted during this session. If replaceExisting + * is false, the specified roots will be added to the current set of trusted + * root certs. If this function has never been called, the current trusted + * root set is the same as the system's default trusted root set. + * Successive calls with replaceExisting false result in accumulation + * of additional root certs. * - * The trustedRoots array contains SecCertificateRefs. + * The trustedRoots array contains SecCertificateRefs. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To trust specific roots in a session, first disable - * Secure Transport's automatic verification of peer certificates by calling - * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When - * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, - * your code should obtain the SecTrustRef for the peer's certificates and - * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). - * - * See the description of the SSLSetAllowsExpiredCerts function (above) - * for a code example. You can call SecTrustSetAnchorCertificates to - * augment the system's trusted root set, or SecTrustSetAnchorCertificatesOnly - * to make these the only trusted roots, prior to calling SecTrustEvaluate. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To trust specific roots in a session, first disable + * Secure Transport's automatic verification of peer certificates by calling + * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. When + * SSLHandshake subsequently returns an errSSLServerAuthCompleted result, + * your code should obtain the SecTrustRef for the peer's certificates and + * perform a custom trust evaluation with SecTrust APIs (see SecTrust.h). + * + * See the description of the SSLSetAllowsExpiredCerts function (above) + * for a code example. You can call SecTrustSetAnchorCertificates to + * augment the system's trusted root set, or SecTrustSetAnchorCertificatesOnly + * to make these the only trusted roots, prior to calling SecTrustEvaluate. + * @param context A valid SSLContextRef. + * @param trustedRoots Array of SecCertificateRef roots. + * @param replaceExisting Boolean indicating if provided roots should override all others for this connection. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetTrustedRoots (SSLContextRef context, CFArrayRef trustedRoots, Boolean replaceExisting) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); /* - * Obtain an array of SecCertificateRefs representing the current - * set of trusted roots. If SSLSetTrustedRoots() has never been called - * for this session, this returns the system's default root set. - * - * Caller must CFRelease the returned CFArray. + * @function SSLCopyTrustedRoots + * @abstract Obtain an array of SecCertificateRefs representing the current + * set of trusted roots. + * @discussion If SSLSetTrustedRoots() has never been called + * for this session, this returns the system's default root set. + * Caller must CFRelease the returned CFArray. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To get the current set of trusted roots, call the - * SSLCopyPeerTrust function to obtain the SecTrustRef for the peer certificate - * chain, then SecTrustCopyCustomAnchorCertificates (see SecTrust.h). + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To get the current set of trusted roots, call the + * SSLCopyPeerTrust function to obtain the SecTrustRef for the peer certificate + * chain, then SecTrustCopyCustomAnchorCertificates (see SecTrust.h). + * @param context A valid SSLContextRef. + * @param trustedRoots Array of SecCertificateRef roots. + * @param replaceExisting Boolean indicating if provided roots should override all others for this connection. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLCopyTrustedRoots (SSLContextRef context, CFArrayRef * __nonnull CF_RETURNS_RETAINED trustedRoots) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.5, 10.9)); /* - * Request peer certificates. Valid anytime, subsequent to a handshake attempt. - * - * The certs argument is a CFArray containing SecCertificateRefs. - * Caller must CFRelease the returned array. + * @function SSLCopyPeerCertificates + * @abstract Request peer certificates. Valid anytime, subsequent to a handshake attempt. + * @discussion The certs argument is a CFArray containing SecCertificateRefs. + * Caller must CFRelease the returned array. * - * The cert at index 0 of the returned array is the subject (end - * entity) cert; the root cert (or the closest cert to it) is at - * the end of the returned array. + * The cert at index 0 of the returned array is the subject (end + * entity) cert; the root cert (or the closest cert to it) is at + * the end of the returned array. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. To get peer certificates, call SSLCopyPeerTrust - * to obtain the SecTrustRef for the peer certificate chain, then use the - * SecTrustGetCertificateCount and SecTrustGetCertificateAtIndex functions - * to retrieve individual certificates in the chain (see SecTrust.h). + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. To get peer certificates, call SSLCopyPeerTrust + * to obtain the SecTrustRef for the peer certificate chain, then use the + * SecTrustGetCertificateCount and SecTrustGetCertificateAtIndex functions + * to retrieve individual certificates in the chain (see SecTrust.h). + * @param context A valid SSLContextRef. + * @param certs Pointer to CFArrayRef that will store a reference to the peer's certificates. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLCopyPeerCertificates (SSLContextRef context, CFArrayRef * __nonnull CF_RETURNS_RETAINED certs) /* RETURNED */ - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.5, 10.9)); #endif /* MAC OS X */ /* - * Obtain a SecTrustRef representing peer certificates. Valid anytime, - * subsequent to a handshake attempt. Caller must CFRelease the returned - * trust reference. - * - * The returned trust reference will have already been evaluated for you, - * unless one of the following is true: - * - Your code has disabled automatic certificate verification, by calling - * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. - * - Your code has called SSLSetPeerID, and this session has been resumed - * from an earlier cached session. + * @function SSLCopyPeerTrust + * @abstract Obtain a SecTrustRef representing peer certificates. Valid anytime, + * subsequent to a handshake attempt. Caller must CFRelease the returned + * trust reference. + * @discussion The returned trust reference will have already been evaluated for + * you, unless one of the following is true: + * - Your code has disabled automatic certificate verification, by calling + * SSLSetSessionOption to set kSSLSessionOptionBreakOnServerAuth to true. + * - Your code has called SSLSetPeerID, and this session has been resumed + * from an earlier cached session. * - * In these cases, your code should call SecTrustEvaluate prior to - * examining the peer certificate chain or trust results (see SecTrust.h). + * In these cases, your code should call SecTrustEvaluate prior to + * examining the peer certificate chain or trust results (see SecTrust.h). * - * NOTE: if you have not called SSLHandshake at least once prior to - * calling this function, the returned trust reference will be NULL. + * @note If you have not called SSLHandshake at least once prior to + * calling this function, the returned trust reference will be NULL. + * @param context A valid SSLContextRef. + * @param trust Pointer to SecTrustRef where peer's SecTrustRef is copied (retained). + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLCopyPeerTrust (SSLContextRef context, SecTrustRef * __nonnull CF_RETURNS_RETAINED trust) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.6, 10.15), ios(5.0, 13.0)); /* - * Specify some data, opaque to this library, which is sufficient - * to uniquely identify the peer of the current session. An example - * would be IP address and port, stored in some caller-private manner. - * To be optionally called prior to SSLHandshake for the current - * session. This is mandatory if this session is to be resumable. + * @function SSLSetPeerID + * @discussion Specify some data, opaque to this library, which is sufficient + * to uniquely identify the peer of the current session. An example + * would be IP address and port, stored in some caller-private manner. + * To be optionally called prior to SSLHandshake for the current + * session. This is mandatory if this session is to be resumable. * - * SecureTransport allocates its own copy of the incoming peerID. The - * data provided in *peerID, while opaque to SecureTransport, is used - * in a byte-for-byte compare to other previous peerID values set by the - * current application. Matching peerID blobs result in SecureTransport - * attempting to resume an SSL session with the same parameters as used - * in the previous session which specified the same peerID bytes. + * SecureTransport allocates its own copy of the incoming peerID. The + * data provided in *peerID, while opaque to SecureTransport, is used + * in a byte-for-byte compare to other previous peerID values set by the + * current application. Matching peerID blobs result in SecureTransport + * attempting to resume an SSL session with the same parameters as used + * in the previous session which specified the same peerID bytes. + * @param context A valid SSLContextRef. + * @param peerID Opaque peer ID. + * @param peerIDLen Length of opaque peer ID. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetPeerID (SSLContextRef context, const void * __nullable peerID, size_t peerIDLen) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Obtain current PeerID. Returns NULL pointer, zero length if - * SSLSetPeerID has not been called for this context. + * @function SSLGetPeerID + * @abstract Obtain current PeerID. Returns NULL pointer, zero length if + * SSLSetPeerID has not been called for this context. + * @param context A valid SSLContextRef. + * @param peerID Pointer to storage for the peer ID. + * @param peerIDLen Pointer to storage for the peer ID length. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetPeerID (SSLContextRef context, const void * __nullable * __nonnull peerID, size_t *peerIDLen) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Obtain the SSLCipherSuite (e.g., SSL_RSA_WITH_DES_CBC_SHA) negotiated - * for this session. Only valid when a session is active. + * @function SSLGetNegotiatedCipher + * @abstract Obtain the SSLCipherSuite (e.g., SSL_RSA_WITH_DES_CBC_SHA) negotiated + * for this session. Only valid when a session is active. + * @param context A valid SSLContextRef. + * @param cipherSuite Pointer to storage for negotiated SSLCipherSuite. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetNegotiatedCipher (SSLContextRef context, SSLCipherSuite *cipherSuite) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Set the ALPN protocols to be passed in the ALPN negotiation. - * This is the list of supported application-layer protocols supported. + * @function SSLSetALPNProtocols + * @abstract Set the ALPN protocols to be passed in the ALPN negotiation. + * @discussion This is the list of supported application-layer protocols supported. * - * The protocols parameter must be an array of CFStringRef values - * with ASCII-encoded reprensetations of the supported protocols, e.g., "http/1.1". + * The protocols parameter must be an array of CFStringRef values + * with ASCII-encoded reprensetations of the supported protocols, e.g., "http/1.1". * - * See RFC 7301 for more information. + * @note See RFC 7301 for more information. + * @param context A valid SSLContextRef. + * @param protocols Array of CFStringRefs carrying application protocols. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetALPNProtocols (SSLContextRef context, CFArrayRef protocols) - __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.13, 10.15), ios(11.0, 13.0)); /* - * Get the ALPN protocols associated with this SSL context. - * This is the list of supported application-layer protocols supported. + * @function SSLCopyALPNProtocols + * @abstract Get the ALPN protocols associated with this SSL context. + * @discussion This is the list of supported application-layer protocols supported. * - * The resultant protocols array will contain CFStringRef values containing - * ASCII-encoded representations of the supported protocols, e.g., "http/1.1". + * The resultant protocols array will contain CFStringRef values containing + * ASCII-encoded representations of the supported protocols, e.g., "http/1.1". * - * See RFC 7301 for more information. + * See RFC 7301 for more information. * - * Note: The `protocols` pointer must be NULL, otherwise the copy will fail. - * This function will allocate memory for the CFArrayRef container - * if there is data to provide. Otherwise, the pointer will remain NULL. + * @note The `protocols` pointer must be NULL, otherwise the copy will fail. + * This function will allocate memory for the CFArrayRef container + * if there is data to provide. Otherwise, the pointer will remain NULL. + * @param context A valid SSLContextRef. + * @param protocols Pointer to a CFArrayRef where peer ALPN protocols are stored. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLCopyALPNProtocols (SSLContextRef context, CFArrayRef __nullable * __nonnull protocols) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.13, 10.15), ios(11.0, 13.0)); /* - * Set the OCSP response for the given SSL session. - * - * The response parameter must be a non-NULL CFDataRef containing the - * bytes of the OCSP response. + * @function SSLSetOCSPResponse + * @abstract Set the OCSP response for the given SSL session. + * @discussion The response parameter must be a non-NULL CFDataRef containing the + * bytes of the OCSP response. + * @param context A valid SSLContextRef. + * @param response CFDataRef carrying OCSP response. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetOCSPResponse (SSLContextRef context, CFDataRef __nonnull response) -__OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.13, 10.15), ios(11.0, 13.0)); /******************************************************** *** Session context configuration, server side only. *** ********************************************************/ /* - * This function is deprecated in OSX 10.11 and iOS 9.0 and - * has no effect on the TLS handshake since OSX 10.10 and - * iOS 8.0. Using separate RSA certificates for encryption - * and signing is no longer supported. + * @function SSLSetEncryptionCertificate + * @discussion This function is deprecated in OSX 10.11 and iOS 9.0 and + * has no effect on the TLS handshake since OSX 10.10 and + * iOS 8.0. Using separate RSA certificates for encryption + * and signing is no longer supported. + * @param context A valid SSLContextRef. + * @param certRefs Array of certificates. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetEncryptionCertificate (SSLContextRef context, CFArrayRef certRefs) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_11, __IPHONE_5_0, __IPHONE_9_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.11), ios(5.0, 9.0)); /* - * Specify requirements for client-side authentication. - * Optional; Default is kNeverAuthenticate. - * - * Can only be called when no session is active. + * @enum SSLAuthenticate + * @discussion Optional; Default is kNeverAuthenticate. + * Can only be called when no session is active. */ typedef CF_ENUM(int, SSLAuthenticate) { kNeverAuthenticate, /* skip client authentication */ kAlwaysAuthenticate, /* require it */ - kTryAuthenticate /* try to authenticate, but not an error - * if client doesn't have a cert */ + kTryAuthenticate /* try to authenticate, but not an error if client doesn't have a cert */ }; +/* + * @function SSLSetClientSideAuthenticate + * @abstract Specify requirements for client-side authentication. + * @param context A valid SSLContextRef. + * @param auth A SSLAuthenticate enumeration value. + * @result errSecSuccess on success, alternative error on failure. + */ OSStatus SSLSetClientSideAuthenticate (SSLContextRef context, SSLAuthenticate auth) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Add a DER-encoded distinguished name to list of acceptable names - * to be specified in requests for client certificates. + * @function SSLAddDistinguishedName + * @abstract Add a DER-encoded distinguished name to list of acceptable names + * to be specified in requests for client certificates. + * @param context A valid SSLContextRef. + * @param derDN A DER-encoded Distinguished Name blob. + * @param derDNLen Length of the Distinguished Name blob. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLAddDistinguishedName (SSLContextRef context, const void * __nullable derDN, size_t derDNLen) - __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.4, 10.15), ios(5.0, 13.0)); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX /* - * Add a SecCertificateRef, or a CFArray of them, to a server's list - * of acceptable Certificate Authorities (CAs) to present to the client - * when client authentication is performed. - * - * If replaceExisting is true, the specified certificate(s) will replace - * a possible existing list of acceptable CAs. If replaceExisting is - * false, the specified certificate(s) will be appended to the existing - * list of acceptable CAs, if any. + * @function SSLSetCertificateAuthorities + * @abstract Add a SecCertificateRef, or a CFArray of them, to a server's list + * of acceptable Certificate Authorities (CAs) to present to the client + * when client authentication is performed. + * @discussion If replaceExisting is true, the specified certificate(s) will + * replace a possible existing list of acceptable CAs. If replaceExisting + * is false, the specified certificate(s) will be appended to the existing + * list of acceptable CAs, if any. * - * Returns errSecParam if this is called on a SSLContextRef which - * is configured as a client, or when a session is active. + * Returns errSecParam if this is called on a SSLContextRef which + * is configured as a client, or when a session is active. * - * NOTE: this function is currently not available on iOS. + * @note this function is currently not available on iOS. + * @param context A valid SSLContextRef. + * @param certificateOrARray Either a SecCertificateRef (or CFArrayRef of them). + * @param replaceExisting Boolean indicating if existing CAs should be overruled for this connection. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetCertificateAuthorities(SSLContextRef context, CFTypeRef certificateOrArray, Boolean replaceExisting) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.5, 10.15)); /* - * Obtain the certificates specified in SSLSetCertificateAuthorities(), - * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not - * been called. - * Caller must CFRelease the returned array. + * @function SSLCopyCertificateAuthorities + * @abstract Obtain the certificates specified in SSLSetCertificateAuthorities(), + * if any. Returns a NULL array if SSLSetCertificateAuthorities() has not been called. + * @discussion Caller must CFRelease the returned array. * - * NOTE: this function is currently not available on iOS. + * @note This function is currently not available on iOS. + * @param context A valid SSLContextRef. + * @param certificates Pointer to CFArrayRef storage for retained copy of CAs for this connection. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLCopyCertificateAuthorities(SSLContextRef context, CFArrayRef * __nonnull CF_RETURNS_RETAINED certificates) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA); + __SECURETRANSPORT_API_DEPRECATED(macos(10.5, 10.15)); #endif /* MAC OS X */ /* - * Obtain the list of acceptable distinguished names as provided by - * a server (if the SSLContextRef is configured as a client), or as - * specified by SSLSetCertificateAuthorities (if the SSLContextRef - * is configured as a server). - * The returned array contains CFDataRefs, each of which represents - * one DER-encoded RDN. - * - * Caller must CFRelease the returned array. + * @function SSLCopyDistinguishedNames + * @abstract Obtain the list of acceptable distinguished names as provided by + * a server (if the SSLContextRef is configured as a client), or as + * specified by SSLSetCertificateAuthorities (if the SSLContextRef + * is configured as a server). + * @discussion The returned array contains CFDataRefs, each of which represents + * one DER-encoded RDN. Caller must CFRelease the returned array. + * @param context A valid SSLContextRef. + * @param names Pointer to CFArrayRef storage for retained copy of Distinguished Names. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLCopyDistinguishedNames (SSLContextRef context, CFArrayRef * __nonnull CF_RETURNS_RETAINED names) - __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.5, 10.15), ios(5.0, 13.0)); /* - * Obtain client certificate exchange status. Can be called - * any time. Reflects the *last* client certificate state change; - * subsequent to a renegotiation attempt by either peer, the state - * is reset to kSSLClientCertNone. + * @function SSLGetClientCertificateState + * @abstract Obtain client certificate exchange status. + * @discussion Can be called any time. + * Reflects the *last* client certificate state change; + * subsequent to a renegotiation attempt by either peer, the state + * is reset to kSSLClientCertNone. + * @param context A valid SSLContextRef. + * @param clientState Pointer to SSLClientCertificateState storage. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetClientCertificateState (SSLContextRef context, SSLClientCertificateState *clientState) - __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.3, 10.15), ios(5.0, 13.0)); -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX /* - * Specify Diffie-Hellman parameters. Optional; if we are configured to allow - * for D-H ciphers and a D-H cipher is negotiated, and this function has not - * been called, a set of process-wide parameters will be calculated. However - * that can take a long time (30 seconds). - * - * NOTE: this function is currently not available on iOS. + * @function SSLSetDiffieHellmanParams + * @abstract Specify Diffie-Hellman parameters. + * @discussion Optional; if we are configured to allow + * for D-H ciphers and a D-H cipher is negotiated, and this function has not + * been called, a set of process-wide parameters will be calculated. However + * that can take a long time (30 seconds). + * @note This function is currently not available on iOS. + * @param context A valid SSLContextRef. + * @param clientState Pointer to SSLClientCertificateState storage. + * @result errSecSuccess on success, alternative error on failure. */ -OSStatus SSLSetDiffieHellmanParams (SSLContextRef context, - const void * __nullable dhParams, - size_t dhParamsLen) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); +OSStatus +SSLSetDiffieHellmanParams (SSLContextRef context, + const void * __nullable dhParams, + size_t dhParamsLen) + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15)); /* - * Return parameter block specified in SSLSetDiffieHellmanParams. - * Returned data is not copied and belongs to the SSLContextRef. - * - * NOTE: this function is currently not available on iOS. + * @function SSLGetDiffieHellmanParams + * @abstract Return parameter block specified in SSLSetDiffieHellmanParams. + * @discussion Returned data is not copied and belongs to the SSLContextRef. + * @note This function is currently not available on iOS. + * @param context A valid SSLContextRef. + * @param dhParams Pointer to storage for DH parameters (if set), of at length most |*dhParamsLen|. + * @param dhParamsLen (Input and output) length of dhParams. + * @result errSecSuccess on success, alternative error on failure. */ -OSStatus SSLGetDiffieHellmanParams (SSLContextRef context, - const void * __nullable * __nonnull dhParams, - size_t *dhParamsLen) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_NA); +OSStatus +SSLGetDiffieHellmanParams (SSLContextRef context, + const void * __nullable * __nonnull dhParams, + size_t *dhParamsLen) + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15)); /* - * Enable/Disable RSA blinding. This feature thwarts a known timing - * attack to which RSA keys are vulnerable; enabling it is a tradeoff - * between performance and security. The default for RSA blinding is - * enabled. + * @function SSLSetRsaBlinding + * @abstract Enable/Disable RSA blinding. + * @discussion This feature thwarts a known timing + * attack to which RSA keys are vulnerable; enabling it is a tradeoff + * between performance and security. The default for RSA blinding is + * enabled. * * ========================== * MAC OS X ONLY (DEPRECATED) * ========================== - * NOTE: this function is not available on iOS, and should be considered - * deprecated on Mac OS X. RSA blinding is enabled unconditionally, as - * it prevents a known way for an attacker to recover the private key, - * and the performance gain of disabling it is negligible. + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. RSA blinding is enabled unconditionally, as + * it prevents a known way for an attacker to recover the private key, + * and the performance gain of disabling it is negligible. + * @param context A valid SSLContextRef. + * @param blinding Boolean indicating if RSA blinding is enabled. + * @result errSecSuccess on success, alternative error on failure. */ -OSStatus SSLSetRsaBlinding (SSLContextRef context, - Boolean blinding) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); +OSStatus +SSLSetRsaBlinding (SSLContextRef context, + Boolean blinding) + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); -OSStatus SSLGetRsaBlinding (SSLContextRef context, - Boolean *blinding) - __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_9,__IPHONE_NA,__IPHONE_NA); +/* + * @function SSLGetRsaBlinding + * @abstract Get RSA blinding state. + * @discussion See SSLSetRsaBlinding(). + * + * ========================== + * MAC OS X ONLY (DEPRECATED) + * ========================== + * @note This function is not available on iOS, and should be considered + * deprecated on Mac OS X. + * @param context A valid SSLContextRef. + * @param blinding Pointer to Boolean storage for RSA blinding state. + * @result errSecSuccess on success, alternative error on failure. + */ +OSStatus +SSLGetRsaBlinding (SSLContextRef context, + Boolean *blinding) + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.9)); #endif /* MAC OS X */ @@ -1422,115 +1599,153 @@ OSStatus SSLGetRsaBlinding (SSLContextRef context, */ /* - * Perform the SSL handshake. On successful return, session is - * ready for normal secure application I/O via SSLWrite and SSLRead. + * @function SSLHandshake + * @abstract Perform the SSL handshake. + * @discussion On successful return, session is ready for normal secure application + * I/O via SSLWrite and SSLRead. * - * Interesting error returns: + * Interesting error returns: * - * errSSLUnknownRootCert: Peer had a valid cert chain, but the root of - * the chain is unknown. + * errSSLUnknownRootCert: Peer had a valid cert chain, but the root of + * the chain is unknown. * - * errSSLNoRootCert: Peer had a cert chain which did not end in a root. + * errSSLNoRootCert: Peer had a cert chain which did not end in a root. * - * errSSLCertExpired: Peer's cert chain had one or more expired certs. + * errSSLCertExpired: Peer's cert chain had one or more expired certs. * - * errSSLXCertChainInvalid: Peer had an invalid cert chain (i.e., - * signature verification within the chain failed, or no certs - * were found). + * errSSLXCertChainInvalid: Peer had an invalid cert chain (i.e., + * signature verification within the chain failed, or no certs + * were found). * - * In all of the above errors, the handshake was aborted; the peer's - * cert chain is available via SSLCopyPeerTrust or SSLCopyPeerCertificates. + * In all of the above errors, the handshake was aborted; the peer's + * cert chain is available via SSLCopyPeerTrust or SSLCopyPeerCertificates. * - * Other interesting result codes: + * Other interesting result codes: * - * errSSLPeerAuthCompleted: Peer's cert chain is valid, or was ignored if - * cert verification was disabled via SSLSetEnableCertVerify. The application - * may decide to continue with the handshake (by calling SSLHandshake - * again), or close the connection at this point. + * errSSLPeerAuthCompleted: Peer's cert chain is valid, or was ignored if + * cert verification was disabled via SSLSetEnableCertVerify. The application + * may decide to continue with the handshake (by calling SSLHandshake + * again), or close the connection at this point. * - * errSSLClientCertRequested: The server has requested a client certificate. - * The client may choose to examine the server's certificate and - * distinguished name list, then optionally call SSLSetCertificate prior - * to resuming the handshake by calling SSLHandshake again. + * errSSLClientCertRequested: The server has requested a client certificate. + * The client may choose to examine the server's certificate and + * distinguished name list, then optionally call SSLSetCertificate prior + * to resuming the handshake by calling SSLHandshake again. * - * A return value of errSSLWouldBlock indicates that SSLHandshake has to be - * called again (and again and again until something else is returned). + * A return value of errSSLWouldBlock indicates that SSLHandshake has to be + * called again (and again and again until something else is returned). + * @param context A valid SSLContextRef. + * @result errSecSuccess on success, alternative error on failure or incomplete state. */ OSStatus SSLHandshake (SSLContextRef context) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Server Only: Request renegotation. - * This will return an error if the server is already renegotiating, or if the session is closed. - * After this return without error, the application should call SSLHandshake() and/or SSLRead() as - * for the original handshake. + * @function SSLReHandshake + * @abstract Server Only: Request renegotation. + * @discussion This will return an error if the server is already renegotiating, or if the session is closed. + * After this return without error, the application should call SSLHandshake() and/or SSLRead() as + * for the original handshake. + * @param context A valid SSLContextRef. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLReHandshake (SSLContextRef context) - __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.12, 10.15), ios(10.0, 13.0)); /* - * Normal application-level read/write. On both of these, a errSSLWouldBlock - * return and a partially completed transfer - or even zero bytes transferred - - * are NOT mutually exclusive. + * @function SSLWrite + * @abstract Normal application-level write. + * @discussion On both of these, a errSSLWouldBlock return and a partially completed + * transfer - or even zero bytes transferred - are NOT mutually exclusive. + * @param context A valid SSLContextRef. + * @param data Pointer to data to write. + * @param dataLength Length of data to write. + * @param processed Pointer to storage indicating how much data was written. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLWrite (SSLContextRef context, const void * __nullable data, size_t dataLength, size_t *processed) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * data is mallocd by caller; available size specified in - * dataLength; actual number of bytes read returned in - * *processed. + * @function SSLRead + * @abstract * @abstract Normal application-level write. + * @discussion Data is mallocd by caller; available size specified in + * dataLength; actual number of bytes read returned in + * *processed. + * @param context A valid SSLContextRef. + * @param data Pointer to storage where data can be read. + * @param dataLength Length of data storage. + * @param processed Pointer to storage indicating how much data was read. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLRead (SSLContextRef context, void * data, /* RETURNED */ size_t dataLength, size_t *processed) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Determine how much data the client can be guaranteed to - * obtain via SSLRead() without blocking or causing any low-level - * read operations to occur. + * @function SSLGetBufferedReadSize + * @abstract Determine how much data the client can be guaranteed to + * obtain via SSLRead() without blocking or causing any low-level + * read operations to occur. + * @param context A valid SSLContextRef. + * @param bufferSize Pointer to store the amount of buffered data to be read. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetBufferedReadSize (SSLContextRef context, - size_t *bufSize) /* RETURNED */ - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + size_t *bufferSize) /* RETURNED */ + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Determine how much data the application can be guaranteed to write - * with SSLWrite() without causing fragmentation. The value is based on - * the maximum Datagram Record size defined by the application with - * SSLSetMaxDatagramRecordSize(), minus the DTLS Record header size. + * @function SSLGetDatagramWriteSize + * @abstract Determine how much data the application can be guaranteed to write + * with SSLWrite() without causing fragmentation. The value is based on + * the maximum Datagram Record size defined by the application with + * SSLSetMaxDatagramRecordSize(), minus the DTLS Record header size. + * @param context A valid SSLContextRef (for DTLS). + * @param bufferSize Pointer to store the amount of data that can be written. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLGetDatagramWriteSize (SSLContextRef dtlsContext, size_t *bufSize) - __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.8, 10.15), ios(5.0, 13.0)); /* - * Terminate current SSL session. + * @function SSLClose + * @abstract Terminate current SSL session. + * @param context A valid SSLContextRef. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLClose (SSLContextRef context) - __OSX_AVAILABLE_STARTING(__MAC_10_2, __IPHONE_5_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.2, 10.15), ios(5.0, 13.0)); /* - * Set the status of a SSLContextRef. This is to be done after handling - * steps of the SSL handshake such as server certificate validation. + * @function SSLSetError + * @abstract Set the status of a SSLContextRef. + * @discussion This is to be done after handling steps of the SSL handshake such + * as server certificate validation. + * @param context A valid SSLContextRef. + * @param status Error status to set internally, which will be translated to an alert. + * @result errSecSuccess on success, alternative error on failure. */ OSStatus SSLSetError (SSLContextRef context, OSStatus status) - __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_11_0); + __SECURETRANSPORT_API_DEPRECATED(macos(10.13, 10.15), ios(11.0, 13.0)); + +#undef __SECURETRANSPORT_API_DEPRECATED CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/OSX/libsecurity_ssl/lib/SecureTransportPriv.h b/OSX/libsecurity_ssl/lib/SecureTransportPriv.h index d7cab1af..f7a6c5f9 100644 --- a/OSX/libsecurity_ssl/lib/SecureTransportPriv.h +++ b/OSX/libsecurity_ssl/lib/SecureTransportPriv.h @@ -37,6 +37,40 @@ extern "C" { #include +/* Enum defining connection strength for TLS connections. */ +typedef CF_ENUM(int, SSLConnectionStrength) { + SSLConnectionStrengthStrong, + SSLConnectionStrengthWeak, + SSLConnectionStrengthNonsecure, +}; + +/* See: https://tools.ietf.org/html/rfc8446#section-4.2.7 */ +typedef CF_ENUM(uint16_t, SSLKeyExchangeGroup) { + SSLKeyExchangeGroupSecp256r1 = 0x0017, + SSLKeyExchangeGroupSecp384r1 = 0x0018, + SSLKeyExchangeGroupSecp521r1 = 0x0019, + SSLKeyExchangeGroupX25519 = 0x001D, + SSLKeyExchangeGroupX448 = 0x001E, + SSLKeyExchangeGroupFFDHE2048 = 0x0100, + SSLKeyExchangeGroupFFDHE3072 = 0x0101, + SSLKeyExchangeGroupFFDHE4096 = 0x0102, + SSLKeyExchangeGroupFFDHE6144 = 0x0103, + SSLKeyExchangeGroupFFDHE8192 = 0x0104, +}; + +/* + * Convenience key exchange groups that collate group identifiers of + * comparable security into a single alias. + */ +typedef CF_ENUM(int, SSLKeyExchangeGroupSet) { + kSSLKeyExchangeGroupSetDefault, + kSSLKeyExchangeGroupSetCompatibility, + kSSLKeyExchangeGroupSetLegacy, +}; + +/* Determine if a ciphersuite belongs to a specific ciphersuite group */ +bool SSLCiphersuiteGroupContainsCiphersuite(SSLCiphersuiteGroup group, SSLCipherSuite suite); + /* Return the list of ciphersuites associated with a SSLCiphersuiteGroup */ const SSLCipherSuite *SSLCiphersuiteGroupToCiphersuiteList(SSLCiphersuiteGroup group, size_t *listSize); @@ -47,6 +81,15 @@ SSLProtocol SSLCiphersuiteMinimumTLSVersion(SSLCipherSuite ciphersuite); /* Determine maximum allowed TLS version for the given ciphersuite */ SSLProtocol SSLCiphersuiteMaximumTLSVersion(SSLCipherSuite ciphersuite); +/* Get a human readable name for the given ciphersuite. */ +const char *SSLCiphersuiteGetName(SSLCipherSuite ciphersuite); + +/* Get the 2-byte IANA codepoint representation of the given TLS protocol version. */ +uint16_t SSLProtocolGetVersionCodepoint(SSLProtocol protocol_version); + +/* Get the internal SSLProtocol enumeration value from a 2-byte IANA TLS version codepoint. */ +SSLProtocol SSLProtocolFromVersionCodepoint(uint16_t protocol_version); + /* Create an SSL Context with an external record layer - eg: kernel accelerated layer */ SSLContextRef SSLCreateContextWithRecordFuncs(CFAllocatorRef alloc, diff --git a/OSX/libsecurity_ssl/lib/sslCipherSpecs.c b/OSX/libsecurity_ssl/lib/sslCipherSpecs.c index b898a933..47588641 100644 --- a/OSX/libsecurity_ssl/lib/sslCipherSpecs.c +++ b/OSX/libsecurity_ssl/lib/sslCipherSpecs.c @@ -38,6 +38,9 @@ #include #include #include +#include + +#include "SecProtocolInternal.h" #include @@ -162,215 +165,94 @@ static const uint16_t STKnownCipherSuites[] = { 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 tls_ciphersuite_group_t +_SSLCiphersuteGroupToTLSCiphersuiteGroup(SSLCiphersuiteGroup group) +{ + switch (group) { + case kSSLCiphersuiteGroupDefault: + return tls_ciphersuite_group_default; + case kSSLCiphersuiteGroupCompatibility: + return tls_ciphersuite_group_compatibility; + case kSSLCiphersuiteGroupLegacy: + return tls_ciphersuite_group_legacy; + case kSSLCiphersuiteGroupATS: + return tls_ciphersuite_group_ats; + case kSSLCiphersuiteGroupATSCompatibility: + return tls_ciphersuite_group_ats_compatibility; + } + return tls_ciphersuite_group_default; } -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; - } + tls_ciphersuite_group_t tls_group = _SSLCiphersuteGroupToTLSCiphersuiteGroup(group); + const tls_ciphersuite_t *list = sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(tls_group, listSize); + return (const SSLCipherSuite *)list; +} - const SSLCipherSuite *ciphersuites = NULL; - size_t count = 0; +bool +SSLCiphersuiteGroupContainsCiphersuite(SSLCiphersuiteGroup group, SSLCipherSuite suite) +{ + tls_ciphersuite_group_t tls_group = _SSLCiphersuteGroupToTLSCiphersuiteGroup(group); + return sec_protocol_helper_ciphersuite_group_contains_ciphersuite(tls_group, (tls_ciphersuite_t)suite); +} -#define CASE_CONFIG(GROUPNAME) \ - case GROUPNAME: \ - ciphersuites = List##GROUPNAME; \ - count = sizeof(List##GROUPNAME) / sizeof(SSLCipherSuite); \ - break; +static struct ssl_protocol_version_map_entry { + SSLProtocol protocol; + uint16_t codepoint; +} ssl_protocol_version_map[] = { + { .protocol = kTLSProtocol13, .codepoint = tls_protocol_version_TLSv13 }, + { .protocol = kTLSProtocol12, .codepoint = tls_protocol_version_TLSv12 }, + { .protocol = kTLSProtocol11, .codepoint = tls_protocol_version_TLSv11 }, + { .protocol = kTLSProtocol1, .codepoint = tls_protocol_version_TLSv10 }, + { .protocol = kDTLSProtocol12, .codepoint = tls_protocol_version_DTLSv12 }, + { .protocol = kDTLSProtocol1, .codepoint = tls_protocol_version_DTLSv10 }, + { .protocol = kSSLProtocol3, .codepoint = 0x0300 }, + { .protocol = kSSLProtocol2, .codepoint = 0x0000 }, +}; +static size_t ssl_protocol_version_map_len = sizeof(ssl_protocol_version_map) / sizeof(ssl_protocol_version_map[0]); - switch (group) { - CASE_CONFIG(kSSLCiphersuiteGroupDefault); - CASE_CONFIG(kSSLCiphersuiteGroupCompatibility); - CASE_CONFIG(kSSLCiphersuiteGroupLegacy); - CASE_CONFIG(kSSLCiphersuiteGroupATS); - CASE_CONFIG(kSSLCiphersuiteGroupATSCompatibility); +uint16_t +SSLProtocolGetVersionCodepoint(SSLProtocol protocol_version) +{ + for (size_t i = 0; i < ssl_protocol_version_map_len; i++) { + if (ssl_protocol_version_map[i].protocol == protocol_version) { + return ssl_protocol_version_map[i].codepoint; + } } + return 0; +} -#undef CASE_CONFIG - - if (ciphersuites != NULL) { - *listSize = count; - return ciphersuites; +SSLProtocol +SSLProtocolFromVersionCodepoint(uint16_t protocol_version) +{ + for (size_t i = 0; i < ssl_protocol_version_map_len; i++) { + if (ssl_protocol_version_map[i].codepoint == protocol_version) { + return ssl_protocol_version_map[i].protocol; + } } - - *listSize = 0; - return NULL; + return kSSLProtocolUnknown; } 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; + tls_protocol_version_t version = sec_protocol_helper_ciphersuite_minimum_TLS_version((tls_ciphersuite_t)ciphersuite); + return SSLProtocolFromVersionCodepoint((uint16_t)version); } 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; + tls_protocol_version_t version = sec_protocol_helper_ciphersuite_maximum_TLS_version((tls_ciphersuite_t)ciphersuite); + return SSLProtocolFromVersionCodepoint((uint16_t)version); +} + +const char * +SSLCiphersuiteGetName(SSLCipherSuite ciphersuite) +{ + return sec_protocol_helper_get_ciphersuite_name((tls_ciphersuite_t)ciphersuite); } /* diff --git a/OSX/libsecurity_ssl/lib/sslContext.c b/OSX/libsecurity_ssl/lib/sslContext.c index a0b80866..fc1826fe 100644 --- a/OSX/libsecurity_ssl/lib/sslContext.c +++ b/OSX/libsecurity_ssl/lib/sslContext.c @@ -1246,6 +1246,9 @@ _SSLProtocolVersionToWireFormatValue (SSLProtocol protocol) case kDTLSProtocol1: { return tls_protocol_version_DTLS_1_0; } + case kDTLSProtocol12: { + return tls_protocol_version_DTLS_1_2; + } case kSSLProtocolUnknown: { return tls_protocol_version_Undertermined; } @@ -1632,7 +1635,7 @@ SSLCopyTrustedRoots (SSLContextRef ctx, CFRetain(ctx->trustedCerts); return errSecSuccess; } -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX /* use default system roots */ return sslDefaultSystemRoots(ctx, trustedRoots); #else @@ -2515,8 +2518,11 @@ OSStatus SSLGetECDSACurves( if(*numCurves < ctx->ecdhNumCurves) { return errSecParam; } - memmove(namedCurves, ctx->ecdhCurves, - (ctx->ecdhNumCurves * sizeof(SSL_ECDSA_NamedCurve))); + static_assert(sizeof(*namedCurves) >= sizeof(*(ctx->ecdhCurves)), + "SSL_ECDSA_NamedCurve must be large enough for SSLContext ecdhCurves."); + for (unsigned i = 0; i < ctx->ecdhNumCurves; i++) { + namedCurves[i] = ctx->ecdhCurves[i]; + } *numCurves = ctx->ecdhNumCurves; return errSecSuccess; } @@ -2537,20 +2543,26 @@ OSStatus SSLSetECDSACurves( return errSecBadReq; } - size_t size = numCurves * sizeof(uint16_t); - ctx->ecdhCurves = (uint16_t *)sslMalloc(size); + if (SIZE_MAX / sizeof(*(ctx->ecdhCurves)) < (size_t)numCurves) { + return errSecParam; + } + ctx->ecdhCurves = sslMalloc((size_t)numCurves * sizeof(*(ctx->ecdhCurves))); if(ctx->ecdhCurves == NULL) { ctx->ecdhNumCurves = 0; return errSecAllocate; } - for (unsigned i=0; iecdhCurves[i] = namedCurves[i]; - } + for (unsigned i=0; i UINT16_MAX - 1) { + ctx->ecdhCurves[i] = SSL_Curve_None; + continue; + } + ctx->ecdhCurves[i] = namedCurves[i]; + } ctx->ecdhNumCurves = numCurves; - tls_handshake_set_curves(ctx->hdsk, ctx->ecdhCurves, ctx->ecdhNumCurves); + tls_handshake_set_curves(ctx->hdsk, ctx->ecdhCurves, ctx->ecdhNumCurves); return errSecSuccess; } diff --git a/OSX/libsecurity_ssl/lib/sslContext.h b/OSX/libsecurity_ssl/lib/sslContext.h index 82f5ffc7..84486c2c 100644 --- a/OSX/libsecurity_ssl/lib/sslContext.h +++ b/OSX/libsecurity_ssl/lib/sslContext.h @@ -262,12 +262,6 @@ OSStatus SSLUpdateNegotiatedClientAuthType(SSLContextRef ctx); Boolean sslIsSessionActive(const SSLContext *ctx); -static inline bool sslVersionIsLikeTls12(SSLContext *ctx) -{ - check(ctx->negProtocolVersion!=SSL_Version_Undetermined); - return ctx->isDTLS ? ctx->negProtocolVersion > DTLS_Version_1_0 : ctx->negProtocolVersion >= TLS_Version_1_2; -} - OSStatus SSLGetSessionConfigurationIdentifier(SSLContext *ctx, SSLBuffer *buffer); /* This is implemented in tls_callbacks.c */ diff --git a/OSX/libsecurity_ssl/lib/sslCrypto.c b/OSX/libsecurity_ssl/lib/sslCrypto.c index 60362e4a..e26fff2f 100644 --- a/OSX/libsecurity_ssl/lib/sslCrypto.c +++ b/OSX/libsecurity_ssl/lib/sslCrypto.c @@ -48,22 +48,6 @@ #include -/* - * Get algorithm id for a SSLPubKey object. - */ -CFIndex sslPubKeyGetAlgorithmID(SecKeyRef pubKey) -{ - return SecKeyGetAlgorithmId(pubKey); -} - -/* - * Get algorithm id for a SSLPrivKey object. - */ -CFIndex sslPrivKeyGetAlgorithmID(SecKeyRef privKey) -{ - return SecKeyGetAlgorithmId(privKey); -} - OSStatus sslCreateSecTrust( @@ -213,37 +197,6 @@ errOut: return status; } -/* Convert cert in DER format into an CFArray of SecCertificateRef */ -CFArrayRef -tls_get_peer_certs(const SSLCertificate *certs) -{ - const SSLCertificate *cert; - - CFMutableArrayRef certArray = NULL; - CFDataRef certData = NULL; - SecCertificateRef cfCert = NULL; - - certArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - require(certArray, out); - cert = certs; - while(cert) { - require((certData = CFDataCreate(kCFAllocatorDefault, cert->derCert.data, cert->derCert.length)), out); - require((cfCert = SecCertificateCreateWithData(kCFAllocatorDefault, certData)), out); - CFArrayAppendValue(certArray, cfCert); - CFReleaseNull(cfCert); - CFReleaseNull(certData); - cert=cert->next; - } - - return certArray; - -out: - CFReleaseNull(cfCert); - CFReleaseNull(certData); - CFReleaseNull(certArray); - return NULL; -} - int tls_verify_peer_cert(SSLContext *ctx) { @@ -382,7 +335,7 @@ OSStatus sslVerifySelectedCipher(SSLContext *ctx) } /* Check the alg of our signing key. */ - CFIndex keyAlg = sslPrivKeyGetAlgorithmID(ctx->signingPrivKeyRef); + CFIndex keyAlg = SecKeyGetAlgorithmId(ctx->signingPrivKeyRef); if (requireAlg != keyAlg) { sslErrorLog("sslVerifySelectedCipher: signing key alg mismatch\n"); return errSSLBadConfiguration; diff --git a/OSX/libsecurity_ssl/lib/sslCrypto.h b/OSX/libsecurity_ssl/lib/sslCrypto.h index 007fa969..e4dd9e65 100644 --- a/OSX/libsecurity_ssl/lib/sslCrypto.h +++ b/OSX/libsecurity_ssl/lib/sslCrypto.h @@ -42,16 +42,6 @@ extern void stPrintCdsaError(const char *op, OSStatus crtn); #define stPrintCdsaError(o, cr) #endif -/* - * Get algorithm id for a SSLPubKey object. - */ -CFIndex sslPubKeyGetAlgorithmID(SecKeyRef pubKey); - -/* - * Get algorithm id for a SSLPrivKey object. - */ -CFIndex sslPrivKeyGetAlgorithmID(SecKeyRef privKey); - /* * Create a new SecTrust object and return it. */ @@ -63,9 +53,6 @@ sslCreateSecTrust( OSStatus sslVerifySelectedCipher( SSLContext *ctx); -/* Convert DER certs to SecCertificateRefs */ -CFArrayRef tls_get_peer_certs(const SSLCertificate *certs); - /* * Set the pubkey after receiving the certificate */ diff --git a/OSX/libsecurity_ssl/lib/sslKeychain.c b/OSX/libsecurity_ssl/lib/sslKeychain.c index 83762723..387c34ab 100644 --- a/OSX/libsecurity_ssl/lib/sslKeychain.c +++ b/OSX/libsecurity_ssl/lib/sslKeychain.c @@ -216,9 +216,9 @@ parseIncomingCerts( sslFreePrivKey(sslPrivKey); size_t size = SecKeyGetBlockSize(privKey); - if(sslPrivKeyGetAlgorithmID(privKey) == kSecRSAAlgorithmID) { + if(SecKeyGetAlgorithmId(privKey) == kSecRSAAlgorithmID) { *sslPrivKey = tls_private_key_rsa_create(privKey, SecKeyGetBlockSize(privKey), mySSLPrivKeyRSA_sign, mySSLPrivKeyRSA_decrypt); - } else if (sslPrivKeyGetAlgorithmID(privKey) == kSecECDSAAlgorithmID) { + } else if (SecKeyGetAlgorithmId(privKey) == kSecECDSAAlgorithmID) { #if TARGET_OS_IPHONE /* Compute signature size from key size */ size_t sigSize = 8+2*size; diff --git a/OSX/libsecurity_ssl/lib/sslMemory.c b/OSX/libsecurity_ssl/lib/sslMemory.c index 831b8861..00600da6 100644 --- a/OSX/libsecurity_ssl/lib/sslMemory.c +++ b/OSX/libsecurity_ssl/lib/sslMemory.c @@ -93,26 +93,6 @@ sslFree(void *p) } } -void * -sslRealloc(void *oldPtr, size_t oldLen, size_t newLen) -{ - /* _REALLOC is in sys/malloc.h but is only exported in debug kernel */ - /* return _REALLOC(oldPtr, newLen, M_TEMP, M_NOWAIT); */ - - /* FIXME */ - void *newPtr; - if(newLen>oldLen) { - newPtr=sslMalloc(newLen); - if(newPtr) { - memcpy(newPtr, oldPtr, oldLen); - sslFree(oldPtr); - } - } else { - newPtr=oldPtr; - } - return newPtr; -} - #else #include @@ -131,12 +111,6 @@ sslFree(void *p) } } -void * -sslRealloc(void *oldPtr, size_t oldLen, size_t newLen) -{ - return realloc(oldPtr, newLen); -} - #endif // MARK: - @@ -171,23 +145,6 @@ SSLFreeBuffer(SSLBuffer *buf) return 0; } -int -SSLReallocBuffer(SSLBuffer *buf, size_t newSize) -{ - buf->data = (uint8_t *)sslRealloc(buf->data, buf->length, newSize); - if(buf->data == NULL) { - sslErrorLog("SSLReallocBuffer: NULL buf!\n"); - check(0); - buf->length = 0; - return -1; - } - buf->length = newSize; - return 0; -} - -// MARK: - -// MARK: Convenience routines - uint8_t *sslAllocCopy( const uint8_t *src, size_t len) @@ -202,28 +159,6 @@ uint8_t *sslAllocCopy( return dst; } -int SSLAllocCopyBuffer( - const SSLBuffer *src, - SSLBuffer **dst) // buffer and data mallocd and returned -{ - int serr; - - SSLBuffer *rtn = (SSLBuffer *)sslMalloc(sizeof(SSLBuffer)); - if(rtn == NULL) { - sslErrorLog("SSLAllocCopyBuffer: NULL buf!\n"); - check(0); - return -1; - } - serr = SSLCopyBuffer(src, rtn); - if(serr) { - sslFree(rtn); - } - else { - *dst = rtn; - } - return serr; -} - int SSLCopyBufferFromData( const void *src, size_t len, diff --git a/OSX/libsecurity_ssl/lib/sslMemory.h b/OSX/libsecurity_ssl/lib/sslMemory.h index 563090a1..f2fb8ded 100644 --- a/OSX/libsecurity_ssl/lib/sslMemory.h +++ b/OSX/libsecurity_ssl/lib/sslMemory.h @@ -41,22 +41,17 @@ extern "C" { */ void *sslMalloc(size_t length); void sslFree(void *p); -void *sslRealloc(void *oldPtr, size_t oldLen, size_t newLen); /* * SSLBuffer-oriented allocators */ int SSLAllocBuffer(SSLBuffer *buf, size_t length); int SSLFreeBuffer(SSLBuffer *buf); -int SSLReallocBuffer(SSLBuffer *buf, size_t newSize); /* * Convenience routines */ uint8_t *sslAllocCopy(const uint8_t *src, size_t len); -int SSLAllocCopyBuffer( - const SSLBuffer *src, - SSLBuffer **dst); // buffer itself and data mallocd and returned int SSLCopyBufferFromData( const void *src, size_t len, diff --git a/OSX/libsecurity_ssl/lib/sslTransport.c b/OSX/libsecurity_ssl/lib/sslTransport.c index 616b9d49..c22cf500 100644 --- a/OSX/libsecurity_ssl/lib/sslTransport.c +++ b/OSX/libsecurity_ssl/lib/sslTransport.c @@ -474,7 +474,7 @@ SSLHandshake(SSLContext *ctx) return errSecSuccess; } -#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) +#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) #include "SecADWrapper.h" diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m index aeb66843..ca6cd471 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+ciphers.m @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -35,6 +36,9 @@ #include "ssl-utils.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + /* SSL CipherSuite tests */ @@ -147,58 +151,7 @@ typedef struct { 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 +#if SECTRANS_VERBOSE_DEBUG static void hexdump(const uint8_t *bytes, size_t len) { size_t ix; printf("socket write(%p, %lu)\n", bytes, len); @@ -274,10 +227,12 @@ 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); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, + server ? kSSLServerSide : kSSLClientSide, + dtls ? kSSLDatagramType : kSSLStreamType); require(ctx, out); - if(dtls) { + if (dtls) { size_t mtu; require_noerr(SSLSetMaxDatagramRecordSize(ctx, 400), out); require_noerr(SSLGetMaxDatagramRecordSize(ctx, &mtu), out); @@ -294,31 +249,25 @@ static SSLContextRef make_ssl_ref(bool server, SSLAuthenticate client_side_auth, require_noerr(SSLSetMinimumDHGroupSize(ctx, 512), out); if (!dh_anonymous) { - if (server) + 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(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 */ + 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); @@ -328,8 +277,9 @@ static SSLContextRef make_ssl_ref(bool server, SSLAuthenticate client_side_auth, return ctx; out: - if (ctx) + if (ctx) { CFRelease(ctx); + } return NULL; } @@ -340,6 +290,7 @@ static bool check_peer_cert(SSLContextRef ctx, const ssl_test_handle *ssl, SecTr /* verify peer cert chain */ require_noerr(SSLCopyPeerTrust(ctx, trust), out); + require_noerr(SSLGetPeerSecTrust(ctx, trust), out); SecTrustResultType trust_result = 0; /* this won't verify without setting up a trusted anchor */ require_noerr(SecTrustEvaluate(*trust, &trust_result), out); @@ -348,12 +299,12 @@ static bool check_peer_cert(SSLContextRef ctx, const ssl_test_handle *ssl, SecTr peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks); orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->peer_certs); - while (n_certs--) + while (n_certs--) { CFArrayInsertValueAtIndex(peer_cert_array, 0, SecTrustGetCertificateAtIndex(*trust, n_certs)); + } - SecIdentityRef ident = - (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0); + 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); @@ -377,6 +328,10 @@ out: #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 test_get_client_server_random(SSLContextRef ctx, const void *arg, void *secret, size_t *secretLen) +{ + return; +} static void *securetransport_ssl_thread(void *arg) { @@ -386,21 +341,27 @@ static void *securetransport_ssl_thread(void *arg) SecTrustRef trust = NULL; bool got_server_auth = false, got_client_cert_req = false; SSLSessionState ssl_state; + char random[SSL_CLIENT_SRVR_RAND_SIZE*2]; + size_t randomSize = SSL_CLIENT_SRVR_RAND_SIZE*2; + size_t offset; perf_start(); - pthread_setname_np(ssl->is_server?"server thread":"client thread"); + 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); + 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_noerr(SSLGetSessionState(ctx, &ssl_state), out); + require_noerr(SSLInternalSetMasterSecretFunction(ctx, test_get_client_server_random, NULL), out); + require_noerr(SSLInternalClientRandom(ctx, random, &randomSize), out); + offset = randomSize; + randomSize = SSL_CLIENT_SRVR_RAND_SIZE; + require_noerr(SSLInternalServerRandom(ctx, random+offset, &randomSize), 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 @@ -414,7 +375,7 @@ static void *securetransport_ssl_thread(void *arg) 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_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"); @@ -434,15 +395,15 @@ static void *securetransport_ssl_thread(void *arg) require_noerr(SSLSetCertificate(ctx, ssl->certs), out); } } else if (ortn == errSSLWouldBlock) { - require_action(ssl_state==kSSLHandshake, out, ortn = -1); + 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")); + 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); + 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"); @@ -457,8 +418,12 @@ static void *securetransport_ssl_thread(void *arg) SSLCipherSuite cipherSuite; require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); - - if(ssl->is_dtls) { + KeyExchangeMethod kem = sslCipherSuiteGetKeyExchangeMethod(cipherSuite); + if (kem == SSL_ECDHE_ECDSA || kem == SSL_ECDHE_RSA) { + SSL_ECDSA_NamedCurve namedCurve; + require_noerr_quiet(ortn = SSLGetNegotiatedCurve(ctx, &namedCurve), out); + } + if (ssl->is_dtls) { size_t sz; SSLGetDatagramWriteSize(ctx, &sz); } @@ -472,7 +437,7 @@ static void *securetransport_ssl_thread(void *arg) #define BUFSIZE (8*1024) unsigned char ibuf[BUFSIZE], obuf[BUFSIZE]; - for(int i=0; i<10; i++) { + for (int i = 0; i < 10; i++) { size_t len; if (ssl->is_server) { memset(obuf, i, BUFSIZE); @@ -483,9 +448,9 @@ static void *securetransport_ssl_thread(void *arg) require_action(len == 0, out, ortn = -1); } - len=0; - while(lentime, - ciphersuite_name(SupportedCipherSuites[i]), + cipher_name, 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]), + cipher_name, 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); + CFReleaseNull(client_certs); + CFReleaseNull(server_ec_certs); + CFReleaseNull(server_rsa_certs); } @end +#pragma clang diagnostic pop + /* TODO: count errSSLWouldBlock TODO: skip tests that don't matter: client_auth and anonymous dh @@ -683,3 +650,4 @@ 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 index efaf9780..a16881e6 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth.m @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,9 @@ #include "ssl-utils.h" #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (clientauth) /* @@ -84,8 +88,9 @@ static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *len len -= ret; ptr += ret; } - else + else { return -36; + } } while (len > 0); *length = *length - len; @@ -139,8 +144,15 @@ ssl_client_handle_create(bool break_on_req, int comm, CFArrayRef certs, CFArrayR require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name, strlen(peer_domain_name)), out); + CFArrayRef trustedRoots = NULL; + require_noerr(SSLCopyTrustedRoots(ctx, &trustedRoots), out); +#if (TARGET_OS_MAC && !TARGET_OS_IPHONE) + require(trustedRoots, out); +#endif + CFReleaseNull(trustedRoots); require_noerr(SSLSetTrustedRoots(ctx, trustedCA, true), out); - + require_noerr(SSLCopyTrustedRoots(ctx, &trustedRoots), out); + CFReleaseNull(trustedRoots); /* Setting client certificate in advance */ if (!break_on_req && certs) { @@ -161,11 +173,10 @@ ssl_client_handle_create(bool break_on_req, int comm, CFArrayRef certs, CFArrayR return handle; out: - if (ctx) - CFRelease(ctx); - if (handle) + CFReleaseNull(ctx); + if (handle) { free(handle); - + } return NULL; } @@ -186,25 +197,34 @@ static void *securetransport_ssl_client_thread(void *arg) SSLContextRef ctx = ssl->st; bool got_client_cert_req = false; SSLSessionState ssl_state; + SSLSignatureAndHashAlgorithm *sigAlgs; + unsigned int numSigAlgs, numTypes; + SSLClientAuthenticationType *authTypes; pthread_setname_np("client thread"); - require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); - require_action(ssl_state==kSSLIdle, out, ortn = -1); + 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); + require_noerr(SSLGetSessionState(ctx, &ssl_state), out); if (ortn == errSSLClientCertRequested) { + require_noerr(SSLGetNumberOfSignatureAlgorithms(ctx, &numSigAlgs), out); + sigAlgs = malloc(numSigAlgs * sizeof(SSLSignatureAndHashAlgorithm)); + require_noerr(SSLGetSignatureAlgorithms(ctx, sigAlgs, &numSigAlgs), out); + require_noerr(SSLGetNumberOfClientAuthTypes(ctx, &numTypes), out); + authTypes = malloc(numTypes * sizeof(SSLClientAuthenticationType)); + require_noerr(SSLGetClientAuthTypes(ctx, authTypes, &numTypes), out); require_string(ssl->auth, out, "cert req not expected"); - require_string(ssl_state==kSSLHandshake, out, "wrong client handshake state after errSSLClientCertRequested"); + 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(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) { @@ -212,7 +232,7 @@ static void *securetransport_ssl_client_thread(void *arg) } } else if (ortn == errSSLWouldBlock) { - require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); + require_string(ssl_state == kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); } } while (ortn == errSSLWouldBlock || ortn == errSSLClientCertRequested); @@ -254,7 +274,7 @@ ssl_server_handle_create(SSLAuthenticate client_auth, int comm, CFArrayRef certs SSLAuthenticate auth; require_noerr(SSLSetClientSideAuthenticate(ctx, client_auth), out); require_noerr(SSLGetClientSideAuthenticate(ctx, &auth), out); - require(auth==client_auth, out); + require(auth == client_auth, out); handle->client_auth = client_auth; handle->comm = comm; @@ -275,7 +295,7 @@ out: static void ssl_server_handle_destroy(ssl_server_handle *handle) { - if(handle) { + if (handle) { SSLClose(handle->st); CFRelease(handle->st); free(handle); @@ -291,21 +311,21 @@ static void *securetransport_ssl_server_thread(void *arg) pthread_setname_np("server thread"); - require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); - require_action(ssl_state==kSSLIdle, out, ortn = -1); + 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); + require_noerr(SSLGetSessionState(ctx, &ssl_state), out); if (ortn == errSSLWouldBlock) { - require_action(ssl_state==kSSLHandshake, out, ortn = -1); + require_action(ssl_state == kSSLHandshake, out, ortn = -1); } } while (ortn == errSSLWouldBlock); require_noerr_quiet(ortn, out); - require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(ssl_state == kSSLConnected, out, ortn = -1); out: SSLClose(ssl->st); @@ -327,17 +347,17 @@ out: 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 */ + 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 + bool break_on_req = (j != 0); + SSLAuthenticate auth = (k == 0) ? kNeverAuthenticate : (k == 1) ? kTryAuthenticate : kAlwaysAuthenticate; @@ -405,3 +425,5 @@ out: } @end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m index 5cf1ce6b..f845a3c5 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+clientauth41.m @@ -21,6 +21,9 @@ #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (clientauth41) #define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) { CFRelease(_cf); } } @@ -373,3 +376,5 @@ errOut: CFReleaseNull(trust_chain); } @end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m index a2db3afd..af122c2c 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+crashes.m @@ -43,6 +43,8 @@ #include #include +#include + #include #include #include @@ -56,6 +58,9 @@ #include "ssl-utils.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (crashes) typedef struct { @@ -70,7 +75,7 @@ typedef struct { #pragma mark - #pragma mark SecureTransport support -#if 0 +#if SECTRANS_VERBOSE_DEBUG 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); @@ -189,12 +194,10 @@ static void *securetransport_ssl_thread(void *arg) SSLContextRef ctx = ssl->st; bool got_server_auth = false; - //uint64_t start = mach_absolute_time(); do { ortn = SSLHandshake(ctx); - if (ortn == errSSLServerAuthCompleted) - { + if (ortn == errSSLServerAuthCompleted) { require_string(!got_server_auth, out, "second server auth"); got_server_auth = true; } @@ -242,10 +245,6 @@ ssl_test_handle_create(bool server, int comm, CFArrayRef certs) 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; @@ -267,10 +266,11 @@ out: int i; - for(i=0; i<4; i++) - { + for (i = 0; i < 4; i++) { int sp[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) exit(errno); + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp)) { + exit(errno); + } fcntl(sp[0], F_SETNOSIGPIPE, 1); fcntl(sp[1], F_SETNOSIGPIPE, 1); @@ -279,8 +279,8 @@ out: 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; + server->test = i; + client->test = i; require(client, out); require(server, out); @@ -308,3 +308,5 @@ out: } @end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m index 7e41a080..2c81e923 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+dhe.m @@ -26,6 +26,7 @@ #include #include #include +#include #if TARGET_OS_IPHONE #include @@ -34,6 +35,9 @@ #include "ssl-utils.h" #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (dhe) /* @@ -101,8 +105,7 @@ typedef struct { unsigned dhe_size; } ssl_client_handle; -static ssl_client_handle * -ssl_client_handle_create(int comm, CFArrayRef trustedCA, unsigned dhe_size) +-(ssl_client_handle *)ssl_client_handle_create:(int) comm trustedCA:(CFArrayRef) trustedCA dhe_size:(unsigned) dhe_size { ssl_client_handle *handle = calloc(1, sizeof(ssl_client_handle)); SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); @@ -110,20 +113,27 @@ ssl_client_handle_create(int comm, CFArrayRef trustedCA, unsigned dhe_size) require(handle, out); require(ctx, out); - require_noerr(SSLSetIOFuncs(ctx, - (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); - require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + XCTAssertEqual(errSecSuccess, SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite)); + XCTAssertEqual(errSecSuccess, SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm)); + SSLConnectionRef getConn; + XCTAssertEqual(errSecSuccess, SSLGetConnection(ctx, &getConn)); 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); + XCTAssertEqual(errSecSuccess, SSLSetPeerDomainName(ctx, peer_domain_name, + strlen(peer_domain_name))); - require_noerr(SSLSetDHEEnabled(ctx, true), out); + XCTAssertEqual(errSecSuccess, SSLSetTrustedRoots(ctx, trustedCA, true)); - if(dhe_size) - require_noerr(SSLSetMinimumDHGroupSize(ctx, dhe_size), out); + XCTAssertEqual(errSecSuccess, SSLSetDHEEnabled(ctx, true)); + bool enabled; + XCTAssertEqual(errSecSuccess, SSLGetDHEEnabled(ctx, &enabled)); + XCTAssertEqual(enabled, true); + if(dhe_size) { + XCTAssertEqual(errSecSuccess, SSLSetMinimumDHGroupSize(ctx, dhe_size)); + unsigned int nbits = 0; + XCTAssertEqual(errSecSuccess, SSLGetMinimumDHGroupSize(ctx, &nbits)); + } handle->comm = comm; handle->st = ctx; handle->dhe_size = dhe_size; @@ -142,7 +152,7 @@ out: static void ssl_client_handle_destroy(ssl_client_handle *handle) { - if(handle) { + if (handle) { SSLClose(handle->st); CFRelease(handle->st); free(handle); @@ -158,15 +168,15 @@ static void *securetransport_ssl_client_thread(void *arg) pthread_setname_np("client thread"); - require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); - require_action(ssl_state==kSSLIdle, out, ortn = -1); + 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"); + require_string(ssl_state == kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); } } while (ortn == errSSLWouldBlock); @@ -185,40 +195,40 @@ typedef struct { } ssl_server_handle; -static ssl_server_handle * -ssl_server_handle_create(int comm, CFArrayRef certs, const void *dhParams, size_t dhParamsLen) +-(ssl_server_handle *)ssl_server_handle_create:(int) comm certs: (CFArrayRef) certs dhParams: (const void *)dhParams dhParamsLen: (size_t) dhParamsLen { ssl_server_handle *handle = calloc(1, sizeof(ssl_server_handle)); + XCTAssert(handle, "handle allocation failed"); + SSLContextRef ctx = SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType); - SSLCipherSuite cipher = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; + XCTAssert(ctx, "SSLCreateContext failed"); - require(handle, out); - require(ctx, out); + SSLCipherSuite cipher = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256; - require_noerr(SSLSetIOFuncs(ctx, - (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); - require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), out); + XCTAssertEqual(errSecSuccess, SSLSetIOFuncs(ctx, + (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), "Failed to Set IO"); + XCTAssertEqual(errSecSuccess, SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)comm), "Failed to set SSL connection"); - require_noerr(SSLSetCertificate(ctx, certs), out); + XCTAssertEqual(errSecSuccess, SSLSetCertificate(ctx, certs), "Failed to set certificate"); + CFArrayRef inputCerts = NULL; + XCTAssertEqual(errSecSuccess, SSLGetCertificate(ctx, &inputCerts), "Failed to get certificates"); - require_noerr(SSLSetEnabledCiphers(ctx, &cipher, 1), out); + XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(ctx, &cipher, 1), "SSLSetEnabledCiphers failed"); - if(dhParams) - require_noerr(SSLSetDiffieHellmanParams(ctx, dhParams, dhParamsLen), out); + if (dhParams) { + XCTAssertEqual(errSecSuccess, SSLSetDiffieHellmanParams(ctx, dhParams, dhParamsLen), + "Failed to set DH parameters"); + const void *inputDH = NULL; + size_t inputDHLen; + XCTAssertEqual(errSecSuccess, SSLGetDiffieHellmanParams(ctx, &inputDH, &inputDHLen), + "Failed to get DH parameters"); + } handle->comm = comm; handle->certs = certs; handle->st = ctx; return handle; - -out: - if (ctx) - CFRelease(ctx); - if (handle) - free(handle); - - return NULL; } static void @@ -240,21 +250,21 @@ static void *securetransport_ssl_server_thread(void *arg) pthread_setname_np("server thread"); - require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); - require_action(ssl_state==kSSLIdle, out, ortn = -1); + 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); + require_noerr(SSLGetSessionState(ctx, &ssl_state), out); if (ortn == errSSLWouldBlock) { - require_action(ssl_state==kSSLHandshake, out, ortn = -1); + require_action(ssl_state == kSSLHandshake, out, ortn = -1); } } while (ortn == errSSLWouldBlock); require_noerr_quiet(ortn, out); - require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(ssl_state == kSSLConnected, out, ortn = -1); out: SSLClose(ssl->st); @@ -360,8 +370,8 @@ int expected_client_error[n_server_dhe_params][n_client_dhe_sizes] = { int i, j; - for (i=0; i #include - #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (falsestart) typedef struct { @@ -62,8 +64,7 @@ typedef struct { } ssl_test_handle; - -#if 0 +#if SECTRANS_VERBOSE_DEBUG static void hexdump(const uint8_t *bytes, size_t len) { size_t ix; printf("socket write(%p, %lu)\n", bytes, len); @@ -104,7 +105,7 @@ static int SocketConnect(const char *hostName, int port) addr.sin_family = AF_INET; err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); - if(err!=0) + if(err != 0) { perror("connect failed"); return -1; @@ -132,9 +133,9 @@ static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *len if (ret > 0) { len -= ret; ptr += ret; - } - else + } else { return -36; + } } while (len > 0); *length = *length - len; @@ -152,11 +153,10 @@ OSStatus SocketRead( len = read(fd, data, *dataLength); - if(len<0) { + if (len < 0) { int theErr = errno; switch(theErr) { case EAGAIN: - //printf("SocketRead: EAGAIN\n"); *dataLength=0; /* nonblocking, no data */ return errSSLWouldBlock; @@ -166,8 +166,8 @@ OSStatus SocketRead( } } - if(len<(ssize_t)*dataLength) { - *dataLength=len; + if (len < (ssize_t)*dataLength) { + *dataLength = len; return errSSLWouldBlock; } @@ -193,8 +193,9 @@ static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, Boolean false_s return ctx; out: - if (ctx) + if (ctx) { SSLDisposeContext(ctx); + } return NULL; } @@ -210,23 +211,22 @@ static OSStatus securetransport(ssl_test_handle * ssl) ortn = SSLHandshake(ctx); - require_action_quiet(ortn==errSSLWouldBlock, out, printf("SSLHandshake failed with err %ld\n", (long)ortn)); + 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); + 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 == errSSLWouldBlock) { + r += sent; + l -= sent; } - if (ortn == errSSLServerAuthCompleted) - { + 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; @@ -237,9 +237,7 @@ static OSStatus securetransport(ssl_test_handle * ssl) /* 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"); + } while (ortn == errSSLWouldBlock || ortn == errSSLServerAuthCompleted); require_noerr_action_quiet(ortn, out, printf("SSLWrite failed with err %ld\n", (long)ortn)); @@ -247,17 +245,11 @@ static OSStatus securetransport(ssl_test_handle * ssl) do { ortn = SSLRead(ctx, reply, sizeof(reply)-1, &received); - //fprintf(stderr, "r"); usleep(1000); - } while(ortn == errSSLWouldBlock); - - //fprintf(stderr, "\n"); + } while (ortn == errSSLWouldBlock); 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); + reply[received] = 0; out: SSLClose(ctx); @@ -287,7 +279,6 @@ struct s_server { /* 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])) @@ -299,32 +290,32 @@ struct s_server { int p; int fs; - for(p=0; p #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (dhe) static @@ -33,6 +36,6 @@ OSStatus w(SSLConnectionRef connection, const void *data, size_t *dataLength) { CFRelease(ctx); } - @end +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m index 0d7e2ad9..e15156f0 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+renegotiate.m @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,9 @@ #include "ssl-utils.h" #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (renegotiation) /* @@ -463,3 +467,4 @@ out: } @end +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+session.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+session.m new file mode 100644 index 00000000..a91a1afd --- /dev/null +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+session.m @@ -0,0 +1,235 @@ +#import +#include +#include /* SSLSetOption */ +#include +#include +#include + +#import "STLegacyTests.h" +static unsigned char cert_der[] = { + 0x30, 0x82, 0x02, 0x79, 0x30, 0x82, 0x02, 0x23, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29, 0x2b, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x05, 0x05, 0x00, 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, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x38, 0x30, 0x39, 0x31, + 0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 0x17, 0x0d, 0x30, 0x39, + 0x30, 0x39, 0x31, 0x35, 0x32, 0x31, 0x35, 0x30, 0x35, 0x36, 0x5a, 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, 0x30, + 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + 0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, + 0xc0, 0x80, 0x43, 0xf1, 0x4d, 0xdc, 0x9a, 0x24, 0xe7, 0x25, 0x7c, 0x8b, + 0x8b, 0x65, 0x87, 0x97, 0xed, 0x3f, 0xfa, 0xfe, 0xbe, 0xcb, 0x12, 0x43, + 0x1f, 0x0c, 0xb5, 0xbf, 0x6b, 0x81, 0xee, 0x1b, 0x46, 0x6a, 0x02, 0x86, + 0x92, 0xec, 0x8a, 0xb3, 0x65, 0x77, 0x15, 0xd0, 0x49, 0xb4, 0x22, 0x84, + 0xf4, 0x85, 0x56, 0x53, 0xf5, 0x5a, 0x3b, 0xad, 0x23, 0xa8, 0x0c, 0x24, + 0xb7, 0xf5, 0xf4, 0xa1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xc3, + 0x30, 0x81, 0xc0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, + 0x04, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca, + 0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0x30, 0x81, + 0x90, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x81, 0x88, 0x30, 0x81, 0x85, + 0x80, 0x14, 0xe3, 0x58, 0xab, 0x35, 0xc0, 0x58, 0xb8, 0x65, 0x40, 0xca, + 0x9b, 0x6c, 0xeb, 0x2f, 0xf5, 0xbf, 0xbd, 0x0b, 0xf3, 0xa6, 0xa1, 0x62, + 0xa4, 0x60, 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, 0x82, 0x09, 0x00, 0xc2, 0xa8, 0x3b, 0xaa, 0x40, 0xa4, 0x29, + 0x2b, 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, 0x05, 0x05, 0x00, 0x03, 0x41, 0x00, 0x41, 0x40, 0x07, + 0xde, 0x1f, 0xd0, 0x00, 0x62, 0x75, 0x36, 0xb3, 0x94, 0xa8, 0xac, 0x3b, + 0x98, 0xbb, 0x28, 0x56, 0xf6, 0x9f, 0xe3, 0x87, 0xd4, 0xa1, 0x7a, 0x85, + 0xce, 0x40, 0x8a, 0xfd, 0x12, 0xb4, 0x99, 0x8c, 0x1d, 0x05, 0x61, 0xdb, + 0x35, 0xb8, 0x04, 0x7c, 0xfb, 0xe4, 0x97, 0x88, 0x66, 0xa0, 0x54, 0x7b, + 0x1c, 0xce, 0x99, 0xd8, 0xd3, 0x99, 0x80, 0x40, 0x9b, 0xa2, 0x73, 0x8b, + 0xfd +}; +static unsigned int cert_der_len = 637; + +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; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +@implementation STLegacyTests (session) + +-(void)test_set_protocol_version +{ + SSLContextRef ctx = NULL; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + SSLProtocol version; + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersionMin(ctx, &version)); + XCTAssertNotEqual(version, kSSLProtocolUnknown); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersionMin(ctx, kTLSProtocol12)); + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersionMin(ctx, &version)); + XCTAssertEqual(version, kTLSProtocol12); + + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersionMax(ctx, &version)); + XCTAssertEqual(version, kTLSProtocol12); + CFReleaseNull(ctx); +} + +-(void)test_set_peer_name +{ + SSLContextRef ctx = NULL; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + const char *peerName = "localhost"; + size_t peerNameLen = strlen(peerName); + XCTAssertEqual(errSecSuccess, SSLSetPeerDomainName(ctx, peerName, peerNameLen)); + size_t getPeerNameLen; + + XCTAssertEqual(errSecSuccess, SSLGetPeerDomainNameLength(ctx, &getPeerNameLen)); + XCTAssertEqual(getPeerNameLen, peerNameLen); + char *getPeerName = malloc(getPeerNameLen); + XCTAssertEqual(errSecSuccess, SSLGetPeerDomainName(ctx, getPeerName, &getPeerNameLen)); + free(getPeerName); + CFReleaseNull(ctx); +} + +-(void)test_set_session_ticket +{ + SSLContextRef ctx = NULL; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetSessionTicketsEnabled(ctx, true)); + CFReleaseNull(ctx); +} + +-(void)test_set_cert_verify +{ + SSLContextRef ctx; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetEnableCertVerify(ctx, false)); + Boolean enableVerify; + XCTAssertEqual(errSecSuccess, SSLGetEnableCertVerify(ctx, &enableVerify)); + XCTAssertEqual(false, enableVerify); + CFReleaseNull(ctx); +} + +-(void)test_set_any_root +{ + SSLContextRef ctx; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetAllowsAnyRoot(ctx, false)); + Boolean anyRoot; + XCTAssertEqual(errSecSuccess, SSLGetAllowsAnyRoot(ctx, &anyRoot)); + XCTAssertEqual(false, anyRoot); + CFReleaseNull(ctx); +} + +-(void)test_set_ca +{ + SSLContextRef serverCtx, clientCtx; + CFMutableArrayRef certList = NULL; + XCTAssert(serverCtx = SSLCreateContext(NULL, kSSLServerSide, kSSLStreamType), "SSLNewContext"); + XCTAssert(clientCtx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + SecCertificateRef cert = SecCertificateCreateWithBytes(kCFAllocatorDefault, + cert_der, cert_der_len); + + XCTAssertEqual(errSecParam, SSLSetCertificateAuthorities(clientCtx, cert, true)); + XCTAssertEqual(errSecSuccess, SSLSetCertificateAuthorities(serverCtx, cert, true)); + + certList = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(certList, cert); + XCTAssertEqual(errSecSuccess, SSLSetCertificateAuthorities(serverCtx, certList, true)); + + CFArrayRef inputCertList = NULL; + XCTAssertEqual(errSecSuccess, SSLCopyCertificateAuthorities(serverCtx, &inputCertList)); + CFReleaseNull(inputCertList); + CFReleaseNull(certList); + CFReleaseNull(cert); + CFReleaseNull(serverCtx); + CFReleaseNull(clientCtx); + +} + +-(void)test_set_psk_identity +{ + SSLContextRef ctx; + const uint8_t *pskIdentity; + size_t pskIdentityLen; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetPSKIdentity(ctx, "Client_identity", 15), "Set PSK Identity"); + XCTAssertEqual(errSecSuccess, SSLSetPSKIdentity(ctx, "Client_identity2", 16), "Set PSK Identity"); + XCTAssertEqual(errSecSuccess, SSLGetPSKIdentity(ctx, (void*)&pskIdentity, &pskIdentityLen), "Get PSK Identity"); + CFReleaseNull(ctx); +} + +-(void)test_get_set_ec_curves +{ + SSLContextRef ctx; + unsigned int numCurves; + SSL_ECDSA_NamedCurve ecCurve = SSL_Curve_secp256r1; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetECDSACurves(ctx, &ecCurve, 1), "Set EC Curve"); + XCTAssertEqual(errSecSuccess, SSLGetNumberOfECDSACurves(ctx, &numCurves), "Get number of EC curves"); + XCTAssertEqual(numCurves, 1); + SSL_ECDSA_NamedCurve *namedCurves = malloc(numCurves * sizeof(SSL_ECDSA_NamedCurve)); + SSLGetECDSACurves(ctx, namedCurves, &numCurves); + XCTAssertEqual(*namedCurves, ecCurve); + CFReleaseNull(ctx); +} + +-(void)test_set_protocol_version_deprecated +{ + SSLContextRef ctx; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, true)); + Boolean enabled; + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersionEnabled(ctx, kTLSProtocol12, &enabled)); + XCTAssertEqual(enabled, true); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersion(ctx, kTLSProtocol12)); + SSLProtocol protocol; + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersion(ctx, &protocol)); + XCTAssertEqual(protocol, kSSLProtocolAll); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersionEnabled(ctx, kTLSProtocol12, true)); + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersionEnabled(ctx, kTLSProtocol12, &enabled)); + XCTAssertEqual(enabled, true); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersionEnabled(ctx, kTLSProtocol1, false)); + XCTAssertEqual(errSecSuccess, SSLGetProtocolVersionEnabled(ctx, kTLSProtocol1, &enabled)); + XCTAssertEqual(enabled, false); + CFReleaseNull(ctx); +} + +-(void)test_ssl_error_session +{ + SSLContextRef ctx; + XCTAssert(ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType), "SSLNewContext"); + XCTAssertEqual(errSecSuccess, SSLSetError(ctx, errSecCertificateRevoked)); + XCTAssertEqual(errSecSuccess, SSLHandshake(ctx)); + CFReleaseNull(ctx); +} + +@end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m index 5d83e3c3..b0dd8676 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessioncache.m @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,9 @@ #include "ssl-utils.h" #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (sessioncache) /* @@ -121,6 +125,8 @@ ssl_client_handle_create(int comm, bool anyRoot, CFArrayRef trustedCA, bool trus require_noerr(SSLSetTrustedRoots(ctx, trustedCA, trustedCAOnly), out); #if !TARGET_OS_IPHONE require_noerr(SSLSetTrustedLeafCertificates(ctx, trustedLeafs), out); + CFArrayRef recvTrustedLeafs = NULL; + require_noerr(SSLCopyTrustedLeafCertificates(ctx, &recvTrustedLeafs), out); #endif require_noerr(SSLSetSessionCacheTimeout(ctx, cache_ttl), out); @@ -144,7 +150,7 @@ out: static void ssl_client_handle_destroy(ssl_client_handle *handle) { - if(handle) { + if (handle) { SSLClose(handle->st); CFRelease(handle->st); free(handle); @@ -160,15 +166,15 @@ static void *securetransport_ssl_client_thread(void *arg) pthread_setname_np("client thread"); - require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); - require_action(ssl_state==kSSLIdle, out, ortn = -1); + 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); + require_noerr(SSLGetSessionState(ctx, &ssl_state), out); if (ortn == errSSLWouldBlock) { - require_string(ssl_state==kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); + require_string(ssl_state == kSSLHandshake, out, "Wrong client handshake state after errSSLWouldBlock"); } } while (ortn == errSSLWouldBlock); @@ -228,7 +234,7 @@ out: static void ssl_server_handle_destroy(ssl_server_handle *handle) { - if(handle) { + if (handle) { SSLClose(handle->st); CFRelease(handle->st); free(handle); @@ -244,21 +250,21 @@ static void *securetransport_ssl_server_thread(void *arg) pthread_setname_np("server thread"); - require_noerr(ortn=SSLGetSessionState(ctx,&ssl_state), out); - require_action(ssl_state==kSSLIdle, out, ortn = -1); + 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); + require_noerr(SSLGetSessionState(ctx, &ssl_state), out); if (ortn == errSSLWouldBlock) { - require_action(ssl_state==kSSLHandshake, out, ortn = -1); + require_action(ssl_state == kSSLHandshake, out, ortn = -1); } } while (ortn == errSSLWouldBlock); require_noerr_quiet(ortn, out); - require_action(ssl_state==kSSLConnected, out, ortn = -1); + require_action(ssl_state == kSSLConnected, out, ortn = -1); out: SSLClose(ssl->st); @@ -279,9 +285,9 @@ out: 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++) { + 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; @@ -291,11 +297,11 @@ out: 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); + 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); + 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); @@ -371,7 +377,7 @@ out: 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); + 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); @@ -413,3 +419,4 @@ out: } @end +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m index 3c60b055..441ae283 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sessionstate.m @@ -39,6 +39,9 @@ #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (sessionstate) #define test_printf(x...) @@ -84,7 +87,7 @@ int tls_buffer_free(tls_buffer *buf) #pragma mark - #pragma mark SecureTransport support -#if 0 +#if SECTRANS_VERBOSE_DEBUG 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); @@ -120,7 +123,7 @@ static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length) struct RecQueueItem *item = STAILQ_FIRST(&handle->rec_queue); - if(item==NULL) { + if(item == NULL) { test_printf("%s: %p no data available\n", __FUNCTION__, h); return errSSLWouldBlock; } @@ -129,7 +132,7 @@ static OSStatus SocketRead(SSLConnectionRef h, void *data, size_t *length) test_printf("%s: %p %zd bytes available in %p\n", __FUNCTION__, h, avail, item); - if(avail > *length) { + if (avail > *length) { memcpy(data, item->record.data+item->offset, *length); item->offset += *length; } else { @@ -304,46 +307,6 @@ int mySSLRecordSetProtocolVersionFunc(tls_handshake_ctx_t ref, } -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, @@ -355,17 +318,13 @@ tls_handshake_callbacks_t myTLS_handshake_callbacks = { .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) { 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); @@ -435,6 +394,7 @@ out: ssl_test_handle *client; SSLSessionState state; + Boolean option; client = ssl_test_handle_create(false); @@ -443,6 +403,9 @@ out: ortn = SSLGetSessionState(client->st, &state); require_noerr(ortn, out); XCTAssertEqual(state, kSSLIdle, "State should be Idle"); + ortn = SSLGetSessionOption(client->st, kSSLSessionOptionBreakOnServerAuth, &option); + require_noerr(ortn, out); + XCTAssertEqual(option, true, "Session should break on Server auth"); do { ortn = SSLHandshake(client->st); @@ -450,13 +413,12 @@ out: require_noerr(SSLGetSessionState(client->st, &state), out); - if (ortn == errSSLPeerAuthCompleted || ortn == errSSLWouldBlock) - { - require_action(state==kSSLHandshake, out, ortn = -1); + if (ortn == errSSLPeerAuthCompleted || ortn == errSSLWouldBlock) { + require_action(state == kSSLHandshake, out, ortn = -1); } - } while(ortn==errSSLWouldBlock || - ortn==errSSLPeerAuthCompleted); + } while(ortn == errSSLWouldBlock || + ortn == errSSLPeerAuthCompleted); XCTAssertEqual(ortn, 0, "Unexpected SSLHandshake exit code"); @@ -464,20 +426,20 @@ out: uint8_t buffer[128]; size_t available = 0; + size_t avail = 0; test_printf("Initial handshake done\n"); do { + XCTAssertEqual(errSecSuccess, SSLGetBufferedReadSize(client->st, &avail)); 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); + if (ortn == errSSLPeerAuthCompleted) { + require_action(state == kSSLHandshake, out, ortn = -1); } - - } while(available==0); + } while (available == 0); XCTAssertEqual(ortn, 0, "Unexpected SSLRead exit code"); XCTAssertEqual(state, kSSLConnected, "State should be Connected"); @@ -490,3 +452,5 @@ out: } @end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m index 5a55ea82..ee34807c 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sni.m @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -32,6 +33,12 @@ #include "ssl-utils.h" #import "STLegacyTests.h" +#define serverSelectedProtocol "baz" +#define serverAdvertisedProtocols "\x03""baz" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (sni) typedef struct { @@ -45,7 +52,7 @@ typedef struct { #pragma mark - #pragma mark SecureTransport support -#if 0 +#if SECTRANS_VERBOSE_DEBUG static void hexdump(const uint8_t *bytes, size_t len) { size_t ix; printf("socket write(%p, %lu)\n", bytes, len); @@ -120,8 +127,6 @@ static void *securetransport_server_thread(void *arg) ortn = SSLHandshake(ctx); } while (ortn == errSSLWouldBlock); - ok(ortn==errSSLClientHelloReceived, "Unexpected Handshake exit code"); - if (ortn == errSSLClientHelloReceived) { char *sni = NULL; size_t length = 0; @@ -134,20 +139,35 @@ static void *securetransport_server_thread(void *arg) SSLProtocol version = 0; require_noerr(SSLGetProtocolVersionMax(ctx, &version), out); if (version == kSSLProtocol3) { - ok(sni==NULL, "Unexpected SNI"); + require_string(sni == NULL, out, "Unexpected SNI"); } else { - ok(sni!=NULL && + require_string(sni != NULL && length == sizeof(peername) && - (memcmp(sni, peername, sizeof(peername))==0), + (memcmp(sni, peername, sizeof(peername))==0), out, "SNI does not match"); } require_noerr(SSLSetCertificate(ctx, server_certs), out); free(sni); + + tls_buffer alpnData; + alpnData.length = strlen(serverSelectedProtocol); + alpnData.data = malloc(alpnData.length); + memcpy(alpnData.data, serverSelectedProtocol, alpnData.length); + require_noerr_string(SSLSetALPNData(ctx, alpnData.data, alpnData.length), out, "Error setting alpn data"); + free(alpnData.data); + + tls_buffer npnData; + npnData.length = strlen(serverAdvertisedProtocols); + npnData.data = malloc(npnData.length); + memcpy(npnData.data, serverAdvertisedProtocols, npnData.length); + require_noerr_string(SSLSetNPNData(ctx, npnData.data, npnData.length), out, "Error setting npn data"); + free(npnData.data); + } out: SSLClose(ctx); - SSLDisposeContext(ctx); + CFReleaseNull(ctx); close(ssl->comm); CFReleaseSafe(server_certs); @@ -165,8 +185,23 @@ static void *securetransport_client_thread(void *arg) ortn = SSLHandshake(ctx); } while (ortn == errSSLWouldBlock || ortn != errSSLClosedGraceful); + size_t length = 0; + uint8_t *alpnData = NULL; + alpnData = (uint8_t*)SSLGetALPNData(ctx, &length); + if (alpnData != NULL) { + require_noerr(memcmp(alpnData, serverSelectedProtocol, strlen(serverSelectedProtocol)), out); + } + + length = 0; + uint8_t *npnData = NULL; + npnData = (uint8_t*)SSLGetNPNData(ctx, &length); + if (npnData != NULL) { + require_noerr_string(memcmp(npnData, serverAdvertisedProtocols, strlen(serverAdvertisedProtocols)), + out, "npn Data received does not match"); + } +out: SSLClose(ctx); - SSLDisposeContext(ctx); + CFReleaseNull(ctx); close(ssl->comm); pthread_exit((void *)(intptr_t)ortn); @@ -197,10 +232,6 @@ ssl_test_handle_create(uint32_t session_id, bool server, int comm) 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; @@ -227,7 +258,7 @@ static int nversions = sizeof(versions)/sizeof(versions[0]); 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); + XCTAssertEqual(errSecSuccess, SSLSetPeerID(server->handle, &session_id, sizeof(session_id))); + XCTAssertEqual(errSecSuccess, SSLSetPeerID(client->handle, &session_id, sizeof(session_id))); + const void *inputPeerId = NULL; + size_t inputPeerIdLen; + XCTAssertEqual(errSecSuccess, SSLGetPeerID(client->handle, &inputPeerId, &inputPeerIdLen)); /* 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); + XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(client->handle, &ciphers[0], 1)); + XCTAssertEqual(errSecSuccess, SSLSetEnabledCiphers(server->handle, &ciphers[0], 1)); - require_noerr(SSLSetProtocolVersionMax(client->handle, versions[j]), out); - require_noerr(SSLSetPeerDomainName(client->handle, peername, sizeof(peername)), out); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersionMax(client->handle, versions[j])); + XCTAssertEqual(errSecSuccess, SSLSetPeerDomainName(client->handle, peername, sizeof(peername))); - require_noerr(SSLSetProtocolVersionMax(server->handle, versions[j]), out); + XCTAssertEqual(errSecSuccess, SSLSetProtocolVersionMax(server->handle, versions[j])); pthread_create(&client_thread, NULL, securetransport_client_thread, client); pthread_create(&server_thread, NULL, securetransport_server_thread, server); @@ -257,7 +291,6 @@ static int nversions = sizeof(versions)/sizeof(versions[0]); pthread_join(client_thread, (void*)&client_err); pthread_join(server_thread, (void*)&server_err); - out: free(client); free(server); @@ -265,3 +298,5 @@ static int nversions = sizeof(versions)/sizeof(versions[0]); } @end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m index 52aaca2c..9689198b 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+split.m @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -34,6 +36,9 @@ #include #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (split) typedef struct { @@ -50,7 +55,7 @@ typedef struct { #pragma mark - #pragma mark SecureTransport support -#if 0 +#if SECTRANS_VERBOSE_DEBUG 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); @@ -148,12 +153,10 @@ static void *securetransport_ssl_thread(void *arg) SSLContextRef ctx = ssl->st; bool got_server_auth = false; - //uint64_t start = mach_absolute_time(); do { ortn = SSLHandshake(ctx); - if (ortn == errSSLServerAuthCompleted) - { + if (ortn == errSSLServerAuthCompleted) { require_string(!got_server_auth, out, "second server auth"); got_server_auth = true; } @@ -167,7 +170,7 @@ static void *securetransport_ssl_thread(void *arg) if (ssl->is_server) { size_t len; - require_action(errSecSuccess==SecRandomCopyBytes(kSecRandomDefault, ssl->write_size, obuf), out, ortn = -1); + 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); @@ -194,8 +197,10 @@ out: static void ssl_test_handle_destroy(ssl_test_handle *handle) { - if(handle) { - if(handle->parser) tls_stream_parser_destroy(handle->parser); + if (handle) { + if (handle->parser) { + tls_stream_parser_destroy(handle->parser); + } free(handle); } } @@ -213,8 +218,9 @@ ssl_test_handle_create(bool server, int comm, CFArrayRef certs) (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)handle), out); - if (server) + if (server) { require_noerr(SSLSetCertificate(ctx, certs), out); + } require_noerr(SSLSetSessionOption(ctx, kSSLSessionOptionBreakOnServerAuth, true), out); @@ -308,7 +314,6 @@ static int nwsizes = sizeof(wsizes)/sizeof(wsizes[0]); // 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); @@ -326,7 +331,6 @@ static int nwsizes = sizeof(wsizes)/sizeof(wsizes[0]); 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); @@ -337,3 +341,5 @@ out: } @end + +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m index b41ae22c..5c4aa39f 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+sslciphers.m @@ -26,13 +26,16 @@ #include #include #include +#include #include "ssl-utils.h" - #include "cipherSpecs.h" #import "STLegacyTests.h" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + @implementation STLegacyTests (sslciphers) static int test_GetSupportedCiphers(SSLContextRef ssl, bool server) @@ -366,9 +369,8 @@ out: SSLContextRef ssl = NULL; bool server = (side == kSSLServerSide); - ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + 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); @@ -393,8 +395,8 @@ out: SSLContextRef ssl = NULL; bool server = (side == kSSLServerSide); - ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); - XCTAssert(ssl!=NULL, "test_config: SSLCreateContext(1) failed (%s)", server?"server":"client"); + 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 */ @@ -403,18 +405,47 @@ out: CFRelease(ssl); ssl=NULL; - ssl=SSLCreateContext(kCFAllocatorDefault, side, kSSLStreamType); + 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); + if (ssl) { + CFRelease(ssl); + } } +-(void) test_get_cipher_tls_version +{ + SSLContextRef ctx = NULL; + size_t num_ciphers; + SSLCipherSuite *ciphers = NULL; + SSLProtocol sslmin, sslmax; + ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType); + XCTAssert(ctx, "Error creating SSL context"); + XCTAssertEqual(errSecSuccess, SSLGetNumberEnabledCiphers(ctx, &num_ciphers)); + ciphers = (SSLCipherSuite *) malloc(num_ciphers * sizeof (SSLCipherSuite)); + + XCTAssertEqual(errSecSuccess, SSLGetEnabledCiphers(ctx, ciphers, &num_ciphers), "Error getting enabled ciphers"); + for (size_t i = 0; i < num_ciphers; i++) { + sslmin = SSLCiphersuiteMinimumTLSVersion(ciphers[i]); + XCTAssertNotEqual(kSSLProtocolUnknown, sslmin); + sslmax = SSLCiphersuiteMaximumTLSVersion(ciphers[i]); + } + free(ciphers); + CFReleaseNull(ctx); +} +-(void) test_cipher_group_to_list +{ + SSLCiphersuiteGroup group = kSSLCiphersuiteGroupDefault; + size_t cipher_count = 0; + const SSLCipherSuite *list = SSLCiphersuiteGroupToCiphersuiteList(group, &cipher_count); + XCTAssert(list, "Error getting cipher list for group"); +} -(void) testSSLCiphers { @@ -448,3 +479,4 @@ out: @end +#pragma clang diagnostic pop diff --git a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m index 9a2b321d..795b0f29 100644 --- a/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m +++ b/OSX/libsecurity_ssl/regressions/SecureTransportTests/STLegacyTests+tls12.m @@ -45,6 +45,7 @@ #include #include #include +#include #include #include @@ -74,9 +75,10 @@ typedef struct { CFArrayRef certs; } ssl_test_handle; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" - -#if 0 +#if SECTRANS_VERBOSE_DEBUG static void hexdump(const uint8_t *bytes, size_t len) { size_t ix; printf("socket write(%p, %lu)\n", bytes, len); @@ -117,8 +119,7 @@ static int SocketConnect(const char *hostName, int port) addr.sin_family = AF_INET; err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)); - if(err!=0) - { + if (err!=0) { perror("connect failed"); return -1; } @@ -137,15 +138,17 @@ static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *len do { hexdump(ptr, len); ret = write((int)conn, ptr, len); - if (ret < 0) + if (ret < 0) { perror("send"); + } } while ((ret < 0) && (errno == EAGAIN || errno == EINTR)); if (ret > 0) { len -= ret; ptr += ret; } - else + else { return -36; + } } while (len > 0); *length = *length - len; @@ -168,8 +171,9 @@ static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) len -= ret; ptr += ret; } - else + else { return -36; + } } while (len > 0); *length = *length - len; @@ -179,8 +183,7 @@ static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length) static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, const char *peerName) { SSLContextRef ctx = NULL; - - require_noerr(SSLNewContext(false, &ctx), out); + require((ctx = SSLCreateContext(kCFAllocatorDefault, kSSLClientSide, kSSLStreamType)), out); require_noerr(SSLSetIOFuncs(ctx, (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out); require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out); @@ -197,8 +200,7 @@ static SSLContextRef make_ssl_ref(int sock, SSLProtocol maxprot, const char *pee return ctx; out: - if (ctx) - SSLDisposeContext(ctx); + CFReleaseNull(ctx); return NULL; } @@ -209,12 +211,10 @@ static OSStatus securetransport(ssl_test_handle * ssl) 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) - { + 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; @@ -234,22 +234,17 @@ static OSStatus securetransport(ssl_test_handle * ssl) 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); */ + 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); + CFReleaseNull(ctx); + CFReleaseNull(trust); return ortn; } @@ -258,16 +253,15 @@ out: #define CONNECT_TRIES 3 --(ssl_test_handle*)ssl_test_handle_create:(struct s_server *)server +-(ssl_test_handle *)ssl_test_handle_create:(struct s_server *)server { int comm = -1; - for(int try = 0; comm<0 && tryhost, server->port); + for (int try = 0; comm < 0 && try < CONNECT_TRIES; try++) { + comm = SocketConnect(server->host, server->port); } - if(comm<0) { - XCTFail("connect failed with err=%d - %s:%d", comm, server->host, server->port); + if (comm < 0) { return NULL; } @@ -313,15 +307,15 @@ struct s_server servers[] = { int p; OSStatus r; - for(p=0; p #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-43-ciphers.c b/OSX/libsecurity_ssl/regressions/ssl-43-ciphers.c index 1577120e..f631878d 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-43-ciphers.c +++ b/OSX/libsecurity_ssl/regressions/ssl-43-ciphers.c @@ -47,6 +47,7 @@ #include #include +#include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-44-crashes.c b/OSX/libsecurity_ssl/regressions/ssl-44-crashes.c index 03e1fe95..807a0a85 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-44-crashes.c +++ b/OSX/libsecurity_ssl/regressions/ssl-44-crashes.c @@ -43,6 +43,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-48-split.c b/OSX/libsecurity_ssl/regressions/ssl-48-split.c index 8a47cd46..d4f73a0f 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-48-split.c +++ b/OSX/libsecurity_ssl/regressions/ssl-48-split.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-49-sni.c b/OSX/libsecurity_ssl/regressions/ssl-49-sni.c index 06a173d7..612a1ab9 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-49-sni.c +++ b/OSX/libsecurity_ssl/regressions/ssl-49-sni.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-53-clientauth.c b/OSX/libsecurity_ssl/regressions/ssl-53-clientauth.c index e2e9f709..8284b817 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-53-clientauth.c +++ b/OSX/libsecurity_ssl/regressions/ssl-53-clientauth.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-54-dhe.c b/OSX/libsecurity_ssl/regressions/ssl-54-dhe.c index d1ef7824..38d815e2 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-54-dhe.c +++ b/OSX/libsecurity_ssl/regressions/ssl-54-dhe.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-55-sessioncache.c b/OSX/libsecurity_ssl/regressions/ssl-55-sessioncache.c index 8f9add5b..e00d3c47 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-55-sessioncache.c +++ b/OSX/libsecurity_ssl/regressions/ssl-55-sessioncache.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-56-renegotiate.c b/OSX/libsecurity_ssl/regressions/ssl-56-renegotiate.c index a6525dbf..5bc08a2d 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-56-renegotiate.c +++ b/OSX/libsecurity_ssl/regressions/ssl-56-renegotiate.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/OSX/libsecurity_ssl/regressions/ssl-utils.c b/OSX/libsecurity_ssl/regressions/ssl-utils.c index 5875b2b1..4ff57578 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-utils.c +++ b/OSX/libsecurity_ssl/regressions/ssl-utils.c @@ -38,6 +38,7 @@ #include #include +#include #include "test-certs/eckey.h" #include "test-certs/eccert.h" @@ -90,9 +91,9 @@ CFArrayRef CF_RETURNS_RETAINED chain_from_der(bool ecdsa, const unsigned char *p require(items = CFArrayCreate(kCFAllocatorDefault, (const void **)&ident, 1, &kCFTypeArrayCallBacks), errOut); errOut: - CFReleaseSafe(pkey); - CFReleaseSafe(cert); - CFReleaseSafe(ident); + CFReleaseNull(pkey); + CFReleaseNull(cert); + CFReleaseNull(ident); return items; } @@ -110,7 +111,7 @@ CFArrayRef trusted_roots(void) require(roots = CFArrayCreate(kCFAllocatorDefault, (const void **)&cert, 1, &kCFTypeArrayCallBacks), errOut); errOut: - CFReleaseSafe(cert); + CFReleaseNull(cert); return roots; } diff --git a/OSX/libsecurity_ssl/regressions/ssl-utils.h b/OSX/libsecurity_ssl/regressions/ssl-utils.h index 68016da6..81642878 100644 --- a/OSX/libsecurity_ssl/regressions/ssl-utils.h +++ b/OSX/libsecurity_ssl/regressions/ssl-utils.h @@ -27,9 +27,6 @@ #include -#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) { CFRelease(_cf); } } -#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) { (CF) = NULL; CFRelease(_cf); } } - CFArrayRef CF_RETURNS_RETAINED trusted_roots(void); CFArrayRef CF_RETURNS_RETAINED server_chain(void); CFArrayRef CF_RETURNS_RETAINED server_ec_chain(void); diff --git a/OSX/libsecurity_ssl/regressions/ssl_regressions.h b/OSX/libsecurity_ssl/regressions/ssl_regressions.h index 83231a46..630b601a 100644 --- a/OSX/libsecurity_ssl/regressions/ssl_regressions.h +++ b/OSX/libsecurity_ssl/regressions/ssl_regressions.h @@ -19,9 +19,9 @@ ONE_TEST(ssl_42_ciphers) OFF_ONE_TEST(ssl_43_ciphers) ONE_TEST(ssl_44_crashes) -ONE_TEST(ssl_45_tls12) +OFF_ONE_TEST(ssl_45_tls12) ONE_TEST(ssl_46_SSLGetSupportedCiphers) -ONE_TEST(ssl_47_falsestart) +OFF_ONE_TEST(ssl_47_falsestart) ONE_TEST(ssl_48_split) // This one require a version of coreTLS that support SNI server side. (> coreTLS-17 ?) OFF_ONE_TEST(ssl_49_sni) diff --git a/OSX/libsecurity_transform/100-sha2.m b/OSX/libsecurity_transform/100-sha2.m deleted file mode 100644 index ec9d3c9c..00000000 --- a/OSX/libsecurity_transform/100-sha2.m +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright (c) 2010-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 "SecTransform.h" -#include "SecCustomTransform.h" -#include "SecDigestTransform.h" -#include -#include - -const CFStringRef kCaesarCipher = CFSTR("com.yourcompany.caesarcipher"); -const CFStringRef kKeyAttributeName = CFSTR("key"); - -// ========================================================================= -// Registration function for a ROT-N (caesar cipher) -// ========================================================================= -Boolean RegisterMyCustomTransform() -{ - static dispatch_once_t once; - __block Boolean ok = FALSE; - __block CFErrorRef error = NULL; - - SecTransformCreateBlock createCaesar = NULL; - - // Create the SecTransformCreateBlock block that will be used to - // register this custom transform - createCaesar =^(CFStringRef name, SecTransformRef new_transform, - const SecTransformCreateBlockParameters* parameters) - { - - CFErrorRef result = NULL; - - // Some basic parameter checking. - if (NULL == name || NULL == new_transform ) - { - // return the error - result = CFErrorCreate(kCFAllocatorDefault, SECTRANSFORM_ERROR_DOMAIN, - kSecTransformErrorInvalidInput, NULL); - - return result; - } - // Every time a new instance of this custom transform class is - // created, this block will be called. This behavior means that any - // block variables created in this block will act like instance - // variables for the new custom transform instance. In this case - // the key variable will be in every instance of this custom - // caesar transform - - __block int _key; - - // Use the overrideAttribute block to have our custom transform - // be notified if the 'key' attribute is set - - parameters->overrideAttribute( - kSecCustomTransformAttributeSetNotification, - kKeyAttributeName, - ^(SecTransformAttributeRef name, CFTypeRef d) - { - CFTypeRef result = NULL; - - if (NULL == d) - { - _key = 0; - return result; - } - - // Ensure the correct data type for this attribute - if (CFGetTypeID(d) == CFNumberGetTypeID()) - { - _key = 0; - - if (!CFNumberGetValue((CFNumberRef)d, - kCFNumberIntType, &_key)) - { - _key = 0; - // return the error - result = (CFTypeRef)CFErrorCreate(kCFAllocatorDefault, SECTRANSFORM_ERROR_DOMAIN, - kSecTransformErrorInvalidInput, NULL); - - return result; - } - else - { - result = d; - } - } - - return result; - - }); - - // Use the overrideAttribute to change the processing of the data - // for this transform - parameters->overrideAttribute(kSecCustomTransformProcessData, - NULL, - ^(SecTransformAttributeRef name, CFTypeRef d) - { - CFTypeRef result = NULL; - if (NULL == d) - { - // return the error - result = (CFTypeRef)CFErrorCreate(kCFAllocatorDefault, SECTRANSFORM_ERROR_DOMAIN, - kSecTransformErrorInvalidInput, NULL); - - return result; - } - - if (CFGetTypeID(d) != CFDataGetTypeID()) - { - // return the error - result = (CFTypeRef)CFErrorCreate(kCFAllocatorDefault, SECTRANSFORM_ERROR_DOMAIN, - kSecTransformErrorInvalidInput, NULL); - - return result; - } - - CFDataRef theData = (CFDataRef)d; - - CFIndex dataLength = CFDataGetLength(theData); - - // Do the processing in memory. There are better ways to do - // this but for showing how custom transforms work this is fine. - char* buffer = (char*)malloc(dataLength); - if (NULL == buffer) - { - //return the error - result = (CFErrorRef)CFErrorCreate(kCFAllocatorDefault, SECTRANSFORM_ERROR_DOMAIN, - kSecTransformErrorInvalidInput, NULL); - - return result; - } - - const char* dataPtr = (const char* )CFDataGetBytePtr(theData); - if (NULL == dataPtr) - { - free(buffer); - //return the error - result = (CFErrorRef)CFErrorCreate(kCFAllocatorDefault, SECTRANSFORM_ERROR_DOMAIN, - kSecTransformErrorInvalidInput, NULL); - - return result; - } - // Do the work of the caesar cipher (Rot(n)) - - char rotValue = (char)_key; - CFIndex iCnt; - for (iCnt = 0; iCnt < dataLength; iCnt++) - { - buffer[iCnt] = dataPtr[iCnt] + rotValue; - } - - result = (CFTypeRef)CFDataCreate(kCFAllocatorDefault, - (const UInt8 *)buffer, dataLength); - free(buffer); - return result; - - }); - }; - - // Make sure the custom transform is only registered once - dispatch_once(&once, - ^{ - (void)SecCustomTransformRegister(kCaesarCipher, &error, - createCaesar); - }); - - return (error == NULL); -} - -//The second function show how to use the this custom transform: - -// ========================================================================= -// Use a custom ROT-N (caesar cipher) transform -// ========================================================================= -CFStringRef DoCaesar(CFStringRef clearTest, int rotNumber) -{ - CFStringRef result = NULL; - - if (NULL == clearTest) - { - return result; - } - - if (!RegisterMyCustomTransform()) - { - return result; - } - - CFErrorRef error = NULL; - - SecTransformRef caesarCipher = - SecCustomTransformCreate(kCaesarCipher, &error); - if (NULL == caesarCipher || NULL != error) - { - return result; - } - - CFDataRef data = - CFStringCreateExternalRepresentation(kCFAllocatorDefault, - clearTest, kCFStringEncodingUTF8, 0); - if (NULL == data) - { - CFRelease(caesarCipher); - return result; - } - - SecTransformSetAttribute(caesarCipher, - kSecTransformInputAttributeName, data, &error); - CFRelease(data); - if (NULL != error) - { - CFRelease(caesarCipher); - return result; - } - - CFNumberRef keyNumber = - CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &rotNumber); - if (NULL == keyNumber) - { - CFRelease(caesarCipher); - return result; - } - - SecTransformSetAttribute(caesarCipher, kKeyAttributeName, - keyNumber, &error); - CFRelease(keyNumber); - if (NULL != error) - { - CFRelease(caesarCipher); - return result; - } - - CFDataRef dataResult = - (CFDataRef)SecTransformExecute(caesarCipher, &error); - CFRelease(caesarCipher); - if (NULL != dataResult && NULL == error) - { - result = - CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, - dataResult, kCFStringEncodingUTF8); - CFRelease(dataResult); - } - - return result; -} - -int main(int argc, char *argv[]) -{ - if (!RegisterMyCustomTransform()) - { - return -1; - } - - CFStringRef testStr = CFSTR("When in the course of human event"); - CFStringRef aStr = DoCaesar(testStr, 4); - CFStringRef clearStr = DoCaesar(aStr, -4); - if (CFEqual(testStr, clearStr)) - { - CFShow(CFSTR("All is right with the world")); - return 0; - } - - CFShow(CFSTR("Bummer!")); - return -1; - -} - - - -/* -CFReadStreamRef CFReadStreamCreateWithFD(CFAllocatorRef a, int fd) { - char *fname; - asprintf(&fname, "/dev/fd/%d", fd); - CFURLRef f = CFURLCreateFromFileSystemRepresentation(a, (UInt8*)fname, strlen(fname), FALSE); - CFReadStreamRef rd = CFReadStreamCreateWithFile(a, f); - CFRelease(f); - - return rd; -} - -void pair_CFReadStream_fd(CFReadStreamRef *sr, int *fd) { - int fds[2]; - int rc = pipe(fds); - assert(rc >= 0); - *fd = fds[1]; - *sr = CFReadStreamCreateWithFD(NULL, fds[0]); -} - -CFReadStreamRef many_zeros(uint64_t goal) { - CFReadStreamRef rd; - int fd; - pair_CFReadStream_fd(&rd, &fd); - - // XXX: replace with a dispatch_source and non-blocking I/O... - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - uint64_t nwrites = 0; - char buf[1024*8]; - bzero(buf, sizeof(buf)); - uint64_t left = goal; - - while (left) { - size_t try = (sizeof(buf) < left) ? sizeof(buf) : left; - ssize_t sz = write(fd, buf, try); - if (sz <= 0) { - fprintf(stderr, "Write return %zd, errno=%d\n", sz, errno); - } - assert(sz >= 0); - left -= sz; - nwrites++; - } - - close(fd); - }); - - - return rd; -} - -int main(int argc, char *argv[]) { - CFReadStreamRef rd = many_zeros(1024*1024 *100LL); - Boolean ok = CFReadStreamOpen(rd); - assert(ok); - - SecTransformRef dt = SecDigestTransformCreate(kSecDigestSHA2, 512, NULL); - SecTransformSetAttribute(dt, kSecTransformInputAttributeName, rd, NULL); - - CFDataRef d = SecTransformExecute(dt, NULL); - - return 0; -} -*/ diff --git a/OSX/libsecurity_transform/custom.mm b/OSX/libsecurity_transform/custom.mm deleted file mode 100644 index 64dbe89e..00000000 --- a/OSX/libsecurity_transform/custom.mm +++ /dev/null @@ -1,5118 +0,0 @@ -/* - * Copyright (c) 2010 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 "SecTransform.h" -#import "SecCustomTransform.h" -#import "SecDigestTransform.h" -#import "SecEncryptTransform.h" -#import "SecEncodeTransform.h" -#import "SecDecodeTransform.h" -#import "SecSignVerifyTransform.h" -#import "SecNullTransform.h" -#import "SecExternalSourceTransform.h" -#import -#import "misc.h" -#import "Utilities.h" -#import "SecNullTransform.h" -#include "regex.h" -#include -#import "SecMaskGenerationFunctionTransform.h" -#import "SecTransformInternal.h" -#import "custom.h" -#include "SecTransformReadTransform.h" -#import "SecTransformValidator.h" -#include -#include -#include -#include -#include -#include -#include -#include -#import "NSData+HexString.h" -#include -#include -#include - -// compatibility layer -struct SecTransformCreateBlockParameters { - CFTypeRef (^send)(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type, CFTypeRef value); - CFTypeRef (^get)(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type); - CFTypeRef (^pushback)(SecTransformStringOrAttributeRef attribute, CFTypeRef value); - CFErrorRef (^overrideTransform)(CFStringRef action, SecTransformActionBlock newAction); - CFErrorRef (^overrideAttribute)(CFStringRef action, SecTransformStringOrAttributeRef attribute, SecTransformAttributeActionBlock newAction); -}; - -typedef void (^SecTransformCreateBlock)(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params); - -SecTransformCreateBlock global_create_block; - -static SecTransformInstanceBlock block_for_custom_transform(CFStringRef name, SecTransformRef tr, SecTransformImplementationRef ir) -{ - SecTransformInstanceBlock b = ^{ - // XXX: leak, need to override Finalize and clean up… (and need to handle caller overriding finalize…) - SecTransformCreateBlockParameters *params = static_cast(malloc(sizeof(SecTransformCreateBlockParameters))); - - params->overrideAttribute = ^(CFStringRef action, SecTransformStringOrAttributeRef attribute, SecTransformAttributeActionBlock newAction) { - // We don't need to special case ProcessData to call SecTransformSetDataAction as there are no longer any uses of it - return SecTransformSetAttributeAction(ir, action, attribute, newAction); - }; - - params->overrideTransform = ^(CFStringRef action, SecTransformActionBlock newAction) { - return SecTransformSetTransformAction(ir, action, newAction); - }; - - params->get = ^(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type) { - return SecTranformCustomGetAttribute(ir, attribute, type); - }; - - params->send = ^(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type, CFTypeRef value) { - return SecTransformCustomSetAttribute(ir, attribute, type, value); - }; - - params->pushback = ^(SecTransformStringOrAttributeRef attribute, CFTypeRef value) { - return SecTransformPushbackAttribute(ir, attribute, value); - }; - - params->overrideAttribute = Block_copy(params->overrideAttribute); - params->overrideTransform = Block_copy(params->overrideTransform); - params->get = Block_copy(params->get); - params->send = Block_copy(params->send); - params->pushback = Block_copy(params->pushback); - - global_create_block(name, tr, params); - - return (CFErrorRef)NULL; - }; - - return Block_copy(b); -} - -// Sort of a bridge from the old Custom SPI to the new API, but is also -// useful when you REALLY need to access stack locals as __block variables, -// but don't need multithreading, or generic internalizing. -static SecTransformRef custom_transform(CFStringRef base_name, SecTransformCreateBlock cb) -{ - static int ct_cnt = 0; - static dispatch_queue_t cnt_q = dispatch_queue_create("com.apple.security.custom_trasnform-cnt", 0); - __block CFStringRef name = NULL; - __block SecTransformRef ret = NULL; - - dispatch_sync(cnt_q, ^{ - CFErrorRef err = NULL; - - name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.%d"), base_name, ct_cnt++); - global_create_block = cb; - if (SecTransformRegister(name, block_for_custom_transform, &err)) { - ret = SecTransformCreate(name, &err); - if (err) { - CFfprintf(stderr, "Error %@ creating %@\n", err, base_name); - CFRelease(err); - } - } else { - CFfprintf(stderr, "Error %@ registering %@\n", err, base_name); - CFRelease(err); - } - global_create_block = NULL; - CFRelease(name); - }); - - return ret; -} - - -#define STAssertErrorHas(err, rx, msg...) STAssertTrue(ErrorHas(err, rx), ##msg); - -static BOOL ErrorHas(NSError *error, NSString *rx) { - if (!error) { - return NO; - } - if (![error isKindOfClass:[NSError class]]) { - return NO; - } - - NSString *es = [error description]; - if (!es) { - return NO; - } - return [es rangeOfString:rx options:NSRegularExpressionSearch].location != NSNotFound; -} - - -static SecTransformInstanceBlock DelayTransformBlock(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - - - SecTransformSetDataAction(ref, kSecTransformActionProcessData, - ^(CFTypeRef value) - { - - if (NULL != value && CFNumberGetTypeID() == CFGetTypeID(value)) - { - long long n; - CFNumberGetValue((CFNumberRef)value, kCFNumberLongLongType, &n); - usleep((useconds_t)(n / NSEC_PER_USEC)); - } - - return value; - }); - return result; - }; - - return Block_copy(instanceBlock); -} - -static SecTransformRef delay_transform(long long nsec) { - CFStringRef name = CFSTR("com.apple.security.unit-test.delay"); - - - - static dispatch_once_t once; - __block Boolean ok = TRUE; - - dispatch_block_t aBlock = ^ - { - ok = SecTransformRegister(name, &DelayTransformBlock, NULL); - }; - - dispatch_once(&once, aBlock); - - if (!ok) - { - return NULL; - } - - SecTransformRef ct = SecTransformCreate(name, NULL); - CFNumberRef nr = CFNumberCreate(NULL, kCFNumberLongLongType, &nsec); - SecTransformSetAttribute(ct, CFSTR("DELAY"), nr, NULL); - CFRelease(nr); - - return ct; -} - -@implementation custom - -class BufferStream -{ -protected: - const char* mBuffer; - size_t mLength; - size_t mStringLength; - size_t mPos; - - char *mCurrentString; - -public: - BufferStream(const char* buffer, size_t length) : mBuffer(buffer), mLength(length), mStringLength(0), mPos(0), mCurrentString(NULL) {} - ~BufferStream(); - - const char* GetNextString(); - void SplitString(const char*& stringA, const char*& stringB); -}; - - - -BufferStream::~BufferStream() -{ - if (NULL != mCurrentString) - { - free(mCurrentString); - } -} - - - -const char* BufferStream::GetNextString() -{ - size_t p = mPos; - if (p >= mLength) - { - return NULL; // eof - } - - // run to either the end of the buffer or a return - while (p < mLength && mBuffer[p] != '\n') - { - p += 1; - } - - if (p != mLength) - { - // handle the end of the buffer specially, since it doesn't point - // to valid space - p -= 1; - } - - // p now points to the last character in the string - // allocate memory for our buffer - mStringLength = p - mPos + 1; - mCurrentString = (char*) realloc(mCurrentString, mStringLength + 1); - memmove(mCurrentString, mBuffer + mPos, mStringLength); - mCurrentString[mStringLength] = 0; - mPos = p + 2; - - return mCurrentString; -} - - - -void BufferStream::SplitString(const char*& a, const char*& b) -{ - // scan the buffer, looking for a ':' - size_t p = 0; - while (mCurrentString[p] != 0 && mCurrentString[p] != ':') - { - p += 1; - } - - // the first string is always our buffer pointer - a = mCurrentString; - - if (mCurrentString[p] == ':') - { - mCurrentString[p] = 0; - - // look for the beginning of the next string - p += 1; - while (p < mLength && isspace(mCurrentString[p])) - { - p += 1; - } - - b = mCurrentString + p; - } - else - { - b = NULL; - } -} - - - --(void)disabledtestzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz -{ - // open leaks and make a connection to it. - char* name; - - const int kChunkSize = 16384; - char buffer[kChunkSize]; - pid_t thePid = getpid(); - asprintf(&name, "/tmp/leaks%d.txt", thePid); - sprintf(buffer, "/usr/bin/leaks %d >%s", thePid, name); - system(buffer); - - struct stat st; - stat(name, &st); - - char* rBuffer = (char*) malloc((size_t)st.st_size); - FILE* f = fopen(name, "r"); - fread(rBuffer, 1, (size_t)st.st_size, f); - fclose(f); - - // set up our output parser - BufferStream bStream(rBuffer, (size_t)st.st_size); - const char* s = bStream.GetNextString(); - - bool didError = true; - - if (NULL != s) - { - // we have our string, split it and see what it means - const char* key; - const char* value; - - bStream.SplitString(key, value); - if (strcmp(key, "leaks Report Version") != 0 || strcmp(value, "2.0") != 0) - { - didError = true; - } - else - { - didError = false; - } - } - - if (!didError) - { - const char* key; - const char* value; - - // figure out what our target line will look like - char* target; - asprintf(&target, "Process %d", thePid); - - const char* nextString = bStream.GetNextString(); - while (nextString) - { - bStream.SplitString(key, value); - if (strcmp(key, target) == 0) // we found our target!!! - { - // do it again - bStream.GetNextString(); - bStream.SplitString(key, value); - - if (value[0] != '0') // we have a non-zero result... :( - { - didError = true; - } - } - - nextString = bStream.GetNextString(); - } - - free(target); - } - - STAssertFalse(didError, @"You have leaks!"); - - if (didError) - { - // dump to our output file - // make a file name for the leaks output - FILE* f = fopen(name, "w"); - fwrite(rBuffer, 1, (size_t)st.st_size, f); - fclose(f); - } - else - { - unlink(name); - } - - free(name); -} - - - -static const char* gHMACText = "The judicial Power shall extend to all Cases, in " - "Law and Equity, arising under this Constitution, " - "the Laws of the United States, and Treaties made, " - "or which shall be made, under their Authority;--to " - "all Cases affecting Ambassadors, other public " - "Ministers and Consuls;--to all Cases of admiralty " - "and maritime Jurisdiction;--to Controversies to " - "which the United States shall be a Party;--to " - "Controversies between two or more States;-- " - "between a State and Citizens of another State, " - "--between Citizens of different States,-- " - "between Citizens of the same State claiming Lands " - "under Grants of different States, and between a " - "State, or the Citizens thereof, and foreign " - "States, Citizens or Subjects"; - -const NSString* gAbortTransformName = (NSString*) kSecTransformAbortAttributeName; - -static const char* gHMACKey = "No person shall be held to answer for a capital, or " - "otherwise infamous crime, unless on a presentment " - "or indictment of a Grand Jury, except in cases " - "arising in the land or naval forces, or in the " - "Militia, when in actual service in time of War or " - "public danger; nor shall any person be subject for " - "the same offence to be twice put in jeopardy of life " - "or limb; nor shall be compelled in any criminal case " - "to be a witness against himself, nor be deprived of " - "life, liberty, or property, without due process of " - "law; nor shall private property be taken for public " - "use, without just compensation."; - -static const u_int8_t gSHA1HMAC[] = {0x2f, 0x68, 0x4b, 0x6b, 0x4f, - 0xf7, 0x41, 0xc3, 0x76, 0x3d, - 0x0b, 0xc3, 0x25, 0x02, 0x99, - 0x03, 0xfa, 0xa5, 0xe9, 0xde}; - -static const u_int8_t gSHA256HMAC[] = {0xc2, 0x5c, 0x9a, 0x65, 0x08, 0x9e, 0x61, 0xb5, - 0x03, 0xfe, 0xcb, 0x57, 0xb7, 0x55, 0x4f, 0x69, - 0xdb, 0xef, 0xdb, 0xe7, 0x0d, 0xe2, 0x78, 0x2e, - 0xf9, 0x48, 0xbd, 0xf6, 0x4f, 0x4b, 0x94, 0x0c}; --(void)testPaddings -{ - CFStringRef paddings[] = {kSecPaddingNoneKey, kSecPaddingPKCS7Key, kSecPaddingPKCS5Key, kSecPaddingPKCS1Key}; - - for(int i = 0; i < sizeof(paddings) / sizeof(*paddings); i++) { - CFErrorRef error = NULL; - SecKeyRef cryptokey = NULL; - SecTransformRef encrypt = NULL, decrypt = NULL; - CFDataRef cfdatacryptokey = NULL, sourceData = NULL, encryptedData = NULL, decryptedData = NULL; - const uint8_t rawcryptokey[16] = { 63, 17, 27, 99, 185, 231, 1, 191, 217, 74, 141, 16, 12, 99, 253, 41 }; // 128-bit AES key. - const char *sourceCString = "All these worlds are yours except Europa."; // I'm not so sure about that Earth one either - - CFMutableDictionaryRef parameters = CFDictionaryCreateMutable( - kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES); - - cfdatacryptokey = CFDataCreate(kCFAllocatorDefault, rawcryptokey, - sizeof(rawcryptokey)); - cryptokey = SecKeyCreateFromData(parameters, - cfdatacryptokey, &error); - STAssertNil((id)error, @"Unexpected SecKeyCreateFromData error: %@", error); - - size_t len = strlen(sourceCString) +1; - if (paddings[i] == kSecPaddingNoneKey) { - STAssertTrue(len >= kCCBlockSizeAES128, @"Had at least one block"); - // Get to an AES block multiple, discarding bytes wildly. - len -= len % kCCBlockSizeAES128; - } - sourceData = (CFDataRef)[NSData dataWithBytes:sourceCString length:len]; - - encrypt = SecEncryptTransformCreate(cryptokey, &error); - STAssertNil((id)error, @"Unexpected error creating encrypt transform: %@", error); - decrypt = SecDecryptTransformCreate(cryptokey, &error); - STAssertNil((id)error, @"Unexpected error creating decrypt transform: %@", error); - - /* Set the padding on the transforms */ - SecTransformSetAttribute(encrypt, kSecPaddingKey, paddings[i], &error); - STAssertNil((id)error, @"Couldn't set encrypt padding to %@: %@", paddings[i], error); - SecTransformSetAttribute(decrypt, kSecPaddingKey, paddings[i], &error); - STAssertNil((id)error, @"Couldn't set decrypt padding to %@: %@", paddings[i], error); - - SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName, sourceData, &error); - STAssertNil((id)error, @"Couldn't set encrypt transform input: %@", error); - - encryptedData = (CFDataRef)SecTransformExecute(encrypt, &error); - STAssertNil((id)error, @"Couldn't execute encrypt: %@ (padding %@)", paddings[i], error); - STAssertNotNil((id)encryptedData, @"Didn't get encrypted data"); - - SecTransformSetAttribute(decrypt, kSecTransformInputAttributeName, encryptedData, &error); - STAssertNil((id)error, @"Couldn't set decrypt transform input: %@", error); - - decryptedData = (CFDataRef)SecTransformExecute(decrypt, &error); - STAssertNil((id)error, @"Couldn't execute decrypt: %@", error); - STAssertNotNil((id)decryptedData, @"Didn't get decrypt data"); - - STAssertEqualObjects((id)decryptedData, (id)sourceData, @"Decrypt output didn't match encrypt input for padding %@", paddings[i]); - } -} - -static SecTransformInstanceBlock nopInstance(CFStringRef name, SecTransformRef newTransform, SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = ^{ - return (CFErrorRef)NULL; - }; - - return Block_copy(instanceBlock); -} - - --(void)test_manyregister -{ - dispatch_apply(4000, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^(size_t i) { - NSString *name = [NSString stringWithFormat:@"many%luregister", i]; - CFErrorRef err = NULL; - BOOL ok = SecTransformRegister((CFStringRef)name, nopInstance, &err); - STAssertTrue(ok, @"register not ok"); - STAssertNil((id)err, @"register error: %@", err); - }); -} - --(void)test_emptyOAEP -{ - SecKeychainRef tmp_keychain = NULL; - char *kcfname; - asprintf(&kcfname, "%s-OAEP-XXXXXXXXXX", "/tmp/"); - const char *passwd = "sekret"; - // NOTE: "mktemp" isn't as safe as you might think...but this is test code and doesn't have to be, but - // if you copy it elsewhere you may well need to rewrite it. (use mkstemp) - mktemp(kcfname); - OSStatus status = SecKeychainCreate(kcfname, (UInt32)strlen(passwd), passwd, NO, NULL, &tmp_keychain); - STAssertTrue(status == 0, @"Expected to make keychain, but got error 0x%x", status); - - const char *pem_key_bytes[] = { - // From the spec - "-----BEGIN PUBLIC KEY-----\nMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC7+C8JBoLOnCM4rCudqHH3No0H\n7tQQQ6RA1rbwdFT1H7jfuq8DXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jg\no9/HN3I+5rS32TolhO5qZJ0GCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNy\nmMoqj1lG+OX9CR29ywIBEQ==\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQC7+C8JBoLOnCM4rCudqHH3No0H7tQQQ6RA1rbwdFT1H7jfuq8D\nXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jgo9/HN3I+5rS32TolhO5qZJ0G\nCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNymMoqj1lG+OX9CR29ywIBEQKB\ngQCl2vxTQfryicS5iNswwc34PzElHgZotCeEgTgBV5ZBspQQs8eZjWvEZXReXDkm\nadaHDaLAgqk543/cuC7JPtrJf/OtWVCsz7wRHHbxqVKUROVqr2jFbAks043DvvXS\nCpOZJu1PdKE+3fvhoc7MSJSvlCjCt7iIP+RGOkvIWxyzwQJBAO7ProGxubPJCIEL\nEKG1YAGZ659ErvT9pJO4Gp49hPYyEk7wI25dHjt+KPrnqgQKLVslIXZFnR85dUG6\nKlj7ZZkCQQDJf7HwJ/RT9jQSM+qq0dk1P2xC0IhmsdBaDyA1AoudhphAtBZmtC6S\n6g2jtDIEtc/OM1JSTQQWpaRB5wCvRhUDAkBUSUymProDN+TiQCP81ppa6wfd3AGD\npNCsm1SwUfKxPtlJCXXqt3QU/1nB92kumi4gKzj8kQpHQXStyTwfZ8mBAkBHHgKQ\n/wrwdQNRt/h4hkypYa29Oop+mRxcBVapTDFGp/mAP49viuNC6TH9iuR6Ig0bmaSV\nhJgH/jn5JFqYNto9AkEAsGxP2rtjARmNJlvbrpQjs4Dycfc0U4hQkwd/zTniEZ/J\nhjIVT1iDsWepZ79AK06eLg+WVuaY6jZm7fsleYA59w==\n-----END RSA PRIVATE KEY-----\n", - NULL, - }; - struct key_pair { - SecKeyRef pubKey, privKey; - }; - key_pair keys[1]; - - int i; - for(i = 0; i < sizeof(keys)/sizeof(key_pair); i++) { - NSAssert(pem_key_bytes[i] != NULL, @"Expected a key"); - NSLog(@"Importing: %s", pem_key_bytes[i]); - CFDataRef pem_data = CFDataCreate(NULL, (UInt8*)(pem_key_bytes[i]), strlen(pem_key_bytes[i])); - SecKeyImportExportParameters import_params; - bzero(&import_params, sizeof(import_params)); - - import_params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - import_params.keyUsage = CSSM_KEYUSE_ANY; - import_params.keyAttributes = CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_SENSITIVE; - import_params.accessRef = NULL; - import_params.passphrase = CFSTR(""); - import_params.alertPrompt = CFSTR(""); - - CFArrayRef keypair = NULL; - SecExternalFormat key_format = kSecFormatOpenSSL; - SecExternalItemType itemType = kSecItemTypeUnknown; - status = SecKeychainItemImport(pem_data, CFSTR(".pem"), &key_format, &itemType, 0, &import_params, tmp_keychain, &keypair); - STAssertTrue(status == 0, @"Expected pubkey import to be ok, got err=0x%x", status); - NSAssert(keypair != NULL, @"Expected to get some keys back"); - STAssertNotNil((id)keypair, @"Expected to get some keys back"); - STAssertTrue(CFArrayGetCount(keypair) == 2, @"Expected 2 keys, got %@", keypair); - keys[i].pubKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 0); - keys[i].privKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 1); - } - STAssertNil((id)pem_key_bytes[i], @"Expected to convert all pem keys, but found at least: %s", pem_key_bytes[i]); - CFDataRef encoding_parameters = CFDataCreate(NULL, NULL, 0); - - - CFErrorRef err = NULL; - - SecTransformRef encryptor = SecEncryptTransformCreate(keys[0].pubKey, &err); - - CFReadStreamRef empty_stream = CFReadStreamCreateWithBytesNoCopy(NULL, (UInt8*)"", 0, kCFAllocatorNull); - SecTransformSetAttribute(encryptor, kSecTransformInputAttributeName, empty_stream, &err); - SecTransformSetAttribute(encryptor, kSecPaddingKey, kSecPaddingOAEPKey, &err); - SecTransformSetAttribute(encryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, &err); - - CFTypeRef encryptedData = SecTransformExecute(encryptor, &err); - STAssertNotNil((id)encryptedData, @"Expected to get encrypted data"); - STAssertNil((NSError*)err, @"Expected no error, got err=%@", err); - // Can't support "seed" with commoncrypto, just check round trip. - //STAssertEqualObjects((id)encryptedData, (id)tests[i].encryptedMessage, @"encrypted data should have matched test vector (%@) data", tests[i].label); - CFRelease(encryptor); - - SecTransformRef decryptor = SecDecryptTransformCreate(keys[0].privKey, NULL); - // XXX: totally round trip, not even partial KAT (KAT can't really be done on OAEP - // without supporitng settign the seed externally) - SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, encryptedData, NULL); - SecTransformSetAttribute(decryptor, kSecPaddingKey, kSecPaddingOAEPKey, NULL); - SecTransformSetAttribute(decryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, NULL); - CFTypeRef decryptedData = SecTransformExecute(decryptor, &err); - STAssertNil((id)err, @"Expected no error, got: %@", err); - STAssertNotNil((id)decryptedData, @"Expected to get decrypted data"); - // What do we expect an empty enc/dec to look like? Mostly "not a crash" - CFDataRef empty_data = CFDataCreate(NULL, (UInt8*)"", 0); - STAssertEqualObjects((id)decryptedData, (id)empty_data, @"Expected decrypted data to match original message"); - CFRelease(decryptor); - sleep(5); - - return; -} - --(void)testzzzzZZZZ -{ - // Give xcode a little time to parse all the output before the unit tests exit - sleep(2); -} - --(void)test_multiOAEP -{ - SecKeychainRef tmp_keychain = NULL; - char *kcfname; - asprintf(&kcfname, "%s-OAEP-XXXXXXXXXX", "/tmp/"); - const char *passwd = "sekret"; - // NOTE: "mktemp" isn't as safe as you might think...but this is test code and doesn't have to be, but - // if you copy it elsewhere you may well need to rewrite it. (use mkstemp) - mktemp(kcfname); - OSStatus status = SecKeychainCreate(kcfname, (UInt32)strlen(passwd), passwd, NO, NULL, &tmp_keychain); - STAssertTrue(status == 0, @"Expected to make keychain, but got error 0x%x", status); - - const char *pem_key_bytes[] = { - // From the spec - "-----BEGIN PUBLIC KEY-----\nMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC7+C8JBoLOnCM4rCudqHH3No0H\n7tQQQ6RA1rbwdFT1H7jfuq8DXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jg\no9/HN3I+5rS32TolhO5qZJ0GCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNy\nmMoqj1lG+OX9CR29ywIBEQ==\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQC7+C8JBoLOnCM4rCudqHH3No0H7tQQQ6RA1rbwdFT1H7jfuq8D\nXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jgo9/HN3I+5rS32TolhO5qZJ0G\nCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNymMoqj1lG+OX9CR29ywIBEQKB\ngQCl2vxTQfryicS5iNswwc34PzElHgZotCeEgTgBV5ZBspQQs8eZjWvEZXReXDkm\nadaHDaLAgqk543/cuC7JPtrJf/OtWVCsz7wRHHbxqVKUROVqr2jFbAks043DvvXS\nCpOZJu1PdKE+3fvhoc7MSJSvlCjCt7iIP+RGOkvIWxyzwQJBAO7ProGxubPJCIEL\nEKG1YAGZ659ErvT9pJO4Gp49hPYyEk7wI25dHjt+KPrnqgQKLVslIXZFnR85dUG6\nKlj7ZZkCQQDJf7HwJ/RT9jQSM+qq0dk1P2xC0IhmsdBaDyA1AoudhphAtBZmtC6S\n6g2jtDIEtc/OM1JSTQQWpaRB5wCvRhUDAkBUSUymProDN+TiQCP81ppa6wfd3AGD\npNCsm1SwUfKxPtlJCXXqt3QU/1nB92kumi4gKzj8kQpHQXStyTwfZ8mBAkBHHgKQ\n/wrwdQNRt/h4hkypYa29Oop+mRxcBVapTDFGp/mAP49viuNC6TH9iuR6Ig0bmaSV\nhJgH/jn5JFqYNto9AkEAsGxP2rtjARmNJlvbrpQjs4Dycfc0U4hQkwd/zTniEZ/J\nhjIVT1iDsWepZ79AK06eLg+WVuaY6jZm7fsleYA59w==\n-----END RSA PRIVATE KEY-----\n", - // The next 10 are from oaep-vect.txt (via a lot of OpenSSL higgerdy-jiggerdey) - "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCos7KEr461CzhwNKhg8UbEkZ8x\nh2PNbFWYyK5IEaHgq8TH4LCC1pOl5/ztZ1z0ZoUSdywMvGSnQsbGMPUzyMxy9iro\nM8QL8lhC6YS7eL2/l8AQfVW9tmL1xOD6uYRctRSO9zkt06r/k64ea2Z7s9QkdhbU\n9boQ1M/SJt6I058W+wIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCos7KEr461CzhwNKhg8UbEkZ8xh2PNbFWYyK5IEaHgq8TH4LCC\n1pOl5/ztZ1z0ZoUSdywMvGSnQsbGMPUzyMxy9iroM8QL8lhC6YS7eL2/l8AQfVW9\ntmL1xOD6uYRctRSO9zkt06r/k64ea2Z7s9QkdhbU9boQ1M/SJt6I058W+wIDAQAB\nAoGAUzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6Dkqylp\nPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZ\nv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dECQQDTJzfnJn/+E0Gy\n1cDRUKgbWG+zEyvtL41SYoZKnLnzCvOL5EhZjUE6Fy77gCwhrPHBHFIMLyakcdyt\nIS6sfKOdAkEAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeR\nZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwJADhK/FxjpzvVZm6HDiC/oBGqQh07v\nzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQJBAJUp\new+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMT\nhrfjVMiZ9fESyoXXFYMCQE9FbFAkk73A7Sq3VqOm7U1nNSppfUIW6TISsSemPVQR\nzm+pjV2+/XMmPjcoFCdDgYFm7X3WNofdKoyh0vT72OE=\n-----END RSA PRIVATE KEY-----\n", - "RSA key ok\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQGUfH/OkEJfRyeecIUfJdXmIxb+\nih3xk3Hj5ijiYFQ+SQHvYIH2jAuBQRkNKujaun0SUOxttjbpROw3Iod8fB0KZ/FL\nFpTF8DeUUaQ+SaMt3oNnC3PakaHJm8I7Q2pgBVxhDwuvmcGgeVZblaPxUmYy0dTa\nYPIO2iXmU8TwAnZvRQIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQGUfH/OkEJfRyeecIUfJdXmIxb+ih3xk3Hj5ijiYFQ+SQHvYIH2\njAuBQRkNKujaun0SUOxttjbpROw3Iod8fB0KZ/FLFpTF8DeUUaQ+SaMt3oNnC3Pa\nkaHJm8I7Q2pgBVxhDwuvmcGgeVZblaPxUmYy0dTaYPIO2iXmU8TwAnZvRQIDAQAB\nAoGAaHJZomJX8Thzf5M4nNltSXcIKgRKRSY4w4ucRRBw0ICTslduV9bD5cWEjYTm\nCg0b3M3ur0ndFhFJGdedusRlzrJ3phMQcCvg8AygYOPN4gqYbIqz7xshfRxwQoGT\nGwFbOc4FQzlmlGna+VJDZ8sxykucXXKZh+wfN0vR7xXmj6UCQQFZ294Eoz7wb7YI\nuAsZD00+IrzBOsjkoIEDOr+kFu2wsziqCLVzCepaUkDn3G5UN4xpQUwx2X3bH0Bt\ns3acxBpDAkEBK2UvMEA7OLQJlf1v9BoazIracDcyNrcgLTmy7jDPtG2wlRH28wfM\nYcwhYGwYp1uKYvgi3wMboN8Nr9VQb1aL1wJAQ271CN5zZRnC2kxYDZjILLdFKj+1\n763Ducd4mhvGWE95Wt270yQ5x0aGVS7LbCwwek069/U57sFXJIx7MfGiVQJBASsV\nqJ89+ys5Bz5z8CvdDBp7N53UNfBc3eLv+eRilIt87GLukFDV4IFuB4WoVrSRCNy3\nXzaDh00cpjKaGQEwZv8CQAJw2xfVkUsBjXYRiyQ4mnNQ7INrAGOiFyEjb9jtttib\nUefuuHthG3Eyy36nNWwjFRwed1FQfHhtnuF5QXCoyOg=\n-----END RSA PRIVATE KEY-----\n", - "RSA key ok\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQK1j+wDmoYHAKTXtkYvk+bN1JEW\nHd109OgQtA48FlIAalwneyd0wRMFpMurWnjvpX4XqG33o/o2/EsdIknyLsfC3WpG\nMjKszqkG1m6+gLVwSxBynab4MyNKu1791KKSy/rTO00z+noUuMOXtW46zSEgNCi3\nfN+jOm2nBrPYsPxD6QIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQK1j+wDmoYHAKTXtkYvk+bN1JEWHd109OgQtA48FlIAalwneyd0\nwRMFpMurWnjvpX4XqG33o/o2/EsdIknyLsfC3WpGMjKszqkG1m6+gLVwSxBynab4\nMyNKu1791KKSy/rTO00z+noUuMOXtW46zSEgNCi3fN+jOm2nBrPYsPxD6QIDAQAB\nAoGAFbSKW1aDqUZw4jtXGPgU+g4T+FA49QcRGCy6YVEFgfPSLH4jLvk34i5VHWi4\nbi+MsarYvi5Ij13379J54/Vo1Orzb4DPcUGs5g/MkRP7bEqEH9ULvHxRL/y+/yFI\neqgR6zyoxiAFNGqG3oa/odipSP0/NIwi6q3zM8PObOEyCP0CQQG/AdIW1zWVzwJw\nwr63jUCg2ER9MdqRmpg/fup4G3fYX+Nxs+k3PntpIX0xUKAtiVjef62dVVFglYtE\nVBJ+Dn6vAkEBjTOZZYFm2zgpgW17KVQWdZ6ckZh/Wy2K7NY7BLSL17L88im7f4pt\nyIuhPdLjmtVbbRoGFgcI+XAL6AuP03RM5wJABsCiSdIKby7nXIi0lNU/aq6ZqkJ8\niMKLFjp2lEXl85DPQMJ0/W6mMppc58fOA6IVg5buKnhFeG4J4ohalyjk5QJBANHS\nfCn+3ZLYbDSO3QzL+sFPdG4FHOHRgR3zXWHy7hyX1L8oBIAvZCcYe6jpCor0QkO0\nB5sDRF5gLin6UZPmT+kCQQCMsvdWvYlBsdO3cOWtMe43Oyis2mn/m29A/leLnxr7\nhYNvlifTes/3PCd55jS7JgEcLI9/M2GuKp6mXtaJ42Oa\n-----END RSA PRIVATE KEY-----\n", - "RSA key ok\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQUSQLbMAAT6SNATRnHAeMfI3sOz\n4vJbwlZEZzOds4hT0GuF7qWy3jU7/0KsLka8l/rmrJYY2pU3pcj1U8HjV2JZkdYQ\njc14hfs6JUE/U+/K2UjLNc2bmunBxnYm0RPVfd5MW+p2u1u33pbADQc3LpaFptdc\n+dI5+hSNcJMbXz+wOQIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgQUSQLbMAAT6SNATRnHAeMfI3sOz4vJbwlZEZzOds4hT0GuF7qWy\n3jU7/0KsLka8l/rmrJYY2pU3pcj1U8HjV2JZkdYQjc14hfs6JUE/U+/K2UjLNc2b\nmunBxnYm0RPVfd5MW+p2u1u33pbADQc3LpaFptdc+dI5+hSNcJMbXz+wOQIDAQAB\nAoGBAQs6yuW+80dZiYsOKwgFVIpiYEI86so8fGlkHNnPRLaL5jYRY4Yn+yk4Z87t\nT54uYnTs/ZBsHd7wfycQcI6NRC5hgVY5sbQKDJDJIHgDPvxewvmE+mgbRFo7v4RH\nGGacGivrZVhXdDMpOm3KyxRfToWUJIq6IhT0AeURYrezGJABAkECdFjBnsFjaRnn\nNsmvJdYJpRuPVh0Zxr9pQ90e4auKSj8jIQC9QLiN7Ma6I1VItu95KhHJ3oI9Cnki\nxwlbbrpXAQJBAhDumzOrYXFuJ9JRvUZfSzWhojLi2gCQHClL8iNQzkkNCZ9kK1N1\nYS22O6HyA4ZJK/BNNLPCK865CdE0QbU7UTkCQDn6AouCbojBEht1CoskL6mjXFtm\nvf0fpjfTzEioSk9FehlOdyfkn3vMblpaQSZX/EcMcyLrw3QW70WMMHqMCQECQQFd\nmahBlZQ5efqeG+LDwbafQy9G/QPkfVvvu7/WsdE3HYPvszCj4CCUKy/tEV5dAr4k\n/ZLJAZ0c7NbdTPHlTMiZAkEB8LcBUXCz9eQiI7owMBxBpth8u3DjDLfTxn0lRz2x\n9svwPj+RJuPpeWgnmoZbLCtCZSTPxSpoPTHtMOuYS+QSug==\n-----END RSA PRIVATE KEY-----\n", - "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQqt8/nBJeXYkfMaxEjpk97+WA+A\nK0X51/IrpQIenEdXa1oeaAMbqdtObavk2Wodbz0mcmjP9AgAXxGO/K25mIjRwjRG\ncWayorhJoFqInAYKwNoMX66LVfMJumLnA3QvoDJvLRCwEQIUif9Jd3AZDYlf059S\nKTw579c6aYvaufEO2QIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgQqt8/nBJeXYkfMaxEjpk97+WA+AK0X51/IrpQIenEdXa1oeaAMb\nqdtObavk2Wodbz0mcmjP9AgAXxGO/K25mIjRwjRGcWayorhJoFqInAYKwNoMX66L\nVfMJumLnA3QvoDJvLRCwEQIUif9Jd3AZDYlf059SKTw579c6aYvaufEO2QIDAQAB\nAoGBAlbrTLpwZ/LSvlQNzf9FgqNrfTHRyQmbshS3mEhGaiaPgPWKSawEwONkiTSg\nIGwEU3wZsjZkOmCCcyFE33X6IXWI95RoK+iRaCdtxybFwMvbhNMbvybQpDr0lXF/\nfVKKz+40FWH2/zyuBcV4+EcNloL5wNBy+fYGi1bViA9oK+LFAkEDsNOWL20XVJy/\nyhEpQ0jc8Ofjn4wrxoJPIWS2BtaHhg2uHmMjk8/t9RMigikGni9g5KzX5jOkNgY/\ngjhfSJk3BwJBAuTDLi9Rcmm3ByMJ8AwOMTZffOKLI2uCkS3yOavzlXLPDtYEsCmC\n5TVkxS1qBTl95cBSov3cFB73GJg2NGrrMx8CQQHoSxGdJRYfpnsAJWpb2bZF0rIy\n7LBbAVGAApqIYircPwmzrqzeYWGrfN4iwq0m53l99U4HLL07JnOACz5DONvVAkEA\n65CqGkATW0zqBxl87ciBm+Hny/8lR2YhFvRlpKn0h6sS87pP7xOCImWmUpfZi3ve\n2TcuP/6Bo4s+lgD+0FV1TwJBAS9/gTj5QEBi64WkKSRSCzj1u4hqAZb0i7jc6mD9\nkswCfxjngVijSlxdX4YKD2wEBxp9ATEsBlBi8etIt50cg8s=\n-----END RSA PRIVATE KEY-----\n", - "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgRKxf22tLs0Z/0bcE/eGDwng4M+2\nd7OKUlkjBc6vAiwWbbkNBKwp4z990S2fr2bggWu2Pq0mfMfUbBfDe+IUvKKiLXI6\nZOREB0Nrb8llcprvwlVPN2zV3OpoKTeApivznQApSFoWC7ueXcCXLSGlBPUuXuAo\nqkFjMvUQsunP9fcirwIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgRKxf22tLs0Z/0bcE/eGDwng4M+2d7OKUlkjBc6vAiwWbbkNBKwp\n4z990S2fr2bggWu2Pq0mfMfUbBfDe+IUvKKiLXI6ZOREB0Nrb8llcprvwlVPN2zV\n3OpoKTeApivznQApSFoWC7ueXcCXLSGlBPUuXuAoqkFjMvUQsunP9fcirwIDAQAB\nAoGBApXso1YGGDaVWc7NMDqpz9r8HZ8GlZ33X/75KaqJaWG80ZDcaZftp/WWPnJN\nB7TcEfMGXlrpfZaDURIoC5CEuxTyoh69ToidQbnEEy7BlW/KuLsv7QV1iEk2Uixf\n99MyYZBIJOfK3uTguzctJFfPeOK9EoYij/g/EHMc5jyQz/P5AkEEps6Lc1jfppvc\n90JhcAWvtThfXzpYok73SiKowFy3zDjr1Mydmp14mmLND2Dwy5QdNCPJaS76T+Ot\n/ykMR0mjiwJBBATJqAM3H+20xb4588ALAJ5eCKY74eQANc2spQEcxwHPfuvLmfD/\n4Xz9Ckv3vv0t1TaslG23l/28Sr6PKTSbke0CQQOWHI92CqK9UVTHqv13Ils7rNAT\nmue1lI6jMR/M2G+5XHWvp2coS5st5VlXLxXY0ETH64Ohvl+t8sw3fA2EdSlLAkEC\nIZfgZnQhlqq8A/ov7rTnCxXLeH1hes0xu3XHvCNK1wb3xI0hgtHw/5wijc9Blnts\nC6bSwK0RChuFeDHsJF4ssQJBBAHEwMU9RdvbXp2W0P7PQnXfCXS8Sgc2tKdMMmkF\nPvtoas4kBuIsngWN20rlQGJ64v2wgmHo5+S8vJlNqvowXEU=\n-----END RSA PRIVATE KEY-----\n", - "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgTERefC8/JudPKMV0A7zDXvdOiz6\n6ZEb/ty5SLOkeC0HMrarRKpL8DdBpkTcAb7D5psBoDPmddis18SSXGsa7DEZBR39\niXYtIV1FR1/8tZ+QgUhiPzcXcVb2robdenxfQ9weH5CCVAWKKEpfBsACF5OofxrF\n/v99yu5pxeUaN4njcwIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgTERefC8/JudPKMV0A7zDXvdOiz66ZEb/ty5SLOkeC0HMrarRKpL\n8DdBpkTcAb7D5psBoDPmddis18SSXGsa7DEZBR39iXYtIV1FR1/8tZ+QgUhiPzcX\ncVb2robdenxfQ9weH5CCVAWKKEpfBsACF5OofxrF/v99yu5pxeUaN4njcwIDAQAB\nAoGBDzqRUfoVnGZsj2ERtdIReUPr7lHhc7vwmaiXu8lr0u3M+4ykPwZag4vIgs6V\nbBN42triUblREfJy9PtH26X7cC0twt93fImTyuAcrKSNXKQIizI0XrhyB/9ewQv8\nkuI8dQugKhVIO+A1Ii2HPT7q9BC1DS9aYZ/PUzUQ68WM7b2BAkEHSSYsERzUcOwl\nZuazcy/AkylGmqGQcdO5wBkGUUxvHSa6oUvqsJcci35hGk95AJ1v6ndpKMolKFsN\n42Q9Gj+McQJBBrweUOlsAr9jbp7qi4mbvr92Ud533UdMPpvCO62BgrYZBMfZffvr\n+x4AEIh4tuZ+QVOR1nlCwrK/m0Q1+IsMsCMCQQO8fqfwqrFDq8bOi5cRhjajAXLk\nz+Asj6Ddo7e6r5D4CSmCmFUl9Ii9/LS9cm4iY5rGSjCSq3/8vx1TNM+lC1vxAkEC\nYqaqKcKjxn3FNGwGOBr9mHqjzJPPv+z1T92fnXh9f1mlI9OYl52hN6L2OB/pSAH3\nyU2iFRjcNMtAhwxGl5lK2QJAZJ1MF7buFyHnctA4mlWcPTzflVDUV8RrA3t0ZBsd\nUhZq+KITyDliBs37pEIvGNb2Hby10hTJcb9IKuuXanNwwg==\n-----END RSA PRIVATE KEY-----\n", - "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgVvfDjDTId2lFH+IJAj6aRlUgN+P\ngNP26L9YGFBPNkJ8qbH1VAucZaj2l0z4RHokTZKAIBu0n8u+Y3jRlEzSJ+Iw+W49\nEPgZ3O8nbGSgCypLZwHn0B3l+r3jsemg34L0YxNZzSJmlkf7sXFyRhNO17SXz/+9\nxCtZxzqW7ZAWYhLf9wIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgVvfDjDTId2lFH+IJAj6aRlUgN+PgNP26L9YGFBPNkJ8qbH1VAuc\nZaj2l0z4RHokTZKAIBu0n8u+Y3jRlEzSJ+Iw+W49EPgZ3O8nbGSgCypLZwHn0B3l\n+r3jsemg34L0YxNZzSJmlkf7sXFyRhNO17SXz/+9xCtZxzqW7ZAWYhLf9wIDAQAB\nAoGBD30enlqqJf0T5KBmOuFE4NFfXNGLzbCd8sx+ZOPF6RWtYmRTBBYdCYxxW7er\ni9AdB+rz/tfH7QivKopi70SrFrMg4Ur3Kkj5av4mKgrkz2XmNekQeQzU7lzqdopL\nJjn35vZ3s/C7a+MrdXR9iQkDbwJk9Y1AHNuhMXFhV6dez2MxAkEKAu+ESNn62LvQ\n0ATIwqqXUe+XIcGw0DI2pUsN+UfLrtWiVe6ejiDUkeoXI/4JRwSpdi6Ir9Fuu1mU\nQSypZtxPnwJBCS02Ln7ToL/Z6f0ObAMBtt8pFZz1DMg7mwz01u6nGmHgArRuCuny\n3mLSW110UtSYuByaxvxYWT1MP7T11y37sKkCQQfHFBCvEDli2zZ0BON66FC6pOnC\nndkhRYFSlKZ8fRxt7SY6oDCptjOuUDA+FANdGvAUEj66aHggMI2OvIW2lX19AkEA\nrix1OAwCwBatBYkbMwHeiB8orhFxGCtrLIO+p8UV7KnKKYx7HKtYF6WXBo/IUGDe\nTaigFjeKrkPH+We8w3kEuQJBBZjRBZ462k9jIHUsCdgF/30fGuDQF67u6c76DX3X\n/3deRLV4Mi9kBdYhHaGVGWZqqH/cTNjIj2tuPWfpYdy7o9A=\n-----END RSA PRIVATE KEY-----\n", - "-----BEGIN PUBLIC KEY-----\nMIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDPLNQeNMo6co6ly4r/ZMNtJ73v\nU2TjNv1o0xI8WhlqjChwE+hT1RVtWNFRlUUg+09texertoF3ZZCcV2EZZZ2QKxkG\n7YorEMFVwk0SRSjaue6uN5vqxm5KQReG3Lj9AGLrwDDeEhmgTCqMG33TEx5Na2yu\n4uMaXtQawVCbLvHuKrGDZL5WjKlBwl7MhP+dZDtewaquECog1z9Hm3gP1tqRB1IS\n2erAOgZ02JnrouQx9MRLYVtroiMr1LM7rtc9Yl0CAwEAAQ==\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIIDfgIBAAKBwQDPLNQeNMo6co6ly4r/ZMNtJ73vU2TjNv1o0xI8WhlqjChwE+hT\n1RVtWNFRlUUg+09texertoF3ZZCcV2EZZZ2QKxkG7YorEMFVwk0SRSjaue6uN5vq\nxm5KQReG3Lj9AGLrwDDeEhmgTCqMG33TEx5Na2yu4uMaXtQawVCbLvHuKrGDZL5W\njKlBwl7MhP+dZDtewaquECog1z9Hm3gP1tqRB1IS2erAOgZ02JnrouQx9MRLYVtr\noiMr1LM7rtc9Yl0CAwEAAQKBwQCBIn4tPdZ3zAQiT9caDiLKHSWE0cRm5FXcSwRo\n3fhNs4NZKO99oaozeFMwuQxX3I3LvhgpDh9w3rve15BMlkw6GsME0Hd5FH6OCAim\nRLmMbKzbpwnmszz3x870Xwxnlx7xZblxuoKHiq4tjuoOK2FETNi979bB1jGO0xrA\nd8Oap2AMKBju4OmNpRdzjTKaMVyFavjn7HKHZ2Pp2Y45K/X+hIv0Kx8xx7kkaix7\nyxQLIVKMPjoanViwHTxWls9mUQECYQD8jWwEvsTrmoGSynkAy+U24ui1Gd7PM7JF\nl5jGkJ308XbbfSMZD8criGWnGK+JXxvNkUUpgCdCO2BecKR89YOQqMPoj8jEjosy\n49ohDfvj6IHqVnS2o0jCHpP55V6mXv0CYQDSANReeIqs6mBqQB0EYPh91cECfhLc\nGg11huiTnZz3ibQPUawEQpYd59Icwh4FyDFVwfKqkZM4fP35VstI0VO6JwQG+bu6\nU31Jh9ni+ZQtehTL//6nT+zdqSjSPiWfXuECYQDbFoAveaLw1F81jWn9M+RLgfro\nKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHM\njPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0CYQCgoxfP598UI/h6be6EUfTi\ntKZ+VJfym08eToMLn63ZQBFnAm9VluWjnJeBfg9fFuJ+GeyZAuAdfqb7mqPHYK/u\nHjgbad5qycB1haBq2cS6AL91yK0vqJikeegK4pT+0qECYAsh8zXDUzQutEw6okRF\neAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH\n2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==\n-----END RSA PRIVATE KEY-----\n", - "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArkXtVgHOxrjMBfgDk1xn\nTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn\n9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4j\nwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2\nAMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQ\ndle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muD\nuwIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcM\nUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65\ntRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv\n4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5\nUMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE\n5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwIDAQABAoIBAFyN+sxwzVaxEnoh\nDBUZQCwTmMgH1sJ/gg1O17O2pRgt2dAGLp6okbpzX9RYElzxEtXompxfM9chDw+R\niYVLgIe6C8kG7rHpUsSFt97VvhuW9OLKOiq3ApAeC0vzzwz41o7379DzXD4RWWcF\n8f9XbvnKPehvKCcL/D/x7KuRCHlfcePoXxNqn5d8sTvh6/sn+8FRT63/A5FYxhQX\nMt8loVGw8ezKX5U98U/gvoSWCK6lJ4YEcBgdlIewIj0ueWehA7cLMzzPpVxtqp1J\nFEw1ruWhwGiIIPHEgj8tnyAq17lDs6I/Drx0MGJ9eWQNpn0RVRDluALBIuf5RjU1\ntCRJU+ECgYEA7PWuzR5VFf/6y9daKBbG6/SQGM37RjjhhdZqc5a2+AkPgBjH/ZXM\nNLhX3BfwzGUWuxNGq01YLK2te0EDNSOHtwM40IQEfJ2VObZJYgSz3W6kQkmSB77A\nH5ZCh/9jNsOYRlgzaEb1bkaGGIHBAjPSF2vxWl6W3ceAvIaKp30852kCgYEAvEbE\nZPxqxMp4Ow6wijyEG3cvfpsvKLq9WIroheGgxh5IWKD7JawpmZDzW+hRZMJZuhF1\nzdcZJwcTUYSZK2wpt0bdDSyr4UKDX30UjMFhUktKCZRtSLgoRz8c52tstohsNFwD\n4F9B1RtcOpCj8kBzx9dKT+JdnPIcdZYPP8OGMYMCgYEAxzVkVx0A+xXQij3plXpQ\nkV1xJulELaz0K8guhi5Wc/9qAI7U0uN0YX34nxehYLQ7f9qctra3QhhgmBX31Fyi\nY8FZqjLSctEn+vS8jKLXc3jorrGbCtfaPLPeCucxSYD2K21LCoddHfA8G645zNgz\n72zX4tlSi/CE0flp55Tp9sECgYAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CU\ndBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM\n0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYK\nYqReSQKBgG84Ums5JQhVNO8+QVqDbt6LhhWKLHy/7MsL2DQwT+xoO6jU9HnEM9Q0\nFuYyaWI86hAHdtha/0AdP/9hDuZUEc47E2PWOpcJ7t5CZHzqVhST1UVwqHnBhoLN\nl3ELliBewxEX1ztfNiI/rdboupDdfA7mHUThYyUeIMf2brMFEXy4\n-----END RSA PRIVATE KEY-----\n", - NULL, - }; - struct key_pair { - SecKeyRef pubKey, privKey; - }; - key_pair keys[11]; - - int i; - for(i = 0; i < sizeof(keys)/sizeof(key_pair); i++) { - NSAssert(pem_key_bytes[i] != NULL, @"Expected a key"); - NSLog(@"Importing: %s", pem_key_bytes[i]); - CFDataRef pem_data = CFDataCreate(NULL, (UInt8*)(pem_key_bytes[i]), strlen(pem_key_bytes[i])); - SecKeyImportExportParameters import_params; - bzero(&import_params, sizeof(import_params)); - - import_params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION; - import_params.keyUsage = CSSM_KEYUSE_ANY; - import_params.keyAttributes = CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_SENSITIVE; - import_params.accessRef = NULL; - import_params.passphrase = CFSTR(""); - import_params.alertPrompt = CFSTR(""); - - CFArrayRef keypair = NULL; - SecExternalFormat key_format = kSecFormatOpenSSL; - SecExternalItemType itemType = kSecItemTypeUnknown; - status = SecKeychainItemImport(pem_data, CFSTR(".pem"), &key_format, &itemType, 0, &import_params, tmp_keychain, &keypair); - STAssertTrue(status == 0, @"Expected pubkey import to be ok, got err=0x%x", status); - NSAssert(keypair != NULL, @"Expected to get some keys back"); - STAssertNotNil((id)keypair, @"Expected to get some keys back"); - STAssertTrue(CFArrayGetCount(keypair) == 2, @"Expected 2 keys, got %@", keypair); - keys[i].pubKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 0); - keys[i].privKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 1); - } - STAssertNil((id)pem_key_bytes[i], @"Expected to convert all pem keys, but found at least: %s", pem_key_bytes[i]); - CFDataRef encoding_parameters = CFDataCreate(NULL, NULL, 0); - - struct KAT { - NSData *message, *seed, *encryptedMessage; - NSString *label; - key_pair keys; - }; - KAT tests[] = { - // This first one is from the spec - { - .message = [NSData dataWithHexString:@"d436e99569fd32a7c8a05bbc90d32c49"], - .seed = [NSData dataWithHexString:@"aafd12f659cae63489b479e5076ddec2f06cb58f"], - .encryptedMessage = [NSData dataWithHexString:@"1253e04dc0a5397bb44a7ab87e9bf2a039a33d1e996fc82a94ccd30074c95df763722017069e5268da5d1c0b4f872cf653c11df82314a67968dfeae28def04bb6d84b1c31d654a1970e5783bd6eb96a024c2ca2f4a90fe9f2ef5c9c140e5bb48da9536ad8700c84fc9130adea74e558d51a74ddf85d8b50de96838d6063e0955"], - .keys = keys[0], - .label = @"From spec", - }, - // The next 60 are from oaep-vect.txt - { - .message = [NSData dataWithHexString:@"6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"], - .seed = [NSData dataWithHexString:@"18b776ea21069d69776a33e96bad48e1dda0a5ef"], - .encryptedMessage = [NSData dataWithHexString:@"354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"], - .keys = keys[1], - .label = @"1-1", - }, - { - .message = [NSData dataWithHexString:@"750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"], - .seed = [NSData dataWithHexString:@"0cc742ce4a9b7f32f951bcb251efd925fe4fe35f"], - .encryptedMessage = [NSData dataWithHexString:@"640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44"], - .keys = keys[1], - .label = @"1-2", - }, - { - .message = [NSData dataWithHexString:@"d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051"], - .seed = [NSData dataWithHexString:@"2514df4695755a67b288eaf4905c36eec66fd2fd"], - .encryptedMessage = [NSData dataWithHexString:@"423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb"], - .keys = keys[1], - .label = @"1-3", - }, - { - .message = [NSData dataWithHexString:@"52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85"], - .seed = [NSData dataWithHexString:@"c4435a3e1a18a68b6820436290a37cefb85db3fb"], - .encryptedMessage = [NSData dataWithHexString:@"45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755"], - .keys = keys[1], - .label = @"1-4", - }, - { - .message = [NSData dataWithHexString:@"8da89fd9e5f974a29feffb462b49180f6cf9e802"], - .seed = [NSData dataWithHexString:@"b318c42df3be0f83fea823f5a7b47ed5e425a3b5"], - .encryptedMessage = [NSData dataWithHexString:@"36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439"], - .keys = keys[1], - .label = @"1-5", - }, - { - .message = [NSData dataWithHexString:@"26521050844271"], - .seed = [NSData dataWithHexString:@"e4ec0982c2336f3a677f6a356174eb0ce887abc2"], - .encryptedMessage = [NSData dataWithHexString:@"42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3df06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded243b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255"], - .keys = keys[1], - .label = @"1-6", - }, - - { - .message = [NSData dataWithHexString:@"8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7"], - .seed = [NSData dataWithHexString:@"8c407b5ec2899e5099c53e8ce793bf94e71b1782"], - .encryptedMessage = [NSData dataWithHexString:@"0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e"], - .keys = keys[2], - .label = @"2-1", - }, - { - .message = [NSData dataWithHexString:@"2d"], - .seed = [NSData dataWithHexString:@"b600cf3c2e506d7f16778c910d3a8b003eee61d5"], - .encryptedMessage = [NSData dataWithHexString:@"018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245"], - .keys = keys[2], - .label = @"2-2", - }, - { - .message = [NSData dataWithHexString:@"74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e"], - .seed = [NSData dataWithHexString:@"a73768aeeaa91f9d8c1ed6f9d2b63467f07ccae3"], - .encryptedMessage = [NSData dataWithHexString:@"018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053"], - .keys = keys[2], - .label = @"2-3", - }, - { - .message = [NSData dataWithHexString:@"a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a"], - .seed = [NSData dataWithHexString:@"9a7b3b0e708bd96f8190ecab4fb9b2b3805a8156"], - .encryptedMessage = [NSData dataWithHexString:@"00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641"], - .keys = keys[2], - .label = @"2-4", - }, - { - .message = [NSData dataWithHexString:@"2ef2b066f854c33f3bdcbb5994a435e73d6c6c"], - .seed = [NSData dataWithHexString:@"eb3cebbc4adc16bb48e88c8aec0e34af7f427fd3"], - .encryptedMessage = [NSData dataWithHexString:@"00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec"], - .keys = keys[2], - .label = @"2-5", - }, - { - .message = [NSData dataWithHexString:@"8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0"], - .seed = [NSData dataWithHexString:@"4c45cf4d57c98e3d6d2095adc51c489eb50dff84"], - .encryptedMessage = [NSData dataWithHexString:@"010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef3a"], - .keys = keys[2], - .label = @"2-6", - }, - - { - .message = [NSData dataWithHexString:@"087820b569e8fa8d"], - .seed = [NSData dataWithHexString:@"8ced6b196290805790e909074015e6a20b0c4894"], - .encryptedMessage = [NSData dataWithHexString:@"026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80"], - .keys = keys[3], - .label = @"3-1", - }, - { - .message = [NSData dataWithHexString:@"4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04"], - .seed = [NSData dataWithHexString:@"b4291d6567550848cc156967c809baab6ca507f0"], - .encryptedMessage = [NSData dataWithHexString:@"024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5"], - .keys = keys[3], - .label = @"3-2", - }, - { - .message = [NSData dataWithHexString:@"d94cd0e08fa404ed89"], - .seed = [NSData dataWithHexString:@"ce8928f6059558254008badd9794fadcd2fd1f65"], - .encryptedMessage = [NSData dataWithHexString:@"0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a"], - .keys = keys[3], - .label = @"3-3", - }, - { - .message = [NSData dataWithHexString:@"6cc641b6b61e6f963974dad23a9013284ef1"], - .seed = [NSData dataWithHexString:@"6e2979f52d6814a57d83b090054888f119a5b9a3"], - .encryptedMessage = [NSData dataWithHexString:@"02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0"], - .keys = keys[3], - .label = @"3-4", - }, - { - .message = [NSData dataWithHexString:@"df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223"], - .seed = [NSData dataWithHexString:@"2d760bfe38c59de34cdc8b8c78a38e66284a2d27"], - .encryptedMessage = [NSData dataWithHexString:@"0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60"], - .keys = keys[3], - .label = @"3-5", - }, - { - .message = [NSData dataWithHexString:@"3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1"], - .seed = [NSData dataWithHexString:@"f174779c5fd3cfe007badcb7a36c9b55bfcfbf0e"], - .encryptedMessage = [NSData dataWithHexString:@"00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e574744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac3785d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d005730"], - .label = @"3-6", - .keys = keys[3], - }, - - { - .message = [NSData dataWithHexString:@"4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2"], - .seed = [NSData dataWithHexString:@"1cac19ce993def55f98203f6852896c95ccca1f3"], - .encryptedMessage = [NSData dataWithHexString:@"04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8"], - .keys = keys[4], - .label = @"4-1", - }, - { - .message = [NSData dataWithHexString:@"b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8"], - .seed = [NSData dataWithHexString:@"f545d5897585e3db71aa0cb8da76c51d032ae963"], - .encryptedMessage = [NSData dataWithHexString:@"0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e"], - .keys = keys[4], - .label = @"4-2", - }, - { - .message = [NSData dataWithHexString:@"bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99"], - .seed = [NSData dataWithHexString:@"ad997feef730d6ea7be60d0dc52e72eacbfdd275"], - .encryptedMessage = [NSData dataWithHexString:@"0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065"], - .keys = keys[4], - .label = @"4-3", - }, - { - .message = [NSData dataWithHexString:@"fb2ef112f5e766eb94019297934794f7be2f6fc1c58e"], - .seed = [NSData dataWithHexString:@"136454df5730f73c807a7e40d8c1a312ac5b9dd3"], - .encryptedMessage = [NSData dataWithHexString:@"02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4"], - .keys = keys[4], - .label = @"4-4", - }, - { - .message = [NSData dataWithHexString:@"28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284"], - .seed = [NSData dataWithHexString:@"bca8057f824b2ea257f2861407eef63d33208681"], - .encryptedMessage = [NSData dataWithHexString:@"00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2"], - .keys = keys[4], - .label = @"4-5", - }, - { - .message = [NSData dataWithHexString:@"f22242751ec6b1"], - .seed = [NSData dataWithHexString:@"2e7e1e17f647b5ddd033e15472f90f6812f3ac4e"], - .encryptedMessage = [NSData dataWithHexString:@"00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e17cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc8250c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619a9"], - .keys = keys[4], - .label = @"4-6", - }, - - { - .message = [NSData dataWithHexString:@"af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8"], - .seed = [NSData dataWithHexString:@"44c92e283f77b9499c603d963660c87d2f939461"], - .encryptedMessage = [NSData dataWithHexString:@"036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5"], - .keys = keys[5], - .label = @"5-1", - }, - { - .message = [NSData dataWithHexString:@"a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399"], - .seed = [NSData dataWithHexString:@"cb28f5860659fceee49c3eeafce625a70803bd32"], - .encryptedMessage = [NSData dataWithHexString:@"03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad"], - .keys = keys[5], - .label = @"5-2", - }, - { - .message = [NSData dataWithHexString:@"308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7"], - .seed = [NSData dataWithHexString:@"2285f40d770482f9a9efa2c72cb3ac55716dc0ca"], - .encryptedMessage = [NSData dataWithHexString:@"0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967"], - .keys = keys[5], - .label = @"5-3", - }, - { - .message = [NSData dataWithHexString:@"15c5b9ee1185"], - .seed = [NSData dataWithHexString:@"49fa45d3a78dd10dfd577399d1eb00af7eed5513"], - .encryptedMessage = [NSData dataWithHexString:@"0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf"], - .keys = keys[5], - .label = @"5-4", - }, - { - .message = [NSData dataWithHexString:@"21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a"], - .seed = [NSData dataWithHexString:@"f0287413234cc5034724a094c4586b87aff133fc"], - .encryptedMessage = [NSData dataWithHexString:@"07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723"], - .keys = keys[5], - .label = @"5-5", - }, - { - .message = [NSData dataWithHexString:@"541e37b68b6c8872b84c02"], - .seed = [NSData dataWithHexString:@"d9fba45c96f21e6e26d29eb2cdcb6585be9cb341"], - .encryptedMessage = [NSData dataWithHexString:@"08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701ed9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f24a"], - .keys = keys[5], - .label = @"5-6", - }, - { - .label = @"6-1", - .keys = keys[6], - .message = [NSData dataWithHexString:@"4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4"], - .seed = [NSData dataWithHexString:@"dd0f6cfe415e88e5a469a51fbba6dfd40adb4384"], - .encryptedMessage = [NSData dataWithHexString:@"0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3"], - }, - { - .label = @"6-2", - .keys = keys[6], - .message = [NSData dataWithHexString:@"5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7"], - .seed = [NSData dataWithHexString:@"8d14bd946a1351148f5cae2ed9a0c653e85ebd85"], - .encryptedMessage = [NSData dataWithHexString:@"0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f"], - }, - { - .label = @"6-3", - .keys = keys[6], - .message = [NSData dataWithHexString:@"b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c"], - .seed = [NSData dataWithHexString:@"6c075bc45520f165c0bf5ea4c5df191bc9ef0e44"], - .encryptedMessage = [NSData dataWithHexString:@"0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65"], - }, - { - .label = @"6-4", - .keys = keys[6], - .message = [NSData dataWithHexString:@"684e3038c5c041f7"], - .seed = [NSData dataWithHexString:@"3bbc3bd6637dfe12846901029bf5b0c07103439c"], - .encryptedMessage = [NSData dataWithHexString:@"008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8"], - }, - { - .label = @"6-5", - .keys = keys[6], - .message = [NSData dataWithHexString:@"32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693"], - .seed = [NSData dataWithHexString:@"b46b41893e8bef326f6759383a83071dae7fcabc"], - .encryptedMessage = [NSData dataWithHexString:@"00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab"], - }, - { - .label = @"6-6", - .keys = keys[6], - .message = [NSData dataWithHexString:@"50ba14be8462720279c306ba"], - .seed = [NSData dataWithHexString:@"0a2403312a41e3d52f060fbc13a67de5cf7609a7"], - .encryptedMessage = [NSData dataWithHexString:@"0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c92c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d79634cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab5470"], - }, - { - .label = @"7-1", - .keys = keys[7], - .message = [NSData dataWithHexString:@"47aae909"], - .seed = [NSData dataWithHexString:@"43dd09a07ff4cac71caa4632ee5e1c1daee4cd8f"], - .encryptedMessage = [NSData dataWithHexString:@"1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1"], - }, - { - .label = @"7-2", - .keys = keys[7], - .message = [NSData dataWithHexString:@"1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7"], - .seed = [NSData dataWithHexString:@"3a9c3cec7b84f9bd3adecbc673ec99d54b22bc9b"], - .encryptedMessage = [NSData dataWithHexString:@"1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6"], - }, - { - .label = @"7-3", - .keys = keys[7], - .message = [NSData dataWithHexString:@"d976fc"], - .seed = [NSData dataWithHexString:@"76a75e5b6157a556cf8884bb2e45c293dd545cf5"], - .encryptedMessage = [NSData dataWithHexString:@"2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b"], - }, - { - .label = @"7-4", - .keys = keys[7], - .message = [NSData dataWithHexString:@"d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb"], - .seed = [NSData dataWithHexString:@"7866314a6ad6f2b250a35941db28f5864b585859"], - .encryptedMessage = [NSData dataWithHexString:@"0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac"], - }, - { - .label = @"7-5", - .keys = keys[7], - .message = [NSData dataWithHexString:@"bb47231ca5ea1d3ad46c99345d9a8a61"], - .seed = [NSData dataWithHexString:@"b2166ed472d58db10cab2c6b000cccf10a7dc509"], - .encryptedMessage = [NSData dataWithHexString:@"028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478"], - }, - { - .label = @"7-6", - .keys = keys[7], - .message = [NSData dataWithHexString:@"2184827095d35c3f86f600e8e59754013296"], - .seed = [NSData dataWithHexString:@"52673bde2ca166c2aa46131ac1dc808d67d7d3b1"], - .encryptedMessage = [NSData dataWithHexString:@"14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd47d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e346eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2acf7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae674115"], - }, - { - .label = @"8-1", - .keys = keys[8], - .message = [NSData dataWithHexString:@"050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967"], - .seed = [NSData dataWithHexString:@"7706ffca1ecfb1ebee2a55e5c6e24cd2797a4125"], - .encryptedMessage = [NSData dataWithHexString:@"09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d12919790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61"], - }, - { - .label = @"8-2", - .keys = keys[8], - .message = [NSData dataWithHexString:@"4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc"], - .seed = [NSData dataWithHexString:@"a3717da143b4dcffbc742665a8fa950585548343"], - .encryptedMessage = [NSData dataWithHexString:@"2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d"], - }, - { - .label = @"8-3", - .keys = keys[8], - .message = [NSData dataWithHexString:@"8604ac56328c1ab5ad917861"], - .seed = [NSData dataWithHexString:@"ee06209073cca026bb264e5185bf8c68b7739f86"], - .encryptedMessage = [NSData dataWithHexString:@"4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f"], - }, - { - .label = @"8-4", - .keys = keys[8], - .message = [NSData dataWithHexString:@"fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc"], - .seed = [NSData dataWithHexString:@"990ad573dc48a973235b6d82543618f2e955105d"], - .encryptedMessage = [NSData dataWithHexString:@"2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0"], - }, - { - .label = @"8-5", - .keys = keys[8], - .message = [NSData dataWithHexString:@"4a5f4914bee25de3c69341de07"], - .seed = [NSData dataWithHexString:@"ecc63b28f0756f22f52ac8e6ec1251a6ec304718"], - .encryptedMessage = [NSData dataWithHexString:@"1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2"], - }, - { - .label = @"8-6", - .keys = keys[8], - .message = [NSData dataWithHexString:@"8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be"], - .seed = [NSData dataWithHexString:@"3925c71b362d40a0a6de42145579ba1e7dd459fc"], - .encryptedMessage = [NSData dataWithHexString:@"3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5bf1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f075aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c98b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c210"], - }, - { - .label = @"9-1", - .keys = keys[9], - .message = [NSData dataWithHexString:@"f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6"], - .seed = [NSData dataWithHexString:@"8ec965f134a3ec9931e92a1ca0dc8169d5ea705c"], - .encryptedMessage = [NSData dataWithHexString:@"267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72"], - }, - { - .label = @"9-2", - .keys = keys[9], - .message = [NSData dataWithHexString:@"81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659"], - .seed = [NSData dataWithHexString:@"ecb1b8b25fa50cdab08e56042867f4af5826d16c"], - .encryptedMessage = [NSData dataWithHexString:@"93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8"], - }, - { - .label = @"9-3", - .keys = keys[9], - .message = [NSData dataWithHexString:@"fd326429df9b890e09b54b18b8f34f1e24"], - .seed = [NSData dataWithHexString:@"e89bb032c6ce622cbdb53bc9466014ea77f777c0"], - .encryptedMessage = [NSData dataWithHexString:@"81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3"], - }, - { - .label = @"9-4", - .keys = keys[9], - .message = [NSData dataWithHexString:@"f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e"], - .seed = [NSData dataWithHexString:@"606f3b99c0b9ccd771eaa29ea0e4c884f3189ccc"], - .encryptedMessage = [NSData dataWithHexString:@"bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858"], - }, - { - .label = @"9-5", - .keys = keys[9], - .message = [NSData dataWithHexString:@"53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d"], - .seed = [NSData dataWithHexString:@"fcbc421402e9ecabc6082afa40ba5f26522c840e"], - .encryptedMessage = [NSData dataWithHexString:@"232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e"], - }, - { - .label = @"9-6", - .keys = keys[9], - .message = [NSData dataWithHexString:@"b6b28ea2198d0c1008bc64"], - .seed = [NSData dataWithHexString:@"23aade0e1e08bb9b9a78d2302a52f9c21b2e1ba2"], - .encryptedMessage = [NSData dataWithHexString:@"438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e94732450434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de5589e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f"], - }, - { - .label = @"10-1", - .keys = keys[10], - .message = [NSData dataWithHexString:@"8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee"], - .seed = [NSData dataWithHexString:@"47e1ab7119fee56c95ee5eaad86f40d0aa63bd33"], - .encryptedMessage = [NSData dataWithHexString:@"53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e61396144e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfcc7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a8774a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc"], - }, - { - .label = @"10-2", - .keys = keys[10], - .message = [NSData dataWithHexString:@"e6ad181f053b58a904f2457510373e57"], - .seed = [NSData dataWithHexString:@"6d17f5b4c1ffac351d195bf7b09d09f09a4079cf"], - .encryptedMessage = [NSData dataWithHexString:@"a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f5874400110828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b5776eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0bb19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e71964607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9fccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795"], - }, - { - .label = @"10-3", - .keys = keys[10], - .message = [NSData dataWithHexString:@"510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124"], - .seed = [NSData dataWithHexString:@"385387514deccc7c740dd8cdf9daee49a1cbfd54"], - .encryptedMessage = [NSData dataWithHexString:@"9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6edc56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4afc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede"], - }, - { - .label = @"10-4", - .keys = keys[10], - .message = [NSData dataWithHexString:@"bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649a94045c9"], - .seed = [NSData dataWithHexString:@"5caca6a0f764161a9684f85d92b6e0ef37ca8b65"], - .encryptedMessage = [NSData dataWithHexString:@"6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97bad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af499408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa7122e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d15bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc855828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6de1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8"], - }, - { - .label = @"10-5", - .keys = keys[10], - .message = [NSData dataWithHexString:@"a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9"], - .seed = [NSData dataWithHexString:@"95bca9e3859894b3dd869fa7ecd5bbc6401bf3e4"], - .encryptedMessage = [NSData dataWithHexString:@"75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d11b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab131573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d51f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5fa6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e722eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0"], - }, - { - .label = @"10-6", - .keys = keys[10], - .message = [NSData dataWithHexString:@"eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed00b7c39ec6922d7b8ea2c04ebac"], - .seed = [NSData dataWithHexString:@"9f47ddf42e97eea856a9bdbc714eb3ac22f6eb32"], - .encryptedMessage = [NSData dataWithHexString:@"2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492fd6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b973f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afdd2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bfd90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46"], - }, - - }; - - int max_cycles = 100; - if (!getenv("SUBMISSION_TEST")) { - max_cycles = 10; - CFfprintf(stderr, "Running the far faster but far less reliable fast test.\nSet the SUBMISSION_TEST environment variable for full testing\n"); - } - - for (int j = 0; j < max_cycles; j++) { - NSLog(@"Cycle %d", j); - for (i = 0; i < sizeof(tests)/sizeof(KAT); i++) { - NSLog(@"test#%d %@ L(IN)=%lu, L(OUT)=%lu", i, tests[i].label, (unsigned long)[tests[i].message length], (unsigned long)[tests[i].encryptedMessage length]); - CFErrorRef err = NULL; - - SecTransformRef encryptor = SecEncryptTransformCreate(tests[i].keys.pubKey, &err); - - SecTransformSetAttribute(encryptor, kSecTransformInputAttributeName, tests[i].message, &err); - SecTransformSetAttribute(encryptor, kSecPaddingKey, kSecPaddingOAEPKey, &err); - SecTransformSetAttribute(encryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, &err); - SecTransformSetAttribute(encryptor, CFSTR("FixedSeedForOAEPTesting"), tests[i].seed, &err); - - CFTypeRef encryptedData = SecTransformExecute(encryptor, &err); - STAssertNotNil((id)encryptedData, @"Expected to get encrypted data"); - STAssertNil((NSError*)err, @"Expected no error, got err=%@", err); - // Can't support "seed" with commoncrypto, just check round trip. - //STAssertEqualObjects((id)encryptedData, (id)tests[i].encryptedMessage, @"encrypted data should have matched test vector (%@) data", tests[i].label); - CFRelease(encryptor); - - SecTransformRef decryptor = SecDecryptTransformCreate(tests[i].keys.privKey, NULL); - SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, tests[i].encryptedMessage, NULL); - // XXX: totally round trip, not even partial KAT (KAT can't really be done on OAEP - // without supporitng settign the seed externally) - SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, encryptedData, NULL); - SecTransformSetAttribute(decryptor, kSecPaddingKey, kSecPaddingOAEPKey, NULL); - SecTransformSetAttribute(decryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, NULL); - CFTypeRef decryptedData = SecTransformExecute(decryptor, &err); - STAssertNil((id)err, @"Expected no error, got: %@", err); - STAssertNotNil((id)decryptedData, @"Expected to get decrypted data"); - STAssertEqualObjects((id)decryptedData, tests[i].message, @"Expected decrypted data to match original message (%@)", tests[i].label); - CFRelease(decryptor); - } - } - - return; -} - --(void)testNoSignKeyMakesError -{ - NSData *data = [NSData dataWithBytes:"" length:1]; - - struct test_case { - NSString *name; - CFErrorRef createError; - SecTransformRef transform; - } test_cases[] = { - { - .name = @"Sign", - .createError = NULL, - .transform = SecSignTransformCreate(NULL, &(test_cases[0].createError)) - }, - { - .name = @"Verify", - .createError = NULL, - .transform = SecVerifyTransformCreate(NULL, (CFDataRef)data, &(test_cases[1].createError)) - } - }; - - for(int i = 0; i < sizeof(test_cases) / sizeof(test_case); i++) { - struct test_case *test = test_cases + i; - STAssertNil((id)test->createError, @"Testing %@, unexpected error: %@", test->name, test->createError); - STAssertNotNil((id)test->transform, @"Didn't manage to create transform for %@", test->name); - if (!test->transform) { - continue; - } - - __block CFErrorRef err = NULL; - SecTransformSetAttribute(test->transform, kSecTransformInputAttributeName, data, &err); - STAssertNil((id)err, @"Error setting input for %@: %@", test->name, err); - - dispatch_group_t execute_done = dispatch_group_create(); - dispatch_group_enter(execute_done); - - SecTransformExecuteAsync(test->transform, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) { - if (error) { - err = error; - } - if (isFinal) { - dispatch_group_leave(execute_done); - } - }); - - STAssertFalse(dispatch_group_wait(execute_done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5)), @"Timeout waiting for %@ transform", test->name); - STAssertErrorHas((id)err, @"missing required attributes?:.*KEY", @"Unexpected error during %@ test, expected one about missing keys: %@", test->name, err); - dispatch_group_notify(execute_done, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^(void) { - dispatch_release(execute_done); - }); - } -} - --(void)testHMAC -{ - // make the data for the key and the data to be HMAC'd - CFDataRef hmacData = CFDataCreate(NULL, (u_int8_t*) gHMACText, strlen(gHMACText)); - CFDataRef hmacKey = CFDataCreate(NULL, (u_int8_t*) gHMACKey, strlen(gHMACKey)); - SecTransformRef hmacRef; - CFErrorRef error = NULL; - CFDataRef result; - CFDataRef rightAnswer; - CFComparisonResult ok; - - // create the object - hmacRef = SecDigestTransformCreate(kSecDigestHMACSHA1, 20, &error); - STAssertNil((id) error, @"Unexpected error returned."); - - // set the key - SecTransformSetAttribute(hmacRef, kSecDigestHMACKeyAttribute, hmacKey, &error); - STAssertNil((id) error, @"Unexpected error returned."); - - // digest the data - SecTransformSetAttribute(hmacRef, kSecTransformInputAttributeName, hmacData, &error); - STAssertNil((id) error, @"Unexpected error returned."); - - result = (CFDataRef) SecTransformExecute(hmacRef, &error); - if (error) - { - CFShow(error); - STAssertNil((id) error, @"Unexpected error returned."); - CFRelease(error); - } - - STAssertNotNil((id) result, @"No data returned for SHA1"); - - // check to make sure we got the right answer - rightAnswer = CFDataCreate(NULL, gSHA1HMAC, sizeof(gSHA1HMAC)); - ok = CFEqual(rightAnswer, result); - CFRelease(rightAnswer); - CFRelease(hmacRef); - CFRelease(result); - - if (error) - { - CFRelease(error); - } - - STAssertTrue(ok, @"Digest returned incorrect HMACSHA1 result."); - - //+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+ - - // create the object - hmacRef = SecDigestTransformCreate(kSecDigestHMACSHA2, 256, &error); - STAssertNil((id) error, @"Unexpected error returned."); - - // set the key - SecTransformSetAttribute(hmacRef, kSecDigestHMACKeyAttribute, hmacKey, &error); - STAssertNil((id) error, @"Unexpected error returned."); - - // digest the data - SecTransformSetAttribute(hmacRef, kSecTransformInputAttributeName, hmacData, &error); - STAssertNil((id) error, @"Unexpected error returned."); - - result = (CFDataRef) SecTransformExecute(hmacRef, &error); - if (error != nil) - { - CFShow(error); - STAssertNil((id) error, @"Unexpected error returned."); - CFRelease(error); - } - - STAssertNotNil((id) result, @"No data returned for SHA256"); - - rightAnswer = CFDataCreate(NULL, gSHA256HMAC, sizeof(gSHA256HMAC)); - ok = CFEqual(result, rightAnswer); - - CFRelease(rightAnswer); - CFRelease(hmacRef); - - CFRelease(hmacData); - CFRelease(hmacKey); - CFRelease(result); - - STAssertTrue(ok, @"Digest returned incorrect HMACSHA256 result."); -} - - - --(void)echoParams:(NSString*)p1 p2:(NSString*)p2 -{ -} - --(void)testReadStreamTransform -{ - // point to our test data - CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/usr/share/dict/words"), kCFURLPOSIXPathStyle, false); - FSRef force_resolve; - STAssertTrue(CFURLGetFSRef(url, &force_resolve), @"Expected to create FSRef from %@", url); - CFURLRef resolved_url = CFURLCreateFromFSRef(NULL, &force_resolve); - CFNumberRef size_on_disk = NULL; - CFURLCopyResourcePropertyForKey(resolved_url, kCFURLFileSizeKey, &size_on_disk, NULL); - STAssertNotNil((id)size_on_disk, @"Expected to fetch size"); - - CFReadStreamRef readStreamRef = CFReadStreamCreateWithFile(NULL, url); - SecTransformRef transform = SecTransformCreateReadTransformWithReadStream(readStreamRef); - STAssertNotNil((id) transform, @"Returned transform should not be nil."); - - dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0); - dispatch_queue_t queue = dispatch_queue_create("ReadStream queue", NULL); - __block ssize_t bytes_presented = 0; - - SecTransformExecuteAsync(transform, queue, - ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) - { - if (message) - { - bytes_presented += CFDataGetLength((CFDataRef)message); - } - if (isFinal) - { - STAssertNil((id)error, @"Unexpected error!"); - dispatch_semaphore_signal(waitSemaphore); - } - }); - - dispatch_semaphore_wait(waitSemaphore, DISPATCH_TIME_FOREVER); - NSNumber *size_via_stream = [NSNumber numberWithLongLong:bytes_presented]; - STAssertEqualObjects(size_via_stream, (NSNumber*)size_on_disk, @"Expected sizes to match"); - CFRelease(size_on_disk); - - dispatch_release(queue); - dispatch_release(waitSemaphore); - CFRelease(transform); - CFRelease(readStreamRef); - CFRelease(url); - CFRelease(resolved_url); -} - --(void)testMGF -{ - UInt8 raw_seed[] = {0xaa, 0xfd, 0x12, 0xf6, 0x59, 0xca, 0xe6, 0x34, 0x89, 0xb4, 0x79, 0xe5, 0x07, 0x6d, 0xde, 0xc2, 0xf0, 0x6c, 0xb5, 0x8f}; - UInt8 raw_mgf107[] = {0x06, 0xe1, 0xde, 0xb2, 0x36, 0x9a, 0xa5, 0xa5, 0xc7, 0x07, 0xd8, 0x2c, 0x8e, 0x4e, 0x93, 0x24, 0x8a, 0xc7, 0x83, 0xde, 0xe0, 0xb2, 0xc0, 0x46, 0x26, 0xf5, 0xaf, 0xf9, 0x3e, 0xdc, 0xfb, 0x25, 0xc9, 0xc2, 0xb3, 0xff, 0x8a, 0xe1, 0x0e, 0x83, 0x9a, 0x2d, 0xdb, 0x4c, 0xdc, 0xfe, 0x4f, 0xf4, 0x77, 0x28, 0xb4, 0xa1, 0xb7, 0xc1, 0x36, 0x2b, 0xaa, 0xd2, 0x9a, 0xb4, 0x8d, 0x28, 0x69, 0xd5, 0x02, 0x41, 0x21, 0x43, 0x58, 0x11, 0x59, 0x1b, 0xe3, 0x92, 0xf9, 0x82, 0xfb, 0x3e, 0x87, 0xd0, 0x95, 0xae, 0xb4, 0x04, 0x48, 0xdb, 0x97, 0x2f, 0x3a, 0xc1, 0x4e, 0xaf, 0xf4, 0x9c, 0x8c, 0x3b, 0x7c, 0xfc, 0x95, 0x1a, 0x51, 0xec, 0xd1, 0xdd, 0xe6, 0x12, 0x64}; - CFDataRef seed = CFDataCreate(NULL, raw_seed, sizeof(raw_seed)); - CFDataRef mgf107 = CFDataCreate(NULL, raw_mgf107, sizeof(raw_mgf107)); - CFErrorRef err = NULL; - - SecTransformRef mgfTransform = SecCreateMaskGenerationFunctionTransform(NULL, 107, &err); - STAssertNotNil((id)mgfTransform, @"Expected to create a MGF transform e=%@", err); - err = NULL; - SecTransformSetAttribute(mgfTransform, kSecTransformInputAttributeName, seed, &err); - STAssertNil((id)err, @"Expected no error setting MGF's input, got %@", err); - err = NULL; - CFDataRef mgfOutput = (CFDataRef)SecTransformExecute(mgfTransform, &err); - STAssertNotNil((id)mgfOutput, @"Expected output from mgf, got error %@", err); - STAssertEqualObjects((id)mgfOutput, (id)mgf107, @"Expected matching output"); - - CFRelease(mgfTransform); - // XXX: leak test?? - - UInt8 raw_maskedDB[] = {0xdc, 0xd8, 0x7d, 0x5c, 0x68, 0xf1, 0xee, 0xa8, 0xf5, 0x52, 0x67, 0xc3, 0x1b, 0x2e, 0x8b, 0xb4, 0x25, 0x1f, 0x84, 0xd7, 0xe0, 0xb2, 0xc0, 0x46, 0x26, 0xf5, 0xaf, 0xf9, 0x3e, 0xdc, 0xfb, 0x25, 0xc9, 0xc2, 0xb3, 0xff, 0x8a, 0xe1, 0x0e, 0x83, 0x9a, 0x2d, 0xdb, 0x4c, 0xdc, 0xfe, 0x4f, 0xf4, 0x77, 0x28, 0xb4, 0xa1, 0xb7, 0xc1, 0x36, 0x2b, 0xaa, 0xd2, 0x9a, 0xb4, 0x8d, 0x28, 0x69, 0xd5, 0x02, 0x41, 0x21, 0x43, 0x58, 0x11, 0x59, 0x1b, 0xe3, 0x92, 0xf9, 0x82, 0xfb, 0x3e, 0x87, 0xd0, 0x95, 0xae, 0xb4, 0x04, 0x48, 0xdb, 0x97, 0x2f, 0x3a, 0xc1, 0x4f, 0x7b, 0xc2, 0x75, 0x19, 0x52, 0x81, 0xce, 0x32, 0xd2, 0xf1, 0xb7, 0x6d, 0x4d, 0x35, 0x3e, 0x2d}; - - UInt8 raw_mgf20[] = {0x41, 0x87, 0x0b, 0x5a, 0xb0, 0x29, 0xe6, 0x57, 0xd9, 0x57, 0x50, 0xb5, 0x4c, 0x28, 0x3c, 0x08, 0x72, 0x5d, 0xbe, 0xa9}; - CFDataRef maskedDB = CFDataCreate(NULL, raw_maskedDB, sizeof(raw_maskedDB)); - CFDataRef mgf20 = CFDataCreate(NULL, raw_mgf20, sizeof(raw_mgf20)); - err = NULL; - - mgfTransform = SecCreateMaskGenerationFunctionTransform(kSecDigestSHA1, 20, &err); - STAssertNotNil((id)mgfTransform, @"Expected to create a MGF transform e=%@", err); - err = NULL; - SecTransformSetAttribute(mgfTransform, kSecTransformInputAttributeName, maskedDB, &err); - STAssertNil((id)err, @"Expected no error setting MGF's input, got %@", err); - err = NULL; - mgfOutput = (CFDataRef)SecTransformExecute(mgfTransform, &err); - STAssertNotNil((id)mgfOutput, @"Expected output from mgf, got error %@", err); - STAssertEqualObjects((id)mgfOutput, (id)mgf20, @"Expected matching output"); -} - --(void)testAbortParams -{ - // make a simple transform - SecTransformRef a = SecNullTransformCreate(); - - // try to abort the transform - CFErrorRef errorRef = NULL; - STAssertFalse(SecTransformSetAttribute(a, CFSTR("ABORT"), NULL, &errorRef), @"SecTransformSetAttribute should have returned FALSE"); - STAssertNotNil((id) errorRef, @"SecTransformSetAttribute should have had an error."); - if (errorRef != NULL) - { - CFRelease(errorRef); - } - - CFRelease(a); - - // We have instant end of stream, it is wired directly to null_abort's ABORT. It is wired to the final drain via a delay and some other - // things. If the end of stream makes it to the final drain we get an empty CFData. If the abort triggers then abort has invalidly - // triggered off of a NULL value. - SecGroupTransformRef test_null_abort_via_connection = SecTransformCreateGroupTransform(); - SecTransformRef pass_through = SecNullTransformCreate(); - SecTransformRef null_abort = SecNullTransformCreate(); - - CFURLRef dev_null_url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/dev/null"), kCFURLPOSIXPathStyle, NO); - CFReadStreamRef dev_null_stream = CFReadStreamCreateWithFile(NULL, dev_null_url); - CFReadStreamOpen(dev_null_stream); - CFRelease(dev_null_url); - - SecTransformSetAttribute(pass_through, kSecTransformInputAttributeName, dev_null_stream, NULL); - SecTransformConnectTransforms(pass_through, kSecTransformOutputAttributeName, null_abort, kSecTransformAbortAttributeName, test_null_abort_via_connection, NULL); - - SecTransformRef delay_null = delay_transform(NSEC_PER_SEC / 10); - SecTransformConnectTransforms(pass_through, kSecTransformOutputAttributeName, delay_null, kSecTransformInputAttributeName, test_null_abort_via_connection, NULL); - SecTransformConnectTransforms(delay_null, kSecTransformOutputAttributeName, null_abort, kSecTransformInputAttributeName, test_null_abort_via_connection, NULL); - - - CFErrorRef err = NULL; - CFTypeRef not_null = SecTransformExecute(test_null_abort_via_connection, &err); - - STAssertNotNil((id)not_null, @"aborted via a NULL from a connection? err=%@", err); - - if (err) - { - CFRelease(err); - } - - CFRelease(test_null_abort_via_connection); - CFRelease(pass_through); - CFRelease(null_abort); - CFRelease(delay_null); - - CFReadStreamClose(dev_null_stream); - CFRelease(dev_null_stream); -} - - --(void)testDisconnect -{ - SecTransformRef a = SecNullTransformCreate(); - SecTransformRef b = SecNullTransformCreate(); - SecTransformRef c = SecNullTransformCreate(); - SecGroupTransformRef g = SecTransformCreateGroupTransform(); - - SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, g, NULL); - SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, c, kSecTransformInputAttributeName, g, NULL); - - SecTransformDisconnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName); - STAssertTrue(SecGroupTransformHasMember(g, a), @"A should still be in the group, but isn't"); - - SecTransformDisconnectTransforms(a, kSecTransformOutputAttributeName, c, kSecTransformInputAttributeName); - STAssertFalse(SecGroupTransformHasMember(g, a), @"A should no longer be in the group, but is"); - - CFRelease(g); - CFRelease(c); - CFRelease(b); - CFRelease(a); -} - - --(void)testAbort -{ - CFStringRef abort_test_name = CFSTR("com.apple.security.unit-test.abortTest"); - - SecTransformCreateBlock setupBlock = - ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) - { - params->send(kSecTransformInputAttributeName, kSecTransformMetaAttributeDeferred, kCFBooleanTrue); - - params->overrideAttribute(kSecTransformActionAttributeNotification, CFSTR("PB"), ^(SecTransformAttributeRef ah, CFTypeRef value) { - // Makes sure we can shut down (via ABORT) a transform that has a pending pushback - params->pushback(ah, value); - return (CFTypeRef)NULL; - }); - }; - - - SecTransformRef a; - SecTransformRef dt; - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - - // make two of these transforms and link them together - a = custom_transform(abort_test_name, setupBlock); - STAssertNotNil((id) a, @"SecCustomTransformCreate failed"); - - dt = delay_transform(NSEC_PER_SEC / 10); - STAssertNotNil((id) dt, @"SecCustomTransformCreate failed"); - - // connect the two transforms - CFErrorRef error; - - // hook the output up so that the abort automatically fires. - SecTransformConnectTransforms(dt, kSecTransformOutputAttributeName, a, CFSTR("ABORT"), group, &error); - STAssertNil((id) error, @"SecTransformConnectTransforms failed."); - - // also hook it up to the input because the input attribute is required on a null transform - SecTransformConnectTransforms(dt, CFSTR("NOVALUES"), a, kSecTransformInputAttributeName, group, &error); - STAssertNil((id) error, @"SecTransformConnectTransforms failed."); - - // pass a plain piece of data down the transform just for fun... - const u_int8_t data[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4}; - - CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL, data, sizeof(data), kCFAllocatorNull); - SecTransformSetAttribute(dt, kSecTransformInputAttributeName, dataRef, NULL); - - CFStringRef str = CFStringCreateMutable(NULL, 0); - SecTransformSetAttribute(a, CFSTR("PB"), str, NULL); - - CFTypeRef er = SecTransformExecute(a, &error); - - STAssertNil((id)er, @"Didn't expect an result from aborted transform"); - STAssertNotNil((id)error, @"Expected error from execute"); - - if (error) - { - CFShow(error); - - // while we are at it, make sure that the user dictionary has the originating transform - CFDictionaryRef userDictionary = CFErrorCopyUserInfo(error); - STAssertNotNil((id) CFDictionaryGetValue(userDictionary, kSecTransformAbortOriginatorKey), @"Originating transform not listed."); - CFRelease(error); - } - - CFRelease(a); - CFRelease(dt); - CFRelease(group); - CFRelease(dataRef); - -/* - // XXX: these should both be 1, not 3 or 4. WTF? Is this an abort issue, or a generic leak? - // STAssertEquals(rc0, CFGetRetainCount(str), @"The value we sent to PB hasn't been released (value retained by pushback)"); - // STAssertEquals(rc0, CFGetRetainCount(dataRef), @"The value we sent to INPUT hasn't been released"); -*/ -} - --(void)testPreAbort { - CFErrorRef error = NULL; - SecTransformRef prebort = SecNullTransformCreate(); - SecTransformSetAttribute(prebort, kSecTransformInputAttributeName, CFSTR("quux"), NULL); - SecTransformSetAttribute(prebort, CFSTR("ABORT"), CFSTR("OOPS"), NULL); - CFTypeRef er = SecTransformExecute(prebort, &error); - STAssertNil((id)er, @"Didn't expect an result from pre-aborted transform"); - STAssertNotNil((id)error, @"Expected error from execute of pre-aborted transform"); - CFRelease(error); -} - -#ifdef DEBUG --(void)testFireAndForget -{ - bool isGC = false; - NSGarbageCollector* gc = [NSGarbageCollector defaultCollector]; - if (gc) - { - isGC = [gc isEnabled]; - } - - CFIndex retCount = 0; - - // make transforms - SecNullTransformRef a = SecNullTransformCreate(); - SecNullTransformRef b = SecNullTransformCreate(); - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, group, NULL); - - if (!isGC) - { - retCount = CFGetRetainCount(group); - } - - // set up a blob of data to fire - const u_int8_t data[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4}; - CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL, data, sizeof(data), kCFAllocatorNull); - SecTransformSetAttribute(a, kSecTransformInputAttributeName, dataRef, NULL); - CFRelease(dataRef); - - // make dispatch related stuff - dispatch_queue_t queue = dispatch_queue_create("ffqueue", NULL); - // semaphore0's job is to be signaled when we know ExecuteAsync is actually executing (so we don't sample the retain - // count too soone), semaphore signals when we are about done with ExecuteAsync (I'm not sure why we need to know), - // and semaphore2 is signaled to let the execute block know we are done sampling retain counts. - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - dispatch_semaphore_t semaphore2 = dispatch_semaphore_create(0); - - // launch the chain - SecTransformExecuteAsync(group, queue, - ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) - { - CFfprintf(stderr, "message %p, final %d\n", message, isFinal ? 1 : 0); - STAssertEquals(queue, const_cast(dispatch_get_current_queue()), @"Expected to be executing on own queue, got %s", dispatch_queue_get_label(dispatch_get_current_queue())); - if (isFinal) - { - fprintf(stderr, "Final message received.\n"); - dispatch_semaphore_wait(semaphore2, DISPATCH_TIME_FOREVER); // make sure that the other chain has released its material - dispatch_semaphore_signal(semaphore); - } - }); - CFRelease(a); - CFRelease(b); - CFRelease(group); - dispatch_semaphore_signal(semaphore2); - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - - // no crash? Life is good. -} -#endif - --(void)testExternalSource -{ - CFErrorRef err = NULL; - SecTransformRef xs = SecExternalSourceTransformCreate(&err); - SecTransformRef tee = SecNullTransformCreate(); - SecTransformRef group = SecTransformCreateGroupTransform(); - - SecTransformConnectTransforms(xs, kSecTransformOutputAttributeName, tee, kSecTransformInputAttributeName, group, &err); - - dispatch_queue_t q = dispatch_queue_create("com.apple.security.unit-tests.test-external-source", 0); - dispatch_group_t dg = dispatch_group_create(); - dispatch_group_enter(dg); - __block bool got_ping = false; - - SecTransformExecuteAsync(group, q, ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) { - CFfprintf(stderr, "B: message %@, e %p, f %d\n", message ? message : (CFTypeRef)CFSTR("(NULL)"), error, isFinal); - - if (message) { - if (CFEqual(message, CFSTR("PING"))) { - got_ping = true; - } else { - STFail(@"expected ping, got: %@", message); - } - } - - if (error) { - STFail(@"unexpected error: %@", error); - } - - if (isFinal) { - if (!got_ping) { - STFail(@"never got ping"); - } - dispatch_group_leave(dg); - } - }); - - SecExternalSourceSetValue(tee, CFSTR("PONG"), &err); - STAssertNotNil((id)err, @"Expected error setting tee"); - STAssertErrorHas((id)err, @"ExternalSource", @"Error should note what should be passed in: %@", err); - CFRelease(err); - err = NULL; - SecExternalSourceSetValue(xs, CFSTR("PING"), &err); - STAssertNil((id)err, @"unexpected error setting xs: %@", err); - SecExternalSourceSetValue(xs, NULL, &err); - STAssertNil((id)err, @"unexpected error setting xs: %@", err); - dispatch_group_wait(dg, DISPATCH_TIME_FOREVER); - - dispatch_release(dg); - dispatch_release(q); - CFRelease(xs); - CFRelease(tee); - CFRelease(group); -} - --(void)testFindLastAndMonitor -{ - SecNullTransformRef a = delay_transform(NSEC_PER_SEC / 10); - SecNullTransformRef b = SecNullTransformCreate(); - - SecGroupTransformRef groupRef = SecTransformCreateGroupTransform(); - CFErrorRef error = NULL; - SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, groupRef, &error); - STAssertNil((id)error, @"An error was returned when none was expected."); - SecTransformSetAttribute(a, kSecTransformInputAttributeName, kCFNull, &error); - STAssertNil((id)error, @"An error was returned when none was expected."); - - - // get the last transform in the chain (unexecuted). It had better be b... - SecTransformRef tr = SecGroupTransformFindLastTransform(groupRef); - STAssertNotNil((id)tr, @"FindLastTransform returned NULL"); - STAssertTrue(tr == b, @"FindLastTransform returned incorrect result"); - STAssertFalse(tr == a, @"FindLastTransform returned the head of the chain"); - - // execute the transform. This should attach an output monitor - dispatch_queue_t queue = dispatch_queue_create("test delivery queue", NULL); - dispatch_semaphore_t last_block_run = dispatch_semaphore_create(0L); - dispatch_semaphore_t last_assert_run = dispatch_semaphore_create(0L); - SecTransformExecuteAsync(groupRef, queue, - ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) - { - if (isFinal) - { - dispatch_semaphore_signal(last_block_run); - dispatch_semaphore_wait(last_assert_run, DISPATCH_TIME_FOREVER); - dispatch_release(last_assert_run); - } - - }); - - dispatch_semaphore_wait(last_block_run, DISPATCH_TIME_FOREVER); - - // see if the returned transform is the same now - tr = SecGroupTransformFindLastTransform(groupRef); - STAssertNotNil((id) tr, @"FindLastTransform returned NULL"); - STAssertTrue(tr == b, @"FindLastTransform returned incorrect result"); - STAssertFalse(tr == a, @"FindLastTransform returned the head of the chain"); - - // get the monitor, it had better not be a or b - tr = SecGroupTransformFindMonitor(groupRef); - STAssertNotNil((id) tr, @"FindMonitor returned NULL"); - STAssertFalse(tr == a, @"FindLastTransform returned the head of the chain"); - STAssertFalse(tr == b, @"FindLastTransform returned the head of the chain"); - - dispatch_semaphore_signal(last_assert_run); - dispatch_release(queue); - dispatch_release(last_block_run); - CFRelease(a); - CFRelease(b); - CFRelease(groupRef); -} - - --(void)testConnectUnsetAttributes /* Can't connect transform attributes with no setting */ -{ - SecNullTransformRef a = SecNullTransformCreate(); - SecNullTransformRef b = SecNullTransformCreate(); - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - CFErrorRef error = NULL; - SecTransformConnectTransforms(a, CFSTR("RANDOM_NAME"), b, CFSTR("RANDOM_DESTINATION"), group, &error); - CFRelease(group); - CFRelease(b); - CFRelease(a); - STAssertNil((id) error, @"An error was returned when none was expected."); -} - --(void)testNoDataFlowPriorToInit /* Monitor must be attached before the data flow becomes active */ -{ - CFStringRef name = CFSTR("com.apple.security.unit-test.flow-check"); - SecTransformCreateBlock cb = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) { - __block bool inited = false; - __block bool saw_x_start = false; - __block bool saw_null = false; - __block int post_send_left = 8; - SecTransformAttributeRef out_ah = params->get(kSecTransformOutputAttributeName, kSecTransformMetaAttributeRef); - params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("create")); - - params->overrideTransform(kSecTransformActionStartingExecution, ^{ - params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("x-start")); - inited = true; - return (CFTypeRef)NULL; - }); - - params->overrideTransform(kSecTransformActionCanExecute, ^{ - params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("can-x")); - return (CFTypeRef)NULL; - }); - - params->overrideAttribute(kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, ^(SecTransformAttributeRef ah, CFTypeRef value) { - if (inited) { - if (value) { - if (!saw_x_start) { - saw_x_start = CFStringHasPrefix((CFStringRef)value, CFSTR("x-start")); - } - if (saw_null) { - params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 88, "saw %@ after NULL", value)); - } - if (post_send_left--) { - params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("post-init")); - } - } else { - saw_null = true; - // The FIRST flow transform should not see x-start (it is the OUTPUT of the flow transform - // before you in the chain), but all the other transforms should see it. - if (params->get(CFSTR("FIRST"), kSecTransformMetaAttributeValue)) { - if (saw_x_start) { - params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 42, "saw bogus x-start on FIRST flow transform")); - } else { - params->send(out_ah, kSecTransformMetaAttributeValue, value); - } - } else { - if (saw_x_start) { - params->send(out_ah, kSecTransformMetaAttributeValue, value); - } else { - params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 42, "never saw x-start before EOS")); - return (CFTypeRef)kCFNull; - } - } - } - } else { - // attempting to put the value in the error string sometimes blows up, so I've left it out. - params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 42, "got: value before init")); - return (CFTypeRef)kCFNull; - } - return (CFTypeRef)value; - }); - }; - - // Reliably reproduces with 100000 transforms in our group, but - // not at 1000...doesn't even seem to do it at 50000. - // Likely a timing issue triggered by heavy swapping. - int n_transforms = 100000; - - if (!getenv("SUBMISSION_TEST")) { - n_transforms = 10000; - CFfprintf(stderr, "Running the far faster but far less reliable fast test.\nSet the SUBMISSION_TEST environment variable for full testing\n"); - } - - int i; - CFMutableArrayRef ta = CFArrayCreateMutable(NULL, n_transforms, &kCFTypeArrayCallBacks); - CFErrorRef err = NULL; - - for(i = 0; i < n_transforms; ++i) { - SecTransformRef tr = custom_transform(name, cb); - STAssertNil((id)err, @"Failure %@ creating %@ transform", err, name); - CFStringRef l = CFStringCreateWithFormat(NULL, NULL, CFSTR("flow-%d"), i); - SecTransformSetAttribute(tr, kSecTransformTransformName, l, &err); - if (0 == i % 1000) { - CFfprintf(stderr, "Created %@ of %d\n", l, n_transforms); - } - CFRelease(l); - STAssertNil((id)err, @"Can't set name %@", err); - CFArrayAppendValue(ta, tr); - assert(CFArrayGetCount(ta)); - assert(CFArrayGetCount(ta) == i+1); - } - - SecTransformRef prev_tr = NULL; - SecTransformRef group = SecTransformCreateGroupTransform(); - CFIndex cnt; - - while ((cnt = CFArrayGetCount(ta))) { - CFIndex r = arc4random() % cnt; - SecTransformRef tr = CFArrayGetValueAtIndex(ta, r); - if (prev_tr) { - SecTransformConnectTransforms(tr, kSecTransformOutputAttributeName, prev_tr, kSecTransformInputAttributeName, group, &err); - STAssertNil((id)err, @"Can't connect %@ to %@", tr, prev_tr); - STAssertNotNil((id)group, @"nil group after connect"); - CFRelease(prev_tr); - } - prev_tr = tr; - CFArrayRemoveValueAtIndex(ta, r); - - if (0 == cnt % 1000) { - CFfprintf(stderr, "%d left to hook up\n", cnt); - } - } - - CFTypeRef ptl = SecTransformGetAttribute(prev_tr, kSecTransformTransformName); - CFfprintf(stderr, "Setting INPUT for %@\n", ptl); - SecTransformSetAttribute(prev_tr, kSecTransformInputAttributeName, CFSTR("First!"), &err); - STAssertNil((id)err, @"Can't set first's input? %@", err); - SecTransformSetAttribute(prev_tr, CFSTR("FIRST"), kCFBooleanTrue, &err); - STAssertNil((id)err, @"Can't set FIRST? %@", err); - CFTypeRef r = SecTransformExecute(group, &err); - STAssertNil((id)err, @"execution error: %@", err); - STAssertNotNil((id)r, @"result expected from execute"); - CFRelease(group); - CFRelease(prev_tr); -} - --(void)testNoDataDescription /* CFShow(SecCustomTransformNoData()) crashes */ -{ - CFStringRef result = CFCopyDescription(SecTransformNoData()); // this is called under the hood in CFShow, and it doesn't dump output - STAssertNotNil((id)result, @"SecTransformNoData can be formatted"); - CFRelease(result); -} - -static SecTransformInstanceBlock KnownProblemPlumbing(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - // At the moment fully disconnecting a transform from a group leaves it in the group, so it can't have any - // kSecTransformMetaAttributeRequiresOutboundConnection=TRUE attributes (by default OUTPUT requires an outbound connection) - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, - kSecTransformMetaAttributeRequiresOutboundConnection, kCFBooleanFalse); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - return (CFTypeRef)CFErrorCreate(NULL, kCFErrorDomainPOSIX, EOPNOTSUPP, NULL); - }); - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)knownProblemPlumbing // note, this test has been disconnected! -{ - SecNullTransformRef a = SecNullTransformCreate(); - CFStringRef name = CFSTR("com.apple.security.unit-test.error+outputless"); - CFErrorRef err = NULL; - - SecTransformRegister(name, &KnownProblemPlumbing, &err); - - SecTransformRef b = SecTransformCreate(name, NULL); - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - - SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, group, NULL); - SecTransformDisconnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName); - - - CFStringRef data = CFSTR("Test"); - - SecTransformSetAttribute(a, kSecTransformInputAttributeName, data, NULL); - CFTypeRef result = SecTransformExecute(a, &err); - - STAssertEqualObjects((id)data, (id)result, @"Plumbing disconnect failed."); - STAssertNil((id)err, @"Unexpected error=%@", err); - CFRelease(a); - CFRelease(b); - CFRelease(group); -} - --(void)testUnknownEncodeType { - CFErrorRef err1 = NULL; - CFStringRef invalid_encode_type = CFSTR("no such encoding type ☃✪"); - SecTransformRef not_created = SecEncodeTransformCreate(invalid_encode_type, &err1); - STAssertNil((id)not_created, @"Created encode transform with bad type"); - STAssertErrorHas((NSError*)err1, @"☃✪", @"Error mentions bad encoding type: %@", err1); - fprintf(stderr, "Err1 = %p\n", err1); - if (err1) CFRelease(err1); - err1 = NULL; - - CFErrorRef err2 = NULL; - SecTransformRef no_type_at_create = SecEncodeTransformCreate(NULL, &err2); - fprintf(stderr, "Err2 = %p\n", err2); - STAssertNotNil((id)no_type_at_create, @"should be able to create encoder with unset type, but got error %@", err2); - - if (no_type_at_create) { - CFErrorRef err3 = NULL; - SecTransformSetAttribute(no_type_at_create, kSecTransformInputAttributeName, NULL, &err3); - STAssertNil((id)err3, @"Can't set INPUT: %@", err3); - if (err3) { - CFRelease(err3); - err3 = NULL; - } - STAssertTrue(SecTransformSetAttribute(no_type_at_create, kSecEncodeTypeAttribute, kSecBase32Encoding, &err3), @"Can't set encode to valid type error: %@", err3); - STAssertFalse(SecTransformSetAttribute(no_type_at_create, kSecEncodeTypeAttribute, invalid_encode_type, &err3), @"Set encode to invalid type, no error signaled", err3); - fprintf(stderr, "Err3 = %p\n", err3); - if (err3) CFRelease(err3); - - CFErrorRef err4 = NULL; - CFTypeRef no_result = SecTransformExecute(no_type_at_create, &err4); - STAssertNil((id)no_result, @"Got result when none expected %@"); - STAssertNotNil((id)err4, @"No error when one expected"); - fprintf(stderr, "Err4 = %p\n", err4); - if (err4) CFRelease(err4); - } else { - STFail(@"Unable to run some tests"); - } - - CFRelease(no_type_at_create); - CFRelease(invalid_encode_type); -} - --(void)testNoUnderscores -{ - SecTransformRef zt = SecEncodeTransformCreate(kSecZLibEncoding, NULL); - CFErrorRef err = NULL; - SecTransformSetAttribute(zt, CFSTR("_FAIL"), kCFBooleanTrue, &err); - STAssertNotNil((id)err, @"Expeced an error setting _FAIL"); - STAssertErrorHas((id)err, @"_FAIL", @"Expected error to contain _FAIL"); - STAssertErrorHas((id)err, @"Encoder", @"Expecting error to name offending transform", err); - CFTypeRef v = SecTransformGetAttribute(zt, CFSTR("_FAIL")); - STAssertNil((id)v, @"Expected nil result, got v=%p", v); - CFRelease(err); - CFRelease(zt); -} - --(void)testCanFetchDigestSizes -{ - NSDictionary *digests = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:128/8], kSecDigestMD2, - [NSNumber numberWithInt:128/8], kSecDigestMD4, - [NSNumber numberWithInt:128/8], kSecDigestMD5, - [NSNumber numberWithInt:160/8], kSecDigestSHA1, - [NSNumber numberWithInt:512/8], kSecDigestSHA2, - nil]; - NSData *zero = [NSData dataWithBytes:"" length:1]; - - for (NSString *digestType in digests) { - CFErrorRef err = NULL; - SecTransformRef digest = SecDigestTransformCreate(digestType, 0, &err); - STAssertNotNil((id)digest, @"Expected to make digest (err=%@)", err); - STAssertNil((id)err, @"Unexpected error: %@", err); - NSNumber *actualLength = (NSNumber*)SecTransformGetAttribute(digest, kSecDigestLengthAttribute); - STAssertTrue([actualLength intValue] != 0, @"Got zero length back"); - STAssertNotNil(actualLength, @"Expected to get a length"); - STAssertEqualObjects(actualLength, [digests objectForKey:digestType], @"Expected lengths to match for %@", digestType); - - SecTransformSetAttribute(digest, kSecTransformInputAttributeName, zero, &err); - STAssertNil((id)err, @"Unexpected error: %@", err); - - NSData *output = (NSData *)SecTransformExecute(digest, &err); - STAssertNil((id)err, @"Unexpected error: %@", err); - STAssertNotNil((id)output, @"No output"); - - STAssertEquals([actualLength intValue], (int)[output length], @"Actual output not expected length"); - - [output release]; - CFRelease(digest); - } -} - --(void)testBadTransformTypeNames -{ - CFErrorRef error = NULL; - Boolean ok = SecTransformRegister(CFSTR("Not valid: has a col..co...double dot thing"), DelayTransformBlock, &error); - STAssertFalse(ok, @"Register of name with : fails"); - STAssertErrorHas((id)error, @":", @"Error mentions invalid character (error=%@)", error); - - ok = SecTransformRegister(CFSTR("Not/valid has a slash"), DelayTransformBlock, &error); - STAssertFalse(ok, @"Register of name with / fails"); - STAssertErrorHas((id)error, @"/", @"Error mentions invalid character (error=%@)", error); - - ok = SecTransformRegister(CFSTR("https://NOT/VALID"), DelayTransformBlock, &error); - STAssertFalse(ok, @"Register of name with : and / fails"); - STAssertErrorHas((id)error, @"[:/]", @"Error mentions invalid character (error=%@)", error); - - ok = SecTransformRegister(CFSTR("_not valid at start"), DelayTransformBlock, &error); - STAssertFalse(ok, @"Register of _name fails"); - STAssertErrorHas((id)error, @"_", @"Error mentions invalid character (error=%@)", error); - - ok = SecTransformRegister(CFSTR("it is ok to have a _ after start"), DelayTransformBlock, &error); - STAssertTrue(ok, @"Register of _ IN should have worked (error=%@)", error); -} - --(void)testExecuteBlock { - unsigned char *raw_data = (unsigned char *)"Just some bytes, you know"; - //NSData *empty = [NSData dataWithBytes:NULL length:0]; - NSData *data = [NSData dataWithBytes:raw_data length:strlen((const char *)raw_data)]; - //NSUInteger ecnt = [empty retainCount]; - - SecTransformRef zt = SecEncodeTransformCreate(kSecZLibEncoding, NULL); - SecTransformSetAttribute(zt, kSecTransformInputAttributeName, data, NULL); - dispatch_queue_t q = dispatch_queue_create("com.apple.security.testingQ", NULL); - dispatch_queue_t q_sync = dispatch_queue_create("com.apple.security.testingQ_sync", NULL); - dispatch_suspend((dispatch_object_t)q_sync); - __block BOOL ran_block = NO; - - SecTransformExecuteAsync(zt, q, ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) { -// if ([empty length]) { -// NSLog(@"Empty data not so empty"); -// } - STAssertTrue(dispatch_get_current_queue() == q, @"block dispatched to proper queue"); - - if (!ran_block) { - usleep(200); - ran_block = YES; - } - - if (message == NULL) { - dispatch_resume((dispatch_object_t)q_sync); - } - }); - - //STAssertTrue(ecnt < [empty retainCount], @"SecTransformExecute retained block"); - dispatch_sync(q_sync, ^{ }); - STAssertTrue(ran_block, @"Block executed"); - - dispatch_release(q_sync); - dispatch_release(q); - CFRelease(zt); - - // test for 7735698 - // STAssertTrue(ecnt == [empty retainCount], @"SecTransformExecute released block"); -} - -static SecTransformInstanceBlock ConnectionCheck(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - __block SecTransformMetaAttributeType dir = kSecTransformMetaAttributeValue; - - SecTransformAttributeRef out_ah = - SecTranformCustomGetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeRef); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("DIRECTION"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (CFEqual(value, CFSTR("<"))) - { - dir = kSecTransformMetaAttributeHasInboundConnection; - } - else if (CFEqual(value, CFSTR(">"))) - { - dir = kSecTransformMetaAttributeHasOutboundConnections; - } - else - { - return (CFTypeRef)CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "Unsupported direction %@, expected < or >", value); - } - return value; - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (dir != kSecTransformMetaAttributeValue) - { - if (value) - { - SecTransformCustomSetAttribute(ref, out_ah, kSecTransformMetaAttributeValue, - SecTranformCustomGetAttribute(ref, value, dir)); - } - else - { - SecTransformCustomSetAttribute(ref, out_ah, kSecTransformMetaAttributeValue, NULL); - } - } - else - { - SecTransformPushbackAttribute(ref, ah, value); - } - - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testConnectionChecks { - - CFStringRef name = CFSTR("com.apple.security.unit-test.connection-checks"); - CFErrorRef error = NULL; - SecTransformRegister(name, &*ConnectionCheck, &error); - - struct test_case { - NSString *attr, *dir; - CFBooleanRef expect; - } cases[] = { - {@"INPUT", @"<", kCFBooleanTrue}, - {@"OUTPUT", @">", kCFBooleanTrue}, - {@"INPUT", @">", kCFBooleanFalse}, - {@"OUTPUT", @"<", kCFBooleanFalse}, - {@"DIRECTION", @"<", kCFBooleanFalse}, - {@"DIRECTION", @">", kCFBooleanFalse}, - }; - - CFIndex i, n = sizeof(cases)/sizeof(test_case); - for(i = 0; i < n; ++i) - { - test_case *t = cases + i; - - SecTransformRef cct = SecTransformCreate(name, NULL); - SecTransformRef tee0 = SecNullTransformCreate(); - SecTransformRef tee1 = SecNullTransformCreate(); - SecTransformRef group = SecTransformCreateGroupTransform(); - - SecTransformSetAttribute(cct, CFSTR("DEBUG"), kCFBooleanTrue, NULL); - SecTransformSetAttribute(tee0, CFSTR("DEBUG"), kCFBooleanTrue, NULL); - SecTransformSetAttribute(tee1, CFSTR("DEBUG"), kCFBooleanTrue, NULL); - - SecTransformSetAttribute(tee0, CFSTR("NAME"), CFSTR("tee0"), NULL); - SecTransformSetAttribute(tee1, CFSTR("NAME"), CFSTR("tee1"), NULL); - - SecTransformConnectTransforms(cct, CFSTR("OUTPUT"), tee1, CFSTR("INPUT"), group, NULL); - SecTransformConnectTransforms(tee0, CFSTR("OUTPUT"), cct, CFSTR("INPUT"), group, NULL); - - SecTransformSetAttribute(cct, CFSTR("DIRECTION"), t->dir, NULL); - SecTransformSetAttribute(tee0, CFSTR("INPUT"), t->attr, NULL); - CFErrorRef err = NULL; - CFTypeRef r = SecTransformExecute(group, &err); - STAssertNil((id)err, @"Error=%@ for case#%d", err, i); - STAssertNotNil((id)r, @"Nil result for case#%d", i); - STAssertEqualObjects((id)(t->expect), (id)r, @"Expected result for case#%d %@%@", i, t->dir, t->attr); - - CFRelease(cct); - CFRelease(tee0); - CFRelease(tee1); - CFRelease(group); - } - -} - -static SecTransformInstanceBlock PushBackTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - __block CFStringRef input_d = NULL; - __block CFStringRef data_d = NULL; - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("DATA"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (!input_d) - { - SecTransformPushbackAttribute(ref, ah, value); - } - else - { - if (data_d) - { - CFRelease(data_d); - } - data_d = (CFStringRef)CFRetain(value); - } - return value; - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (value) - { - if (input_d) - { - CFRelease(input_d); - } - input_d = (CFStringRef)CFRetain(value); - if (!data_d) - { - SecTransformPushbackAttribute(ref, ah, value); - return value; - } - } - else - { - if (data_d) - { - SecTransformPushbackAttribute(ref, ah, NULL); - value = data_d; - data_d = NULL; - } - } - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, value); - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testPushback { - - CFStringRef name = CFSTR("com.apple.security.unit-test.basic-pushback"); - CFStringRef one = CFSTR("1"); - CFStringRef two = CFSTR("2"); - CFStringRef expect = CFSTR("12"); - - // This unit test makes pushback look very complex, but that is because we are abusing it for test purposes. - // normally it is a simple "if I need X before I can go on, and X isn't here yet pushback". Here we attempt - // to carefully sequence 2 attributes to be the inverse of the normal order AND test pushback of NULL as well - // as normal values. - - CFErrorRef error = NULL; - SecTransformRegister(name, &PushBackTest, &error); - - SecTransformRef pt = SecTransformCreate(name, NULL); - - SecTransformSetAttribute(pt, CFSTR("DATA"), two, NULL); - SecTransformSetAttribute(pt, CFSTR("INPUT"), one, NULL); - - CFTypeRef result = SecTransformExecute(pt, NULL); - - STAssertEqualObjects((id)result, (id)expect, @"Testing pushback"); - - CFRelease(pt); - - // NOTE: we want to test doing a double pushback, but that sets the Abort attribute which currently causes an abort not an orderly shutdown - -} - -static SecTransformInstanceBlock CustomExternalization(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - // Create a non-attribute 'instance' variable which will contain - // the version number of this class - - __block float versionNumber = 1.0; - - // Register the custom externalize override - SecTransformActionBlock ExternalizeExtraDataOverride = - ^{ - CFStringRef key = CFSTR("VersionNumber"); - CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &versionNumber); - - CFDictionaryRef result = CFDictionaryCreate(kCFAllocatorDefault, - (const void **)&key, (const void **)&value, - 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - CFRelease(value); - - - return (CFTypeRef)result; - - }; - SecTransformSetTransformAction(ref, kSecTransformActionExternalizeExtraData, ExternalizeExtraDataOverride); - - // Register the custom internalize override - SecTransformDataBlock InternalizeExtraDataOverride = - ^(CFTypeRef d) - { - CFTypeRef internalizeResult = NULL; - //id testObj = (id)d; - - //STAssertNotNil(testObj, @"Internalize did NOT get a dictionary!"); - - if (CFDictionaryGetTypeID() == CFGetTypeID(d)) - { - CFStringRef key = CFSTR("VersionNumber"); - CFDictionaryRef dict = (CFDictionaryRef)d; - CFNumberRef varsNum = (CFNumberRef)CFDictionaryGetValue(dict, key); - // STAssertNotNil((NSNumber *)varsNum, - // @"Unable to retrieve the dictionary when the internalized data override"); - if (NULL != varsNum) - { - Boolean numResult = CFNumberGetValue(varsNum, kCFNumberFloatType, &versionNumber); - // STAssertTrue(numResult, @"Could not get the version number from the CFNumberRef"); - if (numResult) - { - //float knownVersion = 1.0; - // STAssertTrue(knownVersion == versionNumber, @"Versions do not Match!"); - } - } - } - return internalizeResult; - }; - SecTransformSetDataAction(ref, kSecTransformActionInternalizeExtraData, - InternalizeExtraDataOverride); - - return result; - }; - - return Block_copy(instanceBlock); -} - -/* -------------------------------------------------------------------------- - method: testCustomExternalization - description: Test the ability to write out custom external data - -------------------------------------------------------------------------- */ -- (void)testCustomExternalization -{ - NSString* ctName = @"com.apple.security.unit-test-customExternalization"; - NSError* error = nil; - - CFStringRef aName = (CFStringRef)ctName; - CFErrorRef* anError = (CFErrorRef *)&error; - - Boolean registerResult = SecTransformRegister(aName, &CustomExternalization, anError); - STAssertTrue(registerResult, @"Unable to register the custom externalization transform"); - - SecTransformRef externalTrans = SecTransformCreate((CFStringRef)ctName, - (CFErrorRef *)&error); - - STAssertNotNil((id)externalTrans, @"Could not create the custom externalization transform"); - - CFDictionaryRef externalData = SecTransformCopyExternalRepresentation(externalTrans); - STAssertNotNil((NSDictionary *)externalData, @"Did not get a dictionary from SecTransformCopyExternalRepresentation"); - - CFRelease(externalTrans); - - externalTrans = NULL; - externalTrans = SecTransformCreateFromExternalRepresentation(externalData, (CFErrorRef *)&error); - STAssertNotNil((id)externalTrans, @"Could not create the custom external representation"); - CFRelease(externalData); - if (NULL != externalTrans) - { - CFRelease(externalTrans); - } -} - -static SecTransformInstanceBlock TestString(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - SecTransformSetDataAction(ref, kSecTransformActionProcessData, - ^(CFTypeRef value) - { - CFDataRef d = (CFDataRef)value; - if (d) { - return (CFTypeRef)CFStringCreateWithBytes(NULL, CFDataGetBytePtr(d), CFDataGetLength(d), kCFStringEncodingMacRoman, FALSE); - } else { - return (CFTypeRef)d; - } - }); - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testStringResults { - CFStringRef name = CFSTR("com.apple.security.unit-test.string-converter"); - CFErrorRef error = NULL; - SecTransformRegister(name, &TestString, &error); - - SecTransformRef sr = SecTransformCreate(name, NULL); - - unsigned char *msg = (unsigned char *)"This is a test message, it isn't large, but it will get broken into parts by the encode/decode transforms..."; - CFDataRef data = CFDataCreate(NULL, msg, strlen((const char *)msg)); - NSString *ns_msg = [NSString stringWithCString:(const char *)msg encoding:NSMacOSRomanStringEncoding]; - - SecTransformRef er = SecEncodeTransformCreate(kSecBase32Encoding, NULL); - SecTransformRef dr = SecDecodeTransformCreate(kSecBase32Encoding, NULL); - - SecTransformSetAttribute(er, kSecTransformInputAttributeName, data, NULL); - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(er, kSecTransformOutputAttributeName, dr, kSecTransformInputAttributeName, group, NULL); - SecTransformConnectTransforms(dr, kSecTransformOutputAttributeName, sr, kSecTransformInputAttributeName, group, NULL); - - - CFStringRef result = (CFStringRef)SecTransformExecute(sr, NULL); - STAssertEqualObjects(ns_msg, (NSString *)result, @"string results"); - - CFRelease(result); - CFRelease(group); - CFRelease(dr); - CFRelease(er); - CFRelease(sr); - if (error) - { - CFRelease(error); - } -} - -static CFNumberRef MakeNumber1(long n) -{ - return CFNumberCreate(NULL, kCFNumberLongType, &n); -} - - - -static SecTransformInstanceBlock TestRegisterCreate(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - - - SecTransformInstanceBlock instanceBlock = - ^{ - __block long count = 0; - - __block CFNumberRef countNum = MakeNumber1(count);; - SecTransformCustomSetAttribute(ref, CFSTR("Count"), kSecTransformMetaAttributeValue, countNum); - CFRelease(countNum); - fprintf(stderr, "countNum = %p\n", countNum); - - CFErrorRef result = NULL; - SecTransformSetDataAction(ref, kSecTransformActionProcessData, - ^(CFTypeRef value) - { - CFDataRef d = (CFDataRef)value; - if (d) - { - count += CFDataGetLength(d); - - CFNumberRef countNum2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &count); - SecTransformCustomSetAttribute(ref, CFSTR("Count"), kSecTransformMetaAttributeValue, countNum2); - CFRelease(countNum2); - fprintf(stderr, "countNum = %p\n", countNum); - - } else - { - SecTransformCustomSetAttribute(ref, CFSTR("Count"), kSecTransformMetaAttributeValue, NULL); - } - return value; - }); - - - return result; - }; - - return Block_copy(instanceBlock); -} - -- (void)testRegisterCreate -{ - CFStringRef name = CFSTR("com.apple.security.unit-test.novel-unique-at-least-unusual-name"); - long count = 0; - CFNumberRef countNum = NULL; - CFErrorRef error = NULL; - Boolean ok = SecTransformRegister(name, &TestRegisterCreate, &error); - STAssertTrue(ok, @"Successful register"); - - SecTransformRef tr = SecTransformCreate(name, NULL); - STAssertNotNil((NSObject *)tr, @"newly created custom transform"); - SecTransformSetAttribute(tr, CFSTR("DEBUG"), kCFBooleanTrue, NULL); - - char *data_bytes = (char *)"It was the best of transforms, it was the worst of transforms."; - CFDataRef data = CFDataCreate(NULL, (const UInt8 *)data_bytes, strlen(data_bytes)); - - SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL); - - SecTransformRef nt = SecNullTransformCreate(); - SecTransformRef tg = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(tr, CFSTR("OUTPUT"), nt, CFSTR("DISCARD"), tg, &error); - STAssertNil((id)error, @"Connected tr's output to nt's discard: %@", error); - SecTransformConnectTransforms(tr, CFSTR("Count"), nt, CFSTR("INPUT"), tg, &error); - STAssertNil((id)error, @"Connected tr's count to nt's input: %@", error); - - SecTransformSetAttribute(nt, CFSTR("DEBUG"), kCFBooleanTrue, NULL); - - usleep(100); - countNum = (CFNumberRef)SecTransformGetAttribute(tr, CFSTR("Count")); - CFNumberGetValue(countNum, kCFNumberLongType, &count); - CFRelease(countNum); - STAssertTrue(count == 0, @"length unchanged before execute"); - - countNum = (CFNumberRef)SecTransformExecute(tg, NULL); - STAssertNotNil((id)countNum, @"Got result from execute"); - STAssertEquals(CFGetTypeID(countNum), CFNumberGetTypeID(), @"expected a number from execute"); - CFNumberGetValue(countNum, kCFNumberLongType, &count); - CFRelease(countNum); - - STAssertTrue(count == CFDataGetLength(data), @"Wrong data length"); - - CFRelease(tg); - CFRelease(nt); - CFRelease(tr); - CFRelease(data); -} - - -static SecTransformInstanceBlock CountTransformTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - SecTransformSetAttributeAction(ref,kSecTransformActionAttributeNotification, CFSTR("INPUT"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (value) { - if (CFGetTypeID(value) != CFNumberGetTypeID()) { - SecTransformCustomSetAttribute(ref, CFSTR("ABORT"), kSecTransformMetaAttributeValue, CFSTR("Bad type")); - return value; - } - CFNumberRef nr = (CFNumberRef)value; - int max, i; - CFNumberGetValue(nr, kCFNumberIntType, &max); - for(i = 0; i < max; ++i) { - nr = CFNumberCreate(NULL, kCFNumberIntType, &i); - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, nr); - CFRelease(nr); - } - } else { - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, value); - } - - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - -static SecTransformRef count_transform(int n) { - CFStringRef name = CFSTR("com.apple.security.unit-test.count"); - static dispatch_once_t once; - - dispatch_once(&once, - ^{ - SecTransformRegister(name, &CountTransformTest, NULL); - }); - - SecTransformRef ct = SecTransformCreate(name, NULL); - CFNumberRef num = CFNumberCreate(NULL, kCFNumberIntType, &n); - SecTransformSetAttribute(ct, CFSTR("INPUT"), num, NULL); - CFRelease(num); - - return ct; -} - - -static SecTransformInstanceBlock StallTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - __block bool go = false; - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("GO"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - go = true; - return value; - }); - - SecTransformAttributeRef in_ah = SecTransformCustomGetAttribute(ref, CFSTR("INPUT"), kSecTransformMetaAttributeRef); - SecTransformAttributeRef out_ah = SecTransformCustomGetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeRef); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, NULL, - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (!go) { - SecTransformPushbackAttribute(ref, ah, value); - } else { - if (ah == in_ah) { - SecTransformCustomSetAttribute(ref, out_ah, kSecTransformMetaAttributeValue, value); - } - } - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testStall { - CFStringRef name = CFSTR("com.apple.security.unit-test.stall"); - - (void)SecTransformRegister(name, &StallTest, NULL); - - SecTransformRef stall = SecTransformCreate(name, NULL); - SecTransformRef seven = count_transform(7); - SecTransformRef group = SecTransformCreateGroupTransform(); - SecTransformRef delay = delay_transform(NSEC_PER_SEC / 10); - - SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("FOO"), group, NULL); - SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("BAR"), group, NULL); - SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("BAZ"), group, NULL); - SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("INPUT"), group, NULL); - SecTransformConnectTransforms(delay, CFSTR("OUTPUT"), stall, CFSTR("GO"), group, NULL); - - SecTransformSetAttribute(delay, CFSTR("INPUT"), (CFNumberRef)[NSNumber numberWithInt:42], NULL); - - CFErrorRef err = NULL; - CFTypeRef r = SecTransformExecute(group, &err); - - STAssertNotNil((id)r, @"Results from testStall"); - STAssertNil((id)err, @"Got %@ error from testStall", err); - NSArray *array_seven = [NSArray arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], [NSNumber numberWithInt:4], [NSNumber numberWithInt:5], [NSNumber numberWithInt:6], NULL]; - STAssertEqualObjects((id)r, array_seven, @"Correct stall test results"); - - CFRelease(delay); - CFRelease(group); - CFRelease(seven); - CFRelease(stall); -} - --(void)testInappropriateExecution -{ - // We want to have more then enough work for all the CPUs to help force a race, so twice - // the number of logical CPUs should do it. NOTE: the completion blocks got to a low - // priority concurrent queue to encourage them to finish out of order and put more - // stress on the system we are testing. - - int logical_cpus = 1; - size_t int_size = sizeof(logical_cpus); - int return_code = sysctlbyname("hw.logicalcpu_max", &logical_cpus, &int_size, NULL, 0); - int e = errno; // Save this value so it doesn't get trashed by any subsequent syscalls - STAssertEquals(return_code, 0, @"sysctlbyname failed %s (%d), assuming 1 CPU", strerror(e), e); - - SecTransformRef count_a_bunch = count_transform(logical_cpus * 2); - CFErrorRef err = NULL; - dispatch_group_t wait_for_async_to_complete = dispatch_group_create(); - dispatch_group_t outstanding_executions = dispatch_group_create(); - SecTransformRef count_group = SecTransformCreateGroupTransform(); - - SecTransformConnectTransforms(count_a_bunch, CFSTR("kludge1"), count_a_bunch, CFSTR("kludge2"), count_group, &err); - STAssertNil((id)err, @"Error (%@) connecting count transform to itself", err); - - dispatch_group_enter(wait_for_async_to_complete); - SecTransformExecuteAsync(count_a_bunch, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) - { - dispatch_group_enter(outstanding_executions); - - CFErrorRef err = NULL; - CFTypeRef no_result = SecTransformExecute(count_a_bunch, &err); - STAssertNil((id)no_result, @"Attempting to execute an already executing transform should fail, not provide results: %@", no_result); - STAssertNotNil((id)err, @"Attempting to execute an already executing transform should produce some sort of error"); - CFRelease(err); - - dispatch_group_leave(outstanding_executions); - - if (isFinal) - { - // Give any pending executions time to get to the group_enter - usleep(100); - dispatch_group_wait(outstanding_executions, DISPATCH_TIME_FOREVER); - dispatch_release(outstanding_executions); - dispatch_group_leave(wait_for_async_to_complete); - } - }); - - // Before that SecTransformExecuteAsync completes, we do some more work at >low priority to help - // keep the completion blocks landing out of order. In particular we run a transform to - // completion, and then confirm that we can't run it again. - - SecTransformRef no_work = SecNullTransformCreate(); - SecTransformRef no_work_group = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(no_work, CFSTR("kludge1"), no_work, CFSTR("kludge2"), no_work_group, &err); - STAssertNil((id)err, @"Can't connect no_work to itself (to make no_work_group), err=%@", err); - - SecTransformSetAttribute(no_work, CFSTR("INPUT"), CFSTR("value"), NULL); - CFTypeRef no_result = SecTransformExecute(no_work_group, &err); - STAssertNil((id)err, @"First execute of Null Transform should be ok, got e=%@", err); - STAssertNotNil((id)no_result, @"First execute of Null Transform should produce a value"); - - no_result = SecTransformExecute(no_work_group, &err); - - STAssertNotNil((id)err, @"Second execute of Null Transform should fail!"); - STAssertNil((id)no_result, @"Second execute of Null Transform shouldn't produce a value, got r=%@", no_result); - CFRelease(err); - - // Now we wait for that first batch of tests to finish, we don't want to call STFail after self goes away. - - dispatch_group_wait(wait_for_async_to_complete, DISPATCH_TIME_FOREVER); - dispatch_release(wait_for_async_to_complete); - - if (no_result) CFRelease(no_result); - if (no_work) CFRelease(no_work); - if (no_work_group) CFRelease(no_work_group); - if (count_group) CFRelease(count_group); - if (count_a_bunch) CFRelease(count_a_bunch); -} - -static SecTransformInstanceBlock ConnectionReqTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - SecTransformAttributeRef xah = - (SecTransformAttributeRef)SecTranformCustomGetAttribute(ref, CFSTR("XYZZY"), kSecTransformMetaAttributeRef); - - SecTransformCustomSetAttribute(ref, xah, kSecTransformMetaAttributeRequiresOutboundConnection, kCFBooleanTrue); - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeRequiresOutboundConnection, kCFBooleanFalse); - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - SecTransformCustomSetAttribute(ref, xah, kSecTransformMetaAttributeValue, value); - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - - --(void)testConnectionReq { - - CFStringRef req_xyzzy_name = CFSTR("com.apple.security.unit-test.req_xyzzy"); - - (void)SecTransformRegister(req_xyzzy_name, &ConnectionReqTest, NULL); - - SecTransformRef tr_req_xyzzy = SecTransformCreate(req_xyzzy_name, NULL); - - CFTypeRef in_value = (CFTypeRef)@"Fnord"; - SecTransformSetAttribute(tr_req_xyzzy, CFSTR("INPUT"), in_value, NULL); - - CFErrorRef err = NULL; - CFTypeRef r = SecTransformExecute(tr_req_xyzzy, &err); - - STAssertNil((id)r, @"Execute of tr_req_xyzzy with no xyzzy r=%@", r); - STAssertErrorHas((id)err, @"req_xyzzy", @"Error failed to refer to the transform by name (%@)", err); - STAssertErrorHas((id)err, @"XYZZY", @"Error failed to refer to missing attribute by name (%@)", err); - STAssertErrorHas((id)err, @"requires.*outbound connection", @"Error failed to diagnose invalid condition (%@)", err); - - CFRelease(err); - CFRelease(tr_req_xyzzy); - if (r) CFRelease(r); - - /* - - Note For Josh: - - To make this work we need Josh's fix for FindLastTransform! - - CFRelease(tr_req_xyzzy); - tr_req_xyzzy = SecTransformCreate(req_xyzzy_name, NULL); - SecTransformSetAttribute(tr_req_xyzzy, CFSTR("INPUT"), in_value, NULL); - - SecTransformRef group = SecTransformCreateGroupTransform(); - SecTransformRef tee = SecNullTransformCreate(); - SecTransformConnectTransforms(tr_req_xyzzy, CFSTR("XYZZY"), tee, kSecTransformInputAttributeName, group, &err); - STAssertNil((id)err, @"err=%@ from connect", err); - STAssertNotNil((id)group, @"No group after connect"); - r = SecTransformExecute(group, &err); - STAssertNil((id)err, @"Execute err=%@"); - STAssertEqualObjects((id)in_value, (id)r, @"Execution Result"); - - */ -} - -static SecTransformInstanceBlock DeferredTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - SecTransformCustomSetAttribute(ref, CFSTR("LATE"), kSecTransformMetaAttributeDeferred, kCFBooleanTrue); - SecTransformCustomSetAttribute(ref, CFSTR("INPUT"), kSecTransformMetaAttributeDeferred, kCFBooleanFalse); - - __block CFTypeRef in_v = NULL, late_v = NULL; - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (NULL != late_v) { - SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, - CreateGenericErrorRef(CFSTR("FAIL"), 1, "LATE (%@) should process after INPUT (%@)", late_v, value)); - } - in_v = value; - return value; - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("LATE"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (NULL == in_v) { - SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, - CreateGenericErrorRef(CFSTR("FAIL"), 1, "INPUT (%@) should process before LATE (%@)", in_v, value)); - } - - late_v = value; - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, NULL); - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - - --(void)testDeferred { - CFStringRef deferred_name = CFSTR("com.apple.security.unit-test.deferred"); - - (void)SecTransformRegister(deferred_name, &DeferredTest, NULL); - - SecTransformRef dt = SecTransformCreate(deferred_name, NULL); - - // these set attribute calls are failing, but we're ignoring the failures - SecTransformSetAttribute(dt, CFSTR("INPUT"), (CFTypeRef)CFSTR("BLAH"), NULL); - SecTransformSetAttribute(dt, CFSTR("LATE"), (CFTypeRef)CFSTR("QUUX"), NULL); - CFErrorRef err = NULL; - SecTransformExecute(dt, &err); - STAssertNil((id)err, @"Error from execute err=%@", err); - - if (err) CFRelease(err); - // CFRelease(dt); -} - -static SecTransformInstanceBlock SaveRestoreTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - SecTransformCustomSetAttribute(ref, CFSTR("Needed"), kSecTransformMetaAttributeRequired, kCFBooleanTrue); - SecTransformCustomSetAttribute(ref, CFSTR("NoSaves"), kSecTransformMetaAttributeExternalize, kCFBooleanFalse); - - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testSaveRestore -{ - - unsigned char raw_data[] = "Val-U-Sav, nw wth lss vwls!"; - CFDataRef data = CFDataCreate(NULL, (const UInt8*)&raw_data, sizeof(raw_data)); - CFErrorRef err = NULL; - - CFStringRef name = CFSTR("com.apple.security.unit-test.SaveRestoreTest"); - - (void)SecTransformRegister(name, &SaveRestoreTest, NULL); - - SecTransformRef tr1 = SecTransformCreate(name, NULL); - - SecTransformSetAttribute(tr1, CFSTR("Optional"), CFSTR("42"), NULL); - SecTransformSetAttribute(tr1, CFSTR("Needed"), CFSTR("and provided"), NULL); - SecTransformSetAttribute(tr1, CFSTR("NoSaves"), CFSTR("42"), NULL); - - CFDictionaryRef xr = SecTransformCopyExternalRepresentation(tr1); - STAssertNotNil((NSDictionary *)xr, @"external rep"); - SecTransformRef tr2 = SecTransformCreateFromExternalRepresentation(xr, NULL); - SecTransformSetAttribute(tr2, kSecTransformInputAttributeName, data, NULL); - CFTypeRef none = SecTransformGetAttribute(tr2, CFSTR("NoSaves")); - STAssertNil((id)none, @"Expected %@ to be nil", none); - CFTypeRef forty_two = SecTransformGetAttribute(tr2, CFSTR("Optional")); - STAssertEqualObjects((id)forty_two, @"42", @"restored incorrect value"); - - CFDataRef d = (CFDataRef)SecTransformExecute((NSObject *)tr2, &err); - - STAssertNotNil((NSData * )d, @"execute result (err=%@)", err); - - if (err) { - CFRelease(err); - } - - CFRelease(tr1); - CFRelease(tr2); - CFRelease(xr); - - tr1 = SecTransformCreate(name, NULL); - SecTransformSetAttribute(tr1, CFSTR("Needed"), CFSTR("and provided"), NULL); - SecTransformSetAttribute(tr1, CFSTR("NoSaves"), CFSTR("42"), NULL); - xr = SecTransformCopyExternalRepresentation(tr1); - tr2 = SecTransformCreateFromExternalRepresentation(xr, NULL); - - - - //tr2 = SecTransformCreateFromExternalRepresentation(xr, NULL); - SecTransformRef tga = SecTransformCreateGroupTransform(); - SecTransformSetAttribute(tr1, kSecTransformInputAttributeName, data, NULL); - - // XXX did not swap - SecTransformConnectTransforms(tr1, CFSTR("OUTPUT"), tr2, CFSTR("INPUT"), tga, NULL); - CFStringRef has1 = CFSTR("I has one!"); - CFStringRef has2 = CFSTR("I has two of them!"); - SecTransformSetAttribute(tr1, CFSTR("Needed"), has1, NULL); - SecTransformSetAttribute(tr2, CFSTR("Needed"), has2, NULL); - xr = SecTransformCopyExternalRepresentation(tr1); - STAssertNotNil((NSDictionary *)xr, @"external rep for 2"); - NSLog(@"xr=%@", xr); - - SecTransformRef tgb = SecTransformCreateFromExternalRepresentation(xr, &err); - STAssertNil((id)tgb, @"made transform group with duplicate labels"); - STAssertErrorHas((id)err, (NSString*)name, @"Error failed to identify the transform (%@)", err); - STAssertErrorHas((id)err, @"damage|duplicate", @"Error failed to diagnose the invalid condition (%@)", err); - - CFStringRef new_name2 = CFSTR("SaveRestoreTestThingie#2"); - CFStringRef fetched_name; - int attempts; - - for(attempts = 0; attempts < 20; ++attempts) - { - SecTransformSetAttribute(tr2, CFSTR("NAME"), new_name2, &err); - fetched_name = (CFStringRef)SecTransformGetAttribute(tr2, CFSTR("NAME")); - - STAssertNil((id)err, @"Error from setting tr2's name: %@", err); - STAssertEqualObjects((id)fetched_name, (id)new_name2, @"Set tr2's name, attempt %d", attempts); - if (CFEqual(fetched_name, new_name2)) - { - break; - } - if (attempts > 10) - { - usleep(1000); - } - } - - xr = SecTransformCopyExternalRepresentation(tr1); - STAssertNotNil((NSDictionary *)xr, @"external rep for 2, take 2"); - NSLog(@"xr=%@", xr); - - tgb = SecTransformCreateFromExternalRepresentation(xr, &err); - STAssertNotNil((id)tgb, @"made transform group (take 2)"); - STAssertNil((id)err, @"error from make 2 take 2 (err=%@)", err); - - SecTransformRef tr1b = SecTransformFindByName(tgb, (CFStringRef)SecTransformGetAttribute(tr1, CFSTR("NAME"))); - STAssertNotNil((id)tr1b, @"Found tr1b"); - SecTransformRef tr2b = SecTransformFindByName(tgb, (CFStringRef)SecTransformGetAttribute(tr2, CFSTR("NAME"))); - STAssertNotNil((id)tr2b, @"Found tr2b"); - - CFStringRef has1b = (CFStringRef)SecTransformGetAttribute(tr1b, CFSTR("Needed")); - STAssertNotNil((id)tr1b, @"tr1b's name"); - CFStringRef has2b = (CFStringRef)SecTransformGetAttribute(tr2b, CFSTR("Needed")); - STAssertNotNil((id)tr2b, @"tr1b's name"); - - STAssertEqualObjects((id)has1, (id)has1b, @"has1 == has1b"); - STAssertEqualObjects((id)has2, (id)has2b, @"has2 == has2b"); - -} - --(void)testRequiredAttributes -{ - CFStringRef name = CFSTR("com.apple.security.unit-test.requiresStuffThings"); - CFErrorRef error; - // In addition to testing required attributes, this also does a partial "lifecycle" test, making sure we - // pass through the stages, don't regress stages, and don't receive the wrong events in the wrong stages. - typedef enum { S_INITED = 0, S_STARTED, S_RUN, S_EOS, S_GONE } state_t; - - __block state_t state = S_INITED; - dispatch_group_t leave_on_finalize = dispatch_group_create(); - - SecTransformCreateBlock required_attributes_create_block = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) { - params->overrideAttribute(kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, ^(SecTransformAttributeRef attribute, CFTypeRef value) { - // NOTE: this is for testing with a single data value, not a series. - if (value) - { - STAssertTrue(state == S_STARTED, @"Init'ed for data (state=%d)", state); - state = S_RUN; - } else { - STAssertTrue(state == S_RUN, @"In run state at EOS (state=%d)", state); - state = S_EOS; - } - params->send(kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, value); - return value; - }); - - params->send(CFSTR("Stuff"), kSecTransformMetaAttributeRequired, kCFBooleanTrue); - params->send(CFSTR("Things"), kSecTransformMetaAttributeRequired, kCFBooleanTrue); - - params->overrideTransform(kSecTransformActionStartingExecution, ^{ - STAssertTrue(state == S_INITED, @"Inited (state=%d)"); - state = S_STARTED; - return (CFTypeRef)NULL; - }); - - params->overrideTransform(kSecTransformActionFinalize, ^{ - state = S_GONE; - dispatch_group_leave(leave_on_finalize); - return (CFTypeRef)NULL; - }); - }; - - dispatch_group_enter(leave_on_finalize); - SecTransformRef tr = custom_transform(name, required_attributes_create_block); - STAssertNotNil((NSObject *)tr, @"newly created custom transform"); - - char *data_bytes = (char *)"It was the best of transforms, it was the worst of transforms."; - CFDataRef data = CFDataCreate(NULL, (const UInt8*)data_bytes, strlen(data_bytes)); - SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL); - usleep(100); - STAssertTrue(state == S_INITED, @"not run yet"); - CFDataRef rdata = (CFDataRef)SecTransformExecute((NSObject *)tr, &error); - - STAssertTrue(rdata == NULL, @"Expected no result, but got: %@", rdata); - STAssertErrorHas((id)error, @"missing required attributes?", @"Error describes condition (%@)", error); - STAssertErrorHas((id)error, @" Things[ ,)]", @"Missing attributes named (%@)", error); - STAssertErrorHas((id)error, @" Stuff[ ,)]", @"Missing attributes named (%@)", error); - STAssertErrorHas((id)error, @"requiresStuffThings", @"Name of erroring Transform in message (%@)", error); - - if (error) { - CFRelease(error); - } - CFRelease(tr); - - STAssertFalse(dispatch_group_wait(leave_on_finalize, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"group was ready"); - STAssertTrue(state == S_GONE, @"Transform should be gone, state=%d", state); - - dispatch_group_enter(leave_on_finalize); - state = S_INITED; - tr = custom_transform(name, required_attributes_create_block); - STAssertNotNil((NSObject *)tr, @"newly created custom transform"); - - error = NULL; - SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL); - SecTransformSetAttribute(tr, CFSTR("Things"), CFSTR("grubby things"), NULL); - SecTransformSetAttribute(tr, CFSTR("Stuff"), CFSTR("Cool stuff"), NULL); - rdata = (CFDataRef)SecTransformExecute(tr, &error); - - STAssertNotNil((NSData *)rdata, @"Got data back"); - STAssertEqualObjects((NSData *)rdata, (NSData *)data, @"Data unchanged"); - STAssertTrue(state == S_EOS, @"Transform hit EOS"); - STAssertTrue(error == NULL, @"Error not set"); - - CFRelease(tr); - STAssertFalse(dispatch_group_wait(leave_on_finalize, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"group was ready"); - STAssertTrue(state == S_GONE, @"Transform gone (state=%d)", state); - dispatch_group_notify(leave_on_finalize, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - dispatch_release(leave_on_finalize); - }); -} - -static SecTransformInstanceBlock AttributeNotificationTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, NULL, - ^(SecTransformStringOrAttributeRef ah, CFTypeRef value) - { - SecTransformCustomSetAttribute(ref, CFSTR("Generic"), kSecTransformMetaAttributeValue, kCFBooleanTrue); - return value; - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("Specific"), - ^(SecTransformStringOrAttributeRef ah, CFTypeRef value) - { - SecTransformCustomSetAttribute(ref, CFSTR("Specific"), kSecTransformMetaAttributeValue, kCFBooleanTrue); - return value; - - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("AlsoSpecific"), - ^(SecTransformStringOrAttributeRef ah, CFTypeRef value) - { - SecTransformCustomSetAttribute(ref, CFSTR("AlsoSpecific"), kSecTransformMetaAttributeValue, kCFBooleanTrue); - - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testAttributeNotifications -{ - NSString *name = @"com.apple.security.unit-test.testAttributeNotifications"; - Boolean generic_called = NO; - Boolean specific_called = NO; - Boolean also_specific_called = NO; - - Boolean ok = SecTransformRegister((CFStringRef)name, &AttributeNotificationTest, NULL); - - STAssertTrue(ok, @"Successful register"); - - SecTransformRef tr = SecTransformCreate((CFStringRef)name, NULL); - - CFStringRef aNameStr = ((CFStringRef)name); - SecTransformSetAttribute(tr, CFSTR("Generic"), aNameStr, NULL); - SecTransformSetAttribute(tr, CFSTR("Specific"), aNameStr, NULL); - SecTransformSetAttribute(tr, CFSTR("AlsoSpecific"), aNameStr, NULL); - - generic_called = (kCFBooleanTrue == (CFBooleanRef)SecTransformGetAttribute(tr, CFSTR("Generic"))); - specific_called = (kCFBooleanTrue == (CFBooleanRef)SecTransformGetAttribute(tr, CFSTR("Specific"))); - also_specific_called = (kCFBooleanTrue == (CFBooleanRef)SecTransformGetAttribute(tr, CFSTR("AlsoSpecific"))); - - - STAssertTrue(generic_called, @"generic called"); - STAssertTrue(specific_called, @"specific called"); - STAssertTrue(also_specific_called, @"also specific called"); - - CFRelease(tr); -} - --(void)testEncryptAndDecryptTransforms -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - - // generate a symmetrical key for testing - OSStatus err = errSecSuccess; - - NSString* algNames[] = - { - @"AES 128", - @"AES 192", - @"AES 256", - @"DES", - @"3DES", - @"CAST", - @"RC4" - }; - - CSSM_ALGORITHMS symmetricalAlgos[] = - { - CSSM_ALGID_AES, - CSSM_ALGID_AES, - CSSM_ALGID_AES, - CSSM_ALGID_DES, - CSSM_ALGID_3DES_3KEY_EDE, - CSSM_ALGID_CAST, - CSSM_ALGID_RC4 - }; - - uint32 keySizes[] = - { - 128, - 192, - 256, - 64, - 192, - 40, - 8 - }; - - CSSM_KEYUSE keyUse = CSSM_KEYUSE_ANY; - CSSM_KEYATTR_FLAGS keyAttrFlags = CSSM_KEYATTR_RETURN_DEFAULT; - SecAccessRef accessRef = NULL; - CSSM_CC_HANDLE handle = ((CSSM_CC_HANDLE)0); - - NSString* dataStr = @"At the round earth's imagined corners blow\ - Your trumpets, angels, and arise, arise\ - From death, you numberless infinities\ - Of souls, and to your scattered bodies go,\ - All whom the flood did, and fire shall, overthrow,\ - All whom war, dearth, age, agues, tyrannies,\ - Despair, law, chance, hath slain, and you whose eyes\ - Shall behold God, and never taste death's woe.\ - But let them sleep, Lord, and me mourn a space,\ - For, if above all these my sins abound,\ - 'Tis late to ask abundance of Thy grace,\ - When we are there. Here on this lowly ground\ - Teach me how to repent; for that's as good\ - As if Thou'dst sealed my pardon, with Thy blood."; - - NSData* testData = [dataStr dataUsingEncoding:NSUTF8StringEncoding]; - int numItems = (sizeof(symmetricalAlgos) / sizeof(CSSM_ALGORITHMS)); - int iCnt = 0; - - for (iCnt = 0; iCnt < numItems; iCnt++) - { - SecKeyRef testKey = NULL; - CSSM_ALGORITHMS algoToUse = symmetricalAlgos[iCnt]; - uint32 keySizeInBits = keySizes[iCnt]; - - err = SecKeyGenerate(NULL, algoToUse, keySizeInBits, handle, keyUse, keyAttrFlags, accessRef, &testKey); - STAssertTrue(err == errSecSuccess, [NSString stringWithFormat:@"Unable to create a symmetrical key %@", algNames[iCnt]]); - if (errSecSuccess != err) - { - continue; - } - __block CFErrorRef error = NULL; - - SecTransformRef encryptSymRef = NULL; - encryptSymRef = SecEncryptTransformCreate(testKey, &error); - if (NULL != error) - { - CFRelease(testKey); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the encrypt transform for key %@", algNames[iCnt]]); - continue; - } - - SecTransformRef decryptSymRef = SecDecryptTransformCreate(testKey, &error); - if (NULL != error) - { - CFRelease(testKey); - CFRelease(encryptSymRef); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the decrypt transform for key %@", algNames[iCnt]]); - continue; - } - - // connect the output of the encryption to the input of the decryption transform - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - (void)SecTransformConnectTransforms(encryptSymRef, kSecTransformOutputAttributeName, - decryptSymRef, kSecTransformInputAttributeName, - group, &error); - if (NULL != error) - { - CFRelease(testKey); - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to connect transforms for key %@", algNames[iCnt]]); - continue; - } - - - NSInputStream* dataStream = [NSInputStream inputStreamWithData:testData]; - [dataStream open]; - - SecTransformSetAttribute(encryptSymRef, kSecTransformInputAttributeName, (CFTypeRef)dataStream, &error); - if (NULL != error) - { - CFRelease(testKey); - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to set the input for key %@", algNames[iCnt]]); - continue; - } - - CFTypeRef transformResult = SecTransformExecute(encryptSymRef, &error); - CFRelease(group); - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - - if (NULL != error) - { - STAssertTrue(NO, [NSString stringWithFormat:@"returned an error for algo %@", algNames[iCnt]]); - continue; - CFRelease(error); - } - - if (NULL == transformResult || 0 == [(NSData*)transformResult length]) - { - STAssertTrue(NO, [NSString stringWithFormat:@"transformResult was NULL or empty for %@", algNames[iCnt]]); - continue; - } - - NSData* resultData = nil; - if (CFGetTypeID(transformResult) == CFDataGetTypeID()) - { - resultData = (NSData*)transformResult; - [resultData autorelease]; - } - - CFRelease(testKey); - - STAssertTrue([testData isEqualToData:resultData], @"The output of the decrypt transform does NOT match the original input!"); - } - - - SecKeyRef publicKey = NULL; - SecKeyRef privateKey = NULL; - - keyAttrFlags = CSSM_KEYATTR_RETURN_REF; - - const uint32 publicKeyAttributes = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF; - const uint32 privateKeyAttributes = CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE; - - CSSM_KEYUSE pubKeyUse = CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_WRAP; - CSSM_KEYUSE privKeyUse = CSSM_KEYUSE_SIGN | CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_UNWRAP; - - - err = SecKeyCreatePair(NULL, CSSM_ALGID_RSA, 2048, ((CSSM_CC_HANDLE)0), - pubKeyUse, publicKeyAttributes, - privKeyUse, privateKeyAttributes, - NULL, &publicKey, &privateKey); - - STAssertTrue(errSecSuccess == err, @"Unable to create a key pair"); - if (errSecSuccess != err) - { - cssmPerror(NULL, err); - return; - } - - CFErrorRef error = NULL; - SecTransformRef encryptSymRef = SecEncryptTransformCreate(publicKey , &error); - if (NULL != error) - { - CFRelease(publicKey); - CFRelease(privateKey); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the encrypt transform for key RSA"]); - return; - } - - SecTransformRef decryptSymRef = SecDecryptTransformCreate(privateKey, &error); - if (NULL != error) - { - CFRelease(publicKey); - CFRelease(privateKey); - CFRelease(encryptSymRef); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the decrypt transform for key RSA"]); - return; - } - - // connect the output of the encryption to the input of the decryption transform - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - (void)SecTransformConnectTransforms( encryptSymRef, kSecTransformOutputAttributeName, - decryptSymRef, kSecTransformInputAttributeName, - group, &error); - if (NULL != error) - { - CFRelease(publicKey); - CFRelease(privateKey); - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to connect transforms for key RSA"]); - return; - } - - NSInputStream* dataStream = [NSInputStream inputStreamWithData:testData]; - [dataStream open]; - - SecTransformSetAttribute(encryptSymRef, kSecTransformInputAttributeName, (CFTypeRef)dataStream, &error); - if (NULL != error) - { - CFRelease(publicKey); - CFRelease(privateKey); - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - STAssertTrue(NO, [NSString stringWithFormat:@"Unable to set the input for key RSA"]); - return; - } - CFTypeRef transformResult = SecTransformExecute(encryptSymRef, &error); - if (NULL != error) - { - STAssertTrue(NO, [NSString stringWithFormat:@"returned an error for RSA"]); - CFRelease(error); - return; - } - - if (NULL == transformResult || 0 == [(NSData*)transformResult length]) - { - STAssertTrue(NO, [NSString stringWithFormat:@"transformResult was NULL or empty for RSA"]); - return; - } - - NSData* resultData = nil; - if (CFGetTypeID(transformResult) == CFDataGetTypeID()) - { - resultData = (NSData*)transformResult; - [resultData autorelease]; - } - - CFRelease(publicKey); - CFRelease(privateKey); - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - - STAssertTrue([testData isEqualToData:resultData], @"(RSA)The output of the decrypt transform does NOT match the original input!"); - - [pool drain]; -} - -// NOTE: this test is largely the same as testEncryptAndDecryptTransforms, but -// we make a single key and use it from many threads at once. This uncovered -// some locking issues, so makes a good regression test. --(void)testMultiEncryptWithSameKey { - // generate a symmetrical key for testing - CSSM_KEYUSE keyUse = CSSM_KEYUSE_ANY; - CSSM_KEYATTR_FLAGS keyAttrFlags = CSSM_KEYATTR_RETURN_DEFAULT; - SecAccessRef accessRef = NULL; - CSSM_CC_HANDLE handle = ((CSSM_CC_HANDLE)0); - - NSString* dataStr = @"Reduce, reuse, recycle. No crashes please."; - NSData* testData = [dataStr dataUsingEncoding:NSUTF8StringEncoding]; - - SecKeyRef testKey = NULL; - { - OSStatus err; - err = SecKeyGenerate(NULL, CSSM_ALGID_AES, 256, handle, keyUse, keyAttrFlags, accessRef, &testKey); - STAssertTrue(err == errSecSuccess, @"Unable to create a symmetrical key err=%x", err); - } - - // The number of iterations is somewhat arbitrary. When we use to have failures they were - // within 2*#logicalCPUs iterations, but nothing says we won't have a regression that happens - // outside that window. - dispatch_apply(128, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t i) { - __block CFErrorRef error = NULL; - - SecTransformRef encryptSymRef = NULL; - encryptSymRef = SecEncryptTransformCreate(testKey, &error); - if (NULL != error) - { - STFail(@"Unable to create the encrypt transform iteration#%d error=%@", i, error); - return; - } - if (NULL == encryptSymRef) { - STFail(@"Unable to create the encrypt transform iteration#%d, error=NULL", i); - return; - } - - SecTransformRef decryptSymRef = SecDecryptTransformCreate(testKey, &error); - if (NULL != error) - { - CFRelease(encryptSymRef); - STFail(@"Unable to create the decrypt transform iteration#%d error=%@", i, error); - return; - } - if (NULL == decryptSymRef) { - CFRelease(encryptSymRef); - STFail(@"Unable to create the decrypt transform iteration#%d, error=NULL", i); - return; - } - - // connect the output of the encryption to the input of the decryption transform - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - (void)SecTransformConnectTransforms(encryptSymRef, kSecTransformOutputAttributeName, - decryptSymRef, kSecTransformInputAttributeName, - group, &error); - if (NULL != error) - { - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - STFail(@"Unable to connect transforms on iteration %d error=%@", i, error); - return; - } - - - NSInputStream* dataStream = [NSInputStream inputStreamWithData:testData]; - [dataStream open]; - - SecTransformSetAttribute(encryptSymRef, kSecTransformInputAttributeName, (CFTypeRef)dataStream, &error); - if (NULL != error) - { - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - STFail(@"Unable to set the input on iteration %d error=%@", i, error); - return; - } - - CFTypeRef transformResult = SecTransformExecute(encryptSymRef, &error); - CFRelease(group); - - if (NULL != error) - { - STFail(@"returned an error on iteration %d error=%@", i, error); - CFRelease(error); - return; - } - - if (NULL == transformResult || 0 == [(NSData*)transformResult length]) - { - STFail(@"transformResult was NULL or empty for iteration %d", i); - return; - } - - NSData* resultData = nil; - if (CFGetTypeID(transformResult) == CFDataGetTypeID()) - { - resultData = (NSData*)transformResult; - [resultData autorelease]; - } - - CFRelease(encryptSymRef); - CFRelease(decryptSymRef); - - STAssertEqualObjects(testData, resultData, @"The output of the decrypt transform does NOT match the original input iteration %d", i); - }); - - CFRelease(testKey); -} - -static SecTransformInstanceBlock RoundTripCheck(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - __block CFDataRef remainder = NULL; - __block SecTransformStringOrAttributeRef ahead = NULL; - __block int eof_count = 0; - __block bool drain = false; - - SecTransformCustomSetAttribute(ref, CFSTR("INPUT2"), kSecTransformMetaAttributeDeferred, kCFBooleanTrue); - SecTransformCustomSetAttribute(ref, CFSTR("INPUT2"), kSecTransformMetaAttributeStream, kCFBooleanTrue); - - dispatch_block_t not_equal = - ^{ - // not equal - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, kCFBooleanFalse); - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, NULL); - drain = true; - }; - - SecTransformAttributeActionBlock action = - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (drain) - { - return (CFTypeRef)NULL; - } - - if (ahead == ah) - { - SecTransformPushbackAttribute(ref, ah, value); - } - else if (value) - { - CFDataRef d = (CFDataRef)value; - if (remainder) - { - CFIndex compare_length; - CFIndex remainder_length = CFDataGetLength(remainder); - CFIndex d_length = CFDataGetLength(d); - CFDataRef new_remainder = NULL; - SecTransformAttributeRef new_ahead = NULL; - - if (remainder_length == d_length) - { - compare_length = d_length; - } - else if (remainder_length < d_length) - { - new_remainder = CFDataCreate(NULL, CFDataGetBytePtr(d) + remainder_length, d_length - remainder_length); - compare_length = remainder_length; - new_ahead = ah; - } else - { - new_remainder = CFDataCreate(NULL, CFDataGetBytePtr(remainder) + d_length, remainder_length - d_length); - compare_length = d_length; - new_ahead = ahead; - } - - if (bcmp(CFDataGetBytePtr(d), CFDataGetBytePtr(remainder), compare_length)) { - not_equal(); - } else - { - // same, keep going - CFRelease(remainder); - remainder = new_remainder; - ahead = new_ahead; - } - } - else - { - if (!eof_count) - { - ahead = ah; - remainder = CFDataCreateCopy(NULL, d); - } - else - { - if (CFDataGetLength(d)) - { - not_equal(); - } - } - } - } - else - { // EOF case - ahead = NULL; - if (++eof_count == 2) - { - if (remainder) - { - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, - kSecTransformMetaAttributeValue, - CFDataGetLength(remainder) ? kCFBooleanFalse : kCFBooleanTrue); - - CFRelease(remainder); - } - else - { - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, - kSecTransformMetaAttributeValue, kCFBooleanTrue); - } - - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, - kSecTransformMetaAttributeValue, NULL); - } - } - - return (CFTypeRef)NULL; - }; - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT2"), action); - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, action); - - return result; - }; - - return Block_copy(instanceBlock); -} - -static BOOL RoundTrip(CFStringRef fname, SecTransformRef in, SecTransformRef out, BOOL share) -{ - static dispatch_once_t once; - CFStringRef name = CFSTR("com.apple.examples.cmp"); - // concepts: pushback, SecTransformSetAttributeAction vs. ProcessData, ah==, & send value to output - - dispatch_once(&once, - ^{ - SecTransformRegister(name, &RoundTripCheck, NULL); - }); - - SecTransformRef cmp = SecTransformCreate(name, NULL); - SecTransformRef group = SecTransformCreateGroupTransform(); - CFErrorRef err = NULL; - SecTransformConnectTransforms(in, kSecTransformOutputAttributeName, out, kSecTransformInputAttributeName, group, NULL); - SecTransformConnectTransforms(out, kSecTransformOutputAttributeName, cmp, kSecTransformInputAttributeName, group, NULL); - NSInputStream *is = [NSInputStream inputStreamWithFileAtPath:(NSString *)fname]; - // XXX: failure to do this seem to crash SecTransformExecute when it releases the error, track down & fix or file radar - [is open]; - - NSInputStream *is2 = nil; - - if (share) - { - SecTransformRef tee = SecNullTransformCreate(); - SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, in, kSecTransformInputAttributeName, group, NULL); - SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, cmp, CFSTR("INPUT2"), group, NULL); - SecTransformSetAttribute(tee, kSecTransformInputAttributeName, (CFTypeRef)is, NULL); - CFRelease(tee); - } else { - is2 = [NSInputStream inputStreamWithFileAtPath:(NSString *)fname]; - [is2 open]; - SecTransformSetAttribute(in, kSecTransformInputAttributeName, (CFTypeRef)is, &err); - SecTransformSetAttribute(cmp, CFSTR("INPUT2"), (CFTypeRef)is2, &err); - } - - assert(err == NULL); - CFTypeRef r = SecTransformExecute(group, &err); - - if (err) - { - CFRelease(err); - } - - CFRelease(group); - CFRelease(cmp); - - if (is2) - { - [is2 close]; - } - - if (is) - { - [is close]; - } - - if (r) - { - return r == kCFBooleanTrue; - } - else - { - CFfprintf(stderr, "round trip error: %@", err); - return NO; - } -} - -static SecTransformInstanceBlock LineLengthCheck(CFStringRef name, SecTransformRef newTransform, SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = ^{ - CFErrorRef result = NULL; - __block int bytesPastLastEOL = 0; - __block int max = 0; - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("MAX"), ^(SecTransformAttributeRef ah, CFTypeRef value) { - CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &max); - return value; - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, ^(SecTransformAttributeRef ah, CFTypeRef value) { - if (NULL != value) { - CFDataRef d = (CFDataRef)value; - CFIndex len = CFDataGetLength(d); - const UInt8 *bytes = CFDataGetBytePtr(d); - - for(int i = 0; i < len; i++) { - if (bytes[i] == '\n') { - bytesPastLastEOL = 0; - } else { - bytesPastLastEOL++; - if (bytesPastLastEOL > max) { - SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "MAX line length of %d exceeded", max)); - break; - } - } - } - } - SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, value); - return value; - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - --(void)testLargeChunkEncode -{ - NSError *err = NULL; - NSData *d = [NSData dataWithContentsOfFile:@"/usr/share/dict/web2a" options:NSDataReadingMapped error: &err]; - STAssertNil(err, @"dataWithContentsOfFile %@", err); - CFStringRef types[] = {kSecZLibEncoding, kSecBase64Encoding, kSecBase32Encoding, NULL}; - - dispatch_group_t dg = dispatch_group_create(); - - CFStringRef lengthCheckName = CFSTR("com.apple.security.unit-test.lineLengthCheck"); - SecTransformRegister(lengthCheckName, LineLengthCheck, (CFErrorRef *)&err); - STAssertNil(err, @"Expected to register %@", lengthCheckName); - - for(int i = 0; types[i]; i++) { - int max_j = 80; - CFStringRef etype = types[i]; - - void (^trial)(NSString *testName, id lineLength, int maxLineLength) = ^(NSString *testName, id lineLength, int maxLineLength) { - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - - SecTransformRef et = SecEncodeTransformCreate(etype, (CFErrorRef *)&err); - SecTransformRef dt = SecDecodeTransformCreate(etype, (CFErrorRef *)&err); - - SecTransformRef lineLengthChecker = (etype == kSecZLibEncoding) ? SecNullTransformCreate() : SecTransformCreate(lengthCheckName, NULL); - STAssertNotNil((id)lineLengthChecker, @"Expected to create line length checker"); - SecTransformSetAttribute(lineLengthChecker, CFSTR("MAX"), [NSNumber numberWithInt:maxLineLength], NULL); - - SecTransformConnectTransforms(et, kSecTransformOutputAttributeName, lineLengthChecker, kSecTransformInputAttributeName, group, (CFErrorRef *)&err); - SecTransformConnectTransforms(lineLengthChecker, kSecTransformOutputAttributeName, dt, kSecTransformInputAttributeName, group, (CFErrorRef *)&err); - - SecTransformSetAttribute(et, kSecTransformInputAttributeName, (CFDataRef)d, (CFErrorRef *)&err); - SecTransformSetAttribute(et, kSecEncodeLineLengthAttribute, lineLength, (CFErrorRef *)&err); - SecTransformSetAttribute(et, CFSTR("NAME"), (CFStringRef)testName, (CFErrorRef *)&err); - - dispatch_group_async(dg, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - CFDataRef result = (CFDataRef)SecTransformExecute(group, (CFErrorRef *)&err); - - STAssertNil(err, @"execute for %@ got %@", testName, err); - STAssertNotNil((id)result, @"No result from execute of %@", testName); - - if (result) { - STAssertEqualObjects(d, (id)result, @"test %@ failed", testName); - } - }); - }; - - for(int j = max_j; j > 70; --j) { - if (etype == kSecZLibEncoding && j != max_j) { - break; - } - trial([NSString stringWithFormat:@"%@-%d", etype, j], [NSNumber numberWithInt:j], j); - } - - if (etype != kSecZLibEncoding) { - trial([NSString stringWithFormat:@"%@-LL64", etype], (id)kSecLineLength64, 64); - trial([NSString stringWithFormat:@"%@-LL76", etype], (id)kSecLineLength76, 76); - } - } - - dispatch_group_wait(dg, DISPATCH_TIME_FOREVER); -} - --(void)testZLib { - SecTransformRef et = SecEncodeTransformCreate(kSecZLibEncoding, NULL); - SecTransformRef dt = SecDecodeTransformCreate(kSecZLibEncoding, NULL); - - // using a tee would require >10 buffered items (we need to buffer about 64K), so we pass share=NO - STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/web2a", et, dt, NO), @"Roundtrip /usr/share/dict/web2a"); - - CFRelease(et); - CFRelease(dt); - - /* - If we want this we need a 'new' custom transform that will get receive the ratio data and be able to - query that data. - - CFNumberRef r1 = (CFNumberRef)SecTransformGetAttribute(et, kSecCompressionRatio); - CFNumberRef r2 = (CFNumberRef)SecTransformGetAttribute(dt, kSecCompressionRatio); - - STAssertNotNil((NSNumber *)r1, @"encode ratio"); - STAssertNotNil((NSNumber *)r2, @"decode ratio"); - STAssertEqualObjects((NSNumber *)r1, (NSNumber *)r2, @"same ratios"); - */ -} - -static SecTransformInstanceBlock CycleCheckTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - int zero = 0; - __block CFNumberRef feedback = CFNumberCreate(NULL, kCFNumberIntType, &zero); - - SecTransformCustomSetAttribute(ref, CFSTR("FEEDBACK"), kSecTransformMetaAttributeCanCycle, kCFBooleanTrue); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (value == NULL) { - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, value); - return value; - } - if (feedback == NULL) { - SecTransformPushbackAttribute(ref, ah, value); - return (CFTypeRef)NULL; - } - - int x, y; - CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &x); - CFNumberGetValue(feedback, kCFNumberIntType, &y); - x ^= y; - CFNumberRef res = CFNumberCreate(NULL, kCFNumberIntType, &x); - SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, res); - CFRelease(res); - CFRelease(feedback); - feedback = NULL; - return (CFTypeRef)NULL; - }); - - SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("FEEDBACK"), - ^(SecTransformAttributeRef ah, CFTypeRef value) - { - if (value) { - if (feedback) { - SecTransformPushbackAttribute(ref, ah, value); - } else { - feedback = (CFNumberRef)CFRetain(value); - } - } - - return (CFTypeRef)NULL; - }); - - return result; - - }; - - return Block_copy(instanceBlock); -} - --(void)testCycleCheck { - - SecTransformRef cat = SecNullTransformCreate(); - SecTransformRef group = SecTransformCreateGroupTransform(); - CFErrorRef err = NULL; - - CFStringRef name = CFSTR("com.apple.examples.unit-test.loop-test"); - - SecTransformRegister(name, &CycleCheckTest, NULL); - - SecTransformRef twenty = count_transform(20); - - // this is getting an internal error, but it's being ignored. - SecTransformRef xxor = SecTransformCreate(name, &err); - - SecTransformConnectTransforms(xxor, CFSTR("OUTPUT"), cat, CFSTR("INPUT"), group, &err); - STAssertNil((id)err, @"xor->cat"); - SecTransformConnectTransforms(xxor, CFSTR("OUTPUT"), xxor, CFSTR("FEEDBACK"), group, &err); - STAssertNil((id)err, @"xor->xor"); - SecTransformConnectTransforms(twenty, CFSTR("OUTPUT"), xxor, CFSTR("INPUT"), group, &err); - STAssertNil((id)err, @"twenty->xor"); - - //SecTransformSetAttribute(xxor, CFSTR("DEBUG"), kCFBooleanTrue, &err); - - CFTypeRef r = SecTransformExecute(group, &err); - STAssertNil((id)err, @"execute err=%@", err); - STAssertNotNil((id)r, @"no results from execute"); - - if (r) { - CFNumberRef z = (CFNumberRef)[NSNumber numberWithInt:0]; - CFIndex n = CFArrayGetCountOfValue((CFArrayRef)r, CFRangeMake(0, CFArrayGetCount((CFArrayRef)r)), z); - // There should be six zeros in the xor->feedback chain from 0 to 19. - STAssertEquals(n, (CFIndex) 6, @"There should be six zeros in %@", r); - } - - CFRelease(r); - CFRelease(group); - CFRelease(twenty); - CFRelease(xxor); - CFRelease(cat); -} - --(void)testValidate { - SecTransformRef group = SecTransformCreateGroupTransform(); - CFErrorRef err = NULL; - - CFStringRef data_or_null_name = CFSTR("com.apple.examples.unit-test.data-or-null"); - SecTransformCreateBlock data_or_null = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) { - params->overrideAttribute(kSecTransformActionAttributeValidation, CFSTR("INPUT"), SecTransformCreateValidatorForCFtype(CFDataGetTypeID(), YES)); - }; - - - SecTransformRef makes_numbers = count_transform(20); - SecTransformRef wants_data = custom_transform(data_or_null_name, data_or_null); - - SecTransformConnectTransforms(makes_numbers, CFSTR("OUTPUT"), wants_data, CFSTR("INPUT"), group, NULL); - STAssertNil((id)err, @"unexpected connect error: %@", err); - CFTypeRef r = SecTransformExecute(group, &err); - STAssertNil((id)r, @"Got non-null result (%@) when expecting null!", r); - STAssertNotNil((id)err, @"Expected an error!", err); - STAssertErrorHas((id)err, @"/INPUT", @"Error indicated attribute that was set incorrectly"); - STAssertErrorHas((id)err, @" type CFNumber", @"Error indicated provided type"); - STAssertErrorHas((id)err, @" a CFData", @"Error indicated required type"); - - if (err) { - CFRelease(err); - } - err = NULL; - CFRelease(wants_data); - - wants_data = custom_transform(data_or_null_name, data_or_null); - - char raw_data[] = "`Twas brillig, and the slithy toves / Did gyre and gimble in the wabe: / All mimsy were the borogoves, / And the mome raths outgrabe."; - CFDataRef the_data = CFDataCreate(NULL, (UInt8*)raw_data, strlen(raw_data)); - SecTransformSetAttribute(wants_data, kSecTransformInputAttributeName, the_data, &err); - CFRelease(the_data); - - STAssertNil((id)err, @"unexpected set error: %@", err); - r = SecTransformExecute(wants_data, &err); - STAssertNotNil((id)r, @"Expected a result, got error: %@", err); - if (r) { - STAssertEqualObjects((id)the_data, (id)r, @"Invalid result"); - } - - CFStringRef numbers_only_name = CFSTR("com.apple.examples.unit-test.numbers-only"); - SecTransformCreateBlock numbers_only = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) { - params->overrideAttribute(kSecTransformActionAttributeValidation, CFSTR("INPUT"), SecTransformCreateValidatorForCFtype(CFNumberGetTypeID(), NO)); - }; - - CFRelease(group); - CFRelease(makes_numbers); - CFRelease(wants_data); - - group = SecTransformCreateGroupTransform(); - makes_numbers = count_transform(20); - SecTransformRef wants_numbers = custom_transform(numbers_only_name, numbers_only); - - SecTransformConnectTransforms(makes_numbers, CFSTR("OUTPUT"), wants_numbers, CFSTR("INPUT"), group, NULL); - STAssertNil((id)err, @"unexpected connect error: %@", err); - r = SecTransformExecute(group, &err); - CFfprintf(stderr, "r=%@; err=%@\n", r, err); - STAssertNil((id)r, @"Got non-null result (%@) when expecting null!", r); - STAssertNotNil((id)err, @"Expected an error!", err); - STAssertErrorHas((id)err, @"/INPUT", @"Error indicated attribute that was set incorrectly"); - STAssertErrorHas((id)err, @"received NULL value", @"Error indicated provided value is NULL"); - STAssertErrorHas((id)err, @" a CFNumber", @"Error indicated required type"); - - CFRelease(err); - CFRelease(group); - CFRelease(makes_numbers); - CFRelease(wants_numbers); -} - --(void)testCodeBase32 { - struct base32_test_vector { - const char *plain_text; - const char *base32_rfc4648; - const char *base32_fde; - }; - - // RFC 4648 test vectors - static base32_test_vector base32_test_vectors[] = { - {"", "", ""}, - {"f", "MY======", "MY======"}, - {"fo", "MZXQ====", "MZXQ===="}, - {"foo", "MZXW6===", "MZXW6==="}, - {"foob", "MZXW6YQ=", "MZXW6YQ="}, - {"fooba", "MZXW6YTB", "MZXW6YTB"}, - {"foobar", "MZXW6YTBOI======", "MZXW6YTBO8======"}}; - - void (^test)(NSString *test_name, SecTransformRef transform, const char *input, const char *expected_output, NSString *error_format) = - ^(NSString *test_name, SecTransformRef transform, const char *input, const char *expected_output, NSString *error_format) - { - if (!transform) { - STFail(@"No transform for %@", test_name); - return; - } - - CFErrorRef err = NULL; - NSData *input_data = [NSData dataWithBytes:input length:strlen(input)]; - NSData *expected_output_data = [NSData dataWithBytes:expected_output length:strlen(expected_output)]; - SecTransformSetAttribute(transform, kSecTransformInputAttributeName, input_data, &err); - STAssertNil((NSError *)err, @"unexpected error %@ from SecTransformSetAttribute for %@", err, test_name); - NSData *output_data = (NSData *)SecTransformExecute(transform, &err); - [output_data autorelease]; - STAssertNil((NSError *)err, @"Error from %@ execute (in=%s, err=%s)", test_name, input, err); - STAssertNotNil(output_data, @"Unexpected nil output from %@ execute (in=%s)", test_name, input); - if (output_data) { - NSString *output_string = [NSString alloc]; - output_string = [output_string initWithBytes:[output_data bytes] length:[output_data length] encoding:NSMacOSRomanStringEncoding]; - [output_string autorelease]; - NSString *msg = [NSString stringWithFormat:error_format, input, expected_output, output_string]; - STAssertEqualObjects(expected_output_data, output_data, @"%@ %@", test_name, msg); - } - CFRelease(transform); - }; - - for(int idx = 0; idx < sizeof(base32_test_vectors)/sizeof(*base32_test_vectors); idx++) - { - SecTransformRef base32encoder = SecEncodeTransformCreate(kSecBase32Encoding, NULL); - test(@"base32 encode", base32encoder, base32_test_vectors[idx].plain_text, base32_test_vectors[idx].base32_rfc4648, @"B32(\"%1$s\") should be \"%2$s\", got \"%3$@\""); - - SecTransformRef base32decoder = SecDecodeTransformCreate(kSecBase32Encoding, NULL); - test(@"base32 decode", base32decoder, base32_test_vectors[idx].base32_rfc4648, base32_test_vectors[idx].plain_text, @"B32dec(\"%1$s\") should be \"%2$s\", got \"%3$@\""); - - SecTransformRef base32FDEencoder = SecEncodeTransformCreate(CFSTR("base32FDE"), NULL); - test(@"base32FDE encode", base32FDEencoder, base32_test_vectors[idx].plain_text, base32_test_vectors[idx].base32_fde, @"B32(\"%1$s\") should be \"%2$s\", got \"%3$@\""); - - SecTransformRef base32FDEdecoder = SecDecodeTransformCreate(CFSTR("base32FDE"), NULL); - test(@"base32FDE decode", base32FDEdecoder, base32_test_vectors[idx].base32_fde, base32_test_vectors[idx].plain_text, @"B32dec(\"%1$s\") should be \"%2$s\", got \"%3$@\""); - } - - SecTransformRef bet = SecEncodeTransformCreate(kSecBase32Encoding, NULL); - STAssertNotNil((id)bet, @"got bulk base 32 encoder"); - SecTransformRef bdt = SecDecodeTransformCreate(kSecBase32Encoding, NULL); - STAssertNotNil((id)bdt, @"got bulk base 32 decoder"); - STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/words", bet, bdt, YES), @"Roundtrip base32 /usr/share/dict/words"); - - CFRelease(bet); - CFRelease(bdt); - - // FDE uses a modified base32 alphabet, we want to test it here. - SecTransformRef FDE_encode_transform = SecEncodeTransformCreate(@"base32FDE", NULL); - STAssertNotNil((id)FDE_encode_transform, @"got FDE encoder"); - SecTransformRef FDE_decode_transform = SecDecodeTransformCreate(@"base32FDE", NULL); - STAssertNotNil((id)FDE_decode_transform, @"got bulk base 32 decoder"); - STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/words", FDE_encode_transform, FDE_decode_transform, YES), @"Roundtrip base32FDE /usr/share/dict/words"); - - CFRelease(FDE_encode_transform); - CFRelease(FDE_decode_transform); -} - --(void)testCodeBase64 { - CFErrorRef error = NULL; - -#if 0 - SecTransformRef tr = SecDecodeTransformCreate(@"Not a real encoding", &error); - // XXX: known failure in Transform::SetAttribute 7707822 -- I would fix on this branch, but I think that code has diverged - STAssertTrue(tr == NULL, @"Checks for invalid encodings"); - NSLog(@"Error: %@", error); -#endif - - SecTransformRef dt = SecDecodeTransformCreate(kSecBase64Encoding, NULL); - STAssertNotNil((id)dt, @"Got decoder"); - - const char raw_data0[] = "Tm90IHV1ZW5jb2RlZAo="; - const char raw_data1[] = "Not uuencoded\n"; - CFDataRef data0 = CFDataCreate(NULL, (const UInt8*)raw_data0, strlen(raw_data0)); - CFDataRef data1 = CFDataCreate(NULL, (const UInt8*)raw_data1, strlen(raw_data1)); - SecTransformSetAttribute(dt, kSecTransformInputAttributeName, data0, NULL); - - CFDataRef decoded_data = (CFDataRef)SecTransformExecute(dt, &error); - STAssertNotNil((NSData *)decoded_data, @"Got a decode result"); - STAssertEqualObjects((NSData *)decoded_data, (NSData *)data1, @"Proper decode results"); - - SecTransformRef et = SecEncodeTransformCreate(kSecBase64Encoding, NULL); - STAssertNotNil((id)et, @"Got encoder"); - - SecTransformSetAttribute(et, kSecTransformInputAttributeName, data1, NULL); - - CFDataRef encoded_data = (CFDataRef)SecTransformExecute(et, NULL); - STAssertNotNil((NSData *)encoded_data, @"Got an encode result"); - - STAssertEqualObjects((NSData *)encoded_data, (NSData *)data0, @"Proper encode results"); - - // Negative testing, assume the following struct - // struct __CFData { - // CFRuntimeBase _base; - // CFIndex _length; /* number of bytes */ - // CFIndex _capacity; /* maximum number of bytes */ - // CFAllocatorRef _bytesDeallocator; /* used only for immutable; if NULL, no deallocation */ - // uint8_t *_bytes; /* compaction: direct access to _bytes is only valid when data is not inline */ - // }; - SecTransformRef et_neg = SecEncodeTransformCreate(kSecBase64Encoding, NULL); - STAssertNotNil((id)et_neg, @"Got encoder for negative testing"); - - CFIndex *data1_length=(CFIndex*)((unsigned char *)data1 + sizeof(CFRuntimeBase)); - CFIndex data1_backup=*data1_length; - if (sizeof(CFIndex)==8) - { - *data1_length=0x5ffffffffffffff7; - } - else if (sizeof(CFIndex)==4) - { - *data1_length=0x5ffffff7; - } - else - { - STAssertTrue(false, @"Test error, representation of CFIndex not supported. Sizeof(CFIndex)=%d. Only support 4 or 8",sizeof(CFIndex)); - } - STAssertTrue(CFDataGetLength(data1)==*data1_length, @"Length not properly set - test bug - reads %lu expect %lu",CFDataGetLength(data1),*data1_length); - SecTransformSetAttribute(et_neg, kSecTransformInputAttributeName, data1, NULL); - CFDataRef encoded_data2 = (CFDataRef)SecTransformExecute(et_neg, &error); - STAssertNil((id)encoded_data2, @"No encoded data for negative testing"); - STAssertNotNil((id)error, @"Got error for negative testing"); - *data1_length=data1_backup; - if (error!=NULL) - { - STAssertTrue((CFErrorGetCode(error)==kSecTransformErrorInvalidLength), - @"Error for invalid length, got %lu expect %lu",CFErrorGetCode(error),kSecTransformErrorInvalidLength); - } - // XXX also for general testing we want a "RandomChunkSizer" that copies INPUT to OUTPUT, but makes random size chunks (incl 0) as it goes. - - SecTransformRef dt2 = SecDecodeTransformCreate(kSecBase64Encoding, NULL); - SecTransformRef et2 = SecEncodeTransformCreate(kSecBase64Encoding, NULL); - int ll = 75; - SecTransformSetAttribute(et2, kSecEncodeLineLengthAttribute, CFNumberCreate(NULL, kCFNumberIntType, &ll), NULL); - - STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/words", et2, dt2, YES), @"Roundtrip base64 /usr/share/dict/words"); - - CFRelease(et2); - CFRelease(dt2); - CFRelease(et); - CFRelease(et_neg); - CFRelease(dt); -} - -static SecTransformInstanceBlock ErrorResultsTest(CFStringRef name, - SecTransformRef newTransform, - SecTransformImplementationRef ref) -{ - SecTransformInstanceBlock instanceBlock = - ^{ - CFErrorRef result = NULL; - SecTransformSetDataAction(ref, kSecTransformActionProcessData, - ^(CFTypeRef value) - { - if (value != NULL) - { - return (CFTypeRef)CFErrorCreate(NULL, CFSTR("expected error"), 42, NULL); - } - else - { - return SecTransformNoData(); - } - }); - - return result; - }; - - return Block_copy(instanceBlock); -} - - --(void)testErrorResults { - CFStringRef name = CFSTR("com.apple.security.unit-test.error-results"); - SecTransformRegister(name, &ErrorResultsTest, NULL); - - SecTransformRef tr = SecTransformCreate(name, NULL); - CFDataRef data = CFDataCreate(NULL, NULL, 0); - SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL); - - CFErrorRef err = NULL; - CFTypeRef no_result = SecTransformExecute(tr, &err); - - STAssertErrorHas((id)err, @"expected error", @"Signaled error has original string"); - STAssertErrorHas((id)err, @"42", @"Signaled error has original error code"); - STAssertNil((id)no_result, @"No result from erroring transform"); - CFRelease(data); - CFRelease(tr); - CFRelease(err); -} - --(void)testErrorExecutesInRightQueue { - // testExecuteBlock checks to see if blocks are generally executed on the proper queue, this specifically checks - // for an error while starting (which was originally improperly coded). - - SecTransformRef unassigned_input = SecNullTransformCreate(); - dispatch_queue_t q = dispatch_queue_create("com.apple.unit-test.ErrorExecutesInRightQueue", NULL); - dispatch_group_t got_final = dispatch_group_create(); - dispatch_group_enter(got_final); - __block bool saw_data = false; - __block bool saw_error = false; - - SecTransformExecuteAsync(unassigned_input, q, ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) { - STAssertEquals(q, const_cast(dispatch_get_current_queue()), @"Should be running on %p, but is running on %p", q, dispatch_get_current_queue()); - saw_data = saw_data || (message != NULL); - saw_error = saw_error || (error != NULL); - if (isFinal) { - dispatch_group_leave(got_final); - } - }); - - STAssertFalse(dispatch_group_wait(got_final, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"Execute completed"); - STAssertFalse(saw_data, @"Should have seen no data (but did)"); - STAssertTrue(saw_error, @"Should have seen error (but didn't)"); - - CFRelease(unassigned_input); - dispatch_group_notify(got_final, q, ^{ - dispatch_release(got_final); - dispatch_release(q); - }); - -} - --(void)testSignVerify { - unsigned char *raw_message = (unsigned char *)"Controlling complexity is the essence of computer programming. - Brian Kernigan"; - dispatch_group_t dg = dispatch_group_create(); - CFErrorRef err = NULL; - CFDataRef message = CFDataCreate(NULL, raw_message, strlen((const char *)raw_message)); - __block SecKeyRef rsa_pub_key = NULL; - __block SecKeyRef rsa_priv_key = NULL; - __block SecKeyRef ecdsa_pub_key = NULL; - __block SecKeyRef ecdsa_priv_key = NULL; - __block SecKeyRef dsa_pub_key = NULL; - __block SecKeyRef dsa_priv_key = NULL; - - char *tmp_dir; - asprintf(&tmp_dir, "%s/sign-verify-test-keychain-", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp"); - - unsigned char *raw_bad_message = (unsigned char *)"Standards are great, there are so many to choose from - Andrew S. Tanenbaum (maybe)"; - CFDataRef bad_message = CFDataCreate(NULL, raw_bad_message, strlen((const char *)raw_bad_message)); - - // when safe replace with a concurrent queue - dispatch_queue_t key_q = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - - dispatch_group_async(dg, key_q, - ^{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - - // (note the key must be bigger then a SHA2-256 signature plus the DER.1 packing of the OID, so 1024 was chosen for that, not speed or safety) - NSDictionary *key_opts = [NSDictionary dictionaryWithObjectsAndKeys: - (NSString *)kSecAttrKeyTypeRSA, (NSString *)kSecAttrKeyType, - [NSNumber numberWithInt:1024], (NSString *)kSecAttrKeySizeInBits, - @"RSA transform unit test key", (NSString *)kSecAttrLabel, - nil]; - OSStatus gp_status = SecKeyGeneratePair((CFDictionaryRef)key_opts, &rsa_pub_key, &rsa_priv_key); - STAssertTrue(gp_status == 0, @"RSA (gp_status=0x%x)", gp_status); - [pool drain]; - }); - - dispatch_group_async(dg, key_q, - ^{ - OSStatus gp_status; -#if 0 - // I don't know how "safe" a 512 bit ECDSA key is, but again this is just for testing, not for signing any real data - NSDictionary *key_opts = [NSDictionary dictionaryWithObjectsAndKeys: - (NSString *)kSecAttrKeyTypeECDSA, (NSString *)kSecAttrKeyType, - [NSNumber numberWithInt:512], (NSString *)kSecAttrKeySizeInBits, - @"ECDSA transform unit test key", (NSString *)kSecAttrLabel, - nil]; - gp_status = SecKeyGeneratePair((CFDictionaryRef)key_opts, &ecdsa_pub_key, &ecdsa_priv_key); -#else - { - SecKeychainRef tmp_keychain = NULL; - gp_status = SecKeyCreatePair(tmp_keychain, CSSM_ALGID_ECDSA, 256, NULL, - CSSM_KEYUSE_VERIFY, - CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT, - CSSM_KEYUSE_SIGN, - CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT, - NULL, &ecdsa_pub_key, &ecdsa_priv_key); - } -#endif - if (gp_status) - { - STAssertTrue(gp_status == 0, @"ECDSA (gp_status=0x%x)", gp_status); - } - }); - - dispatch_group_async(dg, key_q, - ^{ - OSStatus gp_status; -#if 0 - // I don't know how "safe" a 1024 bit DSA key is, but again this is just for testing, not for signing any real data - NSDictionary *key_opts = [NSDictionary dictionaryWithObjectsAndKeys:(NSString *)kSecAttrKeyTypeDSA, - (NSString *)kSecAttrKeyType, [NSNumber numberWithInt:512], (NSString *)kSecAttrKeySizeInBits, nil]; - gp_status = SecKeyGeneratePair((CFDictionaryRef)key_opts, &ecdsa_pub_key, &ecdsa_priv_key); -#else - { - const char *passwd = "this is not secret"; - SecKeychainRef tmp_keychain = NULL; - char *kcfname; - asprintf(&kcfname, "%s-DSA-XXXXXXXXXX", tmp_dir); - // NOTE: "mktemp" isn't as safe as you might think...but this is test code and doesn't have to be, but - // if you copy it elsewhere you may well need to rewrite it. (use mkstemp) - mktemp(kcfname); - gp_status = SecKeychainCreate(kcfname, (UInt32) strlen(passwd), passwd, NO, NULL, &tmp_keychain); - STAssertTrue(gp_status == 0, @"SecKeychainCreate (gp_status=0x%x)", gp_status); - gp_status = SecKeyCreatePair(tmp_keychain, CSSM_ALGID_DSA, 512, NULL, - CSSM_KEYUSE_VERIFY|CSSM_KEYUSE_ENCRYPT|CSSM_KEYUSE_WRAP, - CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_RETURN_REF, - CSSM_KEYUSE_SIGN|CSSM_KEYUSE_DECRYPT|CSSM_KEYUSE_UNWRAP, - CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_RETURN_REF, - NULL, &dsa_pub_key, &dsa_priv_key); - free(kcfname); - } -#endif - STAssertTrue(gp_status == 0, @"DSA (gp_status=0x%x)", gp_status); - }); - - struct sv_test { - NSString *name; - SecKeyRef pub_key, priv_key; - CFDataRef msg_sign, msg_verify; - CFTypeRef dalgo_sign, dalgo_verify; - int dlen_sign, dlen_verify; - BOOL pass; - }; - - dispatch_group_wait(dg, DISPATCH_TIME_FOREVER); - - struct sv_test sv_tests[] = - { - {@"Basic RSA", rsa_pub_key, rsa_priv_key, message, message, NULL, NULL, 0, 0, YES}, - {@"Basic RSA (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, NULL, NULL, 0, 0, NO}, - {@"RSA, mismatched digest algos", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA1, 0, 0, NO}, - - {@"RSA SHA1 MD5", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, YES}, - {@"RSA SHA1 MD5 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, NO}, - - {@"RSA MD5", rsa_pub_key, rsa_priv_key, message, message, kSecDigestMD5, kSecDigestMD5, 0, 0, YES}, - {@"RSA MD5 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestMD5, kSecDigestMD5, 0, 0, NO}, - - {@"RSA MD2", rsa_pub_key, rsa_priv_key, message, message, kSecDigestMD2, kSecDigestMD2, 0, 0, YES}, - {@"RSA MD2 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestMD2, kSecDigestMD2, 0, 0, NO}, - - {@"RSA SHA2 512", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, YES}, - {@"RSA SHA2 512 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, NO}, - {@"RSA SHA2 512 vs. 384", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 512, 384, NO}, - - {@"RSA SHA2 384", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, YES}, - {@"RSA SHA2 384 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, NO}, - - {@"RSA SHA2 256", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, YES}, - {@"RSA SHA2 256 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, NO}, - - {@"RSA SHA2 224", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, YES}, - {@"RSA SHA2 224 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, NO}, - - {@"RSA SHA2 0", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, YES}, - {@"RSA SHA2 0 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, NO}, - - {@"Basic ECDSA", ecdsa_pub_key, ecdsa_priv_key, message, message, NULL, NULL, 0, 0, YES}, - {@"Basic ECDSA (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, NULL, NULL, 0, 0, NO}, - {@"ECDSA (mismatched digest algos)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA1, 0, 0, NO}, - - {@"ECDSA SHA1", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, YES}, - {@"ECDSA SHA1 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, NO}, - - {@"ECDSA SHA2 224", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, YES}, - {@"ECDSA SHA2 224 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, NO}, - - {@"ECDSA SHA2 256", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, YES}, - {@"ECDSA SHA2 256 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, NO}, - - {@"ECDSA SHA2 384", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, YES}, - {@"ECDSA SHA2 384 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, NO}, - - {@"ECDSA SHA2 512", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, YES}, - {@"ECDSA SHA2 512 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, NO}, - - {@"ECDSA SHA2 0", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, YES}, - {@"ECDSA SHA2 0 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, NO}, - - {@"Basic DSA", dsa_pub_key, dsa_priv_key, message, message, NULL, NULL, 0, 0, YES}, - {@"Basic DSA (tampered data)", dsa_pub_key, dsa_priv_key, message, bad_message, NULL, NULL, 0, 0, NO}, - // only SHA1 is supported, so no mismatched digest algo test is available - - {@"DSA SHA1", dsa_pub_key, dsa_priv_key, message, message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, YES}, - {@"DSA SHA1 (tampered data)", dsa_pub_key, dsa_priv_key, message, bad_message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, NO}, - }; - - free(tmp_dir); - - int i; - for(i = 0; i < sizeof(sv_tests)/sizeof(sv_test); i++) - { - CFStringRef input_cases[] = {kSecInputIsPlainText, kSecInputIsDigest}; - //CFStringRef input_cases[] = {kSecInputIsPlainText, kSecInputIsDigest, kSecInputIsRaw}; - const int ilim = sizeof(input_cases)/sizeof(input_cases[0]); - int ii = 0, ij = 0; - for(; ii < ilim; ++ii) - { - for(ij = 0; ij < ilim; ++ij) - { - err = NULL; - struct sv_test *tst = sv_tests + i; - NSString *tname = [NSString stringWithFormat:@"%@ %@ %@", tst->name, input_cases[ii], input_cases[ij]]; - - CFStringRef sign_input_is = input_cases[ii]; - CFStringRef verify_input_is = input_cases[ij]; - - if (sign_input_is != kSecInputIsPlainText && tst->dalgo_sign == NULL) { - continue; - } - if (verify_input_is != kSecInputIsPlainText && tst->dalgo_verify == NULL) { - continue; - } - - if ((sign_input_is == kSecInputIsRaw || verify_input_is == kSecInputIsRaw) && [tst->name rangeOfString:@"RSA"].location == NSNotFound) { - // we can only synthesize these tests for RSA - NSLog(@"No %@ test", tname); - continue; - } - - STAssertNotNil((id)tst->pub_key, @"Have pub_key for %@", tname); - STAssertNotNil((id)tst->priv_key, @"Have priv_key for %@", tname); - - if (tst->pub_key == nil || tst->priv_key == nil) { - continue; - } - - SecTransformRef sign = SecSignTransformCreate(tst->priv_key, &err); - STAssertNil((NSError *)err, @"creating sign for %@", tname); - STAssertNotNil((id)sign, @"Creating sign for %@", tname); - - if (sign == NULL) { - continue; - } - - SecTransformRef verify = SecVerifyTransformCreate(tst->pub_key, NULL, &err); - STAssertNotNil((id)verify, @"Creating verify for %@", tname); - STAssertNil((NSError *)err, @"Creating verify for %@", tname); - - if (verify == NULL) { - continue; - } - - SecTransformRef sign_digest = NULL; - SecTransformRef verify_digest = NULL; - SecTransformRef sign2 = NULL; - - if (tst->dalgo_sign) - { - SecTransformSetAttribute(sign, kSecDigestTypeAttribute, tst->dalgo_sign, &err); - STAssertNil((NSError *)err, @"Setting sign's digest type for %@", tname); - SecTransformSetAttribute(sign, kSecDigestLengthAttribute, [NSNumber numberWithInt:tst->dlen_sign], &err); - STAssertNil((NSError *)err, @"Setting sign's digest length for %@", tname); - - if (sign_input_is == kSecInputIsDigest) - { - sign_digest = SecDigestTransformCreate(tst->dalgo_sign, tst->dlen_sign, &err); - STAssertNotNil((id)sign_digest, @"Create sign's %@-%d digest transform (for %@)", tst->dalgo_sign, tst->dlen_sign, tname); - STAssertNil((NSError *)err, @"Making sign's digester (for %@) - err=%@", tname, err); - - SecTransformSetAttribute(sign, kSecInputIsAttributeName, sign_input_is, &err); - STAssertNil((NSError *)err, @"Setting sign's InputIs (for %@) - err=%@", tname, err); - } - } - - if (tst->dalgo_verify) { - SecTransformSetAttribute(verify, kSecDigestTypeAttribute, tst->dalgo_verify, &err); - STAssertNil((NSError *)err, @"Setting verify's digest type for %@", tname); - SecTransformSetAttribute(verify, kSecDigestLengthAttribute, [NSNumber numberWithInt:tst->dlen_verify], &err); - STAssertNil((NSError *)err, @"Setting verify's digest length for %@", tname); - - if (verify_input_is == kSecInputIsDigest) { - verify_digest = SecDigestTransformCreate(tst->dalgo_verify, tst->dlen_verify, &err); - STAssertNotNil((id)verify_digest, @"Create verify's %@-%d digest transform (for %@)", tst->dalgo_verify, tst->dlen_verify, tname); - STAssertNil((NSError *)err, @"Making verify's digester (for %@) - err=%@", tname, err); - - SecTransformSetAttribute(verify, kSecInputIsAttributeName, verify_input_is, &err); - STAssertNil((NSError *)err, @"Setting verify's InputIs (for %@) - err=%@", tname, err); - } - } - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - SecTransformSetAttribute(sign_digest ? sign_digest : sign, kSecTransformInputAttributeName, tst->msg_sign, (CFErrorRef *)&err); - if (sign_digest) { - STAssertNil((NSError *)err, @"Setting sign's digest's input for %@", tname); - SecTransformConnectTransforms(sign_digest, kSecTransformOutputAttributeName, - sign, kSecTransformInputAttributeName, group, NULL); - } else { - STAssertNil((NSError *)err, @"Setting sign's input for %@", tname); - } - - - SecTransformSetAttribute(verify_digest ? verify_digest : verify, kSecTransformInputAttributeName, tst->msg_verify, (CFErrorRef *)&err); - if (verify_digest) { - STAssertNil((NSError *)err, @"Setting verify's digest's input for %@", tname); - SecTransformConnectTransforms(verify_digest, kSecTransformOutputAttributeName, - verify, kSecTransformInputAttributeName, group, NULL); - } else { - STAssertNil((NSError *)err, @"Setting verify's input for %@", tname); - } - - SecTransformConnectTransforms(sign2 ? sign2 : sign, kSecTransformOutputAttributeName, verify, kSecSignatureAttributeName, group, NULL); - - dispatch_group_enter(dg); - dispatch_queue_t temp_q = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); - SecTransformExecuteAsync(sign, temp_q, - ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) - { - if (message) - { - if (tst->pass) - { - STAssertTrue(message == kCFBooleanTrue, @"Failed to verify proper signature %@; message = %@", tname, message); - } else - { - STAssertTrue(message == kCFBooleanFalse, @"Failed to detect tampering %@; message = %@", tname, message); - } - } - - STAssertNil((NSError *)err, @"Executed ok for %@ (err=%@)", tname, error); - - if (isFinal) - { - dispatch_group_leave(dg); - } - }); - - CFRelease(sign); - CFRelease(verify); - CFRelease(group); - } - } - } - - struct raw_test { - SecKeyRef pub, priv; - NSString *name; - } raw_tests[] = { - {rsa_pub_key, rsa_priv_key, @"RSA raw test"}, - {dsa_pub_key, dsa_priv_key, @"DSA raw test"}, - {ecdsa_pub_key, ecdsa_priv_key, @"ECDSA raw test"}, - }; - - for(i = 0; i < sizeof(raw_tests)/sizeof(raw_tests[0]); ++i) { - raw_test *t = raw_tests + i; - SecTransformRef tee = SecNullTransformCreate(); - const char *raw_bytes = "some bytes"; - CFDataRef bytes = CFDataCreate(NULL, (UInt8*)raw_bytes, strlen(raw_bytes)); - CFErrorRef err = NULL; - - SecTransformRef sign = SecSignTransformCreate(t->priv, &err); - STAssertNil((id)err, @"%@ test sign create err=%@", t->name, err); - - SecTransformRef verify = SecVerifyTransformCreate(t->pub, NULL, &err); - STAssertNil((id)err, @"%@ test verify create err=%@", t->name, err); - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(sign, kSecTransformOutputAttributeName, verify, kSecSignatureAttributeName, group, &err); - SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, sign, kSecTransformInputAttributeName, group, &err); - SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, verify, kSecTransformInputAttributeName, group, &err); - SecTransformSetAttribute(tee, kSecTransformInputAttributeName, bytes, &err); - STAssertNil((id)err, @"%@ setup error=%@", t->name, err); - CFRetain(group); - dispatch_group_async(dg, dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - CFErrorRef xerr = NULL; - CFTypeRef result = SecTransformExecute(group, &xerr); - CFRelease(group); - - if (result) { - STAssertTrue(result == kCFBooleanTrue, @"%@ sign result=%@", t->name, result); - } else { - STFail(@"%@ no result", t->name); - } - STAssertNil((id)err, @"%@ execute error=%@", t->name, xerr); - }); - CFRelease(group); - } - - // Test some things we want to fail for: - - SecTransformRef tee = SecNullTransformCreate(); - SecTransformSetAttribute(tee, kSecTransformInputAttributeName, message, NULL); - SecTransformRef vrfy = SecVerifyTransformCreate(ecdsa_pub_key, NULL, NULL); - - SecGroupTransformRef group = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, vrfy, kSecSignatureAttributeName, group, NULL); - SecTransformSetAttribute(vrfy, kSecDigestTypeAttribute, CFSTR("No such type"), NULL); - SecTransformSetAttribute(vrfy, kSecTransformInputAttributeName, message, NULL); - err = NULL; - CFTypeRef no_result = SecTransformExecute(group, (CFErrorRef*)&err); - CFRelease(group); - - STAssertNil((id)no_result, @"No result from nonexistent digest"); - STAssertErrorHas((id)err, @"[Ii]nvalid digest algorithm", @"Error message describes nature of error (%@)", err); - STAssertErrorHas((id)err, @"ECDSA signature", @"Error is not overly general (%@)", err); - STAssertErrorHas((id)err, @"ECDSA signature", @"Error is not overly general (%@)", err); - STAssertErrorHas((id)err, @"SHA1.*SHA2", @"Error describes valid algorithms (%@)", err); - CFRelease(vrfy); - - // It would be awesome if we supported all the digests, and this test went away. - vrfy = SecVerifyTransformCreate(dsa_pub_key, message, NULL); - tee = SecNullTransformCreate(); - - group = SecTransformCreateGroupTransform(); - SecTransformConnectTransforms(vrfy, kSecSignatureAttributeName, tee, kSecTransformOutputAttributeName, group, NULL); - SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, vrfy, kSecTransformInputAttributeName, group, NULL); - SecTransformSetAttribute(vrfy, kSecDigestTypeAttribute, kSecDigestSHA2, NULL); - SecTransformSetAttribute(tee, kSecTransformInputAttributeName, message, NULL); - err = NULL; - no_result = SecTransformExecute(group, (CFErrorRef*)&err); - CFRelease(group); - - STAssertNil((id)no_result, @"No result from invalid digest"); - STAssertErrorHas((id)err, @"[Ii]nvalid digest algorithm", @"Error message gives problem statement (%@)", err); - STAssertErrorHas((id)err, @"[^A-Z]DSA signature", @"Error is not overly general (%@)", err); - STAssertErrorHas((id)err, @"SHA1", @"Correct algorithm is named (%@)", err); - - dispatch_group_wait(dg, DISPATCH_TIME_FOREVER); -} - -static BOOL keyWithBytes(CFDataRef keyData, SecKeyRef* key, CFTypeRef keyClass) { - CFErrorRef errorRef=NULL; - CFMutableDictionaryRef parameters; - parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 10, NULL, NULL); - - /* - kSecAttrKeyClass values: - kSecAttrKeyClassPublic - kSecAttrKeyClassPrivate - kSecAttrKeyClassSymmetric - */ - CFDictionaryAddValue(parameters, kSecAttrKeyClass, keyClass); - CFDictionaryAddValue(parameters, kSecAttrIsPermanent, kCFBooleanFalse); /* also means we have raw bits */ - CFDictionaryAddValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeRSA); /* also means we have raw bits */ - *key = SecKeyCreateFromData(parameters, keyData, &errorRef); - CFRelease(parameters); - return (key != NULL); -} - --(void)testVerifyWithKeyFromBytes { - /* - static const uint8_t original_pubKeyData[] = - { - 0x30, 0x48, 0x02, 0x41, 0x00, 0xd1, 0x4d, 0x1c, 0xe6, 0xbd, 0xd6, 0x8c, 0x4b, 0x77, 0x1e, 0x9f, - 0xbc, 0xe1, 0xf6, 0x96, 0xf2, 0x55, 0xa2, 0xdc, 0x28, 0x36, 0x39, 0xf4, 0xec, 0x5b, 0x85, 0x9b, - 0x3c, 0x7f, 0x98, 0xe0, 0xed, 0x49, 0xf5, 0x44, 0xb1, 0x87, 0xa8, 0xf6, 0x7f, 0x55, 0xc0, 0x39, - 0xf0, 0xe7, 0xcc, 0x9c, 0x84, 0xde, 0x7d, 0x9a, 0x87, 0x38, 0xf2, 0x4b, 0x11, 0x6f, 0x63, 0x90, - 0xfc, 0x72, 0x2c, 0x86, 0xa3, 0x02, 0x03, 0x01, 0x00, 0x01 - }; */ - - // openssl genrsa -out /tmp/rsa512.pem - // openssl rsa -inform PEM -in /tmp/rsa512.pem -outform DER -out /tmp/rsa512.der - // hexdump -C /tmp/rsa512.der | cut -c10-58 | tr -s ' ' ' ' | sed -e 's/ /, 0x/g' -e 's/$/,/' | cut -c3-|pbcopy - static const uint8_t pubKeyData[] = { - 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, - 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xbf, 0xd5, 0xce, 0x43, 0x59, 0xd5, 0xf8, - 0x41, 0xb2, 0xe1, 0x16, 0x02, 0x2a, 0x16, 0xcb, 0xef, 0x49, 0xea, 0x98, 0x71, 0xf8, 0xfb, 0x94, - 0x23, 0x12, 0xf7, 0xbc, 0x80, 0xd0, 0x8b, 0xfd, 0x29, 0xb8, 0xfc, 0x2c, 0x3d, 0x13, 0x6f, 0x37, - 0xef, 0xa7, 0x1e, 0xf9, 0x4c, 0x3d, 0x38, 0x3a, 0x2f, 0x6b, 0xa8, 0x16, 0x00, 0x27, 0x5a, 0xbe, - 0x3d, 0x61, 0xdd, 0x18, 0x45, 0x22, 0xdb, 0x1a, 0xff, 0x02, 0x03, 0x01, 0x00, 0x01, - }; - static const uint8_t signatureData[] = - { - 0xbc, 0x76, 0x2a, 0x50, 0x4e, 0x17, 0x0b, 0xa9, 0x31, 0x3b, 0xc5, 0xb0, 0x4d, 0x2a, 0x01, 0x9a, - 0xbb, 0x5e, 0x7b, 0x6e, 0x90, 0x2f, 0xaf, 0x3f, 0x40, 0xdb, 0xb0, 0xfc, 0x49, 0xcf, 0xbb, 0xb6, - 0x08, 0xf0, 0xbb, 0x04, 0x5f, 0x89, 0x0b, 0x10, 0x47, 0x06, 0x93, 0xb3, 0xb7, 0x0b, 0x4e, 0x17, - 0xe9, 0xb1, 0x55, 0x94, 0x63, 0x30, 0x0b, 0xa3, 0xb1, 0x28, 0xba, 0xe8, 0xef, 0xb4, 0xbd, 0xc5 - }; - - const char *raw_data = "Data to verify"; - CFDataRef data = CFDataCreate(NULL, (UInt8*) raw_data, strlen(raw_data)); - - SecKeyRef key; - CFDataRef cfkeybytes; - CFErrorRef error; - cfkeybytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pubKeyData, sizeof(pubKeyData),kCFAllocatorNull); - - if(keyWithBytes(cfkeybytes, &key, kSecAttrKeyClassPublic)){ - CFDataRef signature = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, signatureData, sizeof(signatureData),kCFAllocatorNull); - SecTransformRef vt = SecVerifyTransformCreate(key,signature,&error); - SecTransformSetAttribute(vt, kSecTransformDebugAttributeName, @"YES", NULL); - SecTransformSetAttribute(vt, kSecTransformInputAttributeName, data, &error); - CFBooleanRef signature_ok = (CFBooleanRef) SecTransformExecute(vt, &error); - - CFRelease(vt); - CFRelease(key); - CFRelease(signature); - CFRelease(data); - CFRelease(cfkeybytes); - - NSLog(@"STE result %@, err=%@", signature_ok, error); - STAssertNil((id)error, @"Error from SecTransformExecute: %@", error); - } else { - STFail(@"Can't get SecKeyCreateFromData to work"); - } -} - --(void)testAESAndCastKeysFromBytes { - CFErrorRef err = NULL; - struct tcase { - const char *name; - CFTypeRef key_type; - NSData *key_data; - }; - const char *aes_kbytes = "0123456789012345"; - const char *cast_kbytes = "01234567"; - - struct tcase cases[] = { - {"AES", kSecAttrKeyTypeAES, [NSData dataWithBytes:aes_kbytes length:strlen(aes_kbytes)]}, - {"CAST", kSecAttrKeyTypeCAST, [NSData dataWithBytes:cast_kbytes length:strlen(cast_kbytes)]}, - }; - - int i; - for(i = 0; i < sizeof(cases)/sizeof(cases[0]); ++i) { - NSDictionary *parm = [NSDictionary dictionaryWithObjectsAndKeys: - (id)kSecAttrKeyClassSymmetric, kSecAttrKeyClass, - (id)cases[i].key_type, kSecAttrKeyType, - (id)kCFBooleanFalse, kSecAttrIsPermanent, - NULL]; - - SecKeyRef k = SecKeyCreateFromData((CFDictionaryRef)parm, (CFDataRef)cases[i].key_data, (CFErrorRef *)&err); - STAssertNotNil((id)k, @"%s SecKeyCreateFromData didn't", cases[i].name); - STAssertNil((id)err, @"%s SecKeyCreateFromData err=%@", err); - - SecTransformRef et = SecEncryptTransformCreate(k, &err); - STAssertNotNil((id)et, @"No %s EncryptTransform created", cases[i].name); - STAssertNil((id)err, @"Error from %s SecEncryptTransformCreate err=%@", cases[i].name, err); - - SecTransformRef dt = SecDecryptTransformCreate(k, &err); - STAssertNotNil((id)dt, @"No %s DecryptTransform created", cases[i].name); - STAssertNil((id)err, @"Error from %s SecDecryptTransformCreate err=%@", cases[i].name, err); - - if (k) { - BOOL rt_ok = RoundTrip(CFSTR("/usr/share/dict/propernames"), et, dt, YES); - CFRelease(et); - CFRelease(dt); - STAssertTrue(rt_ok, @"%s's round trip", cases[i].name); - } - } -} - --(void)testDispatchAsumptions { - // Failures here don't directly indicate we have a bug. It would indicate that - // either dispatch has one, or that we rely on something dispatch never promised - // and has changed. - - dispatch_semaphore_t pre_sem = dispatch_semaphore_create(0); - dispatch_semaphore_t post_sem = dispatch_semaphore_create(0); - __block bool pre_wait_works = false; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ - STAssertTrue(0 == dispatch_semaphore_wait(pre_sem, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"semaphore signal prior to wait pre-wakes"); - pre_wait_works = true; - dispatch_semaphore_signal(post_sem); - }); - dispatch_semaphore_signal(pre_sem); - STAssertTrue(0 == dispatch_semaphore_wait(post_sem, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"signal after wait wakes"); - STAssertTrue(pre_wait_works, @"pre-wait worked"); - - -} - -// Build a group containing 3 subgroups, G1 which has 2 encoders, G2 and G3 which have one -// decoder each. Exports and attributes are hooked up so execution results in a CFData -// with the same contents as input_data. "self" is used by the STAssert macros. -// The various transforms are assigned names: G1, G2, G3, E64, EZLIB, DZLIB, D64. -static SecTransformRef build_nested_groups(id self, CFDataRef input_data) { - SecGroupTransformRef outer = SecTransformCreateGroupTransform(); - SecGroupTransformRef g1 = SecTransformCreateGroupTransform(); - SecGroupTransformRef g2 = SecTransformCreateGroupTransform(); - SecGroupTransformRef g3 = SecTransformCreateGroupTransform(); - - CFErrorRef err = NULL; - - SecTransformSetAttribute(outer, kSecTransformTransformName, CFSTR("OUTER"), &err); - STAssertNil((id)err, @"Can't set outer's name: %@", err); - SecTransformSetAttribute(g1, kSecTransformTransformName, CFSTR("G1"), &err); - STAssertNil((id)err, @"Can't set g1's name: %@", err); - SecTransformSetAttribute(g2, kSecTransformTransformName, CFSTR("G2"), &err); - STAssertNil((id)err, @"Can't set g2's name: %@", err); - SecTransformSetAttribute(g3, kSecTransformTransformName, CFSTR("G3"), &err); - STAssertNil((id)err, @"Can't set g3's name: %@", err); - - SecTransformRef e64 = SecEncodeTransformCreate(kSecBase64Encoding, &err); - STAssertNil((id)err, @"Expected err to be nil, got: %@", err); - STAssertNotNil((id)e64, @"Could not make Encode64 transform"); - SecTransformSetAttribute(e64, kSecTransformTransformName, CFSTR("E64"), NULL); - SecTransformRef ezlib = SecEncodeTransformCreate(kSecZLibEncoding, &err); - STAssertNil((id)err, @"Expected err to be nil, got: %@", err); - STAssertNotNil((id)ezlib, @"Could not make Encode ZLib transform"); - SecTransformSetAttribute(ezlib, kSecTransformTransformName, CFSTR("EZLIB"), NULL); - - SecTransformConnectTransforms(e64, kSecTransformOutputAttributeName, ezlib, kSecTransformInputAttributeName, g1, &err); - STAssertNil((id)err, @"Can't connect e64 to ezlib: %@", err); - SecTransformConnectTransforms(g1, kSecTransformInputAttributeName, e64, kSecTransformInputAttributeName, g1, &err); - STAssertNil((id)err, @"Can't connect g1's input to e64's input: %@", err); - SecTransformConnectTransforms(ezlib, kSecTransformOutputAttributeName, g1, kSecTransformOutputAttributeName, g1, &err); - STAssertNil((id)err, @"Can't connect ezlib's output to g1's output: %@", err); - - SecTransformRef dzlib = SecDecodeTransformCreate(kSecZLibEncoding, &err); - STAssertNil((id)err, @"Expected err to be nil, got: %@", err); - STAssertNotNil((id)dzlib, @"Could not make Decode ZLib transform"); - SecTransformSetAttribute(dzlib, kSecTransformTransformName, CFSTR("dzlib"), NULL); - SecTransformRef d64 = SecDecodeTransformCreate(kSecBase64Encoding, &err); - STAssertNil((id)err, @"Expected err to be nil, got: %@", err); - STAssertNotNil((id)d64, @"Could not make Decode64 transform"); - SecTransformSetAttribute(dzlib, kSecTransformTransformName, CFSTR("D64"), NULL); - - // putting just one transform in g2 and g3 - SecTransformConnectTransforms(g2, kSecTransformInputAttributeName, dzlib, kSecTransformInputAttributeName, g2, &err); - STAssertNil((id)err, @"Can't connect g2's input to dzlib's input: %@", err); - SecTransformConnectTransforms(dzlib, kSecTransformOutputAttributeName, g2, kSecTransformOutputAttributeName, g2, &err); - STAssertNil((id)err, @"Can't connect dzlib's output to g2's output: %@", err); - - SecTransformConnectTransforms(g3, kSecTransformInputAttributeName, d64, kSecTransformInputAttributeName, g3, &err); - STAssertNil((id)err, @"Can't connect g2's input to d64's input: %@", err); - SecTransformConnectTransforms(d64, kSecTransformOutputAttributeName, g3, kSecTransformOutputAttributeName, g3, &err); - STAssertNil((id)err, @"Can't connect d64's output to g2's output: %@", err); - - SecTransformConnectTransforms(g1, kSecTransformOutputAttributeName, g2, kSecTransformInputAttributeName, outer, &err); - STAssertNil((id)err, @"Can't connect g1 to g2 (dzlib): %@", err); - SecTransformConnectTransforms(g2, kSecTransformOutputAttributeName, g3, kSecTransformInputAttributeName, outer, &err); - STAssertNil((id)err, @"Can't connect g2 (dzlib) to g3 (d64): %@", err); - - SecTransformSetAttribute(g1, kSecTransformInputAttributeName, input_data, &err); - STAssertNil((id)err, @"Can't set g1's input: %@", err); - - - CFRelease(e64); - CFRelease(ezlib); - CFRelease(dzlib); - CFRelease(d64); - CFRelease(g1); - CFRelease(g2); - CFRelease(g3); - return outer; -} - --(void)testGroupsInGroups { - UInt8 original_bytes[] = "'Twas brillig and the...was that smiley toads? Something with chives? Aw heck!"; - CFDataRef original = CFDataCreate(NULL, original_bytes, sizeof(original_bytes)); - - // Test executing the top group, a sub group, and a non-group member. - for (NSString *name in [NSArray arrayWithObjects:@"OUTER", @"G1", @"D64", nil]) { - CFErrorRef err = NULL; - SecGroupTransformRef outer = build_nested_groups(self, original); - SecTransformRef start_at = SecTransformFindByName(outer, (CFStringRef)name); - STAssertNotNil((id)start_at, @"Expected to find %@", name); - - CFDataRef output = (CFDataRef)SecTransformExecute(start_at, &err); - STAssertNil((id)err, @"Can't execute directly created nested transform starting at %@: %@", start_at, err); - STAssertEqualObjects((id)output, (id)original, @"Output and original should match (started at %@)", start_at); - CFRelease(outer); - if (err) { - CFRelease(err); - } - } - - { - SecGroupTransformRef bad_outer = build_nested_groups(self, original); - SecTransformRef d64 = SecTransformFindByName(bad_outer, CFSTR("D64")); - STAssertNotNil((id)d64, @"Expected to find d64"); - CFErrorRef err = NULL; - // d64 is in a group in bad_outer, we set things up to fail - // and later expect execute to fail because of it. - SecTransformSetAttribute(d64, kSecDecodeTypeAttribute, CFSTR("NOT valid"), &err); - if (err) { - // It can fail right away - ErrorHas((NSError*)err, @"Unsupported decode type"); - } else { - // Or later (see below) - STAssertNil((id)err, @"Expected to set decode type: %@", err); - } - - SecTransformRef e64 = SecTransformFindByName(bad_outer, CFSTR("E64")); - STAssertNotNil((id)e64, @"Expected to find e64"); - CFStringRef any = CFSTR("ANY"); - // e64 and d64 aren't in the same groups, but they are in outer. - // There should be no way to (directly) connect them, so try all - // 4 groups and make sure none work. - for (NSString *group_name in [NSArray arrayWithObjects:@"OUTER", @"G1", @"G2", @"G3", nil]) { - SecTransformRef connect_in = SecTransformFindByName(bad_outer, (CFStringRef)group_name); - STAssertNotNil((id)connect_in, @"Expected to find %@", group_name); - err = NULL; - SecTransformConnectTransforms(d64, any, e64, any, bad_outer, &err); - STAssertNotNil((id)err, @"Expected error on cross group connect (in %@)", group_name); - if (err) { - STAssertEquals(CFErrorGetCode(err), (CFIndex)kSecTransformErrorInvalidConnection, @"error code (in %@)", group_name); - STAssertEqualObjects((id)CFErrorGetDomain(err), (id)kSecTransformErrorDomain, @"error domain (in %@)", group_name); - CFRelease(err); - err = NULL; - } - - // While we are here, make sure we can't set a non-exported group attribute - SecTransformSetAttribute((SecTransformRef)connect_in, CFSTR("nobody-exports-me"), CFSTR("VALUE"), &err); - STAssertNotNil((id)err, @"Expected an error setting a non-exported attribute on %@", connect_in); - // Make sure this is the error we expect, not something unrelated to our transgression - ErrorHas((NSError*)err, @"non-exported attribute"); - // Error should have the name of the offending attribute - ErrorHas((NSError*)err, @"nobody-exports-me"); - if (err) { - CFRelease(err); - err = NULL; - } - } - - CFTypeRef no_result = SecTransformExecute(bad_outer, &err); - STAssertNotNil((id)err, @"Expected error"); - ErrorHas((NSError*)err, @"Unsupported decode type"); - STAssertNil((id)no_result, @"Expected no result, got: %@", no_result); - CFRelease(bad_outer); - - // Make sure we can't connect to or from non-exported group attributes - bad_outer = build_nested_groups(self, original); - STAssertNotNil((id)bad_outer, @"Expected to build nested transform"); - SecTransformRef g1 = SecTransformFindByName(bad_outer, CFSTR("G1")); - STAssertNotNil((id)g1, @"Expected to find g1"); - SecTransformRef appendix = SecNullTransformCreate(); - SecTransformConnectTransforms(appendix, kSecTransformOutputAttributeName, g1, CFSTR("NONE"), bad_outer, &err); - STAssertNotNil((id)err, @"Expected to fail connecting appendix to g1, but didn't"); - ErrorHas((NSError*)err, @"non-exported attribute"); - if (err) { - CFRelease(err); - err = NULL; - } - SecTransformConnectTransforms(g1, CFSTR("DOES_NOT_EXIST"), appendix, kSecTransformInputAttributeName, bad_outer, &err); - STAssertNotNil((id)err, @"Expected to fail connecting g1 to appendix, but didn't"); - ErrorHas((NSError*)err, @"non-exported attribute"); - if (err) { - CFRelease(err); - err = NULL; - } - - CFRelease(bad_outer); - CFRelease(appendix); - } -} - -// 10080968 covers this case. It isn't a regression (it was impossible to create nested groups -// until recently), but it needs to be addressed before we ship. --(void)disabledUntilPR_10080968_testExternalizeGroupsInGroups { - CFErrorRef err = NULL; - UInt8 original_bytes[] = "Sic Semper Tyrannosaurus!"; - CFDataRef original = CFDataCreate(NULL, original_bytes, sizeof(original_bytes)); - - SecGroupTransformRef outer = build_nested_groups(self, original); - NSLog(@"outer=%@", SecTransformDotForDebugging(outer)); - SecTransformRef d64 = SecTransformFindByName(outer, CFSTR("D64")); - STAssertNotNil((id)d64, @"Expected to find d64"); - - CFDictionaryRef freezeDriedNestedGroups = SecTransformCopyExternalRepresentation(d64); - STAssertNotNil((id)freezeDriedNestedGroups, @"Expected to externalize group"); - - SecTransformRef outer2 = SecTransformCreateFromExternalRepresentation(freezeDriedNestedGroups, &err); - STAssertNil((id)err, @"Can't create nested group err: %@", err); - STAssertNotNil((id)outer2, @"Expected transform fron xrep: %@", freezeDriedNestedGroups); - NSLog(@"outer2=%@", SecTransformDotForDebugging(outer2)); - - CFTypeRef output2 = SecTransformExecute(outer2, &err); - STAssertNil((id)err, @"Can't execute outer2: %@", err); - STAssertEqualObjects((id)output2, (id)original, @"Output2 and original should match"); -} - -static NSString *CopyLeakLine() -{ - static char os_build[16]; - static dispatch_once_t get_os_build_once; - static BOOL broken_leaks_command = NO; - - dispatch_once(&get_os_build_once, ^{ - int mib[] = { CTL_KERN, KERN_OSVERSION }; - size_t bufsz = sizeof(os_build); - sysctl(mib, 2, os_build, &bufsz, NULL, 0); - - if (4 == sizeof(char*) && 0 == strcmp(os_build, "12A75")) { - // 12A75's leaks command was badly broken for 32 bit. - // Running it suspends otest, and it is too hard to - // recover. - broken_leaks_command = YES; - } - }); - - if (broken_leaks_command) { - return [NSString stringWithFormat:@"Leaks command is broken in %s", os_build]; - } - - NSRegularExpression *matchLeaksLine = [NSRegularExpression regularExpressionWithPattern:@"^Process \\d+: \\d+ leaks for \\d+ total leaked bytes.$" options:NSRegularExpressionAnchorsMatchLines error:NULL]; - - char *leak_command = NULL; - NSString *fname = [NSString stringWithFormat:@"/tmp/L%d-%d", getpid(), (int)arc4random()]; - asprintf(&leak_command, "(/usr/bin/leaks %d >%s || (echo OOPS; kill -CONT %d))", getpid(), [fname UTF8String], getpid()); - system(leak_command); - free(leak_command); - NSString *output = [NSString stringWithContentsOfFile:fname encoding:NSUTF8StringEncoding error:NULL]; - NSTextCheckingResult *result = [matchLeaksLine firstMatchInString:output options:0 range:NSMakeRange(0, [output length])]; - if (result.range.location == NSNotFound) { - return NULL; - } - NSRange matchRange = result.range; - return [output substringWithRange:matchRange]; -} - --(void)testAAASimpleLeakTest { - NSString *starting_leaks = CopyLeakLine(); - STAssertNotNil(starting_leaks, @"Found initial leaks"); - for(int i = 0; i < 10; i++) { - CFRelease(SecTransformCreateGroupTransform()); - } - - NSString *current_leaks = NULL; - - // Some of the destruction is async, so if they don't pan out the same, a little sleep and retry - // can legitimately fix it. - for(int i = 0; i < 10; i++) { - current_leaks = CopyLeakLine(); - if ([current_leaks isEqualToString:starting_leaks]) { - break; - } else { - sleep(1); - } - } - - STAssertNotNil(current_leaks, @"Found current leaks"); - STAssertEqualObjects(current_leaks, starting_leaks, @"Expected no new leaks"); -} - --(void)testAAASimpleishLeakTest { - NSLog(@"pid=%d", getpid()); - NSString *starting_leaks = CopyLeakLine(); - STAssertNotNil(starting_leaks, @"Found initial leaks"); - CFErrorRef err = NULL; - - // Derived from Matt Wright's 10242560 test.c - SecTransformRef b64encode = SecEncodeTransformCreate(kSecBase64Encoding, NULL); - const int buffer_size = 1024; - void *buffer = malloc(buffer_size); - STAssert(SecRandomCopyBytes(kSecRandomDefault, buffer_size, buffer) == noErr), @"Random failed"); - - CFDataRef data = CFDataCreateWithBytesNoCopy(NULL, (UInt8*)buffer, buffer_size, kCFAllocatorMalloc); - SecTransformSetAttribute(b64encode, kSecTransformInputAttributeName, data, &err); - STAssertNil((id)err, @"Expected no SecTransformSetAttribute error, got: %@", err); - CFRelease(data); - CFTypeRef output = SecTransformExecute(b64encode, &err); - STAssertNotNil((id)output, @"Expected result"); - STAssertNil((id)err, @"Expected no execute error, got: %@", err); - CFRelease(output); - CFRelease(b64encode); - - NSString *current_leaks = NULL; - - // Some of the destruction is async, so if they don't pan out the same, a little sleep and retry - // can legitimately fix it. - for(int i = 0; i < 10; i++) { - current_leaks = CopyLeakLine(); - if ([current_leaks isEqualToString:starting_leaks]) { - break; - } else { - sleep(1); - } - } - - STAssertNotNil(current_leaks, @"Found current leaks"); - STAssertEqualObjects(current_leaks, starting_leaks, @"Expected no new leaks"); -} - -@end diff --git a/OSX/libsecurity_utilities/lib/alloc.cpp b/OSX/libsecurity_utilities/lib/alloc.cpp index 313d187e..5d297087 100644 --- a/OSX/libsecurity_utilities/lib/alloc.cpp +++ b/OSX/libsecurity_utilities/lib/alloc.cpp @@ -137,8 +137,12 @@ void *SensitiveAllocator::realloc(void *addr, size_t newSize) throw(std::bad_all // void *CssmHeap::operator new (size_t size, Allocator *alloc) throw(std::bad_alloc) { - if (alloc == NULL) + if (size > SIZE_T_MAX / 2) { + throw std::bad_alloc(); + } + if (alloc == NULL) { alloc = &Allocator::standard(); + } size = alignUp(size, alignof_template()); size_t totalSize = size + sizeof(Allocator *); void *addr = alloc->malloc(totalSize); diff --git a/OSX/libsecurity_utilities/lib/cfmunge.cpp b/OSX/libsecurity_utilities/lib/cfmunge.cpp index 7c7bbf96..f26ccc72 100644 --- a/OSX/libsecurity_utilities/lib/cfmunge.cpp +++ b/OSX/libsecurity_utilities/lib/cfmunge.cpp @@ -93,7 +93,7 @@ bool CFMunge::parameter() // // The top constructor. // -CFTypeRef CFMake::make() +CFTypeRef CF_RETURNS_RETAINED CFMake::make() { while (next() == '@') parameter(); @@ -126,7 +126,7 @@ CFTypeRef CFMake::make() } -CFTypeRef CFMake::makeformat() +CFTypeRef CF_RETURNS_RETAINED CFMake::makeformat() { ++format; switch (*format++) { @@ -184,7 +184,7 @@ CFTypeRef CFMake::makenumber() // Embedded strings can either be alphanumeric (only), or delimited with single quotes ''. // No escapes are processed within such quotes. If you want arbitrary string values, use %s. // -CFTypeRef CFMake::makestring() +CFTypeRef CF_RETURNS_RETAINED CFMake::makestring() { const char *start, *end; if (*format == '\'') { @@ -208,7 +208,7 @@ CFTypeRef CFMake::makestring() // // Construct a CFDictionary // -CFTypeRef CFMake::makedictionary() +CFTypeRef CF_RETURNS_RETAINED CFMake::makedictionary() { ++format; // next '{' next('!'); // indicates mutable (currently always true) @@ -272,7 +272,7 @@ CFDictionaryRef CFMake::addto(CFMutableDictionaryRef dict) // // Construct a CFArray // -CFTypeRef CFMake::makearray() +CFTypeRef CF_RETURNS_RETAINED CFMake::makearray() { ++format; // next '[' next('!'); // indicates mutable (currently always) @@ -538,7 +538,7 @@ CFTypeRef CFScan::dictpath(CFTypeRef obj) // // The public functions // -CFTypeRef cfmake(const char *format, ...) +CFTypeRef CF_RETURNS_RETAINED cfmake(const char *format, ...) { va_list args; va_start(args, format); @@ -547,7 +547,7 @@ CFTypeRef cfmake(const char *format, ...) return result; } -CFTypeRef vcfmake(const char *format, va_list *args) +CFTypeRef CF_RETURNS_RETAINED vcfmake(const char *format, va_list *args) { return CFMake(format, args).make(); } diff --git a/OSX/libsecurity_utilities/lib/cfutilities.cpp b/OSX/libsecurity_utilities/lib/cfutilities.cpp index 0fc0f02f..26aa1d96 100644 --- a/OSX/libsecurity_utilities/lib/cfutilities.cpp +++ b/OSX/libsecurity_utilities/lib/cfutilities.cpp @@ -430,7 +430,7 @@ CFDataRef cfMapFile(CFURLRef url) { } CFDataRef cfLoadFile(CFURLRef url){ -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR return cfMapFile(url); #else return cfReadFile(url); @@ -438,7 +438,7 @@ CFDataRef cfLoadFile(CFURLRef url){ } CFDataRef cfLoadFile(int fd, size_t bytes){ -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR return cfMapFile(fd, bytes); #else return cfReadFile(fd, bytes); diff --git a/OSX/libsecurity_utilities/lib/devrandom.cpp b/OSX/libsecurity_utilities/lib/devrandom.cpp deleted file mode 100644 index 626ed7ef..00000000 --- a/OSX/libsecurity_utilities/lib/devrandom.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2000-2004,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@ - */ - - -// -// devrandom - RNG operations based on /dev/random -// -#include -#include -#include - -using namespace UnixPlusPlus; - - -namespace Security { - - -// -// The common (shared) open file descriptor to /dev/random -// -ModuleNexus DevRandomGenerator::mWriter; - - -// -// In the current implementation, opening the file descriptor is deferred. -// -DevRandomGenerator::DevRandomGenerator(bool writable) -{ -} - - -// -// Standard generate (directly from /dev/random) -// -void DevRandomGenerator::random(void *data, size_t length) -{ - if (CCRandomCopyBytes(kCCRandomDefault, data, length)) { - Syslog::error("DevRandomGenerator: failed to generate random"); - UnixError::throwMe(EIO); - } -} - - -// -// If you opened for writing, you add entropy to the global pool here -// -void DevRandomGenerator::addEntropy(const void *data, size_t length) -{ - if (mWriter().write(data, length) != length) - UnixError::throwMe(EIO); // short write (shouldn't happen) -} - - -} // end namespace Security diff --git a/OSX/libsecurity_utilities/lib/devrandom.h b/OSX/libsecurity_utilities/lib/devrandom.h deleted file mode 100644 index a2bf448a..00000000 --- a/OSX/libsecurity_utilities/lib/devrandom.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2000-2004,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@ - */ - - -// -// devrandom - RNG operations based on /dev/random -// -#ifndef _H_DEVRANDOM -#define _H_DEVRANDOM - -#include -#include -#include - - -namespace Security { - - -// -// This RNG doesn't use /dev/random for reading, it uses CommonCrypto -// (same as SecRandom does). It is not repeatable. -// -// AddEntropy() contributes random entropy to a global pool (only). -// -class DevRandomGenerator { - struct Writable : public UnixPlusPlus::FileDesc { - Writable() { open("/dev/random", O_RDWR); } - }; - -public: - DevRandomGenerator(bool writable = false); - - void random(void *data, size_t length); - void addEntropy(const void *data, size_t length); - -private: - static ModuleNexus mWriter; -}; - - -}; // end namespace Security - - -#endif //_H_DEVRANDOM diff --git a/OSX/libsecurity_utilities/lib/mach_notify.c b/OSX/libsecurity_utilities/lib/mach_notify.c deleted file mode 100644 index a580313b..00000000 --- a/OSX/libsecurity_utilities/lib/mach_notify.c +++ /dev/null @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2001-2002,2004,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@ - */ -/* - * IDENTIFICATION: - * stub generated Fri Mar 1 18:02:22 2002 - * with a MiG generated Thu Feb 21 15:16:47 PST 2002 by root@blur - * OPTIONS: - */ - -/* Module notify */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef mig_internal -#define mig_internal static -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#ifndef TypeCheck -#define TypeCheck 0 -#endif /* TypeCheck */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 1 -#endif /* UseStaticTemplates */ - -#define _WALIGN_(x) (((x) + 3) & ~3) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#ifndef __DeclareRcvRpc -#define __DeclareRcvRpc(_NUM_, _NAME_) -#endif /* __DeclareRcvRpc */ - -#ifndef __BeforeRcvRpc -#define __BeforeRcvRpc(_NUM_, _NAME_) -#endif /* __BeforeRcvRpc */ - -#ifndef __AfterRcvRpc -#define __AfterRcvRpc(_NUM_, _NAME_) -#endif /* __AfterRcvRpc */ - -#ifndef __DeclareRcvSimple -#define __DeclareRcvSimple(_NUM_, _NAME_) -#endif /* __DeclareRcvSimple */ - -#ifndef __BeforeRcvSimple -#define __BeforeRcvSimple(_NUM_, _NAME_) -#endif /* __BeforeRcvSimple */ - -#ifndef __AfterRcvSimple -#define __AfterRcvSimple(_NUM_, _NAME_) -#endif /* __AfterRcvSimple */ - -#define novalue void - -#define msgh_request_port msgh_local_port -#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) -#define msgh_reply_port msgh_remote_port -#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) - -#define MIG_RETURN_ERROR(X, code) {\ - ((mig_reply_error_t *)X)->RetCode = code;\ - ((mig_reply_error_t *)X)->NDR = NDR_record;\ - return;\ - } - -/* typedefs for all requests */ - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_port_name_t name; - } __Request__mach_notify_port_deleted_t; - - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t rights; - /* end of the kernel processed data */ - } __Request__mach_notify_port_destroyed_t; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_port_mscount_t mscount; - } __Request__mach_notify_no_senders_t; - - typedef struct { - mach_msg_header_t Head; - } __Request__mach_notify_send_once_t; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_port_name_t name; - } __Request__mach_notify_dead_name_t; - - -/* typedefs for all replies */ - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_notify_port_deleted_t; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_notify_port_destroyed_t; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_notify_no_senders_t; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_notify_send_once_t; - - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_notify_dead_name_t; - - -/* Forward Declarations */ - - -mig_internal novalue _Xmach_notify_port_deleted - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_notify_port_destroyed - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_notify_no_senders - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_notify_send_once - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_notify_dead_name - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - - -/* SimpleRoutine mach_notify_port_deleted */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_port_deleted -( - mach_port_t notify, - mach_port_name_t name -); - -/* SimpleRoutine mach_notify_port_deleted */ -mig_internal novalue _Xmach_notify_port_deleted - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_port_name_t name; - mach_msg_trailer_t trailer; - } Request; - -#if TypeCheck - typedef __Request__mach_notify_port_deleted_t __Request; -#endif - - typedef __Reply__mach_notify_port_deleted_t Reply; - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register Request *In0P = (Request *) InHeadP; - register Reply *OutP = (Reply *) OutHeadP; - __DeclareRcvSimple(65, "mach_notify_port_deleted") - __BeforeRcvSimple(65, "mach_notify_port_deleted") -#if TypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != sizeof(__Request))) - { MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); } -#endif /* TypeCheck */ - - OutP->RetCode = cdsa_mach_notify_port_deleted(In0P->Head.msgh_request_port, In0P->name); - __AfterRcvSimple(65, "mach_notify_port_deleted") -} - -/* SimpleRoutine mach_notify_port_destroyed */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_port_destroyed -( - mach_port_t notify, - mach_port_t rights -); - -/* SimpleRoutine mach_notify_port_destroyed */ -mig_internal novalue _Xmach_notify_port_destroyed - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t rights; - /* end of the kernel processed data */ - mach_msg_trailer_t trailer; - } Request; - -#if TypeCheck - typedef __Request__mach_notify_port_destroyed_t __Request; -#endif - - typedef __Reply__mach_notify_port_destroyed_t Reply; - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register Request *In0P = (Request *) InHeadP; - register Reply *OutP = (Reply *) OutHeadP; - __DeclareRcvSimple(69, "mach_notify_port_destroyed") - __BeforeRcvSimple(69, "mach_notify_port_destroyed") -#if TypeCheck - if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->msgh_body.msgh_descriptor_count != 1) || - (In0P->Head.msgh_size != sizeof(__Request))) - { MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); } -#endif /* TypeCheck */ - -#if TypeCheck - if (In0P->rights.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->rights.disposition != MACH_MSG_TYPE_MOVE_RECEIVE) - { MIG_RETURN_ERROR(OutP, MIG_TYPE_ERROR); } -#endif /* TypeCheck */ - - OutP->RetCode = cdsa_mach_notify_port_destroyed(In0P->Head.msgh_request_port, In0P->rights.name); - __AfterRcvSimple(69, "mach_notify_port_destroyed") -} - -/* SimpleRoutine mach_notify_no_senders */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_no_senders -( - mach_port_t notify, - mach_port_mscount_t mscount -); - -/* SimpleRoutine mach_notify_no_senders */ -mig_internal novalue _Xmach_notify_no_senders - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_port_mscount_t mscount; - mach_msg_trailer_t trailer; - } Request; - -#if TypeCheck - typedef __Request__mach_notify_no_senders_t __Request; -#endif - - typedef __Reply__mach_notify_no_senders_t Reply; - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register Request *In0P = (Request *) InHeadP; - register Reply *OutP = (Reply *) OutHeadP; - __DeclareRcvSimple(70, "mach_notify_no_senders") - __BeforeRcvSimple(70, "mach_notify_no_senders") -#if TypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != sizeof(__Request))) - { MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); } -#endif /* TypeCheck */ - - OutP->RetCode = cdsa_mach_notify_no_senders(In0P->Head.msgh_request_port, In0P->mscount); - __AfterRcvSimple(70, "mach_notify_no_senders") -} - -/* SimpleRoutine mach_notify_send_once */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_send_once -( - mach_port_t notify -); - -/* SimpleRoutine mach_notify_send_once */ -mig_internal novalue _Xmach_notify_send_once - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - typedef struct { - mach_msg_header_t Head; - mach_msg_trailer_t trailer; - } Request; - -#if TypeCheck - typedef __Request__mach_notify_send_once_t __Request; -#endif - - typedef __Reply__mach_notify_send_once_t Reply; - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register Request *In0P = (Request *) InHeadP; - register Reply *OutP = (Reply *) OutHeadP; - __DeclareRcvSimple(71, "mach_notify_send_once") - __BeforeRcvSimple(71, "mach_notify_send_once") -#if TypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != sizeof(__Request))) - { MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); } -#endif /* TypeCheck */ - - OutP->RetCode = cdsa_mach_notify_send_once(In0P->Head.msgh_request_port); - __AfterRcvSimple(71, "mach_notify_send_once") -} - -/* SimpleRoutine mach_notify_dead_name */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_dead_name -( - mach_port_t notify, - mach_port_name_t name -); - -/* SimpleRoutine mach_notify_dead_name */ -mig_internal novalue _Xmach_notify_dead_name - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_port_name_t name; - mach_msg_trailer_t trailer; - } Request; - -#if TypeCheck - typedef __Request__mach_notify_dead_name_t __Request; -#endif - - typedef __Reply__mach_notify_dead_name_t Reply; - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register Request *In0P = (Request *) InHeadP; - register Reply *OutP = (Reply *) OutHeadP; - __DeclareRcvSimple(72, "mach_notify_dead_name") - __BeforeRcvSimple(72, "mach_notify_dead_name") -#if TypeCheck - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->Head.msgh_size != sizeof(__Request))) - { MIG_RETURN_ERROR(OutP, MIG_BAD_ARGUMENTS); } -#endif /* TypeCheck */ - - OutP->RetCode = cdsa_mach_notify_dead_name(In0P->Head.msgh_request_port, In0P->name); - __AfterRcvSimple(72, "mach_notify_dead_name") -} - -/* union of all requests */ - -union __RequestUnion__cdsa_notify_subsystem { - __Request__mach_notify_port_deleted_t Request_mach_notify_port_deleted; - __Request__mach_notify_port_destroyed_t Request_mach_notify_port_destroyed; - __Request__mach_notify_no_senders_t Request_mach_notify_no_senders; - __Request__mach_notify_send_once_t Request_mach_notify_send_once; - __Request__mach_notify_dead_name_t Request_mach_notify_dead_name; -}; - -/* union of all replies */ - -union __ReplyUnion__cdsa_notify_subsystem { - __Reply__mach_notify_port_deleted_t Reply_mach_notify_port_deleted; - __Reply__mach_notify_port_destroyed_t Reply_mach_notify_port_destroyed; - __Reply__mach_notify_no_senders_t Reply_mach_notify_no_senders; - __Reply__mach_notify_send_once_t Reply_mach_notify_send_once; - __Reply__mach_notify_dead_name_t Reply_mach_notify_dead_name; -}; - - -extern boolean_t cdsa_notify_server( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP); - -extern mig_routine_t notify_server_routine( - mach_msg_header_t *InHeadP); - - -/* Description of this subsystem, for use in direct RPC */ -const struct cdsa_notify_subsystem { - mig_server_routine_t server; /* Server routine */ - mach_msg_id_t start; /* Min routine number */ - mach_msg_id_t end; /* Max routine number + 1 */ - unsigned int maxsize; /* Max msg size */ - vm_address_t reserved; /* Reserved */ - struct routine_descriptor /*Array of routine descriptors */ - routine[9]; -} cdsa_notify_subsystem = { - notify_server_routine, - 64, - 73, - sizeof(union __ReplyUnion__cdsa_notify_subsystem), - (vm_address_t)0, - { - {0, 0, 0, 0, 0, 0}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_notify_port_deleted, 2, 0, (routine_arg_descriptor_t)0, sizeof(__Reply__mach_notify_port_deleted_t)}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - {0, 0, 0, 0, 0, 0}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_notify_port_destroyed, 2, 0, (routine_arg_descriptor_t)0, sizeof(__Reply__mach_notify_port_destroyed_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_notify_no_senders, 2, 0, (routine_arg_descriptor_t)0, sizeof(__Reply__mach_notify_no_senders_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_notify_send_once, 1, 0, (routine_arg_descriptor_t)0, sizeof(__Reply__mach_notify_send_once_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_notify_dead_name, 2, 0, (routine_arg_descriptor_t)0, sizeof(__Reply__mach_notify_dead_name_t)}, - } -}; - -mig_external boolean_t cdsa_notify_server - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register mig_routine_t routine; - - OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); - OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; - /* Minimal size: routine() will update it if different */ - OutHeadP->msgh_size = sizeof(mig_reply_error_t); - OutHeadP->msgh_local_port = MACH_PORT_NULL; - OutHeadP->msgh_id = InHeadP->msgh_id + 100; - - if ((InHeadP->msgh_id > 72) || (InHeadP->msgh_id < 64) || - ((routine = cdsa_notify_subsystem.routine[InHeadP->msgh_id - 64].stub_routine) == 0)) { - ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; - ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; - return FALSE; - } - (*routine) (InHeadP, OutHeadP); - return TRUE; -} - -mig_external mig_routine_t notify_server_routine - (mach_msg_header_t *InHeadP) -{ - register int msgh_id; - - msgh_id = InHeadP->msgh_id - 64; - - if ((msgh_id > 8) || (msgh_id < 0)) - return 0; - - return cdsa_notify_subsystem.routine[msgh_id].stub_routine; -} diff --git a/OSX/libsecurity_utilities/lib/mach_notify.defs b/OSX/libsecurity_utilities/lib/mach_notify.defs new file mode 100644 index 00000000..eebac4ca --- /dev/null +++ b/OSX/libsecurity_utilities/lib/mach_notify.defs @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +subsystem + notify 64; + +#include + +serverprefix cdsa_; +serverdemux cdsa_notify_server; + +/* MACH_NOTIFY_FIRST: 0100 */ +skip; + +/* MACH_NOTIFY_PORT_DELETED: 0101 */ +simpleroutine mach_notify_port_deleted( + notify : mach_port_move_send_once_t; + name : mach_port_name_t); + +skip; + +skip; /* was NOTIFY_OWNERSHIP_RIGHTS: 0103 */ + +skip; /* was NOTIFY_RECEIVE_RIGHTS: 0104 */ + +/* MACH_NOTIFY_PORT_DESTROYED: 0105 */ +simpleroutine mach_notify_port_destroyed( + notify : mach_port_move_send_once_t; + rights : mach_port_move_receive_t); + +/* MACH_NOTIFY_NO_SENDERS: 0106 */ +simpleroutine mach_notify_no_senders( + notify : mach_port_move_send_once_t; + mscount : mach_port_mscount_t); + +/* MACH_NOTIFY_SEND_ONCE: 0107 */ +simpleroutine mach_notify_send_once( + notify : mach_port_move_send_once_t + ); + +/* MACH_NOTIFY_DEAD_NAME: 0110 */ +simpleroutine mach_notify_dead_name( + notify : mach_port_move_send_once_t; + name : mach_port_name_t); + +/* vim: set ft=c : */ diff --git a/OSX/libsecurity_utilities/lib/mach_notify.h b/OSX/libsecurity_utilities/lib/mach_notify.h deleted file mode 100644 index fef3bf90..00000000 --- a/OSX/libsecurity_utilities/lib/mach_notify.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2000-2001,2004,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@ - */ - - -#ifndef _notify_user_ -#define _notify_user_ - -/* Module notify */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef notify_MSG_COUNT -#define notify_MSG_COUNT 9 -#endif /* notify_MSG_COUNT */ - -#include -#include - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include -__BEGIN_DECLS - - -/* SimpleRoutine mach_notify_port_deleted */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_port_deleted -( - mach_port_t notify, - mach_port_name_t name -); - -/* SimpleRoutine mach_notify_port_destroyed */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_port_destroyed -( - mach_port_t notify, - mach_port_t rights -); - -/* SimpleRoutine mach_notify_no_senders */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_no_senders -( - mach_port_t notify, - mach_port_mscount_t mscount -); - -/* SimpleRoutine mach_notify_send_once */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t cdsa_mach_notify_send_once -( - mach_port_t notify -); - -/* SimpleRoutine mach_notify_dead_name */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -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 },\ - { "mach_notify_port_destroyed", 69 },\ - { "mach_notify_no_senders", 70 },\ - { "mach_notify_send_once", 71 },\ - { "mach_notify_dead_name", 72 } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - -#endif /* _notify_user_ */ diff --git a/OSX/libsecurity_utilities/lib/machrunloopserver.cpp b/OSX/libsecurity_utilities/lib/machrunloopserver.cpp deleted file mode 100644 index f6ef5ac5..00000000 --- a/OSX/libsecurity_utilities/lib/machrunloopserver.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2000-2004,2011-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@ - */ - - -// -// machrunloopserver - C++ shell for writing Mach 3 servers called by CFRunLoop -// -#include "machrunloopserver.h" -#include -#include -#include - - -namespace Security { -namespace MachPlusPlus { - - -// -// Generic Mach server -// -MachRunLoopServer::MachRunLoopServer(const char *name) - : MachServer(name), CFAutoPort(primaryServicePort()) -{ -} - -MachRunLoopServer::MachRunLoopServer(const char *name, const Bootstrap &boot) - : MachServer(name, boot), CFAutoPort(primaryServicePort()) -{ -} - -void MachRunLoopServer::run(mach_msg_size_t bufferSize, mach_msg_options_t options) -{ - // allocate reply buffer - mReplyMessage.setBuffer(bufferSize); - - // enable reception - CFAutoPort::enable(); - - // we are it! - perThread().server = this; -} - - -MachRunLoopServer::~MachRunLoopServer() -{ - // no longer active on this thread - perThread().server = NULL; -} - - -// -// Handle dead-port notifications. -// Since we don't actually run our own runloop here, we can't well use standard -// notifications to our own server port. So we use a CFMachPort facility instead. -// -void MachRunLoopServer::notifyIfDead(Port port, bool doNotify) const -{ - if (CFMachPortRef cfPort = CFMachPortCreateWithPort(NULL, port, NULL, NULL, NULL)) - CFMachPortSetInvalidationCallBack(cfPort, cfInvalidate); -} - -void MachRunLoopServer::cfInvalidate(CFMachPortRef cfPort, void *context) -{ - reinterpret_cast(context)->notifyDeadName(CFMachPortGetPort(cfPort)); - //@@@ should we CFRelease cfPort here? -} - - -// -// Reception callback -// -void MachRunLoopServer::receive(const Message &request) -{ - active().oneRequest(request); -} - -void MachRunLoopServer::oneRequest(const Message &request) -{ - if (!handle(request, mReplyMessage)) { // MIG dispatch failed - secinfo("machrls", "MachRunLoopServer dispatch failed"); - } else { - // MIG dispatch handled the call. Send reply back to caller. - mReplyMessage.send((MACH_MSGH_BITS_REMOTE(mReplyMessage.bits()) == MACH_MSG_TYPE_MOVE_SEND_ONCE) ? - MACH_SEND_MSG : MACH_SEND_MSG|MACH_SEND_TIMEOUT); - } - active().releaseDeferredAllocations(); -} - - -} // end namespace MachPlusPlus -} // end namespace Security diff --git a/OSX/libsecurity_utilities/lib/machrunloopserver.h b/OSX/libsecurity_utilities/lib/machrunloopserver.h deleted file mode 100644 index c5df09e9..00000000 --- a/OSX/libsecurity_utilities/lib/machrunloopserver.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2000-2001,2003-2004,2011-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@ - */ - - -// -// machrunloopserver - C++ shell for writing Mach 3 servers called by CFRunLoop. -// -// Note that this is a subclass of MachServer and tries to preserve its interface, -// so you can switch back-and-forth between them with a minimum of fuss. -// Timers are not currently implemented; they're not that hard to add if you need them. -// -#ifndef _H_MACHRUNLOOPSERVER -#define _H_MACHRUNLOOPSERVER - -#include -#include -#include -#include - - -namespace Security { -namespace MachPlusPlus { - - -// -// A Mach server object variant for use with CFRunLoops -// -// This currently only supports a subset of full MachServer functionality. -// -class MachRunLoopServer : public MachServer, private CFAutoPort { -public: - MachRunLoopServer(); // anonymous - MachRunLoopServer(const char *name); // register by name - MachRunLoopServer(const char *name, const Bootstrap &boot); // register in bootstrap - virtual ~MachRunLoopServer(); - - void run(mach_msg_size_t maxSize = 4096, mach_msg_options_t options = 0); - - static MachRunLoopServer &active() - { return safer_cast(MachServer::active()); } - - void notifyIfDead(Port port, bool doNotify = true) const; - -protected: - void receive(const Message &request); - void oneRequest(const Message &request); - -private: - static void cfInvalidate(CFMachPortRef port, void *info); - -private: - Message mReplyMessage; -}; - - -} // end namespace MachPlusPlus - -} // end namespace Security - -#endif //_H_MACHRUNLOOPSERVER diff --git a/OSX/libsecurity_utilities/lib/machserver.cpp b/OSX/libsecurity_utilities/lib/machserver.cpp index 30408289..4fca0b64 100644 --- a/OSX/libsecurity_utilities/lib/machserver.cpp +++ b/OSX/libsecurity_utilities/lib/machserver.cpp @@ -30,7 +30,7 @@ #include #include #include -#include "mach_notify.h" +#include "mach_notifyServer.h" #include #include @@ -300,21 +300,25 @@ void MachServer::runServerThread(bool doTimeout) * To avoid falling off the kernel's fast RPC path unnecessarily, * we only supply MACH_SEND_TIMEOUT when absolutely necessary. */ - mr = mach_msg_overwrite(bufReply, + mr = mach_msg_overwrite(bufReply, (MACH_MSGH_BITS_REMOTE(bufReply.bits()) == MACH_MSG_TYPE_MOVE_SEND_ONCE) ? MACH_SEND_MSG | mMsgOptions : MACH_SEND_MSG | MACH_SEND_TIMEOUT | mMsgOptions, bufReply.length(), 0, MACH_PORT_NULL, 0, MACH_PORT_NULL, NULL, 0); - switch (mr) { - case MACH_MSG_SUCCESS: - break; - default: + switch (mr) { + case MACH_MSG_SUCCESS: + break; + case MACH_SEND_INVALID_DEST: + case MACH_SEND_TIMED_OUT: secinfo("machserver", "send error: %d %d", mr, bufReply.remotePort().port()); - bufReply.destroy(); - break; - } + bufReply.destroy(); + break; + default: + secinfo("machserver", "send error: %d %d", mr, bufReply.remotePort().port()); + break; + } // clean up after the transaction diff --git a/OSX/libsecurity_utilities/lib/powerwatch.cpp b/OSX/libsecurity_utilities/lib/powerwatch.cpp index 80448e04..f23735db 100644 --- a/OSX/libsecurity_utilities/lib/powerwatch.cpp +++ b/OSX/libsecurity_utilities/lib/powerwatch.cpp @@ -62,110 +62,19 @@ void PowerWatcher::systemWillPowerOn() // IOPowerWatchers // -void -IOPowerWatcher::iopmcallback(void * param, - IOPMConnection connection, - IOPMConnectionMessageToken token, - IOPMSystemPowerStateCapabilities capabilities) -{ - IOPowerWatcher *me = (IOPowerWatcher *)param; - - secnotice("powerwatch", "powerstates"); - if (capabilities & kIOPMSystemPowerStateCapabilityDisk) - secnotice("powerwatch", "disk"); - if (capabilities & kIOPMSystemPowerStateCapabilityNetwork) - secnotice("powerwatch", "net"); - if (capabilities & kIOPMSystemPowerStateCapabilityAudio) - secnotice("powerwatch", "audio"); - if (capabilities & kIOPMSystemPowerStateCapabilityVideo) - secnotice("powerwatch", "video"); - - /* if cpu and no display -> in DarkWake */ - if ((capabilities & (kIOPMSystemPowerStateCapabilityCPU|kIOPMSystemPowerStateCapabilityVideo)) == kIOPMSystemPowerStateCapabilityCPU) { - secnotice("powerwatch", "enter DarkWake"); - me->mInDarkWake = true; - } else if (me->mInDarkWake) { - secnotice("powerwatch", "exit DarkWake"); - me->mInDarkWake = false; - } - - (void)IOPMConnectionAcknowledgeEvent(connection, token); - - return; -} - - -void -IOPowerWatcher::setupDarkWake() -{ - IOReturn ret; - - mInDarkWake = false; - - ret = ::IOPMConnectionCreate(CFSTR("IOPowerWatcher"), - kIOPMSystemPowerStateCapabilityDisk - | kIOPMSystemPowerStateCapabilityNetwork - | kIOPMSystemPowerStateCapabilityAudio - | kIOPMSystemPowerStateCapabilityVideo, - &mIOPMconn); - if (ret == kIOReturnSuccess) { - ret = ::IOPMConnectionSetNotification(mIOPMconn, this, - (IOPMEventHandlerType)iopmcallback); - if (ret == kIOReturnSuccess) { - ::IOPMConnectionSetDispatchQueue(mIOPMconn, mIOPMqueue); - } - } - - mUserActiveHandle = IOPMScheduleUserActiveChangedNotification(mIOPMqueue, ^(bool active) { - if (active) { - mInDarkWake = false; - } - }); - - dispatch_group_leave(mDarkWakeGroup); -} - IOPowerWatcher::IOPowerWatcher() : - mKernelPort(0), mIOPMconn(NULL), mIOPMqueue(NULL), mDarkWakeGroup(NULL), mUserActiveHandle(NULL) + mKernelPort(0) { if (!(mKernelPort = ::IORegisterForSystemPower(this, &mPortRef, ioCallback, &mHandle))) UnixError::throwMe(EINVAL); // no clue - - mIOPMqueue = dispatch_queue_create("com.apple.security.IOPowerWatcher", NULL); - if (mIOPMqueue == NULL) - return; - - // Running in background since this will wait for the power - // management in configd and we are not willing to block on - // that, power events will come in when they do. - mDarkWakeGroup = dispatch_group_create(); - dispatch_group_enter(mDarkWakeGroup); - dispatch_async(mIOPMqueue, ^ { setupDarkWake(); }); } IOPowerWatcher::~IOPowerWatcher() { - // Make sure to wait until the asynchronous method - // finishes, to avoid - if (mDarkWakeGroup) { - ::dispatch_group_wait(mDarkWakeGroup, DISPATCH_TIME_FOREVER); - ::dispatch_release(mDarkWakeGroup); - } if (mKernelPort) ::IODeregisterForSystemPower(&mHandle); - - if (mIOPMconn) { - ::IOPMConnectionSetDispatchQueue(mIOPMconn, NULL); - ::IOPMConnectionRelease(mIOPMconn); - } - if (mUserActiveHandle) - ::IOPMUnregisterNotification(mUserActiveHandle); - if (mIOPMqueue) - ::dispatch_release(mIOPMqueue); - } - // // The callback dispatcher // diff --git a/OSX/libsecurity_utilities/lib/powerwatch.h b/OSX/libsecurity_utilities/lib/powerwatch.h index a688759f..9212c16f 100644 --- a/OSX/libsecurity_utilities/lib/powerwatch.h +++ b/OSX/libsecurity_utilities/lib/powerwatch.h @@ -56,11 +56,6 @@ public: virtual void systemIsWaking(); virtual void systemWillPowerDown(); virtual void systemWillPowerOn(); - - bool inDarkWake() { return mInDarkWake; } - - protected: - bool mInDarkWake; }; @@ -76,21 +71,10 @@ protected: io_connect_t mKernelPort; IONotificationPortRef mPortRef; io_object_t mHandle; - IOPMConnection mIOPMconn; - dispatch_queue_t mIOPMqueue; - dispatch_group_t mDarkWakeGroup; - IOPMNotificationHandle mUserActiveHandle; - + static void ioCallback(void *refCon, io_service_t service, natural_t messageType, void *argument); - static void - iopmcallback(void * param, IOPMConnection connection, - IOPMConnectionMessageToken token, - IOPMSystemPowerStateCapabilities capabilities); - - void setupDarkWake(); - }; diff --git a/OSX/libsecurity_utilities/lib/seccfobject.h b/OSX/libsecurity_utilities/lib/seccfobject.h index 0cbec6b1..29e9a5d3 100644 --- a/OSX/libsecurity_utilities/lib/seccfobject.h +++ b/OSX/libsecurity_utilities/lib/seccfobject.h @@ -46,7 +46,9 @@ operator APIPTR() const \ \ OBJTYPE *retain() \ { SecCFObject::handle(true); return this; } \ -APIPTR handle(bool retain = true) \ +APIPTR CF_RETURNS_RETAINED handle() \ +{ return (APIPTR)SecCFObject::handle(true); } \ +APIPTR handle(bool retain) \ { return (APIPTR)SecCFObject::handle(retain); } #define SECCFFUNCTIONS_CREATABLE(OBJTYPE, APIPTR, CFCLASS) \ diff --git a/OSX/libsecurity_utilities/lib/security_utilities.h b/OSX/libsecurity_utilities/lib/security_utilities.h index d5350a3f..42abf0d3 100644 --- a/OSX/libsecurity_utilities/lib/security_utilities.h +++ b/OSX/libsecurity_utilities/lib/security_utilities.h @@ -30,16 +30,13 @@ #include #include #include -#include #include #include #include -#include #include #include #include #include -#include #include #include #include diff --git a/OSX/libsecurity_utilities/lib/streams.cpp b/OSX/libsecurity_utilities/lib/streams.cpp deleted file mode 100644 index 2a37b98c..00000000 --- a/OSX/libsecurity_utilities/lib/streams.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2000-2001,2003-2004,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@ - */ - - -// -// streams.h - lightweight source and sink objects -// -#include "streams.h" -#include - - -namespace Security { - - -// -// Source and Sink abstract superclasses -// -Source::State Source::state() const -{ - return mState; -} - -size_t Source::getSize() -{ - return unknownSize; -} - -void Sink::setSize(size_t) -{ - // ignored -} - - -// -// Null sources and sinks -// -void NullSource::produce(void *, size_t &length) -{ - length = 0; -} - -Source::State NullSource::state() const -{ - return endOfData; -} - -void NullSink::consume(const void *, size_t) -{ - // ignore the data -} - - -// -// File sources and sinks -// -void FileSource::produce(void *data, size_t &length) -{ - if ((length = read(data, length)) == 0) - mState = endOfData; -} - -size_t FileSource::getSize() -{ - return fileSize(); -} - - -void FileSink::consume(const void *data, size_t length) -{ - write(data, length); -} - - -// -// Memory sources -// -void MemorySource::produce(void *data, size_t &length) -{ - if (mRemaining < length) - length = mRemaining; - memcpy(data, mData, length); - mData = LowLevelMemoryUtilities::increment(mData, length); - mRemaining -= length; -} - -size_t MemorySource::getSize() -{ - return mRemaining; -} - -Source::State MemorySource::state() const -{ - return mRemaining ? producing : endOfData; -} - - -// -// Memory sinks -// -void MemorySink::consume(const void *data, size_t length) -{ - if (mSize + length > mMax) - grow(mSize * 3 / 2); - assert(mSize + length <= mMax); - memcpy(((char *)mBuffer) + mSize, data, length); - mSize += length; -} - -void MemorySink::setSize(size_t expectedSize) -{ - grow(expectedSize); -} - -void MemorySink::grow(size_t newSize) -{ - if (void *p = realloc(mBuffer, newSize)) { - mBuffer = p; - mMax = newSize; - } else - UnixError::throwMe(); -} - - -} // end namespace Security diff --git a/OSX/libsecurity_utilities/lib/streams.h b/OSX/libsecurity_utilities/lib/streams.h deleted file mode 100644 index 0d2036d7..00000000 --- a/OSX/libsecurity_utilities/lib/streams.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2000-2002,2004,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@ - */ - - -// -// streams.h - lightweight source and sink objects -// -#ifndef _H_STREAMS -#define _H_STREAMS - -#include "unix++.h" - - -namespace Security { - -using UnixPlusPlus::FileDesc; - - -// -// An abstract Source object. -// Source can yield data when its produce method is called. Produce can yield -// anything between zero and length bytes and sets length accordingly. -// If the last call to produce returned zero bytes (and only then), the state method -// will yield an explanation: -// producing -> we're in business; there just no data quite yet (try again) -// stalled -> there may be more data coming, but not in the near future; -// wait a while then call state again to see -// endOfData -> no more data will be produced by this Source -// When called *before* the first call to produce, getSize may return the number -// of bytes that all calls to produce will yield together. If getSize returns unknownSize, -// this value cannot be determined beforehand. GetSize *may* yield the number of bytes -// yet to come when called after produce, but this is not guaranteed for all Sources. -// -class Source { -public: - virtual void produce(void *data, size_t &length) = 0; - virtual ~Source() { } - - static const size_t unknownSize = size_t(-1); - virtual size_t getSize(); - - enum State { - producing, // yielding data (go ahead) - stalled, // no data now, perhaps more later - endOfData // end of data (no more data) - }; - virtual State state() const; - -protected: - State mState; // auto-regulated state (can be overridden) -}; - - -// -// An abstract Sink object. -// Sinks can cansume data when their consume method is called. -// Sinks cannot refuse data; they always consume all data given to consume. -// There is currently no flow control/throttle mechanism (one will probably -// be added soon). -// -class Sink { -public: - Sink() : mSize(0) {} - virtual ~Sink() { } - virtual void consume(const void *data, size_t length) = 0; - virtual void setSize(size_t expectedSize); - size_t getSize() {return mSize;} - -protected: - size_t mSize; - -}; - - -// -// The NullSource produces no data. -// -class NullSource : public Source { -public: - void produce(void *addr, size_t &len); - State state() const; -}; - - -// -// A FileSource reads from a UNIX file or file descriptor. -// Note that getSize will yield the size of the underlying i-node, -// which is usually correct but may not be in the case of simultaneous -// access. -// -class FileSource : public Source, public FileDesc { -public: - FileSource(const char *path, int mode = O_RDONLY) : FileDesc(path, mode) { mState = producing; } - FileSource(int fd) : FileDesc(fd) { mState = producing; } - void produce(void *data, size_t &length); - size_t getSize(); -}; - - -// -// A MemorySource yields the contents of a preset contiguous memory block. -// -class MemorySource : public Source { -public: - MemorySource(const void *data, size_t length) : mData(data), mRemaining(length) { } - - template - MemorySource(const Data &data) : mData(data.data()), mRemaining(data.length()) { } - - void produce(void *data, size_t &length); - size_t getSize(); - State state() const; - -private: - const void *mData; - size_t mRemaining; -}; - - -// -// A NullSink eats all data and discards it quietly. -// -class NullSink : public Sink { -public: - void consume(const void *data, size_t length); -}; - - -// -// A FileSink writes its received data to a UNIX file or file descriptor. -// -class FileSink : public Sink, public FileDesc { -public: - FileSink(const char *path, int mode = O_WRONLY | O_CREAT | O_TRUNC) - : FileDesc(path, mode) { } - FileSink(int fd) : FileDesc(fd) { } - void consume(const void *data, size_t length); -}; - - -// -// MemorySinks collect output in a contiguous memory block. -// This is not often a good idea, so if you find yourself using this, -// consider consuming on-the-fly or streaming to secondary media, -// or (at least) use a BufferFifo instead. -// -class MemorySink : public Sink { -public: - MemorySink() : mBuffer(NULL), mMax(0) { } - ~MemorySink() { free(mBuffer); } - - void consume(const void *data, size_t length); - void setSize(size_t expectedSize); - - void *data() const { return mBuffer; } - size_t length() const { return mSize; } - - void clear() { free(mBuffer); mBuffer = NULL; mSize = mMax = 0; } - -private: - void grow(size_t newSize); - -private: - void *mBuffer; // buffer base - size_t mMax; // currently allocated -}; - - -} // end namespace Security - - -#endif /* _H_STREAMS */ diff --git a/OSX/libsecurity_utilities/lib/vproc++.cpp b/OSX/libsecurity_utilities/lib/vproc++.cpp deleted file mode 100644 index 62d1758b..00000000 --- a/OSX/libsecurity_utilities/lib/vproc++.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2008,2011,2013 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@ - */ - - -// -// fdsel - select-style file descriptor set management -// -#include "vproc++.h" -#include -#include -#include -#include -#include -#include - -namespace Security { -namespace VProc { - - -void Transaction::activate() -{ - assert(!active()); - mTransaction = ::vproc_transaction_begin(mVP); -} - - -// -// Get the in-process accumulated transaction count. -// Use for debugging only. -// -size_t Transaction::debugCount() -{ -#if TARGET_OS_OSX - return ::_vproc_transaction_count(); -#else - MacOSError::throwMe(errSecUnimplemented); -#endif -} - - -} // end namespace VProc -} // end namespace Security diff --git a/OSX/libsecurity_utilities/lib/vproc++.h b/OSX/libsecurity_utilities/lib/vproc++.h deleted file mode 100644 index 8dcef402..00000000 --- a/OSX/libsecurity_utilities/lib/vproc++.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2008,2011 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@ - */ - - -// -// vproc++ - interface to low-level transaction tracking facility -// -#ifndef _H_VPROCPP -#define _H_VPROCPP - -#include - - -namespace Security { -namespace VProc { - - -class Transaction { -public: - Transaction(vproc_t vp = 0) : mVP(vp) { mTransaction = ::vproc_transaction_begin(vp); } - Transaction(bool activate, vproc_t vp = 0) : mVP(vp) - { if (activate) mTransaction = ::vproc_transaction_begin(vp); else mTransaction = 0; } - ~Transaction() { deactivate(); } - - // explicit state management - void activate(); - void deactivate() - { if (mTransaction) { ::vproc_transaction_end(mVP, mTransaction); mTransaction = 0; }} - bool active() const { return mTransaction != 0; } - - static size_t debugCount(); // debug use only - -private: - vproc_t mVP; - vproc_transaction_t mTransaction; -}; - - -} // end namespace VProc -} // end namespace Security - - -#endif //_H_VPROCPP diff --git a/OSX/libsecurityd/lib/ssclient.cpp b/OSX/libsecurityd/lib/ssclient.cpp index 76853a35..a6341b12 100644 --- a/OSX/libsecurityd/lib/ssclient.cpp +++ b/OSX/libsecurityd/lib/ssclient.cpp @@ -43,7 +43,6 @@ namespace SecurityServer { UnixPlusPlus::StaticForkMonitor ClientSession::mHasForked; ModuleNexus ClientSession::mGlobal; const char *ClientSession::mContactName; -SecGuestRef ClientSession::mDedicatedGuest = kSecNoGuest; // @@ -93,12 +92,6 @@ void ClientSession::activate() secinfo("SSclnt", "Thread registered with %s", mContactName); } - // if the thread's guest state has changed, tell securityd - if (thread.currentGuest != thread.lastGuest) { - IPCN(ucsp_client_setGuest(UCSP_ARGS, thread.currentGuest, kSecCSDefaultFlags)); - thread.lastGuest = thread.currentGuest; - secinfo("SSclnt", "switched guest state to 0x%x", thread.currentGuest); - } } // @@ -198,7 +191,7 @@ void ClientSession::childCheckIn(Port serverPort, Port taskPort) if (originPort != securitydPort.port()) CssmError::throwMe(CSSM_ERRCODE_VERIFICATION_FAILURE); mach_port_mod_refs(mach_task_self(), originPort, MACH_PORT_RIGHT_SEND, -1); - check(ucsp_client_childCheckIn(securitydPort, serverPort, taskPort)); + check(ucsp_client_childCheckIn(securitydPort, serverPort, MACH_PORT_NULL)); } diff --git a/OSX/libsecurityd/lib/ssclient.h b/OSX/libsecurityd/lib/ssclient.h index 5fd07093..adf3e949 100644 --- a/OSX/libsecurityd/lib/ssclient.h +++ b/OSX/libsecurityd/lib/ssclient.h @@ -34,7 +34,6 @@ #include "sscommon.h" #include #include -#include #ifdef __cplusplus @@ -354,7 +353,7 @@ public: const void *data, size_t dataLength, void *context); public: - // securityd helper support + // securityd helper support. The taskPort argument is no longer used, server will use client's audit token void childCheckIn(Port serverPort, Port taskPort); public: @@ -363,19 +362,6 @@ public: KeyHandle key, CSSM_ACL_AUTHORIZATION_TAG tag); void registerForAclEdits(DidChangeKeyAclCallback *callback, void *context); -public: - // Code Signing hosting interface - void registerHosting(mach_port_t hostingPort, SecCSFlags flags); - mach_port_t hostingPort(pid_t pid); - - SecGuestRef createGuest(SecGuestRef host, - uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags); - void setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes); - void removeGuest(SecGuestRef host, SecGuestRef guest); - - void selectGuest(SecGuestRef guest); - SecGuestRef selectedGuest() const; - private: static Port findSecurityd(); void getAcl(AclKind kind, GenericHandle key, const char *tag, @@ -402,16 +388,12 @@ private: static UnixPlusPlus::StaticForkMonitor mHasForked; // global fork indicator struct Thread { - Thread() : registered(false), notifySeq(0), - currentGuest(kSecNoGuest), lastGuest(kSecNoGuest) { } + Thread() : registered(false), notifySeq(0) { } operator bool() const { return registered; } ReceivePort replyPort; // dedicated reply port (send right held by SecurityServer) bool registered; // has been registered with SecurityServer uint32 notifySeq; // notification sequence number - - SecGuestRef currentGuest; // last set guest path - SecGuestRef lastGuest; // last transmitted guest path }; struct Global { @@ -423,7 +405,6 @@ private: static ModuleNexus mGlobal; static const char *mContactName; - static SecGuestRef mDedicatedGuest; }; diff --git a/OSX/libsecurityd/lib/transition.cpp b/OSX/libsecurityd/lib/transition.cpp index 63ffabc9..5c242e74 100644 --- a/OSX/libsecurityd/lib/transition.cpp +++ b/OSX/libsecurityd/lib/transition.cpp @@ -50,6 +50,7 @@ #include "sstransit.h" #include +#include #include #include #include @@ -481,12 +482,18 @@ uint32 ClientSession::getOutputSize(const Context &context, KeyHandle key, // a PRNG in its CSP. If you need a reproducible PRNG, attach a local CSP and use it. // Note that this function does not allocate a buffer; it always fills the buffer provided. // +// As of macOS 10.15 this no longer fetches random data from the daemon but generates it in-process +// void ClientSession::generateRandom(const Security::Context &context, CssmData &data, Allocator &alloc) { - CopyIn ctxcopy(&context, reinterpret_cast(xdr_CSSM_CONTEXT)); - DataOutput result(data, alloc); - - IPC(ucsp_client_generateRandom(UCSP_ARGS, 0, ctxcopy.data(), ctxcopy.length(), DATA_OUT(result))); + size_t count = context.getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE); + if (data.length() < count) { + CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA); + } + CCRNGStatus status = CCRandomGenerateBytes(data.data(), count); + if (status != kCCSuccess) { + CssmError::throwMe(status); + } } @@ -843,63 +850,6 @@ void ClientSession::postNotification(NotificationDomain domain, NotificationEven } -// -// Code Signing related -// -void ClientSession::registerHosting(mach_port_t hostingPort, SecCSFlags flags) -{ - IPC(ucsp_client_registerHosting(UCSP_ARGS, hostingPort, flags)); -} - -mach_port_t ClientSession::hostingPort(pid_t pid) -{ - mach_port_t result; - IPC(ucsp_client_hostingPort(UCSP_ARGS, pid, &result)); - return result; -} - -SecGuestRef ClientSession::createGuest(SecGuestRef host, - uint32_t status, const char *path, const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags) -{ - SecGuestRef newGuest; - IPC(ucsp_client_createGuest(UCSP_ARGS, host, status, path, DATA(cdhash), DATA(attributes), flags, &newGuest)); - if (flags & kSecCSDedicatedHost) { - secinfo("ssclient", "setting dedicated guest to 0x%x (was 0x%x)", - mDedicatedGuest, newGuest); - mDedicatedGuest = newGuest; - } - return newGuest; -} - -void ClientSession::setGuestStatus(SecGuestRef guest, uint32 status, const CssmData &attributes) -{ - IPC(ucsp_client_setGuestStatus(UCSP_ARGS, guest, status, DATA(attributes))); -} - -void ClientSession::removeGuest(SecGuestRef host, SecGuestRef guest) -{ - IPC(ucsp_client_removeGuest(UCSP_ARGS, host, guest)); -} - -void ClientSession::selectGuest(SecGuestRef newGuest) -{ - if (mDedicatedGuest) { - secinfo("ssclient", "ignoring selectGuest(0x%x) because dedicated guest=0x%x", - newGuest, mDedicatedGuest); - } else { - secinfo("ssclient", "switching to guest 0x%x", newGuest); - mGlobal().thread().currentGuest = newGuest; - } -} - -SecGuestRef ClientSession::selectedGuest() const -{ - if (mDedicatedGuest) - return mDedicatedGuest; - else - return mGlobal().thread().currentGuest; -} - // // Testing related // diff --git a/OSX/libsecurityd/mig/cshosting.defs b/OSX/libsecurityd/mig/cshosting.defs deleted file mode 100644 index 7d4b45df..00000000 --- a/OSX/libsecurityd/mig/cshosting.defs +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2006,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@ -// -// cshosting - Mach IPC interface for Code Signing Hosts -// -#include -#include -#include "ss_types.defs" - -subsystem cshosting 20000; -serverprefix cshosting_server_; -userprefix cshosting_client_; - -import ; - - -#define CSH_PORTS requestport sport: mach_port_t; \ - replyport rport: mach_port_make_send_once_t; \ - out rcode: OSStatus - - -// -// Code Signing Hosting protocol. -// These routines are straightforward implementations of the hosting -// protocol, translated into MIG terms. Hosts are represented by -// Hosting Ports, whose receive rights are held by the host (whatever -// it might be). -// The hosting protocol carries no privileges and can be called by -// anyone without authentication. It's supposed to be easy to obtain a host's -// hosting port, so don't hand out any secrets in your implementation. -// -routine findGuest(CSH_PORTS; in host: SecGuestRef; in attributes: XMLBlob; - out guest: GuestChain; out subhost: mach_port_make_send_t); -routine guestStatus(CSH_PORTS; in guest: SecGuestRef; out status: uint32); -skip; -routine identifyGuest(CSH_PORTS; in guest: SecGuestRef; out path: FilePathOut; - out cdhash: HashDataOut; out hashLength: uint32; out attributes: XMLBlobOut); diff --git a/OSX/libsecurityd/mig/ucsp.defs b/OSX/libsecurityd/mig/ucsp.defs index 19f66ecc..223ebb57 100644 --- a/OSX/libsecurityd/mig/ucsp.defs +++ b/OSX/libsecurityd/mig/ucsp.defs @@ -167,7 +167,8 @@ routine deriveKey(UCSP_PORTS; in db: IPCDbHandle; in context: Data; in baseKey: in paramInput: Data; out paramOutput: Data; in keyUsage: uint32; in keyAttrs: uint32; out key: IPCKeyHandle; out header: Data); -routine generateRandom(UCSP_PORTS; in ssid: uint32; in context: Data; out data: Data); +// routine generateRandom(UCSP_PORTS; in ssid: uint32; in context: Data; out data: Data); +skip; // @@ -280,7 +281,7 @@ skip; // was setAlternateSystemRoot // Subsidiary process (child) management. // This call does NOT cause securityd-client activation. // -simpleroutine childCheckIn(requestport sport: mach_port_t; +simpleroutine childCheckIn(ServerAuditToken sourceAudit: audit_token_t; requestport sport: mach_port_t; in servicePort: mach_port_make_send_t; in task_port: mach_port_t); #if 1 @@ -290,29 +291,19 @@ routine commitDbForSync(UCSP_PORTS; in srcDb: IPCDbHandle; in cloneDb: IPCDbHand out blob: DbBlob); #endif - // -// Code Signing Hosting protocol part 1: registration services. +// The following three blocks of skips replace the old Code Hosting routines // -routine registerHosting(UCSP_PORTS; - in hostingPort: mach_port_make_send_t; in flags: uint32); -routine hostingPort(UCSP_PORTS; - in hostPid: pid_t; out hostingPort: mach_port_make_send_t); -routine setGuest(UCSP_PORTS; in guest: SecGuestRef; in flags: uint32); -// -// Code Signing Hosting protocol part 2: proxy services. -// -routine createGuest(UCSP_PORTS; in host: SecGuestRef; in status: uint32_t; - in path: FilePath; in cdhash: HashData; in attributes: Data; in flags: uint32; out guest: SecGuestRef); -routine setGuestStatus(UCSP_PORTS; in guest: SecGuestRef; - in status: uint32_t; in attributes: Data); -routine removeGuest(UCSP_PORTS; in host: SecGuestRef; in guest: SecGuestRef); +skip; +skip; +skip; -// -// Code Signing support calls -// -routine helpCheckLoad(UCSP_PORTS; in path: FilePath; in addType: uint32_t); +skip; +skip; +skip; + +skip; // // Keychain Syncing setup support calls diff --git a/OSX/macos_tapi_hacks.h b/OSX/macos_tapi_hacks.h index ae9740d2..a03e17e8 100644 --- a/OSX/macos_tapi_hacks.h +++ b/OSX/macos_tapi_hacks.h @@ -83,17 +83,11 @@ bool securityd_message_no_error(xpc_object_t message, CFErrorRef *error); void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); CFArrayRef SecAccessGroupsGetCurrent(void); +void SecServerSetTrustdMachServiceName(const char *name); + // checkpw.c int checkpw_internal( const struct passwd* pw, const char* password ); -// SecFramework.h -CFDataRef SecDigestCreate(CFAllocatorRef allocator, - const SecAsn1Oid *algorithm, const SecAsn1Item *params, - const UInt8 *data, CFIndex length); -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/regressions/test/testenv.m b/OSX/regressions/test/testenv.m index e6a96cd3..ac5096d2 100644 --- a/OSX/regressions/test/testenv.m +++ b/OSX/regressions/test/testenv.m @@ -71,7 +71,7 @@ static char *home_var; static int rmdir_recursive(const char *path) { -#if (!TARGET_IPHONE_SIMULATOR) +#if (!TARGET_OS_SIMULATOR) char command_buf[256]; if (strlen(path) + 10 > sizeof(command_buf) || strchr(path, '\'')) { diff --git a/OSX/sec/ProjectHeaders/SOSCircle/Tool b/OSX/sec/ProjectHeaders/SOSCircle/Tool deleted file mode 120000 index 75d632ab..00000000 --- a/OSX/sec/ProjectHeaders/SOSCircle/Tool +++ /dev/null @@ -1 +0,0 @@ -./../SOSCircle/Tool \ No newline at end of file diff --git a/OSX/sec/ProjectHeaders/Security/CKBridge b/OSX/sec/ProjectHeaders/Security/CKBridge deleted file mode 120000 index 446b2efb..00000000 --- a/OSX/sec/ProjectHeaders/Security/CKBridge +++ /dev/null @@ -1 +0,0 @@ -./../SOSCircle/CKBridge \ No newline at end of file diff --git a/OSX/sec/ProjectHeaders/Security/SecureObjectSync b/OSX/sec/ProjectHeaders/Security/SecureObjectSync deleted file mode 120000 index 4c09948d..00000000 --- a/OSX/sec/ProjectHeaders/Security/SecureObjectSync +++ /dev/null @@ -1 +0,0 @@ -./../SOSCircle/SecureObjectSync \ No newline at end of file diff --git a/OSX/sec/ProjectHeaders/Security/Tool b/OSX/sec/ProjectHeaders/Security/Tool deleted file mode 120000 index 533c3ce3..00000000 --- a/OSX/sec/ProjectHeaders/Security/Tool +++ /dev/null @@ -1 +0,0 @@ -./../Security/Tool \ No newline at end of file diff --git a/OSX/sec/ProjectHeaders/SecurityTool b/OSX/sec/ProjectHeaders/SecurityTool deleted file mode 120000 index 1b39748b..00000000 --- a/OSX/sec/ProjectHeaders/SecurityTool +++ /dev/null @@ -1 +0,0 @@ -./SecurityTool \ No newline at end of file diff --git a/OSX/sec/SOSCircle/Regressions/sc-25-soskeygen.c b/OSX/sec/SOSCircle/Regressions/sc-25-soskeygen.c deleted file mode 100644 index d3693545..00000000 --- a/OSX/sec/SOSCircle/Regressions/sc-25-soskeygen.c +++ /dev/null @@ -1,110 +0,0 @@ -// -// sc-25-soskeygen.c -// sec -// -// Created by Richard Murphy on 6/1/15. -// -// - -/* - * 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 -#include "SOSCircle_regressions.h" - -#include "SOSRegressionUtilities.h" - - -#if TARGET_OS_WATCH -#define NPARMS 3 -#define NKEYS 3 -#else -#define NPARMS 10 -#define NKEYS 10 -#endif - -static int kTestTestCount = (NKEYS*(4+NPARMS*4)); - - -static SecKeyRef createTestKey(CFDataRef cfpassword, CFDataRef parameters, CFErrorRef *error) { - SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, error); - ok(user_privkey, "No key!"); - ok(*error == NULL, "Error: (%@)", *error); - CFReleaseNull(*error); - return user_privkey; -} - -static void tests(void) { - CFErrorRef error = NULL; - CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10); - - for(int j=0; j < NPARMS; j++) { - CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error); - ok(parameters, "No parameters!"); - ok(error == NULL, "Error: (%@)", error); - CFReleaseNull(error); - - SecKeyRef baseline_privkey = createTestKey(cfpassword, parameters, &error); - if(baseline_privkey) { - SecKeyRef baseline_pubkey = SecKeyCreatePublicFromPrivate(baseline_privkey); - - for(int i = 0; i < NKEYS; i++) { - SecKeyRef user_privkey = createTestKey(cfpassword, parameters, &error); - SecKeyRef user_pubkey = SecKeyCreatePublicFromPrivate(user_privkey); - ok(CFEqualSafe(baseline_privkey, user_privkey), "Private Keys Don't Match"); - ok(CFEqualSafe(baseline_pubkey, user_pubkey), "Public Keys Don't Match"); - CFReleaseNull(error); - CFReleaseNull(user_privkey); - CFReleaseNull(user_pubkey); - } - CFReleaseNull(baseline_pubkey); - } - CFReleaseNull(baseline_privkey); - CFReleaseNull(parameters); - } - CFReleaseNull(cfpassword); -} - -int sc_25_soskeygen(int argc, char *const *argv) -{ - plan_tests(kTestTestCount); - - tests(); - - return 0; -} diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.h deleted file mode 100644 index f4123ba4..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// SOSAccountGhost.h -// sec -// -// Created by Richard Murphy on 4/12/16. -// -// - -#ifndef SOSAccountGhost_h -#define SOSAccountGhost_h - -#include "SOSAccount.h" - -bool SOSAccountTrustedCircleHasNoGhostOfMe(SOSAccount* account); -bool SOSAccountGhostResultsInReset(SOSAccount* account); -CF_RETURNS_RETAINED SOSCircleRef SOSAccountCloneCircleWithoutMyGhosts(SOSAccount* account, SOSCircleRef startCircle); - -#endif /* SOSAccountGhost_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m deleted file mode 100644 index 985db5c1..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGhost.m +++ /dev/null @@ -1,149 +0,0 @@ -// -// SOSAccountGhost.c -// sec -// -// Created by Richard Murphy on 4/12/16. -// -// - -#include "SOSAccountPriv.h" -#include "SOSAccountGhost.h" -#include -#include -#include -#include -#include -#include -#include - -#define DETECT_IOS_ONLY 1 - -static bool sosGhostCheckValid(SOSPeerInfoRef pi) { -#if DETECT_IOS_ONLY - bool retval = false; - require_quiet(pi, retOut); - SOSPeerInfoDeviceClass peerClass = SOSPeerInfoGetClass(pi); - switch(peerClass) { - case SOSPeerInfo_iOS: - case SOSPeerInfo_tvOS: - case SOSPeerInfo_watchOS: - retval = true; - break; - case SOSPeerInfo_macOS: - case SOSPeerInfo_iCloud: - case SOSPeerInfo_unknown: - default: - retval = false; - break; - } -retOut: - return retval; -#else - return true; -#endif -} - -static CFSetRef SOSCircleCreateGhostsOfPeerSet(SOSCircleRef circle, SOSPeerInfoRef me) { - CFMutableSetRef ghosts = NULL; - require_quiet(me, errOut); - require_quiet(sosGhostCheckValid(me), errOut); - require_quiet(circle, errOut); - require_quiet(SOSPeerInfoSerialNumberIsSet(me), errOut); - CFStringRef mySerial = SOSPeerInfoCopySerialNumber(me); - require_quiet(mySerial, errOut); - CFStringRef myPeerID = SOSPeerInfoGetPeerID(me); - ghosts = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - require_quiet(ghosts, errOut1); - SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef pi) { - CFStringRef theirPeerID = SOSPeerInfoGetPeerID(pi); - if(!CFEqual(myPeerID, theirPeerID)) { - CFStringRef piSerial = SOSPeerInfoCopySerialNumber(pi); - if(CFEqualSafe(mySerial, piSerial)) { - CFSetAddValue(ghosts, theirPeerID); - } - CFReleaseNull(piSerial); - } - }); -errOut1: - CFReleaseNull(mySerial); -errOut: - return ghosts; - -} - -static CFSetRef SOSTrustedCircleCreateGhostsOfPeerSet(SOSAccount* account, SOSPeerInfoRef pi) { - return (account) ? SOSCircleCreateGhostsOfPeerSet([account.trust getCircle:NULL], pi): NULL; -} - -static CFSetRef SOSTrustedCircleCopyGhostSet(SOSAccount* account) { - CFSetRef ghosts = NULL; - require_quiet(account, errOut); - SOSPeerInfoRef me = account.peerInfo; - require_quiet(me, errOut); - require_quiet(sosGhostCheckValid(me), errOut); - ghosts = SOSTrustedCircleCreateGhostsOfPeerSet(account, me); -errOut: - return ghosts; - -} - -static CFIndex SOSTrustedCircleGhostSetCount(SOSAccount* account) { - CFIndex retval = 0; - CFSetRef ghosts = SOSTrustedCircleCopyGhostSet(account); - require_quiet(ghosts, retOut); - retval = CFSetGetCount(ghosts); - CFReleaseNull(ghosts); -retOut: - return retval; -} - -bool SOSAccountTrustedCircleHasNoGhostOfMe(SOSAccount* account) { - return SOSTrustedCircleGhostSetCount(account) == 0; -} - -bool SOSAccountGhostResultsInReset(SOSAccount* account) { - return SOSTrustedCircleGhostSetCount(account) == SOSCircleCountPeers([account.trust getCircle:NULL]); -} - - -// This only works if you're in the circle and have the private key - -CF_RETURNS_RETAINED SOSCircleRef SOSAccountCloneCircleWithoutMyGhosts(SOSAccount* account, SOSCircleRef startCircle) { - SOSCircleRef newCircle = NULL; - CFSetRef ghosts = NULL; - require_quiet(account, retOut); - SecKeyRef userPrivKey = SOSAccountGetPrivateCredential(account, NULL); - require_quiet(userPrivKey, retOut); - SOSPeerInfoRef me = account.peerInfo; - require_quiet(me, retOut); - bool iAmApplicant = SOSCircleHasApplicant(startCircle, me, NULL); - - ghosts = SOSCircleCreateGhostsOfPeerSet(startCircle, me); - require_quiet(ghosts, retOut); - require_quiet(CFSetGetCount(ghosts), retOut); - - CFStringSetPerformWithDescription(ghosts, ^(CFStringRef description) { - secnotice("ghostbust", "Removing peers: %@", description); - }); - - newCircle = SOSCircleCopyCircle(kCFAllocatorDefault, startCircle, NULL); - require_quiet(newCircle, retOut); - if(iAmApplicant) { - if(SOSCircleRemovePeersByIDUnsigned(newCircle, ghosts) && (SOSCircleCountPeers(newCircle) == 0)) { - secnotice("resetToOffering", "Reset to offering with last ghost and me as applicant"); - if(!SOSCircleResetToOffering(newCircle, userPrivKey, account.fullPeerInfo, NULL) || - ![account.trust addiCloudIdentity:newCircle key:userPrivKey err:NULL]){ - CFReleaseNull(newCircle); - } - account.notifyBackupOnExit = true; - } else { - CFReleaseNull(newCircle); - } - } else { - SOSCircleRemovePeersByID(newCircle, userPrivKey, account.fullPeerInfo, ghosts, NULL); - } -retOut: - CFReleaseNull(ghosts); - return newCircle; -} - diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.h deleted file mode 100644 index 59ee33a7..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// SOSAccountLog.h -// sec -// -// Created by Richard Murphy on 6/1/16. -// -// - -#ifndef SOSAccountLog_h -#define SOSAccountLog_h - -#include -#import -#include -#include -#include -#include -#include -#include -#include -#import - -//#include -@class SOSAccount; - -void SOSAccountLog(SOSAccount* account); -SOSAccount* SOSAccountCreateFromStringRef(CFStringRef hexString); - -#endif /* SOSAccountLog_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h b/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h deleted file mode 100644 index 4652f047..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// 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/SOSSysdiagnose.m b/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m deleted file mode 100644 index af466cff..00000000 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSSysdiagnose.m +++ /dev/null @@ -1,199 +0,0 @@ -// -// SOSSysdiagnose.c -// sec -// -// Created by Richard Murphy on 1/27/16. -// -// - - -#include "SOSCloudCircleInternal.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "SOSSysdiagnose.h" -#include "keychain_log.h" -#include "secToolFileIO.h" -#include "secViewDisplay.h" -#include "accountCirclesViewsPrint.h" - - - -#include - -static char *CFDictionaryCopyCStringWithDefault(CFDictionaryRef dict, const void *key, char *defaultString) { - char *retval = NULL; - require_quiet(dict, use_default); - CFStringRef val = CFDictionaryGetValue(dict, key); - retval = CFStringToCString(val); -use_default: - if(!retval) retval = strdup(defaultString); - return retval; -} - -static char *createDateStrNow() { - char *retval = NULL; - time_t clock; - - struct tm *tmstruct; - - time(&clock); - tmstruct = localtime(&clock); - - retval = malloc(15); - sprintf(retval, "%04d%02d%02d%02d%02d%02d", tmstruct->tm_year+1900, tmstruct->tm_mon+1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); - return retval; -} - -#if !TARGET_OS_EMBEDDED -static char *assemblePath(char *dir, char *fname) { - size_t length = strlen(dir) + strlen(fname) + 2; - char *outputDir = malloc(length); - int status = snprintf(outputDir, length, "%s/%s", dir, fname); - if(status < 0) { - if(outputDir) free(outputDir); - return NULL; - } - return outputDir; -} - -static char *homedirPath() { - char *homeDir = ""; - struct passwd* pwd = getpwuid(getuid()); - if (pwd) homeDir = pwd->pw_dir; - return homeDir; -} -#endif - -static char *sysdiagnose_dir(const char *passedIn, const char *hostname, const char *productVersion, const char *now) { - if(passedIn) return (char *) passedIn; - - // OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW} - char *outputParent = NULL; - size_t length = strlen("ckcdiagnose_snapshot___") + strlen(hostname) + strlen(productVersion) + strlen(now) + 1; - char *outputBase = malloc(length); - int status = snprintf(outputBase, length, "ckcdiagnose_snapshot_%s_%s_%s", hostname, productVersion, now); - if(status < 0) outputBase = ""; - -#if TARGET_OS_EMBEDDED - outputParent = "/Library/Logs/CrashReporter"; -#else - outputParent = "/var/tmp"; -#endif - length = strlen(outputParent) + strlen(outputBase) + 2; - char *outputDir = malloc(length); - status = snprintf(outputDir, length, "%s/%s", outputParent, outputBase); - if(status < 0) { - if(outputDir) free(outputDir); - return NULL; - } - return outputDir; -} - - -static char *sysdiagnose_dump(const char *dirname) { - char *outputDir = NULL; - char hostname[80]; - char *productName = NULL; - char *productVersion = NULL; - char *buildVersion = NULL; - char *keysToRegister = NULL; - char *cloudkeychainproxy3 = NULL; - char *now = createDateStrNow(); - - CFDictionaryRef sysfdef = _CFCopySystemVersionDictionary(); - productName = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionProductNameKey, "unknownProduct"); - productVersion = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionProductVersionKey, "unknownProductVersion"); - buildVersion = CFDictionaryCopyCStringWithDefault(sysfdef, _kCFSystemVersionBuildVersionKey, "unknownVersion"); - - if(gethostname(hostname, 80)) { - strcpy(hostname, "unknownhost"); - } - -#if TARGET_OS_EMBEDDED - keysToRegister = "/private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist"; - cloudkeychainproxy3 = "/var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist"; -#else - char *homeDir = homedirPath(); - keysToRegister = assemblePath(homeDir, "Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist"); - cloudkeychainproxy3 = assemblePath(homeDir, "Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist"); -#endif - - outputDir = sysdiagnose_dir(dirname, hostname, productVersion, now); - if(!outputDir) goto errOut; - - mkdir(outputDir, 0700); - - SOSLogSetOutputTo(outputDir, "sw_vers.log"); - // report uname stuff + hostname - fprintf(outFile, "HostName: %s\n", hostname); - fprintf(outFile, "ProductName: %s\n", productName); - fprintf(outFile, "ProductVersion: %s\n", productVersion); - fprintf(outFile, "BuildVersion: %s\n", buildVersion); - closeOutput(); - - SOSLogSetOutputTo(outputDir, "syncD.log"); - // do sync -D - SOSCCDumpCircleKVSInformation(optarg); - closeOutput(); - - SOSLogSetOutputTo(outputDir, "synci.log"); - // do sync -i - SOSCCDumpCircleInformation(); - closeOutput(); - - SOSLogSetOutputTo(outputDir, "syncL.log"); - // do sync -L - listviewcmd(NULL); - closeOutput(); - - copyFileToOutputDir(outputDir, keysToRegister); - copyFileToOutputDir(outputDir, cloudkeychainproxy3); - -errOut: - if(now) free(now); - CFReleaseNull(sysfdef); -#if ! TARGET_OS_EMBEDDED - free(keysToRegister); - free(cloudkeychainproxy3); -#endif - if(productName) free(productName); - if(productVersion) free(productVersion); - if(buildVersion) free(buildVersion); - return outputDir; -} - - -char *SOSCCSysdiagnose(const char *directoryname) { - sysdiagnose_dump(directoryname); - return NULL; -} - diff --git a/OSX/sec/SOSCircle/Tool/keychain_log.m b/OSX/sec/SOSCircle/Tool/keychain_log.m deleted file mode 100644 index 8286b218..00000000 --- a/OSX/sec/SOSCircle/Tool/keychain_log.m +++ /dev/null @@ -1,267 +0,0 @@ -// -// keychain_log.c -// sec -// -// Created by Richard Murphy on 1/26/16. -// -// - -#include "keychain_log.h" - -/* - * Copyright (c) 2003-2007,2009-2010,2013-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@ - * - * keychain_add.c - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "SOSSysdiagnose.h" -#include "keychain_log.h" -#include "secToolFileIO.h" -#include "secViewDisplay.h" -#include "accountCirclesViewsPrint.h" -#include - - -#include - -#define MAXKVSKEYTYPE kUnknownKey -#define DATE_LENGTH 18 - -#define USE_NEW_SPI 1 -#if ! USE_NEW_SPI - -static char *createDateStrNow() { - char *retval = NULL; - time_t clock; - - struct tm *tmstruct; - - time(&clock); - tmstruct = localtime(&clock); - - retval = malloc(15); - sprintf(retval, "%04d%02d%02d%02d%02d%02d", tmstruct->tm_year+1900, tmstruct->tm_mon+1, tmstruct->tm_mday, tmstruct->tm_hour, tmstruct->tm_min, tmstruct->tm_sec); - return retval; -} - -static char *CFDictionaryCopyCString(CFDictionaryRef dict, const void *key) { - CFStringRef val = CFDictionaryGetValue(dict, key); - char *retval = CFStringToCString(val); - return retval; -} - -#include - -static void sysdiagnose_dump() { - char *outputBase = NULL; - char *outputParent = NULL; - char *outputDir = NULL; - char hostname[80]; - char *productName = "NA"; - char *productVersion = "NA"; - char *buildVersion = "NA"; - char *keysToRegister = NULL; - char *cloudkeychainproxy3 = NULL; - char *now = createDateStrNow(); - size_t length = 0; - int status = 0; - CFDictionaryRef sysfdef = _CFCopySystemVersionDictionary(); - - if(gethostname(hostname, 80)) { - strcpy(hostname, "unknownhost"); - } - - if(sysfdef) { - productName = CFDictionaryCopyCString(sysfdef, _kCFSystemVersionProductNameKey); - productVersion = CFDictionaryCopyCString(sysfdef, _kCFSystemVersionProductVersionKey); - buildVersion = CFDictionaryCopyCString(sysfdef, _kCFSystemVersionBuildVersionKey); - } - - // OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW} - length = strlen("ckcdiagnose_snapshot___") + strlen(hostname) + strlen(productVersion) + strlen(now) + 1; - outputBase = malloc(length); - status = snprintf(outputBase, length, "ckcdiagnose_snapshot_%s_%s_%s", hostname, productVersion, now); - if(status < 0) outputBase = ""; - -#if TARGET_OS_EMBEDDED - outputParent = "/Library/Logs/CrashReporter"; - keysToRegister = "/private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist"; - cloudkeychainproxy3 = "/var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist"; -#else - outputParent = "/var/tmp"; - { - char *homeDir = ""; - struct passwd* pwd = getpwuid(getuid()); - if (pwd) homeDir = pwd->pw_dir; - - char *k2regfmt = "%s/Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist"; - char *ckp3fmt = "%s/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist"; - size_t k2rlen = strlen(homeDir) + strlen(k2regfmt) + 2; - size_t ckp3len = strlen(homeDir) + strlen(ckp3fmt) + 2; - keysToRegister = malloc(k2rlen); - cloudkeychainproxy3 = malloc(ckp3len); - snprintf(keysToRegister, k2rlen, k2regfmt, homeDir); - snprintf(cloudkeychainproxy3, ckp3len, ckp3fmt, homeDir); - } -#endif - - length = strlen(outputParent) + strlen(outputBase) + 2; - outputDir = malloc(length); - status = snprintf(outputDir, length, "%s/%s", outputParent, outputBase); - if(status < 0) return; - - mkdir(outputDir, 0700); - - SOSLogSetOutputTo(outputDir, "sw_vers.log"); - // report uname stuff + hostname - fprintf(outFile, "HostName: %s\n", hostname); - fprintf(outFile, "ProductName: %s\n", productName); - fprintf(outFile, "ProductVersion: %s\n", productVersion); - fprintf(outFile, "BuildVersion: %s\n", buildVersion); - closeOutput(); - - SOSLogSetOutputTo(outputDir, "syncD.log"); - // do sync -D - SOSCCDumpCircleKVSInformation(optarg); - closeOutput(); - - SOSLogSetOutputTo(outputDir, "synci.log"); - // do sync -i - SOSCCDumpCircleInformation(); - SOSCCDumpEngineInformation(); - closeOutput(); - - SOSLogSetOutputTo(outputDir, "syncL.log"); - // do sync -L - listviewcmd(NULL); - closeOutput(); - - copyFileToOutputDir(outputDir, keysToRegister); - copyFileToOutputDir(outputDir, cloudkeychainproxy3); - - free(now); - CFReleaseNull(sysfdef); -#if ! TARGET_OS_EMBEDDED - free(keysToRegister); - free(cloudkeychainproxy3); -#endif - -} -#else -static void sysdiagnose_dump() { - SOSCCSysdiagnose(NULL); -} - -#endif /* USE_NEW_SPI */ - -static bool logmark(const char *optarg) { - if(!optarg) return false; - secnotice("mark", "%s", optarg); - return true; -} - - -// enable, disable, accept, reject, status, Reset, Clear -int -keychain_log(int argc, char * const *argv) -{ - /* - "Keychain Logging" - " -i info (current status)" - " -D [itemName] dump contents of KVS" - " -L list all known view and their status" - " -s sysdiagnose log dumps" - " -M string place a mark in the syslog - category \"mark\"" - - */ - SOSLogSetOutputTo(NULL, NULL); - - int ch, result = 0; - CFErrorRef error = NULL; - bool hadError = false; - - while ((ch = getopt(argc, argv, "DiLM:s")) != -1) - switch (ch) { - - case 'i': - SOSCCDumpCircleInformation(); - SOSCCDumpEngineInformation(); - break; - - - case 's': - sysdiagnose_dump(); - break; - - case 'D': - (void)SOSCCDumpCircleKVSInformation(optarg); - break; - - case 'L': - hadError = !listviewcmd(&error); - break; - - case 'M': - hadError = !logmark(optarg); - break; - - case '?': - default: - return SHOW_USAGE_MESSAGE; - } - - if (hadError) - printerr(CFSTR("Error: %@\n"), error); - - return result; -} diff --git a/OSX/sec/Security/Regressions/Security_regressions.h b/OSX/sec/Security/Regressions/Security_regressions.h index b610bdf4..11849edf 100644 --- a/OSX/sec/Security/Regressions/Security_regressions.h +++ b/OSX/sec/Security/Regressions/Security_regressions.h @@ -36,7 +36,7 @@ ONE_TEST(si_69_keydesc) ONE_TEST(si_72_syncableitems) ONE_TEST(si_73_secpasswordgenerate) #if TARGET_OS_IPHONE -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR OFF_ONE_TEST(si_76_shared_credentials) #else ONE_TEST(si_76_shared_credentials) diff --git a/OSX/sec/Security/Regressions/crypto/padding-00-mmcs.c b/OSX/sec/Security/Regressions/crypto/padding-00-mmcs.c index fdf0f4c1..62fa5b53 100644 --- a/OSX/sec/Security/Regressions/crypto/padding-00-mmcs.c +++ b/OSX/sec/Security/Regressions/crypto/padding-00-mmcs.c @@ -2,11 +2,11 @@ * Copyright (c) 2017 Apple Inc. All Rights Reserved. */ -#include "testmore.h" +#include "test/testmore.h" -#include "SecPaddingConfigurationsPriv.h" +#include #include "shared_regressions.h" -#include "SecCFWrappers.h" +#include #define kTestTestCount 67 diff --git a/OSX/sec/Security/Regressions/otr/otr-packetdata.c b/OSX/sec/Security/Regressions/otr/otr-packetdata.c index f4e1753d..e4d8987c 100644 --- a/OSX/sec/Security/Regressions/otr/otr-packetdata.c +++ b/OSX/sec/Security/Regressions/otr/otr-packetdata.c @@ -27,7 +27,7 @@ #include -#include "security_regressions.h" +#include "Security_regressions.h" static bool CFDataMatches(CFDataRef data, size_t amount, const uint8_t* bytes) { diff --git a/OSX/sec/Security/Regressions/rk_01_recoverykey.m b/OSX/sec/Security/Regressions/rk_01_recoverykey.m index 8dd2c9d6..e0ef725a 100644 --- a/OSX/sec/Security/Regressions/rk_01_recoverykey.m +++ b/OSX/sec/Security/Regressions/rk_01_recoverykey.m @@ -7,7 +7,7 @@ #include #include -#include "SecRecoveryKey.h" +#include #include "shared_regressions.h" int rk_01_recoverykey(int argc, char *const *argv) @@ -45,7 +45,7 @@ int rk_01_recoverykey(int argc, char *const *argv) NSString *knownPublicKey = obj[@"publicKey"]; NSString *knownPrivateKey = obj[@"privateKey"]; NSString *knownPassword = obj[@"password"]; -#if !(defined(__i386__) || TARGET_IPHONE_SIMULATOR || TARGET_OS_BRIDGE) +#if !(defined(__i386__) || TARGET_OS_SIMULATOR || TARGET_OS_BRIDGE) NSString *knownMasterID = obj[@"masterID"]; #endif @@ -68,7 +68,7 @@ int rk_01_recoverykey(int argc, char *const *argv) ok(recoveryPassword, "got account recovery password"); ok([recoveryPassword isEqualToString:knownPassword], "password same: %@", recoveryPassword); -#if defined(__i386__) || TARGET_IPHONE_SIMULATOR || TARGET_OS_BRIDGE +#if defined(__i386__) || TARGET_OS_SIMULATOR || TARGET_OS_BRIDGE ok(true, "skipping recovery verifier test for unsupported platform"); #else NSDictionary *recoveryVerifier = SecRKCopyAccountRecoveryVerifier(recoveryKey, NULL); diff --git a/OSX/sec/Security/Regressions/secitem/si-15-certificate.c b/OSX/sec/Security/Regressions/secitem/si-15-certificate.c deleted file mode 100644 index b57f6b06..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-15-certificate.c +++ /dev/null @@ -1,1265 +0,0 @@ -/* - * Copyright (c) 2008-2010,2012 Apple Inc. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "shared_regressions.h" - -/* - Apple Inc. CA -*/ -static const uint8_t _c0[] = { - 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, -}; - -/* - subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign - issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - serial=254B8A853842CCE358F8C5DDAE226EA4 -*/ -static const uint8_t _c1[] = { - 0x30, 0x82, 0x03, 0x83, 0x30, 0x82, 0x02, 0xec, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x25, - 0x4b, 0x8a, 0x85, 0x38, 0x42, 0xcc, 0xe3, 0x58, - 0xf8, 0xc5, 0xdd, 0xae, 0x22, 0x6e, 0xa4, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x5f, - 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, 0x37, - 0x30, 0x35, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, - 0x2e, 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, 0x30, - 0x1e, 0x17, 0x0d, 0x39, 0x37, 0x30, 0x34, 0x31, - 0x37, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, - 0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, 0x32, 0x34, - 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, - 0x81, 0xba, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, - 0x55, 0x04, 0x0a, 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, 0x17, 0x30, 0x15, 0x06, - 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0e, 0x56, 0x65, - 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x2c, 0x20, - 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x33, 0x30, 0x31, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x2a, 0x56, - 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, - 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x20, 0x43, 0x41, 0x20, - 0x2d, 0x20, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x20, - 0x33, 0x31, 0x49, 0x30, 0x47, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x40, 0x77, 0x77, 0x77, 0x2e, - 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, - 0x20, 0x49, 0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, - 0x62, 0x79, 0x20, 0x52, 0x65, 0x66, 0x2e, 0x20, - 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c, 0x49, 0x54, - 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63, - 0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, - 0x53, 0x69, 0x67, 0x6e, 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, 0xd8, 0x82, 0x80, 0xe8, 0xd6, 0x19, 0x02, - 0x7d, 0x1f, 0x85, 0x18, 0x39, 0x25, 0xa2, 0x65, - 0x2b, 0xe1, 0xbf, 0xd4, 0x05, 0xd3, 0xbc, 0xe6, - 0x36, 0x3b, 0xaa, 0xf0, 0x4c, 0x6c, 0x5b, 0xb6, - 0xe7, 0xaa, 0x3c, 0x73, 0x45, 0x55, 0xb2, 0xf1, - 0xbd, 0xea, 0x97, 0x42, 0xed, 0x9a, 0x34, 0x0a, - 0x15, 0xd4, 0xa9, 0x5c, 0xf5, 0x40, 0x25, 0xdd, - 0xd9, 0x07, 0xc1, 0x32, 0xb2, 0x75, 0x6c, 0xc4, - 0xca, 0xbb, 0xa3, 0xfe, 0x56, 0x27, 0x71, 0x43, - 0xaa, 0x63, 0xf5, 0x30, 0x3e, 0x93, 0x28, 0xe5, - 0xfa, 0xf1, 0x09, 0x3b, 0xf3, 0xb7, 0x4d, 0x4e, - 0x39, 0xf7, 0x5c, 0x49, 0x5a, 0xb8, 0xc1, 0x1d, - 0xd3, 0xb2, 0x8a, 0xfe, 0x70, 0x30, 0x95, 0x42, - 0xcb, 0xfe, 0x2b, 0x51, 0x8b, 0x5a, 0x3c, 0x3a, - 0xf9, 0x22, 0x4f, 0x90, 0xb2, 0x02, 0xa7, 0x53, - 0x9c, 0x4f, 0x34, 0xe7, 0xab, 0x04, 0xb2, 0x7b, - 0x6f, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, - 0xe3, 0x30, 0x81, 0xe0, 0x30, 0x0f, 0x06, 0x03, - 0x55, 0x1d, 0x13, 0x04, 0x08, 0x30, 0x06, 0x01, - 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x44, 0x06, - 0x03, 0x55, 0x1d, 0x20, 0x04, 0x3d, 0x30, 0x3b, - 0x30, 0x39, 0x06, 0x0b, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x45, 0x01, 0x07, 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, 0x76, 0x65, 0x72, 0x69, 0x73, - 0x69, 0x67, 0x6e, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x43, 0x50, 0x53, 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, 0x09, 0x60, 0x86, 0x48, 0x01, - 0x86, 0xf8, 0x42, 0x04, 0x01, 0x06, 0x0a, 0x60, - 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45, 0x01, 0x08, - 0x01, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, - 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x11, - 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, - 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x01, - 0x06, 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, 0x76, - 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x70, 0x63, 0x61, 0x33, - 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, - 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x08, - 0x01, 0xec, 0xe4, 0x68, 0x94, 0x03, 0x42, 0xf1, - 0x73, 0xf1, 0x23, 0xa2, 0x3a, 0xde, 0xe9, 0xf1, - 0xda, 0xc6, 0x54, 0xc4, 0x23, 0x3e, 0x86, 0xea, - 0xcf, 0x6a, 0x3a, 0x33, 0xab, 0xea, 0x9c, 0x04, - 0x14, 0x07, 0x36, 0x06, 0x0b, 0xf9, 0x88, 0x6f, - 0xd5, 0x13, 0xee, 0x29, 0x2b, 0xc3, 0xe4, 0x72, - 0x8d, 0x44, 0xed, 0xd1, 0xac, 0x20, 0x09, 0x2d, - 0xe1, 0xf6, 0xe1, 0x19, 0x05, 0x38, 0xb0, 0x3d, - 0x0f, 0x9f, 0x7f, 0xf8, 0x9e, 0x02, 0xdc, 0x86, - 0x02, 0x86, 0x61, 0x4e, 0x26, 0x5f, 0x5e, 0x9f, - 0x92, 0x1e, 0x0c, 0x24, 0xa4, 0xf5, 0xd0, 0x70, - 0x13, 0xcf, 0x26, 0xc3, 0x43, 0x3d, 0x49, 0x1d, - 0x9e, 0x82, 0x2e, 0x52, 0x5f, 0xbc, 0x3e, 0xc6, - 0x66, 0x29, 0x01, 0x8e, 0x4e, 0x92, 0x2c, 0xbc, - 0x46, 0x75, 0x03, 0x82, 0xac, 0x73, 0xe9, 0xd9, - 0x7e, 0x0b, 0x67, 0xef, 0x54, 0x52, 0x1a -}; - - -/* - subject= /C=US/O=University of Virginia/OU=UVA Standard PKI User/emailAddress=kmm6b@Virginia.EDU/CN=Keith M. Moores 10 - issuer= /C=US/ST=Virginia/L=Charlottesville/O=University of Virginia/emailAddress=pkimaster@virginia.edu/CN=UVA Standard Assurance SKP 1 - serial=0C6D -*/ -static const uint8_t _c2[] = { - 0x30, 0x82, 0x05, 0x56, 0x30, 0x82, 0x04, 0xbf, - 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x0c, - 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, - 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, - 0x30, 0x81, 0xa9, 0x31, 0x0b, 0x30, 0x09, 0x06, - 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, - 0x08, 0x13, 0x08, 0x56, 0x69, 0x72, 0x67, 0x69, - 0x6e, 0x69, 0x61, 0x31, 0x18, 0x30, 0x16, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x0f, 0x43, 0x68, - 0x61, 0x72, 0x6c, 0x6f, 0x74, 0x74, 0x65, 0x73, - 0x76, 0x69, 0x6c, 0x6c, 0x65, 0x31, 0x1f, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, - 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x74, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x56, 0x69, - 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x31, 0x25, - 0x30, 0x23, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x16, 0x70, - 0x6b, 0x69, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, - 0x40, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, - 0x61, 0x2e, 0x65, 0x64, 0x75, 0x31, 0x25, 0x30, - 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x1c, - 0x55, 0x56, 0x41, 0x20, 0x53, 0x74, 0x61, 0x6e, - 0x64, 0x61, 0x72, 0x64, 0x20, 0x41, 0x73, 0x73, - 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x20, 0x53, - 0x4b, 0x50, 0x20, 0x31, 0x30, 0x1e, 0x17, 0x0d, - 0x30, 0x34, 0x30, 0x31, 0x30, 0x38, 0x31, 0x37, - 0x32, 0x35, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x30, - 0x35, 0x30, 0x31, 0x30, 0x38, 0x31, 0x37, 0x32, - 0x35, 0x30, 0x30, 0x5a, 0x30, 0x81, 0x8e, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, - 0x13, 0x02, 0x55, 0x53, 0x31, 0x1f, 0x30, 0x1d, - 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16, 0x55, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, - 0x79, 0x20, 0x6f, 0x66, 0x20, 0x56, 0x69, 0x72, - 0x67, 0x69, 0x6e, 0x69, 0x61, 0x31, 0x1e, 0x30, - 0x1c, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x15, - 0x55, 0x56, 0x41, 0x20, 0x53, 0x74, 0x61, 0x6e, - 0x64, 0x61, 0x72, 0x64, 0x20, 0x50, 0x4b, 0x49, - 0x20, 0x55, 0x73, 0x65, 0x72, 0x31, 0x21, 0x30, - 0x1f, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x09, 0x01, 0x16, 0x12, 0x6b, 0x6d, - 0x6d, 0x36, 0x62, 0x40, 0x56, 0x69, 0x72, 0x67, - 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x45, 0x44, 0x55, - 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x12, 0x4b, 0x65, 0x69, 0x74, 0x68, - 0x20, 0x4d, 0x2e, 0x20, 0x4d, 0x6f, 0x6f, 0x72, - 0x65, 0x73, 0x20, 0x31, 0x30, 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, 0xb4, 0xf9, 0x1b, 0xda, 0x10, 0x01, - 0x47, 0x96, 0xb4, 0xea, 0xb2, 0x35, 0xbb, 0x7e, - 0x69, 0x69, 0xd9, 0x49, 0x2c, 0x36, 0x3a, 0x27, - 0x55, 0x6e, 0x11, 0xb1, 0xdf, 0x13, 0x54, 0xf2, - 0x66, 0xa5, 0x98, 0x3a, 0xfd, 0x7e, 0xda, 0x6d, - 0x12, 0xb7, 0x06, 0xaa, 0xde, 0x55, 0x50, 0x04, - 0xf5, 0x91, 0x27, 0xc7, 0x4d, 0x85, 0x91, 0xd9, - 0xc5, 0xd6, 0x88, 0xc6, 0x33, 0x40, 0x83, 0xc0, - 0xe4, 0x83, 0xe2, 0x9f, 0x49, 0xfb, 0xc1, 0x1f, - 0xdb, 0xd9, 0xf4, 0xd4, 0x32, 0x2e, 0x3a, 0xe9, - 0xb4, 0x12, 0x5d, 0x58, 0x2a, 0x65, 0x4e, 0xc7, - 0x09, 0x59, 0xfc, 0x2b, 0x0d, 0xda, 0x6a, 0xc3, - 0x9f, 0x32, 0x7d, 0xf2, 0xfc, 0xf4, 0x3e, 0xb8, - 0x63, 0xbc, 0x13, 0x74, 0xc6, 0x0e, 0x76, 0x3a, - 0x7a, 0xe9, 0x93, 0x97, 0x7f, 0xc8, 0x2b, 0x33, - 0x9f, 0xd8, 0x59, 0xef, 0xc0, 0x0a, 0x2e, 0xd3, - 0xd9, 0x69, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x82, 0x02, 0xa4, 0x30, 0x82, 0x02, 0xa0, 0x30, - 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 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, - 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x03, 0x04, 0x30, 0x1d, 0x06, 0x03, 0x55, - 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x4d, 0xe0, - 0xe1, 0x57, 0xb6, 0x91, 0x7a, 0x34, 0x99, 0x7a, - 0xe5, 0x2a, 0xd6, 0xae, 0x0a, 0x75, 0x05, 0x73, - 0x5d, 0x30, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, - 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, - 0x80, 0x14, 0x2c, 0xb7, 0xe3, 0xa6, 0x09, 0x68, - 0x85, 0x90, 0x58, 0x8e, 0x2d, 0xd5, 0x3a, 0xef, - 0x93, 0x02, 0x2a, 0x4c, 0x85, 0x62, 0x30, 0x41, - 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x3a, 0x30, - 0x38, 0xa0, 0x22, 0x06, 0x0a, 0x2b, 0x06, 0x01, - 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03, 0xa0, - 0x14, 0x0c, 0x12, 0x6b, 0x6d, 0x6d, 0x36, 0x62, - 0x40, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, - 0x61, 0x2e, 0x45, 0x44, 0x55, 0x81, 0x12, 0x6b, - 0x6d, 0x6d, 0x36, 0x62, 0x40, 0x56, 0x69, 0x72, - 0x67, 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x45, 0x44, - 0x55, 0x30, 0x2f, 0x06, 0x03, 0x55, 0x1d, 0x12, - 0x04, 0x28, 0x30, 0x26, 0x81, 0x16, 0x70, 0x6b, - 0x69, 0x6d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x40, - 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, - 0x2e, 0x45, 0x44, 0x55, 0x82, 0x0c, 0x56, 0x69, - 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x45, - 0x44, 0x55, 0x30, 0x82, 0x01, 0x5c, 0x06, 0x03, - 0x55, 0x1d, 0x1f, 0x04, 0x82, 0x01, 0x53, 0x30, - 0x82, 0x01, 0x4f, 0x30, 0x74, 0xa0, 0x72, 0xa0, - 0x70, 0x86, 0x6e, 0x6c, 0x64, 0x61, 0x70, 0x3a, - 0x2f, 0x2f, 0x6c, 0x64, 0x61, 0x70, 0x2e, 0x70, - 0x6b, 0x69, 0x2e, 0x76, 0x69, 0x72, 0x67, 0x69, - 0x6e, 0x69, 0x61, 0x2e, 0x65, 0x64, 0x75, 0x2f, - 0x63, 0x3d, 0x55, 0x53, 0x2c, 0x6f, 0x3d, 0x55, - 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, 0x74, - 0x79, 0x25, 0x32, 0x30, 0x6f, 0x66, 0x25, 0x32, - 0x30, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, - 0x61, 0x2c, 0x6f, 0x75, 0x3d, 0x55, 0x56, 0x41, - 0x25, 0x32, 0x30, 0x53, 0x74, 0x61, 0x6e, 0x64, - 0x61, 0x72, 0x64, 0x25, 0x32, 0x30, 0x41, 0x73, - 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x25, - 0x32, 0x30, 0x53, 0x4b, 0x50, 0x25, 0x32, 0x30, - 0x31, 0x2c, 0x63, 0x6e, 0x3d, 0x30, 0x43, 0x36, - 0x44, 0x30, 0x74, 0xa0, 0x72, 0xa0, 0x70, 0x86, - 0x6e, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, - 0x6c, 0x64, 0x61, 0x70, 0x2e, 0x70, 0x6b, 0x69, - 0x2e, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, - 0x61, 0x2e, 0x65, 0x64, 0x75, 0x2f, 0x63, 0x6e, - 0x3d, 0x30, 0x43, 0x36, 0x44, 0x2c, 0x6f, 0x75, - 0x3d, 0x55, 0x56, 0x41, 0x25, 0x32, 0x30, 0x53, - 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x25, - 0x32, 0x30, 0x41, 0x73, 0x73, 0x75, 0x72, 0x61, - 0x6e, 0x63, 0x65, 0x25, 0x32, 0x30, 0x53, 0x4b, - 0x50, 0x25, 0x32, 0x30, 0x31, 0x2c, 0x6f, 0x3d, - 0x55, 0x6e, 0x69, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x74, 0x79, 0x25, 0x32, 0x30, 0x6f, 0x66, 0x25, - 0x32, 0x30, 0x56, 0x69, 0x72, 0x67, 0x69, 0x6e, - 0x69, 0x61, 0x2c, 0x63, 0x3d, 0x55, 0x53, 0x30, - 0x61, 0xa0, 0x5f, 0xa0, 0x5d, 0x86, 0x5b, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, - 0x77, 0x2e, 0x70, 0x6b, 0x69, 0x2e, 0x76, 0x69, - 0x72, 0x67, 0x69, 0x6e, 0x69, 0x61, 0x2e, 0x65, - 0x64, 0x75, 0x2f, 0x63, 0x67, 0x69, 0x2d, 0x62, - 0x69, 0x6e, 0x2f, 0x67, 0x65, 0x74, 0x2d, 0x63, - 0x72, 0x6c, 0x3f, 0x6f, 0x75, 0x3d, 0x55, 0x56, - 0x41, 0x25, 0x32, 0x30, 0x53, 0x74, 0x61, 0x6e, - 0x64, 0x61, 0x72, 0x64, 0x25, 0x32, 0x30, 0x41, - 0x73, 0x73, 0x75, 0x72, 0x61, 0x6e, 0x63, 0x65, - 0x25, 0x32, 0x30, 0x53, 0x4b, 0x50, 0x25, 0x32, - 0x30, 0x31, 0x26, 0x63, 0x6e, 0x3d, 0x30, 0x43, - 0x36, 0x44, 0x30, 0x53, 0x06, 0x03, 0x55, 0x1d, - 0x20, 0x04, 0x4c, 0x30, 0x4a, 0x30, 0x48, 0x06, - 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xb4, 0x76, - 0x01, 0x01, 0x30, 0x3b, 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, 0x70, 0x6b, 0x69, - 0x2e, 0x76, 0x69, 0x72, 0x67, 0x69, 0x6e, 0x69, - 0x61, 0x2e, 0x65, 0x64, 0x75, 0x2f, 0x73, 0x74, - 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x2f, 0x63, - 0x70, 0x73, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, - 0x81, 0x00, 0x9f, 0xf2, 0x7f, 0x51, 0x97, 0x2c, - 0xe6, 0x8f, 0x50, 0xba, 0x75, 0xd8, 0x9c, 0x77, - 0x5e, 0x2a, 0xe9, 0xbe, 0x18, 0x37, 0x7f, 0x18, - 0x86, 0xbb, 0x9d, 0x22, 0xf2, 0xf9, 0x3e, 0x22, - 0x00, 0x0b, 0xf2, 0x41, 0x6b, 0x08, 0x17, 0xbc, - 0x7a, 0xc4, 0xc9, 0x99, 0xa0, 0xbd, 0x53, 0x8d, - 0x52, 0xdb, 0xcc, 0xd0, 0x88, 0x14, 0x2a, 0x05, - 0x93, 0xcd, 0xf3, 0xa0, 0xf3, 0xb9, 0xdb, 0x35, - 0x5c, 0xec, 0x24, 0xe8, 0x08, 0xbe, 0x4e, 0xa1, - 0xa2, 0x54, 0x41, 0xbc, 0xbe, 0x7b, 0x22, 0xf4, - 0x03, 0x7d, 0xd0, 0xfb, 0x25, 0x8d, 0xf5, 0xa9, - 0x04, 0x14, 0xe9, 0xe3, 0x3e, 0x3f, 0x13, 0x6f, - 0x89, 0x72, 0x76, 0x41, 0x67, 0x8a, 0x48, 0x2a, - 0x36, 0xf0, 0xe6, 0xb9, 0x33, 0x35, 0x88, 0xda, - 0x27, 0x9d, 0xf9, 0x5d, 0x42, 0x04, 0x6f, 0x7d, - 0x60, 0x53, 0x86, 0xf2, 0xf4, 0x3b, 0x3d, 0xbe, - 0x1d, 0x99, -}; - -/* subject:/C=US/O=Apple Computer, Inc./OU=mac.com/CN=phased/description=.Mac Sharing Certificate */ -/* issuer :/C=US/O=Apple Computer, Inc./OU=Apple Computer Certificate Authority/CN=Apple .Mac Certificate Authority */ -static unsigned char _phased_c3[1376]={ -0x30,0x82,0x05,0x5C,0x30,0x82,0x04,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x20, -0x7D,0xC7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, -0x00,0x30,0x81,0x86,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, -0x53,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x41,0x70,0x70,0x6C, -0x65,0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,0x65,0x72,0x2C,0x20,0x49,0x6E,0x63,0x2E, -0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x41,0x70,0x70,0x6C,0x65, -0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66, -0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31, -0x29,0x30,0x27,0x06,0x03,0x55,0x04,0x03,0x13,0x20,0x41,0x70,0x70,0x6C,0x65,0x20, -0x2E,0x4D,0x61,0x63,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65, -0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x37, -0x31,0x30,0x32,0x38,0x31,0x38,0x35,0x34,0x35,0x33,0x5A,0x17,0x0D,0x30,0x38,0x31, -0x30,0x32,0x38,0x31,0x38,0x35,0x34,0x35,0x33,0x5A,0x30,0x72,0x31,0x0B,0x30,0x09, -0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55, -0x04,0x0A,0x13,0x14,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x6F,0x6D,0x70,0x75,0x74, -0x65,0x72,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04, -0x0B,0x13,0x07,0x6D,0x61,0x63,0x2E,0x63,0x6F,0x6D,0x31,0x0F,0x30,0x0D,0x06,0x03, -0x55,0x04,0x03,0x13,0x06,0x70,0x68,0x61,0x73,0x65,0x64,0x31,0x21,0x30,0x1F,0x06, -0x03,0x55,0x04,0x0D,0x13,0x18,0x2E,0x4D,0x61,0x63,0x20,0x53,0x68,0x61,0x72,0x69, -0x6E,0x67,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,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,0xFB,0x0E,0x62,0xD3, -0xE2,0xCC,0xC7,0x54,0x6A,0x4F,0x9C,0x4E,0x40,0x9D,0x30,0x3D,0x60,0x86,0x00,0x7C, -0x33,0x0C,0x2E,0x2E,0x45,0xDF,0xBE,0xEB,0x94,0xE7,0xD6,0xBE,0x6B,0x0F,0x7B,0x88, -0x3C,0x02,0xA7,0x25,0x5E,0x18,0xC6,0x97,0xF0,0x0C,0xDD,0x89,0x22,0x27,0x9C,0x85, -0x25,0x36,0x95,0x61,0x26,0xE7,0x6C,0x7E,0x41,0xDE,0xFF,0x5D,0x77,0xCB,0xE6,0x05, -0xB0,0xAD,0x77,0xC9,0xFC,0xA5,0xF1,0x82,0x1A,0xB4,0xE4,0x26,0x8D,0x1B,0xC3,0xE2, -0xEF,0x6A,0xE0,0xEE,0xF3,0x38,0x27,0xE1,0x73,0x9E,0xD0,0x93,0x6A,0xA6,0xD5,0xD1, -0xEC,0xE5,0x0D,0x4B,0x3A,0x42,0x8C,0xF1,0xE1,0x24,0x0A,0x02,0x0D,0x22,0xAE,0xEC, -0x47,0xDA,0xFA,0x6B,0x12,0x50,0x47,0x2E,0x4A,0xD8,0x9F,0x02,0x03,0x01,0x00,0x01, -0xA3,0x82,0x02,0x68,0x30,0x82,0x02,0x64,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,0x03,0x88,0x30,0x28,0x06,0x03,0x55,0x1D,0x25,0x04,0x21,0x30, -0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0A,0x2A,0x86,0x48, -0x86,0xF7,0x63,0x64,0x03,0x02,0x01,0x06,0x07,0x2B,0x06,0x01,0x05,0x02,0x03,0x04, -0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x3D,0xD9,0xDD,0x8F,0x5B, -0x5E,0xA3,0x3A,0x8C,0x89,0x7F,0x8A,0x85,0x26,0xA7,0x84,0x0E,0xF3,0x0D,0x82,0x30, -0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7A,0x7D,0x90,0xB1, -0x30,0x59,0x08,0x92,0x91,0xF9,0x53,0xB9,0x71,0x1D,0x35,0x33,0x67,0x34,0x8B,0xD5, -0x30,0x81,0xAD,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0xA0, -0x30,0x81,0x9D,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86, -0x1C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x65,0x72,0x74,0x69,0x6E,0x66,0x6F, -0x2E,0x6D,0x61,0x63,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x44,0x06, -0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x38,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,0x63,0x61,0x73,0x69,0x67,0x6E,0x65,0x72,0x73,0x2E,0x68, -0x74,0x6D,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x12,0x86,0x24,0x68,0x74,0x74,0x70, -0x3A,0x2F,0x2F,0x63,0x65,0x72,0x74,0x69,0x6E,0x66,0x6F,0x2E,0x6D,0x61,0x63,0x2E, -0x63,0x6F,0x6D,0x2F,0x64,0x6F,0x74,0x4D,0x61,0x63,0x43,0x41,0x2E,0x63,0x65,0x72, -0x30,0x82,0x01,0x28,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x1F,0x30,0x82,0x01, -0x1B,0x30,0x82,0x01,0x17,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x02, -0x30,0x82,0x01,0x08,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, -0x16,0x34,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,0x74,0x65,0x72,0x6D, -0x73,0x2E,0x68,0x74,0x6D,0x6C,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, -0x30,0x48,0x04,0xA8,0x63,0x5A,0x7A,0xF9,0xEA,0x8B,0xF7,0x7F,0xF6,0x27,0x21,0x02, -0xE2,0x83,0xC8,0x64,0x99,0xB3,0x40,0x71,0x97,0x30,0xE2,0x92,0xD4,0x58,0xB8,0xD8, -0xF1,0xAA,0x30,0x59,0x75,0x4C,0x67,0x16,0xF8,0x38,0xBD,0xD7,0xF4,0xEA,0x03,0xB5, -0xE6,0x42,0xF8,0x95,0xBA,0x5B,0xE4,0x3C,0xA8,0x75,0x6C,0x05,0xFB,0x3C,0x3C,0xE3, -0x08,0x90,0x5F,0x6D,0x7E,0x3A,0xEA,0xBD,0x19,0x52,0x82,0x3B,0x9C,0x7F,0x64,0x15, -0x3A,0xCA,0x54,0x52,0x57,0xEB,0x53,0x09,0xE8,0x05,0x53,0x79,0xB9,0x7D,0x51,0xA3, -0x8E,0x31,0xF1,0xE5,0x5E,0xC6,0xA6,0x81,0x11,0x68,0x0A,0x17,0xD5,0xA0,0xBB,0x49, -0xF3,0x4E,0x59,0x1D,0xCB,0xCA,0x3E,0x09,0x64,0x2F,0x27,0x6C,0xCA,0x39,0x50,0x73, -0x42,0x5C,0x9D,0xE2,0x92,0x45,0x37,0x7F,0x02,0xF0,0x2B,0xA0,0xDD,0x1C,0x02,0xDC, -0x77,0xA9,0x0C,0xEA,0x14,0xAE,0xDE,0x81,0xDF,0x3E,0x31,0x59,0xF6,0xF7,0xE5,0x7F, -0xBC,0x7C,0xFD,0xE8,0x22,0xBE,0x9A,0x78,0xDD,0xFD,0x32,0x7F,0xE0,0xEC,0x0F,0x8D, -0x4D,0xB5,0xDE,0xF6,0x91,0x4B,0xAD,0xDB,0x7D,0xF9,0x07,0xB8,0x2B,0x0E,0xB5,0x58, -0x05,0xA2,0x85,0xF6,0x72,0x0E,0xCB,0x63,0x4E,0x8F,0xBF,0xD6,0x33,0x6F,0xF3,0xC2, -0x53,0xFA,0x67,0x5D,0x19,0xA8,0x49,0x1C,0x05,0x5D,0xAF,0x6C,0xDC,0x14,0x37,0xD5, -0x65,0x42,0x24,0x3B,0x69,0xC9,0x78,0x3F,0x4B,0x0E,0xAF,0x13,0x37,0x00,0x1E,0x6B, -0xCE,0xB9,0xCC,0xAA,0x99,0x1A,0xB7,0x5A,0x27,0xB9,0xE9,0xD6,0x87,0x0A,0xEB,0x77, -}; - -static unsigned char pem[] = "\n" -"-----BEGIN CERTIFICATE-----\n" -"MIIDSzCCAjOgAwIBAgIJAPsB+wAAAAABMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNV\n" -"BAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSYwJAYDVQQLEx1BcHBsZSBDZXJ0\n" -"aWZpY2F0aW9uIEF1dGhvcml0eTEyMDAGA1UEAxMpQXBwbGUgU2VjdXJlIEJvb3Qg\n" -"Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcwMTA2MDUyMDUyWhcNMTcwMTA2\n" -"MDUyMDUyWjB0MQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEyMDAG\n" -"A1UECxMpQXBwbGUgU2VjdXJlIEJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx\n" -"HDAaBgNVBAMTE1M1TDg5MDAgU2VjdXJlIEJvb3QwgZ8wDQYJKoZIhvcNAQEBBQAD\n" -"gY0AMIGJAoGBAMSrg/5uSm6EaOPbN2sedX5F31i+4x5BLd8cVbopszz/9OJZz/RD\n" -"tWbVkSh2O7PZbvfYwwHB6D3pebAA1S9rakwaKO7hKyKzHqpHeiqu+ECdmPGBRhFf\n" -"16zQL/pXzEnHn4IBfHcG5O49VqI8TK9pMZiqOQ4nh5H5mYIBImcaQ7frAgMBAAGj\n" -"WjBYMAsGA1UdDwQEAwIHgDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQZ39dDpsNXFu2G\n" -"Qt2ylAihau3f3jAfBgNVHSMEGDAWgBRJPTZTydcV4YZhTqyrqxhWY13DxjANBgkq\n" -"hkiG9w0BAQUFAAOCAQEAlAHI8JncOxR8kSzIuN6jCY22DgiZYahvO7H3f68w3QO3\n" -"NE8Cp/UCECv+pQmlMuJPMAYzfLwGtoLhpq6BlCQXEc4KYhjGh5aicdXBkZDf+rA0\n" -"p1KphAd8c2UEIAWBbqU87q1FbDSJBw3YKN7C/I4qGnzUrWSpBbq6musM0QzO/uUZ\n" -"3R1QsfpicZ+nT/1WmlJSAwtoQsBjNAgMauhRLAJc/fCPi8TqONju/xxbGDYJ/cQs\n" -"bCGfszrUSeGYu4ryxeyNuu2L8gluHUKbhfZ7J1XYgIsvoCnk5E5hWJDhpIyywylb\n" -"9F/uRNib8zb0L80S64vAWC4m4QUJ3iLmTfIsk+NYPQ==\n" -"-----END CERTIFICATE-----\n"; - -static unsigned char _elektron_v1_cert_der[] = { - 0x30, 0x82, 0x02, 0x71, 0x30, 0x82, 0x01, 0xda, 0x02, 0x01, 0x01, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, - 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, - 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x73, 0x61, 0x6e, 0x20, 0x6a, 0x6f, - 0x73, 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, - 0x04, 0x62, 0x72, 0x61, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, - 0x04, 0x0b, 0x13, 0x1e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, - 0x20, 0x62, 0x79, 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, - 0x20, 0x76, 0x32, 0x2e, 0x30, 0x2e, 0x31, 0x38, 0x35, 0x32, 0x31, 0x19, - 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x62, 0x72, 0x61, - 0x64, 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x43, - 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x33, 0x31, 0x32, 0x32, 0x33, 0x31, - 0x31, 0x34, 0x36, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x32, - 0x32, 0x32, 0x31, 0x31, 0x34, 0x36, 0x30, 0x37, 0x5a, 0x30, 0x81, 0x80, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, - 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, - 0x63, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, - 0x08, 0x73, 0x61, 0x6e, 0x20, 0x6a, 0x6f, 0x73, 0x65, 0x31, 0x0d, 0x30, - 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x04, 0x62, 0x72, 0x61, 0x64, - 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x50, - 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x45, - 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x76, 0x32, 0x2e, 0x30, - 0x2e, 0x31, 0x38, 0x35, 0x32, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, - 0x04, 0x03, 0x13, 0x10, 0x62, 0x72, 0x61, 0x64, 0x20, 0x45, 0x6c, 0x65, - 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x43, 0x41, 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, 0xe0, 0xab, 0x3a, 0x05, 0x8d, 0xed, 0x81, 0x73, 0xa8, 0x76, 0x9c, - 0x14, 0x07, 0x50, 0x4b, 0x56, 0x8f, 0xfe, 0x88, 0xba, 0xec, 0xde, 0xab, - 0x9a, 0x5d, 0x49, 0x23, 0x3b, 0x87, 0x4f, 0x50, 0x59, 0x8d, 0x0f, 0x78, - 0xd0, 0x61, 0x98, 0x28, 0x9d, 0x1d, 0x39, 0xbf, 0x92, 0x62, 0xda, 0x21, - 0xf7, 0xb1, 0x32, 0x6a, 0x5d, 0x73, 0x1c, 0x1d, 0x36, 0xba, 0xf7, 0x3c, - 0xff, 0xda, 0xd9, 0xff, 0xf0, 0xbd, 0x62, 0x1d, 0xde, 0x6d, 0xc7, 0x76, - 0x93, 0xdd, 0x3a, 0x90, 0x2b, 0x97, 0xab, 0x86, 0xea, 0x48, 0xb5, 0x70, - 0xe7, 0xe1, 0xa2, 0x5c, 0x61, 0x1a, 0x7d, 0x48, 0x4d, 0x83, 0x42, 0x73, - 0x70, 0xaf, 0x5d, 0xcf, 0x8c, 0x26, 0xb4, 0x83, 0xff, 0x77, 0xd5, 0x64, - 0xe0, 0x14, 0x52, 0x20, 0xa2, 0xe9, 0xc5, 0x8c, 0x70, 0xb5, 0x6f, 0xf5, - 0x6d, 0x31, 0x2b, 0xcb, 0x1d, 0xad, 0xf4, 0xb2, 0x27, 0x02, 0x03, 0x01, - 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x74, 0x49, 0x79, - 0x14, 0xc0, 0x68, 0xd7, 0x9d, 0xfd, 0x35, 0x6a, 0xda, 0xa0, 0x1d, 0x46, - 0x0a, 0xc6, 0x1b, 0x51, 0x4b, 0xdf, 0x27, 0xd6, 0x14, 0x1a, 0xcf, 0xf1, - 0xd0, 0xe2, 0x1b, 0x92, 0x39, 0x33, 0x98, 0x13, 0xc2, 0x6e, 0x97, 0xed, - 0x2b, 0x1b, 0xfc, 0x28, 0x8a, 0x93, 0xf9, 0xe5, 0xe1, 0xf0, 0xbf, 0xf8, - 0xa3, 0x5e, 0x08, 0x9c, 0x9f, 0x61, 0x7d, 0xb9, 0xe7, 0x14, 0x0e, 0x6d, - 0x07, 0x3e, 0x35, 0x12, 0xd4, 0x98, 0x2e, 0x0a, 0x9c, 0x5c, 0xb9, 0xbf, - 0x20, 0x29, 0x01, 0x55, 0x82, 0x86, 0xa7, 0xcb, 0x97, 0x8f, 0xbb, 0xd8, - 0x2b, 0xbd, 0x40, 0xd3, 0x1a, 0xa7, 0xb1, 0x66, 0x5c, 0xe5, 0x9a, 0x7b, - 0x39, 0xb7, 0x73, 0x49, 0x2c, 0x44, 0x8c, 0x79, 0x5b, 0xb5, 0x18, 0x41, - 0xd0, 0xf1, 0x4b, 0x6d, 0xc5, 0x1a, 0xf8, 0x51, 0xea, 0x99, 0x0d, 0x85, - 0x1b, 0xbe, 0x16, 0x56, 0x18 -}; - -#if 0 // currently unused. -static unsigned int _elektron_v1_cert_der_len = 629; -#endif - -static unsigned char _wapi_as_der[] = { - 0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0x6c, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x12, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xd7, - 0x63, 0x01, 0x01, 0x01, 0x05, 0x00, 0x30, 0x1d, 0x31, 0x0c, 0x30, 0x0a, - 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, 0x4d, 0x43, 0x31, 0x0d, - 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x57, 0x41, 0x50, - 0x49, 0x30, 0x1e, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, - 0x30, 0x30, 0x30, 0x31, 0x38, 0x5a, 0x17, 0x0d, 0x39, 0x30, 0x30, 0x31, - 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x31, 0x38, 0x5a, 0x30, 0x1d, 0x31, - 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, 0x4d, - 0x43, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, - 0x57, 0x41, 0x50, 0x49, 0x30, 0x4a, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, - 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x09, 0x2a, 0x81, 0x1c, 0xd7, 0x63, - 0x01, 0x01, 0x02, 0x01, 0x03, 0x32, 0x00, 0x04, 0x74, 0xd9, 0x78, 0x91, - 0xc4, 0xd3, 0xb5, 0x9e, 0xb0, 0xa9, 0x9e, 0xf1, 0x01, 0x5b, 0xd7, 0x7f, - 0x79, 0x9a, 0x02, 0xe5, 0x87, 0x65, 0xa1, 0x0d, 0x04, 0xc9, 0x06, 0xdb, - 0xf6, 0x12, 0x24, 0x05, 0x9d, 0x1c, 0x51, 0x00, 0x75, 0x58, 0x46, 0x11, - 0xe3, 0xdc, 0x71, 0x02, 0x69, 0x43, 0x37, 0x61, 0xa3, 0x81, 0xa9, 0x30, - 0x81, 0xa6, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, - 0x14, 0x08, 0xa9, 0x47, 0x65, 0xf2, 0x39, 0xa9, 0xe8, 0x8b, 0xd1, 0x75, - 0x43, 0xce, 0x8c, 0x1c, 0xc0, 0xec, 0x99, 0xae, 0xad, 0x30, 0x45, 0x06, - 0x03, 0x55, 0x1d, 0x23, 0x04, 0x3e, 0x30, 0x3c, 0x80, 0x14, 0x08, 0xa9, - 0x47, 0x65, 0xf2, 0x39, 0xa9, 0xe8, 0x8b, 0xd1, 0x75, 0x43, 0xce, 0x8c, - 0x1c, 0xc0, 0xec, 0x99, 0xae, 0xad, 0xa1, 0x21, 0xa4, 0x1f, 0x30, 0x1d, - 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, - 0x4d, 0x43, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, - 0x04, 0x57, 0x41, 0x50, 0x49, 0x82, 0x01, 0x12, 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, 0x31, 0x39, - 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x30, 0x30, 0x3a, - 0x38, 0x30, 0x38, 0x30, 0x2f, 0x61, 0x73, 0x2e, 0x63, 0x72, 0x6c, 0x30, - 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, - 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xd7, 0x63, 0x01, 0x01, 0x01, - 0x05, 0x00, 0x03, 0x37, 0x00, 0x30, 0x34, 0x02, 0x18, 0x23, 0xc5, 0x39, - 0xc9, 0x91, 0x89, 0x3d, 0xe5, 0xae, 0x95, 0x75, 0x88, 0x68, 0xf6, 0x11, - 0x64, 0xb1, 0x71, 0xe7, 0x67, 0x1f, 0xa1, 0x58, 0x77, 0x02, 0x18, 0x15, - 0xef, 0x5a, 0x62, 0x7f, 0x7d, 0x9d, 0x6e, 0x6d, 0x91, 0x2b, 0x61, 0x15, - 0x4d, 0x5a, 0xbe, 0xc8, 0x8d, 0xdc, 0x85, 0x00, 0xa9, 0x7d, 0x99 -}; - -#if 0 // currently unused. -static unsigned int _wapi_as_der_len = 443; -#endif - -/* subject:/DC=com/DC=outsidevpntest/CN=Users/CN=certxauthsplit */ -/* issuer :/DC=com/DC=outsidevpntest/CN=outsidevpntest-SERVER02-CA */ -static uint8_t two_common_names[1427]={ - 0x30,0x82,0x05,0x8F,0x30,0x82,0x04,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x0A,0x45, - 0x0F,0xA6,0x09,0x00,0x00,0x00,0x00,0x00,0x16,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, - 0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x5A,0x31,0x13,0x30,0x11,0x06,0x0A, - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x03,0x63,0x6F,0x6D,0x31, - 0x1E,0x30,0x1C,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16, - 0x0E,0x6F,0x75,0x74,0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x31, - 0x23,0x30,0x21,0x06,0x03,0x55,0x04,0x03,0x13,0x1A,0x6F,0x75,0x74,0x73,0x69,0x64, - 0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2D,0x53,0x45,0x52,0x56,0x45,0x52,0x30, - 0x32,0x2D,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x39,0x30,0x36,0x30,0x33, - 0x30,0x32,0x30,0x30,0x5A,0x17,0x0D,0x31,0x33,0x30,0x39,0x30,0x36,0x30,0x33,0x30, - 0x32,0x30,0x30,0x5A,0x30,0x5E,0x31,0x13,0x30,0x11,0x06,0x0A,0x09,0x92,0x26,0x89, - 0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x03,0x63,0x6F,0x6D,0x31,0x1E,0x30,0x1C,0x06, - 0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x0E,0x6F,0x75,0x74, - 0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x31,0x0E,0x30,0x0C,0x06, - 0x03,0x55,0x04,0x03,0x13,0x05,0x55,0x73,0x65,0x72,0x73,0x31,0x17,0x30,0x15,0x06, - 0x03,0x55,0x04,0x03,0x13,0x0E,0x63,0x65,0x72,0x74,0x78,0x61,0x75,0x74,0x68,0x73, - 0x70,0x6C,0x69,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,0xB9,0xC7,0x0A,0x4A,0x2D,0xA4,0xD4,0x8F,0x0A,0xC3,0x49,0xDC,0xA0,0xE2,0x36, - 0x67,0x2E,0x0E,0xD2,0x02,0xA8,0x3B,0x23,0xDF,0xE4,0x67,0xCA,0x98,0xB9,0x37,0x10, - 0xF9,0x7D,0x76,0x40,0x3F,0xED,0xBE,0x0E,0x8C,0x3B,0x1A,0x91,0x61,0x37,0x5B,0x8E, - 0xDA,0xB5,0x98,0xD0,0x4A,0x2E,0x1B,0xB4,0xF8,0xBC,0xAB,0x5B,0x90,0xE7,0x46,0x3C, - 0xDC,0x62,0x0F,0xD0,0x97,0x28,0x15,0x91,0x2F,0xD5,0x33,0x63,0xA5,0x4F,0xD2,0x84, - 0x0D,0x7C,0xD0,0x8A,0x5B,0x20,0x23,0xF3,0xAA,0x1E,0xAC,0xB4,0x31,0xE3,0xAF,0x6C, - 0x51,0xBE,0xC1,0xBE,0xCE,0x12,0x34,0x6E,0x6D,0x09,0xB3,0x9D,0x88,0x6D,0x35,0x37, - 0xCB,0xDB,0x08,0xF3,0x55,0x98,0x62,0x75,0x93,0x6B,0x15,0xD0,0xF1,0xFC,0x59,0xB4, - 0x37,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0xD5,0x30,0x82,0x02,0xD1,0x30,0x0E, - 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x44, - 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,0x04,0x37,0x30,0x35,0x30, - 0x0E,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,0x02,0x02,0x00,0x80,0x30, - 0x0E,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,0x02,0x02,0x00,0x80,0x30, - 0x07,0x06,0x05,0x2B,0x0E,0x03,0x02,0x07,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x03,0x07,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xDD, - 0x63,0xE5,0xA8,0xBE,0x94,0x8D,0x3B,0xCF,0xDB,0x51,0x4A,0xAB,0x63,0xDC,0x5A,0x30, - 0x12,0x66,0x16,0x30,0x17,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02, - 0x04,0x0A,0x1E,0x08,0x00,0x55,0x00,0x73,0x00,0x65,0x00,0x72,0x30,0x1F,0x06,0x03, - 0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x13,0x9B,0xAB,0x61,0x39,0x5F,0x45, - 0x84,0xDB,0x37,0x72,0xD7,0xAC,0x67,0x19,0x26,0xBD,0x85,0x33,0xC0,0x30,0x81,0xE0, - 0x06,0x03,0x55,0x1D,0x1F,0x04,0x81,0xD8,0x30,0x81,0xD5,0x30,0x81,0xD2,0xA0,0x81, - 0xCF,0xA0,0x81,0xCC,0x86,0x81,0xC9,0x6C,0x64,0x61,0x70,0x3A,0x2F,0x2F,0x2F,0x43, - 0x4E,0x3D,0x6F,0x75,0x74,0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74, - 0x2D,0x53,0x45,0x52,0x56,0x45,0x52,0x30,0x32,0x2D,0x43,0x41,0x2C,0x43,0x4E,0x3D, - 0x73,0x65,0x72,0x76,0x65,0x72,0x30,0x32,0x2C,0x43,0x4E,0x3D,0x43,0x44,0x50,0x2C, - 0x43,0x4E,0x3D,0x50,0x75,0x62,0x6C,0x69,0x63,0x25,0x32,0x30,0x4B,0x65,0x79,0x25, - 0x32,0x30,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x53,0x65, - 0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x43,0x6F,0x6E,0x66,0x69,0x67, - 0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x44,0x43,0x3D,0x6F,0x75,0x74,0x73,0x69, - 0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2C,0x44,0x43,0x3D,0x63,0x6F,0x6D, - 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, - 0x6F,0x62,0x6A,0x65,0x63,0x74,0x43,0x6C,0x61,0x73,0x73,0x3D,0x63,0x52,0x4C,0x44, - 0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x69,0x6F,0x6E,0x50,0x6F,0x69,0x6E,0x74, - 0x30,0x81,0xD3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0xC6, - 0x30,0x81,0xC3,0x30,0x81,0xC0,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, - 0x86,0x81,0xB3,0x6C,0x64,0x61,0x70,0x3A,0x2F,0x2F,0x2F,0x43,0x4E,0x3D,0x6F,0x75, - 0x74,0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2D,0x53,0x45,0x52, - 0x56,0x45,0x52,0x30,0x32,0x2D,0x43,0x41,0x2C,0x43,0x4E,0x3D,0x41,0x49,0x41,0x2C, - 0x43,0x4E,0x3D,0x50,0x75,0x62,0x6C,0x69,0x63,0x25,0x32,0x30,0x4B,0x65,0x79,0x25, - 0x32,0x30,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x53,0x65, - 0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x43,0x6F,0x6E,0x66,0x69,0x67, - 0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x44,0x43,0x3D,0x6F,0x75,0x74,0x73,0x69, - 0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2C,0x44,0x43,0x3D,0x63,0x6F,0x6D, - 0x3F,0x63,0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x3F,0x62, - 0x61,0x73,0x65,0x3F,0x6F,0x62,0x6A,0x65,0x63,0x74,0x43,0x6C,0x61,0x73,0x73,0x3D, - 0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,0x74, - 0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x29,0x06,0x03,0x55,0x1D,0x25,0x04,0x22,0x30, - 0x20,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,0x06,0x08,0x2B, - 0x06,0x01,0x05,0x05,0x07,0x03,0x04,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03, - 0x02,0x30,0x3C,0x06,0x03,0x55,0x1D,0x11,0x04,0x35,0x30,0x33,0xA0,0x31,0x06,0x0A, - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,0xA0,0x23,0x0C,0x21,0x63,0x65, - 0x72,0x74,0x78,0x61,0x75,0x74,0x68,0x73,0x70,0x6C,0x69,0x74,0x40,0x6F,0x75,0x74, - 0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, - 0x01,0x01,0x00,0x98,0xD5,0x24,0x83,0x28,0xC0,0xB5,0xE2,0xF9,0x22,0xE6,0xED,0x9C, - 0xC8,0xFB,0x07,0xB0,0x23,0x16,0xD0,0x62,0x32,0xF4,0xCC,0x71,0x00,0x31,0x48,0x8A, - 0x5D,0xFA,0xDC,0x80,0x49,0x35,0x38,0x16,0x81,0xA8,0xA8,0x01,0x69,0xC1,0x64,0xD9, - 0x64,0x72,0xC4,0xB3,0x24,0x02,0x7C,0xB8,0xD9,0x92,0xAA,0x28,0xB0,0x87,0x63,0x73, - 0x21,0xD7,0x4D,0x68,0x2D,0x99,0xF5,0x9B,0x10,0xD1,0x6B,0xF3,0xF8,0x1B,0x7B,0x73, - 0x2E,0x06,0xF1,0x17,0xCA,0xEE,0xAA,0xD7,0x6B,0x14,0x72,0x2E,0xA5,0x3C,0xC3,0x4A, - 0xFA,0x1C,0x28,0x72,0x16,0x08,0x33,0xF7,0x94,0xA1,0x30,0x94,0x37,0xF0,0xB3,0xAF, - 0xA5,0x49,0xD1,0x87,0xEB,0xD7,0xA0,0x3F,0xA7,0xDA,0x4D,0x70,0xFD,0xA9,0x53,0x82, - 0x1B,0xA7,0x6A,0xC8,0x3A,0x9D,0x9C,0x09,0x4D,0xD5,0xB1,0x71,0xFC,0xC4,0xC6,0x9D, - 0x9F,0xC5,0x16,0x13,0x7F,0x53,0x7C,0x5E,0x83,0xB0,0x8F,0xFA,0x24,0x9F,0xD3,0x2A, - 0x64,0x7E,0xA2,0x98,0x30,0x5B,0x7F,0x41,0x6C,0xE3,0xD4,0xE8,0x1E,0x18,0x2A,0x83, - 0x05,0x0F,0x0C,0x6A,0xF6,0x03,0xEB,0xF9,0x77,0x67,0xB9,0x4C,0xF7,0x98,0x45,0xC6, - 0x52,0x7E,0xF0,0xFA,0xAD,0x96,0xCC,0xA3,0x19,0xA7,0xF5,0x06,0x35,0x28,0x5E,0xE4, - 0xAC,0x8E,0x06,0x32,0xCC,0xEB,0xA6,0x0C,0x39,0xD3,0xF8,0xCF,0xA5,0xEC,0x87,0x74, - 0x58,0xFA,0xBE,0xB7,0x89,0xA3,0x4A,0xD6,0x62,0x9D,0x3E,0x37,0x5E,0x1E,0xC1,0x9F, - 0xBC,0xE0,0xF7,0x86,0xE2,0x6D,0xFF,0x71,0x9B,0x93,0xA8,0xEE,0xD8,0xA0,0x8C,0x1B, - 0x99,0x58,0xFC, -}; - -/* Test basic add delete update copy matching stuff. */ -static void tests(void) -{ - SecCertificateRef cert0, cert1, cert2, cert3, cert4, cert5, cert6; - isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), - NULL, "create cert0"); - isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), - NULL, "create cert1"); - - CFDataRef cert2Data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - _c2, sizeof(_c2), kCFAllocatorNull); - isnt(cert2 = SecCertificateCreateWithData(kCFAllocatorDefault, cert2Data), - NULL, "create cert2"); - CFReleaseNull(cert2Data); - - isnt(cert3 = SecCertificateCreateWithBytes(NULL, _phased_c3, sizeof(_phased_c3)), - NULL, "create cert3"); - - CFDataRef cert4data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, - pem, sizeof(pem), kCFAllocatorNull); - ok(cert4 = SecCertificateCreateWithPEM(NULL, cert4data), "create cert from pem"); - CFReleaseNull(cert4data); - - isnt(cert5 = SecCertificateCreateWithBytes(NULL, _elektron_v1_cert_der, - sizeof(_elektron_v1_cert_der)), NULL, "create cert5"); - - isnt(cert6 = SecCertificateCreateWithBytes(NULL, _wapi_as_der, - sizeof(_wapi_as_der)), NULL, "create cert6"); - - if (!cert0 || !cert1 || !cert2 || !cert3 || !cert4 || !cert5 || !cert6) { - goto errOut; - } - - ok(SecCertificateIsSelfSignedCA(cert0), "cert0 is CA"); - ok(!SecCertificateIsSelfSignedCA(cert1), "cert1 is not CA"); - ok(SecCertificateIsSelfSignedCA(cert5), "cert5 is v1 CA"); - - CFStringRef subjectSummary, issuerSummary; - isnt(subjectSummary = SecCertificateCopySubjectSummary(cert1), NULL, - "cert1 has a subject summary"); - isnt(issuerSummary = SecCertificateCopyIssuerSummary(cert1), NULL, - "cert1 has an issuer summary"); - - ok(subjectSummary && CFEqual(subjectSummary, CFSTR("www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.")), - "subject summary is \"www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.\""); - ok(issuerSummary && CFEqual(issuerSummary, - CFSTR("Class 3 Public Primary Certification Authority")), - "issuer summary is \"Class 3 Public Primary Certification Authority\""); - - CFArrayRef ntPrincipalNames; - ok(ntPrincipalNames = SecCertificateCopyNTPrincipalNames(cert2), - "SecCertificateCopyNTPrincipalNames"); - is(CFArrayGetCount(ntPrincipalNames), 1, "we got 1 princialname back"); - CFStringRef principal = (CFStringRef)CFArrayGetValueAtIndex(ntPrincipalNames, 0); - ok(CFEqual(principal, CFSTR("kmm6b@Virginia.EDU")), - "first principal is kmm6b@Virginia.EDU"); - CFReleaseSafe(ntPrincipalNames); - - CFReleaseSafe(subjectSummary); - CFReleaseSafe(issuerSummary); - - isnt(subjectSummary = SecCertificateCopySubjectSummary(cert3), NULL, - "cert3 has a subject summary"); - /* @@@ this causes a double free without an extra retain in obtainSummaryFromX501Name(): - summary->description = string = copyDERThingDescription(kCFAllocatorDefault, value, true); */ - CFReleaseSafe(subjectSummary); - - isnt(subjectSummary = SecCertificateCopySubjectSummary(cert4), NULL, - "cert4 has a subject summary"); - ok(subjectSummary && CFEqual(subjectSummary, CFSTR("S5L8900 Secure Boot")), - "cert4 is S5L8900 Secure Boot"); - CFReleaseSafe(subjectSummary); - - CFStringRef desc = NULL; - ok(desc = CFCopyDescription(cert4), "cert4 CFCopyDescription works"); - CFReleaseNull(desc); - - CFDataRef spki1Hash = SecCertificateCopySubjectPublicKeyInfoSHA1Digest(cert0); - isnt(spki1Hash, NULL, "cert0 has a SHA-1 subject public key info hash"); - CFReleaseSafe(spki1Hash); - - CFDataRef spki2Hash = SecCertificateCopySubjectPublicKeyInfoSHA256Digest(cert0); - isnt(spki2Hash, NULL, "cert0 has a SHA-256 subject public key info hash"); - CFReleaseSafe(spki2Hash); - -errOut: - CFReleaseSafe(cert0); - CFReleaseSafe(cert1); - CFReleaseSafe(cert2); - CFReleaseSafe(cert3); - CFReleaseSafe(cert4); - CFReleaseSafe(cert5); - CFReleaseSafe(cert6); -} - -static void test_common_name(void) { - SecCertificateRef cert = NULL; - CFStringRef commonName = NULL; - - require(cert = SecCertificateCreateWithBytes(NULL, two_common_names, sizeof(two_common_names)), errOut); - require_noerr(SecCertificateCopyCommonName(cert, &commonName), errOut); - is(CFStringCompare(commonName, CFSTR("certxauthsplit"), 0), kCFCompareEqualTo, "copy common name got the wrong name"); - -errOut: - CFReleaseSafe(commonName); - CFReleaseSafe(cert); -} - -const uint8_t mail_google_com [] = { - 0x30, 0x82, 0x03, 0x22, 0x30, 0x82, 0x02, 0x8b, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x10, 0x2b, 0x9f, 0x7e, 0xe5, 0xca, 0x25, 0xa6, 0x25, 0x14, - 0x20, 0x47, 0x82, 0x75, 0x3a, 0x9b, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4c, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5a, - 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, - 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29, 0x20, - 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, - 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x47, - 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, - 0x32, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, - 0x33, 0x30, 0x39, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, - 0x30, 0x69, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x14, 0x0d, 0x4d, - 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, - 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x0a, 0x47, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x18, 0x30, - 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x0f, 0x6d, 0x61, 0x69, 0x6c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 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, 0xaf, 0x39, 0x15, 0x98, 0x68, 0xe4, 0x92, 0xfe, - 0x4f, 0x4f, 0xf1, 0xbb, 0xff, 0x0d, 0x2e, 0xb0, 0xfe, 0x25, 0xaa, 0xbd, - 0x68, 0x04, 0x67, 0x27, 0xea, 0x6c, 0x43, 0x4c, 0xa7, 0x6d, 0xcb, 0xc8, - 0x8f, 0x7e, 0x81, 0xee, 0x87, 0x26, 0x25, 0x10, 0x12, 0x54, 0x33, 0x9e, - 0xaa, 0x3d, 0x9b, 0x8f, 0x8e, 0x92, 0xb3, 0x4b, 0x01, 0xe3, 0xf9, 0x4a, - 0x29, 0xc3, 0x0f, 0xfd, 0xac, 0xb7, 0xd3, 0x4c, 0x97, 0x29, 0x3f, 0x69, - 0x55, 0xcf, 0x70, 0x83, 0x04, 0xaf, 0x2e, 0x04, 0x6e, 0x74, 0xd6, 0x0f, - 0x17, 0x09, 0xfe, 0x9e, 0x20, 0x24, 0x24, 0xe3, 0xc7, 0x68, 0x9c, 0xac, - 0x11, 0xbd, 0x92, 0xe4, 0xb2, 0x1b, 0x09, 0xf2, 0x02, 0x32, 0xbb, 0x55, - 0x1b, 0x2d, 0x16, 0x5f, 0x30, 0x12, 0x23, 0xe2, 0x4c, 0x4a, 0x8d, 0xc2, - 0xda, 0x3f, 0xe1, 0xb8, 0xbf, 0xf7, 0x3a, 0xb1, 0x86, 0xbe, 0xf0, 0xc5, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe7, 0x30, 0x81, 0xe4, 0x30, - 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, - 0x00, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, - 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, - 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x53, 0x47, 0x43, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x28, 0x06, - 0x03, 0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, - 0x42, 0x04, 0x01, 0x30, 0x72, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x01, 0x01, 0x04, 0x66, 0x30, 0x64, 0x30, 0x22, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, - 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x08, 0x2b, - 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x32, 0x68, 0x74, 0x74, - 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, - 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, - 0x5f, 0x53, 0x47, 0x43, 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, - 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, - 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0x80, 0x11, 0xcd, 0x52, 0x3e, - 0x84, 0x29, 0xfb, 0xc1, 0x28, 0xe1, 0x20, 0xe5, 0x02, 0x8f, 0x5f, 0x71, - 0x65, 0x58, 0x1d, 0x62, 0x72, 0x57, 0x3c, 0xe6, 0x5e, 0x25, 0x61, 0xd3, - 0xcb, 0xad, 0x22, 0xf8, 0xd8, 0x81, 0xa4, 0xe7, 0xf4, 0xae, 0x7c, 0xd9, - 0xc1, 0x6d, 0xaa, 0x93, 0x0d, 0x62, 0x07, 0x9f, 0xf2, 0x67, 0x47, 0x99, - 0x34, 0x33, 0x4f, 0x3d, 0x02, 0x74, 0xf4, 0x81, 0xd6, 0x38, 0x08, 0x21, - 0xe8, 0xe2, 0xa1, 0xfa, 0x05, 0x41, 0x9c, 0x9c, 0xc9, 0xf9, 0xf3, 0xc8, - 0xa3, 0xee, 0x0d, 0xa5, 0xd7, 0x50, 0x54, 0x5e, 0x2f, 0x7d, 0x79, 0xb7, - 0x7e, 0x0a, 0x7c, 0xb6, 0xe2, 0x2c, 0xa8, 0xae, 0xfe, 0x94, 0xd7, 0xcd, - 0x16, 0x30, 0x71, 0x04, 0xaa, 0x9e, 0x79, 0xc3, 0xd2, 0xb6, 0x24, 0xa7, - 0x25, 0xab, 0xf0, 0x48, 0x8e, 0x2f, 0xc3, 0xa7, 0xbb, 0x50, 0xdd, 0x0f, - 0xcf, 0xb0, }; - -static void test_copy_email_addresses(void) { - SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, mail_google_com, sizeof (mail_google_com)); - CFArrayRef array = NULL; - CFStringRef name = NULL; - - ok_status(SecCertificateCopyCommonName(cert, &name), "Failed to get common name from cert"); - ok(name, "Failed to get common name"); - ok(CFEqual(name, CFSTR("mail.google.com")), "Got wrong common name"); - - ok_status(SecCertificateCopyEmailAddresses (cert, &array), "Failed to get email addresses from cert"); - ok(array, "Failed to get email address array"); - is(CFArrayGetCount(array), 0, "Found unexpected email addresses"); - - CFReleaseNull(cert); - CFReleaseNull(name); - CFReleaseNull(array); -} - -static void test_copy_extension_value(void) { - SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, mail_google_com, sizeof(mail_google_com)); - CFDataRef extension = NULL, expected = NULL, oid = NULL; - bool critical = false; - - /* parameter fails */ - is(extension = SecCertificateCopyExtensionValue(NULL, CFSTR("1.2.3.4"), &critical), NULL, - "NULL cert input succeeded"); - is(extension = SecCertificateCopyExtensionValue(cert, NULL, &critical), NULL, - "NULL OID input succeeded"); - - /* Extension not present */ - is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("1.2.3.4"), &critical), NULL, - "Got extension value for non-present extension OID"); - - /* Using decimal OID, extension present and critical */ - isnt(extension = SecCertificateCopyExtensionValue(cert, CFSTR("2.5.29.19"), &critical), NULL, - "Failed to get extension for present extension OID"); - is(critical, true, "Got wrong criticality for critical extension"); - uint8_t basic_constraints_value[2] = { 0x30, 0x00 }; - expected = CFDataCreate(NULL, basic_constraints_value, sizeof(basic_constraints_value)); - ok(CFEqual(extension, expected), "Got wrong extension value for basic constraints"); - CFReleaseNull(extension); - CFReleaseNull(expected); - - /* Using binary OID, extension present and non critical */ - uint8_t oidExtendedKeyUsage[3] = { 0x55, 0x01d, 0x25 }; - oid = CFDataCreate(NULL, oidExtendedKeyUsage, sizeof(oidExtendedKeyUsage)); - isnt(extension = SecCertificateCopyExtensionValue(cert, oid, &critical), NULL, - "Failed to get extension for present extension OID"); - is(critical, false, "Got wrong criticality for non-critical extension"); - uint8_t eku_value[] = { - 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, - 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, - 0x01 - }; - expected = CFDataCreate(NULL, eku_value, sizeof(eku_value)); - ok(CFEqual(extension, expected), "Got wrong extension value for extended key usage"); - CFReleaseNull(oid); - CFReleaseNull(extension); - CFReleaseNull(expected); - - /* No critical output */ - isnt(extension = SecCertificateCopyExtensionValue(cert, CFSTR("2.5.29.19"), NULL), NULL, - "Failed to get extension for present extension OID"); - CFReleaseNull(extension); - - /* messed up binary OIDs */ - is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("abcd"), NULL), NULL, - "letters in OID"); - is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("8.1.1.2"), NULL), NULL, - "bad first arc"); - is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("10.1.1.1"), NULL), NULL, - "longer bad first arc"); - is(extension = SecCertificateCopyExtensionValue(cert, CFSTR(""), NULL), NULL, - "empty string"); - is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("1.2.1099511627776."), NULL), NULL, - "six byte component"); - - CFReleaseNull(cert); -} - -/* subject:/UID=372S63A2R8/CN=Developer ID Application: John Brayton/OU=372S63A2R8/O=John Brayton/C=US */ -/* issuer :/CN=Developer ID Certification Authority/OU=Apple Certification Authority/O=Apple Inc./C=US */ -const uint8_t _old_developer_cert[] = { - 0x30,0x82,0x05,0x65,0x30,0x82,0x04,0x4D,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x3B, - 0x8B,0xC9,0x83,0xCC,0x57,0x54,0x95,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,0x32,0x30,0x34,0x32,0x31,0x31,0x39,0x33,0x39,0x33, - 0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x34,0x32,0x32,0x31,0x39,0x33,0x39,0x33,0x30, - 0x5A,0x30,0x81,0x86,0x31,0x1A,0x30,0x18,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2, - 0x2C,0x64,0x01,0x01,0x0C,0x0A,0x33,0x37,0x32,0x53,0x36,0x33,0x41,0x32,0x52,0x38, - 0x31,0x2F,0x30,0x2D,0x06,0x03,0x55,0x04,0x03,0x0C,0x26,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,0x4A,0x6F,0x68,0x6E,0x20,0x42,0x72,0x61,0x79,0x74,0x6F, - 0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0A,0x33,0x37,0x32,0x53, - 0x36,0x33,0x41,0x32,0x52,0x38,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x0C, - 0x0C,0x4A,0x6F,0x68,0x6E,0x20,0x42,0x72,0x61,0x79,0x74,0x6F,0x6E,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,0xDE,0x02,0xD5,0xBC,0x79, - 0x03,0x44,0x44,0xA0,0xCC,0x53,0xB9,0x4D,0xF6,0xF7,0x59,0xCF,0xA4,0x71,0x8A,0x20, - 0x72,0xA2,0x60,0xEA,0x45,0x26,0x52,0x39,0xA7,0xBD,0xFF,0x0A,0x45,0x0E,0xA2,0xE4, - 0x42,0x8C,0x0D,0x4B,0xF5,0x96,0x73,0xB3,0x56,0x0E,0xAA,0x2B,0x3F,0xBB,0x69,0x93, - 0xD5,0xC1,0x20,0xF2,0x40,0x38,0xB6,0x6C,0xB1,0xA0,0x4C,0x1B,0xA6,0xF1,0xE5,0x34, - 0xD4,0xD8,0xB0,0xF0,0x34,0x8C,0x2B,0xA4,0xBF,0x1E,0x8F,0x64,0xF0,0x25,0x9F,0x5D, - 0x65,0x1E,0x61,0xBA,0x63,0x68,0x16,0x67,0xDE,0x0B,0x76,0x25,0xFD,0xAF,0xB3,0xBF, - 0x1D,0xEA,0x82,0x85,0xE5,0x80,0xC7,0x62,0x1B,0x17,0xB3,0x5E,0x56,0xEA,0xD4,0x39, - 0x9C,0xA7,0x39,0x9B,0x1F,0xAD,0xD7,0xE1,0x7D,0x71,0x48,0xE5,0x19,0x53,0x98,0x6A, - 0x01,0x14,0x21,0x53,0xE4,0x69,0x69,0x3F,0xF3,0xC0,0x6C,0x2D,0x82,0x78,0x63,0x4E, - 0xAA,0xE4,0x0C,0xEF,0xC3,0x99,0x53,0xCA,0x1A,0x08,0xF4,0x95,0x48,0x23,0x8F,0xC9, - 0x13,0xCA,0xA7,0x0C,0xDC,0xB8,0x34,0x67,0x46,0x68,0x72,0x04,0x7E,0x17,0xC1,0x73, - 0x38,0x21,0xB8,0x52,0x35,0x3F,0x15,0x4D,0x60,0x82,0x63,0xEE,0x37,0xCC,0xF6,0x1F, - 0xF8,0xBC,0xA3,0xF6,0x1F,0xE1,0x9F,0x45,0xFA,0x5A,0xF6,0xC1,0x06,0x16,0xF8,0x03, - 0x84,0x7E,0x2F,0xE3,0x0D,0xEC,0x3E,0x05,0xF5,0xC0,0x0C,0x57,0x84,0x4C,0xCB,0x25, - 0x81,0x4C,0x59,0x2C,0xDC,0x63,0xA7,0xA0,0xA6,0x6C,0xC3,0xDC,0x7F,0x1E,0xAA,0x1E, - 0xD8,0x31,0x7D,0x08,0x8C,0x2F,0x85,0xB9,0x09,0xFF,0xD9,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,0xB1,0x95,0xE5,0x40,0x5D,0xE0,0x7B,0x76,0xF6,0x2B,0xD4,0x5B,0x16, - 0x6F,0x90,0x52,0x43,0x9C,0x8E,0xEA,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,0x53,0x09,0xBD,0xA3,0xB5,0xE0,0x63, - 0x49,0x02,0x71,0x3C,0x3A,0xF3,0xC9,0x08,0xF0,0xF9,0xCA,0x4E,0x70,0xD4,0x8D,0x3F, - 0xE5,0x9C,0x67,0xED,0x49,0xB4,0x7C,0xA3,0x5D,0x44,0xDE,0xF0,0x48,0xB9,0xDD,0x54, - 0x4F,0x56,0x7D,0xFD,0x08,0x14,0x3C,0x15,0xB8,0xFF,0x54,0x23,0x9A,0x48,0xC5,0x6C, - 0x48,0x72,0xE4,0x30,0xA6,0xC6,0xE8,0x42,0x62,0x29,0xA5,0x13,0x72,0x1C,0x04,0x6C, - 0x91,0x92,0xC3,0x3A,0x53,0x0A,0x52,0xDC,0x26,0x88,0xDE,0x42,0xA1,0x57,0xC2,0x03, - 0x3A,0xD7,0xE3,0x9B,0x2A,0x1F,0x48,0x65,0xFD,0x7F,0x81,0xEF,0x8E,0x39,0x64,0xB8, - 0x36,0x2B,0x60,0xCC,0x6A,0x50,0x0C,0x79,0xAD,0x75,0xD2,0x44,0x43,0xA1,0x31,0x5A, - 0x27,0xEC,0xB1,0xF5,0xC2,0x32,0x0D,0x35,0xF8,0x70,0x45,0x66,0xA3,0x6A,0x29,0x1F, - 0x60,0x7E,0xEE,0x34,0xF7,0x0F,0xBE,0x23,0x1D,0x97,0x3F,0x6C,0xE4,0xA6,0xF6,0x59, - 0x73,0x51,0x1B,0x13,0x38,0x04,0x98,0x59,0x8F,0xBF,0x8D,0xB8,0x0E,0xC7,0x57,0x00, - 0x8D,0x14,0x3A,0xA5,0xD9,0x4F,0xD9,0x4E,0xFF,0x75,0x83,0x15,0xA6,0x0E,0x1A,0xD3, - 0x0D,0xBC,0x0B,0x7E,0x99,0x3A,0xB9,0x73,0xAE,0x84,0x49,0xEE,0x8B,0x26,0x8E,0xD3, - 0xE9,0x36,0xCD,0xAD,0xC1,0xA9,0x00,0xC0,0x91,0x8B,0x3E,0x7E,0x7B,0x25,0x7F,0x7F, - 0x0D,0x4B,0xA4,0xE4,0xAD,0x67,0x4D,0x6A,0xF1,0xF7,0xF4,0xC0,0x5F,0x4B,0x9A,0xB4, - 0x2D,0x9B,0x91,0x3B,0x5A,0x67,0x9B,0xC5,0x64,0x99,0x04,0xA0,0x01,0xCF,0x52,0xE0, - 0xBB,0xA1,0xC9,0xDD,0xD6,0x75,0x2E,0xE8,0x04, -}; - -/* subject:/UID=PV45XFU466/CN=Developer ID Application: T Solanki (PV45XFU466)/OU=PV45XFU466/O=T Solanki/C=US */ -/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Test Apple Caspian Certification Authority */ -const uint8_t _new_developer_cert[] = { - 0x30,0x82,0x05,0xBF,0x30,0x82,0x04,0xA7,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x69, - 0x87,0x9F,0x89,0x35,0xB9,0x9C,0xD7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, - 0x0D,0x01,0x01,0x0B,0x05,0x00,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,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,0x33,0x30,0x31,0x06,0x03,0x55,0x04,0x03,0x0C,0x2A,0x54,0x65,0x73, - 0x74,0x20,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x61,0x73,0x70,0x69,0x61,0x6E,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,0x39,0x30,0x33,0x30, - 0x35,0x32,0x32,0x30,0x32,0x32,0x31,0x5A,0x17,0x0D,0x32,0x34,0x30,0x33,0x30,0x35, - 0x32,0x32,0x30,0x32,0x32,0x31,0x5A,0x30,0x81,0x8D,0x31,0x1A,0x30,0x18,0x06,0x0A, - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,0x0C,0x0A,0x50,0x56,0x34,0x35, - 0x58,0x46,0x55,0x34,0x36,0x36,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x03,0x0C, - 0x30,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,0x54,0x20,0x53,0x6F,0x6C, - 0x61,0x6E,0x6B,0x69,0x20,0x28,0x50,0x56,0x34,0x35,0x58,0x46,0x55,0x34,0x36,0x36, - 0x29,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0A,0x50,0x56,0x34,0x35, - 0x58,0x46,0x55,0x34,0x36,0x36,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x0C, - 0x09,0x54,0x20,0x53,0x6F,0x6C,0x61,0x6E,0x6B,0x69,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,0xC8,0xA7,0xFD,0xE0,0x5C,0xBD,0x35,0x6D, - 0x73,0x44,0xE1,0x9A,0xDA,0x70,0xE9,0x6E,0x99,0xDB,0x9C,0x0A,0x47,0x9B,0x71,0xBC, - 0xCF,0xE2,0x2A,0x1D,0x6C,0x11,0x5A,0x45,0x27,0xD5,0x3B,0x42,0x4C,0x1B,0xE2,0x43, - 0x5D,0xCA,0x37,0x48,0xB1,0xCD,0xA5,0xDC,0x2B,0x46,0xE9,0xD5,0xEE,0xCE,0xE1,0xF2, - 0x9C,0xD0,0x55,0x14,0x42,0x7A,0x9A,0xFB,0x2C,0xF0,0x20,0xD5,0x53,0x6B,0x3E,0x76, - 0x45,0x59,0xB6,0x16,0x41,0x52,0x61,0x64,0x2E,0xFA,0x69,0x43,0x95,0xD7,0x75,0x63, - 0x24,0xF8,0xFD,0x62,0x99,0xE9,0x5B,0xF8,0x72,0xE9,0x85,0x06,0x73,0x60,0x9C,0x83, - 0xD7,0xD6,0x1D,0xEC,0xC5,0x85,0x48,0xE0,0x55,0x71,0xFE,0xE0,0x54,0xAF,0x06,0xE7, - 0xD6,0x39,0x87,0xFB,0x5A,0xE7,0x7F,0x02,0x7C,0x80,0x2B,0x8B,0xA6,0x6A,0x06,0xF0, - 0xBE,0xDF,0xB3,0x1D,0x4D,0x40,0x9F,0x05,0x36,0x55,0xA4,0x09,0x58,0xB1,0xD2,0xB8, - 0xC0,0x8B,0xDE,0x25,0xD8,0xEB,0x80,0x07,0x34,0x64,0xE5,0x77,0x9A,0x39,0xD6,0xE1, - 0x7F,0x8A,0xF2,0xE4,0x56,0x15,0x84,0xB2,0x8A,0x54,0x31,0xCB,0xC3,0xAD,0xB6,0x63, - 0x72,0x64,0x53,0x8F,0xE5,0x74,0xD3,0xAA,0x91,0x0D,0xF0,0xEF,0x03,0x24,0x21,0x8C, - 0x0D,0x45,0xE4,0x18,0x0E,0xE0,0xDB,0x8C,0x20,0xF1,0x4A,0xD6,0x8B,0x60,0x84,0x3D, - 0x14,0x0D,0xCA,0x46,0x20,0x1F,0x13,0x07,0x7E,0x23,0x90,0x5B,0x8F,0xCF,0xD0,0x1E, - 0x48,0x56,0xF5,0xED,0xF3,0x96,0x52,0x03,0x40,0xF7,0x47,0x4A,0xAF,0xD0,0x67,0x0F, - 0xC1,0x5F,0xB1,0xA8,0xCD,0x29,0xDD,0x91,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02, - 0x2E,0x30,0x82,0x02,0x2A,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, - 0xF8,0x7A,0x23,0x8A,0xD2,0xE7,0xD2,0xDF,0x21,0xDB,0x7A,0xF4,0x12,0x31,0x6E,0x28, - 0xF6,0xF9,0xF0,0x8E,0x30,0x49,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, - 0x04,0x3D,0x30,0x3B,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, - 0x86,0x2D,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,0x64,0x65,0x76,0x69,0x64,0x30,0x39,0x30, - 0x82,0x01,0x1D,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x14,0x30,0x82,0x01,0x10, - 0x30,0x82,0x01,0x0C,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x01,0x30, - 0x81,0xFE,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,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,0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,0x30,0x0A,0x06,0x08, - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, - 0x16,0x04,0x14,0x6A,0x2A,0x84,0xE8,0xAF,0x4B,0x33,0x37,0xB3,0x09,0xD5,0x8D,0x49, - 0x5B,0xF1,0xA9,0x3D,0x6E,0xCD,0x71,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, - 0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x13,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7, - 0x63,0x64,0x06,0x01,0x0D,0x01,0x01,0xFF,0x04,0x02,0x05,0x00,0x30,0x1F,0x06,0x0A, - 0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x01,0x21,0x04,0x11,0x0C,0x0F,0x32,0x30, - 0x31,0x39,0x30,0x33,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x10,0x06, - 0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x01,0x20,0x04,0x02,0x05,0x00,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, - 0x01,0x01,0x00,0x64,0x2D,0x1E,0xE4,0x1A,0x98,0xEF,0x62,0xF9,0xD8,0xEE,0xF8,0xCA, - 0x87,0xD7,0x71,0x55,0xDB,0x0D,0x9E,0x8F,0xDE,0x6E,0xBA,0x7D,0xBE,0xE7,0x2E,0xE3, - 0x48,0x09,0x09,0x11,0x54,0x3C,0x6F,0x79,0x61,0xF6,0x18,0xAB,0xE6,0xF4,0x87,0x59, - 0x20,0x97,0xC3,0xC2,0x47,0x25,0x03,0x47,0xA0,0xD6,0x95,0x08,0x67,0xA4,0x25,0xB1, - 0x94,0x0A,0x17,0x90,0xA7,0x64,0xD1,0xB6,0x35,0x59,0xF8,0x9D,0x0E,0x1E,0xF2,0x5D, - 0x2A,0x68,0x90,0x30,0xDF,0xC0,0xF6,0xBE,0x82,0x96,0x9C,0x26,0xAA,0x23,0xFB,0x05, - 0xC0,0xC2,0xE5,0xED,0x91,0xEF,0x44,0x93,0xC2,0x1D,0x53,0xE8,0x73,0xB7,0xBC,0xDB, - 0x3F,0x06,0x19,0xE5,0x40,0x2A,0xA2,0xE0,0x6F,0xA7,0xF7,0x08,0xB5,0xCB,0x90,0x19, - 0x4E,0x94,0xCF,0xD0,0x06,0x90,0xD7,0x60,0x2A,0x12,0x8A,0x54,0xE7,0x0B,0x67,0xEA, - 0x7B,0x02,0x42,0xAF,0xFE,0xA0,0x70,0x0D,0x7E,0xC6,0x28,0x96,0x41,0x55,0x34,0x83, - 0x5A,0x8C,0xBB,0x85,0x67,0xBC,0x0F,0x18,0x81,0x22,0xA4,0x66,0xCA,0x17,0x54,0xF3, - 0x2D,0xFE,0xBE,0xC7,0xAC,0x21,0x7A,0x6A,0x52,0x2E,0xAD,0x45,0x8B,0x39,0xF7,0x57, - 0x67,0x35,0x86,0xB8,0x3C,0x78,0x40,0xE0,0x28,0xD5,0xE9,0x80,0xA2,0xC2,0x07,0xFA, - 0xAC,0x63,0x1B,0xB6,0x8B,0x47,0xAB,0xC4,0xF1,0x29,0x75,0xE4,0x18,0xF6,0xBB,0x5E, - 0x37,0xD9,0x20,0xEA,0x1F,0xBD,0xA2,0xB6,0x1D,0x22,0x67,0x7C,0x13,0x6D,0xFD,0x91, - 0x01,0x34,0x43,0xB8,0xAA,0x8D,0xEA,0x1A,0xB0,0x31,0xCE,0xF1,0xCB,0x0B,0xC4,0x38, - 0xA4,0x85,0x74, -}; - -static void test_developer_id_date(void) { - SecCertificateRef old_devid = SecCertificateCreateWithBytes(NULL, _old_developer_cert, sizeof(_old_developer_cert)); - SecCertificateRef new_devid = SecCertificateCreateWithBytes(NULL, _new_developer_cert, sizeof(_new_developer_cert)); - - CFErrorRef error = NULL; - CFAbsoluteTime time; - is(SecCertificateGetDeveloperIDDate(old_devid, &time, &error), false, "old Developer ID cert returned date"); - is(CFErrorGetCode(error), errSecMissingRequiredExtension, "old Developer ID cert failed with wrong error code"); - CFReleaseNull(error); - - ok(SecCertificateGetDeveloperIDDate(new_devid, &time, &error), "new developer ID cert failed to copy date"); - is(time, 573436800.0, "date in certificate wasn't 2019-03-05 00:00:00Z"); - - CFReleaseNull(old_devid); - CFReleaseNull(new_devid); -} - -int si_15_certificate(int argc, char *const *argv) -{ - plan_tests(49); - - tests(); - test_common_name(); - test_copy_email_addresses(); - test_copy_extension_value(); - test_developer_id_date(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-16-ec-certificate.c b/OSX/sec/Security/Regressions/secitem/si-16-ec-certificate.c deleted file mode 100644 index 0aff5eee..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-16-ec-certificate.c +++ /dev/null @@ -1,1193 +0,0 @@ -/* - * Copyright (c) 2010,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@ - */ - - - -/* - * Copyright (c) 2010,2012,2014 Apple Inc. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include - -#include "shared_regressions.h" - -/* Set this to 1 to test support for the legacy ecdsa-with-specified - signature oid. */ -#define TEST_ECDSA_WITH_SPECIFIED 0 - -/* subject:/C=US/O=Red Hat/CN=ECC CA */ -/* issuer :/C=US/O=Red Hat/CN=ECC CA */ -unsigned char ECCCA_cer[386]={ -0x30,0x82,0x01,0x7E,0x30,0x82,0x01,0x26,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, -0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x30,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,0x30,0x0E,0x06,0x03, -0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,0x31,0x0F,0x30,0x0D, -0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,0x41,0x30,0x20,0x17, -0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x31,0x35,0x37,0x5A,0x18,0x0F, -0x32,0x30,0x35,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x31,0x35,0x37,0x5A,0x30, -0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, -0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, -0x41,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,0x25,0xDF,0xFC,0x2F, -0x17,0xA8,0xED,0xAD,0x1B,0x49,0xBA,0xA9,0xA5,0x9E,0x8B,0x17,0x24,0x39,0x25,0xFF, -0xDD,0x42,0x1F,0xBE,0xAB,0x79,0x99,0x4F,0xC8,0x6D,0x28,0x6B,0x10,0x06,0x1E,0x55, -0xF5,0x12,0x2D,0x96,0x1D,0x7B,0x05,0x99,0x76,0xDA,0xC7,0xD4,0xB7,0x7F,0x18,0x89, -0x27,0x6F,0xA5,0x20,0x09,0x6C,0x72,0xF8,0xC6,0x05,0xCD,0x11,0xA3,0x30,0x30,0x2E, -0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03, -0x02,0x00,0x07,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01, -0xFF,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x02,0x84,0x30,0x09, -0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x47,0x00,0x30,0x44,0x02,0x20, -0x30,0x09,0x1B,0x6F,0xE1,0xB2,0x99,0x8D,0xD1,0x84,0xB1,0xE2,0x9B,0xA4,0x05,0xB0, -0xC9,0x33,0x1D,0xF2,0x82,0x8A,0x57,0x0C,0xE1,0xE4,0xA6,0xC8,0xB3,0x0A,0x49,0x2D, -0x02,0x20,0x46,0x85,0xA2,0x1D,0xC1,0x0F,0xA2,0x94,0x85,0xF5,0x09,0xF7,0x53,0x5A, -0xD8,0x81,0x2A,0xFB,0x02,0x0D,0xD9,0x42,0xE2,0xB4,0xF7,0xB7,0x28,0xDF,0x3A,0xF7, -0x99,0x5C, -}; -/* subject:/C=US/O=Red Hat/OU=ECC p192/CN=jordan.sfbay.redhat.com */ -/* issuer :/C=US/O=Red Hat/CN=ECC CA */ -unsigned char ECCp192_cer[382]={ -0x30,0x82,0x01,0x7A,0x30,0x82,0x01,0x21,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, -0x81,0x7D,0x68,0xFA,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, -0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, -0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, -0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x37,0x34, -0x36,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x37,0x34,0x36, -0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, -0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, -0x20,0x70,0x31,0x39,0x32,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, -0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, -0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x49,0x30,0x13,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,0x03,0x32, -0x00,0x04,0x5E,0x73,0x9E,0x99,0xB2,0xCB,0xC8,0x29,0x9B,0x6A,0x60,0xE2,0x5C,0x04, -0x38,0x61,0x42,0x76,0x4E,0xFA,0xC0,0x74,0x82,0x43,0x7F,0x73,0x98,0x03,0x8A,0x98, -0x6D,0x49,0x76,0x35,0x4F,0xD6,0x5B,0x39,0x4F,0x93,0x57,0x2D,0xE8,0xFE,0xD4,0x1B, -0xD5,0x26,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, -0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xD0,0xDA,0x8B,0xD0, -0xCD,0x6A,0x49,0x59,0xD7,0xBF,0xFB,0xAA,0xFF,0x9D,0x86,0xBF,0xF1,0x08,0xA6,0x8D, -0xE8,0x0E,0x34,0x18,0x06,0xCE,0x1D,0x26,0x3D,0x2E,0xFF,0xB4,0x02,0x20,0x5D,0x34, -0x70,0xDC,0x65,0xBE,0xC3,0x86,0x3B,0xEF,0x4A,0xBA,0x25,0x6C,0x76,0xC1,0x78,0x3D, -0xFB,0xD9,0xCF,0xD8,0x63,0x0A,0x76,0x24,0x04,0x82,0x82,0xDB,0x47,0xBE, -}; -/* subject:/C=US/O=Red Hat/OU=ECC p224/CN=jordan.sfbay.redhat.com */ -/* issuer :/C=US/O=Red Hat/CN=ECC CA */ -unsigned char ECCp224_cer[388]={ -0x30,0x82,0x01,0x80,0x30,0x82,0x01,0x26,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, -0x81,0x7D,0x69,0xB5,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, -0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, -0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, -0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x39,0x32, -0x35,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x39,0x32,0x35, -0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, -0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, -0x20,0x70,0x32,0x32,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, -0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, -0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x4E,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x21,0x03,0x3A,0x00,0x04,0xB1, -0x41,0x9F,0x63,0x9A,0xFB,0xBE,0xC5,0xD6,0x2D,0xDD,0xC2,0x94,0x5E,0x3D,0xAC,0x5A, -0x2C,0x85,0xD5,0xE7,0x4C,0xC4,0x67,0xF5,0xA7,0x27,0x99,0xC8,0x2D,0x8D,0x90,0x9A, -0x50,0xFD,0x9A,0x5C,0x87,0xA5,0x24,0xDE,0x1F,0x01,0x9D,0xCE,0xDF,0x75,0x93,0x14, -0x54,0x04,0x1C,0x9F,0x03,0x44,0x20,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60, -0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09, -0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x49,0x00,0x30,0x46,0x02,0x21, -0x00,0xEA,0xCC,0x97,0xB3,0xF3,0xF2,0x23,0xF1,0xAB,0x90,0x4D,0x74,0x03,0x46,0xF9, -0xE0,0x04,0x84,0x20,0xC1,0xD6,0x4B,0xC0,0xC1,0xE4,0x73,0xD8,0x91,0x28,0x13,0x0D, -0xD5,0x02,0x21,0x00,0xAF,0xF7,0x8F,0x5F,0x58,0xD1,0x9F,0x15,0xD1,0x14,0x3B,0x4C, -0xA8,0xA2,0x01,0xBA,0x31,0x85,0xEC,0x6A,0x36,0x5B,0x6B,0x64,0xF4,0x2E,0x0E,0x2D, -0xA9,0x05,0x10,0x6C, -}; -/* subject:/C=US/O=Red Hat/OU=ECC p256/CN=jordan.sfbay.redhat.com */ -/* issuer :/C=US/O=Red Hat/CN=ECC CA */ -unsigned char ECCp256_cer[398]={ -0x30,0x82,0x01,0x8A,0x30,0x82,0x01,0x31,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, -0x81,0x7D,0x6A,0x1D,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, -0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, -0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, -0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x30,0x31, -0x39,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x30,0x31,0x39, -0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, -0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, -0x20,0x70,0x32,0x35,0x36,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, -0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, -0x68,0x61,0x74,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,0x02,0x5E,0xC5,0x3F,0x2D,0xB3,0x57,0x12,0xFE,0xDA,0x3D,0x2A,0xE1,0x27, -0xD5,0xBA,0x99,0x56,0xB0,0x1D,0x47,0x3D,0x56,0xEB,0x7D,0xAE,0x72,0xBC,0x7D,0xEA, -0x3F,0xCB,0x5B,0xD8,0x8F,0xA3,0x62,0xB0,0x0C,0xD5,0x14,0x0B,0x11,0x21,0x1A,0x34, -0xDB,0x64,0x96,0x76,0x21,0x15,0xB6,0x17,0x9E,0xB8,0xF6,0x48,0x33,0xBD,0xD3,0x4F, -0xEA,0xA5,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, -0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x4A,0x1D,0x02,0x95,0xC3, -0xD8,0x71,0x6C,0x9E,0x8E,0x9E,0xC1,0x13,0x16,0xC5,0x7D,0x76,0x5C,0xB0,0x77,0x7C, -0x37,0x0A,0xB6,0x7E,0x85,0xB1,0xDA,0x7C,0x32,0x52,0xBA,0x02,0x21,0x00,0xAC,0x8F, -0x49,0x7D,0x42,0x6D,0x6D,0x03,0x6C,0x8B,0x0B,0x64,0x9C,0xFA,0x9B,0x08,0x05,0xD0, -0x1D,0x4D,0xA9,0xF0,0x07,0x83,0x95,0xBE,0xB7,0x0E,0x9E,0xBE,0xC6,0x75, -}; -/* subject:/C=US/O=Red Hat/OU=ECC p384/CN=jordan.sfbay.redhat.com */ -/* issuer :/C=US/O=Red Hat/CN=ECC CA */ -unsigned char ECCp384_cer[427]={ -0x30,0x82,0x01,0xA7,0x30,0x82,0x01,0x4E,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, -0x81,0x7D,0x6A,0x67,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, -0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, -0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, -0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x30,0x35, -0x39,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x30,0x35,0x39, -0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, -0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, -0x20,0x70,0x33,0x38,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, -0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, -0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x43, -0x52,0x0B,0x54,0x28,0x27,0xB5,0x05,0xEC,0x01,0x7B,0x33,0xF5,0x8F,0x3E,0x69,0xF7, -0xFA,0x93,0x8B,0x46,0xC2,0x1C,0xC8,0x28,0x4D,0xF5,0x8A,0x88,0xEC,0x91,0x9C,0x2E, -0xD0,0x3F,0x2E,0x64,0x84,0x1B,0x3E,0xBD,0xF1,0xDD,0xA9,0xE4,0xC2,0xA8,0x2E,0xD4, -0x98,0x91,0x5F,0xD8,0x21,0x2B,0x1D,0x38,0xB4,0x6D,0xF8,0xE9,0x05,0x5C,0x46,0x1A, -0x2B,0x48,0xA9,0x8F,0xBD,0xC7,0xD9,0xE5,0x75,0xD4,0x1A,0x7B,0x91,0x8D,0x36,0xEE, -0xF0,0xA6,0xB8,0x7C,0xDE,0xEE,0xBB,0x9E,0xF4,0x82,0x63,0xAD,0xA7,0xC3,0x1B,0xA3, -0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01, -0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04, -0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0x9C,0xC0,0x76,0x15,0x17,0xB8,0x44, -0xB9,0x48,0x02,0x74,0xB0,0x02,0x34,0xBE,0x4D,0x06,0xE7,0x05,0x03,0x2C,0xD0,0xF6, -0xEB,0x45,0x5D,0x47,0xA4,0x79,0x9D,0xEE,0x66,0x02,0x20,0x02,0x05,0x84,0xD5,0xDC, -0x9F,0x8A,0xA5,0xEB,0x09,0x58,0x0E,0xB5,0x02,0x71,0x5D,0xF7,0xDF,0x46,0xAE,0x6A, -0x15,0xB0,0xCC,0x7C,0xF0,0x4B,0x56,0xFB,0x20,0x95,0x41, -}; -/* subject:/C=US/O=Red Hat/OU=ECC p5214/CN=jordan.sfbay.redhat.com */ -/* issuer :/C=US/O=Red Hat/CN=ECC CA */ -unsigned char ECCp521_cer[465]={ -0x30,0x82,0x01,0xCD,0x30,0x82,0x01,0x75,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, -0x81,0x7D,0x6A,0xB7,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, -0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, -0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, -0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, -0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x31,0x34, -0x31,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x31,0x34,0x31, -0x5A,0x30,0x55,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, -0x61,0x74,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0B,0x13,0x09,0x45,0x43,0x43, -0x20,0x70,0x35,0x32,0x31,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13, -0x17,0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65, -0x64,0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A, -0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86, -0x00,0x04,0x01,0x71,0xB4,0x18,0xE9,0x83,0x60,0x7E,0x23,0x8F,0xDF,0x40,0xA2,0x95, -0x76,0x3F,0x90,0xBB,0x39,0xAA,0x69,0x44,0x1B,0x5F,0xA4,0x98,0x4A,0xEC,0xED,0x11, -0xC1,0xAE,0x14,0x84,0x5F,0x71,0xB6,0xAF,0x74,0x02,0x6F,0x65,0x31,0x09,0x2F,0x96, -0x96,0x06,0xEC,0xA7,0x88,0x71,0x4A,0xBC,0x60,0x76,0x49,0xF7,0xA6,0x55,0x5A,0xF4, -0xE6,0x6F,0xFC,0xA0,0x01,0x70,0x86,0x93,0xE2,0xC7,0xF6,0xB4,0x98,0x77,0xAA,0x91, -0xAB,0xEA,0xB0,0x70,0x3E,0x81,0xC4,0xB9,0x47,0x67,0xB8,0xCC,0x8D,0x48,0x62,0x9E, -0x3B,0xE3,0xC0,0x40,0x7D,0xF5,0xB4,0x69,0x1F,0xA3,0xEB,0x04,0x68,0x95,0x0A,0x42, -0xC0,0xAC,0xE9,0xCF,0x2E,0xEC,0xA6,0x40,0x41,0x6A,0x30,0x20,0x89,0x57,0x4C,0xEC, -0xC5,0x71,0x50,0x9F,0x1E,0x87,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86, -0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06, -0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x6D, -0x48,0x0F,0x69,0xDA,0xB8,0x48,0x51,0x43,0xF5,0x02,0xD8,0x94,0xFA,0xFF,0xC9,0x23, -0xEF,0xFF,0xD6,0xAA,0xC4,0x90,0xDB,0xE0,0xA4,0xEA,0xB4,0xCF,0x54,0xED,0xFD,0x02, -0x20,0x55,0xB4,0xC1,0x2C,0x62,0x52,0x7E,0x70,0x46,0xFA,0x67,0xEF,0xB4,0xD4,0x94, -0xEF,0x29,0xDC,0x71,0x46,0x5D,0x48,0x61,0x94,0x2B,0x6E,0xA8,0x62,0x1D,0xF9,0x13, -0x1F, -}; - -#if TEST_ECDSA_WITH_SPECIFIED -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P256_Specified_SHA1_cer[574]={ -0x30,0x82,0x02,0x3A,0x30,0x82,0x01,0xD6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xE4, -0xDD,0xA2,0x79,0x22,0x46,0xAF,0x9D,0x4A,0x71,0xDA,0xBC,0x68,0x30,0x70,0x63,0x30, -0x14,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E, -0x03,0x02,0x1A,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03, -0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,0x50,0x00,0x32, -0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,0x30,0x31,0x30,0x30, -0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,0x31,0x30,0x30,0x30, -0x30,0x30,0x30,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x03,0x1E, -0x2E,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00, -0x36,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,0x69,0x00,0x66,0x00, -0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,0x00,0x31,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2, -0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4, -0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85, -0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F, -0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0xA3,0x81,0xD1,0x30,0x81,0xCE, -0x30,0x81,0xCB,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67, -0x86,0xA3,0x53,0x01,0x04,0x81,0xB7,0x30,0x81,0xB4,0x04,0x12,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x18, -0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36,0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69, -0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14, -0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00, -0x35,0x00,0x36,0x00,0x04,0x68,0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD, -0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57, -0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85, -0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62, -0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9, -0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20,0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B, -0xEC,0x08,0xB5,0x78,0x19,0x16,0x88,0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x14, -0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03, -0x02,0x1A,0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xCD,0x27,0x04,0x6A, -0x7A,0xFC,0x0F,0xCA,0xAA,0x17,0xDD,0x62,0xAD,0x56,0x40,0x26,0xBF,0xBB,0x8F,0xFD, -0x47,0x80,0x24,0x09,0x5F,0x05,0x6B,0x61,0x86,0x8B,0xEA,0xC9,0x02,0x20,0x1B,0x57, -0x9B,0x7D,0x07,0x71,0x74,0xEC,0x2E,0xA6,0x7F,0xF3,0x31,0x9F,0x76,0x21,0xA5,0x4E, -0x37,0xAE,0xCB,0xA2,0x7B,0x09,0x3F,0x01,0x66,0x25,0x18,0xE3,0x8F,0x4D, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P256_Specified_SHA256_cer[589]={ -0x30,0x82,0x02,0x49,0x30,0x82,0x01,0xE0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x92, -0x1A,0x37,0x71,0x59,0xAB,0x6E,0xB3,0x48,0x9C,0xC1,0x3E,0xCB,0x20,0x2B,0xA0,0x30, -0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, -0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, -0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, -0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, -0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, -0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03, -0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00, -0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00, -0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x32,0x00,0x35,0x00,0x36,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A, -0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA, -0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0, -0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E, -0x5A,0x1B,0xA3,0x81,0xD3,0x30,0x81,0xD0,0x30,0x81,0xCD,0x06,0x0F,0x2B,0x06,0x01, -0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB9,0x30, -0x81,0xB6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, -0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36, -0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35, -0x36,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00, -0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68, -0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33, -0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA, -0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0, -0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E, -0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F, -0x20,0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16, -0x88,0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, -0x05,0x00,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xB9,0xE7,0x43,0x4B,0x49,0xA9, -0x28,0xE0,0x25,0x6A,0xF6,0x40,0xF8,0xD7,0x08,0x1A,0x90,0x48,0x96,0x2B,0x13,0x23, -0x50,0xE9,0x93,0x18,0xEA,0x0D,0x24,0x79,0xF6,0x40,0x02,0x21,0x00,0xBC,0xB3,0x8D, -0xDF,0x5C,0x96,0xE4,0xB0,0x20,0xBA,0xAE,0x59,0x83,0x1E,0xE6,0x0D,0x06,0x5A,0x0B, -0x3A,0xCB,0xA7,0x52,0xC9,0x20,0x90,0x78,0xA9,0x36,0x11,0xC3,0x9E, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P384_Specified_SHA256_cer[668]={ -0x30,0x82,0x02,0x98,0x30,0x82,0x02,0x30,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xD7, -0x49,0x65,0x6B,0xBB,0x38,0x01,0xB1,0x43,0xDD,0xC2,0xB9,0x37,0xD8,0x2B,0x56,0x30, -0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, -0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, -0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, -0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, -0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, -0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03, -0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00, -0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00, -0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50, -0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, -0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, -0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, -0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, -0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, -0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3, -0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x81,0xFE,0x06,0x0F,0x2B,0x06,0x01,0x04, -0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xEA,0x30,0x81, -0xE7,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61, -0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F, -0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36, -0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, -0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98, -0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44, -0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB, -0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9, -0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11, -0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1, -0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84, -0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2, -0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92, -0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55, -0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, -0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x59,0x2A,0xCA,0xB2,0x04,0x41,0x23, -0xDD,0x0E,0x23,0x58,0xD2,0x02,0xCB,0xB5,0xDA,0x7E,0x2A,0x9D,0xFF,0xC8,0x5F,0x39, -0x11,0xE2,0x45,0x1A,0x75,0x5C,0x76,0xCE,0x7D,0x02,0x21,0x00,0xC9,0x57,0xBB,0x43, -0x27,0xAE,0x84,0x53,0x17,0x11,0xE5,0x9E,0x6C,0x3D,0x14,0xB4,0x71,0x05,0x9F,0x45, -0x9E,0xEF,0x7F,0xF2,0xAF,0xBD,0x57,0xE5,0xE7,0xE4,0x25,0x0F, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x003\x008\x004 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P384_Specified_SHA384_cer[669]={ -0x30,0x82,0x02,0x99,0x30,0x82,0x02,0x30,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xF2, -0x2A,0x87,0x2B,0x7D,0x53,0x13,0xA3,0x4A,0xF1,0x35,0x7C,0xDB,0x23,0x6F,0xA3,0x30, -0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, -0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, -0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, -0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, -0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, -0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03, -0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00, -0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00, -0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x33,0x00,0x38,0x00,0x34,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50, -0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, -0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, -0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, -0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, -0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, -0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3, -0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x81,0xFE,0x06,0x0F,0x2B,0x06,0x01,0x04, -0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xEA,0x30,0x81, -0xE7,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61, -0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F, -0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x33,0x38,0x34, -0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, -0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98, -0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44, -0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB, -0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9, -0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11, -0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1, -0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84, -0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2, -0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92, -0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55, -0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02, -0x05,0x00,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xB8,0x9E,0x1B,0xB7,0x4C,0x37, -0x88,0xD0,0x41,0x96,0xBD,0x8C,0xC4,0xD4,0x51,0xC8,0xF8,0xEB,0xE2,0x40,0x1B,0x15, -0x68,0x36,0xB0,0x72,0x90,0x03,0x7B,0x7C,0xF3,0xD3,0x02,0x21,0x00,0xC2,0x00,0x4F, -0x0D,0xD7,0x3A,0x21,0x3F,0x02,0x3F,0x76,0x4E,0xA8,0xF2,0x70,0x19,0xFF,0x88,0x0A, -0xE8,0xA8,0x50,0xD4,0xD5,0x88,0xFD,0x2E,0x32,0xA4,0xED,0x63,0x4B, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x005\x002\x001\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P521_Specified_SHA1_cer[749]={ -0x30,0x82,0x02,0xE9,0x30,0x82,0x02,0x85,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xBB, -0x17,0x7C,0x5C,0xD2,0x80,0xF2,0x8F,0x4B,0x16,0x8F,0x07,0x9B,0x85,0x90,0x34,0x30, -0x14,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E, -0x03,0x02,0x1A,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03, -0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,0x50,0x00,0x32, -0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,0x30,0x31,0x30,0x30, -0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,0x31,0x30,0x30,0x30, -0x30,0x30,0x30,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x03,0x1E, -0x2E,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00, -0x31,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,0x69,0x00,0x66,0x00, -0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,0x00,0x31,0x30, -0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B, -0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84, -0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78, -0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54, -0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8, -0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E, -0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA, -0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90, -0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED, -0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0xA3,0x82,0x01, -0x3C,0x30,0x82,0x01,0x38,0x30,0x82,0x01,0x34,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01, -0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x82,0x01,0x1F,0x30,0x82, -0x01,0x1B,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, -0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x18,0x45,0x6E,0x64,0x5F,0x50,0x35,0x32,0x31, -0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00, -0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00, -0x41,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x04,0x81,0xCE,0x45, -0x43,0x53,0x36,0x42,0x00,0x00,0x00,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93, -0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9, -0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31, -0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD, -0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28, -0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86, -0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78, -0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01, -0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,0xCB,0x4A, -0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,0x76,0x76,0x2E,0x66,0x17,0x79,0x73,0x85,0x22, -0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,0x57,0x0B, -0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,0x83,0xA8, -0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,0x14,0x06, -0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02, -0x1A,0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x0B,0x00,0xD0,0x87,0x48,0x6E, -0x91,0x69,0x6C,0xBD,0xE1,0x54,0x4E,0xD2,0x4A,0xB6,0x88,0x5E,0xAA,0xC1,0xFE,0xEF, -0xDC,0x6A,0x7C,0x72,0x70,0xFD,0x54,0x47,0x61,0x6C,0x02,0x21,0x00,0xFD,0xD8,0xFE, -0xBB,0xF3,0x60,0x49,0x42,0x77,0x6A,0x2B,0xB6,0x38,0x67,0xA3,0x52,0xE8,0xC1,0xA9, -0x8E,0x81,0xD3,0xC5,0xA0,0x24,0x14,0x3F,0xC8,0xFD,0xBF,0x51,0xC5, -}; -#endif /* TEST_ECDSA_WITH_SPECIFIED */ - -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P256_combined_SHA256_cer[557]={ -0x30,0x82,0x02,0x29,0x30,0x82,0x01,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x56, -0xFE,0xDD,0xC2,0x3F,0xD9,0x7C,0xA3,0x48,0x0E,0x9E,0x46,0x75,0xAE,0x31,0x39,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x1D,0x31,0x1B,0x30, -0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, -0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, -0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, -0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, -0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, -0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, -0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x32,0x00,0x35,0x00,0x36,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A, -0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA, -0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0, -0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E, -0x5A,0x1B,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x81,0xCC,0x06,0x0F,0x2B,0x06,0x01, -0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB8,0x30, -0x81,0xB5,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, -0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36, -0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36, -0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, -0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,0x45, -0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5, -0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02, -0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F, -0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F, -0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20, -0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,0x88, -0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, -0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x7B,0x9C,0x11,0xF8,0x74,0x62, -0x81,0x33,0x42,0x81,0x09,0x93,0x90,0x7D,0x3F,0xA6,0xEA,0xD6,0x47,0x7F,0x02,0xCE, -0x6E,0x2A,0x70,0x69,0x4F,0xE3,0xA0,0x42,0x48,0xB3,0x02,0x21,0x00,0xD2,0x0F,0xFF, -0xF5,0xDB,0x13,0xE7,0xD5,0xB2,0x4D,0x60,0x74,0x41,0xFD,0x7A,0xF7,0x87,0xFA,0x38, -0xFF,0x41,0x62,0xC0,0x60,0xBE,0x85,0x77,0x50,0xE2,0x34,0x64,0x3E, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x005\x001\x002 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P256_combined_SHA512_cer[557]={ -0x30,0x82,0x02,0x29,0x30,0x82,0x01,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x6A, -0x4A,0x02,0x0A,0xE7,0xBD,0x6F,0x90,0x40,0x1F,0xF8,0xF1,0xF6,0x29,0x0B,0x73,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,0x30,0x1D,0x31,0x1B,0x30, -0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, -0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, -0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, -0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, -0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, -0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, -0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x35,0x00,0x31,0x00,0x32,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A, -0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA, -0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0, -0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E, -0x5A,0x1B,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x81,0xCC,0x06,0x0F,0x2B,0x06,0x01, -0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB8,0x30, -0x81,0xB5,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, -0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36, -0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x35,0x31,0x32, -0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, -0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,0x45, -0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5, -0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02, -0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F, -0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F, -0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20, -0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,0x88, -0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, -0x04,0x03,0x04,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0x87,0xA9,0x50,0xE4,0x9D, -0x51,0x56,0x8F,0x29,0xC1,0x0F,0xBD,0x10,0x6D,0x43,0x43,0x10,0x10,0xF3,0x08,0x9C, -0x80,0x16,0x1A,0x5A,0x9F,0x1E,0x96,0x73,0x1C,0x96,0x54,0x02,0x20,0x1D,0x22,0xE1, -0x9B,0x25,0x6E,0x21,0xB4,0x0A,0x64,0xF3,0xC4,0xDB,0x77,0xA4,0x5F,0x15,0x5A,0xAD, -0xA4,0x81,0x68,0xB1,0x55,0xFE,0xD8,0xE6,0x4B,0xC8,0xB9,0x4C,0x95, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P384_combined_SHA1_cer[628]={ -0x30,0x82,0x02,0x70,0x30,0x82,0x02,0x17,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x10, -0x75,0xF7,0x9E,0x1A,0x44,0xE2,0xA6,0x48,0x38,0x44,0x2E,0xAD,0x3D,0x06,0xFD,0x30, -0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x1D,0x31,0x1B,0x30,0x19, -0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00, -0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30, -0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32, -0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x35,0x30,0x33,0x06, -0x03,0x55,0x04,0x03,0x1E,0x2C,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50, -0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x62, -0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41, -0x00,0x31,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06, -0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50,0x39,0x6D,0xDC,0x02,0x89, -0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B, -0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22, -0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D, -0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51, -0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66, -0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3,0x82,0x01,0x01,0x30,0x81, -0xFE,0x30,0x81,0xFB,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF, -0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xE7,0x30,0x81,0xE4,0x04,0x12,0x43,0x65,0x72, -0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04, -0x17,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E, -0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14, -0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00, -0x38,0x00,0x34,0x00,0x04,0x81,0x98,0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50, -0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, -0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, -0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, -0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, -0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, -0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58, -0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55, -0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB, -0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30, -0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02, -0x20,0x5B,0x9F,0x7C,0x3A,0x41,0x10,0x43,0xC5,0x4E,0xF4,0xFA,0xCD,0xB4,0x55,0xE2, -0x93,0x26,0xF9,0x3D,0xB5,0x4D,0x2B,0xE7,0x76,0x73,0x38,0xA0,0x4F,0xB6,0x89,0x63, -0xF7,0x02,0x21,0x00,0xFC,0xD6,0xF7,0x3E,0x9E,0x8E,0x59,0x93,0x5C,0xAA,0x41,0xA2, -0x24,0x9A,0x9F,0xBC,0x37,0xAE,0x45,0x7C,0x3C,0x7C,0xFF,0xC7,0xFE,0x4B,0x61,0x48, -0x9B,0xE8,0xE6,0x38, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P384_combined_SHA256_cer[636]={ -0x30,0x82,0x02,0x78,0x30,0x82,0x02,0x1F,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xA8, -0xC0,0xEA,0x79,0x10,0x6D,0x61,0xAD,0x43,0x66,0xD0,0xDC,0xAC,0x2E,0x51,0x06,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x1D,0x31,0x1B,0x30, -0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, -0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, -0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, -0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, -0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, -0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, -0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, -0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50, -0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, -0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, -0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, -0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, -0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, -0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3, -0x82,0x01,0x04,0x30,0x82,0x01,0x00,0x30,0x81,0xFD,0x06,0x0F,0x2B,0x06,0x01,0x04, -0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xE9,0x30,0x81, -0xE6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61, -0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F, -0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36,0x00, -0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00, -0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98,0x45, -0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90, -0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4, -0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3, -0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F, -0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A, -0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10, -0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,0x71, -0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,0x08, -0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,0x81, -0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, -0x04,0x03,0x02,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x29,0x22,0x02,0x06,0x24,0xB8, -0xED,0xEC,0x12,0xC9,0xE5,0xE0,0xC7,0xB2,0x75,0x12,0x62,0x05,0xED,0x62,0xAF,0x9A, -0x31,0x0D,0x42,0xA7,0x3C,0x03,0x2A,0x76,0xD8,0x1E,0x02,0x20,0x27,0x74,0x0F,0x3B, -0x0A,0x8A,0x7D,0x4F,0x2B,0x76,0x0C,0x34,0x87,0xC8,0xD2,0xC9,0xBC,0xF7,0x0A,0x0D, -0xF9,0x64,0x52,0xD2,0x8D,0xCF,0x9E,0x06,0x90,0xF6,0xE8,0x13, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x005\x002\x001\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P521_combined_SHA1_cer[725]={ -0x30,0x82,0x02,0xD1,0x30,0x82,0x02,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xD2, -0x71,0xD1,0x3D,0x82,0x40,0xE3,0xA9,0x44,0x27,0x3F,0xC6,0x18,0x9A,0x4E,0x44,0x30, -0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x1D,0x31,0x1B,0x30,0x19, -0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00, -0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30, -0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32, -0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x35,0x30,0x33,0x06, -0x03,0x55,0x04,0x03,0x1E,0x2C,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50, -0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x62, -0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41, -0x00,0x31,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, -0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x01,0x8C,0x45,0xFF, -0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2, -0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B, -0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32, -0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05, -0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0, -0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC, -0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C, -0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57, -0xA3,0x82,0x01,0x3B,0x30,0x82,0x01,0x37,0x30,0x82,0x01,0x33,0x06,0x0F,0x2B,0x06, -0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x82,0x01, -0x1E,0x30,0x82,0x01,0x1A,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, -0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x17,0x45,0x6E,0x64,0x5F,0x50, -0x35,0x32,0x31,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41, -0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00, -0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x04,0x81, -0xCE,0x45,0x43,0x53,0x36,0x42,0x00,0x00,0x00,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84, -0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78, -0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54, -0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8, -0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E, -0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA, -0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90, -0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED, -0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16, -0xCB,0x4A,0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,0x76,0x76,0x2E,0x66,0x17,0x79,0x73, -0x85,0x22,0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7, -0x57,0x0B,0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42, -0x83,0xA8,0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30, -0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x49,0x00,0x30,0x46,0x02, -0x21,0x00,0xC2,0xC4,0x47,0x63,0x90,0x43,0xDD,0x8C,0x62,0x6D,0x6F,0xC9,0xBE,0xDF, -0x5E,0x85,0xDD,0x66,0xBC,0x50,0x3C,0x05,0xBA,0x1A,0x08,0x5B,0xE9,0x4F,0x53,0xA1, -0x0E,0x93,0x02,0x21,0x00,0xDC,0xD6,0xA2,0x50,0x24,0x7C,0x62,0xFA,0x29,0x8B,0x97, -0x8B,0x17,0x6F,0x1F,0x19,0x40,0x7B,0x50,0x7C,0xED,0xCE,0xB0,0xF5,0x6E,0xCA,0xE6, -0xD2,0xFF,0xB2,0x10,0xBB, -}; -/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x005\x001\x002 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char End_P521_combined_SHA512_cer[733]={ -0x30,0x82,0x02,0xD9,0x30,0x82,0x02,0x7E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, -0xC5,0xA8,0x41,0x8A,0xCD,0x27,0xBB,0x44,0x7A,0x81,0xFE,0x64,0xBC,0xC2,0x86,0x30, -0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,0x30,0x1D,0x31,0x1B,0x30, -0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, -0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, -0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, -0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, -0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, -0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, -0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, -0x41,0x00,0x35,0x00,0x31,0x00,0x32,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86, -0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00, -0x04,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4, -0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C, -0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98, -0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C, -0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0, -0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6, -0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B, -0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82, -0x02,0xE4,0xCB,0xF8,0x57,0xA3,0x82,0x01,0x3D,0x30,0x82,0x01,0x39,0x30,0x82,0x01, -0x35,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3, -0x53,0x01,0x04,0x82,0x01,0x20,0x30,0x82,0x01,0x1C,0x04,0x12,0x43,0x65,0x72,0x74, -0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19, -0x45,0x6E,0x64,0x5F,0x50,0x35,0x32,0x31,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65, -0x64,0x5F,0x53,0x48,0x41,0x35,0x31,0x32,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04, -0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x35, -0x00,0x32,0x00,0x31,0x00,0x04,0x81,0xCE,0x45,0x43,0x53,0x36,0x42,0x00,0x00,0x00, -0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7, -0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23, -0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24, -0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1, -0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74, -0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2, -0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2, -0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02, -0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,0xCB,0x4A,0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4, -0x76,0x76,0x2E,0x66,0x17,0x79,0x73,0x85,0x22,0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00, -0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,0x57,0x0B,0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB, -0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,0x83,0xA8,0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF, -0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04, -0x03,0x04,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xD3,0xE5,0x57,0xD9,0xA3,0x26, -0x56,0x5F,0x1D,0x5C,0x88,0x1B,0x63,0x80,0x33,0x22,0x5D,0x35,0x52,0x3F,0x29,0xFC, -0xFF,0x5E,0x5D,0xBE,0x80,0x4D,0xCD,0xC4,0xA1,0x27,0x02,0x21,0x00,0xAC,0xA0,0x01, -0x4F,0x29,0xC3,0xA9,0x04,0xE3,0xB9,0xCB,0xA3,0xF7,0xF0,0x80,0x5C,0x61,0xCF,0x1F, -0x8B,0xEE,0x79,0xBD,0x16,0x2D,0x5B,0xF3,0xBD,0xF2,0x84,0x49,0xF8, -}; -/* subject:/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ -unsigned char RootP256_cer[539]={ -0x30,0x82,0x02,0x17,0x30,0x82,0x01,0xB0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x8F, -0x92,0x09,0xDB,0xA4,0xFC,0xDA,0xA1,0x45,0xC2,0xFA,0x59,0x87,0xC6,0xEA,0xE6,0x30, -0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, -0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, -0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, -0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, -0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, -0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03, -0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00, -0x50,0x00,0x32,0x00,0x35,0x00,0x36,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,0x85,0x59,0x2A,0x87,0x8E,0x6A,0x9B,0xB9,0x19,0xD4,0x73,0x82,0x24,0xC1, -0x03,0x15,0xB3,0xF1,0x70,0x88,0x1B,0xAA,0xBA,0x57,0xE8,0x76,0x9F,0xC0,0xCE,0xF6, -0xA9,0xBB,0x19,0xF5,0x6B,0x09,0x63,0xFB,0x69,0xA1,0x3D,0x88,0x67,0x3E,0x7E,0x1F, -0x7B,0x18,0xC8,0xF2,0x31,0xE6,0xD7,0x54,0xD5,0xA7,0xAA,0x09,0x9C,0x15,0xD1,0x8D, -0x37,0x7F,0xA3,0x81,0xC3,0x30,0x81,0xC0,0x30,0x81,0xBD,0x06,0x0F,0x2B,0x06,0x01, -0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xA9,0x30, -0x81,0xA6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, -0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x0A,0x52,0x4F,0x4F,0x54,0x5F,0x50,0x32,0x35, -0x36,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00, -0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68, -0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x85,0x59,0x2A,0x87,0x8E,0x6A,0x9B,0xB9, -0x19,0xD4,0x73,0x82,0x24,0xC1,0x03,0x15,0xB3,0xF1,0x70,0x88,0x1B,0xAA,0xBA,0x57, -0xE8,0x76,0x9F,0xC0,0xCE,0xF6,0xA9,0xBB,0x19,0xF5,0x6B,0x09,0x63,0xFB,0x69,0xA1, -0x3D,0x88,0x67,0x3E,0x7E,0x1F,0x7B,0x18,0xC8,0xF2,0x31,0xE6,0xD7,0x54,0xD5,0xA7, -0xAA,0x09,0x9C,0x15,0xD1,0x8D,0x37,0x7F,0x61,0x97,0x7D,0x85,0xBF,0x7E,0x4E,0xD5, -0x70,0x08,0xF2,0xE8,0xB5,0xBC,0x39,0x59,0xB3,0x23,0x97,0x5F,0xD4,0xCB,0x63,0x74, -0xB9,0x88,0x6D,0xD6,0xF4,0xB8,0x20,0xA8,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, -0x05,0x00,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x44,0xC4,0xBD,0x7A,0xDE,0x6F,0x41, -0xA6,0x78,0x82,0xFD,0x32,0xB7,0x55,0xCA,0xE3,0x21,0x01,0x1C,0xD5,0x6A,0x0B,0x19, -0xA4,0xA9,0x4D,0x06,0x6F,0xB2,0xE8,0xBF,0x9E,0x02,0x20,0x20,0x1C,0x24,0xEA,0x39, -0x24,0xEB,0x91,0xBE,0x73,0x76,0xAF,0xFC,0x99,0x60,0xEC,0x22,0xFD,0x43,0xBF,0xDA, -0xF3,0x7F,0xE4,0x8E,0x6C,0xA5,0x46,0xBF,0x64,0x01,0x3D, -}; - -/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */ -/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */ -unsigned char secp256r1ca_cer[825]={ -0x30,0x82,0x03,0x35,0x30,0x82,0x02,0xDD,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, -0xC5,0x80,0x5F,0x51,0x16,0xE3,0xA8,0x04,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41, -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,0x26,0x30,0x24,0x06,0x03,0x55,0x04, -0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74, -0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73, -0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20, -0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22, -0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, -0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, -0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39, -0x35,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35, -0x33,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A, -0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65, -0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31, -0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43, -0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30, -0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65, -0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,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,0xDC,0xC0,0x0F,0x8D, -0xF5,0xED,0x3E,0x9B,0x6F,0x5A,0x22,0xA3,0x52,0x76,0x6B,0x0B,0xB2,0x6F,0x6C,0x12, -0x17,0xBA,0x24,0xB8,0x7C,0x1B,0x16,0x17,0xD3,0xB9,0x78,0x2F,0x2E,0xC4,0x1C,0x01, -0x68,0x77,0xE0,0xC7,0x79,0x48,0x9E,0xF5,0xD6,0xB3,0x7B,0x6A,0x7F,0xAC,0x12,0xBD, -0x11,0x57,0x21,0x3A,0x87,0xAC,0xE0,0x42,0x40,0xFC,0x0D,0x4C,0xA3,0x82,0x01,0x05, -0x30,0x82,0x01,0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x48, -0xF7,0xD9,0x0A,0x7A,0x90,0xA1,0xD1,0x60,0xE9,0x89,0x41,0xC9,0x20,0x42,0xB2,0xB8, -0xD0,0xEE,0x16,0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xC9,0x30,0x81, -0xC6,0x80,0x14,0x48,0xF7,0xD9,0x0A,0x7A,0x90,0xA1,0xD1,0x60,0xE9,0x89,0x41,0xC9, -0x20,0x42,0xB2,0xB8,0xD0,0xEE,0x16,0xA1,0x81,0xA2,0xA4,0x81,0x9F,0x30,0x81,0x9C, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, -0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, -0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,0x03, -0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,0x65, -0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04, -0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,0x6E, -0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,0x09,0x00,0xC5, -0x80,0x5F,0x51,0x16,0xE3,0xA8,0x04,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05, -0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, -0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x79,0x72,0xE8,0x77,0xD2,0xBB,0x03,0x75,0x46, -0x47,0x0F,0xF7,0xC0,0xC5,0xEB,0x9F,0x13,0x54,0x03,0xE2,0xB8,0xCB,0x37,0xC0,0x7F, -0x53,0xA5,0x0B,0x2F,0x3D,0xDB,0x79,0x02,0x20,0x6A,0xAE,0xDF,0xEF,0x41,0xE6,0x56, -0x60,0x1D,0x6B,0xC7,0x89,0x60,0x64,0x8E,0x99,0x01,0xA9,0xE8,0x01,0xA7,0x9B,0x75, -0xED,0x8C,0x95,0xE0,0xAD,0x40,0x2F,0x17,0x07, -}; -/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp256r1server-secp256r1ca)/CN=dev.experimentalstuff.com */ -/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */ -unsigned char secp256r1server_secp256r1ca_cer[578]={ -0x30,0x82,0x02,0x3E,0x30,0x82,0x01,0xE5,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73, -0xB5,0xC2,0x3A,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81, -0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75, -0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C, -0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73, -0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55, -0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65, -0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17, -0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x31,0x35,0x5A,0x17,0x0D, -0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x31,0x35,0x5A,0x30,0x81,0xB2, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, -0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, -0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03, -0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72, -0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x73,0x65,0x72,0x76,0x65, -0x72,0x2D,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x63,0x61,0x29,0x31,0x22, -0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, -0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,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,0x47,0x09,0x8C, -0x61,0x41,0xD7,0xA6,0x9F,0x4B,0x7D,0xB0,0xE6,0x93,0x7D,0xF2,0x58,0xE8,0xC0,0x7F, -0xD7,0xE5,0xCF,0x8D,0xC8,0x1E,0xA1,0x6A,0xDB,0x16,0xBA,0x6D,0xCC,0xEF,0x72,0x1B, -0x7B,0x64,0x39,0x1A,0xED,0x49,0x92,0x39,0x54,0x3C,0x03,0xC7,0x76,0x15,0xD8,0xC6, -0x06,0x5A,0x80,0x9C,0x42,0xAF,0x08,0x79,0x71,0xAB,0x0E,0x35,0x4A,0x30,0x09,0x06, -0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x7F, -0xBE,0x32,0x64,0x5A,0x63,0xB2,0x21,0xC9,0x27,0x22,0xE8,0x71,0x9F,0xB0,0x00,0x83, -0xA2,0xD9,0x43,0x0E,0xDE,0xA4,0xBE,0x92,0x4E,0x09,0x35,0xD0,0x4B,0x41,0xBC,0x02, -0x21,0x00,0xC0,0xD0,0x3E,0xE3,0xFC,0x15,0x78,0x4B,0xED,0x8D,0xE9,0xDD,0x80,0xB5, -0xFB,0x89,0xC3,0x4A,0xDF,0x72,0xF9,0xDD,0xF2,0xBD,0x0A,0xA8,0x99,0xA2,0xF7,0xE2, -0xC3,0xBA, -}; -/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */ -/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */ -unsigned char secp384r1ca_cer[887]={ -0x30,0x82,0x03,0x73,0x30,0x82,0x02,0xFA,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, -0xC2,0xA9,0x40,0xC7,0xF5,0x21,0x4A,0x02,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41, -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,0x26,0x30,0x24,0x06,0x03,0x55,0x04, -0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74, -0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73, -0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20, -0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22, -0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, -0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, -0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39, -0x35,0x34,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35, -0x34,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A, -0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65, -0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31, -0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43, -0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30, -0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65, -0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F, -0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05, -0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xC6,0x97,0x31,0x8C,0x95,0x62,0x93, -0x7A,0x41,0x67,0xBE,0xE5,0x3A,0x53,0x37,0xCA,0xFD,0x8D,0xB0,0x0F,0x50,0x43,0xBF, -0x62,0xE4,0x76,0xDC,0x73,0x97,0xE4,0xAA,0xB5,0x6C,0xFD,0x06,0xA0,0x5F,0x7A,0xB9, -0x7C,0x79,0xDD,0x7D,0x15,0xD0,0x43,0xA7,0x71,0xFF,0xE7,0x6A,0xF4,0xDD,0xF5,0xEE, -0xE8,0x17,0x80,0x4E,0x82,0x40,0xAC,0x1D,0xED,0x1B,0x0F,0x6A,0x7C,0x6F,0xCD,0x88, -0x21,0xB4,0x3D,0xE7,0x72,0xB7,0x0C,0x34,0xFA,0x78,0x85,0xB8,0x4D,0x71,0x7B,0x62, -0xF4,0xBF,0xC4,0x5F,0x41,0xC8,0x8C,0x7F,0x89,0xA3,0x82,0x01,0x05,0x30,0x82,0x01, -0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xEA,0xCB,0x02,0x59, -0x57,0xA6,0xC2,0x49,0xE3,0xA7,0x49,0x0D,0xEB,0x88,0x33,0x34,0x4C,0x37,0xC8,0x31, -0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xC9,0x30,0x81,0xC6,0x80,0x14, -0xEA,0xCB,0x02,0x59,0x57,0xA6,0xC2,0x49,0xE3,0xA7,0x49,0x0D,0xEB,0x88,0x33,0x34, -0x4C,0x37,0xC8,0x31,0xA1,0x81,0xA2,0xA4,0x81,0x9F,0x30,0x81,0x9C,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03, -0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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, -0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69, -0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72, -0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B, -0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33, -0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19, -0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C, -0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,0x09,0x00,0xC2,0xA9,0x40,0xC7, -0xF5,0x21,0x4A,0x02,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01, -0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x68,0x00, -0x30,0x65,0x02,0x30,0x5B,0xF0,0x3E,0xD4,0xF0,0xE8,0xAA,0x3B,0xC6,0x54,0xF6,0x05, -0x2B,0x90,0xCA,0x34,0x63,0x6D,0xC0,0x37,0x9F,0x28,0xDD,0x34,0x9A,0xA5,0x18,0x1E, -0xEE,0xA8,0x80,0xB9,0x43,0x95,0xAD,0xA5,0xA2,0xA0,0xDA,0xEB,0x35,0x5A,0x42,0xDB, -0x3D,0x98,0x23,0x66,0x02,0x31,0x00,0xB9,0xDD,0xB2,0x90,0xBE,0x5A,0x88,0x43,0xE1, -0x9B,0x18,0xC6,0x3A,0x0B,0x9B,0xFE,0x17,0xFC,0xC4,0x4A,0x65,0x62,0x7B,0x4E,0xAF, -0x6D,0xAE,0xEA,0x7B,0x6B,0xC8,0x97,0xA3,0x88,0x06,0x23,0xCE,0x3F,0x97,0x39,0x80, -0x28,0xF8,0x36,0x3D,0x60,0xDE,0xE2, -}; -/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp384r1server-secp384r1ca)/CN=dev.experimentalstuff.com */ -/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */ -unsigned char secp384r1server_secp384r1ca_cer[640]={ -0x30,0x82,0x02,0x7C,0x30,0x82,0x02,0x02,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73, -0xB5,0xC2,0x43,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81, -0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75, -0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C, -0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73, -0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55, -0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65, -0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17, -0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x32,0x32,0x5A,0x17,0x0D, -0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x32,0x32,0x5A,0x30,0x81,0xB2, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, -0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, -0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03, -0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72, -0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x73,0x65,0x72,0x76,0x65, -0x72,0x2D,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x63,0x61,0x29,0x31,0x22, -0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, -0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, -0x6F,0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06, -0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x2E,0xB6,0x93,0xC0,0x46,0xD0, -0xAD,0x39,0x38,0xD2,0x75,0x3B,0xE8,0x8F,0xCC,0x51,0x6B,0xC3,0xAD,0x7E,0x07,0x12, -0x19,0xCD,0xB7,0x65,0xA8,0xAF,0x9D,0x33,0xCC,0x7A,0x4D,0xB5,0xC5,0xA5,0x0E,0x1E, -0xB8,0xC7,0x20,0xC8,0x50,0xEE,0x88,0x83,0x03,0xEE,0x99,0x8F,0x77,0x3C,0xC5,0x11, -0x13,0x63,0x9B,0x13,0x0D,0x73,0x9B,0x68,0xCB,0xC7,0xE9,0x5D,0xDF,0x60,0x87,0x66, -0x15,0x43,0xDC,0xD1,0x60,0xD5,0xEC,0x94,0xCF,0x15,0x16,0x5E,0x59,0xD5,0xE5,0x8C, -0x8C,0x42,0x0E,0x24,0x33,0xE4,0x38,0x45,0xF4,0xA8,0x30,0x09,0x06,0x07,0x2A,0x86, -0x48,0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0x9A,0x76,0xDA, -0xF6,0x4A,0x3C,0xEF,0xC5,0x7A,0xD9,0x6A,0xC0,0xB2,0x1C,0x82,0x1A,0xA8,0xCB,0x4A, -0xEE,0x78,0x2B,0x24,0x15,0x00,0xB9,0xDD,0xF8,0x54,0xD3,0x30,0x32,0x6D,0x38,0x88, -0xCC,0x32,0xF3,0x33,0x70,0x30,0xC3,0x02,0x23,0x1C,0x72,0x2F,0x39,0x02,0x31,0x00, -0xBC,0xA5,0x79,0xA7,0xDA,0xAB,0x3F,0x94,0x87,0x5D,0x16,0x5A,0x78,0x5E,0x9D,0x9E, -0x30,0x11,0xC1,0xAD,0x9E,0xF3,0x2A,0xEC,0xD3,0x8B,0x03,0x6E,0x83,0xB6,0xD0,0x6A, -0x1D,0xD6,0xB8,0x50,0x99,0xC1,0x91,0x11,0x41,0xA3,0x9F,0x8D,0xD2,0x6F,0xA5,0xE9, -}; -/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */ -/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */ -unsigned char secp521r1ca_cer[962]={ -0x30,0x82,0x03,0xBE,0x30,0x82,0x03,0x20,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, -0xD1,0x2B,0x56,0x0F,0xA8,0x93,0xA8,0x80,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, -0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41, -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,0x26,0x30,0x24,0x06,0x03,0x55,0x04, -0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74, -0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73, -0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20, -0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22, -0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, -0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, -0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39, -0x35,0x35,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35, -0x35,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, -0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A, -0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65, -0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31, -0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43, -0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30, -0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65, -0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F, -0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06, -0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0x33,0x52,0x71,0xF2, -0x20,0x84,0x86,0x46,0x37,0x54,0xC8,0xF4,0x0E,0xA2,0x33,0xC1,0x7E,0x2E,0xB0,0x20, -0xC6,0xB2,0x27,0x73,0xB9,0xE6,0x28,0x80,0x6D,0x75,0x86,0x1F,0xB0,0x55,0xB0,0x4F, -0x83,0xFA,0x6D,0x0A,0x8D,0xAC,0xE6,0x62,0xC6,0xB4,0xA6,0x4E,0x26,0x57,0x48,0x65, -0xA1,0xCD,0xA8,0xFE,0x80,0x60,0x1D,0x17,0xCB,0xDF,0xAF,0xCD,0x58,0x01,0x53,0x5E, -0xD6,0x19,0x2E,0x3F,0x78,0x82,0xFF,0x88,0x9A,0x46,0x4F,0x6F,0xC8,0xC0,0xC7,0x36, -0xF2,0x83,0x1D,0x07,0x94,0xC4,0x53,0x48,0x2F,0x65,0x13,0x01,0xF4,0x93,0x97,0x4B, -0xD8,0x98,0xBD,0x42,0xE4,0xA9,0x29,0x61,0x4D,0xFE,0xA8,0x15,0x45,0x4C,0xBA,0x5A, -0xEE,0xE2,0x26,0x93,0x5B,0x37,0xC1,0x02,0x24,0x4D,0x31,0xF2,0x14,0xB2,0xCC,0xA3, -0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, -0x04,0x14,0x0C,0x0F,0xD9,0xE6,0x4E,0x8C,0x8A,0xBA,0x17,0xCE,0xCF,0xB1,0x28,0xE9, -0xAA,0x78,0x91,0xCF,0x16,0x69,0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81, -0xC9,0x30,0x81,0xC6,0x80,0x14,0x0C,0x0F,0xD9,0xE6,0x4E,0x8C,0x8A,0xBA,0x17,0xCE, -0xCF,0xB1,0x28,0xE9,0xAA,0x78,0x91,0xCF,0x16,0x69,0xA1,0x81,0xA2,0xA4,0x81,0x9F, -0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D, -0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73, -0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30, -0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20, -0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06, -0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69, -0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82, -0x09,0x00,0xD1,0x2B,0x56,0x0F,0xA8,0x93,0xA8,0x80,0x30,0x0C,0x06,0x03,0x55,0x1D, -0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, -0x3D,0x04,0x01,0x03,0x81,0x8C,0x00,0x30,0x81,0x88,0x02,0x42,0x01,0x80,0xFF,0x46, -0x4F,0x45,0x30,0xF9,0x34,0x67,0x33,0x6B,0x5C,0x21,0xCA,0x45,0xD5,0xE4,0x8C,0x1A, -0x9F,0xB2,0x80,0x79,0x55,0x84,0x63,0x14,0x84,0x27,0x23,0x3F,0x3E,0xC4,0x40,0x02, -0x2A,0xA1,0xE3,0x76,0x66,0x1D,0xE1,0xD8,0xD1,0xEA,0x5E,0x8D,0x03,0x8A,0x25,0x29, -0x09,0xFE,0x2D,0x4C,0x04,0xDA,0x19,0xAD,0xA2,0x6E,0xAB,0x7A,0xCD,0x86,0x02,0x42, -0x01,0x3C,0x39,0x41,0x73,0x01,0xB3,0xA0,0x3C,0x54,0xE0,0x24,0x10,0x6F,0xFA,0xCF, -0x70,0x51,0x0C,0x68,0x0E,0x48,0xE1,0xFA,0x46,0x75,0x23,0x58,0xB4,0x82,0x43,0x91, -0x73,0x65,0xB9,0x51,0xC0,0x3E,0x4B,0xFE,0xB8,0xAF,0x65,0xAE,0x1B,0x23,0xBA,0xFA, -0x55,0x6E,0x1E,0xFA,0xFA,0x63,0x37,0x07,0xD6,0xE0,0xE1,0x3A,0xBA,0xF8,0xFC,0x5B, -0x28,0xDD, -}; -/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp521r1server-secp521r1ca)/CN=dev.experimentalstuff.com */ -/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */ -unsigned char secp521r1server_secp521r1ca_cer[714]={ -0x30,0x82,0x02,0xC6,0x30,0x82,0x02,0x28,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73, -0xB5,0xC2,0x4C,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81, -0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, -0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75, -0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C, -0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06, -0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73, -0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55, -0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65, -0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17, -0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x33,0x30,0x5A,0x17,0x0D, -0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x33,0x30,0x5A,0x30,0x81,0xB2, -0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, -0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, -0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, -0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03, -0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72, -0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x73,0x65,0x72,0x76,0x65, -0x72,0x2D,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x63,0x61,0x29,0x31,0x22, -0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, -0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, -0x6F,0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, -0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0xC9,0x8F,0xA5, -0x49,0x40,0x30,0x24,0x4E,0x61,0x3C,0x45,0x02,0xC2,0xE7,0x1C,0x7A,0xB7,0x5F,0xCE, -0x86,0x4C,0xA7,0x77,0x3D,0x1E,0x4C,0x3F,0x7E,0x7B,0xD5,0x8D,0x0A,0x40,0xD1,0x5B, -0xDB,0xD2,0x98,0x81,0x27,0x7F,0x4C,0x44,0x21,0x98,0x8B,0xAD,0xD1,0x6D,0xA4,0x6C, -0x41,0xEC,0x66,0x52,0xAD,0xD7,0x19,0xD6,0xCB,0xF2,0x6C,0x28,0x57,0x46,0x01,0xE6, -0x78,0x8E,0x67,0xD7,0x20,0xE9,0x87,0xAA,0x5D,0x10,0x27,0x91,0xC4,0xBF,0x19,0xBA, -0x07,0x36,0x3B,0x58,0x41,0x6C,0xAC,0xB5,0xAF,0x83,0xF9,0xD7,0xD7,0xF1,0x2D,0x60, -0x60,0x1B,0x97,0x74,0xD6,0x6B,0x6C,0x67,0x40,0x8F,0xD5,0x0F,0xEF,0xE8,0x33,0xFF, -0xD5,0xAB,0x3C,0xE7,0x2D,0xCF,0xA8,0x30,0xC9,0xE8,0x8A,0x2C,0xAB,0x2F,0xA2,0xC3, -0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x81,0x8C,0x00,0x30, -0x81,0x88,0x02,0x42,0x01,0x2B,0xC4,0xEB,0xEA,0xCE,0xB4,0xED,0xE5,0xE1,0xEB,0x74, -0x7E,0x19,0xC5,0x49,0xF8,0x00,0xCF,0x5D,0x04,0x0A,0x97,0xDF,0x78,0xCA,0x5C,0x12, -0x8D,0xB9,0x18,0x26,0xC9,0x82,0x31,0xA0,0x83,0xB6,0x73,0x6B,0x6A,0x91,0xDC,0x42, -0xAD,0x79,0x9E,0xB9,0xD1,0x59,0x98,0x51,0x84,0x10,0x1A,0x2B,0xE5,0xB8,0x36,0x44, -0xC2,0x3A,0xA6,0x47,0x28,0x5B,0x02,0x42,0x01,0xEE,0x93,0x23,0x1D,0x0A,0x71,0xA1, -0x7A,0x0F,0x5C,0x16,0xF6,0xD9,0x66,0x45,0x76,0x7E,0xF3,0xCF,0x12,0x4B,0xA1,0x6A, -0x05,0xD5,0x70,0x9F,0x86,0xBC,0xFF,0xA4,0xEB,0x4F,0x14,0x06,0x98,0x30,0xFA,0xA9, -0x54,0xF0,0x19,0xCA,0x3B,0xEA,0xE9,0xA3,0x1E,0x76,0xA6,0xE7,0x42,0x9C,0xBE,0x0E, -0xA2,0x04,0x08,0xDF,0x49,0x49,0xB0,0x8F,0xFE,0x7A, -}; - - -#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); } -#define CFReleaseNull(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); (CF) = NULL; } - -#define trust_ok(CERT, ROOT, DATE, ...) \ -({ \ - test_trust_ok(CERT, sizeof(CERT), ROOT, sizeof(ROOT), DATE, \ - test_create_description(__VA_ARGS__), test_directive, test_reason, \ - __FILE__, __LINE__); \ -}) - -static void test_trust_ok(const uint8_t *cert_data, size_t cert_len, - const uint8_t *root_data, size_t root_len, const char *date_str, - CFStringRef CF_CONSUMED testname, const char *directive, - const char *reason, const char *file, int line) { - SecTrustResultType trustResult; - SETUP: { - SecTrustRef trust = NULL; - SecCertificateRef cert, root; - setup("sectrust" /* testname */); - isnt(cert = SecCertificateCreateWithBytes(NULL, cert_data, cert_len), - NULL, "create cert"); - isnt(root = SecCertificateCreateWithBytes(NULL, root_data, root_len), - NULL, "create root"); - - SecPolicyRef policy = SecPolicyCreateSSL(false, NULL); - ok_status(SecTrustCreateWithCertificates(cert, policy, &trust), - "create trust with single cert"); - CFArrayRef anchors = CFArrayCreate(NULL, (const void **)&root, 1, - &kCFTypeArrayCallBacks); - ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors"); - - /* 2006/03/03 00:12:00 */ - CFDateRef date = CFDateCreate(NULL, 163037520.0); - ok_status(SecTrustSetVerifyDate(trust, date), "set date"); - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); - - CFReleaseSafe(date); - CFReleaseSafe(anchors); - CFReleaseSafe(policy); - CFReleaseSafe(root); - CFReleaseSafe(cert); - CFReleaseSafe(trust); - } - - test_ok(trustResult == kSecTrustResultUnspecified, testname, - directive, reason, file, line, - "# unexpected trustResult: %ld\n", trustResult); -} - -/* Test basic add delete update copy matching stuff. */ -static void tests(void) -{ - /* Verification of ECC certs created by Microsoft */ - trust_ok(RootP256_cer, RootP256_cer, - "20060303001200", "RootP256_cer root"); -#if TEST_ECDSA_WITH_SPECIFIED - trust_ok(End_P256_Specified_SHA1_cer, RootP256_cer, - "20060303001200", "End_P256_Specified_SHA1_cer"); - trust_ok(End_P256_Specified_SHA256_cer, RootP256_cer, - "20060303001200", "End_P256_Specified_SHA256_cer"); - trust_ok(End_P384_Specified_SHA256_cer, RootP256_cer, - "20060303001200", "End_P384_Specified_SHA256_cer"); - trust_ok(End_P384_Specified_SHA384_cer, RootP256_cer, - "20060303001200", "End_P384_Specified_SHA384_cer"); - trust_ok(End_P521_Specified_SHA1_cer, RootP256_cer, - "20060303001200", "End_P521_Specified_SHA1_cer"); -#endif /* TEST_ECDSA_WITH_SPECIFIED */ - trust_ok(End_P256_combined_SHA256_cer, RootP256_cer, - "20060303001200", "End_P256_combined_SHA256_cer"); - trust_ok(End_P384_combined_SHA256_cer, RootP256_cer, - "20060303001200", "End_P384_combined_SHA256_cer"); - trust_ok(End_P384_combined_SHA1_cer, RootP256_cer, - "20060303001200", "End_P384_combined_SHA1_cer"); - trust_ok(End_P521_combined_SHA1_cer, RootP256_cer, - "20060303001200", "End_P521_combined_SHA1_cer"); - trust_ok(End_P256_combined_SHA512_cer, RootP256_cer, - "20060303001200", "End_P256_combined_SHA512_cer"); - trust_ok(End_P521_combined_SHA512_cer, RootP256_cer, - "20060303001200", "End_P521_combined_SHA512_cer"); - - /* Verification of ECC certs created by NSS */ - trust_ok(ECCCA_cer, ECCCA_cer, - "20060303001200", "ECCCA_cer root"); - trust_ok(ECCp192_cer, ECCCA_cer, - "20060303001200", "ECCp192_cer"); - trust_ok(ECCp256_cer, ECCCA_cer, - "20060303001200", "ECCp256_cer"); - trust_ok(ECCp384_cer, ECCCA_cer, - "20060303001200", "ECCp384_cer"); - trust_ok(ECCp521_cer, ECCCA_cer, - "20060303001200", "ECCp521_cer"); - - /* Verification of ECC certs created by OpenSSL */ - trust_ok(secp256r1ca_cer, secp256r1ca_cer, - "20060303001200", "secp256r1ca_cer root"); - trust_ok(secp256r1server_secp256r1ca_cer, secp256r1ca_cer, - "20060303001200", "secp256r1server_secp256r1ca_cer"); - trust_ok(secp384r1ca_cer, secp384r1ca_cer, - "20060303001200", "secp384r1ca_cer root"); - trust_ok(secp384r1server_secp384r1ca_cer, secp384r1ca_cer, - "20060303001200", "secp384r1server_secp384r1ca_cer"); - trust_ok(secp521r1ca_cer, secp521r1ca_cer, - "20060303001200", "secp521r1ca_cer root"); - trust_ok(secp521r1server_secp521r1ca_cer, secp521r1ca_cer, - "20060303001200", "secp521r1server_secp521r1ca_cer"); -} - -int si_16_ec_certificate(int argc, char *const *argv) -{ -#if TEST_ECDSA_WITH_SPECIFIED - plan_tests(23); -#else /* !TEST_ECDSA_WITH_SPECIFIED */ - plan_tests(18); -#endif /* !TEST_ECDSA_WITH_SPECIFIED */ - - - - tests(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m b/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m deleted file mode 100644 index edd8ed5e..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-18-certificate-parse.m +++ /dev/null @@ -1,191 +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@ - */ - -#include "shared_regressions.h" - -#include -#import - -#include -#include -#include -#include -#include - -const NSString *kSecTestParseFailureResources = @"si-18-certificate-parse/ParseFailureCerts"; -const NSString *kSecTestParseSuccessResources = @"si-18-certificate-parse/ParseSuccessCerts"; -const NSString *kSecTestKeyFailureResources = @"si-18-certificate-parse/KeyFailureCerts"; -const NSString *kSecTestPathFailureResources = @"si-18-certificate-parse/PathFailureCerts"; -const NSString *kSecTestTODOFailureResources = @"si-18-certificate-parse/TODOFailureCerts"; - -static uint64_t num_certs() { - uint64_t num_certs = 0; - NSArray * certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseFailureResources]; - num_certs += [certURLs count]; - certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseSuccessResources]; - num_certs += [certURLs count]; - certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestKeyFailureResources]; - num_certs += [certURLs count]; - certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestPathFailureResources]; - num_certs += [certURLs count]; - certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestTODOFailureResources]; - num_certs += [certURLs count]; - - return num_certs; -} - -static void test_parse_failure(void) { - /* A bunch of certificates with different parsing errors */ - NSArray * certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseFailureResources]; - require_action([certURLs count] > 0, testOut, - fail("Unable to find parse test failure certs in bundle.")); - - [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { - NSData *certData = [NSData dataWithContentsOfURL:url]; - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); - is(cert, NULL, "Successfully parsed bad cert: %@", url); - CFReleaseNull(cert); - }]; - -testOut: - return; -} - -static void test_parse_success(void) { - /* A bunch of certificates with different parsing variations */ - NSArray * certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseSuccessResources]; - require_action([certURLs count] > 0, testOut, - fail("Unable to find parse test failure certs in bundle.")); - - [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { - NSData *certData = [NSData dataWithContentsOfURL:url]; - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); - isnt(cert, NULL, "Failed to parse good cert: %@", url); - CFReleaseNull(cert); - }]; - -testOut: - return; -} - -static void test_key_failure(void) { - /* Parse failures that require public key extraction */ - NSArray * certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestKeyFailureResources]; - require_action([certURLs count] > 0, testOut, - fail("Unable to find parse test failure certs in bundle.")); - - [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { - NSData *certData = [NSData dataWithContentsOfURL:url]; - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); - SecKeyRef pubkey = NULL; - require_action(cert, blockOut, - fail("Failed to parse cert with SPKI error: %@", url)); - pubkey = SecCertificateCopyKey(cert); - is(pubkey, NULL, "Successfully parsed bad SPKI: %@", url); - - blockOut: - CFReleaseNull(cert); - CFReleaseNull(pubkey); - }]; - -testOut: - return; -} - -static void test_path_parse_failure(void) { - NSArray * certURLs = nil; - SecCertificateRef root = nil; - - NSURL *rootURL = [[NSBundle mainBundle] URLForResource:@"root" withExtension:@".cer" subdirectory:@"si-18-certificate-parse"]; - root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)[NSData dataWithContentsOfURL:rootURL]); - require_action(root, testOut, - fail("Unable to create root cert")); - certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestPathFailureResources]; - require_action([certURLs count] > 0, testOut, - fail("Unable to find parse test failure certs in bundle.")); - - [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { - NSData *certData = [NSData dataWithContentsOfURL:url]; - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateBasicX509(); - SecTrustResultType trustResult = kSecTrustResultInvalid; - - require_noerr_action(SecTrustCreateWithCertificates(cert, policy, &trust), blockOut, - fail("Unable to create trust with certificate: %@", url)); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)[NSArray arrayWithObject:(__bridge id)root]), - blockOut, fail("Unable to set trust in root cert: %@", url)); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)[NSDate dateWithTimeIntervalSinceReferenceDate:507200000.0]), - blockOut, fail("Unable to set verify date: %@", url)); - require_noerr_action(SecTrustEvaluate(trust, &trustResult), blockOut, - fail("Failed to evaluate trust with error: %@", url)); - is(trustResult, kSecTrustResultRecoverableTrustFailure, "Got wrong trust result (%d) for %@", trustResult, url); - - require_action(cert, blockOut, - fail("Failed to parse cert with SPKI error: %@", url)); - - blockOut: - CFReleaseNull(cert); - CFReleaseNull(trust); - CFReleaseNull(policy); - }]; - - -testOut: - CFReleaseNull(root); -} - -static void test_todo_failures(void) { - /* A bunch of certificates with different parsing errors that currently succeed. */ - NSArray * certURLs = [[NSBundle mainBundle] URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestTODOFailureResources]; - require_action([certURLs count] > 0, testOut, - fail("Unable to find parse test failure certs in bundle.")); - - [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { - NSData *certData = [NSData dataWithContentsOfURL:url]; - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); - { - NSString *reason = [NSString stringWithFormat:@"Bad cert succeeds: %@",url]; - todo([reason UTF8String]); - is(cert, NULL, "Successfully parsed bad cert: %@", url); - } - CFReleaseNull(cert); - }]; - -testOut: - return; -} - -int si_18_certificate_parse(int argc, char *const *argv) -{ - - plan_tests((int)num_certs()); - - test_parse_failure(); - test_parse_success(); - test_key_failure(); - test_path_parse_failure(); - test_todo_failures(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c b/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c deleted file mode 100644 index 396d72db..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-20-sectrust.c +++ /dev/null @@ -1,987 +0,0 @@ -/* - * Copyright (c) 2006-2010,2012-2018 Apple Inc. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if TARGET_OS_IPHONE -#include -#include -#endif - -#include "shared_regressions.h" -#include "si-20-sectrust.h" - -/* Test SecTrust API. */ -static void basic_tests(void) -{ - SecTrustRef trust = NULL; - CFArrayRef _anchors = NULL, certs = NULL, anchors = NULL, replacementPolicies; - 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; - CFDictionaryRef query = NULL; - - isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), - NULL, "create cert0"); - isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), - NULL, "create cert1"); - const void *v_certs[] = { - cert0, - cert1 - }; - policy = SecPolicyCreateSSL(false, NULL); - certs = CFArrayCreate(NULL, v_certs, - array_size(v_certs), &kCFTypeArrayCallBacks); - - /* SecTrustCreateWithCertificates failures. */ - is_status(SecTrustCreateWithCertificates(kCFBooleanTrue, policy, &trust), - errSecParam, "create trust with boolean instead of cert"); - is_status(SecTrustCreateWithCertificates(cert0, kCFBooleanTrue, &trust), - errSecParam, "create trust with boolean instead of policy"); - - /* SecTrustCreateWithCertificates using array of certs. */ - ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); - - /* NOTE: prior to _int2048A -> _leaf2048A - * _root2048 -> _int512 -> _leaf2048B - * _root2048 -> _int2048B -> _leaf512 - * _root2048 -> _int2048B -> _leaf1024 - * _root2048 -> _int2048B -> _leaf2048C - */ - -/* subject:/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Root CA */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Root CA */ -unsigned char _root512[600]={ - 0x30,0x82,0x02,0x54,0x30,0x82,0x01,0xFE,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0xAF,0x64,0x99,0x71,0x1A,0x67,0x40,0xD8,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8A,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14, - 0x35,0x31,0x32,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F, - 0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33, - 0x30,0x33,0x32,0x34,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x31,0x35,0x32,0x33,0x30, - 0x33,0x32,0x34,0x5A,0x30,0x81,0x8A,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,0x14,0x30, - 0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14,0x35,0x31,0x32, - 0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, - 0x41,0x30,0x5C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01, - 0x05,0x00,0x03,0x4B,0x00,0x30,0x48,0x02,0x41,0x00,0xBE,0x86,0xC0,0x0C,0x4A,0x75, - 0xC7,0xEC,0x8D,0xBF,0x1E,0xFC,0x70,0x58,0x23,0x5E,0xF0,0x61,0x1E,0x59,0x74,0x41, - 0x88,0x19,0x87,0x20,0x87,0x77,0xE3,0x08,0x8A,0x68,0x80,0xE4,0xED,0x35,0xE7,0x85, - 0x52,0x30,0xF7,0xF1,0xC4,0x16,0xED,0x59,0xE8,0xF3,0x40,0x23,0x8E,0x30,0x72,0x40, - 0x22,0x26,0x15,0x9F,0xE4,0x97,0xEB,0x56,0xE8,0xAF,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,0x03,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,0x14,0xE9,0x8B,0x3E,0x9D,0x8A,0xA7,0xCA,0x70,0x97,0x2B,0x9A,0x2C,0x31, - 0xC7,0xF9,0xA2,0x5A,0x4B,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, - 0x01,0x01,0x0B,0x05,0x00,0x03,0x41,0x00,0x6E,0x14,0x08,0x64,0xCD,0x84,0xDB,0xBF, - 0xA4,0x2B,0x5F,0x51,0x5F,0x2D,0x00,0x46,0xA5,0x20,0x28,0x53,0x74,0x90,0x6D,0x24, - 0xD4,0xB9,0x7E,0x0D,0xFD,0x5E,0x65,0x7F,0xB5,0x88,0x96,0xD8,0x54,0xBA,0xBD,0x09, - 0x1C,0x89,0x91,0x5B,0xC4,0x4B,0xD4,0x6B,0xE4,0x4B,0x7A,0xBF,0x62,0x36,0x97,0xF7, - 0x58,0xAC,0xCD,0x9C,0xAF,0x9B,0x02,0x68, -}; - -/* subject:/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ -unsigned char _root2048[996]={ - 0x30,0x82,0x03,0xE0,0x30,0x82,0x02,0xC8,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0xD2,0xA0,0x17,0x6E,0xF4,0xB7,0xF3,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8B,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, - 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, - 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32, - 0x33,0x30,0x34,0x31,0x30,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x31,0x35,0x32,0x33, - 0x30,0x34,0x31,0x30,0x5A,0x30,0x81,0x8B,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,0x14, - 0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30, - 0x34,0x38,0x2D,0x62,0x69,0x74,0x20,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,0xEE,0x68,0xB9,0x94,0x15,0x11,0x2F,0x35,0x36,0xBC,0x9D,0x63, - 0x25,0x8E,0x55,0xE4,0x17,0xE0,0x60,0x9C,0x6D,0x71,0x4C,0x30,0x7B,0xB7,0xEE,0x42, - 0x2D,0xE9,0x05,0x4C,0x41,0x3A,0x19,0x97,0x77,0xCC,0x4C,0xFF,0x81,0x52,0xE8,0xDF, - 0xB7,0x1A,0x75,0x1F,0xD1,0xD7,0x4D,0x21,0x5E,0x79,0xDF,0x7E,0xCF,0x45,0x47,0xF5, - 0x4D,0x05,0xD6,0xB1,0xF3,0xEA,0xF8,0x28,0xD8,0xAC,0x2C,0xCE,0x83,0xBF,0xA5,0x70, - 0x6F,0x5B,0x46,0x39,0xF6,0xC1,0x78,0x56,0x31,0x24,0x7E,0x15,0xCE,0x04,0x50,0x99, - 0x30,0xDA,0xF0,0xAE,0x23,0xDD,0x86,0x54,0xAD,0xBC,0x55,0x45,0x93,0xCC,0xC8,0xE7, - 0x16,0x46,0x00,0x34,0x2C,0x8C,0x8F,0x31,0xED,0x08,0x3F,0xD9,0xA6,0x90,0x32,0x37, - 0x1B,0xCD,0xD4,0x16,0x83,0xEE,0xF9,0x52,0x80,0x3E,0x27,0x26,0xEF,0xEF,0xF9,0xFD, - 0xA6,0xD5,0x38,0x83,0xD9,0x8F,0xB6,0xF0,0xA1,0x0D,0x4F,0x89,0x8D,0x7C,0x14,0x7D, - 0x8F,0x7A,0x84,0xF9,0xCB,0x8C,0x68,0x9E,0xF3,0x0E,0x2C,0x68,0xBF,0x37,0x69,0x2A, - 0x67,0x90,0x7D,0xAF,0xF0,0x7B,0x38,0xBC,0xB3,0x77,0xD1,0xDD,0xF4,0x5E,0x3F,0xA0, - 0x48,0xE8,0xBA,0x59,0xD8,0xB6,0xFF,0x51,0x7C,0xB8,0xCE,0xAE,0x02,0x5A,0x71,0x1E, - 0xD6,0x5A,0x0A,0x55,0x27,0x29,0x9C,0xC2,0xF6,0x8B,0x0E,0x0D,0xFA,0xF3,0x3F,0x60, - 0x17,0xE8,0xFA,0x98,0xC0,0x92,0xD7,0x14,0x9B,0xD1,0x3E,0x03,0xE4,0x8D,0x58,0xFF, - 0x4C,0x01,0x77,0x74,0x83,0x01,0xA6,0xB1,0x81,0x34,0x26,0x0D,0xF8,0xAA,0x08,0xF2, - 0xDC,0xEA,0x32,0x11,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, - 0x03,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,0xCA,0x4D,0x8B,0xBD, - 0x98,0x36,0x22,0xF8,0xA9,0x21,0x8E,0xEA,0xFC,0xE6,0xD7,0x17,0x81,0xA7,0xE2,0x12, - 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, - 0x82,0x01,0x01,0x00,0x99,0x99,0xDB,0x59,0xEE,0x32,0x98,0x1C,0xE4,0x62,0xE4,0xF9, - 0xA5,0xE9,0xA4,0x3F,0x49,0x57,0x37,0x71,0x34,0x3E,0x68,0xAE,0x27,0xB4,0xAF,0xCB, - 0x96,0xFD,0xA8,0x0A,0xE7,0x0A,0x22,0x7C,0x5E,0x78,0x95,0xA9,0x67,0xAF,0xB4,0xDD, - 0x09,0xD1,0xE5,0x0C,0x6B,0xC6,0xD8,0x1A,0xE3,0x91,0x5F,0xBD,0xD0,0xB9,0x0F,0x1D, - 0xB9,0xB7,0xF1,0xC7,0x64,0xCA,0xAB,0x69,0x6E,0xD0,0x61,0xB3,0x9F,0x27,0x1E,0x06, - 0xB6,0x42,0x84,0xAB,0x6F,0xE7,0x2B,0xBC,0x04,0x28,0x64,0xC2,0xC0,0x1D,0x43,0xFF, - 0x2A,0x1D,0x3F,0x92,0xA1,0xD7,0xD5,0xFB,0x04,0xF9,0x57,0x9F,0x78,0x87,0x8C,0xDB, - 0xB3,0x3F,0x41,0x96,0x8E,0x65,0x50,0x39,0xE7,0xD0,0x8A,0x39,0x29,0x68,0x12,0x11, - 0x44,0xDD,0x7B,0x86,0x59,0xAF,0x40,0xEA,0x78,0xD9,0xDD,0xB5,0xDB,0xA7,0x7F,0xD4, - 0xBA,0x94,0x8D,0x7D,0xA5,0xD0,0xAA,0x48,0x42,0x1E,0x6C,0x71,0x33,0x49,0xCA,0x0D, - 0xF5,0x8D,0x10,0xD0,0x3E,0xF8,0xD3,0x35,0xAE,0x83,0xCA,0x02,0x23,0xC2,0xCD,0x21, - 0x75,0x9B,0x2C,0xE0,0xF7,0x23,0x26,0x04,0xED,0x78,0xE8,0x29,0x33,0x87,0x65,0x98, - 0x4C,0x7E,0xC3,0x61,0xB5,0xDB,0x66,0xBD,0x9D,0x3D,0xC9,0x02,0x7A,0xB8,0xA2,0x7C, - 0x81,0x8B,0x10,0xB5,0x97,0x63,0x85,0x2B,0x19,0x94,0xB3,0x4C,0x8D,0xED,0x76,0xCE, - 0x31,0x49,0xCC,0x22,0x67,0xFB,0xDA,0x6A,0x0A,0xE2,0x56,0xCD,0x51,0x6A,0x6E,0x54, - 0xDF,0x04,0x1A,0xBE,0x77,0xB9,0x28,0x2F,0xCA,0xA5,0xA5,0xF4,0xF1,0xE5,0x12,0x1B, - 0x2D,0x60,0xB7,0xA7, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 1 */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Root CA */ -unsigned char _int2048A[809]={ - 0x30,0x82,0x03,0x25,0x30,0x82,0x02,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x76, - 0xCD,0xF6,0x90,0x52,0xAA,0x72,0x81,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, - 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8A,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, - 0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C, - 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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14,0x35, - 0x31,0x32,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74, - 0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30,0x32,0x30, - 0x38,0x34,0x31,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x30,0x32,0x30,0x38, - 0x34,0x31,0x5A,0x30,0x77,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A, - 0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C, - 0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20, - 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x31,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,0xF2,0x04, - 0x31,0xBD,0x86,0x8D,0x5A,0x0C,0xF1,0xDF,0x48,0xBE,0xD3,0x98,0x61,0x50,0x75,0x95, - 0xCB,0x1D,0xE3,0x0D,0x17,0x3F,0xEC,0xD6,0xEA,0x5C,0xB7,0x75,0xEB,0x3B,0x73,0x09, - 0x69,0x35,0xD2,0x82,0xF8,0x08,0xAE,0xF0,0xF5,0xC1,0xCA,0xFB,0x84,0x3E,0x36,0xAE, - 0xCB,0xF9,0x59,0x61,0xE2,0x18,0xED,0x77,0xF8,0xCC,0x75,0x3E,0x4B,0x98,0x81,0x2B, - 0x04,0x04,0xEE,0xC5,0x79,0x64,0xBB,0x77,0xED,0xA1,0xC3,0x6C,0x80,0xD7,0xFE,0xAE, - 0x05,0x58,0xBD,0x42,0x26,0xD5,0xC4,0xE5,0x4E,0x26,0x09,0x74,0x0A,0xAE,0x49,0x31, - 0x80,0x4E,0x25,0xD8,0x2C,0x87,0x32,0xEB,0xD9,0x3D,0xFB,0x5F,0x21,0x6B,0x0E,0xC7, - 0x83,0x4A,0x6C,0x2C,0xB1,0x82,0xEC,0xDF,0xD2,0x65,0x92,0x32,0x5C,0x30,0xEA,0x48, - 0xC7,0x13,0x39,0xB7,0x4D,0x81,0x79,0x1C,0x17,0x31,0xC1,0x83,0x42,0xFB,0xC3,0x1B, - 0xF0,0xA0,0x45,0xED,0xAA,0xDC,0x02,0x73,0x4B,0x48,0x76,0xAE,0x68,0x80,0x93,0x51, - 0x3D,0x79,0x7F,0x9E,0x53,0xD3,0x60,0x5A,0x4F,0x5B,0x2E,0xB8,0x13,0x6A,0x5F,0x27, - 0x7E,0x09,0x80,0x61,0xCF,0x41,0xDE,0xD1,0x9F,0xFA,0xEF,0x42,0xD0,0xB1,0x81,0x69, - 0x03,0x91,0x1A,0xD9,0xE2,0x33,0x34,0x78,0xFE,0x45,0xB1,0x23,0x39,0x20,0xBC,0x2D, - 0xA5,0x8A,0xB2,0x84,0xEF,0x2A,0xF4,0x6C,0x2E,0xD1,0xEE,0x61,0x38,0x8F,0xA0,0xB0, - 0x0D,0xC4,0x0A,0x3D,0xB9,0x2C,0x6D,0x77,0xB5,0xE3,0x06,0x8B,0xB4,0x0D,0xA7,0x71, - 0xFD,0x38,0x0B,0x1F,0x5C,0x1C,0x9F,0x2F,0x2E,0xA4,0xD4,0xE8,0x6F,0x02,0x03,0x01, - 0x00,0x01,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, - 0x04,0x14,0x03,0x99,0x06,0x5B,0xDA,0x2C,0xBA,0x9B,0x66,0x0A,0x5A,0x7B,0xAB,0x99, - 0xA5,0x7F,0x72,0xA9,0xD4,0xF7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, - 0x16,0x80,0x14,0x14,0xE9,0x8B,0x3E,0x9D,0x8A,0xA7,0xCA,0x70,0x97,0x2B,0x9A,0x2C, - 0x31,0xC7,0xF9,0xA2,0x5A,0x4B,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, - 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x41,0x00,0xAE,0x2A,0xA7,0x7F,0xE7,0xC9,0xE4, - 0xAA,0x2C,0x7F,0x04,0x5D,0x9B,0x0E,0x01,0x47,0x1E,0xB1,0x0E,0x35,0xD7,0x1F,0xAC, - 0x8E,0xA7,0xCC,0xAD,0x16,0xAC,0x47,0xDC,0x5E,0x13,0x1C,0x15,0x05,0x89,0x56,0xC0, - 0x76,0x55,0x96,0xA0,0x8B,0xBD,0x3B,0xD7,0x93,0x08,0xBA,0xD0,0x7E,0x64,0x7A,0xB1, - 0x74,0xE0,0x82,0x2B,0xE4,0x12,0xA3,0x4D,0x0B, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test SubCA */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ -unsigned char _int512[802]={ - 0x30,0x82,0x03,0x1E,0x30,0x82,0x02,0x06,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0xBE,0x29,0xEC,0x6D,0x40,0x7E,0x44,0x98,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8B,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, - 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, - 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30, - 0x32,0x30,0x39,0x32,0x32,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x30,0x32, - 0x30,0x39,0x32,0x32,0x5A,0x30,0x74,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,0x14,0x30,0x12,0x06,0x03,0x55, - 0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1B, - 0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x0C,0x12,0x35,0x31,0x32,0x2D,0x62,0x69,0x74, - 0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x30,0x5C,0x30,0x0D,0x06, - 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x4B,0x00,0x30, - 0x48,0x02,0x41,0x00,0xF2,0xD1,0x57,0xDD,0xA6,0xBC,0x2B,0xBC,0x22,0x7B,0x5D,0xC5, - 0x3A,0x73,0xCE,0x80,0x88,0xD7,0xDF,0x45,0xBE,0x01,0x22,0xA7,0xC2,0x7E,0x35,0x1F, - 0x74,0x02,0xA4,0xE3,0xD9,0xF3,0xE4,0x35,0xE9,0xB0,0xBD,0x71,0xC7,0x19,0x80,0xA8, - 0x9F,0xD7,0x62,0xFC,0x46,0xA6,0x84,0xF2,0xB0,0x9F,0xF5,0x1C,0xF1,0xA5,0x18,0x58, - 0x76,0x49,0x3F,0xF9,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D, - 0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9E,0x85,0x9A,0xA5,0x88,0x09,0xB0, - 0x93,0x9B,0xB4,0xE5,0xCE,0x68,0x99,0x93,0xE9,0x79,0xE9,0x7C,0x98,0x30,0x1F,0x06, - 0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xCA,0x4D,0x8B,0xBD,0x98,0x36, - 0x22,0xF8,0xA9,0x21,0x8E,0xEA,0xFC,0xE6,0xD7,0x17,0x81,0xA7,0xE2,0x12,0x30,0x0D, - 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01, - 0x01,0x00,0xD7,0x94,0x1E,0x53,0x9B,0xB5,0xC6,0x02,0x26,0xC2,0x7F,0xB2,0xD1,0x36, - 0x63,0xD5,0xEE,0x35,0x66,0x92,0x48,0xEF,0xD1,0xB4,0xDD,0xD7,0xE1,0xDF,0x05,0xF2, - 0x76,0x74,0x28,0x75,0xC1,0x51,0x66,0x6E,0x2C,0x2A,0x8C,0x82,0x34,0xD3,0x43,0x0F, - 0x22,0x12,0x01,0xD6,0x7D,0xFA,0x0E,0xF0,0x52,0xB0,0x20,0x1E,0x25,0x2B,0x39,0xA5, - 0x2C,0xD5,0x9F,0x89,0x87,0x42,0xAC,0xCB,0xEA,0x56,0xB6,0x8A,0x65,0x40,0xD9,0x19, - 0x84,0xF3,0x37,0x71,0x1C,0x0A,0x5E,0x2C,0xBB,0xB1,0xB4,0xA0,0x99,0x35,0x5A,0x0F, - 0x62,0xE0,0x7A,0x91,0x2A,0x14,0x47,0xF9,0x2E,0x3D,0x7C,0x53,0x98,0x23,0x63,0x3D, - 0x47,0x46,0x9E,0x7C,0x49,0x09,0x50,0xEA,0xCE,0xB4,0x1A,0x17,0x4E,0x6E,0x6D,0x0A, - 0x99,0xF5,0xAD,0x6E,0x88,0xF1,0xCE,0xF0,0xD7,0xB4,0x3A,0x6E,0xE7,0x97,0x4C,0x53, - 0x04,0x1D,0xB3,0x08,0x49,0x63,0x14,0x25,0x99,0xA7,0xCD,0x82,0xD5,0xF9,0xB9,0xCB, - 0x89,0x83,0xCD,0xD5,0x9E,0x57,0xBA,0x90,0x83,0x5F,0x31,0xB4,0x3C,0x3C,0x46,0xD0, - 0xA1,0xA7,0x7F,0x7A,0xF8,0x18,0x4B,0xC0,0xA9,0x0E,0x47,0x9A,0xE4,0x9B,0x6F,0x1B, - 0xAB,0x8F,0x71,0x54,0x8E,0xA6,0x0B,0xCC,0x16,0xE2,0xCD,0x38,0xA8,0xC2,0x0E,0x20, - 0xB0,0x6E,0x9C,0x8B,0x02,0xDF,0xC3,0xCE,0xB8,0xBB,0x92,0x50,0x27,0xB2,0x81,0xC5, - 0x48,0x16,0x82,0xC4,0xB1,0x5E,0x5F,0x43,0x47,0xF9,0x6F,0x8A,0x81,0x95,0x93,0xB2, - 0x78,0x24,0x67,0xEB,0xCB,0xC1,0xA4,0x4F,0x23,0x11,0xDF,0x33,0xD0,0x5F,0x79,0x26, - 0x1F,0x81, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ -unsigned char _int2048B[1005]={ - 0x30,0x82,0x03,0xE9,0x30,0x82,0x02,0xD1,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0xBE,0x29,0xEC,0x6D,0x40,0x7E,0x44,0x99,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8B,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, - 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, - 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30, - 0x32,0x30,0x39,0x33,0x39,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x30,0x32, - 0x30,0x39,0x33,0x39,0x5A,0x30,0x77,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,0x14,0x30,0x12,0x06,0x03,0x55, - 0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E, - 0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D,0x62,0x69, - 0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,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, - 0x74,0x33,0x7D,0x7B,0x48,0x2C,0x25,0x5F,0x73,0x9C,0x09,0xCC,0xBC,0x90,0x38,0xDF, - 0x41,0x06,0xD2,0x1F,0x92,0xD3,0xF0,0x94,0xBC,0x97,0x39,0x17,0x68,0x76,0xE0,0x9C, - 0x68,0x78,0xD3,0xE7,0xC7,0xBE,0xC8,0xD8,0xBE,0x2F,0x94,0x93,0x3E,0xCF,0x24,0x4D, - 0xB3,0xCF,0xA8,0xC1,0xDF,0xF3,0xC5,0x6A,0x23,0xFC,0x7C,0xAC,0x20,0xC1,0x28,0x7D, - 0x61,0x50,0xEB,0x1D,0xD1,0xAE,0xD3,0xCC,0xEC,0x67,0x95,0x0B,0x6C,0x06,0xFE,0x6C, - 0xC5,0xBC,0xBA,0xCB,0xDF,0x2D,0x0E,0xBD,0x1E,0x67,0xF9,0xD0,0xF0,0x71,0x91,0x96, - 0xD4,0x2E,0x4C,0x1A,0xC0,0xEA,0xD7,0x8B,0x09,0xDF,0xC2,0x89,0x30,0xAD,0x48,0xC4, - 0xEE,0x22,0x7A,0x8A,0xD9,0x8E,0x71,0xD1,0xE8,0x3B,0x4D,0x2A,0xB6,0x41,0x32,0x04, - 0x66,0x5B,0x5C,0x5C,0x8D,0x0E,0xFC,0x80,0x2A,0x26,0x23,0xF8,0xEA,0x77,0xA1,0xEC, - 0xF1,0x2F,0x63,0xB0,0xB3,0xA0,0x8F,0x53,0xDB,0xF2,0x7E,0x9E,0xF8,0x8F,0x9B,0x4B, - 0xA2,0x57,0xB5,0xE9,0x47,0xEF,0x86,0xEE,0xAE,0x88,0xB5,0xF7,0x6E,0x42,0x79,0x99, - 0x84,0xB8,0x7F,0x48,0x47,0x25,0x52,0x88,0x9C,0x1F,0xAB,0x7D,0xCE,0x8B,0x21,0x39, - 0x7B,0xF6,0xD1,0xB8,0x2B,0xCE,0xDA,0x21,0x15,0x3A,0xF0,0x0D,0xD1,0x59,0x0F,0xF4, - 0xFF,0x6B,0xCF,0x71,0x5D,0xE9,0x8F,0xE7,0xC1,0x4F,0xF7,0xEA,0xB8,0xE5,0x9F,0x16, - 0xB7,0x17,0x5A,0x27,0x35,0x2C,0xDE,0x18,0xF6,0x55,0xDC,0x05,0x18,0xD2,0x12,0x0C, - 0x35,0x44,0x88,0xFC,0xEC,0x5E,0x46,0x17,0xDA,0x48,0xD5,0x73,0xD2,0x73,0xEB,0x02, - 0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, - 0x04,0x16,0x04,0x14,0x0C,0x3F,0x97,0x58,0x60,0x67,0x21,0xC9,0xDB,0xD4,0x23,0x58, - 0x60,0x8E,0xC1,0x3F,0x99,0x9F,0x12,0x78,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04, - 0x18,0x30,0x16,0x80,0x14,0xCA,0x4D,0x8B,0xBD,0x98,0x36,0x22,0xF8,0xA9,0x21,0x8E, - 0xEA,0xFC,0xE6,0xD7,0x17,0x81,0xA7,0xE2,0x12,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, - 0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x62,0x5B,0x7A, - 0xEA,0x51,0xBC,0x4B,0xE2,0xA6,0x3F,0xC9,0x71,0x1F,0x03,0x64,0x83,0x96,0x69,0x09, - 0x36,0x14,0xA3,0xCF,0xFB,0x7D,0x67,0xB5,0x24,0x12,0x10,0xCF,0xA2,0x38,0x41,0x60, - 0x73,0xDD,0x9F,0x78,0x3A,0xE2,0x57,0xBF,0x64,0x0A,0xE4,0xB5,0x97,0x64,0x38,0x6E, - 0x36,0xCE,0x49,0x5E,0x21,0x53,0x4E,0x77,0x20,0x1E,0xBE,0xE0,0x33,0xDB,0x99,0xF1, - 0xC9,0xE8,0xA8,0x29,0x0A,0x23,0xE9,0x8D,0x91,0xE3,0x65,0x03,0xCB,0x97,0xA5,0x3F, - 0xF1,0xBF,0x28,0x4D,0x6C,0x2E,0xA7,0xFE,0x65,0x57,0xBE,0x1B,0x64,0xCE,0xFB,0x4B, - 0x33,0x7C,0x79,0x9B,0xCE,0x57,0xBE,0xB3,0x11,0x44,0xC1,0xD8,0x83,0x88,0x01,0x02, - 0x7C,0x51,0x32,0x31,0xA5,0xE7,0xE2,0xD2,0x91,0xAB,0x4F,0x37,0xE7,0x8D,0xBC,0x44, - 0x93,0xC8,0x29,0x0D,0x68,0x30,0xDB,0x54,0x1A,0x42,0x92,0x54,0xC2,0x0D,0xBF,0x28, - 0x69,0x94,0x95,0x77,0xCA,0xDA,0x68,0xFA,0x12,0xF4,0x19,0xEE,0x81,0x8F,0x9C,0x22, - 0x04,0x89,0xDD,0x2F,0x0A,0x17,0xC5,0xB5,0x1C,0x3A,0x3F,0x13,0x77,0x21,0x49,0xFC, - 0xBF,0xB7,0x82,0x9A,0x37,0x8A,0x6D,0x10,0xF6,0x44,0xF2,0xD5,0xFB,0xBC,0xB6,0xC5, - 0x50,0xD7,0x9B,0x4D,0x6D,0x18,0x85,0xB7,0xE6,0x90,0xE1,0xD4,0x3F,0x16,0x8A,0x74, - 0x97,0x32,0x29,0x3C,0xCA,0xE2,0x9E,0xC6,0xEB,0xBA,0x7A,0x9B,0xF9,0xE8,0xC7,0xA5, - 0x01,0x29,0x38,0x5B,0x6D,0x13,0xFC,0x2D,0x6A,0xE9,0x99,0xEC,0x62,0x10,0xEA,0x07, - 0x31,0x7F,0xF6,0x2C,0xE3,0x85,0x8C,0x0C,0x20,0x99,0x69,0x60,0x53, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Leaf 1 */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 1 */ -unsigned char _leaf2048A[1000]={ - 0x30,0x82,0x03,0xE4,0x30,0x82,0x02,0xCC,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7E, - 0x98,0x75,0xB3,0x73,0xE3,0x76,0xC7,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A, - 0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06,0x03, - 0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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, - 0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D,0x62, - 0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x31,0x30, - 0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x31,0x38,0x35,0x36,0x5A, - 0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x31,0x38,0x35,0x36,0x5A,0x30, - 0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70, - 0x70,0x6C,0x65,0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04, - 0x03,0x0C,0x14,0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74, - 0x20,0x4C,0x65,0x61,0x66,0x20,0x31,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,0xA5,0x19,0x09,0x20,0x84,0xCE,0x67, - 0x24,0x88,0xCD,0xEB,0x25,0x9C,0xE7,0xD3,0x52,0xC5,0xC0,0x0F,0xA2,0x39,0x6C,0xF2, - 0x1D,0x6D,0x8F,0x29,0x45,0x09,0xD8,0x34,0xE8,0xD7,0xE0,0xD4,0xE6,0x96,0x20,0x33, - 0xDC,0x4A,0x99,0x3F,0x39,0x20,0x52,0x72,0x4A,0x12,0x5F,0x31,0xF3,0xB0,0x2B,0x17, - 0x6E,0x6B,0x80,0x8F,0xFD,0xC7,0x48,0x8D,0x42,0xBB,0xFA,0x2E,0xBD,0x98,0xA4,0x14, - 0x6B,0x6B,0xD0,0x98,0x3D,0x33,0x13,0x99,0x00,0x3A,0x69,0xAD,0x76,0xD5,0x2A,0x01, - 0x7B,0x32,0x68,0x2D,0x7F,0xA2,0x48,0x25,0x2C,0x0F,0x6F,0xA1,0xD9,0xA7,0xB7,0x75, - 0xE1,0x1D,0xAD,0xCA,0xBB,0x3A,0xBF,0xA8,0x4D,0x93,0x8E,0xC3,0xF3,0x51,0x65,0xDC, - 0xD8,0x2D,0x6B,0x4C,0x10,0x77,0x6B,0xEC,0x4F,0x07,0x8C,0x5B,0x8B,0x9A,0x53,0xDC, - 0xF3,0x1C,0x17,0x10,0x42,0x42,0x29,0x14,0x0A,0xE7,0x4C,0xEF,0x04,0x95,0xA0,0x84, - 0x47,0xD2,0x2C,0x81,0xB4,0x37,0x53,0xD2,0x76,0x31,0x97,0xE1,0x11,0xB1,0xDE,0x83, - 0xE0,0xFC,0xA5,0x12,0x34,0x0C,0xBD,0x81,0x31,0xA9,0x6D,0xDC,0x7C,0xE6,0x79,0xC2, - 0x42,0xED,0x91,0xCA,0x26,0xD5,0x4C,0x30,0xA8,0x49,0x70,0x69,0xD5,0x4C,0x34,0x92, - 0xCB,0xC3,0xA4,0x52,0x70,0x2D,0xDD,0x5A,0xFB,0x22,0x00,0xD7,0x2D,0xA3,0x75,0xC1, - 0xED,0xE4,0x2A,0x3E,0x23,0xE6,0xBD,0x84,0xC4,0xCC,0xE8,0x49,0xE0,0xAE,0xCA,0x81, - 0x75,0xDB,0x87,0xEF,0xE9,0xE9,0x1E,0xA9,0xBE,0x40,0x0B,0x64,0x86,0x22,0xBA,0xAE, - 0x64,0x27,0xA9,0xFE,0x07,0xE5,0x69,0x8F,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,0x05,0xA0,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,0x5D, - 0xA6,0xDA,0xDF,0xA5,0x29,0x94,0xF6,0x34,0xA9,0xC5,0x46,0xA3,0xBB,0xBD,0x0A,0x00, - 0x0E,0xD4,0xFC,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, - 0x03,0x99,0x06,0x5B,0xDA,0x2C,0xBA,0x9B,0x66,0x0A,0x5A,0x7B,0xAB,0x99,0xA5,0x7F, - 0x72,0xA9,0xD4,0xF7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, - 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0D,0xCB,0x71,0x05,0x25,0x22,0xD7,0x9A, - 0xE9,0x74,0x9E,0x16,0x91,0x73,0x90,0x95,0x1D,0x52,0xA7,0xAB,0xDA,0xDF,0x40,0x7B, - 0x57,0x7D,0x0A,0x9A,0xE9,0x65,0x18,0xF7,0x94,0x2B,0x9E,0x88,0x30,0xD3,0x8E,0x2A, - 0xE6,0xC6,0x7E,0xF7,0xF7,0x1A,0xE0,0x9F,0x91,0xB5,0xD0,0x62,0xA1,0x5D,0xB7,0x6B, - 0x0E,0xC7,0x4E,0x44,0xCC,0x79,0x39,0x56,0xA0,0x2D,0x9E,0x43,0xC3,0xF7,0x26,0x8B, - 0x99,0xC8,0x0E,0x68,0x5D,0xBD,0x02,0xB5,0xB1,0x59,0xB5,0x0F,0xF0,0x58,0xF6,0x32, - 0x57,0x7D,0xD3,0xB6,0x4C,0x89,0x64,0x21,0xBB,0xB3,0x13,0x15,0xC0,0xDD,0xF7,0xB5, - 0x1C,0xD1,0x1F,0xF9,0xE0,0xE9,0xB6,0x7F,0x1D,0x60,0xDC,0x9F,0x07,0xE9,0x5C,0x42, - 0x02,0x9B,0x64,0x13,0x5D,0x75,0xB5,0x77,0x01,0xF6,0xF6,0x2D,0x02,0xA8,0x18,0x59, - 0x9C,0x38,0x35,0xBC,0x75,0x11,0xCC,0x56,0xF5,0x5A,0x01,0x73,0xA9,0x06,0x31,0xAC, - 0x12,0x0C,0x03,0xC2,0xF3,0x67,0x26,0xA4,0xB3,0x2D,0xA2,0x7A,0xE5,0x44,0xE2,0x4F, - 0x28,0x25,0x6C,0xB8,0xF2,0x52,0xAF,0xCE,0x72,0x47,0xE9,0xD6,0xD1,0xFD,0x6B,0xFB, - 0x94,0x28,0xA8,0x82,0x85,0x49,0x8B,0xBC,0xB5,0x7B,0x93,0xCF,0x2D,0x29,0xE1,0x0C, - 0x5B,0xAF,0x3C,0xEC,0xED,0x78,0xDC,0x24,0x56,0x5C,0xC8,0xF4,0x47,0xBC,0x63,0xA3, - 0x37,0xF9,0x9C,0x92,0xF5,0xD3,0xAD,0x71,0xEC,0x43,0xE9,0x0B,0xDC,0xB5,0x9F,0x03, - 0x44,0x55,0x12,0x1D,0x39,0xF3,0x8C,0xAE,0x59,0x15,0xC1,0x12,0xAF,0xC1,0x02,0x95, - 0x62,0x7D,0x56,0xF0,0x93,0x47,0x5A,0x50, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Leaf 2 */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test SubCA */ -unsigned char _leaf2048B[803]={ - 0x30,0x82,0x03,0x1F,0x30,0x82,0x02,0xC9,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x4E, - 0xBF,0xB9,0x68,0xC8,0x8C,0x3A,0xE1,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, - 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x74,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,0x14,0x30,0x12,0x06,0x03, - 0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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, - 0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x0C,0x12,0x35,0x31,0x32,0x2D,0x62,0x69, - 0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x30,0x1E,0x17,0x0D, - 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x31,0x39,0x33,0x34,0x5A,0x17,0x0D,0x31, - 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x31,0x39,0x33,0x34,0x5A,0x30,0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14, - 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x4C,0x65, - 0x61,0x66,0x20,0x32,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,0x79,0xB9,0x77,0x2A,0x76,0x17,0xEE,0xD1,0x4E,0x6D, - 0x6B,0x9F,0x42,0xAA,0xDE,0x81,0x47,0xC5,0x2B,0x43,0x3A,0x4F,0xB9,0x42,0x5E,0x5A, - 0x35,0xDE,0xF5,0x86,0x8C,0x0E,0xD1,0xC3,0x7B,0xA2,0x82,0x52,0x33,0xA0,0x2B,0x8C, - 0x58,0x04,0x75,0x8E,0xFB,0x08,0x9B,0xA7,0xEA,0x66,0x86,0xFA,0x5E,0xC2,0xCC,0x21, - 0x6C,0x17,0xC3,0x6B,0x05,0xFE,0x33,0x21,0x51,0x18,0xA1,0x0A,0xDD,0x5F,0xCE,0xF2, - 0xF6,0xB6,0x82,0x6C,0xBB,0x26,0x68,0x76,0xC3,0x16,0xEB,0x35,0x78,0x79,0x03,0xB0, - 0x36,0xC5,0x7D,0xDF,0x5C,0x38,0xB6,0xF0,0xD1,0xE0,0x9D,0x71,0xFB,0xA8,0x1B,0x83, - 0x9D,0x30,0xBC,0x2D,0x09,0x4D,0x9F,0xF4,0x69,0x33,0x99,0xE5,0xE9,0x76,0x6B,0x78, - 0x71,0xA7,0x13,0xF4,0xFB,0x2A,0x24,0x4D,0xD0,0x54,0x6E,0xAE,0x19,0xEE,0xCB,0x43, - 0x8C,0x3F,0x90,0x0F,0xDC,0xFE,0xA4,0xFF,0x8A,0xAD,0x22,0x21,0x61,0x51,0xAA,0x76, - 0x66,0x43,0xC0,0xE5,0x42,0x94,0x0F,0xBE,0x3C,0x89,0x45,0x50,0x0D,0x4F,0xDC,0x19, - 0xEF,0xF8,0x19,0xB6,0x7E,0x42,0xBD,0x88,0xA3,0x65,0x59,0xE8,0x7A,0xC1,0x7F,0x32, - 0x15,0x38,0xA3,0x58,0xC4,0x25,0x74,0xFC,0x02,0x8C,0xFC,0x31,0x28,0x20,0x05,0xAD, - 0x9B,0x27,0xE5,0x25,0x81,0x63,0x92,0xE1,0x49,0x55,0x5B,0xD7,0x36,0x3E,0xC4,0x2F, - 0x98,0x23,0xAA,0x62,0x85,0x68,0x4C,0x2D,0xEA,0x46,0xD6,0x99,0xCE,0x61,0x7C,0xE7, - 0x18,0x0B,0x72,0x5E,0xA0,0x06,0x49,0x6E,0x1C,0x31,0x0F,0x61,0x3F,0x62,0x68,0xC0, - 0x89,0xC8,0x91,0x45,0xAD,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,0x05,0xA0,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,0x81,0x88,0xF3,0xCE, - 0xC9,0x31,0x5E,0x77,0x3C,0x27,0x4E,0x5E,0x4A,0xE6,0xEA,0x06,0x7A,0xEA,0x32,0x43, - 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x9E,0x85,0x9A, - 0xA5,0x88,0x09,0xB0,0x93,0x9B,0xB4,0xE5,0xCE,0x68,0x99,0x93,0xE9,0x79,0xE9,0x7C, - 0x98,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, - 0x03,0x41,0x00,0x39,0x1A,0x27,0x7C,0xDB,0x9C,0xE7,0x83,0x5F,0x57,0x69,0x4D,0xAD, - 0xD5,0x98,0xBA,0xA8,0x56,0x54,0x8D,0x84,0x18,0xB0,0xAF,0xEA,0x4B,0x74,0xB7,0x87, - 0xDC,0xD8,0x1E,0x10,0x10,0xE3,0x73,0xC1,0x90,0x83,0x9F,0xB8,0xF4,0x41,0x03,0x02, - 0x49,0xF7,0x57,0x5C,0x7D,0x03,0xE9,0x9E,0x57,0xF4,0xBC,0x74,0x3A,0xC0,0x9B,0xFF, - 0x20,0x73,0xC7, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Leaf */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ -unsigned char _leaf512[798]={ - 0x30,0x82,0x03,0x1A,0x30,0x82,0x02,0x02,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0x81,0x94,0x54,0x10,0xDC,0xA5,0x98,0x14,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, - 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06, - 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D, - 0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32, - 0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x30,0x30,0x38, - 0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x30,0x30,0x38,0x5A, - 0x30,0x73,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41, - 0x70,0x70,0x6C,0x65,0x2C,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,0x1A,0x30,0x18,0x06,0x03,0x55, - 0x04,0x03,0x0C,0x11,0x35,0x31,0x32,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74, - 0x20,0x4C,0x65,0x61,0x66,0x30,0x5C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, - 0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x4B,0x00,0x30,0x48,0x02,0x41,0x00,0xEB,0x34, - 0xD8,0x83,0x6D,0xFE,0xDD,0x09,0x27,0xC1,0xA1,0xA7,0x1F,0x9D,0xA8,0xDF,0x55,0xDE, - 0x54,0x03,0x3D,0x42,0x54,0x24,0x3D,0x92,0x8B,0x21,0x4B,0xEE,0x8C,0x2B,0x9C,0x3F, - 0x34,0xD1,0x6B,0xDE,0xC0,0xC2,0x20,0x06,0x87,0x9B,0x11,0x96,0x8C,0xB5,0x24,0xDD, - 0x93,0xE6,0x1B,0x77,0xC1,0x7A,0xD0,0x1F,0xD2,0x09,0x3D,0x21,0x8A,0x15,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,0x05,0xA0,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,0xAE,0x83,0x56,0x29,0x05,0x75,0x48,0xB2,0x2F,0x0D,0x92, - 0x26,0x21,0xC2,0x7C,0x34,0x48,0xF7,0xAC,0xAF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, - 0x04,0x18,0x30,0x16,0x80,0x14,0x0C,0x3F,0x97,0x58,0x60,0x67,0x21,0xC9,0xDB,0xD4, - 0x23,0x58,0x60,0x8E,0xC1,0x3F,0x99,0x9F,0x12,0x78,0x30,0x0D,0x06,0x09,0x2A,0x86, - 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x85,0xEC, - 0xC6,0xA7,0x1B,0x36,0x62,0x3A,0x04,0xBB,0xE8,0x8F,0xE2,0x66,0x8E,0xD4,0x02,0x97, - 0x6C,0x29,0x27,0xFF,0xC8,0xC6,0xBC,0xFE,0x9D,0xBC,0x09,0x8C,0x6B,0x0B,0x1E,0x48, - 0x82,0x46,0xBD,0xCF,0x02,0xB7,0x59,0x6E,0x7A,0xFC,0x8C,0x58,0x03,0x6A,0x92,0x4A, - 0xB0,0x1F,0x2E,0x6F,0x78,0x84,0x10,0x54,0xA9,0x70,0x65,0xDD,0xA2,0xAA,0xAA,0xFA, - 0x59,0x98,0xD7,0x42,0x60,0x42,0x15,0x2C,0x11,0x48,0xDE,0xF6,0x76,0x91,0x5C,0x2B, - 0x0B,0xEF,0x5F,0x23,0x61,0x8A,0x4E,0x81,0x82,0x3F,0xDA,0x9E,0x02,0xAF,0x82,0xDD, - 0x43,0x94,0x08,0xD1,0xA0,0x31,0x98,0x14,0x4C,0xBD,0x5E,0xFA,0x73,0xDC,0x0A,0x72, - 0xA4,0xB0,0x78,0x8A,0xC6,0xFE,0xBB,0x5A,0xBF,0x78,0x32,0x8D,0x26,0x7B,0xA3,0xBD, - 0x06,0x45,0x93,0xC6,0x96,0x99,0x14,0x8C,0x69,0xD1,0x52,0xDC,0xD4,0x1C,0x3E,0xCB, - 0x91,0x46,0x92,0x1B,0xBE,0x21,0xEC,0x21,0xE2,0xB9,0x23,0xD5,0xB0,0xAD,0x42,0xFA, - 0x9A,0x91,0xA4,0xA1,0x48,0x4D,0x94,0xB5,0xCF,0x14,0x21,0xA4,0x8E,0x18,0x2E,0x78, - 0x93,0xA0,0xED,0x43,0x15,0x92,0x68,0x57,0x78,0x52,0x28,0xEB,0x4A,0x48,0x79,0xEF, - 0x17,0xD3,0xD5,0xAD,0x2F,0x8A,0xF4,0xD2,0x21,0x79,0x08,0x08,0x66,0xE1,0x54,0x7F, - 0xFC,0x3D,0x5D,0x81,0xD8,0xA8,0x47,0xC3,0x3B,0xE9,0x52,0x77,0x05,0xF2,0x42,0xDE, - 0x23,0x24,0x99,0x7A,0x20,0x49,0x86,0x49,0x04,0x60,0x77,0xBD,0xD5,0x33,0xBB,0x49, - 0x61,0x8B,0x1C,0xBB,0x8E,0xE8,0x1D,0xA4,0x1E,0xA4,0x21,0x77,0x59,0xBD, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=1024-bit Test Leaf */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ -unsigned char _leaf1024[867]={ - 0x30,0x82,0x03,0x5F,0x30,0x82,0x02,0x47,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0x81,0x94,0x54,0x10,0xDC,0xA5,0x98,0x15,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, - 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06, - 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D, - 0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32, - 0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x30,0x32,0x32, - 0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x30,0x32,0x32,0x5A, - 0x30,0x74,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41, - 0x70,0x70,0x6C,0x65,0x2C,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,0x1B,0x30,0x19,0x06,0x03,0x55, - 0x04,0x03,0x0C,0x12,0x31,0x30,0x32,0x34,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73, - 0x74,0x20,0x4C,0x65,0x61,0x66,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,0xCA,0xCD,0xBD,0x1E,0xA5,0xF1,0xDC,0x50,0x7F,0xF6,0x52,0x96,0x56, - 0x1F,0xD9,0x9A,0x3F,0x32,0xED,0x45,0x29,0xCE,0x2C,0x18,0xA4,0x3E,0xA6,0x92,0xDF, - 0x8E,0x33,0x76,0x4D,0xCB,0xDB,0xD9,0x5E,0x83,0x32,0x96,0x19,0x8B,0x62,0xFE,0x67, - 0xBB,0xE6,0xC0,0x3D,0x1A,0xEF,0xE4,0x19,0x40,0x8B,0x26,0x80,0xD9,0x22,0x8A,0x1E, - 0xDF,0xC6,0x79,0x2C,0x07,0x7C,0xD7,0x10,0x91,0x7E,0x0F,0xC5,0x5E,0x69,0xC3,0xEB, - 0x1F,0x34,0x50,0x4D,0xA5,0xE1,0xF6,0x3A,0x6C,0xF0,0xD4,0x21,0x20,0x5C,0x0A,0x68, - 0xC1,0x26,0x4B,0x4A,0x79,0x08,0x64,0x67,0xDE,0x1E,0x17,0xC5,0xE4,0xEE,0xA6,0xE3, - 0xC4,0x54,0x34,0x7C,0xFE,0x82,0x5B,0xE4,0xAB,0xAF,0x97,0x2C,0x6B,0xAC,0x02,0x11, - 0xF3,0xD9,0x67,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,0x05,0xA0,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,0xB9,0xC9,0xD8,0x19,0xA6,0x69, - 0x3A,0x16,0x2E,0x32,0x2B,0x9A,0x10,0xB6,0xFA,0x20,0x93,0x16,0x7E,0xBC,0x30,0x1F, - 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x0C,0x3F,0x97,0x58,0x60, - 0x67,0x21,0xC9,0xDB,0xD4,0x23,0x58,0x60,0x8E,0xC1,0x3F,0x99,0x9F,0x12,0x78,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, - 0x01,0x01,0x00,0xA6,0x0A,0xB5,0x39,0x4B,0xA9,0xED,0x9B,0x8C,0xC5,0x5D,0xF1,0xAA, - 0x9D,0x57,0x55,0x5C,0xF2,0x10,0x29,0xBD,0x56,0x36,0xEF,0x52,0xDC,0xEA,0x27,0xF9, - 0xA2,0x79,0xBB,0xE6,0x16,0x29,0xA4,0x90,0x31,0x26,0x24,0x8A,0x79,0xBE,0x36,0xFC, - 0xA9,0xEF,0x77,0x13,0x16,0xA3,0x55,0xEB,0xD1,0x1A,0xD8,0xE2,0x16,0x72,0x5F,0x7D, - 0x10,0x76,0x3B,0x9A,0x00,0x51,0xAC,0x5A,0x4E,0x05,0xA3,0x82,0x1D,0xAB,0xC1,0x5E, - 0x44,0xD8,0xA0,0x95,0xD1,0xB5,0x75,0xE6,0x3B,0xB2,0x20,0xFB,0xBB,0xB9,0x88,0xD5, - 0x27,0x3B,0x90,0xA6,0xF0,0x6D,0x80,0xC8,0xA3,0x3A,0x3D,0x33,0x8F,0x14,0x09,0x5D, - 0xBB,0xA0,0xD7,0x3D,0x10,0xE9,0x8D,0x0E,0xB4,0x51,0x42,0xD3,0xB3,0xEF,0xC2,0xF2, - 0x0B,0x35,0x35,0x5D,0x7B,0xE1,0x47,0x9E,0x90,0xF9,0x14,0xDD,0xDD,0x1E,0x5F,0xDC, - 0xAB,0x04,0x08,0x8A,0x6B,0x82,0x2F,0xCA,0xA6,0x37,0x07,0x4C,0x94,0xD5,0x4F,0x83, - 0x67,0xEF,0xE2,0x12,0xDB,0x71,0x69,0x5A,0x33,0x8E,0x32,0x90,0xDE,0xE7,0x8C,0x6E, - 0x64,0xFD,0x8E,0x09,0xDA,0xBD,0x08,0xBE,0xC1,0x6F,0xD0,0x30,0xDD,0x18,0xDB,0xD1, - 0x34,0x7D,0x86,0x69,0xD7,0x57,0xE4,0x70,0x7F,0xF8,0x49,0xC0,0x4B,0xE4,0x73,0xE1, - 0x29,0x26,0x5E,0x04,0xDC,0xC6,0x69,0x17,0xDF,0x62,0x20,0xE1,0x15,0xAB,0xDD,0x1B, - 0x0C,0xD7,0xA6,0x1C,0x2C,0x7B,0xD9,0x2D,0xDE,0x46,0x43,0x81,0xFA,0xD9,0x11,0xDD, - 0xE8,0x4B,0x6A,0x31,0x85,0x24,0x0A,0xFD,0xAD,0x93,0xF6,0x50,0x2B,0x36,0xE5,0xE5, - 0x9E,0x8D,0x85, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Leaf 3 */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ -unsigned char _leaf2048C[1001]={ - 0x30,0x82,0x03,0xE5,0x30,0x82,0x02,0xCD,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0x81,0x94,0x54,0x10,0xDC,0xA5,0x98,0x16,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, - 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06, - 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D, - 0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32, - 0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x30,0x33,0x33, - 0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x30,0x33,0x33,0x5A, - 0x30,0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41, - 0x70,0x70,0x6C,0x65,0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55, - 0x04,0x03,0x0C,0x14,0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73, - 0x74,0x20,0x4C,0x65,0x61,0x66,0x20,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,0xC4,0xFE,0xE0,0xE5,0xC7,0x13,0x95, - 0x56,0x9E,0xA2,0x32,0xF5,0x52,0xD8,0xAA,0x06,0xF0,0x0F,0x2A,0x76,0xA8,0xCB,0xF3, - 0x39,0x5D,0x6E,0xEA,0x9C,0x4F,0x80,0xA1,0x9F,0xAC,0x8F,0x7D,0x34,0xDD,0x5D,0xD1, - 0x69,0xD9,0x2C,0x5D,0x49,0x2D,0x31,0x81,0x0D,0x2E,0x25,0xB7,0xA2,0x63,0x77,0xA1, - 0x58,0x8C,0x8D,0x2A,0x73,0x86,0xD8,0x15,0xFF,0xA9,0xED,0xF1,0xE6,0x08,0x7F,0x15, - 0x7B,0xFE,0xCC,0x07,0x7F,0xB7,0x63,0xA0,0x00,0x98,0xF0,0xBA,0x74,0x0C,0x34,0x2B, - 0xC4,0xE6,0xD6,0x2A,0xEE,0x7E,0x9D,0xBE,0xFD,0x34,0x70,0xCC,0x22,0x2C,0x2E,0x4F, - 0x81,0xC1,0xDA,0xB8,0x0B,0xC4,0xF9,0xFE,0xFD,0x74,0x47,0xE4,0xA9,0xA4,0x65,0x85, - 0x10,0x86,0x29,0x72,0x35,0x38,0x4B,0xD7,0xDA,0x3A,0x59,0xE7,0x8A,0x6D,0xC5,0x71, - 0x59,0x89,0xA5,0xC4,0xA3,0x9E,0xFC,0x81,0x18,0xD3,0x97,0x48,0xB2,0xDD,0xFE,0xB3, - 0xB3,0x78,0x71,0x35,0x3C,0x66,0x0F,0xD6,0xAA,0x84,0xF8,0xCB,0x87,0xB8,0xB4,0xFD, - 0x19,0x18,0x31,0xCC,0x53,0xB7,0x1B,0xB6,0x7D,0x99,0x9C,0x14,0x19,0xDA,0x84,0x72, - 0x88,0x21,0x9A,0x87,0x60,0x69,0xC3,0x8E,0x1F,0x34,0x3B,0xA3,0x56,0xA5,0x21,0xF0, - 0xDB,0xC1,0x54,0xEA,0x41,0x69,0x19,0x45,0x5E,0x52,0xB3,0x3A,0xBD,0x1A,0x8A,0x64, - 0x7B,0xA9,0xD4,0xF1,0x2B,0x58,0xCF,0x0D,0x7F,0x3C,0x86,0xDA,0x9A,0x94,0x42,0x36, - 0x6B,0x9F,0xD8,0xF4,0x64,0x18,0x66,0x6F,0xF7,0xB5,0x80,0xCE,0x43,0x8D,0x84,0x7A, - 0x99,0xE3,0x3D,0x03,0xB5,0x94,0x86,0xBD,0xEB,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,0x05,0xA0, - 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, - 0x50,0x25,0x7E,0xA7,0xF5,0x2B,0xA3,0x3A,0x35,0x31,0x82,0x4C,0xD6,0xA6,0x5F,0x04, - 0xC1,0x3A,0xAC,0x63,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, - 0x14,0x0C,0x3F,0x97,0x58,0x60,0x67,0x21,0xC9,0xDB,0xD4,0x23,0x58,0x60,0x8E,0xC1, - 0x3F,0x99,0x9F,0x12,0x78,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, - 0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x7E,0xF7,0x12,0xE6,0x05,0x3B,0x13, - 0x4B,0x35,0xAD,0x63,0xCF,0x39,0xC7,0x9B,0x62,0x83,0xF6,0x52,0xCC,0x54,0x14,0x13, - 0x5D,0xD8,0xE3,0x1E,0x33,0x37,0x6F,0x3B,0x13,0x9F,0x23,0xBC,0xA0,0xAC,0xF3,0xA1, - 0x94,0x0C,0xE0,0x51,0xDE,0x08,0x56,0x8B,0x90,0x2E,0x4B,0xB1,0xCD,0x9B,0x1A,0x44, - 0x8E,0xB9,0x0B,0xA7,0x0B,0x5B,0xAC,0x7A,0x37,0xF7,0x71,0x27,0x4E,0xB8,0x15,0x09, - 0x70,0x10,0xAA,0x3C,0x61,0xC8,0x76,0x2A,0x2E,0x13,0x76,0xC9,0x2E,0xEE,0x98,0x75, - 0xF7,0x61,0x7D,0x8E,0x3C,0xFC,0x19,0xDE,0xAB,0xE5,0xDA,0xFE,0x30,0x00,0x45,0x13, - 0xE2,0x82,0x96,0x59,0xEE,0x02,0x5A,0x9B,0xFA,0x1B,0x4E,0x65,0xE0,0x75,0x8F,0x99, - 0x82,0xBD,0x2A,0x16,0x10,0xC2,0xA5,0xA2,0x1A,0xC0,0xF6,0x4A,0x42,0x46,0xBA,0x12, - 0xE0,0x64,0x7B,0x10,0x57,0xB6,0xFE,0xC3,0x46,0xCC,0x43,0xDC,0x69,0xF0,0x72,0x69, - 0x62,0xDB,0x0C,0x6E,0x21,0xF9,0xB4,0x59,0xD7,0xA3,0xFC,0x82,0x98,0x60,0x60,0x57, - 0x7F,0xDD,0x25,0x65,0xB7,0x04,0x3E,0xDA,0xA3,0x07,0x7C,0x69,0xAF,0x81,0xA9,0x49, - 0x81,0x09,0x62,0x71,0x51,0x4F,0x40,0x8F,0xE4,0x01,0x4C,0xAE,0xF4,0x9D,0xE0,0x38, - 0xB1,0x20,0xF0,0x5D,0x1C,0xA0,0xB4,0x31,0xBF,0xE7,0xC7,0xFE,0xFF,0xA5,0x81,0xFB, - 0x8E,0xEE,0x19,0xB1,0xF1,0x64,0x44,0x3D,0xDA,0x71,0xE3,0x80,0x58,0xFB,0x23,0x6E, - 0xAE,0x3B,0x69,0x64,0x37,0x82,0x54,0xD6,0xEA,0xD4,0x02,0xD9,0x27,0x1A,0x9F,0xCE, - 0x0D,0x44,0xA9,0x29,0x07,0x8C,0x76,0x0A,0xCB, -}; - -// MARK: EC Key Size Test Certs - -/* EC Key Size Test Cert Chains - * _root384 -> _int384B -> _leaf128 - * _root384 -> _int384B -> _leaf192 - * _root384 -> _int384B -> _leaf384C - */ - -/* subject:/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Root CA */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Root CA */ -unsigned char _root384[662]={ - 0x30,0x82,0x02,0x92,0x30,0x82,0x02,0x18,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0x9B,0x8A,0xBF,0x1F,0x3B,0x4D,0xCC,0x76,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, - 0x3D,0x04,0x01,0x30,0x81,0x8C,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,0x14,0x30,0x12, - 0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70, - 0x33,0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20, - 0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30,0x33,0x30,0x34, - 0x32,0x35,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x31,0x35,0x30,0x33,0x30,0x34,0x32, - 0x35,0x5A,0x30,0x81,0x8C,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,0x14,0x30,0x12,0x06, - 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33, - 0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, - 0x41,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05, - 0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xFE,0xE3,0x68,0x79,0x40,0x81,0x4D, - 0xC3,0xAA,0x9F,0x1D,0x9D,0x03,0x33,0x5F,0x39,0x4D,0xFD,0x4E,0x7E,0xC3,0xC2,0x9D, - 0xB4,0x61,0x98,0x8D,0x02,0xA9,0xA0,0xA7,0x4E,0x49,0xE8,0xFE,0xAD,0x1D,0x6B,0x7D, - 0xAF,0xDA,0x55,0xF5,0xD2,0x8E,0x5F,0x2F,0x0E,0x55,0x50,0x61,0x07,0x81,0xE6,0xDF, - 0xD5,0xD1,0xA5,0x21,0xA9,0x78,0x38,0xC5,0x75,0x76,0x06,0x54,0x67,0xC7,0xD1,0x00, - 0x37,0xD2,0x65,0x52,0xB6,0x28,0xA0,0x5D,0x76,0x32,0xF0,0x48,0xAC,0x86,0x8B,0x5B, - 0x90,0x08,0xE4,0xD3,0xCA,0xF0,0xE8,0x0E,0x45,0xA3,0x45,0x30,0x43,0x30,0x12,0x06, - 0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01, - 0x03,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,0x86,0xC8,0x90,0xD5, - 0xD7,0x5C,0x3A,0xE1,0x29,0xF4,0x13,0x54,0xD0,0x06,0x90,0xAA,0xEC,0xF8,0x97,0xF7, - 0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66, - 0x02,0x31,0x00,0xE3,0xE1,0x9C,0xB4,0xEE,0x40,0x25,0x9A,0x82,0x3F,0x0A,0x03,0x55, - 0xDC,0x52,0x7D,0x3B,0xFC,0xC2,0x1A,0x05,0x97,0xEF,0x3F,0xA0,0x63,0x49,0x8A,0x00, - 0x38,0x72,0x05,0xDB,0x74,0x9C,0xED,0x68,0x8E,0x03,0xB8,0x6B,0x36,0x11,0x2C,0x77, - 0xA3,0xB8,0x7C,0x02,0x31,0x00,0xA9,0xB5,0x88,0xB6,0x3A,0x85,0x55,0x2E,0x69,0x56, - 0x8D,0xC4,0x5B,0x24,0xD2,0x8A,0x0E,0x01,0xA9,0x0E,0xC1,0x4D,0xDB,0x39,0xE9,0x9C, - 0x16,0x49,0xEE,0xD8,0x50,0xC0,0x1E,0x02,0xD4,0x5C,0x8B,0x07,0xD1,0xA5,0x74,0xE3, - 0x6F,0x62,0xC8,0x32,0x40,0x1D, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ -/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Root CA */ -unsigned char _int384B[671]={ - 0x30,0x82,0x02,0x9B,0x30,0x82,0x02,0x21,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, - 0xFE,0xE6,0x21,0x31,0x73,0x83,0x11,0xBA,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, - 0x3D,0x04,0x01,0x30,0x81,0x8C,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,0x14,0x30,0x12, - 0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70, - 0x33,0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20, - 0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x32,0x31,0x32, - 0x31,0x38,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x32,0x31,0x32,0x31, - 0x38,0x5A,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, - 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, - 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, - 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x76,0x30,0x10, - 0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22, - 0x03,0x62,0x00,0x04,0x08,0xAE,0xF2,0x28,0x6E,0x8C,0xE8,0x16,0x01,0x86,0x37,0xFE, - 0xFD,0x17,0xA5,0x37,0x30,0xD2,0x55,0xDB,0x4C,0x6D,0xE5,0xAF,0x63,0xBD,0x5F,0xB5, - 0x6E,0xDB,0x66,0xB3,0x2C,0xA0,0xD1,0x6B,0xC2,0x82,0x28,0xBB,0xEF,0xD7,0xFE,0xA1, - 0x3D,0x5A,0x00,0x56,0xFD,0xD2,0x28,0x36,0x8D,0xEE,0xFC,0x3F,0x58,0xFE,0x5D,0x0C, - 0x82,0xE8,0x7F,0x0D,0x89,0xEE,0x4A,0xC1,0xF7,0xF3,0xB3,0x64,0xF7,0xB9,0x58,0xD6, - 0x76,0x62,0x67,0x52,0x9B,0xDA,0x19,0xDA,0xD3,0xCA,0x55,0xF9,0xBD,0xBD,0x38,0x4E, - 0x23,0xA5,0xF8,0xA9,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, - 0x04,0x16,0x04,0x14,0xD8,0xEA,0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC, - 0xB4,0x63,0x42,0xAF,0x57,0xCC,0xBC,0x79,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04, - 0x18,0x30,0x16,0x80,0x14,0x86,0xC8,0x90,0xD5,0xD7,0x5C,0x3A,0xE1,0x29,0xF4,0x13, - 0x54,0xD0,0x06,0x90,0xAA,0xEC,0xF8,0x97,0xF7,0x30,0x09,0x06,0x07,0x2A,0x86,0x48, - 0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0xBD,0x7D,0x2C,0x3A, - 0xC6,0xE6,0xA7,0xDB,0x73,0xA2,0x36,0x13,0x38,0xC4,0x17,0x71,0x35,0x41,0x23,0xC7, - 0xCC,0xF1,0x9E,0x89,0x97,0x1F,0xD7,0xFC,0x58,0x9D,0x50,0x2D,0x0B,0xD9,0x33,0xD5, - 0x7E,0xB4,0xD8,0x43,0xCF,0xDB,0x0A,0xBE,0xBE,0x44,0xDF,0x10,0x02,0x31,0x00,0xFD, - 0xE3,0x32,0x58,0x06,0x7D,0xA1,0x7B,0x1F,0x22,0x85,0x82,0x54,0xD9,0xB0,0x36,0x4A, - 0x2E,0x0B,0x24,0xA6,0x9B,0xBD,0x15,0x76,0xDB,0xAC,0xD4,0x97,0x91,0x64,0x11,0xFE, - 0x47,0x11,0x59,0xBC,0xAF,0x1C,0x5A,0x16,0xF8,0x2E,0x0B,0x46,0x2C,0xD7,0x6E, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp128r1 Test Leaf */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ -unsigned char _leaf128[599]={ - 0x30,0x82,0x02,0x53,0x30,0x82,0x01,0xDA,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x49, - 0xF9,0xF0,0x5F,0xA0,0x17,0xBD,0x2F,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, - 0x04,0x01,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, - 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, - 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, - 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D, - 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x32,0x33,0x34,0x5A,0x17,0x0D,0x31, - 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x32,0x33,0x34,0x5A,0x30,0x75,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13, - 0x73,0x65,0x63,0x70,0x31,0x32,0x38,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x4C, - 0x65,0x61,0x66,0x30,0x36,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, - 0x06,0x05,0x2B,0x81,0x04,0x00,0x1C,0x03,0x22,0x00,0x04,0xB1,0x4F,0xBB,0xCA,0x19, - 0xDD,0x23,0xF4,0x58,0xC2,0xDF,0x70,0x7A,0x46,0xB4,0xC9,0x22,0x71,0xF6,0x4D,0x1D, - 0xDA,0x4C,0x0F,0x62,0x68,0x14,0x42,0xA7,0x77,0x8F,0xC6,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,0x05,0xA0,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,0x56,0x3C,0xD0, - 0xEF,0xEF,0x08,0x74,0x41,0xD8,0xAB,0x26,0x21,0xD7,0xD9,0x6A,0xED,0xE1,0x1B,0x54, - 0xF2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xD8,0xEA, - 0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC,0xB4,0x63,0x42,0xAF,0x57,0xCC, - 0xBC,0x79,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x68,0x00, - 0x30,0x65,0x02,0x31,0x00,0xFD,0x13,0x19,0x07,0xFB,0xD1,0x1B,0x3A,0xB1,0x82,0x2D, - 0xA0,0x16,0xEE,0xAD,0x0B,0xCF,0x19,0x65,0x49,0x64,0xCE,0x03,0x04,0x32,0xD9,0x1F, - 0xD2,0xC7,0x0A,0x43,0xD8,0xB9,0x9B,0x74,0x41,0x1A,0x20,0xAA,0xB3,0x2A,0xA8,0x71, - 0xAC,0x65,0x73,0xBE,0xD1,0x02,0x30,0x2D,0x0D,0xFC,0x08,0x2E,0x9A,0x61,0xA3,0xB6, - 0x55,0x72,0x4A,0x26,0x73,0xE3,0xA2,0x1A,0xE4,0x64,0x1C,0x44,0x93,0x5B,0xF8,0x93, - 0xBB,0x42,0x2E,0x01,0xC9,0xAF,0xE1,0x98,0x04,0x8B,0x8C,0xC1,0x9F,0x2B,0x37,0x54, - 0x4B,0x55,0xC9,0xF2,0x3F,0x6F,0x5E, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=prime192v1 Test Leaf */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ -unsigned char _leaf192[619]={ - 0x30,0x82,0x02,0x67,0x30,0x82,0x01,0xEE,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x49, - 0xF9,0xF0,0x5F,0xA0,0x17,0xBD,0x30,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, - 0x04,0x01,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, - 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, - 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, - 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D, - 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x32,0x34,0x33,0x5A,0x17,0x0D,0x31, - 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x32,0x34,0x33,0x5A,0x30,0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14, - 0x70,0x72,0x69,0x6D,0x65,0x31,0x39,0x32,0x76,0x31,0x20,0x54,0x65,0x73,0x74,0x20, - 0x4C,0x65,0x61,0x66,0x30,0x49,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02, - 0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,0x03,0x32,0x00,0x04,0x29, - 0x68,0x3F,0x3A,0xC9,0x63,0xDD,0x0F,0xC9,0x1A,0x4B,0x94,0x5C,0xEE,0x2C,0x41,0x42, - 0xE0,0x35,0x9B,0xA9,0x93,0x03,0x8C,0xB7,0x2A,0xC5,0x96,0x8D,0x33,0x94,0x90,0x58, - 0x78,0x5F,0xA4,0xFE,0x93,0x96,0x89,0x4D,0x50,0xB6,0xB8,0x78,0x40,0xC5,0xBA,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,0x05, - 0xA0,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,0x69,0x6E,0x52,0x27,0xD9,0x64,0x18,0x47,0x7F,0x23,0xF7,0xFB,0xF6,0x07,0x48, - 0xDD,0x0E,0x48,0x0D,0xC3,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, - 0x80,0x14,0xD8,0xEA,0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC,0xB4,0x63, - 0x42,0xAF,0x57,0xCC,0xBC,0x79,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04, - 0x01,0x03,0x68,0x00,0x30,0x65,0x02,0x31,0x00,0xC3,0x36,0x26,0x00,0x44,0x7B,0xEE, - 0xAA,0x4A,0x13,0xA5,0x64,0x8A,0x6B,0x40,0x91,0x43,0x3A,0x4E,0x3C,0xDF,0x28,0x59, - 0x12,0x86,0xB1,0x45,0x34,0x23,0xAE,0x8B,0x6D,0x91,0x7D,0xFB,0x0E,0x15,0xF9,0xC9, - 0xFB,0x52,0x96,0xBA,0x0B,0xBE,0x84,0xAC,0x58,0x02,0x30,0x5C,0x21,0x90,0x17,0x18, - 0x38,0xA3,0x40,0xAF,0x53,0x76,0x88,0x4B,0x22,0x97,0x5E,0x54,0xF2,0x98,0x0F,0xB5, - 0x61,0x4C,0x10,0x44,0x53,0xFC,0xB6,0x6E,0xF3,0x9E,0x2C,0x4B,0x3B,0xAC,0xC8,0x90, - 0xBF,0xAE,0xEC,0xC7,0x62,0xFE,0x2F,0xAF,0x1A,0x90,0x35, -}; - -/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Leaf 3 */ -/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ -unsigned char _leaf384C[665]={ - 0x30,0x82,0x02,0x95,0x30,0x82,0x02,0x1C,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x49, - 0xF9,0xF0,0x5F,0xA0,0x17,0xBD,0x31,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, - 0x04,0x01,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, - 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, - 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, - 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D, - 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x32,0x35,0x35,0x5A,0x17,0x0D,0x31, - 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x32,0x35,0x35,0x5A,0x30,0x77,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, - 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, - 0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x4C, - 0x65,0x61,0x66,0x20,0x33,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, - 0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x1F,0x62,0x07, - 0xBA,0x5D,0x2A,0x56,0xED,0x5D,0xE7,0x0B,0x18,0xDE,0x65,0x13,0xA4,0x31,0x53,0xFC, - 0x86,0x86,0xB4,0xC4,0x27,0x39,0x4D,0xD1,0x22,0xC2,0xFF,0x07,0x62,0xAB,0x64,0xDD, - 0xCC,0xEB,0x7F,0x08,0x12,0x78,0x20,0x90,0x40,0xD3,0xCF,0x45,0x71,0x98,0x6E,0x4E, - 0x93,0xC5,0x66,0x40,0x76,0xB0,0xAD,0xDB,0xD6,0xFA,0x9C,0x7F,0x46,0xF9,0xC9,0xDE, - 0xF5,0x41,0xA3,0x0C,0x7F,0x73,0xF3,0x0C,0x91,0xE1,0x0B,0xAD,0xBC,0xD5,0xD2,0xB1, - 0x6F,0xC3,0x1F,0x43,0x94,0x9C,0x18,0x5B,0xD9,0xE1,0x5A,0x84,0x2F,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,0x05,0xA0,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,0xB3, - 0xB5,0xC9,0x62,0x46,0xDD,0x1C,0x89,0x93,0xE3,0xAA,0x7C,0xEA,0x61,0x22,0x8B,0xF2, - 0x04,0x31,0x74,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, - 0xD8,0xEA,0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC,0xB4,0x63,0x42,0xAF, - 0x57,0xCC,0xBC,0x79,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03, - 0x68,0x00,0x30,0x65,0x02,0x30,0x33,0xE4,0xE8,0x8E,0x00,0x57,0xE4,0x53,0xCC,0xD4, - 0x04,0xF2,0xB6,0x7D,0xD5,0x14,0x5B,0xB2,0xBE,0x28,0xF8,0x5D,0x55,0x7A,0xB3,0x06, - 0x17,0x87,0xA9,0xAA,0x23,0xCE,0xAF,0x15,0xF3,0xE1,0xA8,0x9B,0xCF,0x06,0xC9,0x06, - 0x75,0x0C,0x13,0x12,0x40,0x32,0x02,0x31,0x00,0xE2,0x28,0x4A,0x28,0xA6,0x94,0x2C, - 0x8E,0x5A,0x13,0xCF,0x33,0xBB,0x6A,0x11,0x74,0x3A,0xED,0x3A,0x61,0x07,0x6D,0x49, - 0x84,0xBF,0xE2,0x1F,0xED,0x08,0x70,0x0F,0xCA,0x45,0xBA,0x68,0x1C,0xF3,0x15,0x7E, - 0xAB,0x41,0x0E,0xAB,0x84,0x29,0x33,0x87,0x3A, -}; - -/* subject:/C=US/O=Apple Inc./OU=Apple Accessories/CN=IPA_204E6F2CB683A518F7726D190000C5DA */ -/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ -unsigned char _leaf_NegativeIntInSig[559]={ - 0x30,0x82,0x02,0x2B,0x30,0x82,0x01,0xD1,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x20, - 0x4E,0x6F,0x2C,0xB6,0x83,0xA5,0x18,0xF7,0x72,0x6D,0x19,0x00,0x00,0xC5,0xDA,0x30, - 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x89,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,0x3D,0x30,0x3B,0x06,0x03,0x55,0x04, - 0x03,0x13,0x34,0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F, - 0x72,0x69,0x65,0x73,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,0x30, - 0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x33, - 0x31,0x31,0x31,0x35,0x31,0x31,0x37,0x5A,0x17,0x0D,0x34,0x39,0x31,0x32,0x33,0x31, - 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x6D,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,0x1A,0x30,0x18,0x06, - 0x03,0x55,0x04,0x0B,0x13,0x11,0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65, - 0x73,0x73,0x6F,0x72,0x69,0x65,0x73,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x03, - 0x14,0x24,0x49,0x50,0x41,0x5F,0x32,0x30,0x34,0x45,0x36,0x46,0x32,0x43,0x42,0x36, - 0x38,0x33,0x41,0x35,0x31,0x38,0x46,0x37,0x37,0x32,0x36,0x44,0x31,0x39,0x30,0x30, - 0x30,0x30,0x43,0x35,0x44,0x41,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,0x9A,0x21,0x88,0x3D,0x3B,0xCD,0xA9,0x9F,0x1B,0xC6,0x5F,0x47,0x5D,0xA8,0xEB, - 0x52,0x18,0x9F,0x1E,0xF3,0xD8,0x7C,0xB6,0x1D,0x39,0x7A,0x8C,0xE0,0xDB,0x79,0xB4, - 0x9D,0x37,0x16,0xB8,0x6F,0x1C,0x29,0x42,0x59,0xA5,0x4E,0xA2,0x9A,0xB1,0x0E,0xC4, - 0x55,0xCC,0x89,0x79,0x4A,0x9E,0xDB,0x95,0x7A,0xF3,0x3D,0x7F,0x58,0xAD,0xF7,0x61, - 0xB3,0xA3,0x36,0x30,0x34,0x30,0x32,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64, - 0x06,0x24,0x01,0x01,0xFF,0x04,0x22,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,0x04,0x00,0x00,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48, - 0xCE,0x3D,0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x80,0x6B,0x96,0x6C, - 0x83,0x04,0x29,0x68,0x52,0xF9,0x74,0x42,0x7C,0x49,0x81,0x39,0x53,0x91,0x53,0x0D, - 0x95,0xB7,0x4F,0x18,0xFC,0xA5,0x38,0x9A,0x55,0x68,0x53,0x02,0x02,0x21,0x00,0xF5, - 0xE4,0xF2,0xB7,0x0B,0x7F,0x43,0xFA,0xDB,0xC2,0x1A,0x05,0xEF,0xF9,0x0E,0x31,0xFC, - 0x0A,0xCB,0xCD,0x6C,0x03,0x8A,0x73,0x95,0x74,0xB1,0x57,0x03,0x09,0x55,0x8D, -}; - -/* subject:/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ -/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ -unsigned char _root_AACA2[618]={ - 0x30,0x82,0x02,0x66,0x30,0x82,0x02,0x0C,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, - 0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x89,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,0x3D,0x30,0x3B,0x06,0x03,0x55, - 0x04,0x03,0x13,0x34,0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65,0x73,0x73, - 0x6F,0x72,0x69,0x65,0x73,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, - 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x31, - 0x31,0x38,0x32,0x31,0x32,0x35,0x33,0x32,0x5A,0x17,0x0D,0x34,0x35,0x31,0x31,0x31, - 0x38,0x32,0x31,0x32,0x35,0x33,0x32,0x5A,0x30,0x81,0x89,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,0x3D,0x30,0x3B,0x06,0x03,0x55,0x04,0x03,0x13,0x34, - 0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,0x72,0x69,0x65, - 0x73,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,0x30,0x30,0x30,0x30, - 0x30,0x30,0x30,0x32,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,0x0E, - 0x9B,0x88,0xC9,0x72,0x9C,0x91,0x0B,0xA3,0x08,0xFE,0x6C,0x6B,0x70,0x0D,0xF6,0x49, - 0x31,0x87,0x60,0xE4,0xB9,0x0E,0x8A,0xD8,0xB1,0x41,0x2D,0xEE,0x09,0x9E,0x7A,0xD2, - 0x0C,0xEB,0xFD,0x97,0x23,0x33,0x8F,0xCD,0x44,0x0A,0x6C,0xBD,0x5E,0xA5,0xC0,0x1B, - 0x9E,0x04,0x8A,0xD4,0x28,0x17,0x52,0xE8,0x28,0x35,0x84,0xED,0x7D,0xBE,0x2A,0xA3, - 0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, - 0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, - 0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x58, - 0x4B,0x2B,0x2A,0x6C,0x19,0x2A,0x4D,0x45,0xCC,0x24,0x52,0x5A,0xEC,0x54,0x1A,0xA9, - 0xC8,0xA5,0x32,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, - 0x58,0x4B,0x2B,0x2A,0x6C,0x19,0x2A,0x4D,0x45,0xCC,0x24,0x52,0x5A,0xEC,0x54,0x1A, - 0xA9,0xC8,0xA5,0x32,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, - 0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x10,0x6F,0xD9,0x76,0x71,0xC9,0x4C,0xC0,0x78, - 0x6D,0x0E,0x43,0xD1,0x56,0x53,0x36,0x58,0x56,0xED,0x87,0x40,0xAC,0xF6,0xC5,0x86, - 0x87,0xF0,0xCD,0xA6,0x13,0x3B,0x53,0x02,0x21,0x00,0xD6,0x45,0x85,0xE3,0xE3,0x1A, - 0xE1,0x7D,0x22,0xD8,0x36,0xC1,0x88,0xC1,0x07,0xD9,0x4D,0x88,0x2E,0x08,0xA2,0xDD, - 0x13,0xB5,0x2A,0xAE,0x3B,0x83,0x2B,0xB2,0x7E,0xB3, -}; - -/* subject:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.badssl.com */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ -unsigned char _expired_badssl[1359]={ - 0x30,0x82,0x05,0x4B,0x30,0x82,0x04,0x33,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4A, - 0xE7,0x95,0x49,0xFA,0x9A,0xBE,0x3F,0x10,0x0F,0x17,0xA4,0x78,0xE1,0x69,0x09,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, - 0x90,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,0x36,0x30,0x34,0x06,0x03,0x55, - 0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44, - 0x6F,0x6D,0x61,0x69,0x6E,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,0x35,0x30,0x34,0x30,0x39,0x30,0x30,0x30,0x30,0x30, - 0x30,0x5A,0x17,0x0D,0x31,0x35,0x30,0x34,0x31,0x32,0x32,0x33,0x35,0x39,0x35,0x39, - 0x5A,0x30,0x59,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x44,0x6F, - 0x6D,0x61,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x56,0x61,0x6C, - 0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13, - 0x14,0x50,0x6F,0x73,0x69,0x74,0x69,0x76,0x65,0x53,0x53,0x4C,0x20,0x57,0x69,0x6C, - 0x64,0x63,0x61,0x72,0x64,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x14,0x0C, - 0x2A,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,0xC2,0x04,0xEC, - 0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58,0xCC,0x93,0x18,0xEB,0x5C, - 0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B,0x2C,0x76,0x3E,0x6C,0xC0, - 0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6,0xB0,0xF9,0x72,0xC9,0x86, - 0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B,0xBC,0xE9,0x94,0x2E,0x50, - 0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46,0xD3,0x16,0x87,0x27,0x9F, - 0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84,0x4C,0x79,0x55,0xE4,0xD1, - 0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB,0xAA,0xFF,0x6E,0xFF,0x60, - 0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD,0x4D,0xC0,0xC4,0xFC,0x53, - 0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2,0x33,0x48,0xE7,0x22,0x71, - 0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA,0x6C,0xB5,0x72,0xB4,0x7E, - 0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12,0xAB,0xDE,0xC3,0x0F,0x47, - 0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD,0x22,0x06,0x29,0x2E,0xB1, - 0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40,0x72,0x00,0xAC,0x92,0x08, - 0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B,0x54,0x98,0x40,0x27,0x85, - 0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45,0x55,0x7C,0xF9,0x64,0x3F, - 0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1,0xCA,0x85,0x02,0x03,0x01, - 0x00,0x01,0xA3,0x82,0x01,0xD5,0x30,0x82,0x01,0xD1,0x30,0x1F,0x06,0x03,0x55,0x1D, - 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90, - 0xEA,0x12,0x56,0x73,0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x1D,0x06,0x03,0x55, - 0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81,0x0B,0x3A,0x47,0x69,0x71, - 0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,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,0x4F,0x06,0x03,0x55,0x1D,0x20,0x04,0x48, - 0x30,0x46,0x30,0x3A,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x02, - 0x07,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,0x08, - 0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x01,0x30,0x54,0x06,0x03,0x55,0x1D,0x1F,0x04, - 0x4D,0x30,0x4B,0x30,0x49,0xA0,0x47,0xA0,0x45,0x86,0x43,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,0x44,0x6F,0x6D,0x61, - 0x69,0x6E,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, - 0x85,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x79,0x30,0x77,0x30, - 0x4F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x43,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,0x44,0x6F, - 0x6D,0x61,0x69,0x6E,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,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30, - 0x1A,0x82,0x0C,0x2A,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82, - 0x0A,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A, - 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6A, - 0x7A,0xF1,0xDA,0xFF,0x03,0x07,0x72,0x78,0xC5,0x66,0xA1,0x4F,0x46,0x43,0x0E,0x5F, - 0x14,0x21,0x8C,0x75,0x1A,0xEB,0x36,0xE0,0x1F,0xA4,0x10,0x15,0xEC,0xDA,0x33,0x25, - 0x7C,0x3B,0xB5,0x0A,0xC7,0x01,0x38,0x3D,0x27,0xFD,0x58,0xD9,0xCC,0xEA,0x2D,0x69, - 0x39,0x7C,0xBE,0x97,0xEF,0x0B,0xD6,0x0B,0x58,0xE7,0x8C,0x7F,0xBF,0xB3,0x4C,0x1D, - 0xF3,0xB7,0x90,0x80,0xA6,0x36,0x7C,0x14,0x5B,0xEC,0x07,0x2D,0x02,0x3E,0x1B,0x5B, - 0x63,0x5B,0x15,0xAB,0x00,0xFA,0x1F,0x3B,0x19,0x2D,0xDF,0xE2,0x23,0x10,0x11,0x07, - 0x7E,0x72,0x7F,0xE2,0xBF,0xB7,0x00,0x1B,0x98,0x2F,0x2C,0x3F,0xCE,0x85,0x9A,0x27, - 0x8C,0x10,0x22,0x08,0x41,0x2B,0x8A,0x3E,0x82,0x4E,0xFC,0xDD,0x21,0xC6,0x56,0x74, - 0x70,0xA4,0x34,0xF2,0xB1,0x40,0x9E,0x2B,0x58,0xA2,0x59,0x0F,0x1D,0x48,0xEF,0xEB, - 0x11,0x3E,0xC1,0x4A,0x9E,0xBC,0x65,0x55,0x6D,0xC6,0xA3,0xEF,0xD5,0xD4,0x96,0xCD, - 0xF1,0xAE,0x27,0xF7,0xA4,0x57,0x14,0x3C,0x94,0x41,0x05,0x7A,0x8B,0xA1,0x37,0x47, - 0xD7,0xF5,0x7D,0xDC,0xFA,0xCE,0x6F,0x31,0xA2,0xB0,0x8C,0xEA,0xCC,0x12,0x9B,0x22, - 0xF1,0x34,0x70,0xCF,0x7D,0x75,0x4A,0x8B,0x68,0x29,0x0C,0x1E,0xE9,0x96,0xA8,0xCF, - 0xB0,0x12,0x1F,0x5C,0x2A,0xEE,0x67,0x2F,0x7F,0xBD,0x73,0xF3,0x5A,0x01,0x22,0x0C, - 0x70,0xFA,0xCD,0x45,0xEF,0x78,0x5C,0xCE,0x0D,0xFA,0x4E,0xE1,0xEF,0xCE,0x65,0x9F, - 0x47,0x0C,0x4F,0xBB,0x36,0x44,0x68,0x56,0x5C,0x56,0x59,0xAD,0xAA,0x8A,0xBC, -}; - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ -unsigned char _comodo_rsa_dvss[1548]={ - 0x30,0x82,0x06,0x08,0x30,0x82,0x03,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2B, - 0x2E,0x6E,0xEA,0xD9,0x75,0x36,0x6C,0x14,0x8A,0x6E,0xDB,0xA3,0x7C,0x8C,0x07,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,0x34,0x30,0x32,0x31,0x32, - 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x32,0x31,0x31,0x32, - 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x90,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,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F, - 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44,0x6F,0x6D,0x61,0x69,0x6E,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,0x8E,0xC2,0x02,0x19,0xE1,0xA0, - 0x59,0xA4,0xEB,0x38,0x35,0x8D,0x2C,0xFD,0x01,0xD0,0xD3,0x49,0xC0,0x64,0xC7,0x0B, - 0x62,0x05,0x45,0x16,0x3A,0xA8,0xA0,0xC0,0x0C,0x02,0x7F,0x1D,0xCC,0xDB,0xC4,0xA1, - 0x6D,0x77,0x03,0xA3,0x0F,0x86,0xF9,0xE3,0x06,0x9C,0x3E,0x0B,0x81,0x8A,0x9B,0x49, - 0x1B,0xAD,0x03,0xBE,0xFA,0x4B,0xDB,0x8C,0x20,0xED,0xD5,0xCE,0x5E,0x65,0x8E,0x3E, - 0x0D,0xAF,0x4C,0xC2,0xB0,0xB7,0x45,0x5E,0x52,0x2F,0x34,0xDE,0x48,0x24,0x64,0xB4, - 0x41,0xAE,0x00,0x97,0xF7,0xBE,0x67,0xDE,0x9E,0xD0,0x7A,0xA7,0x53,0x80,0x3B,0x7C, - 0xAD,0xF5,0x96,0x55,0x6F,0x97,0x47,0x0A,0x7C,0x85,0x8B,0x22,0x97,0x8D,0xB3,0x84, - 0xE0,0x96,0x57,0xD0,0x70,0x18,0x60,0x96,0x8F,0xEE,0x2D,0x07,0x93,0x9D,0xA1,0xBA, - 0xCA,0xD1,0xCD,0x7B,0xE9,0xC4,0x2A,0x9A,0x28,0x21,0x91,0x4D,0x6F,0x92,0x4F,0x25, - 0xA5,0xF2,0x7A,0x35,0xDD,0x26,0xDC,0x46,0xA5,0xD0,0xAC,0x59,0x35,0x8C,0xFF,0x4E, - 0x91,0x43,0x50,0x3F,0x59,0x93,0x1E,0x6C,0x51,0x21,0xEE,0x58,0x14,0xAB,0xFE,0x75, - 0x50,0x78,0x3E,0x4C,0xB0,0x1C,0x86,0x13,0xFA,0x6B,0x98,0xBC,0xE0,0x3B,0x94,0x1E, - 0x85,0x52,0xDC,0x03,0x93,0x24,0x18,0x6E,0xCB,0x27,0x51,0x45,0xE6,0x70,0xDE,0x25, - 0x43,0xA4,0x0D,0xE1,0x4A,0xA5,0xED,0xB6,0x7E,0xC8,0xCD,0x6D,0xEE,0x2E,0x1D,0x27, - 0x73,0x5D,0xDC,0x45,0x30,0x80,0xAA,0xE3,0xB2,0x41,0x0B,0xAF,0xBD,0x44,0x87,0xDA, - 0xB9,0xE5,0x1B,0x9D,0x7F,0xAE,0xE5,0x85,0x82,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3, - 0x82,0x01,0x65,0x30,0x82,0x01,0x61,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,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90,0xEA,0x12,0x56,0x73, - 0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, - 0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,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,0x1B,0x06,0x03,0x55,0x1D, - 0x20,0x04,0x14,0x30,0x12,0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x08,0x06, - 0x06,0x67,0x81,0x0C,0x01,0x02,0x01,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,0x4E,0x2B,0x76,0x4F, - 0x92,0x1C,0x62,0x36,0x89,0xBA,0x77,0xC1,0x27,0x05,0xF4,0x1C,0xD6,0x44,0x9D,0xA9, - 0x9A,0x3E,0xAA,0xD5,0x66,0x66,0x01,0x3E,0xEA,0x49,0xE6,0xA2,0x35,0xBC,0xFA,0xF6, - 0xDD,0x95,0x8E,0x99,0x35,0x98,0x0E,0x36,0x18,0x75,0xB1,0xDD,0xDD,0x50,0x72,0x7C, - 0xAE,0xDC,0x77,0x88,0xCE,0x0F,0xF7,0x90,0x20,0xCA,0xA3,0x67,0x2E,0x1F,0x56,0x7F, - 0x7B,0xE1,0x44,0xEA,0x42,0x95,0xC4,0x5D,0x0D,0x01,0x50,0x46,0x15,0xF2,0x81,0x89, - 0x59,0x6C,0x8A,0xDD,0x8C,0xF1,0x12,0xA1,0x8D,0x3A,0x42,0x8A,0x98,0xF8,0x4B,0x34, - 0x7B,0x27,0x3B,0x08,0xB4,0x6F,0x24,0x3B,0x72,0x9D,0x63,0x74,0x58,0x3C,0x1A,0x6C, - 0x3F,0x4F,0xC7,0x11,0x9A,0xC8,0xA8,0xF5,0xB5,0x37,0xEF,0x10,0x45,0xC6,0x6C,0xD9, - 0xE0,0x5E,0x95,0x26,0xB3,0xEB,0xAD,0xA3,0xB9,0xEE,0x7F,0x0C,0x9A,0x66,0x35,0x73, - 0x32,0x60,0x4E,0xE5,0xDD,0x8A,0x61,0x2C,0x6E,0x52,0x11,0x77,0x68,0x96,0xD3,0x18, - 0x75,0x51,0x15,0x00,0x1B,0x74,0x88,0xDD,0xE1,0xC7,0x38,0x04,0x43,0x28,0xE9,0x16, - 0xFD,0xD9,0x05,0xD4,0x5D,0x47,0x27,0x60,0xD6,0xFB,0x38,0x3B,0x6C,0x72,0xA2,0x94, - 0xF8,0x42,0x1A,0xDF,0xED,0x6F,0x06,0x8C,0x45,0xC2,0x06,0x00,0xAA,0xE4,0xE8,0xDC, - 0xD9,0xB5,0xE1,0x73,0x78,0xEC,0xF6,0x23,0xDC,0xD1,0xDD,0x6C,0x8E,0x1A,0x8F,0xA5, - 0xEA,0x54,0x7C,0x96,0xB7,0xC3,0xFE,0x55,0x8E,0x8D,0x49,0x5E,0xFC,0x64,0xBB,0xCF, - 0x3E,0xBD,0x96,0xEB,0x69,0xCD,0xBF,0xE0,0x48,0xF1,0x62,0x82,0x10,0xE5,0x0C,0x46, - 0x57,0xF2,0x33,0xDA,0xD0,0xC8,0x63,0xED,0xC6,0x1F,0x94,0x05,0x96,0x4A,0x1A,0x91, - 0xD1,0xF7,0xEB,0xCF,0x8F,0x52,0xAE,0x0D,0x08,0xD9,0x3E,0xA8,0xA0,0x51,0xE9,0xC1, - 0x87,0x74,0xD5,0xC9,0xF7,0x74,0xAB,0x2E,0x53,0xFB,0xBB,0x7A,0xFB,0x97,0xE2,0xF8, - 0x1F,0x26,0x8F,0xB3,0xD2,0xA0,0xE0,0x37,0x5B,0x28,0x3B,0x31,0xE5,0x0E,0x57,0x2D, - 0x5A,0xB8,0xAD,0x79,0xAC,0x5E,0x20,0x66,0x1A,0xA5,0xB9,0xA6,0xB5,0x39,0xC1,0xF5, - 0x98,0x43,0xFF,0xEE,0xF9,0xA7,0xA7,0xFD,0xEE,0xCA,0x24,0x3D,0x80,0x16,0xC4,0x17, - 0x8F,0x8A,0xC1,0x60,0xA1,0x0C,0xAE,0x5B,0x43,0x47,0x91,0x4B,0xD5,0x9A,0x17,0x5F, - 0xF9,0xD4,0x87,0xC1,0xC2,0x8C,0xB7,0xE7,0xE2,0x0F,0x30,0x19,0x37,0x86,0xAC,0xE0, - 0xDC,0x42,0x03,0xE6,0x94,0xA8,0x9D,0xAE,0xFD,0x0F,0x24,0x51,0x94,0xCE,0x92,0x08, - 0xD1,0xFC,0x50,0xF0,0x03,0x40,0x7B,0x88,0x59,0xED,0x0E,0xDD,0xAC,0xD2,0x77,0x82, - 0x34,0xDC,0x06,0x95,0x02,0xD8,0x90,0xF9,0x2D,0xEA,0x37,0xD5,0x1A,0x60,0xD0,0x67, - 0x20,0xD7,0xD8,0x42,0x0B,0x45,0xAF,0x82,0x68,0xDE,0xDD,0x66,0x24,0x37,0x90,0x29, - 0x94,0x19,0x46,0x19,0x25,0xB8,0x80,0xD7,0xCB,0xD4,0x86,0x28,0x6A,0x44,0x70,0x26, - 0x23,0x62,0xA9,0x9F,0x86,0x6F,0xBF,0xBA,0x90,0x70,0xD2,0x56,0x77,0x85,0x78,0xEF, - 0xEA,0x25,0xA9,0x17,0xCE,0x50,0x72,0x8C,0x00,0x3A,0xAA,0xE3,0xDB,0x63,0x34,0x9F, - 0xF8,0x06,0x71,0x01,0xE2,0x82,0x20,0xD4,0xFE,0x6F,0xBD,0xB1, -}; - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ -unsigned char _comodo_rsa_root[1500]={ - 0x30,0x82,0x05,0xD8,0x30,0x82,0x03,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, - 0xAA,0xF9,0xCA,0xDB,0x63,0x6F,0xE0,0x1F,0xF7,0x4E,0xD8,0x5B,0x03,0x86,0x9D,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,0x30,0x30,0x31,0x31,0x39, - 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32, - 0x33,0x35,0x39,0x35,0x39,0x5A,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,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,0x91, - 0xE8,0x54,0x92,0xD2,0x0A,0x56,0xB1,0xAC,0x0D,0x24,0xDD,0xC5,0xCF,0x44,0x67,0x74, - 0x99,0x2B,0x37,0xA3,0x7D,0x23,0x70,0x00,0x71,0xBC,0x53,0xDF,0xC4,0xFA,0x2A,0x12, - 0x8F,0x4B,0x7F,0x10,0x56,0xBD,0x9F,0x70,0x72,0xB7,0x61,0x7F,0xC9,0x4B,0x0F,0x17, - 0xA7,0x3D,0xE3,0xB0,0x04,0x61,0xEE,0xFF,0x11,0x97,0xC7,0xF4,0x86,0x3E,0x0A,0xFA, - 0x3E,0x5C,0xF9,0x93,0xE6,0x34,0x7A,0xD9,0x14,0x6B,0xE7,0x9C,0xB3,0x85,0xA0,0x82, - 0x7A,0x76,0xAF,0x71,0x90,0xD7,0xEC,0xFD,0x0D,0xFA,0x9C,0x6C,0xFA,0xDF,0xB0,0x82, - 0xF4,0x14,0x7E,0xF9,0xBE,0xC4,0xA6,0x2F,0x4F,0x7F,0x99,0x7F,0xB5,0xFC,0x67,0x43, - 0x72,0xBD,0x0C,0x00,0xD6,0x89,0xEB,0x6B,0x2C,0xD3,0xED,0x8F,0x98,0x1C,0x14,0xAB, - 0x7E,0xE5,0xE3,0x6E,0xFC,0xD8,0xA8,0xE4,0x92,0x24,0xDA,0x43,0x6B,0x62,0xB8,0x55, - 0xFD,0xEA,0xC1,0xBC,0x6C,0xB6,0x8B,0xF3,0x0E,0x8D,0x9A,0xE4,0x9B,0x6C,0x69,0x99, - 0xF8,0x78,0x48,0x30,0x45,0xD5,0xAD,0xE1,0x0D,0x3C,0x45,0x60,0xFC,0x32,0x96,0x51, - 0x27,0xBC,0x67,0xC3,0xCA,0x2E,0xB6,0x6B,0xEA,0x46,0xC7,0xC7,0x20,0xA0,0xB1,0x1F, - 0x65,0xDE,0x48,0x08,0xBA,0xA4,0x4E,0xA9,0xF2,0x83,0x46,0x37,0x84,0xEB,0xE8,0xCC, - 0x81,0x48,0x43,0x67,0x4E,0x72,0x2A,0x9B,0x5C,0xBD,0x4C,0x1B,0x28,0x8A,0x5C,0x22, - 0x7B,0xB4,0xAB,0x98,0xD9,0xEE,0xE0,0x51,0x83,0xC3,0x09,0x46,0x4E,0x6D,0x3E,0x99, - 0xFA,0x95,0x17,0xDA,0x7C,0x33,0x57,0x41,0x3C,0x8D,0x51,0xED,0x0B,0xB6,0x5C,0xAF, - 0x2C,0x63,0x1A,0xDF,0x57,0xC8,0x3F,0xBC,0xE9,0x5D,0xC4,0x9B,0xAF,0x45,0x99,0xE2, - 0xA3,0x5A,0x24,0xB4,0xBA,0xA9,0x56,0x3D,0xCF,0x6F,0xAA,0xFF,0x49,0x58,0xBE,0xF0, - 0xA8,0xFF,0xF4,0xB8,0xAD,0xE9,0x37,0xFB,0xBA,0xB8,0xF4,0x0B,0x3A,0xF9,0xE8,0x43, - 0x42,0x1E,0x89,0xD8,0x84,0xCB,0x13,0xF1,0xD9,0xBB,0xE1,0x89,0x60,0xB8,0x8C,0x28, - 0x56,0xAC,0x14,0x1D,0x9C,0x0A,0xE7,0x71,0xEB,0xCF,0x0E,0xDD,0x3D,0xA9,0x96,0xA1, - 0x48,0xBD,0x3C,0xF7,0xAF,0xB5,0x0D,0x22,0x4C,0xC0,0x11,0x81,0xEC,0x56,0x3B,0xF6, - 0xD3,0xA2,0xE2,0x5B,0xB7,0xB2,0x04,0x22,0x52,0x95,0x80,0x93,0x69,0xE8,0x8E,0x4C, - 0x65,0xF1,0x91,0x03,0x2D,0x70,0x74,0x02,0xEA,0x8B,0x67,0x15,0x29,0x69,0x52,0x02, - 0xBB,0xD7,0xDF,0x50,0x6A,0x55,0x46,0xBF,0xA0,0xA3,0x28,0x61,0x7F,0x70,0xD0,0xC3, - 0xA2,0xAA,0x2C,0x21,0xAA,0x47,0xCE,0x28,0x9C,0x06,0x45,0x76,0xBF,0x82,0x18,0x27, - 0xB4,0xD5,0xAE,0xB4,0xCB,0x50,0xE6,0x6B,0xF4,0x4C,0x86,0x71,0x30,0xE9,0xA6,0xDF, - 0x16,0x86,0xE0,0xD8,0xFF,0x40,0xDD,0xFB,0xD0,0x42,0x88,0x7F,0xA3,0x33,0x3A,0x2E, - 0x5C,0x1E,0x41,0x11,0x81,0x63,0xCE,0x18,0x71,0x6B,0x2B,0xEC,0xA6,0x8A,0xB7,0x31, - 0x5C,0x3A,0x6A,0x47,0xE0,0xC3,0x79,0x59,0xD6,0x20,0x1A,0xAF,0xF2,0x6A,0x98,0xAA, - 0x72,0xBC,0x57,0x4A,0xD2,0x4B,0x9D,0xBB,0x10,0xFC,0xB0,0x4C,0x41,0xE5,0xED,0x1D, - 0x3D,0x5E,0x28,0x9D,0x9C,0xCC,0xBF,0xB3,0x51,0xDA,0xA7,0x47,0xE5,0x84,0x53,0x02, - 0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, - 0x16,0x04,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84,0x8E,0xAD,0xEE, - 0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,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,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, - 0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x0A,0xF1,0xD5,0x46, - 0x84,0xB7,0xAE,0x51,0xBB,0x6C,0xB2,0x4D,0x41,0x14,0x00,0x93,0x4C,0x9C,0xCB,0xE5, - 0xC0,0x54,0xCF,0xA0,0x25,0x8E,0x02,0xF9,0xFD,0xB0,0xA2,0x0D,0xF5,0x20,0x98,0x3C, - 0x13,0x2D,0xAC,0x56,0xA2,0xB0,0xD6,0x7E,0x11,0x92,0xE9,0x2E,0xBA,0x9E,0x2E,0x9A, - 0x72,0xB1,0xBD,0x19,0x44,0x6C,0x61,0x35,0xA2,0x9A,0xB4,0x16,0x12,0x69,0x5A,0x8C, - 0xE1,0xD7,0x3E,0xA4,0x1A,0xE8,0x2F,0x03,0xF4,0xAE,0x61,0x1D,0x10,0x1B,0x2A,0xA4, - 0x8B,0x7A,0xC5,0xFE,0x05,0xA6,0xE1,0xC0,0xD6,0xC8,0xFE,0x9E,0xAE,0x8F,0x2B,0xBA, - 0x3D,0x99,0xF8,0xD8,0x73,0x09,0x58,0x46,0x6E,0xA6,0x9C,0xF4,0xD7,0x27,0xD3,0x95, - 0xDA,0x37,0x83,0x72,0x1C,0xD3,0x73,0xE0,0xA2,0x47,0x99,0x03,0x38,0x5D,0xD5,0x49, - 0x79,0x00,0x29,0x1C,0xC7,0xEC,0x9B,0x20,0x1C,0x07,0x24,0x69,0x57,0x78,0xB2,0x39, - 0xFC,0x3A,0x84,0xA0,0xB5,0x9C,0x7C,0x8D,0xBF,0x2E,0x93,0x62,0x27,0xB7,0x39,0xDA, - 0x17,0x18,0xAE,0xBD,0x3C,0x09,0x68,0xFF,0x84,0x9B,0x3C,0xD5,0xD6,0x0B,0x03,0xE3, - 0x57,0x9E,0x14,0xF7,0xD1,0xEB,0x4F,0xC8,0xBD,0x87,0x23,0xB7,0xB6,0x49,0x43,0x79, - 0x85,0x5C,0xBA,0xEB,0x92,0x0B,0xA1,0xC6,0xE8,0x68,0xA8,0x4C,0x16,0xB1,0x1A,0x99, - 0x0A,0xE8,0x53,0x2C,0x92,0xBB,0xA1,0x09,0x18,0x75,0x0C,0x65,0xA8,0x7B,0xCB,0x23, - 0xB7,0x1A,0xC2,0x28,0x85,0xC3,0x1B,0xFF,0xD0,0x2B,0x62,0xEF,0xA4,0x7B,0x09,0x91, - 0x98,0x67,0x8C,0x14,0x01,0xCD,0x68,0x06,0x6A,0x63,0x21,0x75,0x03,0x80,0x88,0x8A, - 0x6E,0x81,0xC6,0x85,0xF2,0xA9,0xA4,0x2D,0xE7,0xF4,0xA5,0x24,0x10,0x47,0x83,0xCA, - 0xCD,0xF4,0x8D,0x79,0x58,0xB1,0x06,0x9B,0xE7,0x1A,0x2A,0xD9,0x9D,0x01,0xD7,0x94, - 0x7D,0xED,0x03,0x4A,0xCA,0xF0,0xDB,0xE8,0xA9,0x01,0x3E,0xF5,0x56,0x99,0xC9,0x1E, - 0x8E,0x49,0x3D,0xBB,0xE5,0x09,0xB9,0xE0,0x4F,0x49,0x92,0x3D,0x16,0x82,0x40,0xCC, - 0xCC,0x59,0xC6,0xE6,0x3A,0xED,0x12,0x2E,0x69,0x3C,0x6C,0x95,0xB1,0xFD,0xAA,0x1D, - 0x7B,0x7F,0x86,0xBE,0x1E,0x0E,0x32,0x46,0xFB,0xFB,0x13,0x8F,0x75,0x7F,0x4C,0x8B, - 0x4B,0x46,0x63,0xFE,0x00,0x34,0x40,0x70,0xC1,0xC3,0xB9,0xA1,0xDD,0xA6,0x70,0xE2, - 0x04,0xB3,0x41,0xBC,0xE9,0x80,0x91,0xEA,0x64,0x9C,0x7A,0xE1,0x22,0x03,0xA9,0x9C, - 0x6E,0x6F,0x0E,0x65,0x4F,0x6C,0x87,0x87,0x5E,0xF3,0x6E,0xA0,0xF9,0x75,0xA5,0x9B, - 0x40,0xE8,0x53,0xB2,0x27,0x9D,0x4A,0xB9,0xC0,0x77,0x21,0x8D,0xFF,0x87,0xF2,0xDE, - 0xBC,0x8C,0xEF,0x17,0xDF,0xB7,0x49,0x0B,0xD1,0xF2,0x6E,0x30,0x0B,0x1A,0x0E,0x4E, - 0x76,0xED,0x11,0xFC,0xF5,0xE9,0x56,0xB2,0x7D,0xBF,0xC7,0x6D,0x0A,0x93,0x8C,0xA5, - 0xD0,0xC0,0xB6,0x1D,0xBE,0x3A,0x4E,0x94,0xA2,0xD7,0x6E,0x6C,0x0B,0xC2,0x8A,0x7C, - 0xFA,0x20,0xF3,0xC4,0xE4,0xE5,0xCD,0x0D,0xA8,0xCB,0x91,0x92,0xB1,0x7C,0x85,0xEC, - 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 a4c7a57f..934d1161 100644 --- a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c +++ b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.c @@ -266,15 +266,73 @@ static void test_sw_auth_cert(void) { CFReleaseNull(data1); } +static void test_component_type_cert(void) { + SecCertificateRef batteryCA = NULL, nonComponent = NULL; + isnt(batteryCA = SecCertificateCreateWithBytes(NULL, _componentCABattery, sizeof(_componentCABattery)), + NULL, "create battery component CA cert"); + isnt(nonComponent = SecCertificateCreateWithBytes(NULL, _iAP2CA, sizeof(_iAP2CA)), + NULL, "create non-component cert"); + + CFStringRef componentType = NULL; + isnt(componentType = SecCertificateCopyComponentType(batteryCA), NULL, "Get component type"); + ok(CFEqual(componentType, CFSTR("Battery")), "Got correct component type"); + CFReleaseNull(componentType); + + is(componentType = SecCertificateCopyComponentType(nonComponent), NULL, "Get component type"); + + CFReleaseNull(batteryCA); + CFReleaseNull(nonComponent); +} + +static void test_component_type_trust(void) { + SecCertificateRef leaf = NULL, subCA = NULL, root = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFMutableArrayRef certs = NULL; + CFArrayRef anchors = NULL; + CFDateRef date = NULL; + SecTrustResultType trustResult; + + isnt(leaf = SecCertificateCreateWithBytes(NULL, _batteryLeaf, sizeof(_batteryLeaf)), + NULL, "create battery leaf"); + isnt(subCA = SecCertificateCreateWithBytes(NULL, _componentCABattery, sizeof(_componentCABattery)), + NULL, "create battery subCA"); + isnt(root = SecCertificateCreateWithBytes(NULL, _componentRoot, sizeof(_componentRoot)), + NULL, "create component root"); + + /* Test Battery component certs meet component policy */ + certs = CFArrayCreateMutable(NULL, 2, &kCFTypeArrayCallBacks); + CFArrayAppendValue(certs, leaf); + CFArrayAppendValue(certs, subCA); + anchors = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks); + policy = SecPolicyCreateAppleComponentCertificate(NULL); + require_noerr(SecTrustCreateWithCertificates(certs, policy, &trust), trustFail); + require_noerr(SecTrustSetAnchorCertificates(trust, anchors), trustFail); + require(date = CFDateCreate(NULL, 576000000.0), trustFail); /* April 3, 2019 at 9:00:00 AM PDT */ + require_noerr(SecTrustSetVerifyDate(trust, date), trustFail); + require_noerr(SecTrustEvaluate(trust, &trustResult), trustFail); + is_status(trustResult, kSecTrustResultUnspecified, "trust is kSecTrustResultUnspecified"); + +trustFail: + CFReleaseNull(leaf); + CFReleaseNull(subCA); + CFReleaseNull(root); + CFReleaseNull(date); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + int si_22_sectrust_iap(int argc, char *const *argv) { - plan_tests(14+21+5+13); + plan_tests(14+21+5+13+5+4); test_v1(); test_v3(); test_sw_auth_trust(); test_sw_auth_cert(); + test_component_type_cert(); + test_component_type_trust(); 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 3a1cf060..1589d431 100644 --- a/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.h +++ b/OSX/sec/Security/Regressions/secitem/si-22-sectrust-iap.h @@ -346,7 +346,7 @@ const uint8_t _v3ca[618]={ /* subject:/C=US/O=Apple Inc./OU=Apple Accessories/CN=IPA_019256C98E8DCE6074DEE81A0002A756 */ /* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000000 */ -unsigned char _v3leaf[558]={ +const unsigned char _v3leaf[558]={ 0x30,0x82,0x02,0x2A,0x30,0x82,0x01,0xD1,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, 0x92,0x56,0xC9,0x8E,0x8D,0xCE,0x60,0x74,0xDE,0xE8,0x1A,0x00,0x02,0xA7,0x56,0x30, 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x89,0x31,0x0B, @@ -386,7 +386,7 @@ unsigned char _v3leaf[558]={ /* subject:/C=US/O=Apple Inc./OU=Apple Accessories/CN=IPA_204E6F2CB683A518F7726D190000C5DA */ /* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ -unsigned char _malformedV3Leaf[] = { +const unsigned char _malformedV3Leaf[] = { 0x30,0x82,0x02,0x2B,0x30,0x82,0x01,0xD1,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x20, 0x4E,0x6F,0x2C,0xB6,0x83,0xA5,0x18,0xF7,0x72,0x6D,0x19,0x00,0x00,0xC5,0xDA,0x30, 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x89,0x31,0x0B, @@ -426,7 +426,7 @@ unsigned char _malformedV3Leaf[] = { /* 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]={ +const 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, @@ -468,7 +468,7 @@ uint8_t _iAPSWAuthTestRoot[584]={ /* 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]={ +const 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, @@ -520,7 +520,7 @@ uint8_t _malformed_iAPSWAuth_leaf[739]={ /* 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]={ +const 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, @@ -569,4 +569,122 @@ uint8_t _iAPSWAuth_leaf[735]={ 0xFE,0x75,0x5E,0xB2,0xEF,0x34,0x2F,0x71,0x8B,0xCD,0xD2,0xF0,0x9F,0xF7,0x63, }; +/* subject:/CN=Component Root CA/O=Apple Inc./ST=California */ +/* issuer :/CN=Component Root CA/O=Apple Inc./ST=California */ +const uint8_t _componentRoot[] = { + 0x30,0x82,0x02,0x01,0x30,0x82,0x01,0x87,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x60, + 0x38,0x41,0xE4,0xE2,0xE9,0x38,0x31,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x03,0x03,0x30,0x46,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11, + 0x43,0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,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,0x30,0x1E,0x17,0x0D,0x31, + 0x38,0x31,0x32,0x31,0x39,0x31,0x39,0x33,0x31,0x35,0x34,0x5A,0x17,0x0D,0x34,0x33, + 0x31,0x32,0x31,0x36,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x46,0x31,0x1A,0x30, + 0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x43,0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E, + 0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,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,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, + 0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x98,0x15,0xB6,0x3A,0x39, + 0xC0,0xBA,0x4D,0xC6,0x27,0xE2,0xB1,0x74,0x1E,0x99,0x0B,0xEB,0x2D,0x37,0xC5,0x3F, + 0x20,0xA9,0x8E,0xB3,0xFC,0x42,0x2E,0x33,0x07,0x40,0x47,0xF1,0x27,0xEC,0x02,0xC4, + 0x46,0xEC,0x2F,0x3C,0xC0,0xF8,0xAE,0xD7,0x0C,0x95,0xA9,0x90,0x3C,0x39,0x8C,0xAD, + 0x2F,0x20,0x8F,0x57,0xD9,0x96,0x6C,0xAD,0x89,0x6D,0x2B,0x10,0x06,0x00,0x5E,0x1C, + 0xD3,0xC2,0xD0,0x3F,0xDC,0x4E,0x89,0x1A,0xCC,0x41,0xC4,0xC1,0x75,0x37,0xC6,0xCB, + 0xFB,0xA2,0x6C,0xB5,0xCE,0x90,0x77,0x1D,0xC7,0x2C,0x9C,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,0x90,0xD1,0x56,0xA9,0x3E, + 0xB4,0xEE,0x8C,0xD0,0x10,0x4B,0x9F,0x17,0x1C,0x5B,0x55,0xF2,0x12,0xF6,0x4C,0x30, + 0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x02,0x04,0x30, + 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03,0x03,0x68,0x00,0x30,0x65, + 0x02,0x31,0x00,0x9D,0x5A,0xE3,0x17,0xA8,0x56,0xB4,0x3C,0xB1,0x61,0x30,0x01,0xDC, + 0x03,0x3D,0xD4,0xEC,0xA4,0xAA,0xA4,0x2D,0xF9,0xE5,0x79,0x59,0x88,0xF7,0xE3,0xAC, + 0x3C,0xD0,0x68,0x76,0x79,0xCC,0x81,0x64,0xEC,0x34,0x2F,0x94,0x7D,0xF0,0x70,0x5D, + 0x65,0x8D,0xFC,0x02,0x30,0x71,0x6A,0x4F,0xE9,0x2E,0x38,0x87,0xDE,0x90,0x89,0x3B, + 0x1B,0x75,0xAD,0xED,0xE2,0x5C,0x53,0x75,0x71,0x1E,0x5A,0x2A,0xF2,0xD7,0x95,0xF7, + 0x32,0x1B,0xB6,0x0A,0x09,0x12,0x60,0x94,0xAE,0x55,0x2C,0xBE,0xCE,0x3F,0x4B,0xF4, + 0x4C,0x02,0xFB,0x9B,0x8C, +}; + +/* subject:/CN=Battery CA M1/OU=Component CA/O=Apple Inc./ST=California */ +/* issuer :/CN=Component Root CA/O=Apple Inc./ST=California */ +const uint8_t _componentCABattery[] = { + 0x30,0x82,0x02,0x36,0x30,0x82,0x01,0xBD,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x6A, + 0x22,0x01,0x3F,0xEB,0x2B,0x0D,0xA2,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x03,0x03,0x30,0x46,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x03,0x0C,0x11, + 0x43,0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,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,0x30,0x1E,0x17,0x0D,0x31, + 0x39,0x30,0x31,0x32,0x33,0x31,0x38,0x35,0x39,0x35,0x31,0x5A,0x17,0x0D,0x33,0x38, + 0x31,0x32,0x31,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x59,0x31,0x16,0x30, + 0x14,0x06,0x03,0x55,0x04,0x03,0x0C,0x0D,0x42,0x61,0x74,0x74,0x65,0x72,0x79,0x20, + 0x43,0x41,0x20,0x4D,0x31,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0C, + 0x43,0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x20,0x43,0x41,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,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,0xAF,0x9C,0xF2,0x4B,0x8C,0xBD,0xA3,0x47,0xDF,0xA6,0x18,0x58,0x11,0xA0,0xF9, + 0x54,0xEE,0x5C,0x1E,0xA6,0x49,0x6B,0x74,0x6E,0x79,0xB5,0x36,0x36,0xB6,0x44,0x04, + 0x91,0x0E,0x4C,0x15,0xBD,0x8B,0xA1,0x7D,0x61,0x28,0xB8,0x6A,0x0F,0xE4,0x4C,0x39, + 0x57,0x1B,0x72,0x5B,0xBE,0x5C,0x1D,0x88,0x87,0xBD,0x37,0x3A,0xBC,0x0C,0x10,0x69, + 0x12,0xA3,0x81,0x81,0x30,0x7F,0x30,0x12,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF, + 0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01,0x00,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xD1,0x56,0xA9,0x3E,0xB4,0xEE,0x8C,0xD0, + 0x10,0x4B,0x9F,0x17,0x1C,0x5B,0x55,0xF2,0x12,0xF6,0x4C,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x8C,0x3D,0xFA,0x31,0xF4,0x32,0x17,0x69,0x22,0xA3, + 0x4F,0x5F,0xC1,0x91,0x8E,0xF8,0x07,0xDA,0x84,0xD2,0x30,0x0E,0x06,0x03,0x55,0x1D, + 0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x19,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x63,0x64,0x0B,0x01,0x01,0x01,0xFF,0x04,0x09,0x16,0x07,0x42,0x61, + 0x74,0x74,0x65,0x72,0x79,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, + 0x03,0x03,0x67,0x00,0x30,0x64,0x02,0x30,0x6D,0x3D,0xD2,0x6F,0x08,0xEA,0xA3,0x4B, + 0xBD,0x62,0xFA,0x33,0xCC,0xE6,0xD7,0xD8,0x99,0xD7,0x5E,0x34,0x26,0x9B,0x7C,0x92, + 0x1D,0xF2,0x78,0x41,0xED,0x34,0x1E,0x38,0x56,0x27,0xB4,0x41,0xCE,0xBE,0xFC,0x64, + 0x0B,0x12,0x17,0x4D,0xE0,0x26,0xC6,0xCA,0x02,0x30,0x7A,0x0D,0xC5,0x67,0xA7,0x9D, + 0xA9,0xFA,0x72,0x66,0x8E,0xF8,0xAD,0x40,0x68,0xC4,0xDB,0xE4,0xDB,0x57,0xBF,0x10, + 0x86,0x60,0x14,0x5F,0x4F,0x50,0x01,0x66,0xDB,0x45,0x89,0x8D,0xBC,0x13,0xA8,0x33, + 0xA1,0x26,0xCB,0x84,0x3B,0x2B,0xDB,0xA3,0xE6,0x4E, +}; + +/* subject:/C=US/O=Apple Inc./OU=Components/CN=F5D91143R5LMCRH1P-6A2E0F00 */ +/* issuer :/CN=Battery CA M1/OU=Component CA/O=Apple Inc./ST=California */ +const uint8_t _batteryLeaf[] = { + 0x30,0x82,0x02,0x0E,0x30,0x82,0x01,0xB4,0xA0,0x03,0x02,0x01,0x02,0x02,0x0E,0x2D, + 0x95,0x4B,0x3A,0x9B,0x74,0x5C,0x9A,0xA6,0x8E,0x45,0xD6,0x99,0xC2,0x30,0x0A,0x06, + 0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x59,0x31,0x16,0x30,0x14,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x0D,0x42,0x61,0x74,0x74,0x65,0x72,0x79,0x20,0x43,0x41, + 0x20,0x4D,0x31,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0C,0x43,0x6F, + 0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x20,0x43,0x41,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,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x33,0x32,0x36,0x32,0x30, + 0x32,0x34,0x31,0x34,0x5A,0x17,0x0D,0x32,0x39,0x30,0x33,0x32,0x33,0x32,0x32,0x32, + 0x34,0x31,0x34,0x5A,0x30,0x5C,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04, + 0x0B,0x0C,0x0A,0x43,0x6F,0x6D,0x70,0x6F,0x6E,0x65,0x6E,0x74,0x73,0x31,0x23,0x30, + 0x21,0x06,0x03,0x55,0x04,0x03,0x0C,0x1A,0x46,0x35,0x44,0x39,0x31,0x31,0x34,0x33, + 0x52,0x35,0x4C,0x4D,0x43,0x52,0x48,0x31,0x50,0x2D,0x36,0x41,0x32,0x45,0x30,0x46, + 0x30,0x30,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,0xBB,0x20,0x19, + 0xBF,0x3F,0xDC,0x9A,0xA6,0x8F,0xEF,0x94,0x34,0x82,0x29,0x01,0xB3,0xA8,0xF4,0x47, + 0xFA,0x51,0xEC,0x77,0x68,0x1C,0xC1,0xF6,0xD1,0xFE,0x79,0xD0,0xCC,0xEC,0x2D,0xF7, + 0x8D,0xF6,0x07,0xD1,0xDE,0x13,0xF5,0x39,0x4B,0xBF,0xBF,0x11,0x81,0x7F,0x73,0x99, + 0x2A,0x6F,0x6C,0x88,0x2C,0xF7,0x4F,0xA9,0x8B,0x4C,0x72,0x3E,0x5D,0xA3,0x5D,0x30, + 0x5B,0x30,0x2E,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x11,0x04,0x21, + 0x0C,0x1F,0x36,0x38,0x3A,0x66,0x65,0x3A,0x66,0x37,0x3A,0x30,0x34,0x3A,0x62,0x35, + 0x3A,0x34,0x34,0x2F,0x31,0x37,0x32,0x2E,0x31,0x38,0x2E,0x32,0x37,0x2E,0x31,0x36, + 0x37,0x30,0x14,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x0B,0x01,0x04,0x07, + 0x42,0x61,0x74,0x74,0x65,0x72,0x79,0x30,0x13,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x63,0x64,0x0B,0x02,0x04,0x06,0x66,0x33,0x36,0x66,0x38,0x64,0x30,0x0A,0x06,0x08, + 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00, + 0xA1,0x7A,0xC9,0x6B,0xB1,0xC5,0x75,0x80,0x91,0x6C,0xBB,0xF3,0x39,0xC0,0xE1,0xFF, + 0x9C,0xA8,0x9E,0x3D,0xA6,0xA6,0x3A,0x57,0xCD,0x57,0x72,0xA6,0x4C,0x63,0xFD,0x43, + 0x02,0x20,0x33,0xB5,0x9E,0x7C,0x52,0x29,0xDD,0x9A,0xB8,0x10,0x34,0xB8,0x53,0xD4, + 0xAA,0x69,0x6B,0x4E,0xDF,0x69,0xA9,0x56,0x9F,0xBA,0xED,0x66,0xDA,0xD5,0x81,0x67, + 0xE0,0x3D, +}; + #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 fd88f613..95761683 100644 --- a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c +++ b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.c @@ -45,11 +45,11 @@ static void tests(void) CFRelease(ocspPolicy); ok_status(SecTrustCreateWithCertificates(certs, policies, &trust), "create trust"); - /* August 14, 2018 at 9:26:40 PM PDT */ - CFDateRef date = CFDateCreate(NULL, 556000000.0); + /* April 14, 2019 at 10:46:40 PM PDT */ + CFDateRef date = CFDateCreate(NULL, 577000000.0); ok_status(SecTrustSetVerifyDate(trust, date), "set date"); - is(SecTrustGetVerifyTime(trust), 556000000.0, "get date"); + is(SecTrustGetVerifyTime(trust), 577000000.0, "get date"); SecTrustResultType trustResult; ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); @@ -83,9 +83,9 @@ static void test_ocsp_responder_policy() { CFDateRef date = CFDateCreate(NULL, 556000000.0); isnt(leaf = SecCertificateCreateWithBytes(NULL, valid_ist_certificate, - sizeof(valid_ist_certificate)), NULL, "create ist leaf"); + sizeof(valid_ist_certificate)), NULL, "create ist leaf"); isnt(subCA = SecCertificateCreateWithBytes(NULL, ist_intermediate_certificate, - sizeof(ist_intermediate_certificate)), NULL, "create ist subCA"); + sizeof(ist_intermediate_certificate)), NULL, "create ist subCA"); CFArrayAppendValue(certs, leaf); CFArrayAppendValue(certs, subCA); @@ -766,6 +766,136 @@ errOut: CFReleaseNull(ocspResponse); } +static void test_results_dictionary_revocation_reason(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"); + +#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. */ + is(SecTrustEvaluateWithError(trust, &error), false, "revoked cert succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecCertificateRevoked, "got wrong error code for revoked cert, got %ld, expected %d", + (long)CFErrorGetCode(error), errSecCertificateRevoked); + + /* Verify that the results dictionary contains all the right keys for a revoked cert */ + CFDictionaryRef result = SecTrustCopyResult(trust); + isnt(result, NULL, "failed to copy result dictionary"); + if (result) { + int64_t reason = -1; + CFNumberRef cfreason = CFNumberCreate(NULL, kCFNumberSInt64Type, &reason); + is(CFNumberCompare(cfreason, CFDictionaryGetValue(result, kSecTrustRevocationReason), NULL), kCFCompareEqualTo, "expected revocation reason -1"); + CFReleaseNull(cfreason); + } + CFReleaseNull(result); + } 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 void test_results_dictionary_revocation_checked(void) { + SecCertificateRef leaf = NULL, subCA = NULL, root = NULL; + SecPolicyRef sslPolicy = NULL, ocspPolicy = NULL; + SecTrustRef trust = NULL; + CFArrayRef certs = NULL, anchors = NULL, policies = NULL; + CFDateRef verifyDate = NULL; + CFErrorRef error = NULL; + + leaf = SecCertificateCreateWithBytes(NULL, _ocsp_c0, sizeof(_ocsp_c0)); + subCA = SecCertificateCreateWithBytes(NULL, _ocsp_c1, sizeof(_ocsp_c1)); + root = SecCertificateCreateWithBytes(NULL, _ocsp_c2, sizeof(_ocsp_c2)); + + sslPolicy = SecPolicyCreateSSL(true, CFSTR("www.apple.com")); + ocspPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod); + + const void *v_certs[] = { leaf, subCA }; + const void *v_anchors[] = { root }; + const void *v_policies[] = { sslPolicy, ocspPolicy }; + + certs = CFArrayCreate(NULL, v_certs, 2, &kCFTypeArrayCallBacks); + policies = CFArrayCreate(NULL, v_policies, 2, &kCFTypeArrayCallBacks); + require_noerr_action(SecTrustCreateWithCertificates(certs, policies, &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, 577000000.0); // April 14, 2019 at 10:46:40 PM PDT + require_noerr_action(SecTrustSetVerifyDate(trust, verifyDate), errOut, fail("failed to set verify date")); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability-new" + is(SecTrustEvaluateWithError(trust, &error), true, "valid cert failed"); + + /* Verify that the results dictionary contains all the right keys for a valid cert where revocation checked */ + CFDictionaryRef result = SecTrustCopyResult(trust); + isnt(result, NULL, "failed to copy result dictionary"); + if (result) { + is(CFDictionaryGetValue(result, kSecTrustRevocationChecked), kCFBooleanTrue, "expected revocation checked flag"); + CFDateRef validUntil = CFDictionaryGetValue(result, kSecTrustRevocationValidUntilDate); + isnt(validUntil, NULL, "expected revocation valid until date"); + if (validUntil) { + ok(CFDateGetAbsoluteTime(validUntil) > CFAbsoluteTimeGetCurrent(), "expected valid until date in the future"); + } else { + fail("did not get valid until date"); + } + } + CFReleaseNull(result); +#pragma clang diagnostic pop + +errOut: + CFReleaseNull(leaf); + CFReleaseNull(subCA); + CFReleaseNull(root); + CFReleaseNull(ocspPolicy); + CFReleaseNull(sslPolicy); + CFReleaseNull(trust); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(policies); + CFReleaseNull(verifyDate); + CFReleaseNull(error); +} + static int ping_host(char *host_name){ struct sockaddr_in pin; @@ -818,7 +948,7 @@ int si_23_sectrust_ocsp(int argc, char *const *argv) unsigned host_cnt = 0; - plan_tests(95); + plan_tests(105); for (host_cnt = 0; host_cnt < sizeof(hosts)/sizeof(hosts[0]); host_cnt ++) { if(!ping_host(hosts[host_cnt])) { @@ -837,6 +967,8 @@ int si_23_sectrust_ocsp(int argc, char *const *argv) test_check_if_trusted(); test_cache(); test_stapled_revoked_response(); + test_results_dictionary_revocation_reason(); + test_results_dictionary_revocation_checked(); 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 index 14c314b4..cc78fcf5 100644 --- a/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.h +++ b/OSX/sec/Security/Regressions/secitem/si-23-sectrust-ocsp.h @@ -28,8 +28,8 @@ /* subject:/businessCategory=Private Organization/jurisdictionCountryName=US/jurisdictionStateOrProvinceName=California/serialNumber=C0806592/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Internet Services for Akamai/CN=www.apple.com */ /* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA */ static const uint8_t _ocsp_c0[]={ - 0x30,0x82,0x06,0xF0,0x30,0x82,0x05,0xD8,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x05, - 0x43,0xF9,0xBA,0x21,0xAD,0xC4,0x65,0x39,0x19,0x20,0x14,0xC9,0x77,0x24,0xD1,0x30, + 0x30,0x82,0x06,0xF1,0x30,0x82,0x05,0xD9,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0F, + 0x8E,0x4E,0x4C,0x9C,0xF5,0x5E,0xA5,0xFE,0x2E,0x9B,0x2B,0x7E,0xFF,0xDE,0x8F,0x30, 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x75, 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, @@ -38,8 +38,8 @@ static const uint8_t _ocsp_c0[]={ 0x34,0x30,0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65, 0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64, 0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76, - 0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x35,0x30,0x39,0x30, - 0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x33,0x32,0x35,0x31,0x32, + 0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x33,0x30,0x37,0x30, + 0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x30,0x30,0x33,0x30,0x37,0x31,0x32, 0x30,0x30,0x30,0x30,0x5A,0x30,0x81,0xEE,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04, 0x0F,0x0C,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72,0x67,0x61,0x6E, 0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x13,0x30,0x11,0x06,0x0B,0x2B,0x06,0x01, @@ -57,30 +57,30 @@ static const uint8_t _ocsp_c0[]={ 0x30,0x14,0x06,0x03,0x55,0x04,0x03,0x13,0x0D,0x77,0x77,0x77,0x2E,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,0xC0,0x14,0x0E,0x40,0xB0,0xFB,0x3A,0xB4,0x6D, - 0x4A,0xA6,0x24,0xCC,0x18,0x79,0x74,0x11,0x88,0x85,0x12,0x79,0xFF,0xA2,0x15,0xA1, - 0x05,0x43,0xF0,0xC2,0x1E,0xAC,0x3C,0xE2,0x26,0x3A,0x05,0x40,0x96,0xAD,0x48,0x59, - 0x04,0x06,0x0C,0x76,0x84,0x50,0xF7,0x94,0x5C,0xF0,0xD8,0xAE,0xEA,0xFE,0x0B,0xE0, - 0x4A,0xBB,0x58,0x08,0x12,0x99,0x9F,0xB7,0x31,0xB2,0xFC,0xF7,0x2C,0x63,0x3E,0x92, - 0xF0,0x10,0xF5,0x88,0x3C,0x65,0x27,0x42,0x0E,0x5F,0xBB,0x7E,0x5F,0xC5,0x94,0x1C, - 0x7D,0x56,0xA3,0xB4,0x50,0x2F,0x45,0x45,0x40,0xA1,0xAF,0x11,0x47,0x63,0x64,0x8C, - 0xFC,0xAB,0xE7,0x13,0x39,0xAD,0xDD,0x1B,0x3C,0x50,0x11,0x56,0x0F,0x26,0x33,0x94, - 0x9F,0xF4,0x97,0x25,0xCE,0xBA,0x42,0x16,0xC2,0xB2,0x10,0xC3,0x14,0xD1,0x14,0x15, - 0x1F,0x32,0x17,0x00,0x6C,0x24,0x65,0x26,0x36,0xA7,0xEE,0xC2,0x52,0xD3,0xD2,0xB0, - 0xA6,0xCD,0x56,0x47,0x71,0xF5,0xEC,0xE3,0xCE,0xA2,0x0A,0xC5,0xAF,0xD6,0x5B,0x15, - 0xD9,0x52,0xE3,0x17,0x85,0x98,0x7D,0xEF,0x52,0xC2,0x09,0x82,0x75,0x36,0xAE,0x2C, - 0x6D,0xD4,0xC3,0x8A,0x85,0x12,0x1F,0x79,0x1E,0xAB,0x1E,0xCC,0xBA,0x3D,0x6E,0x99, - 0x41,0x95,0x20,0x8F,0xF2,0x56,0xF8,0x7A,0x53,0x07,0xC9,0x02,0x97,0x77,0x5E,0x62, - 0x19,0xB4,0xAA,0xF6,0xEB,0x68,0xB1,0x20,0x4F,0x55,0x1F,0x46,0x67,0xF0,0xCF,0xEF, - 0xAD,0xE9,0x6E,0x4A,0x57,0xB1,0x23,0xF2,0xB7,0xB6,0xEB,0xD4,0xCC,0x9C,0x82,0xE7, - 0xAB,0xC6,0x25,0xA4,0x7B,0x48,0x8D,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x00, - 0x30,0x82,0x02,0xFC,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, + 0x01,0x0A,0x02,0x82,0x01,0x01,0x00,0xED,0x5E,0x5D,0xC6,0x85,0xBE,0xE5,0x2A,0x78, + 0x7A,0x1F,0x77,0x1F,0x42,0x17,0xEA,0xC1,0xE3,0x75,0xAE,0xC9,0x38,0x7A,0xE0,0xCF, + 0x9F,0xEB,0xBA,0x47,0x42,0xCF,0x63,0x75,0x26,0xD3,0x4C,0x8E,0x6C,0x2F,0xC7,0xBC, + 0x1C,0xBB,0x37,0xC9,0xA5,0xA0,0xD3,0x8F,0xEA,0x3D,0x02,0xC8,0xE8,0x06,0xA1,0xA7, + 0x2B,0x4C,0x7B,0x91,0x55,0xBC,0x51,0xAB,0xE7,0xC8,0xB8,0xA8,0xA6,0x49,0x3E,0x94, + 0x45,0xF1,0x00,0x90,0x26,0xB9,0xB5,0xAF,0xB5,0xA0,0x22,0x41,0x2C,0x10,0x52,0x8B, + 0xD9,0xF0,0x91,0xE5,0x40,0x76,0x60,0xFD,0xC2,0xB1,0xFE,0xD0,0x55,0xC3,0x4F,0x18, + 0x7D,0x20,0x00,0x0C,0x8B,0x41,0x2C,0x2D,0xC1,0x0A,0xC0,0xE1,0x2E,0xDE,0xF8,0x47, + 0x84,0xB2,0x36,0x4E,0x03,0x5F,0x77,0x90,0xF6,0xF5,0x60,0xD8,0xAA,0x25,0x10,0xEB, + 0x37,0x38,0x03,0x7F,0x4B,0x46,0x36,0x76,0x2E,0x66,0xFE,0x18,0xE4,0x9B,0x31,0xEC, + 0xD5,0x2A,0xDB,0x60,0x90,0xD7,0xA0,0xD5,0xAB,0x79,0x9C,0x01,0xF6,0xAC,0x87,0x88, + 0x73,0x43,0x08,0xE0,0x48,0xF0,0x09,0xAC,0x41,0x40,0x60,0xE4,0x9C,0xA7,0xCC,0xBD, + 0x2F,0xC7,0x5D,0x32,0x32,0x2E,0x42,0xD7,0x69,0x2F,0x46,0x30,0xD3,0x6E,0x17,0xBA, + 0x1C,0xA6,0xBA,0xBC,0xB5,0x62,0x53,0x89,0xC7,0x4A,0xEF,0xB9,0xF8,0x0F,0x25,0x2F, + 0xB4,0x7A,0x5C,0x05,0xFB,0xE4,0xFD,0x13,0x47,0x1B,0xFF,0x60,0x6F,0x40,0xF2,0x0F, + 0x2D,0x53,0x38,0x3F,0x21,0x87,0x4D,0x08,0xB1,0x1B,0xD3,0xDA,0xAB,0xD5,0x9E,0x94, + 0x69,0x43,0xA3,0xA2,0x5E,0xF1,0xE9,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x03,0x01, + 0x30,0x82,0x02,0xFD,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, 0x14,0x3D,0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65,0xD3,0x21, 0xD4,0xF8,0xF8,0xD6,0x0F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14, - 0xC9,0xBC,0xFC,0x9B,0x14,0x87,0xFE,0xE9,0xC1,0x53,0x82,0xA7,0xE4,0x4F,0xD1,0x74, - 0xC2,0xA5,0x79,0x13,0x30,0x2A,0x06,0x03,0x55,0x1D,0x11,0x04,0x23,0x30,0x21,0x82, - 0x0D,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D,0x82,0x10, - 0x69,0x6D,0x61,0x67,0x65,0x73,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F,0x6D, + 0xD8,0xF5,0xFF,0x6D,0xDC,0x96,0x30,0x5C,0xAD,0x80,0x75,0xFF,0xCE,0xC5,0xF7,0x9D, + 0x16,0x73,0xCB,0x16,0x30,0x2A,0x06,0x03,0x55,0x1D,0x11,0x04,0x23,0x30,0x21,0x82, + 0x10,0x69,0x6D,0x61,0x67,0x65,0x73,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63,0x6F, + 0x6D,0x82,0x0D,0x77,0x77,0x77,0x2E,0x61,0x70,0x70,0x6C,0x65,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, @@ -105,41 +105,41 @@ static const uint8_t _ocsp_c0[]={ 0x63,0x6F,0x6D,0x2F,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x53,0x48,0x41,0x32, 0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69, 0x6F,0x6E,0x53,0x65,0x72,0x76,0x65,0x72,0x43,0x41,0x2E,0x63,0x72,0x74,0x30,0x09, - 0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x82,0x01,0x03,0x06,0x0A,0x2B, - 0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,0x04,0x81,0xF4,0x04,0x81,0xF1,0x00, - 0xEF,0x00,0x76,0x00,0xBB,0xD9,0xDF,0xBC,0x1F,0x8A,0x71,0xB5,0x93,0x94,0x23,0x97, + 0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00,0x30,0x82,0x01,0x04,0x06,0x0A,0x2B, + 0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02,0x04,0x81,0xF5,0x04,0x81,0xF2,0x00, + 0xF0,0x00,0x76,0x00,0xBB,0xD9,0xDF,0xBC,0x1F,0x8A,0x71,0xB5,0x93,0x94,0x23,0x97, 0xAA,0x92,0x7B,0x47,0x38,0x57,0x95,0x0A,0xAB,0x52,0xE8,0x1A,0x90,0x96,0x64,0x36, - 0x8E,0x1E,0xD1,0x85,0x00,0x00,0x01,0x63,0x46,0x25,0xD6,0x3A,0x00,0x00,0x04,0x03, - 0x00,0x47,0x30,0x45,0x02,0x21,0x00,0xCD,0x06,0x70,0xA1,0x82,0x9D,0x94,0x7C,0xFD, - 0xBA,0x24,0xF6,0xD1,0x32,0x3C,0x0E,0x6B,0x08,0x27,0xD7,0x40,0xF1,0x3D,0x69,0x0D, - 0x97,0x67,0x94,0xFC,0xC8,0x04,0x9A,0x02,0x20,0x29,0xEB,0x04,0x1E,0xEB,0xB0,0x8A, - 0x4B,0xE0,0xA6,0xCF,0x95,0xCD,0x05,0x74,0x7F,0x18,0xD8,0x6B,0x76,0xE2,0xC2,0x45, - 0x45,0x66,0x1E,0x40,0xEF,0xFB,0xEF,0x89,0x1F,0x00,0x75,0x00,0x56,0x14,0x06,0x9A, + 0x8E,0x1E,0xD1,0x85,0x00,0x00,0x01,0x69,0x58,0x42,0xD1,0x06,0x00,0x00,0x04,0x03, + 0x00,0x47,0x30,0x45,0x02,0x20,0x68,0x81,0x0C,0x54,0x88,0x45,0x7A,0xC6,0x84,0xB8, + 0x65,0x9B,0xFD,0x9C,0x34,0x80,0xF6,0x38,0x91,0xEF,0xCF,0x58,0xF9,0xFD,0xF3,0x50, + 0x6F,0xAD,0x8E,0xA0,0xAD,0xE8,0x02,0x21,0x00,0xCE,0x32,0x9D,0x5B,0x3D,0xA2,0x8B, + 0xB6,0x04,0x48,0xEE,0x01,0x26,0x6C,0xD3,0x50,0xA1,0xEA,0x7F,0x25,0x0C,0x00,0x2A, + 0x42,0x6D,0x42,0x0D,0x13,0xC0,0xA9,0x85,0xBC,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,0x63, - 0x46,0x25,0xD5,0xC3,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x0B,0x27, - 0x52,0x85,0x46,0x02,0x37,0x41,0x10,0x05,0x4E,0x0E,0xD4,0x99,0x0A,0x38,0x93,0xFD, - 0xFE,0xCB,0x93,0xD2,0x73,0x6D,0x19,0x45,0x4D,0x91,0x1C,0xDA,0xFB,0x59,0x02,0x20, - 0x64,0xCD,0x18,0x8D,0xA4,0x20,0xEE,0x9A,0x61,0xE0,0x5E,0x42,0x3E,0x0F,0xA9,0x22, - 0x16,0x24,0xE4,0xD8,0xB0,0x6F,0x5F,0xFC,0xA3,0x0F,0xA7,0x45,0xFA,0xC1,0xB8,0x3F, - 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, - 0x82,0x01,0x01,0x00,0x04,0x71,0x4E,0x20,0xBF,0xD1,0x77,0x37,0x21,0x1E,0x02,0x82, - 0x70,0x87,0xA1,0x94,0xA0,0xF9,0x65,0xCE,0xE6,0x2A,0xC5,0x07,0xDF,0x1F,0xE4,0x0E, - 0x8B,0xB2,0x0A,0xD4,0xB9,0x3C,0x12,0x70,0x35,0xA2,0xF9,0xF9,0x0B,0x12,0x7E,0x4E, - 0xEE,0x18,0x2E,0x36,0xF2,0x3E,0x46,0x09,0xC5,0x4A,0x8C,0xBA,0xCA,0x5D,0xD7,0x72, - 0x06,0x6C,0x39,0xF8,0x6B,0x62,0x76,0x1A,0xC1,0xB3,0xA3,0x07,0xB2,0x5C,0x88,0xA1, - 0xA9,0x7D,0x77,0x11,0x9D,0x69,0x4D,0xBC,0x81,0xB6,0xA2,0x18,0x53,0x67,0xBA,0x7D, - 0xD0,0xFC,0xD1,0xBB,0x28,0x7B,0xBC,0x83,0x17,0x96,0x8B,0x1E,0xFF,0x17,0x36,0x72, - 0xC9,0x60,0xB7,0x19,0xE7,0xDC,0xF5,0x25,0x48,0x33,0x60,0xB1,0xFE,0x1A,0x92,0x8B, - 0xF5,0x84,0xE0,0xD8,0xDC,0x33,0x7F,0xD7,0x8F,0x56,0xDB,0x11,0x31,0xA5,0xAD,0x38, - 0xA0,0x8B,0x40,0x21,0xFA,0x64,0x7A,0xCA,0x44,0xF0,0xD8,0x39,0x38,0x10,0xDC,0x3D, - 0x35,0x0E,0x1E,0x01,0x49,0xDC,0xE9,0xA2,0x3C,0xD0,0x0D,0xFD,0x69,0x93,0x83,0x9E, - 0x80,0xCD,0xEE,0x0C,0x6B,0x2E,0xF1,0x27,0xFD,0x09,0xC0,0x44,0x0B,0xA9,0x7D,0xE6, - 0x24,0xA1,0x32,0xC4,0xAD,0xB9,0x25,0xC5,0x00,0xB8,0x1E,0x8A,0xFA,0x03,0x58,0xEA, - 0x02,0xE6,0x03,0x17,0xFA,0x4B,0xBE,0x74,0x1A,0x8E,0xBF,0xC5,0xC3,0xBD,0x89,0x5E, - 0x76,0xE3,0x7E,0x6B,0x2B,0x06,0x7E,0xA3,0xEC,0x12,0x39,0x90,0x7E,0xC1,0x00,0x51, - 0xA8,0x64,0x00,0x57,0x9B,0x27,0xD9,0x91,0x5F,0x75,0x53,0xDC,0x24,0x0C,0xD3,0x55, - 0x62,0x3A,0x5F,0xD1, + 0x99,0x11,0x5C,0xC0,0xEF,0x94,0x98,0x55,0xD6,0x89,0xD0,0xDD,0x00,0x00,0x01,0x69, + 0x58,0x42,0xD1,0x44,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x20,0x4B,0xD4, + 0x64,0x52,0xD3,0x52,0xF0,0x3E,0xD8,0xD4,0x3D,0xC5,0x40,0x72,0xED,0xC3,0x04,0x8C, + 0x3C,0x16,0x46,0x5D,0x38,0x02,0xBA,0xA2,0x1E,0x52,0xAA,0xE1,0xDA,0xB6,0x02,0x21, + 0x00,0xA3,0x5E,0x2F,0x6B,0xCC,0xB9,0x34,0xD9,0xA4,0x00,0x70,0xE1,0x3A,0x99,0xB4, + 0x0D,0x25,0x6D,0xD3,0x59,0x77,0xC2,0x98,0x8C,0x6A,0xA0,0xAE,0xA7,0xE1,0x06,0x73, + 0x32,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, + 0x03,0x82,0x01,0x01,0x00,0x3F,0xD9,0xA1,0x19,0xB3,0x7C,0x56,0xA5,0x89,0xE5,0xA2, + 0x33,0x33,0xE3,0xFC,0xBB,0x29,0xDB,0xD7,0x69,0x76,0x31,0x2F,0x69,0x97,0x90,0xA1, + 0x0C,0x11,0x0B,0x5A,0xCB,0xAB,0x41,0x66,0xB2,0x9B,0xDF,0x71,0xD6,0xDC,0x92,0x91, + 0xB6,0x17,0x8B,0xD3,0x9C,0x83,0x3C,0xDC,0x7C,0xA7,0x29,0x5D,0xBA,0x38,0x97,0x9B, + 0x0D,0x07,0xE0,0x46,0xCA,0x27,0x5F,0x41,0xA0,0xC0,0x84,0x1E,0x47,0x00,0xDC,0x87, + 0x79,0xFD,0xAF,0x3E,0x34,0xC2,0x6D,0xB1,0x47,0x0C,0x52,0x14,0x81,0xAC,0xB2,0x6C, + 0xB4,0x30,0xB2,0x41,0x61,0x77,0x07,0x96,0x05,0x5B,0x26,0x36,0xA2,0x94,0xC2,0x70, + 0xC3,0xCD,0xC1,0x15,0xAC,0x33,0x0D,0x60,0x68,0xFA,0x19,0x95,0x3E,0x28,0x14,0xDE, + 0x19,0x15,0xF2,0x4B,0x43,0xAB,0x00,0xBF,0x54,0xE3,0xAF,0x5A,0x29,0x0F,0x32,0xCB, + 0xCC,0xBE,0x7F,0x07,0x30,0xF6,0xD9,0x49,0xE6,0x27,0x1F,0xC0,0x3B,0x9C,0x3D,0x2E, + 0xD1,0x6C,0xC5,0xB6,0x0E,0x8D,0x17,0xDC,0x48,0x5C,0x1F,0xC1,0x7E,0x4B,0xBA,0x8C, + 0x43,0xCA,0xAF,0x99,0x76,0x88,0x9B,0xA4,0x68,0x60,0xFA,0xC2,0xD3,0x87,0xEF,0x39, + 0x16,0x8C,0x49,0x36,0x2C,0x09,0xF9,0x07,0x2A,0x2E,0x7B,0x61,0x3E,0x76,0x76,0xEF, + 0x74,0x96,0xA5,0xAE,0xFF,0x6B,0x4C,0xF7,0x7F,0x96,0x41,0xBE,0x9C,0x09,0x41,0xBA, + 0x8A,0x1C,0xFD,0xC2,0x4A,0xE1,0x0A,0xA8,0x7E,0x7B,0xA8,0x98,0xA8,0x01,0x5D,0xAB, + 0xEF,0xDB,0x36,0xB3,0xE6,0x93,0x5D,0x27,0x0C,0x26,0xC3,0x33,0x93,0x74,0xAF,0x79, + 0x81,0xE5,0xD4,0x46,0x4E, }; /* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA */ @@ -223,6 +223,72 @@ static const uint8_t _ocsp_c1[]= { 0xF1,0x35,0x28,0x13,0xAB,0x26,0x7E,0xD5,0xF7,0x7A, }; +/* subject:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ +/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA */ +static const uint8_t _ocsp_c2[]= { + 0x30,0x82,0x03,0xC5,0x30,0x82,0x02,0xAD,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x02, + 0xAC,0x5C,0x26,0x6A,0x0B,0x40,0x9B,0x8F,0x0B,0x79,0xF2,0xAE,0x46,0x25,0x77,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x6C, + 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, + 0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63, + 0x65,0x20,0x45,0x56,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,0x6C,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,0x2B,0x30, + 0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63,0x65,0x20, + 0x45,0x56,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,0xC6,0xCC,0xE5,0x73,0xE6, + 0xFB,0xD4,0xBB,0xE5,0x2D,0x2D,0x32,0xA6,0xDF,0xE5,0x81,0x3F,0xC9,0xCD,0x25,0x49, + 0xB6,0x71,0x2A,0xC3,0xD5,0x94,0x34,0x67,0xA2,0x0A,0x1C,0xB0,0x5F,0x69,0xA6,0x40, + 0xB1,0xC4,0xB7,0xB2,0x8F,0xD0,0x98,0xA4,0xA9,0x41,0x59,0x3A,0xD3,0xDC,0x94,0xD6, + 0x3C,0xDB,0x74,0x38,0xA4,0x4A,0xCC,0x4D,0x25,0x82,0xF7,0x4A,0xA5,0x53,0x12,0x38, + 0xEE,0xF3,0x49,0x6D,0x71,0x91,0x7E,0x63,0xB6,0xAB,0xA6,0x5F,0xC3,0xA4,0x84,0xF8, + 0x4F,0x62,0x51,0xBE,0xF8,0xC5,0xEC,0xDB,0x38,0x92,0xE3,0x06,0xE5,0x08,0x91,0x0C, + 0xC4,0x28,0x41,0x55,0xFB,0xCB,0x5A,0x89,0x15,0x7E,0x71,0xE8,0x35,0xBF,0x4D,0x72, + 0x09,0x3D,0xBE,0x3A,0x38,0x50,0x5B,0x77,0x31,0x1B,0x8D,0xB3,0xC7,0x24,0x45,0x9A, + 0xA7,0xAC,0x6D,0x00,0x14,0x5A,0x04,0xB7,0xBA,0x13,0xEB,0x51,0x0A,0x98,0x41,0x41, + 0x22,0x4E,0x65,0x61,0x87,0x81,0x41,0x50,0xA6,0x79,0x5C,0x89,0xDE,0x19,0x4A,0x57, + 0xD5,0x2E,0xE6,0x5D,0x1C,0x53,0x2C,0x7E,0x98,0xCD,0x1A,0x06,0x16,0xA4,0x68,0x73, + 0xD0,0x34,0x04,0x13,0x5C,0xA1,0x71,0xD3,0x5A,0x7C,0x55,0xDB,0x5E,0x64,0xE1,0x37, + 0x87,0x30,0x56,0x04,0xE5,0x11,0xB4,0x29,0x80,0x12,0xF1,0x79,0x39,0x88,0xA2,0x02, + 0x11,0x7C,0x27,0x66,0xB7,0x88,0xB7,0x78,0xF2,0xCA,0x0A,0xA8,0x38,0xAB,0x0A,0x64, + 0xC2,0xBF,0x66,0x5D,0x95,0x84,0xC1,0xA1,0x25,0x1E,0x87,0x5D,0x1A,0x50,0x0B,0x20, + 0x12,0xCC,0x41,0xBB,0x6E,0x0B,0x51,0x38,0xB8,0x4B,0xCB,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, + 0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08,0x02,0xEF, + 0x63,0x64,0x2B,0xC3,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, + 0x14,0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08,0x02, + 0xEF,0x63,0x64,0x2B,0xC3,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, + 0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x1C,0x1A,0x06,0x97,0xDC,0xD7,0x9C, + 0x9F,0x3C,0x88,0x66,0x06,0x08,0x57,0x21,0xDB,0x21,0x47,0xF8,0x2A,0x67,0xAA,0xBF, + 0x18,0x32,0x76,0x40,0x10,0x57,0xC1,0x8A,0xF3,0x7A,0xD9,0x11,0x65,0x8E,0x35,0xFA, + 0x9E,0xFC,0x45,0xB5,0x9E,0xD9,0x4C,0x31,0x4B,0xB8,0x91,0xE8,0x43,0x2C,0x8E,0xB3, + 0x78,0xCE,0xDB,0xE3,0x53,0x79,0x71,0xD6,0xE5,0x21,0x94,0x01,0xDA,0x55,0x87,0x9A, + 0x24,0x64,0xF6,0x8A,0x66,0xCC,0xDE,0x9C,0x37,0xCD,0xA8,0x34,0xB1,0x69,0x9B,0x23, + 0xC8,0x9E,0x78,0x22,0x2B,0x70,0x43,0xE3,0x55,0x47,0x31,0x61,0x19,0xEF,0x58,0xC5, + 0x85,0x2F,0x4E,0x30,0xF6,0xA0,0x31,0x16,0x23,0xC8,0xE7,0xE2,0x65,0x16,0x33,0xCB, + 0xBF,0x1A,0x1B,0xA0,0x3D,0xF8,0xCA,0x5E,0x8B,0x31,0x8B,0x60,0x08,0x89,0x2D,0x0C, + 0x06,0x5C,0x52,0xB7,0xC4,0xF9,0x0A,0x98,0xD1,0x15,0x5F,0x9F,0x12,0xBE,0x7C,0x36, + 0x63,0x38,0xBD,0x44,0xA4,0x7F,0xE4,0x26,0x2B,0x0A,0xC4,0x97,0x69,0x0D,0xE9,0x8C, + 0xE2,0xC0,0x10,0x57,0xB8,0xC8,0x76,0x12,0x91,0x55,0xF2,0x48,0x69,0xD8,0xBC,0x2A, + 0x02,0x5B,0x0F,0x44,0xD4,0x20,0x31,0xDB,0xF4,0xBA,0x70,0x26,0x5D,0x90,0x60,0x9E, + 0xBC,0x4B,0x17,0x09,0x2F,0xB4,0xCB,0x1E,0x43,0x68,0xC9,0x07,0x27,0xC1,0xD2,0x5C, + 0xF7,0xEA,0x21,0xB9,0x68,0x12,0x9C,0x3C,0x9C,0xBF,0x9E,0xFC,0x80,0x5C,0x9B,0x63, + 0xCD,0xEC,0x47,0xAA,0x25,0x27,0x67,0xA0,0x37,0xF3,0x00,0x82,0x7D,0x54,0xD7,0xA9, + 0xF8,0xE9,0x2E,0x13,0xA3,0x77,0xE8,0x1F,0x4A, +}; + /* subject:/CN=Apple IST CA 2 OCSP Responder NL01/O=Apple Inc./C=US */ /* issuer :/CN=Apple IST CA 2 - G1/OU=Certification Authority/O=Apple Inc./C=US */ static const uint8_t _responderCert[]= { @@ -619,104 +685,6 @@ static unsigned char comodo_aia_certificate[1554]={ 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 valid_ist_certificate[] = { 0x30,0x82,0x08,0x51,0x30,0x82,0x07,0x39,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x3A, 0xFC,0x35,0x65,0x26,0x40,0x12,0xAF,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, @@ -854,6 +822,104 @@ static unsigned char valid_ist_certificate[] = { 0x2A,0xC5,0xEF,0x98,0xCF, }; +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, diff --git a/OSX/sec/Security/Regressions/secitem/si-24-sectrust-nist.c b/OSX/sec/Security/Regressions/secitem/si-24-sectrust-nist.c deleted file mode 100644 index c2ff1f1a..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-24-sectrust-nist.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2011-2012 Apple Inc. All Rights Reserved. - */ - -#include -#include - -#include - -#include "shared_regressions.h" - -static void tests(void) -{ - SecPolicyRef basicPolicy = SecPolicyCreateBasicX509(); - - /* Run the tests. */ - runCertificateTestForDirectory(basicPolicy, CFSTR("nist-certs"), NULL); - - CFReleaseSafe(basicPolicy); -} - -int si_24_sectrust_nist(int argc, char *const *argv) -{ - plan_tests(179); - - tests(); - - return 0; -} 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 7aa5ba2d..fffb493d 100644 --- a/OSX/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c +++ b/OSX/sec/Security/Regressions/secitem/si-27-sectrust-exceptions.c @@ -375,6 +375,36 @@ static void tests(void) ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); +#if TARGET_OS_IPHONE + /* Test the extenions epoch feature. */ + CFReleaseNull(exceptions); + CFReleaseNull(trust); + CFReleaseNull(policy); + policy = SecPolicyCreateSSL(false, CFSTR("self-signed.ssltest.apple.com")); + ok_status(SecTrustCreateWithCertificates(sscert0, policy, &trust), "create trust"); + ok(exceptions = SecTrustCopyExceptions(trust), "create exceptions"); + if (!exceptions) { goto errOut; } + + /* Test the uninitialized extensions epoch. */ + CFErrorRef exceptionResetCountError = NULL; + uint64_t exceptionResetCount = SecTrustGetExceptionResetCount(&exceptionResetCountError); + ok(exceptionResetCount == 0, "exception reset count is not set yet"); + ok(SecTrustSetExceptions(trust, exceptions), "set exceptions"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); + is_status(trustResult, kSecTrustResultProceed, "trust is kSecTrustResultProceed"); + + /* Test increasing the extensions epoch. */ + exceptionResetCountError = NULL; + ok_status(SecTrustIncrementExceptionResetCount(&exceptionResetCountError), "increase exception reset count"); + exceptionResetCountError = NULL; + is(SecTrustGetExceptionResetCount(&exceptionResetCountError), 1 + exceptionResetCount, "exception reset count is 1 + previous count"); + + /* Test trust evaluation under a future extensions epoch. */ + ok(!SecTrustSetExceptions(trust, exceptions), "set exceptions"); + ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); + is_status(trustResult, kSecTrustResultRecoverableTrustFailure, "trust is kSecTrustResultRecoverableTrustFailure"); +#endif + errOut: CFReleaseSafe(anchors); CFReleaseSafe(exceptions); @@ -389,8 +419,11 @@ errOut: int si_27_sectrust_exceptions(int argc, char *const *argv) { +#if TARGET_OS_IPHONE + plan_tests(62); +#else plan_tests(51); - +#endif tests(); diff --git a/OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.h b/OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.h new file mode 100644 index 00000000..049a41ae --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2019 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_29_CMS_CHAIN_MODE_H_ +#define _SECURITY_SI_29_CMS_CHAIN_MODE_H_ + +/* random content */ +uint8_t _chain_mode_content[] = { + 0x5a, 0x10, 0xd2, 0xf4, 0x38, 0xee, 0x12, 0xcb, 0x73, 0x9f, 0xc0, 0x64, 0xb4, 0x3d, 0xb4, 0x83, + 0xa9, 0x46, 0xe7, 0xba, 0x78, 0xb6, 0xbc, 0xfe, 0x85, 0x1a, 0x44, 0xf7, 0xbb, 0x06, 0x80, 0x94 +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CMS Chain Mode Test Root */ +uint8_t _chain_mode_root[] = { + 0x30,0x82,0x02,0x95,0x30,0x82,0x02,0x1B,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xD7,0xD8,0xE3,0x65,0x2C,0x72,0x09,0xDB,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x03,0x02,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,0x43,0x4D,0x53,0x20, + 0x43,0x68,0x61,0x69,0x6E,0x20,0x4D,0x6F,0x64,0x65,0x20,0x54,0x65,0x73,0x74,0x20, + 0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x38,0x30,0x38,0x32,0x31, + 0x34,0x35,0x32,0x33,0x5A,0x17,0x0D,0x32,0x39,0x30,0x38,0x30,0x35,0x32,0x31,0x34, + 0x35,0x32,0x33,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,0x43,0x4D,0x53,0x20, + 0x43,0x68,0x61,0x69,0x6E,0x20,0x4D,0x6F,0x64,0x65,0x20,0x54,0x65,0x73,0x74,0x20, + 0x52,0x6F,0x6F,0x74,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02, + 0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x2E,0xA9,0x02,0xE1, + 0x22,0x43,0x0C,0x90,0xF3,0x05,0xFD,0x4C,0x68,0xE0,0x0B,0xB6,0xE5,0x1E,0x6C,0xC5, + 0x66,0x30,0xEA,0xEF,0xB0,0x09,0xB4,0x2C,0x0F,0xB0,0x30,0x13,0x6C,0x58,0x33,0x0F, + 0x97,0xB8,0xB6,0x78,0x64,0xBB,0x92,0xC7,0x1E,0xED,0xBC,0x30,0xDE,0x4C,0xAC,0x4E, + 0xDC,0x50,0xF2,0xD2,0x60,0xBF,0xD4,0x85,0x7B,0x37,0x14,0xD9,0x3E,0x13,0x18,0x1B, + 0x8F,0xA5,0xF2,0xE0,0xE0,0x3E,0x72,0x8C,0x04,0x42,0x03,0xD7,0x9B,0x17,0xD6,0x98, + 0x27,0xC2,0x28,0x31,0x3B,0xEC,0x52,0x1F,0x5F,0xA1,0x34,0x5D,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,0x48, + 0xAA,0x9F,0xEC,0xE0,0xFF,0x26,0x75,0xC6,0xB5,0x96,0x2E,0x20,0x41,0x1A,0x04,0x3A, + 0xB2,0xDF,0x8A,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x03, + 0x68,0x00,0x30,0x65,0x02,0x31,0x00,0xD4,0xEA,0x83,0xCB,0xBD,0x64,0x82,0xB1,0xF1, + 0x37,0x27,0xBE,0xA8,0xA6,0x05,0x3A,0x86,0xB9,0x17,0xA3,0xCF,0x5B,0xEC,0xBD,0x58, + 0x5A,0xE2,0x9B,0x4D,0xE8,0x8C,0x9D,0xA3,0x5A,0xDF,0x3E,0x33,0xA4,0x6A,0x12,0x63, + 0xFA,0xDA,0xC1,0xEF,0x26,0xD3,0x18,0x02,0x30,0x0C,0x5C,0x26,0x90,0xE1,0x8B,0x30, + 0x27,0x22,0x34,0x96,0x7B,0x2A,0x6D,0x7F,0xFA,0xE2,0xFD,0x4C,0x7B,0x05,0x3C,0x76, + 0x76,0x82,0x78,0x47,0xE7,0x7F,0x32,0xAE,0xCC,0x09,0x22,0xB4,0x2B,0x1C,0x19,0x3E, + 0x61,0x54,0xC2,0xE2,0x2C,0xA6,0x00,0x42,0xED, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CMS Chain Mode Test SubCA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CMS Chain Mode Test Root */ +uint8_t _chain_mode_subca[] = { + 0x30,0x82,0x02,0xBC,0x30,0x82,0x02,0x43,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,0xC9,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,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,0x43,0x4D,0x53,0x20,0x43,0x68,0x61,0x69,0x6E,0x20,0x4D, + 0x6F,0x64,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17, + 0x0D,0x31,0x39,0x30,0x38,0x30,0x38,0x32,0x31,0x35,0x35,0x31,0x38,0x5A,0x17,0x0D, + 0x32,0x30,0x30,0x38,0x30,0x37,0x32,0x31,0x35,0x35,0x31,0x38,0x5A,0x30,0x81,0x8E, + 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,0x22,0x30,0x20,0x06,0x03, + 0x55,0x04,0x03,0x0C,0x19,0x43,0x4D,0x53,0x20,0x43,0x68,0x61,0x69,0x6E,0x20,0x4D, + 0x6F,0x64,0x65,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x30,0x76, + 0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04, + 0x00,0x22,0x03,0x62,0x00,0x04,0xB2,0x24,0x94,0x53,0xAD,0xD7,0x59,0xD9,0x3B,0xD9, + 0x09,0xF9,0xEB,0x00,0x85,0x30,0xDB,0x98,0xCA,0xEA,0x26,0xCE,0x64,0xB1,0xDC,0x61, + 0x1C,0x19,0xE3,0xC8,0xC9,0xB3,0x42,0xD1,0x04,0x08,0x94,0x69,0x79,0x93,0xD0,0x42, + 0x15,0xDA,0xA9,0xDF,0x30,0x2D,0xD3,0x3C,0x1A,0x8C,0x63,0x76,0xFE,0x4E,0xB4,0xB2, + 0x0E,0xE6,0x3E,0xA1,0x22,0xD8,0x34,0x53,0xC5,0x77,0x86,0xD6,0x04,0x1C,0xF0,0x2E, + 0x93,0x11,0xE0,0x0A,0x78,0x8E,0xD5,0x01,0x91,0xF9,0xD4,0x7C,0xBD,0x1E,0x86,0x19, + 0x2A,0x12,0x39,0x65,0xE2,0x3B,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x7F,0xF3,0x58,0xF2,0x27,0x8A,0x3D,0xA5,0x40,0x14, + 0xEA,0x88,0x6A,0xF6,0xAF,0x8F,0xA2,0x01,0x2F,0x0C,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x48,0xAA,0x9F,0xEC,0xE0,0xFF,0x26,0x75,0xC6, + 0xB5,0x96,0x2E,0x20,0x41,0x1A,0x04,0x3A,0xB2,0xDF,0x8A,0x30,0x09,0x06,0x07,0x2A, + 0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x68,0x00,0x30,0x65,0x02,0x31,0x00,0xC1,0x29, + 0x72,0xD0,0x09,0x23,0x07,0xFA,0xA6,0xDE,0x51,0xF6,0x27,0x56,0xCF,0xA1,0xD6,0xC7, + 0xA6,0xE8,0x63,0xD8,0xE6,0x8C,0xBE,0xD6,0xE8,0x98,0x3A,0xE9,0x82,0xD9,0x82,0x14, + 0xB7,0xE2,0x69,0xB5,0xAD,0x8A,0x6B,0xDB,0x15,0x15,0xCA,0x0B,0x05,0x6A,0x02,0x30, + 0x25,0xCD,0x12,0xEF,0x65,0x90,0x46,0xA5,0x06,0x35,0x2B,0x56,0xBF,0x46,0x10,0x1F, + 0x96,0x2F,0x9B,0xEE,0x2E,0x01,0x42,0xDB,0x6B,0xD4,0x67,0x78,0x4F,0xEC,0xCE,0x9A, + 0xEF,0x3E,0x4B,0x20,0x05,0x73,0xB9,0xDE,0x07,0x60,0xB8,0xCF,0x52,0xB1,0x52,0x8F, +}; + +/* + * password: "password" + * localKeyID: 8F 9D 45 BD AE 29 BC 28 92 9E 40 17 B3 BB D2 60 40 5F 63 7D + * subject=/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CMS Chain Mode Test Leaf + * issuer=/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CMS Chain Mode Test SubCA + */ +uint8_t _chain_mode_leaf_p12[] = { + 0x30, 0x82, 0x04, 0xb2, 0x02, 0x01, 0x03, 0x30, 0x82, 0x04, 0x78, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x04, 0x69, 0x04, 0x82, 0x04, 0x65, 0x30, 0x82, + 0x04, 0x61, 0x30, 0x82, 0x03, 0x57, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + 0x06, 0xa0, 0x82, 0x03, 0x48, 0x30, 0x82, 0x03, 0x44, 0x02, 0x01, 0x00, 0x30, 0x82, 0x03, 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, 0xbf, 0xb5, 0xd4, + 0xdd, 0x7d, 0xe9, 0x78, 0xc4, 0x02, 0x02, 0x08, 0x00, 0x80, 0x82, 0x03, 0x10, 0x22, 0xb2, 0x56, + 0xef, 0x90, 0x96, 0x39, 0x78, 0xbb, 0x0b, 0x19, 0xbc, 0x94, 0xa4, 0x85, 0x69, 0x8a, 0x3c, 0x9e, + 0x72, 0xa4, 0x4b, 0xcd, 0x7c, 0x03, 0xe8, 0x16, 0x7c, 0x12, 0xc9, 0x0f, 0x5a, 0x94, 0x61, 0xd6, + 0x63, 0xbe, 0x32, 0x63, 0x4e, 0xe0, 0x32, 0x82, 0xf6, 0x0f, 0x23, 0x01, 0x86, 0x26, 0x0d, 0x27, + 0xf9, 0x60, 0x27, 0x7b, 0xc7, 0xbe, 0xd8, 0x26, 0x4d, 0xdf, 0x4e, 0x95, 0x3f, 0xb5, 0xb9, 0x12, + 0x92, 0x25, 0x44, 0x26, 0x2b, 0xa5, 0xf9, 0x29, 0xc6, 0x99, 0x05, 0x77, 0x79, 0xd1, 0xb7, 0x5a, + 0xa4, 0x7d, 0x6d, 0xeb, 0xc2, 0xf9, 0xa2, 0xbc, 0xf8, 0x70, 0x6f, 0x03, 0x69, 0x1a, 0x6d, 0x06, + 0xbf, 0x33, 0x0f, 0xe2, 0xc7, 0xcd, 0xf0, 0xfe, 0x97, 0x58, 0xbe, 0x8d, 0x9e, 0xe1, 0x00, 0x5b, + 0xb0, 0x4c, 0x0e, 0xbb, 0x7e, 0x20, 0x3c, 0x23, 0xf7, 0x7c, 0x6e, 0xe7, 0xaf, 0x2c, 0x30, 0xcf, + 0x45, 0xb2, 0x1b, 0xaa, 0x3b, 0x8c, 0xd5, 0xdf, 0x0a, 0xd3, 0x1b, 0x09, 0xd2, 0x52, 0xca, 0xcc, + 0x1b, 0xdc, 0x62, 0x17, 0x57, 0xa8, 0x95, 0xf0, 0x47, 0xb1, 0xfc, 0x64, 0xd4, 0x14, 0xf8, 0x5c, + 0xb0, 0xed, 0x3c, 0x52, 0x96, 0xf1, 0x93, 0x78, 0x6c, 0x2d, 0x6d, 0xf3, 0x39, 0x1b, 0x4c, 0x25, + 0x3c, 0x2f, 0x80, 0x74, 0x4b, 0x17, 0xea, 0x0b, 0xe9, 0x1b, 0xdd, 0x95, 0xfa, 0xad, 0xa7, 0x99, + 0x54, 0x96, 0xbe, 0x7a, 0xdc, 0x46, 0xe6, 0xdf, 0xa9, 0x07, 0x8d, 0x62, 0xe8, 0x9b, 0x7d, 0xcc, + 0x33, 0x59, 0x90, 0x11, 0x64, 0x9d, 0x83, 0x10, 0x67, 0xdb, 0x7a, 0x7a, 0x65, 0x0f, 0x26, 0x81, + 0x4d, 0xd0, 0x6c, 0x8a, 0x79, 0xf6, 0xe5, 0x8a, 0x9b, 0xdd, 0xd3, 0x2f, 0x31, 0xcb, 0x7f, 0xf3, + 0xfc, 0xae, 0x84, 0xa4, 0xe0, 0x4c, 0x97, 0x54, 0xee, 0x35, 0x8a, 0xc5, 0x8a, 0xc9, 0x25, 0x68, + 0x8b, 0x7d, 0xe5, 0x32, 0x35, 0xc0, 0xe1, 0x50, 0x42, 0xb5, 0xb8, 0x5c, 0xdc, 0xa6, 0x56, 0x8f, + 0x7a, 0xd0, 0x12, 0xf4, 0x1e, 0x05, 0xce, 0x3a, 0x88, 0x96, 0x18, 0xd8, 0x99, 0x21, 0x67, 0x62, + 0x85, 0x69, 0x6e, 0x3d, 0x76, 0x19, 0xe1, 0x96, 0x4e, 0x3b, 0xc5, 0x9c, 0x5a, 0xc2, 0x43, 0x07, + 0x6b, 0xab, 0x09, 0x90, 0xe7, 0xc3, 0x8a, 0xd7, 0x62, 0x37, 0xba, 0x61, 0xfe, 0x5b, 0xee, 0x98, + 0x4f, 0x4e, 0x0e, 0x6a, 0x34, 0xa4, 0xe1, 0xd3, 0x93, 0xbd, 0xc5, 0x68, 0x0b, 0xcb, 0x23, 0x35, + 0x72, 0xdc, 0x6d, 0x90, 0xa9, 0x0e, 0xd6, 0xd9, 0xf9, 0xe8, 0x7a, 0x21, 0x2b, 0xdd, 0xd8, 0x9a, + 0x1d, 0xad, 0x18, 0xe9, 0xb3, 0x8c, 0x45, 0x94, 0x52, 0x81, 0xa5, 0x65, 0x81, 0xee, 0xa8, 0x17, + 0x9a, 0x95, 0xd6, 0x5c, 0x29, 0x69, 0x71, 0xea, 0x55, 0x67, 0x93, 0x4d, 0xfe, 0x3f, 0x7b, 0xb2, + 0x60, 0x74, 0x9d, 0x4c, 0x34, 0x22, 0x25, 0x97, 0x68, 0x77, 0xa0, 0x11, 0xef, 0x7f, 0xf6, 0x85, + 0x4e, 0x94, 0x9f, 0xe3, 0x83, 0x89, 0x7f, 0x4d, 0x86, 0x95, 0xc7, 0x8c, 0xcb, 0x52, 0x65, 0x79, + 0xcc, 0x40, 0xab, 0x33, 0x60, 0x04, 0x85, 0x62, 0x6f, 0xb2, 0xac, 0xbf, 0x8f, 0xed, 0x79, 0x6e, + 0x9e, 0x24, 0xf3, 0x20, 0xc1, 0x77, 0x3d, 0x9f, 0x33, 0x60, 0xf1, 0x4d, 0x70, 0x4b, 0x2b, 0x11, + 0x17, 0x7b, 0x84, 0x15, 0x8d, 0xa0, 0x6b, 0xeb, 0x73, 0x0a, 0xdc, 0xb7, 0x9d, 0xea, 0x63, 0x43, + 0x0c, 0x08, 0xc3, 0xbe, 0xe6, 0xf6, 0x1a, 0xb4, 0xbf, 0x23, 0xbd, 0x40, 0xf5, 0xa6, 0x89, 0xbb, + 0x76, 0x13, 0xc5, 0xd2, 0xe9, 0xb2, 0x6d, 0x1a, 0xc3, 0x5a, 0x0e, 0x56, 0xea, 0x13, 0x1b, 0x04, + 0x6c, 0x75, 0xda, 0x32, 0x83, 0x96, 0xb1, 0x2c, 0x61, 0xdf, 0x87, 0x16, 0xa9, 0x71, 0x58, 0x99, + 0xd5, 0xb1, 0x78, 0xe1, 0x7e, 0x04, 0xab, 0x50, 0xe4, 0x1c, 0x88, 0xd4, 0x35, 0xf2, 0x61, 0x68, + 0x31, 0x33, 0xef, 0x6b, 0x97, 0xc8, 0x46, 0xab, 0xcf, 0xdd, 0x5b, 0x20, 0x65, 0xcd, 0x6f, 0xfd, + 0xf8, 0xd2, 0x13, 0xde, 0xa3, 0x36, 0xf2, 0x7d, 0x4b, 0xc4, 0xd3, 0xd2, 0x8c, 0x6f, 0x23, 0x95, + 0xb8, 0x92, 0x9f, 0xee, 0x2c, 0x3a, 0x85, 0x36, 0xb2, 0x7b, 0x1d, 0x9d, 0xea, 0x87, 0xdf, 0xff, + 0xe5, 0x89, 0xa4, 0x49, 0x0d, 0x11, 0xc1, 0x2a, 0x7b, 0xc0, 0x5e, 0x9e, 0x2f, 0xd8, 0x54, 0x99, + 0x56, 0x08, 0x42, 0xf1, 0x78, 0x0c, 0x8e, 0x49, 0x2c, 0x84, 0xca, 0x55, 0xdb, 0xba, 0xe9, 0x40, + 0xb5, 0x3c, 0xeb, 0x47, 0x8c, 0x80, 0x5e, 0xea, 0x08, 0x60, 0xef, 0xe2, 0xda, 0x1f, 0x77, 0xe1, + 0xc8, 0x5c, 0x84, 0x9a, 0xe8, 0x1d, 0x3f, 0x93, 0x41, 0x21, 0xe6, 0x51, 0x89, 0x2a, 0xf3, 0x2d, + 0x2e, 0x73, 0x91, 0x30, 0xd9, 0x20, 0xfe, 0x53, 0x2a, 0xc5, 0xb7, 0x5b, 0x0b, 0xde, 0x03, 0xc5, + 0xd5, 0xbb, 0x5c, 0x09, 0xa3, 0x07, 0x8a, 0xb7, 0x48, 0x1c, 0x51, 0x0f, 0xe4, 0xe1, 0x7b, 0xfe, + 0x44, 0x65, 0xa7, 0x25, 0x56, 0x22, 0x58, 0x57, 0x1f, 0x51, 0x54, 0x16, 0xe5, 0x9f, 0x3c, 0xf8, + 0x72, 0x5c, 0x2e, 0xa4, 0x09, 0x77, 0x65, 0x98, 0xb6, 0x66, 0x48, 0x17, 0xe4, 0x5e, 0x5f, 0x8a, + 0x32, 0x65, 0x79, 0x47, 0x04, 0x38, 0xcd, 0x6a, 0xab, 0xc8, 0x95, 0x9b, 0x19, 0xa7, 0xdf, 0xb3, + 0xdf, 0x13, 0x13, 0xb1, 0x9c, 0xb4, 0x70, 0xe7, 0x26, 0xde, 0x45, 0x70, 0x8a, 0x68, 0x4d, 0x3c, + 0x8f, 0xb2, 0xe6, 0x9a, 0xdc, 0x1b, 0x3b, 0xa3, 0x46, 0xc5, 0xe9, 0x33, 0x07, 0xe1, 0x56, 0x34, + 0x73, 0x15, 0xce, 0xbe, 0x54, 0x19, 0xfb, 0xff, 0x41, 0x81, 0xeb, 0x32, 0xe1, 0xc4, 0x4d, 0x88, + 0x45, 0xb3, 0xb1, 0xb6, 0x77, 0x93, 0x95, 0x93, 0xda, 0x53, 0x04, 0x63, 0xca, 0x30, 0x82, 0x01, + 0x02, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x81, 0xf4, 0x04, + 0x81, 0xf1, 0x30, 0x81, 0xee, 0x30, 0x81, 0xeb, 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x0c, 0x0a, 0x01, 0x02, 0xa0, 0x81, 0xb4, 0x30, 0x81, 0xb1, 0x30, 0x1c, 0x06, 0x0a, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, 0x30, 0x0e, 0x04, 0x08, 0x34, 0x1d, 0x9e, + 0x9a, 0x1f, 0x50, 0x7b, 0xed, 0x02, 0x02, 0x08, 0x00, 0x04, 0x81, 0x90, 0x47, 0x40, 0x9d, 0x78, + 0xde, 0x5d, 0x13, 0xc8, 0xff, 0xf4, 0xa7, 0xe0, 0x33, 0xab, 0x3b, 0x17, 0x11, 0xf5, 0x30, 0x89, + 0x84, 0x8c, 0x35, 0x6d, 0xdb, 0xfd, 0x8f, 0xec, 0x9b, 0x7f, 0xd7, 0xc9, 0xd9, 0xc7, 0x0f, 0xe3, + 0x95, 0xaf, 0xb0, 0x7a, 0x2c, 0x56, 0xb9, 0x67, 0x18, 0x9d, 0x01, 0xc9, 0xc9, 0xcd, 0x28, 0x79, + 0x33, 0x42, 0xd6, 0x4f, 0x42, 0xdc, 0x57, 0x72, 0xe7, 0xbb, 0x8e, 0x77, 0xc0, 0x59, 0xb1, 0x66, + 0x8a, 0x85, 0xb2, 0xa7, 0xbb, 0xe1, 0x75, 0xa5, 0xe5, 0xbc, 0xb0, 0xa5, 0x9a, 0x4d, 0x84, 0xd6, + 0xae, 0x76, 0x31, 0x73, 0xea, 0xe7, 0x6e, 0xfc, 0x13, 0x78, 0xe9, 0x3f, 0x92, 0x66, 0xa1, 0xce, + 0x6f, 0xc0, 0xa1, 0xeb, 0x74, 0x6b, 0x16, 0xeb, 0x6e, 0xd7, 0x6c, 0x16, 0x39, 0xb7, 0x09, 0x42, + 0x29, 0x28, 0xf9, 0x6e, 0x48, 0x3c, 0x62, 0x88, 0x80, 0x16, 0x70, 0x89, 0x2a, 0xf4, 0xa5, 0xa7, + 0xad, 0x28, 0xb9, 0x66, 0x40, 0x31, 0x7a, 0x10, 0x4e, 0x91, 0xf7, 0xa7, 0x31, 0x25, 0x30, 0x23, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, 0x31, 0x16, 0x04, 0x14, 0x8f, + 0x9d, 0x45, 0xbd, 0xae, 0x29, 0xbc, 0x28, 0x92, 0x9e, 0x40, 0x17, 0xb3, 0xbb, 0xd2, 0x60, 0x40, + 0x5f, 0x63, 0x7d, 0x30, 0x31, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, + 0x05, 0x00, 0x04, 0x14, 0xd4, 0x65, 0x3d, 0x79, 0x6b, 0x30, 0xa1, 0x9f, 0x6c, 0x52, 0xa8, 0xe8, + 0xe7, 0x90, 0x85, 0x33, 0x6b, 0x76, 0x5a, 0xd1, 0x04, 0x08, 0xec, 0xd1, 0x23, 0xf2, 0xaa, 0xf8, + 0xc8, 0x89, 0x02, 0x02, 0x08, 0x00 +}; + +#endif /* _SECURITY_SI_29_CMS_CHAIN_MODE_H_ */ diff --git a/OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.m b/OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.m new file mode 100644 index 00000000..6ce68c92 --- /dev/null +++ b/OSX/sec/Security/Regressions/secitem/si-29-cms-chain-mode.m @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2019 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 +#include +#include + +#include + +#if TARGET_OS_OSX +#include +#define kSystemLoginKeychainPath "/Library/Keychains/System.keychain" +#endif + +#include "shared_regressions.h" + +#include "si-29-cms-chain-mode.h" + +static NSData* CMSEncoder_encode_for_chain_mode(SecIdentityRef identity, CMSCertificateChainMode chainMode) { + CMSEncoderRef encoder = 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")); + + /* Set chain mode */ + require_noerr_action(CMSEncoderSetCertificateChainMode(encoder, chainMode), exit, fail("Failed to set chain mode")); + + /* Load content */ + CMSEncoderUpdateContent(encoder, _chain_mode_content, sizeof(_chain_mode_content)); + + /* output cms message */ + CMSEncoderCopyEncodedContent(encoder, &message); + +exit: + CFReleaseNull(encoder); + return CFBridgingRelease(message); +} + +static NSData* SecCMS_encode_for_chain_mode(SecIdentityRef identity, SecCmsCertChainMode chainMode) { + NSMutableData *data = [NSMutableData data]; + NSData *content = [NSData dataWithBytes:_chain_mode_content length:sizeof(_chain_mode_content)]; + NSDictionary *parameters = @{ + (__bridge NSString*)kSecCMSSignHashAlgorithm : (__bridge NSString*)kSecCMSHashingAlgorithmSHA256, + (__bridge NSString*)kSecCMSCertChainMode : [NSString stringWithFormat:@"%d", chainMode], + }; + SecCMSCreateSignedData(identity, (__bridge CFDataRef)content, (__bridge CFDictionaryRef)parameters, nil, (__bridge CFMutableDataRef)data); + + if (data.length > 0) { + return data; + } + return nil; +} + +static NSArray* CMSDecoder_copy_certs(NSData *cms_message) { + CMSDecoderRef decoder = NULL; + CFArrayRef certs = NULL; + + if (!cms_message) { + return nil; + } + + require_noerr_action(CMSDecoderCreate(&decoder), exit, fail("Failed to create CMS decoder")); + require_noerr_action(CMSDecoderUpdateMessage(decoder, cms_message.bytes, cms_message.length), exit, + fail("Failed to update decoder with CMS message")); + require_noerr_action(CMSDecoderFinalizeMessage(decoder), exit, fail("Failed to finalize decoder")); + ok_status(CMSDecoderCopyAllCerts(decoder, &certs), "Failed to get certs from cms message"); + +exit: + CFReleaseNull(decoder); + return CFBridgingRelease(certs); +} + +static void SecCMS_root_unavailable_tests(SecIdentityRef identity) { + /* Chain Mode None */ + NSData *cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMNone); + NSArray *certs = CMSDecoder_copy_certs(cms_message); + is(0, certs.count, "Expected 0 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Signer */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertOnly); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 1, "Expected 1 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertChain); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 2, "Expected 2 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertChainWithRoot); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 2, "Expected 2 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root or Fail */ + /* We shouldn't be able to find the root, so we shouldn't be able to make the CMS message */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertChainWithRootOrFail); + ok(cms_message == nil, "Expected to fail to encode CMS message without root in keychain"); +} + +static void CMSEncoder_root_unavailable_tests(SecIdentityRef identity) { + /* Chain Mode None */ + NSData *cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateNone); + NSArray *certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 0, "Expected 0 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Signer */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateSignerOnly); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 1, "Expected 1 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateChain); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 2, "Expected 2 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateChainWithRoot); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 2, "Expected 2 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root or Fail */ + /* We shouldn't be able to find the root, so we shouldn't be able to make the CMS message */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateChainWithRootOrFail); + ok(cms_message == nil, "Expected to fail to encode CMS message without root in keychain"); +} + +static void SecCMS_root_available_tests(SecIdentityRef identity) { + /* Chain Mode None */ + NSData *cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMNone); + NSArray *certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 0, "Expected 0 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Signer */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertOnly); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 1, "Expected 1 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertChain); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 2, "Expected 2 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertChainWithRoot); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 3, "Expected 3 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root or Fail */ + cms_message = SecCMS_encode_for_chain_mode(identity, SecCmsCMCertChainWithRootOrFail); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 3, "Expected 3 certs, got %lu", (unsigned long)certs.count); +} + +static void CMSEncoder_root_available_tests(SecIdentityRef identity) { + /* Chain Mode None */ + NSData *cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateNone); + NSArray *certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 0, "Expected 0 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Signer */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateSignerOnly); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 1, "Expected 1 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateChain); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 2, "Expected 2 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateChainWithRoot); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 3, "Expected 3 certs, got %lu", (unsigned long)certs.count); + + /* Chain Mode: Chain With Root or Fail */ + cms_message = CMSEncoder_encode_for_chain_mode(identity, kCMSCertificateChainWithRootOrFail); + certs = CMSDecoder_copy_certs(cms_message); + is(certs.count, 3, "Expected 3 certs, got %lu", (unsigned long)certs.count); +} + +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:p12 length:p12_len]; + 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, NSArray *certs) { +#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 + for(id cert in certs) { + NSDictionary *cert_query = @{ (__bridge NSString*)kSecValueRef : cert }; + ok_status(SecItemDelete((__bridge CFDictionaryRef)cert_query), "failed to remove cert from keychain"); + } +} + +static void add_cert_to_keychain(SecCertificateRef cert) { +#if TARGET_OS_OSX + SecKeychainRef kcRef = NULL; + SecKeychainOpen(kSystemLoginKeychainPath, &kcRef); + if (!kcRef) { + fail("failed to open system keychain"); + return; + } + NSDictionary *query = @{ + (__bridge NSString*)kSecValueRef : (__bridge id)cert, + (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef, + }; +#else + NSDictionary *query = @{ (__bridge NSString*)kSecValueRef : (__bridge id)cert}; +#endif + ok_status(SecItemAdd((__bridge CFDictionaryRef)query, NULL), "failed to add cert to keychain. following tests may fail."); +} + +int si_29_cms_chain_mode(int argc, char *const *argv) { + plan_tests(43); + + SecIdentityRef identity = NULL; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _chain_mode_root, sizeof(_chain_mode_root)); + SecCertificateRef intermediate = SecCertificateCreateWithBytes(NULL, _chain_mode_subca, sizeof(_chain_mode_subca)); + + if (setup_keychain(_chain_mode_leaf_p12 , sizeof(_chain_mode_leaf_p12), &identity)) { + add_cert_to_keychain(intermediate); + + SecCMS_root_unavailable_tests(identity); + CMSEncoder_root_unavailable_tests(identity); + + add_cert_to_keychain(root); + + SecCMS_root_available_tests(identity); + CMSEncoder_root_available_tests(identity); + + cleanup_keychain(identity, @[(__bridge id) intermediate, (__bridge id)root]); + } + + CFReleaseNull(identity); + CFReleaseNull(root); + CFReleaseNull(intermediate); + + return 0; +} diff --git a/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.h b/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.h deleted file mode 100644 index cf6d65dd..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.h +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. - */ - -#ifndef si_29_sectrust_sha1_deprecation_h -#define si_29_sectrust_sha1_deprecation_h - -/* subject:/C=US/ST=California/L=Walnut Creek/O=Lucas Garron/CN=*.badssl.com */ -/* issuer :/C=US/O=DigiCert Inc/CN=DigiCert Secure Server CA */ -unsigned char _badssl_sha1[1286]={ - 0x30,0x82,0x05,0x02,0x30,0x82,0x03,0xEA,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0B, - 0xA1,0x28,0x31,0xAB,0x8A,0x7D,0x86,0x4E,0x61,0x59,0xDC,0x34,0xE7,0x5E,0x0D,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x48, - 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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x44, - 0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53, - 0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x30,0x36, - 0x30,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x31,0x30, - 0x35,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x67,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,0x15,0x30,0x13,0x06,0x03, - 0x55,0x04,0x03,0x0C,0x0C,0x2A,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,0xC2,0x04,0xEC,0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58, - 0xCC,0x93,0x18,0xEB,0x5C,0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B, - 0x2C,0x76,0x3E,0x6C,0xC0,0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6, - 0xB0,0xF9,0x72,0xC9,0x86,0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B, - 0xBC,0xE9,0x94,0x2E,0x50,0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46, - 0xD3,0x16,0x87,0x27,0x9F,0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84, - 0x4C,0x79,0x55,0xE4,0xD1,0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB, - 0xAA,0xFF,0x6E,0xFF,0x60,0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD, - 0x4D,0xC0,0xC4,0xFC,0x53,0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2, - 0x33,0x48,0xE7,0x22,0x71,0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA, - 0x6C,0xB5,0x72,0xB4,0x7E,0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12, - 0xAB,0xDE,0xC3,0x0F,0x47,0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD, - 0x22,0x06,0x29,0x2E,0xB1,0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40, - 0x72,0x00,0xAC,0x92,0x08,0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B, - 0x54,0x98,0x40,0x27,0x85,0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45, - 0x55,0x7C,0xF9,0x64,0x3F,0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1, - 0xCA,0x85,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0xC7,0x30,0x82,0x01,0xC3,0x30, - 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0x71,0xDB,0x37, - 0xEB,0x73,0xC8,0xEF,0xDC,0xD5,0x1E,0x12,0xB6,0x34,0xBA,0x2B,0x5A,0xA0,0xA6,0x92, - 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81, - 0x0B,0x3A,0x47,0x69,0x71,0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,0x30, - 0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30,0x1A,0x82,0x0A,0x62,0x61,0x64,0x73, - 0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x0C,0x2A,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,0x02,0x06,0x08,0x2B,0x06,0x01,0x05,0x05, - 0x07,0x03,0x01,0x30,0x61,0x06,0x03,0x55,0x1D,0x1F,0x04,0x5A,0x30,0x58,0x30,0x2A, - 0xA0,0x28,0xA0,0x26,0x86,0x24,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,0x67,0x37,0x2E,0x63,0x72,0x6C,0x30,0x2A,0xA0,0x28,0xA0,0x26, - 0x86,0x24,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, - 0x67,0x37,0x2E,0x63,0x72,0x6C,0x30,0x42,0x06,0x03,0x55,0x1D,0x20,0x04,0x3B,0x30, - 0x39,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,0x78,0x06,0x08,0x2B,0x06, - 0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x6C,0x30,0x6A,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,0x42,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x36,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,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,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, - 0x00,0x03,0x82,0x01,0x01,0x00,0x63,0x5C,0x60,0xD0,0xDB,0x4D,0x93,0xF9,0xAE,0x41, - 0xF0,0x4E,0xBF,0xFF,0x2A,0x11,0x6A,0x5E,0x15,0x5C,0x95,0x61,0x95,0x04,0x6A,0xD8, - 0x0E,0xA1,0xA2,0x80,0x12,0x4A,0x9E,0x15,0x3B,0x80,0x7A,0x4F,0xAA,0x49,0xCB,0x86, - 0xDA,0xD8,0xAF,0xF1,0xE2,0x87,0x36,0xA3,0xE6,0xDB,0xCA,0x98,0xDF,0x5A,0x3C,0x5C, - 0xDF,0x95,0x1C,0xA7,0xE9,0xCB,0xB2,0xD9,0xF5,0xE2,0x20,0x5C,0x4D,0xF4,0xD3,0x6D, - 0xCE,0x4A,0xE9,0xE2,0x20,0x32,0x29,0x0C,0x1B,0x60,0x01,0x9B,0xEA,0xDB,0x84,0xEF, - 0x1B,0xBD,0xA7,0xC7,0x4B,0x20,0x5F,0xD9,0x9D,0x1B,0xDB,0xEB,0x82,0x79,0x3E,0xDF, - 0xFD,0xDA,0xCF,0xFD,0x8C,0x50,0x1B,0xDD,0x6F,0x71,0x82,0x92,0x23,0x03,0x64,0xF0, - 0x00,0x57,0x28,0xFA,0x8B,0x03,0x3F,0xB9,0xCC,0x90,0x40,0x93,0xBB,0x70,0xC8,0x56, - 0x59,0xA8,0x4D,0x6A,0x77,0x94,0xAA,0x15,0xEE,0x5E,0x13,0x10,0xC8,0x07,0xC4,0xCD, - 0xC7,0xFA,0x24,0x25,0xFB,0xDB,0x8A,0x1C,0xB2,0x2E,0xA1,0x52,0xB9,0x28,0x3F,0xD8, - 0x50,0x22,0xB2,0x04,0x0C,0xB4,0x81,0x83,0xB8,0xC3,0x4A,0x0C,0xF9,0xB2,0xAC,0x89, - 0x5C,0xDD,0x04,0xE6,0x26,0xFA,0xF5,0x09,0x5E,0x34,0xCD,0x4C,0xE0,0xAB,0x02,0xBB, - 0x98,0x63,0x7E,0x07,0x57,0x6E,0xAA,0x61,0x8A,0x53,0xFC,0x3E,0x95,0x77,0x84,0x8C, - 0x4D,0x4B,0x5F,0x6E,0xA3,0x38,0x06,0x0E,0x82,0x63,0x57,0xA1,0x22,0x87,0x95,0x12, - 0x71,0xA1,0x84,0x61,0xBA,0xF1,0x0B,0x07,0xB4,0x01,0x32,0x68,0x14,0x29,0xC9,0x58, - 0x3A,0x57,0xE6,0x5C,0x21,0x78, -}; - -/* subject:/C=US/O=DigiCert Inc/CN=DigiCert Secure Server CA */ -/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ -unsigned char _digiCertSSCA[1171]={ - 0x30,0x82,0x04,0x8F,0x30,0x82,0x03,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x06, - 0x9E,0x1D,0xB7,0x7F,0xCF,0x1D,0xFB,0xA9,0x7A,0xF5,0xE5,0xC9,0xA2,0x40,0x37,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,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,0x48,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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03, - 0x13,0x19,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,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,0xBB,0x57,0xE4,0x21, - 0xA9,0xD5,0x9B,0x60,0x37,0x7E,0x8E,0xA1,0x61,0x7F,0x81,0xE2,0x1A,0xC2,0x75,0x64, - 0xD9,0x91,0x50,0x0B,0xE4,0x36,0x44,0x24,0x6E,0x30,0xD2,0x9B,0x7A,0x27,0xFA,0xC2, - 0x6A,0xAE,0x6A,0x70,0x09,0x38,0xB9,0x20,0x0A,0xC8,0x65,0x10,0x4A,0x88,0xAC,0x31, - 0xF2,0xDC,0x92,0xF2,0x63,0xA1,0x5D,0x80,0x63,0x59,0x80,0x92,0x23,0x1C,0xE6,0xEF, - 0x76,0x4A,0x50,0x35,0xC9,0xD8,0x71,0x38,0xB9,0xED,0xF0,0xE6,0x42,0xAE,0xD3,0x38, - 0x26,0x79,0x30,0xF9,0x22,0x94,0xC6,0xDB,0xA6,0x3F,0x41,0x78,0x90,0xD8,0xDE,0x5C, - 0x7E,0x69,0x7D,0xF8,0x90,0x15,0x3A,0xD0,0xA1,0xA0,0xBE,0xFA,0xB2,0xB2,0x19,0xA1, - 0xD8,0x2B,0xD1,0xCE,0xBF,0x6B,0xDD,0x49,0xAB,0xA3,0x92,0xFE,0xB5,0xAB,0xC8,0xC1, - 0x3E,0xEE,0x01,0x00,0xD8,0xA9,0x44,0xB8,0x42,0x73,0x88,0xC3,0x61,0xF5,0xAB,0x4A, - 0x83,0x28,0x0A,0xD2,0xD4,0x49,0xFA,0x6A,0xB1,0xCD,0xDF,0x57,0x2C,0x94,0xE5,0xE2, - 0xCA,0x83,0x5F,0xB7,0xBA,0x62,0x5C,0x2F,0x68,0xA5,0xF0,0xC0,0xB9,0xFD,0x2B,0xD1, - 0xE9,0x1F,0xD8,0x1A,0x62,0x15,0xBD,0xFF,0x3D,0xA6,0xF7,0xCB,0xEF,0xE6,0xDB,0x65, - 0x2F,0x25,0x38,0xEC,0xFB,0xE6,0x20,0x66,0x58,0x96,0x34,0x19,0xD2,0x15,0xCE,0x21, - 0xD3,0x24,0xCC,0xD9,0x14,0x6F,0xD8,0xFE,0x55,0xC7,0xE7,0x6F,0xB6,0x0F,0x1A,0x8C, - 0x49,0xBE,0x29,0xF2,0xBA,0x5A,0x9A,0x81,0x26,0x37,0x24,0x6F,0xD7,0x48,0x12,0x6C, - 0x2E,0x59,0xF5,0x9C,0x18,0xBB,0xD9,0xF6,0x68,0xE2,0xDF,0x45,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,0x90,0x71,0xDB,0x37,0xEB,0x73, - 0xC8,0xEF,0xDC,0xD5,0x1E,0x12,0xB6,0x34,0xBA,0x2B,0x5A,0xA0,0xA6,0x92,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,0x30,0xCE,0xD1,0x95,0x51,0x00,0xAE,0x06,0x0B,0xA1,0x0E,0x02,0xC0, - 0x17,0xAC,0xB6,0x7F,0x8F,0x20,0xF6,0x40,0x75,0x74,0x1C,0xCC,0x78,0xB1,0xA4,0x4F, - 0xEA,0xF4,0xD0,0xC4,0x9D,0xA2,0xDE,0x81,0x07,0x26,0x1F,0x40,0x88,0x51,0xF0,0x1F, - 0xCF,0xB7,0x4C,0x40,0x99,0xD0,0xF4,0x3C,0x71,0x98,0x73,0x88,0x97,0x2C,0x19,0xD7, - 0x6E,0x84,0x8F,0xA4,0x1F,0x9C,0x5A,0x20,0xE3,0x51,0x5C,0xB0,0xC5,0x9E,0x99,0x6A, - 0x4F,0xC8,0x69,0xF7,0x10,0xFF,0x4E,0xAD,0x19,0xD9,0xC9,0x58,0xB3,0x33,0xAE,0x0C, - 0xD9,0x96,0x29,0x9E,0x71,0xB2,0x70,0x63,0xA3,0xB6,0x99,0x16,0x42,0x1D,0x65,0xF3, - 0xF7,0xA0,0x1E,0x7D,0xC5,0xD4,0x65,0x14,0xB2,0x62,0x84,0xD4,0x6C,0x5C,0x08,0x0C, - 0xD8,0x6C,0x93,0x2B,0xB4,0x76,0x59,0x8A,0xD1,0x7F,0xFF,0x03,0xD8,0xC2,0x5D,0xB8, - 0x2F,0x22,0xD6,0x38,0xF0,0xF6,0x9C,0x6B,0x7D,0x46,0xEB,0x99,0x74,0xF7,0xEB,0x4A, - 0x0E,0xA9,0xA6,0x04,0xEB,0x7B,0xCE,0xF0,0x5C,0x6B,0x98,0x31,0x5A,0x98,0x40,0xEB, - 0x69,0xC4,0x05,0xF4,0x20,0xA8,0xCA,0x08,0x3A,0x65,0x6C,0x38,0x15,0xF5,0x5C,0x2C, - 0xB2,0x55,0xE4,0x2C,0x6B,0x41,0xF0,0xBE,0x5C,0x46,0xCA,0x4A,0x29,0xA0,0x48,0x5E, - 0x20,0xD2,0x45,0xFF,0x05,0xDE,0x34,0xAF,0x70,0x4B,0x81,0x39,0xE2,0xCA,0x07,0x57, - 0x7C,0xB6,0x31,0xDC,0x21,0x29,0xE2,0xBE,0x97,0x0E,0x77,0x90,0x14,0x51,0x40,0xE1, - 0xBF,0xE3,0xCC,0x1B,0x19,0x9C,0x25,0xCA,0xA7,0x06,0xB2,0x53,0xDF,0x23,0xB2,0xCF, - 0x12,0x19,0xA3, -}; - -/* 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 */ -unsigned char _digiCertRoot[947]={ - 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, -}; - -/* subject:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.badssl.com */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ -unsigned char _badssl_sha2[1359]={ - 0x30,0x82,0x05,0x4B,0x30,0x82,0x04,0x33,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, - 0x8E,0x18,0x71,0x4B,0x34,0xE7,0x5E,0x8D,0xAE,0xFB,0xE8,0xF6,0x4C,0x3A,0x82,0x30, - 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, - 0x90,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,0x36,0x30,0x34,0x06,0x03,0x55, - 0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44, - 0x6F,0x6D,0x61,0x69,0x6E,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,0x36,0x30,0x37,0x30,0x37,0x30,0x30,0x30,0x30,0x30, - 0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x39,0x30,0x35,0x32,0x33,0x35,0x39,0x35,0x39, - 0x5A,0x30,0x59,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x44,0x6F, - 0x6D,0x61,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x56,0x61,0x6C, - 0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13, - 0x14,0x50,0x6F,0x73,0x69,0x74,0x69,0x76,0x65,0x53,0x53,0x4C,0x20,0x57,0x69,0x6C, - 0x64,0x63,0x61,0x72,0x64,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C, - 0x2A,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,0xC2,0x04,0xEC, - 0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58,0xCC,0x93,0x18,0xEB,0x5C, - 0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B,0x2C,0x76,0x3E,0x6C,0xC0, - 0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6,0xB0,0xF9,0x72,0xC9,0x86, - 0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B,0xBC,0xE9,0x94,0x2E,0x50, - 0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46,0xD3,0x16,0x87,0x27,0x9F, - 0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84,0x4C,0x79,0x55,0xE4,0xD1, - 0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB,0xAA,0xFF,0x6E,0xFF,0x60, - 0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD,0x4D,0xC0,0xC4,0xFC,0x53, - 0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2,0x33,0x48,0xE7,0x22,0x71, - 0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA,0x6C,0xB5,0x72,0xB4,0x7E, - 0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12,0xAB,0xDE,0xC3,0x0F,0x47, - 0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD,0x22,0x06,0x29,0x2E,0xB1, - 0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40,0x72,0x00,0xAC,0x92,0x08, - 0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B,0x54,0x98,0x40,0x27,0x85, - 0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45,0x55,0x7C,0xF9,0x64,0x3F, - 0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1,0xCA,0x85,0x02,0x03,0x01, - 0x00,0x01,0xA3,0x82,0x01,0xD5,0x30,0x82,0x01,0xD1,0x30,0x1F,0x06,0x03,0x55,0x1D, - 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90, - 0xEA,0x12,0x56,0x73,0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x1D,0x06,0x03,0x55, - 0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81,0x0B,0x3A,0x47,0x69,0x71, - 0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,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,0x4F,0x06,0x03,0x55,0x1D,0x20,0x04,0x48, - 0x30,0x46,0x30,0x3A,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x02, - 0x07,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,0x08, - 0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x01,0x30,0x54,0x06,0x03,0x55,0x1D,0x1F,0x04, - 0x4D,0x30,0x4B,0x30,0x49,0xA0,0x47,0xA0,0x45,0x86,0x43,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,0x44,0x6F,0x6D,0x61, - 0x69,0x6E,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, - 0x85,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x79,0x30,0x77,0x30, - 0x4F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x43,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,0x44,0x6F, - 0x6D,0x61,0x69,0x6E,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,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30, - 0x1A,0x82,0x0C,0x2A,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82, - 0x0A,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A, - 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x75, - 0x48,0x83,0x88,0x9C,0x55,0x24,0x37,0x30,0x07,0xEB,0x26,0x68,0xC8,0x79,0x1C,0x5C, - 0xAE,0x9A,0x02,0x9A,0xB5,0x52,0x75,0x44,0xAC,0xA9,0xED,0x59,0x65,0xD0,0xC6,0x47, - 0x26,0x04,0x8D,0x57,0x89,0x16,0x2E,0x71,0x18,0x48,0x98,0x68,0x1C,0xF6,0x31,0xF5, - 0x26,0x4B,0xE8,0x81,0x44,0xB1,0xFF,0x5C,0x65,0x3D,0x78,0x54,0x94,0xC3,0x86,0x9D, - 0x48,0x96,0xE8,0x32,0xAF,0xE1,0x8F,0x94,0x47,0xBE,0x37,0x8C,0xC3,0xED,0x4D,0x97, - 0xBB,0xC6,0x2A,0x37,0x72,0x01,0x3A,0x8F,0x82,0xA4,0x34,0x44,0xC4,0xC4,0xF8,0x50, - 0x24,0x48,0x9E,0x19,0xF0,0xEC,0xE1,0xC6,0x13,0x44,0x26,0xB6,0x65,0xE1,0x62,0x49, - 0x87,0xA4,0xF4,0xD8,0xC4,0x39,0x3C,0x7D,0x42,0xC8,0xA4,0x2A,0x54,0x05,0xA0,0xDC, - 0x0A,0xF8,0x2B,0x22,0x94,0x93,0x78,0x4E,0x6A,0x36,0x1B,0xD2,0xE7,0xE9,0xAE,0x84, - 0xED,0x13,0x1D,0xA1,0xF7,0xA2,0x83,0x81,0x03,0x4C,0x9E,0x21,0xFB,0xBF,0xA8,0x30, - 0xFE,0xEB,0x00,0x68,0xB1,0x7F,0xBA,0x5D,0xE2,0x5D,0xFF,0x41,0x1F,0xD6,0xF5,0xA6, - 0x5C,0x8A,0xEF,0x81,0x80,0xC8,0xF1,0x52,0x00,0x17,0x9D,0xD1,0x96,0x1A,0x7D,0x5E, - 0xD2,0x83,0xB3,0x82,0xC2,0x3D,0x46,0x83,0xA5,0x1E,0xB4,0x36,0x35,0x38,0xC4,0x7A, - 0x2E,0xDF,0x0B,0xA1,0x98,0x63,0x58,0x0B,0x1E,0xD0,0x6D,0x83,0x1F,0xF1,0x72,0x4D, - 0x09,0xAC,0x96,0x1A,0x0B,0xE5,0xF6,0x34,0x4C,0xAB,0xBC,0xBC,0x99,0x5B,0x82,0x59, - 0xE6,0x6C,0xD3,0xDB,0x98,0xE0,0xCE,0x95,0x3B,0xCF,0x4E,0x17,0xC3,0xEE,0x3A, -}; - -/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ -/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ -unsigned char _COMODO_DV[1548]={ - 0x30,0x82,0x06,0x08,0x30,0x82,0x03,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2B, - 0x2E,0x6E,0xEA,0xD9,0x75,0x36,0x6C,0x14,0x8A,0x6E,0xDB,0xA3,0x7C,0x8C,0x07,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,0x34,0x30,0x32,0x31,0x32, - 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x32,0x31,0x31,0x32, - 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x90,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,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F, - 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44,0x6F,0x6D,0x61,0x69,0x6E,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,0x8E,0xC2,0x02,0x19,0xE1,0xA0, - 0x59,0xA4,0xEB,0x38,0x35,0x8D,0x2C,0xFD,0x01,0xD0,0xD3,0x49,0xC0,0x64,0xC7,0x0B, - 0x62,0x05,0x45,0x16,0x3A,0xA8,0xA0,0xC0,0x0C,0x02,0x7F,0x1D,0xCC,0xDB,0xC4,0xA1, - 0x6D,0x77,0x03,0xA3,0x0F,0x86,0xF9,0xE3,0x06,0x9C,0x3E,0x0B,0x81,0x8A,0x9B,0x49, - 0x1B,0xAD,0x03,0xBE,0xFA,0x4B,0xDB,0x8C,0x20,0xED,0xD5,0xCE,0x5E,0x65,0x8E,0x3E, - 0x0D,0xAF,0x4C,0xC2,0xB0,0xB7,0x45,0x5E,0x52,0x2F,0x34,0xDE,0x48,0x24,0x64,0xB4, - 0x41,0xAE,0x00,0x97,0xF7,0xBE,0x67,0xDE,0x9E,0xD0,0x7A,0xA7,0x53,0x80,0x3B,0x7C, - 0xAD,0xF5,0x96,0x55,0x6F,0x97,0x47,0x0A,0x7C,0x85,0x8B,0x22,0x97,0x8D,0xB3,0x84, - 0xE0,0x96,0x57,0xD0,0x70,0x18,0x60,0x96,0x8F,0xEE,0x2D,0x07,0x93,0x9D,0xA1,0xBA, - 0xCA,0xD1,0xCD,0x7B,0xE9,0xC4,0x2A,0x9A,0x28,0x21,0x91,0x4D,0x6F,0x92,0x4F,0x25, - 0xA5,0xF2,0x7A,0x35,0xDD,0x26,0xDC,0x46,0xA5,0xD0,0xAC,0x59,0x35,0x8C,0xFF,0x4E, - 0x91,0x43,0x50,0x3F,0x59,0x93,0x1E,0x6C,0x51,0x21,0xEE,0x58,0x14,0xAB,0xFE,0x75, - 0x50,0x78,0x3E,0x4C,0xB0,0x1C,0x86,0x13,0xFA,0x6B,0x98,0xBC,0xE0,0x3B,0x94,0x1E, - 0x85,0x52,0xDC,0x03,0x93,0x24,0x18,0x6E,0xCB,0x27,0x51,0x45,0xE6,0x70,0xDE,0x25, - 0x43,0xA4,0x0D,0xE1,0x4A,0xA5,0xED,0xB6,0x7E,0xC8,0xCD,0x6D,0xEE,0x2E,0x1D,0x27, - 0x73,0x5D,0xDC,0x45,0x30,0x80,0xAA,0xE3,0xB2,0x41,0x0B,0xAF,0xBD,0x44,0x87,0xDA, - 0xB9,0xE5,0x1B,0x9D,0x7F,0xAE,0xE5,0x85,0x82,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3, - 0x82,0x01,0x65,0x30,0x82,0x01,0x61,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,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90,0xEA,0x12,0x56,0x73, - 0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, - 0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,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,0x1B,0x06,0x03,0x55,0x1D, - 0x20,0x04,0x14,0x30,0x12,0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x08,0x06, - 0x06,0x67,0x81,0x0C,0x01,0x02,0x01,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,0x4E,0x2B,0x76,0x4F, - 0x92,0x1C,0x62,0x36,0x89,0xBA,0x77,0xC1,0x27,0x05,0xF4,0x1C,0xD6,0x44,0x9D,0xA9, - 0x9A,0x3E,0xAA,0xD5,0x66,0x66,0x01,0x3E,0xEA,0x49,0xE6,0xA2,0x35,0xBC,0xFA,0xF6, - 0xDD,0x95,0x8E,0x99,0x35,0x98,0x0E,0x36,0x18,0x75,0xB1,0xDD,0xDD,0x50,0x72,0x7C, - 0xAE,0xDC,0x77,0x88,0xCE,0x0F,0xF7,0x90,0x20,0xCA,0xA3,0x67,0x2E,0x1F,0x56,0x7F, - 0x7B,0xE1,0x44,0xEA,0x42,0x95,0xC4,0x5D,0x0D,0x01,0x50,0x46,0x15,0xF2,0x81,0x89, - 0x59,0x6C,0x8A,0xDD,0x8C,0xF1,0x12,0xA1,0x8D,0x3A,0x42,0x8A,0x98,0xF8,0x4B,0x34, - 0x7B,0x27,0x3B,0x08,0xB4,0x6F,0x24,0x3B,0x72,0x9D,0x63,0x74,0x58,0x3C,0x1A,0x6C, - 0x3F,0x4F,0xC7,0x11,0x9A,0xC8,0xA8,0xF5,0xB5,0x37,0xEF,0x10,0x45,0xC6,0x6C,0xD9, - 0xE0,0x5E,0x95,0x26,0xB3,0xEB,0xAD,0xA3,0xB9,0xEE,0x7F,0x0C,0x9A,0x66,0x35,0x73, - 0x32,0x60,0x4E,0xE5,0xDD,0x8A,0x61,0x2C,0x6E,0x52,0x11,0x77,0x68,0x96,0xD3,0x18, - 0x75,0x51,0x15,0x00,0x1B,0x74,0x88,0xDD,0xE1,0xC7,0x38,0x04,0x43,0x28,0xE9,0x16, - 0xFD,0xD9,0x05,0xD4,0x5D,0x47,0x27,0x60,0xD6,0xFB,0x38,0x3B,0x6C,0x72,0xA2,0x94, - 0xF8,0x42,0x1A,0xDF,0xED,0x6F,0x06,0x8C,0x45,0xC2,0x06,0x00,0xAA,0xE4,0xE8,0xDC, - 0xD9,0xB5,0xE1,0x73,0x78,0xEC,0xF6,0x23,0xDC,0xD1,0xDD,0x6C,0x8E,0x1A,0x8F,0xA5, - 0xEA,0x54,0x7C,0x96,0xB7,0xC3,0xFE,0x55,0x8E,0x8D,0x49,0x5E,0xFC,0x64,0xBB,0xCF, - 0x3E,0xBD,0x96,0xEB,0x69,0xCD,0xBF,0xE0,0x48,0xF1,0x62,0x82,0x10,0xE5,0x0C,0x46, - 0x57,0xF2,0x33,0xDA,0xD0,0xC8,0x63,0xED,0xC6,0x1F,0x94,0x05,0x96,0x4A,0x1A,0x91, - 0xD1,0xF7,0xEB,0xCF,0x8F,0x52,0xAE,0x0D,0x08,0xD9,0x3E,0xA8,0xA0,0x51,0xE9,0xC1, - 0x87,0x74,0xD5,0xC9,0xF7,0x74,0xAB,0x2E,0x53,0xFB,0xBB,0x7A,0xFB,0x97,0xE2,0xF8, - 0x1F,0x26,0x8F,0xB3,0xD2,0xA0,0xE0,0x37,0x5B,0x28,0x3B,0x31,0xE5,0x0E,0x57,0x2D, - 0x5A,0xB8,0xAD,0x79,0xAC,0x5E,0x20,0x66,0x1A,0xA5,0xB9,0xA6,0xB5,0x39,0xC1,0xF5, - 0x98,0x43,0xFF,0xEE,0xF9,0xA7,0xA7,0xFD,0xEE,0xCA,0x24,0x3D,0x80,0x16,0xC4,0x17, - 0x8F,0x8A,0xC1,0x60,0xA1,0x0C,0xAE,0x5B,0x43,0x47,0x91,0x4B,0xD5,0x9A,0x17,0x5F, - 0xF9,0xD4,0x87,0xC1,0xC2,0x8C,0xB7,0xE7,0xE2,0x0F,0x30,0x19,0x37,0x86,0xAC,0xE0, - 0xDC,0x42,0x03,0xE6,0x94,0xA8,0x9D,0xAE,0xFD,0x0F,0x24,0x51,0x94,0xCE,0x92,0x08, - 0xD1,0xFC,0x50,0xF0,0x03,0x40,0x7B,0x88,0x59,0xED,0x0E,0xDD,0xAC,0xD2,0x77,0x82, - 0x34,0xDC,0x06,0x95,0x02,0xD8,0x90,0xF9,0x2D,0xEA,0x37,0xD5,0x1A,0x60,0xD0,0x67, - 0x20,0xD7,0xD8,0x42,0x0B,0x45,0xAF,0x82,0x68,0xDE,0xDD,0x66,0x24,0x37,0x90,0x29, - 0x94,0x19,0x46,0x19,0x25,0xB8,0x80,0xD7,0xCB,0xD4,0x86,0x28,0x6A,0x44,0x70,0x26, - 0x23,0x62,0xA9,0x9F,0x86,0x6F,0xBF,0xBA,0x90,0x70,0xD2,0x56,0x77,0x85,0x78,0xEF, - 0xEA,0x25,0xA9,0x17,0xCE,0x50,0x72,0x8C,0x00,0x3A,0xAA,0xE3,0xDB,0x63,0x34,0x9F, - 0xF8,0x06,0x71,0x01,0xE2,0x82,0x20,0xD4,0xFE,0x6F,0xBD,0xB1, -}; - -#endif /* si_29_sectrust_sha1_deprecation_h */ 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 deleted file mode 100644 index 8ad5a799..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-29-sectrust-sha1-deprecation.m +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. - */ - -#include -#import -#include -#include -#include -#include -#include -#include -#include - -#if TARGET_OS_IPHONE -#include -#else -#include -#endif - -#include "shared_regressions.h" - -#include "si-29-sectrust-sha1-deprecation.h" - -#import - -static SecCertificateRef sha1_root = NULL; - -#if TARGET_OS_IPHONE -static SecTrustStoreRef defaultStore = NULL; -#else -#define kSystemLoginKeychainPath "/Library/Keychains/System.keychain" -static NSMutableArray *deleteMeCertificates = NULL; -#endif - - -static void setup_globals(void) { - - sha1_root = SecCertificateCreateWithBytes(NULL, _digiCertRoot, sizeof(_digiCertRoot)); - -#if TARGET_OS_IPHONE - defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser); -#else - /* Since we're putting trust settings in the admin domain, - * we need to add the certs to the system keychain. */ - SecKeychainRef kcRef = NULL; - CFArrayRef certRef = NULL; - NSDictionary *attrs = nil; - - SecKeychainOpen(kSystemLoginKeychainPath, &kcRef); - if (!kcRef) { - goto out; - } - - deleteMeCertificates = [[NSMutableArray alloc] init]; - - attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)sha1_root, - (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef, - (__bridge NSString*)kSecReturnPersistentRef: @YES}; - if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0) - [deleteMeCertificates addObject:(__bridge NSArray *)certRef]; - CFReleaseNull(certRef); - - out: - CFReleaseNull(kcRef); -#endif -} - -static void cleanup_globals(void) { -#if !TARGET_OS_IPHONE - [deleteMeCertificates enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { - SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: [obj objectAtIndex:0]}); - }]; -#endif - - CFReleaseNull(sha1_root); -} - - -static void setTrust(SecTrustRef *trust, NSArray *certs, SecPolicyRef policy) -{ - // November 4, 2016 at 5:53:20 PM PDT - NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0]; - CFReleaseNull(*trust); - require_noerr_string(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, trust), cleanup, "failed to create trust"); - require_noerr_string(SecTrustSetVerifyDate(*trust, (__bridge CFDateRef)verifyDate), - cleanup, "failed to set verify date"); -cleanup: - return; -} - -static void tests(void) -{ - SecCertificateRef sha1_leaf = NULL, sha1_int = NULL, - sha2_leaf = NULL, sha2_int = NULL; - NSArray *anchors = nil, *sha1_certs = nil, *sha2_certs = nil; - SecPolicyRef serverPolicy = NULL, clientPolicy = NULL; - SecTrustRef trust = NULL; - SecTrustResultType trustResult = kSecTrustResultInvalid; - - sha1_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha1, sizeof(_badssl_sha1)); - sha1_int = SecCertificateCreateWithBytes(NULL, _digiCertSSCA, sizeof(_digiCertSSCA)); - sha2_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha2, sizeof(_badssl_sha2)); - sha2_int = SecCertificateCreateWithBytes(NULL, _COMODO_DV, sizeof(_COMODO_DV)); - - /* SHA1 cert from system roots fails SSL server policy*/ - sha1_certs = @[ (__bridge id)sha1_leaf, (__bridge id)sha1_int]; - serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com")); - setTrust(&trust, sha1_certs, serverPolicy); - require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust"); - is(trustResult, kSecTrustResultRecoverableTrustFailure, "reject test: system-trusted SHA-1 SSL server"); - - /* Add trust setting for root */ -#if TARGET_OS_IPHONE - require_noerr_string(SecTrustStoreSetTrustSettings(defaultStore, sha1_root, NULL), - cleanup, "failed to set trust settings"); -#else - require_noerr_string(SecTrustSettingsSetTrustSettings(sha1_root, kSecTrustSettingsDomainAdmin, - NULL), - cleanup, "failed to set trust settings"); - usleep(20000); -#endif - - /* SHA1 cert now passes SSL server*/ - setTrust(&trust, sha1_certs, serverPolicy); - require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust"); - is(trustResult, kSecTrustResultProceed, "accept test: user-trusted SHA-1 SSL server"); - - /* Remove trust setting for root */ -#if TARGET_OS_IPHONE - require_noerr_string(SecTrustStoreRemoveCertificate(defaultStore, sha1_root), - cleanup, "failed to remove trust settings"); -#else - require_noerr_string(SecTrustSettingsRemoveTrustSettings(sha1_root, kSecTrustSettingsDomainAdmin), - cleanup, "failed to remove trust settings"); -#endif - - /* SHA1 cert fails SSL server */ - setTrust(&trust, sha1_certs, serverPolicy); - require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust"); - is(trustResult, kSecTrustResultRecoverableTrustFailure, "reject test: system-trusted SHA-1 SSL server"); - - /* Set anchor for root */ - require_quiet(sha1_root, cleanup); - anchors = @[(__bridge id)sha1_root]; - require_noerr_string(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), cleanup, "failed to set anchors"); - - /* SHA1 cert passes SSL server */ - require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust"); - is(trustResult, kSecTrustResultUnspecified, "accept test: app-trusted SHA-1 SSL server"); - - /* SHA1 cert from system root passes SSL client */ - 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"); - - /* SHA256 cert from system root passes SSL server */ - sha2_certs = @[ (__bridge id)sha2_leaf, (__bridge id)sha2_int]; - setTrust(&trust, sha2_certs, serverPolicy); - require_noerr_string(SecTrustEvaluate(trust, &trustResult), cleanup, "failed to evaluate trust"); - is(trustResult, kSecTrustResultUnspecified, "accept test: system-trusted SHA2 SSL server"); - -cleanup: - CFReleaseNull(sha1_leaf); - CFReleaseNull(sha1_int); - CFReleaseNull(sha2_leaf); - CFReleaseNull(sha2_int); - CFReleaseNull(serverPolicy); - CFReleaseNull(clientPolicy); - CFReleaseNull(trust); -} - -int si_29_sectrust_sha1_deprecation(int argc, char *const *argv) -{ - plan_tests(6); - - @autoreleasepool { - setup_globals(); - tests(); - cleanup_globals(); - } - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-33-keychain-backup.c b/OSX/sec/Security/Regressions/secitem/si-33-keychain-backup.c index 5549562d..258e5895 100644 --- a/OSX/sec/Security/Regressions/secitem/si-33-keychain-backup.c +++ b/OSX/sec/Security/Regressions/secitem/si-33-keychain-backup.c @@ -24,12 +24,7 @@ #include -#if TARGET_IPHONE_SIMULATOR -#define USE_KEYSTORE 0 -#else /* No AppleKeyStore.kext on this OS. */ -#define USE_KEYSTORE 1 -#endif - +#include "securityd/SecKeybagSupport.h" #include #include @@ -41,7 +36,7 @@ #if USE_KEYSTORE #include -#include +#include "OSX/utilities/SecAKSWrappers.h" #endif #include @@ -395,10 +390,16 @@ static CFDataRef create_keybag(keybag_handle_t bag_type, CFDataRef password) int bagLen = 0; keybag_handle_t handle = bad_keybag_handle; - require_noerr(aks_create_bag(DATA_ARG(password), bag_type, &handle), out); - require_noerr(aks_save_bag(handle, &bag, &bagLen), out); + kern_return_t bag_created = aks_create_bag(DATA_ARG(password), bag_type, &handle); + ok_status(bag_created, "Bag should have been created"); + require_noerr(bag_created, out); + + kern_return_t bag_saved = aks_save_bag(handle, &bag, &bagLen); + ok_status(bag_saved, "Bag should have been saved"); + require_noerr(bag_saved, out); result = CFDataCreate(kCFAllocatorDefault, bag, bagLen); + isnt(result, NULL, "Result should not be null"); out: return result; } @@ -412,6 +413,16 @@ static void tests(void) (void)SecItemDelete(lock_down_query); CFReleaseNull(lock_down_query); } + { + CFMutableDictionaryRef sysbound_query = test_create_sysbound_query(); + (void)SecItemDelete(sysbound_query); + CFReleaseNull(sysbound_query); + } + { + CFMutableDictionaryRef managed_configuration_query = test_create_managedconfiguration_query(); + (void)SecItemDelete(managed_configuration_query); + CFReleaseNull(managed_configuration_query); + } int v_eighty = 80; CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); diff --git a/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m b/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m index 4662cf15..af261c72 100644 --- a/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m +++ b/OSX/sec/Security/Regressions/secitem/si-34-cms-timestamp.m @@ -28,6 +28,7 @@ #import #import +#import #import #include #include @@ -37,8 +38,9 @@ #include #include +#define TIMESTAMPING_SUPPORTED TARGET_OS_OSX + #if TARGET_OS_OSX -#include #include #endif @@ -135,7 +137,9 @@ static void test_create_timestamp(void) { #if TIMESTAMPING_SUPPORTED /* Set timestamp context */ - CmsMessageSetTSAContext(encoder, SecCmsTSAGetDefaultContext(NULL)); + CFMutableDictionaryRef context = SecCmsTSAGetDefaultContext(NULL); + CmsMessageSetTSAContext(encoder, context); + CFReleaseNull(context); #endif /* Load content */ 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 index da84844a..26c1aa2c 100644 --- a/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.m +++ b/OSX/sec/Security/Regressions/secitem/si-35-cms-expiration-time.m @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -320,9 +321,8 @@ int si_35_cms_expiration_time(int argc, char *const *argv) { SecCMS_tests(); CMSEncoder_tests(identity); CMSDecoder_tests(); + cleanup_keychain(identity); } - cleanup_keychain(identity); - return 0; } diff --git a/OSX/sec/Security/Regressions/secitem/si-60-cms.c b/OSX/sec/Security/Regressions/secitem/si-60-cms.c index 4ebc3948..7a90e5fa 100644 --- a/OSX/sec/Security/Regressions/secitem/si-60-cms.c +++ b/OSX/sec/Security/Regressions/secitem/si-60-cms.c @@ -44,6 +44,8 @@ #include "shared_regressions.h" +#define VERBOSE_ERRORS 1 + /* Bag Attributes friendlyName: uranusLeaf @@ -1744,7 +1746,21 @@ static void tests(void) ok_status(SecCMSSignDataAndAttributes(identity, test_data, false, message_data, simple_attr), "encode message"); ok_status(SecCMSVerifyCopyDataAndAttributes(message_data, NULL, policy, &trust, &message, &attrs), "decode message again"); CFReleaseNull(trust); +#if VERBOSE_ERRORS + size_t message_len = CFDataGetLength(message_data); + const uint8_t* message_ptr = CFDataGetBytePtr(message_data); + char *message_hex = (char *)calloc(1, 2 * message_len + 1); + for (size_t ix = 0; ix < message_len; ix++) { + snprintf(&message_hex[2*ix], 3, "%02X", message_ptr[ix]); + } + is(CFDictionaryGetCount(attrs), 6, "5 signed attributes + cooked date. \n\tattrs=%@\tmessage_data=%s", attrs, message_hex); + free(message_hex); +#else is(CFDictionaryGetCount(attrs), 6, "5 signed attributes + cooked date"); +#endif + isnt(CFDictionaryGetValue(attrs, kSecCMSSignDate), NULL, "failed to get cooked data from attributes"); + isnt(CFDictionaryGetValue(attrs, kSecCMSAllCerts), NULL, "failed to get cert(s) from attributes"); + isnt(CFDictionaryGetValue(attrs, oid_data), NULL, "failed to get user-defined attribute"); CFReleaseNull(attrs); is(CFEqual(message, test_data), true, "contents preserved"); CFReleaseNull(message); @@ -1939,9 +1955,9 @@ out: int si_60_cms(int argc, char *const *argv) { #if TARGET_OS_IPHONE - plan_tests(43); + plan_tests(46); #else - plan_tests(42); + plan_tests(45); #endif tests(); diff --git a/OSX/sec/Security/Regressions/secitem/si-63-scep.m b/OSX/sec/Security/Regressions/secitem/si-63-scep.m index f9773ca8..f6f9356b 100644 --- a/OSX/sec/Security/Regressions/secitem/si-63-scep.m +++ b/OSX/sec/Security/Regressions/secitem/si-63-scep.m @@ -37,7 +37,7 @@ #include #include "Security_regressions.h" -#include +#include "test/testcert.h" static uint8_t msscep_getcacert[] = { 0x30, 0x82, 0x10, 0x8d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, diff --git a/OSX/sec/Security/Regressions/secitem/si-64-ossl-cms.c b/OSX/sec/Security/Regressions/secitem/si-64-ossl-cms.c index b136beec..0afdc542 100644 --- a/OSX/sec/Security/Regressions/secitem/si-64-ossl-cms.c +++ b/OSX/sec/Security/Regressions/secitem/si-64-ossl-cms.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include 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 80038cc8..fce8b222 100644 --- a/OSX/sec/Security/Regressions/secitem/si-70-sectrust-unified.c +++ b/OSX/sec/Security/Regressions/secitem/si-70-sectrust-unified.c @@ -261,6 +261,29 @@ static void tests(void) ok_status(SecTrustSetNetworkFetchAllowed(trust, allow)); ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow)); is((allow == curAllow), true, "network fetch toggle"); + + /* ensure trust with revocation policy returns the correct status */ + SecPolicyRef revocation = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); + ok_status(SecTrustSetPolicies(trust, revocation)); + ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow)); + is(curAllow, true, "network fetch set for revocation policy"); + + SecPolicyRef basic = SecPolicyCreateBasicX509(); + CFMutableArrayRef policies = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + CFArrayAppendValue(policies, basic); + CFArrayAppendValue(policies, revocation); + ok_status(SecTrustSetPolicies(trust, policies)); + ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow)); + is(curAllow, true, "network fetch set for basic+revocation policy"); + CFReleaseNull(revocation); + CFReleaseNull(basic); + CFReleaseNull(policies); + + revocation = SecPolicyCreateRevocation(kSecRevocationNetworkAccessDisabled); + ok_status(SecTrustSetPolicies(trust, revocation)); + ok_status(SecTrustGetNetworkFetchAllowed(trust, &curAllow)); + is(curAllow, false, "network fetch not set for revocation policy"); + CFReleaseNull(revocation); } /* Test setting OCSP response data */ @@ -336,7 +359,7 @@ errOut: int si_70_sectrust_unified(int argc, char *const *argv) { - plan_tests(27); + plan_tests(36); tests(); return 0; diff --git a/OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.c b/OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.c deleted file mode 100644 index b04c7405..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (c) 2015 Apple Inc. All Rights Reserved. - */ - -#include -#include -#include -#include -#include -#include - -#include "shared_regressions.h" - -#include "si-85-sectrust-ssl-policy.h" - -static void runTestForDictionary (const void *test_key, const void *test_value, void *context) { - CFDictionaryRef test_info = test_value; - CFStringRef test_name = test_key, file = NULL, reason = NULL, expectedResult = NULL, failReason = NULL; - CFURLRef cert_file_url = NULL; - CFDataRef cert_data = NULL; - bool expectTrustSuccess = false; - - SecCertificateRef leaf = NULL, root = NULL; - CFStringRef hostname = NULL; - SecPolicyRef policy = NULL; - SecTrustRef trust = NULL; - CFArrayRef anchor_array = NULL; - CFDateRef date = NULL; - - /* Note that this is built without many of the test convenience macros - * in order to ensure there's only one "test" per test. - */ - - /* get filename in test dictionary */ - file = CFDictionaryGetValue(test_info, CFSTR("Filename")); - require_action_quiet(file, cleanup, fail("%@: Unable to load filename from plist", test_name)); - - /* get leaf certificate from file */ - cert_file_url = CFBundleCopyResourceURL(CFBundleGetMainBundle(), file, CFSTR("cer"), CFSTR("ssl-policy-certs")); - require_action_quiet(cert_file_url, cleanup, fail("%@: Unable to get url for cert file %@", - test_name, file)); - - SInt32 errorCode; - require_action_quiet(CFURLCreateDataAndPropertiesFromResource(NULL, cert_file_url, &cert_data, NULL, NULL, &errorCode), - cleanup, - fail("%@: Could not create cert data for %@ with error %d", - test_name, file, (int)errorCode)); - - /* create certificates */ - leaf = SecCertificateCreateWithData(NULL, cert_data); - root = SecCertificateCreateWithBytes(NULL, _SSLTrustPolicyTestRootCA, sizeof(_SSLTrustPolicyTestRootCA)); - CFRelease(cert_data); - require_action_quiet(leaf && root, cleanup, fail("%@: Unable to create certificates", test_name)); - - /* create policy */ - hostname = CFDictionaryGetValue(test_info, CFSTR("Hostname")); - require_action_quiet(hostname, cleanup, fail("%@: Unable to load hostname from plist", test_name)); - - policy = SecPolicyCreateSSL(true, hostname); - require_action_quiet(policy, cleanup, fail("%@: Unable to create SSL policy with hostname %@", - test_name, hostname)); - - /* create trust ref */ - OSStatus err = SecTrustCreateWithCertificates(leaf, policy, &trust); - CFRelease(policy); - require_noerr_action(err, cleanup, ok_status(err, "SecTrustCreateWithCertificates")); - - /* set anchor in trust ref */ - anchor_array = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks); - require_action_quiet(anchor_array, cleanup, fail("%@: Unable to create anchor array", test_name)); - err = SecTrustSetAnchorCertificates(trust, anchor_array); - require_noerr_action(err, cleanup, ok_status(err, "SecTrustSetAnchorCertificates")); - - /* set date in trust ref to 4 Sep 2015 */ - date = CFDateCreate(NULL, 463079909.0); - require_action_quiet(date, cleanup, fail("%@: Unable to create verify date", test_name)); - err = SecTrustSetVerifyDate(trust, date); - CFRelease(date); - require_noerr_action(err, cleanup, ok_status(err, "SecTrustSetVerifyDate")); - - /* evaluate */ - SecTrustResultType actualResult = 0; - err = SecTrustEvaluate(trust, &actualResult); - require_noerr_action(err, cleanup, ok_status(err, "SecTrustEvaluate")); - bool is_valid = (actualResult == kSecTrustResultProceed || actualResult == kSecTrustResultUnspecified); - if (!is_valid) failReason = SecTrustCopyFailureDescription(trust); - - /* get expected result for test */ - expectedResult = CFDictionaryGetValue(test_info, CFSTR("Result")); - require_action_quiet(expectedResult, cleanup, fail("%@: Unable to get expected result",test_name)); - if (!CFStringCompare(expectedResult, CFSTR("kSecTrustResultUnspecified"), 0) || - !CFStringCompare(expectedResult, CFSTR("kSecTrustResultProceed"), 0)) { - expectTrustSuccess = true; - } - - /* process results */ - if(!CFDictionaryGetValueIfPresent(test_info, CFSTR("Reason"), (const void **)&reason)) { - /* not a known failure */ - ok(is_valid == expectTrustSuccess, "%s %@%@", - expectTrustSuccess ? "REGRESSION" : "SECURITY", - test_name, - failReason ? failReason : CFSTR("")); - } - else if(reason) { - /* known failure */ - todo(CFStringGetCStringPtr(reason, kCFStringEncodingUTF8)); - ok(is_valid == expectTrustSuccess, "%@%@", - test_name, expectTrustSuccess ? (failReason ? failReason : CFSTR("")) : CFSTR(" valid")); - } - else { - fail("%@: unable to get reason for known failure", test_name); - } - -cleanup: - CFReleaseNull(cert_file_url); - CFReleaseNull(leaf); - CFReleaseNull(root); - CFReleaseNull(trust); - CFReleaseNull(anchor_array); - CFReleaseNull(failReason); -} - -static void tests(void) -{ - CFDataRef plist_data = NULL; - CFArrayRef plist = NULL; - CFPropertyListRef tests_dictionary = NULL; - - plist = CFBundleCopyResourceURLsOfType(CFBundleGetMainBundle(), CFSTR("plist"), CFSTR("ssl-policy-certs")); - if (CFArrayGetCount(plist) != 1) { - fail("Incorrect number of plists found in ssl-policy-certs"); - goto exit; - } - - SInt32 errorCode; - if(!CFURLCreateDataAndPropertiesFromResource(NULL, CFArrayGetValueAtIndex(plist, 0), &plist_data, NULL, NULL, &errorCode)) { - fail("Could not create data from plist with error %d", (int)errorCode); - goto exit; - } - - CFErrorRef err; - tests_dictionary = CFPropertyListCreateWithData(NULL, plist_data, kCFPropertyListImmutable, NULL, &err); - if(!tests_dictionary || (CFGetTypeID(tests_dictionary) != CFDictionaryGetTypeID())) { - fail("Failed to create tests dictionary from plist"); - goto exit; - } - - CFDictionaryApplyFunction(tests_dictionary, runTestForDictionary, NULL); - -exit: - CFReleaseNull(plist); - CFReleaseNull(plist_data); - CFReleaseNull(tests_dictionary); -} - -int si_85_sectrust_ssl_policy(int argc, char *const *argv) -{ - plan_tests(37); - - tests(); - - return 0; -} diff --git a/OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.h b/OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.h deleted file mode 100644 index 92c259ba..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-85-sectrust-ssl-policy.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2015 Apple Inc. All Rights Reserved. - */ - -unsigned char _SSLTrustPolicyTestRootCA[987] = { - 0x30, 0x82, 0x03, 0xd7, 0x30, 0x82, 0x02, 0xbf, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8e, 0x31, 0x21, - 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x53, 0x53, 0x4c, - 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, - 0x79, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, - 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, - 0x65, 0x2c, 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, 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, - 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, - 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x30, 0x1e, 0x17, 0x0d, - 0x31, 0x35, 0x30, 0x38, 0x32, 0x30, 0x30, 0x32, 0x30, 0x31, 0x31, 0x39, - 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x38, 0x31, 0x37, 0x30, 0x32, 0x30, - 0x31, 0x31, 0x39, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x21, 0x30, 0x1f, 0x06, - 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x72, - 0x75, 0x73, 0x74, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, - 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 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, 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, 0x31, 0x12, 0x30, - 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, - 0x72, 0x74, 0x69, 0x6e, 0x6f, 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, 0xdf, 0x3b, 0x3f, 0xbc, 0xee, 0xbe, 0x24, 0xf1, 0x44, 0x79, - 0x8b, 0x39, 0x01, 0x3d, 0xd3, 0x9c, 0xe4, 0xf3, 0xd1, 0x2b, 0x43, 0x83, - 0xfe, 0x44, 0xf3, 0xf8, 0xd8, 0xf3, 0xd7, 0xa3, 0xe8, 0x7d, 0xd0, 0x1b, - 0x18, 0x1d, 0x0d, 0x7e, 0x5d, 0x89, 0xb3, 0xc7, 0xe1, 0x3e, 0xbe, 0x6e, - 0xe3, 0xdd, 0x9f, 0x8d, 0x42, 0xd6, 0xb1, 0xd2, 0x63, 0x69, 0x4d, 0x09, - 0xe9, 0x09, 0x21, 0x11, 0x42, 0x1e, 0x78, 0xf7, 0x20, 0x8c, 0x55, 0xf3, - 0x32, 0xeb, 0xd4, 0xed, 0xfd, 0xbd, 0xa7, 0x25, 0x90, 0x0b, 0x24, 0x6a, - 0x86, 0xc1, 0x3f, 0xbc, 0x19, 0xc5, 0x3d, 0x02, 0x52, 0x10, 0xfe, 0xf3, - 0xd3, 0xac, 0x97, 0x2d, 0xf5, 0xa2, 0xf5, 0x92, 0x47, 0xcc, 0x2e, 0x78, - 0x21, 0x6c, 0x57, 0xc8, 0x8d, 0x9e, 0x04, 0x59, 0x83, 0x17, 0xd8, 0x63, - 0x5e, 0xdf, 0xe5, 0x24, 0x3b, 0x34, 0x0b, 0x15, 0x73, 0xec, 0x50, 0x61, - 0x92, 0xef, 0xab, 0x1c, 0xeb, 0x42, 0xdf, 0x76, 0x6b, 0x5f, 0x64, 0xd1, - 0x38, 0xdc, 0xe9, 0x36, 0x82, 0x6a, 0xb3, 0xcc, 0x6f, 0x4a, 0x3b, 0xaf, - 0xd3, 0xf2, 0x1d, 0xf3, 0xf4, 0xd8, 0x0f, 0xa0, 0x5d, 0xf5, 0xdd, 0x21, - 0x92, 0x1f, 0xf1, 0x98, 0x0d, 0x12, 0x72, 0x82, 0x3e, 0xea, 0xc9, 0xf4, - 0x4c, 0x0c, 0x43, 0x3f, 0x1d, 0x18, 0x8a, 0xe5, 0x4d, 0xbd, 0x9f, 0x5b, - 0x11, 0x37, 0xd1, 0x3c, 0xad, 0xdb, 0x72, 0xac, 0x90, 0xd0, 0x72, 0x42, - 0x12, 0xb6, 0xe1, 0x6f, 0x10, 0x77, 0x1e, 0x60, 0x3b, 0x42, 0x31, 0xdc, - 0x9c, 0xdd, 0xfb, 0x36, 0xab, 0x5e, 0x65, 0xf4, 0xab, 0x1c, 0x0d, 0x7f, - 0x1b, 0xff, 0xb0, 0xfa, 0x42, 0x0a, 0x82, 0x2e, 0x43, 0x4c, 0x29, 0x72, - 0x82, 0xcb, 0x61, 0xf4, 0xbf, 0xbb, 0x34, 0x9e, 0x43, 0xac, 0xef, 0x50, - 0xc5, 0xc4, 0x58, 0x7f, 0x65, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, - 0x3e, 0x30, 0x3c, 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, 0x02, 0x84, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, - 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, - 0x07, 0x03, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, - 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x0d, - 0x4e, 0xac, 0x67, 0xc0, 0xe0, 0xfa, 0x66, 0x2e, 0xc3, 0x3e, 0x90, 0x34, - 0x4e, 0xdf, 0x64, 0xfa, 0x06, 0x2e, 0x4e, 0x99, 0xa0, 0x91, 0xf6, 0x96, - 0xe1, 0x41, 0x5d, 0xf6, 0x23, 0x56, 0xbc, 0x64, 0xf9, 0x79, 0xcd, 0x70, - 0xcb, 0xd0, 0xa3, 0x17, 0x87, 0x64, 0x6c, 0x3d, 0x72, 0xca, 0x4b, 0x5e, - 0xae, 0xbf, 0xef, 0x84, 0x04, 0xd4, 0x30, 0xf3, 0xff, 0xbc, 0xa1, 0x28, - 0x2e, 0xd1, 0xfd, 0x43, 0xa3, 0x18, 0xce, 0x89, 0x00, 0x59, 0x3e, 0x6a, - 0x70, 0x73, 0xca, 0x3c, 0x3c, 0xac, 0x6a, 0xfc, 0xb9, 0x5c, 0x79, 0x14, - 0xd7, 0xc8, 0x19, 0x63, 0x6d, 0x37, 0x28, 0xf9, 0x78, 0xd6, 0xb9, 0x2e, - 0xb2, 0x75, 0xd1, 0x05, 0x9c, 0xce, 0xd4, 0x87, 0xe0, 0x92, 0xf7, 0x46, - 0xdf, 0x73, 0x5f, 0x56, 0x1c, 0xff, 0x95, 0x04, 0xa8, 0xb3, 0xa9, 0x4c, - 0x74, 0x07, 0xc6, 0x0a, 0xb9, 0xcd, 0x4c, 0x17, 0x1f, 0x40, 0x73, 0x7d, - 0xb6, 0x73, 0xc7, 0x28, 0x1f, 0x7d, 0x47, 0x86, 0x2a, 0xa2, 0xa1, 0x83, - 0x8b, 0xa4, 0x46, 0x85, 0xeb, 0x19, 0x8c, 0x5e, 0x3c, 0xa4, 0x73, 0x9d, - 0x04, 0x82, 0xe7, 0x0e, 0x2a, 0x3c, 0x83, 0xa1, 0x10, 0xcc, 0x27, 0x81, - 0x1d, 0x3e, 0x1a, 0x7d, 0x1c, 0x4b, 0xfd, 0x45, 0x39, 0xbb, 0x1a, 0xc5, - 0xae, 0x29, 0x22, 0x56, 0x2c, 0x2a, 0x76, 0xc8, 0x26, 0x9f, 0xf0, 0x4f, - 0x48, 0xc8, 0x9d, 0x20, 0xc9, 0x9d, 0x63, 0xc4, 0xe1, 0xad, 0x70, 0xa9, - 0x75, 0xb3, 0xb2, 0xff, 0x35, 0xeb, 0x89, 0x6a, 0x80, 0x11, 0x60, 0x7d, - 0xab, 0xd5, 0xd2, 0xa4, 0xd3, 0x1c, 0x34, 0x21, 0xdf, 0xbe, 0x0a, 0x4f, - 0xcc, 0x79, 0xca, 0x88, 0x81, 0x2b, 0x06, 0x11, 0x1f, 0x31, 0x22, 0x43, - 0x93, 0x76, 0x2c, 0x90, 0x5b, 0x5f, 0x42, 0x3e, 0x97, 0x61, 0x4b, 0xcc, - 0x22, 0x6e, 0xf0 -}; 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 deleted file mode 100644 index 130ae6dd..00000000 --- a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.m +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved. - */ - -#include -#import - -#import -#import - -#include -#include -#include -#include -#include -#include - -#include "shared_regressions.h" - -#include "si-87-sectrust-name-constraints.h" - - -static void tests(void) { - 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; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017 - - require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut, - fail("Failed to create root cert")); - require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, - fail("Failed to create subca cert")); - require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut, - 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")); - 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"); - - 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 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 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); - CFReleaseNull(subca); - CFReleaseNull(leaf1); - CFReleaseNull(leaf2); - CFReleaseNull(policy); - CFReleaseNull(trust); -} - -/* MARK: BetterTLS tests */ -NSString *kSecTrustTestNameConstraintsResources = @"si-87-sectrust-name-constraints"; -NSString *kSecTrustTestCertificates = @"TestCertificates"; -NSString *kSecTrustTestIPAddress = @"52.20.118.238"; -NSString *kSecTrustTestDNSAddress = @"test.nameconstraints.bettertls.com"; -NSString *kSecTrustTestID = @"id"; -NSString *kSecTrustTestDNSResult = @"dns"; -NSString *kSecTrustTestIPResult = @"ip"; -NSString *kSecTrustTestExpect = @"expect"; -NSString *kSecTrustTestExpectFailure = @"ERROR"; -NSString *kSecTrustTestExpectSuccess = @"OK"; -NSString *kSecTrustTestExpectMaybeSuccess = @"WEAK-OK"; - -static NSArray *anchors = nil; -static NSURL *tmpCertsDir = nil; - -static NSArray *getTestsArray(void) { - NSURL *testPlist = nil; - NSDictionary *testsDict = nil; - NSArray *testsArray = nil; - - testPlist = [[NSBundle mainBundle] URLForResource:@"debugging" withExtension:@"plist" - subdirectory:kSecTrustTestNameConstraintsResources]; - if (!testPlist) { - testPlist = [[NSBundle mainBundle] URLForResource:@"expects" withExtension:@"plist" - subdirectory:kSecTrustTestNameConstraintsResources]; - } - require_action_quiet(testPlist, exit, - fail("Failed to get tests plist from %@", kSecTrustTestNameConstraintsResources)); - testsDict = [NSDictionary dictionaryWithContentsOfURL:testPlist]; - require_action_quiet(testsDict, exit, fail("Failed to decode tests plist into dictionary")); - - testsArray = testsDict[@"expects"]; - require_action_quiet(testsArray, exit, fail("Failed to get expects array from test dictionary")); - require_action_quiet([testsArray isKindOfClass:[NSArray class]], exit, fail("expected array of tests")); - -exit: - return testsArray; -} - -static NSFileHandle *openFileForWriting(const char *filename) { - NSFileHandle *fileHandle = NULL; - NSURL *file = [NSURL URLWithString:[NSString stringWithCString:filename encoding:NSUTF8StringEncoding] relativeToURL:tmpCertsDir]; - int fd; - off_t off; - fd = open([file fileSystemRepresentation], O_RDWR | O_CREAT | O_TRUNC, 0644); - if (fd < 0 || (off = lseek(fd, 0, SEEK_SET)) < 0) { - fail("unable to open file for archive"); - } - if (fd >= 0) { - close(fd); - } - - NSError *error; - fileHandle = [NSFileHandle fileHandleForWritingToURL:file error:&error]; - if (!fileHandle) { - fail("unable to get file handle for %@\n\terror:%@", file, error); - } - - return fileHandle; -} - -static BOOL -extract(NSURL *archive) { - BOOL result = NO; - int r; - struct archive_entry *entry; - - struct archive *a = archive_read_new(); - archive_read_support_compression_all(a); - archive_read_support_format_tar(a); - r = archive_read_open_filename(a, [archive fileSystemRepresentation], 16384); - if (r != ARCHIVE_OK) { - fail("unable to open archive"); - goto exit; - } - - while((r = archive_read_next_header(a, &entry)) == ARCHIVE_OK) { - @autoreleasepool { - const char *filename = archive_entry_pathname(entry); - NSFileHandle *fh = openFileForWriting(filename); - ssize_t size = 0; - size_t bufsize = 4192; - uint8_t *buf = calloc(bufsize, 1); - for (;;) { - size = archive_read_data(a, buf, bufsize); - if (size < 0) { - fail("failed to read %s from archive", filename); - [fh closeFile]; - goto exit; - } - if (size == 0) { - break; - } - [fh writeData:[NSData dataWithBytes:buf length:size]]; - } - free(buf); - [fh closeFile]; - } - } - if (r != ARCHIVE_EOF) { - fail("unable to read archive header"); - } else { - result = YES; - } - -exit: - archive_read_finish(a); - return result; -} - -static BOOL untar_test_certs(void) { - NSError *error = nil; - tmpCertsDir = [[NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES] URLByAppendingPathComponent:kSecTrustTestNameConstraintsResources isDirectory:YES]; - - if (![[NSFileManager defaultManager] createDirectoryAtURL:tmpCertsDir - withIntermediateDirectories:NO - attributes:NULL - error:&error]) { - fail("unable to create temporary cert directory: %@", error); - return NO; - } - - NSURL *certs_tar = [[NSBundle mainBundle] URLForResource:kSecTrustTestCertificates withExtension:nil - subdirectory:kSecTrustTestNameConstraintsResources]; - if(!extract(certs_tar)) { - return NO; - } - - return YES; -} - -static BOOL extractLeaf(NSString *filename, NSMutableArray *certs) { - NSString *fullFilename = [NSString stringWithFormat:@"%@.cer", filename]; - NSURL *leafURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename]; - if (!leafURL) { - fail("Failed to get leaf certificate for test id %@", filename); - return NO; - } - NSData *leafData = [NSData dataWithContentsOfURL:leafURL]; - if (!leafData) { - fail("Failed to get leaf certificate data for URL %@", leafURL); - return NO; - } - SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)leafData); - if (!leafData) { - fail("Failed to create leaf cert for %@", leafURL); - return NO; - } - [certs addObject:(__bridge id)cert]; - CFReleaseNull(cert); - return YES; -} - -static BOOL extractChain(NSString *filename, NSMutableArray *certs) { - NSString *fullFilename = [NSString stringWithFormat:@"%@.chain", filename]; - NSURL *chainURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename]; - if (!chainURL) { - fail("Failed to get chain URL for %@", filename); - return NO; - } - NSString *chain = [NSString stringWithContentsOfURL:chainURL encoding:NSUTF8StringEncoding error:nil]; - if (!chain) { - fail("Failed to get chain for %@", chainURL); - return NO; - } - - NSString *pattern = @"-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----\n"; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern - options:NSRegularExpressionDotMatchesLineSeparators|NSRegularExpressionUseUnixLineSeparators - error:nil]; - [regex enumerateMatchesInString:chain options:0 range:NSMakeRange(0, [chain length]) - usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { - NSString *certPEMString = [chain substringWithRange:[result range]]; - NSData *certPEMData = [certPEMString dataUsingEncoding:NSUTF8StringEncoding]; - SecCertificateRef cert = SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)certPEMData); - [certs addObject:(__bridge id)cert]; - CFReleaseNull(cert); - }]; - return YES; -} - -static BOOL getAnchor(void) { - NSURL *rootURL = [[NSBundle mainBundle] URLForResource:@"root" withExtension:@"cer" - subdirectory:kSecTrustTestNameConstraintsResources]; - if (!rootURL) { - fail("Failed to get root cert"); - return NO; - } - NSData *rootData = [NSData dataWithContentsOfURL:rootURL]; - SecCertificateRef root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)rootData); - if (!root) { - fail("failed to create root cert"); - return NO; - } - anchors = [NSArray arrayWithObject:(__bridge id)root]; - CFReleaseNull(root); - return YES; -} - -static BOOL testTrust(NSArray *certs, NSString *hostname) { - if (!anchors && !getAnchor()) { - return NO; - } - BOOL result = NO; - SecPolicyRef policy = SecPolicyCreateSSL(true, (__bridge CFStringRef)hostname); - SecTrustRef trust = NULL; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:531900000.0]; /* November 8, 2017 at 10:00:00 PM PST */ - require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), exit, - fail("Failed to create trust ref")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), exit, - fail("Failed to add anchor")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), exit, - fail("Failed to set verify date")); -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - result = SecTrustEvaluateWithError(trust, nil); -#pragma clang diagnostic pop - -exit: - CFReleaseNull(policy); - CFReleaseNull(trust); - return result; -} - -void (^runNameConstraintsTestForObject)(id, NSUInteger, BOOL *) = -^(NSDictionary *testDict, NSUInteger idx, BOOL *stop) { - @autoreleasepool { - /* Get the certificates */ - NSNumber *testNum = testDict[kSecTrustTestID]; - NSString *fileName = [NSString stringWithFormat:@"%@",testNum]; - NSMutableArray *certificates = [NSMutableArray array]; - if (!extractLeaf(fileName, certificates) || !extractChain(fileName, certificates)) { - return; - } - - /* Test DNS address */ - NSDictionary *dnsDict = testDict[kSecTrustTestDNSResult]; - BOOL result = testTrust(certificates, kSecTrustTestDNSAddress); - NSString *dnsExpectedResult = dnsDict[kSecTrustTestExpect]; - if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectFailure]) { - is(result, NO, - "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result); - } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) { - is(result, YES, - "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result); - } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) { - /* These are "OK" but it's acceptable to reject them */ - pass(); - } - - /* Test IP address */ - NSDictionary *ipDict = testDict[kSecTrustTestIPResult]; - result = testTrust(certificates, kSecTrustTestIPAddress); - NSString *ipExpectedResult = ipDict[kSecTrustTestExpect]; - if ([ipExpectedResult isEqualToString:kSecTrustTestExpectFailure]) { - is(result, NO, - "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result); - } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) { - is(result, YES, - "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result); - } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) { - /* These are "OK" but it's acceptable to reject them */ - pass(); - } - } -}; - -static void cleanup(NSURL *tmpDir) { - [[NSFileManager defaultManager] removeItemAtURL:tmpDir error:nil]; -} - -int si_87_sectrust_name_constraints(int argc, char *const *argv) -{ - NSArray *testsArray = getTestsArray(); - plan_tests(3 + (int)(2 * [testsArray count])); - tests(); - - if(untar_test_certs()) { - [testsArray enumerateObjectsUsingBlock:runNameConstraintsTestForObject]; - } - cleanup(tmpCertsDir); - - return 0; -} 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 dbe3b245..d8871b43 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 @@ -29,6 +29,7 @@ #include #include #include +#include #include #if TARGET_OS_OSX diff --git a/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c b/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c index 18611e44..6aed79c3 100644 --- a/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c +++ b/OSX/sec/Security/Regressions/secitem/si-95-cms-basic.c @@ -49,7 +49,7 @@ #include /* These tests are essentially the same as cms_01_basic in the OS X - * libsecurity_smime_regressions. They are not unified into a single + * libsecurity_cms_regressions. They are not unified into a single * test because libsecurity_smime diverges so much between the platforms * that unifying the tests makes every third line a TARGET macro. */ diff --git a/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c b/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c index ec8251e0..f3de052c 100644 --- a/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c +++ b/OSX/sec/Security/Regressions/secitem/si_77_SecAccessControl.c @@ -96,7 +96,11 @@ static void tests(void) CFReleaseNull(acl); // ACL with protection and flags +#if TARGET_OS_OSX + acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlBiometryAny | kSecAccessControlDevicePasscode | kSecAccessControlWatch | kSecAccessControlAnd | kSecAccessControlApplicationPassword, &error); +#else acl = SecAccessControlCreateWithFlags(allocator, protection, kSecAccessControlBiometryAny | kSecAccessControlDevicePasscode | kSecAccessControlAnd | kSecAccessControlApplicationPassword, &error); +#endif ok(acl != NULL, "SecAccessControlCreateWithFlags: %@", error); CFReleaseNull(error); CFReleaseNull(acl); @@ -161,6 +165,12 @@ static void tests(void) CFReleaseNull(error); CFReleaseNull(policy); + // Watch constraint + aclConstraint = SecAccessConstraintCreateWatch(allocator); + ok(aclConstraint != NULL && isDictionary(aclConstraint), "SecAccessConstraintCreateWatch"); + is(CFDictionaryGetValue(aclConstraint, CFSTR(kACMKeyAclConstraintWatch)), kCFBooleanTrue, "SecAccessConstraintCreateWatch"); + CFReleaseNull(aclConstraint); + // Passcode constraint SecAccessConstraintRef passcode = SecAccessConstraintCreatePasscode(allocator); ok(passcode != NULL && isDictionary(passcode), "SecAccessConstraintCreatePasscode"); @@ -509,9 +519,9 @@ static CFDataRef kc_copy_constraints_data(SecAccessControlRef access_control, CF int si_77_SecAccessControl(int argc, char *const *argv) { #if LA_CONTEXT_IMPLEMENTED && TARGET_HAS_KEYSTORE - plan_tests(71); + plan_tests(73); #else - plan_tests(63); + plan_tests(65); #endif tests(); diff --git a/OSX/sec/Security/SecAccessControl.m b/OSX/sec/Security/SecAccessControl.m index 1f172f78..849426be 100644 --- a/OSX/sec/Security/SecAccessControl.m +++ b/OSX/sec/Security/SecAccessControl.m @@ -27,10 +27,10 @@ #include #include -#include "SecAccessControl.h" -#include "SecAccessControlPriv.h" -#include "SecItem.h" -#include "SecItemPriv.h" +#include +#include +#include +#include #include #include #include @@ -186,6 +186,14 @@ SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef allocator, CF CFReleaseNull(constraint); } +#if TARGET_OS_OSX + if (flags & kSecAccessControlWatch) { + require_quiet(constraint = SecAccessConstraintCreateWatch(allocator), errOut); + CFArrayAppendValue(constraints, constraint); + CFReleaseNull(constraint); + } +#endif + #pragma clang diagnostic pop if (flags & kSecAccessControlApplicationPassword) { @@ -316,6 +324,10 @@ SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef return SecAccessConstraintCreateBiometryCurrentSet(allocator, catacombUUID, bioDbHash); } +SecAccessConstraintRef SecAccessConstraintCreateWatch(CFAllocatorRef allocator) { + return CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclConstraintWatch), kCFBooleanTrue, NULL); +} + static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRef allocator, size_t numRequired, CFArrayRef constraints, CFErrorRef *error) { CFNumberRef k = CFNumberCreateWithCFIndex(allocator, numRequired); CFMutableDictionaryRef kofn = CFDictionaryCreateMutableForCFTypesWith(allocator, CFSTR(kACMKeyAclParamKofN), k, NULL); @@ -325,7 +337,7 @@ static SecAccessConstraintRef SecAccessConstraintCreateValueOfKofN(CFAllocatorRe constraint parameters, but we might err-out if some parameter is found, since we cannot propagate parameteres into k-of-n dictionary. */ const CFTypeRef keysToCopy[] = { CFSTR(kACMKeyAclConstraintBio), CFSTR(kACMKeyAclConstraintPolicy), - CFSTR(kACMKeyAclConstraintUserPasscode) }; + CFSTR(kACMKeyAclConstraintUserPasscode), CFSTR(kACMKeyAclConstraintWatch) }; SecAccessConstraintRef constraint; CFArrayForEachC(constraints, constraint) { require_quiet(isDictionary(constraint), errOut); diff --git a/OSX/sec/Security/SecAccessControlExports.exp-in b/OSX/sec/Security/SecAccessControlExports.exp-in index f287ba95..53aa6419 100644 --- a/OSX/sec/Security/SecAccessControlExports.exp-in +++ b/OSX/sec/Security/SecAccessControlExports.exp-in @@ -9,6 +9,7 @@ _SecAccessConstraintCreatePasscode _SecAccessConstraintCreatePolicy _SecAccessConstraintCreateTouchIDAny _SecAccessConstraintCreateTouchIDCurrentSet +_SecAccessConstraintCreateWatch _SecAccessControlAddConstraintForOperation _SecAccessControlCopyData _SecAccessControlCreate diff --git a/OSX/sec/Security/SecAccessControlPriv.h b/OSX/sec/Security/SecAccessControlPriv.h index 9a57a15a..efb0adea 100644 --- a/OSX/sec/Security/SecAccessControlPriv.h +++ b/OSX/sec/Security/SecAccessControlPriv.h @@ -68,6 +68,9 @@ SecAccessConstraintRef SecAccessConstraintCreateBiometryCurrentSet(CFAllocatorRe SecAccessConstraintRef SecAccessConstraintCreateTouchIDCurrentSet(CFAllocatorRef allocator, CFDataRef catacombUUID, CFDataRef bioDbHash) API_DEPRECATED_WITH_REPLACEMENT("SecAccessConstraintCreateBiometryCurrentSet", macos(10.12.1, 10.13.4), ios(9.0, 11.3)); +/*! Creates constraint which requires watch verification. */ +SecAccessConstraintRef SecAccessConstraintCreateWatch(CFAllocatorRef allocator) API_AVAILABLE(macos(10.14), ios(12.0)); + /*! Creates constraint composed of other constraints. @param numRequired Number of constraints required to be satisfied in order to consider overal constraint satisfied. @param constraints Array of constraints to be chosen from. diff --git a/OSX/sec/Security/SecBackupKeybagEntry.m b/OSX/sec/Security/SecBackupKeybagEntry.m index 8c77c759..558c4e44 100644 --- a/OSX/sec/Security/SecBackupKeybagEntry.m +++ b/OSX/sec/Security/SecBackupKeybagEntry.m @@ -97,14 +97,21 @@ // used by saveToDatabaseWithConnection to write to db - (NSDictionary*) sqlValues { return @{ - @"publickey": self.publickey, - @"publickeyHash": self.publickeyHash, - @"musr": self.musr + @"publickey": [self.publickey base64EncodedStringWithOptions:0], + @"publickeyHash": [self.publickeyHash base64EncodedStringWithOptions:0], + @"musr": [self.musr base64EncodedStringWithOptions:0], }; } -+ (instancetype) fromDatabaseRow: (NSDictionary*) row { - return [[SecBackupKeybagEntry alloc] initWithPublicKey: row[@"publickey"] publickeyHash: row[@"publickeyHash"] user: row[@"musr"]]; ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + NSData *publicKey = row[@"publickey"].asBase64DecodedData; + NSData *publickeyHash = row[@"publickeyHash"].asBase64DecodedData; + NSData *musr = row[@"musr"].asBase64DecodedData; + if (publicKey == NULL || publickeyHash == NULL || musr == NULL) { + return nil; + } + + return [[SecBackupKeybagEntry alloc] initWithPublicKey:publicKey publickeyHash:publickeyHash user:musr]; } @end diff --git a/OSX/sec/Security/SecCMS.c b/OSX/sec/Security/SecCMS.c index ba1ee699..5ae8dbf4 100644 --- a/OSX/sec/Security/SecCMS.c +++ b/OSX/sec/Security/SecCMS.c @@ -31,7 +31,7 @@ #include #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #define ENABLE_CMS 0 #else #define ENABLE_CMS 1 @@ -56,7 +56,7 @@ #include #include -#include "SecCMS.h" +#include #include diff --git a/OSX/sec/Security/SecCTKKey.m b/OSX/sec/Security/SecCTKKey.m index 44e1dd81..5ebebb06 100644 --- a/OSX/sec/Security/SecCTKKey.m +++ b/OSX/sec/Security/SecCTKKey.m @@ -30,11 +30,13 @@ #include #include #include +#include #include #include #include -#include +#include #include +#include "OSX/sec/Security/SecItemShim.h" #include "SecECKey.h" #include "SecRSAKey.h" @@ -73,7 +75,7 @@ static CFIndex SecCTKGetAlgorithmID(SecKeyRef key) { static SecItemAuthResult SecCTKProcessError(CFStringRef operation, TKTokenRef token, CFDataRef object_id, CFArrayRef *ac_pairs, CFErrorRef *error) { if (CFEqualSafe(CFErrorGetDomain(*error), CFSTR(kTKErrorDomain)) && - CFErrorGetCode(*error) == kTKErrorCodeAuthenticationFailed && + CFErrorGetCode(*error) == kTKErrorCodeAuthenticationNeeded && operation != NULL) { CFDataRef access_control = TKTokenCopyObjectAccessControl(token, object_id, error); if (access_control != NULL) { @@ -384,6 +386,7 @@ static SecKeyRef SecCTKKeyCreateDuplicate(SecKeyRef key) { } SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttributes, CFErrorRef *error) { + SecKeyRef result = NULL; SecKeyRef key = SecKeyCreate(allocator, &kSecCTKKeyDescriptor, 0, 0, 0); SecCTKKeyData *kd = key->key; kd->token = CFRetainSafe(CFDictionaryGetValue(refAttributes, kSecUseToken)); @@ -405,40 +408,48 @@ SecKeyRef SecKeyCreateCTKKey(CFAllocatorRef allocator, CFDictionaryRef refAttrib NULL, }; + CFMutableDictionaryRef attrs = NULL; if (kd->token == NULL) { - kd->token = SecCTKKeyCopyToken(key, error); + require_quiet(kd->token = SecCTKKeyCopyToken(key, error), out); if (kd->token != NULL) { - CFMutableDictionaryRef attrs = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, kd->attributes.dictionary); + attrs = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, kd->attributes.dictionary); CFAssignRetained(kd->object_id, TKTokenCreateOrUpdateObject(kd->token, kd->object_id, attrs, error)); + require_quiet(kd->object_id, out); CFDictionaryForEach(attrs, ^(const void *key, const void *value) { CFDictionaryAddValue(SecCFDictionaryCOWGetMutable(&kd->attributes), key, value); }); + + CFTypeRef accc = CFDictionaryGetValue(kd->attributes.dictionary, kSecAttrAccessControl); + if (accc && CFDataGetTypeID() == CFGetTypeID(accc)) { + SecAccessControlRef ac = SecAccessControlCreateFromData(kCFAllocatorDefault, accc, error); + require_quiet(ac, out); + CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrAccessControl, ac); + CFRelease(ac); + } CFDictionaryRemoveValue(SecCFDictionaryCOWGetMutable(&kd->attributes), kSecAttrTokenOID); - CFReleaseSafe(attrs); - } - - if (kd->token == NULL || kd->object_id == NULL) { - CFReleaseNull(key); } + require_quiet(kd->token != NULL && kd->object_id != NULL, out); } - if (key != NULL) { - for (const CFStringRef **attrName = &numericAttributes[0]; *attrName != NULL; attrName++) { - CFTypeRef value = CFDictionaryGetValue(kd->attributes.dictionary, **attrName); - if (value != NULL && CFGetTypeID(value) == CFNumberGetTypeID()) { - CFIndex number; - if (CFNumberGetValue(value, kCFNumberCFIndexType, &number)) { - CFStringRef newValue = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), (long)number); - if (newValue != NULL) { - CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), **attrName, newValue); - CFRelease(newValue); - } + for (const CFStringRef **attrName = &numericAttributes[0]; *attrName != NULL; attrName++) { + CFTypeRef value = CFDictionaryGetValue(kd->attributes.dictionary, **attrName); + if (value != NULL && CFGetTypeID(value) == CFNumberGetTypeID()) { + CFIndex number; + if (CFNumberGetValue(value, kCFNumberCFIndexType, &number)) { + CFStringRef newValue = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%ld"), (long)number); + if (newValue != NULL) { + CFDictionarySetValue(SecCFDictionaryCOWGetMutable(&kd->attributes), **attrName, newValue); + CFRelease(newValue); } } } } + result = (SecKeyRef)CFRetain(key); - return key; +out: + CFReleaseSafe(attrs); + CFReleaseSafe(key); + return result; } OSStatus SecCTKKeyGeneratePair(CFDictionaryRef parameters, SecKeyRef *publicKey, SecKeyRef *privateKey) { @@ -510,6 +521,10 @@ SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef // [[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' }; + static const uint8_t casdObjectIDBytes[] = { 0x04, 27, 'c', 'o', 'm', '.', 'a', 'p', 'p', 'l', 'e', '.', 's', 'e', 'c', 'e', 'l', 'e', 'm', 't', 'o', 'k', 'e', 'n', '.', 'c', 'a', 's', 'd' }; + + CFStringRef token = kSecAttrTokenIDAppleKeyStore; + switch (keyType) { case kSecKeyAttestationKeyTypeSIK: object_id = CFDataCreate(kCFAllocatorDefault, sikObjectIDBytes, sizeof(sikObjectIDBytes)); @@ -523,6 +538,10 @@ SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef case kSecKeyAttestationKeyTypeUIKProposed: object_id = CFDataCreate(kCFAllocatorDefault, uikProposedObjectIDBytes, sizeof(uikProposedObjectIDBytes)); break; + case kSecKeyAttestationKeyTypeSecureElement: + object_id = CFDataCreate(kCFAllocatorDefault, casdObjectIDBytes, sizeof(casdObjectIDBytes)); + token = kSecAttrTokenIDSecureElement; + break; default: SecError(errSecParam, error, CFSTR("unexpected attestation key type %d"), (int)keyType); goto out; @@ -530,7 +549,7 @@ SecKeyRef SecKeyCopyAttestationKey(SecKeyAttestationKeyType keyType, CFErrorRef attributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, kSecAttrTokenOID, object_id, - kSecAttrTokenID, kSecAttrTokenIDAppleKeyStore, + kSecAttrTokenID, token, NULL); key = SecKeyCreateCTKKey(kCFAllocatorDefault, attributes, error); diff --git a/OSX/sec/Security/SecCertificate.c b/OSX/sec/Security/SecCertificate.c index a74f1f99..0850a4b7 100644 --- a/OSX/sec/Security/SecCertificate.c +++ b/OSX/sec/Security/SecCertificate.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -49,11 +49,11 @@ #include #include #include -#include "SecBasePriv.h" +#include #include "SecRSAKey.h" #include "SecFramework.h" -#include "SecItem.h" -#include "SecItemPriv.h" +#include +#include #include "SecSignatureVerificationSupport.h" #include #include @@ -82,6 +82,9 @@ #define MIN_STRONG_RSA_KEY_SIZE 256 // 2048-bit #define MIN_STRONG_EC_KEY_SIZE 28 // 224-bit +#define IPv4ADDRLEN 4 // 4 octets +#define IPv6ADDRLEN 16 // 16 octets + typedef struct SecCertificateExtension { DERItem extnID; bool critical; @@ -173,6 +176,7 @@ struct __SecCertificate { /* All other (non known) extensions. The _extensions array is malloced. */ CFIndex _extensionCount; SecCertificateExtension *_extensions; + CFIndex _unparseableKnownExtensionIndex; /* Optional cached fields. */ SecKeyRef _pubKey; @@ -212,6 +216,8 @@ SEC_CONST_DECL (kSecPropertyTypeData, "data"); SEC_CONST_DECL (kSecPropertyTypeString, "string"); SEC_CONST_DECL (kSecPropertyTypeURL, "url"); SEC_CONST_DECL (kSecPropertyTypeDate, "date"); +SEC_CONST_DECL (kSecPropertyTypeArray, "array"); +SEC_CONST_DECL (kSecPropertyTypeNumber, "number"); /* Extension parsing routine. */ typedef bool (*SecCertificateExtensionParser)(SecCertificateRef certificate, @@ -633,21 +639,23 @@ static bool SecCEPKeyUsage(SecCertificateRef certificate, DERReturn drtn = DERDecodeItem(&extn->extnValue, &bitStringContent); require_noerr_quiet(drtn, badDER); require_quiet(bitStringContent.tag == ASN1_BIT_STRING, badDER); + /* check that there's no extra bytes at the end */ + require_quiet(bitStringContent.content.data + bitStringContent.content.length == extn->extnValue.data + extn->extnValue.length, badDER); DERSize len = bitStringContent.content.length - 1; require_quiet(len == 1 || len == 2, badDER); DERByte numUnusedBits = bitStringContent.content.data[0]; require_quiet(numUnusedBits < 8, badDER); - /* Flip the bits in the bit string so the first bit in the lsb. */ - uint_fast16_t bits = 8 * len - numUnusedBits; - uint_fast16_t value = bitStringContent.content.data[1]; - uint_fast16_t mask; + /* Flip the bits in the bit string so the first bit is the lsb. */ + uint16_t bits = 8 * len - numUnusedBits; + uint16_t value = bitStringContent.content.data[1]; + uint16_t mask; if (len > 1) { value = (value << 8) + bitStringContent.content.data[2]; mask = 0x8000; } else { mask = 0x80; } - uint_fast16_t ix; + uint16_t ix; for (ix = 0; ix < bits; ++ix) { if (value & mask) { keyUsage |= 1 << ix; @@ -867,7 +875,7 @@ static bool SecCEPCrlDistributionPoints(SecCertificateRef certificate, } } if (dp.cRLIssuer.data) { - drtn = SecCertificateParseGeneralNames(&dp.cRLIssuer, &certificate->_crlDistributionPoints, + drtn = parseGeneralNamesContent(&dp.cRLIssuer, &certificate->_crlDistributionPoints, appendCRLDPFromGeneralNames); require_noerr_quiet(drtn, badDER); } @@ -1073,7 +1081,19 @@ badDER: static bool SecCEPExtendedKeyUsage(SecCertificateRef certificate, const SecCertificateExtension *extn) { secdebug("cert", "critical: %s", extn->critical ? "yes" : "no"); + DERSequence ekuSeq; + DERTag ekuTag; + DERReturn drtn = DERDecodeSeqInit(&extn->extnValue, &ekuTag, &ekuSeq); + require_quiet((drtn == DR_Success) && (ekuTag == ASN1_CONSTR_SEQUENCE), badDER); + DERDecodedInfo ekuContent; + while ((drtn = DERDecodeSeqNext(&ekuSeq, &ekuContent)) == DR_Success) { + require_quiet(ekuContent.tag == ASN1_OBJECT_ID, badDER); + } + require_quiet(drtn == DR_EndOfSequence, badDER); return true; +badDER: + secwarning("Invalidate EKU Extension"); + return false; } /* @@ -1335,10 +1355,17 @@ CFGiblisWithFunctions(SecCertificate, NULL, NULL, SecCertificateDestroy, SecCert static bool isAppleExtensionOID(const DERItem *extnID) { - static const uint8_t appleExtension[8] = { 0x2a,0x86,0x48,0x86,0xf7,0x63,0x64,0x06 }; - return (extnID && extnID->data && - extnID->length > sizeof(appleExtension) && - !memcmp(extnID->data, appleExtension, sizeof(appleExtension))); + static const uint8_t appleExtensionArc[8] = { 0x2a,0x86,0x48,0x86,0xf7,0x63,0x64,0x06 }; + static const uint8_t appleComponentExtensionArc[8] = { 0x2a,0x86,0x48,0x86,0xf7,0x63,0x64,0x0b }; + static const uint8_t appleSigningExtensionArc[8] = { 0x2a,0x86,0x48,0x86,0xf7,0x63,0x64,0x0c }; + static const uint8_t appleEncryptionExtensionArc[8] = { 0x2a,0x86,0x48,0x86,0xf7,0x63,0x64,0x0d }; + if (!extnID && !extnID->data && extnID->length <= sizeof(appleExtensionArc)) { + return false; + } + return (!memcmp(extnID->data, appleExtensionArc, sizeof(appleExtensionArc)) || + !memcmp(extnID->data, appleComponentExtensionArc, sizeof(appleComponentExtensionArc)) || + !memcmp(extnID->data, appleSigningExtensionArc, sizeof(appleSigningExtensionArc)) || + !memcmp(extnID->data, appleEncryptionExtensionArc, sizeof(appleEncryptionExtensionArc))); } /* Given the contents of an X.501 Name return the contents of a normalized @@ -1739,19 +1766,19 @@ static bool SecCertificateParse(SecCertificateRef certificate) certificate->_subjectUniqueID = tbsCert.subjectID; /* Extensions. */ + certificate->_unparseableKnownExtensionIndex = kCFNotFound; if (tbsCert.extensions.length) { CFIndex extensionCount = 0; DERSequence derSeq; DERTag tag; - drtn = DERDecodeSeqInit(&tbsCert.extensions, &tag, - &derSeq); + drtn = DERDecodeSeqInit(&tbsCert.extensions, &tag, &derSeq); require_noerr_quiet(drtn, badCert); require_quiet(tag == ASN1_CONSTR_SEQUENCE, badCert); DERDecodedInfo currDecoded; while ((drtn = DERDecodeSeqNext(&derSeq, &currDecoded)) == DR_Success) { #if 0 -/* ! = MUST recognize ? = SHOULD recognize -*/ + /* ! = MUST recognize ? = SHOULD recognize + */ KnownExtension _subjectKeyID; /* ?SubjectKeyIdentifier id-ce 14 */ KnownExtension _keyUsage; /* !KeyUsage id-ce 15 */ @@ -1782,8 +1809,7 @@ static bool SecCertificateParse(SecCertificateRef certificate) /* Put some upper limit on the number of extensions allowed. */ require_quiet(extensionCount < 10000, badCert); certificate->_extensionCount = extensionCount; - certificate->_extensions = - malloc(sizeof(SecCertificateExtension) * (extensionCount > 0 ? extensionCount : 1)); + certificate->_extensions = malloc(sizeof(SecCertificateExtension) * (extensionCount > 0 ? extensionCount : 1)); require_quiet(certificate->_extensions, badCert); CFIndex ix = 0; @@ -1791,40 +1817,41 @@ static bool SecCertificateParse(SecCertificateRef certificate) require_noerr_quiet(drtn, badCert); for (ix = 0; ix < extensionCount; ++ix) { drtn = DERDecodeSeqNext(&derSeq, &currDecoded); - require_quiet(drtn == DR_Success || - (ix == extensionCount - 1 && drtn == DR_EndOfSequence), badCert); + require_quiet(drtn == DR_Success || (ix == extensionCount - 1 && drtn == DR_EndOfSequence), badCert); require_quiet(currDecoded.tag == ASN1_CONSTR_SEQUENCE, badCert); DERExtension extn; drtn = DERParseSequenceContent(&currDecoded.content, - DERNumExtensionItemSpecs, DERExtensionItemSpecs, - &extn, sizeof(extn)); + DERNumExtensionItemSpecs, DERExtensionItemSpecs, + &extn, sizeof(extn)); require_noerr_quiet(drtn, badCert); /* Copy stuff into certificate->extensions[ix]. */ certificate->_extensions[ix].extnID = extn.extnID; require_noerr_quiet(drtn = DERParseBooleanWithDefault(&extn.critical, false, - &certificate->_extensions[ix].critical), badCert); + &certificate->_extensions[ix].critical), badCert); certificate->_extensions[ix].extnValue = extn.extnValue; - SecCertificateExtensionParser parser = - (SecCertificateExtensionParser)CFDictionaryGetValue( - sExtensionParsers, &certificate->_extensions[ix].extnID); - if (parser) { - /* Invoke the parser. If the extension is critical and the + SecCertificateExtensionParser parser = + (SecCertificateExtensionParser)CFDictionaryGetValue(sExtensionParsers, &certificate->_extensions[ix].extnID); + if (parser) { + /* Invoke the parser. If the extension is critical and the * parser fails, fail the cert. */ - require_quiet(parser(certificate, &certificate->_extensions[ix]) || - !certificate->_extensions[ix].critical, badCert); - } else if (certificate->_extensions[ix].critical) { - if (isAppleExtensionOID(&extn.extnID)) { - continue; - } - secdebug("cert", "Found unknown critical extension"); - certificate->_foundUnknownCriticalExtension = true; - } else { - secdebug("cert", "Found unknown non critical extension"); - } - } - } - checkForMissingRevocationInfo(certificate); + bool parseResult = parser(certificate, &certificate->_extensions[ix]); + if (!parseResult) { + certificate->_unparseableKnownExtensionIndex = ix; + } + require_quiet(parseResult || !certificate->_extensions[ix].critical, badCert); + } else if (certificate->_extensions[ix].critical) { + if (isAppleExtensionOID(&extn.extnID)) { + continue; + } + secdebug("cert", "Found unknown critical extension"); + certificate->_foundUnknownCriticalExtension = true; + } else { + secdebug("cert", "Found unknown non critical extension"); + } + } + } + checkForMissingRevocationInfo(certificate); return true; @@ -1947,6 +1974,20 @@ const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate) { return certificate->_der.data; } +static bool SecCertificateIsCertificate(SecCertificateRef certificate) { + if (!certificate) { + return false; + } +#ifndef IS_TRUSTTESTS + /* TrustTests registers two SecCertificate TypeIDs, so we'll skip this check + * in the tests and just let the tests crash if they pass the wrong object type. */ + if (CFGetTypeID(certificate) != SecCertificateGetTypeID()) { + return false; + } +#endif + return true; +} + /* Used to recreate preCert from cert for Certificate Transparency */ CFDataRef SecCertificateCopyPrecertTBS(SecCertificateRef certificate) { @@ -2124,6 +2165,7 @@ static CFStringRef copyOidDescription(CFAllocatorRef allocator, /* Return the ipAddress as a dotted quad for ipv4, or as 8 colon separated 4 digit hex strings for ipv6. Return NULL if the provided IP doesn't have a length of exactly 4 or 16 octets. + Note: hex values are normalized to uppercase. */ static CFStringRef copyIPAddressContentDescription(CFAllocatorRef allocator, const DERItem *ip) { @@ -2132,14 +2174,14 @@ static CFStringRef copyIPAddressContentDescription(CFAllocatorRef allocator, For IPv6 it's 16 octets addr, or 32 octets addr/mask. */ CFStringRef value = NULL; - if (ip->length == 4) { + if (ip->length == IPv4ADDRLEN) { value = CFStringCreateWithFormat(allocator, NULL, CFSTR("%u.%u.%u.%u"), ip->data[0], ip->data[1], ip->data[2], ip->data[3]); - } else if (ip->length == 16) { + } else if (ip->length == IPv6ADDRLEN) { value = CFStringCreateWithFormat(allocator, NULL, - CFSTR("%02x%02x:%02x%02x:%02x%02x:%02x%02x:" - "%02x%02x:%02x%02x:%02x%02x:%02x%02x"), + CFSTR("%02X%02X:%02X%02X:%02X%02X:%02X%02X:" + "%02X%02X:%02X%02X:%02X%02X:%02X%02X"), ip->data[0], ip->data[1], ip->data[2], ip->data[3], ip->data[4], ip->data[5], ip->data[6], ip->data[7], ip->data[8], ip->data[9], ip->data[10], ip->data[11], @@ -2973,19 +3015,21 @@ static void appendBitStringContentNames(CFMutableArrayRef properties, SecCopyCertString(SEC_STRING_LIST_KEY) : SEC_STRING_LIST_KEY; CFStringRef string = NULL; for (ix = 0; ix < bits; ++ix) { + CFStringRef localizedName = (localized) ? SecCopyCertString(names[ix]) : CFRetainSafe(names[ix]); if (value & mask) { if (string) { CFStringRef s = CFStringCreateWithFormat(CFGetAllocator(properties), - NULL, fmt, string, names[ix]); + NULL, fmt, string, localizedName); CFRelease(string); string = s; } else { - string = names[ix]; + string = localizedName; CFRetain(string); } } mask >>= 1; + CFReleaseNull(localizedName); } CFRelease(fmt); appendProperty(properties, kSecPropertyTypeString, label, NULL, @@ -4377,8 +4421,11 @@ CFDataRef SecCertificateGetNormalizedSubjectContent( /* Verify that certificate was signed by issuerKey. */ OSStatus SecCertificateIsSignedBy(SecCertificateRef certificate, SecKeyRef issuerKey) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" /* Setup algId in SecAsn1AlgId format. */ SecAsn1AlgId algId; +#pragma clang diagnostic pop algId.algorithm.Length = certificate->_tbsSigAlg.oid.length; algId.algorithm.Data = certificate->_tbsSigAlg.oid.data; algId.parameters.Length = certificate->_tbsSigAlg.params.length; @@ -4415,8 +4462,9 @@ const DERItem * SecCertificateGetSubjectAltName(SecCertificateRef certificate) { return &certificate->_subjectAltName->extnValue; } -static bool convertIPAddress(CFStringRef name, CFDataRef *dataIP) { - /* IPv4: 4 octets in decimal separated by dots. We don't support matching IPv6 already. */ +/* Convert IPv4 address string to canonical data format (4 bytes) */ +static bool convertIPv4Address(CFStringRef name, CFDataRef *dataIP) { + /* IPv4: 4 octets in decimal separated by dots. */ bool result = false; /* Check size */ if (CFStringGetLength(name) < 7 || /* min size is #.#.#.# */ @@ -4424,15 +4472,16 @@ static bool convertIPAddress(CFStringRef name, CFDataRef *dataIP) { return false; } - CFCharacterSetRef decimals = CFCharacterSetCreateWithCharactersInString(NULL, CFSTR("0123456789.")); - CFCharacterSetRef nonDecimals = CFCharacterSetCreateInvertedSet(NULL, decimals); + CFCharacterSetRef allowed = CFCharacterSetCreateWithCharactersInString(NULL, CFSTR("0123456789.")); + CFCharacterSetRef disallowed = CFCharacterSetCreateInvertedSet(NULL, allowed); CFMutableDataRef data = CFDataCreateMutable(NULL, 0); CFArrayRef parts = CFStringCreateArrayBySeparatingStrings(NULL, name, CFSTR(".")); + CFIndex i, count = (parts) ? CFArrayGetCount(parts) : 0; /* Check character set */ - if (CFStringFindCharacterFromSet(name, nonDecimals, - CFRangeMake(0, CFStringGetLength(name)), - kCFCompareForcedOrdering, NULL)) { + if (CFStringFindCharacterFromSet(name, disallowed, + CFRangeMake(0, CFStringGetLength(name)), + kCFCompareForcedOrdering, NULL)) { goto out; } @@ -4442,9 +4491,8 @@ static bool convertIPAddress(CFStringRef name, CFDataRef *dataIP) { } /* Check each label and convert */ - CFIndex i, count = CFArrayGetCount(parts); for (i = 0; i < count; i++) { - CFStringRef octet = CFArrayGetValueAtIndex(parts, i); + CFStringRef octet = (CFStringRef) CFArrayGetValueAtIndex(parts, i); char *cString = CFStringToCString(octet); uint32_t value = atoi(cString); free(cString); @@ -4457,17 +4505,125 @@ static bool convertIPAddress(CFStringRef name, CFDataRef *dataIP) { } result = true; if (dataIP) { - *dataIP = CFRetain(data); + *dataIP = (CFDataRef) CFRetain(data); + } + +out: + CFReleaseNull(data); + CFReleaseNull(parts); + CFReleaseNull(allowed); + CFReleaseNull(disallowed); + return result; +} + +/* Convert IPv6 address string to canonical data format (16 bytes) */ +static bool convertIPv6Address(CFStringRef name, CFDataRef *dataIP) { + /* IPv6: 8 16-bit fields with colon delimiters. */ + /* Note: we don't support conversion of hybrid IPv4-mapped addresses here. */ + bool result = false; + CFMutableStringRef addr = NULL; + CFIndex length = (name) ? CFStringGetLength(name) : 0; + /* Sanity check size */ + if (length < 2 || /* min size is '::' */ + length > 41) { /* max size is '[####:####:####:####:####:####:####:####]' */ + return result; + } + /* Remove literal brackets, if present */ + if (CFStringHasPrefix(name, CFSTR("[")) && CFStringHasSuffix(name, CFSTR("]"))) { + CFStringRef tmpName = CFStringCreateWithSubstring(NULL, name, CFRangeMake(1, length-2)); + if (tmpName) { + addr = CFStringCreateMutableCopy(NULL, 0, tmpName); + CFRelease(tmpName); + } + } + if (NULL == addr) { + addr = CFStringCreateMutableCopy(NULL, 0, name); + } + CFStringUppercase(addr, CFLocaleGetSystem()); + + CFCharacterSetRef allowed = CFCharacterSetCreateWithCharactersInString(NULL, CFSTR("0123456789ABCDEF:")); + CFCharacterSetRef disallowed = CFCharacterSetCreateInvertedSet(NULL, allowed); + CFMutableDataRef data = CFDataCreateMutable(NULL, 0); + CFArrayRef parts = CFStringCreateArrayBySeparatingStrings(NULL, addr, CFSTR(":")); + CFIndex i, count = (parts) ? CFArrayGetCount(parts) : 0; + + /* Check character set */ + if (CFStringFindCharacterFromSet(addr, disallowed, + CFRangeMake(0, CFStringGetLength(addr)), + kCFCompareForcedOrdering, NULL)) { + goto out; + } + + /* Check number of fields (no fewer than 3, no more than 8) */ + if (CFArrayGetCount(parts) < 3 || CFArrayGetCount(parts) > 8) { + goto out; + } + + /* Check each field and convert to network-byte-order value */ + for (i = 0; i < count; i++) { + uint16_t svalue = 0; + CFStringRef fieldValue = (CFStringRef) CFArrayGetValueAtIndex(parts, i); + char *cString = CFStringToCString(fieldValue); + length = (cString) ? strlen(cString) : 0; + if (length == 0) { + /* empty value indicates one or more zeros in the address */ + if (i == 0 || i == count-1) { /* leading or trailing part of '::' */ + CFDataAppendBytes(data, (const UInt8 *)&svalue, 2); + } else { /* determine how many fields are missing, then zero-fill */ + CFIndex z, missing = (8 - count) + 1; + for (z = 0; z < missing; z++) { + CFDataAppendBytes(data, (const UInt8 *)&svalue, 2); + } + } + } else if (length <= 4) { + /* valid field value is 4 characters or less */ + unsigned long value = strtoul(cString, NULL, 16); + svalue = htons(value & 0xFFFF); + CFDataAppendBytes(data, (const UInt8 *)&svalue, 2); + } + free(cString); + } + if (CFDataGetLength(data) != IPv6ADDRLEN) { + goto out; /* after expansion, data must be exactly 16 bytes */ + } + + result = true; + if (dataIP) { + *dataIP = (CFDataRef) CFRetain(data); } out: CFReleaseNull(data); CFReleaseNull(parts); - CFReleaseNull(decimals); - CFReleaseNull(nonDecimals); + CFReleaseNull(allowed); + CFReleaseNull(disallowed); + CFReleaseNull(addr); return result; } +static bool convertIPAddress(CFStringRef string, CFDataRef *dataIP) { + if (NULL == string) { + return false; + } + if (convertIPv4Address(string, dataIP) || + convertIPv6Address(string, dataIP)) { + return true; + } + return false; +} + +bool SecFrameworkIsIPAddress(CFStringRef string) { + return convertIPAddress(string, NULL); +} + +CFDataRef SecFrameworkCopyIPAddressData(CFStringRef string) { + CFDataRef data = NULL; + if (!convertIPAddress(string, &data)) { + return NULL; + } + return data; +} + static OSStatus appendIPAddressesFromGeneralNames(void *context, SecCEGeneralNameType gnType, const DERItem *generalName) { CFMutableArrayRef ipAddresses = (CFMutableArrayRef)context; @@ -4563,6 +4719,10 @@ static OSStatus appendDNSNamesFromGeneralNames(void *context, SecCEGeneralNameTy ProgramArguments diff --git a/OSX/sec/ipc/com.apple.secitemd.plist b/OSX/sec/ipc/com.apple.secitemd.plist new file mode 100644 index 00000000..d18bdcca --- /dev/null +++ b/OSX/sec/ipc/com.apple.secitemd.plist @@ -0,0 +1,33 @@ + + + + + EnablePressuredExit + + EnableTransactions + + GroupName + _securityd + Label + com.apple.secitemd + MachServices + + com.apple.securityd + + + POSIXSpawnType + Interactive + ProgramArguments + + /usr/libexec/secitemd + + Umask + 54 + UserName + _securityd + _LimitLoadFromVariant + IsRecovery + _LimitLoadToVariant + IsDarwinOS + + diff --git a/OSX/sec/ipc/com.apple.securityd.plist b/OSX/sec/ipc/com.apple.securityd.plist index a0d71850..e75b5e1b 100644 --- a/OSX/sec/ipc/com.apple.securityd.plist +++ b/OSX/sec/ipc/com.apple.securityd.plist @@ -31,7 +31,7 @@ com.apple.securityd.sos - com.apple.security.sfkeychainserver + com.apple.security.escrow-update ProgramArguments @@ -56,6 +56,16 @@ Utility Interval 86400 + GracePeriod + 21600 + PowerNap + + AllowBattery + + RequireInexpensiveNetworkConnectivity + + NetworkTransferDirection + Bidirectional com.apple.notifyd.matching @@ -67,5 +77,7 @@ + _LimitLoadFromVariant + IsRecovery diff --git a/OSX/sec/ipc/securityd_client.h b/OSX/sec/ipc/securityd_client.h index ee7a94c8..1927babc 100644 --- a/OSX/sec/ipc/securityd_client.h +++ b/OSX/sec/ipc/securityd_client.h @@ -20,35 +20,38 @@ * * @APPLE_LICENSE_HEADER_END@ */ -#ifndef _SECURITYD_CLIENT_H_ +#ifndef _SECURITYD_CLIENT_H_ #define _SECURITYD_CLIENT_H_ #include -#include +#include "securityd/SecKeybagSupport.h" #include #include #ifndef MINIMIZE_INCLUDES -# include + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfour-char-constants" +# include "OSX/sec/Security/SecTrustStore.h" +#pragma clang diagnostic pop + #else typedef struct __SecTrustStore *SecTrustStoreRef; -# ifndef _SECURITY_SECCERTIFICATE_H_ -typedef struct __SecCertificate *SecCertificateRef; -# endif // _SECURITY_SECCERTIFICATE_H_ +//# ifndef _SECURITY_SECCERTIFICATE_H_ +//typedef struct __SecCertificate *SecCertificateRef; +//# endif // _SECURITY_SECCERTIFICATE_H_ #endif // MINIMIZE_INCLUDES -#if TARGET_HAS_KEYSTORE -#include -#endif +#include "OSX/utilities/SecAKSWrappers.h" #include #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSCloudCircle.h" +#include "keychain/SecureObjectSync/SOSPeerInfo.h" +#include "keychain/SecureObjectSync/SOSRing.h" #include #include @@ -73,7 +76,9 @@ typedef struct __SecCertificate *SecCertificateRef; // MARK: XPC Information. // +#if TARGET_OS_IPHONE extern CFStringRef sSecXPCErrorDomain; +#endif extern const char *kSecXPCKeyOperation; extern const char *kSecXPCKeyResult; @@ -110,16 +115,16 @@ 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__); \ - } \ +#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) // @@ -131,14 +136,7 @@ extern const char *kSecXPCKeyBackupKeybagPath; // MARK: XPC Interfaces // -extern const char *kSecXPCKeyOperation; -extern const char *kSecXPCKeyResult; -extern const char *kSecXPCKeyError; -extern const char *kSecXPCKeyPeerInfoArray; extern const char *kSecXPCKeyPeerInfo; -extern const char *kSecXPCKeyUserLabel; -extern const char *kSecXPCKeyUserPassword; -extern const char *kSecXPCKeyDSID; extern const char *kSecXPCLimitInMinutes; extern const char *kSecXPCKeyQuery; extern const char *kSecXPCKeyAttributesToUpdate; @@ -153,8 +151,6 @@ extern const char *kSecXPCOTRReady; // OTR ready for messages extern const char *kSecXPCKeyViewName; extern const char *kSecXPCKeyViewActionCode; extern const char *kSecXPCKeyHSA2AutoAcceptInfo; -extern const char *kSecXPCKeyEscrowLabel; -extern const char *kSecXPCKeyTriesLabel; extern const char *kSecXPCKeyString; extern const char *kSecXPCKeyArray; extern const char *kSecXPCKeySet; @@ -195,6 +191,8 @@ enum SecXPCOperation { sec_otr_session_process_packet_remote_id, kSecXPCOpOTAPKIGetNewAsset, kSecXPCOpOTAGetEscrowCertificates, + kSecXPCOpOTAPKICopyTrustedCTLogs, + kSecXPCOpOTAPKICopyCTLogForKeyID, kSecXPCOpProcessUnlockNotification, kSecXPCOpProcessSyncWithAllPeers, kSecXPCOpRollKeys, @@ -310,6 +308,10 @@ enum SecXPCOperation { kSecXPCOpNetworkingAnalyticsReport, kSecXPCOpSetCTExceptions, kSecXPCOpCopyCTExceptions, + kSecXPCOpOTASecExperimentGetAsset, + kSecXPCOpOTASecExperimentGetNewAsset, + sec_trust_get_exception_reset_count_id, + sec_trust_increment_exception_reset_count_id, }; @@ -322,7 +324,7 @@ typedef struct SecurityClient { bool canAccessNetworkExtensionAccessGroups; uid_t uid; CFDataRef musr; -#if TARGET_OS_EMBEDDED && TARGET_HAS_KEYSTORE +#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) && TARGET_HAS_KEYSTORE keybag_handle_t keybag; #endif #if TARGET_OS_IPHONE @@ -335,20 +337,27 @@ typedef struct SecurityClient { extern SecurityClient * SecSecurityClientGet(void); #if TARGET_OS_IOS void SecSecuritySetMusrMode(bool mode, uid_t uid, int activeUser); +void SecSecuritySetPersonaMusr(CFStringRef uuid); #endif struct securityd { + /* LOCAL KEYCHAIN */ bool (*sec_item_add)(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *result, CFErrorRef* error); bool (*sec_item_copy_matching)(CFDictionaryRef query, SecurityClient *client, CFTypeRef *result, CFErrorRef* error); bool (*sec_item_update)(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, SecurityClient *client, CFErrorRef* error); bool (*sec_item_delete)(CFDictionaryRef query, SecurityClient *client, CFErrorRef* error); - bool (*sec_add_shared_web_credential)(CFDictionaryRef attributes, SecurityClient *client, const audit_token_t *clientAuditToken, CFStringRef appID, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error); - bool (*sec_copy_shared_web_credential)(CFDictionaryRef query, SecurityClient *client, const audit_token_t *clientAuditToken, CFStringRef appID, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error); bool (*sec_item_delete_all)(CFErrorRef* error); CFArrayRef (*sec_item_copy_parent_certificates)(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error); bool (*sec_item_certificate_exists)(CFDataRef normalizedIssuer, CFDataRef serialNumber, CFArrayRef accessGroups, CFErrorRef *error); CFDataRef (*sec_keychain_backup)(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef* error); bool (*sec_keychain_restore)(CFDataRef backup, SecurityClient *client, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); + bool (*sec_roll_keys)(bool force, CFErrorRef* error); + bool (*sec_item_update_token_items)(CFStringRef tokenID, CFArrayRef query, SecurityClient *client, CFErrorRef* error); + bool (*sec_delete_items_with_access_groups)(CFArrayRef bundleIDs, SecurityClient *client, CFErrorRef *error); + /* SHAREDWEBCREDENTIALS */ + bool (*sec_add_shared_web_credential)(CFDictionaryRef attributes, SecurityClient *client, const audit_token_t *clientAuditToken, CFStringRef appID, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error); + bool (*sec_copy_shared_web_credential)(CFDictionaryRef query, SecurityClient *client, const audit_token_t *clientAuditToken, CFStringRef appID, CFArrayRef accessGroups, CFTypeRef *result, CFErrorRef *error); + /* SECUREOBJECTSYNC */ CFDictionaryRef (*sec_keychain_backup_syncable)(CFDictionaryRef backup_in, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); bool (*sec_keychain_restore_syncable)(CFDictionaryRef backup, CFDataRef keybag, CFDataRef passcode, CFErrorRef* error); CFArrayRef (*sec_item_backup_copy_names)(CFErrorRef *error); @@ -360,7 +369,7 @@ 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_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); @@ -410,7 +419,6 @@ struct securityd { CFSetRef (*soscc_ProcessSyncWithPeers)(CFSetRef peerIDs, CFSetRef backupPeerIDs, CFErrorRef* error); SyncWithAllPeersReason (*soscc_ProcessSyncWithAllPeers)(CFErrorRef* error); bool (*soscc_EnsurePeerRegistration)(CFErrorRef* error); - bool (*sec_roll_keys)(bool force, CFErrorRef* error); CFArrayRef (*sec_keychain_sync_update_message)(CFDictionaryRef update, CFErrorRef *error); CFPropertyListRef (*sec_get_log_settings)(CFErrorRef* error); bool (*sec_set_xpc_log_settings)(CFTypeRef type, CFErrorRef* error); @@ -436,8 +444,6 @@ struct securityd { bool (*soscc_SOSCCTestPopulateKVSWithBadKeys)(CFErrorRef *error); bool (*soscc_AccountHasPublicKey)(CFErrorRef *error); bool (*soscc_AccountIsNew)(CFErrorRef *error); - bool (*sec_item_update_token_items)(CFStringRef tokenID, CFArrayRef query, SecurityClient *client, CFErrorRef* error); - 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); CFBooleanRef (*soscc_SOSCCPeersHaveViewsEnabled)(CFArrayRef views, CFErrorRef *error); @@ -445,6 +451,7 @@ struct securityd { bool (*soscc_SOSCCMessageFromPeerIsPending)(SOSPeerInfoRef peer, CFErrorRef* error); bool (*soscc_SOSCCSendToPeerIsPending)(SOSPeerInfoRef peer, CFErrorRef* error); CFTypeRef (*soscc_status)(void); + /* otherstuff */ CFTypeRef secd_xpc_server; }; @@ -461,12 +468,20 @@ struct trustd { uint64_t (*sec_ota_pki_asset_version)(CFErrorRef* error); CFArrayRef (*ota_CopyEscrowCertificates)(uint32_t escrowRootType, CFErrorRef* error); uint64_t (*sec_ota_pki_get_new_asset)(CFErrorRef* error); + uint64_t (*sec_ota_secexperiment_get_new_asset)(CFErrorRef* error); + CFDictionaryRef (*sec_ota_secexperiment_get_asset)(CFErrorRef* error); + CFDictionaryRef (*sec_ota_pki_copy_trusted_ct_logs)(CFErrorRef *error); + CFDictionaryRef (*sec_ota_pki_copy_ct_log_for_keyid)(CFDataRef keyID, CFErrorRef *error); bool (*sec_trust_store_copy_all)(SecTrustStoreRef ts, CFArrayRef *trustStoreContents, CFErrorRef *error); bool (*sec_trust_store_copy_usage_constraints)(SecTrustStoreRef ts, CFDataRef digest, CFArrayRef *usageConstraints, CFErrorRef *error); bool (*sec_ocsp_cache_flush)(CFErrorRef *error); bool (*sec_networking_analytics_report)(CFStringRef event_name, xpc_object_t tls_analytics_attributes, CFErrorRef *error); bool (*sec_trust_store_set_ct_exceptions)(CFStringRef appID, CFDictionaryRef exceptions, CFErrorRef *error); CFDictionaryRef (*sec_trust_store_copy_ct_exceptions)(CFStringRef appID, CFErrorRef *error); +#if TARGET_OS_IPHONE + bool (*sec_trust_increment_exception_reset_count)(CFErrorRef *error); + uint64_t (*sec_trust_get_exception_reset_count)(CFErrorRef *error); +#endif }; extern struct trustd *gTrustd; @@ -478,7 +493,7 @@ 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); + 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); @@ -488,8 +503,8 @@ bool securityd_send_sync_and_do(enum SecXPCOperation op, 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); + 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); @@ -541,6 +556,21 @@ typedef void (^SecBoolNSErrorCallback) (bool, NSError*); - (void) secItemDigest:(NSString *)keychainClass accessGroup:(NSString *)accessGroup complete:(void (^)(NSArray *digest, NSError* error))complete; + +// Delete the multi-user slice of persona uuid +// +// Should be done just before account volume is unmounted, will delete all this user's data unconditionally +// There is nothing stopping futher storage though. +- (void) secKeychainDeleteMultiuser:(NSData *)uuid + complete:(void (^)(bool status, NSError* error))complete; + +// Go through the keychain to verify the backup infrastructure is present and valid. +// The completion handler's dictionary will contain a string with statistics about the class, error will be nil or +// complain about what went wrong during verification. +// Lightweight mode only checks consistency of the backup infrastructure without verifying all keychain items +- (void)secItemVerifyBackupIntegrity:(BOOL)lightweight + completion:(void (^)(NSDictionary* resultsPerKeyclass, NSError* error))completion; + @end // Call this to receive a proxy object conforming to SecuritydXPCProtocol that you can call methods on. @@ -548,7 +578,7 @@ typedef void (^SecBoolNSErrorCallback) (bool, NSError*); id SecuritydXPCProxyObject(void (^rpcErrorHandler)(NSError *)); // Set up a local securityxpcserver: after this call, all securitydxpc calls will be handled in-process instead of actually transferring to securityd -id SecCreateLocalSecuritydXPCServer(void); +id SecCreateLocalSecuritydXPCServer(void) NS_RETURNS_RETAINED; // Make a SecBoolNSErrorCallback block into an Objective-C object (for proxying across NSXPC) @interface SecuritydXPCCallback : NSObject { diff --git a/OSX/sec/ipc/server.c b/OSX/sec/ipc/server.c index 111b1165..cfef1c39 100644 --- a/OSX/sec/ipc/server.c +++ b/OSX/sec/ipc/server.c @@ -21,12 +21,21 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#if TARGET_DARWINOS +#undef OCTAGON +#undef SECUREOBJECTSYNC +#undef SHAREDWEBCREDENTIALS +#endif + +#include +#include + +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSControlServer.h" #include #include #include @@ -67,6 +76,9 @@ #include "keychain/ot/OctagonControlServer.h" #include +#if !TARGET_OS_BRIDGE +#include +#endif #include #include @@ -94,103 +106,81 @@ #include #include +#include "keychain/ot/OT.h" +#include "keychain/escrowrequest/EscrowRequestXPCServer.h" +#include "keychain/escrowrequest/EscrowRequestServerHelpers.h" + #if TARGET_OS_OSX #include #include #include #endif -static bool accessGroupPermitted(SecurityClient* client, CFArrayRef accessGroups, CFStringRef accessGroup) { - /* NULL accessGroups is wildcard. */ - if (!accessGroups) - return true; - /* Make sure we have a string. */ - if (!isString(accessGroup)) - return false; +#include "util.h" - /* Having the special accessGroup "*" allows access to all accessGroups. */ - CFRange range = { 0, CFArrayGetCount(accessGroups) }; - if (range.length && - (CFArrayContainsValue(accessGroups, range, accessGroup) || - CFArrayContainsValue(accessGroups, range, CFSTR("*")))) - return true; +#if SECUREOBJECTSYNC - return false; +CF_RETURNS_RETAINED +static CFStringRef +_xpc_dictionary_copy_CFString(xpc_object_t xdict, const char *key) +{ + CFStringRef result = NULL; + const char *str = xpc_dictionary_get_string(xdict, key); + if (str != NULL) { + result = CFStringCreateWithCString(kCFAllocatorDefault, str, kCFStringEncodingUTF8); + } + return result; } -static bool extractAccessGroup(SecurityClient *client, CFStringRef requestedAgrp, CFStringRef *resolvedAgrp, CFErrorRef *error) { - bool ok = true; - - /* Access group sanity checking. - Similar to accessGroupsAllows, but ignores accessGroupIsNetworkExtensionAndClientIsEntitled */ - CFArrayRef accessGroups = client->accessGroups; - CFStringRef agrp = requestedAgrp; - /* Having the special accessGroup "*" allows access to all accessGroups. */ - if (CFArrayContainsValue(accessGroups, CFRangeMake(0,CFArrayGetCount(accessGroups)), CFSTR("*"))) - accessGroups = NULL; - - if (requestedAgrp) { - /* The user specified an explicit access group, validate it. */ - if (!accessGroupPermitted(client, accessGroups, requestedAgrp)) - ok = SecError(errSecMissingEntitlement, error, CFSTR("explicit accessGroup %@ not in client access %@"), requestedAgrp, accessGroups); - } else { - // We are using an implicit access group - // Add it as if the user specified it as an attribute. - agrp = (CFStringRef)CFArrayGetValueAtIndex(client->accessGroups, 0); +CF_RETURNS_RETAINED +static CFDataRef +_xpc_dictionary_copy_CFDataNoCopy(xpc_object_t xdict, const char *key) +{ + CFDataRef result = NULL; + size_t len = 0; + const void *ptr = xpc_dictionary_get_data(xdict, key, &len); + if (ptr != NULL) { + result = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, ptr, len, kCFAllocatorNull); } - - if (agrp && resolvedAgrp) - *resolvedAgrp = agrp; - return ok; + return result; } static void with_label_and_password(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password)) { - const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel); - - if (label_utf8) { // Anything we would do here requires a user label - size_t password_length = 0; - const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length); - - CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull); - CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8); - - action(user_label, user_password); + CFStringRef user_label = _xpc_dictionary_copy_CFString(message, kSecXPCKeyUserLabel); + CFDataRef user_password = _xpc_dictionary_copy_CFDataNoCopy(message, kSecXPCKeyUserPassword); - CFReleaseNull(user_password); - CFReleaseNull(user_label); + if (user_label != NULL && user_password != NULL) { + action(user_label, user_password); } + + CFReleaseNull(user_label); + CFReleaseNull(user_password); } static void with_label_and_password_and_dsid(xpc_object_t message, void (^action)(CFStringRef label, CFDataRef password, CFStringRef dsid)) { - const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyUserLabel); - - if (label_utf8) { // Anything we would do here requires a user label - size_t password_length = 0; - const void *password_data = xpc_dictionary_get_data(message, kSecXPCKeyUserPassword, &password_length); - const char *xdsid = xpc_dictionary_get_string(message, kSecXPCKeyDSID); - - CFDataRef user_password = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, password_data, password_length, kCFAllocatorNull); - CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8); - CFStringRef dsid = CFStringCreateWithCString(kCFAllocatorDefault, xdsid, kCFStringEncodingUTF8); - + CFStringRef user_label = _xpc_dictionary_copy_CFString(message, kSecXPCKeyUserLabel); + CFDataRef user_password = _xpc_dictionary_copy_CFDataNoCopy(message, kSecXPCKeyUserPassword); + CFStringRef dsid = _xpc_dictionary_copy_CFString(message, kSecXPCKeyDSID); + + /* dsid is optional */ + if (user_label != NULL && user_password != NULL) { action(user_label, user_password, dsid); - - CFReleaseNull(dsid); - CFReleaseNull(user_password); - CFReleaseNull(user_label); } -} -static void with_label_and_number(xpc_object_t message, void (^action)(CFStringRef label, uint64_t number)) { - const char *label_utf8 = xpc_dictionary_get_string(message, kSecXPCKeyViewName); + CFReleaseNull(user_label); + CFReleaseNull(user_password); + CFReleaseNull(dsid); +} - if (label_utf8) { // Anything we would do here requires a user label - const int64_t number = xpc_dictionary_get_int64(message, kSecXPCKeyViewActionCode); - CFStringRef user_label = CFStringCreateWithCString(kCFAllocatorDefault, label_utf8, kCFStringEncodingUTF8); +static void with_view_and_action(xpc_object_t message, void (^action)(CFStringRef view_name, uint64_t view_action_code)) { + CFStringRef view = _xpc_dictionary_copy_CFString(message, kSecXPCKeyViewName); + const int64_t number = xpc_dictionary_get_int64(message, kSecXPCKeyViewActionCode); - action(user_label, number); - CFReleaseNull(user_label); + if (view != NULL) { + action(view, number); } + + CFReleaseNull(view); } static CFArrayRef SecXPCDictionaryCopyPeerInfoArray(xpc_object_t dictionary, const char *key, CFErrorRef *error) { @@ -271,6 +261,8 @@ bool xpc_dictionary_set_and_consume_PeerInfoArray(xpc_object_t xdict, const char return success; } +#endif /* SECUREOBJECTSYNC */ + static CFDataRef SecDataCopyMmapFileDescriptor(int fd, void **mem, size_t *size, CFErrorRef *error) { @@ -312,7 +304,6 @@ SecDataWriteFileDescriptor(int fd, CFDataRef data) return writeResult; } - // Returns error if entitlement isn't present. static bool EntitlementPresentAndTrue(uint64_t op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error) @@ -324,18 +315,6 @@ EntitlementPresentAndTrue(uint64_t op, SecTaskRef clientTask, CFStringRef entitl return true; } -// Per Disable the entitlement check for "keychain-cloud-circle" -// we disable entitlement enforcement. However, we still log so we know who needs the entitlement -static bool -EntitlementPresentOrWhine(uint64_t op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error) -{ - if (!SecTaskGetBooleanValueForEntitlement(clientTask, entitlement)) - secnotice("serverxpc", "%@: %@ lacks entitlement %@", SOSCCGetOperationDescription((enum SecXPCOperation)op), clientTask, entitlement); - - return true; -} - - static bool EntitlementAbsentOrFalse(uint64_t op, SecTaskRef clientTask, CFStringRef entitlement, CFErrorRef *error) { @@ -375,7 +354,12 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_connection_get_audit_token(connection, &auditToken); clientAuditToken = CFDataCreate(kCFAllocatorDefault, (const UInt8*)&auditToken, sizeof(auditToken)); - fill_security_client(&client, xpc_connection_get_euid(connection), auditToken); + if (!fill_security_client(&client, xpc_connection_get_euid(connection), auditToken)) { + CFReleaseNull(clientAuditToken); + xpc_connection_send_message(connection, replyMessage); + xpc_release(replyMessage); + return; + } #if TARGET_OS_IOS if (operation == sec_add_shared_web_credential_id || operation == sec_copy_shared_web_credential_id) { @@ -494,6 +478,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFStringRef applicationIdentifier = SecTaskCopyApplicationIdentifier(client.task); bool isBuddy = applicationIdentifier && CFEqual(applicationIdentifier, CFSTR("com.apple.purplebuddy")); + CFReleaseNull(applicationIdentifier); if (isBuddy || EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateDeleteAll, &error)) { @@ -593,6 +578,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; } +#if SECUREOBJECTSYNC case sec_keychain_sync_update_message_id: { CFDictionaryRef updates = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error); @@ -722,7 +708,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } case sec_add_shared_web_credential_id: { -#if TARGET_OS_IOS && !TARGET_OS_BRIDGE +#if SHAREDWEBCREDENTIALS CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error); if (query) { CFTypeRef result = NULL; @@ -742,7 +728,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } case sec_copy_shared_web_credential_id: { -#if TARGET_OS_IOS && !TARGET_OS_BRIDGE +#if SHAREDWEBCREDENTIALS CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error); if (query) { CFTypeRef result = NULL; @@ -824,7 +810,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, break; } case kSecXPCOpTryUserCredentials: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCTryUserCredentials_Server(label, password, dsid, &error)); @@ -832,7 +818,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpSetUserCredentials: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { with_label_and_password(event, ^(CFStringRef label, CFDataRef password) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetUserCredentials_Server(label, password, &error)); @@ -840,7 +826,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpSetUserCredentialsAndDSID: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { with_label_and_password_and_dsid(event, ^(CFStringRef label, CFDataRef password, CFStringRef dsid) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCSetUserCredentialsAndDSID_Server(label, password, dsid, &error)); @@ -848,7 +834,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpSetUserCredentialsAndDSIDWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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){ @@ -861,31 +847,21 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpView: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - with_label_and_number(event, ^(CFStringRef view, uint64_t actionCode) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + with_view_and_action(event, ^(CFStringRef view, uint64_t actionCode) { xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCView_Server(view, (SOSViewActionCode)actionCode, &error)); }); } break; - case kSecXPCOpViewSet: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFSetRef enabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyEnabledViewsKey); - CFSetRef disabledViews = SecXPCSetCreateFromXPCDictionaryElement(event, kSecXPCKeyDisabledViewsKey); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCViewSet_Server(enabledViews, disabledViews)); - CFReleaseNull(enabledViews); - CFReleaseNull(disabledViews); - } - break; + case kSecXPCOpViewSet: // FALLTHROUGH case kSecXPCOpViewSetWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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){ + if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error)){ 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); @@ -893,31 +869,31 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpCanAuthenticate: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCCanAuthenticate_Server(&error)); } break; case kSecXPCOpPurgeUserCredentials: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCPurgeUserCredentials_Server(&error)); } break; case kSecXPCOpDeviceInCircle: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCThisDeviceIsInCircle_Server(&error)); } break; case kSecXPCOpRequestToJoin: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircle_Server(&error)); } break; case kSecXPCOpRequestToJoinWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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)); @@ -928,25 +904,25 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpAccountHasPublicKey: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCAccountHasPublicKey_Server(&error)); } break; case kSecXPCOpAccountIsNew: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCAccountIsNew_Server(&error)); } break; case kSecXPCOpRequestToJoinAfterRestore: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestToJoinCircleAfterRestore_Server(&error)); } break; case kSecXPCOpRequestToJoinAfterRestoreWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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)); @@ -957,17 +933,18 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpRequestEnsureFreshParameters: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRequestEnsureFreshParameters_Server(&error)); } break; case kSecXPCOpGetAllTheRings: if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef ringDescriptions = SOSCCGetAllTheRings_Server(&error); + CFStringRef ringDescriptions = SOSCCGetAllTheRings_Server(&error); xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(ringDescriptions); xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_dictionary); xpc_release(xpc_dictionary); + CFReleaseNull(ringDescriptions); } break; case kSecXPCOpApplyToARing: @@ -1009,25 +986,25 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_dictionary_set_int64(replyMessage, kSecXPCKeyError, errSecUnimplemented); } break; - case kSecXPCOpAccountSetToNew: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + case kSecXPCOpAccountSetToNew: + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCAccountSetToNew_Server(&error)); } - break; + break; case kSecXPCOpResetToOffering: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCResetToOffering_Server(&error)); } break; case kSecXPCOpResetToEmpty: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCResetToEmpty_Server(&error)); } break; case kSecXPCOpResetToEmptyWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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)); @@ -1037,13 +1014,13 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpRemoveThisDeviceFromCircle: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemoveThisDeviceFromCircle_Server(&error)); } break; case kSecXPCOpRemoveThisDeviceFromCircleWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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)); @@ -1054,7 +1031,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpRemovePeersFromCircle: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRemovePeersFromCircle_Server(applicants, &error)); @@ -1062,7 +1039,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpRemovePeersFromCircleWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFArrayRef applicants = SecXPCDictionaryCopyPeerInfoArray(event, kSecXPCKeyPeerInfoArray, &error); CFDataRef parentEvent = NULL; if(SecXPCDictionaryCopyDataOptional(event, kSecXPCKeySignInAnalytics, &parentEvent, &error) && parentEvent != NULL){ @@ -1075,21 +1052,23 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpLoggedOutOfAccount: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCLoggedOutOfAccount_Server(&error)); } break; case kSecXPCOpBailFromCircle: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + // 0 is valid; ok for this parameter to be unset or incorrect type. Note: kSecXPCLimitInMinutes is actually seconds, not minutes uint64_t limit_in_seconds = xpc_dictionary_get_uint64(event, kSecXPCLimitInMinutes); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCBailFromCircle_Server(limit_in_seconds, &error)); } break; case kSecXPCOpAcceptApplicants: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfoArray); + // CreateArrayOfPeerInfoWithXPCObject enforces that xapplicants is a non-NULL xpc data object CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants)); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, (applicants && SOSCCAcceptApplicants_Server(applicants, &error))); @@ -1097,8 +1076,9 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpRejectApplicants: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_object_t xapplicants = xpc_dictionary_get_value(event, kSecXPCKeyPeerInfoArray); + // CreateArrayOfPeerInfoWithXPCObject enforces that xapplicants is a non-NULL xpc data object CFArrayRef applicants = CreateArrayOfPeerInfoWithXPCObject(xapplicants, &error); //(CFArrayRef)(_CFXPCCreateCFObjectFromXPCObject(xapplicants)); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, (applicants && SOSCCRejectApplicants_Server(applicants, &error))); @@ -1109,17 +1089,18 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, { if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) { CFDataRef publicBackupKey = SecXPCDictionaryCopyData(event, kSecXPCKeyNewPublicBackupKey, &error); - SOSPeerInfoRef peerInfo = SOSCCSetNewPublicBackupKey_Server(publicBackupKey, &error); - CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL; - CFReleaseNull(peerInfo); - if (peerInfoData) { - xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData); - xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object); - xpc_release(xpc_object); + if (publicBackupKey != NULL) { + SOSPeerInfoRef peerInfo = SOSCCSetNewPublicBackupKey_Server(publicBackupKey, &error); + CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL; + CFReleaseNull(peerInfo); + if (peerInfoData) { + xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(peerInfoData); + xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object); + xpc_release(xpc_object); + } + CFReleaseNull(peerInfoData); + CFReleaseSafe(publicBackupKey); } - CFReleaseNull(peerInfoData); - CFReleaseSafe(publicBackupKey); - } } break; @@ -1127,14 +1108,16 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, { if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) { CFDataRef recovery_key = SecXPCDictionaryCopyData(event, kSecXPCKeyRecoveryPublicKey, &error); - uint8_t zero = 0; - CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, &zero, 1); // token we send if we really wanted to send NULL - if(CFEqual(recovery_key, nullData)) { + if (recovery_key != NULL) { + uint8_t zero = 0; + CFDataRef nullData = CFDataCreate(kCFAllocatorDefault, &zero, 1); // token we send if we really wanted to send NULL + if(CFEqual(recovery_key, nullData)) { + CFReleaseNull(recovery_key); + } + CFReleaseNull(nullData); + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRegisterRecoveryPublicKey_Server(recovery_key, &error)); CFReleaseNull(recovery_key); } - CFReleaseNull(nullData); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCRegisterRecoveryPublicKey_Server(recovery_key, &error)); - CFReleaseNull(recovery_key); } } break; @@ -1154,55 +1137,55 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, case kSecXPCOpSetBagForAllSlices: { if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementRestoreKeychain, &error)) { - CFDataRef backupSlice = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error); - bool includeV0 = xpc_dictionary_get_bool(event, kSecXPCKeyIncludeV0); + CFDataRef backupSlice = SecXPCDictionaryCopyData(event, kSecXPCKeyKeybag, &error); // NULL checked below + bool includeV0 = xpc_dictionary_get_bool(event, kSecXPCKeyIncludeV0); // false is ok, so it's safe for this paramter to be unset or incorrect type xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, backupSlice && SOSCCRegisterSingleRecoverySecret_Server(backupSlice, includeV0, &error)); CFReleaseSafe(backupSlice); } } break; case kSecXPCOpCopyApplicantPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyApplicantPeerInfo_Server(&error), &error); } break; case kSecXPCOpCopyValidPeerPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyValidPeerPeerInfo_Server(&error), &error); } break; case kSecXPCOpValidateUserPublic: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { bool trusted = SOSCCValidateUserPublic_Server(&error); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, trusted); } break; case kSecXPCOpCopyNotValidPeerPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyNotValidPeerPeerInfo_Server(&error), &error); } break; case kSecXPCOpCopyGenerationPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_CFArray(replyMessage, kSecXPCKeyResult, SOSCCCopyGenerationPeerInfo_Server(&error)); } break; case kSecXPCOpCopyRetirementPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyRetirementPeerInfo_Server(&error), &error); } break; case kSecXPCOpCopyViewUnawarePeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyViewUnawarePeerInfo_Server(&error), &error); @@ -1270,21 +1253,21 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpCopyPeerPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyPeerPeerInfo_Server(&error), &error); } break; case kSecXPCOpCopyConcurringPeerPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_and_consume_PeerInfoArray(replyMessage, kSecXPCKeyResult, SOSCCCopyConcurringPeerPeerInfo_Server(&error), &error); } break; case kSecXPCOpCopyMyPeerInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo_Server(&error); CFDataRef peerInfoData = peerInfo ? SOSPeerInfoCopyEncodedData(peerInfo, kCFAllocatorDefault, &error) : NULL; CFReleaseNull(peerInfo); @@ -1297,13 +1280,14 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpGetLastDepartureReason: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCGetLastDepartureReason_Server(&error)); } break; - case kSecXPCOpSetLastDepartureReason: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + case kSecXPCOpSetLastDepartureReason: + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + // 0 is a legitimate reason (kSOSDepartureReasonError), so it's safe for this parameter to be unset or incorrect type int32_t reason = (int32_t) xpc_dictionary_get_int64(event, kSecXPCKeyReason); xpc_dictionary_set_int64(replyMessage, kSecXPCKeyResult, SOSCCSetLastDepartureReason_Server(reason, &error)); @@ -1337,7 +1321,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpCopyIncompatibilityInfo: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFStringRef iis = SOSCCCopyIncompatibilityInfo_Server(&error); SecXPCDictionarySetString(replyMessage, kSecXPCKeyResult, iis, &error); CFReleaseSafe(iis); @@ -1345,20 +1329,21 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, break; case kSecXPCOpRollKeys: { + // false is valid, so it's safe for this parameter to be unset or incorrect type bool force = xpc_dictionary_get_bool(event, "force"); xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, _SecServerRollKeys(force, &client, &error)); } break; case kSecXPCOpWaitForInitialSync: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCWaitForInitialSync_Server(&error)); } break; case kSecXPCOpWaitForInitialSyncWithAnalytics: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(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)); @@ -1369,7 +1354,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpCopyYetToSyncViews: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFArrayRef array = SOSCCCopyYetToSyncViewsList_Server(&error); if (array) { xpc_object_t xpc_array = _CFXPCCreateXPCObjectFromCFObject(array); @@ -1380,19 +1365,21 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpSetEscrowRecord: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { - CFStringRef escrow_label = SecXPCDictionaryCopyString(event, kSecXPCKeyEscrowLabel, &error); - uint64_t tries = xpc_dictionary_get_int64(event, kSecXPCKeyTriesLabel); + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + CFStringRef escrow_label = SecXPCDictionaryCopyString(event, kSecXPCKeyEscrowLabel, &error); // NULL checked below + uint64_t tries = xpc_dictionary_get_int64(event, kSecXPCKeyTriesLabel); // 0 is acceptable; safe for this parameter to be unset or incorrect type - bool result = SOSCCSetEscrowRecord_Server(escrow_label, tries, &error); - if (result) { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result); + if (escrow_label != NULL) { + bool result = SOSCCSetEscrowRecord_Server(escrow_label, tries, &error); + if (result) { + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result); + } + CFReleaseNull(escrow_label); } - CFReleaseNull(escrow_label); } break; case kSecXPCOpGetEscrowRecord: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFDictionaryRef record = SOSCCCopyEscrowRecord_Server(&error); if (record) { xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record); @@ -1403,7 +1390,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; case kSecXPCOpCopyBackupInformation: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { CFDictionaryRef record = SOSCCCopyBackupInformation_Server(&error); if (record) { xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(record); @@ -1415,7 +1402,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, break; case kSecXPCOpIsThisDeviceLastBackup: - if (EntitlementPresentOrWhine(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { + if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementKeychainCloudCircle, &error)) { xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, SOSCCkSecXPCOpIsThisDeviceLastBackup_Server(&error)); } break; @@ -1532,16 +1519,20 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, case kSecXPCOpCopyCircleJoiningBlob: if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) { CFDataRef appBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error); - SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(kCFAllocatorDefault, &error, appBlob); - CFDataRef pbblob = SOSCCCopyCircleJoiningBlob_Server(applicant, &error); - if (pbblob) { - xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(pbblob); - xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object); - xpc_release(xpc_object); + if (appBlob != NULL) { + SOSPeerInfoRef applicant = SOSPeerInfoCreateFromData(kCFAllocatorDefault, &error, appBlob); + if (applicant != NULL) { + CFDataRef pbblob = SOSCCCopyCircleJoiningBlob_Server(applicant, &error); + if (pbblob) { + xpc_object_t xpc_object = _CFXPCCreateXPCObjectFromCFObject(pbblob); + xpc_dictionary_set_value(replyMessage, kSecXPCKeyResult, xpc_object); + xpc_release(xpc_object); + } + CFReleaseNull(pbblob); + CFReleaseNull(applicant); + } + CFReleaseNull(appBlob); } - CFReleaseNull(pbblob); - CFReleaseNull(applicant); - CFReleaseNull(appBlob); } break; case kSecXPCOpCopyInitialSyncBlob: @@ -1557,11 +1548,13 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, break; case kSecXPCOpJoinWithCircleJoiningBlob: if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementCircleJoin, &error)) { - CFDataRef joiningBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error); - uint64_t version = xpc_dictionary_get_uint64(event, kSecXPCVersion); - bool retval = SOSCCJoinWithCircleJoiningBlob_Server(joiningBlob, (PiggyBackProtocolVersion) version, &error); - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval); - CFReleaseNull(joiningBlob); + CFDataRef joiningBlob = SecXPCDictionaryCopyCFDataRef(event, kSecXPCData, &error); // NULL checked below + uint64_t version = xpc_dictionary_get_uint64(event, kSecXPCVersion); // 0 is valid, so this parameter can be unset or incorrect type + if (joiningBlob != NULL) { + bool retval = SOSCCJoinWithCircleJoiningBlob_Server(joiningBlob, (PiggyBackProtocolVersion) version, &error); + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval); + CFReleaseNull(joiningBlob); + } } break; @@ -1597,6 +1590,7 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, CFReleaseNull(peer); break; } +#endif /* !SECUREOBJECTSYNC */ case sec_delete_items_with_access_groups_id: { bool retval = false; @@ -1613,88 +1607,15 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, retval); } break; - case sec_item_copy_parent_certificates_id: - { - CFArrayRef results = NULL; - if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) { - CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error); - CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error); - if (issuer && accessGroups) { - results = _SecItemCopyParentCertificates(issuer, accessGroups, &error); - } - CFReleaseNull(issuer); - CFReleaseNull(accessGroups); - } - SecXPCDictionarySetPListOptional(replyMessage, kSecXPCKeyResult, results, &error); - CFReleaseNull(results); - } - break; - case sec_item_certificate_exists_id: - { - bool result = false; - if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) { - CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error); - CFDataRef serialNum = SecXPCDictionaryCopyData(event, kSecXPCKeySerialNumber, &error); - CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error); - if (issuer && serialNum && accessGroups) { - result = _SecItemCertificateExists(issuer, serialNum, accessGroups, &error); - } - CFReleaseNull(issuer); - CFReleaseNull(serialNum); - CFReleaseNull(accessGroups); - } - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result); - } - break; case kSecXPCOpBackupKeybagAdd: { if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) { - CFDataRef keybag = NULL, passcode = NULL; - if (SecXPCDictionaryCopyDataOptional(event, kSecXPCKeyUserPassword, &passcode, &error)) { - CFDataRef identifier = NULL; - CFDataRef pathinfo = NULL; // really a CFURLRef - bool added = _SecServerBackupKeybagAdd(&client, passcode, &identifier, &pathinfo, &error); - if (added) { - added &= SecXPCDictionarySetDataOptional(replyMessage, kSecXPCKeyBackupKeybagIdentifier, identifier, &error); - added &= SecXPCDictionarySetDataOptional(replyMessage, kSecXPCKeyBackupKeybagPath, pathinfo, &error); - SecXPCDictionarySetBool(replyMessage, kSecXPCKeyResult, added, NULL); - } else { - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); - } - } - CFReleaseSafe(passcode); - CFReleaseSafe(keybag); + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); } break; } case kSecXPCOpBackupKeybagDelete: { - // >>> if (EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperations, &error)) { - bool deleted = false; - CFDictionaryRef query = SecXPCDictionaryCopyDictionary(event, kSecXPCKeyQuery, &error); - if (query) { - CFTypeRef matchLimit = CFDictionaryGetValue(query, kSecMatchLimit); - bool deleteAll = matchLimit && CFEqualSafe(matchLimit, kSecMatchLimitAll); - - if (deleteAll && !EntitlementPresentAndTrue(operation, client.task, kSecEntitlementBackupTableOperationsDeleteAll, &error)) { - // require special entitlement to delete all backup keybags - } else { - CFMutableDictionaryRef attributes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, query); - CFStringRef requestedAgrp = CFDictionaryGetValue(attributes, kSecAttrAccessGroup); - CFStringRef resolvedAgrp = NULL; - if (client.musr) { - CFDictionarySetValue(attributes, kSecAttrMultiUser, client.musr); - } - if (extractAccessGroup(&client, requestedAgrp, &resolvedAgrp, &error)) { - if (resolvedAgrp) { - CFDictionarySetValue(attributes, kSecAttrAccessGroup, resolvedAgrp); - } - deleted = _SecServerBackupKeybagDelete(attributes, deleteAll, &error); - } - CFReleaseNull(attributes); - } - } - xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, deleted); - CFReleaseNull(query); + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, false); } break; } @@ -1711,8 +1632,39 @@ static void securityd_xpc_dictionary_handler(const xpc_connection_t connection, } break; } + case sec_item_copy_parent_certificates_id: { + CFArrayRef results = NULL; + if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) { + CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error); + CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error); + if (issuer && accessGroups) { + results = _SecItemCopyParentCertificates(issuer, accessGroups, &error); + } + CFReleaseNull(issuer); + CFReleaseNull(accessGroups); + } + SecXPCDictionarySetPListOptional(replyMessage, kSecXPCKeyResult, results, &error); + CFReleaseNull(results); + break; + } + case sec_item_certificate_exists_id: { + bool result = false; + if(EntitlementPresentAndTrue(operation, client.task, kSecEntitlementPrivateCertificateAllAccess, &error)) { + CFDataRef issuer = SecXPCDictionaryCopyData(event, kSecXPCKeyNormalizedIssuer, &error); + CFDataRef serialNum = SecXPCDictionaryCopyData(event, kSecXPCKeySerialNumber, &error); + CFArrayRef accessGroups = SecXPCDictionaryCopyArray(event, kSecXPCKeyAccessGroups, &error); + if (issuer && serialNum && accessGroups) { + result = _SecItemCertificateExists(issuer, serialNum, accessGroups, &error); + } + CFReleaseNull(issuer); + CFReleaseNull(serialNum); + CFReleaseNull(accessGroups); + } + xpc_dictionary_set_bool(replyMessage, kSecXPCKeyResult, result); + break; + } default: - break; + break; } if (error) @@ -1765,24 +1717,8 @@ 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) { - /* - * 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); - } 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); - }); - } + // Synchronous. The client has a connection pool so they can be somewhat re-entrant if they need. + securityd_xpc_dictionary_handler(connection, event); } }); xpc_connection_resume(connection); @@ -1795,15 +1731,23 @@ static void securityd_xpc_init(const char *service_name) xpc_activity_state_t activityState = xpc_activity_get_state(activity); if (activityState == XPC_ACTIVITY_STATE_RUN) { SecCKKS24hrNotification(); + SecOctagon24hrNotification(); } }); #endif + +#if OCTAGON && !TARGET_OS_BRIDGE + // Kick off reporting tasks. + if (os_variant_has_internal_diagnostics("com.apple.security") && !os_variant_is_recovery("securityd")) { + InitPolicyReporter(); + } +#endif } // 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR static void securityd_soscc_lock_hack() { dispatch_queue_t soscc_lock_queue = dispatch_queue_create("soscc_lock_queue", DISPATCH_QUEUE_PRIORITY_DEFAULT); int soscc_tok; @@ -1823,16 +1767,16 @@ static void securityd_soscc_lock_hack() { CFErrorRef error = NULL; uint64_t one_minute = 60ull; - if(SecAKSLockUserKeybag(one_minute, &error)){ + if(SecAKSUserKeybagHoldLockAssertion(one_minute, &error)){ // Prevent securityd from quitting while holding a keychain assertion - xpc_transaction_begin(); + os_transaction_t transaction = os_transaction_create("securityd-LockAssertedingHolder"); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, one_minute*NSEC_PER_SEC), soscc_lock_queue, ^{ CFErrorRef localError = NULL; - if(!SecAKSUnLockUserKeybag(&localError)) + if(!SecAKSUserKeybagDropLockAssertion(&localError)) secerror("failed to unlock: %@", localError); CFReleaseNull(localError); - xpc_transaction_end(); + os_release(transaction); }); } else { secerror("Failed to take device lock assertion: %@", error); @@ -1866,6 +1810,8 @@ homedirPath(void) int main(int argc, char *argv[]) { + DisableLocalization(); + char *wait4debugger = getenv("WAIT4DEBUGGER"); if (wait4debugger && !strcasecmp("YES", wait4debugger)) { seccritical("SIGSTOPing self, awaiting debugger"); @@ -1910,6 +1856,14 @@ int main(int argc, char *argv[]) #endif /* TARGET_OS_OSX */ const char *serviceName = kSecuritydXPCServiceName; + +// Mark our interest in running some features (before we bring the DB layer up) +#if OCTAGON + EscrowRequestServerSetEnabled(true); + OctagonSetShouldPerformInitialization(true); + SecCKKSEnable(); +#endif + /* setup SQDLite before some other component have a chance to create a database connection */ _SecDbServerSetup(); @@ -1917,17 +1871,21 @@ int main(int argc, char *argv[]) securityd_xpc_init(serviceName); SecCreateSecuritydXPCServer(); - CKKSControlServerInitialize(); +#if SECUREOBJECTSYNC SOSControlServerInitialize(); +#endif +#if OCTAGON + CKKSControlServerInitialize(); OctagonControlServerInitialize(); - SFKeychainServerInitialize(); - + EscrowRequestXPCServerInitialize(); +#endif + // 13B104+Roots:Device never moved past spinner after using approval to ENABLE icdp -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR securityd_soscc_lock_hack(); #endif - dispatch_main(); + CFRunLoopRun(); } /* vi:set ts=4 sw=4 et: */ diff --git a/OSX/sec/ipc/server_endpoint.m b/OSX/sec/ipc/server_endpoint.m index 4e9cb906..4d3fa424 100644 --- a/OSX/sec/ipc/server_endpoint.m +++ b/OSX/sec/ipc/server_endpoint.m @@ -27,12 +27,12 @@ #include #include -#include -#include -#include -#include +#include "ipc/securityd_client.h" +#include "ipc/server_security_helpers.h" +#include "ipc/server_entitlement_helpers.h" +#include "ipc/server_endpoint.h" -#include +#include "securityd/SecItemServer.h" #include #pragma mark - Securityd Server @@ -45,7 +45,9 @@ if ((self = [super init])) { _connection = connection; - fill_security_client(&self->_client, connection.effectiveUserIdentifier, connection.auditToken); + if (!fill_security_client(&self->_client, connection.effectiveUserIdentifier, connection.auditToken)) { + return nil; + } } return self; } @@ -66,7 +68,7 @@ self->_client.canAccessNetworkExtensionAccessGroups = existingClient->canAccessNetworkExtensionAccessGroups; self->_client.uid = existingClient->uid; self->_client.musr = CFRetainSafe(existingClient->musr); -#if TARGET_OS_EMBEDDED && TARGET_HAS_KEYSTORE +#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) && TARGET_HAS_KEYSTORE self->_client.keybag = existingClient->keybag; #endif #if TARGET_OS_IPHONE @@ -173,7 +175,7 @@ id SecCreateLocalSecuritydXPCServer(void) { } CFTypeRef SecCreateLocalCFSecuritydXPCServer(void) { - return (CFTypeRef) CFBridgingRetain(SecCreateLocalSecuritydXPCServer()); + return CFBridgingRetain(SecCreateLocalSecuritydXPCServer()); } void SecResetLocalSecuritydXPCFakeEntitlements(void) { diff --git a/OSX/sec/ipc/server_entitlement_helpers.c b/OSX/sec/ipc/server_entitlement_helpers.c index 93db1fda..3dd4c584 100644 --- a/OSX/sec/ipc/server_entitlement_helpers.c +++ b/OSX/sec/ipc/server_entitlement_helpers.c @@ -27,12 +27,12 @@ #include #include -#include +#include "ipc/securityd_client.h" #include #include -#include -#include -#include +#include "utilities/SecCFRelease.h" +#include "utilities/SecCFWrappers.h" +#include "utilities/debugging.h" CFStringRef SecTaskCopyStringForEntitlement(SecTaskRef task, CFStringRef entitlement) @@ -85,15 +85,15 @@ CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) { CFMutableArrayRef groups = NULL; -#if TARGET_SIMULATOR - groups = (CFMutableArrayRef)CFRetainSafe(SecAccessGroupsGetCurrent()); -#else CFArrayRef keychainAccessGroups, appleSecurityApplicationGroups; CFStringRef appID; + CFArrayRef associatedAppIDs; keychainAccessGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementKeychainAccessGroups); appleSecurityApplicationGroups = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAppleSecurityApplicationGroups); appID = SecTaskCopyApplicationIdentifier(task); + // Marzipan apps (may?) have this entitlement. + associatedAppIDs = SecTaskCopyArrayOfStringsForEntitlement(task, kSecEntitlementAssociatedApplicationIdentifier); groups = CFArrayCreateMutableForCFTypes(NULL); @@ -110,7 +110,10 @@ CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) 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. + // and not being properly signed. Assoc-app-id behaves similarly. + if (associatedAppIDs) { + CFArrayAppendAll(groups, associatedAppIDs); + } if (appID) { CFArrayAppendValue(groups, appID); } @@ -142,10 +145,10 @@ CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task) CFArrayAppendValue(groups, kSecAttrAccessGroupToken); } + CFReleaseNull(associatedAppIDs); CFReleaseNull(appID); CFReleaseNull(keychainAccessGroups); CFReleaseNull(appleSecurityApplicationGroups); -#endif return groups; } diff --git a/OSX/sec/ipc/server_entitlement_helpers.h b/OSX/sec/ipc/server_entitlement_helpers.h index e8a37b90..6027fbd1 100644 --- a/OSX/sec/ipc/server_entitlement_helpers.h +++ b/OSX/sec/ipc/server_entitlement_helpers.h @@ -25,7 +25,7 @@ #define server_entitlement_helpers_h #include -#include +#include "ipc/securityd_client.h" CFStringRef SecTaskCopyApplicationIdentifier(SecTaskRef task); CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task); diff --git a/OSX/sec/ipc/server_security_helpers.c b/OSX/sec/ipc/server_security_helpers.c deleted file mode 100644 index 88d71b90..00000000 --- a/OSX/sec/ipc/server_security_helpers.c +++ /dev/null @@ -1,120 +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@ - */ - -#include - -#include "server_security_helpers.h" -#include "server_entitlement_helpers.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if __has_include() && TARGET_HAS_KEYSTORE -#include -#define HAVE_MOBILE_KEYBAG_SUPPORT 1 -#endif - -#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED -static bool -device_is_multiuser(void) -{ - static dispatch_once_t once; - static bool result; - - dispatch_once(&once, ^{ - CFDictionaryRef deviceMode = MKBUserTypeDeviceMode(NULL, NULL); - CFTypeRef value = NULL; - - if (deviceMode && CFDictionaryGetValueIfPresent(deviceMode, kMKBDeviceModeKey, &value) && CFEqual(value, kMKBDeviceModeMultiUser)) { - result = true; - } - CFReleaseNull(deviceMode); - }); - - return result; -} -#endif /* HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED */ - -void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken) { - if(!client) { - return; - } - - client->uid = uid; - -#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED - - if (device_is_multiuser()) { - CFErrorRef error = NULL; - - client->inMultiUser = true; - client->activeUser = MKBForegroundUserSessionID(&error); - if (client->activeUser == -1 || client->activeUser == 0) { - assert(0); - client->activeUser = 0; - } - - /* - * If we are a edu mode user, and its not the active user, - * then the request is coming from inside the syncbubble. - * - * otherwise we are going to execute the request as the - * active user. - */ - - if (client->uid > 501 && (uid_t)client->activeUser != client->uid) { - secinfo("serverxpc", "securityd client: sync bubble user"); - client->musr = SecMUSRCreateSyncBubbleUserUUID(client->uid); - client->keybag = KEYBAG_DEVICE; - } else { - secinfo("serverxpc", "securityd client: active user"); - client->musr = SecMUSRCreateActiveUserUUID(client->activeUser); - client->uid = (uid_t)client->activeUser; - client->keybag = KEYBAG_DEVICE; - } - } -#endif - - client->task = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken); - - client->accessGroups = SecTaskCopyAccessGroups(client->task); - -#if TARGET_OS_IPHONE - client->allowSystemKeychain = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateSystemKeychain); - client->isNetworkExtension = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateNetworkExtension); - client->canAccessNetworkExtensionAccessGroups = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementNetworkExtensionAccessGroups); -#endif -#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_EMBEDDED - if (client->inMultiUser) { - client->allowSyncBubbleKeychain = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateKeychainSyncBubble); - } -#endif -} - diff --git a/OSX/sec/ipc/server_security_helpers.h b/OSX/sec/ipc/server_security_helpers.h index 0ff23beb..9986b7cb 100644 --- a/OSX/sec/ipc/server_security_helpers.h +++ b/OSX/sec/ipc/server_security_helpers.h @@ -25,14 +25,14 @@ #define server_security_helpers_h #include -#include +#include "ipc/securityd_client.h" CFTypeRef SecCreateLocalCFSecuritydXPCServer(void); void SecAddLocalSecuritydXPCFakeEntitlement(CFStringRef entitlement, CFTypeRef value); void SecResetLocalSecuritydXPCFakeEntitlements(void); void SecCreateSecuritydXPCServer(void); -void fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken); +bool fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken); CFArrayRef SecTaskCopyAccessGroups(SecTaskRef task); void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); diff --git a/OSX/sec/ipc/server_security_helpers.m b/OSX/sec/ipc/server_security_helpers.m new file mode 100644 index 00000000..946e16f3 --- /dev/null +++ b/OSX/sec/ipc/server_security_helpers.m @@ -0,0 +1,147 @@ +/* + * 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@ + */ + +#include + +#include "server_security_helpers.h" +#include "server_entitlement_helpers.h" + +#include +#include +#include "ipc/securityd_client.h" +#include +#include +#include "utilities/SecCFRelease.h" +#include "utilities/SecCFWrappers.h" +#include "utilities/debugging.h" +#include "securityd/SecDbQuery.h" + +#if __has_include() && TARGET_HAS_KEYSTORE +#include +#define HAVE_MOBILE_KEYBAG_SUPPORT 1 +#endif + +#if __has_include() +#include +#endif + +#if TARGET_OS_IOS && HAVE_MOBILE_KEYBAG_SUPPORT +static bool +device_is_multiuser(void) +{ + static dispatch_once_t once; + static bool result; + + dispatch_once(&once, ^{ + CFDictionaryRef deviceMode = MKBUserTypeDeviceMode(NULL, NULL); + CFTypeRef value = NULL; + + if (deviceMode && CFDictionaryGetValueIfPresent(deviceMode, kMKBDeviceModeKey, &value) && CFEqual(value, kMKBDeviceModeMultiUser)) { + result = true; + } + CFReleaseNull(deviceMode); + }); + + return result; +} +#endif /* HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_IOS */ + +bool +fill_security_client(SecurityClient * client, const uid_t uid, audit_token_t auditToken) { + if(!client) { + return false; + } + + @autoreleasepool { + + client->uid = uid; + client->musr = NULL; + +#if TARGET_OS_IOS +#if HAVE_MOBILE_KEYBAG_SUPPORT + if (device_is_multiuser()) { + CFErrorRef error = NULL; + + client->inMultiUser = true; + client->activeUser = MKBForegroundUserSessionID(&error); + if (client->activeUser == -1 || client->activeUser == 0) { + assert(0); + client->activeUser = 0; + } + + /* + * If we are a edu mode user, and its not the active user, + * then the request is coming from inside the syncbubble. + * + * otherwise we are going to execute the request as the + * active user. + */ + + if (client->uid > 501 && (uid_t)client->activeUser != client->uid) { + secinfo("serverxpc", "securityd client: sync bubble user"); + client->musr = SecMUSRCreateSyncBubbleUserUUID(client->uid); + client->keybag = KEYBAG_DEVICE; + } else { + secinfo("serverxpc", "securityd client: active user"); + client->musr = SecMUSRCreateActiveUserUUID(client->activeUser); + client->uid = (uid_t)client->activeUser; + client->keybag = KEYBAG_DEVICE; + } + } else +#endif + /* + * If the client application is a enterprise app according to usermanager, switch + * to the per enterprise slice of keychain. + */ + { + UMUserPersona * persona = [[UMUserManager sharedManager] currentPersona]; + if (persona && persona.userPersonaType == UMUserPersonaTypeEnterprise) { + secinfo("serverxpc", "securityd client: enterprise user"); + uuid_t uuid; + + if (uuid_parse([persona.userPersonaUniqueString UTF8String], uuid) != 0) { + return false; + } + client->musr = CFDataCreate(NULL, uuid, sizeof(uuid_t)); + } + } +#endif /* TARGET_OS_IOS */ + + client->task = SecTaskCreateWithAuditToken(kCFAllocatorDefault, auditToken); + + client->accessGroups = SecTaskCopyAccessGroups(client->task); + +#if TARGET_OS_IPHONE + client->allowSystemKeychain = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateSystemKeychain); + client->isNetworkExtension = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateNetworkExtension); + client->canAccessNetworkExtensionAccessGroups = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementNetworkExtensionAccessGroups); +#endif +#if HAVE_MOBILE_KEYBAG_SUPPORT && TARGET_OS_IOS + if (client->inMultiUser) { + client->allowSyncBubbleKeychain = SecTaskGetBooleanValueForEntitlement(client->task, kSecEntitlementPrivateKeychainSyncBubble); + } +#endif + } + return true; +} + diff --git a/OSX/sec/ipc/server_xpc.m b/OSX/sec/ipc/server_xpc.m index 8a55d96e..c311212f 100644 --- a/OSX/sec/ipc/server_xpc.m +++ b/OSX/sec/ipc/server_xpc.m @@ -28,6 +28,12 @@ #include #include +#if TARGET_DARWINOS +#undef OCTAGON +#undef SECUREOBJECTSYNC +#undef SHAREDWEBCREDENTIALS +#endif + #if OCTAGON #import "keychain/categories/NSError+UsefulConstructors.h" #include @@ -47,6 +53,8 @@ #include "keychain/ckks/CKKSViewManager.h" +#import "securityd/SecDbBackupManager.h" + @interface SecOSTransactionHolder : NSObject @property os_transaction_t transaction; - (instancetype)init:(os_transaction_t)transaction; @@ -350,10 +358,10 @@ } NSDictionary *attributes = @{ - (__bridge NSString *)kSecClass : itemClass, - (__bridge NSString *)kSecAttrAccessGroup : accessGroup, - (__bridge NSString *)kSecAttrSynchronizable : (__bridge NSString *)kSecAttrSynchronizableAny, - }; + (__bridge NSString *)kSecClass : itemClass, + (__bridge NSString *)kSecAttrAccessGroup : accessGroup, + (__bridge NSString *)kSecAttrSynchronizable : (__bridge NSString *)kSecAttrSynchronizableAny, + }; Query *q = query_create_with_limit((__bridge CFDictionaryRef)attributes, _client.musr, 0, &cferror); if (q == NULL) { @@ -378,4 +386,43 @@ } +- (void) secKeychainDeleteMultiuser:(NSData *)uuid + complete:(void(^)(bool status, NSError* error))complete +{ + __block CFErrorRef cferror = NULL; + +#define SKDMUEntitlement @"com.apple.keychain.multiuser-admin" + + if([self clientHasBooleanEntitlement: SKDMUEntitlement]) { + SecError(errSecNotAvailable, &cferror, CFSTR("secKeychainDeleteMultiuser: %@ need entitlement %@"), _client.task, SKDMUEntitlement); + complete(false, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + return; + } + if ([uuid length] != 16) { + SecError(errSecNotAvailable, &cferror, CFSTR("secKeychainDeleteMultiuser: %@ uuid have wrong length: %d"), _client.task, (int)[uuid length]); + complete(false, (__bridge NSError *)cferror); + CFReleaseNull(cferror); + return; + + } + +#if TARGET_OS_IPHONE + bool status = kc_with_dbt(true, &cferror, ^(SecDbConnectionRef dbt) { + return SecServerDeleteAllForUser(dbt, (__bridge CFDataRef)uuid, false, &cferror); + }); +#else + bool status = false; +#endif + + complete(status, (__bridge NSError *)cferror); + CFReleaseNull(cferror); +} + +- (void)secItemVerifyBackupIntegrity:(BOOL)lightweight + completion:(void (^)(NSDictionary* results, NSError* error))completion +{ + [[SecDbBackupManager manager] verifyBackupIntegrity:lightweight completion:completion]; +} + @end diff --git a/protocol/SecProtocol.h b/OSX/sec/ipc/util.h similarity index 80% rename from protocol/SecProtocol.h rename to OSX/sec/ipc/util.h index 6f333f55..39745e15 100644 --- a/protocol/SecProtocol.h +++ b/OSX/sec/ipc/util.h @@ -19,14 +19,18 @@ * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ + * */ -#ifndef SecProtocol_h -#define SecProtocol_h +#ifndef _UTIL +#define _UTIL -#include -#include -#include -#include +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus +void DisableLocalization(void); +#ifdef __cplusplus +} +#endif // __cplusplus -#endif // SecProtocol_h +#endif // _UTIL diff --git a/OSX/libsecurity_transform/custom.h b/OSX/sec/ipc/util.m similarity index 81% rename from OSX/libsecurity_transform/custom.h rename to OSX/sec/ipc/util.m index 3e308d53..9249ab30 100644 --- a/OSX/libsecurity_transform/custom.h +++ b/OSX/sec/ipc/util.m @@ -1,15 +1,15 @@ /* - * Copyright (c) 2010-2011,2014 Apple Inc. All Rights Reserved. + * 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, @@ -17,16 +17,15 @@ * 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 "util.h" -#import - - -@interface custom : XCTestCase { +#import +void DisableLocalization(void) { + [NSError _setFileNameLocalizationEnabled:NO]; } - -@end diff --git a/OSX/sec/os_log/com.apple.securityd.plist b/OSX/sec/os_log/com.apple.securityd.plist index 3d7b7702..87da5a3d 100644 --- a/OSX/sec/os_log/com.apple.securityd.plist +++ b/OSX/sec/os_log/com.apple.securityd.plist @@ -28,7 +28,7 @@ Persist True TTL - 2d + 2 circleOps @@ -60,5 +60,25 @@ 14 + item + + Default-Privacy-Setting + Public + Enabled + True + Persist + True + TTL + 30 + Development + + Enabled + True + Persist + True + TTL + 30 + + diff --git a/OSX/sec/securityd/AsymKeybagBackup.m b/OSX/sec/securityd/AsymKeybagBackup.m deleted file mode 100644 index bf21ed08..00000000 --- a/OSX/sec/securityd/AsymKeybagBackup.m +++ /dev/null @@ -1,147 +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@ - */ - -#include -#import -#include -#import "AsymKeybagBackup.h" -#import - -#if USE_KEYSTORE -#include -#endif - -#include -#include -#include "sec/ipc/securityd_client.h" - -#if OCTAGON -#import "SecBackupKeybagEntry.h" -#endif - -#if OCTAGON -#if USE_KEYSTORE - -static bool writeKeybagPublicKey(CFDataRef keybag, CFDataRef identifier, CFErrorRef *error) { - bool ok = true; - NSData* publickeyHash = (__bridge NSData *)(identifier); - NSData* musr = [[NSData alloc] init]; - NSError *localError = NULL; - - SecBackupKeybagEntry *kbe = [[SecBackupKeybagEntry alloc] initWithPublicKey: (__bridge NSData*)keybag publickeyHash: (NSData*) publickeyHash user: musr]; - ok = [kbe saveToDatabase: &localError]; - CFErrorPropagate((__bridge CFErrorRef)(localError), error); - return ok; -} - -static bool deleteKeybagViaPublicKeyHash(CFDataRef publickeyHash, CFStringRef agrp, CFDataRef musr, CFErrorRef *error) { - bool ok = true; - NSData* keybag = nil; - NSError *localError = NULL; - - SecBackupKeybagEntry *kbe = [[SecBackupKeybagEntry alloc] initWithPublicKey: keybag publickeyHash: (__bridge NSData*)publickeyHash user: (__bridge NSData *)(musr)]; - ok = [kbe deleteFromDatabase: &localError]; - - CFErrorPropagate((__bridge CFErrorRef)(localError), error); - return ok; -} - -static bool deleteAllKeybags(CFErrorRef *error) { - NSError *localError = NULL; - - bool ok = [SecBackupKeybagEntry deleteAll: &localError]; - - CFErrorPropagate((__bridge CFErrorRef)(localError), error); - return ok; -} - -#endif -#endif - -bool _SecServerBackupKeybagAdd(SecurityClient *client, CFDataRef passcode, CFDataRef *identifier, CFDataRef *pathinfo, CFErrorRef *error) { - bool ok = true; -#if OCTAGON -#if USE_KEYSTORE - CFURLRef upathinfo = NULL; - CFDataRef keybagData = NULL; - uuid_t uuid; - char uuidstr[37]; - CFDataRef tidentifier = NULL; - - secerror("_SecServerBackupKeybagAdd: passlen: %ld", CFDataGetLength(passcode) ); - - require_action(passcode && CFDataGetLength(passcode), xit, ok = SecError(errSecParam, error, CFSTR("passcode is required"))); - keybag_handle_t handle = bad_keybag_handle; - - kern_return_t kr = aks_create_bag(CFDataGetBytePtr(passcode), (int)CFDataGetLength(passcode), kAppleKeyStoreAsymmetricBackupBag, &handle); - require_action(kr == kIOReturnSuccess, xit, ok = SecError(errSecParam, error, CFSTR("could not create keybag: %d"), kr)); - - void *keybag = NULL; - int keybag_size = 0; - kr = aks_save_bag(handle, &keybag, &keybag_size); - require_action(kr == kIOReturnSuccess, xit, ok = SecError(errSecParam, error, CFSTR("could not save keybag: %d"), kr)); - keybagData = CFDataCreate(kCFAllocatorDefault, keybag, keybag_size); - - // For now, use uuid as key in db; will use publicKey hash later - kr = aks_get_bag_uuid(handle, uuid); - require_action(kr == kIOReturnSuccess, xit, ok = SecError(errSecParam, error, CFSTR("could not get keybag uuid: %d"), kr)); - - tidentifier = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)uuidstr, sizeof(uuidstr)); - uuid_unparse_lower(uuid, uuidstr); - if (identifier) - *identifier = CFRetainSafe(tidentifier); - - require_action(writeKeybagPublicKey(keybagData, tidentifier, error), xit, ok = SecError(errSecParam, error, CFSTR("passcode is required"))); - - if (pathinfo) - *pathinfo = NULL; -xit: - CFReleaseNull(tidentifier); - CFReleaseNull(upathinfo); - CFReleaseNull(keybagData); -#endif /* USE_KEYSTORE */ -#endif - return ok; -} - -bool _SecServerBackupKeybagDelete(CFDictionaryRef attributes, bool deleteAll, CFErrorRef *error) { - bool ok = true; -#if OCTAGON -#if USE_KEYSTORE - // Look for matching publicKeyHash - - if (deleteAll) { - deleteAllKeybags(error); - } else { - CFDataRef publickeyHash = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrPublicKeyHash); - CFStringRef agrp = (CFStringRef)CFDictionaryGetValue(attributes, kSecAttrAccessGroup); - CFDataRef musr = (CFDataRef)CFDictionaryGetValue(attributes, kSecAttrMultiUser); - - require_action(publickeyHash, xit, ok = SecError(errSecParam, error, CFSTR("publickeyHash is required"))); - ok = deleteKeybagViaPublicKeyHash(publickeyHash, agrp, musr, error); - } -xit: -#endif /* USE_KEYSTORE */ -#endif /* OCTAGON */ - return ok; -} diff --git a/OSX/sec/securityd/CheckV12DevEnabled.h b/OSX/sec/securityd/CheckV12DevEnabled.h new file mode 100644 index 00000000..34c930d5 --- /dev/null +++ b/OSX/sec/securityd/CheckV12DevEnabled.h @@ -0,0 +1,14 @@ +// +// CheckV12DevEnabled.h +// Security_ios +// +// Created by Wouter de Groot on 2018-10-20. +// + +#ifndef CHECKV12DEVENABLED_H_ +#define CHECKV12DEVENABLED_H_ + +void resetCheckV12DevEnabled(void); +extern int (*checkV12DevEnabled)(void); + +#endif diff --git a/OSX/sec/securityd/CheckV12DevEnabled.m b/OSX/sec/securityd/CheckV12DevEnabled.m new file mode 100644 index 00000000..b211e141 --- /dev/null +++ b/OSX/sec/securityd/CheckV12DevEnabled.m @@ -0,0 +1,33 @@ +// +// CheckV12DevEnabled.m +// Security_ios +// +// Created by Wouter de Groot on 2018-10-20. +// + +// TODO: remove me when keychain backup is enabled for all + +#include "CheckV12DevEnabled.h" + +#if __OBJC2__ + +#import +#import + +static int realCheckV12DevEnabled() { + static bool enabled = NO; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.security"]; + enabled = [defaults boolForKey:@"enableKeychainBackupDevelopment"]; + }); + return enabled ? 1 : 0; +} + +int (*checkV12DevEnabled)(void) = realCheckV12DevEnabled; + +void resetCheckV12DevEnabled(void) { + checkV12DevEnabled = realCheckV12DevEnabled; +} + +#endif diff --git a/OSX/sec/securityd/OTATrustUtilities.h b/OSX/sec/securityd/OTATrustUtilities.h index 38f99053..4b770f9d 100644 --- a/OSX/sec/securityd/OTATrustUtilities.h +++ b/OSX/sec/securityd/OTATrustUtilities.h @@ -29,6 +29,7 @@ #include #include #include +#include __BEGIN_DECLS @@ -38,9 +39,16 @@ typedef struct _OpaqueSecOTAPKI *SecOTAPKIRef; // Returns a boolean for whether the current instance is the system trustd bool SecOTAPKIIsSystemTrustd(void); +// Returns the trust server workloop +dispatch_queue_t SecTrustServerGetWorkloop(void); + +// Convert a trusted CT log array to a trusted CT log dictionary, indexed by the LogID +CF_RETURNS_RETAINED +CFDictionaryRef SecOTAPKICreateTrustedCTLogsDictionaryFromArray(CFArrayRef trustedCTLogsArray); + // Get a reference to the current OTA PKI asset data // Caller is responsible for releasing the returned SecOTAPKIRef -CF_EXPORT +CF_EXPORT CF_RETURNS_RETAINED SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef(void); // Accessor to retrieve a copy of the current black listed key. @@ -66,7 +74,7 @@ CFArrayRef SecOTAPKICopyAllowListForAuthKeyID(SecOTAPKIRef otapkiRef, CFStringRe // Accessor to retrieve a copy of the current trusted certificate transparency logs. // Caller is responsible for releasing the returned CFArrayRef CF_EXPORT -CFArrayRef SecOTAPKICopyTrustedCTLogs(SecOTAPKIRef otapkiRef); +CFDictionaryRef SecOTAPKICopyTrustedCTLogs(SecOTAPKIRef otapkiRef); // Accessor to retrieve the path of the current pinning list. // Caller is responsible for releasing the returned CFURLRef @@ -152,6 +160,14 @@ bool SecOTAPKIKillSwitchEnabled(SecOTAPKIRef otapkiRef, CFStringRef switchKey); CF_EXPORT CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(uint32_t escrowRootType, CFErrorRef* error); +// SPI to return the array of currently trusted CT logs +CF_EXPORT +CFDictionaryRef SecOTAPKICopyCurrentTrustedCTLogs(CFErrorRef* error); + +// SPI to return dictionary of CT log matching specified key id */ +CF_EXPORT +CFDictionaryRef SecOTAPKICopyCTLogForKeyID(CFDataRef keyID, CFErrorRef* error); + // SPI to return the current OTA PKI trust store version // Note: Trust store is not mutable by assets CF_EXPORT @@ -161,6 +177,10 @@ uint64_t SecOTAPKIGetCurrentTrustStoreVersion(CFErrorRef* CF_RETURNS_RETAINED e CF_EXPORT uint64_t SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error); +// SPI to return the current OTA SecExperiment asset version +CF_EXPORT +uint64_t SecOTASecExperimentGetCurrentAssetVersion(CFErrorRef* error); + // SPI to reset the current OTA PKI asset version to the version shipped // with the system CF_EXPORT @@ -172,6 +192,22 @@ uint64_t SecOTAPKIResetCurrentAssetVersion(CFErrorRef* CF_RETURNS_RETAINED erro CF_EXPORT uint64_t SecOTAPKISignalNewAsset(CFErrorRef* CF_RETURNS_RETAINED error); +// SPI to signal trustd to get a new set of SecExperiment data +// Always returns the current asset version. Returns an error with +// a reason if the update was not successful. +CF_EXPORT +uint64_t SecOTASecExperimentGetNewAsset(CFErrorRef* error); + +// SPI to copy current SecExperiment asset data +CF_EXPORT +CFDictionaryRef SecOTASecExperimentCopyAsset(CFErrorRef* error); + +/* "Internal" interfaces for tests */ +#if !TARGET_OS_BRIDGE && __OBJC__ +BOOL UpdateOTACheckInDate(void); +void UpdateKillSwitch(NSString *key, bool value); +#endif + __END_DECLS #endif /* _OTATRUSTUTILITIES_H_ */ diff --git a/OSX/sec/securityd/OTATrustUtilities.m b/OSX/sec/securityd/OTATrustUtilities.m index 5c90306d..c9510aa0 100644 --- a/OSX/sec/securityd/OTATrustUtilities.m +++ b/OSX/sec/securityd/OTATrustUtilities.m @@ -51,8 +51,10 @@ #include #include #include +#include #include #include +#import #if !TARGET_OS_BRIDGE #import @@ -68,10 +70,6 @@ #include #endif -#if TARGET_OS_OSX -#import -#endif - static inline bool isNSNumber(id nsType) { return nsType && [nsType isKindOfClass:[NSNumber class]]; } @@ -88,6 +86,10 @@ static inline bool isNSDate(id nsType) { return nsType && [nsType isKindOfClass:[NSDate class]]; } +static inline bool isNSData(id nsType) { + return nsType && [nsType isKindOfClass:[NSData class]]; +} + #define SECURITYD_ROLE_ACCOUNT 64 #define ROOT_ACCOUNT 0 @@ -96,9 +98,10 @@ bool SecOTAPKIIsSystemTrustd() { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ #ifdef NO_SERVER - // Test app running as securityd + // Test app running as trustd #elif TARGET_OS_IPHONE - if (getuid() == SECURITYD_ROLE_ACCOUNT) + if (getuid() == SECURITYD_ROLE_ACCOUNT || + (getuid() == ROOT_ACCOUNT && gTrustd)) // Test app running as trustd #else if (getuid() == ROOT_ACCOUNT) #endif @@ -109,6 +112,15 @@ bool SecOTAPKIIsSystemTrustd() { return result; } +dispatch_queue_t SecTrustServerGetWorkloop(void) { + static dispatch_workloop_t workloop = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + workloop = dispatch_workloop_create("com.apple.trustd.evaluation"); + }); + return workloop; +} + /* MARK: - */ /* MARK: System Trust Store */ static CFStringRef kSecSystemTrustStoreBundlePath = CFSTR("/System/Library/Security/Certificates.bundle"); @@ -182,11 +194,8 @@ static uint64_t GetAssetVersion(CFErrorRef *error); static uint64_t GetSystemVersion(CFStringRef key); #if !TARGET_OS_BRIDGE static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version, NSError **error); -static BOOL UpdateOTACheckInDate(void); -static void UpdateKillSwitch(NSString *key, bool value); -#endif -#if TARGET_OS_IPHONE -static void TriggerUnlockNotificationOTATrustAssetCheck(dispatch_queue_t queue); +static NSNumber *SecExperimentUpdateAsset(MAAsset *asset, NSNumber *asset_version, NSError **error); +static void TriggerUnlockNotificationOTATrustAssetCheck(NSString* assetType, dispatch_queue_t queue); #endif /* This queue is for fetching changes to the OTAPKI reference or otherwise doing maintenance activities */ @@ -199,19 +208,23 @@ NSString *kOTATrustContextFilename = @"OTAPKIContext.plist"; NSString *kOTATrustTrustedCTLogsFilename = @"TrustedCTLogs.plist"; NSString *kOTATrustAnalyticsSamplingRatesFilename = @"AnalyticsSamplingRates.plist"; NSString *kOTATrustAppleCertifcateAuthoritiesFilename = @"AppleCertificateAuthorities.plist"; -NSString *kOTATrustCTKillSwitch = @"CTKillSwitch"; +NSString *kOTASecExperimentConfigFilename = @"SecExperimentAssets.plist"; const CFStringRef kOTAPKIKillSwitchCT = CFSTR("CTKillSwitch"); #if !TARGET_OS_BRIDGE -const NSString *OTATrustMobileAssetType = @"com.apple.MobileAsset.PKITrustSupplementals"; -#define kOTATrustMobileAssetNotification "com.apple.MobileAsset.PKITrustSupplementals.cached-metadata-updated" +NSString *OTATrustMobileAssetType = @"com.apple.MobileAsset.PKITrustSupplementals"; +NSString *OTASecExperimentMobileAssetType = @"com.apple.MobileAsset.SecExperimentAssets"; +#define kOTATrustMobileAssetNotification "com.apple.MobileAsset.PKITrustSupplementals.ma.cached-metadata-updated" #define kOTATrustOnDiskAssetNotification "com.apple.trustd.asset-updated" #define kOTATrustCheckInNotification "com.apple.trustd.asset-check-in" #define kOTATrustKillSwitchNotification "com.apple.trustd.kill-switch" +#define kOTASecExperimentNewAssetNotification "com.apple.trustd.secexperiment.asset-updated" const NSUInteger OTATrustMobileAssetCompatibilityVersion = 1; +const NSUInteger OTASecExperimentMobileAssetCompatibilityVersion = 1; #define kOTATrustDefaultUpdatePeriod 60*60*12 // 12 hours #define kOTATrustMinimumUpdatePeriod 60*5 // 5 min +#define kOTATrustDefaultWaitPeriod 60 // 1 min #if TARGET_OS_OSX const CFStringRef kSecSUPrefDomain = CFSTR("com.apple.SoftwareUpdate"); @@ -227,14 +240,14 @@ typedef enum { OTATrustLogLevelError, } OTATrustLogLevel; -static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(5,6); -static void MakeOTATrustErrorWithAttributes(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, +static void MakeOTATrustError(NSString *assetType, NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) NS_FORMAT_FUNCTION(6,7); +static void MakeOTATrustErrorWithAttributes(NSString *assetType, NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSDictionary *attributes, NSString *format,...) - NS_FORMAT_FUNCTION(6,7); + NS_FORMAT_FUNCTION(7,8); -static void MakeOTATrustErrorArgs(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, +static void MakeOTATrustErrorArgs(NSString *assetType, NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSDictionary *attributes, NSString *format, va_list arguments) - NS_FORMAT_FUNCTION(6,0); + NS_FORMAT_FUNCTION(7,0); static void LogLocally(OTATrustLogLevel level, NSString *errorString) { switch (level) { @@ -270,7 +283,7 @@ static void LogRemotely(OTATrustLogLevel level, NSError **error) { LogRemotelyWithAttributes(level, error, nil); } -static void MakeOTATrustErrorArgs(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, +static void MakeOTATrustErrorArgs(NSString *assetType, NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSDictionary *attributes, NSString *format, va_list args) { NSString *formattedString = nil; if (format) { @@ -290,22 +303,24 @@ static void MakeOTATrustErrorArgs(NSError **error, OTATrustLogLevel level, NSErr userInfo:userInfo]; LogLocally(level, formattedString); - LogRemotelyWithAttributes(level, &localError, attributes); + if ([assetType isEqualToString:OTATrustMobileAssetType]) { + LogRemotelyWithAttributes(level, &localError, attributes); + } if (error) { *error = localError; } } -static void MakeOTATrustErrorWithAttributes(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, +static void MakeOTATrustErrorWithAttributes(NSString *assetType, NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSDictionary *attributes, NSString *format,...) { va_list args; va_start(args, format); - MakeOTATrustErrorArgs(error, level, errDomain, errCode, attributes, format, args); + MakeOTATrustErrorArgs(assetType, error, level, errDomain, errCode, attributes, format, args); va_end(args); } -static void MakeOTATrustError(NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) { +static void MakeOTATrustError(NSString *assetType, NSError **error, OTATrustLogLevel level, NSErrorDomain errDomain, OSStatus errCode, NSString *format,...) { va_list args; va_start(args, format); - MakeOTATrustErrorArgs(error, level, errDomain, errCode, nil, format, args); + MakeOTATrustErrorArgs(assetType, error, level, errDomain, errCode, nil, format, args); va_end(args); } @@ -340,12 +355,19 @@ static BOOL CanCheckMobileAsset(void) { return result; } -static BOOL ShouldUpdateWithAsset(NSNumber *asset_version) { +static BOOL ShouldUpdateWithAsset(NSString *assetType, NSNumber *asset_version) { if (![asset_version isKindOfClass:[NSNumber class]]) { return NO; } CFErrorRef error = nil; - uint64_t current_version = SecOTAPKIGetCurrentAssetVersion(&error); + uint64_t current_version; + if ([assetType isEqualToString:OTATrustMobileAssetType]) { + current_version = SecOTAPKIGetCurrentAssetVersion(&error); + } else if ([assetType isEqualToString:OTASecExperimentMobileAssetType]) { + current_version = SecOTASecExperimentGetCurrentAssetVersion(&error); + } else { + return NO; + } if (error) { CFReleaseNull(error); return NO; @@ -356,6 +378,7 @@ static BOOL ShouldUpdateWithAsset(NSNumber *asset_version) { return NO; } +// MARK: File management functions static bool verify_create_path(const char *path) { int ret = mkpath_np(path, 0755); if (!(ret == 0 || ret == EEXIST)) { @@ -365,14 +388,9 @@ static bool verify_create_path(const char *path) { return true; } -// MARK: File management functions static NSURL *GetAssetFileURL(NSString *filename) { /* Make sure the /Library/Keychains directory is there */ -#if TARGET_OS_IPHONE - NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); -#else - NSURL *keychainsDirectory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; -#endif + NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInSystemKeychainDirectory(nil)); NSURL *directory = [keychainsDirectory URLByAppendingPathComponent:@"SupplementalsAssets/" isDirectory:YES]; if (!verify_create_path([directory fileSystemRepresentation])) { return nil; @@ -450,13 +468,13 @@ static bool ChangeFileProtectionToClassD(NSURL *fileURL, NSError **error) { if (file_fd) { int retval = fcntl(file_fd, F_SETPROTECTIONCLASS, PROTECTION_CLASS_D); if (retval < 0) { - MakeOTATrustError(error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno, + MakeOTATrustError(OTATrustMobileAssetType, error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno, @"set proteciton class error for asset %d: %s", errno, strerror(errno)); result = NO; } close(file_fd); } else { - MakeOTATrustError(error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno, + MakeOTATrustError(OTATrustMobileAssetType, error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno, @"open error for asset %d: %s", errno, strerror(errno)); result = NO; } @@ -473,7 +491,7 @@ static BOOL CopyFileToDisk(NSString *filename, NSURL *localURL, NSError **error) state, COPYFILE_DATA); copyfile_state_free(state); if (retval < 0) { - MakeOTATrustError(error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno, + MakeOTATrustError(OTATrustMobileAssetType, error, OTATrustLogLevelError, NSPOSIXErrorDomain, errno, @"copyfile error for asset %d: %s", errno, strerror(errno)); return NO; } else { @@ -492,11 +510,11 @@ static void GetKillSwitchAttributes(NSDictionary *attributes) { bool killSwitchEnabled = false; // CT Kill Switch - NSNumber *ctKillSwitch = [attributes objectForKey:kOTATrustCTKillSwitch]; + NSNumber *ctKillSwitch = [attributes objectForKey:(__bridge NSString*)kOTAPKIKillSwitchCT]; if (isNSNumber(ctKillSwitch)) { NSError *error = nil; - UpdateOTAContextOnDisk(kOTATrustCTKillSwitch, ctKillSwitch, &error); - UpdateKillSwitch(kOTATrustCTKillSwitch, [ctKillSwitch boolValue]); + UpdateOTAContextOnDisk((__bridge NSString*)kOTAPKIKillSwitchCT, ctKillSwitch, &error); + UpdateKillSwitch((__bridge NSString*)kOTAPKIKillSwitchCT, [ctKillSwitch boolValue]); secnotice("OTATrust", "got CT kill switch = %d", [ctKillSwitch boolValue]); killSwitchEnabled = true; } @@ -513,8 +531,7 @@ static void GetKillSwitchAttributes(NSDictionary *attributes) { } // MARK: Fetch and Update Functions -#if TARGET_OS_IPHONE -static NSNumber *UpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NSError **error) { +static NSNumber *PKIUpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NSError **error) { if (SecPinningDbUpdateFromURL([asset getLocalFileUrl], error) && UpdateFromAsset([asset getLocalFileUrl], asset_version, error)) { secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version); @@ -528,12 +545,22 @@ static NSNumber *UpdateAndPurgeAsset(MAAsset *asset, NSNumber *asset_version, NS }]; return asset_version; } else { - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecCallbackFailed, + MakeOTATrustError(OTATrustMobileAssetType, error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecCallbackFailed, @"Failed to install new asset version %@ from %@", asset_version, [asset getLocalFileUrl]); return nil; } } +static NSNumber *UpdateAndPurgeAsset(NSString* assetType, MAAsset *asset, NSNumber *asset_version, NSError **error) { + if ([assetType isEqualToString:OTATrustMobileAssetType]) { + return PKIUpdateAndPurgeAsset(asset, asset_version, error); + } else if ([assetType isEqualToString:OTASecExperimentMobileAssetType]) { + return SecExperimentUpdateAsset(asset, asset_version, error); + } else { + return nil; + } +} + static MADownloadOptions *GetMADownloadOptions(BOOL wait) { /* default behavior */ MADownloadOptions *options = [[MADownloadOptions alloc] init]; @@ -561,9 +588,57 @@ static MADownloadOptions *GetMADownloadOptions(BOOL wait) { return options; } -static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) { +static BOOL assetVersionCheck(NSString *assetType, MAAsset *asset) { + NSUInteger compatVersion; + NSError *ma_error = nil; + if ([assetType isEqualToString:OTATrustMobileAssetType]) { + compatVersion = OTATrustMobileAssetCompatibilityVersion; + } else { + compatVersion = OTASecExperimentMobileAssetCompatibilityVersion; + } + /* Check Compatibility Version against this software version */ + NSNumber *compatibilityVersion = [asset assetProperty:@"_CompatibilityVersion"]; + if (!isNSNumber(compatibilityVersion) || + [compatibilityVersion unsignedIntegerValue] != compatVersion) { + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecIncompatibleVersion, + @"skipping asset %@ because Compatibility Version doesn't match %@", assetType, compatibilityVersion); + return NO; + } + /* Check Content Version against the current content version */ + NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; + if (!ShouldUpdateWithAsset(assetType, asset_version)) { + /* write the version and last (successful) check-in time */ + if ([assetType isEqualToString:OTATrustMobileAssetType]) { + UpdateOTAContext(asset_version, &ma_error); + NSDictionary *eventAttributes = @{ + @"assetVersion" : asset_version, + @"systemVersion" : @(GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey)), + @"installedVersion" : @(SecOTAPKIGetCurrentAssetVersion(nil)), + }; + MakeOTATrustErrorWithAttributes(assetType, &ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, eventAttributes, + @"skipping asset %@ because we already have _ContentVersion %@ (or newer)", assetType, asset_version); + } else { + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, + @"skipping asset %@ because we already have _ContentVersion %@ (or newer)", assetType, asset_version); + } + return NO; + } + return YES; +} + +static int downloadWaitTime(void) { + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.security"]; + NSNumber *updateTimeout = [defaults valueForKey:@"TrustdAssetDownloadWaitTimeout"]; + int timeout = kOTATrustDefaultWaitPeriod; + if (isNSNumber(updateTimeout)) { + timeout = [updateTimeout intValue]; + } + return timeout; +} + +static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSString *assetType, NSError **error) { if (!CanCheckMobileAsset()) { - MakeOTATrustError(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable, + MakeOTATrustError(assetType, error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecServiceNotAvailable, @"MobileAsset disabled, skipping check."); return NO; } @@ -571,93 +646,78 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) __block NSNumber *updated_version = nil; __block dispatch_semaphore_t done = wait ? dispatch_semaphore_create(0) : nil; __block NSError *ma_error = nil; - secnotice("OTATrust", "begin MobileAsset query for catalog"); - [MAAsset startCatalogDownload:(NSString *)OTATrustMobileAssetType options:GetMADownloadOptions(wait) then:^(MADownLoadResult result) { + + secnotice("OTATrust", "begin MobileAsset query for catalog %@", assetType); + [MAAsset startCatalogDownload:assetType options:GetMADownloadOptions(wait) then:^(MADownLoadResult result) { @autoreleasepool { - os_transaction_t transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.download"); - if (result != MADownloadSucceesful) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", (OSStatus)result, - @"failed to download catalog: %ld", (long)result); - if (result == MADownloadDaemonNotReady) { - /* mobileassetd has to wait for first unlock to downalod. trustd usually launches before first unlock. */ - TriggerUnlockNotificationOTATrustAssetCheck(kOTABackgroundQueue); + os_transaction_t transaction = os_transaction_create("com.apple.trustd.asset.download"); + if (result != MADownloadSuccessful) { + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelError, @"MADownLoadResult", (OSStatus)result, + @"failed to download catalog for asset %@: %ld", assetType, (long)result); + if (result == MADownloadDaemonNotReady && ([assetType isEqualToString:OTATrustMobileAssetType])) { + /* mobileassetd has to wait for first unlock to download. trustd usually launches before first unlock. */ + TriggerUnlockNotificationOTATrustAssetCheck(assetType, kOTABackgroundQueue); } return; } - MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)OTATrustMobileAssetType]; + MAAssetQuery *query = [[MAAssetQuery alloc] initWithType:(NSString *)assetType]; [query augmentResultsWithState:true]; - secnotice("OTATrust", "begin MobileAsset metadata sync request"); + secnotice("OTATrust", "begin MobileAsset metadata sync request %{public}@", assetType); MAQueryResult queryResult = [query queryMetaDataSync]; - if (queryResult != MAQuerySucceesful) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAQueryResult", (OSStatus)queryResult, - @"failed to query MobileAsset metadata: %ld", (long)queryResult); + if (queryResult != MAQuerySuccessful) { + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelError, @"MAQueryResult", (OSStatus)queryResult, + @"failed to query MobileAsset %@ metadata: %ld", assetType, (long)queryResult); return; } if (!query.results) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, - @"no results in MobileAsset query"); + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, + @"no results in MobileAsset query for %@", assetType); 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; - } - - /* Check Content Version against the current content version */ NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; - if (!ShouldUpdateWithAsset(asset_version)) { - /* write the version and last (successful) check-in time */ - UpdateOTAContext(asset_version, &ma_error); - NSDictionary *eventAttributes = @{ - @"assetVersion" : asset_version, - @"systemVersion" : @(GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey)), - @"installedVersion" : @(SecOTAPKIGetCurrentAssetVersion(nil)), - }; - MakeOTATrustErrorWithAttributes(&ma_error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, eventAttributes, - @"skipping asset because we already have _ContentVersion %@ (or newer)", asset_version); + if (!assetVersionCheck(assetType, asset)) { continue; } - GetKillSwitchAttributes(asset.attributes); + if ([assetType isEqualToString:OTATrustMobileAssetType]) { + GetKillSwitchAttributes(asset.attributes); + } switch (asset.state) { default: - MakeOTATrustError(&ma_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, + MakeOTATrustError(assetType, &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); + secdebug("OTATrust", "OTATrust asset %{public}@ already installed", assetType); + updated_version = UpdateAndPurgeAsset(assetType, asset, asset_version, &ma_error); break; case MAUnknown: - MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MAAssetState", (OSStatus)asset.state, - @"asset is unknown"); + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelError, @"MAAssetState", (OSStatus)asset.state, + @"asset %@ is unknown", assetType); continue; case MADownloading: - secnotice("OTATrust", "asset is downloading"); + secnotice("OTATrust", "asset %{public}@ is downloading", assetType); /* fall through */ case MANotPresent: secnotice("OTATrust", "begin download of OTATrust asset"); began_async_job = true; [asset startDownload:GetMADownloadOptions(wait) then:^(MADownLoadResult downloadResult) { @autoreleasepool { - os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.PKITrustSupplementals.downloadAsset"); - if (downloadResult != MADownloadSucceesful) { - MakeOTATrustError(&ma_error, OTATrustLogLevelError, @"MADownLoadResult", (OSStatus)downloadResult, - @"failed to download asset: %ld", (long)downloadResult); + os_transaction_t inner_transaction = os_transaction_create("com.apple.trustd.asset.downloadAsset"); + if (downloadResult != MADownloadSuccessful) { + MakeOTATrustError(assetType, &ma_error, OTATrustLogLevelError, @"MADownLoadResult", (OSStatus)downloadResult, + @"failed to download asset %@: %ld", assetType, (long)downloadResult); return; } - updated_version = UpdateAndPurgeAsset(asset, asset_version, &ma_error); + updated_version = UpdateAndPurgeAsset(assetType, asset, asset_version, &ma_error); if (wait) { dispatch_semaphore_signal(done); } @@ -685,15 +745,15 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) * an unknown error. */ BOOL result = NO; if (wait) { - if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecNetworkFailure, - @"Failed to get asset metadata within 1 minute."); + if (dispatch_semaphore_wait(done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * downloadWaitTime())) != 0) { + MakeOTATrustError(assetType, error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecNetworkFailure, + @"Failed to get asset %@ metadata within %d seconds.", assetType, downloadWaitTime()); } else { result = (updated_version != nil); if (error && ma_error) { *error = ma_error; } else if (!result) { - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent, + MakeOTATrustError(assetType, error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent, @"Unknown error occurred."); } } @@ -701,228 +761,24 @@ static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) return result; } -static void TriggerUnlockNotificationOTATrustAssetCheck(dispatch_queue_t queue) { +static void TriggerUnlockNotificationOTATrustAssetCheck(NSString* assetType, dispatch_queue_t queue) { SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); /* If the last check-in is recent enough, wait for our regularly scheduled check-in. */ if (SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessAtRisk)) { CFReleaseNull(otapkiref); return; } + CFReleaseNull(otapkiref); #if !TARGET_OS_SIMULATOR /* register for unlock notifications */ int out_token = 0; notify_register_dispatch(kMobileKeyBagLockStatusNotificationID, &out_token, queue, ^(int token) { secnotice("OTATrust", "Got lock status notification for at-risk last check-in after MA daemon error"); - (void)DownloadOTATrustAsset(NO, NO, nil); + (void)DownloadOTATrustAsset(NO, NO, assetType, nil); notify_cancel(token); }); #endif } -#else /* !TARGET_OS_IPHONE */ -/* MobileAssetV2 fails on macOS, so use V1 */ -static NSNumber *UpdateAndPurgeAsset(ASAsset *asset, NSNumber *asset_version, NSError **error) { - if (SecPinningDbUpdateFromURL([asset localURL], error) && - UpdateFromAsset([asset localURL], asset_version, error)) { - secnotice("OTATrust", "finished update to version %@ from installed asset. purging asset.", asset_version); -#if ENABLE_TRUSTD_ANALYTICS - [[TrustdHealthAnalytics logger] logSuccessForEventNamed:TrustdHealthAnalyticsEventOTAPKIEvent]; -#endif // ENABLE_TRUSTD_ANALYTICS - [asset purge:^(NSError *ma_error) { - if (ma_error) { - secerror("OTATrust: purge failed %@", ma_error); - } - }]; - return asset_version; - } else { - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecCallbackFailed, - @"Failed to install new asset version %@ from %@", asset_version, [asset localURL]); - return nil; - } -} - -static NSDictionary *GetASDownloadOptions(BOOL wait) { - /* default behavior */ - NSMutableDictionary *options = [NSMutableDictionary dictionary]; - options[ASDownloadOptionPriority] = ASDownloadPriorityNormal; - - /* If an XPC interface is waiting on this, all expenses allowed */ - if (wait) { - options[ASDownloadOptionPriority] = ASDownloadPriorityHigh; - options[ASDownloadOptionAllowBatteryPower] = @YES; - return options; - } - - /* If last asset check-in was too long ago, use more expensive options */ - SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); - if (!SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessWarning)) { - secnotice("OTATrust", "Asset staleness state: warning"); - options[ASDownloadOptionPriority] = ASDownloadPriorityHigh; - options[ASDownloadOptionAllowBatteryPower] = @YES; - } else if (!SecOTAPKIAssetStalenessLessThanSeconds(otapkiref, kSecOTAPKIAssetStalenessAtRisk)) { - secnotice("OTATrust", "Asset staleness state: at risk"); - options[ASDownloadOptionPriority] = ASDownloadPriorityHigh; - } - CFReleaseNull(otapkiref); - return options; -} - -static BOOL DownloadOTATrustAsset(BOOL isLocalOnly, BOOL wait, NSError **error) { - if (!CanCheckMobileAsset()) { - 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:&localError]; - if (!query_results) { - if (localError) { - secerror("OTATrust: asset query failed: %@", localError); - LogRemotely(OTATrustLogLevelError, &localError); - if (error) { *error = localError; } - } - return NO; - } - - __block NSNumber *updated_version = nil; - __block NSError *handler_error = nil; - __block dispatch_semaphore_t done = wait ? dispatch_semaphore_create(0) : nil; - bool began_async_job = false; - 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, NSOSStatusErrorDomain, errSecIncompatibleVersion, - @"skipping asset because Compatibility Version doesn't match %@", compatibilityVersion); - continue; - } - - /* Check Content Version against the current content version */ - NSNumber *contentVersion = [attributes objectForKey:ASAttributeContentVersion]; - if (!ShouldUpdateWithAsset(contentVersion)) { - /* write the version and last (successful) check-in time */ - UpdateOTAContext(contentVersion, error); - NSDictionary *eventAttributes = @{ - @"assetVersion" : contentVersion, - @"systemVersion" : @(GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey)), - @"installedVersion" : @(SecOTAPKIGetCurrentAssetVersion(nil)), - }; - MakeOTATrustErrorWithAttributes(error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecDuplicateItem, eventAttributes, - @"skipping asset because we already have _ContentVersion %@ (or newer)", contentVersion); - continue; - } - - GetKillSwitchAttributes(attributes); - - ASProgressHandler OTATrustHandler = ^(NSDictionary *state, NSError *progressError){ - NSString *operationState = nil; - if (progressError) { - secerror("OTATrust: progress handler failed: %@", progressError); - LogRemotely(OTATrustLogLevelError, &progressError); - handler_error = [progressError copy]; - if (wait) { - dispatch_semaphore_signal(done); - } - return; - } - - if (!state) { - MakeOTATrustError(&handler_error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, - @"no asset state in progress handler"); - if (wait) { - dispatch_semaphore_signal(done); - } - return; - } - - operationState = [state objectForKey:ASStateOperation]; - secdebug("OTATrust", "Asset state is %@", operationState); - - if (operationState && [operationState isEqualToString:ASOperationCompleted]) { - updated_version = UpdateAndPurgeAsset(asset, contentVersion, &handler_error); - if (wait) { - dispatch_semaphore_signal(done); - } - } - /* Other states keep calling our progress handler until completed so don't signal */ - }; - - switch ([asset state]) { - case ASAssetStateNotPresent: - secdebug("OTATrust", "OTATrust asset needs to be downloaded"); - asset.progressHandler= OTATrustHandler; - asset.userInitiatedDownload = YES; - [asset beginDownloadWithOptions:GetASDownloadOptions(wait)]; - began_async_job = true; - break; - case ASAssetStateInstalled: - /* The asset is already in the cache, get it from disk. */ - secdebug("OTATrust", "OTATrust asset already installed"); - updated_version = UpdateAndPurgeAsset(asset, contentVersion, error); - break; - case ASAssetStatePaused: - secdebug("OTATrust", "OTATrust asset download paused"); - asset.progressHandler = OTATrustHandler; - asset.userInitiatedDownload = YES; - [asset adjustDownloadOptions:GetASDownloadOptions(wait) completion:nil]; - 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; - } - break; - case ASAssetStateStalled: - secdebug("OTATrust", "OTATrust asset stalled"); - // drop through - case ASAssetStateDownloading: - secdebug("OTATrust", "OTATrust asset downloading"); - asset.progressHandler = OTATrustHandler; - asset.userInitiatedDownload = YES; - [asset adjustDownloadOptions:GetASDownloadOptions(wait) completion:nil]; - began_async_job = true; - break; - default: - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, - @"unhandled asset state %ld", (long)asset.state); - continue; - } - } - - /* If the caller is waiting for a response, wait up to one minute for the update to complete. - * If the OTATrustHandler does not complete in the time, report a timeout. - * If the OTATrustHandler completes and did not successfully update and it reported an error; - * forward that error to the caller. */ - 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, NSOSStatusErrorDomain, errSecNetworkFailure, - @"Failed to get asset metadata within 1 minute."); - } else { - /* finished an async job, update the result */ - result = (updated_version != nil); - if (error && handler_error) { - *error = handler_error; - } - } - } - - /* If we failed and don't know why, report an unknown error */ - if (!result && error && (*error == NULL)) { - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternalComponent, - @"Unknown error occurred."); - } - return result; -} -#endif /* !TARGET_OS_IPHONE */ static bool InitializeKillSwitch(NSString *key) { #if !TARGET_OS_BRIDGE @@ -934,11 +790,11 @@ static bool InitializeKillSwitch(NSString *key) { secinfo("OTATrust", "found on-disk kill switch %{public}@ with value %d", key, [killSwitchValue boolValue]); return [killSwitchValue boolValue]; } else { - MakeOTATrustError(&error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue, + MakeOTATrustError(OTATrustMobileAssetType, &error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue, @"OTAContext.plist missing check-in"); } } else { - MakeOTATrustError(&error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue, + MakeOTATrustError(OTATrustMobileAssetType, &error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue, @"OTAContext.plist missing dictionary"); } #endif @@ -951,7 +807,7 @@ static void InitializeOTATrustAsset(dispatch_queue_t queue) { /* Asynchronously ask MobileAsset for most recent asset. */ dispatch_async(queue, ^{ secnotice("OTATrust", "Initial check with MobileAsset for newer PKITrustSupplementals asset"); - (void)DownloadOTATrustAsset(NO, NO, nil); + (void)DownloadOTATrustAsset(NO, NO, OTATrustMobileAssetType, nil); }); /* Register for changes in our asset */ @@ -959,12 +815,12 @@ static void InitializeOTATrustAsset(dispatch_queue_t queue) { int out_token = 0; notify_register_dispatch(kOTATrustMobileAssetNotification, &out_token, queue, ^(int __unused token) { secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from mobileassetd."); - (void)DownloadOTATrustAsset(YES, NO, nil); + (void)DownloadOTATrustAsset(YES, NO, OTATrustMobileAssetType, nil); }); } } else { /* Register for changes signaled by the system trustd */ - secnotice("OTATrust", "Intializing listener for Asset changes from system trustd."); + secnotice("OTATrust", "Initializing listener for PKI Asset changes from system trustd."); int out_token = 0; notify_register_dispatch(kOTATrustOnDiskAssetNotification, &out_token, queue, ^(int __unused token) { secnotice("OTATrust", "Got notification about a new PKITrustSupplementals asset from system trustd."); @@ -989,7 +845,42 @@ static void InitializeOTATrustAsset(dispatch_queue_t queue) { }); int out_token3 = 0; notify_register_dispatch(kOTATrustKillSwitchNotification, &out_token3, queue, ^(int __unused token) { - UpdateKillSwitch(kOTATrustCTKillSwitch, InitializeKillSwitch(kOTATrustCTKillSwitch)); + UpdateKillSwitch((__bridge NSString*)kOTAPKIKillSwitchCT, InitializeKillSwitch((__bridge NSString*)kOTAPKIKillSwitchCT)); + }); + } +} + +static void InitializeOTASecExperimentAsset(dispatch_queue_t queue) { + /* Only the "system" trustd does updates */ + if (SecOTAPKIIsSystemTrustd()) { + /* Asynchronously ask MobileAsset for most recent asset. */ + dispatch_async(queue, ^{ + secnotice("OTATrust", "Initial check with MobileAsset for newer SecExperiment asset"); + (void)DownloadOTATrustAsset(NO, NO, OTASecExperimentMobileAssetType, nil); + }); + } else { + /* Register for changes signaled by the system trustd */ + secnotice("OTATrust", "Initializing listener for SecExperiment Asset changes from system trustd."); + int out_token = 0; + notify_register_dispatch(kOTASecExperimentNewAssetNotification, &out_token, queue, ^(int __unused token) { + NSError *error = nil; + secnotice("OTATrust", "Got notification about a new SecExperiment asset from system trustd."); + MAAssetQuery *assetQuery = [[MAAssetQuery alloc] initWithType:OTASecExperimentMobileAssetType]; + [assetQuery returnTypes:MAInstalledOnly]; + MAQueryResult queryResult = [assetQuery queryMetaDataSync]; + + if (queryResult != MAQuerySuccessful) { + secerror("OTATrust: failed to update SecExperiment Asset after notification: %ld", (long)queryResult); + } else { + secnotice("OTATrust", "Updated SecExperiment asset successfully"); + for (MAAsset *asset in assetQuery.results) { + NSNumber *asset_version = [asset assetProperty:@"_ContentVersion"]; + if (!assetVersionCheck(OTASecExperimentMobileAssetType, asset)) { + continue; + } + UpdateAndPurgeAsset(OTASecExperimentMobileAssetType, asset, asset_version, &error); + } + } }); } } @@ -1013,7 +904,8 @@ static void TriggerPeriodicOTATrustAssetChecks(dispatch_queue_t queue) { action = sec_action_create_with_queue(queue,"OTATrust", delta); sec_action_set_handler(action, ^{ if (!first_launch) { - (void)DownloadOTATrustAsset(NO, NO, nil); + (void)DownloadOTATrustAsset(NO, NO, OTASecExperimentMobileAssetType, nil); + (void)DownloadOTATrustAsset(NO, NO, OTATrustMobileAssetType, nil); } first_launch = false; }); @@ -1131,28 +1023,61 @@ static CF_RETURNS_RETAINED CFDictionaryRef InitializeAllowList() { } } -static CF_RETURNS_RETAINED CFArrayRef InitializeTrustedCTLogs() { - NSArray *trustedCTLogs = nil; - NSError *error = nil; -#if !TARGET_OS_BRIDGE - if (ShouldInitializeWithAsset()) { - trustedCTLogs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustTrustedCTLogsFilename) error:&error]; - if (!isNSArray(trustedCTLogs)) { - secerror("OTATrust: failed to read CT list from asset data: %@", error); - LogRemotely(OTATrustLogLevelError, &error); - if (!DeleteAssetFromDisk()) { - initialization_error_from_asset_data = true; +static NSDictionary *ConvertTrustedCTLogsArrayToDictionary(NSArray *trustedLogsArray) { + NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:trustedLogsArray.count]; + [trustedLogsArray enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (!isNSDictionary(obj)) { + secerror("OTATrust: failed to read entry from trusted CT logs array at index %lu", (unsigned long)idx); + return; + } + NSDictionary *log_data = (NSDictionary *)obj; + NSData *log_id = log_data[@"log_id"]; + if (!isNSData(log_id)) { + secinfo("OTATrust", "failed to read log_id from trusted CT log array entry at index %lu, computing log_id", (unsigned long)idx); + // We can make the log_id from the key + NSData *key = log_data[@"key"]; + if (!isNSData(key)) { + secerror("failed to read key from trusted CT log array entry at index %lu", (unsigned long)idx); + return; } + log_id = CFBridgingRelease(SecSHA256DigestCreateFromData(NULL, (__bridge CFDataRef)key)); } + [result setObject:log_data forKey:log_id]; + }]; + return result; +} + +CFDictionaryRef SecOTAPKICreateTrustedCTLogsDictionaryFromArray(CFArrayRef trustedCTLogsArray) +{ + @autoreleasepool { + return CFBridgingRetain(ConvertTrustedCTLogsArrayToDictionary((__bridge NSArray*)trustedCTLogsArray)); } +} + +static CF_RETURNS_RETAINED CFDictionaryRef InitializeTrustedCTLogs() { + @autoreleasepool { + NSArray *trustedCTLogs = nil; + NSError *error = nil; +#if !TARGET_OS_BRIDGE + if (ShouldInitializeWithAsset()) { + trustedCTLogs = [NSArray arrayWithContentsOfURL:GetAssetFileURL(kOTATrustTrustedCTLogsFilename) error:&error]; + if (!isNSArray(trustedCTLogs)) { + secerror("OTATrust: failed to read CT list from asset data: %@", error); + LogRemotely(OTATrustLogLevelError, &error); + if (!DeleteAssetFromDisk()) { + initialization_error_from_asset_data = true; + } + } + } #endif - if (!isNSArray(trustedCTLogs)) { - trustedCTLogs = [NSArray arrayWithContentsOfURL:SecSystemTrustStoreCopyResourceNSURL(kOTATrustTrustedCTLogsFilename)]; - } - if (isNSArray(trustedCTLogs)) { - return CFBridgingRetain(trustedCTLogs); + if (!isNSArray(trustedCTLogs)) { + trustedCTLogs = [NSArray arrayWithContentsOfURL:SecSystemTrustStoreCopyResourceNSURL(kOTATrustTrustedCTLogsFilename)]; + } + if (isNSArray(trustedCTLogs)) { + return CFBridgingRetain(ConvertTrustedCTLogsArrayToDictionary(trustedCTLogs)); + } + return NULL; } - return NULL; } static CF_RETURNS_RETAINED CFDictionaryRef InitializeEVPolicyToAnchorDigestsTable() { @@ -1530,7 +1455,7 @@ struct _OpaqueSecOTAPKI { CFSetRef _blackListSet; CFSetRef _grayListSet; CFDictionaryRef _allowList; - CFArrayRef _trustedCTLogs; + CFDictionaryRef _trustedCTLogs; CFURLRef _pinningList; CFArrayRef _escrowCertificates; CFArrayRef _escrowPCSCertificates; @@ -1545,6 +1470,8 @@ struct _OpaqueSecOTAPKI { CFDateRef _lastAssetCheckIn; CFDictionaryRef _eventSamplingRates; CFArrayRef _appleCAs; + CFDictionaryRef _secExperimentConfig; + uint64_t _secExperimentAssetVersion; bool _ctKillSwitch; }; @@ -1572,6 +1499,7 @@ static void SecOTAPKIDestroy(CFTypeRef cf) { CFReleaseNull(otapkiref->_eventSamplingRates); CFReleaseNull(otapkiref->_appleCAs); CFReleaseNull(otapkiref->_lastAssetCheckIn); + CFReleaseNull(otapkiref->_secExperimentConfig); if (otapkiref->_anchorTable) { free((void *)otapkiref->_anchorTable); @@ -1601,11 +1529,11 @@ static uint64_t GetAssetVersion(CFErrorRef *error) { if (isNSNumber(tmpNumber)) { asset_version = [tmpNumber unsignedLongLongValue]; } else if (error) { - MakeOTATrustError(&nserror, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue, + MakeOTATrustError(OTATrustMobileAssetType, &nserror, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue, @"OTAContext.plist missing version"); } } else if (error) { - MakeOTATrustError(&nserror, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue, + MakeOTATrustError(OTATrustMobileAssetType, &nserror, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue, @"OTAContext.plist missing dictionary"); } @@ -1634,11 +1562,11 @@ static CF_RETURNS_RETAINED CFDateRef InitializeLastAssetCheckIn(void) { if (isNSDate(checkIn)) { return CFRetainSafe((__bridge CFDateRef)checkIn); } else { - MakeOTATrustError(&error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue, + MakeOTATrustError(OTATrustMobileAssetType, &error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecInvalidValue, @"OTAContext.plist missing check-in"); } } else { - MakeOTATrustError(&error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue, + MakeOTATrustError(OTATrustMobileAssetType, &error, OTATrustLogLevelNotice, NSOSStatusErrorDomain, errSecMissingValue, @"OTAContext.plist missing dictionary"); } #endif @@ -1702,7 +1630,7 @@ static SecOTAPKIRef SecOTACreate() { } else { otapkiref->_assetVersion = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey); } - + otapkiref->_secExperimentAssetVersion = 0; // Get the valid update snapshot version and format CFIndex update_format = 0; otapkiref->_validSnapshotVersion = InitializeValidSnapshotVersion(&update_format); @@ -1748,7 +1676,8 @@ static SecOTAPKIRef SecOTACreate() { #if !TARGET_OS_BRIDGE /* Initialize our update handling */ InitializeOTATrustAsset(kOTABackgroundQueue); - otapkiref->_ctKillSwitch = InitializeKillSwitch(kOTATrustCTKillSwitch); + otapkiref->_ctKillSwitch = InitializeKillSwitch((__bridge NSString*)kOTAPKIKillSwitchCT); + InitializeOTASecExperimentAsset(kOTABackgroundQueue); #else // TARGET_OS_BRIDGE otapkiref->_ctKillSwitch = true; // bridgeOS never enforces CT #endif // TARGET_OS_BRIDGE @@ -1783,7 +1712,7 @@ SecOTAPKIRef SecOTAPKICopyCurrentOTAPKIRef() { } #if !TARGET_OS_BRIDGE -static BOOL UpdateOTACheckInDate(void) { +BOOL UpdateOTACheckInDate(void) { __block NSDate *checkIn = [NSDate date]; dispatch_sync(kOTAQueue, ^{ CFRetainAssign(kCurrentOTAPKIRef->_lastAssetCheckIn, (__bridge CFDateRef)checkIn); @@ -1805,9 +1734,9 @@ static BOOL UpdateOTACheckInDate(void) { } } -static void UpdateKillSwitch(NSString *key, bool value) { +void UpdateKillSwitch(NSString *key, bool value) { dispatch_sync(kOTAQueue, ^{ - if ([key isEqualToString:kOTATrustCTKillSwitch]) { + if ([key isEqualToString:(__bridge NSString*)kOTAPKIKillSwitchCT]) { kCurrentOTAPKIRef->_ctKillSwitch = value; } }); @@ -1815,7 +1744,7 @@ static void UpdateKillSwitch(NSString *key, bool value) { static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version, NSError **error) { if (!localURL || !asset_version) { - MakeOTATrustError(error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, + MakeOTATrustError(OTATrustMobileAssetType, error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, @"missing url and version for downloaded asset"); return NO; } @@ -1854,7 +1783,7 @@ static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version, NSError ** /* Update the Current OTAPKIRef with the new data */ dispatch_sync(kOTAQueue, ^{ secnotice("OTATrust", "updating asset version from %llu to %llu", kCurrentOTAPKIRef->_assetVersion, version); - CFRetainAssign(kCurrentOTAPKIRef->_trustedCTLogs, (__bridge CFArrayRef)newTrustedCTLogs); + CFRetainAssign(kCurrentOTAPKIRef->_trustedCTLogs, (__bridge CFDictionaryRef)ConvertTrustedCTLogsArrayToDictionary(newTrustedCTLogs)); CFRetainAssign(kCurrentOTAPKIRef->_eventSamplingRates, (__bridge CFDictionaryRef)newAnalyticsSamplingRates); CFRetainAssign(kCurrentOTAPKIRef->_appleCAs, (__bridge CFArrayRef)newAppleCAs); kCurrentOTAPKIRef->_assetVersion = version; @@ -1876,6 +1805,35 @@ static BOOL UpdateFromAsset(NSURL *localURL, NSNumber *asset_version, NSError ** } #endif // !TARGET_OS_BRIDGE +#if !TARGET_OS_BRIDGE +static NSNumber *SecExperimentUpdateAsset(MAAsset *asset, NSNumber *asset_version, NSError **error) { + NSURL *localURL = [asset getLocalFileUrl]; + if (!localURL || !asset_version) { + MakeOTATrustError(OTASecExperimentMobileAssetType, error, OTATrustLogLevelError, NSOSStatusErrorDomain, errSecInternal, + @"missing url and version for downloaded SecExperiment asset"); + return nil; + } + NSDictionary *newSecExpConfig = NULL; + uint64_t version = [asset_version unsignedLongLongValue]; + + NSURL *secExpConfigFileLoc = [NSURL URLWithString:kOTASecExperimentConfigFilename + relativeToURL:localURL]; + newSecExpConfig = [NSDictionary dictionaryWithContentsOfURL:secExpConfigFileLoc error:error]; + if (!newSecExpConfig) { + secerror("OTATrust: unable to create SecExperiment from asset file: %@", error ? *error: nil); + return nil; + } + /* Update the Current OTAPKIRef with the new data */ + dispatch_sync(kOTAQueue, ^{ + secnotice("OTATrust", "updating SecExperiment asset version from %llu to %llu", kCurrentOTAPKIRef->_secExperimentAssetVersion, version); + CFRetainAssign(kCurrentOTAPKIRef->_secExperimentConfig, (__bridge CFDictionaryRef)newSecExpConfig); + kCurrentOTAPKIRef->_secExperimentAssetVersion = version; + }); + /* Signal the other trustds to pick up the changes */ + notify_post(kOTASecExperimentNewAssetNotification); + return asset_version; +} +#endif // !TARGET_OS_BRIDGE CFSetRef SecOTAPKICopyBlackListSet(SecOTAPKIRef otapkiRef) { if (NULL == otapkiRef) { @@ -1941,8 +1899,8 @@ CFArrayRef SecOTAPKICopyAllowListForAuthKeyID(SecOTAPKIRef otapkiRef, CFStringRe return result; } -CFArrayRef SecOTAPKICopyTrustedCTLogs(SecOTAPKIRef otapkiRef) { - CFArrayRef result = NULL; +CFDictionaryRef SecOTAPKICopyTrustedCTLogs(SecOTAPKIRef otapkiRef) { + CFDictionaryRef result = NULL; if (NULL == otapkiRef) { return result; } @@ -2096,13 +2054,17 @@ CFDateRef SecOTAPKICopyLastAssetCheckInDate(SecOTAPKIRef otapkiRef) { } bool SecOTAPKIAssetStalenessLessThanSeconds(SecOTAPKIRef otapkiRef, CFTimeInterval seconds) { - if (NULL == otapkiRef || !isDate(otapkiRef->_lastAssetCheckIn)) { + if (NULL == otapkiRef) { return false; } - if(fabs([(__bridge NSDate *)otapkiRef->_lastAssetCheckIn timeIntervalSinceNow]) < seconds) { - return true; + + bool result = false; + CFDateRef lastCheckIn = CFRetainSafe(otapkiRef->_lastAssetCheckIn); + if (isDate(lastCheckIn) && (fabs([(__bridge NSDate *)lastCheckIn timeIntervalSinceNow]) < seconds)) { + result = true; } - return false; + CFReleaseNull(lastCheckIn); + return result; } NSNumber *SecOTAPKIGetSamplingRateForEvent(SecOTAPKIRef otapkiRef, NSString *eventName) { @@ -2166,6 +2128,55 @@ CFArrayRef SecOTAPKICopyCurrentEscrowCertificates(uint32_t escrowRootType, CFErr return result; } +static CF_RETURNS_RETAINED CFDictionaryRef convertDataKeysToBase64Strings(CFDictionaryRef CF_CONSUMED dictionaryWithDataKeys) { + @autoreleasepool { + NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:((__bridge NSDictionary*)dictionaryWithDataKeys).count]; + NSDictionary *input = CFBridgingRelease(dictionaryWithDataKeys); + for (NSData *key in input) { + id obj = [input objectForKey:key]; + NSString *base64Key = [key base64EncodedStringWithOptions:0]; + result[base64Key] = obj; + } + return CFBridgingRetain(result); + } +} + +/* Returns an dictionary of dictionaries for currently trusted CT logs, indexed by the base64-encoded LogID */ +CFDictionaryRef SecOTAPKICopyCurrentTrustedCTLogs(CFErrorRef* error) { + SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiref) { + SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); + return NULL; + } + + CFDictionaryRef result = convertDataKeysToBase64Strings(SecOTAPKICopyTrustedCTLogs(otapkiref)); + CFReleaseSafe(otapkiref); + + if (NULL == result) { + SecError(errSecInternal, error, CFSTR("Could not get CT logs from the current OTAPKIRef")); + } + return result; +} + +/* Returns a dictionary for the CT log matching specified LogID */ +CFDictionaryRef SecOTAPKICopyCTLogForKeyID(CFDataRef keyID, CFErrorRef* error) { + SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiref) { + SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); + return NULL; + } + + CFDictionaryRef trustedLogs = SecOTAPKICopyTrustedCTLogs(otapkiref); + CFReleaseNull(otapkiref); + if (!trustedLogs) { + return NULL; + } + CFDictionaryRef logDict = CFDictionaryGetValue(trustedLogs, keyID); + CFRetainSafe(logDict); + CFReleaseSafe(trustedLogs); + return logDict; +} + uint64_t SecOTAPKIGetCurrentTrustStoreVersion(CFErrorRef* error){ SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); if (NULL == otapkiref) { @@ -2173,7 +2184,9 @@ uint64_t SecOTAPKIGetCurrentTrustStoreVersion(CFErrorRef* error){ return 0; } - return otapkiref->_trustStoreVersion; + uint64_t result = otapkiref->_trustStoreVersion; + CFReleaseNull(otapkiref); + return result; } uint64_t SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error) { @@ -2183,9 +2196,23 @@ uint64_t SecOTAPKIGetCurrentAssetVersion(CFErrorRef* error) { return 0; } - return otapkiref->_assetVersion; + uint64_t result = otapkiref->_assetVersion; + CFReleaseNull(otapkiref); + return result; } +uint64_t SecOTASecExperimentGetCurrentAssetVersion(CFErrorRef* error) { + SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiref) { + SecError(errSecInternal, error, CFSTR("Unable to get the current OTAPKIRef")); + return 0; + } + + uint64_t result = otapkiref->_secExperimentAssetVersion; + CFReleaseNull(otapkiref); + return result; + } + uint64_t SecOTAPKIResetCurrentAssetVersion(CFErrorRef* error) { uint64_t system_version = GetSystemVersion((__bridge CFStringRef)kOTATrustContentVersionKey); @@ -2206,11 +2233,11 @@ uint64_t SecOTAPKISignalNewAsset(CFErrorRef* error) { uint64_t version = 0; #if !TARGET_OS_BRIDGE if (SecOTAPKIIsSystemTrustd()) { - if (!DownloadOTATrustAsset(NO, YES, &nserror) && error) { + if (!DownloadOTATrustAsset(NO, YES, OTATrustMobileAssetType, &nserror) && error) { *error = CFRetainSafe((__bridge CFErrorRef)nserror); } } else { - SecError(errSecServiceNotAvailable, error, CFSTR("This function may ony be performed by the system trustd.")); + SecError(errSecServiceNotAvailable, error, CFSTR("This function may only be performed by the system trustd.")); } version = GetAssetVersion(nil); #else @@ -2219,3 +2246,36 @@ uint64_t SecOTAPKISignalNewAsset(CFErrorRef* error) { #endif return version; } + +uint64_t SecOTASecExperimentGetNewAsset(CFErrorRef* error) { + NSError *nserror = nil; +#if !TARGET_OS_BRIDGE + if (SecOTAPKIIsSystemTrustd()) { + if (!DownloadOTATrustAsset(NO, YES, OTASecExperimentMobileAssetType, &nserror) && error) { + *error = CFRetainSafe((__bridge CFErrorRef)nserror); + } + } else { + SecError(errSecServiceNotAvailable, error, CFSTR("This function may only be performed by the system trustd.")); + } +#else + SecError(errSecUnsupportedService, error, CFSTR("This function is not available on this platform")); +#endif + return SecOTASecExperimentGetCurrentAssetVersion(error); +} + +CFDictionaryRef SecOTASecExperimentCopyAsset(CFErrorRef* error) { + SecOTAPKIRef otapkiRef = SecOTAPKICopyCurrentOTAPKIRef(); + if (NULL == otapkiRef) { + secnotice("OTATrust", "Null otapkiref"); + return NULL; + } + CFDictionaryRef asset = NULL; + if (otapkiRef->_secExperimentConfig) { + asset = CFRetainSafe(otapkiRef->_secExperimentConfig); + secnotice("OTATrust", "asset found"); + } else { + secnotice("OTATrust", "asset NULL"); + } + CFReleaseNull(otapkiRef); + return asset; +} diff --git a/OSX/sec/securityd/PolicyReporter.h b/OSX/sec/securityd/PolicyReporter.h new file mode 100644 index 00000000..bc9a3c15 --- /dev/null +++ b/OSX/sec/securityd/PolicyReporter.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019 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_POLICY_REPORTER_H +#define _SECURITY_POLICY_REPORTER_H + +#include + +__BEGIN_DECLS +void InitPolicyReporter(void); +__END_DECLS + +#endif diff --git a/OSX/sec/securityd/PolicyReporter.m b/OSX/sec/securityd/PolicyReporter.m new file mode 100644 index 00000000..c5b42c66 --- /dev/null +++ b/OSX/sec/securityd/PolicyReporter.m @@ -0,0 +1,339 @@ +#include "PolicyReporter.h" + +#import +#import +#import +#import +#import +#import +#import +#import + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#import "utilities/debugging.h" +#import "TrustedPeers/TrustedPeers.h" + +// Stolen from keychain/SecureObjectSync/SOSEngine.c + +static NSString* getSOSView(id object, NSString* itemClass) { + if (![object isKindOfClass:[NSDictionary class]]) { + return nil; + } + + NSString *viewHint = object[(NSString*)kSecAttrSyncViewHint]; + if (viewHint != nil) { + return viewHint; + } else { + NSString *ag = object[(NSString*)kSecAttrAccessGroup]; + if ([itemClass isEqualToString: (NSString*)kSecClassKey] && [ag isEqualToString: @"com.apple.security.sos"]) { + return (NSString*)kSOSViewiCloudIdentity; + } else if ([ag isEqualToString: @"com.apple.cfnetwork"]) { + return (NSString*)kSOSViewAutofillPasswords; + } else if ([ag isEqualToString: @"com.apple.safari.credit-cards"]) { + return (NSString*)kSOSViewSafariCreditCards; + } else if ([itemClass isEqualToString: (NSString*)kSecClassGenericPassword]) { + if ([ag isEqualToString: @"apple"] && + [object[(NSString*)kSecAttrService] isEqualToString: @"AirPort"]) { + return (NSString*)kSOSViewWiFi; + } else if ([ag isEqualToString: @"com.apple.sbd"]) { + return (NSString*)kSOSViewBackupBagV0; + } else { + return (NSString*)kSOSViewOtherSyncable; // (genp) + } + } else { + return (NSString*)kSOSViewOtherSyncable; // (inet || keys) + } + } +} + +static inline NSNumber *now_msecs() { + return @(((long)[[NSDate date] timeIntervalSince1970] * 1000)); +} + +static NSString* cloudKitDeviceID() { + __block NSString* ret = nil; + + if (!os_variant_has_internal_diagnostics("com.apple.security")) { + return nil; + } + CKContainer *container = [CKContainer containerWithIdentifier:@"com.apple.security.keychain"]; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + [container fetchCurrentDeviceIDWithCompletionHandler:^(NSString* deviceID, NSError* error) { + if (error != nil) { + NSLog(@"failed to fetch CK deviceID: %@", error); + } else { + ret = deviceID; + } + dispatch_semaphore_signal(sem); + }]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + return ret; +} + +static void reportStats(unsigned expected_mismatches, unsigned real_mismatches, NSArray* reportedMismatches) { + NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:defaultConfiguration]; + NSURL *endpoint = [NSURL URLWithString:@"https://xp.apple.com/report/2/xp_sear_keysync"]; + NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init]; + req.URL = endpoint; + req.HTTPMethod = @"POST"; + NSMutableDictionary *dict = [@{ + @"expectedMismatches": @(expected_mismatches), + @"realMismatches": @(real_mismatches), + @"eventTime": now_msecs(), + @"topic": @"xp_sear_keysync", + @"eventType": @"policy-dryrun", + } mutableCopy]; + NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); + NSString *build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; + if (build != nil) { + dict[@"build"] = build; + } else { + NSLog(@"Unable to find out build version"); + } + NSString *product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; + if (product != nil) { + dict[@"product"] = product; + } else { + NSLog(@"Unable to find out build product"); + } + NSString* ckDeviceID = cloudKitDeviceID(); + if (ckDeviceID) { + dict[@"SFAnalyticsDeviceID"] = ckDeviceID; + dict[@"ckdeviceID"] = ckDeviceID; + } else { + NSLog(@"Unable to fetch CK device ID"); + } + + dict[@"mismatches"] = reportedMismatches; + + NSArray* events = @[dict]; + NSDictionary *wrapper = @{ + @"postTime": @([[NSDate date] timeIntervalSince1970] * 1000), + @"events": events, + }; + NSError *encodeError = nil; + NSData* post_data = [NSJSONSerialization dataWithJSONObject:wrapper options:0 error:&encodeError]; + if (post_data == nil || encodeError != nil) { + NSLog(@"failed to encode data: %@", encodeError); + return; + } + NSLog(@"logging %@, %@", wrapper, post_data); + req.HTTPBody = post_data; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + NSURLSessionDataTask *task = [session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error != nil) { + NSLog(@"splunk upload failed: %@", error); + return; + } + NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*)response; + if (httpResp.statusCode != 200) { + NSLog(@"HTTP Post error: %@", httpResp); + } + NSLog(@"%@", httpResp); + if (data != nil) { + size_t length = [data length]; + char *buf = malloc(length); + [data getBytes:buf length:length]; + NSLog(@"%.*s", (int)length, buf); + free(buf); + } + dispatch_semaphore_signal(sem); + }]; + [task resume]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); +} + +static void oneReport(void) { + NSError* error = nil; + + // From Swift.policy, policy v5 + TPPolicyDocument *tpd = [TPPolicyDocument policyDocWithHash:@"SHA256:O/ECQlWhvNlLmlDNh2+nal/yekUC87bXpV3k+6kznSo=" + data:[[NSData alloc] initWithBase64EncodedString: + @"CAUSDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSDAoEaVBvZBIEZnVsbBILCgNNYWMSBGZ1bGwSDAoEaU1hYxIEZnVsbBINCgdBcHBsZVRWEgJ0dhIOCgVXYXRjaBIFd2F0Y2gSFwoOQXVkaW9BY2Nlc3NvcnkSBWF1ZGlvGhsKDEFwcGxpY2F0aW9ucxIEZnVsbBIFd2F0Y2gaHwoQU2VjdXJlT2JqZWN0U3luYxIEZnVsbBIFd2F0Y2gaHAoNRGV2aWNlUGFpcmluZxIEZnVsbBIFd2F0Y2gaGgoLQ3JlZGl0Q2FyZHMSBGZ1bGwSBXdhdGNoGhUKBkhlYWx0aBIEZnVsbBIFd2F0Y2gaLQoTTGltaXRlZFBlZXJzQWxsb3dlZBIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxokChVQcm90ZWN0ZWRDbG91ZFN0b3JhZ2USBGZ1bGwSBXdhdGNoGhcKCEFwcGxlUGF5EgRmdWxsEgV3YXRjaBoZCgpBdXRvVW5sb2NrEgRmdWxsEgV3YXRjaBoWCgdNYW5hdGVlEgRmdWxsEgV3YXRjaBoYCglQYXNzd29yZHMSBGZ1bGwSBXdhdGNoGhUKBkVuZ3JhbRIEZnVsbBIFd2F0Y2gaHgoEV2lGaRIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxoTCgRIb21lEgRmdWxsEgV3YXRjaCIbCgVhdWRpbxIEZnVsbBIFd2F0Y2gSBWF1ZGlvIhMKBGZ1bGwSBGZ1bGwSBXdhdGNoIhUKAnR2EgRmdWxsEgV3YXRjaBICdHYiFAoFd2F0Y2gSBGZ1bGwSBXdhdGNoMiIKFgAEIhICBHZ3aHQKCl5BcHBsZVBheSQSCEFwcGxlUGF5MiYKGAAEIhQCBHZ3aHQKDF5BdXRvVW5sb2NrJBIKQXV0b1VubG9jazIeChQABCIQAgR2d2h0CgheRW5ncmFtJBIGRW5ncmFtMh4KFAAEIhACBHZ3aHQKCF5IZWFsdGgkEgZIZWFsdGgyGgoSAAQiDgIEdndodAoGXkhvbWUkEgRIb21lMiAKFQAEIhECBHZ3aHQKCV5NYW5hdGVlJBIHTWFuYXRlZTI4CiEABCIdAgR2d2h0ChVeTGltaXRlZFBlZXJzQWxsb3dlZCQSE0xpbWl0ZWRQZWVyc0FsbG93ZWQyXQpQAAISHgAEIhoCBHZ3aHQKEl5Db250aW51aXR5VW5sb2NrJBIVAAQiEQIEdndodAoJXkhvbWVLaXQkEhUABCIRAgR2d2h0CgleQXBwbGVUViQSCU5vdFN5bmNlZDIrChsABCIXAgRhZ3JwCg9eWzAtOUEtWl17MTB9XC4SDEFwcGxpY2F0aW9uczLFAQqwAQACEjQAAQoTAAQiDwIFY2xhc3MKBl5nZW5wJAobAAQiFwIEYWdycAoPXmNvbS5hcHBsZS5zYmQkEj0AAQoTAAQiDwIFY2xhc3MKBl5rZXlzJAokAAQiIAIEYWdycAoYXmNvbS5hcHBsZS5zZWN1cml0eS5zb3MkEhkABCIVAgR2d2h0Cg1eQmFja3VwQmFnVjAkEhwABCIYAgR2d2h0ChBeaUNsb3VkSWRlbnRpdHkkEhBTZWN1cmVPYmplY3RTeW5jMmMKWwACEhIABCIOAgR2d2h0CgZeV2lGaSQSQwABChMABCIPAgVjbGFzcwoGXmdlbnAkChMABCIPAgRhZ3JwCgdeYXBwbGUkChUABCIRAgRzdmNlCgleQWlyUG9ydCQSBFdpRmkynQMKgwMAAhIYAAQiFAIEdndodAoMXlBDUy1CYWNrdXAkEhoABCIWAgR2d2h0Cg5eUENTLUNsb3VkS2l0JBIYAAQiFAIEdndodAoMXlBDUy1Fc2Nyb3ckEhUABCIRAgR2d2h0CgleUENTLUZERSQSGgAEIhYCBHZ3aHQKDl5QQ1MtRmVsZHNwYXIkEhoABCIWAgR2d2h0Cg5eUENTLU1haWxEcm9wJBIaAAQiFgIEdndodAoOXlBDUy1NYWlsZHJvcCQSGwAEIhcCBHZ3aHQKD15QQ1MtTWFzdGVyS2V5JBIXAAQiEwIEdndodAoLXlBDUy1Ob3RlcyQSGAAEIhQCBHZ3aHQKDF5QQ1MtUGhvdG9zJBIZAAQiFQIEdndodAoNXlBDUy1TaGFyaW5nJBIeAAQiGgIEdndodAoSXlBDUy1pQ2xvdWRCYWNrdXAkEh0ABCIZAgR2d2h0ChFeUENTLWlDbG91ZERyaXZlJBIaAAQiFgIEdndodAoOXlBDUy1pTWVzc2FnZSQSFVByb3RlY3RlZENsb3VkU3RvcmFnZTI6CisABCInAgRhZ3JwCh9eY29tLmFwcGxlLnNhZmFyaS5jcmVkaXQtY2FyZHMkEgtDcmVkaXRDYXJkczIuCiEABCIdAgRhZ3JwChVeY29tLmFwcGxlLmNmbmV0d29yayQSCVBhc3N3b3JkczJtClwAAhIeAAQiGgIEdndodAoSXkFjY2Vzc29yeVBhaXJpbmckEhoABCIWAgR2d2h0Cg5eTmFub1JlZ2lzdHJ5JBIcAAQiGAIEdndodAoQXldhdGNoTWlncmF0aW9uJBINRGV2aWNlUGFpcmluZzIOCgIABhIIQmFja3N0b3A=" options:0]]; + + TPPolicy *policy = [tpd policyWithSecrets:@{} decrypter:nil error:&error]; + if (error != nil) { + NSLog(@"policy error: %@", error); + return; + } + if (policy == nil) { + NSLog(@"policy is nil"); + return; + } + + unsigned real_mismatches = 0; + unsigned expected_mismatches = 0; + NSMutableArray* reportedMismatches = [[NSMutableArray alloc] init]; + + NSArray* keychainClasses = @[(id)kSecClassInternetPassword, + (id)kSecClassGenericPassword, + (id)kSecClassKey, + (id)kSecClassCertificate]; + + for(NSString* itemClass in keychainClasses) { + NSDictionary *query = @{ (id)kSecMatchLimit : (id)kSecMatchLimitAll, + (id)kSecClass : (id)itemClass, + (id)kSecReturnAttributes : @YES, + (id)kSecAttrSynchronizable: @YES, + (id)kSecUseDataProtectionKeychain: @YES, + (id)kSecUseAuthenticationUI : (id)kSecUseAuthenticationUISkip, + }; + + NSArray *result; + + OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (void*)&result); + if (status) { + if (status == errSecItemNotFound) { + NSLog(@"no items found matching: %@", query); + continue; + } else { + NSLog(@"SecItemCopyMatching(%@) failed: %d", query, (int)status); + return; + } + } + + if (![result isKindOfClass:[NSArray class]]) { + NSLog(@"expected NSArray result from SecItemCopyMatching"); + return; + } + + for (id a in result) { + NSLog(@"%@", a); + NSString *oldView = getSOSView(a, itemClass); + if (oldView != nil) { + NSLog(@"old: %@", oldView); + } + + NSMutableDictionary* mutA = [a mutableCopy]; + mutA[(id)kSecClass] = (id)itemClass; + + NSString* newView = [policy mapKeyToView:mutA]; + if (newView != nil) { + NSLog(@"new: %@", newView); + } + if(oldView == nil ^ newView == nil) { + NSLog(@"real mismatch: old view (%@) != new view (%@)", oldView, newView); + ++real_mismatches; + [reportedMismatches addObject: a]; + + } else if (oldView && newView && ![oldView isEqualToString: newView]) { + if ([oldView hasPrefix:@"PCS-"] && [newView isEqualToString: @"ProtectedCloudStorage"]) { + NSLog(@"(expected PCS mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if([oldView isEqualToString:@"OtherSyncable"] && [newView isEqualToString: @"Applications"]) { + NSLog(@"(expected 3rd party mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if([oldView isEqualToString:@"OtherSyncable"] && [newView isEqualToString: @"Backstop"]) { + NSLog(@"(expected backstop mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if([newView isEqualToString:@"NotSynced"]) { + NSLog(@"(expected NotSynced mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if(([oldView isEqualToString:@"BackupBagV0"] || [oldView isEqualToString:@"iCloudIdentity"]) && [newView isEqualToString:@"SecureObjectSync"]) { + NSLog(@"(expected BackupBag - SecureObjectSync mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if(([oldView isEqualToString:@"AccessoryPairing"] + || [oldView isEqualToString:@"NanoRegistry"] + || [oldView isEqualToString:@"WatchMigration"]) && [newView isEqualToString:@"DevicePairing"]) { + NSLog(@"(expected DevicePairing mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else { + NSLog(@"real mismatch: old view (%@) != new view (%@)", oldView, newView); + ++real_mismatches; + [reportedMismatches addObject: a]; + } + } + } + } + + NSLog(@"%d expected_mismatches", expected_mismatches); + NSLog(@"%d real_mismatches", real_mismatches); + reportStats(expected_mismatches, real_mismatches, reportedMismatches); +} + +static dispatch_queue_t queue; + +static void report(void); + +static void maybeReport(void) { + CFErrorRef error = NULL; + bool locked = true; + if (!SecAKSGetIsLocked(&locked, &error)) { + secerror("PolicyReporter: %@", error); + CFReleaseNull(error); + xpc_object_t options = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_uint64(options, XPC_ACTIVITY_DELAY, random() % 60); + xpc_dictionary_set_uint64(options, XPC_ACTIVITY_GRACE_PERIOD, 30); + xpc_dictionary_set_bool(options, XPC_ACTIVITY_REPEATING, false); + xpc_dictionary_set_bool(options, XPC_ACTIVITY_ALLOW_BATTERY, true); + xpc_dictionary_set_string(options, XPC_ACTIVITY_PRIORITY, XPC_ACTIVITY_PRIORITY_UTILITY); + xpc_dictionary_set_bool(options, XPC_ACTIVITY_REQUIRE_NETWORK_CONNECTIVITY, true); +#if TARGET_OS_IPHONE + xpc_dictionary_set_bool(options, XPC_ACTIVITY_REQUIRES_CLASS_A, true); +#endif + xpc_activity_register("com.apple.security.securityd.policy-reporting2", + options, ^(xpc_activity_t activity) { + report(); + }); + return; + } + + if (locked) { + int token = 0; + notify_register_dispatch(kUserKeybagStateChangeNotification, &token, queue, ^(int t) { + report(); + }); + return; + } + oneReport(); +} + +static void report() { + @autoreleasepool { + maybeReport(); + } +} + +void InitPolicyReporter(void) { + if (!os_feature_enabled(Security, securitydReportPolicy)) { + secnotice("securityd-PolicyReporter", "not enabled by feature flag"); + return; + } + + srandom(getpid() ^ (int)time(NULL)); + queue = dispatch_queue_create("com.apple.security.securityd_reporting", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + xpc_object_t options = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_uint64(options, XPC_ACTIVITY_DELAY, random() % 3600); + xpc_dictionary_set_uint64(options, XPC_ACTIVITY_GRACE_PERIOD, 1800); + xpc_dictionary_set_uint64(options, XPC_ACTIVITY_INTERVAL, 3600); + xpc_dictionary_set_bool(options, XPC_ACTIVITY_REPEATING, true); + xpc_dictionary_set_bool(options, XPC_ACTIVITY_ALLOW_BATTERY, true); + xpc_dictionary_set_string(options, XPC_ACTIVITY_PRIORITY, XPC_ACTIVITY_PRIORITY_UTILITY); + xpc_dictionary_set_bool(options, XPC_ACTIVITY_REQUIRE_NETWORK_CONNECTIVITY, true); +#if TARGET_OS_IPHONE + xpc_dictionary_set_bool(options, XPC_ACTIVITY_REQUIRES_CLASS_A, true); +#endif + + xpc_activity_register("com.apple.security.securityd.policy-reporting", + options, ^(xpc_activity_t activity) { + report(); + }); +} diff --git a/OSX/sec/securityd/Regressions/SOSAccountTesting.h b/OSX/sec/securityd/Regressions/SOSAccountTesting.h index b5029c15..37565454 100644 --- a/OSX/sec/securityd/Regressions/SOSAccountTesting.h +++ b/OSX/sec/securityd/Regressions/SOSAccountTesting.h @@ -26,15 +26,15 @@ #define SEC_SOSAccountTesting_h #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include -#include -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import -#import -#import +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" #include "SOSTestDataSource.h" #include "SOSRegressionUtilities.h" @@ -811,7 +811,7 @@ static inline bool testAccountPersistence(SOSAccount* account) { ok(CFEqualSafe((__bridge CFTypeRef)reinflatedAccount, (__bridge CFTypeRef)account), "Compares"); // Repeat through SOSAccountCopyEncodedData() interface - this is the normally called combined interface - accountDER = [reinflatedAccount encodedData:&error]; + accountDER = [account encodedData:&error]; error = nil; reinflatedAccount = [SOSAccount accountFromData:accountDER factory:test_factory error:&error]; ok(reinflatedAccount, "inflated2: %@", error); @@ -877,9 +877,9 @@ static inline bool SOSTestJoinWithApproval(CFDataRef cfpassword, CFStringRef cfa // retval will return op failures, not count failures - we'll still report those from in here. bool retval = false; - ok(retval = SOSTestJoinWith(cfpassword, cfaccount, changes, joiner), "Applyication Made"); + ok(retval = SOSTestJoinWith(cfpassword, cfaccount, changes, joiner), "Application Made"); - is(ProcessChangesUntilNoChange(changes, approver, joiner, NULL), 2, "updates"); + ProcessChangesUntilNoChange(changes, approver, joiner, NULL); int nrounds = 2; if(dropUserKey) SOSAccountPurgePrivateCredential(joiner); // lose the userKey so we don't "fix" the ghost problem yet. @@ -888,7 +888,7 @@ static inline bool SOSTestJoinWithApproval(CFDataRef cfpassword, CFStringRef cfa if(expectCleanup) nrounds++; ok(retval &= SOSTestApproveRequest(approver, 1), "Accepting Request to Join"); - is(ProcessChangesUntilNoChange(changes, approver, joiner, NULL), nrounds, "updates"); + ProcessChangesUntilNoChange(changes, approver, joiner, NULL); 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 71a715d2..e702ad6f 100644 --- a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.h +++ b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.h @@ -1,8 +1,8 @@ #ifndef SEC_SOSTransportTestTransports_h #define SEC_SOSTransportTestTransports_h -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" -#import "Security/SecureObjectSync/SOSTransportMessageKVS.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" extern CFMutableArrayRef key_transports; extern CFMutableArrayRef circle_transports; diff --git a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m index 391e75d8..e354c55f 100644 --- a/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m +++ b/OSX/sec/securityd/Regressions/SOSTransportTestTransports.m @@ -1,18 +1,18 @@ #include #include -#include -#include -#include -#import -#import -#import -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSPeerCoder.h" #include -#include -#import -#import +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" #include "SOSTransportTestTransports.h" #include "SOSAccountTesting.h" diff --git a/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.c b/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.c index ad748d66..ae4e9877 100644 --- a/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.c +++ b/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.c @@ -44,7 +44,8 @@ void secd_test_setup_temp_keychain(const char* test_prefix, dispatch_block_t do_ CFStringRef keychain_dir = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@Library/Keychains"), tmp_dir); CFStringPerformWithCString(keychain_dir, ^(const char *keychain_dir_string) { - ok_unix(mkpath_np(keychain_dir_string, 0755), "Create temp dir %s", keychain_dir_string); + errno_t err = mkpath_np(keychain_dir_string, 0755); + ok(err == 0 || err == EEXIST, "Create temp dir %s (%d)", keychain_dir_string, err); }); @@ -60,18 +61,17 @@ void secd_test_setup_temp_keychain(const char* test_prefix, dispatch_block_t do_ CFStringRef kTestView1 = CFSTR("TestView1"); CFStringRef kTestView2 = CFSTR("TestView2"); -void secd_test_setup_testviews(void) { - static dispatch_once_t onceToken = 0; +void secd_test_setup_testviews(void) { + CFMutableSetRef testViews = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + CFSetAddValue(testViews, kTestView1); + CFSetAddValue(testViews, kTestView2); - dispatch_once(&onceToken, ^{ - CFMutableSetRef testViews = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(testViews, kTestView1); - CFSetAddValue(testViews, kTestView2); - - SOSViewsSetTestViewsSet(testViews); - CFReleaseNull(testViews); - }); + SOSViewsSetTestViewsSet(testViews); + CFReleaseNull(testViews); } +void secd_test_clear_testviews(void) { + SOSViewsSetTestViewsSet(NULL); +} diff --git a/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.h b/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.h index cb179bca..e11ed683 100644 --- a/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.h +++ b/OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.h @@ -35,5 +35,6 @@ extern CFStringRef kTestView1; extern CFStringRef kTestView2; void secd_test_setup_testviews(void); +void secd_test_clear_testviews(void); #endif diff --git a/OSX/sec/securityd/Regressions/secd-01-items.m b/OSX/sec/securityd/Regressions/secd-01-items.m index 80596f4c..ffd19e82 100644 --- a/OSX/sec/securityd/Regressions/secd-01-items.m +++ b/OSX/sec/securityd/Regressions/secd-01-items.m @@ -36,7 +36,7 @@ #include "SecdTestKeychainUtilities.h" #if USE_KEYSTORE -#include +#include "OSX/utilities/SecAKSWrappers.h" int secd_01_items(int argc, char *const *argv) { @@ -52,14 +52,14 @@ int secd_01_items(int argc, char *const *argv) char *passcode="password"; int passcode_len=(int)strlen(passcode); - ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); SecItemServerSetKeychainKeybag(keybag); /* lock */ - ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_lock_bag(keybag), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(state&keybag_state_locked, "keybag locked"); @@ -98,24 +98,24 @@ int secd_01_items(int argc, char *const *argv) is_status(SecItemAdd(item, NULL), errSecInteractionNotAllowed, "add internet password while locked"); /* unlock */ - ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "unlock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "unlock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); ok_status(SecItemAdd(item, NULL), "add internet password, while unlocked"); /* lock */ - ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_lock_bag(keybag), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(state&keybag_state_locked, "keybag locked"); is_status(SecItemAdd(item, NULL), errSecInteractionNotAllowed, "add internet password again, while locked"); /* unlock */ - ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "unlock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "unlock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); is_status(SecItemAdd(item, NULL), errSecDuplicateItem, @@ -132,8 +132,8 @@ int secd_01_items(int argc, char *const *argv) } /* lock */ - ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_lock_bag(keybag), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(state&keybag_state_locked, "keybag locked"); is_status(SecItemCopyMatching(query, &results), errSecInteractionNotAllowed, "find internet password, while locked "); 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 01e207e4..e6e17a34 100644 --- a/OSX/sec/securityd/Regressions/secd-02-upgrade-while-locked.m +++ b/OSX/sec/securityd/Regressions/secd-02-upgrade-while-locked.m @@ -44,7 +44,7 @@ #include #if TARGET_OS_IPHONE && USE_KEYSTORE -#include +#include "OSX/utilities/SecAKSWrappers.h" #include "SecdTestKeychainUtilities.h" @@ -135,21 +135,21 @@ int secd_02_upgrade_while_locked(int argc, char *const *argv) SecItemServerSetKeychainChangedNotification("com.apple.secdtests.keychainchanged"); /* Create and lock custom keybag */ - ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); SecItemServerSetKeychainKeybag(keybag); /* lock */ - ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_lock_bag(keybag), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(state&keybag_state_locked, "keybag locked"); }); CFReleaseSafe(keychain_path_cf); }); - CFArrayRef old_ag = SecAccessGroupsGetCurrent(); + CFArrayRef old_ag = CFRetainSafe(SecAccessGroupsGetCurrent()); CFMutableArrayRef test_ag = CFArrayCreateMutableCopy(NULL, 0, old_ag); CFArrayAppendValue(test_ag, CFSTR("test")); SecAccessGroupsSetCurrent(test_ag); @@ -171,8 +171,8 @@ int secd_02_upgrade_while_locked(int argc, char *const *argv) ok(query_err[i]==NULL, "query thread ok"); ok(sos_err==NULL, "sos thread ok"); - ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); is_status(query_one(), errSecItemNotFound, "Query after unlock"); @@ -182,6 +182,7 @@ int secd_02_upgrade_while_locked(int argc, char *const *argv) // Reset server accessgroups. SecAccessGroupsSetCurrent(old_ag); + CFReleaseNull(old_ag); CFReleaseSafe(test_ag); return 0; diff --git a/OSX/sec/securityd/Regressions/secd-100-initialsync.m b/OSX/sec/securityd/Regressions/secd-100-initialsync.m index 5cf56e51..ed92a2f4 100644 --- a/OSX/sec/securityd/Regressions/secd-100-initialsync.m +++ b/OSX/sec/securityd/Regressions/secd-100-initialsync.m @@ -33,11 +33,11 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include #include @@ -52,15 +52,36 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 43; - static void tests(void) { CFErrorRef error = NULL; CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10); CFStringRef cfaccount = CFSTR("test@test.org"); - + CFSetRef initialSyncViews = SOSViewCopyViewSet(kViewSetInitial); + CFMutableSetRef alwaysOnViews = SOSViewCopyViewSet(kViewSetAlwaysOn); + CFSetRef defaultViews = SOSViewCopyViewSet(kViewSetDefault); + int initialSyncViewCount = (int) CFSetGetCount(initialSyncViews); + CFReleaseNull(initialSyncViews); + CFSetRef backupSyncViews = SOSViewCopyViewSet(kViewSetRequiredForBackup); + int backupSyncViewCount = (int) CFSetGetCount(backupSyncViews); + CFReleaseNull(backupSyncViews); + int expectedStartupViewCount; + + if(initialSyncViewCount == 0) { + CFSetUnion(alwaysOnViews, defaultViews); + expectedStartupViewCount = (int) CFSetGetCount(alwaysOnViews); + } else { + CFMutableSetRef isViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, initialSyncViews); + CFSetUnion(isViews, backupSyncViews); + expectedStartupViewCount = (int) CFSetGetCount(isViews); + CFReleaseNull(isViews); + } + CFReleaseNull(alwaysOnViews); + CFReleaseNull(defaultViews); + + + CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); SOSDataSourceFactoryRef test_factory = SOSTestDataSourceFactoryCreate(); @@ -99,18 +120,27 @@ static void tests(void) is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates"); accounts_agree("bob&alice pair", bob_account, alice_account); - - ok(!SOSAccountCheckHasBeenInSync_wTxn(bob_account), "Bob should not be initially synced"); + + if(initialSyncViewCount > 0) { + ok(!SOSAccountCheckHasBeenInSync_wTxn(bob_account), "Bob should not be initially synced"); + } CFSetRef bob_viewSet = SOSPeerInfoCopyEnabledViews(bob_account.peerInfo); - is(CFSetGetCount(bob_viewSet), 14, "bob's initial view set should be just the 14 views"); + is(CFSetGetCount(bob_viewSet), expectedStartupViewCount, "bob's initial view set should be just the initial sync and backup views"); CFReleaseNull(bob_viewSet); - - ok(!SOSAccountCheckHasBeenInSync_wTxn(bob_account), "Bob should not be initially synced"); + + if(initialSyncViewCount > 0) { + ok(!SOSAccountCheckHasBeenInSync_wTxn(bob_account), "Bob should not be initially synced"); + } + SOSAccountPeerGotInSync_wTxn(bob_account, alice_account.peerInfo); - - bob_viewSet = SOSPeerInfoCopyEnabledViews(bob_account.peerInfo); - is(CFSetGetCount(bob_viewSet), 20, "bob's initial view set should be just the back up"); - CFReleaseNull(bob_viewSet); + + if(initialSyncViewCount > 0) { + bob_viewSet = SOSPeerInfoCopyEnabledViews(bob_account.peerInfo); + is(CFSetGetCount(bob_viewSet), backupSyncViewCount, "bob's initial view set should be just the back up"); + CFReleaseNull(bob_viewSet); + } else { + ok(true, "don't mess with the total test count"); + } bob_account = nil; alice_account = nil; @@ -121,7 +151,7 @@ static void tests(void) int secd_100_initialsync(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(33); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-130-other-peer-views.m b/OSX/sec/securityd/Regressions/secd-130-other-peer-views.m index 8cc3349d..8fe1cb2c 100644 --- a/OSX/sec/securityd/Regressions/secd-130-other-peer-views.m +++ b/OSX/sec/securityd/Regressions/secd-130-other-peer-views.m @@ -19,7 +19,7 @@ #include "SOSAccountTesting.h" -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #define kAccountPasswordString ((uint8_t*) "FooFooFoo") #define kAccountPasswordStringLen 10 @@ -31,6 +31,9 @@ static void tests(void) { CFDataRef cfpassword = CFDataCreate(NULL, kAccountPasswordString, kAccountPasswordStringLen); CFStringRef cfaccount = CFSTR("test@test.org"); CFMutableDictionaryRef cfchanges = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); + CFSetRef initialSyncViews = SOSViewCopyViewSet(kViewSetInitial); + int initialSyncViewCount = (int) CFSetGetCount(initialSyncViews); + CFReleaseNull(initialSyncViews); SOSAccount* alice_account = CreateAccountForLocalChanges(CFSTR("Alice"), CFSTR("TestSource")); SOSAccount* bob_account = CreateAccountForLocalChanges(CFSTR("Bob"), CFSTR("TestSource")); @@ -111,7 +114,8 @@ static void tests(void) { SOSAccountPeerGotInSync_wTxn(carole_account, alice_account.peerInfo); SOSAccountPeerGotInSync_wTxn(david_account, alice_account.peerInfo); - is(ProcessChangesUntilNoChange(cfchanges, alice_account, bob_account, carole_account, david_account, NULL), 4, "updates"); + int changeCount = (initialSyncViewCount) ? 4 : 1; + is(ProcessChangesUntilNoChange(cfchanges, alice_account, bob_account, carole_account, david_account, NULL), changeCount, "updates"); is(SOSAccountPeersHaveViewsEnabled(alice_account, aView, &error), kCFBooleanTrue, "Peer views empty (%@)", error); CFReleaseNull(error); @@ -164,10 +168,10 @@ static void tests(void) { int secd_130_other_peer_views(int argc, char *const *argv) { - plan_tests(107); + plan_tests(72); secd_test_setup_temp_keychain(__FUNCTION__, NULL); - + secd_test_clear_testviews(); tests(); return 0; 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 5fbdcb22..17404974 100644 --- a/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m +++ b/OSX/sec/securityd/Regressions/secd-155-otr-negotiation-monitor.m @@ -6,15 +6,15 @@ // #import -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSPeerOTRTimer.h" #import "SOSAccountTesting.h" #import "SOSTransportTestTransports.h" @@ -26,7 +26,7 @@ #include "SOSTestDataSource.h" #include "SOSRegressionUtilities.h" -#include "SecRecoveryKey.h" +#include #include #include @@ -37,8 +37,7 @@ #import "SOSTransportTestTransports.h" #include "SOSTestDevice.h" #include "SOSTestDataSource.h" -#include -static int kTestTestCount = 114; +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" static void tests(void) @@ -162,7 +161,7 @@ static void tests(void) int secd_155_otr_negotiation_monitor(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(44); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m b/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m index 659f2b54..8987682f 100644 --- a/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m +++ b/OSX/sec/securityd/Regressions/secd-20-keychain_upgrade.m @@ -43,6 +43,7 @@ #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" +#include "server_security_helpers.h" static int ckmirror_row_exists = 0; static int ckmirror_row_callback(void* unused, int count, char **data, char **columns) @@ -74,7 +75,7 @@ keychain_upgrade(bool musr, const char *dbname) * Check system keychain migration */ - res = SecItemAdd((CFDictionaryRef)@{ + res = SecItemAdd((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"system-label-me", (id)kSecUseSystemKeychain : (id)kCFBooleanTrue, @@ -87,7 +88,7 @@ keychain_upgrade(bool musr, const char *dbname) * Check user keychain */ - res = SecItemAdd((CFDictionaryRef)@{ + res = SecItemAdd((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"user-label-me", (id)kSecValueData : [NSData dataWithBytes:"some data" length:9], @@ -116,7 +117,7 @@ keychain_upgrade(bool musr, const char *dbname) }); #if TARGET_OS_IPHONE - res = SecItemCopyMatching((CFDictionaryRef)@{ + res = SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"system-label-me", (id)kSecUseSystemKeychain : (id)kCFBooleanTrue, @@ -124,7 +125,7 @@ keychain_upgrade(bool musr, const char *dbname) is(res, 0, "SecItemCopyMatching(system)"); #endif - res = SecItemCopyMatching((CFDictionaryRef)@{ + res = SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"user-label-me", }, NULL); @@ -143,9 +144,6 @@ keychain_upgrade(bool musr, const char *dbname) #endif } -void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(void); - int secd_20_keychain_upgrade(int argc, char *const *argv) { @@ -157,7 +155,7 @@ secd_20_keychain_upgrade(int argc, char *const *argv) plan_tests((kSecdTestSetupTestCount + 5 + have_system_keychain_tests + 8) * 2); - CFArrayRef currentACL = SecAccessGroupsGetCurrent(); + CFArrayRef currentACL = CFRetainSafe(SecAccessGroupsGetCurrent()); NSMutableArray *newACL = [NSMutableArray arrayWithArray:(__bridge NSArray *)currentACL]; [newACL addObjectsFromArray:@[ @@ -172,6 +170,7 @@ secd_20_keychain_upgrade(int argc, char *const *argv) keychain_upgrade(true, "secd_20_keychain_upgrade-musr"); SecAccessGroupsSetCurrent(currentACL); + CFReleaseNull(currentACL); return 0; } diff --git a/OSX/sec/securityd/Regressions/secd-200-logstate.m b/OSX/sec/securityd/Regressions/secd-200-logstate.m index 265bda37..4fe18f6b 100644 --- a/OSX/sec/securityd/Regressions/secd-200-logstate.m +++ b/OSX/sec/securityd/Regressions/secd-200-logstate.m @@ -35,11 +35,11 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include #include @@ -59,9 +59,6 @@ #define HOW_MANY_MINIONS 4 -static int kTestTestCount = ((HOW_MANY_MINIONS+1)*20); - - static bool SOSArrayForEachAccount(CFArrayRef accounts, bool (^operation)(SOSAccount* account)) { __block bool retval = true; CFArrayForEach(accounts, ^(const void *value) { @@ -229,7 +226,7 @@ static void tests(void) int secd_200_logstate(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(((HOW_MANY_MINIONS+1)*10 + 1)); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-201-coders.m b/OSX/sec/securityd/Regressions/secd-201-coders.m index 74a131db..692150be 100644 --- a/OSX/sec/securityd/Regressions/secd-201-coders.m +++ b/OSX/sec/securityd/Regressions/secd-201-coders.m @@ -35,13 +35,13 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include -#import +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSEngine.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -167,7 +167,7 @@ static void tests(void) int secd_201_coders(int argc, char *const *argv) { - plan_tests(166); + plan_tests(38); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-21-transmogrify.m b/OSX/sec/securityd/Regressions/secd-21-transmogrify.m index 34f087f7..a62a93c5 100644 --- a/OSX/sec/securityd/Regressions/secd-21-transmogrify.m +++ b/OSX/sec/securityd/Regressions/secd-21-transmogrify.m @@ -43,9 +43,7 @@ #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" - -void SecAccessGroupsSetCurrent(CFArrayRef accessGroups); -CFArrayRef SecAccessGroupsGetCurrent(void); +#include "server_security_helpers.h" int secd_21_transmogrify(int argc, char *const *argv) @@ -57,7 +55,7 @@ secd_21_transmogrify(int argc, char *const *argv) CFDictionaryRef result = NULL; OSStatus res; - CFArrayRef currentACL = SecAccessGroupsGetCurrent(); + CFArrayRef currentACL = CFRetainSafe(SecAccessGroupsGetCurrent()); NSMutableArray *newACL = [NSMutableArray arrayWithArray:(__bridge NSArray *)currentACL]; [newACL addObjectsFromArray:@[ @@ -194,6 +192,7 @@ secd_21_transmogrify(int argc, char *const *argv) SecSecuritySetMusrMode(false, 501, -1); SecAccessGroupsSetCurrent(currentACL); + CFReleaseNull(currentACL); CFRelease(musr); #else diff --git a/OSX/sec/securityd/Regressions/secd-230-keybagtable.m b/OSX/sec/securityd/Regressions/secd-230-keybagtable.m index 34545e6d..0803a8d9 100644 --- a/OSX/sec/securityd/Regressions/secd-230-keybagtable.m +++ b/OSX/sec/securityd/Regressions/secd-230-keybagtable.m @@ -53,7 +53,7 @@ sudo defaults read /Library/Preferences/com.apple.security V10SchemaUpgradeTest #endif #if USE_KEYSTORE -#include +#include "OSX/utilities/SecAKSWrappers.h" #include "SecdTestKeychainUtilities.h" @@ -94,15 +94,15 @@ static bool createCustomKeybag() { int passcode_len=(int)strlen(passcode); const bool kTestLockedKeybag = false; - ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); SecItemServerSetKeychainKeybag(keybag); if (kTestLockedKeybag) { /* lock */ - ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_lock_bag(keybag), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(state&keybag_state_locked, "keybag locked"); } diff --git a/OSX/sec/securityd/Regressions/secd-31-keychain-bad.m b/OSX/sec/securityd/Regressions/secd-31-keychain-bad.m deleted file mode 100644 index bac3a4b5..00000000 --- a/OSX/sec/securityd/Regressions/secd-31-keychain-bad.m +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2008,2010,2013-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" - -const uint8_t keychain_data[] = { - 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x01, 0x02, 0x03, - 0x04, 0x5f, 0x10, 0x1b, 0x4e, 0x53, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, - 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x10, 0x1d, 0x4e, 0x53, - 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, - 0x20, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, - 0x4d, 0x61, 0x63, 0x5f, 0x10, 0x1c, 0x32, 0x38, 0x20, 0x33, 0x37, 0x33, - 0x20, 0x33, 0x34, 0x36, 0x20, 0x32, 0x39, 0x30, 0x20, 0x30, 0x20, 0x30, - 0x20, 0x31, 0x34, 0x34, 0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x5f, 0x10, - 0x1d, 0x35, 0x36, 0x38, 0x20, 0x33, 0x39, 0x35, 0x20, 0x33, 0x30, 0x37, - 0x20, 0x33, 0x37, 0x39, 0x20, 0x30, 0x20, 0x30, 0x20, 0x31, 0x34, 0x34, - 0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x08, 0x0d, 0x2b, 0x4b, 0x6a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a -}; - -#include "SecdTestKeychainUtilities.h" - -#include -#include - -/* Test basic add delete update copy matching stuff. */ -static void tests(void) -{ - /* custom keychain dir */ - secd_test_setup_temp_keychain("secd_31_keychain_bad", ^{ - CFStringRef keychain_path_cf = __SecKeychainCopyPath(); - - CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) { - int fd; - ok_unix(fd = open(keychain_path, O_RDWR | O_CREAT | O_TRUNC, 0644), - "create keychain file"); - SKIP: { - skip("Cannot write to keychain file with invalid fd", 2, fd > -1); - is(write(fd, keychain_data, sizeof(keychain_data)), - (ssize_t)sizeof(keychain_data), "write garbage to keychain file"); - ok_unix(close(fd), "close keychain file"); - } - }); - - CFReleaseSafe(keychain_path_cf); - }); - __security_simulatecrash_enable(false); - - int v_eighty = 80; - CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); - const char *v_data = "test"; - CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); - CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL); - CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword); - CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net")); - CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith")); - CFDictionaryAddValue(query, kSecAttrPort, eighty); - CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP); - CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault); - CFDictionaryAddValue(query, kSecValueData, pwdata); - ok_status(SecItemAdd(query, NULL), "add internet password"); - is_status(SecItemAdd(query, NULL), errSecDuplicateItem, - "add internet password again"); - - ok_status(SecItemCopyMatching(query, NULL), "Found the item we added"); - - ok_status(SecItemDelete(query),"Deleted the item we added"); - - is(__security_simulatecrash_enable(true), 1, "expecting 1 simcrashes from opening DB connection"); - - CFRelease(query); - CFRelease(eighty); - CFRelease(pwdata); -} - -int secd_31_keychain_bad(int argc, char *const *argv) -{ - plan_tests(8 + kSecdTestSetupTestCount); - - tests(); - - return 0; -} diff --git a/OSX/sec/securityd/Regressions/secd-33-keychain-backup.m b/OSX/sec/securityd/Regressions/secd-33-keychain-backup.m new file mode 100644 index 00000000..30146b07 --- /dev/null +++ b/OSX/sec/securityd/Regressions/secd-33-keychain-backup.m @@ -0,0 +1,636 @@ +/* + * Copyright (c) 2010,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 "securityd/SecKeybagSupport.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "OSX/utilities/SecAKSWrappers.h" + +#include +#include +#include +#include +#include + +#include "secd_regressions.h" +#include "SecdTestKeychainUtilities.h" +#include "server_security_helpers.h" + +struct test_persistent_s { + CFTypeRef persist[2]; + CFDictionaryRef query; + CFDictionaryRef query1; + CFDictionaryRef query2; + CFMutableDictionaryRef query3; + CFMutableDictionaryRef query4; +}; + +static void test_persistent(struct test_persistent_s *p) +{ + int v_eighty = 80; + CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); + const char *v_data = "test"; + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); + const void *keys[] = { + kSecClass, + kSecAttrServer, + kSecAttrAccount, + kSecAttrPort, + kSecAttrProtocol, + kSecAttrAuthenticationType, + kSecReturnPersistentRef, + kSecValueData + }; + const void *values[] = { + kSecClassInternetPassword, + CFSTR("zuigt.nl"), + CFSTR("frtnbf"), + eighty, + CFSTR("http"), + CFSTR("dflt"), + kCFBooleanTrue, + pwdata + }; + CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values, + array_size(keys), &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + p->persist[0] = NULL; + // NUKE anything we might have left around from a previous test run so we don't crash. + SecItemDelete(item); + ok_status(SecItemAdd(item, &p->persist[0]), "add internet password"); + CFTypeRef results = NULL; + CFTypeRef results2 = NULL; +SKIP: { + skip("no persistent ref", 6, ok(p->persist[0], "got back persistent ref")); + + /* Create a dict with all attrs except the data. */ + keys[(array_size(keys)) - 2] = kSecReturnAttributes; + p->query = CFDictionaryCreate(NULL, keys, values, + (array_size(keys)) - 1, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + ok_status(SecItemCopyMatching(p->query, &results), "find internet password by attr"); + + const void *keys_persist[] = { + kSecReturnAttributes, + kSecValuePersistentRef + }; + const void *values_persist[] = { + kCFBooleanTrue, + p->persist[0] + }; + p->query2 = CFDictionaryCreate(NULL, keys_persist, values_persist, + (array_size(keys_persist)), &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + ok_status(SecItemCopyMatching(p->query2, &results2), "find internet password by persistent ref"); + ok(CFEqual(results, results2 ? results2 : CFSTR("")), "same item (attributes)"); + + CFReleaseNull(results); + CFReleaseNull(results2); + + ok_status(SecItemDelete(p->query), "delete internet password"); + + ok_status(!SecItemCopyMatching(p->query, &results), + "don't find internet password by attributes"); + ok(!results, "no results"); +} + + /* clean up left over from aborted run */ + if (results) { + CFDictionaryRef cleanup = CFDictionaryCreate(NULL, (const void **)&kSecValuePersistentRef, + &results, 1, &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + SecItemDelete(cleanup); + CFRelease(results); + CFRelease(cleanup); + } + + ok_status(!SecItemCopyMatching(p->query2, &results2), + "don't find internet password by persistent ref anymore"); + ok(!results2, "no results"); + + CFReleaseNull(p->persist[0]); + + /* Add a new item and get it's persitant ref. */ + ok_status(SecItemAdd(item, &p->persist[0]), "add internet password"); + p->persist[1] = NULL; + CFMutableDictionaryRef item2 = CFDictionaryCreateMutableCopy(NULL, 0, item); + CFDictionarySetValue(item2, kSecAttrAccount, CFSTR("johndoe-bu")); + // NUKE anything we might have left around from a previous test run so we don't crash. + SecItemDelete(item2); + ok_status(SecItemAdd(item2, &p->persist[1]), "add second internet password"); + CFMutableDictionaryRef update = NULL; + CFStringRef server = NULL; +SKIP: { + skip("no persistent ref", 3, ok(p->persist[0], "got back persistent ref from first internet password")); + + is(CFGetTypeID(p->persist[0]), CFDataGetTypeID(), "result is a CFData"); + p->query3 = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(p->query3, kSecValuePersistentRef, p->persist[0]); + update = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(update, kSecAttrServer, CFSTR("zuigt.com")); + ok_status(SecItemUpdate(p->query3, update), "update via persitant ref"); + + /* Verify that the update really worked. */ + CFDictionaryAddValue(p->query3, kSecReturnAttributes, kCFBooleanTrue); + ok_status(SecItemCopyMatching(p->query3, &results2), "find updated internet password by persistent ref"); + server = CFDictionaryGetValue(results2, kSecAttrServer); + ok(CFEqual(server, CFSTR("zuigt.com")), "verify attribute was modified by update"); + CFReleaseNull(results2); + CFDictionaryRemoveValue(p->query3, kSecReturnAttributes); +} + +SKIP: { + skip("no persistent ref", 2, ok(p->persist[1], "got back persistent ref")); + + /* Verify that item2 wasn't affected by the update. */ + p->query4 = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(p->query4, kSecValuePersistentRef, p->persist[1]); + CFDictionaryAddValue(p->query4, kSecReturnAttributes, kCFBooleanTrue); + ok_status(SecItemCopyMatching(p->query4, &results2), "find non updated internet password by persistent ref"); + server = CFDictionaryGetValue(results2, kSecAttrServer); + ok(CFEqual(server, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update"); + CFReleaseNull(results2); +} + + /* Delete the item via persitant ref. */ + ok_status(SecItemDelete(p->query3), "delete via persitant ref"); + is_status(SecItemCopyMatching(p->query3, &results2), errSecItemNotFound, + "don't find deleted internet password by persistent ref"); + CFReleaseNull(results2); + ok_status(SecItemCopyMatching(p->query4, &results2), + "find non deleted internet password by persistent ref"); + CFReleaseNull(results2); + + CFReleaseNull(update); + CFReleaseNull(item); + CFReleaseNull(item2); + CFReleaseNull(eighty); + CFReleaseNull(pwdata); +} + +static void test_persistent2(struct test_persistent_s *p) +{ + CFTypeRef results = NULL; + CFTypeRef results2 = NULL; + + ok_status(!SecItemCopyMatching(p->query, &results), + "don't find internet password by attributes"); + ok(!results, "no results"); + + ok_status(!SecItemCopyMatching(p->query2, &results2), + "don't find internet password by persistent ref anymore"); + ok(!results2, "no results"); + +SKIP:{ + ok_status(SecItemCopyMatching(p->query4, &results2), "find non updated internet password by persistent ref"); + skip("non updated internet password by persistent ref NOT FOUND!", 2, results2); + ok(results2, "non updated internet password not found"); + CFStringRef server = CFDictionaryGetValue(results2, kSecAttrServer); + ok(CFEqual(server, CFSTR("zuigt.nl")), "verify second items attribute was not modified by update"); + CFReleaseNull(results2); +} + + is_status(SecItemCopyMatching(p->query3, &results2), errSecItemNotFound, + "don't find deleted internet password by persistent ref"); + CFReleaseNull(results2); + ok_status(SecItemCopyMatching(p->query4, &results2), + "find non deleted internet password by persistent ref"); + CFReleaseNull(results2); + + ok_status(SecItemDelete(p->query4),"Deleted internet password by persistent ref"); + + CFRelease(p->query); + CFRelease(p->query2); + CFRelease(p->query3); + CFRelease(p->query4); + CFReleaseNull(p->persist[0]); + CFReleaseNull(p->persist[1]); +} + +static CFMutableDictionaryRef test_create_lockdown_identity_query(void) { + CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("test-delete-me")); + CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("lockdown-identities")); + return query; +} + +static CFMutableDictionaryRef test_create_managedconfiguration_query(void) { + CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecAttrService, CFSTR("com.apple.managedconfiguration")); + CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("Public")); + CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("apple")); + return query; +} + +static CFMutableDictionaryRef test_create_accounts_query(void) { + CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecAttrService, CFSTR("com.apple.account.CloudKit.token")); + CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("apple")); + return query; +} + +static void test_add_lockdown_identity_items(void) { + CFMutableDictionaryRef query = test_create_lockdown_identity_query(); + const char *v_data = "lockdown identity data (which should be a cert + key)"; + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); + CFDictionaryAddValue(query, kSecValueData, pwdata); + ok_status(SecItemAdd(query, NULL), "test_add_lockdown_identity_items"); + CFReleaseSafe(pwdata); + CFReleaseSafe(query); +} + +static void test_remove_lockdown_identity_items(void) { + CFMutableDictionaryRef query = test_create_lockdown_identity_query(); + ok_status(SecItemDelete(query), "test_remove_lockdown_identity_items"); + CFReleaseSafe(query); +} + +static void test_no_find_lockdown_identity_item(void) { + CFMutableDictionaryRef query = test_create_lockdown_identity_query(); + is_status(SecItemCopyMatching(query, NULL), errSecItemNotFound, + "test_no_find_lockdown_identity_item"); + CFReleaseSafe(query); +} + +static CFMutableDictionaryRef test_create_sysbound_query(void) { + CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("sysbound")); + CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("apple")); + return query; +} + +static void test_add_sysbound_item(void) { + CFMutableDictionaryRef query = test_create_sysbound_query(); + int32_t val = kSecSecAttrSysBoundPreserveDuringRestore; + CFNumberRef num = CFNumberCreate(NULL, kCFNumberSInt32Type, &val); + CFDictionaryAddValue(query, kSecAttrSysBound, num); + CFReleaseNull(num); + + const char *v_data = "sysbound identity data"; + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); + CFDictionaryAddValue(query, kSecValueData, pwdata); + ok_status(SecItemAdd(query, NULL), "test_add_sysbound_item"); + CFReleaseSafe(pwdata); + CFReleaseSafe(query); +} + +static void test_remove_sysbound_item(void) { + CFMutableDictionaryRef query = test_create_sysbound_query(); + ok_status(SecItemDelete(query), "test_remove_sysbound_item"); + CFReleaseSafe(query); +} + +static void test_find_sysbound_item(OSStatus expectedCode) { + CFMutableDictionaryRef query = test_create_sysbound_query(); + is_status(SecItemCopyMatching(query, NULL), expectedCode, + "test_find_sysbound_item"); + CFReleaseSafe(query); +} + +/* + * BT + */ + +static CFMutableDictionaryRef test_create_bt_query(bool sync) { + CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(query, kSecClass, kSecClassGenericPassword); + CFDictionaryAddValue(query, kSecAttrAccessGroup, CFSTR("com.apple.bluetooth")); + CFDictionaryAddValue(query, kSecAttrSynchronizable, sync ? kCFBooleanTrue : kCFBooleanFalse); + CFDictionarySetValue(query, kSecAttrAccount, sync ? CFSTR("sync") : CFSTR("non-sync")); + return query; +} + +static void test_add_bt_items(const char *data) { + CFMutableDictionaryRef query = NULL; + + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)data, strlen(data)); + + query = test_create_bt_query(false); + (void)SecItemDelete(query); + CFDictionarySetValue(query, kSecValueData, pwdata); + ok_status(SecItemAdd(query, NULL), "test_add_bt_item(nonsync)"); + CFReleaseSafe(query); + + query = test_create_bt_query(true); + (void)SecItemDelete(query); + CFDictionarySetValue(query, kSecValueData, pwdata); + ok_status(SecItemAdd(query, NULL), "test_add_bt_item(sync)"); + CFReleaseSafe(query); + + CFReleaseSafe(pwdata); +} + +static void test_find_bt_item(OSStatus expectedCode, bool sync, const char *data) { + CFMutableDictionaryRef query = test_create_bt_query(sync); + CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue); + CFDataRef pwdata = NULL; + is_status(SecItemCopyMatching(query, (CFTypeRef *)&pwdata), expectedCode, + "test_find_bt_item: %s", data); + CFIndex len = strlen(data); + is(len, CFDataGetLength(pwdata), "length wrong(%s)", data); + ok(memcmp(data, CFDataGetBytePtr(pwdata), len) == 0, "length wrong(%s)", data); + CFReleaseSafe(query); +} + +/* + * MC + */ + +static void test_add_managedconfiguration_item(void) { + CFMutableDictionaryRef query = test_create_managedconfiguration_query(); + const char *v_data = "public managedconfiguration password history data"; + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); + CFDictionaryAddValue(query, kSecValueData, pwdata); + ok_status(SecItemAdd(query, NULL), "test_add_managedconfiguration_item"); + CFReleaseSafe(pwdata); + CFReleaseSafe(query); +} + +static void test_find_managedconfiguration_item(void) { + CFMutableDictionaryRef query = test_create_managedconfiguration_query(); + ok_status(SecItemCopyMatching(query, NULL), "test_find_managedconfiguration_item"); + ok_status(SecItemDelete(query), "test_find_managedconfiguration_item (deleted)"); + CFReleaseSafe(query); +} + +/* + * Accounts + */ + +static void test_add_accounts_item(const char *string) { + CFMutableDictionaryRef query = test_create_accounts_query(); + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)string, strlen(string)); + CFDictionaryAddValue(query, kSecValueData, pwdata); + ok_status(SecItemAdd(query, NULL), "test_add_accounts_item"); + CFReleaseSafe(pwdata); + CFReleaseSafe(query); +} + +static char *test_find_accounts_item(void) { + CFMutableDictionaryRef query = test_create_accounts_query(); + CFDataRef data = NULL; + CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue); + ok_status(SecItemCopyMatching(query, (CFTypeRef *)&data), "test_find_accounts_item"); + if (data == NULL) + return NULL; + ok(isData(data), "data"); + size_t len = CFDataGetLength(data); + char *str = malloc(len + 1); + memcpy(str, CFDataGetBytePtr(data), len); + str[len] = '\0'; + CFReleaseSafe(query); + CFReleaseSafe(data); + return str; +} + +static void test_delete_accounts_item(void) { + CFMutableDictionaryRef query = test_create_accounts_query(); + ok_status(SecItemDelete(query), "test_delete_accounts_item"); + CFReleaseSafe(query); +} + + + +#if USE_KEYSTORE +#define DATA_ARG(x) (x) ? CFDataGetBytePtr((x)) : NULL, (x) ? (int)CFDataGetLength((x)) : 0 +static CFDataRef create_keybag(keybag_handle_t bag_type, CFDataRef password) +{ + CFDataRef result = NULL; + void *bag = NULL; + int bagLen = 0; + + keybag_handle_t handle = bad_keybag_handle; + require_noerr(aks_create_bag(DATA_ARG(password), bag_type, &handle), out); + require_noerr(aks_save_bag(handle, &bag, &bagLen), out); + + result = CFDataCreate(kCFAllocatorDefault, bag, bagLen); + out: + return result; +} +#endif + +/* Test low level keychain migration from device to device interface. */ +static void tests(void) +{ + { + CFMutableDictionaryRef lock_down_query = test_create_lockdown_identity_query(); + (void)SecItemDelete(lock_down_query); + CFReleaseNull(lock_down_query); + } + + int v_eighty = 80; + CFNumberRef eighty = CFNumberCreate(NULL, kCFNumberSInt32Type, &v_eighty); + const char *v_data = "test"; + CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data)); + CFMutableDictionaryRef query = CFDictionaryCreateMutableForCFTypes(NULL); + CFDictionaryAddValue(query, kSecClass, kSecClassInternetPassword); + CFDictionaryAddValue(query, kSecAttrServer, CFSTR("members.spamcop.net")); + CFDictionaryAddValue(query, kSecAttrAccount, CFSTR("smith")); + CFDictionaryAddValue(query, kSecAttrPort, eighty); + CFDictionaryAddValue(query, kSecAttrProtocol, kSecAttrProtocolHTTP); + CFDictionaryAddValue(query, kSecAttrAuthenticationType, kSecAttrAuthenticationTypeDefault); + CFDictionaryAddValue(query, kSecValueData, pwdata); + // NUKE anything we might have left around from a previous test run so we don't crash. + (void)SecItemDelete(query); + + ok_status(SecItemAdd(query, NULL), "add internet password"); + is_status(SecItemAdd(query, NULL), errSecDuplicateItem, + "add internet password again"); + + ok_status(SecItemCopyMatching(query, NULL), "Found the item we added"); + + struct test_persistent_s p = {}; + test_persistent(&p); + + CFDataRef backup = NULL, keybag = NULL, password = NULL; + + test_add_lockdown_identity_items(); + test_add_sysbound_item(); + test_add_accounts_item("1"); + test_add_bt_items("kaka1"); + +#if USE_KEYSTORE + keybag = create_keybag(kAppleKeyStoreBackupBag, password); +#else + keybag = CFDataCreate(kCFAllocatorDefault, NULL, 0); +#endif + + ok(backup = _SecKeychainCopyBackup(keybag, password), + "_SecKeychainCopyBackup"); + + test_add_managedconfiguration_item(); + test_delete_accounts_item(); + test_add_accounts_item("2"); + test_remove_lockdown_identity_items(); + test_remove_sysbound_item(); + + test_add_bt_items("kaka2"); + + ok_status(_SecKeychainRestoreBackup(backup, keybag, password), + "_SecKeychainRestoreBackup"); + CFReleaseSafe(backup); + + test_no_find_lockdown_identity_item(); + test_find_sysbound_item(errSecItemNotFound); + test_find_managedconfiguration_item(); + char *val = test_find_accounts_item(); + eq_string(val, "2", "string not 2 as expected: %s", val); + test_delete_accounts_item(); + + /* + * Check that the kaka1 entry was "overwritten" + */ + test_find_bt_item(errSecSuccess, true, "kaka2"); + test_find_bt_item(errSecSuccess, false, "kaka1"); + + ok_status(SecItemCopyMatching(query, NULL), + "Found the item we added after restore"); + + test_persistent2(&p); + +#if USE_KEYSTORE + CFReleaseNull(keybag); + keybag = create_keybag(kAppleKeyStoreOTABackupBag, password); +#endif + + ok(backup = _SecKeychainCopyBackup(keybag, password), + "_SecKeychainCopyBackup"); + ok_status(_SecKeychainRestoreBackup(backup, keybag, password), + "_SecKeychainRestoreBackup"); + ok_status(SecItemCopyMatching(query, NULL), + "Found the item we added after restore"); + CFReleaseNull(backup); + + // force tombstone to be added, since it's not the default behavior per rdar://14680869 + CFDictionaryAddValue(query, kSecUseTombstones, kCFBooleanTrue); + + ok_status(SecItemDelete(query), "Deleted item we added"); + +#if USE_KEYSTORE + CFReleaseNull(keybag); + keybag = create_keybag(kAppleKeyStoreOTABackupBag /* use truthiness bag once it's there */, password); +#endif + + // add syncable item + CFDictionaryAddValue(query, kSecAttrSynchronizable, kCFBooleanTrue); + ok_status(SecItemAdd(query, NULL), "add internet password"); + + // and non-syncable item + test_add_managedconfiguration_item(); + + CFDictionaryRef syncableBackup = NULL; + + CFErrorRef error = NULL; + CFDictionaryRef scratch = NULL; +SKIP: { + skip("skipping syncable backup tests", 7, + ok_status(_SecKeychainBackupSyncable(keybag, password, NULL, &syncableBackup), "export items")); + + // TODO: add item, call SecServerCopyTruthInTheCloud again + + // CFShow(syncableBackup); + + // find and delete + skip("skipping syncable backup tests", 6, + ok_status(SecItemCopyMatching(query, NULL), "find item we are about to destroy")); + + skip("skipping syncable backup tests", 5, + ok_status(SecItemDelete(query), "delete item we backed up")); + + // ensure we added a tombstone + CFDictionaryAddValue(query, kSecAttrTombstone, kCFBooleanTrue); + skip("skipping syncable backup tests", 4, + ok_status(SecItemCopyMatching(query, NULL), "find tombstone for item we deleted")); + CFDictionaryRemoveValue(query, kSecAttrTombstone); + + test_find_managedconfiguration_item(); // <- 2 tests here + + // TODO: add a different new item - delete what's not in the syncableBackup? + + // Do another backup after some changes + skip("skipping syncable backup tests", 1, + ok_status(_SecKeychainBackupSyncable(keybag, password, syncableBackup, &scratch), "export items after changes")); + + skip("skipping syncable backup tests", 0, + ok_status(_SecKeychainRestoreSyncable(keybag, password, syncableBackup), "import items")); +} + CFReleaseNull(scratch); + CFReleaseNull(error); + + // non-syncable item should (still) be gone -> add should work + test_add_managedconfiguration_item(); + test_find_managedconfiguration_item(); + + // syncable item should have not been restored, because the tombstone was newer than the item in the backup -> copy matching should fail + is_status(errSecItemNotFound, SecItemCopyMatching(query, NULL), + "find restored item"); + is_status(errSecItemNotFound, SecItemDelete(query), "delete restored item"); + + CFReleaseSafe(syncableBackup); + CFReleaseSafe(keybag); + CFReleaseSafe(eighty); + CFReleaseSafe(pwdata); + CFReleaseSafe(query); +} + +int secd_33_keychain_backup(int argc, char *const *argv) +{ + plan_tests(85); + + CFArrayRef currentACL = CFRetainSafe(SecAccessGroupsGetCurrent()); + + NSMutableArray *newACL = [NSMutableArray arrayWithArray:(__bridge NSArray *)currentACL]; + [newACL addObjectsFromArray:@[ + @"com.apple.bluetooth", + @"lockdown-identities", + @"apple", + ]]; + + SecAccessGroupsSetCurrent((__bridge CFArrayRef)newACL); + + + secd_test_setup_temp_keychain("secd_33_keychain_backup", NULL); + + tests(); + + SecAccessGroupsSetCurrent(currentACL); + CFReleaseNull(currentACL); + + return 0; +} diff --git a/OSX/sec/securityd/Regressions/secd-33-keychain-ctk.m b/OSX/sec/securityd/Regressions/secd-33-keychain-ctk.m index f7422fc2..4aa765e0 100644 --- a/OSX/sec/securityd/Regressions/secd-33-keychain-ctk.m +++ b/OSX/sec/securityd/Regressions/secd-33-keychain-ctk.m @@ -39,11 +39,11 @@ #include #include #include -#include +#include #include -#include +#include #include #include "secd_regressions.h" @@ -63,8 +63,7 @@ static void test_item_add(void) { static const UInt8 data[] = { 0x01, 0x02, 0x03, 0x04 }; CFDataRef valueData = CFDataCreate(NULL, data, sizeof(data)); - static const UInt8 oid[] = { 0x05, 0x06, 0x07, 0x08 }; - CFDataRef oidData = CFDataCreate(NULL, oid, sizeof(oid)); + __block NSUInteger objIDIdx = 0; CFMutableDictionaryRef attrs = CFDictionaryCreateMutableForCFTypesWith(NULL, kSecClass, kSecClassGenericPassword, @@ -87,7 +86,8 @@ static void test_item_add(void) { eq_cf(CFDictionaryGetValue(at, kSecAttrTokenID), CFSTR("tokenid")); eq_cf(CFDictionaryGetValue(at, kSecValueData), valueData); CFDictionaryRemoveValue(at, kSecValueData); - return CFRetainSafe(oidData); + ++objIDIdx; + return (__bridge_retained CFDataRef)[NSData dataWithBytes:&objIDIdx length:sizeof(objIDIdx)]; }; blocks->copyObjectAccessControl = ^CFDataRef(CFDataRef oid, CFErrorRef *error) { @@ -136,12 +136,9 @@ static void test_item_add(void) { CFRelease(attrs); CFRelease(valueData); - CFRelease(oidData); } static void test_item_query() { - static const UInt8 oid[] = { 0x05, 0x06, 0x07, 0x08 }; - CFDataRef oidData = CFDataCreate(NULL, oid, sizeof(oid)); static const UInt8 data[] = { 0x01, 0x02, 0x03, 0x04 }; CFDataRef valueData = CFDataCreate(NULL, data, sizeof(data)); CFDataRef valueData2 = CFDataCreate(NULL, data, sizeof(data) - 1); @@ -211,10 +208,51 @@ static void test_item_query() { eq_cf(result, valueData); CFReleaseSafe(result); + static const uint8_t tk_persistent_ref_id[] = {'t', 'k', 'p', 'r'}; + NSData *persistentRefId = [NSData dataWithBytes:tk_persistent_ref_id length:sizeof(tk_persistent_ref_id)]; + phase = 0; + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrService : @"ctktest-service", + (id)kSecReturnPersistentRef : @YES }, &result)); + is(phase, 0); + NSData *persistentRef = (__bridge NSData *)result; + is(CFDataCompare((__bridge CFDataRef)persistentRefId, (__bridge CFDataRef)[persistentRef subdataWithRange:NSMakeRange(0, 4)]), kCFCompareEqualTo); + CFReleaseSafe(result); + + phase = 0; + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrService : @"ctktest-service", + (id)kSecReturnData : @YES, + (id)kSecReturnPersistentRef : @YES }, &result)); + is(phase, 2); + persistentRef = ((__bridge NSDictionary *)result)[(id)kSecValuePersistentRef]; + is(CFDataCompare((__bridge CFDataRef)persistentRefId, (__bridge CFDataRef)[persistentRef subdataWithRange:NSMakeRange(0, 4)]), kCFCompareEqualTo); + CFReleaseSafe(result); + + phase = 0; + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrService : @"ctktest-service", + (id)kSecReturnAttributes : @YES, + (id)kSecReturnPersistentRef : @YES }, &result)); + is(phase, 0); + persistentRef = ((__bridge NSDictionary *)result)[(id)kSecValuePersistentRef]; + is(CFDataCompare((__bridge CFDataRef)persistentRefId, (__bridge CFDataRef)[persistentRef subdataWithRange:NSMakeRange(0, 4)]), kCFCompareEqualTo); + CFReleaseSafe(result); + + phase = 0; + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrService : @"ctktest-service", + (id)kSecReturnData : @YES, + (id)kSecReturnAttributes : @YES, + (id)kSecReturnPersistentRef : @YES }, &result)); + is(phase, 2); + persistentRef = ((__bridge NSDictionary *)result)[(id)kSecValuePersistentRef]; + is(CFDataCompare((__bridge CFDataRef)persistentRefId, (__bridge CFDataRef)[persistentRef subdataWithRange:NSMakeRange(0, 4)]), kCFCompareEqualTo); + CFReleaseSafe(result); + CFRelease(query); CFRelease(valueData); CFRelease(valueData2); - CFRelease(oidData); } static void test_item_update() { @@ -364,7 +402,7 @@ static void test_item_delete(void) { phase = 0; #if LA_CONTEXT_IMPLEMENTED LASetErrorCodeBlock(^{ return (CFErrorRef)NULL; }); - deleteError = CFErrorCreate(NULL, CFSTR(kTKErrorDomain), kTKErrorCodeAuthenticationFailed, NULL); + deleteError = CFErrorCreate(NULL, CFSTR(kTKErrorDomain), kTKErrorCodeAuthenticationNeeded, NULL); ok_status(SecItemDelete(query), "delete multiple token items"); is(phase, 6, "connect + delete-auth-fail + copyAccess + connect + delete + delete-2nd"); #else @@ -398,7 +436,7 @@ static void test_key_generate(int globalPersistence, int privatePersistence, int privateKey = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)objectID, (CFDictionaryRef)params, NULL)); } else { phase |= 0x02; - privateKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, error)); + privateKey = CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)params, error)); } NSDictionary *privKeyAttrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)privateKey)); CFDictionarySetValue(at, kSecClass, kSecClassKey); @@ -449,7 +487,7 @@ static void test_key_generate(int globalPersistence, int privatePersistence, int NSError *error; phase = 0; - id privateKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error)); + id privateKey = CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)params, (void *)&error)); isnt(privateKey, nil, "failed to generate token key, error %@", error); is(phase, privateIsPersistent ? 0x3f : 0x1f); id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)privateKey)); @@ -462,7 +500,7 @@ static void test_key_generate(int globalPersistence, int privatePersistence, int phase = 0; NSDictionary *result; if (privateIsPersistent) { - ok_status(SecItemCopyMatching((CFDictionaryRef)query, (void *)&result), "persistent private key not found in kc"); + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (void *)&result), "persistent private key not found in kc"); is(phase, 0x19); is(result[(id)kSecValueData], nil); eq_cf((__bridge CFTypeRef)result[(id)kSecAttrTokenID], @"tokenid"); @@ -471,7 +509,7 @@ static void test_key_generate(int globalPersistence, int privatePersistence, int keyAttrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)publicKey)); eq_cf((__bridge CFTypeRef)keyAttrs[(id)kSecAttrApplicationLabel], (__bridge CFTypeRef)result[(id)kSecAttrApplicationLabel]); } else { - is_status(SecItemCopyMatching((CFDictionaryRef)query, (void *)&result), errSecItemNotFound, "ephemeral private key found in kc"); + is_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (void *)&result), errSecItemNotFound, "ephemeral private key found in kc"); is(phase, 0x08); // Balancing test count from the branch above @@ -488,11 +526,11 @@ static void test_key_generate(int globalPersistence, int privatePersistence, int phase = 0; result = nil; if (publicIsPersistent) { - ok_status(SecItemCopyMatching((CFDictionaryRef)query, (void *)&result), "persistent public key not found in kc"); + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (void *)&result), "persistent public key not found in kc"); NSDictionary *keyAttrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)publicKey)); eq_cf((__bridge CFTypeRef)keyAttrs[(id)kSecAttrApplicationLabel], (__bridge CFTypeRef)result[(id)kSecAttrApplicationLabel]); } else { - is_status(SecItemCopyMatching((CFDictionaryRef)query, (void *)&result), errSecItemNotFound, "ephemeral public key found in kc"); + is_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (void *)&result), errSecItemNotFound, "ephemeral public key found in kc"); // Balancing test count from the branch above ok(true); @@ -577,7 +615,7 @@ static void test_key_sign(void) { phase = 0; SecKeyRef privateKey = NULL; - ok_status(SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef *)&privateKey)); + ok_status(SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&privateKey)); is(phase, 2); phase = 0; @@ -597,7 +635,7 @@ static void test_key_sign(void) { CFDataSetLength(sig, 256); sigLen = CFDataGetLength(sig); LASetErrorCodeBlock(^{ return (CFErrorRef)NULL; }); - cryptoError = CFErrorCreate(NULL, CFSTR(kTKErrorDomain), kTKErrorCodeAuthenticationFailed, NULL); + cryptoError = CFErrorCreate(NULL, CFSTR(kTKErrorDomain), kTKErrorCodeAuthenticationNeeded, NULL); ok_status(SecKeyRawSign(privateKey, kSecPaddingPKCS1, data, sizeof(data), CFDataGetMutableBytePtr(sig), &sigLen)); is(phase, 4); is(cryptoError, NULL); @@ -616,7 +654,7 @@ static void test_key_sign(void) { NSDictionary *params = @{ (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256 }; SecKeyRef otherPrivKey = NULL, otherPubKey = NULL; - ok_status(SecKeyGeneratePair((CFDictionaryRef)params, &otherPubKey, &otherPrivKey)); + ok_status(SecKeyGeneratePair((__bridge CFDictionaryRef)params, &otherPubKey, &otherPrivKey)); error = nil; result = CFBridgingRelease(SecKeyCopyKeyExchangeResult(privateKey, kSecKeyAlgorithmECDHKeyExchangeCofactor, @@ -932,19 +970,6 @@ static void test_identity_on_two_tokens() { CFStringRef cert3OID = CFSTR("oid1"); TKTokenTestSetHook(^(CFDictionaryRef attributes, TKTokenTestBlocks *blocks) { - blocks->createOrUpdateObject = ^CFDataRef(CFDataRef objectID, CFMutableDictionaryRef at, CFErrorRef *error) { - return CFBridgingRetain([[NSData alloc] initWithBase64EncodedString:@"BAcrF9iBupEeZOE+c73JBfkqsv8Q9rp1lTnZbKzmALf8yTR02310uGlZuUBVp4HOSiziO43dzFuegH0ywLhu+gtJj81RD8Rt+nLR6oTARkL+0l2/fzrIouleaEYpYmEp0A==" options:NSDataBase64DecodingIgnoreUnknownCharacters]); - }; - - blocks->copyPublicKeyData = ^CFDataRef(CFDataRef objectID, CFErrorRef *error) { - SecKeyRef privKey = SecKeyCreateECPrivateKey(NULL, CFDataGetBytePtr(objectID), CFDataGetLength(objectID), kSecKeyEncodingBytes); - ok(privKey); - CFDataRef publicData; - ok_status(SecKeyCopyPublicBytes(privKey, &publicData)); - CFReleaseSafe(privKey); - return publicData; - }; - blocks->copyObjectData = ^CFTypeRef(CFDataRef oid, CFErrorRef *error) { if (CFEqual(oid, cert3OID)) return copy_certificate_data(cert3); @@ -952,60 +977,53 @@ static void test_identity_on_two_tokens() { return kCFNull; }; - blocks->copyObjectAccessControl = ^CFDataRef(CFDataRef oid, CFErrorRef *error) { - SecAccessControlRef ac = SecAccessControlCreate(NULL, NULL); - SecAccessControlSetProtection(ac, kSecAttrAccessibleAlwaysPrivate, NULL); - test_IsTrue(SecAccessControlAddConstraintForOperation(ac, kAKSKeyOpDefaultAcl, kCFBooleanTrue, NULL)); - CFDataRef acData = SecAccessControlCopyData(ac); - CFRelease(ac); - return acData; - }; - - blocks->copyOperationResult = ^CFTypeRef(CFDataRef objectID, CFIndex operation, CFArrayRef algorithms, CFIndex secKeyOperationMode, CFTypeRef in1, CFTypeRef in2, CFErrorRef *error) { - ok(operation == 0); - SecKeyRef privKey = SecKeyCreateECPrivateKey(NULL, CFDataGetBytePtr(objectID), CFDataGetLength(objectID), kSecKeyEncodingBytes); - ok(privKey); - CFDataRef signature = SecKeyCreateSignature(privKey, kSecKeyAlgorithmECDSASignatureDigestX962, in1, error); - ok(signature); - CFReleaseSafe(privKey); - return signature; - }; - }); @autoreleasepool { NSString *tokenID1 = @"com.apple.secdtest:identity_test_token1"; NSString *tokenID2 = @"com.apple.secdtest:identity_test_token2"; - NSDictionary *params = @{ (id)kSecAttrKeyType : (id)kSecAttrKeyTypeEC, - (id)kSecAttrKeySizeInBits : @"256", - (id)kSecAttrTokenID : tokenID1, - (id)kSecPrivateKeyAttrs : @{ (id)kSecAttrIsPermanent : @YES/*, (id)kSecAttrIsPrivate : @YES*/ } - }; + NSError *error; + NSData *privKeyData = [[NSData alloc] initWithBase64EncodedString:@"BAcrF9iBupEeZOE+c73JBfkqsv8Q9rp1lTnZbKzmALf8yTR02310uGlZuUBVp4HOSiziO43dzFuegH0ywLhu+gtJj81RD8Rt+nLR6oTARkL+0l2/fzrIouleaEYpYmEp0A==" options:NSDataBase64DecodingIgnoreUnknownCharacters]; + id privKey = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)privKeyData, (CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate}, (void *)&error)); + id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((__bridge SecKeyRef)privKey)); + NSData *pubKeyHash = CFBridgingRelease(SecKeyCopyPublicKeyHash((__bridge SecKeyRef)publicKey)); + + id ac = CFBridgingRelease(SecAccessControlCreateWithFlags(kCFAllocatorDefault, kSecAttrAccessibleWhenUnlocked, 0, NULL)); + id acData = CFBridgingRelease(SecAccessControlCopyData((__bridge SecAccessControlRef)ac)); + NSDictionary *keyQuery = @{ (id)kSecClass: (id)kSecClassKey, + (id)kSecAttrTokenID: tokenID1, + (id)kSecAttrKeyType : (id)kSecAttrKeyTypeECSECPrimeRandom, + (id)kSecAttrKeySizeInBits : @"256", + (id)kSecAttrKeyClass: (id)kSecAttrKeyClassPrivate, + (id)kSecAttrIsPrivate: @YES, + (id)kSecAttrAccessControl: acData, + (id)kSecAttrTokenOID : privKeyData, + (id)kSecAttrApplicationLabel : pubKeyHash, + }; + OSStatus result; + ok_status(result = SecItemUpdateTokenItems((__bridge CFStringRef)tokenID1, (__bridge CFArrayRef)@[keyQuery]), "Failed to propagate key item."); - SecKeyRef publicKey = NULL, privateKey = NULL; - ok_status(SecKeyGeneratePair((CFDictionaryRef)params, &publicKey, &privateKey)); + id privateKey; + ok_status(result = SecItemCopyMatching((__bridge CFDictionaryRef)@{(id)kSecClass: (id)kSecClassKey, (id)kSecAttrTokenID: tokenID1, (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, (id)kSecReturnRef: @YES}, (void *)&privateKey)); NSDictionary *certQuery = CFBridgingRelease(copy_certificate_query(cert3, CFSTR("test_cert3"), cert3OID, (__bridge CFStringRef)tokenID2)); ok(certQuery); - OSStatus result; - ok_status(result = SecItemUpdateTokenItems((__bridge CFStringRef)tokenID2, (__bridge CFArrayRef)@[certQuery]), "Failed to propagate items."); - - NSData *pubKeyHash = CFBridgingRelease(SecKeyCopyPublicKeyHash(publicKey)); + ok_status(result = SecItemUpdateTokenItems((__bridge CFStringRef)tokenID2, (__bridge CFArrayRef)@[certQuery]), "Failed to propagate cert item."); CFTypeRef resultRef; - NSDictionary *query = @{ (id)kSecClass : (id)kSecClassKey, (id)kSecAttrApplicationLabel : pubKeyHash, (id)kSecReturnRef : @YES, (id)kSecReturnAttributes : @YES }; - ok_status(result = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)&resultRef)); - CFReleaseSafe(resultRef); + NSDictionary *query = @{ (id)kSecClass : (id)kSecClassKey, (id)kSecAttrApplicationLabel : pubKeyHash, (id)kSecReturnRef : @YES, (id)kSecReturnAttributes : @YES, (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken }; + ok_status(result = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&resultRef)); + CFReleaseNull(resultRef); - query = @{ (id)kSecClass : (id)kSecClassCertificate, (id)kSecAttrPublicKeyHash : pubKeyHash, (id)kSecReturnRef : @YES, (id)kSecReturnAttributes : @YES }; - ok_status(result = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)&resultRef)); - CFReleaseSafe(resultRef); + query = @{ (id)kSecClass : (id)kSecClassCertificate, (id)kSecAttrPublicKeyHash : pubKeyHash, (id)kSecReturnRef : @YES, (id)kSecReturnAttributes : @YES, (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken }; + ok_status(result = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&resultRef)); + CFReleaseNull(resultRef); - query = @{ (id)kSecClass : (id)kSecClassIdentity, (id)kSecAttrApplicationLabel : pubKeyHash, (id)kSecReturnRef : @YES, (id)kSecReturnAttributes : @YES }; - ok_status(result = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)&resultRef)); - CFReleaseSafe(resultRef); + query = @{ (id)kSecClass : (id)kSecClassIdentity, (id)kSecAttrApplicationLabel : pubKeyHash, (id)kSecReturnRef : @YES, (id)kSecReturnAttributes : @YES, (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken }; + ok_status(result = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&resultRef)); + CFReleaseNull(resultRef); } } @@ -1078,7 +1096,7 @@ static void test_ies(SecKeyRef privateKey, SecKeyAlgorithm algorithm) { (id)kSecPrivateKeyAttrs : @{ (id)kSecAttrIsPermanent : @YES } }; NSError *error; - SecKeyRef tokenKey = SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error); + SecKeyRef tokenKey = SecKeyCreateRandomKey((__bridge CFDictionaryRef)params, (void *)&error); ok(tokenKey != NULL, "create token-based key (err %@)", error); SecKeyRef tokenPublicKey = SecKeyCopyPublicKey(tokenKey); @@ -1099,7 +1117,7 @@ static void test_ies(SecKeyRef privateKey, SecKeyAlgorithm algorithm) { static void test_ecies() { NSError *error; - SecKeyRef privateKey = SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256}, (void *)&error); + SecKeyRef privateKey = SecKeyCreateRandomKey((__bridge CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256}, (void *)&error); ok(privateKey != NULL, "failed to generate CPU EC key: %@", error); test_ies(privateKey, kSecKeyAlgorithmECIESEncryptionCofactorX963SHA256AESGCM); @@ -1109,7 +1127,7 @@ static void test_ecies() { static void test_rsawrap() { NSError *error; - SecKeyRef privateKey = SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @2048}, (void *)&error); + SecKeyRef privateKey = SecKeyCreateRandomKey((__bridge CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeRSA, (id)kSecAttrKeySizeInBits: @2048}, (void *)&error); ok(privateKey != NULL, "failed to generate CPU RSA key: %@", error); test_ies(privateKey, kSecKeyAlgorithmRSAEncryptionOAEPSHA256AESGCM); @@ -1147,7 +1165,7 @@ static void tests(void) { } int secd_33_keychain_ctk(int argc, char *const *argv) { - plan_tests(484); + plan_tests(491); tests(); return 0; diff --git a/OSX/sec/securityd/Regressions/secd-34-backup-der-parse.m b/OSX/sec/securityd/Regressions/secd-34-backup-der-parse.m index dcc571ec..e860ca41 100644 --- a/OSX/sec/securityd/Regressions/secd-34-backup-der-parse.m +++ b/OSX/sec/securityd/Regressions/secd-34-backup-der-parse.m @@ -420,7 +420,8 @@ static void secd_perform_with_data_in_file(const char* test_prefix, void(^with)( CFStringRef tmp_dir = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("/tmp/%s.%X/"), test_prefix, arc4random()); CFStringPerformWithCString(tmp_dir, ^(const char *tmp_dir_string) { - ok_unix(mkpath_np(tmp_dir_string, 0755), "Create temp dir %s", tmp_dir_string); + errno_t err = mkpath_np(tmp_dir_string, 0755); + ok(err == 0 || err == EEXIST, "Create temp dir %s (%d)", tmp_dir_string, err); FILE *file = fopen(fname, "w", error); }); 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 2c1c12ef..56368e54 100644 --- a/OSX/sec/securityd/Regressions/secd-35-keychain-migrate-inet.m +++ b/OSX/sec/securityd/Regressions/secd-35-keychain-migrate-inet.m @@ -38,7 +38,7 @@ #include #if TARGET_OS_IPHONE && USE_KEYSTORE -#include +#include "OSX/utilities/SecAKSWrappers.h" #include "SecdTestKeychainUtilities.h" @@ -67,21 +67,21 @@ int secd_35_keychain_migrate_inet(int argc, char *const *argv) SecItemServerSetKeychainChangedNotification("com.apple.secdtests.keychainchanged"); /* Create and lock custom keybag */ - ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); SecItemServerSetKeychainKeybag(keybag); /* lock */ - ok(kIOReturnSuccess==aks_lock_bag(keybag), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_lock_bag(keybag), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(state&keybag_state_locked, "keybag locked"); }); CFReleaseSafe(keychain_path_cf); }); - CFArrayRef old_ag = SecAccessGroupsGetCurrent(); + CFArrayRef old_ag = CFRetainSafe(SecAccessGroupsGetCurrent()); CFMutableArrayRef test_ag = CFArrayCreateMutableCopy(NULL, 0, old_ag); CFArrayAppendValue(test_ag, CFSTR("com.apple.cfnetwork")); SecAccessGroupsSetCurrent(test_ag); @@ -106,8 +106,8 @@ int secd_35_keychain_migrate_inet(int argc, char *const *argv) CFTypeRef results = NULL; is_status(SecItemCopyMatching(query, &results), errSecInteractionNotAllowed); - ok(kIOReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "lock keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_unlock_bag(keybag, passcode, passcode_len), "lock keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); // We should be able to query 2 inet items from the DB here. But the database is encrypted @@ -121,6 +121,7 @@ int secd_35_keychain_migrate_inet(int argc, char *const *argv) // Reset server accessgroups. SecAccessGroupsSetCurrent(old_ag); + CFReleaseNull(old_ag); CFReleaseSafe(test_ag); CFReleaseSafe(results); diff --git a/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m b/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m index d13d6f3d..ff85cb8f 100644 --- a/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m +++ b/OSX/sec/securityd/Regressions/secd-36-ks-encrypt.m @@ -32,13 +32,13 @@ #include #if USE_KEYSTORE -#include +#include "OSX/utilities/SecAKSWrappers.h" #include "SecdTestKeychainUtilities.h" int secd_36_ks_encrypt(int argc, char *const *argv) { - plan_tests(8); + plan_tests(9); secd_test_setup_temp_keychain("secd_36_ks_encrypt", NULL); @@ -55,8 +55,8 @@ int secd_36_ks_encrypt(int argc, char *const *argv) /* Create and lock custom keybag */ - is(kIOReturnSuccess, aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); - is(kIOReturnSuccess, aks_get_lock_state(keybag, &state), "get keybag state"); + is(kAKSReturnSuccess, aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &keybag), "create keybag"); + is(kAKSReturnSuccess, aks_get_lock_state(keybag, &state), "get keybag state"); is(0, (int)(state&keybag_state_locked), "keybag unlocked"); data = (__bridge CFDictionaryRef)@{ 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 b527505b..7ac6d8ac 100644 --- a/OSX/sec/securityd/Regressions/secd-37-pairing-initial-sync.m +++ b/OSX/sec/securityd/Regressions/secd-37-pairing-initial-sync.m @@ -65,7 +65,7 @@ int secd_37_pairing_initial_sync(int argc, char *const *argv) /* custom keychain dir */ secd_test_setup_temp_keychain("secd_37_pairing_initial_sync", NULL); - CFArrayRef currentACL = SecAccessGroupsGetCurrent(); + CFArrayRef currentACL = CFRetainSafe(SecAccessGroupsGetCurrent()); NSMutableArray *newACL = [NSMutableArray arrayWithArray:(__bridge NSArray *)currentACL]; [newACL addObjectsFromArray:@[ @@ -151,6 +151,7 @@ int secd_37_pairing_initial_sync(int argc, char *const *argv) CFReleaseNull(stuff); SecAccessGroupsSetCurrent(currentACL); + CFReleaseNull(currentACL); return 0; diff --git a/OSX/sec/securityd/Regressions/secd-49-manifests.m b/OSX/sec/securityd/Regressions/secd-49-manifests.m index 93685b4a..fe098739 100644 --- a/OSX/sec/securityd/Regressions/secd-49-manifests.m +++ b/OSX/sec/securityd/Regressions/secd-49-manifests.m @@ -22,15 +22,15 @@ */ -#include -#include +#include "keychain/SecureObjectSync/SOSManifest.h" +#include "keychain/SecureObjectSync/SOSMessage.h" #include "secd_regressions.h" #include #include #include -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" #include #include diff --git a/OSX/sec/securityd/Regressions/secd-50-account.m b/OSX/sec/securityd/Regressions/secd-50-account.m index 66d3e631..097b3990 100644 --- a/OSX/sec/securityd/Regressions/secd-50-account.m +++ b/OSX/sec/securityd/Regressions/secd-50-account.m @@ -26,12 +26,12 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include diff --git a/OSX/sec/securityd/Regressions/secd-50-message.m b/OSX/sec/securityd/Regressions/secd-50-message.m index 418b8133..0fa120bc 100644 --- a/OSX/sec/securityd/Regressions/secd-50-message.m +++ b/OSX/sec/securityd/Regressions/secd-50-message.m @@ -22,14 +22,14 @@ */ -#include -#include +#include "keychain/SecureObjectSync/SOSManifest.h" +#include "keychain/SecureObjectSync/SOSMessage.h" #include "secd_regressions.h" #include #include -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" #include static void testNullMessage(uint64_t msgid) diff --git a/OSX/sec/securityd/Regressions/secd-51-account-inflate.m b/OSX/sec/securityd/Regressions/secd-51-account-inflate.m index d9214a47..c50f219d 100644 --- a/OSX/sec/securityd/Regressions/secd-51-account-inflate.m +++ b/OSX/sec/securityd/Regressions/secd-51-account-inflate.m @@ -25,11 +25,11 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -243,7 +243,7 @@ static void tests(void) ok(SOSAccountResetToOffering_wTxn(account, &error), "Reset to offering (%@)", error); CFReleaseNull(error); - + ok(testAccountPersistence(account), "Test Account->DER->Account Equivalence"); SOSTestCleanup(); @@ -257,6 +257,7 @@ int secd_51_account_inflate(int argc, char *const *argv) plan_tests(kTestTestCount + kCompatibilityTestCount); secd_test_setup_temp_keychain(__FUNCTION__, NULL); + secd_test_clear_testviews(); tests(); /* we can't re-inflate the v6 DER since we don't have a viable private key for it. */ diff --git a/OSX/sec/securityd/Regressions/secd-52-account-changed.m b/OSX/sec/securityd/Regressions/secd-52-account-changed.m index 838f859d..214c0ab6 100644 --- a/OSX/sec/securityd/Regressions/secd-52-account-changed.m +++ b/OSX/sec/securityd/Regressions/secd-52-account-changed.m @@ -26,11 +26,11 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -46,7 +46,6 @@ #include "SecdTestKeychainUtilities.h" #include "SOSAccountTesting.h" -static int kTestTestCount = 152; static void tests(void) { @@ -206,7 +205,7 @@ static void tests(void) int secd_52_account_changed(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(113); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m b/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m index 1425ec83..22a15018 100644 --- a/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m +++ b/OSX/sec/securityd/Regressions/secd-52-offering-gencount-reset.m @@ -29,12 +29,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -52,7 +52,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 79; static void tests(void) { @@ -172,7 +171,7 @@ static void tests(void) int secd_52_offering_gencount_reset(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(63); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-55-account-circle.m b/OSX/sec/securityd/Regressions/secd-55-account-circle.m index e21b77a4..9e91f032 100644 --- a/OSX/sec/securityd/Regressions/secd-55-account-circle.m +++ b/OSX/sec/securityd/Regressions/secd-55-account-circle.m @@ -29,13 +29,13 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include diff --git a/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m b/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m index e5c66d62..fcb6b210 100644 --- a/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m +++ b/OSX/sec/securityd/Regressions/secd-55-account-incompatibility.m @@ -29,13 +29,13 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include diff --git a/OSX/sec/securityd/Regressions/secd-56-account-apply.m b/OSX/sec/securityd/Regressions/secd-56-account-apply.m index 3dc630a3..7e12348f 100644 --- a/OSX/sec/securityd/Regressions/secd-56-account-apply.m +++ b/OSX/sec/securityd/Regressions/secd-56-account-apply.m @@ -29,11 +29,11 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include #include @@ -51,8 +51,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 181; - #define kAccountPasswordString ((uint8_t*) "FooFooFoo") #define kAccountPasswordStringLen 10 @@ -214,7 +212,7 @@ static void tests(void) int secd_56_account_apply(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(181); secd_test_setup_temp_keychain(__FUNCTION__, NULL); 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 9ddf953c..ba45cf74 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 @@ -33,12 +33,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -57,9 +57,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 61; - - static bool acceptApplicants(SOSAccount* account, CFIndex count) { bool retval = false; CFErrorRef error = NULL; @@ -154,7 +151,7 @@ static void tests(void) int secd_57_1_account_last_standing(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(45); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-57-account-leave.m b/OSX/sec/securityd/Regressions/secd-57-account-leave.m index a85691de..4c9b0732 100644 --- a/OSX/sec/securityd/Regressions/secd-57-account-leave.m +++ b/OSX/sec/securityd/Regressions/secd-57-account-leave.m @@ -29,12 +29,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -53,8 +53,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 251; - /* static void trim_retirements_from_circle(SOSAccount* account) { SOSAccountForEachCircle(account, ^(SOSCircleRef circle) { @@ -254,9 +252,10 @@ static void tests(void) int secd_57_account_leave(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(191); secd_test_setup_temp_keychain(__FUNCTION__, NULL); + secd_test_clear_testviews(); tests(); diff --git a/OSX/sec/securityd/Regressions/secd-58-password-change.m b/OSX/sec/securityd/Regressions/secd-58-password-change.m index 26aa9486..ca235fbb 100644 --- a/OSX/sec/securityd/Regressions/secd-58-password-change.m +++ b/OSX/sec/securityd/Regressions/secd-58-password-change.m @@ -29,11 +29,11 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include #include @@ -50,7 +50,6 @@ #include "SOSAccountTesting.h" #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 257; static bool AssertCreds(SOSAccount* account,CFStringRef acct_name, CFDataRef password) { CFErrorRef error = NULL; @@ -224,7 +223,7 @@ static void tests(void) int secd_58_password_change(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(211); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-59-account-cleanup.m b/OSX/sec/securityd/Regressions/secd-59-account-cleanup.m index 4dc43f3f..380ae6ab 100644 --- a/OSX/sec/securityd/Regressions/secd-59-account-cleanup.m +++ b/OSX/sec/securityd/Regressions/secd-59-account-cleanup.m @@ -29,13 +29,13 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" #include #include @@ -52,7 +52,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 121; static void tests(void) { @@ -150,7 +149,7 @@ static void tests(void) int secd_59_account_cleanup(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(91); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m b/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m index 9bd82500..cdccf871 100644 --- a/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m +++ b/OSX/sec/securityd/Regressions/secd-60-account-cloud-identity.m @@ -29,12 +29,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -52,7 +52,9 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 161; +static int kTestTestCount = 111; + +#if FIX_ICLOUD_IDENTITY_AS_SET_CRED_SIDE_EFFECT static bool purgeICloudIdentity(SOSAccount* account) { bool retval = false; @@ -63,6 +65,8 @@ static bool purgeICloudIdentity(SOSAccount* account) { return retval; } +#endif + static void tests(void) { CFErrorRef error = NULL; @@ -150,7 +154,8 @@ static void tests(void) accounts_agree_internal("Carole's in", bob_account, alice_account, false); accounts_agree_internal("Carole's in - 2", bob_account, carole_account, false); - + +#if FIX_ICLOUD_IDENTITY_AS_SET_CRED_SIDE_EFFECT /* Break iCloud identity FPI in all peers */ ok(purgeICloudIdentity(alice_account), "remove iCloud private key"); @@ -184,14 +189,14 @@ static void tests(void) is(countApplicants(alice_account), 0, "See no applicants"); - + is(countPeers(carole_account), 3, "Carole sees 3 valid peers after sliding in"); is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, carole_account, NULL), 1, "updates"); accounts_agree_internal("Carole's in", bob_account, alice_account, false); accounts_agree_internal("Carole's in - 2", bob_account, carole_account, false); - +#endif //join after piggybacking the icloud identity?? CFMutableArrayRef identityArray = SOSAccountCopyiCloudIdentities(alice_account); @@ -209,7 +214,7 @@ static void tests(void) NSMutableDictionary* query = [@{ (id)kSecClass : (id)kSecClassKey, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup: @"com.apple.security.sos", (id)kSecAttrLabel : @"Cloud Identity - piggy", (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, @@ -235,7 +240,7 @@ static void tests(void) //now grab this grom the keychain NSMutableDictionary* query2 = [@{ (id)kSecClass : (id)kSecClassKey, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup: @"com.apple.security.sos", (id)kSecAttrLabel : @"Cloud Identity - piggy", (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, diff --git a/OSX/sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.m b/OSX/sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.m index c526a5dd..c6cb5cc7 100644 --- a/OSX/sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.m +++ b/OSX/sec/securityd/Regressions/secd-61-account-leave-not-in-kansas-anymore.m @@ -28,12 +28,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -51,8 +51,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 116; - /* static void trim_retirements_from_circle(SOSAccount* account) { SOSAccountForEachCircle(account, ^(SOSCircleRef circle) { @@ -182,7 +180,7 @@ static void tests(void) int secd_61_account_leave_not_in_kansas_anymore(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(82); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-62-account-backup.m b/OSX/sec/securityd/Regressions/secd-62-account-backup.m index 2012835c..2875ef20 100644 --- a/OSX/sec/securityd/Regressions/secd-62-account-backup.m +++ b/OSX/sec/securityd/Regressions/secd-62-account-backup.m @@ -30,16 +30,16 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include #include -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" #include #include @@ -53,12 +53,12 @@ #include -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR #include "SOSAccountTesting.h" #endif #include "SecdTestKeychainUtilities.h" -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static CFDataRef CopyBackupKeyForString(CFStringRef string, CFErrorRef *error) { @@ -68,22 +68,17 @@ static CFDataRef CopyBackupKeyForString(CFStringRef string, CFErrorRef *error) }); return result; } - -static int kTestTestCount = 129; -#else -static int kTestTestCount = 1; #endif static void tests(void) { -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR __block CFErrorRef error = NULL; CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10); CFStringRef cfaccount = CFSTR("test@test.org"); - secd_test_setup_testviews(); // for running this test solo - + CFMutableDictionaryRef changes = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); SOSAccount* alice_account = CreateAccountForLocalChanges(CFSTR("Alice"), CFSTR("TestSource")); SOSAccount* bob_account = CreateAccountForLocalChanges(CFSTR("Bob"), CFSTR("TestSource")); @@ -216,12 +211,12 @@ static void tests(void) ok(!SOSAccountIsMyPeerInBackupAndCurrentInView(bob_account, kTestView1), "Bob isn't in the backup yet"); - ok(!SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is not last backup peer - Bob still registers as one"); + ok(!SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is the not the last backup peer - Bob still registers as one"); CFReleaseNull(error); - ok(SOSAccountSetBackupPublicKey_wTxn(bob_account, bob_backup_key, &error), "Set backup public key, alice (%@)", error); + ok(SOSAccountSetBackupPublicKey_wTxn(bob_account, bob_backup_key, &error), "Set backup public key, bob (%@)", error); - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 1, "updates"); + is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates"); ok(!SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is not last backup peer"); CFReleaseNull(error); @@ -231,7 +226,7 @@ static void tests(void) // ok(SOSAccountRemoveBackupPublickey_wTxn(bob_account, &error), "Removing Bob's backup key (%@)", error); - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates"); + is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); ok(!SOSAccountIsMyPeerInBackupAndCurrentInView(bob_account, kTestView1), "Bob's backup key is in the backup - should not be so!"); ok(!SOSAccountIsPeerInBackupAndCurrentInView(alice_account, bobTrust.peerInfo, kTestView1), "Bob is up to date in the backup!"); @@ -240,12 +235,12 @@ static void tests(void) // Setting new backup public key for Bob // - ok(SOSAccountSetBackupPublicKey_wTxn(bob_account, bob_backup_key, &error), "Set backup public key, alice (%@)", error); + ok(SOSAccountSetBackupPublicKey_wTxn(bob_account, bob_backup_key, &error), "Set backup public key, bob (%@)", error); CFReleaseNull(error); - + is([bob_account.trust updateView:bob_account name:kTestView1 code:kSOSCCViewEnable err:&error], kSOSCCViewMember, "Enable view (%@)", error); ok(SOSAccountNewBKSBForView(bob_account, kTestView1, &error), "Setting new backup public key for bob account failed: (%@)", error); - + //bob is in his own backup ok(SOSAccountIsMyPeerInBackupAndCurrentInView(bob_account, kTestView1), "Bob's backup key is not in the backup"); //alice does not have bob in her backup @@ -273,9 +268,14 @@ static void tests(void) int secd_62_account_backup(int argc, char *const *argv) { - plan_tests(kTestTestCount); +#if !TARGET_OS_SIMULATOR + plan_tests(95); +#else + plan_tests(1); +#endif secd_test_setup_temp_keychain(__FUNCTION__, NULL); + secd_test_setup_testviews(); // for running this test solo tests(); diff --git a/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m b/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m index 2291a9a4..c1ccc9ea 100644 --- a/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m +++ b/OSX/sec/securityd/Regressions/secd-63-account-resurrection.m @@ -29,12 +29,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -53,8 +53,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 107; - typedef void (^stir_block)(int expected_iterations); typedef int (^execute_block)(void); @@ -203,7 +201,7 @@ static void tests(void) int secd_63_account_resurrection(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(73); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-64-circlereset.m b/OSX/sec/securityd/Regressions/secd-64-circlereset.m index 79ef5e62..74f8cf9a 100644 --- a/OSX/sec/securityd/Regressions/secd-64-circlereset.m +++ b/OSX/sec/securityd/Regressions/secd-64-circlereset.m @@ -13,12 +13,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -75,8 +75,6 @@ static SOSCircleRef SOSCircleCreateWithGenCount(int64_t gcount) { return c; } -static int kTestTestCount = 45; - static void tests(void) { CFErrorRef error = NULL; @@ -136,7 +134,7 @@ static void tests(void) int secd_64_circlereset(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(35); secd_test_setup_temp_keychain(__FUNCTION__, NULL); 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 ba205e63..520cb8cd 100644 --- a/OSX/sec/securityd/Regressions/secd-65-account-retirement-reset.m +++ b/OSX/sec/securityd/Regressions/secd-65-account-retirement-reset.m @@ -29,12 +29,12 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include #include @@ -53,8 +53,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 43; - typedef void (^stir_block)(int expected_iterations); typedef int (^execute_block)(void); @@ -174,7 +172,7 @@ static void tests(void) int secd_65_account_retirement_reset(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(28); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-66-account-recovery.m b/OSX/sec/securityd/Regressions/secd-66-account-recovery.m index 31c244d3..e8df91f4 100644 --- a/OSX/sec/securityd/Regressions/secd-66-account-recovery.m +++ b/OSX/sec/securityd/Regressions/secd-66-account-recovery.m @@ -39,13 +39,13 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include -#include +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" #include #include @@ -54,7 +54,7 @@ #include "SOSTestDataSource.h" #include "SOSRegressionUtilities.h" -#include "SecRecoveryKey.h" +#include #include #include @@ -62,7 +62,7 @@ #include #include "SecdTestKeychainUtilities.h" -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR int secd_66_account_recovery(int argc, char *const *argv) { plan_tests(1); @@ -104,6 +104,8 @@ static inline bool SOSAccountSOSAccountRemoveRecoveryKey_wTxn(SOSAccount* acct, static void registerRecoveryKeyNow(CFMutableDictionaryRef changes, SOSAccount* registrar, SOSAccount* observer, CFDataRef recoveryPub, bool recKeyFirst) { CFErrorRef error = NULL; + is(ProcessChangesUntilNoChange(changes, registrar, observer, NULL), 1, "updates"); + if(recoveryPub) { ok(SOSAccountSetRecoveryKey_wTxn(registrar, recoveryPub, &error), "Set Recovery Key"); CFReleaseNull(error); @@ -113,9 +115,7 @@ static void registerRecoveryKeyNow(CFMutableDictionaryRef changes, SOSAccount* r } ok(error == NULL, "Error shouldn't be %@", error); CFReleaseNull(error); - int nchanges = (recKeyFirst) ? 3: 5; - nchanges = (recoveryPub) ? nchanges: 5; - is(ProcessChangesUntilNoChange(changes, registrar, observer, NULL), nchanges, "updates"); + ProcessChangesUntilNoChange(changes, registrar, observer, NULL); CFDataRef registrar_recKey = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, registrar, &error); CFReleaseNull(error); @@ -188,6 +188,8 @@ static void tests(bool recKeyFirst) ok([alice_account.trust checkForRings:&error], "Alice_account is good"); CFReleaseNull(error); + + ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL); is([bob_account.trust updateView:bob_account name:kTestView1 code:kSOSCCViewEnable err:&error], kSOSCCViewMember, "Enable view (%@)", error); CFReleaseNull(error); @@ -246,14 +248,14 @@ static void tests(bool recKeyFirst) //Alice should kick Bob out of the backup! is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 2, "updates"); - ok(SOSAccountIsMyPeerInBackupAndCurrentInView(alice_account, kTestView1), "Bob left the circle, Alice is not in the backup"); + ok(SOSAccountIsMyPeerInBackupAndCurrentInView(alice_account, kTestView1), "Bob left the circle, Alice is in the backup"); ok(SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is last backup peer"); CFReleaseNull(error); ok(!SOSAccountIsLastBackupPeer(bob_account, &error), "Bob is not last backup peer"); CFReleaseNull(error); - ok(testAccountPersistence(alice_account), "Test Account->DER->Account Equivalence"); + //ok(testAccountPersistence(alice_account), "Test Account->DER->Account Equivalence"); SOSAccountTrustClassic* bobTrust = bob_account.trust; ok(!SOSAccountIsPeerInBackupAndCurrentInView(alice_account, bobTrust.peerInfo, kTestView1), "Bob is still in the backup!"); @@ -266,12 +268,12 @@ static void tests(bool recKeyFirst) ok(!SOSAccountIsMyPeerInBackupAndCurrentInView(bob_account, kTestView1), "Bob isn't in the backup yet"); - ok(!SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is not last backup peer - Bob still registers as one"); + ok(!SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is the not the last backup peer - Bob still registers as one"); CFReleaseNull(error); ok(SOSAccountSetBackupPublicKey_wTxn(bob_account, bob_backup_key, &error), "Set backup public key, alice (%@)", error); - is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 1, "updates"); + is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), 3, "updates"); ok(!SOSAccountIsLastBackupPeer(alice_account, &error), "Alice is not last backup peer"); CFReleaseNull(error); @@ -281,7 +283,7 @@ static void tests(bool recKeyFirst) // ok(SOSAccountRemoveBackupPublickey_wTxn(bob_account, &error), "Removing Bob's backup key (%@)", error); - int nchanges = (recKeyFirst) ? 4: 3; + int nchanges = (recKeyFirst) ? 2: 2; is(ProcessChangesUntilNoChange(changes, alice_account, bob_account, NULL), nchanges, "updates"); ok(!SOSAccountIsMyPeerInBackupAndCurrentInView(bob_account, kTestView1), "Bob's backup key is in the backup - should not be so!"); @@ -332,7 +334,7 @@ static void tests(bool recKeyFirst) ok(!SOSAccountRecoveryKeyIsInBackupAndCurrentInView(alice_account, kTestView1), "Recovery Key is not in the backup"); ok(!SOSAccountRecoveryKeyIsInBackupAndCurrentInView(bob_account, kTestView1), "Recovery Key is not in the backup"); - + bskb = SOSAccountBackupSliceKeyBagForView(alice_account, kTestView1, &error); CFReleaseNull(error); @@ -360,7 +362,7 @@ static void tests(bool recKeyFirst) } int secd_66_account_recovery(int argc, char *const *argv) { - plan_tests(396); + plan_tests(278); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-668-ghosts.m b/OSX/sec/securityd/Regressions/secd-668-ghosts.m index 95313c2e..957c30ae 100644 --- a/OSX/sec/securityd/Regressions/secd-668-ghosts.m +++ b/OSX/sec/securityd/Regressions/secd-668-ghosts.m @@ -29,8 +29,8 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #include "secd_regressions.h" #include "SOSAccountTesting.h" @@ -45,6 +45,7 @@ For phase 1 we expect the ghostfix to work with iOS devices, but not with MacOSX devices. */ +#if 0 static void hauntedCircle(SOSPeerInfoDeviceClass devClass, bool expectGhostBusted) { CFErrorRef error = NULL; @@ -195,13 +196,16 @@ static void iosICloudIdentity() { alice_account = nil; SOSTestCleanup(); } +#endif // 0 int secd_68_ghosts(int argc, char *const *argv) { - plan_tests(573); + plan_tests(1); secd_test_setup_temp_keychain(__FUNCTION__, NULL); - + +#if 0 + // changing ghostbusting. handleUpdateCircle version is going away. hauntedCircle(SOSPeerInfo_iOS, true); hauntedCircle(SOSPeerInfo_macOS, false); multiBob(SOSPeerInfo_iOS, true, false, false); @@ -209,6 +213,6 @@ int secd_68_ghosts(int argc, char *const *argv) multiBob(SOSPeerInfo_iOS, false, false, true); // piggyback join case iosICloudIdentity(); - +#endif return 0; } diff --git a/OSX/sec/securityd/Regressions/secd-70-engine-corrupt.m b/OSX/sec/securityd/Regressions/secd-70-engine-corrupt.m index 9e57d6c2..cf7fba71 100644 --- a/OSX/sec/securityd/Regressions/secd-70-engine-corrupt.m +++ b/OSX/sec/securityd/Regressions/secd-70-engine-corrupt.m @@ -24,15 +24,15 @@ // Test syncing between SecItemDataSource and SOSTestDataSource -#include -#include +#include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h" +#include "keychain/SecureObjectSync/Regressions/SOSTestDataSource.h" #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#import "keychain/SecureObjectSync/SOSChangeTracker.h" #include #include #include diff --git a/OSX/sec/securityd/Regressions/secd-70-engine-smash.m b/OSX/sec/securityd/Regressions/secd-70-engine-smash.m index 2afaae93..62be20d5 100644 --- a/OSX/sec/securityd/Regressions/secd-70-engine-smash.m +++ b/OSX/sec/securityd/Regressions/secd-70-engine-smash.m @@ -22,7 +22,7 @@ */ -#include +#include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h" #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" diff --git a/OSX/sec/securityd/Regressions/secd-70-engine.m b/OSX/sec/securityd/Regressions/secd-70-engine.m index ac7aa29d..eba7cb04 100644 --- a/OSX/sec/securityd/Regressions/secd-70-engine.m +++ b/OSX/sec/securityd/Regressions/secd-70-engine.m @@ -24,13 +24,13 @@ // Test syncing between SecItemDataSource and SOSTestDataSource -#include -#include +#include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h" +#include "keychain/SecureObjectSync/Regressions/SOSTestDataSource.h" #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" -#include -#include +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #include #include #include @@ -44,8 +44,6 @@ #include #include -static int kTestTestCount = 2478; - __unused static bool SOSCircleHandleCircleWithLock(SOSEngineRef engine, CFStringRef myID, CFDataRef message, CFErrorRef *error) { CFMutableArrayRef trustedPeers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); @@ -303,7 +301,7 @@ SKIP: SecKeychainDbReset(NULL); #else - skip("Keychain not reset", kTestTestCount, false); + skip("Keychain not reset", 0, false); #endif testsync3("secd_70_engine3", test_directive, test_reason); @@ -508,7 +506,7 @@ SKIP: int secd_70_engine(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(1172); /* custom keychain dir */ secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd-70-otr-remote.m b/OSX/sec/securityd/Regressions/secd-70-otr-remote.m index 7da445b5..88735ab4 100644 --- a/OSX/sec/securityd/Regressions/secd-70-otr-remote.m +++ b/OSX/sec/securityd/Regressions/secd-70-otr-remote.m @@ -34,11 +34,11 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include "SOSCircle_regressions.h" #include "SOSRegressionUtilities.h" diff --git a/OSX/sec/securityd/Regressions/secd-71-engine-save.m b/OSX/sec/securityd/Regressions/secd-71-engine-save.m index 2266ae2d..1de658be 100644 --- a/OSX/sec/securityd/Regressions/secd-71-engine-save.m +++ b/OSX/sec/securityd/Regressions/secd-71-engine-save.m @@ -24,13 +24,13 @@ // Test save and restore of SOSEngine states -#include -#include +#include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h" +#include "keychain/SecureObjectSync/Regressions/SOSTestDataSource.h" #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" -#include -#include +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #include #include #include diff --git a/OSX/sec/securityd/Regressions/secd-74-engine-beer-servers.m b/OSX/sec/securityd/Regressions/secd-74-engine-beer-servers.m index 73ba369b..d814afdf 100644 --- a/OSX/sec/securityd/Regressions/secd-74-engine-beer-servers.m +++ b/OSX/sec/securityd/Regressions/secd-74-engine-beer-servers.m @@ -22,7 +22,7 @@ */ -#include +#include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h" #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" diff --git a/OSX/sec/securityd/Regressions/secd-75-engine-views.m b/OSX/sec/securityd/Regressions/secd-75-engine-views.m index 91143fd3..6e65d3c3 100644 --- a/OSX/sec/securityd/Regressions/secd-75-engine-views.m +++ b/OSX/sec/securityd/Regressions/secd-75-engine-views.m @@ -22,11 +22,11 @@ */ -#include +#include "keychain/SecureObjectSync/Regressions/SOSTestDevice.h" #include "secd_regressions.h" #include "SecdTestKeychainUtilities.h" #include -#include +#include "keychain/SecureObjectSync/SOSPeer.h" static int kTestTestCount = 53; diff --git a/OSX/sec/securityd/Regressions/secd-80-views-alwayson.m b/OSX/sec/securityd/Regressions/secd-80-views-alwayson.m index 2d8337b4..57bc8d44 100644 --- a/OSX/sec/securityd/Regressions/secd-80-views-alwayson.m +++ b/OSX/sec/securityd/Regressions/secd-80-views-alwayson.m @@ -32,7 +32,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include "secd_regressions.h" #include "SOSAccountTesting.h" @@ -82,10 +82,10 @@ static void alwaysOnTest() CFReleaseNull(cfpassword); testView(alice_account, kSOSCCViewMember, kSOSViewContinuityUnlock, kSOSCCViewQuery, "Expected view capability for kSOSViewContinuityUnlock"); - testView(alice_account, kSOSCCViewNotMember, kSOSViewContinuityUnlock, kSOSCCViewDisable, "Expected to disable kSOSViewContinuityUnlock"); + testView(alice_account, kSOSCCViewMember, kSOSViewContinuityUnlock, kSOSCCViewDisable, "Not expected to disable kSOSViewContinuityUnlock - it's always-on"); ok(SOSAccountAssertUserCredentialsAndUpdate(bob_account, cfaccount, cfpasswordNew, NULL), "Bob changes the password"); - testView(alice_account, kSOSCCViewNotMember, kSOSViewContinuityUnlock, kSOSCCViewQuery, "Expected kSOSViewContinuityUnlock is off for alice still"); + testView(alice_account, kSOSCCViewMember, kSOSViewContinuityUnlock, kSOSCCViewQuery, "Expected kSOSViewContinuityUnlock is on for alice still"); ok(SOSAccountAssertUserCredentialsAndUpdate(alice_account, cfaccount, cfpasswordNew, NULL), "Alice sets the new password"); CFReleaseNull(cfpasswordNew); testView(alice_account, kSOSCCViewMember, kSOSViewContinuityUnlock, kSOSCCViewQuery, "Expected view capability for kSOSViewContinuityUnlock"); @@ -97,8 +97,8 @@ static void alwaysOnTest() int secd_80_views_alwayson(int argc, char *const *argv) { - plan_tests(44); - + plan_tests(35); + secd_test_clear_testviews(); secd_test_setup_temp_keychain(__FUNCTION__, NULL); alwaysOnTest(); return 0; diff --git a/OSX/sec/securityd/Regressions/secd-80-views-basic.m b/OSX/sec/securityd/Regressions/secd-80-views-basic.m index f81f7fba..b628d575 100644 --- a/OSX/sec/securityd/Regressions/secd-80-views-basic.m +++ b/OSX/sec/securityd/Regressions/secd-80-views-basic.m @@ -35,11 +35,11 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include #include @@ -84,7 +84,7 @@ static void testViewLists(void) { is(CFSetGetCount(allViews), 24, "make sure count of allViews is correct"); is(CFSetGetCount(defaultViews), 20, "make sure count of defaultViews is correct"); - is(CFSetGetCount(initialViews), 14, "make sure count of initialViews is correct"); + is(CFSetGetCount(initialViews), 0, "make sure count of initialViews is correct"); is(CFSetGetCount(alwaysOnViews), 20, "make sure count of alwaysOnViews is correct"); is(CFSetGetCount(backupRequiredViews), 3, "make sure count of backupRequiredViews is correct"); is(CFSetGetCount(V0Views), 6, "make sure count of V0Views is correct"); @@ -130,8 +130,8 @@ static void tests(void) testView(account, kSOSCCViewMember, kSOSViewPCSiCloudDrive, kSOSCCViewEnable, "Expected to enable kSOSViewPCSiCloudDrive"); testView(account, kSOSCCViewMember, kSOSViewPCSiCloudDrive, kSOSCCViewQuery, "Expected view capability for kSOSViewPCSiCloudDrive"); - testView(account, kSOSCCViewNotMember, kSOSViewPCSiCloudDrive, kSOSCCViewDisable, "Expected to disable kSOSViewPCSiCloudDrive"); - testView(account, kSOSCCViewNotMember, kSOSViewPCSiCloudDrive, kSOSCCViewQuery, "Expected no view capability for kSOSViewPCSiCloudDrive"); + testView(account, kSOSCCViewMember, kSOSViewPCSiCloudDrive, kSOSCCViewDisable, "Expected cannot disable kSOSViewPCSiCloudDrive"); + testView(account, kSOSCCViewMember, kSOSViewPCSiCloudDrive, kSOSCCViewQuery, "Expected view capability for kSOSViewPCSiCloudDrive"); testView(account, kSOSCCViewMember, kSOSViewPCSiCloudDrive, kSOSCCViewEnable, "Expected to enable kSOSViewPCSiCloudDrive"); testView(account, kSOSCCViewMember, kSOSViewPCSiCloudDrive, kSOSCCViewQuery, "Expected view capability for kSOSViewPCSiCloudDrive"); @@ -143,10 +143,10 @@ static void tests(void) testView(account, kSOSCCViewNotMember, kSOSViewKeychainV0, kSOSCCViewQuery, "Expected view capability for kSOSViewKeychainV0"); testView(account, kSOSCCViewMember, kSOSViewAppleTV, kSOSCCViewQuery, "Expected view capability for kSOSViewAppleTV"); - ok([account.trust updateViewSets:account enabled:SOSViewsGetV0ViewSet() disabled:nullSet], "Expect not accepting kSOSKeychainV0"); + ok([account.trust updateViewSetsWithAnalytics:account enabled:SOSViewsGetV0ViewSet() disabled:nullSet parentEvent: NULL], "Expect not accepting kSOSKeychainV0"); testView(account, kSOSCCViewNotMember, kSOSViewKeychainV0, kSOSCCViewQuery, "Expected no addition of kSOSKeychainV0"); - ok([account.trust updateViewSets:account enabled:SOSViewsGetV0ViewSet() disabled:nullSet], "Expect not accepting kSOSKeychainV0"); + ok([account.trust updateViewSetsWithAnalytics:account enabled:SOSViewsGetV0ViewSet() disabled:nullSet parentEvent: NULL], "Expect not accepting kSOSKeychainV0"); testView(account, kSOSCCViewNotMember, kSOSViewKeychainV0, kSOSCCViewQuery, "Expected no addition of kSOSKeychainV0"); SOSPeerInfoRef pi = account.peerInfo; @@ -155,10 +155,10 @@ static void tests(void) ok(vr == kSOSCCViewMember, "Set Virtual View manually"); - ok(![account.trust updateViewSets:account enabled:nullSet disabled:SOSViewsGetV0ViewSet()], "Expect not removing kSOSKeychainV0"); + ok(![account.trust updateViewSetsWithAnalytics:account enabled:nullSet disabled:SOSViewsGetV0ViewSet() parentEvent: NULL], "Expect not removing kSOSKeychainV0"); testView(account, kSOSCCViewMember, kSOSViewKeychainV0, kSOSCCViewQuery, "Expected kSOSKeychainV0 is still there"); - ok(![account.trust updateViewSets:account enabled:nullSet disabled:SOSViewsGetV0ViewSet()], "Expect not removing kSOSKeychainV0"); + ok(![account.trust updateViewSetsWithAnalytics:account enabled:nullSet disabled:SOSViewsGetV0ViewSet() parentEvent: NULL], "Expect not removing kSOSKeychainV0"); testView(account, kSOSCCViewMember, kSOSViewKeychainV0, kSOSCCViewQuery, "Expected kSOSKeychainV0 is still there"); SOSDataSourceRelease(test_source, NULL); @@ -172,7 +172,7 @@ int secd_80_views_basic(int argc, char *const *argv) plan_tests(kTestTestCount); secd_test_setup_temp_keychain(__FUNCTION__, NULL); - + secd_test_clear_testviews(); testViewLists(); tests(); diff --git a/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m b/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m index 921af46b..b5c60442 100644 --- a/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m +++ b/OSX/sec/securityd/Regressions/secd-81-item-acl-stress.m @@ -28,7 +28,7 @@ #if USE_KEYSTORE #include #include "SecdTestKeychainUtilities.h" -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include #endif @@ -343,8 +343,8 @@ int secd_81_item_acl_stress(int argc, char *const *argv) keybag_state_t state; int passcode_len=(int)strlen(passcode); - ok(kIOReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &test_keybag), "create keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(test_keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_create_bag(passcode, passcode_len, kAppleKeyStoreDeviceBag, &test_keybag), "create keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(test_keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); SecItemServerSetKeychainKeybag(test_keybag); }); diff --git a/OSX/sec/securityd/Regressions/secd-81-item-acl.m b/OSX/sec/securityd/Regressions/secd-81-item-acl.m index 4db56a5c..c51a8aed 100644 --- a/OSX/sec/securityd/Regressions/secd-81-item-acl.m +++ b/OSX/sec/securityd/Regressions/secd-81-item-acl.m @@ -29,9 +29,8 @@ #include #include #include "SecdTestKeychainUtilities.h" -#if TARGET_OS_IPHONE -#include -#endif + +#include "OSX/utilities/SecAKSWrappers.h" #if LA_CONTEXT_IMPLEMENTED static keybag_handle_t test_keybag; @@ -474,8 +473,8 @@ int secd_81_item_acl(int argc, char *const *argv) keybag_state_t state; int passcode_len=(int)strlen(passcode1); - ok(kIOReturnSuccess==aks_create_bag(passcode1, passcode_len, kAppleKeyStoreDeviceBag, &test_keybag), "create keybag"); - ok(kIOReturnSuccess==aks_get_lock_state(test_keybag, &state), "get keybag state"); + ok(kAKSReturnSuccess==aks_create_bag(passcode1, passcode_len, kAppleKeyStoreDeviceBag, &test_keybag), "create keybag"); + ok(kAKSReturnSuccess==aks_get_lock_state(test_keybag, &state), "get keybag state"); ok(!(state&keybag_state_locked), "keybag unlocked"); SecItemServerSetKeychainKeybag(test_keybag); }); diff --git a/OSX/sec/securityd/Regressions/secd-95-escrow-persistence.m b/OSX/sec/securityd/Regressions/secd-95-escrow-persistence.m index 17167bd7..c2d4cdda 100644 --- a/OSX/sec/securityd/Regressions/secd-95-escrow-persistence.m +++ b/OSX/sec/securityd/Regressions/secd-95-escrow-persistence.m @@ -27,11 +27,11 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include #include @@ -168,7 +168,7 @@ static void tests(void) int secd_95_escrow_persistence(int argc, char *const *argv) { - plan_tests(63); + plan_tests(41); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m b/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m index ca6f7fd9..0eca1b36 100644 --- a/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m +++ b/OSX/sec/securityd/Regressions/secd60-account-cloud-exposure.m @@ -33,14 +33,14 @@ #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" #include #include @@ -58,8 +58,6 @@ #include "SecdTestKeychainUtilities.h" -static int kTestTestCount = 56; - static bool SOSAccountResetCircleToNastyOffering(SOSAccount* account, SecKeyRef userPriv, SOSPeerInfoRef pi, CFErrorRef *error) { bool result = false; SecKeyRef userPub = SecKeyCreatePublicFromPrivate(userPriv); @@ -224,7 +222,7 @@ static void tests(void) int secd_60_account_cloud_exposure(int argc, char *const *argv) { - plan_tests(kTestTestCount); + plan_tests(41); secd_test_setup_temp_keychain(__FUNCTION__, NULL); diff --git a/OSX/sec/securityd/Regressions/secd_regressions.h b/OSX/sec/securityd/Regressions/secd_regressions.h index fb52b6d0..d3de4a06 100644 --- a/OSX/sec/securityd/Regressions/secd_regressions.h +++ b/OSX/sec/securityd/Regressions/secd_regressions.h @@ -23,6 +23,7 @@ #include +#include "OSX/sec/Security/SecItemShim.h" ONE_TEST(secd_01_items) ONE_TEST(secd_02_upgrade_while_locked) @@ -32,10 +33,10 @@ ONE_TEST(secd_05_corrupted_items) ONE_TEST(secd_20_keychain_upgrade) ONE_TEST(secd_21_transmogrify) DISABLED_ONE_TEST(secd_30_keychain_upgrade) //obsolete, needs updating -ONE_TEST(secd_31_keychain_bad) DISABLED_ONE_TEST(secd_31_keychain_unreadable) OFF_ONE_TEST(secd_32_restore_bad_backup) ONE_TEST(secd_33_keychain_ctk) +ONE_TEST(secd_33_keychain_backup) ONE_TEST(secd_35_keychain_migrate_inet) ONE_TEST(secd_36_ks_encrypt) ONE_TEST(secd_37_pairing_initial_sync) @@ -46,7 +47,7 @@ ONE_TEST(secd_50_message) ONE_TEST(secd_51_account_inflate) ONE_TEST(secd_52_account_changed) ONE_TEST(secd_52_offering_gencount_reset) -ONE_TEST(secd_55_account_circle) +DISABLED_ONE_TEST(secd_55_account_circle) ONE_TEST(secd_55_account_incompatibility) ONE_TEST(secd_56_account_apply) ONE_TEST(secd_57_account_leave) @@ -95,4 +96,7 @@ ONE_TEST(secd_201_coders) ONE_TEST(secd_202_recoverykey) ONE_TEST(secd_210_keyinterest) DISABLED_ONE_TEST(secd_230_keybagtable) +#if TARGET_OS_OSX +ONE_TEST(sc_25_soskeygen) +#endif diff --git a/OSX/sec/securityd/SFKeychainControlManager.m b/OSX/sec/securityd/SFKeychainControlManager.m index ede2edda..89e1ae5c 100644 --- a/OSX/sec/securityd/SFKeychainControlManager.m +++ b/OSX/sec/securityd/SFKeychainControlManager.m @@ -92,7 +92,7 @@ XPC_RETURNS_RETAINED xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void) CFTypeRef genericPasswords = NULL; NSDictionary* genericPasswordsQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecReturnPersistentRef : @(YES), - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecMatchLimit : (id)kSecMatchLimitAll }; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordsQuery, &genericPasswords); CFErrorRef genericPasswordError = NULL; @@ -106,7 +106,7 @@ XPC_RETURNS_RETAINED xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void) CFTypeRef internetPasswords = NULL; NSDictionary* internetPasswordsQuery = @{ (id)kSecClass : (id)kSecClassInternetPassword, (id)kSecReturnPersistentRef : @(YES), - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecMatchLimit : (id)kSecMatchLimitAll }; status = SecItemCopyMatching((__bridge CFDictionaryRef)internetPasswordsQuery, &internetPasswords); CFErrorRef internetPasswordError = NULL; @@ -120,7 +120,7 @@ XPC_RETURNS_RETAINED xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void) CFTypeRef keys = NULL; NSDictionary* keysQuery = @{ (id)kSecClass : (id)kSecClassKey, (id)kSecReturnPersistentRef : @(YES), - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecMatchLimit : (id)kSecMatchLimitAll }; status = SecItemCopyMatching((__bridge CFDictionaryRef)keysQuery, &keys); CFErrorRef keyError = NULL; @@ -133,7 +133,7 @@ XPC_RETURNS_RETAINED xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void) CFTypeRef certificates = NULL; NSDictionary* certificateQuery = @{ (id)kSecClass : (id)kSecClassCertificate, (id)kSecReturnPersistentRef : @(YES), - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecMatchLimit : (id)kSecMatchLimitAll }; status = SecItemCopyMatching((__bridge CFDictionaryRef)certificateQuery, &certificates); CFErrorRef certificateError = NULL; @@ -151,7 +151,7 @@ XPC_RETURNS_RETAINED xpc_endpoint_t SecServerCreateKeychainControlEndpoint(void) NSDictionary* itemQuery = @{ (id)kSecClass : class, (id)kSecValuePersistentRef : persistentRef, (id)kSecReturnAttributes : @(YES), - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; CFTypeRef itemAttributes = NULL; OSStatus copyStatus = SecItemCopyMatching((__bridge CFDictionaryRef)itemQuery, &itemAttributes); if (copyStatus != errSecSuccess && status != errSecInteractionNotAllowed) { diff --git a/OSX/sec/securityd/SFKeychainServer.m b/OSX/sec/securityd/SFKeychainServer.m index ca6bc37b..fb9c07b2 100644 --- a/OSX/sec/securityd/SFKeychainServer.m +++ b/OSX/sec/securityd/SFKeychainServer.m @@ -257,12 +257,12 @@ static NSString* const SFCredentialSecretPassword = @"password"; 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) { + [_keychain insertItems:@[item] withConnection:self completionHandler:^(bool success, NSError* insertError) { + if (success && !insertError) { reply(persistentID.UUIDString, nil); } else { - reply(nil, error); + reply(nil, insertError); } }]; } diff --git a/OSX/sec/securityd/SOSCloudCircleServer.h b/OSX/sec/securityd/SOSCloudCircleServer.h index 5d49f88f..581c87b0 100644 --- a/OSX/sec/securityd/SOSCloudCircleServer.h +++ b/OSX/sec/securityd/SOSCloudCircleServer.h @@ -26,7 +26,7 @@ #define _SECURITY_SOSCLOUDCIRCLESERVER_H_ #import -#import +#include "keychain/SecureObjectSync/SOSRing.h" #import #import @@ -61,7 +61,7 @@ bool SOSCCRequestEnsureFreshParameters_Server(CFErrorRef* error); bool SOSCCApplyToARing_Server(CFStringRef ringName, CFErrorRef *error); bool SOSCCWithdrawlFromARing_Server(CFStringRef ringName, CFErrorRef *error); SOSRingStatus SOSCCRingStatus_Server(CFStringRef ringName, CFErrorRef *error); -CFStringRef SOSCCGetAllTheRings_Server(CFErrorRef *error); +CF_RETURNS_RETAINED CFStringRef SOSCCGetAllTheRings_Server(CFErrorRef *error); bool SOSCCEnableRing_Server(CFStringRef ringName, CFErrorRef *error); @@ -92,7 +92,7 @@ CFBooleanRef SOSCCPeersHaveViewsEnabled_Server(CFArrayRef viewNames, CFErrorRef 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); +bool SOSCCViewSet_Server(CFSetRef enabledViews, CFSetRef disabledViews); CFStringRef SOSCCCopyIncompatibilityInfo_Server(CFErrorRef* error); enum DepartureReason SOSCCGetLastDepartureReason_Server(CFErrorRef* error); @@ -195,6 +195,10 @@ void SOSCCPerformWithOctagonEncryptionPublicKey(void (^action)(SecKeyRef octagon void SOSCCPerformWithAllOctagonKeys(void (^action)(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef error)); void SOSCCPerformWithTrustedPeers(void (^action)(CFSetRef sosPeerInfoRefs, CFErrorRef error)); void SOSCCPerformWithPeerID(void (^action)(CFStringRef peerID, CFErrorRef error)); +void SOSCCPerformUpdateOfAllOctagonKeys(CFDataRef octagonSigningFullKey, CFDataRef octagonEncryptionFullKey, + CFDataRef signingPublicKey, CFDataRef encryptionPublicKey, + SecKeyRef octagonSigningPublicKeyRef, SecKeyRef octagonEncryptionPublicKeyRef, + void (^action)(CFErrorRef error)); void SOSCCResetOTRNegotiation_Server(CFStringRef peerid); void SOSCCPeerRateLimiterSendNextMessage_Server(CFStringRef peerid, CFStringRef accessGroup); diff --git a/OSX/sec/securityd/SOSCloudCircleServer.m b/OSX/sec/securityd/SOSCloudCircleServer.m index ffed641f..dafc9991 100644 --- a/OSX/sec/securityd/SOSCloudCircleServer.m +++ b/OSX/sec/securityd/SOSCloudCircleServer.m @@ -26,31 +26,34 @@ #include #include -#include +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" #include #include #include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#import -#import -#import -#import +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSAccountGhost.h" + +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSMessage.h" +#include "keychain/SecureObjectSync/SOSBackupInformation.h" +#include "keychain/SecureObjectSync/SOSDataSource.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAuthKitHelpers.h" +#import "keychain/ot/OTManager.h" +#import "NSError+UsefulConstructors.h" #include #include @@ -61,7 +64,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include #include @@ -84,9 +87,11 @@ #include #include +#include + #include -#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE #include #else #include @@ -108,6 +113,8 @@ typedef SOSDataSourceFactoryRef (^SOSCCAccountDataSourceFactoryBlock)(void); static SOSCCAccountDataSourceFactoryBlock accountDataSourceOverride = NULL; + + // // Forward declared // @@ -302,7 +309,7 @@ static CFStringRef CopyModelName(void) static dispatch_once_t once; dispatch_once(&once, ^{ if (SOSGestaltModel == NULL) { -#if TARGET_OS_EMBEDDED || TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE SOSGestaltModel = MGCopyAnswer(kMGQDeviceName, NULL); #else SOSGestaltModel = ASI_CopyComputerModelName(FALSE); @@ -436,18 +443,23 @@ errOut: return retval; }; +#define FOR_EXISTING_ACCOUNT 1 +#define CREATE_ACCOUNT_IF_NONE 0 - -static SOSAccount* GetSharedAccount(void) { +static SOSAccount* GetSharedAccount(bool onlyIfItExists) { static SOSAccount* sSharedAccount = NULL; static dispatch_once_t onceToken; -#if !(TARGET_OS_EMBEDDED) +#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR if(geteuid() == 0){ secerror("Cannot inflate account object as root"); return NULL; } #endif + + if(onlyIfItExists) { + return sSharedAccount; + } dispatch_once(&onceToken, ^{ secdebug("account", "Account Creation start"); @@ -455,7 +467,7 @@ static SOSAccount* GetSharedAccount(void) { CFDictionaryRef gestalt = CreateDeviceGestaltDictionaryAndRegisterForUpdate(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), NULL); if (!gestalt) { -#if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR gestalt = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, NULL); #else secerror("Didn't get machine gestalt! This is going to be ugly."); @@ -556,20 +568,21 @@ static SOSAccount* GetSharedAccount(void) { // provide state handler to sysdiagnose and logging os_state_add_handler(dispatch_get_global_queue(0, 0), accountStateBlock); + [sSharedAccount ghostBustSchedule]; + }); - return sSharedAccount; } CFTypeRef GetSharedAccountRef(void) { - return (__bridge CFTypeRef)GetSharedAccount(); + return (__bridge CFTypeRef)GetSharedAccount(FOR_EXISTING_ACCOUNT); } static void do_with_account(void (^action)(SOSAccountTransaction* txn)) { @autoreleasepool { - SOSAccount* account = GetSharedAccount(); + SOSAccount* account = GetSharedAccount(CREATE_ACCOUNT_IF_NONE); if(account){ [account performTransaction:^(SOSAccountTransaction * _Nonnull txn) { @@ -580,7 +593,7 @@ static void do_with_account(void (^action)(SOSAccountTransaction* txn)) { } static bool isValidUser(CFErrorRef* error) { -#if !(TARGET_OS_EMBEDDED) +#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR if(geteuid() == 0){ secerror("Cannot inflate account object as root"); SOSErrorCreate(kSOSErrorUnsupported, error, NULL, CFSTR("Cannot inflate account object as root")); @@ -593,7 +606,7 @@ static bool isValidUser(CFErrorRef* error) { static bool do_if_after_first_unlock(CFErrorRef *error, dispatch_block_t action) { -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR action(); return true; #else @@ -615,30 +628,11 @@ fail: static bool do_with_account_if_after_first_unlock(CFErrorRef *error, bool (^action)(SOSAccountTransaction* txn, CFErrorRef* error)) { - static dispatch_once_t initialNotificationToken; __block bool action_result = false; return isValidUser(error) && do_if_after_first_unlock(error, ^{ do_with_account(^(SOSAccountTransaction* txn) { action_result = action(txn, error); - - // The first time we run do_with_account_if_after_first_unlock and the bag is unlocked, - // if we are now 'in circle', notify our listeners of a 'circle change' and a 'view change'. - // This will prompt them to refetch circle status, and we can actually respond correctly now! - // If we are out of circle, don't send the notification--all clients 'know' we're out of circle anyway. - dispatch_once(&initialNotificationToken, ^{ - CFErrorRef cferror = NULL; - - SOSCCStatus status = [txn.account getCircleStatus:&cferror]; - if(cferror) { - 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"); - txn.account.notifyCircleChangeOnExit = true; - txn.account.notifyViewChangeOnExit = true; - } - CFReleaseNull(cferror); - }); }); }) && action_result; @@ -669,21 +663,51 @@ static bool do_with_account_while_unlocked(CFErrorRef *error, bool (^action)(SOS return result; } - result = SecAKSDoWhileUserBagLocked(&localError, ^{ + result = SecAKSDoWithUserBagLockAssertion(&localError, ^{ + // SOSAccountGhostBustingOptions need to be retrieved from RAMP while not holding the account queue + // yet we only want to request RAMP info if it's "time" to ghostbust. + +#if GHOSTBUST_PERIODIC && (TARGET_OS_IOS || TARGET_OS_OSX) + __block bool ghostbustnow = false; + __block SOSAccountGhostBustingOptions gbOptions = 0; + + // Avoid mutual deadlock for just checking date. + SOSAccount *tmpAccount = GetSharedAccount(FOR_EXISTING_ACCOUNT); + if(tmpAccount && [tmpAccount isInCircle:(NULL)]) { + if(tmpAccount.settings) { + ghostbustnow = [tmpAccount ghostBustCheckDate]; + } + + if(ghostbustnow) { + gbOptions = [SOSAccount ghostBustGetRampSettings]; + } + } + +#endif + do_with_account(^(SOSAccountTransaction* txn) { SOSAccount *account = txn.account; - if([account isInCircle: NULL]) { + if ([account isInCircle:(NULL)] && [SOSAuthKitHelpers accountIsHSA2]) { if(![SOSAuthKitHelpers peerinfoHasMID: account]) { // This is the first good opportunity to update our FullPeerInfo and // push the resulting circle. [SOSAuthKitHelpers updateMIDInPeerInfo: account]; } } +#if GHOSTBUST_PERIODIC && (TARGET_OS_IOS || TARGET_OS_OSX) + if(ghostbustnow) { + [account ghostBustPeriodic:gbOptions complete:^(bool ghostBusted, NSError *error) { + secnotice("ghostbust", "GhostBusting: %@", ghostBusted ? CFSTR("true"): CFSTR("false")); + }]; + } +#endif attempted_action = true; action_result = action(txn, error); }); }); + + // For 13E196: Circle join fails after successful recovery with a mach error if performed while device is locked // If we fail with an error attempting to get an assertion while someone else has one and the system is unlocked, it must be trying to lock. // we assume our caller will hold the lock assertion for us to finsh our job. @@ -746,18 +770,11 @@ static bool do_with_account_while_unlocked(CFErrorRef *error, bool (^action)(SOS CFTypeRef SOSKeychainAccountGetSharedAccount() { __block SOSAccount* result = NULL; - CFErrorRef localError = NULL; - - bool success = do_with_account_if_after_first_unlock(&localError, ^bool (SOSAccountTransaction* txn, CFErrorRef *error) { - result = txn.account; - return true; - }); + result = GetSharedAccount(FOR_EXISTING_ACCOUNT); - if(!success) { - secnotice("secAccount", "Failed request for account object (%@)", localError); - CFReleaseNull(localError); + if(!result) { + secnotice("secAccount", "Failed request for account object"); } - return (__bridge CFTypeRef)result; } @@ -765,16 +782,6 @@ CFTypeRef SOSKeychainAccountGetSharedAccount() // Mark: Credential processing // -bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { - secnotice("updates", "Trying credentials and dsid (%@) for %@", dsid, user_label); - - return do_with_account_if_after_first_unlock(error, ^bool (SOSAccountTransaction* txn, CFErrorRef* block_error) { - if (dsid != NULL && CFStringCompare(dsid, CFSTR(""), 0) != 0) { - SOSAccountAssertDSID(txn.account, dsid); - } - return SOSAccountTryUserCredentials(txn.account, user_label, user_password, block_error); - }); -} SOSViewResultCode SOSCCView_Server(CFStringRef viewname, SOSViewActionCode action, CFErrorRef *error) { __block SOSViewResultCode status = kSOSCCGeneralViewError; @@ -816,14 +823,9 @@ bool SOSCCViewSetWithAnalytics_Server(CFSetRef enabledViews, CFSetRef disabledVi return status; } + bool SOSCCViewSet_Server(CFSetRef enabledViews, CFSetRef disabledViews) { - __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]; - return true; - }); - return status; + return SOSCCViewSetWithAnalytics_Server(enabledViews, disabledViews, NULL); } @@ -902,6 +904,32 @@ static bool Flush(CFErrorRef *error) { return success; } +bool SOSCCTryUserCredentials_Server(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { + secnotice("updates", "Trying credentials and dsid (%@) for %@", dsid, user_label); + + 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); + + require_quiet(SyncKVSAndWait(error), done); // Make sure we've seen what the server has + require_quiet(Flush(error), done); // And processed it already...before asserting + + result = do_with_account_while_unlocked(error, ^bool(SOSAccountTransaction* txn, CFErrorRef *block_error) { + return SOSAccountTryUserCredentials(txn.account, user_label, user_password, block_error); + }); + + require_quiet(result, done); + require_quiet(Flush(error), done); + +done: + return result; +} + static bool SOSCCAssertUserCredentialsAndOptionalDSID(CFStringRef user_label, CFDataRef user_password, CFStringRef dsid, CFErrorRef *error) { secnotice("updates", "Setting credentials and dsid (%@) for %@", dsid, user_label); @@ -928,6 +956,8 @@ static bool SOSCCAssertUserCredentialsAndOptionalDSID(CFStringRef user_label, CF return SOSAccountGenerationSignatureUpdate(txn.account, error); }); + secnotice("updates", "Complete credentials and dsid (%@) for %@: %d %@", + dsid, user_label, result, error ? *error : NULL); done: return result; } @@ -988,6 +1018,9 @@ done: if(generationSignatureUpdateEvent){ [generationSignatureUpdateEvent stopWithAttributes:nil]; } + secnotice("updates", "Complete credentials and dsid (%@) for %@: %d %@", + dsid, user_label, result, error ? *error : NULL); + return result; } @@ -1477,7 +1510,6 @@ bool SOSCCWaitForInitialSyncWithAnalytics_Server(CFDataRef parentEvent, CFErrorR bool alreadyInSync = (SOSAccountHasCompletedInitialSync(txn.account)); if (!alreadyInSync) { - txn.account.isInitialSyncing = true; start = time(NULL); inSyncSema = dispatch_semaphore_create(0); @@ -1541,10 +1573,6 @@ bool SOSCCWaitForInitialSyncWithAnalytics_Server(CFDataRef parentEvent, CFErrorR SecADAddValueForScalarKey(SOSAggdSyncTimeoutKey, 1); } - (void)do_with_account(^(SOSAccountTransaction *txn) { - txn.account.isInitialSyncing = false; - }); - secnotice("initial sync", "Finished!: %d", result); fail: @@ -1569,7 +1597,6 @@ bool SOSCCWaitForInitialSync_Server(CFErrorRef* error) { bool alreadyInSync = (SOSAccountHasCompletedInitialSync(txn.account)); if (!alreadyInSync) { - txn.account.isInitialSyncing = true; start = time(NULL); inSyncSema = dispatch_semaphore_create(0); @@ -1623,10 +1650,6 @@ bool SOSCCWaitForInitialSync_Server(CFErrorRef* error) { SecADAddValueForScalarKey(SOSAggdSyncTimeoutKey, 1); } - (void)do_with_account(^(SOSAccountTransaction *txn) { - txn.account.isInitialSyncing = false; - }); - secnotice("initial sync", "Finished!: %d", result); fail: @@ -2135,7 +2158,7 @@ void SOSCCRequestSyncWithBackupPeer(CFStringRef backupPeerId) { } bool SOSCCIsSyncPendingFor(CFStringRef peerID, CFErrorRef *error) { - return SOSCloudKeychainHasPendingSyncWithPeer(peerID, error); + return false; } void SOSCCEnsurePeerRegistration(void) @@ -2163,7 +2186,6 @@ SOSPeerInfoRef SOSCCCopyApplication_Server(CFErrorRef *error) { return application != NULL; }); return application; - } bool SOSCCCleanupKVSKeys_Server(CFErrorRef *error) { @@ -2365,6 +2387,149 @@ void SOSCCPerformWithAllOctagonKeys(void (^action)(SecKeyRef octagonEncryptionKe }); CFReleaseNull(localError); } + +static bool saveOctagonKeysToKeychain(NSString* keyLabel, NSData* keyDataToSave, int keySize, SecKeyRef octagonPublicKey, NSError** error) { + NSError* localerror = nil; + + CFDataRef publicKeyHash = SecKeyCopyPublicKeyHash(octagonPublicKey); + + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassKey, + (id)kSecAttrKeyType : (id)kSecAttrKeyTypeEC, + (id)kSecAttrKeyClass : (id)kSecAttrKeyClassPrivate, + (id)kSecAttrAccessGroup : (id)kSOSInternalAccessGroup, + (id)kSecAttrLabel : keyLabel, + (id)kSecAttrApplicationLabel : (__bridge NSData*)(publicKeyHash), + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecValueData : keyDataToSave, + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &result); + + if(status == errSecSuccess) { + CFReleaseNull(publicKeyHash); + return true; + } + if(status == errSecDuplicateItem) { + // Add every primary key attribute to this find dictionary + NSMutableDictionary* findQuery = [[NSMutableDictionary alloc] init]; + findQuery[(id)kSecClass] = query[(id)kSecClass]; + findQuery[(id)kSecAttrKeyType] = query[(id)kSecAttrKeyTypeEC]; + findQuery[(id)kSecAttrKeyClass] = query[(id)kSecAttrKeyClassPrivate]; + findQuery[(id)kSecAttrAccessGroup] = query[(id)kSecAttrAccessGroup]; + findQuery[(id)kSecAttrLabel] = query[(id)kSecAttrLabel]; + findQuery[(id)kSecAttrApplicationLabel] = query[(id)kSecAttrApplicationLabel]; + findQuery[(id)kSecUseDataProtectionKeychain] = query[(id)kSecUseDataProtectionKeychain]; + + NSMutableDictionary* updateQuery = [query mutableCopy]; + updateQuery[(id)kSecClass] = nil; + + status = SecItemUpdate((__bridge CFDictionaryRef)findQuery, (__bridge CFDictionaryRef)updateQuery); + + if(status) { + localerror = [NSError + errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemUpdate: %d", (int)status]]; + } + } else { + localerror = [NSError + errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemAdd: %d", (int)status]]; + } + if(localerror && error) { + *error = localerror; + } + + CFReleaseNull(publicKeyHash); + + return (status == errSecSuccess); +} + +static NSString* createKeyLabel(NSDictionary *gestalt, NSString* circleName, NSString* prefix) +{ + NSString *keyName = [NSString stringWithFormat:@"ID for %@-%@",SOSPeerGestaltGetName((__bridge CFDictionaryRef)(gestalt)), circleName]; + + NSString* octagonSigningKeyName = [prefix stringByAppendingString: keyName]; + + return octagonSigningKeyName; +} + +static NSError* saveKeysToKeychain(SOSAccount* account, NSData* octagonSigningFullKey, NSData* octagonEncryptionFullKey, SecKeyRef octagonSigningPublicKeyRef, SecKeyRef octagonEncryptionPublicKeyRef) +{ + NSError* saveToKeychainError = nil; + + NSString* circleName = (__bridge NSString*)(SOSCircleGetName(account.trust.trustedCircle)); + NSString* signingPrefix = @"Octagon Peer Signing "; + NSString* encryptionPrefix = @"Octagon Peer Encryption "; + NSString* octagonSigningKeyName = createKeyLabel(account.gestalt, circleName, signingPrefix); + NSString* octagonEncryptionKeyName = createKeyLabel(account.gestalt, circleName, encryptionPrefix); + + /* behavior mimics GeneratePermanentFullECKey_internal */ + saveOctagonKeysToKeychain(octagonSigningKeyName, octagonSigningFullKey, 384, octagonSigningPublicKeyRef, &saveToKeychainError); + if(saveToKeychainError) { + secerror("octagon: could not save signing key: %@", saveToKeychainError); + return saveToKeychainError; + } + saveOctagonKeysToKeychain(octagonEncryptionKeyName, octagonEncryptionFullKey, 384, octagonEncryptionPublicKeyRef, &saveToKeychainError); + if(saveToKeychainError) { + secerror("octagon: could not save encryption key: %@", saveToKeychainError); + return saveToKeychainError; + } + + return nil; +} + +void SOSCCPerformUpdateOfAllOctagonKeys(CFDataRef octagonSigningFullKey, CFDataRef octagonEncryptionFullKey, + CFDataRef signingPublicKey, CFDataRef encryptionPublicKey, + SecKeyRef octagonSigningPublicKeyRef, SecKeyRef octagonEncryptionPublicKeyRef, + void (^action)(CFErrorRef error)) +{ + CFErrorRef localError = NULL; + do_with_account_if_after_first_unlock(&localError, ^bool(SOSAccountTransaction *txn, CFErrorRef *err) { + CFErrorRef updateOctagonKeysError = NULL; + bool updatedPeerInfo = SOSAccountUpdatePeerInfoAndPush(txn.account, CFSTR("Updating Octagon Keys in SOS"), &updateOctagonKeysError, ^bool(SOSPeerInfoRef pi, CFErrorRef *error) { + + //save octagon key set to the keychain + NSError* saveError = nil; + saveError = saveKeysToKeychain(txn.account, (__bridge NSData*)octagonSigningFullKey, (__bridge NSData*)octagonEncryptionFullKey, + octagonSigningPublicKeyRef, octagonEncryptionPublicKeyRef); + + if(saveError) { + secerror("octagon: failed to save Octagon keys to the keychain: %@", saveError); + action((__bridge CFErrorRef)saveError); + return false; + } + + //now update the peer info to contain octagon keys + if(pi){ + CFErrorRef setError = NULL; + SOSPeerInfoSetOctagonKeysInDescription(pi, octagonSigningPublicKeyRef, octagonEncryptionPublicKeyRef, &setError); + if(setError) { + secerror("octagon: Failed to set Octagon Keys in peerInfo: %@", setError); + action(setError); + return false; + } + } else { + secnotice("octagon", "No peer info to update?"); + NSError *noPIError = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:kSOSErrorPeerNotFound userInfo:@{NSLocalizedDescriptionKey : @"Device has no full peer info"}]; + action((__bridge CFErrorRef)noPIError); + return false; + } + + secnotice("octagon", "Success! Upated Octagon keys in SOS!"); + + action(nil); + return true; + }); + return updatedPeerInfo; + }); + CFReleaseNull(localError); +} + void SOSCCPerformWithTrustedPeers(void (^action)(CFSetRef sosPeerInfoRefs, CFErrorRef error)) { CFErrorRef cfAccountError = NULL; diff --git a/OSX/sec/securityd/SecAKSObjCWrappers.h b/OSX/sec/securityd/SecAKSObjCWrappers.h new file mode 100644 index 00000000..d7bf4e94 --- /dev/null +++ b/OSX/sec/securityd/SecAKSObjCWrappers.h @@ -0,0 +1,49 @@ +/* + * 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 "SecKeybagSupport.h" +#include + +#define BridgeCFErrorToNSErrorOut(nsErrorOut, CFErr) \ +{ \ + if (nsErrorOut) { \ + *nsErrorOut = CFBridgingRelease(CFErr); \ + CFErr = NULL; \ + } \ + else { \ + CFReleaseNull(CFErr); \ + } \ +} + +NS_ASSUME_NONNULL_BEGIN + +@interface SecAKSObjCWrappers : NSObject ++ (bool)aksEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass plaintext:(NSData*)plaintext + outKeyclass:(keyclass_t* _Nullable)outKeyclass ciphertext:(NSMutableData*)ciphertext error:(NSError**)error; + ++ (bool)aksDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass ciphertext:(NSData*)ciphertext + outKeyclass:(keyclass_t* _Nullable)outKeyclass plaintext:(NSMutableData*)plaintext error:(NSError**)error; +@end + +NS_ASSUME_NONNULL_END diff --git a/OSX/sec/securityd/SecAKSObjCWrappers.m b/OSX/sec/securityd/SecAKSObjCWrappers.m new file mode 100644 index 00000000..68eb3d6a --- /dev/null +++ b/OSX/sec/securityd/SecAKSObjCWrappers.m @@ -0,0 +1,46 @@ +/* + * 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 "SecAKSObjCWrappers.h" + +@implementation SecAKSObjCWrappers + ++ (bool)aksEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass plaintext:(NSData*)plaintext + outKeyclass:(keyclass_t*)outKeyclass ciphertext:(NSMutableData*)ciphertext error:(NSError**)error +{ + CFErrorRef cfError = NULL; + bool result = ks_crypt(kAKSKeyOpEncrypt, keybag, keyclass, (uint32_t)plaintext.length, plaintext.bytes, outKeyclass, (__bridge CFMutableDataRef)ciphertext, &cfError); + BridgeCFErrorToNSErrorOut(error, cfError); + return result; +} + ++ (bool)aksDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass ciphertext:(NSData*)ciphertext + outKeyclass:(keyclass_t*)outKeyclass plaintext:(NSMutableData*)plaintext error:(NSError**)error +{ + CFErrorRef cfError = NULL; + bool result = ks_crypt(kAKSKeyOpDecrypt, keybag, keyclass, (uint32_t)ciphertext.length, ciphertext.bytes, outKeyclass, (__bridge CFMutableDataRef)plaintext, &cfError); + BridgeCFErrorToNSErrorOut(error, cfError); + return result; +} + +@end diff --git a/OSX/sec/securityd/SecCertificateServer.c b/OSX/sec/securityd/SecCertificateServer.c index 0236ca49..39e8ee37 100644 --- a/OSX/sec/securityd/SecCertificateServer.c +++ b/OSX/sec/securityd/SecCertificateServer.c @@ -58,6 +58,7 @@ struct SecCertificateVC { CFRuntimeBase _base; SecCertificateRef certificate; CFArrayRef usageConstraints; + CFNumberRef revocationReason; bool optionallyEV; bool isWeakHash; bool require_revocation_response; @@ -68,6 +69,7 @@ static void SecCertificateVCDestroy(CFTypeRef cf) { SecCertificateVCRef cvc = (SecCertificateVCRef) cf; CFReleaseNull(cvc->certificate); CFReleaseNull(cvc->usageConstraints); + CFReleaseNull(cvc->revocationReason); } static Boolean SecCertificateVCCompare(CFTypeRef cf1, CFTypeRef cf2) { @@ -173,23 +175,7 @@ static bool SecCertificateVCCouldBeEV(SecCertificateRef certificate) { } /* 6.3.2 Validity Periods */ - CFAbsoluteTime jul2016 = 489024000; - CFAbsoluteTime notAfter = SecCertificateNotValidAfter(certificate); - CFAbsoluteTime notBefore = SecCertificateNotValidBefore(certificate); - if (SecCertificateNotValidBefore(certificate) < jul2016) { - /* Validity Period no greater than 60 months. - 60 months is no more than 5 years and 2 leap days. */ - CFAbsoluteTime maxPeriod = 60*60*24*(365*5+2); - require_action_quiet(notAfter - notBefore <= maxPeriod, notEV, - secnotice("ev", "Leaf's validity period is more than 60 months")); - } else { - /* Validity Period no greater than 39 months. - 39 months is no more than 3 years, 2 31-day months, - 1 30-day month, and 1 leap day */ - CFAbsoluteTime maxPeriod = 60*60*24*(365*3+2*31+30+1); - require_action_quiet(notAfter - notBefore <= maxPeriod, notEV, - secnotice("ev", "Leaf has validity period longer than 39 months and issued after 30 June 2016")); - } + // Will be checked by the policy server (see SecPolicyCheckValidityPeriodMaximums) /* 7.1.3 Algorithm Object Identifiers */ CFAbsoluteTime jan2016 = 473299200; @@ -875,25 +861,15 @@ CFAbsoluteTime SecCertificatePathVCGetEarliestNextUpdate(SecCertificatePathVCRef if (thisCertNextUpdate == 0) { if (certIX > 0) { /* We allow for CA certs to not be revocation checked if they - have no ocspResponders nor CRLDPs to check against, but the leaf + have no ocspResponders to check against, but the leaf must be checked in order for us to claim we did revocation checking. */ SecCertificateRef cert = SecCertificatePathVCGetCertificateAtIndex(path, rvc->certIX); CFArrayRef ocspResponders = NULL; ocspResponders = SecCertificateGetOCSPResponders(cert); -#if ENABLE_CRLS - CFArrayRef crlDPs = NULL; - crlDPs = SecCertificateGetCRLDistributionPoints(cert); -#endif - if ((!ocspResponders || CFArrayGetCount(ocspResponders) == 0) -#if ENABLE_CRLS - && (!crlDPs || CFArrayGetCount(crlDPs) == 0) -#endif - ) { + if (!ocspResponders || CFArrayGetCount(ocspResponders) == 0) { /* We can't check this cert so we don't consider it a soft - failure that we didn't. Ideally we should support crl - checking and remove this workaround, since that more - strict. */ + failure that we didn't. */ continue; } } @@ -915,6 +891,23 @@ CFAbsoluteTime SecCertificatePathVCGetEarliestNextUpdate(SecCertificatePathVCRef return enu; } +void SecCertificatePathVCSetRevocationReasonForCertificateAtIndex(SecCertificatePathVCRef certificatePath, + CFIndex ix, CFNumberRef revocationReason) { + if (ix > certificatePath->count - 1) { return; } + SecCertificateVCRef cvc = certificatePath->certificates[ix]; + cvc->revocationReason = CFRetainSafe(revocationReason); +} + +CFNumberRef SecCertificatePathVCGetRevocationReason(SecCertificatePathVCRef certificatePath) { + for (CFIndex ix = 0; ix < certificatePath->count; ix++) { + SecCertificateVCRef cvc = certificatePath->certificates[ix]; + if (cvc->revocationReason) { + return cvc->revocationReason; + } + } + return NULL; +} + bool SecCertificatePathVCIsRevocationRequiredForCertificateAtIndex(SecCertificatePathVCRef certificatePath, CFIndex ix) { if (ix > certificatePath->count - 1) { return false; } diff --git a/OSX/sec/securityd/SecCertificateServer.h b/OSX/sec/securityd/SecCertificateServer.h index 879e08a3..96b3b44b 100644 --- a/OSX/sec/securityd/SecCertificateServer.h +++ b/OSX/sec/securityd/SecCertificateServer.h @@ -34,7 +34,7 @@ #include -#include +#include "securityd/policytree.h" typedef struct SecCertificateVC *SecCertificateVCRef; @@ -133,6 +133,9 @@ bool SecCertificatePathVCIsRevocationRequiredForCertificateAtIndex(SecCertificat CFIndex ix); void SecCertificatePathVCSetRevocationRequiredForCertificateAtIndex(SecCertificatePathVCRef certificatePath, CFIndex ix); +void SecCertificatePathVCSetRevocationReasonForCertificateAtIndex(SecCertificatePathVCRef certificatePath, + CFIndex ix, CFNumberRef revocationReason); +CFNumberRef SecCertificatePathVCGetRevocationReason(SecCertificatePathVCRef certificatePath); // returns first revocation reason found bool SecCertificatePathVCCheckedIssuers(SecCertificatePathVCRef certificatePath); void SecCertificatePathVCSetCheckedIssuers(SecCertificatePathVCRef certificatePath, bool checked); diff --git a/OSX/sec/securityd/SecCertificateSource.c b/OSX/sec/securityd/SecCertificateSource.c index 393dd7f3..26464069 100644 --- a/OSX/sec/securityd/SecCertificateSource.c +++ b/OSX/sec/securityd/SecCertificateSource.c @@ -298,18 +298,14 @@ void SecItemCertificateSourceDestroy(SecCertificateSourceRef source) { static bool SecSystemAnchorSourceCopyParents(SecCertificateSourceRef source, SecCertificateRef certificate, void *context, SecCertificateSourceParents callback) { - //#ifndef SECITEM_SHIM_OSX CFArrayRef parents = NULL; CFArrayRef anchors = NULL; - SecOTAPKIRef otapkiref = NULL; CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate); /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor. It does not matter since we would be returning the wrong anchors */ assert((unsigned long)CFDataGetLength(nic) +#import + +@class SecDbBackupBagIdentity; + +#ifdef __cplusplus +#define SECDBBACKUPBAG_FUNCTION extern "C" +#else +#define SECDBBACKUPBAG_FUNCTION extern +#endif + +/** Insert into backupbags table, v12_backupBag column */ +@interface SecDbBackupBag : PBCodable +{ + SecDbBackupBagIdentity *_bagIdentity; + NSData *_keybag; +} + + +@property (nonatomic, readonly) BOOL hasBagIdentity; +@property (nonatomic, retain) SecDbBackupBagIdentity *bagIdentity; + +@property (nonatomic, readonly) BOOL hasKeybag; +@property (nonatomic, retain) NSData *keybag; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbBackupBag *)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:(SecDbBackupBag *)other; + +SECDBBACKUPBAG_FUNCTION BOOL SecDbBackupBagReadFrom(__unsafe_unretained SecDbBackupBag *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBag.m b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBag.m new file mode 100644 index 00000000..01ab3770 --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBag.m @@ -0,0 +1,177 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import "SecDbBackupBag.h" +#import +#import +#import + +#import "SecDbBackupBagIdentity.h" + +#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 SecDbBackupBag + +- (BOOL)hasBagIdentity +{ + return _bagIdentity != nil; +} +@synthesize bagIdentity = _bagIdentity; +- (BOOL)hasKeybag +{ + return _keybag != nil; +} +@synthesize keybag = _keybag; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_bagIdentity) + { + [dict setObject:[_bagIdentity dictionaryRepresentation] forKey:@"bagIdentity"]; + } + if (self->_keybag) + { + [dict setObject:self->_keybag forKey:@"keybag"]; + } + return dict; +} + +BOOL SecDbBackupBagReadFrom(__unsafe_unretained SecDbBackupBag *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 /* bagIdentity */: + { + SecDbBackupBagIdentity *new_bagIdentity = [[SecDbBackupBagIdentity alloc] init]; + self->_bagIdentity = new_bagIdentity; + PBDataReaderMark mark_bagIdentity; + BOOL markError = !PBReaderPlaceMark(reader, &mark_bagIdentity); + if (markError) + { + return NO; + } + BOOL inError = !SecDbBackupBagIdentityReadFrom(new_bagIdentity, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_bagIdentity); + } + break; + case 2 /* keybag */: + { + NSData *new_keybag = PBReaderReadData(reader); + self->_keybag = new_keybag; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbBackupBagReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* bagIdentity */ + { + if (self->_bagIdentity != nil) + { + PBDataWriterWriteSubmessage(writer, self->_bagIdentity, 1); + } + } + /* keybag */ + { + if (self->_keybag) + { + PBDataWriterWriteDataField(writer, self->_keybag, 2); + } + } +} + +- (void)copyTo:(SecDbBackupBag *)other +{ + if (_bagIdentity) + { + other.bagIdentity = _bagIdentity; + } + if (_keybag) + { + other.keybag = _keybag; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbBackupBag *copy = [[[self class] allocWithZone:zone] init]; + copy->_bagIdentity = [_bagIdentity copyWithZone:zone]; + copy->_keybag = [_keybag copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbBackupBag *other = (SecDbBackupBag *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_bagIdentity && !other->_bagIdentity) || [self->_bagIdentity isEqual:other->_bagIdentity]) + && + ((!self->_keybag && !other->_keybag) || [self->_keybag isEqual:other->_keybag]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_bagIdentity hash] + ^ + [self->_keybag hash] + ; +} + +- (void)mergeFrom:(SecDbBackupBag *)other +{ + if (self->_bagIdentity && other->_bagIdentity) + { + [self->_bagIdentity mergeFrom:other->_bagIdentity]; + } + else if (!self->_bagIdentity && other->_bagIdentity) + { + [self setBagIdentity:other->_bagIdentity]; + } + if (other->_keybag) + { + [self setKeybag:other->_keybag]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.h b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.h new file mode 100644 index 00000000..939066cb --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.h @@ -0,0 +1,40 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import +#import + +#ifdef __cplusplus +#define SECDBBACKUPBAGIDENTITY_FUNCTION extern "C" +#else +#define SECDBBACKUPBAGIDENTITY_FUNCTION extern +#endif + +/** Maintain identity consistency by including this in key and bag messages */ +@interface SecDbBackupBagIdentity : PBCodable +{ + NSData *_baghash; + NSData *_baguuid; +} + + +@property (nonatomic, readonly) BOOL hasBaguuid; +@property (nonatomic, retain) NSData *baguuid; + +@property (nonatomic, readonly) BOOL hasBaghash; +@property (nonatomic, retain) NSData *baghash; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbBackupBagIdentity *)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:(SecDbBackupBagIdentity *)other; + +SECDBBACKUPBAGIDENTITY_FUNCTION BOOL SecDbBackupBagIdentityReadFrom(__unsafe_unretained SecDbBackupBagIdentity *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.m b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.m new file mode 100644 index 00000000..03bcbf45 --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupBagIdentity.m @@ -0,0 +1,159 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import "SecDbBackupBagIdentity.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 SecDbBackupBagIdentity + +- (BOOL)hasBaguuid +{ + return _baguuid != nil; +} +@synthesize baguuid = _baguuid; +- (BOOL)hasBaghash +{ + return _baghash != nil; +} +@synthesize baghash = _baghash; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_baguuid) + { + [dict setObject:self->_baguuid forKey:@"baguuid"]; + } + if (self->_baghash) + { + [dict setObject:self->_baghash forKey:@"baghash"]; + } + return dict; +} + +BOOL SecDbBackupBagIdentityReadFrom(__unsafe_unretained SecDbBackupBagIdentity *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 /* baguuid */: + { + NSData *new_baguuid = PBReaderReadData(reader); + self->_baguuid = new_baguuid; + } + break; + case 2 /* baghash */: + { + NSData *new_baghash = PBReaderReadData(reader); + self->_baghash = new_baghash; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbBackupBagIdentityReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* baguuid */ + { + if (self->_baguuid) + { + PBDataWriterWriteDataField(writer, self->_baguuid, 1); + } + } + /* baghash */ + { + if (self->_baghash) + { + PBDataWriterWriteDataField(writer, self->_baghash, 2); + } + } +} + +- (void)copyTo:(SecDbBackupBagIdentity *)other +{ + if (_baguuid) + { + other.baguuid = _baguuid; + } + if (_baghash) + { + other.baghash = _baghash; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbBackupBagIdentity *copy = [[[self class] allocWithZone:zone] init]; + copy->_baguuid = [_baguuid copyWithZone:zone]; + copy->_baghash = [_baghash copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbBackupBagIdentity *other = (SecDbBackupBagIdentity *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_baguuid && !other->_baguuid) || [self->_baguuid isEqual:other->_baguuid]) + && + ((!self->_baghash && !other->_baghash) || [self->_baghash isEqual:other->_baghash]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_baguuid hash] + ^ + [self->_baghash hash] + ; +} + +- (void)mergeFrom:(SecDbBackupBagIdentity *)other +{ + if (other->_baguuid) + { + [self setBaguuid:other->_baguuid]; + } + if (other->_baghash) + { + [self setBaghash:other->_baghash]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.h b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.h new file mode 100644 index 00000000..e3b5c0bc --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.h @@ -0,0 +1,58 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import +#import + +#ifdef __cplusplus +#define SECDBBACKUPKEYCLASSSIGNINGKEY_FUNCTION extern "C" +#else +#define SECDBBACKUPKEYCLASSSIGNINGKEY_FUNCTION extern +#endif + +/** Insert into backupkeyclasssigningkeys table, v12_keyClassSigningKey column */ +@interface SecDbBackupKeyClassSigningKey : PBCodable +{ + NSData *_aksRefKey; + NSData *_aksWrappedKey; + NSData *_backupWrappedKey; + int32_t _keyClass; + NSData *_publicKey; + struct { + int keyClass:1; + } _has; +} + + +@property (nonatomic) BOOL hasKeyClass; +@property (nonatomic) int32_t keyClass; + +@property (nonatomic, readonly) BOOL hasPublicKey; +@property (nonatomic, retain) NSData *publicKey; + +@property (nonatomic, readonly) BOOL hasAksRefKey; +/** Contains bag identity as authenticated data */ +@property (nonatomic, retain) NSData *aksRefKey; + +@property (nonatomic, readonly) BOOL hasAksWrappedKey; +/** SFECIESKeyPair wrapped by AKS ref key */ +@property (nonatomic, retain) NSData *aksWrappedKey; + +@property (nonatomic, readonly) BOOL hasBackupWrappedKey; +/** SFECIESKeyPair wrapped by KCSKSecret in RecoverySet. Also authenticates bag identity */ +@property (nonatomic, retain) NSData *backupWrappedKey; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbBackupKeyClassSigningKey *)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:(SecDbBackupKeyClassSigningKey *)other; + +SECDBBACKUPKEYCLASSSIGNINGKEY_FUNCTION BOOL SecDbBackupKeyClassSigningKeyReadFrom(__unsafe_unretained SecDbBackupKeyClassSigningKey *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.m b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.m new file mode 100644 index 00000000..b86f63cb --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupKeyClassSigningKey.m @@ -0,0 +1,279 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import "SecDbBackupKeyClassSigningKey.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 SecDbBackupKeyClassSigningKey + +@synthesize keyClass = _keyClass; +- (void)setKeyClass:(int32_t)v +{ + _has.keyClass = YES; + _keyClass = v; +} +- (void)setHasKeyClass:(BOOL)f +{ + _has.keyClass = f; +} +- (BOOL)hasKeyClass +{ + return _has.keyClass; +} +- (BOOL)hasPublicKey +{ + return _publicKey != nil; +} +@synthesize publicKey = _publicKey; +- (BOOL)hasAksRefKey +{ + return _aksRefKey != nil; +} +@synthesize aksRefKey = _aksRefKey; +- (BOOL)hasAksWrappedKey +{ + return _aksWrappedKey != nil; +} +@synthesize aksWrappedKey = _aksWrappedKey; +- (BOOL)hasBackupWrappedKey +{ + return _backupWrappedKey != nil; +} +@synthesize backupWrappedKey = _backupWrappedKey; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.keyClass) + { + [dict setObject:[NSNumber numberWithInt:self->_keyClass] forKey:@"keyClass"]; + } + if (self->_publicKey) + { + [dict setObject:self->_publicKey forKey:@"publicKey"]; + } + if (self->_aksRefKey) + { + [dict setObject:self->_aksRefKey forKey:@"aksRefKey"]; + } + if (self->_aksWrappedKey) + { + [dict setObject:self->_aksWrappedKey forKey:@"aksWrappedKey"]; + } + if (self->_backupWrappedKey) + { + [dict setObject:self->_backupWrappedKey forKey:@"backupWrappedKey"]; + } + return dict; +} + +BOOL SecDbBackupKeyClassSigningKeyReadFrom(__unsafe_unretained SecDbBackupKeyClassSigningKey *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 /* keyClass */: + { + self->_has.keyClass = YES; + self->_keyClass = PBReaderReadInt32(reader); + } + break; + case 3 /* publicKey */: + { + NSData *new_publicKey = PBReaderReadData(reader); + self->_publicKey = new_publicKey; + } + break; + case 4 /* aksRefKey */: + { + NSData *new_aksRefKey = PBReaderReadData(reader); + self->_aksRefKey = new_aksRefKey; + } + break; + case 5 /* aksWrappedKey */: + { + NSData *new_aksWrappedKey = PBReaderReadData(reader); + self->_aksWrappedKey = new_aksWrappedKey; + } + break; + case 6 /* backupWrappedKey */: + { + NSData *new_backupWrappedKey = PBReaderReadData(reader); + self->_backupWrappedKey = new_backupWrappedKey; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbBackupKeyClassSigningKeyReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* keyClass */ + { + if (self->_has.keyClass) + { + PBDataWriterWriteInt32Field(writer, self->_keyClass, 1); + } + } + /* publicKey */ + { + if (self->_publicKey) + { + PBDataWriterWriteDataField(writer, self->_publicKey, 3); + } + } + /* aksRefKey */ + { + if (self->_aksRefKey) + { + PBDataWriterWriteDataField(writer, self->_aksRefKey, 4); + } + } + /* aksWrappedKey */ + { + if (self->_aksWrappedKey) + { + PBDataWriterWriteDataField(writer, self->_aksWrappedKey, 5); + } + } + /* backupWrappedKey */ + { + if (self->_backupWrappedKey) + { + PBDataWriterWriteDataField(writer, self->_backupWrappedKey, 6); + } + } +} + +- (void)copyTo:(SecDbBackupKeyClassSigningKey *)other +{ + if (self->_has.keyClass) + { + other->_keyClass = _keyClass; + other->_has.keyClass = YES; + } + if (_publicKey) + { + other.publicKey = _publicKey; + } + if (_aksRefKey) + { + other.aksRefKey = _aksRefKey; + } + if (_aksWrappedKey) + { + other.aksWrappedKey = _aksWrappedKey; + } + if (_backupWrappedKey) + { + other.backupWrappedKey = _backupWrappedKey; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbBackupKeyClassSigningKey *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.keyClass) + { + copy->_keyClass = _keyClass; + copy->_has.keyClass = YES; + } + copy->_publicKey = [_publicKey copyWithZone:zone]; + copy->_aksRefKey = [_aksRefKey copyWithZone:zone]; + copy->_aksWrappedKey = [_aksWrappedKey copyWithZone:zone]; + copy->_backupWrappedKey = [_backupWrappedKey copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbBackupKeyClassSigningKey *other = (SecDbBackupKeyClassSigningKey *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.keyClass && other->_has.keyClass && self->_keyClass == other->_keyClass) || (!self->_has.keyClass && !other->_has.keyClass)) + && + ((!self->_publicKey && !other->_publicKey) || [self->_publicKey isEqual:other->_publicKey]) + && + ((!self->_aksRefKey && !other->_aksRefKey) || [self->_aksRefKey isEqual:other->_aksRefKey]) + && + ((!self->_aksWrappedKey && !other->_aksWrappedKey) || [self->_aksWrappedKey isEqual:other->_aksWrappedKey]) + && + ((!self->_backupWrappedKey && !other->_backupWrappedKey) || [self->_backupWrappedKey isEqual:other->_backupWrappedKey]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.keyClass ? PBHashInt((NSUInteger)self->_keyClass) : 0) + ^ + [self->_publicKey hash] + ^ + [self->_aksRefKey hash] + ^ + [self->_aksWrappedKey hash] + ^ + [self->_backupWrappedKey hash] + ; +} + +- (void)mergeFrom:(SecDbBackupKeyClassSigningKey *)other +{ + if (other->_has.keyClass) + { + self->_keyClass = other->_keyClass; + self->_has.keyClass = YES; + } + if (other->_publicKey) + { + [self setPublicKey:other->_publicKey]; + } + if (other->_aksRefKey) + { + [self setAksRefKey:other->_aksRefKey]; + } + if (other->_aksWrappedKey) + { + [self setAksWrappedKey:other->_aksWrappedKey]; + } + if (other->_backupWrappedKey) + { + [self setBackupWrappedKey:other->_backupWrappedKey]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.h b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.h new file mode 100644 index 00000000..b967187f --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.h @@ -0,0 +1,44 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import +#import + +#ifdef __cplusplus +#define SECDBBACKUPMETADATACLASSKEY_FUNCTION extern "C" +#else +#define SECDBBACKUPMETADATACLASSKEY_FUNCTION extern +#endif + +/** Insert into metadatakeys table, v12_metadatakeydata column */ +@interface SecDbBackupMetadataClassKey : PBCodable +{ + NSData *_backupWrappedMetadataKey; + int32_t _keyClass; + struct { + int keyClass:1; + } _has; +} + + +@property (nonatomic) BOOL hasKeyClass; +@property (nonatomic) int32_t keyClass; + +@property (nonatomic, readonly) BOOL hasBackupWrappedMetadataKey; +/** wrapped by appropriate backup keyclass for recovery */ +@property (nonatomic, retain) NSData *backupWrappedMetadataKey; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbBackupMetadataClassKey *)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:(SecDbBackupMetadataClassKey *)other; + +SECDBBACKUPMETADATACLASSKEY_FUNCTION BOOL SecDbBackupMetadataClassKeyReadFrom(__unsafe_unretained SecDbBackupMetadataClassKey *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.m b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.m new file mode 100644 index 00000000..eae21ba4 --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupMetadataClassKey.m @@ -0,0 +1,174 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import "SecDbBackupMetadataClassKey.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 SecDbBackupMetadataClassKey + +@synthesize keyClass = _keyClass; +- (void)setKeyClass:(int32_t)v +{ + _has.keyClass = YES; + _keyClass = v; +} +- (void)setHasKeyClass:(BOOL)f +{ + _has.keyClass = f; +} +- (BOOL)hasKeyClass +{ + return _has.keyClass; +} +- (BOOL)hasBackupWrappedMetadataKey +{ + return _backupWrappedMetadataKey != nil; +} +@synthesize backupWrappedMetadataKey = _backupWrappedMetadataKey; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.keyClass) + { + [dict setObject:[NSNumber numberWithInt:self->_keyClass] forKey:@"keyClass"]; + } + if (self->_backupWrappedMetadataKey) + { + [dict setObject:self->_backupWrappedMetadataKey forKey:@"backupWrappedMetadataKey"]; + } + return dict; +} + +BOOL SecDbBackupMetadataClassKeyReadFrom(__unsafe_unretained SecDbBackupMetadataClassKey *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 /* keyClass */: + { + self->_has.keyClass = YES; + self->_keyClass = PBReaderReadInt32(reader); + } + break; + case 2 /* backupWrappedMetadataKey */: + { + NSData *new_backupWrappedMetadataKey = PBReaderReadData(reader); + self->_backupWrappedMetadataKey = new_backupWrappedMetadataKey; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbBackupMetadataClassKeyReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* keyClass */ + { + if (self->_has.keyClass) + { + PBDataWriterWriteInt32Field(writer, self->_keyClass, 1); + } + } + /* backupWrappedMetadataKey */ + { + if (self->_backupWrappedMetadataKey) + { + PBDataWriterWriteDataField(writer, self->_backupWrappedMetadataKey, 2); + } + } +} + +- (void)copyTo:(SecDbBackupMetadataClassKey *)other +{ + if (self->_has.keyClass) + { + other->_keyClass = _keyClass; + other->_has.keyClass = YES; + } + if (_backupWrappedMetadataKey) + { + other.backupWrappedMetadataKey = _backupWrappedMetadataKey; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbBackupMetadataClassKey *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.keyClass) + { + copy->_keyClass = _keyClass; + copy->_has.keyClass = YES; + } + copy->_backupWrappedMetadataKey = [_backupWrappedMetadataKey copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbBackupMetadataClassKey *other = (SecDbBackupMetadataClassKey *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.keyClass && other->_has.keyClass && self->_keyClass == other->_keyClass) || (!self->_has.keyClass && !other->_has.keyClass)) + && + ((!self->_backupWrappedMetadataKey && !other->_backupWrappedMetadataKey) || [self->_backupWrappedMetadataKey isEqual:other->_backupWrappedMetadataKey]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.keyClass ? PBHashInt((NSUInteger)self->_keyClass) : 0) + ^ + [self->_backupWrappedMetadataKey hash] + ; +} + +- (void)mergeFrom:(SecDbBackupMetadataClassKey *)other +{ + if (other->_has.keyClass) + { + self->_keyClass = other->_keyClass; + self->_has.keyClass = YES; + } + if (other->_backupWrappedMetadataKey) + { + [self setBackupWrappedMetadataKey:other->_backupWrappedMetadataKey]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.h b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.h new file mode 100644 index 00000000..13490afc --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.h @@ -0,0 +1,63 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import +#import + +@class SecDbBackupBagIdentity; + +#ifdef __cplusplus +#define SECDBBACKUPRECOVERYSET_FUNCTION extern "C" +#else +#define SECDBBACKUPRECOVERYSET_FUNCTION extern +#endif + +/** + * optional bytes aksWrappedMetadataKey = 3; // wrapped by device bag for daily use. Not in use right now. + * Insert into backuprecoverysets table, v12_recoverySet column + */ +@interface SecDbBackupRecoverySet : PBCodable +{ + SecDbBackupBagIdentity *_bagIdentity; + int32_t _recoveryType; + NSData *_wrappedBagSecret; + NSData *_wrappedKCSKSecret; + NSData *_wrappedRecoveryKey; + struct { + int recoveryType:1; + } _has; +} + + +@property (nonatomic) BOOL hasRecoveryType; +@property (nonatomic) int32_t recoveryType; + +@property (nonatomic, readonly) BOOL hasBagIdentity; +@property (nonatomic, retain) SecDbBackupBagIdentity *bagIdentity; + +@property (nonatomic, readonly) BOOL hasWrappedBagSecret; +/** 'passphrase' to unlock backup bag's private keys */ +@property (nonatomic, retain) NSData *wrappedBagSecret; + +@property (nonatomic, readonly) BOOL hasWrappedKCSKSecret; +/** recovers KCSKs to verify authenticity of IKs and MCKs */ +@property (nonatomic, retain) NSData *wrappedKCSKSecret; + +@property (nonatomic, readonly) BOOL hasWrappedRecoveryKey; +/** wraps the above two secrets */ +@property (nonatomic, retain) NSData *wrappedRecoveryKey; + +// Performs a shallow copy into other +- (void)copyTo:(SecDbBackupRecoverySet *)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:(SecDbBackupRecoverySet *)other; + +SECDBBACKUPRECOVERYSET_FUNCTION BOOL SecDbBackupRecoverySetReadFrom(__unsafe_unretained SecDbBackupRecoverySet *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.m b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.m new file mode 100644 index 00000000..1621b0d2 --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager-protobufs/generated_source/SecDbBackupRecoverySet.m @@ -0,0 +1,297 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecDbBackupRecoverySet.proto + +#import "SecDbBackupRecoverySet.h" +#import +#import +#import + +#import "SecDbBackupBagIdentity.h" + +#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 SecDbBackupRecoverySet + +@synthesize recoveryType = _recoveryType; +- (void)setRecoveryType:(int32_t)v +{ + _has.recoveryType = YES; + _recoveryType = v; +} +- (void)setHasRecoveryType:(BOOL)f +{ + _has.recoveryType = f; +} +- (BOOL)hasRecoveryType +{ + return _has.recoveryType; +} +- (BOOL)hasBagIdentity +{ + return _bagIdentity != nil; +} +@synthesize bagIdentity = _bagIdentity; +- (BOOL)hasWrappedBagSecret +{ + return _wrappedBagSecret != nil; +} +@synthesize wrappedBagSecret = _wrappedBagSecret; +- (BOOL)hasWrappedKCSKSecret +{ + return _wrappedKCSKSecret != nil; +} +@synthesize wrappedKCSKSecret = _wrappedKCSKSecret; +- (BOOL)hasWrappedRecoveryKey +{ + return _wrappedRecoveryKey != nil; +} +@synthesize wrappedRecoveryKey = _wrappedRecoveryKey; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.recoveryType) + { + [dict setObject:[NSNumber numberWithInt:self->_recoveryType] forKey:@"recoveryType"]; + } + if (self->_bagIdentity) + { + [dict setObject:[_bagIdentity dictionaryRepresentation] forKey:@"bagIdentity"]; + } + if (self->_wrappedBagSecret) + { + [dict setObject:self->_wrappedBagSecret forKey:@"wrappedBagSecret"]; + } + if (self->_wrappedKCSKSecret) + { + [dict setObject:self->_wrappedKCSKSecret forKey:@"wrappedKCSKSecret"]; + } + if (self->_wrappedRecoveryKey) + { + [dict setObject:self->_wrappedRecoveryKey forKey:@"wrappedRecoveryKey"]; + } + return dict; +} + +BOOL SecDbBackupRecoverySetReadFrom(__unsafe_unretained SecDbBackupRecoverySet *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 /* recoveryType */: + { + self->_has.recoveryType = YES; + self->_recoveryType = PBReaderReadInt32(reader); + } + break; + case 2 /* bagIdentity */: + { + SecDbBackupBagIdentity *new_bagIdentity = [[SecDbBackupBagIdentity alloc] init]; + self->_bagIdentity = new_bagIdentity; + PBDataReaderMark mark_bagIdentity; + BOOL markError = !PBReaderPlaceMark(reader, &mark_bagIdentity); + if (markError) + { + return NO; + } + BOOL inError = !SecDbBackupBagIdentityReadFrom(new_bagIdentity, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_bagIdentity); + } + break; + case 3 /* wrappedBagSecret */: + { + NSData *new_wrappedBagSecret = PBReaderReadData(reader); + self->_wrappedBagSecret = new_wrappedBagSecret; + } + break; + case 4 /* wrappedKCSKSecret */: + { + NSData *new_wrappedKCSKSecret = PBReaderReadData(reader); + self->_wrappedKCSKSecret = new_wrappedKCSKSecret; + } + break; + case 5 /* wrappedRecoveryKey */: + { + NSData *new_wrappedRecoveryKey = PBReaderReadData(reader); + self->_wrappedRecoveryKey = new_wrappedRecoveryKey; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecDbBackupRecoverySetReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* recoveryType */ + { + if (self->_has.recoveryType) + { + PBDataWriterWriteInt32Field(writer, self->_recoveryType, 1); + } + } + /* bagIdentity */ + { + if (self->_bagIdentity != nil) + { + PBDataWriterWriteSubmessage(writer, self->_bagIdentity, 2); + } + } + /* wrappedBagSecret */ + { + if (self->_wrappedBagSecret) + { + PBDataWriterWriteDataField(writer, self->_wrappedBagSecret, 3); + } + } + /* wrappedKCSKSecret */ + { + if (self->_wrappedKCSKSecret) + { + PBDataWriterWriteDataField(writer, self->_wrappedKCSKSecret, 4); + } + } + /* wrappedRecoveryKey */ + { + if (self->_wrappedRecoveryKey) + { + PBDataWriterWriteDataField(writer, self->_wrappedRecoveryKey, 5); + } + } +} + +- (void)copyTo:(SecDbBackupRecoverySet *)other +{ + if (self->_has.recoveryType) + { + other->_recoveryType = _recoveryType; + other->_has.recoveryType = YES; + } + if (_bagIdentity) + { + other.bagIdentity = _bagIdentity; + } + if (_wrappedBagSecret) + { + other.wrappedBagSecret = _wrappedBagSecret; + } + if (_wrappedKCSKSecret) + { + other.wrappedKCSKSecret = _wrappedKCSKSecret; + } + if (_wrappedRecoveryKey) + { + other.wrappedRecoveryKey = _wrappedRecoveryKey; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecDbBackupRecoverySet *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.recoveryType) + { + copy->_recoveryType = _recoveryType; + copy->_has.recoveryType = YES; + } + copy->_bagIdentity = [_bagIdentity copyWithZone:zone]; + copy->_wrappedBagSecret = [_wrappedBagSecret copyWithZone:zone]; + copy->_wrappedKCSKSecret = [_wrappedKCSKSecret copyWithZone:zone]; + copy->_wrappedRecoveryKey = [_wrappedRecoveryKey copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecDbBackupRecoverySet *other = (SecDbBackupRecoverySet *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.recoveryType && other->_has.recoveryType && self->_recoveryType == other->_recoveryType) || (!self->_has.recoveryType && !other->_has.recoveryType)) + && + ((!self->_bagIdentity && !other->_bagIdentity) || [self->_bagIdentity isEqual:other->_bagIdentity]) + && + ((!self->_wrappedBagSecret && !other->_wrappedBagSecret) || [self->_wrappedBagSecret isEqual:other->_wrappedBagSecret]) + && + ((!self->_wrappedKCSKSecret && !other->_wrappedKCSKSecret) || [self->_wrappedKCSKSecret isEqual:other->_wrappedKCSKSecret]) + && + ((!self->_wrappedRecoveryKey && !other->_wrappedRecoveryKey) || [self->_wrappedRecoveryKey isEqual:other->_wrappedRecoveryKey]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.recoveryType ? PBHashInt((NSUInteger)self->_recoveryType) : 0) + ^ + [self->_bagIdentity hash] + ^ + [self->_wrappedBagSecret hash] + ^ + [self->_wrappedKCSKSecret hash] + ^ + [self->_wrappedRecoveryKey hash] + ; +} + +- (void)mergeFrom:(SecDbBackupRecoverySet *)other +{ + if (other->_has.recoveryType) + { + self->_recoveryType = other->_recoveryType; + self->_has.recoveryType = YES; + } + if (self->_bagIdentity && other->_bagIdentity) + { + [self->_bagIdentity mergeFrom:other->_bagIdentity]; + } + else if (!self->_bagIdentity && other->_bagIdentity) + { + [self setBagIdentity:other->_bagIdentity]; + } + if (other->_wrappedBagSecret) + { + [self setWrappedBagSecret:other->_wrappedBagSecret]; + } + if (other->_wrappedKCSKSecret) + { + [self setWrappedKCSKSecret:other->_wrappedKCSKSecret]; + } + if (other->_wrappedRecoveryKey) + { + [self setWrappedRecoveryKey:other->_wrappedRecoveryKey]; + } +} + +@end + diff --git a/OSX/sec/securityd/SecDbBackupManager.h b/OSX/sec/securityd/SecDbBackupManager.h new file mode 100644 index 00000000..2459ad75 --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager.h @@ -0,0 +1,98 @@ +/* + * 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@ + */ + +// For now at least, we'll support backups only on iOS and macOS +#define SECDB_BACKUPS_ENABLED ((TARGET_OS_OSX || TARGET_OS_IOS || TARGET_OS_IOSMAC) && !TARGET_OS_SIMULATOR && !TARGET_DARWINOS) + +#if __OBJC2__ +#import +#if !TARGET_OS_BRIDGE // Specifically needed until rdar://problem/40583882 lands +#import +#endif +#import "SecAKSObjCWrappers.h" +#import "CheckV12DevEnabled.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, SecDbBackupRecoveryType) { + SecDbBackupRecoveryTypeInvalid = -1, + SecDbBackupRecoveryTypeAKS = 1, + SecDbBackupRecoveryTypeCylon = 2, + SecDbBackupRecoveryTypeRecoveryKey = 3, +}; + +extern NSString* const KeychainBackupsErrorDomain; + +typedef NS_ENUM(NSInteger, SecDbBackupErrorCode) { + SecDbBackupUnknownError = -1, + SecDbBackupSuccess = 0, + SecDbBackupAKSFailure, + SecDbBackupCryptoFailure, + SecDbBackupWriteFailure, + SecDbBackupDeserializationFailure, + SecDbBackupSetupFailure, + SecDbBackupNoBackupBagFound, + SecDbBackupNoKCSKFound, + SecDbBackupDuplicateBagFound, + SecDbBackupMultipleDefaultBagsFound, + SecDbBackupMalformedBagDataOnDisk, + SecDbBackupMalformedKCSKDataOnDisk, + SecDbBackupMalformedUUIDDataOnDisk, + SecDbBackupUUIDMismatch, + SecDbBackupDataMismatch, + SecDbBackupUnknownOption, + SecDbBackupKeychainLocked, + SecDbBackupInvalidArgument, + SecDbBackupNotSupported, + SecDbBackupInternalError, + + SecDbBackupTestCodeFailure = 255, // support code for testing is falling over somehow +}; + +@interface SecDbBackupWrappedItemKey : NSObject +@property (nonatomic) NSData* wrappedKey; +@property (nonatomic) NSData* baguuid; +@end + +@interface SecDbBackupManager : NSObject + ++ (instancetype)manager; +- (instancetype)init NS_UNAVAILABLE; + +#if !TARGET_OS_BRIDGE // Specifically needed until rdar://problem/40583882 lands +- (SecDbBackupWrappedItemKey* _Nullable)wrapItemKey:(SFAESKey*)key forKeyclass:(keyclass_t)keyclass error:(NSError**)error; +#else +- (SecDbBackupWrappedItemKey* _Nullable)wrapItemKey:(id)key forKeyclass:(keyclass_t)keyclass error:(NSError**)error; +#endif + +- (void)verifyBackupIntegrity:(bool)lightweight + completion:(void (^)(NSDictionary* results, NSError* _Nullable error))completion; + +@end + +NS_ASSUME_NONNULL_END +#endif // __OBJC2__ + +// Declare C functions here + +bool SecDbBackupCreateOrLoadBackupInfrastructure(CFErrorRef _Nullable * _Nonnull error); diff --git a/OSX/sec/securityd/SecDbBackupManager.m b/OSX/sec/securityd/SecDbBackupManager.m new file mode 100644 index 00000000..ff4dc45a --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager.m @@ -0,0 +1,1055 @@ +/* + * 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 "SecDbBackupManager.h" + +NSString* const KeychainBackupsErrorDomain = @"com.apple.security.keychain.backups"; + +// oink oink +@implementation SecDbBackupWrappedItemKey ++ (BOOL)supportsSecureCoding { + return YES; +} +- (void)encodeWithCoder:(nonnull NSCoder *)coder { + [coder encodeObject:self.wrappedKey forKey:@"wrappedKey"]; + [coder encodeObject:self.baguuid forKey:@"baguuid"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder { + if (self = [super init]) { + _wrappedKey = [coder decodeObjectOfClass:[NSData class] forKey:@"wrappedKey"]; + _baguuid = [coder decodeObjectOfClass:[NSData class] forKey:@"baguuid"]; + } + return self; +} +@end + +#if !SECDB_BACKUPS_ENABLED + +@implementation SecDbBackupManager + ++ (instancetype)manager +{ + return nil; +} + +- (void)verifyBackupIntegrity:(bool)lightweight + completion:(void (^)(NSDictionary* results, NSError* _Nullable error))completion +{ + completion(nil, [NSError errorWithDomain:KeychainBackupsErrorDomain + code:SecDbBackupNotSupported + userInfo:@{NSLocalizedDescriptionKey : @"platform doesn't do backups"}]); +} + +- (SecDbBackupWrappedItemKey* _Nullable)wrapItemKey:(id)key forKeyclass:(keyclass_t)keyclass error:(NSError**)error +{ + return nil; +} + +@end + +bool SecDbBackupCreateOrLoadBackupInfrastructure(CFErrorRef* error) +{ + return true; +} + +#else // SECDB_BACKUPS_ENABLED is true, roll out the code + +#import "SecDbBackupManager_Internal.h" +#include +#import +#import "SecItemServer.h" +#import "SecItemDb.h" +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "sec_action.h" +#import "SecItemServer.h" +#include "utilities/der_plist.h" + +// TODO: fire off metric on outcome +bool SecDbBackupCreateOrLoadBackupInfrastructure(CFErrorRef* error) +{ + NSError* localError; + bool ok = [[SecDbBackupManager manager] createOrLoadBackupInfrastructure:&localError]; + if (!ok) { + // Translate this to intelligible constant in C, but other errors can be passed along + if (localError.code == SecDbBackupKeychainLocked) { + *error = CFErrorCreate(kCFAllocatorDefault, kSecErrorDomain, errSecInteractionNotAllowed, NULL); + } else { + *error = (CFErrorRef)CFBridgingRetain(localError); + } + } + return ok; +} + +// Reading from disk is relatively expensive. Keep wrapped key in memory and just delete the unwrapped copy on lock +@interface InMemoryKCSK : NSObject +@property aks_ref_key_t refKey; +@property (nonatomic) NSData* wrappedKey; +@property (nonatomic) SFECKeyPair* key; +@end + +@implementation InMemoryKCSK +- (void)dealloc +{ + if (_refKey) { + free(_refKey); + } +} + ++ (instancetype)kcskWithRefKey:(aks_ref_key_t)refKey wrappedKey:(NSData*)wrappedKey key:(SFECKeyPair*)key +{ + InMemoryKCSK* kcsk = [InMemoryKCSK new]; + kcsk.refKey = refKey; + kcsk.wrappedKey = wrappedKey; + kcsk.key = key; + return kcsk; +} + +@end + +@interface SecDbBackupManager () { + dispatch_queue_t _queue; + keybag_handle_t _handle; + SecDbBackupBagIdentity* _bagIdentity; + NSMutableDictionary* _cachedKCSKs; +} +@end + +@implementation SecDbBackupManager + +#pragma mark - Misc Helpers + +- (NSData*)getSHA256OfData:(NSData*)data +{ + NSMutableData* digest = [[NSMutableData alloc] initWithLength:CC_SHA512_DIGEST_LENGTH]; + if (!CC_SHA512(data.bytes, (CC_LONG)data.length, digest.mutableBytes)) { + return nil; + } + return digest; +} + +- (void)setBagIdentity:(SecDbBackupBagIdentity *)bagIdentity +{ + _bagIdentity = bagIdentity; +} + +- (SecDbBackupBagIdentity*)bagIdentity +{ + return _bagIdentity; +} + +- (bool)fillError:(NSError**)error code:(enum SecDbBackupErrorCode)code underlying:(NSError*)underlying description:(NSString*)format, ... NS_FORMAT_FUNCTION(4, 5) +{ + if (error) { + va_list ap; + va_start(ap, format); + NSString* desc = [[NSString alloc] initWithFormat:format arguments:ap]; + va_end(ap); + if (underlying) { + *error = [NSError errorWithDomain:KeychainBackupsErrorDomain code:code description:desc underlying:underlying]; + } else { + *error = [NSError errorWithDomain:KeychainBackupsErrorDomain code:code description:desc]; + } + } + + // analyzer gets upset when a method taking an error** doesn't return a value + return true; +} + +static SecDbBackupManager* staticManager; ++ (instancetype)manager +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + staticManager = [SecDbBackupManager new]; + }); + return staticManager; +} + +// Testing only please ++ (void)resetManager +{ + if (staticManager) { + staticManager = [SecDbBackupManager new]; + } +} + +- (instancetype)init +{ + if (!checkV12DevEnabled()) { + return nil; + } + if (self = [super init]) { + _queue = dispatch_queue_create("com.apple.security.secdbbackupmanager", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _handle = bad_keybag_handle; + _cachedKCSKs = [NSMutableDictionary new]; + } + return self; +} + +- (SFECKeyPair*)getECKeyPairFromDERBytes:(void*)bytes length:(size_t)len error:(NSError**)error +{ + if (!bytes || len == 0) { + [self fillError:error code:SecDbBackupInvalidArgument underlying:nil description:@"Need valid byte buffer to make EC keypair from"]; + return nil; + } + CFTypeRef cftype = NULL; + CFErrorRef cferr = NULL; + const uint8_t* derp = der_decode_plist(kCFAllocatorDefault, NSPropertyListImmutable, &cftype, &cferr, bytes, bytes + len); + free(bytes); + if (derp == NULL || derp != (bytes + len) || cftype == NULL) { + [self fillError:error code:SecDbBackupMalformedKCSKDataOnDisk underlying:CFBridgingRelease(cferr) description:@"Unable to parse der data"]; + return nil; + } + + return [[SFECKeyPair alloc] initWithData:(__bridge_transfer NSData*)cftype + specifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384] + error:error]; +} + +#pragma mark - Fixup And Verification + +- (void)verifyBackupIntegrity:(bool)lightweight + completion:(void (^)(NSDictionary* _Nonnull, NSError * _Nullable))completion +{ + NSError* error = nil; + completion(@{@"summary" : @"Unimplemented"}, error); +} + +#pragma mark - Backup Bag Management + +// Get the bag's UUID from AKS and the hash from provided data. This must always be the original bag's data +- (SecDbBackupBagIdentity*)bagIdentityWithHandle:(keybag_handle_t)handle data:(NSData*)data error:(NSError**)error { + assert(data); + secnotice("SecDbBackup", "Getting bag identity"); + SecDbBackupBagIdentity* identity = [SecDbBackupBagIdentity new]; + + uuid_t uuid = {0}; + kern_return_t aksResult = aks_get_bag_uuid(handle, uuid); + if (aksResult != kAKSReturnSuccess) { + [self fillError:error code:SecDbBackupAKSFailure underlying:nil description:@"Unable to get keybag UUID (%d)", aksResult]; + return nil; + } + identity.baguuid = [NSData dataWithBytes:uuid length:16]; + + NSData* digest = [self getSHA256OfData:data]; + if (!digest) { + [self fillError:error code:SecDbBackupCryptoFailure underlying:nil description:@"CC_SHA512 returned failure, can't get bag hash"]; + return nil; + } + identity.baghash = digest; + + secnotice("SecDbBackup", "Obtained bag identity: %@", identity); + + return identity; +} + +- (NSData*)createBackupBagSecret:(NSError**)error +{ + uint8_t* data = calloc(1, BACKUPBAG_PASSPHRASE_LENGTH); + if (!data) { + return nil; // Good luck allocating an error message + } + + CCRNGStatus rngResult = CCRandomGenerateBytes(data, BACKUPBAG_PASSPHRASE_LENGTH); + if (rngResult != kCCSuccess) { + [self fillError:error code:SecDbBackupCryptoFailure underlying:nil description:@"Unable to generate random bytes (%d)", rngResult]; + return nil; + } + + NSData* secret = [NSData _newZeroingDataWithBytesNoCopy:data length:BACKUPBAG_PASSPHRASE_LENGTH deallocator:NSDataDeallocatorNone]; + return secret; +} + +- (keybag_handle_t)onQueueCreateBackupBagWithSecret:(NSData*)secret error:(NSError**)error +{ + dispatch_assert_queue(_queue); + + keybag_handle_t handle = bad_keybag_handle; + kern_return_t aksresult = aks_create_bag(secret.bytes, BACKUPBAG_PASSPHRASE_LENGTH, kAppleKeyStoreAsymmetricBackupBag, &handle); + if (aksresult != kAKSReturnSuccess) { + [self fillError:error code:SecDbBackupAKSFailure underlying:nil description:@"Unable to create keybag (%d)", aksresult]; + return bad_keybag_handle; + } + + // Make secret keys unavailable. Causes pubkeys to be destroyed so reload bag before use + aksresult = aks_lock_bag(handle); + if (aksresult != kAKSReturnSuccess) { // This would be rather surprising + [self fillError:error code:SecDbBackupAKSFailure underlying:nil description:@"Unable to lock keybag (%d)", aksresult]; + aks_unload_bag(handle); + return bad_keybag_handle; + } + + return handle; +} + +- (BOOL)onQueueInTransaction:(SecDbConnectionRef)dbt saveBackupBag:(keybag_handle_t)handle asDefault:(BOOL)asDefault error:(NSError**)error +{ + dispatch_assert_queue(_queue); + + void* buf = NULL; + int buflen = 0; + kern_return_t aksResult = aks_save_bag(handle, &buf, &buflen); + if (aksResult != kAKSReturnSuccess) { + [self fillError:error code:SecDbBackupAKSFailure underlying:nil description:@"Unable to serialize keybag (%d)", aksResult]; + return NO; + } + NSData* bagData = [NSData dataWithBytesNoCopy:buf length:buflen]; + + SecDbBackupBagIdentity* bagIdentity = [self bagIdentityWithHandle:handle data:bagData error:error]; + if (!bagIdentity) { + return NO; + } + SecDbBackupBag* bag = [SecDbBackupBag new]; + bag.bagIdentity = bagIdentity; + bag.keybag = bagData; + + __block CFErrorRef cfError = NULL; + __block bool ok = true; + if (asDefault) { + ok &= SecDbPrepare(dbt, CFSTR("UPDATE backupbags SET defaultvalue = 0 WHERE defaultvalue = 1"), &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { + // FIXME: Should this be an error? Should something else happen? + secwarning("SecDbBackup: Marking existing bag as non-default"); + }); + }); + } + if (!ok) { + return ok; + } + ok &= SecDbPrepare(dbt, CFSTR("INSERT INTO backupbags (backupUUID, backupbag, defaultvalue) VALUES (?,?,?)"), &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbBindObject(stmt, 1, (__bridge CFDataRef)bag.bagIdentity.baguuid, &cfError); + ok &= SecDbBindObject(stmt, 2, (__bridge CFDataRef)bag.data, &cfError); + ok &= SecDbBindInt(stmt, 3, asDefault ? 1 : 0, &cfError); + ok &= SecDbStep(dbt, stmt, &cfError, NULL); + }); + + if (!ok) { + secerror("SecDbBackup: unable to save keybag to disk: %@", cfError); + [self fillError:error code:SecDbBackupWriteFailure underlying:CFBridgingRelease(cfError) description:@"Unable to save keybag to disk"]; + } + + return ok; +} + +- (keybag_handle_t)onQueueLoadBackupBag:(NSUUID*)uuid error:(NSError**)error { + dispatch_assert_queue(_queue); + + secnotice("SecDbBackup", "Attempting to load backup bag from disk"); + + __block CFErrorRef localErr = NULL; + __block bool ok = true; + __block NSData* readUUID; + __block NSData* readBagData; + __block unsigned found = 0; + ok &= kc_with_dbt_non_item_tables(false, &localErr, ^bool(SecDbConnectionRef dbt) { + NSString* sql = [NSString stringWithFormat:@"SELECT backupUUID, backupbag FROM backupbags WHERE %@", uuid ? @"backupUUID = ?" : @"defaultvalue = 1"]; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &localErr, ^(sqlite3_stmt *stmt) { + if (uuid) { + unsigned char uuidbytes[UUIDBYTESLENGTH] = {0}; + [uuid getUUIDBytes:uuidbytes]; + ok &= SecDbBindBlob(stmt, 1, uuidbytes, UUIDBYTESLENGTH, SQLITE_TRANSIENT, &localErr); + } + ok &= SecDbStep(dbt, stmt, &localErr, ^(bool *stop) { + if (found > 0) { // For uuids this should have violated constraints + secerror("Encountered more than one backup bag by %@", uuid ? @"backupUUID" : @"defaultvalue"); + *stop = true; + } + readUUID = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; + readBagData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 1) length:sqlite3_column_bytes(stmt, 1)]; + ++found; + }); + }); + return ok; + }); + + if (!ok) { + secerror("SecDbBackup: Unable to load backup bag from disk: %@", localErr); + [self fillError:error code:SecDbBackupWriteFailure underlying:CFBridgingRelease(localErr) description:@"Unable to load backup bag from disk"]; + return bad_keybag_handle; + } + + if (!found) { + [self fillError:error code:SecDbBackupNoBackupBagFound underlying:nil description:@"No backup bag found to load from disk"]; + return bad_keybag_handle; + } else if (found > 1) { + [self fillError:error + code:uuid ? SecDbBackupDuplicateBagFound : SecDbBackupMultipleDefaultBagsFound + underlying:nil + description:@"More than one backup bag found"]; + return bad_keybag_handle; + } + + if (!readUUID || readUUID.length != UUIDBYTESLENGTH || !readBagData || !readBagData.length) { + [self fillError:error code:SecDbBackupMalformedBagDataOnDisk underlying:nil description:@"bags read from disk malformed"]; + return bad_keybag_handle; + } + + SecDbBackupBag* readBag = [[SecDbBackupBag alloc] initWithData:readBagData]; + if (!readBag) { + [self fillError:error code:SecDbBackupDeserializationFailure underlying:nil description:@"bag from disk does not deserialize"]; + return bad_keybag_handle; + } + + secnotice("SecDbBackup", "Successfully read backup bag from disk; loading and verifying. Read bag ID: %@", readBag.bagIdentity); + + keybag_handle_t handle = bad_keybag_handle; + kern_return_t aksResult = aks_load_bag(readBag.keybag.bytes, (int)readBag.keybag.length, &handle); + if (aksResult != kAKSReturnSuccess) { + [self fillError:error code:SecDbBackupAKSFailure underlying:nil description:@"Unable to load bag from disk (%d)", aksResult]; + return bad_keybag_handle; + } + + SecDbBackupBagIdentity* loadedID = [self bagIdentityWithHandle:handle data:readBag.keybag error:error]; + if (!loadedID) { + aks_unload_bag(handle); + return bad_keybag_handle; + } + + if (memcmp(loadedID.baguuid.bytes, readBag.bagIdentity.baguuid.bytes, UUIDBYTESLENGTH) || + memcmp(loadedID.baguuid.bytes, readUUID.bytes, UUIDBYTESLENGTH)) { + [self fillError:error code:SecDbBackupUUIDMismatch underlying:nil description:@"Loaded UUID does not match UUIDs on disk"]; + aks_unload_bag(handle); + return bad_keybag_handle; + } + + if (memcmp(loadedID.baghash.bytes, readBag.bagIdentity.baghash.bytes, CC_SHA512_DIGEST_LENGTH)) { + [self fillError:error code:SecDbBackupDeserializationFailure underlying:nil description:@"Keybag hash does not match its identity's hash"]; + return bad_keybag_handle; + } + + // TODO: verify that bag is still signed, rdar://problem/46702467 + + secnotice("SecDbBackup", "Backup bag loaded and verified."); + + // Must load readBag's identity because the hash from AKS is unstable. + // This is the hash of the original saved bag and is anchored in the KCSKes. + _bagIdentity = readBag.bagIdentity; + + return handle; +} + +- (BOOL)onQueueReloadDefaultBackupBagWithError:(NSError**)error +{ + if (_handle != bad_keybag_handle) { + aks_unload_bag(_handle); + } + + _handle = [self onQueueLoadBackupBag:nil error:error]; + return _handle != bad_keybag_handle; +} + +#pragma mark - KCSK Management + +- (SecDbBackupKeyClassSigningKey*)createKCSKForKeyClass:(keyclass_t)class withWrapper:(SFAESKey*)wrapper error:(NSError**)error +{ + if (!wrapper) { + [self fillError:error code:SecDbBackupInvalidArgument underlying:nil description:@"Need wrapper for KCSK"]; + return nil; + } + + SecDbBackupKeyClassSigningKey* kcsk = [SecDbBackupKeyClassSigningKey new]; + kcsk.keyClass = class; + + SFECKeyPair* keypair = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + kcsk.publicKey = [keypair.publicKey.keyData copy]; + + // Create a DER-encoded dictionary of bag identity + void* der_blob; + size_t der_len; + CFErrorRef cfErr = NULL; + NSDictionary* identDict = @{@"baguuid" : _bagIdentity.baguuid, @"baghash" : _bagIdentity.baghash}; + NSData* identData = (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)identDict, &cfErr); + aks_operation_optional_params(NULL, 0, identData.bytes, identData.length, NULL, 0, &der_blob, &der_len); + + // Create ref key with embedded bag identity DER data + aks_ref_key_t refkey = NULL; + kern_return_t aksResult = aks_ref_key_create(KEYBAG_DEVICE, class, key_type_sym, der_blob, der_len, &refkey); + free(der_blob); + if (aksResult != kAKSReturnSuccess) { + [self fillError:error code:SecDbBackupAKSFailure underlying:nil + description:@"Unable to create AKS ref key for KCSK class %d: %d", class, aksResult]; + return nil; + } + + size_t refkeyblobsize = 0; + const uint8_t* refkeyblob = aks_ref_key_get_blob(refkey, &refkeyblobsize); + kcsk.aksRefKey = [NSData dataWithBytes:refkeyblob length:refkeyblobsize]; + + size_t wrappedKeyLen = 0; + void* wrappedKey = NULL; + NSData* keypairAsData = keypair.keyData; + aksResult = aks_ref_key_encrypt(refkey, NULL, 0, keypairAsData.bytes, keypairAsData.length, &wrappedKey, &wrappedKeyLen); + if (aksResult != kAKSReturnSuccess) { + [self fillError:error code:SecDbBackupAKSFailure underlying:nil + description:@"Unable to encrypt KCSK class %d with AKS ref key: %d", class, aksResult]; + return nil; + } + aks_ref_key_free(&refkey); + kcsk.aksWrappedKey = [NSData dataWithBytesNoCopy:wrappedKey length:wrappedKeyLen]; + + // Also add DER-encoded bag identity here + SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]]; + SFAuthenticatedCiphertext* backupwrapped = [op encrypt:keypair.keyData withKey:wrapper additionalAuthenticatedData:identData error:error]; + kcsk.backupWrappedKey = [NSKeyedArchiver archivedDataWithRootObject:backupwrapped requiringSecureCoding:YES error:error]; + if (!kcsk.backupWrappedKey) { + return nil; + } + + return kcsk; +} + +- (BOOL)inTransaction:(SecDbConnectionRef)dbt writeKCSKToKeychain:(SecDbBackupKeyClassSigningKey*)kcsk error:(NSError**)error +{ + __block bool ok = true; + __block CFErrorRef cfError = NULL; + NSString* sql = @"INSERT INTO backupkeyclasssigningkeys (keyclass, backupUUID, signingkey) VALUES (?, ?, ?)"; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbBindInt(stmt, 1, kcsk.keyClass, &cfError); + ok &= SecDbBindObject(stmt, 2, (__bridge CFTypeRef)(self->_bagIdentity.baguuid), &cfError); + ok &= SecDbBindObject(stmt, 3, (__bridge CFTypeRef)(kcsk.data), &cfError); + ok &= SecDbStep(dbt, stmt, &cfError, NULL); + }); + + if (!ok) { + secerror("SecDbBackup: Unable to write KCSK for class %d to keychain: %@", kcsk.keyClass, cfError); + [self fillError:error code:SecDbBackupWriteFailure underlying:CFBridgingRelease(cfError) description:@"Unable to write KCSK for class %d to keychain", kcsk.keyClass]; + } + + return ok; +} + +- (InMemoryKCSK*)onQueueReadKCSKFromDiskForClass:(keyclass_t)keyclass error:(NSError**)error +{ + __block bool ok = true; + __block CFErrorRef cfError = NULL; + __block NSData* readUUID; + __block NSData* readKCSK; + NSString* sql = @"SELECT backupUUID, signingkey FROM backupkeyclasssigningkeys WHERE keyclass = ?"; + ok &= kc_with_dbt_non_item_tables(NO, &cfError, ^bool(SecDbConnectionRef dbt) { + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbBindInt(stmt, 1, keyclass, &cfError); + ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { + readUUID = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; + readKCSK = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 1) length:sqlite3_column_bytes(stmt, 1)]; + }); + }); + return ok; + }); + if (!readKCSK || !readUUID) { + [self fillError:error code:SecDbBackupNoKCSKFound underlying:nil description:@"KCSK for class %d not on disk", keyclass]; + return nil; + } + + SecDbBackupKeyClassSigningKey* kcsk = [[SecDbBackupKeyClassSigningKey alloc] initWithData:readKCSK]; + if (!kcsk) { + [self fillError:error code:SecDbBackupMalformedKCSKDataOnDisk underlying:nil description:@"Retrieved KCSK blob but it didn't become a KCSK"]; + return nil; + } + + aks_ref_key_t refkey = NULL; + kern_return_t aksResult = aks_ref_key_create_with_blob(KEYBAG_DEVICE, kcsk.aksRefKey.bytes, kcsk.aksRefKey.length, &refkey); + if (aksResult != kAKSReturnSuccess) { + [self fillError:error + code:SecDbBackupAKSFailure + underlying:nil + description:@"Failed to create refkey from KCSK blob for class %d: %d", keyclass, aksResult]; + return nil; + } + + size_t externalDataLen = 0; + const uint8_t* externalData = aks_ref_key_get_external_data(refkey, &externalDataLen); + NSData* derBagIdent = [NSData dataWithBytes:externalData length:externalDataLen]; + CFErrorRef cfErr = NULL; + NSDictionary* identData = (__bridge_transfer NSDictionary*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)derBagIdent, 0, NULL, &cfErr); + if (!identData || ![_bagIdentity.baghash isEqualToData:identData[@"baghash"]] || ![_bagIdentity.baguuid isEqualToData:identData[@"baguuid"]]) { + secerror("SecDbBackup: KCSK ref key embedded bag identity does not match loaded bag. %@ vs %@", identData, _bagIdentity); + [self fillError:error code:SecDbBackupMalformedKCSKDataOnDisk underlying:CFBridgingRelease(cfErr) description:@"KCSK ref key embedded bag identity does not match loaded bag."]; + return nil; + } + + // AKS refkey claims in its external data to belong to our backup bag. Let's see if the claim holds up: use the key. + void* keypairBytes = NULL; + size_t keypairLength = 0; + aksResult = aks_ref_key_decrypt(refkey, NULL, 0, kcsk.aksWrappedKey.bytes, kcsk.aksWrappedKey.length, &keypairBytes, &keypairLength); + if (aksResult == kSKSReturnNoPermission) { + [self fillError:error code:SecDbBackupKeychainLocked underlying:nil description:@"Unable to unwrap KCSK private key for class %d. Locked", keyclass]; + return nil; + } else if (aksResult != kAKSReturnSuccess) { + // Failure could indicate key was corrupted or tampered with + [self fillError:error + code:SecDbBackupAKSFailure + underlying:nil + description:@"AKS did not unwrap KCSK private key for class %d: %d", keyclass, aksResult]; + return nil; + } + + SFECKeyPair* keypair = [self getECKeyPairFromDERBytes:keypairBytes length:keypairLength error:error]; + return keypair ? [InMemoryKCSK kcskWithRefKey:refkey wrappedKey:kcsk.aksWrappedKey key:keypair] : nil; +} + +- (SFECKeyPair*)onQueueFetchKCSKForKeyclass:(keyclass_t)keyclass error:(NSError**)error +{ + assert(error); + assert(_bagIdentity); + assert(_handle != bad_keybag_handle); + + InMemoryKCSK* cached = _cachedKCSKs[@(keyclass)]; + if (cached.key) { + return cached.key; + } + + if (cached) { + secnotice("SecDbBackup", "Cached but wrapped KCSK found for class %d, unwrapping", keyclass); + void* keybytes = NULL; + size_t keylen = 0; + kern_return_t aksResult = aks_ref_key_decrypt(cached.refKey, NULL, 0, cached.wrappedKey.bytes, cached.wrappedKey.length, &keybytes, &keylen); + if (aksResult == kAKSReturnSuccess) { + cached.key = [self getECKeyPairFromDERBytes:keybytes length:keylen error:error]; + return cached.key; + } else { + secerror("SecDbBackup: Cached KCSK isn't unwrapping key material. This is a bug."); + } + } + + secnotice("SecDbBackup", "No cached KCSK for class %d, reading from disk", keyclass); + cached = [self onQueueReadKCSKFromDiskForClass:keyclass error:error]; + if (!cached.key) { + secerror("SecDbBackup: Failed to obtain KCSK for class %d: %@", keyclass, *error); + if ((*error).code != SecDbBackupKeychainLocked) { + seccritical("SecDbBackup: KCSK unavailable, cannot backup-wrap class %d items. Need to perform recovery.", keyclass); + // TODO: We're borked. Need to recover from this. + } + } + _cachedKCSKs[@(keyclass)] = cached; + return cached.key; +} + +#pragma mark - Recovery Set Management + +- (BOOL)onQueueInTransaction:(SecDbConnectionRef)dbt writeRecoverySetToKeychain:(SecDbBackupRecoverySet*)set error:(NSError**)error +{ + dispatch_assert_queue(_queue); + __block bool ok = true; + __block CFErrorRef cfError = NULL; + + NSString* sql = @"INSERT INTO backuprecoverysets (backupUUID, recoverytype, recoveryset) VALUES (?, ?, ?)"; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbBindObject(stmt, 1, (__bridge CFDataRef)set.bagIdentity.baguuid, &cfError); + ok &= SecDbBindObject(stmt, 2, (__bridge CFNumberRef)@(set.recoveryType), &cfError); + ok &= SecDbBindObject(stmt, 3, (__bridge CFDataRef)set.data, &cfError); + ok &= SecDbStep(dbt, stmt, &cfError, NULL); + }); + + if (!ok) { + secerror("SecDbBackup: Unable to write recovery set to keychain: %@", cfError); + [self fillError:error code:SecDbBackupWriteFailure underlying:CFBridgingRelease(cfError) description:@"Unable to write recovery set to keychain"]; + } + + return ok; +} + +- (SecDbBackupRecoverySet*)onQueueInTransaction:(SecDbConnectionRef)dbt createRecoverySetWithBagSecret:(NSData*)secret + forType:(SecDbBackupRecoveryType)type error:(NSError**)error +{ + dispatch_assert_queue(_queue); + if (!secret) { + [self fillError:error code:SecDbBackupInvalidArgument underlying:nil description:@"Can't create recovery set without secret"]; + return nil; + } + + SecDbBackupRecoverySet* set; + switch (type) { + case SecDbBackupRecoveryTypeAKS: + set = [self inTransaction:dbt createAKSTypeRecoverySetWithBagSecret:secret handle:_handle error:error]; + break; + case SecDbBackupRecoveryTypeCylon: + secerror("SecDbBackup: Cylon recovery type not yet implemented"); + [self fillError:error code:SecDbBackupUnknownOption underlying:nil description:@"Recovery type Cylon not yet implemented"]; + break; + case SecDbBackupRecoveryTypeRecoveryKey: + secerror("SecDbBackup: RecoveryKey recovery type not yet implemented"); + [self fillError:error code:SecDbBackupUnknownOption underlying:nil description:@"Recovery type RecoveryKey not yet implemented"]; + break; + default: + secerror("SecDbBackup: Unknown type %ld", (long)type); + [self fillError:error code:SecDbBackupUnknownOption underlying:nil description:@"Recovery type %li unknown", (long)type]; + break; + } + + return set; +} + +- (SecDbBackupRecoverySet*)inTransaction:(SecDbConnectionRef)dbt createAKSTypeRecoverySetWithBagSecret:(NSData*)secret handle:(keybag_handle_t)handle error:(NSError**)error +{ + SecDbBackupRecoverySet* set = [SecDbBackupRecoverySet new]; + set.recoveryType = SecDbBackupRecoveryTypeAKS; + set.bagIdentity = _bagIdentity; + + NSError* cryptoError; + SFAESKeySpecifier* specifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; + SFAESKey* KCSKSecret = [[SFAESKey alloc] initRandomKeyWithSpecifier:specifier error:&cryptoError]; + if (!KCSKSecret) { + [self fillError:error code:SecDbBackupCryptoFailure underlying:cryptoError description:@"Unable to create AKS recovery set"]; + return nil; + } + + // We explicitly do NOT want akpu. For the rest, create and write all KCSKs + for (NSNumber* class in @[@(key_class_ak), @(key_class_ck), @(key_class_dk), @(key_class_aku), @(key_class_cku), @(key_class_dku)]) { + SecDbBackupKeyClassSigningKey* kcsk = [self createKCSKForKeyClass:[class intValue] withWrapper:KCSKSecret error:error]; + if (!kcsk) { + secerror("SecDbBackup: Unable to create KCSK for class %@: %@", class, *error); + return nil; + } + if (![self inTransaction:dbt writeKCSKToKeychain:kcsk error:error]) { + secerror("SecDbBackup: Unable to write KCSK for class %@ to keychain: %@", class, *error); + return nil; + } + } + + SFAESKey* recoverykey = [[SFAESKey alloc] initRandomKeyWithSpecifier:specifier error:&cryptoError]; + if (!recoverykey) { + [self fillError:error code:SecDbBackupCryptoFailure underlying:cryptoError description:@"Unable to create recovery key"]; + return nil; + } + + SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] + initWithKeySpecifier:[[SFAESKeySpecifier alloc] + initWithBitSize:SFAESKeyBitSize256]]; + SFAuthenticatedCiphertext* wrappedsecret = [op encrypt:secret withKey:recoverykey error:&cryptoError]; + if (!wrappedsecret) { + secerror("SecDbBackup: Unable to wrap keybag secret: %@", cryptoError); + [self fillError:error code:SecDbBackupCryptoFailure underlying:cryptoError description:@"Unable to wrap keybag secret"]; + return nil; + } + set.wrappedBagSecret = [NSKeyedArchiver archivedDataWithRootObject:wrappedsecret requiringSecureCoding:YES error:error]; + + SFAuthenticatedCiphertext* wrappedkcsksecret = [op encrypt:KCSKSecret.keyData withKey:recoverykey error:&cryptoError]; + if (!wrappedkcsksecret) { + secerror("SecDbBackup: Unable to wrap KCSK secret: %@", cryptoError); + [self fillError:error code:SecDbBackupCryptoFailure underlying:cryptoError description:@"Unable to wrap KCSK secret"]; + return nil; + } + set.wrappedKCSKSecret = [NSKeyedArchiver archivedDataWithRootObject:wrappedkcsksecret requiringSecureCoding:YES error:error]; + + NSMutableData* wrappedrecoverykey = [[NSMutableData alloc] initWithLength:APPLE_KEYSTORE_MAX_SYM_WRAPPED_KEY_LEN]; + if (![SecAKSObjCWrappers aksEncryptWithKeybag:KEYBAG_DEVICE keyclass:key_class_aku plaintext:recoverykey.keyData outKeyclass:nil ciphertext:wrappedrecoverykey error:&cryptoError]) { + secerror("SecDbBackup: Unable to wrap recovery key to AKS: %@", cryptoError); + [self fillError:error code:SecDbBackupAKSFailure underlying:cryptoError description:@"Unable to wrap recovery key to AKS"]; + return nil; + } + set.wrappedRecoveryKey = [wrappedrecoverykey copy]; + + return set; +} + +#pragma mark - Backup System Initialization / Maintenance + +- (BOOL)createOrLoadBackupInfrastructure:(NSError**)error { + assert(error); + __block BOOL ok = true; + __block NSError* localError; + dispatch_sync(_queue, ^{ + ok = [self onQueueCreateOrLoadBackupInfrastructure:&localError]; + }); + + if (localError) { + *error = localError; + } + return ok; +} + +// TODO: if this creates the infrastructure, kick off a fixup routine +// TODO: if not, make sure we actually delete stuff. Nested transactions are not a thing (use checkpointing or delete explicitly) + +- (BOOL)onQueueCreateOrLoadBackupInfrastructure:(NSError**)error { + dispatch_assert_queue(_queue); + assert(error); + if (self->_handle != bad_keybag_handle) { + return true; + } + + self->_handle = [self onQueueLoadBackupBag:nil error:error]; + if (self->_handle != bad_keybag_handle) { + secnotice("SecDbBackup", "Keybag found and loaded"); + return true; + } else if (self->_handle == bad_keybag_handle && (*error).code != SecDbBackupNoBackupBagFound) { + return false; + } + *error = nil; + + __block BOOL ok = YES; + __block CFErrorRef cfError = NULL; + __block NSError* localError; + secnotice("SecDbBackup", "CreateOrLoad: No backup bag found, attempting to create new infrastructure"); + if (ok && !SecAKSDoWithUserBagLockAssertion(&cfError, ^{ + ok &= kc_with_dbt_non_item_tables(YES, &cfError, ^bool(SecDbConnectionRef dbt) { + ok &= kc_transaction(dbt, &cfError, ^bool{ + NSData* secret = [self createBackupBagSecret:&localError]; + if (!secret) { + return false; + } + + self->_handle = [self onQueueCreateBackupBagWithSecret:secret error:&localError]; + if (self->_handle == bad_keybag_handle) { + return false; + } + secnotice("SecDbBackup", "CreateOrLoad: Successfully created backup bag"); + + if (![self onQueueInTransaction:dbt saveBackupBag:self->_handle asDefault:YES error:&localError]) { + return false; + } + secnotice("SecDbBackup", "CreateOrLoad: Successfully saved backup bag"); + + if (![self onQueueReloadDefaultBackupBagWithError:&localError]) { + return false; + } + secnotice("SecDbBackup", "CreateOrLoad: Successfully reloaded backup bag"); + + SecDbBackupRecoverySet* set = [self onQueueInTransaction:dbt + createRecoverySetWithBagSecret:secret + forType:SecDbBackupRecoveryTypeAKS + error:&localError]; + if (!set) { + secnotice("SecDbBackup", "CreateOrLoad: Successfully created recovery set"); + return false; + } + + if (![self onQueueInTransaction:dbt writeRecoverySetToKeychain:set error:&localError]) { + return false; + } + secnotice("SecDbBackup", "CreateOrLoad: Successfully saved recovery set"); + + return true; + }); + return ok; + }); + })) { // could not perform action with lock assertion + static dispatch_once_t once; + static sec_action_t action; + dispatch_once(&once, ^{ + action = sec_action_create("keybag_locked_during_backup_setup_complaint", 5); + sec_action_set_handler(action, ^{ + secerror("SecDbBackup: Cannot obtain AKS lock assertion so cannot setup backup infrastructure"); + }); + }); + sec_action_perform(action); + [self fillError:&localError code:SecDbBackupKeychainLocked underlying:nil + description:@"Unable to initialize backup infrastructure, keychain locked"]; + ok = NO; + } + + if (!ok) { + self->_bagIdentity = nil; + aks_unload_bag(self->_handle); + self->_handle = bad_keybag_handle; + } + + if (ok) { + secnotice("SecDbBackup", "Hurray! Successfully created backup infrastructure"); + } else { + assert(localError || cfError); + if (localError) { + secerror("SecDbBackup: Could not initialize backup infrastructure: %@", localError); + *error = localError; + } else if (cfError) { + secerror("SecDbBackup: Could not initialize backup infrastructure: %@", cfError); + [self fillError:error code:SecDbBackupSetupFailure underlying:CFBridgingRelease(cfError) + description:@"Unable to initialize backup infrastructure"]; + } else { + secerror("SecDbBackup: Could not initialize backup infrastructure but have no error"); + [self fillError:error code:SecDbBackupSetupFailure underlying:nil + description:@"Unable to initialize backup infrastructure (not sure why)"]; + } + CFReleaseNull(cfError); + } + + return ok; +} + +#pragma mark - Item Encryption + +- (SecDbBackupWrappedItemKey*)wrapItemKey:(SFAESKey*)key forKeyclass:(keyclass_t)keyclass error:(NSError**)error +{ + assert(error); + if (keyclass == key_class_akpu) { + secwarning("SecDbBackup: Don't tempt me Frodo!"); + [self fillError:error code:SecDbBackupInvalidArgument underlying:nil description:@"Do not call wrapItemKey with class akpu"]; + return nil; + } + + if (![self createOrLoadBackupInfrastructure:error]) { + if ((*error).domain != (__bridge NSString*)kSecErrorDomain || (*error).code != errSecInteractionNotAllowed) { + secerror("SecDbBackup: Could not create/load backup infrastructure: %@", *error); + } + return nil; + } + + __block SecDbBackupWrappedItemKey* backupWrappedKey; + + __block NSMutableData* wrappedKey = [NSMutableData dataWithLength:APPLE_KEYSTORE_MAX_ASYM_WRAPPED_KEY_LEN]; + __block NSError* localError; + dispatch_sync(_queue, ^{ + if (![self onQueueCreateOrLoadBackupInfrastructure:&localError]) { + return; + } + if (![SecAKSObjCWrappers aksEncryptWithKeybag:self->_handle + keyclass:keyclass + plaintext:key.keyData + outKeyclass:nil + ciphertext:wrappedKey + error:&localError]) { + return; + } + SFSignedData* wrappedAndSigned = [self onQueueSignData:wrappedKey withKCSKForKeyclass:keyclass error:&localError]; + if (!wrappedAndSigned) { + if (localError.code != SecDbBackupKeychainLocked) { + secerror("SecDbBackup: Unable to sign item for class %d: %@", keyclass, localError); + return; + } + } + backupWrappedKey = [SecDbBackupWrappedItemKey new]; + backupWrappedKey.wrappedKey = [NSKeyedArchiver archivedDataWithRootObject:wrappedAndSigned requiringSecureCoding:YES error:&localError]; + backupWrappedKey.baguuid = self->_bagIdentity.baguuid; + }); + + if (localError) { + secerror("SecDbBackup: Unable to wrap-and-sign item of class %d: %@", keyclass, localError); + *error = localError; + return nil; + } + + return backupWrappedKey; +} + +- (SFSignedData*)onQueueSignData:(NSMutableData*)data withKCSKForKeyclass:(keyclass_t)keyclass error:(NSError**)error +{ + SFECKeyPair* kcsk = [self onQueueFetchKCSKForKeyclass:keyclass error:error]; + if (!kcsk) { + return nil; + } + + SFEC_X962SigningOperation* op = [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + return [op sign:data withKey:kcsk error:error]; +} + +#pragma mark - Testing Helpers + +- (keybag_handle_t)createBackupBagWithSecret:(NSData*)secret error:(NSError**)error +{ + assert(error); + __block keybag_handle_t handle = bad_keybag_handle; + __block NSError* localError; + dispatch_sync(_queue, ^{ + handle = [self onQueueCreateBackupBagWithSecret:secret error:&localError]; + }); + if (localError) { + *error = localError; + } else if (handle == bad_keybag_handle) { + [self fillError:error code:SecDbBackupTestCodeFailure underlying:nil description:@"Unable to create backup bag, but no reason"]; + } + return handle; +} + +- (BOOL)saveBackupBag:(keybag_handle_t)handle asDefault:(BOOL)asDefault error:(NSError**)error +{ + assert(error); + __block bool ok = true; + __block NSError* localErr; + __block CFErrorRef cfError = NULL; + dispatch_sync(_queue, ^{ + ok &= kc_with_dbt_non_item_tables(YES, &cfError, ^bool(SecDbConnectionRef dbt) { + ok &= kc_transaction(dbt, &cfError, ^bool{ + ok &= [self onQueueInTransaction:dbt saveBackupBag:handle asDefault:asDefault error:&localErr]; + return ok; + }); + return ok; + }); + }); + + if (!ok) { + if (cfError) { + [self fillError:error code:SecDbBackupTestCodeFailure underlying:CFBridgingRelease(cfError) description:@"Unable to save keybag to disk"]; + } else if (localErr) { + *error = localErr; + } else if (!localErr) { + [self fillError:error code:SecDbBackupTestCodeFailure underlying:nil description:@"Unable to save keybag to disk but who knows why"]; + } + } + return ok; +} + +- (keybag_handle_t)loadBackupBag:(NSUUID*)uuid error:(NSError**)error { + __block keybag_handle_t handle = bad_keybag_handle; + __block NSError* localError; + dispatch_sync(_queue, ^{ + handle = [self onQueueLoadBackupBag:uuid error:&localError]; + }); + if (error && localError) { + *error = localError; + } + return handle; +} + +- (SecDbBackupRecoverySet*)createRecoverySetWithBagSecret:(NSData*)secret forType:(SecDbBackupRecoveryType)type error:(NSError**)error +{ + __block SecDbBackupRecoverySet* set; + __block BOOL ok = YES; + __block NSError* localError; + __block CFErrorRef cfError = NULL; + dispatch_sync(_queue, ^{ + ok &= kc_with_dbt_non_item_tables(true, &cfError, ^bool(SecDbConnectionRef dbt) { + ok &= kc_transaction(dbt, &cfError, ^bool{ + set = [self onQueueInTransaction:dbt createRecoverySetWithBagSecret:secret forType:type error:&localError]; + return set != nil; + }); + return ok; + }); + }); + if (error && cfError) { + *error = CFBridgingRelease(cfError); + } else if (error && localError) { + *error = localError; + } + CFReleaseNull(cfError); + + return set; +} + +- (SFECKeyPair*)fetchKCSKForKeyclass:(keyclass_t)keyclass error:(NSError**)error +{ + __block SFECKeyPair* keypair; + __block NSError* localError; + dispatch_sync(_queue, ^{ + keypair = [self onQueueFetchKCSKForKeyclass:keyclass error:&localError]; + }); + if (localError && error) { + *error = localError; + } + + return keypair; +} + +@end + +#endif // SECDB_BACKUPS_ENABLED diff --git a/OSX/sec/securityd/SecDbBackupManager_Internal.h b/OSX/sec/securityd/SecDbBackupManager_Internal.h new file mode 100644 index 00000000..71a3b3eb --- /dev/null +++ b/OSX/sec/securityd/SecDbBackupManager_Internal.h @@ -0,0 +1,72 @@ +/* + * 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@ + */ + +// DO NOT INCLUDE ME (unless you're SecDbBackupManager.m or a unit test) +// These are for internal use and testing only + +#ifndef SecDbBackupManager_Internal_h +#define SecDbBackupManager_Internal_h + +// Need these things in tests, too +#import "SecDbBackupManager.h" + +#if SECDB_BACKUPS_ENABLED + +#import "SecDbBackupBag.h" +#import "SecDbBackupBagIdentity.h" +#import "SecDbBackupKeyClassSigningKey.h" +#import "SecDbBackupMetadataClassKey.h" +#import "SecDbBackupRecoverySet.h" + +#include + +#import +#import +#import +#import + +@interface SecDbBackupManager (Internal) +@property (nonatomic) SecDbBackupBagIdentity* bagIdentity; + +#define BACKUPBAG_PASSPHRASE_LENGTH 32 +#define UUIDBYTESLENGTH 16 + ++ (void)resetManager; +- (NSData*)createBackupBagSecret:(NSError**)error; +- (keybag_handle_t)createBackupBagWithSecret:(NSData*)secret error:(NSError**)error; +- (BOOL)saveBackupBag:(keybag_handle_t)handle asDefault:(BOOL)asDefault error:(NSError**)error; +- (keybag_handle_t)loadBackupBag:(NSUUID*)uuid error:(NSError**)error; +- (BOOL)createOrLoadBackupInfrastructure:(NSError**)error; +- (SecDbBackupKeyClassSigningKey*)createKCSKForKeyClass:(keyclass_t)keyclass withWrapper:(SFAESKey*)wrapper error:(NSError**)error; +- (SecDbBackupRecoverySet*)createRecoverySetWithBagSecret:(NSData*)secret forType:(SecDbBackupRecoveryType)type error:(NSError**)error; +- (SFECKeyPair*)fetchKCSKForKeyclass:(keyclass_t)keyclass error:(NSError**)error; + +// Pure utilities +- (NSData*)getSHA256OfData:(NSData*)data; +- (SFECKeyPair*)ECKeyPairFromDerBytes:(void*)bytes length:(size_t)len error:(NSError**)error; + +@end + +#endif // SECDB_BACKUPS_ENABLED + +#endif /* SecDbBackupManager_Internal_h */ diff --git a/OSX/sec/securityd/SecDbItem.c b/OSX/sec/securityd/SecDbItem.c index 7e25b4d6..167e95d5 100644 --- a/OSX/sec/securityd/SecDbItem.c +++ b/OSX/sec/securityd/SecDbItem.c @@ -26,6 +26,12 @@ * database items (certificates, keys, identities, and passwords.) */ +#if TARGET_DARWINOS +#undef OCTAGON +#undef SECUREOBJECTSYNC +#undef SHAREDWEBCREDENTIALS +#endif + #include #include #include @@ -405,8 +411,9 @@ bool SecDbItemEnsureDecrypted(SecDbItemRef item, bool decryptSecretData, CFError // Only called if cached value is not found. static CFTypeRef SecDbItemCopyValue(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { - if (attr->copyValue) + if (attr->copyValue) { return attr->copyValue(item, attr, error); + } CFTypeRef value = NULL; switch (attr->kind) { @@ -1616,6 +1623,16 @@ static bool SecDbItemDeleteTombstone(SecDbItemRef item, SecDbConnectionRef dbcon } #endif +static bool +isCKKSEnabled(void) +{ +#if OCTAGON + return SecCKKSIsEnabled(); +#else + return false; +#endif +} + // Replace old_item with new_item. If primary keys are the same this does an update otherwise it does a delete + add bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnectionRef dbconn, CFBooleanRef makeTombstone, bool uuid_from_primary_key, CFErrorRef *error) { __block bool ok = true; @@ -1629,7 +1646,7 @@ bool SecDbItemUpdate(SecDbItemRef old_item, SecDbItemRef new_item, SecDbConnecti bool pk_equal = ok && CFEqual(old_pk, new_pk); if (pk_equal) { ok = SecDbItemMakeYounger(new_item, old_item, error); - } else if(!CFEqualSafe(makeTombstone, kCFBooleanFalse) && SecCKKSIsEnabled()) { + } else if(!CFEqualSafe(makeTombstone, kCFBooleanFalse) && isCKKSEnabled()) { // The primary keys aren't equal, and we're going to make a tombstone. // Help CKKS out: the tombstone should have the existing item's UUID, and the newly updated item should have a new UUID. @@ -1791,8 +1808,8 @@ bool SecDbItemSelectBind(SecDbQueryRef query, sqlite3_stmt *stmt, CFErrorRef *er range.location++; } } - CFArrayApplyFunction(array, range, apply_block_1, (void (^)(const void *value)) ^(const void *value) { - ok = SecDbItemSelectBindValue(query, stmt, param++, attr, value, error); + CFArrayApplyFunction(array, range, apply_block_1, (void (^)(const void *value)) ^(const void *arrayValue) { + ok = SecDbItemSelectBindValue(query, stmt, param++, attr, arrayValue, error); }); } else { ok = SecDbItemSelectBindValue(query, stmt, param++, attr, value, error); diff --git a/OSX/sec/securityd/SecDbItem.h b/OSX/sec/securityd/SecDbItem.h index 97f35f69..8b38586b 100644 --- a/OSX/sec/securityd/SecDbItem.h +++ b/OSX/sec/securityd/SecDbItem.h @@ -34,10 +34,10 @@ #include #include // For CCSHA1_OUTPUT_SIZE #include -#include -#include -#include -#include +#include "utilities/SecCFError.h" +#include "utilities/SecCFWrappers.h" +#include "utilities/SecDb.h" +#include "securityd/SecKeybagSupport.h" #include #include diff --git a/OSX/sec/securityd/SecDbKeychainItem.h b/OSX/sec/securityd/SecDbKeychainItem.h index c19cd42b..1cb4bfca 100644 --- a/OSX/sec/securityd/SecDbKeychainItem.h +++ b/OSX/sec/securityd/SecDbKeychainItem.h @@ -36,6 +36,8 @@ __BEGIN_DECLS 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); +bool ks_encrypt_data_with_backupuuid(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, + CFDictionaryRef secretData, CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, CFDataRef *bkUUID, bool useDefaultIV, CFErrorRef *error); bool ks_encrypt_data_legacy(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, bool useDefaultIV, CFErrorRef *error); // used for backup bool ks_decrypt_data(keybag_handle_t keybag, CFTypeRef cryptoOp, SecAccessControlRef *paccess_control, CFDataRef acm_context, diff --git a/OSX/sec/securityd/SecDbKeychainItem.m b/OSX/sec/securityd/SecDbKeychainItem.m index 63e99e31..54c5cf04 100644 --- a/OSX/sec/securityd/SecDbKeychainItem.m +++ b/OSX/sec/securityd/SecDbKeychainItem.m @@ -46,6 +46,7 @@ #include #include #import "SecDbKeychainItemV7.h" +#import "SecDbKeychainMetadataKeyStore.h" #import "sec_action.h" #if USE_KEYSTORE @@ -57,6 +58,8 @@ #endif /* USE_KEYSTORE */ +#include "OSX/utilities/SecAKSWrappers.h" + pthread_key_t CURRENT_CONNECTION_KEY; // From SecItemServer, should be a acl-check block @@ -304,10 +307,11 @@ ks_warn_non_device_keybag(void) 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) { - secerror("SecDbKeychainItem: encrypting item with no secret data"); // not actually making this an error because it seems this is done frequently by third parties - } + return ks_encrypt_data_with_backupuuid(keybag, access_control, acm_context, secretData, attributes, authenticated_attributes, pBlob, NULL, useDefaultIV, error); +} +bool ks_encrypt_data_with_backupuuid(keybag_handle_t keybag, SecAccessControlRef access_control, CFDataRef acm_context, + CFDictionaryRef secretData, CFDictionaryRef attributes, CFDictionaryRef authenticated_attributes, CFDataRef *pBlob, CFDataRef *bkUUID, bool useDefaultIV, CFErrorRef *error) { if (keybag != KEYBAG_DEVICE) { ks_warn_non_device_keybag(); @@ -347,6 +351,9 @@ bool ks_encrypt_data(keybag_handle_t keybag, SecAccessControlRef access_control, *((uint32_t*)encryptedBlobWithVersion.mutableBytes) = (uint32_t)7; memcpy((uint32_t*)encryptedBlobWithVersion.mutableBytes + 1, encryptedBlob.bytes, encryptedBlob.length); *pBlob = (__bridge_retained CFDataRef)encryptedBlobWithVersion; + if (bkUUID && item.backupUUID) { // TODO: Failing this should turn into at least a stern warning at some point + *bkUUID = (__bridge_retained CFDataRef)[item.backupUUID copy]; + } success = true; } else { @@ -442,10 +449,6 @@ bool ks_decrypt_data(keybag_handle_t keybag, CFTypeRef cryptoOp, SecAccessContro NSDictionary* secretAttributes = [item secretAttributesWithAcmContext:(__bridge NSData*)acm_context accessControl:access_control callerAccessGroups:(__bridge NSArray*)caller_access_groups error:&localError]; if (secretAttributes) { [itemAttributes addEntriesFromDictionary:secretAttributes]; - - if (secretAttributes.count == 0) { - secerror("SecDbKeychainItemV7: item decrypted succussfully, but has no secret data so it's useless"); // not actually making this an error because a bunch of third parties store items with no secret data on purpose - } } else { ok = false; @@ -978,18 +981,22 @@ bool s3dl_item_from_data(CFDataRef edata, Query *q, CFArrayRef accessGroups, require_quiet((ok = ks_decrypt_data(q->q_keybag, kAKSKeyOpDecrypt, &ac, q->q_use_cred_handle, edata, q->q_class, q->q_caller_access_groups, item, &version, decryptSecretData, keyclass, error)), out); if (version < 2) { + SecError(errSecDecode, error, CFSTR("version is unexpected: %d"), (int)version); + ok = false; goto out; } ac_data = SecAccessControlCopyData(ac); if (!itemInAccessGroup(*item, accessGroups)) { - secerror("items accessGroup %@ not in %@", + secerror("items accessGroup '%@' not in %@", CFDictionaryGetValue(*item, kSecAttrAccessGroup), accessGroups); - ok = SecError(errSecDecode, error, CFSTR("items accessGroup %@ not in %@"), - CFDictionaryGetValue(*item, kSecAttrAccessGroup), - accessGroups); + // We likely don't want to surface it to clients like this, but this is most accurate + SecError(errSecMissingEntitlement, error, CFSTR("item's access group '%@' not in %@"), + CFDictionaryGetValue(*item, kSecAttrAccessGroup), accessGroups); CFReleaseNull(*item); + ok = false; + goto out; } /* AccessControl attribute does not exist in the db, so synthesize it. */ @@ -1214,6 +1221,7 @@ CFTypeRef SecDbKeychainItemCopySHA1(SecDbItemRef item, const SecDbAttr *attr, CF CFTypeRef SecDbKeychainItemCopyEncryptedData(SecDbItemRef item, const SecDbAttr *attr, CFErrorRef *error) { CFDataRef edata = NULL; + CFDataRef bkuuid = NULL; CFMutableDictionaryRef secretStuff = SecDbItemCopyPListWithMask(item, kSecDbReturnDataFlag, error); CFMutableDictionaryRef attributes = SecDbItemCopyPListWithMask(item, kSecDbInCryptoDataFlag, error); CFMutableDictionaryRef auth_attributes = SecDbItemCopyPListWithMask(item, kSecDbInAuthenticatedDataFlag, error); @@ -1230,8 +1238,8 @@ CFTypeRef SecDbKeychainItemCopyEncryptedData(SecDbItemRef item, const SecDbAttr CFDictionaryRemoveValue(attributes, key); CFDictionaryRemoveValue(auth_attributes, key); }); - - if (ks_encrypt_data(item->keybag, access_control, item->credHandle, secretStuff, attributes, auth_attributes, &edata, true, error)) { + + if (ks_encrypt_data_with_backupuuid(item->keybag, access_control, item->credHandle, secretStuff, attributes, auth_attributes, &edata, &bkuuid, true, error)) { item->_edataState = kSecDbItemEncrypting; } else if (!error || !*error || CFErrorGetCode(*error) != errSecAuthNeeded || !CFEqualSafe(CFErrorGetDomain(*error), kSecErrorDomain) ) { seccritical("ks_encrypt_data (db): failed: %@", error ? *error : (CFErrorRef)CFSTR("")); @@ -1242,8 +1250,18 @@ CFTypeRef SecDbKeychainItemCopyEncryptedData(SecDbItemRef item, const SecDbAttr CFReleaseNull(attributes); CFReleaseNull(auth_attributes); CFReleaseNull(sha1); + if (bkuuid) { + // "data" is defined first in the schema so called first. The UUID will therefore be in the cache when ForEach gets to it + CFErrorRef localError = NULL; + SecDbItemSetValueWithName(item, CFSTR("backupUUID"), bkuuid, &localError); + if (localError) { + // Don't want to propagate this. It's bad but should be handled in the manager and not interrupt production + secerror("Unable to wrap keychain item to backup: %@", localError); + CFReleaseNull(localError); + CFReleaseNull(bkuuid); + } + } } - return edata; } @@ -1520,7 +1538,5 @@ exit: } void SecDbResetMetadataKeys(void) { -#if !TARGET_OS_BRIDGE [SecDbKeychainMetadataKeyStore resetSharedStore]; -#endif } diff --git a/OSX/sec/securityd/SecDbKeychainItemV7.h b/OSX/sec/securityd/SecDbKeychainItemV7.h index 56af9f64..7c96a0a3 100644 --- a/OSX/sec/securityd/SecDbKeychainItemV7.h +++ b/OSX/sec/securityd/SecDbKeychainItemV7.h @@ -24,12 +24,14 @@ #import "SecKeybagSupport.h" #import #import +#import "CheckV12DevEnabled.h" NS_ASSUME_NONNULL_BEGIN @interface SecDbKeychainItemV7 : NSObject @property (nonatomic, readonly) keyclass_t keyclass; +@property (nonatomic, readonly) NSData* backupUUID; - (nullable instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error; - (instancetype)initWithSecretAttributes:(NSDictionary*)secretAttributes metadataAttributes:(NSDictionary*)metadataAttributes tamperCheck:(NSString*)tamperCheck keyclass:(keyclass_t)keyclass; @@ -51,9 +53,6 @@ extern const NSInteger SecDbKeychainErrorDeserializationFailed; @interface SecDbKeychainItemV7 (UnitTesting) -+ (bool)aksEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass keyData:(NSData*)keyData outKeyclass:(keyclass_t* _Nullable)outKeyclass wrappedKey:(NSMutableData*)wrappedKey error:(NSError**)error; -+ (bool)aksDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass wrappedKeyData:(NSData*)wrappedKeyData outKeyclass:(keyclass_t* _Nullable)outKeyclass unwrappedKey:(NSMutableData*)unwrappedKey error:(NSError**)error; - + (bool)isKeychainUnlocked; @property (readonly) NSData* encryptedMetadataBlob; @@ -64,18 +63,4 @@ extern const NSInteger SecDbKeychainErrorDeserializationFailed; @end -// For Db resets _only_ -@interface SecDbKeychainMetadataKeyStore : NSObject - -+ (bool)cachingEnabled; - -+ (void)resetSharedStore; -+ (instancetype)sharedStore; - -- (instancetype)init NS_UNAVAILABLE; - -- (void)dropClassAKeys; - -@end - NS_ASSUME_NONNULL_END diff --git a/OSX/sec/securityd/SecDbKeychainItemV7.m b/OSX/sec/securityd/SecDbKeychainItemV7.m index d30cd30f..1fd3957d 100644 --- a/OSX/sec/securityd/SecDbKeychainItemV7.m +++ b/OSX/sec/securityd/SecDbKeychainItemV7.m @@ -29,77 +29,38 @@ #import "SecDbKeychainSerializedAKSWrappedKey.h" #import "SecDbKeychainSerializedMetadata.h" #import "SecDbKeychainSerializedSecretData.h" -#import #import #import +#import "SecAKSObjCWrappers.h" #import -#import "sec_action.h" -#if !TARGET_OS_BRIDGE #import #import #import -#endif + #import -#if USE_KEYSTORE +#if USE_KEYSTORE && __has_include() #import #endif -#define KEYCHAIN_ITEM_PADDING_MODULUS 20 - -NSString* const SecDbKeychainErrorDomain = @"SecDbKeychainErrorDomain"; -const NSInteger SecDbKeychainErrorDeserializationFailed = 1; - -static NSString* const SecDBTamperCheck = @"TamperCheck"; - -#define BridgeCFErrorToNSErrorOut(nsErrorOut, CFErr) \ -{ \ - if (nsErrorOut) { \ - *nsErrorOut = CFBridgingRelease(CFErr); \ - CFErr = NULL; \ - } \ - else { \ - CFReleaseNull(CFErr); \ - } \ -} - -#if TARGET_OS_BRIDGE - -@implementation SecDbKeychainItemV7 - -- (instancetype)initWithData:(NSData*)data decryptionKeybag:(keybag_handle_t)decryptionKeybag error:(NSError**)error -{ - return nil; -} - -- (instancetype)initWithSecretAttributes:(NSDictionary*)secretAttributes metadataAttributes:(NSDictionary*)metadataAttributes tamperCheck:(NSString*)tamperCheck keyclass:(keyclass_t)keyclass -{ - return nil; -} +#import "SecDbKeychainMetadataKeyStore.h" +#import "SecDbBackupManager.h" -- (NSDictionary*)metadataAttributesWithError:(NSError**)error -{ - return nil; -} +#define KEYCHAIN_ITEM_PADDING_MODULUS 20 -- (NSDictionary*)secretAttributesWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error -{ - return nil; -} +// See corresponding "reasonable size" client-side limit(s) in SecItem. -- (BOOL)deleteWithAcmContext:(NSData*)acmContext accessControl:(SecAccessControlRef)accessControl callerAccessGroups:(NSArray*)callerAccessGroups error:(NSError**)error -{ - return NO; -} +// Generally the secret data dictionary contains a single key +// with the client's password/key NSData therein, so 4k feels extremely luxurious +#define REASONABLE_SECRET_DATA_SIZE 4096 -- (NSData*)encryptedBlobWithKeybag:(keybag_handle_t)keybag accessControl:(SecAccessControlRef)accessControl acmContext:(NSData*)acmContext error:(NSError**)error -{ - return nil; -} +// This feels similarly generous, but let's find out +#define REASONABLE_METADATA_SIZE 2048 -@end +NSString* const SecDbKeychainErrorDomain = @"SecDbKeychainErrorDomain"; +const NSInteger SecDbKeychainErrorDeserializationFailed = 1; -#else +static NSString* const SecDBTamperCheck = @"TamperCheck"; static NSDictionary* dictionaryFromDERData(NSData* data) { @@ -148,7 +109,7 @@ typedef NS_ENUM(uint32_t, SecDbKeychainAKSWrappedKeyType) { @property (readonly) NSData* serializedRepresentation; - (instancetype)initWithData:(NSData*)data; -- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SecDbKeychainAKSWrappedKey*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error; +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SecDbKeychainAKSWrappedKey*)wrappedKey tamperCheck:(NSString*)tamperCheck backupWrappedKey:(SecDbBackupWrappedItemKey*)backupWrappedKey error:(NSError**)error; @end @@ -217,7 +178,10 @@ typedef NS_ENUM(uint32_t, SecDbKeychainAKSWrappedKeyType) { SecDbKeychainSerializedMetadata* _serializedHolder; } -- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SFAuthenticatedCiphertext*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext + wrappedKey:(SFAuthenticatedCiphertext*)wrappedKey + tamperCheck:(NSString*)tamperCheck + error:(NSError**)error { if (self = [super init]) { _serializedHolder = [[SecDbKeychainSerializedMetadata alloc] init]; @@ -282,13 +246,18 @@ typedef NS_ENUM(uint32_t, SecDbKeychainAKSWrappedKeyType) { SecDbKeychainSerializedSecretData* _serializedHolder; } -- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext wrappedKey:(SecDbKeychainAKSWrappedKey*)wrappedKey tamperCheck:(NSString*)tamperCheck error:(NSError**)error +- (instancetype)initWithCiphertext:(SFAuthenticatedCiphertext*)ciphertext + wrappedKey:(SecDbKeychainAKSWrappedKey*)wrappedKey + tamperCheck:(NSString*)tamperCheck + backupWrappedKey:(SecDbBackupWrappedItemKey*)backupWrappedKey + error:(NSError**)error { if (self = [super init]) { _serializedHolder = [[SecDbKeychainSerializedSecretData alloc] init]; _serializedHolder.ciphertext = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:error]; _serializedHolder.wrappedKey = wrappedKey.serializedRepresentation; _serializedHolder.tamperCheck = tamperCheck; + _serializedHolder.secDbBackupWrappedItemKey = backupWrappedKey ? [NSKeyedArchiver archivedDataWithRootObject:backupWrappedKey requiringSecureCoding:YES error:error] : nil; if (!_serializedHolder.ciphertext || !_serializedHolder.wrappedKey || !_serializedHolder.tamperCheck) { self = nil; } @@ -337,364 +306,9 @@ typedef NS_ENUM(uint32_t, SecDbKeychainAKSWrappedKeyType) { @end -////// SecDbKeychainMetadataKeyStore - -@interface SecDbKeychainMetadataKeyStore () -- (SFAESKey*)keyForKeyclass:(keyclass_t)keyClass - keybag:(keybag_handle_t)keybag - keySpecifier:(SFAESKeySpecifier*)keySpecifier - createKeyIfMissing:(bool)createIfMissing - overwriteCorruptKey:(bool)overwriteCorruptKey - error:(NSError**)error; -@end - -static SecDbKeychainMetadataKeyStore* sharedStore = nil; -static dispatch_queue_t sharedMetadataStoreQueue; -static void initializeSharedMetadataStoreQueue(void) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedMetadataStoreQueue = dispatch_queue_create("metadata_store", DISPATCH_QUEUE_SERIAL); - }); -} - -@implementation SecDbKeychainMetadataKeyStore { - NSMutableDictionary* _keysDict; - dispatch_queue_t _queue; -} - -+ (void)resetSharedStore -{ - initializeSharedMetadataStoreQueue(); - dispatch_sync(sharedMetadataStoreQueue, ^{ - if(sharedStore) { - dispatch_sync(sharedStore->_queue, ^{ - [sharedStore _onQueueDropAllKeys]; - }); - } - sharedStore = nil; - }); -} - -+ (instancetype)sharedStore -{ - __block SecDbKeychainMetadataKeyStore* ret; - initializeSharedMetadataStoreQueue(); - dispatch_sync(sharedMetadataStoreQueue, ^{ - if(!sharedStore) { - sharedStore = [[self alloc] _init]; - } - - ret = sharedStore; - }); - - return ret; -} - -+ (bool)cachingEnabled -{ - return true; -} - -- (instancetype)_init -{ - if (self = [super init]) { - _keysDict = [[NSMutableDictionary alloc] init]; - _queue = dispatch_queue_create("SecDbKeychainMetadataKeyStore", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - int token = 0; - __weak __typeof(self) weakSelf = self; - notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int inToken) { - bool locked = true; - CFErrorRef error = NULL; - if (!SecAKSGetIsLocked(&locked, &error)) { - secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", error); - CFReleaseNull(error); - } - - if (locked) { - [weakSelf _onQueueDropClassAKeys]; - } - }); - } - - return self; -} - -- (void)dropClassAKeys -{ - dispatch_sync(_queue, ^{ - [self _onQueueDropClassAKeys]; - }); -} - -- (void)_onQueueDropClassAKeys -{ - dispatch_assert_queue(_queue); - - secnotice("SecDbKeychainMetadataKeyStore", "dropping class A metadata keys"); - _keysDict[@(key_class_ak)] = nil; - _keysDict[@(key_class_aku)] = nil; - _keysDict[@(key_class_akpu)] = nil; -} - -- (void)_onQueueDropAllKeys -{ - dispatch_assert_queue(_queue); - - secnotice("SecDbKeychainMetadataKeyStore", "dropping all metadata keys"); - [_keysDict removeAllObjects]; -} - -- (void)_updateActualKeyclassIfNeeded:(keyclass_t)actualKeyclassToWriteBackToDB keyclass:(keyclass_t)keyclass -{ - __block CFErrorRef cfError = NULL; - - secnotice("SecDbKeychainItemV7", "saving actualKeyclass %d for metadata keyclass %d", actualKeyclassToWriteBackToDB, keyclass); - - kc_with_dbt_non_item_tables(true, &cfError, ^bool(SecDbConnectionRef dbt) { - __block bool actualKeyWriteBackOk = true; - - // we did not find an actualKeyclass entry in the db, so let's add one in now. - NSString *sql = @"UPDATE metadatakeys SET actualKeyclass = ? WHERE keyclass = ? AND actualKeyclass IS NULL"; - __block CFErrorRef actualKeyWriteBackError = NULL; - actualKeyWriteBackOk &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &actualKeyWriteBackError, ^(sqlite3_stmt* stmt) { - actualKeyWriteBackOk &= SecDbBindInt(stmt, 1, actualKeyclassToWriteBackToDB, &actualKeyWriteBackError); - actualKeyWriteBackOk &= SecDbBindInt(stmt, 2, keyclass, &actualKeyWriteBackError); - actualKeyWriteBackOk &= SecDbStep(dbt, stmt, &actualKeyWriteBackError, ^(bool* stop) { - // woohoo - }); - }); - - if (actualKeyWriteBackOk) { - secnotice("SecDbKeychainItemV7", "successfully saved actualKeyclass %d for metadata keyclass %d", actualKeyclassToWriteBackToDB, keyclass); - - } - else { - // we can always try this again in the future if it failed - secerror("SecDbKeychainItemV7: failed to save actualKeyclass %d for metadata keyclass %d; error: %@", actualKeyclassToWriteBackToDB, keyclass, actualKeyWriteBackError); - } - return actualKeyWriteBackOk; - }); -} - -- (SFAESKey*)keyForKeyclass:(keyclass_t)keyclass - keybag:(keybag_handle_t)keybag - keySpecifier:(SFAESKeySpecifier*)keySpecifier - createKeyIfMissing:(bool)createIfMissing - overwriteCorruptKey:(bool)overwriteCorruptKey - error:(NSError**)error -{ - __block SFAESKey* key = nil; - __block NSError* nsErrorLocal = nil; - __block CFErrorRef cfError = NULL; - static __thread BOOL reentrant = NO; - - NSAssert(!reentrant, @"re-entering -[%@ %@] - that shouldn't happen!", NSStringFromClass(self.class), NSStringFromSelector(_cmd)); - reentrant = YES; - -#if USE_KEYSTORE - if (keyclass > key_class_last) { - // idea is that AKS may return a keyclass value with extra bits above key_class_last from aks_wrap_key, but we only keep metadata keys for the canonical key classes - // so just sanitize all our inputs to the canonical values - keyclass_t sanitizedKeyclass = keyclass & key_class_last; - secinfo("SecDbKeychainItemV7", "sanitizing request for metadata keyclass %d to keyclass %d", keyclass, sanitizedKeyclass); - keyclass = sanitizedKeyclass; - } -#endif - - dispatch_sync(_queue, ^{ - // 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]) { - [self _onQueueDropClassAKeys]; - allowKeyCaching = !(keyclass == key_class_ak || keyclass == key_class_aku || keyclass == key_class_akpu); - } -#endif - - key = allowKeyCaching ? self->_keysDict[@(keyclass)] : nil; - if (!key) { - __block bool ok = true; - __block bool metadataKeyDoesntAuthenticate = false; - 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) { - NSData* wrappedKeyData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; - NSMutableData* unwrappedKeyData = [NSMutableData dataWithLength:wrappedKeyData.length]; - - keyclass_t actualKeyclass = sqlite3_column_int(stmt, 1); - - keyclass_t actualKeyclassToWriteBackToDB = 0; - keyclass_t keyclassForUnwrapping = actualKeyclass == 0 ? keyclass : actualKeyclass; - 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; - } - } -#if USE_KEYSTORE - else if (actualKeyclass == 0 && keyclass <= key_class_last) { - // in this case we might have luck decrypting with a key-rolled keyclass - keyclass_t keyrolledKeyclass = keyclass | (key_class_last + 1); - secerror("SecDbKeychainItemV7: failed to decrypt metadata key for class %d, but trying keyrolled keyclass (%d); error: %@", keyclass, keyrolledKeyclass, nsErrorLocal); - - // we don't want to pollute subsequent error-handling logic with what happens on our retry - // we'll give it a shot, and if it works, great - if it doesn't work, we'll just report that error in the log and move on - NSError* retryError = nil; - ok = [SecDbKeychainItemV7 aksDecryptWithKeybag:keybag keyclass:keyrolledKeyclass wrappedKeyData:wrappedKeyData outKeyclass:NULL unwrappedKey:unwrappedKeyData error:&retryError]; - - 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); - } - } -#endif - - if (ok && key) { - if (actualKeyclassToWriteBackToDB > 0) { - // check if we have updated this keyclass or not already - static NSMutableDictionary* updated = NULL; - if (!updated) { - updated = [NSMutableDictionary dictionary]; - } - if (!updated[@(keyclass)]) { - updated[@(keyclass)] = @YES; - dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ - [self _updateActualKeyclassIfNeeded:actualKeyclassToWriteBackToDB keyclass:keyclass]; - }); - } - } - } - else { - if (nsErrorLocal && [nsErrorLocal.domain isEqualToString:(__bridge NSString*)kSecErrorDomain] && nsErrorLocal.code == errSecInteractionNotAllowed) { - static dispatch_once_t kclockedtoken; - static sec_action_t kclockedaction; - dispatch_once(&kclockedtoken, ^{ - kclockedaction = sec_action_create("keychainlockedlogmessage", 1); - sec_action_set_handler(kclockedaction, ^{ - secerror("SecDbKeychainItemV7: failed to decrypt metadata key because the keychain is locked (%d)", (int)errSecInteractionNotAllowed); - }); - }); - sec_action_perform(kclockedaction); - } else { - 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); - } - } - } - }); - }); - - bool keyNotYetCreated = ok && !key; - bool forceOverwriteBadKey = !key && metadataKeyDoesntAuthenticate && overwriteCorruptKey; - - 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"); - // TODO: track this in LocalKeychainAnalytics - } - - 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; - 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); - NSString* insertString = forceOverwriteBadKey ? @"INSERT OR REPLACE" : @"INSERT"; - sql = [NSString stringWithFormat:@"%@ into metadatakeys (keyclass, actualKeyclass, data) VALUES (?, ?, ?)", insertString]; - ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt* stmt) { - ok &= SecDbBindInt(stmt, 1, keyclass, &cfError); - ok &= SecDbBindInt(stmt, 2, outKeyclass, &cfError); - ok &= SecDbBindBlob(stmt, 3, wrappedKey.bytes, wrappedKey.length, SQLITE_TRANSIENT, NULL); - ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { - // woohoo - }); - }); - - if (ok) { - secnotice("SecDbKeychainItemV7", "successfully saved new metadata key for keyclass %d", keyclass); - } - else { - secerror("SecDbKeychainItemV7: failed to save new metadata key for keyclass %d - probably there is already one in the database: %@", keyclass, cfError); - } - } else { - secerror("SecDbKeychainItemV7: unable to encrypt new metadata key(%d) with keybag(%d): %@", keyclass, keybag, nsErrorLocal); - } - } - 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) { - // 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, ^{ - [weakSelf _onQueueDropClassAKeys]; - }); - } - } - else { - key = nil; - } - } - }); - - reentrant = NO; - - if (error && nsErrorLocal) { - *error = nsErrorLocal; - CFReleaseNull(cfError); - } - else { - BridgeCFErrorToNSErrorOut(error, cfError); - } - - return key; -} - -@end +@interface SecDbKeychainItemV7 () +@property (nonatomic) NSData* backupUUID; +@end; @implementation SecDbKeychainItemV7 { SecDbKeychainSecretData* _encryptedSecretData; @@ -708,22 +322,6 @@ static void initializeSharedMetadataStoreQueue(void) { @synthesize keyclass = _keyclass; -+ (bool)aksEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass keyData:(NSData*)keyData outKeyclass:(keyclass_t*)outKeyclass wrappedKey:(NSMutableData*)wrappedKey error:(NSError**)error -{ - CFErrorRef cfError = NULL; - bool result = ks_crypt(kAKSKeyOpEncrypt, keybag, keyclass, (uint32_t)keyData.length, keyData.bytes, outKeyclass, (__bridge CFMutableDataRef)wrappedKey, &cfError); - BridgeCFErrorToNSErrorOut(error, cfError); - return result; -} - -+ (bool)aksDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass wrappedKeyData:(NSData*)wrappedKeyData outKeyclass:(keyclass_t*)outKeyclass unwrappedKey:(NSMutableData*)unwrappedKey error:(NSError**)error -{ - CFErrorRef cfError = NULL; - bool result = ks_crypt(kAKSKeyOpDecrypt, keybag, keyclass, (uint32_t)wrappedKeyData.length, wrappedKeyData.bytes, outKeyclass, (__bridge CFMutableDataRef)unwrappedKey, &cfError); - BridgeCFErrorToNSErrorOut(error, cfError); - return result; -} - // bring back with #if 0 + (bool)isKeychainUnlocked @@ -737,6 +335,12 @@ static void initializeSharedMetadataStoreQueue(void) { if (self = [super init]) { SecDbKeychainSerializedItemV7* serializedItem = [[SecDbKeychainSerializedItemV7 alloc] initWithData:data]; if (serializedItem) { + + // Add 10% for serializing overhead. We're trying to catch blatant overstuffing, not enforce hard limits + if (data.length > ((REASONABLE_SECRET_DATA_SIZE + REASONABLE_METADATA_SIZE) * 1.1)) { + secwarning("SecDbKeychainItemV7: serialized item exceeds reasonable size (%lu bytes)", (unsigned long)data.length); + } + _keybag = decryptionKeybag; _encryptedSecretData = [[SecDbKeychainSecretData alloc] initWithData:serializedItem.encryptedSecretData]; _encryptedMetadata = [[SecDbKeychainMetadata alloc] initWithData:serializedItem.encryptedMetadata]; @@ -956,6 +560,12 @@ static void initializeSharedMetadataStoreQueue(void) { NSMutableDictionary* attributesToEncrypt = _metadataAttributes.mutableCopy; attributesToEncrypt[SecDBTamperCheck] = _tamperCheck; NSData* metadata = (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)attributesToEncrypt, NULL); + + if (metadata.length > REASONABLE_METADATA_SIZE) { + NSString *agrp = _metadataAttributes[(__bridge NSString *)kSecAttrAccessGroup]; + secwarning("SecDbKeychainItemV7: item's metadata exceeds reasonable size (%lu bytes) (%@)", (unsigned long)metadata.length, agrp); + } + SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:metadata withKey:key error:error]; SFAESKey* metadataClassKey = [self metadataClassKeyWithKeybag:keybag @@ -982,6 +592,11 @@ static void initializeSharedMetadataStoreQueue(void) { attributesToEncrypt[SecDBTamperCheck] = _tamperCheck; NSMutableData* secretData = [(__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)attributesToEncrypt, NULL) mutableCopy]; + if (secretData.length > REASONABLE_SECRET_DATA_SIZE) { + NSString *agrp = _metadataAttributes[(__bridge NSString *)kSecAttrAccessGroup]; + secwarning("SecDbKeychainItemV7: item's secret data exceeds reasonable size (%lu bytes) (%@)", (unsigned long)secretData.length, agrp); + } + int8_t paddingLength = KEYCHAIN_ITEM_PADDING_MODULUS - (secretData.length % KEYCHAIN_ITEM_PADDING_MODULUS); int8_t paddingBytes[KEYCHAIN_ITEM_PADDING_MODULUS]; for (int i = 0; i < KEYCHAIN_ITEM_PADDING_MODULUS; i++) { @@ -992,7 +607,24 @@ static void initializeSharedMetadataStoreQueue(void) { SFAuthenticatedCiphertext* ciphertext = [encryptionOperation encrypt:secretData withKey:key error:error]; SecDbKeychainAKSWrappedKey* wrappedKey = [self wrapToAKS:key withKeybag:keybag accessControl:accessControl acmContext:acmContext error:error]; - _encryptedSecretData = [[SecDbKeychainSecretData alloc] initWithCiphertext:ciphertext wrappedKey:wrappedKey tamperCheck:_tamperCheck error:error]; + SecDbBackupWrappedItemKey* backupWrappedKey; + if (checkV12DevEnabled()) { + backupWrappedKey = [[SecDbBackupManager manager] wrapItemKey:key forKeyclass:_keyclass error:error]; + if (backupWrappedKey) { + _backupUUID = backupWrappedKey.baguuid; + } else { + secwarning("SecDbKeychainItemV7: backup manager didn't return wrapped key: %@", error ? *error : nil); + if (error) { + *error = nil; + } + } + } + + _encryptedSecretData = [[SecDbKeychainSecretData alloc] initWithCiphertext:ciphertext + wrappedKey:wrappedKey + tamperCheck:_tamperCheck + backupWrappedKey:backupWrappedKey + error:error]; return _encryptedSecretData != nil; } @@ -1072,12 +704,12 @@ static void initializeSharedMetadataStoreQueue(void) { } else { NSMutableData* wrappedKey = [[NSMutableData alloc] initWithLength:(size_t)keyData.length + 40]; - bool success = [self.class aksEncryptWithKeybag:keybag keyclass:_keyclass keyData:keyData outKeyclass:&_keyclass wrappedKey:wrappedKey error:error]; + bool success = [SecAKSObjCWrappers aksEncryptWithKeybag:keybag keyclass:_keyclass plaintext:keyData outKeyclass:&_keyclass ciphertext:wrappedKey error:error]; return success ? [[SecDbKeychainAKSWrappedKey alloc] initRegularWrappedKeyWithData:wrappedKey] : nil; } #else NSMutableData* wrappedKey = [[NSMutableData alloc] initWithLength:(size_t)keyData.length + 40]; - bool success = [self.class aksEncryptWithKeybag:keybag keyclass:_keyclass keyData:keyData outKeyclass:&_keyclass wrappedKey:wrappedKey error:error]; + bool success = [SecAKSObjCWrappers aksEncryptWithKeybag:keybag keyclass:_keyclass plaintext:keyData outKeyclass:&_keyclass ciphertext:wrappedKey error:error]; return success ? [[SecDbKeychainAKSWrappedKey alloc] initRegularWrappedKeyWithData:wrappedKey] : nil; #endif } @@ -1089,7 +721,7 @@ static void initializeSharedMetadataStoreQueue(void) { if (wrappedKey.type == SecDbKeychainAKSWrappedKeyTypeRegular) { NSMutableData* unwrappedKey = [NSMutableData dataWithCapacity:wrappedKeyData.length + 40]; unwrappedKey.length = wrappedKeyData.length + 40; - bool result = [self.class aksDecryptWithKeybag:_keybag keyclass:_keyclass wrappedKeyData:wrappedKeyData outKeyclass:&_keyclass unwrappedKey:unwrappedKey error:error]; + bool result = [SecAKSObjCWrappers aksDecryptWithKeybag:_keybag keyclass:_keyclass ciphertext:wrappedKeyData outKeyclass:&_keyclass plaintext:unwrappedKey error:error]; if (result) { return [[SFAESKey alloc] initWithData:unwrappedKey specifier:[self.class keySpecifier] error:error]; } @@ -1189,5 +821,3 @@ static void initializeSharedMetadataStoreQueue(void) { } @end - -#endif // TARGET_OS_BRIDGE diff --git a/OSX/sec/securityd/SecDbKeychainMetadataKeyStore.h b/OSX/sec/securityd/SecDbKeychainMetadataKeyStore.h new file mode 100644 index 00000000..5c35094a --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainMetadataKeyStore.h @@ -0,0 +1,53 @@ +/* + * 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 "SecKeybagSupport.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +// This class is intended for SecDbKeychainItemV7, db resets and SecDbKeychainManager _only_ + +@interface SecDbKeychainMetadataKeyStore : NSObject + ++ (bool)cachingEnabled; + ++ (void)resetSharedStore; ++ (instancetype)sharedStore; + +- (instancetype)init NS_UNAVAILABLE; + +- (void)dropClassAKeys; + +- (SFAESKey*)keyForKeyclass:(keyclass_t)keyClass + keybag:(keybag_handle_t)keybag + keySpecifier:(SFAESKeySpecifier*)keySpecifier + createKeyIfMissing:(bool)createIfMissing + overwriteCorruptKey:(bool)overwriteCorruptKey + error:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/OSX/sec/securityd/SecDbKeychainMetadataKeyStore.m b/OSX/sec/securityd/SecDbKeychainMetadataKeyStore.m new file mode 100644 index 00000000..d406a1b1 --- /dev/null +++ b/OSX/sec/securityd/SecDbKeychainMetadataKeyStore.m @@ -0,0 +1,370 @@ +/* + * 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 "SecDbKeychainMetadataKeyStore.h" +#import +#import +#import +#import "SecItemServer.h" +#import "SecAKSObjCWrappers.h" +#import "sec_action.h" + +static SecDbKeychainMetadataKeyStore* sharedStore = nil; +static dispatch_queue_t sharedMetadataStoreQueue; +static void initializeSharedMetadataStoreQueue(void) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedMetadataStoreQueue = dispatch_queue_create("metadata_store", DISPATCH_QUEUE_SERIAL); + }); +} + +@implementation SecDbKeychainMetadataKeyStore { + NSMutableDictionary* _keysDict; + dispatch_queue_t _queue; +} + ++ (void)resetSharedStore +{ + initializeSharedMetadataStoreQueue(); + dispatch_sync(sharedMetadataStoreQueue, ^{ + if(sharedStore) { + dispatch_sync(sharedStore->_queue, ^{ + [sharedStore _onQueueDropAllKeys]; + }); + } + sharedStore = nil; + }); +} + ++ (instancetype)sharedStore +{ + __block SecDbKeychainMetadataKeyStore* ret; + initializeSharedMetadataStoreQueue(); + dispatch_sync(sharedMetadataStoreQueue, ^{ + if(!sharedStore) { + sharedStore = [[self alloc] _init]; + } + + ret = sharedStore; + }); + + return ret; +} + ++ (bool)cachingEnabled +{ + return true; +} + +- (instancetype)_init +{ + if (self = [super init]) { + _keysDict = [[NSMutableDictionary alloc] init]; + _queue = dispatch_queue_create("SecDbKeychainMetadataKeyStore", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + int token = 0; + __weak __typeof(self) weakSelf = self; + notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int inToken) { + bool locked = true; + CFErrorRef error = NULL; + if (!SecAKSGetIsLocked(&locked, &error)) { + secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", error); + CFReleaseNull(error); + } + + if (locked) { + [weakSelf _onQueueDropClassAKeys]; + } + }); + } + + return self; +} + +- (void)dropClassAKeys +{ + dispatch_sync(_queue, ^{ + [self _onQueueDropClassAKeys]; + }); +} + +- (void)_onQueueDropClassAKeys +{ + dispatch_assert_queue(_queue); + + secnotice("SecDbKeychainMetadataKeyStore", "dropping class A metadata keys"); + _keysDict[@(key_class_ak)] = nil; + _keysDict[@(key_class_aku)] = nil; + _keysDict[@(key_class_akpu)] = nil; +} + +- (void)_onQueueDropAllKeys +{ + dispatch_assert_queue(_queue); + + secnotice("SecDbKeychainMetadataKeyStore", "dropping all metadata keys"); + [_keysDict removeAllObjects]; +} + +- (void)_updateActualKeyclassIfNeeded:(keyclass_t)actualKeyclassToWriteBackToDB keyclass:(keyclass_t)keyclass +{ + __block CFErrorRef cfError = NULL; + + secnotice("SecDbKeychainItemV7", "saving actualKeyclass %d for metadata keyclass %d", actualKeyclassToWriteBackToDB, keyclass); + + kc_with_dbt_non_item_tables(true, &cfError, ^bool(SecDbConnectionRef dbt) { + __block bool actualKeyWriteBackOk = true; + + // we did not find an actualKeyclass entry in the db, so let's add one in now. + NSString *sql = @"UPDATE metadatakeys SET actualKeyclass = ? WHERE keyclass = ? AND actualKeyclass IS NULL"; + __block CFErrorRef actualKeyWriteBackError = NULL; + actualKeyWriteBackOk &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &actualKeyWriteBackError, ^(sqlite3_stmt* stmt) { + actualKeyWriteBackOk &= SecDbBindInt(stmt, 1, actualKeyclassToWriteBackToDB, &actualKeyWriteBackError); + actualKeyWriteBackOk &= SecDbBindInt(stmt, 2, keyclass, &actualKeyWriteBackError); + actualKeyWriteBackOk &= SecDbStep(dbt, stmt, &actualKeyWriteBackError, ^(bool* stop) { + // woohoo + }); + }); + + if (actualKeyWriteBackOk) { + secnotice("SecDbKeychainItemV7", "successfully saved actualKeyclass %d for metadata keyclass %d", actualKeyclassToWriteBackToDB, keyclass); + + } + else { + // we can always try this again in the future if it failed + secerror("SecDbKeychainItemV7: failed to save actualKeyclass %d for metadata keyclass %d; error: %@", actualKeyclassToWriteBackToDB, keyclass, actualKeyWriteBackError); + } + return actualKeyWriteBackOk; + }); +} + +- (SFAESKey*)keyForKeyclass:(keyclass_t)keyclass + keybag:(keybag_handle_t)keybag + keySpecifier:(SFAESKeySpecifier*)keySpecifier + createKeyIfMissing:(bool)createIfMissing + overwriteCorruptKey:(bool)overwriteCorruptKey + error:(NSError**)error +{ + __block SFAESKey* key = nil; + __block NSError* nsErrorLocal = nil; + __block CFErrorRef cfError = NULL; + static __thread BOOL reentrant = NO; + + NSAssert(!reentrant, @"re-entering -[%@ %@] - that shouldn't happen!", NSStringFromClass(self.class), NSStringFromSelector(_cmd)); + reentrant = YES; + + keyclass = SecAKSSanitizedKeyclass(keyclass); + + dispatch_sync(_queue, ^{ + // 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]) { + [self _onQueueDropClassAKeys]; + allowKeyCaching = !(keyclass == key_class_ak || keyclass == key_class_aku || keyclass == key_class_akpu); + } +#endif + + key = allowKeyCaching ? self->_keysDict[@(keyclass)] : nil; + if (!key) { + __block bool ok = true; + __block bool metadataKeyDoesntAuthenticate = false; + 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) { + NSData* wrappedKeyData = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; + NSMutableData* unwrappedKeyData = [NSMutableData dataWithLength:wrappedKeyData.length]; + + keyclass_t actualKeyclass = sqlite3_column_int(stmt, 1); + + keyclass_t actualKeyclassToWriteBackToDB = 0; + keyclass_t keyclassForUnwrapping = actualKeyclass == 0 ? keyclass : actualKeyclass; + ok &= [SecAKSObjCWrappers aksDecryptWithKeybag:keybag keyclass:keyclassForUnwrapping ciphertext:wrappedKeyData outKeyclass:NULL plaintext: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; + } + } +#if USE_KEYSTORE + else if (actualKeyclass == 0 && keyclass <= key_class_last) { + // in this case we might have luck decrypting with a key-rolled keyclass + keyclass_t keyrolledKeyclass = keyclass | (key_class_last + 1); + secerror("SecDbKeychainItemV7: failed to decrypt metadata key for class %d, but trying keyrolled keyclass (%d); error: %@", keyclass, keyrolledKeyclass, nsErrorLocal); + + // we don't want to pollute subsequent error-handling logic with what happens on our retry + // we'll give it a shot, and if it works, great - if it doesn't work, we'll just report that error in the log and move on + NSError* retryError = nil; + ok = [SecAKSObjCWrappers aksDecryptWithKeybag:keybag keyclass:keyrolledKeyclass ciphertext:wrappedKeyData outKeyclass:NULL plaintext:unwrappedKeyData error:&retryError]; + + 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); + } + } +#endif + + if (ok && key) { + if (actualKeyclassToWriteBackToDB > 0) { + // check if we have updated this keyclass or not already + static NSMutableDictionary* updated = NULL; + if (!updated) { + updated = [NSMutableDictionary dictionary]; + } + if (!updated[@(keyclass)]) { + updated[@(keyclass)] = @YES; + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ + [self _updateActualKeyclassIfNeeded:actualKeyclassToWriteBackToDB keyclass:keyclass]; + }); + } + } + } + else { + if (nsErrorLocal && [nsErrorLocal.domain isEqualToString:(__bridge NSString*)kSecErrorDomain] && nsErrorLocal.code == errSecInteractionNotAllowed) { + static dispatch_once_t kclockedtoken; + static sec_action_t kclockedaction; + dispatch_once(&kclockedtoken, ^{ + kclockedaction = sec_action_create("keychainlockedlogmessage", 1); + sec_action_set_handler(kclockedaction, ^{ + secerror("SecDbKeychainItemV7: failed to decrypt metadata key because the keychain is locked (%d)", (int)errSecInteractionNotAllowed); + }); + }); + sec_action_perform(kclockedaction); + } else { + 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); + } + } + } + }); + }); + + bool keyNotYetCreated = ok && !key; + bool forceOverwriteBadKey = !key && metadataKeyDoesntAuthenticate && overwriteCorruptKey; + + 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"); + // TODO: track this in LocalKeychainAnalytics + } + + 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; + ok &= [SecAKSObjCWrappers aksEncryptWithKeybag:keybag keyclass:keyclass plaintext:key.keyData outKeyclass:&outKeyclass ciphertext:wrappedKey error:&nsErrorLocal]; + if (ok) { + secinfo("SecDbKeychainItemV7", "attempting to save new metadata key for keyclass %d with actualKeyclass %d", keyclass, outKeyclass); + NSString* insertString = forceOverwriteBadKey ? @"INSERT OR REPLACE" : @"INSERT"; + sql = [NSString stringWithFormat:@"%@ into metadatakeys (keyclass, actualKeyclass, data) VALUES (?, ?, ?)", insertString]; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt* stmt) { + ok &= SecDbBindInt(stmt, 1, keyclass, &cfError); + ok &= SecDbBindInt(stmt, 2, outKeyclass, &cfError); + ok &= SecDbBindBlob(stmt, 3, wrappedKey.bytes, wrappedKey.length, SQLITE_TRANSIENT, NULL); + ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { + // woohoo + }); + }); + + if (ok) { + secnotice("SecDbKeychainItemV7", "successfully saved new metadata key for keyclass %d", keyclass); + } + else { + secerror("SecDbKeychainItemV7: failed to save new metadata key for keyclass %d - probably there is already one in the database: %@", keyclass, cfError); + } + } else { + secerror("SecDbKeychainItemV7: unable to encrypt new metadata key(%d) with keybag(%d): %@", keyclass, keybag, nsErrorLocal); + } + } + 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) { + // 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, ^{ + [weakSelf _onQueueDropClassAKeys]; + }); + } + } + else { + key = nil; + } + } + }); + + reentrant = NO; + + if (error && nsErrorLocal) { + *error = nsErrorLocal; + CFReleaseNull(cfError); + } + else { + BridgeCFErrorToNSErrorOut(error, cfError); + } + + return key; +} + +@end diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainAKSSerializedWrappedKey.proto b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.proto similarity index 100% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainAKSSerializedWrappedKey.proto rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.proto diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto index 81b03aca..55353e16 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.proto @@ -4,4 +4,5 @@ message SecDbKeychainSerializedSecretData { required bytes ciphertext = 1; required bytes wrappedKey = 2; required string tamperCheck = 3; + optional bytes SecDbBackupWrappedItemKey = 4; } diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedAKSWrappedKey.h similarity index 95% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.h rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedAKSWrappedKey.h index a0dbbbcd..154cc192 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.h +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedAKSWrappedKey.h @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedAKSWrappedKey.proto #import #import diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedAKSWrappedKey.m similarity index 97% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.m rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedAKSWrappedKey.m index 7df5d9ec..5a4b4465 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedAKSWrappedKey.m +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedAKSWrappedKey.m @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedAKSWrappedKey.proto #import "SecDbKeychainSerializedAKSWrappedKey.h" #import @@ -62,18 +62,18 @@ BOOL SecDbKeychainSerializedAKSWrappedKeyReadFrom(__unsafe_unretained SecDbKeych NSData *new_wrappedKey = PBReaderReadData(reader); self->_wrappedKey = new_wrappedKey; } - break; + break; case 2 /* refKeyBlob */: { NSData *new_refKeyBlob = PBReaderReadData(reader); self->_refKeyBlob = new_refKeyBlob; } - break; + break; case 3 /* type */: { self->_type = PBReaderReadUint32(reader); } - break; + break; default: if (!PBReaderSkipValueWithTag(reader, tag, aType)) return NO; diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedItemV7.h similarity index 98% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.h rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedItemV7.h index 4530a8a7..630bd070 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.h +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedItemV7.h @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedItemV7.proto #import #import diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedItemV7.m similarity index 98% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.m rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedItemV7.m index 8d7a75b7..3ccff9ec 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedItemV7.m +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedItemV7.m @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedItemV7.proto #import "SecDbKeychainSerializedItemV7.h" #import diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedMetadata.h similarity index 95% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.h rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedMetadata.h index 0143c9b8..a2855be0 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.h +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedMetadata.h @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedMetadata.proto #import #import diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedMetadata.m similarity index 98% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.m rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedMetadata.m index e53c9f88..b32c5b2d 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedMetadata.m +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedMetadata.m @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedMetadata.proto #import "SecDbKeychainSerializedMetadata.h" #import diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.h b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedSecretData.h similarity index 83% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.h rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedSecretData.h index 43dfdf44..9f74bff0 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.h +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedSecretData.h @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedSecretData.proto #import #import @@ -14,6 +14,7 @@ @interface SecDbKeychainSerializedSecretData : PBCodable { NSData *_ciphertext; + NSData *_secDbBackupWrappedItemKey; NSString *_tamperCheck; NSData *_wrappedKey; } @@ -25,6 +26,9 @@ @property (nonatomic, retain) NSString *tamperCheck; +@property (nonatomic, readonly) BOOL hasSecDbBackupWrappedItemKey; +@property (nonatomic, retain) NSData *secDbBackupWrappedItemKey; + // Performs a shallow copy into other - (void)copyTo:(SecDbKeychainSerializedSecretData *)other; diff --git a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.m b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedSecretData.m similarity index 76% rename from OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.m rename to OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedSecretData.m index 864421a3..b073d483 100644 --- a/OSX/sec/securityd/SecDbKeychainV7-protobufs/SecDbKeychainSerializedSecretData.m +++ b/OSX/sec/securityd/SecDbKeychainV7-protobufs/generated_source/SecDbKeychainSerializedSecretData.m @@ -1,6 +1,6 @@ // This file was automatically generated by protocompiler // DO NOT EDIT! -// Compiled from foo.proto +// Compiled from SecDbKeychainSerializedSecretData.proto #import "SecDbKeychainSerializedSecretData.h" #import @@ -16,6 +16,11 @@ @synthesize ciphertext = _ciphertext; @synthesize wrappedKey = _wrappedKey; @synthesize tamperCheck = _tamperCheck; +- (BOOL)hasSecDbBackupWrappedItemKey +{ + return _secDbBackupWrappedItemKey != nil; +} +@synthesize secDbBackupWrappedItemKey = _secDbBackupWrappedItemKey; - (NSString *)description { @@ -37,6 +42,10 @@ { [dict setObject:self->_tamperCheck forKey:@"tamperCheck"]; } + if (self->_secDbBackupWrappedItemKey) + { + [dict setObject:self->_secDbBackupWrappedItemKey forKey:@"SecDbBackupWrappedItemKey"]; + } return dict; } @@ -74,6 +83,12 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain self->_tamperCheck = new_tamperCheck; } break; + case 4 /* secDbBackupWrappedItemKey */: + { + NSData *new_secDbBackupWrappedItemKey = PBReaderReadData(reader); + self->_secDbBackupWrappedItemKey = new_secDbBackupWrappedItemKey; + } + break; default: if (!PBReaderSkipValueWithTag(reader, tag, aType)) return NO; @@ -104,6 +119,13 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain assert(nil != self->_tamperCheck); PBDataWriterWriteStringField(writer, self->_tamperCheck, 3); } + /* secDbBackupWrappedItemKey */ + { + if (self->_secDbBackupWrappedItemKey) + { + PBDataWriterWriteDataField(writer, self->_secDbBackupWrappedItemKey, 4); + } + } } - (void)copyTo:(SecDbKeychainSerializedSecretData *)other @@ -111,6 +133,10 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain other.ciphertext = _ciphertext; other.wrappedKey = _wrappedKey; other.tamperCheck = _tamperCheck; + if (_secDbBackupWrappedItemKey) + { + other.secDbBackupWrappedItemKey = _secDbBackupWrappedItemKey; + } } - (id)copyWithZone:(NSZone *)zone @@ -119,6 +145,7 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain copy->_ciphertext = [_ciphertext copyWithZone:zone]; copy->_wrappedKey = [_wrappedKey copyWithZone:zone]; copy->_tamperCheck = [_tamperCheck copyWithZone:zone]; + copy->_secDbBackupWrappedItemKey = [_secDbBackupWrappedItemKey copyWithZone:zone]; return copy; } @@ -132,6 +159,8 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain ((!self->_wrappedKey && !other->_wrappedKey) || [self->_wrappedKey isEqual:other->_wrappedKey]) && ((!self->_tamperCheck && !other->_tamperCheck) || [self->_tamperCheck isEqual:other->_tamperCheck]) + && + ((!self->_secDbBackupWrappedItemKey && !other->_secDbBackupWrappedItemKey) || [self->_secDbBackupWrappedItemKey isEqual:other->_secDbBackupWrappedItemKey]) ; } @@ -144,6 +173,8 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain [self->_wrappedKey hash] ^ [self->_tamperCheck hash] + ^ + [self->_secDbBackupWrappedItemKey hash] ; } @@ -161,6 +192,10 @@ BOOL SecDbKeychainSerializedSecretDataReadFrom(__unsafe_unretained SecDbKeychain { [self setTamperCheck:other->_tamperCheck]; } + if (other->_secDbBackupWrappedItemKey) + { + [self setSecDbBackupWrappedItemKey:other->_secDbBackupWrappedItemKey]; + } } @end diff --git a/OSX/sec/securityd/SecDbQuery.c b/OSX/sec/securityd/SecDbQuery.c index 886a3e4f..ae67d53a 100644 --- a/OSX/sec/securityd/SecDbQuery.c +++ b/OSX/sec/securityd/SecDbQuery.c @@ -630,13 +630,13 @@ static void query_add_use(const void *key, const void *value, Query *q) } #if TARGET_OS_IPHONE } else if (CFEqual(key, kSecUseSystemKeychain)) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR q->q_keybag = KEYBAG_DEVICE; #endif q->q_system_keychain = true; } else if (CFEqual(key, kSecUseSyncBubbleKeychain)) { if (isNumber(value) && CFNumberGetValue(value, kCFNumberSInt32Type, &q->q_sync_bubble) && q->q_sync_bubble > 0) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR q->q_keybag = KEYBAG_DEVICE; #endif } else { diff --git a/OSX/sec/securityd/SecDbQuery.h b/OSX/sec/securityd/SecDbQuery.h index 76354ee2..dc132a0e 100644 --- a/OSX/sec/securityd/SecDbQuery.h +++ b/OSX/sec/securityd/SecDbQuery.h @@ -28,8 +28,8 @@ #ifndef _SECURITYD_SECDBQUERY_H_ #define _SECURITYD_SECDBQUERY_H_ -#include -#include +#include "securityd/SecKeybagSupport.h" +#include "securityd/SecDbItem.h" __BEGIN_DECLS diff --git a/OSX/sec/securityd/SecItemBackupServer.c b/OSX/sec/securityd/SecItemBackupServer.c index e7a8dd17..476b3bd9 100644 --- a/OSX/sec/securityd/SecItemBackupServer.c +++ b/OSX/sec/securityd/SecItemBackupServer.c @@ -23,8 +23,8 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSEnginePriv.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #include #include #include diff --git a/OSX/sec/securityd/SecItemDataSource.c b/OSX/sec/securityd/SecItemDataSource.c index a19f39b6..4984c375 100644 --- a/OSX/sec/securityd/SecItemDataSource.c +++ b/OSX/sec/securityd/SecItemDataSource.c @@ -34,8 +34,8 @@ #include #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSEngine.h" #include #include #include diff --git a/OSX/sec/securityd/SecItemDataSource.h b/OSX/sec/securityd/SecItemDataSource.h index d9c04f49..fab2678e 100644 --- a/OSX/sec/securityd/SecItemDataSource.h +++ b/OSX/sec/securityd/SecItemDataSource.h @@ -30,7 +30,7 @@ #ifndef _SECURITYD_SECITEMDATASOURCE_H_ #define _SECURITYD_SECITEMDATASOURCE_H_ -#include +#include "keychain/SecureObjectSync/SOSDataSource.h" #include __BEGIN_DECLS diff --git a/OSX/sec/securityd/SecItemDb.c b/OSX/sec/securityd/SecItemDb.c index ca13565c..865202cc 100644 --- a/OSX/sec/securityd/SecItemDb.c +++ b/OSX/sec/securityd/SecItemDb.c @@ -27,6 +27,12 @@ passwords.) */ +#if TARGET_DARWINOS +#undef OCTAGON +#undef SECUREOBJECTSYNC +#undef SHAREDWEBCREDENTIALS +#endif + #include #include @@ -43,7 +49,6 @@ #include #include #include -#include #include #include "sec_action.h" @@ -68,7 +73,7 @@ const SecDbAttr *SecDbAttrWithKey(const SecDbClass *c, if (CFEqual(a->name, key)) return a; } - if (CFEqual(kSecAttrNoLegacy, key)) { + if (CFEqual(kSecUseDataProtectionKeychain, key)) { return NULL; /* results in no ops for this attribute */ } } @@ -428,6 +433,10 @@ handle_result(Query *q, CFTypeRef a_result; CFDataRef data; data = CFDictionaryGetValue(item, kSecValueData); + CFDataRef pref = NULL; + if (q->q_return_type & kSecReturnPersistentRefMask) { + pref = _SecItemCreatePersistentRef(q->q_class->name, rowid, item); + } if (q->q_return_type == 0) { /* Caller isn't interested in any results at all. */ a_result = kCFNull; @@ -481,16 +490,14 @@ handle_result(Query *q, } CFReleaseSafe(data); } - if (q->q_return_type & kSecReturnPersistentRefMask) { - CFDataRef pref = _SecItemCreatePersistentRef(q->q_class->name, rowid, item); + if (q->q_return_type & kSecReturnPersistentRefMask && pref != NULL) { CFDictionarySetValue(item, kSecValuePersistentRef, pref); - CFRelease(pref); } a_result = item; CFRetain(item); } - + CFReleaseSafe(pref); return a_result; } @@ -500,6 +507,7 @@ static void s3dl_merge_into_dict(const void *key, const void *value, void *conte static bool checkTokenObjectID(CFDataRef token_object_id, CFDataRef value_data) { bool equalOID = false; + require_quiet(value_data, out); CFDictionaryRef itemValue = SecTokenItemValueCopy(value_data, NULL); require_quiet(itemValue, out); CFDataRef oID = CFDictionaryGetValue(itemValue, kSecTokenValueObjectIDKey); @@ -526,6 +534,29 @@ decode: if (status == errSecDecode) { secwarning("ignoring corrupt %@,rowid=%" PRId64 " %@", q->q_class->name, rowid, q->q_error); { + CFStringRef tablename = CFStringCreateCopy(kCFAllocatorDefault, q->q_class->name); + // Can't get rid of this item on the read path. Let's come back from elsewhere. + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + __block CFErrorRef localErr = NULL; + __block bool ok = true; + ok &= kc_with_dbt(true, &localErr, ^bool(SecDbConnectionRef dbt) { + CFStringRef sql = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("DELETE FROM %@ WHERE rowid=%lli"), tablename, rowid); + ok &= SecDbPrepare(dbt, sql, &localErr, ^(sqlite3_stmt *stmt) { + ok &= SecDbStep(dbt, stmt, &localErr, NULL); + }); + + if (!ok || localErr) { + secerror("Failed to delete corrupt item, %@ row %lli: %@", tablename, rowid, localErr); + } else { + secnotice("item", "Deleted corrupt rowid %lli from table %@", rowid, tablename); + } + CFReleaseNull(localErr); + CFReleaseNull(sql); + CFReleaseSafe(tablename); + return ok; + }); + }); + CFDataRef edata = s3dl_copy_data_from_col(stmt, 1, NULL); CFMutableStringRef edatastring = CFStringCreateMutable(kCFAllocatorDefault, 0); if(edatastring) { @@ -535,7 +566,7 @@ decode: CFReleaseSafe(edata); CFReleaseSafe(edatastring); } - CFReleaseNull(q->q_error); + CFReleaseNull(q->q_error); // This item was never here, keep going } else if (status == errSecAuthNeeded) { secwarning("Authentication is needed for %@,rowid=%" PRId64 " (%" PRIdOSStatus "): %@", q->q_class->name, rowid, status, q->q_error); } else if (status == errSecInteractionNotAllowed) { @@ -548,6 +579,10 @@ decode: }); }); sec_action_perform(kclockedaction); + } else if (status == errSecMissingEntitlement) { + // That's fine, let's pretend the item never existed for this query. + // We may find other, better items for the caller! + CFReleaseNull(q->q_error); } else { secerror("decode %@,rowid=%" PRId64 " failed (%" PRIdOSStatus "): %@", q->q_class->name, rowid, status, q->q_error); } @@ -1290,6 +1325,16 @@ bool SecItemIsSystemBound(CFDictionaryRef item, const SecDbClass *cls, bool mult return true; } } + + if (isString(service) && CFEqual(service, CFSTR("com.apple.account.CloudKit.token"))) { + secdebug("backup", "found sys_bound item: %@", item); + return true; + } + + if (isString(service) && CFEqual(service, CFSTR("com.apple.account.idms.continuation-key"))) { + secdebug("backup", "found sys_bound item: %@", item); + return true; + } } if (multiUser && CFEqual(agrp, CFSTR("com.apple.apsd")) && cls == genp_class()) { @@ -1397,6 +1442,10 @@ bool SecItemIsSystemBound(CFDictionaryRef item, const SecDbClass *cls, bool mult } } + if (multiUser && CFEqual(agrp, CFSTR("com.apple.rapport")) && cls == genp_class()) { + secdebug("backup", "found exact sys_bound item: %@", item); + return true; + } secdebug("backup", "found non sys_bound item: %@", item); return false; @@ -1510,8 +1559,9 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) { } } - bool is_akpu = access_control ? CFEqualSafe(SecAccessControlGetProtection(access_control), - kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly) : keyclass == key_class_akpu; + bool is_akpu = access_control ? CFEqualSafe(SecAccessControlGetProtection(access_control), kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly) + // Mask generation, only look at class per se + : (keyclass & key_class_last) == key_class_akpu; bool is_token = (ok && allAttributes != NULL) ? CFDictionaryContainsKey(allAttributes, kSecAttrTokenID) : false; if (ok && allAttributes && !(skip_akpu_or_token && (is_akpu || is_token))) { @@ -1558,7 +1608,13 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) { } else { OSStatus status = SecErrorGetOSStatus(localError); - if (status == errSecInteractionNotAllowed && is_akpu && skip_akpu_or_token) { + if (status == errSecInteractionNotAllowed && is_akpu) { + if (skip_akpu_or_token) { + secdebug("item", "Skipping akpu item for backup"); + } else { // Probably failed to decrypt sysbound item. Should never be an akpu item in backup. + secerror("Encountered akpu item we cannot export (filter %d), skipping. %@", c->filter, localError); + // TODO: Find out who is doing this somehow and make them not do this + } // We expect akpu items to be inaccessible when the device is locked. CFReleaseNull(localError); } else { @@ -1566,11 +1622,11 @@ static void s3dl_export_row(sqlite3_stmt *stmt, void *context) { /* If the error is "corrupted item" then we just ignore it, otherwise we save it in the query */ secinfo("item","Could not export item for rowid %llu: %@", rowid, localError); - if(status == errSecDecode) { + if (status == errSecDecode) { CFReleaseNull(localError); } else { CFReleaseSafe(q->q_error); - q->q_error=localError; + q->q_error = localError; } } } @@ -1638,8 +1694,9 @@ SecServerCopyKeychainPlist(SecDbConnectionRef dbt, CFRetain(q.q_musrView); keybaguuid = SecCreateKeybagUUID(dest_keybag); - if (keybaguuid) + if (keybaguuid) { CFDictionarySetValue(keychain, kSecBackupKeybagUUIDKey, keybaguuid); + } } /* Get rid of this duplicate. */ @@ -1659,10 +1716,11 @@ SecServerCopyKeychainPlist(SecDbConnectionRef dbt, .multiUser = inMultiUser, }; - secnotice("item", "exporting class '%@'", q.q_class->name); + secnotice("item", "exporting %ssysbound class '%@'", filter != kSecSysBoundItemFilter ? "non-" : "", q.q_class->name); CFErrorRef localError = NULL; if (s3dl_query(s3dl_export_row, &ctx, &localError)) { + secnotice("item", "exporting class '%@' complete", q.q_class->name); if (CFArrayGetCount(ctx.qc.result)) { SecSignpostBackupCount(SecSignpostImpulseBackupClassCount, q.q_class->name, CFArrayGetCount(ctx.qc.result), filter); CFDictionaryAddValue(keychain, q.q_class->name, ctx.qc.result); @@ -1671,9 +1729,10 @@ SecServerCopyKeychainPlist(SecDbConnectionRef dbt, } else { OSStatus status = (OSStatus)CFErrorGetCode(localError); if (status == errSecItemNotFound) { + secnotice("item", "exporting class '%@' complete (no items)", q.q_class->name); CFRelease(localError); } else { - secerror("Export failed: %@", localError); + secerror("exporting class '%@' failed: %@", q.q_class->name, localError); if (error) { CFReleaseSafe(*error); *error = localError; @@ -1731,30 +1790,54 @@ SecServerImportItem(const void *value, void *context) secdebug("item", "Import Item : %@", dict); + SecDbItemRef item = NULL; + + /* This is sligthly confusing: + - During upgrade all items are exported with KEYBAG_NONE. + - During restore from backup, existing sys_bound items are exported with KEYBAG_NONE, and are exported as dictionary of attributes. + - Item in the actual backup are export with a real keybag, and are exported as encrypted v_Data and v_PersistentRef + */ + if (state->s->src_keybag == KEYBAG_NONE) { + item = SecDbItemCreateWithAttributes(kCFAllocatorDefault, state->class, dict, state->s->dest_keybag, &state->s->error); + } else { + item = SecDbItemCreateWithBackupDictionary(kCFAllocatorDefault, state->class, dict, state->s->src_keybag, state->s->dest_keybag, &state->s->error); + } + + /* If item is NULL here, control flow ends up at the end where error is cleared. */ + if (item && !SecDbItemEnsureDecrypted(item, true, &state->s->error)) { + secdebug("item", "Failed to import item because of decryption failure: %@", state->s->error); + CFReleaseNull(item); + /* No early return; as just above, go to the end where error is cleared. */ + } + /* We use the kSecSysBoundItemFilter to indicate that we don't * preserve rowid's during import. */ - if (state->s->filter == kSecBackupableItemFilter) { + if (item && item->attributes && state->s->filter == kSecBackupableItemFilter) { CFTypeRef pdmu; - + /* We don't filter non sys_bound items during import since we know we * will never have any in this case. */ - if (SecItemIsSystemBound(dict, state->class, inMultiUser)) + if (SecItemIsSystemBound(item->attributes, state->class, inMultiUser)) { + secdebug("item", "skipping backup of item: %@", dict); + CFReleaseNull(item); return; - - /* + } + + /* * Don't bother with u items when in edu mode since our current backup system * don't keep track of items that blongs to the device (u) but rather just * merge them into one blob. */ - if (inMultiUser && (pdmu = CFDictionaryGetValue(dict, kSecAttrAccessible))) { + if (inMultiUser && (pdmu = CFDictionaryGetValue(item->attributes, kSecAttrAccessible))) { if (CFEqual(pdmu, kSecAttrAccessibleWhenUnlockedThisDeviceOnly) || CFEqual(pdmu, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly) || CFEqual(pdmu, kSecAttrAccessibleWhenUnlockedThisDeviceOnly) || CFEqual(pdmu, kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly)) { secdebug("item", "Skipping KU item : %@", dict); + CFReleaseNull(item); return; } } @@ -1762,32 +1845,20 @@ SecServerImportItem(const void *value, void *context) /* Avoid importing token-based items. Although newer backups should not have them, * older (iOS9, iOS10.0) produced backups with token-based items. */ - if (CFDictionaryContainsKey(dict, kSecAttrTokenID)) { + if (CFDictionaryContainsKey(item->attributes, kSecAttrTokenID)) { secdebug("item", "Skipping token-based item : %@", dict); + CFReleaseNull(item); return; } } - SecDbItemRef item; - - /* This is sligthly confusing: - - During upgrade all items are exported with KEYBAG_NONE. - - During restore from backup, existing sys_bound items are exported with KEYBAG_NONE, and are exported as dictionary of attributes. - - Item in the actual backup are export with a real keybag, and are exported as encrypted v_Data and v_PersistentRef - */ - if (state->s->src_keybag == KEYBAG_NONE) { - item = SecDbItemCreateWithAttributes(kCFAllocatorDefault, state->class, dict, state->s->dest_keybag, &state->s->error); - } else { - item = SecDbItemCreateWithBackupDictionary(kCFAllocatorDefault, state->class, dict, state->s->src_keybag, state->s->dest_keybag, &state->s->error); - } - /* * */ - if (item) { + if (item && item->attributes) { CFDataRef musr = NULL; - CFDataRef musrBackup = CFDictionaryGetValue(dict, kSecAttrMultiUser); + CFDataRef musrBackup = CFDictionaryGetValue(item->attributes, kSecAttrMultiUser); CFDataRef systemKeychainUUID = SecMUSRGetSystemKeychainUUID(); bool systemKeychain = CFEqualSafe(musrBackup, systemKeychainUUID); @@ -1843,7 +1914,7 @@ SecServerImportItem(const void *value, void *context) SecDbItemClearRowId(item, NULL); SecDbItemInsert(item, state->s->dbt, &state->s->error); } - } + } /* Reset error if we had one, since we just skip the current item and continue importing what we can. */ @@ -1948,11 +2019,16 @@ bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt, SecurityClient *clie // Custom hack to support bluetooth's workflow for 11.3. Should be removed in a future release. __block CFErrorRef btError = NULL; bool deletedBT = kc_transaction(dbt, &btError, ^bool{ - bool ok = SecDbExec(dbt, CFSTR("DELETE FROM genp WHERE sync = 0 AND NOT agrp IN ('com.apple.security.sos', 'com.apple.security.sos-usercredential', 'com.apple.security.ckks');"), &btError); - ok &= SecDbExec(dbt, CFSTR("DELETE FROM inet WHERE sync = 0 AND NOT agrp IN ('com.apple.security.sos', 'com.apple.security.sos-usercredential', 'com.apple.security.ckks');"), &btError); - ok &= SecDbExec(dbt, CFSTR("DELETE FROM cert WHERE sync = 0 AND NOT agrp IN ('com.apple.security.sos', 'com.apple.security.sos-usercredential', 'com.apple.security.ckks');"), &btError); - ok &= SecDbExec(dbt, CFSTR("DELETE FROM keys WHERE sync = 0 AND NOT agrp IN ('com.apple.security.sos', 'com.apple.security.sos-usercredential', 'com.apple.security.ckks');"), &btError); - return ok; + +#define EXCLUDE_AGRPS "'com.apple.security.sos', 'com.apple.security.sos-usercredential', 'com.apple.security.ckks', 'com.apple.security.egoIdentities', 'com.apple.security.octagon'" + + bool tok = SecDbExec(dbt, CFSTR("DELETE FROM genp WHERE sync = 0 AND NOT agrp IN (" EXCLUDE_AGRPS ");"), &btError); + tok &= SecDbExec(dbt, CFSTR("DELETE FROM inet WHERE sync = 0 AND NOT agrp IN (" EXCLUDE_AGRPS ");"), &btError); + tok &= SecDbExec(dbt, CFSTR("DELETE FROM cert WHERE sync = 0 AND NOT agrp IN (" EXCLUDE_AGRPS ");"), &btError); + tok &= SecDbExec(dbt, CFSTR("DELETE FROM keys WHERE sync = 0 AND NOT agrp IN (" EXCLUDE_AGRPS ");"), &btError); + +#undef EXCLUDE_AGRPS + return tok; }); if (!deletedBT) { secerror("Unable to delete nonsyncable items prior to keychain restore: %@", btError); @@ -1993,7 +2069,9 @@ bool SecServerImportKeychainInPlist(SecDbConnectionRef dbt, SecurityClient *clie // If CKKS had spun up, it's very likely that we just deleted its data. // Tell it to perform a local resync. +#if OCTAGON SecCKKSPerformLocalResync(); +#endif errOut: CFReleaseSafe(sys_bound); @@ -2103,7 +2181,7 @@ bool s3dl_dbt_update_keys(SecDbConnectionRef dbt, SecurityClient *client, CFErro (keystore_generation_status & generation_change_in_progress)) { /* take a lock assertion */ - bool operated_while_unlocked = SecAKSDoWhileUserBagLocked(error, ^{ + bool operated_while_unlocked = SecAKSDoWithUserBagLockAssertion(error, ^{ CFErrorRef localError = NULL; CFDictionaryRef backup = SecServerCopyKeychainPlist(dbt, NULL, KEYBAG_DEVICE, KEYBAG_NONE, kSecNoItemFilter, &localError); diff --git a/OSX/sec/securityd/SecItemSchema.c b/OSX/sec/securityd/SecItemSchema.c index 53dbea4c..5b5b7dce 100644 --- a/OSX/sec/securityd/SecItemSchema.c +++ b/OSX/sec/securityd/SecItemSchema.c @@ -2,14 +2,14 @@ * Copyright (c) 2006-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, @@ -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@ */ @@ -30,6 +30,7 @@ #include "SecItemSchema.h" #include #include +#include "CheckV12DevEnabled.h" // MARK - // MARK Keychain version 6 schema @@ -239,6 +240,276 @@ SECDB_ATTR(v11_1lastunlock, "lastunlock", String, SecDbFlags( ,L, , , , SECDB_ATTR(v11_2actualKeyclass, "actualKeyclass", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v11_5octagonpeerid, "octagonpeerid", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); +SECDB_ATTR(v11_5octagonStatus, "octagonstatus", String, SecDbFlags( ,L, , , , , , , , , , , , , , ), NULL, NULL); + +SECDB_ATTR(v12_backupUUIDPrimary, "backupUUID", UUID, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v12_backupUUID, "backupUUID", UUID, SecDbFlags( ,L,I, , , , , , , , ,E, , , , ), NULL, NULL); +SECDB_ATTR(v12_backupBag, "backupbag", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v12_defaultValue, "defaultvalue", Number, SecDbFlags( ,L,I, , , , , , , ,Z, , , , , ), NULL, NULL); +SECDB_ATTR(v12_keyClassSigningKey, "signingkey", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v12_recoveryType, "recoverytype", String, SecDbFlags(P,L,I, , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v12_recoverySet, "recoveryset", Blob, SecDbFlags( ,L, , , , , , , , , , ,N, , , ), NULL, NULL); +SECDB_ATTR(v12_metadatakeydata, "metadatakeydata", Blob, SecDbFlags( ,L, , , , , , , , , ,E, , , , ), NULL, NULL); + +const SecDbClass v12_backupbags_class = { + .name = CFSTR("backupbags"), + .itemclass = false, + .attrs = { + &v12_backupUUIDPrimary, // primary + &v12_backupBag, + &v12_defaultValue, + 0 + } +}; + +const SecDbClass v12_backupkeyclasssigningkeys_class = { + .name = CFSTR("backupkeyclasssigningkeys"), + .itemclass = false, + .attrs = { + &v10keyclass, // primary + &v12_backupUUIDPrimary, // primary + &v12_keyClassSigningKey, + 0 + } +}; + +const SecDbClass v12_backuprecoverysets_class = { + .name = CFSTR("backuprecoverysets"), + .itemclass = false, + .attrs = { + &v12_backupUUIDPrimary, // primary + &v12_recoveryType, // primary + &v12_recoverySet, + 0 + } +}; + +const SecDbClass v12_metadatakeys_class = { + .name = CFSTR("metadatakeys"), + .itemclass = false, + .attrs = { + &v10keyclass, + &v11_2actualKeyclass, + &v6data, + &v12_metadatakeydata, + 0 + } +}; + +const SecDbClass v12_genp_class = { + .name = CFSTR("genp"), + .itemclass = true, + .attrs = { + &v6rowid, + &v6cdat, + &v6mdat, + &v6desc, + &v6icmt, + &v6crtr, + &v6type, + &v6scrp, + &v6labl, + &v6alis, + &v6invi, + &v6nega, + &v6cusi, + &v6prot, + &v6acct, + &v6svce, + &v6gena, + &v6data, + &v6agrp, + &v6pdmn, + &v6sync, + &v6tomb, + &v6sha1, + &v7vwht, + &v7tkid, + &v6v_Data, + &v6v_pk, + &v6accc, + &v7utomb, + &v8musr, + &v10itemuuid, + &v10sysbound, + &v10_1pcsservice, + &v10_1pcspublickey, + &v10_1pcspublicidentity, + &v10_1itempersistentref, + &v12_backupUUID, + 0 + }, +}; + +const SecDbClass v12_inet_class = { + .name = CFSTR("inet"), + .itemclass = true, + .attrs = { + &v6rowid, + &v6cdat, + &v6mdat, + &v6desc, + &v6icmt, + &v6crtr, + &v6type, + &v6scrp, + &v6labl, + &v6alis, + &v6invi, + &v6nega, + &v6cusi, + &v6prot, + &v6acct, + &v6sdmn, + &v6srvr, + &v6ptcl, + &v6atyp, + &v6port, + &v6path, + &v6data, + &v6agrp, + &v6pdmn, + &v6sync, + &v6tomb, + &v6sha1, + &v7vwht, + &v7tkid, + &v6v_Data, + &v6v_pk, + &v6accc, + &v7utomb, + &v8musr, + &v10itemuuid, + &v10sysbound, + &v10_1pcsservice, + &v10_1pcspublickey, + &v10_1pcspublicidentity, + &v10_1itempersistentref, + &v12_backupUUID, + 0 + }, +}; + +const SecDbClass v12_cert_class = { + .name = CFSTR("cert"), + .itemclass = true, + .attrs = { + &v6rowid, + &v6cdat, + &v6mdat, + &v6ctyp, + &v6cenc, + &v6labl, + &v6certalis, + &v6subj, + &v6issr, + &v6slnr, + &v6skid, + &v6pkhh, + &v6data, + &v6agrp, + &v6pdmn, + &v6sync, + &v6tomb, + &v6sha1, + &v7vwht, + &v7tkid, + &v6v_Data, + &v6v_pk, + &v6accc, + &v7utomb, + &v8musr, + &v10itemuuid, + &v10sysbound, + &v10_1pcsservice, + &v10_1pcspublickey, + &v10_1pcspublicidentity, + &v10_1itempersistentref, + &v12_backupUUID, + 0 + }, +}; + +const SecDbClass v12_keys_class = { + .name = CFSTR("keys"), + .itemclass = true, + .attrs = { + &v6rowid, + &v6cdat, + &v6mdat, + &v6kcls, + &v6labl, + &v6alis, + &v6perm, + &v6priv, + &v6modi, + &v6klbl, + &v6atag, + &v6keycrtr, + &v6keytype, + &v6bsiz, + &v6esiz, + &v6sdat, + &v6edat, + &v6sens, + &v6asen, + &v6extr, + &v6next, + &v6encr, + &v6decr, + &v6drve, + &v6sign, + &v6vrfy, + &v6snrc, + &v6vyrc, + &v6wrap, + &v6unwp, + &v6data, + &v6agrp, + &v6pdmn, + &v6sync, + &v6tomb, + &v6sha1, + &v7vwht, + &v7tkid, + &v6v_Data, + &v6v_pk, + &v6accc, + &v7utomb, + &v8musr, + &v10itemuuid, + &v10sysbound, + &v10_1pcsservice, + &v10_1pcspublickey, + &v10_1pcspublicidentity, + &v10_1itempersistentref, + &v12_backupUUID, + 0 + } +}; + +const SecDbClass v11_5_ckdevicestate_class = { + .name = CFSTR("ckdevicestate"), + .itemclass = false, + .attrs = { + &v10ckzone, + &v10_2device, + &v11_1osversion, + &v11_1lastunlock, + &v10_2peerid, + &v10_2circleStatus, + &v11_5octagonpeerid, + &v11_5octagonStatus, + &v10_2keyState, + &v10_2currentTLK, + &v10_2currentClassA, + &v10_2currentClassC, + &v10_1encRecord, + 0 + } +}; + const SecDbClass v11_2_metadatakeys_class = { .name = CFSTR("metadatakeys"), .itemclass = false, @@ -859,6 +1130,7 @@ const SecDbClass v10_0_ckstate_class = { /* Backup table */ /* Primary keys: v10primaryKey, v8musr */ +/* This table is currently unused */ const SecDbClass v10_0_item_backup_class = { .name = CFSTR("item_backup"), .itemclass = false, @@ -875,6 +1147,7 @@ const SecDbClass v10_0_item_backup_class = { /* Backup Keybag table */ /* Primary keys: v10publickeyHash, v8musr */ +/* This table is currently unused */ const SecDbClass v10_0_backup_keybag_class = { .name = CFSTR("backup_keybag"), .itemclass = false, @@ -939,6 +1212,81 @@ const SecDbClass v_identity_class = { }, }; +/* + * Version 12.0 + * Add backup/restore mechanism + */ +const SecDbSchema v12_0_schema = { + .majorVersion = 12, + .minorVersion = 0, + .classes = { + &v12_genp_class, + &v12_inet_class, + &v12_cert_class, + &v12_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_5_ckdevicestate_class, + &v10_5_tlkshare_class, + &v12_metadatakeys_class, + &v12_backupbags_class, + &v12_backupkeyclasssigningkeys_class, + &v12_backuprecoverysets_class, + 0 + } +}; + +/* + * Version 11.5 (Add octagon fields to device state) + */ +const SecDbSchema v11_5_schema = { + .majorVersion = 11, + .minorVersion = 5, + .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_5_ckdevicestate_class, + &v10_5_tlkshare_class, + &v11_2_metadatakeys_class, + 0 + } +}; + + /* * Version 11.4 (Add some more indexes) */ @@ -2517,7 +2865,31 @@ static const SecDbSchema v5_schema = { SecDbSchema const * const * kc_schemas = NULL; +const SecDbSchema *v10_kc_schemas_dev[] = { + &v12_0_schema, + &v11_5_schema, + &v11_4_schema, + &v11_3_schema, + &v11_2_schema, + &v11_1_schema, + &v11_schema, + &v10_5_schema, + &v10_4_schema, + &v10_3_schema, + &v10_2_schema, + &v10_1_schema, + &v10_0_schema, + &v9_1_schema, + &v9_schema, + &v8_schema, + &v7_schema, + &v6_schema, + &v5_schema, + 0 +}; + const SecDbSchema *v10_kc_schemas[] = { + &v11_5_schema, &v11_4_schema, &v11_3_schema, &v11_2_schema, @@ -2539,7 +2911,19 @@ const SecDbSchema *v10_kc_schemas[] = { }; const SecDbSchema * const * all_schemas() { - return v10_kc_schemas; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + if (checkV12DevEnabled()) { + secwarning("SecItemSchema: v12 development enabled, returning experimental schema"); + } else { + secnotice("SecItemSchema", "v12 development disabled, returning production schemas"); + } + }); + if (checkV12DevEnabled() != 0) { + return v10_kc_schemas_dev; + } else { + return v10_kc_schemas; + } } const SecDbSchema* current_schema() { diff --git a/OSX/sec/securityd/SecItemServer.c b/OSX/sec/securityd/SecItemServer.c index cd1f60b9..79cde4cb 100644 --- a/OSX/sec/securityd/SecItemServer.c +++ b/OSX/sec/securityd/SecItemServer.c @@ -27,6 +27,12 @@ passwords.) */ +#if TARGET_DARWINOS +#undef OCTAGON +#undef SECUREOBJECTSYNC +#undef SHAREDWEBCREDENTIALS +#endif + #include #include @@ -39,9 +45,10 @@ #include #include #include -#include -#include -#include +#include +#import "keychain/SecureObjectSync/SOSChangeTracker.h" +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSEngine.h" #include #include #include @@ -50,21 +57,27 @@ #include #include +#import "keychain/ot/OT.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/escrowrequest/EscrowRequestServerHelpers.h" #if USE_KEYSTORE + +#if __has_include() #include +#else +#include "OSX/utilities/SecAKSWrappers.h" +#endif + +#if __has_include() #include #endif -// TODO: Make this include work on both platforms. rdar://problem/16526848 -#if TARGET_OS_EMBEDDED -#include -#else -/* defines from */ -#define kSecEntitlementAssociatedDomains CFSTR("com.apple.developer.associated-domains") -#define kSecEntitlementPrivateAssociatedDomains CFSTR("com.apple.private.associated-domains") + +#include + #endif -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include #include #include @@ -83,6 +96,9 @@ #include #endif +#include + + #include "Analytics/Clients/LocalKeychainAnalytics.h" /* Changed the name of the keychain changed notification, for testing */ @@ -170,12 +186,12 @@ isClassD(SecDbItemRef item) { CFTypeRef accessible = SecDbItemGetCachedValueWithName(item, kSecAttrAccessible); - if (CFEqualSafe(accessible, kSecAttrAccessibleAlways) || CFEqualSafe(accessible, kSecAttrAccessibleAlwaysThisDeviceOnly)) + if (CFEqualSafe(accessible, kSecAttrAccessibleAlwaysPrivate) || CFEqualSafe(accessible, kSecAttrAccessibleAlwaysThisDeviceOnlyPrivate)) return true; return false; } -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR static int64_t measureDuration(struct timeval *start) @@ -213,7 +229,7 @@ measureUpgradePhase2(struct timeval *start, int64_t itemsMigrated) SecADSetValueForScalarKey(CFSTR("com.apple.keychain.phase2.migrated-items"), itemsMigrated); SecADSetValueForScalarKey(CFSTR("com.apple.keychain.phase2.migrated-time"), duration); } -#endif /* TARGET_OS_EMBEDDED */ +#endif /* TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */ static bool DBClassesAreEqual(const SecDbClass* class1, const SecDbClass* class2) { @@ -265,7 +281,7 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc SecDbQueryRef query = NULL; CFMutableStringRef sql = NULL; SecDbClass* renamedOldClass = NULL; -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR __block int64_t itemsMigrated = 0; struct timeval start; @@ -279,7 +295,9 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc int classIndex = 0; for (oldClass = oldSchema->classes, newClass = newSchema->classes; *newClass != NULL; classIndex++, oldClass++, newClass++) { - oldClassDone |= (*oldClass) == NULL; // Check if the new schema has more tables than the old + if (!oldClassDone) { + oldClassDone |= (*oldClass) == NULL; // Check if the new schema has more tables than the old + } if (!oldClassDone && !CFEqual((*oldClass)->name, (*newClass)->name) && ShouldRenameTable(*oldClass, *newClass, oldSchema->majorVersion)) { CFStringAppendFormat(sql, NULL, CFSTR("ALTER TABLE %@ RENAME TO %@_old;"), (*newClass)->name, (*oldClass)->name); @@ -365,7 +383,7 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc }, NULL, NULL, ^(SecDbItemRef item, bool *stop) { CFErrorRef localError = NULL; - #if TARGET_OS_EMBEDDED + #if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR itemsMigrated++; #endif // Switch item to the new class. @@ -476,7 +494,7 @@ static bool UpgradeSchemaPhase1(SecDbConnectionRef dbt, const SecDbSchema *oldSc LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase1DropOld, error ? *error : NULL)); } out: -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR measureUpgradePhase1(&start, ok, SecBucket2Significant(itemsMigrated)); #endif @@ -492,21 +510,32 @@ out: return ok; } -__thread SecDbConnectionRef dbt = NULL; +__thread SecDbConnectionRef threadDbt = NULL; // 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, int oldVersion, CFErrorRef *error) { - SecDbConnectionRef oldDbt = dbt; - dbt = inDbt; + SecDbConnectionRef oldDbt = threadDbt; + threadDbt = inDbt; __block bool ok = true; SecDbQueryRef query = NULL; -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR __block int64_t itemsMigrated = 0; struct timeval start; gettimeofday(&start, NULL); #endif +#if SECDB_BACKUPS_ENABLED + CFErrorRef backuperror = NULL; + if (!SecDbBackupCreateOrLoadBackupInfrastructure(&backuperror)) { + secerror("upgr: failed to create backup infrastructure: %@", backuperror); + } else { + secnotice("upgr", "setup backup infrastructure"); + } +#else + secnotice("upgr", "skipping backup setup for this platform"); +#endif + // Go through all classes in new schema const SecDbSchema *newSchema = current_schema(); int newVersion = SCHEMA_VERSION(newSchema); @@ -526,7 +555,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int ol query_destroy(query, NULL); } require_action_quiet(query = query_create(*class, SecMUSRGetAllViews(), NULL, error), out, ok = false); - ok &= SecDbItemSelect(query, dbt, error, NULL, ^bool(const SecDbAttr *attr) { + ok &= SecDbItemSelect(query, threadDbt, error, NULL, ^bool(const SecDbAttr *attr) { // No simple per-attribute filtering. return false; }, ^bool(CFMutableStringRef sql, bool *needWhere) { @@ -540,7 +569,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int ol }, ^(SecDbItemRef item, bool *stop) { CFErrorRef localError = NULL; -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR itemsMigrated++; #endif @@ -557,11 +586,11 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int ol if (CFEqualSafe(SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup), kSecAttrAccessGroupToken) && SecDbItemGetCachedValueWithName(item, kSecAttrTokenID) == NULL) { secnotice("upgr", "dropping item during item upgrade due to agrp=com.apple.token: %@", item); - ok = SecDbItemDelete(item, dbt, kCFBooleanFalse, &localError); + ok = SecDbItemDelete(item, threadDbt, kCFBooleanFalse, &localError); } else { // Replace item with the new value in the table; this will cause the item to be decoded and recoded back, // incl. recalculation of item's hash. - ok = SecDbItemUpdate(item, item, dbt, false, query->q_uuid_from_primary_key, &localError); + ok = SecDbItemUpdate(item, item, threadDbt, false, query->q_uuid_from_primary_key, &localError); } } @@ -574,7 +603,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int ol // make sure we use a local error so that this error is not proppaged upward and cause a // migration failure. CFErrorRef deleteError = NULL; - (void)SecDbItemDelete(item, dbt, false, &deleteError); + (void)SecDbItemDelete(item, threadDbt, false, &deleteError); CFReleaseNull(deleteError); ok = true; break; @@ -629,7 +658,7 @@ static bool UpgradeItemPhase2(SecDbConnectionRef inDbt, bool *inProgress, int ol require_action(ok, out, LKAReportKeychainUpgradeOutcomeWithError(oldVersion, newVersion, LKAKeychainUpgradeOutcomePhase2, error ? *error : NULL)); } -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR measureUpgradePhase2(&start, SecBucket2Significant(itemsMigrated)); #endif @@ -637,7 +666,7 @@ out: if (query != NULL) query_destroy(query, NULL); - dbt = oldDbt; + threadDbt = oldDbt; return ok; } @@ -645,7 +674,7 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, __block bool didPhase2 = false; __block bool ok = true; __block CFErrorRef localError = NULL; - + if (error) *error = NULL; @@ -766,7 +795,7 @@ static bool SecKeychainDbUpgradeFromVersion(SecDbConnectionRef dbt, int version, }); if (ok && didPhase2) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR SecADSetValueForScalarKey(CFSTR("com.apple.keychain.migration-success"), 1); #endif } @@ -809,7 +838,7 @@ out: if (markedCorrupt) { secerror("upgrade: marking database as corrupt"); SecDbCorrupt(dbt, localError); -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR SecADSetValueForScalarKey(CFSTR("com.apple.keychain.migration-failure"), 1); #endif } @@ -825,7 +854,7 @@ out: for (SecDbClass const* const* newClass = newSchema->classes; *newClass; ++newClass) { SecDbForEachAttrWithMask((*newClass), desc, kSecDbIndexFlag | kSecDbInFlag) { CFStringRef sql = NULL; - CFErrorRef localError = NULL; + CFErrorRef classLocalError = NULL; bool localOk = true; if (desc->kind == kSecDbSyncAttr) { @@ -835,13 +864,13 @@ out: } 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); + localOk &= SecDbExec(dbt, sql, &classLocalError); CFReleaseNull(sql); if(!localOk) { - secerror("upgrade: unable to opportunistically create index (%@,%@): %@", (*newClass)->name, desc->name, localError); + secerror("upgrade: unable to opportunistically create index (%@,%@): %@", (*newClass)->name, desc->name, classLocalError); } - CFReleaseNull(localError); + CFReleaseNull(classLocalError); } } } @@ -1024,6 +1053,7 @@ static bool SecServerKeychainRestore(SecDbConnectionRef dbt, bool ok = false; keybag_handle_t backup_keybag; + secnotice("SecServerKeychainRestore", "Restoring keychain backup"); SecSignpostStart(SecSignpostRestoreOpenKeybag); #if USE_KEYSTORE @@ -1049,20 +1079,22 @@ out: #endif if (ok) { - secwarning("Restore completed sucessfully"); + secnotice("SecServerKeychainRestore", "Restore completed successfully"); } else { - secwarning("Restore failed with: %@", error ? *error : NULL); + secwarning("SecServerKeychainRestore: Restore failed with: %@", error ? *error : NULL); } return ok; } - // MARK - External SPI support code. CFStringRef __SecKeychainCopyPath(void) { CFStringRef kcRelPath = NULL; - if (use_hwaes()) { + + if (os_variant_is_recovery("securityd")) { + kcRelPath = CFSTR("keychain-recovery-2.db"); + } else if (use_hwaes()) { kcRelPath = CFSTR("keychain-2.db"); } else { kcRelPath = CFSTR("keychain-2-debug.db"); @@ -1084,19 +1116,19 @@ SecDbRef SecKeychainDbCreate(CFStringRef path, CFErrorRef* error) { __block CFErrorRef localerror = NULL; SecDbRef kc = SecDbCreate(path, 0600, true, true, true, true, kSecDbMaxIdleHandles, - ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *error) + ^bool (SecDbRef db, SecDbConnectionRef dbconn, bool didCreate, bool *callMeAgainForNextConnection, CFErrorRef *createError) { // Upgrade from version 0 means create the schema in empty db. int version = 0; bool ok = true; if (!didCreate) - ok = SecKeychainDbGetVersion(dbconn, &version, error); + ok = SecKeychainDbGetVersion(dbconn, &version, createError); - ok = ok && SecKeychainDbUpgradeFromVersion(dbconn, version, callMeAgainForNextConnection, error); + ok = ok && SecKeychainDbUpgradeFromVersion(dbconn, version, callMeAgainForNextConnection, createError); if (!ok) - secerror("Upgrade %sfailed: %@", didCreate ? "from v0 " : "", error ? *error : NULL); + secerror("Upgrade %sfailed: %@", didCreate ? "from v0 " : "", createError ? *createError : NULL); - localerror = error ? *error : NULL; + localerror = createError ? *createError : NULL; if(ok) { // This block might get called many, many times due to callMeAgainForNextConnection. @@ -1132,6 +1164,18 @@ SecDbRef SecKeychainDbInitialize(SecDbRef db) { }); } + + if(OctagonIsEnabled() && OctagonShouldPerformInitialization()) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + OctagonInitialize(); + }); + } + + if(EscrowRequestServerIsEnabled()) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + EscrowRequestServerInitialize(); + }); + } #endif return db; @@ -1219,32 +1263,34 @@ bool kc_with_custom_db(bool writeAndRead, bool usesItemTables, SecDbRef db, CFEr if (db && db != kc_dbhandle(error)) { __block bool result = false; if (writeAndRead) { - return SecDbPerformWrite(db, error, ^(SecDbConnectionRef dbconn) { + SecDbPerformWrite(db, error, ^(SecDbConnectionRef dbconn) { result = perform(dbconn); }); } else { - return SecDbPerformRead(db, error, ^(SecDbConnectionRef dbconn) { + SecDbPerformRead(db, error, ^(SecDbConnectionRef dbconn) { result = perform(dbconn); }); } return result; } - if(dbt) { + if(threadDbt) { // The kc_with_dbt upthread will clean this up when it's done. - return perform(dbt); + return perform(threadDbt); } if (writeAndRead && usesItemTables) { +#if SECUREOBJECTSYNC SecItemDataSourceFactoryGetDefault(); +#endif } bool ok = false; - if (kc_acquire_dbt(writeAndRead, &dbt, error)) { - ok = perform(dbt); - SecDbConnectionRelease(dbt); - dbt = NULL; + if (kc_acquire_dbt(writeAndRead, &threadDbt, error)) { + ok = perform(threadDbt); + SecDbConnectionRelease(threadDbt); + threadDbt = NULL; } return ok; } @@ -1495,10 +1541,12 @@ out: **************** Beginning of Externally Callable Interface **************** ****************************************************************************/ -static bool SecEntitlementError(OSStatus status, CFErrorRef *error) +static bool SecEntitlementError(CFErrorRef *error) { #if TARGET_OS_OSX -#define SEC_ENTITLEMENT_WARNING CFSTR("com.apple.application-identifier, com.apple.security.application-groups nor keychain-access-groups") +#define SEC_ENTITLEMENT_WARNING CFSTR("com.apple.application-identifier nor com.apple.security.application-groups nor keychain-access-groups") +#elif TARGET_OS_IOSMAC +#define SEC_ENTITLEMENT_WARNING CFSTR("com.apple.developer.associated-application-identifier nor application-identifier nor com.apple.security.application-groups nor keychain-access-groups") #else #define SEC_ENTITLEMENT_WARNING CFSTR("application-identifier nor keychain-access-groups") #endif @@ -1506,6 +1554,11 @@ static bool SecEntitlementError(OSStatus status, CFErrorRef *error) return SecError(errSecMissingEntitlement, error, CFSTR("Client has neither %@ entitlements"), SEC_ENTITLEMENT_WARNING); } +static bool SecEntitlementErrorForExplicitAccessGroup(CFStringRef agrp, CFArrayRef clientGroups, CFErrorRef* error) +{ + return SecError(errSecMissingEntitlement, error, CFSTR("Client explicitly specifies access group %@ but is only entitled for %@"), agrp, clientGroups); +} + static CFStringRef CopyAccessGroupForRowID(sqlite_int64 rowID, CFStringRef itemClass) { __block CFStringRef accessGroup = NULL; @@ -1543,12 +1596,12 @@ static bool SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, SecurityClient *client, CFErrorRef *error) { - CFArrayRef accessGroups = client->accessGroups; - CFMutableArrayRef mutableAccessGroups = NULL; + CFArrayRef accessGroups = CFRetainSafe(client->accessGroups); CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - return SecEntitlementError(errSecMissingEntitlement, error); + CFReleaseNull(accessGroups); + return SecEntitlementError(error); } SecSignpostStart(SecSignpostSecItemCopyMatching); @@ -1560,8 +1613,9 @@ SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, if (persistentRef && _SecItemParsePersistentRef(persistentRef, &itemClass, &itemRowID, NULL)) { CFStringRef accessGroup = CopyAccessGroupForRowID(itemRowID, itemClass); if (accessGroup && CFStringHasSuffix(accessGroup, kSecNetworkExtensionAccessGroupSuffix) && !CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), accessGroup)) { - mutableAccessGroups = CFArrayCreateMutableCopy(NULL, 0, accessGroups); + CFMutableArrayRef mutableAccessGroups = CFArrayCreateMutableCopy(NULL, 0, accessGroups); CFArrayAppendValue(mutableAccessGroups, accessGroup); + CFReleaseNull(accessGroups); accessGroups = mutableAccessGroups; } CFReleaseNull(accessGroup); @@ -1570,19 +1624,36 @@ SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, if (CFArrayContainsValue(accessGroups, CFRangeMake(0, ag_count), CFSTR("*"))) { /* Having the special accessGroup "*" allows access to all accessGroups. */ - accessGroups = NULL; + CFReleaseNull(accessGroups); } bool ok = false; Query *q = query_create_with_limit(query, client->musr, 1, error); if (q) { CFStringRef agrp = CFDictionaryGetValue(q->q_item, kSecAttrAccessGroup); - if (agrp && accessGroupsAllows(accessGroups, agrp, client)) { - // TODO: Return an error if agrp is not NULL and accessGroupsAllows() fails above. - const void *val = agrp; - accessGroups = CFArrayCreate(0, &val, 1, &kCFTypeArrayCallBacks); + if (agrp) { + if (accessGroupsAllows(accessGroups, agrp, client)) { + const void *val = agrp; + CFReleaseNull(accessGroups); + accessGroups = CFArrayCreate(0, &val, 1, &kCFTypeArrayCallBacks); + } else { + (void)SecEntitlementErrorForExplicitAccessGroup(agrp, accessGroups, error); + CFReleaseNull(accessGroups); + query_destroy(q, NULL); + return false; + } } else { - CFRetainSafe(accessGroups); +#if !TARGET_OS_OSX + if (accessGroups != NULL) { + // On iOS, drop 'com.apple.token' AG from allowed accessGroups, to avoid inserting token elements into + // unsuspecting application's keychain. If the application on iOS wants to access token items, it needs + // explicitly specify kSecAttrAccessGroup=kSecAttrAccessGroupToken in its query. + CFMutableArrayRef mutableGroups = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, accessGroups); + CFArrayRemoveAllValue(mutableGroups, kSecAttrAccessGroupToken); + CFReleaseNull(accessGroups); + accessGroups = mutableGroups; + } +#endif } #if TARGET_OS_IPHONE @@ -1625,11 +1696,10 @@ SecItemServerCopyMatching(CFDictionaryRef query, CFTypeRef *result, }); } - CFReleaseSafe(accessGroups); if (!query_destroy(q, error)) ok = false; } - CFReleaseNull(mutableAccessGroups); + CFReleaseNull(accessGroups); SecSignpostStop(SecSignpostSecItemCopyMatching); @@ -1688,7 +1758,7 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { CFReleaseNull(accessGroups); - return SecEntitlementError(errSecMissingEntitlement, error); + return SecEntitlementError(error); } SecSignpostStart(SecSignpostSecItemAdd); @@ -1706,8 +1776,7 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul if (agrp) { /* The user specified an explicit access group, validate it. */ if (!accessGroupsAllows(accessGroups, agrp, client)) - ok = SecError(errSecMissingEntitlement, error, - CFSTR("explicit accessGroup %@ not in client access %@"), agrp, accessGroups); + ok = SecEntitlementErrorForExplicitAccessGroup(agrp, accessGroups, error); } else { agrp = (CFStringRef)CFArrayGetValueAtIndex(client->accessGroups, 0); @@ -1768,10 +1837,10 @@ _SecItemAdd(CFDictionaryRef attributes, SecurityClient *client, CFTypeRef *resul } else { ok = false; } + CFReleaseNull(accessGroups); SecSignpostStop(SecSignpostSecItemAdd); - CFReleaseNull(accessGroups); return ok; } @@ -1788,7 +1857,16 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { CFReleaseNull(accessGroups); - return SecEntitlementError(errSecMissingEntitlement, error); + return SecEntitlementError(error); + } + + // Queries using implicit access groups which only find items that're inaccessible yield errSecItemNotFound, + // but we can pre-emptively shut down queries which are clearly illegal + CFTypeRef q_agrp = CFDictionaryGetValue(query, kSecAttrAccessGroup); + if (q_agrp && !accessGroupsAllows(accessGroups, q_agrp, client)) { + SecEntitlementErrorForExplicitAccessGroup(q_agrp, accessGroups, error); + CFReleaseSafe(accessGroups); + return false; } SecSignpostStart(SecSignpostSecItemUpdate); @@ -1851,7 +1929,8 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, /* The user is attempting to modify the access group column, validate it to make sure the new value is allowable. */ if (!accessGroupsAllows(accessGroups, agrp, client)) { - ok = SecError(errSecNoAccessForItem, error, CFSTR("accessGroup %@ not in %@"), agrp, accessGroups); + secerror("Cannot update keychain item to access group %@", agrp); + ok = SecEntitlementErrorForExplicitAccessGroup(agrp, accessGroups, error); } } } @@ -1866,10 +1945,10 @@ _SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate, if (q) { ok = query_notify_and_destroy(q, ok, error); } + CFReleaseNull(accessGroups); SecSignpostStop(SecSignpostSecItemUpdate); - CFReleaseNull(accessGroups); return ok; } @@ -1885,7 +1964,14 @@ _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { CFReleaseNull(accessGroups); - return SecEntitlementError(errSecMissingEntitlement, error); + return SecEntitlementError(error); + } + + CFTypeRef q_agrp = CFDictionaryGetValue(query, kSecAttrAccessGroup); + if (q_agrp && !accessGroupsAllows(accessGroups, q_agrp, client)) { + SecEntitlementErrorForExplicitAccessGroup(q_agrp, accessGroups, error); + CFReleaseSafe(accessGroups); + return false; } SecSignpostStart(SecSignpostSecItemDelete); @@ -1943,10 +2029,10 @@ _SecItemDelete(CFDictionaryRef query, SecurityClient *client, CFErrorRef *error) } else { ok = false; } + CFReleaseNull(accessGroups); SecSignpostStop(SecSignpostSecItemDelete); - CFReleaseNull(accessGroups); return ok; } @@ -2001,7 +2087,7 @@ bool _SecItemUpdateTokenItems(CFStringRef tokenID, CFArrayRef items, SecurityCli CFArrayRef accessGroups = client->accessGroups; CFIndex ag_count; if (!accessGroups || 0 == (ag_count = CFArrayGetCount(accessGroups))) { - return SecEntitlementError(errSecMissingEntitlement, error); + return SecEntitlementError(error); } ok = kc_with_dbt(true, error, ^bool (SecDbConnectionRef dbt) { @@ -2187,7 +2273,7 @@ fail: // MARK: - // MARK: Shared web credentials -#if TARGET_OS_IOS && !TARGET_OS_BRIDGE +#if SHAREDWEBCREDENTIALS /* constants */ #define SEC_CONST_DECL(k,v) const CFStringRef k = CFSTR(v); @@ -2198,13 +2284,15 @@ SEC_CONST_DECL (kSecSafariPasswordsNotSaved, "Passwords not saved"); SEC_CONST_DECL (kSecSharedCredentialUrlScheme, "https://"); SEC_CONST_DECL (kSecSharedWebCredentialsService, "webcredentials"); -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static SWCFlags _SecAppDomainApprovalStatus(CFStringRef appID, CFStringRef fqdn, CFErrorRef *error) { __block SWCFlags flags = kSWCFlags_None; OSStatus status; + secnotice("swc", "Application %@ is requesting approval for %@", appID, fqdn); + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); if (semaphore == NULL) return 0; @@ -2228,11 +2316,7 @@ _SecAppDomainApprovalStatus(CFStringRef appID, CFStringRef fqdn, CFErrorRef *err if (error) { if (!(flags & kSWCFlag_SiteApproved)) { - if (flags & kSWCFlag_Pending) { - SecError(errSecAuthFailed, error, CFSTR("Approval is pending for \"%@\", try later"), fqdn); - } else { - SecError(errSecAuthFailed, error, CFSTR("\"%@\" failed to approve \"%@\""), fqdn, appID); - } + SecError(errSecAuthFailed, error, CFSTR("\"%@\" failed to approve \"%@\""), fqdn, appID); } else if (flags & kSWCFlag_UserDenied) { SecError(errSecAuthFailed, error, CFSTR("User denied access to \"%@\" by \"%@\""), fqdn, appID); } @@ -2271,7 +2355,7 @@ _SecEntitlementContainsDomainForService(CFArrayRef domains, CFStringRef domain, static bool _SecAddNegativeWebCredential(SecurityClient *client, CFStringRef fqdn, CFStringRef appID, bool forSafari) { -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR bool result = false; if (!fqdn) { return result; } @@ -2409,7 +2493,7 @@ _SecAddSharedWebCredential(CFDictionaryRef attributes, goto cleanup; } -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR secerror("app/site association entitlements not checked in Simulator"); #else OSStatus status = errSecMissingEntitlement; @@ -2433,7 +2517,7 @@ _SecAddSharedWebCredential(CFDictionaryRef attributes, } #endif -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR secerror("Ignoring app/site approval state in the Simulator."); #else // get approval status for this app/domain pair @@ -2500,7 +2584,9 @@ _SecAddSharedWebCredential(CFDictionaryRef attributes, CFDictionaryAddValue(attrs, kSecAttrComment, kSecSafariDefaultComment); ok = samePassword || swca_confirm_operation(swca_update_request_id, clientAuditToken, query, error, - ^void (CFStringRef fqdn) { _SecAddNegativeWebCredential(client, fqdn, appID, false); }); + ^void (CFStringRef confirm_fqdn) { + _SecAddNegativeWebCredential(client, confirm_fqdn, appID, false); + }); if (ok) { ok = _SecItemUpdate(query, attrs, &swcclient, error); } @@ -2509,7 +2595,9 @@ _SecAddSharedWebCredential(CFDictionaryRef attributes, // confirm the delete // (per rdar://16676288 we always prompt, even if there was prior user approval) ok = /*approved ||*/ swca_confirm_operation(swca_delete_request_id, clientAuditToken, query, error, - ^void (CFStringRef fqdn) { _SecAddNegativeWebCredential(client, fqdn, appID, false); }); + ^void (CFStringRef confirm_fqdn) { + _SecAddNegativeWebCredential(client, confirm_fqdn, appID, false); + }); if (ok) { ok = _SecItemDelete(query, &swcclient, error); } @@ -2555,8 +2643,8 @@ _SecAddSharedWebCredential(CFDictionaryRef attributes, } // confirm the add - ok = swca_confirm_operation(swca_add_request_id, clientAuditToken, query, error, ^void (CFStringRef fqdn) { - _SecAddNegativeWebCredential(client, fqdn, appID, false); + ok = swca_confirm_operation(swca_add_request_id, clientAuditToken, query, error, ^void (CFStringRef confirm_fqdn) { + _SecAddNegativeWebCredential(client, confirm_fqdn, appID, false); }); } if (ok) { @@ -2586,7 +2674,6 @@ _SecCopySharedWebCredential(CFDictionaryRef query, CFMutableArrayRef fqdns = NULL; CFStringRef fqdn = NULL; CFStringRef account = NULL; - CFIndex idx, count; SInt32 port = -1; bool ok = false; @@ -2603,7 +2690,7 @@ _SecCopySharedWebCredential(CFDictionaryRef query, .allowSystemKeychain = false, .allowSyncBubbleKeychain = false, .isNetworkExtension = false, - .musr = client->musr, + .musr = client->musr, }; // On input, the query dictionary contains optional fqdn and account entries. @@ -2637,6 +2724,8 @@ _SecCopySharedWebCredential(CFDictionaryRef query, } } } + CFIndex count, idx; + count = CFArrayGetCount(fqdns); if (count < 1) { SecError(errSecParam, error, CFSTR("No domain provided")); @@ -2669,7 +2758,7 @@ _SecCopySharedWebCredential(CFDictionaryRef query, } } -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR secerror("app/site association entitlements not checked in Simulator"); #else OSStatus status = errSecMissingEntitlement; @@ -2726,7 +2815,7 @@ _SecCopySharedWebCredential(CFDictionaryRef query, CFReleaseNull(*error); } if (ok && items && CFGetTypeID(items) == CFArrayGetTypeID()) { -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR secerror("Ignoring app/site approval state in the Simulator."); bool approved = true; #else @@ -2790,7 +2879,11 @@ _SecCopySharedWebCredential(CFDictionaryRef query, CFReleaseSafe(password); } } - if (icmt && CFEqual(icmt, kSecSafariDefaultComment)) { + + if (acct && CFEqual(acct, kSecSafariPasswordsNotSaved)) { + // Do not add to credentials list! + secwarning("copySWC: Skipping \"%@\" item", kSecSafariPasswordsNotSaved); + } else if (icmt && CFEqual(icmt, kSecSafariDefaultComment)) { CFArrayInsertValueAtIndex(credentials, 0, newdict); } else { CFArrayAppendValue(credentials, newdict); @@ -2799,12 +2892,10 @@ _SecCopySharedWebCredential(CFDictionaryRef query, CFReleaseSafe(newdict); } + count = CFArrayGetCount(credentials); if (count) { - ok = false; - // create a new array of dictionaries (without the actual password) for picker UI - count = CFArrayGetCount(credentials); CFMutableArrayRef items = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); for (idx = 0; idx < count; idx++) { CFDictionaryRef dict = (CFDictionaryRef) CFArrayGetValueAtIndex(credentials, idx); @@ -2847,14 +2938,14 @@ _SecCopySharedWebCredential(CFDictionaryRef query, CFReleaseSafe(items); CFArrayRemoveAllValues(credentials); if (selected && ok) { -#if TARGET_OS_IPHONE && !TARGET_OS_WATCH +#if TARGET_OS_IOS && !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR fqdn = CFDictionaryGetValue(selected, kSecAttrServer); #endif CFArrayAppendValue(credentials, selected); } if (ok) { -#if TARGET_OS_IOS && !TARGET_OS_BRIDGE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IOS && !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR // register confirmation with database CFRetainSafe(appID); CFRetainSafe(fqdn); @@ -2891,7 +2982,7 @@ cleanup: return ok; } -#endif /* TARGET_OS_IOS */ +#endif /* SHAREDWEBCREDENTIALS */ // MARK: - @@ -2900,24 +2991,31 @@ cleanup: CF_RETURNS_RETAINED CFDataRef _SecServerKeychainCreateBackup(SecurityClient *client, CFDataRef keybag, CFDataRef passcode, bool emcs, CFErrorRef *error) { __block CFDataRef backup; - kc_with_dbt(true, error, ^bool (SecDbConnectionRef dbt) { - if (!dbt) - return NULL; + kc_with_dbt(false, error, ^bool (SecDbConnectionRef dbt) { + + LKABackupReportStart(!!keybag, !!passcode, emcs); + + return kc_transaction_type(dbt, kSecDbNormalTransactionType, error, ^bool{ + secnotice("SecServerKeychainCreateBackup", "Performing backup from %s keybag%s", keybag ? "provided" : "device", emcs ? ", EMCS mode" : ""); - if (keybag == NULL && passcode == NULL) { + if (keybag == NULL && passcode == NULL) { #if USE_KEYSTORE - backup = SecServerExportBackupableKeychain(dbt, client, KEYBAG_DEVICE, backup_keybag_handle, error); + backup = SecServerExportBackupableKeychain(dbt, client, KEYBAG_DEVICE, backup_keybag_handle, error); #else /* !USE_KEYSTORE */ - (void)client; - SecError(errSecParam, error, CFSTR("Why are you doing this?")); - backup = NULL; + (void)client; + SecError(errSecParam, error, CFSTR("Why are you doing this?")); + backup = NULL; #endif /* USE_KEYSTORE */ - } else { - backup = SecServerKeychainCreateBackup(dbt, client, keybag, passcode, emcs, error); - } - return (backup != NULL); + } else { + backup = SecServerKeychainCreateBackup(dbt, client, keybag, passcode, emcs, error); + } + return (backup != NULL); + }); }); + secnotice("SecServerKeychainCreateBackup", "Backup result: %s (%@)", backup ? "success" : "fail", error ? *error : NULL); + LKABackupReportEnd(!!backup, error ? *error : NULL); + return backup; } @@ -2962,6 +3060,8 @@ _SecServerBackupCopyUUID(CFDataRef data, CFErrorRef *error) // MARK: - // MARK: SecItemDataSource +#if SECUREOBJECTSYNC + // Make sure to call this before any writes to the keychain, so that we fire // up the engines to monitor manifest changes. SOSDataSourceFactoryRef SecItemDataSourceFactoryGetDefault(void) { @@ -3162,6 +3262,7 @@ _SecServerRestoreSyncable(CFDictionaryRef backup, CFDataRef keybag, CFDataRef pa errOut: return ok; } +#endif /* SECUREOBJECTSYNC */ bool _SecServerRollKeysGlue(bool force, CFErrorRef *error) { return _SecServerRollKeys(force, NULL, error); @@ -3728,24 +3829,24 @@ _SecServerTransmogrifyToSystemKeychain(SecurityClient *client, CFErrorRef *error }, ^bool(sqlite3_stmt *stmt, int col) { return SecDbBindObject(stmt, col++, SecMUSRGetSingleUserKeychainUUID(), error); }, ^(SecDbItemRef item, bool *stop) { - CFErrorRef localError = NULL; + CFErrorRef itemError = NULL; - if (!SecDbItemSetValueWithName(item, kSecAttrMultiUser, systemUUID, &localError)) { - secerror("item: %@ update musr to system failed: %@", item, localError); + if (!SecDbItemSetValueWithName(item, kSecAttrMultiUser, systemUUID, &itemError)) { + secerror("item: %@ update musr to system failed: %@", item, itemError); ok = false; goto out; } - if (!SecDbItemDoUpdate(item, item, dbt, &localError, ^bool (const SecDbAttr *attr) { + if (!SecDbItemDoUpdate(item, item, dbt, &itemError, ^bool (const SecDbAttr *attr) { return attr->kind == kSecDbRowIdAttr; })) { - secerror("item: %@ insert during UPDATE: %@", item, localError); + secerror("item: %@ insert during UPDATE: %@", item, itemError); ok = false; goto out; } out: - SecErrorPropagate(localError, error); + SecErrorPropagate(itemError, error); }); if (q) @@ -3789,63 +3890,6 @@ _SecServerDeleteMUSERViews(SecurityClient *client, uid_t uid, CFErrorRef *error) #endif /* TARGET_OS_IOS */ -bool -_SecServerGetKeyStats(const SecDbClass *qclass, - struct _SecServerKeyStats *stats) -{ - __block CFErrorRef error = NULL; - bool res = false; - - Query *q = query_create(qclass, NULL, NULL, &error); - require(q, fail); - - q->q_return_type = kSecReturnDataMask | kSecReturnAttributesMask; - q->q_limit = kSecMatchUnlimited; - q->q_keybag = KEYBAG_DEVICE; - query_add_or_attribute(kSecAttrAccessible, kSecAttrAccessibleWhenUnlocked, q); - query_add_or_attribute(kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock, q); - query_add_or_attribute(kSecAttrAccessible, kSecAttrAccessibleAlways, q); - query_add_or_attribute(kSecAttrAccessible, kSecAttrAccessibleWhenUnlockedThisDeviceOnly, q); - query_add_or_attribute(kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, q); - query_add_or_attribute(kSecAttrAccessible, kSecAttrAccessibleAlwaysThisDeviceOnly, q); - query_add_attribute(kSecAttrTombstone, kCFBooleanFalse, q); - - kc_with_dbt(false, &error, ^(SecDbConnectionRef dbconn) { - CFErrorRef error2 = NULL; - __block CFIndex totalSize = 0; - stats->maxDataSize = 0; - - SecDbItemSelect(q, dbconn, &error2, NULL, ^bool(const SecDbAttr *attr) { - return CFDictionaryContainsKey(q->q_item, attr->name); - }, NULL, NULL, ^(SecDbItemRef item, bool *stop) { - CFErrorRef error3 = NULL; - CFDataRef data = SecDbItemGetValue(item, &v6v_Data, &error3); - if (isData(data)) { - CFIndex size = CFDataGetLength(data); - if (size > stats->maxDataSize) - stats->maxDataSize = size; - totalSize += size; - stats->items++; - } - CFReleaseNull(error3); - }); - CFReleaseNull(error2); - if (stats->items) - stats->averageSize = totalSize / stats->items; - - return (bool)true; - }); - - - res = true; - -fail: - CFReleaseNull(error); - if (q) - query_destroy(q, NULL); - return res; -} - CFArrayRef _SecItemCopyParentCertificates(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error) { const void *keys[] = { kSecClass, diff --git a/OSX/sec/securityd/SecItemServer.h b/OSX/sec/securityd/SecItemServer.h index 9755d77c..7b550e49 100644 --- a/OSX/sec/securityd/SecItemServer.h +++ b/OSX/sec/securityd/SecItemServer.h @@ -31,9 +31,9 @@ #define _SECURITYD_SECITEMSERVER_H_ #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "securityd/SecDbQuery.h" +#include "utilities/SecDb.h" #include #include "sec/ipc/securityd_client.h" @@ -115,14 +115,6 @@ bool _SecServerRollKeysGlue(bool force, CFErrorRef *error); CFArrayRef _SecServerCopyInitialSyncCredentials(uint32_t flags, CFErrorRef *error); bool _SecServerImportInitialSyncCredentials(CFArrayRef array, CFErrorRef *error); -struct _SecServerKeyStats { - unsigned long items; - CFIndex maxDataSize; - CFIndex averageSize; -}; - -bool _SecServerGetKeyStats(const SecDbClass *qclass, struct _SecServerKeyStats *stats); - CF_RETURNS_RETAINED CFArrayRef _SecItemCopyParentCertificates(CFDataRef normalizedIssuer, CFArrayRef accessGroups, CFErrorRef *error); bool _SecItemCertificateExists(CFDataRef normalizedIssuer, CFDataRef serialNumber, CFArrayRef accessGroups, CFErrorRef *error); diff --git a/OSX/sec/securityd/SecKeybagSupport.c b/OSX/sec/securityd/SecKeybagSupport.c index ed026e45..d9c80487 100644 --- a/OSX/sec/securityd/SecKeybagSupport.c +++ b/OSX/sec/securityd/SecKeybagSupport.c @@ -28,19 +28,16 @@ */ #include +#include #include #if USE_KEYSTORE #include -#include #include #include #include #include -#if TARGET_OS_EMBEDDED -#include -#endif #else /* !USE_KEYSTORE */ #include #endif /* USE_KEYSTORE */ @@ -48,11 +45,12 @@ #include #include +#include "OSX/utilities/SecAKSWrappers.h" /* g_keychain_handle is the keybag handle used for encrypting item in the keychain. For testing purposes, it can be set to something other than the default, with SecItemServerSetKeychainKeybag */ #if USE_KEYSTORE -#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED +#if TARGET_OS_OSX keybag_handle_t g_keychain_keybag = session_keybag_handle; #else keybag_handle_t g_keychain_keybag = device_keybag_handle; @@ -72,7 +70,7 @@ void SecItemServerSetKeychainKeybag(int32_t keybag) void SecItemServerResetKeychainKeybag(void) { #if USE_KEYSTORE -#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED +#if TARGET_OS_OSX g_keychain_keybag = session_keybag_handle; #else g_keychain_keybag = device_keybag_handle; @@ -82,41 +80,6 @@ void SecItemServerResetKeychainKeybag(void) #endif /* USE_KEYSTORE */ } -#if USE_KEYSTORE - -static bool hwaes_key_available(void) -{ - keybag_handle_t handle = bad_keybag_handle; - keybag_handle_t special_handle = bad_keybag_handle; -#if TARGET_OS_OSX - special_handle = session_keybag_handle; -#elif TARGET_OS_EMBEDDED - special_handle = device_keybag_handle; -#else -#error "supported keybag target" -#endif - - kern_return_t kr = aks_get_system(special_handle, &handle); - if (kr != kIOReturnSuccess) { -#if TARGET_OS_EMBEDDED - /* TODO: Remove this once the kext runs the daemon on demand if - there is no system keybag. */ - int kb_state = MKBGetDeviceLockState(NULL); - secinfo("aks", "AppleKeyStore lock state: %d", kb_state); -#endif - } - return true; -} - -#else /* !USE_KEYSTORE */ - -static bool hwaes_key_available(void) -{ - return false; -} - -#endif /* USE_KEYSTORE */ - /* Wrap takes a 128 - 256 bit key as input and returns output of inputsize + 64 bits. In bytes this means that a @@ -126,7 +89,7 @@ static bool hwaes_key_available(void) bool ks_crypt(CFTypeRef operation, keybag_handle_t keybag, keyclass_t keyclass, uint32_t textLength, const uint8_t *source, keyclass_t *actual_class, CFMutableDataRef dest, CFErrorRef *error) { #if USE_KEYSTORE - kern_return_t kernResult = kIOReturnBadArgument; + kern_return_t kernResult = kAKSReturnBadArgument; int dest_len = (int)CFDataGetLength(dest); if (CFEqual(operation, kAKSKeyOpEncrypt)) { @@ -136,16 +99,16 @@ bool ks_crypt(CFTypeRef operation, keybag_handle_t keybag, } if (kernResult != KERN_SUCCESS) { - if ((kernResult == kIOReturnNotPermitted) || (kernResult == kIOReturnNotPrivileged)) { + if ((kernResult == kAKSReturnNoPermission) || (kernResult == kAKSReturnNotPrivileged)) { const char *substatus = ""; if (keyclass == key_class_ck || keyclass == key_class_cku) substatus = " (hibernation?)"; /* Access to item attempted while keychain is locked. */ return SecError(errSecInteractionNotAllowed, error, CFSTR("ks_crypt: %x failed to '%@' item (class %"PRId32", bag: %"PRId32") Access to item attempted while keychain is locked%s."), kernResult, operation, keyclass, keybag, substatus); - } else if (kernResult == kIOReturnNotFound) { + } else if (kernResult == kAKSReturnNotFound) { return SecError(errSecNotAvailable, error, CFSTR("ks_crypt: %x failed to '%@' item (class %"PRId32", bag: %"PRId32") No key available for class."), kernResult, operation, keyclass, keybag); - } else if (kernResult == kIOReturnError || kernResult == kAKSReturnDecodeError) { + } else if (kernResult == kAKSReturnError || kernResult == kAKSReturnDecodeError) { /* Item can't be decrypted on this device, ever, so drop the item. */ return SecError(errSecDecode, error, CFSTR("ks_crypt: %x failed to '%@' item (class %"PRId32", bag: %"PRId32") Item can't be decrypted on this device, ever, so drop the item."), kernResult, operation, keyclass, keybag); @@ -300,7 +263,7 @@ bool create_cferror_from_aks(int aks_return, CFTypeRef operation, keybag_handle_ SecError(errSecDecode, error, CFSTR("aks_ref_key: %x failed to '%s' item (class %"PRId32", bag: %"PRId32") Item can't be decrypted on this device, ever, so drop the item."), aks_return, operation_string, keyclass, keybag); - } else if (aks_return == kIOReturnNotFound) { + } else if (aks_return == kAKSReturnNotFound) { return SecError(errSecNotAvailable, error, CFSTR("ks_crypt: %x failed to '%@' item (class %"PRId32", bag: %"PRId32") No key available for class."), aks_return, operation, keyclass, keybag); } else { SecError(errSecNotAvailable, error, CFSTR("aks_ref_key: %x failed to '%s' item (class %"PRId32", bag: %"PRId32")"), @@ -443,6 +406,7 @@ out: #endif bool use_hwaes(void) { +#if !TARGET_OS_BRIDGE static bool use_hwaes; static dispatch_once_t check_once; dispatch_once(&check_once, ^{ @@ -454,6 +418,9 @@ bool use_hwaes(void) { } }); return use_hwaes; +#else + return false; +#endif // TARGET_OS_BRIDGE } bool ks_open_keybag(CFDataRef keybag, CFDataRef password, keybag_handle_t *handle, CFErrorRef *error) { diff --git a/OSX/sec/securityd/SecKeybagSupport.h b/OSX/sec/securityd/SecKeybagSupport.h index 6f48990d..b2b6aa28 100644 --- a/OSX/sec/securityd/SecKeybagSupport.h +++ b/OSX/sec/securityd/SecKeybagSupport.h @@ -29,34 +29,25 @@ #define _SECURITYD_SECKEYBAGSUPPORT_H_ #include -#include +#include "utilities/SecAKSWrappers.h" #include +#include #ifndef USE_KEYSTORE -#define USE_KEYSTORE TARGET_HAS_KEYSTORE +// Use keystore (real or mock) on all platforms, except bridge +#define USE_KEYSTORE !TARGET_OS_BRIDGE #endif -#if USE_KEYSTORE +#if __has_include() #include +#endif + +#if USE_KEYSTORE #include #endif /* USE_KEYSTORE */ __BEGIN_DECLS -#if !USE_KEYSTORE -/* TODO: this needs to be available in the sim! */ -typedef int32_t keyclass_t; -typedef int32_t key_handle_t; -enum key_classes { - key_class_ak = 6, - key_class_ck, - key_class_dk, - key_class_aku, - key_class_cku, - key_class_dku, - key_class_akpu -}; -#endif /* !USE_KEYSTORE */ /* KEYBAG_NONE is private to security and have special meaning. They should not collide with AppleKeyStore constants, but are only referenced @@ -67,6 +58,7 @@ enum key_classes { extern keybag_handle_t g_keychain_keybag; bool use_hwaes(void); + bool ks_crypt(CFTypeRef operation, keybag_handle_t keybag, keyclass_t keyclass, uint32_t textLength, const uint8_t *source, keyclass_t *actual_class, CFMutableDataRef dest, CFErrorRef *error); diff --git a/OSX/sec/securityd/SecLogSettingsServer.m b/OSX/sec/securityd/SecLogSettingsServer.m index c4c02dc4..fd15022f 100644 --- a/OSX/sec/securityd/SecLogSettingsServer.m +++ b/OSX/sec/securityd/SecLogSettingsServer.m @@ -5,10 +5,10 @@ // #include -#import +#include "keychain/SecureObjectSync/SOSAccountPriv.h" #include #include -#include +#include "keychain/SecureObjectSync/SOSTransportCircle.h" #include #include #include diff --git a/OSX/sec/securityd/SecOCSPCache.c b/OSX/sec/securityd/SecOCSPCache.c index bc7e55df..5c221b71 100644 --- a/OSX/sec/securityd/SecOCSPCache.c +++ b/OSX/sec/securityd/SecOCSPCache.c @@ -234,9 +234,6 @@ static void _SecOCSPCacheReplaceResponse(SecOCSPCacheRef this, CFDataGetLength(uriData), SQLITE_TRANSIENT, &localError); CFRelease(uriData); - } else { - // Since we use SecDbClearBindings this shouldn't be needed. - //ok = SecDbBindNull(insertResponse, 2, &localError); } } /* responses.expires */ diff --git a/OSX/sec/securityd/SecOCSPCache.h b/OSX/sec/securityd/SecOCSPCache.h index 0069a502..39a9744c 100644 --- a/OSX/sec/securityd/SecOCSPCache.h +++ b/OSX/sec/securityd/SecOCSPCache.h @@ -31,8 +31,8 @@ #ifndef _SECURITY_SECOCSPCACHE_H_ #define _SECURITY_SECOCSPCACHE_H_ -#include -#include +#include "securityd/SecOCSPRequest.h" +#include "securityd/SecOCSPResponse.h" #include __BEGIN_DECLS diff --git a/OSX/sec/securityd/SecOCSPResponse.h b/OSX/sec/securityd/SecOCSPResponse.h index 1434439b..0398c438 100644 --- a/OSX/sec/securityd/SecOCSPResponse.h +++ b/OSX/sec/securityd/SecOCSPResponse.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include "securityd/SecOCSPRequest.h" #include __BEGIN_DECLS diff --git a/OSX/sec/securityd/SecOTRRemote.m b/OSX/sec/securityd/SecOTRRemote.m index f7757a87..29c85ee7 100644 --- a/OSX/sec/securityd/SecOTRRemote.m +++ b/OSX/sec/securityd/SecOTRRemote.m @@ -31,7 +31,7 @@ #include "SOSAccountPriv.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" CFDataRef SecOTRSessionCreateRemote_internal(CFDataRef publicAccountData, CFDataRef publicPeerId, CFDataRef privateAccountData, CFErrorRef *error) { SOSDataSourceFactoryRef ds = SecItemDataSourceFactoryGetDefault(); diff --git a/OSX/sec/securityd/SecPinningDb.m b/OSX/sec/securityd/SecPinningDb.m index 55ad8f4b..b0308ccb 100644 --- a/OSX/sec/securityd/SecPinningDb.m +++ b/OSX/sec/securityd/SecPinningDb.m @@ -58,7 +58,6 @@ #include #include "utilities/sec_action.h" -#define kSecPinningBasePath "/Library/Keychains/" #define kSecPinningDbFileName "pinningrules.sqlite3" const uint64_t PinningDbSchemaVersion = 2; @@ -427,6 +426,8 @@ static inline bool isNSDictionary(id nsType) { return true; } + dispatch_assert_queue_not(self->_queue); + __block BOOL ok = true; dispatch_sync(self->_queue, ^{ bool updateSchema = false; @@ -494,15 +495,11 @@ static void verify_create_path(const char *path) - (NSURL *)pinningDbPath { /* Make sure the /Library/Keychains directory is there */ -#if TARGET_OS_IPHONE - NSURL *directory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); -#else - NSURL *directory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; -#endif + NSURL *directory = CFBridgingRelease(SecCopyURLForFileInSystemKeychainDirectory(nil)); verify_create_path([directory fileSystemRepresentation]); /* Get the full path of the pinning DB */ - return [directory URLByAppendingPathComponent:@"pinningrules.sqlite3"]; + return [directory URLByAppendingPathComponent:@kSecPinningDbFileName]; } - (void) initializedDb { diff --git a/OSX/sec/securityd/SecPolicyServer.c b/OSX/sec/securityd/SecPolicyServer.c index fda34f81..03775ed2 100644 --- a/OSX/sec/securityd/SecPolicyServer.c +++ b/OSX/sec/securityd/SecPolicyServer.c @@ -98,6 +98,7 @@ static void secdumpdata(CFDataRef data, const char *name) { static SecCertificateRef SecPVCGetCertificateAtIndex(SecPVCRef pvc, CFIndex ix); static CFIndex SecPVCGetCertificateCount(SecPVCRef pvc); static CFAbsoluteTime SecPVCGetVerifyTime(SecPVCRef pvc); +static SecTrustSettingsResult SecPVCGetTrustSettingsResult(SecPVCRef pvc, SecCertificateRef certificate, CFArrayRef constraints); static CFMutableDictionaryRef gSecPolicyLeafCallbacks = NULL; static CFMutableDictionaryRef gSecPolicyPathCallbacks = NULL; @@ -803,7 +804,9 @@ static void SecPolicyCheckLeafMarkerOid(SecPVCRef pvc, CFStringRef key) CFTypeRef value = CFDictionaryGetValue(policy->_options, key); if (!SecPolicyCheckCertLeafMarkerOid(cert, value)) { - SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + // Don't use 'key' because that may be the legacy key (see ) + // Force because we may have gotten the legacy key instead of the new key in the policy + SecPVCSetResultForced(pvc, kSecPolicyCheckLeafMarkerOid, 0, kCFBooleanFalse, true); } } @@ -834,7 +837,9 @@ static void SecPolicyCheckLeafMarkersProdAndQA(SecPVCRef pvc, CFStringRef key) if (!SecPolicyCheckCertLeafMarkerOid(cert, prodValue)) { bool result = false; if (!result) { - SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + // Don't use 'key' because that may be the legacy key (see ) + // Force because we may have gotten the legacy key instead of the new key in the policy + SecPVCSetResultForced(pvc, kSecPolicyCheckLeafMarkersProdAndQA, 0, kCFBooleanFalse, true); } } } @@ -850,7 +855,23 @@ static void SecPolicyCheckIntermediateMarkerOid(SecPVCRef pvc, CFStringRef key) if (SecCertificateHasMarkerExtension(cert, value)) return; } - SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + // Don't use 'key' because that may be the legacy key (see ) + // Force because we may have gotten the legacy key instead of the new key in the policy + SecPVCSetResultForced(pvc, kSecPolicyCheckIntermediateMarkerOid, 0, kCFBooleanFalse, true); +} + +static void SecPolicyCheckIntermediateMarkerOidWithoutValueCheck(SecPVCRef pvc, CFStringRef key) +{ + CFIndex ix, count = SecPVCGetCertificateCount(pvc); + SecPolicyRef policy = SecPVCGetPolicy(pvc); + CFTypeRef value = CFDictionaryGetValue(policy->_options, key); + + for (ix = 1; ix < count - 1; ix++) { + SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); + if (!SecPolicyCheckCertLeafMarkerOidWithoutValueCheck(cert, value)) { + SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + } + } } static void SecPolicyCheckIntermediateEKU(SecPVCRef pvc, CFStringRef key) @@ -876,7 +897,9 @@ static void SecPolicyCheckIntermediateOrganization(SecPVCRef pvc, CFStringRef ke for (ix = 1; ix < count - 1; ix++) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); if (!SecPolicyCheckCertSubjectOrganization(cert, organization)) { - SecPVCSetResult(pvc, key, ix, kCFBooleanFalse); + // Don't use 'key' because that may be the legacy key (see ) + // Force because we may have gotten the legacy key instead of the new key in the policy + SecPVCSetResultForced(pvc, kSecPolicyCheckIntermediateOrganization, ix, kCFBooleanFalse, true); } } } @@ -890,7 +913,9 @@ static void SecPolicyCheckIntermediateCountry(SecPVCRef pvc, CFStringRef key) for (ix = 1; ix < count - 1; ix++) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); if (!SecPolicyCheckCertSubjectCountry(cert, country)) { - SecPVCSetResult(pvc, key, ix, kCFBooleanFalse); + // Don't use 'key' because that may be the legacy key (see ) + // Force because we may have gotten the legacy key instead of the new key in the policy + SecPVCSetResultForced(pvc, kSecPolicyCheckIntermediateCountry, ix, kCFBooleanFalse, true); } } } @@ -961,8 +986,22 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, #if POLICY_SUBTREES CFMutableArrayRef permitted_subtrees = NULL; CFMutableArrayRef excluded_subtrees = NULL; - permitted_subtrees = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - excluded_subtrees = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + /* set the initial subtrees to the trusted anchor's subtrees, if it has them */ + SecCertificateRef anchor = SecCertificatePathVCGetRoot(path); + CFArrayRef anchor_permitted_subtrees = SecCertificateGetPermittedSubtrees(anchor); + if (is_anchor_trusted && anchor_permitted_subtrees) { + permitted_subtrees = CFArrayCreateMutableCopy(NULL, 0, anchor_permitted_subtrees); + } else { + permitted_subtrees = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + + CFArrayRef anchor_excluded_subtrees = SecCertificateGetExcludedSubtrees(anchor); + if (is_anchor_trusted && anchor_excluded_subtrees) { + excluded_subtrees = CFArrayCreateMutableCopy(NULL, 0, anchor_excluded_subtrees); + } else { + excluded_subtrees = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + } + require_action_quiet(permitted_subtrees != NULL, errOut, SecPVCSetResultForced(pvc, kSecPolicyCheckNameConstraints, 0, kCFBooleanFalse, true)); require_action_quiet(excluded_subtrees != NULL, errOut, @@ -1079,24 +1118,25 @@ static void SecPolicyCheckBasicCertificateProcessing(SecPVCRef pvc, && bc->pathLenConstraint < max_path_length) { max_path_length = bc->pathLenConstraint; } -#if 0 /* Checked in chain builder pre signature verify already. SecPVCParentCertificateChecks */ + /* (n) If a key usage extension is present, verify that the keyCertSign bit is set. */ - SecKeyUsage keyUsage = SecCertificateGetKeyUsage(cert); - if (keyUsage && !(keyUsage & kSecKeyUsageKeyCertSign)) { - if (!SecPVCSetResultForced(pvc, kSecPolicyCheckKeyUsage, - n - i, kCFBooleanFalse, true)) { - goto errOut; - } - } -#endif + /* Checked in chain builder pre signature verify already. SecPVCParentCertificateChecks */ + /* (o) Recognize and process any other critical extension present in the certificate. Process any other recognized non-critical extension present in the certificate that is relevant to path processing. */ if (SecCertificateHasUnknownCriticalExtension(cert)) { /* Certificate contains one or more unknown critical extensions. */ - if (!SecPVCSetResult(pvc, kSecPolicyCheckCriticalExtensions, - n - i, kCFBooleanFalse)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckCriticalExtensions, n - i, kCFBooleanFalse)) { goto errOut; } } + + if (SecCertificateGetUnparseableKnownExtension(cert) != kCFNotFound) { + /* Certificate contains one or more known exensions where parsing failed. */ + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckUnparseableExtension, n-i, kCFBooleanFalse, true)) { + goto errOut; + } + } + } /* end loop over certs in path */ /* Wrap up */ /* (a) (b) done by SecCertificatePathVCVerifyPolicyTree */ @@ -1108,8 +1148,14 @@ working_public_key_algorithm are different, set the working_public_key_parameter /* (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. */ - if (!SecPVCSetResult(pvc, kSecPolicyCheckCriticalExtensions, - 0, kCFBooleanFalse)) { + if (!SecPVCSetResult(pvc, kSecPolicyCheckCriticalExtensions, 0, kCFBooleanFalse)) { + goto errOut; + } + } + + if (SecCertificateGetUnparseableKnownExtension(cert) != kCFNotFound) { + /* Certificate contains one or more known exensions where parsing failed. */ + if (!SecPVCSetResultForced(pvc, kSecPolicyCheckUnparseableExtension, 0, kCFBooleanFalse, true)) { goto errOut; } } @@ -1220,6 +1266,16 @@ certificatePolicies or extendedKeyUsage extensions. /* * MARK: Certificate Transparency support */ +const CFStringRef kSecCTRetirementDateKey = CFSTR("expiry"); // For backwards compatibility, retirement date is represented with the "expiry" key +const CFStringRef kSecCTReadOnlyDateKey = CFSTR("frozen"); // For backwards compatibility, read-only date is represented with the "frozen" key +const CFStringRef kSecCTShardStartDateKey = CFSTR("start_inclusive"); +const CFStringRef kSecCTShardEndDateKey = CFSTR("end_exclusive"); +const CFStringRef kSecCTPublicKeyKey = CFSTR("key"); + +enum { + kSecCTEntryTypeCert = 0, + kSecCTEntryTypePreCert = 1, +}; /*** @@ -1377,7 +1433,31 @@ uint64_t TimestampFromCFAbsoluteTime(CFAbsoluteTime at) return (uint64_t)(at + kCFAbsoluteTimeIntervalSince1970) * 1000; } +static bool isSCTValidForLogData(CFDictionaryRef logData, int entry_type, CFAbsoluteTime sct_time, CFAbsoluteTime cert_expiry_date) { + /* only embedded SCTs can be used from retired logs. */ + if(entry_type==kSecCTEntryTypeCert && CFDictionaryContainsKey(logData, kSecCTRetirementDateKey)) { + return false; + } + /* SCTs from after the transition to read-only are not valid (and indicate a operator failure) */ + CFDateRef frozen_date = CFDictionaryGetValue(logData, kSecCTReadOnlyDateKey); + if (frozen_date && (sct_time > CFDateGetAbsoluteTime(frozen_date))) { + secerror("Frozen CT log issued SCT after freezing (log=%@)\n", logData); + return false; + } + + /* If the log is temporally sharded, the certificate expiry date must be within the temporal shard window */ + CFDateRef start_inclusive = CFDictionaryGetValue(logData, kSecCTShardStartDateKey); + CFDateRef end_exclusive = CFDictionaryGetValue(logData, kSecCTShardEndDateKey); + if (start_inclusive && (cert_expiry_date < CFDateGetAbsoluteTime(start_inclusive))) { + return false; + } + if (end_exclusive && (cert_expiry_date >= CFDateGetAbsoluteTime(end_exclusive))) { + return false; + } + + return true; +} /* @@ -1402,9 +1482,7 @@ uint64_t TimestampFromCFAbsoluteTime(CFAbsoluteTime at) If an entry for the same log already existing in the dictionary, the entry is replaced only if the timestamp of this SCT is earlier. */ - - -static CFDictionaryRef getSCTValidatingLog(CFDataRef sct, int entry_type, CFDataRef entry, uint64_t vt, CFArrayRef trustedLogs, CFAbsoluteTime *sct_at) +static CFDictionaryRef getSCTValidatingLog(CFDataRef sct, int entry_type, CFDataRef entry, uint64_t vt, CFAbsoluteTime cert_expiry_date, CFDictionaryRef trustedLogs, CFAbsoluteTime *sct_at) { uint8_t version; const uint8_t *logID; @@ -1473,31 +1551,11 @@ static CFDictionaryRef getSCTValidatingLog(CFDataRef sct, int entry_type, CFData logIDData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, logID, 32, kCFAllocatorNull); - CFDictionaryRef logData = CFArrayGetValueMatching(trustedLogs, ^bool(const void *dict) { - const void *key_data; - if(!isDictionary(dict)) return false; - if(!CFDictionaryGetValueIfPresent(dict, CFSTR("key"), &key_data)) return false; - if(!isData(key_data)) return false; - CFDataRef valueID = SecSHA256DigestCreateFromData(kCFAllocatorDefault, (CFDataRef)key_data); - bool result = (bool)(CFDataCompare(logIDData, valueID)==kCFCompareEqualTo); - CFReleaseSafe(valueID); - return result; - }); - require(logData, out); - - if(entry_type==0) { - // For external SCTs, only keep SCTs from currently valid logs. - require(!CFDictionaryContainsKey(logData, CFSTR("expiry")), out); - } - + CFDictionaryRef logData = CFDictionaryGetValue(trustedLogs, logIDData); CFAbsoluteTime sct_time = TimestampToCFAbsoluteTime(timestamp); - CFDateRef frozen_date = CFDictionaryGetValue(logData, CFSTR("frozen")); - if (frozen_date && (sct_time > CFDateGetAbsoluteTime(frozen_date))) { - secerror("Frozen CT log issued SCT after freezing (log=%@)\n", logData); - goto out; - } + require(logData && isSCTValidForLogData(logData, entry_type, sct_time, cert_expiry_date), out); - CFDataRef logKeyData = CFDictionaryGetValue(logData, CFSTR("key")); + CFDataRef logKeyData = CFDictionaryGetValue(logData, kSecCTPublicKeyKey); require(logKeyData, out); // This failing would be an internal logic error pubKey = SecKeyCreateFromSubjectPublicKeyInfoData(kCFAllocatorDefault, logKeyData); require(pubKey, out); @@ -1591,12 +1649,13 @@ static void SecPolicyCheckCT(SecPVCRef pvc) SecCertificateRef leafCert = SecPVCGetCertificateAtIndex(pvc, 0); CFArrayRef embeddedScts = SecCertificateCopySignedCertificateTimestamps(leafCert); CFArrayRef builderScts = SecPathBuilderCopySignedCertificateTimestamps(pvc->builder); - CFArrayRef trustedLogs = SecPathBuilderCopyTrustedLogs(pvc->builder); + CFDictionaryRef trustedLogs = SecPathBuilderCopyTrustedLogs(pvc->builder); CFArrayRef ocspScts = copy_ocsp_scts(pvc); CFDataRef precertEntry = copy_precert_entry_from_chain(pvc); CFDataRef x509Entry = copy_x509_entry_from_chain(pvc); __block uint32_t trustedSCTCount = 0; __block CFAbsoluteTime issuanceTime = SecPVCGetVerifyTime(pvc); + __block CFAbsoluteTime certExpiry = SecCertificateNotValidAfter(leafCert); TA_CTFailureReason failureReason = TA_CTNoFailure; if (!trustedLogs) { @@ -1620,24 +1679,24 @@ static void SecPolicyCheckCT(SecPVCRef pvc) require(currentLogsValidatingScts, out); /* Skip if there are no SCTs. */ - require_action((embeddedScts && CFArrayGetCount(embeddedScts) > 0) || + bool no_scts = (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; - } + (ocspScts && CFArrayGetCount(ocspScts) > 0); + require_action_quiet(no_scts, 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(trustedLogs && CFDictionaryGetCount(trustedLogs) > 0) { // 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){ CFAbsoluteTime sct_at; - CFDictionaryRef log = getSCTValidatingLog(value, 1, precertEntry, vt, trustedLogs, &sct_at); + CFDictionaryRef log = getSCTValidatingLog(value, 1, precertEntry, vt, certExpiry, trustedLogs, &sct_at); if(log) { addValidatingLog(logsValidatingEmbeddedScts, log, sct_at); - if(!CFDictionaryContainsKey(log, CFSTR("expiry"))) { + if(!CFDictionaryContainsKey(log, kSecCTRetirementDateKey)) { addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_embedded = true; trustedSCTCount++; @@ -1653,7 +1712,7 @@ static void SecPolicyCheckCT(SecPVCRef pvc) if(builderScts && x509Entry) { // Don't bother if we could not get the cert. CFArrayForEach(builderScts, ^(const void *value){ CFAbsoluteTime sct_at; - CFDictionaryRef log = getSCTValidatingLog(value, 0, x509Entry, vt, trustedLogs, &sct_at); + CFDictionaryRef log = getSCTValidatingLog(value, 0, x509Entry, vt, certExpiry, trustedLogs, &sct_at); if(log) { addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_external = true; @@ -1667,7 +1726,7 @@ static void SecPolicyCheckCT(SecPVCRef pvc) if(ocspScts && x509Entry) { CFArrayForEach(ocspScts, ^(const void *value){ CFAbsoluteTime sct_at; - CFDictionaryRef log = getSCTValidatingLog(value, 0, x509Entry, vt, trustedLogs, &sct_at); + CFDictionaryRef log = getSCTValidatingLog(value, 0, x509Entry, vt, certExpiry, trustedLogs, &sct_at); if(log) { addValidatingLog(currentLogsValidatingScts, log, sct_at); at_least_one_currently_valid_external = true; @@ -1704,7 +1763,7 @@ static void SecPolicyCheckCT(SecPVCRef pvc) /* Calculate issuance time based on timestamp of SCTs from current logs */ CFDictionaryForEach(currentLogsValidatingScts, ^(const void *key, const void *value) { CFDictionaryRef log = key; - if(!CFDictionaryContainsKey(log, CFSTR("expiry"))) { + if(!CFDictionaryContainsKey(log, kSecCTRetirementDateKey)) { // Log is still qualified CFDateRef ts = (CFDateRef) value; CFAbsoluteTime timestamp = CFDateGetAbsoluteTime(ts); @@ -1729,7 +1788,7 @@ static void SecPolicyCheckCT(SecPVCRef pvc) CFDictionaryForEach(logsValidatingEmbeddedScts, ^(const void *key, const void *value) { CFDictionaryRef log = key; CFDateRef ts = value; - CFDateRef expiry = CFDictionaryGetValue(log, CFSTR("expiry")); + CFDateRef expiry = CFDictionaryGetValue(log, kSecCTRetirementDateKey); if (expiry == NULL) { // Currently qualified OR once_or_current_qualified_embedded++; } else if (CFDateCompare(ts, expiry, NULL) == kCFCompareLessThan && // Once qualified. That is, qualified at the time of SCT AND @@ -1922,6 +1981,18 @@ static void SecPolicyCheckKeySize(SecPVCRef pvc, CFStringRef key) { CFIndex ix, count = SecPVCGetCertificateCount(pvc); SecPolicyRef policy = SecPVCGetPolicy(pvc); CFDictionaryRef keySizes = CFDictionaryGetValue(policy->_options, key); + SecCertificateRef leaf = SecPVCGetCertificateAtIndex(pvc, 0); + + /* Don't check key size for user-anchored leafs */ +#if TARGET_OS_IPHONE + SecCertificateSourceRef userSource = kSecUserAnchorSource; +#else + SecCertificateSourceRef userSource = kSecLegacyAnchorSource; +#endif + if (SecPVCIsAnchorPerConstraints(pvc, userSource, leaf)) { + return; + } + for (ix = 0; ix < count; ++ix) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); if (!SecCertificateIsAtLeastMinKeySize(cert, keySizes)) { @@ -1946,15 +2017,28 @@ static void SecPolicyCheckWeakSignature(SecPVCRef pvc, CFStringRef key) { static void SecPolicyCheckSignatureHashAlgorithms(SecPVCRef pvc, CFStringRef key) { - CFIndex ix, count = SecPVCGetCertificateCount(pvc); + CFIndex ix = 0, count = SecPVCGetCertificateCount(pvc); + + /* Ignore (a non-self-signed) anchor if it's trusted by the user */ +#if TARGET_OS_IPHONE + bool userAnchored = SecPVCIsAnchorPerConstraints(pvc, kSecUserAnchorSource, SecPVCGetCertificateAtIndex(pvc, count - 1)); +#else + bool userAnchored = SecPVCIsAnchorPerConstraints(pvc, kSecLegacyAnchorSource, SecPVCGetCertificateAtIndex(pvc, count - 1)); +#endif + if (SecPathBuilderIsAnchored(pvc->builder) && userAnchored) { + count--; + } + SecPolicyRef policy = SecPVCGetPolicy(pvc); CFSetRef disallowedHashAlgorithms = CFDictionaryGetValue(policy->_options, key); - for (ix = 0; ix < count; ++ix) { + while (ix < count) { SecCertificateRef cert = SecPVCGetCertificateAtIndex(pvc, ix); + /* note that these checks skip self-signed certs */ if (!SecPolicyCheckCertSignatureHashAlgorithms(cert, disallowedHashAlgorithms)) { if (!SecPVCSetResult(pvc, key, ix, kCFBooleanFalse)) return; } + ix++; } } @@ -2086,14 +2170,13 @@ static void SecPolicyCheckPinningRequired(SecPVCRef pvc, CFStringRef key) { } } -static bool is_configured_test_system_root(SecCertificateRef root) { +static bool is_configured_test_system_root(SecCertificateRef root, CFStringRef preference) { if (!SecIsInternalRelease()) { return false; } bool result = false; CFDataRef rootHash = SecCertificateCopySHA256Digest(root); - CFTypeRef value = CFPreferencesCopyValue(CFSTR("TestCTRequiredSystemRoot"), CFSTR("com.apple.security"), - kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + CFTypeRef value = CFPreferencesCopyAppValue(preference, CFSTR("com.apple.security")); require_quiet(isData(value), out); require_quiet(kCFCompareEqualTo == CFDataCompare(rootHash, value), out); result = true; @@ -2249,7 +2332,11 @@ static bool is_ct_excepted(SecPVCRef pvc) { /* some Apple servers not getting certs with embedded SCTs * some Google apps have their own TLS stacks and aren't passing us TLS SCTs */ -static bool is_apple_ca(SecCertificatePathVCRef path) { +static bool is_ct_allowlisted_ca(SecCertificatePathVCRef path) { + if (CFPreferencesGetAppBooleanValue(CFSTR("DisableCTAllowlist"), CFSTR("com.apple.security"), NULL)) { + return false; + } + /* subject:/CN=Apple IST CA 8 - G1/OU=Certification Authority/O=Apple Inc./C=US */ /* issuer :/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 */ static const uint8_t appleISTCA8G1_spkiSHA256[] = { @@ -2275,11 +2362,21 @@ static bool is_apple_ca(SecCertificatePathVCRef path) { for (CFIndex certIX = 1; certIX < SecCertificatePathVCGetCount(path); certIX++) { SecCertificateRef ca = SecCertificatePathVCGetCertificateAtIndex(path, certIX); + bool allowlistAppleCAs = true, allowlistGoogleCA = true; + if (CFPreferencesGetAppBooleanValue(CFSTR("DisableCTAllowlistApple"), CFSTR("com.apple.security"), NULL)) { + allowlistAppleCAs = false; + } + if (CFPreferencesGetAppBooleanValue(CFSTR("DisableCTAllowlistGoogle"), CFSTR("com.apple.security"), NULL)) { + allowlistGoogleCA = false; + } + CFDataRef caSPKIHash = SecCertificateCopySubjectPublicKeyInfoSHA256Digest(ca); const uint8_t *dp = CFDataGetBytePtr(caSPKIHash); - if (dp && (!memcmp(appleISTCA8G1_spkiSHA256, dp, CC_SHA256_DIGEST_LENGTH) || - !memcmp(appleISTCA2G1_spkiSHA256, dp, CC_SHA256_DIGEST_LENGTH) || - !memcmp(googleIAG3_spkiSHA256, dp, CC_SHA256_DIGEST_LENGTH))) { + if (dp && allowlistAppleCAs && (!memcmp(appleISTCA8G1_spkiSHA256, dp, CC_SHA256_DIGEST_LENGTH) || + !memcmp(appleISTCA2G1_spkiSHA256, dp, CC_SHA256_DIGEST_LENGTH))) { + result = true; + } + if (dp && allowlistGoogleCA && !memcmp(googleIAG3_spkiSHA256, dp, CC_SHA256_DIGEST_LENGTH)) { result = true; } CFReleaseNull(caSPKIHash); @@ -2294,7 +2391,7 @@ static void SecPolicyCheckSystemTrustedCTRequired(SecPVCRef pvc) { SecCertificateSourceRef appleAnchorSource = NULL; SecOTAPKIRef otaref = SecOTAPKICopyCurrentOTAPKIRef(); SecCertificatePathVCRef path = SecPathBuilderGetPath(pvc->builder); - CFArrayRef trustedLogs = SecPathBuilderCopyTrustedLogs(pvc->builder); + CFDictionaryRef trustedLogs = SecPathBuilderCopyTrustedLogs(pvc->builder); /* Skip this check if we haven't done the CT checks yet */ require_quiet(SecCertificatePathVCIsPathValidated(path), out); @@ -2324,8 +2421,8 @@ static void SecPolicyCheckSystemTrustedCTRequired(SecPVCRef pvc) { require_quiet(SecPathBuilderIsAnchored(pvc->builder), out); require_quiet((SecCertificateSourceContains(kSecSystemAnchorSource, root) && appleAnchorSource && !SecCertificateSourceContains(appleAnchorSource, root) && - !is_apple_ca(path)) || - is_configured_test_system_root(root), out); + !is_ct_allowlisted_ca(path)) || + is_configured_test_system_root(root, CFSTR("TestCTRequiredSystemRoot")), out); if (!SecCertificatePathVCIsCT(path) && !is_ct_excepted(pvc)) { /* Set failure. By not using the Forced variant, we implicitly check that this @@ -2341,6 +2438,122 @@ out: } } +static bool SecPolicyCheckSystemTrustValidityPeriodMaximums(CFAbsoluteTime notBefore, CFAbsoluteTime notAfter) { + CFAbsoluteTime jul2016 = 489024000.0; // 1 July 2016 00:00:00 UTC + CFAbsoluteTime mar2018 = 541555200.0; // 1 March 2018 00:00:00 UTC + if (notBefore < jul2016) { + /* Validity Period no greater than 60 months. + 60 months is no more than 5 years and 2 leap days (and 1 hour slip). */ + CFAbsoluteTime maxPeriod = 60*60*24*(365*5+2) + 3600; + if (notAfter - notBefore > maxPeriod) { + secnotice("policy", "System-trusted leaf validity period is more than 60 months"); + return false; + } + } else if (notBefore < mar2018) { + /* Validity Period no greater than 39 months. + 39 months is no more than 3 years, 2 31-day months, + 1 30-day month, and 1 leap day (and 1 hour slip) */ + CFAbsoluteTime maxPeriod = 60*60*24*(365*3+2*31+30+1) + 3600; + if (notAfter - notBefore > maxPeriod) { + secnotice("policy", "System-trusted leaf validity period longer than 39 months and issued after 30 June 2016"); + return false; + } + } else { + /* Validity Period no greater than 825 days (and 1 hour slip). */ + CFAbsoluteTime maxPeriod = 60*60*24*825 + 3600; + if (notAfter - notBefore > maxPeriod) { + secnotice("policy", "System-trusted leaf validity period longer than 825 days and issued on or after 1 March 2018"); + return false; + } + } + return true; +} + +static bool SecPolicyCheckOtherTrustValidityPeriodMaximums(CFAbsoluteTime notBefore, CFAbsoluteTime notAfter) { + /* Check whether we will enforce the validity period maximum for a non-system trusted leaf. */ + if (SecIsInternalRelease()) { + if (CFPreferencesGetAppBooleanValue(CFSTR("IgnoreMaximumValidityPeriod"), + CFSTR("com.apple.security"), NULL)) { + return true; + } + } + CFAbsoluteTime jul2019 = 583628400.0; // 1 July 2019 00:00:00 UTC + if (notBefore > jul2019) { + /* Validity Period no greater than 825 days (and 1 hour slip). */ + CFAbsoluteTime maxPeriod = 60*60*24*825 + 3600; + if (notAfter - notBefore > maxPeriod) { + secnotice("policy", "Non-system-trusted leaf validity period longer than 825 days and issued on or after 1 July 2019"); + return false; + } + } + return true; +} + +static void SecPolicyCheckValidityPeriodMaximums(SecPVCRef pvc, CFStringRef key) { + SecCertificateRef leaf = SecPVCGetCertificateAtIndex(pvc, 0); + CFAbsoluteTime notAfter = SecCertificateNotValidAfter(leaf); + CFAbsoluteTime notBefore = SecCertificateNotValidBefore(leaf); + + CFIndex count = SecPVCGetCertificateCount(pvc); + SecCertificateRef root = SecPVCGetCertificateAtIndex(pvc, count - 1); + if (SecCertificateSourceContains(kSecSystemAnchorSource, root) || is_configured_test_system_root(root, CFSTR("TestSystemRoot"))) { + if (!SecPolicyCheckSystemTrustValidityPeriodMaximums(notBefore, notAfter)) { + SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + } + return; + } + + /* Don't check validity periods against maximums for user-anchored leafs */ +#if TARGET_OS_IPHONE + SecCertificateSourceRef userSource = kSecUserAnchorSource; +#else + SecCertificateSourceRef userSource = kSecLegacyAnchorSource; +#endif + if (SecPVCIsAnchorPerConstraints(pvc, userSource, leaf)) { + return; + } + + /* all other trust */ + if (!SecPolicyCheckOtherTrustValidityPeriodMaximums(notBefore, notAfter)) { + SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + } +} + +static void SecPolicyCheckServerAuthEKU(SecPVCRef pvc, CFStringRef key) { + /* The ExtendedKeyUsage check will verify a looser version of this check for all TLS server certs. + * Here we want to be stricter (enforcing that there is an EKU extension and that it contains the + * one true Server Auth EKU OID) for system and app anchors */ + SecCertificateRef leaf = SecPVCGetCertificateAtIndex(pvc, 0); + CFIndex count = SecPVCGetCertificateCount(pvc); + SecCertificateRef root = SecPVCGetCertificateAtIndex(pvc, count - 1); + if (SecCertificateSourceContains(kSecSystemAnchorSource, root) || is_configured_test_system_root(root, CFSTR("TestSystemRoot"))) { + /* all system-anchored chains must be compliant */ + if (!SecPolicyCheckCertExtendedKeyUsage(leaf, CFSTR("1.3.6.1.5.5.7.3.1"))) { // server auth EKU + SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + } + return; + } + + /* skip user/admin-anchored chains */ +#if TARGET_OS_IPHONE + SecCertificateSourceRef userSource = kSecUserAnchorSource; +#else + SecCertificateSourceRef userSource = kSecLegacyAnchorSource; +#endif + if (SecPVCIsAnchorPerConstraints(pvc, userSource, root)) { + return; + } + + /* All other anchor types must be compliant if issued on or after 1 July 2019 */ + CFAbsoluteTime notBefore = SecCertificateNotValidBefore(leaf); + CFAbsoluteTime jul2019 = 583628400.0; // 1 July 2019 00:00:00 UTC + if (notBefore > jul2019) { + if (!SecPolicyCheckCertExtendedKeyUsage(leaf, CFSTR("1.3.6.1.5.5.7.3.1"))) { // server auth EKU + SecPVCSetResult(pvc, key, 0, kCFBooleanFalse); + } + } +} + void SecPolicyServerInitialize(void) { gSecPolicyLeafCallbacks = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL); @@ -2606,12 +2819,6 @@ if (__PC_TYPE_MEMBER_##TRUSTRESULT && CFEqual(key,CFSTR(#NAME))) { \ bool SecPVCSetResultForced(SecPVCRef pvc, CFStringRef key, CFIndex ix, CFTypeRef result, bool force) { - secnotice("policy", "cert[%d]: %@ =(%s)[%s]> %@", (int) ix, key, - (pvc->callbacks == gSecPolicyLeafCallbacks ? "leaf" - : (pvc->callbacks == gSecPolicyPathCallbacks ? "path" - : "custom")), - (force ? "force" : ""), result); - /* If this is not something the current policy cares about ignore this error and return true so our caller continues evaluation. */ if (!force) { @@ -2636,6 +2843,12 @@ bool SecPVCSetResultForced(SecPVCRef pvc, return true; } + secnotice("policy", "cert[%d]: %@ =(%s)[%s]> %@", (int) ix, key, + (pvc->callbacks == gSecPolicyLeafCallbacks ? "leaf" + : (pvc->callbacks == gSecPolicyPathCallbacks ? "path" + : "custom")), + (force ? "force" : ""), result); + /* Avoid resetting deny or fatal to recoverable */ SecTrustResultType trustResult = trust_result_for_key(key); if (SecPVCIsOkResult(pvc) || trustResult == kSecTrustResultFatalTrustFailure) { @@ -2650,6 +2863,11 @@ bool SecPVCSetResultForced(SecPVCRef pvc, CFMutableDictionaryRef detail = (CFMutableDictionaryRef)CFArrayGetValueAtIndex(pvc->details, ix); + if (!detail) { + secerror("SecPVCSetResultForced: failed to get detail at index %ld (array length %ld)", + ix, CFArrayGetCount(pvc->details)); + return false; + } /* Perhaps detail should have an array of results per key? As it stands in the case of multiple policy failures the last failure stands. */ @@ -2952,12 +3170,17 @@ static bool SecPVCContainsString(SecPVCRef pvc, CFIndex policyIX, CFStringRef st } bool result = false; + /* Previous versions of macOS null-terminated the string, so we need to strip it. */ CFStringRef tmpStringValue = NULL; if (CFStringGetCharacterAtIndex(stringValue, CFStringGetLength(stringValue) -1) == (UniChar)0x0000) { tmpStringValue = CFStringCreateTruncatedCopy(stringValue, CFStringGetLength(stringValue) - 1); } else { tmpStringValue = CFStringCreateCopy(NULL, stringValue); } + /* Some users have strings that only contain the null-termination, so we need to check that we + * still have a string. */ + require(tmpStringValue, out); + if (policyIX >= 0 && policyIX < CFArrayGetCount(pvc->policies)) { SecPolicyRef policy = (SecPolicyRef)CFArrayGetValueAtIndex(pvc->policies, policyIX); /* Have to look for all the possible locations of name string */ @@ -3156,7 +3379,7 @@ static bool SecPVCMeetsConstraint(SecPVCRef pvc, SecCertificateRef certificate, keyUsageMatch = false, policyOptionMatch = false; bool result = false; -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX /* OS X returns a SecPolicyRef in the constraints. Convert to the oid string. */ SecPolicyRef policy = NULL; policy = (SecPolicyRef)CFDictionaryGetValue(constraint, kSecTrustSettingsPolicy); @@ -3175,7 +3398,7 @@ static bool SecPVCMeetsConstraint(SecPVCRef pvc, SecCertificateRef certificate, keyUsageMatch = SecPVCContainsTrustSettingsKeyUsage(pvc, certificate, policyIX, keyUsageNumber); policyOptionMatch = SecPVCContainsTrustSettingsPolicyOption(pvc, policyOptions); -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX trustedApplicationData = CFDictionaryGetValue(constraint, kSecTrustSettingsApplication); CFDataRef clientAuditToken = SecPathBuilderCopyClientAuditToken(pvc->builder); applicationMatch = SecPVCCallerIsApplication(clientAuditToken, trustedApplicationData); @@ -3200,7 +3423,7 @@ static bool SecPVCMeetsConstraint(SecPVCRef pvc, SecCertificateRef certificate, return result; } -SecTrustSettingsResult SecPVCGetTrustSettingsResult(SecPVCRef pvc, SecCertificateRef certificate, CFArrayRef constraints) { +static SecTrustSettingsResult SecPVCGetTrustSettingsResult(SecPVCRef pvc, SecCertificateRef certificate, CFArrayRef constraints) { SecTrustSettingsResult result = kSecTrustSettingsResultInvalid; CFIndex constraintIX, constraintCount = CFArrayGetCount(constraints); for (constraintIX = 0; constraintIX < constraintCount; constraintIX++) { @@ -3225,6 +3448,54 @@ SecTrustSettingsResult SecPVCGetTrustSettingsResult(SecPVCRef pvc, SecCertificat return result; } +/* This function assumes that the input source is an anchor source */ +bool SecPVCIsAnchorPerConstraints(SecPVCRef pvc, SecCertificateSourceRef source, SecCertificateRef certificate) { + __block bool result = false; + CFArrayRef constraints = NULL; + constraints = SecCertificateSourceCopyUsageConstraints(source, certificate); + + /* Unrestricted certificates: + * -those that come from anchor sources with no constraints + * -self-signed certificates with empty contraints arrays + */ + Boolean selfSigned = false; + require(errSecSuccess == SecCertificateIsSelfSigned(certificate, &selfSigned), out); + if ((NULL == source->copyUsageConstraints) || + (constraints && (CFArrayGetCount(constraints) == 0) && selfSigned)) { + secinfo("trust", "unrestricted anchor%s", + (NULL == source->copyUsageConstraints) ? " source" : ""); + result = true; + goto out; + } + + /* Get the trust settings result for the PVC. Only one PVC need match to + * trigger the anchor behavior -- policy validation will handle whether the + * path is truly anchored for that PVC. */ + require_quiet(constraints, out); + SecTrustSettingsResult settingsResult = kSecTrustSettingsResultInvalid; + settingsResult = SecPVCGetTrustSettingsResult(pvc, + certificate, + constraints); + if ((selfSigned && settingsResult == kSecTrustSettingsResultTrustRoot) || + (!selfSigned && settingsResult == kSecTrustSettingsResultTrustAsRoot)) { + // For our purposes, this is an anchor. + secinfo("trust", "complex trust settings anchor"); + result = true; + } + + if (settingsResult == kSecTrustSettingsResultDeny) { + /* We consider denied certs "anchors" because the trust decision + is set regardless of building the chain further. The policy + validation will handle rejecting this chain. */ + secinfo("trust", "complex trust settings denied anchor"); + result = true; + } + +out: + CFReleaseNull(constraints); + return result; +} + static void SecPVCCheckUsageConstraints(SecPVCRef pvc) { CFIndex certIX, certCount = SecPVCGetCertificateCount(pvc); for (certIX = 0; certIX < certCount; certIX++) { @@ -3243,11 +3514,12 @@ static void SecPVCCheckUsageConstraints(SecPVCRef pvc) { * all mean we should use the special "Proceed" trust result. */ #if TARGET_OS_IPHONE if (SecPathBuilderIsAnchorSource(pvc->builder, kSecUserAnchorSource) && - SecCertificateSourceContains(kSecUserAnchorSource, cert)) { + SecCertificateSourceContains(kSecUserAnchorSource, cert)) #else if (SecPathBuilderIsAnchorSource(pvc->builder, kSecLegacyAnchorSource) && - SecCertificateSourceContains(kSecLegacyAnchorSource, cert)) { + SecCertificateSourceContains(kSecLegacyAnchorSource, cert)) #endif + { pvc->result = kSecTrustResultProceed; } } @@ -3421,6 +3693,18 @@ static void SecPVCCheckRequireCTConstraints(SecPVCRef pvc) { CFReleaseNull(otaref); } +/* "Deep" copy the details array */ +static CFArrayRef CF_RETURNS_RETAINED SecPVCCopyDetailsArray(SecPVCRef pvc) { + CFArrayRef details = pvc->details; + CFMutableArrayRef copiedDetails = CFArrayCreateMutable(NULL, CFArrayGetCount(details), &kCFTypeArrayCallBacks); + CFArrayForEach(details, ^(const void *value) { + CFMutableDictionaryRef copiedValue = CFDictionaryCreateMutableCopy(NULL, 0, (CFDictionaryRef)value); + CFArrayAppendValue(copiedDetails, copiedValue); + CFReleaseNull(copiedValue); + }); + return copiedDetails; +} + /* AUDIT[securityd](done): policy->_options is a caller provided dictionary, only its cf type has been checked. @@ -3468,11 +3752,13 @@ void SecPVCPathChecks(SecPVCRef pvc) { bool ev_check_ok = false; if (SecCertificatePathVCIsOptionallyEV(path)) { SecTrustResultType pre_ev_check_result = pvc->result; + CFArrayRef pre_ev_check_details = pvc->details ? SecPVCCopyDetailsArray(pvc) : NULL; SecPolicyCheckEV(pvc, kSecPolicyCheckExtendedValidation); ev_check_ok = SecPVCIsOkResult(pvc); /* If ev checking failed, we still want to accept this chain as a non EV one, if it was valid as such. */ pvc->result = pre_ev_check_result; + CFAssignRetained(pvc->details, pre_ev_check_details); } /* Check for CT */ diff --git a/OSX/sec/securityd/SecPolicyServer.h b/OSX/sec/securityd/SecPolicyServer.h index 90f428ab..5c58babb 100644 --- a/OSX/sec/securityd/SecPolicyServer.h +++ b/OSX/sec/securityd/SecPolicyServer.h @@ -31,11 +31,11 @@ #define _SECURITY_SECPOLICYSERVER_H_ #include -#include +#include "Security/SecPolicyInternal.h" #include -#include -#include +#include "securityd/SecTrustServer.h" +#include "securityd/SecCertificateServer.h" __BEGIN_DECLS @@ -91,7 +91,7 @@ void SecPolicyServerInitialize(void); bool SecPolicyIsEVPolicy(const DERItem *policyOID); -SecTrustSettingsResult SecPVCGetTrustSettingsResult(SecPVCRef pvc, SecCertificateRef certificate, CFArrayRef constraints); +bool SecPVCIsAnchorPerConstraints(SecPVCRef pvc, SecCertificateSourceRef source, SecCertificateRef certificate); __END_DECLS diff --git a/OSX/sec/securityd/SecRevocationDb.c b/OSX/sec/securityd/SecRevocationDb.c index 2bdde133..2e29051c 100644 --- a/OSX/sec/securityd/SecRevocationDb.c +++ b/OSX/sec/securityd/SecRevocationDb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 Apple Inc. All Rights Reserved. + * Copyright (c) 2016-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -67,10 +67,151 @@ #include #include +#include #include #include #include +/* + ============================================================================== + CoreFoundation utilities + ============================================================================== +*/ + +static bool hashCFThing(CFTypeRef thing, CC_SHA256_CTX* hash_ctx); + +/* comparison function for sorting dictionary keys alphabetically */ +static int compareCFStrings(const void *p, const void *q) { + CFStringRef str1 = *(CFStringRef *)p; + CFStringRef str2 = *(CFStringRef *)q; + if (!(isString(str1) && isString(str2))) { + return -1; /* can't compare non-string types */ + } + CFComparisonResult result = CFStringCompare(str1, str2, 0); + if (result == kCFCompareLessThan) { + return -1; + } else if (result == kCFCompareGreaterThan) { + return 1; + } + return 0; /* (result == kCFCompareEqualTo) */ +} + +static bool hashData(CFDataRef data, CC_SHA256_CTX* hash_ctx) { + if (!isData(data)) { return false; } + uint32_t length = (uint32_t)(CFDataGetLength(data) & 0xFFFFFFFF); + uint32_t n = OSSwapInt32(length); + CC_SHA256_Update(hash_ctx, &n, sizeof(uint32_t)); + const uint8_t *p = (uint8_t*)CFDataGetBytePtr(data); + if (p) { CC_SHA256_Update(hash_ctx, p, length); } + return (p != NULL); +} + +static bool hashString(CFStringRef str, CC_SHA256_CTX* hash_ctx) { + if (!isString(str)) { return false; } + __block bool ok = false; + CFStringPerformWithCString(str, ^(const char *strbuf) { + // hash string length (in bytes, not counting null terminator) + uint32_t c = (uint32_t)(strlen(strbuf) & 0xFFFFFFFF); + uint32_t n = OSSwapInt32(c); + CC_SHA256_Update(hash_ctx, &n, sizeof(uint32_t)); + // hash string bytes + CC_SHA256_Update(hash_ctx, strbuf, c); + ok = true; + }); + return ok; +} + +static bool hashNumber(CFNumberRef num, CC_SHA256_CTX* hash_ctx) { + uint32_t n = 0; + if (!isNumber(num) || !CFNumberGetValue(num, kCFNumberSInt32Type, &n)) { + return false; + } + n = OSSwapInt32(n); + CC_SHA256_Update(hash_ctx, &n, sizeof(uint32_t)); + return true; +} + +static bool hashBoolean(CFBooleanRef value, CC_SHA256_CTX* hash_ctx) { + if (!isBoolean(value)) { return false; } + uint8_t c = CFBooleanGetValue(value) ? 1 : 0; + CC_SHA256_Update(hash_ctx, &c, sizeof(uint8_t)); + return true; +} + +static bool hashArray(CFArrayRef array, CC_SHA256_CTX* hash_ctx) { + if (!isArray(array)) { return false; } + CFIndex count = CFArrayGetCount(array); + uint32_t n = OSSwapInt32(count & 0xFFFFFFFF); + CC_SHA256_Update(hash_ctx, &n, sizeof(uint32_t)); + __block bool ok = true; + CFArrayForEach(array, ^(const void *thing) { + ok &= hashCFThing(thing, hash_ctx); + }); + return ok; +} + +static bool hashDictionary(CFDictionaryRef dictionary, CC_SHA256_CTX* hash_ctx) { + if (!isDictionary(dictionary)) { return false; } + CFIndex count = CFDictionaryGetCount(dictionary); + const void **keys = (const void **)malloc(sizeof(void*) * count); + const void **vals = (const void **)malloc(sizeof(void*) * count); + bool ok = (keys && vals); + if (ok) { + CFDictionaryGetKeysAndValues(dictionary, keys, vals); + qsort(keys, count, sizeof(CFStringRef), compareCFStrings); + uint32_t n = OSSwapInt32(count & 0xFFFFFFFF); + CC_SHA256_Update(hash_ctx, &n, sizeof(uint32_t)); + } + for (CFIndex idx = 0; ok && idx < count; idx++) { + CFStringRef key = (CFStringRef)keys[idx]; + CFTypeRef value = (CFTypeRef)CFDictionaryGetValue(dictionary, key); + ok &= hashString(key, hash_ctx); + ok &= hashCFThing(value, hash_ctx); + } + free(keys); + free(vals); + return ok; +} + +static bool hashCFThing(CFTypeRef thing, CC_SHA256_CTX* hash_ctx) { + if (isArray(thing)) { + return hashArray(thing, hash_ctx); + } else if (isDictionary(thing)) { + return hashDictionary(thing, hash_ctx); + } else if (isData(thing)) { + return hashData(thing, hash_ctx); + } else if (isString(thing)) { + return hashString(thing, hash_ctx); + } else if (isNumber(thing)) { + return hashNumber(thing, hash_ctx); + } else if (isBoolean(thing)) { + return hashBoolean(thing, hash_ctx); + } + return false; +} + +static double htond(double h) { + /* no-op if big endian */ + if (OSHostByteOrder() == OSBigEndian) { + return h; + } + double n; + size_t i=0; + char *hp = (char*)&h; + char *np = (char*)&n; + while (i < sizeof(h)) { np[i] = hp[(sizeof(h)-1)-i]; ++i; } + return n; +} + + +// MARK: - +// MARK: Valid definitions +/* + ============================================================================== + Valid definitions + ============================================================================== +*/ + const CFStringRef kValidUpdateProdServer = CFSTR("valid.apple.com"); const CFStringRef kValidUpdateSeedServer = CFSTR("valid.apple.com/seed"); const CFStringRef kValidUpdateCarryServer = CFSTR("valid.apple.com/carry"); @@ -78,6 +219,7 @@ const CFStringRef kValidUpdateCarryServer = CFSTR("valid.apple.com/carry"); static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security"); static CFStringRef kUpdateServerKey = CFSTR("ValidUpdateServer"); static CFStringRef kUpdateEnabledKey = CFSTR("ValidUpdateEnabled"); +static CFStringRef kVerifyEnabledKey = CFSTR("ValidVerifyEnabled"); static CFStringRef kUpdateIntervalKey = CFSTR("ValidUpdateInterval"); static CFStringRef kBoolTrueKey = CFSTR("1"); static CFStringRef kBoolFalseKey = CFSTR("0"); @@ -103,7 +245,7 @@ typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { #define kSecMinUpdateInterval (60.0 * 5) /* standard update interval */ -#define kSecStdUpdateInterval (60.0 * 60) +#define kSecStdUpdateInterval (60.0 * 60 * 3) /* maximum allowed interval */ #define kSecMaxUpdateInterval (60.0 * 60 * 24 * 7) @@ -124,14 +266,15 @@ typedef CF_OPTIONS(CFOptionFlags, SecValidInfoFlags) { 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 + v7 = add policies column to groups table (policy constraints) 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 6 /* current version we support */ -#define kSecRevocationDbMinSchemaVersion 6 /* minimum version we can use */ +#define kSecRevocationDbSchemaVersion 7 /* current version we support */ +#define kSecRevocationDbMinSchemaVersion 7 /* minimum version we can use */ /* update file format */ @@ -164,6 +307,7 @@ struct __SecRevocationDbConnection { SecDbConnectionRef dbconn; CFIndex precommitVersion; CFIndex precommitDbVersion; + CFIndex precommitInterval; bool fullUpdate; }; @@ -181,14 +325,21 @@ CFAbsoluteTime SecRevocationDbGetNextUpdateTime(void); dispatch_queue_t SecRevocationDbGetUpdateQueue(void); bool _SecRevocationDbRemoveAllEntries(SecRevocationDbConnectionRef dbc, CFErrorRef *error); void SecRevocationDbReleaseAllConnections(void); +static bool SecValidUpdateForceReplaceDatabase(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 SecRevocationDbPerformRead(SecRevocationDbRef rdb, CFErrorRef *error, bool(^readJob)(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError)); +static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnectionRef dbc, int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFDataRef *policies, CFErrorRef *error); +static bool _SecRevocationDbSetUpdateInterval(SecRevocationDbConnectionRef dbc, int64_t interval, CFErrorRef *error); +static int64_t _SecRevocationDbGetUpdateInterval(SecRevocationDbConnectionRef dbc, 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 CFArrayRef _SecRevocationDbCopyHashes(SecRevocationDbConnectionRef dbc, CFErrorRef *error); +static bool _SecRevocationDbSetHashes(SecRevocationDbConnectionRef dbc, CFArrayRef hashes, CFErrorRef *error); static void SecRevocationDbResetCaches(void); static SecRevocationDbConnectionRef SecRevocationDbConnectionInit(SecRevocationDbRef db, SecDbConnectionRef dbconn, CFErrorRef *error); +static bool SecRevocationDbComputeDigests(SecRevocationDbConnectionRef dbc, CFErrorRef *error); static CFDataRef copyInflatedData(CFDataRef data) { @@ -223,10 +374,7 @@ static CFDataRef copyInflatedData(CFDataRef data) { } while (rc == Z_OK); inflateEnd(&zs); - - if (buf) { - free(buf); - } + free(buf); if (rc != Z_STREAM_END) { CFReleaseSafe(outData); return NULL; @@ -273,10 +421,7 @@ static CFDataRef copyDeflatedData(CFDataRef data) { } while (rc == Z_OK && zs.avail_in); deflateEnd(&zs); - - if (buf) { - free(buf); - } + free(buf); if (rc != Z_STREAM_END) { CFReleaseSafe(outData); return NULL; @@ -346,6 +491,36 @@ static bool removeFileWithSuffix(const char *basepath, const char *suffix) { return result; } +static CFDataRef CF_RETURNS_RETAINED createPoliciesData(CFArrayRef policies) { + /* + * Given an array of CFNumber values (in the range 0..127), + * allocate and return a CFDataRef representation. Per Valid specification, + * a zero-length array is allowed, meaning no policies are permitted. + */ + CFIndex count = (policies) ? CFArrayGetCount(policies) : -1; + if (count < 0 || count > 127) { + return NULL; /* either no constraints, or far more than we expect. */ + } + CFDataRef data = NULL; + CFIndex length = 1 + (sizeof(int8_t) * count); + int8_t *bytes = malloc(length); + if (bytes) { + int8_t *p = bytes; + *p++ = (int8_t)(count & 0xFF); + for (CFIndex idx = 0; idx < count; idx++) { + int8_t pval = 0; + CFNumberRef value = (CFNumberRef)CFArrayGetValueAtIndex(policies, idx); + if (isNumber(value)) { + (void)CFNumberGetValue(value, kCFNumberSInt8Type, &pval); + } + *p++ = pval; + } + data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)bytes, length); + } + free(bytes); + return data; +} + static CFDataRef CF_RETURNS_RETAINED cfToHexData(CFDataRef data, bool prependWildcard) { if (!isData(data)) { return NULL; } CFIndex len = CFDataGetLength(data) * 2; @@ -365,12 +540,54 @@ static CFDataRef CF_RETURNS_RETAINED cfToHexData(CFDataRef data, bool prependWil return result; } +static bool copyFilterComponents(CFDataRef xmlData, CFDataRef * CF_RETURNS_RETAINED xor, + CFArrayRef * CF_RETURNS_RETAINED params) { + /* + The 'xmlData' parameter is a flattened XML dictionary, + containing 'xor' and 'params' keys. First order of + business is to reconstitute the blob into components. + */ + bool result = false; + CFRetainSafe(xmlData); + CFDataRef propListData = xmlData; + /* Expand data blob if needed */ + CFDataRef inflatedData = copyInflatedData(propListData); + if (inflatedData) { + CFReleaseSafe(propListData); + propListData = inflatedData; + } + CFDataRef xorData = NULL; + CFArrayRef paramsArray = NULL; + CFPropertyListRef nto1 = CFPropertyListCreateWithData(kCFAllocatorDefault, propListData, 0, NULL, NULL); + CFReleaseSafe(propListData); + if (nto1) { + xorData = (CFDataRef)CFDictionaryGetValue((CFDictionaryRef)nto1, CFSTR("xor")); + CFRetainSafe(xorData); + paramsArray = (CFArrayRef)CFDictionaryGetValue((CFDictionaryRef)nto1, CFSTR("params")); + CFRetainSafe(paramsArray); + CFReleaseSafe(nto1); + } + result = (xorData && paramsArray); + if (xor) { + *xor = xorData; + } else { + CFReleaseSafe(xorData); + } + if (params) { + *params = paramsArray; + } else { + CFReleaseSafe(paramsArray); + } + return result; +} + // MARK: - // MARK: SecValidUpdate - -/* ====================================================================== +/* + ============================================================================== SecValidUpdate - ======================================================================*/ + ============================================================================== +*/ CFAbsoluteTime gUpdateStarted = 0.0; CFAbsoluteTime gNextUpdate = 0.0; @@ -460,6 +677,10 @@ static bool SecValidUpdateProcessData(SecRevocationDbConnectionRef dbc, CFIndex if (isNumber(value)) { CFNumberGetValue((CFNumberRef)value, kCFNumberCFIndexType, &interval); } + // get server-provided hash list + value = (CFArrayRef)CFDictionaryGetValue((CFDictionaryRef)propertyList, + CFSTR("hash")); + ok = _SecRevocationDbSetHashes(dbc, (CFArrayRef)value, &localError); } if (ok && curVersion < 0) { plistCount = 0; // we already had this version; skip remaining plists @@ -516,20 +737,19 @@ void SecValidUpdateVerifyAndIngest(CFDataRef updateData, CFStringRef updateServe 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 && _SecRevocationDbRemoveAllEntries(dbc, blockError); ok = ok && _SecRevocationDbSetUpdateSource(dbc, updateServer, blockError); - if (dbc) { - dbc->precommitVersion = 0; - dbc->fullUpdate = true; - } + dbc->precommitVersion = 0; + dbc->fullUpdate = true; } + CFIndex startingVersion = dbc->precommitVersion; ok = ok && SecValidUpdateProcessData(dbc, kSecValidUpdateFormatG3, updateData, blockError); + rdb->changed = ok && (startingVersion < dbc->precommitVersion); if (!ok) { secerror("failed to process valid update: %@", blockError ? *blockError : NULL); TrustdHealthAnalyticsLogErrorCode(TAEventValidUpdate, TAFatalError, errSecDecode); @@ -540,6 +760,24 @@ void SecValidUpdateVerifyAndIngest(CFDataRef updateData, CFStringRef updateServe }); if (rdb->changed) { rdb->changed = false; + bool verifyEnabled = false; + CFBooleanRef value = (CFBooleanRef)CFPreferencesCopyValue(kVerifyEnabledKey, + kSecPrefsDomain, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + if (isBoolean(value)) { + verifyEnabled = CFBooleanGetValue(value); + } + CFReleaseNull(value); + if (verifyEnabled) { + /* compute and verify database content hashes */ + ok = ok && SecRevocationDbPerformRead(rdb, &localError, ^bool(SecRevocationDbConnectionRef dbc, CFErrorRef *blockError) { + ok = ok && SecRevocationDbComputeDigests(dbc, blockError); + if (!ok) { + /* digests failed to verify, so roll back to known-good snapshot */ + (void) SecValidUpdateForceReplaceDatabase(); + } + return ok; + }); + } /* signal other trustd instances that the database has been updated */ notify_post(kSecRevocationDbChanged); } @@ -548,31 +786,25 @@ void SecValidUpdateVerifyAndIngest(CFDataRef updateData, CFStringRef updateServe /* remember next update time in case of restart (separate write transaction) */ (void) SecRevocationDbSetNextUpdateTime(gNextUpdate, NULL); - if (dbc) { - free(dbc); - } CFReleaseSafe(localError); } static bool SecValidUpdateForceReplaceDatabase(void) { - bool result = false; + __block bool result = false; // write semaphore file that we will pick up when we next launch - char *semPathBuf = NULL; - asprintf(&semPathBuf, "%s/%s", kSecRevocationBasePath, kSecRevocationDbReplaceFile); - if (semPathBuf) { + WithPathInRevocationInfoDirectory(CFSTR(kSecRevocationDbReplaceFile), ^(const char *utf8String) { struct stat sb; - int fd = open(semPathBuf, O_WRONLY | O_CREAT, DEFFILEMODE); + int fd = open(utf8String, O_WRONLY | O_CREAT, DEFFILEMODE); if (fd == -1 || fstat(fd, &sb)) { - secnotice("validupdate", "unable to write %s", semPathBuf); + secnotice("validupdate", "unable to write %s (error %d)", utf8String, errno); } 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"); @@ -711,7 +943,9 @@ void SecRevocationDbInitialize() { __block bool initializeDb = false; /* create base path if it doesn't exist */ - (void)mkpath_np(kSecRevocationBasePath, 0755); + WithPathInRevocationInfoDirectory(NULL, ^(const char *utf8String) { + (void)mkpath_np(utf8String, 0755); + }); /* check semaphore file */ WithPathInRevocationInfoDirectory(CFSTR(kSecRevocationDbReplaceFile), ^(const char *path) { @@ -765,11 +999,11 @@ void SecRevocationDbInitialize() { // MARK: - // MARK: SecValidInfoRef - -/* ====================================================================== +/* + ============================================================================== SecValidInfoRef - ====================================================================== - */ + ============================================================================== +*/ CFGiblisWithCompareFor(SecValidInfo); @@ -875,10 +1109,10 @@ static CFStringRef SecValidInfoCopyFormatDescription(CFTypeRef cf, CFDictionaryR // MARK: - // MARK: SecRevocationDb - -/* ====================================================================== +/* + ============================================================================== SecRevocationDb - ====================================================================== + ============================================================================== */ /* SecRevocationDbCheckNextUpdate returns true if we dispatched an @@ -1201,8 +1435,8 @@ setVersionAndExit: 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 + kSecValidInfoNameConstraints (0x00000100) set if this group has name constraints in database + kSecValidInfoPolicyConstraints (0x00000200) 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 @@ -1210,6 +1444,7 @@ setVersionAndExit: kSecValidInfoFormatSHA256 (2) SHA-256 hash, 32 bytes in length kSecValidInfoFormatNto1 (3) filter data blob of arbitrary length data (blob) // Bloom filter data if format is 'nto1', otherwise NULL + policies (blob) // NULL, or uint8_t count value followed by array of int8_t policy values --> entries in groups table are unique by groupid serials table holds serial number blobs with these attributes: @@ -1243,7 +1478,8 @@ setVersionAndExit: "groupid INTEGER PRIMARY KEY AUTOINCREMENT," \ "flags INTEGER," \ "format INTEGER," \ - "data BLOB" \ + "data BLOB," \ + "policies BLOB" \ ");" \ "CREATE TABLE IF NOT EXISTS serials(" \ "groupid INTEGER NOT NULL," \ @@ -1283,8 +1519,10 @@ setVersionAndExit: "WHERE key='db_source'") #define selectNextUpdateSQL CFSTR("SELECT value FROM admin " \ "WHERE key='check_again'") -#define selectGroupRecordSQL CFSTR("SELECT flags,format,data FROM " \ - "groups WHERE groupid=?") +#define selectUpdateIntervalSQL CFSTR("SELECT ival FROM admin " \ + "WHERE key='interval'") +#define selectGroupRecordSQL CFSTR("SELECT flags,format,data,policies " \ + "FROM groups WHERE groupid=?") #define selectSerialRecordSQL CFSTR("SELECT rowid FROM serials " \ "WHERE groupid=? AND serial=?") #define selectDateRecordSQL CFSTR("SELECT notbefore,notafter FROM " \ @@ -1296,7 +1534,7 @@ setVersionAndExit: #define insertIssuerRecordSQL CFSTR("INSERT OR REPLACE INTO issuers " \ "(groupid,issuer_hash) VALUES (?,?)") #define insertGroupRecordSQL CFSTR("INSERT OR REPLACE INTO groups " \ - "(groupid,flags,format,data) VALUES (?,?,?,?)") + "(groupid,flags,format,data,policies) VALUES (?,?,?,?,?)") #define insertSerialRecordSQL CFSTR("INSERT OR REPLACE INTO serials " \ "(groupid,serial) VALUES (?,?)") #define deleteSerialRecordSQL CFSTR("DELETE FROM serials " \ @@ -1311,6 +1549,10 @@ setVersionAndExit: "WHERE groupid=?") #define deleteGroupIssuersSQL CFSTR("DELETE FROM issuers " \ "WHERE groupid=?") +#define addPoliciesColumnSQL CFSTR("ALTER TABLE groups " \ + "ADD COLUMN policies BLOB") +#define updateGroupPoliciesSQL CFSTR("UPDATE OR IGNORE groups " \ + "SET policies=? WHERE groupid=?") #define updateConstraintsTablesSQL CFSTR("" \ "CREATE TABLE IF NOT EXISTS dates(" \ @@ -1485,8 +1727,9 @@ static SecRevocationDbConnectionRef SecRevocationDbConnectionInit(SecRevocationD if (dbc) { dbc->db = db; dbc->dbconn = dbconn; - dbc->precommitVersion = _SecRevocationDbGetVersion(dbc, &localError); - dbc->precommitDbVersion = _SecRevocationDbGetSchemaVersion(db, dbc, &localError); + dbc->precommitVersion = (CFIndex)_SecRevocationDbGetVersion(dbc, &localError); + dbc->precommitDbVersion = (CFIndex)_SecRevocationDbGetSchemaVersion(db, dbc, &localError); + dbc->precommitInterval = 0; /* set only if we are explicitly given a new value */ dbc->fullUpdate = false; } (void) CFErrorPropagate(localError, error); @@ -1581,6 +1824,116 @@ static void SecRevocationDbCachePurge(SecRevocationDbRef db) { os_unfair_lock_unlock(&db->info_cache_lock); } +static int64_t _SecRevocationDbGetUpdateInterval(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + /* look up interval entry in admin table; returns -1 on error */ + __block int64_t interval = -1; + __block bool ok = true; + __block CFErrorRef localError = NULL; + + ok = ok && SecDbWithSQL(dbc->dbconn, selectUpdateIntervalSQL, &localError, ^bool(sqlite3_stmt *selectInterval) { + ok = ok && SecDbStep(dbc->dbconn, selectInterval, &localError, ^void(bool *stop) { + interval = sqlite3_column_int64(selectInterval, 0); + *stop = true; + }); + return ok; + }); + if (!ok || localError) { + secerror("_SecRevocationDbGetUpdateInterval failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationRead, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } + (void) CFErrorPropagate(localError, error); + return interval; +} + +static bool _SecRevocationDbSetUpdateInterval(SecRevocationDbConnectionRef dbc, int64_t interval, CFErrorRef *error) { + secdebug("validupdate", "setting interval to %lld", interval); + + __block CFErrorRef localError = NULL; + __block bool ok = (dbc != NULL); + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertInterval) { + const char *intervalKey = "interval"; + ok = ok && SecDbBindText(insertInterval, 1, intervalKey, strlen(intervalKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertInterval, 2, + (sqlite3_int64)interval, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertInterval, &localError, NULL); + return ok; + }); + if (!ok || localError) { + secerror("_SecRevocationDbSetUpdateInterval failed: %@", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } + (void) CFErrorPropagate(localError, error); + return ok; +} + +static CFArrayRef _SecRevocationDbCopyHashes(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + /* return a retained copy of the db_hash array stored in the admin table; or NULL on error */ + __block CFMutableArrayRef hashes = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + __block bool ok = (dbc && hashes); + __block CFErrorRef localError = NULL; + + ok = ok && SecDbWithSQL(dbc->dbconn, selectDbHashSQL, &localError, ^bool(sqlite3_stmt *selectDbHash) { + ok = ok && SecDbStep(dbc->dbconn, selectDbHash, &localError, ^void(bool *stop) { + uint8_t *p = (uint8_t *)sqlite3_column_blob(selectDbHash, 0); + uint64_t len = sqlite3_column_bytes(selectDbHash, 0); + CFIndex hashLen = CC_SHA256_DIGEST_LENGTH; + while (p && len >= (uint64_t)hashLen) { + CFDataRef hash = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)p, hashLen); + if (hash) { + CFArrayAppendValue(hashes, hash); + CFReleaseNull(hash); + } + len -= hashLen; + p += hashLen; + } + *stop = true; + }); + return ok; + }); + if (!ok || localError) { + CFReleaseNull(hashes); + } + (void) CFErrorPropagate(localError, error); + return hashes; +} + +static bool _SecRevocationDbSetHashes(SecRevocationDbConnectionRef dbc, CFArrayRef hashes, CFErrorRef *error) { + /* flatten and store db_hash array in the admin table */ + __block CFErrorRef localError = NULL; + __block bool ok = (dbc && hashes); + + ok = ok && SecDbWithSQL(dbc->dbconn, insertAdminRecordSQL, &localError, ^bool(sqlite3_stmt *insertHashes) { + CFIndex count = CFArrayGetCount(hashes); + CFIndex hashLen = CC_SHA256_DIGEST_LENGTH, dataLen = hashLen * count; + uint8_t *dataPtr = (uint8_t *)calloc(dataLen, 1); + uint8_t *p = dataPtr; + for (CFIndex idx = 0; idx < count && p; idx++) { + CFDataRef hash = CFArrayGetValueAtIndex(hashes, idx); + uint8_t *h = (hash) ? (uint8_t *)CFDataGetBytePtr(hash) : NULL; + if (h && CFDataGetLength(hash) == hashLen) { memcpy(p, h, hashLen); } + p += hashLen; + } + const char *hashKey = "db_hash"; + ok = ok && SecDbBindText(insertHashes, 1, hashKey, strlen(hashKey), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(insertHashes, 2, + (sqlite3_int64)0, &localError); + ok = ok && SecDbBindBlob(insertHashes, 3, + dataPtr, dataLen, + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbStep(dbc->dbconn, insertHashes, &localError, NULL); + free(dataPtr); + return ok; + }); + if (!ok || localError) { + } + (void) CFErrorPropagate(localError, error); + return ok; +} + static int64_t _SecRevocationDbGetVersion(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { /* look up version entry in admin table; returns -1 on error */ __block int64_t version = -1; @@ -1752,6 +2105,14 @@ static bool _SecRevocationDbUpdateSchema(SecRevocationDbConnectionRef dbc, CFErr SecValidUpdateForceReplaceDatabase(); } } + if (ok && db_version < 7) { + /* apply v7 changes (add policies column in groups table) */ + ok &= SecDbWithSQL(dbc->dbconn, addPoliciesColumnSQL, &localError, ^bool(sqlite3_stmt *addPoliciesColumn) { + ok = SecDbStep(dbc->dbconn, addPoliciesColumn, &localError, NULL); + return ok; + }); + secdebug("validupdate", "applied schema update to v7 (%s)", (ok) ? "ok" : "failed!"); + } if (!ok) { secerror("_SecRevocationDbUpdateSchema failed: %@", localError); @@ -2026,7 +2387,7 @@ static SecValidInfoFormat _SecRevocationDbGetGroupFormatForData(SecRevocationDbC otherwise return the expected format for the given data. */ SecValidInfoFormat format = kSecValidInfoFormatUnknown; if (groupId >= 0 && !dbc->fullUpdate) { - format = _SecRevocationDbGetGroupFormat(dbc, groupId, NULL, NULL, NULL); + format = _SecRevocationDbGetGroupFormat(dbc, groupId, NULL, NULL, NULL, NULL); } if (format == kSecValidInfoFormatUnknown && data != NULL) { /* group doesn't exist, so determine format based on length of specified data. @@ -2194,11 +2555,10 @@ static bool _SecRevocationDbCopyDateConstraints(SecRevocationDbConnectionRef dbc return ok; } -static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { - /* update optional records in dates, names, or policies tables. */ - if (!dbc || !dict || groupId < 0) { - return false; /* must have something to insert, and a group to associate with it */ - } +static bool _SecRevocationDbUpdateDateConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { + /* Called only from _SecRevocationDbUpdateIssuerConstraints. + Function assumes that the caller has checked the input arguments. + */ __block bool ok = true; __block CFErrorRef localError = NULL; __block CFAbsoluteTime notBefore = -3155760000.0; /* default: 1901-01-01 00:00:00-0000 */ @@ -2206,6 +2566,7 @@ static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef CFDateRef notBeforeDate = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-before")); CFDateRef notAfterDate = (CFDateRef)CFDictionaryGetValue(dict, CFSTR("not-after")); + if (isDate(notBeforeDate)) { notBefore = CFDateGetAbsoluteTime(notBeforeDate); } else { @@ -2240,7 +2601,6 @@ static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef } } } - ok = ok && SecDbWithSQL(dbc->dbconn, insertDateRecordSQL, &localError, ^bool(sqlite3_stmt *insertDate) { /* (groupid,notbefore,notafter) */ ok = ok && SecDbBindInt64(insertDate, 1, groupId, &localError); @@ -2250,24 +2610,76 @@ static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef return ok; }); - /* %%% (TBI:9254570,21234699) update name and policy constraint entries here */ - if (!ok || localError) { - secinfo("validupdate", "_SecRevocationDbUpdateIssuerConstraints failed (ok=%s, localError=%@)", + secinfo("validupdate", "_SecRevocationDbUpdateDateConstraints failed (ok=%s, localError=%@)", (ok) ? "1" : "0", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, localError ? CFErrorGetCode(localError) : errSecInternalComponent); } + (void) CFErrorPropagate(localError, error); + return ok; +} +static bool _SecRevocationDbUpdatePolicyConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { + /* Called only from _SecRevocationDbUpdateIssuerConstraints. + Function assumes that the caller has checked the input arguments. + */ + __block bool ok = true; + __block CFErrorRef localError = NULL; + CFArrayRef policies = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("policies")); + if (!isArray(policies)) { + return ok; /* no policies supplied, so nothing to update for this issuer */ + } + + __block CFDataRef data = createPoliciesData(policies); + ok = data && SecDbWithSQL(dbc->dbconn, updateGroupPoliciesSQL, &localError, ^bool(sqlite3_stmt *updatePolicies) { + /* (policies,groupid) */ + ok = ok && SecDbBindBlob(updatePolicies, 1, + CFDataGetBytePtr(data), + CFDataGetLength(data), + SQLITE_TRANSIENT, &localError); + ok = ok && SecDbBindInt64(updatePolicies, 2, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, updatePolicies, &localError, NULL); + return ok; + }); + CFReleaseSafe(data); + + if (!ok || localError) { + secinfo("validupdate", "_SecRevocationDbUpdatePolicyConstraints failed (ok=%s, localError=%@)", + (ok) ? "1" : "0", localError); + TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, + localError ? CFErrorGetCode(localError) : errSecInternalComponent); + } (void) CFErrorPropagate(localError, error); return ok; } +static bool _SecRevocationDbUpdateNameConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { + /* Called only from _SecRevocationDbUpdateIssuerConstraints. + Function assumes that the caller has checked the input arguments. + */ + + /* %%% (TBI:9254570) update name constraint entries here */ + return true; +} + +static bool _SecRevocationDbUpdateIssuerConstraints(SecRevocationDbConnectionRef dbc, int64_t groupId, CFDictionaryRef dict, CFErrorRef *error) { + /* check input arguments */ + if (!dbc || !dict || groupId < 0) { + return false; + } + bool ok = true; + ok = ok && _SecRevocationDbUpdateDateConstraints(dbc, groupId, dict, error); + ok = ok && _SecRevocationDbUpdateNameConstraints(dbc, groupId, dict, error); + ok = ok && _SecRevocationDbUpdatePolicyConstraints(dbc, groupId, dict, error); + return ok; +} + static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnectionRef dbc, - int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFErrorRef *error) { + int64_t groupId, SecValidInfoFlags *flags, CFDataRef *data, CFDataRef *policies, 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. + caller is responsible for releasing data, policies, and error parameters, if provided. */ __block bool ok = (dbc != NULL); __block SecValidInfoFormat format = 0; @@ -2289,6 +2701,13 @@ static SecValidInfoFormat _SecRevocationDbGetGroupFormat(SecRevocationDbConnecti *data = CFDataCreate(kCFAllocatorDefault, p, length); } } + if (policies) { + uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 3); + if (p != NULL) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 3); + *policies = CFDataCreate(kCFAllocatorDefault, p, length); + } + } }); return ok; }); @@ -2483,11 +2902,12 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int __block SecValidInfoFormat format = kSecValidInfoFormatUnknown; __block SecValidInfoFormat formatUpdate = kSecValidInfoFormatUnknown; __block CFDataRef data = NULL; + __block CFDataRef policies = NULL; if (groupId >= 0) { /* fetch the flags and data for an existing group record, in case some are being changed. */ if (ok) { - format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, NULL); + format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, &policies, NULL); } if (format == kSecValidInfoFormatUnknown) { secdebug("validupdate", "existing group %lld has unknown format %d, flags=0x%lx", @@ -2527,7 +2947,7 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int }); } ok = ok && SecDbWithSQL(dbc->dbconn, insertGroupRecordSQL, &localError, ^bool(sqlite3_stmt *insertGroup) { - /* (groupid,flags,format,data) */ + /* (groupid,flags,format,data,policies) */ /* groups.groupid */ if (ok && (!isFormatChange) && (groupId >= 0)) { /* bind to existing groupId row if known, otherwise will insert and autoincrement */ @@ -2557,10 +2977,16 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int this flag; either a new date entry will be supplied, or a format change will cause the entire group entry to be deleted. */ } + /* policy constraints exist if "policies" key is found */ + CFTypeRef policiesValue = (CFArrayRef)CFDictionaryGetValue(dict, CFSTR("policies")); + if (isArray(policiesValue)) { + (void)_SecRevocationDbUpdateFlags(dict, kBoolTrueKey, kSecValidInfoPolicyConstraints, &flags); + /* As above, not providing this value in an update does not change the existing state, + so we never need to clear this flag once it is set. */ + } - /* %%% (TBI:9254570,21234699) name and policy constraints don't exist yet */ + /* %%% (TBI:9254570) name 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) { @@ -2602,6 +3028,26 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int } /* else there is no data, so NULL is implicitly bound to column 4 */ } + /* groups.policies */ + CFDataRef newPoliciesData = NULL; + if (ok) { + CFDataRef policiesValue = policies; /* use existing policies */ + newPoliciesData = createPoliciesData((CFArrayRef)CFDictionaryGetValue(dict, CFSTR("policies"))); + if (newPoliciesData) { + policiesValue = newPoliciesData; /* use updated policies */ + } + if (policiesValue) { + ok = SecDbBindBlob(insertGroup, 5, + CFDataGetBytePtr(policiesValue), + CFDataGetLength(policiesValue), + SQLITE_TRANSIENT, &localError); + } + /* else there is no policy data, so NULL is implicitly bound to column 5 */ + if (!ok) { + secdebug("validupdate", "failed to set policies for groupId %lld", + (long long)groupId); + } + } /* Execute the insert statement for the group record. */ if (ok) { @@ -2615,11 +3061,15 @@ static int64_t _SecRevocationDbUpdateGroup(SecRevocationDbConnectionRef dbc, int if (!ok) { secdebug("validupdate", "failed to insert group %lld", (long long)result); } - /* Clean up temporary allocation made in this block. */ + /* Clean up temporary allocations made in this block. */ CFReleaseSafe(xmlData); - CFReleaseSafe(data); + CFReleaseSafe(newPoliciesData); return ok; }); + + CFReleaseSafe(data); + CFReleaseSafe(policies); + if (!ok || localError) { secerror("_SecRevocationDbUpdateGroup failed: %@", localError); TrustdHealthAnalyticsLogErrorCodeForDatabase(TARevocationDb, TAOperationWrite, TAFatalError, @@ -2814,6 +3264,13 @@ bool _SecRevocationDbApplyUpdate(SecRevocationDbConnectionRef dbc, CFDictionaryR /* set version */ ok = ok && _SecRevocationDbSetVersion(dbc, version, &localError); + /* set interval if not already set, or changed */ + int64_t interval = _SecRevocationDbGetUpdateInterval(dbc, NULL); + if (interval != dbc->precommitInterval) { + interval = (dbc->precommitInterval > 0) ? dbc->precommitInterval : kSecStdUpdateInterval; + ok = ok && _SecRevocationDbSetUpdateInterval(dbc, interval, &localError); + } + /* set db_version if not already set */ int64_t db_version = _SecRevocationDbGetSchemaVersion(dbc->db, dbc, NULL); if (db_version <= 0) { @@ -2975,16 +3432,16 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbCo CFDataRef certHash = NULL; CFDateRef notBeforeDate = NULL; CFDateRef notAfterDate = NULL; - CFDataRef nameConstraints = NULL; - CFDataRef policyConstraints = NULL; + CFDataRef names = NULL; + CFDataRef policies = NULL; SecValidInfoRef result = NULL; require((serial = SecCertificateCopySerialNumberData(certificate, NULL)) != NULL, errOut); require((certHash = SecCertificateCopySHA256Digest(certificate)) != NULL, errOut); - require((groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, &localError)) > 0, errOut); + require_quiet((groupId = _SecRevocationDbGroupIdForIssuerHash(dbc, issuerHash, &localError)) > 0, errOut); /* Look up the group record to determine flags and format. */ - format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, &localError); + format = _SecRevocationDbGetGroupFormat(dbc, groupId, &flags, &data, &policies, &localError); if (format == kSecValidInfoFormatUnknown) { /* No group record found for this issuer. Don't return a SecValidInfoRef */ @@ -3024,7 +3481,7 @@ static SecValidInfoRef _SecRevocationDbValidInfoForCertificate(SecRevocationDbCo result = SecValidInfoCreate(format, flags, isOnList, certHash, issuerHash, /*anchorHash*/ NULL, notBeforeDate, notAfterDate, - nameConstraints, policyConstraints); + names, policies); if (result && SecIsAppleTrustAnchor(certificate, 0)) { /* Prevent a catch-22. */ @@ -3040,8 +3497,8 @@ errOut: CFReleaseSafe(serial); CFReleaseSafe(notBeforeDate); CFReleaseSafe(notAfterDate); - CFReleaseSafe(nameConstraints); - CFReleaseSafe(policyConstraints); + CFReleaseSafe(names); + CFReleaseSafe(policies); return result; } @@ -3195,7 +3652,7 @@ CFIndex SecRevocationDbGetVersion(void) { CFIndex SecRevocationDbGetSchemaVersion(void) { __block CFIndex result = -1; SecRevocationDbWith(^(SecRevocationDbRef db) { - result = _SecRevocationDbGetSchemaVersion(db, NULL, NULL); + result = (CFIndex)_SecRevocationDbGetSchemaVersion(db, NULL, NULL); }); return result; } @@ -3214,3 +3671,308 @@ CFIndex SecRevocationDbGetUpdateFormat(void) { }); return result; } + +// MARK: - +// MARK: Digests +/* + ============================================================================== + Digest computation + ============================================================================== +*/ + +/* Returns array of SHA-256 hashes computed over the contents of a valid.sqlite3 + database, in the order specified by the valid-server-api documentation. The + resulting hashes can be compared against those in the update's 'hash' array. + + Hash 0: full database (all fields in initial Valid specification) + Hash 1: all issuer_hash arrays, plus not-after and not-before dates for each + Hash 2: subset of issuer_hash arrays where the no-ca-v2 flag is set +*/ +static CF_RETURNS_RETAINED CFArrayRef SecRevocationDbComputeFullContentDigests(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + if (!dbc) { return NULL; } + __block bool ok = true; + __block CFErrorRef localError = NULL; + __block uint32_t N[4]={0,0,0,0}; + __block CC_SHA256_CTX hash0_ctx, hash1_ctx, hash2_ctx; + CC_SHA256_Init(&hash0_ctx); + CC_SHA256_Init(&hash1_ctx); + CC_SHA256_Init(&hash2_ctx); + + // Add version, check-again, and update (array count) fields as array of N. + // (Note: 'N' is defined as "unsigned 32-bit integer in network byte order") + int64_t version = _SecRevocationDbGetVersion(dbc, NULL); + N[0] = OSSwapInt32(version & 0xffffffff); + int64_t interval = _SecRevocationDbGetUpdateInterval(dbc, NULL); + if (interval < 0) { + interval = kSecStdUpdateInterval; // if we didn't store it, assume default + } + N[1] = OSSwapInt32(interval & 0xffffffff); + __block int64_t count = 0; + ok = ok && SecDbWithSQL(dbc->dbconn, CFSTR("SELECT count(*) FROM groups"), &localError, ^bool(sqlite3_stmt *selectGroupsCount) { + ok = ok && SecDbStep(dbc->dbconn, selectGroupsCount, &localError, ^void(bool *stop) { + count = sqlite3_column_int64(selectGroupsCount, 0); + *stop = true; + }); + return ok; + }); + N[2] = OSSwapInt32(count & 0xffffffff); + CC_SHA256_Update(&hash0_ctx, N, sizeof(uint32_t) * 3); + + // Sort the update array in order of minimum 'issuer-hash' entry. + // The issuer-hash array is first sorted to determine the lowest issuer-hash, + // and that value is used to sort the update entries. + // + // For our sqlite database, recreating the update array order means fetching + // the groupid column from the issuers table after sorting on issuer_hash, + // using DISTINCT to remove duplicates. Then, for each returned groupid, we + // obtain its list of issuers, its list of serials or hashes, and other data. + + ok = ok && SecDbWithSQL(dbc->dbconn, CFSTR("SELECT DISTINCT groupid FROM issuers ORDER BY issuer_hash ASC"), &localError, ^bool(sqlite3_stmt *selectGroups) { + ok = ok && SecDbForEach(dbc->dbconn, selectGroups, &localError, ^bool(int row_index) { + __block int64_t groupId = sqlite3_column_int64(selectGroups, 0); + ok = ok && SecDbWithSQL(dbc->dbconn, CFSTR("SELECT flags,format,data FROM groups WHERE groupid=?"), &localError, ^bool(sqlite3_stmt *selectGroup) { + ok = ok && SecDbBindInt64(selectGroup, 1, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, selectGroup, &localError, ^(bool *stop) { + // per-group info is hashed in the following order: + // - issuer_hash array data (sorted) + // - flag bytes, in order listed below + // - format string [serial|sha256|nto1] + // - add array data (sorted), if [serial|sha256] + // - params (if present) + // - xor data (if present) + + int64_t flags = sqlite3_column_int64(selectGroup, 0); + bool noCAv2 = (flags & kSecValidInfoNoCAv2Check); + + // instead of recreating the issuer_hash array in memory, + // hash its length (item count) followed by the data of each issuer_hash. + ok = ok && SecDbWithSQL(dbc->dbconn, CFSTR("SELECT count(*) FROM issuers WHERE groupid=?"), &localError, ^bool(sqlite3_stmt *selectIssuersCount) { + ok = ok && SecDbBindInt64(selectIssuersCount, 1, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, selectIssuersCount, &localError, ^void(bool *stop) { + count = sqlite3_column_int64(selectIssuersCount, 0); + *stop = true; + }); + return ok; + }); + uint32_t n = OSSwapInt32(count & 0xffffffff); + CC_SHA256_Update(&hash0_ctx, &n, sizeof(uint32_t)); + CC_SHA256_Update(&hash1_ctx, &n, sizeof(uint32_t)); + if (noCAv2) { + CC_SHA256_Update(&hash2_ctx, &n, sizeof(uint32_t)); + } + + // process issuer_hash entries for this group + ok = ok && SecDbWithSQL(dbc->dbconn, CFSTR("SELECT issuer_hash FROM issuers WHERE groupid=? ORDER BY issuer_hash ASC"), &localError, ^bool(sqlite3_stmt *selectIssuerHash) { + ok = ok && SecDbBindInt64(selectIssuerHash, 1, groupId, &localError); + ok = ok && SecDbForEach(dbc->dbconn, selectIssuerHash, &localError, ^bool(int row_index) { + uint8_t *p = (uint8_t *)sqlite3_column_blob(selectIssuerHash, 0); + CFDataRef data = NULL; + if (p != NULL) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectIssuerHash, 0); + data = CFDataCreate(kCFAllocatorDefault, p, length); + } + if (data != NULL) { + hashData(data, &hash0_ctx); + hashData(data, &hash1_ctx); + if (noCAv2) { + hashData(data, &hash2_ctx); + } + CFRelease(data); + } else { + ok = false; + } + return ok; + }); + return ok; + }); + + // process flags, converting to array of unsigned 8-bit values, either 0 or 1: + // [ complete, check-ocsp, known-intermediates-only, no-ca, overridable, require-ct, valid ] + uint8_t C[8]={0,0,0,0,0,0,0,0}; + C[0] = (flags & kSecValidInfoComplete) ? 1 : 0; + C[1] = (flags & kSecValidInfoCheckOCSP) ? 1 : 0; + C[2] = (flags & kSecValidInfoKnownOnly) ? 1 : 0; + C[3] = (flags & kSecValidInfoNoCACheck) ? 1 : 0; + C[4] = (flags & kSecValidInfoOverridable) ? 1 : 0; + C[5] = (flags & kSecValidInfoRequireCT) ? 1 : 0; + C[6] = (flags & kSecValidInfoAllowlist) ? 1 : 0; + CC_SHA256_Update(&hash0_ctx, C, sizeof(uint8_t) * 7); + + // process format, converting integer to string value [serial|sha256|nto1] + SecValidInfoFormat format = (SecValidInfoFormat)sqlite3_column_int(selectGroup, 1); + switch (format) { + case kSecValidInfoFormatSerial: + hashString(CFSTR("serial"), &hash0_ctx); + break; + case kSecValidInfoFormatSHA256: + hashString(CFSTR("sha256"), &hash0_ctx); + break; + case kSecValidInfoFormatNto1: + hashString(CFSTR("nto1"), &hash0_ctx); + break; + case kSecValidInfoFormatUnknown: + default: + ok = false; // unexpected format values are not allowed + break; + } + // process 'add' array (serial or sha256 format). + // instead of recreating the 'add' array in memory, + // hash its length (item count) followed by the data of each entry. + CFStringRef arrayCountSql = NULL; + if (format == kSecValidInfoFormatSerial) { + arrayCountSql = CFSTR("SELECT count(*) FROM serials WHERE groupid=?"); + } else if (format == kSecValidInfoFormatSHA256) { + arrayCountSql = CFSTR("SELECT count(*) FROM hashes WHERE groupid=?"); + } + if (arrayCountSql) { + ok = ok && SecDbWithSQL(dbc->dbconn, arrayCountSql, &localError, ^bool(sqlite3_stmt *selectAddCount) { + ok = ok && SecDbBindInt64(selectAddCount, 1, groupId, &localError); + ok = ok && SecDbStep(dbc->dbconn, selectAddCount, &localError, ^void(bool *stop) { + count = sqlite3_column_int64(selectAddCount, 0); + *stop = true; + }); + return ok; + }); + n = OSSwapInt32(count & 0xffffffff); + CC_SHA256_Update(&hash0_ctx, &n, sizeof(uint32_t)); + } + // process data entries for this group + CFStringRef arrayDataSql = NULL; + if (format == kSecValidInfoFormatSerial) { + arrayDataSql = CFSTR("SELECT serial FROM serials WHERE groupid=? ORDER BY serial ASC"); + } else if (format == kSecValidInfoFormatSHA256) { + arrayDataSql = CFSTR("SELECT sha256 FROM hashes WHERE groupid=? ORDER by sha256 ASC"); + } + if (arrayDataSql) { + ok = ok && SecDbWithSQL(dbc->dbconn, arrayDataSql, &localError, ^bool(sqlite3_stmt *selectAddData) { + ok = ok && SecDbBindInt64(selectAddData, 1, groupId, &localError); + ok = ok && SecDbForEach(dbc->dbconn, selectAddData, &localError, ^bool(int row_index) { + uint8_t *p = (uint8_t *)sqlite3_column_blob(selectAddData, 0); + CFDataRef data = NULL; + if (p != NULL) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectAddData, 0); + data = CFDataCreate(kCFAllocatorDefault, p, length); + } + if (data != NULL) { + hashData(data, &hash0_ctx); + CFRelease(data); + } else { + ok = false; + } + return ok; + }); + return ok; + }); + } + + // process params and xor data, if format is nto1 + if (format == kSecValidInfoFormatNto1) { + uint8_t *p = (uint8_t *)sqlite3_column_blob(selectGroup, 2); + CFDataRef data = NULL; + if (p != NULL) { + CFIndex length = (CFIndex)sqlite3_column_bytes(selectGroup, 2); + data = CFDataCreate(kCFAllocatorDefault, p, length); + } + if (data != NULL) { + // unpack params and xor data + CFDataRef xor = NULL; + CFArrayRef params = NULL; + if (copyFilterComponents(data, &xor, ¶ms)) { + hashArray(params, &hash0_ctx); + hashData(xor, &hash0_ctx); + } else { + ok = false; + } + CFReleaseSafe(xor); + CFReleaseSafe(params); + } + CFReleaseSafe(data); + } + + // process date constraints [not-after, not-before] + CFAbsoluteTime notBefore = -3155760000.0; /* default: 1901-01-01 00:00:00-0000 */ + CFAbsoluteTime notAfter = 31556908800.0; /* default: 3001-01-01 00:00:00-0000 */ + CFDateRef notBeforeDate = NULL; + CFDateRef notAfterDate = NULL; + if (_SecRevocationDbCopyDateConstraints(dbc, groupId, ¬BeforeDate, ¬AfterDate, &localError)) { + if (notBeforeDate) { + notBefore = CFDateGetAbsoluteTime(notBeforeDate); + CFReleaseNull(notBeforeDate); + } + if (notAfterDate) { + notAfter = CFDateGetAbsoluteTime(notAfterDate); + CFReleaseNull(notAfterDate); + } + } + double nb = htond(notBefore); + double na = htond(notAfter); + CC_SHA256_Update(&hash1_ctx, &na, sizeof(double)); + CC_SHA256_Update(&hash1_ctx, &nb, sizeof(double)); + + *stop = true; + }); // per-group step + return ok; + }); // per-group select + return ok; + }); // for each group in list + return ok; + }); // select full group list + + CFMutableArrayRef result = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + if (result) { + uint8_t digest[CC_SHA256_DIGEST_LENGTH]; + CFDataRef data = NULL; + CC_SHA256_Final(digest, &hash0_ctx); + if ((data = CFDataCreate(NULL, (const UInt8 *)digest, CC_SHA256_DIGEST_LENGTH)) != NULL) { + CFArrayAppendValue(result, data); + CFReleaseNull(data); + } + CC_SHA256_Final(digest, &hash1_ctx); + if ((data = CFDataCreate(NULL, (const UInt8 *)digest, CC_SHA256_DIGEST_LENGTH)) != NULL) { + CFArrayAppendValue(result, data); + CFReleaseNull(data); + } + CC_SHA256_Final(digest, &hash2_ctx); + if ((data = CFDataCreate(NULL, (const UInt8 *)digest, CC_SHA256_DIGEST_LENGTH)) != NULL) { + CFArrayAppendValue(result, data); + CFReleaseNull(data); + } + } + (void) CFErrorPropagate(localError, error); + return result; +} + +static bool SecRevocationDbComputeDigests(SecRevocationDbConnectionRef dbc, CFErrorRef *error) { + secinfo("validupdate", "Started verifying db content"); + bool result = true; + CFArrayRef expectedList = _SecRevocationDbCopyHashes(dbc, error); + CFIndex expectedCount = (expectedList) ? CFArrayGetCount(expectedList) : 0; + if (expectedCount < 1) { + secinfo("validupdate", "Unable to read db_hash values"); + CFReleaseNull(expectedList); + return result; // %%%% this will happen on first update, when db_hash isn't there + } + CFArrayRef computedList = SecRevocationDbComputeFullContentDigests(dbc, error); + CFIndex computedCount = (computedList) ? CFArrayGetCount(computedList) : 0; + for (CFIndex idx = 0; idx < expectedCount; idx++) { + if (idx >= computedCount) { + continue; // server provided additional hash value that we don't yet compute + } + CFDataRef expectedHash = (CFDataRef)CFArrayGetValueAtIndex(expectedList, idx); + CFDataRef computedHash = (CFDataRef)CFArrayGetValueAtIndex(computedList, idx); + if (!CFEqualSafe(expectedHash, computedHash)) { + result = false; + break; + } + } + if (!result) { + secinfo("validupdate", "Expected: %@", expectedList); + secinfo("validupdate", "Computed: %@", computedList); + } + secinfo("validupdate", "Finished verifying db content; result=%s", + (result) ? "SUCCESS" : "FAIL"); + CFReleaseSafe(expectedList); + CFReleaseSafe(computedList); + return result; +} + diff --git a/OSX/sec/securityd/SecRevocationDb.h b/OSX/sec/securityd/SecRevocationDb.h index 91f613ac..8559cfb5 100644 --- a/OSX/sec/securityd/SecRevocationDb.h +++ b/OSX/sec/securityd/SecRevocationDb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018 Apple Inc. All Rights Reserved. + * Copyright (c) 2016-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -49,6 +49,17 @@ typedef CF_ENUM(uint32_t, SecValidInfoFormat) { kSecValidInfoFormatNto1 = 3 }; +/* policy types */ +typedef CF_ENUM(int8_t, SecValidPolicy) { + kSecValidPolicyNone = -1, + kSecValidPolicyAny = 0, + kSecValidPolicyServerAuthentication = 1, + kSecValidPolicyClientAuthentication = 2, + kSecValidPolicyEmailProtection = 3, + kSecValidPolicyCodeSigning = 4, + kSecValidPolicyTimeStamping = 5, +}; + /*! @typedef SecValidInfoRef @abstract CFType used to return valid info lookup results. diff --git a/OSX/sec/securityd/SecRevocationNetworking.m b/OSX/sec/securityd/SecRevocationNetworking.m index ec7be407..c1852066 100644 --- a/OSX/sec/securityd/SecRevocationNetworking.m +++ b/OSX/sec/securityd/SecRevocationNetworking.m @@ -48,8 +48,6 @@ #import "SecRevocationNetworking.h" /* MARK: Valid Update Networking */ -#define kSecRevocationBasePath "/Library/Keychains/crls" - static CFStringRef kSecPrefsDomain = CFSTR("com.apple.security"); static CFStringRef kUpdateWiFiOnlyKey = CFSTR("ValidUpdateWiFiOnly"); static CFStringRef kUpdateBackgroundKey = CFSTR("ValidUpdateBackground"); diff --git a/OSX/sec/securityd/SecRevocationServer.c b/OSX/sec/securityd/SecRevocationServer.c index 512dd6fd..b81b047e 100644 --- a/OSX/sec/securityd/SecRevocationServer.c +++ b/OSX/sec/securityd/SecRevocationServer.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2018 Apple Inc. All Rights Reserved. + * Copyright (c) 2008-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -99,12 +99,9 @@ static bool SecOCSPSingleResponseProcess(SecOCSPSingleResponseRef this, CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, cfreason, true); - if (rvc->builder) { - CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); - if (info) { - /* make the revocation reason available in the trust result */ - CFDictionarySetValue(info, kSecTrustRevocationReason, cfreason); - } + SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); + if (path) { + SecCertificatePathVCSetRevocationReasonForCertificateAtIndex(path, rvc->certIX, cfreason); } CFRelease(cfreason); processed = true; @@ -165,11 +162,14 @@ static bool SecOCSPResponseEvaluateSigner(SecORVCRef rvc, CFArrayRef signers, CF }); CFDataRef clientAuditToken = SecPathBuilderCopyClientAuditToken(rvc->builder); - SecPathBuilderRef oBuilder = SecPathBuilderCreate(clientAuditToken, + SecPathBuilderRef oBuilder = SecPathBuilderCreate(NULL, clientAuditToken, signers, issuers, true, false, policies, NULL, NULL, NULL, verifyTime, NULL, NULL, SecOCSPEvaluateCompleted, completed); + /* disable network access to avoid recursion */ + SecPathBuilderSetCanAccessNetwork(oBuilder, false); + /* Build the chain(s), evaluate them, call the completed block, free the block and builder */ SecPathBuilderStep(oBuilder); CFReleaseNull(clientAuditToken); @@ -349,235 +349,6 @@ static void SecORVCProcessStapledResponses(SecORVCRef rvc) { } } -// MARK: SecCRVCRef -/******************************************************** - ******************* CRL RVC Functions ****************** - ********************************************************/ -#if ENABLE_CRLS -#include <../trustd/macOS/SecTrustOSXEntryPoints.h> -#define kSecDefaultCRLTTL kSecDefaultOCSPResponseTTL - -/* CRL Revocation verification context. */ -struct OpaqueSecCRVC { - /* Response data from ocspd. Yes, ocspd does CRLs, but not OCSP... */ - async_ocspd_t async_ocspd; - - /* Pointer to the builder for this revocation check. */ - SecPathBuilderRef builder; - - /* Pointer to the generic rvc for this revocation check */ - SecRVCRef rvc; - - /* The current CRL status from ocspd. */ - OSStatus status; - - /* Index of cert in builder that this RVC is for 0 = leaf, etc. */ - CFIndex certIX; - - /* Index in array returned by SecCertificateGetCRLDistributionPoints() for - current distribution point. */ - CFIndex distributionPointIX; - - /* URL of current distribution point. */ - CFURLRef distributionPoint; - - /* Date until which this revocation status is valid. */ - CFAbsoluteTime nextUpdate; - - bool done; -}; - -static void SecCRVCFinish(SecCRVCRef crvc) { - // nothing yet -} - -#define MAX_CRL_DPS 3 -#define CRL_REQUEST_THRESHOLD 10 - -static CFURLRef SecCRVCGetNextDistributionPoint(SecCRVCRef rvc) { - SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); - CFArrayRef crlDPs = SecCertificateGetCRLDistributionPoints(cert); - if (crlDPs) { - CFIndex crlDPCount = CFArrayGetCount(crlDPs); - if (crlDPCount >= CRL_REQUEST_THRESHOLD) { - secnotice("rvc", "too many CRL DP entries (%ld)", (long)crlDPCount); - return NULL; - } - while (rvc->distributionPointIX < crlDPCount && rvc->distributionPointIX < MAX_CRL_DPS) { - CFURLRef distributionPoint = CFArrayGetValueAtIndex(crlDPs, rvc->distributionPointIX); - rvc->distributionPointIX++; - CFStringRef scheme = CFURLCopyScheme(distributionPoint); - if (scheme) { - /* We only support http and https responders currently. */ - bool valid_DP = (CFEqual(CFSTR("http"), scheme) || - CFEqual(CFSTR("https"), scheme) || - CFEqual(CFSTR("ldap"), scheme)); - CFRelease(scheme); - if (valid_DP) - return distributionPoint; - } - } - } - return NULL; -} - -static void SecCRVCGetCRLStatus(SecCRVCRef rvc) { - SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); - SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); - CFArrayRef serializedCertPath = SecCertificatePathVCCreateSerialized(path); - secdebug("rvc", "searching CRL cache for cert: %ld", rvc->certIX); - rvc->status = SecTrustLegacyCRLStatus(cert, serializedCertPath, rvc->distributionPoint); - CFReleaseNull(serializedCertPath); - /* we got a response indicating that the CRL was checked */ - if (rvc->status == errSecSuccess || rvc->status == errSecCertificateRevoked) { - rvc->done = true; - /* ocspd doesn't give us the nextUpdate time, so set to default */ - rvc->nextUpdate = SecPathBuilderGetVerifyTime(rvc->builder) + kSecDefaultCRLTTL; - } -} - -static void SecCRVCCheckRevocationCache(SecCRVCRef rvc) { - while ((rvc->distributionPoint = SecCRVCGetNextDistributionPoint(rvc))) { - SecCRVCGetCRLStatus(rvc); - if (rvc->status == errSecCertificateRevoked) { - return; - } - } -} - -/* Fire off an async http request for this certs revocation status, return - false if request was queued, true if we're done. */ -static bool SecCRVCFetchNext(SecCRVCRef rvc) { - while ((rvc->distributionPoint = SecCRVCGetNextDistributionPoint(rvc))) { - SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); - SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); - CFArrayRef serializedCertPath = SecCertificatePathVCCreateSerialized(path); - secinfo("rvc", "fetching CRL for cert: %ld", rvc->certIX); - if (!SecTrustLegacyCRLFetch(&rvc->async_ocspd, rvc->distributionPoint, - CFAbsoluteTimeGetCurrent(), cert, serializedCertPath)) { - CFDataRef clientAuditToken = NULL; - SecTaskRef task = NULL; - audit_token_t auditToken = {}; - clientAuditToken = SecPathBuilderCopyClientAuditToken(rvc->builder); - require(clientAuditToken, out); - require(sizeof(auditToken) == CFDataGetLength(clientAuditToken), out); - CFDataGetBytes(clientAuditToken, CFRangeMake(0, sizeof(auditToken)), (uint8_t *)&auditToken); - require(task = SecTaskCreateWithAuditToken(NULL, auditToken), out); - secnotice("rvc", "asynchronously fetching CRL (%@) for client (%@)", - rvc->distributionPoint, task); - - out: - CFReleaseNull(clientAuditToken); - CFReleaseNull(task); - /* Async request was posted, wait for reply. */ - return false; - } - } - rvc->done = true; - return true; -} - -static void SecCRVCUpdatePVC(SecCRVCRef rvc) { - if (rvc->status == errSecCertificateRevoked) { - secdebug("rvc", "CRL revoked cert %" PRIdCFIndex, rvc->certIX); - SInt32 reason = 0; // unspecified, since ocspd didn't tell us - CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); - SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, - cfreason, true); - if (rvc->builder) { - CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); - if (info) { - /* make the revocation reason available in the trust result */ - CFDictionarySetValue(info, kSecTrustRevocationReason, cfreason); - } - } - CFReleaseNull(cfreason); - } -} - -static void SecCRVCFetchCompleted(async_ocspd_t *ocspd) { - SecCRVCRef rvc = ocspd->info; - SecPathBuilderRef builder = rvc->builder; - TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); - if (analytics) { - /* Add the time this fetch took to complete to the total time */ - analytics->crl_fetch_time += (mach_absolute_time() - ocspd->start_time); - } - /* we got a response indicating that the CRL was checked */ - if (ocspd->response == errSecSuccess || ocspd->response == errSecCertificateRevoked) { - rvc->status = ocspd->response; - rvc->done = true; - /* ocspd doesn't give us the nextUpdate time, so set to default */ - rvc->nextUpdate = SecPathBuilderGetVerifyTime(rvc->builder) + kSecDefaultCRLTTL; - secdebug("rvc", "got CRL response for cert: %ld", rvc->certIX); - SecCRVCUpdatePVC(rvc); - if (!SecPathBuilderDecrementAsyncJobCount(builder)) { - secdebug("rvc", "done with all async jobs"); - SecPathBuilderStep(builder); - } - } else { - if (analytics) { - /* We didn't get any data back, so the fetch failed */ - analytics->crl_fetch_failed++; - } - if(SecCRVCFetchNext(rvc)) { - if (!SecPathBuilderDecrementAsyncJobCount(builder)) { - secdebug("rvc", "done with all async jobs"); - SecPathBuilderStep(builder); - } - } - } -} - -static SecCRVCRef SecCRVCCreate(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) { - SecCRVCRef crvc = NULL; - crvc = malloc(sizeof(struct OpaqueSecCRVC)); - if (crvc) { - memset(crvc, 0, sizeof(struct OpaqueSecCRVC)); - crvc->builder = builder; - crvc->rvc = rvc; - crvc->certIX = certIX; - crvc->status = errSecInternal; - crvc->distributionPointIX = 0; - crvc->distributionPoint = NULL; - crvc->nextUpdate = NULL_TIME; - crvc->async_ocspd.queue = SecPathBuilderGetQueue(builder); - crvc->async_ocspd.completed = SecCRVCFetchCompleted; - crvc->async_ocspd.response = errSecInternal; - crvc->async_ocspd.info = crvc; - crvc->done = false; - } - return crvc; -} - -static bool SecRVCShouldCheckCRL(SecRVCRef rvc) { - CFStringRef revocation_method = SecPathBuilderGetRevocationMethod(rvc->builder); - TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); - if (revocation_method && - CFEqual(kSecPolicyCheckRevocationCRL, revocation_method)) { - /* Our client insists on CRLs */ - secinfo("rvc", "client told us to check CRL"); - if (analytics) { - analytics->crl_client = true; - } - return true; - } - SecCertificateRef cert = SecPathBuilderGetCertificateAtIndex(rvc->builder, rvc->certIX); - CFArrayRef ocspResponders = SecCertificateGetOCSPResponders(cert); - if ((!ocspResponders || CFArrayGetCount(ocspResponders) == 0) && - (revocation_method && !CFEqual(kSecPolicyCheckRevocationOCSP, revocation_method))) { - /* The cert doesn't have OCSP responders and the client didn't specifically ask for OCSP. - * This logic will skip the CRL cache check if the client didn't ask for revocation checking */ - secinfo("rvc", "client told us to check revocation and CRL is only option for cert: %ld", rvc->certIX); - if (analytics) { - analytics->crl_cert = true; - } - return true; - } - return false; -} -#endif /* ENABLE_CRLS */ - void SecRVCDelete(SecRVCRef rvc) { secdebug("alloc", "delete rvc %p", rvc); if (rvc->orvc) { @@ -585,13 +356,6 @@ void SecRVCDelete(SecRVCRef rvc) { free(rvc->orvc); rvc->orvc = NULL; } -#if ENABLE_CRLS - if (rvc->crvc) { - SecCRVCFinish(rvc->crvc); - free(rvc->crvc); - rvc->crvc = NULL; - } -#endif if (rvc->valid_info) { CFReleaseNull(rvc->valid_info); } @@ -605,14 +369,7 @@ static void SecRVCInit(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) rvc->builder = builder; rvc->certIX = certIX; rvc->orvc = SecORVCCreate(rvc, builder, certIX); -#if ENABLE_CRLS - rvc->crvc = SecCRVCCreate(rvc, builder, certIX); -#endif - if (!rvc->orvc -#if ENABLE_CRLS - || !rvc->crvc -#endif - ) { + if (!rvc->orvc) { SecRVCDelete(rvc); SecRVCSetFinishedWithoutNetwork(rvc); } else { @@ -620,20 +377,125 @@ static void SecRVCInit(SecRVCRef rvc, SecPathBuilderRef builder, CFIndex certIX) } } -#if ENABLE_CRLS static bool SecRVCShouldCheckOCSP(SecRVCRef rvc) { - CFStringRef revocation_method = SecPathBuilderGetRevocationMethod(rvc->builder); - if (!revocation_method - || !CFEqual(revocation_method, kSecPolicyCheckRevocationCRL)) { - return true; + return true; +} + +static bool SecRVCPolicyConstraintsPermitPolicy(SecValidPolicy *constraints, CFIndex count, SecPolicyRef policy) { + if (!constraints || !policy) { + return true; /* nothing to constrain */ + } + SecValidPolicy policyType = kSecValidPolicyAny; + CFStringRef policyName = SecPolicyGetName(policy); + /* determine if the policy is a candidate for being constrained */ + if (CFEqualSafe(policyName, kSecPolicyNameSSLServer) || + CFEqualSafe(policyName, kSecPolicyNameEAPServer) || + CFEqualSafe(policyName, kSecPolicyNameIPSecServer)) { + policyType = kSecValidPolicyServerAuthentication; + } else if (CFEqualSafe(policyName, kSecPolicyNameSSLClient) || + CFEqualSafe(policyName, kSecPolicyNameEAPClient) || + CFEqualSafe(policyName, kSecPolicyNameIPSecClient)) { + policyType = kSecValidPolicyClientAuthentication; + } else if (CFEqualSafe(policyName, kSecPolicyNameSMIME)) { + policyType = kSecValidPolicyEmailProtection; + } else if (CFEqualSafe(policyName, kSecPolicyNameCodeSigning)) { + policyType = kSecValidPolicyCodeSigning; + } else if (CFEqualSafe(policyName, kSecPolicyNameTimeStamping)) { + policyType = kSecValidPolicyTimeStamping; + } + if (policyType == kSecValidPolicyAny) { + return true; /* policy not subject to constraint */ + } + /* policy is subject to constraint; do the constraints allow it? */ + bool result = false; + for (CFIndex ix = 0; ix < count; ix++) { + SecValidPolicy allowedPolicy = constraints[ix]; + if (allowedPolicy == kSecValidPolicyAny || + allowedPolicy == policyType) { + result = true; + break; + } } - return false; + if (!result) { + secnotice("rvc", "%@ not allowed by policy constraints on issuing CA", policyName); + } + return result; } -#else -static bool SecRVCShouldCheckOCSP(SecRVCRef rvc) { - return true; + +static bool SecRVCGetPolicyConstraints(CFDataRef data, SecValidPolicy **constraints, CFIndex *count) { + /* Sanity-check the input policy constraints data, returning pointer and + * count values in output arguments. Function result is true if successful. + * + * The first byte of the policy constraints data contains the number of entries, + * followed by an array of 0..n policy constraint values of type SecValidPolicy. + * The maximum number of defined policies is not expected to approach 127, i.e. + * the largest value which can be expressed in a signed byte. + */ + bool result = false; + CFIndex length = 0; + SecValidPolicy *p = NULL; + if (data) { + length = CFDataGetLength(data); + p = (SecValidPolicy *)CFDataGetBytePtr(data); + } + /* Verify that count is 0 or greater, and equal to remaining number of bytes */ + CFIndex c = (length > 0) ? *p++ : -1; + if (c < 0 || c != (length - 1)) { + secerror("invalid policy constraints array"); + } else { + if (constraints) { + *constraints = p; + } + if (count) { + *count = c; + } + result = true; + } + return result; +} + +static void SecRVCProcessValidPolicyConstraints(SecRVCRef rvc) { + if (!rvc || !rvc->valid_info || !rvc->builder) { + return; + } + if (!rvc->valid_info->hasPolicyConstraints) { + return; + } + CFIndex count = 0; + SecValidPolicy *constraints = NULL; + if (!SecRVCGetPolicyConstraints(rvc->valid_info->policyConstraints, &constraints, &count)) { + return; + } + secdebug("rvc", "found policy constraints for cert at index %ld", rvc->certIX); + + /* check that policies being verified are permitted by the policy constraints */ + bool policyDeniedByConstraints = false; + CFIndex ix, initialPVCCount = SecPathBuilderGetPVCCount(rvc->builder); + for (ix = 0; ix < initialPVCCount; ix++) { + SecPVCRef pvc = SecPathBuilderGetPVCAtIndex(rvc->builder, ix); + CFArrayRef policies = CFRetainSafe(pvc->policies); + CFIndex policyCount = (policies) ? CFArrayGetCount(policies) : 0; + for (CFIndex policyIX = 0; policyIX < policyCount; policyIX++) { + SecPolicyRef policy = (SecPolicyRef)CFArrayGetValueAtIndex(policies, policyIX); + if (!SecRVCPolicyConstraintsPermitPolicy(constraints, count, policy)) { + policyDeniedByConstraints = true; + SecPVCSetResultForced(pvc, kSecPolicyCheckIssuerPolicyConstraints, rvc->certIX, + kCFBooleanFalse, true); + pvc->result = kSecTrustResultRecoverableTrustFailure; + if (!rvc->valid_info->overridable) { + /* error for this check should be non-recoverable */ + pvc->result = kSecTrustResultFatalTrustFailure; + } + } + } + CFReleaseSafe(policies); + } + TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(rvc->builder); + if (analytics) { + TAValidStatus status = (policyDeniedByConstraints) ? TAValidPolicyConstrainedDenied : TAValidPolicyConstrainedOK; + analytics->valid_status |= status; + } } -#endif static void SecRVCProcessValidDateConstraints(SecRVCRef rvc) { if (!rvc || !rvc->valid_info || !rvc->builder) { @@ -671,7 +533,7 @@ static void SecRVCProcessValidDateConstraints(SecRVCRef rvc) { secnotice("rvc", "certificate issuance date not within the allowed range for this CA%s", (rvc->valid_info->overridable) ? "" : " (non-recoverable error)"); if (analytics) { - analytics->valid_status |= TAValidDateContrainedRevoked; + analytics->valid_status |= TAValidDateConstrainedRevoked; } if (rvc->valid_info->overridable) { /* error is recoverable, treat certificate as untrusted @@ -684,10 +546,9 @@ static void SecRVCProcessValidDateConstraints(SecRVCRef rvc) { CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, cfreason, true); - CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); - if (info) { - /* make the revocation reason available in the trust result */ - CFDictionarySetValue(info, kSecTrustRevocationReason, cfreason); + SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); + if (path) { + SecCertificatePathVCSetRevocationReasonForCertificateAtIndex(path, rvc->certIX, cfreason); } CFReleaseNull(cfreason); } @@ -746,10 +607,9 @@ void SecRVCSetValidDeterminedErrorResult(SecRVCRef rvc) { CFNumberRef cfreason = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &reason); SecPathBuilderSetResultInPVCs(rvc->builder, kSecPolicyCheckRevocation, rvc->certIX, cfreason, true); - CFMutableDictionaryRef info = SecPathBuilderGetInfo(rvc->builder); - if (info) { - /* make the revocation reason available in the trust result */ - CFDictionarySetValue(info, kSecTrustRevocationReason, cfreason); + SecCertificatePathVCRef path = SecPathBuilderGetPath(rvc->builder); + if (path) { + SecCertificatePathVCSetRevocationReasonForCertificateAtIndex(path, rvc->certIX, cfreason); } CFReleaseNull(cfreason); } @@ -793,6 +653,9 @@ static void SecRVCProcessValidInfoResults(SecRVCRef rvc) { return; } + /* Handle policy constraints, if present. */ + SecRVCProcessValidPolicyConstraints(rvc); + /* Handle date constraints, if present. * Note: a not-after date may set the CT requirement, * so check requireCT after this function is called. */ @@ -902,29 +765,17 @@ static void SecRVCCheckRevocationCaches(SecRVCRef rvc) { analytics->ocsp_cache_hit = true; } } -#if ENABLE_CRLS - /* Don't check CRL cache if policy requested OCSP only */ - if (SecRVCShouldCheckCRL(rvc)) { - SecCRVCCheckRevocationCache(rvc->crvc); - } -#endif } static void SecRVCUpdatePVC(SecRVCRef rvc) { SecRVCProcessValidInfoResults(rvc); /* restore the results we got from Valid */ if (rvc->orvc) { SecORVCUpdatePVC(rvc->orvc); } -#if ENABLE_CRLS - if (rvc->crvc) { SecCRVCUpdatePVC(rvc->crvc); } -#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) { @@ -944,26 +795,6 @@ static bool SecRVCFetchNext(SecRVCRef rvc) { /* we didn't start an OCSP background job for this cert */ (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); } - -#if ENABLE_CRLS - bool CRL_fetch_finished = true; - /* Don't check CRL cache if policy requested OCSP only */ - if (SecRVCShouldCheckCRL(rvc)) { - /* reset the distributionPointIX because we already iterated through the CRLDPs - * in SecCRVCCheckRevocationCache */ - rvc->crvc->distributionPointIX = 0; - CRL_fetch_finished &= SecCRVCFetchNext(rvc->crvc); - } - if (CRL_fetch_finished) { - /* we didn't start a CRL background job for this cert */ - (void)SecPathBuilderDecrementAsyncJobCount(rvc->builder); - } else if (analytics) { - /* We did a CRL fetch */ - analytics->crl_fetches++; - } - OCSP_fetch_finished &= CRL_fetch_finished; -#endif - return OCSP_fetch_finished; } @@ -1110,14 +941,7 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { and decrement pvc->asyncJobCount for each cert that we don't start a 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)); -#else - /* If we enable CRLS, we may end up with two async jobs per cert: one - * 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 revocation status checking isn't done yet (and we have an issuer!) */ @@ -1130,9 +954,8 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { SecRVCInit(rvc, builder, certIX); - /* RFC 6960: OCSP No-Check extension says that we shouldn't check revocation. */ - if (SecCertificateHasMarkerExtension(SecCertificatePathVCGetCertificateAtIndex(path, certIX), - CFSTR("1.3.6.1.5.5.7.48.1.5"))) // id-pkix-ocsp-nocheck + /* RFC 6960: id-pkix-ocsp-nocheck extension says that we shouldn't check revocation. */ + if (SecCertificateHasOCSPNoCheckMarkerExtension(SecCertificatePathVCGetCertificateAtIndex(path, certIX))) { secdebug("rvc", "skipping revocation checks for no-check cert: %ld", certIX); TrustAnalyticsBuilder *analytics = SecPathBuilderGetAnalyticsData(builder); @@ -1171,17 +994,12 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { * do here. */ SecRVCSetFinishedWithoutNetwork(rvc); continue; -#endif - +#else // !TARGET_OS_BRIDGE /* Then check the caches for revocation results. */ SecRVCCheckRevocationCaches(rvc); /* The check is done if we found cached responses from either method. */ - if (rvc->done || rvc->orvc->done -#if ENABLE_CRLS - || rvc->crvc->done -#endif - ) { + if (rvc->done || rvc->orvc->done) { secdebug("rvc", "found cached response for cert: %ld", certIX); SecRVCSetFinishedWithoutNetwork(rvc); continue; @@ -1203,12 +1021,10 @@ bool SecPathBuilderCheckRevocation(SecPathBuilderRef builder) { SecRVCUpdatePVC(rvc); /* We didn't really start any background jobs for this cert. */ (void)SecPathBuilderDecrementAsyncJobCount(builder); -#if ENABLE_CRLS - (void)SecPathBuilderDecrementAsyncJobCount(builder); -#endif } else { (void)SecRVCFetchNext(rvc); } +#endif // !TARGET_OS_BRIDGE } /* Return false if there are still async jobs running. */ @@ -1222,13 +1038,5 @@ CFAbsoluteTime SecRVCGetEarliestNextUpdate(SecRVCRef rvc) { CFAbsoluteTime enu = NULL_TIME; if (!rvc || !rvc->orvc) { return enu; } enu = rvc->orvc->nextUpdate; -#if ENABLE_CRLS - CFAbsoluteTime crlNextUpdate = rvc->crvc->nextUpdate; - if (enu == NULL_TIME || - ((crlNextUpdate > NULL_TIME) && (enu > crlNextUpdate))) { - /* We didn't check OCSP or CRL next update time was sooner */ - enu = crlNextUpdate; - } -#endif return enu; } diff --git a/OSX/sec/securityd/SecRevocationServer.h b/OSX/sec/securityd/SecRevocationServer.h index 7f42f736..d6400167 100644 --- a/OSX/sec/securityd/SecRevocationServer.h +++ b/OSX/sec/securityd/SecRevocationServer.h @@ -36,9 +36,6 @@ #include typedef struct OpaqueSecORVC *SecORVCRef; -#if ENABLE_CRLS -typedef struct OpaqueSecCRVC *SecCRVCRef; -#endif /* Revocation verification context. */ struct OpaqueSecRVC { @@ -51,10 +48,6 @@ struct OpaqueSecRVC { /* The OCSP Revocation verification context */ SecORVCRef orvc; -#if ENABLE_CRLS - SecCRVCRef crvc; -#endif - /* Valid database info for this revocation check */ SecValidInfoRef valid_info; diff --git a/OSX/sec/securityd/SecTrustExceptionResetCount.h b/OSX/sec/securityd/SecTrustExceptionResetCount.h new file mode 100644 index 00000000..c9cd2dbb --- /dev/null +++ b/OSX/sec/securityd/SecTrustExceptionResetCount.h @@ -0,0 +1,14 @@ +// +// SecTrustExceptionResetCount.h +// Security +// + +#ifndef SecTrustExceptionResetCount_h +#define SecTrustExceptionResetCount_h + +#include + +bool SecTrustServerIncrementExceptionResetCount(CFErrorRef *error); +uint64_t SecTrustServerGetExceptionResetCount(CFErrorRef *error); + +#endif /* SecTrustExceptionResetCount_h */ diff --git a/OSX/sec/securityd/SecTrustExceptionResetCount.m b/OSX/sec/securityd/SecTrustExceptionResetCount.m new file mode 100644 index 00000000..4552f3ce --- /dev/null +++ b/OSX/sec/securityd/SecTrustExceptionResetCount.m @@ -0,0 +1,194 @@ +// +// SecTrustExceptionResetCount.m +// Security_ios +// + +#import +#import "SecTrustExceptionResetCount.h" + +#import +#import + +static NSString *kExceptionResetCountKey = @"ExceptionResetCount"; +static NSString *exceptionResetCounterFile = @"com.apple.security.exception_reset_counter.plist"; + +/* Returns the path to the, existing or internally-created, 'exceptionResetCounterFile' file. */ +static NSString *SecPlistFileExistsInKeychainDirectory(CFErrorRef *error) { + NSString *status = NULL; + + NSString *path = [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)exceptionResetCounterFile) path]; + if (!path) { + secerror("Unable to address permanent storage for '%{public}@'.", exceptionResetCounterFile); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, ENOENT, NULL); + } + return status; + } + secinfo("trust", "'%{public}@' is at '%{public}@'.", exceptionResetCounterFile, path); + + NSFileManager *fm = [NSFileManager defaultManager]; + if (!fm) { + secerror("Failed to initialize the file manager in '%{public}s'.", __func__); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, ENOMEM, NULL); + } + return status; + } + + BOOL isDir = false; + bool fileExists = [fm fileExistsAtPath:path isDirectory:&isDir]; + if (isDir) { + secerror("'%{public}@' is a directory. (not a file)", path); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, EISDIR, NULL); + } + return status; + } + if (fileExists) { + secdebug("trust", "'%{public}@' already exists.", path); + status = path; + return status; + } + + if (![fm createFileAtPath:path contents:nil attributes:nil]) { + secerror("Failed to create permanent storage at '%{public}@'.", path); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, EIO, NULL); + } + return status; + } + secinfo("trust", "'%{public}@' has been created.", path); + status = path; + + return status; +} + +static uint64_t SecReadPlistFromFileInKeychainDirectory(CFErrorRef *error) { + uint64_t value = 0; + + CFErrorRef localError = NULL; + NSString *path = SecPlistFileExistsInKeychainDirectory(&localError); + if (localError) { + if (error) { + *error = localError; + } + secerror("Permanent storage for the exceptions epoch is unavailable."); + return value; + } + if (!path) { + secinfo("trust", "Permanent storage for the exceptions epoch is missing. Defaulting to value %llu.", value); + return value; + } + + NSMutableDictionary *plDict = [NSMutableDictionary dictionaryWithContentsOfFile:path]; + if (!plDict) { + secerror("Failed to read from permanent storage at '%{public}@' or the data is bad. Defaulting to value %llu.", path, value); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, ENXIO, NULL); + } + return value; + } + + id valueObject = [plDict objectForKey:kExceptionResetCountKey]; + if (!valueObject) { + secinfo("trust", "Could not find key '%{public}@'. Defaulting to value %llu.", kExceptionResetCountKey, value); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, ENXIO, NULL); + } + return value; + } + if (![valueObject isKindOfClass:[NSNumber class]]) { + secerror("The value for key '%{public}@' is not a number.", kExceptionResetCountKey); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, EDOM, NULL); + } + return value; + } + + value = [valueObject unsignedIntValue]; + + secinfo("trust", "'%{public}@' is %llu.", kExceptionResetCountKey, value); + return value; +} + +static bool SecWritePlistToFileInKeychainDirectory(uint64_t exceptionResetCount, CFErrorRef *error) { + bool status = false; + + CFErrorRef localError = NULL; + SecPlistFileExistsInKeychainDirectory(&localError); + if (localError) { + if (error) { + *error = localError; + } + secerror("Permanent storage for the exceptions epoch is unavailable."); + return status; + } + + NSString *path = [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)exceptionResetCounterFile) path]; + if (!path) { + secerror("Unable to address permanent storage for '%{public}@'.", exceptionResetCounterFile); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, EIO, NULL); + } + return status; + } + + NSMutableDictionary *dataToSave = [NSMutableDictionary new]; + if (!dataToSave) { + secerror("Failed to allocate memory for the exceptions epoch structure."); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, ENOMEM, NULL); + } + return status; + } + dataToSave[@"Version"] = [NSNumber numberWithUnsignedInteger:1]; + dataToSave[kExceptionResetCountKey] = [NSNumber numberWithUnsignedInteger:exceptionResetCount]; + + status = [dataToSave writeToFile:path atomically:YES]; + if (!status) { + secerror("Failed to write to permanent storage at '%{public}@'.", path); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, EIO, NULL); + } + return status; + } + + secinfo("trust", "'%{public}@' has been committed to permanent storage at '%{public}@'.", kExceptionResetCountKey, path); + return status; +} + +uint64_t SecTrustServerGetExceptionResetCount(CFErrorRef *error) { + CFErrorRef localError = NULL; + uint64_t exceptionResetCount = SecReadPlistFromFileInKeychainDirectory(&localError); + /* Treat ENXIO as a transient error; I/O seems to be working but we have failed to read the current epoch. + * That's expected when epoch is still 0 and there is nothing to store in permanent storage. (and later read) + */ + if (localError && CFEqualSafe(CFErrorGetDomain(localError), kCFErrorDomainPOSIX) && CFErrorGetCode(localError) == ENXIO) { + CFRelease(localError); + localError = NULL; + } + if (error && localError) { + *error = localError; + } + secinfo("trust", "exceptionResetCount: %llu (%s)", exceptionResetCount, error ? (*error ? "Error" : "OK") : "N/A"); + return exceptionResetCount; +} + +bool SecTrustServerIncrementExceptionResetCount(CFErrorRef *error) { + bool status = false; + + uint64_t currentExceptionResetCount = SecTrustServerGetExceptionResetCount(error); + if (error && *error) { + secerror("Failed to increment the extensions epoch."); + return status; + } + if (currentExceptionResetCount >= INT64_MAX) { + secerror("Current exceptions epoch value is too large. (%llu) Won't increment.", currentExceptionResetCount); + if (error) { + *error = CFErrorCreate(NULL, kCFErrorDomainPOSIX, ERANGE, NULL); + } + return status; + } + + return SecWritePlistToFileInKeychainDirectory(currentExceptionResetCount + 1, error); +} diff --git a/OSX/sec/securityd/SecTrustServer.c b/OSX/sec/securityd/SecTrustServer.c index b34972eb..476fc887 100644 --- a/OSX/sec/securityd/SecTrustServer.c +++ b/OSX/sec/securityd/SecTrustServer.c @@ -101,7 +101,7 @@ struct SecPathBuilder { CFMutableArrayRef parentSources; CFArrayRef ocspResponses; // Stapled OCSP responses CFArrayRef signedCertificateTimestamps; // Stapled SCTs - CFArrayRef trustedLogs; // Trusted CT logs + CFDictionaryRef trustedLogs; // Trusted CT logs CFAbsoluteTime verifyTime; CFArrayRef exceptions; @@ -162,7 +162,7 @@ static bool SecPathBuilderIsAnchor(SecPathBuilderRef builder, SecCertificateRef certificate, SecCertificateSourceRef *foundInSource); static void SecPathBuilderSetPath(SecPathBuilderRef builder, SecCertificatePathVCRef path); -static void SecPathBuilderInit(SecPathBuilderRef builder, +static void SecPathBuilderInit(SecPathBuilderRef builder, dispatch_queue_t builderQueue, CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef ocspResponses, @@ -178,26 +178,13 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, builder->clientAuditToken = (CFDataRef) ((clientAuditToken) ? CFRetain(clientAuditToken) : NULL); - /* 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); + if (!builderQueue) { + /* make our own queue if caller fails to provide one */ + builder->queue = dispatch_queue_create("com.apple.trustd.evaluation.builder", DISPATCH_QUEUE_SERIAL); } else { - builderQueue = workloop; dispatch_retain_safe(builderQueue); + builder->queue = builderQueue; } - builder->queue = builderQueue; builder->nextParentSource = 1; #if !TARGET_OS_WATCH @@ -277,20 +264,22 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, ** Apple's anchors cannot be overriden by a trust setting. **/ #if !TARGET_OS_BRIDGE - if (builder->anchorSource) { - CFArrayAppendValue(builder->anchorSources, builder->anchorSource); - } + if (builder->anchorSource) { + CFArrayAppendValue(builder->anchorSources, builder->anchorSource); + } if (!anchorsOnly) { /* Only add the system and user anchor certificate db to the anchorSources if we are supposed to trust them. */ CFArrayAppendValue(builder->anchorSources, builder->appleAnchorSource); - #if TARGET_OS_IPHONE - CFArrayAppendValue(builder->anchorSources, kSecUserAnchorSource); - #else /* TARGET_OS_OSX */ - if (keychainsAllowed && kSecLegacyAnchorSource->contains && kSecLegacyAnchorSource->copyParents) { - CFArrayAppendValue(builder->anchorSources, kSecLegacyAnchorSource); + if (keychainsAllowed) { +#if TARGET_OS_IPHONE + CFArrayAppendValue(builder->anchorSources, kSecUserAnchorSource); +#else /* TARGET_OS_OSX */ + if (kSecLegacyAnchorSource->contains && kSecLegacyAnchorSource->copyParents) { + CFArrayAppendValue(builder->anchorSources, kSecLegacyAnchorSource); + } +#endif } - #endif CFArrayAppendValue(builder->anchorSources, kSecSystemAnchorSource); } #else /* TARGET_OS_BRIDGE */ @@ -307,7 +296,7 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, builder->signedCertificateTimestamps = CFRetainSafe(signedCertificateTimestamps); if(trustedLogs) { - builder->trustedLogs = CFRetainSafe(trustedLogs); + builder->trustedLogs = SecOTAPKICreateTrustedCTLogsDictionaryFromArray(trustedLogs); } /* Now let's get the leaf cert and turn it into a path. */ @@ -328,7 +317,7 @@ static void SecPathBuilderInit(SecPathBuilderRef builder, builder->context = context; } -SecPathBuilderRef SecPathBuilderCreate(CFDataRef clientAuditToken, +SecPathBuilderRef SecPathBuilderCreate(dispatch_queue_t builderQueue, CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef ocspResponses, CFArrayRef signedCertificateTimestamps, CFArrayRef trustedLogs, @@ -336,7 +325,7 @@ SecPathBuilderRef SecPathBuilderCreate(CFDataRef clientAuditToken, SecPathBuilderCompleted completed, const void *context) { SecPathBuilderRef builder = malloc(sizeof(*builder)); memset(builder, 0, sizeof(*builder)); - SecPathBuilderInit(builder, clientAuditToken, certificates, + SecPathBuilderInit(builder, builderQueue, clientAuditToken, certificates, anchors, anchorsOnly, keychainsAllowed, policies, ocspResponses, signedCertificateTimestamps, trustedLogs, verifyTime, accessGroups, exceptions, completed, context); @@ -459,7 +448,7 @@ CFArrayRef SecPathBuilderCopySignedCertificateTimestamps(SecPathBuilderRef build return CFRetainSafe(builder->signedCertificateTimestamps); } -CFArrayRef SecPathBuilderCopyTrustedLogs(SecPathBuilderRef builder) +CFDictionaryRef SecPathBuilderCopyTrustedLogs(SecPathBuilderRef builder) { return CFRetainSafe(builder->trustedLogs); } @@ -617,53 +606,18 @@ SecPVCRef SecPathBuilderGetResultPVC(SecPathBuilderRef builder) { /* This function assumes that the input source is an anchor source */ static bool SecPathBuilderIsAnchorPerConstraints(SecPathBuilderRef builder, SecCertificateSourceRef source, SecCertificateRef certificate) { - __block bool result = false; - CFArrayRef constraints = NULL; - constraints = SecCertificateSourceCopyUsageConstraints(source, certificate); - - /* Unrestricted certificates: - * -those that come from anchor sources with no constraints - * -self-signed certificates with empty contraints arrays - */ - Boolean selfSigned = false; - require(errSecSuccess == SecCertificateIsSelfSigned(certificate, &selfSigned), out); - if ((NULL == source->copyUsageConstraints) || - (constraints && (CFArrayGetCount(constraints) == 0) && selfSigned)) { - secinfo("trust", "unrestricted anchor%s", - (NULL == source->copyUsageConstraints) ? " source" : ""); - result = true; - goto out; - } /* Get the trust settings result for the PVCs. Only one PVC need match to * trigger the anchor behavior -- policy validation will handle whether the * path is truly anchored for that PVC. */ - require(constraints, out); + __block bool result = false; SecPathBuilderForEachPVC(builder, ^(SecPVCRef pvc, bool * __unused stop) { - SecTrustSettingsResult settingsResult = kSecTrustSettingsResultInvalid; - settingsResult = SecPVCGetTrustSettingsResult(pvc, - certificate, - constraints); - if ((selfSigned && settingsResult == kSecTrustSettingsResultTrustRoot) || - (!selfSigned && settingsResult == kSecTrustSettingsResultTrustAsRoot)) { - // For our purposes, this is an anchor. - secinfo("trust", "complex trust settings anchor"); - result = true; - *stop = true; - } - - if (settingsResult == kSecTrustSettingsResultDeny) { - /* We consider denied certs "anchors" because the trust decision - is set regardless of building the chain further. The policy - validation will handle rejecting this chain. */ - secinfo("trust", "complex trust settings denied anchor"); + if (SecPVCIsAnchorPerConstraints(pvc, source, certificate)) { result = true; *stop = true; } }); -out: - CFReleaseNull(constraints); return result; } @@ -726,7 +680,7 @@ static bool SecPathBuilderIsPartial(SecPathBuilderRef builder, } if (vstatus == kSecPathVerifySuccess) { - /* The signature chain verified sucessfully, now let's find + /* The signature chain verified successfully, now let's find out if we have an anchor for path. */ if (SecCertificatePathVCIsAnchored(path)) { secdebug("trust", "Adding candidate %@", path); @@ -1257,6 +1211,14 @@ static bool SecPathBuilderReportResult(SecPathBuilderRef builder) { } } + /* If revoked, set the revocation reason */ + if (builder->info && !SecPathBuilderIsOkResult(builder) && SecCertificatePathVCIsRevocationDone(builder->bestPath) + && SecCertificatePathVCGetRevocationReason(builder->bestPath)) { + CFNumberRef reason = SecCertificatePathVCGetRevocationReason(builder->bestPath); + CFDictionarySetValue(builder->info, kSecTrustRevocationReason, reason); + } + + /* Set CT marker in the info */ if (builder->info && SecCertificatePathVCIsCT(builder->bestPath) && SecPathBuilderIsOkResult(builder)) { CFDictionarySetValue(builder->info, kSecTrustInfoCertificateTransparencyKey, kCFBooleanTrue); @@ -1376,7 +1338,7 @@ SecTrustServerEvaluateCompleted(const void *userData, } void -SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error)) { +SecTrustServerEvaluateBlock(dispatch_queue_t builderQueue, CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error)) { /* We need an array containing at least one certificate to proceed. */ if (!isArray(certificates) || !(CFArrayGetCount(certificates) > 0)) { CFErrorRef certError = CFErrorCreate(NULL, kCFErrorDomainOSStatus, errSecInvalidCertificate, NULL); @@ -1386,13 +1348,13 @@ SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, } SecTrustServerEvaluationCompleted userData = Block_copy(evaluated); /* Call the actual evaluator function. */ - SecPathBuilderRef builder = SecPathBuilderCreate(clientAuditToken, + SecPathBuilderRef builder = SecPathBuilderCreate(builderQueue, clientAuditToken, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, SCTs, trustedLogs, verifyTime, accessGroups, exceptions, SecTrustServerEvaluateCompleted, userData); - dispatch_async(builder->queue, ^{ SecPathBuilderStep(builder); }); + SecPathBuilderStep(builder); } @@ -1400,31 +1362,41 @@ SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, CFArrayRef *pdetails, CFDictionaryRef *pinfo, CFArrayRef *pchain, CFErrorRef *perror) { dispatch_semaphore_t done = dispatch_semaphore_create(0); __block SecTrustResultType result = kSecTrustResultInvalid; - SecTrustServerEvaluateBlock(NULL, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, SCTs, trustedLogs, verifyTime, accessGroups, exceptions, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error) { - result = tr; - if (tr == kSecTrustResultInvalid) { - if (perror) { - *perror = error; - CFRetainSafe(error); - } - } else { - if (pdetails) { - *pdetails = details; - CFRetainSafe(details); - } - if (pinfo) { - *pinfo = info; - CFRetainSafe(info); - } - if (pchain) { - *pchain = chain; - CFRetainSafe(chain); + __block dispatch_queue_t queue = dispatch_queue_create("com.apple.trustd.evaluation.recursive", DISPATCH_QUEUE_SERIAL); + + /* We need to use the async call with the semaphore here instead of a synchronous call because we may return from + * SecPathBuilderStep while waiting for an asynchronous network call in order to complete the evaluation. That return + * is necessary in the XPC interface in order to free up the workloop for other trust evaluations while we wait for + * the networking to complete, but here, we need to make sure we wait for the network call (which will async back + * onto our queue) to complete and signal us before we return to the "inline" caller. */ + dispatch_async(queue, ^{ + SecTrustServerEvaluateBlock(queue, NULL, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, SCTs, trustedLogs, verifyTime, accessGroups, exceptions, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error) { + result = tr; + if (tr == kSecTrustResultInvalid) { + if (perror) { + *perror = error; + CFRetainSafe(error); + } + } else { + if (pdetails) { + *pdetails = details; + CFRetainSafe(details); + } + if (pinfo) { + *pinfo = info; + CFRetainSafe(info); + } + if (pchain) { + *pchain = chain; + CFRetainSafe(chain); + } } - } - dispatch_semaphore_signal(done); + dispatch_semaphore_signal(done); + }); }); dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER); dispatch_release(done); + dispatch_release_null(queue); return result; } diff --git a/OSX/sec/securityd/SecTrustServer.h b/OSX/sec/securityd/SecTrustServer.h index 4e95664b..02983bae 100644 --- a/OSX/sec/securityd/SecTrustServer.h +++ b/OSX/sec/securityd/SecTrustServer.h @@ -32,16 +32,12 @@ #include #include /* For errSecWaitForCallback. */ -#include -#include +#include "securityd/SecCertificateServer.h" +#include "securityd/SecCertificateSource.h" #include __BEGIN_DECLS -/* CRLs only implemented for macOS for legacy compatibility purposes using - * ocspd's (legacy) interfaces */ -#define ENABLE_CRLS TARGET_OS_OSX - typedef struct SecPathBuilder *SecPathBuilderRef; typedef struct OpaqueSecPVC *SecPVCRef; @@ -66,7 +62,7 @@ typedef void(*SecPathBuilderCompleted)(const void *userData, SecTrustResultType result); /* Returns a new trust path builder and policy evaluation engine instance. */ -SecPathBuilderRef SecPathBuilderCreate(CFDataRef clientAuditToken, +SecPathBuilderRef SecPathBuilderCreate(dispatch_queue_t builderQueue, CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef ocspResponse, CFArrayRef signedCertificateTimestamps, CFArrayRef trustedLogs, @@ -83,7 +79,7 @@ void SecPathBuilderSetCanAccessNetwork(SecPathBuilderRef builder, bool allow); /* Get the stapled SCTs */ CFArrayRef SecPathBuilderCopySignedCertificateTimestamps(SecPathBuilderRef builder); CFArrayRef SecPathBuilderCopyOCSPResponses(SecPathBuilderRef builder); -CFArrayRef SecPathBuilderCopyTrustedLogs(SecPathBuilderRef builder); +CFDictionaryRef SecPathBuilderCopyTrustedLogs(SecPathBuilderRef builder); CFSetRef SecPathBuilderGetAllPaths(SecPathBuilderRef builder); SecCertificatePathVCRef SecPathBuilderGetPath(SecPathBuilderRef builder); @@ -144,7 +140,7 @@ dispatch_queue_t SecPathBuilderGetQueue(SecPathBuilderRef builder); CFDataRef SecPathBuilderCopyClientAuditToken(SecPathBuilderRef builder); /* Evaluate trust and call evaluated when done. */ -void SecTrustServerEvaluateBlock(CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error)); +void SecTrustServerEvaluateBlock(dispatch_queue_t builderQueue, CFDataRef clientAuditToken, CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, bool keychainsAllowed, CFArrayRef policies, CFArrayRef responses, CFArrayRef SCTs, CFArrayRef trustedLogs, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef exceptions, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef error)); /* Synchronously invoke SecTrustServerEvaluateBlock. */ SecTrustResultType SecTrustServerEvaluate(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, CFErrorRef *error); @@ -171,12 +167,14 @@ typedef CF_ENUM(uint8_t, TA_CTFailureReason) { }; typedef CF_OPTIONS(uint8_t, TAValidStatus) { - TAValidDefinitelyOK = 1 << 0, - TAValidProbablyOK = 1 << 1, - TAValidProbablyRevoked = 1 << 2, - TAValidDefinitelyRevoked = 1 << 3, - TAValidDateConstrainedOK = 1 << 4, - TAValidDateContrainedRevoked = 1 << 5, + TAValidDefinitelyOK = 1 << 0, + TAValidProbablyOK = 1 << 1, + TAValidProbablyRevoked = 1 << 2, + TAValidDefinitelyRevoked = 1 << 3, + TAValidDateConstrainedOK = 1 << 4, + TAValidDateConstrainedRevoked = 1 << 5, + TAValidPolicyConstrainedOK = 1 << 6, + TAValidPolicyConstrainedDenied = 1 << 7, }; typedef struct { @@ -203,14 +201,6 @@ typedef struct { uint64_t ocsp_fetch_time; uint32_t ocsp_fetch_failed; bool ocsp_validation_failed; -#if ENABLE_CRLS - // CRLs - bool crl_client; - bool crl_cert; - uint32_t crl_fetches; - uint64_t crl_fetch_time; - uint32_t crl_fetch_failed; -#endif // Valid TAValidStatus valid_status; bool valid_trigger_ocsp; diff --git a/OSX/sec/securityd/SecTrustStoreServer.c b/OSX/sec/securityd/SecTrustStoreServer.c index 587dd6c9..aaa6bf0b 100644 --- a/OSX/sec/securityd/SecTrustStoreServer.c +++ b/OSX/sec/securityd/SecTrustStoreServer.c @@ -43,7 +43,7 @@ #include #include #include -#include "SecBasePriv.h" +#include #include #include #include diff --git a/OSX/sec/securityd/SecTrustStoreServer.h b/OSX/sec/securityd/SecTrustStoreServer.h index eb918965..41444de1 100644 --- a/OSX/sec/securityd/SecTrustStoreServer.h +++ b/OSX/sec/securityd/SecTrustStoreServer.h @@ -29,7 +29,7 @@ #ifndef _SECURITY_SECTRUSTSTORESERVER_H_ #define _SECURITY_SECTRUSTSTORESERVER_H_ -#include +#include "Security/SecTrustStore.h" #include #include diff --git a/OSX/sec/securityd/SecTrustStoreServer.m b/OSX/sec/securityd/SecTrustStoreServer.m index 27d1ce6c..acb0fb48 100644 --- a/OSX/sec/securityd/SecTrustStoreServer.m +++ b/OSX/sec/securityd/SecTrustStoreServer.m @@ -114,23 +114,31 @@ static bool checkInputExceptionsAndSetAppExceptions(NSDictionary *inExceptions, static _Atomic bool gHasCTExceptions = false; #define kSecCTExceptionsChanged "com.apple.trustd.ct.exceptions-changed" +static NSURL *CTExceptionsFileURL() { + return CFBridgingRelease(SecCopyURLForFileInSystemKeychainDirectory(CFSTR("CTExceptions.plist"))); +} + +static NSDictionary *readExceptionsFromDisk(NSError **error) { + secdebug("ct", "reading CT exceptions from disk"); + NSDictionary *allExceptions = [NSDictionary dictionaryWithContentsOfURL:CTExceptionsFileURL() + error:error]; + return allExceptions; +} + bool _SecTrustStoreSetCTExceptions(CFStringRef appID, CFDictionaryRef exceptions, CFErrorRef *error) { if (!SecOTAPKIIsSystemTrustd()) { + secerror("Unable to write CT exceptions from user agent"); return SecError(errSecWrPerm, error, CFSTR("Unable to write CT exceptions from user agent")); } if (!appID) { + secerror("application-identifier required to set exceptions"); return SecError(errSecParam, error, CFSTR("application-identifier required to set exceptions")); } @autoreleasepool { -#if TARGET_OS_IPHONE - NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); -#else - NSURL *keychainsDirectory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; -#endif - NSURL *ctExceptionsFile = [keychainsDirectory URLByAppendingPathComponent:@"CTExceptions.plist"]; - NSMutableDictionary *allExceptions = [NSMutableDictionary dictionaryWithContentsOfURL:ctExceptionsFile]; + NSError *nserror = nil; + NSMutableDictionary *allExceptions = [readExceptionsFromDisk(&nserror) mutableCopy]; NSMutableDictionary *appExceptions = NULL; if (allExceptions && allExceptions[(__bridge NSString*)appID]) { appExceptions = [allExceptions[(__bridge NSString*)appID] mutableCopy]; @@ -144,6 +152,7 @@ bool _SecTrustStoreSetCTExceptions(CFStringRef appID, CFDictionaryRef exceptions if (exceptions && (CFDictionaryGetCount(exceptions) > 0)) { NSDictionary *inExceptions = (__bridge NSDictionary*)exceptions; if (!checkInputExceptionsAndSetAppExceptions(inExceptions, appExceptions, error)) { + secerror("input exceptions have error: %@", error ? *error : nil); return false; } } @@ -154,11 +163,14 @@ bool _SecTrustStoreSetCTExceptions(CFStringRef appID, CFDictionaryRef exceptions allExceptions[(__bridge NSString*)appID] = appExceptions; } - NSError *nserror = nil; - if (![allExceptions writeToURL:ctExceptionsFile error:&nserror] && error) { - *error = CFRetainSafe((__bridge CFErrorRef)nserror); + if (![allExceptions writeToURL:CTExceptionsFileURL() error:&nserror]) { + secerror("failed to write CT exceptions: %@", nserror); + if (error) { + *error = CFRetainSafe((__bridge CFErrorRef)nserror); + } return false; } + secnotice("ct", "wrote %lu CT exceptions", (unsigned long)[allExceptions count]); atomic_store(&gHasCTExceptions, [allExceptions count] != 0); notify_post(kSecCTExceptionsChanged); return true; @@ -167,33 +179,23 @@ bool _SecTrustStoreSetCTExceptions(CFStringRef appID, CFDictionaryRef exceptions CFDictionaryRef _SecTrustStoreCopyCTExceptions(CFStringRef appID, CFErrorRef *error) { @autoreleasepool { + /* Set us up for not reading the disk when there are never exceptions */ static int notify_token = 0; int check = 0; - if (!SecOTAPKIIsSystemTrustd()) { - /* Check whether we got a notification. If we didn't, and there are no exceptions set, return NULL. - * Otherwise, we need to read from disk */ - uint32_t check_status = notify_check(notify_token, &check); - if (check_status == NOTIFY_STATUS_OK && check == 0 && !atomic_load(&gHasCTExceptions)) { - return NULL; - } - } else { - if (!atomic_load(&gHasCTExceptions)) { - return NULL; - } - } - -#if TARGET_OS_IPHONE - NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); -#else - NSURL *keychainsDirectory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; -#endif - NSURL *ctExceptionsFile = [keychainsDirectory URLByAppendingPathComponent:@"CTExceptions.plist"]; - NSDictionary *allExceptions = [NSDictionary dictionaryWithContentsOfURL:ctExceptionsFile]; - - /* Set us up for not reading the disk when there are never exceptions */ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - atomic_init(&gHasCTExceptions, allExceptions && [allExceptions count] == 0); + /* initialize gHashCTExceptions cache */ + NSError *read_error = nil; + NSDictionary *allExceptions = readExceptionsFromDisk(&read_error); + if (!allExceptions || [allExceptions count] == 0) { + secnotice("ct", "skipping further reads. no CT exceptions found: %@", read_error); + atomic_store(&gHasCTExceptions, false); + } else { + secnotice("ct", "have CT exceptions. will need to read."); + atomic_store(&gHasCTExceptions, true); + } + + /* read-only trustds register for notfications from the read-write trustd */ if (!SecOTAPKIIsSystemTrustd()) { uint32_t status = notify_register_check(kSecCTExceptionsChanged, ¬ify_token); if (status == NOTIFY_STATUS_OK) { @@ -207,7 +209,23 @@ CFDictionaryRef _SecTrustStoreCopyCTExceptions(CFStringRef appID, CFErrorRef *er } }); + /* Read the negative cached value as to whether there are any exceptions to read */ + if (!SecOTAPKIIsSystemTrustd()) { + /* Check whether we got a notification. If we didn't, and there are no exceptions set, return NULL. + * Otherwise, we need to read from disk */ + uint32_t check_status = notify_check(notify_token, &check); + if (check_status == NOTIFY_STATUS_OK && check == 0 && !atomic_load(&gHasCTExceptions)) { + return NULL; + } + } else if (!atomic_load(&gHasCTExceptions)) { + return NULL; + } + + /* We need to read the exceptions from disk */ + NSError *read_error = nil; + NSDictionary *allExceptions = readExceptionsFromDisk(&read_error); if (!allExceptions || [allExceptions count] == 0) { + secnotice("ct", "skipping further reads. no CT exceptions found: %@", read_error); atomic_store(&gHasCTExceptions, false); return NULL; } @@ -241,6 +259,7 @@ CFDictionaryRef _SecTrustStoreCopyCTExceptions(CFStringRef appID, CFErrorRef *er exceptions[(__bridge NSString*)kSecCTExceptionsCAsKey] = caExceptions; } if ([exceptions count] > 0) { + secdebug("ct", "found %lu CT exceptions on disk", (unsigned long)[exceptions count]); atomic_store(&gHasCTExceptions, true); return CFBridgingRetain(exceptions); } diff --git a/OSX/sec/securityd/com.apple.secd.sb b/OSX/sec/securityd/com.apple.secd.sb index f6a02c3a..fd9e6476 100644 --- a/OSX/sec/securityd/com.apple.secd.sb +++ b/OSX/sec/securityd/com.apple.secd.sb @@ -9,6 +9,10 @@ (regex #"^/private/var/folders/[^/]+/[^/]+/T(/|$)") (regex (string-append "^" (regex-quote (param "_HOME")) #"/Library/Keychains(/|$)"))) +(allow file-read* + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.imessage.bag.plist")) + (literal (string-append (param "_HOME") "/Library/Preferences/com.apple.facetime.bag.plist"))) + ;;;;;; will be fully fixed in 29465717 (allow file-read* (subpath "/")) @@ -17,6 +21,20 @@ (preference-domain ".GlobalPreferences")) (allow user-preference-read (preference-domain "com.apple.security")) +(allow user-preference-read + (preference-domain "com.apple.imessage.bag")) +(allow user-preference-read + (preference-domain "com.apple.facetime.bag")) +(allow user-preference-read user-preference-write + (preference-domain "com.apple.security.sosaccount")) + +(allow distributed-notification-post) + +(allow iokit-open + (iokit-user-client-class "AppleKeyStoreUserClient") + (iokit-user-client-class "AppleAPFSUserClient") + (iokit-user-client-class "RootDomainUserClient")) + (allow file-read* (literal "/usr/libexec/secd") @@ -25,26 +43,29 @@ (literal "/AppleInternal") (literal "/usr/libexec")) - (allow mach-lookup (global-name "com.apple.system.opendirectoryd.api") (global-name "com.apple.SystemConfiguration.configd") (global-name "com.apple.security.cloudkeychainproxy3") (global-name "com.apple.accountsd.accountmanager") + (global-name "com.apple.CoreServices.coreservicesd") + (global-name "com.apple.distributed_notifications@Uv3") (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.analyticsd") (global-name "com.apple.ak.anisette.xpc") - (global-name "com.apple.windowserver.active")) + (global-name "com.apple.corefollowup.agent") + (global-name "com.apple.windowserver.active") + (global-name "com.apple.powerlog.plxpclogger.xpc") + (global-name "com.apple.SecureBackupDaemon") +) ;; Used to send logs for MoiC. (allow mach-lookup (global-name "com.apple.imagent.desktop.auth")) -(allow iokit-open - (iokit-user-client-class "AppleKeyStoreUserClient")) - (allow iokit-get-properties (iokit-registry-entry-class "IOPlatformExpertDevice")) (allow ipc-posix-shm @@ -52,3 +73,14 @@ (allow network-outbound) (allow system-socket) + +;; to be deleted once SecTrustEvaluate and SecTrustCopyKey can avoid touching legacy cert and keychain stack +(allow file-read* file-write* + (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds/mdsDirectory\.db$") + (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds/mdsObject\.db$") + (regex #"^/private/var/folders/[^/]+/[^/]+/C/mds/mds\.lock$")) +(allow mach-lookup + (global-name "com.apple.SecurityServer")) + +(allow system-fsctl (fsctl-command afpfsByteRangeLock2FSCTL)) + diff --git a/OSX/sec/securityd/entitlements.plist b/OSX/sec/securityd/entitlements.plist index 2b813b22..5f8eecff 100644 --- a/OSX/sec/securityd/entitlements.plist +++ b/OSX/sec/securityd/entitlements.plist @@ -2,12 +2,16 @@ + com.apple.private.dark-wake-push + com.apple.private.accounts.allaccounts com.apple.private.aps-connection-initiate aps-connection-initiate + com.apple.developer.aps-environment + serverPreferred aps-environment serverPreferred com.apple.aps-environment @@ -28,6 +32,10 @@ com.apple.private.cloudkit.buddyAccess + com.apple.private.cloudkit.allowUnverifiedAccount + + com.apple.private.cloudkit.supportservice + com.apple.private.appleaccount.app-hidden-from-icloud-settings com.apple.private.tcc.allow @@ -68,5 +76,19 @@ com.apple.authkit.client.private + com.apple.private.trustedpeershelper.client + + com.apple.private.imcore.imremoteurlconnection + + com.apple.private.ids.remoteurlconnection + + com.apple.private.imcore.remoteurlconnection + + com.apple.securebackupd.access + + com.apple.CloudKeychainProxy.client + + com.apple.security.network.client + diff --git a/OSX/sec/securityd/iCloudTrace.c b/OSX/sec/securityd/iCloudTrace.c index 8a19f191..6ac75cfd 100644 --- a/OSX/sec/securityd/iCloudTrace.c +++ b/OSX/sec/securityd/iCloudTrace.c @@ -30,49 +30,9 @@ #include #include #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #include #endif #include #include - -static void -TraceKeyClassItem(void *token, CFStringRef keyclass, CFStringRef name, int64_t num) -{ - CFStringRef key = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.%@"), keyclass, name); - if (key) { - num = SecBucket2Significant(num); - AddKeyValuePairToKeychainLoggingTransaction(token, key, num); - CFReleaseNull(key); - } - -} - -static void -TraceKeyClass(void *token, CFStringRef keyclass, const struct _SecServerKeyStats *stats) -{ - TraceKeyClassItem(token, keyclass, CFSTR("AverageSize"), stats->averageSize); - TraceKeyClassItem(token, keyclass, CFSTR("MaxSize"), stats->maxDataSize); - TraceKeyClassItem(token, keyclass, CFSTR("NumItems"), stats->items); -} - -/* -------------------------------------------------------------------------- - Function: DoLogging - - Description: If it has been determined that logging should be done - this function will perform the logging - -------------------------------------------------------------------------- */ -void CloudKeychainTrace(CFIndex num_peers, size_t num_items, - const struct _SecServerKeyStats *genpStats, - const struct _SecServerKeyStats *inetStats, - const struct _SecServerKeyStats *keysStats) -{ - void *token = BeginCloudKeychainLoggingTransaction(); - AddKeyValuePairToKeychainLoggingTransaction(token, kNumberOfiCloudKeychainPeers, (int64_t)num_peers); - AddKeyValuePairToKeychainLoggingTransaction(token, kNumberOfiCloudKeychainItemsBeingSynced, SecBucket1Significant((int64_t)num_items)); - TraceKeyClass(token, CFSTR("genp"), genpStats); - TraceKeyClass(token, CFSTR("inet"), inetStats); - TraceKeyClass(token, CFSTR("keys"), keysStats); - CloseCloudKeychainLoggingTransaction(token); -} diff --git a/OSX/sec/securityd/iCloudTrace.h b/OSX/sec/securityd/iCloudTrace.h index 2da30fe1..594a5b87 100644 --- a/OSX/sec/securityd/iCloudTrace.h +++ b/OSX/sec/securityd/iCloudTrace.h @@ -26,24 +26,4 @@ #define sec_iCloudTrace_h #include -struct _SecServerKeyStats; - -extern const CFStringRef kNumberOfiCloudKeychainPeers - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); -extern const CFStringRef kNumberOfiCloudKeychainItemsBeingSynced - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); -extern const CFStringRef kNumbrerOfiCloudKeychainSyncingConflicts - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); -extern const CFStringRef kNumberOfiCloudKeychainTimesSyncFailed - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); -extern const CFStringRef kNumberOfiCloudKeychainConflictsResolved - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); -extern const CFStringRef kNumberOfiCloudKeychainTimesSyncedWithPeers - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_2_0); - -void CloudKeychainTrace(CFIndex num_peers, size_t num_items, - const struct _SecServerKeyStats *genpStats, - const struct _SecServerKeyStats *inetStats, - const struct _SecServerKeyStats *keysStats); - #endif diff --git a/OSX/sec/securityd/nameconstraints.c b/OSX/sec/securityd/nameconstraints.c index 40052ed2..e025fd64 100644 --- a/OSX/sec/securityd/nameconstraints.c +++ b/OSX/sec/securityd/nameconstraints.c @@ -381,49 +381,6 @@ static void update_match(bool permit, match_t *input_match, match_t *output_matc } } -static void nc_compare_DNSName_to_subtrees(const void *value, void *context) { - CFStringRef dnsName = (CFStringRef)value; - char *dnsNameString = NULL; - nc_san_match_context_t *san_context = context; - CFArrayRef subtrees = NULL; - if (san_context) { - subtrees = san_context->subtrees; - } - if (subtrees) { - CFIndex num_trees = CFArrayGetCount(subtrees); - CFRange range = { 0, num_trees }; - match_t match = { false, false }; - dnsNameString = CFStringToCString(dnsName); - if (!dnsNameString) { return; } - const DERItem name = { (unsigned char *)dnsNameString, - CFStringGetLength(dnsName) }; - nc_match_context_t match_context = {GNT_DNSName, &name, &match}; - CFArrayApplyFunction(subtrees, range, nc_decode_and_compare_subtree, &match_context); - free(dnsNameString); - - update_match(san_context->permit, &match, san_context->match); - } -} - -static void nc_compare_IPAddress_to_subtrees(const void *value, void *context) { - CFDataRef ipAddr = (CFDataRef)value; - nc_san_match_context_t *san_context = context; - CFArrayRef subtrees = NULL; - if (san_context) { - subtrees = san_context->subtrees; - } - if (subtrees) { - CFIndex num_trees = CFArrayGetCount(subtrees); - CFRange range = { 0, num_trees }; - match_t match = { false, false }; - const DERItem addr = { (unsigned char *)CFDataGetBytePtr(ipAddr), CFDataGetLength(ipAddr) }; - nc_match_context_t match_context = {GNT_IPAddress, &addr, &match}; - CFArrayApplyFunction(subtrees, range, nc_decode_and_compare_subtree, &match_context); - - update_match(san_context->permit, &match, san_context->match); - } -} - static void nc_compare_RFC822Name_to_subtrees(const void *value, void *context) { CFStringRef rfc822Name = (CFStringRef)value; char *rfc822NameString = NULL; @@ -449,33 +406,6 @@ 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); @@ -495,34 +425,6 @@ static void nc_compare_subject_to_subtrees(SecCertificateRef certificate, CFArra CFReleaseNull(subject); update_match(permit, &x500_match, match); - /* 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(sanDnsNames); - - /* Compare IPAddresss constraints */ - match_t ip_match = { false, permit }; - CFArrayRef ipAddresses = SecCertificateCopyIPAddressesFromSubject(certificate); - if (ipAddresses) { - CFRange ipRange = { 0, CFArrayGetCount(ipAddresses) }; - nc_san_match_context_t ipContext = { subtrees, &ip_match, permit }; - CFArrayApplyFunction(ipAddresses, ipRange, nc_compare_IPAddress_to_subtrees, &ipContext); - } - CFReleaseNull(ipAddresses); - update_match(permit, &ip_match, match); - /* Compare RFC822 constraints to subject email address */ match_t email_match = { false, permit }; CFArrayRef rfc822Names = SecCertificateCopyRFC822NamesFromSubject(certificate); diff --git a/OSX/sec/securityd/spi.c b/OSX/sec/securityd/spi.c index f0bc9d8a..04fbc37a 100644 --- a/OSX/sec/securityd/spi.c +++ b/OSX/sec/securityd/spi.c @@ -21,42 +21,54 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if TARGET_DARWINOS +#undef OCTAGON +#undef SECUREOBJECTSYNC +#undef SHAREDWEBCREDENTIALS +#endif + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wfour-char-constants" -#include -#include -#include -#include -#include -#include -#include -#include +#include "securityd/spi.h" +#include "ipc/SecdWatchdog.h" +#include "ipc/server_security_helpers.h" +#include "ipc/securityd_client.h" +#include "securityd/SecItemBackupServer.h" +#include "securityd/SecItemServer.h" #include #include #include -#include -#include -#include -#include -#include -#include +#include "securityd/SOSCloudCircleServer.h" +#include "securityd/SecOTRRemote.h" +#include "securityd/SecLogSettingsServer.h" #include #include "utilities/iOSforOSX.h" #include "utilities/SecFileLocations.h" #include "OTATrustUtilities.h" +#include "../../trustd/trustd_spi.h" + +#pragma clang diagnostic pop static struct securityd securityd_spi = { .sec_item_add = _SecItemAdd, .sec_item_copy_matching = _SecItemCopyMatching, .sec_item_update = _SecItemUpdate, .sec_item_delete = _SecItemDelete, -#if TARGET_OS_IOS && !TARGET_OS_BRIDGE - .sec_add_shared_web_credential = _SecAddSharedWebCredential, - .sec_copy_shared_web_credential = _SecCopySharedWebCredential, -#endif .sec_item_delete_all = _SecItemDeleteAll, .sec_keychain_backup = _SecServerKeychainCreateBackup, .sec_keychain_restore = _SecServerKeychainRestore, + .sec_item_copy_parent_certificates = _SecItemCopyParentCertificates, + .sec_item_certificate_exists = _SecItemCertificateExists, + .sec_roll_keys = _SecServerRollKeysGlue, + .sec_item_update_token_items = _SecItemUpdateTokenItems, + .sec_delete_items_with_access_groups = _SecItemServerDeleteAllWithAccessGroups, +#if SHAREDWEBCREDENTIALS + .sec_add_shared_web_credential = _SecAddSharedWebCredential, + .sec_copy_shared_web_credential = _SecCopySharedWebCredential, +#endif +#if SECUREOBJECTSYNC .sec_keychain_backup_syncable = _SecServerBackupSyncable, .sec_keychain_restore_syncable = _SecServerRestoreSyncable, .sec_item_backup_copy_names = SecServerItemBackupCopyNames, @@ -109,7 +121,6 @@ static struct securityd securityd_spi = { .soscc_ProcessSyncWithPeers = SOSCCProcessSyncWithPeers_Server, .soscc_ProcessSyncWithAllPeers = SOSCCProcessSyncWithAllPeers_Server, .soscc_EnsurePeerRegistration = SOSCCProcessEnsurePeerRegistration_Server, - .sec_roll_keys = _SecServerRollKeysGlue, .sec_keychain_sync_update_message = _SecServerKeychainSyncUpdateMessage, .sec_get_log_settings = SecCopyLogSettings_Server, .sec_set_xpc_log_settings = SecSetXPCLogSettings_Server, @@ -130,8 +141,6 @@ static struct securityd securityd_spi = { .soscc_DeleteEngineState = SOSCCDeleteEngineState_Server, .soscc_AccountHasPublicKey = SOSCCAccountHasPublicKey_Server, .soscc_AccountIsNew = SOSCCAccountIsNew_Server, - .sec_item_update_token_items = _SecItemUpdateTokenItems, - .sec_delete_items_with_access_groups = _SecItemServerDeleteAllWithAccessGroups, .soscc_IsThisDeviceLastBackup = SOSCCkSecXPCOpIsThisDeviceLastBackup_Server, .soscc_SOSCCPeersHaveViewsEnabled = SOSCCPeersHaveViewsEnabled_Server, .soscc_RegisterRecoveryPublicKey = SOSCCRegisterRecoveryPublicKey_Server, @@ -139,47 +148,20 @@ static struct securityd securityd_spi = { .soscc_CopyBackupInformation = SOSCCCopyBackupInformation_Server, .soscc_SOSCCMessageFromPeerIsPending = SOSCCMessageFromPeerIsPending_Server, .soscc_SOSCCSendToPeerIsPending = SOSCCSendToPeerIsPending_Server, - .sec_item_copy_parent_certificates = _SecItemCopyParentCertificates, - .sec_item_certificate_exists = _SecItemCertificateExists, -}; - -#ifdef LIBTRUSTD -static struct trustd trustd_spi = { - .sec_trust_store_for_domain = SecTrustStoreForDomainName, - .sec_trust_store_contains = SecTrustStoreContainsCertificateWithDigest, - .sec_trust_store_set_trust_settings = _SecTrustStoreSetTrustSettings, - .sec_trust_store_remove_certificate = SecTrustStoreRemoveCertificateWithDigest, - .sec_truststore_remove_all = _SecTrustStoreRemoveAll, - .sec_trust_evaluate = SecTrustServerEvaluate, - .sec_ota_pki_trust_store_version = SecOTAPKIGetCurrentTrustStoreVersion, - .sec_ota_pki_asset_version = SecOTAPKIGetCurrentAssetVersion, - .ota_CopyEscrowCertificates = SecOTAPKICopyCurrentEscrowCertificates, - .sec_ota_pki_get_new_asset = SecOTAPKISignalNewAsset, - .sec_trust_store_copy_all = _SecTrustStoreCopyAll, - .sec_trust_store_copy_usage_constraints = _SecTrustStoreCopyUsageConstraints, - .sec_ocsp_cache_flush = SecOCSPCacheFlush, - .sec_networking_analytics_report = SecNetworkingAnalyticsReport, - .sec_trust_store_set_ct_exceptions = _SecTrustStoreSetCTExceptions, - .sec_trust_store_copy_ct_exceptions = _SecTrustStoreCopyCTExceptions, +#endif /* SECUREOBJECTSYNC */ }; -#endif -#if SECD_SERVER +#if SECD_SERVER && SECUREOBJECTSYNC static CFTypeRef delayedSOSSharedObject(void) { - static CFTypeRef soscc_status; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - soscc_status = SOSKeychainAccountGetSharedAccount(); - }); - return soscc_status; + return SOSKeychainAccountGetSharedAccount(); } #endif void securityd_init_local_spi(void) { gSecurityd = &securityd_spi; -#if SECD_SERVER +#if SECD_SERVER && SECUREOBJECTSYNC // We're the server: we need to handle this locally. Bring them up and set them in the global object. securityd_spi.soscc_status = delayedSOSSharedObject; #endif @@ -205,17 +187,13 @@ void securityd_init_server(void) { SecdLoadWatchDog(); } -static void trustd_init_server(void) { -#ifdef LIBTRUSTD - gTrustd = &trustd_spi; - SecPolicyServerInitialize(); -#endif -} - void securityd_init(CFURLRef home_path) { - if (home_path) + if (home_path) { SetCustomHomeURL(home_path); + } securityd_init_server(); +#ifdef LIBTRUSTD trustd_init_server(); +#endif } diff --git a/OSX/sec/securityd/spi.h b/OSX/sec/securityd/spi.h index 7e769031..efe159fe 100644 --- a/OSX/sec/securityd/spi.h +++ b/OSX/sec/securityd/spi.h @@ -23,7 +23,7 @@ #ifndef _SECURITYD_SPI_H_ #define _SECURITYD_SPI_H_ -#include +#include "utilities/SecCFError.h" #include #include diff --git a/OSX/sectests/SecurityTests-Entitlements.plist b/OSX/sectests/SecurityTests-Entitlements.plist index bcd392ae..35eb8339 100644 --- a/OSX/sectests/SecurityTests-Entitlements.plist +++ b/OSX/sectests/SecurityTests-Entitlements.plist @@ -8,6 +8,8 @@ com.apple.keystore.device + com.apple.private.applecredentialmanager.allow + restore-keychain migrate-keychain diff --git a/OSX/sectests/testlist.h b/OSX/sectests/testlist.h index f8c6e61d..44ebadc5 100644 --- a/OSX/sectests/testlist.h +++ b/OSX/sectests/testlist.h @@ -6,6 +6,5 @@ #include #include #include -#include #include diff --git a/OSX/shared_regressions/shared_regressions.h b/OSX/shared_regressions/shared_regressions.h index 52740b97..534f8cd5 100644 --- a/OSX/shared_regressions/shared_regressions.h +++ b/OSX/shared_regressions/shared_regressions.h @@ -8,11 +8,6 @@ */ #include -ONE_TEST(si_15_certificate) -ONE_TEST(si_16_ec_certificate) -ONE_TEST(si_18_certificate_parse) -ONE_TEST(si_20_sectrust) -ONE_TEST(si_20_sectrust_policies) ONE_TEST(si_21_sectrust_asr) ONE_TEST(si_22_sectrust_iap) #if !TARGET_OS_WATCH @@ -21,7 +16,6 @@ ONE_TEST(si_23_sectrust_ocsp) DISABLED_ONE_TEST(si_23_sectrust_ocsp) #endif ONE_TEST(si_24_sectrust_itms) -ONE_TEST(si_24_sectrust_nist) ONE_TEST(si_24_sectrust_diginotar) ONE_TEST(si_24_sectrust_digicert_malaysia) ONE_TEST(si_24_sectrust_passbook) @@ -29,7 +23,7 @@ ONE_TEST(si_25_cms_skid) ONE_TEST(si_26_sectrust_copyproperties) ONE_TEST(si_27_sectrust_exceptions) ONE_TEST(si_28_sectrustsettings) -ONE_TEST(si_29_sectrust_sha1_deprecation) +ONE_TEST(si_29_cms_chain_mode) ONE_TEST(si_32_sectrust_pinning_required) ONE_TEST(si_34_cms_timestamp) ONE_TEST(si_35_cms_expiration_time) @@ -59,14 +53,9 @@ ONE_TEST(si_68_secmatchissuer) ONE_TEST(si_70_sectrust_unified) ONE_TEST(si_71_mobile_store_policy) ONE_TEST(si_74_OTA_PKI_Signer) -ONE_TEST(si_82_seccertificate_ct) -ONE_TEST(si_82_sectrust_ct) 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) ONE_TEST(padding_00_mmcs) diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_length_63.cer b/OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_length_63.cer similarity index 100% rename from OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_length_63.cer rename to OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_length_63.cer diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_27.cer b/OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_27.cer similarity index 100% rename from OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_27.cer rename to OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_27.cer diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_28.cer b/OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_28.cer similarity index 100% rename from OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_28.cer rename to OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_28.cer diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_32.cer b/OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_32.cer similarity index 100% rename from OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_32.cer rename to OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_32.cer diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_36.cer b/OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_36.cer similarity index 100% rename from OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_tag_36.cer rename to OSX/shared_regressions/si-18-certificate-parse/ExtensionFailureCerts/parse_fail_tag_36.cer diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_keyusage_extra_bit.cer b/OSX/shared_regressions/si-18-certificate-parse/ParseFailureCerts/parse_fail_keyusage_extra_bit.cer similarity index 100% rename from OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/parse_fail_keyusage_extra_bit.cer rename to OSX/shared_regressions/si-18-certificate-parse/ParseFailureCerts/parse_fail_keyusage_extra_bit.cer diff --git a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/TODODescriptions.txt b/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/TODODescriptions.txt index 6a30ddba..d401065e 100644 --- a/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/TODODescriptions.txt +++ b/OSX/shared_regressions/si-18-certificate-parse/TODOFailureCerts/TODODescriptions.txt @@ -1,19 +1,3 @@ -The following certs do not fail because parse failures in non-critical extensions are ignored. -The certificate merely marks those extensions as not present. -parse_fail_keyusage_extra_bit.cer - -the length field says 2 but there are 2 bytes in the bitstring (plus unused bits field which makes 3) - -we happily skip the extra byte -parse_fail_length_63.cer - -length field in AKID -parse_fail_tag_27.cer - -tag field in EKU (seq) -parse_fail_tag_28.cer - -tag field in EKU (oid) -parse_fail_tag_32.cer - -tag field in SKID -parse_fail_tag_36.cer - -tag field in AKID - parse_fail_too_big.cer succeeds because we ignore extra data after the cert. parse_fail_basic_constraints_notCA_pathlen.cer @@ -26,4 +10,4 @@ parse_fail_ec_not_on_curve.cer We don’t check that the point is on the curve until we use the key (e.g. for verifying a signature). spki_fail_tag_4.cer -SecECPublicKeyInit doesn’t read the parameters of the algorithm ID. \ No newline at end of file +SecECPublicKeyInit doesn’t read the parameters of the algorithm ID. 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 cf5ed7af..cc6821c8 100644 --- a/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist +++ b/OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist @@ -3,6 +3,8 @@ + CertDirectory + si-20-sectrust-policies-data MajorTestName AST2 MinorTestName @@ -29,6 +31,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AST2 MinorTestName @@ -59,6 +63,8 @@ AppleServerAuthenticationAllowUATAST2 + CertDirectory + si-20-sectrust-policies-data MajorTestName EscrowProxy MinorTestName @@ -89,6 +95,8 @@ AppleServerAuthenticationAllowUATEscrow + CertDirectory + si-20-sectrust-policies-data MajorTestName EscrowProxy MinorTestName @@ -115,6 +123,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName FMiP MinorTestName @@ -145,6 +155,8 @@ AppleServerAuthenticationAllowUATFMiP + CertDirectory + si-20-sectrust-policies-data MajorTestName FMiP MinorTestName @@ -171,6 +183,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName HomeKit MinorTestName @@ -199,6 +213,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName HomeKit MinorTestName @@ -225,6 +241,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName SWUpdate MinorTestName @@ -246,6 +264,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName SWUpdate MinorTestName @@ -267,6 +287,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName SWUpdate MinorTestName @@ -290,6 +312,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName SWUpdate MinorTestName @@ -313,6 +337,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ApplePinned MinorTestName @@ -345,6 +371,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ApplePinned MinorTestName @@ -375,6 +403,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleSSLPinned MinorTestName @@ -409,6 +439,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleSSLPinned MinorTestName @@ -443,6 +475,8 @@ ApplePinningAllowTestCertsTLSPinningTest + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleSSLPinned MinorTestName @@ -473,6 +507,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleSSLPinned MinorTestName @@ -507,6 +543,8 @@ ApplePinningAllowTestCertsTestAST2ServerAuth + CertDirectory + si-20-sectrust-policies-data MajorTestName VPNProfile MinorTestName @@ -532,6 +570,8 @@ ApplePinningAllowTestCertsATVVPNProfile + CertDirectory + si-20-sectrust-policies-data MinorTestName NegativeTest MajorTestName @@ -553,6 +593,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleTVOSAppSigning MinorTestName @@ -576,6 +618,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleTVOSAppSigning MinorTestName @@ -599,6 +643,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleTVOSAppSigning MinorTestName @@ -620,6 +666,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName EAPTLS MinorTestName @@ -641,6 +689,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleServerAuth MinorTestName @@ -664,6 +714,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleCorporate MinorTestName @@ -692,6 +744,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleCorporate MinorTestName @@ -720,6 +774,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleCorporate MinorTestName @@ -748,6 +804,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleCorporate MinorTestName @@ -778,6 +836,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleCorporate MinorTestName @@ -806,6 +866,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName TestSMP MinorTestName @@ -829,6 +891,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName TestSMP MinorTestName @@ -850,6 +914,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName SMP MinorTestName @@ -873,6 +939,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName SMP MinorTestName @@ -894,6 +962,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleIDRecordSigning MinorTestName @@ -917,6 +987,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneApplicationSigning MinorTestName @@ -938,6 +1010,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneApplicationSigning MinorTestName @@ -963,6 +1037,8 @@ ApplePinningAllowTestCertsiPhoneApplicationSigning + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneApplicationSigning MinorTestName @@ -986,6 +1062,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneApplicationSigning MinorTestName @@ -1007,6 +1085,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneProfileSigning MinorTestName @@ -1030,6 +1110,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneProvisioningProfile MinorTestName @@ -1053,6 +1135,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneProvisioningProfile MinorTestName @@ -1078,6 +1162,8 @@ ApplePinningAllowTestCertsiPhoneProvisioningProfileSigning + CertDirectory + si-20-sectrust-policies-data MajorTestName ExternalDeveloper MinorTestName @@ -1101,6 +1187,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ExternalDeveloper MinorTestName @@ -1124,6 +1212,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ExternalDeveloper MinorTestName @@ -1147,6 +1237,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ExternalDeveloper MinorTestName @@ -1168,6 +1260,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName SoftwareSigning MinorTestName @@ -1191,6 +1285,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName SoftwareSigning MinorTestName @@ -1212,6 +1308,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName GrandSlam MinorTestName @@ -1240,6 +1338,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName IDS MinorTestName @@ -1270,6 +1370,8 @@ AppleServerAuthenticationAllowUATIDS + CertDirectory + si-20-sectrust-policies-data MajorTestName LegacyAPN MinorTestName @@ -1299,6 +1401,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName IPSec MinorTestName @@ -1327,6 +1431,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName IPSec MinorTestName @@ -1355,6 +1461,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName IPSec MinorTestName @@ -1383,6 +1491,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName IPSec MinorTestName @@ -1411,6 +1521,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName EAP MinorTestName @@ -1443,6 +1555,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName IPSec MinorTestName @@ -1471,6 +1585,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName EAP MinorTestName @@ -1500,6 +1616,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName Passbook MinorTestName @@ -1529,6 +1647,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName Passbook MinorTestName @@ -1555,6 +1675,8 @@ 4 + CertDirectory + si-20-sectrust-policies-data MajorTestName Passbook MinorTestName @@ -1581,6 +1703,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName Passbook MinorTestName @@ -1607,6 +1731,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName OTATasking MinorTestName @@ -1628,6 +1754,8 @@ 4 + CertDirectory + si-20-sectrust-policies-data MajorTestName OTATasking MinorTestName @@ -1649,6 +1777,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName MobileAsset MinorTestName @@ -1670,6 +1800,8 @@ 4 + CertDirectory + si-20-sectrust-policies-data MajorTestName MobileAsset MinorTestName @@ -1691,6 +1823,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName AppleIDAuthority MinorTestName @@ -1712,6 +1846,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName UniqueDeviceCert MinorTestName @@ -1731,6 +1867,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName UniqueDeviceCert MinorTestName @@ -1757,6 +1895,8 @@ ApplePinningAllowTestCertsUCRT + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneActivation MinorTestName @@ -1776,6 +1916,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneActivation MinorTestName @@ -1797,6 +1939,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneDeviceCert MinorTestName @@ -1819,6 +1963,8 @@ 2008-01-01T20:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName FactoryDeviceCert MinorTestName @@ -1842,6 +1988,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName LockdownPairing MinorTestName @@ -1863,6 +2011,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName LockdownPairing MinorTestName @@ -1882,6 +2032,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName LockdownPairing MinorTestName @@ -1901,6 +2053,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName ConfigurationProfile MinorTestName @@ -1924,6 +2078,8 @@ 2016-01-01T20:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName MacAppStoreReceipt MinorTestName @@ -1947,6 +2103,8 @@ 2016-01-01T20:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName MacAppStoreReceipt MinorTestName @@ -1968,6 +2126,8 @@ 2016-03-01T20:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName MacAppStoreReceipt MinorTestName @@ -1989,6 +2149,8 @@ 2016-03-01T20:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName EscrowProxyCompatibility MinorTestName @@ -2015,6 +2177,10 @@ 2016-10-04T19:00:00Z + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName EscrowProxy MinorTestName @@ -2041,6 +2207,8 @@ 2016-10-04T19:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName EscrowProxyCompatibility MinorTestName @@ -2070,6 +2238,8 @@ 2016-10-04T19:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName MMCSCompatibility MinorTestName @@ -2096,6 +2266,10 @@ 2016-10-04T19:00:00Z + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName MMCSCompatibility MinorTestName @@ -2124,6 +2298,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName TLDWildcard MinorTestName @@ -2150,6 +2326,8 @@ 2018-04-14T19:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName LASecureStaticIOAssets MinorTestName @@ -2169,6 +2347,8 @@ 4 + CertDirectory + si-20-sectrust-policies-data MajorTestName LASecureStaticIOAssets MinorTestName @@ -2190,6 +2370,8 @@ AllowAppleTestCertificatesSecureIOStaticAsset + CertDirectory + si-20-sectrust-policies-data MajorTestName FakeDOD MinorTestName @@ -2221,6 +2403,8 @@ 2016-12-10T04:38:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName FakeDOD MinorTestName @@ -2252,6 +2436,8 @@ 2016-12-10T04:38:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName FakeDOD MinorTestName @@ -2283,6 +2469,8 @@ 2016-12-10T04:38:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName DOD MinorTestName @@ -2314,6 +2502,8 @@ 2016-01-01T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide-Baseline MinorTestName @@ -2342,6 +2532,8 @@ 2019-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide-Baseline MinorTestName @@ -2370,6 +2562,8 @@ 2017-12-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide-Hostname MinorTestName @@ -2398,6 +2592,10 @@ 2019-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName Systemwide-Hostname MinorTestName @@ -2424,6 +2622,8 @@ 2017-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide-PolicyName MinorTestName @@ -2454,6 +2654,8 @@ 2019-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide-PolicyName MinorTestName @@ -2482,6 +2684,8 @@ 2017-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide-Both MinorTestName @@ -2512,6 +2716,10 @@ 2019-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName Systemwide-Both MinorTestName @@ -2540,6 +2748,10 @@ 2017-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName Systemwide MinorTestName @@ -2566,6 +2778,8 @@ 2017-02-08T21:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide MinorTestName @@ -2592,6 +2806,8 @@ 2017-04-08T20:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName PPQSigning MinorTestName @@ -2615,6 +2831,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName Systemwide MinorTestName @@ -2641,6 +2859,10 @@ 2017-02-20T21:00:00Z + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName PCSEscrowService MinorTestName @@ -2660,6 +2882,10 @@ 5 + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName EscrowService MinorTestName @@ -2679,6 +2905,10 @@ 5 + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName EscrowService MinorTestName @@ -2698,6 +2928,10 @@ 5 + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName PCSEscrowService MinorTestName @@ -2719,6 +2953,8 @@ 2 + CertDirectory + si-20-sectrust-policies-data MajorTestName macOSProfileSigning MinorTestName @@ -2740,6 +2976,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName macOSProfileSigning MinorTestName @@ -2761,6 +2999,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName macOSProfileSigning MinorTestName @@ -2782,6 +3022,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneVPNApplicationSigning MinorTestName @@ -2805,6 +3047,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName iPhoneVPNApplicationSigning MinorTestName @@ -2826,6 +3070,8 @@ 5 + CertDirectory + si-20-sectrust-policies-data MajorTestName BAA_UCRT MinorTestName @@ -2847,6 +3093,8 @@ 4 + CertDirectory + si-20-sectrust-policies-data MajorTestName BAA_SCRT MinorTestName @@ -2868,6 +3116,8 @@ 4 + CertDirectory + si-20-sectrust-policies-data MajorTestName AssetReceipt MinorTestName @@ -2891,6 +3141,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AssetReceipt MinorTestName @@ -2914,6 +3166,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName AssetReceipt MinorTestName @@ -2935,6 +3189,68 @@ 5 + CertDirectory + si-20-sectrust-policies-data + MajorTestName + SSLClient + MinorTestName + NegativeTest + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + content.googleapis.com + SecPolicyClient + + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + GlobalSignRootCAR2 + ExpectedResult + 5 + VerifyDate + 2018-04-14T19:00:00Z + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + IPSecServer + MinorTestName + PositiveTest + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.11 + Properties + + SecPolicyName + content.googleapis.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + GlobalSignRootCAR2 + ExpectedResult + 4 + VerifyDate + 2018-04-14T19:00:00Z + + + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName ISTCrossSignPinning MinorTestName @@ -2963,6 +3279,10 @@ 3 + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + MajorTestName ISTCrossSignPinning MinorTestName @@ -2994,6 +3314,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSignPinning MinorTestName @@ -3025,6 +3347,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSign MinorTestName @@ -3053,6 +3377,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSignCA8Baltimore MinorTestName @@ -3081,6 +3407,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSignCA8DigiCert MinorTestName @@ -3107,6 +3435,8 @@ 2019-10-04T19:00:00Z + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSign MinorTestName @@ -3138,6 +3468,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSign MinorTestName @@ -3169,6 +3501,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSignOldPin MinorTestName @@ -3202,6 +3536,8 @@ 3 + CertDirectory + si-20-sectrust-policies-data MajorTestName ISTCrossSignOldPin MinorTestName @@ -3234,5 +3570,69 @@ ChainLength 3 + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + ValidPolicyConstraints + MinorTestName + SmimeCA-SmimeLeaf + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.8 + Properties + + SecPolicyName + test@validsmime.apple.geoffk.net + + + Leaf + Valid-leaf-serial+invalid+policysmime+complete-smime + Intermediates + + Valid-ca-serial+invalid+policysmime+complete + + ExpectedResult + 4 + Anchors + Valid-root + VerifyDate + 2019-03-01T16:00:00Z + ChainLength + 3 + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + ValidPolicyConstraints + MinorTestName + SSLCA-SSLServerLeaf + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + validssl.apple.geoffk.net + + + Leaf + Valid-leaf-serial+invalid+policyssl+complete-ssl + Intermediates + + Valid-ca-serial+invalid+policyssl+complete + + ExpectedResult + 4 + Anchors + Valid-root + VerifyDate + 2019-03-01T16:00:00Z + ChainLength + 3 + diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-ca-serial+invalid+policysmime+complete.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-ca-serial+invalid+policysmime+complete.cer new file mode 100644 index 0000000000000000000000000000000000000000..ca5beeb7b706b16b75bfa550422c2b82df118d82 GIT binary patch literal 1102 zcmXqLV(~I)Vm4a9%*4pV#L6&nd(UqJUN%mxHjlRNyo`+8tPBQ??S^s&GHlGDEX+Kj zVTn1JDGDK}#U%>PjtW8f`6UWrMutiT3LtrI9!ZFNKv8~HYH|roT`@?Fuz?^*4HplW zV?jYqs)A=;vYw%kfdEL5orlx8v>>&pBr`AHklTP0B*wwRXt!=& zt*6qq$qei-o+hWxxUeE&1G~(T-HI2d%5OV0Gw^QqZ?#M9)92L6l^ouGBl|@D^c$VC zf-3`0?JzkwW2)4X-+!7!3om_R=6AhvI?{K&P*J}~3E!i8f7Th)6i-$XKDlOLV3^#o zsaiqnf9_mWu!K`rJ7=r%EYrRfAx91s-%hl%H4i#F=fQNzIr+0SG}Jb!^h$Ke|C@5> zYDtSs&-djm8BbERyl3$CA!9I{)g*q?Uya`Mfw7cMjgpN$CA3_>Cw53hgmZC)h9d%w%YMHZo@?; zW=00a#f{4i8kZRG0b@{>pONuD3kxt|vKa`0_`)DQhXEUqVq#=4kOhhHv52vV)abq! zPp@v;G4;%mE4CX;o;DaUr5nhDq?K7D48$5lc7@#tPuu$^`jNmV%gyUI6}=7Rmocyd zDUfF|H!w9YUSPODzfCuzq@=(~Umu)QN`NU`FA<=00dOw?AvH7}QzEL@gRaWv%oM*(PO^On;-uTtmS#Nk&|J!gKh@T|7hDwB)*LQZp1ze(*1NaL#O-tQf=D z!`V}^p5L%*Ir`dbisz#K&HO3t^J97aMef==?>O;n&THX>Po9gk57|3Raq+mG@w|Gs aH<$MNFX8i&UU={ literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-ca-serial+invalid+policyssl+complete.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-ca-serial+invalid+policyssl+complete.cer new file mode 100644 index 0000000000000000000000000000000000000000..d6c972c53cea7cdc2bb631fc6cbc0aa521f1a9f7 GIT binary patch literal 1099 zcmXqLVsSTUV%A^4%*4pV#3K5dx6^=^jZ>@5qwPB{BO^B}gF$1vp`3vX8*?ZNGmmIk zVoqj?LP%p^||DNS>QV5+WZ^l%JKFTmn;93{oR(AP7>!#lz)T zP>_?V;F*`KXDDPK01{;9;dCx7NG&SK%*!|AHsAz_aquuXJHj|@!c3vT1`6W5h86}E zhQ@}L24*H^Q4;({hCl&xBLk>_LE|(-T?1{9c4i(GpaY9ji!u{)6f*P5!0s-{&&f=# zEH2JbNY2j%I-(?%UQTafR6-6{Mpg#qCPsb+gC<5UrY1&4hCA`^A1+&bxp|&*VFF{= zI)(ZF`wq-TYUMlg?*<`dPv0zGpr~Q>F_Z{W3rzu`zOSuqv*;eV= zVWEU8)8D-I=`Jcv*x_)UGjoDOdgMc+&wkuOAJ(V6^}l!3E7dd0Sz}3M^8S~avyMq! zn06;HT5A8dB_FTG=tUJA_P!@V7WU;W}3&J`E;DjqCc_)C&|w`e^RGb01z z;>P6$jY|ypfbl2G&&c?ng$0-@*$jk0d|?ou!+;G)F)=b2$b!W9Sj1RFCb!(a+7-3b zM$q(~ouNnL)UqcV`VHhk(#k9n24W2&yTWdSr|ta{{Yc=G<>vL9ir$9u%NW>!6v(rf z8<-jxFECu7-=>>UQc_^0uMbWrCBXEpmk3Ixdg-b8X=&Mdd8sA(Wk$M1zyzOHcv*sFN#C%ZPv`zH>&=HO|q>sXHUHGTGDsr!bnHS;D?IM`UQ`c X95Q`tfBO5jigg!)?`yVMl~w@&{uYv9 literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-clientauth.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-clientauth.cer new file mode 100644 index 0000000000000000000000000000000000000000..e2b5bf61022b4b6fe1669b07545f292d228fe27c GIT binary patch literal 1208 zcmXqLV%cKQ#5`vKGZP~d6AMfH*0%<{Y@Awc9&O)w85y}*84Ma{80s77vN4CUF!QK6 zJ1P{X7G);pC}if9CFW$NC=}%9WF}V@=Vs=nDkSIU7UZOsq#7z2D1bC@^GJq)6$KRK zXQd{WD1@XImnb+p7Au4q844Q+g4A&Fa5)wLbt!n}CF>aq83=#`*?BmfOAAtqN;32E z4Y>_CL1G*{OwNul4x2DjXt05TIIp3FfrX)|fvJg!p+S@czmXwOz}(0PDqzsK)X>Jj z3Z$Kx$Ji$|F^w4KD7D%O_2YO32~P$jZRn#K_NJ(8S2a)WpchaQ@VO zYX+g)f1T_~W3NBss+zZoZ};YT7jH2!Te!Y{sCp^3{&M-zx`6n(H$Rl^zhq>)^StpS zPyc{p(_{a=obXpN^QG=ji_b5v^)o0Hqy6=4Vp=`&ZSxrHz zRZ}K}E#H+ZV83zVY~>!6h~U#Q6aQHMb*Px^z4bz5*HY)!S-1VKYgMb;34dd~f5jqS zELyg!w|J@a(vz!owkOSGdyvSzY&J{&8<%p`DX*EQh)fBS@BFD+-Sc6~PV*Hd{C|J; zciGG|5IYme#LURRxVZ6)LE}dQK45gp@-s62XJKJxVs9|u0r7=Fd?o`119=cnnMJ}t ztU;tk_q}*}b<>WiXO3L4-B|Lp!H6l{AQq%Ro+Zp6#2{!vzyiNEpNx`{0xNxeaC$BQ zrck{^P=eG;Pt8wD%htmRb&dA83 zYoKkQ3F8|uw#h|AAFn}2n zm@pU_wp?FQ@z-W)_sQ&c?c&0!OMjKkFyNcO*uGM|>SwP3XZ`croHMSR|Gz;(N@})f z*sQgWi*@(kYFSphw81;BI@_^k+C71ve`U_ju2xmrt+ZxNsm1k4dgo7>O`o{rq?fGV zck8(alh)R65D40QlBcR{zNfvGRf(zm6B%~#R*T5G{ zBi0!#vcALoa>C8aFZALHC;hu{JA190+@*U4?bjloG3tL5o~Tpr#@74cskf7-mDKywXL7dmn!ob4N)WFol#Lys0g5SsxC}3`61Qjr7Tx@7% zU;)z3%wy=2nwUn6^MU?INiEJy&!d+=ni!RkL!FV8fw_s1pTVGsk&CH`k&$7mDKop; z+^37HOSqJ02Kkhv-3%)ex>b`oQF7K4pSu=UoL6%1&thB0_NaP3+th1&cB_17sw$Xn;8&)5 zYC?mw*{jSo{~xc-_xScW)!*w}$>iX(%-tvz!q7h1NuY}tK82Yl+m7g%Y-Be`s^XBemmg!%YzZO+l z8keHismjF6$iTR`@ryy@M*}`!WXke0GX7^_VP;})FyI04g+Y8K0|oczSiyj;UvkT(R9)^0dK-Dcv9zq(Gh}%pk-dXhFaNzc!zYl9B=|eSL6hE&--b zy+lxQ)JspzPfN?z%S$cMFEi4GBzj$FqSr-A^t!M_ua{huV_?a~q0Pp~%F52j$f9eY zZJ-I`8!)!XLT$><%P-Hu@^I8JF&rtG+Ub5-??`Y}u-~0BiYW(&1?L$nJx^H&vi!7UeX`Q=Q Q*d_C0>57Y=Iw^h!0I-R!g#Z8m literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-smime.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-smime.cer new file mode 100644 index 0000000000000000000000000000000000000000..83c77f22460ea953df0cc4e3abc9b50d8a72f373 GIT binary patch literal 1251 zcmXqLV!3b7#C&`KGZP~d6Dz}Ro`xU;UN%mxHjlRNyo`+8tPBQ?GYs_&blI3gS(tg$ zoE;U4Q;RYaa}+Z3$`W%jQxppFb25`Fi*qw`Qx%f)a|?1(OHvJ$3=}{bxOpVQz={Hj z^0QKtOB6y7-mDKywXL7dmn!ob4N*wE6%z|Zl`k>PrU#|oBTj?cSy zu;sc4YyWQEx{ihT4p_$Ijd=>wU>3l1k?X>H0m~)W|Z+< zvtE@^TqTkdcPsS9cd|?2L>ox(3dXz*i;ioaTI%OYJzc?Vt{)*EVw+I; zTlM5tYkv3XUVlY2_pkLZi9WViV|T=_@aTGlTV!y?^uC24{zRo7*oJy5IS_*}&=ScLv3xUGHbz z7Aar<=*RKnoMM+YXC@vA{8aSCv!>|%gVKl33)lSkQ}l5%&x(BCqb>`VuRY7gzUZ6t z4C5r=UZ$xOXAo6UoED#)J8otY=~p#IYqr;W~D%Krp|uJAl*-R8${R?nt> gTkekk)#w|n585qESGq+TZjrIx!)GVrQ2$~d0A$9xmH+?% literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-ssl.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policysmime+complete-ssl.cer new file mode 100644 index 0000000000000000000000000000000000000000..0de2b43d78965a4bb2ec89c159d36b5b7552b6c7 GIT binary patch literal 1242 zcmXqLV!39}#Jq0-GZP~d6D!01;(zxHc-c6$+C196^D;7WvoaVo&M?$B&}Cx|Wntz~ zb9PiHPA$qz%u&e9D@)ADOi?Jv&&f=#EY8i$O;t$F&n?JFElD+0GEe|%;O3DG11kzB z%FjwoE>Q?cEiO@Tb}Uv1Gcpu55Co~=;^A^E0P0fk%uCiY6fzJ139|EWI+qrt7L{b? z6 zfiXxsGmnl>YGN8O&Q~Zd&Y_nVni!Rk1DuhSfw_s1pTVGsk&CH`k&$8LqMfe0Cn#<0 zeX)P@+D|fnD%Y-Dw0%>_K@nrlMh!;mMapbGOH3=?Z3aqR3LIo%&u*t;y9Rb#Uv zEUZsbgnJcp$>QW+d42^vhuG~`J-Ghu*Xz5#yA>-xCNJ`l|D(yBdFNk7cN*vFs*B=k z1vg{Y81xs$d8TAI-@L-GHuTHAMQ8c0cj-JR*Y`-bEET(^^7q!oZ7Y55{Ha#cW{kgn zlZly;fpKvYqcku?#0~g>F)7Q>$oQXyg_()H!GH(E7Y6Z}3>XaLK|Ey^2?MbPks96i z;_1~*JEopFa>aII$^!33>xdfOv^%6m8 zQ7=6;KP@d=FE6!3zsyJ%lHzrtDP9*T#p}XSyk2rqj)5f`hc+7{D=RxABa5zqwt*&$ zZ@}0l3$-abFTXrbH!-icJhezSKe@O-A4C|4fn25v@(7Os7fc&7qk#%YT#!Z9K)Oj1 z>_}kJ#Bd{W0s`h(U;<)fa8WM)_x=0sD}5$S$Le-1#G7Q0w-P_@_R(X4%&Uv;!!n0dBV=e|WkdCGd{>*n`ecN})H zt&oZeTUn?tnk)X=ReM75n;Z9@v+>82E=f;3sQb)(vbO9pCCS@Qy)Sb0zl-bJckaNR zAIBnW!yGf;bFwikRQYmr$&VEb^Sr(Z&6i%*{OlJ`by;{Zd)@x@^p$EX+J= z&W;MjsYRKIISQG1Wr;bNDGCMoIho0o#krZesS3&Yxdl0?C8>r=1_~ez+&q$DU_}8% z`B|ySB?=*_#U%>Pj>QULMux%$f*>_qJY0?iKwS!+dC7W)LIwgLL3SQa=hA}IqLR$K zd_!&nPLLP}50kSajKe0(6dG)xAkJ%OVPIisYG7(&VrU#C!Ea;;6fie3f(jTkE-|z= zumovm<}va~O-v)k`3faK&lHy=<`&S)BTbA-$idFY%D~*j$j@NV#K^_e#K_37YL-+n z>*2d=FX$@1JrtCir1JT$Mq_H|n+;16r{C3E^t5W;xvT2sY8+E^!?J@~cSSuDkmW2*(cY!X!&#cDeYsUgCb(x=`H!DB zOT*VoKE84Ah~fOniN!_|?bod)B`Oq56TEchnb7HuGcu-0&wox5YC5~vw{iZ${1TQR zzdiS=&N4AGGB7S~{9@4f(SQ#ao3i|jjQ?3!n3>oc40u3%VGy6mfWbf>#8YOGFc51H zsnLBeo?hLwW9peBS8O+yJZ&&yN;ilFDUfFgGYByVS`e_nugxc;q@=(~Umu*DOMvmN zmk3Iadg-b8X=&Mdd8sA(Wk$M?RIdw7^}0x@UKf_?^^%KnfN70Gn~jl`m7S51Mb|*v zKoiC{U~H3x+LWD_U!JF%m{(k$TBMtwTwI_JA`HYpE>i`0gvWpjrj3~cIbi_vBQRkw zGN`mJ5O?p(cRKhr=8}-^hg)r)UwyAENNc&Z(qzp+)yuyYe=J&)DfZTv-*Rib`P2n3 zw-&{uE)LeU-M#mE-M#4+*H7I(85y}%;m_U2Q}+5ehPpW0eWult zt*X*i8v7&Nb>40}CR=T2)p6l?^smDk!*q8TM3_hgUVT%Qot5J}MN6V{()vXU=fz)t Pte?W8zwD=K)%;`t^q#M> literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-clientauth.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-clientauth.cer new file mode 100644 index 0000000000000000000000000000000000000000..95dc5b1855f61c4b59c0e7ef101c753914ac4059 GIT binary patch literal 1203 zcmXqLVp(s{#5{cgGZP~d6Dz~|qQC?LUN%mxHjlRNyo`+8tPBQ?(+qVDwAq+LS(tfL zoE;U4Q;RYaa}+Z3$`W%jQxppFb25`Fi;Hs*0AF)}i2d!CU| zy2w&!%1*JBySIwxr;{hD zV|~^>zc$_5C9%uC+UTOOtlvl0iO+K7cf4aNi|IPone#7S>IC&E%$8H+J$Y5Z}1= z#bx%pAcV&njIcAt{lE>irZN{d+XZ1T*S*_n`n0&yoGS|ec{GZ0eNh`U{ zr%al`_VBM(YRFY3`6IvCKAxQ-Bz50|dGf;f`)`W6Pnzy6|Nqd+`O`P`KbXMf(7f;8 zg5rvoa-2-ej0}v68$TH|zBk|lMy4!3BjbM-7G@^)1_K@tUl_z^GGH)}2l13yBn-qF zL?*Y~zSdawqLJWco0v7l!@M-hPC@Cqh($@#44sA9@R#tXKMiyX> zG0=qZ4H(;Gq4s3w<(KE_Cgv5FrxxkvCl?p!g9rmLkh@et-rzCdf@x!BLQWRItO!gN zj0}ZyUSCdOySD4VoKwa7s-|j8zxr^=bJi37W@bC<4sDzr?|Z=I?89qSZy)StE>||4 z?On#C%;=r8$WeT~zHoE9$U=*6O=>o0RntyqFQ{TVd{U?Q_FiTkjRO@2OnsLfiL(82 zRrF@JM$D?0UcVh0R!9DNx7D{!;^j}ik4fkH7)zYQ-hIzjH#xsDeW7Nr4*yaX;S^_o zcHv(>qD3Y8lf+v~CYpKiJUifZvi@wsu~WCtzELw)p1vuJbz#iR>m8**rFX>N@|~Az zySznbN%c~0hUb^Wt#3|^jGi?+j7!3xsC8?S6Z^%Gi5*W~+l&4Y`BS=2H>Bjcg-0EC Pm3Zk*$z`n^nvQk=6^W_3 literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-codesign.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-codesign.cer new file mode 100644 index 0000000000000000000000000000000000000000..2fd096dcf7071d81fee200d547771cf80386aa8b GIT binary patch literal 1200 zcmXqLVp(I*#5`pIGZP~d6H94Y#s>plHcqWJkGAi;jEvl@3%DH(Y!@x=cit@8k zlS>prQj1FzoE?i5!i)@s4Fo}IxOli63xK*5JoA$E4228?K!WT%oX({MsYNB3dHIIi z2Am)<4jv|FM;M1qm?<>aKtY_>(89pN(A2=x#KgcXN`l|W5GY`7WCRs3Xj};7n}M`5 z^XU7eCZ-W~JkS>@sl}P;dGzu{6QdGxh%>S>FgG#sGZ-{6axpbAGBWJlEj#(19hVuW zS45%lmY2QFEWR(0e7C}bVXv~b*>4G$o?rF2 z=`mx>No@f}=NB{hXNL1U|1hU$b$q^HC%u7dL(~Xnb$L2aHNten!UsEG*1S>R9;~Oxx z$wKYP&dV>)(@o4PE>A7e%}*{a&<7C)Vjy>^g1o_Fzy;IB%#55YfEf{(EEpMXb>2$U z-|9L2u!6(Ftod`K{yVrfm^6fYJ56IRT0S@Go^zOP>XzxnbNp9D8XnL+V=(9Y@f%-e zT%UZf*Ynw@60Vl3-<6bpv#O~CY&`M5MN;r)uJn>+UT%t<>9*e=Bq#MnoT<XO?(zhH2CgHoH`UPbm*%1|7|ye!sUK8GWKe$4}Y~-o53$} zM&0E1A2!Gtt@1Ky6I;Ew;>3abhaTrRzpO3LH#N~(kRT%%dL$}%N5WLG3dyEJn<~1w z>m>#5Hu)U*amQA|$;eYqY?n#%)$m`DYkODU+AP1F?}q3b^U052XFq2D%dutog=0d# J*@CTK3jj|BrriJl literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-smime.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-smime.cer new file mode 100644 index 0000000000000000000000000000000000000000..0614b8f79f4d3e69cc09624bf28b941f3c9d9963 GIT binary patch literal 1244 zcmXqLV!2_^#C%`@GZP~d6HCZaEoK8=HcqWJkGAi;jEvl@3%DH(Y!@x=cit@8k zlS>prQj1FzoE?i5!i)@s4Fo}IxOli63xK*5JoA$E4228?K!WT%oX({MsYNB3dHIIi z2Am)<4jv|FM;M1qm?<>aKtY_>(89pN(Adz@#K6=%N`l|W5GY`7WB?T~Xq;zgYG4e~ z&dj6ZlbV=D*zpR*xtY0i^FkA&5^``evNA9?G4eAQG%<29H8CvzA+~7vHV_uI2J^ChOC;Dz-A$0;k`L+1b6M@0619w8PC& ztqPg;hcmkZ=ii|J)9Xo`-j~O<;}uUcK`c zgXr6ZVp?Ye4>}%E`WDj1_R27Qj^~R~zR;qemrYU{x7(+`?DY3LU1OZ^uEPA6(z2dq zD?3&lS#6Q|@awl1{5zFQ&9*39JK(Lx#ec@^3D5Qr)(XAFHRct*Z&uvDI`MF_;>&O* zW=00a#Z8O~zz~r!-~+~_EI%XTe-;*ICe{T8JRrU>h|greU?30TDYHlzh&6~zZn=H6 zD{85Ypy@k1LyyL(WluKr8$^Q?$g_kP1Q`S@@LS;1=9N)WQedU84^GG>z{IJS2uh23 z>8bf?Y1w*tsU`YlM!Jynt_w}?y72U_3rp{M$wfH^mTVl_Y>cd|?2L>o!0ck63F8|u zw#h>6$@iFbFzXgDh5i83Lw`x zfZYjBpBN5BPDQ{>3rt0f4AY+^OxaZa!9&G3;aV?m$oh#FWUrjwcK9QY^Rt~!7bow0 zRX$O4;q&79>;isE*)W~Nf}$ht{YqDlcy3*N+o1E@#fXpbOIkoVl$JANE zaa%N37w11Rb#{wSuU=r#l``qbs@i{l1vYL^%4hOd3ikQio^}8H#>9p1re~{a3VJ38 z>y_0{i#d8X-~GRe`i_m)qbz*#Id;rHx$&mw#kEZab}3TJ;T1*Z}szj@2NZu0JK581poj5 literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-ssl.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-ssl.cer new file mode 100644 index 0000000000000000000000000000000000000000..5e6785b89a7b9eb64f5f6c5f9cf72ecc7b07d6f1 GIT binary patch literal 1235 zcmXqLVmWWn#Jqh0GZP~d6HBm1?^6R_HcqWJkGAi;jEvl@3%DH(Y!@x=cit@8k zlS>prQj1FzoE?i5!i)@s4Fo}IxOli63xK*5JoA$E4228?K!WT%oX({MsYNB3dHIIi z2Am)<4jv|FM;M1qm?<>aKtY_>(89pN(Adz@#K6=%N`l|W5GY`7WB?T~Xq;ncY+wk| z&dj6blbV=D*zpQLpU}$#O^iy&fz8Ouz}&>h&tTBR$i>ve$jETW?!@#>i~lXl)tYs0 za}HPdN4t~t2c%bsp54%YdTIgRg2Se(m(DmFU&*~U!fQwRP1BpQr&DBRuX(>;I#px) zhcw@a6+8W>sV-kwF#osplz;_xBJ<{#$?5VH_FUNBniT7&H@o4;<|Rp?FB=tBys~Iy z=YG!B-IwB{RF&3lv~pg#-C42FKWA1PU3g^T*V5UG%yv(WTFDK76wWpSc zoD+7oEScjmW&dq)*RsjJ+1IB&{>GU%xwa|3NoyfXaLK|Ey^2?MbPk;yH$uXaT( zwGlLZXJ_cqIJNA_hJJ%+kOFy@5Q89tfCYXFeA>J+N=gc>^!35XxCEFq^%6lTQ7=6; zKP@d=FE6!3zsyJ%lG=5lsa+SI+I3;6T`##P$H0<}Lz|6}m6e^5kp-Ap3^ZYU1I9L4 zs6E+v`Q>@KiFw84sYSZ^$;AcwAi_WlUpZT@Y1E= z;Byy$$EJk-7z-D%oj;<&vw2;mmDSVCPbAKhue1FxoXo1%Xtd|)f_6p!0$$B;g(rzyPOm^b4$gVE!&)q%HMoG zKZC{V{W`DN$Fdf*G2OasnfG&@*w*@j&7v-cZFyKt(>JoJxi7n4;t}_GYb=+hoY>>9 YM}1FD=G^{D`Ip~nqoT6-$t-ON0CD20*8l(j literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-timestamp.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-leaf-serial+invalid+policyssl+complete-timestamp.cer new file mode 100644 index 0000000000000000000000000000000000000000..64c915041f9f434a8459f4cea9c1ab36e9fde485 GIT binary patch literal 1202 zcmXqLVp(U<#5`>QGZP~d6Dz}kkLA7wylk9WZ60mkc^MhGSs4r(ry1%RXtObgvM}?g zI6Ep7rxs-<<|t(5l_ln6rYIET=VT^V78mCzBlq3e2!I6Hc{rU*3sQ?pGV}5c zxeYi$VjMh7&Wb8(9*yh zq@9_^z$Y~^jj-btN-}eS&P>cLpqDqA7?qHNoRO7*xrvdV!Jvtei>Zl`k>S4b{e9in zb7vjvuUybp*i|JlalyU^~pn4j>M z3iM+eV5;L+y?5!htoxRKeOkY6*5M{Dp+MDh zx!N@yRu>uE&#Z~P>eZ*;woGy3MMm4j$8&#AUUZ(()9=)_)sZhw-BaildmgrxM|+N( z(3`ogOw5c7jEfsT88p5(-~+~`EI%XTe-;*ICiVsc9uQv`#Ah;KFpvlFlvyMU#2Q2< zx7@zk6}8kx(Da?1p-1D?vL_q*4WdB`NVidTM@JTDD$ZYKeZCkuD^~>q1k!E@d%3t&zJCJRP} zWLwkorOR*pNP75HcE0iImhC^5rbK%S&R@2d@lpK6WgBd@j|N?=F=3bZzkPju$Gdf! z%T!{vF=?5Yho$Uzt#HVQDQ)`CQy;#sd>pZV&fS&u|L?!ke6&Eie9v~>4a={q{J(yz zc&YPlon3$RnCj|EPtW-9>}ldGz4D$@v(|I^`9~`x98@^u%A2vMv)S7^?2WFr7XP|0 zOv={|Ec53GPEGwZJL%-v*jWp|OFus2{m?V|(W|GizYDIoF*#c*Ui&{?U}N6@zyzQ7 zbN}qts7jf)t!tjc)azZ29u-DSi(NiTt9E@1k=pv!=+R8E4!PBmzrr7vy1!gsVEJC+ Qh`7v0OS7k&)<<^(09PlsKL7v# literal 0 HcmV?d00001 diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-root.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/Valid-root.cer new file mode 100644 index 0000000000000000000000000000000000000000..a3fdaf9f2a3e670bb5bb2697b550378c62cf767d GIT binary patch literal 987 zcmXqLV!m$B#I%0_GZP~d6DLCtPj7&UrtCHYUN%mxHjlRNyo`+8tPBQ??S^s&GHlGD zEX+KjVTn1JDGDK}#U%>PjtW8f`6UWrMutiT3LtrI9!ZFNKv8~HYH|roT`@?Fuz?^* z4HplWV?jYqs)A=;vYw%kfdEL5orlx8v>>&pBr`AHklTP0B*wwRL)w85x@z8%0U*8yNxxObpDS0)xn{O^iy&0m;b9z}&>h&tTBR$i>ve$jERw zS0rKcWv;Go`<6THKQ4GEr)$bbKHGGexn9@w4!$a1l(%YT`o8(g_w7}==zPMeqr5<6 z?yf1w9J>1(LET(C1$Utui$BHdg*7bb=-_d zuYz;`mnc6|c2<7ct^Y1dL&Mu}!3mBWeha}p>h+1|H<<10*|p1#LGHr;!b!Im_Q*49 z3fHV}U*xD2$NulV`H3w>$2*xDGZ{}*?`z_6ebjL+xgkW8;oJI%?WtZDr0Po<*}iR> zq8lg6wBy~c&=YrCG@nPVy7oFpP)+Rpms`a*EN{H|*e@e|O{eN+m(a(DwyPWSYp0ed zWF3(G5?ynbiJ6gsaj}zug8?5fwq^Ml8UM4e08=8H0Y8W@4C1pIFas$AS&#r9ix`W@ zuCN>7X?y=fKN9$4xq1DjqPL;^GRUC}Os>FCW@OkF{wPOzLi<&RFOMuu^`(Cs@`?QX zKRxDcRc?HP{EW$5!b|&SYb)@rPmiRzJ7Ly0y>qG?UP&A`>atij|DC)zuT0bH zNl)9Q=h;0ns@^((PmnzO#&WThhqlc>_~ewjtHgKq`jV+}J?XZu6fC{GD!08kH^V+5 zQ0=ohAI~2f6wzi-#5&D%T_~#^3#Zr z^0*iaV_5NC!KIX${+B*=;Udd#fYJALADwjnQ)Cb9t?^xf^ZP7vC$T8mMB^v z8Cez+a~?tBChc3p)*Jpz8;d`6$%_%$Ln1WhNenI)x3dEe_2wkojcT1TdfacAqTNZe zygplN;M-;DkI!D*v44(3q zc5N=*&|17wCaxgYwSVv1b6aTpa~0L7dOvP>JO%Nfz3y*bWQ*lE44N$ZQX`v>l4~~H*5b5X(A_H{+kR#DhFPt*! zgk_*v0Ez?#>IY&lh$S)%)E>t~Z-KfQPe)Bj3^WPw98ixEm}n1yj_wBBW*H`Gf}^7f zz>kJ!pe%5w9`slMbr`6bz=uy_qK!a*66BkJ2M@$EV3v0<1N{v0X^`sx{biuH0Fi)Y zqB6i!74(V)Jv;zE3-UlB6I}zd#DIJN;11A6fxG(PJRSHv1hc?0bhH<6R)9+dXaW2( z=;;Pv2_Ob%yMPWQDWUlU7Fvm=qxrz69PqDzb{tQ`P_LaQ1z`l+EPaFBG>-|knM)Q` z&L0zV-=CC2;XkWtwSSXH8g^(DhT*I6IcO3I4op~*ud&m8jcl9`kIAeMYd(= zT+?W59M#>L-(nk&p!|uuqW-EWQWqWFm zPV;C&FOW>vn7l93AMdgEeI)2J??#g1R-!z#ZBzy%(k9}Cmf zaxpjCg6iT0}lXcIoOfmpyDQu?;3kTD1n zfK7dS(x;fr)APE4dQ-};T5iZc;p=3DH4u&t&N!YBl{skjefdU9uZL|4PdM61eI``I z2kQ2*SU$5i4QHE8JdC@dOSd{96g=tcUq!)S$TARCh`~T+_DW}NMDmEuGmB{;t?7sKeh%j=tb-H5Xl+{q?M^)GYw zd*Fw)0r!>myQke=lju2Do#CaAOq7r|s#|b0nYq%C-fpk?v)xu$uf1#SZz~#f?1XO= n=YAjg@PPbGsWv5}Ok}aQrOmJjj*gH$bn|0CZW3cZ({KE5!c=j* delta 1566 zcmYjPeOQZo7=GV(A8l>bP}@+fQ~4;(yUiN;C^3DgacQ+egj1)XGS2eRoN1v#UDYoU zNvWd@DMTMEhA2lUMM_7Gz9=7ODm6#vm+Sm-{&=qExu56$-S_jn*ZaZdr40+$m^b4Z zGhHqLLotjJc)j%2b}BD4ZR#E-4;S!60-->#nq|hvaX!xHiRK8?F6~z5+3n#Z{+6R2 zGHgy=QW9_VrIO~`kqHP=Xg@)(%JFR!#rl#VS-kX^VI+QQXPV$gQT2%&VZE z{&bQecH17clRDsj(@U|eq2Av+lC(}2vcBK!^I7ETPi1{Un(CPvNBhSZ<5*jE4{3{# zvc>+9Q;}oE0q-!%pm?S_wnt=jMt9#L$i^x6+6BLJ<|kg#wN5q1T}B4R33{_46x~@x z+Up))dBd8(pm`jIyO*7BpHcVO^PWbH_*(vc#y?X1<9wPLy{= zJX8s9wJ&%TT{#jSdbW@nC+nl<*hIhdQyr)suw1b*(n2)yagnvf1!s(aB51ybb_&lh<0UenQ`pHb7CbEErzykMS#F(%^7R*jm7O*3- zL5c|z@L;cr%mN}38yJX8K!^RU1SY70eH+*hhTO*#7U06z2r&z0Kw^Pb$m@o+3G{dY zaWCW#K?_PumJ-u?E#mSz*zxwng;t} zu$B_6KsI$ekPs(Qog(h?HK+Z>#^_c`vTm2 z?2B5U=qQm$z(~3HEV8NNL9c^Dn|>zaC~*qin#bjH=gz^oJf6TsAms9Joa@5niy-Fm zaSawtHgzJSM6`J~M#P93Y(0!MSTM2^scQN2#?(WKGLT_+Oq(9-2>@+^e}rWNN<|PN z0rA3@VYW!;lt0q5?S0z1GVU3tlw3aLmhxteL%5UcgN^kAw=D2MNNMOkO7mUO)RGW; zVwdaGS7Jl5ZP2xRueXBrvFiqPwkyCk`m}&CUBdr#leEtA4dt;*2S52t<0sQoR;KD( zPfyc5eH}Hc?TVwD8tUqw4ZN3=&()+aE0qL2xNRsHrf%{mupqzd*`F4#H{&2m@Sbk3 z9#ba%P+o>F#W>=`HuQefbmd@kz9gB``0eKJdbuI5vQ=cMh@#LOiBnAnHd!}cmx}ZMqXeVV0{6F1#J9pPM2MTL; zzShQMLL(hP&@o#Iv{e%jPh1SwZS5(aGq2RrL%Y|F6jlB>cRJ%@SkeUd_|cGt8rLE3 zrx?d&`*_p*9z`SFsPz4kt*X2e#3XgBt`cstK6|A&IUoZXCn&4CgH>OTEXi7b(-1Wp znCuzoGU`(ndi(0T(RI1;7XKM%|G0O|m!p>3+hg&!t*vV9_J5Z4?p(8a-;E9TiWI?1 zj+b^^tzF83t7XXxVyIg1Fjuy}wIu0KILqzc%EM2JtM)dcM;(2Zl5jIJ^~XbdRwbc=rPs?h-inD zJL~jCbHSkLE8={a^u9jBQM}++L*1EGij^O2FUm9iy3`o=K>3859?-p4TvsM*wEk>r zIJluNrr~`5s`LLmW9q(E1V29%B5@pUUR7;;F%ap#$4)WpZj1l-xEWph@ToZrPlvwO zqR-Mz#s0rzH|xVY6F|%4`DvMDo&9YkiIHHdy((;bqB6`+*-j94S*z-++pz`xnw(f& G68~SwNOFDv diff --git a/OSX/shared_regressions/si-20-sectrust-policies-data/ids_prod.cer b/OSX/shared_regressions/si-20-sectrust-policies-data/ids_prod.cer deleted file mode 100644 index 4d538bbf724fe032fd8123167341483e65496a37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1930 zcmXqLVsA5OV#`~=%*4pV#3A)>4x>}U?{x;eY@Awc9&O)w85y}*84Pj_)eThHm_u2Z zdE^`m3UX2vf>VpiQi~KEOG`3R^GY(46H7Al^AwyN4HXRJKnl5e#GO-%N;1=6QXrN2 zMVTd)hQbDdAQfCZTo9u?^OE%pxeYi$f^5P}p}_`n;=G3D29}1FMh2#4hNe+Ku7#li zoNEwdC}SW6agK0dX=+iWUTSf%ULwe0ddc~@h5`nB5I3-Ux&$i(2e}eqXA`3mvacCg z8JL?G`56qF7`d357#SJ%&El$4eZYC~2;Z^OqT3#9`mycy+~cthi<_9Ab*1sQ3#^RL zK0PI2n{aoCmyv^hMiZmglUnIljj_Z`!+5$zJnW>rM9uZn*Yl?tWI6 zz4`@nty|vclz8-IFx1VKT=Y`#yQ!ER^93ir>4#Q&%on~<5_8S=aCcRV0vfW(6v(rf8WH!si<64#kCN7a*keZj9Sd^WLu0uLAuPn0!oGWxOjFT=X%1_J8 zN!3kGEJ9DbP4Y#l>6yhPMG(E%9Fv&>%5o)WslG`L$x3Vn%O$3#1I$uGicu{6wF zY#|_l(2N!aGH`9!EQN+#ZV{R;DOeC-@t`!qF3hl#LJl4@Lluzau=-IP6v5csDFKOL zEUppDD$Pp;}8NT&ySu`v{E&F6NlU(jXn^<#m2;+_q6Ee@_frB*rNPi^GV z(k-2W+G{6o{dYy`;2lZE -#import - -#include -#include -#include -#include -#include -#include - -/* Key Constants for Test Dictionaries */ -const NSString *kSecTrustTestMajorTestName = @"MajorTestName"; /* Required; value: string */ -const NSString *kSecTrustTestMinorTestName = @"MinorTestName"; /* Required; value: string */ -const NSString *kSecTrustTestPolicies = @"Policies"; /* Required; value: dictionary or array of dictionaries */ -const NSString *kSecTrustTestLeaf = @"Leaf"; /* Required; value: string */ -const NSString *kSecTrustTestIntermediates = @"Intermediates"; /* Required; value: string or array of strings */ -const NSString *kSecTrustTestAnchors = @"Anchors"; /* Recommended; value: string or array of strings */ -const NSString *kSecTrustTestVerifyDate = @"VerifyDate"; /* Recommended; value: date */ -const NSString *kSecTrustTestExpectedResult = @"ExpectedResult"; /* Required; value: number */ -const NSString *kSecTrustTestChainLength = @"ChainLength"; /* Optional; value: number */ -const NSString *kSecTrustTestEnableTestCerts= @"EnableTestCertificates"; /* Optional; value: string */ - -/* Key Constants for Policies Dictionaries */ -const NSString *kSecTrustTestPolicyOID = @"PolicyIdentifier"; /* Required; value: string */ -const NSString *kSecTrustTestPolicyProperties = @"Properties"; /* Optional; value: dictionary, see Policy Value Constants, SecPolicy.h */ - -const NSString *kSecTrustTestPinningPolicyResources = @"si-20-sectrust-policies-data"; - -@interface TestObject : NSObject -@property (readonly) NSMutableArray *certificates; -@property (readonly) NSMutableArray *policies; -@property (readonly) NSMutableArray *anchors; -@property (readonly) NSString *fullTestName; - -- (id)initWithMajorTestName:(NSString *)majorTestName minorTestName:(NSString *)minorTestName; -- (bool)addLeafToCertificates:(NSString *)leafName; -- (bool)addCertsToArray:(id)pathsObj outputArray:(NSMutableArray *)outArray; -- (bool)addIntermediatesToCertificates:(id)intermediatesObj; -- (bool)addPolicies:(id)policiesObj; -- (bool)addAnchors:(id)anchorsObj; -@end - -@implementation TestObject -#if TARGET_OS_TV -/* Mastering removes all files named i[Pp]hone, so dynamically replace any i[Pp]hone's with - * iPh0ne. We have two copies in the resources directory. */ -- (NSString *)replaceiPhoneNamedFiles:(NSString *)filename { - NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:@"iphone" - options:NSRegularExpressionCaseInsensitive - error:nil]; - NSString *newfilename = [regularExpression stringByReplacingMatchesInString:filename - options:0 - range:NSMakeRange(0, [filename length]) - withTemplate:@"iPh0ne"]; - return newfilename; -} -#endif - -- (id)init { - self = [super init]; - return self; -} - -- (id)initWithMajorTestName:(NSString *)majorTestName minorTestName:(NSString *)minorTestName { - if ((self = [super init])) { - _fullTestName = [[majorTestName stringByAppendingString:@"-"] stringByAppendingString:minorTestName]; - } - return self; -} - -- (bool)addLeafToCertificates:(NSString *)leafName { - SecCertificateRef cert; - NSString *path = nil, *filename = nil; - require_action_quiet(leafName, errOut, - fail("%@: failed to get leaf for test", _fullTestName)); -#if TARGET_OS_TV - filename = [self replaceiPhoneNamedFiles:leafName]; -#else - filename = leafName; -#endif - - path = [[NSBundle mainBundle] - pathForResource:filename - ofType:@"cer" - inDirectory:(NSString *)kSecTrustTestPinningPolicyResources]; - require_action_quiet(path, errOut, fail("%@: failed to get path for leaf %@", _fullTestName, filename)); - cert = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); - require_action_quiet(cert, errOut, - fail("%@: failed to create leaf certificate from path %@", - _fullTestName, path)); - _certificates = [[NSMutableArray alloc] initWithObjects:(__bridge id)cert, nil]; - CFReleaseNull(cert); - require_action_quiet(_certificates, errOut, - fail("%@: failed to initialize certificates array", - _fullTestName)); - return true; - -errOut: - return false; -} - -- (bool)addCertsToArray:(id)pathsObj outputArray:(NSMutableArray *)outArray { - __block SecCertificateRef cert = NULL; - __block NSString* path = nil, *filename = nil; - require_action_quiet(pathsObj, errOut, - fail("%@: failed to get certificate paths for test", _fullTestName)); - - if ([pathsObj isKindOfClass:[NSString class]]) { - /* Only one cert path */ -#if TARGET_OS_TV - filename = [self replaceiPhoneNamedFiles:pathsObj]; -#else - filename = pathsObj; -#endif - path = [[NSBundle mainBundle] - pathForResource:filename - ofType:@"cer" - inDirectory:(NSString *)kSecTrustTestPinningPolicyResources]; - require_action_quiet(path, errOut, fail("%@: failed to get path for cert %@", - _fullTestName, filename)); - cert = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); - require_action_quiet(cert, errOut, - fail("%@: failed to create certificate from path %@", - _fullTestName, path)); - [outArray addObject:(__bridge id)cert]; - CFReleaseNull(cert); - } - - else if ([pathsObj isKindOfClass:[NSArray class]]) { - /* Test has more than one intermediate */ - [(NSArray *)pathsObj enumerateObjectsUsingBlock:^(NSString *resource, NSUInteger idx, BOOL *stop) { -#if TARGET_OS_TV - filename = [self replaceiPhoneNamedFiles:resource]; -#else - filename = resource; -#endif - path = [[NSBundle mainBundle] - pathForResource:filename - ofType:@"cer" - inDirectory:(NSString *)kSecTrustTestPinningPolicyResources]; - require_action_quiet(path, blockOut, - fail("%@: failed to get path for cert %ld, %@", - self->_fullTestName, (unsigned long)idx, filename)); - cert = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); - require_action_quiet(cert, blockOut, - fail("%@: failed to create certificate %ld from path %@", - self->_fullTestName, (unsigned long) idx, path)); - [outArray addObject:(__bridge id)cert]; - - CFReleaseNull(cert); - return; - - blockOut: - CFReleaseNull(cert); - *stop = YES; - }]; - } - - else { - fail("%@: unexpected type for intermediates or anchors value", _fullTestName); - goto errOut; - } - - return true; - -errOut: - CFReleaseNull(cert); - return false; - -} - -- (bool)addIntermediatesToCertificates:(id)intermediatesObj { - require_action_quiet(intermediatesObj, errOut, - fail("%@: failed to get intermediates for test", _fullTestName)); - - require_action_quiet([self addCertsToArray:intermediatesObj outputArray:_certificates], errOut, - fail("%@: failed to add intermediates to certificates array", _fullTestName)); - - if ([intermediatesObj isKindOfClass:[NSString class]]) { - require_action_quiet([_certificates count] == 2, errOut, - fail("%@: failed to add all intermediates", _fullTestName)); - } else if ([intermediatesObj isKindOfClass:[NSArray class]]) { - require_action_quiet([_certificates count] == [(NSArray *)intermediatesObj count] + 1, errOut, - fail("%@: failed to add all intermediates", _fullTestName)); - } - - return true; - -errOut: - return false; -} - -- (bool)addPolicies:(id)policiesObj { - __block SecPolicyRef policy = NULL; - require_action_quiet(policiesObj, errOut, - fail("%@: failed to get policies for test", _fullTestName)); - - _policies = [[NSMutableArray alloc] init]; - require_action_quiet(_policies, errOut, - fail("%@: failed to initialize policies array", _fullTestName)); - if ([policiesObj isKindOfClass:[NSDictionary class]]) { - /* Test has only one policy */ - NSString *policyIdentifier = [(NSDictionary *)policiesObj objectForKey:kSecTrustTestPolicyOID]; - NSDictionary *policyProperties = [(NSDictionary *)policiesObj objectForKey:kSecTrustTestPolicyProperties]; - require_action_quiet(policyIdentifier, errOut, fail("%@: failed to get policy OID", _fullTestName)); - - policy = SecPolicyCreateWithProperties((__bridge CFStringRef)policyIdentifier, - (__bridge CFDictionaryRef)policyProperties); - require_action_quiet(policy, errOut, - fail("%@: failed to create properties for policy OID %@", - _fullTestName, policyIdentifier)); - [_policies addObject:(__bridge id)policy]; - CFReleaseNull(policy); - } - - else if ([policiesObj isKindOfClass:[NSArray class]]) { - /* Test more than one intermediate */ - [(NSArray *)policiesObj enumerateObjectsUsingBlock:^(NSDictionary *policyDict, NSUInteger idx, BOOL *stop) { - NSString *policyIdentifier = [(NSDictionary *)policyDict objectForKey:kSecTrustTestPolicyOID]; - NSDictionary *policyProperties = [(NSDictionary *)policyDict objectForKey:kSecTrustTestPolicyProperties]; - require_action_quiet(policyIdentifier, blockOut, fail("%@: failed to get policy OID", self->_fullTestName)); - - policy = SecPolicyCreateWithProperties((__bridge CFStringRef)policyIdentifier, - (__bridge CFDictionaryRef)policyProperties); - require_action_quiet(policy, blockOut, - fail("%@: failed to create properties for policy OID %@", - self->_fullTestName, policyIdentifier)); - [self->_policies addObject:(__bridge id)policy]; - - CFReleaseNull(policy); - return; - - blockOut: - CFReleaseNull(policy); - *stop = YES; - }]; - - require_action_quiet([(NSArray *)policiesObj count] == [_policies count], errOut, - fail("%@: failed to add all policies", _fullTestName)); - } - - else { - fail("%@: unexpected type for %@ value", _fullTestName, kSecTrustTestPolicies); - goto errOut; - } - - return true; - -errOut: - CFReleaseNull(policy); - return false; -} - -- (bool)addAnchors:(id)anchorsObj { - require_action_quiet(anchorsObj, errOut, - fail("%@: failed to get anchors for test", _fullTestName)); - - _anchors = [[NSMutableArray alloc] init]; - require_action_quiet(_anchors, errOut, - fail("%@: failed to initialize anchors array", _fullTestName)); - require_action_quiet([self addCertsToArray:anchorsObj outputArray:_anchors], errOut, - fail("%@: failed to add anchors to anchors array", _fullTestName)); - - if ([anchorsObj isKindOfClass:[NSString class]]) { - require_action_quiet([_anchors count] == 1, errOut, - fail("%@: failed to add all anchors", _fullTestName)); - } else if ([anchorsObj isKindOfClass:[NSArray class]]) { - require_action_quiet([_anchors count] == [(NSArray *)anchorsObj count], errOut, - fail("%@: failed to add all anchors", _fullTestName)); - } - - return true; - -errOut: - return false; -} - -@end - -void (^runPolicyTestForObject)(id, NSUInteger, BOOL *) = -^(NSDictionary *testDict, NSUInteger idx, BOOL *stop) { - NSString *majorTestName = nil, *minorTestName = nil; - TestObject *test = nil; - SecTrustRef trust = NULL; - SecTrustResultType trustResult = kSecTrustResultInvalid; - NSDate *verifyDate = nil; - NSNumber *expectedResult = nil, *chainLen = nil; - - /* Test certificates work by default on internal builds. We still need this to - * determine whether to expect failure for production devices. */ - bool enableTestCertificates = (bool)[testDict objectForKey:kSecTrustTestEnableTestCerts]; - - /* Test name, for documentation purposes */ - majorTestName = [testDict objectForKey:kSecTrustTestMajorTestName]; - minorTestName = [testDict objectForKey:kSecTrustTestMinorTestName]; - require_action_quiet(majorTestName && minorTestName, testOut, - fail("Failed to create test names for test %lu",(unsigned long)idx)); - test = [[TestObject alloc] initWithMajorTestName:majorTestName minorTestName:minorTestName]; - require_action_quiet((test), testOut, fail("%@-%@: failed to create test object", majorTestName, minorTestName)); - - /* Populate the certificates array */ - require_quiet([test addLeafToCertificates:[testDict objectForKey:kSecTrustTestLeaf]], testOut); - require_quiet([test addIntermediatesToCertificates:[testDict objectForKey:kSecTrustTestIntermediates]], testOut); - - /* Create the policies */ - require_quiet([test addPolicies:[testDict objectForKey:kSecTrustTestPolicies]], testOut); - - /* Create the trust object */ - require_noerr_action_quiet(SecTrustCreateWithCertificates((__bridge CFArrayRef)test.certificates, - (__bridge CFArrayRef)test.policies, - &trust), - testOut, - fail("%@: failed to create trust ref", test.fullTestName)); - - /* Optionally set anchors in trust object */ - if ([testDict objectForKey:kSecTrustTestAnchors]) { - require_quiet([test addAnchors:[testDict objectForKey:kSecTrustTestAnchors]], testOut); - require_noerr_action_quiet(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test.anchors), - testOut, - fail("%@: failed to add anchors to trust ref", test.fullTestName)); - } - - /* Set optional date in trust object */ - verifyDate = [testDict objectForKey:kSecTrustTestVerifyDate]; - if (verifyDate) { - require_noerr_action_quiet(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), testOut, - fail("%@: failed to set verify date, %@, in trust ref", test.fullTestName, - verifyDate)); - } - - /* Evaluate */ - require_noerr_action_quiet(SecTrustEvaluate(trust, &trustResult), testOut, - fail("%@: failed to evaluate trust", test.fullTestName)); - - /* Check results */ - require_action_quiet(expectedResult = [testDict objectForKey:kSecTrustTestExpectedResult], - testOut, fail("%@: failed to get expected result for test", test.fullTestName)); - - /* If we enabled test certificates on a non-internal device, expect a failure instead of success. */ - if (enableTestCertificates && !SecIsInternalRelease() && ([expectedResult unsignedIntValue] == 4)) { - ok(trustResult == 5, - "%@: actual trust result %u did not match expected trust result %u", - test.fullTestName, trustResult, 5); - } else { - ok(trustResult == [expectedResult unsignedIntValue], - "%@: actual trust result %u did not match expected trust result %u", - test.fullTestName, trustResult, [expectedResult unsignedIntValue]); - } - require_quiet(trustResult == [expectedResult unsignedIntValue], testOut); - - require_quiet(chainLen = [testDict objectForKey:kSecTrustTestChainLength], testOut); - require_action_quiet(SecTrustGetCertificateCount(trust) == [chainLen longValue], testOut, - fail("%@: actual chain length %ld did not match expected chain length %ld", - test.fullTestName, SecTrustGetCertificateCount(trust), [chainLen longValue])); - -testOut: - CFReleaseNull(trust); -}; - -static void tests(void) -{ - NSURL *testPlist = nil; - NSArray *testsArray = nil; - - testPlist = [[NSBundle mainBundle] URLForResource:@"debugging" withExtension:@"plist" - subdirectory:(NSString *)kSecTrustTestPinningPolicyResources ]; - if (!testPlist) { - testPlist = [[NSBundle mainBundle] URLForResource:nil withExtension:@"plist" - subdirectory:(NSString *)kSecTrustTestPinningPolicyResources ]; - } - require_action_quiet(testPlist, exit, - fail("Failed to get tests plist from %@", kSecTrustTestPinningPolicyResources)); - - testsArray = [NSArray arrayWithContentsOfURL: testPlist]; - require_action_quiet(testsArray, exit, - fail("Failed to create array from plist")); - - plan_tests((int)[testsArray count]); - - [testsArray enumerateObjectsUsingBlock:runPolicyTestForObject]; - -exit: - return; -} - -int si_20_sectrust_policies(int argc, char *const *argv) -{ - - @autoreleasepool { - tests(); - } - - return 0; -} diff --git a/OSX/shared_regressions/si-44-seckey-aks.m b/OSX/shared_regressions/si-44-seckey-aks.m index 53232555..048929d5 100644 --- a/OSX/shared_regressions/si-44-seckey-aks.m +++ b/OSX/shared_regressions/si-44-seckey-aks.m @@ -146,7 +146,6 @@ static void attestationTest(CFStringRef protection, BOOL noACL) { 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); @@ -176,7 +175,7 @@ static void attestationTest(CFStringRef protection, BOOL noACL) { 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"); + ok([pubUIKPN isEqual:pubUIKCN], "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)); @@ -187,13 +186,28 @@ static void attestationTest(CFStringRef protection, BOOL noACL) { } } -static const uint8_t satori_pub[] = { - 0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46, 0x0d, 0xa6, 0xbd, 0x77, 0x14, 0x65, 0xe5, 0x5a, - 0x14, 0xc9, 0xf8, 0xd8, 0xdd, 0x4c, 0x70, 0x44, 0x50, 0x49, 0xe4, 0xfa, 0x24, 0x71, 0xaa, 0x4c, - 0xe2, 0x74, 0x3b, 0xfd, 0x23, 0xda, 0x6f, 0x92, 0x04, 0x4c, 0x93, 0x6c, 0xea, 0x8a, 0xac, 0x22, - 0x99, 0xd9, 0x6e, 0x3f, 0xed, 0x20, 0xfd, 0xdd, 0x95, 0xe2, 0x32, 0xa0, 0xeb, 0x23, 0xa2, 0xd2, - 0x8b -}; +static void keyFromBlobTest(void) { + NSError *error; + + NSDictionary *keyParams = @{ (id)kSecAttrTokenID: (id)kSecAttrTokenIDAppleKeyStore, + (id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, + (id)kSecAttrIsPermanent: @NO + }; + id privateKeyRef = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)keyParams, (void *)&error)); + ok(privateKeyRef != nil, "Failed to create a random key: %@", error); + + NSDictionary *keyAttrs = CFBridgingRelease(SecKeyCopyAttributes((SecKeyRef)privateKeyRef)); + NSData *keyBlob = keyAttrs[(id)kSecAttrTokenOID]; + + // keyBlob -> SecKey: + NSDictionary *params = @{ (id)kSecAttrTokenID : (id)kSecAttrTokenIDAppleKeyStore, + (id)kSecAttrTokenOID : keyBlob }; + id newKeyRef = CFBridgingRelease(SecKeyCreateWithData((CFDataRef)keyBlob, (CFDictionaryRef)params, (void *)&error)); + ok(newKeyRef != nil, "Failed to create key from data: %@", error); + + id ref; + is_status(SecItemCopyMatching(((__bridge CFDictionaryRef) @{(id)kSecClass: (id)kSecClassKey, (id)kSecValueRef: newKeyRef}), (void *)&ref), errSecItemNotFound); +} static const uint8_t satori_priv[] = { 0x04, 0xe4, 0xef, 0x00, 0x27, 0xcb, 0xa6, 0x46, @@ -414,16 +428,18 @@ int si_44_seckey_aks(int argc, char *const *argv) { testPKA = NO; #endif - plan_tests(testPKA ? 100 : 85); + plan_tests(testPKA ? 102 : 87); + + secKeySepTest(testPKA); + attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, NO); + attestationTest(kSecAttrAccessibleUntilReboot, YES); + keyFromBlobTest(); // Put SEP keys into test-keybag mode. Available only when running in direct-mode, not with extension. SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanTrue, NULL); rewrapTest(); SecKeySetParameter(NULL, kSecAttrTokenIDAppleKeyStore, kCFBooleanFalse, NULL); - secKeySepTest(testPKA); - attestationTest(kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, NO); - attestationTest(kSecAttrAccessibleUntilReboot, YES); return 0; } } diff --git a/OSX/shared_regressions/si-44-seckey-ies.m b/OSX/shared_regressions/si-44-seckey-ies.m index cb477769..5c165492 100644 --- a/OSX/shared_regressions/si-44-seckey-ies.m +++ b/OSX/shared_regressions/si-44-seckey-ies.m @@ -116,6 +116,24 @@ static void test_ecies() { test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM); test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM); + privateKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, +#if TARGET_OS_OSX + (id)kSecUseDataProtectionKeychain: @YES, +#endif + (id)kSecAttrKeySizeInBits: @224}, (void *)&error)); + ok(privateKey, "key generation error %@", error); + error = nil; + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardX963SHA1AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardX963SHA224AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardX963SHA256AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardX963SHA384AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardX963SHA512AESGCM); + + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA224AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA256AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM); + test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM); + privateKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)@{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256}, (void *)&error)); ok(privateKey, "key generation error %@", error); error = nil; @@ -144,7 +162,7 @@ static void test_ecies() { test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM); test_ies_run(privateKey, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM); } -static const int TestCountECIES = TestCountIESRun * 9 * 3 + 3; +static const int TestCountECIES = 4 * (TestCountIESRun * 9 + 1); static void test_rsawrap() { NSError *error; @@ -253,7 +271,7 @@ static void test_against_corecrypto() { NSDictionary *params; NSError *error; - params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @192, (id)kSecAttrNoLegacy: @YES}; + params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @192, (id)kSecUseDataProtectionKeychain: @YES}; privKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error)); ok(privKey != nil, "create key (error %@)", error); error = nil; @@ -268,7 +286,7 @@ static void test_against_corecrypto() { test_ies_against_corecrypto(privKey, ccec_cp_192(), ccsha384_di(), 16, true, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM); test_ies_against_corecrypto(privKey, ccec_cp_192(), ccsha512_di(), 16, true, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM); - params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256, (id)kSecAttrNoLegacy: @YES}; + params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @256, (id)kSecUseDataProtectionKeychain: @YES}; privKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error)); ok(privKey != nil, "create key (error %@)", error); error = nil; @@ -283,7 +301,7 @@ static void test_against_corecrypto() { test_ies_against_corecrypto(privKey, ccec_cp_256(), ccsha384_di(), 16, true, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM); test_ies_against_corecrypto(privKey, ccec_cp_256(), ccsha512_di(), 16, true, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM); - params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @384, (id)kSecAttrNoLegacy: @YES}; + params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @384, (id)kSecUseDataProtectionKeychain: @YES}; privKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error)); ok(privKey != nil, "create key (error %@)", error); error = nil; @@ -298,7 +316,7 @@ static void test_against_corecrypto() { test_ies_against_corecrypto(privKey, ccec_cp_384(), ccsha384_di(), 32, true, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA384AESGCM); test_ies_against_corecrypto(privKey, ccec_cp_384(), ccsha512_di(), 32, true, kSecKeyAlgorithmECIESEncryptionStandardVariableIVX963SHA512AESGCM); - params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @521, (id)kSecAttrNoLegacy: @YES}; + params = @{(id)kSecAttrKeyType: (id)kSecAttrKeyTypeECSECPrimeRandom, (id)kSecAttrKeySizeInBits: @521, (id)kSecUseDataProtectionKeychain: @YES}; privKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error)); ok(privKey != nil, "create key (error %@)", error); error = nil; @@ -320,7 +338,7 @@ static void test_ies_known_ciphertext(CFStringRef keyType, id keySize, SecKeyAlg NSError *error = nil; #if GENERATE_VECTORS - NSDictionary *params = @{(id)kSecAttrKeyType: (__bridge id)keyType, (id)kSecAttrKeySizeInBits: keySize, (id)kSecAttrNoLegacy: @YES}; + NSDictionary *params = @{(id)kSecAttrKeyType: (__bridge id)keyType, (id)kSecAttrKeySizeInBits: keySize, (id)kSecUseDataProtectionKeychain: @YES}; id privKey = CFBridgingRelease(SecKeyCreateRandomKey((CFDictionaryRef)params, (void *)&error)); ok(privKey != nil, "generate key (error %@)", error); #else diff --git a/OSX/shared_regressions/si-44-seckey-skv.m b/OSX/shared_regressions/si-44-seckey-skv.m new file mode 100644 index 00000000..7f348139 --- /dev/null +++ b/OSX/shared_regressions/si-44-seckey-skv.m @@ -0,0 +1,68 @@ +// +// si-44-seckey-skv.m +// + +#import + +#if TARGET_OS_IOS && !TARGET_OS_SIMULATOR +#import "SecureKeyVaultPublic.h" +#import + +#import "shared_regressions.h" + +static void testSecureKeyVaultKeyRawSign() { + id key = CFBridgingRelease(SecKeyCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); + id certificate = CFBridgingRelease(SecCertificateCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); + id pubKey = CFBridgingRelease(SecCertificateCopyPublicKey((SecCertificateRef)certificate)); + + uint8_t hash[20] = { 0 }; + uint8_t signature[256] = { 0 }; + size_t siglen = sizeof(signature); + ok_status(SecKeyRawSign((SecKeyRef)key, kSecPaddingPKCS1SHA1, hash, sizeof(hash), signature, &siglen), "rawSign for fileVault failed"); + ok_status(SecKeyRawVerify((SecKeyRef)pubKey, kSecPaddingPKCS1SHA1, hash, sizeof(hash), signature, siglen), "rawverify for fileVault failed"); +} + +static void testSecureKeyVaultKeySign() { + NSData *data = [@"dataToSign" dataUsingEncoding:NSUTF8StringEncoding]; + NSData *signature; + SecKeyAlgorithm algorithm = NULL; + NSError *error; + id key = CFBridgingRelease(SecKeyCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); + id certificate = CFBridgingRelease(SecCertificateCreateWithSecureKeyVaultID(kCFAllocatorDefault, kSecureKeyVaultIAPAuthPrivateKey)); + id pubKey = CFBridgingRelease(SecCertificateCopyPublicKey((SecCertificateRef)certificate)); + + algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1; + error = nil; + signature = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key, algorithm, (CFDataRef)data, (void *)&error)); + ok(signature != NULL, "signing with alg %@ failed, err %@", algorithm, error); + ok(SecKeyVerifySignature((SecKeyRef)pubKey, algorithm, (CFDataRef)data, (CFDataRef)signature, (void *)&error)); + + algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256; + error = nil; + signature = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key, algorithm, (CFDataRef)data, (void *)&error)); + ok(signature != NULL, "signing with alg %@ failed, err %@", algorithm, error); + ok(SecKeyVerifySignature((SecKeyRef)pubKey, algorithm, (CFDataRef)data, (CFDataRef)signature, (void *)&error)); + + algorithm = kSecKeyAlgorithmRSASignatureMessagePSSSHA1; + error = nil; + signature = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key, algorithm, (CFDataRef)data, (void *)&error)); + ok(signature != NULL, "signing with alg %@ failed, err %@", algorithm, error); + ok(SecKeyVerifySignature((SecKeyRef)pubKey, algorithm, (CFDataRef)data, (CFDataRef)signature, (void *)&error)); + + algorithm = kSecKeyAlgorithmRSASignatureMessagePSSSHA256; + error = nil; + signature = CFBridgingRelease(SecKeyCreateSignature((SecKeyRef)key, algorithm, (CFDataRef)data, (void *)&error)); + ok(signature != NULL, "signing with alg %@ failed, err %@", algorithm, error); + ok(SecKeyVerifySignature((SecKeyRef)pubKey, algorithm, (CFDataRef)data, (CFDataRef)signature, (void *)&error)); +} + +int si_44_seckey_skv(int argc, char *const *argv) { + @autoreleasepool { + plan_tests(10); + testSecureKeyVaultKeyRawSign(); + testSecureKeyVaultKeySign(); + return 0; + } +} + +#endif diff --git a/OSX/shared_regressions/si-82-seccertificate-ct.c b/OSX/shared_regressions/si-82-seccertificate-ct.c deleted file mode 100644 index b2dafa31..00000000 --- a/OSX/shared_regressions/si-82-seccertificate-ct.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * si-82-seccertificate-ct.c - * Security - * - * Copyright (c) 2014 Apple Inc. All Rights Reserved. - * - */ - -#include -#include -#include -#include -#include - -#include "shared_regressions.h" - -static -unsigned char serverF_cert_der[] = { - 0x30, 0x82, 0x03, 0x73, 0x30, 0x82, 0x02, 0xdc, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x52, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1a, - 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x63, 0x6f, 0x72, - 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, - 0x43, 0x41, 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, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x32, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, - 0x17, 0x0d, 0x32, 0x32, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x0e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, - 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 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, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x63, - 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, - 0x74, 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, 0xd2, 0x49, 0x0c, 0xd0, 0xc5, 0xa8, 0xc3, 0x0f, - 0x36, 0x99, 0x54, 0x00, 0xd7, 0xf0, 0x2a, 0xcb, 0x21, 0x20, 0x4c, 0xac, - 0xaa, 0xcb, 0x36, 0x20, 0x72, 0x78, 0x05, 0xd1, 0xc2, 0xf9, 0xce, 0xc9, - 0x5b, 0xbc, 0x38, 0xda, 0xdd, 0x27, 0xf7, 0x6b, 0x0a, 0xf0, 0x16, 0xe2, - 0xc9, 0x74, 0x8c, 0x47, 0x5b, 0x07, 0x91, 0xa5, 0x6c, 0xcf, 0xf9, 0x0a, - 0x05, 0xb3, 0x05, 0x6a, 0xbe, 0x59, 0xdb, 0xa2, 0x1b, 0x21, 0x29, 0xe1, - 0xef, 0x0d, 0x4f, 0xa1, 0xc5, 0xbd, 0x16, 0xeb, 0x8c, 0x45, 0x6f, 0x64, - 0x42, 0x93, 0x82, 0xb3, 0x6d, 0xff, 0x83, 0x61, 0xdc, 0xcf, 0x8d, 0xd0, - 0x09, 0x2c, 0x37, 0x87, 0x1b, 0x75, 0xf6, 0xb3, 0xf8, 0x45, 0xef, 0xe2, - 0xcb, 0xff, 0x6d, 0xbb, 0xe4, 0xa5, 0x29, 0xee, 0xc0, 0x78, 0x17, 0x94, - 0xdc, 0x6b, 0xc7, 0x46, 0x01, 0x74, 0xf9, 0x65, 0x3b, 0x59, 0x21, 0xf5, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x37, 0x30, 0x82, 0x01, - 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, - 0x69, 0x9d, 0x9f, 0x7e, 0xd9, 0x34, 0x7c, 0xfa, 0xd5, 0xc2, 0x7e, 0x02, - 0x0f, 0x1e, 0x4d, 0x1d, 0xa9, 0x8e, 0xa8, 0xcb, 0x30, 0x7a, 0x06, 0x03, - 0x55, 0x1d, 0x23, 0x04, 0x73, 0x30, 0x71, 0x80, 0x14, 0xdc, 0x16, 0x44, - 0x15, 0x3e, 0x53, 0x27, 0xd8, 0x68, 0x66, 0x41, 0x40, 0x88, 0x90, 0xe4, - 0x4e, 0x0a, 0xda, 0x08, 0xa9, 0xa1, 0x56, 0xa4, 0x54, 0x30, 0x52, 0x31, - 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, - 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x63, - 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, - 0x74, 0x20, 0x43, 0x41, 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, 0x82, 0x01, 0x01, - 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, - 0x81, 0x8a, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, - 0x04, 0x02, 0x04, 0x7c, 0x04, 0x7a, 0x00, 0x78, 0x00, 0x76, 0x00, 0xab, - 0xa8, 0xb5, 0xb4, 0x7d, 0x00, 0x00, 0x1b, 0x46, 0x58, 0x28, 0xc4, 0x0a, - 0xc7, 0x0b, 0x03, 0xf6, 0x91, 0x70, 0xa3, 0x5f, 0xed, 0xc8, 0x74, 0x40, - 0x3c, 0xd0, 0x58, 0x1d, 0x3c, 0x8c, 0x16, 0x00, 0x00, 0x01, 0x47, 0xdc, - 0x04, 0xbc, 0x5a, 0x00, 0x00, 0x04, 0x03, 0x00, 0x47, 0x30, 0x45, 0x02, - 0x20, 0x5b, 0x3b, 0xe2, 0x6b, 0xa2, 0xda, 0x49, 0xb2, 0xa5, 0x55, 0x1d, - 0x2f, 0x4d, 0x21, 0x2e, 0x2d, 0xf7, 0x59, 0xb3, 0x22, 0x1d, 0x90, 0x38, - 0x88, 0x77, 0xad, 0x49, 0xca, 0x28, 0x1d, 0x4a, 0xa8, 0x02, 0x21, 0x00, - 0xb7, 0x08, 0x08, 0xfb, 0x6a, 0x06, 0x13, 0xaa, 0xe6, 0x4d, 0x69, 0x44, - 0xce, 0xc0, 0x17, 0x8f, 0x3e, 0x80, 0x30, 0xe2, 0xd0, 0xe1, 0x8b, 0xc0, - 0x34, 0x28, 0x8b, 0xd8, 0x85, 0xb5, 0x14, 0x97, 0x30, 0x0d, 0x06, 0x09, - 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, - 0x81, 0x81, 0x00, 0xae, 0x8c, 0x7f, 0x63, 0x9d, 0xdd, 0xee, 0x4f, 0xc4, - 0xc5, 0x7b, 0x20, 0xb5, 0xe8, 0x89, 0x3e, 0x2c, 0xfe, 0x36, 0x0e, 0x31, - 0x1a, 0x38, 0xd6, 0xb3, 0xfd, 0x37, 0xeb, 0x26, 0xd0, 0x27, 0xfa, 0x04, - 0x12, 0x9c, 0xe2, 0x20, 0xe1, 0x61, 0xbf, 0xee, 0x60, 0x45, 0x84, 0xa0, - 0xea, 0xce, 0x1f, 0xf7, 0x73, 0x31, 0xd4, 0xd7, 0x87, 0xe7, 0xd5, 0x9f, - 0xff, 0x8d, 0x14, 0x32, 0x22, 0x89, 0xf6, 0x31, 0x38, 0xef, 0x1c, 0x36, - 0x55, 0x0d, 0x5f, 0x0d, 0x99, 0x36, 0x58, 0x6a, 0xa3, 0xff, 0xf0, 0xc7, - 0xe0, 0x5e, 0x02, 0x20, 0x9f, 0x04, 0x0a, 0xa4, 0xba, 0x1a, 0x1c, 0xb2, - 0x43, 0x85, 0xc2, 0xcc, 0xd2, 0x95, 0x8f, 0x20, 0x11, 0x1d, 0xea, 0x9e, - 0x10, 0xf1, 0x45, 0xd2, 0x4d, 0x95, 0x80, 0xed, 0xe1, 0x86, 0x71, 0xee, - 0x50, 0x0f, 0xb0, 0x73, 0x12, 0x32, 0xdd, 0x95, 0xc5, 0xb9, 0x54 -}; - - -__unused -static -unsigned char serverF_pre_cert_der[] = { - 0x30, 0x82, 0x02, 0xf9, 0x30, 0x82, 0x02, 0x62, 0xa0, 0x03, 0x02, 0x01, - 0x02, 0x02, 0x01, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, - 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x52, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1a, - 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x63, 0x6f, 0x72, - 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, - 0x43, 0x41, 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, 0x30, 0x1e, 0x17, 0x0d, 0x31, - 0x32, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, - 0x17, 0x0d, 0x32, 0x32, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, - 0x30, 0x30, 0x5a, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, - 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, - 0x55, 0x04, 0x0a, 0x0c, 0x0e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, - 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 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, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x63, - 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, - 0x74, 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, 0xd2, 0x49, 0x0c, 0xd0, 0xc5, 0xa8, 0xc3, 0x0f, - 0x36, 0x99, 0x54, 0x00, 0xd7, 0xf0, 0x2a, 0xcb, 0x21, 0x20, 0x4c, 0xac, - 0xaa, 0xcb, 0x36, 0x20, 0x72, 0x78, 0x05, 0xd1, 0xc2, 0xf9, 0xce, 0xc9, - 0x5b, 0xbc, 0x38, 0xda, 0xdd, 0x27, 0xf7, 0x6b, 0x0a, 0xf0, 0x16, 0xe2, - 0xc9, 0x74, 0x8c, 0x47, 0x5b, 0x07, 0x91, 0xa5, 0x6c, 0xcf, 0xf9, 0x0a, - 0x05, 0xb3, 0x05, 0x6a, 0xbe, 0x59, 0xdb, 0xa2, 0x1b, 0x21, 0x29, 0xe1, - 0xef, 0x0d, 0x4f, 0xa1, 0xc5, 0xbd, 0x16, 0xeb, 0x8c, 0x45, 0x6f, 0x64, - 0x42, 0x93, 0x82, 0xb3, 0x6d, 0xff, 0x83, 0x61, 0xdc, 0xcf, 0x8d, 0xd0, - 0x09, 0x2c, 0x37, 0x87, 0x1b, 0x75, 0xf6, 0xb3, 0xf8, 0x45, 0xef, 0xe2, - 0xcb, 0xff, 0x6d, 0xbb, 0xe4, 0xa5, 0x29, 0xee, 0xc0, 0x78, 0x17, 0x94, - 0xdc, 0x6b, 0xc7, 0x46, 0x01, 0x74, 0xf9, 0x65, 0x3b, 0x59, 0x21, 0xf5, - 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xbe, 0x30, 0x81, 0xbb, 0x30, - 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x69, 0x9d, - 0x9f, 0x7e, 0xd9, 0x34, 0x7c, 0xfa, 0xd5, 0xc2, 0x7e, 0x02, 0x0f, 0x1e, - 0x4d, 0x1d, 0xa9, 0x8e, 0xa8, 0xcb, 0x30, 0x7a, 0x06, 0x03, 0x55, 0x1d, - 0x23, 0x04, 0x73, 0x30, 0x71, 0x80, 0x14, 0xdc, 0x16, 0x44, 0x15, 0x3e, - 0x53, 0x27, 0xd8, 0x68, 0x66, 0x41, 0x40, 0x88, 0x90, 0xe4, 0x4e, 0x0a, - 0xda, 0x08, 0xa9, 0xa1, 0x56, 0xa4, 0x54, 0x30, 0x52, 0x31, 0x0b, 0x30, - 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1a, - 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x63, 0x6f, 0x72, - 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, - 0x43, 0x41, 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, 0x82, 0x01, 0x01, 0x30, 0x09, - 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x13, 0x06, - 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x04, 0x03, 0x01, - 0x01, 0xff, 0x04, 0x02, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, - 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, - 0x00, 0x66, 0x40, 0xd9, 0x60, 0xc6, 0x02, 0x39, 0x87, 0xc1, 0x15, 0x8e, - 0x3a, 0x3c, 0x4b, 0xf1, 0x29, 0xe7, 0x73, 0xbf, 0xca, 0xb4, 0x3c, 0x07, - 0x85, 0x9b, 0x8f, 0x2f, 0x23, 0xa9, 0x61, 0x58, 0x49, 0x04, 0xeb, 0xd5, - 0x6c, 0x4b, 0x2b, 0x4a, 0xd0, 0x73, 0xf1, 0xf2, 0x7a, 0x4a, 0x36, 0xd0, - 0x17, 0x1f, 0x61, 0xf8, 0xcf, 0xd7, 0xf4, 0x2c, 0x1a, 0x9d, 0x6a, 0xb0, - 0x5f, 0x3f, 0x06, 0xb5, 0xd0, 0x77, 0x18, 0x76, 0x69, 0x38, 0x3c, 0xc9, - 0x5e, 0xc7, 0x51, 0x12, 0xf2, 0x7a, 0xdf, 0xf7, 0x88, 0x70, 0x1f, 0xaf, - 0x3e, 0x50, 0xde, 0x95, 0x43, 0x1f, 0xee, 0x19, 0x80, 0xca, 0x7d, 0x7d, - 0x97, 0xce, 0x4f, 0x85, 0xbb, 0x7e, 0x5c, 0x67, 0xfe, 0x58, 0xb5, 0xf7, - 0xd2, 0x0c, 0x08, 0x64, 0xbe, 0x08, 0x49, 0x6d, 0xca, 0xbd, 0xd4, 0x54, - 0xa2, 0x8c, 0xeb, 0xe0, 0xa0, 0xa6, 0x0b, 0x39, 0x0c -}; - - -__unused -static -unsigned char serverF_pre_cert_proof[] = { - 0x00, 0xab, 0xa8, 0xb5, 0xb4, 0x7d, 0x00, 0x00, 0x1b, 0x46, 0x58, 0x28, - 0xc4, 0x0a, 0xc7, 0x0b, 0x03, 0xf6, 0x91, 0x70, 0xa3, 0x5f, 0xed, 0xc8, - 0x74, 0x40, 0x3c, 0xd0, 0x58, 0x1d, 0x3c, 0x8c, 0x16, 0x00, 0x00, 0x01, - 0x47, 0xdc, 0x04, 0xbc, 0x5a, 0x00, 0x00, 0x04, 0x03, 0x00, 0x47, 0x30, - 0x45, 0x02, 0x20, 0x5b, 0x3b, 0xe2, 0x6b, 0xa2, 0xda, 0x49, 0xb2, 0xa5, - 0x55, 0x1d, 0x2f, 0x4d, 0x21, 0x2e, 0x2d, 0xf7, 0x59, 0xb3, 0x22, 0x1d, - 0x90, 0x38, 0x88, 0x77, 0xad, 0x49, 0xca, 0x28, 0x1d, 0x4a, 0xa8, 0x02, - 0x21, 0x00, 0xb7, 0x08, 0x08, 0xfb, 0x6a, 0x06, 0x13, 0xaa, 0xe6, 0x4d, - 0x69, 0x44, 0xce, 0xc0, 0x17, 0x8f, 0x3e, 0x80, 0x30, 0xe2, 0xd0, 0xe1, - 0x8b, 0xc0, 0x34, 0x28, 0x8b, 0xd8, 0x85, 0xb5, 0x14, 0x97 -}; - - -static void tests() -{ - SecCertificateRef certF = NULL; - - CFDataRef precertTBS = NULL; - CFArrayRef proofs = NULL; - CFDataRef spkiDigest = NULL; - - isnt(certF = SecCertificateCreateWithBytes(NULL, serverF_cert_der, sizeof(serverF_cert_der)), NULL, "create certF"); - - isnt(precertTBS = SecCertificateCopyPrecertTBS(certF), NULL, "copy precertTBS"); - - isnt(spkiDigest = SecCertificateCopySubjectPublicKeyInfoSHA256Digest(certF), NULL, "copy SPKI digest"); - - isnt(proofs = SecCertificateCopySignedCertificateTimestamps(certF), NULL, "copy SCTs"); - - CFReleaseSafe(certF); - CFReleaseSafe(precertTBS); - CFReleaseSafe(proofs); - CFReleaseSafe(spkiDigest); - -} - -int si_82_seccertificate_ct(int argc, char *const *argv) -{ - plan_tests(4); - - tests(); - - return 0; -} diff --git a/OSX/shared_regressions/si-82-sectrust-ct.m b/OSX/shared_regressions/si-82-sectrust-ct.m deleted file mode 100644 index 63615768..00000000 --- a/OSX/shared_regressions/si-82-sectrust-ct.m +++ /dev/null @@ -1,1446 +0,0 @@ -/* - * si-82-sectrust-ct.c - * Security - * - * Copyright (c) 2014 Apple Inc. All Rights Reserved. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if TARGET_OS_IPHONE -#include -#else -#include -#endif - -#include "shared_regressions.h" -#include "si-82-sectrust-ct.h" - -//define this if you want to print clock time of SecTrustEvaluate call. -//define PRINT_SECTRUST_EVALUATE_TIME - -static bool isCFTrue(CFTypeRef cf) -{ - return (cf == kCFBooleanTrue); -} - -static void test_ct_trust(CFArrayRef certs, CFArrayRef scts, CFTypeRef ocspresponses, CFArrayRef anchors, - CFArrayRef trustedLogs, CFStringRef hostname, CFDateRef date, - bool ct_expected, bool ev_expected, bool ct_whitelist_expected, - const char *test_name) -{ - CFArrayRef policies=NULL; - SecPolicyRef policy=NULL; - SecTrustRef trust=NULL; - SecTrustResultType trustResult; - CFDictionaryRef results=NULL; - CFArrayRef properties=NULL; - - - - 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"); - - assert(trust); // silence analyzer - if(anchors) { - ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchors"); - } - - if(scts) { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - ok_status(SecTrustSetSignedCertificateTimestamps(trust, scts), "set standalone SCTs"); -#pragma clang diagnostic pop - } - - if(trustedLogs) { - ok_status(SecTrustSetTrustedLogs(trust, trustedLogs), "set trusted logs"); - } - - if(ocspresponses) { - ok_status(SecTrustSetOCSPResponse(trust, ocspresponses), "set ocsp responses"); - } - - if (!date) { goto errOut; } - ok_status(SecTrustSetVerifyDate(trust, date), "set date"); -#ifdef PRINT_SECTRUST_EVALUATE_TIME - clock_t t0 = clock(); -#endif - ok_status(SecTrustEvaluate(trust, &trustResult), "evaluate trust"); -#ifdef PRINT_SECTRUST_EVALUATE_TIME - clock_t t1 = clock() - t0; -#endif - ok(trustResult == kSecTrustResultUnspecified, "trustResult 4 expected (got %d)", - (int)trustResult); - - results = SecTrustCopyResult(trust); - - CFTypeRef ct = CFDictionaryGetValue(results, kSecTrustCertificateTransparency); - CFTypeRef ev = CFDictionaryGetValue(results, kSecTrustExtendedValidation); - CFTypeRef ct_whitelist = CFDictionaryGetValue(results, kSecTrustCertificateTransparencyWhiteList); - - - ok((isCFTrue(ct) == ct_expected), "unexpected CT result (%s)", test_name); - ok((isCFTrue(ev) == ev_expected), "unexpected EV result (%s)", test_name); - ok((isCFTrue(ct_whitelist) == ct_whitelist_expected), "unexpected CT WhiteList result (%s)", test_name); - /* Note that the CT whitelist has been removed due to the expiration of all contents. */ - -#ifdef PRINT_SECTRUST_EVALUATE_TIME - printf("%s: %lu\n", test_name, t1); -#endif - - properties = SecTrustCopyProperties(trust); - -errOut: - CFReleaseSafe(policy); - CFReleaseSafe(policies); - CFReleaseSafe(trust); - CFReleaseSafe(results); - CFReleaseSafe(properties); -} - -#import - -static -SecCertificateRef SecCertificateCreateFromResource(NSString *name) -{ - NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"]; - - NSData *certData = [NSData dataWithContentsOfURL:url]; - - SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData); - - return cert; -} - -static -CFDataRef CFDataCreateFromResource(NSString *name) -{ - NSURL *url = [[NSBundle mainBundle] URLForResource:name withExtension:@".bin" subdirectory:@"si-82-sectrust-ct-data"]; - - NSData *binData = [[NSData alloc] initWithContentsOfURL:url]; - - return (__bridge_retained CFDataRef) binData; -} - -static CFArrayRef CTTestsCopyTrustedLogs(void) { - CFArrayRef trustedLogs=NULL; - CFURLRef trustedLogsURL=NULL; - - trustedLogsURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), - CFSTR("CTlogs"), - CFSTR("plist"), - CFSTR("si-82-sectrust-ct-data")); - isnt(trustedLogsURL, NULL, "trustedLogsURL"); - trustedLogs = (CFArrayRef) CFPropertyListReadFromFile(trustedLogsURL); - isnt(trustedLogs, NULL, "trustedLogs"); - - CFReleaseNull(trustedLogsURL); - return trustedLogs; -} - -static void tests() -{ - SecCertificateRef certA=NULL, certD=NULL, certF=NULL, certCA_alpha=NULL, certCA_beta=NULL; - CFDataRef proofD=NULL, proofA_1=NULL, proofA_2=NULL; - SecCertificateRef www_digicert_com_2015_cert=NULL, www_digicert_com_2016_cert=NULL, digicert_sha2_ev_server_ca=NULL; - SecCertificateRef pilot_cert_3055998=NULL, pilot_cert_3055998_issuer=NULL; - SecCertificateRef whitelist_00008013=NULL, whitelist_5555bc4f=NULL, whitelist_aaaae152=NULL, whitelist_fff9b5f6=NULL; - SecCertificateRef whitelist_00008013_issuer=NULL, whitelist_5555bc4f_issuer=NULL, whitelist_fff9b5f6_issuer=NULL; - SecCertificateRef cfCert = NULL; - CFMutableArrayRef certs=NULL; - CFMutableArrayRef scts=NULL; - CFMutableArrayRef anchors=NULL; - CFDataRef valid_ocsp=NULL; - CFDataRef invalid_ocsp=NULL; - CFDataRef bad_hash_ocsp=NULL; - - CFArrayRef trustedLogs= CTTestsCopyTrustedLogs(); - - isnt(certCA_alpha = SecCertificateCreateFromResource(@"CA_alpha"), NULL, "create ca-alpha cert"); - isnt(certCA_beta = SecCertificateCreateFromResource(@"CA_beta"), NULL, "create ca-beta cert"); - isnt(anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create anchors array"); - CFArrayAppendValue(anchors, certCA_alpha); - CFArrayAppendValue(anchors, certCA_beta); - isnt(certA = SecCertificateCreateFromResource(@"serverA"), NULL, "create certA"); - isnt(certD = SecCertificateCreateFromResource(@"serverD"), NULL, "create certD"); - isnt(certF = SecCertificateCreateFromResource(@"serverF"), NULL, "create certF"); - isnt(proofD = CFDataCreateFromResource(@"serverD_proof"), NULL, "creat proofD"); - isnt(proofA_1 = CFDataCreateFromResource(@"serverA_proof_Alfa_3"), NULL, "creat proofA_1"); - isnt(proofA_2 = CFDataCreateFromResource(@"serverA_proof_Bravo_3"), NULL, "creat proofA_2"); - isnt(www_digicert_com_2015_cert = SecCertificateCreateFromResource(@"www_digicert_com_2015"), NULL, "create www.digicert.com 2015 cert"); - isnt(www_digicert_com_2016_cert = SecCertificateCreateFromResource(@"www_digicert_com_2016"), NULL, "create www.digicert.com 2016 cert"); - isnt(digicert_sha2_ev_server_ca = SecCertificateCreateFromResource(@"digicert_sha2_ev_server_ca"), NULL, "create digicert.com subCA cert"); - isnt(valid_ocsp = CFDataCreateFromResource(@"valid_ocsp_response"), NULL, "create valid_ocsp"); - isnt(invalid_ocsp = CFDataCreateFromResource(@"invalid_ocsp_response"), NULL, "create invalid_ocsp"); - isnt(bad_hash_ocsp = CFDataCreateFromResource(@"bad_hash_ocsp_response"), NULL, "create bad_hash_ocsp"); - isnt(pilot_cert_3055998 = SecCertificateCreateFromResource(@"pilot_3055998"), NULL, "create pilot_cert_3055998 cert"); - isnt(pilot_cert_3055998_issuer = SecCertificateCreateFromResource(@"pilot_3055998_issuer"), NULL, "create pilot_cert_3055998 issuer cert"); - - isnt(whitelist_00008013 = SecCertificateCreateFromResource(@"whitelist_00008013"), NULL, "create whitelist_00008013 cert"); - isnt(whitelist_5555bc4f = SecCertificateCreateFromResource(@"whitelist_5555bc4f"), NULL, "create whitelist_5555bc4f cert"); - isnt(whitelist_aaaae152 = SecCertificateCreateFromResource(@"whitelist_aaaae152"), NULL, "create whitelist_aaaae152 cert"); - isnt(whitelist_fff9b5f6 = SecCertificateCreateFromResource(@"whitelist_fff9b5f6"), NULL, "create whitelist_fff9b5f6 cert"); - isnt(whitelist_00008013_issuer = SecCertificateCreateFromResource(@"whitelist_00008013_issuer"), NULL, "create whitelist_00008013_issuer cert"); - isnt(whitelist_5555bc4f_issuer = SecCertificateCreateFromResource(@"whitelist_5555bc4f_issuer"), NULL, "create whitelist_5555bc4f_issuer cert"); - isnt(whitelist_fff9b5f6_issuer = SecCertificateCreateFromResource(@"whitelist_fff9b5f6_issuer"), NULL, "create whitelist_fff9b5f6_issuer cert"); - - CFCalendarRef cal = NULL; - CFAbsoluteTime at; - CFDateRef date_20150307 = NULL; // Date for older set of tests. - CFDateRef date_20160422 = NULL; // Date for newer set of tests. - - isnt(cal = CFCalendarCreateWithIdentifier(kCFAllocatorDefault, kCFGregorianCalendar), NULL, "create calendar"); - ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2015, 3, 7), "create verify absolute time 20150307"); - isnt(date_20150307 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20150307"); - ok(CFCalendarComposeAbsoluteTime(cal, &at, "yMd", 2016, 4, 22), "create verify absolute time 20160422"); - isnt(date_20160422 = CFDateCreate(kCFAllocatorDefault, at), NULL, "create verify date 20160422"); - - - /* 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, NULL, date_20150307, - false, false, false, "coreos-ct-test 1"); - CFReleaseNull(certs); - - /* Case 2: coreos-ct-test standalone SCT - only 1 SCT - so not CT qualified */ - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, certD); - isnt(scts = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create SCT array"); - CFArrayAppendValue(scts, proofD); - test_ct_trust(certs, scts, NULL, anchors, trustedLogs, NULL, date_20150307, - false, false, false, "coreos-ct-test 2"); - CFReleaseNull(certs); - CFReleaseNull(scts); - - /* case 3: digicert : 2 embedded SCTs, but lifetime of cert is 24 month, so not CT qualified */ - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, www_digicert_com_2015_cert); - CFArrayAppendValue(certs, digicert_sha2_ev_server_ca); - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.digicert.com"), date_20150307, - false, false, false, "digicert 2015"); - CFReleaseNull(certs); - - /* 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, NULL, date_20150307, - true, false, false, "coreos-ct-test 3"); - CFReleaseNull(certs); - CFReleaseNull(scts); - - /* 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, NULL, date_20150307, - false, false, false, "coreos-ct-test 4"); - CFReleaseNull(certs); - CFReleaseNull(scts); - - /* 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, NULL, date_20150307, - false, false, false, "coreos-ct-test 5"); - CFReleaseNull(certs); - CFReleaseNull(scts); - - /* 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, NULL, date_20150307, - false, false, false, "coreos-ct-test 6"); - CFReleaseNull(certs); - CFReleaseNull(scts); - - /* case 8: April 2016 www.digicert.com cert: 3 embedded SCTs, CT qualified, but OCSP doesn't respond */ - isnt(certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks), NULL, "create cert array"); - CFArrayAppendValue(certs, www_digicert_com_2016_cert); - CFArrayAppendValue(certs, digicert_sha2_ev_server_ca); - - /* WatchOS doesn't require OCSP for EV flag, so even though the OCSP responder no longer responds for this cert, - * it is EV on watchOS. */ -#if TARGET_OS_WATCH - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.digicert.com"), date_20160422, - true, true, false, "digicert 2016"); -#else - test_ct_trust(certs, NULL, NULL, NULL, NULL, CFSTR("www.digicert.com"), date_20160422, - true, false, false, "digicert 2016"); -#endif - CFReleaseNull(certs); - - - -#define TEST_CASE(x) \ - do { \ - 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, NULL, date_20150307, true, false, false, #x); \ - CFReleaseNull(certs); \ - CFReleaseNull(cfCert); \ - } while (0) - - - TEST_CASE(server_1601); - TEST_CASE(server_1603); - TEST_CASE(server_1604); - TEST_CASE(server_1701); - TEST_CASE(server_1704); - TEST_CASE(server_1705); - TEST_CASE(server_1801); - TEST_CASE(server_1804); - TEST_CASE(server_1805); - TEST_CASE(server_2001); - - - CFReleaseSafe(certCA_alpha); - CFReleaseSafe(certCA_beta); - CFReleaseSafe(anchors); - CFReleaseSafe(certA); - CFReleaseSafe(certD); - CFReleaseSafe(certF); - CFReleaseSafe(proofD); - CFReleaseSafe(proofA_1); - CFReleaseSafe(proofA_2); - CFReleaseSafe(www_digicert_com_2015_cert); - CFReleaseSafe(www_digicert_com_2016_cert); - CFReleaseSafe(digicert_sha2_ev_server_ca); - CFReleaseSafe(pilot_cert_3055998); - CFReleaseSafe(pilot_cert_3055998_issuer); - CFReleaseSafe(whitelist_00008013); - CFReleaseSafe(whitelist_5555bc4f); - CFReleaseSafe(whitelist_aaaae152); - CFReleaseSafe(whitelist_fff9b5f6); - CFReleaseSafe(whitelist_00008013_issuer); - CFReleaseSafe(whitelist_5555bc4f_issuer); - CFReleaseSafe(whitelist_fff9b5f6_issuer); - CFReleaseSafe(trustedLogs); - CFReleaseSafe(valid_ocsp); - CFReleaseSafe(invalid_ocsp); - CFReleaseSafe(bad_hash_ocsp); - CFReleaseSafe(cal); - CFReleaseSafe(date_20150307); - CFReleaseSafe(date_20160422); - -} - -static void test_sct_serialization(void) { - SecCertificateRef certA = NULL, certCA_alpha = NULL, certCA_beta = NULL; - CFArrayRef trustedLogs= CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL, deserializedTrust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, NULL); - NSData *proofA_1 = NULL, *proofA_2 = NULL; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:447450000.0]; // March 7, 2015 at 11:40:00 AM PST - CFErrorRef error = NULL; - - isnt(certA = SecCertificateCreateFromResource(@"serverA"), NULL, "create certA"); - isnt(certCA_alpha = SecCertificateCreateFromResource(@"CA_alpha"), NULL, "create ca-alpha cert"); - isnt(certCA_beta = SecCertificateCreateFromResource(@"CA_beta"), NULL, "create ca-beta cert"); - - NSArray *anchors = @[ (__bridge id)certCA_alpha, (__bridge id)certCA_beta ]; - - isnt(proofA_1 = CFBridgingRelease(CFDataCreateFromResource(@"serverA_proof_Alfa_3")), NULL, "creat proofA_1"); - isnt(proofA_2 = CFBridgingRelease(CFDataCreateFromResource(@"serverA_proof_Bravo_3")), NULL, "creat proofA_2"); - NSArray *scts = @[ proofA_1, proofA_2 ]; - - /* Make a SecTrustRef and then serialize it */ - ok_status(SecTrustCreateWithCertificates(certA, policy, &trust), "failed to create trust object"); - ok_status(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), "failed to set anchors"); - ok_status(SecTrustSetTrustedLogs(trust, trustedLogs), "failed to set trusted logs"); - ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "failed to set verify date"); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunguarded-availability-new" - ok_status(SecTrustSetSignedCertificateTimestamps(trust, (__bridge CFArrayRef)scts), "failed to set SCTS"); -#pragma clang diagnostic pop - - NSData *serializedTrust = CFBridgingRelease(SecTrustSerialize(trust, &error)); - isnt(serializedTrust, NULL, "failed to serialize trust: %@", error); - - /* Evaluate it to make sure it's CT */ - ok(SecTrustEvaluateWithError(trust, &error), "failed to evaluate trust: %@", error); - NSDictionary *results = CFBridgingRelease(SecTrustCopyResult(trust)); - isnt(results[(__bridge NSString*)kSecTrustCertificateTransparency], NULL, "failed get CT result"); - ok([results[(__bridge NSString*)kSecTrustCertificateTransparency] boolValue], "CT failed"); - - /* Make a new trust object by deserializing the previous trust object */ - ok(deserializedTrust = SecTrustDeserialize((__bridge CFDataRef)serializedTrust, &error), "failed to deserialize trust: %@", error); - - /* Evaluate the new one to make sure it's CT (because the SCTs were serialized) */ - ok(SecTrustEvaluateWithError(deserializedTrust, &error), "failed to evaluate trust: %@", error); - results = CFBridgingRelease(SecTrustCopyResult(deserializedTrust)); - isnt(results[(__bridge NSString*)kSecTrustCertificateTransparency], NULL, "failed get CT result"); - ok([results[(__bridge NSString*)kSecTrustCertificateTransparency] boolValue], "CT failed"); - - CFReleaseNull(certA); - CFReleaseNull(certCA_alpha); - CFReleaseNull(certCA_beta); - CFReleaseNull(trustedLogs); - CFReleaseNull(policy); - CFReleaseNull(trust); - CFReleaseNull(deserializedTrust); - CFReleaseNull(error); -} - -static void testSetCTExceptions(void) { - CFErrorRef error = NULL; - const CFStringRef SecurityTestsAppID = CFSTR("com.apple.security.regressions"); - const CFStringRef AnotherAppID = CFSTR("com.apple.security.not-this-one"); - CFDictionaryRef copiedExceptions = NULL; - - /* Verify no exceptions set */ - is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set"); - if (copiedExceptions) { - /* If we're starting out with exceptions set, a lot of the following will also fail, so just skip them */ - CFReleaseNull(copiedExceptions); - return; - } - - /* Set exceptions with specified AppID */ - NSDictionary *exceptions1 = @{ - (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"], - }; - ok(SecTrustStoreSetCTExceptions(SecurityTestsAppID, (__bridge CFDictionaryRef)exceptions1, &error), - "failed to set exceptions for SecurityTests: %@", error); - - /* Copy all exceptions (with only one set) */ - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), - "failed to copy all exceptions: %@", error); - ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], - "got the wrong exceptions back"); - CFReleaseNull(copiedExceptions); - - /* Copy this app's exceptions */ - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(SecurityTestsAppID, &error), - "failed to copy SecurityTests' exceptions: %@", error); - ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], - "got the wrong exceptions back"); - CFReleaseNull(copiedExceptions); - - /* Copy a different app's exceptions */ - is(copiedExceptions = SecTrustStoreCopyCTExceptions(AnotherAppID, &error), NULL, - "failed to copy different app's exceptions: %@", error); - CFReleaseNull(copiedExceptions); - - /* Set different exceptions with implied AppID */ - CFDataRef leafHash = SecSHA256DigestCreate(NULL, _system_after_leafSPKI, sizeof(_system_after_leafSPKI)); - NSDictionary *leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)leafHash, - }; - - NSDictionary *exceptions2 = @{ - (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@".test.apple.com"], - (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] - }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions2, &error), - "failed to set exceptions for this app: %@", error); - - /* Ensure exceptions are replaced for SecurityTests */ - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(SecurityTestsAppID, &error), - "failed to copy SecurityTests' exceptions: %@", error); - ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], - "got the wrong exceptions back"); - CFReleaseNull(copiedExceptions); - - /* Set exceptions with a different AppID */ - CFDataRef rootHash = SecSHA256DigestCreate(NULL, _system_rootSPKI, sizeof(_system_rootSPKI)); - NSDictionary *rootExceptions = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)rootHash, - }; - NSDictionary *exceptions3 = @{ - (__bridge NSString*)kSecCTExceptionsCAsKey : @[ rootExceptions ] - }; - ok(SecTrustStoreSetCTExceptions(AnotherAppID, (__bridge CFDictionaryRef)exceptions3, &error), - "failed to set exceptions for different app: %@", error); - - /* Copy only one of the app's exceptions */ - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(SecurityTestsAppID, &error), - "failed to copy SecurityTests' exceptions: %@", error); - ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], - "got the wrong exceptions back"); - CFReleaseNull(copiedExceptions); - - /* Set empty exceptions */ - NSDictionary *empty = @{}; - ok(SecTrustStoreSetCTExceptions(SecurityTestsAppID, (__bridge CFDictionaryRef)empty, &error), - "failed to set empty exceptions"); - - /* Copy exceptiosn to ensure no change */ - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(SecurityTestsAppID, &error), - "failed to copy SecurityTests' exceptions: %@", error); - ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], - "got the wrong exceptions back"); - CFReleaseNull(copiedExceptions); - - /* Copy all exceptions */ - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), - "failed to copy all exceptions: %@", error); - is(CFDictionaryGetCount(copiedExceptions), 2, "Got the wrong number of all exceptions"); - NSDictionary *nsCopiedExceptions = CFBridgingRelease(copiedExceptions); - NSArray *domainExceptions = nsCopiedExceptions[(__bridge NSString*)kSecCTExceptionsDomainsKey]; - NSArray *caExceptions = nsCopiedExceptions[(__bridge NSString*)kSecCTExceptionsCAsKey]; - ok(domainExceptions && caExceptions, "Got both domain and CA exceptions"); - ok([domainExceptions count] == 1, "Got 1 domain exception"); - ok([caExceptions count] == 2, "Got 2 CA exceptions"); - ok([domainExceptions[0] isEqualToString:@".test.apple.com"], "domain exception is .test.apple.com"); - ok([caExceptions containsObject:leafException] && [caExceptions containsObject:rootExceptions], "got expected leaf and root CA exceptions"); - - /* Reset other app's exceptions */ - ok(SecTrustStoreSetCTExceptions(AnotherAppID, NULL, &error), - "failed to reset exceptions for different app: %@", error); - ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), - "failed to copy all exceptions: %@", error); - ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], - "got the wrong exceptions back"); - CFReleaseNull(copiedExceptions); - -#define check_errSecParam \ - if (error) { \ - is(CFErrorGetCode(error), errSecParam, "bad input produced unxpected error code: %ld", (long)CFErrorGetCode(error)); \ - } else { \ - fail("expected failure to set NULL exceptions"); \ - } - - /* Set exceptions with bad inputs */ - NSDictionary *badExceptions = @{ - (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"], - @"not a key": @"not a value", - }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with unknown key"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey:@"test.apple.com" }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with bad value"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey: @[ @{} ] }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with bad array value"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @"test.apple.com" ] }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with bad array value"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{ - (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - @"not-a-key" : (__bridge NSData*)rootHash, - }] }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with bad CA dictionary value"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{ - (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - }] }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with bad CA dictionary value"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{ - (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)rootHash, - @"not-a-key":@"not-a-value" - }] }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with bad CA dictionary value"); - check_errSecParam - - badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey: @[ @".com" ] }; - is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, - "set exceptions with TLD value"); - check_errSecParam -#undef check_errSecParam - - /* Remove exceptions using empty arrays */ - NSDictionary *emptyArrays = @{ - (__bridge NSString*)kSecCTExceptionsDomainsKey: @[], - (__bridge NSString*)kSecCTExceptionsCAsKey : @[] - }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)emptyArrays, &error), - "failed to set empty array exceptions for this app: %@", error); - is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set"); - - CFReleaseNull(leafHash); - CFReleaseNull(rootHash); -} - -static void setup_for_user_trust(NSArray *in_certs, NSArray **deleteMeCertificates) { -#if TARGET_OS_OSX - /* Since we're putting trust settings in the admin domain, - * we need to add the certs to the system keychain. */ - SecKeychainRef kcRef = NULL; - CFArrayRef certRef = NULL; - NSDictionary *attrs = nil; - NSMutableArray *persistenRefs = nil; - - SecKeychainOpen("/Library/Keychains/System.keychain", &kcRef); - if (!kcRef) { - return; - } - - persistenRefs = [[NSMutableArray alloc] init]; - - for (id cert in in_certs) { - attrs = @{(__bridge NSString*)kSecValueRef: cert, - (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef, - (__bridge NSString*)kSecReturnPersistentRef: @YES}; - if (SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef) == 0) - [persistenRefs addObject:(__bridge NSArray *)certRef]; - CFReleaseNull(certRef); - } - - CFReleaseNull(kcRef); - *deleteMeCertificates = persistenRefs; -#endif -} - -static void cleanup_keychain(NSArray *deleteMeCertificates) { -#if TARGET_OS_OSX - if (!deleteMeCertificates) { - return; - } - - [deleteMeCertificates enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { - SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: [obj objectAtIndex:0]}); - }]; -#endif -} - -static bool set_trust_settings_for_cert(SecCertificateRef cert) { - bool ok = false; - NSDictionary *settings = nil; - if (!SecCertificateIsSelfSignedCA(cert)) { - settings = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)}; - } -#if TARGET_OS_IPHONE - require_noerr_string(SecTrustStoreSetTrustSettings(SecTrustStoreForDomain(kSecTrustStoreDomainUser), cert, - (__bridge CFDictionaryRef)settings), - errOut, "failed to set trust settings"); -#else - require_noerr_string(SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, - (__bridge CFDictionaryRef)settings), - errOut, "failed to set trust settings"); - usleep(20000); -#endif - ok = true; -errOut: - return ok; -} - -static bool remove_trust_settings_for_cert(SecCertificateRef cert) { - bool ok = false; -#if TARGET_OS_IPHONE - require_noerr_string(SecTrustStoreRemoveCertificate(SecTrustStoreForDomain(kSecTrustStoreDomainUser), cert), - errOut, "failed to remove trust settings"); -#else - require_noerr_string(SecTrustSettingsRemoveTrustSettings(cert, kSecTrustSettingsDomainAdmin), - errOut, "failed to remove trust settings"); -#endif - ok = true; -errOut: - return ok; -} - -static void test_enforcement(void) { - SecCertificateRef system_root = NULL, user_root = NULL; - SecCertificateRef system_server_before = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; - SecCertificateRef user_server_after = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil, *keychain_certs = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - NSDate *expiredDate = [NSDate dateWithTimeIntervalSinceReferenceDate:570000000.0]; // January 24, 2019 at 12:20:00 AM EST - CFErrorRef error = nil; - CFDataRef exceptions = nil; - - require_action(system_root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(user_root = SecCertificateCreateFromResource(@"enforcement_user_root"), - errOut, fail("failed to create user root")); - require_action(system_server_before = SecCertificateCreateFromResource(@"enforcement_system_server_before"), - errOut, fail("failed to create system server cert issued before flag day")); - require_action(system_server_after = SecCertificateCreateFromResource(@"enforcement_system_server_after"), - errOut, fail("failed to create system server cert issued after flag day")); - require_action(system_server_after_with_CT = SecCertificateCreateFromResource(@"enforcement_system_server_after_scts"), - errOut, fail("failed to create system server cert issued after flag day with SCTs")); - require_action(user_server_after = SecCertificateCreateFromResource(@"enforcement_user_server_after"), - errOut, fail("failed to create user server cert issued after flag day")); - - /* set up the user and system roots to be used with trust settings */ - setup_for_user_trust(@[(__bridge id)system_root, (__bridge id)user_root, (__bridge id)system_server_after], - &keychain_certs); - anchors = @[ (__bridge id)system_root ]; - require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - -#if 0 // Disable this test until we can mock MobileAsset and force asset to be out-of-date - // Out-of-date asset, test system cert after date without CT passes - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with out-of-date asset"); -#endif - - // test system cert after date without CT fails - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with in-date asset succeeded"); - if (error) { - is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d", - (long)CFErrorGetCode(error), errSecVerifyActionFailed); - } else { - fail("expected trust evaluation to fail and it did not."); - } - - // test expired system cert after date without CT passes with only expiration error - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)expiredDate), errOut, fail("failed to set verify date")); - ok(SecTrustIsExpiredOnly(trust), "expired system post-flag-date non-CT cert had non-expiration errors"); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - - // test exceptions for failing cert passes - exceptions = SecTrustCopyExceptions(trust); - ok(SecTrustSetExceptions(trust, exceptions), "failed to set exceptions for failing non-CT cert"); - CFReleaseNull(exceptions); - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with exceptions set"); - SecTrustSetExceptions(trust, NULL); - - // test system cert + enterprise anchor after date without CT fails -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" /* required because of */ - require_noerr_action(SecTrustSetAnchorCertificates(trust, NULL), errOut, fail("failed to unset anchors")); -#pragma clang diagnostic pop - require_action(set_trust_settings_for_cert(system_root), errOut, fail("failed to set trust settings for system_root")); - is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag date non-CT cert with enterprise root trust succeeded"); - if (error) { - is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d", - (long)CFErrorGetCode(error), errSecVerifyActionFailed); - } else { - fail("expected trust evaluation to fail and it did not."); - } - require_action(remove_trust_settings_for_cert(system_root), errOut, fail("failed to remove trust settings for system_root")); - - // test app anchor for failing cert passes - anchors = @[ (__bridge id)system_server_after ]; - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with server cert app anchor"); - - // test trust settings for failing cert passes -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" /* required because of */ - require_noerr_action(SecTrustSetAnchorCertificates(trust, NULL), errOut, fail("failed to remove anchors")); -#pragma clang diagnostic pop - require_action(set_trust_settings_for_cert(system_server_after), errOut, fail("failed to set trust settings for system_server_after")); - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with server cert enterprise anchor"); - require_action(remove_trust_settings_for_cert(system_server_after), errOut, fail("failed to remove trust settings for system_server_after")); - - // EAP, test system cert after date without CT passes - anchors = @[ (__bridge id)system_root ]; - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - CFReleaseNull(policy); - policy = SecPolicyCreateEAP(true, NULL); - require_noerr_action(SecTrustSetPolicies(trust, policy), errOut, fail("failed to set EAP policy")); - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with EAP cert"); - - // Test pinning policy name - CFReleaseNull(policy); - policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - require_noerr_action(SecTrustSetPolicies(trust, policy), errOut, fail("failed to set SSL policy")); - require_noerr_action(SecTrustSetPinningPolicyName(trust, CFSTR("a-policy-name")), errOut, fail("failed to set policy name")); - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with pinning policy name"); - CFReleaseNull(trust); - - // test system cert after date with CT passes - require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date CT cert failed"); - CFReleaseNull(trust); - - // test system cert before date without CT passes - require_noerr_action(SecTrustCreateWithCertificates(system_server_before, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - ok(SecTrustEvaluateWithError(trust, NULL), "system pre-flag-date non-CT cert failed"); - CFReleaseNull(trust); - - // test enterprise (non-public) after date without CT passes - require_action(set_trust_settings_for_cert(user_root), errOut, fail("failed to set trust settings for user_root")); - require_noerr_action(SecTrustCreateWithCertificates(user_server_after, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - ok(SecTrustEvaluateWithError(trust, NULL), "non-system post-flag-date non-CT cert failed with enterprise anchor"); - require_action(remove_trust_settings_for_cert(user_root), errOut, fail("failed to remove trust settings for user_root")); - - // test app anchor (non-public) after date without CT passes - anchors = @[ (__bridge id)user_root ]; - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - ok(SecTrustEvaluateWithError(trust, NULL), "non-system post-flag-date non-CT cert failed with app anchor"); - CFReleaseNull(trust); - CFReleaseNull(policy); - -errOut: - cleanup_keychain(keychain_certs); - CFReleaseNull(system_root); - CFReleaseNull(user_root); - CFReleaseNull(system_server_before); - CFReleaseNull(system_server_after); - CFReleaseNull(system_server_after_with_CT); - CFReleaseNull(user_server_after); - CFReleaseNull(trustedLogs); - CFReleaseNull(trust); - CFReleaseNull(policy); -} - -static void test_apple_enforcement_exceptions(void) { - SecCertificateRef appleRoot = NULL, appleServerAuthCA = NULL, apple_server_after = NULL; - SecCertificateRef geoTrustRoot = NULL, appleISTCA8G1 = NULL, deprecatedSSLServer = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = NULL; - NSArray *anchors = nil, *certs = nil; - NSDate *date1 = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - NSDate *date2 = [NSDate dateWithTimeIntervalSinceReferenceDate:576000000.0]; // April 3, 2019 at 9:00:00 AM PDT - - require_action(appleRoot = SecCertificateCreateFromResource(@"enforcement_apple_root"), - errOut, fail("failed to create apple root")); - require_action(appleServerAuthCA = SecCertificateCreateFromResource(@"enforcement_apple_ca"), - errOut, fail("failed to create apple server auth CA")); - require_action(apple_server_after = SecCertificateCreateFromResource(@"enforcement_apple_server_after"), - errOut, fail("failed to create apple server cert issued after flag day")); - require_action(geoTrustRoot = SecCertificateCreateFromResource(@"GeoTrustPrimaryCAG2"), - errOut, fail("failed to create GeoTrust root")); - require_action(appleISTCA8G1 = SecCertificateCreateFromResource(@"AppleISTCA8G1"), - errOut, fail("failed to create apple IST CA")); - require_action(deprecatedSSLServer = SecCertificateCreateFromResource(@"deprecatedSSLServer"), - errOut, fail("failed to create livability cert")); - - // test apple anchor after date without CT passes - policy = SecPolicyCreateSSL(true, CFSTR("bbasile-test.scv.apple.com")); - certs = @[ (__bridge id)apple_server_after, (__bridge id)appleServerAuthCA ]; - require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date1), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - ok(SecTrustEvaluateWithError(trust, NULL), "apple root post-flag-date non-CT cert failed"); - CFReleaseNull(trust); - CFReleaseNull(policy); - - // test apple ca after date without CT passes - policy = SecPolicyCreateSSL(true, CFSTR("bbasile-test.scv.apple.com")); - certs = @[ (__bridge id)deprecatedSSLServer, (__bridge id)appleISTCA8G1 ]; - anchors = @[ (__bridge id)geoTrustRoot ]; - require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date2), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - ok(SecTrustEvaluateWithError(trust, NULL), "apple public post-flag-date non-CT cert failed"); - -errOut: - CFReleaseNull(appleRoot); - CFReleaseNull(appleServerAuthCA); - CFReleaseNull(apple_server_after); - CFReleaseNull(geoTrustRoot); - CFReleaseNull(appleISTCA8G1); - CFReleaseNull(deprecatedSSLServer); - CFReleaseNull(trustedLogs); - CFReleaseNull(trust); - CFReleaseNull(policy); -} - -static void test_google_enforcement_exception(void) { - SecCertificateRef globalSignRoot = NULL, googleIAG3 = NULL, google = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = NULL; - NSArray *anchors = nil, *certs = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - - require_action(globalSignRoot = SecCertificateCreateFromResource(@"GlobalSignRootCAR2"), - errOut, fail("failed to create GlobalSign root")); - require_action(googleIAG3 = SecCertificateCreateFromResource(@"GoogleIAG3"), - errOut, fail("failed to create Google IA CA")); - require_action(google = SecCertificateCreateFromResource(@"google"), - errOut, fail("failed to create google server cert")); - - // test google ca after date without CT passes - policy = SecPolicyCreateSSL(true, CFSTR("www.google.com")); - certs = @[ (__bridge id)google, (__bridge id)googleIAG3]; - anchors = @[ (__bridge id)globalSignRoot ]; - require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); - 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(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - ok(SecTrustEvaluateWithError(trust, NULL), "google public post-flag-date non-CT cert failed"); - -errOut: - CFReleaseNull(globalSignRoot); - CFReleaseNull(googleIAG3); - CFReleaseNull(google); - CFReleaseNull(trustedLogs); - CFReleaseNull(trust); - CFReleaseNull(policy); -} - -static void test_precerts_fail(void) { - SecCertificateRef precert = NULL, system_root = NULL; - SecTrustRef trust = NULL; - NSArray *anchors = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:561540800.0]; // October 18, 2018 at 12:33:20 AM PDT - CFErrorRef error = NULL; - - require_action(system_root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(precert = SecCertificateCreateFromResource(@"precert"), - errOut, fail("failed to create precert")); - - anchors = @[(__bridge id)system_root]; - require_noerr_action(SecTrustCreateWithCertificates(precert, NULL, &trust), errOut, fail("failed to create trust object")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchor certificate")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - - is(SecTrustEvaluateWithError(trust, &error), false, "SECURITY: trust evaluation of precert succeeded"); - if (error) { - is(CFErrorGetCode(error), errSecUnknownCriticalExtensionFlag, "got wrong error code for precert, got %ld, expected %d", - (long)CFErrorGetCode(error), errSecUnknownCriticalExtensionFlag); - } else { - fail("expected trust evaluation to fail and it did not."); - } - - -errOut: - CFReleaseNull(system_root); - CFReleaseNull(precert); - CFReleaseNull(error); -} - -#define evalTrustExpectingError(errCode, ...) \ - is(SecTrustEvaluateWithError(trust, &error), false, __VA_ARGS__); \ - if (error) { \ - is(CFErrorGetCode(error), errCode, "got wrong error code, got %ld, expected %d", \ - (long)CFErrorGetCode(error), errCode); \ - } else { \ - fail("expected trust evaluation to fail and it did not."); \ - } \ - CFReleaseNull(error); - -static void test_specific_domain_exceptions(void) { - SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - CFErrorRef error = nil; - NSDictionary *exceptions = nil; - - require_action(system_root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(system_server_after = SecCertificateCreateFromResource(@"enforcement_system_server_after"), - errOut, fail("failed to create system server cert issued after flag day")); - require_action(system_server_after_with_CT = SecCertificateCreateFromResource(@"enforcement_system_server_after_scts"), - errOut, fail("failed to create system server cert issued after flag day with SCTs")); - - anchors = @[ (__bridge id)system_root ]; - require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - - /* superdomain exception without CT fails */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"test.apple.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - evalTrustExpectingError(errSecVerifyActionFailed, "superdomain exception unexpectedly succeeded"); - - /* subdomain exceptions without CT fails */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"one.ct.test.apple.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - evalTrustExpectingError(errSecVerifyActionFailed, "subdomain exception unexpectedly succeeded") - - /* no match without CT fails */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"example.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - evalTrustExpectingError(errSecVerifyActionFailed, "unrelated domain exception unexpectedly succeeded"); - - /* matching domain without CT succeeds */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - is(SecTrustEvaluateWithError(trust, &error), true, "exact match domain exception did not apply"); - - /* matching domain with CT succeeds */ - CFReleaseNull(trust); - require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - is(SecTrustEvaluateWithError(trust, &error), true, "ct cert should always pass"); - - ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); - -errOut: - CFReleaseNull(system_root); - CFReleaseNull(system_server_after); - CFReleaseNull(system_server_after_with_CT); - CFReleaseNull(trust); - CFReleaseNull(policy); - CFReleaseNull(error); - CFReleaseNull(trustedLogs); -} - -static void test_subdomain_exceptions(void) { - SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - CFErrorRef error = nil; - NSDictionary *exceptions = nil; - - require_action(system_root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(system_server_after = SecCertificateCreateFromResource(@"enforcement_system_server_after"), - errOut, fail("failed to create system server cert issued after flag day")); - require_action(system_server_after_with_CT = SecCertificateCreateFromResource(@"enforcement_system_server_after_scts"), - errOut, fail("failed to create system server cert issued after flag day with SCTs")); - - anchors = @[ (__bridge id)system_root ]; - require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - - /* superdomain exception without CT succeeds */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".test.apple.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - is(SecTrustEvaluateWithError(trust, &error), true, "superdomain exception did not apply"); - - /* exact domain exception without CT succeeds */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".ct.test.apple.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - is(SecTrustEvaluateWithError(trust, &error), true, "exact domain exception did not apply"); - - /* no match without CT fails */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".example.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - evalTrustExpectingError(errSecVerifyActionFailed, "unrelated domain exception unexpectedly succeeded"); - - /* subdomain without CT fails */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".one.ct.test.apple.com"] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - evalTrustExpectingError(errSecVerifyActionFailed, "subdomain exception unexpectedly succeeded"); - - ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); - -errOut: - CFReleaseNull(system_root); - CFReleaseNull(system_server_after); - CFReleaseNull(system_server_after_with_CT); - CFReleaseNull(trust); - CFReleaseNull(policy); - CFReleaseNull(error); - CFReleaseNull(trustedLogs); -} - -static void test_mixed_domain_exceptions(void) { - SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - CFErrorRef error = nil; - NSDictionary *exceptions = nil; - - require_action(system_root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(system_server_after = SecCertificateCreateFromResource(@"enforcement_system_server_after"), - errOut, fail("failed to create system server cert issued after flag day")); - require_action(system_server_after_with_CT = SecCertificateCreateFromResource(@"enforcement_system_server_after_scts"), - errOut, fail("failed to create system server cert issued after flag day with SCTs")); - - anchors = @[ (__bridge id)system_root ]; - require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - - /* specific domain exception without CT succeeds */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com", @".example.com" ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - is(SecTrustEvaluateWithError(trust, &error), true, "one of exact domain exception did not apply"); - - /* super domain exception without CT succeeds */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".apple.com", @"example.com" ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - is(SecTrustEvaluateWithError(trust, &error), true, "one of superdomain exception did not apply"); - - /* both super domain and specific domain exceptions without CT succeeds */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com", @".apple.com" ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - is(SecTrustEvaluateWithError(trust, &error), true, "both domain exception did not apply"); - - /* neither specific domain nor super domain exceptions without CT fails */ - exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"apple.com", @".example.com" ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - evalTrustExpectingError(errSecVerifyActionFailed, "no match domain unexpectedly succeeded"); - - ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); - -errOut: - CFReleaseNull(system_root); - CFReleaseNull(system_server_after); - CFReleaseNull(system_server_after_with_CT); - CFReleaseNull(trust); - CFReleaseNull(policy); - CFReleaseNull(error); - CFReleaseNull(trustedLogs); -} - - - -static void test_ct_domain_exceptions(void) { - test_specific_domain_exceptions(); - test_subdomain_exceptions(); - test_mixed_domain_exceptions(); -} - -static void test_ct_leaf_exceptions(void) { - SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - CFErrorRef error = nil; - NSDictionary *leafException = nil, *exceptions = nil; - NSData *leafHash = nil; - - require_action(system_root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(system_server_after = SecCertificateCreateFromResource(@"enforcement_system_server_after"), - errOut, fail("failed to create system server cert issued after flag day")); - require_action(system_server_after_with_CT = SecCertificateCreateFromResource(@"enforcement_system_server_after_scts"), - errOut, fail("failed to create system server cert issued after flag day with SCTs")); - - anchors = @[ (__bridge id)system_root ]; - require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - - /* set exception on leaf cert without CT */ - leafHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(system_server_after)); - leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : leafHash, - }; - exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), - "failed to set exceptions: %@", error); - is(SecTrustEvaluateWithError(trust, &error), true, "leaf public key exception did not apply"); - - /* set exception on leaf cert with CT */ - leafHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(system_server_after_with_CT)); - leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : leafHash, - }; - exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), - "failed to set exceptions: %@", error); - SecTrustSetNeedsEvaluation(trust); - evalTrustExpectingError(errSecVerifyActionFailed, "leaf cert with no public key exceptions succeeded"); - - /* matching public key with CT succeeds */ - CFReleaseNull(trust); - require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust")); - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior - is(SecTrustEvaluateWithError(trust, &error), true, "ct cert should always pass"); - - ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); - -errOut: - CFReleaseNull(system_root); - CFReleaseNull(system_server_after); - CFReleaseNull(system_server_after_with_CT); - CFReleaseNull(trustedLogs); - CFReleaseNull(trust); - CFReleaseNull(policy); - CFReleaseNull(error); -} - -static void test_ct_unconstrained_ca_exceptions(void) { - SecCertificateRef root = NULL, subca = NULL; - SecCertificateRef server_matching = NULL, server_matching_with_CT = NULL, server_partial = NULL, server_no_match = NULL, server_no_org = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil, *certs = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - CFErrorRef error = nil; - NSDictionary *caException = nil, *exceptions = nil; - NSData *caHash = nil; - - require_action(root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(subca = SecCertificateCreateFromResource(@"enforcement_system_unconstrained_subca"), - errOut, fail("failed to create subca")); - require_action(server_matching = SecCertificateCreateFromResource(@"enforcement_system_server_matching_orgs"), - errOut, fail("failed to create server cert with matching orgs")); - require_action(server_matching_with_CT = SecCertificateCreateFromResource(@"enforcement_system_server_matching_orgs_scts"), - errOut, fail("failed to create server cert with matching orgs and scts")); - require_action(server_partial = SecCertificateCreateFromResource(@"enforcement_system_server_partial_orgs"), - errOut, fail("failed to create server cert with partial orgs")); - require_action(server_no_match = SecCertificateCreateFromResource(@"enforcement_system_server_nonmatching_orgs"), - errOut, fail("failed to create server cert with non-matching orgs")); - require_action(server_no_org = SecCertificateCreateFromResource(@"enforcement_system_server_no_orgs"), - errOut, fail("failed to create server cert with no orgs")); - - anchors = @[ (__bridge id)root ]; - -#define createTrust(certs) \ - CFReleaseNull(trust); \ - require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); \ - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); \ - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); \ - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - - /* Set exception on the subCA */ - caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(subca)); - caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, - }; - exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ caException ] }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), - "failed to set exceptions: %@", error); - - /* Verify that non-CT cert with Orgs matching subCA passes */ - certs = @[ (__bridge id)server_matching, (__bridge id)subca]; - createTrust(certs); - is(SecTrustEvaluateWithError(trust, &error), true, "matching org subca exception did not apply: %@", error); - - /* Verify that CT cert with Orgs matching subCA passes */ - certs = @[ (__bridge id)server_matching_with_CT, (__bridge id)subca]; - createTrust(certs); - is(SecTrustEvaluateWithError(trust, &error), true, "CT matching org subca exception did not apply: %@", error); - - /* Verify that non-CT cert with partial Org match fails */ - certs = @[ (__bridge id)server_partial, (__bridge id)subca]; - createTrust(certs); - evalTrustExpectingError(errSecVerifyActionFailed, "partial matching org leaf succeeded"); - - /* Verify that a non-CT cert with non-matching Org fails */ - certs = @[ (__bridge id)server_no_match, (__bridge id)subca]; - createTrust(certs); - evalTrustExpectingError(errSecVerifyActionFailed, "non-matching org leaf succeeded"); - - /* Verify that a non-CT cert with no Org fails */ - certs = @[ (__bridge id)server_no_org, (__bridge id)subca]; - createTrust(certs); - evalTrustExpectingError(errSecVerifyActionFailed, "no org leaf succeeded"); - - ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); - -#undef createTrust - -errOut: - CFReleaseNull(root); - CFReleaseNull(subca); - CFReleaseNull(server_matching); - CFReleaseNull(server_matching_with_CT); - CFReleaseNull(server_partial); - CFReleaseNull(server_no_match); - CFReleaseNull(server_no_org); - CFReleaseNull(trustedLogs); - CFReleaseNull(trust); - CFReleaseNull(policy); - CFReleaseNull(error); -} - -static void test_ct_constrained_ca_exceptions(void) { - SecCertificateRef root = NULL, org_constrained_subca = NULL; - SecCertificateRef constraint_pass_server = NULL, constraint_pass_server_ct = NULL, constraint_fail_server = NULL; - SecCertificateRef dn_constrained_subca = NULL, dn_constrained_server = NULL, dn_constrained_server_mismatch = NULL; - SecCertificateRef dns_constrained_subca = NULL, dns_constrained_server = NULL, dns_constrained_server_mismatch = NULL; - CFArrayRef trustedLogs = CTTestsCopyTrustedLogs(); - SecTrustRef trust = NULL; - SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); - NSArray *anchors = nil, *certs = nil; - NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT - CFErrorRef error = nil; - NSDictionary *caException = nil, *exceptions = nil; - NSMutableArray *caExceptions = [NSMutableArray array]; - NSData *caHash = nil; - - require_action(root = SecCertificateCreateFromResource(@"enforcement_system_root"), - errOut, fail("failed to create system root")); - require_action(org_constrained_subca = SecCertificateCreateFromResource(@"enforcement_system_constrained_subca"), - errOut, fail("failed to create org-constrained subca")); - require_action(constraint_pass_server = SecCertificateCreateFromResource(@"enforcement_system_constrained_server"), - errOut, fail("failed to create constrained non-CT leaf")); - require_action(constraint_pass_server_ct = SecCertificateCreateFromResource(@"enforcement_system_constrained_server_scts"), - errOut, fail("failed to create constrained CT leaf")); - require_action(constraint_fail_server= SecCertificateCreateFromResource(@"enforcement_system_constrained_fail_server"), - errOut, fail("failed to create constraint failure leaf")); - require_action(dn_constrained_subca = SecCertificateCreateFromResource(@"enforcement_system_constrained_no_org_subca"), - errOut, fail("failed to create dn-constrained subca")); - require_action(dn_constrained_server = SecCertificateCreateFromResource(@"enforcement_system_constrained_no_org_server"), - errOut, fail("failed to create dn-constrained leaf")); - require_action(dn_constrained_server_mismatch = SecCertificateCreateFromResource(@"enforcement_system_constrained_no_org_server_mismatch"), - errOut, fail("failed to create dn-constrained leaf with mismatched orgs")); - require_action(dns_constrained_subca = SecCertificateCreateFromResource(@"enforcement_system_constrained_no_dn_subca"), - errOut, fail("failed to create dns-constrained subca")); - require_action(dns_constrained_server = SecCertificateCreateFromResource(@"enforcement_system_constrained_no_dn_server"), - errOut, fail("failed to create dns-constrained leaf")); - require_action(dns_constrained_server_mismatch = SecCertificateCreateFromResource(@"enforcement_system_constrained_no_dn_server_mismatch"), - errOut, fail("failed to create dns-constrained leaf with mismatched orgs")); - - anchors = @[ (__bridge id)root ]; - - /* Set exception on the subCAs */ - caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(org_constrained_subca)); - caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, - }; - [caExceptions addObject:caException]; - - caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(dn_constrained_subca)); - caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, - }; - [caExceptions addObject:caException]; - - caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(dns_constrained_subca)); - caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", - (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, - }; - [caExceptions addObject:caException]; - exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : caExceptions }; - ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), - "failed to set exceptions: %@", error); - -#define createTrust(certs) \ - CFReleaseNull(trust); \ - require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); \ - require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), errOut, fail("failed to set anchors")); \ - require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); \ - require_noerr_action(SecTrustSetTrustedLogs(trust, trustedLogs), errOut, fail("failed to set trusted logs")); - - /* Verify org-constrained non-CT leaf passes */ - certs = @[ (__bridge id)constraint_pass_server, (__bridge id)org_constrained_subca ]; - createTrust(certs); - is(SecTrustEvaluateWithError(trust, &error), true, "org constrained exception did not apply: %@", error); - - /* Verify org-constrained CT leaf passes */ - certs = @[ (__bridge id)constraint_pass_server_ct, (__bridge id)org_constrained_subca ]; - createTrust(certs); - is(SecTrustEvaluateWithError(trust, &error), true, "org constrained exception did not apply: %@", error); - - /* Verify org-constrained non-CT leaf with wrong org fails */ - certs = @[ (__bridge id)constraint_fail_server, (__bridge id)org_constrained_subca ]; - createTrust(certs); - evalTrustExpectingError(errSecInvalidName, "leaf failing name constraints succeeded"); - - /* Verify dn-constrained (but not with org) non-CT leaf with matching orgs succeeds */ - certs = @[ (__bridge id)dn_constrained_server, (__bridge id)dn_constrained_subca ]; - createTrust(certs); - is(SecTrustEvaluateWithError(trust, &error), true, "org match exception did not apply: %@", error); - - /* Verify dn-constrained (but not with org) non-CT leaf without matching orgs fails */ - certs = @[ (__bridge id)dn_constrained_server_mismatch, (__bridge id)dn_constrained_subca ]; - createTrust(certs); - evalTrustExpectingError(errSecVerifyActionFailed, "dn name constraints with no org succeeded"); - - /* Verify dns-constrained (no DN constraints) non-CT leaf with matching orgs succeeds */ - certs = @[ (__bridge id)dns_constrained_server, (__bridge id)dns_constrained_subca ]; - createTrust(certs); - is(SecTrustEvaluateWithError(trust, &error), true, "org match exception did not apply: %@", error); - - /* Verify dns-constrained (no DN constraints) non-CT leaf without matching orgs fails*/ - certs = @[ (__bridge id)dns_constrained_server_mismatch, (__bridge id)dns_constrained_subca ]; - createTrust(certs); - evalTrustExpectingError(errSecVerifyActionFailed, "dns name constraints with no DN constraint succeeded"); - - ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); - -#undef createTrust - -errOut: - CFReleaseNull(root); - CFReleaseNull(org_constrained_subca); - CFReleaseNull(constraint_pass_server); - CFReleaseNull(constraint_pass_server_ct); - CFReleaseNull(constraint_fail_server); - CFReleaseNull(dn_constrained_subca); - CFReleaseNull(dn_constrained_server); - CFReleaseNull(dn_constrained_server_mismatch); - CFReleaseNull(dns_constrained_subca); - CFReleaseNull(dns_constrained_server); - CFReleaseNull(dns_constrained_server_mismatch); - CFReleaseNull(trustedLogs); - CFReleaseNull(trust); - CFReleaseNull(policy); - CFReleaseNull(error); -} - -static void test_ct_key_exceptions(void) { - test_ct_leaf_exceptions(); - test_ct_unconstrained_ca_exceptions(); - test_ct_constrained_ca_exceptions(); -} - -static void test_ct_exceptions(void) { - test_ct_domain_exceptions(); - test_ct_key_exceptions(); -} - -int si_82_sectrust_ct(int argc, char *const *argv) -{ - plan_tests(431); - - tests(); - test_sct_serialization(); - testSetCTExceptions(); - test_enforcement(); - test_apple_enforcement_exceptions(); - test_google_enforcement_exception(); - test_precerts_fail(); - test_ct_exceptions(); - - return 0; -} diff --git a/OSX/shared_regressions/si-88-sectrust-valid.m b/OSX/shared_regressions/si-88-sectrust-valid.m index b8d67982..28b593aa 100644 --- a/OSX/shared_regressions/si-88-sectrust-valid.m +++ b/OSX/shared_regressions/si-88-sectrust-valid.m @@ -2,7 +2,7 @@ * si-88-sectrust-valid.m * Security * - * Copyright (c) 2017-2018 Apple Inc. All Rights Reserved. + * Copyright (c) 2017-2019 Apple Inc. All Rights Reserved. * */ @@ -14,6 +14,12 @@ #include #include +#include +#include +#include +#include +#include + #include "shared_regressions.h" enum { @@ -233,11 +239,68 @@ static void known_intermediate_tests() CFReleaseSafe(date_20180310); } +static int ping_host(char *host_name) +{ + struct sockaddr_in pin; + struct hostent *nlp_host; + int sd = 0; + int port = 80; + int retries = 5; // we try 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; + } + close(sd); + return 1; +} + +static int preflight_network() +{ + char *hosts[] = { + "EVSecure-ocsp.verisign.com", + "EVIntl-ocsp.verisign.com", + "EVIntl-aia.verisign.com", + "ocsp.comodoca.com", + "crt.comodoca.com", + "ocsp.entrust.net", + "ocsp.digicert.com", + }; + + for (unsigned host_cnt = 0; host_cnt < sizeof(hosts)/sizeof(hosts[0]); host_cnt ++) { + if (!ping_host(hosts[host_cnt])) { + printf("Accessing specific server (%s) failed, check the network!\n", hosts[host_cnt]); + return 0; + } + } + return 1; +} int si_88_sectrust_valid(int argc, char *const *argv) { plan_tests(DC_COUNT+KI_COUNT); + if (!preflight_network()) { + return 0; + } + date_constraints_tests(); known_intermediate_tests(); diff --git a/OSX/trustd/iOS/entitlements.plist b/OSX/trustd/iOS/entitlements.plist index 125854bc..dc6f6d2e 100644 --- a/OSX/trustd/iOS/entitlements.plist +++ b/OSX/trustd/iOS/entitlements.plist @@ -16,8 +16,8 @@ com.apple.private.assets.accessible-asset-types - com.apple.MobileAsset.CertificatePinning com.apple.MobileAsset.PKITrustSupplementals + com.apple.MobileAsset.SecExperimentAssets seatbelt-profiles diff --git a/OSX/trustd/macOS/SecTrustOSXEntryPoints.h b/OSX/trustd/macOS/SecTrustOSXEntryPoints.h index 6dd6529b..142b62e5 100644 --- a/OSX/trustd/macOS/SecTrustOSXEntryPoints.h +++ b/OSX/trustd/macOS/SecTrustOSXEntryPoints.h @@ -36,19 +36,6 @@ __BEGIN_DECLS void SecTrustLegacySourcesListenForKeychainEvents(void); -OSStatus SecTrustLegacyCRLStatus(SecCertificateRef cert, CFArrayRef chain, CFURLRef currCRLDP); - -typedef struct async_ocspd_s { - uint64_t start_time; - void (*completed)(struct async_ocspd_s *ocspd); - void *info; - OSStatus response; - dispatch_queue_t queue; -} async_ocspd_t; - -bool SecTrustLegacyCRLFetch(async_ocspd_t *ocspd, - CFURLRef currCRLDP, CFAbsoluteTime verifyTime, - SecCertificateRef cert, CFArrayRef chain); __END_DECLS #endif /* _SECURITY_SECTRUST_OSX_ENTRY_POINTS_H_ */ diff --git a/OSX/trustd/macOS/com.apple.trustd.sb b/OSX/trustd/macOS/com.apple.trustd.sb index e080f69c..f13684b1 100644 --- a/OSX/trustd/macOS/com.apple.trustd.sb +++ b/OSX/trustd/macOS/com.apple.trustd.sb @@ -58,10 +58,12 @@ (global-name "com.apple.ocspd") (global-name "com.apple.SecurityServer") (global-name "com.apple.SystemConfiguration.configd") - (global-name "com.apple.mobileassetd") + (global-name "com.apple.mobileassetd.v2") (global-name "com.apple.securityd.xpc") (global-name "com.apple.cfnetwork.cfnetworkagent") - (global-name "com.apple.nsurlsessiond")) + (global-name "com.apple.nsurlsessiond") + (xpc-service-name "com.apple.powerlog.plxpclogger.xpc") + (global-name "com.apple.nesessionmanager.content-filter")) (allow ipc-posix-shm (ipc-posix-name "com.apple.AppleDatabaseChanged")) diff --git a/OSX/trustd/macOS/entitlements.plist b/OSX/trustd/macOS/entitlements.plist index 1682ccdd..efa5ea47 100644 --- a/OSX/trustd/macOS/entitlements.plist +++ b/OSX/trustd/macOS/entitlements.plist @@ -16,8 +16,8 @@ com.apple.private.assets.accessible-asset-types - com.apple.MobileAsset.CertificatePinning com.apple.MobileAsset.PKITrustSupplementals + com.apple.MobileAsset.SecExperimentAssets diff --git a/OSX/trustd/trustd-Info.plist b/OSX/trustd/trustd-Info.plist index df9088c6..98f152cf 100644 --- a/OSX/trustd/trustd-Info.plist +++ b/OSX/trustd/trustd-Info.plist @@ -27,5 +27,10 @@ ServiceType System + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + diff --git a/OSX/trustd/trustd.c b/OSX/trustd/trustd.c index 8e56e848..898a2c40 100644 --- a/OSX/trustd/trustd.c +++ b/OSX/trustd/trustd.c @@ -57,6 +57,9 @@ #include #include #include +#if TARGET_OS_IPHONE +#include +#endif #if TARGET_OS_OSX #include @@ -65,25 +68,7 @@ #endif #include "OTATrustUtilities.h" - -static struct trustd trustd_spi = { - .sec_trust_store_for_domain = SecTrustStoreForDomainName, - .sec_trust_store_contains = SecTrustStoreContainsCertificateWithDigest, - .sec_trust_store_set_trust_settings = _SecTrustStoreSetTrustSettings, - .sec_trust_store_remove_certificate = SecTrustStoreRemoveCertificateWithDigest, - .sec_truststore_remove_all = _SecTrustStoreRemoveAll, - .sec_trust_evaluate = SecTrustServerEvaluate, - .sec_ota_pki_trust_store_version = SecOTAPKIGetCurrentTrustStoreVersion, - .sec_ota_pki_asset_version = SecOTAPKIGetCurrentAssetVersion, - .ota_CopyEscrowCertificates = SecOTAPKICopyCurrentEscrowCertificates, - .sec_ota_pki_get_new_asset = SecOTAPKISignalNewAsset, - .sec_trust_store_copy_all = _SecTrustStoreCopyAll, - .sec_trust_store_copy_usage_constraints = _SecTrustStoreCopyUsageConstraints, - .sec_ocsp_cache_flush = SecOCSPCacheFlush, - .sec_networking_analytics_report = SecNetworkingAnalyticsReport, - .sec_trust_store_set_ct_exceptions = _SecTrustStoreSetCTExceptions, - .sec_trust_store_copy_ct_exceptions = _SecTrustStoreCopyCTExceptions, -}; +#include "trustd_spi.h" static bool SecXPCDictionarySetChainOptional(xpc_object_t message, const char *key, CFArrayRef path, CFErrorRef *error) { if (!path) @@ -272,7 +257,7 @@ static bool SecXPC_OTAPKI_GetCurrentTrustStoreVersion(SecurityClient * __unused } static bool SecXPC_OTAPKI_GetCurrentAssetVersion(SecurityClient * __unused client, xpc_object_t __unused event, - xpc_object_t reply, CFErrorRef *error) { + xpc_object_t reply, CFErrorRef *error) { xpc_dictionary_set_uint64(reply, kSecXPCKeyResult, SecOTAPKIGetCurrentAssetVersion(error)); return true; } @@ -298,6 +283,64 @@ static bool SecXPC_OTAPKI_GetNewAsset(SecurityClient * __unused client, xpc_obje return true; } +static bool SecXPC_OTASecExperiment_GetNewAsset(SecurityClient * __unused client, xpc_object_t __unused event, + xpc_object_t reply, CFErrorRef *error) { + xpc_dictionary_set_uint64(reply, kSecXPCKeyResult, SecOTASecExperimentGetNewAsset(error)); + return true; +} + +static bool SecXPC_OTASecExperiment_GetAsset(SecurityClient * __unused client, xpc_object_t __unused event, + xpc_object_t reply, CFErrorRef *error) { + bool result = false; + CFDictionaryRef asset = SecOTASecExperimentCopyAsset(error); + if (asset) { + xpc_object_t xpc_dict = _CFXPCCreateXPCObjectFromCFObject(asset); + if (xpc_dict) { + xpc_dictionary_set_value(reply, kSecXPCKeyResult, xpc_dict); + xpc_release(xpc_dict); + result = true; + } + } + CFReleaseNull(asset); + return result; +} + +static bool SecXPC_OTAPKI_CopyTrustedCTLogs(SecurityClient * __unused client, xpc_object_t event, + xpc_object_t reply, CFErrorRef *error) { + bool result = false; + CFDictionaryRef trustedLogs = SecOTAPKICopyCurrentTrustedCTLogs(error); + if (trustedLogs) { + xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(trustedLogs); + if (xpc_dictionary) { + xpc_dictionary_set_value(reply, kSecXPCKeyResult, xpc_dictionary); + xpc_release(xpc_dictionary); + result = true; + } + } + CFReleaseNull(trustedLogs); + return result; +} + +static bool SecXPC_OTAPKI_CopyCTLogForKeyID(SecurityClient * __unused client, xpc_object_t event, + xpc_object_t reply, CFErrorRef *error) { + bool result = false; + size_t length = 0; + const void *bytes = xpc_dictionary_get_data(event, kSecXPCData, &length); + CFDataRef keyID = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, length, kCFAllocatorNull); + if (keyID) { + CFDictionaryRef logDict = SecOTAPKICopyCTLogForKeyID(keyID, error); + if (logDict) { + xpc_object_t xpc_dictionary = _CFXPCCreateXPCObjectFromCFObject(logDict); + xpc_dictionary_set_value(reply, kSecXPCKeyResult, xpc_dictionary); + xpc_release(xpc_dictionary); + CFReleaseNull(logDict); + result = true; + } + CFReleaseNull(keyID); + } + return result; +} + static bool SecXPC_Networking_AnalyticsReport(SecurityClient * __unused client, xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { xpc_object_t attributes = xpc_dictionary_get_dictionary(event, kSecTrustEventAttributesKey); @@ -338,6 +381,29 @@ static bool SecXPCTrustStoreCopyCTExceptions(SecurityClient * __unused client, x return false; } +#if TARGET_OS_IPHONE +static bool SecXPCTrustGetExceptionResetCount(SecurityClient * __unused client, xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { + uint64_t exceptionResetCount = SecTrustServerGetExceptionResetCount(error); + if (error && *error) { + return false; + } + + xpc_dictionary_set_uint64(reply, kSecXPCKeyResult, exceptionResetCount); + return true; +} + +static bool SecXPCTrustIncrementExceptionResetCount(SecurityClient * __unused client, xpc_object_t event, xpc_object_t reply, CFErrorRef *error) { + OSStatus status = errSecInternal; + bool result = SecTrustServerIncrementExceptionResetCount(error); + if (result && (!error || (error && !*error))) { + status = errSecSuccess; + } + + xpc_dictionary_set_bool(reply, kSecXPCKeyResult, status); + return result; +} +#endif + typedef bool(*SecXPCOperationHandler)(SecurityClient *client, xpc_object_t event, xpc_object_t reply, CFErrorRef *error); typedef struct { @@ -356,9 +422,17 @@ struct trustd_operations { SecXPCServerOperation ota_pki_asset_version; SecXPCServerOperation ota_pki_get_escrow_certs; SecXPCServerOperation ota_pki_get_new_asset; + SecXPCServerOperation ota_pki_copy_trusted_ct_logs; + SecXPCServerOperation ota_pki_copy_ct_log_for_keyid; SecXPCServerOperation networking_analytics_report; SecXPCServerOperation trust_store_set_ct_exceptions; SecXPCServerOperation trust_store_copy_ct_exceptions; + SecXPCServerOperation ota_secexperiment_get_asset; + SecXPCServerOperation ota_secexperiment_get_new_asset; +#if TARGET_OS_IPHONE + SecXPCServerOperation trust_get_exception_reset_count; + SecXPCServerOperation trust_increment_exception_reset_count; +#endif }; static struct trustd_operations trustd_ops = { @@ -372,9 +446,17 @@ static struct trustd_operations trustd_ops = { .ota_pki_asset_version = { NULL, SecXPC_OTAPKI_GetCurrentAssetVersion }, .ota_pki_get_escrow_certs = { NULL, SecXPC_OTAPKI_GetEscrowCertificates }, .ota_pki_get_new_asset = { NULL, SecXPC_OTAPKI_GetNewAsset }, + .ota_secexperiment_get_new_asset = { NULL, SecXPC_OTASecExperiment_GetNewAsset }, + .ota_secexperiment_get_asset = { NULL, SecXPC_OTASecExperiment_GetAsset }, + .ota_pki_copy_trusted_ct_logs = { NULL, SecXPC_OTAPKI_CopyTrustedCTLogs }, + .ota_pki_copy_ct_log_for_keyid = { NULL, SecXPC_OTAPKI_CopyCTLogForKeyID }, .networking_analytics_report = { NULL, SecXPC_Networking_AnalyticsReport }, .trust_store_set_ct_exceptions = {kSecEntitlementModifyAnchorCertificates, SecXPCTrustStoreSetCTExceptions }, - .trust_store_copy_ct_exceptions = {kSecEntitlementModifyAnchorCertificates, SecXPCTrustStoreCopyCTExceptions } + .trust_store_copy_ct_exceptions = {kSecEntitlementModifyAnchorCertificates, SecXPCTrustStoreCopyCTExceptions }, +#if TARGET_OS_IPHONE + .trust_get_exception_reset_count = { NULL, SecXPCTrustGetExceptionResetCount }, + .trust_increment_exception_reset_count = { kSecEntitlementModifyAnchorCertificates, SecXPCTrustIncrementExceptionResetCount }, +#endif }; static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc_object_t event) { @@ -435,7 +517,7 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc xpc_object_t asyncReply = replyMessage; replyMessage = NULL; - SecTrustServerEvaluateBlock(clientAuditToken, certificates, anchors, anchorsOnly, keychainsAllowed, policies, + SecTrustServerEvaluateBlock(SecTrustServerGetWorkloop(), clientAuditToken, certificates, anchors, anchorsOnly, keychainsAllowed, policies, responses, scts, trustedLogs, verifyTime, client.accessGroups, exceptions, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, CFArrayRef chain, CFErrorRef replyError) { @@ -507,6 +589,18 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc case kSecXPCOpOTAPKIGetNewAsset: server_op = &trustd_ops.ota_pki_get_new_asset; break; + case kSecXPCOpOTASecExperimentGetNewAsset: + server_op = &trustd_ops.ota_secexperiment_get_new_asset; + break; + case kSecXPCOpOTASecExperimentGetAsset: + server_op = &trustd_ops.ota_secexperiment_get_asset; + break; + case kSecXPCOpOTAPKICopyTrustedCTLogs: + server_op = &trustd_ops.ota_pki_copy_trusted_ct_logs; + break; + case kSecXPCOpOTAPKICopyCTLogForKeyID: + server_op = &trustd_ops.ota_pki_copy_ct_log_for_keyid; + break; case kSecXPCOpNetworkingAnalyticsReport: server_op = &trustd_ops.networking_analytics_report; break; @@ -516,6 +610,14 @@ static void trustd_xpc_dictionary_handler(const xpc_connection_t connection, xpc case kSecXPCOpCopyCTExceptions: server_op = &trustd_ops.trust_store_copy_ct_exceptions; break; +#if TARGET_OS_IPHONE + case sec_trust_get_exception_reset_count_id: + server_op = &trustd_ops.trust_get_exception_reset_count; + break; + case sec_trust_increment_exception_reset_count_id: + server_op = &trustd_ops.trust_increment_exception_reset_count; + break; +#endif default: break; } @@ -578,91 +680,20 @@ static void trustd_xpc_init(const char *service_name) xpc_connection_set_event_handler(listener, ^(xpc_object_t connection) { if (xpc_get_type(connection) == XPC_TYPE_CONNECTION) { + xpc_connection_set_target_queue(connection, SecTrustServerGetWorkloop()); xpc_connection_set_event_handler(connection, ^(xpc_object_t event) { if (xpc_get_type(event) == XPC_TYPE_DICTIONARY) { trustd_xpc_dictionary_handler(connection, event); } }); - xpc_connection_resume(connection); + xpc_connection_activate(connection); } }); - xpc_connection_resume(listener); -} - -static void trustd_delete_old_sqlite_keychain_files(CFStringRef baseFilename) { - WithPathInKeychainDirectory(baseFilename, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFStringRef shmFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-shm"), baseFilename); - WithPathInKeychainDirectory(shmFile, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFReleaseNull(shmFile); - CFStringRef walFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-wal"), baseFilename); - WithPathInKeychainDirectory(walFile, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFReleaseNull(walFile); - CFStringRef journalFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-journal"), baseFilename); - WithPathInKeychainDirectory(journalFile, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFReleaseNull(journalFile); -} - -#if TARGET_OS_OSX -static void trustd_delete_old_sqlite_user_cache_files(CFStringRef baseFilename) { - WithPathInUserCacheDirectory(baseFilename, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFStringRef shmFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-shm"), baseFilename); - WithPathInUserCacheDirectory(shmFile, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFReleaseNull(shmFile); - CFStringRef walFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-wal"), baseFilename); - WithPathInUserCacheDirectory(walFile, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFReleaseNull(walFile); - CFStringRef journalFile = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-journal"), baseFilename); - WithPathInUserCacheDirectory(journalFile, ^(const char *utf8String) { - (void)remove(utf8String); - }); - CFReleaseNull(journalFile); -} -#endif // TARGET_OS_OSX - -static void trustd_delete_old_files(void) { - /* We try to clean up after ourselves, but don't care if we succeed. */ - WithPathInRevocationInfoDirectory(CFSTR("update-current"), ^(const char *utf8String) { - (void)remove(utf8String); - }); - WithPathInRevocationInfoDirectory(CFSTR("update-full"), ^(const char *utf8String) { - (void)remove(utf8String); - }); - WithPathInRevocationInfoDirectory(CFSTR("update-full.gz"), ^(const char *utf8String) { - (void)remove(utf8String); - }); -#if TARGET_OS_IPHONE - trustd_delete_old_sqlite_keychain_files(CFSTR("trustd_health_analytics.db")); - trustd_delete_old_sqlite_keychain_files(CFSTR("trust_analytics.db")); - trustd_delete_old_sqlite_keychain_files(CFSTR("TLS_analytics.db")); -#else - trustd_delete_old_sqlite_user_cache_files(CFSTR("trustd_health_analytics.db")); - trustd_delete_old_sqlite_user_cache_files(CFSTR("trust_analytics.db")); - trustd_delete_old_sqlite_user_cache_files(CFSTR("TLS_analytics.db")); -#endif //TARGET_OS_IPHONE -} - -#if TARGET_OS_OSX -static void trustd_delete_old_caches(void) { - /* We try to clean up after ourselves, but don't care if we succeed. */ - trustd_delete_old_sqlite_keychain_files(CFSTR("ocspcache.sqlite3")); - trustd_delete_old_sqlite_keychain_files(CFSTR("caissuercache.sqlite3")); + xpc_connection_activate(listener); } static void trustd_sandbox(void) { +#if TARGET_OS_OSX char buf[PATH_MAX] = ""; if (!_set_user_dir_suffix("com.apple.trustd") || @@ -704,14 +735,12 @@ static void trustd_sandbox(void) { free(tempdir); free(cachedir); -} -#else -static void trustd_sandbox(void) { +#else // !TARGET_OS_OSX char buf[PATH_MAX] = ""; _set_user_dir_suffix("com.apple.trustd"); confstr(_CS_DARWIN_USER_TEMP_DIR, buf, sizeof(buf)); +#endif // !TARGET_OS_OSX } -#endif int main(int argc, char *argv[]) { @@ -725,34 +754,8 @@ int main(int argc, char *argv[]) kill(getpid(), SIGSTOP); } - /* Users with network home folders are unable to use/save password for Mail/Cal/Contacts/websites - Our process doesn't realize DB connections get invalidated when network home directory users logout - and their home gets unmounted. Exit our process and start fresh when user logs back in. - */ -#if TARGET_OS_OSX - int sessionstatechanged_tok; - notify_register_dispatch(kSA_SessionStateChangedNotification, &sessionstatechanged_tok, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(int token __unused) { - // we could be a process running as root. - // However, since root never logs out this isn't an issue. - if (SASSessionStateForUser(getuid()) == kSA_state_loggingout_pointofnoreturn) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - xpc_transaction_exit_clean(); - }); - } - }); -#endif - -#if TARGET_OS_OSX - /* Before we enter the sandbox, we need to delete the old caches kept in ~/Library/Keychains - * After we enter the sandbox, we won't be able to access them. */ - trustd_delete_old_caches(); -#endif - trustd_sandbox(); - /* Also clean up old files in our sandbox. After sandboxing, so that user dir suffix is set. */ - trustd_delete_old_files(); - const char *serviceName = kTrustdXPCServiceName; if (argc > 1 && (!strcmp(argv[1], "--agent"))) { serviceName = kTrustdAgentXPCServiceName; diff --git a/OSX/trustd/trustd_spi.c b/OSX/trustd/trustd_spi.c new file mode 100644 index 00000000..4a9082ab --- /dev/null +++ b/OSX/trustd/trustd_spi.c @@ -0,0 +1,96 @@ +/* + * 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@ + */ + +#ifdef LIBTRUSTD +#include + +#include "../utilities/SecFileLocations.h" + +#include "../sec/ipc/securityd_client.h" +#include "../sec/securityd/SecPolicyServer.h" +#include "../sec/securityd/SecTrustServer.h" +#include "../sec/securityd/SecTrustStoreServer.h" +#include "../sec/securityd/SecOCSPCache.h" +#include "../sec/securityd/OTATrustUtilities.h" +#include "../sec/securityd/SecTrustLoggingServer.h" +#include "../sec/securityd/SecRevocationDb.h" +#include "../sec/securityd/SecPinningDb.h" +#include "trustd_spi.h" + +#if TARGET_OS_OSX +#include +#endif + +#if TARGET_OS_IPHONE +#include +#endif + +#endif // LIBTRUSTD + +#ifdef LIBTRUSTD +struct trustd trustd_spi = { + .sec_trust_store_for_domain = SecTrustStoreForDomainName, + .sec_trust_store_contains = SecTrustStoreContainsCertificateWithDigest, + .sec_trust_store_set_trust_settings = _SecTrustStoreSetTrustSettings, + .sec_trust_store_remove_certificate = SecTrustStoreRemoveCertificateWithDigest, + .sec_truststore_remove_all = _SecTrustStoreRemoveAll, + .sec_trust_evaluate = SecTrustServerEvaluate, + .sec_ota_pki_trust_store_version = SecOTAPKIGetCurrentTrustStoreVersion, + .sec_ota_pki_asset_version = SecOTAPKIGetCurrentAssetVersion, + .ota_CopyEscrowCertificates = SecOTAPKICopyCurrentEscrowCertificates, + .sec_ota_pki_copy_trusted_ct_logs = SecOTAPKICopyCurrentTrustedCTLogs, + .sec_ota_pki_copy_ct_log_for_keyid = SecOTAPKICopyCTLogForKeyID, + .sec_ota_pki_get_new_asset = SecOTAPKISignalNewAsset, + .sec_ota_secexperiment_get_new_asset = SecOTASecExperimentGetNewAsset, + .sec_ota_secexperiment_get_asset = SecOTASecExperimentCopyAsset, + .sec_trust_store_copy_all = _SecTrustStoreCopyAll, + .sec_trust_store_copy_usage_constraints = _SecTrustStoreCopyUsageConstraints, + .sec_ocsp_cache_flush = SecOCSPCacheFlush, + .sec_networking_analytics_report = SecNetworkingAnalyticsReport, + .sec_trust_store_set_ct_exceptions = _SecTrustStoreSetCTExceptions, + .sec_trust_store_copy_ct_exceptions = _SecTrustStoreCopyCTExceptions, +#if TARGET_OS_IPHONE + .sec_trust_get_exception_reset_count = SecTrustServerGetExceptionResetCount, + .sec_trust_increment_exception_reset_count = SecTrustServerIncrementExceptionResetCount, +#endif +}; +#endif + +void trustd_init(CFURLRef home_path) { + if (home_path) + SetCustomHomeURL(home_path); + + trustd_init_server(); +} + +void trustd_init_server(void) { +#ifdef LIBTRUSTD + gTrustd = &trustd_spi; + SecPolicyServerInitialize(); + SecRevocationDbInitialize(); + SecPinningDbInitialize(); +#if TARGET_OS_OSX + SecTrustLegacySourcesListenForKeychainEvents(); // set up the legacy keychain event listeners (for cache invalidation) +#endif +#endif // LIBTRUSTD +} diff --git a/OSX/trustd/trustd_spi.h b/OSX/trustd/trustd_spi.h new file mode 100644 index 00000000..107acec6 --- /dev/null +++ b/OSX/trustd/trustd_spi.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2009-2010,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@ + */ + +#ifndef _TRUSTD_SPI_h +#define _TRUSTD_SPI_h + +#include +#include + +// Don't call these functions unless you are trustd +extern struct trustd trustd_spi; + +void trustd_init_server(void); +void trustd_init(CFURLRef home_dir); + +#endif /* _TRUSTD_SPI_h */ diff --git a/OSX/utilities/src/NSURL+SOSPlistStore.h b/OSX/utilities/NSURL+SOSPlistStore.h similarity index 100% rename from OSX/utilities/src/NSURL+SOSPlistStore.h rename to OSX/utilities/NSURL+SOSPlistStore.h diff --git a/OSX/utilities/src/NSURL+SOSPlistStore.m b/OSX/utilities/NSURL+SOSPlistStore.m similarity index 100% rename from OSX/utilities/src/NSURL+SOSPlistStore.m rename to OSX/utilities/NSURL+SOSPlistStore.m diff --git a/OSX/utilities/src/SecADWrapper.c b/OSX/utilities/SecADWrapper.c similarity index 93% rename from OSX/utilities/src/SecADWrapper.c rename to OSX/utilities/SecADWrapper.c index 3f50e112..7d6aba8f 100644 --- a/OSX/utilities/src/SecADWrapper.c +++ b/OSX/utilities/SecADWrapper.c @@ -23,7 +23,7 @@ #include "SecADWrapper.h" -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include static typeof(ADClientAddValueForScalarKey) *soft_ADClientAddValueForScalarKey = NULL; @@ -68,7 +68,7 @@ setup(void) void SecADClearScalarKey(CFStringRef key) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR if (setup()) soft_ADClientClearScalarKey(key); #endif @@ -77,7 +77,7 @@ SecADClearScalarKey(CFStringRef key) void SecADSetValueForScalarKey(CFStringRef key, int64_t value) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR if (setup()) soft_ADClientSetValueForScalarKey(key, value); #endif @@ -85,7 +85,7 @@ SecADSetValueForScalarKey(CFStringRef key, int64_t value) void SecADAddValueForScalarKey(CFStringRef key, int64_t value) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR if (setup()) soft_ADClientAddValueForScalarKey(key, value); #endif @@ -94,7 +94,7 @@ SecADAddValueForScalarKey(CFStringRef key, int64_t value) void SecADClientPushValueForDistributionKey(CFStringRef key, int64_t value) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR if (setup()) soft_ADClientPushValueForDistributionKey(key, value); #endif diff --git a/OSX/utilities/src/SecADWrapper.h b/OSX/utilities/SecADWrapper.h similarity index 100% rename from OSX/utilities/src/SecADWrapper.h rename to OSX/utilities/SecADWrapper.h diff --git a/OSX/utilities/src/SecAKSWrappers.c b/OSX/utilities/SecAKSWrappers.c similarity index 70% rename from OSX/utilities/src/SecAKSWrappers.c rename to OSX/utilities/SecAKSWrappers.c index 032bc1c8..11614a19 100644 --- a/OSX/utilities/src/SecAKSWrappers.c +++ b/OSX/utilities/SecAKSWrappers.c @@ -30,7 +30,7 @@ #include #include -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR # define change_notification "com.apple.will.never.happen" #elif TARGET_OS_IPHONE # include @@ -42,7 +42,7 @@ # error "unsupported target platform" #endif -#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && TARGET_HAS_KEYSTORE +#if TARGET_OS_OSX && TARGET_HAS_KEYSTORE // OS X const keybag_handle_t keybagHandle = session_keybag_handle; #elif TARGET_HAS_KEYSTORE // iOS, but not simulator @@ -62,11 +62,11 @@ static uint32_t count = 0; #endif const char * const kUserKeybagStateChangeNotification = change_notification; -bool SecAKSLockUserKeybag(uint64_t timeout, CFErrorRef *error){ +bool SecAKSUserKeybagHoldLockAssertion(uint64_t timeout, CFErrorRef *error){ #if !TARGET_HAS_KEYSTORE return true; #else - __block kern_return_t status = kIOReturnSuccess; + __block kern_return_t status = kAKSReturnSuccess; dispatch_sync(GetKeybagAssertionQueue(), ^{ if (count == 0) { @@ -74,18 +74,18 @@ bool SecAKSLockUserKeybag(uint64_t timeout, CFErrorRef *error){ status = aks_assert_hold(keybagHandle, lockAssertType, timeout); } - if (status == kIOReturnSuccess) + if (status == kAKSReturnSuccess) ++count; }); return SecKernError(status, error, CFSTR("Kern return error")); #endif /* !TARGET_HAS_KEYSTORE */ } -bool SecAKSUnLockUserKeybag(CFErrorRef *error){ +bool SecAKSUserKeybagDropLockAssertion(CFErrorRef *error){ #if !TARGET_HAS_KEYSTORE return true; #else - __block kern_return_t status = kIOReturnSuccess; + __block kern_return_t status = kAKSReturnSuccess; dispatch_sync(GetKeybagAssertionQueue(), ^{ if (count && (--count == 0)) { @@ -97,9 +97,7 @@ bool SecAKSUnLockUserKeybag(CFErrorRef *error){ return SecKernError(status, error, CFSTR("Kern return error")); #endif /* !TARGET_HAS_KEYSTORE */ } - - -bool SecAKSDoWhileUserBagLocked(CFErrorRef *error, dispatch_block_t action) +bool SecAKSDoWithUserBagLockAssertion(CFErrorRef *error, dispatch_block_t action) { #if !TARGET_HAS_KEYSTORE action(); @@ -109,13 +107,40 @@ bool SecAKSDoWhileUserBagLocked(CFErrorRef *error, dispatch_block_t action) bool status = false; uint64_t timeout = 60ull; - if (SecAKSLockUserKeybag(timeout, error)) { + if (SecAKSUserKeybagHoldLockAssertion(timeout, error)) { action(); - status = SecAKSUnLockUserKeybag(error); + status = SecAKSUserKeybagDropLockAssertion(error); } return status; #endif /* !TARGET_HAS_KEYSTORE */ } + +bool SecAKSDoWithUserBagLockAssertionSoftly(dispatch_block_t action) +{ +#if !TARGET_HAS_KEYSTORE + action(); + return true; +#else + uint64_t timeout = 60ull; + CFErrorRef localError = NULL; + + bool heldAssertion = SecAKSUserKeybagHoldLockAssertion(timeout, &localError); + if (!heldAssertion) { + secnotice("secaks", "SecAKSDoWithUserBagLockAssertionSoftly: failed to get assertion proceeding bravely: %@", localError); + CFReleaseNull(localError); + } + + action(); + + if (heldAssertion) { + (void)SecAKSUserKeybagDropLockAssertion(&localError); + CFReleaseNull(localError); + } + return true; +#endif /* !TARGET_HAS_KEYSTORE */ +} + + CFDataRef SecAKSCopyBackupBagWithSecret(size_t size, uint8_t *secret, CFErrorRef *error) { #if !TARGET_HAS_KEYSTORE return NULL; @@ -154,3 +179,16 @@ fail: #endif } +keyclass_t SecAKSSanitizedKeyclass(keyclass_t keyclass) +{ + keyclass_t sanitizedKeyclass = keyclass; +#if TARGET_HAS_KEYSTORE + if (keyclass > key_class_last) { + // idea is that AKS may return a keyclass value with extra bits above key_class_last from aks_wrap_key, but we only keep metadata keys for the canonical key classes + // so just sanitize all our inputs to the canonical values + sanitizedKeyclass = keyclass & key_class_last; + secinfo("SanitizeKeyclass", "sanitizing request for keyclass %d to keyclass %d", keyclass, sanitizedKeyclass); + } +#endif + return sanitizedKeyclass; +} diff --git a/OSX/utilities/src/SecAKSWrappers.h b/OSX/utilities/SecAKSWrappers.h similarity index 76% rename from OSX/utilities/src/SecAKSWrappers.h rename to OSX/utilities/SecAKSWrappers.h index 4233c69e..541e9401 100644 --- a/OSX/utilities/src/SecAKSWrappers.h +++ b/OSX/utilities/SecAKSWrappers.h @@ -26,14 +26,15 @@ #define _SECAKSWRAPPERS_H_ #include -#include +#include "utilities/SecCFError.h" #include #include #include -#ifdef USE_KEYSTORE +#if defined(USE_KEYSTORE) #define TARGET_HAS_KEYSTORE USE_KEYSTORE + #else #if RC_HORIZON @@ -54,42 +55,33 @@ #endif // USE_KEYSTORE -#if !TARGET_HAS_KEYSTORE - -#include - -// Make the compiler happy so this will compile. -#define device_keybag_handle 0 -#define session_keybag_handle 0 - -#define bad_keybag_handle -1 - -enum keybag_state { - keybag_state_unlocked = 0, - keybag_state_locked = 1 << 0, - keybag_state_no_pin = 1 << 1, - keybag_state_been_unlocked = 1 << 2, -}; -typedef uint32_t keybag_state_t; -typedef int32_t keybag_handle_t; - -static kern_return_t aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state) { - if (state) *state = keybag_state_no_pin & keybag_state_been_unlocked; - return kIOReturnSuccess; -} - +#if __has_include() +#include #else +#undef INCLUDE_MOCK_AKS +#define INCLUDE_MOCK_AKS 1 +#endif -#include +#if __has_include() +#include +#else +#undef INCLUDE_MOCK_AKS +#define INCLUDE_MOCK_AKS 1 +#endif +#if INCLUDE_MOCK_AKS +#include "tests/secdmockaks/mockaks.h" #endif + +bool hwaes_key_available(void); + // // MARK: User lock state // enum { - user_keybag_handle = TARGET_OS_EMBEDDED ? device_keybag_handle : session_keybag_handle, + user_keybag_handle = (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) ? device_keybag_handle : session_keybag_handle, }; extern const char * const kUserKeybagStateChangeNotification; @@ -98,7 +90,7 @@ static inline bool SecAKSGetLockedState(keybag_state_t *state, CFErrorRef* error { kern_return_t status = aks_get_lock_state(user_keybag_handle, state); - return SecKernError(status, error, CFSTR("aks_get_lock_state failed: %d"), status); + return SecKernError(status, error, CFSTR("aks_get_lock_state failed: %x"), status); } // returns true if any of the bits in bits is set in the current state of the user bag @@ -138,15 +130,20 @@ static inline bool SecAKSGetHasBeenUnlocked(bool* hasBeenUnlocked, CFErrorRef* e return SecAKSLockedAnyStateBitIsSet(hasBeenUnlocked, keybag_state_been_unlocked, error); } -bool SecAKSDoWhileUserBagLocked(CFErrorRef *error, dispatch_block_t action); +bool SecAKSDoWithUserBagLockAssertion(CFErrorRef *error, dispatch_block_t action); + +//just like SecAKSDoWithUserBagLockAssertion, but always perform action regardless if we got the assertion or not +bool SecAKSDoWithUserBagLockAssertionSoftly(dispatch_block_t action); // // if you can't use the block version above, use these. // !!!!!Remember to balance them!!!!!! // -bool SecAKSUnLockUserKeybag(CFErrorRef *error); -bool SecAKSLockUserKeybag(uint64_t timeout, CFErrorRef *error); +bool SecAKSUserKeybagDropLockAssertion(CFErrorRef *error); +bool SecAKSUserKeybagHoldLockAssertion(uint64_t timeout, CFErrorRef *error); CFDataRef SecAKSCopyBackupBagWithSecret(size_t size, uint8_t *secret, CFErrorRef *error); +keyclass_t SecAKSSanitizedKeyclass(keyclass_t keyclass); + #endif diff --git a/OSX/utilities/src/SecAppleAnchor.c b/OSX/utilities/SecAppleAnchor.c similarity index 100% rename from OSX/utilities/src/SecAppleAnchor.c rename to OSX/utilities/SecAppleAnchor.c diff --git a/OSX/utilities/src/SecAppleAnchorPriv.h b/OSX/utilities/SecAppleAnchorPriv.h similarity index 100% rename from OSX/utilities/src/SecAppleAnchorPriv.h rename to OSX/utilities/SecAppleAnchorPriv.h diff --git a/OSX/utilities/src/SecAutorelease.h b/OSX/utilities/SecAutorelease.h similarity index 100% rename from OSX/utilities/src/SecAutorelease.h rename to OSX/utilities/SecAutorelease.h diff --git a/OSX/utilities/src/SecAutorelease.m b/OSX/utilities/SecAutorelease.m similarity index 100% rename from OSX/utilities/src/SecAutorelease.m rename to OSX/utilities/SecAutorelease.m diff --git a/OSX/utilities/src/SecBuffer.c b/OSX/utilities/SecBuffer.c similarity index 100% rename from OSX/utilities/src/SecBuffer.c rename to OSX/utilities/SecBuffer.c diff --git a/OSX/utilities/src/SecBuffer.h b/OSX/utilities/SecBuffer.h similarity index 100% rename from OSX/utilities/src/SecBuffer.h rename to OSX/utilities/SecBuffer.h diff --git a/OSX/utilities/src/SecCFCCWrappers.c b/OSX/utilities/SecCFCCWrappers.c similarity index 100% rename from OSX/utilities/src/SecCFCCWrappers.c rename to OSX/utilities/SecCFCCWrappers.c diff --git a/OSX/utilities/src/SecCFCCWrappers.h b/OSX/utilities/SecCFCCWrappers.h similarity index 100% rename from OSX/utilities/src/SecCFCCWrappers.h rename to OSX/utilities/SecCFCCWrappers.h diff --git a/OSX/utilities/src/SecCFError.c b/OSX/utilities/SecCFError.c similarity index 100% rename from OSX/utilities/src/SecCFError.c rename to OSX/utilities/SecCFError.c diff --git a/OSX/utilities/src/SecCFError.h b/OSX/utilities/SecCFError.h similarity index 99% rename from OSX/utilities/src/SecCFError.h rename to OSX/utilities/SecCFError.h index bc6ea016..3d6121ee 100644 --- a/OSX/utilities/src/SecCFError.h +++ b/OSX/utilities/SecCFError.h @@ -26,7 +26,7 @@ #define _SECCFERROR_H_ #include -#include +#include "utilities/SecCFRelease.h" // // Leaf error creation from other systems diff --git a/OSX/utilities/src/SecCFRelease.h b/OSX/utilities/SecCFRelease.h similarity index 100% rename from OSX/utilities/src/SecCFRelease.h rename to OSX/utilities/SecCFRelease.h diff --git a/OSX/utilities/src/SecCFWrappers.c b/OSX/utilities/SecCFWrappers.c similarity index 100% rename from OSX/utilities/src/SecCFWrappers.c rename to OSX/utilities/SecCFWrappers.c diff --git a/OSX/utilities/src/SecCFWrappers.h b/OSX/utilities/SecCFWrappers.h similarity index 98% rename from OSX/utilities/src/SecCFWrappers.h rename to OSX/utilities/SecCFWrappers.h index 82ad991c..b9672113 100644 --- a/OSX/utilities/src/SecCFWrappers.h +++ b/OSX/utilities/SecCFWrappers.h @@ -28,9 +28,9 @@ #include #include -#include -#include -#include +#include "utilities/SecCFRelease.h" +#include "utilities/debugging.h" +#include "utilities/SecCFError.h" #include @@ -42,6 +42,8 @@ #include +#include + #if __has_feature(objc_arc) #define __SECBRIDGE __bridge #else @@ -289,9 +291,9 @@ bool CFErrorPropagate(CFErrorRef possibleError CF_CONSUMED, CFErrorRef *error) { static inline bool CFErrorIsMalfunctioningKeybagError(CFErrorRef error){ switch(CFErrorGetCode(error)) { - case(kIOReturnError): - case(kIOReturnBusy): - case(kIOReturnNotPermitted): + case(kAKSReturnError): + case(kAKSReturnBusy): + case(kAKSReturnNoPermission): break; default: return false; @@ -873,9 +875,11 @@ static inline CFMutableArrayRef CFSetCopyValues(CFSetRef set) { static inline bool CFSetIntersectionIsEmpty(CFSetRef set1, CFSetRef set2) { __block bool intersectionIsEmpty = true; - CFSetForEach(set1, ^(const void *value) { - intersectionIsEmpty &= !CFSetContainsValue(set2, value); - }); + if(set1 != NULL && set2 != NULL) { + CFSetForEach(set1, ^(const void *value) { + intersectionIsEmpty &= !CFSetContainsValue(set2, value); + }); + } return intersectionIsEmpty; } diff --git a/OSX/utilities/SecCoreAnalytics.h b/OSX/utilities/SecCoreAnalytics.h new file mode 100644 index 00000000..244ffd28 --- /dev/null +++ b/OSX/utilities/SecCoreAnalytics.h @@ -0,0 +1,39 @@ +/* +* 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 + +#if __OBJC__ + +NS_ASSUME_NONNULL_BEGIN + +@interface SecCoreAnalytics : NSObject + ++ (void)sendEvent:(NSString*) eventName event:(NSDictionary *)event; ++ (void)sendEventLazy:(NSString*) eventName builder:(NSDictionary* (^)(void))builder; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* __OBCJ__ */ diff --git a/OSX/utilities/SecCoreAnalytics.m b/OSX/utilities/SecCoreAnalytics.m new file mode 100644 index 00000000..3e41cf17 --- /dev/null +++ b/OSX/utilities/SecCoreAnalytics.m @@ -0,0 +1,52 @@ +/* + * 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 "SecCoreAnalytics.h" +#import +#import +#import + +@implementation SecCoreAnalytics + +SOFT_LINK_FRAMEWORK_SAFE(PrivateFrameworks, CoreAnalytics); + +SOFT_LINK_FUNCTION(CoreAnalytics, AnalyticsSendEvent, soft_AnalyticsSendEvent, \ + void, (NSString* eventName, NSDictionary* eventPayload),(eventName, eventPayload)); +SOFT_LINK_FUNCTION(CoreAnalytics, AnalyticsSendEventLazy, soft_AnalyticsSendEventLazy, \ + void, (NSString* eventName, NSDictionary* (^eventPayloadBuilder)(void)),(eventName, eventPayloadBuilder)); + ++ (void)sendEvent:(NSString*) eventName event:(NSDictionary*)event +{ + if (isCoreAnalyticsAvailable()) { + soft_AnalyticsSendEvent(eventName, event); + } +} + ++ (void)sendEventLazy:(NSString*) eventName builder:(NSDictionary* (^)(void))builder +{ + if (isCoreAnalyticsAvailable()) { + soft_AnalyticsSendEventLazy(eventName, builder); + } +} + +@end diff --git a/OSX/utilities/src/SecCoreCrypto.c b/OSX/utilities/SecCoreCrypto.c similarity index 100% rename from OSX/utilities/src/SecCoreCrypto.c rename to OSX/utilities/SecCoreCrypto.c diff --git a/OSX/utilities/src/SecCoreCrypto.h b/OSX/utilities/SecCoreCrypto.h similarity index 100% rename from OSX/utilities/src/SecCoreCrypto.h rename to OSX/utilities/SecCoreCrypto.h diff --git a/OSX/utilities/src/SecDb.c b/OSX/utilities/SecDb.c similarity index 90% rename from OSX/utilities/src/SecDb.c rename to OSX/utilities/SecDb.c index 4260ed21..dbc32864 100644 --- a/OSX/utilities/src/SecDb.c +++ b/OSX/utilities/SecDb.c @@ -38,6 +38,8 @@ #include #include "Security/SecBase.h" #include "SecAutorelease.h" +#include +#include // xpc_transaction_exit_clean() // @@ -45,8 +47,10 @@ // These are in SecureObjectSync but utilities depends on them // Fix layer violation (SOSDigestVector, SOSManifest, SecDB.c) // -#include -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSManifest.h" + +#define SECDB_DEBUGGING 0 struct __OpaqueSecDbStatement { CFRuntimeBase _base; @@ -429,8 +433,6 @@ static uint8_t knownDbPathIndex(SecDbConnectionRef dbconn) static bool SecDbConnectionCheckCode(SecDbConnectionRef dbconn, int code, CFErrorRef *error, CFStringRef desc, ...) CF_FORMAT_FUNCTION(4, 5); - - // Return true if there was no error, returns false otherwise and set *error to an appropriate CFErrorRef. static bool SecDbConnectionCheckCode(SecDbConnectionRef dbconn, int code, CFErrorRef *error, CFStringRef desc, ...) { if (code == SQLITE_OK || code == SQLITE_DONE) @@ -541,6 +543,9 @@ static SecDbStepResult _SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, int s3e; int ntries = 0; for (;;) { + if (SecDbConnectionIsReadOnly(dbconn) && !sqlite3_stmt_readonly(stmt)) { + secerror("_SecDbStep: SecDbConnection is readonly but we're about to write: %s", sqlite3_sql(stmt)); + } s3e = sqlite3_step(stmt); if (s3e == SQLITE_ROW) { return kSecDbRowStep; @@ -746,10 +751,12 @@ bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, for (;;) { switch (_SecDbStep(dbconn, stmt, error)) { case kSecDbErrorStep: - secdebug("db", "kSecDbErrorStep %@", error?*error:NULL); + secdebug("db", "kSecDbErrorStep %@", error ? *error : NULL); return false; case kSecDbRowStep: - secdebug("db", "kSecDbRowStep %@", error?*error:NULL); +#if SECDB_DEBUGGING + secdebug("db", "kSecDbRowStep %@", error ? *error : NULL); +#endif if (row) { __block bool stop = false; SecAutoreleaseInvokeWithPool(^{ @@ -762,7 +769,9 @@ bool SecDbStep(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, SecDbError(SQLITE_ERROR, error, CFSTR("SecDbStep SQLITE_ROW returned without a row handler")); return false; case kSecDbDoneStep: - secdebug("db", "kSecDbDoneStep %@", error?*error:NULL); +#if SECDB_DEBUGGING + secdebug("db", "kSecDbDoneStep %@", error ? *error : NULL); +#endif return true; } } @@ -804,15 +813,14 @@ static sqlite3 *_SecDbOpenV2(const char *path, * set it to incremental and vacuum. */ - int s3e = sqlite3_prepare_v2(handle, "PRAGMA auto_vacuum", -1, &stmt, NULL); + 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); + (void)sqlite3_finalize(stmt); } - sqlite3_finalize(stmt); if (vacuumMode != SECDB_SQLITE_AUTO_VACUUM_INCREMENTAL) { (void)sqlite3_exec(handle, "PRAGMA auto_vacuum = incremental", NULL, NULL, NULL); @@ -833,110 +841,82 @@ static bool SecDbOpenV2(SecDbConnectionRef dbconn, const char *path, int flags, return (dbconn->handle = _SecDbOpenV2(path, flags, dbconn->db->useWAL, dbconn->db->useRobotVacuum, error)) != NULL; } -static bool SecDbTruncate(SecDbConnectionRef dbconn, CFErrorRef *error) +// This construction lets tests not exit here +static void SecDbProductionCorruptionExitHandler(void) { - int flags = SQLITE_TRUNCATE_AUTOVACUUM_FULL; - if (dbconn->db->useWAL) { - flags |= SQLITE_TRUNCATE_JOURNALMODE_WAL; - } - __block bool ok = SecDbFileControl(dbconn, SQLITE_TRUNCATE_DATABASE, &flags, error); - if (!ok) { - sqlite3_close(dbconn->handle); - dbconn->handle = NULL; - CFStringPerformWithCString(dbconn->db->db_path, ^(const char *path) { - if (error) - CFReleaseNull(*error); - if (SecCheckErrno(unlink(path), error, CFSTR("unlink %s"), path)) { - ok = SecDbOpenHandle(dbconn, NULL, error); - } - }); - if (!ok) { - secinfo("#SecDB", "#SecDB Failed to delete db handle: %{public}@", error ? *error : NULL); - abort(); - } - } + exit(EXIT_FAILURE); +} +void (*SecDbCorruptionExitHandler)(void) = SecDbProductionCorruptionExitHandler; - return ok; +void SecDbResetCorruptionExitHandler(void) +{ + SecDbCorruptionExitHandler = SecDbProductionCorruptionExitHandler; } +/* + There's not much to do in here because we should only ever be here when + SQLite tells us the DB is corrupt, or the DB is unrecoverable because of + some fatal logic problem. But we can't shoot it dead either due to client + connections. So, first we create a marker to tell ourselves things are bad, + then we'll die. When we come back up we'll notice the marker and remove the DB. + */ static bool SecDbHandleCorrupt(SecDbConnectionRef dbconn, int rc, CFErrorRef *error) { if (!dbconn->db->allowRepair) { SecCFCreateErrorWithFormat(rc, kSecErrnoDomain, NULL, error, NULL, - CFSTR("SecDbHandleCorrupt handled error: [%d] %s"), rc, strerror(rc)); + CFSTR("SecDbHandleCorrupt not allowed to repair, handled error: [%d] %s"), rc, strerror(rc)); dbconn->isCorrupted = false; return false; } - // Backup current db. - __block bool didRename = false; CFStringPerformWithCString(dbconn->db->db_path, ^(const char *db_path) { - 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, 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")); - sqlite3_close(corrupt_db); + char marker[PATH_MAX+1]; + snprintf(marker, sizeof(marker), "%s-iscorrupt", db_path); + struct stat info = {}; + if (0 == stat(marker, &info)) { + secerror("SecDbHandleCorrupt: Tried to write corruption marker %s but one already exists", marker); } - if (!didRename) { - if (dbconn->handle) - secerror("Tried to rename corrupt database at path %@, but we failed: %@, trying explicit rename", dbconn->db->db_path, error ? *error : NULL); - if (error) - CFReleaseNull(*error); - - // Explicitly close our connection, plus all other open connections to this db. - bool closed = true; - if (dbconn->handle) { - closed &= SecDbError(sqlite3_close(dbconn->handle), error, CFSTR("close")); - dbconn->handle = NULL; - } - SecDbRef db = dbconn->db; - CFIndex idx, count = (db->connections) ? CFArrayGetCount(db->connections) : 0; - for (idx = 0; idx < count; idx++) { - SecDbConnectionRef dbconn = (SecDbConnectionRef) CFArrayGetValueAtIndex(db->connections, idx); - if (dbconn && dbconn->handle) { - closed &= SecDbError(sqlite3_close(dbconn->handle), error, CFSTR("close")); - dbconn->handle = NULL; - } - } - CFArrayRemoveAllValues(db->connections); - // Attempt rename only if all connections closed successfully. - if (closed) { - if (SecCheckErrno(rename(db_path, buf), error, CFSTR("rename %s %s"), db_path, buf)) { - if (SecDbOpenHandle(dbconn, NULL, error)) { - didRename = true; - } - } - } - } - if (didRename) { - secerror("Database at path %@ is corrupt. Copied it to %s for further investigation.", dbconn->db->db_path, buf); + FILE* file = fopen(marker, "w"); + if (file == NULL) { + secerror("SecDbHandleCorrupt: Unable (%{darwin.errno}d) to create corruption marker %{public}s", errno, marker); } else { - seccritical("Tried to copy corrupt database at path %@, but we failed: %@", dbconn->db->db_path, error ? *error : NULL); + fclose(file); } }); - bool ok = (didRename && - (dbconn->handle || SecDbOpenHandle(dbconn, NULL, error)) && - SecDbTruncate(dbconn, error)); - - // Mark the db as not corrupted, even if something failed. - // Always note we are no longer in the corruption handler - dbconn->isCorrupted = false; + secwarning("SecDbHandleCorrupt: killing self so that successor might cleanly delete corrupt db"); - // Invoke our callers opened callback, since we just created a new database - if (ok && dbconn->db->opened) { - dbconn->db->callOpenedHandlerForNextConnection = false; - ok = dbconn->db->opened(dbconn->db, dbconn, true, &dbconn->db->callOpenedHandlerForNextConnection, error); - } + // Call through function pointer so tests can replace it and call a SecKeychainDbReset instead + SecDbCorruptionExitHandler(); + return true; +} - if (dbconn->db->corruptionReset) { - dbconn->db->corruptionReset(); - } +static bool SecDbProcessCorruptionMarker(CFStringRef db_path) { + __block bool ok = true; + CFStringPerformWithCString(db_path, ^(const char *db_path) { + char marker[PATH_MAX+1]; + snprintf(marker, sizeof(marker), "%s-iscorrupt", db_path); + struct stat info = {}; + int result = stat(marker, &info); + if (result != 0 && errno == ENOENT) { + return; + } else if (result != 0) { + secerror("SecDbSecDbProcessCorruptionMarker: Unable to check for corruption marker: %{darwin.errno}d", errno); + return; + } + secwarning("SecDbSecDbProcessCorruptionMarker: found corruption marker %s", marker); + if (remove(marker)) { + secerror("SecDbSecDbProcessCorruptionMarker: Unable (%{darwin.errno}d) to delete corruption marker", errno); + ok = false; + } else if (remove(db_path) && errno != ENOENT) { // Not sure how we'd get ENOENT but it would suit us just fine + secerror("SecDbSecDbProcessCorruptionMarker: Unable (%{darwin.errno}d) to delete db %{public}s", errno, db_path); + ok = false; + } else { + secwarning("SecDbSecDbProcessCorruptionMarker: deleted corrupt db %{public}s", db_path); + } + }); return ok; } @@ -1014,7 +994,9 @@ SecDbTraceV2(unsigned mask, void *ctx, void *p, void *x) { trace = sqlite3_expanded_sql(p); } +#if SECDB_DEBUGGING secinfo("#SecDB", "#SecDB %{public}s", trace); +#endif return 0; } @@ -1023,6 +1005,13 @@ static bool SecDbOpenHandle(SecDbConnectionRef dbconn, bool *created, CFErrorRef { __block bool ok = true; + // This is pretty terrible because now what? We know we have a corrupt DB + // and now we can't get rid of it. + if (!SecDbProcessCorruptionMarker(dbconn->db->db_path)) { + SecCFCreateErrorWithFormat(errno, kSecErrnoDomain, NULL, error, NULL, CFSTR("Unable to process corruption marker: %{darwin.errno}d"), errno); + return false; + } + CFStringPerformWithCString(dbconn->db->db_path, ^(const char *db_path) { int flags = (dbconn->db->readWrite) ? SQLITE_OPEN_READWRITE : SQLITE_OPEN_READONLY; ok = created && SecDbOpenV2(dbconn, db_path, flags, NULL); @@ -1090,7 +1079,7 @@ done: return dbconn; } -static bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn) { +bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn) { return dbconn->readOnly; } @@ -1109,7 +1098,9 @@ SecDbConnectionRef SecDbConnectionAcquire(SecDbRef db, bool readOnly, CFErrorRef bool SecDbConnectionAcquireRefMigrationSafe(SecDbRef db, bool readOnly, SecDbConnectionRef* dbconnRef, CFErrorRef *error) { CFRetain(db); +#if SECDB_DEBUGGING secinfo("dbconn", "acquire %s connection", readOnly ? "ro" : "rw"); +#endif dispatch_semaphore_wait(readOnly ? db->read_semaphore : db->write_semaphore, DISPATCH_TIME_FOREVER); __block SecDbConnectionRef dbconn = NULL; __block bool ok = true; @@ -1210,7 +1201,9 @@ void SecDbConnectionRelease(SecDbConnectionRef dbconn) { return; } SecDbRef db = dbconn->db; +#if SECDB_DEBUGGING secinfo("dbconn", "release %@", dbconn); +#endif dispatch_sync(db->queue, ^{ bool readOnly = SecDbConnectionIsReadOnly(dbconn); if (dbconn->hasIOFailure) { @@ -1289,6 +1282,7 @@ SecDbConnectionDestroy(CFTypeRef value) if (s3e != SQLITE_OK) { secerror("failed to close database connection (%d) for %@: %s", s3e, dbconn->db->db_path, sqlite3_errmsg(dbconn->handle)); } + os_assert(s3e == SQLITE_OK); // Crash now or jetsam later } dbconn->db = NULL; CFReleaseNull(dbconn->changes); @@ -1311,14 +1305,9 @@ void SecDbPerformOnCommitQueue(SecDbConnectionRef dbconn, bool barrier, dispatch // MARK: - // MARK: Bind helpers -#if 0 -bool SecDbBindNull(sqlite3_stmt *stmt, int param, CFErrorRef *error) { - bool ok = SecDbErrorWithStmt(sqlite3_bind_null(stmt, param), - stmt, error, CFSTR("bind_null[%d]"), param); - secinfo("bind", "bind_null[%d] error: %@", param, error ? *error : NULL); - return ok; -} -#endif +// Logging binds is very spammy when debug logging is on (~90% of log lines), and isn't often useful. +// Enable this in your local build if you actually want every single SQL variable bind logged for debugging. +#define LOG_SECDB_BINDS 0 bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error) { if (n > INT_MAX) { @@ -1327,7 +1316,9 @@ bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, v } bool ok = SecDbErrorWithStmt(sqlite3_bind_blob(stmt, param, zData, (int)n, xDel), stmt, error, CFSTR("bind_blob[%d]"), param); - secinfo("bind", "bind_blob[%d]: %.*s: %@", param, (int)n, zData, error ? *error : NULL); +#if LOG_SECDB_BINDS + secinfo("bind", "bind_blob[%d]: %.*P: %@", param, (int)n, zData, error ? *error : NULL); +#endif return ok; } @@ -1338,28 +1329,36 @@ bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, v } bool ok = SecDbErrorWithStmt(sqlite3_bind_text(stmt, param, zData, (int)n, xDel), stmt, error, CFSTR("bind_text[%d]"), param); +#if LOG_SECDB_BINDS secinfo("bind", "bind_text[%d]: \"%s\" error: %@", param, zData, error ? *error : NULL); +#endif return ok; } bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error) { bool ok = SecDbErrorWithStmt(sqlite3_bind_double(stmt, param, value), stmt, error, CFSTR("bind_double[%d]"), param); +#if LOG_SECDB_BINDS secinfo("bind", "bind_double[%d]: %f error: %@", param, value, error ? *error : NULL); +#endif return ok; } bool SecDbBindInt(sqlite3_stmt *stmt, int param, int value, CFErrorRef *error) { bool ok = SecDbErrorWithStmt(sqlite3_bind_int(stmt, param, value), stmt, error, CFSTR("bind_int[%d]"), param); +#if LOG_SECDB_BINDS secinfo("bind", "bind_int[%d]: %d error: %@", param, value, error ? *error : NULL); +#endif return ok; } bool SecDbBindInt64(sqlite3_stmt *stmt, int param, sqlite3_int64 value, CFErrorRef *error) { bool ok = SecDbErrorWithStmt(sqlite3_bind_int64(stmt, param, value), stmt, error, CFSTR("bind_int64[%d]"), param); +#if LOG_SECDB_BINDS secinfo("bind", "bind_int64[%d]: %lld error: %@", param, value, error ? *error : NULL); +#endif return ok; } @@ -1377,11 +1376,7 @@ bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef if (!value || (valueId = CFGetTypeID(value)) == CFNullGetTypeID()) { /* Skip bindings for NULL values. sqlite3 will interpret unbound params as NULL which is exactly what we want. */ -#if 1 result = true; -#else - result = SecDbBindNull(stmt, param, error); -#endif } else if (valueId == CFStringGetTypeID()) { CFStringPerformWithCStringAndLength(value, ^(const char *cstr, size_t clen) { result = SecDbBindText(stmt, param, cstr, clen, SQLITE_TRANSIENT, error); @@ -1407,15 +1402,10 @@ bool SecDbBindObject(sqlite3_stmt *stmt, int param, CFTypeRef value, CFErrorRef convertOk = CFNumberGetValue(value, kCFNumberDoubleType, &nval); result = SecDbBindDouble(stmt, param, nval, error); } else { - SInt32 nval; - convertOk = CFNumberGetValue(value, kCFNumberSInt32Type, &nval); + sqlite_int64 nval64; + convertOk = CFNumberGetValue(value, kCFNumberSInt64Type, &nval64); if (convertOk) { - result = SecDbBindInt(stmt, param, nval, error); - } else { - sqlite_int64 nval64; - convertOk = CFNumberGetValue(value, kCFNumberSInt64Type, &nval64); - if (convertOk) - result = SecDbBindInt64(stmt, param, nval64, error); + result = SecDbBindInt64(stmt, param, nval64, error); } } if (!convertOk) { @@ -1548,13 +1538,15 @@ bool SecDbWithSQL(SecDbConnectionRef dbconn, CFStringRef sql, CFErrorRef *error, return ok; } -#if 1 /* SecDbForEach returns true if all SQLITE_ROW returns of sqlite3_step() return true from the row block. If the row block returns false and doesn't set an error (to indicate it has reached a limit), this entire function returns false. In that case no error will be set. */ bool SecDbForEach(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index)) { bool result = false; for (int row_ix = 0;;++row_ix) { + if (SecDbConnectionIsReadOnly(dbconn) && !sqlite3_stmt_readonly(stmt)) { + secerror("SecDbForEach: SecDbConnection is readonly but we're about to write: %s", sqlite3_sql(stmt)); + } int s3e = sqlite3_step(stmt); if (s3e == SQLITE_ROW) { if (row) { @@ -1578,27 +1570,6 @@ bool SecDbForEach(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *err } return result; } -#else -bool SecDbForEach(sqlite3_stmt *stmt, CFErrorRef *error, bool(^row)(int row_index)) { - int row_ix = 0; - for (;;) { - switch (_SecDbStep(dbconn, stmt, error)) { - case kSecDbErrorStep: - return false; - case kSecDbRowStep: - if (row) { - if (row(row_ix++)) - break; - } else { - SecDbError(SQLITE_ERROR, error, CFSTR("SecDbStep SQLITE_ROW returned without a row handler")); - } - return false; - case kSecDbDoneStep: - return true; - } - } -} -#endif void SecDbRecordChange(SecDbConnectionRef dbconn, CFTypeRef deleted, CFTypeRef inserted) { if (!dbconn->db->notifyPhase) return; diff --git a/OSX/utilities/src/SecDb.h b/OSX/utilities/SecDb.h similarity index 95% rename from OSX/utilities/src/SecDb.h rename to OSX/utilities/SecDb.h index 598374c4..b3c90402 100644 --- a/OSX/utilities/src/SecDb.h +++ b/OSX/utilities/SecDb.h @@ -58,7 +58,7 @@ typedef CFOptionFlags SecDbTransactionType; enum SecDbTransactionPhase { kSecDbTransactionDidRollback = 0, // A transaction just got rolled back kSecDbTransactionWillCommit, // A transaction is about to commit. - kSecDbTransactionDidCommit, // A transnaction sucessfully committed. + kSecDbTransactionDidCommit, // A transnaction successfully committed. }; typedef CFOptionFlags SecDbTransactionPhase; @@ -145,6 +145,8 @@ bool SecDbTransaction(SecDbConnectionRef dbconn, SecDbTransactionType ttype, CFE sqlite3 *SecDbHandle(SecDbConnectionRef dbconn); +bool SecDbConnectionIsReadOnly(SecDbConnectionRef dbconn); + // Do not call this unless you are SecDbItem! void SecDbRecordChange(SecDbConnectionRef dbconn, CFTypeRef deleted, CFTypeRef inserted); @@ -154,9 +156,6 @@ void SecDBManagementTasks(SecDbConnectionRef dbconn); // MARK: - // MARK: Bind helpers -#if 0 -bool SecDbBindNull(sqlite3_stmt *stmt, int param, CFErrorRef *error); -#endif bool SecDbBindBlob(sqlite3_stmt *stmt, int param, const void *zData, size_t n, void(*xDel)(void*), CFErrorRef *error); bool SecDbBindText(sqlite3_stmt *stmt, int param, const char *zData, size_t n, void(*xDel)(void*), CFErrorRef *error); bool SecDbBindDouble(sqlite3_stmt *stmt, int param, double value, CFErrorRef *error); @@ -179,6 +178,9 @@ bool SecDbForEach(SecDbConnectionRef dbconn, sqlite3_stmt *stmt, CFErrorRef *err // Mark the database as corrupted. void SecDbCorrupt(SecDbConnectionRef dbconn, CFErrorRef error); +// Testing only. Normally this calls exit() so make it do something more test-friendly instead +extern void (*SecDbCorruptionExitHandler)(void); +void SecDbResetCorruptionExitHandler(void); __END_DECLS #endif /* !_UTILITIES_SECDB_H_ */ diff --git a/OSX/utilities/src/SecDispatchRelease.h b/OSX/utilities/SecDispatchRelease.h similarity index 100% rename from OSX/utilities/src/SecDispatchRelease.h rename to OSX/utilities/SecDispatchRelease.h diff --git a/OSX/utilities/src/SecFileLocations.c b/OSX/utilities/SecFileLocations.c similarity index 85% rename from OSX/utilities/src/SecFileLocations.c rename to OSX/utilities/SecFileLocations.c index 65ff60b4..ffe3923b 100644 --- a/OSX/utilities/src/SecFileLocations.c +++ b/OSX/utilities/SecFileLocations.c @@ -58,19 +58,13 @@ CFURLRef SecCopyHomeURL(void) if (homeURL) { CFRetain(homeURL); } else { -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - // We would use CFCopyHomeDirectoryURL but it doesn't exist on MACOS. - // This does the same. - homeURL = CFCopyHomeDirectoryURLForUser(NULL); -#else homeURL = CFCopyHomeDirectoryURL(); -#endif } return homeURL; } -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX static const char * get_host_uuid() { static uuid_string_t hostuuid = {}; @@ -127,22 +121,29 @@ static bool keychain_verify_create_path(const char *keychainBasePath) } } if (!created) { - require_action(mkpath_np(kb_path, 0700) == 0, done, secerror("could not create path: %s (%s)", kb_path, strerror(errno))); + errno_t err = mkpath_np(kb_path, 0700); + require_action(err == 0 || err == EEXIST, done, secerror("could not create path: %s (%s)", kb_path, strerror(err))); created = true; } done: return created; } -#endif /*(TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */ +#endif /* TARGET_OS_OSX */ -static CFURLRef SecCopyBaseFilesURL() +static CFURLRef SecCopyBaseFilesURL(bool system) { CFURLRef baseURL = sCustomHomeURL; if (baseURL) { CFRetain(baseURL); } else { -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED)) +#if TARGET_OS_OSX + if (system) { + baseURL = CFURLCreateWithFileSystemPath(NULL, CFSTR("/"), kCFURLPOSIXPathStyle, true); + } else { + baseURL = SecCopyHomeURL(); + } +#elif TARGET_OS_SIMULATOR baseURL = SecCopyHomeURL(); #else baseURL = CFURLCreateWithFileSystemPath(NULL, CFSTR("/"), kCFURLPOSIXPathStyle, true); @@ -151,11 +152,11 @@ static CFURLRef SecCopyBaseFilesURL() return baseURL; } -static CFURLRef SecCopyURLForFileInBaseDirectory(CFStringRef directoryPath, CFStringRef fileName) +static CFURLRef SecCopyURLForFileInBaseDirectory(bool system, CFStringRef directoryPath, CFStringRef fileName) { CFURLRef fileURL = NULL; CFStringRef suffix = NULL; - CFURLRef homeURL = SecCopyBaseFilesURL(); + CFURLRef homeURL = SecCopyBaseFilesURL(system); if (fileName) suffix = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@/%@"), directoryPath, fileName); @@ -172,14 +173,14 @@ static CFURLRef SecCopyURLForFileInBaseDirectory(CFStringRef directoryPath, CFSt CFURLRef SecCopyURLForFileInKeychainDirectory(CFStringRef fileName) { -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX // need to tack on uuid here Boolean isDirectory = (fileName == NULL); CFURLRef resultURL = NULL; CFStringRef resultStr = NULL; __block bool directoryExists = false; - CFURLRef keyChainBaseURL = SecCopyURLForFileInBaseDirectory(CFSTR("Library/Keychains"), NULL); + CFURLRef keyChainBaseURL = SecCopyURLForFileInBaseDirectory(false, CFSTR("Library/Keychains"), NULL); CFStringRef uuid_path = copy_keychain_uuid_path(keyChainBaseURL); CFStringPerformWithCString(uuid_path, ^(const char *utf8Str) { directoryExists = keychain_verify_create_path(utf8Str); @@ -199,11 +200,15 @@ done: CFRelease(resultStr); } return resultURL; -#else - return SecCopyURLForFileInBaseDirectory(CFSTR("Library/Keychains"), fileName); +#else /* !TARGET_OS_OSX */ + return SecCopyURLForFileInBaseDirectory(true, CFSTR("Library/Keychains"), fileName); #endif } +CFURLRef SecCopyURLForFileInSystemKeychainDirectory(CFStringRef fileName) { + return SecCopyURLForFileInBaseDirectory(true, CFSTR("Library/Keychains"), fileName); +} + CFURLRef SecCopyURLForFileInUserCacheDirectory(CFStringRef fileName) { #if TARGET_OS_OSX @@ -223,13 +228,13 @@ CFURLRef SecCopyURLForFileInUserCacheDirectory(CFStringRef fileName) CFReleaseSafe(cacheDirStr); return resultURL; #else - return SecCopyURLForFileInBaseDirectory(CFSTR("Library/Caches"), fileName); + return SecCopyURLForFileInBaseDirectory(true, CFSTR("Library/Caches"), fileName); #endif } CFURLRef SecCopyURLForFileInPreferencesDirectory(CFStringRef fileName) { - return SecCopyURLForFileInBaseDirectory(CFSTR("Library/Preferences"), fileName); + return SecCopyURLForFileInBaseDirectory(false, CFSTR("Library/Preferences"), fileName); } CFURLRef SecCopyURLForFileInManagedPreferencesDirectory(CFStringRef fileName) @@ -237,7 +242,7 @@ CFURLRef SecCopyURLForFileInManagedPreferencesDirectory(CFStringRef fileName) CFURLRef resultURL = NULL; CFStringRef userName; -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX userName = CFCopyUserName(); #else userName = CFStringCreateWithCString(kCFAllocatorDefault, "mobile", kCFStringEncodingASCII); @@ -257,13 +262,7 @@ CFURLRef SecCopyURLForFileInManagedPreferencesDirectory(CFStringRef fileName) CFURLRef SecCopyURLForFileInRevocationInfoDirectory(CFStringRef fileName) { - CFURLRef resultURL = NULL; - CFStringRef path = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("/Library/Keychains/crls/%@"), fileName); - if (path) { - resultURL = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, false); - CFReleaseSafe(path); - } - return resultURL; + return SecCopyURLForFileInBaseDirectory(true, CFSTR("Library/Keychains/crls/"), fileName); } static void WithPathInDirectory(CFURLRef fileURL, void(^operation)(const char *utf8String)) diff --git a/OSX/utilities/src/SecFileLocations.h b/OSX/utilities/SecFileLocations.h similarity index 86% rename from OSX/utilities/src/SecFileLocations.h rename to OSX/utilities/SecFileLocations.h index fb434a23..09dcd233 100644 --- a/OSX/utilities/src/SecFileLocations.h +++ b/OSX/utilities/SecFileLocations.h @@ -34,11 +34,12 @@ __BEGIN_DECLS -CFURLRef SecCopyURLForFileInKeychainDirectory(CFStringRef fileName); -CFURLRef SecCopyURLForFileInUserCacheDirectory(CFStringRef fileName); -CFURLRef SecCopyURLForFileInPreferencesDirectory(CFStringRef fileName); -CFURLRef SecCopyURLForFileInManagedPreferencesDirectory(CFStringRef fileName); -CFURLRef SecCopyURLForFileInRevocationInfoDirectory(CFStringRef fileName); +CFURLRef SecCopyURLForFileInKeychainDirectory(CFStringRef fileName) CF_RETURNS_RETAINED; +CFURLRef SecCopyURLForFileInSystemKeychainDirectory(CFStringRef fileName) CF_RETURNS_RETAINED; +CFURLRef SecCopyURLForFileInUserCacheDirectory(CFStringRef fileName) CF_RETURNS_RETAINED; +CFURLRef SecCopyURLForFileInPreferencesDirectory(CFStringRef fileName) CF_RETURNS_RETAINED; +CFURLRef SecCopyURLForFileInManagedPreferencesDirectory(CFStringRef fileName) CF_RETURNS_RETAINED; +CFURLRef SecCopyURLForFileInRevocationInfoDirectory(CFStringRef fileName) CF_RETURNS_RETAINED; void WithPathInKeychainDirectory(CFStringRef fileName, void(^operation)(const char *utf8String)); void WithPathInRevocationInfoDirectory(CFStringRef fileName, void(^operation)(const char *utf8String)); @@ -48,7 +49,7 @@ void SetCustomHomePath(const char* path); void SetCustomHomeURLString(CFStringRef path); void SetCustomHomeURL(CFURLRef url); -CFURLRef SecCopyHomeURL(void); +CFURLRef SecCopyHomeURL(void) CF_RETURNS_RETAINED; __END_DECLS diff --git a/OSX/utilities/src/SecIOFormat.h b/OSX/utilities/SecIOFormat.h similarity index 100% rename from OSX/utilities/src/SecIOFormat.h rename to OSX/utilities/SecIOFormat.h diff --git a/OSX/utilities/src/SecInternalRelease.c b/OSX/utilities/SecInternalRelease.c similarity index 100% rename from OSX/utilities/src/SecInternalRelease.c rename to OSX/utilities/SecInternalRelease.c diff --git a/OSX/utilities/src/SecInternalReleasePriv.h b/OSX/utilities/SecInternalReleasePriv.h similarity index 100% rename from OSX/utilities/src/SecInternalReleasePriv.h rename to OSX/utilities/SecInternalReleasePriv.h diff --git a/OSX/utilities/src/SecNSAdditions.h b/OSX/utilities/SecNSAdditions.h similarity index 100% rename from OSX/utilities/src/SecNSAdditions.h rename to OSX/utilities/SecNSAdditions.h diff --git a/OSX/utilities/src/SecNSAdditions.m b/OSX/utilities/SecNSAdditions.m similarity index 100% rename from OSX/utilities/src/SecNSAdditions.m rename to OSX/utilities/SecNSAdditions.m diff --git a/OSX/utilities/src/SecPLWrappers.h b/OSX/utilities/SecPLWrappers.h similarity index 100% rename from OSX/utilities/src/SecPLWrappers.h rename to OSX/utilities/SecPLWrappers.h diff --git a/OSX/utilities/src/SecPLWrappers.m b/OSX/utilities/SecPLWrappers.m similarity index 94% rename from OSX/utilities/src/SecPLWrappers.m rename to OSX/utilities/SecPLWrappers.m index d4e915b4..e4f76b20 100644 --- a/OSX/utilities/src/SecPLWrappers.m +++ b/OSX/utilities/SecPLWrappers.m @@ -25,7 +25,7 @@ #include #include "SecPLWrappers.h" -#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE +#if !TARGET_OS_SIMULATOR && !TARGET_OS_BRIDGE #include static typeof(PLShouldLogRegisteredEvent) *soft_PLShouldLogRegisteredEvent = NULL; @@ -63,12 +63,11 @@ setup(void) return bundle != NULL; } - #endif bool SecPLShouldLogRegisteredEvent(NSString *event) { -#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE +#if !TARGET_OS_SIMULATOR && !TARGET_OS_BRIDGE if (setup()) return soft_PLShouldLogRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)event); #endif @@ -77,7 +76,7 @@ bool SecPLShouldLogRegisteredEvent(NSString *event) void SecPLLogRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary) { -#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE +#if !TARGET_OS_SIMULATOR && !TARGET_OS_BRIDGE if (setup()) soft_PLLogRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)eventName, @@ -88,7 +87,7 @@ void SecPLLogRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary) void SecPLLogTimeSensitiveRegisteredEvent(NSString *eventName, NSDictionary *eventDictionary) { -#if TARGET_OS_EMBEDDED && !TARGET_OS_BRIDGE +#if !TARGET_OS_SIMULATOR && !TARGET_OS_BRIDGE if (setup()) soft_PLLogTimeSensitiveRegisteredEvent(PLClientIDSecurity, (__bridge CFStringRef)eventName, diff --git a/OSX/utilities/src/SecPaddingConfigurations.c b/OSX/utilities/SecPaddingConfigurations.c similarity index 98% rename from OSX/utilities/src/SecPaddingConfigurations.c rename to OSX/utilities/SecPaddingConfigurations.c index c20e38e8..6ecdc87e 100644 --- a/OSX/utilities/src/SecPaddingConfigurations.c +++ b/OSX/utilities/SecPaddingConfigurations.c @@ -30,7 +30,7 @@ typedef enum { #include "debugging.h" #include "SecCFError.h" #include "SecCFWrappers.h" -#include "SecPaddingConfigurationsPriv.h" +#include #pragma mark Padding Helper Methods diff --git a/OSX/utilities/src/SecPaddingConfigurationsPriv.h b/OSX/utilities/SecPaddingConfigurationsPriv.h similarity index 100% rename from OSX/utilities/src/SecPaddingConfigurationsPriv.h rename to OSX/utilities/SecPaddingConfigurationsPriv.h diff --git a/OSX/utilities/src/SecSCTUtils.c b/OSX/utilities/SecSCTUtils.c similarity index 100% rename from OSX/utilities/src/SecSCTUtils.c rename to OSX/utilities/SecSCTUtils.c diff --git a/OSX/utilities/src/SecSCTUtils.h b/OSX/utilities/SecSCTUtils.h similarity index 100% rename from OSX/utilities/src/SecSCTUtils.h rename to OSX/utilities/SecSCTUtils.h diff --git a/OSX/utilities/SecTapToRadar.h b/OSX/utilities/SecTapToRadar.h new file mode 100644 index 00000000..fbc593c4 --- /dev/null +++ b/OSX/utilities/SecTapToRadar.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019 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 SecTapToRadar : NSObject + +@property NSString* componentID; +@property NSString* componentName; +@property NSString* componentVersion; + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initTapToRadar:(NSString *)alert + description:(NSString *)description + radar:(NSString *)radarnumber; + +- (void)trigger; + +- (void)clearRetryTimestamp; +- (void)updateRetryTimestamp; +- (BOOL)isRateLimited; + ++ (NSString *)keyname:(SecTapToRadar *)ttrRequest; ++ (BOOL)isRateLimited:(SecTapToRadar *)ttrRequest; ++ (BOOL)askUserIfTTR:(SecTapToRadar *)ttrRequest; ++ (void)triggerTapToRadar:(SecTapToRadar *)ttrRequest; + ++ (void)disableTTRsEntirely; + +@end + +NS_ASSUME_NONNULL_END diff --git a/OSX/utilities/SecTapToRadar.m b/OSX/utilities/SecTapToRadar.m new file mode 100644 index 00000000..358dc6da --- /dev/null +++ b/OSX/utilities/SecTapToRadar.m @@ -0,0 +1,225 @@ +/* + * Copyright (c) 2019 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 "SecTapToRadar.h" +#import "utilities/debugging.h" + +#if TARGET_OS_IOS + +#import +#import +#import + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" +SOFT_LINK_FRAMEWORK(Frameworks, MobileCoreServices) +SOFT_LINK_CLASS(MobileCoreServices, LSApplicationWorkspace); +#pragma clang diagnostic pop + +#endif + +#include "utilities/SecInternalReleasePriv.h" + +static NSString* kSecNextTTRDate = @"NextTTRDate"; +static NSString* kSecPreferenceDomain = @"com.apple.security"; + +@interface SecTapToRadar () +@property (readwrite) NSString *alert; +@property (readwrite) NSString *radarDescription; +@property (readwrite) NSString *radarnumber; +@property (readwrite) dispatch_queue_t queue; + +@end + +static BOOL SecTTRDisabled = true; + +@implementation SecTapToRadar + +- (instancetype)initTapToRadar:(NSString *)alert + description:(NSString *)radarDescription + radar:(NSString *)radarnumber +{ + if ((self = [super init]) == nil) { + return nil; + } + + _alert = alert; + _radarDescription = radarDescription; + _radarnumber = radarnumber; + _queue = dispatch_queue_create("com.apple.security.diagnostic-queue", 0); + dispatch_set_target_queue(_queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)); + + _componentName = @"Security"; + _componentVersion = @"all"; + _componentID = @"606179"; + + return self; +} + ++ (NSString *)keyname:(SecTapToRadar *)ttrRequest +{ + return [NSString stringWithFormat:@"%@-%@", kSecNextTTRDate, ttrRequest.radarnumber]; +} + ++ (BOOL)isRateLimited:(SecTapToRadar *)ttrRequest +{ + return SecTTRDisabled || [ttrRequest isRateLimited]; +} + +- (BOOL)isRateLimited +{ + NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:kSecPreferenceDomain]; + + NSString *key = [[self class] keyname: self]; + NSDate *val = [defaults valueForKey:key]; + if (![val isKindOfClass:[NSDate class]]) { + [defaults removeObjectForKey:key]; + return NO; + } + + if ([val compare:[NSDate date]] == NSOrderedAscending) { + return NO; + } + + return YES; +} + ++ (void)disableTTRsEntirely { + SecTTRDisabled = YES; +} + + +- (void)updateRetryTimestamp +{ + NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:kSecPreferenceDomain]; + [defaults setObject:[[NSDate date] dateByAddingTimeInterval:24*3600.0] + forKey:[[self class] keyname: self]]; +} + +- (void)clearRetryTimestamp +{ + NSUserDefaults* defaults = [[NSUserDefaults alloc] initWithSuiteName:kSecPreferenceDomain]; + [defaults removeObjectForKey:[[self class] keyname: self]]; +} + + ++ (void)triggerTapToRadar:(SecTapToRadar *)ttrRequest +{ + secnotice("secttr", "Triggering TTR: %@", ttrRequest.alert); + dispatch_assert_queue(ttrRequest.queue); + +#if TARGET_OS_IOS + static dispatch_once_t onceToken; + static NSMutableCharacterSet *queryComponent; + dispatch_once(&onceToken, ^{ + queryComponent = [[NSMutableCharacterSet alloc] init]; + [queryComponent formUnionWithCharacterSet:[NSCharacterSet URLQueryAllowedCharacterSet]]; + [queryComponent removeCharactersInString:@"&"]; + }); + + Class workspaceCls = getLSApplicationWorkspaceClass(); + if (workspaceCls == NULL) { + return; + } + + NSString *title = [NSString stringWithFormat:@"Triggered SecTTR: %@ - %@", ttrRequest.alert, ttrRequest.radarnumber]; + NSString *encodedTitle = [title stringByAddingPercentEncodingWithAllowedCharacters:queryComponent]; + + NSString *desc = [NSString stringWithFormat:@"%@\nRelated radar: radr://%@", ttrRequest.radarDescription, ttrRequest.radarnumber]; + NSString *encodedDesc = [desc stringByAddingPercentEncodingWithAllowedCharacters:queryComponent]; + + NSString *url = [NSString stringWithFormat:@"tap-to-radar://new?" + "Reproducibilty=Always&" + "Title=%@&" + "ComponentName=%@&" + "ComponentVersion=%@&" + "Reproducibility=Not%%20Applicable&" + "ComponentID=%@&" + "Classification=Crash/Hang/Data%%20Loss&" + "Description=%@", + encodedTitle, + [ttrRequest.componentName stringByAddingPercentEncodingWithAllowedCharacters:queryComponent], + [ttrRequest.componentVersion stringByAddingPercentEncodingWithAllowedCharacters:queryComponent], + [ttrRequest.componentID stringByAddingPercentEncodingWithAllowedCharacters:queryComponent], + encodedDesc]; + + NSURL *tapToRadarURL = [NSURL URLWithString:url]; + [[workspaceCls defaultWorkspace] openURL:tapToRadarURL configuration:nil completionHandler:^(NSDictionary * __unused result, NSError * __unused error) { + }]; +#endif +} + ++ (BOOL)askUserIfTTR:(SecTapToRadar *)ttrRequest +{ + BOOL result = NO; + +#if TARGET_OS_IOS + NSDictionary *alertOptions = @{ + (NSString *)kCFUserNotificationDefaultButtonTitleKey : @"Tap-To-Radar", + (NSString *)kCFUserNotificationAlternateButtonTitleKey : @"Go away", + (NSString *)kCFUserNotificationAlertMessageKey : ttrRequest.alert, + (NSString *)kCFUserNotificationAlertHeaderKey : @"Security", + }; + + SInt32 error = 0; + CFUserNotificationRef notification = CFUserNotificationCreate(NULL, 0, kCFUserNotificationPlainAlertLevel, &error, (__bridge CFDictionaryRef)alertOptions); + if (notification != NULL) { + CFOptionFlags responseFlags = 0; + CFUserNotificationReceiveResponse(notification, 1.0 * 60 * 3, &responseFlags); + switch (responseFlags & 0x03) { + case kCFUserNotificationDefaultResponse: + result = YES; + break; + default: + break; + } + CFRelease(notification); + } else { + secnotice("SecTTR", "Failed to create notification error %@", @(error)); + } +#endif + return result; +} + +- (void)trigger +{ + dispatch_sync(self.queue, ^{ + @autoreleasepool { + if (!SecIsInternalRelease()) { + return; + } + + if ([[self class] isRateLimited:self]) { + secnotice("SecTTR", "Not showing ttr due to ratelimiting: %@", self.alert); + return; + } + + if ([[self class] askUserIfTTR:self]) { + [[self class] triggerTapToRadar:self]; + } + [self updateRetryTimestamp]; + } + }); +} + +@end diff --git a/OSX/utilities/src/SecTrace.c b/OSX/utilities/SecTrace.c similarity index 100% rename from OSX/utilities/src/SecTrace.c rename to OSX/utilities/SecTrace.c diff --git a/OSX/utilities/src/SecTrace.h b/OSX/utilities/SecTrace.h similarity index 100% rename from OSX/utilities/src/SecTrace.h rename to OSX/utilities/SecTrace.h diff --git a/OSX/utilities/src/SecXPCError.c b/OSX/utilities/SecXPCError.c similarity index 100% rename from OSX/utilities/src/SecXPCError.c rename to OSX/utilities/SecXPCError.c diff --git a/OSX/utilities/src/SecXPCError.h b/OSX/utilities/SecXPCError.h similarity index 100% rename from OSX/utilities/src/SecXPCError.h rename to OSX/utilities/SecXPCError.h diff --git a/OSX/utilities/SecXPCHelper.h b/OSX/utilities/SecXPCHelper.h new file mode 100644 index 00000000..905eca6d --- /dev/null +++ b/OSX/utilities/SecXPCHelper.h @@ -0,0 +1,27 @@ +// +// SecXPCHelper.h +// Security +// + +#ifndef SecXPCHelper_h +#define SecXPCHelper_h + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SecXPCHelper : NSObject ++ (NSSet *)safeErrorClasses; ++ (NSError *)cleanseErrorForXPC:(NSError * _Nullable)error; + +/* + * Some NSError objects contain non-NSSecureCoding-compliant userInfo. + * When in doubt, use cleanseErrorForXPC: before encodedDataFromError: + */ ++ (NSError *)errorFromEncodedData:(NSData *)data; ++ (NSData *)encodedDataFromError:(NSError *)error; +@end + +NS_ASSUME_NONNULL_END + +#endif // SecXPCHelper_h diff --git a/OSX/utilities/SecXPCHelper.m b/OSX/utilities/SecXPCHelper.m new file mode 100644 index 00000000..d9d80e09 --- /dev/null +++ b/OSX/utilities/SecXPCHelper.m @@ -0,0 +1,183 @@ +// +// SecXPCHelper.m +// Security +// + +#import +#import +#import "SecXPCHelper.h" + +@implementation SecXPCHelper : NSObject + ++ (NSSet *)safeErrorPrimitiveClasses +{ + static NSMutableSet *errorClasses = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + errorClasses = [NSMutableSet set]; + char *classes[] = { + "NSData", + "NSDate", + "NSNull", + "NSNumber", + "NSString", + "NSURL", + }; + + for (unsigned n = 0; n < sizeof(classes) / sizeof(classes[0]); n++) { + Class class = objc_getClass(classes[n]); + if (class) { + [errorClasses addObject:class]; + } + } + }); + + return errorClasses; +} + ++ (NSSet *)safeErrorCollectionClasses +{ + static NSMutableSet *errorClasses = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + errorClasses = [NSMutableSet set]; + char *classes[] = { + "NSArray", + "NSDictionary", + "NSError", + "NSOrderedSet", + "NSSet", + }; + + for (unsigned n = 0; n < sizeof(classes) / sizeof(classes[0]); n++) { + Class class = objc_getClass(classes[n]); + if (class) { + [errorClasses addObject:class]; + } + } + }); + + return errorClasses; +} + ++ (NSSet *)safeErrorClasses +{ + static NSMutableSet *errorClasses = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + errorClasses = [NSMutableSet set]; + for (Class class in [SecXPCHelper safeErrorPrimitiveClasses]) { + [errorClasses addObject:class]; + } + for (Class class in [SecXPCHelper safeErrorCollectionClasses]) { + [errorClasses addObject:class]; + } + }); + + return errorClasses; +} + ++ (NSDictionary *)cleanDictionaryForXPC:(NSDictionary *)dict +{ + if (!dict) { + return nil; + } + + NSMutableDictionary *mutableDictionary = [dict mutableCopy]; + for (id key in mutableDictionary.allKeys) { + id object = mutableDictionary[key]; + mutableDictionary[key] = [SecXPCHelper cleanObjectForXPC:object]; + } + return mutableDictionary; +} + ++ (id)cleanObjectForXPC:(id)object +{ + if (!object) { + return nil; + } + + // Check for primitive classes first, and return them as is + for (Class class in [SecXPCHelper safeErrorPrimitiveClasses]) { + if ([object isKindOfClass:class]) { + return object; + } + } + + // Else, check for known collection classes. We only handle those collection classes we whitelist as + // safe, as per the result of `[SecXPCHelper safeErrorCollectionClasses]`. For each collection class, + // we also handle the contents uniquely, since not all collections share the same APIs. + for (Class class in [SecXPCHelper safeErrorCollectionClasses]) { + if ([object isKindOfClass:class]) { + if ([object isKindOfClass:[NSError class]]) { + NSError *errorObject = (NSError *)object; + return [NSError errorWithDomain:errorObject.domain code:errorObject.code userInfo:[SecXPCHelper cleanDictionaryForXPC:errorObject.userInfo]]; + } if ([object isKindOfClass:[NSDictionary class]]) { + return [SecXPCHelper cleanDictionaryForXPC:(NSDictionary *)object]; + } else if ([object isKindOfClass:[NSArray class]]) { + NSArray *arrayObject = (NSArray *)object; + NSMutableArray* cleanArray = [NSMutableArray arrayWithCapacity:arrayObject.count]; + for (id x in arrayObject) { + [cleanArray addObject:[SecXPCHelper cleanObjectForXPC:x]]; + } + return cleanArray; + } else if ([object isKindOfClass:[NSSet class]]) { + NSSet *setObject = (NSSet *)object; + NSMutableSet *cleanSet = [NSMutableSet setWithCapacity:setObject.count]; + for (id x in setObject) { + [cleanSet addObject:[SecXPCHelper cleanObjectForXPC:x]]; + } + return cleanSet; + } else if ([object isKindOfClass:[NSOrderedSet class]]) { + NSOrderedSet *setObject = (NSOrderedSet *)object; + NSMutableOrderedSet *cleanSet = [NSMutableOrderedSet orderedSetWithCapacity:setObject.count]; + for (id x in setObject) { + [cleanSet addObject:[SecXPCHelper cleanObjectForXPC:x]]; + } + return cleanSet; + } + } + } + + // If all else fails, just return the object's class description + return NSStringFromClass([object class]); +} + ++ (NSError *)cleanseErrorForXPC:(NSError * _Nullable)error +{ + if (!error) { + return nil; + } + + NSDictionary *userInfo = [SecXPCHelper cleanDictionaryForXPC:error.userInfo]; + return [NSError errorWithDomain:error.domain code:error.code userInfo:userInfo]; +} + +static NSString *kArchiveKeyError = @"error"; + ++ (NSError *)errorFromEncodedData:(NSData *)data +{ + NSKeyedUnarchiver *unarchiver = nil; + NSError *error = nil; + + unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:NULL]; + if (unarchiver != nil) { + error = [unarchiver decodeObjectOfClass:[NSError class] forKey:kArchiveKeyError]; + } + + return error; +} + ++ (NSData *)encodedDataFromError:(NSError *)error +{ + NSKeyedArchiver *archiver = nil; + NSData *data = nil; + + archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [archiver encodeObject:error forKey:kArchiveKeyError]; + data = archiver.encodedData; + + return data; +} + +@end diff --git a/OSX/utilities/src/array_size.h b/OSX/utilities/array_size.h similarity index 100% rename from OSX/utilities/src/array_size.h rename to OSX/utilities/array_size.h diff --git a/OSX/utilities/src/debugging.c b/OSX/utilities/debugging.c similarity index 92% rename from OSX/utilities/src/debugging.c rename to OSX/utilities/debugging.c index 124fae55..14695726 100644 --- a/OSX/utilities/src/debugging.c +++ b/OSX/utilities/debugging.c @@ -504,48 +504,3 @@ CFStringRef SecLogAPICreate(bool apiIn, const char *api, CFStringRef format, ... return outStr; } - -#if TARGET_OS_OSX -// Functions for weak-linking os_log functions -#include - -#define weak_log_f(fname, newname, rettype, fallthrough) \ - rettype newname(log_args) { \ - static dispatch_once_t onceToken = 0; \ - static rettype (*newname)(log_args) = NULL; \ - \ - dispatch_once(&onceToken, ^{ \ - void* libtrace = dlopen("/usr/lib/system/libsystem_trace.dylib", RTLD_LAZY | RTLD_LOCAL); \ - if (libtrace) { \ - newname = (rettype(*)(log_args)) dlsym(libtrace, #fname); \ - } \ - }); \ - \ - if(newname) { \ - return newname(log_argnames); \ - } \ - fallthrough;\ -} - -#define log_args void *dso, os_log_t log, os_log_type_t type, const char *format, uint8_t *buf, unsigned int size -#define log_argnames dso, log, type, format, buf, size -weak_log_f(_os_log_impl, weak_os_log_impl, void, return); -#undef log_args -#undef log_argnames - -#define log_args const char *subsystem, const char *category -#define log_argnames subsystem, category -weak_log_f(os_log_create, weak_os_log_create, os_log_t, return NULL); -#undef log_args -#undef log_argnames - -#define log_args os_log_t oslog, os_log_type_t type -#define log_argnames oslog, type -weak_log_f(os_log_type_enabled, weak_os_log_type_enabled, bool, return false); -#undef log_args -#undef log_argnames - -#undef weak_log_f - -#endif // TARGET_OS_OSX - diff --git a/OSX/utilities/src/debugging.h b/OSX/utilities/debugging.h similarity index 93% rename from OSX/utilities/src/debugging.h rename to OSX/utilities/debugging.h index 1c1bbcc3..3a2a3106 100644 --- a/OSX/utilities/src/debugging.h +++ b/OSX/utilities/debugging.h @@ -79,14 +79,6 @@ extern bool secLogEnabled(void); extern void secLogDisable(void); extern void secLogEnable(void); -#if TARGET_OS_OSX -// Downstream projects link these, but we no longer use them internally. Keep them here for now. -// Remove weak-linked os_log functions -void weak_os_log_impl(void *dso, os_log_t log, os_log_type_t type, const char *format, uint8_t *buf, unsigned int size); -os_log_t weak_os_log_create(const char *subsystem, const char *category); -bool weak_os_log_type_enabled(os_log_t oslog, os_log_type_t type); -#endif // TARGET_OS_OSX - CFStringRef SecLogAPICreate(bool apiIn, const char *api, CFStringRef format, ...) CF_FORMAT_FUNCTION(3, 4); diff --git a/OSX/utilities/src/debugging_test.h b/OSX/utilities/debugging_test.h similarity index 100% rename from OSX/utilities/src/debugging_test.h rename to OSX/utilities/debugging_test.h diff --git a/OSX/utilities/src/der_array.c b/OSX/utilities/der_array.c similarity index 100% rename from OSX/utilities/src/der_array.c rename to OSX/utilities/der_array.c diff --git a/OSX/utilities/src/der_boolean.c b/OSX/utilities/der_boolean.c similarity index 100% rename from OSX/utilities/src/der_boolean.c rename to OSX/utilities/der_boolean.c diff --git a/OSX/utilities/src/der_data.c b/OSX/utilities/der_data.c similarity index 100% rename from OSX/utilities/src/der_data.c rename to OSX/utilities/der_data.c diff --git a/OSX/utilities/src/der_date.c b/OSX/utilities/der_date.c similarity index 100% rename from OSX/utilities/src/der_date.c rename to OSX/utilities/der_date.c diff --git a/OSX/utilities/src/der_date.h b/OSX/utilities/der_date.h similarity index 100% rename from OSX/utilities/src/der_date.h rename to OSX/utilities/der_date.h diff --git a/OSX/utilities/src/der_dictionary.c b/OSX/utilities/der_dictionary.c similarity index 100% rename from OSX/utilities/src/der_dictionary.c rename to OSX/utilities/der_dictionary.c diff --git a/OSX/utilities/src/der_null.c b/OSX/utilities/der_null.c similarity index 100% rename from OSX/utilities/src/der_null.c rename to OSX/utilities/der_null.c diff --git a/OSX/utilities/src/der_number.c b/OSX/utilities/der_number.c similarity index 100% rename from OSX/utilities/src/der_number.c rename to OSX/utilities/der_number.c diff --git a/OSX/utilities/src/der_plist.c b/OSX/utilities/der_plist.c similarity index 100% rename from OSX/utilities/src/der_plist.c rename to OSX/utilities/der_plist.c diff --git a/OSX/utilities/src/der_plist.h b/OSX/utilities/der_plist.h similarity index 100% rename from OSX/utilities/src/der_plist.h rename to OSX/utilities/der_plist.h diff --git a/OSX/utilities/src/der_plist_internal.c b/OSX/utilities/der_plist_internal.c similarity index 100% rename from OSX/utilities/src/der_plist_internal.c rename to OSX/utilities/der_plist_internal.c diff --git a/OSX/utilities/src/der_plist_internal.h b/OSX/utilities/der_plist_internal.h similarity index 100% rename from OSX/utilities/src/der_plist_internal.h rename to OSX/utilities/der_plist_internal.h diff --git a/OSX/utilities/src/der_set.c b/OSX/utilities/der_set.c similarity index 100% rename from OSX/utilities/src/der_set.c rename to OSX/utilities/der_set.c diff --git a/OSX/utilities/src/der_set.h b/OSX/utilities/der_set.h similarity index 100% rename from OSX/utilities/src/der_set.h rename to OSX/utilities/der_set.h diff --git a/OSX/utilities/src/der_string.c b/OSX/utilities/der_string.c similarity index 100% rename from OSX/utilities/src/der_string.c rename to OSX/utilities/der_string.c diff --git a/OSX/utilities/src/fileIo.c b/OSX/utilities/fileIo.c similarity index 100% rename from OSX/utilities/src/fileIo.c rename to OSX/utilities/fileIo.c diff --git a/OSX/utilities/src/fileIo.h b/OSX/utilities/fileIo.h similarity index 100% rename from OSX/utilities/src/fileIo.h rename to OSX/utilities/fileIo.h diff --git a/OSX/utilities/iCloudKeychainTrace.c b/OSX/utilities/iCloudKeychainTrace.c new file mode 100644 index 00000000..c3847340 --- /dev/null +++ b/OSX/utilities/iCloudKeychainTrace.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013-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 "iCloudKeychainTrace.h" +#include +#include +#include "SecCFWrappers.h" +#include +#include diff --git a/OSX/libsecurity_smime/regressions/smime_regressions.h b/OSX/utilities/iCloudKeychainTrace.h similarity index 82% rename from OSX/libsecurity_smime/regressions/smime_regressions.h rename to OSX/utilities/iCloudKeychainTrace.h index c9687a23..f72b5bbe 100644 --- a/OSX/libsecurity_smime/regressions/smime_regressions.h +++ b/OSX/utilities/iCloudKeychainTrace.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2007,2009-2010,2013-2014 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,10 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ +/* + * iCloudKeychainTrace.h - log statistics for iCloud Keychain usage + */ - -#include - -ONE_TEST(smime_cms_test) -ONE_TEST(cms_01_basic) +#include diff --git a/OSX/utilities/src/iOSforOSX-SecAttr.c b/OSX/utilities/iOSforOSX-SecAttr.c similarity index 97% rename from OSX/utilities/src/iOSforOSX-SecAttr.c rename to OSX/utilities/iOSforOSX-SecAttr.c index b842012d..abbff31f 100644 --- a/OSX/utilities/src/iOSforOSX-SecAttr.c +++ b/OSX/utilities/iOSforOSX-SecAttr.c @@ -24,7 +24,7 @@ #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #include #include diff --git a/OSX/utilities/src/iOSforOSX-SecRandom.c b/OSX/utilities/iOSforOSX-SecRandom.c similarity index 94% rename from OSX/utilities/src/iOSforOSX-SecRandom.c rename to OSX/utilities/iOSforOSX-SecRandom.c index f576e83a..c9e4c8f5 100644 --- a/OSX/utilities/src/iOSforOSX-SecRandom.c +++ b/OSX/utilities/iOSforOSX-SecRandom.c @@ -24,6 +24,6 @@ #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX const void *kSecRandomDefault = (void*)0; #endif diff --git a/OSX/utilities/src/iOSforOSX.c b/OSX/utilities/iOSforOSX.c similarity index 97% rename from OSX/utilities/src/iOSforOSX.c rename to OSX/utilities/iOSforOSX.c index 5dd2b181..7705297a 100644 --- a/OSX/utilities/src/iOSforOSX.c +++ b/OSX/utilities/iOSforOSX.c @@ -24,7 +24,7 @@ #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #include #include diff --git a/OSX/utilities/src/iOSforOSX.h b/OSX/utilities/iOSforOSX.h similarity index 93% rename from OSX/utilities/src/iOSforOSX.h rename to OSX/utilities/iOSforOSX.h index 7c3c34af..d1dcba3a 100644 --- a/OSX/utilities/src/iOSforOSX.h +++ b/OSX/utilities/iOSforOSX.h @@ -26,7 +26,7 @@ #define utilities_iOSforOSX_h #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX extern CFURLRef SecCopyKeychainDirectoryFile(CFStringRef file); @@ -37,7 +37,7 @@ extern const void *kSecRandomDefault; #endif #ifndef _SECURITY_SECBASE_H_ -typedef struct OpaqueSecKeyRef *SecKeyRef; +typedef struct __SecKey *SecKeyRef; #endif OSStatus SecKeyCopyPersistentRef(SecKeyRef item, CFDataRef *newpersistentRef); OSStatus SecKeyFindWithPersistentRef(CFDataRef persistentRef, SecKeyRef *key); diff --git a/OSX/utilities/src/sec_action.c b/OSX/utilities/sec_action.c similarity index 100% rename from OSX/utilities/src/sec_action.c rename to OSX/utilities/sec_action.c diff --git a/OSX/utilities/src/sec_action.h b/OSX/utilities/sec_action.h similarity index 100% rename from OSX/utilities/src/sec_action.h rename to OSX/utilities/sec_action.h diff --git a/OSX/utilities/src/simulate_crash.c b/OSX/utilities/simulate_crash.c similarity index 81% rename from OSX/utilities/src/simulate_crash.c rename to OSX/utilities/simulate_crash.c index 74ebb05a..0ccd2f5d 100644 --- a/OSX/utilities/src/simulate_crash.c +++ b/OSX/utilities/simulate_crash.c @@ -20,20 +20,29 @@ typedef signed char BOOL; // even if -funsigned-char is used. #endif +static void * +__security_get_CrashReporterSupport(void) +{ + static void *image = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW); + }); + return image; +} + static void __security_simulatecrash_link(CFStringRef reason, uint32_t code) { -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR // Prototype defined in , but objC only. // Soft linking here so we don't link unless we hit this. - static BOOL (*__SimulateCrash)(pid_t pid, mach_exception_data_type_t exceptionCode, CFStringRef description); + static BOOL (*__SimulateCrash)(pid_t pid, mach_exception_data_type_t exceptionCode, CFStringRef description) = NULL; static dispatch_once_t once = 0; dispatch_once(&once, ^{ - void *image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW); + void *image = __security_get_CrashReporterSupport(); if (image) __SimulateCrash = dlsym(image, "SimulateCrash"); - else - __SimulateCrash = NULL; }); if (__SimulateCrash) @@ -59,14 +68,14 @@ void __security_simulatecrash(CFStringRef reason, uint32_t code) void __security_stackshotreport(CFStringRef reason, uint32_t code) { secerror("stackshot report, reason: %@, code=%08x", reason, code); -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR // Prototype defined in , but objC only. // Soft linking here so we don't link unless we hit this. static BOOL (*__WriteStackshotReport)(void *, mach_exception_data_type_t) = NULL; static dispatch_once_t once = 0; dispatch_once(&once, ^{ - void *image = dlopen("/System/Library/PrivateFrameworks/CrashReporterSupport.framework/CrashReporterSupport", RTLD_NOW); + void *image = __security_get_CrashReporterSupport(); if (image) __WriteStackshotReport = dlsym(image, "WriteStackshotReport"); }); diff --git a/OSX/utilities/src/sqlutils.h b/OSX/utilities/sqlutils.h similarity index 100% rename from OSX/utilities/src/sqlutils.h rename to OSX/utilities/sqlutils.h diff --git a/OSX/utilities/src/iCloudKeychainTrace.c b/OSX/utilities/src/iCloudKeychainTrace.c deleted file mode 100644 index dd545ec2..00000000 --- a/OSX/utilities/src/iCloudKeychainTrace.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright (c) 2013-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 "iCloudKeychainTrace.h" -#include -#include -#include "SecCFWrappers.h" -#include -#include - -const CFStringRef kNumberOfiCloudKeychainPeers = CFSTR("numberOfPeers"); -const CFStringRef kNumberOfiCloudKeychainItemsBeingSynced = CFSTR("numberOfItemsBeingSynced"); -const CFStringRef kCloudKeychainNumberOfSyncingConflicts = CFSTR("conflictsCount"); -const CFStringRef kCloudKeychainNumberOfTimesSyncFailed = CFSTR("syncFailureCount"); -const CFStringRef kCloudKeychainNumberOfConflictsResolved = CFSTR("conflictsResolved"); -const CFStringRef kCloudKeychainNumberOfTimesSyncedWithPeers = CFSTR("syncedWithPeers"); - -#if !TARGET_IPHONE_SIMULATOR -#if TARGET_OS_IPHONE -static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icdp"; -#else -static const char* gTopLevelKeyForiCloudKeychainTracing = "com.apple.icdp.KeychainStats"; -#endif -#endif - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR)) -#include - -struct msgtracer_instance { - msgtracer_msg_t message; - msgtracer_domain_t domain; -}; - -static const char* gMessageTracerSetPrefix = "com.apple.message."; - -/* -------------------------------------------------------------------------- - Function: OSX_BeginCloudKeychainLoggingTransaction - - Description: For OSX the message tracer back end wants its logging - done in "bunches". This function allows for beginning - a 'transaction' of logging which will allow for putting - all of the transactions items into a single log making - the message tracer folks happy. - - The work of this function is to ask msgtracer for a domain, - create a message and return the pair as a void *. - -------------------------------------------------------------------------- */ -static void *OSX_BeginCloudKeychainLoggingTransaction() -{ - - struct msgtracer_instance *instance = calloc(1, sizeof *instance); - if (!instance) { - return NULL; - } - - instance->domain = msgtracer_domain_new(gTopLevelKeyForiCloudKeychainTracing); - if (instance->domain) { - instance->message = msgtracer_msg_new(instance->domain); - if (instance->message) { - return (void *)instance; - } - msgtracer_domain_free(instance->domain); - } - free(instance); - return NULL; -} - -/* -------------------------------------------------------------------------- - Function: OSX_AddKeyValuePairToKeychainLoggingTransaction - - Description: Once a call to OSX_BeginCloudKeychainLoggingTransaction - is done, this call all allow for adding items to the - "bunch" of items being logged. - - NOTE: The key should be a simple key such as - "numberOfPeers". This is because this function will - prepend the required prefix of "com.apple.message." - -------------------------------------------------------------------------- */ -static bool OSX_AddKeyValuePairToKeychainLoggingTransaction(void *token, CFStringRef key, int64_t value) -{ - if (NULL == token || NULL == key) - { - return false; - } - - struct msgtracer_instance *instance = (struct msgtracer_instance *)token; - msgtracer_msg_t msg = instance->message; - - // Fix up the key - __block char *real_key = NULL; - CFStringPerformWithCString(key, ^(const char *key_utf8) { - asprintf(&real_key, "%s%s", gMessageTracerSetPrefix, key_utf8); - }); - if (NULL == real_key) - { - return false; - } - - char value_buffer[32]; - snprintf(value_buffer, sizeof(value_buffer), "%lld", value); - - msgtracer_set(msg, real_key, value_buffer); - free(real_key); - return true; -} - -/* -------------------------------------------------------------------------- - Function: OSX_CloseCloudKeychainLoggingTransaction - - Description: Once a call to OSX_BeginCloudKeychainLoggingTransaction - is done, and all of the items that are to be in the - "bunch" of items being logged, this function will do the - real logging and free the aslmsg context. - -------------------------------------------------------------------------- */ -static void OSX_CloseCloudKeychainLoggingTransaction(void *token) -{ - if (NULL != token) - { - struct msgtracer_instance *instance = (struct msgtracer_instance *)token; - msgtracer_log(instance->message, ASL_LEVEL_NOTICE, ""); - msgtracer_msg_free(instance->message); - msgtracer_domain_free(instance->domain); - free(instance); - } -} - -/* -------------------------------------------------------------------------- - Function: OSX_SetCloudKeychainTraceValueForKey - - Description: If "bunching" of items either cannot be done or is not - desired, then this 'single shot' function shold be used. - It will create the aslmsg context, register the domain - fix up the key and log the key value pair and then - do the real logging and free the aslmsg context. - -------------------------------------------------------------------------- */ -static bool OSX_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value) -{ - bool result = false; - - if (NULL == key) - { - return result; - } - - msgtracer_msg_t message = NULL; - msgtracer_domain_t domain = msgtracer_domain_new(gTopLevelKeyForiCloudKeychainTracing); - - if (NULL == domain) { - return result; - } - - message = msgtracer_msg_new(domain); - if (NULL == message) { - msgtracer_domain_free(domain); - return result; - } - - // Fix up the key - __block char *real_key = NULL; - CFStringPerformWithCString(key, ^(const char *key_utf8) { - asprintf(&real_key, "%s%s", gMessageTracerSetPrefix, key_utf8); - }); - if (NULL == real_key) - { - return false; - } - - char value_buffer[32]; - snprintf(value_buffer, sizeof(value_buffer), "%lld", value); - - msgtracer_set(message, real_key, value_buffer); - msgtracer_log(message, ASL_LEVEL_NOTICE, "%s is %lld", real_key, value); - msgtracer_msg_free(message); - msgtracer_domain_free(domain); - free(real_key); - return true; - -} -#endif - -#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) - -typedef void (*type_ADClientClearScalarKey)(CFStringRef key); -typedef void (*type_ADClientSetValueForScalarKey)(CFStringRef key, int64_t value); - -static type_ADClientClearScalarKey gADClientClearScalarKey = NULL; -static type_ADClientSetValueForScalarKey gADClientSetValueForScalarKey = NULL; - -static dispatch_once_t gADFunctionPointersSet = 0; -static CFBundleRef gAggdBundleRef = NULL; -static bool gFunctionPointersAreLoaded = false; - -/* -------------------------------------------------------------------------- - Function: InitializeADFunctionPointers - - Description: Linking to the Aggregate library causes a build cycle so - This function will dynamically load the needed function - pointers. - -------------------------------------------------------------------------- */ -static bool InitializeADFunctionPointers() -{ - if (gFunctionPointersAreLoaded) - { - return gFunctionPointersAreLoaded; - } - - dispatch_once(&gADFunctionPointersSet, - ^{ - CFStringRef path_to_aggd_framework = CFSTR("/System/Library/PrivateFrameworks/AggregateDictionary.framework"); - - CFURLRef aggd_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_to_aggd_framework, kCFURLPOSIXPathStyle, true); - - if (NULL != aggd_url) - { - gAggdBundleRef = CFBundleCreate(kCFAllocatorDefault, aggd_url); - if (NULL != gAggdBundleRef) - { - gADClientClearScalarKey = (type_ADClientClearScalarKey) - CFBundleGetFunctionPointerForName(gAggdBundleRef, CFSTR("ADClientClearScalarKey")); - - gADClientSetValueForScalarKey = (type_ADClientSetValueForScalarKey) - CFBundleGetFunctionPointerForName(gAggdBundleRef, CFSTR("ADClientSetValueForScalarKey")); - } - CFRelease(aggd_url); - } - }); - - gFunctionPointersAreLoaded = ((NULL != gADClientClearScalarKey) && (NULL != gADClientSetValueForScalarKey)); - return gFunctionPointersAreLoaded; -} - -/* -------------------------------------------------------------------------- - Function: Internal_ADClientClearScalarKey - - Description: This fucntion is a wrapper around calling the - ADClientClearScalarKey function. - - NOTE: The key should be a simple key such as - "numberOfPeers". This is because this function will - apptend the required prefix of "com.apple.cloudkeychain" - -------------------------------------------------------------------------- */ -static void Internal_ADClientClearScalarKey(CFStringRef key) -{ - if (InitializeADFunctionPointers()) - { - CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s.%@"), gTopLevelKeyForiCloudKeychainTracing, key); - if (NULL == real_key) - { - return; - } - - gADClientClearScalarKey(real_key); - CFRelease(real_key); - } -} - -/* -------------------------------------------------------------------------- - Function: Internal_ADClientSetValueForScalarKey - - Description: This fucntion is a wrapper around calling the - ADClientSetValueForScalarKey function. - - NOTE: The key should be a simple key such as - "numberOfPeers". This is because this function will - apptend the required prefix of "com.apple.cloudkeychain" - -------------------------------------------------------------------------- */ -static void Internal_ADClientSetValueForScalarKey(CFStringRef key, int64_t value) -{ - if (InitializeADFunctionPointers()) - { - CFStringRef real_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%s.%@"), gTopLevelKeyForiCloudKeychainTracing, key); - if (NULL == real_key) - { - return; - } - - gADClientSetValueForScalarKey(real_key, value); - CFRelease(real_key); - } -} - - -/* -------------------------------------------------------------------------- - Function: iOS_SetCloudKeychainTraceValueForKey - - Description: This fucntion is a wrapper around calling either - ADClientSetValueForScalarKey or ADClientClearScalarKey - depending on if the value is 0. - - NOTE: The key should be a simple key such as - "numberOfPeers". This is because this function will - apptend the required prefix of "com.apple.cloudkeychain" - -------------------------------------------------------------------------- */ -static bool iOS_SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value) -{ - if (NULL == key) - { - return false; - } - - if (0LL == value) - { - Internal_ADClientClearScalarKey(key); - } - else - { - Internal_ADClientSetValueForScalarKey(key, value); - } - return true; -} - -/* -------------------------------------------------------------------------- - Function: iOS_AddKeyValuePairToKeychainLoggingTransaction - - Description: For iOS the is no "bunching" This function will simply - call iOS_SetCloudKeychainTraceValueForKey to log the - key value pair - -------------------------------------------------------------------------- */ -static bool iOS_AddKeyValuePairToKeychainLoggingTransaction(void* token, CFStringRef key, int64_t value) -{ -#pragma unused(token) - return iOS_SetCloudKeychainTraceValueForKey(key, value); -} -#endif - -/* -------------------------------------------------------------------------- - Function: SetCloudKeychainTraceValueForKey - - Description: SPI to log a single key value pair with the logging system - -------------------------------------------------------------------------- */ -bool SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value) -{ -#if (TARGET_IPHONE_SIMULATOR) - return false; -#endif - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - return OSX_SetCloudKeychainTraceValueForKey(key, value); -#endif - -#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) - return iOS_SetCloudKeychainTraceValueForKey(key, value); -#endif -} - -/* -------------------------------------------------------------------------- - Function: BeginCloudKeychainLoggingTransaction - - Description: SPI to begin a logging transaction - -------------------------------------------------------------------------- */ -void* BeginCloudKeychainLoggingTransaction() -{ -#if (TARGET_IPHONE_SIMULATOR) - return (void *)-1; -#endif - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - return OSX_BeginCloudKeychainLoggingTransaction(); -#endif - -#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) - return NULL; -#endif -} - -/* -------------------------------------------------------------------------- - Function: AddKeyValuePairToKeychainLoggingTransaction - - Description: SPI to add a key value pair to an outstanding logging - tansaction - -------------------------------------------------------------------------- */ -bool AddKeyValuePairToKeychainLoggingTransaction(void* token, CFStringRef key, int64_t value) -{ -#if (TARGET_IPHONE_SIMULATOR) - return false; -#endif - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - return OSX_AddKeyValuePairToKeychainLoggingTransaction(token, key, value); -#endif - -#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) - return iOS_AddKeyValuePairToKeychainLoggingTransaction(token, key, value); -#endif -} - -/* -------------------------------------------------------------------------- - Function: CloseCloudKeychainLoggingTransaction - - Description: SPI to complete a logging transaction and clean up the - context - -------------------------------------------------------------------------- */ -void CloseCloudKeychainLoggingTransaction(void* token) -{ -#if (TARGET_IPHONE_SIMULATOR) - ; // nothing -#endif - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - OSX_CloseCloudKeychainLoggingTransaction(token); -#endif - -#if (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) - ; // nothing -#endif -} - diff --git a/OSX/utilities/src/iCloudKeychainTrace.h b/OSX/utilities/src/iCloudKeychainTrace.h deleted file mode 100644 index c9c834f9..00000000 --- a/OSX/utilities/src/iCloudKeychainTrace.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2006-2007,2009-2010,2013-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@ - */ - -/* - * iCloudKeychainTrace.h - log statistics for iCloud Keychain usage - */ - -#include - -extern const CFStringRef kCloudKeychainNumberOfSyncingConflicts - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -extern const CFStringRef kCloudKeychainNumberOfTimesSyncFailed - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -extern const CFStringRef kCloudKeychainNumberOfConflictsResolved - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); -extern const CFStringRef kCloudKeychainNumberOfTimesSyncedWithPeers - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); - -bool SetCloudKeychainTraceValueForKey(CFStringRef key, int64_t value) - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); - -void* BeginCloudKeychainLoggingTransaction(void) - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); - -bool AddKeyValuePairToKeychainLoggingTransaction(void* token, CFStringRef key, int64_t value) - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); - -void CloseCloudKeychainLoggingTransaction(void* token) - __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); - - - - - diff --git a/OSX/utilities/test/Info.plist b/OSX/utilities/test/Info.plist new file mode 100644 index 00000000..64d65ca4 --- /dev/null +++ b/OSX/utilities/test/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/OSX/utilities/test/SecTapToRadarTests.m b/OSX/utilities/test/SecTapToRadarTests.m new file mode 100644 index 00000000..d79732ef --- /dev/null +++ b/OSX/utilities/test/SecTapToRadarTests.m @@ -0,0 +1,108 @@ +// +// SecTapToRadarTests.m +// TrustedPeersTests +// + +#import + +#if !TARGET_OS_BRIDGE + +#import +#import +#import "utilities/SecTapToRadar.h" + +@interface SecTapToRadarTests : XCTestCase +@property BOOL isRateLimited; +@property BOOL userSay; + +@property bool ttrDidAppear; +@property id mockTTR; + +@end + +@implementation SecTapToRadarTests + +- (void)triggerTapToRadar:(SecTapToRadar *)ttrRequest +{ + self.ttrDidAppear = true; +} + +- (BOOL)isRateLimited:(SecTapToRadar *)ttrRequest +{ + return self.isRateLimited; +} + +- (BOOL)askUserIfTTR:(SecTapToRadar *)ttrRequest +{ + return self.userSay; +} + +- (void)setUp { + + self.ttrDidAppear = NO; + self.isRateLimited = NO; + self.userSay = YES; + + self.mockTTR = OCMClassMock([SecTapToRadar class]); + OCMStub([self.mockTTR triggerTapToRadar:[OCMArg any]]).andCall(self, @selector(triggerTapToRadar:)); + OCMStub([self.mockTTR isRateLimited:[OCMArg any]]).andCall(self, @selector(isRateLimited:)); + OCMStub([self.mockTTR askUserIfTTR:[OCMArg any]]).andCall(self, @selector(askUserIfTTR:)); +} + +- (void)testSecTTRNormal { + + SecTapToRadar *ttr = [[SecTapToRadar alloc] initTapToRadar:@"alert" description:@"test" radar:@"1"]; + + [ttr trigger]; + XCTAssertTrue(self.ttrDidAppear, "should have appeared"); +} + +- (void)testSecTTRRateLimit { + SecTapToRadar *ttr = [[SecTapToRadar alloc] initTapToRadar:@"alert" description:@"test" radar:@"1"]; + + self.isRateLimited = YES; + [ttr trigger]; + XCTAssertFalse(self.ttrDidAppear, "should not have appered"); +} + +- (void)testSecTTRUserSupress { + + SecTapToRadar *ttr = [[SecTapToRadar alloc] initTapToRadar:@"alert" description:@"test" radar:@"1"]; + + self.userSay = false; + [ttr trigger]; + XCTAssertFalse(self.ttrDidAppear, "should not have appered"); + + self.userSay = true; + [ttr trigger]; + XCTAssertTrue(self.ttrDidAppear, "should have appeared"); +} + +- (void)testSecTTRRateLimiter { + + SecTapToRadar *ttr = [[SecTapToRadar alloc] initTapToRadar:@"alert" description:@"test" radar:@"1"]; + NSString *key = [SecTapToRadar keyname:ttr]; + NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.apple.security"]; + + [ttr clearRetryTimestamp]; + + XCTAssertFalse([ttr isRateLimited], @"should not be rate-limited for first request"); + [ttr updateRetryTimestamp]; + XCTAssertTrue([ttr isRateLimited], @"should be rate-limited after first request"); + + [ttr clearRetryTimestamp]; + XCTAssertFalse([ttr isRateLimited], @"should not be ratelitmied after clear"); + + // check invalid settings + [defaults setObject:@"invalid" forKey:key]; + XCTAssertNotNil([defaults objectForKey:key], "should have cleared setting"); + XCTAssertFalse([ttr isRateLimited], @"should not be rate-limited if invalid type"); + XCTAssertNil([defaults objectForKey:key], "should have cleared setting"); + + +} + + +@end + +#endif /* TARGET_OS_BRIDGE */ diff --git a/OSX/utilities/test/SecXPCHelperTests.m b/OSX/utilities/test/SecXPCHelperTests.m new file mode 100644 index 00000000..90aa40ab --- /dev/null +++ b/OSX/utilities/test/SecXPCHelperTests.m @@ -0,0 +1,127 @@ +// +// SecXPCHelperTests.m +// SecurityUtilityTests +// + +#import +#import "utilities/SecXPCHelper.h" + +@interface UnsafeType : NSObject +@property(class, readonly) BOOL supportsSecureCoding; +- (id)initWithCoder:(NSCoder *)decoder; +@end + +@implementation UnsafeType + +- (id)init { + return [super init]; +} + ++ (BOOL)supportsSecureCoding { + return NO; +} + +- (id)initWithCoder:(NSCoder *)decoder { + return [[UnsafeType alloc] init]; +} + +@end + +@interface SafeType : NSObject +@property(class, readonly) BOOL supportsSecureCoding; +- (id)initWithCoder:(NSCoder *)decoder; +@end + +@implementation SafeType + +- (id)init { + return [super init]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + return [[SafeType alloc] init]; +} + +@end + +@interface SecXPCHelperTests : XCTestCase +@end + +@implementation SecXPCHelperTests + +- (void)testSanitizerWithNilError { + XCTAssertNil([SecXPCHelper cleanseErrorForXPC:nil]); +} + +- (void)testSanitizerWithCleanError { + NSDictionary *cleanInfo = @{@"Key" : @"Safe String"}; + NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:-1 userInfo:cleanInfo]; + NSError *cleansed = [SecXPCHelper cleanseErrorForXPC:error]; + XCTAssertNotNil(cleansed); + XCTAssertTrue(cleansed.code == error.code); + XCTAssertTrue(cleansed.domain == error.domain); + XCTAssertTrue([cleansed.userInfo isEqualToDictionary:cleanInfo]); +} + +- (void)testSanitizerWithSafeCodingError { + SafeType *safe = [[SafeType alloc] init]; + NSDictionary *cleanInfo = @{@"Key" : safe}; + NSDictionary *sanitizedInfo = @{@"Key" : [[safe class] description]}; + NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:-1 userInfo:cleanInfo]; + NSError *cleansed = [SecXPCHelper cleanseErrorForXPC:error]; + XCTAssertNotNil(cleansed); + XCTAssertTrue(cleansed.code == error.code); + XCTAssertTrue(cleansed.domain == error.domain); + XCTAssertTrue([cleansed.userInfo isEqualToDictionary:sanitizedInfo]); +} + +- (void)testSanitizerWithDirtyUnsafeError { + UnsafeType *unsafe = [[UnsafeType alloc] init]; + NSDictionary *cleanInfo = @{@"Key" : unsafe}; + NSDictionary *sanitizedInfo = @{@"Key" : [[unsafe class] description]}; + NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:-1 userInfo:cleanInfo]; + NSError *cleansed = [SecXPCHelper cleanseErrorForXPC:error]; + XCTAssertNotNil(cleansed); + XCTAssertTrue(cleansed.code == error.code); + XCTAssertTrue(cleansed.domain == error.domain); + XCTAssertTrue([cleansed.userInfo isEqualToDictionary:sanitizedInfo]); +} + +- (void)testErrorEncodingUnsafe { + NSDictionary *unsafeInfo = @{ @"info" : [[NSObject alloc] init] }; + NSError *unsafeError = [NSError errorWithDomain:@"domain" code:23 userInfo:unsafeInfo]; + NSData *unsafeEncodedData = nil; + bool exceptionCaught = false; + @try { + unsafeEncodedData = [SecXPCHelper encodedDataFromError:unsafeError]; + } @catch (NSException *e) { + XCTAssertNotNil(e); + XCTAssertEqualObjects(e.name, NSInvalidUnarchiveOperationException); + exceptionCaught = true; + } + XCTAssertTrue(exceptionCaught); + XCTAssertNil(unsafeEncodedData); +} + +- (void)testErrorEncodingSafe { + NSDictionary *safeInfo = @{ @"info" : @(57) }; + NSError *safeError = [NSError errorWithDomain:@"domain" code:19 userInfo:safeInfo]; + NSData *safeEncodedData = [SecXPCHelper encodedDataFromError:safeError]; + XCTAssertNotNil(safeEncodedData); + NSError *decodedSafeError = [SecXPCHelper errorFromEncodedData:safeEncodedData]; + XCTAssertNotNil(decodedSafeError); + XCTAssertEqualObjects(decodedSafeError.domain, safeError.domain); + XCTAssertEqual(decodedSafeError.code, safeError.code); + XCTAssertEqualObjects(decodedSafeError.userInfo, safeError.userInfo); + + /* Double-check the archive key */ + NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:safeEncodedData error:NULL]; + XCTAssertNotNil(unarchiver); + XCTAssertTrue([unarchiver containsValueForKey:@"error"], "missing expected key (this is a wire format!)"); +} + +@end diff --git a/OSX/utilities/utilities b/OSX/utilities/utilities deleted file mode 120000 index 945c9b46..00000000 --- a/OSX/utilities/utilities +++ /dev/null @@ -1 +0,0 @@ -. \ No newline at end of file diff --git a/README b/README index cb203b69..a6819cf9 100644 --- a/README +++ b/README @@ -1,6 +1,30 @@ +Update Feb 25, 2019 + +This project has many aggregate top-level targets. These map directly to build system aliases of Security in the obvious way: +Alias macOS Target iOS Target bridgeOS Target tvOS Target watchOS Target +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +Security | Security_frameworks_osx | Security_frameworks_ios | Security_frameworks_bridge | Security_frameworks_tvos | Security_frameworks_watchos +Security_executables_core | Security_executables_core_osx | Security_executables_core_ios | | Security_executables_core_tvos | Security_executables_core_watchos +Security_executables | Security_executables_osx | Security_executables_ios | Security_executables_bridge | Security_executables_tvos | Security_executables_watchos +Security_internal | Security_internal_osx | Security_internal_ios | | Security_internal_tvos | Security_internal_watchos +Security_executables_Swift | Security_executables_Swift | Security_executables_Swift | | Security_executables_Swift | +Security_tests | Security_tests_osx | Security_tests_ios | Security_tests_bridge | Security_tests_tvos | Security_tests_watchos +Security_executables_darwinos_only | Security_executables_darwinos_only_osx | Security_executables_darwinos_only_ios | | | +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + +Security_frameworks targets are for frameworks, dynamic libraries, or libraries that should be in the (public or private) SDK. +Security_executables_core targets are for binaries (particularly daemons) that are absolutely necessary for base operation of any variant of the OS, including the recovery OS. If you are unsure, do not put your target here. +Security_executables targets are for binaries that ship in customer images. These are daemons, tools, services, plug-ins, apps, etc. +Security_internal targets are for non-test binaries that ship in internal images (e.g. /AppleInternal/*, /usr/local/*). These are usually tools and internal apps. +Security_executables_Swift is for any and all Swift targets. +Security_tests targets are for test binaries that ship in the TestsSupport dmg. These are usually xctests and test executables and test apps. +Security_executables_darwinos_only targets are for binaries that should only ship in very special variants of the OS. If you are unsure, do not put your target here. + +Security_all targets aggregate all of the above targets for each platform and are used by the local Xcode schemes. + Update Dec 1, 2016 -This project wont build without internal headers that are not public. +This project currently does not build without internal headers that are not public. Update June 17, 2014 @@ -38,6 +62,6 @@ libScripts/ ==== To regenerate strings file run: -genstrings -u -o resources/English.lproj -s SecString OSX/sec/Security/SecFrameworkStrings.h +genstrings -u -o resources/en.lproj -s SecString OSX/sec/Security/SecFrameworkStrings.h in the top level dir. diff --git a/README-TRIESTE.md b/README-TRIESTE.md new file mode 100644 index 00000000..b35b3f4c --- /dev/null +++ b/README-TRIESTE.md @@ -0,0 +1,38 @@ +# Testing the Security project components using Trieste + +## Development testing (a.k.a. Testing from your local machine while developing) + +### Trieste-specific components + +Security project contains several components that enable Trieste testing. Those are: + +- Three projects located under `keychain/Trieste`: + * `OctagonTestHarnessXPCServiceProtocol`: this is an XPC API exposed by the test harness for remote invocations by the Trieste tests; + * `OctagonTestHarnessXPCService`: this is an XPC service implementating the API above using the NSXPC platform; + * `OctagonTestHarness`: this is a container project for the XPC protocol and XPC service above. +- One project located under `keychain/Trieste/OctagonTriesteTests`: + * `OctagonTrieste`: this is a test project that is ran by Xcode on the developer's macOS machine and invokes `OctagonTestHarness` remotely on a device. + +Projects under `keychain/Trieste` are explicitly added to the top-level `Security.xcodeproj` and are available right after the project is open. Of those three, `OctagonTestHarnessXPCServiceProtocol` is available as a Swift Package Manager project, but not managed as such by Xcode -- it's managed as a simple directory tree of sources. + +Unlike these projects above, `OctagonTrieste` is a real Swift Package Manager project that is fully managed by Swift. Because of that, this project's `.xcodeproj` file is added as a sub-project to `Security.xcodeproj`, but is not checked into the source control. + +This means that after cloning the repository, but before opening `Security.xcodeproj`, the following command needs to be run: + +``` +cd keychain/Trieste/OctagonTriesteTests +./remake-local-project.sh +``` + +This will generate `OctagonTrieste.xcodeproj` that is already set up to be referenced from `Security.xcodeproj`. The commands above need to be re-run when there are some major changes to the OctagonTrieste project, like adding or removing sources files, or updating or modifying dependencies. + +### Trieste-specific test schemes configuration + +The following environment variables are needed in the `OctagonTrieste-Package` scheme's Run action: + +- `TRIESTE_INSTALLED_TARGETS_PROJECT_FILE_DIR=$(PROJECT_DIR)/../../..` +- `TRIESTE_SCREEN_SHARING_DO_NOT_OPEN_AUTOMATICALLY=YES` +- `TRIESTE_TEAM_ID` -- this needs to be set to your WWDR team ID. Please contact Trieste team at `trieste-dev@group.apple.com` if you have authentication troubles after setting this. +- `TRIESTE_GATEWAY_URL=https://p33-trieste.ic.apple.com` + +When running the tests involving installation of local targets to a remote Trieste-controlled device (see `CDAIOSDevice.installXcodeTargets(_:rebootWhenDone:)` for details), you may get errors about Xcode scheme `OctagonTestHarness` missing from your project. This indeed may be the case and you need to add a scheme named `OctagonTestHarness` based on the target `OctagonTestHarness` to fix that. This happens because not all schemes may happen to be committed to the repository. diff --git a/RegressionTests/Security.plist b/RegressionTests/Security.plist index c9fde58c..0c9e0521 100644 --- a/RegressionTests/Security.plist +++ b/RegressionTests/Security.plist @@ -6,22 +6,6 @@ Security Tests - - TestName - security-sysdiagnose - Command - - /usr/libexec/security-sysdiagnose - - - - TestName - BackupNegativeTest - Command - - /AppleInternal/CoreOS/tests/Security/secbackupntest - - TestName keystorectl-get-lock-state @@ -33,13 +17,11 @@ TestName - BackupTest + security-sysdiagnose Command - /AppleInternal/CoreOS/tests/Security/secbackuptest + /usr/libexec/security-sysdiagnose - EligibleResource - cpuArchitecture BEGINSWITH 'arm' TestName @@ -65,42 +47,6 @@ /AppleInternal/CoreOS/tests/Security/secitemnotifications - - 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 secd_02_upgrade_while_locked @@ -148,6 +94,8 @@ TestName KCPairingTest + ShowSubtestResults + Command /AppleInternal/CoreOS/tests/Security/KeychainEntitledTestRunner @@ -168,6 +116,8 @@ TestName KeychainAnalyticsTests + ShowSubtestResults + Command BATS_XCTEST_CMD @@ -177,6 +127,8 @@ TestName KeychainMockAKSTests + ShowSubtestResults + Command BATS_XCTEST_CMD @@ -185,36 +137,40 @@ TestName - MultiDeviceSimulatorTests + KeychainSecd_macOS + ShowSubtestResults + Command BATS_XCTEST_CMD - /AppleInternal/XCTests/com.apple.security/MultiDeviceSimulatorTests.xctest + /AppleInternal/XCTests/com.apple.security/secdxctests_mac.xctest EligibleResource type != 'CAMEmbeddedDeviceResource' TestName - KeychainSecd_macOS + KeychainSecd_iOS + ShowSubtestResults + Command BATS_XCTEST_CMD - /AppleInternal/XCTests/com.apple.security/secdxctests_mac.xctest + /AppleInternal/XCTests/com.apple.security/secdxctests_ios.xctest EligibleResource - type != 'CAMEmbeddedDeviceResource' + type == 'CAMEmbeddedDeviceResource' TestName - KeychainSecd_iOS + SecurityUtiltitesTests + ShowSubtestResults + Command BATS_XCTEST_CMD - /AppleInternal/XCTests/com.apple.security/secdxctests_ios.xctest + /AppleInternal/XCTests/com.apple.security/SecurityUtilitiesTests.xctest - EligibleResource - type == 'CAMEmbeddedDeviceResource' diff --git a/RegressionTests/SecurityLocalKeychain.plist b/RegressionTests/SecurityLocalKeychain.plist new file mode 100644 index 00000000..39337485 --- /dev/null +++ b/RegressionTests/SecurityLocalKeychain.plist @@ -0,0 +1,77 @@ + + + + + Project + Security + Tests + + + TestName + BackupNegativeTest + Command + + /AppleInternal/CoreOS/tests/Security/secbackupntest + + + + TestName + BackupTest + Command + + /AppleInternal/CoreOS/tests/Security/secbackuptest + + + + TestName + secitemstresstest + Command + + /AppleInternal/CoreOS/tests/Security/secitemstresstest + + ShowSubtestResults + + + + TestName + secitemfunctionality + EnableEasyperf + + EasyperfArgs + + -p + secd + + Command + + /AppleInternal/CoreOS/tests/Security/secitemfunctionality + + ShowSubtestResults + + EligibleResource + type != 'CAMEmbeddedDeviceResource' + + + TestName + secitemfunctionality + EnableEasyperf + + EasyperfArgs + + -p + securityd + + AsRoot + + Command + + /AppleInternal/CoreOS/tests/Security/secitemfunctionality + + ShowSubtestResults + + EligibleResource + type == 'CAMEmbeddedDeviceResource' + + + + diff --git a/RegressionTests/manifeststresstest/Keychain.m b/RegressionTests/manifeststresstest/Keychain.m index b5106c4b..52ac3614 100644 --- a/RegressionTests/manifeststresstest/Keychain.m +++ b/RegressionTests/manifeststresstest/Keychain.m @@ -43,7 +43,7 @@ static NSString *kService = @"manifeststresstest"; (id)kSecAttrAccount : name, (id)kSecValueData : [value dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrSynchronizable: (id)kCFBooleanTrue, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecAttrSyncViewHint : view, (id)kSecReturnPersistentRef: @YES, }; @@ -150,7 +150,7 @@ static NSString *kService = @"manifeststresstest"; (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : kAccessGroup, (id)kSecAttrService : kService, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecAttrSynchronizable: (id)kCFBooleanTrue, }; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result); diff --git a/RegressionTests/secbackuptest/secbackuptest.m b/RegressionTests/secbackuptest/secbackuptest.m index fbb18248..04c24548 100644 --- a/RegressionTests/secbackuptest/secbackuptest.m +++ b/RegressionTests/secbackuptest/secbackuptest.m @@ -18,7 +18,7 @@ #include #include -#if TARGET_OS_SIMULATOR +#if TARGET_OS_SIMULATOR || TARGET_OS_BRIDGE int main(void) { diff --git a/RegressionTests/secitemcanarytest/secitemcanarytest.m b/RegressionTests/secitemcanarytest/secitemcanarytest.m index bc496868..966d41ce 100644 --- a/RegressionTests/secitemcanarytest/secitemcanarytest.m +++ b/RegressionTests/secitemcanarytest/secitemcanarytest.m @@ -75,7 +75,7 @@ create_item(NSString *acct) (id)kSecAttrAccount : acct, (id)kSecAttrAccessGroup : kCanaryAccessGroup, (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecValueData : [NSData dataWithBytes:"password" length: 8], }; status = SecItemAdd((__bridge CFDictionaryRef)attrs, NULL); @@ -107,7 +107,7 @@ verify_item(NSString *acct, bool deleteit) (id)kSecAttrAccount : acct, (id)kSecReturnAttributes : @YES, (id)kSecMatchLimit : (id)kSecMatchLimitAll, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; result = NULL; status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); @@ -154,7 +154,7 @@ initial_state(void) (id)kSecAttrAccount : kCanaryStateAccount, (id)kSecAttrAccessGroup : kCanaryAccessGroup, (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecValueData : [NSData dataWithBytes:&state length:sizeof(state)], }; status = SecItemAdd((__bridge CFDictionaryRef)attrs, NULL); @@ -181,7 +181,7 @@ update_state(void) query[(id)kSecClass] = (id)kSecClassGenericPassword; query[(id)kSecAttrAccessGroup] = kCanaryAccessGroup; query[(id)kSecAttrAccount] = kCanaryStateAccount; - query[(id)kSecAttrNoLegacy] = (id)kCFBooleanTrue; + query[(id)kSecUseDataProtectionKeychain] = (id)kCFBooleanTrue; query[(id)kSecReturnData] = @YES; status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); @@ -223,7 +223,7 @@ reset(void) query = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : kCanaryAccessGroup, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; status = SecItemDelete((__bridge CFDictionaryRef)query); switch (status) { diff --git a/RegressionTests/secitemfunctionality/secitemfunctionality.m b/RegressionTests/secitemfunctionality/secitemfunctionality.m index 59650cbb..4afbc161 100644 --- a/RegressionTests/secitemfunctionality/secitemfunctionality.m +++ b/RegressionTests/secitemfunctionality/secitemfunctionality.m @@ -142,7 +142,7 @@ CheckItemUpdateAccessGroupGENP(void) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"keychain-test1", (id)kSecAttrAccount : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, }; status = SecItemAdd((__bridge CFDictionaryRef)add, NULL); @@ -156,7 +156,7 @@ CheckItemUpdateAccessGroupGENP(void) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"keychain-test1", (id)kSecAttrAccount : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; NSDictionary *modified = @{ (id)kSecAttrAccessGroup : @"keychain-test2", @@ -173,7 +173,7 @@ CheckItemUpdateAccessGroupGENP(void) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"keychain-test1", (id)kSecAttrAccount : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; status = SecItemCopyMatching((__bridge CFDictionaryRef)check1, NULL); if (status != errSecItemNotFound) @@ -184,7 +184,7 @@ CheckItemUpdateAccessGroupGENP(void) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"keychain-test2", (id)kSecAttrAccount : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; status = SecItemCopyMatching((__bridge CFDictionaryRef)check2, NULL); if (status != errSecSuccess) @@ -280,7 +280,7 @@ CheckIdentityItem(NSString *accessGroup, OSStatus expectedStatus) (id)kSecClass : (id)kSecClassIdentity, (id)kSecAttrAccessGroup : accessGroup, (id)kSecAttrLabel : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; status = SecItemCopyMatching((__bridge CFDictionaryRef)check, NULL); if (status != expectedStatus) @@ -324,7 +324,7 @@ CheckItemUpdateAccessGroupIdentity(void) (id)kSecAttrAccessGroup : @"keychain-test1", (id)kSecAttrLabel : @"item-delete-me", (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecReturnPersistentRef: (id)kCFBooleanTrue, }; status = SecItemAdd((__bridge CFDictionaryRef)add, &ref); @@ -345,7 +345,7 @@ CheckItemUpdateAccessGroupIdentity(void) (id)kSecClass : (id)kSecClassIdentity, (id)kSecAttrAccessGroup : @"keychain-test1", (id)kSecAttrLabel : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; NSDictionary *modified = @{ (id)kSecAttrAccessGroup : @"keychain-test2", @@ -371,7 +371,7 @@ CheckItemUpdateAccessGroupIdentity(void) (id)kSecClass : (id)kSecClassIdentity, (id)kSecAttrAccessGroup : @"keychain-test2", (id)kSecAttrLabel : @"item-delete-me", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecReturnPersistentRef : (id)kCFBooleanTrue, }; status = SecItemCopyMatching((__bridge CFDictionaryRef)prefQuery, (CFTypeRef *)&data); @@ -383,7 +383,7 @@ CheckItemUpdateAccessGroupIdentity(void) */ NSDictionary *query2 = @{ (id)kSecValuePersistentRef : (__bridge id)data, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; NSDictionary *modified2 = @{ (id)kSecAttrAccessGroup : @"keychain-test1", @@ -444,7 +444,7 @@ CheckFindIdentityByReference(void) (id)kSecAttrAccessGroup : @"keychain-test1", (id)kSecAttrLabel : @"CheckItemReference", (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecReturnPersistentRef: (id)kCFBooleanTrue, }; status = SecItemAdd((__bridge CFDictionaryRef)add, (CFTypeRef *)&pref); @@ -587,14 +587,14 @@ RunDigestPerfTest(NSString *name, NSString *itemClass, NSString *accessGroup, NS _SecItemFetchDigests(itemClass, accessGroup, ^(NSArray *items, NSError *error) { stop = mach_absolute_time(); if (error) { - printf("_SecItemFetchDigests failed with: %ld\n", (long)error.code); + printf("%s: _SecItemFetchDigests failed with: %ld\n", [name UTF8String], (long)error.code); fflush(stdout); abort(); } dispatch_semaphore_signal(sema); if (expectedCount != [items count]) { - printf("_SecItemFetchDigests didn't return expected items: %ld\n", (long)[items count]); + printf("%s: _SecItemFetchDigests didn't return expected items: %ld\n", [name UTF8String], (long)[items count]); fflush(stdout); abort(); } @@ -623,7 +623,7 @@ CheckItemPerformance(void) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrService : @"service", (id)kSecAttrAccessGroup : @"keychain-test1", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; (void)SecItemDelete((__bridge CFDictionaryRef)clean1); @@ -634,9 +634,9 @@ CheckItemPerformance(void) (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : [NSString stringWithFormat:@"account-%d", n], (id)kSecAttrService : @"service", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecAttrAccessGroup : @"keychain-test1", - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecValueData : data, }; SecItemAdd((__bridge CFDictionaryRef)item, NULL); diff --git a/RegressionTests/secitemstresstest/secitemstresstest.m b/RegressionTests/secitemstresstest/secitemstresstest.m index fdbf00fe..122a78bd 100644 --- a/RegressionTests/secitemstresstest/secitemstresstest.m +++ b/RegressionTests/secitemstresstest/secitemstresstest.m @@ -40,7 +40,7 @@ Cleanup(void) query = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : kAccessGroup1, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; status = SecItemDelete((__bridge CFDictionaryRef)query); if (status != errSecSuccess || status == errSecItemNotFound) @@ -49,7 +49,7 @@ Cleanup(void) query = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : kAccessGroup2, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, }; status = SecItemDelete((__bridge CFDictionaryRef)query); if (status != errSecSuccess || status != errSecItemNotFound) @@ -84,7 +84,7 @@ CreateDeleteItem(NSString *account, NSString *accessGroup, bool ignorePedestrian (id)kSecAttrAccount : account, (id)kSecAttrAccessGroup : accessGroup, (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, - (id)kSecAttrNoLegacy : (id)kCFBooleanTrue, + (id)kSecUseDataProtectionKeychain : (id)kCFBooleanTrue, (id)kSecValueData : [NSData dataWithBytes:"password" length: 8], }; OSStatus status; @@ -216,7 +216,8 @@ int main (int argc, const char * argv[]) @autoreleasepool { Cleanup(); - printf("[TEST] testing serial items\n"); + printf("[TEST] secitemstresstest\n"); + printf("[BEGIN] testing serial items\n"); CreateDeleteItem(@"account1", kAccessGroup1, false); CreateDeleteItem(@"account2", kAccessGroup1, false); @@ -225,19 +226,21 @@ int main (int argc, const char * argv[]) printf("[PASS]\n"); Cleanup(); - printf("[TEST] testing concurrent items\n"); + printf("[BEGIN] testing concurrent items\n"); CreateDeleteConcurrentItems(2); CreateDeleteConcurrentItems(10); printf("[PASS]\n"); Cleanup(); - printf("[TEST] testing concurrent same item\n"); + printf("[BEGIN] testing concurrent same item\n"); CreateDeleteConcurrentSameItem(2); CreateDeleteConcurrentSameItem(10); printf("[PASS]\n"); + printf("[SUMMARY]\n"); + printf("test completed\n"); return 0; } diff --git a/RegressionTests/seckeychainnetworkextensionstest/main.m b/RegressionTests/seckeychainnetworkextensionstest/main.m index 73caf534..def0a932 100644 --- a/RegressionTests/seckeychainnetworkextensionstest/main.m +++ b/RegressionTests/seckeychainnetworkextensionstest/main.m @@ -21,14 +21,14 @@ static void cleanupKeychain() attributes[(__bridge NSString*)kSecClass] = (__bridge NSString*)kSecClassGenericPassword; attributes[(__bridge NSString*)kSecAttrAccessGroup] = NetworkExtensionAccessGroup; attributes[(__bridge NSString*)kSecAttrAccount] = TestAccount; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; SecItemDelete((__bridge CFDictionaryRef)attributes); attributes = [NSMutableDictionary dictionary]; attributes[(__bridge NSString*)kSecClass] = (__bridge NSString*)kSecClassGenericPassword; attributes[(__bridge NSString*)kSecAttrAccessGroup] = NetworkExtensionPersistentRefSharingAccessGroup; attributes[(__bridge NSString*)kSecAttrAccount] = TestAccount; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; SecItemDelete((__bridge CFDictionaryRef)attributes); } @@ -44,7 +44,7 @@ int main(int argc, const char * argv[]) attributes[(__bridge NSString*)kSecAttrAccount] = TestAccount; attributes[(__bridge NSString*)kSecValueData] = [NSData dataWithBytes:TestPassword.UTF8String length:TestPassword.length]; attributes[(__bridge NSString*)kSecReturnPersistentRef] = @YES; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; CFTypeRef returnData = NULL; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)attributes, &returnData); @@ -59,7 +59,7 @@ int main(int argc, const char * argv[]) attributes[(__bridge NSString*)kSecAttrAccessGroup] = NetworkExtensionPersistentRefSharingAccessGroup; attributes[(__bridge NSString*)kSecAttrAccount] = TestAccount; attributes[(__bridge NSString*)kSecValueData] = (__bridge NSData*)returnData; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; result = SecItemAdd((__bridge CFDictionaryRef)attributes, &returnData); if (result == 0) { diff --git a/RegressionTests/seckeychainnetworkextensionsystemdaemontest/main.m b/RegressionTests/seckeychainnetworkextensionsystemdaemontest/main.m index c7d13983..696295b2 100644 --- a/RegressionTests/seckeychainnetworkextensionsystemdaemontest/main.m +++ b/RegressionTests/seckeychainnetworkextensionsystemdaemontest/main.m @@ -21,7 +21,7 @@ int main(int argc, const char* argv[]) attributes[(__bridge NSString*)kSecAttrAccessGroup] = NetworkExtensionPersistentRefSharingAccessGroup; attributes[(__bridge NSString*)kSecAttrAccount] = TestAccount; attributes[(__bridge NSString*)kSecReturnPersistentRef] = @YES; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; CFTypeRef persistentRefData = NULL; OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &persistentRefData); @@ -34,7 +34,7 @@ int main(int argc, const char* argv[]) attributes[(__bridge NSString*)kSecClass] = (__bridge NSString*)kSecClassGenericPassword; attributes[(__bridge NSString*)kSecValuePersistentRef] = (__bridge NSData*)persistentRefData; attributes[(__bridge NSString*)kSecReturnData] = @YES; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; CFTypeRef passwordData = NULL; result = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &passwordData); diff --git a/RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/main.m b/RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/main.m index 8e5609fe..8e76a850 100644 --- a/RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/main.m +++ b/RegressionTests/seckeychainnetworkextensionunauthorizedaccesstest/main.m @@ -21,7 +21,7 @@ int main(int argc, const char* argv[]) attributes[(__bridge NSString*)kSecAttrAccessGroup] = NetworkExtensionPersistentRefSharingAccessGroup; attributes[(__bridge NSString*)kSecAttrAccount] = TestAccount; attributes[(__bridge NSString*)kSecReturnData] = @YES; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; CFTypeRef persistentRefData = NULL; OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &persistentRefData); @@ -34,7 +34,7 @@ int main(int argc, const char* argv[]) attributes[(__bridge NSString*)kSecClass] = (__bridge NSString*)kSecClassGenericPassword; attributes[(__bridge NSString*)kSecValuePersistentRef] = (__bridge NSData*)persistentRefData; attributes[(__bridge NSString*)kSecReturnData] = @YES; - attributes[(__bridge NSString*)kSecAttrNoLegacy] = @YES; + attributes[(__bridge NSString*)kSecUseDataProtectionKeychain] = @YES; CFTypeRef passwordData = NULL; result = SecItemCopyMatching((__bridge CFDictionaryRef)attributes, &passwordData); diff --git a/SOSCCAuthPlugin/SOSCCAuthPlugin.m b/SOSCCAuthPlugin/SOSCCAuthPlugin.m index 744fde2b..07708538 100644 --- a/SOSCCAuthPlugin/SOSCCAuthPlugin.m +++ b/SOSCCAuthPlugin/SOSCCAuthPlugin.m @@ -6,7 +6,7 @@ // Copyright 2015 Apple, Inc. All rights reserved. // -#import +#import "SOSCCAuthPlugin.h" #import #import #import @@ -15,6 +15,7 @@ #import #import #import +#import #import #import "utilities/SecCFRelease.h" #import "utilities/debugging.h" @@ -37,11 +38,7 @@ static bool accountIsHSA2(ACAccount *account) { #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) { @@ -70,8 +67,8 @@ static bool accountIsHSA2(ACAccount *account) { secinfo("accounts", "IDS account: iCloud %@ (personID %@)", icloud, icloud.aa_personID); do_auth = icloud && icloud.aa_personID && [icloud.aa_personID isEqualToString:dsid]; } else if ([account.accountType.identifier isEqualToString:ACAccountTypeIdentifierAppleAccount]) { - secinfo("accounts", "AppleID account: primary %@", @([account aa_isPrimaryAccount])); - do_auth = [account aa_isPrimaryAccount]; + do_auth = [account aa_isAccountClass:AAAccountClassPrimary]; + secinfo("accounts", "AppleID account: primary %@", @(do_auth)); } if(do_auth && !accountIsHSA2(account)) { diff --git a/SecExperiment/SecExperiment.m b/SecExperiment/SecExperiment.m new file mode 100644 index 00000000..fac3efd4 --- /dev/null +++ b/SecExperiment/SecExperiment.m @@ -0,0 +1,322 @@ +// +// SecExperiment.m +// Security +// + +#include +#include +#include +#include + +#define OS_OBJECT_HAVE_OBJC_SUPPORT 1 + +#define SEC_EXP_NULL_BAD_INPUT ((void *_Nonnull)NULL) +#define SEC_EXP_NULL_OUT_OF_MEMORY SEC_EXP_NULL_BAD_INPUT + +#define SEC_EXP_NIL_BAD_INPUT ((void *_Nonnull)nil) +#define SEC_EXP_NIL_OUT_OF_MEMORY SEC_EXP_NIL_BAD_INPUT + +#define SEC_EXP_CONCRETE_CLASS_NAME(external_type) SecExpConcrete_##external_type +#define SEC_EXP_CONCRETE_PREFIX_STR "SecExpConcrete_" + +#define SEC_EXP_OBJECT_DECL_INTERNAL_OBJC(external_type) \ +@class SEC_EXP_CONCRETE_CLASS_NAME(external_type); \ +typedef SEC_EXP_CONCRETE_CLASS_NAME(external_type) *external_type##_t + +#define SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, _protocol, visibility, ...) \ +@protocol OS_OBJECT_CLASS(external_type) <_protocol> \ +@end \ +visibility \ +@interface SEC_EXP_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_EXP_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL(external_type, _protocol, ...) \ +SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, _protocol, ,__VA_ARGS__) + +#define SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC(external_type, ...) \ +SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL(external_type, NSObject, ##__VA_ARGS__) + +#define SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC_WITH_VISIBILITY(external_type, visibility, ...) \ +SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC_WITH_PROTOCOL_AND_VISBILITY(external_type, NSObject, visibility, ##__VA_ARGS__) + +SEC_EXP_OBJECT_DECL_INTERNAL_OBJC(sec_experiment); + +#define SEC_EXP_OBJECT_IMPL 1 +#import "SecExperimentPriv.h" +#import "SecExperimentInternal.h" +#import "SecCFRelease.h" +#import +#import + +#define SEC_EXPERIMENT_SAMPLING_RATE 100.0 +#define HASH_INITIAL_VALUE 0 +#define HASH_MULTIPLIER 31 + +const char *kSecExperimentDefaultsDomain = "com.apple.security.experiment"; +const char *kSecExperimentDefaultsDisableSampling = "disableSampling"; +const char *kSecExperimentTLSMobileAssetConfig = "TLSConfig"; + +const NSString *SecExperimentMAPrefix = @"com.apple.MobileAsset."; + +SEC_EXP_OBJECT_IMPL_INTERNAL_OBJC(sec_experiment, +{ + const char *identifier; + bool sampling_disabled; +}); + +@implementation SEC_EXP_CONCRETE_CLASS_NAME(sec_experiment) + +- (instancetype)initWithBundle:(const char *)bundle +{ + if (bundle == NULL) { + return SEC_EXP_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_EXP_NIL_OUT_OF_MEMORY; + } else { + self->identifier = bundle; + } + return self; +} + +// Computes hash of input and returns a value between 1-100 +static uint32_t +_hash_multiplicative(const char *key, size_t len) +{ + if (!key) { + return 0; + } + uint32_t hash = HASH_INITIAL_VALUE; + for (uint32_t i = 0; i < len; ++i) { + hash = HASH_MULTIPLIER * hash + key[i]; + } + return hash % 101; // value between 1-100 +} + +// Computes hash of device UUID +static uint32_t +_get_host_id_hash(void) +{ + static uuid_string_t hostuuid = {}; + static uint32_t hash = 0; + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + struct timespec timeout = {0, 0}; + uuid_t uuid = {}; + if (gethostuuid(uuid, &timeout) == 0) { + uuid_unparse(uuid, hostuuid); + hash = _hash_multiplicative(hostuuid, strlen(hostuuid)); + } else { + onceToken = 0; + } + }); + return hash; +} + +static bool +sec_experiment_is_sampling_disabled_with_default(bool default_value) +{ + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + if (defaults != nil) { + NSMutableDictionary *experimentDefaults = [[defaults persistentDomainForName:[NSString stringWithUTF8String:kSecExperimentDefaultsDomain]] mutableCopy]; + if (experimentDefaults != nil) { + NSString *key = [NSString stringWithUTF8String:kSecExperimentDefaultsDisableSampling]; + if (experimentDefaults[key] != nil) { + return [experimentDefaults[key] boolValue]; + } + } + } + + return default_value; +} + +sec_experiment_t +sec_experiment_create(const char *bundle) +{ + return [[SEC_EXP_CONCRETE_CLASS_NAME(sec_experiment) alloc] initWithBundle:bundle]; +} + +static xpc_object_t +_copy_builtin_experiment_asset(sec_experiment_t experiment) +{ + if (strncmp(experiment->identifier, kSecExperimentTLSMobileAssetConfig, strlen(kSecExperimentTLSMobileAssetConfig)) != 0) { + return nil; + } + + static NSDictionary *defaultTLSConfig = NULL; + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + NSDictionary *validate = @{ + @"tcp" : @{}, + @"tls" : @{@"max_version": @0x0303, + @"false_start_enabled" : @false + } + }; + NSDictionary *transform = @{ + @"tcp" : @{}, + @"tls" : @{@"max_version": @0x0304, + @"false_start_enabled" : @true + } + }; + defaultTLSConfig = @{ + @"validate" : validate, + @"transform" : transform + }; + }); + + return _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)defaultTLSConfig); +} + +// Default check to compute sampling in lieu of MobileAsset download +static bool +_device_is_in_experiment(sec_experiment_t experiment) +{ + if (experiment->sampling_disabled) { + return YES; + } + + uint32_t sample = arc4random(); + return (float)sample < ((float)UINT32_MAX / SEC_EXPERIMENT_SAMPLING_RATE); +} + +static NSDictionary * +_copy_experiment_asset(sec_experiment_t experiment) +{ + CFErrorRef error = NULL; + NSDictionary *config = NULL; + NSDictionary *asset = CFBridgingRelease(SecTrustOTASecExperimentCopyAsset(&error)); + if (asset) { + config = [asset valueForKey:[NSString stringWithUTF8String:experiment->identifier]]; + } + return config; +} + +static xpc_object_t +_copy_defaults_experiment_asset(sec_experiment_t experiment) +{ + xpc_object_t result = nil; + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + if (defaults != nil) { + NSMutableDictionary *experimentDefaults = [[defaults persistentDomainForName:[NSString stringWithUTF8String:kSecExperimentDefaultsDomain]] mutableCopy]; + if (experimentDefaults != nil) { + NSString *key = [NSString stringWithUTF8String:experiment->identifier]; + if (experimentDefaults[key] != nil) { + result = _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)experimentDefaults[key]); + } + } + } + + return result; +} + +void +sec_experiment_set_sampling_disabled(sec_experiment_t experiment, bool sampling_disabled) +{ + experiment->sampling_disabled = sampling_disabled; +} + +xpc_object_t +sec_experiment_copy_configuration(sec_experiment_t experiment) +{ + if (experiment == NULL) { + return NULL; + } + /* Check first for defaults configured */ + if (!sec_experiment_is_sampling_disabled_with_default(experiment->sampling_disabled)) { + xpc_object_t defaultAsset = _copy_defaults_experiment_asset(experiment); + if (defaultAsset != nil) { + return defaultAsset; + } + } + /* Copy assets downloaded from MA */ + NSDictionary *asset = _copy_experiment_asset(experiment); + if (asset != NULL) { + /* Get random config from array of experiments */ + NSArray *array = [asset valueForKey:@"ConfigArray"]; + if (array == NULL) { + return NULL; + } + NSDictionary *randomConfig = [array objectAtIndex:(arc4random() % [array count])]; + + /* Only if sampling is enabled for the experiment */ + if (!experiment->sampling_disabled) { + /* Check FleetSampleRate if device should be in experiment */ + uint32_t fleetSample = [[randomConfig objectForKey:@"FleetSampleRate"] intValue]; + + /* fleetSample is a percentage value configured to determine + percentage of devices in an experiment */ + uint32_t hostIdHash = _get_host_id_hash(); + if ((hostIdHash == 0) || (fleetSample < hostIdHash)) { + return nil; + } + /* Check device sampling rate if device should run experiment */ + uint32_t samplingRate = [[randomConfig objectForKey:@"DeviceSampleRate"] intValue]; + /* Only run experiment 1 out of the samplingRate value */ + uint32_t sample = arc4random(); + if ((float)sample > ((float)UINT32_MAX / samplingRate)) { + return nil; + } + } + return _CFXPCCreateXPCObjectFromCFObject((__bridge CFDictionaryRef)randomConfig); + } + + /* If asset download is not successful, fallback to built-in */ + if (_device_is_in_experiment(experiment)) { + return _copy_builtin_experiment_asset(experiment); + } + return nil; +} + +const char * +sec_experiment_get_identifier(sec_experiment_t experiment) +{ + return experiment->identifier; +} + +bool +sec_experiment_run_internal(const char *experiment_name, bool sampling_disabled, dispatch_queue_t queue, sec_experiment_run_block_t run_block) +{ + if (experiment_name == NULL || queue == nil || run_block == nil) { + return false; + } + + dispatch_async(queue, ^{ + sec_experiment_t experiment = sec_experiment_create(experiment_name); + if (experiment != nil) { + sec_experiment_set_sampling_disabled(experiment, sec_experiment_is_sampling_disabled_with_default(sampling_disabled)); + xpc_object_t config = sec_experiment_copy_configuration(experiment); + if (config != nil) { + const char *identifier = sec_experiment_get_identifier(experiment); + if (run_block(identifier, config)) { + os_log_info(OS_LOG_DEFAULT, "Configuration '%s' for experiment '%s' succeeded", identifier, experiment_name); + } else { + os_log_info(OS_LOG_DEFAULT, "Configuration '%s' for experiment '%s' failed", identifier, experiment_name); + } + } else { + os_log_debug(OS_LOG_DEFAULT, "Experiment '%s' not sampled to run", experiment_name); + } + } else { + os_log_debug(OS_LOG_DEFAULT, "Experiment '%s' not found", experiment_name); + } + }); + + return true; +} + +bool +sec_experiment_run(const char *experiment_name, dispatch_queue_t queue, sec_experiment_run_block_t run_block) +{ + // Sampling is always enabled for SecExperiment callers. Appliations may override this by setting the + // `disableSampling` key in the `com.apple.security.experiment` defaults domain. + return sec_experiment_run_internal(experiment_name, false, queue, run_block); +} + +@end diff --git a/SecExperiment/SecExperimentInternal.h b/SecExperiment/SecExperimentInternal.h new file mode 100644 index 00000000..6bd4fb2e --- /dev/null +++ b/SecExperiment/SecExperimentInternal.h @@ -0,0 +1,34 @@ +// +// SecExperimentInternal.h +// Security +// + +#ifndef SecExperimentInternal_h +#define SecExperimentInternal_h + +#include + +/*! + * @function sec_experiment_run_internal + * + * @abstract + * Asynchronously run an experiment, optionally disabling sampling if desired. + * + * Note: This function MUST NOT be called outside of tests. + * + * @param experiment_name + * Name of the experiment to run. + * + * @param sampling_disabled + * Flag to disable sampling. + * + * @param queue + * Queue on which to run the experiment. + * + * @param run_block + * A `sec_experiment_run_block_t` block upon which to execute the given experiment. + */ +bool +sec_experiment_run_internal(const char *experiment_name, bool sampling_disabled, dispatch_queue_t queue, sec_experiment_run_block_t run_block); + +#endif /* SecExperimentInternal_h */ diff --git a/SecExperiment/SecExperimentPriv.h b/SecExperiment/SecExperimentPriv.h new file mode 100644 index 00000000..5e99758a --- /dev/null +++ b/SecExperiment/SecExperimentPriv.h @@ -0,0 +1,120 @@ +// +// SecExperimentPriv.h +// Security +// + +#ifndef SecExperiment_h +#define SecExperiment_h + +#include + +#ifndef SEC_EXP_OBJECT_IMPL +SEC_OBJECT_DECL(sec_experiment); +#endif // !SEC_EXP_OBJECT_IMPL + +SEC_ASSUME_NONNULL_BEGIN + +extern const char *kSecExperimentTLSMobileAssetConfig; +extern const char *kSecExperimentDefaultsDomain; + +/*! + * @block sec_experiment_run_block_t + * + * @abstract A block to execute an experiment with a loggable identifier + * and configuration. `identifier` will be uniquely associated with + * `experiment_config` and should be used when measuring data. + * + * @param identifier + * Identifier for the experiment. + * + * @param experiment_config + * Configuration of this experiment. + * + * @return True if the experiment ran successfully, and false otherwise. + */ +typedef bool (^sec_experiment_run_block_t)(const char *identifier, xpc_object_t experiment_config); + +/*! + * @function sec_experiment_run + * + * @abstract + * Asynchronously run an experiment. + * + * @param experiment_name + * Name of the experiment to run. + * + * @param queue + * Queue on which to run the experiment. + * + * @param run_block + * A `sec_experiment_run_block_t` block upon which to execute the given experiment. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_experiment_run(const char *experiment_name, dispatch_queue_t queue, sec_experiment_run_block_t run_block); + +/*! + * @function sec_experiment_create + * + * @abstract + * Create an ARC-able `sec_experiment_t` instance + * + * @param experiment_name + * Name of the experiment. + * + * @return a `sec_experiment_t` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED _Nullable sec_experiment_t +sec_experiment_create(const char *experiment_name); + +/*! + * @function sec_experiment_set_sampling_disabled + * + * @abstract + * Set a flag to disable experiment sampling. + * This function should only be used for testing purposes. + * + * @param experiment + * A `sec_experiment_t` instance. + * + * @param sampling_disabled + * A flag indicating if sampling should be disabled. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_experiment_set_sampling_disabled(sec_experiment_t experiment, bool sampling_disabled); + +/*! + * @function sec_experiment_copy_configuration + * + * @abstract + * Returns the configuration dictionary associated with the given experiment. + * + * @param experiment + * A valid `sec_experiment_t` instance. + * + * @return xpc_object_t containing asset bundle, if client is not part of the experiment return NULL + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED _Nullable xpc_object_t +sec_experiment_copy_configuration(sec_experiment_t experiment); + +/*! + * @function sec_experiment_get_identifier + * + * @abstract + * Returns a loggable identifier for the given experiment. + * + * @param experiment + * A valid `sec_experiment_t` instance. + * + * @return A NULL-terminated, loggable experiment identifier. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +const char * _Nullable +sec_experiment_get_identifier(sec_experiment_t experiment); + +SEC_ASSUME_NONNULL_END + +#endif // SecExperiment_h diff --git a/SecExperiment/TLSAssets/Info.plist b/SecExperiment/TLSAssets/Info.plist new file mode 100644 index 00000000..d314b507 --- /dev/null +++ b/SecExperiment/TLSAssets/Info.plist @@ -0,0 +1,23 @@ + + + + + CFBundleIdentifier + com.apple.MobileAsset.SecExperimentAssets + CFBundleName + SecExperimentAssets + CFBundleVersion + 1.0 + CFBundleShortVersionString + 1.0.0 + CFBundleInfoDictionaryVersion + 1 + MobileAssetProperties + + _ContentVersion + 1 + _CompatibilityVersion + 1 + + + diff --git a/SecExperiment/TLSAssets/Makefile b/SecExperiment/TLSAssets/Makefile new file mode 100644 index 00000000..e3577db2 --- /dev/null +++ b/SecExperiment/TLSAssets/Makefile @@ -0,0 +1,35 @@ +ASSET_DIR = BuiltTLSConfigAssets +ASSET_DATA = ${ASSET_DIR}/AssetData + +asset: + rm -rf ${ASSET_DIR} + mkdir -p ${ASSET_DIR} + ditto Info.plist ${ASSET_DIR} + mkdir -p ${ASSET_DATA} + ditto TLSConfig.plist ${ASSET_DIR}/AssetData + +cleanall: clean + rm -rf ${ASSET_DIR} + +clean: + rm -rf staged + +stage: asset + echo "TLSConfigs staging" + rm -rf staged + $(shell /usr/bin/xcrun --find assettool --sdk ioshostadditions) stage -p . -s staged -v 1 + $(shell /usr/bin/xcrun --find assettool --sdk ioshostadditions) sign -s staged + +installsrc: + $(DITTO) . $(SRCROOT) + +install: + $(PLUTIL) -convert binary1 $(SRCROOT)/Asset/Info.plist + $(DITTO) $(SRCROOT)/Asset $(DSTROOT)/MySampleProject/ + chown -R root:wheel $(DSTROOT) + find $(DSTROOT) -type d -exec chmod 755 {} \; + find $(DSTROOT) -type f -exec chmod 644 {} \; + $(DOTCLEAN) -m $(DSTROOT) + +installhdrs: + $(ECHO) "doing nothing" diff --git a/SecExperiment/TLSAssets/TLSConfig.plist b/SecExperiment/TLSAssets/TLSConfig.plist new file mode 100644 index 00000000..83b98cba --- /dev/null +++ b/SecExperiment/TLSAssets/TLSConfig.plist @@ -0,0 +1,30 @@ + + + + + validate + + tcp + + tls + + max_version + 771 + false_start_enabled + + + + transform + + tcp + + tls + + max_version + 772 + false_start_enabled + + + + + diff --git a/SecExperiment/test/SecExperimentTests.m b/SecExperiment/test/SecExperimentTests.m new file mode 100644 index 00000000..4374136b --- /dev/null +++ b/SecExperiment/test/SecExperimentTests.m @@ -0,0 +1,77 @@ +// +// SecExperimentTests.m +// +// + +#import +#import "SecExperimentInternal.h" +#import "SecExperimentPriv.h" + +@interface SecExperimentTests : XCTestCase +@end + +@implementation SecExperimentTests + +- (void)testCStyleGetTlsConfig { + sec_experiment_t experiment = sec_experiment_create(kSecExperimentTLSMobileAssetConfig); + sec_experiment_set_sampling_disabled(experiment, true); + XCTAssert(experiment, @"sec_experiment_create"); + + xpc_object_t tlsconfig = nil; + tlsconfig = sec_experiment_copy_configuration(experiment); + XCTAssertNotNil(tlsconfig); + +} + +- (void)testCStyleGetTlsConfig_SkipSampling { + sec_experiment_t experiment = sec_experiment_create(kSecExperimentTLSMobileAssetConfig); + XCTAssert(experiment, @"sec_experiment_create"); + + sec_experiment_set_sampling_disabled(experiment, true); + xpc_object_t tlsconfig = sec_experiment_copy_configuration(experiment); + XCTAssertNotNil(tlsconfig); +} + +- (void)testExperimentRun_SkipSamping { + dispatch_queue_t test_queue = dispatch_queue_create("test_queue", NULL); + + __block dispatch_semaphore_t blocker = dispatch_semaphore_create(0); + __block bool experiment_invoked = false; + sec_experiment_run_block_t run_block = ^bool(const char *identifier, xpc_object_t config) { + experiment_invoked = identifier != NULL && config != NULL; + dispatch_semaphore_signal(blocker); + return experiment_invoked; + }; + + sec_experiment_run_internal(kSecExperimentTLSMobileAssetConfig, true, test_queue, run_block); + XCTAssertTrue(dispatch_semaphore_wait(blocker, dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(5 * NSEC_PER_SEC))) == 0L); + XCTAssertTrue(experiment_invoked); +} + +- (void)testDefaultsConfigCopy { + const char *test_key = "test_defaults_experiment_key"; + const char *test_value = "test_value"; + + sec_experiment_t experiment = sec_experiment_create(test_key); + XCTAssert(experiment, @"sec_experiment_create"); + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + + NSString *test_key_string = [NSString stringWithUTF8String:test_key]; + NSString *test_value_string = [NSString stringWithUTF8String:test_value]; + NSDictionary *testConfig = @{test_key_string: test_value_string}; + [defaults setPersistentDomain:testConfig forName:[NSString stringWithUTF8String:kSecExperimentDefaultsDomain]]; + + sec_experiment_set_sampling_disabled(experiment, true); + xpc_object_t tlsconfig = sec_experiment_copy_configuration(experiment); + XCTAssertNotNil(tlsconfig); + XCTAssertTrue(xpc_get_type(tlsconfig) == XPC_TYPE_STRING); + if (xpc_get_type(tlsconfig) == XPC_TYPE_STRING) { + XCTAssertTrue(strcmp(xpc_string_get_string_ptr(tlsconfig), test_value) == 0); + } + + // Clear the persistent domain + [defaults removePersistentDomainForName:[NSString stringWithUTF8String:kSecExperimentDefaultsDomain]]; +} + +@end diff --git a/Security.exp-in b/Security.exp-in index f69fb59b..bf1ddfe8 100644 --- a/Security.exp-in +++ b/Security.exp-in @@ -1,10 +1,16 @@ #include +#if __OBJC2__ +#define SEC_EXP_CLASS(_name) _OBJC_CLASS_$_##_name +#else +#define SEC_EXP_CLASS(_name) .objc_class_name_##_name +#endif + _kSecFrameworkBundleID #include "Security/SecExports.exp-in" #include "Security/SecAccessControlExports.exp-in" -#include "Security/SecureObjectSync/SOSExports.exp-in" +#include "keychain/SecureObjectSync/SOSExports.exp-in" #include "CSSMOID.exp-in" @@ -31,6 +37,9 @@ _SSLSetALPNProtocols _SSLCopyALPNProtocols __SSLProtocolVersionToWireFormatValue _SSLSetECDSACurves +_SSLCiphersuiteGetName +_SSLProtocolGetVersionCodepoint +_SSLProtocolFromVersionCodepoint #if TARGET_OS_IPHONE _SSLAddDistinguishedName @@ -40,6 +49,10 @@ _SSLCopyDistinguishedNames _SSLCopyPeerTrust _SSLCreateContext _SSLCreateContextWithRecordFuncs +_SSLCiphersuiteGroupToCiphersuiteList +_SSLCiphersuiteGroupContainsCiphersuite +_SSLCiphersuiteMaximumTLSVersion +_SSLCiphersuiteMinimumTLSVersion _SSLGetAllowAnonymousCiphers _SSLGetBufferedReadSize _SSLGetCertificate @@ -176,6 +189,10 @@ _SSLClose _SSLContextGetTypeID _SSLCreateContext _SSLCreateContextWithRecordFuncs +_SSLCiphersuiteGroupToCiphersuiteList +_SSLCiphersuiteGroupContainsCiphersuite +_SSLCiphersuiteMaximumTLSVersion +_SSLCiphersuiteMinimumTLSVersion _SSLDisposeContext _SSLGetAllowsAnyRoot _SSLGetAllowsExpiredCerts @@ -310,27 +327,69 @@ _SecAbsoluteTimeFromDateContent /* Internal securityd RPC stuff */ _CKKSSetupControlProtocol -#if TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__) -_OBJC_CLASS_$_CKKSControl -_OBJC_CLASS_$_SecuritydXPCClient -#else -.objc_class_name_CKKSControl -.objc_class_name_SecuritydXPCClient +SEC_EXP_CLASS(CKKSControl) +SEC_EXP_CLASS(SecuritydXPCClient) + +#if __OBJC2__ +SEC_EXP_CLASS(SFSignInAnalytics) +SEC_EXP_CLASS(SecXPCHelper) +SEC_EXP_CLASS(OTClique) +SEC_EXP_CLASS(OTConfigurationContext) +SEC_EXP_CLASS(OTBottleIDs) +SEC_EXP_CLASS(OTOperationConfiguration) +_kSecEntitlementPrivateOctagonEscrow #endif -#if __OBJC2__ && (TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__)) -_OBJC_CLASS_$_SFSignInAnalytics -#endif //__OBJC2__ && IPHONE || OSX +_OTCliqueStatusToString +_OTCliqueStatusFromString + +_OTCliqueCFTypeRepair +_OTCliqueCFTypePasscode +_OTCliqueCFTypeUpgrade +_OTCliqueCDPContextTypeNone +_OTCliqueCDPContextTypeSignIn +_OTCliqueCDPContextTypeRepair +_OTCliqueCDPContextTypeFinishPasscodeChange +_OTCliqueCDPContextTypeRecoveryKeyGenerate +_OTCliqueCDPContextTypeRecoveryKeyNew +_OTCliqueCDPContextTypeUpdatePasscode _OTSetupControlProtocol _OTDefaultContext -#if TARGET_OS_IPHONE || (TARGET_OS_OSX && __x86_64__) -_OBJC_CLASS_$_OTControl -_OBJC_CLASS_$_SecuritydXPCClient -#else -.objc_class_name_OTControl -.objc_class_name_SecuritydXPCClient -#endif +_OctagonErrorDomain +_OTProtocolPairing +_OTProtocolPiggybacking +_OTDefaultsDomain +_OTDefaultsOctagonEnable +_OTTrustStatusChangeNotification + +_OctagonEventAttributeZoneName +_OctagonEventAttributeFailureReason +_OctagonEventAttributeTimeSinceLastPostedFollowUp + +_SecEscrowRequestHavePrecord +_SecEscrowRequestPendingPasscode +_SecEscrowRequestPendingCertificate + +_OTCKContainerName +_CuttlefishTrustZone +_CuttlefishErrorDomain +_TrustedPeersHelperErrorDomain + +_OctagonPlatformSupportsSOS +_OctagonSetPlatformSupportsSOS +_OctagonPerformSOSUpgrade +_OctagonSetSOSUpgrade +_OctagonIsEnabled +_OctagonSetIsEnabled +_OctagonRecoveryKeyIsEnabled +_OctagonRecoveryKeySetIsEnabled +_OctagonAuthoritativeTrustIsEnabled +_OctagonAuthoritativeTrustSetIsEnabled + +SEC_EXP_CLASS(OTJoiningConfiguration) +SEC_EXP_CLASS(OTControl) +SEC_EXP_CLASS(SecuritydXPCClient) _SecAccessGroupsGetCurrent _SecAccessGroupsSetCurrent @@ -342,16 +401,25 @@ _securityd_send_sync_and_do _securityd_send_async_and_do #if TARGET_OS_IOS _SecSecuritySetMusrMode +_SecSecuritySetPersonaMusr #endif +#if TARGET_OS_OSX __SecSetSecuritydTargetUID +#endif _SecDERItemCopyOIDDecimalRepresentation _SecDigestCreate -_SecFrameworkCopyResourceContents _SecFrameworkCopyResourceURL _SecCopyErrorMessageString +_SecFrameworkCopyIPAddressData +_SecFrameworkIsDNSName +_SecFrameworkIsIPAddress + _SecPKCS12Import +#if TARGET_OS_OSX +_SecPKCS12Import_ios +#endif _SecRandomCopyBytes _SecSHA1DigestCreate _SecTaskCopySigningIdentifier @@ -360,6 +428,7 @@ _SecTaskCopyValueForEntitlement _SecTaskCopyValuesForEntitlements _SecTaskCreateFromSelf _SecTaskCreateWithAuditToken +_SecTaskCreateWithXPCMessage _SecTaskGetCodeSignStatus _SecTaskGetTypeID _SecTaskEntitlementsValidated @@ -378,12 +447,6 @@ _SecSMIMEFindBulkAlgForRecipients //Localization _SecFrameworkCopyLocalizedString -// -// utilities -// -_readFileSizet -_writeFileSizet - #if TARGET_OS_OSX // // libsecurity_cms @@ -462,6 +525,8 @@ _AuthorizationCreateWithAuditToken _AuthorizationCreateFromExternalForm _AuthorizationExecuteWithPrivileges _AuthorizationExecuteWithPrivilegesExternalForm +_AuthorizationExecuteWithPrivilegesInternal +_AuthorizationExecuteWithPrivilegesExternalFormInternal _AuthorizationFree _AuthorizationFreeItemSet _AuthorizationMakeExternalForm @@ -708,7 +773,6 @@ _kSecDigestHMACSHA2 _SecExternalSourceTransformCreate _SecExternalSourceSetValue _kSecDecodeTypeAttribute -_CreateSecTransformErrorRef _kSecTransformAbortOriginatorKey _SecGroupTransformHasMember _kSecDigestTypeAttribute @@ -863,6 +927,9 @@ _SecIdentityUpdatePreferenceItem _SecInferLabelFromX509Name _SecItemAdd_ios _SecItemCopyMatching_ios +_SecItemUpdateTokenItems_ios + +_SecKeyGeneratePair_ios _SecItemCopyParentCertificates_osx _SecItemParentCachePurge @@ -1288,6 +1355,45 @@ _kSecAsn1OCSPSignatureTemplate _kSecAsn1OCSPSingleResponseTemplate _kSecAsn1OCSPTbsRequestTemplate +_SecAsn1TaggedTemplateChooser + +_kSecAsn1ATVTemplate +_kSecAsn1GeneralNameTemplate +_kSecAsn1GenNameOtherNameTemplate +_kSecAsn1NameTemplate +_kSecAsn1OtherNameTemplate +_kSecAsn1RDNTemplate + +_kSecAsn1CertExtensionTemplate +_kSecAsn1RevokedCertTemplate +_kSecAsn1SequenceOfCertExtensionTemplate +_kSecAsn1SequenceOfRevokedCertTemplate +_kSecAsn1SignedCertOrCRLTemplate +_kSecAsn1SignedCertTemplate +_kSecAsn1SignedCrlTemplate +_kSecAsn1TBSCertificateTemplate +_kSecAsn1TBSCrlTemplate +_kSecAsn1ValidityTemplate + +_kSecAsn1AccessDescriptionTemplate +_kSecAsn1AuthorityInfoAccessTemplate +_kSecAsn1AuthorityKeyIdTemplate +_kSecAsn1BasicConstraintsTemplate +_kSecAsn1CRLDistributionPointsTemplate +_kSecAsn1CertPoliciesTemplate +_kSecAsn1DistPointFullNameTemplate +_kSecAsn1DistPointRDNTemplate +_kSecAsn1DistributionPointTemplate +_kSecAsn1IssuingDistributionPointTemplate +_kSecAsn1NameConstraintsTemplate +_kSecAsn1PolicyConstraintsTemplate +_kSecAsn1PolicyInformationTemplate +_kSecAsn1PolicyMappingsTemplate +_kSecAsn1PolicyQualifierTemplate +_kSecAsn1QC_StatementTemplate +_kSecAsn1QC_StatementsTemplate +_kSecAsn1SemanticsInformationTemplate + #elif TARGET_OS_OSX _PORT_FreeArena _PORT_NewArena @@ -1601,6 +1707,8 @@ _kSecRequirementKeyEntitlements _kSecRequirementKeyIdentifier _kSecRequirementKeyPackageChecksum _kSecRequirementKeyChecksumAlgorithm +_kSecRequirementKeySecureTimestamp +_kSecRequirementKeyTeamIdentifier _kSecCFErrorArchitecture _kSecCFErrorPath _kSecCFErrorPattern @@ -1621,6 +1729,7 @@ _SecAssessmentUpdate _SecAssessmentCopyUpdate _SecAssessmentControl _SecAssessmentGetTypeID +_SecAssessmentLegacyCheck _SecAssessmentRegisterPackageTicket _SecAssessmentTicketLookup _SecAssessmentTicketRegister @@ -1915,9 +2024,6 @@ _checkpw_internal // _secdebug_internal _secdebugfunc_internal -_weak_os_log_impl -_weak_os_log_create -_weak_os_log_type_enabled _secLogEnable _secLogDisable @@ -1973,6 +2079,7 @@ _OBJC_CLASS_$_SFAnalyticsActivityTracker _OBJC_CLASS_$_SFAnalyticsMultiSampler _OBJC_CLASS_$_SFAnalyticsSampler _OBJC_CLASS_$_SFAnalyticsSQLiteStore +_OBJC_CLASS_$_SecCoreAnalytics _OBJC_METACLASS_$_SFSignInAnalytics _SFAnalyticsMaxEventsToReport _SFSQLiteJournalSuffixes @@ -1981,7 +2088,7 @@ _SFAnalyticsTableSuccessCount _SFAnalyticsTableHardFailures _SFAnalyticsTableSoftFailures _SFAnalyticsTableSamples -_SFAnalyticsTableAllEvents +_SFAnalyticsTableNotes _SFAnalyticsColumnSuccessCount _SFAnalyticsColumnHardFailureCount _SFAnalyticsColumnSoftFailureCount @@ -1989,6 +2096,8 @@ _SFAnalyticsColumnSampleValue _SFAnalyticsColumnSampleName _SFAnalyticsEventTime _SFAnalyticsEventType +_SFAnalyticsEventTypeErrorEvent +_SFAnalyticsEventErrorDestription _SFAnalyticsEventClassKey _SFAnalyticsUserDefaultsSuite _SFAnalyticsFireSamplersNotification @@ -1996,8 +2105,11 @@ _SFAnalyticsTableSchema _SFAnalyticsAttributeErrorCode _SFAnalyticsAttributeErrorDomain _SFAnalyticsAttributeErrorUnderlyingChain +_SFAnalyticsAttributeLastUploadTime +_SFAnalyticsTopicCloudServices _SFAnalyticsTopicKeySync -_SFAnaltyicsTopicTrust +_SFAnalyticsTopicTransparency +_SFAnalyticsTopicTrust _SFAnalyticsErrorDomain _OBJC_CLASS_$_SOSAnalytics @@ -2016,12 +2128,25 @@ _LKAEventUpgrade _LKAReportKeychainUpgradeOutcome _LKAReportKeychainUpgradeOutcomeWithError +_LKABackupReportStart +_LKABackupReportEnd // // Padding // _SecPaddingCompute +// +// Escrow Request Support +// +#if __OBJC2__ + +_OBJC_CLASS_$_SecEscrowRequest + +#endif // __OBJC2__ + +_SecEscrowRequestSetupControlProtocol + // // Code coverage support // @@ -2029,3 +2154,8 @@ _SecPaddingCompute _VPMergeHook* ___llvm_profile_* _lprofCurFilename* + +_SecCreateCFErrorWithXPCObject +_SecCreateXPCObjectWithCFError + +_SecItemVerifyBackupIntegrity diff --git a/Security.xcodeproj/project.pbxproj b/Security.xcodeproj/project.pbxproj index f7e1cec6..1dfe15aa 100644 --- a/Security.xcodeproj/project.pbxproj +++ b/Security.xcodeproj/project.pbxproj @@ -3,33 +3,10 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 52; objects = { /* Begin PBXAggregateTarget section */ - 05EF68AF1949149C007958C3 /* Security_temporary_UI */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 05EF68B01949149C007958C3 /* Build configuration list for PBXAggregateTarget "Security_temporary_UI" */; - buildPhases = ( - ); - dependencies = ( - DCE4E9731D7F3FC200AFB96E /* PBXTargetDependency */, - DCE4E90C1D7F3B4A00AFB96E /* PBXTargetDependency */, - ); - name = Security_temporary_UI; - productName = Security_temporary_UI; - }; - 05EF68B519491512007958C3 /* Security_frameworks */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 05EF68B619491512007958C3 /* Build configuration list for PBXAggregateTarget "Security_frameworks" */; - buildPhases = ( - ); - dependencies = ( - E79EEDDF1CD3FFEA00C2FBFC /* PBXTargetDependency */, - ); - name = Security_frameworks; - productName = Security_framework; - }; 05EF68BB194915A5007958C3 /* Security_executables_osx */ = { isa = PBXAggregateTarget; buildConfigurationList = 05EF68BC194915A5007958C3 /* Build configuration list for PBXAggregateTarget "Security_executables_osx" */; @@ -37,58 +14,23 @@ ); dependencies = ( 47C2F1902059CBFC0062DE30 /* PBXTargetDependency */, + D469C4E5218BECCE008AC1FC /* PBXTargetDependency */, 0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */, - F621D0831ED6ED5B000EA569 /* PBXTargetDependency */, - 6C24EF4A1E415109000DE79F /* PBXTargetDependency */, EB27FF261E40716D00EC9E3A /* PBXTargetDependency */, EBF374821DC058B60065D840 /* PBXTargetDependency */, - DCE4E7B81D7A456500AFB96E /* PBXTargetDependency */, - DC61096D1D78E72C002223DE /* PBXTargetDependency */, - DC610A421D78F3A5002223DE /* PBXTargetDependency */, DC5ABE1C1D832F5E00CF422C /* PBXTargetDependency */, - DCE4E6AA1D7A38E700AFB96E /* PBXTargetDependency */, - DCE4E7F11D7A4BEC00AFB96E /* PBXTargetDependency */, - DC610A381D78F15C002223DE /* PBXTargetDependency */, - DC5AC12F1D8356DA00CF422C /* PBXTargetDependency */, - DCE4E82A1D7A4F2500AFB96E /* PBXTargetDependency */, - DCE4E8621D7A58BA00AFB96E /* PBXTargetDependency */, DCE4E8D81D7F37F200AFB96E /* PBXTargetDependency */, DC3A4B6B1D91EBEE00E46D4A /* PBXTargetDependency */, - DCBE6E4A1D91E23D00A3E5E5 /* PBXTargetDependency */, - DC610ABC1D791139002223DE /* PBXTargetDependency */, - DC610A6C1D78FAA2002223DE /* PBXTargetDependency */, - DC610A541D78F759002223DE /* PBXTargetDependency */, - DC61096B1D78E60C002223DE /* PBXTargetDependency */, - EBD849361B242C8900C5FD1E /* PBXTargetDependency */, E74583BE1BF66489001B54A4 /* PBXTargetDependency */, EB31EA831D3EF2FB008F952A /* PBXTargetDependency */, DA30D6821DF8C93500EC6B43 /* PBXTargetDependency */, - EBC15EA91BE29AC3001C0C5B /* PBXTargetDependency */, EBD31B421E0A18A600FBE9FA /* PBXTargetDependency */, EBD31B3B1E0A186500FBE9FA /* PBXTargetDependency */, - DCB515D91ED3CC6B001F1152 /* PBXTargetDependency */, - 6C24EF4A1E415109000DE79F /* PBXTargetDependency */, - DCB515D71ED3CC52001F1152 /* PBXTargetDependency */, 6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */, - 6CAA8CE91F82FD13007B6E03 /* PBXTargetDependency */, - DC5225001E40295C0021640A /* PBXTargetDependency */, - EB636BD320992DB400C1E21A /* PBXTargetDependency */, - EB11965A20A6300600BFDA1B /* PBXTargetDependency */, - 6C7C38811FD88C4700DFFE68 /* PBXTargetDependency */, ); name = Security_executables_osx; productName = Security_executables; }; - 05EF68C1194915FB007958C3 /* Security_kexts */ = { - isa = PBXAggregateTarget; - buildConfigurationList = 05EF68C2194915FB007958C3 /* Build configuration list for PBXAggregateTarget "Security_kexts" */; - buildPhases = ( - ); - dependencies = ( - ); - name = Security_kexts; - productName = Security_kexts; - }; 0C6799F912F7C37C00712919 /* dtlsTests */ = { isa = PBXAggregateTarget; buildConfigurationList = 0C679A0412F7C3AE00712919 /* Build configuration list for PBXAggregateTarget "dtlsTests" */; @@ -107,94 +49,66 @@ buildPhases = ( ); dependencies = ( - DC71D9E31D95BAD50065FB93 /* PBXTargetDependency */, EB6A6FBD1B90F9170045DC68 /* PBXTargetDependency */, - BE9C38CF1EB115C9007E2AE1 /* PBXTargetDependency */, + DC647C46208A85C900D0F9F8 /* PBXTargetDependency */, + D4F56BAB217FCAF600FCA6B7 /* PBXTargetDependency */, ); 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 */, + EB74CC232207E99700F1BBAD /* PBXTargetDependency */, 47C2F18C2059CBEA0062DE30 /* PBXTargetDependency */, + 4771D982209A76B100BA9772 /* PBXTargetDependency */, 0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */, - D41257F11E941E7D00781F23 /* PBXTargetDependency */, EB27FF281E40717400EC9E3A /* PBXTargetDependency */, EBF374841DC058C00065D840 /* PBXTargetDependency */, - EBB696D41BE2085700715F16 /* PBXTargetDependency */, 438169E71B4EE4B300C54D58 /* PBXTargetDependency */, - 5EF7C2561B00EEF900E5E99C /* PBXTargetDependency */, - 5E10995419A5E80B00A60E2B /* PBXTargetDependency */, - 4C541F8C0F250C0400E508AE /* PBXTargetDependency */, - 4C541F8E0F250C0900E508AE /* PBXTargetDependency */, - 4C541F920F250C1300E508AE /* PBXTargetDependency */, - 4C541F900F250C0E00E508AE /* PBXTargetDependency */, - 4C9DE9EF1181ACA000CF5C27 /* PBXTargetDependency */, - 0C664AB41759270C0092D3D9 /* PBXTargetDependency */, - 0C99B740131C984900584CF4 /* PBXTargetDependency */, - 0CC827F2138712B100BD99B7 /* PBXTargetDependency */, 52D82BF616A627100078DFE5 /* PBXTargetDependency */, + DA41FE1D2241B64800838FB3 /* PBXTargetDependency */, 4C52D0EE16EFCD720079966E /* PBXTargetDependency */, - BE197F631911742900BA91D1 /* PBXTargetDependency */, - BE4AC9B418B8020400B84964 /* PBXTargetDependency */, 5346481B17331ED800FE9172 /* PBXTargetDependency */, - F94E7AE21ACC8E7700F23132 /* PBXTargetDependency */, - EB9C1DB71BDFD51800F89272 /* PBXTargetDependency */, - DCB515DB1ED3CC73001F1152 /* PBXTargetDependency */, - 6C24EF531E415132000DE79F /* PBXTargetDependency */, - DCB515D01ED3CC36001F1152 /* PBXTargetDependency */, - DC5224F91E4029520021640A /* PBXTargetDependency */, - EB0D30FA1EF12BFB00C3C17D /* PBXTargetDependency */, 6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */, - 6CAA8CE51F82FD08007B6E03 /* PBXTargetDependency */, - 6C7C38881FD88C5A00DFFE68 /* PBXTargetDependency */, - EB636BCA20992D8900C1E21A /* PBXTargetDependency */, - EB11965C20A6301100BFDA1B /* PBXTargetDependency */, + BE4AC9B418B8020400B84964 /* PBXTargetDependency */, + BE197F631911742900BA91D1 /* PBXTargetDependency */, ); name = Security_executables_ios; productName = phase2; }; - 4C541F950F250C3000E508AE /* phase1 */ = { + 4C91273D0ADBF46200AF202E /* Security_all_ios */ = { isa = PBXAggregateTarget; - buildConfigurationList = 4C541FA20F250C8C00E508AE /* Build configuration list for PBXAggregateTarget "phase1" */; + buildConfigurationList = 4C91274A0ADBF4A100AF202E /* Build configuration list for PBXAggregateTarget "Security_all_ios" */; buildPhases = ( ); dependencies = ( - E79EEDD71CD3F9F800C2FBFC /* PBXTargetDependency */, + EB6A6FBB1B90F8EC0045DC68 /* PBXTargetDependency */, + D4F47B2D22270B23003483E9 /* PBXTargetDependency */, + 4C541FA10F250C5200E508AE /* PBXTargetDependency */, + D4F47B3122270B38003483E9 /* PBXTargetDependency */, + EB58A05E1E74C51F009C10D7 /* PBXTargetDependency */, + DC647C4A208A865200D0F9F8 /* PBXTargetDependency */, ); - name = phase1; - productName = phase1; + name = Security_all_ios; + productName = world; }; - 4C91273D0ADBF46200AF202E /* ios */ = { + BEAA0040202B728B00E51F45 /* Security_executables_Swift */ = { isa = PBXAggregateTarget; - buildConfigurationList = 4C91274A0ADBF4A100AF202E /* Build configuration list for PBXAggregateTarget "ios" */; + buildConfigurationList = BEAA0041202B728B00E51F45 /* Build configuration list for PBXAggregateTarget "Security_executables_Swift" */; buildPhases = ( ); dependencies = ( - EB6A6FBB1B90F8EC0045DC68 /* PBXTargetDependency */, - 4C541FA10F250C5200E508AE /* PBXTargetDependency */, - E7CFF6771C84F66A00E3484E /* PBXTargetDependency */, - EB58A05E1E74C51F009C10D7 /* PBXTargetDependency */, + DCA232FC209A35840007B57D /* PBXTargetDependency */, + DC0503612140848100A8EDB7 /* PBXTargetDependency */, + DCC5D6682087EDB300BBC127 /* PBXTargetDependency */, + DC27C3CD20EAFDF800F7839C /* PBXTargetDependency */, ); - name = ios; - productName = world; + name = Security_executables_Swift; + productName = Security_executables_Swift; }; D41AD42D1B967169008C7270 /* Security_executables_watchos */ = { isa = PBXAggregateTarget; @@ -202,27 +116,15 @@ buildPhases = ( ); dependencies = ( - EB8910FE20E06DF500DE533F /* PBXTargetDependency */, 47C2F1922059CC040062DE30 /* PBXTargetDependency */, - BE061EB91EE5EBA000B22118 /* PBXTargetDependency */, - EBA62C1C1EAD34CD0096B33A /* PBXTargetDependency */, - D41257F51E941E8E00781F23 /* PBXTargetDependency */, EBF374881DC058CC0065D840 /* PBXTargetDependency */, - D41AD45C1B978A7A008C7270 /* PBXTargetDependency */, - D41AD45E1B978A7C008C7270 /* PBXTargetDependency */, - D41AD4601B978E18008C7270 /* PBXTargetDependency */, - D41AD4621B978E24008C7270 /* PBXTargetDependency */, - D41AD4661B978F19008C7270 /* PBXTargetDependency */, - D41AD4681B978F20008C7270 /* PBXTargetDependency */, - D41AD46A1B978F24008C7270 /* PBXTargetDependency */, - D41AD46C1B978F28008C7270 /* PBXTargetDependency */, - D41AD46E1B978F4C008C7270 /* PBXTargetDependency */, - EB9FE0B61BFBC499004FEAAF /* PBXTargetDependency */, - EB636BD520992DC000C1E21A /* PBXTargetDependency */, - EB89FAFE20DBDAA800085498 /* PBXTargetDependency */, - EB89FB0020DBDAA800085498 /* PBXTargetDependency */, - EB89FB0220DBDAA800085498 /* PBXTargetDependency */, - EB8910F820E0287E00DE533F /* PBXTargetDependency */, + 87EDC39E2141BB8A007B0E64 /* PBXTargetDependency */, + 87EDC3A22141BB92007B0E64 /* PBXTargetDependency */, + 87EDC3A42141BB9B007B0E64 /* PBXTargetDependency */, + 87EDC3A82141BBAA007B0E64 /* PBXTargetDependency */, + DA41FE1F2241B65A00838FB3 /* PBXTargetDependency */, + 87EDC3B22141BBD5007B0E64 /* PBXTargetDependency */, + D456A06B22AF1874001119F3 /* PBXTargetDependency */, ); name = Security_executables_watchos; productName = Security_executables_watchos; @@ -233,35 +135,303 @@ buildPhases = ( ); dependencies = ( - 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */, - BE061EB71EE5EB9000B22118 /* PBXTargetDependency */, - EBA62C151EAD34C60096B33A /* PBXTargetDependency */, - D41257F31E941E8600781F23 /* PBXTargetDependency */, + EB2ED4E922547DE900E98082 /* PBXTargetDependency */, + DC391FA321C03F8D00772585 /* PBXTargetDependency */, + 0CF09210219649DB002B0AEE /* PBXTargetDependency */, EBF374861DC058C50065D840 /* PBXTargetDependency */, - D41AD43A1B96721E008C7270 /* PBXTargetDependency */, D41AD4521B9788B2008C7270 /* PBXTargetDependency */, - D41AD4461B9786A3008C7270 /* PBXTargetDependency */, - D41AD43E1B967242008C7270 /* PBXTargetDependency */, - D41AD43C1B96723B008C7270 /* PBXTargetDependency */, - D41AD44C1B9786E2008C7270 /* PBXTargetDependency */, - D41AD4401B96724C008C7270 /* PBXTargetDependency */, - D41AD4441B978681008C7270 /* PBXTargetDependency */, - D41AD4421B97866C008C7270 /* PBXTargetDependency */, - D419C0261E57EACA008619D1 /* PBXTargetDependency */, - D41AD44E1B978791008C7270 /* PBXTargetDependency */, - D41AD44A1B9786D8008C7270 /* PBXTargetDependency */, - EB9FE08D1BFBC48F004FEAAF /* PBXTargetDependency */, - EB636BD120992DA300C1E21A /* PBXTargetDependency */, - EBC73F52209A705A00AE3350 /* PBXTargetDependency */, - EB11965E20A6302100BFDA1B /* PBXTargetDependency */, - EBC73F5D209A739600AE3350 /* PBXTargetDependency */, - EBC73F64209A73A100AE3350 /* PBXTargetDependency */, - EBC73F66209A73A100AE3350 /* PBXTargetDependency */, - EB8910F120E0287600DE533F /* PBXTargetDependency */, + 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */, + D456A06822AF1866001119F3 /* PBXTargetDependency */, ); name = Security_executables_tvos; productName = Security_executables_tvos; }; + D477EE5C21ED476D00C9AAFF /* Security_tests_bridge */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D477EE5D21ED476D00C9AAFF /* Build configuration list for PBXAggregateTarget "Security_tests_bridge" */; + buildPhases = ( + ); + dependencies = ( + D4EB53BE223C3D2B009101F8 /* PBXTargetDependency */, + D4EB53B9223C3CE3009101F8 /* PBXTargetDependency */, + D4EB53BB223C3CE3009101F8 /* PBXTargetDependency */, + 6C4AA1AA2228B640006FA945 /* PBXTargetDependency */, + ); + name = Security_tests_bridge; + productName = Security_tests_bridge; + }; + D477EE6021ED477B00C9AAFF /* Security_tests_tvos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D477EE6121ED477C00C9AAFF /* Build configuration list for PBXAggregateTarget "Security_tests_tvos" */; + buildPhases = ( + ); + dependencies = ( + EB694E87223AB79400F02C1C /* PBXTargetDependency */, + D4E0E9762224DE9100A802E0 /* PBXTargetDependency */, + D4E0E9702224DE8200A802E0 /* PBXTargetDependency */, + D4E0E9722224DE8200A802E0 /* PBXTargetDependency */, + D4E0E9742224DE8200A802E0 /* PBXTargetDependency */, + D4E0E96E2224DE7A00A802E0 /* PBXTargetDependency */, + D4E0E96C2224DE7000A802E0 /* PBXTargetDependency */, + D4E0E96A2224DE6800A802E0 /* PBXTargetDependency */, + D4E0E9682224DE5700A802E0 /* PBXTargetDependency */, + D4E0E9662224DE5100A802E0 /* PBXTargetDependency */, + D4E0E9642224DE4900A802E0 /* PBXTargetDependency */, + D4E0E9622224DE3D00A802E0 /* PBXTargetDependency */, + D4E0E9602224DE2700A802E0 /* PBXTargetDependency */, + D4E0E95E2224DE1A00A802E0 /* PBXTargetDependency */, + D4E0E95C2224DE1000A802E0 /* PBXTargetDependency */, + D4E0E9582224DDFE00A802E0 /* PBXTargetDependency */, + D4E0E95A2224DDFE00A802E0 /* PBXTargetDependency */, + D4E0E9562224DDF000A802E0 /* PBXTargetDependency */, + D4E0E9542224DDEA00A802E0 /* PBXTargetDependency */, + D4E0E9512224DDE300A802E0 /* PBXTargetDependency */, + EBB8521622F793CF00424FD0 /* PBXTargetDependency */, + ); + name = Security_tests_tvos; + productName = Security_tests_tvos; + }; + D477EE6421ED479500C9AAFF /* Security_tests_watchos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D477EE6521ED479500C9AAFF /* Build configuration list for PBXAggregateTarget "Security_tests_watchos" */; + buildPhases = ( + ); + dependencies = ( + EB694E72223AB78E00F02C1C /* PBXTargetDependency */, + D4E0E9AC2224DFEB00A802E0 /* PBXTargetDependency */, + D4E0E9A62224DFDD00A802E0 /* PBXTargetDependency */, + D4E0E9A82224DFDD00A802E0 /* PBXTargetDependency */, + D4E0E9AA2224DFDD00A802E0 /* PBXTargetDependency */, + D4E0E9A42224DFD500A802E0 /* PBXTargetDependency */, + D4E0E9A22224DFCB00A802E0 /* PBXTargetDependency */, + D4E0E9A02224DFC500A802E0 /* PBXTargetDependency */, + D4E0E99E2224DFBA00A802E0 /* PBXTargetDependency */, + D4E0E99C2224DFB500A802E0 /* PBXTargetDependency */, + D4E0E99A2224DFAD00A802E0 /* PBXTargetDependency */, + D4E0E9982224DF9A00A802E0 /* PBXTargetDependency */, + D4E0E9962224DF9300A802E0 /* PBXTargetDependency */, + D4E0E9942224DF8D00A802E0 /* PBXTargetDependency */, + D4E0E9902224DF8500A802E0 /* PBXTargetDependency */, + D4E0E9922224DF8500A802E0 /* PBXTargetDependency */, + D4E0E98E2224DF7D00A802E0 /* PBXTargetDependency */, + D4E0E98C2224DF7700A802E0 /* PBXTargetDependency */, + D4E0E98A2224DF6F00A802E0 /* PBXTargetDependency */, + EBB8521822F793EF00424FD0 /* PBXTargetDependency */, + ); + name = Security_tests_watchos; + productName = Security_tests_watchos; + }; + D477EE6821ED47C500C9AAFF /* Security_executables_darwinos_only_osx */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D477EE6921ED47C600C9AAFF /* Build configuration list for PBXAggregateTarget "Security_executables_darwinos_only_osx" */; + buildPhases = ( + EB15CA26223C60B9002BF362 /* ShellScript */, + ); + dependencies = ( + ); + name = Security_executables_darwinos_only_osx; + productName = Security_executables_darwinos_only_osx; + }; + D477EE6C21ED47DA00C9AAFF /* Security_executables_darwinos_only_ios */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D477EE6D21ED47DB00C9AAFF /* Build configuration list for PBXAggregateTarget "Security_executables_darwinos_only_ios" */; + buildPhases = ( + ); + dependencies = ( + EB6952BB223B75FC00F02C1C /* PBXTargetDependency */, + EB8908A221F17E3B00F0DDDB /* PBXTargetDependency */, + ); + name = Security_executables_darwinos_only_ios; + productName = Security_executables_darwinos_only_ios; + }; + D4D1D3FC21AD0B3F0012C66C /* Security_executables_core_watchos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4D1D3FE21AD0B3F0012C66C /* Build configuration list for PBXAggregateTarget "Security_executables_core_watchos" */; + buildPhases = ( + ); + dependencies = ( + D4E0E9882224DF5800A802E0 /* PBXTargetDependency */, + D4E0E9862224DF4E00A802E0 /* PBXTargetDependency */, + ); + name = Security_executables_core_watchos; + productName = Security_executables_core; + }; + D4D1D40121AD0B4B0012C66C /* Security_executables_core_tvos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4D1D40321AD0B4B0012C66C /* Build configuration list for PBXAggregateTarget "Security_executables_core_tvos" */; + buildPhases = ( + ); + dependencies = ( + D45D8F9A2224DD8200D6C124 /* PBXTargetDependency */, + D45D8F982224DD7B00D6C124 /* PBXTargetDependency */, + ); + name = Security_executables_core_tvos; + productName = Security_executables_core; + }; + D4D1D40821ADC9720012C66C /* Security_executables_core_osx */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4D1D40A21ADC9720012C66C /* Build configuration list for PBXAggregateTarget "Security_executables_core_osx" */; + buildPhases = ( + ); + dependencies = ( + D4A763E52224BE170063B2B9 /* PBXTargetDependency */, + D4A763D12224BCDE0063B2B9 /* PBXTargetDependency */, + D4A763CF2224BCD10063B2B9 /* PBXTargetDependency */, + ); + name = Security_executables_core_osx; + productName = Security_executables_core; + }; + D4F47B3822270B6E003483E9 /* Security_all_watchos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F47B3922270B6F003483E9 /* Build configuration list for PBXAggregateTarget "Security_all_watchos" */; + buildPhases = ( + ); + dependencies = ( + D4F47B4522270BB6003483E9 /* PBXTargetDependency */, + D4F47B4722270BB6003483E9 /* PBXTargetDependency */, + D4F47B4922270BB6003483E9 /* PBXTargetDependency */, + D4F47B4B22270BB6003483E9 /* PBXTargetDependency */, + D4F47B4D22270BB6003483E9 /* PBXTargetDependency */, + D4F47B4F22270BC0003483E9 /* PBXTargetDependency */, + ); + name = Security_all_watchos; + productName = Security_all_watchos; + }; + D4F47B3C22270B89003483E9 /* Security_all_tvos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F47B3D22270B8A003483E9 /* Build configuration list for PBXAggregateTarget "Security_all_tvos" */; + buildPhases = ( + ); + dependencies = ( + D4F47B5122270BD9003483E9 /* PBXTargetDependency */, + D4F47B5322270BD9003483E9 /* PBXTargetDependency */, + D4F47B5522270BD9003483E9 /* PBXTargetDependency */, + D4F47B5722270BD9003483E9 /* PBXTargetDependency */, + D4F47B5922270BD9003483E9 /* PBXTargetDependency */, + D4F47B5B22270BDE003483E9 /* PBXTargetDependency */, + ); + name = Security_all_tvos; + productName = Security_all_tvos; + }; + D4F47B4022270B97003483E9 /* Security_all_bridge */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F47B4122270B97003483E9 /* Build configuration list for PBXAggregateTarget "Security_all_bridge" */; + buildPhases = ( + ); + dependencies = ( + D4F47B5D22270BEB003483E9 /* PBXTargetDependency */, + D4F47B5F22270BEB003483E9 /* PBXTargetDependency */, + D4F47B6122270BEB003483E9 /* PBXTargetDependency */, + ); + name = Security_all_bridge; + productName = Security_all_bridge; + }; + D4F56B86217FA32000FCA6B7 /* Security_executables_core_ios */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56B8B217FA32000FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_executables_core_ios" */; + buildPhases = ( + ); + dependencies = ( + D45D8F702224DB6D00D6C124 /* PBXTargetDependency */, + D45D8F6E2224DB6400D6C124 /* PBXTargetDependency */, + ); + name = Security_executables_core_ios; + productName = Security_executables_core; + }; + D4F56B8D217FA3F800FCA6B7 /* Security_frameworks_tvos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56B8E217FA3F800FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_frameworks_tvos" */; + buildPhases = ( + ); + dependencies = ( + D4F56B9D217FCA7E00FCA6B7 /* PBXTargetDependency */, + D4F56B9F217FCA8600FCA6B7 /* PBXTargetDependency */, + D4F56BB72181380600FCA6B7 /* PBXTargetDependency */, + ); + name = Security_frameworks_tvos; + productName = Security_frameworks_tvos; + }; + D4F56B91217FA40800FCA6B7 /* Security_frameworks_watchos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56B92217FA40800FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_frameworks_watchos" */; + buildPhases = ( + ); + dependencies = ( + D4F56BA7217FCAB000FCA6B7 /* PBXTargetDependency */, + D4F56BA5217FCAAA00FCA6B7 /* PBXTargetDependency */, + D4F56BBB2181387600FCA6B7 /* PBXTargetDependency */, + ); + name = Security_frameworks_watchos; + productName = Security_frameworks_watchos; + }; + D4F56BC221813EC900FCA6B7 /* Security_internal_osx */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56BC321813EC900FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_osx" */; + buildPhases = ( + ); + dependencies = ( + D4E0E9BC2224E15500A802E0 /* PBXTargetDependency */, + D45D8F5C2224D9F100D6C124 /* PBXTargetDependency */, + D45D8F5A2224D8A100D6C124 /* PBXTargetDependency */, + D45D8F582224D88F00D6C124 /* PBXTargetDependency */, + D45D8F562224D87C00D6C124 /* PBXTargetDependency */, + D45D8F542224D7C400D6C124 /* PBXTargetDependency */, + D45D8F522224D76E00D6C124 /* PBXTargetDependency */, + D45D8F4F2224D72C00D6C124 /* PBXTargetDependency */, + ); + name = Security_internal_osx; + productName = Security_internal_osx; + }; + D4F56BC621813ECF00FCA6B7 /* Security_internal_ios */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56BC721813ECF00FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_ios" */; + buildPhases = ( + ); + dependencies = ( + D4EB53C9223C4AB5009101F8 /* PBXTargetDependency */, + D4E0E9BE2224E15E00A802E0 /* PBXTargetDependency */, + D45D8F902224DC9900D6C124 /* PBXTargetDependency */, + D45D8F8E2224DC8E00D6C124 /* PBXTargetDependency */, + D45D8F922224DCCB00D6C124 /* PBXTargetDependency */, + D45D8F942224DCD700D6C124 /* PBXTargetDependency */, + D45D8F8C2224DC7600D6C124 /* PBXTargetDependency */, + ); + name = Security_internal_ios; + productName = Security_internal_osx; + }; + D4F56BCA21813EDC00FCA6B7 /* Security_internal_tvos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56BCB21813EDC00FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_tvos" */; + buildPhases = ( + ); + dependencies = ( + D476BC3922BD34280098E15A /* PBXTargetDependency */, + D4EB53CB223C4ABE009101F8 /* PBXTargetDependency */, + D4E0E9C02224E16A00A802E0 /* PBXTargetDependency */, + D4E0E97E2224DF0B00A802E0 /* PBXTargetDependency */, + D4E0E9802224DF0B00A802E0 /* PBXTargetDependency */, + D4E0E9822224DF0B00A802E0 /* PBXTargetDependency */, + D4E0E97C2224DF0300A802E0 /* PBXTargetDependency */, + ); + name = Security_internal_tvos; + productName = Security_internal_osx; + }; + D4F56BCE21813EE800FCA6B7 /* Security_internal_watchos */ = { + isa = PBXAggregateTarget; + buildConfigurationList = D4F56BCF21813EE800FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_watchos" */; + buildPhases = ( + ); + dependencies = ( + D476BC3C22BD34320098E15A /* PBXTargetDependency */, + D4E0E9C22224E17300A802E0 /* PBXTargetDependency */, + D4E0E9B02224E00F00A802E0 /* PBXTargetDependency */, + D4E0E9B22224E00F00A802E0 /* PBXTargetDependency */, + D4E0E9B42224E00F00A802E0 /* PBXTargetDependency */, + D4E0E9AE2224E00600A802E0 /* PBXTargetDependency */, + ); + name = Security_internal_watchos; + productName = Security_internal_osx; + }; DC008B451D90CE53004002A3 /* securityd_macos_mig */ = { isa = PBXAggregateTarget; buildConfigurationList = DC008B561D90CE53004002A3 /* Build configuration list for PBXAggregateTarget "securityd_macos_mig" */; @@ -317,6 +487,17 @@ name = security_cssm_generator; productName = securityd_macos_mig_nomake; }; + DC6D1C70208A547400AB21AF /* Security_frameworks_bridge */ = { + isa = PBXAggregateTarget; + buildConfigurationList = DC6D1C75208A547400AB21AF /* Build configuration list for PBXAggregateTarget "Security_frameworks_bridge" */; + buildPhases = ( + ); + dependencies = ( + DC6D1C73208A547400AB21AF /* PBXTargetDependency */, + ); + name = Security_frameworks_bridge; + productName = kernel; + }; DC82FFE51D90D3F60085674B /* security_utilities_DTrace */ = { isa = PBXAggregateTarget; buildConfigurationList = DC82FFE71D90D3F60085674B /* Build configuration list for PBXAggregateTarget "security_utilities_DTrace" */; @@ -391,20 +572,33 @@ name = "All Codesigning"; productName = "All Codesigning"; }; - E74584661BF68EBA001B54A4 /* osx */ = { + DCDA5E4F2124B9C5009B11B2 /* aks_support */ = { + isa = PBXAggregateTarget; + buildConfigurationList = DCDA5E542124B9C6009B11B2 /* Build configuration list for PBXAggregateTarget "aks_support" */; + buildPhases = ( + ); + dependencies = ( + DC3E18E82125F9EF00073D80 /* PBXTargetDependency */, + DCDA5E582124B9DC009B11B2 /* PBXTargetDependency */, + ); + name = aks_support; + productName = aks_support; + }; + E74584661BF68EBA001B54A4 /* Security_all_osx */ = { isa = PBXAggregateTarget; - buildConfigurationList = E74584671BF68EBA001B54A4 /* Build configuration list for PBXAggregateTarget "osx" */; + buildConfigurationList = E74584671BF68EBA001B54A4 /* Build configuration list for PBXAggregateTarget "Security_all_osx" */; buildPhases = ( ); dependencies = ( E79EEDE71CD4003900C2FBFC /* PBXTargetDependency */, - E7CFF6751C84F65D00E3484E /* PBXTargetDependency */, + D4F47B3322270B4E003483E9 /* PBXTargetDependency */, E745846D1BF68ECB001B54A4 /* PBXTargetDependency */, - E74584711BF68ECB001B54A4 /* PBXTargetDependency */, - E745846F1BF68ECB001B54A4 /* PBXTargetDependency */, + D4F47B3722270B5D003483E9 /* PBXTargetDependency */, EB58A05C1E74C517009C10D7 /* PBXTargetDependency */, + DC647C48208A864800D0F9F8 /* PBXTargetDependency */, + DCC5D66A2087EEE200BBC127 /* PBXTargetDependency */, ); - name = osx; + name = Security_all_osx; productName = macosx; }; E79EEDA71CD3F87B00C2FBFC /* Security_tests_osx */ = { @@ -413,17 +607,40 @@ buildPhases = ( ); dependencies = ( - EBFF18CE1F02BA66004E58FC /* PBXTargetDependency */, - BE061EAC1EE5EA5600B22118 /* PBXTargetDependency */, - F667EC671E96FA4600203D5C /* PBXTargetDependency */, - EB1C4CA71E85883900404981 /* PBXTargetDependency */, - EB1C4CA91E85883900404981 /* PBXTargetDependency */, - EB1C4CAB1E85883900404981 /* PBXTargetDependency */, - EB58A0601E74C8D9009C10D7 /* PBXTargetDependency */, - EB10557F1E14DFBE0003C309 /* PBXTargetDependency */, - BE9C38D11EB115F4007E2AE1 /* PBXTargetDependency */, - DCDB29761FD8839F00B5D242 /* PBXTargetDependency */, - 47D991D720407F890078CAE2 /* PBXTargetDependency */, + EB694E8B223AB7A200F02C1C /* PBXTargetDependency */, + EB694DD0223A087700F02C1C /* PBXTargetDependency */, + EB694DC82239E5F200F02C1C /* PBXTargetDependency */, + EB694DAF2239E59600F02C1C /* PBXTargetDependency */, + D4BFFD6722275A4B00163B4B /* PBXTargetDependency */, + D45D8F5E2224DA1000D6C124 /* PBXTargetDependency */, + D4A763F72224BE980063B2B9 /* PBXTargetDependency */, + D4A763F52224BE8A0063B2B9 /* PBXTargetDependency */, + D4A763F32224BE810063B2B9 /* PBXTargetDependency */, + D4A763EF2224BE6E0063B2B9 /* PBXTargetDependency */, + D4A763F12224BE6E0063B2B9 /* PBXTargetDependency */, + D4A763ED2224BE630063B2B9 /* PBXTargetDependency */, + D4A763EB2224BE580063B2B9 /* PBXTargetDependency */, + D4A763E92224BE430063B2B9 /* PBXTargetDependency */, + D4A763E72224BE2F0063B2B9 /* PBXTargetDependency */, + D4A763E32224BDF90063B2B9 /* PBXTargetDependency */, + D4A763E12224BDED0063B2B9 /* PBXTargetDependency */, + D4A763DF2224BDDC0063B2B9 /* PBXTargetDependency */, + D4A763DD2224BDCC0063B2B9 /* PBXTargetDependency */, + D4A763DB2224BDAB0063B2B9 /* PBXTargetDependency */, + D4A763D92224BD990063B2B9 /* PBXTargetDependency */, + D4A763D52224BD6F0063B2B9 /* PBXTargetDependency */, + D4A763D32224BD640063B2B9 /* PBXTargetDependency */, + D477EE7121ED48A500C9AAFF /* PBXTargetDependency */, + D477EE7321ED48AA00C9AAFF /* PBXTargetDependency */, + D477EE7521ED48B400C9AAFF /* PBXTargetDependency */, + D477EE7721ED48C000C9AAFF /* PBXTargetDependency */, + D477EE7921ED48C000C9AAFF /* PBXTargetDependency */, + D477EE7B21ED48C000C9AAFF /* PBXTargetDependency */, + D477EE7D21ED48CB00C9AAFF /* PBXTargetDependency */, + D477EE7F21ED48D500C9AAFF /* PBXTargetDependency */, + D477EE8321ED48E800C9AAFF /* PBXTargetDependency */, + D477EE8121ED48DF00C9AAFF /* PBXTargetDependency */, + EBB8521022F793A200424FD0 /* PBXTargetDependency */, ); name = Security_tests_osx; productName = Security_test_macos; @@ -434,6 +651,26 @@ buildPhases = ( ); dependencies = ( + EB694E89223AB79B00F02C1C /* PBXTargetDependency */, + EB694DCE223A086C00F02C1C /* PBXTargetDependency */, + EB694DC42239E5A200F02C1C /* PBXTargetDependency */, + D4E0E97A2224DEE600A802E0 /* PBXTargetDependency */, + D45D8F882224DC3F00D6C124 /* PBXTargetDependency */, + D45D8F862224DBF800D6C124 /* PBXTargetDependency */, + D45D8F842224DBEF00D6C124 /* PBXTargetDependency */, + D45D8F822224DBE300D6C124 /* PBXTargetDependency */, + D45D8F7E2224DBD900D6C124 /* PBXTargetDependency */, + D45D8F7C2224DBC600D6C124 /* PBXTargetDependency */, + D45D8F7A2224DBBD00D6C124 /* PBXTargetDependency */, + D45D8F782224DBB500D6C124 /* PBXTargetDependency */, + D45D8F742224DB9C00D6C124 /* PBXTargetDependency */, + D45D8F722224DB9200D6C124 /* PBXTargetDependency */, + D45D8F6C2224DABA00D6C124 /* PBXTargetDependency */, + D45D8F662224DA9900D6C124 /* PBXTargetDependency */, + D45D8F6A2224DA9900D6C124 /* PBXTargetDependency */, + D45D8F642224DA8E00D6C124 /* PBXTargetDependency */, + D45D8F622224DA8400D6C124 /* PBXTargetDependency */, + D45D8F602224DA6600D6C124 /* PBXTargetDependency */, BE061EB31EE5EAC800B22118 /* PBXTargetDependency */, EB1C4CB21E85884300404981 /* PBXTargetDependency */, EB1C4CB41E85884300404981 /* PBXTargetDependency */, @@ -441,8 +678,8 @@ EB58A0621E74C8E4009C10D7 /* PBXTargetDependency */, EB10557D1E14DFB60003C309 /* PBXTargetDependency */, BE9C38D31EB11605007E2AE1 /* PBXTargetDependency */, - DCDB29781FD883AB00B5D242 /* PBXTargetDependency */, 47D991D020407F7E0078CAE2 /* PBXTargetDependency */, + EBB8521222F793AC00424FD0 /* PBXTargetDependency */, ); name = Security_tests_ios; productName = Security_test_ios; @@ -453,49 +690,25 @@ buildPhases = ( ); dependencies = ( - DC71D9E11D95BAC40065FB93 /* PBXTargetDependency */, DC178BF31D77ABE300B50D50 /* PBXTargetDependency */, - BE9C38C81EB115A7007E2AE1 /* PBXTargetDependency */, + DC647C44208A85BE00D0F9F8 /* PBXTargetDependency */, DC58C4431D77C1F8003C25A4 /* PBXTargetDependency */, + D4F56BB32181306900FCA6B7 /* PBXTargetDependency */, ); name = Security_frameworks_osx; productName = Security_frameworks_macos; }; - E79EEDE01CD4000C00C2FBFC /* Security_executables */ = { - isa = PBXAggregateTarget; - buildConfigurationList = E79EEDE11CD4000C00C2FBFC /* Build configuration list for PBXAggregateTarget "Security_executables" */; - buildPhases = ( - ); - dependencies = ( - E79EEDE51CD4001300C2FBFC /* PBXTargetDependency */, - ); - name = Security_executables; - productName = Security_executables; - }; E7CFF6471C84F61200E3484E /* Security_KeychainCircle */ = { isa = PBXAggregateTarget; buildConfigurationList = E7CFF66F1C84F61200E3484E /* Build configuration list for PBXAggregateTarget "Security_KeychainCircle" */; buildPhases = ( + D4E0E9C32224E18900A802E0 /* ShellScript */, ); dependencies = ( - E7CFF6711C84F62900E3484E /* PBXTargetDependency */, - E7CFF6731C84F62900E3484E /* PBXTargetDependency */, - EBFBC2B01E76582C00A34469 /* PBXTargetDependency */, ); name = Security_KeychainCircle; productName = Security_KeychainCircle; }; - EB6A6FA81B90F83A0045DC68 /* phase1_ios */ = { - isa = PBXAggregateTarget; - buildConfigurationList = EB6A6FA91B90F83A0045DC68 /* Build configuration list for PBXAggregateTarget "phase1_ios" */; - buildPhases = ( - ); - dependencies = ( - EB6A6FAD1B90F84D0045DC68 /* PBXTargetDependency */, - ); - name = phase1_ios; - productName = phase1_ios; - }; EB6A6FAE1B90F8810045DC68 /* Security_executables_bridge */ = { isa = PBXAggregateTarget; buildConfigurationList = EB6A6FAF1B90F8810045DC68 /* Build configuration list for PBXAggregateTarget "Security_executables_bridge" */; @@ -504,21 +717,20 @@ dependencies = ( 47455B24205B3E2F008FE980 /* PBXTargetDependency */, D41257F71E941E9600781F23 /* PBXTargetDependency */, - DAE40BD520CF3ED5002D5674 /* PBXTargetDependency */, ); name = Security_executables_bridge; productName = Security_executables_Bridge; }; - EB6A6FB41B90F8C90045DC68 /* phase2 */ = { + EB7E90F12193F90700B1FA21 /* Build C2 Metrics */ = { isa = PBXAggregateTarget; - buildConfigurationList = EB6A6FB51B90F8C90045DC68 /* Build configuration list for PBXAggregateTarget "phase2" */; + buildConfigurationList = EB7E90F22193F90800B1FA21 /* Build configuration list for PBXAggregateTarget "Build C2 Metrics" */; buildPhases = ( + EB7E90F52193F91200B1FA21 /* ShellScript */, ); dependencies = ( - EB6A6FB91B90F8D70045DC68 /* PBXTargetDependency */, ); - name = phase2; - productName = phase2; + name = "Build C2 Metrics"; + productName = "Build C2 Metrics"; }; EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */ = { isa = PBXAggregateTarget; @@ -526,65 +738,57 @@ buildPhases = ( EB9C1DB41BDFD4F200F89272 /* Install BATS plist */, EBC15E801BE29A8C001C0C5B /* Chown BATS plist */, + EBA12514225E55C200138070 /* Check for SYSTEM_FRAMEWORK_SEARCH_PATHS */, ); dependencies = ( EBCF743F1CE593A700BED7CA /* PBXTargetDependency */, EB433A2C1CC3252A00A7EACE /* PBXTargetDependency */, EBA9AA891CE3E76C004E2B68 /* PBXTargetDependency */, EB3A8E011BEEC6F3001A89AA /* PBXTargetDependency */, - EB63ADE11C3E74F900C45A69 /* PBXTargetDependency */, EB425CD11C6585F1000ECE53 /* PBXTargetDependency */, + EB63ADE11C3E74F900C45A69 /* PBXTargetDependency */, ); name = SecurityBatsTests; productName = SecurityBatsTests; }; - F93C49021AB8FCE00047E01A /* ckcdiagnose.sh */ = { - isa = PBXAggregateTarget; - buildConfigurationList = F93C49031AB8FCE00047E01A /* Build configuration list for PBXAggregateTarget "ckcdiagnose.sh" */; - buildPhases = ( - F93C49061AB8FCE50047E01A /* CopyFiles */, - ); - dependencies = ( - ); - name = ckcdiagnose.sh; - productName = ckcdiagnose.sh; - }; /* 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 */; }; 0940F6F82151316500C06F18 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; 0940F6F92151316600C06F18 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; 096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 09BFE35A20A32E0E008511E9 /* KeychainEntitlementsTest.m */; }; - 09A3B9D81F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 09A3B9D91F8267BB00C5C324 /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 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 */; }; 09EF431B21A5A8CC0066CF20 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; - 0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; - 0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C00FC86217A980100C8BF00 /* OTLocalCuttlefishReset.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C00FC81217A971800C8BF00 /* OTLocalCuttlefishReset.m */; }; + 0C0582C620D9CA4800D7BD7A /* OTClique.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDBCD8620AD03FB007F8EA7 /* OTClique.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 0C0582CC20D9CA4900D7BD7A /* OTClique.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CDBCD8620AD03FB007F8EA7 /* OTClique.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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 */; }; 0C0BDB8F1756A6D500BC1A7E /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; 0C0BDB911756A8A400BC1A7E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; 0C0BDB931756A8C900BC1A7E /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; - 0C0C88781CCEC5C400617D1B /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */; }; - 0C0C88791CCEC5C500617D1B /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */; }; + 0C0C4F86216FB73C00C14C61 /* EscrowKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0C4F83216FB55600C14C61 /* EscrowKeys.swift */; }; + 0C0C4F87216FB73F00C14C61 /* BottledPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0C4F84216FB56B00C14C61 /* BottledPeer.swift */; }; 0C0CECA41DA45ED700C22FBC /* recovery_key.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0CEC9E1DA45EA200C22FBC /* recovery_key.m */; }; 0C0DA5CE1FE1EAB9003BD3BB /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; 0C0DA5CF1FE1F1C5003BD3BB /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; 0C0DA5D01FE1F1F3003BD3BB /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + 0C0E60DA20D033E400E654F2 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; + 0C0E60E020D033E400E654F2 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; + 0C101F942053528700387951 /* OTBottledPeerState.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C101F932053528700387951 /* OTBottledPeerState.m */; }; + 0C12B1F12138D31600BE0A98 /* OTClientStateMachine.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C12B1F02138D31600BE0A98 /* OTClientStateMachine.m */; }; 0C16371C1FD116B300210823 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; 0C1637211FD12F1500210823 /* OTCloudStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */; }; 0C1637271FD2065400210823 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; 0C1637291FD2066A00210823 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; 0C16372B1FD2067F00210823 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; 0C16372D1FD2069300210823 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; - 0C1637301FD206BC00210823 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + 0C1637301FD206BC00210823 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + 0C1B8BB72233244F0094D5DA /* OTVouchWithRecoveryKeyOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C1B8BB52233241E0094D5DA /* OTVouchWithRecoveryKeyOperation.m */; }; + 0C24D693204F56E900926E5F /* OTBottledPeerUpdateBottlesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C24D692204F56E900926E5F /* OTBottledPeerUpdateBottlesTests.m */; }; 0C2BCBAF1D06401F00ED7A2F /* ioSock.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5A65809C79E0600D27A3F /* ioSock.c */; }; 0C2BCBB01D06401F00ED7A2F /* sslAppUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CE5A65A09C79E0600D27A3F /* sslAppUtils.cpp */; }; 0C2BCBB41D06401F00ED7A2F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; @@ -595,34 +799,69 @@ 0C2BCBC91D0648D100ED7A2F /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; 0C2BCBCA1D0648D100ED7A2F /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; 0C2BCBCF1D0648EF00ED7A2F /* dtlsEchoServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 0C2BCBA61D063F7D00ED7A2F /* dtlsEchoServer.c */; }; - 0C36B3212007F2550029F7A2 /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; }; - 0C36B3222007F2570029F7A2 /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; }; + 0C2F337220DD64930031A92D /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F337120DD647D0031A92D /* OTRamping.m */; }; + 0C2F337320DD64940031A92D /* OTRamping.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F337120DD647D0031A92D /* OTRamping.m */; }; + 0C38AA92212B2D1900C90A1D /* OTEpochOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C4F4DE121153659007F7E20 /* OTEpochOperation.h */; }; + 0C38AA96212B2D1E00C90A1D /* OTClientVoucherOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CC8A9002123AA3B005D7F6A /* OTClientVoucherOperation.h */; }; + 0C38AA98212B2D2300C90A1D /* OTJoinWithVoucherOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CC8A9052123AF16005D7F6A /* OTJoinWithVoucherOperation.h */; }; + 0C3BB3582188E18C0018FC14 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3BB3522188E18A0018FC14 /* OTPrivateKey+SF.m */; }; + 0C3BB35A2188E18C0018FC14 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3BB3542188E18B0018FC14 /* OTAuthenticatedCiphertext+SF.m */; }; 0C3C00731EF3636500AB19FE /* secd-155-otr-negotiation-monitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3C00721EF3636300AB19FE /* secd-155-otr-negotiation-monitor.m */; }; + 0C3E316B21372FA50093C04B /* OctagonPairingTests+ProximitySetup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C6604812134DD5D00BFBBB8 /* OctagonPairingTests+ProximitySetup.swift */; }; 0C46A5712034C6BA00F17112 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; 0C46A57B2035019800F17112 /* OTLockStateNetworkingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */; }; 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 */; }; - 0C52C1FF20003BCA003F0733 /* OTTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */; }; + 0C48B371202E3ED800A0E1AA /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; }; + 0C48B377202E3EE700A0E1AA /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; }; + 0C48B380202E438100A0E1AA /* CloudKitKeychainSyncingMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */; }; + 0C4C547620E1A0B400BA61BA /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C4C548020E1A53D00BA61BA /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C4CDE6F22922E550050C499 /* OctagonTests+RecoveryKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C4CDE6D22922E360050C499 /* OctagonTests+RecoveryKey.swift */; }; + 0C4D96A621F24E5700617E60 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C4D96A721F25F2C00617E60 /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C4F4DE221153E9E007F7E20 /* OTEpochOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C4F4DDA211535E8007F7E20 /* OTEpochOperation.m */; }; + 0C5258BA21BB062F00B32C96 /* FakeSOSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5258B821BB05C100B32C96 /* FakeSOSControl.m */; }; + 0C5258BB21BB128000B32C96 /* FakeSOSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C5258B821BB05C100B32C96 /* FakeSOSControl.m */; }; + 0C5258BD21BB137900B32C96 /* FakeSOSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C5258BC21BB137800B32C96 /* FakeSOSControl.h */; }; 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; 0C5663EF20BE2E220035F362 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 0C5824A52286002D009E8C15 /* OctagonTests+HealthCheck.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C5824A322860001009E8C15 /* OctagonTests+HealthCheck.swift */; }; 0C5960641FB2E2070095BA29 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; settings = {ATTRIBUTES = (Weak, ); }; }; 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 */; }; + 0C5A8C1D200A9B0C004C771D /* OTPreflightInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */; }; + 0C61F1F62194FC79009566D4 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3BB3522188E18A0018FC14 /* OTPrivateKey+SF.m */; }; + 0C61F1F92194FC82009566D4 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3BB3542188E18B0018FC14 /* OTAuthenticatedCiphertext+SF.m */; }; + 0C66046A2134983900BFBBB8 /* OTEstablishOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C6604692134983900BFBBB8 /* OTEstablishOperation.m */; }; + 0C66047E2134CA5600BFBBB8 /* OTDeviceInformation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C66047B2134C88C00BFBBB8 /* OTDeviceInformation.m */; }; + 0C6C0FCB21F1415B00CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C6C0FCF21F1457600CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C6C0FD021F145F600CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C6C0FD121F1465500CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C6C0FD221F146E700CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C6C0FD321F1494C00CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + 0C6C0FD621F14D3900CD5B9E /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; 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 */; }; + 0C78826F20132069002B7475 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.m */; }; + 0C78827520132074002B7475 /* SFSignInAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 0CF0E2E71F8EE40700BD18E4 /* SFSignInAnalytics.h */; }; 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, ); }; }; 0C78F1CF16A5E1BF00654E08 /* sectask_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = 0C78F1CB16A5E1BF00654E08 /* sectask_ipc.defs */; settings = {ATTRIBUTES = (Client, Server, ); }; }; 0C78F1D016A5E3EB00654E08 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; - 0C85DFE71FB38BB6000343A7 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; - 0C85DFE81FB38BB6000343A7 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; + 0C7A8BBF21714CDC00F4C480 /* OTJoiningConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8FD549214AECD70098E3FB /* OTJoiningConfiguration.m */; }; + 0C7A8BC021714D0E00F4C480 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0C84D8341FCF43AF00B822E3 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C84D8351FCF43BB00B822E3 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C84D8371FCF43BF00B822E3 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C84D8381FCF43BF00B822E3 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; + 0C84D8391FCF43CA00B822E3 /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; }; + 0C84D83B1FCF443A00B822E3 /* otctl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBEF71FCB405700580909 /* otctl.m */; }; + 0C84D83C1FCF448200B822E3 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; }; + 0C84D83D1FCF449700B822E3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + 0C85DFE71FB38BB6000343A7 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; 0C85DFE91FB38BB6000343A7 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; 0C85DFEA1FB38BB6000343A7 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; 0C85DFEB1FB38BB6000343A7 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; @@ -641,51 +880,30 @@ 0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; 0C85DFFB1FB38BB6000343A7 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; 0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 0C87D3D9229326AA007853B5 /* OTEnsureOctagonKeyConsistency.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C87D3D6229326A2007853B5 /* OTEnsureOctagonKeyConsistency.m */; }; + 0C87D3E4229368BD007853B5 /* OctagonTests+SOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C87D3E2229368A7007853B5 /* OctagonTests+SOS.swift */; }; + 0C8884012154C4E80053224D /* OTJoiningConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8FD549214AECD70098E3FB /* OTJoiningConfiguration.m */; }; + 0C8884042154C4EA0053224D /* OTJoiningConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8FD549214AECD70098E3FB /* OTJoiningConfiguration.m */; }; 0C8A03461FDF42BA0042E8BE /* OTEscrowKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */; }; 0C8A034D1FDF4CCE0042E8BE /* OTLocalStoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */; }; 0C8A034F1FDF60070042E8BE /* OTBottledPeerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */; }; 0C8BBE9F1FC9DBA400580909 /* OTBottledPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */; }; - 0C8BBEA01FC9DBA400580909 /* OTBottledPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */; }; - 0C8BBEA21FC9DBAA00580909 /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; }; 0C8BBEA51FC9DBB100580909 /* OTEscrowKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */; }; - 0C8BBEA61FC9DBB200580909 /* OTEscrowKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */; }; - 0C8BBEA71FC9DBB500580909 /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; }; - 0C8BBEA81FC9DBB600580909 /* OTIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */; }; 0C8BBEA91FC9DBBF00580909 /* OTLocalStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */; }; - 0C8BBEAA1FC9DBC000580909 /* OTLocalStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */; }; - 0C8BBEE61FCA6E0500580909 /* OTContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBE981FC9DA5A00580909 /* OTContext.m */; }; - 0C8BBEFF1FCB446400580909 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; }; - 0C8BBF031FCB446400580909 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; - 0C8BBF091FCB447600580909 /* otctl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBEF71FCB405700580909 /* otctl.m */; }; - 0C8BBF111FCB4AAA00580909 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; - 0C8BBF121FCB4AAB00580909 /* OTControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0E1FCB452400580909 /* OTControl.m */; }; - 0C8BBF131FCB4AFA00580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; - 0C8BBF141FCB4AFB00580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; - 0C8BBF151FCB4B1B00580909 /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; }; - 0C8BBF161FCB4B1C00580909 /* OTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0F1FCB481800580909 /* OTManager.m */; }; - 0C8BBF171FCB4E5000580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; - 0C8BBF181FCB4E5000580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; - 0C8BBF1B1FCB4EC500580909 /* OTControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */; }; - 0C8BBF1C1FCB4F0300580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; }; - 0C8BBF1D1FCB4F0300580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; - 0C8BBF1E1FCB4F0400580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; }; - 0C8BBF1F1FCB4F0400580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; - 0C8BBF201FCB4F1800580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 0C8BBF211FCB4F1800580909 /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; }; - 0C8BBF221FCB4F1800580909 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 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 */; }; + 0C8FD52521483EF20098E3FB /* OT.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCCC7C820261D310024405E /* OT.m */; }; + 0C98122821ACCC9300784441 /* OTClique.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F336A20DD643B0031A92D /* OTClique.m */; }; 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 */; }; + 0CA2282F2187A5CA00A1C56C /* BottledPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0C4F84216FB56B00C14C61 /* BottledPeer.swift */; }; + 0CA4B4722171410200B17169 /* EscrowKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0C4F83216FB55600C14C61 /* EscrowKeys.swift */; }; 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, ); }; }; 0CA4EC11202BB5E9002B1D96 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 0CA7020A2280D5BD0085AC54 /* OTCheckHealthOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA702082280D5600085AC54 /* OTCheckHealthOperation.m */; }; 0CAC5DBF1EB3DA4C00AD884B /* SOSPeerRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */; }; 0CAD1E1C1E032ADB00537693 /* SOSCloudCircleServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CAA1D8085D800865A7C /* SOSCloudCircleServer.m */; }; 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; }; @@ -693,46 +911,112 @@ 0CAD1E5A1E1C5CD100537693 /* secd-71-engine-save.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C641D8085D800865A7C /* secd-71-engine-save.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 */; }; + 0CADDF0721545CF100DF8B06 /* OctagonPairingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CADDF0421545C8E00DF8B06 /* OctagonPairingTests.swift */; }; 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 */; }; + 0CB582C82189157F0040C5F2 /* OTAuthenticatedCiphertext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C5218915390040C5F2 /* OTAuthenticatedCiphertext.m */; }; + 0CB582C92189157F0040C5F2 /* OTBottle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C4218915390040C5F2 /* OTBottle.m */; }; + 0CB582CA2189157F0040C5F2 /* OTBottleContents.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C62189153A0040C5F2 /* OTBottleContents.m */; }; + 0CB582CB2189157F0040C5F2 /* OTPrivateKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C3218915390040C5F2 /* OTPrivateKey.m */; }; + 0CB582D021891FF40040C5F2 /* OTBottle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C4218915390040C5F2 /* OTBottle.m */; }; + 0CB582D1218920090040C5F2 /* OTAuthenticatedCiphertext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C5218915390040C5F2 /* OTAuthenticatedCiphertext.m */; }; + 0CB582D2218920090040C5F2 /* OTBottleContents.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C62189153A0040C5F2 /* OTBottleContents.m */; }; + 0CB582D3218920090040C5F2 /* OTPrivateKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C3218915390040C5F2 /* OTPrivateKey.m */; }; + 0CB5C677218B803C0044F730 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3BB3542188E18B0018FC14 /* OTAuthenticatedCiphertext+SF.m */; }; + 0CB5C678218B803C0044F730 /* OTPrivateKey+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C3BB3522188E18A0018FC14 /* OTPrivateKey+SF.m */; }; + 0CB72D9D21E42FCF00D8BC9B /* OTApplicantToSponsorRound2M1.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C9AE28E214054F6003BFDB5 /* OTApplicantToSponsorRound2M1.m */; }; + 0CB72D9E21E42FCF00D8BC9B /* OTPairingMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C9AE2A2214055CF003BFDB5 /* OTPairingMessage.m */; }; + 0CB72D9F21E42FCF00D8BC9B /* OTSOSMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE9C98A21B8891A006BDD80 /* OTSOSMessage.m */; }; + 0CB72DA021E42FCF00D8BC9B /* OTSponsorToApplicantRound1M2.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C9AE28D214054F6003BFDB5 /* OTSponsorToApplicantRound1M2.m */; }; + 0CB72DA121E42FCF00D8BC9B /* OTSponsorToApplicantRound2M2.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C9AE290214054F7003BFDB5 /* OTSponsorToApplicantRound2M2.m */; }; + 0CB8DC9A2194B14C0021A7C8 /* OTVouchWithBottleOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB8DC992194B1440021A7C8 /* OTVouchWithBottleOperation.m */; }; 0CB9754F2023A8F5008D6B48 /* CloudKitMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC222CA71E08A7D900B09171 /* CloudKitMockXCTest.m */; }; 0CB975512023B199008D6B48 /* OTRampingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB975502023B199008D6B48 /* OTRampingTests.m */; }; + 0CBA047D214C4E4D005B3A2F /* OctagonPairingTests+ProxMultiClients.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBA047C214C4E4D005B3A2F /* OctagonPairingTests+ProxMultiClients.swift */; }; 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 */; }; + 0CBEF3432242CA0600015691 /* TestsObjcTranslation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CBEF3412242C9AE00015691 /* TestsObjcTranslation.m */; }; 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 */; }; + 0CC593F02299B9AA006C34B5 /* SecInternalRelease.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC761D8C68CF00070CB0 /* SecInternalRelease.c */; }; + 0CC593F62299EC3D006C34B5 /* OTDeviceInformationAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC19484B21812EC5007C2260 /* OTDeviceInformationAdapter.m */; }; + 0CC593F92299EE06006C34B5 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + 0CC8A8FE2123A9F6005D7F6A /* OTClientVoucherOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CC8A8FA2123A9EB005D7F6A /* OTClientVoucherOperation.m */; }; + 0CC8A9032123AF06005D7F6A /* OTJoinWithVoucherOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CC8A9012123AEF7005D7F6A /* OTJoinWithVoucherOperation.m */; }; 0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CCDE7161EEB08220021A946 /* secd-156-timers.m */; }; + 0CD3D519224048A800024755 /* OTSetRecoveryKeyOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD3D5152240479600024755 /* OTSetRecoveryKeyOperation.m */; }; + 0CD5797A21498F8200C43496 /* OctagonPairingTests+Piggybacking.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD5797721498F7700C43496 /* OctagonPairingTests+Piggybacking.swift */; }; 0CD8CB051ECA50780076F37F /* SOSPeerOTRTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */; }; 0CD8CB0B1ECA50920076F37F /* SOSPeerOTRTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD8CB041ECA50780076F37F /* SOSPeerOTRTimer.m */; }; 0CD9E8001FE05B6600F66C38 /* OTContextRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */; }; - 0CD9E8011FE05B6600F66C38 /* OTContextRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */; }; + 0CDD6F79226E83F6009094C2 /* OTTriggerEscrowUpdateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CDD6F76226E62AD009094C2 /* OTTriggerEscrowUpdateOperation.m */; }; + 0CE079F41FEA15B20040A3F1 /* SFBehavior.m in Sources */ = {isa = PBXBuildFile; fileRef = EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */; }; + 0CE15E2C222DF63600B7EAA4 /* RecoveryKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2A222DF63500B7EAA4 /* RecoveryKey.swift */; }; + 0CE15E2D222DF63600B7EAA4 /* RecoveryKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2A222DF63500B7EAA4 /* RecoveryKey.swift */; }; + 0CE15E2F222DF63600B7EAA4 /* RecoveryKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2A222DF63500B7EAA4 /* RecoveryKey.swift */; }; + 0CE15E2F222DF63600B7EAA5 /* SetValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2A222DF63500B7EAA5 /* SetValueTransformer.swift */; }; + 0CE15E30222DF63600B7EAA4 /* RecoverKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2B222DF63600B7EAA4 /* RecoverKeySet.swift */; }; + 0CE15E31222DF63600B7EAA4 /* RecoverKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2B222DF63600B7EAA4 /* RecoverKeySet.swift */; }; + 0CE15E33222DF63600B7EAA4 /* RecoverKeySet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2B222DF63600B7EAA4 /* RecoverKeySet.swift */; }; + 0CE15E39222DF67800B7EAA4 /* OTRecovery.proto in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E34222DF66D00B7EAA4 /* OTRecovery.proto */; }; + 0CE15E3E222DF6A800B7EAA4 /* OTRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E3A222DF6A600B7EAA4 /* OTRecovery.m */; }; + 0CE15E3F222DF6A800B7EAA4 /* OTRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E3A222DF6A600B7EAA4 /* OTRecovery.m */; }; + 0CE15E41222DF6A800B7EAA4 /* OTRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E3A222DF6A600B7EAA4 /* OTRecovery.m */; }; + 0CE15E43222DF6A800B7EAA4 /* Recovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E3C222DF6A700B7EAA4 /* Recovery.m */; }; + 0CE15E44222DF6A800B7EAA4 /* Recovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E3C222DF6A700B7EAA4 /* Recovery.m */; }; + 0CE15E46222DF6A800B7EAA4 /* Recovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E3C222DF6A700B7EAA4 /* Recovery.m */; }; 0CE1BCCE1FCE11680017230E /* OTBottledPeerSigned.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */; }; - 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 */; }; - 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 */; }; + 0CE751AF20ACC497002B2832 /* SFSignInAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF0E2E31F8EE3B000BD18E4 /* SFSignInAnalytics.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 */; }; + 0CE780A321421C730049340E /* libcompression.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EB067E8A20EC873D00B7D961 /* libcompression.tbd */; }; + 0CE780AF2142F1350049340E /* KeychainCircle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D847C51C6BE9710025BB44 /* KeychainCircle.framework */; }; + 0CE887D22299A8CF0082D120 /* libMobileGestalt.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BE53602C209BBF2F0027E25A /* libMobileGestalt.tbd */; }; + 0CE887D32299A9090082D120 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 0CE887D52299A9C70082D120 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF405F42072E2BF003D6A7F /* SFSignInAnalyticsTests.m */; }; + 0CF70BD9218BED1000EC3515 /* CuttlefishExtensionWorkaround.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CF70BD6218BECF500EC3515 /* CuttlefishExtensionWorkaround.swift */; }; + 0CF70BDA218BEFAE00EC3515 /* CuttlefishExtensionWorkaround.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CF70BD6218BECF500EC3515 /* CuttlefishExtensionWorkaround.swift */; }; + 0CF70BDB218BEFF000EC3515 /* CuttlefishExtensionWorkaround.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CF70BD6218BECF500EC3515 /* CuttlefishExtensionWorkaround.swift */; }; + 0CF70BE0218CF26600EC3515 /* BottledPeer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0C4F84216FB56B00C14C61 /* BottledPeer.swift */; }; + 0CF70BE1218CF27600EC3515 /* EscrowKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0C4F83216FB55600C14C61 /* EscrowKeys.swift */; }; + 0CF70BE2218CF2AA00EC3515 /* OTAuthenticatedCiphertext.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C5218915390040C5F2 /* OTAuthenticatedCiphertext.m */; }; + 0CF70BE3218CF2AA00EC3515 /* OTBottle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C4218915390040C5F2 /* OTBottle.m */; }; + 0CF70BE4218CF2AA00EC3515 /* OTBottleContents.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C62189153A0040C5F2 /* OTBottleContents.m */; }; + 0CF70BE5218CF2AA00EC3515 /* OTPrivateKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582C3218915390040C5F2 /* OTPrivateKey.m */; }; + 0CF74E4120DDD5290014A5DB /* OTTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F337720DD64C20031A92D /* OTTestsBase.m */; }; + 0CF74E4720DDD5390014A5DB /* OTCliqueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F337520DD64C10031A92D /* OTCliqueTests.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, ); }; }; 18F7F67914D77F4400F88A12 /* NtlmGenerator.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C999BA10AB5F0BB0010451D /* NtlmGenerator.c */; }; 18F7F67A14D77F4400F88A12 /* ntlmBlobPriv.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C999BA30AB5F0BB0010451D /* ntlmBlobPriv.c */; }; + 1B4AE38722400A22002188E1 /* TPDictionaryMatchingRules.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8846802237431400738068 /* TPDictionaryMatchingRules.m */; }; + 1B4C444B223AE65500C6F97F /* TPPBPolicyKeyViewMapping.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B4C4448223AE65400C6F97F /* TPPBPolicyKeyViewMapping.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 1B4C444C223AE65500C6F97F /* TPPBPolicyKeyViewMapping.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B4C444A223AE65400C6F97F /* TPPBPolicyKeyViewMapping.m */; }; + 1B5EAADC2252ABCD008D27E7 /* OTFetchViewsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 1B5EAAD92252ABCC008D27E7 /* OTFetchViewsOperation.h */; }; + 1B5EAADD2252ABCD008D27E7 /* OTFetchViewsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B5EAADB2252ABCC008D27E7 /* OTFetchViewsOperation.m */; }; + 1B8341B92239AD3A002BF18A /* TPPBPolicyKeyViewMapping.proto in Sources */ = {isa = PBXBuildFile; fileRef = 1B8341B72239AD39002BF18A /* TPPBPolicyKeyViewMapping.proto */; }; + 1B8D2D96226E1FA500C94238 /* SetValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2A222DF63500B7EAA5 /* SetValueTransformer.swift */; }; + 1B916CCE223FFED7006657FD /* libprotobuf_source_generation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCF216D721ADD5B10029CCC1 /* libprotobuf_source_generation.a */; }; + 1B916CD0223FFF25006657FD /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; }; + 1B995259226681FA00A2D6CD /* PolicyReporter.h in Sources */ = {isa = PBXBuildFile; fileRef = 1B995256226681ED00A2D6CD /* PolicyReporter.h */; }; + 1B99525A226681FA00A2D6CD /* PolicyReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B995258226681EE00A2D6CD /* PolicyReporter.m */; }; + 1BC6F79C21C9955F005ED67A /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 1BC6F79821C9955E005ED67A /* util.h */; }; + 1BDEBEF92252DEB1009AD3D6 /* policy_dryrun.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BDEBEF72252DEB1009AD3D6 /* policy_dryrun.m */; }; + 1BDEBEFD2253E6D9009AD3D6 /* policy_dryrun.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BDEBEF72252DEB1009AD3D6 /* policy_dryrun.m */; }; + 1BF640EF222EEB6C002D0FCB /* TPPolicyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BF640EE222EEB6C002D0FCB /* TPPolicyTests.m */; }; + 1F631C5422387F27005920D8 /* legacydevid.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F631C5222387F27005920D8 /* legacydevid.h */; }; + 1F631C5622387FFE005920D8 /* legacydevid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F631C5122387F27005920D8 /* legacydevid.cpp */; }; + 1F631C5722388022005920D8 /* legacydevid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1F631C5122387F27005920D8 /* legacydevid.cpp */; }; 220179E31E3BEB7100EFB6F3 /* dirscanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067FD1D8CDF7E007602F1 /* dirscanner.cpp */; }; 220179E91E3BF03200EFB6F3 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC1789A41D779E3B00B50D50 /* dummy.cpp */; }; 220179EA1E3BF16000EFB6F3 /* slcrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067DB1D8CDF7E007602F1 /* slcrep.cpp */; }; @@ -781,6 +1065,12 @@ 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 */; }; + 3D55EA832242F50B008E7459 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + 3D58394F21891061000ACA44 /* SecExperimentTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D7AA28E2187AD0000F1575C /* SecExperimentTests.m */; }; + 3D680BE42241BC0000C04821 /* SecExperiment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD852B02177FF72009E705D /* SecExperiment.m */; }; + 3D680BE72241C16E00C04821 /* SecExperiment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD852B02177FF72009E705D /* SecExperiment.m */; }; + 3D909E372195042C00205F8C /* SecExperimentPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DA3384421658AA8008C0CE1 /* SecExperimentPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 3D909E382195042C00205F8C /* SecExperimentPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DA3384421658AA8008C0CE1 /* SecExperimentPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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 */; }; @@ -825,9 +1115,13 @@ 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 */; }; + 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in Copy Plist */ = {isa = PBXBuildFile; fileRef = 3DD1FE86201AA5120086D049 /* SecureTransport_iosTests.plist */; }; 3DD1FFD7201FF7B10086D049 /* SecureTransport_macosTests.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = 3DD1FE79201AA50D0086D049 /* SecureTransport_macosTests.plist */; }; + 3DD2589F20478CF900F5DA78 /* STLegacyTests+session.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD2589820478CCE00F5DA78 /* STLegacyTests+session.m */; }; + 3DD258A020478CFA00F5DA78 /* STLegacyTests+session.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD2589820478CCE00F5DA78 /* STLegacyTests+session.m */; }; + 3DD258AC2051F10300F5DA78 /* STLegacyTests+sni.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD1FE7F201AA50F0086D049 /* STLegacyTests+sni.m */; }; + 3DD852B12177FF72009E705D /* SecExperiment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD852B02177FF72009E705D /* SecExperiment.m */; }; + 3DE8F6C121829EFF006041DA /* SecExperiment.m in Sources */ = {isa = PBXBuildFile; fileRef = 3DD852B02177FF72009E705D /* SecExperiment.m */; }; 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 */; }; @@ -851,8 +1145,6 @@ 4432AF8B1A014664000958DC /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; 4432AF8D1A01472C000958DC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; 4432B0B71A014987000958DC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; - 4432B15E1A014D37000958DC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; - 4432B15F1A014D55000958DC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; 4432B1601A014D85000958DC /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; 4432B1611A014D85000958DC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; 4432B1621A014D8F000958DC /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; @@ -867,15 +1159,13 @@ 44A655A61AA4B4C80059D185 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; }; 470415DC1E5E1534001F3D95 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 470415DB1E5E1534001F3D95 /* main.m */; }; 470D96711FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; }; - 470D96721FCDE55B0065FE90 /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; }; 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 */; }; + 4718AE14205B39620068EC3F /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; 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 */; }; @@ -883,28 +1173,20 @@ 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 */; }; + 4718AE27205B39620068EC3F /* com.apple.securityd.plist in Launchd plists */ = {isa = PBXBuildFile; fileRef = DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */; }; + 4718AE29205B39620068EC3F /* com.apple.securityd.plist in Copy Logging Files */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; 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 */; }; + 4718AE37205B39C40068EC3F /* CKKSAccountStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFB12C41E95A4C000510F5F /* CKKSAccountStateTracker.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 */; }; @@ -916,7 +1198,6 @@ 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 */; }; @@ -955,7 +1236,6 @@ 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 */; }; @@ -974,26 +1254,23 @@ 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 */; }; + 4718AE87205B39C40068EC3F /* CKKSTLKShareRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShareRecord.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 */; }; + 4718AE8C205B39C40068EC3F /* OctagonAPSReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D841E2F14810089CF55 /* OctagonAPSReceiver.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 */; }; @@ -1020,16 +1297,14 @@ 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 */; }; + 4718AEB8205B39C40068EC3F /* CKKSAccountStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFB12C31E95A4C000510F5F /* CKKSAccountStateTracker.h */; }; 4718AEB9205B39C40068EC3F /* CKKSZoneStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B361DEFADB500A3DAFA /* CKKSZoneStateEntry.h */; }; - 4718AEBA205B39C40068EC3F /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */; }; + 4718AEBA205B39C40068EC3F /* CKKSTLKShareRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShareRecord.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 */; }; @@ -1047,8 +1322,7 @@ 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 */; }; + 4718AED3205B39C40068EC3F /* OctagonAPSReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D831E2F14810089CF55 /* OctagonAPSReceiver.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 */; }; @@ -1058,10 +1332,8 @@ 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 */; }; 4723C9C21F152EB50082882F /* SFObjCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C01F152EB10082882F /* SFObjCType.h */; }; 4723C9C31F152EB60082882F /* SFObjCType.h in Headers */ = {isa = PBXBuildFile; fileRef = 4723C9C01F152EB10082882F /* SFObjCType.h */; }; @@ -1094,12 +1366,9 @@ 4727FBEC1F99235B0003AE36 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; 4727FBED1F99249A0003AE36 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; 4727FBEE1F9924DA0003AE36 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; - 4727FBEF1F9924FB0003AE36 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + 4727FBEF1F9924FB0003AE36 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; 473337791FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */; }; - 4733377A1FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */; }; 4733377B1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; - 4733377C1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; - 473337841FDB29C400E19F30 /* KeychainCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337831FDB29A200E19F30 /* KeychainCheck.m */; }; 474B5FC61E662E48007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; 474B5FC71E662E67007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; 474B5FC81E662E79007546F8 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; @@ -1128,18 +1397,19 @@ 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 */; }; 477A1FE4203763A500ACD81D /* KeychainAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FE1203763A500ACD81D /* KeychainAPITests.m */; }; 477A1FE5203763A500ACD81D /* KeychainAPITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FE1203763A500ACD81D /* KeychainAPITests.m */; }; 477A1FED2037A0E000ACD81D /* KeychainXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */; }; 477A1FEE2037A0E000ACD81D /* KeychainXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */; }; + 478014541FBF577000C4043D /* si-44-seckey-proxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */; }; + 4780146A1FBF5BD600C4043D /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; }; + 478014701FBF5BD800C4043D /* SecKeyProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */; }; + 478014791FBF5D2000C4043D /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4780147F1FBF5D2100C4043D /* SecKeyProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 09A3B9D71F8267BB00C5C324 /* SecKeyProxy.h */; settings = {ATTRIBUTES = (Private, ); }; }; 478D42761FD72A8100CAB645 /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; - 478D42771FD72A8100CAB645 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + 478D42771FD72A8100CAB645 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; 478D42781FD72A8100CAB645 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; 478D42791FD72A8100CAB645 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; 478D427A1FD72A8100CAB645 /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; @@ -1170,32 +1440,22 @@ 478D429E1FD72C4800CAB645 /* CrashReporterSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E9391D7F3DF200AFB96E /* CrashReporterSupport.framework */; }; 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 */; }; - 47922D211FAA76000008F7E0 /* SecDbKeychainSerializedMetadata.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */; }; - 47922D2D1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */; }; + 4791B4652118BBFF00977C3F /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4791B46B2118BC0000977C3F /* OTControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4791B46C2118BD0A00977C3F /* SecXPCError.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC6F1D8C68CF00070CB0 /* SecXPCError.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 4791B46D2118BD0B00977C3F /* SecXPCError.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC6F1D8C68CF00070CB0 /* SecXPCError.h */; settings = {ATTRIBUTES = (Private, ); }; }; 47922D421FAA7C240008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; }; - 47922D431FAA7C260008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */; }; - 47922D441FAA7C2C0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; - 47922D451FAA7C2E0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; 47922D461FAA7C340008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */; }; - 47922D471FAA7C350008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */; }; 47922D481FAA7C3C0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; - 47922D491FAA7C3D0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; 47922D4A1FAA7C430008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */; }; - 47922D4B1FAA7C440008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */; }; 47922D4C1FAA7C4A0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; - 47922D4D1FAA7C4B0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; - 47922D4F1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto in Resources */ = {isa = PBXBuildFile; fileRef = 47922D4E1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto */; }; 47922D541FAA7E060008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */ = {isa = PBXBuildFile; fileRef = 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */; }; - 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 */; }; @@ -1206,7 +1466,7 @@ 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 */; }; + 47C51B871EEA657D0032D9E5 /* SecKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 47C51B861EEA657D0032D9E5 /* SecKeyTests.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 */; }; @@ -1214,12 +1474,24 @@ 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 */; }; + 480ADDB22155A0CE00318FC6 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; + 480C03DB2145A8490034570E /* SOSTrustedDeviceAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 480C03D321459CD60034570E /* SOSTrustedDeviceAttributes.m */; }; + 480C03DC2145A84F0034570E /* SOSTrustedDeviceAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 480C03D621459CD70034570E /* SOSTrustedDeviceAttributes.h */; }; + 482FE5602177C5DA0031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE5632177C5E80031C11E /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; + 482FE5642177C6850031C11E /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; + 482FE5652177C6D90031C11E /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; + 482FE5662177C6E40031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE5672177C7260031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE5682177C73C0031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE5692177C7670031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE56A2177C7980031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE56C2177CEEF0031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE56D2177CF150031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + 482FE56E2177CF340031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 482FE56B2177C7AE0031C11E /* AuthKit.framework */; }; + 482FE56F2177CF520031C11E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; 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 */; }; @@ -1411,9 +1683,6 @@ 522B280E1E64B4BF002B5638 /* secd-230-keybagtable.m in Sources */ = {isa = PBXBuildFile; fileRef = 522B28081E64B48E002B5638 /* secd-230-keybagtable.m */; }; 524492941AFD6D480043695A /* der_plist.h in Headers */ = {isa = PBXBuildFile; fileRef = 524492931AFD6D480043695A /* der_plist.h */; settings = {ATTRIBUTES = (Private, ); }; }; 5269658D1E6A154700627F9D /* SecBackupKeybagEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 52AA92881E662A4A004301A6 /* SecBackupKeybagEntry.m */; }; - 5269658E1E6A154800627F9D /* SecBackupKeybagEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 52AA92881E662A4A004301A6 /* SecBackupKeybagEntry.m */; }; - 526965D21E6E284400627F9D /* AsymKeybagBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */; }; - 526965D31E6E284500627F9D /* AsymKeybagBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */; }; 5296CB4E1655B8F5009912AF /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; 5296CB4F1655B92F009912AF /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; 5296CB501655B990009912AF /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; @@ -1429,20 +1698,54 @@ 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, ); }; }; + 5A04BAF822973E7F001848A0 /* OTFollowup.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A04BAF722973E43001848A0 /* OTFollowup.m */; }; + 5A04BAFA22976A15001848A0 /* OTClique.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F336A20DD643B0031A92D /* OTClique.m */; }; + 5A04BAFB22976A16001848A0 /* OTClique.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F336A20DD643B0031A92D /* OTClique.m */; }; + 5A04BB0222982733001848A0 /* OTFollowupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A04BAF922973EA9001848A0 /* OTFollowupTests.m */; }; + 5A04BB1922986717001848A0 /* SecXPCHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A04BB182298670C001848A0 /* SecXPCHelper.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5A04BB1A22986717001848A0 /* SecXPCHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A04BB182298670C001848A0 /* SecXPCHelper.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5A06118E229ED5EB006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061191229ED6DB006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061192229ED6E5006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061193229ED6E6006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061194229ED6E7006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061196229ED6E8006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061197229ED6EB006AF14A /* NSDate+SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */; }; + 5A061198229ED8F3006AF14A /* NSDate+SFAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A061190229ED60C006AF14A /* NSDate+SFAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5A061199229ED8F4006AF14A /* NSDate+SFAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A061190229ED60C006AF14A /* NSDate+SFAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5A0F84A522AEAF5B0097AEEA /* NSDate+SFAnalyticsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A1A1C2122A71D2A00CB8D1D /* NSDate+SFAnalyticsTests.m */; }; + 5A2551F32229F41300512FAE /* SecExperimentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A2551F12229F40800512FAE /* SecExperimentInternal.h */; }; + 5A2551F52229F41500512FAE /* SecExperimentInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A2551F12229F40800512FAE /* SecExperimentInternal.h */; }; + 5A43A083225FA39C005450E4 /* SecProtocolHelperTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A43A07F225FA38D005450E4 /* SecProtocolHelperTest.m */; }; + 5A43A084225FA3A5005450E4 /* SecProtocolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0B3202E3451001EA371 /* SecProtocolTest.m */; }; + 5A43A085225FA3A5005450E4 /* SecProtocolHelperTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A43A07F225FA38D005450E4 /* SecProtocolHelperTest.m */; }; + 5A43A08A226112DB005450E4 /* SecProtocolConfigurationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = AADD4A2B215E83140054FC6D /* SecProtocolConfigurationTest.m */; }; + 5A47FFB3228F5E5500F781B8 /* KCInitialMessageData.proto in Sources */ = {isa = PBXBuildFile; fileRef = 5A47FFB1228F5DF700F781B8 /* KCInitialMessageData.proto */; }; + 5A47FFB9228F5F2A00F781B8 /* KCInitialMessageData.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A47FFB5228F5E9000F781B8 /* KCInitialMessageData.m */; }; + 5A47FFBA228F60DF00F781B8 /* KCInitialMessageData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A47FFB4228F5E9000F781B8 /* KCInitialMessageData.h */; }; + 5A47FFBE228F6D1B00F781B8 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; }; + 5A6D1B9520810EAD0057CAC8 /* SecProtocolMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6D1B8D20810EA30057CAC8 /* SecProtocolMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A6D1B9620810EAE0057CAC8 /* SecProtocolMetadata.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6D1B8D20810EA30057CAC8 /* SecProtocolMetadata.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A6D1B9B20810EDD0057CAC8 /* SecProtocolOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6D1B9320810EA30057CAC8 /* SecProtocolOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A6D1B9C20810EDE0057CAC8 /* SecProtocolOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6D1B9320810EA30057CAC8 /* SecProtocolOptions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A6D1B9D20810EF40057CAC8 /* SecProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6D1B9420810EA40057CAC8 /* SecProtocolTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A6D1B9E20810EF40057CAC8 /* SecProtocolTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A6D1B9420810EA40057CAC8 /* SecProtocolTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5A7E037822272C2D003DB3A0 /* SecProtocolHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A7E037722272C2D003DB3A0 /* SecProtocolHelper.m */; }; + 5A7E037A22272E0E003DB3A0 /* SecProtocolHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A7E037722272C2D003DB3A0 /* SecProtocolHelper.m */; }; + 5A7E037B2227301D003DB3A0 /* SecProtocolInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = AADD4A28215E82440054FC6D /* SecProtocolInternal.h */; }; + 5A7E037C2227301E003DB3A0 /* SecProtocolInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = AADD4A28215E82440054FC6D /* SecProtocolInternal.h */; }; + 5AA465CF2228AF4B00C068F4 /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 5AF593FE1FA0EE5300A5C1EC /* SecProtocol.c */; }; + 5AA465D02228AF4B00C068F4 /* SecProtocolHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A7E037722272C2D003DB3A0 /* SecProtocolHelper.m */; }; + 5AA465D12228AF4B00C068F4 /* SecProtocolConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = AA9FD59B2152AFD70045A07A /* SecProtocolConfiguration.m */; }; + 5AA465D22228AF4B00C068F4 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 78ADC6251FA0FAC5001EB8B6 /* SecProtocolTypes.m */; }; + 5AA465E12229A40400C068F4 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; + 5AE4BEEF1FA79456001B9DA4 /* SecProtocolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AE4BEEE1FA79456001B9DA4 /* SecProtocolObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AE4BEF01FA79456001B9DA4 /* SecProtocolObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AE4BEEE1FA79456001B9DA4 /* SecProtocolObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5AF593FF1FA0EE5300A5C1EC /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 5AF593FE1FA0EE5300A5C1EC /* SecProtocol.c */; }; + 5AF594001FA0EE5300A5C1EC /* SecProtocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 5AF593FE1FA0EE5300A5C1EC /* SecProtocol.c */; }; + 5AF594021FA1051600A5C1EC /* SecProtocolPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AF594011FA1051500A5C1EC /* SecProtocolPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5AF594031FA1051600A5C1EC /* SecProtocolPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AF594011FA1051500A5C1EC /* SecProtocolPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5E01F5B1227C859200BC884C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 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 */; }; @@ -1459,30 +1762,86 @@ 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 */; }; + 5F00F9562306146700B832E0 /* p12import.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E2A1D8085FC00865A7C /* p12import.c */; }; + 5F00F9582306147100B832E0 /* p12pbegen.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E2C1D8085FC00865A7C /* p12pbegen.c */; }; + 5F00F9592306147A00B832E0 /* SecImportExport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E551D8085FC00865A7C /* SecImportExport.c */; }; + 5F00F95B230614AC00B832E0 /* SecImportExportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F00F95A230614A200B832E0 /* SecImportExportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5F00F95C230614AD00B832E0 /* SecImportExportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 5F00F95A230614A200B832E0 /* SecImportExportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 5F84950222DFB505008B3EFB /* SecTrustExceptionResetCount.m in Sources */ = {isa = PBXBuildFile; fileRef = 5F8494FF22DFB502008B3EFB /* SecTrustExceptionResetCount.m */; }; + 6C02134E21F7ED25009D5C80 /* SecDbBackupTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C02134D21F7ED16009D5C80 /* SecDbBackupTests.m */; }; + 6C02135021F7EF07009D5C80 /* SecDbBackupTests.plist in Copy BATS Test Discovery Plist */ = {isa = PBXBuildFile; fileRef = 6C02134C21F7ED16009D5C80 /* SecDbBackupTests.plist */; }; 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 */; }; + 6C23F02F227A3A28009F6756 /* com.apple.securityd.sb in Install Sandbox Profile */ = {isa = PBXBuildFile; fileRef = 6C23F02C227A39E9009F6756 /* com.apple.securityd.sb */; }; 6C32BB9920EAE6B00042DF59 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; - 6C32BB9A20EAE6B80042DF59 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; + 6C32D36420F2C23100ACAB2C /* TPPBPolicyRedaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C70D8DE20EBDFD700AB6FAF /* TPPBPolicyRedaction.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C32D36520F2C23D00ACAB2C /* TPPBPolicyDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C0C807420EAF81900334E33 /* TPPBPolicyDocument.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C32D36620F2C23D00ACAB2C /* TPPBPolicyCategoriesByView.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C0C809620EB024800334E33 /* TPPBPolicyCategoriesByView.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C32D36720F2C23D00ACAB2C /* TPPBPolicyIntroducersByCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C0C809720EB024900334E33 /* TPPBPolicyIntroducersByCategory.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 6C32D36820F2C23D00ACAB2C /* TPPBPolicyModelToCategory.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C0C809820EB024900334E33 /* TPPBPolicyModelToCategory.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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 */; }; + 6C39234E21F13E4D00D018AD /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + 6C39234F21F13E4D00D018AD /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + 6C39235021F13E4D00D018AD /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + 6C39235221F13E4D00D018AD /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + 6C39235321F13E4D00D018AD /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + 6C39235421F13E4D00D018AD /* KeychainModel.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 470D966B1FCDE4BA0065FE90 /* KeychainModel.xcdatamodeld */; }; + 6C39235621F13E4D00D018AD /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + 6C39235821F13E4D00D018AD /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + 6C39235B21F13E4D00D018AD /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EB80DE57219600CF005B10FA /* libz.dylib */; }; + 6C39235C21F13E4D00D018AD /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 482FE56B2177C7AE0031C11E /* AuthKit.framework */; }; + 6C39235D21F13E4D00D018AD /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + 6C39235E21F13E4D00D018AD /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + 6C39235F21F13E4D00D018AD /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + 6C39236021F13E4D00D018AD /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 477A1F4C20320E4900ACD81D /* Accounts.framework */; }; + 6C39236121F13E4D00D018AD /* libprequelite.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 472339611FD7155C00CB6A72 /* libprequelite.dylib */; }; + 6C39236321F13E4D00D018AD /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; + 6C39236421F13E4D00D018AD /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE81F9921D00003AE36 /* libACM.a */; }; + 6C39236521F13E4D00D018AD /* ApplePushService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE61F9921890003AE36 /* ApplePushService.framework */; }; + 6C39236621F13E4D00D018AD /* SharedWebCredentials.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */; }; + 6C39236721F13E4D00D018AD /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBE01F99212F0003AE36 /* IOKit.framework */; }; + 6C39236821F13E4D00D018AD /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBDA1F9920CB0003AE36 /* WirelessDiagnostics.framework */; }; + 6C39236921F13E4D00D018AD /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD81F9920BB0003AE36 /* SystemConfiguration.framework */; }; + 6C39236A21F13E4D00D018AD /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + 6C39236B21F13E4D00D018AD /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + 6C39236C21F13E4D00D018AD /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD41F9920510003AE36 /* ProtocolBuffer.framework */; }; + 6C39236D21F13E4D00D018AD /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 6C39236E21F13E4D00D018AD /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBD21F9920290003AE36 /* CloudKit.framework */; }; + 6C39237021F13E4D00D018AD /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCF1F991F820003AE36 /* SecurityFoundation.framework */; }; + 6C39237121F13E4D00D018AD /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBCC1F991F660003AE36 /* libsqlite3.dylib */; }; + 6C39237221F13E4D00D018AD /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + 6C39237321F13E4D00D018AD /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */; }; + 6C39237421F13E4D00D018AD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4727FBC41F991C460003AE36 /* Foundation.framework */; }; + 6C39237B21F13EB400D018AD /* SecDbBackupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */; }; + 6C39237C21F13EB400D018AD /* SecDbBackupBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC321C334FD00D38D66 /* SecDbBackupBag.m */; }; + 6C39237D21F13EB400D018AD /* SecDbBackupBagIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC621C334FE00D38D66 /* SecDbBackupBagIdentity.m */; }; + 6C39237F21F13EB400D018AD /* SecDbBackupKeyClassSigningKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC221C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.m */; }; + 6C39238121F13EB400D018AD /* SecDbBackupMetadataClassKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC121C334FC00D38D66 /* SecDbBackupMetadataClassKey.m */; }; + 6C39238221F13EB400D018AD /* SecDbBackupRecoverySet.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC021C334FC00D38D66 /* SecDbBackupRecoverySet.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 */; }; + 6C4AEF88218A09E70012C5DA /* CheckV12DevEnabled.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF83218A09210012C5DA /* CheckV12DevEnabled.m */; }; + 6C4AEF89218A09E80012C5DA /* CheckV12DevEnabled.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF83218A09210012C5DA /* CheckV12DevEnabled.m */; }; + 6C4AEF90218A0C170012C5DA /* SecDbBackupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */; }; + 6C4AEF91218A0C190012C5DA /* SecDbBackupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */; }; + 6C4AEF96218A127F0012C5DA /* SecDbKeychainMetadataKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF93218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.m */; }; + 6C4AEF97218A12810012C5DA /* SecDbKeychainMetadataKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF93218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.m */; }; + 6C4AEFA0218A189A0012C5DA /* SecAKSObjCWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF9D218A16F80012C5DA /* SecAKSObjCWrappers.m */; }; + 6C4AEFA1218A189B0012C5DA /* SecAKSObjCWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF9D218A16F80012C5DA /* SecAKSObjCWrappers.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 */; }; + 6C540C3922289A3B0032B5BC /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC4A76A92212698B006F2D8F /* CloudServices.framework */; }; 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 */; }; 6C5B36BA1E2F9B95008AD443 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C3D1E2537C6007F95E5 /* WirelessDiagnostics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; 6C5B36C01E2F9BEA008AD443 /* WirelessDiagnostics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C3D1E2537C6007F95E5 /* WirelessDiagnostics.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + 6C7094CC2239D21E00C5DAC6 /* SecDbBackupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */; }; 6C73F48A2006B839003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; 6C73F48B2006B83A003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; - 6C73F48C2006B83D003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; 6C73F48D2006B83E003D5D63 /* SOSAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C7BB0032006B4EE004D1B6B /* SOSAnalytics.m */; }; 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, ); }; }; @@ -1490,13 +1849,26 @@ 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 */; }; + 6C880FC821C3351400D38D66 /* SecDbBackupBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC321C334FD00D38D66 /* SecDbBackupBag.m */; }; + 6C880FC921C3351400D38D66 /* SecDbBackupBagIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC621C334FE00D38D66 /* SecDbBackupBagIdentity.m */; }; + 6C880FCA21C3351400D38D66 /* SecDbBackupKeyClassSigningKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC221C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.m */; }; + 6C880FCB21C3351400D38D66 /* SecDbBackupMetadataClassKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC121C334FC00D38D66 /* SecDbBackupMetadataClassKey.m */; }; + 6C880FCC21C3351400D38D66 /* SecDbBackupRecoverySet.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC021C334FC00D38D66 /* SecDbBackupRecoverySet.m */; }; + 6C880FCD21C3351500D38D66 /* SecDbBackupBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC321C334FD00D38D66 /* SecDbBackupBag.m */; }; + 6C880FCE21C3351500D38D66 /* SecDbBackupBagIdentity.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC621C334FE00D38D66 /* SecDbBackupBagIdentity.m */; }; + 6C880FCF21C3351500D38D66 /* SecDbBackupKeyClassSigningKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC221C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.m */; }; + 6C880FD021C3351500D38D66 /* SecDbBackupMetadataClassKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC121C334FC00D38D66 /* SecDbBackupMetadataClassKey.m */; }; + 6C880FD121C3351500D38D66 /* SecDbBackupRecoverySet.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C880FC021C334FC00D38D66 /* SecDbBackupRecoverySet.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 */; }; + 6C8FF4B3224C1A8D00E5C812 /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; + 6C9791C821C20CFF0074C609 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + 6C9791C921C2EAB60074C609 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + 6C9791CA21C2EAB70074C609 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + 6C9791CB21C325C30074C609 /* SecDbBackupRecoverySet.proto in Sources */ = {isa = PBXBuildFile; fileRef = 6CB6CC022198D4BC0080AD6F /* SecDbBackupRecoverySet.proto */; }; 6C98083E1E788AEB00E70590 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; - 6C98084A1E788AEB00E70590 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; - 6C98084C1E788AEB00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; + 6C98084A1E788AEB00E70590 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; 6C98084D1E788AEB00E70590 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; 6C98084E1E788AEB00E70590 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; 6C98084F1E788AEB00E70590 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; @@ -1514,8 +1886,7 @@ 6C98085B1E788AEB00E70590 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; 6C98085C1E788AEB00E70590 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; 6C98087A1E788AFD00E70590 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; - 6C9808861E788AFD00E70590 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; - 6C9808881E788AFD00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; + 6C9808861E788AFD00E70590 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; 6C9808891E788AFD00E70590 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; 6C98088A1E788AFD00E70590 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; 6C98088B1E788AFD00E70590 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; @@ -1541,12 +1912,10 @@ 6CAA8CEE1F83E417007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; 6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; 6CAA8CF01F83E65E007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; - 6CAA8CF41F83E799007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; 6CAA8CF61F83E79D007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; 6CAA8CF71F83E79E007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; 6CAA8CF81F83E7A9007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; 6CAA8CF91F83E7AA007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; - 6CAA8CFA1F83E7AC007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; 6CAA8CFC1F83E7EA007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; 6CAA8CFD1F83E7EB007B6E03 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; 6CAA8CFE1F83E800007B6E03 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; @@ -1554,7 +1923,6 @@ 6CAA8D0D1F83EC57007B6E03 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; 6CAA8D131F83ECD4007B6E03 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; 6CAA8D141F83ECD5007B6E03 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; - 6CAA8D151F83ECD9007B6E03 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; 6CAA8D271F843002007B6E03 /* supd.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69517E1F758E1000F68F91 /* supd.m */; }; 6CAA8D351F84306C007B6E03 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C6951801F758E1000F68F91 /* main.m */; }; 6CAA8D371F843196007B6E03 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; @@ -1575,16 +1943,15 @@ 6CBF65421FA2255800A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; 6CBF65431FA2257100A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; 6CBF65441FA2257200A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; - 6CBF65451FA2257500A68667 /* SFAnalyticsActivityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */; }; 6CC1859E1E24E8EB009657D8 /* CKKSRateLimiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC185971E24E87D009657D8 /* CKKSRateLimiter.h */; }; 6CC1859F1E24E8EB009657D8 /* CKKSRateLimiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CC185981E24E87D009657D8 /* CKKSRateLimiter.m */; }; 6CC952481FB4CB2C0051A823 /* SFAnalytics+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC952421FB4C5CA0051A823 /* SFAnalytics+Internal.h */; }; 6CC952491FB4CB2D0051A823 /* SFAnalytics+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CC952421FB4C5CA0051A823 /* SFAnalytics+Internal.h */; }; 6CCDF78C1E3C26BC003F2555 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CCDF78B1E3C26BC003F2555 /* XCTest.framework */; }; 6CCDF78D1E3C26C2003F2555 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */; }; + 6CD1DBED21F9281D00D158FB /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; 6CDB5FF51FA78D1A00410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; 6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; - 6CDB5FF71FA78D2100410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; 6CDB5FF81FA78D2300410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; 6CDB5FF91FA78D2400410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; 6CDB5FFA1FA78D2500410924 /* SFAnalyticsMultiSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDB5FED1FA78CB400410924 /* SFAnalyticsMultiSampler.m */; }; @@ -1596,7 +1963,6 @@ 6CDB601B1FA93A2000410924 /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CFDC4561F907E1D00646DBB /* libprequelite.tbd */; }; 6CDF8DEF1F96495600140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; 6CDF8DF01F96495700140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; - 6CDF8DF11F96498300140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; 6CDF8DF21F9649AB00140B54 /* SFAnalyticsSampler.m in Sources */ = {isa = PBXBuildFile; fileRef = 6CDF8DE61F95562B00140B54 /* SFAnalyticsSampler.m */; }; 6CDF8DF31F9649C000140B54 /* SFAnalyticsSQLiteStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */; }; 6CDF8DF41F9649C000140B54 /* SFAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9DB1F1540CE0082882F /* SFAnalytics.m */; }; @@ -1621,29 +1987,17 @@ 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 */; }; - 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, ); }; }; 7281E0871DFD01800021E1B7 /* SOSAccountGetSet.m in Sources */ = {isa = PBXBuildFile; fileRef = 7281E0861DFD015A0021E1B7 /* SOSAccountGetSet.m */; }; - 7281E0881DFD06480021E1B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 7281E08D1DFD0B520021E1B7 /* XPCNotificationDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = E7C787331DD0FED50087FC34 /* XPCNotificationDispatcher.m */; }; 7281E08F1DFD0DBB0021E1B7 /* secd-210-keyinterest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7281E08E1DFD0D810021E1B7 /* secd-210-keyinterest.m */; }; 7281E0901DFD0E0A0021E1B7 /* CKDKVSProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = E7A5F4C71C0CFF3200F3BEBB /* CKDKVSProxy.m */; }; 7281E0911DFD0E510021E1B7 /* CKDSimulatedStore.m in Sources */ = {isa = PBXBuildFile; fileRef = E7FE40C41DC804E400F0F5B6 /* CKDSimulatedStore.m */; }; - 7281E0971DFD0FD00021E1B7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; 72CDF5131EC679A4002D233B /* sec_action.h in Headers */ = {isa = PBXBuildFile; fileRef = 7221843F1EC6782A004C7BED /* sec_action.h */; }; 72CDF5191EC679A8002D233B /* sec_action.c in Sources */ = {isa = PBXBuildFile; fileRef = 7221843E1EC6782A004C7BED /* sec_action.c */; }; + 78ADC62B1FA0FACD001EB8B6 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 78ADC6251FA0FAC5001EB8B6 /* SecProtocolTypes.m */; }; + 78ADC62C1FA0FACE001EB8B6 /* SecProtocolTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = 78ADC6251FA0FAC5001EB8B6 /* SecProtocolTypes.m */; }; 78F92F11195128D70023B54B /* SecECKeyPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 78F92F10195128D70023B54B /* SecECKeyPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791812D51F7200CA4D44 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901790E12D51F7200CA4D44 /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791912D51F7200CA4D44 /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901790F12D51F7200CA4D44 /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791A12D51F7200CA4D44 /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791012D51F7200CA4D44 /* SecCmsDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791B12D51F7200CA4D44 /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791112D51F7200CA4D44 /* SecCmsDigestContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791C12D51F7200CA4D44 /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791212D51F7200CA4D44 /* SecCmsEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791D12D51F7200CA4D44 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791312D51F7200CA4D44 /* SecCmsEnvelopedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791E12D51F7200CA4D44 /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791412D51F7200CA4D44 /* SecCmsMessage.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901791F12D51F7200CA4D44 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791512D51F7200CA4D44 /* SecCmsRecipientInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901792012D51F7200CA4D44 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791612D51F7200CA4D44 /* SecCmsSignedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 7901792112D51F7200CA4D44 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 7901791712D51F7200CA4D44 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; 790850F70CA88AE10083CC4D /* securityd_client.h in Headers */ = {isa = PBXBuildFile; fileRef = 790850820CA87CF00083CC4D /* securityd_client.h */; }; 790851D40CA9B19D0083CC4D /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; }; 790851EE0CA9B3410083CC4D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; @@ -1662,7 +2016,6 @@ 79679E2A146202A800CF997F /* Invalid-webmail.jaring.my.crt in Copy DigiCertMalaysia Resources */ = {isa = PBXBuildFile; fileRef = 79679E261462028800CF997F /* Invalid-webmail.jaring.my.crt */; }; 79679E2C146202CB00CF997F /* Digisign-Server-ID-Enrich-Entrust-Cert.crt in Copy DigicertMalaysia Resources */ = {isa = PBXBuildFile; fileRef = 79679E251462028800CF997F /* Digisign-Server-ID-Enrich-Entrust-Cert.crt */; }; 79679E2D146202CB00CF997F /* Invalid-webmail.jaring.my.crt in Copy DigicertMalaysia Resources */ = {isa = PBXBuildFile; fileRef = 79679E261462028800CF997F /* Invalid-webmail.jaring.my.crt */; }; - 79BDD3C20D60DB84000D84D3 /* SecCMS.h in Headers */ = {isa = PBXBuildFile; fileRef = 79BDD3C00D60DB84000D84D3 /* SecCMS.h */; settings = {ATTRIBUTES = (Private, ); }; }; 79EF5B6E0D3D6A31009F5270 /* SecImportExport.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EF5B6C0D3D6A31009F5270 /* SecImportExport.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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, ); }; }; @@ -1670,12 +2023,23 @@ 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, ); }; }; + AA0DA47A21E818AB009F1C74 /* builtins.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = AA0DA47921E8189E009F1C74 /* builtins.json */; }; + AA0DA47B21E818AB009F1C74 /* example1.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = AA0DA47821E8189D009F1C74 /* example1.json */; }; + AA0DA47D21E818D2009F1C74 /* builtins.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = AA0DA47921E8189E009F1C74 /* builtins.json */; }; + AA0DA47E21E818D2009F1C74 /* example1.json in CopyFiles */ = {isa = PBXBuildFile; fileRef = AA0DA47821E8189D009F1C74 /* example1.json */; }; + AA15CB4D2076C5A900C1A978 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + AA15CB4F2076C9D500C1A978 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + AA44E0B5202E355C001EA371 /* SecProtocolTest.m in Sources */ = {isa = PBXBuildFile; fileRef = AA44E0B3202E3451001EA371 /* SecProtocolTest.m */; }; + AA5B12192164671000A6AB81 /* SecProtocolConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FD5982152AFC00045A07A /* SecProtocolConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; }; + AA5B121C2164671000A6AB81 /* SecProtocolConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9FD5982152AFC00045A07A /* SecProtocolConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; }; + AA7C71B62185429800EB314F /* SecProtocolTypesPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = AAE91C542162634200B6BF0B /* SecProtocolTypesPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + AA7C71B72185429900EB314F /* SecProtocolTypesPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = AAE91C542162634200B6BF0B /* SecProtocolTypesPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + AA9FD59C2152AFD70045A07A /* SecProtocolConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = AA9FD59B2152AFD70045A07A /* SecProtocolConfiguration.m */; }; + AA9FD59D2152AFE30045A07A /* SecProtocolConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = AA9FD59B2152AFD70045A07A /* SecProtocolConfiguration.m */; }; + AAA5FC7E21664D1D00B52A48 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 475EDCD420D98934009D2409 /* Security.framework */; }; + AAD6630A203362490073E17B /* libnetwork.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = AAD66304203362480073E17B /* libnetwork.tbd */; }; + AAD6630B203362500073E17B /* libnetwork.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = AAD66304203362480073E17B /* libnetwork.tbd */; }; + AADD4A2D215E83270054FC6D /* SecProtocolConfigurationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = AADD4A2B215E83140054FC6D /* SecProtocolConfigurationTest.m */; }; 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 */; }; @@ -1702,11 +2066,6 @@ BE25C41618B83491003320E0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; BE2AD2B31FDA07EF00739F96 /* OTBottledPeerRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */; }; BE2AD2BA1FDA080800739F96 /* OTBottledPeerRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */; }; - BE2AD2BB1FDA080900739F96 /* OTBottledPeerRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */; }; - BE3405AC1FD7258900933DAC /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A11FD71CC800933DAC /* OTBottle.proto */; }; - BE3405AD1FD725A700933DAC /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A51FD720C900933DAC /* OTBottleContents.proto */; }; - BE3405AE1FD725EC00933DAC /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A11FD71CC800933DAC /* OTBottle.proto */; }; - BE3405AF1FD725F000933DAC /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE3405A51FD720C900933DAC /* OTBottleContents.proto */; }; BE405EE21DC2F10E00E227B1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; BE405EE31DC2F11E00E227B1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; BE442BAE18B7FDB800F24DAE /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; @@ -1719,43 +2078,89 @@ BE4AC9A218B7FFAD00B84964 /* swcagent.m in Sources */ = {isa = PBXBuildFile; fileRef = BE4AC9A118B7FFAD00B84964 /* swcagent.m */; }; BE4AC9AE18B7FFC800B84964 /* com.apple.security.swcagent.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = BE4AC9AD18B7FFC800B84964 /* com.apple.security.swcagent.plist */; }; BE4AC9BA18B8273600B84964 /* SharedWebCredentials.strings in Resources */ = {isa = PBXBuildFile; fileRef = BE4AC9B818B8273600B84964 /* SharedWebCredentials.strings */; }; + BE4C6AB820CAF4F700EAD6BE /* ContainerSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE4C6AB120CAF4E500EAD6BE /* ContainerSync.swift */; }; + BE536019209BB76B0027E25A /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC9EBA311DEE768000D0F733 /* CloudKit.framework */; }; + BE53601A209BB7F80027E25A /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + BE53601B209BB8390027E25A /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + BE53601C209BB8970027E25A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; + BE53602D209BBF630027E25A /* libMobileGestalt.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BE53602C209BBF2F0027E25A /* libMobileGestalt.tbd */; }; + BE536030209BC1FD0027E25A /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + BE536031209BC2F90027E25A /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + BE536032209BC3250027E25A /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + BE536033209BC3B30027E25A /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + BE536034209BC3C40027E25A /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + BE55C77C2044D0C90045863D /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE55C77B2044D0C90045863D /* Client.swift */; }; + BE55C77E2044D7E60045863D /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE55C77D2044D7E60045863D /* main.swift */; }; BE61F5AF1EB0060C00556CCF /* TrustedPeers.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C641EB0005F00357577 /* TrustedPeers.h */; settings = {ATTRIBUTES = (Public, ); }; }; BE6215BE1DB6E69100961E15 /* si-84-sectrust-allowlist.m in Sources */ = {isa = PBXBuildFile; fileRef = BE6215BD1DB6E69100961E15 /* si-84-sectrust-allowlist.m */; }; + BE64A7FA22AF006F001209F3 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; + BE64A7FB22AF0084001209F3 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E8141D7A4E6F00AFB96E /* CFNetwork.framework */; }; + BE64A7FC22AF008D001209F3 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D848541C6C1D9C0025BB44 /* Foundation.framework */; }; + BE64A80022AF010B001209F3 /* trusted_cert_ssl.m in Sources */ = {isa = PBXBuildFile; fileRef = BE64A7FE22AF010A001209F3 /* trusted_cert_ssl.m */; }; + BE70899D1F9AB03E001ACC20 /* TPPBVoucher.h in Headers */ = {isa = PBXBuildFile; fileRef = BE70899A1F9AAFF7001ACC20 /* TPPBVoucher.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BE727824209CBCA800F0DA77 /* Cuttlefish.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F4F8B2072D881004A52C2 /* Cuttlefish.pb.swift */; }; + BE72782B209D27C800F0DA77 /* TPKeyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BE72782A209D27C800F0DA77 /* TPKeyTests.m */; }; + BE72782C209D2C1400F0DA77 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; BE759DCB1917E38D00801E02 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE451314471B000DE34E /* CoreGraphics.framework */; }; BE8ABDD81DC2DD9100EC2D58 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; - BEA74211202525CD00EC7993 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; - BEA74217202525DC00EC7993 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; - BEB0B0D71FFC3D9A007E6A83 /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */; }; - BEB0B0D81FFC3DD3007E6A83 /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */; }; - BEB0B0DB1FFC45C2007E6A83 /* OTPrivateKey+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB0B0D91FFC45C2007E6A83 /* OTPrivateKey+SF.h */; }; - 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 */; }; - BEB9EA301FFF1B0800676593 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */; }; + BE92249E204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BE92249C204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld */; }; + BE9B8B4A202BB4A20081EF87 /* si-88-sectrust-valid.m in Sources */ = {isa = PBXBuildFile; fileRef = BE9B8B49202BB4A10081EF87 /* si-88-sectrust-valid.m */; }; + BE9B8B4B202BB4D10081EF87 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BE9B8B43202BB42C0081EF87 /* si-88-sectrust-valid-data */; }; + BE9B8B4C202BB4E30081EF87 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BE9B8B43202BB42C0081EF87 /* si-88-sectrust-valid-data */; }; + BE9B8B4D202BB4F30081EF87 /* si-88-sectrust-valid-data in Resources */ = {isa = PBXBuildFile; fileRef = BE9B8B43202BB42C0081EF87 /* si-88-sectrust-valid-data */; }; + BE9F4F8C2072D881004A52C2 /* Cuttlefish.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F4F8B2072D881004A52C2 /* Cuttlefish.pb.swift */; }; + BE9F8D10206C099800B53D16 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D0F206C099800B53D16 /* Container.swift */; }; + BE9F8D12206C121400B53D16 /* Decrypter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D11206C121400B53D16 /* Decrypter.swift */; }; + BE9F8D15206C2E0200B53D16 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + BE9F8D19206C4AD300B53D16 /* ContainerMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D18206C4AD300B53D16 /* ContainerMap.swift */; }; + BEA8558120B5DC7D00D5AD11 /* FakeCuttlefish.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA8557F20B5DC7D00D5AD11 /* FakeCuttlefish.swift */; }; + BEAA0046202B785000E51F45 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + BEB0B06E1FE9E81D007E6A83 /* TPPBPeerDynamicInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BE7089CF1FA3BA01001ACC20 /* TPPBPeerDynamicInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEB0B06F1FE9E850007E6A83 /* TPPBPeerPermanentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BE7089DD1FA40B93001ACC20 /* TPPBPeerPermanentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEB0B0701FE9E8F6007E6A83 /* TPPBPeerStableInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = BE7089D41FA3BA04001ACC20 /* TPPBPeerStableInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEB0B0711FE9E936007E6A83 /* TPPBPolicySecret.h in Headers */ = {isa = PBXBuildFile; fileRef = BE7089D31FA3BA03001ACC20 /* TPPBPolicySecret.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEB49F30206E98D0008DA7F4 /* TPECPublicKeyFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB49F29206E98CD008DA7F4 /* TPECPublicKeyFactory.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEB49F31206E98D0008DA7F4 /* TPECPublicKeyFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB49F2F206E98CE008DA7F4 /* TPECPublicKeyFactory.m */; }; + BEB49F34206E9A1A008DA7F4 /* SFKey+TPKey.h in Headers */ = {isa = PBXBuildFile; fileRef = BEB49F32206E9A18008DA7F4 /* SFKey+TPKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEB49F35206E9A1A008DA7F4 /* SFKey+TPKey.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB49F33206E9A19008DA7F4 /* SFKey+TPKey.m */; }; + BEB49F37206E9B8B008DA7F4 /* TPECPublicKeyFactoryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEB49F36206E9B89008DA7F4 /* TPECPublicKeyFactoryTests.m */; }; + BEC0A96420B362EC00DBD772 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEC0A96320B362EC00DBD772 /* Utils.swift */; }; + BEC0A96520B362EC00DBD772 /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEC0A96320B362EC00DBD772 /* Utils.swift */; }; + BEC373A420CF3B5D00DBDF5B /* TPPBDisposition.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC373A220CF3B5C00DBDF5B /* TPPBDisposition.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEC373B220D815F500DBDF5B /* TPPBUnknownMachineID.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC373B120D815E400DBDF5B /* TPPBUnknownMachineID.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEC373B320D815FB00DBDF5B /* TPPBPolicyProhibits.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC373B020D815E300DBDF5B /* TPPBPolicyProhibits.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEC373B420D8160100DBDF5B /* TPPBAncientEpoch.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC373AF20D815E200DBDF5B /* TPPBAncientEpoch.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEC373CB20D822DA00DBDF5B /* TPPBDispositionEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = BEC373CA20D822CE00DBDF5B /* TPPBDispositionEntry.h */; settings = {ATTRIBUTES = (Private, ); }; }; + BEC373D020D87B4D00DBDF5B /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + BECEC11220A508F600E97255 /* TPVoucher.h in Headers */ = {isa = PBXBuildFile; fileRef = BECEC11020A508F600E97255 /* TPVoucher.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BECEC11320A508F600E97255 /* TPVoucher.m in Sources */ = {isa = PBXBuildFile; fileRef = BECEC11120A508F600E97255 /* TPVoucher.m */; }; + BECEC11C20A634E000E97255 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; }; + BECFA43120F91AFE00B11002 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = BECFA43020F91AFE00B11002 /* main.m */; }; + BECFA43A20F91B8300B11002 /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; + BECFA43B20F91CE500B11002 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; }; + BECFA43D20F9493000B11002 /* Policy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECFA43C20F9493000B11002 /* Policy.swift */; }; + BECFA43E20F9493000B11002 /* Policy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECFA43C20F9493000B11002 /* Policy.swift */; }; + BECFA44320FD0A4B00B11002 /* LocalKeychainAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C814A4B2050B4B600CB391B /* LocalKeychainAnalytics.m */; }; + BECFA45920FEB90900B11002 /* Policy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BECFA43C20F9493000B11002 /* Policy.swift */; }; + BECFA46420FFB87500B11002 /* TPKey.m in Sources */ = {isa = PBXBuildFile; fileRef = BECFA46320FFB87400B11002 /* TPKey.m */; }; BED208D81EDF950E00753952 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; BED208D91EDF950E00753952 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; BED208E81EDF974500753952 /* manifeststresstest.m in Sources */ = {isa = PBXBuildFile; fileRef = BED208E71EDF971600753952 /* manifeststresstest.m */; }; - BEE4B18C1FFD585800777D39 /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */; }; - BEE4B18D1FFD588000777D39 /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */; }; - BEE4B1921FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */; }; - BEE4B1931FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */; }; - BEE4B1941FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */; }; - BEE4B1951FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */; }; - BEE4B1981FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */; }; - BEE4B1991FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */ = {isa = PBXBuildFile; fileRef = BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */; }; - BEE4B19A1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */; }; - BEE4B19B1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */ = {isa = PBXBuildFile; fileRef = BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */; }; + BED987D62099145300607A5F /* TrustedPeersHelperUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED987D52099145300607A5F /* TrustedPeersHelperUnitTests.swift */; }; + BED987D82099145300607A5F /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; + BED987DE2099156B00607A5F /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D0F206C099800B53D16 /* Container.swift */; }; + BED987DF209918A500607A5F /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + BED987E020991B1100607A5F /* TrustedPeersHelper.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BE92249C204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld */; }; + BED987E120991B9B00607A5F /* Decrypter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D11206C121400B53D16 /* Decrypter.swift */; }; + BED987E320991C4D00607A5F /* MockCuttlefish.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED987E220991C4D00607A5F /* MockCuttlefish.swift */; }; BEE523D91DACAA2500DD0AA3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789221D7799A600B50D50 /* libz.dylib */; }; BEE523DC1DACAA9200DD0AA3 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789221D7799A600B50D50 /* libz.dylib */; }; BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */ = {isa = PBXBuildFile; fileRef = BEEB47D71EA189F5004AA5C6 /* SecTrustStatusCodes.c */; }; BEEB47DA1EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */ = {isa = PBXBuildFile; fileRef = BEEB47D71EA189F5004AA5C6 /* SecTrustStatusCodes.c */; }; BEEB47DB1EA189F5004AA5C6 /* SecTrustStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = BEEB47D81EA189F5004AA5C6 /* SecTrustStatusCodes.h */; }; BEEB47DC1EA189F5004AA5C6 /* SecTrustStatusCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = BEEB47D81EA189F5004AA5C6 /* SecTrustStatusCodes.h */; }; - BEF88C311EAFFC3F00357577 /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; BEF88C771EB000BE00357577 /* TPCategoryRule.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C481EB0005E00357577 /* TPCategoryRule.h */; settings = {ATTRIBUTES = (Public, ); }; }; BEF88C781EB000BE00357577 /* TPCategoryRule.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C491EB0005E00357577 /* TPCategoryRule.m */; }; - BEF88C791EB000BE00357577 /* TPCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C4A1EB0005E00357577 /* TPCircle.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BEF88C7A1EB000BE00357577 /* TPCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C4B1EB0005E00357577 /* TPCircle.m */; }; BEF88C7B1EB000BE00357577 /* TPDecrypter.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C4C1EB0005E00357577 /* TPDecrypter.h */; settings = {ATTRIBUTES = (Public, ); }; }; BEF88C7C1EB000BE00357577 /* TPEncrypter.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C4D1EB0005E00357577 /* TPEncrypter.h */; settings = {ATTRIBUTES = (Public, ); }; }; BEF88C7D1EB000BE00357577 /* TPHash.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C4E1EB0005E00357577 /* TPHash.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1774,13 +2179,8 @@ BEF88C8A1EB000BE00357577 /* TPPolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C5B1EB0005E00357577 /* TPPolicy.m */; }; BEF88C8B1EB000BE00357577 /* TPPolicyDocument.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C5C1EB0005E00357577 /* TPPolicyDocument.h */; settings = {ATTRIBUTES = (Public, ); }; }; BEF88C8C1EB000BE00357577 /* TPPolicyDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C5D1EB0005E00357577 /* TPPolicyDocument.m */; }; - BEF88C8D1EB000BE00357577 /* TPSigningKey.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C5E1EB0005E00357577 /* TPSigningKey.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BEF88C8D1EB000BE00357577 /* TPKey.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C5E1EB0005E00357577 /* TPKey.h */; settings = {ATTRIBUTES = (Public, ); }; }; BEF88C8E1EB000BE00357577 /* TPTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C5F1EB0005E00357577 /* TPTypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BEF88C8F1EB000BE00357577 /* TPUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C601EB0005E00357577 /* TPUtils.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BEF88C901EB000BE00357577 /* TPUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C611EB0005E00357577 /* TPUtils.m */; }; - BEF88C911EB000BE00357577 /* TPVoucher.h in Headers */ = {isa = PBXBuildFile; fileRef = BEF88C621EB0005E00357577 /* TPVoucher.h */; settings = {ATTRIBUTES = (Public, ); }; }; - BEF88C921EB000BE00357577 /* TPVoucher.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C631EB0005F00357577 /* TPVoucher.m */; }; - BEF88C931EB000FD00357577 /* TPCircleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C671EB0008E00357577 /* TPCircleTests.m */; }; BEF88C941EB000FD00357577 /* TPDummyDecrypter.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C691EB0008E00357577 /* TPDummyDecrypter.m */; }; BEF88C951EB000FD00357577 /* TPDummyEncrypter.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C6B1EB0008E00357577 /* TPDummyEncrypter.m */; }; BEF88C961EB000FD00357577 /* TPDummySigningKey.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C6D1EB0008E00357577 /* TPDummySigningKey.m */; }; @@ -1790,8 +2190,6 @@ BEF88C9A1EB000FD00357577 /* TPPeerStableInfoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C721EB0008E00357577 /* TPPeerStableInfoTests.m */; }; BEF88C9B1EB000FD00357577 /* TPPeerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = BEF88C731EB0008E00357577 /* TPPeerTests.m */; }; 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 */; }; CD112FC51DDA31AD00C77A07 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; CD198F971DE27B9E00F6FB83 /* SOSAccountPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = CD9021471DE27A9E00F81DC4 /* SOSAccountPriv.h */; }; CD791B3C1DFC9A7600F0E5DC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD2F99D91DFC995B00769430 /* libsqlite3.0.dylib */; }; @@ -1799,25 +2197,42 @@ CD9F2AF81DF23CA600AD3577 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; CD9F2AF91DF249B400AD3577 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; CD9F2AFA1DF249CF00AD3577 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - CD9F2AFB1DF24BAF00AD3577 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; CDB9FCAB179CD098000AAD66 /* Info.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = CDB9FCA9179CC757000AAD66 /* Info.plist */; }; CDDE9BD11729ABFA0013B0E8 /* SecPasswordGenerate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDE9BC31729AB910013B0E8 /* SecPasswordGenerate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D401E8B420A26F1F00CD8BB4 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; }; + D4056A1A22712A650026E24E /* SSLPolicyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4056A1922712A650026E24E /* SSLPolicyTests.m */; }; + D4056A1B22712A650026E24E /* SSLPolicyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4056A1922712A650026E24E /* SSLPolicyTests.m */; }; + D4056A1F22712D750026E24E /* ssl-policy-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4056A1D22712D740026E24E /* ssl-policy-certs */; }; + D4056A2022712D750026E24E /* ssl-policy-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4056A1D22712D740026E24E /* ssl-policy-certs */; }; + D40881EF2175731E00180E81 /* SecTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E901D8085FC00865A7C /* SecTrust.c */; }; + D40881F02175732600180E81 /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E971D8085FC00865A7C /* SecTrustStore.c */; }; + D40881F12175732E00180E81 /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; }; + D40881F22175733500180E81 /* SecSignatureVerificationSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E8E1D8085FC00865A7C /* SecSignatureVerificationSupport.c */; }; + D40881F32175733F00180E81 /* SecPolicy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7E1D8085FC00865A7C /* SecPolicy.c */; }; + D40881F42175738C00180E81 /* SecPolicyLeafCallbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7F1D8085FC00865A7C /* SecPolicyLeafCallbacks.c */; }; + D40881F5217573C900180E81 /* SecTrustStatusCodes.c in Sources */ = {isa = PBXBuildFile; fileRef = BEEB47D71EA189F5004AA5C6 /* SecTrustStatusCodes.c */; }; + D40881F6217573D500180E81 /* SecTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E901D8085FC00865A7C /* SecTrust.c */; }; + D40881F7217573E000180E81 /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E971D8085FC00865A7C /* SecTrustStore.c */; }; + D40881F8217573E700180E81 /* SecCertificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E381D8085FC00865A7C /* SecCertificate.c */; }; + D40881F9217573EF00180E81 /* SecSignatureVerificationSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E8E1D8085FC00865A7C /* SecSignatureVerificationSupport.c */; }; + D40881FA217573F800180E81 /* SecPolicy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7E1D8085FC00865A7C /* SecPolicy.c */; }; + D40881FB217573F800180E81 /* SecPolicyLeafCallbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E7F1D8085FC00865A7C /* SecPolicyLeafCallbacks.c */; }; D4096E011ED5F0B5000AC459 /* si-60-cms.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD81D8085FC00865A7C /* si-60-cms.c */; }; D4096E021ED5F207000AC459 /* si-64-ossl-cms.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DE71D8085FC00865A7C /* si-64-ossl-cms.c */; }; D4096E031ED5F21C000AC459 /* si-65-cms-cert-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DE81D8085FC00865A7C /* si-65-cms-cert-policy.c */; }; - D40B6A831E2B5F5B00CD6EE5 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + D40B6A831E2B5F5B00CD6EE5 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; D40B6A8D1E2B63D900CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; D40B6A8E1E2B643500CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; D40B6A8F1E2B643D00CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; D40B6A901E2B673500CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; D40B6A931E2B67E500CD6EE5 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; D40B6A971E2B684900CD6EE5 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CD2F99D91DFC995B00769430 /* libsqlite3.0.dylib */; }; - D40B6A981E2B687F00CD6EE5 /* libDiagnosticMessagesClient.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3C1D78F25C002223DE /* libDiagnosticMessagesClient.dylib */; }; D40B6A991E2B68A400CD6EE5 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; D40B6A9A1E2B68E800CD6EE5 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; D40B6A9B1E2B690E00CD6EE5 /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; D40B6A9D1E2B6A2700CD6EE5 /* login.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E8271D7A4F0E00AFB96E /* login.framework */; }; D40B6A9E1E2B6A6F00CD6EE5 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; + D40B7CA021605BF800AC9A75 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (Required, ); }; }; D4119E78202BDF490048587B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; D4119E79202BDF580048587B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; D4119E882032A8FA0048587B /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; @@ -1836,7 +2251,71 @@ D41D36711EB14D87007FA978 /* libDiagnosticMessagesClient.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */; }; D425EC1D1DD3C3CF00DE5DEC /* SecInternalRelease.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC761D8C68CF00070CB0 /* SecInternalRelease.c */; }; D425EC231DD3FFF200DE5DEC /* SecInternalRelease.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC761D8C68CF00070CB0 /* SecInternalRelease.c */; }; + D42C837C21158ACC008D3D83 /* cmscinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = D44D1F8521158AAC00E76E1A /* cmscinfo.c */; }; + D42C837D21158ACC008D3D83 /* cmsdigest.c in Sources */ = {isa = PBXBuildFile; fileRef = D44D1F8821158AAE00E76E1A /* cmsdigest.c */; }; + D42C837E21158ACC008D3D83 /* cmsencode.c in Sources */ = {isa = PBXBuildFile; fileRef = D44D1F8A21158AAF00E76E1A /* cmsencode.c */; }; + D42C837F21158ACC008D3D83 /* cmsreclist.c in Sources */ = {isa = PBXBuildFile; fileRef = D44D1F8921158AAE00E76E1A /* cmsreclist.c */; }; + D42C838021158ACC008D3D83 /* cmssiginfo.c in Sources */ = {isa = PBXBuildFile; fileRef = D44D1F8621158AAD00E76E1A /* cmssiginfo.c */; }; + D42C838121158ACC008D3D83 /* crypto-embedded.c in Sources */ = {isa = PBXBuildFile; fileRef = D44D1F8421158AAC00E76E1A /* crypto-embedded.c */; }; + D42C838921158B4E008D3D83 /* SecAsn1Item.c in Sources */ = {isa = PBXBuildFile; fileRef = D42C838821158B40008D3D83 /* SecAsn1Item.c */; }; + D42C838A21158B90008D3D83 /* libCMS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D44D1F662115893000E76E1A /* libCMS.a */; }; + D42C838B21158EF4008D3D83 /* libCMS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D44D1F662115893000E76E1A /* libCMS.a */; }; + D42C839C21159170008D3D83 /* CMSEncoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D42C8393211590D7008D3D83 /* CMSEncoder.cpp */; }; + D42C839D21159170008D3D83 /* CMSUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D42C8392211590D7008D3D83 /* CMSUtils.cpp */; }; + D42C839E21159170008D3D83 /* CMSDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D42C8390211590BC008D3D83 /* CMSDecoder.cpp */; }; + D42C839F211593D8008D3D83 /* libsecurity_cms.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D42C839821159146008D3D83 /* libsecurity_cms.a */; }; D42CDC351DC12FE90090E2C9 /* si-66-smime.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DEB1D8085FC00865A7C /* si-66-smime.c */; }; + D437185F211671A500EA350A /* cms-01-basic.c in Sources */ = {isa = PBXBuildFile; fileRef = D437185C211671A300EA350A /* cms-01-basic.c */; }; + D4371860211671A500EA350A /* smime-cms-test.c in Sources */ = {isa = PBXBuildFile; fileRef = D437185D211671A400EA350A /* smime-cms-test.c */; }; + D4371861211671A500EA350A /* cms-01-basic.h in Headers */ = {isa = PBXBuildFile; fileRef = D437185E211671A400EA350A /* cms-01-basic.h */; }; + D4371869211682D800EA350A /* cmscipher.c in Sources */ = {isa = PBXBuildFile; fileRef = D4371862211682D500EA350A /* cmscipher.c */; }; + D437186A211682D800EA350A /* cmsarray.c in Sources */ = {isa = PBXBuildFile; fileRef = D4371863211682D500EA350A /* cmsarray.c */; }; + D437186B211682D800EA350A /* cmsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = D4371864211682D600EA350A /* cmsattr.c */; }; + D437186C211682D800EA350A /* cmsasn1.c in Sources */ = {isa = PBXBuildFile; fileRef = D4371865211682D600EA350A /* cmsasn1.c */; }; + D437186D211682D800EA350A /* cmscinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = D4371866211682D600EA350A /* cmscinfo.c */; }; + D437186E211682D800EA350A /* cert.c in Sources */ = {isa = PBXBuildFile; fileRef = D4371867211682D700EA350A /* cert.c */; }; + D437186F211682D800EA350A /* cert.h in Headers */ = {isa = PBXBuildFile; fileRef = D4371868211682D700EA350A /* cert.h */; }; + D43718782116831A00EA350A /* cmsdigest.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718702116831600EA350A /* cmsdigest.c */; }; + D43718792116831A00EA350A /* cmsenvdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718712116831600EA350A /* cmsenvdata.c */; }; + D437187A2116831A00EA350A /* cmsdecode.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718722116831700EA350A /* cmsdecode.c */; }; + D437187B2116831A00EA350A /* cmsmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718732116831700EA350A /* cmsmessage.c */; }; + D437187C2116831A00EA350A /* cmsencode.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718742116831800EA350A /* cmsencode.c */; }; + D437187D2116831A00EA350A /* cmsencdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718752116831900EA350A /* cmsencdata.c */; }; + D437187E2116831A00EA350A /* cmslocal.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718762116831900EA350A /* cmslocal.h */; }; + D437187F2116831A00EA350A /* cmsdigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718772116831A00EA350A /* cmsdigdata.c */; }; + D43718882116834400EA350A /* cmsreclist.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718802116834000EA350A /* cmsreclist.c */; }; + D43718892116834400EA350A /* cmsreclist.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718812116834000EA350A /* cmsreclist.h */; }; + D437188A2116834400EA350A /* cmspriv.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718822116834100EA350A /* cmspriv.h */; }; + D437188B2116834400EA350A /* cmssiginfo.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718832116834100EA350A /* cmssiginfo.c */; }; + D437188C2116834400EA350A /* cmssigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718842116834200EA350A /* cmssigdata.c */; }; + D437188D2116834400EA350A /* cmstpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718852116834300EA350A /* cmstpriv.h */; }; + D437188E2116834400EA350A /* cmsrecinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718862116834300EA350A /* cmsrecinfo.c */; }; + D437188F2116834400EA350A /* cmspubkey.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718872116834400EA350A /* cmspubkey.c */; }; + D43718992116836300EA350A /* secalgid.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718902116835E00EA350A /* secalgid.c */; }; + D437189A2116836300EA350A /* cryptohi.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718912116835E00EA350A /* cryptohi.h */; }; + D437189B2116836300EA350A /* secitem.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718922116835F00EA350A /* secitem.c */; }; + D437189C2116836300EA350A /* cryptohi.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718932116836000EA350A /* cryptohi.c */; }; + D437189D2116836300EA350A /* plhash.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718942116836000EA350A /* plhash.h */; }; + D437189E2116836300EA350A /* plhash.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718952116836100EA350A /* plhash.c */; }; + D437189F2116836300EA350A /* SecCMS.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718962116836200EA350A /* SecCMS.c */; }; + D43718A02116836300EA350A /* secitem.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718972116836200EA350A /* secitem.h */; }; + D43718A12116836300EA350A /* cmsutil.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718982116836300EA350A /* cmsutil.c */; }; + D43718A82116839300EA350A /* siginfoUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D43718A22116838F00EA350A /* siginfoUtils.cpp */; }; + D43718A92116839300EA350A /* secoidt.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718A32116839000EA350A /* secoidt.h */; }; + D43718AA2116839300EA350A /* secoid.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718A42116839000EA350A /* secoid.c */; }; + D43718AB2116839300EA350A /* secoid.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718A52116839100EA350A /* secoid.h */; }; + D43718AC2116839300EA350A /* SecSMIMEPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718A62116839200EA350A /* SecSMIMEPriv.h */; }; + D43718AD2116839300EA350A /* smimeutil.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718A72116839200EA350A /* smimeutil.c */; }; + D43718B0211683AA00EA350A /* tsaSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718AE211683A900EA350A /* tsaSupport.c */; }; + D43718B1211683AA00EA350A /* tsaTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = D43718AF211683AA00EA350A /* tsaTemplates.c */; }; + D43718B6211683D400EA350A /* tsaSupportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718B2211683D100EA350A /* tsaSupportPriv.h */; }; + D43718B7211683D400EA350A /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718B3211683D200EA350A /* tsaSupport.h */; }; + D43718B9211683D400EA350A /* tsaTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718B5211683D300EA350A /* tsaTemplates.h */; }; + D43718BC211683F100EA350A /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718B3211683D200EA350A /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D43718C121168C4300EA350A /* libsecurity_cms.plist in Copy Open Source Version */ = {isa = PBXBuildFile; fileRef = D43718BF21168BCD00EA350A /* libsecurity_cms.plist */; }; + D43718C321168C6D00EA350A /* libsecurity_cms.txt in Copy Open Source Licenses */ = {isa = PBXBuildFile; fileRef = D43718BE21168BCC00EA350A /* libsecurity_cms.txt */; }; + D43718C821168D7D00EA350A /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718C721168D7C00EA350A /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D43718C921168D7D00EA350A /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = D43718C721168D7C00EA350A /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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, ); }; }; @@ -1860,14 +2339,80 @@ D43DBF0B1E99D1CA00C04AEA /* SecTrustLoggingServer.m in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.m */; }; D43DBF0C1E99D1CA00C04AEA /* SecTrustServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF71E99D17300C04AEA /* SecTrustServer.c */; }; D43DBF0D1E99D1CA00C04AEA /* SecTrustStoreServer.c in Sources */ = {isa = PBXBuildFile; fileRef = D43DBEF91E99D17300C04AEA /* SecTrustStoreServer.c */; }; + D44282FF22D68564001746B3 /* TrustEvaluationTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = D44282FE22D68556001746B3 /* TrustEvaluationTestHelpers.m */; }; + D442830022D68564001746B3 /* TrustEvaluationTestHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = D44282FE22D68556001746B3 /* TrustEvaluationTestHelpers.m */; }; + D4428B342122604300EB8448 /* SecFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0B906C0ACCBD240077CD03 /* SecFramework.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4428B36212262F800EB8448 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; D447C4101D3094740082FC1D /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + D44D1F6F2115899C00E76E1A /* CMSUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E762115886D0014647E /* CMSUtils.c */; }; + D44D1F70211589AC00E76E1A /* CMSDecoder.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E68211588680014647E /* CMSDecoder.c */; }; + D44D1F71211589AC00E76E1A /* CMSEncoder.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E7C2115886F0014647E /* CMSEncoder.c */; }; + D44D1F7221158A1300E76E1A /* smimeutil.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E722115886B0014647E /* smimeutil.c */; }; + D44D1F7321158A1700E76E1A /* secoid.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E792115886E0014647E /* secoid.c */; }; + D44D1F7421158A1A00E76E1A /* secalgid.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E69211588680014647E /* secalgid.c */; }; + D44D1F7521158A1E00E76E1A /* plhash.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E742115886C0014647E /* plhash.c */; }; + D44D1F7621158A3300E76E1A /* cmsutil.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E782115886D0014647E /* cmsutil.c */; }; + D44D1F7821158A3A00E76E1A /* cmsrecinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E7F211588700014647E /* cmsrecinfo.c */; }; + D44D1F7921158A3D00E76E1A /* cmspubkey.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E65211588670014647E /* cmspubkey.c */; }; + D44D1F7A21158A4000E76E1A /* cmsmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E6C211588690014647E /* cmsmessage.c */; }; + D44D1F7B21158A4400E76E1A /* cmsenvdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E7D2115886F0014647E /* cmsenvdata.c */; }; + D44D1F7C21158A4900E76E1A /* cmsencdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E6F2115886A0014647E /* cmsencdata.c */; }; + D44D1F7D21158A4C00E76E1A /* cmsdigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E7B2115886E0014647E /* cmsdigdata.c */; }; + D44D1F7E21158A5300E76E1A /* cmsdecode.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E732115886C0014647E /* cmsdecode.c */; }; + D44D1F8021158A5B00E76E1A /* cmsarray.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E6B211588690014647E /* cmsarray.c */; }; + D44D1F8121158A5D00E76E1A /* cmsasn1.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E772115886D0014647E /* cmsasn1.c */; }; + D44D1F8221158A6000E76E1A /* cmsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E66211588670014647E /* cmsattr.c */; }; D450686A1E948D2200FA7675 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; - D453C3901FEC66AE00DE349B /* trust_update.m in Sources */ = {isa = PBXBuildFile; fileRef = D453C38A1FEC669300DE349B /* trust_update.m */; }; + D453A4A32122235700850A26 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + D453A4AB2122236D00850A26 /* TrustEvaluationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A0F8C9211E6A8200443CA1 /* TrustEvaluationTestCase.m */; }; + D453A4AD2122236D00850A26 /* TrustFrameworkTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A0F8C4211E6A5700443CA1 /* TrustFrameworkTestCase.m */; }; + D453A4AF2122236D00850A26 /* CertificateInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A0F8C6211E6A5700443CA1 /* CertificateInterfaceTests.m */; }; + D453A4B22122236D00850A26 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + D453A4B32122236D00850A26 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */; }; + D453A4B42122236D00850A26 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4B68C5C211A7D98009FED69 /* libDER.a */; }; + D453A4B52122236D00850A26 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + D453A4B62122236D00850A26 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; + D453A4B82122236D00850A26 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; + D453A4B92122236D00850A26 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + D453A4BA2122236D00850A26 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + D453A4BC2122236D00850A26 /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = D4A0F8C1211E6A2F00443CA1 /* si-82-sectrust-ct-data */; }; + D458C4B0214E198F0043D982 /* CTTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4AA214E198D0043D982 /* CTTests.m */; }; + D458C4B1214E198F0043D982 /* CTTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4AA214E198D0043D982 /* CTTests.m */; }; + D458C4B2214E198F0043D982 /* EvaluationBasicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4AF214E198E0043D982 /* EvaluationBasicTests.m */; }; + D458C4B3214E198F0043D982 /* EvaluationBasicTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4AF214E198E0043D982 /* EvaluationBasicTests.m */; }; + D458C4B8214E19AF0043D982 /* PathParseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4B4214E19AE0043D982 /* PathParseTests.m */; }; + D458C4B9214E19AF0043D982 /* PathParseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4B4214E19AE0043D982 /* PathParseTests.m */; }; + D458C4BA214E19AF0043D982 /* iAPTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4B5214E19AE0043D982 /* iAPTests.m */; }; + D458C4BB214E19AF0043D982 /* iAPTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4B5214E19AE0043D982 /* iAPTests.m */; }; + D458C4BC214E19AF0043D982 /* SignatureAlgorithmTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4B7214E19AF0043D982 /* SignatureAlgorithmTests.m */; }; + D458C4BD214E19AF0043D982 /* SignatureAlgorithmTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4B7214E19AF0043D982 /* SignatureAlgorithmTests.m */; }; + D458C4C2214E19FC0043D982 /* TrustSettingsInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4BE214E19FA0043D982 /* TrustSettingsInterfaceTests.m */; }; + D458C4C3214E19FC0043D982 /* TrustInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4BF214E19FB0043D982 /* TrustInterfaceTests.m */; }; + D458C4C4214E19FC0043D982 /* TrustInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4BF214E19FB0043D982 /* TrustInterfaceTests.m */; }; + D458C4F9214E1E1B0043D982 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4CA214E1A420043D982 /* AppDelegate.m */; }; + D458C4FB214E1E1B0043D982 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4CD214E1A430043D982 /* ViewController.m */; }; + D458C4FD214E1E6C0043D982 /* appmain.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4FC214E1E6C0043D982 /* appmain.m */; }; + D458C4FF214E1F8E0043D982 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D458C4FE214E1F8E0043D982 /* UIKit.framework */; }; + D458C501214E1FB00043D982 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D458C500214E1FAF0043D982 /* Foundation.framework */; }; + D458C507214E20540043D982 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D458C500214E1FAF0043D982 /* Foundation.framework */; }; + D458C510214E207C0043D982 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4C6214E1A400043D982 /* main.m */; }; + D458C512214E20850043D982 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D458C511214E20840043D982 /* XCTest.framework */; }; + D458C515214E286C0043D982 /* PolicyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C513214E27620043D982 /* PolicyTests.m */; }; + D458C516214E286D0043D982 /* PolicyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C513214E27620043D982 /* PolicyTests.m */; }; + D458C517214E2C690043D982 /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; + D458C51A214E2CC80043D982 /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; + D458C51C214E2DEB0043D982 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D458C4C5214E1A400043D982 /* Assets.xcassets */; }; + D458C51D214E2DEB0043D982 /* Base.lproj in Resources */ = {isa = PBXBuildFile; fileRef = D458C4C7214E1A400043D982 /* Base.lproj */; }; + D458C51F214E2E0C0043D982 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D458C51E214E2E0C0043D982 /* Main.storyboard */; }; + D458C520214E33260043D982 /* ECTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC5766214E195300A32C01 /* ECTests.m */; }; + D458C521214E33260043D982 /* ECTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC5766214E195300A32C01 /* ECTests.m */; }; + D458C522214E33370043D982 /* KeySizeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC5768214E195400A32C01 /* KeySizeTests.m */; }; + D458C523214E33380043D982 /* KeySizeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC5768214E195400A32C01 /* KeySizeTests.m */; }; + D458C524214E33430043D982 /* VerifyDateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC5764214E195200A32C01 /* VerifyDateTests.m */; }; + D458C525214E33440043D982 /* VerifyDateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC5764214E195200A32C01 /* VerifyDateTests.m */; }; D45917E41DC13E6700752D25 /* SecCertificateRequest.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E3E1D8085FC00865A7C /* SecCertificateRequest.c */; }; 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 */; }; - D46246A71F9AE62000D63882 /* oids.c in Sources */ = {isa = PBXBuildFile; fileRef = D462469C1F9AE45900D63882 /* oids.c */; }; D46246A81F9AE64000D63882 /* oids.h in Headers */ = {isa = PBXBuildFile; fileRef = D46246A21F9AE49E00D63882 /* oids.h */; settings = {ATTRIBUTES = (Public, ); }; }; D46246AA1F9AE6CA00D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246A91F9AE6C900D63882 /* libDER.a */; }; D46246B51F9AE74000D63882 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; @@ -1883,32 +2428,45 @@ 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 */; }; - D46A6C09215336BC008ABF6A /* SecFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C0B906C0ACCBD240077CD03 /* SecFramework.h */; settings = {ATTRIBUTES = (Private, ); }; }; - D46B37A62151B7950083DAAA /* SecTrustStoreServer.m in Sources */ = {isa = PBXBuildFile; fileRef = D46B379F2151B6E50083DAAA /* SecTrustStoreServer.m */; }; + D46CD4C72267949C00E2C4D7 /* certExtensionTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787621D77911D00B50D50 /* certExtensionTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D46CD4C82267949C00E2C4D7 /* nameTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787651D77911D00B50D50 /* nameTemplates.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D46CD4C92267949C00E2C4D7 /* X509Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787691D77911D00B50D50 /* X509Templates.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D47079F321128C74005BCFDA /* SecCMS.h in Headers */ = {isa = PBXBuildFile; fileRef = D47079F221128C46005BCFDA /* SecCMS.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D47079F421128CA0005BCFDA /* SecCMS.h in Headers */ = {isa = PBXBuildFile; fileRef = D47079F221128C46005BCFDA /* SecCMS.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D47079FA211355C5005BCFDA /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D47079F9211355B3005BCFDA /* CMSEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D47079FB211355C9005BCFDA /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D47079F9211355B3005BCFDA /* CMSEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A0E211373DB005BCFDA /* CMSPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A0D211373D4005BCFDA /* CMSPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A0F211373DE005BCFDA /* CMSPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A0D211373D4005BCFDA /* CMSPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A1121137719005BCFDA /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A1021137525005BCFDA /* CMSDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A1221137719005BCFDA /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A1021137525005BCFDA /* CMSDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4707A202113AC33005BCFDA /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A1F2113AB65005BCFDA /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A212113AC34005BCFDA /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A1F2113AB65005BCFDA /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A232113E74B005BCFDA /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A222113B48E005BCFDA /* SecCmsEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A242113E74B005BCFDA /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A222113B48E005BCFDA /* SecCmsEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A262113EBC1005BCFDA /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A252113E9B6005BCFDA /* SecCmsDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A272113EBC1005BCFDA /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A252113E9B6005BCFDA /* SecCmsDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A292113EF68005BCFDA /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A282113ECA0005BCFDA /* SecCmsMessage.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A2A2113EF68005BCFDA /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A282113ECA0005BCFDA /* SecCmsMessage.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A2C2114C1E5005BCFDA /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A2B2114B31A005BCFDA /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A2D2114C1E8005BCFDA /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A2B2114B31A005BCFDA /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A2F2114C315005BCFDA /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A2E2114C30A005BCFDA /* SecCmsDigestContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4707A302114C316005BCFDA /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A2E2114C30A005BCFDA /* SecCmsDigestContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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 */; }; - D479F6E51F981FD600388D28 /* Trust.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = D479F6DF1F980F8F00388D28 /* Trust.strings */; }; + D479F6E31F981FD600388D28 /* OID.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C198F1F0ACDB4BF00AAB142 /* OID.strings */; }; + D479F6E41F981FD600388D28 /* Certificate.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4C198F1D0ACDB4BF00AAB142 /* Certificate.strings */; }; + D479F6E51F981FD600388D28 /* Trust.strings in Resources */ = {isa = PBXBuildFile; fileRef = D479F6DF1F980F8F00388D28 /* Trust.strings */; }; D47CA65D1EB036450038E2BB /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */; }; D47E69401E92F75D002C8CF6 /* si-61-pkcs12.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */; }; D47F514C1C3B812500A7CEFE /* SecCFAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */; settings = {ATTRIBUTES = (Private, ); }; }; - D484A1072167D707008653A9 /* ct_exceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = D484A1012167D6F8008653A9 /* ct_exceptions.m */; }; D487B9821DFA28DB000410A1 /* SecInternalReleasePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC771D8C68CF00070CB0 /* SecInternalReleasePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; 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, ); }; }; @@ -1918,60 +2476,134 @@ 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 */; }; + D4A0F8C2211E6A2F00443CA1 /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = D4A0F8C1211E6A2F00443CA1 /* si-82-sectrust-ct-data */; }; + D4A0F8C7211E6A5800443CA1 /* TrustFrameworkTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A0F8C4211E6A5700443CA1 /* TrustFrameworkTestCase.m */; }; + D4A0F8C8211E6A5800443CA1 /* CertificateInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A0F8C6211E6A5700443CA1 /* CertificateInterfaceTests.m */; }; + D4A0F8CC211E6A8300443CA1 /* TrustEvaluationTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A0F8C9211E6A8200443CA1 /* TrustEvaluationTestCase.m */; }; + D4A3A597217A85D500F0A8DA /* ct_exceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A3A596217A85CB00F0A8DA /* ct_exceptions.m */; }; + D4A3A598217A85D600F0A8DA /* ct_exceptions.m in Sources */ = {isa = PBXBuildFile; fileRef = D4A3A596217A85CB00F0A8DA /* ct_exceptions.m */; }; + D4A55E70226A50E900FCC664 /* PolicyReporter.h in Sources */ = {isa = PBXBuildFile; fileRef = 1B995256226681ED00A2D6CD /* PolicyReporter.h */; }; + D4A55E71226A50E900FCC664 /* PolicyReporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B995258226681EE00A2D6CD /* PolicyReporter.m */; }; + D4A7DD7420A26D3D00F51F3F /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4A7DD7520A26D4900F51F3F /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + D4AA0D9A22FB959600D77FA4 /* si-29-cms-chain-mode.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AA0D9922FB959600D77FA4 /* si-29-cms-chain-mode.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 */; }; D4AA643E1E95D94400D317ED /* trustd.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = D41257EC1E941CF200781F23 /* trustd.8 */; }; - D4AA64861E97273D00D317ED /* si-18-certificate-parse in Resources */ = {isa = PBXBuildFile; fileRef = D4AA64831E97270300D317ED /* si-18-certificate-parse */; }; - D4AA64871E97274900D317ED /* si-18-certificate-parse in Resources */ = {isa = PBXBuildFile; fileRef = D4AA64831E97270300D317ED /* si-18-certificate-parse */; }; - D4AA64881E97275200D317ED /* si-18-certificate-parse in Resources */ = {isa = PBXBuildFile; fileRef = D4AA64831E97270300D317ED /* si-18-certificate-parse */; }; - D4AA64891E9727EB00D317ED /* si-18-certificate-parse.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AA647C1E97144700D317ED /* si-18-certificate-parse.m */; }; D4AA9D121C3B1B1900A5640C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + D4AC8BE821320AD0006E9871 /* CertificateParseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC8BE721320AD0006E9871 /* CertificateParseTests.m */; }; + D4AC8BE921320AD0006E9871 /* CertificateParseTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4AC8BE721320AD0006E9871 /* CertificateParseTests.m */; }; + D4AC8BEE21321291006E9871 /* si-18-certificate-parse in Resources */ = {isa = PBXBuildFile; fileRef = D4AC8BED2132127A006E9871 /* si-18-certificate-parse */; }; + D4AC8BEF213212A7006E9871 /* si-18-certificate-parse in Resources */ = {isa = PBXBuildFile; fileRef = D4AC8BED2132127A006E9871 /* si-18-certificate-parse */; }; D4AD87701E452CE000CA1B7F /* si-68-secmatchissuer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DF81D8085FC00865A7C /* si-68-secmatchissuer.c */; }; D4ADA32E1E2B43220031CEA3 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; 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 */; }; + D4B2966A22DBFDC700DCF250 /* TestCopyProperties_ios-data in Resources */ = {isa = PBXBuildFile; fileRef = D4B2966822DBFDB100DCF250 /* TestCopyProperties_ios-data */; }; + D4B2966B22DBFDD300DCF250 /* TestCopyProperties_ios-data in Resources */ = {isa = PBXBuildFile; fileRef = D4B2966822DBFDB100DCF250 /* TestCopyProperties_ios-data */; }; + D4B3B1CC2115150D00A43409 /* SecCmsDigestedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1CB2115149C00A43409 /* SecCmsDigestedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1CD2115150D00A43409 /* SecCmsDigestedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1CB2115149C00A43409 /* SecCmsDigestedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1CF211516A000A43409 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1CE2115167600A43409 /* SecCmsEncryptedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D0211516A100A43409 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1CE2115167600A43409 /* SecCmsEncryptedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D2211517BC00A43409 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D1211517B000A43409 /* SecCmsEnvelopedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D3211517BC00A43409 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D1211517B000A43409 /* SecCmsEnvelopedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D52115195900A43409 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D42115193600A43409 /* SecCmsRecipientInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D62115195900A43409 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D42115193600A43409 /* SecCmsRecipientInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D821151BBF00A43409 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D721151B9900A43409 /* SecCmsSignedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1D921151BBF00A43409 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D721151B9900A43409 /* SecCmsSignedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1DB21152AD200A43409 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1DA2115293300A43409 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B3B1DC21152AD300A43409 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1DA2115293300A43409 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; + D4B68C44211A3DCC009FED69 /* libtrustd.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; }; + D4B68C5B211A7D29009FED69 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + D4B68C5D211A7D98009FED69 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4B68C5C211A7D98009FED69 /* libDER.a */; }; + D4B68C5F211A80B1009FED69 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */; }; + D4B68C60211A80BC009FED69 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; + D4B68C61211A80C4009FED69 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + D4B68C62211A80CE009FED69 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + D4B68C63211A80DA009FED69 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + D4B68C66211A8186009FED69 /* trustd_spi.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B68C64211A8186009FED69 /* trustd_spi.h */; }; + D4B68C68211A827C009FED69 /* trustd_spi.c in Sources */ = {isa = PBXBuildFile; fileRef = D4B68C65211A8186009FED69 /* trustd_spi.c */; }; 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 */; }; + D4BD5E83228A6823001650A7 /* util.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BC6F79621C9955D005ED67A /* util.m */; }; + D4BD5E85228A6854001650A7 /* util.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BC6F79621C9955D005ED67A /* util.m */; }; + D4BD5E86228A6855001650A7 /* util.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BC6F79621C9955D005ED67A /* util.m */; }; + D4BD5E87228A6856001650A7 /* util.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BC6F79621C9955D005ED67A /* util.m */; }; + D4BD5E88228A6857001650A7 /* util.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BC6F79621C9955D005ED67A /* util.m */; }; + D4BD5E93228A720E001650A7 /* util.m in Sources */ = {isa = PBXBuildFile; fileRef = 1BC6F79621C9955D005ED67A /* util.m */; }; D4BEECE81E93094500F76D1A /* trustd.c in Sources */ = {isa = PBXBuildFile; fileRef = D4BEECE61E93093A00F76D1A /* trustd.c */; }; D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4C263CC1F952F6C001317EA /* SecErrorMessages.strings */; }; D4C263CF1F953019001317EA /* SecDebugErrorMessages.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4C263C81F952E64001317EA /* SecDebugErrorMessages.strings */; }; - D4C6C5C81FB2AD5E007EA57E /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; - D4C6C5C91FB2AD6D007EA57E /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; - D4C6C5CA1FB2AD7A007EA57E /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; D4C6C5CD1FB3B423007EA57E /* libarchive.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C6C5CB1FB3B3CC007EA57E /* libarchive.tbd */; }; D4C6C5CF1FB3B44D007EA57E /* libarchive.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */; }; D4C6C5D01FB3B45E007EA57E /* libarchive.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */; }; D4C7CD661E71E92D00139817 /* MobileAsset.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7273402816CAFB3C0096622A /* MobileAsset.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; D4CFAA7E1E660BB3004746AA /* si-32-sectrust-pinning-required.m in Sources */ = {isa = PBXBuildFile; fileRef = D4CFAA7D1E660BB3004746AA /* si-32-sectrust-pinning-required.m */; }; + D4D1FDC721163F6A003538E2 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A1F2113AB65005BCFDA /* SecCmsBase.h */; }; + D4D1FDC821163F6A003538E2 /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A2B2114B31A005BCFDA /* SecCmsContentInfo.h */; }; + D4D1FDC921163F6A003538E2 /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A252113E9B6005BCFDA /* SecCmsDecoder.h */; }; + D4D1FDCA21163F6A003538E2 /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A2E2114C30A005BCFDA /* SecCmsDigestContext.h */; }; + D4D1FDCB21163F6A003538E2 /* SecCmsDigestedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1CB2115149C00A43409 /* SecCmsDigestedData.h */; }; + D4D1FDCC21163F6A003538E2 /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A222113B48E005BCFDA /* SecCmsEncoder.h */; }; + D4D1FDCD21163F6A003538E2 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1CE2115167600A43409 /* SecCmsEncryptedData.h */; }; + D4D1FDCE21163F6A003538E2 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D1211517B000A43409 /* SecCmsEnvelopedData.h */; }; + D4D1FDCF21163F6A003538E2 /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = D4707A282113ECA0005BCFDA /* SecCmsMessage.h */; }; + D4D1FDD021163F6A003538E2 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D42115193600A43409 /* SecCmsRecipientInfo.h */; }; + D4D1FDD121163F6A003538E2 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1D721151B9900A43409 /* SecCmsSignedData.h */; }; + D4D1FDD221163F6A003538E2 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = D4B3B1DA2115293300A43409 /* SecCmsSignerInfo.h */; }; + D4D1FDD621164138003538E2 /* cmssigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E6D2115886A0014647E /* cmssigdata.c */; }; + D4D1FDD721164167003538E2 /* cmscipher.c in Sources */ = {isa = PBXBuildFile; fileRef = D4CF6E6E2115886A0014647E /* cmscipher.c */; }; + D4D1FDE021165FAE003538E2 /* cms_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = D42C83A121159568008D3D83 /* cms_regressions.h */; }; + D4D1FDE221165FC6003538E2 /* cms-trust-settings-test.c in Sources */ = {isa = PBXBuildFile; fileRef = D42C83A221159569008D3D83 /* cms-trust-settings-test.c */; }; + D4D1FDE32116608B003538E2 /* libsecurity_cms_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4D1FDDC21165F8B003538E2 /* libsecurity_cms_regressions.a */; }; + D4D1FDE4211660F4003538E2 /* cms-trust-settings-test.h in Headers */ = {isa = PBXBuildFile; fileRef = D42C83A321159569008D3D83 /* cms-trust-settings-test.h */; }; + D4D1FDE521166135003538E2 /* libsecurity_cms_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D4D1FDDC21165F8B003538E2 /* libsecurity_cms_regressions.a */; }; D4D718351E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c in Sources */ = {isa = PBXBuildFile; fileRef = D4D718341E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c */; }; - D4D886BF1CEB9F3B00DC7583 /* ssl-policy-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886BE1CEB9F3B00DC7583 /* ssl-policy-certs */; }; - D4D886C01CEB9F7200DC7583 /* ssl-policy-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886BE1CEB9F3B00DC7583 /* ssl-policy-certs */; }; D4D886E91CEBDD2A00DC7583 /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886E81CEBDD2A00DC7583 /* nist-certs */; }; D4D886EA1CEBDE0800DC7583 /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886E81CEBDD2A00DC7583 /* nist-certs */; }; - D4EC94FB1CEA482D0083E753 /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; - D4EC94FE1CEA48760083E753 /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; - D4FBBD621DD661A7004408F7 /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD601DD66196004408F7 /* CMSEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - D4FBBD631DD661AD004408F7 /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD611DD66196004408F7 /* CMSDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DA19DAEF1FCFA420008E82EE /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; - DA19DAF01FCFA425008E82EE /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + D4D92DA522788FEB0009A7CF /* NISTTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4D92DA422788FEB0009A7CF /* NISTTests.m */; }; + D4D92DA622788FEB0009A7CF /* NISTTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4D92DA422788FEB0009A7CF /* NISTTests.m */; }; + D4D92DA8227890500009A7CF /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D92DA72278904F0009A7CF /* nist-certs */; }; + D4D92DA9227890500009A7CF /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D92DA72278904F0009A7CF /* nist-certs */; }; + D4EA5CF822B225D100883439 /* LoggingServerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EA5CF622B225C000883439 /* LoggingServerTests.m */; }; + D4EA5CF922B225D100883439 /* LoggingServerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EA5CF622B225C000883439 /* LoggingServerTests.m */; }; + D4EF32172156B025000A31A5 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; + D4EF32182156DDEB000A31A5 /* TrustSettingsInterfaceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D458C4BE214E19FA0043D982 /* TrustSettingsInterfaceTests.m */; }; + D4EF3221215F0F7F000A31A5 /* SecTrustStoreServer.m in Sources */ = {isa = PBXBuildFile; fileRef = D4EF321E215F0F76000A31A5 /* SecTrustStoreServer.m */; }; + D4F56B95217FC93500FCA6B7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + D4FD421C217D789C002B7EE2 /* NameConstraintsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FD421B217D7891002B7EE2 /* NameConstraintsTests.m */; }; + D4FD421D217D789C002B7EE2 /* NameConstraintsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FD421B217D7891002B7EE2 /* NameConstraintsTests.m */; }; + D4FD4220217D7B2E002B7EE2 /* PathScoringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FD421F217D7B27002B7EE2 /* PathScoringTests.m */; }; + D4FD4221217D7B2E002B7EE2 /* PathScoringTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4FD421F217D7B27002B7EE2 /* PathScoringTests.m */; }; + D4FD4224217D7BE4002B7EE2 /* libarchive.2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4FD4223217D7BE3002B7EE2 /* libarchive.2.tbd */; }; + D4FD4225217D7BEE002B7EE2 /* libarchive.2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4FD4223217D7BE3002B7EE2 /* libarchive.2.tbd */; }; + D4FD4226217D7C41002B7EE2 /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; + D4FD4227217D7C4F002B7EE2 /* si-87-sectrust-name-constraints in Resources */ = {isa = PBXBuildFile; fileRef = D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */; }; + DA20716222E9367500E209E4 /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + DA2C402E2189302F005F1CC3 /* mach_notify.defs in Sources */ = {isa = PBXBuildFile; fileRef = DA2C402D2189302E005F1CC3 /* mach_notify.defs */; settings = {ATTRIBUTES = (Server, ); }; }; DA30D6851DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = DA30D6841DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m */; }; + DA41FE1A2241AF4600838FB3 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DA41FE192241AF3E00838FB3 /* main.m */; }; + DA41FE1B2241AF8200838FB3 /* IDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD744683195A00BB00FB01C0 /* IDS.framework */; }; + DA45865C2245AEDB0073F993 /* OTPairingService.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4586592245AEDA0073F993 /* OTPairingService.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 */; }; + DAC58D1B22443C0700D4CD41 /* KeychainCircle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C75AC642141F18D0073A2F9 /* KeychainCircle.framework */; }; + DAC58D202244528B00D4CD41 /* OTPairingPacketContext.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC58D1E2244528000D4CD41 /* OTPairingPacketContext.m */; }; + DACAD62A229F6E6A0002BBC3 /* OTPairingSession.m in Sources */ = {isa = PBXBuildFile; fileRef = DACAD629229F6E6A0002BBC3 /* OTPairingSession.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 */; }; + DAEF8E5A22581A1200F7DF79 /* OTPairingClient.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEF8E57225819EF00F7DF79 /* OTPairingClient.m */; }; + DAEF8E5C22581CDF00F7DF79 /* OTPairingClient.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEF8E57225819EF00F7DF79 /* OTPairingClient.m */; }; DC0067C11D87879D005AF8DB /* ucspServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82811D87734600418608 /* ucspServer.cpp */; }; DC0067C21D8787A4005AF8DB /* ucspNotifyReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82831D87734600418608 /* ucspNotifyReceiver.cpp */; }; DC0067D11D8788B7005AF8DB /* ucspClientC.c in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82801D87734600418608 /* ucspClientC.c */; }; @@ -1982,21 +2614,15 @@ DC00AB6F1D821C3400513D74 /* libSecItemShimOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EE6E1D80D82600B0A59C /* libSecItemShimOSX.a */; }; DC00AB701D821C3800513D74 /* libSecOtrOSX.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD66DDB1D8205C400DB1393 /* libSecOtrOSX.a */; }; DC00AB7A1D821C6B00513D74 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; - DC00AB7B1D821C6E00513D74 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; DC00AB7C1D821C7100513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; DC00AB811D821C9100513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; DC00AB821D821C9500513D74 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; DC00AB831D821C9A00513D74 /* libSWCAgent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */; }; DC00AB8E1D821D4900513D74 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; - DC00AB8F1D821D4D00513D74 /* libSecurityTool.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EA4C1D80CB7000B0A59C /* libSecurityTool.a */; }; - DC00AB901D821D5600513D74 /* libSecurityCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EBD51D80CEF100B0A59C /* libSecurityCommands.a */; }; DC00AB971D821D7100513D74 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; - DC00AB981D821D7400513D74 /* libSecurityTool.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EA4C1D80CB7000B0A59C /* libSecurityTool.a */; }; - DC00AB991D821D7700513D74 /* libSecurityCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EBD51D80CEF100B0A59C /* libSecurityCommands.a */; }; DC00AB9A1D821D8800513D74 /* libSWCAgent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */; }; DC00AB9B1D821D9F00513D74 /* libSWCAgent.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */; }; DC00AB9C1D821DA400513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; - DC00ABA51D821DCD00513D74 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; DC00ABB31D821E0400513D74 /* libSharedRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EE411D80D6DD00B0A59C /* libSharedRegressions.a */; }; DC00ABB41D821E0700513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; DC00ABB51D821E0B00513D74 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; @@ -2019,19 +2645,30 @@ DC00ABE61D821F7700513D74 /* libsecdRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */; }; DC00ABE81D821F7D00513D74 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; DC00ABE91D821F8000513D74 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; - DC00ABEC1D821FA600513D74 /* libSecurityTool.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EA4C1D80CB7000B0A59C /* libSecurityTool.a */; }; 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 */; }; + DC00C91D20B3B79600628BEB /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + DC00C92020B3B7CC00628BEB /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246911F9AE2E400D63882 /* libDER.a */; }; + DC00C92320B3B80500628BEB /* libbsm.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EB49B2DC202DF251003F34A0 /* libbsm.tbd */; }; + DC00C92420B3B82600628BEB /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + DC00C93420B48B4100628BEB /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + DC00C93520B48BA800628BEB /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + DC047081218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC04707F218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.h */; }; + DC047082218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = DC047080218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.m */; }; + DC047087218BCEF20078BDAA /* OTOperationDependencies.h in Headers */ = {isa = PBXBuildFile; fileRef = DC047085218BCEF20078BDAA /* OTOperationDependencies.h */; }; + DC047088218BCEF20078BDAA /* OTOperationDependencies.m in Sources */ = {isa = PBXBuildFile; fileRef = DC047086218BCEF20078BDAA /* OTOperationDependencies.m */; }; + DC05035E214083B200A8EDB7 /* TPHObjcTranslation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB9475421274A1900ED9272 /* TPHObjcTranslation.m */; }; + DC05037A21409A4100A8EDB7 /* OCMockUmbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DC05037821409A4100A8EDB7 /* OCMockUmbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC05038121409A6100A8EDB7 /* OCMock.framework in Embed OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + DC05038221409B3400A8EDB7 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; }; DC066DF02102563300694EAF /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; + DC07090422936DB2002711B9 /* OctagonTests+ErrorHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC07090222936BCC002711B9 /* OctagonTests+ErrorHandling.swift */; }; 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 */; }; - DC0984FD1E1DB6DF00140ADC /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DC0984FE1E1DB70100140ADC /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; DC0B62281D90974300D43BCB /* si-25-cms-skid.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0B62261D90973900D43BCB /* si-25-cms-skid.h */; }; 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 */; }; DC0BC5611D8B6D6000070CB0 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC5461D8B6AFE00070CB0 /* main.c */; }; DC0BC5621D8B6D7000070CB0 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; @@ -2080,15 +2717,10 @@ DC0BC5F51D8B745700070CB0 /* comDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC5EF1D8B745700070CB0 /* comDebug.h */; }; DC0BC6511D8B755200070CB0 /* byteRep.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6031D8B755200070CB0 /* byteRep.c */; }; DC0BC6521D8B755200070CB0 /* byteRep.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6041D8B755200070CB0 /* byteRep.h */; }; - DC0BC6541D8B755200070CB0 /* CipherFileDES.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6061D8B755200070CB0 /* CipherFileDES.h */; }; - DC0BC6561D8B755200070CB0 /* CipherFileFEED.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6081D8B755200070CB0 /* CipherFileFEED.h */; }; - DC0BC6571D8B755200070CB0 /* CipherFileTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6091D8B755200070CB0 /* CipherFileTypes.h */; }; DC0BC6581D8B755200070CB0 /* ckconfig.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC60A1D8B755200070CB0 /* ckconfig.h */; }; - DC0BC65A1D8B755200070CB0 /* ckDES.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC60C1D8B755200070CB0 /* ckDES.h */; }; DC0BC65C1D8B755200070CB0 /* ckMD5.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC60E1D8B755200070CB0 /* ckMD5.h */; }; DC0BC65D1D8B755200070CB0 /* ckSHA1.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC60F1D8B755200070CB0 /* ckSHA1.c */; }; DC0BC65E1D8B755200070CB0 /* ckSHA1.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6101D8B755200070CB0 /* ckSHA1.h */; }; - DC0BC6601D8B755200070CB0 /* ckSHA1_priv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6121D8B755200070CB0 /* ckSHA1_priv.h */; }; DC0BC6611D8B755200070CB0 /* ckutilities.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6131D8B755200070CB0 /* ckutilities.c */; }; DC0BC6621D8B755200070CB0 /* ckutilities.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6141D8B755200070CB0 /* ckutilities.h */; }; DC0BC6631D8B755200070CB0 /* Crypt.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6151D8B755200070CB0 /* Crypt.h */; }; @@ -2097,11 +2729,9 @@ DC0BC6681D8B755200070CB0 /* CryptKitDER.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC61A1D8B755200070CB0 /* CryptKitDER.cpp */; }; DC0BC6691D8B755200070CB0 /* CryptKitDER.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC61B1D8B755200070CB0 /* CryptKitDER.h */; }; DC0BC66A1D8B755200070CB0 /* curveParamData.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC61C1D8B755200070CB0 /* curveParamData.h */; }; - DC0BC66B1D8B755200070CB0 /* curveParamDataOld.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC61D1D8B755200070CB0 /* curveParamDataOld.h */; }; DC0BC66C1D8B755200070CB0 /* curveParams.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC61E1D8B755200070CB0 /* curveParams.c */; }; DC0BC66D1D8B755200070CB0 /* curveParams.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC61F1D8B755200070CB0 /* curveParams.h */; }; DC0BC66E1D8B755200070CB0 /* ECDSA_Profile.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6201D8B755200070CB0 /* ECDSA_Profile.h */; }; - DC0BC66F1D8B755200070CB0 /* ECDSA_Verify_Prefix.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6211D8B755200070CB0 /* ECDSA_Verify_Prefix.h */; }; DC0BC6701D8B755200070CB0 /* elliptic.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6221D8B755200070CB0 /* elliptic.c */; }; DC0BC6711D8B755200070CB0 /* elliptic.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6231D8B755200070CB0 /* elliptic.h */; }; DC0BC6721D8B755200070CB0 /* ellipticMeasure.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6241D8B755200070CB0 /* ellipticMeasure.h */; }; @@ -2109,13 +2739,9 @@ DC0BC6741D8B755200070CB0 /* ellipticProj.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6261D8B755200070CB0 /* ellipticProj.h */; }; DC0BC6751D8B755200070CB0 /* enc64.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6271D8B755200070CB0 /* enc64.c */; }; DC0BC6761D8B755200070CB0 /* enc64.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6281D8B755200070CB0 /* enc64.h */; }; - DC0BC6771D8B755200070CB0 /* engineNSA127.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6291D8B755200070CB0 /* engineNSA127.c */; }; DC0BC6781D8B755200070CB0 /* falloc.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC62A1D8B755200070CB0 /* falloc.c */; }; DC0BC6791D8B755200070CB0 /* falloc.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC62B1D8B755200070CB0 /* falloc.h */; }; - DC0BC67A1D8B755200070CB0 /* feeCipherFile.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC62C1D8B755200070CB0 /* feeCipherFile.h */; }; DC0BC67B1D8B755200070CB0 /* feeDebug.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC62D1D8B755200070CB0 /* feeDebug.h */; }; - DC0BC67C1D8B755200070CB0 /* feeDES.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC62E1D8B755200070CB0 /* feeDES.c */; }; - DC0BC67D1D8B755200070CB0 /* feeDES.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC62F1D8B755200070CB0 /* feeDES.h */; }; DC0BC67E1D8B755200070CB0 /* feeDigitalSignature.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6301D8B755200070CB0 /* feeDigitalSignature.c */; }; DC0BC67F1D8B755200070CB0 /* feeDigitalSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6311D8B755200070CB0 /* feeDigitalSignature.h */; }; DC0BC6801D8B755200070CB0 /* feeECDSA.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6321D8B755200070CB0 /* feeECDSA.c */; }; @@ -2136,11 +2762,6 @@ DC0BC68F1D8B755200070CB0 /* giantIntegers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6411D8B755200070CB0 /* giantIntegers.c */; }; DC0BC6901D8B755200070CB0 /* giantIntegers.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6421D8B755200070CB0 /* giantIntegers.h */; }; DC0BC6911D8B755200070CB0 /* giantPort_Generic.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6431D8B755200070CB0 /* giantPort_Generic.h */; }; - DC0BC6921D8B755200070CB0 /* giantPort_i486.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6441D8B755200070CB0 /* giantPort_i486.h */; }; - DC0BC6931D8B755200070CB0 /* giantPort_PPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6451D8B755200070CB0 /* giantPort_PPC.c */; }; - DC0BC6941D8B755200070CB0 /* giantPort_PPC.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6461D8B755200070CB0 /* giantPort_PPC.h */; }; - DC0BC6951D8B755200070CB0 /* giantPort_PPC_Gnu.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6471D8B755200070CB0 /* giantPort_PPC_Gnu.h */; }; - DC0BC6961D8B755200070CB0 /* giantPort_PPC_Gnu.s in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC6481D8B755200070CB0 /* giantPort_PPC_Gnu.s */; }; DC0BC6971D8B755200070CB0 /* giantPortCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC6491D8B755200070CB0 /* giantPortCommon.h */; }; DC0BC6981D8B755200070CB0 /* HmacSha1Legacy.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BC64A1D8B755200070CB0 /* HmacSha1Legacy.c */; }; DC0BC6991D8B755200070CB0 /* HmacSha1Legacy.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BC64B1D8B755200070CB0 /* HmacSha1Legacy.h */; }; @@ -2467,9 +3088,6 @@ DC0BCC171D8C64B600070CB0 /* testcert.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC081D8C64B500070CB0 /* testcert.h */; }; DC0BCC181D8C64B600070CB0 /* testpolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC091D8C64B500070CB0 /* testpolicy.h */; }; DC0BCC191D8C64B600070CB0 /* testpolicy.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC0A1D8C64B500070CB0 /* testpolicy.m */; }; - DC0BCC1A1D8C653600070CB0 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FC30AB1332DE9000802946 /* MobileKeyBag.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - DC0BCC291D8C684F00070CB0 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FC30AB1332DE9000802946 /* MobileKeyBag.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; - DC0BCD1D1D8C694700070CB0 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FC30AB1332DE9000802946 /* MobileKeyBag.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DC0BCD661D8C69A000070CB0 /* utilities_regressions.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCD491D8C697100070CB0 /* utilities_regressions.h */; }; DC0BCD671D8C69A000070CB0 /* su-05-cfwrappers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCD4A1D8C697100070CB0 /* su-05-cfwrappers.c */; }; DC0BCD681D8C69A000070CB0 /* su-07-debugging.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCD4B1D8C697100070CB0 /* su-07-debugging.c */; }; @@ -2486,8 +3104,6 @@ DC0BCD731D8C69A000070CB0 /* su-41-secdb-stress.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCD561D8C697100070CB0 /* su-41-secdb-stress.c */; }; DC0BCD751D8C6A1E00070CB0 /* iCloudKeychainTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC3A1D8C68CF00070CB0 /* iCloudKeychainTrace.c */; }; DC0BCD761D8C6A1E00070CB0 /* iCloudKeychainTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC3B1D8C68CF00070CB0 /* iCloudKeychainTrace.h */; }; - DC0BCD771D8C6A1E00070CB0 /* SecAKSWrappers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC3C1D8C68CF00070CB0 /* SecAKSWrappers.c */; }; - DC0BCD781D8C6A1E00070CB0 /* SecAKSWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC3D1D8C68CF00070CB0 /* SecAKSWrappers.h */; }; DC0BCD791D8C6A1E00070CB0 /* SecBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC3E1D8C68CF00070CB0 /* SecBuffer.c */; }; DC0BCD7A1D8C6A1E00070CB0 /* SecBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC3F1D8C68CF00070CB0 /* SecBuffer.h */; }; DC0BCD7B1D8C6A1E00070CB0 /* SecCoreCrypto.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC401D8C68CF00070CB0 /* SecCoreCrypto.c */; }; @@ -2539,24 +3155,26 @@ DC0BCDAF1D8C6A1F00070CB0 /* SecAppleAnchor.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC741D8C68CF00070CB0 /* SecAppleAnchor.c */; }; DC0BCDB01D8C6A1F00070CB0 /* SecAppleAnchorPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC751D8C68CF00070CB0 /* SecAppleAnchorPriv.h */; }; DC0BCDB21D8C6A1F00070CB0 /* SecInternalReleasePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC771D8C68CF00070CB0 /* SecInternalReleasePriv.h */; }; - DC0BCDB51D8C6A5B00070CB0 /* not_on_this_platorm.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */; }; + DC0BD4F121BB05F2006B9154 /* CKKSKeychainBackedKey.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BD4EF21BB05F2006B9154 /* CKKSKeychainBackedKey.h */; }; + DC0BD4F521BB060F006B9154 /* CKKSKeychainBackedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0BD4F021BB05F2006B9154 /* CKKSKeychainBackedKey.m */; }; + DC0BD4F621BB0610006B9154 /* CKKSKeychainBackedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0BD4F021BB05F2006B9154 /* CKKSKeychainBackedKey.m */; }; + DC0C343821FA7DEB00417D04 /* SecEscrowRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = DC90A4C021F27680001300EB /* SecEscrowRequest.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC0C343A21FA7DEB00417D04 /* SecEscrowRequest.h in Headers */ = {isa = PBXBuildFile; fileRef = DC90A4C021F27680001300EB /* SecEscrowRequest.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC0EF8F2208697C600AB9E95 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0EF8F1208697C600AB9E95 /* main.swift */; }; + DC0FA6B02291F63F00FE01C4 /* OctagonPendingFlag.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0FA6AE2291F63F00FE01C4 /* OctagonPendingFlag.h */; }; + DC0FA6B12291F63F00FE01C4 /* OctagonPendingFlag.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0FA6AF2291F63F00FE01C4 /* OctagonPendingFlag.m */; }; DC1002AF1D8E18870025549C /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD0677F1D8CDF19007602F1 /* libsecurity_codesigning.a */; }; DC1002D81D8E1A670025549C /* SecTask.h in Headers */ = {isa = PBXBuildFile; fileRef = 107226D10D91DB32003CF14F /* SecTask.h */; }; DC124DCD20059BA900BE8DAC /* OctagonControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC124DC220059B8700BE8DAC /* OctagonControlServer.m */; }; - DC124DCE20059BA900BE8DAC /* OctagonControlServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC124DC220059B8700BE8DAC /* OctagonControlServer.m */; }; + DC13A11D211D1982000A80BC /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; + DC13A11E211D1982000A80BC /* NSOperationCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447951F5766D200236DB4 /* NSOperationCategories.m */; }; DC14478A1F5764C600236DB4 /* CKKSResultOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447881F5764C600236DB4 /* CKKSResultOperation.h */; }; - DC14478B1F5764C600236DB4 /* CKKSResultOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447881F5764C600236DB4 /* CKKSResultOperation.h */; }; DC14478C1F5764C600236DB4 /* CKKSResultOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447891F5764C600236DB4 /* CKKSResultOperation.m */; }; - DC14478D1F5764C600236DB4 /* CKKSResultOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447891F5764C600236DB4 /* CKKSResultOperation.m */; }; DC1447961F5766D200236DB4 /* NSOperationCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447941F5766D200236DB4 /* NSOperationCategories.h */; }; - DC1447971F5766D200236DB4 /* NSOperationCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1447941F5766D200236DB4 /* NSOperationCategories.h */; }; - DC1447981F5766D200236DB4 /* NSOperationCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447951F5766D200236DB4 /* NSOperationCategories.m */; }; - DC1447991F5766D200236DB4 /* NSOperationCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1447951F5766D200236DB4 /* NSOperationCategories.m */; }; DC15F7661E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC15F7641E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h */; }; - DC15F7671E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC15F7641E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h */; }; DC15F7681E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC15F7651E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m */; }; - DC15F7691E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC15F7651E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m */; }; DC15F79C1E68EAD5003B9A40 /* CKKSTests+API.m in Sources */ = {isa = PBXBuildFile; fileRef = DC15F79B1E68EAD5003B9A40 /* CKKSTests+API.m */; }; + DC176232224C57D600BB9A6E /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; DC1785161D77895A00B50D50 /* oidsalg.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785111D77895A00B50D50 /* oidsalg.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785171D77895A00B50D50 /* oidsattr.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785121D77895A00B50D50 /* oidsattr.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785181D77895A00B50D50 /* SecAsn1Coder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785131D77895A00B50D50 /* SecAsn1Coder.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2613,8 +3231,6 @@ DC1785891D778B8000B50D50 /* SecCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785831D778B7F00B50D50 /* SecCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17858B1D778B8000B50D50 /* SecRequirement.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785851D778B8000B50D50 /* SecRequirement.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC17858C1D778B8000B50D50 /* SecStaticCode.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785861D778B8000B50D50 /* SecStaticCode.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC1785901D778B9D00B50D50 /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17858E1D778B9D00B50D50 /* CMSDecoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC1785911D778B9D00B50D50 /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17858F1D778B9D00B50D50 /* CMSEncoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785921D778BE400B50D50 /* SecAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 443381D918A3D81400215606 /* SecAccessControl.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785931D778BEE00B50D50 /* SecBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C696B3709BFA94F000CBC75 /* SecBase.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC1785941D778BF400B50D50 /* SecPolicy.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CBA0E860BB33C0000E72B55 /* SecPolicy.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -2638,21 +3254,6 @@ DC1786FA1D778F2500B50D50 /* SecTransformInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786F71D778F2500B50D50 /* SecTransformInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1786FC1D778F3D00B50D50 /* sslTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786FB1D778F3C00B50D50 /* sslTypes.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1786FE1D778F5000B50D50 /* SecureTransportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786FD1D778F5000B50D50 /* SecureTransportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787111D778FA900B50D50 /* SecCMS.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787001D778FA900B50D50 /* SecCMS.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787121D778FAA00B50D50 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787011D778FA900B50D50 /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787131D778FAA00B50D50 /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787021D778FA900B50D50 /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787141D778FAA00B50D50 /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787031D778FA900B50D50 /* SecCmsDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787151D778FAA00B50D50 /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787041D778FA900B50D50 /* SecCmsDigestContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787161D778FAA00B50D50 /* SecCmsDigestedData.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787051D778FA900B50D50 /* SecCmsDigestedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787171D778FAA00B50D50 /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787061D778FA900B50D50 /* SecCmsEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787181D778FAA00B50D50 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787071D778FA900B50D50 /* SecCmsEncryptedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787191D778FAA00B50D50 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787081D778FA900B50D50 /* SecCmsEnvelopedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC17871A1D778FAA00B50D50 /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787091D778FA900B50D50 /* SecCmsMessage.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC17871B1D778FAA00B50D50 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870A1D778FA900B50D50 /* SecCmsRecipientInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC17871C1D778FAA00B50D50 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870B1D778FA900B50D50 /* SecCmsSignedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC17871D1D778FAA00B50D50 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870C1D778FA900B50D50 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC17871E1D778FAA00B50D50 /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870D1D778FA900B50D50 /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC17871F1D778FAA00B50D50 /* tsaSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17870E1D778FA900B50D50 /* tsaSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787231D778FC900B50D50 /* mdspriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787221D778FC900B50D50 /* mdspriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787261D778FDE00B50D50 /* SecManifest.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787241D778FDE00B50D50 /* SecManifest.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787271D778FDE00B50D50 /* SecureDownloadInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787251D778FDE00B50D50 /* SecureDownloadInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -2676,7 +3277,6 @@ DC1787521D7790A500B50D50 /* SecCodeSigner.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787481D7790A500B50D50 /* SecCodeSigner.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787551D7790A500B50D50 /* SecRequirementPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17874B1D7790A500B50D50 /* SecRequirementPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787561D7790A500B50D50 /* SecStaticCodePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17874C1D7790A500B50D50 /* SecStaticCodePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC1787591D7790B600B50D50 /* CMSPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787581D7790B600B50D50 /* CMSPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17875C1D7790CE00B50D50 /* checkpw.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17875B1D7790CE00B50D50 /* checkpw.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17875F1D7790E500B50D50 /* AuthorizationPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17875D1D7790E500B50D50 /* AuthorizationPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC1787601D7790E500B50D50 /* AuthorizationTagsPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC17875E1D7790E500B50D50 /* AuthorizationTagsPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -2709,7 +3309,6 @@ DC1787851D7791CE00B50D50 /* SecTrustSettingsPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C12828C0BB4957D00985BB0 /* SecTrustSettingsPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC17890B1D77980500B50D50 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; DC1789131D7798B300B50D50 /* libDiagnosticMessagesClient.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789121D7798B300B50D50 /* libDiagnosticMessagesClient.dylib */; }; - DC1789151D77997F00B50D50 /* libOpenScriptingUtil.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789141D77997F00B50D50 /* libOpenScriptingUtil.dylib */; settings = {ATTRIBUTES = (Weak, ); }; }; DC1789171D77998700B50D50 /* libauto.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789161D77998700B50D50 /* libauto.dylib */; }; DC1789191D77998C00B50D50 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789181D77998C00B50D50 /* libbsm.dylib */; }; DC17891D1D77999700B50D50 /* libpam.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC17891C1D77999700B50D50 /* libpam.dylib */; }; @@ -2721,10 +3320,9 @@ DC1789281D779A0F00B50D50 /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; DC1789291D779A2800B50D50 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; }; DC17892A1D779A3200B50D50 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; - DC1789471D779AAF00B50D50 /* libsecurity_smime.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1784491D77869A00B50D50 /* libsecurity_smime.a */; }; DC1789A21D779DF400B50D50 /* SecBreadcrumb.c in Sources */ = {isa = PBXBuildFile; fileRef = DC1789A01D779DEE00B50D50 /* SecBreadcrumb.c */; }; DC1789A51D779E3B00B50D50 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC1789A41D779E3B00B50D50 /* dummy.cpp */; }; - DC1789E91D77A0F300B50D50 /* CloudKeychain.strings in CopyFiles */ = {isa = PBXBuildFile; fileRef = 53C0E1F1177FAC2C00F8A018 /* CloudKeychain.strings */; }; + DC1789E91D77A0F300B50D50 /* CloudKeychain.strings in Resources */ = {isa = PBXBuildFile; fileRef = 53C0E1F1177FAC2C00F8A018 /* CloudKeychain.strings */; }; DC178A1F1D77A1E700B50D50 /* cssm.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = DC178A0E1D77A1E700B50D50 /* cssm.mdsinfo */; }; DC178A201D77A1E700B50D50 /* csp_capabilities.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = DC178A0F1D77A1E700B50D50 /* csp_capabilities.mdsinfo */; }; DC178A211D77A1E700B50D50 /* csp_capabilities_common.mds in Resources */ = {isa = PBXBuildFile; fileRef = DC178A101D77A1E700B50D50 /* csp_capabilities_common.mds */; }; @@ -2748,69 +3346,32 @@ DC178A451D77A1F600B50D50 /* framework.sb in Resources */ = {isa = PBXBuildFile; fileRef = DC178A351D77A1F500B50D50 /* framework.sb */; }; DC178A471D77A1F600B50D50 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC178A381D77A1F500B50D50 /* InfoPlist.strings */; }; DC178A481D77A1F600B50D50 /* TimeStampingPrefs.plist in Resources */ = {isa = PBXBuildFile; fileRef = DC178A3A1D77A1F500B50D50 /* TimeStampingPrefs.plist */; }; - DC178A491D77A1F600B50D50 /* authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC178A3B1D77A1F500B50D50 /* authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings */; }; + DC178A491D77A1F600B50D50 /* authorization.dfr.prompts.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC178A3B1D77A1F500B50D50 /* authorization.dfr.prompts.strings */; }; DC178A4A1D77A1F600B50D50 /* authorization.buttons.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC178A3D1D77A1F500B50D50 /* authorization.buttons.strings */; }; DC178A4B1D77A1F600B50D50 /* authorization.prompts.strings in Resources */ = {isa = PBXBuildFile; fileRef = DC178A3F1D77A1F500B50D50 /* authorization.prompts.strings */; }; DC18F76F1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC18F76D1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h */; }; - DC18F7701E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC18F76D1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h */; }; DC18F7711E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC18F76E1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m */; }; - DC18F7721E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC18F76E1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m */; }; + DC19484C21812EC5007C2260 /* OTDeviceInformationAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = DC19484A21812EC5007C2260 /* OTDeviceInformationAdapter.h */; }; + DC19484D21812EC5007C2260 /* OTDeviceInformationAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC19484B21812EC5007C2260 /* OTDeviceInformationAdapter.m */; }; DC1DA65E1E4554620094CE7F /* CKKSScanLocalItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1DA65C1E4554620094CE7F /* CKKSScanLocalItemsOperation.h */; }; - DC1DA65F1E4554620094CE7F /* CKKSScanLocalItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1DA65C1E4554620094CE7F /* CKKSScanLocalItemsOperation.h */; }; DC1DA6681E4555D80094CE7F /* CKKSScanLocalItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1DA6671E4555D80094CE7F /* CKKSScanLocalItemsOperation.m */; }; - DC1DA6691E4555D80094CE7F /* CKKSScanLocalItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1DA6671E4555D80094CE7F /* CKKSScanLocalItemsOperation.m */; }; DC1ED8C11DD5197E002BDCFA /* CKKSItemEncrypter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8BA1DD51883002BDCFA /* CKKSItemEncrypter.m */; }; DC1ED8C61DD55476002BDCFA /* CKKS.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8C51DD55476002BDCFA /* CKKS.m */; }; + DC221BAB2267E2A60068DBCF /* OTUpdateTPHOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC221BA92267E2A60068DBCF /* OTUpdateTPHOperation.h */; }; + DC221BAC2267E2A70068DBCF /* OTUpdateTPHOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC221BAA2267E2A60068DBCF /* OTUpdateTPHOperation.m */; }; DC222C321E0240D300B09171 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; DC222C351E02418100B09171 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; DC222C361E02419B00B09171 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; - DC222C3A1E034D1F00B09171 /* CKKSItemEncrypter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8BA1DD51883002BDCFA /* CKKSItemEncrypter.m */; }; - DC222C3B1E034D1F00B09171 /* SOSChangeTracker.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D4F1D8085F200865A7C /* SOSChangeTracker.c */; }; - DC222C3D1E034D1F00B09171 /* SOSEngine.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D561D8085F200865A7C /* SOSEngine.c */; }; - DC222C401E034D1F00B09171 /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; }; - DC222C411E034D1F00B09171 /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; }; - DC222C421E034D1F00B09171 /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; }; - DC222C431E034D1F00B09171 /* SecItemBackupServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9C1D8085D800865A7C /* SecItemBackupServer.c */; }; - DC222C441E034D1F00B09171 /* SecItemDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C941D8085D800865A7C /* SecItemDataSource.c */; }; - DC222C451E034D1F00B09171 /* CKKSIncomingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B3B1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m */; }; - DC222C461E034D1F00B09171 /* SecItemDb.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C961D8085D800865A7C /* SecItemDb.c */; }; - DC222C471E034D1F00B09171 /* SecItemSchema.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C981D8085D800865A7C /* SecItemSchema.c */; }; - DC222C481E034D1F00B09171 /* SecItemServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9A1D8085D800865A7C /* SecItemServer.c */; }; - DC222C491E034D1F00B09171 /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; - DC222C4A1E034D1F00B09171 /* SecLogSettingsServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CAE1D8085D800865A7C /* SecLogSettingsServer.m */; }; - DC222C4D1E034D1F00B09171 /* CKKSOutgoingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9B7AE41DCBF604004E9385 /* CKKSOutgoingQueueEntry.m */; }; - DC222C4E1E034D1F00B09171 /* CKKS.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1ED8C51DD55476002BDCFA /* CKKS.m */; }; - DC222C501E034D1F00B09171 /* SecOTRRemote.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB41D8085D800865A7C /* SecOTRRemote.m */; }; - DC222C511E034D1F00B09171 /* CKKSItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCDCCB8E1DF7B8D4006E840E /* CKKSItem.m */; }; - DC222C541E034D1F00B09171 /* CKKSSQLDatabaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DC797E131DD3F88300CC9E42 /* CKKSSQLDatabaseObject.m */; }; - DC222C571E034D1F00B09171 /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; - DC222C5A1E034D1F00B09171 /* iCloudTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB31D8085D800865A7C /* iCloudTrace.c */; }; - DC222C5D1E034D1F00B09171 /* CKKSMirrorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B2E1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m */; }; - DC222C611E034D1F00B09171 /* swcagent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78EA01D80860C00865A7C /* swcagent_client.c */; }; - DC222C621E034D1F00B09171 /* CKKSZoneStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B371DEFADB500A3DAFA /* CKKSZoneStateEntry.m */; }; - DC222C651E034D1F00B09171 /* SOSChangeTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D501D8085F200865A7C /* SOSChangeTracker.h */; }; - DC222C661E034D1F00B09171 /* SOSEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D571D8085F200865A7C /* SOSEngine.h */; }; - DC222C671E034D1F00B09171 /* SecDbKeychainItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C911D8085D800865A7C /* SecDbKeychainItem.h */; }; - DC222C681E034D1F00B09171 /* SecDbQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C931D8085D800865A7C /* SecDbQuery.h */; }; - DC222C691E034D1F00B09171 /* CKKSMirrorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B2C1DEF9DF000A3DAFA /* CKKSMirrorEntry.h */; }; - DC222C6A1E034D1F00B09171 /* CKKSZoneStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B361DEFADB500A3DAFA /* CKKSZoneStateEntry.h */; }; - DC222C6B1E034D1F00B09171 /* SecItemDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C951D8085D800865A7C /* SecItemDataSource.h */; }; - DC222C6C1E034D1F00B09171 /* CKKSIncomingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B3A1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h */; }; - DC222C6D1E034D1F00B09171 /* SecItemDb.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C971D8085D800865A7C /* SecItemDb.h */; }; - DC222C6E1E034D1F00B09171 /* SecItemSchema.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C991D8085D800865A7C /* SecItemSchema.h */; }; - DC222C6F1E034D1F00B09171 /* SecKeybagSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C9F1D8085D800865A7C /* SecKeybagSupport.h */; }; - DC222C701E034D1F00B09171 /* iCloudTrace.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78CB21D8085D800865A7C /* iCloudTrace.h */; }; - DC222C711E034D1F00B09171 /* CKKSOutgoingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9B7AE61DCBF651004E9385 /* CKKSOutgoingQueueEntry.h */; }; - DC222C731E034D1F00B09171 /* CKKSItem.h in Headers */ = {isa = PBXBuildFile; fileRef = DCDCCB8D1DF7B8D4006E840E /* CKKSItem.h */; }; - DC222C7A1E034EF700B09171 /* libsecurityd_ios_NO_AKS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; }; DC222C8A1E089BAE00B09171 /* CKKSSQLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC222C891E089BAE00B09171 /* CKKSSQLTests.m */; }; DC222CA81E08A7D900B09171 /* CloudKitMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC222CA71E08A7D900B09171 /* CloudKitMockXCTest.m */; }; DC2353291ECA658300D7C1BE /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; DC23532F1ECA658400D7C1BE /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; - DC2353301ECA658900D7C1BE /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC2353311ECA658B00D7C1BE /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + DC2353301ECA658900D7C1BE /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC2353311ECA658B00D7C1BE /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; DC2353321ECA659000D7C1BE /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DC2353331ECA659000D7C1BE /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + DC26666A21CAC32700F19960 /* OTControlCLI.m in Sources */ = {isa = PBXBuildFile; fileRef = DC26666921CAC32700F19960 /* OTControlCLI.m */; }; + DC26666C21CAC97000F19960 /* OTControlCLI.m in Sources */ = {isa = PBXBuildFile; fileRef = DC26666921CAC32700F19960 /* OTControlCLI.m */; }; DC2670F21F3E6EC500816EED /* debugging.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC531D8C68CF00070CB0 /* debugging.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC2670F51F3E711400816EED /* SOSAccountCloudParameters.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D1A1D8085F200865A7C /* SOSAccountCloudParameters.m */; }; DC2670F61F3E714000816EED /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; @@ -2820,35 +3381,66 @@ DC2670FC1F3E72C400816EED /* SOSCircleDer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D341D8085F200865A7C /* SOSCircleDer.h */; }; DC2671001F3E766E00816EED /* SecOTRSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFB15AFB73800B9D400 /* SecOTRSession.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC2671071F3E8A0900816EED /* SecECKey.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CD3BA601106FF4D00BE8B75 /* SecECKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC26710E1F3E932D00816EED /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DC26710E1F3E932D00816EED /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; + DC27C3C120EAD9C300F7839C /* OctagonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC27C3C020EAD9C300F7839C /* OctagonTests.swift */; }; + DC27C3C920EADEE700F7839C /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; + DC27C3CA20EADF1700F7839C /* CloudKitKeychainSyncingTestsBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CA4EBF2202B8D1D002B1D96 /* CloudKitKeychainSyncingTestsBase.m */; }; + DC27C3CB20EADF3500F7839C /* CloudKitKeychainSyncingMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */; }; + DC27C3CE20EAFE9C00F7839C /* CloudKitMockXCTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC222CA71E08A7D900B09171 /* CloudKitMockXCTest.m */; }; + DC2819B922F8F6FE007829F5 /* OctagonTests+DeviceList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC2819B822F8F6FE007829F5 /* OctagonTests+DeviceList.swift */; }; + DC2B757621F2A270003C9356 /* SecEscrowRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC90A4C121F27680001300EB /* SecEscrowRequest.m */; }; + DC2B757721F2A272003C9356 /* SecEscrowRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = DC90A4C121F27680001300EB /* SecEscrowRequest.m */; }; + DC2B9A5223147A3800D4C79D /* TPMachineID.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2B9A5023147A3800D4C79D /* TPMachineID.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DC2B9A5323147A3800D4C79D /* TPMachineID.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2B9A5123147A3800D4C79D /* TPMachineID.m */; }; DC2C5F4B1F0D935200FEBDA7 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC2C5F511F0D935300FEBDA7 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC2C5F5D1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */; }; - DC2C5F5E1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */; }; DC2C5F601F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */; }; - DC2C5F611F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */ = {isa = PBXBuildFile; fileRef = DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */; }; DC2D438F1F0EEC2A0005D382 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; DC2D43951F0EEC300005D382 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; + DC2FA71120E5770400DB7518 /* OTClique.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C2F336A20DD643B0031A92D /* OTClique.m */; }; + DC2FA72520E57AB500DB7518 /* SOSPeerInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D631D8085F200865A7C /* SOSPeerInfo.m */; }; + DC2FA72A20E57BFD00DB7518 /* SOSAccountTrust.m in Sources */ = {isa = PBXBuildFile; fileRef = CD31F8601DCD4C1400414B46 /* SOSAccountTrust.m */; }; + DC2FA72B20E57C1000DB7518 /* SOSAccountTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = CD31F8611DCD4C1400414B46 /* SOSAccountTrust.h */; }; + DC311E682124A9E1002F5EAE /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DC311E7A2124B8EF002F5EAE /* aks_real_witness.h in Headers */ = {isa = PBXBuildFile; fileRef = DC311E782124B8EF002F5EAE /* aks_real_witness.h */; }; + DC311E7B2124B8EF002F5EAE /* aks_real_witness.c in Sources */ = {isa = PBXBuildFile; fileRef = DC311E792124B8EF002F5EAE /* aks_real_witness.c */; }; DC337B1F1EA04E2100B3A1F0 /* SecBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 18351B8F14CB65870097860E /* SecBase64.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC340C54208E828F004D7EEC /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; DC3502B81E0208BE00BC0587 /* CKKSTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502B71E0208BE00BC0587 /* CKKSTests.m */; }; - DC3502C51E020D5100BC0587 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DC3502C51E020D5100BC0587 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; - DC3502CF1E020E2900BC0587 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC3502D21E02113900BC0587 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; - DC3502D31E02115200BC0587 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; - DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - DC3502E21E0212D100BC0587 /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; }; DC3502E31E0212E600BC0587 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; - DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; DC3502E71E0214C800BC0587 /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; DC3502E91E02172C00BC0587 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; }; + DC36895821235F23003A3735 /* SecAKSWrappers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC3C1D8C68CF00070CB0 /* SecAKSWrappers.c */; }; + DC36895921235F2A003A3735 /* SecAKSWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = DC0BCC3D1D8C68CF00070CB0 /* SecAKSWrappers.h */; }; + DC36896221235F99003A3735 /* mockaks.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2E4202DFE7F003F34A0 /* mockaks.m */; }; + DC36896321235FA2003A3735 /* mockaks.h in Headers */ = {isa = PBXBuildFile; fileRef = EB49B303202FB8DE003F34A0 /* mockaks.h */; }; + DC372C8C22B4501900AB9F41 /* SecCoreAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = EBE8258F2193353300102304 /* SecCoreAnalytics.m */; }; + DC372C8D22B4501900AB9F41 /* SecCoreAnalytics.m in Sources */ = {isa = PBXBuildFile; fileRef = EBE8258F2193353300102304 /* SecCoreAnalytics.m */; }; + DC372C8E22B4509100AB9F41 /* SecCoreAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = EBE8258E2193353300102304 /* SecCoreAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC372C8F22B4509200AB9F41 /* SecCoreAnalytics.h in Headers */ = {isa = PBXBuildFile; fileRef = EBE8258E2193353300102304 /* SecCoreAnalytics.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC378B2D1DEF9DF000A3DAFA /* CKKSMirrorEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B2C1DEF9DF000A3DAFA /* CKKSMirrorEntry.h */; }; DC378B2F1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B2E1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m */; }; DC378B381DEFADB500A3DAFA /* CKKSZoneStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B361DEFADB500A3DAFA /* CKKSZoneStateEntry.h */; }; DC378B391DEFADB500A3DAFA /* CKKSZoneStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B371DEFADB500A3DAFA /* CKKSZoneStateEntry.m */; }; DC378B3C1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC378B3A1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h */; }; DC378B3D1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC378B3B1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m */; }; + DC391F8A21BF222500772585 /* CKKSKeychainBackedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0BD4F021BB05F2006B9154 /* CKKSKeychainBackedKey.m */; }; + DC391F8C21BF222B00772585 /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5A01E721BB428500D87AB9 /* CKKSTLKShare.m */; }; + DC391F8D21BF244000772585 /* CKKSSIV.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */; }; + DC391F8E21BF274600772585 /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; + DC391F8F21BF284D00772585 /* CKKSSerializedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3261F858D3E00C8AAC8 /* CKKSSerializedKey.m */; }; + DC391F9D21BF2F8100772585 /* CKKSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DC391F9921BF2F4B00772585 /* CKKSConstants.m */; }; + DC391F9E21BF2F8700772585 /* CKKSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DC391F9921BF2F4B00772585 /* CKKSConstants.m */; }; + DC391F9F21BF2F8700772585 /* CKKSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DC391F9921BF2F4B00772585 /* CKKSConstants.m */; }; + DC391FA621C04D1500772585 /* OctagonPeerKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC391FA521C04D1500772585 /* OctagonPeerKeys.swift */; }; + DC391FA721C04D6800772585 /* OctagonPeerKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC391FA521C04D1500772585 /* OctagonPeerKeys.swift */; }; + DC391FA821C04DAE00772585 /* OctagonPeerKeys.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC391FA521C04D1500772585 /* OctagonPeerKeys.swift */; }; + DC391FAE21C1903E00772585 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DC3A4B4B1D91E30400E46D4A /* sec_xdr.h in Headers */ = {isa = PBXBuildFile; fileRef = DC6A825A1D87732E00418608 /* sec_xdr.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC3A4B531D91E8EB00E46D4A /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */; }; DC3A4B641D91EADC00E46D4A /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC3A4B621D91EAC500E46D4A /* main.cpp */; }; @@ -2861,6 +3453,37 @@ DC3A81D61D99D57F000C7419 /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; }; DC3A81D71D99D58A000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3A81D41D99D567000C7419 /* libcoretls_cfhelpers.dylib */; }; DC3A81EC1D99F568000C7419 /* libcoretls.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CFC029B1D41650700E6283B /* libcoretls.dylib */; }; + DC3AA2782097DF70007CA68A /* readline.c in Sources */ = {isa = PBXBuildFile; fileRef = DC65E7BE1D8CBB1500152EF0 /* readline.c */; }; + DC3AA2792097DF71007CA68A /* readline.c in Sources */ = {isa = PBXBuildFile; fileRef = DC65E7BE1D8CBB1500152EF0 /* readline.c */; }; + DC3AA27A2097DF84007CA68A /* not_on_this_platorm.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */; }; + DC3AA27B2097DF85007CA68A /* not_on_this_platorm.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */; }; + DC3AA27D2097E206007CA68A /* verify_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E191D8085FC00865A7C /* verify_cert.c */; }; + DC3AA27E2097E207007CA68A /* verify_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E191D8085FC00865A7C /* verify_cert.c */; }; + DC3AA27F2097E20A007CA68A /* keychain_util.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1A1D8085FC00865A7C /* keychain_util.c */; }; + DC3AA2802097E20B007CA68A /* keychain_util.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1A1D8085FC00865A7C /* keychain_util.c */; }; + DC3AA2812097E216007CA68A /* add_internet_password.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1C1D8085FC00865A7C /* add_internet_password.c */; }; + DC3AA2822097E218007CA68A /* add_internet_password.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1C1D8085FC00865A7C /* add_internet_password.c */; }; + DC3AA2832097E21C007CA68A /* log_control.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1D1D8085FC00865A7C /* log_control.c */; }; + DC3AA2842097E21D007CA68A /* log_control.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1D1D8085FC00865A7C /* log_control.c */; }; + DC3AA2852097E22A007CA68A /* codesign.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1E1D8085FC00865A7C /* codesign.c */; }; + DC3AA2862097E22A007CA68A /* codesign.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1E1D8085FC00865A7C /* codesign.c */; }; + DC3AA2872097E231007CA68A /* keychain_add.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1F1D8085FC00865A7C /* keychain_add.c */; }; + DC3AA2882097E232007CA68A /* keychain_add.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1F1D8085FC00865A7C /* keychain_add.c */; }; + DC3AA2892097E23A007CA68A /* keychain_find.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E201D8085FC00865A7C /* keychain_find.m */; }; + DC3AA28A2097E23B007CA68A /* keychain_find.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E201D8085FC00865A7C /* keychain_find.m */; }; + DC3AA28B2097E23F007CA68A /* pkcs12_util.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E221D8085FC00865A7C /* pkcs12_util.c */; }; + DC3AA28C2097E23F007CA68A /* pkcs12_util.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E221D8085FC00865A7C /* pkcs12_util.c */; }; + DC3AA28D2097E24B007CA68A /* scep.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E231D8085FC00865A7C /* scep.c */; }; + DC3AA28E2097E24C007CA68A /* scep.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E231D8085FC00865A7C /* scep.c */; }; + DC3AA28F2097E253007CA68A /* show_certificates.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E251D8085FC00865A7C /* show_certificates.c */; }; + DC3AA2902097E254007CA68A /* show_certificates.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E251D8085FC00865A7C /* show_certificates.c */; }; + DC3AA2912097E25B007CA68A /* trust_update.m in Sources */ = {isa = PBXBuildFile; fileRef = D453C38A1FEC669300DE349B /* trust_update.m */; }; + DC3AA2922097E25C007CA68A /* trust_update.m in Sources */ = {isa = PBXBuildFile; fileRef = D453C38A1FEC669300DE349B /* trust_update.m */; }; + DC3AA2932097E263007CA68A /* spc.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E261D8085FC00865A7C /* spc.c */; }; + DC3AA2942097E264007CA68A /* spc.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E261D8085FC00865A7C /* spc.c */; }; + DC3AF52C2229E6C0006577E8 /* CKKSListenerCollection.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3AF52A2229E6C0006577E8 /* CKKSListenerCollection.h */; }; + DC3AF52D2229E6C0006577E8 /* CKKSListenerCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3AF52B2229E6C0006577E8 /* CKKSListenerCollection.m */; }; + DC3AF52F2229E770006577E8 /* CKKSListenerCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3AF52B2229E6C0006577E8 /* CKKSListenerCollection.m */; }; DC3C72E21D8374D600F6A832 /* SecureTransportPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786FD1D778F5000B50D50 /* SecureTransportPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C72E91D83776B00F6A832 /* SOSBackupSliceKeyBag.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; DC3C72EB1D83777600F6A832 /* SOSCloudCircle.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */; }; @@ -2882,11 +3505,10 @@ DC3C7AB71D838C5C00F6A832 /* secasn1t.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787681D77911D00B50D50 /* secasn1t.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C7AB81D838C6F00F6A832 /* oidsalg.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785111D77895A00B50D50 /* oidsalg.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC3C7ABA1D838C9F00F6A832 /* sslTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1786FB1D778F3C00B50D50 /* sslTypes.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DC3C7C901D83957F00F6A832 /* NSFileHandle+Formatting.m in Sources */ = {isa = PBXBuildFile; fileRef = E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */; }; DC3D748C1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */; }; - DC3D748D1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */; }; DC3D748E1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */; }; - DC3D748F1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */; }; + DC3E18C82125015300073D80 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DC3E18EB2125FB8700073D80 /* libaks_mock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC36895E21235F42003A3735 /* libaks_mock.a */; }; DC4268F61E82036F002B7110 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; DC4268FC1E820370002B7110 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; DC4268FE1E820371002B7110 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; @@ -2895,22 +3517,36 @@ DC4269011E82038D002B7110 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; DC4269041E82EDAC002B7110 /* SecItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269031E82EDAC002B7110 /* SecItem.m */; }; DC4269051E82EDC4002B7110 /* SecItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269031E82EDAC002B7110 /* SecItem.m */; }; - DC4269081E82FD8B002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC4269091E82FD8C002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC42690C1E82FD9A002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC42690D1E82FD9B002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC42690F1E82FD9C002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC4269101E82FD9F002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC4269111E82FDA0002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; - DC4269121E82FDA1002B7110 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + DC4269081E82FD8B002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC4269091E82FD8C002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC42690C1E82FD9A002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC42690D1E82FD9B002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC42690F1E82FD9C002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC4269101E82FD9F002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC4269111E82FDA0002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC4269121E82FDA1002B7110 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC45D43D22EB619D00CEB6B7 /* OctagonStateMachineObservers.h in Headers */ = {isa = PBXBuildFile; fileRef = DC45D43B22EB619D00CEB6B7 /* OctagonStateMachineObservers.h */; }; + DC45D43E22EB619D00CEB6B7 /* OctagonStateMachineObservers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC45D43C22EB619D00CEB6B7 /* OctagonStateMachineObservers.m */; }; + DC4A76A02212676D006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76A3221267D4006F2D8F /* EscrowRequestServerHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4A76A2221267D4006F2D8F /* EscrowRequestServerHelpers.m */; }; + DC4A76A5221268A6006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76A62212691F006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76A72212694F006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76A822126959006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76AA22126993006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76AB221269B8006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC4A76A92212698B006F2D8F /* CloudServices.framework */; }; + DC4A76AC221269E4006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76AD22126A17006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DC4A76AE22126C49006F2D8F /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; DC4DB1501E24692100CD6769 /* CKKSKey.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4DB14E1E24692100CD6769 /* CKKSKey.h */; }; - DC4DB1511E24692100CD6769 /* CKKSKey.h in Headers */ = {isa = PBXBuildFile; fileRef = DC4DB14E1E24692100CD6769 /* CKKSKey.h */; }; DC4DB1521E24692100CD6769 /* CKKSKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4DB14F1E24692100CD6769 /* CKKSKey.m */; }; - DC4DB1531E24692100CD6769 /* CKKSKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4DB14F1E24692100CD6769 /* CKKSKey.m */; }; DC4DB15F1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4DB15E1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m */; }; DC4DB1691E26E99E00CD6769 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DC4DB16A1E26E9F900CD6769 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DC4EA5961E70A237008840B4 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; + DC5060EB20E2D88300925005 /* OTCuttlefishContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5060E920E2D88300925005 /* OTCuttlefishContext.h */; }; + DC5060ED20E2D88300925005 /* OTCuttlefishContext.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5060EA20E2D88300925005 /* OTCuttlefishContext.m */; }; + DC5060F520E2DB9700925005 /* OTCuttlefishContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5060F420E2DB9700925005 /* OTCuttlefishContextTests.m */; }; DC52E7C41D80BCAD00B0A59C /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; }; DC52E7C51D80BCB300B0A59C /* swcagent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78EA01D80860C00865A7C /* swcagent_client.c */; }; DC52E7CB1D80BCD800B0A59C /* SecItemBackupServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9C1D8085D800865A7C /* SecItemBackupServer.c */; }; @@ -2980,29 +3616,8 @@ DC52E9331D80C4E500B0A59C /* SOSDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D531D8085F200865A7C /* SOSDataSource.h */; }; DC52E9381D80C50800B0A59C /* SOSPeer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D5D1D8085F200865A7C /* SOSPeer.h */; }; DC52EA9C1D80CC8300B0A59C /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; - DC52EA9D1D80CC9700B0A59C /* syncbubble.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA921D80CC2A00B0A59C /* syncbubble.m */; }; - DC52EA9E1D80CC9B00B0A59C /* leaks.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA931D80CC2A00B0A59C /* leaks.c */; }; - DC52EA9F1D80CCA100B0A59C /* digest_calc.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA8F1D80CC2A00B0A59C /* digest_calc.c */; }; - DC52EAA01D80CCA700B0A59C /* whoami.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA911D80CC2A00B0A59C /* whoami.m */; }; - DC52EAA11D80CCAC00B0A59C /* SecurityTool.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA981D80CC2A00B0A59C /* SecurityTool.c */; }; - DC52EAA21D80CCB200B0A59C /* keychain_backup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E211D8085FC00865A7C /* keychain_backup.c */; }; - DC52EAA31D80CCC300B0A59C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - DC52EBC31D80CEBA00B0A59C /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; DC52EBC41D80CEBA00B0A59C /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; DC52EBC51D80CEBA00B0A59C /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; - DC52EBD01D80CEF100B0A59C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; - DC52EC141D80CF0500B0A59C /* spc.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E261D8085FC00865A7C /* spc.c */; }; - DC52EC151D80CF0B00B0A59C /* show_certificates.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E251D8085FC00865A7C /* show_certificates.c */; }; - DC52EC161D80CF3B00B0A59C /* scep.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E231D8085FC00865A7C /* scep.c */; }; - DC52EC171D80CF4200B0A59C /* pkcs12_util.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E221D8085FC00865A7C /* pkcs12_util.c */; }; - DC52EC181D80CF4700B0A59C /* log_control.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1D1D8085FC00865A7C /* log_control.c */; }; - DC52EC191D80CF4C00B0A59C /* keychain_find.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E201D8085FC00865A7C /* keychain_find.m */; }; - DC52EC1A1D80CF5100B0A59C /* keychain_add.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1F1D8085FC00865A7C /* keychain_add.c */; }; - DC52EC1B1D80CF5600B0A59C /* codesign.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1E1D8085FC00865A7C /* codesign.c */; }; - DC52EC1C1D80CF5D00B0A59C /* add_internet_password.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1C1D8085FC00865A7C /* add_internet_password.c */; }; - DC52EC1D1D80CF6200B0A59C /* keychain_util.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E1A1D8085FC00865A7C /* keychain_util.c */; }; - DC52EC1E1D80CF6700B0A59C /* verify_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E191D8085FC00865A7C /* verify_cert.c */; }; - DC52EC2F1D80CFB200B0A59C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; DC52EC361D80CFD000B0A59C /* keychain_sync.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D971D8085F200865A7C /* keychain_sync.m */; }; DC52EC371D80CFD400B0A59C /* keychain_sync_test.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D991D8085F200865A7C /* keychain_sync_test.m */; }; DC52EC381D80CFDB00B0A59C /* secToolFileIO.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D931D8085F200865A7C /* secToolFileIO.c */; }; @@ -3012,8 +3627,6 @@ DC52EC4E1D80D01F00B0A59C /* swcagent_client.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78EA01D80860C00865A7C /* swcagent_client.c */; }; DC52EC4F1D80D02400B0A59C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; DC52EC5D1D80D06300B0A59C /* SecLogging.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E651D8085FC00865A7C /* SecLogging.c */; }; - DC52EC6B1D80D0E300B0A59C /* IDSFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC6A1D80D0E300B0A59C /* IDSFoundation.framework */; }; - DC52EC6C1D80D0E800B0A59C /* IDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD744683195A00BB00FB01C0 /* IDS.framework */; }; DC52EC6D1D80D0F100B0A59C /* sc-31-peerinfo-simplefuzz.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D001D8085F200865A7C /* sc-31-peerinfo-simplefuzz.c */; }; DC52EC6E1D80D0F700B0A59C /* SOSTestDevice.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D0E1D8085F200865A7C /* SOSTestDevice.c */; }; DC52EC6F1D80D11800B0A59C /* sc-25-soskeygen.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CFE1D8085F200865A7C /* sc-25-soskeygen.c */; }; @@ -3074,9 +3687,6 @@ DC52ED9E1D80D4ED00B0A59C /* secd-95-escrow-persistence.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C741D8085D800865A7C /* secd-95-escrow-persistence.m */; }; DC52ED9F1D80D4F200B0A59C /* SOSTransportTestTransports.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C7C1D8085D800865A7C /* SOSTransportTestTransports.m */; }; DC52EDA01D80D4F700B0A59C /* sd-10-policytree.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C3D1D8085D800865A7C /* sd-10-policytree.m */; }; - DC52EDA11D80D4FC00B0A59C /* IDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD744683195A00BB00FB01C0 /* IDS.framework */; }; - DC52EDAC1D80D58400B0A59C /* IDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD744683195A00BB00FB01C0 /* IDS.framework */; }; - DC52EDB21D80D59700B0A59C /* IDSFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC6A1D80D0E300B0A59C /* IDSFoundation.framework */; }; DC52EDB51D80D5C500B0A59C /* secd-03-corrupted-items.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C391D8085D800865A7C /* secd-03-corrupted-items.m */; }; DC52EDB61D80D5C500B0A59C /* secd-04-corrupted-items.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C3A1D8085D800865A7C /* secd-04-corrupted-items.m */; }; DC52EDB71D80D5C500B0A59C /* secd-05-corrupted-items.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C3B1D8085D800865A7C /* secd-05-corrupted-items.m */; }; @@ -3085,7 +3695,6 @@ DC52EDBD1D80D5C500B0A59C /* secd-20-keychain_upgrade.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C411D8085D800865A7C /* secd-20-keychain_upgrade.m */; }; DC52EDBE1D80D5C500B0A59C /* secd-21-transmogrify.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C421D8085D800865A7C /* secd-21-transmogrify.m */; }; DC52EDBF1D80D5C500B0A59C /* secd-30-keychain-upgrade.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C431D8085D800865A7C /* secd-30-keychain-upgrade.m */; }; - DC52EDC01D80D5C500B0A59C /* secd-31-keychain-bad.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C441D8085D800865A7C /* secd-31-keychain-bad.m */; }; DC52EDC11D80D5C500B0A59C /* secd-31-keychain-unreadable.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C451D8085D800865A7C /* secd-31-keychain-unreadable.m */; }; DC52EDC21D80D5C500B0A59C /* secd-32-restore-bad-backup.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C461D8085D800865A7C /* secd-32-restore-bad-backup.m */; }; DC52EDC31D80D5C500B0A59C /* secd-33-keychain-ctk.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C471D8085D800865A7C /* secd-33-keychain-ctk.m */; }; @@ -3133,40 +3742,30 @@ DC52EDF81D80D65C00B0A59C /* SOSTestDevice.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D0E1D8085F200865A7C /* SOSTestDevice.c */; }; DC52EDF91D80D66000B0A59C /* SOSTestDataSource.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D0C1D8085F200865A7C /* SOSTestDataSource.c */; }; DC52EDFA1D80D66600B0A59C /* SOSRegressionUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D0A1D8085F200865A7C /* SOSRegressionUtilities.m */; }; - DC52EE421D80D71900B0A59C /* si-20-sectrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DBB1D8085FC00865A7C /* si-20-sectrust.c */; }; DC52EE441D80D71900B0A59C /* si-21-sectrust-asr.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DBD1D8085FC00865A7C /* si-21-sectrust-asr.c */; }; DC52EE451D80D71900B0A59C /* si-22-sectrust-iap.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DBE1D8085FC00865A7C /* si-22-sectrust-iap.c */; }; DC52EE471D80D71900B0A59C /* si-23-sectrust-ocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC01D8085FC00865A7C /* si-23-sectrust-ocsp.c */; }; DC52EE481D80D71900B0A59C /* si-24-sectrust-digicert-malaysia.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC11D8085FC00865A7C /* si-24-sectrust-digicert-malaysia.c */; }; DC52EE491D80D71900B0A59C /* si-24-sectrust-diginotar.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC21D8085FC00865A7C /* si-24-sectrust-diginotar.c */; }; DC52EE4A1D80D71900B0A59C /* si-24-sectrust-itms.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC31D8085FC00865A7C /* si-24-sectrust-itms.c */; }; - DC52EE4B1D80D71900B0A59C /* si-24-sectrust-nist.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC41D8085FC00865A7C /* si-24-sectrust-nist.c */; }; DC52EE4C1D80D71900B0A59C /* si-24-sectrust-passbook.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC51D8085FC00865A7C /* si-24-sectrust-passbook.c */; }; DC52EE4D1D80D71900B0A59C /* si-26-sectrust-copyproperties.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC61D8085FC00865A7C /* si-26-sectrust-copyproperties.c */; }; DC52EE4E1D80D71900B0A59C /* si-27-sectrust-exceptions.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC71D8085FC00865A7C /* si-27-sectrust-exceptions.c */; }; DC52EE4F1D80D71900B0A59C /* si-28-sectrustsettings.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DC81D8085FC00865A7C /* si-28-sectrustsettings.m */; }; - DC52EE511D80D73800B0A59C /* si-15-certificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DB71D8085FC00865A7C /* si-15-certificate.c */; }; - DC52EE521D80D73800B0A59C /* si-16-ec-certificate.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DB81D8085FC00865A7C /* si-16-ec-certificate.c */; }; DC52EE531D80D73800B0A59C /* si-44-seckey-gen.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD31D8085FC00865A7C /* si-44-seckey-gen.m */; }; DC52EE541D80D73800B0A59C /* si-44-seckey-rsa.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD41D8085FC00865A7C /* si-44-seckey-rsa.m */; }; DC52EE551D80D73800B0A59C /* si-44-seckey-ec.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD51D8085FC00865A7C /* si-44-seckey-ec.m */; }; DC52EE561D80D73800B0A59C /* si-44-seckey-ies.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DD61D8085FC00865A7C /* si-44-seckey-ies.m */; }; DC52EE571D80D73800B0A59C /* si-67-sectrust-blocklist.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DF71D8085FC00865A7C /* si-67-sectrust-blocklist.c */; }; DC52EE581D80D73800B0A59C /* si-70-sectrust-unified.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DFA1D8085FC00865A7C /* si-70-sectrust-unified.c */; }; - DC52EE591D80D73800B0A59C /* si-82-seccertificate-ct.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E031D8085FC00865A7C /* si-82-seccertificate-ct.c */; }; DC52EE5A1D80D73800B0A59C /* si-83-seccertificate-sighashalg.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E061D8085FC00865A7C /* si-83-seccertificate-sighashalg.c */; }; - DC52EE5B1D80D73800B0A59C /* si-97-sectrust-path-scoring.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E101D8085FC00865A7C /* si-97-sectrust-path-scoring.m */; }; - DC52EE5C1D80D76300B0A59C /* si-20-sectrust-policies.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DBA1D8085FC00865A7C /* si-20-sectrust-policies.m */; }; - DC52EE5D1D80D76B00B0A59C /* si-87-sectrust-name-constraints.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E091D8085FC00865A7C /* si-87-sectrust-name-constraints.m */; }; - DC52EE5E1D80D78C00B0A59C /* si-82-sectrust-ct.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E041D8085FC00865A7C /* si-82-sectrust-ct.m */; }; - DC52EE5F1D80D79400B0A59C /* si-85-sectrust-ssl-policy.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E071D8085FC00865A7C /* si-85-sectrust-ssl-policy.c */; }; DC52EE601D80D79900B0A59C /* si-74-OTAPKISigner.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78DFE1D8085FC00865A7C /* si-74-OTAPKISigner.c */; }; 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.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 */; }; + DC52EE731D80D86800B0A59C /* SecKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.m */; }; DC52EE741D80D86F00B0A59C /* SecAccessControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E301D8085FC00865A7C /* SecAccessControl.m */; }; DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E441D8085FC00865A7C /* SecCTKKey.m */; }; DC52EE771D80D88300B0A59C /* SecDH.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E461D8085FC00865A7C /* SecDH.c */; }; @@ -3176,12 +3775,31 @@ 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 */; }; DC55329B1DDAA28600B6A6A7 /* XPCNotificationDispatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = E7C787331DD0FED50087FC34 /* XPCNotificationDispatcher.m */; }; + DC5681AA224DA05F008F8DEB /* OctagonFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5681A8224DA05F008F8DEB /* OctagonFlags.h */; }; + DC5681AB224DA05F008F8DEB /* OctagonFlags.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5681A9224DA05F008F8DEB /* OctagonFlags.m */; }; DC58C4331D77BE2E003C25A4 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; DC58C43E1D77BED0003C25A4 /* csparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC58C43B1D77BED0003C25A4 /* csparser.cpp */; }; - DC59E9A41D91C6F0001BDDF5 /* libCMS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002D71D8E19F20025549C /* libCMS.a */; }; - DC59E9A71D91C7C7001BDDF5 /* libCMS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002D71D8E19F20025549C /* libCMS.a */; }; + DC59244A20E46E9D0073D284 /* SOSRingUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D461D8085F200865A7C /* SOSRingUtils.c */; }; + DC59244B20E46EA20073D284 /* SOSRingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D451D8085F200865A7C /* SOSRingTypes.h */; }; + DC59244C20E46EDD0073D284 /* SOSRingTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D441D8085F200865A7C /* SOSRingTypes.m */; }; + DC59244D20E46F0E0073D284 /* SOSTransport.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D741D8085F200865A7C /* SOSTransport.m */; }; + DC59244E20E46F200073D284 /* SOSTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D751D8085F200865A7C /* SOSTransport.h */; }; + DC59244F20E46F470073D284 /* SOSAccountRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C801DA5BC0E00CC09B9 /* SOSAccountRecovery.m */; }; + DC59245020E46F800073D284 /* SOSRecoveryKeyBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C731DA5BB4200CC09B9 /* SOSRecoveryKeyBag.m */; }; + DC59245120E46F840073D284 /* SOSRecoveryKeyBag.h in Headers */ = {isa = PBXBuildFile; fileRef = 48776C741DA5BB4200CC09B9 /* SOSRecoveryKeyBag.h */; }; + DC59245220E46FAA0073D284 /* SOSRingBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D3A1D8085F200865A7C /* SOSRingBackup.m */; }; + DC59245320E46FB10073D284 /* SOSRingBackup.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D3B1D8085F200865A7C /* SOSRingBackup.h */; }; + DC59245420E46FDE0073D284 /* SOSRingBasic.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D3C1D8085F200865A7C /* SOSRingBasic.m */; }; + DC59245520E470070073D284 /* SOSRingRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C7C1DA5BB5F00CC09B9 /* SOSRingRecovery.m */; }; + DC59245620E470350073D284 /* SOSRingConcordanceTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D3E1D8085F200865A7C /* SOSRingConcordanceTrust.c */; }; + DC59245720E470390073D284 /* SOSRingConcordanceTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D3F1D8085F200865A7C /* SOSRingConcordanceTrust.h */; }; + DC59245820E4711F0073D284 /* SOSRingDER.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D401D8085F200865A7C /* SOSRingDER.c */; }; + DC5999752232FA3700A9F1A3 /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; + DC5A01E821BB428500D87AB9 /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5A01E621BB428500D87AB9 /* CKKSTLKShare.h */; }; + DC5A01E921BB428500D87AB9 /* CKKSTLKShare.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5A01E621BB428500D87AB9 /* CKKSTLKShare.h */; }; + DC5A01EA21BB428500D87AB9 /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5A01E721BB428500D87AB9 /* CKKSTLKShare.m */; }; + DC5A01EB21BB428500D87AB9 /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5A01E721BB428500D87AB9 /* CKKSTLKShare.m */; }; DC5ABDCC1D832E4000CF422C /* srCdsaUtils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABD781D832D5800CF422C /* srCdsaUtils.cpp */; }; DC5ABDCD1D832E4000CF422C /* createFVMaster.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABD7A1D832D5800CF422C /* createFVMaster.c */; }; DC5ABDCE1D832E4000CF422C /* mds_install.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABD7D1D832D5800CF422C /* mds_install.cpp */; }; @@ -3254,7 +3872,7 @@ DC5ABE181D832F2200CF422C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; DC5ABE191D832F2700CF422C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; DC5ABE1A1D832F3E00CF422C /* security.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC5ABDBF1D832D5D00CF422C /* security.1 */; }; - DC5AC0C01D83538000CF422C /* securityd.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC5ABFE01D83513400CF422C /* securityd.1 */; }; + DC5AC0C01D83538000CF422C /* securityd.1 in Man pages */ = {isa = PBXBuildFile; fileRef = DC5ABFE01D83513400CF422C /* securityd.1 */; }; DC5AC0C11D83538800CF422C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; }; DC5AC0C21D83538D00CF422C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; DC5AC0C41D8353BB00CF422C /* System.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC5AC0C31D8353B900CF422C /* System.framework */; }; @@ -3297,7 +3915,6 @@ DC5AC0F41D8354CA00CF422C /* credential.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFBB1D83511A00CF422C /* credential.cpp */; }; DC5AC0F51D8354CA00CF422C /* clientid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFBE1D83511A00CF422C /* clientid.cpp */; }; DC5AC0F61D8354CA00CF422C /* codesigdb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFC01D83511A00CF422C /* codesigdb.cpp */; }; - DC5AC0F71D8354CA00CF422C /* csproxy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFC31D83511A00CF422C /* csproxy.cpp */; }; DC5AC0F81D8354CA00CF422C /* agentquery.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFC71D83511A00CF422C /* agentquery.cpp */; }; DC5AC0F91D8354CA00CF422C /* auditevents.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFC91D83511A00CF422C /* auditevents.cpp */; }; DC5AC0FA1D8354CA00CF422C /* ccaudit_extensions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC5ABFCB1D83511A00CF422C /* ccaudit_extensions.cpp */; }; @@ -3335,7 +3952,6 @@ DC5AC11F1D83555A00CF422C /* credential.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFBA1D83511A00CF422C /* credential.h */; }; DC5AC1201D83555A00CF422C /* clientid.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFBD1D83511A00CF422C /* clientid.h */; }; DC5AC1211D83555A00CF422C /* codesigdb.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFBF1D83511A00CF422C /* codesigdb.h */; }; - DC5AC1221D83555A00CF422C /* csproxy.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFC21D83511A00CF422C /* csproxy.h */; }; DC5AC1231D83555A00CF422C /* agentclient.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFC51D83511A00CF422C /* agentclient.h */; }; DC5AC1241D83555A00CF422C /* agentquery.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFC61D83511A00CF422C /* agentquery.h */; }; DC5AC1251D83555A00CF422C /* auditevents.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5ABFC81D83511A00CF422C /* auditevents.h */; }; @@ -3349,16 +3965,14 @@ 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 */; }; - DC5BB4FF1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5BB4FC1E0C98320010F836 /* CKKSOutgoingQueueOperation.h */; }; DC5BB5001E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4FD1E0C98320010F836 /* CKKSOutgoingQueueOperation.m */; }; - DC5BB5011E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5BB4FD1E0C98320010F836 /* CKKSOutgoingQueueOperation.m */; }; DC5BCC481E53820200649140 /* SecArgParse.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5BCC461E5380EA00649140 /* SecArgParse.c */; }; DC5BD5831E8C6FC800C5EC49 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; DC5BD5841E8C6FD100C5EC49 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; + DC5BEACD2217509A001681F0 /* OctagonTests+CloudKitAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5BEACC2217509A001681F0 /* OctagonTests+CloudKitAccount.swift */; }; + DC5F2BBE2310B941001ADA5D /* OctagonTests+CoreFollowUp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5F2BBD2310B941001ADA5D /* OctagonTests+CoreFollowUp.swift */; }; DC5F35A61EE0F25000900966 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; DC5F35A71EE0F25100900966 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; DC5F35A81EE0F25300900966 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; @@ -3371,6 +3985,13 @@ DC5F35B01EE0F27C00900966 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; DC5F35B11EE0F28B00900966 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; DC5F35B21EE0F28C00900966 /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + DC5F65AE2225C22C0051E9FA /* CKKSProvideKeySetOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC5F65AC2225C22C0051E9FA /* CKKSProvideKeySetOperation.h */; }; + DC5F65AF2225C22C0051E9FA /* CKKSProvideKeySetOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5F65AD2225C22C0051E9FA /* CKKSProvideKeySetOperation.m */; }; + DC5F65B12225CD720051E9FA /* CKKSProvideKeySetOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5F65AD2225C22C0051E9FA /* CKKSProvideKeySetOperation.m */; }; + DC60132E2147220600863C1A /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DC6013312147220F00863C1A /* libaks_mock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC36895E21235F42003A3735 /* libaks_mock.a */; }; + DC6013392147227800863C1A /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DC6063B221B09AB200069B82 /* KCJoiningRequestCircleSession.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6063B121B09AB200069B82 /* KCJoiningRequestCircleSession.m */; }; DC610A181D78F129002223DE /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C0BDB31175685B000BC1A7E /* main.m */; }; DC610A1D1D78F129002223DE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; DC610A1E1D78F129002223DE /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; @@ -3381,7 +4002,6 @@ DC610A2C1D78F129002223DE /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; DC610A2E1D78F129002223DE /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; DC610A2F1D78F129002223DE /* libctkclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */; }; - DC610A391D78F1B7002223DE /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB2CA4D81D2C28C800AB770F /* libaks.a */; }; DC610A3B1D78F234002223DE /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; DC610A3D1D78F25C002223DE /* libDiagnosticMessagesClient.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3C1D78F25C002223DE /* libDiagnosticMessagesClient.dylib */; }; DC610A501D78F715002223DE /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = DC610A4F1D78F715002223DE /* main.c */; }; @@ -3394,7 +4014,9 @@ DC610A6A1D78FA8C002223DE /* validation.sh in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC610A681D78FA87002223DE /* validation.sh */; }; 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 */; }; + DC614C5122A9BDB500E16ADA /* CKKSZoneModifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DC614C4F22A9BDB500E16ADA /* CKKSZoneModifier.h */; }; + DC614C5222A9BDB500E16ADA /* CKKSZoneModifier.m in Sources */ = {isa = PBXBuildFile; fileRef = DC614C5022A9BDB500E16ADA /* CKKSZoneModifier.m */; }; + DC62DC6D22A87137000D2D5D /* CKKSTests+MultiZone.m in Sources */ = {isa = PBXBuildFile; fileRef = DC62DC6B22A87128000D2D5D /* CKKSTests+MultiZone.m */; }; 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 */; }; @@ -3413,12 +4035,9 @@ DC65E77B1D8CB8E800152EF0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DC65E77C1D8CB8F100152EF0 /* MobileKeyBag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FC30AB1332DE9000802946 /* MobileKeyBag.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DC65E7BD1D8CBA6C00152EF0 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; - DC65E7C01D8CBB1500152EF0 /* readline.c in Sources */ = {isa = PBXBuildFile; fileRef = DC65E7BE1D8CBB1500152EF0 /* readline.c */; }; - DC65E7C11D8CBB1500152EF0 /* readline.h in Headers */ = {isa = PBXBuildFile; fileRef = DC65E7BF1D8CBB1500152EF0 /* readline.h */; }; DC65E7C21D8CBB5800152EF0 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; DC65E7C31D8CBBA200152EF0 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; DC65E7C41D8CBC0900152EF0 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; - DC6A82A01D87761700418608 /* cshosting.h in Headers */ = {isa = PBXBuildFile; fileRef = DC6A82841D87734600418608 /* cshosting.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC6A82A11D87761F00418608 /* ucspNotify.h in Headers */ = {isa = PBXBuildFile; fileRef = DC6A827E1D87734600418608 /* ucspNotify.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC6A82A21D87762400418608 /* ucsp.h in Headers */ = {isa = PBXBuildFile; fileRef = DC6A827D1D87734600418608 /* ucsp.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC6A82A31D87762900418608 /* ucsp_types.h in Headers */ = {isa = PBXBuildFile; fileRef = DC6A82741D87732E00418608 /* ucsp_types.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -3451,89 +4070,77 @@ DC6A82BE1D87769800418608 /* transition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82711D87732E00418608 /* transition.cpp */; }; DC6A82BF1D8776B300418608 /* ucspClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A827F1D87734600418608 /* ucspClient.cpp */; }; DC6A82C01D8776B300418608 /* ucspNotifySender.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82821D87734600418608 /* ucspNotifySender.cpp */; }; - DC6A82C11D8776B900418608 /* cshostingClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82851D87734600418608 /* cshostingClient.cpp */; }; - DC6A82C21D8776B900418608 /* cshostingServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82861D87734600418608 /* cshostingServer.cpp */; }; DC6A82C41D8776D800418608 /* ssblob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC6A82571D87732E00418608 /* ssblob.cpp */; }; DC6ACC461E81E08D00125DC5 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; DC6ACC471E81E08E00125DC5 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; DC6BC2721D90D05900DD57B3 /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DC5ABFE41D83514700CF422C /* com.apple.securityd.plist */; }; DC6D2C921DD2835A00BE372D /* CKKSOutgoingQueueEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9B7AE41DCBF604004E9385 /* CKKSOutgoingQueueEntry.m */; }; DC6D2C931DD2836500BE372D /* CKKSOutgoingQueueEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9B7AE61DCBF651004E9385 /* CKKSOutgoingQueueEntry.h */; }; - DC7162D21EB413F2000D2BB5 /* KeychainCKKS.plist in Copy BATS Test Discovery plist */ = {isa = PBXBuildFile; fileRef = 6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */; }; + DC6DE899213076C000C6B56D /* OTSOSUpgradeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC6DE897213076C000C6B56D /* OTSOSUpgradeOperation.h */; }; + DC6DE89C213076C000C6B56D /* OTSOSUpgradeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6DE898213076C000C6B56D /* OTSOSUpgradeOperation.m */; }; DC71D85C1D94CCD40065FB93 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; - DC71D8F51D959F150065FB93 /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; - DC71D9A11D95BA6C0065FB93 /* SecAsn1Coder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785131D77895A00B50D50 /* SecAsn1Coder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A21D95BA6C0065FB93 /* SecAsn1Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785141D77895A00B50D50 /* SecAsn1Templates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A31D95BA6C0065FB93 /* SecAsn1Types.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785151D77895A00B50D50 /* SecAsn1Types.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A41D95BA6C0065FB93 /* SecNssCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834421D8A21AA00CE0ACA /* SecNssCoder.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A51D95BA6C0065FB93 /* X509Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787691D77911D00B50D50 /* X509Templates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A61D95BA6C0065FB93 /* oidsbase.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785681D778B4A00B50D50 /* oidsbase.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A71D95BA6C0065FB93 /* certExtensionTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787621D77911D00B50D50 /* certExtensionTemplates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A81D95BA6C0065FB93 /* csrTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787631D77911D00B50D50 /* csrTemplates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9A91D95BA6C0065FB93 /* keyTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787641D77911D00B50D50 /* keyTemplates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9AA1D95BA6C0065FB93 /* nameTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787651D77911D00B50D50 /* nameTemplates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9AB1D95BA6C0065FB93 /* nssUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834201D8A21AA00CE0ACA /* nssUtils.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9AC1D95BA6C0065FB93 /* ocspTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787661D77911D00B50D50 /* ocspTemplates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9AD1D95BA6C0065FB93 /* oidsalg.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785111D77895A00B50D50 /* oidsalg.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9AE1D95BA6C0065FB93 /* oidsattr.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1785121D77895A00B50D50 /* oidsattr.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9AF1D95BA6C0065FB93 /* oidsocsp.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88344F1D8A21AA00CE0ACA /* oidsocsp.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B01D95BA6C0065FB93 /* osKeyTemplates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787671D77911D00B50D50 /* osKeyTemplates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B11D95BA6C0065FB93 /* pkcs12Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88341A1D8A21AA00CE0ACA /* pkcs12Templates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B21D95BA6C0065FB93 /* pkcs7Templates.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834181D8A21AA00CE0ACA /* pkcs7Templates.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B31D95BA6C0065FB93 /* plarena.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834241D8A21AA00CE0ACA /* plarena.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B41D95BA6C0065FB93 /* plarenas.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834251D8A21AA00CE0ACA /* plarenas.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B51D95BA6C0065FB93 /* plstr.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834261D8A21AA00CE0ACA /* plstr.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B61D95BA6C0065FB93 /* prbit.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834271D8A21AA00CE0ACA /* prbit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B71D95BA6C0065FB93 /* prcpucfg.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834281D8A21AA00CE0ACA /* prcpucfg.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B81D95BA6C0065FB93 /* prerr.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88342B1D8A21AA00CE0ACA /* prerr.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9B91D95BA6C0065FB93 /* prerror.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88342C1D8A21AA00CE0ACA /* prerror.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9BA1D95BA6C0065FB93 /* prlog.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834301D8A21AA00CE0ACA /* prlog.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9BB1D95BA6C0065FB93 /* prmem.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834321D8A21AA00CE0ACA /* prmem.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9BC1D95BA6C0065FB93 /* protypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834341D8A21AA00CE0ACA /* protypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9BD1D95BA6C0065FB93 /* prtypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834371D8A21AA00CE0ACA /* prtypes.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9BE1D95BA6C0065FB93 /* secasn1.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834391D8A21AA00CE0ACA /* secasn1.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9BF1D95BA6C0065FB93 /* secasn1t.h in Headers */ = {isa = PBXBuildFile; fileRef = DC1787681D77911D00B50D50 /* secasn1t.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9C01D95BA6C0065FB93 /* seccomon.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88343E1D8A21AA00CE0ACA /* seccomon.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9C11D95BA6C0065FB93 /* secerr.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88343F1D8A21AA00CE0ACA /* secerr.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9C21D95BA6C0065FB93 /* secport.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8834441D8A21AA00CE0ACA /* secport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DC71D9C41D95BA6C0065FB93 /* X509Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834451D8A21AA00CE0ACA /* X509Templates.c */; }; - DC71D9C51D95BA6C0065FB93 /* keyTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834131D8A21AA00CE0ACA /* keyTemplates.c */; }; - DC71D9C61D95BA6C0065FB93 /* SecAsn1Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340C1D8A21AA00CE0ACA /* SecAsn1Templates.c */; }; - DC71D9C71D95BA6C0065FB93 /* osKeyTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834471D8A21AA00CE0ACA /* osKeyTemplates.c */; }; - DC71D9C81D95BA6C0065FB93 /* nsprPortX.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88341B1D8A21AA00CE0ACA /* nsprPortX.c */; }; - DC71D9C91D95BA6C0065FB93 /* nameTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834151D8A21AA00CE0ACA /* nameTemplates.c */; }; - DC71D9CA1D95BA6C0065FB93 /* pkcs7Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834171D8A21AA00CE0ACA /* pkcs7Templates.c */; }; - DC71D9CB1D95BA6C0065FB93 /* plarena.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834231D8A21AA00CE0ACA /* plarena.c */; }; - DC71D9CC1D95BA6C0065FB93 /* secasn1e.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88343B1D8A21AA00CE0ACA /* secasn1e.c */; }; - DC71D9CD1D95BA6C0065FB93 /* SecNssCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC8834411D8A21AA00CE0ACA /* SecNssCoder.cpp */; }; - DC71D9CE1D95BA6C0065FB93 /* oidsalg.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834491D8A21AA00CE0ACA /* oidsalg.c */; }; - DC71D9CF1D95BA6C0065FB93 /* ocspTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834211D8A21AA00CE0ACA /* ocspTemplates.c */; }; - DC71D9D01D95BA6C0065FB93 /* certExtensionTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340F1D8A21AA00CE0ACA /* certExtensionTemplates.c */; }; - DC71D9D11D95BA6C0065FB93 /* secport.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834431D8A21AA00CE0ACA /* secport.c */; }; - DC71D9D21D95BA6C0065FB93 /* nssUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88341F1D8A21AA00CE0ACA /* nssUtils.c */; }; - DC71D9D31D95BA6C0065FB93 /* pkcs12Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834191D8A21AA00CE0ACA /* pkcs12Templates.c */; }; - DC71D9D41D95BA6C0065FB93 /* csrTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834111D8A21AA00CE0ACA /* csrTemplates.c */; }; - DC71D9D51D95BA6C0065FB93 /* oidsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88344B1D8A21AA00CE0ACA /* oidsattr.c */; }; - DC71D9D61D95BA6C0065FB93 /* secErrorStr.c in Sources */ = {isa = PBXBuildFile; fileRef = DC8834401D8A21AA00CE0ACA /* secErrorStr.c */; }; - DC71D9D71D95BA6C0065FB93 /* oidsocsp.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88344E1D8A21AA00CE0ACA /* oidsocsp.c */; }; - 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 */; }; - DC7341F61F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */; }; + DC71D8F51D959F150065FB93 /* com.apple.securityd.plist in Copy Logging Files */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; + DC725030229600C000493D88 /* OctagonTests+Reset.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC72502D229600A800493D88 /* OctagonTests+Reset.swift */; }; + DC7250372296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7250352296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.h */; }; + DC7250382296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7250362296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.m */; }; + DC730E1222400D790051DD48 /* TPDictionaryMatchingRules.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8846802237431400738068 /* TPDictionaryMatchingRules.m */; }; + DC730E1322400D7B0051DD48 /* TPDictionaryMatchingRules.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88467F2237431400738068 /* TPDictionaryMatchingRules.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC730E142240103A0051DD48 /* TPDictionaryMatchingRuleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC88466C2237407500738068 /* TPDictionaryMatchingRuleTests.m */; }; + DC730E1B224011E20051DD48 /* TPPBDictionaryMatchingRule.m in Sources */ = {isa = PBXBuildFile; fileRef = DC730E15224011D60051DD48 /* TPPBDictionaryMatchingRule.m */; }; + DC730E1C224011E40051DD48 /* TPPBDictionaryMatchingRuleFieldExists.m in Sources */ = {isa = PBXBuildFile; fileRef = DC730E17224011D80051DD48 /* TPPBDictionaryMatchingRuleFieldExists.m */; }; + DC730E1D224011E70051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.m in Sources */ = {isa = PBXBuildFile; fileRef = DC730E19224011DB0051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.m */; }; + DC730E1F224012710051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.h in Headers */ = {isa = PBXBuildFile; fileRef = DC730E18224011D90051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC730E20224012770051DD48 /* TPPBDictionaryMatchingRuleFieldExists.h in Headers */ = {isa = PBXBuildFile; fileRef = DC730E1A224011DD0051DD48 /* TPPBDictionaryMatchingRuleFieldExists.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC730E212240127D0051DD48 /* TPPBDictionaryMatchingRule.h in Headers */ = {isa = PBXBuildFile; fileRef = DC730E16224011D70051DD48 /* TPPBDictionaryMatchingRule.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DC730E2522401E310051DD48 /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; + DC730E2922401F5E0051DD48 /* ProtocolBuffer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */; }; + DC7341F31F8447AB00AB9BDF /* CKKSTLKShareRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7341F11F8447AB00AB9BDF /* CKKSTLKShareRecord.h */; }; + DC7341F51F8447AB00AB9BDF /* CKKSTLKShareRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341F21F8447AB00AB9BDF /* CKKSTLKShareRecord.m */; }; DC7341FE1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7341FD1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m */; }; + DC747993222720C8001E0E8C /* MockCloudKit.m in Sources */ = {isa = PBXBuildFile; fileRef = DC3502E61E0214C800BC0587 /* MockCloudKit.m */; }; + DC7479982227229D001E0E8C /* CKKSTLKShare.m in Sources */ = {isa = PBXBuildFile; fileRef = DC5A01E721BB428500D87AB9 /* CKKSTLKShare.m */; }; + DC747999222722B2001E0E8C /* CKKSConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DC391F9921BF2F4B00772585 /* CKKSConstants.m */; }; + DC74799A222722BC001E0E8C /* CKKSKeychainBackedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC0BD4F021BB05F2006B9154 /* CKKSKeychainBackedKey.m */; }; + DC74799C22272331001E0E8C /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; + DC74799D22272344001E0E8C /* CKKSSIV.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */; }; + DC74799E22272358001E0E8C /* CKKSSerializedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3261F858D3E00C8AAC8 /* CKKSSerializedKey.m */; }; + DC752F1721C1B48400216089 /* SOSPiggyback.m in Sources */ = {isa = PBXBuildFile; fileRef = EB75B4941E75A44100E469CC /* SOSPiggyback.m */; }; + DC752F1921C1B69C00216089 /* SFSQLite.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BC1F152EB10082882F /* SFSQLite.m */; }; + DC752F1A21C1B6A700216089 /* SFSQLiteStatement.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BF1F152EB10082882F /* SFSQLiteStatement.m */; }; + DC752F1F21C1B98000216089 /* SFObjCType.m in Sources */ = {isa = PBXBuildFile; fileRef = 4723C9BE1F152EB10082882F /* SFObjCType.m */; }; + DC754C722228B57C00A39C8E /* TrustedPeersHelperProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DC754C712228B57B00A39C8E /* TrustedPeersHelperProtocol.m */; }; + DC754C742228B59000A39C8E /* TrustedPeersHelperProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DC754C712228B57B00A39C8E /* TrustedPeersHelperProtocol.m */; }; DC762A9E1E57A86A00B03A2C /* CKKSRecordHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC762A9C1E57A86A00B03A2C /* CKKSRecordHolder.h */; }; - DC762A9F1E57A86A00B03A2C /* CKKSRecordHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = DC762A9C1E57A86A00B03A2C /* CKKSRecordHolder.h */; }; DC762AA01E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = DC762A9D1E57A86A00B03A2C /* CKKSRecordHolder.m */; }; - DC762AA11E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */ = {isa = PBXBuildFile; fileRef = DC762A9D1E57A86A00B03A2C /* CKKSRecordHolder.m */; }; DC797E1A1DD3F9A400CC9E42 /* CKKSSQLDatabaseObject.m in Sources */ = {isa = PBXBuildFile; fileRef = DC797E131DD3F88300CC9E42 /* CKKSSQLDatabaseObject.m */; }; DC7A17ED1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7A17EB1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h */; }; - DC7A17EE1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7A17EB1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h */; }; DC7A17EF1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7A17EC1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m */; }; - DC7A17F01E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7A17EC1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m */; }; + DC7F79B622EA4ED4001FB69A /* OctagonTests+CKKS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC7F79B522EA4ED4001FB69A /* OctagonTests+CKKS.swift */; }; + DC7F79BA22EA5C73001FB69A /* OTLocalCKKSResetOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7F79B822EA5C72001FB69A /* OTLocalCKKSResetOperation.h */; }; + DC7F79BB22EA5C73001FB69A /* OTLocalCKKSResetOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7F79B922EA5C72001FB69A /* OTLocalCKKSResetOperation.m */; }; + DC7FC45021EE917D003C39B8 /* Security.plist in Install Security FeatureFlags plist */ = {isa = PBXBuildFile; fileRef = DC7FC44321EE6F7B003C39B8 /* Security.plist */; }; + DC85069B2097E69500C712EC /* keychain_backup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E211D8085FC00865A7C /* keychain_backup.c */; }; + DC85069D2097E69500C712EC /* keychain_backup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E211D8085FC00865A7C /* keychain_backup.c */; }; + DC8506A62097EE7300C712EC /* SecurityTool.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA981D80CC2A00B0A59C /* SecurityTool.c */; }; + DC8506A72097EE7500C712EC /* SecurityTool.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA981D80CC2A00B0A59C /* SecurityTool.c */; }; + DC8506A82097EE8E00C712EC /* KeychainCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337831FDB29A200E19F30 /* KeychainCheck.m */; }; + DC8506A92097EE8F00C712EC /* KeychainCheck.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337831FDB29A200E19F30 /* KeychainCheck.m */; }; + DC8506AA2097EEA500C712EC /* syncbubble.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA921D80CC2A00B0A59C /* syncbubble.m */; }; + DC8506AB2097EEA600C712EC /* syncbubble.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA921D80CC2A00B0A59C /* syncbubble.m */; }; + DC8506AC2097EEBA00C712EC /* sos.m in Sources */ = {isa = PBXBuildFile; fileRef = EB48C19E1E573EDC00EC5E57 /* sos.m */; }; + DC8506AD2097EEBC00C712EC /* sos.m in Sources */ = {isa = PBXBuildFile; fileRef = EB48C19E1E573EDC00EC5E57 /* sos.m */; }; + DC8506AE2097EEDA00C712EC /* leaks.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA931D80CC2A00B0A59C /* leaks.c */; }; + DC8506AF2097EEDB00C712EC /* leaks.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA931D80CC2A00B0A59C /* leaks.c */; }; + DC8506B02097EEF200C712EC /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; + DC8506B12097EEF300C712EC /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; + DC8506B22097F1DF00C712EC /* digest_calc.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA8F1D80CC2A00B0A59C /* digest_calc.c */; }; + DC8506B32097F1E000C712EC /* digest_calc.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA8F1D80CC2A00B0A59C /* digest_calc.c */; }; + DC8506B42097F1FC00C712EC /* whoami.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA911D80CC2A00B0A59C /* whoami.m */; }; + DC8506B52097F1FD00C712EC /* whoami.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA911D80CC2A00B0A59C /* whoami.m */; }; + DC8506B62097F39100C712EC /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; + DC85687E2284E7860088D3EF /* OctagonTestMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC85687C2284E7850088D3EF /* OctagonTestMocks.swift */; }; + DC8757F4218D2003000E65F1 /* OTRemovePeersOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC8757F2218D2003000E65F1 /* OTRemovePeersOperation.h */; }; + DC8757F5218D2003000E65F1 /* OTRemovePeersOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8757F3218D2003000E65F1 /* OTRemovePeersOperation.m */; }; DC8834521D8A21AA00CE0ACA /* SecAsn1Coder.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340A1D8A21AA00CE0ACA /* SecAsn1Coder.c */; }; DC8834541D8A21AA00CE0ACA /* SecAsn1Templates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340C1D8A21AA00CE0ACA /* SecAsn1Templates.c */; }; DC8834571D8A21AA00CE0ACA /* certExtensionTemplates.c in Sources */ = {isa = PBXBuildFile; fileRef = DC88340F1D8A21AA00CE0ACA /* certExtensionTemplates.c */; }; @@ -3557,63 +4164,121 @@ 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 */; }; + DC88466B22373A5E00738068 /* TPPBDictionaryMatchingRule.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC88466922373A4000738068 /* TPPBDictionaryMatchingRule.proto */; }; DC8D238D2064649400E163C8 /* CKKSAPSHandlingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC8D238C2064649400E163C8 /* CKKSAPSHandlingTests.m */; }; + DC8DF6DC212F8A7C007B3FE8 /* OTSOSAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB9475C2127562100ED9272 /* OTSOSAdapter.m */; }; + DC8DF6DF212F8A7D007B3FE8 /* OTSOSAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB9475C2127562100ED9272 /* OTSOSAdapter.m */; }; + DC8E3DC4224460C6003D86DB /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; 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, ); }; }; + DC9061B922B02BA30071474D /* TPTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9061B822B02BA30071474D /* TPTypes.m */; }; DC9082C41EA0277600D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; }; - DC9082C51EA0277700D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */; }; DC9082C61EA027DB00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */; }; - DC9082C71EA027DC00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */; }; + DC90A4C721F279D4001300EB /* SecEscrowPendingRecord.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC90A4C621F279D4001300EB /* SecEscrowPendingRecord.proto */; }; DC926F071F33F7C20012A315 /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067981D8CDF7E007602F1 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC926F081F33F7D30012A315 /* SecCodeHost.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067981D8CDF7E007602F1 /* SecCodeHost.h */; settings = {ATTRIBUTES = (Public, ); }; }; DC926F091F33FA8D0012A315 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; DC926F0A1F33FA8E0012A315 /* CKKSControlProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */; }; + DC93C4C5214713C5008F8362 /* libaks_mock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC36895E21235F42003A3735 /* libaks_mock.a */; }; + DC93C4CA214713E5008F8362 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DC93C4CB214713ED008F8362 /* libaks_mock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC36895E21235F42003A3735 /* libaks_mock.a */; }; + DC93C4D021471FD8008F8362 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DC93F02922387A010072720A /* OTSOSUpdatePreapprovalsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DC93F02722387A010072720A /* OTSOSUpdatePreapprovalsOperation.h */; }; + DC93F02A22387A010072720A /* OTSOSUpdatePreapprovalsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DC93F02822387A010072720A /* OTSOSUpdatePreapprovalsOperation.m */; }; DC94BCCA1F10448600E07CEB /* CloudKitCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC94BCC81F10448600E07CEB /* CloudKitCategories.h */; }; - DC94BCCB1F10448600E07CEB /* CloudKitCategories.h in Headers */ = {isa = PBXBuildFile; fileRef = DC94BCC81F10448600E07CEB /* CloudKitCategories.h */; }; DC94BCCC1F10448600E07CEB /* CloudKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC94BCC91F10448600E07CEB /* CloudKitCategories.m */; }; - DC94BCCD1F10448600E07CEB /* CloudKitCategories.m in Sources */ = {isa = PBXBuildFile; fileRef = DC94BCC91F10448600E07CEB /* CloudKitCategories.m */; }; DC96053F1ECA2D6400AF9BDA /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; DC963E7E1D95EBB1008A153E /* libsecurity_apple_csp.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCF784F81D88B63800E694BB /* libsecurity_apple_csp.plist */; }; DC963E801D95EBD1008A153E /* libsecurity_apple_csp.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCF784F91D88B63800E694BB /* libsecurity_apple_csp.txt */; }; DC963E821D95EC1C008A153E /* libsecurity_codesigning.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCD068CB1D8CDFFE007602F1 /* libsecurity_codesigning.plist */; }; DC963E841D95EC31008A153E /* libsecurity_codesigning.txt in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCD068CC1D8CDFFE007602F1 /* libsecurity_codesigning.txt */; }; DC963EC61D95F646008A153E /* der_plist.h in Headers */ = {isa = PBXBuildFile; fileRef = 524492931AFD6D480043695A /* der_plist.h */; }; + DC99B86B20EACA470065B73B /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + DC99B86C20EACA470065B73B /* FakeCuttlefish.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEA8557F20B5DC7D00D5AD11 /* FakeCuttlefish.swift */; }; + DC99B86D20EACA470065B73B /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + DC99B86E20EACA470065B73B /* MockCuttlefish.swift in Sources */ = {isa = PBXBuildFile; fileRef = BED987E220991C4D00607A5F /* MockCuttlefish.swift */; }; + DC99B86F20EACA470065B73B /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DC99B87020EACA470065B73B /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + DC99B87120EACA470065B73B /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DC99B87220EACA470065B73B /* Cuttlefish.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F4F8B2072D881004A52C2 /* Cuttlefish.pb.swift */; }; + DC99B87320EACA470065B73B /* Decrypter.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D11206C121400B53D16 /* Decrypter.swift */; }; + DC99B87420EACA470065B73B /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + DC99B87520EACA470065B73B /* TrustedPeersHelper.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = BE92249C204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld */; }; + DC99B87720EACA470065B73B /* ContainerSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE4C6AB120CAF4E500EAD6BE /* ContainerSync.swift */; }; + DC99B87820EACA470065B73B /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D0F206C099800B53D16 /* Container.swift */; }; + DC99B87920EACA470065B73B /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = BEC0A96320B362EC00DBD772 /* Utils.swift */; }; + DC99B87B20EACA470065B73B /* libbsm.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = EB49B2DC202DF251003F34A0 /* libbsm.tbd */; }; + DC99B87C20EACA470065B73B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + DC99B87F20EACA470065B73B /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246911F9AE2E400D63882 /* libDER.a */; }; + DC99B88020EACA470065B73B /* libMobileGestalt.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BE53602C209BBF2F0027E25A /* libMobileGestalt.tbd */; }; + DC99B88220EACA470065B73B /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC9EBA311DEE768000D0F733 /* CloudKit.framework */; }; + DC99B88320EACA470065B73B /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + DC99B88420EACA470065B73B /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; + DC99B88520EACA470065B73B /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; + DC99B88620EACA470065B73B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + DC99B88920EACA470065B73B /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + DC99B88A20EACA470065B73B /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + DC99B88B20EACA470065B73B /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DC9A2C5F1EB3F557008FAC27 /* CKKSTests+Coalesce.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9A2C5E1EB3F556008FAC27 /* CKKSTests+Coalesce.m */; }; DC9A2C7F1EB40A76008FAC27 /* OCMock.framework in Embed OCMock */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + DC9C06692149DFE400C6F7B8 /* OTAuthKitAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C06672149DFE400C6F7B8 /* OTAuthKitAdapter.h */; }; + DC9C066B2149DFE400C6F7B8 /* OTAuthKitAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C06682149DFE400C6F7B8 /* OTAuthKitAdapter.m */; }; + DC9C066D2149E33D00C6F7B8 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DC9C066E2149E35F00C6F7B8 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DC9C066F2149E36900C6F7B8 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DC9C06702149E3CB00C6F7B8 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DC9C06712149E6B900C6F7B8 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DC9C06722149E6F500C6F7B8 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; DC9C75161E4BCE1800F1CA0D /* CKKSOperationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C750F1E4BCC5100F1CA0D /* CKKSOperationTests.m */; }; DC9C95971F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95951F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m */; }; DC9C95B41F79CFD1000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; }; - DC9C95B51F79CFD1000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; }; DC9C95BD1F79DC5A000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC9C95BE1F79DC5F000D19E5 /* CKKSControl.h in Headers */ = {isa = PBXBuildFile; fileRef = DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; DC9C95BF1F79DC88000D19E5 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; DC9C95C01F79DC89000D19E5 /* CKKSControl.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */; }; - DC9FD3231F8587A500C8AAC8 /* CKKSSerializedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */; }; + DC9C98C722E264F30021E29F /* CKKSFetchTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9C98C622E264F30021E29F /* CKKSFetchTests.m */; }; DC9FD32C1F85990A00C8AAC8 /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; - DC9FD32D1F85990B00C8AAC8 /* CKKSPeer.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3291F8598F300C8AAC8 /* CKKSPeer.m */; }; - DC9FD3361F86A34F00C8AAC8 /* CKKSSerializedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */; }; + DCA143341FE0802C00A40D59 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCA1433C1FE0803200A40D59 /* OTControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBF0B1FCB452200580909 /* OTControl.h */; settings = {ATTRIBUTES = (Private, ); }; }; DCA4D1FF1E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D1F41E5520550056214F /* CKKSCurrentKeyPointer.m */; }; - DCA4D2001E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D1F41E5520550056214F /* CKKSCurrentKeyPointer.m */; }; DCA4D2151E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA4D2131E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h */; }; - DCA4D2161E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA4D2131E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h */; }; DCA4D2171E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D2141E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m */; }; - DCA4D2181E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA4D2141E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m */; }; DCA85B931E8D97E400BA7241 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; DCA85B941E8D97E400BA7241 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; - DCA85B961E8D980100BA7241 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; DCA85B971E8D980200BA7241 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; DCA85B981E8D980A00BA7241 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; DCA85B991E8D980B00BA7241 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; - DCA85B9A1E8D981100BA7241 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; DCA85B9B1E8D981200BA7241 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; - DCAB14271E40039600C81511 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCA9BC02221B721E00B4EB26 /* CKKSCloudKitClassDependencies.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA9BC00221B721D00B4EB26 /* CKKSCloudKitClassDependencies.h */; }; + DCA9BC03221B721E00B4EB26 /* CKKSCloudKitClassDependencies.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9BC01221B721E00B4EB26 /* CKKSCloudKitClassDependencies.m */; }; + DCA9BC07221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9BC06221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.m */; }; + DCA9D83E21FFE51A00B27421 /* EscrowRequestXPCServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9D83C21FFE50900B27421 /* EscrowRequestXPCServer.m */; }; + DCA9D84121FFE62A00B27421 /* EscrowRequestXPCProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA9D83F21FFE62A00B27421 /* EscrowRequestXPCProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCA9D84221FFE62A00B27421 /* EscrowRequestXPCProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA9D83F21FFE62A00B27421 /* EscrowRequestXPCProtocol.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCA9D84621FFE7CF00B27421 /* EscrowRequestXPCProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9D84521FFE7CF00B27421 /* EscrowRequestXPCProtocol.m */; }; + DCA9D84721FFE7CF00B27421 /* EscrowRequestXPCProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9D84521FFE7CF00B27421 /* EscrowRequestXPCProtocol.m */; }; + DCA9D84821FFEE9800B27421 /* EscrowRequestXPCProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9D84521FFE7CF00B27421 /* EscrowRequestXPCProtocol.m */; }; + DCA9D84D21FFF04700B27421 /* EscrowRequestServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCA9D84B21FFF04600B27421 /* EscrowRequestServer.h */; }; + DCA9D84E21FFF04700B27421 /* EscrowRequestServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9D84C21FFF04700B27421 /* EscrowRequestServer.m */; }; + DCAB14271E40039600C81511 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; + DCAB17CE21FFF75B00E1DFCF /* MockSynchronousEscrowServer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAB17CC21FFF6C400E1DFCF /* MockSynchronousEscrowServer.m */; }; + DCAB17D12200D26900E1DFCF /* SecEscrowPendingRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAB17CF2200D26700E1DFCF /* SecEscrowPendingRecord.h */; }; + DCAB17D22200D26900E1DFCF /* SecEscrowPendingRecord.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAB17D02200D26800E1DFCF /* SecEscrowPendingRecord.m */; }; + DCAB17D52200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAB17D32200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.h */; }; + DCAB17D62200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAB17D42200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.m */; }; + DCAB17DB2200E7A700E1DFCF /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCAD8F8622C43EC1007C3872 /* Container_MachineIDs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAD8F8422C43EAD007C3872 /* Container_MachineIDs.swift */; }; + DCAD8F8722C43ECA007C3872 /* Container_MachineIDs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAD8F8422C43EAD007C3872 /* Container_MachineIDs.swift */; }; + DCAD8F8922C43EDB007C3872 /* Container_MachineIDs.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCAD8F8422C43EAD007C3872 /* Container_MachineIDs.swift */; }; + DCAD8F8C22C55D76007C3872 /* TPPBDispositionDisallowedMachineID.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAD8F8A22C55D73007C3872 /* TPPBDispositionDisallowedMachineID.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCAD8F8D22C55D76007C3872 /* TPPBDispositionDisallowedMachineID.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAD8F8B22C55D75007C3872 /* TPPBDispositionDisallowedMachineID.m */; }; DCAD9B441F8D939C00C5E2AE /* CKKSFixups.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAD9B421F8D939C00C5E2AE /* CKKSFixups.h */; }; - DCAD9B451F8D939C00C5E2AE /* CKKSFixups.h in Headers */ = {isa = PBXBuildFile; fileRef = DCAD9B421F8D939C00C5E2AE /* CKKSFixups.h */; }; 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 */; }; + DCB0C291222F5E130083AECB /* CuttlefishErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB0C28F222F5DF80083AECB /* CuttlefishErrors.swift */; }; + DCB0C292222F5E1D0083AECB /* CuttlefishErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB0C28F222F5DF80083AECB /* CuttlefishErrors.swift */; }; + DCB0C295222F5EF60083AECB /* CuttlefishErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB0C28F222F5DF80083AECB /* CuttlefishErrors.swift */; }; 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 */; }; @@ -3622,10 +4287,9 @@ DCB221581E8B08C9001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DCB221591E8B08CA001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; DCB2215A1E8B08CB001598BC /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; - DCB332381F46804600178C30 /* SOSSysdiagnose.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB332371F46804000178C30 /* SOSSysdiagnose.h */; }; + DCB24B45221B901700BE73FE /* CKKSMockSOSPresentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCA9BC06221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.m */; }; DCB3323B1F4681AE00178C30 /* SecOTR.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF315AFB73800B9D400 /* SecOTR.h */; settings = {ATTRIBUTES = (Private, ); }; }; DCB3323C1F46833E00178C30 /* SecLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E661D8085FC00865A7C /* SecLogging.h */; settings = {ATTRIBUTES = (Private, ); }; }; - DCB332451F47856B00178C30 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; DCB332591F478C3C00178C30 /* SOSUserKeygen.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D2B1D8085F200865A7C /* SOSUserKeygen.m */; }; DCB3325A1F478C4100178C30 /* SOSUserKeygen.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2C1D8085F200865A7C /* SOSUserKeygen.h */; }; DCB3407D1D8A24F70054D16E /* Authorization.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB3406F1D8A24F70054D16E /* Authorization.c */; }; @@ -3785,8 +4449,6 @@ DCB342291D8A2BAD0054D16E /* osxverifier.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB341D41D8A2BAC0054D16E /* osxverifier.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCB3422A1D8A2BAD0054D16E /* u32handleobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCB341D51D8A2BAC0054D16E /* u32handleobject.cpp */; }; DCB3422B1D8A2BAD0054D16E /* u32handleobject.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB341D61D8A2BAC0054D16E /* u32handleobject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCB3422C1D8A2BAD0054D16E /* uniformrandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCB341D71D8A2BAC0054D16E /* uniformrandom.cpp */; }; - DCB3422D1D8A2BAD0054D16E /* uniformrandom.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB341D81D8A2BAC0054D16E /* uniformrandom.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCB3422E1D8A2BAD0054D16E /* walkers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCB341D91D8A2BAC0054D16E /* walkers.cpp */; }; DCB3422F1D8A2BAD0054D16E /* walkers.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB341DA1D8A2BAC0054D16E /* walkers.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCB342341D8A2C6B0054D16E /* KeySchema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCB342311D8A2C6B0054D16E /* KeySchema.cpp */; }; @@ -3967,6 +4629,13 @@ DCB344A51D8A35270054D16E /* si-20-sectrust-provisioning.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */; }; DCB344A61D8A35270054D16E /* si-33-keychain-backup.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB344711D8A35270054D16E /* si-33-keychain-backup.c */; }; DCB344A71D8A35270054D16E /* si-34-one-true-keychain.c in Sources */ = {isa = PBXBuildFile; fileRef = DCB344721D8A35270054D16E /* si-34-one-true-keychain.c */; }; + DCB41DF1216C2DBB00F219E0 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DCB41DF4216C2DD300F219E0 /* AppleAccount.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C84DA541720698900AEE225 /* AppleAccount.framework */; }; + DCB41DFC216D5E5B00F219E0 /* OTAccountMetadataClassC+KeychainSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = DC7EB921211E17E500516452 /* OTAccountMetadataClassC+KeychainSupport.m */; }; + DCB41E01216D5FE500F219E0 /* OctagonDataPersistenceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC7EB928211E20DF00516452 /* OctagonDataPersistenceTests.swift */; }; + DCB4584C2240396E00115F8C /* NSError+UsefulConstructors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCAE1DD62073FCDE00B4F687 /* NSError+UsefulConstructors.m */; }; + DCB468DF20EC25FF00BA7E5B /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE55C77B2044D0C90045863D /* Client.swift */; }; + DCB468E520EC262C00BA7E5B /* ContainerMap.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE9F8D18206C4AD300B53D16 /* ContainerMap.swift */; }; DCB515DE1ED3CF86001F1152 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; DCB515DF1ED3CF95001F1152 /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; DCB515E01ED3D111001F1152 /* client.c in Sources */ = {isa = PBXBuildFile; fileRef = 7908507F0CA87CF00083CC4D /* client.c */; }; @@ -3975,25 +4644,56 @@ DCB515E31ED3D135001F1152 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; DCB515E41ED3D15A001F1152 /* client_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC844AEC1E81F315007AAB71 /* client_endpoint.m */; }; DCB5D93B1E4A9A3400BE22AB /* CKKSSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB5D9391E4A9A3400BE22AB /* CKKSSynchronizeOperation.h */; }; - DCB5D93C1E4A9A3400BE22AB /* CKKSSynchronizeOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB5D9391E4A9A3400BE22AB /* CKKSSynchronizeOperation.h */; }; DCB5D93D1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB5D93A1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m */; }; - DCB5D93E1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB5D93A1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m */; }; DCB7D8C31D8E181B00867385 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */; }; DCB7D8D01D8E183C00867385 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */; }; DCB7D8D11D8E185900867385 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */; }; DCB837321ED5045000015C07 /* CKKSLockStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DC207EB71ED4EAB600D46873 /* CKKSLockStateTracker.m */; }; - DCB837381ED5045100015C07 /* CKKSLockStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DC207EB71ED4EAB600D46873 /* CKKSLockStateTracker.m */; }; + DCB946AF22FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCB946AD22FCB88400BE4490 /* OTDetermineHSA2AccountStatusOperation.h */; }; + DCB946B022FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB946AE22FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.m */; }; + DCB9475621274A1900ED9272 /* TPHObjcTranslation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB9475421274A1900ED9272 /* TPHObjcTranslation.m */; }; + DCB9475821274F9D00ED9272 /* TPHObjcTranslation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB9475421274A1900ED9272 /* TPHObjcTranslation.m */; }; + DCB9475A2127534C00ED9272 /* OctagonTests+SOSUpgrade.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCB947592127534C00ED9272 /* OctagonTests+SOSUpgrade.swift */; }; DCBB8AC41D80DD95007ED154 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; DCBDB3B71E57C82300B61300 /* CKKSKeychainView.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3B11E57C67500B61300 /* CKKSKeychainView.m */; }; - DCBDB3B81E57C82300B61300 /* CKKSKeychainView.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3B11E57C67500B61300 /* CKKSKeychainView.m */; }; DCBDB3BB1E57CA7A00B61300 /* CKKSViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBDB3B91E57CA7A00B61300 /* CKKSViewManager.h */; }; - DCBDB3BC1E57CA7A00B61300 /* CKKSViewManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBDB3B91E57CA7A00B61300 /* CKKSViewManager.h */; }; DCBDB3BD1E57CA7A00B61300 /* CKKSViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3BA1E57CA7A00B61300 /* CKKSViewManager.m */; }; - DCBDB3BE1E57CA7A00B61300 /* CKKSViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBDB3BA1E57CA7A00B61300 /* CKKSViewManager.m */; }; DCBF2F7D1F90084D00ED0CA4 /* CKKSTLKSharingTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */; }; DCBF2F851F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */; }; - DCBF2F861F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBF2F831F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h */; }; - DCBF2F881F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */; }; + DCBF4A9A21FFC82100539F0A /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + DCBF4AAE21FFC82100539F0A /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; + DCBF4AB521FFC82100539F0A /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + DCBF4AB621FFC82100539F0A /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + DCBF4AB721FFC82100539F0A /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + DCBF4ABA21FFC82100539F0A /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + DCBF4ABB21FFC82100539F0A /* SecFramework.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E4F1D8085FC00865A7C /* SecFramework.c */; }; + DCBF4ABE21FFC82100539F0A /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + DCBF4AC121FFC82100539F0A /* CoreCDP.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C9FB40120D8729A00864612 /* CoreCDP.framework */; }; + DCBF4AC221FFC82100539F0A /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + DCBF4AC321FFC82100539F0A /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; + DCBF4AC421FFC82100539F0A /* AppleAccount.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C84DA541720698900AEE225 /* AppleAccount.framework */; }; + DCBF4AC521FFC82100539F0A /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DCBF4AC621FFC82100539F0A /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246AF1F9AE73F00D63882 /* libDER.a */; }; + DCBF4AC721FFC82100539F0A /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */; }; + DCBF4AC821FFC82100539F0A /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; + DCBF4AC921FFC82100539F0A /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; + DCBF4ACA21FFC82100539F0A /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; + DCBF4ACB21FFC82100539F0A /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF730310EF9CDE300E17471 /* CFNetwork.framework */; }; + DCBF4ACC21FFC82100539F0A /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + DCBF4ACD21FFC82100539F0A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + DCBF4ACE21FFC82100539F0A /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; + DCBF4ACF21FFC82100539F0A /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC3502E81E02172C00BC0587 /* OCMock.framework */; }; + DCBF4AD021FFC82100539F0A /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + DCBF4AD121FFC82100539F0A /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; + DCBF4AD221FFC82100539F0A /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; + DCBF4AD321FFC82100539F0A /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; + DCBF4AD421FFC82100539F0A /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; + DCBF4AD521FFC82100539F0A /* libctkclient_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; }; + DCBF4AD621FFC82100539F0A /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; + DCBF4AD721FFC82100539F0A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; + DCBF4AE521FFC9B300539F0A /* SecEscrowRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBF4AE321FFC9A800539F0A /* SecEscrowRequestTests.m */; }; + DCBFF832222611A200C5C044 /* OTFetchCKKSKeysOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCBFF830222611A200C5C044 /* OTFetchCKKSKeysOperation.h */; }; + DCBFF833222611A200C5C044 /* OTFetchCKKSKeysOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCBFF831222611A200C5C044 /* OTFetchCKKSKeysOperation.m */; }; DCC093791D80B02100F984E4 /* SecOnOSX.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E671D8085FC00865A7C /* SecOnOSX.h */; }; DCC0937A1D80B07200F984E4 /* SecOTRSessionPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFC15AFB73800B9D400 /* SecOTRSessionPriv.h */; }; DCC0937B1D80B07B00F984E4 /* SecOTRSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFFB15AFB73800B9D400 /* SecOTRSession.h */; }; @@ -4002,10 +4702,14 @@ DCC0937E1D80B0A700F984E4 /* SecOTRPacketData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF915AFB73800B9D400 /* SecOTRPacketData.h */; }; DCC0937F1D80B0B100F984E4 /* SecOTRMath.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF715AFB73800B9D400 /* SecOTRMath.h */; }; DCC093801D80B0B700F984E4 /* SecCFAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */; }; + DCC19518214C53FD00C9E0B6 /* AuthKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4A7DD7320A26CF900F51F3F /* AuthKit.framework */; }; + DCC1951C214C668A00C9E0B6 /* AppleAccount.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C84DA541720698900AEE225 /* AppleAccount.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; DCC19F711EB9151B00B7D70F /* KeychainCKKS.plist in Copy BATS Test Discovery Plist */ = {isa = PBXBuildFile; fileRef = 6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */; }; + DCC51C99209B7C1500A40387 /* print_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA951D80CC2A00B0A59C /* print_cert.c */; }; + DCC54181225C05180095D926 /* OTUploadNewCKKSTLKsOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC5417F225C05170095D926 /* OTUploadNewCKKSTLKsOperation.h */; }; + DCC54182225C05180095D926 /* OTUploadNewCKKSTLKsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC54180225C05180095D926 /* OTUploadNewCKKSTLKsOperation.m */; }; 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 */; }; @@ -4013,7 +4717,6 @@ DCC5BF1F1D93725A008D1E84 /* libsecurity_authorization.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB3406D1D8A24DF0054D16E /* libsecurity_authorization.a */; }; DCC5BF201D937263008D1E84 /* libsecurity_cdsa_plugin.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB341371D8A2A010054D16E /* libsecurity_cdsa_plugin.a */; }; DCC5BF211D937269008D1E84 /* libsecurity_checkpw.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC5B71D8B71FD00070CB0 /* libsecurity_checkpw.a */; }; - DCC5BF221D937270008D1E84 /* libsecurity_cms.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1002C91D8E19D70025549C /* libsecurity_cms.a */; }; DCC5BF231D937277008D1E84 /* libsecurity_comcryption.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC5E91D8B742200070CB0 /* libsecurity_comcryption.a */; }; DCC5BF241D93727E008D1E84 /* libsecurity_cryptkit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC5FF1D8B752B00070CB0 /* libsecurity_cryptkit.a */; }; DCC5BF251D937288008D1E84 /* libsecurity_cssm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC74C1D8B771600070CB0 /* libsecurity_cssm.a */; }; @@ -4024,11 +4727,14 @@ DCC5BF2A1D93729E008D1E84 /* libsecurity_ssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC9CF1D8B824700070CB0 /* libsecurity_ssl.a */; }; DCC5BF2B1D9372A4008D1E84 /* libsecurity_transform.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCA801D8B858600070CB0 /* libsecurity_transform.a */; }; DCC5BF2C1D9372AA008D1E84 /* libsecurity_translocate.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCB081D8B894F00070CB0 /* libsecurity_translocate.a */; }; + DCC67E0E20DD7E0A00A70A31 /* OTStates.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC67E0C20DD7E0A00A70A31 /* OTStates.h */; }; + DCC67E1020DD7E0A00A70A31 /* OTStates.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC67E0D20DD7E0A00A70A31 /* OTStates.m */; }; + DCC67E2D20DDC07900A70A31 /* OTPrepareOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC67E2B20DDC07900A70A31 /* OTPrepareOperation.h */; }; + DCC67E2F20DDC07900A70A31 /* OTPrepareOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC67E2C20DDC07900A70A31 /* OTPrepareOperation.m */; }; DCC78EB81D80899C00865A7C /* vmdh.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9C1D8085FC00865A7C /* vmdh.c */; }; DCC78EB91D8089A700865A7C /* pbkdf2.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E2E1D8085FC00865A7C /* pbkdf2.c */; }; DCC78EBA1D8089BD00865A7C /* p12pbegen.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E2C1D8085FC00865A7C /* p12pbegen.c */; }; DCC78EBB1D8089C200865A7C /* p12import.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E2A1D8085FC00865A7C /* p12import.c */; }; - DCC78EBC1D8089CD00865A7C /* verify_cert.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E191D8085FC00865A7C /* verify_cert.c */; }; DCC78EBD1D808A0400865A7C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; DCC78EBE1D808A0E00865A7C /* SecTrustStore.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E971D8085FC00865A7C /* SecTrustStore.c */; }; DCC78EC01D808A1C00865A7C /* SecTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E901D8085FC00865A7C /* SecTrust.c */; }; @@ -4051,7 +4757,7 @@ DCC78ED11D808A8E00865A7C /* SecOTRFullIdentity.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E6C1D8085FC00865A7C /* SecOTRFullIdentity.c */; }; DCC78ED21D808A9500865A7C /* SecOTRDHKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E691D8085FC00865A7C /* SecOTRDHKey.c */; }; DCC78ED31D808AA000865A7C /* SecKeyAdaptors.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */; }; - DCC78ED41D808AA800865A7C /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; }; + DCC78ED41D808AA800865A7C /* SecKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.m */; }; 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 */; }; @@ -4082,9 +4788,9 @@ DCCD33E91E3FFDBF00AA4AD1 /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; DCCD34001E4001AD00AA4AD1 /* libACM.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC610A3A1D78F228002223DE /* libACM.a */; }; DCCD88E81E42622200F5AA71 /* CKKSGroupOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCCD88E61E42622200F5AA71 /* CKKSGroupOperation.h */; }; - DCCD88E91E42622200F5AA71 /* CKKSGroupOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCCD88E61E42622200F5AA71 /* CKKSGroupOperation.h */; }; DCCD88EA1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCCD88E71E42622200F5AA71 /* CKKSGroupOperation.m */; }; - DCCD88EB1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCCD88E71E42622200F5AA71 /* CKKSGroupOperation.m */; }; + DCCFB14E212394EC003D2DA2 /* libaks_mock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC36895E21235F42003A3735 /* libaks_mock.a */; }; + DCCFB14F21239534003D2DA2 /* libaks_mock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC36895E21235F42003A3735 /* libaks_mock.a */; }; DCD0676E1D8CDECD007602F1 /* gkmerge in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCD067631D8CDEB2007602F1 /* gkmerge */; }; DCD0676F1D8CDED1007602F1 /* gkhandmake in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCD067641D8CDEB2007602F1 /* gkhandmake */; }; DCD067701D8CDED5007602F1 /* gklist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCD067651D8CDEB2007602F1 /* gklist */; }; @@ -4151,8 +4857,6 @@ DCD0684E1D8CDF7E007602F1 /* cskernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067CA1D8CDF7E007602F1 /* cskernel.cpp */; }; DCD0684F1D8CDF7E007602F1 /* csprocess.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067CB1D8CDF7E007602F1 /* csprocess.h */; }; DCD068501D8CDF7E007602F1 /* csprocess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067CC1D8CDF7E007602F1 /* csprocess.cpp */; }; - DCD068511D8CDF7E007602F1 /* csgeneric.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067CD1D8CDF7E007602F1 /* csgeneric.h */; }; - DCD068521D8CDF7E007602F1 /* csgeneric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067CE1D8CDF7E007602F1 /* csgeneric.cpp */; }; DCD068531D8CDF7E007602F1 /* diskrep.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067D01D8CDF7E007602F1 /* diskrep.h */; }; DCD068541D8CDF7E007602F1 /* diskrep.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067D11D8CDF7E007602F1 /* diskrep.cpp */; }; DCD068551D8CDF7E007602F1 /* filediskrep.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067D21D8CDF7E007602F1 /* filediskrep.h */; }; @@ -4283,8 +4987,6 @@ DCD069431D8CDFFF007602F1 /* TokenStreamRewriteEngine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD068EF1D8CDFFE007602F1 /* TokenStreamRewriteEngine.cpp */; }; DCD069441D8CDFFF007602F1 /* TokenStreamSelector.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD068F01D8CDFFE007602F1 /* TokenStreamSelector.cpp */; }; DCD069451D8CDFFF007602F1 /* TreeParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD068F11D8CDFFE007602F1 /* TreeParser.cpp */; }; - DCD06A521D8CE29C007602F1 /* SecCodeHostLib.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD067E71D8CDF7E007602F1 /* SecCodeHostLib.h */; }; - DCD06A531D8CE2A4007602F1 /* SecCodeHostLib.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD067E81D8CDF7E007602F1 /* SecCodeHostLib.c */; }; DCD06A751D8CE2F0007602F1 /* gkunpack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD0676B1D8CDEB2007602F1 /* gkunpack.cpp */; }; DCD06A761D8CE2F7007602F1 /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD0677F1D8CDF19007602F1 /* libsecurity_codesigning.a */; }; DCD06A781D8CE309007602F1 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; @@ -4310,8 +5012,6 @@ DCD06B4F1D8E0D7D007602F1 /* debugging_internal.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AC31D8E0D7D007602F1 /* debugging_internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B501D8E0D7D007602F1 /* debugsupport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AC41D8E0D7D007602F1 /* debugsupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B511D8E0D7D007602F1 /* debugging_internal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AC51D8E0D7D007602F1 /* debugging_internal.cpp */; }; - DCD06B521D8E0D7D007602F1 /* devrandom.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AC61D8E0D7D007602F1 /* devrandom.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCD06B531D8E0D7D007602F1 /* devrandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AC71D8E0D7D007602F1 /* devrandom.cpp */; }; DCD06B541D8E0D7D007602F1 /* dispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AC81D8E0D7D007602F1 /* dispatch.cpp */; }; DCD06B551D8E0D7D007602F1 /* dispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AC91D8E0D7D007602F1 /* dispatch.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B561D8E0D7D007602F1 /* endian.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06ACA1D8E0D7D007602F1 /* endian.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -4338,8 +5038,6 @@ DCD06B6E1D8E0D7D007602F1 /* simpleprefs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AE21D8E0D7D007602F1 /* simpleprefs.cpp */; }; DCD06B6F1D8E0D7D007602F1 /* sqlite++.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AE31D8E0D7D007602F1 /* sqlite++.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B701D8E0D7D007602F1 /* sqlite++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AE41D8E0D7D007602F1 /* sqlite++.cpp */; }; - DCD06B711D8E0D7D007602F1 /* streams.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AE51D8E0D7D007602F1 /* streams.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCD06B721D8E0D7D007602F1 /* streams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AE61D8E0D7D007602F1 /* streams.cpp */; }; DCD06B731D8E0D7D007602F1 /* superblob.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AE71D8E0D7D007602F1 /* superblob.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B741D8E0D7D007602F1 /* superblob.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06AE81D8E0D7D007602F1 /* superblob.cpp */; }; DCD06B751D8E0D7D007602F1 /* threading.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06AE91D8E0D7D007602F1 /* threading.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -4366,12 +5064,8 @@ DCD06B921D8E0D7D007602F1 /* unix++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B061D8E0D7D007602F1 /* unix++.cpp */; }; DCD06B931D8E0D7D007602F1 /* unixchild.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B071D8E0D7D007602F1 /* unixchild.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B941D8E0D7D007602F1 /* unixchild.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B081D8E0D7D007602F1 /* unixchild.cpp */; }; - DCD06B951D8E0D7D007602F1 /* vproc++.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B091D8E0D7D007602F1 /* vproc++.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCD06B961D8E0D7D007602F1 /* vproc++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B0A1D8E0D7D007602F1 /* vproc++.cpp */; }; DCD06B971D8E0D7D007602F1 /* mach++.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B0C1D8E0D7D007602F1 /* mach++.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B981D8E0D7D007602F1 /* mach++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B0D1D8E0D7D007602F1 /* mach++.cpp */; }; - DCD06B991D8E0D7D007602F1 /* mach_notify.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B0E1D8E0D7D007602F1 /* mach_notify.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCD06B9A1D8E0D7D007602F1 /* mach_notify.c in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B0F1D8E0D7D007602F1 /* mach_notify.c */; }; DCD06B9B1D8E0D7D007602F1 /* cfmach++.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B101D8E0D7D007602F1 /* cfmach++.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06B9C1D8E0D7D007602F1 /* cfmach++.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B111D8E0D7D007602F1 /* cfmach++.cpp */; }; DCD06B9D1D8E0D7D007602F1 /* macho++.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B121D8E0D7D007602F1 /* macho++.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -4381,8 +5075,6 @@ DCD06BA11D8E0D7D007602F1 /* dyld_cache_format.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B161D8E0D7D007602F1 /* dyld_cache_format.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06BA21D8E0D7D007602F1 /* machserver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B171D8E0D7D007602F1 /* machserver.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06BA31D8E0D7D007602F1 /* machserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B181D8E0D7D007602F1 /* machserver.cpp */; }; - DCD06BA41D8E0D7D007602F1 /* machrunloopserver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B191D8E0D7D007602F1 /* machrunloopserver.h */; settings = {ATTRIBUTES = (Public, ); }; }; - DCD06BA51D8E0D7D007602F1 /* machrunloopserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B1A1D8E0D7D007602F1 /* machrunloopserver.cpp */; }; DCD06BA61D8E0D7D007602F1 /* coderepository.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B1C1D8E0D7D007602F1 /* coderepository.h */; settings = {ATTRIBUTES = (Public, ); }; }; DCD06BA71D8E0D7D007602F1 /* coderepository.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD06B1D1D8E0D7D007602F1 /* coderepository.cpp */; }; DCD06BA81D8E0D7D007602F1 /* cfclass.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD06B1E1D8E0D7D007602F1 /* cfclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -4400,25 +5092,25 @@ DCD06BD51D8E173A007602F1 /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD0677F1D8CDF19007602F1 /* libsecurity_codesigning.a */; }; DCD06BD61D8E175D007602F1 /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */; }; DCD06BD71D8E17A0007602F1 /* libsecurity_codesigning.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD0677F1D8CDF19007602F1 /* libsecurity_codesigning.a */; }; - DCD22D4B1D8CBF54001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D4B1D8CBF54001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D4C1D8CBF7E001C9B81 /* libsecurityd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC6A82921D87749900418608 /* libsecurityd_client.a */; }; DCD22D4D1D8CBF95001C9B81 /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB341821D8A2B860054D16E /* libsecurity_cdsa_utilities.a */; }; DCD22D4E1D8CBFAB001C9B81 /* libsecurity_cdsa_utils.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC58C1D8B70E700070CB0 /* libsecurity_cdsa_utils.a */; }; DCD22D511D8CC039001C9B81 /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB341821D8A2B860054D16E /* libsecurity_cdsa_utilities.a */; }; DCD22D521D8CC053001C9B81 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; - DCD22D531D8CC0EF001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D531D8CC0EF001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D541D8CC0FC001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D551D8CC148001C9B81 /* libsecurity_keychain_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB3443E1D8A34FD0054D16E /* libsecurity_keychain_regressions.a */; }; DCD22D561D8CC154001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D571D8CC196001C9B81 /* libsecurity_ssl_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCA1A1D8B82B000070CB0 /* libsecurity_ssl_regressions.a */; }; - DCD22D581D8CC1FA001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D581D8CC1FA001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D591D8CC200001C9B81 /* libsecurity_cdsa_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB340951D8A267C0054D16E /* libsecurity_cdsa_client.a */; }; DCD22D5A1D8CC205001C9B81 /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB341821D8A2B860054D16E /* libsecurity_cdsa_utilities.a */; }; DCD22D5B1D8CC20D001C9B81 /* libsecurity_cdsa_utils.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC58C1D8B70E700070CB0 /* libsecurity_cdsa_utils.a */; }; DCD22D5C1D8CC224001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D5E1D8CC269001C9B81 /* libsecurity_keychain_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB3443E1D8A34FD0054D16E /* libsecurity_keychain_regressions.a */; }; DCD22D5F1D8CC294001C9B81 /* libsecurity_ssl_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCA1A1D8B82B000070CB0 /* libsecurity_ssl_regressions.a */; }; - DCD22D601D8CC2EF001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D601D8CC2EF001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D611D8CC2F8001C9B81 /* libbsm.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 107227350D91FE89003CF14F /* libbsm.dylib */; }; DCD22D631D8CC33A001C9B81 /* libSOSRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC681D80D0C400B0A59C /* libSOSRegressions.a */; }; DCD22D641D8CC341001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; @@ -4430,11 +5122,11 @@ DCD22D6E1D8CC71D001C9B81 /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB341821D8A2B860054D16E /* libsecurity_cdsa_utilities.a */; }; DCD22D6F1D8CC728001C9B81 /* libsecurity_cdsa_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB340951D8A267C0054D16E /* libsecurity_cdsa_client.a */; }; DCD22D701D8CC733001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - DCD22D711D8CC78E001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D711D8CC78E001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D721D8CC804001C9B81 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; DCD22D751D8CC8A5001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D761D8CC8CF001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - DCD22D771D8CC9CD001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D771D8CC9CD001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D781D8CC9D8001C9B81 /* libsecurity_ssl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC9CF1D8B824700070CB0 /* libsecurity_ssl.a */; }; DCD22D791D8CC9F1001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D801D8CCB0F001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; @@ -4444,13 +5136,13 @@ DCD22D881D8CCBEF001C9B81 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; settings = {ATTRIBUTES = (Weak, ); }; }; DCD22D891D8CCC1F001C9B81 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; DCD22D8A1D8CCC23001C9B81 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; - DCD22D8B1D8CCC58001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D8B1D8CCC58001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D8C1D8CCC63001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D8D1D8CCC79001C9B81 /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; DCD22D901D8CCCA0001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D911D8CCCB7001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D921D8CCD09001C9B81 /* libsecurity_ssl_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCA1A1D8B82B000070CB0 /* libsecurity_ssl_regressions.a */; }; - DCD22D931D8CCD17001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D931D8CCD17001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D941D8CCDFA001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D951D8CCE5E001C9B81 /* libutilitiesRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */; }; DCD22D961D8CCF08001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; @@ -4458,24 +5150,31 @@ DCD22D981D8CCF78001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; DCD22D991D8CCFB4001C9B81 /* libsecurity_ssl_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCA1A1D8B82B000070CB0 /* libsecurity_ssl_regressions.a */; }; DCD22D9A1D8CCFC1001C9B81 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - DCD22D9B1D8CCFCB001C9B81 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + DCD22D9B1D8CCFCB001C9B81 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */; }; + DCD24DEC228C9A480052604C /* SetValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CE15E2A222DF63500B7EAA5 /* SetValueTransformer.swift */; }; + DCD33D7C220B99CC000A390B /* EscrowRequestController.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD33D7A220B985A000A390B /* EscrowRequestController.m */; }; + DCD33D80220B9DC8000A390B /* OctagonStateMachineHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD33D7E220B9DC8000A390B /* OctagonStateMachineHelpers.h */; }; + DCD33D81220B9DC8000A390B /* OctagonStateMachineHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD33D7F220B9DC8000A390B /* OctagonStateMachineHelpers.m */; }; + DCD33D8E220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD33D8C220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.h */; }; + DCD33D8F220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD33D8D220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.m */; }; + DCD33D93220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD33D91220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.h */; }; + DCD33D94220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD33D92220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.m */; }; 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 */; }; + DCD48BFE20BF3D83009A3224 /* tpctl-objc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD48BFD20BF3D83009A3224 /* tpctl-objc.m */; }; 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 */; }; - DCD662F81E329B6800188186 /* CKKSNewTLKOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD662F41E329B6800188186 /* CKKSNewTLKOperation.m */; }; 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.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E491D8085FC00865A7C /* SecECKey.m */; }; - DCD66DB61D82050900DB1393 /* SecKey.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.c */; }; + DCD66DB61D82050900DB1393 /* SecKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E601D8085FC00865A7C /* SecKey.m */; }; 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 */; }; @@ -4495,10 +5194,10 @@ DCD66DE31D8205FB00DB1393 /* SecOTRSession.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E751D8085FC00865A7C /* SecOTRSession.c */; }; DCD66DE41D8205FB00DB1393 /* SecOTRSessionAKE.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E771D8085FC00865A7C /* SecOTRSessionAKE.c */; }; DCD6C4B21EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6C4B01EC5302400414FEE /* CKKSNearFutureScheduler.h */; }; - DCD6C4B31EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD6C4B01EC5302400414FEE /* CKKSNearFutureScheduler.h */; }; DCD6C4B41EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */; }; - DCD6C4B51EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */; }; DCD6C4B71EC5319600414FEE /* CKKSNearFutureSchedulerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD6C4B61EC5319600414FEE /* CKKSNearFutureSchedulerTests.m */; }; + DCD7DD9F22B868F800161396 /* TPPBDispositionDuplicateMachineID.m in Sources */ = {isa = PBXBuildFile; fileRef = DCD7DD9B22B868C100161396 /* TPPBDispositionDuplicateMachineID.m */; }; + DCD7DDA022B86A5500161396 /* TPPBDispositionDuplicateMachineID.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD7DD9D22B868C200161396 /* TPPBDispositionDuplicateMachineID.h */; settings = {ATTRIBUTES = (Private, ); }; }; DCD7EE841F4E46F9007D9804 /* accountCirclesViewsPrint.m in Sources */ = {isa = PBXBuildFile; fileRef = 48C2F9321E4BCFC30093D70C /* accountCirclesViewsPrint.m */; }; DCD7EE851F4E47D2007D9804 /* reqparser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCD067C31D8CDF7E007602F1 /* reqparser.cpp */; }; DCD7EE981F4F4DE9007D9804 /* SecBase64.h in Headers */ = {isa = PBXBuildFile; fileRef = 18351B8F14CB65870097860E /* SecBase64.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -4506,7 +5205,6 @@ DCD7EE9A1F4F5156007D9804 /* oidsocsp.h in Headers */ = {isa = PBXBuildFile; fileRef = DC88344F1D8A21AA00CE0ACA /* oidsocsp.h */; settings = {ATTRIBUTES = (Private, ); }; }; DCD7EEA41F4F58D7007D9804 /* SecLogging.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E661D8085FC00865A7C /* SecLogging.h */; settings = {ATTRIBUTES = (Private, ); }; }; DCD8A0CF1E09EA1800E4FA0A /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; - DCD8A1321E09EE0F00E4FA0A /* SOSPeerInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D631D8085F200865A7C /* SOSPeerInfo.m */; }; DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D4A1D8085F200865A7C /* SOSViews.m */; }; DCD8A15A1E09EE0F00E4FA0A /* SOSAccountTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D151D8085F200865A7C /* SOSAccountTransaction.h */; }; DCD8A15C1E09EE0F00E4FA0A /* SOSBackupSliceKeyBag.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D2A1D8085F200865A7C /* SOSBackupSliceKeyBag.h */; }; @@ -4514,7 +5212,6 @@ DCD8A15F1E09EE0F00E4FA0A /* SOSCirclePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D311D8085F200865A7C /* SOSCirclePriv.h */; }; DCD8A1601E09EE0F00E4FA0A /* SOSCircleRings.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D331D8085F200865A7C /* SOSCircleRings.h */; }; DCD8A1611E09EE0F00E4FA0A /* SOSCircleV2.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D301D8085F200865A7C /* SOSCircleV2.h */; }; - DCD8A1621E09EE0F00E4FA0A /* SOSCloudCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */; }; DCD8A1631E09EE0F00E4FA0A /* SOSCloudCircleInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8B1D8085F200865A7C /* SOSCloudCircleInternal.h */; }; DCD8A1641E09EE0F00E4FA0A /* SOSCloudKeychainClient.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78CF71D8085F200865A7C /* SOSCloudKeychainClient.h */; }; DCD8A1651E09EE0F00E4FA0A /* SOSCloudKeychainConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78CF91D8085F200865A7C /* SOSCloudKeychainConstants.h */; }; @@ -4525,20 +5222,13 @@ DCD8A16F1E09EE0F00E4FA0A /* SOSKVSKeys.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D731D8085F200865A7C /* SOSKVSKeys.h */; }; DCD8A1741E09EE0F00E4FA0A /* SOSPeerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D641D8085F200865A7C /* SOSPeerInfo.h */; }; DCD8A17C1E09EE0F00E4FA0A /* SOSPlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D901D8085F200865A7C /* SOSPlatform.h */; }; - DCD8A17D1E09EE0F00E4FA0A /* SOSRing.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D391D8085F200865A7C /* SOSRing.h */; }; - DCD8A17E1E09EE0F00E4FA0A /* SOSRingBackup.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D3B1D8085F200865A7C /* SOSRingBackup.h */; }; DCD8A17F1E09EE0F00E4FA0A /* SOSKeyedPubKeyIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 485B64091DC16E8300B771B9 /* SOSKeyedPubKeyIdentifier.h */; }; DCD8A1801E09EE0F00E4FA0A /* SOSRingBasic.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D3D1D8085F200865A7C /* SOSRingBasic.h */; }; DCD8A1821E09EE0F00E4FA0A /* SOSAccountGhost.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFAEDC91D999851005187E4 /* SOSAccountGhost.h */; }; - DCD8A1831E09EE0F00E4FA0A /* SOSRingConcordanceTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D3F1D8085F200865A7C /* SOSRingConcordanceTrust.h */; }; - DCD8A1841E09EE0F00E4FA0A /* SOSRecoveryKeyBag.h in Headers */ = {isa = PBXBuildFile; fileRef = 48776C741DA5BB4200CC09B9 /* SOSRecoveryKeyBag.h */; }; DCD8A1851E09EE0F00E4FA0A /* SOSRingDER.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D411D8085F200865A7C /* SOSRingDER.h */; }; DCD8A1861E09EE0F00E4FA0A /* SOSRingPeerInfoUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D431D8085F200865A7C /* SOSRingPeerInfoUtils.h */; }; - DCD8A1871E09EE0F00E4FA0A /* SOSRingTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D451D8085F200865A7C /* SOSRingTypes.h */; }; DCD8A1891E09EE0F00E4FA0A /* SOSRingUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D471D8085F200865A7C /* SOSRingUtils.h */; }; DCD8A18A1E09EE0F00E4FA0A /* SOSRingV0.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D491D8085F200865A7C /* SOSRingV0.h */; }; - DCD8A18B1E09EE0F00E4FA0A /* SOSTransport.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D751D8085F200865A7C /* SOSTransport.h */; }; - DCD8A1901E09EE0F00E4FA0A /* SOSAccountTrust.h in Headers */ = {isa = PBXBuildFile; fileRef = CD31F8611DCD4C1400414B46 /* SOSAccountTrust.h */; }; DCD8A1931E09EE0F00E4FA0A /* SOSTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D8F1D8085F200865A7C /* SOSTypes.h */; }; DCD8A1951E09EE0F00E4FA0A /* SOSViews.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D4B1D8085F200865A7C /* SOSViews.h */; }; DCD8A19A1E09EE9800E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; @@ -4551,9 +5241,6 @@ DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D671D8085F200865A7C /* SOSPeerInfoV2.m */; }; DCD8A1A61E09EFD700E4FA0A /* SOSKVSKeys.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D721D8085F200865A7C /* SOSKVSKeys.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 */; }; - DCD8A1B01E09F0F400E4FA0A /* SOSRingTypes.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D441D8085F200865A7C /* SOSRingTypes.m */; }; DCD8A1B11E09F11900E4FA0A /* SOSPeerInfoDER.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D651D8085F200865A7C /* SOSPeerInfoDER.m */; }; DCD8A1B21E09F11900E4FA0A /* SOSPeerInfoRingState.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D6D1D8085F200865A7C /* SOSPeerInfoRingState.m */; }; DCD8A1B31E09F12D00E4FA0A /* SOSCircle.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D2E1D8085F200865A7C /* SOSCircle.c */; }; @@ -4561,15 +5248,8 @@ DCD8A1B51E09F15400E4FA0A /* SOSGenCount.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D371D8085F200865A7C /* SOSGenCount.c */; }; DCD8A1B61E09F16C00E4FA0A /* SOSKeyedPubKeyIdentifier.c in Sources */ = {isa = PBXBuildFile; fileRef = 485B64081DC16E8300B771B9 /* SOSKeyedPubKeyIdentifier.c */; }; DCD8A1B71E09F19100E4FA0A /* SOSRingV0.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D481D8085F200865A7C /* SOSRingV0.m */; }; - DCD8A1B81E09F1BB00E4FA0A /* SOSRingBackup.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D3A1D8085F200865A7C /* SOSRingBackup.m */; }; - DCD8A1B91E09F1BB00E4FA0A /* SOSRingBasic.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D3C1D8085F200865A7C /* SOSRingBasic.m */; }; - DCD8A1BA1E09F1BB00E4FA0A /* SOSRingRecovery.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C7C1DA5BB5F00CC09B9 /* SOSRingRecovery.m */; }; - DCD8A1BB1E09F1BB00E4FA0A /* SOSRingConcordanceTrust.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D3E1D8085F200865A7C /* SOSRingConcordanceTrust.c */; }; DCD8A1BC1E09F1BB00E4FA0A /* SOSRingPeerInfoUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D421D8085F200865A7C /* SOSRingPeerInfoUtils.c */; }; DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D611D8085F200865A7C /* SOSFullPeerInfo.m */; }; - DCD8A1C21E09F23B00E4FA0A /* SOSRecoveryKeyBag.m in Sources */ = {isa = PBXBuildFile; fileRef = 48776C731DA5BB4200CC09B9 /* SOSRecoveryKeyBag.m */; }; - DCD8A1C71E09F2B400E4FA0A /* SOSTransport.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D741D8085F200865A7C /* SOSTransport.m */; }; - DCD8A1DB1E09F5D100E4FA0A /* SOSAccountTrust.m in Sources */ = {isa = PBXBuildFile; fileRef = CD31F8601DCD4C1400414B46 /* SOSAccountTrust.m */; }; DCD8A1DC1E09F5E500E4FA0A /* SOSAccount.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D131D8085F200865A7C /* SOSAccount.h */; }; DCD8A1DD1E09F73F00E4FA0A /* SOSPeerInfoDER.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D661D8085F200865A7C /* SOSPeerInfoDER.h */; }; DCD8A1DE1E09F74700E4FA0A /* SOSPeerInfoV2.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D681D8085F200865A7C /* SOSPeerInfoV2.h */; }; @@ -4577,17 +5257,12 @@ DCD8A1E01E09F76800E4FA0A /* SOSPeerInfoRingState.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D6E1D8085F200865A7C /* SOSPeerInfoRingState.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 */; }; - DCD8A1EA1E09F87B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1ED1E09F8B500E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1F01E09F8D100E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1F31E09F91700E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; - DCD8A1F61E09F96900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1F91E09F98E00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1FC1E09FA0B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A1FF1E09FA6100E4FA0A /* secViewDisplay.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D9E1D8085F200865A7C /* secViewDisplay.c */; }; - DCD8A2011E09FAD900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; - DCD8A2041E09FB0D00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A20A1E09FB5900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; settings = {ATTRIBUTES = (Weak, ); }; }; DCD8A20B1E09FB5A00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; DCD8A20C1E09FB6600E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; @@ -4621,17 +5296,53 @@ DCDD59CF1F69ACF70060641E /* SOSPeerInfo.h in Copy SecureObjectSync Headers */ = {isa = PBXBuildFile; fileRef = DCC78D641D8085F200865A7C /* SOSPeerInfo.h */; }; 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 */; }; + DCDF03122284E34B008055BA /* OctagonTests+EscrowRecovery.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCDF03112284E34B008055BA /* OctagonTests+EscrowRecovery.swift */; }; DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */ = {isa = PBXBuildFile; fileRef = 4CB7405F0A47498100D641BB /* Security.exp-in */; }; + DCE0774321ADD635002662FD /* TPPBPeerDynamicInfo.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE7089CB1FA3B19A001ACC20 /* TPPBPeerDynamicInfo.proto */; }; + DCE0774621ADD638002662FD /* TPPBDisposition.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEC3739B20CF2AA200DBDF5B /* TPPBDisposition.proto */; }; + DCE0774721ADD63A002662FD /* TPPBDispositionEntry.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEC373C120D8224A00DBDF5B /* TPPBDispositionEntry.proto */; }; + DCE0774821ADD63C002662FD /* TPPBAncientEpoch.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEC373A820D810DA00DBDF5B /* TPPBAncientEpoch.proto */; }; + DCE0774921ADD63E002662FD /* TPPBPolicyProhibits.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEC373A620D810D800DBDF5B /* TPPBPolicyProhibits.proto */; }; + DCE0774A21ADD640002662FD /* TPPBUnknownMachineID.proto in Sources */ = {isa = PBXBuildFile; fileRef = BEC373A720D810D900DBDF5B /* TPPBUnknownMachineID.proto */; }; + DCE0774B21ADD642002662FD /* TPPBPeerStableInfo.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE7089CC1FA3B332001ACC20 /* TPPBPeerStableInfo.proto */; }; + DCE0774C21ADD648002662FD /* TPPBPeerPermanentInfo.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE7089DB1FA407E4001ACC20 /* TPPBPeerPermanentInfo.proto */; }; + DCE0774D21ADD64A002662FD /* TPPBPolicySecret.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE7089D91FA3F0AF001ACC20 /* TPPBPolicySecret.proto */; }; + DCE0774E21ADD64C002662FD /* TPPBPolicyDocument.proto in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C807D20EAF86100334E33 /* TPPBPolicyDocument.proto */; }; + DCE0774F21ADD651002662FD /* TPPBPolicyCategoriesByView.proto in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C807F20EAFB9600334E33 /* TPPBPolicyCategoriesByView.proto */; }; + DCE0775021ADD655002662FD /* TPPBPolicyModelToCategory.proto in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C808020EAFB9600334E33 /* TPPBPolicyModelToCategory.proto */; }; + DCE0775121ADD658002662FD /* TPPBPolicyIntroducersByCategory.proto in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C808320EAFD7A00334E33 /* TPPBPolicyIntroducersByCategory.proto */; }; + DCE0775221ADD65A002662FD /* TPPBPolicyRedaction.proto in Sources */ = {isa = PBXBuildFile; fileRef = 6C70D8D520EBDE4500AB6FAF /* TPPBPolicyRedaction.proto */; }; + DCE0775321ADD65E002662FD /* OTAuthenticatedCiphertext.proto in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582BD218915270040C5F2 /* OTAuthenticatedCiphertext.proto */; }; + DCE0775421ADD661002662FD /* OTBottle.proto in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582BE218915270040C5F2 /* OTBottle.proto */; }; + DCE0775521ADD663002662FD /* OTBottleContents.proto in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582BF218915280040C5F2 /* OTBottleContents.proto */; }; + DCE0775621ADD665002662FD /* OTPrivateKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = 0CB582BC218915270040C5F2 /* OTPrivateKey.proto */; }; + DCE0775721ADD669002662FD /* SecDbKeychainSerializedItemV7.proto in Sources */ = {isa = PBXBuildFile; fileRef = 47922D4E1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto */; }; + DCE0775821ADD66B002662FD /* SecDbKeychainSerializedAKSWrappedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = 47922D171FAA65120008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.proto */; }; + DCE0775921ADD66E002662FD /* SecDbKeychainSerializedMetadata.proto in Sources */ = {isa = PBXBuildFile; fileRef = 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */; }; + DCE0775A21ADD671002662FD /* SecDbKeychainSerializedSecretData.proto in Sources */ = {isa = PBXBuildFile; fileRef = 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */; }; + DCE0775E21ADD71C002662FD /* TPPBDispositionEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC373C920D822CD00DBDF5B /* TPPBDispositionEntry.m */; }; + DCE0776021ADD71C002662FD /* TPPBAncientEpoch.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC373AD20D815E100DBDF5B /* TPPBAncientEpoch.m */; }; + DCE0776221ADD71C002662FD /* TPPBPolicyProhibits.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC373AE20D815E200DBDF5B /* TPPBPolicyProhibits.m */; }; + DCE0776421ADD71C002662FD /* TPPBUnknownMachineID.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC373AC20D815E000DBDF5B /* TPPBUnknownMachineID.m */; }; + DCE0776621ADD71C002662FD /* TPPBDisposition.m in Sources */ = {isa = PBXBuildFile; fileRef = BEC373A320CF3B5C00DBDF5B /* TPPBDisposition.m */; }; + DCE0776821ADD71C002662FD /* TPPBPeerPermanentInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = BE7089DE1FA40B95001ACC20 /* TPPBPeerPermanentInfo.m */; }; + DCE0776A21ADD71C002662FD /* TPPBPeerDynamicInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = BE7089D21FA3BA03001ACC20 /* TPPBPeerDynamicInfo.m */; }; + DCE0776C21ADD71C002662FD /* TPPBPolicySecret.m in Sources */ = {isa = PBXBuildFile; fileRef = BE7089D01FA3BA01001ACC20 /* TPPBPolicySecret.m */; }; + DCE0776E21ADD71C002662FD /* TPPBPeerStableInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = BE7089D11FA3BA02001ACC20 /* TPPBPeerStableInfo.m */; }; + DCE0777021ADD71C002662FD /* TPPBVoucher.m in Sources */ = {isa = PBXBuildFile; fileRef = BE70899B1F9AAFF7001ACC20 /* TPPBVoucher.m */; }; + DCE0777221ADD71C002662FD /* TPPBPolicyDocument.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C807520EAF81900334E33 /* TPPBPolicyDocument.m */; }; + DCE0777421ADD71C002662FD /* TPPBPolicyCategoriesByView.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C70D8D420EB02B700AB6FAF /* TPPBPolicyCategoriesByView.m */; }; + DCE0777621ADD71C002662FD /* TPPBPolicyIntroducersByCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C809520EB024800334E33 /* TPPBPolicyIntroducersByCategory.m */; }; + DCE0777821ADD71C002662FD /* TPPBPolicyModelToCategory.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C0C809920EB024900334E33 /* TPPBPolicyModelToCategory.m */; }; + DCE0777A21ADD71C002662FD /* TPPBPolicyRedaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C70D8DD20EBDFD600AB6FAF /* TPPBPolicyRedaction.m */; }; + DCE0777F21ADEC07002662FD /* OTAccountMetadataClassC.m in Sources */ = {isa = PBXBuildFile; fileRef = 0C89BDA021554DD2003F3CC0 /* OTAccountMetadataClassC.m */; }; + DCE0778021ADEC4B002662FD /* CKKSSerializedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = DC9FD3261F858D3E00C8AAC8 /* CKKSSerializedKey.m */; }; 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 */; }; - DCE278E01ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */; }; DCE278E81ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */; }; - DCE278E91ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */; }; DCE278EA1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278E71ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m */; }; - DCE278EB1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE278E71ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m */; }; DCE4E6921D7A37FA00AFB96E /* security_tool_commands.c in Sources */ = {isa = PBXBuildFile; fileRef = E7104A0B169E171900DB0045 /* security_tool_commands.c */; }; DCE4E6931D7A37FA00AFB96E /* NSFileHandle+Formatting.m in Sources */ = {isa = PBXBuildFile; fileRef = E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */; }; DCE4E6961D7A37FA00AFB96E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; @@ -4648,9 +5359,6 @@ DCE4E75E1D7A43B500AFB96E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; DCE4E7681D7A43B500AFB96E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; DCE4E76D1D7A43B500AFB96E /* nist-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886E81CEBDD2A00DC7583 /* nist-certs */; }; - DCE4E76E1D7A43B500AFB96E /* ssl-policy-certs in Resources */ = {isa = PBXBuildFile; fileRef = D4D886BE1CEB9F3B00DC7583 /* ssl-policy-certs */; }; - DCE4E76F1D7A43B500AFB96E /* si-20-sectrust-policies-data in Resources */ = {isa = PBXBuildFile; fileRef = D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */; }; - DCE4E7701D7A43B500AFB96E /* si-82-sectrust-ct-data in Resources */ = {isa = PBXBuildFile; fileRef = 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */; }; DCE4E7721D7A43B500AFB96E /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFD1410671D00EE92DE /* Invalid-asterisk.google.com.crt */; }; DCE4E7731D7A43B500AFB96E /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFE1410671D00EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt */; }; DCE4E7741D7A43B500AFB96E /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */ = {isa = PBXBuildFile; fileRef = 4C50ACFF1410671D00EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt */; }; @@ -4707,18 +5415,15 @@ DCE4E7AA1D7A43B500AFB96E /* Digisign-Server-ID-Enrich-GTETrust-Cert.crt in Copy DigiCertMalaysia Resources */ = {isa = PBXBuildFile; fileRef = 7947431C146214E500D638A3 /* Digisign-Server-ID-Enrich-GTETrust-Cert.crt */; }; DCE4E7AB1D7A43B500AFB96E /* Invalid-webmail.jaring.my.crt in Copy DigiCertMalaysia Resources */ = {isa = PBXBuildFile; fileRef = 79679E261462028800CF997F /* Invalid-webmail.jaring.my.crt */; }; DCE4E7AC1D7A43B500AFB96E /* Invalid-www.cybersecurity.my.crt in Copy DigiCertMalaysia Resources */ = {isa = PBXBuildFile; fileRef = 794743191462137C00D638A3 /* Invalid-www.cybersecurity.my.crt */; }; - DCE4E7B41D7A43DC00AFB96E /* si-82-sectrust-ct-logs.plist in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E72E1D7A436300AFB96E /* si-82-sectrust-ct-logs.plist */; }; DCE4E7B51D7A43FF00AFB96E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE4E6D71D7A420D00AFB96E /* main.m */; }; DCE4E7B61D7A440A00AFB96E /* bc-10-knife-on-bread.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE4E6D41D7A41E400AFB96E /* bc-10-knife-on-bread.m */; }; DCE4E7BF1D7A463400AFB96E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; DCE4E7C11D7A463E00AFB96E /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E7C01D7A463E00AFB96E /* SecurityFoundation.framework */; }; - DCE4E7C41D7A465500AFB96E /* libsecurity_smime_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC17844B1D77869A00B50D50 /* libsecurity_smime_regressions.a */; }; DCE4E7C61D7A468300AFB96E /* libaks.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB2CA4D81D2C28C800AB770F /* libaks.a */; }; DCE4E7DF1D7A4B4C00AFB96E /* bc-10-knife-on-bread.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE4E6D41D7A41E400AFB96E /* bc-10-knife-on-bread.m */; }; DCE4E7E21D7A4B7F00AFB96E /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = DCE4E7E11D7A4B7F00AFB96E /* main.c */; }; DCE4E7E41D7A4B8F00AFB96E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D848541C6C1D9C0025BB44 /* Foundation.framework */; }; DCE4E7E71D7A4B9C00AFB96E /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789261D7799D300B50D50 /* IOKit.framework */; }; - DCE4E7E81D7A4BA400AFB96E /* libsecurity_smime_regressions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC17844B1D77869A00B50D50 /* libsecurity_smime_regressions.a */; }; DCE4E7EA1D7A4BAE00AFB96E /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789241D7799CD00B50D50 /* CoreFoundation.framework */; }; DCE4E7EB1D7A4BB200AFB96E /* SecurityFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DCE4E6E71D7A427200AFB96E /* SecurityFoundation.framework */; }; DCE4E7EC1D7A4BB800AFB96E /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC1789041D77980500B50D50 /* Security.framework */; }; @@ -4795,22 +5500,17 @@ 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 */; }; DCE4E9711D7F3EBB00AFB96E /* com.apple.security.keychain-circle-notification.plist in Install launchd plist */ = {isa = PBXBuildFile; fileRef = DCE4E9461D7F3E8700AFB96E /* com.apple.security.keychain-circle-notification.plist */; }; - DCE5DC0F1EA80256006308A6 /* SOSSysdiagnose.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D8C1D8085F200865A7C /* SOSSysdiagnose.m */; }; DCE5DC101EA802DA006308A6 /* secToolFileIO.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78D921D8085F200865A7C /* secToolFileIO.h */; }; DCE5DC111EA80348006308A6 /* accountCirclesViewsPrint.h in Headers */ = {isa = PBXBuildFile; fileRef = 48C2F9331E4BCFC30093D70C /* accountCirclesViewsPrint.h */; }; - DCE5DC121EA80369006308A6 /* libSOSCommands.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52EC341D80CFB200B0A59C /* libSOSCommands.a */; }; - DCE7F2091F21726500DDB0F7 /* CKKSAPSReceiverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE7F2081F21726500DDB0F7 /* CKKSAPSReceiverTests.m */; }; - DCE809F31D9342BE00F91177 /* com.apple.securityd.plist in CopyFiles */ = {isa = PBXBuildFile; fileRef = DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */; }; + DCE772662290712F005862B4 /* OctagonCheckTrustStateOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCE772642290712F005862B4 /* OctagonCheckTrustStateOperation.h */; }; + DCE772672290712F005862B4 /* OctagonCheckTrustStateOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE772652290712F005862B4 /* OctagonCheckTrustStateOperation.m */; }; + DCE7F2091F21726500DDB0F7 /* OctagonAPSReceiverTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCE7F2081F21726500DDB0F7 /* OctagonAPSReceiverTests.m */; }; + DCE809F31D9342BE00F91177 /* com.apple.securityd.plist in launchd plist */ = {isa = PBXBuildFile; fileRef = DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */; }; DCEA5D551E2826DB0089CF55 /* CKKSSIV.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D531E2826DB0089CF55 /* CKKSSIV.h */; }; - DCEA5D561E2826DB0089CF55 /* CKKSSIV.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D531E2826DB0089CF55 /* CKKSSIV.h */; }; DCEA5D571E2826DB0089CF55 /* CKKSSIV.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */; }; - DCEA5D581E2826DB0089CF55 /* CKKSSIV.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */; }; - DCEA5D851E2F14810089CF55 /* CKKSAPSReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D831E2F14810089CF55 /* CKKSAPSReceiver.h */; }; - DCEA5D861E2F14810089CF55 /* CKKSAPSReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D831E2F14810089CF55 /* CKKSAPSReceiver.h */; }; - DCEA5D871E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D841E2F14810089CF55 /* CKKSAPSReceiver.m */; }; - DCEA5D881E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D841E2F14810089CF55 /* CKKSAPSReceiver.m */; }; + DCEA5D851E2F14810089CF55 /* OctagonAPSReceiver.h in Headers */ = {isa = PBXBuildFile; fileRef = DCEA5D831E2F14810089CF55 /* OctagonAPSReceiver.h */; }; + DCEA5D871E2F14810089CF55 /* OctagonAPSReceiver.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D841E2F14810089CF55 /* OctagonAPSReceiver.m */; }; DCEA5D971E3015830089CF55 /* CKKSZone.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D961E3014250089CF55 /* CKKSZone.m */; }; - DCEA5D981E3015840089CF55 /* CKKSZone.m in Sources */ = {isa = PBXBuildFile; fileRef = DCEA5D961E3014250089CF55 /* CKKSZone.m */; }; DCEDE3511D80B0FA00C3826E /* secd-71-engine-save-sample1.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C651D8085D800865A7C /* secd-71-engine-save-sample1.h */; }; DCEDE3901D80B10100C3826E /* SecOTRIdentityPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF7FFF615AFB73800B9D400 /* SecOTRIdentityPriv.h */; }; DCEDE3911D80B10800C3826E /* SecCTKKeyPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */; }; @@ -4819,6 +5519,27 @@ DCEDE3941D80B11800C3826E /* SecPasswordGenerate.h in Headers */ = {isa = PBXBuildFile; fileRef = CDDE9BC31729AB910013B0E8 /* SecPasswordGenerate.h */; }; DCEDE3961D80B12600C3826E /* SecTrustInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78E921D8085FC00865A7C /* SecTrustInternal.h */; }; DCEE1E861D93427400DC0EB7 /* com.apple.securityd.plist in Resources */ = {isa = PBXBuildFile; fileRef = DCE4E80D1D7A4E3A00AFB96E /* com.apple.securityd.plist */; }; + DCF12673218A757A000124C6 /* OTLeaveCliqueOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF12671218A7579000124C6 /* OTLeaveCliqueOperation.h */; }; + DCF12674218A757A000124C6 /* OTLeaveCliqueOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF12672218A757A000124C6 /* OTLeaveCliqueOperation.m */; }; + DCF216DE21ADD5F90029CCC1 /* CKKSSerializedKey.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */; }; + DCF216DF21ADD5FB0029CCC1 /* OTPairingMessage.proto in Sources */ = {isa = PBXBuildFile; fileRef = 0C0F76DD21399AF40074EDDF /* OTPairingMessage.proto */; }; + DCF216E021ADD5FD0029CCC1 /* OTAccountMetadataClassC.proto in Sources */ = {isa = PBXBuildFile; fileRef = DC751A0C211E02B100C18042 /* OTAccountMetadataClassC.proto */; }; + DCF216E121ADD6060029CCC1 /* TPPBVoucher.proto in Sources */ = {isa = PBXBuildFile; fileRef = BE7089911F9AA027001ACC20 /* TPPBVoucher.proto */; }; + DCF458B3221F6964007F5507 /* TPLog.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF458AE221F6890007F5507 /* TPLog.m */; }; + DCF458B4221F6A90007F5507 /* TPLog.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF458AD221F6890007F5507 /* TPLog.h */; settings = {ATTRIBUTES = (Private, ); }; }; + DCF46570220110C900BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF46571220110E100BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF46572220114E400BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF46573220114F000BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF465742201155000BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF46575220115E300BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF465762201162800BA6EEA /* CloudServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C8A38C817B93DF10001B4C0 /* CloudServices.framework */; }; + DCF4657A22011E1400BA6EEA /* EscrowRequestCLI.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF4657922011E1300BA6EEA /* EscrowRequestCLI.m */; }; + DCF46C2E214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF46C2C214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.h */; }; + DCF46C30214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF46C2D214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.m */; }; + DCF6320521C074F30030CCC0 /* CuttlefishAPIHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF6320421C074F30030CCC0 /* CuttlefishAPIHelpers.swift */; }; + DCF6320721C075210030CCC0 /* CuttlefishAPIHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF6320421C074F30030CCC0 /* CuttlefishAPIHelpers.swift */; }; + DCF6320821C09DCE0030CCC0 /* CuttlefishAPIHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF6320421C074F30030CCC0 /* CuttlefishAPIHelpers.swift */; }; DCF7839D1D88B60D00E694BB /* aesCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783151D88B60D00E694BB /* aesCommon.h */; }; DCF7839E1D88B60D00E694BB /* aescsp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783161D88B60D00E694BB /* aescsp.cpp */; }; DCF7839F1D88B60D00E694BB /* aescspi.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783171D88B60D00E694BB /* aescspi.h */; }; @@ -4858,18 +5579,6 @@ DCF783C21D88B60D00E694BB /* wrapKeyCms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF7833B1D88B60D00E694BB /* wrapKeyCms.cpp */; }; DCF783C31D88B60D00E694BB /* YarrowConnection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF7833C1D88B60D00E694BB /* YarrowConnection.cpp */; }; DCF783C41D88B60D00E694BB /* YarrowConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7833D1D88B60D00E694BB /* YarrowConnection.h */; }; - DCF783C51D88B60D00E694BB /* algmaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF7833F1D88B60D00E694BB /* algmaker.cpp */; }; - DCF783C61D88B60D00E694BB /* bsafeAsymmetric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783401D88B60D00E694BB /* bsafeAsymmetric.cpp */; }; - DCF783C71D88B60D00E694BB /* bsafeContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783411D88B60D00E694BB /* bsafeContext.cpp */; }; - DCF783C81D88B60D00E694BB /* bsafecsp.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783421D88B60D00E694BB /* bsafecsp.h */; }; - DCF783C91D88B60D00E694BB /* bsafecspi.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783431D88B60D00E694BB /* bsafecspi.h */; }; - DCF783CA1D88B60D00E694BB /* bsafeKeyGen.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783441D88B60D00E694BB /* bsafeKeyGen.cpp */; }; - DCF783CB1D88B60D00E694BB /* bsafePKCS1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783451D88B60D00E694BB /* bsafePKCS1.cpp */; }; - DCF783CC1D88B60D00E694BB /* bsafePKCS1.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783461D88B60D00E694BB /* bsafePKCS1.h */; }; - DCF783CD1D88B60D00E694BB /* bsafeSymmetric.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783471D88B60D00E694BB /* bsafeSymmetric.cpp */; }; - DCF783CE1D88B60D00E694BB /* bsobjects.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF783481D88B60D00E694BB /* bsobjects.h */; }; - DCF783CF1D88B60D00E694BB /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF783491D88B60D00E694BB /* memory.cpp */; }; - DCF783D01D88B60D00E694BB /* miscalgorithms.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF7834A1D88B60D00E694BB /* miscalgorithms.cpp */; }; DCF783D11D88B60D00E694BB /* ascContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF7834C1D88B60D00E694BB /* ascContext.cpp */; }; DCF783D21D88B60D00E694BB /* ascContext.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7834D1D88B60D00E694BB /* ascContext.h */; }; DCF783D31D88B60D00E694BB /* ascFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7834E1D88B60D00E694BB /* ascFactory.h */; }; @@ -5131,31 +5840,39 @@ DCF789441D88CD6700E694BB /* tpTime.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF788FA1D88CD4200E694BB /* tpTime.h */; }; DCF789481D88D17C00E694BB /* AppleX509TPBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF789471D88D17C00E694BB /* AppleX509TPBuiltin.cpp */; }; DCF7A8A01F04502400CABE89 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; }; - DCF7A8A11F04502400CABE89 /* CKKSControlProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */; }; + DCF94A7B222D9F2400C01744 /* OctagonCKKSPeerAdapter.h in Headers */ = {isa = PBXBuildFile; fileRef = DCF94A79222D9F2400C01744 /* OctagonCKKSPeerAdapter.h */; }; + DCF94A7C222D9F2400C01744 /* OctagonCKKSPeerAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DCF94A7A222D9F2400C01744 /* OctagonCKKSPeerAdapter.m */; }; DCFABF8E20081E2F001128B5 /* CKKSDeviceStateUploadTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFABF8D20081E2F001128B5 /* CKKSDeviceStateUploadTests.m */; }; DCFAEDCF1D999859005187E4 /* SOSAccountGhost.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEDC81D999851005187E4 /* SOSAccountGhost.m */; }; DCFAEDD21D99991F005187E4 /* secd-668-ghosts.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEDD11D9998DD005187E4 /* secd-668-ghosts.m */; }; DCFAEDD61D99A47A005187E4 /* secd-36-ks-encrypt.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFAEDD51D99A464005187E4 /* secd-36-ks-encrypt.m */; }; DCFAEDD71D99A4AB005187E4 /* secd-154-engine-backoff.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C771D8085D800865A7C /* secd-154-engine-backoff.m */; }; - DCFB12C51E95A4C000510F5F /* CKKSCKAccountStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFB12C31E95A4C000510F5F /* CKKSCKAccountStateTracker.h */; }; - DCFB12C61E95A4C000510F5F /* CKKSCKAccountStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFB12C31E95A4C000510F5F /* CKKSCKAccountStateTracker.h */; }; - DCFB12C71E95A4C000510F5F /* CKKSCKAccountStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFB12C41E95A4C000510F5F /* CKKSCKAccountStateTracker.m */; }; - DCFB12C81E95A4C000510F5F /* CKKSCKAccountStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFB12C41E95A4C000510F5F /* CKKSCKAccountStateTracker.m */; }; + DCFB12C51E95A4C000510F5F /* CKKSAccountStateTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFB12C31E95A4C000510F5F /* CKKSAccountStateTracker.h */; }; + DCFB12C71E95A4C000510F5F /* CKKSAccountStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFB12C41E95A4C000510F5F /* CKKSAccountStateTracker.m */; }; + DCFC91AF21F16E0B00E674DD /* OctagonStateMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFC91AD21F16E0B00E674DD /* OctagonStateMachine.h */; }; + DCFC91B021F16E0B00E674DD /* OctagonStateMachine.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFC91AE21F16E0B00E674DD /* OctagonStateMachine.m */; }; DCFE1C271F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C251F17E455007640C8 /* CKKSDeviceStateEntry.h */; }; - DCFE1C281F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C251F17E455007640C8 /* CKKSDeviceStateEntry.h */; }; DCFE1C291F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C261F17E455007640C8 /* CKKSDeviceStateEntry.m */; }; - DCFE1C2A1F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C261F17E455007640C8 /* CKKSDeviceStateEntry.m */; }; DCFE1C341F17ECE5007640C8 /* CKKSCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C321F17ECE5007640C8 /* CKKSCondition.h */; }; - DCFE1C351F17ECE5007640C8 /* CKKSCondition.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C321F17ECE5007640C8 /* CKKSCondition.h */; }; DCFE1C361F17ECE5007640C8 /* CKKSCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C331F17ECE5007640C8 /* CKKSCondition.m */; }; - DCFE1C371F17ECE5007640C8 /* CKKSCondition.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C331F17ECE5007640C8 /* CKKSCondition.m */; }; DCFE1C3D1F17EFB5007640C8 /* CKKSConditionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFE1C3C1F17EFB5007640C8 /* CKKSConditionTests.m */; }; DCFE1C511F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFE1C4F1F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h */; }; - 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, ); }; }; + DCFF82712162834D00D54B02 /* OctagonTestsXPCConnections.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCFF82702162834C00D54B02 /* OctagonTestsXPCConnections.swift */; }; + DCFF82742162876400D54B02 /* OTResetOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = DCFF82722162876400D54B02 /* OTResetOperation.h */; }; + DCFF82762162876400D54B02 /* OTResetOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = DCFF82732162876400D54B02 /* OTResetOperation.m */; }; + DCFFE9692277DEAF0092069C /* TrustedPeersHelperProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = DC754C712228B57B00A39C8E /* TrustedPeersHelperProtocol.m */; }; + DCFFE96D2277E0E90092069C /* TrustedPeers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */; }; + E060D1A9212478100025B833 /* OctagonTestHarnessXPCServiceProtocol.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E060D1A72124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + E060D1B8212478120025B833 /* OctagonTestHarnessXPCService.xpc in Embed XPC Services */ = {isa = PBXBuildFile; fileRef = E060D1B7212478110025B833 /* OctagonTestHarnessXPCService.xpc */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + E060D1BF212478120025B833 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E060D1BE212478120025B833 /* main.m */; }; + E060D1C7212478120025B833 /* OctagonTestHarness.h in Headers */ = {isa = PBXBuildFile; fileRef = E060D19E2124780F0025B833 /* OctagonTestHarness.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E060D24721247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = E060D24221247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.m */; }; + E060D24821247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = E060D24421247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.h */; }; + E09E09EB215506650042C7D3 /* OctagonTestHarnessXPCService.m in Sources */ = {isa = PBXBuildFile; fileRef = E09E09E9215506570042C7D3 /* OctagonTestHarnessXPCService.m */; }; + E291657F2048BCCB0046512B /* TPPBPeerStableInfoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E291657E2048BCCB0046512B /* TPPBPeerStableInfoTests.m */; }; 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 */; }; @@ -5172,7 +5889,6 @@ E75C0E821C6FC31D00E6953B /* KCSRPContext.h in Headers */ = {isa = PBXBuildFile; fileRef = E75C0E801C6FC31D00E6953B /* KCSRPContext.h */; settings = {ATTRIBUTES = (Public, ); }; }; E75C0E831C6FC31D00E6953B /* KCSRPContext.m in Sources */ = {isa = PBXBuildFile; fileRef = E75C0E811C6FC31D00E6953B /* KCSRPContext.m */; }; E75C0E851C71329900E6953B /* KeychainCircle.h in Headers */ = {isa = PBXBuildFile; fileRef = E75C0E841C71325000E6953B /* KeychainCircle.h */; settings = {ATTRIBUTES = (Public, ); }; }; - E7650E6F1C7699DA00378669 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; E76638A81DD679BC00B769D3 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; E7676DB619411DF300498DD4 /* SecServerEncryptionSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = E7676DB519411DF300498DD4 /* SecServerEncryptionSupport.h */; settings = {ATTRIBUTES = (Private, ); }; }; E772FD471CC15EFA00D63E41 /* NSData+SecRandom.m in Sources */ = {isa = PBXBuildFile; fileRef = E772FD461CC15EFA00D63E41 /* NSData+SecRandom.m */; }; @@ -5205,18 +5921,16 @@ E7D690A11652E07B0079537A /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D690911652E06A0079537A /* libMobileGestalt.dylib */; }; E7D848051C6BEFCD0025BB44 /* KCSRPTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E7D848041C6BEFC10025BB44 /* KCSRPTests.m */; }; E7D848561C6C1E830025BB44 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D848541C6C1D9C0025BB44 /* Foundation.framework */; }; - E7D8489F1C6C244B0025BB44 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D848541C6C1D9C0025BB44 /* Foundation.framework */; }; E7DC73B71C890F0E0008BF73 /* KeychainCircle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D847C51C6BE9710025BB44 /* KeychainCircle.framework */; }; E7E3EFBA1CBC192A00E79A5D /* KCAccountKCCircleDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E7E3EFB91CBC192A00E79A5D /* KCAccountKCCircleDelegate.m */; }; E7E3EFE31CBC195700E79A5D /* KCAccountKCCircleDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = E7E3EFE21CBC195700E79A5D /* KCAccountKCCircleDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; E7EBDEBC1C87C0DB001BAA62 /* KeychainCircle.plist in Install BATS Tests */ = {isa = PBXBuildFile; fileRef = E7CFF7221C8660A000E3484E /* KeychainCircle.plist */; }; E7F480121C729C7B00390FDB /* NSError+KCCreationHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F480111C729C7B00390FDB /* NSError+KCCreationHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; }; - E7F480151C73980D00390FDB /* KCJoiningRequestSession.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F480141C73980D00390FDB /* KCJoiningRequestSession.m */; }; + E7F480151C73980D00390FDB /* KCJoiningRequestSecretSession.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F480141C73980D00390FDB /* KCJoiningRequestSecretSession.m */; }; E7F480321C73FC4C00390FDB /* KCAESGCMDuplexSession.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F480301C73FC4C00390FDB /* KCAESGCMDuplexSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; E7F480331C73FC4C00390FDB /* KCAESGCMDuplexSession.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F480311C73FC4C00390FDB /* KCAESGCMDuplexSession.m */; }; E7F4809C1C74E85200390FDB /* KCDerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F4809B1C74E85200390FDB /* KCDerTest.m */; }; E7F4809E1C74E86D00390FDB /* KCAESGCMTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F4809D1C74E86D00390FDB /* KCAESGCMTest.m */; }; - E7F482701C74FDD100390FDB /* KCJoiningSessionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E7F4826F1C74FDD100390FDB /* KCJoiningSessionTest.m */; }; E7F482961C74FDF800390FDB /* KCJoiningSession.h in Headers */ = {isa = PBXBuildFile; fileRef = E7F480131C7397CE00390FDB /* KCJoiningSession.h */; settings = {ATTRIBUTES = (Public, ); }; }; E7F482A11C7543E500390FDB /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; E7F482A31C7544E600390FDB /* libctkclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E7F482A21C7544E600390FDB /* libctkclient_test.a */; }; @@ -5227,12 +5941,11 @@ 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 */; }; + EB09310D213F980800C0A495 /* TestResourceUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = EB093107213F8EC100C0A495 /* TestResourceUsage.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 */; }; + EB0F4A2C22F7D3DC009E855B /* OCMock.framework in Embedd OCMock */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; EB1055791E14DF570003C309 /* SecCertificateFuzzer.c in Sources */ = {isa = PBXBuildFile; fileRef = EB10556B1E14DC0F0003C309 /* SecCertificateFuzzer.c */; }; EB1055831E14E1F90003C309 /* Digisign-Server-ID-Enrich-GTETrust-Cert.crt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 7947431C146214E500D638A3 /* Digisign-Server-ID-Enrich-GTETrust-Cert.crt */; }; EB1055841E14E1F90003C309 /* Invalid-www.cybersecurity.my.crt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 794743191462137C00D638A3 /* Invalid-www.cybersecurity.my.crt */; }; @@ -5265,18 +5978,25 @@ EB108F261E6CE4D2003B0456 /* KCPairingTest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB413B7E1E663A8300592085 /* KCPairingTest.m */; }; EB10A3E520356E2000E84270 /* OTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = EB10A3E320356E2000E84270 /* OTConstants.h */; settings = {ATTRIBUTES = (Private, ); }; }; EB10A3E620356E2000E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; - EB10A3E720356E6500E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; EB10A3E820356E6500E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; EB10A3E920356E7A00E84270 /* OTConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = EB10A3E420356E2000E84270 /* OTConstants.m */; }; EB10A3FC2035789B00E84270 /* OTConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = EB10A3E320356E2000E84270 /* OTConstants.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB18A7BA2238C07600A0FC41 /* OTDeviceInformationAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = DC19484B21812EC5007C2260 /* OTDeviceInformationAdapter.m */; }; + EB1C319D2215ED3500A188BB /* otctl.1 in Install man1 pages */ = {isa = PBXBuildFile; fileRef = EB1C319C2215EC9600A188BB /* otctl.1 */; }; + EB1E069D211E16260088F0B1 /* mockaksxcbase.m in Sources */ = {isa = PBXBuildFile; fileRef = EB1E0695211E137E0088F0B1 /* mockaksxcbase.m */; }; + EB1E069F211E17C00088F0B1 /* mockaksWatchDog.m in Sources */ = {isa = PBXBuildFile; fileRef = EB1E069E211E17B70088F0B1 /* mockaksWatchDog.m */; }; EB27FF2D1E407FF600EC9E3A /* ckksctl.m in Sources */ = {isa = PBXBuildFile; fileRef = EB27FF0C1E402C8000EC9E3A /* ckksctl.m */; }; EB27FF311E408DC700EC9E3A /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EB2CA4DA1D2C28F100AB770F /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; EB2CA5571D2C36D400AB770F /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; EB2D54AB1F02A47200E46890 /* SecAtomicFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = EB2D54A01F02A28200E46890 /* SecAtomicFile.cpp */; }; + EB3210C720F532CD003504F7 /* SOSAccountTrustClassic+Identity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7604B1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m */; }; + EB3210CD20F532F3003504F7 /* SOSAccountTrustClassic+Retirement.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE7604D1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m */; }; EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + EB351540211A79E30097A87C /* secd-33-keychain-backup.m in Sources */ = {isa = PBXBuildFile; fileRef = EB35153F211A79CB0097A87C /* secd-33-keychain-backup.m */; }; 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 */; }; + EB3F9C9D21FCFD67007B6EBA /* OctagonTestHarness.m in Sources */ = {isa = PBXBuildFile; fileRef = EB3F9C9B21FCFC60007B6EBA /* OctagonTestHarness.m */; }; 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 */; }; @@ -5286,16 +6006,14 @@ EB433A291CC3244C00A7EACE /* secitemstresstest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB433A1E1CC3242C00A7EACE /* secitemstresstest.m */; }; EB433A2A1CC3246800A7EACE /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EB433A2E1CC325E900A7EACE /* secitemstresstest.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = EB433A2D1CC325E900A7EACE /* secitemstresstest.entitlements */; }; - EB48C1A51E573EE400EC5E57 /* whoami.m in Sources */ = {isa = PBXBuildFile; fileRef = DC52EA911D80CC2A00B0A59C /* whoami.m */; }; - EB48C1A61E573EEC00EC5E57 /* sos.m in Sources */ = {isa = PBXBuildFile; fileRef = EB48C19E1E573EDC00EC5E57 /* sos.m */; }; - EB49B2B1202D8780003F34A0 /* secdmockaks.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2B0202D8780003F34A0 /* secdmockaks.m */; }; + EB49B2B1202D8780003F34A0 /* mockaksKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2B0202D8780003F34A0 /* mockaksKeychain.m */; }; EB49B2BB202D8894003F34A0 /* libsecurityd_ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */; }; EB49B2BC202DEF14003F34A0 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */; }; EB49B2BD202DEF29003F34A0 /* libSecureObjectSyncFramework.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */; }; EB49B2BE202DEF29003F34A0 /* libSecureObjectSyncServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; }; EB49B2BF202DEF67003F34A0 /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; EB49B2C0202DEF7D003F34A0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - EB49B2C1202DEF8D003F34A0 /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + EB49B2C1202DEF8D003F34A0 /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; EB49B2C2202DF002003F34A0 /* libDER.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D46246911F9AE2E400D63882 /* libDER.a */; }; EB49B2C7202DF0E9003F34A0 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; EB49B2CD202DF0F9003F34A0 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; @@ -5307,16 +6025,14 @@ EB49B2D5202DF1D8003F34A0 /* SecTask.c in Sources */ = {isa = PBXBuildFile; fileRef = 107226D00D91DB32003CF14F /* SecTask.c */; }; EB49B2D7202DF1F7003F34A0 /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; EB49B2D8202DF1F7003F34A0 /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; - EB49B2D9202DF1F7003F34A0 /* server_security_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.c */; }; + EB49B2D9202DF1F7003F34A0 /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; 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 */; }; - EB49B2E5202DFEB3003F34A0 /* mockaks.m in Sources */ = {isa = PBXBuildFile; fileRef = EB49B2E4202DFE7F003F34A0 /* mockaks.m */; }; EB49B308202FF421003F34A0 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; 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 */; }; - EB4E0CDC1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EB4E0CD51FF36A1900CDCACC /* CKKSReachabilityTracker.m */; }; EB58A0511E74BF07009C10D7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EB59D6731E95F01600997EAC /* libcompression.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EB59D66B1E95EF2900997EAC /* libcompression.dylib */; }; EB5E3BCC2003C67A00F1631B /* SecSignpost.h in Headers */ = {isa = PBXBuildFile; fileRef = EB5E3BC62003C66300F1631B /* SecSignpost.h */; settings = {ATTRIBUTES = (Private, ); }; }; @@ -5326,23 +6042,139 @@ EB6928C61D9C9C6F00062A18 /* SecRecoveryKey.h in Headers */ = {isa = PBXBuildFile; fileRef = EB6928BE1D9C9C5900062A18 /* SecRecoveryKey.h */; settings = {ATTRIBUTES = (Private, ); }; }; EB6928CA1D9C9E1800062A18 /* rk_01_recoverykey.m in Sources */ = {isa = PBXBuildFile; fileRef = EB6928C91D9C9D9D00062A18 /* rk_01_recoverykey.m */; }; EB6928F91D9ED5BA00062A18 /* SecRecoveryKey.m in Sources */ = {isa = PBXBuildFile; fileRef = EB6928BF1D9C9C5900062A18 /* SecRecoveryKey.m */; }; + EB69528A223B75C300F02C1C /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; }; + EB69528B223B75C300F02C1C /* SecItemBackupServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C9D1D8085D800865A7C /* SecItemBackupServer.h */; }; + EB69528C223B75C300F02C1C /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; }; + EB69528E223B75C300F02C1C /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; }; + EB69528F223B75C300F02C1C /* SecAKSObjCWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF9D218A16F80012C5DA /* SecAKSObjCWrappers.m */; }; + EB695290223B75C300F02C1C /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; + EB695291223B75C300F02C1C /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; + EB695294223B75C300F02C1C /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + EB695295223B75C300F02C1C /* SecItemDb.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C961D8085D800865A7C /* SecItemDb.c */; }; + EB695296223B75C300F02C1C /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; + EB695297223B75C300F02C1C /* SecDbKeychainMetadataKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF93218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.m */; }; + EB695298223B75C300F02C1C /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + EB69529A223B75C300F02C1C /* CheckV12DevEnabled.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF83218A09210012C5DA /* CheckV12DevEnabled.m */; }; + EB69529B223B75C300F02C1C /* SecDbBackupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */; }; + EB69529C223B75C300F02C1C /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; }; + EB69529D223B75C300F02C1C /* SecItemSchema.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C981D8085D800865A7C /* SecItemSchema.c */; }; + EB69529E223B75C300F02C1C /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + EB69529F223B75C300F02C1C /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; + EB6952A0223B75C300F02C1C /* SecItemServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9A1D8085D800865A7C /* SecItemServer.c */; }; + EB6952A1223B75C300F02C1C /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; }; + EB6952A2223B75C300F02C1C /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + EB6952A3223B75C300F02C1C /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; + EB6952A4223B75C300F02C1C /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + EB6952A5223B75C300F02C1C /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; + EB6952A6223B75C300F02C1C /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; }; + EB6952A7223B75C300F02C1C /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; + EB6952A8223B75C300F02C1C /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + EB6952A9223B75C300F02C1C /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; + EB6952AB223B75C300F02C1C /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB6952AC223B75C300F02C1C /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */; }; + EB6952AD223B75C300F02C1C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + EB6952AE223B75C300F02C1C /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + EB6952AF223B75C300F02C1C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; + EB6952B0223B75C300F02C1C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + EB6952B1223B75C300F02C1C /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D4911167209558900066A1E4 /* CoreData.framework */; settings = {ATTRIBUTES = (Weak, ); }; }; + EB6952B2223B75C300F02C1C /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + EB6952B3223B75C300F02C1C /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; + EB6952BD223B786800F02C1C /* com.apple.secitemd.plist in launchd plist */ = {isa = PBXBuildFile; fileRef = EB6952BC223B783500F02C1C /* com.apple.secitemd.plist */; }; + EB6952BE223B793100F02C1C /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; EB69AB301BF4348000913AF1 /* SecEMCSPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = EB69AB091BF4347700913AF1 /* SecEMCSPriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB71CF7822E825AF00DA3D0E /* SecTapToRadar.m in Sources */ = {isa = PBXBuildFile; fileRef = EB71CF6422E8238000DA3D0E /* SecTapToRadar.m */; }; + EB74CC172207E48000F1BBAD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D458C500214E1FAF0043D982 /* Foundation.framework */; }; + EB74CC1F2207E4BA00F1BBAD /* KeychainSettings.h in Headers */ = {isa = PBXBuildFile; fileRef = EB74CC1D2207E4BA00F1BBAD /* KeychainSettings.h */; }; + EB74CC242207EB9800F1BBAD /* KeychainSettings.m in Sources */ = {isa = PBXBuildFile; fileRef = EB74CC1E2207E4BA00F1BBAD /* KeychainSettings.m */; }; + EB74CC262207ECCC00F1BBAD /* Preferences.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB74CC252207ECCB00F1BBAD /* Preferences.framework */; }; + EB74CC272207ECE100F1BBAD /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + EB74CC282207EE4300F1BBAD /* KeychainSettings.plist in Resources */ = {isa = PBXBuildFile; fileRef = EB74CC212207E4FA00F1BBAD /* KeychainSettings.plist */; }; + EB74CC2F2207FBF600F1BBAD /* KeychainSettingsOctagonPeers.plist in Resources */ = {isa = PBXBuildFile; fileRef = EB74CC2E2207FBE900F1BBAD /* KeychainSettingsOctagonPeers.plist */; }; EB75B4821E753EAA00E469CC /* KeychainCircle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7D847C51C6BE9710025BB44 /* KeychainCircle.framework */; }; EB75B4871E75400200E469CC /* libaks_acl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF8C1A01472C000958DC /* libaks_acl.a */; }; EB75B4881E75401700E469CC /* ApplePushService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC9EBA231DEE36FE00D0F733 /* ApplePushService.framework */; }; EB75B4891E75402400E469CC /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CBCE5A90BE7F69100FF81F5 /* IOKit.framework */; }; - EB75B48A1E75405100E469CC /* libsecurity.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCC78EA91D8088E200865A7C /* libsecurity.a */; }; EB75B48C1E75407C00E469CC /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; - EB75B48D1E75408900E469CC /* libASN1_not_installed.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; }; + EB75B48D1E75408900E469CC /* libASN1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC8834081D8A218F00CE0ACA /* libASN1.a */; }; EB75B48F1E75409A00E469CC /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; EB75B4901E7540AA00E469CC /* libctkclient_test.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDC1AA0A45C0021AA26 /* libctkclient_test.a */; }; 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 */; }; EB76B7591DCB0CA200C43FBC /* CloudKeychainProxy.8 in Install man8 page */ = {isa = PBXBuildFile; fileRef = DC24B5851DA432E900330B48 /* CloudKeychainProxy.8 */; }; + EB7732C221963B0500FCF513 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB7732D921963BA500FCF513 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EB80DE57219600CF005B10FA /* libz.dylib */; }; + EB7732DB21963BC100FCF513 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; EB78D3F91E600E93009AFE05 /* SOSCloudCircle.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78D891D8085F200865A7C /* SOSCloudCircle.m */; }; EB7AE6F81E86DACC00B80B15 /* SecPLWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */; }; EB7AE6F91E86DAD200B80B15 /* SecPLWrappers.h in Headers */ = {isa = PBXBuildFile; fileRef = EB7AE6F71E86D55400B80B15 /* SecPLWrappers.h */; }; + EB7AFAF422323CB6004EF091 /* com.apple.recovery_securityd.plist in launchd plist */ = {isa = PBXBuildFile; fileRef = EB8908BB21F20E0200F0DDDB /* com.apple.recovery_securityd.plist */; }; + EB7E91152194846E00B1FA21 /* SecMetrics.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E90EC2193A54100B1FA21 /* SecMetrics.m */; }; + EB7E91172194847A00B1FA21 /* SecEventMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91122194826F00B1FA21 /* SecEventMetric.m */; }; + EB7E91182194849900B1FA21 /* SECC2MPCloudKitInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91042193F97400B1FA21 /* SECC2MPCloudKitInfo.m */; }; + EB7E91192194849900B1FA21 /* SECC2MPCloudKitOperationGroupInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91062193F97500B1FA21 /* SECC2MPCloudKitOperationGroupInfo.m */; }; + EB7E911A2194849900B1FA21 /* SECC2MPCloudKitOperationInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E90FC2193F97100B1FA21 /* SECC2MPCloudKitOperationInfo.m */; }; + EB7E911B2194849900B1FA21 /* SECC2MPDeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E90F92193F97000B1FA21 /* SECC2MPDeviceInfo.m */; }; + EB7E911C2194849900B1FA21 /* SECC2MPError.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E90FD2193F97100B1FA21 /* SECC2MPError.m */; }; + EB7E911D2194849900B1FA21 /* SECC2MPGenericEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91022193F97300B1FA21 /* SECC2MPGenericEvent.m */; }; + EB7E911E2194849900B1FA21 /* SECC2MPGenericEventMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E90FF2193F97200B1FA21 /* SECC2MPGenericEventMetric.m */; }; + EB7E911F2194849900B1FA21 /* SECC2MPGenericEventMetricValue.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E910A2193F97600B1FA21 /* SECC2MPGenericEventMetricValue.m */; }; + EB7E91202194849900B1FA21 /* SECC2MPInternalTestConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E90FA2193F97000B1FA21 /* SECC2MPInternalTestConfig.m */; }; + EB7E91212194849900B1FA21 /* SECC2MPMetric.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91052193F97400B1FA21 /* SECC2MPMetric.m */; }; + EB7E91222194849900B1FA21 /* SECC2MPNetworkEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91072193F97500B1FA21 /* SECC2MPNetworkEvent.m */; }; + EB7E91232194849900B1FA21 /* SECC2MPServerInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E910B2193F97700B1FA21 /* SECC2MPServerInfo.m */; }; + EB80DE162195EDA4005B10FA /* SecC2DeviceInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = EB7E91102193FB7E00B1FA21 /* SecC2DeviceInfo.m */; }; + EB80DE38219600A8005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE54219600B4005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE55219600BF005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE56219600C6005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE59219600DF005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE5A219600F2005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE5B219600FC005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE5C2196010F005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB80DE5D21960C0A005B10FA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB86BEF6222C3C0500EC0F13 /* AppleAccount.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C84DA541720698900AEE225 /* AppleAccount.framework */; }; + EB89086821F17D3C00F0DDDB /* spi.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78CB01D8085D800865A7C /* spi.c */; }; + EB89086921F17D3C00F0DDDB /* SecdWatchdog.m in Sources */ = {isa = PBXBuildFile; fileRef = 476541641F339F6300413F65 /* SecdWatchdog.m */; }; + EB89086A21F17D3C00F0DDDB /* server.c in Sources */ = {isa = PBXBuildFile; fileRef = 790850840CA87CF00083CC4D /* server.c */; }; + EB89086B21F17D3C00F0DDDB /* server_entitlement_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */; }; + EB89086C21F17D3C00F0DDDB /* server_security_helpers.m in Sources */ = {isa = PBXBuildFile; fileRef = DC4269061E82FBDF002B7110 /* server_security_helpers.m */; }; + EB89086D21F17D3C00F0DDDB /* server_xpc.m in Sources */ = {isa = PBXBuildFile; fileRef = DCB2214A1E8B0861001598BC /* server_xpc.m */; }; + EB89086E21F17D3C00F0DDDB /* server_endpoint.m in Sources */ = {isa = PBXBuildFile; fileRef = DC6ACC401E81DF9400125DC5 /* server_endpoint.m */; }; + EB89087021F17D3C00F0DDDB /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D4119E72202BDF2B0048587B /* libz.tbd */; }; + EB89087221F17D3C00F0DDDB /* libMobileGestalt.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */; }; + EB89087321F17D3C00F0DDDB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + EB89087421F17D3C00F0DDDB /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + EB89087521F17D3C00F0DDDB /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; + EB89087921F17D3C00F0DDDB /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C32C0AF0A4975F6002891BD /* Security.framework */; }; + EB89087B21F17D3C00F0DDDB /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E71F3E3016EA69A900FAF9B4 /* SystemConfiguration.framework */; }; + EB89087E21F17D3C00F0DDDB /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CB740680A4749C800D641BB /* libsqlite3.dylib */; }; + EB8908A521F1870800F0DDDB /* SecCDKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 470D966F1FCDE55B0065FE90 /* SecCDKeychain.h */; }; + EB8908A621F1871800F0DDDB /* SFKeychainServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 47FF17241FD60ACA00875565 /* SFKeychainServer.h */; }; + EB8908A721F1882300F0DDDB /* SecItemDb.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C961D8085D800865A7C /* SecItemDb.c */; }; + EB8908A821F1886100F0DDDB /* SecDbQuery.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C921D8085D800865A7C /* SecDbQuery.c */; }; + EB8908A921F1888300F0DDDB /* SecItemServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9A1D8085D800865A7C /* SecItemServer.c */; }; + EB8908AA21F18BBF00F0DDDB /* SecDbItem.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C8E1D8085D800865A7C /* SecDbItem.c */; }; + EB8908AB21F18BFD00F0DDDB /* SecKeybagSupport.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9E1D8085D800865A7C /* SecKeybagSupport.c */; }; + EB8908AC21F18C4200F0DDDB /* SecItemSchema.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C981D8085D800865A7C /* SecItemSchema.c */; }; + EB8908AD21F18CEF00F0DDDB /* SecuritydXPC.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */; }; + EB8908AE21F18D0E00F0DDDB /* SecDbKeychainItem.m in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */; }; + EB8908AF21F18D3500F0DDDB /* SecDbKeychainItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */; }; + EB8908B021F18D7B00F0DDDB /* SecDbKeychainSerializedMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */; }; + EB8908B121F18DB600F0DDDB /* SecDbKeychainMetadataKeyStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF93218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.m */; }; + EB8908B221F18E1400F0DDDB /* SecDbKeychainSerializedItemV7.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */; }; + EB8908B321F18E3200F0DDDB /* SecItemBackupServer.h in Headers */ = {isa = PBXBuildFile; fileRef = DCC78C9D1D8085D800865A7C /* SecItemBackupServer.h */; }; + EB8908B421F18E4A00F0DDDB /* SecItemBackupServer.c in Sources */ = {isa = PBXBuildFile; fileRef = DCC78C9C1D8085D800865A7C /* SecItemBackupServer.c */; }; + EB8908B721F1943200F0DDDB /* SecDbKeychainSerializedSecretData.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */; }; + EB8908B821F1944500F0DDDB /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */; }; + EB8908B921F1953100F0DDDB /* CheckV12DevEnabled.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF83218A09210012C5DA /* CheckV12DevEnabled.m */; }; + EB8908BA21F1957300F0DDDB /* SecAKSObjCWrappers.m in Sources */ = {isa = PBXBuildFile; fileRef = 6C4AEF9D218A16F80012C5DA /* SecAKSObjCWrappers.m */; }; + EB8908BE21F2181600F0DDDB /* SFKeychainControlManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */; }; + EB9795B522FE9256002BDBFB /* SecItemTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EB6D1D5322FE8D3000205E83 /* SecItemTests.m */; }; + EB9B283321C7755700173DC2 /* OTDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE971FC9DA5A00580909 /* OTDefines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB9B283421C7755800173DC2 /* OTDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8BBE971FC9DA5A00580909 /* OTDefines.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EB9B285721C77C8D00173DC2 /* OTDefines.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCE06E521C6E26000FB1493 /* OTDefines.m */; }; + EB9B285821C77C8D00173DC2 /* OTDefines.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCE06E521C6E26000FB1493 /* OTDefines.m */; }; + EB9B285921C77E7400173DC2 /* OTDefines.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCE06E521C6E26000FB1493 /* OTDefines.m */; }; EB9C02481E8A15B40040D3C6 /* secd-37-pairing-initial-sync.m in Sources */ = {isa = PBXBuildFile; fileRef = EB9C02421E8A112A0040D3C6 /* secd-37-pairing-initial-sync.m */; }; EB9C1D7B1BDFD0E000F89272 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EB9C1D7E1BDFD0E100F89272 /* secbackupntest.m in Sources */ = {isa = PBXBuildFile; fileRef = EB9C1D7D1BDFD0E100F89272 /* secbackupntest.m */; }; @@ -5351,10 +6183,20 @@ EBA9AA811CE30E58004E2B68 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EBA9AA821CE30E58004E2B68 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EBA9AA871CE30E6F004E2B68 /* secitemnotifications.m in Sources */ = {isa = PBXBuildFile; fileRef = EBA9AA7C1CE30CE7004E2B68 /* secitemnotifications.m */; }; + EBB02A6A2220649F007241CB /* KeychainSettingsCKKSViews.plist in Resources */ = {isa = PBXBuildFile; fileRef = EBB02A56221FF362007241CB /* KeychainSettingsCKKSViews.plist */; }; + EBB02A702220ED26007241CB /* CKKSLaunchSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB02A6D2220ED16007241CB /* CKKSLaunchSequence.m */; }; + EBB0315822223AAF007241CB /* CKKSLaunchSequenceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB03155222237A7007241CB /* CKKSLaunchSequenceTests.m */; }; EBB407B31EBA46B200A541A5 /* CKKSPowerCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */; }; - EBB407B41EBA46B300A541A5 /* CKKSPowerCollection.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */; }; EBB839B01E2968AB00853BAC /* secfuzzer.m in Sources */ = {isa = PBXBuildFile; fileRef = EBB8399B1E295B8F00853BAC /* secfuzzer.m */; }; EBB839B11E2968B400853BAC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; + EBB8520922F7914A00424FD0 /* SecXPCHelperTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A04BB22229872CB001848A0 /* SecXPCHelperTests.m */; }; + EBB8520A22F7914A00424FD0 /* SecTapToRadarTests.m in Sources */ = {isa = PBXBuildFile; fileRef = EB6AC0AA22F22E80003F067B /* SecTapToRadarTests.m */; }; + EBB8521B22F7945600424FD0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6CCDF78B1E3C26BC003F2555 /* XCTest.framework */; }; + EBB8521D22F7948B00424FD0 /* libutilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCC361D8C684F00070CB0 /* libutilities.a */; }; + EBB8528122F79F6E00424FD0 /* SecXPCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A04BB14229866F7001848A0 /* SecXPCHelper.m */; }; + EBB852CF22F7A05600424FD0 /* OCMock.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 47D1838B1FB3827700CFCD89 /* OCMock.framework */; }; + EBB852D022F7A13D00424FD0 /* SecInternalRelease.c in Sources */ = {isa = PBXBuildFile; fileRef = DC0BCC761D8C68CF00070CB0 /* SecInternalRelease.c */; }; + EBC1024422EBF93E0083D356 /* CKKSTests+LockStateTracker.m in Sources */ = {isa = PBXBuildFile; fileRef = EBC1023022EBF8AC0083D356 /* CKKSTests+LockStateTracker.m */; }; 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 */; }; @@ -5363,76 +6205,40 @@ 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_sep.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4469FBDD1AA0A45C0021AA26 /* libctkclient_sep.a */; }; - EBCE16541FE6DE5A002E7CCC /* libprequelite.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 0CE98B5B1FA9360700CF1D54 /* libprequelite.tbd */; }; - EBCE16551FE6DE5A002E7CCC /* libsqlite3.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */; }; - EBCE16561FE6DE5A002E7CCC /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */; }; - 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 */; }; + EBCC31B1228CF0FD000AF5D9 /* libMobileGestalt.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = BE53602C209BBF2F0027E25A /* libMobileGestalt.tbd */; }; 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 */; }; + EBD531762198AF0B003A57E6 /* AppleAccount.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C84DA541720698900AEE225 /* AppleAccount.framework */; }; + EBD531772198AF19003A57E6 /* Accounts.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CF4C19C171E0EA600877419 /* Accounts.framework */; }; + EBDAA7E920EC4838003EA6E5 /* SecurityLocalKeychain.plist in Install BATS plist */ = {isa = PBXBuildFile; fileRef = EBDAA7E320EC46CF003EA6E5 /* SecurityLocalKeychain.plist */; }; + EBDAF15D21C75FF200EAE89F /* NSXPCConnectionMock.h in Headers */ = {isa = PBXBuildFile; fileRef = EBDAF15B21C75FF200EAE89F /* NSXPCConnectionMock.h */; }; + EBDE5E0E22BA3DE900A229C8 /* CKKSMockOctagonAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = EBDE5DFA22BA3D5D00A229C8 /* CKKSMockOctagonAdapter.m */; }; + EBDE5E0F22BA3DEA00A229C8 /* CKKSMockOctagonAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = EBDE5DFA22BA3D5D00A229C8 /* CKKSMockOctagonAdapter.m */; }; + EBE2026B20908C7100B48020 /* tpctl.8 in install man8 page */ = {isa = PBXBuildFile; fileRef = EBE2026420908A8A00B48020 /* tpctl.8 */; }; 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 */; }; EBE9019C1C2285DB007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; }; EBE9019E1C228610007308C6 /* AggregateDictionary.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 72B368BD179891FC004C37CE /* AggregateDictionary.framework */; }; - EBEEEE3C1EA31D9600E15F5C /* SOSControlHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */; }; - EBEEEE3D1EA31DB000E15F5C /* SOSControlHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */; }; - EBEEEE3E1EA31DB100E15F5C /* SOSControlHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */; }; EBEEEE3F1EA31E6D00E15F5C /* SOSControlHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */; }; + EBF252222155E910000204D6 /* OTJoiningConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8FD546214AEC650098E3FB /* OTJoiningConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; }; + EBF252252155E911000204D6 /* OTJoiningConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 0C8FD546214AEC650098E3FB /* OTJoiningConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; }; EBF2D73C1C1E2B47006AB6FF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E7FCBE431314471B000DE34E /* Foundation.framework */; }; EBF3745F1DBFB32A0065D840 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = EBF3745E1DBFB32A0065D840 /* libobjc.dylib */; }; EBF374751DC055590065D840 /* security-sysdiagnose.m in Sources */ = {isa = PBXBuildFile; fileRef = EBF374741DC055590065D840 /* security-sysdiagnose.m */; }; EBF3747E1DC057B40065D840 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D82BD316A5EADA0078DFE5 /* Security.framework */; }; EBF374801DC058070065D840 /* security-sysdiagnose.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = EBF3747F1DC057FE0065D840 /* security-sysdiagnose.1 */; }; + EBF5323A21C8B6330073C1C7 /* OTDefines.m in Sources */ = {isa = PBXBuildFile; fileRef = EBCE06E521C6E26000FB1493 /* OTDefines.m */; }; EBFF18C41F02A4EF004E58FC /* libsecurity_filedb.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BC89F1D8B7CBD00070CB0 /* libsecurity_filedb.a */; }; EBFF18CA1F02A677004E58FC /* libsecurity_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */; }; EBFF18CB1F02A68B004E58FC /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5E43C48C1B00D07000E5ECB2 /* CoreFoundation.framework */; }; EBFF18CC1F02A6AE004E58FC /* libsecurity_cdsa_utilities.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DCB341821D8A2B860054D16E /* libsecurity_cdsa_utilities.a */; }; + EBFF95ED214C80880021CD14 /* SecRemoteDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = EB056E421FE5E390000A771E /* SecRemoteDevice.m */; }; + EBFF95EE214C80B90021CD14 /* OctagonTestHarnessXPCServiceDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E060D1C3212478120025B833 /* OctagonTestHarnessXPCServiceDelegate.m */; }; + EBFF95EF214C823F0021CD14 /* KeychainCircle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0C75AC642141F18D0073A2F9 /* KeychainCircle.framework */; }; + F3384FD42165A049004A2171 /* SecurityCustomSignposts.plist in Install Ariadne Signposts Plist */ = {isa = PBXBuildFile; fileRef = EBD8AD632004B45500588BBA /* SecurityCustomSignposts.plist */; }; + F3384FD62165A08E004A2171 /* SecurityCustomSignposts.plist in Install Ariadne Signposts Plist */ = {isa = PBXBuildFile; fileRef = EBD8AD632004B45500588BBA /* SecurityCustomSignposts.plist */; }; F619D71E1ED70BC1005B5F46 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F619D71D1ED70BB0005B5F46 /* main.m */; }; F667EC5A1E96E9B100203D5C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EB10557A1E14DF640003C309 /* Security.framework */; }; F667EC5B1E96E9B100203D5C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */; }; @@ -5441,70 +6247,58 @@ F667EC631E96EDC500203D5C /* libregressionBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DC0BCBFD1D8C648C00070CB0 /* libregressionBase.a */; }; F682C1D41F4486F700F1B029 /* libctkloginhelper.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F682C1CE1F4486F600F1B029 /* libctkloginhelper.a */; }; F6AF96681E646CAF00917214 /* libcoreauthd_client.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 4432AF6A1A01458F000958DC /* libcoreauthd_client.a */; }; - F93C493B1AB8FF530047E01A /* ckcdiagnose.sh in CopyFiles */ = {isa = PBXBuildFile; fileRef = F93C493A1AB8FF530047E01A /* ckcdiagnose.sh */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; + F6EEF76F21675E8000FB7F79 /* AuthorizationTrampolinePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = F6D600702166551800F9F7C9 /* AuthorizationTrampolinePriv.h */; }; + F6EEF77521675EF000FB7F79 /* AuthorizationTrampolinePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = F6D600702166551800F9F7C9 /* AuthorizationTrampolinePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; F964772C1E5832540019E4EB /* SecCodePriv.h in Headers */ = {isa = PBXBuildFile; fileRef = DCD0678E1D8CDF7E007602F1 /* SecCodePriv.h */; settings = {ATTRIBUTES = (Private, ); }; }; - F9C8AFCD223740C800E7D6AE /* requirement.h in Headers */ = {isa = PBXBuildFile; fileRef = F9C8AFCB223740C800E7D6AE /* requirement.h */; }; - F9C8AFD222374D1100E7D6AE /* requirement.c in Sources */ = {isa = PBXBuildFile; fileRef = F9C8AFC5223740C700E7D6AE /* requirement.c */; }; + F9F77E98223C2F9A00E5CBF6 /* requirement.c in Sources */ = {isa = PBXBuildFile; fileRef = F9F77E96223C2F7B00E5CBF6 /* requirement.c */; }; + F9F77E99223C2F9A00E5CBF6 /* requirement.h in Headers */ = {isa = PBXBuildFile; fileRef = F9F77E97223C2F7C00E5CBF6 /* requirement.h */; }; /* 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; filePatterns = "*.exp-in"; fileType = pattern.proxy; - isEditable = 1; - outputFiles = ( - "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp", + inputFiles = ( + "$(SRCROOT)/Security.exp-in", ); - script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nfor prep in ${GCC_PREPROCESSOR_DEFINITIONS[@]} ; do\nPREPROCESSOR=\"${PREPROCESSOR} -D${prep}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x objective-c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${PREPROCESSOR} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.${CURRENT_ARCH}.exp\n"; - }; - DC9FD3201F85818000C8AAC8 /* 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", + "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).exp", ); - 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"; + runOncePerArchitecture = 0; + script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nfor prep in ${GCC_PREPROCESSOR_DEFINITIONS[@]} ; do\nPREPROCESSOR=\"${PREPROCESSOR} -D${prep}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x objective-c ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${PREPROCESSOR} ${INPUT_FILE_PATH} -o \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.exp\"\n"; }; - DC9FD3221F85877000C8AAC8 /* PBXBuildRule */ = { + DCF216DD21ADD5D10029CCC1 /* PBXBuildRule */ = { isa = PBXBuildRule; compilerSpec = com.apple.compilers.proxy.script; filePatterns = "*.proto"; fileType = pattern.proxy; + inputFiles = ( + ); isEditable = 1; outputFiles = ( - "$(INPUT_FILE_DIR)/source/${INPUT_FILE_BASE}.h", - "$(INPUT_FILE_DIR)/source/${INPUT_FILE_BASE}.m", + "$(INPUT_FILE_DIR)/generated_source/${INPUT_FILE_BASE}.h", + "$(INPUT_FILE_DIR)/generated_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"; + runOncePerArchitecture = 0; + script = "set -x\n\nprotocompiler --arc --strict --emitDeprecated=NO --outputDir ${INPUT_FILE_DIR}/generated_source --proto ${INPUT_FILE_DIR}/${INPUT_FILE_NAME}\n"; }; E7B006FF170B56E700B27966 /* PBXBuildRule */ = { isa = PBXBuildRule; compilerSpec = com.apple.compilers.proxy.script; filePatterns = "*.exp-in"; fileType = pattern.proxy; + inputFiles = ( + "$(SRCROOT)/Security.exp-in", + ); isEditable = 1; outputFiles = ( - "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp", + "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).exp", ); - script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nfor prep in ${GCC_PREPROCESSOR_DEFINITIONS[@]} ; do\nPREPROCESSOR=\"${PREPROCESSOR} -D${prep}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x objective-c -arch ${CURRENT_ARCH} ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${PREPROCESSOR} ${INPUT_FILE_PATH} -o ${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.${CURRENT_ARCH}.exp\n"; + runOncePerArchitecture = 0; + script = "#!/bin/sh\n\nfor file in ${HEADER_SEARCH_PATHS[@]} ; do\nHEADER_SEARCH_OPTIONS=\"${HEADER_SEARCH_OPTIONS} -I${file}\"\ndone\n\nfor prep in ${GCC_PREPROCESSOR_DEFINITIONS[@]} ; do\nPREPROCESSOR=\"${PREPROCESSOR} -D${prep}\"\ndone\n\nxcrun clang -E -Xpreprocessor -P -x objective-c ${HEADER_SEARCH_OPTIONS} ${OTHER_INPUT_FILE_FLAGS} ${PREPROCESSOR} \"${INPUT_FILE_PATH}\" -o \"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.exp\"\n"; }; /* End PBXBuildRule section */ @@ -5551,12 +6345,12 @@ remoteGlobalIDString = DC0BCC211D8C684F00070CB0; remoteInfo = utilities; }; - 0C664AB31759270C0092D3D9 /* PBXContainerItemProxy */ = { + 0C604F0121B8E5090036C175 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; - remoteInfo = secdtests; + remoteGlobalIDString = DCF216D621ADD5B10029CCC1; + remoteInfo = protobuf_source_generation; }; 0C78CCE41FCC97E7008B4B24 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -5572,13 +6366,6 @@ remoteGlobalIDString = 0C8BBEFD1FCB446400580909; remoteInfo = otctl; }; - 0C85DFD51FB38BB6000343A7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC222C371E034D1F00B09171; - remoteInfo = libsecurityd_ios_NO_AKS; - }; 0C85DFD91FB38BB6000343A7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5614,26 +6401,26 @@ remoteGlobalIDString = DCC78EA81D8088E200865A7C; remoteInfo = security; }; - 0C99B73F131C984900584CF4 /* PBXContainerItemProxy */ = { + 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C6799F912F7C37C00712919; - remoteInfo = dtlsTests; + remoteGlobalIDString = DC1789031D77980500B50D50; + remoteInfo = Security_osx; }; - 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */ = { + 0CC593F72299EDFC006C34B5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC1789031D77980500B50D50; - remoteInfo = Security_osx; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - 0CC827F1138712B100BD99B7 /* PBXContainerItemProxy */ = { + 0CF0920F219649DB002B0AEE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E710C7411331946400F85568; - remoteInfo = SecurityTests; + remoteGlobalIDString = 5346480017331E1100FE9172; + remoteInfo = KeychainSyncAccountNotification; }; 225394B51E30811400D3CD9B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -5656,13 +6443,6 @@ 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 */; @@ -5684,6 +6464,13 @@ remoteGlobalIDString = DC0BCC211D8C684F00070CB0; remoteInfo = utilities; }; + 3DD258A1204B7DA800F5DA78 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; 438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5824,13 +6611,6 @@ remoteGlobalIDString = 4727FBB61F9918580003AE36; remoteInfo = secdxctests_ios; }; - 47D991D620407F890078CAE2 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 478D426C1FD72A8100CAB645; - remoteInfo = secdxctests_mac; - }; 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5852,20 +6632,6 @@ 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 */; @@ -5873,34 +6639,6 @@ remoteGlobalIDString = 4C52D0B316EFC61E0079966E; remoteInfo = CircleJoinRequested; }; - 4C541F8B0F250C0400E508AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 790851B50CA9859F0083CC4D; - remoteInfo = securityd; - }; - 4C541F8D0F250C0900E508AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4CB740A20A47567C00D641BB; - remoteInfo = security; - }; - 4C541F8F0F250C0E00E508AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; - remoteInfo = sslViewer; - }; - 4C541F910F250C1300E508AE /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 7913B1FF0D172B3900601FE9; - remoteInfo = sslServer; - }; 4C541FA00F250C5200E508AE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5908,13 +6646,6 @@ remoteGlobalIDString = 4C541F840F250BF500E508AE; remoteInfo = phase2; }; - 4C9DE9EE1181ACA000CF5C27 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4C9DE9D11181AC4800CF5C27; - remoteInfo = sslEcdsa; - }; 52D82BF516A627100078DFE5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -5929,47 +6660,19 @@ remoteGlobalIDString = 5346480017331E1100FE9172; remoteInfo = KeychainSyncAccountNotification; }; - 5E10995319A5E80B00A60E2B /* PBXContainerItemProxy */ = { + 6C4AA1A92228B640006FA945 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5E10992419A5E55800A60E2B; - remoteInfo = ISACLProtectedItems; - }; - 5EF7C2551B00EEF900E5E99C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; - remoteInfo = secacltests; - }; - 6C24EF491E415109000DE79F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; - remoteInfo = KeychainEntitledTestRunner; - }; - 6C24EF521E415132000DE79F /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; - remoteInfo = KeychainEntitledTestRunner; - }; - 6C7C38801FD88C4700DFFE68 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6C46056B1F882B9B001421B6; - remoteInfo = KeychainAnalyticsTests; + remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; + remoteInfo = SecurityBatsTests; }; - 6C7C38871FD88C5A00DFFE68 /* PBXContainerItemProxy */ = { + 6C8FF4B5224C1A9800E5C812 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6C46056B1F882B9B001421B6; - remoteInfo = KeychainAnalyticsTests; + remoteGlobalIDString = BEF88C271EAFFC3F00357577; + remoteInfo = TrustedPeers; }; 6C9808301E788AEB00E70590 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -6006,13 +6709,6 @@ remoteGlobalIDString = DCC78EA81D8088E200865A7C; remoteInfo = security; }; - 6C98083C1E788AEB00E70590 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC222C371E034D1F00B09171; - remoteInfo = libsecurityd_ios_NO_AKS; - }; 6C98086C1E788AFD00E70590 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6048,13 +6744,6 @@ remoteGlobalIDString = DCC78EA81D8088E200865A7C; remoteInfo = security; }; - 6C9808781E788AFD00E70590 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DC222C371E034D1F00B09171; - remoteInfo = libsecurityd_ios_NO_AKS; - }; 6C98089F1E788B9400E70590 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6076,20 +6765,6 @@ remoteGlobalIDString = DC0BCC211D8C684F00070CB0; remoteInfo = utilities; }; - 6CAA8CE41F82FD08007B6E03 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; - remoteInfo = supdctl; - }; - 6CAA8CE81F82FD13007B6E03 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; - remoteInfo = supdctl; - }; 6CAA8D3C1F8431BC007B6E03 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; @@ -6104,75 +6779,75 @@ remoteGlobalIDString = 6CAA8D1F1F842FB3007B6E03; remoteInfo = supd; }; - ACBAF6FD1E941E090007BA2F /* PBXContainerItemProxy */ = { + 873C14B121540FED003C9C00 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = ACBAF6991E9417F40007BA2F; - remoteInfo = security_transform_regressions; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - BE061EAB1EE5EA5600B22118 /* PBXContainerItemProxy */ = { + 87EDC39D2141BB8A007B0E64 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BED208D41EDF950E00753952; - remoteInfo = manifeststresstest; + remoteGlobalIDString = 4771D971209A755800BA9772; + remoteInfo = KeychainDataclassOwner; }; - BE061EB21EE5EAC800B22118 /* PBXContainerItemProxy */ = { + 87EDC3A12141BB92007B0E64 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BED208D41EDF950E00753952; - remoteInfo = manifeststresstest; + remoteGlobalIDString = 0C8BBEFD1FCB446400580909; + remoteInfo = otctl; }; - BE061EB61EE5EB9000B22118 /* PBXContainerItemProxy */ = { + 87EDC3A32141BB9B007B0E64 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BED208D41EDF950E00753952; - remoteInfo = manifeststresstest; + remoteGlobalIDString = EB27FF101E402CD300EC9E3A; + remoteInfo = ckksctl; }; - BE061EB81EE5EBA000B22118 /* PBXContainerItemProxy */ = { + 87EDC3A72141BBAA007B0E64 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BED208D41EDF950E00753952; - remoteInfo = manifeststresstest; + remoteGlobalIDString = 4381690B1B4EDCBD00C54D58; + remoteInfo = SOSCCAuthPlugin; }; - BE197F621911742900BA91D1 /* PBXContainerItemProxy */ = { + 87EDC3B12141BBD5007B0E64 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BE197F2519116FD100BA91D1; - remoteInfo = KeychainViewService; + remoteGlobalIDString = 5346480017331E1100FE9172; + remoteInfo = KeychainSyncAccountNotification; }; - BE4AC9B318B8020400B84964 /* PBXContainerItemProxy */ = { + ACBAF6FD1E941E090007BA2F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BE442BA018B7FDB800F24DAE; - remoteInfo = swcagent; + remoteGlobalIDString = ACBAF6991E9417F40007BA2F; + remoteInfo = security_transform_regressions; }; - BE9C38C71EB115A7007E2AE1 /* PBXContainerItemProxy */ = { + BE061EB21EE5EAC800B22118 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEF88C271EAFFC3F00357577; - remoteInfo = TrustedPeers; + remoteGlobalIDString = BED208D41EDF950E00753952; + remoteInfo = manifeststresstest; }; - BE9C38CE1EB115C9007E2AE1 /* PBXContainerItemProxy */ = { + BE197F621911742900BA91D1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEF88C271EAFFC3F00357577; - remoteInfo = TrustedPeers; + remoteGlobalIDString = BE197F2519116FD100BA91D1; + remoteInfo = KeychainViewService; }; - BE9C38D01EB115F4007E2AE1 /* PBXContainerItemProxy */ = { + BE4AC9B318B8020400B84964 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEF88C2F1EAFFC3F00357577; - remoteInfo = TrustedPeersTests; + remoteGlobalIDString = BE442BA018B7FDB800F24DAE; + remoteInfo = swcagent; }; BE9C38D21EB11605007E2AE1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -6181,12 +6856,12 @@ remoteGlobalIDString = BEF88C2F1EAFFC3F00357577; remoteInfo = TrustedPeersTests; }; - BEF88C321EAFFC3F00357577 /* PBXContainerItemProxy */ = { + BED01525206EEC710027A2B4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = BEF88C271EAFFC3F00357577; - remoteInfo = TrustedPeers; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; D40B6A7E1E2B5F3D00CD6EE5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; @@ -6244,2770 +6919,3932 @@ remoteGlobalIDString = D4ADA3181E2B41670031CEA3; remoteInfo = libtrustd; }; - D41257F01E941E7D00781F23 /* PBXContainerItemProxy */ = { + D41257F61E941E9600781F23 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = D41257CE1E9410A300781F23; remoteInfo = trustd_ios; }; - D41257F21E941E8600781F23 /* PBXContainerItemProxy */ = { + D41AD4511B9788B2008C7270 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = D41257CE1E9410A300781F23; - remoteInfo = trustd_ios; + remoteGlobalIDString = 52D82BDD16A621F70078DFE5; + remoteInfo = CloudKeychainProxy; }; - D41257F41E941E8E00781F23 /* PBXContainerItemProxy */ = { + D42C83A4211636A3008D3D83 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = D41257CE1E9410A300781F23; - remoteInfo = trustd_ios; + remoteGlobalIDString = D44D1F652115893000E76E1A; + remoteInfo = CMS; }; - D41257F61E941E9600781F23 /* PBXContainerItemProxy */ = { + D437185321166DD800EA350A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = D41257CE1E9410A300781F23; - remoteInfo = trustd_ios; + remoteGlobalIDString = D42C839721159146008D3D83; + remoteInfo = security_cms; }; - D419C0251E57EACA008619D1 /* PBXContainerItemProxy */ = { + D437185821166FC800EA350A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; - remoteInfo = sslViewer; + remoteGlobalIDString = D44D1F652115893000E76E1A; + remoteInfo = CMS; }; - D41AD4391B96721E008C7270 /* PBXContainerItemProxy */ = { + D437185A211670F600EA350A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 790851B50CA9859F0083CC4D; - remoteInfo = securityd; + remoteGlobalIDString = D4D1FDDB21165F8B003538E2; + remoteInfo = security_cms_regressions; }; - D41AD43B1B96723B008C7270 /* PBXContainerItemProxy */ = { + D437C33021EBF8A000DD1E06 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E710C7411331946400F85568; - remoteInfo = SecurityTests; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - D41AD43D1B967242008C7270 /* PBXContainerItemProxy */ = { + D453A4A62122236D00850A26 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; - remoteInfo = secdtests; + remoteGlobalIDString = D4ADA3181E2B41670031CEA3; + remoteInfo = libtrustd; }; - D41AD43F1B96724C008C7270 /* PBXContainerItemProxy */ = { + D453A4C32122262400850A26 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C6799F912F7C37C00712919; - remoteInfo = dtlsTests; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - D41AD4411B97866C008C7270 /* PBXContainerItemProxy */ = { + D453A4C7212226A900850A26 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 7913B1FF0D172B3900601FE9; - remoteInfo = sslServer; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - D41AD4431B978681008C7270 /* PBXContainerItemProxy */ = { + D456A06722AF1866001119F3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4C9DE9D11181AC4800CF5C27; - remoteInfo = sslEcdsa; + remoteGlobalIDString = 6CAA8D1F1F842FB3007B6E03; + remoteInfo = securityuploadd; }; - D41AD4451B9786A3008C7270 /* PBXContainerItemProxy */ = { + D456A06A22AF1874001119F3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4CB740A20A47567C00D641BB; - remoteInfo = securitytool; + remoteGlobalIDString = 6CAA8D1F1F842FB3007B6E03; + remoteInfo = securityuploadd; }; - D41AD4491B9786D8008C7270 /* PBXContainerItemProxy */ = { + D456A06C22AF3238001119F3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = F93C49021AB8FCE00047E01A; - remoteInfo = ckcdiagnose.sh; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - D41AD44B1B9786E2008C7270 /* PBXContainerItemProxy */ = { + D45D8F4E2224D72C00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; - remoteInfo = secacltests; + remoteGlobalIDString = DCE4E68A1D7A37FA00AFB96E; + remoteInfo = security2tool_macos; }; - D41AD44D1B978791008C7270 /* PBXContainerItemProxy */ = { + D45D8F512224D76E00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5E10992419A5E55800A60E2B; - remoteInfo = ISACLProtectedItems; + remoteGlobalIDString = DCE4E8DC1D7F39DB00AFB96E; + remoteInfo = "Cloud Keychain Utility"; }; - D41AD4511B9788B2008C7270 /* PBXContainerItemProxy */ = { + D45D8F532224D7C400D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 52D82BDD16A621F70078DFE5; - remoteInfo = CloudKeychainProxy; + remoteGlobalIDString = F621D0271ED6DCE7000EA569; + remoteInfo = authorizationdump; }; - D41AD45B1B978A7A008C7270 /* PBXContainerItemProxy */ = { + D45D8F552224D87C00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 790851B50CA9859F0083CC4D; - remoteInfo = securityd; + remoteGlobalIDString = DCD06A541D8CE2D5007602F1; + remoteInfo = gkunpack; }; - D41AD45D1B978A7C008C7270 /* PBXContainerItemProxy */ = { + D45D8F572224D88F00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4CB740A20A47567C00D641BB; - remoteInfo = securitytool; + remoteGlobalIDString = DC610AAD1D7910C3002223DE; + remoteInfo = gk_reset_check_macos; }; - D41AD45F1B978E18008C7270 /* PBXContainerItemProxy */ = { + D45D8F592224D8A100D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E710C7411331946400F85568; - remoteInfo = SecurityTests; + remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; + remoteInfo = sslViewer; }; - D41AD4611B978E24008C7270 /* PBXContainerItemProxy */ = { + D45D8F5B2224D9F100D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; - remoteInfo = secdtests; + remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; + remoteInfo = supdctl; }; - D41AD4651B978F19008C7270 /* PBXContainerItemProxy */ = { + D45D8F5D2224DA1000D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C6799F912F7C37C00712919; - remoteInfo = dtlsTests; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; }; - D41AD4671B978F20008C7270 /* PBXContainerItemProxy */ = { + D45D8F5F2224DA6600D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 7913B1FF0D172B3900601FE9; - remoteInfo = sslServer; + remoteGlobalIDString = 3DD1FFAC201FDB1D0086D049; + remoteInfo = SecureTransportTests_ios; }; - D41AD4691B978F24008C7270 /* PBXContainerItemProxy */ = { + D45D8F612224DA8400D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; - remoteInfo = sslViewer; + remoteGlobalIDString = EB108F181E6CE4D2003B0456; + remoteInfo = KCPairingTests; }; - D41AD46B1B978F28008C7270 /* PBXContainerItemProxy */ = { + D45D8F632224DA8E00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4C9DE9D11181AC4800CF5C27; - remoteInfo = sslEcdsa; + remoteGlobalIDString = E7D847CD1C6BE9720025BB44; + remoteInfo = KeychainCircleTests; }; - D41AD46D1B978F4C008C7270 /* PBXContainerItemProxy */ = { + D45D8F652224DA9900D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; - remoteInfo = secacltests; + remoteGlobalIDString = D458C505214E20530043D982; + remoteInfo = TrustTests; }; - DA30D6811DF8C93500EC6B43 /* PBXContainerItemProxy */ = { + D45D8F692224DA9900D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DA30D6751DF8C8FB00EC6B43; - remoteInfo = KeychainSyncAccountUpdater; + remoteGlobalIDString = D4707A0421136E69005BCFDA; + remoteInfo = TrustTests_ios; }; - DAE40BD420CF3ED5002D5674 /* PBXContainerItemProxy */ = { + D45D8F6B2224DABA00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DAE40BC520CF3E46002D5674; - remoteInfo = secitemcanarytest; + remoteGlobalIDString = DC05037521409A4000A8EDB7; + remoteInfo = OCMockUmbrella; }; - DC00678F1D878132005AF8DB /* PBXContainerItemProxy */ = { + D45D8F6D2224DB6400D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC6A82911D87749900418608; - remoteInfo = libsecurityd_client_macos; + remoteGlobalIDString = D41257CE1E9410A300781F23; + remoteInfo = trustd_ios; }; - DC0067C31D8787AE005AF8DB /* PBXContainerItemProxy */ = { + D45D8F6F2224DB6D00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0067921D87876F005AF8DB; - remoteInfo = libsecurityd_server_macos; + remoteGlobalIDString = 790851B50CA9859F0083CC4D; + remoteInfo = securityd_ios; }; - DC0067D21D8788C4005AF8DB /* PBXContainerItemProxy */ = { + D45D8F712224DB9200D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0067C51D878898005AF8DB; - remoteInfo = libsecurityd_ucspc; + remoteGlobalIDString = EB9C1D791BDFD0E000F89272; + remoteInfo = secbackupntest; }; - DC008B591D90CEC7004002A3 /* PBXContainerItemProxy */ = { + D45D8F732224DB9C00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC008B451D90CE53004002A3; - remoteInfo = securityd_macos_mig_nomake; + remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; + remoteInfo = secacltests; }; - DC008B5B1D90CEE9004002A3 /* PBXContainerItemProxy */ = { + D45D8F772224DBB500D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC008B451D90CE53004002A3; - remoteInfo = securityd_macos_mig_nomake; + remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; + remoteInfo = secdtests_ios; }; - DC008B631D90CF37004002A3 /* PBXContainerItemProxy */ = { + D45D8F792224DBBD00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC008B451D90CE53004002A3; - remoteInfo = securityd_macos_mig_nomake; + remoteGlobalIDString = 0C6799F912F7C37C00712919; + remoteInfo = dtlsTests; }; - DC008B651D90CF40004002A3 /* PBXContainerItemProxy */ = { + D45D8F7B2224DBC600D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC008B451D90CE53004002A3; - remoteInfo = securityd_macos_mig_nomake; + remoteGlobalIDString = E710C7411331946400F85568; + remoteInfo = SecurityTests; }; - DC00AB691D821C0700513D74 /* PBXContainerItemProxy */ = { + D45D8F7D2224DBD900D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC521D80D05200B0A59C; - remoteInfo = liblogging; + remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; + remoteInfo = SecurityBatsTests; }; - DC00AB711D821C4600513D74 /* PBXContainerItemProxy */ = { + D45D8F812224DBE300D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = libsecurity; + remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; + remoteInfo = KeychainEntitledTestRunner; }; - DC00AB731D821C4800513D74 /* PBXContainerItemProxy */ = { + D45D8F832224DBEF00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = 6C9808681E788AFD00E70590; + remoteInfo = CKKSCloudKitTests_ios; }; - DC00AB751D821C4C00513D74 /* PBXContainerItemProxy */ = { + D45D8F852224DBF800D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = DC3502B41E0208BE00BC0587; + remoteInfo = CKKSTests; }; - DC00AB7D1D821C7F00513D74 /* PBXContainerItemProxy */ = { + D45D8F872224DC3F00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; }; - DC00AB7F1D821C8300513D74 /* PBXContainerItemProxy */ = { + D45D8F8B2224DC7600D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; - remoteInfo = libSWCAgent; + remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; + remoteInfo = supdctl; }; - DC00AB911D821D6000513D74 /* PBXContainerItemProxy */ = { + D45D8F8D2224DC8E00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC211D80CFB200B0A59C; - remoteInfo = libSOSCommands; + remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; + remoteInfo = sslViewer; }; - DC00AB931D821D6500513D74 /* PBXContainerItemProxy */ = { + D45D8F8F2224DC9900D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EBC61D80CEF100B0A59C; - remoteInfo = libSecurityCommands; + remoteGlobalIDString = 4CB740A20A47567C00D641BB; + remoteInfo = securitytool_ios; }; - DC00AB951D821D6800513D74 /* PBXContainerItemProxy */ = { + D45D8F912224DCCB00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EA441D80CB7000B0A59C; - remoteInfo = libSecurityTool; + remoteGlobalIDString = 7913B1FF0D172B3900601FE9; + remoteInfo = sslServer; }; - DC00AB9D1D821DBB00513D74 /* PBXContainerItemProxy */ = { + D45D8F932224DCD700D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = libsecurity; + remoteGlobalIDString = 4C9DE9D11181AC4800CF5C27; + remoteInfo = sslEcdsa; }; - DC00ABA91D821DE600513D74 /* PBXContainerItemProxy */ = { + D45D8F972224DD7B00D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = D41257CE1E9410A300781F23; + remoteInfo = trustd_ios; }; - DC00ABAB1D821DE700513D74 /* PBXContainerItemProxy */ = { + D45D8F992224DD8200D6C124 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = 790851B50CA9859F0083CC4D; + remoteInfo = securityd_ios; }; - DC00ABAD1D821DEB00513D74 /* PBXContainerItemProxy */ = { + D469C4E4218BECCE008AC1FC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC7E1D80D1A800B0A59C; - remoteInfo = libiOSSecurityRegressions; + remoteGlobalIDString = DCE4E9101D7F3D5300AFB96E; + remoteInfo = "Keychain Circle Notification"; }; - DC00ABAF1D821DF300513D74 /* PBXContainerItemProxy */ = { + D476BC3822BD34280098E15A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC601D80D0C400B0A59C; - remoteInfo = libSOSRegressions; + remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; + remoteInfo = supdctl; }; - DC00ABB11D821DF600513D74 /* PBXContainerItemProxy */ = { + D476BC3B22BD34320098E15A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EDFD1D80D6DD00B0A59C; - remoteInfo = libSharedRegressions; + remoteGlobalIDString = 6C9AA79D1F7C1D8F00D08296; + remoteInfo = supdctl; }; - DC00ABBA1D821E9B00513D74 /* PBXContainerItemProxy */ = { + D477EE7021ED48A500C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = EB2D54A11F02A45E00E46890; + remoteInfo = secatomicfile; }; - DC00ABBC1D821E9F00513D74 /* PBXContainerItemProxy */ = { + D477EE7221ED48AA00C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = BED208D41EDF950E00753952; + remoteInfo = manifeststresstest; }; - DC00ABBE1D821EA700513D74 /* PBXContainerItemProxy */ = { + D477EE7421ED48B400C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52ED631D80D4CD00B0A59C; - remoteInfo = libiOSsecuritydRegressions; + remoteGlobalIDString = F667EC561E96E9B100203D5C; + remoteInfo = authdtest; }; - DC00ABC81D821F0200513D74 /* PBXContainerItemProxy */ = { + D477EE7621ED48C000C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = 470415CE1E5E14B5001F3D95; + remoteInfo = seckeychainnetworkextensionstest; }; - DC00ABCA1D821F0500513D74 /* PBXContainerItemProxy */ = { + D477EE7821ED48C000C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = 47702B1D1E5F409700B29577; + remoteInfo = seckeychainnetworkextensionsystemdaemontest; }; - DC00ABD01D821F1A00513D74 /* PBXContainerItemProxy */ = { + D477EE7A21ED48C000C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = libsecurity; + remoteGlobalIDString = 47702B2D1E5F492C00B29577; + remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; }; - DC00ABD21D821F1D00513D74 /* PBXContainerItemProxy */ = { + D477EE7C21ED48CB00C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = EBB839A41E29665D00853BAC; + remoteInfo = secfuzzer; }; - DC00ABD41D821F2700513D74 /* PBXContainerItemProxy */ = { + D477EE7E21ED48D500C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = EB1055741E14DF430003C309; + remoteInfo = SecCertificateFuzzer; }; - DC00ABDF1D821F5C00513D74 /* PBXContainerItemProxy */ = { + D477EE8021ED48DF00C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = BEF88C2F1EAFFC3F00357577; + remoteInfo = TrustedPeersTests; }; - DC00ABE11D821F6000513D74 /* PBXContainerItemProxy */ = { + D477EE8221ED48E800C9AAFF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EDA61D80D58400B0A59C; - remoteInfo = libsecdRegressions; + remoteGlobalIDString = 478D426C1FD72A8100CAB645; + remoteInfo = secdxctests_mac; }; - DC00ABE31D821F6200513D74 /* PBXContainerItemProxy */ = { + D4794E6A21222E72007C6725 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - DC00ABED1D821FB700513D74 /* PBXContainerItemProxy */ = { + D4A763CE2224BCD10063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = libSecureObjectSync; + remoteGlobalIDString = DCE4E7F51D7A4DA800AFB96E; + remoteInfo = secd; }; - DC00ABEF1D821FBA00513D74 /* PBXContainerItemProxy */ = { + D4A763D02224BCDE0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC601D80D0C400B0A59C; - remoteInfo = libSOSRegressions; + remoteGlobalIDString = DCE4E82D1D7A57AE00AFB96E; + remoteInfo = trustd_macos; }; - DC0984F61E1DB6D400140ADC /* PBXContainerItemProxy */ = { + D4A763D22224BD640063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC610A551D78F9D2002223DE; + remoteInfo = codesign_tests_macos; }; - DC0984FF1E1DB70A00140ADC /* PBXContainerItemProxy */ = { + D4A763D42224BD6F0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = SecureObjectSyncServer; + remoteGlobalIDString = DC610A021D78F129002223DE; + remoteInfo = secdtests_macos; }; - DC0BB4431ED4D74A0035F886 /* PBXContainerItemProxy */ = { + D4A763D82224BD990063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = security; + remoteGlobalIDString = DC3502B41E0208BE00BC0587; + remoteInfo = CKKSTests; }; - DC0BC5AE1D8B714000070CB0 /* PBXContainerItemProxy */ = { + D4A763DA2224BDAB0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5851D8B70E700070CB0; - remoteInfo = security_cdsa_utils; + remoteGlobalIDString = 6C98082C1E788AEB00E70590; + remoteInfo = CKKSCloudKitTests_mac; }; - DC0BC5C01D8B72BB00070CB0 /* PBXContainerItemProxy */ = { + D4A763DC2224BDCC0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5B01D8B71FD00070CB0; - remoteInfo = security_checkpw; + remoteGlobalIDString = 6CF4A0B31E45488B00ECD7B5; + remoteInfo = KeychainEntitledTestApp_mac; }; - DC0BC5D11D8B732300070CB0 /* PBXContainerItemProxy */ = { + D4A763DE2224BDDC0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5B01D8B71FD00070CB0; - remoteInfo = security_checkpw; + remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; + remoteInfo = SecurityBatsTests; }; - DC0BC5D71D8B73B000070CB0 /* PBXContainerItemProxy */ = { + D4A763E02224BDED0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5B01D8B71FD00070CB0; - remoteInfo = security_checkpw; + remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; + remoteInfo = secacltests; }; - DC0BC5F61D8B749000070CB0 /* PBXContainerItemProxy */ = { + D4A763E22224BDF90063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5E21D8B742200070CB0; - remoteInfo = security_comcryption; + remoteGlobalIDString = DC610A461D78F48F002223DE; + remoteInfo = SecTaskTest_macos; }; - DC0BC7421D8B762F00070CB0 /* PBXContainerItemProxy */ = { + D4A763E42224BE170063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5F81D8B752B00070CB0; - remoteInfo = security_cryptkit; + remoteGlobalIDString = DC5AC04F1D8352D900CF422C; + remoteInfo = securityd_macos; }; - DC0BC7BE1D8B784F00070CB0 /* PBXContainerItemProxy */ = { + D4A763E62224BE2F0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC7451D8B771600070CB0; - remoteInfo = security_cssm; + remoteGlobalIDString = DCE4E7CB1D7A4AED00AFB96E; + remoteInfo = sectests_macos; }; - DC0BC8C81D8B7D1C00070CB0 /* PBXContainerItemProxy */ = { + D4A763E82224BE430063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC8981D8B7CBD00070CB0; - remoteInfo = security_filedb; + remoteGlobalIDString = EB9C1D791BDFD0E000F89272; + remoteInfo = secbackupntest; }; - DC0BC8F51D8B7DE700070CB0 /* PBXContainerItemProxy */ = { + D4A763EA2224BE580063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC8CC1D8B7DA200070CB0; - remoteInfo = security_manifest; + remoteGlobalIDString = DCE4E7311D7A43B500AFB96E; + remoteInfo = SecurityTestsOSX; }; - DC0BC92B1D8B7EBB00070CB0 /* PBXContainerItemProxy */ = { + D4A763EC2224BE630063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC8F91D8B7E8000070CB0; - remoteInfo = security_mds; + remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; + remoteInfo = KeychainEntitledTestRunner; }; - DC0BC9641D8B80D200070CB0 /* PBXContainerItemProxy */ = { + D4A763EE2224BE6E0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC92E1D8B7F6A00070CB0; - remoteInfo = security_ocspd; + remoteGlobalIDString = D458C505214E20530043D982; + remoteInfo = TrustTests; }; - DC0BC9981D8B814A00070CB0 /* PBXContainerItemProxy */ = { + D4A763F02224BE6E0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC9661D8B810A00070CB0; - remoteInfo = security_pkcs12; + remoteGlobalIDString = D453A4A42122236D00850A26; + remoteInfo = TrustTests_macos; }; - DC0BC9C61D8B820000070CB0 /* PBXContainerItemProxy */ = { + D4A763F22224BE810063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC99A1D8B81BE00070CB0; - remoteInfo = security_sd_cspdl; + remoteGlobalIDString = E7D847CD1C6BE9720025BB44; + remoteInfo = KeychainCircleTests; }; - DC0BCA751D8B82E900070CB0 /* PBXContainerItemProxy */ = { + D4A763F42224BE8A0063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC9C81D8B824700070CB0; - remoteInfo = security_ssl; + remoteGlobalIDString = EB108F181E6CE4D2003B0456; + remoteInfo = KCPairingTests; }; - DC0BCA771D8B830900070CB0 /* PBXContainerItemProxy */ = { + D4A763F62224BE980063B2B9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCA131D8B82B000070CB0; - remoteInfo = security_ssl_regressions; + remoteGlobalIDString = 3DD1FEF5201C07F30086D049; + remoteInfo = SecureTransportTests_macos; }; - DC0BCAFF1D8B85E500070CB0 /* PBXContainerItemProxy */ = { + D4B68C69211B6E3E009FED69 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCA791D8B858600070CB0; - remoteInfo = security_transform; + remoteGlobalIDString = D4ADA3181E2B41670031CEA3; + remoteInfo = libtrustd; }; - DC0BCB2F1D8B89AB00070CB0 /* PBXContainerItemProxy */ = { + D4BFFD582227574200163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCB011D8B894F00070CB0; - remoteInfo = security_translocate; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - DC0BCC1B1D8C655900070CB0 /* PBXContainerItemProxy */ = { + D4BFFD5B2227574C00163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionHarness; + remoteGlobalIDString = DC52EDA61D80D58400B0A59C; + remoteInfo = secdRegressions; }; - DC0BCDB61D8C6AD100070CB0 /* PBXContainerItemProxy */ = { + D4BFFD5D2227575C00163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - DC0BCDB81D8C6AE000070CB0 /* PBXContainerItemProxy */ = { + D4BFFD5F2227576E00163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; }; - DC0BCDBA1D8C6AF000070CB0 /* PBXContainerItemProxy */ = { + D4BFFD612227578900163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCCF41D8C694700070CB0; - remoteInfo = iOSutilitiesRegressions; - }; - DC1002C81D8E19D70025549C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 4CA1FEBE052A3C8100F22E42; - remoteInfo = libsecurity_cms; - }; - DC1002CA1D8E19D70025549C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = D4C3345C1BE2A2B100D8C1EF; - remoteInfo = libsecurity_cms_regressions; - }; - DC1002D21D8E19F20025549C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 4C817F8405ED4D7A007975E6; - remoteInfo = libsecurity_smime; - }; - DC1002D41D8E19F20025549C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 4C7FAB41056AC7A200FE0C44; - remoteInfo = security_smime; - }; - DC1002D61D8E19F20025549C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 79DC33620D4E6EEA0039E4BC; - remoteInfo = libCMS; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - DC1784481D77869A00B50D50 /* PBXContainerItemProxy */ = { + D4BFFD6622275A4B00163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 4C817F8405ED4D7A007975E6; - remoteInfo = libsecurity_smime; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC05037521409A4000A8EDB7; + remoteInfo = OCMockUmbrella; }; - DC17844A1D77869A00B50D50 /* PBXContainerItemProxy */ = { + D4BFFD682227B30700163B4B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = AC62F5F018B4356A00704BBD; - remoteInfo = libsecurity_smime_regressions; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - DC1789781D779C6700B50D50 /* PBXContainerItemProxy */ = { + D4E0E9502224DDE300A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4C2741ED03E9FBF700A80181; - remoteInfo = libsecurity_smime; + remoteGlobalIDString = DC05037521409A4000A8EDB7; + remoteInfo = OCMockUmbrella; }; - DC178BF21D77ABE300B50D50 /* PBXContainerItemProxy */ = { + D4E0E9532224DDEA00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC1789031D77980500B50D50; - remoteInfo = Security_osx; + remoteGlobalIDString = EB108F181E6CE4D2003B0456; + remoteInfo = KCPairingTests; }; - DC193C5F20CB4C9D009C1A0F /* PBXContainerItemProxy */ = { + D4E0E9552224DDF000A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = D4C3345B1BE2A2B100D8C1EF; - remoteInfo = libsecurity_cms_regressions; + remoteGlobalIDString = E7D847CD1C6BE9720025BB44; + remoteInfo = KeychainCircleTests; }; - DC222C781E034EE700B09171 /* PBXContainerItemProxy */ = { + D4E0E9572224DDFE00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC222C371E034D1F00B09171; - remoteInfo = libsecurityd_ios_NO_AKS; + remoteGlobalIDString = D458C505214E20530043D982; + remoteInfo = TrustTests; }; - DC26710F1F3E933700816EED /* PBXContainerItemProxy */ = { + D4E0E9592224DDFE00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = D4707A0421136E69005BCFDA; + remoteInfo = TrustTests_ios; }; - DC34CD2C20326C2C00302481 /* PBXContainerItemProxy */ = { + D4E0E95B2224DE1000A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = SecureObjectSyncServer; + remoteGlobalIDString = BEF88C2F1EAFFC3F00357577; + remoteInfo = TrustedPeersTests; }; - DC34CD3320326C3100302481 /* PBXContainerItemProxy */ = { + D4E0E95D2224DE1A00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = BED208D41EDF950E00753952; + remoteInfo = manifeststresstest; }; - DC34CD3520326C3B00302481 /* PBXContainerItemProxy */ = { + D4E0E95F2224DE2700A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; + remoteInfo = KeychainEntitledTestRunner; }; - DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */ = { + D4E0E9612224DE3D00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; + remoteInfo = secdtests_ios; }; - DC3502CD1E020E2200BC0587 /* PBXContainerItemProxy */ = { + D4E0E9632224DE4900A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = E710C7411331946400F85568; + remoteInfo = SecurityTests; }; - DC3502D41E02117600BC0587 /* PBXContainerItemProxy */ = { + D4E0E9652224DE5100A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = security; + remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; + remoteInfo = secacltests; }; - DC3A4B6A1D91EBEE00E46D4A /* PBXContainerItemProxy */ = { + D4E0E9672224DE5700A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC3A4B571D91E9FB00E46D4A; - remoteInfo = CodeSigningHelper; + remoteGlobalIDString = 0C6799F912F7C37C00712919; + remoteInfo = dtlsTests; }; - DC5224F81E4029520021640A /* PBXContainerItemProxy */ = { + D4E0E9692224DE6800A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC3502B41E0208BE00BC0587; - remoteInfo = CKKSTests; + remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; + remoteInfo = SecurityBatsTests; }; - DC5224FF1E40295C0021640A /* PBXContainerItemProxy */ = { + D4E0E96B2224DE7000A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC3502B41E0208BE00BC0587; - remoteInfo = CKKSTests; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; }; - DC52E84A1D80BF1100B0A59C /* PBXContainerItemProxy */ = { + D4E0E96D2224DE7A00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; }; - DC52EAA41D80CCF600B0A59C /* PBXContainerItemProxy */ = { + D4E0E96F2224DE8200A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EA441D80CB7000B0A59C; - remoteInfo = libSecurityTool; + remoteGlobalIDString = 470415CE1E5E14B5001F3D95; + remoteInfo = seckeychainnetworkextensionstest; }; - DC52EC1F1D80CF7400B0A59C /* PBXContainerItemProxy */ = { + D4E0E9712224DE8200A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EBC61D80CEF100B0A59C; - remoteInfo = libSecurityCommands; + remoteGlobalIDString = 47702B1D1E5F409700B29577; + remoteInfo = seckeychainnetworkextensionsystemdaemontest; }; - DC52EC3C1D80CFF000B0A59C /* PBXContainerItemProxy */ = { + D4E0E9732224DE8200A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC211D80CFB200B0A59C; - remoteInfo = libSOSCommands; + remoteGlobalIDString = 47702B2D1E5F492C00B29577; + remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; }; - DC52EC501D80D03100B0A59C /* PBXContainerItemProxy */ = { + D4E0E9752224DE9100A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; - remoteInfo = libSWCAgent; + remoteGlobalIDString = 4727FBB61F9918580003AE36; + remoteInfo = secdxctests_ios; }; - DC52EC5E1D80D08100B0A59C /* PBXContainerItemProxy */ = { + D4E0E9792224DEE600A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC521D80D05200B0A59C; - remoteInfo = liblogging; + remoteGlobalIDString = 6CF4A0DF1E4549F200ECD7B5; + remoteInfo = KeychainEntitledTestApp_ios; }; - DC52EC7C1D80D18800B0A59C /* PBXContainerItemProxy */ = { + D4E0E97B2224DF0300A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC601D80D0C400B0A59C; - remoteInfo = libSOSRegressions; + remoteGlobalIDString = 4CB740A20A47567C00D641BB; + remoteInfo = securitytool_ios; }; - DC52ECEB1D80D34C00B0A59C /* PBXContainerItemProxy */ = { + D4E0E97D2224DF0B00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC7E1D80D1A800B0A59C; - remoteInfo = libSecurityRegressions; + remoteGlobalIDString = 7913B1FF0D172B3900601FE9; + remoteInfo = sslServer; }; - DC52EDA21D80D55300B0A59C /* PBXContainerItemProxy */ = { + D4E0E97F2224DF0B00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52ED631D80D4CD00B0A59C; - remoteInfo = libiOSsecuritydRegressions; + remoteGlobalIDString = 4C9DE9D11181AC4800CF5C27; + remoteInfo = sslEcdsa; }; - DC52EDFB1D80D67C00B0A59C /* PBXContainerItemProxy */ = { + D4E0E9812224DF0B00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EDA61D80D58400B0A59C; - remoteInfo = libsecdRegressions; + remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; + remoteInfo = sslViewer; }; - DC52EE621D80D7D900B0A59C /* PBXContainerItemProxy */ = { + D4E0E9852224DF4E00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EDFD1D80D6DD00B0A59C; - remoteInfo = libSharedRegressions; + remoteGlobalIDString = D41257CE1E9410A300781F23; + remoteInfo = trustd_ios; }; - DC52EE641D80D7F000B0A59C /* PBXContainerItemProxy */ = { + D4E0E9872224DF5800A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EDFD1D80D6DD00B0A59C; - remoteInfo = libSharedRegressions; + remoteGlobalIDString = 790851B50CA9859F0083CC4D; + remoteInfo = securityd_ios; }; - DC52EE7D1D80D8B100B0A59C /* PBXContainerItemProxy */ = { + D4E0E9892224DF6F00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EE661D80D82600B0A59C; - remoteInfo = libSecItemShimOSX; + remoteGlobalIDString = DC05037521409A4000A8EDB7; + remoteInfo = OCMockUmbrella; }; - DC58C4291D77BE03003C25A4 /* PBXContainerItemProxy */ = { + D4E0E98B2224DF7700A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC1789031D77980500B50D50; - remoteInfo = Security_osx; + remoteGlobalIDString = EB108F181E6CE4D2003B0456; + remoteInfo = KCPairingTests; }; - DC58C4421D77C1F8003C25A4 /* PBXContainerItemProxy */ = { + D4E0E98D2224DF7D00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC58C4221D77BDEA003C25A4; - remoteInfo = csparser_osx; + remoteGlobalIDString = E7D847CD1C6BE9720025BB44; + remoteInfo = KeychainCircleTests; }; - DC59E9A51D91C710001BDDF5 /* PBXContainerItemProxy */ = { + D4E0E98F2224DF8500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = D447C4DB1D31C9DD0082FC1D; - remoteInfo = libCMSInstall; + remoteGlobalIDString = D458C505214E20530043D982; + remoteInfo = TrustTests; }; - DC59E9A81D91C7CC001BDDF5 /* PBXContainerItemProxy */ = { + D4E0E9912224DF8500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 79DC33610D4E6EEA0039E4BC; - remoteInfo = libCMS; + remoteGlobalIDString = D4707A0421136E69005BCFDA; + remoteInfo = TrustTests_ios; }; - DC5ABE1B1D832F5E00CF422C /* PBXContainerItemProxy */ = { + D4E0E9932224DF8D00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC5ABDC41D832DAB00CF422C; - remoteInfo = securitytool_macos; - }; - DC5AC0B41D83533400CF422C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 189D4635166AC95C001D8533; - remoteInfo = securityd_service; - }; - DC5AC0B61D83533400CF422C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 189D465B166C15C1001D8533; - remoteInfo = securitydservicectrl; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; }; - DC5AC0B81D83533400CF422C /* PBXContainerItemProxy */ = { + D4E0E9952224DF9300A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 1843240E1714797D00196B52; - remoteInfo = securitydservice_client; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = BED208D41EDF950E00753952; + remoteInfo = manifeststresstest; }; - DC5AC0BA1D83533400CF422C /* PBXContainerItemProxy */ = { + D4E0E9972224DF9A00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = 18F4808E17497521009724DB; - remoteInfo = KeyStoreEvents; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; + remoteInfo = KeychainEntitledTestRunner; }; - DC5AC0BC1D83533E00CF422C /* PBXContainerItemProxy */ = { + D4E0E9992224DFAD00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 1843240D1714797D00196B52; - remoteInfo = securitydservice_client; + remoteGlobalIDString = E710C7411331946400F85568; + remoteInfo = SecurityTests; }; - DC5AC0BE1D83534300CF422C /* PBXContainerItemProxy */ = { + D4E0E99B2224DFB500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 189D4634166AC95C001D8533; - remoteInfo = securityd_service; + remoteGlobalIDString = 0C0BDB2E175685B000BC1A7E; + remoteInfo = secdtests_ios; }; - DC5AC12E1D8356DA00CF422C /* PBXContainerItemProxy */ = { + D4E0E99D2224DFBA00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC5AC04F1D8352D900CF422C; - remoteInfo = securityd_macos; + remoteGlobalIDString = 0C6799F912F7C37C00712919; + remoteInfo = dtlsTests; }; - DC61096A1D78E60C002223DE /* PBXContainerItemProxy */ = { + D4E0E99F2224DFC500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; remoteInfo = secacltests; }; - DC61096C1D78E72C002223DE /* PBXContainerItemProxy */ = { + D4E0E9A12224DFCB00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1D791BDFD0E000F89272; - remoteInfo = secbackupntest; + remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; + remoteInfo = SecurityBatsTests; }; - DC610A371D78F15C002223DE /* PBXContainerItemProxy */ = { + D4E0E9A32224DFD500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC610A021D78F129002223DE; - remoteInfo = secdtests_macos; + remoteGlobalIDString = EB49B2AD202D877F003F34A0; + remoteInfo = secdmockaks; }; - DC610A411D78F3A5002223DE /* PBXContainerItemProxy */ = { + D4E0E9A52224DFDD00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = F93C49021AB8FCE00047E01A; - remoteInfo = ckcdiagnose.sh; + remoteGlobalIDString = 470415CE1E5E14B5001F3D95; + remoteInfo = seckeychainnetworkextensionstest; }; - DC610A531D78F759002223DE /* PBXContainerItemProxy */ = { + D4E0E9A72224DFDD00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC610A461D78F48F002223DE; - remoteInfo = SecTaskTest_macos; + remoteGlobalIDString = 47702B1D1E5F409700B29577; + remoteInfo = seckeychainnetworkextensionsystemdaemontest; }; - DC610A6B1D78FAA2002223DE /* PBXContainerItemProxy */ = { + D4E0E9A92224DFDD00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC610A551D78F9D2002223DE; - remoteInfo = codesign_tests_macos; + remoteGlobalIDString = 47702B2D1E5F492C00B29577; + remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; }; - DC610ABB1D791139002223DE /* PBXContainerItemProxy */ = { + D4E0E9AB2224DFEB00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC610AAD1D7910C3002223DE; - remoteInfo = gk_reset_check_macos; + remoteGlobalIDString = 4727FBB61F9918580003AE36; + remoteInfo = secdxctests_ios; }; - DC63CAF21D90DF6000C03317 /* PBXContainerItemProxy */ = { + D4E0E9AD2224E00600A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC63CAE81D90D63500C03317; - remoteInfo = libsecurityd_macos_mig; + remoteGlobalIDString = 4CB740A20A47567C00D641BB; + remoteInfo = securitytool_ios; }; - DC63CAF41D90DF6700C03317 /* PBXContainerItemProxy */ = { + D4E0E9AF2224E00F00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC63CAE81D90D63500C03317; - remoteInfo = libsecurityd_macos_mig; + remoteGlobalIDString = 7913B1FF0D172B3900601FE9; + remoteInfo = sslServer; }; - DC63CAF61D90DF7000C03317 /* PBXContainerItemProxy */ = { + D4E0E9B12224E00F00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC63CAE81D90D63500C03317; - remoteInfo = libsecurityd_macos_mig; + remoteGlobalIDString = 4C9DE9D11181AC4800CF5C27; + remoteInfo = sslEcdsa; }; - DC63CAF91D91A16700C03317 /* PBXContainerItemProxy */ = { + D4E0E9B32224E00F00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = D4C3345B1BE2A2B100D8C1EF; - remoteInfo = libsecurity_cms_regressions; + remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; + remoteInfo = sslViewer; }; - DC65E7211D8CB27900152EF0 /* PBXContainerItemProxy */ = { + D4E0E9BB2224E15500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = E060D19B2124780E0025B833; + remoteInfo = OctagonTestHarness; }; - DC65E7251D8CB2E100152EF0 /* PBXContainerItemProxy */ = { + D4E0E9BD2224E15E00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = E060D19B2124780E0025B833; + remoteInfo = OctagonTestHarness; }; - DC65E7281D8CB2F400152EF0 /* PBXContainerItemProxy */ = { + D4E0E9BF2224E16A00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = E060D19B2124780E0025B833; + remoteInfo = OctagonTestHarness; }; - DC65E72B1D8CB31200152EF0 /* PBXContainerItemProxy */ = { + D4E0E9C12224E17300A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = E060D19B2124780E0025B833; + remoteInfo = OctagonTestHarness; }; - DC65E72E1D8CB32400152EF0 /* PBXContainerItemProxy */ = { + D4E0E9C42224E71600A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; + remoteInfo = libSWCAgent; }; - DC65E7381D8CB38300152EF0 /* PBXContainerItemProxy */ = { + D4E0E9C62224E76100A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB3417B1D8A2B860054D16E; - remoteInfo = security_cdsa_utilities; + remoteGlobalIDString = D4ADA3181E2B41670031CEA3; + remoteInfo = libtrustd; }; - DC65E73A1D8CB39300152EF0 /* PBXContainerItemProxy */ = { + D4E0E9CA2224FB5700A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = iOSutilities; + remoteInfo = utilities; }; - DC65E73D1D8CB3C100152EF0 /* PBXContainerItemProxy */ = { + D4E0E9CE2224FD7A00A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - DC65E73F1D8CB3CD00152EF0 /* PBXContainerItemProxy */ = { + D4E0E9D02224FE3300A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; }; - DC65E7411D8CB3D400152EF0 /* PBXContainerItemProxy */ = { + D4E0E9D22224FE3300A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; }; - DC65E7431D8CB3E000152EF0 /* PBXContainerItemProxy */ = { + D4E0E9D42224FE4100A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - DC65E7451D8CB3E700152EF0 /* PBXContainerItemProxy */ = { + D4E0E9D62225023600A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = DC0BCC211D8C684F00070CB0; remoteInfo = utilities; }; - DC65E7471D8CB3F000152EF0 /* PBXContainerItemProxy */ = { + D4E0E9DA2225D14500A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCA131D8B82B000070CB0; - remoteInfo = security_ssl_regressions; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - DC65E7491D8CB3FE00152EF0 /* PBXContainerItemProxy */ = { + D4E0E9DC2225D1E600A802E0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - DC65E74B1D8CB40C00152EF0 /* PBXContainerItemProxy */ = { + D4EB53B8223C3CE3009101F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCCF41D8C694700070CB0; - remoteInfo = utilitiesRegressions; + remoteGlobalIDString = D458C505214E20530043D982; + remoteInfo = TrustTests; }; - DC65E74D1D8CB41E00152EF0 /* PBXContainerItemProxy */ = { + D4EB53BA223C3CE3009101F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1; + remoteGlobalIDString = D4707A0421136E69005BCFDA; + remoteInfo = TrustTests_ios; }; - DC65E74F1D8CB42700152EF0 /* PBXContainerItemProxy */ = { + D4EB53BD223C3D2B009101F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCA131D8B82B000070CB0; - remoteInfo = security_ssl_regressions; + remoteGlobalIDString = DAE40BC520CF3E46002D5674; + remoteInfo = secitemcanarytest; }; - DC65E7511D8CB45300152EF0 /* PBXContainerItemProxy */ = { + D4EB53C8223C4AB5009101F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = 5E10992419A5E55800A60E2B; + remoteInfo = ISACLProtectedItems; }; - DC65E7531D8CB46100152EF0 /* PBXContainerItemProxy */ = { + D4EB53CA223C4ABE009101F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = 5E10992419A5E55800A60E2B; + remoteInfo = ISACLProtectedItems; }; - DC65E7551D8CB47600152EF0 /* PBXContainerItemProxy */ = { + D4F47B2C22270B23003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D4F56B86217FA32000FCA6B7; + remoteInfo = Security_executables_core_ios; }; - DC65E7571D8CB47D00152EF0 /* PBXContainerItemProxy */ = { + D4F47B3022270B38003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = D4F56BC621813ECF00FCA6B7; + remoteInfo = Security_internal_ios; }; - DC65E7591D8CB48900152EF0 /* PBXContainerItemProxy */ = { + D4F47B3222270B4E003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1; + remoteGlobalIDString = D4D1D40821ADC9720012C66C; + remoteInfo = Security_executables_core_osx; }; - DC65E75B1D8CB49200152EF0 /* PBXContainerItemProxy */ = { + D4F47B3622270B5D003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = D4F56BC221813EC900FCA6B7; + remoteInfo = Security_internal_osx; }; - DC65E75D1D8CB49A00152EF0 /* PBXContainerItemProxy */ = { + D4F47B4422270BB6003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D4F56B91217FA40800FCA6B7; + remoteInfo = Security_frameworks_watchos; }; - DC65E75F1D8CB4A300152EF0 /* PBXContainerItemProxy */ = { + D4F47B4622270BB6003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1; + remoteGlobalIDString = D4D1D3FC21AD0B3F0012C66C; + remoteInfo = Security_executables_core_watchos; }; - DC65E7611D8CB4AA00152EF0 /* PBXContainerItemProxy */ = { + D4F47B4822270BB6003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = D41AD42D1B967169008C7270; + remoteInfo = Security_executables_watchos; }; - DC65E7631D8CB4B100152EF0 /* PBXContainerItemProxy */ = { + D4F47B4A22270BB6003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D4F56BCE21813EE800FCA6B7; + remoteInfo = Security_internal_watchos; }; - DC65E7651D8CB4C200152EF0 /* PBXContainerItemProxy */ = { + D4F47B4C22270BB6003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = D477EE6421ED479500C9AAFF; + remoteInfo = Security_tests_watchos; }; - DC65E7671D8CB4CB00152EF0 /* PBXContainerItemProxy */ = { + D4F47B4E22270BC0003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB343AD1D8A34FD0054D16E; - remoteInfo = security_keychain_regressions; + remoteGlobalIDString = BEAA0040202B728B00E51F45; + remoteInfo = Security_executables_Swift; }; - DC65E7691D8CB4D300152EF0 /* PBXContainerItemProxy */ = { + D4F47B5022270BD9003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCA131D8B82B000070CB0; - remoteInfo = security_ssl_regressions; + remoteGlobalIDString = D4F56B8D217FA3F800FCA6B7; + remoteInfo = Security_frameworks_tvos; }; - DC65E76B1D8CB4DF00152EF0 /* PBXContainerItemProxy */ = { + D4F47B5222270BD9003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D4D1D40121AD0B4B0012C66C; + remoteInfo = Security_executables_core_tvos; }; - DC65E76D1D8CB4E600152EF0 /* PBXContainerItemProxy */ = { + D4F47B5422270BD9003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D41AD4311B967179008C7270; + remoteInfo = Security_executables_tvos; }; - DC65E76F1D8CB4ED00152EF0 /* PBXContainerItemProxy */ = { + D4F47B5622270BD9003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D4F56BCA21813EDC00FCA6B7; + remoteInfo = Security_internal_tvos; }; - DC65E7711D8CB4F400152EF0 /* PBXContainerItemProxy */ = { + D4F47B5822270BD9003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = D477EE6021ED477B00C9AAFF; + remoteInfo = Security_tests_tvos; }; - DC65E7731D8CB4FB00152EF0 /* PBXContainerItemProxy */ = { + D4F47B5A22270BDE003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = BEAA0040202B728B00E51F45; + remoteInfo = Security_executables_Swift; }; - DC6BC2731D90D07800DD57B3 /* PBXContainerItemProxy */ = { + D4F47B5C22270BEB003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC6BC26C1D90CFEF00DD57B3; - remoteInfo = securityd_macos_startup_nomake; + remoteGlobalIDString = DC6D1C70208A547400AB21AF; + remoteInfo = Security_frameworks_bridge; }; - DC6BC27A1D90D11C00DD57B3 /* PBXContainerItemProxy */ = { + D4F47B5E22270BEB003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC6BC2751D90D0BE00DD57B3; - remoteInfo = securityd_macos_DTrace_nomake; + remoteGlobalIDString = EB6A6FAE1B90F8810045DC68; + remoteInfo = Security_executables_bridge; }; - DC6BC2811D90D30F00DD57B3 /* PBXContainerItemProxy */ = { + D4F47B6022270BEB003483E9 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC6BC27C1D90D1EE00DD57B3; - remoteInfo = security_cssm_generator_nomake; + remoteGlobalIDString = D477EE5C21ED476D00C9AAFF; + remoteInfo = Security_tests_bridge; }; - DC71D8E31D959C000065FB93 /* PBXContainerItemProxy */ = { + D4F56B9C217FCA7E00FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd_ios; + remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; + remoteInfo = Security_ios; }; - DC71D8EA1D959C130065FB93 /* PBXContainerItemProxy */ = { + D4F56B9E217FCA8600FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = BEF88C271EAFFC3F00357577; + remoteInfo = TrustedPeers; }; - DC71D9E01D95BAC40065FB93 /* PBXContainerItemProxy */ = { + D4F56BA4217FCAAA00FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC71D99F1D95BA6C0065FB93; - remoteInfo = ASN1; + remoteGlobalIDString = BEF88C271EAFFC3F00357577; + remoteInfo = TrustedPeers; }; - DC71D9E21D95BAD50065FB93 /* PBXContainerItemProxy */ = { + D4F56BA6217FCAB000FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC71D99F1D95BA6C0065FB93; - remoteInfo = ASN1; + remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; + remoteInfo = Security_ios; }; - DC71DA021D95BDEA0065FB93 /* PBXContainerItemProxy */ = { + D4F56BAA217FCAF600FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = E7D847C41C6BE9710025BB44; + remoteInfo = KeychainCircle; }; - DC71DA041D95BDF90065FB93 /* PBXContainerItemProxy */ = { + D4F56BB22181306900FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = E7D847C41C6BE9710025BB44; + remoteInfo = KeychainCircle; }; - DC71DA061D95BE2F0065FB93 /* PBXContainerItemProxy */ = { + D4F56BB62181380600FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = E7D847C41C6BE9710025BB44; + remoteInfo = KeychainCircle; }; - DC71DA0C1D95DD670065FB93 /* PBXContainerItemProxy */ = { + D4F56BBA2181387600FCA6B7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = SecureObjectSync; + remoteGlobalIDString = E7D847C41C6BE9710025BB44; + remoteInfo = KeychainCircle; }; - DC82FFEA1D90D4640085674B /* PBXContainerItemProxy */ = { + DA30D6811DF8C93500EC6B43 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC82FFE51D90D3F60085674B; - remoteInfo = security_utilities_DTrace_nomake; + remoteGlobalIDString = DA30D6751DF8C8FB00EC6B43; + remoteInfo = KeychainSyncAccountUpdater; }; - DC82FFF11D90D54F0085674B /* PBXContainerItemProxy */ = { + DA41FE1C2241B64800838FB3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC82FFEC1D90D4D20085674B; - remoteInfo = security_ocspd_macos_mig_nomake; + remoteGlobalIDString = DA41FE0D2241ADC000838FB3; + remoteInfo = otpaird; }; - DC89998A1E410DBF00E6E604 /* PBXContainerItemProxy */ = { + DA41FE1E2241B65A00838FB3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = DA41FE0D2241ADC000838FB3; + remoteInfo = otpaird; }; - DCB332461F47857D00178C30 /* PBXContainerItemProxy */ = { + DC00678F1D878132005AF8DB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC211D80CFB200B0A59C; - remoteInfo = SOSCommands; + remoteGlobalIDString = DC6A82911D87749900418608; + remoteInfo = libsecurityd_client_macos; }; - DCB340181D8A248C0054D16E /* PBXContainerItemProxy */ = { + DC0067C31D8787AE005AF8DB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = security_apple_asn1; + remoteGlobalIDString = DC0067921D87876F005AF8DB; + remoteInfo = libsecurityd_server_macos; }; - DCB340891D8A25230054D16E /* PBXContainerItemProxy */ = { + DC0067D21D8788C4005AF8DB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB340661D8A24DF0054D16E; - remoteInfo = security_apple_authorization; + remoteGlobalIDString = DC0067C51D878898005AF8DB; + remoteInfo = libsecurityd_ucspc; }; - DCB3412D1D8A29830054D16E /* PBXContainerItemProxy */ = { + DC008B591D90CEC7004002A3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB3408E1D8A267C0054D16E; - remoteInfo = security_cdsa_client; + remoteGlobalIDString = DC008B451D90CE53004002A3; + remoteInfo = securityd_macos_mig_nomake; }; - DCB341781D8A2AF10054D16E /* PBXContainerItemProxy */ = { + DC008B5B1D90CEE9004002A3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB341301D8A2A010054D16E; - remoteInfo = security_cdsa_plugin; + remoteGlobalIDString = DC008B451D90CE53004002A3; + remoteInfo = securityd_macos_mig_nomake; }; - DCB342361D8A2CD70054D16E /* PBXContainerItemProxy */ = { + DC008B631D90CF37004002A3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB3417B1D8A2B860054D16E; - remoteInfo = security_cdsa_utilities; + remoteGlobalIDString = DC008B451D90CE53004002A3; + remoteInfo = securityd_macos_mig_nomake; }; - DCB345651D8A36060054D16E /* PBXContainerItemProxy */ = { + DC008B651D90CF40004002A3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB3423A1D8A32820054D16E; - remoteInfo = security_keychain; + remoteGlobalIDString = DC008B451D90CE53004002A3; + remoteInfo = securityd_macos_mig_nomake; }; - DCB345B21D8A361F0054D16E /* PBXContainerItemProxy */ = { + DC00AB691D821C0700513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCB343AD1D8A34FD0054D16E; - remoteInfo = security_keychain_regressions; + remoteGlobalIDString = DC52EC521D80D05200B0A59C; + remoteInfo = liblogging; }; - DCB515CF1ED3CC36001F1152 /* PBXContainerItemProxy */ = { + DC00AB711D821C4600513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6C9808681E788AFD00E70590; - remoteInfo = CKKSCloudKitTests_ios; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = libsecurity; }; - DCB515D61ED3CC52001F1152 /* PBXContainerItemProxy */ = { + DC00AB731D821C4800513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6C98082C1E788AEB00E70590; - remoteInfo = CKKSCloudKitTests_mac; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - DCB515D81ED3CC6B001F1152 /* PBXContainerItemProxy */ = { + DC00AB751D821C4C00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6CF4A0B31E45488B00ECD7B5; - remoteInfo = KeychainEntitledTestApp_mac; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCB515DA1ED3CC73001F1152 /* PBXContainerItemProxy */ = { + DC00AB7D1D821C7F00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6CF4A0DF1E4549F200ECD7B5; - remoteInfo = KeychainEntitledTestApp_ios; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCBE6E491D91E23D00A3E5E5 /* PBXContainerItemProxy */ = { + DC00AB7F1D821C8300513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD06A541D8CE2D5007602F1; - remoteInfo = gkunpack; + remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; + remoteInfo = libSWCAgent; }; - DCC093771D80ABC300F984E4 /* PBXContainerItemProxy */ = { + DC00AB911D821D6000513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = libsecurity; + remoteGlobalIDString = DC52EC211D80CFB200B0A59C; + remoteInfo = libSOSCommands; }; - DCC5BF371D937329008D1E84 /* PBXContainerItemProxy */ = { + DC00ABA91D821DE600513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4CA1FEBD052A3C8100F22E42; - remoteInfo = libsecurity_cms; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - DCD067821D8CDF58007602F1 /* PBXContainerItemProxy */ = { + DC00ABAB1D821DE700513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD067561D8CDCF3007602F1; - remoteInfo = codesigning_DTrace; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCD067841D8CDF5C007602F1 /* PBXContainerItemProxy */ = { + DC00ABAD1D821DEB00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD0675B1D8CDD6D007602F1; - remoteInfo = codesigning_SystemPolicy; + remoteGlobalIDString = DC52EC7E1D80D1A800B0A59C; + remoteInfo = libiOSSecurityRegressions; }; - DCD069711D8CE21C007602F1 /* PBXContainerItemProxy */ = { + DC00ABAF1D821DF300513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD0675B1D8CDD6D007602F1; - remoteInfo = codesigning_SystemPolicy; + remoteGlobalIDString = DC52EC601D80D0C400B0A59C; + remoteInfo = libSOSRegressions; }; - DCD069731D8CE21C007602F1 /* PBXContainerItemProxy */ = { + DC00ABB11D821DF600513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD067561D8CDCF3007602F1; - remoteInfo = codesigning_DTrace; + remoteGlobalIDString = DC52EDFD1D80D6DD00B0A59C; + remoteInfo = libSharedRegressions; }; - DCD06A441D8CE281007602F1 /* PBXContainerItemProxy */ = { + DC00ABBA1D821E9B00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD0675B1D8CDD6D007602F1; - remoteInfo = codesigning_SystemPolicy; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - DCD06A461D8CE281007602F1 /* PBXContainerItemProxy */ = { + DC00ABBC1D821E9F00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD067561D8CDCF3007602F1; - remoteInfo = codesigning_DTrace; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCD06A7F1D8CE33B007602F1 /* PBXContainerItemProxy */ = { + DC00ABBE1D821EA700513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD067781D8CDF19007602F1; - remoteInfo = security_codesigning; + remoteGlobalIDString = DC52ED631D80D4CD00B0A59C; + remoteInfo = libiOSsecuritydRegressions; }; - DCD06A811D8CE33F007602F1 /* PBXContainerItemProxy */ = { + DC00ABC81D821F0200513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD0696F1D8CE21C007602F1; - remoteInfo = integrity; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - DCD06A831D8CE343007602F1 /* PBXContainerItemProxy */ = { + DC00ABCA1D821F0500513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD06A421D8CE281007602F1; - remoteInfo = codehost; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCD06A851D8CE348007602F1 /* PBXContainerItemProxy */ = { + DC00ABD01D821F1A00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD069661D8CE105007602F1; - remoteInfo = codesigning_RequirementsLanguage; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = libsecurity; }; - DCD06A871D8CE34D007602F1 /* PBXContainerItemProxy */ = { + DC00ABD21D821F1D00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD06A541D8CE2D5007602F1; - remoteInfo = gkunpack; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCD06A891D8CE356007602F1 /* PBXContainerItemProxy */ = { + DC00ABD41D821F2700513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD067781D8CDF19007602F1; - remoteInfo = security_codesigning; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - DCD06BCE1D8E0F01007602F1 /* PBXContainerItemProxy */ = { + DC00ABDF1D821F5C00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD06AA91D8E0D53007602F1; - remoteInfo = security_utilities; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCD22D661D8CC387001C9B81 /* PBXContainerItemProxy */ = { + DC00ABE11D821F6000513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC601D80D0C400B0A59C; - remoteInfo = SOSRegressions; + remoteGlobalIDString = DC52EDA61D80D58400B0A59C; + remoteInfo = libsecdRegressions; }; - DCD22D681D8CC3A6001C9B81 /* PBXContainerItemProxy */ = { + DC00ABE31D821F6200513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCCF41D8C694700070CB0; - remoteInfo = utilitiesRegressions; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - DCD22D7A1D8CCA07001C9B81 /* PBXContainerItemProxy */ = { + DC00ABED1D821FB700513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC9C81D8B824700070CB0; - remoteInfo = security_ssl; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = libSecureObjectSync; }; - DCD22D7C1D8CCA18001C9B81 /* PBXContainerItemProxy */ = { + DC00ABEF1D821FBA00513D74 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1; + remoteGlobalIDString = DC52EC601D80D0C400B0A59C; + remoteInfo = libSOSRegressions; }; - DCD22D7E1D8CCA2C001C9B81 /* PBXContainerItemProxy */ = { + DC00C91520B3B73900628BEB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; }; - DCD22D811D8CCB5A001C9B81 /* PBXContainerItemProxy */ = { + DC00C91720B3B74600628BEB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E7731D80BC8000B0A59C; - remoteInfo = libsecurityd_ios; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; }; - DCD22D831D8CCB72001C9B81 /* PBXContainerItemProxy */ = { + DC00C91920B3B74E00628BEB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; - remoteInfo = SecureObjectSync; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - DCD66DC21D82056C00DB1393 /* PBXContainerItemProxy */ = { + DC00C91E20B3B7A800628BEB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD66D5E1D8204A700DB1393; - remoteInfo = libSecTrustOSX; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; }; - DCD66DE51D82061F00DB1393 /* PBXContainerItemProxy */ = { + DC00C92620B3B86800628BEB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD66DC41D8205C400DB1393; - remoteInfo = libSecOtrOSX; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - DCD8A19B1E09EEA200E4FA0A /* PBXContainerItemProxy */ = { + DC0503602140848100A8EDB7 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = BED987D22099145300607A5F; + remoteInfo = TrustedPeersHelperUnitTests; }; - DCD8A1E51E09F81300E4FA0A /* PBXContainerItemProxy */ = { + DC0984F61E1DB6D400140ADC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; remoteInfo = SecureObjectSyncFramework; }; - DCD8A1E81E09F85B00E4FA0A /* PBXContainerItemProxy */ = { + DC0984FF1E1DB70A00140ADC /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; }; - DCD8A1EB1E09F88400E4FA0A /* PBXContainerItemProxy */ = { + DC0BB4431ED4D74A0035F886 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; }; - DCD8A1EE1E09F8BC00E4FA0A /* PBXContainerItemProxy */ = { + DC0BC5AE1D8B714000070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC5851D8B70E700070CB0; + remoteInfo = security_cdsa_utils; }; - DCD8A1F11E09F8DB00E4FA0A /* PBXContainerItemProxy */ = { + DC0BC5C01D8B72BB00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC5B01D8B71FD00070CB0; + remoteInfo = security_checkpw; }; - DCD8A1F41E09F91F00E4FA0A /* PBXContainerItemProxy */ = { + DC0BC5D11D8B732300070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC5B01D8B71FD00070CB0; + remoteInfo = security_checkpw; }; - DCD8A1F71E09F97300E4FA0A /* PBXContainerItemProxy */ = { + DC0BC5D71D8B73B000070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC5B01D8B71FD00070CB0; + remoteInfo = security_checkpw; }; - DCD8A1FA1E09F99700E4FA0A /* PBXContainerItemProxy */ = { + DC0BC5F61D8B749000070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC5E21D8B742200070CB0; + remoteInfo = security_comcryption; }; - DCD8A1FD1E09FA1800E4FA0A /* PBXContainerItemProxy */ = { + DC0BC7421D8B762F00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC5F81D8B752B00070CB0; + remoteInfo = security_cryptkit; }; - DCD8A2021E09FAE500E4FA0A /* PBXContainerItemProxy */ = { + DC0BC7BE1D8B784F00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC7451D8B771600070CB0; + remoteInfo = security_cssm; }; - DCD8A2061E09FB1F00E4FA0A /* PBXContainerItemProxy */ = { + DC0BC8C81D8B7D1C00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DC0BC8981D8B7CBD00070CB0; + remoteInfo = security_filedb; }; - DCDB29751FD8839F00B5D242 /* PBXContainerItemProxy */ = { + DC0BC8F51D8B7DE700070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C85DFD11FB38BB6000343A7; - remoteInfo = OTTests_osx; + remoteGlobalIDString = DC0BC8CC1D8B7DA200070CB0; + remoteInfo = security_manifest; }; - DCDB29771FD883AB00B5D242 /* PBXContainerItemProxy */ = { + DC0BC92B1D8B7EBB00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C85DFD11FB38BB6000343A7; - remoteInfo = OTTests_osx; + remoteGlobalIDString = DC0BC8F91D8B7E8000070CB0; + remoteInfo = security_mds; }; - DCE4E6A91D7A38E700AFB96E /* PBXContainerItemProxy */ = { + DC0BC9641D8B80D200070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E68A1D7A37FA00AFB96E; - remoteInfo = security2tool_macos; + remoteGlobalIDString = DC0BC92E1D8B7F6A00070CB0; + remoteInfo = security_ocspd; }; - DCE4E7B71D7A456500AFB96E /* PBXContainerItemProxy */ = { + DC0BC9981D8B814A00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E7311D7A43B500AFB96E; - remoteInfo = SecurityTestsOSX; + remoteGlobalIDString = DC0BC9661D8B810A00070CB0; + remoteInfo = security_pkcs12; }; - DCE4E7BB1D7A45ED00AFB96E /* PBXContainerItemProxy */ = { + DC0BC9C61D8B820000070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = AC62F5EF18B4356A00704BBD; - remoteInfo = libsecurity_smime_regressions; + remoteGlobalIDString = DC0BC99A1D8B81BE00070CB0; + remoteInfo = security_sd_cspdl; }; - DCE4E7D71D7A4B3500AFB96E /* PBXContainerItemProxy */ = { + DC0BCA751D8B82E900070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = AC62F5EF18B4356A00704BBD; - remoteInfo = libsecurity_smime_regressions; + remoteGlobalIDString = DC0BC9C81D8B824700070CB0; + remoteInfo = security_ssl; }; - DCE4E7F01D7A4BEC00AFB96E /* PBXContainerItemProxy */ = { + DC0BCA771D8B830900070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E7CB1D7A4AED00AFB96E; - remoteInfo = sectests_macos; + remoteGlobalIDString = DC0BCA131D8B82B000070CB0; + remoteInfo = security_ssl_regressions; }; - DCE4E8291D7A4F2500AFB96E /* PBXContainerItemProxy */ = { + DC0BCAFF1D8B85E500070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E7F51D7A4DA800AFB96E; - remoteInfo = secd; + remoteGlobalIDString = DC0BCA791D8B858600070CB0; + remoteInfo = security_transform; }; - DCE4E8611D7A58BA00AFB96E /* PBXContainerItemProxy */ = { + DC0BCB2F1D8B89AB00070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E82D1D7A57AE00AFB96E; - remoteInfo = trustd; + remoteGlobalIDString = DC0BCB011D8B894F00070CB0; + remoteInfo = security_translocate; }; - DCE4E8D71D7F37F200AFB96E /* PBXContainerItemProxy */ = { + DC0BCC1B1D8C655900070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E8931D7F34F600AFB96E; - remoteInfo = authd; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionHarness; }; - DCE4E90B1D7F3B4A00AFB96E /* PBXContainerItemProxy */ = { + DC0BCDB61D8C6AD100070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E8DC1D7F39DB00AFB96E; - remoteInfo = "Cloud Keychain Utility"; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - DCE4E9721D7F3FC200AFB96E /* PBXContainerItemProxy */ = { + DC0BCDB81D8C6AE000070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCE4E9101D7F3D5300AFB96E; - remoteInfo = "Keychain Circle Notification"; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - DCE5DC161EA804E5006308A6 /* PBXContainerItemProxy */ = { + DC0BCDBA1D8C6AF000070CB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC52EC211D80CFB200B0A59C; - remoteInfo = SOSCommands; + remoteGlobalIDString = DC0BCCF41D8C694700070CB0; + remoteInfo = iOSutilitiesRegressions; }; - DCF785001D88B80600E694BB /* PBXContainerItemProxy */ = { + DC178BF21D77ABE300B50D50 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCF7830A1D88B4DE00E694BB; - remoteInfo = security_apple_csp; + remoteGlobalIDString = DC1789031D77980500B50D50; + remoteInfo = Security_osx; }; - DCF787311D88C1B000E694BB /* PBXContainerItemProxy */ = { + DC26710F1F3E933700816EED /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCF785021D88B95500E694BB; - remoteInfo = security_apple_cspdl; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - DCF788451D88C98100E694BB /* PBXContainerItemProxy */ = { + DC27C3CC20EAFDF800F7839C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCF788341D88C8C400E694BB; - remoteInfo = security_apple_filedl; + remoteGlobalIDString = DC99B85B20EACA470065B73B; + remoteInfo = OctagonTests; }; - DCF788A31D88CB6000E694BB /* PBXContainerItemProxy */ = { + DC311E662124A9D2002F5EAE /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCF788471D88CA7200E694BB; - remoteInfo = security_apple_x509_cl; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - DCF788A81D88CC3500E694BB /* PBXContainerItemProxy */ = { + DC34CD2C20326C2C00302481 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCF788471D88CA7200E694BB; - remoteInfo = security_apple_x509_cl; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; }; - DCF789451D88CD7C00E694BB /* PBXContainerItemProxy */ = { + DC34CD3320326C3100302481 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCF788AB1D88CD2400E694BB; - remoteInfo = security_apple_x509_tp; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; }; - E74583BD1BF66489001B54A4 /* PBXContainerItemProxy */ = { + DC34CD3520326C3B00302481 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 52D82BDD16A621F70078DFE5; - remoteInfo = CloudKeychainProxy; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - E745846C1BF68ECB001B54A4 /* PBXContainerItemProxy */ = { + DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 05EF68BB194915A5007958C3; - remoteInfo = Security_executables; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - E745846E1BF68ECB001B54A4 /* PBXContainerItemProxy */ = { + DC3502CD1E020E2200BC0587 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 05EF68C1194915FB007958C3; - remoteInfo = Security_kexts; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - E74584701BF68ECB001B54A4 /* PBXContainerItemProxy */ = { + DC3502D41E02117600BC0587 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 05EF68AF1949149C007958C3; - remoteInfo = Security_temporary_UI; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; }; - E79EEDD61CD3F9F800C2FBFC /* PBXContainerItemProxy */ = { + DC391FA221C03F8D00772585 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C7CFA2E14E1BA4800DF9D95; - remoteInfo = Security_frameworks_ios; + remoteGlobalIDString = 0C8BBEFD1FCB446400580909; + remoteInfo = otctl; }; - E79EEDDE1CD3FFEA00C2FBFC /* PBXContainerItemProxy */ = { + DC3A4B6A1D91EBEE00E46D4A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E79EEDD81CD3FFC800C2FBFC; - remoteInfo = Security_frameworks_macos; + remoteGlobalIDString = DC3A4B571D91E9FB00E46D4A; + remoteInfo = CodeSigningHelper; }; - E79EEDE41CD4001300C2FBFC /* PBXContainerItemProxy */ = { + DC3E18C9212501C200073D80 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 05EF68BB194915A5007958C3; - remoteInfo = Security_executables_macos; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - E79EEDE61CD4003900C2FBFC /* PBXContainerItemProxy */ = { + DC3E18CB2125020400073D80 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E79EEDD81CD3FFC800C2FBFC; - remoteInfo = Security_frameworks_macos; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - E7CFF6701C84F62900E3484E /* PBXContainerItemProxy */ = { + DC3E18CD2125024C00073D80 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7D847C41C6BE9710025BB44; - remoteInfo = KeychainCircle; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - E7CFF6721C84F62900E3484E /* PBXContainerItemProxy */ = { + DC3E18E72125F9EF00073D80 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7D847CD1C6BE9720025BB44; - remoteInfo = KeychainCircleTests; + remoteGlobalIDString = DC36895D21235F42003A3735; + remoteInfo = aks_mock; }; - E7CFF6741C84F65D00E3484E /* PBXContainerItemProxy */ = { + DC52E84A1D80BF1100B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7CFF6471C84F61200E3484E; - remoteInfo = Security_KeychainCircle; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd; }; - E7CFF6761C84F66A00E3484E /* PBXContainerItemProxy */ = { + DC52EC3C1D80CFF000B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7CFF6471C84F61200E3484E; - remoteInfo = Security_KeychainCircle; + remoteGlobalIDString = DC52EC211D80CFB200B0A59C; + remoteInfo = libSOSCommands; }; - E7D847D01C6BE9720025BB44 /* PBXContainerItemProxy */ = { + DC52EC501D80D03100B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7D847C41C6BE9710025BB44; - remoteInfo = KeychainCircle; + remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; + remoteInfo = libSWCAgent; }; - EB0D30F91EF12BFB00C3C17D /* PBXContainerItemProxy */ = { + DC52EC5E1D80D08100B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E79EEDD21CD3F8AB00C2FBFC; - remoteInfo = Security_tests_ios; + remoteGlobalIDString = DC52EC521D80D05200B0A59C; + remoteInfo = liblogging; }; - EB10557C1E14DFB60003C309 /* PBXContainerItemProxy */ = { + DC52EC7C1D80D18800B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB1055741E14DF430003C309; - remoteInfo = SecCertificateFuzzer; + remoteGlobalIDString = DC52EC601D80D0C400B0A59C; + remoteInfo = libSOSRegressions; }; - EB10557E1E14DFBE0003C309 /* PBXContainerItemProxy */ = { + DC52ECEB1D80D34C00B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB1055741E14DF430003C309; - remoteInfo = SecCertificateFuzzer; + remoteGlobalIDString = DC52EC7E1D80D1A800B0A59C; + remoteInfo = libSecurityRegressions; }; - EB108F201E6CE4D2003B0456 /* PBXContainerItemProxy */ = { + DC52EDA21D80D55300B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCC211D8C684F00070CB0; - remoteInfo = utilities; + remoteGlobalIDString = DC52ED631D80D4CD00B0A59C; + remoteInfo = libiOSsecuritydRegressions; }; - EB11965920A6300600BFDA1B /* PBXContainerItemProxy */ = { + DC52EDFB1D80D67C00B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4809F7A42061B697003E72D0; - remoteInfo = MultiPeerSimulatorTests; + remoteGlobalIDString = DC52EDA61D80D58400B0A59C; + remoteInfo = libsecdRegressions; }; - EB11965B20A6301100BFDA1B /* PBXContainerItemProxy */ = { + DC52EE621D80D7D900B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4809F7A42061B697003E72D0; - remoteInfo = MultiPeerSimulatorTests; + remoteGlobalIDString = DC52EDFD1D80D6DD00B0A59C; + remoteInfo = libSharedRegressions; }; - EB11965D20A6302100BFDA1B /* PBXContainerItemProxy */ = { + DC52EE641D80D7F000B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4809F7A42061B697003E72D0; - remoteInfo = MultiPeerSimulatorTests; + remoteGlobalIDString = DC52EDFD1D80D6DD00B0A59C; + remoteInfo = libSharedRegressions; }; - EB1C4CA61E85883900404981 /* PBXContainerItemProxy */ = { + DC52EE7D1D80D8B100B0A59C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 470415CE1E5E14B5001F3D95; - remoteInfo = seckeychainnetworkextensionstest; + remoteGlobalIDString = DC52EE661D80D82600B0A59C; + remoteInfo = libSecItemShimOSX; }; - EB1C4CA81E85883900404981 /* PBXContainerItemProxy */ = { + DC58C4421D77C1F8003C25A4 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47702B1D1E5F409700B29577; - remoteInfo = seckeychainnetworkextensionsystemdaemontest; + remoteGlobalIDString = DC58C4221D77BDEA003C25A4; + remoteInfo = csparser_osx; }; - EB1C4CAA1E85883900404981 /* PBXContainerItemProxy */ = { + DC5ABE1B1D832F5E00CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47702B2D1E5F492C00B29577; - remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + remoteGlobalIDString = DC5ABDC41D832DAB00CF422C; + remoteInfo = securitytool_macos; }; - EB1C4CB11E85884300404981 /* PBXContainerItemProxy */ = { + DC5AC0B41D83533400CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 470415CE1E5E14B5001F3D95; - remoteInfo = seckeychainnetworkextensionstest; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 189D4635166AC95C001D8533; + remoteInfo = securityd_service; }; - EB1C4CB31E85884300404981 /* PBXContainerItemProxy */ = { + DC5AC0B61D83533400CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 47702B1D1E5F409700B29577; - remoteInfo = seckeychainnetworkextensionsystemdaemontest; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 189D465B166C15C1001D8533; + remoteInfo = securitydservicectrl; }; - EB1C4CB51E85884300404981 /* PBXContainerItemProxy */ = { + DC5AC0B81D83533400CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 47702B2D1E5F492C00B29577; - remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1843240E1714797D00196B52; + remoteInfo = securitydservice_client; }; - EB27FF251E40716D00EC9E3A /* PBXContainerItemProxy */ = { + DC5AC0BA1D83533400CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; - proxyType = 1; - remoteGlobalIDString = EB27FF101E402CD300EC9E3A; - remoteInfo = ckksctl; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 18F4808E17497521009724DB; + remoteInfo = KeyStoreEvents; }; - EB27FF271E40717400EC9E3A /* PBXContainerItemProxy */ = { + DC5AC0BC1D83533E00CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; proxyType = 1; - remoteGlobalIDString = EB27FF101E402CD300EC9E3A; - remoteInfo = ckksctl; + remoteGlobalIDString = 1843240D1714797D00196B52; + remoteInfo = securitydservice_client; }; - EB31EA821D3EF2FB008F952A /* PBXContainerItemProxy */ = { + DC5AC0BE1D83534300CF422C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; proxyType = 1; - remoteGlobalIDString = 5346480017331E1100FE9172; - remoteInfo = KeychainSyncAccountNotification; + remoteGlobalIDString = 189D4634166AC95C001D8533; + remoteInfo = securityd_service; }; - EB3A8E001BEEC6F3001A89AA /* PBXContainerItemProxy */ = { + DC6013362147222B00863C1A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1D791BDFD0E000F89272; - remoteInfo = secbackupntest; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - EB425CD01C6585F1000ECE53 /* PBXContainerItemProxy */ = { + DC60133C214722C900863C1A /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB425C9E1C65846D000ECE53; - remoteInfo = secbackuptest; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - EB433A2B1CC3252A00A7EACE /* PBXContainerItemProxy */ = { + DC6063AF21B0755D00069B82 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB433A201CC3243600A7EACE; - remoteInfo = secitemstresstest; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - EB58A05B1E74C517009C10D7 /* PBXContainerItemProxy */ = { + DC63CAF21D90DF6000C03317 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E79EEDA71CD3F87B00C2FBFC; - remoteInfo = Security_tests_osx; + remoteGlobalIDString = DC63CAE81D90D63500C03317; + remoteInfo = libsecurityd_macos_mig; }; - EB58A05D1E74C51F009C10D7 /* PBXContainerItemProxy */ = { + DC63CAF41D90DF6700C03317 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E79EEDD21CD3F8AB00C2FBFC; - remoteInfo = Security_tests_ios; + remoteGlobalIDString = DC63CAE81D90D63500C03317; + remoteInfo = libsecurityd_macos_mig; }; - EB58A05F1E74C8D9009C10D7 /* PBXContainerItemProxy */ = { + DC63CAF61D90DF7000C03317 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBB839A41E29665D00853BAC; - remoteInfo = secfuzzer; + remoteGlobalIDString = DC63CAE81D90D63500C03317; + remoteInfo = libsecurityd_macos_mig; }; - EB58A0611E74C8E4009C10D7 /* PBXContainerItemProxy */ = { + DC647C43208A85BE00D0F9F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBB839A41E29665D00853BAC; - remoteInfo = secfuzzer; + remoteGlobalIDString = BEF88C271EAFFC3F00357577; + remoteInfo = TrustedPeers; }; - EB636BC920992D8900C1E21A /* PBXContainerItemProxy */ = { + DC647C45208A85C900D0F9F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB49B2AD202D877F003F34A0; - remoteInfo = secdmockaks; + remoteGlobalIDString = BEF88C271EAFFC3F00357577; + remoteInfo = TrustedPeers; }; - EB636BD020992DA300C1E21A /* PBXContainerItemProxy */ = { + DC647C47208A864800D0F9F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB49B2AD202D877F003F34A0; - remoteInfo = secdmockaks; + remoteGlobalIDString = BEAA0040202B728B00E51F45; + remoteInfo = Security_executables_Swift; }; - EB636BD220992DB400C1E21A /* PBXContainerItemProxy */ = { + DC647C49208A865200D0F9F8 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB49B2AD202D877F003F34A0; - remoteInfo = secdmockaks; + remoteGlobalIDString = BEAA0040202B728B00E51F45; + remoteInfo = Security_executables_Swift; }; - EB636BD420992DC000C1E21A /* PBXContainerItemProxy */ = { + DC65E7211D8CB27900152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB49B2AD202D877F003F34A0; - remoteInfo = secdmockaks; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - EB63ADE01C3E74F900C45A69 /* PBXContainerItemProxy */ = { + DC65E7251D8CB2E100152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB0BC9361C3C791500785842; - remoteInfo = secedumodetest; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - EB6A6FAC1B90F84D0045DC68 /* PBXContainerItemProxy */ = { + DC65E7281D8CB2F400152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C7CFA2E14E1BA4800DF9D95; - remoteInfo = Security_frameworks_ios; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - EB6A6FB81B90F8D70045DC68 /* PBXContainerItemProxy */ = { + DC65E72B1D8CB31200152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4C541F840F250BF500E508AE; - remoteInfo = Security_executables_ios; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - EB6A6FBA1B90F8EC0045DC68 /* PBXContainerItemProxy */ = { + DC65E72E1D8CB32400152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 0C7CFA2E14E1BA4800DF9D95; - remoteInfo = Security_frameworks_ios; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - EB6A6FBC1B90F9170045DC68 /* PBXContainerItemProxy */ = { + DC65E7381D8CB38300152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; - remoteInfo = Security; + remoteGlobalIDString = DCB3417B1D8A2B860054D16E; + remoteInfo = security_cdsa_utilities; }; - EB8910F020E0287600DE533F /* PBXContainerItemProxy */ = { + DC65E73A1D8CB39300152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4727FBB61F9918580003AE36; - remoteInfo = secdxctests_ios; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; }; - EB8910F720E0287E00DE533F /* PBXContainerItemProxy */ = { + DC65E73D1D8CB3C100152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4727FBB61F9918580003AE36; - remoteInfo = secdxctests_ios; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EB8910FD20E06DF500DE533F /* PBXContainerItemProxy */ = { + DC65E73F1D8CB3CD00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6C46056B1F882B9B001421B6; - remoteInfo = KeychainAnalyticsTests; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EB89FAFD20DBDAA800085498 /* PBXContainerItemProxy */ = { + DC65E7411D8CB3D400152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 470415CE1E5E14B5001F3D95; - remoteInfo = seckeychainnetworkextensionstest; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1; }; - EB89FAFF20DBDAA800085498 /* PBXContainerItemProxy */ = { + DC65E7431D8CB3E000152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47702B1D1E5F409700B29577; - remoteInfo = seckeychainnetworkextensionsystemdaemontest; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1; }; - EB89FB0120DBDAA800085498 /* PBXContainerItemProxy */ = { + DC65E7451D8CB3E700152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47702B2D1E5F492C00B29577; - remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EB9C1DB61BDFD51800F89272 /* PBXContainerItemProxy */ = { + DC65E7471D8CB3F000152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; - remoteInfo = SecurityBatsTests; + remoteGlobalIDString = DC0BCA131D8B82B000070CB0; + remoteInfo = security_ssl_regressions; }; - EB9FE08C1BFBC48F004FEAAF /* PBXContainerItemProxy */ = { + DC65E7491D8CB3FE00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; - remoteInfo = SecurityBatsTests; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - EB9FE0B51BFBC499004FEAAF /* PBXContainerItemProxy */ = { + DC65E74B1D8CB40C00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; - remoteInfo = SecurityBatsTests; + remoteGlobalIDString = DC0BCCF41D8C694700070CB0; + remoteInfo = utilitiesRegressions; }; - EBA62C141EAD34C60096B33A /* PBXContainerItemProxy */ = { + DC65E74D1D8CB41E00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; - remoteInfo = KeychainEntitledTestRunner; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1; }; - EBA62C1B1EAD34CD0096B33A /* PBXContainerItemProxy */ = { + DC65E74F1D8CB42700152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; - remoteInfo = KeychainEntitledTestRunner; + remoteGlobalIDString = DC0BCA131D8B82B000070CB0; + remoteInfo = security_ssl_regressions; }; - EBA9AA881CE3E76C004E2B68 /* PBXContainerItemProxy */ = { + DC65E7511D8CB45300152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBA9AA7D1CE30E58004E2B68; - remoteInfo = secitemnotifications; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBB696D31BE2085700715F16 /* PBXContainerItemProxy */ = { + DC65E7531D8CB46100152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1D791BDFD0E000F89272; - remoteInfo = secbackupntest; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - EBC15EA81BE29AC3001C0C5B /* PBXContainerItemProxy */ = { + DC65E7551D8CB47600152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB9C1DAE1BDFD4DE00F89272; - remoteInfo = SecurityBatsTests; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBC73F51209A705A00AE3350 /* PBXContainerItemProxy */ = { + DC65E7571D8CB47D00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 6C46056B1F882B9B001421B6; - remoteInfo = KeychainAnalyticsTests; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - EBC73F5C209A739600AE3350 /* PBXContainerItemProxy */ = { + DC65E7591D8CB48900152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 470415CE1E5E14B5001F3D95; - remoteInfo = seckeychainnetworkextensionstest; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1; }; - EBC73F63209A73A100AE3350 /* PBXContainerItemProxy */ = { + DC65E75B1D8CB49200152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47702B1D1E5F409700B29577; - remoteInfo = seckeychainnetworkextensionsystemdaemontest; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - EBC73F65209A73A100AE3350 /* PBXContainerItemProxy */ = { + DC65E75D1D8CB49A00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 47702B2D1E5F492C00B29577; - remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBCE150F1FE638A2002E7CCC /* PBXContainerItemProxy */ = { + DC65E75F1D8CB4A300152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB056E3D1FE5E390000A771E; - remoteInfo = DeviceSimulator; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1; }; - EBCF743E1CE593A700BED7CA /* PBXContainerItemProxy */ = { + DC65E7611D8CB4AA00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBCF73F31CE45F9C00BED7CA; - remoteInfo = secitemfunctionality; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - EBD31B3A1E0A186500FBE9FA /* PBXContainerItemProxy */ = { + DC65E7631D8CB4B100152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5631D8B6E3D00070CB0; - remoteInfo = XPCTimeStampingService; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBD31B411E0A18A600FBE9FA /* PBXContainerItemProxy */ = { + DC65E7651D8CB4C200152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC5501D8B6D2D00070CB0; - remoteInfo = XPCKeychainSandboxCheck; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; }; - EBD849351B242C8900C5FD1E /* PBXContainerItemProxy */ = { + DC65E7671D8CB4CB00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = 4CE5A54C09C796E100D27A3F; - remoteInfo = sslViewer; + remoteGlobalIDString = DCB343AD1D8A34FD0054D16E; + remoteInfo = security_keychain_regressions; }; - EBF374811DC058B60065D840 /* PBXContainerItemProxy */ = { + DC65E7691D8CB4D300152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBF374711DC055580065D840; - remoteInfo = "security-sysdiagnose"; + remoteGlobalIDString = DC0BCA131D8B82B000070CB0; + remoteInfo = security_ssl_regressions; }; - EBF374831DC058C00065D840 /* PBXContainerItemProxy */ = { + DC65E76B1D8CB4DF00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBF374711DC055580065D840; - remoteInfo = "security-sysdiagnose"; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBF374851DC058C50065D840 /* PBXContainerItemProxy */ = { + DC65E76D1D8CB4E600152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBF374711DC055580065D840; - remoteInfo = "security-sysdiagnose"; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBF374871DC058CC0065D840 /* PBXContainerItemProxy */ = { + DC65E76F1D8CB4ED00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EBF374711DC055580065D840; - remoteInfo = "security-sysdiagnose"; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBFBC2AF1E76582C00A34469 /* PBXContainerItemProxy */ = { + DC65E7711D8CB4F400152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB108F181E6CE4D2003B0456; - remoteInfo = KCPairingTests; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBFBC2B11E76585500A34469 /* PBXContainerItemProxy */ = { + DC65E7731D8CB4FB00152EF0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = E7D847C41C6BE9710025BB44; - remoteInfo = KeychainCircle; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - EBFBC2B31E76586700A34469 /* PBXContainerItemProxy */ = { + DC69A5822165295F00512BD6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCC78EA81D8088E200865A7C; - remoteInfo = security; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - EBFBC2B51E76587800A34469 /* PBXContainerItemProxy */ = { + DC69A5862165298500512BD6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; - remoteInfo = SecureObjectSyncFramework; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; }; - EBFBC2B91E76588A00A34469 /* PBXContainerItemProxy */ = { + DC6BC2731D90D07800DD57B3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC8834011D8A218F00CE0ACA; - remoteInfo = ASN1_not_installed; + remoteGlobalIDString = DC6BC26C1D90CFEF00DD57B3; + remoteInfo = securityd_macos_startup_nomake; }; - EBFF18CD1F02BA66004E58FC /* PBXContainerItemProxy */ = { + DC6BC27A1D90D11C00DD57B3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = EB2D54A11F02A45E00E46890; - remoteInfo = secatomicfile; + remoteGlobalIDString = DC6BC2751D90D0BE00DD57B3; + remoteInfo = securityd_macos_DTrace_nomake; }; - EBFF18CF1F02C2FE004E58FC /* PBXContainerItemProxy */ = { + DC6BC2811D90D30F00DD57B3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BC8981D8B7CBD00070CB0; - remoteInfo = security_filedb; + remoteGlobalIDString = DC6BC27C1D90D1EE00DD57B3; + remoteInfo = security_cssm_generator_nomake; }; - F621D0821ED6ED5B000EA569 /* PBXContainerItemProxy */ = { + DC6D1C74208A547400AB21AF /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = F621D0271ED6DCE7000EA569; - remoteInfo = AuthorizationTestTool; + remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; + remoteInfo = Security; }; - F667EC641E96EDCF00203D5C /* PBXContainerItemProxy */ = { + DC71D8E31D959C000065FB93 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; - remoteInfo = regressionBase; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - F667EC661E96FA4600203D5C /* PBXContainerItemProxy */ = { + DC71D8EA1D959C130065FB93 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = F667EC561E96E9B100203D5C; - remoteInfo = authdtest; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - F94E7AE11ACC8E7700F23132 /* PBXContainerItemProxy */ = { + DC71DA021D95BDEA0065FB93 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 4C35DB69094F906D002917C4 /* Project object */; proxyType = 1; - remoteGlobalIDString = F93C49021AB8FCE00047E01A; - remoteInfo = ckcdiagnose.sh; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 0C0BDB2D175685B000BC1A7E /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - 0C85DFFD1FB38BB6000343A7 /* Embed OCMock */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */, - ); - name = "Embed OCMock"; - runOnlyForDeploymentPostprocessing = 0; + DC71DA041D95BDF90065FB93 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - 0C8BBF041FCB446400580909 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; + DC71DA061D95BE2F0065FB93 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - 0C9AEEB320783FBB00BF6237 /* Embed OCMock */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed OCMock"; - runOnlyForDeploymentPostprocessing = 0; + DC71DA0C1D95DD670065FB93 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSync; }; - 0CF4064A2072E3E3003D6A7F /* Embed OCMock */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed OCMock"; - runOnlyForDeploymentPostprocessing = 0; + DC74799F22272361001E0E8C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF216D621ADD5B10029CCC1; + remoteInfo = protobuf_source_generation; }; - 3DD1FFD3201FF72C0086D049 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /AppleInternal/CoreOS/BATS/unit_tests; - dstSubfolderSpec = 0; - files = ( - 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DC7FC45121EE9208003C39B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC7FC44721EE914C003C39B8; + remoteInfo = FeatureFlagsPlist; }; - 3DD1FFD6201FF7930086D049 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /AppleInternal/CoreOS/BATS/unit_tests; - dstSubfolderSpec = 0; - files = ( - 3DD1FFD7201FF7B10086D049 /* SecureTransport_macosTests.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DC7FC45321EE921A003C39B8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC7FC44721EE914C003C39B8; + remoteInfo = FeatureFlagsPlist; }; - 470415CD1E5E14B5001F3D95 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; + DC82FFEA1D90D4640085674B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC82FFE51D90D3F60085674B; + remoteInfo = security_utilities_DTrace_nomake; }; - 4718AE26205B39620068EC3F /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/LaunchDaemons; - dstSubfolderSpec = 0; - files = ( - 4718AE27205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DC82FFF11D90D54F0085674B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC82FFEC1D90D4D20085674B; + remoteInfo = security_ocspd_macos_mig_nomake; }; - 4718AE28205B39620068EC3F /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/Preferences/Logging/Subsystems; - dstSubfolderSpec = 0; - files = ( - 4718AE29205B39620068EC3F /* com.apple.securityd.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DC89998A1E410DBF00E6E604 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - 47702B1C1E5F409700B29577 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; + DC93C4C8214713DC008F8362 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - 47702B2C1E5F492C00B29577 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; + DC93C4CC21471401008F8362 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; }; - 4814D8691CAA059E002FFC36 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /System/Library/Preferences/Logging/Subsystems; - dstSubfolderSpec = 0; - files = ( - DC71D8F51D959F150065FB93 /* com.apple.securityd.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DC99B85D20EACA470065B73B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; }; - 4C50AD081410673800EE92DE /* Copy DigiNotar Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = DigiNotar; - dstSubfolderSpec = 7; - files = ( - 4C50AD0C1410679000EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */, - 4C50AD0D1410679000EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */, - 4C50AD0E1410679000EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */, - 4C50AD0F1410679000EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar Resources */, - 4C50AD101410679000EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar Resources */, - 4C50AD111410679000EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar Resources */, - 4C50AD121410679000EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar Resources */, - 4C50AD131410679000EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar Resources */, - 4C50AD141410679000EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar Resources */, - 4C50AD151410679000EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar Resources */, - 4C8B91C91416ED7E00A254E2 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar Resources */, - 4C8B91CA1416ED7E00A254E2 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar Resources */, - 4C8B91CB1416ED7E00A254E2 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar Resources */, - 4C8B91CC1416ED7E00A254E2 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar Resources */, - 4C8B91CD1416ED7E00A254E2 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar Resources */, - 4C8B91CF1416ED7E00A254E2 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar Resources */, - 4C8B91D01416ED7E00A254E2 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar Resources */, - 4C8B91D11416ED7E00A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar Resources */, - ); - name = "Copy DigiNotar Resources"; - runOnlyForDeploymentPostprocessing = 0; + DC99B86320EACA470065B73B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; }; - 4C50AD091410675400EE92DE /* Copy DigiNotar-Entrust Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "DigiNotar-Entrust"; - dstSubfolderSpec = 7; - files = ( - 4C50AD181410679900EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD191410679900EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD1A1410679900EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD1B1410679900EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD1C1410679900EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD1D1410679900EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD1E1410679900EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD1F1410679900EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD201410679900EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD211410679900EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD221410679900EE92DE /* diginotar.root.ca-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D21416ED8E00A254E2 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D31416ED8E00A254E2 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D41416ED8E00A254E2 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D51416ED8E00A254E2 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D61416ED8E00A254E2 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D81416ED8E00A254E2 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91D91416ED8E00A254E2 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C8B91DA1416ED8E00A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-Entrust Resources */, - ); - name = "Copy DigiNotar-Entrust Resources"; - runOnlyForDeploymentPostprocessing = 0; + DC99B86520EACA470065B73B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; }; - 4C50AD0A1410676300EE92DE /* Copy DigiNotar-ok Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "DigiNotar-ok"; - dstSubfolderSpec = 7; - files = ( - 4C50AD23141067A100EE92DE /* DigiNotarCA2007RootCertificate.crt in Copy DigiNotar-ok Resources */, - 4C8B91E41416ED9A00A254E2 /* DigiNotar_Root_CA_G2-RootCertificate.crt in Copy DigiNotar-ok Resources */, - 4C50AD24141067A100EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-ok Resources */, - 4C50AD25141067A100EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-ok Resources */, - 4C50AD26141067A100EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-ok Resources */, - 4C50AD27141067A100EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-ok Resources */, - 4C50AD28141067A100EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-ok Resources */, - 4C50AD29141067A100EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD2A141067A100EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD2B141067A100EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD2C141067A100EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD2D141067A100EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-ok Resources */, - 4C8B91DB1416ED9400A254E2 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-ok Resources */, - 4C8B91E31416ED9400A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-ok Resources */, - 4C50AD30141068C100EE92DE /* Expectations.plist in Copy DigiNotar-ok Resources */, - ); - name = "Copy DigiNotar-ok Resources"; - runOnlyForDeploymentPostprocessing = 0; + DCA232FB209A35840007B57D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = BEAA002A202A832500E51F45; + remoteInfo = TrustedPeersHelper; }; - 4C50AD3414106A2900EE92DE /* Copy DigiNotar Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = DigiNotar; - dstSubfolderSpec = 7; - files = ( - 4C50AD3914106A4E00EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */, - 4C50AD3A14106A4E00EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */, - 4C50AD3B14106A4E00EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */, - 4C50AD3C14106A4E00EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar Resources */, - 4C50AD3D14106A4E00EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar Resources */, - 4C50AD3E14106A4E00EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar Resources */, - 4C50AD3F14106A4E00EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar Resources */, - 4C50AD4014106A4E00EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar Resources */, - 4C50AD4114106A4E00EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar Resources */, - 4C50AD4214106A4E00EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar Resources */, - 4C3CECF41416E2EC00947741 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar Resources */, - 4C3CECF51416E2FA00947741 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar Resources */, - 4C3CECF61416E31A00947741 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar Resources */, - 4C3CECF81416E33500947741 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar Resources */, - 4C3CECF91416E34F00947741 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar Resources */, - 4C3CECFB1416E34F00947741 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar Resources */, - 4C3CECFC1416E34F00947741 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar Resources */, - 4C8B91C81416EBB500A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar Resources */, - ); - name = "Copy DigiNotar Resources"; - runOnlyForDeploymentPostprocessing = 0; + DCB332461F47857D00178C30 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC211D80CFB200B0A59C; + remoteInfo = SOSCommands; }; - 4C50AD3514106A2B00EE92DE /* Copy DigiNotar-Entrust Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "DigiNotar-Entrust"; - dstSubfolderSpec = 7; - files = ( - 4C8B91C61416EB8B00A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4614106A5000EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4714106A5000EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4814106A5000EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4914106A5000EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4A14106A5000EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4B14106A5000EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4C14106A5000EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4D14106A5000EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4E14106A5000EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD4F14106A5000EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C50AD5014106A5000EE92DE /* diginotar.root.ca-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C3CECFD1416E35400947741 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-Entrust Resources */, - 4C3CECFE1416E35400947741 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C3CECFF1416E35400947741 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar-Entrust Resources */, - 4C3CED001416E35400947741 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C3CED011416E35400947741 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar-Entrust Resources */, - 4C3CED031416E35400947741 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar-Entrust Resources */, - 4C3CED041416E35400947741 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar-Entrust Resources */, - ); - name = "Copy DigiNotar-Entrust Resources"; - runOnlyForDeploymentPostprocessing = 0; + DCB340181D8A248C0054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = security_apple_asn1; }; - 4C50AD3614106A2C00EE92DE /* Copy DigiNotar-ok Resources */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "DigiNotar-ok"; - dstSubfolderSpec = 7; - files = ( - 4C50AD5114106A5400EE92DE /* Expectations.plist in Copy DigiNotar-ok Resources */, - 4C50AD5214106A5400EE92DE /* DigiNotarCA2007RootCertificate.crt in Copy DigiNotar-ok Resources */, - 4C3CECF31416E25C00947741 /* DigiNotar_Root_CA_G2-RootCertificate.crt in Copy DigiNotar-ok Resources */, - 4C50AD5314106A5400EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-ok Resources */, - 4C50AD5414106A5400EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-ok Resources */, - 4C50AD5514106A5400EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-ok Resources */, - 4C50AD5614106A5400EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-ok Resources */, - 4C50AD5714106A5400EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-ok Resources */, - 4C50AD5814106A5400EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD5914106A5400EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD5A14106A5400EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD5B14106A5400EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-ok Resources */, - 4C50AD5C14106A5400EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-ok Resources */, - 4C3CED051416E35A00947741 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-ok Resources */, - 4C8B91C71416EBA400A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-ok Resources */, - ); - name = "Copy DigiNotar-ok Resources"; - runOnlyForDeploymentPostprocessing = 0; + DCB340891D8A25230054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB340661D8A24DF0054D16E; + remoteInfo = security_apple_authorization; }; - 4C52D0B216EFC61E0079966E /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /System/Library/LaunchDaemons; - dstSubfolderSpec = 0; - files = ( - 4C52D0E916EFCCF80079966E /* com.apple.security.CircleJoinRequested.plist in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DCB3412D1D8A29830054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB3408E1D8A267C0054D16E; + remoteInfo = security_cdsa_client; }; - 5E11CAD919A759E2008A3664 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/local/bin; - dstSubfolderSpec = 0; - files = ( - 5E11CADA19A75A1F008A3664 /* KeychainItemsAclTest.sh in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 1; + DCB341781D8A2AF10054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB341301D8A2A010054D16E; + remoteInfo = security_cdsa_plugin; }; - 6C1520D31DCCF6F000C85C6D /* Install man8 page */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/share/man/man8; - dstSubfolderSpec = 0; - files = ( - 6C1520D41DCCF71400C85C6D /* secd.8 in Install man8 page */, - ); - name = "Install man8 page"; - runOnlyForDeploymentPostprocessing = 1; + DCB342361D8A2CD70054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB3417B1D8A2B860054D16E; + remoteInfo = security_cdsa_utilities; }; - 6C4F981E2075831300A3C5AB /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 6C4F98252075833E00A3C5AB /* OCMock.framework in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; + DCB345651D8A36060054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB3423A1D8A32820054D16E; + remoteInfo = security_keychain; }; - 6C9AA79C1F7C1D8F00D08296 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; + DCB345B21D8A361F0054D16E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCB343AD1D8A34FD0054D16E; + remoteInfo = security_keychain_regressions; }; - 6CAA8D1E1F842FB3007B6E03 /* Copy Manpage */ = { + DCBF4A8C21FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCBF4A8E21FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; + }; + DCBF4A9021FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; + }; + DCBF4A9221FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + DCBF4A9421FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCBF4A9621FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; + }; + DCBF4A9821FFC82100539F0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; + }; + DCC093771D80ABC300F984E4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = libsecurity; + }; + DCC5D6672087EDB300BBC127 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0EF8EE208697C600AB9E95; + remoteInfo = tpctl; + }; + DCC5D6692087EEE200BBC127 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = BEAA0040202B728B00E51F45; + remoteInfo = Security_executables_Swift; + }; + DCC7A67A216435A40034967D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCC78EA81D8088E200865A7C; + remoteInfo = security; + }; + DCC7A67E216435B30034967D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; + }; + DCC7A681216446D30034967D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCC7A683216446D90034967D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; + }; + DCC7A685216446E50034967D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; + }; + DCC7A687216446EB0034967D /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + DCD067821D8CDF58007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD067561D8CDCF3007602F1; + remoteInfo = codesigning_DTrace; + }; + DCD067841D8CDF5C007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD0675B1D8CDD6D007602F1; + remoteInfo = codesigning_SystemPolicy; + }; + DCD069711D8CE21C007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD0675B1D8CDD6D007602F1; + remoteInfo = codesigning_SystemPolicy; + }; + DCD069731D8CE21C007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD067561D8CDCF3007602F1; + remoteInfo = codesigning_DTrace; + }; + DCD06A441D8CE281007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD0675B1D8CDD6D007602F1; + remoteInfo = codesigning_SystemPolicy; + }; + DCD06A461D8CE281007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD067561D8CDCF3007602F1; + remoteInfo = codesigning_DTrace; + }; + DCD06A7F1D8CE33B007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD067781D8CDF19007602F1; + remoteInfo = security_codesigning; + }; + DCD06A811D8CE33F007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD0696F1D8CE21C007602F1; + remoteInfo = integrity; + }; + DCD06A831D8CE343007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD06A421D8CE281007602F1; + remoteInfo = codehost; + }; + DCD06A851D8CE348007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD069661D8CE105007602F1; + remoteInfo = codesigning_RequirementsLanguage; + }; + DCD06A871D8CE34D007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD06A541D8CE2D5007602F1; + remoteInfo = gkunpack; + }; + DCD06A891D8CE356007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD067781D8CDF19007602F1; + remoteInfo = security_codesigning; + }; + DCD06BCE1D8E0F01007602F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD06AA91D8E0D53007602F1; + remoteInfo = security_utilities; + }; + DCD22D661D8CC387001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC601D80D0C400B0A59C; + remoteInfo = SOSRegressions; + }; + DCD22D681D8CC3A6001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCCF41D8C694700070CB0; + remoteInfo = utilitiesRegressions; + }; + DCD22D7A1D8CCA07001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BC9C81D8B824700070CB0; + remoteInfo = security_ssl; + }; + DCD22D7C1D8CCA18001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1; + }; + DCD22D7E1D8CCA2C001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + DCD22D811D8CCB5A001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E7731D80BC8000B0A59C; + remoteInfo = libsecurityd_ios; + }; + DCD22D831D8CCB72001C9B81 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSync; + }; + DCD66DC21D82056C00DB1393 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD66D5E1D8204A700DB1393; + remoteInfo = libSecTrustOSX; + }; + DCD66DE51D82061F00DB1393 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD66DC41D8205C400DB1393; + remoteInfo = libSecOtrOSX; + }; + DCD6BF5321E919610015F7A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCD6BF5521E9196E0015F7A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCD6BF5721E919820015F7A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCD6BF5921E919A60015F7A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCD6BF5D21E919E10015F7A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCD8A19B1E09EEA200E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1E51E09F81300E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1E81E09F85B00E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1EB1E09F88400E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1EE1E09F8BC00E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1F11E09F8DB00E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1F41E09F91F00E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1FA1E09F99700E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A1FD1E09FA1800E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCD8A2021E09FAE500E4FA0A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + DCDA5E572124B9DC009B11B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC311E6E2124B8A8002F5EAE; + remoteInfo = aks_real_witness; + }; + DCDA5E592124BA2F009B11B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCDA5E5B2124BA54009B11B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCDA5E5D2124BA79009B11B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCDA5E612124BAD7009B11B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCDA5E632124BCA9009B11B2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + DCE0775B21ADD6A0002662FD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF216D621ADD5B10029CCC1; + remoteInfo = protobuf_source_generation; + }; + DCE0777D21ADEADA002662FD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF216D621ADD5B10029CCC1; + remoteInfo = protobuf_source_generation; + }; + DCE0778321ADEDDA002662FD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF216D621ADD5B10029CCC1; + remoteInfo = protobuf_source_generation; + }; + DCE4E8D71D7F37F200AFB96E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCE4E8931D7F34F600AFB96E; + remoteInfo = authd; + }; + DCE5DC161EA804E5006308A6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC211D80CFB200B0A59C; + remoteInfo = SOSCommands; + }; + DCF19A6D21AE2CDC002E808F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DC5AC0AD1D83533400CF422C /* securityd_service.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 189D465A166C15C1001D8533; + remoteInfo = securitydservicectrl; + }; + DCF785001D88B80600E694BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF7830A1D88B4DE00E694BB; + remoteInfo = security_apple_csp; + }; + DCF787311D88C1B000E694BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF785021D88B95500E694BB; + remoteInfo = security_apple_cspdl; + }; + DCF788451D88C98100E694BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF788341D88C8C400E694BB; + remoteInfo = security_apple_filedl; + }; + DCF788A31D88CB6000E694BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF788471D88CA7200E694BB; + remoteInfo = security_apple_x509_cl; + }; + DCF788A81D88CC3500E694BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF788471D88CA7200E694BB; + remoteInfo = security_apple_x509_cl; + }; + DCF789451D88CD7C00E694BB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF788AB1D88CD2400E694BB; + remoteInfo = security_apple_x509_tp; + }; + E058E54A21626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "TriesteKit::CloudDeviceTest::Product"; + remoteInfo = CloudDeviceTest; + }; + E058E54C21626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "TriesteKit::CoreDeviceAutomation::Product"; + remoteInfo = CoreDeviceAutomation; + }; + E058E54E21626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "TriesteKit::CoreDeviceAutomationFrameworkFacade::Product"; + remoteInfo = CoreDeviceAutomationFrameworkFacade; + }; + E058E55021626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "OctagonTestHarnessXPCServiceProtocol::OctagonTestHarnessXPCServiceProtocol::Product"; + remoteInfo = OctagonTestHarnessXPCServiceProtocol; + }; + E058E55221626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "OctagonTrieste::OctagonTrieste::Product"; + remoteInfo = OctagonTrieste; + }; + E058E55421626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "OctagonTrieste::OctagonTriesteTests::Product"; + remoteInfo = OctagonTriesteTests; + }; + E058E55621626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "SwiftHTTP::OpenSSLThreadLock::Product"; + remoteInfo = OpenSSLThreadLock; + }; + E058E55A21626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "SSEClient::SSEClient::Product"; + remoteInfo = SSEClient; + }; + E058E55C21626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "SwiftHTTP::SwiftHTTP::Product"; + remoteInfo = SwiftHTTP; + }; + E058E55E21626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "SwiftLog::SwiftLog::Product"; + remoteInfo = SwiftLog; + }; + E058E56021626583002CA574 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = "TriesteKit::os_activity::Product"; + remoteInfo = os_activity; + }; + E060D1AA212478100025B833 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E060D1A62124780F0025B833; + remoteInfo = OctagonTestHarnessXPCServiceProtocol; + }; + E060D1B9212478120025B833 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E060D1B6212478110025B833; + remoteInfo = OctagonTestHarnessXPCService; + }; + E060D1BB212478120025B833 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E060D1A62124780F0025B833; + remoteInfo = OctagonTestHarnessXPCServiceProtocol; + }; + E74583BD1BF66489001B54A4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 52D82BDD16A621F70078DFE5; + remoteInfo = CloudKeychainProxy; + }; + E745846C1BF68ECB001B54A4 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 05EF68BB194915A5007958C3; + remoteInfo = Security_executables; + }; + E79EEDE61CD4003900C2FBFC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E79EEDD81CD3FFC800C2FBFC; + remoteInfo = Security_frameworks_macos; + }; + EB10557C1E14DFB60003C309 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB1055741E14DF430003C309; + remoteInfo = SecCertificateFuzzer; + }; + EB108F201E6CE4D2003B0456 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + EB1C4CB11E85884300404981 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 470415CE1E5E14B5001F3D95; + remoteInfo = seckeychainnetworkextensionstest; + }; + EB1C4CB31E85884300404981 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47702B1D1E5F409700B29577; + remoteInfo = seckeychainnetworkextensionsystemdaemontest; + }; + EB1C4CB51E85884300404981 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 47702B2D1E5F492C00B29577; + remoteInfo = seckeychainnetworkextensionunauthorizedaccesstest; + }; + EB27FF251E40716D00EC9E3A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB27FF101E402CD300EC9E3A; + remoteInfo = ckksctl; + }; + EB27FF271E40717400EC9E3A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB27FF101E402CD300EC9E3A; + remoteInfo = ckksctl; + }; + EB2ED4E822547DE900E98082 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB27FF101E402CD300EC9E3A; + remoteInfo = ckksctl; + }; + EB31EA821D3EF2FB008F952A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5346480017331E1100FE9172; + remoteInfo = KeychainSyncAccountNotification; + }; + EB3A8E001BEEC6F3001A89AA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB9C1D791BDFD0E000F89272; + remoteInfo = secbackupntest; + }; + EB425CD01C6585F1000ECE53 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB425C9E1C65846D000ECE53; + remoteInfo = secbackuptest; + }; + EB433A2B1CC3252A00A7EACE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB433A201CC3243600A7EACE; + remoteInfo = secitemstresstest; + }; + EB58A05B1E74C517009C10D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E79EEDA71CD3F87B00C2FBFC; + remoteInfo = Security_tests_osx; + }; + EB58A05D1E74C51F009C10D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = E79EEDD21CD3F8AB00C2FBFC; + remoteInfo = Security_tests_ios; + }; + EB58A0611E74C8E4009C10D7 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBB839A41E29665D00853BAC; + remoteInfo = secfuzzer; + }; + EB63ADE01C3E74F900C45A69 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB0BC9361C3C791500785842; + remoteInfo = secedumodetest; + }; + EB694DAE2239E59600F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; + remoteInfo = KeychainEntitledTestRunner; + }; + EB694DC32239E5A200F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6CCDF7831E3C25FA003F2555; + remoteInfo = KeychainEntitledTestRunner; + }; + EB694DC72239E5F200F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5EBE24791B00CCAE0007DB0E; + remoteInfo = secacltests; + }; + EB694DCD223A086C00F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; + }; + EB694DCF223A087700F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 6C46056B1F882B9B001421B6; + remoteInfo = KeychainAnalyticsTests; + }; + EB694E71223AB78E00F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC3502B41E0208BE00BC0587; + remoteInfo = CKKSTests; + }; + EB694E86223AB79400F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC3502B41E0208BE00BC0587; + remoteInfo = CKKSTests; + }; + EB694E88223AB79B00F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC3502B41E0208BE00BC0587; + remoteInfo = CKKSTests; + }; + EB694E8A223AB7A200F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC3502B41E0208BE00BC0587; + remoteInfo = CKKSTests; + }; + EB695280223B75C300F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + EB695284223B75C300F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; + }; + EB695286223B75C300F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D4ADA3181E2B41670031CEA3; + remoteInfo = libtrustd; + }; + EB695288223B75C300F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; + remoteInfo = libSWCAgent; + }; + EB6952BA223B75FC00F02C1C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB69527E223B75C300F02C1C; + remoteInfo = secitemd; + }; + EB6A6FBA1B90F8EC0045DC68 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0C7CFA2E14E1BA4800DF9D95; + remoteInfo = Security_frameworks_ios; + }; + EB6A6FBC1B90F9170045DC68 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 4C32C0AE0A4975F6002891BD; + remoteInfo = Security; + }; + EB74CBD522077CC600F1BBAD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = utilities; + }; + EB74CC222207E99700F1BBAD /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB74CC152207E48000F1BBAD; + remoteInfo = KeychainSettings; + }; + EB89085821F17D3C00F0DDDB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCDA5E4F2124B9C5009B11B2; + remoteInfo = aks_support; + }; + EB89085C21F17D3C00F0DDDB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCC211D8C684F00070CB0; + remoteInfo = iOSutilities; + }; + EB89085E21F17D3C00F0DDDB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = D4ADA3181E2B41670031CEA3; + remoteInfo = libtrustd; + }; + EB89086621F17D3C00F0DDDB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52EC3E1D80D00800B0A59C; + remoteInfo = libSWCAgent; + }; + EB8908A121F17E3B00F0DDDB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EB89085621F17D3C00F0DDDB; + remoteInfo = securityd_nerd; + }; + EBA9AA881CE3E76C004E2B68 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBA9AA7D1CE30E58004E2B68; + remoteInfo = secitemnotifications; + }; + EBB8520F22F793A200424FD0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBB851EB22F7912400424FD0; + remoteInfo = SecurityUtilitiesTests; + }; + EBB8521122F793AC00424FD0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBB851EB22F7912400424FD0; + remoteInfo = SecurityUtilitiesTests; + }; + EBB8521522F793CF00424FD0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBB851EB22F7912400424FD0; + remoteInfo = SecurityUtilitiesTests; + }; + EBB8521722F793EF00424FD0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBB851EB22F7912400424FD0; + remoteInfo = SecurityUtilitiesTests; + }; + EBBC11B22200D3BB00F95738 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCF216D621ADD5B10029CCC1; + remoteInfo = protobuf_source_generation; + }; + EBCF743E1CE593A700BED7CA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBCF73F31CE45F9C00BED7CA; + remoteInfo = secitemfunctionality; + }; + EBD31B3A1E0A186500FBE9FA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BC5631D8B6E3D00070CB0; + remoteInfo = XPCTimeStampingService; + }; + EBD31B411E0A18A600FBE9FA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BC5501D8B6D2D00070CB0; + remoteInfo = XPCKeychainSandboxCheck; + }; + EBD7DF8021FF475B0089F2DF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC52E8BE1D80C25800B0A59C; + remoteInfo = SecureObjectSyncServer; + }; + EBD7DF8221FF475B0089F2DF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DCD8A1061E09EE0F00E4FA0A; + remoteInfo = SecureObjectSyncFramework; + }; + EBF374811DC058B60065D840 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBF374711DC055580065D840; + remoteInfo = "security-sysdiagnose"; + }; + EBF374831DC058C00065D840 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBF374711DC055580065D840; + remoteInfo = "security-sysdiagnose"; + }; + EBF374851DC058C50065D840 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBF374711DC055580065D840; + remoteInfo = "security-sysdiagnose"; + }; + EBF374871DC058CC0065D840 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = EBF374711DC055580065D840; + remoteInfo = "security-sysdiagnose"; + }; + EBFBC2B91E76588A00A34469 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC8834011D8A218F00CE0ACA; + remoteInfo = ASN1_not_installed; + }; + EBFF18CF1F02C2FE004E58FC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BC8981D8B7CBD00070CB0; + remoteInfo = security_filedb; + }; + F667EC641E96EDCF00203D5C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 4C35DB69094F906D002917C4 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DC0BCBD91D8C648C00070CB0; + remoteInfo = regressionBase; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 0C0BDB2D175685B000BC1A7E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 0C85DFFD1FB38BB6000343A7 /* Embed OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 0C85DFFE1FB38BB6000343A7 /* OCMock.framework in Embed OCMock */, + ); + name = "Embed OCMock"; + runOnlyForDeploymentPostprocessing = 0; + }; + 0C8BBF041FCB446400580909 /* Install man1 pages */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + EB1C319D2215ED3500A188BB /* otctl.1 in Install man1 pages */, + ); + name = "Install man1 pages"; + 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; + }; + 3D58394821890FFB000ACA44 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3DD1FFD3201FF72C0086D049 /* Copy Plist */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /AppleInternal/CoreOS/BATS/unit_tests; + dstSubfolderSpec = 0; + files = ( + 3DD1FFD5201FF7860086D049 /* SecureTransport_iosTests.plist in Copy Plist */, + ); + name = "Copy Plist"; + 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; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 4718AE26205B39620068EC3F /* Launchd plists */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + 4718AE27205B39620068EC3F /* com.apple.securityd.plist in Launchd plists */, + ); + name = "Launchd plists"; + runOnlyForDeploymentPostprocessing = 1; + }; + 4718AE28205B39620068EC3F /* Copy Logging Files */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/Preferences/Logging/Subsystems; + dstSubfolderSpec = 0; + files = ( + 4718AE29205B39620068EC3F /* com.apple.securityd.plist in Copy Logging Files */, + ); + name = "Copy Logging Files"; + runOnlyForDeploymentPostprocessing = 1; + }; + 4718AEDC205B39C40068EC3F /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/AWD/Metadata; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 47702B1C1E5F409700B29577 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( - 6CDB600F1FA92D2B00410924 /* securityuploadd.8 in Copy Manpage */, ); - name = "Copy Manpage"; runOnlyForDeploymentPostprocessing = 1; }; - 6CCDF7821E3C25FA003F2555 /* Copy BATS Test Discovery plist */ = { + 47702B2C1E5F492C00B29577 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 4814D8691CAA059E002FFC36 /* Copy Logging Files */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/Preferences/Logging/Subsystems; + dstSubfolderSpec = 0; + files = ( + DC71D8F51D959F150065FB93 /* com.apple.securityd.plist in Copy Logging Files */, + ); + name = "Copy Logging Files"; + runOnlyForDeploymentPostprocessing = 1; + }; + 4C50AD081410673800EE92DE /* Copy DigiNotar Resources */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = DigiNotar; + dstSubfolderSpec = 7; + files = ( + 4C50AD0C1410679000EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */, + 4C50AD0D1410679000EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */, + 4C50AD0E1410679000EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */, + 4C50AD0F1410679000EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar Resources */, + 4C50AD101410679000EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar Resources */, + 4C50AD111410679000EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar Resources */, + 4C50AD121410679000EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar Resources */, + 4C50AD131410679000EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar Resources */, + 4C50AD141410679000EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar Resources */, + 4C50AD151410679000EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar Resources */, + 4C8B91C91416ED7E00A254E2 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar Resources */, + 4C8B91CA1416ED7E00A254E2 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar Resources */, + 4C8B91CB1416ED7E00A254E2 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar Resources */, + 4C8B91CC1416ED7E00A254E2 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar Resources */, + 4C8B91CD1416ED7E00A254E2 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar Resources */, + 4C8B91CF1416ED7E00A254E2 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar Resources */, + 4C8B91D01416ED7E00A254E2 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar Resources */, + 4C8B91D11416ED7E00A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar Resources */, + ); + name = "Copy DigiNotar Resources"; + runOnlyForDeploymentPostprocessing = 0; + }; + 4C50AD091410675400EE92DE /* Copy DigiNotar-Entrust Resources */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "DigiNotar-Entrust"; + dstSubfolderSpec = 7; + files = ( + 4C50AD181410679900EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD191410679900EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD1A1410679900EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD1B1410679900EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD1C1410679900EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD1D1410679900EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD1E1410679900EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD1F1410679900EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD201410679900EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD211410679900EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD221410679900EE92DE /* diginotar.root.ca-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D21416ED8E00A254E2 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D31416ED8E00A254E2 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D41416ED8E00A254E2 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D51416ED8E00A254E2 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D61416ED8E00A254E2 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D81416ED8E00A254E2 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91D91416ED8E00A254E2 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C8B91DA1416ED8E00A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-Entrust Resources */, + ); + name = "Copy DigiNotar-Entrust Resources"; + runOnlyForDeploymentPostprocessing = 0; + }; + 4C50AD0A1410676300EE92DE /* Copy DigiNotar-ok Resources */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "DigiNotar-ok"; + dstSubfolderSpec = 7; + files = ( + 4C50AD23141067A100EE92DE /* DigiNotarCA2007RootCertificate.crt in Copy DigiNotar-ok Resources */, + 4C8B91E41416ED9A00A254E2 /* DigiNotar_Root_CA_G2-RootCertificate.crt in Copy DigiNotar-ok Resources */, + 4C50AD24141067A100EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-ok Resources */, + 4C50AD25141067A100EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-ok Resources */, + 4C50AD26141067A100EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-ok Resources */, + 4C50AD27141067A100EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-ok Resources */, + 4C50AD28141067A100EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-ok Resources */, + 4C50AD29141067A100EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD2A141067A100EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD2B141067A100EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD2C141067A100EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD2D141067A100EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-ok Resources */, + 4C8B91DB1416ED9400A254E2 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-ok Resources */, + 4C8B91E31416ED9400A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-ok Resources */, + 4C50AD30141068C100EE92DE /* Expectations.plist in Copy DigiNotar-ok Resources */, + ); + name = "Copy DigiNotar-ok Resources"; + runOnlyForDeploymentPostprocessing = 0; + }; + 4C50AD3414106A2900EE92DE /* Copy DigiNotar Resources */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = DigiNotar; + dstSubfolderSpec = 7; + files = ( + 4C50AD3914106A4E00EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar Resources */, + 4C50AD3A14106A4E00EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar Resources */, + 4C50AD3B14106A4E00EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar Resources */, + 4C50AD3C14106A4E00EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar Resources */, + 4C50AD3D14106A4E00EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar Resources */, + 4C50AD3E14106A4E00EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar Resources */, + 4C50AD3F14106A4E00EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar Resources */, + 4C50AD4014106A4E00EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar Resources */, + 4C50AD4114106A4E00EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar Resources */, + 4C50AD4214106A4E00EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar Resources */, + 4C3CECF41416E2EC00947741 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar Resources */, + 4C3CECF51416E2FA00947741 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar Resources */, + 4C3CECF61416E31A00947741 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar Resources */, + 4C3CECF81416E33500947741 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar Resources */, + 4C3CECF91416E34F00947741 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar Resources */, + 4C3CECFB1416E34F00947741 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar Resources */, + 4C3CECFC1416E34F00947741 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar Resources */, + 4C8B91C81416EBB500A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar Resources */, + ); + name = "Copy DigiNotar Resources"; + runOnlyForDeploymentPostprocessing = 0; + }; + 4C50AD3514106A2B00EE92DE /* Copy DigiNotar-Entrust Resources */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "DigiNotar-Entrust"; + dstSubfolderSpec = 7; + files = ( + 4C8B91C61416EB8B00A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4614106A5000EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4714106A5000EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4814106A5000EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4914106A5000EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4A14106A5000EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4B14106A5000EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4C14106A5000EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4D14106A5000EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4E14106A5000EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD4F14106A5000EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C50AD5014106A5000EE92DE /* diginotar.root.ca-entrust-secure-server-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C3CECFD1416E35400947741 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-Entrust Resources */, + 4C3CECFE1416E35400947741 /* Invalid-DigiNotar_PKIoverheid_CA_Organisatie_-_G2-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C3CECFF1416E35400947741 /* Invalid-diginotarpkioverheidcaoverheid.crt in Copy DigiNotar-Entrust Resources */, + 4C3CED001416E35400947741 /* Invalid-diginotarpkioverheidcaoverheidenbedrijven-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C3CED011416E35400947741 /* Ministerie_van_Defensie_Certificatie_Autoriteit_G2.crt in Copy DigiNotar-Entrust Resources */, + 4C3CED031416E35400947741 /* staatdernederlandenorganisatieca-g2-Cert.crt in Copy DigiNotar-Entrust Resources */, + 4C3CED041416E35400947741 /* staatdernederlandenoverheidca-Cert.crt in Copy DigiNotar-Entrust Resources */, + ); + name = "Copy DigiNotar-Entrust Resources"; + runOnlyForDeploymentPostprocessing = 0; + }; + 4C50AD3614106A2C00EE92DE /* Copy DigiNotar-ok Resources */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "DigiNotar-ok"; + dstSubfolderSpec = 7; + files = ( + 4C50AD5114106A5400EE92DE /* Expectations.plist in Copy DigiNotar-ok Resources */, + 4C50AD5214106A5400EE92DE /* DigiNotarCA2007RootCertificate.crt in Copy DigiNotar-ok Resources */, + 4C3CECF31416E25C00947741 /* DigiNotar_Root_CA_G2-RootCertificate.crt in Copy DigiNotar-ok Resources */, + 4C50AD5314106A5400EE92DE /* Invalid-asterisk.google.com.crt in Copy DigiNotar-ok Resources */, + 4C50AD5414106A5400EE92DE /* Invalid-muisonline.omnyacc-denhelder.nl-diginotar.cyberca.crt in Copy DigiNotar-ok Resources */, + 4C50AD5514106A5400EE92DE /* Invalid-webmail.terneuzen.nl-diginotar-services.crt in Copy DigiNotar-ok Resources */, + 4C50AD5614106A5400EE92DE /* Invalid-www.maestre.com-diginotal.extended.validation.crt in Copy DigiNotar-ok Resources */, + 4C50AD5714106A5400EE92DE /* Invalid-www.mobilehostingservices.nl-diginotar-services-1024.crt in Copy DigiNotar-ok Resources */, + 4C50AD5814106A5400EE92DE /* diginotar-public-ca-2025-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD5914106A5400EE92DE /* diginotar-services-1024-entrust-secure-server-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD5A14106A5400EE92DE /* diginotar-services-diginotar-root-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD5B14106A5400EE92DE /* diginotar.cyberca-gte.global.root-Cert.crt in Copy DigiNotar-ok Resources */, + 4C50AD5C14106A5400EE92DE /* diginotar.extended.validation-diginotar.root.ca-Cert.crt in Copy DigiNotar-ok Resources */, + 4C3CED051416E35A00947741 /* Invalid-CertiID_Enterprise_Certificate_Authority.crt in Copy DigiNotar-ok Resources */, + 4C8B91C71416EBA400A254E2 /* Invalid-webmail.portofamsterdam.nl.crt in Copy DigiNotar-ok Resources */, + ); + name = "Copy DigiNotar-ok Resources"; + runOnlyForDeploymentPostprocessing = 0; + }; + 4C52D0B216EFC61E0079966E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + 4C52D0E916EFCCF80079966E /* com.apple.security.CircleJoinRequested.plist in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 5E11CAD919A759E2008A3664 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/local/bin; + dstSubfolderSpec = 0; + files = ( + 5E11CADA19A75A1F008A3664 /* KeychainItemsAclTest.sh in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 6C1520D31DCCF6F000C85C6D /* Install man8 page */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man8; + dstSubfolderSpec = 0; + files = ( + 6C1520D41DCCF71400C85C6D /* secd.8 in Install man8 page */, + ); + name = "Install man8 page"; + runOnlyForDeploymentPostprocessing = 1; + }; + 6C23F02E227A39FD009F6756 /* Install Sandbox Profile */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/Sandbox/Profiles; + dstSubfolderSpec = 0; + files = ( + 6C23F02F227A3A28009F6756 /* com.apple.securityd.sb in Install Sandbox Profile */, + ); + name = "Install Sandbox Profile"; + runOnlyForDeploymentPostprocessing = 1; + }; + 6C4F981E2075831300A3C5AB /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 6C4F98252075833E00A3C5AB /* OCMock.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6C7E8F1F21F7BE64008A2D56 /* Copy BATS Test Discovery Plist */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /AppleInternal/CoreOS/BATS/unit_tests; dstSubfolderSpec = 0; files = ( - DC7162D21EB413F2000D2BB5 /* KeychainCKKS.plist in Copy BATS Test Discovery plist */, + 6C02135021F7EF07009D5C80 /* SecDbBackupTests.plist in Copy BATS Test Discovery Plist */, + ); + name = "Copy BATS Test Discovery Plist"; + runOnlyForDeploymentPostprocessing = 1; + }; + 6C9AA79C1F7C1D8F00D08296 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; + 6CAA8D1E1F842FB3007B6E03 /* Copy Manpage */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + 6CDB600F1FA92D2B00410924 /* securityuploadd.8 in Copy Manpage */, ); - name = "Copy BATS Test Discovery plist"; + name = "Copy Manpage"; runOnlyForDeploymentPostprocessing = 1; }; 79679E231462023800CF997F /* Copy DigiCertMalaysia Resources */ = { @@ -9038,16 +10875,39 @@ name = "Copy DigicertMalaysia Resources"; runOnlyForDeploymentPostprocessing = 0; }; - 79863B6C0CADCE4300818B0D /* CopyFiles */ = { + 79863B6C0CADCE4300818B0D /* launchd plist */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; dstPath = /System/Library/LaunchDaemons; dstSubfolderSpec = 0; files = ( - DCE809F31D9342BE00F91177 /* com.apple.securityd.plist in CopyFiles */, + DCE809F31D9342BE00F91177 /* com.apple.securityd.plist in launchd plist */, ); + name = "launchd plist"; runOnlyForDeploymentPostprocessing = 1; }; + AA0DA47C21E818C1009F1C74 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + AA0DA47D21E818D2009F1C74 /* builtins.json in CopyFiles */, + AA0DA47E21E818D2009F1C74 /* example1.json in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + AAE7D3202161CCE50054245E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 12; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + AA0DA47A21E818AB009F1C74 /* builtins.json in CopyFiles */, + AA0DA47B21E818AB009F1C74 /* example1.json in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; BE442BBA18B7FDB800F24DAE /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9069,6 +10929,15 @@ name = "Copy Sandbox"; runOnlyForDeploymentPostprocessing = 1; }; + BECFA42C20F91AFE00B11002 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; CDB9FCAA179CD054000AAD66 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9090,6 +10959,28 @@ name = "Copy LaunchDaemon"; runOnlyForDeploymentPostprocessing = 1; }; + D43718C021168BD400EA350A /* Copy Open Source Version */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/local/OpenSourceVersions; + dstSubfolderSpec = 0; + files = ( + D43718C121168C4300EA350A /* libsecurity_cms.plist in Copy Open Source Version */, + ); + name = "Copy Open Source Version"; + runOnlyForDeploymentPostprocessing = 1; + }; + D43718C221168C5500EA350A /* Copy Open Source Licenses */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/local/OpenSourceLicenses; + dstSubfolderSpec = 0; + files = ( + D43718C321168C6D00EA350A /* libsecurity_cms.txt in Copy Open Source Licenses */, + ); + name = "Copy Open Source Licenses"; + runOnlyForDeploymentPostprocessing = 1; + }; D4ADA3111E2B209C0031CEA3 /* Install man8 page */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9101,6 +10992,17 @@ name = "Install man8 page"; runOnlyForDeploymentPostprocessing = 1; }; + DC05038021409A4F00A8EDB7 /* Embed OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DC05038121409A6100A8EDB7 /* OCMock.framework in Embed OCMock */, + ); + name = "Embed OCMock"; + runOnlyForDeploymentPostprocessing = 1; + }; DC0BC5C41D8B72E700070CB0 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -9119,18 +11021,14 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - DC1789E81D77A0E700B50D50 /* CopyFiles */ = { + DC0EF8ED208697C600AB9E95 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; - dstPath = en.lproj; - dstSubfolderSpec = 7; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; files = ( - D479F6E31F981FD600388D28 /* OID.strings in CopyFiles */, - D479F6E41F981FD600388D28 /* Certificate.strings in CopyFiles */, - D479F6E51F981FD600388D28 /* Trust.strings in CopyFiles */, - DC1789E91D77A0F300B50D50 /* CloudKeychain.strings in CopyFiles */, ); - runOnlyForDeploymentPostprocessing = 0; + runOnlyForDeploymentPostprocessing = 1; }; DC3A4B681D91EB1700E46D4A /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -9152,14 +11050,15 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - DC5AC04E1D8352D900CF422C /* CopyFiles */ = { + DC5AC04E1D8352D900CF422C /* Man pages */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( - DC5AC0C01D83538000CF422C /* securityd.1 in CopyFiles */, + DC5AC0C01D83538000CF422C /* securityd.1 in Man pages */, ); + name = "Man pages"; runOnlyForDeploymentPostprocessing = 1; }; DC610A301D78F129002223DE /* CopyFiles */ = { @@ -9223,6 +11122,17 @@ name = "Copy BATS Test Discovery Plist"; runOnlyForDeploymentPostprocessing = 1; }; + DC7FC44F21EE9175003C39B8 /* Install Security FeatureFlags plist */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/FeatureFlags/Domain; + dstSubfolderSpec = 0; + files = ( + DC7FC45021EE917D003C39B8 /* Security.plist in Install Security FeatureFlags plist */, + ); + name = "Install Security FeatureFlags plist"; + runOnlyForDeploymentPostprocessing = 1; + }; DC963E7D1D95EBA8008A153E /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9529,6 +11439,28 @@ name = "Copy SecureObjectSync Headers"; runOnlyForDeploymentPostprocessing = 0; }; + E060D1D0212478120025B833 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + E060D1A9212478100025B833 /* OctagonTestHarnessXPCServiceProtocol.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + E060D1D1212478120025B833 /* Embed XPC Services */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; + dstSubfolderSpec = 16; + files = ( + E060D1B8212478120025B833 /* OctagonTestHarnessXPCService.xpc in Embed XPC Services */, + ); + name = "Embed XPC Services"; + runOnlyForDeploymentPostprocessing = 0; + }; E73288DD1AED7215008CE839 /* Copy SecureObjectSync Headers */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -9557,6 +11489,17 @@ name = "Install BATS Tests"; runOnlyForDeploymentPostprocessing = 1; }; + EB0F4A2B22F7D3BD009E855B /* Embedd OCMock */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + EB0F4A2C22F7D3DC009E855B /* OCMock.framework in Embedd OCMock */, + ); + name = "Embedd OCMock"; + runOnlyForDeploymentPostprocessing = 0; + }; EB1055801E14DFE40003C309 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9601,6 +11544,17 @@ ); runOnlyForDeploymentPostprocessing = 1; }; + EB6952B4223B75C300F02C1C /* launchd plist */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + EB6952BD223B786800F02C1C /* com.apple.secitemd.plist in launchd plist */, + ); + name = "launchd plist"; + runOnlyForDeploymentPostprocessing = 1; + }; EB76B7581DCB0C8B00C43FBC /* Install man8 page */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9623,6 +11577,17 @@ name = "Install man8 page"; runOnlyForDeploymentPostprocessing = 1; }; + EB89087F21F17D3C00F0DDDB /* launchd plist */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /System/Library/LaunchDaemons; + dstSubfolderSpec = 0; + files = ( + EB7AFAF422323CB6004EF091 /* com.apple.recovery_securityd.plist in launchd plist */, + ); + name = "launchd plist"; + runOnlyForDeploymentPostprocessing = 1; + }; EB9C1DB41BDFD4F200F89272 /* Install BATS plist */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; @@ -9632,6 +11597,7 @@ EB9C1DB51BDFD50100F89272 /* Security.plist in Install BATS plist */, EB3A8DFF1BEEC66F001A89AA /* Security_edumode.plist in Install BATS plist */, EB3D1FBA2092CB030049EF95 /* SecurityInduceLowDisk.plist in Install BATS plist */, + EBDAA7E920EC4838003EA6E5 /* SecurityLocalKeychain.plist in Install BATS plist */, ); name = "Install BATS plist"; runOnlyForDeploymentPostprocessing = 1; @@ -9656,16 +11622,16 @@ name = "Copy Sandbox profile"; runOnlyForDeploymentPostprocessing = 1; }; - EBCE150D1FE63880002E7CCC /* Embedded XPC service */ = { + EBE2026A20908C5600B48020 /* install man8 page */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = "$(CONTENTS_FOLDER_PATH)/XPCServices"; - dstSubfolderSpec = 16; + buildActionMask = 8; + dstPath = /usr/share/man/man8; + dstSubfolderSpec = 0; files = ( - EBCE150E1FE6389A002E7CCC /* DeviceSimulator.xpc in Embedded XPC service */, + EBE2026B20908C7100B48020 /* tpctl.8 in install man8 page */, ); - name = "Embedded XPC service"; - runOnlyForDeploymentPostprocessing = 0; + name = "install man8 page"; + runOnlyForDeploymentPostprocessing = 1; }; EBF374701DC055580065D840 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -9677,22 +11643,34 @@ ); runOnlyForDeploymentPostprocessing = 1; }; - F667EC5C1E96E9B100203D5C /* CopyFiles */ = { + F3384FD12165A025004A2171 /* Install Ariadne Signposts Plist */ = { isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = /usr/share/man/man1/; + buildActionMask = 8; + dstPath = /AppleInternal/Library/Ariadne/Plists; dstSubfolderSpec = 0; files = ( + F3384FD42165A049004A2171 /* SecurityCustomSignposts.plist in Install Ariadne Signposts Plist */, ); + name = "Install Ariadne Signposts Plist"; runOnlyForDeploymentPostprocessing = 1; }; - F93C49061AB8FCE50047E01A /* CopyFiles */ = { + F3384FD52165A071004A2171 /* Install Ariadne Signposts Plist */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 8; - dstPath = /usr/local/sbin; + dstPath = /AppleInternal/Library/Ariadne/Plists; + dstSubfolderSpec = 0; + files = ( + F3384FD62165A08E004A2171 /* SecurityCustomSignposts.plist in Install Ariadne Signposts Plist */, + ); + name = "Install Ariadne Signposts Plist"; + runOnlyForDeploymentPostprocessing = 1; + }; + F667EC5C1E96E9B100203D5C /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; dstSubfolderSpec = 0; files = ( - F93C493B1AB8FF530047E01A /* ckcdiagnose.sh in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 1; }; @@ -9703,86 +11681,174 @@ 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 = ""; }; + 09C3E08B22A83B40004ACFC4 /* securityd.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = securityd.entitlements; 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 = ""; }; + 0C00FC81217A971800C8BF00 /* OTLocalCuttlefishReset.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTLocalCuttlefishReset.m; sourceTree = ""; }; + 0C00FC85217A972E00C8BF00 /* OTLocalCuttlefishReset.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTLocalCuttlefishReset.h; 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 = ""; }; + 0C0C4F83216FB55600C14C61 /* EscrowKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EscrowKeys.swift; sourceTree = ""; }; + 0C0C4F84216FB56B00C14C61 /* BottledPeer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottledPeer.swift; 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 = ""; }; + 0C0F76DD21399AF40074EDDF /* OTPairingMessage.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = OTPairingMessage.proto; sourceTree = ""; }; + 0C101F932053528700387951 /* OTBottledPeerState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeerState.m; sourceTree = ""; }; + 0C101F96205352AF00387951 /* OTBottledPeerState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTBottledPeerState.h; 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 = ""; }; + 0C12B1F02138D31600BE0A98 /* OTClientStateMachine.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTClientStateMachine.m; sourceTree = ""; }; + 0C12B1F52138D32F00BE0A98 /* OTClientStateMachine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTClientStateMachine.h; sourceTree = ""; }; + 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTCloudStoreTests.m; sourceTree = ""; }; + 0C1B8BB3223323710094D5DA /* OTVouchWithRecoveryKeyOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTVouchWithRecoveryKeyOperation.h; sourceTree = ""; }; + 0C1B8BB52233241E0094D5DA /* OTVouchWithRecoveryKeyOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTVouchWithRecoveryKeyOperation.m; sourceTree = ""; }; + 0C24D692204F56E900926E5F /* OTBottledPeerUpdateBottlesTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeerUpdateBottlesTests.m; sourceTree = ""; }; + 0C2A04152152ED7F00FD4FAD /* KCJoiningAcceptSession+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KCJoiningAcceptSession+Internal.h"; sourceTree = ""; }; + 0C2A041A2152EF3000FD4FAD /* KCJoiningRequestSession+Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KCJoiningRequestSession+Internal.h"; 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 = ""; }; 0C2BCBA71D063F7D00ED7A2F /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = ""; }; 0C2BCBB91D06401F00ED7A2F /* dtlsEchoClient */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dtlsEchoClient; sourceTree = BUILT_PRODUCTS_DIR; }; 0C2BCBCE1D0648D100ED7A2F /* dtlsEchoServer */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = dtlsEchoServer; sourceTree = BUILT_PRODUCTS_DIR; }; - 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTPreflightInfo.m; path = ot/OTPreflightInfo.m; sourceTree = ""; }; - 0C36B3202007EE9B0029F7A2 /* OTPreflightInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTPreflightInfo.h; path = ot/OTPreflightInfo.h; sourceTree = ""; }; + 0C2F336A20DD643B0031A92D /* OTClique.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTClique.m; sourceTree = ""; }; + 0C2F337020DD647C0031A92D /* OTRamping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRamping.h; sourceTree = ""; }; + 0C2F337120DD647D0031A92D /* OTRamping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRamping.m; sourceTree = ""; }; + 0C2F337520DD64C10031A92D /* OTCliqueTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTCliqueTests.m; sourceTree = ""; }; + 0C2F337620DD64C20031A92D /* OTTestsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTTestsBase.h; sourceTree = ""; }; + 0C2F337720DD64C20031A92D /* OTTestsBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTTestsBase.m; sourceTree = ""; }; + 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTPreflightInfo.m; sourceTree = ""; }; + 0C36B3202007EE9B0029F7A2 /* OTPreflightInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTPreflightInfo.h; sourceTree = ""; }; + 0C3BB3522188E18A0018FC14 /* OTPrivateKey+SF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OTPrivateKey+SF.m"; path = "keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.m"; sourceTree = SOURCE_ROOT; }; + 0C3BB3542188E18B0018FC14 /* OTAuthenticatedCiphertext+SF.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OTAuthenticatedCiphertext+SF.m"; path = "keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.m"; sourceTree = SOURCE_ROOT; }; + 0C3BB3562188E18B0018FC14 /* OTPrivateKey+SF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OTPrivateKey+SF.h"; path = "keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.h"; sourceTree = SOURCE_ROOT; }; + 0C3BB3572188E18C0018FC14 /* OTAuthenticatedCiphertext+SF.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OTAuthenticatedCiphertext+SF.h"; path = "keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.h"; sourceTree = SOURCE_ROOT; }; 0C3C00721EF3636300AB19FE /* secd-155-otr-negotiation-monitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-155-otr-negotiation-monitor.m"; sourceTree = ""; }; - 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTLockStateNetworkingTests.m; path = ot/tests/OTLockStateNetworkingTests.m; sourceTree = ""; }; + 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTLockStateNetworkingTests.m; sourceTree = ""; }; 0C48990A1E0E0FF300C6CF70 /* SOSTransportCircleCK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSTransportCircleCK.h; sourceTree = ""; }; 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 = ""; }; - 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 = ""; }; + 0C4CDE6D22922E360050C499 /* OctagonTests+RecoveryKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+RecoveryKey.swift"; sourceTree = ""; }; + 0C4F4DDA211535E8007F7E20 /* OTEpochOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTEpochOperation.m; sourceTree = ""; }; + 0C4F4DE121153659007F7E20 /* OTEpochOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTEpochOperation.h; sourceTree = ""; }; + 0C5258B821BB05C100B32C96 /* FakeSOSControl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = FakeSOSControl.m; path = Tests/FakeSOSControl.m; sourceTree = ""; }; + 0C5258BC21BB137800B32C96 /* FakeSOSControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FakeSOSControl.h; path = Tests/FakeSOSControl.h; sourceTree = ""; }; + 0C5824A322860001009E8C15 /* OctagonTests+HealthCheck.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+HealthCheck.swift"; sourceTree = ""; }; + 0C6604692134983900BFBBB8 /* OTEstablishOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTEstablishOperation.m; sourceTree = ""; }; + 0C66046E2134985100BFBBB8 /* OTEstablishOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTEstablishOperation.h; sourceTree = ""; }; + 0C6604782134C86500BFBBB8 /* OTDeviceInformation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTDeviceInformation.h; sourceTree = ""; }; + 0C66047B2134C88C00BFBBB8 /* OTDeviceInformation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTDeviceInformation.m; sourceTree = ""; }; + 0C6604812134DD5D00BFBBB8 /* OctagonPairingTests+ProximitySetup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonPairingTests+ProximitySetup.swift"; 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 = ""; }; + 0C6C2B682258211800C53C96 /* AppleAccount.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppleAccount.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/AppleAccount.framework; sourceTree = DEVELOPER_DIR; }; + 0C6C2B6C2258295D00C53C96 /* UIKitCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKitCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/UIKitCore.framework; sourceTree = DEVELOPER_DIR; }; + 0C75AC642141F18D0073A2F9 /* KeychainCircle.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = KeychainCircle.framework; path = System/Library/PrivateFrameworks/KeychainCircle.framework; sourceTree = SDKROOT; }; + 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = 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; }; - 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 = ""; }; - 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTCloudStore.h; path = ot/OTCloudStore.h; sourceTree = ""; }; - 0C8BBE8A1FC9DA5300580909 /* OTIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTIdentity.h; path = ot/OTIdentity.h; sourceTree = ""; }; - 0C8BBE8B1FC9DA5300580909 /* OTContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTContext.h; path = ot/OTContext.h; sourceTree = ""; }; - 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTLocalStore.m; path = ot/OTLocalStore.m; sourceTree = ""; }; - 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTIdentity.m; path = ot/OTIdentity.m; sourceTree = ""; }; - 0C8BBE8E1FC9DA5500580909 /* OTLocalStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTLocalStore.h; path = ot/OTLocalStore.h; sourceTree = ""; }; - 0C8BBE921FC9DA5700580909 /* OTEscrowKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTEscrowKeys.h; path = ot/OTEscrowKeys.h; sourceTree = ""; }; - 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeer.m; path = ot/OTBottledPeer.m; sourceTree = ""; }; - 0C8BBE951FC9DA5800580909 /* OTBottledPeer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTBottledPeer.h; path = ot/OTBottledPeer.h; sourceTree = ""; }; - 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTEscrowKeys.m; path = ot/OTEscrowKeys.m; sourceTree = ""; }; - 0C8BBE971FC9DA5A00580909 /* OTDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTDefines.h; path = ot/OTDefines.h; sourceTree = ""; }; - 0C8BBE981FC9DA5A00580909 /* OTContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTContext.m; path = ot/OTContext.m; sourceTree = ""; }; - 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTContextTests.m; path = ot/tests/OTContextTests.m; sourceTree = ""; }; + 0C87D3D6229326A2007853B5 /* OTEnsureOctagonKeyConsistency.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTEnsureOctagonKeyConsistency.m; sourceTree = ""; }; + 0C87D3DA229326CB007853B5 /* OTEnsureOctagonKeyConsistency.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTEnsureOctagonKeyConsistency.h; sourceTree = ""; }; + 0C87D3E2229368A7007853B5 /* OctagonTests+SOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+SOS.swift"; sourceTree = ""; }; + 0C89BDA021554DD2003F3CC0 /* OTAccountMetadataClassC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTAccountMetadataClassC.m; sourceTree = ""; }; + 0C89BDA121554DD3003F3CC0 /* OTAccountMetadataClassC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTAccountMetadataClassC.h; sourceTree = ""; }; + 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTEscrowKeyTests.m; sourceTree = ""; }; + 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTLocalStoreTests.m; sourceTree = ""; }; + 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeerTests.m; sourceTree = ""; }; + 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTCloudStore.h; sourceTree = ""; }; + 0C8BBE8A1FC9DA5300580909 /* OTIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTIdentity.h; sourceTree = ""; }; + 0C8BBE8B1FC9DA5300580909 /* OTContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTContext.h; sourceTree = ""; }; + 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTLocalStore.m; sourceTree = ""; }; + 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTIdentity.m; sourceTree = ""; }; + 0C8BBE8E1FC9DA5500580909 /* OTLocalStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTLocalStore.h; sourceTree = ""; }; + 0C8BBE921FC9DA5700580909 /* OTEscrowKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTEscrowKeys.h; sourceTree = ""; }; + 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeer.m; sourceTree = ""; }; + 0C8BBE951FC9DA5800580909 /* OTBottledPeer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottledPeer.h; sourceTree = ""; }; + 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTEscrowKeys.m; sourceTree = ""; }; + 0C8BBE971FC9DA5A00580909 /* OTDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTDefines.h; sourceTree = ""; }; + 0C8BBE981FC9DA5A00580909 /* OTContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTContext.m; sourceTree = ""; }; + 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTContextTests.m; sourceTree = ""; }; 0C8BBEF71FCB405700580909 /* otctl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = otctl.m; sourceTree = ""; }; 0C8BBEF81FCB407700580909 /* otctl-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "otctl-Entitlements.plist"; sourceTree = ""; }; 0C8BBF081FCB446400580909 /* otctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = otctl; sourceTree = BUILT_PRODUCTS_DIR; }; - 0C8BBF0B1FCB452200580909 /* OTControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTControl.h; path = ot/OTControl.h; sourceTree = ""; }; - 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OTControlProtocol.h; path = ot/OTControlProtocol.h; sourceTree = ""; }; - 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTControlProtocol.m; path = ot/OTControlProtocol.m; sourceTree = ""; }; - 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 = ""; }; + 0C8BBF0B1FCB452200580909 /* OTControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTControl.h; sourceTree = ""; }; + 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTControlProtocol.h; sourceTree = ""; }; + 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTControlProtocol.m; sourceTree = ""; }; + 0C8BBF0E1FCB452400580909 /* OTControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTControl.m; sourceTree = ""; }; + 0C8BBF0F1FCB481800580909 /* OTManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTManager.m; sourceTree = ""; }; + 0C8BBF101FCB486B00580909 /* OTManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTManager.h; sourceTree = ""; }; + 0C8FD546214AEC650098E3FB /* OTJoiningConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTJoiningConfiguration.h; sourceTree = ""; }; + 0C8FD549214AECD70098E3FB /* OTJoiningConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTJoiningConfiguration.m; sourceTree = ""; }; + 0C9AE289214054F4003BFDB5 /* OTSponsorToApplicantRound1M2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTSponsorToApplicantRound1M2.h; sourceTree = ""; }; + 0C9AE28A214054F5003BFDB5 /* OTSponsorToApplicantRound2M2.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTSponsorToApplicantRound2M2.h; sourceTree = ""; }; + 0C9AE28B214054F5003BFDB5 /* OTApplicantToSponsorRound2M1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTApplicantToSponsorRound2M1.h; sourceTree = ""; }; + 0C9AE28D214054F6003BFDB5 /* OTSponsorToApplicantRound1M2.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTSponsorToApplicantRound1M2.m; sourceTree = ""; }; + 0C9AE28E214054F6003BFDB5 /* OTApplicantToSponsorRound2M1.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTApplicantToSponsorRound2M1.m; sourceTree = ""; }; + 0C9AE290214054F7003BFDB5 /* OTSponsorToApplicantRound2M2.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTSponsorToApplicantRound2M2.m; sourceTree = ""; }; + 0C9AE2A1214055CE003BFDB5 /* OTPairingMessage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTPairingMessage.h; sourceTree = ""; }; + 0C9AE2A2214055CF003BFDB5 /* OTPairingMessage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTPairingMessage.m; 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 = ""; }; + 0CA702082280D5600085AC54 /* OTCheckHealthOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTCheckHealthOperation.m; sourceTree = ""; }; + 0CA7020B2280D99D0085AC54 /* OTCheckHealthOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTCheckHealthOperation.h; sourceTree = ""; }; 0CAC5DBE1EB3DA4C00AD884B /* SOSPeerRateLimiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSPeerRateLimiter.m; sourceTree = ""; }; 0CAC5DC51EB3DB3C00AD884B /* SOSPeerRateLimiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSPeerRateLimiter.h; sourceTree = ""; }; 0CAD1E221E032D4000537693 /* AggregateDictionary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AggregateDictionary.framework; path = "../../Library/Developer/Xcode/iOS DeviceSupport/11.0 (15A168)/Symbols/System/Library/PrivateFrameworks/AggregateDictionary.framework"; sourceTree = ""; }; + 0CADDF0421545C8E00DF8B06 /* OctagonPairingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OctagonPairingTests.swift; sourceTree = ""; }; 0CB321F01464A95F00587CD3 /* CreateCerts.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = CreateCerts.sh; sourceTree = ""; }; - 0CB975502023B199008D6B48 /* OTRampingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTRampingTests.m; path = ot/tests/OTRampingTests.m; sourceTree = ""; }; - 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerTLK.m; path = ot/tests/OTBottledPeerTLK.m; sourceTree = ""; }; - 0CCCC7C720261D050024405E /* OT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OT.h; path = ot/OT.h; sourceTree = ""; }; - 0CCCC7C820261D310024405E /* OT.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OT.m; path = ot/OT.m; sourceTree = ""; }; + 0CB582BC218915270040C5F2 /* OTPrivateKey.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = OTPrivateKey.proto; sourceTree = ""; }; + 0CB582BD218915270040C5F2 /* OTAuthenticatedCiphertext.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = OTAuthenticatedCiphertext.proto; sourceTree = ""; }; + 0CB582BE218915270040C5F2 /* OTBottle.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = OTBottle.proto; sourceTree = ""; }; + 0CB582BF218915280040C5F2 /* OTBottleContents.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = OTBottleContents.proto; sourceTree = ""; }; + 0CB582C0218915380040C5F2 /* OTAuthenticatedCiphertext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTAuthenticatedCiphertext.h; sourceTree = ""; }; + 0CB582C1218915380040C5F2 /* OTPrivateKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTPrivateKey.h; sourceTree = ""; }; + 0CB582C2218915380040C5F2 /* OTBottleContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottleContents.h; sourceTree = ""; }; + 0CB582C3218915390040C5F2 /* OTPrivateKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPrivateKey.m; sourceTree = ""; }; + 0CB582C4218915390040C5F2 /* OTBottle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottle.m; sourceTree = ""; }; + 0CB582C5218915390040C5F2 /* OTAuthenticatedCiphertext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTAuthenticatedCiphertext.m; sourceTree = ""; }; + 0CB582C62189153A0040C5F2 /* OTBottleContents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottleContents.m; sourceTree = ""; }; + 0CB582C72189153A0040C5F2 /* OTBottle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottle.h; sourceTree = ""; }; + 0CB8DC962194B1300021A7C8 /* OTVouchWithBottleOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTVouchWithBottleOperation.h; sourceTree = ""; }; + 0CB8DC992194B1440021A7C8 /* OTVouchWithBottleOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTVouchWithBottleOperation.m; sourceTree = ""; }; + 0CB975502023B199008D6B48 /* OTRampingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTRampingTests.m; sourceTree = ""; }; + 0CBA047C214C4E4D005B3A2F /* OctagonPairingTests+ProxMultiClients.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonPairingTests+ProxMultiClients.swift"; sourceTree = ""; }; + 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeerTLK.m; sourceTree = ""; }; + 0CBEF3412242C9AE00015691 /* TestsObjcTranslation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestsObjcTranslation.m; sourceTree = ""; }; + 0CBEF3422242C9BE00015691 /* TestsObjcTranslation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestsObjcTranslation.h; sourceTree = ""; }; + 0CC8A8FA2123A9EB005D7F6A /* OTClientVoucherOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTClientVoucherOperation.m; sourceTree = ""; }; + 0CC8A9002123AA3B005D7F6A /* OTClientVoucherOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTClientVoucherOperation.h; sourceTree = ""; }; + 0CC8A9012123AEF7005D7F6A /* OTJoinWithVoucherOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTJoinWithVoucherOperation.m; sourceTree = ""; }; + 0CC8A9052123AF16005D7F6A /* OTJoinWithVoucherOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTJoinWithVoucherOperation.h; sourceTree = ""; }; + 0CCCC7C720261D050024405E /* OT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OT.h; sourceTree = ""; }; + 0CCCC7C820261D310024405E /* OT.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OT.m; sourceTree = ""; }; 0CCDE7161EEB08220021A946 /* secd-156-timers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-156-timers.m"; sourceTree = ""; }; + 0CD3D5152240479600024755 /* OTSetRecoveryKeyOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTSetRecoveryKeyOperation.m; sourceTree = ""; }; + 0CD3D518224047B400024755 /* OTSetRecoveryKeyOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTSetRecoveryKeyOperation.h; sourceTree = ""; }; + 0CD5797721498F7700C43496 /* OctagonPairingTests+Piggybacking.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonPairingTests+Piggybacking.swift"; 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 = ""; }; - 0CE1BCCD1FCE11610017230E /* OTBottledPeerSigned.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTBottledPeerSigned.h; path = ot/OTBottledPeerSigned.h; sourceTree = ""; }; - 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTCloudStoreState.m; path = ot/OTCloudStoreState.m; sourceTree = ""; }; - 0CE407B31FD476E000F59B31 /* OTCloudStoreState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTCloudStoreState.h; path = ot/OTCloudStoreState.h; sourceTree = ""; }; + 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTContextRecord.m; sourceTree = ""; }; + 0CD9E8071FE05B8700F66C38 /* OTContextRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTContextRecord.h; sourceTree = ""; }; + 0CDBCD8620AD03FB007F8EA7 /* OTClique.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTClique.h; sourceTree = ""; }; + 0CDD6F76226E62AD009094C2 /* OTTriggerEscrowUpdateOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTTriggerEscrowUpdateOperation.m; sourceTree = ""; }; + 0CDD6F78226E62BC009094C2 /* OTTriggerEscrowUpdateOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTTriggerEscrowUpdateOperation.h; sourceTree = ""; }; + 0CE15E2A222DF63500B7EAA4 /* RecoveryKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RecoveryKey.swift; path = keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift; sourceTree = SOURCE_ROOT; }; + 0CE15E2A222DF63500B7EAA5 /* SetValueTransformer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SetValueTransformer.swift; path = keychain/TrustedPeersHelper/SetValueTransformer.swift; sourceTree = SOURCE_ROOT; }; + 0CE15E2B222DF63600B7EAA4 /* RecoverKeySet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RecoverKeySet.swift; path = keychain/TrustedPeersHelper/RecoveryKey/RecoverKeySet.swift; sourceTree = SOURCE_ROOT; }; + 0CE15E34222DF66D00B7EAA4 /* OTRecovery.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = OTRecovery.proto; sourceTree = ""; }; + 0CE15E3A222DF6A600B7EAA4 /* OTRecovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTRecovery.m; sourceTree = ""; }; + 0CE15E3B222DF6A700B7EAA4 /* Recovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Recovery.h; sourceTree = ""; }; + 0CE15E3C222DF6A700B7EAA4 /* Recovery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Recovery.m; sourceTree = ""; }; + 0CE15E3D222DF6A700B7EAA4 /* OTRecovery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTRecovery.h; sourceTree = ""; }; + 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeerSigned.m; sourceTree = ""; }; + 0CE1BCCD1FCE11610017230E /* OTBottledPeerSigned.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTBottledPeerSigned.h; sourceTree = ""; }; + 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTCloudStoreState.m; sourceTree = ""; }; + 0CE407B31FD476E000F59B31 /* OTCloudStoreState.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTCloudStoreState.h; sourceTree = ""; }; 0CE760471E12F2F200B4381E /* SOSAccountTrustClassic+Expansion.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SOSAccountTrustClassic+Expansion.m"; path = "SecureObjectSync/SOSAccountTrustClassic+Expansion.m"; sourceTree = ""; }; 0CE760491E12F30200B4381E /* SOSAccountTrustClassic+Circle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SOSAccountTrustClassic+Circle.m"; path = "SecureObjectSync/SOSAccountTrustClassic+Circle.m"; sourceTree = ""; }; 0CE7604B1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "SOSAccountTrustClassic+Identity.m"; path = "SecureObjectSync/SOSAccountTrustClassic+Identity.m"; sourceTree = ""; }; @@ -9792,19 +11858,43 @@ 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; }; + 0CE9C98921B88919006BDD80 /* OTSOSMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTSOSMessage.h; sourceTree = ""; }; + 0CE9C98A21B8891A006BDD80 /* OTSOSMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTSOSMessage.m; 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; }; + 0CF70BD6218BECF500EC3515 /* CuttlefishExtensionWorkaround.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CuttlefishExtensionWorkaround.swift; sourceTree = ""; }; 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 = ""; }; 107227350D91FE89003CF14F /* libbsm.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbsm.dylib; path = usr/lib/libbsm.dylib; sourceTree = SDKROOT; }; 18351B8F14CB65870097860E /* SecBase64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecBase64.h; sourceTree = ""; }; + 1B4C4448223AE65400C6F97F /* TPPBPolicyKeyViewMapping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyKeyViewMapping.h; sourceTree = ""; }; + 1B4C444A223AE65400C6F97F /* TPPBPolicyKeyViewMapping.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyKeyViewMapping.m; sourceTree = ""; }; + 1B5EAAD92252ABCC008D27E7 /* OTFetchViewsOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTFetchViewsOperation.h; sourceTree = ""; }; + 1B5EAADB2252ABCC008D27E7 /* OTFetchViewsOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTFetchViewsOperation.m; sourceTree = ""; }; + 1B8341B72239AD39002BF18A /* TPPBPolicyKeyViewMapping.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyKeyViewMapping.proto; sourceTree = ""; }; + 1B995256226681ED00A2D6CD /* PolicyReporter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PolicyReporter.h; sourceTree = ""; }; + 1B995258226681EE00A2D6CD /* PolicyReporter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PolicyReporter.m; sourceTree = ""; }; + 1BC6F79621C9955D005ED67A /* util.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = util.m; sourceTree = ""; }; + 1BC6F79821C9955E005ED67A /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; + 1BDEBEF72252DEB1009AD3D6 /* policy_dryrun.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = policy_dryrun.m; sourceTree = ""; }; + 1BDEBEFA2252E1DD009AD3D6 /* policy_dryrun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = policy_dryrun.h; sourceTree = ""; }; + 1BF640EE222EEB6C002D0FCB /* TPPolicyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPolicyTests.m; sourceTree = ""; }; + 1F631C5122387F27005920D8 /* legacydevid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = legacydevid.cpp; sourceTree = ""; usesTabs = 0; }; + 1F631C5222387F27005920D8 /* legacydevid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = legacydevid.h; sourceTree = ""; }; + 1FC7E8A02323303700AC3AD0 /* CodeSigningHelper.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeSigningHelper.entitlements; sourceTree = ""; }; 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 = ""; }; + 3D1A57412166931B009C24FD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3D421458216C0A2400D62870 /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = ""; }; + 3D58394D21890FFB000ACA44 /* SecExperimentTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecExperimentTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3D6C25BA216C00D800AB2A71 /* TLSConfig.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = TLSConfig.plist; sourceTree = ""; }; + 3D7AA28E2187AD0000F1575C /* SecExperimentTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecExperimentTests.m; sourceTree = ""; }; + 3DA3384421658AA8008C0CE1 /* SecExperimentPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecExperimentPriv.h; 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 = ""; }; @@ -9830,6 +11920,8 @@ 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; }; + 3DD2589820478CCE00F5DA78 /* STLegacyTests+session.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "STLegacyTests+session.m"; sourceTree = ""; }; + 3DD852B02177FF72009E705D /* SecExperiment.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecExperiment.m; sourceTree = ""; }; 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 = ""; }; @@ -9883,12 +11975,35 @@ 4727FBE41F99217A0003AE36 /* SharedWebCredentials.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SharedWebCredentials.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/SharedWebCredentials.framework; sourceTree = DEVELOPER_DIR; }; 4727FBE61F9921890003AE36 /* ApplePushService.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplePushService.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/System/Library/PrivateFrameworks/ApplePushService.framework; sourceTree = DEVELOPER_DIR; }; 4727FBE81F9921D00003AE36 /* libACM.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libACM.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.Internal.sdk/usr/local/lib/libACM.a; sourceTree = DEVELOPER_DIR; }; + 472E184F20D9A20D00ECE7C9 /* libcoreauthd_client.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcoreauthd_client.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/local/lib/libcoreauthd_client.a; sourceTree = DEVELOPER_DIR; }; 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFKeychainControlManager.h; sourceTree = ""; }; 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFKeychainControlManager.m; sourceTree = ""; }; 473337821FDB29A200E19F30 /* KeychainCheck.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainCheck.h; sourceTree = ""; }; 473337831FDB29A200E19F30 /* KeychainCheck.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainCheck.m; sourceTree = ""; }; 4738AE241E732D7E006BD53D /* SharedWebCredentials.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SharedWebCredentials.framework; path = System/Library/PrivateFrameworks/SharedWebCredentials.framework; sourceTree = SDKROOT; }; 474B5FBF1E662E21007546F8 /* SecurityFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityFoundation.framework; path = ../../Builds/iphoneos11.0.internal/SecurityFoundation.framework; sourceTree = ""; }; + 475EDCD420D98934009D2409 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCDA20D98A28009D2409 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCDC20D98A3C009D2409 /* SecurityFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/SecurityFoundation.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCDE20D98A54009D2409 /* ApplePushService.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplePushService.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/ApplePushService.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCE020D98A5B009D2409 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCE220D98A65009D2409 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/lib/libsqlite3.dylib; sourceTree = DEVELOPER_DIR; }; + 475EDCE420D98A71009D2409 /* ProtocolBuffer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ProtocolBuffer.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/ProtocolBuffer.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCE820D98AA8009D2409 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCEA20D98AAF009D2409 /* WirelessDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WirelessDiagnostics.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/WirelessDiagnostics.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCEC20D98AB7009D2409 /* Accounts.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accounts.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/Accounts.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCEE20D98AC7009D2409 /* SharedWebCredentials.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SharedWebCredentials.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/SharedWebCredentials.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCF320D98B61009D2409 /* libMobileGestalt.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libMobileGestalt.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/lib/libMobileGestalt.dylib; sourceTree = DEVELOPER_DIR; }; + 475EDCF520D98BCF009D2409 /* libACM.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libACM.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/local/lib/libACM.a; sourceTree = DEVELOPER_DIR; }; + 475EDCF720D98BF6009D2409 /* CoreCDP.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreCDP.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/CoreCDP.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCF920D98C0D009D2409 /* CryptoTokenKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoTokenKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/CryptoTokenKit.framework; sourceTree = DEVELOPER_DIR; }; + 475EDCFB20D98C3C009D2409 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/libDER.a; sourceTree = SDKROOT; }; + 475EDCFD20D98C53009D2409 /* libaks.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaks.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/local/lib/libaks.a; sourceTree = DEVELOPER_DIR; }; + 475EDCFF20D98C64009D2409 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; }; + 475EDD0120D98C81009D2409 /* libaks_acl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libaks_acl.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/local/lib/libaks_acl.a; sourceTree = DEVELOPER_DIR; }; + 475EDD0320D98CD0009D2409 /* libctkclient.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libctkclient.a; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/local/lib/libctkclient.a; sourceTree = DEVELOPER_DIR; }; + 475EDD0520D98CE2009D2409 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/LocalAuthentication.framework; sourceTree = DEVELOPER_DIR; }; + 475EDD0720D9A031009D2409 /* LocalAuthenticationPrivateUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthenticationPrivateUI.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/LocalAuthenticationPrivateUI.framework; sourceTree = DEVELOPER_DIR; }; 475F371F1EE8F23900248FB5 /* SFAnalytics.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SFAnalytics.plist; sourceTree = ""; }; 476541631F339F6300413F65 /* SecdWatchdog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecdWatchdog.h; sourceTree = ""; }; 476541641F339F6300413F65 /* SecdWatchdog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecdWatchdog.m; sourceTree = ""; }; @@ -9912,9 +12027,9 @@ 477A1FEB2037A0E000ACD81D /* KeychainXCTest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainXCTest.h; sourceTree = ""; }; 477A1FEC2037A0E000ACD81D /* KeychainXCTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainXCTest.m; sourceTree = ""; }; 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = secdxctests_mac.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CKKSAnalytics.h; path = ckks/CKKSAnalytics.h; sourceTree = ""; }; - 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CKKSAnalytics.m; path = ckks/CKKSAnalytics.m; sourceTree = ""; }; - 47922D171FAA65120008F7E0 /* SecDbKeychainAKSSerializedWrappedKey.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainAKSSerializedWrappedKey.proto; sourceTree = ""; }; + 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSAnalytics.h; sourceTree = ""; }; + 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSAnalytics.m; sourceTree = ""; }; + 47922D171FAA65120008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = SecDbKeychainSerializedAKSWrappedKey.proto; sourceTree = ""; }; 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainSerializedMetadata.proto; sourceTree = ""; }; 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = SecDbKeychainSerializedSecretData.proto; sourceTree = ""; }; 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainSerializedAKSWrappedKey.m; sourceTree = ""; }; @@ -9931,14 +12046,17 @@ 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 = ""; }; + 47C51B861EEA657D0032D9E5 /* SecKeyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecKeyTests.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; }; + 47D1838B1FB3827700CFCD89 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = ../../AppleInternal/Library/Frameworks/OCMock.framework; sourceTree = SDKROOT; }; 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 = ""; }; + 480C03D321459CD60034570E /* SOSTrustedDeviceAttributes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSTrustedDeviceAttributes.m; sourceTree = ""; }; + 480C03D621459CD70034570E /* SOSTrustedDeviceAttributes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSTrustedDeviceAttributes.h; 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 = ""; }; + 482FE56B2177C7AE0031C11E /* AuthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/AuthKit.framework; sourceTree = DEVELOPER_DIR; }; 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 = ""; }; 485B64091DC16E8300B771B9 /* SOSKeyedPubKeyIdentifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSKeyedPubKeyIdentifier.h; sourceTree = ""; }; @@ -9947,7 +12065,6 @@ 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 = ""; }; @@ -9969,8 +12086,8 @@ 4C079EBC1794A96200D73970 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/PrivateFrameworks/ServiceManagement.framework; sourceTree = SDKROOT; }; 4C0B906C0ACCBD240077CD03 /* SecFramework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecFramework.h; sourceTree = ""; }; 4C12828C0BB4957D00985BB0 /* SecTrustSettingsPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustSettingsPriv.h; path = trust/SecTrustSettingsPriv.h; sourceTree = ""; }; - 4C198F1E0ACDB4BF00AAB142 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Certificate.strings; sourceTree = ""; }; - 4C198F200ACDB4BF00AAB142 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/OID.strings; sourceTree = ""; usesTabs = 1; }; + 4C198F1E0ACDB4BF00AAB142 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/Certificate.strings; sourceTree = ""; }; + 4C198F200ACDB4BF00AAB142 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/OID.strings; sourceTree = ""; usesTabs = 1; }; 4C1B442C0BB9CAF900461B82 /* SecTrustStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTrustStore.h; sourceTree = ""; }; 4C28BCD60986EBCB0020C665 /* certextensions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = certextensions.h; path = cssm/certextensions.h; sourceTree = ""; }; 4C2F81D40BF121D2003C4F77 /* SecRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRandom.h; path = base/SecRandom.h; sourceTree = ""; }; @@ -9990,7 +12107,7 @@ 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; name = entitlements.plist; path = SecurityTool/entitlements.plist; sourceTree = SOURCE_ROOT; }; + 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 = ""; }; 4C50ACFC1410671D00EE92DE /* DigiNotarCA2007RootCertificate.crt */ = {isa = PBXFileReference; lastKnownFileType = file; path = DigiNotarCA2007RootCertificate.crt; sourceTree = ""; }; @@ -10080,9 +12197,7 @@ 4CFBF5F10D5A92E100969BBE /* SecPolicyInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPolicyInternal.h; sourceTree = ""; }; 52222CC0167BDAE100EDD09C /* SpringBoardServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SpringBoardServices.framework; path = System/Library/PrivateFrameworks/SpringBoardServices.framework; sourceTree = SDKROOT; }; 522B28081E64B48E002B5638 /* secd-230-keybagtable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-230-keybagtable.m"; sourceTree = ""; }; - 524492931AFD6D480043695A /* der_plist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_plist.h; path = src/der_plist.h; sourceTree = ""; }; - 526965CB1E6E283100627F9D /* AsymKeybagBackup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsymKeybagBackup.h; sourceTree = ""; }; - 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AsymKeybagBackup.m; sourceTree = ""; }; + 524492931AFD6D480043695A /* der_plist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = der_plist.h; sourceTree = ""; }; 52A23EDB161DEC3700E271E0 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "SecurityTests/Default-568h@2x.png"; sourceTree = SOURCE_ROOT; }; 52AA92871E662A4A004301A6 /* SecBackupKeybagEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecBackupKeybagEntry.h; sourceTree = ""; }; 52AA92881E662A4A004301A6 /* SecBackupKeybagEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecBackupKeybagEntry.m; sourceTree = ""; }; @@ -10094,14 +12209,28 @@ 5346480A17331E1200FE9172 /* KeychainSyncAccountNotification-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "KeychainSyncAccountNotification-Prefix.pch"; sourceTree = ""; }; 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 = ""; }; + 53C0E1F2177FAC2C00F8A018 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/CloudKeychain.strings; sourceTree = ""; }; + 5A04BAF622973E43001848A0 /* OTFollowup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTFollowup.h; sourceTree = ""; }; + 5A04BAF722973E43001848A0 /* OTFollowup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTFollowup.m; sourceTree = ""; }; + 5A04BAF922973EA9001848A0 /* OTFollowupTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OTFollowupTests.m; path = keychain/ot/tests/OTFollowupTests.m; sourceTree = SOURCE_ROOT; }; + 5A04BB14229866F7001848A0 /* SecXPCHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecXPCHelper.m; sourceTree = ""; }; + 5A04BB182298670C001848A0 /* SecXPCHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecXPCHelper.h; sourceTree = ""; }; + 5A04BB22229872CB001848A0 /* SecXPCHelperTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecXPCHelperTests.m; sourceTree = ""; }; + 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDate+SFAnalytics.m"; sourceTree = ""; }; + 5A061190229ED60C006AF14A /* NSDate+SFAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDate+SFAnalytics.h"; sourceTree = ""; }; + 5A1A1C2122A71D2A00CB8D1D /* NSDate+SFAnalyticsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDate+SFAnalyticsTests.m"; sourceTree = ""; }; + 5A2551F12229F40800512FAE /* SecExperimentInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecExperimentInternal.h; sourceTree = ""; }; + 5A43A07F225FA38D005450E4 /* SecProtocolHelperTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecProtocolHelperTest.m; path = protocol/SecProtocolHelperTest.m; sourceTree = ""; }; + 5A47FFB1228F5DF700F781B8 /* KCInitialMessageData.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = KCInitialMessageData.proto; sourceTree = ""; }; + 5A47FFB4228F5E9000F781B8 /* KCInitialMessageData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KCInitialMessageData.h; path = generated_source/KCInitialMessageData.h; sourceTree = ""; }; + 5A47FFB5228F5E9000F781B8 /* KCInitialMessageData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KCInitialMessageData.m; path = generated_source/KCInitialMessageData.m; sourceTree = ""; }; + 5A6D1B8D20810EA30057CAC8 /* SecProtocolMetadata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecProtocolMetadata.h; path = protocol/SecProtocolMetadata.h; sourceTree = ""; }; + 5A6D1B9320810EA30057CAC8 /* SecProtocolOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecProtocolOptions.h; path = protocol/SecProtocolOptions.h; sourceTree = ""; }; + 5A6D1B9420810EA40057CAC8 /* SecProtocolTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecProtocolTypes.h; path = protocol/SecProtocolTypes.h; sourceTree = ""; }; + 5A7E037722272C2D003DB3A0 /* SecProtocolHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecProtocolHelper.m; path = protocol/SecProtocolHelper.m; sourceTree = ""; }; + 5AE4BEEE1FA79456001B9DA4 /* SecProtocolObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolObject.h; path = protocol/SecProtocolObject.h; sourceTree = ""; }; + 5AF593FE1FA0EE5300A5C1EC /* SecProtocol.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SecProtocol.c; path = protocol/SecProtocol.c; sourceTree = ""; }; + 5AF594011FA1051500A5C1EC /* SecProtocolPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolPriv.h; path = protocol/SecProtocolPriv.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 = ""; }; @@ -10119,14 +12248,42 @@ 5EAFA4CD1EF16059002DC188 /* LocalAuthentication.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LocalAuthentication.framework; path = System/Library/Frameworks/LocalAuthentication.framework; sourceTree = SDKROOT; }; 5EBE247A1B00CCAE0007DB0E /* secacltests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secacltests; sourceTree = BUILT_PRODUCTS_DIR; }; 5EBE247C1B00CCAE0007DB0E /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; + 5F00F95A230614A200B832E0 /* SecImportExportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecImportExportPriv.h; path = keychain/SecImportExportPriv.h; sourceTree = ""; }; + 5F8494FF22DFB502008B3EFB /* SecTrustExceptionResetCount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecTrustExceptionResetCount.m; path = OSX/sec/securityd/SecTrustExceptionResetCount.m; sourceTree = ""; }; + 617570BA22C2D19E00EFBA37 /* Security.macOS.private.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = Security.macOS.private.modulemap; path = Modules/Security.macOS.private.modulemap; sourceTree = ""; }; + 6C02134C21F7ED16009D5C80 /* SecDbBackupTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = SecDbBackupTests.plist; path = tests/SecDbBackupTests/SecDbBackupTests.plist; sourceTree = SOURCE_ROOT; }; + 6C02134D21F7ED16009D5C80 /* SecDbBackupTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecDbBackupTests.m; path = tests/SecDbBackupTests/SecDbBackupTests.m; sourceTree = SOURCE_ROOT; }; + 6C02134F21F7ED45009D5C80 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; name = Info.plist; path = tests/SecDbBackupTests/Info.plist; sourceTree = SOURCE_ROOT; }; 6C0B0C3D1E2537C6007F95E5 /* WirelessDiagnostics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WirelessDiagnostics.framework; path = System/Library/PrivateFrameworks/WirelessDiagnostics.framework; sourceTree = SDKROOT; }; 6C0B0C441E2537CC007F95E5 /* ProtocolBuffer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ProtocolBuffer.framework; path = System/Library/PrivateFrameworks/ProtocolBuffer.framework; sourceTree = SDKROOT; }; + 6C0C807420EAF81900334E33 /* TPPBPolicyDocument.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyDocument.h; sourceTree = ""; }; + 6C0C807520EAF81900334E33 /* TPPBPolicyDocument.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyDocument.m; sourceTree = ""; }; + 6C0C807D20EAF86100334E33 /* TPPBPolicyDocument.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyDocument.proto; sourceTree = ""; }; + 6C0C807F20EAFB9600334E33 /* TPPBPolicyCategoriesByView.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyCategoriesByView.proto; sourceTree = ""; }; + 6C0C808020EAFB9600334E33 /* TPPBPolicyModelToCategory.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyModelToCategory.proto; sourceTree = ""; }; + 6C0C808320EAFD7A00334E33 /* TPPBPolicyIntroducersByCategory.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyIntroducersByCategory.proto; sourceTree = ""; }; + 6C0C809520EB024800334E33 /* TPPBPolicyIntroducersByCategory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyIntroducersByCategory.m; sourceTree = ""; }; + 6C0C809620EB024800334E33 /* TPPBPolicyCategoriesByView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyCategoriesByView.h; sourceTree = ""; }; + 6C0C809720EB024900334E33 /* TPPBPolicyIntroducersByCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyIntroducersByCategory.h; sourceTree = ""; }; + 6C0C809820EB024900334E33 /* TPPBPolicyModelToCategory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyModelToCategory.h; sourceTree = ""; }; + 6C0C809920EB024900334E33 /* TPPBPolicyModelToCategory.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyModelToCategory.m; sourceTree = ""; }; 6C1260F21F7D5F25001B2EEC /* securityuploadd-osx.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "securityuploadd-osx.plist"; sourceTree = ""; }; 6C1260FA1F7D631D001B2EEC /* securityuploadd-ios.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "securityuploadd-ios.plist"; sourceTree = ""; }; 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 = ""; }; + 6C2008EF220BB4B500674B3A /* Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Entitlements.plist; sourceTree = ""; }; + 6C23F02C227A39E9009F6756 /* com.apple.securityd.sb */ = {isa = PBXFileReference; lastKnownFileType = text; name = com.apple.securityd.sb; path = securityd/etc/com.apple.securityd.sb; sourceTree = SOURCE_ROOT; }; 6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSRateLimiterTests.m; sourceTree = ""; }; + 6C39237921F13E4D00D018AD /* SecDbBackupTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecDbBackupTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6C4605B81F882B9B001421B6 /* KeychainAnalyticsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainAnalyticsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 6C4AEF82218A09210012C5DA /* CheckV12DevEnabled.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CheckV12DevEnabled.h; sourceTree = ""; }; + 6C4AEF83218A09210012C5DA /* CheckV12DevEnabled.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CheckV12DevEnabled.m; sourceTree = ""; }; + 6C4AEF8A218A0A400012C5DA /* SecDbBackupManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbBackupManager.h; sourceTree = ""; }; + 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecDbBackupManager.m; sourceTree = ""; }; + 6C4AEF92218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbKeychainMetadataKeyStore.h; sourceTree = ""; }; + 6C4AEF93218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecDbKeychainMetadataKeyStore.m; sourceTree = ""; }; + 6C4AEF9C218A16F80012C5DA /* SecAKSObjCWrappers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecAKSObjCWrappers.h; sourceTree = ""; }; + 6C4AEF9D218A16F80012C5DA /* SecAKSObjCWrappers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecAKSObjCWrappers.m; sourceTree = ""; }; 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 = ""; }; 6C5B101B1F91613E009B091E /* supdctl-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "supdctl-Entitlements.plist"; sourceTree = ""; }; @@ -10139,6 +12296,10 @@ 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsSQLiteStore.m; sourceTree = ""; }; 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsSQLiteStore.h; sourceTree = ""; }; 6C69518F1F75A8C100F68F91 /* SFAnalyticsDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsDefines.h; sourceTree = ""; }; + 6C70D8D420EB02B700AB6FAF /* TPPBPolicyCategoriesByView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyCategoriesByView.m; sourceTree = ""; }; + 6C70D8D520EBDE4500AB6FAF /* TPPBPolicyRedaction.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyRedaction.proto; sourceTree = ""; }; + 6C70D8DD20EBDFD600AB6FAF /* TPPBPolicyRedaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyRedaction.m; sourceTree = ""; }; + 6C70D8DE20EBDFD700AB6FAF /* TPPBPolicyRedaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyRedaction.h; sourceTree = ""; }; 6C758CB01F8826100075BD78 /* SupdTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SupdTests.m; sourceTree = ""; }; 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; }; @@ -10147,8 +12308,19 @@ 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 = ""; }; + 6C880FBE21C334FB00D38D66 /* SecDbBackupBagIdentity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbBackupBagIdentity.h; sourceTree = ""; }; + 6C880FBF21C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbBackupKeyClassSigningKey.h; sourceTree = ""; }; + 6C880FC021C334FC00D38D66 /* SecDbBackupRecoverySet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbBackupRecoverySet.m; sourceTree = ""; }; + 6C880FC121C334FC00D38D66 /* SecDbBackupMetadataClassKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbBackupMetadataClassKey.m; sourceTree = ""; }; + 6C880FC221C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbBackupKeyClassSigningKey.m; sourceTree = ""; }; + 6C880FC321C334FD00D38D66 /* SecDbBackupBag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbBackupBag.m; sourceTree = ""; }; + 6C880FC421C334FD00D38D66 /* SecDbBackupBag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbBackupBag.h; sourceTree = ""; }; + 6C880FC521C334FD00D38D66 /* SecDbBackupMetadataClassKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbBackupMetadataClassKey.h; sourceTree = ""; }; + 6C880FC621C334FE00D38D66 /* SecDbBackupBagIdentity.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecDbBackupBagIdentity.m; sourceTree = ""; }; + 6C880FC721C334FE00D38D66 /* SecDbBackupRecoverySet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDbBackupRecoverySet.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 = ""; }; + 6C9791C421C17D060074C609 /* SecDbBackupManager_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecDbBackupManager_Internal.h; sourceTree = ""; }; 6C9808611E788AEB00E70590 /* CKKSCloudKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSCloudKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6C98089D1E788AFD00E70590 /* CKKSCloudKitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSCloudKitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6C9AA79E1F7C1D8F00D08296 /* supdctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = supdctl; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -10160,6 +12332,7 @@ 6CB5F4781E402E5700DBF3F0 /* KeychainCKKS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KeychainCKKS.plist; path = testrunner/KeychainCKKS.plist; sourceTree = ""; }; 6CB5F4791E402E5700DBF3F0 /* KeychainEntitledTestRunner-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "KeychainEntitledTestRunner-Entitlements.plist"; sourceTree = ""; }; 6CB5F47A1E402E5700DBF3F0 /* KeychainEntitledTestRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeychainEntitledTestRunner.m; sourceTree = ""; }; + 6CB6CC022198D4BC0080AD6F /* SecDbBackupRecoverySet.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = SecDbBackupRecoverySet.proto; sourceTree = ""; }; 6CB96BB41F966E0C00E11457 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; 6CBF65371FA147E500A68667 /* SFAnalyticsActivityTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFAnalyticsActivityTracker.h; sourceTree = ""; }; 6CBF65381FA147E500A68667 /* SFAnalyticsActivityTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFAnalyticsActivityTracker.m; sourceTree = ""; }; @@ -10184,7 +12357,6 @@ 6CF4A0BC1E45488B00ECD7B5 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 6CF4A0BD1E45488B00ECD7B5 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 6CF4A0BF1E45488B00ECD7B5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 6CF4A0C21E45488B00ECD7B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 6CF4A0C41E45488B00ECD7B5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6CF4A0E01E4549F200ECD7B5 /* KeychainEntitledTestApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KeychainEntitledTestApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6CF4A0E31E4549F200ECD7B5 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; @@ -10192,13 +12364,12 @@ 6CF4A0E61E4549F300ECD7B5 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 6CF4A0E81E4549F300ECD7B5 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 6CF4A0E91E4549F300ECD7B5 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; - 6CF4A0EC1E4549F300ECD7B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 6CF4A0F11E4549F300ECD7B5 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 6CF4A0F31E4549F300ECD7B5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 6CFDC4561F907E1D00646DBB /* libprequelite.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libprequelite.tbd; path = usr/lib/libprequelite.tbd; sourceTree = SDKROOT; }; - 7221843E1EC6782A004C7BED /* sec_action.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sec_action.c; path = src/sec_action.c; sourceTree = ""; }; - 7221843F1EC6782A004C7BED /* sec_action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sec_action.h; path = src/sec_action.h; sourceTree = ""; }; + 7221843E1EC6782A004C7BED /* sec_action.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sec_action.c; sourceTree = ""; }; + 7221843F1EC6782A004C7BED /* sec_action.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sec_action.h; sourceTree = ""; }; + 725D438D212CAA3B007B49E4 /* xcconfig/swift_binary_shim.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = xcconfig/swift_binary_shim.xcconfig; sourceTree = ""; }; 7273402816CAFB3C0096622A /* MobileAsset.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileAsset.framework; path = System/Library/PrivateFrameworks/MobileAsset.framework; sourceTree = SDKROOT; }; 7281E0861DFD015A0021E1B7 /* SOSAccountGetSet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountGetSet.m; sourceTree = ""; }; 7281E08B1DFD0A380021E1B7 /* secd-80-views-alwayson.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-80-views-alwayson.m"; sourceTree = ""; }; @@ -10206,17 +12377,8 @@ 72B368BD179891FC004C37CE /* AggregateDictionary.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AggregateDictionary.framework; path = System/Library/PrivateFrameworks/AggregateDictionary.framework; sourceTree = SDKROOT; }; 72C3EC2D1705F24E0040C87C /* ManagedConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ManagedConfiguration.framework; path = System/Library/PrivateFrameworks/ManagedConfiguration.framework; sourceTree = SDKROOT; }; 72D1E5F3202FE43C003A38C5 /* secdmock_db_version_10_5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = secdmock_db_version_10_5.h; sourceTree = ""; }; + 78ADC6251FA0FAC5001EB8B6 /* SecProtocolTypes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecProtocolTypes.m; path = protocol/SecProtocolTypes.m; sourceTree = ""; }; 78F92F10195128D70023B54B /* SecECKeyPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecECKeyPriv.h; sourceTree = ""; }; - 7901790E12D51F7200CA4D44 /* SecCmsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsBase.h; sourceTree = ""; }; - 7901790F12D51F7200CA4D44 /* SecCmsContentInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsContentInfo.h; sourceTree = ""; }; - 7901791012D51F7200CA4D44 /* SecCmsDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsDecoder.h; sourceTree = ""; }; - 7901791112D51F7200CA4D44 /* SecCmsDigestContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestContext.h; sourceTree = ""; }; - 7901791212D51F7200CA4D44 /* SecCmsEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsEncoder.h; sourceTree = ""; }; - 7901791312D51F7200CA4D44 /* SecCmsEnvelopedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsEnvelopedData.h; sourceTree = ""; }; - 7901791412D51F7200CA4D44 /* SecCmsMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsMessage.h; sourceTree = ""; }; - 7901791512D51F7200CA4D44 /* SecCmsRecipientInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsRecipientInfo.h; sourceTree = ""; }; - 7901791612D51F7200CA4D44 /* SecCmsSignedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsSignedData.h; sourceTree = ""; }; - 7901791712D51F7200CA4D44 /* SecCmsSignerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsSignerInfo.h; sourceTree = ""; }; 7908507F0CA87CF00083CC4D /* client.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = client.c; sourceTree = ""; }; 790850820CA87CF00083CC4D /* securityd_client.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = securityd_client.h; sourceTree = ""; }; 790850840CA87CF00083CC4D /* server.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = server.c; sourceTree = ""; }; @@ -10230,8 +12392,6 @@ 795CA9CC0D38435E00BAE6A2 /* p12pbegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = p12pbegen.h; sourceTree = ""; }; 79679E251462028800CF997F /* Digisign-Server-ID-Enrich-Entrust-Cert.crt */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Digisign-Server-ID-Enrich-Entrust-Cert.crt"; sourceTree = ""; }; 79679E261462028800CF997F /* Invalid-webmail.jaring.my.crt */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Invalid-webmail.jaring.my.crt"; sourceTree = ""; }; - 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libCMS.xcodeproj; path = ../../../libsecurity_smime/libCMS.xcodeproj; sourceTree = ""; }; - 79BDD3C00D60DB84000D84D3 /* SecCMS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCMS.h; sourceTree = ""; }; 79EF5B6C0D3D6A31009F5270 /* SecImportExport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecImportExport.h; path = keychain/SecImportExport.h; sourceTree = ""; }; 79EF5B720D3D6AFE009F5270 /* p12import.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = p12import.h; sourceTree = ""; }; 8E02FA691107BE460043545E /* pbkdf2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pbkdf2.h; sourceTree = ""; }; @@ -10240,16 +12400,22 @@ 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 = ""; }; + AA0DA47821E8189D009F1C74 /* example1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = example1.json; path = protocol/test_data/example1.json; sourceTree = ""; }; + AA0DA47921E8189E009F1C74 /* builtins.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = builtins.json; path = protocol/test_data/builtins.json; sourceTree = ""; }; + AA44E0B3202E3451001EA371 /* SecProtocolTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecProtocolTest.m; path = protocol/SecProtocolTest.m; sourceTree = ""; }; + AA9FD5982152AFC00045A07A /* SecProtocolConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolConfiguration.h; path = protocol/SecProtocolConfiguration.h; sourceTree = ""; }; + AA9FD59B2152AFD70045A07A /* SecProtocolConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecProtocolConfiguration.m; path = protocol/SecProtocolConfiguration.m; sourceTree = ""; }; + AAD66304203362480073E17B /* libnetwork.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libnetwork.tbd; path = usr/lib/libnetwork.tbd; sourceTree = SDKROOT; }; + AADD4A28215E82440054FC6D /* SecProtocolInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolInternal.h; path = protocol/SecProtocolInternal.h; sourceTree = ""; }; + AADD4A2B215E83140054FC6D /* SecProtocolConfigurationTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecProtocolConfigurationTest.m; path = protocol/SecProtocolConfigurationTest.m; sourceTree = ""; }; + AAE91C542162634200B6BF0B /* SecProtocolTypesPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecProtocolTypesPriv.h; path = protocol/SecProtocolTypesPriv.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 = ""; }; ACBAF6FF1E947E860007BA2F /* testlist.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = testlist.h; path = OSX/SecurityTestsOSX/testlist.h; sourceTree = ""; }; B61577EE1F2021BC004A3930 /* padding-00-mmcs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "padding-00-mmcs.c"; sourceTree = ""; }; - B61F67541F1FCFCA00E2FDBB /* SecPaddingConfigurationsPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecPaddingConfigurationsPriv.h; path = src/SecPaddingConfigurationsPriv.h; sourceTree = ""; }; - B61F67551F1FCFCA00E2FDBB /* SecPaddingConfigurations.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SecPaddingConfigurations.c; path = src/SecPaddingConfigurations.c; sourceTree = ""; }; + B61F67541F1FCFCA00E2FDBB /* SecPaddingConfigurationsPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecPaddingConfigurationsPriv.h; sourceTree = ""; }; + B61F67551F1FCFCA00E2FDBB /* SecPaddingConfigurations.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecPaddingConfigurations.c; sourceTree = ""; }; BE061FE01899ECEE00C739F6 /* SecSharedCredential.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecSharedCredential.h; path = ../../../keychain/SecSharedCredential.h; sourceTree = ""; }; BE197F2619116FD100BA91D1 /* SharedWebCredentialViewService.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SharedWebCredentialViewService.app; sourceTree = BUILT_PRODUCTS_DIR; }; BE197F2919116FD100BA91D1 /* SharedWebCredentialViewService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SharedWebCredentialViewService-Info.plist"; sourceTree = ""; }; @@ -10270,38 +12436,86 @@ BE22FBD01EE2084100893431 /* Config.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Config.m; path = manifeststresstest/Config.m; sourceTree = ""; }; BE22FBFC1EE23D9100893431 /* mark.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = mark.m; path = manifeststresstest/mark.m; sourceTree = ""; }; BE22FC031EE23DA600893431 /* mark.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = mark.h; path = manifeststresstest/mark.h; sourceTree = ""; }; - BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTBottledPeerRecord.h; path = ot/OTBottledPeerRecord.h; sourceTree = ""; }; - BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTBottledPeerRecord.m; path = ot/OTBottledPeerRecord.m; sourceTree = ""; }; - BE3405A11FD71CC800933DAC /* OTBottle.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OTBottle.proto; sourceTree = ""; }; - BE3405A31FD71DA400933DAC /* OTBottle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottle.m; sourceTree = ""; }; - BE3405A41FD71DA600933DAC /* OTBottle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottle.h; sourceTree = ""; }; - BE3405A51FD720C900933DAC /* OTBottleContents.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = OTBottleContents.proto; sourceTree = ""; }; - BE3405A61FD7210200933DAC /* OTBottleContents.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTBottleContents.h; sourceTree = ""; }; - BE3405A71FD7210300933DAC /* OTBottleContents.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTBottleContents.m; sourceTree = ""; }; + BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTBottledPeerRecord.h; sourceTree = ""; }; + BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTBottledPeerRecord.m; sourceTree = ""; }; BE442BC118B7FDB800F24DAE /* swcagent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = swcagent; sourceTree = BUILT_PRODUCTS_DIR; }; BE4AC9A118B7FFAD00B84964 /* swcagent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = swcagent.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; BE4AC9AD18B7FFC800B84964 /* com.apple.security.swcagent.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.security.swcagent.plist; sourceTree = ""; }; - BE4AC9B918B8273600B84964 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/SharedWebCredentials.strings; sourceTree = ""; }; + BE4AC9B918B8273600B84964 /* English */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = English; path = en.lproj/SharedWebCredentials.strings; sourceTree = ""; }; + BE4C6AB120CAF4E500EAD6BE /* ContainerSync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerSync.swift; sourceTree = ""; }; + BE53602C209BBF2F0027E25A /* libMobileGestalt.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libMobileGestalt.tbd; path = usr/lib/libMobileGestalt.tbd; sourceTree = SDKROOT; }; + BE55C77A2044D0C80045863D /* TrustedPeersHelper-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TrustedPeersHelper-Bridging-Header.h"; sourceTree = ""; }; + BE55C77B2044D0C90045863D /* Client.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Client.swift; sourceTree = ""; }; + BE55C77D2044D7E60045863D /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; BE6215BD1DB6E69100961E15 /* si-84-sectrust-allowlist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-84-sectrust-allowlist.m"; sourceTree = ""; }; + BE64A7FD22AF0109001209F3 /* trusted_cert_ssl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = trusted_cert_ssl.h; sourceTree = ""; }; + BE64A7FE22AF010A001209F3 /* trusted_cert_ssl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = trusted_cert_ssl.m; sourceTree = ""; }; + BE7089911F9AA027001ACC20 /* TPPBVoucher.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBVoucher.proto; sourceTree = ""; }; + BE70899A1F9AAFF7001ACC20 /* TPPBVoucher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBVoucher.h; sourceTree = ""; }; + BE70899B1F9AAFF7001ACC20 /* TPPBVoucher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBVoucher.m; sourceTree = ""; }; + BE7089CB1FA3B19A001ACC20 /* TPPBPeerDynamicInfo.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPeerDynamicInfo.proto; sourceTree = ""; }; + BE7089CC1FA3B332001ACC20 /* TPPBPeerStableInfo.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPeerStableInfo.proto; sourceTree = ""; }; + BE7089CF1FA3BA01001ACC20 /* TPPBPeerDynamicInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBPeerDynamicInfo.h; sourceTree = ""; }; + BE7089D01FA3BA01001ACC20 /* TPPBPolicySecret.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicySecret.m; sourceTree = ""; }; + BE7089D11FA3BA02001ACC20 /* TPPBPeerStableInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPeerStableInfo.m; sourceTree = ""; }; + BE7089D21FA3BA03001ACC20 /* TPPBPeerDynamicInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPeerDynamicInfo.m; sourceTree = ""; }; + BE7089D31FA3BA03001ACC20 /* TPPBPolicySecret.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBPolicySecret.h; sourceTree = ""; }; + BE7089D41FA3BA04001ACC20 /* TPPBPeerStableInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBPeerStableInfo.h; sourceTree = ""; }; + BE7089D91FA3F0AF001ACC20 /* TPPBPolicySecret.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicySecret.proto; sourceTree = ""; }; + BE7089DB1FA407E4001ACC20 /* TPPBPeerPermanentInfo.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPeerPermanentInfo.proto; sourceTree = ""; }; + BE7089DD1FA40B93001ACC20 /* TPPBPeerPermanentInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBPeerPermanentInfo.h; sourceTree = ""; }; + BE7089DE1FA40B95001ACC20 /* TPPBPeerPermanentInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBPeerPermanentInfo.m; sourceTree = ""; }; + BE72782A209D27C800F0DA77 /* TPKeyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPKeyTests.m; sourceTree = ""; }; BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = framework_requiring_modern_objc_runtime.xcconfig; path = xcconfig/framework_requiring_modern_objc_runtime.xcconfig; sourceTree = ""; }; BE8ABDD71DC2DD9100EC2D58 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; - BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = OTPrivateKey.proto; sourceTree = ""; }; - BEB0B0D41FFC3D32007E6A83 /* OTPrivateKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPrivateKey.m; sourceTree = ""; }; - BEB0B0D51FFC3D33007E6A83 /* OTPrivateKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTPrivateKey.h; sourceTree = ""; }; - BEB0B0D91FFC45C2007E6A83 /* OTPrivateKey+SF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "OTPrivateKey+SF.h"; path = "ot/OTPrivateKey+SF.h"; sourceTree = ""; }; - BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "OTPrivateKey+SF.m"; path = "ot/OTPrivateKey+SF.m"; sourceTree = ""; }; - BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "si-88-sectrust-valid.m"; path = "OSX/shared_regressions/si-88-sectrust-valid.m"; sourceTree = SOURCE_ROOT; }; - BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "si-88-sectrust-valid-data"; sourceTree = ""; }; + BE92249D204F203C0052E828 /* TrustedPeersHelper.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TrustedPeersHelper.xcdatamodel; sourceTree = ""; }; + BE9B8B43202BB42C0081EF87 /* si-88-sectrust-valid-data */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "si-88-sectrust-valid-data"; sourceTree = ""; }; + BE9B8B49202BB4A10081EF87 /* si-88-sectrust-valid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "si-88-sectrust-valid.m"; path = "OSX/shared_regressions/si-88-sectrust-valid.m"; sourceTree = SOURCE_ROOT; }; + BE9F4F8B2072D881004A52C2 /* Cuttlefish.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cuttlefish.pb.swift; sourceTree = ""; }; + BE9F8D0F206C099800B53D16 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; + BE9F8D11206C121400B53D16 /* Decrypter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Decrypter.swift; sourceTree = ""; }; + BE9F8D18206C4AD300B53D16 /* ContainerMap.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainerMap.swift; sourceTree = ""; }; + BEA8557F20B5DC7D00D5AD11 /* FakeCuttlefish.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeCuttlefish.swift; sourceTree = ""; }; + BEAA002B202A832500E51F45 /* TrustedPeersHelper.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = TrustedPeersHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; + BEAA002D202A832500E51F45 /* TrustedPeersHelperProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TrustedPeersHelperProtocol.h; sourceTree = ""; }; + BEAA0033202A832500E51F45 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BEB49F29206E98CD008DA7F4 /* TPECPublicKeyFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPECPublicKeyFactory.h; sourceTree = ""; }; + BEB49F2F206E98CE008DA7F4 /* TPECPublicKeyFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPECPublicKeyFactory.m; sourceTree = ""; }; + BEB49F32206E9A18008DA7F4 /* SFKey+TPKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SFKey+TPKey.h"; sourceTree = ""; }; + BEB49F33206E9A19008DA7F4 /* SFKey+TPKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SFKey+TPKey.m"; sourceTree = ""; }; + BEB49F36206E9B89008DA7F4 /* TPECPublicKeyFactoryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPECPublicKeyFactoryTests.m; sourceTree = ""; }; + BEC0A94920AB618700DBD772 /* Cuttlefish.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Cuttlefish.proto; path = keychain/trust/cuttlefish/API/Cuttlefish.proto; sourceTree = SOURCE_ROOT; }; + BEC0A96320B362EC00DBD772 /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = ""; }; + BEC3739B20CF2AA200DBDF5B /* TPPBDisposition.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBDisposition.proto; sourceTree = ""; }; + BEC373A220CF3B5C00DBDF5B /* TPPBDisposition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBDisposition.h; sourceTree = ""; }; + BEC373A320CF3B5C00DBDF5B /* TPPBDisposition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBDisposition.m; sourceTree = ""; }; + BEC373A620D810D800DBDF5B /* TPPBPolicyProhibits.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBPolicyProhibits.proto; sourceTree = ""; }; + BEC373A720D810D900DBDF5B /* TPPBUnknownMachineID.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBUnknownMachineID.proto; sourceTree = ""; }; + BEC373A820D810DA00DBDF5B /* TPPBAncientEpoch.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBAncientEpoch.proto; sourceTree = ""; }; + BEC373AC20D815E000DBDF5B /* TPPBUnknownMachineID.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBUnknownMachineID.m; sourceTree = ""; }; + BEC373AD20D815E100DBDF5B /* TPPBAncientEpoch.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBAncientEpoch.m; sourceTree = ""; }; + BEC373AE20D815E200DBDF5B /* TPPBPolicyProhibits.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBPolicyProhibits.m; sourceTree = ""; }; + BEC373AF20D815E200DBDF5B /* TPPBAncientEpoch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBAncientEpoch.h; sourceTree = ""; }; + BEC373B020D815E300DBDF5B /* TPPBPolicyProhibits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBPolicyProhibits.h; sourceTree = ""; }; + BEC373B120D815E400DBDF5B /* TPPBUnknownMachineID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBUnknownMachineID.h; sourceTree = ""; }; + BEC373C120D8224A00DBDF5B /* TPPBDispositionEntry.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.protobuf; path = TPPBDispositionEntry.proto; sourceTree = ""; }; + BEC373C920D822CD00DBDF5B /* TPPBDispositionEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPPBDispositionEntry.m; sourceTree = ""; }; + BEC373CA20D822CE00DBDF5B /* TPPBDispositionEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPPBDispositionEntry.h; sourceTree = ""; }; + BECEC0FD20A3B94C00E97255 /* TrustedPeersHelperUnitTests-BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TrustedPeersHelperUnitTests-BridgingHeader.h"; sourceTree = ""; }; + BECEC11020A508F600E97255 /* TPVoucher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPVoucher.h; sourceTree = ""; }; + BECEC11120A508F600E97255 /* TPVoucher.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPVoucher.m; sourceTree = ""; }; + BECFA42E20F91AFE00B11002 /* tppolicy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tppolicy; sourceTree = BUILT_PRODUCTS_DIR; }; + BECFA43020F91AFE00B11002 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + BECFA43C20F9493000B11002 /* Policy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Policy.swift; sourceTree = ""; }; + BECFA46320FFB87400B11002 /* TPKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPKey.m; sourceTree = ""; }; + BED01530206F050F0027A2B4 /* README.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = README.txt; path = trust/README.txt; sourceTree = ""; }; BED208DD1EDF950E00753952 /* manifeststresstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = manifeststresstest; sourceTree = BUILT_PRODUCTS_DIR; }; BED208E61EDF971600753952 /* manifeststresstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = manifeststresstest.entitlements; path = manifeststresstest/manifeststresstest.entitlements; sourceTree = ""; }; BED208E71EDF971600753952 /* manifeststresstest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = manifeststresstest.m; path = manifeststresstest/manifeststresstest.m; sourceTree = ""; }; - BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = OTAuthenticatedCiphertext.proto; sourceTree = ""; }; - BEE4B18E1FFD5F9000777D39 /* OTAuthenticatedCiphertext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTAuthenticatedCiphertext.h; sourceTree = ""; }; - BEE4B18F1FFD5F9100777D39 /* OTAuthenticatedCiphertext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTAuthenticatedCiphertext.m; sourceTree = ""; }; - BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "OTAuthenticatedCiphertext+SF.h"; path = "ot/OTAuthenticatedCiphertext+SF.h"; sourceTree = ""; }; - BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "OTAuthenticatedCiphertext+SF.m"; path = "ot/OTAuthenticatedCiphertext+SF.m"; sourceTree = ""; }; - BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "SFPublicKey+SPKI.h"; path = "ot/SFPublicKey+SPKI.h"; sourceTree = ""; }; - BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "SFECPublicKey+SPKI.m"; path = "ot/SFECPublicKey+SPKI.m"; sourceTree = ""; }; + BED987D32099145300607A5F /* TrustedPeersHelperUnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrustedPeersHelperUnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + BED987D52099145300607A5F /* TrustedPeersHelperUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedPeersHelperUnitTests.swift; sourceTree = ""; }; + BED987D72099145300607A5F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BED987E220991C4D00607A5F /* MockCuttlefish.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockCuttlefish.swift; sourceTree = ""; }; BEEB47D71EA189F5004AA5C6 /* SecTrustStatusCodes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTrustStatusCodes.c; sourceTree = ""; }; BEEB47D81EA189F5004AA5C6 /* SecTrustStatusCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTrustStatusCodes.h; sourceTree = ""; }; BEF88C281EAFFC3F00357577 /* TrustedPeers.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TrustedPeers.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -10309,8 +12523,6 @@ BEF88C471EB0005E00357577 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = keychain/trust/TrustedPeers/Info.plist; sourceTree = SOURCE_ROOT; }; BEF88C481EB0005E00357577 /* TPCategoryRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPCategoryRule.h; path = keychain/trust/TrustedPeers/TPCategoryRule.h; sourceTree = SOURCE_ROOT; }; BEF88C491EB0005E00357577 /* TPCategoryRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPCategoryRule.m; path = keychain/trust/TrustedPeers/TPCategoryRule.m; sourceTree = SOURCE_ROOT; }; - BEF88C4A1EB0005E00357577 /* TPCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPCircle.h; path = keychain/trust/TrustedPeers/TPCircle.h; sourceTree = SOURCE_ROOT; }; - BEF88C4B1EB0005E00357577 /* TPCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPCircle.m; path = keychain/trust/TrustedPeers/TPCircle.m; sourceTree = SOURCE_ROOT; }; BEF88C4C1EB0005E00357577 /* TPDecrypter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPDecrypter.h; path = keychain/trust/TrustedPeers/TPDecrypter.h; sourceTree = SOURCE_ROOT; }; BEF88C4D1EB0005E00357577 /* TPEncrypter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPEncrypter.h; path = keychain/trust/TrustedPeers/TPEncrypter.h; sourceTree = SOURCE_ROOT; }; BEF88C4E1EB0005E00357577 /* TPHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPHash.h; path = keychain/trust/TrustedPeers/TPHash.h; sourceTree = SOURCE_ROOT; }; @@ -10329,15 +12541,10 @@ BEF88C5B1EB0005E00357577 /* TPPolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPPolicy.m; path = keychain/trust/TrustedPeers/TPPolicy.m; sourceTree = SOURCE_ROOT; }; BEF88C5C1EB0005E00357577 /* TPPolicyDocument.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPPolicyDocument.h; path = keychain/trust/TrustedPeers/TPPolicyDocument.h; sourceTree = SOURCE_ROOT; }; BEF88C5D1EB0005E00357577 /* TPPolicyDocument.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPPolicyDocument.m; path = keychain/trust/TrustedPeers/TPPolicyDocument.m; sourceTree = SOURCE_ROOT; }; - BEF88C5E1EB0005E00357577 /* TPSigningKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPSigningKey.h; path = keychain/trust/TrustedPeers/TPSigningKey.h; sourceTree = SOURCE_ROOT; }; + BEF88C5E1EB0005E00357577 /* TPKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPKey.h; path = keychain/trust/TrustedPeers/TPKey.h; sourceTree = SOURCE_ROOT; }; BEF88C5F1EB0005E00357577 /* TPTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPTypes.h; path = keychain/trust/TrustedPeers/TPTypes.h; sourceTree = SOURCE_ROOT; }; - BEF88C601EB0005E00357577 /* TPUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPUtils.h; path = keychain/trust/TrustedPeers/TPUtils.h; sourceTree = SOURCE_ROOT; }; - BEF88C611EB0005E00357577 /* TPUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPUtils.m; path = keychain/trust/TrustedPeers/TPUtils.m; sourceTree = SOURCE_ROOT; }; - BEF88C621EB0005E00357577 /* TPVoucher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPVoucher.h; path = keychain/trust/TrustedPeers/TPVoucher.h; sourceTree = SOURCE_ROOT; }; - BEF88C631EB0005F00357577 /* TPVoucher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPVoucher.m; path = keychain/trust/TrustedPeers/TPVoucher.m; sourceTree = SOURCE_ROOT; }; BEF88C641EB0005F00357577 /* TrustedPeers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrustedPeers.h; path = keychain/trust/TrustedPeers/TrustedPeers.h; sourceTree = SOURCE_ROOT; }; BEF88C661EB0008E00357577 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = keychain/trust/TrustedPeersTests/Info.plist; sourceTree = SOURCE_ROOT; }; - BEF88C671EB0008E00357577 /* TPCircleTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPCircleTests.m; path = keychain/trust/TrustedPeersTests/TPCircleTests.m; sourceTree = SOURCE_ROOT; }; BEF88C681EB0008E00357577 /* TPDummyDecrypter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPDummyDecrypter.h; path = keychain/trust/TrustedPeersTests/TPDummyDecrypter.h; sourceTree = SOURCE_ROOT; }; BEF88C691EB0008E00357577 /* TPDummyDecrypter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPDummyDecrypter.m; path = keychain/trust/TrustedPeersTests/TPDummyDecrypter.m; sourceTree = SOURCE_ROOT; }; BEF88C6A1EB0008E00357577 /* TPDummyEncrypter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TPDummyEncrypter.h; path = keychain/trust/TrustedPeersTests/TPDummyEncrypter.h; sourceTree = SOURCE_ROOT; }; @@ -10351,8 +12558,6 @@ BEF88C721EB0008E00357577 /* TPPeerStableInfoTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPPeerStableInfoTests.m; path = keychain/trust/TrustedPeersTests/TPPeerStableInfoTests.m; sourceTree = SOURCE_ROOT; }; BEF88C731EB0008E00357577 /* TPPeerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TPPeerTests.m; path = keychain/trust/TrustedPeersTests/TPPeerTests.m; sourceTree = SOURCE_ROOT; }; 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; }; 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 = ""; }; @@ -10361,6 +12566,10 @@ 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; }; CDB9FCA9179CC757000AAD66 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CDDE9BC31729AB910013B0E8 /* SecPasswordGenerate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecPasswordGenerate.h; sourceTree = ""; }; + D4056A1922712A650026E24E /* SSLPolicyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SSLPolicyTests.m; path = tests/TrustTests/EvaluationTests/SSLPolicyTests.m; sourceTree = ""; }; + D4056A1C22712AD80026E24E /* SSLPolicyTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SSLPolicyTests_data.h; path = tests/TrustTests/EvaluationTests/SSLPolicyTests_data.h; sourceTree = ""; }; + D4056A1D22712D740026E24E /* ssl-policy-certs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ssl-policy-certs"; path = "SecurityTests/ssl-policy-certs"; sourceTree = ""; }; + D4056A1E22712D750026E24E /* si-87-sectrust-name-constraints */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-87-sectrust-name-constraints"; path = "SecurityTests/si-87-sectrust-name-constraints"; sourceTree = ""; }; D40B6A871E2B5F9900CD6EE5 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; }; D40B6A881E2B5F9900CD6EE5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; D41149A01E7C935D00C078C7 /* AppleiPhoneDeviceCACertificates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppleiPhoneDeviceCACertificates.h; sourceTree = ""; }; @@ -10373,6 +12582,66 @@ D41257ED1E941D5B00781F23 /* SecTrustOSXEntryPoints.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrustOSXEntryPoints.h; path = OSX/trustd/macOS/SecTrustOSXEntryPoints.h; sourceTree = SOURCE_ROOT; }; D41257EE1E941DA800781F23 /* com.apple.trustd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = com.apple.trustd.plist; path = OSX/trustd/iOS/com.apple.trustd.plist; sourceTree = ""; }; D41D36701EB14D87007FA978 /* libDiagnosticMessagesClient.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libDiagnosticMessagesClient.tbd; path = usr/lib/libDiagnosticMessagesClient.tbd; sourceTree = SDKROOT; }; + D42C838721158B3F008D3D83 /* cmsreclist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cmsreclist.h; path = libsecurity_smime/lib/cmsreclist.h; sourceTree = SOURCE_ROOT; }; + D42C838821158B40008D3D83 /* SecAsn1Item.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecAsn1Item.c; path = libsecurity_smime/lib/SecAsn1Item.c; sourceTree = SOURCE_ROOT; }; + D42C8390211590BC008D3D83 /* CMSDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CMSDecoder.cpp; path = OSX/libsecurity_cms/lib/CMSDecoder.cpp; sourceTree = ""; }; + D42C8391211590D6008D3D83 /* CMSUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSUtils.h; path = OSX/libsecurity_cms/lib/CMSUtils.h; sourceTree = ""; }; + D42C8392211590D7008D3D83 /* CMSUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CMSUtils.cpp; path = OSX/libsecurity_cms/lib/CMSUtils.cpp; sourceTree = ""; }; + D42C8393211590D7008D3D83 /* CMSEncoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CMSEncoder.cpp; path = OSX/libsecurity_cms/lib/CMSEncoder.cpp; sourceTree = ""; }; + D42C839821159146008D3D83 /* libsecurity_cms.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_cms.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D42C83A121159568008D3D83 /* cms_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cms_regressions.h; path = OSX/libsecurity_cms/regressions/cms_regressions.h; sourceTree = ""; }; + D42C83A221159569008D3D83 /* cms-trust-settings-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "cms-trust-settings-test.c"; path = "OSX/libsecurity_cms/regressions/cms-trust-settings-test.c"; sourceTree = ""; }; + D42C83A321159569008D3D83 /* cms-trust-settings-test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "cms-trust-settings-test.h"; path = "OSX/libsecurity_cms/regressions/cms-trust-settings-test.h"; sourceTree = ""; }; + D42C83A621163866008D3D83 /* cert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cert.h; path = libsecurity_smime/lib/cert.h; sourceTree = SOURCE_ROOT; }; + D437185C211671A300EA350A /* cms-01-basic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "cms-01-basic.c"; path = "OSX/libsecurity_smime/regressions/cms-01-basic.c"; sourceTree = ""; }; + D437185D211671A400EA350A /* smime-cms-test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "smime-cms-test.c"; path = "OSX/libsecurity_smime/regressions/smime-cms-test.c"; sourceTree = ""; }; + D437185E211671A400EA350A /* cms-01-basic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "cms-01-basic.h"; path = "OSX/libsecurity_smime/regressions/cms-01-basic.h"; sourceTree = ""; }; + D4371862211682D500EA350A /* cmscipher.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmscipher.c; path = OSX/libsecurity_smime/lib/cmscipher.c; sourceTree = ""; }; + D4371863211682D500EA350A /* cmsarray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsarray.c; path = OSX/libsecurity_smime/lib/cmsarray.c; sourceTree = ""; }; + D4371864211682D600EA350A /* cmsattr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsattr.c; path = OSX/libsecurity_smime/lib/cmsattr.c; sourceTree = ""; }; + D4371865211682D600EA350A /* cmsasn1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsasn1.c; path = OSX/libsecurity_smime/lib/cmsasn1.c; sourceTree = ""; }; + D4371866211682D600EA350A /* cmscinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmscinfo.c; path = OSX/libsecurity_smime/lib/cmscinfo.c; sourceTree = ""; }; + D4371867211682D700EA350A /* cert.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cert.c; path = OSX/libsecurity_smime/lib/cert.c; sourceTree = ""; }; + D4371868211682D700EA350A /* cert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cert.h; path = OSX/libsecurity_smime/lib/cert.h; sourceTree = ""; }; + D43718702116831600EA350A /* cmsdigest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsdigest.c; path = OSX/libsecurity_smime/lib/cmsdigest.c; sourceTree = ""; }; + D43718712116831600EA350A /* cmsenvdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsenvdata.c; path = OSX/libsecurity_smime/lib/cmsenvdata.c; sourceTree = ""; }; + D43718722116831700EA350A /* cmsdecode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsdecode.c; path = OSX/libsecurity_smime/lib/cmsdecode.c; sourceTree = ""; }; + D43718732116831700EA350A /* cmsmessage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsmessage.c; path = OSX/libsecurity_smime/lib/cmsmessage.c; sourceTree = ""; }; + D43718742116831800EA350A /* cmsencode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsencode.c; path = OSX/libsecurity_smime/lib/cmsencode.c; sourceTree = ""; }; + D43718752116831900EA350A /* cmsencdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsencdata.c; path = OSX/libsecurity_smime/lib/cmsencdata.c; sourceTree = ""; }; + D43718762116831900EA350A /* cmslocal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cmslocal.h; path = OSX/libsecurity_smime/lib/cmslocal.h; sourceTree = ""; }; + D43718772116831A00EA350A /* cmsdigdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsdigdata.c; path = OSX/libsecurity_smime/lib/cmsdigdata.c; sourceTree = ""; }; + D43718802116834000EA350A /* cmsreclist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsreclist.c; path = OSX/libsecurity_smime/lib/cmsreclist.c; sourceTree = ""; }; + D43718812116834000EA350A /* cmsreclist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cmsreclist.h; path = OSX/libsecurity_smime/lib/cmsreclist.h; sourceTree = ""; }; + D43718822116834100EA350A /* cmspriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cmspriv.h; path = OSX/libsecurity_smime/lib/cmspriv.h; sourceTree = ""; }; + D43718832116834100EA350A /* cmssiginfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmssiginfo.c; path = OSX/libsecurity_smime/lib/cmssiginfo.c; sourceTree = ""; }; + D43718842116834200EA350A /* cmssigdata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmssigdata.c; path = OSX/libsecurity_smime/lib/cmssigdata.c; sourceTree = ""; }; + D43718852116834300EA350A /* cmstpriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cmstpriv.h; path = OSX/libsecurity_smime/lib/cmstpriv.h; sourceTree = ""; }; + D43718862116834300EA350A /* cmsrecinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsrecinfo.c; path = OSX/libsecurity_smime/lib/cmsrecinfo.c; sourceTree = ""; }; + D43718872116834400EA350A /* cmspubkey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmspubkey.c; path = OSX/libsecurity_smime/lib/cmspubkey.c; sourceTree = ""; }; + D43718902116835E00EA350A /* secalgid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = secalgid.c; path = OSX/libsecurity_smime/lib/secalgid.c; sourceTree = ""; }; + D43718912116835E00EA350A /* cryptohi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cryptohi.h; path = OSX/libsecurity_smime/lib/cryptohi.h; sourceTree = ""; }; + D43718922116835F00EA350A /* secitem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = secitem.c; path = OSX/libsecurity_smime/lib/secitem.c; sourceTree = ""; }; + D43718932116836000EA350A /* cryptohi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cryptohi.c; path = OSX/libsecurity_smime/lib/cryptohi.c; sourceTree = ""; }; + D43718942116836000EA350A /* plhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plhash.h; path = OSX/libsecurity_smime/lib/plhash.h; sourceTree = ""; }; + D43718952116836100EA350A /* plhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = plhash.c; path = OSX/libsecurity_smime/lib/plhash.c; sourceTree = ""; }; + D43718962116836200EA350A /* SecCMS.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCMS.c; path = OSX/libsecurity_smime/lib/SecCMS.c; sourceTree = ""; }; + D43718972116836200EA350A /* secitem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = secitem.h; path = OSX/libsecurity_smime/lib/secitem.h; sourceTree = ""; }; + D43718982116836300EA350A /* cmsutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmsutil.c; path = OSX/libsecurity_smime/lib/cmsutil.c; sourceTree = ""; }; + D43718A22116838F00EA350A /* siginfoUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = siginfoUtils.cpp; path = OSX/libsecurity_smime/lib/siginfoUtils.cpp; sourceTree = ""; }; + D43718A32116839000EA350A /* secoidt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = secoidt.h; path = OSX/libsecurity_smime/lib/secoidt.h; sourceTree = ""; }; + D43718A42116839000EA350A /* secoid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = secoid.c; path = OSX/libsecurity_smime/lib/secoid.c; sourceTree = ""; }; + D43718A52116839100EA350A /* secoid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = secoid.h; path = OSX/libsecurity_smime/lib/secoid.h; sourceTree = ""; }; + D43718A62116839200EA350A /* SecSMIMEPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecSMIMEPriv.h; path = OSX/libsecurity_smime/lib/SecSMIMEPriv.h; sourceTree = ""; }; + D43718A72116839200EA350A /* smimeutil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = smimeutil.c; path = OSX/libsecurity_smime/lib/smimeutil.c; sourceTree = ""; }; + D43718AE211683A900EA350A /* tsaSupport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tsaSupport.c; path = OSX/libsecurity_smime/lib/tsaSupport.c; sourceTree = ""; }; + D43718AF211683AA00EA350A /* tsaTemplates.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tsaTemplates.c; path = OSX/libsecurity_smime/lib/tsaTemplates.c; sourceTree = ""; }; + D43718B2211683D100EA350A /* tsaSupportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tsaSupportPriv.h; path = OSX/libsecurity_smime/lib/tsaSupportPriv.h; sourceTree = ""; }; + D43718B3211683D200EA350A /* tsaSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tsaSupport.h; path = OSX/libsecurity_smime/lib/tsaSupport.h; sourceTree = ""; }; + D43718B5211683D300EA350A /* tsaTemplates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tsaTemplates.h; path = OSX/libsecurity_smime/lib/tsaTemplates.h; sourceTree = ""; }; + D43718BE21168BCC00EA350A /* libsecurity_cms.txt */ = {isa = PBXFileReference; lastKnownFileType = text; name = libsecurity_cms.txt; path = OSX/libsecurity_smime/docs/libsecurity_cms.txt; sourceTree = ""; }; + D43718BF21168BCD00EA350A /* libsecurity_cms.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = libsecurity_cms.plist; path = OSX/libsecurity_smime/docs/libsecurity_cms.plist; sourceTree = ""; }; + D43718C721168D7C00EA350A /* SecSMIME.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecSMIME.h; path = CMS/SecSMIME.h; sourceTree = ""; }; 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 = ""; }; D43DBED71E99D17100C04AEA /* nameconstraints.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = nameconstraints.c; path = OSX/sec/securityd/nameconstraints.c; sourceTree = ""; }; @@ -10413,79 +12682,219 @@ 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 = ""; }; + D44282FE22D68556001746B3 /* TrustEvaluationTestHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TrustEvaluationTestHelpers.m; path = tests/TrustTests/TrustEvaluationTestHelpers.m; sourceTree = ""; }; D442AD62215ADA250050B50F /* AppleCorporateRootCA2.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = AppleCorporateRootCA2.cer; path = OSX/trustd/iOS/AppleCorporateRootCA2.cer; sourceTree = ""; }; D442AD68215ADA250050B50F /* AppleCorporateRootCA.cer */ = {isa = PBXFileReference; lastKnownFileType = file; name = AppleCorporateRootCA.cer; path = OSX/trustd/iOS/AppleCorporateRootCA.cer; sourceTree = ""; }; D44D08B420AB890E0023C439 /* Security.apinotes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Security.apinotes; path = base/Security.apinotes; sourceTree = ""; }; + D44D1F662115893000E76E1A /* libCMS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCMS.a; sourceTree = BUILT_PRODUCTS_DIR; }; + D44D1F8321158AAB00E76E1A /* plhash.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = plhash.h; path = libsecurity_smime/lib/plhash.h; sourceTree = SOURCE_ROOT; }; + D44D1F8421158AAC00E76E1A /* crypto-embedded.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "crypto-embedded.c"; path = "libsecurity_smime/lib/crypto-embedded.c"; sourceTree = SOURCE_ROOT; }; + D44D1F8521158AAC00E76E1A /* cmscinfo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmscinfo.c; path = libsecurity_smime/lib/cmscinfo.c; sourceTree = SOURCE_ROOT; }; + D44D1F8621158AAD00E76E1A /* cmssiginfo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmssiginfo.c; path = libsecurity_smime/lib/cmssiginfo.c; sourceTree = SOURCE_ROOT; }; + D44D1F8721158AAD00E76E1A /* cryptohi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cryptohi.h; path = libsecurity_smime/lib/cryptohi.h; sourceTree = SOURCE_ROOT; }; + D44D1F8821158AAE00E76E1A /* cmsdigest.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsdigest.c; path = libsecurity_smime/lib/cmsdigest.c; sourceTree = SOURCE_ROOT; }; + D44D1F8921158AAE00E76E1A /* cmsreclist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsreclist.c; path = libsecurity_smime/lib/cmsreclist.c; sourceTree = SOURCE_ROOT; }; + D44D1F8A21158AAF00E76E1A /* cmsencode.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsencode.c; path = libsecurity_smime/lib/cmsencode.c; sourceTree = SOURCE_ROOT; }; + D44D1F8B21158AAF00E76E1A /* secoidt.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = secoidt.h; path = libsecurity_smime/lib/secoidt.h; sourceTree = SOURCE_ROOT; }; 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 = ""; }; + D453A4C02122236D00850A26 /* TrustTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrustTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D453C38A1FEC669300DE349B /* trust_update.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = trust_update.m; sourceTree = ""; }; - D453C47F1FFD857400DE349B /* security_tool_commands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = security_tool_commands.h; path = OSX/utilities/SecurityTool/security_tool_commands.h; sourceTree = SOURCE_ROOT; }; + D453C47F1FFD857400DE349B /* security_tool_commands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = security_tool_commands.h; sourceTree = ""; }; + D458C4AA214E198D0043D982 /* CTTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CTTests.m; path = tests/TrustTests/EvaluationTests/CTTests.m; sourceTree = ""; }; + D458C4AD214E198E0043D982 /* iAPTests_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iAPTests_data.h; path = tests/TrustTests/EvaluationTests/iAPTests_data.h; sourceTree = ""; }; + D458C4AE214E198E0043D982 /* EvaluationBasicTests_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EvaluationBasicTests_data.h; path = tests/TrustTests/EvaluationTests/EvaluationBasicTests_data.h; sourceTree = ""; }; + D458C4AF214E198E0043D982 /* EvaluationBasicTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EvaluationBasicTests.m; path = tests/TrustTests/EvaluationTests/EvaluationBasicTests.m; sourceTree = ""; }; + D458C4B4214E19AE0043D982 /* PathParseTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PathParseTests.m; path = tests/TrustTests/EvaluationTests/PathParseTests.m; sourceTree = ""; }; + D458C4B5214E19AE0043D982 /* iAPTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = iAPTests.m; path = tests/TrustTests/EvaluationTests/iAPTests.m; sourceTree = ""; }; + D458C4B6214E19AE0043D982 /* SignatureAlgorithmTests_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SignatureAlgorithmTests_data.h; path = tests/TrustTests/EvaluationTests/SignatureAlgorithmTests_data.h; sourceTree = ""; }; + D458C4B7214E19AF0043D982 /* SignatureAlgorithmTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SignatureAlgorithmTests.m; path = tests/TrustTests/EvaluationTests/SignatureAlgorithmTests.m; sourceTree = ""; }; + D458C4BE214E19FA0043D982 /* TrustSettingsInterfaceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrustSettingsInterfaceTests.m; path = tests/TrustTests/FrameworkTests/TrustSettingsInterfaceTests.m; sourceTree = ""; }; + D458C4BF214E19FB0043D982 /* TrustInterfaceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrustInterfaceTests.m; path = tests/TrustTests/FrameworkTests/TrustInterfaceTests.m; sourceTree = ""; }; + D458C4C0214E19FB0043D982 /* TrustInterfaceTests_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrustInterfaceTests_data.h; path = tests/TrustTests/FrameworkTests/TrustInterfaceTests_data.h; sourceTree = ""; }; + D458C4C5214E1A400043D982 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = tests/TrustTests/TestRunners/Assets.xcassets; sourceTree = ""; }; + D458C4C6214E1A400043D982 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = tests/TrustTests/TestRunners/main.m; sourceTree = ""; }; + D458C4C7214E1A400043D982 /* Base.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Base.lproj; path = tests/TrustTests/TestRunners/Base.lproj; sourceTree = ""; }; + D458C4C8214E1A410043D982 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = tests/TrustTests/TestRunners/AppDelegate.h; sourceTree = ""; }; + D458C4C9214E1A410043D982 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ViewController.h; path = tests/TrustTests/TestRunners/ViewController.h; sourceTree = ""; }; + D458C4CA214E1A420043D982 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = tests/TrustTests/TestRunners/AppDelegate.m; sourceTree = ""; }; + D458C4CB214E1A420043D982 /* trusttests_entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = trusttests_entitlements.plist; path = tests/TrustTests/TestRunners/trusttests_entitlements.plist; sourceTree = ""; }; + D458C4CC214E1A420043D982 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = tests/TrustTests/TestRunners/Info.plist; sourceTree = ""; }; + D458C4CD214E1A430043D982 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ViewController.m; path = tests/TrustTests/TestRunners/ViewController.m; sourceTree = ""; }; + D458C4E1214E1DE00043D982 /* TrustTestsRunner_ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrustTestsRunner_ios.app; sourceTree = BUILT_PRODUCTS_DIR; }; + D458C4FC214E1E6C0043D982 /* appmain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = appmain.m; path = tests/TrustTests/TestRunners/appmain.m; sourceTree = ""; }; + D458C4FE214E1F8E0043D982 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = ../../../../iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; + D458C500214E1FAF0043D982 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + D458C506214E20530043D982 /* TrustTests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = TrustTests; sourceTree = BUILT_PRODUCTS_DIR; }; + D458C511214E20840043D982 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + D458C513214E27620043D982 /* PolicyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = PolicyTests.m; path = tests/TrustTests/EvaluationTests/PolicyTests.m; sourceTree = ""; }; + D458C51B214E2CFF0043D982 /* si-20-sectrust-policies-data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-20-sectrust-policies-data"; path = "OSX/shared_regressions/si-20-sectrust-policies-data"; sourceTree = ""; }; + D458C51E214E2E0C0043D982 /* Main.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Main.storyboard; path = tests/TrustTests/TestRunners/Main.storyboard; sourceTree = ""; }; D46246911F9AE2E400D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; - D462469C1F9AE45900D63882 /* oids.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = oids.c; sourceTree = ""; }; D46246A21F9AE49E00D63882 /* oids.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oids.h; path = trust/oids.h; sourceTree = ""; }; D46246A91F9AE6C900D63882 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; 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 = ""; }; - D46A6BF121531F77008ABF6A /* si-82-sectrust-ct.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "si-82-sectrust-ct.h"; path = "OSX/shared_regressions/si-82-sectrust-ct.h"; sourceTree = SOURCE_ROOT; }; - D46B379F2151B6E50083DAAA /* SecTrustStoreServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecTrustStoreServer.m; path = OSX/sec/securityd/SecTrustStoreServer.m; sourceTree = ""; }; - D479F6E01F980F8F00388D28 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Trust.strings; sourceTree = ""; }; + D47079F221128C46005BCFDA /* SecCMS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecCMS.h; path = CMS/SecCMS.h; sourceTree = ""; }; + D47079F9211355B3005BCFDA /* CMSEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSEncoder.h; path = CMS/CMSEncoder.h; sourceTree = ""; }; + D4707A0521136E69005BCFDA /* TrustTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrustTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + D4707A0D211373D4005BCFDA /* CMSPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSPrivate.h; path = CMS/CMSPrivate.h; sourceTree = ""; }; + D4707A1021137525005BCFDA /* CMSDecoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CMSDecoder.h; path = CMS/CMSDecoder.h; sourceTree = ""; }; + D4707A1F2113AB65005BCFDA /* SecCmsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsBase.h; path = CMS/SecCmsBase.h; sourceTree = ""; }; + D4707A222113B48E005BCFDA /* SecCmsEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsEncoder.h; path = CMS/SecCmsEncoder.h; sourceTree = ""; }; + D4707A252113E9B6005BCFDA /* SecCmsDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsDecoder.h; path = CMS/SecCmsDecoder.h; sourceTree = ""; }; + D4707A282113ECA0005BCFDA /* SecCmsMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsMessage.h; path = CMS/SecCmsMessage.h; sourceTree = ""; }; + D4707A2B2114B31A005BCFDA /* SecCmsContentInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsContentInfo.h; path = CMS/SecCmsContentInfo.h; sourceTree = ""; }; + D4707A2E2114C30A005BCFDA /* SecCmsDigestContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsDigestContext.h; path = CMS/SecCmsDigestContext.h; sourceTree = ""; }; + D479F6E01F980F8F00388D28 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = en.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 = ""; }; D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = all_arches.xcconfig; path = xcconfig/all_arches.xcconfig; sourceTree = ""; }; D47CA65C1EB036450038E2BB /* libMobileGestalt.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libMobileGestalt.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.0.Internal.sdk/usr/lib/libMobileGestalt.dylib; sourceTree = DEVELOPER_DIR; }; D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCFAllocator.h; sourceTree = ""; }; - D484A1012167D6F8008653A9 /* ct_exceptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ct_exceptions.m; 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 = ""; }; + D4A0F8BA211E69CB00443CA1 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = tests/TrustTests/Info.plist; sourceTree = ""; }; + D4A0F8BB211E69CB00443CA1 /* TestMacroConversions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestMacroConversions.h; path = tests/TrustTests/TestMacroConversions.h; sourceTree = ""; }; + D4A0F8C1211E6A2F00443CA1 /* 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 = ""; }; + D4A0F8C3211E6A5600443CA1 /* CertificateInterfaceTests_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CertificateInterfaceTests_data.h; path = tests/TrustTests/FrameworkTests/CertificateInterfaceTests_data.h; sourceTree = ""; }; + D4A0F8C4211E6A5700443CA1 /* TrustFrameworkTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrustFrameworkTestCase.m; path = tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.m; sourceTree = ""; }; + D4A0F8C5211E6A5700443CA1 /* TrustFrameworkTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrustFrameworkTestCase.h; path = tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.h; sourceTree = ""; }; + D4A0F8C6211E6A5700443CA1 /* CertificateInterfaceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CertificateInterfaceTests.m; path = tests/TrustTests/FrameworkTests/CertificateInterfaceTests.m; sourceTree = ""; }; + D4A0F8C9211E6A8200443CA1 /* TrustEvaluationTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TrustEvaluationTestCase.m; path = tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.m; sourceTree = ""; }; + D4A0F8CB211E6A8200443CA1 /* TrustEvaluationTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TrustEvaluationTestCase.h; path = tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.h; sourceTree = ""; }; + D4A3A596217A85CB00F0A8DA /* ct_exceptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ct_exceptions.m; sourceTree = ""; }; + D4A7946D22D7DD6E00D1B2B7 /* TrustEvaluationTestHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TrustEvaluationTestHelpers.h; path = tests/TrustTests/TrustEvaluationTestHelpers.h; sourceTree = ""; }; + D4A7DD7320A26CF900F51F3F /* AuthKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthKit.framework; path = System/Library/PrivateFrameworks/AuthKit.framework; sourceTree = SDKROOT; }; + D4AA0D9922FB959600D77FA4 /* si-29-cms-chain-mode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-29-cms-chain-mode.m"; sourceTree = ""; }; + D4AA0D9C22FB962300D77FA4 /* si-29-cms-chain-mode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-29-cms-chain-mode.h"; 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; }; + D4AC5764214E195200A32C01 /* VerifyDateTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = VerifyDateTests.m; path = tests/TrustTests/EvaluationTests/VerifyDateTests.m; sourceTree = ""; }; + D4AC5765214E195300A32C01 /* VerifyDateTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = VerifyDateTests_data.h; path = tests/TrustTests/EvaluationTests/VerifyDateTests_data.h; sourceTree = ""; }; + D4AC5766214E195300A32C01 /* ECTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = ECTests.m; path = tests/TrustTests/EvaluationTests/ECTests.m; sourceTree = ""; }; + D4AC5767214E195300A32C01 /* ECTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ECTests_data.h; path = tests/TrustTests/EvaluationTests/ECTests_data.h; sourceTree = ""; }; + D4AC5768214E195400A32C01 /* KeySizeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = KeySizeTests.m; path = tests/TrustTests/EvaluationTests/KeySizeTests.m; sourceTree = ""; }; + D4AC5769214E195400A32C01 /* KeySizeTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = KeySizeTests_data.h; path = tests/TrustTests/EvaluationTests/KeySizeTests_data.h; sourceTree = ""; }; + D4AC8BE721320AD0006E9871 /* CertificateParseTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CertificateParseTests.m; path = tests/TrustTests/FrameworkTests/CertificateParseTests.m; sourceTree = ""; }; + D4AC8BED2132127A006E9871 /* si-18-certificate-parse */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-18-certificate-parse"; path = "OSX/shared_regressions/si-18-certificate-parse"; sourceTree = ""; }; 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; }; + D4B2966822DBFDB100DCF250 /* TestCopyProperties_ios-data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "TestCopyProperties_ios-data"; path = "tests/TrustTests/TestData/TestCopyProperties_ios-data"; sourceTree = ""; }; + D4B3B1CB2115149C00A43409 /* SecCmsDigestedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsDigestedData.h; path = CMS/SecCmsDigestedData.h; sourceTree = ""; }; + D4B3B1CE2115167600A43409 /* SecCmsEncryptedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsEncryptedData.h; path = CMS/SecCmsEncryptedData.h; sourceTree = ""; }; + D4B3B1D1211517B000A43409 /* SecCmsEnvelopedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsEnvelopedData.h; path = CMS/SecCmsEnvelopedData.h; sourceTree = ""; }; + D4B3B1D42115193600A43409 /* SecCmsRecipientInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsRecipientInfo.h; path = CMS/SecCmsRecipientInfo.h; sourceTree = ""; }; + D4B3B1D721151B9900A43409 /* SecCmsSignedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsSignedData.h; path = CMS/SecCmsSignedData.h; sourceTree = ""; }; + D4B3B1DA2115293300A43409 /* SecCmsSignerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCmsSignerInfo.h; path = CMS/SecCmsSignerInfo.h; sourceTree = ""; }; + D4B68C5C211A7D98009FED69 /* libDER.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libDER.a; path = usr/local/lib/security_libDER/libDER.a; sourceTree = SDKROOT; }; + D4B68C64211A8186009FED69 /* trustd_spi.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = trustd_spi.h; path = OSX/trustd/trustd_spi.h; sourceTree = ""; }; + D4B68C65211A8186009FED69 /* trustd_spi.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = trustd_spi.c; path = OSX/trustd/trustd_spi.c; sourceTree = ""; }; 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; }; - D4C263C81F952E64001317EA /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; - D4C263CD1F952F6C001317EA /* SecErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = SecErrorMessages.strings; path = derived_src/English.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; + D4C263C81F952E64001317EA /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; fileEncoding = 10; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; + D4C263CD1F952F6C001317EA /* SecErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = SecErrorMessages.strings; path = derived_src/en.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "si-87-sectrust-name-constraints"; sourceTree = ""; }; D4C6C5CB1FB3B3CC007EA57E /* libarchive.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libarchive.tbd; path = usr/lib/libarchive.tbd; sourceTree = SDKROOT; }; D4C6C5CE1FB3B44C007EA57E /* libarchive.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libarchive.2.dylib; path = /usr/lib/libarchive.2.dylib; sourceTree = SDKROOT; }; D4C8A1511E66709800CD6DF1 /* si-32-sectrust-pinning-required.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "si-32-sectrust-pinning-required.h"; sourceTree = ""; }; + D4CF6E63211588660014647E /* SecSMIME.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecSMIME.h; path = libsecurity_smime/lib/SecSMIME.h; sourceTree = SOURCE_ROOT; }; + D4CF6E64211588670014647E /* cmspriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cmspriv.h; path = libsecurity_smime/lib/cmspriv.h; sourceTree = SOURCE_ROOT; }; + D4CF6E65211588670014647E /* cmspubkey.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmspubkey.c; path = libsecurity_smime/lib/cmspubkey.c; sourceTree = SOURCE_ROOT; }; + D4CF6E66211588670014647E /* cmsattr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsattr.c; path = libsecurity_smime/lib/cmsattr.c; sourceTree = SOURCE_ROOT; }; + D4CF6E67211588680014647E /* cmstpriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cmstpriv.h; path = libsecurity_smime/lib/cmstpriv.h; sourceTree = SOURCE_ROOT; }; + D4CF6E68211588680014647E /* CMSDecoder.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = CMSDecoder.c; path = libsecurity_smime/lib/CMSDecoder.c; sourceTree = SOURCE_ROOT; }; + D4CF6E69211588680014647E /* secalgid.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = secalgid.c; path = libsecurity_smime/lib/secalgid.c; sourceTree = SOURCE_ROOT; }; + D4CF6E6A211588690014647E /* secoid.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = secoid.h; path = libsecurity_smime/lib/secoid.h; sourceTree = SOURCE_ROOT; }; + D4CF6E6B211588690014647E /* cmsarray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsarray.c; path = libsecurity_smime/lib/cmsarray.c; sourceTree = SOURCE_ROOT; }; + D4CF6E6C211588690014647E /* cmsmessage.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsmessage.c; path = libsecurity_smime/lib/cmsmessage.c; sourceTree = SOURCE_ROOT; }; + D4CF6E6D2115886A0014647E /* cmssigdata.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmssigdata.c; path = libsecurity_smime/lib/cmssigdata.c; sourceTree = SOURCE_ROOT; }; + D4CF6E6E2115886A0014647E /* cmscipher.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmscipher.c; path = libsecurity_smime/lib/cmscipher.c; sourceTree = SOURCE_ROOT; }; + D4CF6E6F2115886A0014647E /* cmsencdata.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsencdata.c; path = libsecurity_smime/lib/cmsencdata.c; sourceTree = SOURCE_ROOT; }; + D4CF6E712115886B0014647E /* CMSUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CMSUtils.h; path = libsecurity_smime/lib/CMSUtils.h; sourceTree = SOURCE_ROOT; }; + D4CF6E722115886B0014647E /* smimeutil.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = smimeutil.c; path = libsecurity_smime/lib/smimeutil.c; sourceTree = SOURCE_ROOT; }; + D4CF6E732115886C0014647E /* cmsdecode.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsdecode.c; path = libsecurity_smime/lib/cmsdecode.c; sourceTree = SOURCE_ROOT; }; + D4CF6E742115886C0014647E /* plhash.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = plhash.c; path = libsecurity_smime/lib/plhash.c; sourceTree = SOURCE_ROOT; }; + D4CF6E752115886C0014647E /* cmslocal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cmslocal.h; path = libsecurity_smime/lib/cmslocal.h; sourceTree = SOURCE_ROOT; }; + D4CF6E762115886D0014647E /* CMSUtils.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = CMSUtils.c; path = libsecurity_smime/lib/CMSUtils.c; sourceTree = SOURCE_ROOT; }; + D4CF6E772115886D0014647E /* cmsasn1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsasn1.c; path = libsecurity_smime/lib/cmsasn1.c; sourceTree = SOURCE_ROOT; }; + D4CF6E782115886D0014647E /* cmsutil.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsutil.c; path = libsecurity_smime/lib/cmsutil.c; sourceTree = SOURCE_ROOT; }; + D4CF6E792115886E0014647E /* secoid.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = secoid.c; path = libsecurity_smime/lib/secoid.c; sourceTree = SOURCE_ROOT; }; + D4CF6E7A2115886E0014647E /* SecSMIMEPriv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecSMIMEPriv.h; path = libsecurity_smime/lib/SecSMIMEPriv.h; sourceTree = SOURCE_ROOT; }; + D4CF6E7B2115886E0014647E /* cmsdigdata.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsdigdata.c; path = libsecurity_smime/lib/cmsdigdata.c; sourceTree = SOURCE_ROOT; }; + D4CF6E7C2115886F0014647E /* CMSEncoder.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = CMSEncoder.c; path = libsecurity_smime/lib/CMSEncoder.c; sourceTree = SOURCE_ROOT; }; + D4CF6E7D2115886F0014647E /* cmsenvdata.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsenvdata.c; path = libsecurity_smime/lib/cmsenvdata.c; sourceTree = SOURCE_ROOT; }; + D4CF6E7F211588700014647E /* cmsrecinfo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = cmsrecinfo.c; path = libsecurity_smime/lib/cmsrecinfo.c; sourceTree = SOURCE_ROOT; }; + D4CF6E81211588710014647E /* SecAsn1Item.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecAsn1Item.h; path = libsecurity_smime/lib/SecAsn1Item.h; sourceTree = SOURCE_ROOT; }; D4CFAA7D1E660BB3004746AA /* si-32-sectrust-pinning-required.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-32-sectrust-pinning-required.m"; sourceTree = ""; }; + D4D1FDDC21165F8B003538E2 /* libsecurity_cms_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_cms_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; D4D718341E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "spbkdf-01-hmac-sha256.c"; sourceTree = ""; }; D4D886BE1CEB9F3B00DC7583 /* ssl-policy-certs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "ssl-policy-certs"; sourceTree = ""; }; D4D886E81CEBDD2A00DC7583 /* nist-certs */ = {isa = PBXFileReference; lastKnownFileType = folder; path = "nist-certs"; sourceTree = ""; }; + D4D92DA32277E6D10009A7CF /* PathParseTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PathParseTests_data.h; path = tests/TrustTests/EvaluationTests/PathParseTests_data.h; sourceTree = ""; }; + D4D92DA422788FEB0009A7CF /* NISTTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = NISTTests.m; path = tests/TrustTests/EvaluationTests/NISTTests.m; sourceTree = ""; }; + D4D92DA72278904F0009A7CF /* nist-certs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "nist-certs"; path = "SecurityTests/nist-certs"; sourceTree = ""; }; + D4EA5CF622B225C000883439 /* LoggingServerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LoggingServerTests.m; path = tests/TrustTests/DaemonTests/LoggingServerTests.m; sourceTree = ""; }; D4EC94FA1CEA482D0083E753 /* si-20-sectrust-policies-data */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "si-20-sectrust-policies-data"; path = "../OSX/shared_regressions/si-20-sectrust-policies-data"; sourceTree = ""; }; - D4FBBD601DD66196004408F7 /* CMSEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMSEncoder.h; sourceTree = ""; }; - D4FBBD611DD66196004408F7 /* CMSDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMSDecoder.h; sourceTree = ""; }; + D4EF321E215F0F76000A31A5 /* SecTrustStoreServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecTrustStoreServer.m; path = OSX/sec/securityd/SecTrustStoreServer.m; sourceTree = ""; }; + D4EF3222215F102F000A31A5 /* CTTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CTTests_data.h; path = tests/TrustTests/EvaluationTests/CTTests_data.h; sourceTree = ""; }; D4FC521C1EC3E05B00E99785 /* smime_attr_emails.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = smime_attr_emails.h; sourceTree = ""; }; + D4FD421B217D7891002B7EE2 /* NameConstraintsTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = NameConstraintsTests.m; path = tests/TrustTests/EvaluationTests/NameConstraintsTests.m; sourceTree = ""; }; + D4FD421E217D78BB002B7EE2 /* NameConstraintsTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NameConstraintsTests_data.h; path = tests/TrustTests/EvaluationTests/NameConstraintsTests_data.h; sourceTree = ""; }; + D4FD421F217D7B27002B7EE2 /* PathScoringTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = PathScoringTests.m; path = tests/TrustTests/EvaluationTests/PathScoringTests.m; sourceTree = ""; }; + D4FD4222217D7B48002B7EE2 /* PathScoringTests_data.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PathScoringTests_data.h; path = tests/TrustTests/EvaluationTests/PathScoringTests_data.h; sourceTree = ""; }; + D4FD4223217D7BE3002B7EE2 /* libarchive.2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libarchive.2.tbd; path = usr/lib/libarchive.2.tbd; sourceTree = SDKROOT; }; + DA2C402D2189302E005F1CC3 /* mach_notify.defs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.mig; path = mach_notify.defs; sourceTree = ""; }; DA30D6761DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainSyncAccountUpdater.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; + DA41FE0E2241ADC000838FB3 /* otpaird */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = otpaird; sourceTree = BUILT_PRODUCTS_DIR; }; + DA41FE192241AF3E00838FB3 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + DA4586572245AEDA0073F993 /* OTPairingService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTPairingService.h; sourceTree = ""; }; + DA4586592245AEDA0073F993 /* OTPairingService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPairingService.m; sourceTree = ""; }; + DA45865A2245AEDB0073F993 /* otpaird.watchos.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = otpaird.watchos.entitlements; sourceTree = ""; }; + DA45865B2245AEDB0073F993 /* otpaird.iphoneos.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = otpaird.iphoneos.entitlements; sourceTree = ""; }; + DA5B871A2065A8410093F083 /* SecAutorelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecAutorelease.h; sourceTree = ""; }; + DA5B871B2065A8430093F083 /* SecAutorelease.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = 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 = ""; }; + DAC58D1C2244527E00D4CD41 /* OTPairingPacketContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTPairingPacketContext.h; sourceTree = ""; }; + DAC58D1D2244527F00D4CD41 /* com.apple.security.otpaird.watchos.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.security.otpaird.watchos.plist; sourceTree = ""; }; + DAC58D1E2244528000D4CD41 /* OTPairingPacketContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTPairingPacketContext.m; sourceTree = ""; }; + DAC58D1F2244528100D4CD41 /* com.apple.security.otpaird.iphoneos.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = com.apple.security.otpaird.iphoneos.plist; sourceTree = ""; }; + DACAD627229F6E690002BBC3 /* OTPairingSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OTPairingSession.h; sourceTree = ""; }; + DACAD629229F6E6A0002BBC3 /* OTPairingSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OTPairingSession.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 = ""; }; + DAEF8E55225819EE00F7DF79 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DAEF8E57225819EF00F7DF79 /* OTPairingClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTPairingClient.m; sourceTree = ""; }; + DAEF8E58225819EF00F7DF79 /* OTPairingClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTPairingClient.h; sourceTree = ""; }; + DAEF8E59225819F000F7DF79 /* OTPairingConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTPairingConstants.h; sourceTree = ""; }; DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = macos_legacy_lib.xcconfig; path = xcconfig/macos_legacy_lib.xcconfig; sourceTree = ""; }; DC0067C01D87876F005AF8DB /* libsecurityd_server.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_server.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC0067D01D878898005AF8DB /* libsecurityd_ucspc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_ucspc.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DC04707F218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTCuttlefishAccountStateHolder.h; sourceTree = ""; }; + DC047080218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTCuttlefishAccountStateHolder.m; sourceTree = ""; }; + DC047085218BCEF20078BDAA /* OTOperationDependencies.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTOperationDependencies.h; sourceTree = ""; }; + DC047086218BCEF20078BDAA /* OTOperationDependencies.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTOperationDependencies.m; sourceTree = ""; }; + DC05037621409A4000A8EDB7 /* OCMockUmbrella.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OCMockUmbrella.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + DC05037821409A4100A8EDB7 /* OCMockUmbrella.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OCMockUmbrella.h; sourceTree = ""; }; + DC05037921409A4100A8EDB7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + DC07090222936BCC002711B9 /* OctagonTests+ErrorHandling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+ErrorHandling.swift"; sourceTree = ""; }; DC08D1C21E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudKitKeychainSyncingMockXCTest.h; sourceTree = ""; }; DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudKitKeychainSyncingMockXCTest.m; sourceTree = ""; }; DC08D1CB1E64FCC5006237DA /* CKKSSOSTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSSOSTests.m; sourceTree = ""; }; @@ -10532,24 +12941,12 @@ DC0BC5EE1D8B745700070CB0 /* comcryptPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = comcryptPriv.h; sourceTree = ""; }; DC0BC5EF1D8B745700070CB0 /* comDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = comDebug.h; sourceTree = ""; }; DC0BC5FF1D8B752B00070CB0 /* libsecurity_cryptkit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_cryptkit.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DC0BC6011D8B755200070CB0 /* feeCipherFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = feeCipherFile.c; sourceTree = ""; }; - DC0BC6021D8B755200070CB0 /* feeCipherFileAtom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = feeCipherFileAtom.c; sourceTree = ""; }; DC0BC6031D8B755200070CB0 /* byteRep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = byteRep.c; sourceTree = ""; }; DC0BC6041D8B755200070CB0 /* byteRep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = byteRep.h; sourceTree = ""; }; - DC0BC6051D8B755200070CB0 /* CipherFileDES.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CipherFileDES.c; sourceTree = ""; }; - DC0BC6061D8B755200070CB0 /* CipherFileDES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CipherFileDES.h; sourceTree = ""; }; - DC0BC6071D8B755200070CB0 /* CipherFileFEED.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CipherFileFEED.c; sourceTree = ""; }; - DC0BC6081D8B755200070CB0 /* CipherFileFEED.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CipherFileFEED.h; sourceTree = ""; }; - DC0BC6091D8B755200070CB0 /* CipherFileTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CipherFileTypes.h; sourceTree = ""; }; DC0BC60A1D8B755200070CB0 /* ckconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckconfig.h; sourceTree = ""; }; - DC0BC60B1D8B755200070CB0 /* ckDES.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ckDES.c; sourceTree = ""; }; - DC0BC60C1D8B755200070CB0 /* ckDES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckDES.h; sourceTree = ""; }; - DC0BC60D1D8B755200070CB0 /* ckMD5.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ckMD5.c; sourceTree = ""; }; DC0BC60E1D8B755200070CB0 /* ckMD5.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckMD5.h; sourceTree = ""; }; DC0BC60F1D8B755200070CB0 /* ckSHA1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ckSHA1.c; sourceTree = ""; }; DC0BC6101D8B755200070CB0 /* ckSHA1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckSHA1.h; sourceTree = ""; }; - DC0BC6111D8B755200070CB0 /* ckSHA1_priv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ckSHA1_priv.c; sourceTree = ""; }; - DC0BC6121D8B755200070CB0 /* ckSHA1_priv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckSHA1_priv.h; sourceTree = ""; }; DC0BC6131D8B755200070CB0 /* ckutilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ckutilities.c; sourceTree = ""; }; DC0BC6141D8B755200070CB0 /* ckutilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ckutilities.h; sourceTree = ""; }; DC0BC6151D8B755200070CB0 /* Crypt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Crypt.h; sourceTree = ""; }; @@ -10558,11 +12955,9 @@ DC0BC61A1D8B755200070CB0 /* CryptKitDER.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptKitDER.cpp; sourceTree = ""; }; DC0BC61B1D8B755200070CB0 /* CryptKitDER.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptKitDER.h; sourceTree = ""; }; DC0BC61C1D8B755200070CB0 /* curveParamData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curveParamData.h; sourceTree = ""; }; - DC0BC61D1D8B755200070CB0 /* curveParamDataOld.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curveParamDataOld.h; sourceTree = ""; }; DC0BC61E1D8B755200070CB0 /* curveParams.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = curveParams.c; sourceTree = ""; }; DC0BC61F1D8B755200070CB0 /* curveParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = curveParams.h; sourceTree = ""; }; DC0BC6201D8B755200070CB0 /* ECDSA_Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECDSA_Profile.h; sourceTree = ""; }; - DC0BC6211D8B755200070CB0 /* ECDSA_Verify_Prefix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ECDSA_Verify_Prefix.h; sourceTree = ""; }; DC0BC6221D8B755200070CB0 /* elliptic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = elliptic.c; sourceTree = ""; }; DC0BC6231D8B755200070CB0 /* elliptic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = elliptic.h; sourceTree = ""; }; DC0BC6241D8B755200070CB0 /* ellipticMeasure.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ellipticMeasure.h; sourceTree = ""; }; @@ -10570,13 +12965,9 @@ DC0BC6261D8B755200070CB0 /* ellipticProj.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ellipticProj.h; sourceTree = ""; }; DC0BC6271D8B755200070CB0 /* enc64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = enc64.c; sourceTree = ""; }; DC0BC6281D8B755200070CB0 /* enc64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = enc64.h; sourceTree = ""; }; - DC0BC6291D8B755200070CB0 /* engineNSA127.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = engineNSA127.c; sourceTree = ""; }; DC0BC62A1D8B755200070CB0 /* falloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = falloc.c; sourceTree = ""; }; DC0BC62B1D8B755200070CB0 /* falloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = falloc.h; sourceTree = ""; }; - DC0BC62C1D8B755200070CB0 /* feeCipherFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = feeCipherFile.h; sourceTree = ""; }; DC0BC62D1D8B755200070CB0 /* feeDebug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = feeDebug.h; sourceTree = ""; }; - DC0BC62E1D8B755200070CB0 /* feeDES.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = feeDES.c; sourceTree = ""; }; - DC0BC62F1D8B755200070CB0 /* feeDES.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = feeDES.h; sourceTree = ""; }; DC0BC6301D8B755200070CB0 /* feeDigitalSignature.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = feeDigitalSignature.c; sourceTree = ""; }; DC0BC6311D8B755200070CB0 /* feeDigitalSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = feeDigitalSignature.h; sourceTree = ""; }; DC0BC6321D8B755200070CB0 /* feeECDSA.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = feeECDSA.c; sourceTree = ""; }; @@ -10597,11 +12988,6 @@ DC0BC6411D8B755200070CB0 /* giantIntegers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = giantIntegers.c; sourceTree = ""; }; DC0BC6421D8B755200070CB0 /* giantIntegers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = giantIntegers.h; sourceTree = ""; }; DC0BC6431D8B755200070CB0 /* giantPort_Generic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = giantPort_Generic.h; sourceTree = ""; }; - DC0BC6441D8B755200070CB0 /* giantPort_i486.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = giantPort_i486.h; sourceTree = ""; }; - DC0BC6451D8B755200070CB0 /* giantPort_PPC.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = giantPort_PPC.c; sourceTree = ""; }; - DC0BC6461D8B755200070CB0 /* giantPort_PPC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = giantPort_PPC.h; sourceTree = ""; }; - DC0BC6471D8B755200070CB0 /* giantPort_PPC_Gnu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = giantPort_PPC_Gnu.h; sourceTree = ""; }; - DC0BC6481D8B755200070CB0 /* giantPort_PPC_Gnu.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = giantPort_PPC_Gnu.s; sourceTree = ""; }; DC0BC6491D8B755200070CB0 /* giantPortCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = giantPortCommon.h; sourceTree = ""; }; DC0BC64A1D8B755200070CB0 /* HmacSha1Legacy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = HmacSha1Legacy.c; sourceTree = ""; }; DC0BC64B1D8B755200070CB0 /* HmacSha1Legacy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HmacSha1Legacy.h; sourceTree = ""; }; @@ -10779,7 +13165,6 @@ DC0BC9ED1D8B827200070CB0 /* sslRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sslRecord.h; sourceTree = ""; }; DC0BC9F01D8B827200070CB0 /* sslCrypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sslCrypto.c; sourceTree = ""; }; DC0BC9F21D8B827200070CB0 /* sslMemory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sslMemory.c; sourceTree = ""; }; - DC0BC9F31D8B827200070CB0 /* sslUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sslUtils.c; sourceTree = ""; }; DC0BCA1A1D8B82B000070CB0 /* libsecurity_ssl_regressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_ssl_regressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC0BCA1B1D8B82CD00070CB0 /* CA-ECC_Cert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CA-ECC_Cert.h"; sourceTree = ""; }; DC0BCA1C1D8B82CD00070CB0 /* CA-ECC_Key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CA-ECC_Key.h"; sourceTree = ""; }; @@ -10922,63 +13307,63 @@ DC0BCC091D8C64B500070CB0 /* testpolicy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = testpolicy.h; path = OSX/regressions/test/testpolicy.h; sourceTree = ""; }; DC0BCC0A1D8C64B500070CB0 /* testpolicy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = testpolicy.m; path = OSX/regressions/test/testpolicy.m; sourceTree = ""; }; DC0BCC361D8C684F00070CB0 /* libutilities.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libutilities.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DC0BCC3A1D8C68CF00070CB0 /* iCloudKeychainTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iCloudKeychainTrace.c; path = src/iCloudKeychainTrace.c; sourceTree = ""; }; - DC0BCC3B1D8C68CF00070CB0 /* iCloudKeychainTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iCloudKeychainTrace.h; path = src/iCloudKeychainTrace.h; sourceTree = ""; }; - DC0BCC3C1D8C68CF00070CB0 /* SecAKSWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecAKSWrappers.c; path = src/SecAKSWrappers.c; sourceTree = ""; }; - DC0BCC3D1D8C68CF00070CB0 /* SecAKSWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAKSWrappers.h; path = src/SecAKSWrappers.h; sourceTree = ""; }; - DC0BCC3E1D8C68CF00070CB0 /* SecBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecBuffer.c; path = src/SecBuffer.c; sourceTree = ""; }; - DC0BCC3F1D8C68CF00070CB0 /* SecBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecBuffer.h; path = src/SecBuffer.h; sourceTree = ""; }; - DC0BCC401D8C68CF00070CB0 /* SecCoreCrypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCoreCrypto.c; path = src/SecCoreCrypto.c; sourceTree = ""; }; - DC0BCC411D8C68CF00070CB0 /* SecCoreCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCoreCrypto.h; path = src/SecCoreCrypto.h; sourceTree = ""; }; - DC0BCC441D8C68CF00070CB0 /* SecCFCCWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCFCCWrappers.c; path = src/SecCFCCWrappers.c; sourceTree = ""; }; - DC0BCC451D8C68CF00070CB0 /* SecCFCCWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCFCCWrappers.h; path = src/SecCFCCWrappers.h; sourceTree = ""; }; - DC0BCC461D8C68CF00070CB0 /* SecCFRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCFRelease.h; path = src/SecCFRelease.h; sourceTree = ""; }; - DC0BCC471D8C68CF00070CB0 /* SecCFWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCFWrappers.c; path = src/SecCFWrappers.c; sourceTree = ""; }; - DC0BCC481D8C68CF00070CB0 /* SecCFWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = SecCFWrappers.h; path = src/SecCFWrappers.h; sourceTree = ""; }; - DC0BCC491D8C68CF00070CB0 /* SecCFError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecCFError.c; path = src/SecCFError.c; sourceTree = ""; }; - DC0BCC4A1D8C68CF00070CB0 /* SecCFError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCFError.h; path = src/SecCFError.h; sourceTree = ""; }; - DC0BCC4B1D8C68CF00070CB0 /* SecDispatchRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecDispatchRelease.h; path = src/SecDispatchRelease.h; sourceTree = ""; }; - DC0BCC4C1D8C68CF00070CB0 /* SecIOFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecIOFormat.h; path = src/SecIOFormat.h; sourceTree = ""; }; - DC0BCC4D1D8C68CF00070CB0 /* SecTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecTrace.c; path = src/SecTrace.c; sourceTree = ""; }; - DC0BCC4E1D8C68CF00070CB0 /* SecTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTrace.h; path = src/SecTrace.h; sourceTree = ""; }; - DC0BCC4F1D8C68CF00070CB0 /* array_size.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = array_size.h; path = src/array_size.h; sourceTree = ""; }; - DC0BCC521D8C68CF00070CB0 /* debugging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = debugging.c; path = src/debugging.c; sourceTree = ""; }; - DC0BCC531D8C68CF00070CB0 /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = debugging.h; path = src/debugging.h; sourceTree = ""; }; - DC0BCC541D8C68CF00070CB0 /* debugging_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = debugging_test.h; path = src/debugging_test.h; sourceTree = ""; }; - DC0BCC551D8C68CF00070CB0 /* der_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_array.c; path = src/der_array.c; sourceTree = ""; }; - DC0BCC561D8C68CF00070CB0 /* der_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_boolean.c; path = src/der_boolean.c; sourceTree = ""; }; - DC0BCC571D8C68CF00070CB0 /* der_null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_null.c; path = src/der_null.c; sourceTree = ""; }; - DC0BCC581D8C68CF00070CB0 /* der_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_data.c; path = src/der_data.c; sourceTree = ""; }; - DC0BCC591D8C68CF00070CB0 /* der_date.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = der_date.c; path = src/der_date.c; sourceTree = ""; }; - DC0BCC5A1D8C68CF00070CB0 /* der_date.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_date.h; path = src/der_date.h; sourceTree = ""; }; - DC0BCC5B1D8C68CF00070CB0 /* der_dictionary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_dictionary.c; path = src/der_dictionary.c; sourceTree = ""; }; - DC0BCC5C1D8C68CF00070CB0 /* der_number.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_number.c; path = src/der_number.c; sourceTree = ""; }; - DC0BCC5D1D8C68CF00070CB0 /* der_plist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_plist.c; path = src/der_plist.c; sourceTree = ""; }; - DC0BCC5F1D8C68CF00070CB0 /* der_plist_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_plist_internal.c; path = src/der_plist_internal.c; sourceTree = ""; }; - DC0BCC601D8C68CF00070CB0 /* der_plist_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_plist_internal.h; path = src/der_plist_internal.h; sourceTree = ""; }; - DC0BCC611D8C68CF00070CB0 /* der_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_set.c; path = src/der_set.c; sourceTree = ""; }; - DC0BCC621D8C68CF00070CB0 /* der_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = der_set.h; path = src/der_set.h; sourceTree = ""; }; - DC0BCC631D8C68CF00070CB0 /* der_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = der_string.c; path = src/der_string.c; sourceTree = ""; }; - DC0BCC641D8C68CF00070CB0 /* fileIo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fileIo.c; path = src/fileIo.c; sourceTree = ""; }; - DC0BCC651D8C68CF00070CB0 /* fileIo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fileIo.h; path = src/fileIo.h; sourceTree = ""; }; - DC0BCC661D8C68CF00070CB0 /* sqlutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sqlutils.h; path = src/sqlutils.h; sourceTree = ""; }; - DC0BCC671D8C68CF00070CB0 /* iOSforOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = iOSforOSX.h; path = src/iOSforOSX.h; sourceTree = ""; }; - DC0BCC681D8C68CF00070CB0 /* iOSforOSX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = iOSforOSX.c; path = src/iOSforOSX.c; sourceTree = ""; }; - DC0BCC691D8C68CF00070CB0 /* iOSforOSX-SecAttr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "iOSforOSX-SecAttr.c"; path = "src/iOSforOSX-SecAttr.c"; sourceTree = ""; }; - DC0BCC6A1D8C68CF00070CB0 /* iOSforOSX-SecRandom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "iOSforOSX-SecRandom.c"; path = "src/iOSforOSX-SecRandom.c"; sourceTree = ""; }; - DC0BCC6B1D8C68CF00070CB0 /* SecDb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; name = SecDb.c; path = src/SecDb.c; sourceTree = ""; }; - DC0BCC6C1D8C68CF00070CB0 /* SecDb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecDb.h; path = src/SecDb.h; sourceTree = ""; }; - DC0BCC6D1D8C68CF00070CB0 /* SecFileLocations.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecFileLocations.c; path = src/SecFileLocations.c; sourceTree = ""; }; - DC0BCC6E1D8C68CF00070CB0 /* SecFileLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecFileLocations.h; path = src/SecFileLocations.h; sourceTree = ""; }; - DC0BCC6F1D8C68CF00070CB0 /* SecXPCError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecXPCError.h; path = src/SecXPCError.h; sourceTree = ""; }; - DC0BCC701D8C68CF00070CB0 /* SecXPCError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecXPCError.c; path = src/SecXPCError.c; sourceTree = ""; }; - DC0BCC711D8C68CF00070CB0 /* simulate_crash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = simulate_crash.c; path = src/simulate_crash.c; sourceTree = ""; }; - DC0BCC721D8C68CF00070CB0 /* SecSCTUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecSCTUtils.h; path = src/SecSCTUtils.h; sourceTree = ""; }; - DC0BCC731D8C68CF00070CB0 /* SecSCTUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecSCTUtils.c; path = src/SecSCTUtils.c; sourceTree = ""; }; - DC0BCC741D8C68CF00070CB0 /* SecAppleAnchor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecAppleAnchor.c; path = src/SecAppleAnchor.c; sourceTree = ""; }; - DC0BCC751D8C68CF00070CB0 /* SecAppleAnchorPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAppleAnchorPriv.h; path = src/SecAppleAnchorPriv.h; sourceTree = ""; }; - DC0BCC761D8C68CF00070CB0 /* SecInternalRelease.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = SecInternalRelease.c; path = src/SecInternalRelease.c; sourceTree = ""; }; - DC0BCC771D8C68CF00070CB0 /* SecInternalReleasePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecInternalReleasePriv.h; path = src/SecInternalReleasePriv.h; sourceTree = ""; }; + DC0BCC3A1D8C68CF00070CB0 /* iCloudKeychainTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iCloudKeychainTrace.c; sourceTree = ""; }; + DC0BCC3B1D8C68CF00070CB0 /* iCloudKeychainTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iCloudKeychainTrace.h; sourceTree = ""; }; + DC0BCC3C1D8C68CF00070CB0 /* SecAKSWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecAKSWrappers.c; sourceTree = ""; }; + DC0BCC3D1D8C68CF00070CB0 /* SecAKSWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecAKSWrappers.h; sourceTree = ""; }; + DC0BCC3E1D8C68CF00070CB0 /* SecBuffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecBuffer.c; sourceTree = ""; }; + DC0BCC3F1D8C68CF00070CB0 /* SecBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecBuffer.h; sourceTree = ""; }; + DC0BCC401D8C68CF00070CB0 /* SecCoreCrypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCoreCrypto.c; sourceTree = ""; }; + DC0BCC411D8C68CF00070CB0 /* SecCoreCrypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCoreCrypto.h; sourceTree = ""; }; + DC0BCC441D8C68CF00070CB0 /* SecCFCCWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFCCWrappers.c; sourceTree = ""; }; + DC0BCC451D8C68CF00070CB0 /* SecCFCCWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCFCCWrappers.h; sourceTree = ""; }; + DC0BCC461D8C68CF00070CB0 /* SecCFRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCFRelease.h; sourceTree = ""; }; + DC0BCC471D8C68CF00070CB0 /* SecCFWrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFWrappers.c; sourceTree = ""; }; + DC0BCC481D8C68CF00070CB0 /* SecCFWrappers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SecCFWrappers.h; sourceTree = ""; }; + DC0BCC491D8C68CF00070CB0 /* SecCFError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCFError.c; sourceTree = ""; }; + DC0BCC4A1D8C68CF00070CB0 /* SecCFError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCFError.h; sourceTree = ""; }; + DC0BCC4B1D8C68CF00070CB0 /* SecDispatchRelease.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDispatchRelease.h; sourceTree = ""; }; + DC0BCC4C1D8C68CF00070CB0 /* SecIOFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecIOFormat.h; sourceTree = ""; }; + DC0BCC4D1D8C68CF00070CB0 /* SecTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecTrace.c; sourceTree = ""; }; + DC0BCC4E1D8C68CF00070CB0 /* SecTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecTrace.h; sourceTree = ""; }; + DC0BCC4F1D8C68CF00070CB0 /* array_size.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array_size.h; sourceTree = ""; }; + DC0BCC521D8C68CF00070CB0 /* debugging.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = debugging.c; sourceTree = ""; }; + DC0BCC531D8C68CF00070CB0 /* debugging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = debugging.h; sourceTree = ""; }; + DC0BCC541D8C68CF00070CB0 /* debugging_test.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugging_test.h; sourceTree = ""; }; + DC0BCC551D8C68CF00070CB0 /* der_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_array.c; sourceTree = ""; }; + DC0BCC561D8C68CF00070CB0 /* der_boolean.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_boolean.c; sourceTree = ""; }; + DC0BCC571D8C68CF00070CB0 /* der_null.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_null.c; sourceTree = ""; }; + DC0BCC581D8C68CF00070CB0 /* der_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_data.c; sourceTree = ""; }; + DC0BCC591D8C68CF00070CB0 /* der_date.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = der_date.c; sourceTree = ""; }; + DC0BCC5A1D8C68CF00070CB0 /* der_date.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = der_date.h; sourceTree = ""; }; + DC0BCC5B1D8C68CF00070CB0 /* der_dictionary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_dictionary.c; sourceTree = ""; }; + DC0BCC5C1D8C68CF00070CB0 /* der_number.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_number.c; sourceTree = ""; }; + DC0BCC5D1D8C68CF00070CB0 /* der_plist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_plist.c; sourceTree = ""; }; + DC0BCC5F1D8C68CF00070CB0 /* der_plist_internal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_plist_internal.c; sourceTree = ""; }; + DC0BCC601D8C68CF00070CB0 /* der_plist_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = der_plist_internal.h; sourceTree = ""; }; + DC0BCC611D8C68CF00070CB0 /* der_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_set.c; sourceTree = ""; }; + DC0BCC621D8C68CF00070CB0 /* der_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = der_set.h; sourceTree = ""; }; + DC0BCC631D8C68CF00070CB0 /* der_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = der_string.c; sourceTree = ""; }; + DC0BCC641D8C68CF00070CB0 /* fileIo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fileIo.c; sourceTree = ""; }; + DC0BCC651D8C68CF00070CB0 /* fileIo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fileIo.h; sourceTree = ""; }; + DC0BCC661D8C68CF00070CB0 /* sqlutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = sqlutils.h; sourceTree = ""; }; + DC0BCC671D8C68CF00070CB0 /* iOSforOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSforOSX.h; sourceTree = ""; }; + DC0BCC681D8C68CF00070CB0 /* iOSforOSX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iOSforOSX.c; sourceTree = ""; }; + DC0BCC691D8C68CF00070CB0 /* iOSforOSX-SecAttr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "iOSforOSX-SecAttr.c"; sourceTree = ""; }; + DC0BCC6A1D8C68CF00070CB0 /* iOSforOSX-SecRandom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "iOSforOSX-SecRandom.c"; sourceTree = ""; }; + DC0BCC6B1D8C68CF00070CB0 /* SecDb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; lineEnding = 0; path = SecDb.c; sourceTree = ""; }; + DC0BCC6C1D8C68CF00070CB0 /* SecDb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecDb.h; sourceTree = ""; }; + DC0BCC6D1D8C68CF00070CB0 /* SecFileLocations.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecFileLocations.c; sourceTree = ""; }; + DC0BCC6E1D8C68CF00070CB0 /* SecFileLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecFileLocations.h; sourceTree = ""; }; + DC0BCC6F1D8C68CF00070CB0 /* SecXPCError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecXPCError.h; sourceTree = ""; }; + DC0BCC701D8C68CF00070CB0 /* SecXPCError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecXPCError.c; sourceTree = ""; }; + DC0BCC711D8C68CF00070CB0 /* simulate_crash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = simulate_crash.c; sourceTree = ""; }; + DC0BCC721D8C68CF00070CB0 /* SecSCTUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecSCTUtils.h; sourceTree = ""; }; + DC0BCC731D8C68CF00070CB0 /* SecSCTUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecSCTUtils.c; sourceTree = ""; }; + DC0BCC741D8C68CF00070CB0 /* SecAppleAnchor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecAppleAnchor.c; sourceTree = ""; }; + DC0BCC751D8C68CF00070CB0 /* SecAppleAnchorPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecAppleAnchorPriv.h; sourceTree = ""; }; + DC0BCC761D8C68CF00070CB0 /* SecInternalRelease.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecInternalRelease.c; sourceTree = ""; }; + DC0BCC771D8C68CF00070CB0 /* SecInternalReleasePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecInternalReleasePriv.h; sourceTree = ""; }; DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libutilitiesRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC0BCD491D8C697100070CB0 /* utilities_regressions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utilities_regressions.h; sourceTree = ""; }; DC0BCD4A1D8C697100070CB0 /* su-05-cfwrappers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-05-cfwrappers.c"; sourceTree = ""; }; @@ -10995,8 +13380,14 @@ DC0BCD551D8C697100070CB0 /* su-40-secdb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-40-secdb.c"; sourceTree = ""; }; DC0BCD561D8C697100070CB0 /* su-41-secdb-stress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "su-41-secdb-stress.c"; sourceTree = ""; }; DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = not_on_this_platorm.c; sourceTree = ""; }; - DC124DC120059B8700BE8DAC /* OctagonControlServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OctagonControlServer.h; path = ot/OctagonControlServer.h; sourceTree = ""; }; - DC124DC220059B8700BE8DAC /* OctagonControlServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OctagonControlServer.m; path = ot/OctagonControlServer.m; sourceTree = ""; }; + DC0BD4EF21BB05F2006B9154 /* CKKSKeychainBackedKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSKeychainBackedKey.h; sourceTree = ""; }; + DC0BD4F021BB05F2006B9154 /* CKKSKeychainBackedKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSKeychainBackedKey.m; sourceTree = ""; }; + DC0EF8EF208697C600AB9E95 /* tpctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tpctl; sourceTree = BUILT_PRODUCTS_DIR; }; + DC0EF8F1208697C600AB9E95 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + DC0FA6AE2291F63F00FE01C4 /* OctagonPendingFlag.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonPendingFlag.h; sourceTree = ""; }; + DC0FA6AF2291F63F00FE01C4 /* OctagonPendingFlag.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonPendingFlag.m; sourceTree = ""; }; + DC124DC120059B8700BE8DAC /* OctagonControlServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonControlServer.h; sourceTree = ""; }; + DC124DC220059B8700BE8DAC /* OctagonControlServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonControlServer.m; sourceTree = ""; }; DC1447881F5764C600236DB4 /* CKKSResultOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSResultOperation.h; sourceTree = ""; }; DC1447891F5764C600236DB4 /* CKKSResultOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSResultOperation.m; sourceTree = ""; }; DC1447941F5766D200236DB4 /* NSOperationCategories.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSOperationCategories.h; sourceTree = ""; }; @@ -11004,8 +13395,6 @@ DC15F7641E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSHealKeyHierarchyOperation.h; sourceTree = ""; }; DC15F7651E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSHealKeyHierarchyOperation.m; sourceTree = ""; }; DC15F79B1E68EAD5003B9A40 /* CKKSTests+API.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+API.m"; sourceTree = ""; }; - DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_smime.xcodeproj; path = OSX/libsecurity_smime/libsecurity_smime.xcodeproj; sourceTree = ""; }; - DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libsecurity_cms.xcodeproj; path = OSX/libsecurity_cms/libsecurity_cms.xcodeproj; sourceTree = ""; }; DC1785111D77895A00B50D50 /* oidsalg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsalg.h; path = OSX/libsecurity_asn1/lib/oidsalg.h; sourceTree = ""; }; DC1785121D77895A00B50D50 /* oidsattr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = oidsattr.h; path = OSX/libsecurity_asn1/lib/oidsattr.h; sourceTree = ""; }; DC1785131D77895A00B50D50 /* SecAsn1Coder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecAsn1Coder.h; path = OSX/libsecurity_asn1/lib/SecAsn1Coder.h; sourceTree = ""; }; @@ -11062,8 +13451,6 @@ DC1785831D778B7F00B50D50 /* SecCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCode.h; path = lib/SecCode.h; sourceTree = ""; }; DC1785851D778B8000B50D50 /* SecRequirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRequirement.h; path = lib/SecRequirement.h; sourceTree = ""; }; DC1785861D778B8000B50D50 /* SecStaticCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecStaticCode.h; path = lib/SecStaticCode.h; sourceTree = ""; }; - DC17858E1D778B9D00B50D50 /* CMSDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSDecoder.h; path = OSX/libsecurity_cms/lib/CMSDecoder.h; sourceTree = ""; }; - DC17858F1D778B9D00B50D50 /* CMSEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSEncoder.h; path = OSX/libsecurity_cms/lib/CMSEncoder.h; sourceTree = ""; }; DC1785981D778C5300B50D50 /* cssmapple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = cssmapple.h; path = cssm/cssmapple.h; sourceTree = ""; }; DC1785A31D778D0D00B50D50 /* CipherSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CipherSuite.h; path = OSX/libsecurity_ssl/lib/CipherSuite.h; sourceTree = ""; }; DC1785A41D778D0D00B50D50 /* SecureTransport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureTransport.h; path = OSX/libsecurity_ssl/lib/SecureTransport.h; sourceTree = ""; }; @@ -11073,23 +13460,6 @@ DC1786F71D778F2500B50D50 /* SecTransformInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecTransformInternal.h; path = OSX/libsecurity_transform/lib/SecTransformInternal.h; sourceTree = ""; }; DC1786FB1D778F3C00B50D50 /* sslTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sslTypes.h; path = OSX/libsecurity_ssl/lib/sslTypes.h; sourceTree = ""; }; DC1786FD1D778F5000B50D50 /* SecureTransportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureTransportPriv.h; path = OSX/libsecurity_ssl/lib/SecureTransportPriv.h; sourceTree = ""; }; - DC1787001D778FA900B50D50 /* SecCMS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCMS.h; sourceTree = ""; }; - DC1787011D778FA900B50D50 /* SecCmsBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsBase.h; sourceTree = ""; }; - DC1787021D778FA900B50D50 /* SecCmsContentInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsContentInfo.h; sourceTree = ""; }; - DC1787031D778FA900B50D50 /* SecCmsDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsDecoder.h; sourceTree = ""; }; - DC1787041D778FA900B50D50 /* SecCmsDigestContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestContext.h; sourceTree = ""; }; - DC1787051D778FA900B50D50 /* SecCmsDigestedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestedData.h; sourceTree = ""; }; - DC1787061D778FA900B50D50 /* SecCmsEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsEncoder.h; sourceTree = ""; }; - DC1787071D778FA900B50D50 /* SecCmsEncryptedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsEncryptedData.h; sourceTree = ""; }; - DC1787081D778FA900B50D50 /* SecCmsEnvelopedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsEnvelopedData.h; sourceTree = ""; }; - DC1787091D778FA900B50D50 /* SecCmsMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsMessage.h; sourceTree = ""; }; - DC17870A1D778FA900B50D50 /* SecCmsRecipientInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsRecipientInfo.h; sourceTree = ""; }; - DC17870B1D778FA900B50D50 /* SecCmsSignedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsSignedData.h; sourceTree = ""; }; - DC17870C1D778FA900B50D50 /* SecCmsSignerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCmsSignerInfo.h; sourceTree = ""; }; - DC17870D1D778FA900B50D50 /* SecSMIME.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecSMIME.h; sourceTree = ""; }; - DC17870E1D778FA900B50D50 /* tsaSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsaSupport.h; sourceTree = ""; }; - DC17870F1D778FA900B50D50 /* tsaSupportPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsaSupportPriv.h; sourceTree = ""; }; - DC1787101D778FA900B50D50 /* tsaTemplates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsaTemplates.h; sourceTree = ""; }; DC1787221D778FC900B50D50 /* mdspriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mdspriv.h; path = OSX/libsecurity_mds/lib/mdspriv.h; sourceTree = ""; }; DC1787241D778FDE00B50D50 /* SecManifest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecManifest.h; path = OSX/libsecurity_manifest/lib/SecManifest.h; sourceTree = ""; }; DC1787251D778FDE00B50D50 /* SecureDownloadInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureDownloadInternal.h; path = OSX/libsecurity_manifest/lib/SecureDownloadInternal.h; sourceTree = ""; }; @@ -11113,7 +13483,6 @@ DC1787481D7790A500B50D50 /* SecCodeSigner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecCodeSigner.h; path = lib/SecCodeSigner.h; sourceTree = ""; }; DC17874B1D7790A500B50D50 /* SecRequirementPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecRequirementPriv.h; path = lib/SecRequirementPriv.h; sourceTree = ""; }; DC17874C1D7790A500B50D50 /* SecStaticCodePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecStaticCodePriv.h; path = lib/SecStaticCodePriv.h; sourceTree = ""; }; - DC1787581D7790B600B50D50 /* CMSPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CMSPrivate.h; path = OSX/libsecurity_cms/lib/CMSPrivate.h; sourceTree = ""; }; DC17875B1D7790CE00B50D50 /* checkpw.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = checkpw.h; path = OSX/libsecurity_checkpw/lib/checkpw.h; sourceTree = ""; }; DC17875D1D7790E500B50D50 /* AuthorizationPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AuthorizationPriv.h; path = OSX/libsecurity_authorization/lib/AuthorizationPriv.h; sourceTree = ""; }; DC17875E1D7790E500B50D50 /* AuthorizationTagsPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AuthorizationTagsPriv.h; path = OSX/libsecurity_authorization/lib/AuthorizationTagsPriv.h; sourceTree = ""; }; @@ -11158,17 +13527,19 @@ DC178A1D1D77A1E700B50D50 /* tp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = tp_primary.mdsinfo; path = OSX/libsecurity_apple_x509_tp/mds/tp_primary.mdsinfo; sourceTree = ""; }; DC178A1E1D77A1E700B50D50 /* sd_cspdl_common.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = sd_cspdl_common.mdsinfo; path = OSX/libsecurity_sd_cspdl/mds/sd_cspdl_common.mdsinfo; sourceTree = ""; }; DC178A311D77A1F500B50D50 /* FDEPrefs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = FDEPrefs.plist; path = OSX/lib/FDEPrefs.plist; sourceTree = ""; }; - DC178A321D77A1F500B50D50 /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; - DC178A341D77A1F500B50D50 /* SecErrorMessages.strings */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = SecErrorMessages.strings; path = derived_src/en.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; + DC178A321D77A1F500B50D50 /* SecDebugErrorMessages.strings */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; fileEncoding = 10; name = SecDebugErrorMessages.strings; path = derived_src/SecDebugErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; + DC178A341D77A1F500B50D50 /* SecErrorMessages.strings */ = {isa = PBXFileReference; explicitFileType = text.plist.strings; fileEncoding = 10; name = SecErrorMessages.strings; path = derived_src/en.lproj/SecErrorMessages.strings; sourceTree = BUILT_PRODUCTS_DIR; }; DC178A351D77A1F500B50D50 /* framework.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = framework.sb; path = OSX/lib/framework.sb; sourceTree = ""; }; DC178A391D77A1F500B50D50 /* en */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = en; path = OSX/lib/en.lproj/InfoPlist.strings; sourceTree = ""; }; DC178A3A1D77A1F500B50D50 /* TimeStampingPrefs.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = TimeStampingPrefs.plist; path = OSX/lib/TimeStampingPrefs.plist; sourceTree = ""; }; - DC178A3C1D77A1F500B50D50 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = "OSX/lib/en.lproj/authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings"; sourceTree = ""; }; + DC178A3C1D77A1F500B50D50 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/lib/en.lproj/authorization.dfr.prompts.strings; sourceTree = ""; }; DC178A3E1D77A1F500B50D50 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/lib/en.lproj/authorization.buttons.strings; sourceTree = ""; }; DC178A401D77A1F500B50D50 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = OSX/lib/en.lproj/authorization.prompts.strings; sourceTree = ""; }; DC178BB11D77A5F500B50D50 /* security_framework_macos.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = security_framework_macos.xcconfig; path = OSX/config/security_framework_macos.xcconfig; sourceTree = ""; }; DC18F76D1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSFetchAllRecordZoneChangesOperation.h; sourceTree = ""; }; DC18F76E1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSFetchAllRecordZoneChangesOperation.m; sourceTree = ""; }; + DC19484A21812EC5007C2260 /* OTDeviceInformationAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTDeviceInformationAdapter.h; sourceTree = ""; }; + DC19484B21812EC5007C2260 /* OTDeviceInformationAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTDeviceInformationAdapter.m; sourceTree = ""; }; DC1DA65C1E4554620094CE7F /* CKKSScanLocalItemsOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSScanLocalItemsOperation.h; sourceTree = ""; }; DC1DA6671E4555D80094CE7F /* CKKSScanLocalItemsOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSScanLocalItemsOperation.m; sourceTree = ""; }; DC1ED8BA1DD51883002BDCFA /* CKKSItemEncrypter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSItemEncrypter.m; sourceTree = ""; }; @@ -11177,7 +13548,8 @@ DC1ED8C51DD55476002BDCFA /* CKKS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKS.m; sourceTree = ""; }; DC207EB61ED4EAB600D46873 /* CKKSLockStateTracker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSLockStateTracker.h; sourceTree = ""; }; DC207EB71ED4EAB600D46873 /* CKKSLockStateTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLockStateTracker.m; sourceTree = ""; }; - DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_ios_NO_AKS.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DC221BA92267E2A60068DBCF /* OTUpdateTPHOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTUpdateTPHOperation.h; sourceTree = ""; }; + DC221BAA2267E2A60068DBCF /* OTUpdateTPHOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTUpdateTPHOperation.m; sourceTree = ""; }; DC222C891E089BAE00B09171 /* CKKSSQLTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSSQLTests.m; sourceTree = ""; }; DC222CA61E08A7D900B09171 /* CloudKitMockXCTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CloudKitMockXCTest.h; sourceTree = ""; }; DC222CA71E08A7D900B09171 /* CloudKitMockXCTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CloudKitMockXCTest.m; sourceTree = ""; }; @@ -11222,9 +13594,20 @@ 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 = ""; }; DC24B5851DA432E900330B48 /* CloudKeychainProxy.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CloudKeychainProxy.8; path = OSX/sec/CloudKeychainProxy/CloudKeychainProxy.8; sourceTree = ""; }; + DC26666821CAC32700F19960 /* OTControlCLI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTControlCLI.h; sourceTree = ""; }; + DC26666921CAC32700F19960 /* OTControlCLI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTControlCLI.m; sourceTree = ""; }; DC27B57D1DDFC24500599261 /* libsqlite3.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.0.dylib; path = usr/lib/libsqlite3.0.dylib; sourceTree = SDKROOT; }; + DC27C3C020EAD9C300F7839C /* OctagonTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OctagonTests.swift; sourceTree = ""; }; + DC27C3C820EADD8200F7839C /* OctagonTests-BridgingHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OctagonTests-BridgingHeader.h"; sourceTree = ""; }; + DC2819B822F8F6FE007829F5 /* OctagonTests+DeviceList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+DeviceList.swift"; sourceTree = ""; }; + DC2B9A5023147A3800D4C79D /* TPMachineID.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPMachineID.h; sourceTree = ""; }; + DC2B9A5123147A3800D4C79D /* TPMachineID.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPMachineID.m; sourceTree = ""; }; DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSNotifier.h; sourceTree = ""; }; DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSNotifier.m; sourceTree = ""; }; + DC311E772124B8A8002F5EAE /* libaks_real_witness.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libaks_real_witness.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DC311E782124B8EF002F5EAE /* aks_real_witness.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = aks_real_witness.h; sourceTree = ""; }; + DC311E792124B8EF002F5EAE /* aks_real_witness.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = aks_real_witness.c; sourceTree = ""; }; + DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = swift_binary.xcconfig; path = xcconfig/swift_binary.xcconfig; sourceTree = ""; }; DC3502B51E0208BE00BC0587 /* CKKSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CKKSTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DC3502B71E0208BE00BC0587 /* CKKSTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSTests.m; sourceTree = ""; }; DC3502B91E0208BE00BC0587 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -11232,33 +13615,47 @@ DC3502E51E0214C800BC0587 /* MockCloudKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MockCloudKit.h; sourceTree = ""; }; DC3502E61E0214C800BC0587 /* MockCloudKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MockCloudKit.m; sourceTree = ""; }; DC3502E81E02172C00BC0587 /* OCMock.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OCMock.framework; path = ../../AppleInternal/Library/Frameworks/OCMock.framework; sourceTree = SDKROOT; }; + DC36895E21235F42003A3735 /* libaks_mock.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libaks_mock.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC378B2C1DEF9DF000A3DAFA /* CKKSMirrorEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSMirrorEntry.h; sourceTree = ""; }; DC378B2E1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSMirrorEntry.m; sourceTree = ""; }; DC378B361DEFADB500A3DAFA /* CKKSZoneStateEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSZoneStateEntry.h; sourceTree = ""; }; DC378B371DEFADB500A3DAFA /* CKKSZoneStateEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSZoneStateEntry.m; sourceTree = ""; }; DC378B3A1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSIncomingQueueEntry.h; sourceTree = ""; }; DC378B3B1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSIncomingQueueEntry.m; sourceTree = ""; }; + DC391F9921BF2F4B00772585 /* CKKSConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSConstants.m; sourceTree = ""; }; + DC391FA521C04D1500772585 /* OctagonPeerKeys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OctagonPeerKeys.swift; sourceTree = ""; }; DC3A4B581D91E9FB00E46D4A /* com.apple.CodeSigningHelper.xpc */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.apple.CodeSigningHelper.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; DC3A4B5F1D91EAC500E46D4A /* CodeSigningHelper-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "CodeSigningHelper-Info.plist"; sourceTree = ""; }; DC3A4B601D91EAC500E46D4A /* com.apple.CodeSigningHelper.sb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = com.apple.CodeSigningHelper.sb; sourceTree = ""; }; DC3A4B621D91EAC500E46D4A /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = ""; usesTabs = 1; }; DC3A81D41D99D567000C7419 /* libcoretls_cfhelpers.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcoretls_cfhelpers.dylib; path = usr/lib/libcoretls_cfhelpers.dylib; sourceTree = SDKROOT; }; + DC3AA27C2097DF94007CA68A /* security_tool_commands_table.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = security_tool_commands_table.h; sourceTree = ""; }; + DC3AF52A2229E6C0006577E8 /* CKKSListenerCollection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSListenerCollection.h; sourceTree = ""; }; + DC3AF52B2229E6C0006577E8 /* CKKSListenerCollection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSListenerCollection.m; sourceTree = ""; }; + DC3B222C22C408BE006D915C /* TrustedPeersHelper_2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = TrustedPeersHelper_2.xcdatamodel; sourceTree = ""; }; DC3D748A1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSLocalSynchronizeOperation.h; sourceTree = ""; }; DC3D748B1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLocalSynchronizeOperation.m; sourceTree = ""; }; DC4269031E82EDAC002B7110 /* SecItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecItem.m; sourceTree = ""; }; - DC4269061E82FBDF002B7110 /* server_security_helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = server_security_helpers.c; sourceTree = ""; }; + DC4269061E82FBDF002B7110 /* server_security_helpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = server_security_helpers.m; sourceTree = ""; }; DC4269071E82FBDF002B7110 /* server_security_helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = server_security_helpers.h; sourceTree = ""; }; + DC45D43B22EB619D00CEB6B7 /* OctagonStateMachineObservers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonStateMachineObservers.h; sourceTree = ""; }; + DC45D43C22EB619D00CEB6B7 /* OctagonStateMachineObservers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonStateMachineObservers.m; sourceTree = ""; }; + DC4A76A2221267D4006F2D8F /* EscrowRequestServerHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestServerHelpers.m; sourceTree = ""; }; + DC4A76A4221267FB006F2D8F /* EscrowRequestServerHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestServerHelpers.h; sourceTree = ""; }; + DC4A76A92212698B006F2D8F /* CloudServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudServices.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/CloudServices.framework; sourceTree = DEVELOPER_DIR; }; DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */ = {isa = PBXFileReference; lastKnownFileType = text; path = CKKSSerializedKey.proto; sourceTree = ""; }; DC4DB14E1E24692100CD6769 /* CKKSKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSKey.h; sourceTree = ""; }; DC4DB14F1E24692100CD6769 /* CKKSKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSKey.m; sourceTree = ""; }; DC4DB15E1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSAESSIVEncryptionTests.m; sourceTree = ""; }; + DC5060E920E2D88300925005 /* OTCuttlefishContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTCuttlefishContext.h; sourceTree = ""; }; + DC5060EA20E2D88300925005 /* OTCuttlefishContext.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTCuttlefishContext.m; sourceTree = ""; }; + DC5060F420E2DB9700925005 /* OTCuttlefishContextTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTCuttlefishContextTests.m; sourceTree = ""; }; DC5225091E402D8B0021640A /* PlatformLibraries.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = PlatformLibraries.xcconfig; path = xcconfig/PlatformLibraries.xcconfig; sourceTree = ""; }; DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecurityd_ios.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSecureObjectSyncServer.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DC52EA4C1D80CB7000B0A59C /* libSecurityTool.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSecurityTool.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52EA8E1D80CC2A00B0A59C /* builtin_commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = builtin_commands.h; sourceTree = ""; }; DC52EA8F1D80CC2A00B0A59C /* digest_calc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = digest_calc.c; sourceTree = ""; }; - DC52EA901D80CC2A00B0A59C /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = entitlements.plist; path = OSX/sec/SecurityTool/entitlements.plist; sourceTree = SOURCE_ROOT; }; + DC52EA901D80CC2A00B0A59C /* entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = entitlements.plist; sourceTree = ""; }; DC52EA911D80CC2A00B0A59C /* whoami.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = whoami.m; sourceTree = ""; }; DC52EA921D80CC2A00B0A59C /* syncbubble.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = syncbubble.m; sourceTree = ""; }; DC52EA931D80CC2A00B0A59C /* leaks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = leaks.c; sourceTree = ""; }; @@ -11269,7 +13666,6 @@ DC52EA981D80CC2A00B0A59C /* SecurityTool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecurityTool.c; sourceTree = ""; }; DC52EA991D80CC2A00B0A59C /* SecurityTool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityTool.h; sourceTree = ""; }; DC52EA9A1D80CC2A00B0A59C /* tool_errors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tool_errors.h; sourceTree = ""; }; - DC52EBD51D80CEF100B0A59C /* libSecurityCommands.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSecurityCommands.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52EC341D80CFB200B0A59C /* libSOSCommands.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSOSCommands.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSWCAgent.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52EC5C1D80D05200B0A59C /* liblogging.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = liblogging.a; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -11280,12 +13676,16 @@ DC52EDB11D80D58400B0A59C /* libsecdRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libsecdRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52EE411D80D6DD00B0A59C /* libSharedRegressions.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSharedRegressions.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC52EE6E1D80D82600B0A59C /* libSecItemShimOSX.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = libSecItemShimOSX.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DC5681A8224DA05F008F8DEB /* OctagonFlags.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonFlags.h; sourceTree = ""; }; + DC5681A9224DA05F008F8DEB /* OctagonFlags.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonFlags.m; sourceTree = ""; }; DC58C4231D77BDEA003C25A4 /* csparser.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = csparser.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; DC58C43A1D77BED0003C25A4 /* csparser-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "csparser-Info.plist"; path = "OSX/lib/plugins/csparser-Info.plist"; sourceTree = ""; }; DC58C43B1D77BED0003C25A4 /* csparser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = csparser.cpp; path = OSX/lib/plugins/csparser.cpp; sourceTree = ""; }; DC58C43C1D77BED0003C25A4 /* csparser.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; name = csparser.exp; path = OSX/lib/plugins/csparser.exp; sourceTree = ""; }; DC58C4411D77BFA4003C25A4 /* security_macos.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = security_macos.xcconfig; path = OSX/config/security_macos.xcconfig; sourceTree = ""; }; DC59EA731D91CBD0001BDDF5 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; + DC5A01E621BB428500D87AB9 /* CKKSTLKShare.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSTLKShare.h; sourceTree = ""; }; + DC5A01E721BB428500D87AB9 /* CKKSTLKShare.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSTLKShare.m; sourceTree = ""; }; DC5ABD781D832D5800CF422C /* srCdsaUtils.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = srCdsaUtils.cpp; sourceTree = ""; }; DC5ABD791D832D5800CF422C /* srCdsaUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = srCdsaUtils.h; sourceTree = ""; }; DC5ABD7A1D832D5800CF422C /* createFVMaster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = createFVMaster.c; sourceTree = ""; }; @@ -11418,8 +13818,6 @@ DC5ABFBE1D83511A00CF422C /* clientid.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = clientid.cpp; sourceTree = ""; }; DC5ABFBF1D83511A00CF422C /* codesigdb.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = codesigdb.h; sourceTree = ""; }; DC5ABFC01D83511A00CF422C /* codesigdb.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = codesigdb.cpp; sourceTree = ""; }; - DC5ABFC21D83511A00CF422C /* csproxy.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = csproxy.h; sourceTree = ""; }; - DC5ABFC31D83511A00CF422C /* csproxy.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = csproxy.cpp; sourceTree = ""; }; DC5ABFC51D83511A00CF422C /* agentclient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = agentclient.h; sourceTree = ""; }; DC5ABFC61D83511A00CF422C /* agentquery.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = agentquery.h; sourceTree = ""; }; DC5ABFC71D83511A00CF422C /* agentquery.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = agentquery.cpp; sourceTree = ""; }; @@ -11456,8 +13854,13 @@ DC5BB4FD1E0C98320010F836 /* CKKSOutgoingQueueOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSOutgoingQueueOperation.m; sourceTree = ""; }; DC5BCC461E5380EA00649140 /* SecArgParse.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SecArgParse.c; path = lib/SecArgParse.c; sourceTree = ""; }; DC5BCC471E5380EA00649140 /* SecArgParse.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecArgParse.h; path = lib/SecArgParse.h; sourceTree = ""; }; + DC5BEACC2217509A001681F0 /* OctagonTests+CloudKitAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+CloudKitAccount.swift"; sourceTree = ""; }; + DC5F2BBD2310B941001ADA5D /* OctagonTests+CoreFollowUp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+CoreFollowUp.swift"; sourceTree = ""; }; DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = server_entitlement_helpers.c; sourceTree = ""; }; DC5F35A51EE0F1A900900966 /* server_entitlement_helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = server_entitlement_helpers.h; sourceTree = ""; }; + DC5F65AC2225C22C0051E9FA /* CKKSProvideKeySetOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSProvideKeySetOperation.h; sourceTree = ""; }; + DC5F65AD2225C22C0051E9FA /* CKKSProvideKeySetOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSProvideKeySetOperation.m; sourceTree = ""; }; + DC6063B121B09AB200069B82 /* KCJoiningRequestCircleSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KCJoiningRequestCircleSession.m; sourceTree = ""; }; DC610A341D78F129002223DE /* secdtests */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secdtests; sourceTree = BUILT_PRODUCTS_DIR; }; DC610A3A1D78F228002223DE /* libACM.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libACM.a; path = usr/local/lib/libACM.a; sourceTree = SDKROOT; }; DC610A3C1D78F25C002223DE /* libDiagnosticMessagesClient.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libDiagnosticMessagesClient.dylib; path = usr/lib/libDiagnosticMessagesClient.dylib; sourceTree = SDKROOT; }; @@ -11472,8 +13875,11 @@ 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 = ""; }; + DC614C4F22A9BDB500E16ADA /* CKKSZoneModifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSZoneModifier.h; sourceTree = ""; }; + DC614C5022A9BDB500E16ADA /* CKKSZoneModifier.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSZoneModifier.m; sourceTree = ""; }; + DC62DC6B22A87128000D2D5D /* CKKSTests+MultiZone.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+MultiZone.m"; sourceTree = ""; }; + DC62DC6E22A8721C000D2D5D /* CKKSTests+MultiZone.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CKKSTests+MultiZone.h"; 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 = ""; }; @@ -11512,7 +13918,6 @@ DC6A82771D87733C00418608 /* ss_types.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; path = ss_types.defs; sourceTree = ""; }; DC6A82781D87733C00418608 /* ucsp.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; path = ucsp.defs; sourceTree = ""; }; DC6A82791D87733C00418608 /* ucspNotify.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; path = ucspNotify.defs; sourceTree = ""; }; - DC6A827A1D87733C00418608 /* cshosting.defs */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.mig; path = cshosting.defs; sourceTree = ""; }; DC6A827D1D87734600418608 /* ucsp.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ucsp.h; path = derived_src/securityd_client/ucsp.h; sourceTree = BUILT_PRODUCTS_DIR; }; DC6A827E1D87734600418608 /* ucspNotify.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ucspNotify.h; path = derived_src/securityd_client/ucspNotify.h; sourceTree = BUILT_PRODUCTS_DIR; }; DC6A827F1D87734600418608 /* ucspClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ucspClient.cpp; path = derived_src/securityd_client/ucspClient.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -11520,24 +13925,47 @@ DC6A82811D87734600418608 /* ucspServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ucspServer.cpp; path = derived_src/securityd_client/ucspServer.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; DC6A82821D87734600418608 /* ucspNotifySender.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ucspNotifySender.cpp; path = derived_src/securityd_client/ucspNotifySender.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; DC6A82831D87734600418608 /* ucspNotifyReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ucspNotifyReceiver.cpp; path = derived_src/securityd_client/ucspNotifyReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; - DC6A82841D87734600418608 /* cshosting.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cshosting.h; path = derived_src/securityd_client/cshosting.h; sourceTree = BUILT_PRODUCTS_DIR; }; - DC6A82851D87734600418608 /* cshostingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = cshostingClient.cpp; path = derived_src/securityd_client/cshostingClient.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; - DC6A82861D87734600418608 /* cshostingServer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = cshostingServer.cpp; path = derived_src/securityd_client/cshostingServer.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; DC6A82921D87749900418608 /* libsecurityd_client.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurityd_client.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC6ACC401E81DF9400125DC5 /* server_endpoint.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = server_endpoint.m; sourceTree = ""; }; + DC6DE897213076C000C6B56D /* OTSOSUpgradeOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTSOSUpgradeOperation.h; sourceTree = ""; }; + DC6DE898213076C000C6B56D /* OTSOSUpgradeOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTSOSUpgradeOperation.m; sourceTree = ""; }; + DC7181062089172F00B2CB13 /* TrustedPeersHelper-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "TrustedPeersHelper-entitlements.plist"; sourceTree = ""; }; DC71D8DD1D94CF3C0065FB93 /* lib_ios_shim.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = lib_ios_shim.xcconfig; path = xcconfig/lib_ios_shim.xcconfig; sourceTree = ""; }; - DC71D9DF1D95BA6C0065FB93 /* libASN1.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libASN1.a; sourceTree = BUILT_PRODUCTS_DIR; }; - DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSTLKShare.h; sourceTree = ""; }; - DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSTLKShare.m; sourceTree = ""; }; + DC72502D229600A800493D88 /* OctagonTests+Reset.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+Reset.swift"; sourceTree = ""; }; + DC7250352296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTResetCKKSZonesLackingTLKsOperation.h; sourceTree = ""; }; + DC7250362296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTResetCKKSZonesLackingTLKsOperation.m; sourceTree = ""; }; + DC730E15224011D60051DD48 /* TPPBDictionaryMatchingRule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBDictionaryMatchingRule.m; sourceTree = ""; }; + DC730E16224011D70051DD48 /* TPPBDictionaryMatchingRule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBDictionaryMatchingRule.h; sourceTree = ""; }; + DC730E17224011D80051DD48 /* TPPBDictionaryMatchingRuleFieldExists.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBDictionaryMatchingRuleFieldExists.m; sourceTree = ""; }; + DC730E18224011D90051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBDictionaryMatchingRuleFieldRegexMatch.h; sourceTree = ""; }; + DC730E19224011DB0051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBDictionaryMatchingRuleFieldRegexMatch.m; sourceTree = ""; }; + DC730E1A224011DD0051DD48 /* TPPBDictionaryMatchingRuleFieldExists.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBDictionaryMatchingRuleFieldExists.h; sourceTree = ""; }; + DC7341F11F8447AB00AB9BDF /* CKKSTLKShareRecord.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSTLKShareRecord.h; sourceTree = ""; }; + DC7341F21F8447AB00AB9BDF /* CKKSTLKShareRecord.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSTLKShareRecord.m; sourceTree = ""; }; DC7341FD1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSTLKSharingEncryptionTests.m; sourceTree = ""; }; + DC751A0C211E02B100C18042 /* OTAccountMetadataClassC.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = OTAccountMetadataClassC.proto; sourceTree = ""; }; + DC754C712228B57B00A39C8E /* TrustedPeersHelperProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TrustedPeersHelperProtocol.m; sourceTree = ""; }; DC762A9C1E57A86A00B03A2C /* CKKSRecordHolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSRecordHolder.h; sourceTree = ""; }; DC762A9D1E57A86A00B03A2C /* CKKSRecordHolder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSRecordHolder.m; sourceTree = ""; }; + DC79572C21EEB62400761E21 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; DC797E131DD3F88300CC9E42 /* CKKSSQLDatabaseObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSSQLDatabaseObject.m; sourceTree = ""; }; DC797E191DD3F89E00CC9E42 /* CKKSSQLDatabaseObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSSQLDatabaseObject.h; sourceTree = ""; }; DC7A17EB1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSProcessReceivedKeysOperation.h; sourceTree = ""; }; DC7A17EC1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSProcessReceivedKeysOperation.m; sourceTree = ""; }; + DC7EB920211E17E500516452 /* OTAccountMetadataClassC+KeychainSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OTAccountMetadataClassC+KeychainSupport.h"; sourceTree = ""; }; + DC7EB921211E17E500516452 /* OTAccountMetadataClassC+KeychainSupport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "OTAccountMetadataClassC+KeychainSupport.m"; sourceTree = ""; }; + DC7EB928211E20DF00516452 /* OctagonDataPersistenceTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OctagonDataPersistenceTests.swift; sourceTree = ""; }; + DC7F79B522EA4ED4001FB69A /* OctagonTests+CKKS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+CKKS.swift"; sourceTree = ""; }; + DC7F79B822EA5C72001FB69A /* OTLocalCKKSResetOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTLocalCKKSResetOperation.h; sourceTree = ""; }; + DC7F79B922EA5C72001FB69A /* OTLocalCKKSResetOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTLocalCKKSResetOperation.m; sourceTree = ""; }; + DC7FC44321EE6F7B003C39B8 /* Security.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Security.plist; sourceTree = ""; }; + DC7FC44821EE914C003C39B8 /* FeatureFlagsPlist.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FeatureFlagsPlist.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; DC844AEC1E81F315007AAB71 /* client_endpoint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = client_endpoint.m; sourceTree = ""; }; - DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libASN1_not_installed.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DC85687C2284E7850088D3EF /* OctagonTestMocks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OctagonTestMocks.swift; sourceTree = ""; }; + DC85687F2284E79C0088D3EF /* OctagonEscrowRecoverer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OctagonEscrowRecoverer.h; sourceTree = ""; }; + DC8757F2218D2003000E65F1 /* OTRemovePeersOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTRemovePeersOperation.h; sourceTree = ""; }; + DC8757F3218D2003000E65F1 /* OTRemovePeersOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTRemovePeersOperation.m; sourceTree = ""; }; + DC8834081D8A218F00CE0ACA /* libASN1.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libASN1.a; sourceTree = BUILT_PRODUCTS_DIR; }; DC88340A1D8A21AA00CE0ACA /* SecAsn1Coder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecAsn1Coder.c; sourceTree = ""; }; DC88340C1D8A21AA00CE0ACA /* SecAsn1Templates.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecAsn1Templates.c; sourceTree = ""; }; DC88340F1D8A21AA00CE0ACA /* certExtensionTemplates.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = certExtensionTemplates.c; sourceTree = ""; }; @@ -11594,20 +14022,35 @@ 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 = ""; }; + DC88466922373A4000738068 /* TPPBDictionaryMatchingRule.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = TPPBDictionaryMatchingRule.proto; sourceTree = ""; }; + DC88466C2237407500738068 /* TPDictionaryMatchingRuleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPDictionaryMatchingRuleTests.m; sourceTree = ""; }; + DC88467F2237431400738068 /* TPDictionaryMatchingRules.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPDictionaryMatchingRules.h; sourceTree = ""; }; + DC8846802237431400738068 /* TPDictionaryMatchingRules.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPDictionaryMatchingRules.m; 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 = ""; }; + DC9061B822B02BA30071474D /* TPTypes.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPTypes.m; 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 = ""; }; + DC90A4C021F27680001300EB /* SecEscrowRequest.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecEscrowRequest.h; sourceTree = ""; }; + DC90A4C121F27680001300EB /* SecEscrowRequest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecEscrowRequest.m; sourceTree = ""; }; + DC90A4C621F279D4001300EB /* SecEscrowPendingRecord.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = SecEscrowPendingRecord.proto; sourceTree = ""; }; + DC93F02722387A010072720A /* OTSOSUpdatePreapprovalsOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTSOSUpdatePreapprovalsOperation.h; sourceTree = ""; }; + DC93F02822387A010072720A /* OTSOSUpdatePreapprovalsOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTSOSUpdatePreapprovalsOperation.m; sourceTree = ""; }; DC94BCC81F10448600E07CEB /* CloudKitCategories.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CloudKitCategories.h; sourceTree = ""; }; DC94BCC91F10448600E07CEB /* CloudKitCategories.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CloudKitCategories.m; sourceTree = ""; }; DC976C581E3AC5E50012A6DD /* PlatformFeatures.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = PlatformFeatures.xcconfig; path = xcconfig/PlatformFeatures.xcconfig; sourceTree = ""; }; + DC99B89220EACA470065B73B /* OctagonTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OctagonTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DC99B89320EACA480065B73B /* OctagonTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OctagonTests-Info.plist"; sourceTree = ""; }; DC9A2C5E1EB3F556008FAC27 /* CKKSTests+Coalesce.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+Coalesce.m"; sourceTree = ""; }; DC9B7AE41DCBF604004E9385 /* CKKSOutgoingQueueEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSOutgoingQueueEntry.m; sourceTree = ""; }; DC9B7AE61DCBF651004E9385 /* CKKSOutgoingQueueEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSOutgoingQueueEntry.h; sourceTree = ""; }; + DC9C06672149DFE400C6F7B8 /* OTAuthKitAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTAuthKitAdapter.h; sourceTree = ""; }; + DC9C06682149DFE400C6F7B8 /* OTAuthKitAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTAuthKitAdapter.m; sourceTree = ""; }; DC9C750F1E4BCC5100F1CA0D /* CKKSOperationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSOperationTests.m; sourceTree = ""; }; DC9C95951F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSServerValidationRecoveryTests.m; sourceTree = ""; }; DC9C95B21F79CFD1000D19E5 /* CKKSControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSControl.h; sourceTree = ""; }; DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSControl.m; sourceTree = ""; }; + DC9C98C622E264F30021E29F /* CKKSFetchTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSFetchTests.m; sourceTree = ""; }; DC9EBA231DEE36FE00D0F733 /* ApplePushService.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplePushService.framework; path = System/Library/PrivateFrameworks/ApplePushService.framework; sourceTree = SDKROOT; }; DC9EBA2F1DEE651500D0F733 /* Info-macOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = ""; }; DC9EBA311DEE768000D0F733 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; }; @@ -11619,15 +14062,35 @@ DCA4D1F41E5520550056214F /* CKKSCurrentKeyPointer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSCurrentKeyPointer.m; sourceTree = ""; }; DCA4D2131E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSReencryptOutgoingItemsOperation.h; sourceTree = ""; }; DCA4D2141E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSReencryptOutgoingItemsOperation.m; sourceTree = ""; }; + DCA9BC00221B721D00B4EB26 /* CKKSCloudKitClassDependencies.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSCloudKitClassDependencies.h; sourceTree = ""; }; + DCA9BC01221B721E00B4EB26 /* CKKSCloudKitClassDependencies.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSCloudKitClassDependencies.m; sourceTree = ""; }; + DCA9BC05221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSMockSOSPresentAdapter.h; sourceTree = ""; }; + DCA9BC06221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSMockSOSPresentAdapter.m; sourceTree = ""; }; + DCA9D83B21FFDBA100B27421 /* SecEscrowRequestsTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SecEscrowRequestsTests-Info.plist"; sourceTree = ""; }; + DCA9D83C21FFE50900B27421 /* EscrowRequestXPCServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestXPCServer.m; sourceTree = ""; }; + DCA9D83D21FFE50A00B27421 /* EscrowRequestXPCServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestXPCServer.h; sourceTree = ""; }; + DCA9D83F21FFE62A00B27421 /* EscrowRequestXPCProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestXPCProtocol.h; sourceTree = ""; }; + DCA9D84521FFE7CF00B27421 /* EscrowRequestXPCProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestXPCProtocol.m; sourceTree = ""; }; + DCA9D84B21FFF04600B27421 /* EscrowRequestServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestServer.h; sourceTree = ""; }; + DCA9D84C21FFF04700B27421 /* EscrowRequestServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestServer.m; sourceTree = ""; }; + DCAB17CB21FFF6C400E1DFCF /* MockSynchronousEscrowServer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MockSynchronousEscrowServer.h; sourceTree = ""; }; + DCAB17CC21FFF6C400E1DFCF /* MockSynchronousEscrowServer.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MockSynchronousEscrowServer.m; sourceTree = ""; }; + DCAB17CF2200D26700E1DFCF /* SecEscrowPendingRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecEscrowPendingRecord.h; sourceTree = ""; }; + DCAB17D02200D26800E1DFCF /* SecEscrowPendingRecord.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecEscrowPendingRecord.m; sourceTree = ""; }; + DCAB17D32200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SecEscrowPendingRecord+KeychainSupport.h"; sourceTree = ""; }; + DCAB17D42200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "SecEscrowPendingRecord+KeychainSupport.m"; sourceTree = ""; }; + DCAD8F8422C43EAD007C3872 /* Container_MachineIDs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container_MachineIDs.swift; sourceTree = ""; }; + DCAD8F8A22C55D73007C3872 /* TPPBDispositionDisallowedMachineID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBDispositionDisallowedMachineID.h; sourceTree = ""; }; + DCAD8F8B22C55D75007C3872 /* TPPBDispositionDisallowedMachineID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBDispositionDisallowedMachineID.m; sourceTree = ""; }; 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 = ""; }; + DCB0C28F222F5DF80083AECB /* CuttlefishErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CuttlefishErrors.swift; 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 = ""; }; - DCB332371F46804000178C30 /* SOSSysdiagnose.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSSysdiagnose.h; sourceTree = ""; }; DCB3406D1D8A24DF0054D16E /* libsecurity_authorization.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libsecurity_authorization.a; sourceTree = BUILT_PRODUCTS_DIR; }; DCB3406F1D8A24F70054D16E /* Authorization.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = Authorization.c; path = lib/Authorization.c; sourceTree = ""; }; DCB340761D8A24F70054D16E /* Authorization.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Authorization.cpp; path = lib/Authorization.cpp; sourceTree = ""; }; @@ -11795,8 +14258,6 @@ DCB341D41D8A2BAC0054D16E /* osxverifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osxverifier.h; sourceTree = ""; }; DCB341D51D8A2BAC0054D16E /* u32handleobject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = u32handleobject.cpp; sourceTree = ""; }; DCB341D61D8A2BAC0054D16E /* u32handleobject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = u32handleobject.h; sourceTree = ""; }; - DCB341D71D8A2BAC0054D16E /* uniformrandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = uniformrandom.cpp; sourceTree = ""; }; - DCB341D81D8A2BAC0054D16E /* uniformrandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = uniformrandom.h; sourceTree = ""; }; DCB341D91D8A2BAC0054D16E /* walkers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = walkers.cpp; sourceTree = ""; }; DCB341DA1D8A2BAC0054D16E /* walkers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = walkers.h; sourceTree = ""; }; DCB342311D8A2C6B0054D16E /* KeySchema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeySchema.cpp; sourceTree = ""; }; @@ -11978,8 +14439,16 @@ DCB344701D8A35270054D16E /* si-20-sectrust-provisioning.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "si-20-sectrust-provisioning.h"; path = "regressions/si-20-sectrust-provisioning.h"; sourceTree = ""; }; DCB344711D8A35270054D16E /* si-33-keychain-backup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "si-33-keychain-backup.c"; path = "regressions/si-33-keychain-backup.c"; sourceTree = ""; }; DCB344721D8A35270054D16E /* si-34-one-true-keychain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "si-34-one-true-keychain.c"; path = "regressions/si-34-one-true-keychain.c"; sourceTree = ""; }; + DCB41DF9216C3F8A00F219E0 /* tpctl-entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "tpctl-entitlements.plist"; sourceTree = ""; }; DCB5D9391E4A9A3400BE22AB /* CKKSSynchronizeOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSSynchronizeOperation.h; sourceTree = ""; }; DCB5D93A1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSSynchronizeOperation.m; sourceTree = ""; }; + DCB946AD22FCB88400BE4490 /* OTDetermineHSA2AccountStatusOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTDetermineHSA2AccountStatusOperation.h; sourceTree = ""; }; + DCB946AE22FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTDetermineHSA2AccountStatusOperation.m; sourceTree = ""; }; + DCB9475421274A1900ED9272 /* TPHObjcTranslation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPHObjcTranslation.m; sourceTree = ""; }; + DCB9475721274A4D00ED9272 /* TPHObjcTranslation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPHObjcTranslation.h; sourceTree = ""; }; + DCB947592127534C00ED9272 /* OctagonTests+SOSUpgrade.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+SOSUpgrade.swift"; sourceTree = ""; }; + DCB9475B2127562100ED9272 /* OTSOSAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTSOSAdapter.h; sourceTree = ""; }; + DCB9475C2127562100ED9272 /* OTSOSAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTSOSAdapter.m; sourceTree = ""; }; DCBDB3B01E57C67500B61300 /* CKKSKeychainView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSKeychainView.h; sourceTree = ""; }; DCBDB3B11E57C67500B61300 /* CKKSKeychainView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSKeychainView.m; sourceTree = ""; }; DCBDB3B91E57CA7A00B61300 /* CKKSViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSViewManager.h; sourceTree = ""; }; @@ -11987,9 +14456,21 @@ DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSTLKSharingTests.m; sourceTree = ""; }; 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 = ""; }; + DCBF4AE021FFC82100539F0A /* SecEscrowRequestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecEscrowRequestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + DCBF4AE321FFC9A800539F0A /* SecEscrowRequestTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecEscrowRequestTests.m; sourceTree = ""; }; + DCBFF830222611A200C5C044 /* OTFetchCKKSKeysOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTFetchCKKSKeysOperation.h; sourceTree = ""; }; + DCBFF831222611A200C5C044 /* OTFetchCKKSKeysOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTFetchCKKSKeysOperation.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 = ""; }; + DCC1849220EEEC4400F3B26C /* security_framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = security_framework.xcconfig; path = xcconfig/security_framework.xcconfig; sourceTree = ""; }; + DCC5417F225C05170095D926 /* OTUploadNewCKKSTLKsOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTUploadNewCKKSTLKsOperation.h; sourceTree = ""; }; + DCC54180225C05180095D926 /* OTUploadNewCKKSTLKsOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTUploadNewCKKSTLKsOperation.m; sourceTree = ""; }; DCC5860220BF8A98005C7269 /* SecBase.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecBase.c; sourceTree = ""; }; + DCC5D66B2087FADE00BBC127 /* tpctl-bridging-header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "tpctl-bridging-header.h"; sourceTree = ""; }; + DCC67E0C20DD7E0A00A70A31 /* OTStates.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTStates.h; sourceTree = ""; }; + DCC67E0D20DD7E0A00A70A31 /* OTStates.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTStates.m; sourceTree = ""; }; + DCC67E2B20DDC07900A70A31 /* OTPrepareOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTPrepareOperation.h; sourceTree = ""; }; + DCC67E2C20DDC07900A70A31 /* OTPrepareOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTPrepareOperation.m; sourceTree = ""; }; + DCC67E3120E16F3100A70A31 /* ObjCImprovements.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ObjCImprovements.h; 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 = ""; }; @@ -12003,7 +14484,6 @@ DCC78C411D8085D800865A7C /* secd-20-keychain_upgrade.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-20-keychain_upgrade.m"; sourceTree = ""; }; DCC78C421D8085D800865A7C /* secd-21-transmogrify.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-21-transmogrify.m"; sourceTree = ""; }; DCC78C431D8085D800865A7C /* secd-30-keychain-upgrade.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-30-keychain-upgrade.m"; sourceTree = ""; }; - DCC78C441D8085D800865A7C /* secd-31-keychain-bad.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-31-keychain-bad.m"; sourceTree = ""; }; DCC78C451D8085D800865A7C /* secd-31-keychain-unreadable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-31-keychain-unreadable.m"; sourceTree = ""; }; DCC78C461D8085D800865A7C /* secd-32-restore-bad-backup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-32-restore-bad-backup.m"; sourceTree = ""; }; DCC78C471D8085D800865A7C /* secd-33-keychain-ctk.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-33-keychain-ctk.m"; sourceTree = ""; }; @@ -12215,7 +14695,6 @@ DCC78D891D8085F200865A7C /* SOSCloudCircle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = SOSCloudCircle.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.c; }; DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSCloudCircle.h; sourceTree = ""; }; DCC78D8B1D8085F200865A7C /* SOSCloudCircleInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SOSCloudCircleInternal.h; sourceTree = ""; }; - DCC78D8C1D8085F200865A7C /* SOSSysdiagnose.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSSysdiagnose.m; sourceTree = ""; }; DCC78D8D1D8085F200865A7C /* SOSInternal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSInternal.m; sourceTree = ""; }; DCC78D8E1D8085F200865A7C /* SOSInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSInternal.h; sourceTree = ""; }; DCC78D8F1D8085F200865A7C /* SOSTypes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSTypes.h; sourceTree = ""; }; @@ -12251,12 +14730,7 @@ DCC78DB41D8085FC00865A7C /* si-13-item-system.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-13-item-system.m"; sourceTree = ""; }; DCC78DB51D8085FC00865A7C /* si-14-dateparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-14-dateparse.c"; sourceTree = ""; }; DCC78DB61D8085FC00865A7C /* si-15-delete-access-group.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "si-15-delete-access-group.m"; sourceTree = ""; }; - DCC78DB71D8085FC00865A7C /* si-15-certificate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-15-certificate.c"; sourceTree = ""; }; - DCC78DB81D8085FC00865A7C /* si-16-ec-certificate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-16-ec-certificate.c"; sourceTree = ""; }; DCC78DB91D8085FC00865A7C /* si-17-item-system-bluetooth.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-17-item-system-bluetooth.m"; sourceTree = ""; }; - DCC78DBA1D8085FC00865A7C /* si-20-sectrust-policies.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "si-20-sectrust-policies.m"; path = "../../../../shared_regressions/si-20-sectrust-policies.m"; sourceTree = ""; }; - DCC78DBB1D8085FC00865A7C /* si-20-sectrust.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-20-sectrust.c"; sourceTree = ""; }; - DCC78DBC1D8085FC00865A7C /* si-20-sectrust.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-20-sectrust.h"; sourceTree = ""; }; DCC78DBD1D8085FC00865A7C /* si-21-sectrust-asr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-21-sectrust-asr.c"; sourceTree = ""; }; DCC78DBE1D8085FC00865A7C /* si-22-sectrust-iap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-22-sectrust-iap.c"; sourceTree = ""; }; DCC78DBF1D8085FC00865A7C /* si-22-sectrust-iap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-22-sectrust-iap.h"; sourceTree = ""; }; @@ -12264,7 +14738,6 @@ DCC78DC11D8085FC00865A7C /* si-24-sectrust-digicert-malaysia.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-digicert-malaysia.c"; sourceTree = ""; }; DCC78DC21D8085FC00865A7C /* si-24-sectrust-diginotar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-diginotar.c"; sourceTree = ""; }; DCC78DC31D8085FC00865A7C /* si-24-sectrust-itms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-itms.c"; sourceTree = ""; }; - DCC78DC41D8085FC00865A7C /* si-24-sectrust-nist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-nist.c"; sourceTree = ""; }; DCC78DC51D8085FC00865A7C /* si-24-sectrust-passbook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-24-sectrust-passbook.c"; sourceTree = ""; }; DCC78DC61D8085FC00865A7C /* si-26-sectrust-copyproperties.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-26-sectrust-copyproperties.c"; sourceTree = ""; }; DCC78DC71D8085FC00865A7C /* si-27-sectrust-exceptions.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-27-sectrust-exceptions.c"; sourceTree = ""; }; @@ -12323,20 +14796,12 @@ DCC78E001D8085FC00865A7C /* si_77_SecAccessControl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = si_77_SecAccessControl.c; sourceTree = ""; }; DCC78E011D8085FC00865A7C /* si-78-query-attrs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-78-query-attrs.c"; sourceTree = ""; }; DCC78E021D8085FC00865A7C /* si-80-empty-data.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "si-80-empty-data.c"; sourceTree = ""; }; - DCC78E031D8085FC00865A7C /* si-82-seccertificate-ct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "si-82-seccertificate-ct.c"; path = "../../../../shared_regressions/si-82-seccertificate-ct.c"; sourceTree = ""; }; - DCC78E041D8085FC00865A7C /* si-82-sectrust-ct.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "si-82-sectrust-ct.m"; path = "../../../../shared_regressions/si-82-sectrust-ct.m"; sourceTree = ""; }; DCC78E051D8085FC00865A7C /* si-82-token-ag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-82-token-ag.c"; sourceTree = ""; }; DCC78E061D8085FC00865A7C /* si-83-seccertificate-sighashalg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-83-seccertificate-sighashalg.c"; sourceTree = ""; }; - DCC78E071D8085FC00865A7C /* si-85-sectrust-ssl-policy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "si-85-sectrust-ssl-policy.c"; sourceTree = ""; }; - DCC78E081D8085FC00865A7C /* si-85-sectrust-ssl-policy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-85-sectrust-ssl-policy.h"; sourceTree = ""; }; - 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 = ""; }; 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 = ""; }; - DCC78E101D8085FC00865A7C /* si-97-sectrust-path-scoring.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "si-97-sectrust-path-scoring.m"; sourceTree = ""; }; - DCC78E111D8085FC00865A7C /* si-97-sectrust-path-scoring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "si-97-sectrust-path-scoring.h"; sourceTree = ""; }; DCC78E131D8085FC00865A7C /* vmdh-40.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "vmdh-40.c"; sourceTree = ""; }; DCC78E141D8085FC00865A7C /* vmdh-41-example.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "vmdh-41-example.c"; sourceTree = ""; }; DCC78E151D8085FC00865A7C /* vmdh-42-example2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "vmdh-42-example2.c"; sourceTree = ""; }; @@ -12349,7 +14814,7 @@ DCC78E1E1D8085FC00865A7C /* codesign.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = codesign.c; sourceTree = ""; }; DCC78E1F1D8085FC00865A7C /* keychain_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain_add.c; sourceTree = ""; }; DCC78E201D8085FC00865A7C /* keychain_find.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = keychain_find.m; sourceTree = ""; }; - DCC78E211D8085FC00865A7C /* keychain_backup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = keychain_backup.c; path = ../Security/Tool/keychain_backup.c; sourceTree = ""; }; + DCC78E211D8085FC00865A7C /* keychain_backup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain_backup.c; sourceTree = ""; }; DCC78E221D8085FC00865A7C /* pkcs12_util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkcs12_util.c; sourceTree = ""; }; DCC78E231D8085FC00865A7C /* scep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scep.c; sourceTree = ""; }; DCC78E241D8085FC00865A7C /* SecurityCommands.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecurityCommands.h; sourceTree = ""; }; @@ -12380,7 +14845,7 @@ DCC78E5A1D8085FC00865A7C /* SecItemBackup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecItemBackup.c; sourceTree = ""; }; 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 = ""; }; + DCC78E601D8085FC00865A7C /* SecKey.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecKey.m; 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 = ""; }; @@ -12489,8 +14954,6 @@ DCD067CA1D8CDF7E007602F1 /* cskernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = cskernel.cpp; sourceTree = ""; }; DCD067CB1D8CDF7E007602F1 /* csprocess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csprocess.h; sourceTree = ""; }; DCD067CC1D8CDF7E007602F1 /* csprocess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csprocess.cpp; sourceTree = ""; }; - DCD067CD1D8CDF7E007602F1 /* csgeneric.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = csgeneric.h; sourceTree = ""; }; - DCD067CE1D8CDF7E007602F1 /* csgeneric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = csgeneric.cpp; sourceTree = ""; }; DCD067D01D8CDF7E007602F1 /* diskrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = diskrep.h; sourceTree = ""; }; DCD067D11D8CDF7E007602F1 /* diskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = diskrep.cpp; sourceTree = ""; }; DCD067D21D8CDF7E007602F1 /* filediskrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = filediskrep.h; sourceTree = ""; }; @@ -12511,8 +14974,6 @@ DCD067E11D8CDF7E007602F1 /* detachedrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = detachedrep.cpp; sourceTree = ""; }; DCD067E21D8CDF7E007602F1 /* piddiskrep.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = piddiskrep.h; sourceTree = ""; usesTabs = 0; }; DCD067E31D8CDF7E007602F1 /* piddiskrep.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = piddiskrep.cpp; sourceTree = ""; usesTabs = 1; }; - DCD067E71D8CDF7E007602F1 /* SecCodeHostLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecCodeHostLib.h; sourceTree = ""; }; - DCD067E81D8CDF7E007602F1 /* SecCodeHostLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SecCodeHostLib.c; sourceTree = ""; }; DCD067EA1D8CDF7E007602F1 /* sp-watch.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = "sp-watch.d"; path = "../dtrace/sp-watch.d"; sourceTree = ""; }; DCD067EB1D8CDF7E007602F1 /* security_codesigning.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = security_codesigning.d; sourceTree = ""; }; DCD067EC1D8CDF7E007602F1 /* codesign-watch.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; name = "codesign-watch.d"; path = "../dtrace/codesign-watch.d"; sourceTree = ""; }; @@ -12538,7 +14999,7 @@ DCD068061D8CDF7E007602F1 /* SecAssessment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = SecAssessment.h; sourceTree = ""; }; DCD068071D8CDF7E007602F1 /* SecAssessment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = SecAssessment.cpp; sourceTree = ""; }; DCD068081D8CDF7E007602F1 /* evaluationmanager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = evaluationmanager.h; sourceTree = ""; }; - DCD068091D8CDF7E007602F1 /* evaluationmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = evaluationmanager.cpp; sourceTree = ""; }; + DCD068091D8CDF7E007602F1 /* evaluationmanager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = evaluationmanager.cpp; sourceTree = ""; usesTabs = 0; }; DCD0680A1D8CDF7E007602F1 /* opaquewhitelist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = opaquewhitelist.h; sourceTree = ""; }; DCD0680B1D8CDF7E007602F1 /* opaquewhitelist.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = opaquewhitelist.cpp; sourceTree = ""; }; DCD0680C1D8CDF7E007602F1 /* policydb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = policydb.h; sourceTree = ""; }; @@ -12668,8 +15129,6 @@ DCD06AC31D8E0D7D007602F1 /* debugging_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = debugging_internal.h; sourceTree = ""; }; DCD06AC41D8E0D7D007602F1 /* debugsupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debugsupport.h; sourceTree = ""; }; DCD06AC51D8E0D7D007602F1 /* debugging_internal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = debugging_internal.cpp; sourceTree = ""; }; - DCD06AC61D8E0D7D007602F1 /* devrandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = devrandom.h; sourceTree = ""; }; - DCD06AC71D8E0D7D007602F1 /* devrandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = devrandom.cpp; sourceTree = ""; }; DCD06AC81D8E0D7D007602F1 /* dispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dispatch.cpp; sourceTree = ""; }; DCD06AC91D8E0D7D007602F1 /* dispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dispatch.h; sourceTree = ""; }; DCD06ACA1D8E0D7D007602F1 /* endian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endian.h; sourceTree = ""; }; @@ -12696,8 +15155,6 @@ DCD06AE21D8E0D7D007602F1 /* simpleprefs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = simpleprefs.cpp; sourceTree = ""; }; DCD06AE31D8E0D7D007602F1 /* sqlite++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "sqlite++.h"; sourceTree = ""; }; DCD06AE41D8E0D7D007602F1 /* sqlite++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "sqlite++.cpp"; sourceTree = ""; }; - DCD06AE51D8E0D7D007602F1 /* streams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = streams.h; sourceTree = ""; }; - DCD06AE61D8E0D7D007602F1 /* streams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = streams.cpp; sourceTree = ""; }; DCD06AE71D8E0D7D007602F1 /* superblob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = superblob.h; sourceTree = ""; }; DCD06AE81D8E0D7D007602F1 /* superblob.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = superblob.cpp; sourceTree = ""; }; DCD06AE91D8E0D7D007602F1 /* threading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = threading.h; sourceTree = ""; }; @@ -12724,12 +15181,8 @@ DCD06B061D8E0D7D007602F1 /* unix++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = "unix++.cpp"; sourceTree = ""; }; DCD06B071D8E0D7D007602F1 /* unixchild.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unixchild.h; sourceTree = ""; }; DCD06B081D8E0D7D007602F1 /* unixchild.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = unixchild.cpp; sourceTree = ""; }; - DCD06B091D8E0D7D007602F1 /* vproc++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vproc++.h"; sourceTree = ""; }; - DCD06B0A1D8E0D7D007602F1 /* vproc++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "vproc++.cpp"; sourceTree = ""; }; DCD06B0C1D8E0D7D007602F1 /* mach++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "mach++.h"; sourceTree = ""; }; DCD06B0D1D8E0D7D007602F1 /* mach++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = "mach++.cpp"; sourceTree = ""; }; - DCD06B0E1D8E0D7D007602F1 /* mach_notify.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mach_notify.h; sourceTree = ""; }; - DCD06B0F1D8E0D7D007602F1 /* mach_notify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mach_notify.c; sourceTree = ""; }; DCD06B101D8E0D7D007602F1 /* cfmach++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cfmach++.h"; sourceTree = ""; }; DCD06B111D8E0D7D007602F1 /* cfmach++.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = "cfmach++.cpp"; sourceTree = ""; }; DCD06B121D8E0D7D007602F1 /* macho++.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "macho++.h"; sourceTree = ""; }; @@ -12739,8 +15192,6 @@ DCD06B161D8E0D7D007602F1 /* dyld_cache_format.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dyld_cache_format.h; sourceTree = ""; }; DCD06B171D8E0D7D007602F1 /* machserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machserver.h; sourceTree = ""; }; DCD06B181D8E0D7D007602F1 /* machserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = machserver.cpp; sourceTree = ""; }; - DCD06B191D8E0D7D007602F1 /* machrunloopserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = machrunloopserver.h; sourceTree = ""; }; - DCD06B1A1D8E0D7D007602F1 /* machrunloopserver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = machrunloopserver.cpp; sourceTree = ""; }; DCD06B1C1D8E0D7D007602F1 /* coderepository.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coderepository.h; sourceTree = ""; }; DCD06B1D1D8E0D7D007602F1 /* coderepository.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = coderepository.cpp; sourceTree = ""; }; DCD06B1E1D8E0D7D007602F1 /* cfclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cfclass.h; sourceTree = ""; }; @@ -12751,9 +15202,19 @@ 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 = ""; }; + DCD33D79220B985A000A390B /* EscrowRequestController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestController.h; sourceTree = ""; }; + DCD33D7A220B985A000A390B /* EscrowRequestController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestController.m; sourceTree = ""; }; + DCD33D7E220B9DC8000A390B /* OctagonStateMachineHelpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonStateMachineHelpers.h; sourceTree = ""; }; + DCD33D7F220B9DC8000A390B /* OctagonStateMachineHelpers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonStateMachineHelpers.m; sourceTree = ""; }; + DCD33D8C220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestInformCloudServicesOperation.h; sourceTree = ""; }; + DCD33D8D220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestInformCloudServicesOperation.m; sourceTree = ""; }; + DCD33D91220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestPerformEscrowEnrollOperation.h; sourceTree = ""; }; + DCD33D92220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestPerformEscrowEnrollOperation.m; 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 = ""; }; + DCD48BFC20BF3D83009A3224 /* tpctl-objc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "tpctl-objc.h"; sourceTree = ""; }; + DCD48BFD20BF3D83009A3224 /* tpctl-objc.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "tpctl-objc.m"; 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; }; @@ -12761,12 +15222,15 @@ DCD6C4B01EC5302400414FEE /* CKKSNearFutureScheduler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSNearFutureScheduler.h; sourceTree = ""; }; DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSNearFutureScheduler.m; sourceTree = ""; }; DCD6C4B61EC5319600414FEE /* CKKSNearFutureSchedulerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSNearFutureSchedulerTests.m; sourceTree = ""; }; + DCD7DD9B22B868C100161396 /* TPPBDispositionDuplicateMachineID.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPBDispositionDuplicateMachineID.m; sourceTree = ""; }; + DCD7DD9D22B868C200161396 /* TPPBDispositionDuplicateMachineID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPBDispositionDuplicateMachineID.h; sourceTree = ""; }; DCD7EE9B1F4F51D9007D9804 /* ios_tapi_hacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ios_tapi_hacks.h; sourceTree = ""; }; DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libSecureObjectSyncFramework.a; sourceTree = BUILT_PRODUCTS_DIR; }; DCDCC7DD1D9B54DF006487E8 /* secd-202-recoverykey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-202-recoverykey.m"; sourceTree = ""; }; 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 = ""; }; + DCDF03112284E34B008055BA /* OctagonTests+EscrowRecovery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OctagonTests+EscrowRecovery.swift"; 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 = ""; }; @@ -12774,7 +15238,7 @@ DCE278E61ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSUpdateCurrentItemPointerOperation.h; sourceTree = ""; }; DCE278E71ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSUpdateCurrentItemPointerOperation.m; sourceTree = ""; }; DCE4E6A41D7A37FA00AFB96E /* security2 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = security2; sourceTree = BUILT_PRODUCTS_DIR; }; - DCE4E6A71D7A38C000AFB96E /* security2.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; name = security2.1; path = ../OSX/security2/security2.1; sourceTree = ""; }; + DCE4E6A71D7A38C000AFB96E /* security2.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = security2.1; sourceTree = ""; }; DCE4E6D41D7A41E400AFB96E /* bc-10-knife-on-bread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "bc-10-knife-on-bread.m"; path = "OSX/Breadcrumb/bc-10-knife-on-bread.m"; sourceTree = ""; }; DCE4E6D71D7A420D00AFB96E /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = OSX/SecurityTestsOSX/main.m; sourceTree = ""; }; DCE4E6E71D7A427200AFB96E /* SecurityFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SecurityFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/System/Library/Frameworks/SecurityFoundation.framework; sourceTree = DEVELOPER_DIR; }; @@ -12840,15 +15304,28 @@ 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; }; - DCE7F2081F21726500DDB0F7 /* CKKSAPSReceiverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSAPSReceiverTests.m; sourceTree = ""; }; + DCE772642290712F005862B4 /* OctagonCheckTrustStateOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonCheckTrustStateOperation.h; sourceTree = ""; }; + DCE772652290712F005862B4 /* OctagonCheckTrustStateOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonCheckTrustStateOperation.m; sourceTree = ""; }; + DCE7F2081F21726500DDB0F7 /* OctagonAPSReceiverTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonAPSReceiverTests.m; sourceTree = ""; }; + DCEA0FF6213F1E6F0054A328 /* Octagon.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Octagon.plist; sourceTree = ""; }; DCEA5D531E2826DB0089CF55 /* CKKSSIV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSSIV.h; sourceTree = ""; }; DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSSIV.m; sourceTree = ""; }; - DCEA5D831E2F14810089CF55 /* CKKSAPSReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSAPSReceiver.h; sourceTree = ""; }; - DCEA5D841E2F14810089CF55 /* CKKSAPSReceiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSAPSReceiver.m; sourceTree = ""; }; + DCEA5D831E2F14810089CF55 /* OctagonAPSReceiver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OctagonAPSReceiver.h; sourceTree = ""; }; + DCEA5D841E2F14810089CF55 /* OctagonAPSReceiver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OctagonAPSReceiver.m; sourceTree = ""; }; 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 = ""; }; + DCF12671218A7579000124C6 /* OTLeaveCliqueOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTLeaveCliqueOperation.h; sourceTree = ""; }; + DCF12672218A757A000124C6 /* OTLeaveCliqueOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTLeaveCliqueOperation.m; sourceTree = ""; }; + DCF158C52064895C00B87B6D /* OctagonAPSReceiverTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonAPSReceiverTests.h; sourceTree = ""; }; + DCF216D721ADD5B10029CCC1 /* libprotobuf_source_generation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libprotobuf_source_generation.a; sourceTree = BUILT_PRODUCTS_DIR; }; + DCF458AD221F6890007F5507 /* TPLog.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TPLog.h; sourceTree = ""; }; + DCF458AE221F6890007F5507 /* TPLog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TPLog.m; sourceTree = ""; }; + DCF4657822011E1300BA6EEA /* EscrowRequestCLI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EscrowRequestCLI.h; sourceTree = ""; }; + DCF4657922011E1300BA6EEA /* EscrowRequestCLI.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EscrowRequestCLI.m; sourceTree = ""; }; + DCF46C2C214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTUpdateTrustedDeviceListOperation.h; sourceTree = ""; }; + DCF46C2D214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTUpdateTrustedDeviceListOperation.m; sourceTree = ""; }; + DCF6320421C074F30030CCC0 /* CuttlefishAPIHelpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CuttlefishAPIHelpers.swift; 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 = ""; }; @@ -12890,18 +15367,6 @@ DCF7833B1D88B60D00E694BB /* wrapKeyCms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrapKeyCms.cpp; sourceTree = ""; }; DCF7833C1D88B60D00E694BB /* YarrowConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YarrowConnection.cpp; sourceTree = ""; }; DCF7833D1D88B60D00E694BB /* YarrowConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = YarrowConnection.h; sourceTree = ""; }; - DCF7833F1D88B60D00E694BB /* algmaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = algmaker.cpp; sourceTree = ""; }; - DCF783401D88B60D00E694BB /* bsafeAsymmetric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bsafeAsymmetric.cpp; sourceTree = ""; }; - DCF783411D88B60D00E694BB /* bsafeContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bsafeContext.cpp; sourceTree = ""; }; - DCF783421D88B60D00E694BB /* bsafecsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bsafecsp.h; sourceTree = ""; }; - DCF783431D88B60D00E694BB /* bsafecspi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bsafecspi.h; sourceTree = ""; }; - DCF783441D88B60D00E694BB /* bsafeKeyGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bsafeKeyGen.cpp; sourceTree = ""; }; - DCF783451D88B60D00E694BB /* bsafePKCS1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = bsafePKCS1.cpp; sourceTree = ""; }; - DCF783461D88B60D00E694BB /* bsafePKCS1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bsafePKCS1.h; sourceTree = ""; }; - DCF783471D88B60D00E694BB /* bsafeSymmetric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = bsafeSymmetric.cpp; sourceTree = ""; }; - DCF783481D88B60D00E694BB /* bsobjects.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bsobjects.h; sourceTree = ""; }; - DCF783491D88B60D00E694BB /* memory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = ""; }; - DCF7834A1D88B60D00E694BB /* miscalgorithms.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = miscalgorithms.cpp; sourceTree = ""; }; DCF7834C1D88B60D00E694BB /* ascContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = ascContext.cpp; sourceTree = ""; }; DCF7834D1D88B60D00E694BB /* ascContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ascContext.h; sourceTree = ""; }; DCF7834E1D88B60D00E694BB /* ascFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ascFactory.h; sourceTree = ""; }; @@ -13182,13 +15647,17 @@ DCF789471D88D17C00E694BB /* AppleX509TPBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AppleX509TPBuiltin.cpp; path = OSX/libsecurity_apple_x509_tp/lib/AppleX509TPBuiltin.cpp; sourceTree = ""; }; DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSControlProtocol.h; sourceTree = ""; }; DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSControlProtocol.m; sourceTree = ""; }; + DCF94A79222D9F2400C01744 /* OctagonCKKSPeerAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonCKKSPeerAdapter.h; sourceTree = ""; }; + DCF94A7A222D9F2400C01744 /* OctagonCKKSPeerAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonCKKSPeerAdapter.m; sourceTree = ""; }; DCFABF8D20081E2F001128B5 /* CKKSDeviceStateUploadTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSDeviceStateUploadTests.m; sourceTree = ""; }; DCFAEDC81D999851005187E4 /* SOSAccountGhost.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSAccountGhost.m; sourceTree = ""; }; DCFAEDC91D999851005187E4 /* SOSAccountGhost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSAccountGhost.h; sourceTree = ""; }; DCFAEDD11D9998DD005187E4 /* secd-668-ghosts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-668-ghosts.m"; sourceTree = ""; }; DCFAEDD51D99A464005187E4 /* secd-36-ks-encrypt.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-36-ks-encrypt.m"; sourceTree = ""; }; - DCFB12C31E95A4C000510F5F /* CKKSCKAccountStateTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSCKAccountStateTracker.h; sourceTree = ""; }; - DCFB12C41E95A4C000510F5F /* CKKSCKAccountStateTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSCKAccountStateTracker.m; sourceTree = ""; }; + DCFB12C31E95A4C000510F5F /* CKKSAccountStateTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CKKSAccountStateTracker.h; sourceTree = ""; }; + DCFB12C41E95A4C000510F5F /* CKKSAccountStateTracker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CKKSAccountStateTracker.m; sourceTree = ""; }; + DCFC91AD21F16E0B00E674DD /* OctagonStateMachine.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonStateMachine.h; sourceTree = ""; }; + DCFC91AE21F16E0B00E674DD /* OctagonStateMachine.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonStateMachine.m; sourceTree = ""; }; DCFE1C251F17E455007640C8 /* CKKSDeviceStateEntry.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSDeviceStateEntry.h; sourceTree = ""; }; DCFE1C261F17E455007640C8 /* CKKSDeviceStateEntry.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSDeviceStateEntry.m; sourceTree = ""; }; DCFE1C321F17ECE5007640C8 /* CKKSCondition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSCondition.h; sourceTree = ""; }; @@ -13196,6 +15665,27 @@ DCFE1C3C1F17EFB5007640C8 /* CKKSConditionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSConditionTests.m; sourceTree = ""; }; DCFE1C4F1F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSUpdateDeviceStateOperation.h; sourceTree = ""; }; DCFE1C501F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSUpdateDeviceStateOperation.m; sourceTree = ""; }; + DCFF82702162834C00D54B02 /* OctagonTestsXPCConnections.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OctagonTestsXPCConnections.swift; sourceTree = ""; }; + DCFF82722162876400D54B02 /* OTResetOperation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTResetOperation.h; sourceTree = ""; }; + DCFF82732162876400D54B02 /* OTResetOperation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTResetOperation.m; sourceTree = ""; }; + E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OctagonTrieste.xcodeproj; path = OctagonTriesteTests/OctagonTrieste.xcodeproj; sourceTree = ""; }; + E060D19C2124780E0025B833 /* OctagonTestHarness.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OctagonTestHarness.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E060D19E2124780F0025B833 /* OctagonTestHarness.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonTestHarness.h; sourceTree = ""; }; + E060D19F2124780F0025B833 /* OctagonTestHarnessXPCService.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonTestHarnessXPCService.h; sourceTree = ""; }; + E060D1A12124780F0025B833 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E060D1A72124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OctagonTestHarnessXPCServiceProtocol.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E060D1B7212478110025B833 /* OctagonTestHarnessXPCService.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = OctagonTestHarnessXPCService.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; + E060D1BE212478120025B833 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + E060D1C0212478120025B833 /* OctagonTestHarnessXPCServiceDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OctagonTestHarnessXPCServiceDelegate.h; sourceTree = ""; }; + E060D1C3212478120025B833 /* OctagonTestHarnessXPCServiceDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonTestHarnessXPCServiceDelegate.m; sourceTree = ""; }; + E060D1C6212478120025B833 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E060D23F21247C680025B833 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; + E060D24221247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OctagonTestHarnessXPCServiceProtocol.m; sourceTree = ""; }; + E060D24421247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OctagonTestHarnessXPCServiceProtocol.h; sourceTree = ""; }; + E060D24521247C680025B833 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E060D2BD21248F820025B833 /* Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Entitlements.plist; sourceTree = ""; }; + E09E09E9215506570042C7D3 /* OctagonTestHarnessXPCService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OctagonTestHarnessXPCService.m; sourceTree = ""; }; + E291657E2048BCCB0046512B /* TPPBPeerStableInfoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = TPPBPeerStableInfoTests.m; path = keychain/trust/TrustedPeersTests/TPPBPeerStableInfoTests.m; sourceTree = SOURCE_ROOT; }; E7104A0B169E171900DB0045 /* security_tool_commands.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = security_tool_commands.c; sourceTree = ""; }; E710C7421331946400F85568 /* SecurityTests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SecurityTests.app; sourceTree = BUILT_PRODUCTS_DIR; }; E710C74C1331946500F85568 /* SecurityTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SecurityTests-Info.plist"; sourceTree = ""; }; @@ -13214,10 +15704,10 @@ E7676DB519411DF300498DD4 /* SecServerEncryptionSupport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecServerEncryptionSupport.h; sourceTree = ""; }; E772FD461CC15EFA00D63E41 /* NSData+SecRandom.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+SecRandom.m"; sourceTree = ""; }; E772FD6F1CC15F1F00D63E41 /* NSData+SecRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+SecRandom.h"; sourceTree = ""; }; - E78A9AD81D34959200006B5B /* NSFileHandle+Formatting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFileHandle+Formatting.h"; path = "../OSX/sec/SOSCircle/Tool/NSFileHandle+Formatting.h"; sourceTree = ""; }; - E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFileHandle+Formatting.m"; path = "../OSX/sec/SOSCircle/Tool/NSFileHandle+Formatting.m"; sourceTree = ""; }; - E78CCDC61E737F6700C1CFAA /* SecNSAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecNSAdditions.m; path = src/SecNSAdditions.m; sourceTree = ""; }; - E78CCDCD1E737F8100C1CFAA /* SecNSAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecNSAdditions.h; path = src/SecNSAdditions.h; sourceTree = ""; }; + E78A9AD81D34959200006B5B /* NSFileHandle+Formatting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileHandle+Formatting.h"; sourceTree = ""; }; + E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileHandle+Formatting.m"; sourceTree = ""; }; + E78CCDC61E737F6700C1CFAA /* SecNSAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecNSAdditions.m; sourceTree = ""; }; + E78CCDCD1E737F8100C1CFAA /* SecNSAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecNSAdditions.h; sourceTree = ""; }; E794BA6E1C7424D800339A0F /* KCDer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCDer.m; sourceTree = ""; }; E794BAD91C7598E400339A0F /* KCJoiningMessages.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KCJoiningMessages.h; sourceTree = ""; }; E794BAFF1C7598F900339A0F /* KCJoiningMessages.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCJoiningMessages.m; sourceTree = ""; }; @@ -13235,8 +15725,8 @@ E7C787181DCA4C5A0087FC34 /* CKDLockMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDLockMonitor.h; path = KVSKeychainSyncingProxy/CKDLockMonitor.h; sourceTree = ""; }; E7C7871D1DCA4CF70087FC34 /* CKDAKSLockMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDAKSLockMonitor.h; path = KVSKeychainSyncingProxy/CKDAKSLockMonitor.h; sourceTree = ""; }; E7C7871F1DCA4D430087FC34 /* CKDAKSLockMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDAKSLockMonitor.m; path = KVSKeychainSyncingProxy/CKDAKSLockMonitor.m; sourceTree = ""; }; - E7C787301DD0FED50087FC34 /* NSURL+SOSPlistStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSURL+SOSPlistStore.h"; path = "src/NSURL+SOSPlistStore.h"; sourceTree = ""; }; - E7C787311DD0FED50087FC34 /* NSURL+SOSPlistStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSURL+SOSPlistStore.m"; path = "src/NSURL+SOSPlistStore.m"; sourceTree = ""; }; + E7C787301DD0FED50087FC34 /* NSURL+SOSPlistStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+SOSPlistStore.h"; sourceTree = ""; }; + E7C787311DD0FED50087FC34 /* NSURL+SOSPlistStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+SOSPlistStore.m"; sourceTree = ""; }; E7C787321DD0FED50087FC34 /* XPCNotificationDispatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XPCNotificationDispatcher.h; path = KVSKeychainSyncingProxy/XPCNotificationDispatcher.h; sourceTree = ""; }; E7C787331DD0FED50087FC34 /* XPCNotificationDispatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XPCNotificationDispatcher.m; path = KVSKeychainSyncingProxy/XPCNotificationDispatcher.m; sourceTree = ""; }; E7CFF7221C8660A000E3484E /* KeychainCircle.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KeychainCircle.plist; path = Tests/KeychainCircle.plist; sourceTree = ""; }; @@ -13252,7 +15742,7 @@ E7E4318813319C0700AF0CFD /* SecurityTests-Entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "SecurityTests-Entitlements.plist"; sourceTree = ""; }; E7F480111C729C7B00390FDB /* NSError+KCCreationHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+KCCreationHelpers.h"; sourceTree = ""; }; E7F480131C7397CE00390FDB /* KCJoiningSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KCJoiningSession.h; sourceTree = ""; }; - E7F480141C73980D00390FDB /* KCJoiningRequestSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCJoiningRequestSession.m; sourceTree = ""; }; + E7F480141C73980D00390FDB /* KCJoiningRequestSecretSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCJoiningRequestSecretSession.m; sourceTree = ""; }; E7F480301C73FC4C00390FDB /* KCAESGCMDuplexSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KCAESGCMDuplexSession.h; sourceTree = ""; }; E7F480311C73FC4C00390FDB /* KCAESGCMDuplexSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCAESGCMDuplexSession.m; sourceTree = ""; }; E7F4809B1C74E85200390FDB /* KCDerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KCDerTest.m; path = Tests/KCDerTest.m; sourceTree = ""; }; @@ -13266,20 +15756,17 @@ E7FCBE411314471B000DE34E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; E7FCBE431314471B000DE34E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; E7FCBE451314471B000DE34E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; - E7FE40C41DC804E400F0F5B6 /* CKDSimulatedStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDSimulatedStore.m; path = ../../SOSCircle/SecureObjectSync/CKDSimulatedStore.m; sourceTree = ""; }; - E7FE40C61DC804FA00F0F5B6 /* CKDSimulatedStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CKDSimulatedStore.h; path = ../../SOSCircle/SecureObjectSync/CKDSimulatedStore.h; sourceTree = ""; }; - 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 = ""; }; + E7FE40C41DC804E400F0F5B6 /* CKDSimulatedStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDSimulatedStore.m; path = ../../../../keychain/SecureObjectSync/CKDSimulatedStore.m; sourceTree = ""; }; + E7FE40C61DC804FA00F0F5B6 /* CKDSimulatedStore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CKDSimulatedStore.h; path = ../../../../keychain/SecureObjectSync/CKDSimulatedStore.h; sourceTree = ""; }; + E7FE40C71DC8084600F0F5B6 /* CKDSimulatedAccount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CKDSimulatedAccount.h; path = ../../../../keychain/SecureObjectSync/Regressions/CKDSimulatedAccount.h; sourceTree = ""; }; + E7FE40C81DC8084600F0F5B6 /* CKDSimulatedAccount.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CKDSimulatedAccount.m; path = ../../../../keychain/SecureObjectSync/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 = ""; }; + EB056E401FE5E390000A771E /* SecRemoteDeviceProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecRemoteDeviceProtocol.h; sourceTree = ""; }; + EB056E411FE5E390000A771E /* SecRemoteDevice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecRemoteDevice.h; sourceTree = ""; }; + EB056E421FE5E390000A771E /* SecRemoteDevice.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecRemoteDevice.m; sourceTree = ""; }; + EB067E8A20EC873D00B7D961 /* libcompression.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcompression.tbd; path = usr/lib/libcompression.tbd; sourceTree = SDKROOT; }; + EB093106213F8EC100C0A495 /* TestResourceUsage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TestResourceUsage.h; sourceTree = ""; }; + EB093107213F8EC100C0A495 /* TestResourceUsage.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TestResourceUsage.m; 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 = ""; }; @@ -13288,8 +15775,12 @@ EB10557A1E14DF640003C309 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; EB108F121E6CE48B003B0456 /* KCParing.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = KCParing.plist; path = Tests/KCParing.plist; sourceTree = ""; }; EB108F411E6CE4D2003B0456 /* KCPairingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KCPairingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - EB10A3E320356E2000E84270 /* OTConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OTConstants.h; path = ot/OTConstants.h; sourceTree = ""; }; - EB10A3E420356E2000E84270 /* OTConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = OTConstants.m; path = ot/OTConstants.m; sourceTree = ""; }; + EB10A3E320356E2000E84270 /* OTConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OTConstants.h; sourceTree = ""; }; + EB10A3E420356E2000E84270 /* OTConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTConstants.m; sourceTree = ""; }; + EB1C319C2215EC9600A188BB /* otctl.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = otctl.1; sourceTree = ""; }; + EB1E0695211E137E0088F0B1 /* mockaksxcbase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mockaksxcbase.m; sourceTree = ""; }; + EB1E069C211E149A0088F0B1 /* mockaksxcbase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mockaksxcbase.h; sourceTree = ""; }; + EB1E069E211E17B70088F0B1 /* mockaksWatchDog.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mockaksWatchDog.m; sourceTree = ""; }; EB27FF0C1E402C8000EC9E3A /* ckksctl.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ckksctl.m; sourceTree = ""; }; EB27FF111E402CD300EC9E3A /* ckksctl */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ckksctl; sourceTree = BUILT_PRODUCTS_DIR; }; EB27FF2F1E408CC900EC9E3A /* ckksctl-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = "ckksctl-Entitlements.plist"; sourceTree = ""; }; @@ -13297,7 +15788,10 @@ EB2CA5561D2C30F700AB770F /* Security.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Security.xcconfig; path = xcconfig/Security.xcconfig; sourceTree = ""; }; EB2D54A01F02A28200E46890 /* SecAtomicFile.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SecAtomicFile.cpp; sourceTree = ""; }; EB2D54AA1F02A45E00E46890 /* secatomicfile */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secatomicfile; sourceTree = BUILT_PRODUCTS_DIR; }; + EB35153F211A79CB0097A87C /* secd-33-keychain-backup.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "secd-33-keychain-backup.m"; sourceTree = ""; }; EB3A8DD71BEEC4D6001A89AA /* Security_edumode.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Security_edumode.plist; sourceTree = ""; }; + EB3F9C9B21FCFC60007B6EBA /* OctagonTestHarness.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OctagonTestHarness.m; sourceTree = ""; }; + EB3F9C9E21FCFF8E007B6EBA /* OctagonTestHarness.exp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.exports; path = OctagonTestHarness.exp; sourceTree = ""; }; EB413B751E6624A400592085 /* PairingChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PairingChannel.h; sourceTree = ""; }; EB413B761E6624A500592085 /* PairingChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PairingChannel.m; sourceTree = ""; }; EB413B7E1E663A8300592085 /* KCPairingTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KCPairingTest.m; path = Tests/KCPairingTest.m; sourceTree = ""; }; @@ -13308,8 +15802,9 @@ EB433A281CC3243600A7EACE /* secitemstresstest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemstresstest; sourceTree = BUILT_PRODUCTS_DIR; }; EB433A2D1CC325E900A7EACE /* secitemstresstest.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secitemstresstest.entitlements; path = secitemstresstest/secitemstresstest.entitlements; sourceTree = ""; }; EB48C19E1E573EDC00EC5E57 /* sos.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = sos.m; sourceTree = ""; }; + EB490153211C0026001E6D6A /* UserManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserManagement.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/UserManagement.framework; sourceTree = DEVELOPER_DIR; }; EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = secdmockaks.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - EB49B2B0202D8780003F34A0 /* secdmockaks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secdmockaks.m; sourceTree = ""; }; + EB49B2B0202D8780003F34A0 /* mockaksKeychain.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = mockaksKeychain.m; sourceTree = ""; }; EB49B2B2202D8780003F34A0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; EB49B2CE202DF111003F34A0 /* CoreFollowUp.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFollowUp.framework; path = System/Library/PrivateFrameworks/CoreFollowUp.framework; sourceTree = SDKROOT; }; EB49B2DC202DF251003F34A0 /* libbsm.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbsm.tbd; path = usr/lib/libbsm.tbd; sourceTree = SDKROOT; }; @@ -13324,16 +15819,67 @@ EB6928BE1D9C9C5900062A18 /* SecRecoveryKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecRecoveryKey.h; sourceTree = ""; }; EB6928BF1D9C9C5900062A18 /* SecRecoveryKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SecRecoveryKey.m; sourceTree = ""; }; EB6928C91D9C9D9D00062A18 /* rk_01_recoverykey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = rk_01_recoverykey.m; path = Regressions/rk_01_recoverykey.m; sourceTree = ""; }; + EB6952B9223B75C300F02C1C /* secitemd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemd; sourceTree = BUILT_PRODUCTS_DIR; }; + EB6952BC223B783500F02C1C /* com.apple.secitemd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = com.apple.secitemd.plist; path = OSX/sec/ipc/com.apple.secitemd.plist; sourceTree = SOURCE_ROOT; }; EB69AB091BF4347700913AF1 /* SecEMCSPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecEMCSPriv.h; sourceTree = ""; }; + EB6AC0AA22F22E80003F067B /* SecTapToRadarTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecTapToRadarTests.m; sourceTree = ""; }; + EB6D1D5322FE8D3000205E83 /* SecItemTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecItemTests.m; sourceTree = ""; }; + EB71CF6322E8238000DA3D0E /* SecTapToRadar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecTapToRadar.h; sourceTree = ""; }; + EB71CF6422E8238000DA3D0E /* SecTapToRadar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecTapToRadar.m; sourceTree = ""; }; + EB74CC162207E48000F1BBAD /* KeychainSettings.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KeychainSettings.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + EB74CC192207E48100F1BBAD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EB74CC1D2207E4BA00F1BBAD /* KeychainSettings.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeychainSettings.h; sourceTree = ""; }; + EB74CC1E2207E4BA00F1BBAD /* KeychainSettings.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KeychainSettings.m; sourceTree = ""; }; + EB74CC212207E4FA00F1BBAD /* KeychainSettings.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = KeychainSettings.plist; sourceTree = ""; }; + EB74CC252207ECCB00F1BBAD /* Preferences.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Preferences.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/System/Library/PrivateFrameworks/Preferences.framework; sourceTree = DEVELOPER_DIR; }; + EB74CC2E2207FBE900F1BBAD /* KeychainSettingsOctagonPeers.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = KeychainSettingsOctagonPeers.plist; sourceTree = ""; }; EB75B4931E75A44100E469CC /* SOSPiggyback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SOSPiggyback.h; sourceTree = ""; }; EB75B4941E75A44100E469CC /* SOSPiggyback.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SOSPiggyback.m; sourceTree = ""; }; EB76B75A1DCB0CDA00C43FBC /* Keychain Circle Notification.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "Keychain Circle Notification.8"; sourceTree = ""; }; - EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SecPLWrappers.m; path = src/SecPLWrappers.m; sourceTree = ""; }; - EB7AE6F71E86D55400B80B15 /* SecPLWrappers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecPLWrappers.h; path = src/SecPLWrappers.h; sourceTree = ""; }; + EB7732DA21963BAD00FCF513 /* libz.1.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.1.tbd; path = usr/lib/libz.1.tbd; sourceTree = SDKROOT; }; + EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecPLWrappers.m; sourceTree = ""; }; + EB7AE6F71E86D55400B80B15 /* SecPLWrappers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecPLWrappers.h; sourceTree = ""; }; + EB7E90EB2193A54100B1FA21 /* SecMetrics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecMetrics.h; sourceTree = ""; }; + EB7E90EC2193A54100B1FA21 /* SecMetrics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecMetrics.m; sourceTree = ""; }; + EB7E90EF2193A56C00B1FA21 /* C2Metric.proto */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.protobuf; path = C2Metric.proto; sourceTree = ""; }; + EB7E90F72193F96F00B1FA21 /* SECC2MPMetric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPMetric.h; sourceTree = ""; }; + EB7E90F82193F96F00B1FA21 /* SECC2MPGenericEventMetric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPGenericEventMetric.h; sourceTree = ""; }; + EB7E90F92193F97000B1FA21 /* SECC2MPDeviceInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPDeviceInfo.m; sourceTree = ""; }; + EB7E90FA2193F97000B1FA21 /* SECC2MPInternalTestConfig.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPInternalTestConfig.m; sourceTree = ""; }; + EB7E90FB2193F97000B1FA21 /* SECC2MPDeviceInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPDeviceInfo.h; sourceTree = ""; }; + EB7E90FC2193F97100B1FA21 /* SECC2MPCloudKitOperationInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPCloudKitOperationInfo.m; sourceTree = ""; }; + EB7E90FD2193F97100B1FA21 /* SECC2MPError.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPError.m; sourceTree = ""; }; + EB7E90FE2193F97200B1FA21 /* SECC2MPGenericEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPGenericEvent.h; sourceTree = ""; }; + EB7E90FF2193F97200B1FA21 /* SECC2MPGenericEventMetric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPGenericEventMetric.m; sourceTree = ""; }; + EB7E91002193F97200B1FA21 /* SECC2MPGenericEventMetricValue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPGenericEventMetricValue.h; sourceTree = ""; }; + EB7E91012193F97300B1FA21 /* SECC2MPInternalTestConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPInternalTestConfig.h; sourceTree = ""; }; + EB7E91022193F97300B1FA21 /* SECC2MPGenericEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPGenericEvent.m; sourceTree = ""; }; + EB7E91032193F97400B1FA21 /* SECC2MPCloudKitOperationGroupInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPCloudKitOperationGroupInfo.h; sourceTree = ""; }; + EB7E91042193F97400B1FA21 /* SECC2MPCloudKitInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPCloudKitInfo.m; sourceTree = ""; }; + EB7E91052193F97400B1FA21 /* SECC2MPMetric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPMetric.m; sourceTree = ""; }; + EB7E91062193F97500B1FA21 /* SECC2MPCloudKitOperationGroupInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPCloudKitOperationGroupInfo.m; sourceTree = ""; }; + EB7E91072193F97500B1FA21 /* SECC2MPNetworkEvent.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPNetworkEvent.m; sourceTree = ""; }; + EB7E91082193F97600B1FA21 /* SECC2MPServerInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPServerInfo.h; sourceTree = ""; }; + EB7E91092193F97600B1FA21 /* SECC2MPCloudKitInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPCloudKitInfo.h; sourceTree = ""; }; + EB7E910A2193F97600B1FA21 /* SECC2MPGenericEventMetricValue.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPGenericEventMetricValue.m; sourceTree = ""; }; + EB7E910B2193F97700B1FA21 /* SECC2MPServerInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SECC2MPServerInfo.m; sourceTree = ""; }; + EB7E910C2193F97700B1FA21 /* SECC2MPError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPError.h; sourceTree = ""; }; + EB7E910D2193F97800B1FA21 /* SECC2MPCloudKitOperationInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPCloudKitOperationInfo.h; sourceTree = ""; }; + EB7E910E2193F97800B1FA21 /* SECC2MPNetworkEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SECC2MPNetworkEvent.h; sourceTree = ""; }; + EB7E910F2193FB7E00B1FA21 /* SecC2DeviceInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecC2DeviceInfo.h; sourceTree = ""; }; + EB7E91102193FB7E00B1FA21 /* SecC2DeviceInfo.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecC2DeviceInfo.m; sourceTree = ""; }; + EB7E91112194826F00B1FA21 /* SecEventMetric.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecEventMetric.h; sourceTree = ""; }; + EB7E91122194826F00B1FA21 /* SecEventMetric.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecEventMetric.m; sourceTree = ""; }; + EB7E91242194915600B1FA21 /* SecEventMetric_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecEventMetric_private.h; sourceTree = ""; }; EB8021411D3D90BB008540C4 /* Security.iOS.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = Security.iOS.modulemap; path = Modules/Security.iOS.modulemap; sourceTree = ""; }; EB8021421D3D90BB008540C4 /* Security.macOS.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; name = Security.macOS.modulemap; path = Modules/Security.macOS.modulemap; sourceTree = ""; }; + EB80DE57219600CF005B10FA /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS13.0.Internal.sdk/usr/lib/libz.dylib; sourceTree = DEVELOPER_DIR; }; EB82A2A41FAFF26900CA64A9 /* SFBehavior.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SFBehavior.h; sourceTree = ""; }; EB82A2A51FAFF26900CA64A9 /* SFBehavior.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SFBehavior.m; sourceTree = ""; }; + EB89088621F17D3C00F0DDDB /* recovery_securityd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = recovery_securityd; sourceTree = BUILT_PRODUCTS_DIR; }; + EB8908BB21F20E0200F0DDDB /* com.apple.recovery_securityd.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = com.apple.recovery_securityd.plist; path = ../ipc/com.apple.recovery_securityd.plist; sourceTree = ""; }; + EB89111020E3C15D00DE533F /* UserManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UserManagement.framework; path = System/Library/PrivateFrameworks/UserManagement.framework; sourceTree = SDKROOT; }; + EB9795B422FE90E6002BDBFB /* SecurityUnitTests.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SecurityUnitTests.entitlements; sourceTree = ""; }; EB9C02421E8A112A0040D3C6 /* secd-37-pairing-initial-sync.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "secd-37-pairing-initial-sync.m"; sourceTree = ""; }; EB9C1D7A1BDFD0E000F89272 /* secbackupntest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secbackupntest; sourceTree = BUILT_PRODUCTS_DIR; }; EB9C1D7D1BDFD0E100F89272 /* secbackupntest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = secbackupntest.m; sourceTree = ""; }; @@ -13341,32 +15887,45 @@ EBA9AA7B1CE30CE7004E2B68 /* secitemnotifications.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; name = secitemnotifications.entitlements; path = secitemnotifications/secitemnotifications.entitlements; sourceTree = ""; }; EBA9AA7C1CE30CE7004E2B68 /* secitemnotifications.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = secitemnotifications.m; path = secitemnotifications/secitemnotifications.m; sourceTree = ""; }; EBA9AA861CE30E58004E2B68 /* secitemnotifications */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = secitemnotifications; sourceTree = BUILT_PRODUCTS_DIR; }; - EBB407AF1EBA433A00A541A5 /* CKKSPowerCollection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = CKKSPowerCollection.h; path = analytics/CKKSPowerCollection.h; sourceTree = ""; }; - EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = CKKSPowerCollection.m; path = analytics/CKKSPowerCollection.m; sourceTree = ""; }; + EBAC4A512189743D00FBEC43 /* rio.yml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rio.yml; sourceTree = ""; }; + EBB02A56221FF362007241CB /* KeychainSettingsCKKSViews.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = KeychainSettingsCKKSViews.plist; sourceTree = ""; }; + EBB02A6C2220ED16007241CB /* CKKSLaunchSequence.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSLaunchSequence.h; sourceTree = ""; }; + EBB02A6D2220ED16007241CB /* CKKSLaunchSequence.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLaunchSequence.m; sourceTree = ""; }; + EBB03155222237A7007241CB /* CKKSLaunchSequenceTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSLaunchSequenceTests.m; sourceTree = ""; }; + EBB407AF1EBA433A00A541A5 /* CKKSPowerCollection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSPowerCollection.h; sourceTree = ""; }; + EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSPowerCollection.m; sourceTree = ""; }; 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; }; + EBB851EC22F7912400424FD0 /* SecurityUtilitiesTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SecurityUtilitiesTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + EBB8521A22F7943700424FD0 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + EBC1023022EBF8AC0083D356 /* CKKSTests+LockStateTracker.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "CKKSTests+LockStateTracker.m"; sourceTree = ""; }; 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 = ""; }; + EBCE06E521C6E26000FB1493 /* OTDefines.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OTDefines.m; 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 = ""; }; + EBDAA7E320EC46CF003EA6E5 /* SecurityLocalKeychain.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = SecurityLocalKeychain.plist; sourceTree = ""; }; + EBDAF15B21C75FF200EAE89F /* NSXPCConnectionMock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSXPCConnectionMock.h; sourceTree = ""; }; + EBDAF15C21C75FF200EAE89F /* NSXPCConnectionMock.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSXPCConnectionMock.m; sourceTree = ""; }; + EBDE5DF922BA3D5D00A229C8 /* CKKSMockOctagonAdapter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CKKSMockOctagonAdapter.h; sourceTree = ""; }; + EBDE5DFA22BA3D5D00A229C8 /* CKKSMockOctagonAdapter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CKKSMockOctagonAdapter.m; sourceTree = ""; }; + EBE2026420908A8A00B48020 /* tpctl.8 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tpctl.8; 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 = ""; }; + EBE8258E2193353300102304 /* SecCoreAnalytics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecCoreAnalytics.h; sourceTree = ""; }; + EBE8258F2193353300102304 /* SecCoreAnalytics.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecCoreAnalytics.m; sourceTree = ""; }; EBEEEE351EA31A8300E15F5C /* SOSControlHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SOSControlHelper.h; sourceTree = ""; }; EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SOSControlHelper.m; sourceTree = ""; }; EBF3745E1DBFB32A0065D840 /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = usr/lib/libobjc.dylib; sourceTree = SDKROOT; }; EBF374721DC055580065D840 /* security-sysdiagnose */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "security-sysdiagnose"; sourceTree = BUILT_PRODUCTS_DIR; }; EBF374741DC055590065D840 /* security-sysdiagnose.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "security-sysdiagnose.m"; sourceTree = ""; }; EBF3747F1DC057FE0065D840 /* security-sysdiagnose.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = "security-sysdiagnose.1"; sourceTree = ""; }; - EBF3749A1DC064200065D840 /* SecADWrapper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = SecADWrapper.c; path = src/SecADWrapper.c; sourceTree = ""; }; - EBF3749B1DC064200065D840 /* SecADWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SecADWrapper.h; path = src/SecADWrapper.h; sourceTree = ""; }; + EBF3749A1DC064200065D840 /* SecADWrapper.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SecADWrapper.c; sourceTree = ""; }; + EBF3749B1DC064200065D840 /* SecADWrapper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecADWrapper.h; sourceTree = ""; }; EBF9AE171F536D0300FECBF7 /* Version.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Version.xcconfig; path = xcconfig/Version.xcconfig; sourceTree = ""; }; F619D71D1ED70BB0005B5F46 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = OSX/authorizationdump/main.m; sourceTree = ""; }; F621D07F1ED6DCE7000EA569 /* authorizationdump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = authorizationdump; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -13376,10 +15935,10 @@ F6A0971E1E953A1500B1E7D6 /* authdtestlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = authdtestlist.h; path = OSX/authd/tests/authdtestlist.h; sourceTree = ""; }; F6A0971F1E953ABD00B1E7D6 /* authdtests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = authdtests.m; path = OSX/authd/tests/authdtests.m; sourceTree = ""; }; F6A3CB0D1E7062BA00E7821F /* authd-Entitlements.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "authd-Entitlements.plist"; path = "OSX/authd/authd-Entitlements.plist"; sourceTree = ""; }; - F93C493A1AB8FF530047E01A /* ckcdiagnose.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ckcdiagnose.sh; sourceTree = ""; }; + F6D600702166551800F9F7C9 /* AuthorizationTrampolinePriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AuthorizationTrampolinePriv.h; path = OSX/libsecurity_authorization/lib/AuthorizationTrampolinePriv.h; sourceTree = ""; }; F9B458272183E01100F6BCEB /* SignatureEditing.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = SignatureEditing.sh; path = OSX/codesign_tests/SignatureEditing.sh; sourceTree = ""; }; - F9C8AFC5223740C700E7D6AE /* requirement.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = requirement.c; sourceTree = ""; }; - F9C8AFCB223740C800E7D6AE /* requirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = requirement.h; sourceTree = ""; }; + F9F77E96223C2F7B00E5CBF6 /* requirement.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = requirement.c; sourceTree = ""; }; + F9F77E97223C2F7C00E5CBF6 /* requirement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = requirement.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -13387,6 +15946,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DCF46572220114E400BA6EEA /* CloudServices.framework in Frameworks */, + EB80DE55219600BF005B10FA /* libz.tbd in Frameworks */, + DC9C066E2149E35F00C6F7B8 /* AuthKit.framework in Frameworks */, + D42C838B21158EF4008D3D83 /* libCMS.a in Frameworks */, 474B5FC71E662E67007546F8 /* SecurityFoundation.framework in Frameworks */, 6C8CC3B61E2F98C2009025C5 /* ProtocolBuffer.framework in Frameworks */, D40B6A8D1E2B63D900CD6EE5 /* libtrustd.a in Frameworks */, @@ -13394,8 +15957,7 @@ DCD22D8D1D8CCC79001C9B81 /* libregressionBase.a in Frameworks */, 438168C51B4ED43B00C54D58 /* CoreFoundation.framework in Frameworks */, EB3409B01C1D627400D77661 /* Foundation.framework in Frameworks */, - DCD22D8B1D8CCC58001C9B81 /* libASN1_not_installed.a in Frameworks */, - DC59E9A71D91C7C7001BDDF5 /* libCMS.a in Frameworks */, + DCD22D8B1D8CCC58001C9B81 /* libASN1.a in Frameworks */, D491116C2095594A0066A1E4 /* CoreData.framework in Frameworks */, DC00ABD71D821F3F00513D74 /* libsecurity.a in Frameworks */, DC00ABD81D821F4300513D74 /* libsecdRegressions.a in Frameworks */, @@ -13410,7 +15972,6 @@ 0C0BDB931756A8C900BC1A7E /* SystemConfiguration.framework in Frameworks */, D46246B81F9AE77900D63882 /* libDER.a in Frameworks */, 5E8B53A51AA0B8A600345E7B /* libcoreauthd_test_client.a in Frameworks */, - 4432B15F1A014D55000958DC /* libaks_acl.a in Frameworks */, 0C0BDB8F1756A6D500BC1A7E /* libMobileGestalt.dylib in Frameworks */, 0C0BDB881756A51000BC1A7E /* libsqlite3.dylib in Frameworks */, BE8ABDD81DC2DD9100EC2D58 /* libz.dylib in Frameworks */, @@ -13442,8 +16003,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C85DFE71FB38BB6000343A7 /* libASN1_not_installed.a in Frameworks */, - 0C85DFE81FB38BB6000343A7 /* libsecurityd_ios_NO_AKS.a in Frameworks */, + DC6013392147227800863C1A /* libsecurityd_ios.a in Frameworks */, + DCCFB14F21239534003D2DA2 /* libaks_mock.a in Frameworks */, + 0C7A8BC021714D0E00F4C480 /* AuthKit.framework in Frameworks */, + 0C85DFE71FB38BB6000343A7 /* libASN1.a in Frameworks */, 0C85DFE91FB38BB6000343A7 /* libSecureObjectSyncFramework.a in Frameworks */, 0C85DFEA1FB38BB6000343A7 /* libSecureObjectSyncServer.a in Frameworks */, 0C85DFEB1FB38BB6000343A7 /* libsecurity.a in Frameworks */, @@ -13459,6 +16022,7 @@ 0C85DFF61FB38BB6000343A7 /* libDER.a in Frameworks */, 0C85DFF71FB38BB6000343A7 /* libbsm.dylib in Frameworks */, D491116E209559510066A1E4 /* CoreData.framework in Frameworks */, + 0CE780A321421C730049340E /* libcompression.tbd in Frameworks */, 0C85DFF81FB38BB6000343A7 /* libcoreauthd_client.a in Frameworks */, 0C85DFF91FB38BB6000343A7 /* libctkclient_sep.a in Frameworks */, 0C85DFFA1FB38BB6000343A7 /* libsqlite3.0.dylib in Frameworks */, @@ -13470,7 +16034,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C8BBF031FCB446400580909 /* Security.framework in Frameworks */, + 0C84D83D1FCF449700B822E3 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -13498,10 +16062,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 3D58393E21890FFB000ACA44 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3D55EA832242F50B008E7459 /* Security.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 3DD1FF2F201C07F30086D049 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5AA465E12229A40400C068F4 /* Security.framework in Frameworks */, + AAD6630A203362490073E17B /* libnetwork.tbd in Frameworks */, 3DD1FFAA201FC5C30086D049 /* libcoretls.tbd in Frameworks */, 3DD1FFAB201FC5C30086D049 /* libcoretls_cfhelpers.tbd in Frameworks */, 3DD1FFA7201FC5B90086D049 /* Foundation.framework in Frameworks */, @@ -13516,7 +16090,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3DD1FFD2201FDCA80086D049 /* Security.framework in Frameworks */, + AAA5FC7E21664D1D00B52A48 /* Security.framework in Frameworks */, + AAD6630B203362500073E17B /* libnetwork.tbd in Frameworks */, 3DD1FFC4201FDB1D0086D049 /* libcoretls.tbd in Frameworks */, 3DD1FFC5201FDB1D0086D049 /* libcoretls_cfhelpers.tbd in Frameworks */, 3DD1FFC6201FDB1D0086D049 /* Foundation.framework in Frameworks */, @@ -13530,6 +16105,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + EB86BEF6222C3C0500EC0F13 /* AppleAccount.framework in Frameworks */, 438169E41B4EE13B00C54D58 /* Accounts.framework in Frameworks */, 438169E51B4EE14D00C54D58 /* Security.framework in Frameworks */, 4381690D1B4EDCBD00C54D58 /* Foundation.framework in Frameworks */, @@ -13549,13 +16125,13 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 6CD1DBED21F9281D00D158FB /* SecurityFoundation.framework in Frameworks */, 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 */, @@ -13577,6 +16153,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76AB221269B8006F2D8F /* CloudServices.framework in Frameworks */, + EB7732D921963BA500FCF513 /* libz.dylib in Frameworks */, + 482FE56E2177CF340031C11E /* AuthKit.framework in Frameworks */, 479231F02065C52D00B2718C /* Security.framework in Frameworks */, 479231EF2065C52200B2718C /* libsecurity.a in Frameworks */, 479231E82065B31300B2718C /* libsecurityd_ios.a in Frameworks */, @@ -13634,6 +16213,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76AA22126993006F2D8F /* CloudServices.framework in Frameworks */, + 0C6C0FD221F146E700CD5B9E /* CoreCDP.framework in Frameworks */, + EB7732DB21963BC100FCF513 /* libz.tbd in Frameworks */, + 482FE56A2177C7980031C11E /* AuthKit.framework in Frameworks */, 479231EE2065B32200B2718C /* libsecurityd_ios.a in Frameworks */, 477A1F5320320E5100ACD81D /* Accounts.framework in Frameworks */, 478D429F1FD72C8400CAB645 /* AppleSystemInfo.framework in Frameworks */, @@ -13686,6 +16269,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D42C838A21158B90008D3D83 /* libCMS.a in Frameworks */, CD791B3C1DFC9A7600F0E5DC /* libsqlite3.0.dylib in Frameworks */, DC3A81D31D99D561000C7419 /* libcoretls.dylib in Frameworks */, DC3A81D51D99D568000C7419 /* libcoretls_cfhelpers.dylib in Frameworks */, @@ -13693,9 +16277,8 @@ DCD8A19A1E09EE9800E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, 0C78F1D016A5E3EB00654E08 /* libbsm.dylib in Frameworks */, D46246971F9AE2E400D63882 /* libDER.a in Frameworks */, - DCD22D771D8CC9CD001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D771D8CC9CD001C9B81 /* libASN1.a in Frameworks */, 44A655831AA4B4BB0059D185 /* libctkclient_sep.a in Frameworks */, - DC59E9A41D91C6F0001BDDF5 /* libCMS.a in Frameworks */, DCD22D781D8CC9D8001C9B81 /* libsecurity_ssl.a in Frameworks */, CD791B3D1DFC9AB200F0E5DC /* libsqlite3.dylib in Frameworks */, DC00AB631D821BEF00513D74 /* libsecurity.a in Frameworks */, @@ -13738,6 +16321,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76AD22126A17006F2D8F /* CloudServices.framework in Frameworks */, + 0C6C0FD621F14D3900CD5B9E /* CoreCDP.framework in Frameworks */, + EB80DE5B219600FC005B10FA /* libz.tbd in Frameworks */, + 482FE56F2177CF520031C11E /* AuthKit.framework in Frameworks */, D4C6C5CF1FB3B44D007EA57E /* libarchive.2.dylib in Frameworks */, D40B6A8E1E2B643500CD6EE5 /* libtrustd.a in Frameworks */, DC00ABB31D821E0400513D74 /* libSharedRegressions.a in Frameworks */, @@ -13749,7 +16336,7 @@ DC00ABB51D821E0B00513D74 /* libSecureObjectSyncServer.a in Frameworks */, DCD8A1F91E09F98E00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, D46246B51F9AE74000D63882 /* libDER.a in Frameworks */, - DCD22D9B1D8CCFCB001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D9B1D8CCFCB001C9B81 /* libASN1.a in Frameworks */, DC65E7771D8CB82500152EF0 /* libregressionBase.a in Frameworks */, 438168C01B4ED42C00C54D58 /* CoreFoundation.framework in Frameworks */, DCD22D9C1D8CCFD6001C9B81 /* libutilitiesRegressions.a in Frameworks */, @@ -13791,18 +16378,18 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76A5221268A6006F2D8F /* CloudServices.framework in Frameworks */, + EB7732C221963B0500FCF513 /* libz.tbd in Frameworks */, + 482FE56C2177CEEF0031C11E /* AuthKit.framework in Frameworks */, 0C9FB40920D8735500864612 /* CoreCDP.framework in Frameworks */, 47D13F631E8447FB0063B6E2 /* SecurityFoundation.framework in Frameworks */, EBE9019A1C22852C007308C6 /* AggregateDictionary.framework in Frameworks */, 438168BB1B4ED42300C54D58 /* CoreFoundation.framework in Frameworks */, DC00AB8E1D821D4900513D74 /* libSOSCommands.a in Frameworks */, - DC00AB8F1D821D4D00513D74 /* libSecurityTool.a in Frameworks */, - DC00AB901D821D5600513D74 /* libSecurityCommands.a in Frameworks */, 5296CB4F1655B92F009912AF /* libMobileGestalt.dylib in Frameworks */, 4432B0B71A014987000958DC /* libaks_acl.a in Frameworks */, DC65E7361D8CB35E00152EF0 /* libutilities.a in Frameworks */, DCD22D861D8CCBBB001C9B81 /* libSecureObjectSyncServer.a in Frameworks */, - DCD8A1EA1E09F87B00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, DCD22D851D8CCBB6001C9B81 /* libsecurityd_ios.a in Frameworks */, 4C32C1A60A497A21002891BD /* Security.framework in Frameworks */, 4CAE95DC0F3D6E020075278E /* CFNetwork.framework in Frameworks */, @@ -13836,6 +16423,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC176232224C57D600BB9A6E /* AuthKit.framework in Frameworks */, 5328C0521738903F00708984 /* Security.framework in Frameworks */, 5346481F17332F9C00FE9172 /* Accounts.framework in Frameworks */, 5346480217331E1200FE9172 /* Foundation.framework in Frameworks */, @@ -13855,9 +16443,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76A02212676D006F2D8F /* CloudServices.framework in Frameworks */, + 0C6C0FCB21F1415B00CD5B9E /* CoreCDP.framework in Frameworks */, + EB80DE5D21960C0A005B10FA /* libz.tbd in Frameworks */, + 482FE5662177C6E40031C11E /* AuthKit.framework in Frameworks */, + 482FE5652177C6D90031C11E /* Accounts.framework in Frameworks */, D46246BA1F9AE7A000D63882 /* libDER.a in Frameworks */, DCCD34001E4001AD00AA4AD1 /* libACM.a in Frameworks */, - DCAB14271E40039600C81511 /* libASN1_not_installed.a in Frameworks */, + DCAB14271E40039600C81511 /* libASN1.a in Frameworks */, EBF2D73C1C1E2B47006AB6FF /* Foundation.framework in Frameworks */, DCD22D801D8CCB0F001C9B81 /* libutilities.a in Frameworks */, DC00ABCC1D821F0B00513D74 /* libsecurityd_ios.a in Frameworks */, @@ -13874,12 +16467,45 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 6C39235A21F13E4D00D018AD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C8FF4B3224C1A8D00E5C812 /* TrustedPeers.framework in Frameworks */, + 6C540C3922289A3B0032B5BC /* CloudServices.framework in Frameworks */, + 6C39235B21F13E4D00D018AD /* libz.dylib in Frameworks */, + 6C39235C21F13E4D00D018AD /* AuthKit.framework in Frameworks */, + 6C39235D21F13E4D00D018AD /* Security.framework in Frameworks */, + 6C39235E21F13E4D00D018AD /* libsecurity.a in Frameworks */, + 6C39235F21F13E4D00D018AD /* libsecurityd_ios.a in Frameworks */, + 6C39236021F13E4D00D018AD /* Accounts.framework in Frameworks */, + 6C39236121F13E4D00D018AD /* libprequelite.dylib in Frameworks */, + 6C39236321F13E4D00D018AD /* libregressionBase.a in Frameworks */, + 6C39236421F13E4D00D018AD /* libACM.a in Frameworks */, + 6C39236521F13E4D00D018AD /* ApplePushService.framework in Frameworks */, + 6C39236621F13E4D00D018AD /* SharedWebCredentials.framework in Frameworks */, + 6C39236721F13E4D00D018AD /* IOKit.framework in Frameworks */, + 6C39236821F13E4D00D018AD /* WirelessDiagnostics.framework in Frameworks */, + 6C39236921F13E4D00D018AD /* SystemConfiguration.framework in Frameworks */, + 6C39236A21F13E4D00D018AD /* libSecureObjectSyncServer.a in Frameworks */, + 6C39236B21F13E4D00D018AD /* libSecureObjectSyncFramework.a in Frameworks */, + 6C39236C21F13E4D00D018AD /* ProtocolBuffer.framework in Frameworks */, + 6C39236D21F13E4D00D018AD /* CoreData.framework in Frameworks */, + 6C39236E21F13E4D00D018AD /* CloudKit.framework in Frameworks */, + 6C39237021F13E4D00D018AD /* SecurityFoundation.framework in Frameworks */, + 6C39237121F13E4D00D018AD /* libsqlite3.dylib in Frameworks */, + 6C39237221F13E4D00D018AD /* libutilities.a in Frameworks */, + 6C39237321F13E4D00D018AD /* libsecdRegressions.a in Frameworks */, + 6C39237421F13E4D00D018AD /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 6C46059B1F882B9B001421B6 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5AF7630920520870001557AE /* AuthKit.framework in Frameworks */, - 5A4E527B2051D857009D5826 /* Accounts.framework in Frameworks */, + D4A7DD7520A26D4900F51F3F /* AuthKit.framework in Frameworks */, + AA15CB4F2076C9D500C1A978 /* Accounts.framework in Frameworks */, D4119E79202BDF580048587B /* libz.tbd in Frameworks */, 6CDB601B1FA93A2000410924 /* libprequelite.tbd in Frameworks */, 6CDB601A1FA93A1800410924 /* libsqlite3.tbd in Frameworks */, @@ -13894,12 +16520,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76A822126959006F2D8F /* CloudServices.framework in Frameworks */, + 0C4D96A721F25F2C00617E60 /* CoreCDP.framework in Frameworks */, + 482FE5672177C7260031C11E /* AuthKit.framework in Frameworks */, 6CAA8CDD1F82EDEF007B6E03 /* Security.framework in Frameworks */, D46246BC1F9AE82B00D63882 /* libDER.a in Frameworks */, - 6C98084A1E788AEB00E70590 /* libASN1_not_installed.a in Frameworks */, - 6C98084C1E788AEB00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */, + 6C98084A1E788AEB00E70590 /* libASN1.a in Frameworks */, 6C98084D1E788AEB00E70590 /* libSecureObjectSyncFramework.a in Frameworks */, 6C98084E1E788AEB00E70590 /* libSecureObjectSyncServer.a in Frameworks */, + DC93C4C5214713C5008F8362 /* libaks_mock.a in Frameworks */, + DC93C4D021471FD8008F8362 /* libsecurityd_ios.a in Frameworks */, 6C98084F1E788AEB00E70590 /* libsecurity.a in Frameworks */, 6C9808501E788AEB00E70590 /* libutilities.a in Frameworks */, 6C9808511E788AEB00E70590 /* CFNetwork.framework in Frameworks */, @@ -13922,12 +16552,16 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76A72212694F006F2D8F /* CloudServices.framework in Frameworks */, + 0C6C0FD021F145F600CD5B9E /* CoreCDP.framework in Frameworks */, + 482FE5682177C73C0031C11E /* AuthKit.framework in Frameworks */, 6CAA8CEE1F83E417007B6E03 /* Security.framework in Frameworks */, D46246BD1F9AE83600D63882 /* libDER.a in Frameworks */, - 6C9808861E788AFD00E70590 /* libASN1_not_installed.a in Frameworks */, - 6C9808881E788AFD00E70590 /* libsecurityd_ios_NO_AKS.a in Frameworks */, + 6C9808861E788AFD00E70590 /* libASN1.a in Frameworks */, 6C9808891E788AFD00E70590 /* libSecureObjectSyncFramework.a in Frameworks */, 6C98088A1E788AFD00E70590 /* libSecureObjectSyncServer.a in Frameworks */, + DC93C4CB214713ED008F8362 /* libaks_mock.a in Frameworks */, + DC93C4CA214713E5008F8362 /* libsecurityd_ios.a in Frameworks */, 6C98088B1E788AFD00E70590 /* libsecurity.a in Frameworks */, 6C98088C1E788AFD00E70590 /* libutilities.a in Frameworks */, 6C98088D1E788AFD00E70590 /* CFNetwork.framework in Frameworks */, @@ -13959,10 +16593,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5AF762FF2051F990001557AE /* AuthKit.framework in Frameworks */, - 5A4E52792051D7FA009D5826 /* Accounts.framework in Frameworks */, + AA15CB4D2076C5A900C1A978 /* Accounts.framework in Frameworks */, D4119E78202BDF490048587B /* libz.tbd in Frameworks */, 6CAA8D3B1F8431AE007B6E03 /* Foundation.framework in Frameworks */, + D4A7DD7420A26D3D00F51F3F /* AuthKit.framework in Frameworks */, 6CAA8D3A1F8431A7007B6E03 /* libutilities.a in Frameworks */, 6CAA8D371F843196007B6E03 /* Security.framework in Frameworks */, ); @@ -13998,19 +16632,20 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DCF46571220110E100BA6EEA /* CloudServices.framework in Frameworks */, + EB80DE5A219600F2005B10FA /* libz.tbd in Frameworks */, + DC9C066D2149E33D00C6F7B8 /* AuthKit.framework in Frameworks */, D47CA65D1EB036450038E2BB /* libMobileGestalt.dylib in Frameworks */, CD9F2AF81DF23CA600AD3577 /* Foundation.framework in Frameworks */, DC65E72A1D8CB2FC00152EF0 /* libutilities.a in Frameworks */, 438168941B4ED42300C54D58 /* CoreFoundation.framework in Frameworks */, DC00AB811D821C9100513D74 /* libsecurityd_ios.a in Frameworks */, DC00AB821D821C9500513D74 /* libSecureObjectSyncServer.a in Frameworks */, - 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 */, 4C2215220F3A612C00835155 /* libsqlite3.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -14021,7 +16656,6 @@ files = ( DCD22D881D8CCBEF001C9B81 /* libSecureObjectSyncServer.a in Frameworks */, DCD22D871D8CCBEA001C9B81 /* libsecurityd_ios.a in Frameworks */, - DC00ABEC1D821FA600513D74 /* libSecurityTool.a in Frameworks */, 5296CB501655B990009912AF /* libMobileGestalt.dylib in Frameworks */, DCD22D751D8CC8A5001C9B81 /* libutilities.a in Frameworks */, 4432B1A61A024231000958DC /* libaks_acl.a in Frameworks */, @@ -14074,6 +16708,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BEAA0028202A832500E51F45 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BECEC11C20A634E000E97255 /* ProtocolBuffer.framework in Frameworks */, + BEAA0046202B785000E51F45 /* Foundation.framework in Frameworks */, + D401E8B420A26F1F00CD8BB4 /* CoreData.framework in Frameworks */, + DC340C54208E828F004D7EEC /* TrustedPeers.framework in Frameworks */, + BE9F8D15206C2E0200B53D16 /* libutilities.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BECFA42B20F91AFE00B11002 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + BECFA43B20F91CE500B11002 /* ProtocolBuffer.framework in Frameworks */, + BECFA43A20F91B8300B11002 /* TrustedPeers.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; BED208D71EDF950E00753952 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14083,6 +16738,30 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BED987D02099145300607A5F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DCF46575220115E300BA6EEA /* CloudServices.framework in Frameworks */, + DC00C92320B3B80500628BEB /* libbsm.tbd in Frameworks */, + DC00C92420B3B82600628BEB /* libz.tbd in Frameworks */, + DC00C92020B3B7CC00628BEB /* libDER.a in Frameworks */, + DC6013312147220F00863C1A /* libaks_mock.a in Frameworks */, + DC60132E2147220600863C1A /* libsecurityd_ios.a in Frameworks */, + BE53602D209BBF630027E25A /* libMobileGestalt.tbd in Frameworks */, + DC9C06712149E6B900C6F7B8 /* AuthKit.framework in Frameworks */, + BE536019209BB76B0027E25A /* CloudKit.framework in Frameworks */, + DC00C93420B48B4100628BEB /* SystemConfiguration.framework in Frameworks */, + BED987DF209918A500607A5F /* SecurityFoundation.framework in Frameworks */, + BED987D82099145300607A5F /* TrustedPeers.framework in Frameworks */, + DC00C93520B48BA800628BEB /* IOKit.framework in Frameworks */, + DC00C91D20B3B79600628BEB /* libsecurity.a in Frameworks */, + BE53601C209BB8970027E25A /* libSecureObjectSyncFramework.a in Frameworks */, + BE53601B209BB8390027E25A /* libSecureObjectSyncServer.a in Frameworks */, + BE53601A209BB7F80027E25A /* libutilities.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; BEF88C241EAFFC3F00357577 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14094,7 +16773,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - BEF88C311EAFFC3F00357577 /* TrustedPeers.framework in Frameworks */, + 1B916CCE223FFED7006657FD /* libprotobuf_source_generation.a in Frameworks */, + DC730E2922401F5E0051DD48 /* ProtocolBuffer.framework in Frameworks */, + DC730E2522401E310051DD48 /* TrustedPeers.framework in Frameworks */, + 1B916CD0223FFF25006657FD /* ProtocolBuffer.framework in Frameworks */, + BE72782C209D2C1400F0DA77 /* SecurityFoundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14115,6 +16798,74 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D42C839621159146008D3D83 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D44D1F642115893000E76E1A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D453A4B12122236D00850A26 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D4FD4225217D7BEE002B7EE2 /* libarchive.2.tbd in Frameworks */, + D453A4B22122236D00850A26 /* libz.tbd in Frameworks */, + D453A4B32122236D00850A26 /* libsqlite3.tbd in Frameworks */, + D453A4B42122236D00850A26 /* libDER.a in Frameworks */, + D453A4B52122236D00850A26 /* libutilities.a in Frameworks */, + D4428B36212262F800EB8448 /* libASN1.a in Frameworks */, + D453A4B62122236D00850A26 /* libtrustd.a in Frameworks */, + D4EF32172156B025000A31A5 /* Security.framework in Frameworks */, + D453A4B82122236D00850A26 /* CoreFoundation.framework in Frameworks */, + D453A4B92122236D00850A26 /* Foundation.framework in Frameworks */, + D453A4BA2122236D00850A26 /* IOKit.framework in Frameworks */, + D40B7CA021605BF800AC9A75 /* OCMock.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D458C4DE214E1DE00043D982 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D458C501214E1FB00043D982 /* Foundation.framework in Frameworks */, + D458C4FF214E1F8E0043D982 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D458C503214E20530043D982 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D458C512214E20850043D982 /* XCTest.framework in Frameworks */, + D458C507214E20540043D982 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D4707A0221136E69005BCFDA /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D4FD4224217D7BE4002B7EE2 /* libarchive.2.tbd in Frameworks */, + D4B68C62211A80CE009FED69 /* libz.tbd in Frameworks */, + D4B68C5F211A80B1009FED69 /* libsqlite3.tbd in Frameworks */, + D4B68C5D211A7D98009FED69 /* libDER.a in Frameworks */, + D4B68C5B211A7D29009FED69 /* libutilities.a in Frameworks */, + D4B68C44211A3DCC009FED69 /* libtrustd.a in Frameworks */, + D453A4A32122235700850A26 /* Security.framework in Frameworks */, + D4B68C60211A80BC009FED69 /* CoreFoundation.framework in Frameworks */, + D4B68C61211A80C4009FED69 /* Foundation.framework in Frameworks */, + D4B68C63211A80DA009FED69 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; D4ADA3161E2B41670031CEA3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14122,6 +16873,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D4D1FDDA21165F8B003538E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA30D6731DF8C8FB00EC6B43 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14129,6 +16887,19 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DA41FE0B2241ADC000838FB3 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0CC593F92299EE06006C34B5 /* libsecurityd_ios.a in Frameworks */, + 0CE887D52299A9C70082D120 /* SystemConfiguration.framework in Frameworks */, + 0CE887D32299A9090082D120 /* libutilities.a in Frameworks */, + 0CE887D22299A8CF0082D120 /* libMobileGestalt.tbd in Frameworks */, + DA41FE1B2241AF8200838FB3 /* IDS.framework in Frameworks */, + DAC58D1B22443C0700D4CD41 /* KeychainCircle.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DAE40BC820CF3E46002D5674 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14152,6 +16923,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DC05037321409A4000A8EDB7 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DC05038221409B3400A8EDB7 /* OCMock.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DC0BC54E1D8B6D2D00070CB0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14297,7 +17076,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCC1A1D8C653600070CB0 /* MobileKeyBag.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14305,7 +17083,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCC291D8C684F00070CB0 /* MobileKeyBag.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14313,7 +17090,17 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCD1D1D8C694700070CB0 /* MobileKeyBag.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC0EF8EC208697C600AB9E95 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DCFFE96D2277E0E90092069C /* TrustedPeers.framework in Frameworks */, + DCB41DF4216C2DD300F219E0 /* AppleAccount.framework in Frameworks */, + DCB41DF1216C2DBB00F219E0 /* AuthKit.framework in Frameworks */, + DC99B88020EACA470065B73B /* libMobileGestalt.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14322,8 +17109,7 @@ buildActionMask = 2147483647; files = ( 4C47FA9420A51DD800384CB6 /* AppleFSCompression.framework in Frameworks */, - CD9F2AFB1DF24BAF00AD3577 /* Foundation.framework in Frameworks */, - DCD22D4B1D8CBF54001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D4B1D8CBF54001C9B81 /* libASN1.a in Frameworks */, DC00AB6F1D821C3400513D74 /* libSecItemShimOSX.a in Frameworks */, DC00AB701D821C3800513D74 /* libSecOtrOSX.a in Frameworks */, DC00AB6B1D821C1A00513D74 /* libSecTrustOSX.a in Frameworks */, @@ -14340,7 +17126,7 @@ DCD22D4D1D8CBF95001C9B81 /* libsecurity_cdsa_utilities.a in Frameworks */, DCD22D4E1D8CBFAB001C9B81 /* libsecurity_cdsa_utils.a in Frameworks */, DCC5BF211D937269008D1E84 /* libsecurity_checkpw.a in Frameworks */, - DCC5BF221D937270008D1E84 /* libsecurity_cms.a in Frameworks */, + D42C839F211593D8008D3D83 /* libsecurity_cms.a in Frameworks */, DCD06BD51D8E173A007602F1 /* libsecurity_codesigning.a in Frameworks */, DCC5BF231D937277008D1E84 /* libsecurity_comcryption.a in Frameworks */, DCC5BF241D93727E008D1E84 /* libsecurity_cryptkit.a in Frameworks */, @@ -14352,7 +17138,6 @@ DCD06BD31D8E1628007602F1 /* libsecurity_ocspd.a in Frameworks */, DCD06BD11D8E15ED007602F1 /* libsecurity_pkcs12.a in Frameworks */, DCC5BF291D93729A008D1E84 /* libsecurity_sd_cspdl.a in Frameworks */, - DC1789471D779AAF00B50D50 /* libsecurity_smime.a in Frameworks */, DCC5BF2A1D93729E008D1E84 /* libsecurity_ssl.a in Frameworks */, DCC5BF2B1D9372A4008D1E84 /* libsecurity_transform.a in Frameworks */, DCC5BF2C1D9372AA008D1E84 /* libsecurity_translocate.a in Frameworks */, @@ -14360,7 +17145,6 @@ DCD22D4C1D8CBF7E001C9B81 /* libsecurityd_client.a in Frameworks */, DC65E7241D8CB29E00152EF0 /* libutilities.a in Frameworks */, DC1789131D7798B300B50D50 /* libDiagnosticMessagesClient.dylib in Frameworks */, - DC1789151D77997F00B50D50 /* libOpenScriptingUtil.dylib in Frameworks */, DC1789281D779A0F00B50D50 /* libaks_acl.a in Frameworks */, DC1789171D77998700B50D50 /* libauto.dylib in Frameworks */, DC1789191D77998C00B50D50 /* libbsm.dylib in Frameworks */, @@ -14379,7 +17163,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC222C631E034D1F00B09171 /* Frameworks */ = { + DC311E732124B8A8002F5EAE /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -14390,30 +17174,36 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DCF465742201155000BA6EEA /* CloudServices.framework in Frameworks */, + 0C6C0FD121F1465500CD5B9E /* CoreCDP.framework in Frameworks */, + DC391FAE21C1903E00772585 /* libutilities.a in Frameworks */, + EBD531772198AF19003A57E6 /* Accounts.framework in Frameworks */, + EBD531762198AF0B003A57E6 /* AppleAccount.framework in Frameworks */, + DC9C06702149E3CB00C6F7B8 /* AuthKit.framework in Frameworks */, D46246BE1F9AE86400D63882 /* libDER.a in Frameworks */, 47A0ABA81E6F7B24001B388C /* SecurityFoundation.framework in Frameworks */, - DC3502C51E020D5100BC0587 /* libASN1_not_installed.a in Frameworks */, - DC222C7A1E034EF700B09171 /* libsecurityd_ios_NO_AKS.a in Frameworks */, - DC0984FD1E1DB6DF00140ADC /* libSecureObjectSyncFramework.a in Frameworks */, + DC3502C51E020D5100BC0587 /* libASN1.a in Frameworks */, DC0984FE1E1DB70100140ADC /* libSecureObjectSyncServer.a in Frameworks */, - DC3502D61E02118000BC0587 /* libsecurity.a in Frameworks */, - DC3502CF1E020E2900BC0587 /* libutilities.a in Frameworks */, + DC311E682124A9E1002F5EAE /* libsecurityd_ios.a in Frameworks */, DC222C351E02418100B09171 /* CFNetwork.framework in Frameworks */, D491116F209559510066A1E4 /* CoreData.framework in Frameworks */, DC3502DF1E02129F00BC0587 /* Foundation.framework in Frameworks */, DC3502D21E02113900BC0587 /* IOKit.framework in Frameworks */, DC3502E91E02172C00BC0587 /* OCMock.framework in Frameworks */, DC3502E31E0212E600BC0587 /* SystemConfiguration.framework in Frameworks */, - DC3502D31E02115200BC0587 /* libACM.a in Frameworks */, - DC0950411E38271300B2C8AC /* libaks_acl.a in Frameworks */, DC222C361E02419B00B09171 /* libbsm.dylib in Frameworks */, - DC3502E41E02130600BC0587 /* libcoreauthd_client.a in Frameworks */, - DC3502E21E0212D100BC0587 /* libctkclient_sep.a in Frameworks */, DC3502CA1E020DC100BC0587 /* libsqlite3.0.dylib in Frameworks */, DC222C321E0240D300B09171 /* libz.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; + DC36895C21235F42003A3735 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DC3A4B551D91E9FB00E46D4A /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14439,28 +17229,10 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EA471D80CB7000B0A59C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - DC52EAA31D80CCC300B0A59C /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DC52EBCF1D80CEF100B0A59C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - DC52EBD01D80CEF100B0A59C /* Foundation.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; DC52EC2E1D80CFB200B0A59C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C9FB40820D8731800864612 /* CoreCDP.framework in Frameworks */, - DC52EC2F1D80CFB200B0A59C /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14482,9 +17254,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7281E0971DFD0FD00021E1B7 /* Foundation.framework in Frameworks */, - DC52EC6C1D80D0E800B0A59C /* IDS.framework in Frameworks */, - DC52EC6B1D80D0E300B0A59C /* IDSFoundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14499,7 +17268,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - DC52EDA11D80D4FC00B0A59C /* IDS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14507,9 +17275,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7281E0881DFD06480021E1B7 /* Foundation.framework in Frameworks */, - DC52EDB21D80D59700B0A59C /* IDSFoundation.framework in Frameworks */, - DC52EDAC1D80D58400B0A59C /* IDS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14545,13 +17310,16 @@ buildActionMask = 2147483647; files = ( DC5ABE191D832F2700CF422C /* CoreFoundation.framework in Frameworks */, + BE64A7FA22AF006F001209F3 /* SecurityFoundation.framework in Frameworks */, DC5ABE181D832F2200CF422C /* Security.framework in Frameworks */, - DCD22D581D8CC1FA001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D581D8CC1FA001C9B81 /* libASN1.a in Frameworks */, DCD22D5C1D8CC224001C9B81 /* libutilities.a in Frameworks */, DCB7D8D01D8E183C00867385 /* libsecurity_utilities.a in Frameworks */, DCD22D591D8CC200001C9B81 /* libsecurity_cdsa_client.a in Frameworks */, DCD22D5A1D8CC205001C9B81 /* libsecurity_cdsa_utilities.a in Frameworks */, DCD22D5B1D8CC20D001C9B81 /* libsecurity_cdsa_utils.a in Frameworks */, + BE64A7FB22AF0084001209F3 /* CFNetwork.framework in Frameworks */, + BE64A7FC22AF008D001209F3 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14577,7 +17345,6 @@ 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 */, @@ -14590,6 +17357,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DCF46573220114F000BA6EEA /* CloudServices.framework in Frameworks */, + 0C4D96A621F24E5700617E60 /* CoreCDP.framework in Frameworks */, + EB80DE56219600C6005B10FA /* libz.tbd in Frameworks */, + DC9C066F2149E36900C6F7B8 /* AuthKit.framework in Frameworks */, 47C2F1762059A2300062DE30 /* libprequelite.tbd in Frameworks */, 0CA4EC10202BB5AF002B1D96 /* Accounts.framework in Frameworks */, 47B90C901F350966006500BC /* CrashReporterSupport.framework in Frameworks */, @@ -14599,10 +17370,9 @@ 6C5B36BA1E2F9B95008AD443 /* WirelessDiagnostics.framework in Frameworks */, DC610A3D1D78F25C002223DE /* libDiagnosticMessagesClient.dylib in Frameworks */, DC610A3B1D78F234002223DE /* libACM.a in Frameworks */, - DC610A391D78F1B7002223DE /* libaks.a in Frameworks */, DC610A2C1D78F129002223DE /* libaks_acl.a in Frameworks */, D46246B91F9AE79000D63882 /* libDER.a in Frameworks */, - DCD22D601D8CC2EF001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D601D8CC2EF001C9B81 /* libASN1.a in Frameworks */, DCD22D611D8CC2F8001C9B81 /* libbsm.dylib in Frameworks */, DC610A2B1D78F129002223DE /* libcoreauthd_test_client.a in Frameworks */, DC610A2F1D78F129002223DE /* libctkclient_test.a in Frameworks */, @@ -14616,7 +17386,6 @@ DC00ABE81D821F7D00513D74 /* libsecurityd_ios.a in Frameworks */, D40B6A901E2B673500CD6EE5 /* libtrustd.a in Frameworks */, DCD22D631D8CC33A001C9B81 /* libSOSRegressions.a in Frameworks */, - DCB332451F47856B00178C30 /* libSOSCommands.a in Frameworks */, DCD22D641D8CC341001C9B81 /* libutilities.a in Frameworks */, DCD22D651D8CC349001C9B81 /* libutilitiesRegressions.a in Frameworks */, DCDCCB3A1DF25D1D006E840E /* ApplePushService.framework in Frameworks */, @@ -14663,7 +17432,7 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - DC71D9DB1D95BA6C0065FB93 /* Frameworks */ = { + DC7FC44521EE914C003C39B8 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( @@ -14677,6 +17446,30 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DC99B87A20EACA470065B73B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DCF465762201162800BA6EEA /* CloudServices.framework in Frameworks */, + DC3E18C82125015300073D80 /* libsecurityd_ios.a in Frameworks */, + DCCFB14E212394EC003D2DA2 /* libaks_mock.a in Frameworks */, + DC99B87B20EACA470065B73B /* libbsm.tbd in Frameworks */, + DC99B87C20EACA470065B73B /* libz.tbd in Frameworks */, + DC99B87F20EACA470065B73B /* libDER.a in Frameworks */, + EBCC31B1228CF0FD000AF5D9 /* libMobileGestalt.tbd in Frameworks */, + DC9C06722149E6F500C6F7B8 /* AuthKit.framework in Frameworks */, + DC99B88220EACA470065B73B /* CloudKit.framework in Frameworks */, + 0CE780AF2142F1350049340E /* KeychainCircle.framework in Frameworks */, + DC99B88320EACA470065B73B /* SystemConfiguration.framework in Frameworks */, + DC99B88420EACA470065B73B /* SecurityFoundation.framework in Frameworks */, + DC99B88520EACA470065B73B /* TrustedPeers.framework in Frameworks */, + DC99B88620EACA470065B73B /* IOKit.framework in Frameworks */, + DC99B88920EACA470065B73B /* libSecureObjectSyncServer.a in Frameworks */, + DC99B88A20EACA470065B73B /* libutilities.a in Frameworks */, + DC99B88B20EACA470065B73B /* libASN1.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DCB340691D8A24DF0054D16E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14719,6 +17512,37 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DCBF4AC021FFC82100539F0A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DCBF4AC121FFC82100539F0A /* CoreCDP.framework in Frameworks */, + DCBF4AC221FFC82100539F0A /* libutilities.a in Frameworks */, + DCBF4AC321FFC82100539F0A /* Accounts.framework in Frameworks */, + DCBF4AC421FFC82100539F0A /* AppleAccount.framework in Frameworks */, + DCBF4AC521FFC82100539F0A /* AuthKit.framework in Frameworks */, + DCAB17DB2200E7A700E1DFCF /* CloudServices.framework in Frameworks */, + DCBF4AC621FFC82100539F0A /* libDER.a in Frameworks */, + DCBF4AC721FFC82100539F0A /* SecurityFoundation.framework in Frameworks */, + DCBF4AC821FFC82100539F0A /* libASN1.a in Frameworks */, + DCBF4AC921FFC82100539F0A /* libSecureObjectSyncServer.a in Frameworks */, + DCBF4ACA21FFC82100539F0A /* libsecurityd_ios.a in Frameworks */, + DCBF4ACB21FFC82100539F0A /* CFNetwork.framework in Frameworks */, + DCBF4ACC21FFC82100539F0A /* CoreData.framework in Frameworks */, + DCBF4ACD21FFC82100539F0A /* Foundation.framework in Frameworks */, + DCBF4ACE21FFC82100539F0A /* IOKit.framework in Frameworks */, + DCBF4ACF21FFC82100539F0A /* OCMock.framework in Frameworks */, + DCBF4AD021FFC82100539F0A /* SystemConfiguration.framework in Frameworks */, + DCBF4AD121FFC82100539F0A /* libACM.a in Frameworks */, + DCBF4AD221FFC82100539F0A /* libaks_acl.a in Frameworks */, + DCBF4AD321FFC82100539F0A /* libbsm.dylib in Frameworks */, + DCBF4AD421FFC82100539F0A /* libcoreauthd_client.a in Frameworks */, + DCBF4AD521FFC82100539F0A /* libctkclient_sep.a in Frameworks */, + DCBF4AD621FFC82100539F0A /* libsqlite3.0.dylib in Frameworks */, + DCBF4AD721FFC82100539F0A /* libz.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DCC78EA61D8088E200865A7C /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -14791,7 +17615,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C0582AE20D9657800D7BD7A /* CoreCDP.framework in Frameworks */, + DC4A76AE22126C49006F2D8F /* CloudServices.framework in Frameworks */, + EB80DE38219600A8005B10FA /* libz.tbd in Frameworks */, + 482FE5642177C6850031C11E /* libprequelite.tbd in Frameworks */, + 482FE5632177C5E80031C11E /* Accounts.framework in Frameworks */, + 482FE5602177C5DA0031C11E /* AuthKit.framework in Frameworks */, + 0C4C548020E1A53D00BA61BA /* CoreCDP.framework in Frameworks */, 6C1F93111DD5E41A00585608 /* libDiagnosticMessagesClient.dylib in Frameworks */, DCE4E6AE1D7A3C6A00AFB96E /* AppleSystemInfo.framework in Frameworks */, DCE4E6AD1D7A3B9700AFB96E /* libaks.a in Frameworks */, @@ -14801,8 +17630,6 @@ DC65E7BD1D8CBA6C00152EF0 /* libsecurityd_ios.a in Frameworks */, DC65E7781D8CB8A500152EF0 /* libSecureObjectSyncServer.a in Frameworks */, DC00AB971D821D7100513D74 /* libSOSCommands.a in Frameworks */, - DC00AB981D821D7400513D74 /* libSecurityTool.a in Frameworks */, - DC00AB991D821D7700513D74 /* libSecurityCommands.a in Frameworks */, DC65E7371D8CB37500152EF0 /* libutilities.a in Frameworks */, DC65E77A1D8CB8D200152EF0 /* libsqlite3.dylib in Frameworks */, DCE4E69B1D7A37FA00AFB96E /* libaks_acl.a in Frameworks */, @@ -14814,7 +17641,6 @@ DCE4E6A01D7A37FA00AFB96E /* Foundation.framework in Frameworks */, DC65E77B1D8CB8E800152EF0 /* IOKit.framework in Frameworks */, DC65E77C1D8CB8F100152EF0 /* MobileKeyBag.framework in Frameworks */, - DCD8A2011E09FAD900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -14834,11 +17660,10 @@ DCE4E7541D7A43B500AFB96E /* Foundation.framework in Frameworks */, DCE4E7681D7A43B500AFB96E /* IOKit.framework in Frameworks */, DC65E7751D8CB81000152EF0 /* libregressionBase.a in Frameworks */, - DC26710E1F3E932D00816EED /* libASN1_not_installed.a in Frameworks */, + DC26710E1F3E932D00816EED /* libASN1.a in Frameworks */, DC00ABC71D821EF400513D74 /* libSharedRegressions.a in Frameworks */, DCD22D551D8CC148001C9B81 /* libsecurity_keychain_regressions.a in Frameworks */, - DC63CAF81D91A15F00C03317 /* libsecurity_cms_regressions.a in Frameworks */, - DCE4E7C41D7A465500AFB96E /* libsecurity_smime_regressions.a in Frameworks */, + D4D1FDE32116608B003538E2 /* libsecurity_cms_regressions.a in Frameworks */, DCD22D571D8CC196001C9B81 /* libsecurity_ssl_regressions.a in Frameworks */, ACBAF6FC1E941B620007BA2F /* libsecurity_transform_regressions.a in Frameworks */, DCD22D561D8CC154001C9B81 /* libutilities.a in Frameworks */, @@ -14858,8 +17683,7 @@ DCE4E7EB1D7A4BB200AFB96E /* SecurityFoundation.framework in Frameworks */, DCE4E7EA1D7A4BAE00AFB96E /* CoreFoundation.framework in Frameworks */, DCD22D5E1D8CC269001C9B81 /* libsecurity_keychain_regressions.a in Frameworks */, - DCE4E7E81D7A4BA400AFB96E /* libsecurity_smime_regressions.a in Frameworks */, - DC0B622A1D9097C600D43BCB /* libsecurity_cms_regressions.a in Frameworks */, + D4D1FDE521166135003538E2 /* libsecurity_cms_regressions.a in Frameworks */, DCE4E7E71D7A4B9C00AFB96E /* IOKit.framework in Frameworks */, DCDCC8331D9B6A00006487E8 /* libcoretls.dylib in Frameworks */, ); @@ -14869,6 +17693,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC8E3DC4224460C6003D86DB /* TrustedPeers.framework in Frameworks */, + DCF46570220110C900BA6EEA /* CloudServices.framework in Frameworks */, + EB80DE54219600B4005B10FA /* libz.tbd in Frameworks */, + DCC19518214C53FD00C9E0B6 /* AuthKit.framework in Frameworks */, + DCC1951C214C668A00C9E0B6 /* AppleAccount.framework in Frameworks */, 0CA4EC11202BB5E9002B1D96 /* Accounts.framework in Frameworks */, 0C5960641FB2E2070095BA29 /* libprequelite.tbd in Frameworks */, 4710A6D91F34F21700745267 /* CrashReporterSupport.framework in Frameworks */, @@ -14881,13 +17710,11 @@ DCE4E8251D7A4EE400AFB96E /* libACM.a in Frameworks */, DCE4E8241D7A4ECD00AFB96E /* libaks.a in Frameworks */, DCE4E8231D7A4EC900AFB96E /* libaks_acl.a in Frameworks */, - DCD22D711D8CC78E001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D711D8CC78E001C9B81 /* libASN1.a in Frameworks */, DCE4E8201D7A4EAC00AFB96E /* libcoreauthd_client.a in Frameworks */, DCE4E81F1D7A4EA700AFB96E /* libctkclient_sep.a in Frameworks */, DCE4E81C1D7A4E8F00AFB96E /* libsqlite3.0.dylib in Frameworks */, - DCD8A2041E09FB0D00E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, DC00AB7A1D821C6B00513D74 /* libSecureObjectSyncServer.a in Frameworks */, - DC00AB7B1D821C6E00513D74 /* libsecurity.a in Frameworks */, DC65E7271D8CB2EC00152EF0 /* libutilities.a in Frameworks */, DC00AB7C1D821C7100513D74 /* libsecurityd_ios.a in Frameworks */, DCE4E8131D7A4E5300AFB96E /* CoreFoundation.framework in Frameworks */, @@ -14909,11 +17736,10 @@ D46246D41F9AEAE300D63882 /* libDER.a in Frameworks */, D40B6A9A1E2B68E800CD6EE5 /* libbsm.dylib in Frameworks */, D40B6A991E2B68A400CD6EE5 /* libz.dylib in Frameworks */, - D40B6A981E2B687F00CD6EE5 /* libDiagnosticMessagesClient.dylib in Frameworks */, D40B6A971E2B684900CD6EE5 /* libsqlite3.0.dylib in Frameworks */, D40B6A9E1E2B6A6F00CD6EE5 /* libtrustd.a in Frameworks */, D40B6A931E2B67E500CD6EE5 /* libutilities.a in Frameworks */, - D40B6A831E2B5F5B00CD6EE5 /* libASN1_not_installed.a in Frameworks */, + D40B6A831E2B5F5B00CD6EE5 /* libASN1.a in Frameworks */, D40B6A9D1E2B6A2700CD6EE5 /* login.framework in Frameworks */, D4ADA3311E2B43450031CEA3 /* CFNetwork.framework in Frameworks */, D4ADA3301E2B433B0031CEA3 /* Security.framework in Frameworks */, @@ -14927,6 +17753,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5E01F5B1227C859200BC884C /* Foundation.framework in Frameworks */, DCE4E8C91D7F356500AFB96E /* libsqlite3.dylib in Frameworks */, DCE4E8C81D7F355F00AFB96E /* libbsm.dylib in Frameworks */, DCE4E8C71D7F355900AFB96E /* Security.framework in Frameworks */, @@ -14952,7 +17779,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0C0582B820D9B70D00D7BD7A /* CoreCDP.framework in Frameworks */, + 0C4C547620E1A0B400BA61BA /* CoreCDP.framework in Frameworks */, CD112FC51DDA31AD00C77A07 /* Accounts.framework in Frameworks */, 0CC319241DA46FBF005D42EA /* ProtectedCloudStorage.framework in Frameworks */, DCE4E9401D7F3E4D00AFB96E /* Security.framework in Frameworks */, @@ -14965,6 +17792,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DCF216D521ADD5B10029CCC1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DCF783101D88B4DE00E694BB /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -15014,10 +17848,36 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E060D1992124780E0025B833 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E060D1A42124780F0025B833 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E060D1B4212478110025B833 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EBFF95EF214C823F0021CD14 /* KeychainCircle.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; E710C73F1331946400F85568 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76A62212691F006F2D8F /* CloudServices.framework in Frameworks */, + 0C6C0FCF21F1457600CD5B9E /* CoreCDP.framework in Frameworks */, + EB80DE5C2196010F005B10FA /* libz.tbd in Frameworks */, + 482FE56D2177CF150031C11E /* AuthKit.framework in Frameworks */, D4C6C5D01FB3B45E007EA57E /* libarchive.2.dylib in Frameworks */, D40B6A8F1E2B643D00CD6EE5 /* libtrustd.a in Frameworks */, DC00ABC01D821EBE00513D74 /* libSharedRegressions.a in Frameworks */, @@ -15030,7 +17890,7 @@ DC00ABC21D821EC600513D74 /* libSecureObjectSyncServer.a in Frameworks */, DCD8A1F31E09F91700E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, D46246B61F9AE75100D63882 /* libDER.a in Frameworks */, - DCD22D931D8CCD17001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D931D8CCD17001C9B81 /* libASN1.a in Frameworks */, DCD22D941D8CCDFA001C9B81 /* libutilities.a in Frameworks */, DC17890B1D77980500B50D50 /* Security.framework in Frameworks */, 438168BF1B4ED42C00C54D58 /* CoreFoundation.framework in Frameworks */, @@ -15076,10 +17936,10 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 5A47FFBE228F6D1B00F781B8 /* ProtocolBuffer.framework in Frameworks */, EB59D6731E95F01600997EAC /* libcompression.dylib in Frameworks */, DC65E7231D8CB28900152EF0 /* libutilities.a in Frameworks */, - E7D8489F1C6C244B0025BB44 /* Foundation.framework in Frameworks */, - E7650E6F1C7699DA00378669 /* Security.framework in Frameworks */, + D4F56B95217FC93500FCA6B7 /* Security.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -15093,52 +17953,14 @@ E7D848561C6C1E830025BB44 /* Foundation.framework in Frameworks */, DCDCCB361DF25C8D006E840E /* ApplePushService.framework in Frameworks */, E7F482E61C7640D300390FDB /* IOKit.framework in Frameworks */, - DC00ABA51D821DCD00513D74 /* libsecurity.a in Frameworks */, - DCD8A1F61E09F96900E4FA0A /* libSecureObjectSyncFramework.a in Frameworks */, DCD22D541D8CC0FC001C9B81 /* libutilities.a in Frameworks */, - DCD22D531D8CC0EF001C9B81 /* libASN1_not_installed.a in Frameworks */, + DCD22D531D8CC0EF001C9B81 /* libASN1.a in Frameworks */, E7F482A11C7543E500390FDB /* libsqlite3.dylib in Frameworks */, E7F482A31C7544E600390FDB /* libctkclient_test.a in Frameworks */, E7F482A61C75453900390FDB /* libcoreauthd_test_client.a in Frameworks */, ); 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_sep.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; @@ -15166,9 +17988,8 @@ EBA689031E74732700FF90A7 /* Foundation.framework in Frameworks */, EB75B4881E75401700E469CC /* ApplePushService.framework in Frameworks */, EB75B4891E75402400E469CC /* IOKit.framework in Frameworks */, - EB75B48A1E75405100E469CC /* libsecurity.a in Frameworks */, EB75B48C1E75407C00E469CC /* libutilities.a in Frameworks */, - EB75B48D1E75408900E469CC /* libASN1_not_installed.a in Frameworks */, + EB75B48D1E75408900E469CC /* libASN1.a in Frameworks */, EB75B48F1E75409A00E469CC /* libsqlite3.dylib in Frameworks */, EB75B4901E7540AA00E469CC /* libctkclient_test.a in Frameworks */, EB75B4911E7540BF00E469CC /* libcoreauthd_test_client.a in Frameworks */, @@ -15216,12 +18037,17 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DC4A76AC221269E4006F2D8F /* CloudServices.framework in Frameworks */, + 0C6C0FD321F1494C00CD5B9E /* CoreCDP.framework in Frameworks */, + EB80DE59219600DF005B10FA /* libz.tbd in Frameworks */, + DC3E18EB2125FB8700073D80 /* libaks_mock.a in Frameworks */, + 482FE5692177C7670031C11E /* AuthKit.framework in Frameworks */, EB49B2C2202DF002003F34A0 /* libDER.a in Frameworks */, EB49B2BD202DEF29003F34A0 /* libSecureObjectSyncFramework.a in Frameworks */, EB49B2BE202DEF29003F34A0 /* libSecureObjectSyncServer.a in Frameworks */, EB49B2BB202D8894003F34A0 /* libsecurityd_ios.a in Frameworks */, EB49B2BF202DEF67003F34A0 /* libsecurity.a in Frameworks */, - EB49B2C1202DEF8D003F34A0 /* libASN1_not_installed.a in Frameworks */, + EB49B2C1202DEF8D003F34A0 /* libASN1.a in Frameworks */, EB49B2C0202DEF7D003F34A0 /* libutilities.a in Frameworks */, EB49B308202FF421003F34A0 /* OCMock.framework in Frameworks */, EB49B2D2202DF17D003F34A0 /* SecurityFoundation.framework in Frameworks */, @@ -15232,6 +18058,48 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EB6952AA223B75C300F02C1C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EB6952BE223B793100F02C1C /* IOKit.framework in Frameworks */, + EB6952AB223B75C300F02C1C /* libz.tbd in Frameworks */, + EB6952AC223B75C300F02C1C /* libMobileGestalt.dylib in Frameworks */, + EB6952AD223B75C300F02C1C /* Foundation.framework in Frameworks */, + EB6952AE223B75C300F02C1C /* libutilities.a in Frameworks */, + EB6952AF223B75C300F02C1C /* CoreFoundation.framework in Frameworks */, + EB6952B0223B75C300F02C1C /* Security.framework in Frameworks */, + EB6952B1223B75C300F02C1C /* CoreData.framework in Frameworks */, + EB6952B2223B75C300F02C1C /* SystemConfiguration.framework in Frameworks */, + EB6952B3223B75C300F02C1C /* libsqlite3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB74CC132207E48000F1BBAD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EB74CC272207ECE100F1BBAD /* Security.framework in Frameworks */, + EB74CC262207ECCC00F1BBAD /* Preferences.framework in Frameworks */, + EB74CC172207E48000F1BBAD /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB89086F21F17D3C00F0DDDB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EB89087021F17D3C00F0DDDB /* libz.tbd in Frameworks */, + EB89087221F17D3C00F0DDDB /* libMobileGestalt.dylib in Frameworks */, + EB89087321F17D3C00F0DDDB /* Foundation.framework in Frameworks */, + EB89087421F17D3C00F0DDDB /* libutilities.a in Frameworks */, + EB89087521F17D3C00F0DDDB /* CoreFoundation.framework in Frameworks */, + EB89087921F17D3C00F0DDDB /* Security.framework in Frameworks */, + EB89087B21F17D3C00F0DDDB /* SystemConfiguration.framework in Frameworks */, + EB89087E21F17D3C00F0DDDB /* libsqlite3.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EB9C1D771BDFD0E000F89272 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -15257,6 +18125,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + EBB851E922F7912400424FD0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + EBB8521D22F7948B00424FD0 /* libutilities.a in Frameworks */, + EBB8521B22F7945600424FD0 /* XCTest.framework in Frameworks */, + EBB852CF22F7A05600424FD0 /* OCMock.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; EBCF73F61CE45F9C00BED7CA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -15271,7 +18149,7 @@ buildActionMask = 2147483647; files = ( DC2670F61F3E714000816EED /* libSecureObjectSyncServer.a in Frameworks */, - DCE5DC121EA80369006308A6 /* libSOSCommands.a in Frameworks */, + DC8506B62097F39100C712EC /* libSOSCommands.a in Frameworks */, EBF3747E1DC057B40065D840 /* Security.framework in Frameworks */, E76638A81DD679BC00B769D3 /* libutilities.a in Frameworks */, ); @@ -15307,6 +18185,15 @@ path = secdtests; sourceTree = ""; }; + 0C0C4F80216FB53A00C14C61 /* BottledPeer */ = { + isa = PBXGroup; + children = ( + 0C0C4F83216FB55600C14C61 /* EscrowKeys.swift */, + 0C0C4F84216FB56B00C14C61 /* BottledPeer.swift */, + ); + path = BottledPeer; + sourceTree = ""; + }; 0C2BCBA41D063F7D00ED7A2F /* dtlsEcho */ = { isa = PBXGroup; children = ( @@ -15317,6 +18204,25 @@ path = dtlsEcho; sourceTree = ""; }; + 0C3BB3312187EC4D0018FC14 /* Categories */ = { + isa = PBXGroup; + children = ( + 0C3BB3572188E18C0018FC14 /* OTAuthenticatedCiphertext+SF.h */, + 0C3BB3542188E18B0018FC14 /* OTAuthenticatedCiphertext+SF.m */, + 0C3BB3562188E18B0018FC14 /* OTPrivateKey+SF.h */, + 0C3BB3522188E18A0018FC14 /* OTPrivateKey+SF.m */, + ); + path = Categories; + sourceTree = ""; + }; + 0C4C546C20E19CF200BA61BA /* Recovered References */ = { + isa = PBXGroup; + children = ( + 0C9FB40120D8729A00864612 /* CoreCDP.framework */, + ); + name = "Recovered References"; + sourceTree = ""; + }; 0C78F1C816A5E13400654E08 /* regressions */ = { isa = PBXGroup; children = ( @@ -15339,70 +18245,64 @@ 0C8BBE831FC9DA1700580909 /* Octagon Trust */ = { isa = PBXGroup; children = ( + DCD33D7D220B9D98000A390B /* State Machine Machinery */, + DC130B7920D04CFE0065CE61 /* Categories */, + DC68527220D04C6000C61368 /* Octagon via CK API */, + DC68527120D04A5800C61368 /* Framework */, + DC68527020D04A3200C61368 /* IPC */, + DC68526A20D04A1000C61368 /* Bottled Peers */, + DCC67E2A20DDC05900A70A31 /* Operations */, 0CCCC7C720261D050024405E /* OT.h */, 0CCCC7C820261D310024405E /* OT.m */, - EB10A3E320356E2000E84270 /* OTConstants.h */, - EB10A3E420356E2000E84270 /* OTConstants.m */, - DC124DC120059B8700BE8DAC /* OctagonControlServer.h */, - DC124DC220059B8700BE8DAC /* OctagonControlServer.m */, - BEE4B1901FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h */, - BEE4B1911FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m */, - 0C8BBE951FC9DA5800580909 /* OTBottledPeer.h */, - 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */, - BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */, - BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */, - 0CE1BCCD1FCE11610017230E /* OTBottledPeerSigned.h */, - 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */, - 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */, - 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */, - 0CE407B31FD476E000F59B31 /* OTCloudStoreState.h */, - 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */, - 0C8BBE8B1FC9DA5300580909 /* OTContext.h */, - 0C8BBE981FC9DA5A00580909 /* OTContext.m */, + DC04707F218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.h */, + DC047080218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.m */, + DC5060E920E2D88300925005 /* OTCuttlefishContext.h */, + DC5060EA20E2D88300925005 /* OTCuttlefishContext.m */, + DCF94A79222D9F2400C01744 /* OctagonCKKSPeerAdapter.h */, + DCF94A7A222D9F2400C01744 /* OctagonCKKSPeerAdapter.m */, + 0C12B1F52138D32F00BE0A98 /* OTClientStateMachine.h */, + 0C12B1F02138D31600BE0A98 /* OTClientStateMachine.m */, + DCC67E0C20DD7E0A00A70A31 /* OTStates.h */, + DCC67E0D20DD7E0A00A70A31 /* OTStates.m */, 0CD9E8071FE05B8700F66C38 /* OTContextRecord.h */, 0CD9E7FF1FE05B6600F66C38 /* OTContextRecord.m */, - 0C8BBF0B1FCB452200580909 /* OTControl.h */, - 0C8BBF0E1FCB452400580909 /* OTControl.m */, - 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */, - 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */, 0C8BBE971FC9DA5A00580909 /* OTDefines.h */, - 0C8BBE921FC9DA5700580909 /* OTEscrowKeys.h */, - 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */, + EBCE06E521C6E26000FB1493 /* OTDefines.m */, + 0C6604782134C86500BFBBB8 /* OTDeviceInformation.h */, + 0C66047B2134C88C00BFBBB8 /* OTDeviceInformation.m */, + 5A04BAF622973E43001848A0 /* OTFollowup.h */, + 5A04BAF722973E43001848A0 /* OTFollowup.m */, 0C8BBE8A1FC9DA5300580909 /* OTIdentity.h */, 0C8BBE8D1FC9DA5400580909 /* OTIdentity.m */, 0C8BBE8E1FC9DA5500580909 /* OTLocalStore.h */, 0C8BBE8C1FC9DA5400580909 /* OTLocalStore.m */, 0C8BBF101FCB486B00580909 /* OTManager.h */, 0C8BBF0F1FCB481800580909 /* OTManager.m */, - 0C36B3202007EE9B0029F7A2 /* OTPreflightInfo.h */, - 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */, - BEB0B0D91FFC45C2007E6A83 /* OTPrivateKey+SF.h */, - BEB0B0DA1FFC45C2007E6A83 /* OTPrivateKey+SF.m */, - 0C5CFB3F201962FF00913B9C /* OTRamping.h */, - 0C5CFB37201960FF00913B9C /* OTRamping.m */, + 0C8FD546214AEC650098E3FB /* OTJoiningConfiguration.h */, + 0C8FD549214AECD70098E3FB /* OTJoiningConfiguration.m */, + 0C2F337020DD647C0031A92D /* OTRamping.h */, + 0C2F337120DD647D0031A92D /* OTRamping.m */, + DCB9475B2127562100ED9272 /* OTSOSAdapter.h */, + DCB9475C2127562100ED9272 /* OTSOSAdapter.m */, + DC9C06672149DFE400C6F7B8 /* OTAuthKitAdapter.h */, + DC9C06682149DFE400C6F7B8 /* OTAuthKitAdapter.m */, + DC19484A21812EC5007C2260 /* OTDeviceInformationAdapter.h */, + DC19484B21812EC5007C2260 /* OTDeviceInformationAdapter.m */, + DCC67E3120E16F3100A70A31 /* ObjCImprovements.h */, BE34059B1FD71BA700933DAC /* Protocol Buffers */, - BEE4B1971FFDAFE600777D39 /* SFECPublicKey+SPKI.m */, - BEE4B1961FFDAFE600777D39 /* SFPublicKey+SPKI.h */, 0C8BBEB11FC9DCAC00580909 /* tests */, ); name = "Octagon Trust"; + path = ot; sourceTree = ""; }; 0C8BBEB11FC9DCAC00580909 /* tests */ = { isa = PBXGroup; children = ( - 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */, - 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */, - 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */, - 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */, - 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */, - 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */, - 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */, - 0CB975502023B199008D6B48 /* OTRampingTests.m */, - 0C52C20520004248003F0733 /* OTTestsBase.h */, - 0C52C1FE20003BCA003F0733 /* OTTestsBase.m */, + DC99B89720EAD4D20065B73B /* Octagon */, + DC99B89620EAD4AB0065B73B /* CK API */, ); - name = tests; + path = tests; sourceTree = ""; }; 0C8BBEF61FCB402900580909 /* otctl */ = { @@ -15410,10 +18310,57 @@ children = ( 0C8BBEF71FCB405700580909 /* otctl.m */, 0C8BBEF81FCB407700580909 /* otctl-Entitlements.plist */, + DC26666821CAC32700F19960 /* OTControlCLI.h */, + DC26666921CAC32700F19960 /* OTControlCLI.m */, + DCF4657822011E1300BA6EEA /* EscrowRequestCLI.h */, + DCF4657922011E1300BA6EEA /* EscrowRequestCLI.m */, + EB1C319C2215EC9600A188BB /* otctl.1 */, ); path = otctl; sourceTree = ""; }; + 0CB582BA218915010040C5F2 /* proto */ = { + isa = PBXGroup; + children = ( + 0CE15E34222DF66D00B7EAA4 /* OTRecovery.proto */, + 0CB582BD218915270040C5F2 /* OTAuthenticatedCiphertext.proto */, + 0CB582BE218915270040C5F2 /* OTBottle.proto */, + 0CB582BF218915280040C5F2 /* OTBottleContents.proto */, + 0CB582BC218915270040C5F2 /* OTPrivateKey.proto */, + 0CB582BB2189150C0040C5F2 /* generated */, + ); + path = proto; + sourceTree = ""; + }; + 0CB582BB2189150C0040C5F2 /* generated */ = { + isa = PBXGroup; + children = ( + 0CE15E3D222DF6A700B7EAA4 /* OTRecovery.h */, + 0CE15E3A222DF6A600B7EAA4 /* OTRecovery.m */, + 0CE15E3B222DF6A700B7EAA4 /* Recovery.h */, + 0CE15E3C222DF6A700B7EAA4 /* Recovery.m */, + 0CB582C0218915380040C5F2 /* OTAuthenticatedCiphertext.h */, + 0CB582C5218915390040C5F2 /* OTAuthenticatedCiphertext.m */, + 0CB582C72189153A0040C5F2 /* OTBottle.h */, + 0CB582C4218915390040C5F2 /* OTBottle.m */, + 0CB582C2218915380040C5F2 /* OTBottleContents.h */, + 0CB582C62189153A0040C5F2 /* OTBottleContents.m */, + 0CB582C1218915380040C5F2 /* OTPrivateKey.h */, + 0CB582C3218915390040C5F2 /* OTPrivateKey.m */, + ); + name = generated; + path = generated_source; + sourceTree = ""; + }; + 0CE15E29222DF5FF00B7EAA4 /* RecoveryKey */ = { + isa = PBXGroup; + children = ( + 0CE15E2B222DF63600B7EAA4 /* RecoverKeySet.swift */, + 0CE15E2A222DF63500B7EAA4 /* RecoveryKey.swift */, + ); + name = RecoveryKey; + sourceTree = ""; + }; 0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */ = { isa = PBXGroup; children = ( @@ -15453,10 +18400,41 @@ path = ../../../sectask; sourceTree = ""; }; + 3D1A573E21669291009C24FD /* TLSAssets */ = { + isa = PBXGroup; + children = ( + 3D1A57412166931B009C24FD /* Info.plist */, + 3D6C25BA216C00D800AB2A71 /* TLSConfig.plist */, + 3D421458216C0A2400D62870 /* Makefile */, + ); + path = TLSAssets; + sourceTree = ""; + }; + 3D7AA28D2187ACD500F1575C /* test */ = { + isa = PBXGroup; + children = ( + 3D7AA28E2187AD0000F1575C /* SecExperimentTests.m */, + ); + path = test; + sourceTree = ""; + }; + 3DA3384121658755008C0CE1 /* SecExperiment */ = { + isa = PBXGroup; + children = ( + 3DA3384421658AA8008C0CE1 /* SecExperimentPriv.h */, + 5A2551F12229F40800512FAE /* SecExperimentInternal.h */, + 3DD852B02177FF72009E705D /* SecExperiment.m */, + 3D7AA28D2187ACD500F1575C /* test */, + 3D1A573E21669291009C24FD /* TLSAssets */, + ); + path = SecExperiment; + sourceTree = ""; + }; 3DD1FE72201AA38A0086D049 /* SecureTransportTests */ = { isa = PBXGroup; children = ( 3DD1FE7E201AA50F0086D049 /* SecureTransportTests.m */, + 3DD2589820478CCE00F5DA78 /* STLegacyTests+session.m */, 3DD1FE7A201AA50D0086D049 /* STLegacyTests-Entitlements.plist */, 3DD1FE8A201AA5140086D049 /* STLegacyTests.h */, 3DD1FE8C201AA5150086D049 /* STLegacyTests.m */, @@ -15532,6 +18510,8 @@ 6C69518E1F75A7DC00F68F91 /* SFAnalyticsSQLiteStore.h */, 6C69518D1F75A7DB00F68F91 /* SFAnalyticsSQLiteStore.m */, 0CD8D654207D6E65005CDBE8 /* SFAnalytics+Signin.h */, + 5A061190229ED60C006AF14A /* NSDate+SFAnalytics.h */, + 5A06118D229ED5EB006AF14A /* NSDate+SFAnalytics.m */, ); path = Analytics; sourceTree = ""; @@ -15592,6 +18572,17 @@ path = KeychainDataclassOwner; sourceTree = ""; }; + 47B3A90B21027D71001F4281 /* Trieste */ = { + isa = PBXGroup; + children = ( + E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */, + E060D19D2124780F0025B833 /* OctagonTestHarness */, + E060D1BD212478120025B833 /* OctagonTestHarnessXPCService */, + E060D23E21247C680025B833 /* OctagonTestHarnessXPCServiceProtocol */, + ); + path = Trieste; + sourceTree = ""; + }; 47C2F1852059CB680062DE30 /* KeychainResources */ = { isa = PBXGroup; children = ( @@ -15603,8 +18594,10 @@ 47C51B851EEA657D0032D9E5 /* SecurityUnitTests */ = { isa = PBXGroup; children = ( - 47C51B861EEA657D0032D9E5 /* SecurityUnitTests.m */, + 47C51B861EEA657D0032D9E5 /* SecKeyTests.m */, + EB6D1D5322FE8D3000205E83 /* SecItemTests.m */, 47C51B881EEA657D0032D9E5 /* Info.plist */, + EB9795B422FE90E6002BDBFB /* SecurityUnitTests.entitlements */, ); path = SecurityUnitTests; sourceTree = ""; @@ -15612,18 +18605,11 @@ 47D1837D1FB1183D00CFCD89 /* SecDbKeychainV7-protobufs */ = { isa = PBXGroup; children = ( + DCE0777C21ADE96C002662FD /* generated */, 47922D4E1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto */, - 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */, - 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */, - 47922D171FAA65120008F7E0 /* SecDbKeychainAKSSerializedWrappedKey.proto */, - 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */, - 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */, + 47922D171FAA65120008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.proto */, 47922D201FAA75FF0008F7E0 /* SecDbKeychainSerializedMetadata.proto */, - 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */, - 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */, 47922D2C1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto */, - 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */, - 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */, ); path = "SecDbKeychainV7-protobufs"; sourceTree = ""; @@ -15664,17 +18650,19 @@ DC5AC1FF1D83650C00CF422C /* securityd */, 6C69517B1F758E1000F68F91 /* supd */, DC0BC4E51D8B6AA600070CB0 /* applications */, - EB81D0CB1FE5838B00FD7F16 /* MultiDeviceSimulator */, DC5AC2011D83663C00CF422C /* tests */, EB2CA5311D2C30CD00AB770F /* xcconfig */, EBC73F44209A0BB200AE3350 /* xcscripts */, EBF374731DC055590065D840 /* security-sysdiagnose */, + DC7FC44121EE6F4E003C39B8 /* featureflags */, E7FCBE401314471B000DE34E /* Frameworks */, 4C8BC620097DBC1B00C781D5 /* Libraries */, 4C35DC36094F9120002917C4 /* Products */, 4C4CE9120AF81F0E0056B01D /* README */, 4CAB97FD1114CC5300EFB38D /* README.keychain */, 4C4CE9070AF81ED80056B01D /* TODO */, + EBAC4A512189743D00FBEC43 /* rio.yml */, + 0C4C546C20E19CF200BA61BA /* Recovered References */, ); sourceTree = ""; }; @@ -15726,8 +18714,6 @@ DCC78EA91D8088E200865A7C /* libsecurity.a */, DC52E7C21D80BC8000B0A59C /* libsecurityd_ios.a */, DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */, - DC52EA4C1D80CB7000B0A59C /* libSecurityTool.a */, - DC52EBD51D80CEF100B0A59C /* libSecurityCommands.a */, DC52EC341D80CFB200B0A59C /* libSOSCommands.a */, DC52EC4D1D80D00800B0A59C /* libSWCAgent.a */, DC52EC5C1D80D05200B0A59C /* liblogging.a */, @@ -15751,7 +18737,7 @@ DCF7884E1D88CA7200E694BB /* libsecurity_apple_x509_cl.a */, DCF7889D1D88CB5200E694BB /* apple_x509_cl.bundle */, DCF788D61D88CD2400E694BB /* libsecurity_apple_x509_tp.a */, - DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */, + DC8834081D8A218F00CE0ACA /* libASN1.a */, DCB3406D1D8A24DF0054D16E /* libsecurity_authorization.a */, DCB340951D8A267C0054D16E /* libsecurity_cdsa_client.a */, DCB341371D8A2A010054D16E /* libsecurity_cdsa_plugin.a */, @@ -15786,13 +18772,11 @@ DCD06A741D8CE2D5007602F1 /* gkunpack */, DCD06AB01D8E0D53007602F1 /* libsecurity_utilities.a */, DC3A4B581D91E9FB00E46D4A /* com.apple.CodeSigningHelper.xpc */, - DC71D9DF1D95BA6C0065FB93 /* libASN1.a */, EBF374721DC055580065D840 /* security-sysdiagnose */, DA30D6761DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater.bundle */, DCD8A1991E09EE0F00E4FA0A /* libSecureObjectSyncFramework.a */, EB1055751E14DF430003C309 /* libSecCertificateFuzzer.dylib */, DC3502B51E0208BE00BC0587 /* CKKSTests.xctest */, - DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */, EBB839A51E29665D00853BAC /* secfuzzer */, 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */, D4ADA3191E2B41670031CEA3 /* libtrustd.a */, @@ -15821,19 +18805,45 @@ 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 */, + BEAA002B202A832500E51F45 /* TrustedPeersHelper.xpc */, + 478D429C1FD72A8100CAB645 /* secdxctests_mac.xctest */, + EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */, 47C2F1832059CB680062DE30 /* KeychainResources.bundle */, 4718AE2D205B39620068EC3F /* securityd */, 4718AEE2205B39C40068EC3F /* libsecurityd_bridge.a */, 0CF406502072E3E3003D6A7F /* SignInAnalyticsTests_ios.xctest */, 0C9AEEB720783FBB00BF6237 /* SignInAnalyticsTests_osx.xctest */, DAE40BCE20CF3E47002D5674 /* secitemcanarytest */, + DC0EF8EF208697C600AB9E95 /* tpctl */, + BED987D32099145300607A5F /* TrustedPeersHelperUnitTests.xctest */, 4771D972209A755800BA9772 /* KeychainDataclassOwner.bundle */, + DC99B89220EACA470065B73B /* OctagonTests.xctest */, + BECFA42E20F91AFE00B11002 /* tppolicy */, + D44D1F662115893000E76E1A /* libCMS.a */, + D42C839821159146008D3D83 /* libsecurity_cms.a */, + D4D1FDDC21165F8B003538E2 /* libsecurity_cms_regressions.a */, + D4707A0521136E69005BCFDA /* TrustTests.xctest */, + D453A4C02122236D00850A26 /* TrustTests.xctest */, + DC05037621409A4000A8EDB7 /* OCMockUmbrella.framework */, + E060D19C2124780E0025B833 /* OctagonTestHarness.framework */, + E060D1A72124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol.framework */, + E060D1B7212478110025B833 /* OctagonTestHarnessXPCService.xpc */, + D458C4E1214E1DE00043D982 /* TrustTestsRunner_ios.app */, + D458C506214E20530043D982 /* TrustTests */, + DC36895E21235F42003A3735 /* libaks_mock.a */, + DC311E772124B8A8002F5EAE /* libaks_real_witness.a */, + DCF216D721ADD5B10029CCC1 /* libprotobuf_source_generation.a */, + 3D58394D21890FFB000ACA44 /* SecExperimentTests.xctest */, + DC7FC44821EE914C003C39B8 /* FeatureFlagsPlist.bundle */, + EB89088621F17D3C00F0DDDB /* recovery_securityd */, + DCBF4AE021FFC82100539F0A /* SecEscrowRequestTests.xctest */, + EB74CC162207E48000F1BBAD /* KeychainSettings.bundle */, + 6C39237921F13E4D00D018AD /* SecDbBackupTests.xctest */, + EB6952B9223B75C300F02C1C /* secitemd */, + DA41FE0E2241ADC000838FB3 /* otpaird */, + EBB851EC22F7912400424FD0 /* SecurityUtilitiesTests.xctest */, ); name = Products; sourceTree = ""; @@ -15918,7 +18928,11 @@ 4C922CB2097F1984004CEEBD /* Security */ = { isa = PBXGroup; children = ( + 5F00F95A230614A200B832E0 /* SecImportExportPriv.h */, D44D08B420AB890E0023C439 /* Security.apinotes */, + D4707A1021137525005BCFDA /* CMSDecoder.h */, + D47079F9211355B3005BCFDA /* CMSEncoder.h */, + D4707A0D211373D4005BCFDA /* CMSPrivate.h */, DC1785981D778C5300B50D50 /* cssmapple.h */, 4C28BCD60986EBCB0020C665 /* certextensions.h */, 4C696B3709BFA94F000CBC75 /* SecBase.h */, @@ -15926,6 +18940,19 @@ 4C8FD03D099D5C91006867B6 /* SecCertificate.h */, 4C7608B10AC34A8100980096 /* SecCertificatePriv.h */, 791766DD0DD0162C00F3B974 /* SecCertificateRequest.h */, + D47079F221128C46005BCFDA /* SecCMS.h */, + D4707A1F2113AB65005BCFDA /* SecCmsBase.h */, + D4707A2B2114B31A005BCFDA /* SecCmsContentInfo.h */, + D4707A252113E9B6005BCFDA /* SecCmsDecoder.h */, + D4707A2E2114C30A005BCFDA /* SecCmsDigestContext.h */, + D4B3B1CB2115149C00A43409 /* SecCmsDigestedData.h */, + D4707A222113B48E005BCFDA /* SecCmsEncoder.h */, + D4B3B1CE2115167600A43409 /* SecCmsEncryptedData.h */, + D4B3B1D1211517B000A43409 /* SecCmsEnvelopedData.h */, + D4707A282113ECA0005BCFDA /* SecCmsMessage.h */, + D4B3B1D42115193600A43409 /* SecCmsRecipientInfo.h */, + D4B3B1D721151B9900A43409 /* SecCmsSignedData.h */, + D4B3B1DA2115293300A43409 /* SecCmsSignerInfo.h */, 4CAC87D60B8F82720009C9FC /* SecIdentity.h */, 4CCE0AD90D41797400DDBB21 /* SecIdentityPriv.h */, 79EF5B6C0D3D6A31009F5270 /* SecImportExport.h */, @@ -15937,13 +18964,16 @@ 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 */, + 5A6D1B8D20810EA30057CAC8 /* SecProtocolMetadata.h */, + 5AE4BEEE1FA79456001B9DA4 /* SecProtocolObject.h */, + 5A6D1B9320810EA30057CAC8 /* SecProtocolOptions.h */, + AA9FD5982152AFC00045A07A /* SecProtocolConfiguration.h */, + 5AF594011FA1051500A5C1EC /* SecProtocolPriv.h */, + AADD4A28215E82440054FC6D /* SecProtocolInternal.h */, + 5A6D1B9420810EA40057CAC8 /* SecProtocolTypes.h */, + AAE91C542162634200B6BF0B /* SecProtocolTypesPriv.h */, 4C2F81D40BF121D2003C4F77 /* SecRandom.h */, + D43718C721168D7C00EA350A /* SecSMIME.h */, 107226D10D91DB32003CF14F /* SecTask.h */, DCD068031D8CDF7E007602F1 /* SecTaskPriv.h */, 4C8FD03E099D5C91006867B6 /* SecTrust.h */, @@ -15969,21 +18999,6 @@ path = ../../../ntlm; sourceTree = ""; }; - 4CB740FA0A47580400D641BB /* Security2Tool macOS */ = { - isa = PBXGroup; - children = ( - DCE4E6A71D7A38C000AFB96E /* security2.1 */, - DC52EA901D80CC2A00B0A59C /* entitlements.plist */, - E78A9AD81D34959200006B5B /* NSFileHandle+Formatting.h */, - E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */, - E7104A0B169E171900DB0045 /* security_tool_commands.c */, - D453C47F1FFD857400DE349B /* security_tool_commands.h */, - E7FEFB80169E26E200E18152 /* sub_commands.h */, - ); - name = "Security2Tool macOS"; - path = SecurityTool; - sourceTree = ""; - }; 4CE5A55609C7970A00D27A3F /* sslViewer */ = { isa = PBXGroup; children = ( @@ -16026,6 +19041,36 @@ name = "Supporting Files"; sourceTree = ""; }; + 5A04BB1F2298728A001848A0 /* test */ = { + isa = PBXGroup; + children = ( + 5A04BB22229872CB001848A0 /* SecXPCHelperTests.m */, + EB6AC0AA22F22E80003F067B /* SecTapToRadarTests.m */, + EBB8521A22F7943700424FD0 /* Info.plist */, + ); + path = test; + sourceTree = ""; + }; + 5A47FFAF228F5DAB00F781B8 /* Protocol Buffers */ = { + isa = PBXGroup; + children = ( + 5A47FFB1228F5DF700F781B8 /* KCInitialMessageData.proto */, + ); + name = "Protocol Buffers"; + sourceTree = ""; + }; + 5AF593FD1FA0EE2C00A5C1EC /* Protocol */ = { + isa = PBXGroup; + children = ( + AA44E0AD202E3422001EA371 /* test */, + 5AF593FE1FA0EE5300A5C1EC /* SecProtocol.c */, + 5A7E037722272C2D003DB3A0 /* SecProtocolHelper.m */, + AA9FD59B2152AFD70045A07A /* SecProtocolConfiguration.m */, + 78ADC6251FA0FAC5001EB8B6 /* SecProtocolTypes.m */, + ); + name = Protocol; + sourceTree = ""; + }; 5E10992719A5E55800A60E2B /* ISACLProtectedItems */ = { isa = PBXGroup; children = ( @@ -16057,15 +19102,27 @@ path = secacltests; sourceTree = ""; }; - 6C34464D1E2534C200F9522B /* Analytics */ = { + 6C34464D1E2534C200F9522B /* analytics */ = { isa = PBXGroup; children = ( + EBB0314122223786007241CB /* Tests */, + EB7E90F62193F93B00B1FA21 /* C2Metric */, EBB407AF1EBA433A00A541A5 /* CKKSPowerCollection.h */, EBB407B01EBA433A00A541A5 /* CKKSPowerCollection.m */, - 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */, - 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */, - ); - name = Analytics; + EBB02A6C2220ED16007241CB /* CKKSLaunchSequence.h */, + EBB02A6D2220ED16007241CB /* CKKSLaunchSequence.m */, + EB7E91112194826F00B1FA21 /* SecEventMetric.h */, + EB7E91242194915600B1FA21 /* SecEventMetric_private.h */, + EB7E91122194826F00B1FA21 /* SecEventMetric.m */, + EB7E90EB2193A54100B1FA21 /* SecMetrics.h */, + EB7E90EC2193A54100B1FA21 /* SecMetrics.m */, + EB7E910F2193FB7E00B1FA21 /* SecC2DeviceInfo.h */, + EB7E91102193FB7E00B1FA21 /* SecC2DeviceInfo.m */, + EB7E90EF2193A56C00B1FA21 /* C2Metric.proto */, + EB093106213F8EC100C0A495 /* TestResourceUsage.h */, + EB093107213F8EC100C0A495 /* TestResourceUsage.m */, + ); + path = analytics; sourceTree = ""; }; 6C69517B1F758E1000F68F91 /* supd */ = { @@ -16088,6 +19145,7 @@ 6C758CAF1F8826100075BD78 /* Tests */ = { isa = PBXGroup; children = ( + 5A1A1C2122A71D2A00CB8D1D /* NSDate+SFAnalyticsTests.m */, 6C1A29FC1F882788002312D8 /* SFAnalyticsTests.m */, 6C758CB01F8826100075BD78 /* SupdTests.m */, 6C758CB21F8826100075BD78 /* Info.plist */, @@ -16106,6 +19164,35 @@ path = Clients; sourceTree = ""; }; + 6C7E8F1D21F7BD1C008A2D56 /* SecDbBackupTests */ = { + isa = PBXGroup; + children = ( + 6C2008EF220BB4B500674B3A /* Entitlements.plist */, + 6C02134F21F7ED45009D5C80 /* Info.plist */, + 6C02134D21F7ED16009D5C80 /* SecDbBackupTests.m */, + 6C02134C21F7ED16009D5C80 /* SecDbBackupTests.plist */, + ); + name = SecDbBackupTests; + path = tests/SecDbBackupTests; + sourceTree = ""; + }; + 6C880FBD21C334CE00D38D66 /* generated_source */ = { + isa = PBXGroup; + children = ( + 6C880FC421C334FD00D38D66 /* SecDbBackupBag.h */, + 6C880FC321C334FD00D38D66 /* SecDbBackupBag.m */, + 6C880FBE21C334FB00D38D66 /* SecDbBackupBagIdentity.h */, + 6C880FC621C334FE00D38D66 /* SecDbBackupBagIdentity.m */, + 6C880FBF21C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.h */, + 6C880FC221C334FC00D38D66 /* SecDbBackupKeyClassSigningKey.m */, + 6C880FC521C334FD00D38D66 /* SecDbBackupMetadataClassKey.h */, + 6C880FC121C334FC00D38D66 /* SecDbBackupMetadataClassKey.m */, + 6C880FC721C334FE00D38D66 /* SecDbBackupRecoverySet.h */, + 6C880FC021C334FC00D38D66 /* SecDbBackupRecoverySet.m */, + ); + path = generated_source; + sourceTree = ""; + }; 6C9AA79F1F7C1D9000D08296 /* supdctl */ = { isa = PBXGroup; children = ( @@ -16124,6 +19211,15 @@ path = testrunner; sourceTree = ""; }; + 6CB6CBFE2198D40B0080AD6F /* SecDbBackupManager-protobufs */ = { + isa = PBXGroup; + children = ( + 6C880FBD21C334CE00D38D66 /* generated_source */, + 6CB6CC022198D4BC0080AD6F /* SecDbBackupRecoverySet.proto */, + ); + path = "SecDbBackupManager-protobufs"; + sourceTree = ""; + }; 6CF4A0B51E45488B00ECD7B5 /* KeychainEntitledTestApp_mac */ = { isa = PBXGroup; children = ( @@ -16132,7 +19228,6 @@ 6CF4A0BC1E45488B00ECD7B5 /* ViewController.h */, 6CF4A0BD1E45488B00ECD7B5 /* ViewController.m */, 6CF4A0BF1E45488B00ECD7B5 /* Assets.xcassets */, - 6CF4A0C11E45488B00ECD7B5 /* Main.storyboard */, 6CF4A0C41E45488B00ECD7B5 /* Info.plist */, 6CF4A0B91E45488B00ECD7B5 /* Supporting Files */, ); @@ -16155,9 +19250,7 @@ 6CF4A0E61E4549F300ECD7B5 /* AppDelegate.m */, 6CF4A0E81E4549F300ECD7B5 /* ViewController.h */, 6CF4A0E91E4549F300ECD7B5 /* ViewController.m */, - 6CF4A0EB1E4549F300ECD7B5 /* Main.storyboard */, 6CF4A0EE1E4549F300ECD7B5 /* Assets.xcassets */, - 6CF4A0F01E4549F300ECD7B5 /* LaunchScreen.storyboard */, 6CF4A0F31E4549F300ECD7B5 /* Info.plist */, 6CF4A0E21E4549F200ECD7B5 /* Supporting Files */, ); @@ -16184,7 +19277,7 @@ DC6ACC401E81DF9400125DC5 /* server_endpoint.m */, DCB2214A1E8B0861001598BC /* server_xpc.m */, 6C1520CD1DCCF57A00C85C6D /* secd.8 */, - DC4269061E82FBDF002B7110 /* server_security_helpers.c */, + DC4269061E82FBDF002B7110 /* server_security_helpers.m */, DC4269071E82FBDF002B7110 /* server_security_helpers.h */, DC5F35A41EE0F1A900900966 /* server_entitlement_helpers.c */, DC5F35A51EE0F1A900900966 /* server_entitlement_helpers.h */, @@ -16206,13 +19299,24 @@ path = DigicertMalaysia; sourceTree = ""; }; - AA44E0CF2032511C001EA371 /* Protocol */ = { + AA0DA47721E81885009F1C74 /* test_data */ = { isa = PBXGroup; children = ( - AA44E0D02032513F001EA371 /* SecProtocol.c */, - AA44E0D120325140001EA371 /* SecProtocolTypes.m */, + AA0DA47921E8189E009F1C74 /* builtins.json */, + AA0DA47821E8189D009F1C74 /* example1.json */, ); - path = Protocol; + name = test_data; + sourceTree = ""; + }; + AA44E0AD202E3422001EA371 /* test */ = { + isa = PBXGroup; + children = ( + AA0DA47721E81885009F1C74 /* test_data */, + AA44E0B3202E3451001EA371 /* SecProtocolTest.m */, + 5A43A07F225FA38D005450E4 /* SecProtocolHelperTest.m */, + AADD4A2B215E83140054FC6D /* SecProtocolConfigurationTest.m */, + ); + name = test; sourceTree = ""; }; ACBAF6DF1E941A800007BA2F /* regressions */ = { @@ -16251,30 +19355,133 @@ BE34059B1FD71BA700933DAC /* Protocol Buffers */ = { isa = PBXGroup; children = ( - BE3405A11FD71CC800933DAC /* OTBottle.proto */, - BE3405A51FD720C900933DAC /* OTBottleContents.proto */, - BEB0B0CE1FFC37E3007E6A83 /* OTPrivateKey.proto */, - BEE4B1861FFD57D800777D39 /* OTAuthenticatedCiphertext.proto */, - BE3405A21FD71CDE00933DAC /* derived source */, + 0C0F76DD21399AF40074EDDF /* OTPairingMessage.proto */, + DC751A0C211E02B100C18042 /* OTAccountMetadataClassC.proto */, + BE3405A21FD71CDE00933DAC /* generated */, ); name = "Protocol Buffers"; - path = ot/proto; + path = proto; sourceTree = ""; }; - BE3405A21FD71CDE00933DAC /* derived source */ = { - isa = PBXGroup; - children = ( - BE3405A41FD71DA600933DAC /* OTBottle.h */, - BE3405A31FD71DA400933DAC /* OTBottle.m */, - BE3405A61FD7210200933DAC /* OTBottleContents.h */, - BE3405A71FD7210300933DAC /* OTBottleContents.m */, - BEB0B0D51FFC3D33007E6A83 /* OTPrivateKey.h */, - BEB0B0D41FFC3D32007E6A83 /* OTPrivateKey.m */, - BEE4B18E1FFD5F9000777D39 /* OTAuthenticatedCiphertext.h */, - BEE4B18F1FFD5F9100777D39 /* OTAuthenticatedCiphertext.m */, - ); - name = "derived source"; - path = source; + BE3405A21FD71CDE00933DAC /* generated */ = { + isa = PBXGroup; + children = ( + 0C89BDA121554DD3003F3CC0 /* OTAccountMetadataClassC.h */, + 0C89BDA021554DD2003F3CC0 /* OTAccountMetadataClassC.m */, + 0C9AE28B214054F5003BFDB5 /* OTApplicantToSponsorRound2M1.h */, + 0C9AE28E214054F6003BFDB5 /* OTApplicantToSponsorRound2M1.m */, + 0C9AE2A1214055CE003BFDB5 /* OTPairingMessage.h */, + 0C9AE2A2214055CF003BFDB5 /* OTPairingMessage.m */, + 0CE9C98921B88919006BDD80 /* OTSOSMessage.h */, + 0CE9C98A21B8891A006BDD80 /* OTSOSMessage.m */, + 0C9AE289214054F4003BFDB5 /* OTSponsorToApplicantRound1M2.h */, + 0C9AE28D214054F6003BFDB5 /* OTSponsorToApplicantRound1M2.m */, + 0C9AE28A214054F5003BFDB5 /* OTSponsorToApplicantRound2M2.h */, + 0C9AE290214054F7003BFDB5 /* OTSponsorToApplicantRound2M2.m */, + ); + name = generated; + path = generated_source; + sourceTree = ""; + }; + BE7089991F9AAF57001ACC20 /* generated */ = { + isa = PBXGroup; + children = ( + DCD7DD9D22B868C200161396 /* TPPBDispositionDuplicateMachineID.h */, + DCD7DD9B22B868C100161396 /* TPPBDispositionDuplicateMachineID.m */, + DC730E16224011D70051DD48 /* TPPBDictionaryMatchingRule.h */, + DC730E15224011D60051DD48 /* TPPBDictionaryMatchingRule.m */, + DC730E1A224011DD0051DD48 /* TPPBDictionaryMatchingRuleFieldExists.h */, + DC730E17224011D80051DD48 /* TPPBDictionaryMatchingRuleFieldExists.m */, + DC730E18224011D90051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.h */, + DC730E19224011DB0051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.m */, + BEC373CA20D822CE00DBDF5B /* TPPBDispositionEntry.h */, + BEC373C920D822CD00DBDF5B /* TPPBDispositionEntry.m */, + BEC373AF20D815E200DBDF5B /* TPPBAncientEpoch.h */, + BEC373AD20D815E100DBDF5B /* TPPBAncientEpoch.m */, + BEC373B020D815E300DBDF5B /* TPPBPolicyProhibits.h */, + BEC373AE20D815E200DBDF5B /* TPPBPolicyProhibits.m */, + BEC373B120D815E400DBDF5B /* TPPBUnknownMachineID.h */, + BEC373AC20D815E000DBDF5B /* TPPBUnknownMachineID.m */, + BEC373A220CF3B5C00DBDF5B /* TPPBDisposition.h */, + BEC373A320CF3B5C00DBDF5B /* TPPBDisposition.m */, + DCAD8F8A22C55D73007C3872 /* TPPBDispositionDisallowedMachineID.h */, + DCAD8F8B22C55D75007C3872 /* TPPBDispositionDisallowedMachineID.m */, + BE7089DD1FA40B93001ACC20 /* TPPBPeerPermanentInfo.h */, + BE7089DE1FA40B95001ACC20 /* TPPBPeerPermanentInfo.m */, + BE7089CF1FA3BA01001ACC20 /* TPPBPeerDynamicInfo.h */, + BE7089D21FA3BA03001ACC20 /* TPPBPeerDynamicInfo.m */, + BE7089D31FA3BA03001ACC20 /* TPPBPolicySecret.h */, + BE7089D01FA3BA01001ACC20 /* TPPBPolicySecret.m */, + BE7089D41FA3BA04001ACC20 /* TPPBPeerStableInfo.h */, + BE7089D11FA3BA02001ACC20 /* TPPBPeerStableInfo.m */, + BE70899A1F9AAFF7001ACC20 /* TPPBVoucher.h */, + BE70899B1F9AAFF7001ACC20 /* TPPBVoucher.m */, + 6C0C807420EAF81900334E33 /* TPPBPolicyDocument.h */, + 6C0C807520EAF81900334E33 /* TPPBPolicyDocument.m */, + 6C0C809620EB024800334E33 /* TPPBPolicyCategoriesByView.h */, + 6C70D8D420EB02B700AB6FAF /* TPPBPolicyCategoriesByView.m */, + 6C0C809720EB024900334E33 /* TPPBPolicyIntroducersByCategory.h */, + 6C0C809520EB024800334E33 /* TPPBPolicyIntroducersByCategory.m */, + 6C0C809820EB024900334E33 /* TPPBPolicyModelToCategory.h */, + 6C0C809920EB024900334E33 /* TPPBPolicyModelToCategory.m */, + 6C70D8DE20EBDFD700AB6FAF /* TPPBPolicyRedaction.h */, + 6C70D8DD20EBDFD600AB6FAF /* TPPBPolicyRedaction.m */, + 1B4C4448223AE65400C6F97F /* TPPBPolicyKeyViewMapping.h */, + 1B4C444A223AE65400C6F97F /* TPPBPolicyKeyViewMapping.m */, + ); + name = generated; + path = generated_source; + sourceTree = ""; + }; + BE9F4F852072D834004A52C2 /* Cuttlefish Client */ = { + isa = PBXGroup; + children = ( + BE9F4F8B2072D881004A52C2 /* Cuttlefish.pb.swift */, + BEC0A94920AB618700DBD772 /* Cuttlefish.proto */, + 0CF70BD6218BECF500EC3515 /* CuttlefishExtensionWorkaround.swift */, + ); + name = "Cuttlefish Client"; + path = ../trust/cuttlefish/CuttlefishClient/Sources/CuttlefishAPI; + sourceTree = ""; + }; + BEAA002C202A832500E51F45 /* TrustedPeersHelper */ = { + isa = PBXGroup; + children = ( + 0CE15E29222DF5FF00B7EAA4 /* RecoveryKey */, + DCB0C28F222F5DF80083AECB /* CuttlefishErrors.swift */, + 0C3BB3312187EC4D0018FC14 /* Categories */, + 0C0C4F80216FB53A00C14C61 /* BottledPeer */, + BE9F4F852072D834004A52C2 /* Cuttlefish Client */, + BE92249C204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld */, + BEAA002D202A832500E51F45 /* TrustedPeersHelperProtocol.h */, + DC754C712228B57B00A39C8E /* TrustedPeersHelperProtocol.m */, + BE55C77B2044D0C90045863D /* Client.swift */, + BE9F8D0F206C099800B53D16 /* Container.swift */, + DCAD8F8422C43EAD007C3872 /* Container_MachineIDs.swift */, + BE9F8D18206C4AD300B53D16 /* ContainerMap.swift */, + BE9F8D11206C121400B53D16 /* Decrypter.swift */, + BECFA43C20F9493000B11002 /* Policy.swift */, + BEC0A96320B362EC00DBD772 /* Utils.swift */, + 0CE15E2A222DF63500B7EAA5 /* SetValueTransformer.swift */, + BE55C77D2044D7E60045863D /* main.swift */, + BEAA0033202A832500E51F45 /* Info.plist */, + BE55C77A2044D0C80045863D /* TrustedPeersHelper-Bridging-Header.h */, + DC7181062089172F00B2CB13 /* TrustedPeersHelper-entitlements.plist */, + DCB9475421274A1900ED9272 /* TPHObjcTranslation.m */, + DCB9475721274A4D00ED9272 /* TPHObjcTranslation.h */, + 0CB582BA218915010040C5F2 /* proto */, + DC391FA521C04D1500772585 /* OctagonPeerKeys.swift */, + DCF6320421C074F30030CCC0 /* CuttlefishAPIHelpers.swift */, + ); + path = TrustedPeersHelper; + sourceTree = ""; + }; + BECFA42F20F91AFE00B11002 /* tppolicy */ = { + isa = PBXGroup; + children = ( + BECFA43020F91AFE00B11002 /* main.m */, + ); + path = tppolicy; sourceTree = ""; }; BED208E31EDF95BB00753952 /* manifeststresstest */ = { @@ -16294,18 +19501,34 @@ name = manifeststresstest; sourceTree = ""; }; + BED987D42099145300607A5F /* TrustedPeersHelperUnitTests */ = { + isa = PBXGroup; + children = ( + BED987E220991C4D00607A5F /* MockCuttlefish.swift */, + BEA8557F20B5DC7D00D5AD11 /* FakeCuttlefish.swift */, + BE4C6AB120CAF4E500EAD6BE /* ContainerSync.swift */, + BED987D52099145300607A5F /* TrustedPeersHelperUnitTests.swift */, + BED987D72099145300607A5F /* Info.plist */, + BECEC0FD20A3B94C00E97255 /* TrustedPeersHelperUnitTests-BridgingHeader.h */, + ); + path = TrustedPeersHelperUnitTests; + sourceTree = ""; + }; BEF88C451EAFFFED00357577 /* TrustedPeers */ = { isa = PBXGroup; children = ( + DCE0777B21ADD92B002662FD /* proto */, BEF88C641EB0005F00357577 /* TrustedPeers.h */, + DCF458AD221F6890007F5507 /* TPLog.h */, + DCF458AE221F6890007F5507 /* TPLog.m */, BEF88C481EB0005E00357577 /* TPCategoryRule.h */, BEF88C491EB0005E00357577 /* TPCategoryRule.m */, - BEF88C4A1EB0005E00357577 /* TPCircle.h */, - BEF88C4B1EB0005E00357577 /* TPCircle.m */, BEF88C4C1EB0005E00357577 /* TPDecrypter.h */, BEF88C4D1EB0005E00357577 /* TPEncrypter.h */, BEF88C4E1EB0005E00357577 /* TPHash.h */, BEF88C4F1EB0005E00357577 /* TPHash.m */, + DC2B9A5023147A3800D4C79D /* TPMachineID.h */, + DC2B9A5123147A3800D4C79D /* TPMachineID.m */, BEF88C501EB0005E00357577 /* TPModel.h */, BEF88C511EB0005E00357577 /* TPModel.m */, BEF88C521EB0005E00357577 /* TPPeer.h */, @@ -16320,12 +19543,18 @@ BEF88C5B1EB0005E00357577 /* TPPolicy.m */, BEF88C5C1EB0005E00357577 /* TPPolicyDocument.h */, BEF88C5D1EB0005E00357577 /* TPPolicyDocument.m */, - BEF88C5E1EB0005E00357577 /* TPSigningKey.h */, + BEF88C5E1EB0005E00357577 /* TPKey.h */, + BECFA46320FFB87400B11002 /* TPKey.m */, BEF88C5F1EB0005E00357577 /* TPTypes.h */, - BEF88C601EB0005E00357577 /* TPUtils.h */, - BEF88C611EB0005E00357577 /* TPUtils.m */, - BEF88C621EB0005E00357577 /* TPVoucher.h */, - BEF88C631EB0005F00357577 /* TPVoucher.m */, + DC9061B822B02BA30071474D /* TPTypes.m */, + BECEC11020A508F600E97255 /* TPVoucher.h */, + BECEC11120A508F600E97255 /* TPVoucher.m */, + DC88467F2237431400738068 /* TPDictionaryMatchingRules.h */, + DC8846802237431400738068 /* TPDictionaryMatchingRules.m */, + BEB49F29206E98CD008DA7F4 /* TPECPublicKeyFactory.h */, + BEB49F2F206E98CE008DA7F4 /* TPECPublicKeyFactory.m */, + BEB49F32206E9A18008DA7F4 /* SFKey+TPKey.h */, + BEB49F33206E9A19008DA7F4 /* SFKey+TPKey.m */, BEF88C471EB0005E00357577 /* Info.plist */, BEF88C651EB0006C00357577 /* Tests */, ); @@ -16336,7 +19565,8 @@ BEF88C651EB0006C00357577 /* Tests */ = { isa = PBXGroup; children = ( - BEF88C671EB0008E00357577 /* TPCircleTests.m */, + DC88466C2237407500738068 /* TPDictionaryMatchingRuleTests.m */, + 1BF640EE222EEB6C002D0FCB /* TPPolicyTests.m */, BEF88C681EB0008E00357577 /* TPDummyDecrypter.h */, BEF88C691EB0008E00357577 /* TPDummyDecrypter.m */, BEF88C6A1EB0008E00357577 /* TPDummyEncrypter.h */, @@ -16350,8 +19580,9 @@ BEF88C721EB0008E00357577 /* TPPeerStableInfoTests.m */, BEF88C731EB0008E00357577 /* TPPeerTests.m */, BEF88C741EB0008E00357577 /* TPPolicyDocumentTests.m */, - BEF88C751EB0008E00357577 /* TPUtilsTests.m */, - BEF88C761EB0008E00357577 /* TPVoucherTests.m */, + BE72782A209D27C800F0DA77 /* TPKeyTests.m */, + BEB49F36206E9B89008DA7F4 /* TPECPublicKeyFactoryTests.m */, + E291657E2048BCCB0046512B /* TPPBPeerStableInfoTests.m */, BEF88C661EB0008E00357577 /* Info.plist */, ); name = Tests; @@ -16378,6 +19609,235 @@ path = ..; sourceTree = ""; }; + D42C838C2115904E008D3D83 /* cms */ = { + isa = PBXGroup; + children = ( + D42C8390211590BC008D3D83 /* CMSDecoder.cpp */, + D42C8393211590D7008D3D83 /* CMSEncoder.cpp */, + D42C8392211590D7008D3D83 /* CMSUtils.cpp */, + D42C8391211590D6008D3D83 /* CMSUtils.h */, + D4371867211682D700EA350A /* cert.c */, + D4371868211682D700EA350A /* cert.h */, + D4371863211682D500EA350A /* cmsarray.c */, + D4371865211682D600EA350A /* cmsasn1.c */, + D4371864211682D600EA350A /* cmsattr.c */, + D4371866211682D600EA350A /* cmscinfo.c */, + D4371862211682D500EA350A /* cmscipher.c */, + D43718722116831700EA350A /* cmsdecode.c */, + D43718772116831A00EA350A /* cmsdigdata.c */, + D43718702116831600EA350A /* cmsdigest.c */, + D43718752116831900EA350A /* cmsencdata.c */, + D43718742116831800EA350A /* cmsencode.c */, + D43718712116831600EA350A /* cmsenvdata.c */, + D43718762116831900EA350A /* cmslocal.h */, + D43718732116831700EA350A /* cmsmessage.c */, + D43718822116834100EA350A /* cmspriv.h */, + D43718872116834400EA350A /* cmspubkey.c */, + D43718862116834300EA350A /* cmsrecinfo.c */, + D43718802116834000EA350A /* cmsreclist.c */, + D43718812116834000EA350A /* cmsreclist.h */, + D43718842116834200EA350A /* cmssigdata.c */, + D43718832116834100EA350A /* cmssiginfo.c */, + D43718852116834300EA350A /* cmstpriv.h */, + D43718982116836300EA350A /* cmsutil.c */, + D43718932116836000EA350A /* cryptohi.c */, + D43718912116835E00EA350A /* cryptohi.h */, + D43718952116836100EA350A /* plhash.c */, + D43718942116836000EA350A /* plhash.h */, + D43718902116835E00EA350A /* secalgid.c */, + D43718962116836200EA350A /* SecCMS.c */, + D43718922116835F00EA350A /* secitem.c */, + D43718972116836200EA350A /* secitem.h */, + D43718A42116839000EA350A /* secoid.c */, + D43718A52116839100EA350A /* secoid.h */, + D43718A32116839000EA350A /* secoidt.h */, + D43718A62116839200EA350A /* SecSMIMEPriv.h */, + D43718A22116838F00EA350A /* siginfoUtils.cpp */, + D43718A72116839200EA350A /* smimeutil.c */, + D43718AE211683A900EA350A /* tsaSupport.c */, + D43718B3211683D200EA350A /* tsaSupport.h */, + D43718B2211683D100EA350A /* tsaSupportPriv.h */, + D43718AF211683AA00EA350A /* tsaTemplates.c */, + D43718B5211683D300EA350A /* tsaTemplates.h */, + D43718BD21168BA100EA350A /* docs */, + D42C83A02115953E008D3D83 /* regressions */, + ); + name = cms; + sourceTree = ""; + }; + D42C83A02115953E008D3D83 /* regressions */ = { + isa = PBXGroup; + children = ( + D437185C211671A300EA350A /* cms-01-basic.c */, + D437185E211671A400EA350A /* cms-01-basic.h */, + D437185D211671A400EA350A /* smime-cms-test.c */, + D42C83A121159568008D3D83 /* cms_regressions.h */, + D42C83A221159569008D3D83 /* cms-trust-settings-test.c */, + D42C83A321159569008D3D83 /* cms-trust-settings-test.h */, + ); + name = regressions; + sourceTree = ""; + }; + D43718BD21168BA100EA350A /* docs */ = { + isa = PBXGroup; + children = ( + D43718BF21168BCD00EA350A /* libsecurity_cms.plist */, + D43718BE21168BCC00EA350A /* libsecurity_cms.txt */, + ); + name = docs; + sourceTree = ""; + }; + D458C4DC214E1A4B0043D982 /* TestRunners */ = { + isa = PBXGroup; + children = ( + D458C4FC214E1E6C0043D982 /* appmain.m */, + D458C4CA214E1A420043D982 /* AppDelegate.m */, + D458C4C8214E1A410043D982 /* AppDelegate.h */, + D458C4C5214E1A400043D982 /* Assets.xcassets */, + D458C4C7214E1A400043D982 /* Base.lproj */, + D458C4CC214E1A420043D982 /* Info.plist */, + D458C4C6214E1A400043D982 /* main.m */, + D458C4CB214E1A420043D982 /* trusttests_entitlements.plist */, + D458C4C9214E1A410043D982 /* ViewController.h */, + D458C4CD214E1A430043D982 /* ViewController.m */, + D458C51E214E2E0C0043D982 /* Main.storyboard */, + ); + name = TestRunners; + sourceTree = ""; + }; + D4A0F8B9211E69A800443CA1 /* TrustTests */ = { + isa = PBXGroup; + children = ( + D458C4DC214E1A4B0043D982 /* TestRunners */, + D4A0F8BD211E69D500443CA1 /* DaemonTests */, + D4A0F8BE211E69DF00443CA1 /* EvaluationTests */, + D4A0F8BF211E69EB00443CA1 /* FrameworkTests */, + D4A0F8C0211E69F500443CA1 /* TestData */, + D4A0F8BA211E69CB00443CA1 /* Info.plist */, + D4A0F8BB211E69CB00443CA1 /* TestMacroConversions.h */, + D44282FE22D68556001746B3 /* TrustEvaluationTestHelpers.m */, + D4A7946D22D7DD6E00D1B2B7 /* TrustEvaluationTestHelpers.h */, + ); + name = TrustTests; + sourceTree = ""; + }; + D4A0F8BD211E69D500443CA1 /* DaemonTests */ = { + isa = PBXGroup; + children = ( + D4EA5CF622B225C000883439 /* LoggingServerTests.m */, + ); + name = DaemonTests; + sourceTree = ""; + }; + D4A0F8BE211E69DF00443CA1 /* EvaluationTests */ = { + isa = PBXGroup; + children = ( + D458C4AA214E198D0043D982 /* CTTests.m */, + D4EF3222215F102F000A31A5 /* CTTests_data.h */, + D4AC5766214E195300A32C01 /* ECTests.m */, + D4AC5767214E195300A32C01 /* ECTests_data.h */, + D458C4AE214E198E0043D982 /* EvaluationBasicTests_data.h */, + D458C4AF214E198E0043D982 /* EvaluationBasicTests.m */, + D458C4B5214E19AE0043D982 /* iAPTests.m */, + D458C4AD214E198E0043D982 /* iAPTests_data.h */, + D4AC5768214E195400A32C01 /* KeySizeTests.m */, + D4AC5769214E195400A32C01 /* KeySizeTests_data.h */, + D4FD421B217D7891002B7EE2 /* NameConstraintsTests.m */, + D4FD421E217D78BB002B7EE2 /* NameConstraintsTests_data.h */, + D4D92DA422788FEB0009A7CF /* NISTTests.m */, + D458C4B4214E19AE0043D982 /* PathParseTests.m */, + D4D92DA32277E6D10009A7CF /* PathParseTests_data.h */, + D4FD421F217D7B27002B7EE2 /* PathScoringTests.m */, + D4FD4222217D7B48002B7EE2 /* PathScoringTests_data.h */, + D458C513214E27620043D982 /* PolicyTests.m */, + D458C4B7214E19AF0043D982 /* SignatureAlgorithmTests.m */, + D458C4B6214E19AE0043D982 /* SignatureAlgorithmTests_data.h */, + D4056A1922712A650026E24E /* SSLPolicyTests.m */, + D4056A1C22712AD80026E24E /* SSLPolicyTests_data.h */, + D4AC5764214E195200A32C01 /* VerifyDateTests.m */, + D4AC5765214E195300A32C01 /* VerifyDateTests_data.h */, + D4A0F8CB211E6A8200443CA1 /* TrustEvaluationTestCase.h */, + D4A0F8C9211E6A8200443CA1 /* TrustEvaluationTestCase.m */, + ); + name = EvaluationTests; + sourceTree = ""; + }; + D4A0F8BF211E69EB00443CA1 /* FrameworkTests */ = { + isa = PBXGroup; + children = ( + D4A0F8C6211E6A5700443CA1 /* CertificateInterfaceTests.m */, + D4A0F8C3211E6A5600443CA1 /* CertificateInterfaceTests_data.h */, + D4AC8BE721320AD0006E9871 /* CertificateParseTests.m */, + D458C4BF214E19FB0043D982 /* TrustInterfaceTests.m */, + D458C4C0214E19FB0043D982 /* TrustInterfaceTests_data.h */, + D458C4BE214E19FA0043D982 /* TrustSettingsInterfaceTests.m */, + D4A0F8C5211E6A5700443CA1 /* TrustFrameworkTestCase.h */, + D4A0F8C4211E6A5700443CA1 /* TrustFrameworkTestCase.m */, + ); + name = FrameworkTests; + sourceTree = ""; + }; + D4A0F8C0211E69F500443CA1 /* TestData */ = { + isa = PBXGroup; + children = ( + D4B2966822DBFDB100DCF250 /* TestCopyProperties_ios-data */, + D4D92DA72278904F0009A7CF /* nist-certs */, + D4AC8BED2132127A006E9871 /* si-18-certificate-parse */, + D458C51B214E2CFF0043D982 /* si-20-sectrust-policies-data */, + D4A0F8C1211E6A2F00443CA1 /* si-82-sectrust-ct-data */, + D4056A1E22712D750026E24E /* si-87-sectrust-name-constraints */, + D4056A1D22712D740026E24E /* ssl-policy-certs */, + ); + name = TestData; + sourceTree = ""; + }; + D4CF6E62211588140014647E /* cms */ = { + isa = PBXGroup; + children = ( + D42C83A621163866008D3D83 /* cert.h */, + D4CF6E6B211588690014647E /* cmsarray.c */, + D4CF6E772115886D0014647E /* cmsasn1.c */, + D4CF6E66211588670014647E /* cmsattr.c */, + D44D1F8521158AAC00E76E1A /* cmscinfo.c */, + D4CF6E6E2115886A0014647E /* cmscipher.c */, + D4CF6E732115886C0014647E /* cmsdecode.c */, + D4CF6E68211588680014647E /* CMSDecoder.c */, + D4CF6E7B2115886E0014647E /* cmsdigdata.c */, + D44D1F8821158AAE00E76E1A /* cmsdigest.c */, + D4CF6E6F2115886A0014647E /* cmsencdata.c */, + D44D1F8A21158AAF00E76E1A /* cmsencode.c */, + D4CF6E7C2115886F0014647E /* CMSEncoder.c */, + D4CF6E7D2115886F0014647E /* cmsenvdata.c */, + D4CF6E752115886C0014647E /* cmslocal.h */, + D4CF6E6C211588690014647E /* cmsmessage.c */, + D4CF6E64211588670014647E /* cmspriv.h */, + D4CF6E65211588670014647E /* cmspubkey.c */, + D4CF6E7F211588700014647E /* cmsrecinfo.c */, + D44D1F8921158AAE00E76E1A /* cmsreclist.c */, + D42C838721158B3F008D3D83 /* cmsreclist.h */, + D4CF6E6D2115886A0014647E /* cmssigdata.c */, + D44D1F8621158AAD00E76E1A /* cmssiginfo.c */, + D4CF6E67211588680014647E /* cmstpriv.h */, + D4CF6E782115886D0014647E /* cmsutil.c */, + D4CF6E762115886D0014647E /* CMSUtils.c */, + D4CF6E712115886B0014647E /* CMSUtils.h */, + D44D1F8421158AAC00E76E1A /* crypto-embedded.c */, + D44D1F8721158AAD00E76E1A /* cryptohi.h */, + D4CF6E742115886C0014647E /* plhash.c */, + D44D1F8321158AAB00E76E1A /* plhash.h */, + D4CF6E69211588680014647E /* secalgid.c */, + D42C838821158B40008D3D83 /* SecAsn1Item.c */, + D4CF6E81211588710014647E /* SecAsn1Item.h */, + D4CF6E792115886E0014647E /* secoid.c */, + D4CF6E6A211588690014647E /* secoid.h */, + D44D1F8B21158AAF00E76E1A /* secoidt.h */, + D4CF6E63211588660014647E /* SecSMIME.h */, + D4CF6E7A2115886E0014647E /* SecSMIMEPriv.h */, + D4CF6E722115886B0014647E /* smimeutil.c */, + ); + path = cms; + sourceTree = ""; + }; DA30D6771DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */ = { isa = PBXGroup; children = ( @@ -16388,6 +19848,28 @@ path = KeychainSyncAccountUpdater; sourceTree = ""; }; + DA41FDFC2241A7CD00838FB3 /* otpaird */ = { + isa = PBXGroup; + children = ( + DAEF8E55225819EE00F7DF79 /* Info.plist */, + DAEF8E58225819EF00F7DF79 /* OTPairingClient.h */, + DAEF8E57225819EF00F7DF79 /* OTPairingClient.m */, + DAEF8E59225819F000F7DF79 /* OTPairingConstants.h */, + DAC58D1C2244527E00D4CD41 /* OTPairingPacketContext.h */, + DAC58D1E2244528000D4CD41 /* OTPairingPacketContext.m */, + DA4586572245AEDA0073F993 /* OTPairingService.h */, + DA4586592245AEDA0073F993 /* OTPairingService.m */, + DACAD627229F6E690002BBC3 /* OTPairingSession.h */, + DACAD629229F6E6A0002BBC3 /* OTPairingSession.m */, + DAC58D1F2244528100D4CD41 /* com.apple.security.otpaird.iphoneos.plist */, + DAC58D1D2244527F00D4CD41 /* com.apple.security.otpaird.watchos.plist */, + DA41FE192241AF3E00838FB3 /* main.m */, + DA45865B2245AEDB0073F993 /* otpaird.iphoneos.entitlements */, + DA45865A2245AEDB0073F993 /* otpaird.watchos.entitlements */, + ); + path = otpaird; + sourceTree = ""; + }; DAE40BD620CF3F04002D5674 /* secitemcanarytest */ = { isa = PBXGroup; children = ( @@ -16397,6 +19879,15 @@ path = secitemcanarytest; sourceTree = ""; }; + DC05037721409A4100A8EDB7 /* OCMockUmbrella */ = { + isa = PBXGroup; + children = ( + DC05037821409A4100A8EDB7 /* OCMockUmbrella.h */, + DC05037921409A4100A8EDB7 /* Info.plist */, + ); + path = OCMockUmbrella; + sourceTree = ""; + }; DC0BC4E51D8B6AA600070CB0 /* applications */ = { isa = PBXGroup; children = ( @@ -16526,24 +20017,12 @@ DC0BC64E1D8B755200070CB0 /* lib */ = { isa = PBXGroup; children = ( - DC0BC6011D8B755200070CB0 /* feeCipherFile.c */, - DC0BC6021D8B755200070CB0 /* feeCipherFileAtom.c */, DC0BC6031D8B755200070CB0 /* byteRep.c */, DC0BC6041D8B755200070CB0 /* byteRep.h */, - DC0BC6051D8B755200070CB0 /* CipherFileDES.c */, - DC0BC6061D8B755200070CB0 /* CipherFileDES.h */, - DC0BC6071D8B755200070CB0 /* CipherFileFEED.c */, - DC0BC6081D8B755200070CB0 /* CipherFileFEED.h */, - DC0BC6091D8B755200070CB0 /* CipherFileTypes.h */, DC0BC60A1D8B755200070CB0 /* ckconfig.h */, - DC0BC60B1D8B755200070CB0 /* ckDES.c */, - DC0BC60C1D8B755200070CB0 /* ckDES.h */, - DC0BC60D1D8B755200070CB0 /* ckMD5.c */, DC0BC60E1D8B755200070CB0 /* ckMD5.h */, DC0BC60F1D8B755200070CB0 /* ckSHA1.c */, DC0BC6101D8B755200070CB0 /* ckSHA1.h */, - DC0BC6111D8B755200070CB0 /* ckSHA1_priv.c */, - DC0BC6121D8B755200070CB0 /* ckSHA1_priv.h */, DC0BC6131D8B755200070CB0 /* ckutilities.c */, DC0BC6141D8B755200070CB0 /* ckutilities.h */, DC0BC6151D8B755200070CB0 /* Crypt.h */, @@ -16552,11 +20031,9 @@ DC0BC61A1D8B755200070CB0 /* CryptKitDER.cpp */, DC0BC61B1D8B755200070CB0 /* CryptKitDER.h */, DC0BC61C1D8B755200070CB0 /* curveParamData.h */, - DC0BC61D1D8B755200070CB0 /* curveParamDataOld.h */, DC0BC61E1D8B755200070CB0 /* curveParams.c */, DC0BC61F1D8B755200070CB0 /* curveParams.h */, DC0BC6201D8B755200070CB0 /* ECDSA_Profile.h */, - DC0BC6211D8B755200070CB0 /* ECDSA_Verify_Prefix.h */, DC0BC6221D8B755200070CB0 /* elliptic.c */, DC0BC6231D8B755200070CB0 /* elliptic.h */, DC0BC6241D8B755200070CB0 /* ellipticMeasure.h */, @@ -16564,13 +20041,9 @@ DC0BC6261D8B755200070CB0 /* ellipticProj.h */, DC0BC6271D8B755200070CB0 /* enc64.c */, DC0BC6281D8B755200070CB0 /* enc64.h */, - DC0BC6291D8B755200070CB0 /* engineNSA127.c */, DC0BC62A1D8B755200070CB0 /* falloc.c */, DC0BC62B1D8B755200070CB0 /* falloc.h */, - DC0BC62C1D8B755200070CB0 /* feeCipherFile.h */, DC0BC62D1D8B755200070CB0 /* feeDebug.h */, - DC0BC62E1D8B755200070CB0 /* feeDES.c */, - DC0BC62F1D8B755200070CB0 /* feeDES.h */, DC0BC6301D8B755200070CB0 /* feeDigitalSignature.c */, DC0BC6311D8B755200070CB0 /* feeDigitalSignature.h */, DC0BC6321D8B755200070CB0 /* feeECDSA.c */, @@ -16591,11 +20064,6 @@ DC0BC6411D8B755200070CB0 /* giantIntegers.c */, DC0BC6421D8B755200070CB0 /* giantIntegers.h */, DC0BC6431D8B755200070CB0 /* giantPort_Generic.h */, - DC0BC6441D8B755200070CB0 /* giantPort_i486.h */, - DC0BC6451D8B755200070CB0 /* giantPort_PPC.c */, - DC0BC6461D8B755200070CB0 /* giantPort_PPC.h */, - DC0BC6471D8B755200070CB0 /* giantPort_PPC_Gnu.h */, - DC0BC6481D8B755200070CB0 /* giantPort_PPC_Gnu.s */, DC0BC6491D8B755200070CB0 /* giantPortCommon.h */, DC0BC64A1D8B755200070CB0 /* HmacSha1Legacy.c */, DC0BC64B1D8B755200070CB0 /* HmacSha1Legacy.h */, @@ -16995,7 +20463,6 @@ isa = PBXGroup; children = ( DC0BC9F21D8B827200070CB0 /* sslMemory.c */, - DC0BC9F31D8B827200070CB0 /* sslUtils.c */, ); name = Misc.; sourceTree = ""; @@ -17225,7 +20692,7 @@ DC0BCC371D8C689C00070CB0 /* utilities */ = { isa = PBXGroup; children = ( - DC0BCDB31D8C6A4A00070CB0 /* SecurityTool */, + 5A04BB1F2298728A001848A0 /* test */, DC0BCC3A1D8C68CF00070CB0 /* iCloudKeychainTrace.c */, DC0BCC3B1D8C68CF00070CB0 /* iCloudKeychainTrace.h */, EBF3749A1DC064200065D840 /* SecADWrapper.c */, @@ -17236,6 +20703,8 @@ DA5B871B2065A8430093F083 /* SecAutorelease.m */, DC0BCC3E1D8C68CF00070CB0 /* SecBuffer.c */, DC0BCC3F1D8C68CF00070CB0 /* SecBuffer.h */, + EBE8258E2193353300102304 /* SecCoreAnalytics.h */, + EBE8258F2193353300102304 /* SecCoreAnalytics.m */, DC0BCC401D8C68CF00070CB0 /* SecCoreCrypto.c */, DC0BCC411D8C68CF00070CB0 /* SecCoreCrypto.h */, DC0BCC441D8C68CF00070CB0 /* SecCFCCWrappers.c */, @@ -17247,8 +20716,12 @@ DC0BCC4A1D8C68CF00070CB0 /* SecCFError.h */, DC0BCC4B1D8C68CF00070CB0 /* SecDispatchRelease.h */, DC0BCC4C1D8C68CF00070CB0 /* SecIOFormat.h */, + EB71CF6322E8238000DA3D0E /* SecTapToRadar.h */, + EB71CF6422E8238000DA3D0E /* SecTapToRadar.m */, E78CCDC61E737F6700C1CFAA /* SecNSAdditions.m */, E78CCDCD1E737F8100C1CFAA /* SecNSAdditions.h */, + 5A04BB182298670C001848A0 /* SecXPCHelper.h */, + 5A04BB14229866F7001848A0 /* SecXPCHelper.m */, DC0BCC4D1D8C68CF00070CB0 /* SecTrace.c */, DC0BCC4E1D8C68CF00070CB0 /* SecTrace.h */, EB7AE6F61E86D55400B80B15 /* SecPLWrappers.m */, @@ -17316,7 +20789,6 @@ DCC78E401D8085FC00865A7C /* SecCFAllocator.c */, D47F514B1C3B812500A7CEFE /* SecCFAllocator.h */, DCC78E421D8085FC00865A7C /* SecCMS.c */, - 79BDD3C00D60DB84000D84D3 /* SecCMS.h */, DCC78E441D8085FC00865A7C /* SecCTKKey.m */, DCC78E451D8085FC00865A7C /* SecCTKKeyPriv.h */, DCC78E381D8085FC00865A7C /* SecCertificate.c */, @@ -17343,7 +20815,7 @@ DCC78E5C1D8085FC00865A7C /* SecItemConstants.c */, 4CEDF7370F3A6CFB0027C4FE /* SecItemInternal.h */, DCC78E5F1D8085FC00865A7C /* SecItemShim.h */, - DCC78E601D8085FC00865A7C /* SecKey.c */, + DCC78E601D8085FC00865A7C /* SecKey.m */, DCC78E621D8085FC00865A7C /* SecKeyAdaptors.m */, 4C04A90811924BBC0020550C /* SecKeyInternal.h */, 09E9991F1F7D76550018DF67 /* SecKeyProxy.m */, @@ -17399,7 +20871,6 @@ EB6928BF1D9C9C5900062A18 /* SecRecoveryKey.m */, DCC78E9A1D8085FC00865A7C /* SecuritydXPC.c */, DCC78E9B1D8085FC00865A7C /* SecuritydXPC.h */, - D462469C1F9AE45900D63882 /* oids.c */, DCC78E2A1D8085FC00865A7C /* p12import.c */, 79EF5B720D3D6AFE009F5270 /* p12import.h */, DCC78E2C1D8085FC00865A7C /* p12pbegen.c */, @@ -17409,7 +20880,6 @@ DCC78E9C1D8085FC00865A7C /* vmdh.c */, 4C7391770B01745000C4CBFA /* vmdh.h */, 47A05B101FDB5A8B00D0816E /* SFKeychainControl.h */, - DCC5860120BF8A98005C7269 /* SecBase.h */, DCC5860220BF8A98005C7269 /* SecBase.c */, ); name = src; @@ -17445,42 +20915,28 @@ path = OSX/utilities/Regressions; sourceTree = ""; }; - DC0BCDB31D8C6A4A00070CB0 /* SecurityTool */ = { - isa = PBXGroup; - children = ( - DC65E7BE1D8CBB1500152EF0 /* readline.c */, - DC65E7BF1D8CBB1500152EF0 /* readline.h */, - DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */, - ); - path = SecurityTool; - sourceTree = ""; - }; - DC1002C41D8E19D70025549C /* Products */ = { - isa = PBXGroup; - children = ( - DC1002C91D8E19D70025549C /* libsecurity_cms.a */, - DC1002CB1D8E19D70025549C /* libsecurity_cms_regressions.a */, - ); - name = Products; - sourceTree = ""; - }; - DC1002CC1D8E19F20025549C /* Products */ = { + DC0EF8F0208697C600AB9E95 /* tpctl */ = { isa = PBXGroup; children = ( - DC1002D31D8E19F20025549C /* security_smime */, - DC1002D51D8E19F20025549C /* security_smime.framework */, - DC1002D71D8E19F20025549C /* libCMS.a */, + DC0EF8F1208697C600AB9E95 /* main.swift */, + DCC5D66B2087FADE00BBC127 /* tpctl-bridging-header.h */, + EBE2026420908A8A00B48020 /* tpctl.8 */, + DCD48BFC20BF3D83009A3224 /* tpctl-objc.h */, + DCD48BFD20BF3D83009A3224 /* tpctl-objc.m */, + DCB41DF9216C3F8A00F219E0 /* tpctl-entitlements.plist */, ); - name = Products; + path = tpctl; sourceTree = ""; }; - DC1784431D77869A00B50D50 /* Products */ = { + DC130B7920D04CFE0065CE61 /* Categories */ = { isa = PBXGroup; children = ( - DC1784491D77869A00B50D50 /* libsecurity_smime.a */, - DC17844B1D77869A00B50D50 /* libsecurity_smime_regressions.a */, + DC85687F2284E79C0088D3EF /* OctagonEscrowRecoverer.h */, + DC7EB920211E17E500516452 /* OTAccountMetadataClassC+KeychainSupport.h */, + DC7EB921211E17E500516452 /* OTAccountMetadataClassC+KeychainSupport.m */, ); - name = Products; + name = Categories; + path = categories; sourceTree = ""; }; DC1785101D77892600B50D50 /* headers */ = { @@ -17504,25 +20960,6 @@ name = headers; sourceTree = ""; }; - DC17858D1D778B8E00B50D50 /* libsecurity_cms_headers */ = { - isa = PBXGroup; - children = ( - DC1787581D7790B600B50D50 /* CMSPrivate.h */, - DC17858E1D778B9D00B50D50 /* CMSDecoder.h */, - DC17858F1D778B9D00B50D50 /* CMSEncoder.h */, - ); - name = libsecurity_cms_headers; - sourceTree = ""; - }; - DC1786FF1D778F7800B50D50 /* libsecurity_smime_headers */ = { - isa = PBXGroup; - children = ( - E7C4D03512F9EB210022E067 /* iOS */, - DC3C7ABB1D838D1100F6A832 /* macOS */, - ); - name = libsecurity_smime_headers; - sourceTree = ""; - }; DC17899F1D779DD600B50D50 /* SecBreadcrumb */ = { isa = PBXGroup; children = ( @@ -17549,6 +20986,7 @@ DCB3417A1D8A2B7A0054D16E /* cdsa_utilities */, DC0BC5841D8B70D100070CB0 /* cdsa_utils */, DC0BC5B81D8B721900070CB0 /* checkpw */, + D42C838C2115904E008D3D83 /* cms */, DC0BC5EA1D8B743F00070CB0 /* comcryption */, DC0BC6001D8B754000070CB0 /* cryptkit */, DC0BC7441D8B76E500070CB0 /* cssm */, @@ -17562,10 +21000,6 @@ DC0BC9D01D8B825900070CB0 /* ssl */, DC0BCA811D8B859D00070CB0 /* transform */, DC0BCB091D8B896500070CB0 /* translocate */, - DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */, - DC1786FF1D778F7800B50D50 /* libsecurity_smime_headers */, - DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */, - DC17858D1D778B8E00B50D50 /* libsecurity_cms_headers */, DC58C4401D77BF6D003C25A4 /* config */, DC1789A81D77A06800B50D50 /* Resources */, DC1789A41D779E3B00B50D50 /* dummy.cpp */, @@ -17585,7 +21019,7 @@ DC178A351D77A1F500B50D50 /* framework.sb */, DC178A381D77A1F500B50D50 /* InfoPlist.strings */, DC178A3A1D77A1F500B50D50 /* TimeStampingPrefs.plist */, - DC178A3B1D77A1F500B50D50 /* authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings */, + DC178A3B1D77A1F500B50D50 /* authorization.dfr.prompts.strings */, DC178A3D1D77A1F500B50D50 /* authorization.buttons.strings */, DC178A3F1D77A1F500B50D50 /* authorization.prompts.strings */, DC1789A91D77A06C00B50D50 /* mds */, @@ -17617,6 +21051,16 @@ name = mds; sourceTree = ""; }; + DC2B756521F290B4003C9356 /* generated */ = { + isa = PBXGroup; + children = ( + DCAB17CF2200D26700E1DFCF /* SecEscrowPendingRecord.h */, + DCAB17D02200D26800E1DFCF /* SecEscrowPendingRecord.m */, + ); + name = generated; + path = generated_source; + sourceTree = ""; + }; DC35021A1E009E0700BC0587 /* Database Helpers */ = { isa = PBXGroup; children = ( @@ -17647,6 +21091,10 @@ DC15F79B1E68EAD5003B9A40 /* CKKSTests+API.m */, DC6593C91ED8DA9200C19462 /* CKKSTests+CurrentPointerAPI.m */, DC9A2C5E1EB3F556008FAC27 /* CKKSTests+Coalesce.m */, + DC62DC6E22A8721C000D2D5D /* CKKSTests+MultiZone.h */, + DC62DC6B22A87128000D2D5D /* CKKSTests+MultiZone.m */, + EBC1023022EBF8AC0083D356 /* CKKSTests+LockStateTracker.m */, + DC9C98C622E264F30021E29F /* CKKSFetchTests.m */, DCFABF8D20081E2F001128B5 /* CKKSDeviceStateUploadTests.m */, DCAD9B481F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m */, DCBF2F7C1F90084D00ED0CA4 /* CKKSTLKSharingTests.m */, @@ -17656,6 +21104,10 @@ DC222C891E089BAE00B09171 /* CKKSSQLTests.m */, DC4DB15E1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m */, DC7341FD1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m */, + DCA9BC05221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.h */, + DCA9BC06221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.m */, + EBDE5DF922BA3D5D00A229C8 /* CKKSMockOctagonAdapter.h */, + EBDE5DFA22BA3D5D00A229C8 /* CKKSMockOctagonAdapter.m */, 6C34462F1E24F6BE00F9522B /* CKKSRateLimiterTests.m */, DCD6C4B61EC5319600414FEE /* CKKSNearFutureSchedulerTests.m */, DCFE1C3C1F17EFB5007640C8 /* CKKSConditionTests.m */, @@ -17669,8 +21121,8 @@ DC08D1C31E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m */, 6C588D791EAA149F00D7E322 /* RateLimiterTests.m */, 4723C9D11F1531970082882F /* CKKSLoggerTests.m */, - DCF158C52064895C00B87B6D /* CKKSAPSReceiverTests.h */, - DCE7F2081F21726500DDB0F7 /* CKKSAPSReceiverTests.m */, + DCF158C52064895C00B87B6D /* OctagonAPSReceiverTests.h */, + DCE7F2081F21726500DDB0F7 /* OctagonAPSReceiverTests.m */, DC9C95951F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m */, ); name = "Tests (Local)"; @@ -17683,58 +21135,60 @@ DC3A4B5F1D91EAC500E46D4A /* CodeSigningHelper-Info.plist */, DC3A4B601D91EAC500E46D4A /* com.apple.CodeSigningHelper.sb */, DC3A4B621D91EAC500E46D4A /* main.cpp */, + 1FC7E8A02323303700AC3AD0 /* CodeSigningHelper.entitlements */, ); path = CodeSigningHelper; sourceTree = ""; }; - DC3C7ABB1D838D1100F6A832 /* macOS */ = { + DC3AA2992097E60B007CA68A /* SecurityTool (shared) */ = { isa = PBXGroup; children = ( - DC1787001D778FA900B50D50 /* SecCMS.h */, - DC1787011D778FA900B50D50 /* SecCmsBase.h */, - DC1787021D778FA900B50D50 /* SecCmsContentInfo.h */, - DC1787031D778FA900B50D50 /* SecCmsDecoder.h */, - DC1787041D778FA900B50D50 /* SecCmsDigestContext.h */, - DC1787051D778FA900B50D50 /* SecCmsDigestedData.h */, - DC1787061D778FA900B50D50 /* SecCmsEncoder.h */, - DC1787071D778FA900B50D50 /* SecCmsEncryptedData.h */, - DC1787081D778FA900B50D50 /* SecCmsEnvelopedData.h */, - DC1787091D778FA900B50D50 /* SecCmsMessage.h */, - DC17870A1D778FA900B50D50 /* SecCmsRecipientInfo.h */, - DC17870B1D778FA900B50D50 /* SecCmsSignedData.h */, - DC17870C1D778FA900B50D50 /* SecCmsSignerInfo.h */, - DC17870D1D778FA900B50D50 /* SecSMIME.h */, - DC17870E1D778FA900B50D50 /* tsaSupport.h */, - DC17870F1D778FA900B50D50 /* tsaSupportPriv.h */, - DC1787101D778FA900B50D50 /* tsaTemplates.h */, - ); - name = macOS; - path = OSX/libsecurity_smime/lib; - sourceTree = ""; - }; - DC52EA9B1D80CC2A00B0A59C /* SecurityTool iOS */ = { - isa = PBXGroup; - children = ( - 4C4CB7100DDA44900026B660 /* entitlements.plist */, - DCC78E211D8085FC00865A7C /* keychain_backup.c */, + DC8506A52097E92900C712EC /* macOS security2 Resources */, + DC8506A42097E8CF00C712EC /* iOS Resources */, + DCC78E1C1D8085FC00865A7C /* add_internet_password.c */, DC52EA8E1D80CC2A00B0A59C /* builtin_commands.h */, + DCC78E1E1D8085FC00865A7C /* codesign.c */, + D4A3A596217A85CB00F0A8DA /* ct_exceptions.m */, DC52EA8F1D80CC2A00B0A59C /* digest_calc.c */, - DC52EA911D80CC2A00B0A59C /* whoami.m */, - EB48C19E1E573EDC00EC5E57 /* sos.m */, - DC52EA921D80CC2A00B0A59C /* syncbubble.m */, + DCC78E1F1D8085FC00865A7C /* keychain_add.c */, + DCC78E211D8085FC00865A7C /* keychain_backup.c */, + DCC78E201D8085FC00865A7C /* keychain_find.m */, + DCC78E1A1D8085FC00865A7C /* keychain_util.c */, + DCC78E1B1D8085FC00865A7C /* keychain_util.h */, + 473337821FDB29A200E19F30 /* KeychainCheck.h */, + 473337831FDB29A200E19F30 /* KeychainCheck.m */, DC52EA931D80CC2A00B0A59C /* leaks.c */, DC52EA941D80CC2A00B0A59C /* leaks.h */, + DCC78E1D1D8085FC00865A7C /* log_control.c */, + DC0BCDB41D8C6A5B00070CB0 /* not_on_this_platorm.c */, + E78A9AD81D34959200006B5B /* NSFileHandle+Formatting.h */, + E78A9AD91D34959200006B5B /* NSFileHandle+Formatting.m */, + 1BDEBEFA2252E1DD009AD3D6 /* policy_dryrun.h */, + 1BDEBEF72252DEB1009AD3D6 /* policy_dryrun.m */, + DCC78E221D8085FC00865A7C /* pkcs12_util.c */, DC52EA951D80CC2A00B0A59C /* print_cert.c */, DC52EA961D80CC2A00B0A59C /* print_cert.h */, - DC52EA971D80CC2A00B0A59C /* security.1 */, + DC65E7BE1D8CBB1500152EF0 /* readline.c */, + DC65E7BF1D8CBB1500152EF0 /* readline.h */, + DCC78E231D8085FC00865A7C /* scep.c */, + DC3AA27C2097DF94007CA68A /* security_tool_commands_table.h */, + E7104A0B169E171900DB0045 /* security_tool_commands.c */, + D453C47F1FFD857400DE349B /* security_tool_commands.h */, + DCC78E241D8085FC00865A7C /* SecurityCommands.h */, DC52EA981D80CC2A00B0A59C /* SecurityTool.c */, DC52EA991D80CC2A00B0A59C /* SecurityTool.h */, + DCC78E251D8085FC00865A7C /* show_certificates.c */, + EB48C19E1E573EDC00EC5E57 /* sos.m */, + DCC78E261D8085FC00865A7C /* spc.c */, + E7FEFB80169E26E200E18152 /* sub_commands.h */, + DC52EA921D80CC2A00B0A59C /* syncbubble.m */, DC52EA9A1D80CC2A00B0A59C /* tool_errors.h */, - 473337821FDB29A200E19F30 /* KeychainCheck.h */, - 473337831FDB29A200E19F30 /* KeychainCheck.m */, + D453C38A1FEC669300DE349B /* trust_update.m */, + DCC78E191D8085FC00865A7C /* verify_cert.c */, + DC52EA911D80CC2A00B0A59C /* whoami.m */, ); - name = "SecurityTool iOS"; - path = OSX/sec/SecurityTool; + name = "SecurityTool (shared)"; + path = sharedTool; sourceTree = ""; }; DC58C4391D77BEA1003C25A4 /* csparser */ = { @@ -17760,8 +21214,9 @@ DC59E9AA1D91C9BE001BDDF5 /* Security.framework (Shared) */ = { isa = PBXGroup; children = ( + 3DA3384121658755008C0CE1 /* SecExperiment */, + 5AF593FD1FA0EE2C00A5C1EC /* Protocol */, DCC78E4F1D8085FC00865A7C /* SecFramework.c */, - AA44E0CF2032511C001EA371 /* Protocol */, 4723C9B51F152E8E0082882F /* Analytics */, DCD067621D8CDE9B007602F1 /* codesigning */, DCD06AA81D8E0D3D007602F1 /* security_utilities */, @@ -17782,13 +21237,14 @@ DC5ABDBE1D832D5800CF422C /* Source */, ); name = "SecurityTool macOS"; + path = macOS; sourceTree = ""; }; DC5ABDBE1D832D5800CF422C /* Source */ = { isa = PBXGroup; children = ( - F9C8AFC5223740C700E7D6AE /* requirement.c */, - F9C8AFCB223740C800E7D6AE /* requirement.h */, + F9F77E96223C2F7B00E5CBF6 /* requirement.c */, + F9F77E97223C2F7C00E5CBF6 /* requirement.h */, DC5ABD781D832D5800CF422C /* srCdsaUtils.cpp */, DC5ABD791D832D5800CF422C /* srCdsaUtils.h */, DC5ABD7A1D832D5800CF422C /* createFVMaster.c */, @@ -17843,6 +21299,8 @@ DC5ABDAB1D832D5800CF422C /* security_tool.h */, DC5ABDAC1D832D5800CF422C /* trusted_cert_add.c */, DC5ABDAD1D832D5800CF422C /* trusted_cert_add.h */, + BE64A7FE22AF010A001209F3 /* trusted_cert_ssl.m */, + BE64A7FD22AF0109001209F3 /* trusted_cert_ssl.h */, DC5ABDAE1D832D5800CF422C /* trusted_cert_utils.c */, DC5ABDAF1D832D5800CF422C /* trusted_cert_utils.h */, DC5ABDB01D832D5800CF422C /* trust_settings_impexp.h */, @@ -17861,7 +21319,6 @@ DC5ABDBD1D832D5800CF422C /* translocate.h */, ); name = Source; - path = SecurityTool; sourceTree = ""; }; DC5ABDC01D832D5D00CF422C /* Documentation */ = { @@ -17870,7 +21327,6 @@ DC5ABDBF1D832D5D00CF422C /* security.1 */, ); name = Documentation; - path = SecurityTool; sourceTree = ""; }; DC5ABF791D83510300CF422C /* securityd macOS */ = { @@ -18038,8 +21494,6 @@ DC5ABFC41D83511A00CF422C /* Code Signing */ = { isa = PBXGroup; children = ( - DC5ABFC21D83511A00CF422C /* csproxy.h */, - DC5ABFC31D83511A00CF422C /* csproxy.cpp */, ); name = "Code Signing"; sourceTree = ""; @@ -18048,6 +21502,8 @@ isa = PBXGroup; children = ( DC5ABFC51D83511A00CF422C /* agentclient.h */, + 1BC6F79821C9955E005ED67A /* util.h */, + 1BC6F79621C9955D005ED67A /* util.m */, DC5ABFC61D83511A00CF422C /* agentquery.h */, DC5ABFC71D83511A00CF422C /* agentquery.cpp */, DC5ABFC81D83511A00CF422C /* auditevents.h */, @@ -18117,8 +21573,10 @@ DC5ABFE31D83513C00CF422C /* resources */ = { isa = PBXGroup; children = ( + 6C23F02C227A39E9009F6756 /* com.apple.securityd.sb */, DC5ABFE21D83513C00CF422C /* securityd.order */, DC5ABFE41D83514700CF422C /* com.apple.securityd.plist */, + 09C3E08B22A83B40004ACFC4 /* securityd.entitlements */, ); name = resources; path = securityd/src; @@ -18148,8 +21606,6 @@ DC5AC1FD1D83647300CF422C /* SecureObjectSync */ = { isa = PBXGroup; children = ( - DCC78DA11D8085F200865A7C /* SOSCircle */, - F93C49391AB8FF530047E01A /* ckcdiagnose */, 4C52D0B616EFC61E0079966E /* CircleJoinRequested */, 5346480317331E1200FE9172 /* KeychainSyncAccountNotification */, DA30D6771DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */, @@ -18166,12 +21622,10 @@ isa = PBXGroup; children = ( DC5ABD281D832D4C00CF422C /* SecurityTool macOS */, - 4CB740FA0A47580400D641BB /* Security2Tool macOS */, - DC52EA9B1D80CC2A00B0A59C /* SecurityTool iOS */, - DCC78E271D8085FC00865A7C /* Security/Tool */, + DC3AA2992097E60B007CA68A /* SecurityTool (shared) */, ); - name = SecurityTool; - sourceTree = ""; + path = SecurityTool; + sourceTree = SOURCE_ROOT; }; DC5AC1FF1D83650C00CF422C /* securityd */ = { isa = PBXGroup; @@ -18186,7 +21640,9 @@ isa = PBXGroup; children = ( DCEE1E851D93424D00DC0EB7 /* com.apple.securityd.plist */, + EB8908BB21F20E0200F0DDDB /* com.apple.recovery_securityd.plist */, DCE4E8091D7A4E1C00AFB96E /* com.apple.secd.plist */, + EB6952BC223B783500F02C1C /* com.apple.secitemd.plist */, DC9EBA2F1DEE651500D0F733 /* Info-macOS.plist */, ); name = resources; @@ -18195,7 +21651,8 @@ DC5AC2011D83663C00CF422C /* tests */ = { isa = PBXGroup; children = ( - 47C51B851EEA657D0032D9E5 /* SecurityUnitTests */, + EBDAF14021C75FC800EAE89F /* SharedMocks */, + DC05037721409A4100A8EDB7 /* OCMockUmbrella */, F667EC541E96E8C800203D5C /* authdtests */, EB1055641E14DB370003C309 /* secfuzzer */, DC0BCBD81D8C646700070CB0 /* regressionBase */, @@ -18212,6 +21669,8 @@ 0C2BCBA41D063F7D00ED7A2F /* dtlsEcho */, 4727FBB81F9918590003AE36 /* secdxctests */, EB49B2AF202D8780003F34A0 /* secdmockaks */, + 6C7E8F1D21F7BD1C008A2D56 /* SecDbBackupTests */, + D4A0F8B9211E69A800443CA1 /* TrustTests */, ); name = tests; sourceTree = ""; @@ -18267,6 +21726,62 @@ name = gk_reset_check; sourceTree = ""; }; + DC68526A20D04A1000C61368 /* Bottled Peers */ = { + isa = PBXGroup; + children = ( + 0C8BBE921FC9DA5700580909 /* OTEscrowKeys.h */, + 0C8BBE961FC9DA5900580909 /* OTEscrowKeys.m */, + 0C8BBE951FC9DA5800580909 /* OTBottledPeer.h */, + 0C8BBE931FC9DA5700580909 /* OTBottledPeer.m */, + BE2AD2B11FDA07EF00739F96 /* OTBottledPeerRecord.h */, + BE2AD2B21FDA07EF00739F96 /* OTBottledPeerRecord.m */, + 0CE1BCCD1FCE11610017230E /* OTBottledPeerSigned.h */, + 0CE1BCC61FCE11480017230E /* OTBottledPeerSigned.m */, + 0C101F96205352AF00387951 /* OTBottledPeerState.h */, + 0C101F932053528700387951 /* OTBottledPeerState.m */, + 0C36B3202007EE9B0029F7A2 /* OTPreflightInfo.h */, + 0C36B3172007EE6C0029F7A2 /* OTPreflightInfo.m */, + ); + name = "Bottled Peers"; + sourceTree = ""; + }; + DC68527020D04A3200C61368 /* IPC */ = { + isa = PBXGroup; + children = ( + DC124DC120059B8700BE8DAC /* OctagonControlServer.h */, + DC124DC220059B8700BE8DAC /* OctagonControlServer.m */, + 0C8BBF0C1FCB452200580909 /* OTControlProtocol.h */, + 0C8BBF0D1FCB452300580909 /* OTControlProtocol.m */, + ); + name = IPC; + sourceTree = ""; + }; + DC68527120D04A5800C61368 /* Framework */ = { + isa = PBXGroup; + children = ( + 0CDBCD8620AD03FB007F8EA7 /* OTClique.h */, + 0C2F336A20DD643B0031A92D /* OTClique.m */, + 0C8BBF0B1FCB452200580909 /* OTControl.h */, + 0C8BBF0E1FCB452400580909 /* OTControl.m */, + EB10A3E320356E2000E84270 /* OTConstants.h */, + EB10A3E420356E2000E84270 /* OTConstants.m */, + ); + name = Framework; + sourceTree = ""; + }; + DC68527220D04C6000C61368 /* Octagon via CK API */ = { + isa = PBXGroup; + children = ( + 0C8BBE8B1FC9DA5300580909 /* OTContext.h */, + 0C8BBE981FC9DA5A00580909 /* OTContext.m */, + 0C8BBE891FC9DA5200580909 /* OTCloudStore.h */, + 0C770EC31FCF7E2000B5F0E2 /* OTCloudStore.m */, + 0CE407B31FD476E000F59B31 /* OTCloudStoreState.h */, + 0CE407AB1FD4769B00F59B31 /* OTCloudStoreState.m */, + ); + name = "Octagon via CK API"; + sourceTree = ""; + }; DC6A82061D87731C00418608 /* libsecurityd */ = { isa = PBXGroup; children = ( @@ -18354,7 +21869,6 @@ DC6A82771D87733C00418608 /* ss_types.defs */, DC6A82781D87733C00418608 /* ucsp.defs */, DC6A82791D87733C00418608 /* ucspNotify.defs */, - DC6A827A1D87733C00418608 /* cshosting.defs */, ); name = mig; path = OSX/libsecurityd/mig; @@ -18370,9 +21884,6 @@ DC6A82811D87734600418608 /* ucspServer.cpp */, DC6A82821D87734600418608 /* ucspNotifySender.cpp */, DC6A82831D87734600418608 /* ucspNotifyReceiver.cpp */, - DC6A82841D87734600418608 /* cshosting.h */, - DC6A82851D87734600418608 /* cshostingClient.cpp */, - DC6A82861D87734600418608 /* cshostingServer.cpp */, ); path = derived_src; sourceTree = BUILT_PRODUCTS_DIR; @@ -18380,22 +21891,62 @@ DC6D2C941DD3B20400BE372D /* keychain */ = { isa = PBXGroup; children = ( - DCAE1DCF2073FCA400B4F687 /* categories */, + 6C34464D1E2534C200F9522B /* analytics */, 0C7CEA391FE9CE3900125C79 /* behavior */, - 0C8BBEF61FCB402900580909 /* otctl */, - 0C8BBE831FC9DA1700580909 /* Octagon Trust */, - 0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */, + DCAE1DCF2073FCA400B4F687 /* categories */, EB27FF051E402C3C00EC9E3A /* ckksctl */, - 6C34464D1E2534C200F9522B /* Analytics */, - BEF88C451EAFFFED00357577 /* TrustedPeers */, DC9B7AD31DCBF336004E9385 /* CloudKit Syncing */, 470D96651FCDE45C0065FE90 /* CoreDataKeychain */, - 47C2F1852059CB680062DE30 /* KeychainResources */, 4771D974209A755800BA9772 /* KeychainDataclassOwner */, + 47C2F1852059CB680062DE30 /* KeychainResources */, + EB74CC182207E48000F1BBAD /* KeychainSettings */, + 0C8BBE831FC9DA1700580909 /* Octagon Trust */, + 0C8BBEF61FCB402900580909 /* otctl */, + DA41FDFC2241A7CD00838FB3 /* otpaird */, + DC90A4BD21F275EC001300EB /* escrowrequest */, + BED01530206F050F0027A2B4 /* README.txt */, + DCC78D911D8085F200865A7C /* SecureObjectSync */, + 47C51B851EEA657D0032D9E5 /* SecurityUnitTests */, + 0CF0E2DD1F8EE37C00BD18E4 /* Signin Metrics */, + DC0EF8F0208697C600AB9E95 /* tpctl */, + BECFA42F20F91AFE00B11002 /* tppolicy */, + 47B3A90B21027D71001F4281 /* Trieste */, + BEF88C451EAFFFED00357577 /* TrustedPeers */, + BEAA002C202A832500E51F45 /* TrustedPeersHelper */, + BED987D42099145300607A5F /* TrustedPeersHelperUnitTests */, ); path = keychain; sourceTree = ""; }; + DC7FC44121EE6F4E003C39B8 /* featureflags */ = { + isa = PBXGroup; + children = ( + DC79572C21EEB62400761E21 /* Info.plist */, + DC7FC44321EE6F7B003C39B8 /* Security.plist */, + ); + path = featureflags; + sourceTree = ""; + }; + DC8506A42097E8CF00C712EC /* iOS Resources */ = { + isa = PBXGroup; + children = ( + DC52EA971D80CC2A00B0A59C /* security.1 */, + DC52EA901D80CC2A00B0A59C /* entitlements.plist */, + ); + name = "iOS Resources"; + path = iOS; + sourceTree = ""; + }; + DC8506A52097E92900C712EC /* macOS security2 Resources */ = { + isa = PBXGroup; + children = ( + DCE4E6A71D7A38C000AFB96E /* security2.1 */, + 4C4CB7100DDA44900026B660 /* entitlements.plist */, + ); + name = "macOS security2 Resources"; + path = macOS; + sourceTree = ""; + }; DC8834001D8A217200CE0ACA /* ASN1 */ = { isa = PBXGroup; children = ( @@ -18469,9 +22020,101 @@ path = OSX/libsecurity_asn1/lib; sourceTree = ""; }; + DC88467E223742CA00738068 /* View Matching */ = { + isa = PBXGroup; + children = ( + ); + name = "View Matching"; + path = view_matching; + sourceTree = ""; + }; + DC90A4BD21F275EC001300EB /* escrowrequest */ = { + isa = PBXGroup; + children = ( + DCD33D95220CFF93000A390B /* operations */, + DCA9D83A21FFDB7400B27421 /* tests */, + DC90A4BF21F27636001300EB /* Framework */, + DC2B756521F290B4003C9356 /* generated */, + DC90A4C621F279D4001300EB /* SecEscrowPendingRecord.proto */, + DCAB17D32200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.h */, + DCAB17D42200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.m */, + DCA9D84B21FFF04600B27421 /* EscrowRequestServer.h */, + DCA9D84C21FFF04700B27421 /* EscrowRequestServer.m */, + DC4A76A4221267FB006F2D8F /* EscrowRequestServerHelpers.h */, + DC4A76A2221267D4006F2D8F /* EscrowRequestServerHelpers.m */, + DCA9D83D21FFE50A00B27421 /* EscrowRequestXPCServer.h */, + DCA9D83C21FFE50900B27421 /* EscrowRequestXPCServer.m */, + DCA9D83F21FFE62A00B27421 /* EscrowRequestXPCProtocol.h */, + DCA9D84521FFE7CF00B27421 /* EscrowRequestXPCProtocol.m */, + DCD33D79220B985A000A390B /* EscrowRequestController.h */, + DCD33D7A220B985A000A390B /* EscrowRequestController.m */, + ); + path = escrowrequest; + sourceTree = ""; + }; + DC90A4BF21F27636001300EB /* Framework */ = { + isa = PBXGroup; + children = ( + DC90A4C021F27680001300EB /* SecEscrowRequest.h */, + DC90A4C121F27680001300EB /* SecEscrowRequest.m */, + ); + path = Framework; + sourceTree = ""; + }; + DC99B89620EAD4AB0065B73B /* CK API */ = { + isa = PBXGroup; + children = ( + 0C8A034E1FDF60070042E8BE /* OTBottledPeerTests.m */, + 0CBDF64C1FFC951200433E0D /* OTBottledPeerTLK.m */, + 0C2F337520DD64C10031A92D /* OTCliqueTests.m */, + 0C8A034C1FDF4CCE0042E8BE /* OTLocalStoreTests.m */, + 0C2F337620DD64C20031A92D /* OTTestsBase.h */, + 0C2F337720DD64C20031A92D /* OTTestsBase.m */, + 0C24D692204F56E900926E5F /* OTBottledPeerUpdateBottlesTests.m */, + 0C16371F1FD12F1500210823 /* OTCloudStoreTests.m */, + 0C8BBEAF1FC9DCA400580909 /* OTContextTests.m */, + 0C8A03451FDF42BA0042E8BE /* OTEscrowKeyTests.m */, + 0C46A57A2035019800F17112 /* OTLockStateNetworkingTests.m */, + 0CB975502023B199008D6B48 /* OTRampingTests.m */, + DC5060F420E2DB9700925005 /* OTCuttlefishContextTests.m */, + ); + name = "CK API"; + sourceTree = ""; + }; + DC99B89720EAD4D20065B73B /* Octagon */ = { + isa = PBXGroup; + children = ( + DCC0A4C52152C4AB000AF654 /* Pairing */, + DC27C3C820EADD8200F7839C /* OctagonTests-BridgingHeader.h */, + DC85687C2284E7850088D3EF /* OctagonTestMocks.swift */, + DC27C3C020EAD9C300F7839C /* OctagonTests.swift */, + DC7F79B522EA4ED4001FB69A /* OctagonTests+CKKS.swift */, + DC5F2BBD2310B941001ADA5D /* OctagonTests+CoreFollowUp.swift */, + DC2819B822F8F6FE007829F5 /* OctagonTests+DeviceList.swift */, + 0C4CDE6D22922E360050C499 /* OctagonTests+RecoveryKey.swift */, + DC07090222936BCC002711B9 /* OctagonTests+ErrorHandling.swift */, + DCDF03112284E34B008055BA /* OctagonTests+EscrowRecovery.swift */, + DC5BEACC2217509A001681F0 /* OctagonTests+CloudKitAccount.swift */, + 0C5824A322860001009E8C15 /* OctagonTests+HealthCheck.swift */, + DC72502D229600A800493D88 /* OctagonTests+Reset.swift */, + DCB947592127534C00ED9272 /* OctagonTests+SOSUpgrade.swift */, + 0C87D3E2229368A7007853B5 /* OctagonTests+SOS.swift */, + DC7EB928211E20DF00516452 /* OctagonDataPersistenceTests.swift */, + DC99B89320EACA480065B73B /* OctagonTests-Info.plist */, + DCEA0FF6213F1E6F0054A328 /* Octagon.plist */, + 5A04BAF922973EA9001848A0 /* OTFollowupTests.m */, + DCFF82702162834C00D54B02 /* OctagonTestsXPCConnections.swift */, + 0CBEF3422242C9BE00015691 /* TestsObjcTranslation.h */, + 0CBEF3412242C9AE00015691 /* TestsObjcTranslation.m */, + ); + name = Octagon; + path = octagon; + sourceTree = ""; + }; DC9B7AD31DCBF336004E9385 /* CloudKit Syncing */ = { isa = PBXGroup; children = ( + DC88467E223742CA00738068 /* View Matching */, DC9FD3161F857FF800C8AAC8 /* Protocol Buffers */, DCD662F21E3294DE00188186 /* CloudKit Support */, DCFE1C311F17ECC3007640C8 /* dispatch Support */, @@ -18481,8 +22124,11 @@ DCA4D2121E5651950056214F /* Tests (Live CloudKit) */, DC1ED8C21DD5538C002BDCFA /* CKKS.h */, DC1ED8C51DD55476002BDCFA /* CKKS.m */, + DC391F9921BF2F4B00772585 /* CKKSConstants.m */, DCF7A89F1F04502300CABE89 /* CKKSControlProtocol.h */, DCF7A8A21F0450EB00CABE89 /* CKKSControlProtocol.m */, + DCA9BC00221B721D00B4EB26 /* CKKSCloudKitClassDependencies.h */, + DCA9BC01221B721E00B4EB26 /* CKKSCloudKitClassDependencies.m */, DCBDB3B91E57CA7A00B61300 /* CKKSViewManager.h */, DCBDB3BA1E57CA7A00B61300 /* CKKSViewManager.m */, DCBDB3B01E57C67500B61300 /* CKKSKeychainView.h */, @@ -18499,6 +22145,8 @@ DC9C95B31F79CFD1000D19E5 /* CKKSControl.m */, DA6AA1641FE88AFA004565B0 /* CKKSControlServer.h */, DA6AA15E1FE88AF9004565B0 /* CKKSControlServer.m */, + 479108B51EE879F9008CEFA0 /* CKKSAnalytics.h */, + 479108B61EE879F9008CEFA0 /* CKKSAnalytics.m */, ); name = "CloudKit Syncing"; path = ckks; @@ -18507,21 +22155,21 @@ DC9FD3161F857FF800C8AAC8 /* Protocol Buffers */ = { isa = PBXGroup; children = ( - DC9FD3251F858BAD00C8AAC8 /* derived source */, + DC9FD3251F858BAD00C8AAC8 /* generated */, DC4D49D81F857728007AF2B8 /* CKKSSerializedKey.proto */, ); name = "Protocol Buffers"; path = proto; sourceTree = ""; }; - DC9FD3251F858BAD00C8AAC8 /* derived source */ = { + DC9FD3251F858BAD00C8AAC8 /* generated */ = { isa = PBXGroup; children = ( DC9FD3271F858D3F00C8AAC8 /* CKKSSerializedKey.h */, DC9FD3261F858D3E00C8AAC8 /* CKKSSerializedKey.m */, ); - name = "derived source"; - path = source; + name = generated; + path = generated_source; sourceTree = ""; }; DCA4D2121E5651950056214F /* Tests (Live CloudKit) */ = { @@ -18555,6 +22203,17 @@ name = Helpers; sourceTree = ""; }; + DCA9D83A21FFDB7400B27421 /* tests */ = { + isa = PBXGroup; + children = ( + DCAB17CB21FFF6C400E1DFCF /* MockSynchronousEscrowServer.h */, + DCAB17CC21FFF6C400E1DFCF /* MockSynchronousEscrowServer.m */, + DCA9D83B21FFDBA100B27421 /* SecEscrowRequestsTests-Info.plist */, + DCBF4AE321FFC9A800539F0A /* SecEscrowRequestTests.m */, + ); + path = tests; + sourceTree = ""; + }; DCAE1DCF2073FCA400B4F687 /* categories */ = { isa = PBXGroup; children = ( @@ -18567,6 +22226,7 @@ DCB340651D8A24CC0054D16E /* authorization */ = { isa = PBXGroup; children = ( + F6D600702166551800F9F7C9 /* AuthorizationTrampolinePriv.h */, DC17875D1D7790E500B50D50 /* AuthorizationPriv.h */, DC17875E1D7790E500B50D50 /* AuthorizationTagsPriv.h */, DC17851C1D7789AF00B50D50 /* Authorization.h */, @@ -18810,8 +22470,6 @@ DCB341D41D8A2BAC0054D16E /* osxverifier.h */, DCB341D51D8A2BAC0054D16E /* u32handleobject.cpp */, DCB341D61D8A2BAC0054D16E /* u32handleobject.h */, - DCB341D71D8A2BAC0054D16E /* uniformrandom.cpp */, - DCB341D81D8A2BAC0054D16E /* uniformrandom.h */, DCB341D91D8A2BAC0054D16E /* walkers.cpp */, DCB341DA1D8A2BAC0054D16E /* walkers.h */, ); @@ -19087,6 +22745,78 @@ path = OSX/libsecurity_keychain; sourceTree = ""; }; + DCC0A4C52152C4AB000AF654 /* Pairing */ = { + isa = PBXGroup; + children = ( + 0CADDF0421545C8E00DF8B06 /* OctagonPairingTests.swift */, + 0C6604812134DD5D00BFBBB8 /* OctagonPairingTests+ProximitySetup.swift */, + 0CBA047C214C4E4D005B3A2F /* OctagonPairingTests+ProxMultiClients.swift */, + 0CD5797721498F7700C43496 /* OctagonPairingTests+Piggybacking.swift */, + ); + path = Pairing; + sourceTree = ""; + }; + DCC67E2A20DDC05900A70A31 /* Operations */ = { + isa = PBXGroup; + children = ( + DCB946AD22FCB88400BE4490 /* OTDetermineHSA2AccountStatusOperation.h */, + DCB946AE22FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.m */, + DCE772642290712F005862B4 /* OctagonCheckTrustStateOperation.h */, + DCE772652290712F005862B4 /* OctagonCheckTrustStateOperation.m */, + DC047085218BCEF20078BDAA /* OTOperationDependencies.h */, + DC047086218BCEF20078BDAA /* OTOperationDependencies.m */, + 1B5EAAD92252ABCC008D27E7 /* OTFetchViewsOperation.h */, + 1B5EAADB2252ABCC008D27E7 /* OTFetchViewsOperation.m */, + DCBFF830222611A200C5C044 /* OTFetchCKKSKeysOperation.h */, + DCBFF831222611A200C5C044 /* OTFetchCKKSKeysOperation.m */, + DCF12671218A7579000124C6 /* OTLeaveCliqueOperation.h */, + DCF12672218A757A000124C6 /* OTLeaveCliqueOperation.m */, + DC221BA92267E2A60068DBCF /* OTUpdateTPHOperation.h */, + DC221BAA2267E2A60068DBCF /* OTUpdateTPHOperation.m */, + DCF46C2C214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.h */, + DCF46C2D214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.m */, + DC6DE897213076C000C6B56D /* OTSOSUpgradeOperation.h */, + DC6DE898213076C000C6B56D /* OTSOSUpgradeOperation.m */, + DC93F02722387A010072720A /* OTSOSUpdatePreapprovalsOperation.h */, + DC93F02822387A010072720A /* OTSOSUpdatePreapprovalsOperation.m */, + DCC67E2B20DDC07900A70A31 /* OTPrepareOperation.h */, + DCC67E2C20DDC07900A70A31 /* OTPrepareOperation.m */, + 0C4F4DE121153659007F7E20 /* OTEpochOperation.h */, + 0C4F4DDA211535E8007F7E20 /* OTEpochOperation.m */, + 0CC8A9002123AA3B005D7F6A /* OTClientVoucherOperation.h */, + 0CC8A8FA2123A9EB005D7F6A /* OTClientVoucherOperation.m */, + 0CC8A9052123AF16005D7F6A /* OTJoinWithVoucherOperation.h */, + 0CC8A9012123AEF7005D7F6A /* OTJoinWithVoucherOperation.m */, + 0C66046E2134985100BFBBB8 /* OTEstablishOperation.h */, + 0C6604692134983900BFBBB8 /* OTEstablishOperation.m */, + DCFF82722162876400D54B02 /* OTResetOperation.h */, + DCFF82732162876400D54B02 /* OTResetOperation.m */, + 0C00FC85217A972E00C8BF00 /* OTLocalCuttlefishReset.h */, + 0C00FC81217A971800C8BF00 /* OTLocalCuttlefishReset.m */, + DC7F79B822EA5C72001FB69A /* OTLocalCKKSResetOperation.h */, + DC7F79B922EA5C72001FB69A /* OTLocalCKKSResetOperation.m */, + DC8757F2218D2003000E65F1 /* OTRemovePeersOperation.h */, + DC8757F3218D2003000E65F1 /* OTRemovePeersOperation.m */, + DCC5417F225C05170095D926 /* OTUploadNewCKKSTLKsOperation.h */, + DCC54180225C05180095D926 /* OTUploadNewCKKSTLKsOperation.m */, + DC7250352296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.h */, + DC7250362296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.m */, + 0CB8DC962194B1300021A7C8 /* OTVouchWithBottleOperation.h */, + 0CB8DC992194B1440021A7C8 /* OTVouchWithBottleOperation.m */, + 0C1B8BB3223323710094D5DA /* OTVouchWithRecoveryKeyOperation.h */, + 0C1B8BB52233241E0094D5DA /* OTVouchWithRecoveryKeyOperation.m */, + 0CD3D518224047B400024755 /* OTSetRecoveryKeyOperation.h */, + 0CD3D5152240479600024755 /* OTSetRecoveryKeyOperation.m */, + 0CDD6F78226E62BC009094C2 /* OTTriggerEscrowUpdateOperation.h */, + 0CDD6F76226E62AD009094C2 /* OTTriggerEscrowUpdateOperation.m */, + 0CA7020B2280D99D0085AC54 /* OTCheckHealthOperation.h */, + 0CA702082280D5600085AC54 /* OTCheckHealthOperation.m */, + 0C87D3DA229326CB007853B5 /* OTEnsureOctagonKeyConsistency.h */, + 0C87D3D6229326A2007853B5 /* OTEnsureOctagonKeyConsistency.m */, + ); + name = Operations; + sourceTree = ""; + }; DCC78C7E1D8085D800865A7C /* Regressions */ = { isa = PBXGroup; children = ( @@ -19103,10 +22833,10 @@ DCC78C411D8085D800865A7C /* secd-20-keychain_upgrade.m */, DCC78C421D8085D800865A7C /* secd-21-transmogrify.m */, DCC78C431D8085D800865A7C /* secd-30-keychain-upgrade.m */, - DCC78C441D8085D800865A7C /* secd-31-keychain-bad.m */, DCC78C451D8085D800865A7C /* secd-31-keychain-unreadable.m */, DCC78C461D8085D800865A7C /* secd-32-restore-bad-backup.m */, DCC78C471D8085D800865A7C /* secd-33-keychain-ctk.m */, + EB35153F211A79CB0097A87C /* secd-33-keychain-backup.m */, DCC78C481D8085D800865A7C /* secd-34-backup-der-parse.m */, DCC78C491D8085D800865A7C /* secd-35-keychain-migrate-inet.m */, DCFAEDD51D99A464005187E4 /* secd-36-ks-encrypt.m */, @@ -19183,6 +22913,8 @@ DC5AC2001D83653E00CF422C /* resources */, DCC78C7E1D8085D800865A7C /* Regressions */, DCC78C811D8085D800865A7C /* entitlements.plist */, + 6C4AEF82218A09210012C5DA /* CheckV12DevEnabled.h */, + 6C4AEF83218A09210012C5DA /* CheckV12DevEnabled.m */, DCC78C8E1D8085D800865A7C /* SecDbItem.c */, DCC78C8F1D8085D800865A7C /* SecDbItem.h */, DCC78C901D8085D800865A7C /* SecDbKeychainItem.m */, @@ -19212,8 +22944,8 @@ DCC78CB41D8085D800865A7C /* SecOTRRemote.m */, DCC78CB51D8085D800865A7C /* SecOTRRemote.h */, EBC15B1B1DB4306C00126882 /* com.apple.secd.sb */, - 526965CB1E6E283100627F9D /* AsymKeybagBackup.h */, - 526965CC1E6E283100627F9D /* AsymKeybagBackup.m */, + 6C4AEF92218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.h */, + 6C4AEF93218A124B0012C5DA /* SecDbKeychainMetadataKeyStore.m */, 470ACEF21F58C3A600D1D5BD /* SecDbKeychainItemV7.h */, 470ACEF31F58C3A600D1D5BD /* SecDbKeychainItemV7.m */, 47D1837D1FB1183D00CFCD89 /* SecDbKeychainV7-protobufs */, @@ -19221,6 +22953,14 @@ 47FF17251FD60ACA00875565 /* SFKeychainServer.m */, 473337771FDAFBCC00E19F30 /* SFKeychainControlManager.h */, 473337781FDAFBCC00E19F30 /* SFKeychainControlManager.m */, + 6C4AEF8A218A0A400012C5DA /* SecDbBackupManager.h */, + 6C9791C421C17D060074C609 /* SecDbBackupManager_Internal.h */, + 6C4AEF8B218A0A400012C5DA /* SecDbBackupManager.m */, + 6CB6CBFE2198D40B0080AD6F /* SecDbBackupManager-protobufs */, + 6C4AEF9C218A16F80012C5DA /* SecAKSObjCWrappers.h */, + 6C4AEF9D218A16F80012C5DA /* SecAKSObjCWrappers.m */, + 1B995256226681ED00A2D6CD /* PolicyReporter.h */, + 1B995258226681EE00A2D6CD /* PolicyReporter.m */, ); name = "securityd iOS"; path = OSX/sec/securityd; @@ -19441,8 +23181,6 @@ DCC78D891D8085F200865A7C /* SOSCloudCircle.m */, DCC78D8A1D8085F200865A7C /* SOSCloudCircle.h */, DCC78D8B1D8085F200865A7C /* SOSCloudCircleInternal.h */, - DCB332371F46804000178C30 /* SOSSysdiagnose.h */, - DCC78D8C1D8085F200865A7C /* SOSSysdiagnose.m */, DCC78D8D1D8085F200865A7C /* SOSInternal.m */, DCC78D8E1D8085F200865A7C /* SOSInternal.h */, DCC78D8F1D8085F200865A7C /* SOSTypes.h */, @@ -19451,11 +23189,17 @@ EBEEEE361EA31A8300E15F5C /* SOSControlHelper.m */, DAB27ADA1FA29EB700DEBBDE /* SOSControlServer.h */, DAB27AE01FA29EB800DEBBDE /* SOSControlServer.m */, + DCC78CFC1D8085F200865A7C /* CKBridge */, + DCC78D101D8085F200865A7C /* Regressions */, + DCC78DA01D8085F200865A7C /* Tool */, 48FE669520E6E69C00FAEF17 /* SOSAuthKitHelpers.h */, 48FE668F20E6E69B00FAEF17 /* SOSAuthKitHelpers.m */, + 480C03D621459CD70034570E /* SOSTrustedDeviceAttributes.h */, + 480C03D321459CD60034570E /* SOSTrustedDeviceAttributes.m */, ); - path = SecureObjectSync; - sourceTree = ""; + name = SecureObjectSync; + path = keychain/SecureObjectSync; + sourceTree = SOURCE_ROOT; }; DCC78DA01D8085F200865A7C /* Tool */ = { isa = PBXGroup; @@ -19480,18 +23224,6 @@ path = Tool; sourceTree = ""; }; - DCC78DA11D8085F200865A7C /* SOSCircle */ = { - isa = PBXGroup; - children = ( - DCC78CFC1D8085F200865A7C /* CKBridge */, - DCC78D101D8085F200865A7C /* Regressions */, - DCC78D911D8085F200865A7C /* SecureObjectSync */, - DCC78DA01D8085F200865A7C /* Tool */, - ); - name = SOSCircle; - path = OSX/sec/SOSCircle; - sourceTree = ""; - }; DCC78DA61D8085FC00865A7C /* crypto */ = { isa = PBXGroup; children = ( @@ -19578,13 +23310,7 @@ DCC78DB41D8085FC00865A7C /* si-13-item-system.m */, DCC78DB51D8085FC00865A7C /* si-14-dateparse.c */, DCC78DB61D8085FC00865A7C /* si-15-delete-access-group.m */, - DCC78DB71D8085FC00865A7C /* si-15-certificate.c */, - DCC78DB81D8085FC00865A7C /* si-16-ec-certificate.c */, DCC78DB91D8085FC00865A7C /* si-17-item-system-bluetooth.m */, - D4AA647C1E97144700D317ED /* si-18-certificate-parse.m */, - DCC78DBA1D8085FC00865A7C /* si-20-sectrust-policies.m */, - DCC78DBB1D8085FC00865A7C /* si-20-sectrust.c */, - DCC78DBC1D8085FC00865A7C /* si-20-sectrust.h */, DCC78DBD1D8085FC00865A7C /* si-21-sectrust-asr.c */, DCC78DBE1D8085FC00865A7C /* si-22-sectrust-iap.c */, DCC78DBF1D8085FC00865A7C /* si-22-sectrust-iap.h */, @@ -19593,7 +23319,6 @@ DCC78DC11D8085FC00865A7C /* si-24-sectrust-digicert-malaysia.c */, DCC78DC21D8085FC00865A7C /* si-24-sectrust-diginotar.c */, DCC78DC31D8085FC00865A7C /* si-24-sectrust-itms.c */, - DCC78DC41D8085FC00865A7C /* si-24-sectrust-nist.c */, DCC78DC51D8085FC00865A7C /* si-24-sectrust-passbook.c */, DC0B62261D90973900D43BCB /* si-25-cms-skid.h */, DC0B62271D90973900D43BCB /* si-25-cms-skid.m */, @@ -19601,8 +23326,8 @@ DCC78DC71D8085FC00865A7C /* si-27-sectrust-exceptions.c */, DCC78DC81D8085FC00865A7C /* si-28-sectrustsettings.m */, DCC78DC91D8085FC00865A7C /* si-28-sectrustsettings.h */, - D487FBB71DB8357300D4BB0B /* si-29-sectrust-sha1-deprecation.m */, - D487FBB91DB835B500D4BB0B /* si-29-sectrust-sha1-deprecation.h */, + D4AA0D9922FB959600D77FA4 /* si-29-cms-chain-mode.m */, + D4AA0D9C22FB962300D77FA4 /* si-29-cms-chain-mode.h */, DCC78DCA1D8085FC00865A7C /* si-30-keychain-upgrade.c */, DCC78DCB1D8085FC00865A7C /* si-31-keychain-bad.c */, DCC78DCC1D8085FC00865A7C /* si-31-keychain-unreadable.c */, @@ -19623,8 +23348,8 @@ DCC78DD51D8085FC00865A7C /* si-44-seckey-ec.m */, DCC78DD61D8085FC00865A7C /* si-44-seckey-ies.m */, 5E77936E1E5EFEB20074A2D1 /* si-44-seckey-aks.m */, - 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */, 09A3B9DF1F8271A200C5C324 /* si-44-seckey-proxy.m */, + 09CB496A1F2F64AF00C8E4DE /* si-44-seckey-fv.m */, DCC78DD71D8085FC00865A7C /* si-50-secrandom.c */, DCC78DD81D8085FC00865A7C /* si-60-cms.c */, DCC78DD91D8085FC00865A7C /* si-61-pkcs12.c */, @@ -19651,23 +23376,14 @@ DCC78E001D8085FC00865A7C /* si_77_SecAccessControl.c */, DCC78E011D8085FC00865A7C /* si-78-query-attrs.c */, DCC78E021D8085FC00865A7C /* si-80-empty-data.c */, - DCC78E031D8085FC00865A7C /* si-82-seccertificate-ct.c */, - DCC78E041D8085FC00865A7C /* si-82-sectrust-ct.m */, - D46A6BF121531F77008ABF6A /* si-82-sectrust-ct.h */, DCC78E051D8085FC00865A7C /* si-82-token-ag.c */, DCC78E061D8085FC00865A7C /* si-83-seccertificate-sighashalg.c */, BE6215BD1DB6E69100961E15 /* si-84-sectrust-allowlist.m */, - DCC78E071D8085FC00865A7C /* si-85-sectrust-ssl-policy.c */, - DCC78E081D8085FC00865A7C /* si-85-sectrust-ssl-policy.h */, - DCC78E091D8085FC00865A7C /* si-87-sectrust-name-constraints.m */, - DCC78E0A1D8085FC00865A7C /* si-87-sectrust-name-constraints.h */, - BEB9E9E51FFF193D00676593 /* si-88-sectrust-valid.m */, + BE9B8B49202BB4A10081EF87 /* si-88-sectrust-valid.m */, DCC78E0B1D8085FC00865A7C /* si-89-cms-hash-agility.m */, 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 */, @@ -19703,29 +23419,6 @@ name = Regressions; sourceTree = ""; }; - DCC78E271D8085FC00865A7C /* Security/Tool */ = { - isa = PBXGroup; - children = ( - DCC78E191D8085FC00865A7C /* verify_cert.c */, - DCC78E1A1D8085FC00865A7C /* keychain_util.c */, - DCC78E1B1D8085FC00865A7C /* keychain_util.h */, - DCC78E1C1D8085FC00865A7C /* add_internet_password.c */, - DCC78E1D1D8085FC00865A7C /* log_control.c */, - DCC78E1E1D8085FC00865A7C /* codesign.c */, - DCC78E1F1D8085FC00865A7C /* keychain_add.c */, - DCC78E201D8085FC00865A7C /* keychain_find.m */, - DCC78E221D8085FC00865A7C /* pkcs12_util.c */, - DCC78E231D8085FC00865A7C /* scep.c */, - DCC78E241D8085FC00865A7C /* SecurityCommands.h */, - DCC78E251D8085FC00865A7C /* show_certificates.c */, - D453C38A1FEC669300DE349B /* trust_update.m */, - DCC78E261D8085FC00865A7C /* spc.c */, - D484A1012167D6F8008653A9 /* ct_exceptions.m */, - ); - name = Security/Tool; - path = OSX/sec/Security/Tool; - sourceTree = ""; - }; DCC78E9E1D8085FC00865A7C /* Security.framework iOS */ = { isa = PBXGroup; children = ( @@ -19735,7 +23428,7 @@ 7908507E0CA87CF00083CC4D /* ipc */, DCC78E181D8085FC00865A7C /* Regressions */, 4C198F1A0ACDB4BF00AAB142 /* strings */, - 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */, + D4CF6E62211588140014647E /* cms */, DCC78E321D8085FC00865A7C /* SecAccessControlExports.exp-in */, DCC78E4E1D8085FC00865A7C /* SecExports.exp-in */, DCD7EE9B1F4F51D9007D9804 /* ios_tapi_hacks.h */, @@ -19896,8 +23589,6 @@ DCD067CA1D8CDF7E007602F1 /* cskernel.cpp */, DCD067CB1D8CDF7E007602F1 /* csprocess.h */, DCD067CC1D8CDF7E007602F1 /* csprocess.cpp */, - DCD067CD1D8CDF7E007602F1 /* csgeneric.h */, - DCD067CE1D8CDF7E007602F1 /* csgeneric.cpp */, ); name = "Code Classes"; sourceTree = ""; @@ -19930,15 +23621,6 @@ sourceTree = ""; usesTabs = 1; }; - DCD067E91D8CDF7E007602F1 /* Static Support */ = { - isa = PBXGroup; - children = ( - DCD067E71D8CDF7E007602F1 /* SecCodeHostLib.h */, - DCD067E81D8CDF7E007602F1 /* SecCodeHostLib.c */, - ); - name = "Static Support"; - sourceTree = ""; - }; DCD067ED1D8CDF7E007602F1 /* DTrace */ = { isa = PBXGroup; children = ( @@ -19970,6 +23652,8 @@ DCD067FD1D8CDF7E007602F1 /* dirscanner.cpp */, A6B1BA78207BD9D400F1E099 /* notarization.cpp */, A6B1BA79207BD9D400F1E099 /* notarization.h */, + 1F631C5122387F27005920D8 /* legacydevid.cpp */, + 1F631C5222387F27005920D8 /* legacydevid.h */, ); name = "Local Utilities"; sourceTree = ""; @@ -20021,7 +23705,6 @@ DCD067C81D8CDF7E007602F1 /* Requirements */, DCD067CF1D8CDF7E007602F1 /* Code Classes */, DCD067E41D8CDF7E007602F1 /* Disk Representations */, - DCD067E91D8CDF7E007602F1 /* Static Support */, DCD067ED1D8CDF7E007602F1 /* DTrace */, DCD067FE1D8CDF7E007602F1 /* Local Utilities */, DCD068011D8CDF7E007602F1 /* Security Plugins */, @@ -20198,8 +23881,6 @@ DCD06B061D8E0D7D007602F1 /* unix++.cpp */, DCD06B071D8E0D7D007602F1 /* unixchild.h */, DCD06B081D8E0D7D007602F1 /* unixchild.cpp */, - DCD06B091D8E0D7D007602F1 /* vproc++.h */, - DCD06B0A1D8E0D7D007602F1 /* vproc++.cpp */, ); name = Unix; sourceTree = ""; @@ -20207,10 +23888,9 @@ DCD06B1B1D8E0D7D007602F1 /* Mach */ = { isa = PBXGroup; children = ( + DA2C402D2189302E005F1CC3 /* mach_notify.defs */, DCD06B0C1D8E0D7D007602F1 /* mach++.h */, DCD06B0D1D8E0D7D007602F1 /* mach++.cpp */, - DCD06B0E1D8E0D7D007602F1 /* mach_notify.h */, - DCD06B0F1D8E0D7D007602F1 /* mach_notify.c */, DCD06B101D8E0D7D007602F1 /* cfmach++.h */, DCD06B111D8E0D7D007602F1 /* cfmach++.cpp */, DCD06B121D8E0D7D007602F1 /* macho++.h */, @@ -20220,8 +23900,6 @@ DCD06B161D8E0D7D007602F1 /* dyld_cache_format.h */, DCD06B171D8E0D7D007602F1 /* machserver.h */, DCD06B181D8E0D7D007602F1 /* machserver.cpp */, - DCD06B191D8E0D7D007602F1 /* machrunloopserver.h */, - DCD06B1A1D8E0D7D007602F1 /* machrunloopserver.cpp */, ); name = Mach; sourceTree = ""; @@ -20264,8 +23942,6 @@ DCD06AC31D8E0D7D007602F1 /* debugging_internal.h */, DCD06AC41D8E0D7D007602F1 /* debugsupport.h */, DCD06AC51D8E0D7D007602F1 /* debugging_internal.cpp */, - DCD06AC61D8E0D7D007602F1 /* devrandom.h */, - DCD06AC71D8E0D7D007602F1 /* devrandom.cpp */, DCD06AC81D8E0D7D007602F1 /* dispatch.cpp */, DCD06AC91D8E0D7D007602F1 /* dispatch.h */, DCD06ACA1D8E0D7D007602F1 /* endian.h */, @@ -20292,8 +23968,6 @@ DCD06AE21D8E0D7D007602F1 /* simpleprefs.cpp */, DCD06AE31D8E0D7D007602F1 /* sqlite++.h */, DCD06AE41D8E0D7D007602F1 /* sqlite++.cpp */, - DCD06AE51D8E0D7D007602F1 /* streams.h */, - DCD06AE61D8E0D7D007602F1 /* streams.cpp */, DCD06AE71D8E0D7D007602F1 /* superblob.h */, DCD06AE81D8E0D7D007602F1 /* superblob.cpp */, DCD06AE91D8E0D7D007602F1 /* threading.h */, @@ -20335,6 +24009,34 @@ path = OSX/libsecurity_utilities; sourceTree = ""; }; + DCD33D7D220B9D98000A390B /* State Machine Machinery */ = { + isa = PBXGroup; + children = ( + DC0FA6AE2291F63F00FE01C4 /* OctagonPendingFlag.h */, + DC0FA6AF2291F63F00FE01C4 /* OctagonPendingFlag.m */, + DC5681A8224DA05F008F8DEB /* OctagonFlags.h */, + DC5681A9224DA05F008F8DEB /* OctagonFlags.m */, + DCFC91AD21F16E0B00E674DD /* OctagonStateMachine.h */, + DCFC91AE21F16E0B00E674DD /* OctagonStateMachine.m */, + DCD33D7E220B9DC8000A390B /* OctagonStateMachineHelpers.h */, + DCD33D7F220B9DC8000A390B /* OctagonStateMachineHelpers.m */, + DC45D43B22EB619D00CEB6B7 /* OctagonStateMachineObservers.h */, + DC45D43C22EB619D00CEB6B7 /* OctagonStateMachineObservers.m */, + ); + name = "State Machine Machinery"; + sourceTree = ""; + }; + DCD33D95220CFF93000A390B /* operations */ = { + isa = PBXGroup; + children = ( + DCD33D91220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.h */, + DCD33D92220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.m */, + DCD33D8C220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.h */, + DCD33D8D220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.m */, + ); + path = operations; + sourceTree = ""; + }; DCD662EB1E32946000188186 /* Sync Objects */ = { isa = PBXGroup; children = ( @@ -20357,8 +24059,12 @@ DCEA5D541E2826DB0089CF55 /* CKKSSIV.m */, DCE278DB1ED789EF0083B485 /* CKKSCurrentItemPointer.h */, DCE278DC1ED789EF0083B485 /* CKKSCurrentItemPointer.m */, - DC7341F11F8447AB00AB9BDF /* CKKSTLKShare.h */, - DC7341F21F8447AB00AB9BDF /* CKKSTLKShare.m */, + DC7341F11F8447AB00AB9BDF /* CKKSTLKShareRecord.h */, + DC7341F21F8447AB00AB9BDF /* CKKSTLKShareRecord.m */, + DC5A01E621BB428500D87AB9 /* CKKSTLKShare.h */, + DC5A01E721BB428500D87AB9 /* CKKSTLKShare.m */, + DC0BD4EF21BB05F2006B9154 /* CKKSKeychainBackedKey.h */, + DC0BD4F021BB05F2006B9154 /* CKKSKeychainBackedKey.m */, ); name = "Sync Objects"; sourceTree = ""; @@ -20379,6 +24085,8 @@ DCBF2F841F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m */, DC7A17EB1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h */, DC7A17EC1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m */, + DC5F65AC2225C22C0051E9FA /* CKKSProvideKeySetOperation.h */, + DC5F65AD2225C22C0051E9FA /* CKKSProvideKeySetOperation.m */, DCA4D2131E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h */, DCA4D2141E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m */, DC1DA65C1E4554620094CE7F /* CKKSScanLocalItemsOperation.h */, @@ -20400,17 +24108,19 @@ DCD662F21E3294DE00188186 /* CloudKit Support */ = { isa = PBXGroup; children = ( + DC614C4F22A9BDB500E16ADA /* CKKSZoneModifier.h */, + DC614C5022A9BDB500E16ADA /* CKKSZoneModifier.m */, DC9082C21EA0276000D0C1C5 /* CKKSZoneChangeFetcher.h */, DC9082C31EA0276000D0C1C5 /* CKKSZoneChangeFetcher.m */, DC222CA91E08C57400B09171 /* CloudKitDependencies.h */, - DCEA5D831E2F14810089CF55 /* CKKSAPSReceiver.h */, - DCEA5D841E2F14810089CF55 /* CKKSAPSReceiver.m */, + DCEA5D831E2F14810089CF55 /* OctagonAPSReceiver.h */, + DCEA5D841E2F14810089CF55 /* OctagonAPSReceiver.m */, DCEA5D951E3014250089CF55 /* CKKSZone.h */, DCEA5D961E3014250089CF55 /* CKKSZone.m */, DC18F76D1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h */, DC18F76E1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m */, - DCFB12C31E95A4C000510F5F /* CKKSCKAccountStateTracker.h */, - DCFB12C41E95A4C000510F5F /* CKKSCKAccountStateTracker.m */, + DCFB12C31E95A4C000510F5F /* CKKSAccountStateTracker.h */, + DCFB12C41E95A4C000510F5F /* CKKSAccountStateTracker.m */, DC2C5F5A1F0EB97E00FEBDA7 /* CKKSNotifier.h */, DC2C5F5B1F0EB97E00FEBDA7 /* CKKSNotifier.m */, DC94BCC81F10448600E07CEB /* CloudKitCategories.h */, @@ -20419,6 +24129,47 @@ name = "CloudKit Support"; sourceTree = ""; }; + DCE0777B21ADD92B002662FD /* proto */ = { + isa = PBXGroup; + children = ( + BE7089991F9AAF57001ACC20 /* generated */, + BE7089911F9AA027001ACC20 /* TPPBVoucher.proto */, + BE7089CB1FA3B19A001ACC20 /* TPPBPeerDynamicInfo.proto */, + BEC3739B20CF2AA200DBDF5B /* TPPBDisposition.proto */, + BEC373C120D8224A00DBDF5B /* TPPBDispositionEntry.proto */, + BEC373A820D810DA00DBDF5B /* TPPBAncientEpoch.proto */, + BEC373A620D810D800DBDF5B /* TPPBPolicyProhibits.proto */, + BEC373A720D810D900DBDF5B /* TPPBUnknownMachineID.proto */, + BE7089CC1FA3B332001ACC20 /* TPPBPeerStableInfo.proto */, + BE7089DB1FA407E4001ACC20 /* TPPBPeerPermanentInfo.proto */, + BE7089D91FA3F0AF001ACC20 /* TPPBPolicySecret.proto */, + 6C0C807D20EAF86100334E33 /* TPPBPolicyDocument.proto */, + 6C0C807F20EAFB9600334E33 /* TPPBPolicyCategoriesByView.proto */, + 6C0C808020EAFB9600334E33 /* TPPBPolicyModelToCategory.proto */, + 6C0C808320EAFD7A00334E33 /* TPPBPolicyIntroducersByCategory.proto */, + 6C70D8D520EBDE4500AB6FAF /* TPPBPolicyRedaction.proto */, + 1B8341B72239AD39002BF18A /* TPPBPolicyKeyViewMapping.proto */, + DC88466922373A4000738068 /* TPPBDictionaryMatchingRule.proto */, + ); + path = proto; + sourceTree = ""; + }; + DCE0777C21ADE96C002662FD /* generated */ = { + isa = PBXGroup; + children = ( + 47922D501FAA7DF60008F7E0 /* SecDbKeychainSerializedItemV7.h */, + 47922D511FAA7DF70008F7E0 /* SecDbKeychainSerializedItemV7.m */, + 47922D371FAA7C040008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h */, + 47922D361FAA7C030008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.m */, + 47922D3B1FAA7C100008F7E0 /* SecDbKeychainSerializedMetadata.h */, + 47922D3A1FAA7C0F0008F7E0 /* SecDbKeychainSerializedMetadata.m */, + 47922D3E1FAA7C1A0008F7E0 /* SecDbKeychainSerializedSecretData.h */, + 47922D3F1FAA7C1B0008F7E0 /* SecDbKeychainSerializedSecretData.m */, + ); + name = generated; + path = generated_source; + sourceTree = ""; + }; DCE4E6D61D7A420100AFB96E /* SecurityTestsOSX */ = { isa = PBXGroup; children = ( @@ -20443,6 +24194,8 @@ isa = PBXGroup; children = ( D4BEECE61E93093A00F76D1A /* trustd.c */, + D4B68C64211A8186009FED69 /* trustd_spi.h */, + D4B68C65211A8186009FED69 /* trustd_spi.c */, D43DBED71E99D17100C04AEA /* nameconstraints.c */, D43DBED81E99D17100C04AEA /* nameconstraints.h */, D43DBED91E99D17100C04AEA /* OTATrustUtilities.m */, @@ -20475,12 +24228,13 @@ D43761651EB2996C00954447 /* SecRevocationNetworking.m */, D43DBEF31E99D17300C04AEA /* SecRevocationServer.c */, D43DBEF41E99D17300C04AEA /* SecRevocationServer.h */, + 5F8494FF22DFB502008B3EFB /* SecTrustExceptionResetCount.m */, D43DBEF51E99D17300C04AEA /* SecTrustLoggingServer.m */, D43DBEF61E99D17300C04AEA /* SecTrustLoggingServer.h */, D43DBEF71E99D17300C04AEA /* SecTrustServer.c */, D43DBEF81E99D17300C04AEA /* SecTrustServer.h */, D43DBEF91E99D17300C04AEA /* SecTrustStoreServer.c */, - D46B379F2151B6E50083DAAA /* SecTrustStoreServer.m */, + D4EF321E215F0F76000A31A5 /* SecTrustStoreServer.m */, D43DBEFA1E99D17300C04AEA /* SecTrustStoreServer.h */, D4961BBD2079423300F16DA7 /* TrustURLSessionDelegate.m */, D4961BC52079426000F16DA7 /* TrustURLSessionDelegate.h */, @@ -20704,25 +24458,6 @@ name = AppleCSP; sourceTree = ""; }; - DCF7834B1D88B60D00E694BB /* BSafeCSP */ = { - isa = PBXGroup; - children = ( - DCF7833F1D88B60D00E694BB /* algmaker.cpp */, - DCF783401D88B60D00E694BB /* bsafeAsymmetric.cpp */, - DCF783411D88B60D00E694BB /* bsafeContext.cpp */, - DCF783421D88B60D00E694BB /* bsafecsp.h */, - DCF783431D88B60D00E694BB /* bsafecspi.h */, - DCF783441D88B60D00E694BB /* bsafeKeyGen.cpp */, - DCF783451D88B60D00E694BB /* bsafePKCS1.cpp */, - DCF783461D88B60D00E694BB /* bsafePKCS1.h */, - DCF783471D88B60D00E694BB /* bsafeSymmetric.cpp */, - DCF783481D88B60D00E694BB /* bsobjects.h */, - DCF783491D88B60D00E694BB /* memory.cpp */, - DCF7834A1D88B60D00E694BB /* miscalgorithms.cpp */, - ); - name = BSafeCSP; - sourceTree = ""; - }; DCF7834F1D88B60D00E694BB /* ComCryption */ = { isa = PBXGroup; children = ( @@ -20872,7 +24607,6 @@ children = ( DCF783211D88B60D00E694BB /* AES */, DCF7833E1D88B60D00E694BB /* AppleCSP */, - DCF7834B1D88B60D00E694BB /* BSafeCSP */, DCF7834F1D88B60D00E694BB /* ComCryption */, DCF7835B1D88B60D00E694BB /* CryptKitCSP */, DCF783641D88B60D00E694BB /* DiffieHellman */, @@ -21278,10 +25012,93 @@ DCD6C4B11EC5302500414FEE /* CKKSNearFutureScheduler.m */, DCFE1C321F17ECE5007640C8 /* CKKSCondition.h */, DCFE1C331F17ECE5007640C8 /* CKKSCondition.m */, + DC3AF52A2229E6C0006577E8 /* CKKSListenerCollection.h */, + DC3AF52B2229E6C0006577E8 /* CKKSListenerCollection.m */, ); name = "dispatch Support"; sourceTree = ""; }; + E058E53321626583002CA574 /* Products */ = { + isa = PBXGroup; + children = ( + E058E54B21626583002CA574 /* CloudDeviceTest.framework */, + E058E54D21626583002CA574 /* CoreDeviceAutomation.framework */, + E058E54F21626583002CA574 /* CoreDeviceAutomationFrameworkFacade.framework */, + E058E55121626583002CA574 /* OctagonTestHarnessXPCServiceProtocol.framework */, + E058E55321626583002CA574 /* OctagonTrieste.framework */, + E058E55521626583002CA574 /* OctagonTriesteTests.xctest */, + E058E55721626583002CA574 /* OpenSSLThreadLock.framework */, + E058E55B21626583002CA574 /* SSEClient.framework */, + E058E55D21626583002CA574 /* SwiftHTTP.framework */, + E058E55F21626583002CA574 /* SwiftLog.framework */, + E058E56121626583002CA574 /* os_activity.framework */, + ); + name = Products; + sourceTree = ""; + }; + E060D19D2124780F0025B833 /* OctagonTestHarness */ = { + isa = PBXGroup; + children = ( + E060D19E2124780F0025B833 /* OctagonTestHarness.h */, + EB3F9C9B21FCFC60007B6EBA /* OctagonTestHarness.m */, + EB3F9C9E21FCFF8E007B6EBA /* OctagonTestHarness.exp */, + E060D1A12124780F0025B833 /* Info.plist */, + ); + path = OctagonTestHarness; + sourceTree = ""; + }; + E060D1BD212478120025B833 /* OctagonTestHarnessXPCService */ = { + isa = PBXGroup; + children = ( + E060D2BD21248F820025B833 /* Entitlements.plist */, + E060D1BE212478120025B833 /* main.m */, + E060D1C0212478120025B833 /* OctagonTestHarnessXPCServiceDelegate.h */, + E060D1C3212478120025B833 /* OctagonTestHarnessXPCServiceDelegate.m */, + E060D19F2124780F0025B833 /* OctagonTestHarnessXPCService.h */, + E09E09E9215506570042C7D3 /* OctagonTestHarnessXPCService.m */, + EB056E411FE5E390000A771E /* SecRemoteDevice.h */, + EB056E421FE5E390000A771E /* SecRemoteDevice.m */, + EB056E401FE5E390000A771E /* SecRemoteDeviceProtocol.h */, + E060D1C6212478120025B833 /* Info.plist */, + ); + path = OctagonTestHarnessXPCService; + sourceTree = ""; + }; + E060D23E21247C680025B833 /* OctagonTestHarnessXPCServiceProtocol */ = { + isa = PBXGroup; + children = ( + E060D23F21247C680025B833 /* Package.swift */, + E060D24021247C680025B833 /* Sources */, + E060D24521247C680025B833 /* Info.plist */, + ); + path = OctagonTestHarnessXPCServiceProtocol; + sourceTree = ""; + }; + E060D24021247C680025B833 /* Sources */ = { + isa = PBXGroup; + children = ( + E060D24121247C680025B833 /* OctagonTestHarnessXPCServiceProtocol */, + ); + path = Sources; + sourceTree = ""; + }; + E060D24121247C680025B833 /* OctagonTestHarnessXPCServiceProtocol */ = { + isa = PBXGroup; + children = ( + E060D24221247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.m */, + E060D24321247C680025B833 /* include */, + ); + path = OctagonTestHarnessXPCServiceProtocol; + sourceTree = ""; + }; + E060D24321247C680025B833 /* include */ = { + isa = PBXGroup; + children = ( + E060D24421247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.h */, + ); + path = include; + sourceTree = ""; + }; E710C74A1331946500F85568 /* SecurityTests */ = { isa = PBXGroup; children = ( @@ -21295,7 +25112,7 @@ 0C0C88771CCEC5BD00617D1B /* si-82-sectrust-ct-data */, DCE4E72E1D7A436300AFB96E /* si-82-sectrust-ct-logs.plist */, D4C6C5C71FB2AD3F007EA57E /* si-87-sectrust-name-constraints */, - BEB9EA2E1FFF1AF600676593 /* si-88-sectrust-valid-data */, + BE9B8B43202BB42C0081EF87 /* si-88-sectrust-valid-data */, 4C50ACFB1410671D00EE92DE /* DigiNotar */, 79679E241462028800CF997F /* DigicertMalaysia */, E710C74B1331946500F85568 /* Supporting Files */, @@ -21357,35 +25174,21 @@ name = "Supporting Files"; sourceTree = ""; }; - E7C4D03512F9EB210022E067 /* iOS */ = { - isa = PBXGroup; - children = ( - 7901790E12D51F7200CA4D44 /* SecCmsBase.h */, - 7901790F12D51F7200CA4D44 /* SecCmsContentInfo.h */, - 7901791012D51F7200CA4D44 /* SecCmsDecoder.h */, - 7901791112D51F7200CA4D44 /* SecCmsDigestContext.h */, - D4FBBD601DD66196004408F7 /* CMSEncoder.h */, - D4FBBD611DD66196004408F7 /* CMSDecoder.h */, - 7901791212D51F7200CA4D44 /* SecCmsEncoder.h */, - 7901791312D51F7200CA4D44 /* SecCmsEnvelopedData.h */, - 7901791412D51F7200CA4D44 /* SecCmsMessage.h */, - 7901791512D51F7200CA4D44 /* SecCmsRecipientInfo.h */, - 7901791612D51F7200CA4D44 /* SecCmsSignedData.h */, - 7901791712D51F7200CA4D44 /* SecCmsSignerInfo.h */, - ); - name = iOS; - path = libsecurity_smime/lib; - sourceTree = ""; - }; E7D847C61C6BE9710025BB44 /* KeychainCircle.framework */ = { isa = PBXGroup; children = ( + 5A47FFAF228F5DAB00F781B8 /* Protocol Buffers */, E7D848031C6BEFAB0025BB44 /* Tests */, E7D848011C6BEE360025BB44 /* Supporting Files */, E7E3EFE21CBC195700E79A5D /* KCAccountKCCircleDelegate.h */, E7E3EFB91CBC192A00E79A5D /* KCAccountKCCircleDelegate.m */, + 5A47FFB4228F5E9000F781B8 /* KCInitialMessageData.h */, + 5A47FFB5228F5E9000F781B8 /* KCInitialMessageData.m */, E7F480131C7397CE00390FDB /* KCJoiningSession.h */, - E7F480141C73980D00390FDB /* KCJoiningRequestSession.m */, + 0C2A041A2152EF3000FD4FAD /* KCJoiningRequestSession+Internal.h */, + E7F480141C73980D00390FDB /* KCJoiningRequestSecretSession.m */, + DC6063B121B09AB200069B82 /* KCJoiningRequestCircleSession.m */, + 0C2A04152152ED7F00FD4FAD /* KCJoiningAcceptSession+Internal.h */, E7F482AB1C7558F700390FDB /* KCJoiningAcceptSession.m */, E794BAD91C7598E400339A0F /* KCJoiningMessages.h */, E794BAFF1C7598F900339A0F /* KCJoiningMessages.m */, @@ -21428,6 +25231,8 @@ E7F4826F1C74FDD100390FDB /* KCJoiningSessionTest.m */, EB108F121E6CE48B003B0456 /* KCParing.plist */, EB413B7E1E663A8300592085 /* KCPairingTest.m */, + 0C5258BC21BB137800B32C96 /* FakeSOSControl.h */, + 0C5258B821BB05C100B32C96 /* FakeSOSControl.m */, ); name = Tests; sourceTree = ""; @@ -21435,15 +25240,55 @@ E7FCBE401314471B000DE34E /* Frameworks */ = { isa = PBXGroup; children = ( - 0C9FB40120D8729A00864612 /* CoreCDP.framework */, - DC63D70920B3933000D088AD /* libOpenScriptingUtil.tbd */, + 0C6C2B6C2258295D00C53C96 /* UIKitCore.framework */, + 0C6C2B682258211800C53C96 /* AppleAccount.framework */, + DC4A76A92212698B006F2D8F /* CloudServices.framework */, + EB74CC252207ECCB00F1BBAD /* Preferences.framework */, + EB7732DA21963BAD00FCF513 /* libz.1.tbd */, + EB80DE57219600CF005B10FA /* libz.dylib */, + 482FE56B2177C7AE0031C11E /* AuthKit.framework */, + D4FD4223217D7BE3002B7EE2 /* libarchive.2.tbd */, + D458C511214E20840043D982 /* XCTest.framework */, + D458C500214E1FAF0043D982 /* Foundation.framework */, + D458C4FE214E1F8E0043D982 /* UIKit.framework */, + 0C75AC642141F18D0073A2F9 /* KeychainCircle.framework */, + D4B68C5C211A7D98009FED69 /* libDER.a */, + EB490153211C0026001E6D6A /* UserManagement.framework */, + 472E184F20D9A20D00ECE7C9 /* libcoreauthd_client.a */, + 475EDD0720D9A031009D2409 /* LocalAuthenticationPrivateUI.framework */, + 475EDD0520D98CE2009D2409 /* LocalAuthentication.framework */, + 475EDD0320D98CD0009D2409 /* libctkclient.a */, + 475EDD0120D98C81009D2409 /* libaks_acl.a */, + 475EDCFF20D98C64009D2409 /* IOKit.framework */, + 475EDCFD20D98C53009D2409 /* libaks.a */, + 475EDCFB20D98C3C009D2409 /* libDER.a */, + 475EDCF920D98C0D009D2409 /* CryptoTokenKit.framework */, + 475EDCF720D98BF6009D2409 /* CoreCDP.framework */, + 475EDCF520D98BCF009D2409 /* libACM.a */, + 475EDCF320D98B61009D2409 /* libMobileGestalt.dylib */, + 475EDCEE20D98AC7009D2409 /* SharedWebCredentials.framework */, + 475EDCEC20D98AB7009D2409 /* Accounts.framework */, + 475EDCEA20D98AAF009D2409 /* WirelessDiagnostics.framework */, + 475EDCE820D98AA8009D2409 /* SystemConfiguration.framework */, + 475EDCE420D98A71009D2409 /* ProtocolBuffer.framework */, + 475EDCE220D98A65009D2409 /* libsqlite3.dylib */, + 475EDCE020D98A5B009D2409 /* CoreData.framework */, + 475EDCDE20D98A54009D2409 /* ApplePushService.framework */, + 475EDCDC20D98A3C009D2409 /* SecurityFoundation.framework */, + 475EDCDA20D98A28009D2409 /* CloudKit.framework */, + 475EDCD420D98934009D2409 /* Security.framework */, + EB067E8A20EC873D00B7D961 /* libcompression.tbd */, + EB89111020E3C15D00DE533F /* UserManagement.framework */, + BE53602C209BBF2F0027E25A /* libMobileGestalt.tbd */, + D4A7DD7320A26CF900F51F3F /* AuthKit.framework */, + AAD66304203362480073E17B /* libnetwork.tbd */, + 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */, + 3DD1FFA8201FC5C20086D049 /* libcoretls.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 */, @@ -21451,8 +25296,6 @@ EB49B2CE202DF111003F34A0 /* CoreFollowUp.framework */, D4119E72202BDF2B0048587B /* libz.tbd */, 472339611FD7155C00CB6A72 /* libprequelite.dylib */, - 3DD1FFA9201FC5C30086D049 /* libcoretls_cfhelpers.tbd */, - 3DD1FFA8201FC5C20086D049 /* libcoretls.tbd */, 47D1838B1FB3827700CFCD89 /* OCMock.framework */, 4727FBE81F9921D00003AE36 /* libACM.a */, 4727FBE61F9921890003AE36 /* ApplePushService.framework */, @@ -21569,32 +25412,6 @@ 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 = ( @@ -21646,6 +25463,9 @@ DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */, BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */, EBF9AE171F536D0300FECBF7 /* Version.xcconfig */, + DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */, + DCC1849220EEEC4400F3B26C /* security_framework.xcconfig */, + 725D438D212CAA3B007B49E4 /* xcconfig/swift_binary_shim.xcconfig */, ); name = xcconfig; sourceTree = ""; @@ -21681,32 +25501,73 @@ children = ( 72D1E5F3202FE43C003A38C5 /* secdmock_db_version_10_5.h */, EBE700FE204676E700E00A87 /* secdmock_db_version_11_1.h */, - EB49B2B0202D8780003F34A0 /* secdmockaks.m */, + EB49B2B0202D8780003F34A0 /* mockaksKeychain.m */, + EB1E069E211E17B70088F0B1 /* mockaksWatchDog.m */, + EB1E069C211E149A0088F0B1 /* mockaksxcbase.h */, + EB1E0695211E137E0088F0B1 /* mockaksxcbase.m */, EB6667BE204CD65E000B404F /* testPlistDER.m */, EB49B303202FB8DE003F34A0 /* mockaks.h */, EB49B2E4202DFE7F003F34A0 /* mockaks.m */, EB49B2B2202D8780003F34A0 /* Info.plist */, + DC311E782124B8EF002F5EAE /* aks_real_witness.h */, + DC311E792124B8EF002F5EAE /* aks_real_witness.c */, ); name = secdmockaks; path = tests/secdmockaks; sourceTree = ""; }; - EB80211C1D3D9044008540C4 /* Modules */ = { + EB74CC182207E48000F1BBAD /* KeychainSettings */ = { isa = PBXGroup; children = ( - EB8021411D3D90BB008540C4 /* Security.iOS.modulemap */, - EB8021421D3D90BB008540C4 /* Security.macOS.modulemap */, + EB74CC192207E48100F1BBAD /* Info.plist */, + EB74CC1D2207E4BA00F1BBAD /* KeychainSettings.h */, + EB74CC1E2207E4BA00F1BBAD /* KeychainSettings.m */, + EB74CC212207E4FA00F1BBAD /* KeychainSettings.plist */, + EB74CC2E2207FBE900F1BBAD /* KeychainSettingsOctagonPeers.plist */, + EBB02A56221FF362007241CB /* KeychainSettingsCKKSViews.plist */, ); - name = Modules; + path = KeychainSettings; sourceTree = ""; }; - EB81D0CB1FE5838B00FD7F16 /* MultiDeviceSimulator */ = { + EB7E90F62193F93B00B1FA21 /* C2Metric */ = { isa = PBXGroup; children = ( - EB05C4F21FE5E48B00D68712 /* MultiDeviceSimulatorTests */, - EB056E3F1FE5E390000A771E /* DeviceSimulator */, + EB7E91092193F97600B1FA21 /* SECC2MPCloudKitInfo.h */, + EB7E91042193F97400B1FA21 /* SECC2MPCloudKitInfo.m */, + EB7E91032193F97400B1FA21 /* SECC2MPCloudKitOperationGroupInfo.h */, + EB7E91062193F97500B1FA21 /* SECC2MPCloudKitOperationGroupInfo.m */, + EB7E910D2193F97800B1FA21 /* SECC2MPCloudKitOperationInfo.h */, + EB7E90FC2193F97100B1FA21 /* SECC2MPCloudKitOperationInfo.m */, + EB7E90FB2193F97000B1FA21 /* SECC2MPDeviceInfo.h */, + EB7E90F92193F97000B1FA21 /* SECC2MPDeviceInfo.m */, + EB7E910C2193F97700B1FA21 /* SECC2MPError.h */, + EB7E90FD2193F97100B1FA21 /* SECC2MPError.m */, + EB7E90FE2193F97200B1FA21 /* SECC2MPGenericEvent.h */, + EB7E91022193F97300B1FA21 /* SECC2MPGenericEvent.m */, + EB7E90F82193F96F00B1FA21 /* SECC2MPGenericEventMetric.h */, + EB7E90FF2193F97200B1FA21 /* SECC2MPGenericEventMetric.m */, + EB7E91002193F97200B1FA21 /* SECC2MPGenericEventMetricValue.h */, + EB7E910A2193F97600B1FA21 /* SECC2MPGenericEventMetricValue.m */, + EB7E91012193F97300B1FA21 /* SECC2MPInternalTestConfig.h */, + EB7E90FA2193F97000B1FA21 /* SECC2MPInternalTestConfig.m */, + EB7E90F72193F96F00B1FA21 /* SECC2MPMetric.h */, + EB7E91052193F97400B1FA21 /* SECC2MPMetric.m */, + EB7E910E2193F97800B1FA21 /* SECC2MPNetworkEvent.h */, + EB7E91072193F97500B1FA21 /* SECC2MPNetworkEvent.m */, + EB7E91082193F97600B1FA21 /* SECC2MPServerInfo.h */, + EB7E910B2193F97700B1FA21 /* SECC2MPServerInfo.m */, ); - path = MultiDeviceSimulator; + path = C2Metric; + sourceTree = ""; + }; + EB80211C1D3D9044008540C4 /* Modules */ = { + isa = PBXGroup; + children = ( + EB8021411D3D90BB008540C4 /* Security.iOS.modulemap */, + EB8021421D3D90BB008540C4 /* Security.macOS.modulemap */, + 617570BA22C2D19E00EFBA37 /* Security.macOS.private.modulemap */, + ); + name = Modules; sourceTree = ""; }; EB9C1D7C1BDFD0E100F89272 /* secbackupntest */ = { @@ -21721,6 +25582,7 @@ isa = PBXGroup; children = ( EB9C1DAD1BDFD49400F89272 /* Security.plist */, + EBDAA7E320EC46CF003EA6E5 /* SecurityLocalKeychain.plist */, EBE202752092913500B48020 /* SecurityInduceLowDisk.plist */, EB3A8DD71BEEC4D6001A89AA /* Security_edumode.plist */, EB2D549F1F02A25700E46890 /* SecAtomicFile */, @@ -21748,6 +25610,14 @@ name = secitemnotifications; sourceTree = ""; }; + EBB0314122223786007241CB /* Tests */ = { + isa = PBXGroup; + children = ( + EBB03155222237A7007241CB /* CKKSLaunchSequenceTests.m */, + ); + path = Tests; + sourceTree = ""; + }; EBC73F44209A0BB200AE3350 /* xcscripts */ = { isa = PBXGroup; children = ( @@ -21765,6 +25635,15 @@ name = secitemfunctionality; sourceTree = ""; }; + EBDAF14021C75FC800EAE89F /* SharedMocks */ = { + isa = PBXGroup; + children = ( + EBDAF15B21C75FF200EAE89F /* NSXPCConnectionMock.h */, + EBDAF15C21C75FF200EAE89F /* NSXPCConnectionMock.m */, + ); + path = SharedMocks; + sourceTree = ""; + }; EBF374731DC055590065D840 /* security-sysdiagnose */ = { isa = PBXGroup; children = ( @@ -21793,14 +25672,6 @@ name = authdtests; sourceTree = ""; }; - F93C49391AB8FF530047E01A /* ckcdiagnose */ = { - isa = PBXGroup; - children = ( - F93C493A1AB8FF530047E01A /* ckcdiagnose.sh */, - ); - path = ckcdiagnose; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -21849,16 +25720,15 @@ 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 */, + 4718AEB8205B39C40068EC3F /* CKKSAccountStateTracker.h in Headers */, 4718AEB9205B39C40068EC3F /* CKKSZoneStateEntry.h in Headers */, - 4718AEBA205B39C40068EC3F /* CKKSTLKShare.h in Headers */, + DC5A01E921BB428500D87AB9 /* CKKSTLKShare.h in Headers */, + 4718AEBA205B39C40068EC3F /* CKKSTLKShareRecord.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 */, @@ -21876,8 +25746,7 @@ 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 */, + 4718AED3205B39C40068EC3F /* OctagonAPSReceiver.h in Headers */, 4718AED4205B39C40068EC3F /* NSOperationCategories.h in Headers */, 4718AED5205B39C40068EC3F /* CKKSKey.h in Headers */, 4718AED6205B39C40068EC3F /* CKKSCurrentItemPointer.h in Headers */, @@ -21899,46 +25768,60 @@ 4C32C1260A4976BF002891BD /* SecTrust.h in Headers */, 4CF0484C0A5D988F00268236 /* SecItem.h in Headers */, 6CE3654F1FA100F10012F6AB /* SFAnalyticsDefines.h in Headers */, + D4707A292113EF68005BCFDA /* SecCmsMessage.h in Headers */, 4CF048800A5F016300268236 /* SecItemPriv.h in Headers */, + D4B68C66211A8186009FED69 /* trustd_spi.h in Headers */, 4C999BA60AB5F0BB0010451D /* NtlmGenerator.h in Headers */, + 5AE4BEEF1FA79456001B9DA4 /* SecProtocolObject.h in Headers */, 4C999BA80AB5F0BB0010451D /* ntlmBlobPriv.h in Headers */, EB5E3BCC2003C67A00F1631B /* SecSignpost.h in Headers */, - 09A3B9D81F8267BB00C5C324 /* SecKeyProxy.h in Headers */, + 4791B46C2118BD0A00977C3F /* SecXPCError.h in Headers */, + D4707A1121137719005BCFDA /* CMSDecoder.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 */, + DCA9D84121FFE62A00B27421 /* EscrowRequestXPCProtocol.h in Headers */, DC3C73541D837B1900F6A832 /* SOSCloudCircle.h in Headers */, 524492941AFD6D480043695A /* der_plist.h in Headers */, DC3C73531D837AF800F6A832 /* SOSPeerInfo.h in Headers */, + 5A061198229ED8F3006AF14A /* NSDate+SFAnalytics.h in Headers */, + D47079F321128C74005BCFDA /* SecCMS.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 */, + 5A2551F32229F41300512FAE /* SecExperimentInternal.h in Headers */, + D4B3B1CC2115150D00A43409 /* SecCmsDigestedData.h in Headers */, 476541651F339F6300413F65 /* SecdWatchdog.h in Headers */, + D47079FB211355C9005BCFDA /* CMSEncoder.h in Headers */, 4C7072D40AC9ED5A007CC205 /* SecKeyPriv.h in Headers */, + D43718C821168D7D00EA350A /* SecSMIME.h in Headers */, DCD7EE981F4F4DE9007D9804 /* SecBase64.h in Headers */, + 4791B4652118BBFF00977C3F /* OTControlProtocol.h in Headers */, 4C7073CA0ACB2BAD007CC205 /* SecRSAKey.h in Headers */, EB6928C51D9C9C6E00062A18 /* SecRecoveryKey.h in Headers */, 4C0B906E0ACCBD240077CD03 /* SecFramework.h in Headers */, + EBF252222155E910000204D6 /* OTJoiningConfiguration.h in Headers */, + EB9B283321C7755700173DC2 /* OTDefines.h in Headers */, 4C7391790B01745000C4CBFA /* vmdh.h in Headers */, 6CDB5FFB1FA78D2C00410924 /* SFAnalyticsMultiSampler.h in Headers */, 4C64E01C0B8FBC71009B306C /* SecIdentity.h in Headers */, 4C64E01D0B8FBC7E009B306C /* Security.h in Headers */, - 0C8BBF211FCB4F1800580909 /* OTControlProtocol.h in Headers */, E7676DB619411DF300498DD4 /* SecServerEncryptionSupport.h in Headers */, F964772C1E5832540019E4EB /* SecCodePriv.h in Headers */, 4C4296320BB0A68200491999 /* SecTrustSettings.h in Headers */, 4CBA0E880BB33C0000E72B55 /* SecPolicy.h in Headers */, + D4B3B1D52115195900A43409 /* SecCmsRecipientInfo.h in Headers */, + 3D909E372195042C00205F8C /* SecExperimentPriv.h in Headers */, 4C6416D50BB34F00001C83FD /* SecPolicyPriv.h in Headers */, 78F92F11195128D70023B54B /* SecECKeyPriv.h in Headers */, 4CD3BA621106FF4D00BE8B75 /* SecECKey.h in Headers */, 4C6416F10BB357D5001C83FD /* SecInternal.h in Headers */, + 5A6D1B9D20810EF40057CAC8 /* SecProtocolTypes.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 */, @@ -21946,25 +25829,26 @@ 4C2F81D50BF121D2003C4F77 /* SecRandom.h in Headers */, ACBAF6EE1E941AE00007BA2F /* transform_regressions.h in Headers */, 7940D4130C3ACF9000FDB5D8 /* SecDH.h in Headers */, - DCC5860320BF8A98005C7269 /* SecBase.h in Headers */, + 478014791FBF5D2000C4043D /* SecKeyProxy.h in Headers */, 790850F70CA88AE10083CC4D /* securityd_client.h in Headers */, 795CA9CE0D38435E00BAE6A2 /* p12pbegen.h in Headers */, + D4B3B1CF211516A000A43409 /* SecCmsEncryptedData.h in Headers */, 79EF5B730D3D6AFE009F5270 /* p12import.h in Headers */, 4723C9C21F152EB50082882F /* SFObjCType.h in Headers */, + 0C0582C620D9CA4800D7BD7A /* OTClique.h in Headers */, + DC0C343821FA7DEB00417D04 /* SecEscrowRequest.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 */, + DC372C8E22B4509100AB9F41 /* SecCoreAnalytics.h in Headers */, 4723C9CA1F152ECE0082882F /* SFSQLiteStatement.h in Headers */, - 5AFCF32920746BC20010D4B5 /* SecProtocolOptions.h in Headers */, + 5A6D1B9B20810EDD0057CAC8 /* 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 */, @@ -21972,60 +25856,68 @@ 791766DE0DD0162C00F3B974 /* SecCertificateRequest.h in Headers */, 4C7416040F1D71A2008E0E4D /* SecSCEP.h in Headers */, DC3C72E21D8374D600F6A832 /* SecureTransportPriv.h in Headers */, + 1F631C5422387F27005920D8 /* legacydevid.h in Headers */, 4AF7FFFD15AFB73800B9D400 /* SecOTR.h in Headers */, + 5A7E037B2227301D003DB3A0 /* SecProtocolInternal.h in Headers */, DC3C7AB21D838B6D00F6A832 /* SecureTransport.h in Headers */, 6CBF65391FA147E500A68667 /* SFAnalyticsActivityTracker.h in Headers */, 4AF7FFFE15AFB73800B9D400 /* SecOTRDHKey.h in Headers */, + D4B3B1DB21152AD200A43409 /* SecCmsSignerInfo.h in Headers */, DCFE9C8920EC1F3B00EB6BAC /* SOSControlHelper.h in Headers */, 4AF7FFFF15AFB73800B9D400 /* SecOTRErrors.h in Headers */, 6C73F48F2006B910003D5D63 /* SOSAnalytics.h in Headers */, DCD7EE9A1F4F5156007D9804 /* oidsocsp.h in Headers */, + D4B3B1D821151BBF00A43409 /* SecCmsSignedData.h in Headers */, BE2AD2B31FDA07EF00739F96 /* OTBottledPeerRecord.h in Headers */, 4AF7000115AFB73800B9D400 /* SecOTRMath.h in Headers */, 4AF7000315AFB73800B9D400 /* SecOTRPacketData.h in Headers */, + D4707A232113E74B005BCFDA /* SecCmsEncoder.h in Headers */, + D4B3B1D2211517BC00A43409 /* SecCmsEnvelopedData.h in Headers */, + D4707A0E211373DB005BCFDA /* CMSPrivate.h in Headers */, + EB74CC1F2207E4BA00F1BBAD /* KeychainSettings.h in Headers */, + D4707A2F2114C315005BCFDA /* SecCmsDigestContext.h in Headers */, DC3C7AB31D838BC300F6A832 /* CipherSuite.h in Headers */, 6C814A4C2050B4B600CB391B /* LocalKeychainAnalytics.h in Headers */, 4AF7000415AFB73800B9D400 /* SecOTRPackets.h in Headers */, 6C8CE6C11FA248DA0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */, + D4707A262113EBC1005BCFDA /* SecCmsDecoder.h in Headers */, DC3C7ABA1D838C9F00F6A832 /* sslTypes.h in Headers */, 6CE3654B1FA100D00012F6AB /* SFAnalytics.h in Headers */, 4AF7000515AFB73800B9D400 /* SecOTRSession.h in Headers */, + D4707A2C2114C1E5005BCFDA /* SecCmsContentInfo.h in Headers */, D487B9821DFA28DB000410A1 /* SecInternalReleasePriv.h in Headers */, 4AF7000615AFB73800B9D400 /* SecOTRSessionPriv.h in Headers */, EB69AB301BF4348000913AF1 /* SecEMCSPriv.h in Headers */, + DCA143341FE0802C00A40D59 /* OTControl.h in Headers */, D47F514C1C3B812500A7CEFE /* SecCFAllocator.h in Headers */, - BEB0B0DB1FFC45C2007E6A83 /* OTPrivateKey+SF.h in Headers */, + D46CD4C72267949C00E2C4D7 /* certExtensionTemplates.h in Headers */, + D46CD4C82267949C00E2C4D7 /* nameTemplates.h in Headers */, + D46CD4C92267949C00E2C4D7 /* X509Templates.h in Headers */, 8E02FA6B1107BE460043545E /* pbkdf2.h in Headers */, + AA7C71B62185429800EB314F /* SecProtocolTypesPriv.h in Headers */, 8ED6F6CA110904E300D2B368 /* SecPBKDF.h in Headers */, - 7901791812D51F7200CA4D44 /* SecCmsBase.h in Headers */, - D4FBBD631DD661AD004408F7 /* CMSDecoder.h in Headers */, - D4FBBD621DD661A7004408F7 /* CMSEncoder.h in Headers */, + 5F00F95B230614AC00B832E0 /* SecImportExportPriv.h in Headers */, 22A23B3A1E3AAC9800C41830 /* CodeSigning.h in Headers */, + 5A6D1B9520810EAD0057CAC8 /* SecProtocolMetadata.h in Headers */, + 5AF594021FA1051600A5C1EC /* SecProtocolPriv.h in Headers */, 22A23B3B1E3AAC9800C41830 /* CSCommon.h in Headers */, 22A23B3C1E3AAC9800C41830 /* SecCode.h in Headers */, + EBDAF15D21C75FF200EAE89F /* NSXPCConnectionMock.h in Headers */, 22A23B3D1E3AAC9800C41830 /* SecStaticCode.h in Headers */, - 724340BA1ED3FEC800F8F566 /* SecSMIME.h in Headers */, 22A23B3E1E3AAC9800C41830 /* SecRequirement.h in Headers */, DC9C95BE1F79DC5F000D19E5 /* CKKSControl.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 */, + AA5B12192164671000A6AB81 /* SecProtocolConfiguration.h in Headers */, + D4707A202113AC33005BCFDA /* SecCmsBase.h in Headers */, 47A05B161FDB5D9E00D0816E /* SFKeychainControl.h in Headers */, - 7901791912D51F7200CA4D44 /* SecCmsContentInfo.h in Headers */, - 7901791A12D51F7200CA4D44 /* SecCmsDecoder.h in Headers */, - 7901791B12D51F7200CA4D44 /* SecCmsDigestContext.h in Headers */, - 7901791C12D51F7200CA4D44 /* SecCmsEncoder.h in Headers */, - 0C8BBF201FCB4F1800580909 /* OTControl.h in Headers */, - 7901791D12D51F7200CA4D44 /* SecCmsEnvelopedData.h in Headers */, - 7901791E12D51F7200CA4D44 /* SecCmsMessage.h in Headers */, - 7901791F12D51F7200CA4D44 /* SecCmsRecipientInfo.h in Headers */, - 7901792012D51F7200CA4D44 /* SecCmsSignedData.h in Headers */, - 7901792112D51F7200CA4D44 /* SecCmsSignerInfo.h in Headers */, + 0C5258BD21BB137900B32C96 /* FakeSOSControl.h in Headers */, DC3C7AB71D838C5C00F6A832 /* secasn1t.h in Headers */, + 5A04BB1922986717001848A0 /* SecXPCHelper.h in Headers */, DC3C7AB41D838BEB00F6A832 /* SecAsn1Coder.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -22042,23 +25934,87 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - BEF88C911EB000BE00357577 /* TPVoucher.h in Headers */, - BEF88C8D1EB000BE00357577 /* TPSigningKey.h in Headers */, + 6C32D36420F2C23100ACAB2C /* TPPBPolicyRedaction.h in Headers */, + BEF88C8D1EB000BE00357577 /* TPKey.h in Headers */, + 6C32D36720F2C23D00ACAB2C /* TPPBPolicyIntroducersByCategory.h in Headers */, BEF88C7D1EB000BE00357577 /* TPHash.h in Headers */, BEF88C7C1EB000BE00357577 /* TPEncrypter.h in Headers */, BEF88C8B1EB000BE00357577 /* TPPolicyDocument.h in Headers */, - BEF88C8F1EB000BE00357577 /* TPUtils.h in Headers */, + DC2B9A5223147A3800D4C79D /* TPMachineID.h in Headers */, + BEC373CB20D822DA00DBDF5B /* TPPBDispositionEntry.h in Headers */, BEF88C7F1EB000BE00357577 /* TPModel.h in Headers */, - BEF88C791EB000BE00357577 /* TPCircle.h in Headers */, BE61F5AF1EB0060C00556CCF /* TrustedPeers.h in Headers */, BEF88C891EB000BE00357577 /* TPPolicy.h in Headers */, BEF88C871EB000BE00357577 /* TPPeerStableInfo.h in Headers */, BEF88C7B1EB000BE00357577 /* TPDecrypter.h in Headers */, + DCF458B4221F6A90007F5507 /* TPLog.h in Headers */, BEF88C771EB000BE00357577 /* TPCategoryRule.h in Headers */, + DC730E20224012770051DD48 /* TPPBDictionaryMatchingRuleFieldExists.h in Headers */, BEF88C8E1EB000BE00357577 /* TPTypes.h in Headers */, + DCD7DDA022B86A5500161396 /* TPPBDispositionDuplicateMachineID.h in Headers */, BEF88C811EB000BE00357577 /* TPPeer.h in Headers */, + BEC373B220D815F500DBDF5B /* TPPBUnknownMachineID.h in Headers */, + DC730E1322400D7B0051DD48 /* TPDictionaryMatchingRules.h in Headers */, + BEB49F30206E98D0008DA7F4 /* TPECPublicKeyFactory.h in Headers */, BEF88C831EB000BE00357577 /* TPPeerDynamicInfo.h in Headers */, + 6C32D36820F2C23D00ACAB2C /* TPPBPolicyModelToCategory.h in Headers */, + BEB49F34206E9A1A008DA7F4 /* SFKey+TPKey.h in Headers */, BEF88C851EB000BE00357577 /* TPPeerPermanentInfo.h in Headers */, + BEB0B06E1FE9E81D007E6A83 /* TPPBPeerDynamicInfo.h in Headers */, + 6C32D36620F2C23D00ACAB2C /* TPPBPolicyCategoriesByView.h in Headers */, + BEC373B320D815FB00DBDF5B /* TPPBPolicyProhibits.h in Headers */, + DC730E212240127D0051DD48 /* TPPBDictionaryMatchingRule.h in Headers */, + BEC373A420CF3B5D00DBDF5B /* TPPBDisposition.h in Headers */, + 1B4C444B223AE65500C6F97F /* TPPBPolicyKeyViewMapping.h in Headers */, + DCAD8F8C22C55D76007C3872 /* TPPBDispositionDisallowedMachineID.h in Headers */, + BEC373B420D8160100DBDF5B /* TPPBAncientEpoch.h in Headers */, + BEB0B06F1FE9E850007E6A83 /* TPPBPeerPermanentInfo.h in Headers */, + BECEC11220A508F600E97255 /* TPVoucher.h in Headers */, + BE70899D1F9AB03E001ACC20 /* TPPBVoucher.h in Headers */, + DC730E1F224012710051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.h in Headers */, + BEB0B0701FE9E8F6007E6A83 /* TPPBPeerStableInfo.h in Headers */, + 6C32D36520F2C23D00ACAB2C /* TPPBPolicyDocument.h in Headers */, + BEB0B0711FE9E936007E6A83 /* TPPBPolicySecret.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D42C839421159146008D3D83 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D43718AC2116839300EA350A /* SecSMIMEPriv.h in Headers */, + D43718B9211683D400EA350A /* tsaTemplates.h in Headers */, + D437187E2116831A00EA350A /* cmslocal.h in Headers */, + D43718A92116839300EA350A /* secoidt.h in Headers */, + D43718A02116836300EA350A /* secitem.h in Headers */, + D43718892116834400EA350A /* cmsreclist.h in Headers */, + D437189D2116836300EA350A /* plhash.h in Headers */, + D43718AB2116839300EA350A /* secoid.h in Headers */, + D437188D2116834400EA350A /* cmstpriv.h in Headers */, + D43718B6211683D400EA350A /* tsaSupportPriv.h in Headers */, + D437186F211682D800EA350A /* cert.h in Headers */, + D437189A2116836300EA350A /* cryptohi.h in Headers */, + D43718B7211683D400EA350A /* tsaSupport.h in Headers */, + D437188A2116834400EA350A /* cmspriv.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D44D1F622115893000E76E1A /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D4D1FDC921163F6A003538E2 /* SecCmsDecoder.h in Headers */, + D4D1FDCB21163F6A003538E2 /* SecCmsDigestedData.h in Headers */, + D4D1FDC821163F6A003538E2 /* SecCmsContentInfo.h in Headers */, + D4D1FDCA21163F6A003538E2 /* SecCmsDigestContext.h in Headers */, + D4D1FDD021163F6A003538E2 /* SecCmsRecipientInfo.h in Headers */, + D4D1FDC721163F6A003538E2 /* SecCmsBase.h in Headers */, + D4D1FDCE21163F6A003538E2 /* SecCmsEnvelopedData.h in Headers */, + D4D1FDCF21163F6A003538E2 /* SecCmsMessage.h in Headers */, + D4D1FDD121163F6A003538E2 /* SecCmsSignedData.h in Headers */, + D4D1FDCC21163F6A003538E2 /* SecCmsEncoder.h in Headers */, + D4D1FDD221163F6A003538E2 /* SecCmsSignerInfo.h in Headers */, + D4D1FDCD21163F6A003538E2 /* SecCmsEncryptedData.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -22070,6 +26026,16 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + D4D1FDD821165F8B003538E2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D4371861211671A500EA350A /* cms-01-basic.h in Headers */, + D4D1FDE4211660F4003538E2 /* cms-trust-settings-test.h in Headers */, + D4D1FDE021165FAE003538E2 /* cms_regressions.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DC0067951D87876F005AF8DB /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -22084,6 +26050,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + DC05037121409A4000A8EDB7 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DC05037A21409A4100A8EDB7 /* OCMockUmbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DC0BC5861D8B70E700070CB0 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -22122,10 +26096,8 @@ buildActionMask = 2147483647; files = ( DC0BC6901D8B755200070CB0 /* giantIntegers.h in Headers */, - DC0BC6541D8B755200070CB0 /* CipherFileDES.h in Headers */, DC0BC6621D8B755200070CB0 /* ckutilities.h in Headers */, DC0BC65E1D8B755200070CB0 /* ckSHA1.h in Headers */, - DC0BC6921D8B755200070CB0 /* giantPort_i486.h in Headers */, DC0BC6721D8B755200070CB0 /* ellipticMeasure.h in Headers */, DC0BC6711D8B755200070CB0 /* elliptic.h in Headers */, DC0BC66E1D8B755200070CB0 /* ECDSA_Profile.h in Headers */, @@ -22138,33 +26110,23 @@ DC0BC66D1D8B755200070CB0 /* curveParams.h in Headers */, DC0BC66A1D8B755200070CB0 /* curveParamData.h in Headers */, DC0BC67B1D8B755200070CB0 /* feeDebug.h in Headers */, - DC0BC6561D8B755200070CB0 /* CipherFileFEED.h in Headers */, - DC0BC65A1D8B755200070CB0 /* ckDES.h in Headers */, DC0BC6741D8B755200070CB0 /* ellipticProj.h in Headers */, DC0BC6521D8B755200070CB0 /* byteRep.h in Headers */, DC0BC6851D8B755200070CB0 /* feeFEEDExp.h in Headers */, - DC0BC6571D8B755200070CB0 /* CipherFileTypes.h in Headers */, DC0BC6691D8B755200070CB0 /* CryptKitDER.h in Headers */, DC0BC65C1D8B755200070CB0 /* ckMD5.h in Headers */, - DC0BC66F1D8B755200070CB0 /* ECDSA_Verify_Prefix.h in Headers */, - DC0BC6941D8B755200070CB0 /* giantPort_PPC.h in Headers */, DC0BC6861D8B755200070CB0 /* feeFunctions.h in Headers */, DC0BC68B1D8B755200070CB0 /* feePublicKeyPrivate.h in Headers */, DC0BC68A1D8B755200070CB0 /* feePublicKey.h in Headers */, - DC0BC66B1D8B755200070CB0 /* curveParamDataOld.h in Headers */, DC0BC68D1D8B755200070CB0 /* feeRandom.h in Headers */, DC0BC6761D8B755200070CB0 /* enc64.h in Headers */, - DC0BC6601D8B755200070CB0 /* ckSHA1_priv.h in Headers */, DC0BC6791D8B755200070CB0 /* falloc.h in Headers */, DC0BC6971D8B755200070CB0 /* giantPortCommon.h in Headers */, - DC0BC67A1D8B755200070CB0 /* feeCipherFile.h in Headers */, DC0BC6881D8B755200070CB0 /* feeHash.h in Headers */, - DC0BC67D1D8B755200070CB0 /* feeDES.h in Headers */, DC0BC6911D8B755200070CB0 /* giantPort_Generic.h in Headers */, DC0BC6671D8B755200070CB0 /* CryptKitAsn1.h in Headers */, DC0BC68E1D8B755200070CB0 /* feeTypes.h in Headers */, DC0BC6991D8B755200070CB0 /* HmacSha1Legacy.h in Headers */, - DC0BC6951D8B755200070CB0 /* giantPort_PPC_Gnu.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -22455,12 +26417,11 @@ DC0BCD831D8C6A1E00070CB0 /* SecCFWrappers.h in Headers */, DC0BCDB01D8C6A1F00070CB0 /* SecAppleAnchorPriv.h in Headers */, B61577EC1F201562004A3930 /* SecPaddingConfigurationsPriv.h in Headers */, - DC65E7C11D8CBB1500152EF0 /* readline.h in Headers */, EB4B6E261DC0683600AFC494 /* SecADWrapper.h in Headers */, + DC36895921235F2A003A3735 /* SecAKSWrappers.h in Headers */, DC0BCDAA1D8C6A1F00070CB0 /* SecXPCError.h in Headers */, 72CDF5131EC679A4002D233B /* sec_action.h in Headers */, DC0BCD8F1D8C6A1E00070CB0 /* debugging_test.h in Headers */, - DC0BCD781D8C6A1E00070CB0 /* SecAKSWrappers.h in Headers */, DC0BCDA71D8C6A1F00070CB0 /* SecDb.h in Headers */, DC0BCDA11D8C6A1F00070CB0 /* sqlutils.h in Headers */, DC963EC61D95F646008A153E /* der_plist.h in Headers */, @@ -22491,53 +26452,48 @@ DC1785231D7789AF00B50D50 /* AuthorizationPlugin.h in Headers */, DC17875F1D7790E500B50D50 /* AuthorizationPriv.h in Headers */, DC1785241D7789AF00B50D50 /* AuthorizationTags.h in Headers */, + EBF252252155E911000204D6 /* OTJoiningConfiguration.h in Headers */, EB5E3BCD2003C67B00F1631B /* SecSignpost.h in Headers */, DC1787601D7790E500B50D50 /* AuthorizationTagsPriv.h in Headers */, - DC1785901D778B9D00B50D50 /* CMSDecoder.h in Headers */, - DC1785911D778B9D00B50D50 /* CMSEncoder.h in Headers */, + D47079FA211355C5005BCFDA /* CMSEncoder.h in Headers */, + AA5B121C2164671000A6AB81 /* SecProtocolConfiguration.h in Headers */, EB10A3FC2035789B00E84270 /* OTConstants.h in Headers */, - DC1787591D7790B600B50D50 /* CMSPrivate.h in Headers */, DC1785881D778B8000B50D50 /* CSCommon.h in Headers */, - D46A6C09215336BC008ABF6A /* SecFramework.h in Headers */, + D4428B342122604300EB8448 /* SecFramework.h in Headers */, DC17874E1D7790A500B50D50 /* CSCommonPriv.h in Headers */, DC1785A51D778D0D00B50D50 /* CipherSuite.h in Headers */, + DC372C8F22B4509200AB9F41 /* SecCoreAnalytics.h in Headers */, + D4B3B1D62115195900A43409 /* SecCmsRecipientInfo.h in Headers */, DC1785871D778B8000B50D50 /* CodeSigning.h in Headers */, DC17854F1D778ACD00B50D50 /* SecACL.h in Headers */, DC17854E1D778ACD00B50D50 /* SecAccess.h in Headers */, DC1785921D778BE400B50D50 /* SecAccessControl.h in Headers */, + 5A2551F52229F41500512FAE /* SecExperimentInternal.h in Headers */, DC1787751D77916000B50D50 /* SecAccessControlPriv.h in Headers */, DC1787351D77903700B50D50 /* SecAccessPriv.h in Headers */, DC1785181D77895A00B50D50 /* SecAsn1Coder.h in Headers */, + 5AE4BEF01FA79456001B9DA4 /* SecProtocolObject.h in Headers */, DC1785191D77895A00B50D50 /* SecAsn1Templates.h in Headers */, DC17851A1D77895A00B50D50 /* SecAsn1Types.h in Headers */, DC17874F1D7790A500B50D50 /* SecAssessment.h in Headers */, DC1785931D778BEE00B50D50 /* SecBase.h in Headers */, DC2671071F3E8A0900816EED /* SecECKey.h in Headers */, DC17877C1D77919500B50D50 /* SecBasePriv.h in Headers */, - 0C8BBF231FCB4F1800580909 /* OTControlProtocol.h in Headers */, + 5F00F95C230614AD00B832E0 /* SecImportExportPriv.h in Headers */, DC1787741D77915500B50D50 /* SecBreadcrumb.h in Headers */, 6CB420AB2051FDE000FF2D44 /* LocalKeychainAnalytics.h in Headers */, DC1787761D77916600B50D50 /* SecCFAllocator.h in Headers */, - DC1787111D778FA900B50D50 /* SecCMS.h in Headers */, + DC0C343A21FA7DEB00417D04 /* SecEscrowRequest.h in Headers */, DC17859F1D778C8D00B50D50 /* SecCertificate.h in Headers */, DC1787361D77903700B50D50 /* SecCertificateBundle.h in Headers */, DC1785501D778ACD00B50D50 /* SecCertificateOIDs.h in Headers */, DC1787821D7791BE00B50D50 /* SecCertificatePriv.h in Headers */, + 5A6D1B9E20810EF40057CAC8 /* SecProtocolTypes.h in Headers */, DC1787831D7791C400B50D50 /* SecCertificateRequest.h in Headers */, - DC1787121D778FAA00B50D50 /* SecCmsBase.h in Headers */, - DC1787131D778FAA00B50D50 /* SecCmsContentInfo.h in Headers */, - DC1787141D778FAA00B50D50 /* SecCmsDecoder.h in Headers */, - DC1787151D778FAA00B50D50 /* SecCmsDigestContext.h in Headers */, - DC1787161D778FAA00B50D50 /* SecCmsDigestedData.h in Headers */, - DC1787171D778FAA00B50D50 /* SecCmsEncoder.h in Headers */, - DC1787181D778FAA00B50D50 /* SecCmsEncryptedData.h in Headers */, - DC1787191D778FAA00B50D50 /* SecCmsEnvelopedData.h in Headers */, - DC17871A1D778FAA00B50D50 /* SecCmsMessage.h in Headers */, - DC17871B1D778FAA00B50D50 /* SecCmsRecipientInfo.h in Headers */, + DCA1433C1FE0803200A40D59 /* OTControl.h in Headers */, DCFE9C8F20EC1F3C00EB6BAC /* SOSControlHelper.h in Headers */, - DC17871C1D778FAA00B50D50 /* SecCmsSignedData.h in Headers */, - DC17871D1D778FAA00B50D50 /* SecCmsSignerInfo.h in Headers */, DC1785891D778B8000B50D50 /* SecCode.h in Headers */, + 5A04BB1A22986717001848A0 /* SecXPCHelper.h in Headers */, DC1787511D7790A500B50D50 /* SecCodePriv.h in Headers */, DC1787521D7790A500B50D50 /* SecCodeSigner.h in Headers */, DC1785301D778A0100B50D50 /* SecCustomTransform.h in Headers */, @@ -22546,6 +26502,7 @@ DC1785311D778A0100B50D50 /* SecDecodeTransform.h in Headers */, 6CE365561FA101740012F6AB /* SFAnalyticsSQLiteStore.h in Headers */, DC1785321D778A0100B50D50 /* SecDigestTransform.h in Headers */, + 5A7E037C2227301E003DB3A0 /* SecProtocolInternal.h in Headers */, DC1785331D778A0100B50D50 /* SecEncodeTransform.h in Headers */, DC1785341D778A0100B50D50 /* SecEncryptTransform.h in Headers */, DC1787811D7791B200B50D50 /* SecEntitlements.h in Headers */, @@ -22555,50 +26512,57 @@ DC17877E1D7791A100B50D50 /* SecIdentityPriv.h in Headers */, DC1785511D778ACD00B50D50 /* SecIdentitySearch.h in Headers */, DC1787381D77903700B50D50 /* SecIdentitySearchPriv.h in Headers */, + 4791B46B2118BC0000977C3F /* OTControlProtocol.h in Headers */, + 5A6D1B9620810EAE0057CAC8 /* SecProtocolMetadata.h in Headers */, DC17859B1D778C7400B50D50 /* SecImportExport.h in Headers */, DC17859C1D778C7900B50D50 /* SecItem.h in Headers */, + 4780147F1FBF5D2100C4043D /* SecKeyProxy.h in Headers */, + D4707A1221137719005BCFDA /* CMSDecoder.h in Headers */, DC1787781D77917100B50D50 /* SecItemBackup.h in Headers */, DC17877F1D7791A800B50D50 /* SecItemPriv.h in Headers */, DC17859D1D778C8000B50D50 /* SecKey.h in Headers */, + EB9B283421C7755800173DC2 /* OTDefines.h in Headers */, 6CC952481FB4CB2C0051A823 /* SFAnalytics+Internal.h in Headers */, DC1787801D7791AD00B50D50 /* SecKeyPriv.h in Headers */, DC1785521D778ACD00B50D50 /* SecKeychain.h in Headers */, DC1785531D778ACD00B50D50 /* SecKeychainItem.h in Headers */, - 0C8BBF221FCB4F1800580909 /* OTControl.h in Headers */, DC1787391D77903700B50D50 /* SecKeychainItemExtendedAttributes.h in Headers */, DC17873A1D77903700B50D50 /* SecKeychainItemPriv.h in Headers */, DC17873B1D77903700B50D50 /* SecKeychainPriv.h in Headers */, DC1785541D778ACD00B50D50 /* SecKeychainSearch.h in Headers */, DC17873C1D77903700B50D50 /* SecKeychainSearchPriv.h in Headers */, DC1787261D778FDE00B50D50 /* SecManifest.h in Headers */, + DCA9D84221FFE62A00B27421 /* EscrowRequestXPCProtocol.h in Headers */, DC1786F91D778F2500B50D50 /* SecNullTransform.h in Headers */, DC17873D1D77903700B50D50 /* SecPassword.h in Headers */, - 5AFCF32F20746DA70010D4B5 /* SecProtocolObject.h in Headers */, DC1787791D77917700B50D50 /* SecPasswordGenerate.h in Headers */, + F6EEF77521675EF000FB7F79 /* AuthorizationTrampolinePriv.h in Headers */, DC1785941D778BF400B50D50 /* SecPolicy.h in Headers */, + D43718C921168D7D00EA350A /* SecSMIME.h in Headers */, DC17877D1D77919B00B50D50 /* SecPolicyPriv.h in Headers */, B61577EA1F201542004A3930 /* SecPaddingConfigurationsPriv.h in Headers */, + D47079F421128CA0005BCFDA /* SecCMS.h in Headers */, + D4B3B1D3211517BC00A43409 /* SecCmsEnvelopedData.h in Headers */, 222F239F1DAC15C5007ACB90 /* SecTaskPriv.h in Headers */, DC1785551D778ACD00B50D50 /* SecPolicySearch.h in Headers */, DC1785951D778BFA00B50D50 /* SecRandom.h in Headers */, + D4B3B1CD2115150D00A43409 /* SecCmsDigestedData.h in Headers */, DC17873E1D77903700B50D50 /* SecRandomP.h in Headers */, 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 */, DC17877A1D77917D00B50D50 /* SecServerEncryptionSupport.h in Headers */, 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 */, DC1785381D778A0100B50D50 /* SecTransformReadTransform.h in Headers */, DC1786F41D778EF800B50D50 /* SecTranslocate.h in Headers */, + D43718BC211683F100EA350A /* tsaSupport.h in Headers */, DC1785A01D778C9400B50D50 /* SecTrust.h in Headers */, DC1787841D7791C900B50D50 /* SecTrustPriv.h in Headers */, 6CDB5FFC1FA78D2D00410924 /* SFAnalyticsMultiSampler.h in Headers */, @@ -22617,55 +26581,66 @@ DC926F081F33F7D30012A315 /* SecCodeHost.h in Headers */, DC17876A1D77911D00B50D50 /* asn1Templates.h in Headers */, DC17876B1D77911D00B50D50 /* certExtensionTemplates.h in Headers */, + D4707A2D2114C1E8005BCFDA /* SecCmsContentInfo.h in Headers */, DC1785971D778C0800B50D50 /* certextensions.h in Headers */, + 4791B46D2118BD0B00977C3F /* SecXPCError.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 */, + D4707A272113EBC1005BCFDA /* SecCmsDecoder.h in Headers */, + D4707A212113AC34005BCFDA /* SecCmsBase.h in Headers */, 6CBF65401FA1480C00A68667 /* SFAnalyticsActivityTracker.h in Headers */, + 3D909E382195042C00205F8C /* SecExperimentPriv.h in Headers */, 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 */, + 5AF594031FA1051600A5C1EC /* SecProtocolPriv.h in Headers */, DC337B1F1EA04E2100B3A1F0 /* SecBase64.h in Headers */, + D4707A242113E74B005BCFDA /* SecCmsEncoder.h in Headers */, DC1785731D778B4A00B50D50 /* cssmerr.h in Headers */, DC1785741D778B4A00B50D50 /* cssmkrapi.h in Headers */, DC1785751D778B4A00B50D50 /* cssmkrspi.h in Headers */, DC1785761D778B4A00B50D50 /* cssmspi.h in Headers */, DC1785771D778B4A00B50D50 /* cssmtpi.h in Headers */, DC1785781D778B4A00B50D50 /* cssmtype.h in Headers */, - 5AFCF32A20746BC30010D4B5 /* SecProtocolOptions.h in Headers */, + 5A6D1B9C20810EDE0057CAC8 /* SecProtocolOptions.h in Headers */, DC17877B1D77918C00B50D50 /* der_plist.h in Headers */, DC1785791D778B4A00B50D50 /* eisl.h in Headers */, DC17857A1D778B4A00B50D50 /* emmspi.h in Headers */, + D4707A2A2113EF68005BCFDA /* SecCmsMessage.h in Headers */, 6C8CE6C21FA248DB0032ADF0 /* SFAnalyticsActivityTracker+Internal.h in Headers */, + D4B3B1DC21152AD300A43409 /* SecCmsSignerInfo.h in Headers */, DC17857B1D778B4A00B50D50 /* emmtype.h in Headers */, DC17876D1D77911D00B50D50 /* keyTemplates.h in Headers */, DC17853D1D778A3100B50D50 /* mds.h in Headers */, DC17853C1D778A3100B50D50 /* mds_schema.h in Headers */, + D4707A0F211373DE005BCFDA /* CMSPrivate.h in Headers */, DC1787231D778FC900B50D50 /* mdspriv.h in Headers */, DC2671001F3E766E00816EED /* SecOTRSession.h in Headers */, DC17876E1D77911D00B50D50 /* nameTemplates.h in Headers */, + 0C0582CC20D9CA4900D7BD7A /* OTClique.h in Headers */, DC17876F1D77911D00B50D50 /* ocspTemplates.h in Headers */, DC1785161D77895A00B50D50 /* oidsalg.h in Headers */, DC1785171D77895A00B50D50 /* oidsattr.h in Headers */, DCCBFA391DBAE445001DD54D /* SecInternal.h in Headers */, DC17857C1D778B4A00B50D50 /* oidsbase.h in Headers */, DC17857D1D778B4A00B50D50 /* oidscert.h in Headers */, + D4B3B1D921151BBF00A43409 /* SecCmsSignedData.h in Headers */, DC17857E1D778B4A00B50D50 /* oidscrl.h in Headers */, DC1787701D77911D00B50D50 /* osKeyTemplates.h in Headers */, + 5A061199229ED8F4006AF14A /* NSDate+SFAnalytics.h in Headers */, + D4707A302114C316005BCFDA /* SecCmsDigestContext.h in Headers */, DC2C5F511F0D935300FEBDA7 /* CKKSControlProtocol.h in Headers */, + AA7C71B72185429900EB314F /* SecProtocolTypesPriv.h in Headers */, DC1787711D77911D00B50D50 /* secasn1t.h in Headers */, DC1786FC1D778F3D00B50D50 /* sslTypes.h in Headers */, - DC17871F1D778FAA00B50D50 /* tsaSupport.h in Headers */, DC17857F1D778B4A00B50D50 /* x509defs.h in Headers */, DCB3323B1F4681AE00178C30 /* SecOTR.h in Headers */, 4723C9CB1F152ECF0082882F /* SFSQLiteStatement.h in Headers */, @@ -22677,77 +26652,25 @@ DC9C95BD1F79DC5A000D19E5 /* CKKSControl.h in Headers */, DC3C73561D837B9B00F6A832 /* SOSPeerInfoPriv.h in Headers */, EB6928C61D9C9C6F00062A18 /* SecRecoveryKey.h in Headers */, + D4B3B1D0211516A100A43409 /* SecCmsEncryptedData.h in Headers */, 4723C9C71F152EC10082882F /* SFSQLite.h in Headers */, 47A05B171FDB5D9F00D0816E /* SFKeychainControl.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC222C641E034D1F00B09171 /* Headers */ = { + DC311E6F2124B8A8002F5EAE /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 47922D431FAA7C260008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */, - DCFE1C351F17ECE5007640C8 /* CKKSCondition.h in Headers */, - 6C3446461E25346C00F9522B /* CKKSRateLimiter.h in Headers */, - DC2C5F5E1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */, - DC5BB4FF1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */, - DC222C651E034D1F00B09171 /* SOSChangeTracker.h in Headers */, - 47922D551FAA7E070008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */, - 0C770EC21FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */, - DC14478B1F5764C600236DB4 /* CKKSResultOperation.h in Headers */, - DCFE1C521F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */, - DCBDB3BC1E57CA7A00B61300 /* CKKSViewManager.h in Headers */, - DC762A9F1E57A86A00B03A2C /* CKKSRecordHolder.h in Headers */, - DC1DA65F1E4554620094CE7F /* CKKSScanLocalItemsOperation.h in Headers */, - DC222C661E034D1F00B09171 /* SOSEngine.h in Headers */, - 0C8BBF1E1FCB4F0400580909 /* OTControl.h in Headers */, - DCB5D93C1E4A9A3400BE22AB /* CKKSSynchronizeOperation.h in Headers */, - 479108B81EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */, - DC222C671E034D1F00B09171 /* SecDbKeychainItem.h in Headers */, - 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 */, - BEE4B1931FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */, - DCFB12C61E95A4C000510F5F /* CKKSCKAccountStateTracker.h in Headers */, - DC222C6B1E034D1F00B09171 /* SecItemDataSource.h in Headers */, - DC7341F41F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */, - DC18F7701E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */, - DC222C6C1E034D1F00B09171 /* CKKSIncomingQueueEntry.h in Headers */, - 47922D471FAA7C350008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */, - DC9082C71EA027DC00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */, - DCA4D2161E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h in Headers */, - BEE4B1991FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */, - DC222C6D1E034D1F00B09171 /* SecItemDb.h in Headers */, - DC222C6E1E034D1F00B09171 /* SecItemSchema.h in Headers */, - DCAD9B451F8D939C00C5E2AE /* CKKSFixups.h in Headers */, - DC9C95B51F79CFD1000D19E5 /* CKKSControl.h in Headers */, - DC222C6F1E034D1F00B09171 /* SecKeybagSupport.h in Headers */, - DC3D748D1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h in Headers */, - DC222C701E034D1F00B09171 /* iCloudTrace.h in Headers */, - 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 */, - 0C8BBF251FCB4FE800580909 /* OTManager.h in Headers */, - DCBF2F861F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */, - DCE278E91ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h in Headers */, - 0C8BBF1F1FCB4F0400580909 /* OTControlProtocol.h in Headers */, - DCD662F61E329B6800188186 /* CKKSNewTLKOperation.h in Headers */, - DC1447971F5766D200236DB4 /* NSOperationCategories.h in Headers */, - DC4DB1511E24692100CD6769 /* CKKSKey.h in Headers */, - DCE278DE1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */, - DA6AA1681FE88AFB004565B0 /* CKKSControlServer.h in Headers */, - DC222C731E034D1F00B09171 /* CKKSItem.h in Headers */, - 4733377A1FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */, - 47922D4B1FAA7C440008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */, - DC7A17EE1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.h in Headers */, + DC311E7A2124B8EF002F5EAE /* aks_real_witness.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC36895A21235F42003A3735 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DC36896321235FA2003A3735 /* mockaks.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -22755,47 +26678,78 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + DC0FA6B02291F63F00FE01C4 /* OctagonPendingFlag.h in Headers */, 47922D421FAA7C240008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.h in Headers */, DCFE1C341F17ECE5007640C8 /* CKKSCondition.h in Headers */, + DC047081218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.h in Headers */, DC1DA65E1E4554620094CE7F /* CKKSScanLocalItemsOperation.h in Headers */, DC2C5F5D1F0EB97E00FEBDA7 /* CKKSNotifier.h in Headers */, DCCD88E81E42622200F5AA71 /* CKKSGroupOperation.h in Headers */, 6CC1859E1E24E8EB009657D8 /* CKKSRateLimiter.h in Headers */, 47922D541FAA7E060008F7E0 /* SecDbKeychainSerializedItemV7.h in Headers */, + DCD33D93220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.h in Headers */, + DCC54181225C05180095D926 /* OTUploadNewCKKSTLKsOperation.h in Headers */, 0C770EBC1FCF7C9800B5F0E2 /* OTCloudStore.h in Headers */, DC14478A1F5764C600236DB4 /* CKKSResultOperation.h in Headers */, DCFE1C511F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.h in Headers */, DCBDB3BB1E57CA7A00B61300 /* CKKSViewManager.h in Headers */, + DC5A01E821BB428500D87AB9 /* CKKSTLKShare.h in Headers */, + DC45D43D22EB619D00CEB6B7 /* OctagonStateMachineObservers.h in Headers */, + 0C38AA98212B2D2300C90A1D /* OTJoinWithVoucherOperation.h in Headers */, + DCFC91AF21F16E0B00E674DD /* OctagonStateMachine.h in Headers */, DC762A9E1E57A86A00B03A2C /* CKKSRecordHolder.h in Headers */, + DC5681AA224DA05F008F8DEB /* OctagonFlags.h in Headers */, + DCC67E0E20DD7E0A00A70A31 /* OTStates.h in Headers */, DC5BB4FE1E0C98320010F836 /* CKKSOutgoingQueueOperation.h in Headers */, + DC93F02922387A010072720A /* OTSOSUpdatePreapprovalsOperation.h in Headers */, DCB5D93B1E4A9A3400BE22AB /* CKKSSynchronizeOperation.h in Headers */, - 0C8BBF1C1FCB4F0300580909 /* OTControl.h in Headers */, DC52E7E81D80BE8700B0A59C /* SOSChangeTracker.h in Headers */, + DCAB17D12200D26900E1DFCF /* SecEscrowPendingRecord.h in Headers */, 479108B71EE879F9008CEFA0 /* CKKSAnalytics.h in Headers */, DC52E7E51D80BE7400B0A59C /* SOSEngine.h in Headers */, DC52E7E41D80BE6E00B0A59C /* SecDbKeychainItem.h in Headers */, + DC221BAB2267E2A60068DBCF /* OTUpdateTPHOperation.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 */, + DCC67E2D20DDC07900A70A31 /* OTPrepareOperation.h in Headers */, + DCAB17D52200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.h in Headers */, + DC3AF52C2229E6C0006577E8 /* CKKSListenerCollection.h in Headers */, + DCBFF832222611A200C5C044 /* OTFetchCKKSKeysOperation.h in Headers */, + 0C38AA92212B2D1900C90A1D /* OTEpochOperation.h in Headers */, + DC7250372296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.h in Headers */, + DCA9BC02221B721E00B4EB26 /* CKKSCloudKitClassDependencies.h in Headers */, + DCF94A7B222D9F2400C01744 /* OctagonCKKSPeerAdapter.h in Headers */, DCFE1C271F17E455007640C8 /* CKKSDeviceStateEntry.h in Headers */, - BEE4B1921FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.h in Headers */, - DCFB12C51E95A4C000510F5F /* CKKSCKAccountStateTracker.h in Headers */, + DCFB12C51E95A4C000510F5F /* CKKSAccountStateTracker.h in Headers */, DC378B381DEFADB500A3DAFA /* CKKSZoneStateEntry.h in Headers */, - DC7341F31F8447AB00AB9BDF /* CKKSTLKShare.h in Headers */, + DC7341F31F8447AB00AB9BDF /* CKKSTLKShareRecord.h in Headers */, + DC8757F4218D2003000E65F1 /* OTRemovePeersOperation.h in Headers */, DC52E7E71D80BE8100B0A59C /* SecItemDataSource.h in Headers */, DC18F76F1E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.h in Headers */, + DC9C06692149DFE400C6F7B8 /* OTAuthKitAdapter.h in Headers */, 47922D461FAA7C340008F7E0 /* SecDbKeychainSerializedMetadata.h in Headers */, DC9082C61EA027DB00D0C1C5 /* CKKSZoneChangeFetcher.h in Headers */, + DC614C5122A9BDB500E16ADA /* CKKSZoneModifier.h in Headers */, DCA4D2151E5684220056214F /* CKKSReencryptOutgoingItemsOperation.h in Headers */, - BEE4B1981FFDAFE600777D39 /* SFPublicKey+SPKI.h in Headers */, + 0C38AA96212B2D1E00C90A1D /* OTClientVoucherOperation.h in Headers */, DC378B3C1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.h in Headers */, + DC5F65AE2225C22C0051E9FA /* CKKSProvideKeySetOperation.h in Headers */, + DCB946AF22FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.h in Headers */, + DCFF82742162876400D54B02 /* OTResetOperation.h in Headers */, DC52E7E61D80BE7B00B0A59C /* SecItemDb.h in Headers */, + DCF12673218A757A000124C6 /* OTLeaveCliqueOperation.h in Headers */, DCAD9B441F8D939C00C5E2AE /* CKKSFixups.h in Headers */, DC9C95B41F79CFD1000D19E5 /* CKKSControl.h in Headers */, DC52E7EA1D80BE9500B0A59C /* SecItemSchema.h in Headers */, + DC7F79BA22EA5C73001FB69A /* OTLocalCKKSResetOperation.h in Headers */, + DC047087218BCEF20078BDAA /* OTOperationDependencies.h in Headers */, + DC19484C21812EC5007C2260 /* OTDeviceInformationAdapter.h in Headers */, + DCA9D84D21FFF04700B27421 /* EscrowRequestServer.h in Headers */, DC3D748C1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.h in Headers */, + DC6DE899213076C000C6B56D /* OTSOSUpgradeOperation.h in Headers */, DC52E7E91D80BE8D00B0A59C /* SecKeybagSupport.h in Headers */, DCD662F51E329B6800188186 /* CKKSNewTLKOperation.h in Headers */, DC52E7EB1D80BE9B00B0A59C /* iCloudTrace.h in Headers */, @@ -22803,16 +26757,20 @@ 47FF17261FD60ACA00875565 /* SFKeychainServer.h in Headers */, DC6D2C931DD2836500BE372D /* CKKSOutgoingQueueEntry.h in Headers */, DC15F7661E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.h in Headers */, + DCD33D8E220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.h in Headers */, DCD6C4B21EC5302500414FEE /* CKKSNearFutureScheduler.h in Headers */, - 0C8BBF241FCB4FE700580909 /* OTManager.h in Headers */, + 1B5EAADC2252ABCD008D27E7 /* OTFetchViewsOperation.h in Headers */, DCBF2F851F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.h in Headers */, DCE278E81ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.h in Headers */, - 0C8BBF1D1FCB4F0300580909 /* OTControlProtocol.h in Headers */, - DCEA5D851E2F14810089CF55 /* CKKSAPSReceiver.h in Headers */, + DCEA5D851E2F14810089CF55 /* OctagonAPSReceiver.h in Headers */, DC1447961F5766D200236DB4 /* NSOperationCategories.h in Headers */, DC4DB1501E24692100CD6769 /* CKKSKey.h in Headers */, DCE278DD1ED789EF0083B485 /* CKKSCurrentItemPointer.h in Headers */, + DCF46C2E214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.h in Headers */, + DCE772662290712F005862B4 /* OctagonCheckTrustStateOperation.h in Headers */, DA6AA1671FE88AFB004565B0 /* CKKSControlServer.h in Headers */, + DCD33D80220B9DC8000A390B /* OctagonStateMachineHelpers.h in Headers */, + DC5060EB20E2D88300925005 /* OTCuttlefishContext.h in Headers */, DCEA5D551E2826DB0089CF55 /* CKKSSIV.h in Headers */, 473337791FDAFBCC00E19F30 /* SFKeychainControlManager.h in Headers */, 47922D4A1FAA7C430008F7E0 /* SecDbKeychainSerializedSecretData.h in Headers */, @@ -22834,14 +26792,18 @@ DC3C73581D837BDC00F6A832 /* SOSCloudCircleInternal.h in Headers */, DCD8A1DC1E09F5E500E4FA0A /* SOSAccount.h in Headers */, DCD8A1E21E09F78A00E4FA0A /* SOSTransportCircle.h in Headers */, + DC59245120E46F840073D284 /* SOSRecoveryKeyBag.h in Headers */, DC52E91D1D80C44400B0A59C /* SOSCoder.h in Headers */, + DC2FA72B20E57C1000DB7518 /* SOSAccountTrust.h in Headers */, DC52E92B1D80C4A800B0A59C /* SOSConcordanceTrust.h in Headers */, DC52E9331D80C4E500B0A59C /* SOSDataSource.h in Headers */, DC52E9061D80C3AD00B0A59C /* SOSDigestVector.h in Headers */, DC52E9281D80C49300B0A59C /* SOSManifest.h in Headers */, DC52E90B1D80C3D400B0A59C /* SOSMessage.h in Headers */, DC52E9381D80C50800B0A59C /* SOSPeer.h in Headers */, + DC59244B20E46EA20073D284 /* SOSRingTypes.h in Headers */, DC52E91C1D80C43F00B0A59C /* SOSPeerCoder.h in Headers */, + 480C03DC2145A84F0034570E /* SOSTrustedDeviceAttributes.h in Headers */, DC52E9161D80C41A00B0A59C /* SOSPeerInfoInternal.h in Headers */, DC3C735A1D837C0000F6A832 /* SOSPeerInfoPriv.h in Headers */, DC52E91A1D80C43500B0A59C /* SOSRing.h in Headers */, @@ -22849,31 +26811,18 @@ CD198F971DE27B9E00F6FB83 /* SOSAccountPriv.h in Headers */, DC52E9231D80C47100B0A59C /* SOSTransportCircleKVS.h in Headers */, DC52E92C1D80C4AF00B0A59C /* SOSTransportKeyParameter.h in Headers */, + DC59245320E46FB10073D284 /* SOSRingBackup.h in Headers */, + DC59245720E470390073D284 /* SOSRingConcordanceTrust.h in Headers */, DC52E9241D80C47900B0A59C /* SOSTransportMessage.h in Headers */, + DC59244E20E46F200073D284 /* SOSTransport.h in Headers */, DC52E9321D80C4DF00B0A59C /* SOSTransportMessageKVS.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EA481D80CB7000B0A59C /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F9C8AFCD223740C800E7D6AE /* requirement.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DC52EBD11D80CEF100B0A59C /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; DC52EC301D80CFB200B0A59C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - DCB332381F46804600178C30 /* SOSSysdiagnose.h in Headers */, DCE5DC101EA802DA006308A6 /* secToolFileIO.h in Headers */, DCE5DC111EA80348006308A6 /* accountCirclesViewsPrint.h in Headers */, ); @@ -22920,6 +26869,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 0C78827520132074002B7475 /* SFSignInAnalytics.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -22929,7 +26879,6 @@ 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; }; @@ -22947,6 +26896,7 @@ files = ( DC5ABDF01D832E8300CF422C /* srCdsaUtils.h in Headers */, DC5ABDF11D832E8300CF422C /* createFVMaster.h in Headers */, + F9F77E99223C2F9A00E5CBF6 /* requirement.h in Headers */, DC5ABDF21D832E8300CF422C /* mds_install.h in Headers */, DC5ABDF31D832E8300CF422C /* cmsutil.h in Headers */, DC5ABDF41D832E8300CF422C /* db_commands.h in Headers */, @@ -22994,10 +26944,12 @@ DC5AC1091D83555A00CF422C /* server.h in Headers */, DC5AC10A1D83555A00CF422C /* session.h in Headers */, DC5AC10B1D83555A00CF422C /* structure.h in Headers */, + DC0BD4F121BB05F2006B9154 /* CKKSKeychainBackedKey.h in Headers */, DC5AC10C1D83555A00CF422C /* dbcrypto.h in Headers */, DC5AC10D1D83555A00CF422C /* localdatabase.h in Headers */, DC5AC10E1D83555A00CF422C /* localkey.h in Headers */, DC5AC10F1D83555A00CF422C /* kcdatabase.h in Headers */, + 1BC6F79C21C9955F005ED67A /* util.h in Headers */, DC5AC1101D83555A00CF422C /* kckey.h in Headers */, DC5AC1111D83555A00CF422C /* tempdatabase.h in Headers */, DC5AC1121D83555A00CF422C /* tokendatabase.h in Headers */, @@ -23016,7 +26968,6 @@ DC5AC11F1D83555A00CF422C /* credential.h in Headers */, DC5AC1201D83555A00CF422C /* clientid.h in Headers */, DC5AC1211D83555A00CF422C /* codesigdb.h in Headers */, - DC5AC1221D83555A00CF422C /* csproxy.h in Headers */, DC5AC1231D83555A00CF422C /* agentclient.h in Headers */, DC5AC1241D83555A00CF422C /* agentquery.h in Headers */, DC5AC1251D83555A00CF422C /* auditevents.h in Headers */, @@ -23049,52 +27000,10 @@ DC6A82A31D87762900418608 /* ucsp_types.h in Headers */, DC6A82A21D87762400418608 /* ucsp.h in Headers */, DC6A82A11D87761F00418608 /* ucspNotify.h in Headers */, - DC6A82A01D87761700418608 /* cshosting.h in Headers */, DC9036B31D9DFED600B6C234 /* ss_types.defs in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC71D9A01D95BA6C0065FB93 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - DC71D9A11D95BA6C0065FB93 /* SecAsn1Coder.h in Headers */, - DC71D9A21D95BA6C0065FB93 /* SecAsn1Templates.h in Headers */, - DC71D9A31D95BA6C0065FB93 /* SecAsn1Types.h in Headers */, - DC71D9A41D95BA6C0065FB93 /* SecNssCoder.h in Headers */, - DC71D9A51D95BA6C0065FB93 /* X509Templates.h in Headers */, - DC71D9A61D95BA6C0065FB93 /* oidsbase.h in Headers */, - DC71D9A71D95BA6C0065FB93 /* certExtensionTemplates.h in Headers */, - DC71D9A81D95BA6C0065FB93 /* csrTemplates.h in Headers */, - DC71D9A91D95BA6C0065FB93 /* keyTemplates.h in Headers */, - DC71D9AA1D95BA6C0065FB93 /* nameTemplates.h in Headers */, - DC71D9AB1D95BA6C0065FB93 /* nssUtils.h in Headers */, - DC71D9AC1D95BA6C0065FB93 /* ocspTemplates.h in Headers */, - DC71D9AD1D95BA6C0065FB93 /* oidsalg.h in Headers */, - DC71D9AE1D95BA6C0065FB93 /* oidsattr.h in Headers */, - DC71D9AF1D95BA6C0065FB93 /* oidsocsp.h in Headers */, - DC71D9B01D95BA6C0065FB93 /* osKeyTemplates.h in Headers */, - DC71D9B11D95BA6C0065FB93 /* pkcs12Templates.h in Headers */, - DC71D9B21D95BA6C0065FB93 /* pkcs7Templates.h in Headers */, - DC71D9B31D95BA6C0065FB93 /* plarena.h in Headers */, - DC71D9B41D95BA6C0065FB93 /* plarenas.h in Headers */, - DC71D9B51D95BA6C0065FB93 /* plstr.h in Headers */, - DC71D9B61D95BA6C0065FB93 /* prbit.h in Headers */, - DC71D9B71D95BA6C0065FB93 /* prcpucfg.h in Headers */, - DC71D9B81D95BA6C0065FB93 /* prerr.h in Headers */, - DC71D9B91D95BA6C0065FB93 /* prerror.h in Headers */, - DC71D9BA1D95BA6C0065FB93 /* prlog.h in Headers */, - DC71D9BB1D95BA6C0065FB93 /* prmem.h in Headers */, - DC71D9BC1D95BA6C0065FB93 /* protypes.h in Headers */, - DC71D9BD1D95BA6C0065FB93 /* prtypes.h in Headers */, - DC71D9BE1D95BA6C0065FB93 /* secasn1.h in Headers */, - DC71D9BF1D95BA6C0065FB93 /* secasn1t.h in Headers */, - DC71D9C01D95BA6C0065FB93 /* seccomon.h in Headers */, - DC71D9C11D95BA6C0065FB93 /* secerr.h in Headers */, - DC71D9C21D95BA6C0065FB93 /* secport.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; DC8834021D8A218F00CE0ACA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -23106,6 +27015,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + F6EEF76F21675E8000FB7F79 /* AuthorizationTrampolinePriv.h in Headers */, DC0BC57D1D8B701B00070CB0 /* Authorization.h in Headers */, DC0BC57F1D8B703100070CB0 /* AuthorizationPlugin.h in Headers */, DC0BC5801D8B703C00070CB0 /* AuthorizationPriv.h in Headers */, @@ -23175,7 +27085,6 @@ DCB342091D8A2BAD0054D16E /* cssmdata.h in Headers */, DCB342071D8A2BAD0054D16E /* cssmcred.h in Headers */, DCB3422F1D8A2BAD0054D16E /* walkers.h in Headers */, - DCB3422D1D8A2BAD0054D16E /* uniformrandom.h in Headers */, DCB342051D8A2BAD0054D16E /* cssmcert.h in Headers */, DCB3421B1D8A2BAD0054D16E /* cssmtrust.h in Headers */, DCB341FE1D8A2BAD0054D16E /* context.h in Headers */, @@ -23401,7 +27310,6 @@ DCD068191D8CDF7E007602F1 /* SecCodePriv.h in Headers */, DCD0690A1D8CDFFE007602F1 /* InputBuffer.hpp in Headers */, DCD069011D8CDFFE007602F1 /* CharScanner.hpp in Headers */, - DCD068511D8CDF7E007602F1 /* csgeneric.h in Headers */, DCD0687C1D8CDF7E007602F1 /* dirscanner.h in Headers */, DCD068831D8CDF7E007602F1 /* SecAssessment.h in Headers */, DCD068531D8CDF7E007602F1 /* diskrep.h in Headers */, @@ -23449,7 +27357,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - DCD06A521D8CE29C007602F1 /* SecCodeHostLib.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -23457,13 +27364,11 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - DCD06BA41D8E0D7D007602F1 /* machrunloopserver.h in Headers */, DCD06B501D8E0D7D007602F1 /* debugsupport.h in Headers */, DCD06B4C1D8E0D7D007602F1 /* ccaudit.h in Headers */, DCD06B671D8E0D7D007602F1 /* powerwatch.h in Headers */, DCD06B561D8E0D7D007602F1 /* endian.h in Headers */, DCD06BC41D8E0DC2007602F1 /* utilities_dtrace.h in Headers */, - DCD06B711D8E0D7D007602F1 /* streams.h in Headers */, DCD06B7C1D8E0D7D007602F1 /* trackingallocator.h in Headers */, DCD06B691D8E0D7D007602F1 /* refcount.h in Headers */, DCD06BA11D8E0D7D007602F1 /* dyld_cache_format.h in Headers */, @@ -23476,16 +27381,13 @@ DCD06B3F1D8E0D7D007602F1 /* FileLockTransaction.h in Headers */, DCD06B9F1D8E0D7D007602F1 /* dyldcache.h in Headers */, DCD06B821D8E0D7D007602F1 /* utilities.h in Headers */, - DCD06B521D8E0D7D007602F1 /* devrandom.h in Headers */, DCD06B751D8E0D7D007602F1 /* threading.h in Headers */, DCD06B611D8E0D7D007602F1 /* logging.h in Headers */, DCD06B471D8E0D7D007602F1 /* alloc.h in Headers */, DCD06B731D8E0D7D007602F1 /* superblob.h in Headers */, - DCD06B991D8E0D7D007602F1 /* mach_notify.h in Headers */, DCD06B491D8E0D7D007602F1 /* blob.h in Headers */, DCD06B911D8E0D7D007602F1 /* unix++.h in Headers */, DCD06B9D1D8E0D7D007602F1 /* macho++.h in Headers */, - DCD06B951D8E0D7D007602F1 /* vproc++.h in Headers */, DCD06BAA1D8E0D7D007602F1 /* cfmunge.h in Headers */, DCD06B6A1D8E0D7D007602F1 /* seccfobject.h in Headers */, DC2670F21F3E6EC500816EED /* debugging.h in Headers */, @@ -23546,7 +27448,6 @@ DCD8A15F1E09EE0F00E4FA0A /* SOSCirclePriv.h in Headers */, DCD8A1601E09EE0F00E4FA0A /* SOSCircleRings.h in Headers */, DCD8A1611E09EE0F00E4FA0A /* SOSCircleV2.h in Headers */, - DCD8A1621E09EE0F00E4FA0A /* SOSCloudCircle.h in Headers */, 0CE760501E1301DC00B4381E /* SOSAccountTrustClassic+Expansion.h in Headers */, DCD8A1631E09EE0F00E4FA0A /* SOSCloudCircleInternal.h in Headers */, DCD8A1641E09EE0F00E4FA0A /* SOSCloudKeychainClient.h in Headers */, @@ -23560,30 +27461,30 @@ DCD8A16F1E09EE0F00E4FA0A /* SOSKVSKeys.h in Headers */, DCD8A1741E09EE0F00E4FA0A /* SOSPeerInfo.h in Headers */, DCD8A17C1E09EE0F00E4FA0A /* SOSPlatform.h in Headers */, - DCD8A17D1E09EE0F00E4FA0A /* SOSRing.h in Headers */, - DCD8A17E1E09EE0F00E4FA0A /* SOSRingBackup.h in Headers */, DCD8A17F1E09EE0F00E4FA0A /* SOSKeyedPubKeyIdentifier.h in Headers */, DCD8A1801E09EE0F00E4FA0A /* SOSRingBasic.h in Headers */, DCD8A1821E09EE0F00E4FA0A /* SOSAccountGhost.h in Headers */, DCD8A1E01E09F76800E4FA0A /* SOSPeerInfoRingState.h in Headers */, - DCD8A1831E09EE0F00E4FA0A /* SOSRingConcordanceTrust.h in Headers */, - DCD8A1841E09EE0F00E4FA0A /* SOSRecoveryKeyBag.h in Headers */, DCD8A1851E09EE0F00E4FA0A /* SOSRingDER.h in Headers */, DCD8A1861E09EE0F00E4FA0A /* SOSRingPeerInfoUtils.h in Headers */, 0CE760521E1314F700B4381E /* SOSAccountTrustClassic+Identity.h in Headers */, - DCD8A1871E09EE0F00E4FA0A /* SOSRingTypes.h in Headers */, DCD8A1DF1E09F76000E4FA0A /* SOSPeerInfoCollections.h in Headers */, DCD8A1891E09EE0F00E4FA0A /* SOSRingUtils.h in Headers */, DCD8A18A1E09EE0F00E4FA0A /* SOSRingV0.h in Headers */, - DCD8A18B1E09EE0F00E4FA0A /* SOSTransport.h in Headers */, EB75B4951E75A44100E469CC /* SOSPiggyback.h in Headers */, - DCD8A1901E09EE0F00E4FA0A /* SOSAccountTrust.h in Headers */, DCD8A1DE1E09F74700E4FA0A /* SOSPeerInfoV2.h in Headers */, DCD8A1931E09EE0F00E4FA0A /* SOSTypes.h in Headers */, DCD8A1951E09EE0F00E4FA0A /* SOSViews.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; + DCF216D321ADD5B10029CCC1 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DCF7830D1D88B4DE00E694BB /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -23592,7 +27493,6 @@ DCF784011D88B60D00E694BB /* rc4Context.h in Headers */, DCF784E31D88B62E00E694BB /* opensslv_legacy.h in Headers */, DCF783F61D88B60D00E694BB /* pkcs8.h in Headers */, - DCF783CE1D88B60D00E694BB /* bsobjects.h in Headers */, DCF783A71D88B60D00E694BB /* rijndaelApi.h in Headers */, DCF7839D1D88B60D00E694BB /* aesCommon.h in Headers */, DCF783EA1D88B60D00E694BB /* pbkdDigest.h in Headers */, @@ -23614,7 +27514,6 @@ DCF783F81D88B60D00E694BB /* bfContext.h in Headers */, DCF783AA1D88B60D00E694BB /* AppleCSP.h in Headers */, DCF783AD1D88B60D00E694BB /* AppleCSPContext.h in Headers */, - DCF783CC1D88B60D00E694BB /* bsafePKCS1.h in Headers */, DCF783B41D88B60D00E694BB /* BinaryKey.h in Headers */, DCF783BD1D88B60D00E694BB /* MacContext.h in Headers */, DCF7839F1D88B60D00E694BB /* aescspi.h in Headers */, @@ -23637,7 +27536,6 @@ DCF783BB1D88B60D00E694BB /* DigestContext.h in Headers */, DCF783DC1D88B60D00E694BB /* FEEKeys.h in Headers */, DCF784DB1D88B62E00E694BB /* e_os.h in Headers */, - DCF783C91D88B60D00E694BB /* bsafecspi.h in Headers */, DCF784D71D88B62E00E694BB /* cast_legacy.h in Headers */, DCF783C01D88B60D00E694BB /* SignatureContext.h in Headers */, DCF783D31D88B60D00E694BB /* ascFactory.h in Headers */, @@ -23656,7 +27554,6 @@ DCF784EA1D88B62E00E694BB /* x509_legacy.h in Headers */, DCF783B81D88B60D00E694BB /* cspdebugging.h in Headers */, DCF784D31D88B62E00E694BB /* bio_legacy.h in Headers */, - DCF783C81D88B60D00E694BB /* bsafecsp.h in Headers */, DCF784D21D88B62E00E694BB /* asn1_legacy.h in Headers */, DCF784DF1D88B62E00E694BB /* lhash_legacy.h in Headers */, DCF7840F1D88B60D00E694BB /* RSA_asymmetric.h in Headers */, @@ -23759,6 +27656,22 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + E060D1972124780E0025B833 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E060D1C7212478120025B833 /* OctagonTestHarness.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E060D1A22124780F0025B833 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E060D24821247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; E7D847C21C6BE9710025BB44 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; @@ -23770,6 +27683,7 @@ EB413B821E663AFA00592085 /* PairingChannel.h in Headers */, E7F480121C729C7B00390FDB /* NSError+KCCreationHelpers.h in Headers */, E7E3EFE31CBC195700E79A5D /* KCAccountKCCircleDelegate.h in Headers */, + 5A47FFBA228F60DF00F781B8 /* KCInitialMessageData.h in Headers */, E794BB011C759B1200339A0F /* KCJoiningMessages.h in Headers */, E71454EF1C741E0800B5B20B /* KCError.h in Headers */, E7F482961C74FDF800390FDB /* KCJoiningSession.h in Headers */, @@ -23777,21 +27691,23 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - EBCE16631FE7366D002E7CCC /* Headers */ = { + EB695289223B75C300F02C1C /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - EBCE16681FE736AD002E7CCC /* DeviceSimulatorProtocol.h in Headers */, - EBCE16641FE73679002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */, + EB69528A223B75C300F02C1C /* SFKeychainServer.h in Headers */, + EB69528B223B75C300F02C1C /* SecItemBackupServer.h in Headers */, + EB69528C223B75C300F02C1C /* SecCDKeychain.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - EBCE16651FE7368C002E7CCC /* Headers */ = { + EB8908A421F186FE00F0DDDB /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - EBCE16661FE736A1002E7CCC /* MultiDeviceNetworkingProtocol.h in Headers */, - EBCE16671FE736A5002E7CCC /* DeviceSimulatorProtocol.h in Headers */, + EB8908A621F1871800F0DDDB /* SFKeychainServer.h in Headers */, + EB8908B321F18E3200F0DDDB /* SecItemBackupServer.h in Headers */, + EB8908A521F1870800F0DDDB /* SecCDKeychain.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -23967,20 +27883,6 @@ passBuildSettingsInEnvironment = 1; productName = "--- Daemons ---"; }; - EBBE20571C21380100B7A639 /* SecurityFeatures */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "$(PROJECT_DIR)/SecurityFeatures/ExternalProject.sh $(ACTION)"; - buildConfigurationList = EBBE20581C21380200B7A639 /* Build configuration list for PBXLegacyTarget "SecurityFeatures" */; - buildPhases = ( - ); - buildToolPath = /bin/bash; - buildWorkingDirectory = "$(PROJECT_DIR)/SecurityFeatures"; - dependencies = ( - ); - name = SecurityFeatures; - passBuildSettingsInEnvironment = 1; - productName = SecurityFeatures; - }; /* End PBXLegacyTarget section */ /* Begin PBXNativeTarget section */ @@ -23995,12 +27897,13 @@ buildRules = ( ); dependencies = ( + DCD6BF5A21E919A60015F7A8 /* PBXTargetDependency */, D40B6A8C1E2B63D100CD6EE5 /* PBXTargetDependency */, DC00ABD11D821F1A00513D74 /* PBXTargetDependency */, DC00ABD31D821F1D00513D74 /* PBXTargetDependency */, DCD8A1EF1E09F8BC00E4FA0A /* PBXTargetDependency */, DC65E75A1D8CB48900152EF0 /* PBXTargetDependency */, - DC59E9A91D91C7CC001BDDF5 /* PBXTargetDependency */, + D437185921166FC800EA350A /* PBXTargetDependency */, DC65E75C1D8CB49200152EF0 /* PBXTargetDependency */, DC52EDFC1D80D67C00B0A59C /* PBXTargetDependency */, DC00ABD51D821F2700513D74 /* PBXTargetDependency */, @@ -24057,7 +27960,7 @@ buildRules = ( ); dependencies = ( - 0C85DFD41FB38BB6000343A7 /* PBXTargetDependency */, + DC3E18CA212501C200073D80 /* PBXTargetDependency */, 0C85DFD81FB38BB6000343A7 /* PBXTargetDependency */, 0C85DFDA1FB38BB6000343A7 /* PBXTargetDependency */, 0C85DFDC1FB38BB6000343A7 /* PBXTargetDependency */, @@ -24075,7 +27978,7 @@ buildPhases = ( 0C8BBEFE1FCB446400580909 /* Sources */, 0C8BBF021FCB446400580909 /* Frameworks */, - 0C8BBF041FCB446400580909 /* CopyFiles */, + 0C8BBF041FCB446400580909 /* Install man1 pages */, ); buildRules = ( ); @@ -24141,33 +28044,52 @@ productReference = 225394B41E3080A600D3CD9B /* libsecurity_codesigning_ios.a */; productType = "com.apple.product-type.library.static"; }; - 3DD1FEF5201C07F30086D049 /* SecureTransport_macos_tests */ = { + 3D58392D21890FFB000ACA44 /* SecExperimentTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 3D58394A21890FFB000ACA44 /* Build configuration list for PBXNativeTarget "SecExperimentTests" */; + buildPhases = ( + 3D58393021890FFB000ACA44 /* Sources */, + 3D58393E21890FFB000ACA44 /* Frameworks */, + 3D58394821890FFB000ACA44 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SecExperimentTests; + productName = CKKSTests; + productReference = 3D58394D21890FFB000ACA44 /* SecExperimentTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 3DD1FEF5201C07F30086D049 /* SecureTransportTests_macos */ = { isa = PBXNativeTarget; - buildConfigurationList = 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_macos_tests" */; + buildConfigurationList = 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransportTests_macos" */; buildPhases = ( 3DD1FF02201C07F30086D049 /* Sources */, 3DD1FF2F201C07F30086D049 /* Frameworks */, 3DD1FFD6201FF7930086D049 /* CopyFiles */, 3DD1FF49201C07F30086D049 /* ShellScript */, + AAE7D3202161CCE50054245E /* CopyFiles */, ); buildRules = ( ); dependencies = ( 3DD1FF50201C09CD0086D049 /* PBXTargetDependency */, - 3DD1FEF8201C07F30086D049 /* PBXTargetDependency */, + 3DD258A2204B7DA800F5DA78 /* PBXTargetDependency */, ); - name = SecureTransport_macos_tests; + name = SecureTransportTests_macos; productName = CKKSTests; productReference = 3DD1FF4D201C07F30086D049 /* SecureTransport_macos_tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - 3DD1FFAC201FDB1D0086D049 /* SecureTransport_ios_tests */ = { + 3DD1FFAC201FDB1D0086D049 /* SecureTransportTests_ios */ = { isa = PBXNativeTarget; - buildConfigurationList = 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_ios_tests" */; + buildConfigurationList = 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransportTests_ios" */; buildPhases = ( 3DD1FFB3201FDB1D0086D049 /* Sources */, 3DD1FFC3201FDB1D0086D049 /* Frameworks */, - 3DD1FFD3201FF72C0086D049 /* CopyFiles */, + AA0DA47C21E818C1009F1C74 /* CopyFiles */, + 3DD1FFD3201FF72C0086D049 /* Copy Plist */, 3DD1FFCC201FDB1D0086D049 /* ShellScript */, ); buildRules = ( @@ -24176,7 +28098,7 @@ 3DD1FFAF201FDB1D0086D049 /* PBXTargetDependency */, 3DD1FFB1201FDB1D0086D049 /* PBXTargetDependency */, ); - name = SecureTransport_ios_tests; + name = SecureTransportTests_ios; productName = CKKSTests; productReference = 3DD1FFD0201FDB1D0086D049 /* SecureTransport_ios_tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; @@ -24221,12 +28143,13 @@ buildPhases = ( 4718AE0F205B39620068EC3F /* Sources */, 4718AE17205B39620068EC3F /* Frameworks */, - 4718AE26205B39620068EC3F /* CopyFiles */, - 4718AE28205B39620068EC3F /* CopyFiles */, + 4718AE26205B39620068EC3F /* Launchd plists */, + 4718AE28205B39620068EC3F /* Copy Logging Files */, ); buildRules = ( ); dependencies = ( + DC3E18CE2125024C00073D80 /* PBXTargetDependency */, 4718AEE6205B3A350068EC3F /* PBXTargetDependency */, 4718AE03205B39620068EC3F /* PBXTargetDependency */, 4718AE05205B39620068EC3F /* PBXTargetDependency */, @@ -24246,9 +28169,9 @@ 4718AE2F205B39C40068EC3F /* Sources */, 4718AE9C205B39C40068EC3F /* Frameworks */, 4718AE9D205B39C40068EC3F /* Headers */, + 4718AEDC205B39C40068EC3F /* CopyFiles */, ); buildRules = ( - 4718AEDE205B39C40068EC3F /* PBXBuildRule */, ); dependencies = ( ); @@ -24268,6 +28191,10 @@ buildRules = ( ); dependencies = ( + D4BFFD692227B30700163B4B /* PBXTargetDependency */, + EB74CBD622077CC600F1BBAD /* PBXTargetDependency */, + EBD7DF8121FF475B0089F2DF /* PBXTargetDependency */, + EBD7DF8321FF475B0089F2DF /* PBXTargetDependency */, 47A6FC6A206B461700BD6C54 /* PBXTargetDependency */, 47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */, 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */, @@ -24340,6 +28267,7 @@ buildRules = ( ); dependencies = ( + DC69A5872165298500512BD6 /* PBXTargetDependency */, 47A6FC6C206B462400BD6C54 /* PBXTargetDependency */, DC34CD3620326C3B00302481 /* PBXTargetDependency */, DC34CD3420326C3100302481 /* PBXTargetDependency */, @@ -24376,7 +28304,6 @@ buildPhases = ( 47C51B801EEA657D0032D9E5 /* Sources */, 47C51B811EEA657D0032D9E5 /* Frameworks */, - 47C51B821EEA657D0032D9E5 /* Resources */, ); buildRules = ( ); @@ -24398,14 +28325,16 @@ 4C32C0AB0A4975F6002891BD /* Resources */, 4C32C0AC0A4975F6002891BD /* Sources */, 4C32C0AD0A4975F6002891BD /* Frameworks */, - 5EE098DE1CD21661009FCA27 /* Unifdef RC_HIDE_J79/J80 */, + F3384FD12165A025004A2171 /* Install Ariadne Signposts Plist */, ); buildRules = ( E7B006FF170B56E700B27966 /* PBXBuildRule */, ); dependencies = ( - DC59E9A61D91C710001BDDF5 /* PBXTargetDependency */, + DCE0778421ADEDDA002662FD /* PBXTargetDependency */, + DCDA5E5A2124BA2F009B11B2 /* PBXTargetDependency */, DCD22D7D1D8CCA18001C9B81 /* PBXTargetDependency */, + D42C83A5211636A3008D3D83 /* PBXTargetDependency */, DCD22D7B1D8CCA07001C9B81 /* PBXTargetDependency */, DCD8A19C1E09EEA200E4FA0A /* PBXTargetDependency */, DCC093781D80ABC300F984E4 /* PBXTargetDependency */, @@ -24431,6 +28360,7 @@ buildRules = ( ); dependencies = ( + 873C14B221540FED003C9C00 /* PBXTargetDependency */, ); name = CircleJoinRequested; productName = CircleJoinRequested; @@ -24497,12 +28427,12 @@ buildRules = ( ); dependencies = ( + D4E0E9DB2225D14500A802E0 /* PBXTargetDependency */, + D4E0E9D72225023600A802E0 /* PBXTargetDependency */, DCD22D821D8CCB5A001C9B81 /* PBXTargetDependency */, DCD22D841D8CCB72001C9B81 /* PBXTargetDependency */, DCD8A1EC1E09F88400E4FA0A /* PBXTargetDependency */, DC52EC3D1D80CFF000B0A59C /* PBXTargetDependency */, - DC52EC201D80CF7400B0A59C /* PBXTargetDependency */, - DC52EAA51D80CCF600B0A59C /* PBXTargetDependency */, ); name = securitytool_ios; productName = security; @@ -24538,6 +28468,7 @@ buildRules = ( ); dependencies = ( + D4E0E9DD2225D1E600A802E0 /* PBXTargetDependency */, DC65E72F1D8CB32400152EF0 /* PBXTargetDependency */, ); name = CloudKeychainProxy; @@ -24590,6 +28521,7 @@ buildRules = ( ); dependencies = ( + DC3E18CC2125020400073D80 /* PBXTargetDependency */, D40B6A861E2B5F7600CD6EE5 /* PBXTargetDependency */, DC89998B1E410DBF00E6E604 /* PBXTargetDependency */, DC65E7561D8CB47600152EF0 /* PBXTargetDependency */, @@ -24603,6 +28535,30 @@ productReference = 5EBE247A1B00CCAE0007DB0E /* secacltests */; productType = "com.apple.product-type.tool"; }; + 6C39234421F13E4D00D018AD /* SecDbBackupTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6C39237621F13E4D00D018AD /* Build configuration list for PBXNativeTarget "SecDbBackupTests" */; + buildPhases = ( + 6C39234D21F13E4D00D018AD /* Sources */, + 6C39235A21F13E4D00D018AD /* Frameworks */, + 6C7E8F1F21F7BE64008A2D56 /* Copy BATS Test Discovery Plist */, + 6C7E8F2121F7BE7F008A2D56 /* Chown BATS Test Discovery Plist */, + ); + buildRules = ( + ); + dependencies = ( + 6C8FF4B6224C1A9800E5C812 /* PBXTargetDependency */, + D4BFFD622227578900163B4B /* PBXTargetDependency */, + D4BFFD602227576E00163B4B /* PBXTargetDependency */, + D4BFFD5E2227575C00163B4B /* PBXTargetDependency */, + D4BFFD5C2227574C00163B4B /* PBXTargetDependency */, + D4BFFD592227574200163B4B /* PBXTargetDependency */, + ); + name = SecDbBackupTests; + productName = secdxctests; + productReference = 6C39237921F13E4D00D018AD /* SecDbBackupTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */ = { isa = PBXNativeTarget; buildConfigurationList = 6C4605B51F882B9B001421B6 /* Build configuration list for PBXNativeTarget "KeychainAnalyticsTests" */; @@ -24632,12 +28588,13 @@ buildRules = ( ); dependencies = ( + DCD6BF5421E919610015F7A8 /* PBXTargetDependency */, + DC93C4C9214713DC008F8362 /* PBXTargetDependency */, 6C98082F1E788AEB00E70590 /* PBXTargetDependency */, 6C9808311E788AEB00E70590 /* PBXTargetDependency */, 6C9808351E788AEB00E70590 /* PBXTargetDependency */, 6C9808371E788AEB00E70590 /* PBXTargetDependency */, 6C9808391E788AEB00E70590 /* PBXTargetDependency */, - 6C98083B1E788AEB00E70590 /* PBXTargetDependency */, 6C9808A01E788B9400E70590 /* PBXTargetDependency */, ); name = CKKSCloudKitTests_mac; @@ -24656,13 +28613,14 @@ buildRules = ( ); dependencies = ( + DCD6BF5621E9196E0015F7A8 /* PBXTargetDependency */, + DC93C4CD21471401008F8362 /* PBXTargetDependency */, 6C9808A41E788CB100E70590 /* PBXTargetDependency */, 6C98086B1E788AFD00E70590 /* PBXTargetDependency */, 6C98086D1E788AFD00E70590 /* PBXTargetDependency */, 6C9808711E788AFD00E70590 /* PBXTargetDependency */, 6C9808731E788AFD00E70590 /* PBXTargetDependency */, 6C9808751E788AFD00E70590 /* PBXTargetDependency */, - 6C9808771E788AFD00E70590 /* PBXTargetDependency */, ); name = CKKSCloudKitTests_ios; productName = CKKSTests; @@ -24698,6 +28656,7 @@ buildRules = ( ); dependencies = ( + D456A06D22AF3238001119F3 /* PBXTargetDependency */, ); name = securityuploadd; productName = supd; @@ -24710,8 +28669,6 @@ buildPhases = ( 6CCDF7801E3C25FA003F2555 /* Sources */, 6CCDF7811E3C25FA003F2555 /* Frameworks */, - 6CCDF7821E3C25FA003F2555 /* Copy BATS Test Discovery plist */, - 6CB5F4761E402D0000DBF3F0 /* ShellScript */, ); buildRules = ( ); @@ -24762,12 +28719,14 @@ buildPhases = ( 790851B30CA9859F0083CC4D /* Sources */, 790851B40CA9859F0083CC4D /* Frameworks */, - 79863B6C0CADCE4300818B0D /* CopyFiles */, - 4814D8691CAA059E002FFC36 /* CopyFiles */, + 79863B6C0CADCE4300818B0D /* launchd plist */, + 4814D8691CAA059E002FFC36 /* Copy Logging Files */, ); buildRules = ( ); dependencies = ( + DCDA5E5E2124BA79009B11B2 /* PBXTargetDependency */, + DC7FC45221EE9208003C39B8 /* PBXTargetDependency */, DC65E7291D8CB2F400152EF0 /* PBXTargetDependency */, D40B6A7F1E2B5F3D00CD6EE5 /* PBXTargetDependency */, DC52E84B1D80BF1100B0A59C /* PBXTargetDependency */, @@ -24790,6 +28749,9 @@ buildRules = ( ); dependencies = ( + D4E0E9D52224FE4100A802E0 /* PBXTargetDependency */, + D4E0E9D12224FE3300A802E0 /* PBXTargetDependency */, + D4E0E9D32224FE3300A802E0 /* PBXTargetDependency */, DC65E7701D8CB4ED00152EF0 /* PBXTargetDependency */, ); name = sslServer; @@ -24825,6 +28787,8 @@ buildRules = ( ); dependencies = ( + D4E0E9CF2224FD7A00A802E0 /* PBXTargetDependency */, + D4E0E9C52224E71600A802E0 /* PBXTargetDependency */, ); name = SharedWebCredentialViewService; productName = KeychainViewService; @@ -24849,6 +28813,42 @@ productReference = BE442BC118B7FDB800F24DAE /* swcagent */; productType = "com.apple.product-type.tool"; }; + BEAA002A202A832500E51F45 /* TrustedPeersHelper */ = { + isa = PBXNativeTarget; + buildConfigurationList = BEAA003E202A832500E51F45 /* Build configuration list for PBXNativeTarget "TrustedPeersHelper" */; + buildPhases = ( + BEAA0027202A832500E51F45 /* Sources */, + BEAA0029202A832500E51F45 /* Resources */, + BEAA0028202A832500E51F45 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + EBBC11B32200D3BB00F95738 /* PBXTargetDependency */, + BED01526206EEC710027A2B4 /* PBXTargetDependency */, + ); + name = TrustedPeersHelper; + productName = TrustedPeersHelper; + productReference = BEAA002B202A832500E51F45 /* TrustedPeersHelper.xpc */; + productType = "com.apple.product-type.xpc-service"; + }; + BECFA42D20F91AFE00B11002 /* tppolicy */ = { + isa = PBXNativeTarget; + buildConfigurationList = BECFA43920F91AFE00B11002 /* Build configuration list for PBXNativeTarget "tppolicy" */; + buildPhases = ( + BECFA42A20F91AFE00B11002 /* Sources */, + BECFA42B20F91AFE00B11002 /* Frameworks */, + BECFA42C20F91AFE00B11002 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = tppolicy; + productName = tppolicy; + productReference = BECFA42E20F91AFE00B11002 /* tppolicy */; + productType = "com.apple.product-type.tool"; + }; BED208D41EDF950E00753952 /* manifeststresstest */ = { isa = PBXNativeTarget; buildConfigurationList = BED208DA1EDF950E00753952 /* Build configuration list for PBXNativeTarget "manifeststresstest" */; @@ -24865,6 +28865,30 @@ productReference = BED208DD1EDF950E00753952 /* manifeststresstest */; productType = "com.apple.product-type.tool"; }; + BED987D22099145300607A5F /* TrustedPeersHelperUnitTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = BED987DB2099145400607A5F /* Build configuration list for PBXNativeTarget "TrustedPeersHelperUnitTests" */; + buildPhases = ( + BED987CF2099145300607A5F /* Sources */, + BED987D02099145300607A5F /* Frameworks */, + BED987D12099145300607A5F /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + DC69A5832165295F00512BD6 /* PBXTargetDependency */, + DC6013372147222B00863C1A /* PBXTargetDependency */, + DC00C92720B3B86800628BEB /* PBXTargetDependency */, + DC00C91F20B3B7A800628BEB /* PBXTargetDependency */, + DC00C91A20B3B74E00628BEB /* PBXTargetDependency */, + DC00C91820B3B74600628BEB /* PBXTargetDependency */, + DC00C91620B3B73900628BEB /* PBXTargetDependency */, + ); + name = TrustedPeersHelperUnitTests; + productName = TrustedPeersHelperUnitTests; + productReference = BED987D32099145300607A5F /* TrustedPeersHelperUnitTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; BEF88C271EAFFC3F00357577 /* TrustedPeers */ = { isa = PBXNativeTarget; buildConfigurationList = BEF88C421EAFFC4000357577 /* Build configuration list for PBXNativeTarget "TrustedPeers" */; @@ -24877,6 +28901,8 @@ buildRules = ( ); dependencies = ( + DCE0775C21ADD6A0002662FD /* PBXTargetDependency */, + D437C33121EBF8A000DD1E06 /* PBXTargetDependency */, ); name = TrustedPeers; productName = TrustedPeers; @@ -24894,7 +28920,6 @@ buildRules = ( ); dependencies = ( - BEF88C331EAFFC3F00357577 /* PBXTargetDependency */, ); name = TrustedPeersTests; productName = TrustedPeersTests; @@ -24921,6 +28946,116 @@ productReference = D41257CF1E9410A300781F23 /* trustd */; productType = "com.apple.product-type.tool"; }; + D42C839721159146008D3D83 /* security_cms */ = { + isa = PBXNativeTarget; + buildConfigurationList = D42C839921159147008D3D83 /* Build configuration list for PBXNativeTarget "security_cms" */; + buildPhases = ( + D42C839421159146008D3D83 /* Headers */, + D42C839521159146008D3D83 /* Sources */, + D42C839621159146008D3D83 /* Frameworks */, + D43718C021168BD400EA350A /* Copy Open Source Version */, + D43718C221168C5500EA350A /* Copy Open Source Licenses */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = security_cms; + productName = security_cms; + productReference = D42C839821159146008D3D83 /* libsecurity_cms.a */; + productType = "com.apple.product-type.library.static"; + }; + D44D1F652115893000E76E1A /* CMS */ = { + isa = PBXNativeTarget; + buildConfigurationList = D44D1F6E2115893000E76E1A /* Build configuration list for PBXNativeTarget "CMS" */; + buildPhases = ( + D44D1F622115893000E76E1A /* Headers */, + D44D1F632115893000E76E1A /* Sources */, + D44D1F642115893000E76E1A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CMS; + productName = CMS; + productReference = D44D1F662115893000E76E1A /* libCMS.a */; + productType = "com.apple.product-type.library.static"; + }; + D453A4A42122236D00850A26 /* TrustTests_macos */ = { + isa = PBXNativeTarget; + buildConfigurationList = D453A4BD2122236D00850A26 /* Build configuration list for PBXNativeTarget "TrustTests_macos" */; + buildPhases = ( + D453A4A72122236D00850A26 /* Sources */, + D453A4B12122236D00850A26 /* Frameworks */, + D453A4BB2122236D00850A26 /* Resources */, + D4428B46212271E400EB8448 /* Generate BATS Plist */, + ); + buildRules = ( + ); + dependencies = ( + D4794E6B21222E72007C6725 /* PBXTargetDependency */, + D453A4A52122236D00850A26 /* PBXTargetDependency */, + D453A4C42122262400850A26 /* PBXTargetDependency */, + ); + name = TrustTests_macos; + productName = TrustTests; + productReference = D453A4C02122236D00850A26 /* TrustTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + D458C4E0214E1DE00043D982 /* TrustTestsRunner_ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = D458C4F4214E1DE10043D982 /* Build configuration list for PBXNativeTarget "TrustTestsRunner_ios" */; + buildPhases = ( + D458C4DD214E1DE00043D982 /* Sources */, + D458C4DE214E1DE00043D982 /* Frameworks */, + D458C4DF214E1DE00043D982 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TrustTestsRunner_ios; + productName = TrustTestsRunner_ios; + productReference = D458C4E1214E1DE00043D982 /* TrustTestsRunner_ios.app */; + productType = "com.apple.product-type.application"; + }; + D458C505214E20530043D982 /* TrustTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = D458C50D214E20540043D982 /* Build configuration list for PBXNativeTarget "TrustTests" */; + buildPhases = ( + D458C502214E20530043D982 /* Sources */, + D458C503214E20530043D982 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = TrustTests; + productName = TrustTests; + productReference = D458C506214E20530043D982 /* TrustTests */; + productType = "com.apple.product-type.tool"; + }; + D4707A0421136E69005BCFDA /* TrustTests_ios */ = { + isa = PBXNativeTarget; + buildConfigurationList = D4707A0A21136E6A005BCFDA /* Build configuration list for PBXNativeTarget "TrustTests_ios" */; + buildPhases = ( + D4707A0121136E69005BCFDA /* Sources */, + D4707A0221136E69005BCFDA /* Frameworks */, + D4707A0321136E69005BCFDA /* Resources */, + D4428B432122718400EB8448 /* Generate BATS Plist */, + ); + buildRules = ( + ); + dependencies = ( + D453A4C8212226A900850A26 /* PBXTargetDependency */, + D4B68C6A211B6E3E009FED69 /* PBXTargetDependency */, + ); + name = TrustTests_ios; + productName = TrustTests; + productReference = D4707A0521136E69005BCFDA /* TrustTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; D4ADA3181E2B41670031CEA3 /* libtrustd */ = { isa = PBXNativeTarget; buildConfigurationList = D4ADA31A1E2B41670031CEA3 /* Build configuration list for PBXNativeTarget "libtrustd" */; @@ -24938,6 +29073,23 @@ productReference = D4ADA3191E2B41670031CEA3 /* libtrustd.a */; productType = "com.apple.product-type.library.static"; }; + D4D1FDDB21165F8B003538E2 /* security_cms_regressions */ = { + isa = PBXNativeTarget; + buildConfigurationList = D4D1FDDD21165F8B003538E2 /* Build configuration list for PBXNativeTarget "security_cms_regressions" */; + buildPhases = ( + D4D1FDD821165F8B003538E2 /* Headers */, + D4D1FDD921165F8B003538E2 /* Sources */, + D4D1FDDA21165F8B003538E2 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = security_cms_regressions; + productName = security_cms_regressions; + productReference = D4D1FDDC21165F8B003538E2 /* libsecurity_cms_regressions.a */; + productType = "com.apple.product-type.library.static"; + }; DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */ = { isa = PBXNativeTarget; buildConfigurationList = DA30D6801DF8C8FB00EC6B43 /* Build configuration list for PBXNativeTarget "KeychainSyncAccountUpdater" */; @@ -24955,6 +29107,24 @@ productReference = DA30D6761DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater.bundle */; productType = "com.apple.product-type.bundle"; }; + DA41FE0D2241ADC000838FB3 /* otpaird */ = { + isa = PBXNativeTarget; + buildConfigurationList = DA41FE152241ADC000838FB3 /* Build configuration list for PBXNativeTarget "otpaird" */; + buildPhases = ( + DA41FE0A2241ADC000838FB3 /* Sources */, + DA41FE0B2241ADC000838FB3 /* Frameworks */, + DA41FE162241AE9100838FB3 /* Install launchd plist */, + ); + buildRules = ( + ); + dependencies = ( + 0CC593F82299EDFC006C34B5 /* PBXTargetDependency */, + ); + name = otpaird; + productName = otpaird; + productReference = DA41FE0E2241ADC000838FB3 /* otpaird */; + productType = "com.apple.product-type.tool"; + }; DAE40BC520CF3E46002D5674 /* secitemcanarytest */ = { isa = PBXNativeTarget; buildConfigurationList = DAE40BCB20CF3E46002D5674 /* Build configuration list for PBXNativeTarget "secitemcanarytest" */; @@ -25007,6 +29177,25 @@ productReference = DC0067D01D878898005AF8DB /* libsecurityd_ucspc.a */; productType = "com.apple.product-type.library.static"; }; + DC05037521409A4000A8EDB7 /* OCMockUmbrella */ = { + isa = PBXNativeTarget; + buildConfigurationList = DC05037F21409A4100A8EDB7 /* Build configuration list for PBXNativeTarget "OCMockUmbrella" */; + buildPhases = ( + DC05037121409A4000A8EDB7 /* Headers */, + DC05037221409A4000A8EDB7 /* Sources */, + DC05037321409A4000A8EDB7 /* Frameworks */, + DC05037421409A4000A8EDB7 /* Resources */, + DC05038021409A4F00A8EDB7 /* Embed OCMock */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OCMockUmbrella; + productName = OCMockUmbrella; + productReference = DC05037621409A4000A8EDB7 /* OCMockUmbrella.framework */; + productType = "com.apple.product-type.framework"; + }; DC0BC5501D8B6D2D00070CB0 /* XPCKeychainSandboxCheck */ = { isa = PBXNativeTarget; buildConfigurationList = DC0BC55D1D8B6D2E00070CB0 /* Build configuration list for PBXNativeTarget "XPCKeychainSandboxCheck" */; @@ -25386,6 +29575,25 @@ productReference = DC0BCD481D8C694700070CB0 /* libutilitiesRegressions.a */; productType = "com.apple.product-type.library.static"; }; + DC0EF8EE208697C600AB9E95 /* tpctl */ = { + isa = PBXNativeTarget; + buildConfigurationList = DC0EF8F3208697C700AB9E95 /* Build configuration list for PBXNativeTarget "tpctl" */; + buildPhases = ( + DC0EF8EB208697C600AB9E95 /* Sources */, + DC0EF8EC208697C600AB9E95 /* Frameworks */, + DC0EF8ED208697C600AB9E95 /* CopyFiles */, + EBE2026A20908C5600B48020 /* install man8 page */, + ); + buildRules = ( + ); + dependencies = ( + DC7479A022272361001E0E8C /* PBXTargetDependency */, + ); + name = tpctl; + productName = tpctl; + productReference = DC0EF8EF208697C600AB9E95 /* tpctl */; + productType = "com.apple.product-type.tool"; + }; DC1789031D77980500B50D50 /* Security_osx */ = { isa = PBXNativeTarget; buildConfigurationList = DC17890D1D77980500B50D50 /* Build configuration list for PBXNativeTarget "Security_osx" */; @@ -25396,27 +29604,26 @@ DC1789001D77980500B50D50 /* Frameworks */, DC1789A71D779E7E00B50D50 /* Run Script Generate Strings */, DC1789021D77980500B50D50 /* Resources */, - DC1789E81D77A0E700B50D50 /* CopyFiles */, DC178B481D77A51600B50D50 /* Make XPC server symlink */, + F3384FD52165A071004A2171 /* Install Ariadne Signposts Plist */, ); buildRules = ( DC58C36E1D77B4AD003C25A4 /* PBXBuildRule */, ); dependencies = ( - DCD8A1FE1E09FA1800E4FA0A /* PBXTargetDependency */, - DCC5BF381D937329008D1E84 /* PBXTargetDependency */, - DC1789791D779C6700B50D50 /* PBXTargetDependency */, DC0BCDB71D8C6AD100070CB0 /* PBXTargetDependency */, + DCD06BCF1D8E0F01007602F1 /* PBXTargetDependency */, + DCB342371D8A2CD70054D16E /* PBXTargetDependency */, + DC0BC5AF1D8B714000070CB0 /* PBXTargetDependency */, DCB340191D8A248C0054D16E /* PBXTargetDependency */, - DCD66DC31D82056C00DB1393 /* PBXTargetDependency */, DCD66DE61D82061F00DB1393 /* PBXTargetDependency */, + DCD66DC31D82056C00DB1393 /* PBXTargetDependency */, DC52EE7E1D80D8B100B0A59C /* PBXTargetDependency */, - DCD06A8A1D8CE356007602F1 /* PBXTargetDependency */, - DCB342371D8A2CD70054D16E /* PBXTargetDependency */, - DC0BC5AF1D8B714000070CB0 /* PBXTargetDependency */, + D437185421166DD800EA350A /* PBXTargetDependency */, DC0067901D878132005AF8DB /* PBXTargetDependency */, DC0067C41D8787AE005AF8DB /* PBXTargetDependency */, DC0067D31D8788C4005AF8DB /* PBXTargetDependency */, + DCD06A8A1D8CE356007602F1 /* PBXTargetDependency */, DC0BC9991D8B814A00070CB0 /* PBXTargetDependency */, DC0BCB001D8B85E500070CB0 /* PBXTargetDependency */, DC0BC9651D8B80D200070CB0 /* PBXTargetDependency */, @@ -25427,7 +29634,6 @@ DC0BC9C71D8B820000070CB0 /* PBXTargetDependency */, DC0BCB301D8B89AB00070CB0 /* PBXTargetDependency */, DC0BC8F61D8B7DE700070CB0 /* PBXTargetDependency */, - DCD06BCF1D8E0F01007602F1 /* PBXTargetDependency */, DCF785011D88B80600E694BB /* PBXTargetDependency */, DCF788A91D88CC3500E694BB /* PBXTargetDependency */, DCB345661D8A36060054D16E /* PBXTargetDependency */, @@ -25440,6 +29646,7 @@ DCF789461D88CD7C00E694BB /* PBXTargetDependency */, DCB341791D8A2AF10054D16E /* PBXTargetDependency */, DC0BC7BF1D8B784F00070CB0 /* PBXTargetDependency */, + DCD8A1FE1E09FA1800E4FA0A /* PBXTargetDependency */, DC00AB6A1D821C0700513D74 /* PBXTargetDependency */, ); name = Security_osx; @@ -25447,22 +29654,21 @@ productReference = DC1789041D77980500B50D50 /* Security.framework */; productType = "com.apple.product-type.framework"; }; - DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */ = { + DC311E6E2124B8A8002F5EAE /* aks_real_witness */ = { isa = PBXNativeTarget; - buildConfigurationList = DC222C741E034D1F00B09171 /* Build configuration list for PBXNativeTarget "libsecurityd_ios_NO_AKS" */; + buildConfigurationList = DC311E742124B8A8002F5EAE /* Build configuration list for PBXNativeTarget "aks_real_witness" */; buildPhases = ( - DC222C381E034D1F00B09171 /* Sources */, - DC222C631E034D1F00B09171 /* Frameworks */, - DC222C641E034D1F00B09171 /* Headers */, + DC311E6F2124B8A8002F5EAE /* Headers */, + DC311E712124B8A8002F5EAE /* Sources */, + DC311E732124B8A8002F5EAE /* Frameworks */, ); buildRules = ( - DC9FD3221F85877000C8AAC8 /* PBXBuildRule */, ); dependencies = ( ); - name = libsecurityd_ios_NO_AKS; - productName = libsecurity; - productReference = DC222C771E034D1F00B09171 /* libsecurityd_ios_NO_AKS.a */; + name = aks_real_witness; + productName = mockaks; + productReference = DC311E772124B8A8002F5EAE /* libaks_real_witness.a */; productType = "com.apple.product-type.library.static"; }; DC3502B41E0208BE00BC0587 /* CKKSTests */ = { @@ -25478,18 +29684,36 @@ buildRules = ( ); dependencies = ( + DCD6BF5821E919820015F7A8 /* PBXTargetDependency */, + DC311E672124A9D2002F5EAE /* PBXTargetDependency */, DC3502C41E020D4D00BC0587 /* PBXTargetDependency */, DC3502CE1E020E2200BC0587 /* PBXTargetDependency */, DC0984F71E1DB6D400140ADC /* PBXTargetDependency */, DC0985001E1DB70A00140ADC /* PBXTargetDependency */, DC3502D51E02117600BC0587 /* PBXTargetDependency */, - DC222C791E034EE700B09171 /* PBXTargetDependency */, ); name = CKKSTests; productName = CKKSTests; productReference = DC3502B51E0208BE00BC0587 /* CKKSTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + DC36895D21235F42003A3735 /* aks_mock */ = { + isa = PBXNativeTarget; + buildConfigurationList = DC36895F21235F42003A3735 /* Build configuration list for PBXNativeTarget "aks_mock" */; + buildPhases = ( + DC36895A21235F42003A3735 /* Headers */, + DC36895B21235F42003A3735 /* Sources */, + DC36895C21235F42003A3735 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = aks_mock; + productName = mockaks; + productReference = DC36895E21235F42003A3735 /* libaks_mock.a */; + productType = "com.apple.product-type.library.static"; + }; DC3A4B571D91E9FB00E46D4A /* CodeSigningHelper */ = { isa = PBXNativeTarget; buildConfigurationList = DC3A4B5B1D91E9FB00E46D4A /* Build configuration list for PBXNativeTarget "CodeSigningHelper" */; @@ -25517,9 +29741,9 @@ DC52E7AE1D80BC8000B0A59C /* Headers */, ); buildRules = ( - DC9FD3201F85818000C8AAC8 /* PBXBuildRule */, ); dependencies = ( + DCE0777E21ADEADA002662FD /* PBXTargetDependency */, ); name = libsecurityd_ios; productName = libsecurity; @@ -25543,40 +29767,6 @@ productReference = DC52E8C61D80C25800B0A59C /* libSecureObjectSyncServer.a */; productType = "com.apple.product-type.library.static"; }; - DC52EA441D80CB7000B0A59C /* SecurityTool */ = { - isa = PBXNativeTarget; - buildConfigurationList = DC52EA491D80CB7000B0A59C /* Build configuration list for PBXNativeTarget "SecurityTool" */; - buildPhases = ( - DC52EA451D80CB7000B0A59C /* Sources */, - DC52EA471D80CB7000B0A59C /* Frameworks */, - DC52EA481D80CB7000B0A59C /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = SecurityTool; - productName = libsecurity; - productReference = DC52EA4C1D80CB7000B0A59C /* libSecurityTool.a */; - productType = "com.apple.product-type.library.static"; - }; - DC52EBC61D80CEF100B0A59C /* SecurityCommands */ = { - isa = PBXNativeTarget; - buildConfigurationList = DC52EBD21D80CEF100B0A59C /* Build configuration list for PBXNativeTarget "SecurityCommands" */; - buildPhases = ( - DC52EBC71D80CEF100B0A59C /* Sources */, - DC52EBCF1D80CEF100B0A59C /* Frameworks */, - DC52EBD11D80CEF100B0A59C /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = SecurityCommands; - productName = libsecurity; - productReference = DC52EBD51D80CEF100B0A59C /* libSecurityCommands.a */; - productType = "com.apple.product-type.library.static"; - }; DC52EC211D80CFB200B0A59C /* SOSCommands */ = { isa = PBXNativeTarget; buildConfigurationList = DC52EC311D80CFB200B0A59C /* Build configuration list for PBXNativeTarget "SOSCommands" */; @@ -25744,7 +29934,6 @@ dependencies = ( DC65E7391D8CB38300152EF0 /* PBXTargetDependency */, DC65E73B1D8CB39300152EF0 /* PBXTargetDependency */, - DC58C42A1D77BE03003C25A4 /* PBXTargetDependency */, ); name = csparser_osx; productName = csparser; @@ -25777,13 +29966,16 @@ DC5AC0D71D83548B00CF422C /* Headers */, DC5AC04C1D8352D900CF422C /* Sources */, DC5AC04D1D8352D900CF422C /* Frameworks */, - DC5AC04E1D8352D900CF422C /* CopyFiles */, + DC5AC04E1D8352D900CF422C /* Man pages */, + 6C23F02E227A39FD009F6756 /* Install Sandbox Profile */, ); buildRules = ( ); dependencies = ( + D4E0E9CB2224FB5700A802E0 /* PBXTargetDependency */, DC5AC0BF1D83534300CF422C /* PBXTargetDependency */, DC5AC0BD1D83533E00CF422C /* PBXTargetDependency */, + DCF19A6E21AE2CDC002E808F /* PBXTargetDependency */, DC6BC27B1D90D11C00DD57B3 /* PBXTargetDependency */, DC008B5A1D90CEC7004002A3 /* PBXTargetDependency */, DC6BC2741D90D07800DD57B3 /* PBXTargetDependency */, @@ -25891,29 +30083,28 @@ productReference = DC6A82921D87749900418608 /* libsecurityd_client.a */; productType = "com.apple.product-type.library.static"; }; - DC71D99F1D95BA6C0065FB93 /* ASN1 */ = { + DC7FC44721EE914C003C39B8 /* FeatureFlagsPlist */ = { isa = PBXNativeTarget; - buildConfigurationList = DC71D9DC1D95BA6C0065FB93 /* Build configuration list for PBXNativeTarget "ASN1" */; + buildConfigurationList = DC7FC44C21EE914D003C39B8 /* Build configuration list for PBXNativeTarget "FeatureFlagsPlist" */; buildPhases = ( - DC71D9FE1D95BB5B0065FB93 /* Why is this here? */, - DC71D9A01D95BA6C0065FB93 /* Headers */, - DC71D9C31D95BA6C0065FB93 /* Sources */, - DC71D9DB1D95BA6C0065FB93 /* Frameworks */, + DC7FC44421EE914C003C39B8 /* Sources */, + DC7FC44521EE914C003C39B8 /* Frameworks */, + DC7FC44621EE914C003C39B8 /* Resources */, + DC7FC44F21EE9175003C39B8 /* Install Security FeatureFlags plist */, ); buildRules = ( ); dependencies = ( ); - name = ASN1; - productName = libsecurityd_client_macos; - productReference = DC71D9DF1D95BA6C0065FB93 /* libASN1.a */; - productType = "com.apple.product-type.library.static"; + name = FeatureFlagsPlist; + productName = FeatureFlagsPlist; + productReference = DC7FC44821EE914C003C39B8 /* FeatureFlagsPlist.bundle */; + productType = "com.apple.product-type.bundle"; }; - DC8834011D8A218F00CE0ACA /* ASN1_not_installed */ = { + DC8834011D8A218F00CE0ACA /* ASN1 */ = { isa = PBXNativeTarget; - buildConfigurationList = DC8834051D8A218F00CE0ACA /* Build configuration list for PBXNativeTarget "ASN1_not_installed" */; + buildConfigurationList = DC8834051D8A218F00CE0ACA /* Build configuration list for PBXNativeTarget "ASN1" */; buildPhases = ( - DC71D9FF1D95BCDF0065FB93 /* Why is this here? */, DC8834021D8A218F00CE0ACA /* Headers */, DC8834031D8A218F00CE0ACA /* Sources */, DC8834041D8A218F00CE0ACA /* Frameworks */, @@ -25922,11 +30113,34 @@ ); dependencies = ( ); - name = ASN1_not_installed; + name = ASN1; productName = libsecurityd_client_macos; - productReference = DC8834081D8A218F00CE0ACA /* libASN1_not_installed.a */; + productReference = DC8834081D8A218F00CE0ACA /* libASN1.a */; productType = "com.apple.product-type.library.static"; }; + DC99B85B20EACA470065B73B /* OctagonTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DC99B88F20EACA470065B73B /* Build configuration list for PBXNativeTarget "OctagonTests" */; + buildPhases = ( + DC99B86A20EACA470065B73B /* Sources */, + DC99B87A20EACA470065B73B /* Frameworks */, + DC99B88E20EACA470065B73B /* Resources */, + DCEA0FF9213F1F410054A328 /* Generate BATS Plist */, + ); + buildRules = ( + ); + dependencies = ( + DC6063B021B0755D00069B82 /* PBXTargetDependency */, + DC60133D214722C900863C1A /* PBXTargetDependency */, + DC99B85C20EACA470065B73B /* PBXTargetDependency */, + DC99B86220EACA470065B73B /* PBXTargetDependency */, + DC99B86420EACA470065B73B /* PBXTargetDependency */, + ); + name = OctagonTests; + productName = TrustedPeersHelperUnitTests; + productReference = DC99B89220EACA470065B73B /* OctagonTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; DCB340661D8A24DF0054D16E /* security_authorization */ = { isa = PBXNativeTarget; buildConfigurationList = DCB3406A1D8A24DF0054D16E /* Build configuration list for PBXNativeTarget "security_authorization" */; @@ -26030,6 +30244,29 @@ productReference = DCB3443E1D8A34FD0054D16E /* libsecurity_keychain_regressions.a */; productType = "com.apple.product-type.library.static"; }; + DCBF4A8A21FFC82100539F0A /* SecEscrowRequestTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = DCBF4ADD21FFC82100539F0A /* Build configuration list for PBXNativeTarget "SecEscrowRequestTests" */; + buildPhases = ( + DCBF4A9921FFC82100539F0A /* Sources */, + DCBF4AC021FFC82100539F0A /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + DCBF4A8B21FFC82100539F0A /* PBXTargetDependency */, + DCBF4A8D21FFC82100539F0A /* PBXTargetDependency */, + DCBF4A8F21FFC82100539F0A /* PBXTargetDependency */, + DCBF4A9121FFC82100539F0A /* PBXTargetDependency */, + DCBF4A9321FFC82100539F0A /* PBXTargetDependency */, + DCBF4A9521FFC82100539F0A /* PBXTargetDependency */, + DCBF4A9721FFC82100539F0A /* PBXTargetDependency */, + ); + name = SecEscrowRequestTests; + productName = CKKSTests; + productReference = DCBF4AE021FFC82100539F0A /* SecEscrowRequestTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; DCC78EA81D8088E200865A7C /* security */ = { isa = PBXNativeTarget; buildConfigurationList = DCC78EAF1D8088E200865A7C /* Build configuration list for PBXNativeTarget "security" */; @@ -26205,13 +30442,12 @@ buildRules = ( ); dependencies = ( + DCDA5E642124BCA9009B11B2 /* PBXTargetDependency */, DC71D8EB1D959C130065FB93 /* PBXTargetDependency */, DC71D8E41D959C000065FB93 /* PBXTargetDependency */, DC00AB921D821D6000513D74 /* PBXTargetDependency */, DC71DA0D1D95DD670065FB93 /* PBXTargetDependency */, DCD8A2031E09FAE500E4FA0A /* PBXTargetDependency */, - DC00AB941D821D6500513D74 /* PBXTargetDependency */, - DC00AB961D821D6800513D74 /* PBXTargetDependency */, ); name = security2tool_macos; productName = security; @@ -26237,8 +30473,7 @@ DC2671101F3E933700816EED /* PBXTargetDependency */, DC52EE631D80D7D900B0A59C /* PBXTargetDependency */, DCB345B31D8A361F0054D16E /* PBXTargetDependency */, - DC63CAFA1D91A16700C03317 /* PBXTargetDependency */, - DCE4E7BC1D7A45ED00AFB96E /* PBXTargetDependency */, + D437185B211670F600EA350A /* PBXTargetDependency */, ACBAF6FE1E941E090007BA2F /* PBXTargetDependency */, DC0BCA781D8B830900070CB0 /* PBXTargetDependency */, DC65E7521D8CB45300152EF0 /* PBXTargetDependency */, @@ -26260,8 +30495,6 @@ dependencies = ( DC65E7661D8CB4C200152EF0 /* PBXTargetDependency */, DC65E7681D8CB4CB00152EF0 /* PBXTargetDependency */, - DCE4E7D81D7A4B3500AFB96E /* PBXTargetDependency */, - DC193C6020CB4C9D009C1A0F /* PBXTargetDependency */, DC65E76A1D8CB4D300152EF0 /* PBXTargetDependency */, ); name = sectests_macos; @@ -26283,7 +30516,8 @@ buildRules = ( ); dependencies = ( - DCD8A2071E09FB1F00E4FA0A /* PBXTargetDependency */, + DCDA5E5C2124BA54009B11B2 /* PBXTargetDependency */, + DC7FC45421EE921A003C39B8 /* PBXTargetDependency */, DC71DA031D95BDEA0065FB93 /* PBXTargetDependency */, DC00AB721D821C4600513D74 /* PBXTargetDependency */, DC00AB741D821C4800513D74 /* PBXTargetDependency */, @@ -26377,6 +30611,24 @@ productReference = DCE4E9111D7F3D5300AFB96E /* Keychain Circle Notification.app */; productType = "com.apple.product-type.application"; }; + DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */ = { + isa = PBXNativeTarget; + buildConfigurationList = DCF216DC21ADD5B10029CCC1 /* Build configuration list for PBXNativeTarget "protobuf_source_generation" */; + buildPhases = ( + DCF216D321ADD5B10029CCC1 /* Headers */, + DCF216D421ADD5B10029CCC1 /* Sources */, + DCF216D521ADD5B10029CCC1 /* Frameworks */, + ); + buildRules = ( + DCF216DD21ADD5D10029CCC1 /* PBXBuildRule */, + ); + dependencies = ( + ); + name = protobuf_source_generation; + productName = protobuf_source_generation; + productReference = DCF216D721ADD5B10029CCC1 /* libprotobuf_source_generation.a */; + productType = "com.apple.product-type.library.static"; + }; DCF7830A1D88B4DE00E694BB /* security_apple_csp */ = { isa = PBXNativeTarget; buildConfigurationList = DCF783111D88B4DE00E694BB /* Build configuration list for PBXNativeTarget "security_apple_csp" */; @@ -26499,6 +30751,61 @@ productReference = DCF788D61D88CD2400E694BB /* libsecurity_apple_x509_tp.a */; productType = "com.apple.product-type.library.static"; }; + E060D19B2124780E0025B833 /* OctagonTestHarness */ = { + isa = PBXNativeTarget; + buildConfigurationList = E060D1D2212478120025B833 /* Build configuration list for PBXNativeTarget "OctagonTestHarness" */; + buildPhases = ( + E060D1972124780E0025B833 /* Headers */, + E060D1982124780E0025B833 /* Sources */, + E060D1992124780E0025B833 /* Frameworks */, + E060D1D0212478120025B833 /* Embed Frameworks */, + E060D1D1212478120025B833 /* Embed XPC Services */, + ); + buildRules = ( + ); + dependencies = ( + E060D1AB212478100025B833 /* PBXTargetDependency */, + E060D1BA212478120025B833 /* PBXTargetDependency */, + ); + name = OctagonTestHarness; + productName = OctagonTestHarness; + productReference = E060D19C2124780E0025B833 /* OctagonTestHarness.framework */; + productType = "com.apple.product-type.framework"; + }; + E060D1A62124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol */ = { + isa = PBXNativeTarget; + buildConfigurationList = E060D1CA212478120025B833 /* Build configuration list for PBXNativeTarget "OctagonTestHarnessXPCServiceProtocol" */; + buildPhases = ( + E060D1A22124780F0025B833 /* Headers */, + E060D1A32124780F0025B833 /* Sources */, + E060D1A42124780F0025B833 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OctagonTestHarnessXPCServiceProtocol; + productName = OctagonTestHarnessXPCServiceProtocol; + productReference = E060D1A72124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol.framework */; + productType = "com.apple.product-type.framework"; + }; + E060D1B6212478110025B833 /* OctagonTestHarnessXPCService */ = { + isa = PBXNativeTarget; + buildConfigurationList = E060D1CD212478120025B833 /* Build configuration list for PBXNativeTarget "OctagonTestHarnessXPCService" */; + buildPhases = ( + E060D1B3212478110025B833 /* Sources */, + E060D1B4212478110025B833 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + E060D1BC212478120025B833 /* PBXTargetDependency */, + ); + name = OctagonTestHarnessXPCService; + productName = OctagonTestHarnessXPCService; + productReference = E060D1B7212478110025B833 /* OctagonTestHarnessXPCService.xpc */; + productType = "com.apple.product-type.xpc-service"; + }; E710C7411331946400F85568 /* SecurityTests */ = { isa = PBXNativeTarget; buildConfigurationList = E710C75C1331946500F85568 /* Build configuration list for PBXNativeTarget "SecurityTests" */; @@ -26514,6 +30821,7 @@ buildRules = ( ); dependencies = ( + D4E0E9C72224E76100A802E0 /* PBXTargetDependency */, DC00ABBB1D821E9B00513D74 /* PBXTargetDependency */, DC00ABBD1D821E9F00513D74 /* PBXTargetDependency */, DCD8A1F51E09F91F00E4FA0A /* PBXTargetDependency */, @@ -26563,6 +30871,7 @@ buildRules = ( ); dependencies = ( + 0C604F0221B8E5090036C175 /* PBXTargetDependency */, DC65E7221D8CB27900152EF0 /* PBXTargetDependency */, ); name = KeychainCircle; @@ -26583,9 +30892,7 @@ buildRules = ( ); dependencies = ( - E7D847D11C6BE9720025BB44 /* PBXTargetDependency */, - DC00AB9E1D821DBB00513D74 /* PBXTargetDependency */, - DCD8A1F81E09F97300E4FA0A /* PBXTargetDependency */, + DCDA5E622124BAD7009B11B2 /* PBXTargetDependency */, DC65E7401D8CB3CD00152EF0 /* PBXTargetDependency */, DC65E7421D8CB3D400152EF0 /* PBXTargetDependency */, ); @@ -26594,43 +30901,6 @@ 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" */; @@ -26671,14 +30941,10 @@ EB108F251E6CE4D2003B0456 /* Sources */, EB108F2B1E6CE4D2003B0456 /* Frameworks */, EB108F3A1E6CE4D2003B0456 /* Resources */, - EB108F3D1E6CE4D2003B0456 /* chmod BATS Tests */, ); buildRules = ( ); dependencies = ( - EBFBC2B21E76585500A34469 /* PBXTargetDependency */, - EBFBC2B41E76586700A34469 /* PBXTargetDependency */, - EBFBC2B61E76587800A34469 /* PBXTargetDependency */, EB108F1F1E6CE4D2003B0456 /* PBXTargetDependency */, EBFBC2BA1E76588A00A34469 /* PBXTargetDependency */, ); @@ -26764,12 +31030,80 @@ buildRules = ( ); dependencies = ( + DCD6BF5E21E919E10015F7A8 /* PBXTargetDependency */, + DCC7A688216446EB0034967D /* PBXTargetDependency */, + DCC7A686216446E50034967D /* PBXTargetDependency */, + DCC7A684216446D90034967D /* PBXTargetDependency */, + DCC7A682216446D30034967D /* PBXTargetDependency */, + DCC7A67F216435B30034967D /* PBXTargetDependency */, + DCC7A67B216435A40034967D /* PBXTargetDependency */, ); name = secdmockaks; productName = secdmockaks; productReference = EB49B2AE202D877F003F34A0 /* secdmockaks.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + EB69527E223B75C300F02C1C /* secitemd */ = { + isa = PBXNativeTarget; + buildConfigurationList = EB6952B6223B75C300F02C1C /* Build configuration list for PBXNativeTarget "secitemd" */; + buildPhases = ( + EB695289223B75C300F02C1C /* Headers */, + EB69528D223B75C300F02C1C /* Sources */, + EB6952AA223B75C300F02C1C /* Frameworks */, + EB6952B4223B75C300F02C1C /* launchd plist */, + ); + buildRules = ( + ); + dependencies = ( + EB69527F223B75C300F02C1C /* PBXTargetDependency */, + EB695283223B75C300F02C1C /* PBXTargetDependency */, + EB695285223B75C300F02C1C /* PBXTargetDependency */, + EB695287223B75C300F02C1C /* PBXTargetDependency */, + ); + name = secitemd; + productName = securityd; + productReference = EB6952B9223B75C300F02C1C /* secitemd */; + productType = "com.apple.product-type.tool"; + }; + EB74CC152207E48000F1BBAD /* KeychainSettings */ = { + isa = PBXNativeTarget; + buildConfigurationList = EB74CC1A2207E48100F1BBAD /* Build configuration list for PBXNativeTarget "KeychainSettings" */; + buildPhases = ( + EB74CC122207E48000F1BBAD /* Sources */, + EB74CC132207E48000F1BBAD /* Frameworks */, + EB74CC142207E48000F1BBAD /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = KeychainSettings; + productName = KeychainSettings; + productReference = EB74CC162207E48000F1BBAD /* KeychainSettings.bundle */; + productType = "com.apple.product-type.bundle"; + }; + EB89085621F17D3C00F0DDDB /* recovery_securityd */ = { + isa = PBXNativeTarget; + buildConfigurationList = EB89088321F17D3C00F0DDDB /* Build configuration list for PBXNativeTarget "recovery_securityd" */; + buildPhases = ( + EB8908A421F186FE00F0DDDB /* Headers */, + EB89086721F17D3C00F0DDDB /* Sources */, + EB89086F21F17D3C00F0DDDB /* Frameworks */, + EB89087F21F17D3C00F0DDDB /* launchd plist */, + ); + buildRules = ( + ); + dependencies = ( + EB89085721F17D3C00F0DDDB /* PBXTargetDependency */, + EB89085B21F17D3C00F0DDDB /* PBXTargetDependency */, + EB89085D21F17D3C00F0DDDB /* PBXTargetDependency */, + EB89086521F17D3C00F0DDDB /* PBXTargetDependency */, + ); + name = recovery_securityd; + productName = securityd; + productReference = EB89088621F17D3C00F0DDDB /* recovery_securityd */; + productType = "com.apple.product-type.tool"; + }; EB9C1D791BDFD0E000F89272 /* secbackupntest */ = { isa = PBXNativeTarget; buildConfigurationList = EB9C1DA91BDFD0E100F89272 /* Build configuration list for PBXNativeTarget "secbackupntest" */; @@ -26819,6 +31153,23 @@ productReference = EBB839A51E29665D00853BAC /* secfuzzer */; productType = "com.apple.product-type.tool"; }; + EBB851EB22F7912400424FD0 /* SecurityUtilitiesTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = EBB8520822F7912500424FD0 /* Build configuration list for PBXNativeTarget "SecurityUtilitiesTests" */; + buildPhases = ( + EBB851E822F7912400424FD0 /* Sources */, + EBB851E922F7912400424FD0 /* Frameworks */, + EB0F4A2B22F7D3BD009E855B /* Embedd OCMock */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SecurityUtilitiesTests; + productName = SecurityUtilitiesTests; + productReference = EBB851EC22F7912400424FD0 /* SecurityUtilitiesTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; EBCF73F31CE45F9C00BED7CA /* secitemfunctionality */ = { isa = PBXNativeTarget; buildConfigurationList = EBCF73F91CE45F9C00BED7CA /* Build configuration list for PBXNativeTarget "secitemfunctionality" */; @@ -26895,6 +31246,7 @@ 4C35DB69094F906D002917C4 /* Project object */ = { isa = PBXProject; attributes = { + LastSwiftUpdateCheck = 1000; LastUpgradeCheck = 1000; TargetAttributes = { 4381690B1B4EDCBD00C54D58 = { @@ -26930,13 +31282,15 @@ 47C51B831EEA657D0032D9E5 = { CreatedOnToolsVersion = 9.0; }; - 4809F7A42061B697003E72D0 = { - CreatedOnToolsVersion = 10.0; - ProvisioningStyle = Automatic; + 4C32C0AE0A4975F6002891BD = { + LastSwiftMigration = 1000; }; 5EBE24791B00CCAE0007DB0E = { CreatedOnToolsVersion = 7.0; }; + 6C39234421F13E4D00D018AD = { + ProvisioningStyle = Manual; + }; 6C98082C1E788AEB00E70590 = { TestTargetID = 6CF4A0B31E45488B00ECD7B5; }; @@ -26963,6 +31317,20 @@ CreatedOnToolsVersion = 8.3; ProvisioningStyle = Automatic; }; + BEAA002A202A832500E51F45 = { + CreatedOnToolsVersion = 9.3; + LastSwiftMigration = 0930; + }; + BEAA0040202B728B00E51F45 = { + CreatedOnToolsVersion = 9.3; + ProvisioningStyle = Automatic; + }; + BECFA42D20F91AFE00B11002 = { + CreatedOnToolsVersion = 10.0; + }; + BED987D22099145300607A5F = { + CreatedOnToolsVersion = 10.0; + }; BEF88C271EAFFC3F00357577 = { CreatedOnToolsVersion = 9.0; ProvisioningStyle = Automatic; @@ -26981,18 +31349,114 @@ D41AD4311B967179008C7270 = { CreatedOnToolsVersion = 7.0; }; + D42C839721159146008D3D83 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + D44D1F652115893000E76E1A = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + D458C4E0214E1DE00043D982 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + D458C505214E20530043D982 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + D4707A0421136E69005BCFDA = { + CreatedOnToolsVersion = 10.0; + }; + D477EE5C21ED476D00C9AAFF = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D477EE6021ED477B00C9AAFF = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D477EE6421ED479500C9AAFF = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D477EE6821ED47C500C9AAFF = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D477EE6C21ED47DA00C9AAFF = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; D4ADA3181E2B41670031CEA3 = { CreatedOnToolsVersion = 8.3; ProvisioningStyle = Automatic; }; + D4D1D3FC21AD0B3F0012C66C = { + ProvisioningStyle = Automatic; + }; + D4D1D40121AD0B4B0012C66C = { + ProvisioningStyle = Automatic; + }; + D4D1D40821ADC9720012C66C = { + ProvisioningStyle = Automatic; + }; + D4D1FDDB21165F8B003538E2 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + D4F47B3822270B6E003483E9 = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D4F47B3C22270B89003483E9 = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D4F47B4022270B97003483E9 = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + D4F56B86217FA32000FCA6B7 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + D4F56B8D217FA3F800FCA6B7 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + D4F56B91217FA40800FCA6B7 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + D4F56BC221813EC900FCA6B7 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; + }; + D4F56BC621813ECF00FCA6B7 = { + ProvisioningStyle = Automatic; + }; + D4F56BCA21813EDC00FCA6B7 = { + ProvisioningStyle = Automatic; + }; + D4F56BCE21813EE800FCA6B7 = { + ProvisioningStyle = Automatic; + }; DA30D6751DF8C8FB00EC6B43 = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + DA41FE0D2241ADC000838FB3 = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; DC008B451D90CE53004002A3 = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + DC05037521409A4000A8EDB7 = { + CreatedOnToolsVersion = 10.0; + }; DC0BC5501D8B6D2D00070CB0 = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; @@ -27001,6 +31465,10 @@ CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + DC0EF8EE208697C600AB9E95 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; DC1789031D77980500B50D50 = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; @@ -27009,25 +31477,26 @@ CreatedOnToolsVersion = 8.2; ProvisioningStyle = Automatic; }; + DC36895D21235F42003A3735 = { + CreatedOnToolsVersion = 10.0; + }; DC3A4B571D91E9FB00E46D4A = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + DC52E7731D80BC8000B0A59C = { + LastSwiftMigration = 1000; + }; DC58C4221D77BDEA003C25A4 = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; DC5ABDC41D832DAB00CF422C = { CreatedOnToolsVersion = 8.0; - DevelopmentTeam = XPSUQMMH5W; - DevelopmentTeamName = "Apple Inc. - Core OS Plus Others"; ProvisioningStyle = Automatic; }; DC5AC04F1D8352D900CF422C = { CreatedOnToolsVersion = 8.0; - DevelopmentTeam = XPSUQMMH5W; - DevelopmentTeamName = "Apple Inc. - Core OS Plus Others"; - ProvisioningStyle = Automatic; }; DC610A461D78F48F002223DE = { CreatedOnToolsVersion = 8.0; @@ -27037,30 +31506,27 @@ CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + DC7FC44721EE914C003C39B8 = { + CreatedOnToolsVersion = 11.0; + }; DC8E04911D7F6CED006D80EB = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; DCC78EA81D8088E200865A7C = { CreatedOnToolsVersion = 8.0; - DevelopmentTeam = XPSUQMMH5W; - DevelopmentTeamName = "Apple Inc. - Core OS Plus Others"; ProvisioningStyle = Automatic; }; DCD067561D8CDCF3007602F1 = { CreatedOnToolsVersion = 8.0; - DevelopmentTeam = XPSUQMMH5W; ProvisioningStyle = Automatic; }; - DCD0675B1D8CDD6D007602F1 = { - DevelopmentTeam = XPSUQMMH5W; - }; - DCD069661D8CE105007602F1 = { - DevelopmentTeam = XPSUQMMH5W; - }; DCD06A7B1D8CE32F007602F1 = { CreatedOnToolsVersion = 8.0; - DevelopmentTeam = XPSUQMMH5W; + ProvisioningStyle = Automatic; + }; + DCDA5E4F2124B9C5009B11B2 = { + CreatedOnToolsVersion = 10.0; ProvisioningStyle = Automatic; }; DCE4E7CB1D7A4AED00AFB96E = { @@ -27083,10 +31549,26 @@ CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + DCF216D621ADD5B10029CCC1 = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; DCF7889C1D88CB5200E694BB = { CreatedOnToolsVersion = 8.0; ProvisioningStyle = Automatic; }; + E060D19B2124780E0025B833 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + E060D1A62124780F0025B833 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; + E060D1B6212478110025B833 = { + CreatedOnToolsVersion = 10.0; + ProvisioningStyle = Automatic; + }; E74584661BF68EBA001B54A4 = { CreatedOnToolsVersion = 7.1; }; @@ -27099,9 +31581,6 @@ E79EEDD81CD3FFC800C2FBFC = { CreatedOnToolsVersion = 8.0; }; - E79EEDE01CD4000C00C2FBFC = { - CreatedOnToolsVersion = 8.0; - }; E7CFF6471C84F61200E3484E = { CreatedOnToolsVersion = 7.3; }; @@ -27111,14 +31590,6 @@ E7D847CD1C6BE9720025BB44 = { CreatedOnToolsVersion = 7.3; }; - EB056E3D1FE5E390000A771E = { - CreatedOnToolsVersion = 9.3; - ProvisioningStyle = Automatic; - }; - EB05C4F01FE5E48A00D68712 = { - CreatedOnToolsVersion = 9.3; - ProvisioningStyle = Automatic; - }; EB1055741E14DF430003C309 = { CreatedOnToolsVersion = 8.2.1; ProvisioningStyle = Automatic; @@ -27131,14 +31602,16 @@ CreatedOnToolsVersion = 9.3; ProvisioningStyle = Automatic; }; - EB6A6FA81B90F83A0045DC68 = { - CreatedOnToolsVersion = 7.0; - }; EB6A6FAE1B90F8810045DC68 = { CreatedOnToolsVersion = 7.0; }; - EB6A6FB41B90F8C90045DC68 = { - CreatedOnToolsVersion = 7.0; + EB74CC152207E48000F1BBAD = { + CreatedOnToolsVersion = 11.0; + ProvisioningStyle = Automatic; + }; + EB7E90F12193F90700B1FA21 = { + CreatedOnToolsVersion = 10.1; + ProvisioningStyle = Automatic; }; EB9C1D791BDFD0E000F89272 = { CreatedOnToolsVersion = 7.1; @@ -27150,16 +31623,13 @@ CreatedOnToolsVersion = 8.3; ProvisioningStyle = Automatic; }; - EBBE20571C21380100B7A639 = { - CreatedOnToolsVersion = 7.2; + EBB851EB22F7912400424FD0 = { + CreatedOnToolsVersion = 11.0; }; EBF374711DC055580065D840 = { CreatedOnToolsVersion = 8.1; ProvisioningStyle = Automatic; }; - F93C49021AB8FCE00047E01A = { - CreatedOnToolsVersion = 6.3; - }; }; }; buildConfigurationList = 4C35DB6A094F906D002917C4 /* Build configuration list for PBXProject "Security" */; @@ -27179,16 +31649,8 @@ projectDirPath = ""; projectReferences = ( { - ProductGroup = DC1002CC1D8E19F20025549C /* Products */; - ProjectRef = 79BDD3940D60D5F9000D84D3 /* libCMS.xcodeproj */; - }, - { - ProductGroup = DC1002C41D8E19D70025549C /* Products */; - ProjectRef = DC1784AE1D7786C700B50D50 /* libsecurity_cms.xcodeproj */; - }, - { - ProductGroup = DC1784431D77869A00B50D50 /* Products */; - ProjectRef = DC1784421D77869A00B50D50 /* libsecurity_smime.xcodeproj */; + ProductGroup = E058E53321626583002CA574 /* Products */; + ProjectRef = E058E53221626582002CA574 /* OctagonTrieste.xcodeproj */; }, { ProductGroup = DC5AC0AE1D83533400CF422C /* Products */; @@ -27200,18 +31662,36 @@ DC8E04A51D7F6E50006D80EB /* ===== Top-Level Targets ===== */, E79EEDD81CD3FFC800C2FBFC /* Security_frameworks_osx */, 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */, - E7CFF6471C84F61200E3484E /* Security_KeychainCircle */, + D4F56B8D217FA3F800FCA6B7 /* Security_frameworks_tvos */, + D4F56B91217FA40800FCA6B7 /* Security_frameworks_watchos */, + DC6D1C70208A547400AB21AF /* Security_frameworks_bridge */, + D4D1D40821ADC9720012C66C /* Security_executables_core_osx */, + D4F56B86217FA32000FCA6B7 /* Security_executables_core_ios */, + D4D1D3FC21AD0B3F0012C66C /* Security_executables_core_watchos */, + D4D1D40121AD0B4B0012C66C /* Security_executables_core_tvos */, 05EF68BB194915A5007958C3 /* Security_executables_osx */, 4C541F840F250BF500E508AE /* Security_executables_ios */, D41AD4311B967179008C7270 /* Security_executables_tvos */, D41AD42D1B967169008C7270 /* Security_executables_watchos */, EB6A6FAE1B90F8810045DC68 /* Security_executables_bridge */, + D477EE6821ED47C500C9AAFF /* Security_executables_darwinos_only_osx */, + D477EE6C21ED47DA00C9AAFF /* Security_executables_darwinos_only_ios */, + BEAA0040202B728B00E51F45 /* Security_executables_Swift */, + D4F56BC221813EC900FCA6B7 /* Security_internal_osx */, + D4F56BC621813ECF00FCA6B7 /* Security_internal_ios */, + D4F56BCA21813EDC00FCA6B7 /* Security_internal_tvos */, + D4F56BCE21813EE800FCA6B7 /* Security_internal_watchos */, E79EEDA71CD3F87B00C2FBFC /* Security_tests_osx */, E79EEDD21CD3F8AB00C2FBFC /* Security_tests_ios */, - 05EF68C1194915FB007958C3 /* Security_kexts */, - 05EF68AF1949149C007958C3 /* Security_temporary_UI */, - 4C91273D0ADBF46200AF202E /* ios */, - E74584661BF68EBA001B54A4 /* osx */, + D477EE5C21ED476D00C9AAFF /* Security_tests_bridge */, + D477EE6021ED477B00C9AAFF /* Security_tests_tvos */, + D477EE6421ED479500C9AAFF /* Security_tests_watchos */, + E7CFF6471C84F61200E3484E /* Security_KeychainCircle */, + 4C91273D0ADBF46200AF202E /* Security_all_ios */, + E74584661BF68EBA001B54A4 /* Security_all_osx */, + D4F47B3822270B6E003483E9 /* Security_all_watchos */, + D4F47B3C22270B89003483E9 /* Security_all_tvos */, + D4F47B4022270B97003483E9 /* Security_all_bridge */, DC8E04991D7F6D9C006D80EB /* ====== Frameworks ======== */, 4C32C0AE0A4975F6002891BD /* Security_ios */, DC1789031D77980500B50D50 /* Security_osx */, @@ -27221,7 +31701,9 @@ DCE4E8931D7F34F600AFB96E /* authd */, DCE4E7F51D7A4DA800AFB96E /* secd */, 790851B50CA9859F0083CC4D /* securityd_ios */, + EB89085621F17D3C00F0DDDB /* recovery_securityd */, 4718AE02205B39620068EC3F /* securityd_bridge */, + EB69527E223B75C300F02C1C /* secitemd */, DC5AC04F1D8352D900CF422C /* securityd_macos */, 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */, D41257CE1E9410A300781F23 /* trustd_ios */, @@ -27229,16 +31711,15 @@ 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */, DC0BC5501D8B6D2D00070CB0 /* XPCKeychainSandboxCheck */, DC0BC5631D8B6E3D00070CB0 /* XPCTimeStampingService */, + BEAA002A202A832500E51F45 /* TrustedPeersHelper */, + DA41FE0D2241ADC000838FB3 /* otpaird */, DC8E04B11D7F6EC9006D80EB /* ======= Libraries ========= */, DCC78EA81D8088E200865A7C /* security */, DC52E7731D80BC8000B0A59C /* libsecurityd_ios */, 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */, - DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */, D4ADA3181E2B41670031CEA3 /* libtrustd */, DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */, DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */, - DC52EA441D80CB7000B0A59C /* SecurityTool */, - DC52EBC61D80CEF100B0A59C /* SecurityCommands */, DC52EC211D80CFB200B0A59C /* SOSCommands */, DC52EC3E1D80D00800B0A59C /* libSWCAgent */, DC52EC521D80D05200B0A59C /* logging */, @@ -27257,8 +31738,11 @@ DC0BCA131D8B82B000070CB0 /* security_ssl_regressions */, DCD06AA91D8E0D53007602F1 /* security_utilities */, 225394AC1E3080A600D3CD9B /* security_codesigning_ios */, - DC8834011D8A218F00CE0ACA /* ASN1_not_installed */, - DC71D99F1D95BA6C0065FB93 /* ASN1 */, + DC8834011D8A218F00CE0ACA /* ASN1 */, + D44D1F652115893000E76E1A /* CMS */, + DCDA5E4F2124B9C5009B11B2 /* aks_support */, + DC36895D21235F42003A3735 /* aks_mock */, + DC311E6E2124B8A8002F5EAE /* aks_real_witness */, DCF782BA1D88B44300E694BB /* ==== macOS Libraries ====== */, DCF7830A1D88B4DE00E694BB /* security_apple_csp */, DCF785021D88B95500E694BB /* security_apple_cspdl */, @@ -27271,6 +31755,8 @@ DCB3417B1D8A2B860054D16E /* security_cdsa_utilities */, DC0BC5851D8B70E700070CB0 /* security_cdsa_utils */, DC0BC5B01D8B71FD00070CB0 /* security_checkpw */, + D42C839721159146008D3D83 /* security_cms */, + D4D1FDDB21165F8B003538E2 /* security_cms_regressions */, DCD067781D8CDF19007602F1 /* security_codesigning */, DC0BC5E21D8B742200070CB0 /* security_comcryption */, DC0BC5F81D8B752B00070CB0 /* security_cryptkit */, @@ -27297,12 +31783,12 @@ DC58C4221D77BDEA003C25A4 /* csparser_osx */, BE442BA018B7FDB800F24DAE /* swcagent */, 4C52D0B316EFC61E0079966E /* CircleJoinRequested */, - F93C49021AB8FCE00047E01A /* ckcdiagnose.sh */, EBF374711DC055580065D840 /* security-sysdiagnose */, 6C9AA79D1F7C1D8F00D08296 /* supdctl */, EB27FF101E402CD300EC9E3A /* ckksctl */, F621D0271ED6DCE7000EA569 /* authorizationdump */, 0C8BBEFD1FCB446400580909 /* otctl */, + DC0EF8EE208697C600AB9E95 /* tpctl */, DC8E04A11D7F6DFC006D80EB /* ======= Apps ========== */, DCE4E9101D7F3D5300AFB96E /* Keychain Circle Notification */, DCE4E8DC1D7F39DB00AFB96E /* Cloud Keychain Utility */, @@ -27316,6 +31802,7 @@ DCE4E7311D7A43B500AFB96E /* SecurityTestsOSX */, DC3502B41E0208BE00BC0587 /* CKKSTests */, 0C85DFD11FB38BB6000343A7 /* OTTests */, + DC99B85B20EACA470065B73B /* OctagonTests */, 0CF406042072E3E3003D6A7F /* SignInAnalyticsTests_ios */, 0C9AEEAB20783FBB00BF6237 /* SignInAnalyticsTests_osx */, DC610AAD1D7910C3002223DE /* gk_reset_check_macos */, @@ -27352,14 +31839,19 @@ 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 */, + 6C39234421F13E4D00D018AD /* SecDbBackupTests */, + 3DD1FEF5201C07F30086D049 /* SecureTransportTests_macos */, + 3DD1FFAC201FDB1D0086D049 /* SecureTransportTests_ios */, + BED987D22099145300607A5F /* TrustedPeersHelperUnitTests */, + DCBF4A8A21FFC82100539F0A /* SecEscrowRequestTests */, + EBB851EB22F7912400424FD0 /* SecurityUtilitiesTests */, + D458C505214E20530043D982 /* TrustTests */, + D458C4E0214E1DE00043D982 /* TrustTestsRunner_ios */, + D4707A0421136E69005BCFDA /* TrustTests_ios */, + D453A4A42122236D00850A26 /* TrustTests_macos */, DC5AC1351D835D9700CF422C /* ===== Source Gen ===== */, DC008B451D90CE53004002A3 /* securityd_macos_mig */, DC6BC26C1D90CFEF00DD57B3 /* securityd_macos_startup */, @@ -27370,12 +31862,16 @@ DC63CAE81D90D63500C03317 /* libsecurityd_macos_mig */, DCD067561D8CDCF3007602F1 /* codesigning_DTrace */, DCD0675B1D8CDD6D007602F1 /* codesigning_SystemPolicy */, + BECFA42D20F91AFE00B11002 /* tppolicy */, + DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */, DC8E04AD1D7F6E76006D80EB /* ======= misc ========= */, + DC7FC44721EE914C003C39B8 /* FeatureFlagsPlist */, E7B01BBD166594AB000485F1 /* SyncDevTest2 */, 5E10992419A5E55800A60E2B /* ISACLProtectedItems */, 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */, DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */, 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */, + EB74CC152207E48000F1BBAD /* KeychainSettings */, DCD0696B1D8CE1F9007602F1 /* ==== Code Signing ===== */, DCD06A7B1D8CE32F007602F1 /* All Codesigning */, DCD0696F1D8CE21C007602F1 /* integrity */, @@ -27389,4884 +31885,6318 @@ DC8E04A91D7F6E63006D80EB /* === Legacy Targets ===== */, DCF7889C1D88CB5200E694BB /* plugin_apple_x509_cl */, EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */, - EBBE20571C21380100B7A639 /* SecurityFeatures */, - 4C541F950F250C3000E508AE /* phase1 */, - EB6A6FA81B90F83A0045DC68 /* phase1_ios */, - EB6A6FB41B90F8C90045DC68 /* phase2 */, - E79EEDE01CD4000C00C2FBFC /* Security_executables */, - 05EF68B519491512007958C3 /* Security_frameworks */, F667EC561E96E9B100203D5C /* authdtest */, 47C2F1822059CB680062DE30 /* KeychainResources */, 4771D971209A755800BA9772 /* KeychainDataclassOwner */, + DC05037521409A4000A8EDB7 /* OCMockUmbrella */, + E060D19B2124780E0025B833 /* OctagonTestHarness */, + E060D1A62124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol */, + E060D1B6212478110025B833 /* OctagonTestHarnessXPCService */, + EB7E90F12193F90700B1FA21 /* Build C2 Metrics */, + 3D58392D21890FFB000ACA44 /* SecExperimentTests */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - DC1002C91D8E19D70025549C /* libsecurity_cms.a */ = { + DC5AC0B51D83533400CF422C /* securityd_service */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libsecurity_cms.a; - remoteRef = DC1002C81D8E19D70025549C /* PBXContainerItemProxy */; + fileType = "compiled.mach-o.executable"; + path = securityd_service; + remoteRef = DC5AC0B41D83533400CF422C /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + DC5AC0B71D83533400CF422C /* securitydservicectrl */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = securitydservicectrl; + remoteRef = DC5AC0B61D83533400CF422C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC1002CB1D8E19D70025549C /* libsecurity_cms_regressions.a */ = { + DC5AC0B91D83533400CF422C /* libsecuritydservice_client.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; - path = libsecurity_cms_regressions.a; - remoteRef = DC1002CA1D8E19D70025549C /* PBXContainerItemProxy */; + path = libsecuritydservice_client.a; + remoteRef = DC5AC0B81D83533400CF422C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC1002D31D8E19F20025549C /* security_smime */ = { + DC5AC0BB1D83533400CF422C /* com.apple.KeyStore.plugin */ = { isa = PBXReferenceProxy; - fileType = "compiled.mach-o.dylib"; - path = security_smime; - remoteRef = DC1002D21D8E19F20025549C /* PBXContainerItemProxy */; + fileType = wrapper.cfbundle; + path = com.apple.KeyStore.plugin; + remoteRef = DC5AC0BA1D83533400CF422C /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC1002D51D8E19F20025549C /* security_smime.framework */ = { + E058E54B21626583002CA574 /* CloudDeviceTest.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = security_smime.framework; - remoteRef = DC1002D41D8E19F20025549C /* PBXContainerItemProxy */; + path = CloudDeviceTest.framework; + remoteRef = E058E54A21626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC1002D71D8E19F20025549C /* libCMS.a */ = { + E058E54D21626583002CA574 /* CoreDeviceAutomation.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libCMS.a; - remoteRef = DC1002D61D8E19F20025549C /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = CoreDeviceAutomation.framework; + remoteRef = E058E54C21626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC1784491D77869A00B50D50 /* libsecurity_smime.a */ = { + E058E54F21626583002CA574 /* CoreDeviceAutomationFrameworkFacade.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libsecurity_smime.a; - remoteRef = DC1784481D77869A00B50D50 /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = CoreDeviceAutomationFrameworkFacade.framework; + remoteRef = E058E54E21626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC17844B1D77869A00B50D50 /* libsecurity_smime_regressions.a */ = { + E058E55121626583002CA574 /* OctagonTestHarnessXPCServiceProtocol.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libsecurity_smime_regressions.a; - remoteRef = DC17844A1D77869A00B50D50 /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = OctagonTestHarnessXPCServiceProtocol.framework; + remoteRef = E058E55021626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC5AC0B51D83533400CF422C /* securityd_service */ = { + E058E55321626583002CA574 /* OctagonTrieste.framework */ = { isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = securityd_service; - remoteRef = DC5AC0B41D83533400CF422C /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = OctagonTrieste.framework; + remoteRef = E058E55221626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC5AC0B71D83533400CF422C /* securitydservicectrl */ = { + E058E55521626583002CA574 /* OctagonTriesteTests.xctest */ = { isa = PBXReferenceProxy; - fileType = "compiled.mach-o.executable"; - path = securitydservicectrl; - remoteRef = DC5AC0B61D83533400CF422C /* PBXContainerItemProxy */; + fileType = file; + path = OctagonTriesteTests.xctest; + remoteRef = E058E55421626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC5AC0B91D83533400CF422C /* libsecuritydservice_client.a */ = { + E058E55721626583002CA574 /* OpenSSLThreadLock.framework */ = { isa = PBXReferenceProxy; - fileType = archive.ar; - path = libsecuritydservice_client.a; - remoteRef = DC5AC0B81D83533400CF422C /* PBXContainerItemProxy */; + fileType = wrapper.framework; + path = OpenSSLThreadLock.framework; + remoteRef = E058E55621626583002CA574 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E058E55B21626583002CA574 /* SSEClient.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SSEClient.framework; + remoteRef = E058E55A21626583002CA574 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E058E55D21626583002CA574 /* SwiftHTTP.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SwiftHTTP.framework; + remoteRef = E058E55C21626583002CA574 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E058E55F21626583002CA574 /* SwiftLog.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = SwiftLog.framework; + remoteRef = E058E55E21626583002CA574 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + E058E56121626583002CA574 /* os_activity.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = os_activity.framework; + remoteRef = E058E56021626583002CA574 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - DC5AC0BB1D83533400CF422C /* com.apple.KeyStore.plugin */ = { - isa = PBXReferenceProxy; - fileType = wrapper.cfbundle; - path = com.apple.KeyStore.plugin; - remoteRef = DC5AC0BA1D83533400CF422C /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; +/* End PBXReferenceProxy section */ + +/* Begin PBXResourcesBuildPhase section */ + 4381690A1B4EDCBD00C54D58 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4771D970209A755800BA9772 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 47C2F1812059CB680062DE30 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C32C0AB0A4975F6002891BD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D4C263CF1F953019001317EA /* SecDebugErrorMessages.strings in Resources */, + D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */, + 53C0E1FF177FB48A00F8A018 /* CloudKeychain.strings in Resources */, + BE4AC9BA18B8273600B84964 /* SharedWebCredentials.strings in Resources */, + DCEE1E861D93427400DC0EB7 /* com.apple.securityd.plist in Resources */, + EB433A2E1CC325E900A7EACE /* secitemstresstest.entitlements in Resources */, + 475F37201EE8F23900248FB5 /* SFAnalytics.plist in Resources */, + 4C198F220ACDB4BF00AAB142 /* Certificate.strings in Resources */, + 4C198F230ACDB4BF00AAB142 /* OID.strings in Resources */, + D479F6E21F980FAB00388D28 /* Trust.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4C711D7213AFCD0900FE865D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52A23EDD161DEC3F00E271E0 /* Default-568h@2x.png in Resources */, + D4D886E91CEBDD2A00DC7583 /* nist-certs in Resources */, + BE9B8B4B202BB4D10081EF87 /* si-88-sectrust-valid-data in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 534647FF17331E1100FE9172 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5346480817331E1200FE9172 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 5E10992319A5E55800A60E2B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 5E10995119A5E5CE00A60E2B /* ISProtectedItems.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6C98085D1E788AEB00E70590 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6C9808991E788AFD00E70590 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CF4A0B21E45488B00ECD7B5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 6CF4A0DE1E4549F200ECD7B5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BE197F2419116FD100BA91D1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BE197F61191173F200BA91D1 /* entitlements.plist in Resources */, + BE197F2C19116FD100BA91D1 /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BEAA0029202A832500E51F45 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BED987D12099145300607A5F /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BEF88C261EAFFC3F00357577 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BEF88C2E1EAFFC3F00357577 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D453A4BB2122236D00850A26 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D4B2966B22DBFDD300DCF250 /* TestCopyProperties_ios-data in Resources */, + D4D92DA9227890500009A7CF /* nist-certs in Resources */, + D4056A2022712D750026E24E /* ssl-policy-certs in Resources */, + D4AC8BEF213212A7006E9871 /* si-18-certificate-parse in Resources */, + D458C51A214E2CC80043D982 /* si-20-sectrust-policies-data in Resources */, + D453A4BC2122236D00850A26 /* si-82-sectrust-ct-data in Resources */, + D4FD4226217D7C41002B7EE2 /* si-87-sectrust-name-constraints in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D458C4DF214E1DE00043D982 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D458C51F214E2E0C0043D982 /* Main.storyboard in Resources */, + D458C51C214E2DEB0043D982 /* Assets.xcassets in Resources */, + D458C51D214E2DEB0043D982 /* Base.lproj in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D4707A0321136E69005BCFDA /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D4B2966A22DBFDC700DCF250 /* TestCopyProperties_ios-data in Resources */, + D4D92DA8227890500009A7CF /* nist-certs in Resources */, + D4056A1F22712D750026E24E /* ssl-policy-certs in Resources */, + D4AC8BEE21321291006E9871 /* si-18-certificate-parse in Resources */, + D458C517214E2C690043D982 /* si-20-sectrust-policies-data in Resources */, + D4A0F8C2211E6A2F00443CA1 /* si-82-sectrust-ct-data in Resources */, + D4FD4227217D7C4F002B7EE2 /* si-87-sectrust-name-constraints in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DA30D6741DF8C8FB00EC6B43 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC05037421409A4000A8EDB7 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC0BC54F1D8B6D2D00070CB0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC0BC5681D8B6E3D00070CB0 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC1789021D77980500B50D50 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DC178A421D77A1F600B50D50 /* FDEPrefs.plist in Resources */, + DC178A471D77A1F600B50D50 /* InfoPlist.strings in Resources */, + DC178A241D77A1E700B50D50 /* cspdl_common.mdsinfo in Resources */, + DC178A2B1D77A1E700B50D50 /* cl_primary.mdsinfo in Resources */, + DC178A451D77A1F600B50D50 /* framework.sb in Resources */, + DC178A2D1D77A1E700B50D50 /* tp_policyOids.mdsinfo in Resources */, + DC178A231D77A1E700B50D50 /* csp_primary.mdsinfo in Resources */, + DC178A251D77A1E700B50D50 /* cspdl_csp_capabilities.mdsinfo in Resources */, + DC178A281D77A1E700B50D50 /* dl_common.mdsinfo in Resources */, + DC178A441D77A1F600B50D50 /* SecErrorMessages.strings in Resources */, + DC178A1F1D77A1E700B50D50 /* cssm.mdsinfo in Resources */, + DC178A4B1D77A1F600B50D50 /* authorization.prompts.strings in Resources */, + DC178A2E1D77A1E700B50D50 /* tp_primary.mdsinfo in Resources */, + DC178A211D77A1E700B50D50 /* csp_capabilities_common.mds in Resources */, + DC178A2A1D77A1E700B50D50 /* cl_common.mdsinfo in Resources */, + DC178A271D77A1E700B50D50 /* cspdl_dl_primary.mdsinfo in Resources */, + DC178A4A1D77A1F600B50D50 /* authorization.buttons.strings in Resources */, + DC178A2F1D77A1E700B50D50 /* sd_cspdl_common.mdsinfo in Resources */, + DC178A291D77A1E700B50D50 /* dl_primary.mdsinfo in Resources */, + DC178A261D77A1E700B50D50 /* cspdl_csp_primary.mdsinfo in Resources */, + 475F37211EE8F23900248FB5 /* SFAnalytics.plist in Resources */, + DC178A221D77A1E700B50D50 /* csp_common.mdsinfo in Resources */, + DC178A431D77A1F600B50D50 /* SecDebugErrorMessages.strings in Resources */, + DC178A481D77A1F600B50D50 /* TimeStampingPrefs.plist in Resources */, + DC178A201D77A1E700B50D50 /* csp_capabilities.mdsinfo in Resources */, + DC178A2C1D77A1E700B50D50 /* tp_common.mdsinfo in Resources */, + DC178A491D77A1F600B50D50 /* authorization.dfr.prompts.strings in Resources */, + D479F6E31F981FD600388D28 /* OID.strings in Resources */, + D479F6E41F981FD600388D28 /* Certificate.strings in Resources */, + D479F6E51F981FD600388D28 /* Trust.strings in Resources */, + DC1789E91D77A0F300B50D50 /* CloudKeychain.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC3A4B561D91E9FB00E46D4A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC58C4211D77BDEA003C25A4 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC7FC44621EE914C003C39B8 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC99B88E20EACA470065B73B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCE4E76B1D7A43B500AFB96E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCE4E76D1D7A43B500AFB96E /* nist-certs in Resources */, + BE9B8B4D202BB4F30081EF87 /* si-88-sectrust-valid-data in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCE4E8921D7F34F600AFB96E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCE4E8DB1D7F39DB00AFB96E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCE4E9081D7F3A4800AFB96E /* Icon.icns in Resources */, + DCE4E90A1D7F3A4800AFB96E /* Credits.rtf in Resources */, + DCE4E9091D7F3A4800AFB96E /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCE4E90F1D7F3D5300AFB96E /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCE4E9491D7F3E8E00AFB96E /* Localizable.strings in Resources */, + DCE4E94A1D7F3E8E00AFB96E /* com.apple.security.keychain-circle-notification.plist in Resources */, + DCE4E94B1D7F3E8E00AFB96E /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DCF7889B1D88CB5200E694BB /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DCF788A71D88CB7400E694BB /* cl_primary.mdsinfo in Resources */, + DCF788A61D88CB7000E694BB /* cl_common.mdsinfo in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E710C7401331946400F85568 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 52A23EDC161DEC3800E271E0 /* Default-568h@2x.png in Resources */, + D4D886EA1CEBDE0800DC7583 /* nist-certs in Resources */, + BE9B8B4C202BB4E30081EF87 /* si-88-sectrust-valid-data in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7B01BE3166594AB000485F1 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7D847C31C6BE9710025BB44 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7D847CC1C6BE9720025BB44 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB108F3A1E6CE4D2003B0456 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB74CC142207E48000F1BBAD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB74CC282207EE4300F1BBAD /* KeychainSettings.plist in Resources */, + EB74CC2F2207FBF600F1BBAD /* KeychainSettingsOctagonPeers.plist in Resources */, + EBB02A6A2220649F007241CB /* KeychainSettingsCKKSViews.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 090585D020AEF9D300BB7490 /* 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"; + }; + 090585D120AEF9FE00BB7490 /* 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"; + }; + 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + 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\n"; + }; + 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\n"; + }; + 3DD1FFCC201FDB1D0086D049 /* 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"; + }; + 6C7E8F2121F7BE7F008A2D56 /* Chown BATS Test Discovery Plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Chown BATS Test Discovery Plist"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\n chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist\n"; + }; + 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = { + 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\"\n"; + }; + 8E64DB4E1C18A5B80076C9DF /* Install launchd plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "$(PROJECT_DIR)/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.ios.plist", + "$(PROJECT_DIR)/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist", + ); + name = "Install launchd plist"; + outputPaths = ( + "$(INSTALL_ROOT)/$(INSTALL_DAEMON_AGENT_DIR)/com.apple.security.cloudkeychainproxy3.plist", + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "PLIST_FILE_NAME=com.apple.security.cloudkeychainproxy3\nFILE_TO_COPY=${PROJECT_DIR}/KVSKeychainSyncingProxy/${PLIST_FILE_NAME}.ios.plist\n\nif [ ${PLATFORM_NAME} = \"macosx\" ]\nthen\nFILE_TO_COPY=${PROJECT_DIR}/KVSKeychainSyncingProxy/${PLIST_FILE_NAME}.osx.plist\nfi\n\ncp ${FILE_TO_COPY} ${INSTALL_ROOT}/${INSTALL_DAEMON_AGENT_DIR}/${PLIST_FILE_NAME}.plist\n"; + }; + D4428B432122718400EB8448 /* Generate BATS Plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Generate BATS Plist"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\n TRUSTTESTS_DIR=${SRCROOT}/tests/TrustTests\n \n python ${TRUSTTESTS_DIR}/gen_test_plist.py ${TRUSTTESTS_DIR} ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/TrustTests.plist\n chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist\n"; + }; + D4428B46212271E400EB8448 /* Generate BATS Plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Generate BATS Plist"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\n TRUSTTESTS_DIR=${SRCROOT}/tests/TrustTests\n \n python ${TRUSTTESTS_DIR}/gen_test_plist.py ${TRUSTTESTS_DIR} ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/TrustTests.plist\n chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist\n"; + }; + D442AD70215C39100050B50F /* Install Apple Corporate Roots */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "$(SRCROOT)/OSX/trustd/iOS/AppleCorporateRootCA.cer", + "$(SRCROOT)/OSX/trustd/iOS/AppleCorporateRootCA2.cer", + ); + name = "Install Apple Corporate Roots"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DSTROOT)/AppleInternal/Library/Security/AppleCorporateRootCA.cer", + "$(DSTROOT)/AppleInternal/Library/Security/AppleCorporateRootCA2.cer", + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "ditto ${SRCROOT}/OSX/trustd/iOS/AppleCorporateRootCA.cer ${DSTROOT}/AppleInternal/Library/Security/\nditto ${SRCROOT}/OSX/trustd/iOS/AppleCorporateRootCA2.cer ${DSTROOT}/AppleInternal/Library/Security/\nchown -R root:wheel ${DSTROOT}/AppleInternal/Library/Security/\n"; }; -/* End PBXReferenceProxy section */ - -/* Begin PBXResourcesBuildPhase section */ - 4381690A1B4EDCBD00C54D58 /* Resources */ = { - isa = PBXResourcesBuildPhase; + D4C263C41F8FEAA8001317EA /* Run Script Generate Error Strings */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/CSCommon.h", + ); + name = "Run Script Generate Error Strings"; + outputPaths = ( + "${BUILT_PRODUCTS_DIR}/derived_src/SecDebugErrorMessages.strings", + "${BUILT_PRODUCTS_DIR}/derived_src/en.lproj/SecErrorMessages.strings", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -x\n\nDERIVED_SRC=\"${BUILT_PRODUCTS_DIR}/derived_src\"\nmkdir -p \"${DERIVED_SRC}\"\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=\"${DERIVED_SRC}/SecDebugErrorMessages.strings\"\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=\"${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\"\n\nmkdir -p \"${DERIVED_SRC}/en.lproj\"\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n\"${GENDEBUGSTRS[ix]}\" \\\n\"${DERIVED_SRC}\" \\\n\"${ERRORSTRINGS[ix]}\" \\\n\"${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h\" \\\n\"${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h\" \\\n\"${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/CSCommon.h\"\ndone\n"; }; - 4771D970209A755800BA9772 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; + D4E0E9C32224E18900A802E0 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; files = ( ); - runOnlyForDeploymentPostprocessing = 0; + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "# alias/target to be obsoleted\nmkdir -p ${DSTROOT}/AppleInternal/CoreOS/Security/\necho \"shut up now\" > ${DSTROOT}/AppleInternal/CoreOS/Security/Security_KeychainCircle_quiet_verifier.txt\n"; + showEnvVarsInLog = 0; }; - 47C2F1812059CB680062DE30 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; + DA41FE162241AE9100838FB3 /* Install launchd plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; files = ( ); - runOnlyForDeploymentPostprocessing = 0; + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Install launchd plist"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "set -e\nset -x\n\nmkdir -p ${DSTROOT}${SYSTEM_LIBRARY_DIR}/NanoLaunchDaemons\nplutil -convert binary1 -o ${DSTROOT}${SYSTEM_LIBRARY_DIR}/NanoLaunchDaemons/com.apple.security.otpaird.plist ${SRCROOT}/keychain/otpaird/${OTPAIRD_LAUNCHD_PLIST}\n"; }; - 47C51B821EEA657D0032D9E5 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC008B581D90CE70004002A3 /* securityd mig */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - D465131A2097FF2E005D93FE /* Main.storyboard in Resources */, - D465131B2097FF2E005D93FE /* Assets.xcassets in Resources */, - D465131C2097FF2E005D93FE /* LaunchScreen.storyboard in Resources */, + ); + inputPaths = ( + "$(SRCROOT)/securityd/mig/self.defs", + ); + name = "securityd mig"; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/derived_src/self.h", + "$(BUILT_PRODUCTS_DIR)/derived_src/selfUser.cpp", + "$(BUILT_PRODUCTS_DIR)/derived_src/selfServer.cpp", ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "mkdir -p ${BUILT_PRODUCTS_DIR}/derived_src\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/selfServer.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/selfUser.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/self.h \\\n${SRCROOT}/securityd/mig/self.defs\n"; }; - 4C32C0AB0A4975F6002891BD /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC0BC5BF1D8B725C00070CB0 /* Install PAM Config */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "${PROJECT_DIR}/OSX/libsecurity_checkpw/checkpw.pam", + ); + name = "Install PAM Config"; + outputPaths = ( + "${DSTROOT}/private/etc/pam.d/checkpw.pam", + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "name=checkpw\n\nmkdir -p \"${DSTROOT}/private/etc/pam.d/\"\ncp \"${PROJECT_DIR}/OSX/libsecurity_checkpw/checkpw.pam\" \"${DSTROOT}/private/etc/pam.d/${name}\""; + }; + DC1789A71D779E7E00B50D50 /* Run Script Generate Strings */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - D4C263CF1F953019001317EA /* SecDebugErrorMessages.strings in Resources */, - D4C263CE1F95300F001317EA /* SecErrorMessages.strings in Resources */, - 47922D4F1FAA7D5C0008F7E0 /* SecDbKeychainSerializedItemV7.proto in Resources */, - 53C0E1FF177FB48A00F8A018 /* CloudKeychain.strings in Resources */, - BE4AC9BA18B8273600B84964 /* SharedWebCredentials.strings in Resources */, - DCEE1E861D93427400DC0EB7 /* com.apple.securityd.plist in Resources */, - 47922D211FAA76000008F7E0 /* SecDbKeychainSerializedMetadata.proto in Resources */, - EB433A2E1CC325E900A7EACE /* secitemstresstest.entitlements in Resources */, - 47922D2D1FAA77970008F7E0 /* SecDbKeychainSerializedSecretData.proto in Resources */, - 475F37201EE8F23900248FB5 /* SFAnalytics.plist in Resources */, - 4C198F220ACDB4BF00AAB142 /* Certificate.strings in Resources */, - 4C198F230ACDB4BF00AAB142 /* OID.strings in Resources */, - D479F6E21F980FAB00388D28 /* Trust.strings in Resources */, + ); + inputPaths = ( + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h", + "${PROJECT_DIR}/libsecurity_keychain/lib/MacOSErrorStrings.h", + "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h", + ); + name = "Run Script Generate Strings"; + outputPaths = ( + "${BUILT_PRODUCTS_DIR}/derived_src/SecDebugErrorMessages.strings", + "${BUILT_PRODUCTS_DIR}/derived_src/en.lproj/SecErrorMessages.strings", ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -x\n\nDERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/en.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h \\\n${PROJECT_DIR}/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h\ndone\n"; }; - 4C711D7213AFCD0900FE865D /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC178B481D77A51600B50D50 /* Make XPC server symlink */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 52A23EDD161DEC3F00E271E0 /* Default-568h@2x.png in Resources */, - D4D886E91CEBDD2A00DC7583 /* nist-certs in Resources */, - D4D886BF1CEB9F3B00DC7583 /* ssl-policy-certs in Resources */, - D4AA64861E97273D00D317ED /* si-18-certificate-parse in Resources */, - D4EC94FB1CEA482D0083E753 /* si-20-sectrust-policies-data in Resources */, - 0C0C88781CCEC5C400617D1B /* si-82-sectrust-ct-data in Resources */, - D4C6C5CA1FB2AD7A007EA57E /* si-87-sectrust-name-constraints in Resources */, - BEA74217202525DC00EC7993 /* si-88-sectrust-valid-data in Resources */, + ); + inputPaths = ( + ); + name = "Make XPC server symlink"; + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if [ ! -h ${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/XPCServices ]; then\n ln -s Versions/Current/XPCServices ${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/XPCServices\nfi\n\nexit 0\n"; }; - 534647FF17331E1100FE9172 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC58C4381D77BE5E003C25A4 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 5346480817331E1200FE9172 /* InfoPlist.strings in Resources */, + ); + inputPaths = ( + ); + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd ${BUILT_PRODUCTS_DIR}/Security.framework\n/bin/ln -sF Versions/Current/PlugIns PlugIns\nexit 0"; + showEnvVarsInLog = 0; }; - 5E10992319A5E55800A60E2B /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC63CAE91D90D63500C03317 /* libsecurityd mig */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - 5E10995119A5E5CE00A60E2B /* ISProtectedItems.plist in Resources */, + ); + inputPaths = ( + "$(PROJECT_DIR)/mig/ss_types.defs", + "$(PROJECT_DIR)/mig/ucsp.defs", + "$(PROJECT_DIR)/mig/ucspNotify.defs", + ); + name = "libsecurityd mig"; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucsp.h", + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucspServer.cpp", + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucspClient.cpp", + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucspNotify.h", + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucspNotifyReceiver.cpp", + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucspNotifySender.cpp", + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_client/ucspClientC.c", ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\nmkdir -p ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspServer.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClient.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucsp.h \\\n${PROJECT_DIR}/OSX/libsecurityd/mig/ucsp.defs\n\ncp ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClient.cpp ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClientC.c\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotifyReceiver.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotifySender.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotify.h \\\n${PROJECT_DIR}/OSX/libsecurityd/mig/ucspNotify.defs\n"; }; - 6C98085D1E788AEB00E70590 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC6BC2761D90D0BE00DD57B3 /* securityd DTrace */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + "$(SRCROOT)/securityd/src/securityd.d", + ); + name = "securityd DTrace"; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/derived_src/securityd_dtrace.h", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -e\nmkdir -p \"$BUILT_PRODUCTS_DIR/derived_src\" && xcrun usdtheadergen -C -s \"${SRCROOT}/securityd/src/securityd.d\" -o $BUILT_PRODUCTS_DIR/derived_src/securityd_dtrace.h\n"; }; - 6C9808991E788AFD00E70590 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC6BC27D1D90D1EE00DD57B3 /* cssm generator */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + "$(PROJECT_DIR)/OSX/libsecurity_cssm/lib/generator.cfg", + "$(PROJECT_DIR)/OSX/libsecurity_cssm/lib/generator.pl", + "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmapi.h", + "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmaci.h", + "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmcspi.h", + "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmdli.h", + "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmcli.h", + "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmtpi.h", + ); + name = "cssm generator"; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/derived_src/cssmexports.gen", + "$(BUILT_PRODUCTS_DIR)/derived_src/funcnames.gen", + "${BUILT_PRODUCTS_DIR}/derived_src/generator.rpt", + "$(BUILT_PRODUCTS_DIR)/derived_src/transition.gen", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "TARGET=${BUILT_PRODUCTS_DIR}/derived_src\nCONFIG=${PROJECT_DIR}/OSX/libsecurity_cssm/lib/generator.cfg\n\nmkdir -p ${TARGET}\n/usr/bin/perl ${PROJECT_DIR}/OSX/libsecurity_cssm/lib/generator.pl ${SRCROOT}/OSX/libsecurity_cssm/lib/ ${CONFIG} ${TARGET}\n"; }; - 6CF4A0B21E45488B00ECD7B5 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC7162D61EB4157D000D2BB5 /* 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\n"; + }; + DC82FFE61D90D3F60085674B /* security_utilities DTrace */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + "${PROJECT_DIR}/OSX/libsecurity_utilities/lib/security_utilities.d", + ); + name = "security_utilities DTrace"; + outputPaths = ( + "${BUILT_PRODUCTS_DIR}/derived_src/security_utilities/utilities_dtrace.h", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -e\n\nmkdir -p ${BUILT_PRODUCTS_DIR}/derived_src/security_utilities/\n\nxcrun usdtheadergen -C -s \"${PROJECT_DIR}/OSX/libsecurity_utilities/lib/security_utilities.d\" -o \"${BUILT_PRODUCTS_DIR}/derived_src/security_utilities/utilities_dtrace.h\"\n"; }; - 6CF4A0DE1E4549F200ECD7B5 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DC82FFED1D90D4D20085674B /* ocspd mig */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + "${PROJECT_DIR}/OSX/libsecurity_ocspd/mig/ocspd.defs", + ); + name = "ocspd mig"; + outputPaths = ( + $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_server.cpp, + $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_client.cpp, + $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd.h, + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "mkdir -p ${DERIVED_SRC}\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_server.cpp \\\n-user $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_client.cpp \\\n-header $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd.h \\\n${PROJECT_DIR}/OSX/libsecurity_ocspd/mig/ocspd.defs"; }; - BE197F2419116FD100BA91D1 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DCB342301D8A2C0E0054D16E /* Produce Schemas */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - BE197F61191173F200BA91D1 /* entitlements.plist in Resources */, - BE197F2C19116FD100BA91D1 /* InfoPlist.strings in Resources */, + ); + inputPaths = ( + "$(SRCROOT)/OSX/libsecurity_cdsa_utilities/lib/KeySchema.m4", + "$(SRCROOT)/OSX/libsecurity_cdsa_utilities/lib/Schema.m4", + ); + name = "Produce Schemas"; + outputPaths = ( + $BUILT_PRODUCTS_DIR/derived_src/KeySchema.cpp, + $BUILT_PRODUCTS_DIR/derived_src/Schema.cpp, ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "TARGET=$BUILT_PRODUCTS_DIR/derived_src/KeySchema.cpp\nmkdir -p $BUILT_PRODUCTS_DIR/derived_src\n/usr/bin/m4 ${PROJECT_DIR}/OSX/libsecurity_cdsa_utilities/lib/KeySchema.m4 > $TARGET.new\ncmp -s $TARGET.new $TARGET || mv $TARGET.new $TARGET\nTARGET=$BUILT_PRODUCTS_DIR/derived_src/Schema.cpp\n/usr/bin/m4 ${PROJECT_DIR}/OSX/libsecurity_cdsa_utilities/lib/Schema.m4 > $TARGET.new\ncmp -s $TARGET.new $TARGET || mv $TARGET.new $TARGET"; }; - BEF88C261EAFFC3F00357577 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DCD0675A1D8CDCFD007602F1 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + $PROJECT_DIR/OSX/libsecurity_codesigning/lib/security_codesigning.d, + ); + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/cstemp/codesigning_dtrace.h", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -e\nmkdir -p ${BUILT_PRODUCTS_DIR}/cstemp\nxcrun usdtheadergen -C -s \"${PROJECT_DIR}/OSX/libsecurity_codesigning/lib/security_codesigning.d\" -o \"${BUILT_PRODUCTS_DIR}/cstemp/codesigning_dtrace.h\"\n"; }; - BEF88C2E1EAFFC3F00357577 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DCD0675C1D8CDD6D007602F1 /* Make SystemPolicy */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputPaths = ( + "$(PROJECT_DIR)/OSX/libsecurity_codesigning/lib/syspolicy.sql", + ); + name = "Make SystemPolicy"; + outputPaths = ( + "$(BUILT_PRODUCTS_DIR)/cstemp/SystemPolicy", + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "mkdir -p \"$(dirname \"$SCRIPT_OUTPUT_FILE_0\")\"\nrm -f \"$SCRIPT_OUTPUT_FILE_0\"\nsqlite3 \"$SCRIPT_OUTPUT_FILE_0\" <$SRCROOT/OSX/libsecurity_codesigning/lib/RequirementKeywords.h\n"; }; - DC0BC54F1D8B6D2D00070CB0 /* Resources */ = { - isa = PBXResourcesBuildPhase; + DCEA0FF9213F1F410054A328 /* Generate BATS Plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Generate BATS Plist"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\n OTTESTS_DIR=${SRCROOT}/keychain/ot/tests\n \n python ${OTTESTS_DIR}/gen_test_plist.py ${OTTESTS_DIR} ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/Octagon.plist\n chown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist\n"; + }; + E7E0C6D11C90E87D00E69A21 /* chmod BATS Tests */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + "", + ); + name = "chmod BATS Tests"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist\n"; + showEnvVarsInLog = 0; + }; + EB15CA26223C60B9002BF362 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Future home of insecurityd and other darwinos-only executables\nmkdir -p ${DSTROOT}/AppleInternal/CoreOS/Security/\necho \"shut up now\" > ${DSTROOT}/AppleInternal/CoreOS/Security/Security_exectuables_darwinos_only_quiet_verifier.txt\n"; }; - DC0BC5681D8B6E3D00070CB0 /* Resources */ = { - isa = PBXResourcesBuildPhase; + EB7E90F52193F91200B1FA21 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "cd ${SRCROOT}/keychain/analytics\nxcrun --sdk iphoneos protocompiler --arc --outputDir C2Metric --proto C2Metric.proto\n"; }; - DC1789021D77980500B50D50 /* Resources */ = { - isa = PBXResourcesBuildPhase; + EBA12514225E55C200138070 /* Check for SYSTEM_FRAMEWORK_SEARCH_PATHS */ = { + isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( - DC178A421D77A1F600B50D50 /* FDEPrefs.plist in Resources */, - DC178A471D77A1F600B50D50 /* InfoPlist.strings in Resources */, - DC178A241D77A1E700B50D50 /* cspdl_common.mdsinfo in Resources */, - DC178A2B1D77A1E700B50D50 /* cl_primary.mdsinfo in Resources */, - DC178A451D77A1F600B50D50 /* framework.sb in Resources */, - DC178A2D1D77A1E700B50D50 /* tp_policyOids.mdsinfo in Resources */, - DC178A231D77A1E700B50D50 /* csp_primary.mdsinfo in Resources */, - DC178A251D77A1E700B50D50 /* cspdl_csp_capabilities.mdsinfo in Resources */, - DC178A281D77A1E700B50D50 /* dl_common.mdsinfo in Resources */, - DC178A441D77A1F600B50D50 /* SecErrorMessages.strings in Resources */, - DC178A1F1D77A1E700B50D50 /* cssm.mdsinfo in Resources */, - DC178A4B1D77A1F600B50D50 /* authorization.prompts.strings in Resources */, - DC178A2E1D77A1E700B50D50 /* tp_primary.mdsinfo in Resources */, - DC178A211D77A1E700B50D50 /* csp_capabilities_common.mds in Resources */, - DC178A2A1D77A1E700B50D50 /* cl_common.mdsinfo in Resources */, - DC178A271D77A1E700B50D50 /* cspdl_dl_primary.mdsinfo in Resources */, - DC178A4A1D77A1F600B50D50 /* authorization.buttons.strings in Resources */, - DC178A2F1D77A1E700B50D50 /* sd_cspdl_common.mdsinfo in Resources */, - DC178A291D77A1E700B50D50 /* dl_primary.mdsinfo in Resources */, - DC178A261D77A1E700B50D50 /* cspdl_csp_primary.mdsinfo in Resources */, - 475F37211EE8F23900248FB5 /* SFAnalytics.plist in Resources */, - DC178A221D77A1E700B50D50 /* csp_common.mdsinfo in Resources */, - DC178A431D77A1F600B50D50 /* SecDebugErrorMessages.strings in Resources */, - DC178A481D77A1F600B50D50 /* TimeStampingPrefs.plist in Resources */, - DC178A201D77A1E700B50D50 /* csp_capabilities.mdsinfo in Resources */, - DC178A2C1D77A1E700B50D50 /* tp_common.mdsinfo in Resources */, - DC178A491D77A1F600B50D50 /* authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings in Resources */, + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Check for SYSTEM_FRAMEWORK_SEARCH_PATHS"; + outputFileListPaths = ( + ); + outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Don't use SYSTEM_FRAMEWORK_SEARCH_PATHS, its implicit with internal SDK, if added you warnings from system headers as they where problems in our headers\ngrep -e '^\\s*SYSTEM_FRAMEWORK_SEARCH_PATHS =' ${SRCROOT}/Security.xcodeproj/project.pbxproj >/dev/null 2>&1\ntest $? != 0\n"; }; - DC3A4B561D91E9FB00E46D4A /* Resources */ = { - isa = PBXResourcesBuildPhase; + EBC15E801BE29A8C001C0C5B /* Chown BATS plist */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 8; + files = ( + ); + inputPaths = ( + ); + name = "Chown BATS plist"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 1; + shellPath = /bin/sh; + shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist\n"; + 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 */ + 0C0BDB2B175685B000BC1A7E /* Sources */ = { + 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 */, + DC5F35AF1EE0F27C00900966 /* server_entitlement_helpers.c in Sources */, + DC4269101E82FD9F002B7110 /* server_security_helpers.m in Sources */, + DCB221591E8B08CA001598BC /* server_xpc.m in Sources */, + DC4269001E82038D002B7110 /* server_endpoint.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC58C4211D77BDEA003C25A4 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 0C2BCBAD1D06401F00ED7A2F /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0C2BCBBA1D06403B00ED7A2F /* dtlsEchoClient.c in Sources */, + 0C2BCBAF1D06401F00ED7A2F /* ioSock.c in Sources */, + 0C2BCBB01D06401F00ED7A2F /* sslAppUtils.cpp in Sources */, + DC52EBC51D80CEBA00B0A59C /* print_cert.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E76B1D7A43B500AFB96E /* Resources */ = { - isa = PBXResourcesBuildPhase; + 0C2BCBC21D0648D100ED7A2F /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCE4E76D1D7A43B500AFB96E /* nist-certs in Resources */, - DCE4E76E1D7A43B500AFB96E /* ssl-policy-certs in Resources */, - D4AA64881E97275200D317ED /* si-18-certificate-parse in Resources */, - DCE4E76F1D7A43B500AFB96E /* si-20-sectrust-policies-data in Resources */, - DCE4E7701D7A43B500AFB96E /* si-82-sectrust-ct-data in Resources */, - DCE4E7B41D7A43DC00AFB96E /* si-82-sectrust-ct-logs.plist in Resources */, - D4C6C5C81FB2AD5E007EA57E /* si-87-sectrust-name-constraints in Resources */, - BEB9EA301FFF1B0800676593 /* si-88-sectrust-valid-data in Resources */, + 0C2BCBCF1D0648EF00ED7A2F /* dtlsEchoServer.c in Sources */, + 0C2BCBC41D0648D100ED7A2F /* ioSock.c in Sources */, + 0C2BCBC51D0648D100ED7A2F /* sslAppUtils.cpp in Sources */, + DC52EBC41D80CEBA00B0A59C /* print_cert.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E8921D7F34F600AFB96E /* Resources */ = { - isa = PBXResourcesBuildPhase; + 0C85DFE21FB38BB6000343A7 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 0C7A8BBF21714CDC00F4C480 /* OTJoiningConfiguration.m in Sources */, + 0C48B380202E438100A0E1AA /* CloudKitKeychainSyncingMockXCTest.m in Sources */, + 0CB9754F2023A8F5008D6B48 /* CloudKitMockXCTest.m in Sources */, + 0C24D693204F56E900926E5F /* OTBottledPeerUpdateBottlesTests.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 */, + 0C1637211FD12F1500210823 /* OTCloudStoreTests.m in Sources */, + 0CAEC9D81FD740CF00D1F2CA /* OTContextTests.m in Sources */, + 0C0DA5CF1FE1F1C5003BD3BB /* OTControlProtocol.m in Sources */, + 0C8A03461FDF42BA0042E8BE /* OTEscrowKeyTests.m in Sources */, + 0C8A034D1FDF4CCE0042E8BE /* OTLocalStoreTests.m in Sources */, + 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 */, + DC2FA71120E5770400DB7518 /* OTClique.m in Sources */, + DCDB29741FD8822200B5D242 /* SFAnalyticsSQLiteStore.m in Sources */, + 0C46A5712034C6BA00F17112 /* OTControl.m in Sources */, + DCDB29721FD8821D00B5D242 /* SFAnalyticsSampler.m in Sources */, + DCDB297E1FD8849D00B5D242 /* SFObjCType.m in Sources */, + 0CF74E4120DDD5290014A5DB /* OTTestsBase.m in Sources */, + 5A061197229ED6EB006AF14A /* NSDate+SFAnalytics.m in Sources */, + DCDB297C1FD8848A00B5D242 /* SFSQLite.m in Sources */, + 0CA4EBF4202B8DBE002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */, + DCDB297D1FD8849A00B5D242 /* SFSQLiteStatement.m in Sources */, + 0CF74E4720DDD5390014A5DB /* OTCliqueTests.m in Sources */, + DCDB297B1FD8847100B5D242 /* SecTask.c in Sources */, + 0CE751AF20ACC497002B2832 /* SFSignInAnalytics.m in Sources */, + 0C1637291FD2066A00210823 /* SecdWatchdog.m in Sources */, + DCDB29791FD8844C00B5D242 /* client.c in Sources */, + DCDB297A1FD8845600B5D242 /* client_endpoint.m in Sources */, + 0CB975512023B199008D6B48 /* OTRampingTests.m in Sources */, + 0C16372B1FD2067F00210823 /* server_endpoint.m in Sources */, + 0C16372D1FD2069300210823 /* server_entitlement_helpers.c in Sources */, + 0C1637301FD206BC00210823 /* server_security_helpers.m in Sources */, + 0C1637271FD2065400210823 /* spi.c in Sources */, + DC5060F520E2DB9700925005 /* OTCuttlefishContextTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E8DB1D7F39DB00AFB96E /* Resources */ = { - isa = PBXResourcesBuildPhase; + 0C8BBEFE1FCB446400580909 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCE4E9081D7F3A4800AFB96E /* Icon.icns in Resources */, - DCE4E90A1D7F3A4800AFB96E /* Credits.rtf in Resources */, - DCE4E9091D7F3A4800AFB96E /* InfoPlist.strings in Resources */, + DCF4657A22011E1400BA6EEA /* EscrowRequestCLI.m in Sources */, + 0C84D83C1FCF448200B822E3 /* SecArgParse.c in Sources */, + 0C84D83B1FCF443A00B822E3 /* otctl.m in Sources */, + DC26666A21CAC32700F19960 /* OTControlCLI.m in Sources */, + 0C84D8341FCF43AF00B822E3 /* OTControlProtocol.m in Sources */, + DAEF8E5A22581A1200F7DF79 /* OTPairingClient.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E90F1D7F3D5300AFB96E /* Resources */ = { - isa = PBXResourcesBuildPhase; + 0C9AEEAE20783FBB00BF6237 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCE4E9491D7F3E8E00AFB96E /* Localizable.strings in Resources */, - DCE4E94A1D7F3E8E00AFB96E /* com.apple.security.keychain-circle-notification.plist in Resources */, - DCE4E94B1D7F3E8E00AFB96E /* InfoPlist.strings in Resources */, + 0C9AEEAF20783FBB00BF6237 /* SFSignInAnalyticsTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCF7889B1D88CB5200E694BB /* Resources */ = { - isa = PBXResourcesBuildPhase; + 0CF406112072E3E3003D6A7F /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCF788A71D88CB7400E694BB /* cl_primary.mdsinfo in Resources */, - DCF788A61D88CB7000E694BB /* cl_common.mdsinfo in Resources */, + 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */, + 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E710C7401331946400F85568 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 225394AD1E3080A600D3CD9B /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 52A23EDC161DEC3800E271E0 /* Default-568h@2x.png in Resources */, - D4D886EA1CEBDE0800DC7583 /* nist-certs in Resources */, - D4D886C01CEB9F7200DC7583 /* ssl-policy-certs in Resources */, - D4AA64871E97274900D317ED /* si-18-certificate-parse in Resources */, - D4EC94FE1CEA48760083E753 /* si-20-sectrust-policies-data in Resources */, - 0C0C88791CCEC5C500617D1B /* si-82-sectrust-ct-data in Resources */, - D4C6C5C91FB2AD6D007EA57E /* si-87-sectrust-name-constraints in Resources */, - BEA74211202525CD00EC7993 /* si-88-sectrust-valid-data in Resources */, + 220179EB1E3BF1F100EFB6F3 /* detachedrep.cpp in Sources */, + 220179EA1E3BF16000EFB6F3 /* slcrep.cpp in Sources */, + 220179E31E3BEB7100EFB6F3 /* dirscanner.cpp in Sources */, + A690B033208A75D1002FB775 /* notarization.cpp in Sources */, + 1F631C5722388022005920D8 /* legacydevid.cpp in Sources */, + 225394B81E30820900D3CD9B /* Code.cpp in Sources */, + 225394B91E30821400D3CD9B /* bundlediskrep.cpp in Sources */, + 225394BA1E30821E00D3CD9B /* cdbuilder.cpp in Sources */, + 225394BB1E30822700D3CD9B /* codedirectory.cpp in Sources */, + DC5BD5831E8C6FC800C5EC49 /* SecTask.c in Sources */, + 225394BC1E30823E00D3CD9B /* cs.cpp in Sources */, + 225394BD1E30824C00D3CD9B /* SecCode.cpp in Sources */, + 225394BE1E30825500D3CD9B /* SecStaticCode.cpp in Sources */, + 225394BF1E30826100D3CD9B /* SecRequirement.cpp in Sources */, + 225394C01E30826B00D3CD9B /* diskrep.cpp in Sources */, + 225394C11E30827600D3CD9B /* filediskrep.cpp in Sources */, + 225394C21E30827E00D3CD9B /* kerneldiskrep.cpp in Sources */, + 225394C31E30828800D3CD9B /* StaticCode.cpp in Sources */, + 225394C51E3082A100D3CD9B /* requirement.cpp in Sources */, + 225394C61E3082AB00D3CD9B /* Requirements.cpp in Sources */, + DCD7EE851F4E47D2007D9804 /* reqparser.cpp in Sources */, + 225394C71E3082B600D3CD9B /* reqdumper.cpp in Sources */, + 225394C81E3082BE00D3CD9B /* reqinterp.cpp in Sources */, + 225394C91E3082C900D3CD9B /* reqmaker.cpp in Sources */, + 225394CA1E3082D500D3CD9B /* macho++.cpp in Sources */, + 225394CB1E30831D00D3CD9B /* machorep.cpp in Sources */, + 225394CC1E30832A00D3CD9B /* sigblob.cpp in Sources */, + 225394CD1E30833400D3CD9B /* resources.cpp in Sources */, + 225394CE1E30833F00D3CD9B /* cfmunge.cpp in Sources */, + 225394CF1E30835700D3CD9B /* csutilities.cpp in Sources */, + 225394D01E30836200D3CD9B /* singlediskrep.cpp in Sources */, + 225394D11E30836F00D3CD9B /* reqreader.cpp in Sources */, + 225394D21E30837900D3CD9B /* cserror.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E7B01BE3166594AB000485F1 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 3D58393021890FFB000ACA44 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3D680BE72241C16E00C04821 /* SecExperiment.m in Sources */, + 3D58394F21891061000ACA44 /* SecExperimentTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E7D847C31C6BE9710025BB44 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 3DD1FF02201C07F30086D049 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3DD2589F20478CF900F5DA78 /* STLegacyTests+session.m in Sources */, + 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 */, + 5A43A083225FA39C005450E4 /* SecProtocolHelperTest.m in Sources */, + AADD4A2D215E83270054FC6D /* SecProtocolConfigurationTest.m in Sources */, + 3DD1FF94201FC4F40086D049 /* STLegacyTests+ciphers.m in Sources */, + 3DD1FF97201FC5030086D049 /* STLegacyTests+dhe.m in Sources */, + 3DD1FF9A201FC5130086D049 /* STLegacyTests+renegotiate.m in Sources */, + AA44E0B5202E355C001EA371 /* SecProtocolTest.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 */, + 3DD258AC2051F10300F5DA78 /* STLegacyTests+sni.m in Sources */, + 3DD1FFA1201FC5660086D049 /* ssl-utils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E7D847CC1C6BE9720025BB44 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 3DD1FFB3201FDB1D0086D049 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 3DD1FFB4201FDB1D0086D049 /* STLegacyTests+noconn.m in Sources */, + 3DD1FFB5201FDB1D0086D049 /* STLegacyTests+falsestart.m in Sources */, + 5A43A085225FA3A5005450E4 /* SecProtocolHelperTest.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 */, + 5A43A08A226112DB005450E4 /* SecProtocolConfigurationTest.m in Sources */, + 3DD1FFBD201FDB1D0086D049 /* STLegacyTests+sessioncache.m in Sources */, + 3DD1FFBE201FDB1D0086D049 /* STLegacyTests+sessionstate.m in Sources */, + 5A43A084225FA3A5005450E4 /* SecProtocolTest.m in Sources */, + 3DD1FFBF201FDB1D0086D049 /* STLegacyTests+split.m in Sources */, + 3DD1FFC0201FDB1D0086D049 /* STLegacyTests+sslciphers.m in Sources */, + 3DD1FFC1201FDB1D0086D049 /* STLegacyTests+tls12.m in Sources */, + 3DD258A020478CFA00F5DA78 /* STLegacyTests+session.m in Sources */, + 3DD1FFD1201FDC460086D049 /* STLegacyTests+clientauth41.m in Sources */, + 3DD1FFC2201FDB1D0086D049 /* ssl-utils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - EB05C4EF1FE5E48A00D68712 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 438169081B4EDCBD00C54D58 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 438169E31B4EDEE200C54D58 /* SOSCCAuthPlugin.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - EB108F3A1E6CE4D2003B0456 /* Resources */ = { - isa = PBXResourcesBuildPhase; + 470415CB1E5E14B5001F3D95 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 470415DC1E5E1534001F3D95 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 090585D020AEF9D300BB7490 /* Install OCMock framework */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 4718AE0F205B39620068EC3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 4718AE10205B39620068EC3F /* spi.c in Sources */, + D4BD5E88228A6857001650A7 /* util.m in Sources */, + 4718AE11205B39620068EC3F /* SecdWatchdog.m in Sources */, + 4718AE12205B39620068EC3F /* server.c in Sources */, + 4718AE13205B39620068EC3F /* server_entitlement_helpers.c in Sources */, + 4718AE14205B39620068EC3F /* server_security_helpers.m in Sources */, + EB8908B421F18E4A00F0DDDB /* SecItemBackupServer.c in Sources */, + 4718AE15205B39620068EC3F /* server_xpc.m in Sources */, + 4718AE16205B39620068EC3F /* server_endpoint.m in Sources */, ); - inputPaths = ( - ); - name = "Install OCMock framework"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework\n"; + runOnlyForDeploymentPostprocessing = 0; }; - 090585D120AEF9FE00BB7490 /* Install OCMock framework */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 4718AE2F205B39C40068EC3F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 4718AE35205B39C40068EC3F /* CKKSSQLDatabaseObject.m in Sources */, + 4718AE36205B39C40068EC3F /* CKKSRateLimiter.m in Sources */, + 4718AE37205B39C40068EC3F /* CKKSAccountStateTracker.m in Sources */, + 4718AE38205B39C40068EC3F /* SecCDKeychain.m in Sources */, + 4718AE3A205B39C40068EC3F /* CKKSGroupOperation.m in Sources */, + 4718AE3B205B39C40068EC3F /* OTContextRecord.m in Sources */, + 4718AE3D205B39C40068EC3F /* CKKSManifestLeafRecord.m in Sources */, + DC8DF6DF212F8A7D007B3FE8 /* OTSOSAdapter.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 */, + DC3AF52F2229E770006577E8 /* CKKSListenerCollection.m in Sources */, + 4718AE45205B39C40068EC3F /* OTBottledPeerSigned.m in Sources */, + 4718AE46205B39C40068EC3F /* CKKSIncomingQueueOperation.m in Sources */, + 4718AE47205B39C40068EC3F /* CKKSOutgoingQueueOperation.m in Sources */, + 4718AE48205B39C40068EC3F /* CKKSZoneStateEntry.m in Sources */, + 4718AE4A205B39C40068EC3F /* RateLimiter.m in Sources */, + 4718AE4B205B39C40068EC3F /* CKKSHealKeyHierarchyOperation.m in Sources */, + 4718AE4C205B39C40068EC3F /* CKKSCurrentItemPointer.m in Sources */, + 6C4AEF97218A12810012C5DA /* SecDbKeychainMetadataKeyStore.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 */, + 6C880FCF21C3351500D38D66 /* SecDbBackupKeyClassSigningKey.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 */, + 0C2F337320DD64940031A92D /* OTRamping.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 */, + 6C880FD021C3351500D38D66 /* SecDbBackupMetadataClassKey.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 */, + DC5F65B12225CD720051E9FA /* CKKSProvideKeySetOperation.m in Sources */, + 4718AE6D205B39C40068EC3F /* SecItemDb.c in Sources */, + 4718AE6E205B39C40068EC3F /* SecItemSchema.c in Sources */, + 4718AE6F205B39C40068EC3F /* OTConstants.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 */, + 6C9791C821C20CFF0074C609 /* NSError+UsefulConstructors.m in Sources */, + 6C4AEFA1218A189B0012C5DA /* SecAKSObjCWrappers.m in Sources */, + 4718AE80205B39C40068EC3F /* OTCloudStoreState.m in Sources */, + 6C4AEF89218A09E80012C5DA /* CheckV12DevEnabled.m in Sources */, + 4718AE81205B39C40068EC3F /* SecDbKeychainSerializedSecretData.m in Sources */, + 4718AE82205B39C40068EC3F /* CKKSKeychainView.m in Sources */, + 4718AE83205B39C40068EC3F /* SecuritydXPC.c in Sources */, + 4718AE84205B39C40068EC3F /* SecDbKeychainSerializedItemV7.m in Sources */, + 4718AE86205B39C40068EC3F /* CKKSProcessReceivedKeysOperation.m in Sources */, + 4718AE87205B39C40068EC3F /* CKKSTLKShareRecord.m in Sources */, + DC0BD4F621BB0610006B9154 /* CKKSKeychainBackedKey.m in Sources */, + 4718AE88205B39C40068EC3F /* CKKSHealTLKSharesOperation.m in Sources */, + 4718AE89205B39C40068EC3F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, + 4718AE8A205B39C40068EC3F /* SecBackupKeybagEntry.m in Sources */, + 4718AE8B205B39C40068EC3F /* iCloudTrace.c in Sources */, + 4718AE8C205B39C40068EC3F /* OctagonAPSReceiver.m in Sources */, + DC391F9F21BF2F8700772585 /* CKKSConstants.m in Sources */, + 4718AE8D205B39C40068EC3F /* OTBottledPeer.m in Sources */, + 6C880FCD21C3351500D38D66 /* SecDbBackupBag.m in Sources */, + 4718AE8F205B39C40068EC3F /* SOSEnsureBackup.m in Sources */, + 4718AE90205B39C40068EC3F /* OTBottledPeerRecord.m in Sources */, + 6C880FD121C3351500D38D66 /* SecDbBackupRecoverySet.m in Sources */, + 4718AE91205B39C40068EC3F /* OTCloudStore.m in Sources */, + 6C880FCE21C3351500D38D66 /* SecDbBackupBagIdentity.m in Sources */, + 4718AE92205B39C40068EC3F /* CKKSSIV.m in Sources */, + 4718AE93205B39C40068EC3F /* OTPreflightInfo.m in Sources */, + 4718AE96205B39C40068EC3F /* CKKSZoneChangeFetcher.m in Sources */, + 4718AE97205B39C40068EC3F /* CKKSCondition.m in Sources */, + 4718AE98205B39C40068EC3F /* CKKSZone.m in Sources */, + 4718AE99205B39C40068EC3F /* SFKeychainServer.m in Sources */, + 4718AE9B205B39C40068EC3F /* swcagent_client.c in Sources */, + DC5A01EB21BB428500D87AB9 /* CKKSTLKShare.m in Sources */, + 6C4AEF91218A0C190012C5DA /* SecDbBackupManager.m in Sources */, ); - inputPaths = ( - ); - name = "Install OCMock framework"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework"; + runOnlyForDeploymentPostprocessing = 0; }; - 0C85DFFF1FB38BB6000343A7 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 4727FBB31F9918580003AE36 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 47DE88DA1FA7B07400DD3254 /* server_xpc.m in Sources */, + 4727FBEF1F9924FB0003AE36 /* server_security_helpers.m in Sources */, + 4727FBEE1F9924DA0003AE36 /* server_entitlement_helpers.c in Sources */, + 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 */, + 6C9791C921C2EAB60074C609 /* NSError+UsefulConstructors.m in Sources */, + 477A1FE4203763A500ACD81D /* KeychainAPITests.m in Sources */, + 4727FBED1F99249A0003AE36 /* server_endpoint.m in Sources */, + 096C647020AB1BC700D7B7D5 /* KeychainEntitlementsTest.m in Sources */, ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - 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"; + runOnlyForDeploymentPostprocessing = 0; }; - 3DD1FF49201C07F30086D049 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 47702B1A1E5F409700B29577 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 47702B281E5F412500B29577 /* main.m in Sources */, ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + runOnlyForDeploymentPostprocessing = 0; }; - 3DD1FFCC201FDB1D0086D049 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 47702B2A1E5F492C00B29577 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 47702B371E5F495C00B29577 /* main.m in Sources */, ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + runOnlyForDeploymentPostprocessing = 0; }; - 5EE098DE1CD21661009FCA27 /* Unifdef RC_HIDE_J79/J80 */ = { - isa = PBXShellScriptBuildPhase; + 4771D96E209A755800BA9772 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - name = "Unifdef RC_HIDE_J79/J80"; - outputPaths = ( + 47D13759209CD1A200CAD493 /* NSError+UsefulConstructors.m in Sources */, + 4771D980209A75FE00BA9772 /* KeychainDataclassOwner.m in Sources */, ); 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; }; - 6CAA8D361F84317F007B6E03 /* Install launchd plist */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 478D42751FD72A8100CAB645 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 478D42761FD72A8100CAB645 /* server_xpc.m in Sources */, + 4764E92D2059D8BF005497C9 /* KeychainModel.xcdatamodeld in Sources */, + 478D42771FD72A8100CAB645 /* server_security_helpers.m 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 */, + 6C9791CA21C2EAB70074C609 /* NSError+UsefulConstructors.m in Sources */, + 478D427B1FD72A8100CAB645 /* KeychainCryptoTests.m in Sources */, + 477A1FE5203763A500ACD81D /* KeychainAPITests.m in Sources */, + 478D427C1FD72A8100CAB645 /* server_endpoint.m in Sources */, ); - 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\""; + runOnlyForDeploymentPostprocessing = 0; }; - 6CB5F4761E402D0000DBF3F0 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 47C2F17F2059CB680062DE30 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 47C2F18A2059CB820062DE30 /* KeychainModel.xcdatamodeld in Sources */, ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + runOnlyForDeploymentPostprocessing = 0; }; - 8E64DB4E1C18A5B80076C9DF /* Install launchd plist */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 47C51B801EEA657D0032D9E5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + EB9795B522FE9256002BDBFB /* SecItemTests.m in Sources */, + 47C51B871EEA657D0032D9E5 /* SecKeyTests.m in Sources */, ); - inputPaths = ( - "$(PROJECT_DIR)/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.ios.plist", - "$(PROJECT_DIR)/KVSKeychainSyncingProxy/com.apple.security.cloudkeychainproxy3.osx.plist", - ); - name = "Install launchd plist"; - outputPaths = ( - "$(INSTALL_ROOT)/$(INSTALL_DAEMON_AGENT_DIR)/com.apple.security.cloudkeychainproxy3.plist", - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "PLIST_FILE_NAME=com.apple.security.cloudkeychainproxy3\nFILE_TO_COPY=${PROJECT_DIR}/KVSKeychainSyncingProxy/${PLIST_FILE_NAME}.ios.plist\n\nif [ ${PLATFORM_NAME} = \"macosx\" ]\nthen\nFILE_TO_COPY=${PROJECT_DIR}/KVSKeychainSyncingProxy/${PLIST_FILE_NAME}.osx.plist\nfi\n\ncp ${FILE_TO_COPY} ${INSTALL_ROOT}/${INSTALL_DAEMON_AGENT_DIR}/${PLIST_FILE_NAME}.plist\n"; + runOnlyForDeploymentPostprocessing = 0; }; - D442AD70215C39100050B50F /* Install Apple Corporate Roots */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 4C32C0AC0A4975F6002891BD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 6CAA8CFF1F83E800007B6E03 /* SFSQLite.m in Sources */, + 6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */, + 0CBFEACB200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */, + 5A06118E229ED5EB006AF14A /* NSDate+SFAnalytics.m in Sources */, + 0C8884012154C4E80053224D /* OTJoiningConfiguration.m in Sources */, + 0CBD55B31FE883F200A8CE21 /* SFBehavior.m in Sources */, + 3DD852B12177FF72009E705D /* SecExperiment.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 */, + DCA9D84621FFE7CF00B27421 /* EscrowRequestXPCProtocol.m in Sources */, + 6CBF653A1FA147E500A68667 /* SFAnalyticsActivityTracker.m in Sources */, + DC9C95BF1F79DC88000D19E5 /* CKKSControl.m in Sources */, + EB10A3E620356E2000E84270 /* OTConstants.m in Sources */, + 18F7F67914D77F4400F88A12 /* NtlmGenerator.c in Sources */, + 0CD8CB051ECA50780076F37F /* SOSPeerOTRTimer.m in Sources */, + DCA85B981E8D980A00BA7241 /* client_endpoint.m in Sources */, + 0C84D8371FCF43BF00B822E3 /* OTControlProtocol.m in Sources */, + 6CE3654E1FA100E50012F6AB /* SFAnalytics.m in Sources */, + 0C0E60DA20D033E400E654F2 /* OTControl.m in Sources */, + 18F7F67A14D77F4400F88A12 /* ntlmBlobPriv.c in Sources */, + DC2B757721F2A272003C9356 /* SecEscrowRequest.m in Sources */, + 5AF593FF1FA0EE5300A5C1EC /* SecProtocol.c in Sources */, + 5A7E037822272C2D003DB3A0 /* SecProtocolHelper.m in Sources */, + 6CAA8CFC1F83E7EA007B6E03 /* SFObjCType.m in Sources */, + E7B00700170B581D00B27966 /* Security.exp-in in Sources */, + B61F67571F1FCFCB00E2FDBB /* SecPaddingConfigurations.c in Sources */, + 78ADC62B1FA0FACD001EB8B6 /* SecProtocolTypes.m in Sources */, + DC372C8C22B4501900AB9F41 /* SecCoreAnalytics.m in Sources */, + 6CE365531FA101080012F6AB /* SFAnalyticsSampler.m in Sources */, + AA9FD59C2152AFD70045A07A /* SecProtocolConfiguration.m in Sources */, + 6C73F48A2006B839003D5D63 /* SOSAnalytics.m in Sources */, + 5A04BAFA22976A15001848A0 /* OTClique.m in Sources */, + 6CE365571FA1017D0012F6AB /* SFAnalyticsSQLiteStore.m in Sources */, + EB9B285721C77C8D00173DC2 /* OTDefines.m in Sources */, ); - inputFileListPaths = ( - ); - inputPaths = ( - "$(SRCROOT)/OSX/trustd/iOS/AppleCorporateRootCA.cer", - "$(SRCROOT)/OSX/trustd/iOS/AppleCorporateRootCA2.cer", - ); - name = "Install Apple Corporate Roots"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DSTROOT)/AppleInternal/Library/Security/AppleCorporateRootCA.cer", - "$(DSTROOT)/AppleInternal/Library/Security/AppleCorporateRootCA2.cer", - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "ditto ${SRCROOT}/OSX/trustd/iOS/AppleCorporateRootCA.cer ${DSTROOT}/AppleInternal/Library/Security/\nditto ${SRCROOT}/OSX/trustd/iOS/AppleCorporateRootCA2.cer ${DSTROOT}/AppleInternal/Library/Security/\nchown -R root:wheel ${DSTROOT}/AppleInternal/Library/Security/\n"; + runOnlyForDeploymentPostprocessing = 0; }; - D4C263C41F8FEAA8001317EA /* Run Script Generate Error Strings */ = { - isa = PBXShellScriptBuildPhase; + 4C52D0B016EFC61E0079966E /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/CSCommon.h", - ); - name = "Run Script Generate Error Strings"; - outputPaths = ( - "${BUILT_PRODUCTS_DIR}/derived_src/SecDebugErrorMessages.strings", - "${BUILT_PRODUCTS_DIR}/derived_src/English.lproj/SecErrorMessages.strings", + 4C3DD6B0179755560093F9D8 /* NSDate+TimeIntervalDescription.m in Sources */, + 4C52D0E816EFCCA30079966E /* NSArray+map.m in Sources */, + 4C52D0E716EFCCA20079966E /* Applicant.m in Sources */, + 4CC3D29D178F698D0070FCC4 /* PersistentState.m in Sources */, + 4C52D0BA16EFC61E0079966E /* CircleJoinRequested.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -x\n\nDERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/English.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/English.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/PrivateHeaders/CSCommon.h\ndone\n"; }; - DC008B581D90CE70004002A3 /* securityd mig */ = { - isa = PBXShellScriptBuildPhase; + 4C711D6313AFCD0900FE865D /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${SRCROOT}/securityd/mig/self.defs", - ); - name = "securityd mig"; - outputPaths = ( - "${BUILT_PRODUCTS_DIR}/derived_src/self.h", - "${BUILT_PRODUCTS_DIR}/derived_src/selfUser.cpp", - "${BUILT_PRODUCTS_DIR}/derived_src/selfServer.cpp", + 476541A71F33EE3F00413F65 /* SecdWatchdog.m in Sources */, + 4CC92B1D15A3BF2F00C6D578 /* testmain.c in Sources */, + DC4268F61E82036F002B7110 /* server_endpoint.m in Sources */, + 0C78F1CD16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */, + DCB221531E8B08BC001598BC /* server_xpc.m in Sources */, + DCCD33D01E3FEF2A00AA4AD1 /* spi.c in Sources */, + DC42690C1E82FD9A002B7110 /* server_security_helpers.m in Sources */, + DC5F35AA1EE0F27100900966 /* server_entitlement_helpers.c in Sources */, + 0C78F1CF16A5E1BF00654E08 /* sectask_ipc.defs in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p ${BUILT_PRODUCTS_DIR}/derived_src\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/selfServer.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/selfUser.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/self.h \\\n${SRCROOT}/securityd/mig/self.defs\n"; }; - DC0BC5BF1D8B725C00070CB0 /* Install PAM Config */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 4C9DE9CF1181AC4800CF5C27 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 4C9DE9E31181AC8300CF5C27 /* sslEcdsa.cpp in Sources */, + 4C9DEAAD1181B39300CF5C27 /* ioSock.c in Sources */, + 4C9DEAB11181B39800CF5C27 /* sslAppUtils.cpp in Sources */, ); - inputPaths = ( - "${PROJECT_DIR}/OSX/libsecurity_checkpw/checkpw.pam", - ); - name = "Install PAM Config"; - outputPaths = ( - "${DSTROOT}/private/etc/pam.d/checkpw.pam", - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "name=checkpw\n\nmkdir -p \"${DSTROOT}/private/etc/pam.d/\"\ncp \"${PROJECT_DIR}/OSX/libsecurity_checkpw/checkpw.pam\" \"${DSTROOT}/private/etc/pam.d/${name}\""; + runOnlyForDeploymentPostprocessing = 0; }; - DC1789A71D779E7E00B50D50 /* Run Script Generate Strings */ = { - isa = PBXShellScriptBuildPhase; + 4CB740A00A47567C00D641BB /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h", - "${PROJECT_DIR}/libsecurity_keychain/lib/MacOSErrorStrings.h", - "${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h", - ); - name = "Run Script Generate Strings"; - outputPaths = ( - "${BUILT_PRODUCTS_DIR}/derived_src/SecDebugErrorMessages.strings", - "${BUILT_PRODUCTS_DIR}/derived_src/en.lproj/SecErrorMessages.strings", + 1BDEBEFD2253E6D9009AD3D6 /* policy_dryrun.m in Sources */, + DC8506A72097EE7500C712EC /* SecurityTool.c in Sources */, + DC3AA28E2097E24C007CA68A /* scep.c in Sources */, + DC3AA2922097E25C007CA68A /* trust_update.m in Sources */, + DC85069D2097E69500C712EC /* keychain_backup.c in Sources */, + DC8506B42097F1FC00C712EC /* whoami.m in Sources */, + DC8506AA2097EEA500C712EC /* syncbubble.m in Sources */, + DC8506A82097EE8E00C712EC /* KeychainCheck.m in Sources */, + DC3AA2842097E21D007CA68A /* log_control.c in Sources */, + DC3AA27B2097DF85007CA68A /* not_on_this_platorm.c in Sources */, + DC3AA27F2097E20A007CA68A /* keychain_util.c in Sources */, + E7104A0C169E171900DB0045 /* security_tool_commands.c in Sources */, + DC3AA2862097E22A007CA68A /* codesign.c in Sources */, + DC8506AC2097EEBA00C712EC /* sos.m in Sources */, + E78A9ADA1D34959200006B5B /* NSFileHandle+Formatting.m in Sources */, + DC3AA28A2097E23B007CA68A /* keychain_find.m in Sources */, + DC3AA2782097DF70007CA68A /* readline.c in Sources */, + DC3AA2812097E216007CA68A /* add_internet_password.c in Sources */, + DC8506B22097F1DF00C712EC /* digest_calc.c in Sources */, + DC8506AE2097EEDA00C712EC /* leaks.c in Sources */, + DC3AA28F2097E253007CA68A /* show_certificates.c in Sources */, + DC3AA2942097E264007CA68A /* spc.c in Sources */, + DC3AA27D2097E206007CA68A /* verify_cert.c in Sources */, + D4A3A597217A85D500F0A8DA /* ct_exceptions.m in Sources */, + DC3AA2872097E231007CA68A /* keychain_add.c in Sources */, + DC3AA28B2097E23F007CA68A /* pkcs12_util.c in Sources */, + DC8506B02097EEF200C712EC /* print_cert.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "set -x\n\nDERIVED_SRC=${BUILT_PRODUCTS_DIR}/derived_src\nmkdir -p ${DERIVED_SRC}\n\n# make error message string files\n\nGENDEBUGSTRS[0]=YES; ERRORSTRINGS[0]=${DERIVED_SRC}/SecDebugErrorMessages.strings\nGENDEBUGSTRS[1]=NO ; ERRORSTRINGS[1]=${DERIVED_SRC}/en.lproj/SecErrorMessages.strings\n\nmkdir -p ${DERIVED_SRC}/en.lproj\n\nfor ((ix=0;ix<2;ix++)) ; do\nperl OSX/lib/generateErrStrings.pl \\\n${GENDEBUGSTRS[ix]} \\\n${DERIVED_SRC} \\\n${ERRORSTRINGS[ix]} \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/Authorization.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/AuthSession.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecureTransport.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/SecBase.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmerr.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/cssmapple.h \\\n${BUILT_PRODUCTS_DIR}/Security.framework/Headers/CSCommon.h \\\n${PROJECT_DIR}/OSX/libsecurity_keychain/lib/MacOSErrorStrings.h\ndone\n"; }; - DC178B481D77A51600B50D50 /* Make XPC server symlink */ = { - isa = PBXShellScriptBuildPhase; + 4CE5A54A09C796E100D27A3F /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - name = "Make XPC server symlink"; - outputPaths = ( + 4CE5A55B09C7970A00D27A3F /* SSLViewer.c in Sources */, + 4CE5A66009C79E0600D27A3F /* ioSock.c in Sources */, + 4CE5A66109C79E0600D27A3F /* sslAppUtils.cpp in Sources */, + DC52EA9C1D80CC8300B0A59C /* print_cert.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if [ ! -h ${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/XPCServices ]; then\n ln -s Versions/Current/XPCServices ${BUILT_PRODUCTS_DIR}/${FULL_PRODUCT_NAME}/XPCServices\nfi\n\nexit 0"; }; - DC58C4381D77BE5E003C25A4 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; + 52D82BDA16A621F70078DFE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - outputPaths = ( + E7C787201DCA4D430087FC34 /* CKDAKSLockMonitor.m in Sources */, + DC55329B1DDAA28600B6A6A7 /* XPCNotificationDispatcher.m in Sources */, + E7A5F4D21C0CFF7900F3BEBB /* CKDKVSProxy.m in Sources */, + E7B945B31CFE5EBD0027F31D /* CKDSecuritydAccount.m in Sources */, + E7A5F4D51C0CFF7900F3BEBB /* cloudkeychainproxy.m in Sources */, + E7A5F4D81C0D01B000F3BEBB /* SOSCloudKeychainConstants.c in Sources */, + E722E9121CE92DFC005AD94B /* CKDKVSStore.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cd ${BUILT_PRODUCTS_DIR}/Security.framework\n/bin/ln -sF Versions/Current/PlugIns PlugIns\nexit 0"; - showEnvVarsInLog = 0; }; - DC63CAE91D90D63500C03317 /* libsecurityd mig */ = { - isa = PBXShellScriptBuildPhase; + 534647FD17331E1100FE9172 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${PROJECT_DIR}/mig/ss_types.defs", - "${PROJECT_DIR}/mig/ucsp.defs", - "${PROJECT_DIR}/mig/ucspNotify.defs", - "${PROJECT_DIR}/mig/cshosting.defs", - ); - name = "libsecurityd mig"; - outputPaths = ( - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucsp.h", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspServer.cpp", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClient.cpp", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotify.h", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotifyReceiver.cpp", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotifySender.cpp", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/cshosting.h", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/cshostingServer.cpp", - "${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/cshostingClient.cpp", + 5346481E173322BD00FE9172 /* KeychainSyncAccountNotification.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\nmkdir -p ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspServer.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClient.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucsp.h \\\n${PROJECT_DIR}/OSX/libsecurityd/mig/ucsp.defs\n\ncp ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClient.cpp ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspClientC.c\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotifyReceiver.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotifySender.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/ucspNotify.h \\\n${PROJECT_DIR}/OSX/libsecurityd/mig/ucspNotify.defs\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/cshostingServer.cpp \\\n-user ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/cshostingClient.cpp \\\n-header ${BUILT_PRODUCTS_DIR}/derived_src/securityd_client/cshosting.h \\\n${PROJECT_DIR}/OSX/libsecurityd/mig/cshosting.defs"; }; - DC6BC2761D90D0BE00DD57B3 /* securityd DTrace */ = { - isa = PBXShellScriptBuildPhase; + 5E10992119A5E55800A60E2B /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${SRCROOT}/securityd/src/securityd.d", - ); - name = "securityd DTrace"; - outputPaths = ( - $BUILT_PRODUCTS_DIR/derived_src/securityd_dtrace.h, + 5E10995219A5E5CE00A60E2B /* ISProtectedItemsController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p $BUILT_PRODUCTS_DIR/derived_src\n/usr/sbin/dtrace -h -C -s ${SRCROOT}/securityd/src/securityd.d -o $BUILT_PRODUCTS_DIR/derived_src/securityd_dtrace.h"; }; - DC6BC27D1D90D1EE00DD57B3 /* cssm generator */ = { - isa = PBXShellScriptBuildPhase; + 5EBE24761B00CCAE0007DB0E /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "$(PROJECT_DIR)/OSX/libsecurity_cssm/lib/generator.cfg", - "$(PROJECT_DIR)/OSX/libsecurity_cssm/lib/generator.pl", - "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmapi.h", - "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmaci.h", - "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmcspi.h", - "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmdli.h", - "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmcli.h", - "$(SRCROOT)/OSX/libsecurity_cssm/lib/cssmtpi.h", - ); - name = "cssm generator"; - outputPaths = ( - "${BUILT_PRODUCTS_DIR}/derived_src/cssmexports.gen", - "${BUILT_PRODUCTS_DIR}/derived_src/funcnames.gen", - "$(DERIVED_FILE_DIR)/${BUILT_PRODUCTS_DIR}/derived_src/generator.rpt", - "${BUILT_PRODUCTS_DIR}/derived_src/transition.gen", + 4765419B1F33ED7E00413F65 /* SecdWatchdog.m in Sources */, + DCB221581E8B08C9001598BC /* server_xpc.m in Sources */, + DCA85B971E8D980200BA7241 /* client.c in Sources */, + DCCD33E91E3FFDBF00AA4AD1 /* spi.c in Sources */, + DCA85B9B1E8D981200BA7241 /* client_endpoint.m in Sources */, + DC4269111E82FDA0002B7110 /* server_security_helpers.m in Sources */, + DC5F35AE1EE0F27C00900966 /* server_entitlement_helpers.c in Sources */, + 5EBE247D1B00CCAE0007DB0E /* main.c in Sources */, + 5E4E05A41B0CA0FD001C4A31 /* sec_acl_stress.c in Sources */, + DC4268FF1E82038C002B7110 /* server_endpoint.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "TARGET=${BUILT_PRODUCTS_DIR}/derived_src\nCONFIG=${PROJECT_DIR}/OSX/libsecurity_cssm/lib/generator.cfg\n\nmkdir -p ${TARGET}\n/usr/bin/perl ${PROJECT_DIR}/OSX/libsecurity_cssm/lib/generator.pl ${SRCROOT}/OSX/libsecurity_cssm/lib/ ${CONFIG} ${TARGET}"; }; - DC7162D61EB4157D000D2BB5 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 6C39234D21F13E4D00D018AD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 6C39237B21F13EB400D018AD /* SecDbBackupManager.m in Sources */, + 6C39237C21F13EB400D018AD /* SecDbBackupBag.m in Sources */, + 6C39237D21F13EB400D018AD /* SecDbBackupBagIdentity.m in Sources */, + 6C39237F21F13EB400D018AD /* SecDbBackupKeyClassSigningKey.m in Sources */, + 6C39238121F13EB400D018AD /* SecDbBackupMetadataClassKey.m in Sources */, + 6C02134E21F7ED25009D5C80 /* SecDbBackupTests.m in Sources */, + 6C39238221F13EB400D018AD /* SecDbBackupRecoverySet.m in Sources */, + 6C39234E21F13E4D00D018AD /* server_xpc.m in Sources */, + 6C39234F21F13E4D00D018AD /* server_security_helpers.m in Sources */, + 6C39235021F13E4D00D018AD /* server_entitlement_helpers.c in Sources */, + 6C39235221F13E4D00D018AD /* spi.c in Sources */, + 6C39235321F13E4D00D018AD /* SecdWatchdog.m in Sources */, + 6C39235421F13E4D00D018AD /* KeychainModel.xcdatamodeld in Sources */, + 6C39235621F13E4D00D018AD /* NSError+UsefulConstructors.m in Sources */, + 6C39235821F13E4D00D018AD /* server_endpoint.m in Sources */, ); - inputPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown -f root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; + runOnlyForDeploymentPostprocessing = 0; }; - DC71D9FE1D95BB5B0065FB93 /* Why is this here? */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 6C46057A1F882B9B001421B6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 6CB96BB21F966DA400E11457 /* SFSQLite.m in Sources */, + 6CB96BB31F966DA400E11457 /* SFSQLiteStatement.m in Sources */, + 6CBF65421FA2255800A68667 /* SFAnalyticsActivityTracker.m in Sources */, + EB09310D213F980800C0A495 /* TestResourceUsage.m in Sources */, + 6CDF8DF21F9649AB00140B54 /* SFAnalyticsSampler.m in Sources */, + 6CDF8DF41F9649C000140B54 /* SFAnalytics.m in Sources */, + 6C4605BC1F882DB6001421B6 /* SFAnalyticsTests.m in Sources */, + 5A0F84A522AEAF5B0097AEEA /* NSDate+SFAnalyticsTests.m in Sources */, + 6C13AE471F8E9F5F00F047E3 /* supd.m in Sources */, + 6C4605BD1F882DC3001421B6 /* SupdTests.m in Sources */, + 6CDB5FFA1FA78D2500410924 /* SFAnalyticsMultiSampler.m in Sources */, + 6CB96BAC1F966D6500E11457 /* main.m in Sources */, + 6CB96BB61F966E4300E11457 /* SFObjCType.m in Sources */, + 5A061194229ED6E7006AF14A /* NSDate+SFAnalytics.m in Sources */, + 6CDF8DF31F9649C000140B54 /* SFAnalyticsSQLiteStore.m in Sources */, ); - inputPaths = ( - "$(SRCROOT)/OSX/libsecurity_asn1/lib/SecAsn1Coder.h", - ); - name = "Why is this here?"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "# The build system requires that we don't install these headers and .as in multiple phases.\n# This target will install libASN1 (as needed per platform).\n\n# If you make changes to this target, please make them to ASN1_not_installed as well."; - showEnvVarsInLog = 0; + runOnlyForDeploymentPostprocessing = 0; }; - DC71D9FF1D95BCDF0065FB93 /* Why is this here? */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 6C98083D1E788AEB00E70590 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 6CBF65431FA2257100A68667 /* SFAnalyticsActivityTracker.m in Sources */, + 6CAA8CF71F83E79E007B6E03 /* SFSQLite.m in Sources */, + 476541A41F33EDED00413F65 /* SecdWatchdog.m in Sources */, + 47B011991F17D78D0030B49F /* SFSQLiteStatement.m in Sources */, + DC2D438F1F0EEC2A0005D382 /* MockCloudKit.m in Sources */, + 6CDF8DEF1F96495600140B54 /* SFAnalyticsSampler.m in Sources */, + DCB515E21ED3D134001F1152 /* SecTask.c in Sources */, + DCB515E11ED3D11A001F1152 /* client.c in Sources */, + 6C9808A61E788CD200E70590 /* CKKSCloudKitTests.m in Sources */, + 6C98083E1E788AEB00E70590 /* spi.c in Sources */, + 5A061192229ED6E5006AF14A /* NSDate+SFAnalytics.m in Sources */, + DC2353301ECA658900D7C1BE /* server_security_helpers.m in Sources */, + 6CAA8CF01F83E65E007B6E03 /* SFObjCType.m in Sources */, + 6CAA8D131F83ECD4007B6E03 /* SFAnalytics.m in Sources */, + DC2353321ECA659000D7C1BE /* server_xpc.m in Sources */, + 6CDB5FF91FA78D2400410924 /* SFAnalyticsMultiSampler.m in Sources */, + DC5F35B11EE0F28B00900966 /* server_entitlement_helpers.c in Sources */, + DC2353291ECA658300D7C1BE /* server_endpoint.m in Sources */, + 6CAA8CF91F83E7AA007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, ); - inputPaths = ( - "$(SRCROOT)/OSX/libsecurity_asn1/lib/SecAsn1Coder.h", - ); - name = "Why is this here?"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "# The build system requires that we don't install these headers and .as in multiple phases.\n# This target will not install anything, so feel free to depend on it whenever you use it.\n\n# If you make changes to this target, please make them to ASN1 as well."; - showEnvVarsInLog = 0; + runOnlyForDeploymentPostprocessing = 0; }; - DC82FFE61D90D3F60085674B /* security_utilities DTrace */ = { - isa = PBXShellScriptBuildPhase; + 6C9808791E788AFD00E70590 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${PROJECT_DIR}/OSX/libsecurity_utilities/lib/security_utilities.d", - ); - name = "security_utilities DTrace"; - outputPaths = ( - "${BUILT_PRODUCTS_DIR}/derived_src/security_utilities/utilities_dtrace.h", + 6CAA8CF61F83E79D007B6E03 /* SFSQLite.m in Sources */, + 6CDB5FF81FA78D2300410924 /* SFAnalyticsMultiSampler.m in Sources */, + 5A061193229ED6E6006AF14A /* NSDate+SFAnalytics.m in Sources */, + 476541A51F33EE1E00413F65 /* SecdWatchdog.m in Sources */, + DC2D43951F0EEC300005D382 /* MockCloudKit.m in Sources */, + 6CAA8CF81F83E7A9007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, + 6C9808A51E788CD100E70590 /* CKKSCloudKitTests.m in Sources */, + 6CBF65441FA2257200A68667 /* SFAnalyticsActivityTracker.m in Sources */, + DCB515E31ED3D135001F1152 /* SecTask.c in Sources */, + 6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */, + DCB515E01ED3D111001F1152 /* client.c in Sources */, + DCB515E41ED3D15A001F1152 /* client_endpoint.m in Sources */, + 6CAA8D141F83ECD5007B6E03 /* SFAnalytics.m in Sources */, + 6C98087A1E788AFD00E70590 /* spi.c in Sources */, + 6CAA8D0D1F83EC57007B6E03 /* SFSQLiteStatement.m in Sources */, + DC5F35B21EE0F28C00900966 /* server_entitlement_helpers.c in Sources */, + DC2353311ECA658B00D7C1BE /* server_security_helpers.m in Sources */, + DC2353331ECA659000D7C1BE /* server_xpc.m in Sources */, + DC23532F1ECA658400D7C1BE /* server_endpoint.m in Sources */, + 6CDF8DF01F96495700140B54 /* SFAnalyticsSampler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p ${BUILT_PRODUCTS_DIR}/derived_src/security_utilities/\n\n/usr/sbin/dtrace -h -C -s ${PROJECT_DIR}/OSX/libsecurity_utilities/lib/security_utilities.d -o ${BUILT_PRODUCTS_DIR}/derived_src/security_utilities/utilities_dtrace.h"; }; - DC82FFED1D90D4D20085674B /* ocspd mig */ = { - isa = PBXShellScriptBuildPhase; + 6C9AA79A1F7C1D8F00D08296 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "${PROJECT_DIR}/OSX/libsecurity_ocspd/mig/ocspd.defs", - ); - name = "ocspd mig"; - outputPaths = ( - $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_server.cpp, - $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_server.cpp, - $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd.h, + 6C9AA7A51F7C6F7F00D08296 /* SecArgParse.c in Sources */, + 6C9AA7A11F7C1D9000D08296 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p ${DERIVED_SRC}\n\nxcrun mig -isysroot \"${SDKROOT}\" \\\n-server $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_server.cpp \\\n-user $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd_client.cpp \\\n-header $BUILT_PRODUCTS_DIR/derived_src/security_ocspd/ocspd.h \\\n${PROJECT_DIR}/OSX/libsecurity_ocspd/mig/ocspd.defs"; }; - DCB342301D8A2C0E0054D16E /* Produce Schemas */ = { - isa = PBXShellScriptBuildPhase; + 6CAA8D1C1F842FB3007B6E03 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "$(SRCROOT)/OSX/libsecurity_cdsa_utilities/lib/KeySchema.m4", - "$(SRCROOT)/OSX/libsecurity_cdsa_utilities/lib/Schema.m4", - ); - name = "Produce Schemas"; - outputPaths = ( - $BUILT_PRODUCTS_DIR/derived_src/KeySchema.cpp, - $BUILT_PRODUCTS_DIR/derived_src/Schema.cpp, + 6CAA8D351F84306C007B6E03 /* main.m in Sources */, + 6CAA8D271F843002007B6E03 /* supd.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "TARGET=$BUILT_PRODUCTS_DIR/derived_src/KeySchema.cpp\nmkdir -p $BUILT_PRODUCTS_DIR/derived_src\n/usr/bin/m4 ${PROJECT_DIR}/OSX/libsecurity_cdsa_utilities/lib/KeySchema.m4 > $TARGET.new\ncmp -s $TARGET.new $TARGET || mv $TARGET.new $TARGET\nTARGET=$BUILT_PRODUCTS_DIR/derived_src/Schema.cpp\n/usr/bin/m4 ${PROJECT_DIR}/OSX/libsecurity_cdsa_utilities/lib/Schema.m4 > $TARGET.new\ncmp -s $TARGET.new $TARGET || mv $TARGET.new $TARGET"; }; - DCD0675A1D8CDCFD007602F1 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; + 6CCDF7801E3C25FA003F2555 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - $PROJECT_DIR/OSX/libsecurity_codesigning/lib/security_codesigning.d, - ); - outputPaths = ( - "$(BUILT_PRODUCTS_DIR)/cstemp/codesigning_dtrace.h", + 6CB5F47B1E402E6700DBF3F0 /* KeychainEntitledTestRunner.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p ${BUILT_PRODUCTS_DIR}/cstemp\n/usr/sbin/dtrace -h -C -s $PROJECT_DIR/OSX/libsecurity_codesigning/lib/security_codesigning.d -o ${BUILT_PRODUCTS_DIR}/cstemp/codesigning_dtrace.h\n"; }; - DCD0675C1D8CDD6D007602F1 /* Make SystemPolicy */ = { - isa = PBXShellScriptBuildPhase; + 6CF4A0B01E45488B00ECD7B5 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - "$(PROJECT_DIR)/OSX/libsecurity_codesigning/lib/syspolicy.sql", - ); - name = "Make SystemPolicy"; - outputPaths = ( - "$(BUILT_PRODUCTS_DIR)/cstemp/SystemPolicy", + D49111322095154B0066A1E4 /* Assets.xcassets in Sources */, + 6CF4A0BE1E45488B00ECD7B5 /* ViewController.m in Sources */, + 6CF4A0BB1E45488B00ECD7B5 /* main.m in Sources */, + 6CF4A0B81E45488B00ECD7B5 /* AppDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "mkdir -p \"$(dirname \"$SCRIPT_OUTPUT_FILE_0\")\"\nrm -f \"$SCRIPT_OUTPUT_FILE_0\"\nsqlite3 \"$SCRIPT_OUTPUT_FILE_0\" <$SRCROOT/OSX/libsecurity_codesigning/lib/RequirementKeywords.h\n"; }; - E7E0C6D11C90E87D00E69A21 /* chmod BATS Tests */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + 7913B2000D172B3900601FE9 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + 7913B2020D172B3900601FE9 /* ioSock.c in Sources */, + 7913B2030D172B3900601FE9 /* sslAppUtils.cpp in Sources */, + 7913B2050D172B3900601FE9 /* sslServer.cpp in Sources */, + DCC51C99209B7C1500A40387 /* print_cert.c in Sources */, ); - inputPaths = ( - "", - ); - name = "chmod BATS Tests"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; - showEnvVarsInLog = 0; + runOnlyForDeploymentPostprocessing = 0; }; - EB108F3D1E6CE4D2003B0456 /* chmod BATS Tests */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + ACBAF6BB1E9417F40007BA2F /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + ACBAF6F91E941B020007BA2F /* transform-01-sigverify.m in Sources */, ); - inputPaths = ( - "", - ); - name = "chmod BATS Tests"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; - showEnvVarsInLog = 0; + runOnlyForDeploymentPostprocessing = 0; }; - EBC15E801BE29A8C001C0C5B /* Chown BATS plist */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + BE197F2219116FD100BA91D1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + BE197F5E191173A800BA91D1 /* SWCViewController.m in Sources */, + BE197F3219116FD100BA91D1 /* SWCAppDelegate.m in Sources */, + BE197F2E19116FD100BA91D1 /* main.m in Sources */, ); - inputPaths = ( - ); - name = "Chown BATS plist"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "[ \"$(whoami)\" == \"root\" ] || exit 0\nchown root:wheel ${DSTROOT}/AppleInternal/CoreOS/BATS/unit_tests/*.plist"; - showEnvVarsInLog = 0; + runOnlyForDeploymentPostprocessing = 0; }; - EBC73F4B209A0C3400AE3350 /* Install OCMock framework */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; + BE442BAB18B7FDB800F24DAE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; files = ( + BE4AC9A218B7FFAD00B84964 /* swcagent.m in Sources */, ); - inputPaths = ( - ); - name = "Install OCMock framework"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "sh xcscripts/install-test-framework.sh OCMock.framework\n"; + runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 0C0BDB2B175685B000BC1A7E /* Sources */ = { + BEAA0027202A832500E51F45 /* Sources */ = { 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 */, - DC5F35AF1EE0F27C00900966 /* server_entitlement_helpers.c in Sources */, - DC4269101E82FD9F002B7110 /* server_security_helpers.c in Sources */, - DCB221591E8B08CA001598BC /* server_xpc.m in Sources */, - DC4269001E82038D002B7110 /* server_endpoint.m in Sources */, + 0CE15E2F222DF63600B7EAA5 /* SetValueTransformer.swift in Sources */, + 0CE15E2C222DF63600B7EAA4 /* RecoveryKey.swift in Sources */, + 0CE15E43222DF6A800B7EAA4 /* Recovery.m in Sources */, + BE92249E204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld in Sources */, + BE9F8D12206C121400B53D16 /* Decrypter.swift in Sources */, + DC391F8D21BF244000772585 /* CKKSSIV.m in Sources */, + 0CE15E30222DF63600B7EAA4 /* RecoverKeySet.swift in Sources */, + 0C3BB3582188E18C0018FC14 /* OTPrivateKey+SF.m in Sources */, + BECFA43D20F9493000B11002 /* Policy.swift in Sources */, + 0CB582D1218920090040C5F2 /* OTAuthenticatedCiphertext.m in Sources */, + 0CF70BD9218BED1000EC3515 /* CuttlefishExtensionWorkaround.swift in Sources */, + DC754C742228B59000A39C8E /* TrustedPeersHelperProtocol.m in Sources */, + DC391FA621C04D1500772585 /* OctagonPeerKeys.swift in Sources */, + DCF6320521C074F30030CCC0 /* CuttlefishAPIHelpers.swift in Sources */, + DC391F8C21BF222B00772585 /* CKKSTLKShare.m in Sources */, + BE9F8D19206C4AD300B53D16 /* ContainerMap.swift in Sources */, + BE9F4F8C2072D881004A52C2 /* Cuttlefish.pb.swift in Sources */, + DC391F9D21BF2F8100772585 /* CKKSConstants.m in Sources */, + BE9F8D10206C099800B53D16 /* Container.swift in Sources */, + 0CB582D3218920090040C5F2 /* OTPrivateKey.m in Sources */, + BE55C77C2044D0C90045863D /* Client.swift in Sources */, + BE55C77E2044D7E60045863D /* main.swift in Sources */, + DCAD8F8622C43EC1007C3872 /* Container_MachineIDs.swift in Sources */, + DCB0C295222F5EF60083AECB /* CuttlefishErrors.swift in Sources */, + 0CB582D021891FF40040C5F2 /* OTBottle.m in Sources */, + 0C0C4F86216FB73C00C14C61 /* EscrowKeys.swift in Sources */, + DCB9475621274A1900ED9272 /* TPHObjcTranslation.m in Sources */, + 0C3BB35A2188E18C0018FC14 /* OTAuthenticatedCiphertext+SF.m in Sources */, + 0CE15E3E222DF6A800B7EAA4 /* OTRecovery.m in Sources */, + DC391F8E21BF274600772585 /* CKKSPeer.m in Sources */, + DC391F8A21BF222500772585 /* CKKSKeychainBackedKey.m in Sources */, + 0C0C4F87216FB73F00C14C61 /* BottledPeer.swift in Sources */, + 0CB582D2218920090040C5F2 /* OTBottleContents.m in Sources */, + DC391F8F21BF284D00772585 /* CKKSSerializedKey.m in Sources */, + BEC0A96420B362EC00DBD772 /* Utils.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BECFA42A20F91AFE00B11002 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BECFA43120F91AFE00B11002 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0C2BCBAD1D06401F00ED7A2F /* Sources */ = { + BED208D51EDF950E00753952 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C2BCBBA1D06403B00ED7A2F /* dtlsEchoClient.c in Sources */, - 0C2BCBAF1D06401F00ED7A2F /* ioSock.c in Sources */, - 0C2BCBB01D06401F00ED7A2F /* sslAppUtils.cpp in Sources */, - DC52EBC51D80CEBA00B0A59C /* print_cert.c in Sources */, + BE22FC041EE3584400893431 /* mark.m in Sources */, + BE22FBCE1EE1E26600893431 /* Keychain.m in Sources */, + BE22FBD11EE2084100893431 /* Config.m in Sources */, + BE22FBC61EE0E8AB00893431 /* Monkey.m in Sources */, + BED208E81EDF974500753952 /* manifeststresstest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0C2BCBC21D0648D100ED7A2F /* Sources */ = { + BED987CF2099145300607A5F /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C2BCBCF1D0648EF00ED7A2F /* dtlsEchoServer.c in Sources */, - 0C2BCBC41D0648D100ED7A2F /* ioSock.c in Sources */, - 0C2BCBC51D0648D100ED7A2F /* sslAppUtils.cpp in Sources */, - DC52EBC41D80CEBA00B0A59C /* print_cert.c in Sources */, + 0CB582CB2189157F0040C5F2 /* OTPrivateKey.m in Sources */, + EBF5323A21C8B6330073C1C7 /* OTDefines.m in Sources */, + 0CB582C92189157F0040C5F2 /* OTBottle.m in Sources */, + 0CA4B4722171410200B17169 /* EscrowKeys.swift in Sources */, + BE536030209BC1FD0027E25A /* spi.c in Sources */, + BEA8558120B5DC7D00D5AD11 /* FakeCuttlefish.swift in Sources */, + 0CB5C678218B803C0044F730 /* OTPrivateKey+SF.m in Sources */, + DC05035E214083B200A8EDB7 /* TPHObjcTranslation.m in Sources */, + 0CE15E41222DF6A800B7EAA4 /* OTRecovery.m in Sources */, + BE536031209BC2F90027E25A /* SecdWatchdog.m in Sources */, + 0CB582C82189157F0040C5F2 /* OTAuthenticatedCiphertext.m in Sources */, + BED987E320991C4D00607A5F /* MockCuttlefish.swift in Sources */, + BEC373D020D87B4D00DBDF5B /* SecFramework.c in Sources */, + 0CB582CA2189157F0040C5F2 /* OTBottleContents.m in Sources */, + BE536032209BC3250027E25A /* server_endpoint.m in Sources */, + BE536034209BC3C40027E25A /* server_security_helpers.m in Sources */, + BECFA43E20F9493000B11002 /* Policy.swift in Sources */, + 0CA2282F2187A5CA00A1C56C /* BottledPeer.swift in Sources */, + DC747993222720C8001E0E8C /* MockCloudKit.m in Sources */, + 0CB5C677218B803C0044F730 /* OTAuthenticatedCiphertext+SF.m in Sources */, + BE727824209CBCA800F0DA77 /* Cuttlefish.pb.swift in Sources */, + BED987E120991B9B00607A5F /* Decrypter.swift in Sources */, + DC391FA721C04D6800772585 /* OctagonPeerKeys.swift in Sources */, + BE536033209BC3B30027E25A /* server_entitlement_helpers.c in Sources */, + BED987E020991B1100607A5F /* TrustedPeersHelper.xcdatamodeld in Sources */, + BED987D62099145300607A5F /* TrustedPeersHelperUnitTests.swift in Sources */, + BE4C6AB820CAF4F700EAD6BE /* ContainerSync.swift in Sources */, + 0CE15E46222DF6A800B7EAA4 /* Recovery.m in Sources */, + 0CE15E33222DF63600B7EAA4 /* RecoverKeySet.swift in Sources */, + 0CE15E2F222DF63600B7EAA4 /* RecoveryKey.swift in Sources */, + DCF6320721C075210030CCC0 /* CuttlefishAPIHelpers.swift in Sources */, + BED987DE2099156B00607A5F /* Container.swift in Sources */, + DCB0C292222F5E1D0083AECB /* CuttlefishErrors.swift in Sources */, + BECFA44320FD0A4B00B11002 /* LocalKeychainAnalytics.m in Sources */, + DCAD8F8922C43EDB007C3872 /* Container_MachineIDs.swift in Sources */, + 0CF70BDA218BEFAE00EC3515 /* CuttlefishExtensionWorkaround.swift in Sources */, + DCD24DEC228C9A480052604C /* SetValueTransformer.swift in Sources */, + BEC0A96520B362EC00DBD772 /* Utils.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0C85DFE21FB38BB6000343A7 /* Sources */ = { + BEF88C231EAFFC3F00357577 /* Sources */ = { 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 */, - 0C0DA5CF1FE1F1C5003BD3BB /* OTControlProtocol.m in Sources */, - 0C8A03461FDF42BA0042E8BE /* OTEscrowKeyTests.m in Sources */, - 0C8A034D1FDF4CCE0042E8BE /* OTLocalStoreTests.m in Sources */, - 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 */, - 0C46A5712034C6BA00F17112 /* OTControl.m in Sources */, - DCDB29721FD8821D00B5D242 /* SFAnalyticsSampler.m in Sources */, - DCDB297E1FD8849D00B5D242 /* SFObjCType.m in Sources */, - 0CC0445B1FFC4150004A5B63 /* CKKSControl.m in Sources */, - DCDB297C1FD8848A00B5D242 /* SFSQLite.m in Sources */, - 0CA4EBF4202B8DBE002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */, - DCDB297D1FD8849A00B5D242 /* SFSQLiteStatement.m in Sources */, - DCDB297B1FD8847100B5D242 /* SecTask.c in Sources */, - 0C1637291FD2066A00210823 /* SecdWatchdog.m in Sources */, - DCDB29791FD8844C00B5D242 /* client.c in Sources */, - DCDB297A1FD8845600B5D242 /* client_endpoint.m in Sources */, - 0CB975512023B199008D6B48 /* OTRampingTests.m in Sources */, - 0C16372B1FD2067F00210823 /* server_endpoint.m in Sources */, - 0C16372D1FD2069300210823 /* server_entitlement_helpers.c in Sources */, - 0C1637301FD206BC00210823 /* server_security_helpers.c in Sources */, - 0C1637271FD2065400210823 /* spi.c in Sources */, + BEF88C781EB000BE00357577 /* TPCategoryRule.m in Sources */, + BEF88C841EB000BE00357577 /* TPPeerDynamicInfo.m in Sources */, + BEF88C8A1EB000BE00357577 /* TPPolicy.m in Sources */, + DC730E1C224011E40051DD48 /* TPPBDictionaryMatchingRuleFieldExists.m in Sources */, + BEF88C801EB000BE00357577 /* TPModel.m in Sources */, + BEF88C8C1EB000BE00357577 /* TPPolicyDocument.m in Sources */, + DC2B9A5323147A3800D4C79D /* TPMachineID.m in Sources */, + BEF88C7E1EB000BE00357577 /* TPHash.m in Sources */, + DC730E1D224011E70051DD48 /* TPPBDictionaryMatchingRuleFieldRegexMatch.m in Sources */, + DC730E1B224011E20051DD48 /* TPPBDictionaryMatchingRule.m in Sources */, + BEF88C881EB000BE00357577 /* TPPeerStableInfo.m in Sources */, + BEB49F31206E98D0008DA7F4 /* TPECPublicKeyFactory.m in Sources */, + BEF88C861EB000BE00357577 /* TPPeerPermanentInfo.m in Sources */, + 1B4C444C223AE65500C6F97F /* TPPBPolicyKeyViewMapping.m in Sources */, + DC9061B922B02BA30071474D /* TPTypes.m in Sources */, + BEB49F35206E9A1A008DA7F4 /* SFKey+TPKey.m in Sources */, + BEF88C821EB000BE00357577 /* TPPeer.m in Sources */, + DCD7DD9F22B868F800161396 /* TPPBDispositionDuplicateMachineID.m in Sources */, + DCB4584C2240396E00115F8C /* NSError+UsefulConstructors.m in Sources */, + BECEC11320A508F600E97255 /* TPVoucher.m in Sources */, + BECFA46420FFB87500B11002 /* TPKey.m in Sources */, + DCF458B3221F6964007F5507 /* TPLog.m in Sources */, + DCE0775E21ADD71C002662FD /* TPPBDispositionEntry.m in Sources */, + DCAD8F8D22C55D76007C3872 /* TPPBDispositionDisallowedMachineID.m in Sources */, + DCE0776021ADD71C002662FD /* TPPBAncientEpoch.m in Sources */, + DCE0776221ADD71C002662FD /* TPPBPolicyProhibits.m in Sources */, + DCE0776421ADD71C002662FD /* TPPBUnknownMachineID.m in Sources */, + DCE0776621ADD71C002662FD /* TPPBDisposition.m in Sources */, + DCE0776821ADD71C002662FD /* TPPBPeerPermanentInfo.m in Sources */, + DC730E1222400D790051DD48 /* TPDictionaryMatchingRules.m in Sources */, + DCE0776A21ADD71C002662FD /* TPPBPeerDynamicInfo.m in Sources */, + DCE0776C21ADD71C002662FD /* TPPBPolicySecret.m in Sources */, + DCE0776E21ADD71C002662FD /* TPPBPeerStableInfo.m in Sources */, + DCE0777021ADD71C002662FD /* TPPBVoucher.m in Sources */, + DCE0777221ADD71C002662FD /* TPPBPolicyDocument.m in Sources */, + DCE0777421ADD71C002662FD /* TPPBPolicyCategoriesByView.m in Sources */, + DCE0777621ADD71C002662FD /* TPPBPolicyIntroducersByCategory.m in Sources */, + DCE0777821ADD71C002662FD /* TPPBPolicyModelToCategory.m in Sources */, + DCE0777A21ADD71C002662FD /* TPPBPolicyRedaction.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0C8BBEFE1FCB446400580909 /* Sources */ = { + BEF88C2C1EAFFC3F00357577 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C8BBF1B1FCB4EC500580909 /* OTControlProtocol.m in Sources */, - 0C8BBF091FCB447600580909 /* otctl.m in Sources */, - 4771DA2620A4C34800BA9772 /* OT.m in Sources */, - 0C8BBEFF1FCB446400580909 /* SecArgParse.c in Sources */, + 1B4AE38722400A22002188E1 /* TPDictionaryMatchingRules.m in Sources */, + BEF88C941EB000FD00357577 /* TPDummyDecrypter.m in Sources */, + BEF88C951EB000FD00357577 /* TPDummyEncrypter.m in Sources */, + BE72782B209D27C800F0DA77 /* TPKeyTests.m in Sources */, + BEF88C981EB000FD00357577 /* TPModelTests.m in Sources */, + DC730E142240103A0051DD48 /* TPDictionaryMatchingRuleTests.m in Sources */, + E291657F2048BCCB0046512B /* TPPBPeerStableInfoTests.m in Sources */, + BEF88C9B1EB000FD00357577 /* TPPeerTests.m in Sources */, + BEB49F37206E9B8B008DA7F4 /* TPECPublicKeyFactoryTests.m in Sources */, + BEF88C971EB000FD00357577 /* TPDummySigningKeyTests.m in Sources */, + 1BF640EF222EEB6C002D0FCB /* TPPolicyTests.m in Sources */, + BEF88C9A1EB000FD00357577 /* TPPeerStableInfoTests.m in Sources */, + BEF88C991EB000FD00357577 /* TPPeerPermanentInfoTests.m in Sources */, + BEF88C961EB000FD00357577 /* TPDummySigningKey.m in Sources */, + BEF88C9C1EB000FD00357577 /* TPPolicyDocumentTests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0C9AEEAE20783FBB00BF6237 /* Sources */ = { + D41257CB1E9410A300781F23 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C9AEEAF20783FBB00BF6237 /* SFSignInAnalyticsTests.m in Sources */, + D41257D91E9412B800781F23 /* trustd.c in Sources */, + DC5F35A81EE0F25300900966 /* server_entitlement_helpers.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0CF406112072E3E3003D6A7F /* Sources */ = { + D42C839521159146008D3D83 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0C5663EC20BE2DF30035F362 /* SFSignInAnalytics.m in Sources */, - 0CF406522072E422003D6A7F /* SFSignInAnalyticsTests.m in Sources */, + D43718A12116836300EA350A /* cmsutil.c in Sources */, + D43718A82116839300EA350A /* siginfoUtils.cpp in Sources */, + D437186E211682D800EA350A /* cert.c in Sources */, + D43718782116831A00EA350A /* cmsdigest.c in Sources */, + D437187B2116831A00EA350A /* cmsmessage.c in Sources */, + D437186B211682D800EA350A /* cmsattr.c in Sources */, + D437187D2116831A00EA350A /* cmsencdata.c in Sources */, + D437188B2116834400EA350A /* cmssiginfo.c in Sources */, + D437188F2116834400EA350A /* cmspubkey.c in Sources */, + D437189E2116836300EA350A /* plhash.c in Sources */, + D43718AA2116839300EA350A /* secoid.c in Sources */, + D437188E2116834400EA350A /* cmsrecinfo.c in Sources */, + D43718792116831A00EA350A /* cmsenvdata.c in Sources */, + D43718992116836300EA350A /* secalgid.c in Sources */, + D42C839C21159170008D3D83 /* CMSEncoder.cpp in Sources */, + D42C839D21159170008D3D83 /* CMSUtils.cpp in Sources */, + D437186A211682D800EA350A /* cmsarray.c in Sources */, + D43718AD2116839300EA350A /* smimeutil.c in Sources */, + D437186C211682D800EA350A /* cmsasn1.c in Sources */, + D437186D211682D800EA350A /* cmscinfo.c in Sources */, + D43718B0211683AA00EA350A /* tsaSupport.c in Sources */, + D4371869211682D800EA350A /* cmscipher.c in Sources */, + D43718B1211683AA00EA350A /* tsaTemplates.c in Sources */, + D437189B2116836300EA350A /* secitem.c in Sources */, + D437188C2116834400EA350A /* cmssigdata.c in Sources */, + D42C839E21159170008D3D83 /* CMSDecoder.cpp in Sources */, + D437187A2116831A00EA350A /* cmsdecode.c in Sources */, + D437187F2116831A00EA350A /* cmsdigdata.c in Sources */, + D437189C2116836300EA350A /* cryptohi.c in Sources */, + D43718882116834400EA350A /* cmsreclist.c in Sources */, + D437187C2116831A00EA350A /* cmsencode.c in Sources */, + D437189F2116836300EA350A /* SecCMS.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D44D1F632115893000E76E1A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D44D1F7921158A3D00E76E1A /* cmspubkey.c in Sources */, + D4D1FDD621164138003538E2 /* cmssigdata.c in Sources */, + D44D1F7321158A1700E76E1A /* secoid.c in Sources */, + D44D1F7C21158A4900E76E1A /* cmsencdata.c in Sources */, + D44D1F8021158A5B00E76E1A /* cmsarray.c in Sources */, + D42C838121158ACC008D3D83 /* crypto-embedded.c in Sources */, + D44D1F7E21158A5300E76E1A /* cmsdecode.c in Sources */, + D44D1F70211589AC00E76E1A /* CMSDecoder.c in Sources */, + D42C837F21158ACC008D3D83 /* cmsreclist.c in Sources */, + D44D1F7221158A1300E76E1A /* smimeutil.c in Sources */, + D42C837E21158ACC008D3D83 /* cmsencode.c in Sources */, + D44D1F7621158A3300E76E1A /* cmsutil.c in Sources */, + D44D1F7D21158A4C00E76E1A /* cmsdigdata.c in Sources */, + D42C837D21158ACC008D3D83 /* cmsdigest.c in Sources */, + D42C838921158B4E008D3D83 /* SecAsn1Item.c in Sources */, + D44D1F7A21158A4000E76E1A /* cmsmessage.c in Sources */, + D44D1F8121158A5D00E76E1A /* cmsasn1.c in Sources */, + D44D1F7421158A1A00E76E1A /* secalgid.c in Sources */, + D44D1F7B21158A4400E76E1A /* cmsenvdata.c in Sources */, + D44D1F71211589AC00E76E1A /* CMSEncoder.c in Sources */, + D44D1F7821158A3A00E76E1A /* cmsrecinfo.c in Sources */, + D42C837C21158ACC008D3D83 /* cmscinfo.c in Sources */, + D44D1F8221158A6000E76E1A /* cmsattr.c in Sources */, + D4D1FDD721164167003538E2 /* cmscipher.c in Sources */, + D44D1F7521158A1E00E76E1A /* plhash.c in Sources */, + D44D1F6F2115899C00E76E1A /* CMSUtils.c in Sources */, + D42C838021158ACC008D3D83 /* cmssiginfo.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D453A4A72122236D00850A26 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D40881F5217573C900180E81 /* SecTrustStatusCodes.c in Sources */, + D4FD421D217D789C002B7EE2 /* NameConstraintsTests.m in Sources */, + D4FD4221217D7B2E002B7EE2 /* PathScoringTests.m in Sources */, + D40881F42175738C00180E81 /* SecPolicyLeafCallbacks.c in Sources */, + D40881F32175733F00180E81 /* SecPolicy.c in Sources */, + D40881F22175733500180E81 /* SecSignatureVerificationSupport.c in Sources */, + D40881F12175732E00180E81 /* SecCertificate.c in Sources */, + D40881F02175732600180E81 /* SecTrustStore.c in Sources */, + D40881EF2175731E00180E81 /* SecTrust.c in Sources */, + D458C523214E33380043D982 /* KeySizeTests.m in Sources */, + D458C4BD214E19AF0043D982 /* SignatureAlgorithmTests.m in Sources */, + D458C4B1214E198F0043D982 /* CTTests.m in Sources */, + D458C4B9214E19AF0043D982 /* PathParseTests.m in Sources */, + D458C516214E286D0043D982 /* PolicyTests.m in Sources */, + D458C524214E33430043D982 /* VerifyDateTests.m in Sources */, + D458C4B3214E198F0043D982 /* EvaluationBasicTests.m in Sources */, + D458C521214E33260043D982 /* ECTests.m in Sources */, + D458C4BB214E19AF0043D982 /* iAPTests.m in Sources */, + D4AC8BE921320AD0006E9871 /* CertificateParseTests.m in Sources */, + D4D92DA622788FEB0009A7CF /* NISTTests.m in Sources */, + D442830022D68564001746B3 /* TrustEvaluationTestHelpers.m in Sources */, + D453A4AB2122236D00850A26 /* TrustEvaluationTestCase.m in Sources */, + D453A4AD2122236D00850A26 /* TrustFrameworkTestCase.m in Sources */, + D4EA5CF922B225D100883439 /* LoggingServerTests.m in Sources */, + D4056A1B22712A650026E24E /* SSLPolicyTests.m in Sources */, + D458C4C4214E19FC0043D982 /* TrustInterfaceTests.m in Sources */, + D453A4AF2122236D00850A26 /* CertificateInterfaceTests.m in Sources */, + D458C4C2214E19FC0043D982 /* TrustSettingsInterfaceTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D458C4DD214E1DE00043D982 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + D458C4FB214E1E1B0043D982 /* ViewController.m in Sources */, + D458C4F9214E1E1B0043D982 /* AppDelegate.m in Sources */, + D458C4FD214E1E6C0043D982 /* appmain.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 225394AD1E3080A600D3CD9B /* Sources */ = { + D458C502214E20530043D982 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 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 */, - 225394BB1E30822700D3CD9B /* codedirectory.cpp in Sources */, - DC5BD5831E8C6FC800C5EC49 /* SecTask.c in Sources */, - 225394BC1E30823E00D3CD9B /* cs.cpp in Sources */, - 225394BD1E30824C00D3CD9B /* SecCode.cpp in Sources */, - 225394BE1E30825500D3CD9B /* SecStaticCode.cpp in Sources */, - 225394BF1E30826100D3CD9B /* SecRequirement.cpp in Sources */, - 225394C01E30826B00D3CD9B /* diskrep.cpp in Sources */, - 225394C11E30827600D3CD9B /* filediskrep.cpp in Sources */, - 225394C21E30827E00D3CD9B /* kerneldiskrep.cpp in Sources */, - 225394C31E30828800D3CD9B /* StaticCode.cpp in Sources */, - 225394C51E3082A100D3CD9B /* requirement.cpp in Sources */, - 225394C61E3082AB00D3CD9B /* Requirements.cpp in Sources */, - DCD7EE851F4E47D2007D9804 /* reqparser.cpp in Sources */, - 225394C71E3082B600D3CD9B /* reqdumper.cpp in Sources */, - 225394C81E3082BE00D3CD9B /* reqinterp.cpp in Sources */, - 225394C91E3082C900D3CD9B /* reqmaker.cpp in Sources */, - 225394CA1E3082D500D3CD9B /* macho++.cpp in Sources */, - 225394CB1E30831D00D3CD9B /* machorep.cpp in Sources */, - 225394CC1E30832A00D3CD9B /* sigblob.cpp in Sources */, - 225394CD1E30833400D3CD9B /* resources.cpp in Sources */, - 225394CE1E30833F00D3CD9B /* cfmunge.cpp in Sources */, - 225394CF1E30835700D3CD9B /* csutilities.cpp in Sources */, - 225394D01E30836200D3CD9B /* singlediskrep.cpp in Sources */, - 225394D11E30836F00D3CD9B /* reqreader.cpp in Sources */, - 225394D21E30837900D3CD9B /* cserror.cpp in Sources */, + D458C510214E207C0043D982 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3DD1FF02201C07F30086D049 /* Sources */ = { + D4707A0121136E69005BCFDA /* 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 */, + D40881FA217573F800180E81 /* SecPolicy.c in Sources */, + D40881FB217573F800180E81 /* SecPolicyLeafCallbacks.c in Sources */, + D40881F9217573EF00180E81 /* SecSignatureVerificationSupport.c in Sources */, + D40881F8217573E700180E81 /* SecCertificate.c in Sources */, + D40881F7217573E000180E81 /* SecTrustStore.c in Sources */, + D4D92DA522788FEB0009A7CF /* NISTTests.m in Sources */, + D40881F6217573D500180E81 /* SecTrust.c in Sources */, + D458C520214E33260043D982 /* ECTests.m in Sources */, + D458C522214E33370043D982 /* KeySizeTests.m in Sources */, + D4056A1A22712A650026E24E /* SSLPolicyTests.m in Sources */, + D4EA5CF822B225D100883439 /* LoggingServerTests.m in Sources */, + D4FD4220217D7B2E002B7EE2 /* PathScoringTests.m in Sources */, + D458C4BC214E19AF0043D982 /* SignatureAlgorithmTests.m in Sources */, + D4FD421C217D789C002B7EE2 /* NameConstraintsTests.m in Sources */, + D4A0F8CC211E6A8300443CA1 /* TrustEvaluationTestCase.m in Sources */, + D4A0F8C7211E6A5800443CA1 /* TrustFrameworkTestCase.m in Sources */, + D458C4C3214E19FC0043D982 /* TrustInterfaceTests.m in Sources */, + D4AC8BE821320AD0006E9871 /* CertificateParseTests.m in Sources */, + D4A0F8C8211E6A5800443CA1 /* CertificateInterfaceTests.m in Sources */, + D458C4B0214E198F0043D982 /* CTTests.m in Sources */, + D458C4B2214E198F0043D982 /* EvaluationBasicTests.m in Sources */, + D458C4BA214E19AF0043D982 /* iAPTests.m in Sources */, + D458C4B8214E19AF0043D982 /* PathParseTests.m in Sources */, + D458C525214E33440043D982 /* VerifyDateTests.m in Sources */, + D458C515214E286C0043D982 /* PolicyTests.m in Sources */, + D4EF32182156DDEB000A31A5 /* TrustSettingsInterfaceTests.m in Sources */, + D44282FF22D68564001746B3 /* TrustEvaluationTestHelpers.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 3DD1FFB3201FDB1D0086D049 /* Sources */ = { + D4ADA3151E2B41670031CEA3 /* 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 */, + 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.m in Sources */, + D43DBF021E99D1CA00C04AEA /* SecCertificateServer.c in Sources */, + D43DBF031E99D1CA00C04AEA /* SecCertificateSource.c in Sources */, + 5F84950222DFB505008B3EFB /* SecTrustExceptionResetCount.m in Sources */, + D43DBF041E99D1CA00C04AEA /* SecOCSPCache.c in Sources */, + D43DBF051E99D1CA00C04AEA /* SecOCSPRequest.c in Sources */, + D4B68C68211A827C009FED69 /* trustd_spi.c in Sources */, + D43761671EB2996C00954447 /* SecRevocationNetworking.m in Sources */, + D4EF3221215F0F7F000A31A5 /* SecTrustStoreServer.m in Sources */, + D43DBF061E99D1CA00C04AEA /* SecOCSPResponse.c in Sources */, + D43DBF071E99D1CA00C04AEA /* SecPinningDb.m in Sources */, + D43DBF081E99D1CA00C04AEA /* SecPolicyServer.c in Sources */, + 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 */, ); runOnlyForDeploymentPostprocessing = 0; }; - 438169081B4EDCBD00C54D58 /* Sources */ = { + D4D1FDD921165F8B003538E2 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 438169E31B4EDEE200C54D58 /* SOSCCAuthPlugin.m in Sources */, + D4D1FDE221165FC6003538E2 /* cms-trust-settings-test.c in Sources */, + D437185F211671A500EA350A /* cms-01-basic.c in Sources */, + D4371860211671A500EA350A /* smime-cms-test.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 470415CB1E5E14B5001F3D95 /* Sources */ = { + DA30D6721DF8C8FB00EC6B43 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 470415DC1E5E1534001F3D95 /* main.m in Sources */, + DA30D6851DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4718AE0F205B39620068EC3F /* Sources */ = { + DA41FE0A2241ADC000838FB3 /* 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 */, + DACAD62A229F6E6A0002BBC3 /* OTPairingSession.m in Sources */, + DA45865C2245AEDB0073F993 /* OTPairingService.m in Sources */, + DA41FE1A2241AF4600838FB3 /* main.m in Sources */, + 0CC593F02299B9AA006C34B5 /* SecInternalRelease.c in Sources */, + 0CC593F62299EC3D006C34B5 /* OTDeviceInformationAdapter.m in Sources */, + DAC58D202244528B00D4CD41 /* OTPairingPacketContext.m in Sources */, + DA20716222E9367500E209E4 /* NSError+UsefulConstructors.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4718AE2F205B39C40068EC3F /* Sources */ = { + DAE40BC620CF3E46002D5674 /* 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 */, + DAE40BD920CF3F0F002D5674 /* secitemcanarytest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4727FBB31F9918580003AE36 /* Sources */ = { + DC0067A81D87876F005AF8DB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 47DE88DA1FA7B07400DD3254 /* server_xpc.m in Sources */, - 4727FBEF1F9924FB0003AE36 /* server_security_helpers.c in Sources */, - 4727FBEE1F9924DA0003AE36 /* server_entitlement_helpers.c in Sources */, - 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 */, + DC0067C21D8787A4005AF8DB /* ucspNotifyReceiver.cpp in Sources */, + DC0067C11D87879D005AF8DB /* ucspServer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 47702B1A1E5F409700B29577 /* Sources */ = { + DC0067C91D878898005AF8DB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 47702B281E5F412500B29577 /* main.m in Sources */, + DC0067D11D8788B7005AF8DB /* ucspClientC.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 47702B2A1E5F492C00B29577 /* Sources */ = { + DC05037221409A4000A8EDB7 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 47702B371E5F495C00B29577 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4771D96E209A755800BA9772 /* Sources */ = { + DC0BC54D1D8B6D2D00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 47D13759209CD1A200CAD493 /* NSError+UsefulConstructors.m in Sources */, - 4771DA2520A4C33A00BA9772 /* OT.m in Sources */, - 4771D980209A75FE00BA9772 /* KeychainDataclassOwner.m in Sources */, + DC0BC5611D8B6D6000070CB0 /* main.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 478D42751FD72A8100CAB645 /* Sources */ = { + DC0BC5641D8B6E3D00070CB0 /* 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 */, - 477A1FE5203763A500ACD81D /* KeychainAPITests.m in Sources */, - 478D427C1FD72A8100CAB645 /* server_endpoint.m in Sources */, + DC0BC5741D8B6E7700070CB0 /* main-tsa.m in Sources */, + DC0BC5751D8B6E7700070CB0 /* timestampclient.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 47C2F17F2059CB680062DE30 /* Sources */ = { + DC0BC5871D8B70E700070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 47C2F18A2059CB820062DE30 /* KeychainModel.xcdatamodeld in Sources */, + DC0BC5A81D8B711000070CB0 /* cuPem.cpp in Sources */, + DC0BC5A21D8B711000070CB0 /* cuEnc64.c in Sources */, + DC0BC59E1D8B711000070CB0 /* cuCdsaUtils.cpp in Sources */, + DC0BC5A01D8B711000070CB0 /* cuDbUtils.cpp in Sources */, + DC0BC5A61D8B711000070CB0 /* cuOidParser.cpp in Sources */, + DC0BC5AA1D8B711000070CB0 /* cuPrintCert.cpp in Sources */, + DC0BC5AC1D8B711000070CB0 /* cuTimeStr.cpp in Sources */, + DC0BC5A41D8B711000070CB0 /* cuFileIo.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 47C51B801EEA657D0032D9E5 /* Sources */ = { + DC0BC5B21D8B71FD00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 47C51B871EEA657D0032D9E5 /* SecurityUnitTests.m in Sources */, + DC0BC5BC1D8B723500070CB0 /* checkpw.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4C32C0AC0A4975F6002891BD /* Sources */ = { + DC0BC5C21D8B72E700070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CAA8CFF1F83E800007B6E03 /* SFSQLite.m in Sources */, - 6CDB5FF61FA78D1B00410924 /* SFAnalyticsMultiSampler.m in Sources */, - D46246A61F9AE61000D63882 /* oids.c 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 */, - 0C8BBF131FCB4AFA00580909 /* OTControlProtocol.m in Sources */, - EB10A3E620356E2000E84270 /* OTConstants.m in Sources */, - 18F7F67914D77F4400F88A12 /* NtlmGenerator.c in Sources */, - 0CD8CB051ECA50780076F37F /* SOSPeerOTRTimer.m in Sources */, - DCA85B981E8D980A00BA7241 /* client_endpoint.m in Sources */, - 6CE3654E1FA100E50012F6AB /* SFAnalytics.m in Sources */, - 18F7F67A14D77F4400F88A12 /* ntlmBlobPriv.c in Sources */, - 6CAA8CFC1F83E7EA007B6E03 /* SFObjCType.m in Sources */, - E7B00700170B581D00B27966 /* Security.exp-in in Sources */, - 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 */, + DC0BC5CF1D8B730D00070CB0 /* test-checkpw.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4C52D0B016EFC61E0079966E /* Sources */ = { + DC0BC5D81D8B73B000070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4C3DD6B0179755560093F9D8 /* NSDate+TimeIntervalDescription.m in Sources */, - 4C52D0E816EFCCA30079966E /* NSArray+map.m in Sources */, - 4C52D0E716EFCCA20079966E /* Applicant.m in Sources */, - 4CC3D29D178F698D0070FCC4 /* PersistentState.m in Sources */, - 4C52D0BA16EFC61E0079966E /* CircleJoinRequested.m in Sources */, + DC0BC5D91D8B73B000070CB0 /* test-checkpw.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4C711D6313AFCD0900FE865D /* Sources */ = { + DC0BC5E41D8B742200070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 476541A71F33EE3F00413F65 /* SecdWatchdog.m in Sources */, - 4CC92B1D15A3BF2F00C6D578 /* testmain.c in Sources */, - DC4268F61E82036F002B7110 /* server_endpoint.m in Sources */, - 0C78F1CD16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */, - DCB221531E8B08BC001598BC /* server_xpc.m in Sources */, - DCCD33D01E3FEF2A00AA4AD1 /* spi.c in Sources */, - DC42690C1E82FD9A002B7110 /* server_security_helpers.c in Sources */, - DC5F35AA1EE0F27100900966 /* server_entitlement_helpers.c in Sources */, - 0C78F1CF16A5E1BF00654E08 /* sectask_ipc.defs in Sources */, + DC0BC5F11D8B745700070CB0 /* comcryption.c in Sources */, + DC0BC5F31D8B745700070CB0 /* comcryptPriv.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4C9DE9CF1181AC4800CF5C27 /* Sources */ = { + DC0BC5FA1D8B752B00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4C9DE9E31181AC8300CF5C27 /* sslEcdsa.cpp in Sources */, - 4C9DEAAD1181B39300CF5C27 /* ioSock.c in Sources */, - 4C9DEAB11181B39800CF5C27 /* sslAppUtils.cpp in Sources */, + DC0BC6661D8B755200070CB0 /* CryptKitAsn1.cpp in Sources */, + DC0BC6681D8B755200070CB0 /* CryptKitDER.cpp in Sources */, + DC0BC6981D8B755200070CB0 /* HmacSha1Legacy.c in Sources */, + DC0BC6511D8B755200070CB0 /* byteRep.c in Sources */, + DC0BC65D1D8B755200070CB0 /* ckSHA1.c in Sources */, + DC0BC6611D8B755200070CB0 /* ckutilities.c in Sources */, + DC0BC66C1D8B755200070CB0 /* curveParams.c in Sources */, + DC0BC6701D8B755200070CB0 /* elliptic.c in Sources */, + DC0BC6731D8B755200070CB0 /* ellipticProj.c in Sources */, + DC0BC6751D8B755200070CB0 /* enc64.c in Sources */, + DC0BC6781D8B755200070CB0 /* falloc.c in Sources */, + DC0BC67E1D8B755200070CB0 /* feeDigitalSignature.c in Sources */, + DC0BC6801D8B755200070CB0 /* feeECDSA.c in Sources */, + DC0BC6821D8B755200070CB0 /* feeFEED.c in Sources */, + DC0BC6841D8B755200070CB0 /* feeFEEDExp.c in Sources */, + DC0BC6871D8B755200070CB0 /* feeHash.c in Sources */, + DC0BC6891D8B755200070CB0 /* feePublicKey.c in Sources */, + DC0BC68C1D8B755200070CB0 /* feeRandom.c in Sources */, + DC0BC68F1D8B755200070CB0 /* giantIntegers.c in Sources */, + DC0BC69A1D8B755200070CB0 /* platform.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4CB740A00A47567C00D641BB /* Sources */ = { + DC0BC7471D8B771600070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E7104A0C169E171900DB0045 /* security_tool_commands.c in Sources */, - E78A9ADA1D34959200006B5B /* NSFileHandle+Formatting.m in Sources */, + DC0BC79D1D8B773000070CB0 /* attachment.cpp in Sources */, + DC0BC7AE1D8B773000070CB0 /* modloader.cpp in Sources */, + DC0BC79F1D8B773000070CB0 /* cspattachment.cpp in Sources */, + DC0BC7A21D8B773000070CB0 /* cssmcontext.cpp in Sources */, + DC0BC7B21D8B773000070CB0 /* oidsalg.c in Sources */, + DC0BC7AA1D8B773000070CB0 /* modload_plugin.cpp in Sources */, + DC0BC7B41D8B773000070CB0 /* oidscrl.cpp in Sources */, + DC0BC79B1D8B773000070CB0 /* attachfactory.cpp in Sources */, + DC0BC7A51D8B773000070CB0 /* cssmmds.cpp in Sources */, + DC0BC7AC1D8B773000070CB0 /* modload_static.cpp in Sources */, + DC0BC7B51D8B773000070CB0 /* transition.cpp in Sources */, + DC0BC7A11D8B773000070CB0 /* cssm.cpp in Sources */, + DC0BC7B31D8B773000070CB0 /* oidscert.cpp in Sources */, + DC0BC7B01D8B773000070CB0 /* module.cpp in Sources */, + DC0BC7A71D8B773000070CB0 /* guids.cpp in Sources */, + DC0BC7A81D8B773000070CB0 /* manager.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4CE5A54A09C796E100D27A3F /* Sources */ = { + DC0BC89A1D8B7CBD00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4CE5A55B09C7970A00D27A3F /* SSLViewer.c in Sources */, - 4CE5A66009C79E0600D27A3F /* ioSock.c in Sources */, - 4CE5A66109C79E0600D27A3F /* sslAppUtils.cpp in Sources */, - DC52EA9C1D80CC8300B0A59C /* print_cert.c in Sources */, + DC0BC8BC1D8B7CFF00070CB0 /* DbQuery.cpp in Sources */, + DC0BC8B81D8B7CFF00070CB0 /* AtomicFile.cpp in Sources */, + DC0BC8B61D8B7CFF00070CB0 /* AppleDatabase.cpp in Sources */, + DC0BC8C21D8B7CFF00070CB0 /* MetaRecord.cpp in Sources */, + DC0BC8BA1D8B7CFF00070CB0 /* DbIndex.cpp in Sources */, + DC0BC8BE1D8B7CFF00070CB0 /* DbValue.cpp in Sources */, + DC0BC8C51D8B7CFF00070CB0 /* SelectionPredicate.cpp in Sources */, + DC0BC8C01D8B7CFF00070CB0 /* MetaAttribute.cpp in Sources */, + DC0BC8C71D8B7CFF00070CB0 /* ReadWriteSection.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 52D82BDA16A621F70078DFE5 /* Sources */ = { + DC0BC8CE1D8B7DA200070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E7C787201DCA4D430087FC34 /* CKDAKSLockMonitor.m in Sources */, - DC55329B1DDAA28600B6A6A7 /* XPCNotificationDispatcher.m in Sources */, - E7A5F4D21C0CFF7900F3BEBB /* CKDKVSProxy.m in Sources */, - E7B945B31CFE5EBD0027F31D /* CKDSecuritydAccount.m in Sources */, - E7A5F4D51C0CFF7900F3BEBB /* cloudkeychainproxy.m in Sources */, - E7A5F4D81C0D01B000F3BEBB /* SOSCloudKeychainConstants.c in Sources */, - E722E9121CE92DFC005AD94B /* CKDKVSStore.m in Sources */, + DC0BC8EF1D8B7DD000070CB0 /* ManifestSigner.cpp in Sources */, + DC0BC8F11D8B7DD000070CB0 /* Manifest.cpp in Sources */, + DC0BC8F41D8B7DD000070CB0 /* SecManifest.cpp in Sources */, + DC0BC8E91D8B7DD000070CB0 /* SecureDownloadInternal.c in Sources */, + DC0BC8E71D8B7DCF00070CB0 /* SecureDownload.cpp in Sources */, + DC0BC8ED1D8B7DD000070CB0 /* ManifestInternal.cpp in Sources */, + DC0BC8E51D8B7DCF00070CB0 /* Download.cpp in Sources */, + DC0BC8EB1D8B7DD000070CB0 /* AppleManifest.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 534647FD17331E1100FE9172 /* Sources */ = { + DC0BC8FB1D8B7E8000070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4771DA2720A4C37D00BA9772 /* OT.m in Sources */, - 5346481E173322BD00FE9172 /* KeychainSyncAccountNotification.m in Sources */, + DC0BC9201D8B7EA700070CB0 /* MDSDictionary.cpp in Sources */, + DC0BC91E1D8B7EA700070CB0 /* MDSDatabase.cpp in Sources */, + DC0BC9181D8B7EA700070CB0 /* MDSAttrParser.cpp in Sources */, + DC0BC9241D8B7EA700070CB0 /* MDSSchema.cpp in Sources */, + DC0BC9221D8B7EA700070CB0 /* MDSModule.cpp in Sources */, + DC0BC91C1D8B7EA700070CB0 /* MDSAttrUtils.cpp in Sources */, + DC0BC91A1D8B7EA700070CB0 /* MDSAttrStrings.cpp in Sources */, + DC0BC9261D8B7EA700070CB0 /* MDSSession.cpp in Sources */, + DC0BC9171D8B7EA700070CB0 /* mdsapi.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5E10992119A5E55800A60E2B /* Sources */ = { + DC0BC9301D8B7F6A00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5E10995219A5E5CE00A60E2B /* ISProtectedItemsController.m in Sources */, + DC0BC95B1D8B7FFE00070CB0 /* ocspd_client.cpp in Sources */, + DC0BC9461D8B7FA700070CB0 /* ocspdDbSchema.cpp in Sources */, + DC0BC9581D8B7FFE00070CB0 /* ocspd.defs in Sources */, + DC0BC94A1D8B7FA700070CB0 /* ocspResponse.cpp in Sources */, + DC0BC95A1D8B7FFE00070CB0 /* ocspd_server.cpp in Sources */, + DC0BC94F1D8B7FE000070CB0 /* ocspdClient.cpp in Sources */, + DC0BC9481D8B7FA700070CB0 /* ocspExtensions.cpp in Sources */, + DC0BC9421D8B7FA700070CB0 /* ocspdUtils.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 5EBE24761B00CCAE0007DB0E /* Sources */ = { + DC0BC9681D8B810A00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4765419B1F33ED7E00413F65 /* SecdWatchdog.m in Sources */, - DCB221581E8B08C9001598BC /* server_xpc.m in Sources */, - DCA85B971E8D980200BA7241 /* client.c in Sources */, - DCCD33E91E3FFDBF00AA4AD1 /* spi.c in Sources */, - DCA85B9B1E8D981200BA7241 /* client_endpoint.m in Sources */, - DC4269111E82FDA0002B7110 /* server_security_helpers.c in Sources */, - DC5F35AE1EE0F27C00900966 /* server_entitlement_helpers.c in Sources */, - 5EBE247D1B00CCAE0007DB0E /* main.c in Sources */, - 5E4E05A41B0CA0FD001C4A31 /* sec_acl_stress.c in Sources */, - DC4268FF1E82038C002B7110 /* server_endpoint.m in Sources */, + DC0BC9881D8B813800070CB0 /* pkcs12Crypto.cpp in Sources */, + DC0BC9921D8B813800070CB0 /* pkcs12Utils.cpp in Sources */, + DC0BC98B1D8B813800070CB0 /* pkcs12Decode.cpp in Sources */, + DC0BC9841D8B813800070CB0 /* pkcs12BagAttrs.cpp in Sources */, + DC0BC9861D8B813800070CB0 /* pkcs12Coder.cpp in Sources */, + DC0BC98C1D8B813800070CB0 /* pkcs12Encode.cpp in Sources */, + DC0BC9961D8B813800070CB0 /* SecPkcs12.cpp in Sources */, + DC0BC98E1D8B813800070CB0 /* pkcs12SafeBag.cpp in Sources */, + DC0BC98D1D8B813800070CB0 /* pkcs12Keychain.cpp in Sources */, + DC0BC9941D8B813800070CB0 /* pkcs7Templates.cpp in Sources */, + DC0BC9901D8B813800070CB0 /* pkcs12Templates.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6C46057A1F882B9B001421B6 /* Sources */ = { + DC0BC99C1D8B81BE00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CB96BB21F966DA400E11457 /* SFSQLite.m in Sources */, - 6CB96BB31F966DA400E11457 /* SFSQLiteStatement.m in Sources */, - 6CBF65421FA2255800A68667 /* SFAnalyticsActivityTracker.m in Sources */, - 6CDF8DF21F9649AB00140B54 /* SFAnalyticsSampler.m in Sources */, - 6CDF8DF41F9649C000140B54 /* SFAnalytics.m in Sources */, - 6C4605BC1F882DB6001421B6 /* SFAnalyticsTests.m in Sources */, - 6C13AE471F8E9F5F00F047E3 /* supd.m in Sources */, - 6C4605BD1F882DC3001421B6 /* SupdTests.m in Sources */, - 6CDB5FFA1FA78D2500410924 /* SFAnalyticsMultiSampler.m in Sources */, - 6CB96BAC1F966D6500E11457 /* main.m in Sources */, - 6CB96BB61F966E4300E11457 /* SFObjCType.m in Sources */, - 6CDF8DF31F9649C000140B54 /* SFAnalyticsSQLiteStore.m in Sources */, + DC0BC9BE1D8B81EF00070CB0 /* SDCSPSession.cpp in Sources */, + DC0BC9B81D8B81EF00070CB0 /* SDCSPDLDatabase.cpp in Sources */, + DC0BC9C01D8B81EF00070CB0 /* SDDLSession.cpp in Sources */, + DC0BC9B51D8B81EF00070CB0 /* SDContext.cpp in Sources */, + DC0BC9BC1D8B81EF00070CB0 /* SDCSPDLSession.cpp in Sources */, + DC0BC9C21D8B81EF00070CB0 /* SDFactory.cpp in Sources */, + DC0BC9C41D8B81EF00070CB0 /* SDKey.cpp in Sources */, + DC0BC9BA1D8B81EF00070CB0 /* SDCSPDLPlugin.cpp in Sources */, + DC0BC9B71D8B81EF00070CB0 /* SDCSPDLBuiltin.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6C98083D1E788AEB00E70590 /* Sources */ = { + DC0BC9CA1D8B824700070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CBF65431FA2257100A68667 /* SFAnalyticsActivityTracker.m in Sources */, - 6CAA8CF71F83E79E007B6E03 /* SFSQLite.m in Sources */, - 476541A41F33EDED00413F65 /* SecdWatchdog.m in Sources */, - 47B011991F17D78D0030B49F /* SFSQLiteStatement.m in Sources */, - DC2D438F1F0EEC2A0005D382 /* MockCloudKit.m in Sources */, - 6CDF8DEF1F96495600140B54 /* SFAnalyticsSampler.m in Sources */, - DCB515E21ED3D134001F1152 /* SecTask.c in Sources */, - DCB515E11ED3D11A001F1152 /* client.c in Sources */, - 6C9808A61E788CD200E70590 /* CKKSCloudKitTests.m in Sources */, - 6C98083E1E788AEB00E70590 /* spi.c in Sources */, - DC2353301ECA658900D7C1BE /* server_security_helpers.c in Sources */, - 6CAA8CF01F83E65E007B6E03 /* SFObjCType.m in Sources */, - 6CAA8D131F83ECD4007B6E03 /* SFAnalytics.m in Sources */, - DC2353321ECA659000D7C1BE /* server_xpc.m in Sources */, - 6CDB5FF91FA78D2400410924 /* SFAnalyticsMultiSampler.m in Sources */, - DC5F35B11EE0F28B00900966 /* server_entitlement_helpers.c in Sources */, - DC2353291ECA658300D7C1BE /* server_endpoint.m in Sources */, - 6CAA8CF91F83E7AA007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, + 5AA465CF2228AF4B00C068F4 /* SecProtocol.c in Sources */, + 5AA465D02228AF4B00C068F4 /* SecProtocolHelper.m in Sources */, + 5AA465D12228AF4B00C068F4 /* SecProtocolConfiguration.m in Sources */, + 5AA465D22228AF4B00C068F4 /* SecProtocolTypes.m in Sources */, + DC0BC9FA1D8B827200070CB0 /* sslRecord.c in Sources */, + DC0BC9F91D8B827200070CB0 /* sslContext.c in Sources */, + DC0BC9FC1D8B827200070CB0 /* tlsCallbacks.c in Sources */, + DC0BC9F71D8B827200070CB0 /* SSLRecordInternal.c in Sources */, + DC0BC9F61D8B827200070CB0 /* sslKeychain.c in Sources */, + DC0BCA111D8B827200070CB0 /* sslMemory.c in Sources */, + DC0BC9FB1D8B827200070CB0 /* sslTransport.c in Sources */, + DC0BC9F81D8B827200070CB0 /* sslCipherSpecs.c in Sources */, + DC0BCA101D8B827200070CB0 /* sslCrypto.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6C9808791E788AFD00E70590 /* Sources */ = { + DC0BCA151D8B82B000070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CAA8CF61F83E79D007B6E03 /* SFSQLite.m in Sources */, - 6CDB5FF81FA78D2300410924 /* SFAnalyticsMultiSampler.m in Sources */, - 476541A51F33EE1E00413F65 /* SecdWatchdog.m in Sources */, - DC2D43951F0EEC300005D382 /* MockCloudKit.m in Sources */, - 6CAA8CF81F83E7A9007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, - 6C9808A51E788CD100E70590 /* CKKSCloudKitTests.m in Sources */, - 6CBF65441FA2257200A68667 /* SFAnalyticsActivityTracker.m in Sources */, - DCB515E31ED3D135001F1152 /* SecTask.c in Sources */, - 6CAA8CEF1F83E65D007B6E03 /* SFObjCType.m in Sources */, - DCB515E01ED3D111001F1152 /* client.c in Sources */, - DCB515E41ED3D15A001F1152 /* client_endpoint.m in Sources */, - 6CAA8D141F83ECD5007B6E03 /* SFAnalytics.m in Sources */, - 6C98087A1E788AFD00E70590 /* spi.c in Sources */, - 6CAA8D0D1F83EC57007B6E03 /* SFSQLiteStatement.m in Sources */, - DC5F35B21EE0F28C00900966 /* server_entitlement_helpers.c in Sources */, - DC2353311ECA658B00D7C1BE /* server_security_helpers.c in Sources */, - DC2353331ECA659000D7C1BE /* server_xpc.m in Sources */, - DC23532F1ECA658400D7C1BE /* server_endpoint.m in Sources */, - 6CDF8DF01F96495700140B54 /* SFAnalyticsSampler.m in Sources */, + DC0BCA721D8B82CD00070CB0 /* ssl-utils.c in Sources */, + DC0BCA6D1D8B82CD00070CB0 /* ssl-52-noconn.c in Sources */, + DC0BCA661D8B82CD00070CB0 /* ssl-45-tls12.c in Sources */, + DC0BCA691D8B82CD00070CB0 /* ssl-48-split.c in Sources */, + DC0BCA6F1D8B82CD00070CB0 /* ssl-54-dhe.c in Sources */, + DC0BCA651D8B82CD00070CB0 /* ssl-44-crashes.c in Sources */, + DC0BCA621D8B82CD00070CB0 /* ssl-41-clientauth.c in Sources */, + DC0BCA631D8B82CD00070CB0 /* ssl-42-ciphers.c in Sources */, + DC0BCA701D8B82CD00070CB0 /* ssl-55-sessioncache.c in Sources */, + DC0BCA671D8B82CD00070CB0 /* ssl-46-SSLGetSupportedCiphers.c in Sources */, + DC0BCA641D8B82CD00070CB0 /* ssl-43-ciphers.c in Sources */, + DC0BCA6C1D8B82CD00070CB0 /* ssl-51-state.c in Sources */, + DC0BCA6A1D8B82CD00070CB0 /* ssl-49-sni.c in Sources */, + DC0BCA6B1D8B82CD00070CB0 /* ssl-50-server.c in Sources */, + DC0BCA711D8B82CD00070CB0 /* ssl-56-renegotiate.c in Sources */, + DC0BCA6E1D8B82CD00070CB0 /* ssl-53-clientauth.c in Sources */, + DC0BCA601D8B82CD00070CB0 /* ssl-39-echo.c in Sources */, + DC0BCA681D8B82CD00070CB0 /* ssl-47-falsestart.c in Sources */, + DC0BCA611D8B82CD00070CB0 /* ssl-40-clientauth.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6C9AA79A1F7C1D8F00D08296 /* Sources */ = { + DC0BCA7B1D8B858600070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6C9AA7A51F7C6F7F00D08296 /* SecArgParse.c in Sources */, - 6C9AA7A11F7C1D9000D08296 /* main.m in Sources */, + DC0BCAC71D8B85BC00070CB0 /* c++utils.cpp in Sources */, + DC0BCAEF1D8B85BC00070CB0 /* Source.cpp in Sources */, + DC0BCACE1D8B85BC00070CB0 /* EncryptTransform.cpp in Sources */, + DC0BCAE81D8B85BC00070CB0 /* SecSignVerifyTransform.c in Sources */, + DC0BCAD21D8B85BC00070CB0 /* GroupTransform.cpp in Sources */, + DC0BCADD1D8B85BC00070CB0 /* SecCustomTransform.cpp in Sources */, + DC0BCAFA1D8B85BC00070CB0 /* SecExternalSourceTransform.cpp in Sources */, + DC0BCAF11D8B85BC00070CB0 /* StreamSource.cpp in Sources */, + DC0BCAE41D8B85BC00070CB0 /* SecGroupTransform.cpp in Sources */, + DC0BCAD61D8B85BC00070CB0 /* misc.c in Sources */, + DC0BCAE31D8B85BC00070CB0 /* SecEncryptTransform.cpp in Sources */, + DC0BCACA1D8B85BC00070CB0 /* Digest.cpp in Sources */, + DC0BCAC11D8B85BC00070CB0 /* SecMaskGenerationFunctionTransform.c in Sources */, + DC0BCAD41D8B85BC00070CB0 /* LinkedList.cpp in Sources */, + DC0BCAC81D8B85BC00070CB0 /* CoreFoundationBasics.cpp in Sources */, + DC0BCAED1D8B85BC00070CB0 /* SingleShotSource.cpp in Sources */, + DC0BCACF1D8B85BC00070CB0 /* CEncryptDecrypt.c in Sources */, + DC0BCAE61D8B85BC00070CB0 /* SecNullTransform.cpp in Sources */, + DC0BCADA1D8B85BC00070CB0 /* NullTransform.cpp in Sources */, + DC0BCACC1D8B85BC00070CB0 /* EncodeDecodeTransforms.c in Sources */, + DC0BCAEA1D8B85BC00070CB0 /* SecTransform.cpp in Sources */, + DC0BCAF31D8B85BC00070CB0 /* Transform.cpp in Sources */, + DC0BCAF51D8B85BC00070CB0 /* TransformFactory.cpp in Sources */, + DC0BCAD11D8B85BC00070CB0 /* EncryptTransformUtilities.cpp in Sources */, + DC0BCAFC1D8B85BC00070CB0 /* SecTransformReadTransform.cpp in Sources */, + DC0BCAD81D8B85BC00070CB0 /* Monitor.cpp in Sources */, + DC0BCADF1D8B85BC00070CB0 /* SecDigestTransform.cpp in Sources */, + DC0BCAC41D8B85BC00070CB0 /* SecCollectTransform.cpp in Sources */, + DC0BCAF71D8B85BC00070CB0 /* Utilities.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6CAA8D1C1F842FB3007B6E03 /* Sources */ = { + DC0BCB031D8B894F00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CAA8D351F84306C007B6E03 /* main.m in Sources */, - 6CAA8D271F843002007B6E03 /* supd.m in Sources */, + DC0BCB2B1D8B898100070CB0 /* SecTranslocate.cpp in Sources */, + DC0BCB271D8B898100070CB0 /* SecTranslocateShared.cpp in Sources */, + DC0BCB241D8B898100070CB0 /* SecTranslocateLSNotification.cpp in Sources */, + DC0BCB2C1D8B898100070CB0 /* SecTranslocateUtilities.cpp in Sources */, + DC0BCB221D8B898100070CB0 /* SecTranslocateDANotification.cpp in Sources */, + DC0BCB281D8B898100070CB0 /* SecTranslocateServer.cpp in Sources */, + DC0BCB2E1D8B898100070CB0 /* SecTranslocateInterface.cpp in Sources */, + DC0BCB1D1D8B898100070CB0 /* SecTranslocateClient.cpp in Sources */, + DC0BCB1F1D8B898100070CB0 /* SecTranslocateXPCServer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6CCDF7801E3C25FA003F2555 /* Sources */ = { + DC0BCBDA1D8C648C00070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CB5F47B1E402E6700DBF3F0 /* KeychainEntitledTestRunner.m in Sources */, + DC0BCC0D1D8C64B500070CB0 /* test-00-test.c in Sources */, + DC0BCC161D8C64B600070CB0 /* testcert.c in Sources */, + DC0BCC141D8C64B600070CB0 /* testmore.c in Sources */, + DC0BCC121D8C64B600070CB0 /* testenv.m in Sources */, + DC0BCC191D8C64B600070CB0 /* testpolicy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6CF4A0B01E45488B00ECD7B5 /* Sources */ = { + DC0BCC221D8C684F00070CB0 /* Sources */ = { 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 */, + DC0BCD8D1D8C6A1E00070CB0 /* debugging.c in Sources */, + DC0BCD961D8C6A1E00070CB0 /* der_dictionary.c in Sources */, + DC0BCD751D8C6A1E00070CB0 /* iCloudKeychainTrace.c in Sources */, + DC0BCD821D8C6A1E00070CB0 /* SecCFWrappers.c in Sources */, + EB4B6E201DC0682A00AFC494 /* SecADWrapper.c in Sources */, + DC0BCD941D8C6A1E00070CB0 /* der_date.c in Sources */, + DC0BCD9F1D8C6A1F00070CB0 /* fileIo.c in Sources */, + DC0BCDA81D8C6A1F00070CB0 /* SecFileLocations.c in Sources */, + DC0BCDA61D8C6A1F00070CB0 /* SecDb.c in Sources */, + EB7AE6F81E86DACC00B80B15 /* SecPLWrappers.m in Sources */, + DC0BCD7B1D8C6A1E00070CB0 /* SecCoreCrypto.c in Sources */, + DC0BCDAF1D8C6A1F00070CB0 /* SecAppleAnchor.c in Sources */, + DC0BCDA41D8C6A1F00070CB0 /* iOSforOSX-SecAttr.c in Sources */, + DC0BCD881D8C6A1E00070CB0 /* SecTrace.c in Sources */, + DC0BCD9A1D8C6A1F00070CB0 /* der_plist_internal.c in Sources */, + DC0BCDAE1D8C6A1F00070CB0 /* SecSCTUtils.c in Sources */, + DC0BCD971D8C6A1E00070CB0 /* der_number.c in Sources */, + DC0BCDA51D8C6A1F00070CB0 /* iOSforOSX-SecRandom.c in Sources */, + DC0BCD841D8C6A1E00070CB0 /* SecCFError.c in Sources */, + DC0BCD981D8C6A1F00070CB0 /* der_plist.c in Sources */, + 72CDF5191EC679A8002D233B /* sec_action.c in Sources */, + DC0BCD901D8C6A1E00070CB0 /* der_array.c in Sources */, + DC0BCD7F1D8C6A1E00070CB0 /* SecCFCCWrappers.c in Sources */, + E7C787351DD0FEF90087FC34 /* NSURL+SOSPlistStore.m in Sources */, + DC0BCD9E1D8C6A1F00070CB0 /* der_string.c in Sources */, + DC0BCD911D8C6A1E00070CB0 /* der_boolean.c in Sources */, + DC0BCD931D8C6A1E00070CB0 /* der_data.c in Sources */, + E78CCDC71E737F6700C1CFAA /* SecNSAdditions.m in Sources */, + DC0BCD921D8C6A1E00070CB0 /* der_null.c in Sources */, + DC0BCD9C1D8C6A1F00070CB0 /* der_set.c in Sources */, + DC36895821235F23003A3735 /* SecAKSWrappers.c in Sources */, + EBB8528122F79F6E00424FD0 /* SecXPCHelper.m in Sources */, + DC0BCDAC1D8C6A1F00070CB0 /* simulate_crash.c in Sources */, + DC0BCD791D8C6A1E00070CB0 /* SecBuffer.c in Sources */, + DC0BCDAB1D8C6A1F00070CB0 /* SecXPCError.c in Sources */, + DA5B871D2065A8440093F083 /* SecAutorelease.m in Sources */, + EB71CF7822E825AF00DA3D0E /* SecTapToRadar.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 6CF4A0DC1E4549F200ECD7B5 /* Sources */ = { + DC0BCCF51D8C694700070CB0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6CF4A0EA1E4549F300ECD7B5 /* ViewController.m in Sources */, - 6CF4A0E71E4549F300ECD7B5 /* AppDelegate.m in Sources */, - 6CF4A0E41E4549F200ECD7B5 /* main.m in Sources */, + DC0BCD6C1D8C69A000070CB0 /* su-12-cfboolean-der.c in Sources */, + DC0BCD701D8C69A000070CB0 /* su-17-cfset-der.c in Sources */, + DC0BCD731D8C69A000070CB0 /* su-41-secdb-stress.c in Sources */, + DC0BCD6A1D8C69A000070CB0 /* su-10-cfstring-der.c in Sources */, + DC0BCD6D1D8C69A000070CB0 /* su-13-cfnumber-der.c in Sources */, + DC0BCD6E1D8C69A000070CB0 /* su-14-cfarray-der.c in Sources */, + DC0BCD721D8C69A000070CB0 /* su-40-secdb.c in Sources */, + DC0BCD6B1D8C69A000070CB0 /* su-11-cfdata-der.c in Sources */, + DC0BCD691D8C69A000070CB0 /* su-08-secbuffer.c in Sources */, + DC0BCD6F1D8C69A000070CB0 /* su-15-cfdictionary-der.c in Sources */, + DC0BCD671D8C69A000070CB0 /* su-05-cfwrappers.c in Sources */, + DC0BCD711D8C69A000070CB0 /* su-16-cfdate-der.c in Sources */, + DC0BCD681D8C69A000070CB0 /* su-07-debugging.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 790851B30CA9859F0083CC4D /* Sources */ = { + DC0EF8EB208697C600AB9E95 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCCD33CF1E3FEF1800AA4AD1 /* spi.c in Sources */, - 476541711F33B59500413F65 /* SecdWatchdog.m in Sources */, - 790851D40CA9B19D0083CC4D /* server.c in Sources */, - DC5F35A71EE0F25100900966 /* server_entitlement_helpers.c in Sources */, - DC4269091E82FD8C002B7110 /* server_security_helpers.c in Sources */, - DCB221511E8B08A6001598BC /* server_xpc.m in Sources */, - DC6ACC471E81E08E00125DC5 /* server_endpoint.m in Sources */, + EB18A7BA2238C07600A0FC41 /* OTDeviceInformationAdapter.m in Sources */, + DC74799E22272358001E0E8C /* CKKSSerializedKey.m in Sources */, + DC74799D22272344001E0E8C /* CKKSSIV.m in Sources */, + DC74799C22272331001E0E8C /* CKKSPeer.m in Sources */, + DC74799A222722BC001E0E8C /* CKKSKeychainBackedKey.m in Sources */, + DC747999222722B2001E0E8C /* CKKSConstants.m in Sources */, + DC7479982227229D001E0E8C /* CKKSTLKShare.m in Sources */, + DC0EF8F2208697C600AB9E95 /* main.swift in Sources */, + DCD48BFE20BF3D83009A3224 /* tpctl-objc.m in Sources */, + DCFFE9692277DEAF0092069C /* TrustedPeersHelperProtocol.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 7913B2000D172B3900601FE9 /* Sources */ = { + DC1788FF1D77980500B50D50 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 7913B2020D172B3900601FE9 /* ioSock.c in Sources */, - 7913B2030D172B3900601FE9 /* sslAppUtils.cpp in Sources */, - 7913B2050D172B3900601FE9 /* sslServer.cpp in Sources */, + DC2B757621F2A270003C9356 /* SecEscrowRequest.m in Sources */, + 0C84D8381FCF43BF00B822E3 /* OTControlProtocol.m 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 */, + DCA85B941E8D97E400BA7241 /* client.c in Sources */, + DCDF0A4F1D81D76F007AF174 /* Security.exp-in in Sources */, + 0CBFEACA200FCD2D009A60E9 /* SFSignInAnalytics.m in Sources */, + DC1789A51D779E3B00B50D50 /* dummy.cpp in Sources */, + 5A061191229ED6DB006AF14A /* NSDate+SFAnalytics.m in Sources */, + EB9B285821C77C8D00173DC2 /* OTDefines.m in Sources */, + 4723C9CD1F152ED40082882F /* SFSQLiteStatement.m in Sources */, + AA9FD59D2152AFE30045A07A /* SecProtocolConfiguration.m in Sources */, + 5A04BAFB22976A16001848A0 /* OTClique.m in Sources */, + DC372C8D22B4501900AB9F41 /* SecCoreAnalytics.m in Sources */, + EB10A3E920356E7A00E84270 /* OTConstants.m in Sources */, + 6CAA8CFE1F83E800007B6E03 /* SFSQLite.m in Sources */, + DC9C95C01F79DC89000D19E5 /* CKKSControl.m in Sources */, + 5AF594001FA0EE5300A5C1EC /* SecProtocol.c in Sources */, + 0C8884042154C4EA0053224D /* OTJoiningConfiguration.m in Sources */, + 0C0E60E020D033E400E654F2 /* OTControl.m in Sources */, + 6CB420A52051FDD500FF2D44 /* LocalKeychainAnalytics.m in Sources */, + B61577E81F20151C004A3930 /* SecPaddingConfigurations.c in Sources */, + DCA9D84721FFE7CF00B27421 /* EscrowRequestXPCProtocol.m in Sources */, + 6C73F48B2006B83A003D5D63 /* SOSAnalytics.m in Sources */, + 6CE3654D1FA100E50012F6AB /* SFAnalytics.m in Sources */, + 5A7E037A22272E0E003DB3A0 /* SecProtocolHelper.m in Sources */, + 6CAA8CFD1F83E7EB007B6E03 /* SFObjCType.m in Sources */, + DC1789A21D779DF400B50D50 /* SecBreadcrumb.c in Sources */, + 78ADC62C1FA0FACE001EB8B6 /* SecProtocolTypes.m in Sources */, + 0CE079F41FEA15B20040A3F1 /* SFBehavior.m in Sources */, + 3DE8F6C121829EFF006041DA /* SecExperiment.m in Sources */, + 6CBF65411FA1481100A68667 /* SFAnalyticsActivityTracker.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - ACBAF6BB1E9417F40007BA2F /* Sources */ = { + DC311E712124B8A8002F5EAE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ACBAF6F91E941B020007BA2F /* transform-01-sigverify.m in Sources */, + DC311E7B2124B8EF002F5EAE /* aks_real_witness.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - BE197F2219116FD100BA91D1 /* Sources */ = { + DC3502B11E0208BE00BC0587 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BE197F5E191173A800BA91D1 /* SWCViewController.m in Sources */, - BE197F3219116FD100BA91D1 /* SWCAppDelegate.m in Sources */, - BE197F2E19116FD100BA91D1 /* main.m in Sources */, + 476541A61F33EE2700413F65 /* SecdWatchdog.m in Sources */, + EBDE5E0E22BA3DE900A229C8 /* CKKSMockOctagonAdapter.m in Sources */, + DCD6C4B71EC5319600414FEE /* CKKSNearFutureSchedulerTests.m in Sources */, + DC08D1C41E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m in Sources */, + 47E553741EDF674700749715 /* CKKSManifestTests.m in Sources */, + 6C588D7F1EAA14AA00D7E322 /* RateLimiterTests.m in Sources */, + DC4DB15F1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m in Sources */, + DC3502E71E0214C800BC0587 /* MockCloudKit.m in Sources */, + DC6593D11ED8DAB900C19462 /* CKKSTests+CurrentPointerAPI.m in Sources */, + DCAD9B491F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m in Sources */, + DC752F1A21C1B6A700216089 /* SFSQLiteStatement.m in Sources */, + 0CA4EBF3202B8D9C002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */, + DC9A2C5F1EB3F557008FAC27 /* CKKSTests+Coalesce.m in Sources */, + DC222C8A1E089BAE00B09171 /* CKKSSQLTests.m in Sources */, + DC15F79C1E68EAD5003B9A40 /* CKKSTests+API.m in Sources */, + 4723C9D41F1531A30082882F /* CKKSLoggerTests.m in Sources */, + DCBF2F7D1F90084D00ED0CA4 /* CKKSTLKSharingTests.m in Sources */, + DC62DC6D22A87137000D2D5D /* CKKSTests+MultiZone.m in Sources */, + DCFABF8E20081E2F001128B5 /* CKKSDeviceStateUploadTests.m in Sources */, + DC3502B81E0208BE00BC0587 /* CKKSTests.m in Sources */, + 6C3446301E24F6BE00F9522B /* CKKSRateLimiterTests.m in Sources */, + DCE7F2091F21726500DDB0F7 /* OctagonAPSReceiverTests.m in Sources */, + DC96053F1ECA2D6400AF9BDA /* SecTask.c in Sources */, + DC08D1CC1E64FCC5006237DA /* CKKSSOSTests.m in Sources */, + 0C98122821ACCC9300784441 /* OTClique.m in Sources */, + DC222CA81E08A7D900B09171 /* CloudKitMockXCTest.m in Sources */, + EBB0315822223AAF007241CB /* CKKSLaunchSequenceTests.m in Sources */, + DC752F1F21C1B98000216089 /* SFObjCType.m in Sources */, + DC9C98C722E264F30021E29F /* CKKSFetchTests.m in Sources */, + DC9C75161E4BCE1800F1CA0D /* CKKSOperationTests.m in Sources */, + DC8D238D2064649400E163C8 /* CKKSAPSHandlingTests.m in Sources */, + EBC1024422EBF93E0083D356 /* CKKSTests+LockStateTracker.m in Sources */, + DCB221561E8B08BF001598BC /* server_xpc.m in Sources */, + DCA9BC07221B7AFB00B4EB26 /* CKKSMockSOSPresentAdapter.m in Sources */, + DC42690F1E82FD9C002B7110 /* server_security_helpers.m in Sources */, + DC4268FE1E820371002B7110 /* server_endpoint.m in Sources */, + DC752F1921C1B69C00216089 /* SFSQLite.m in Sources */, + DCFE1C3D1F17EFB5007640C8 /* CKKSConditionTests.m in Sources */, + DCCD33C91E3FE95900AA4AD1 /* spi.c in Sources */, + DC5B391720C08B38005B09F6 /* SecFramework.c in Sources */, + DC9C95971F748D0B000D19E5 /* CKKSServerValidationRecoveryTests.m in Sources */, + DC7341FE1F84642C00AB9BDF /* CKKSTLKSharingEncryptionTests.m in Sources */, + DC5F35AC1EE0F27900900966 /* server_entitlement_helpers.c in Sources */, + DAEE055C1FAD3FC700DF27F3 /* AutoreleaseTest.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - BE442BAB18B7FDB800F24DAE /* Sources */ = { + DC36895B21235F42003A3735 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BE4AC9A218B7FFAD00B84964 /* swcagent.m in Sources */, + DC5999752232FA3700A9F1A3 /* SecKeybagSupport.c in Sources */, + DC36896221235F99003A3735 /* mockaks.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - BED208D51EDF950E00753952 /* Sources */ = { + DC3A4B541D91E9FB00E46D4A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BE22FC041EE3584400893431 /* mark.m in Sources */, - BE22FBCE1EE1E26600893431 /* Keychain.m in Sources */, - BE22FBD11EE2084100893431 /* Config.m in Sources */, - BE22FBC61EE0E8AB00893431 /* Monkey.m in Sources */, - BED208E81EDF974500753952 /* manifeststresstest.m in Sources */, + DC3A4B641D91EADC00E46D4A /* main.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - BEF88C231EAFFC3F00357577 /* Sources */ = { + DC52E7741D80BC8000B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BEF88C781EB000BE00357577 /* TPCategoryRule.m in Sources */, - BEF88C841EB000BE00357577 /* TPPeerDynamicInfo.m in Sources */, - BEF88C921EB000BE00357577 /* TPVoucher.m in Sources */, - BEF88C901EB000BE00357577 /* TPUtils.m in Sources */, - BEF88C8A1EB000BE00357577 /* TPPolicy.m in Sources */, - BEF88C801EB000BE00357577 /* TPModel.m in Sources */, - BEF88C8C1EB000BE00357577 /* TPPolicyDocument.m in Sources */, - BEF88C7E1EB000BE00357577 /* TPHash.m in Sources */, - BEF88C881EB000BE00357577 /* TPPeerStableInfo.m in Sources */, - BEF88C861EB000BE00357577 /* TPPeerPermanentInfo.m in Sources */, - BEF88C7A1EB000BE00357577 /* TPCircle.m in Sources */, - BEF88C821EB000BE00357577 /* TPPeer.m in Sources */, + DCE0778021ADEC4B002662FD /* CKKSSerializedKey.m in Sources */, + DCE0777F21ADEC07002662FD /* OTAccountMetadataClassC.m in Sources */, + 0C84D8351FCF43BB00B822E3 /* OTControlProtocol.m in Sources */, + DCBFF833222611A200C5C044 /* OTFetchCKKSKeysOperation.m in Sources */, + 0C00FC86217A980100C8BF00 /* OTLocalCuttlefishReset.m in Sources */, + DCAE1DDD2073FDCC00B4F687 /* NSError+UsefulConstructors.m in Sources */, + 6C4AEF88218A09E70012C5DA /* CheckV12DevEnabled.m in Sources */, + DC797E1A1DD3F9A400CC9E42 /* CKKSSQLDatabaseObject.m in Sources */, + 6CC1859F1E24E8EB009657D8 /* CKKSRateLimiter.m in Sources */, + DCD33D7C220B99CC000A390B /* EscrowRequestController.m in Sources */, + 0C5A8C1D200A9B0C004C771D /* OTPreflightInfo.m in Sources */, + DC19484D21812EC5007C2260 /* OTDeviceInformationAdapter.m in Sources */, + 6C4AEFA0218A189A0012C5DA /* SecAKSObjCWrappers.m in Sources */, + DCFB12C71E95A4C000510F5F /* CKKSAccountStateTracker.m in Sources */, + DCA9D84E21FFF04700B27421 /* EscrowRequestServer.m in Sources */, + 470D96731FCDE55B0065FE90 /* SecCDKeychain.m in Sources */, + DCF94A7C222D9F2400C01744 /* OctagonCKKSPeerAdapter.m in Sources */, + 0CA7020A2280D5BD0085AC54 /* OTCheckHealthOperation.m in Sources */, + EBB407B31EBA46B200A541A5 /* CKKSPowerCollection.m in Sources */, + 0C84D8391FCF43CA00B822E3 /* OTManager.m in Sources */, + DCCD88EA1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */, + 0CD9E8001FE05B6600F66C38 /* OTContextRecord.m in Sources */, + DC54DD0F1EA7D9E700108E92 /* CKKSManifestLeafRecord.m in Sources */, + DCDCCB901DF7B8D4006E840E /* CKKSItem.m in Sources */, + DC1ED8C11DD5197E002BDCFA /* CKKSItemEncrypter.m in Sources */, + 0CDD6F79226E83F6009094C2 /* OTTriggerEscrowUpdateOperation.m in Sources */, + DC6D2C921DD2835A00BE372D /* CKKSOutgoingQueueEntry.m in Sources */, + DC378B3D1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m in Sources */, + 6C880FCB21C3351400D38D66 /* SecDbBackupMetadataClassKey.m in Sources */, + 0C8BBEA91FC9DBBF00580909 /* OTLocalStore.m in Sources */, + 4733377B1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */, + 0C101F942053528700387951 /* OTBottledPeerState.m in Sources */, + 0CE1BCCE1FCE11680017230E /* OTBottledPeerSigned.m in Sources */, + DC5BB4FA1E0C90DE0010F836 /* CKKSIncomingQueueOperation.m in Sources */, + DC5BB5001E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */, + 0CB8DC9A2194B14C0021A7C8 /* OTVouchWithBottleOperation.m in Sources */, + DC5A01EA21BB428500D87AB9 /* CKKSTLKShare.m in Sources */, + DC391F9E21BF2F8700772585 /* CKKSConstants.m in Sources */, + EB7E911E2194849900B1FA21 /* SECC2MPGenericEventMetric.m in Sources */, + DC378B391DEFADB500A3DAFA /* CKKSZoneStateEntry.m in Sources */, + DCA9D83E21FFE51A00B27421 /* EscrowRequestXPCServer.m in Sources */, + DCF46C30214B1E0700319A93 /* OTUpdateTrustedDeviceListOperation.m in Sources */, + EB7E911F2194849900B1FA21 /* SECC2MPGenericEventMetricValue.m in Sources */, + 6C880FC821C3351400D38D66 /* SecDbBackupBag.m in Sources */, + 0C87D3D9229326AA007853B5 /* OTEnsureOctagonKeyConsistency.m in Sources */, + 6C588D801EAA20AB00D7E322 /* RateLimiter.m in Sources */, + DC8DF6DC212F8A7C007B3FE8 /* OTSOSAdapter.m in Sources */, + 0C66046A2134983900BFBBB8 /* OTEstablishOperation.m in Sources */, + DC15F7681E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m in Sources */, + DCE278DF1ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */, + DC3D748E1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */, + DCC67E2F20DDC07900A70A31 /* OTPrepareOperation.m in Sources */, + 0C8BBEA51FC9DBB100580909 /* OTEscrowKeys.m in Sources */, + DCB41DFC216D5E5B00F219E0 /* OTAccountMetadataClassC+KeychainSupport.m in Sources */, + 6C880FCC21C3351400D38D66 /* SecDbBackupRecoverySet.m in Sources */, + DCA4D1FF1E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */, + EB7E91212194849900B1FA21 /* SECC2MPMetric.m in Sources */, + DA6AA1651FE88AFB004565B0 /* CKKSControlServer.m in Sources */, + DCFE1C531F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */, + 47922D481FAA7C3C0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */, + DCD6C4B41EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */, + DC378B2F1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m in Sources */, + DC5681AB224DA05F008F8DEB /* OctagonFlags.m in Sources */, + 0CD3D519224048A800024755 /* OTSetRecoveryKeyOperation.m in Sources */, + DC94BCCC1F10448600E07CEB /* CloudKitCategories.m in Sources */, + DC9FD32C1F85990A00C8AAC8 /* CKKSPeer.m in Sources */, + EB7E911D2194849900B1FA21 /* SECC2MPGenericEvent.m in Sources */, + 6C880FCA21C3351400D38D66 /* SecDbBackupKeyClassSigningKey.m in Sources */, + DC1ED8C61DD55476002BDCFA /* CKKS.m in Sources */, + DCB5D93D1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m in Sources */, + DC5F65AF2225C22C0051E9FA /* CKKSProvideKeySetOperation.m in Sources */, + DC762AA01E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */, + DC52E7DF1D80BD8700B0A59C /* SOSChangeTracker.c in Sources */, + DCD33D94220CFF8A000A390B /* EscrowRequestPerformEscrowEnrollOperation.m in Sources */, + DC1DA6681E4555D80094CE7F /* CKKSScanLocalItemsOperation.m in Sources */, + 0CC8A9032123AF06005D7F6A /* OTJoinWithVoucherOperation.m in Sources */, + DC18F7711E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */, + DC45D43E22EB619D00CEB6B7 /* OctagonStateMachineObservers.m in Sources */, + DC2C5F601F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */, + DC7250382296056000493D88 /* OTResetCKKSZonesLackingTLKsOperation.m in Sources */, + DC221BAC2267E2A70068DBCF /* OTUpdateTPHOperation.m in Sources */, + DC93F02A22387A010072720A /* OTSOSUpdatePreapprovalsOperation.m in Sources */, + 6C4AEF90218A0C170012C5DA /* SecDbBackupManager.m in Sources */, + DC5060ED20E2D88300925005 /* OTCuttlefishContext.m in Sources */, + DC0FA6B12291F63F00FE01C4 /* OctagonPendingFlag.m in Sources */, + EB7E91202194849900B1FA21 /* SECC2MPInternalTestConfig.m in Sources */, + DC4A76A3221267D4006F2D8F /* EscrowRequestServerHelpers.m in Sources */, + 0C1B8BB72233244F0094D5DA /* OTVouchWithRecoveryKeyOperation.m in Sources */, + DC52E7CF1D80BCFD00B0A59C /* SOSEngine.c in Sources */, + DC4DB1521E24692100CD6769 /* CKKSKey.m in Sources */, + DCBDB3BD1E57CA7A00B61300 /* CKKSViewManager.m in Sources */, + 1B5EAADD2252ABCD008D27E7 /* OTFetchViewsOperation.m in Sources */, + 471A03EC1F72E35B000A8904 /* SecDbKeychainItemV7.m in Sources */, + EB4E0CDB1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */, + DC52E7C41D80BCAD00B0A59C /* SecDbItem.c in Sources */, + DCFC91B021F16E0B00E674DD /* OctagonStateMachine.m in Sources */, + DC52E7D31D80BD1800B0A59C /* SecDbKeychainItem.m in Sources */, + DC3AF52D2229E6C0006577E8 /* CKKSListenerCollection.m in Sources */, + DC6DE89C213076C000C6B56D /* OTSOSUpgradeOperation.m in Sources */, + DC52E7CC1D80BCDF00B0A59C /* SecDbQuery.c in Sources */, + DC14478C1F5764C600236DB4 /* CKKSResultOperation.m in Sources */, + 479DA1721EBBA8D10065C98F /* CKKSManifest.m in Sources */, + DC52E7CB1D80BCD800B0A59C /* SecItemBackupServer.c in Sources */, + 0C2F337220DD64930031A92D /* OTRamping.m in Sources */, + DCF12674218A757A000124C6 /* OTLeaveCliqueOperation.m in Sources */, + DC52E7CD1D80BCE700B0A59C /* SecItemDataSource.c in Sources */, + 0C8FD52521483EF20098E3FB /* OT.m in Sources */, + DC9C066B2149DFE400C6F7B8 /* OTAuthKitAdapter.m in Sources */, + DC124DCD20059BA900BE8DAC /* OctagonControlServer.m in Sources */, + DC52E7DE1D80BD7F00B0A59C /* SecItemDb.c in Sources */, + DC52E7E01D80BD8D00B0A59C /* SecItemSchema.c in Sources */, + EB10A3E820356E6500E84270 /* OTConstants.m in Sources */, + DC52E7D71D80BD2D00B0A59C /* SecItemServer.c in Sources */, + DCC54182225C05180095D926 /* OTUploadNewCKKSTLKsOperation.m in Sources */, + DC13A11D211D1982000A80BC /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, + 4718AEE3205B3A050068EC3F /* KeychainModel.xcdatamodeld in Sources */, + EB7E91152194846E00B1FA21 /* SecMetrics.m in Sources */, + DC13A11E211D1982000A80BC /* NSOperationCategories.m in Sources */, + D491112C209515400066A1E4 /* CKKSAnalytics.m in Sources */, + EB7E911C2194849900B1FA21 /* SECC2MPError.m in Sources */, + DCD8A0CF1E09EA1800E4FA0A /* SecKeybagSupport.c in Sources */, + DC52E7E11D80BD9300B0A59C /* SecLogSettingsServer.m in Sources */, + DCAB17D62200D41200E1DFCF /* SecEscrowPendingRecord+KeychainSupport.m in Sources */, + DCFE1C291F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */, + EB7E911A2194849900B1FA21 /* SECC2MPCloudKitOperationInfo.m in Sources */, + 0CC8A8FE2123A9F6005D7F6A /* OTClientVoucherOperation.m in Sources */, + DCAD9B461F8D939C00C5E2AE /* CKKSFixups.m in Sources */, + DCC67E1020DD7E0A00A70A31 /* OTStates.m in Sources */, + DC8757F5218D2003000E65F1 /* OTRemovePeersOperation.m in Sources */, + DC52E7DC1D80BD4F00B0A59C /* SecOTRRemote.m in Sources */, + DCA9BC03221B721E00B4EB26 /* CKKSCloudKitClassDependencies.m in Sources */, + EB7E91182194849900B1FA21 /* SECC2MPCloudKitInfo.m in Sources */, + DCE278EA1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, + DCD662F71E329B6800188186 /* CKKSNewTLKOperation.m in Sources */, + DCB946B022FCB88500BE4490 /* OTDetermineHSA2AccountStatusOperation.m in Sources */, + DCE772672290712F005862B4 /* OctagonCheckTrustStateOperation.m in Sources */, + 5A04BAF822973E7F001848A0 /* OTFollowup.m in Sources */, + DCB837321ED5045000015C07 /* CKKSLockStateTracker.m in Sources */, + 0CE407AC1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */, + EB80DE162195EDA4005B10FA /* SecC2DeviceInfo.m in Sources */, + 47922D4C1FAA7C4A0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */, + DCBDB3B71E57C82300B61300 /* CKKSKeychainView.m in Sources */, + DC52E7D61D80BD2800B0A59C /* SecuritydXPC.c in Sources */, + 0C4F4DE221153E9E007F7E20 /* OTEpochOperation.m in Sources */, + 47922D561FAA7E0D0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */, + DC7A17EF1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */, + 0C48B377202E3EE700A0E1AA /* OTContext.m in Sources */, + DC7341F51F8447AB00AB9BDF /* CKKSTLKShareRecord.m in Sources */, + 0C5960811FB369C50095BA29 /* CKKSHealTLKSharesOperation.m in Sources */, + DCD33D81220B9DC8000A390B /* OctagonStateMachineHelpers.m in Sources */, + DCA4D2171E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, + 5269658D1E6A154700627F9D /* SecBackupKeybagEntry.m in Sources */, + DC52E7D41D80BD1D00B0A59C /* iCloudTrace.c in Sources */, + EB7E91222194849900B1FA21 /* SECC2MPNetworkEvent.m in Sources */, + 0C66047E2134CA5600BFBBB8 /* OTDeviceInformation.m in Sources */, + DCEA5D871E2F14810089CF55 /* OctagonAPSReceiver.m in Sources */, + DC0BD4F521BB060F006B9154 /* CKKSKeychainBackedKey.m in Sources */, + 6C880FC921C3351400D38D66 /* SecDbBackupBagIdentity.m in Sources */, + 0C8BBE9F1FC9DBA400580909 /* OTBottledPeer.m in Sources */, + 6C869A751F50CAF400957298 /* SOSEnsureBackup.m in Sources */, + DC754C722228B57C00A39C8E /* TrustedPeersHelperProtocol.m in Sources */, + 0C12B1F12138D31600BE0A98 /* OTClientStateMachine.m in Sources */, + BE2AD2BA1FDA080800739F96 /* OTBottledPeerRecord.m in Sources */, + 0C770EC41FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */, + DCEA5D571E2826DB0089CF55 /* CKKSSIV.m in Sources */, + EB7E911B2194849900B1FA21 /* SECC2MPDeviceInfo.m in Sources */, + EB7E91192194849900B1FA21 /* SECC2MPCloudKitOperationGroupInfo.m in Sources */, + 0C48B371202E3ED800A0E1AA /* OTIdentity.m in Sources */, + DC9082C41EA0277600D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */, + 6C4AEF96218A127F0012C5DA /* SecDbKeychainMetadataKeyStore.m in Sources */, + DCFE1C361F17ECE5007640C8 /* CKKSCondition.m in Sources */, + EB7E91172194847A00B1FA21 /* SecEventMetric.m in Sources */, + DCEA5D971E3015830089CF55 /* CKKSZone.m in Sources */, + DCAB17D22200D26900E1DFCF /* SecEscrowPendingRecord.m in Sources */, + DC047082218BB21E0078BDAA /* OTCuttlefishAccountStateHolder.m in Sources */, + DC047088218BCEF20078BDAA /* OTOperationDependencies.m in Sources */, + EB7E91232194849900B1FA21 /* SECC2MPServerInfo.m in Sources */, + DC614C5222A9BDB500E16ADA /* CKKSZoneModifier.m in Sources */, + 47FF17281FD60ACA00875565 /* SFKeychainServer.m in Sources */, + DC52E7C51D80BCB300B0A59C /* swcagent_client.c in Sources */, + DC7F79BB22EA5C73001FB69A /* OTLocalCKKSResetOperation.m in Sources */, + DCD33D8F220CEED2000A390B /* EscrowRequestInformCloudServicesOperation.m in Sources */, + EBB02A702220ED26007241CB /* CKKSLaunchSequence.m in Sources */, + DCFF82762162876400D54B02 /* OTResetOperation.m in Sources */, + DAEF8E5C22581CDF00F7DF79 /* OTPairingClient.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - BEF88C2C1EAFFC3F00357577 /* Sources */ = { + DC52E8BF1D80C25800B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BEF88C941EB000FD00357577 /* TPDummyDecrypter.m in Sources */, - BEF88C9D1EB000FD00357577 /* TPUtilsTests.m in Sources */, - BEF88C951EB000FD00357577 /* TPDummyEncrypter.m in Sources */, - BEF88C981EB000FD00357577 /* TPModelTests.m in Sources */, - BEF88C9B1EB000FD00357577 /* TPPeerTests.m in Sources */, - BEF88C931EB000FD00357577 /* TPCircleTests.m in Sources */, - BEF88C971EB000FD00357577 /* TPDummySigningKeyTests.m in Sources */, - BEF88C9A1EB000FD00357577 /* TPPeerStableInfoTests.m in Sources */, - BEF88C991EB000FD00357577 /* TPPeerPermanentInfoTests.m in Sources */, - BEF88C961EB000FD00357577 /* TPDummySigningKey.m in Sources */, - BEF88C9E1EB000FD00357577 /* TPVoucherTests.m in Sources */, - BEF88C9C1EB000FD00357577 /* TPPolicyDocumentTests.m in Sources */, + 48E617211DBEC6BA0098EAAD /* SOSBackupInformation.m in Sources */, + DC52E8F11D80C34000B0A59C /* SOSAccount.m in Sources */, + DC52E8F31D80C34000B0A59C /* SOSAccountBackup.m in Sources */, + DCB332591F478C3C00178C30 /* SOSUserKeygen.m in Sources */, + DC52E8F41D80C34000B0A59C /* SOSAccountCircles.m in Sources */, + DC59245220E46FAA0073D284 /* SOSRingBackup.m in Sources */, + 0CD8CB0B1ECA50920076F37F /* SOSPeerOTRTimer.m in Sources */, + DC2670F51F3E711400816EED /* SOSAccountCloudParameters.m in Sources */, + DCDCC7E51D9B5526006487E8 /* SOSAccountSync.m in Sources */, + DC2670F81F3E723B00816EED /* SOSAccountDer.m in Sources */, + DC59245520E470070073D284 /* SOSRingRecovery.m in Sources */, + DC52E8F71D80C34000B0A59C /* SOSAccountCredentials.m in Sources */, + DC59245420E46FDE0073D284 /* SOSRingBasic.m in Sources */, + EB3210CD20F532F3003504F7 /* SOSAccountTrustClassic+Retirement.m in Sources */, + DC52E8F91D80C34000B0A59C /* SOSAccountFullPeerInfo.m in Sources */, + DC52E8FC1D80C34000B0A59C /* SOSAccountLog.m in Sources */, + DC52E8FA1D80C34000B0A59C /* SOSAccountPeers.m in Sources */, + DC52E8FB1D80C34000B0A59C /* SOSAccountPersistence.m in Sources */, + DC52E8FF1D80C34000B0A59C /* SOSAccountRingUpdate.m in Sources */, + DC52E8FE1D80C34000B0A59C /* SOSAccountRings.m in Sources */, + 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 */, + DC59245820E4711F0073D284 /* SOSRingDER.c in Sources */, + 7281E0871DFD01800021E1B7 /* SOSAccountGetSet.m in Sources */, + 0C4899121E0E105D00C6CF70 /* SOSTransportCircleCK.m in Sources */, + DC52E8DD1D80C31F00B0A59C /* SOSCoder.c in Sources */, + DC52E8DE1D80C31F00B0A59C /* SOSDigestVector.c in Sources */, + DC52E8E01D80C31F00B0A59C /* SOSManifest.c in Sources */, + DC59244C20E46EDD0073D284 /* SOSRingTypes.m in Sources */, + DC59244F20E46F470073D284 /* SOSAccountRecovery.m in Sources */, + DC52E8E11D80C31F00B0A59C /* SOSMessage.c in Sources */, + 480C03DB2145A8490034570E /* SOSTrustedDeviceAttributes.m in Sources */, + DC52E8E21D80C31F00B0A59C /* SOSPeer.m in Sources */, + DC52E8E31D80C31F00B0A59C /* SOSPeerCoder.m in Sources */, + DCFAEDCF1D999859005187E4 /* SOSAccountGhost.m in Sources */, + DC59245620E470350073D284 /* SOSRingConcordanceTrust.c in Sources */, + EB6928F91D9ED5BA00062A18 /* SecRecoveryKey.m in Sources */, + 48FE669620E6E69D00FAEF17 /* SOSAuthKitHelpers.m in Sources */, + DC59244D20E46F0E0073D284 /* SOSTransport.m in Sources */, + DC52E8C91D80C2FD00B0A59C /* SOSTransportBackupPeer.m in Sources */, + DC59245020E46F800073D284 /* SOSRecoveryKeyBag.m in Sources */, + 0CB50A0E20AA4C2F00FE4675 /* SOSAccountTrustClassic+Circle.m in Sources */, + DC52E8CA1D80C2FD00B0A59C /* SOSTransportCircle.m in Sources */, + DC52E8CB1D80C2FD00B0A59C /* SOSTransportCircleKVS.m in Sources */, + DC52E8CC1D80C2FD00B0A59C /* SOSTransportKeyParameter.m in Sources */, + DC2FA72A20E57BFD00DB7518 /* SOSAccountTrust.m in Sources */, + DC52E8CE1D80C2FD00B0A59C /* SOSTransportMessage.m in Sources */, + 0CAD1E1C1E032ADB00537693 /* SOSCloudCircleServer.m in Sources */, + 0CAC5DBF1EB3DA4C00AD884B /* SOSPeerRateLimiter.m in Sources */, + DC59244A20E46E9D0073D284 /* SOSRingUtils.c in Sources */, + DAB27AE11FA29EE300DEBBDE /* SOSControlServer.m in Sources */, + DC52E8D01D80C2FD00B0A59C /* SOSTransportMessageKVS.m in Sources */, + EB3210C720F532CD003504F7 /* SOSAccountTrustClassic+Identity.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D41257CB1E9410A300781F23 /* Sources */ = { + DC52EC221D80CFB200B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D41257D91E9412B800781F23 /* trustd.c in Sources */, - DC5F35A81EE0F25300900966 /* server_entitlement_helpers.c in Sources */, + DCD7EE841F4E46F9007D9804 /* accountCirclesViewsPrint.m in Sources */, + 0C0CECA41DA45ED700C22FBC /* recovery_key.m in Sources */, + DC52EC3B1D80CFE900B0A59C /* syncbackup.m in Sources */, + DC52EC3A1D80CFE400B0A59C /* keychain_log.m in Sources */, + DC52EC391D80CFDF00B0A59C /* secViewDisplay.c in Sources */, + DC52EC381D80CFDB00B0A59C /* secToolFileIO.c in Sources */, + DC52EC371D80CFD400B0A59C /* keychain_sync_test.m in Sources */, + DC52EC361D80CFD000B0A59C /* keychain_sync.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D4ADA3151E2B41670031CEA3 /* Sources */ = { + DC52EC3F1D80D00800B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 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.m in Sources */, - D43DBF021E99D1CA00C04AEA /* SecCertificateServer.c in Sources */, - D43DBF031E99D1CA00C04AEA /* SecCertificateSource.c in Sources */, - D43DBF041E99D1CA00C04AEA /* SecOCSPCache.c in Sources */, - D43DBF051E99D1CA00C04AEA /* SecOCSPRequest.c in Sources */, - D43761671EB2996C00954447 /* SecRevocationNetworking.m in Sources */, - D43DBF061E99D1CA00C04AEA /* SecOCSPResponse.c in Sources */, - D43DBF071E99D1CA00C04AEA /* SecPinningDb.m in Sources */, - D43DBF081E99D1CA00C04AEA /* SecPolicyServer.c in Sources */, - D43DBF091E99D1CA00C04AEA /* SecRevocationDb.c in Sources */, - D46B37A62151B7950083DAAA /* SecTrustStoreServer.m 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 */, + DC52EC4F1D80D02400B0A59C /* SecuritydXPC.c in Sources */, + DC52EC4E1D80D01F00B0A59C /* swcagent_client.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DA30D6721DF8C8FB00EC6B43 /* Sources */ = { + DC52EC531D80D05200B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DA30D6851DF8CA4100EC6B43 /* KeychainSyncAccountUpdater.m in Sources */, + DC52EC5D1D80D06300B0A59C /* SecLogging.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DAE40BC620CF3E46002D5674 /* Sources */ = { + DC52EC611D80D0C400B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DAE40BD920CF3F0F002D5674 /* secitemcanarytest.m in Sources */, + DC52EC7B1D80D15600B0A59C /* sc-30-peerinfo.c in Sources */, + DC52EC7A1D80D15200B0A59C /* sc-40-circle.c in Sources */, + DC52EC791D80D14D00B0A59C /* sc-45-digestvector.c in Sources */, + DC52EC781D80D14800B0A59C /* SOSRegressionUtilities.m in Sources */, + DC52EC771D80D14400B0A59C /* sc-130-resignationticket.c in Sources */, + DC52EC761D80D13F00B0A59C /* sc-150-ring.m in Sources */, + DC52EC751D80D13B00B0A59C /* sc-42-circlegencount.c in Sources */, + DC52EC741D80D13500B0A59C /* SOSTestDataSource.c in Sources */, + DC52EC731D80D12E00B0A59C /* sc-20-keynames.m in Sources */, + DC52EC721D80D12900B0A59C /* sc-150-backupkeyderivation.c in Sources */, + DC52EC711D80D12200B0A59C /* sc-153-backupslicekeybag.c in Sources */, + DC52EC6F1D80D11800B0A59C /* sc-25-soskeygen.c in Sources */, + DC52EC6E1D80D0F700B0A59C /* SOSTestDevice.c in Sources */, + DC52EC6D1D80D0F100B0A59C /* sc-31-peerinfo-simplefuzz.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0067A81D87876F005AF8DB /* Sources */ = { + DC52EC7F1D80D1A800B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0067C21D8787A4005AF8DB /* ucspNotifyReceiver.cpp in Sources */, - DC0067C11D87879D005AF8DB /* ucspServer.cpp in Sources */, + DC52ECE81D80D2FA00B0A59C /* pbkdf2-00-hmac-sha1.c in Sources */, + DC52ECE91D80D2FA00B0A59C /* spbkdf-00-hmac-sha1.c in Sources */, + DC52ECE11D80D2F000B0A59C /* otr-00-identity.c in Sources */, + DC52ECE21D80D2F000B0A59C /* otr-30-negotiation.c in Sources */, + DC52ECE31D80D2F000B0A59C /* otr-40-edgecases.c in Sources */, + DC52ECE41D80D2F000B0A59C /* otr-50-roll.c in Sources */, + DC52ECE51D80D2F000B0A59C /* otr-60-slowroll.c in Sources */, + DC52ECE61D80D2F000B0A59C /* otr-otrdh.c in Sources */, + DC52ECE71D80D2F000B0A59C /* otr-packetdata.c in Sources */, + DC52EC9B1D80D22600B0A59C /* si-00-find-nothing.c in Sources */, + DC52EC9C1D80D22600B0A59C /* si-05-add.c in Sources */, + DC52EC9D1D80D22600B0A59C /* si-10-find-internet.c in Sources */, + DC52EC9E1D80D22600B0A59C /* si-11-update-data.c in Sources */, + DC52EC9F1D80D22600B0A59C /* si-12-item-stress.c in Sources */, + DC52ECA01D80D22600B0A59C /* si-13-item-system.m in Sources */, + DC52ECA11D80D22600B0A59C /* si-14-dateparse.c in Sources */, + DC52ECA21D80D22600B0A59C /* si-15-delete-access-group.m in Sources */, + DC52ECA51D80D22600B0A59C /* si-17-item-system-bluetooth.m in Sources */, + DC52ECB61D80D22600B0A59C /* si-30-keychain-upgrade.c in Sources */, + DC52ECB71D80D22600B0A59C /* si-31-keychain-bad.c in Sources */, + DC52ECB81D80D22600B0A59C /* si-31-keychain-unreadable.c in Sources */, + DC52ECB91D80D22600B0A59C /* si-33-keychain-backup.c in Sources */, + DC52ECBA1D80D22600B0A59C /* si-40-seckey-custom.c in Sources */, + DC52ECBB1D80D22600B0A59C /* si-40-seckey.c in Sources */, + DC52ECBC1D80D22600B0A59C /* si-41-sececkey.c in Sources */, + DC52ECBD1D80D22600B0A59C /* si-42-identity.c in Sources */, + DC52ECBE1D80D22600B0A59C /* si-43-persistent.c in Sources */, + DC52ECC31D80D22600B0A59C /* si-50-secrandom.c in Sources */, + DC52ECC71D80D22600B0A59C /* si-63-scep.m in Sources */, + DC52ECCD1D80D22600B0A59C /* si-69-keydesc.c in Sources */, + DC52ECD01D80D22600B0A59C /* si-72-syncableitems.c in Sources */, + DC52ECD11D80D22600B0A59C /* si-73-secpasswordgenerate.c in Sources */, + DC52ECD31D80D22600B0A59C /* si-76-shared-credentials.c in Sources */, + DC52ECD41D80D22600B0A59C /* si_77_SecAccessControl.c in Sources */, + DC52ECD51D80D22600B0A59C /* si-78-query-attrs.c in Sources */, + DC52ECD61D80D22600B0A59C /* si-80-empty-data.c in Sources */, + DC52ECD91D80D22600B0A59C /* si-82-token-ag.c in Sources */, + DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */, + DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */, + DC52EC981D80D1D100B0A59C /* vmdh-40.c in Sources */, + D4D718351E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c in Sources */, + DC52EC991D80D1D100B0A59C /* vmdh-41-example.c in Sources */, + DC52EC9A1D80D1D100B0A59C /* vmdh-42-example2.c in Sources */, + DC52ECEA1D80D30900B0A59C /* so_01_serverencryption.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0067C91D878898005AF8DB /* Sources */ = { + DC52ED641D80D4CD00B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0067D11D8788B7005AF8DB /* ucspClientC.c in Sources */, + DC52EDA01D80D4F700B0A59C /* sd-10-policytree.m in Sources */, + DC52ED9F1D80D4F200B0A59C /* SOSTransportTestTransports.m in Sources */, + DC52ED9E1D80D4ED00B0A59C /* secd-95-escrow-persistence.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC54D1D8B6D2D00070CB0 /* Sources */ = { + DC52EDA71D80D58400B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5611D8B6D6000070CB0 /* main.c in Sources */, + E7C787211DCA4D430087FC34 /* CKDAKSLockMonitor.m in Sources */, + DC52EDFA1D80D66600B0A59C /* SOSRegressionUtilities.m in Sources */, + DCFAEDD61D99A47A005187E4 /* secd-36-ks-encrypt.m in Sources */, + 7281E08D1DFD0B520021E1B7 /* XPCNotificationDispatcher.m in Sources */, + DC52EDF91D80D66000B0A59C /* SOSTestDataSource.c in Sources */, + 7281E0911DFD0E510021E1B7 /* CKDSimulatedStore.m in Sources */, + E73A7E911DC81E0300A5B2D1 /* CKDSimulatedAccount.m in Sources */, + DC52EDF81D80D65C00B0A59C /* SOSTestDevice.c in Sources */, + DC52EDF71D80D65700B0A59C /* si-90-emcs.m in Sources */, + 483E798F1DC87605005C0008 /* secd-67-prefixedKeyIDs.m in Sources */, + 48CC589F1DA5FF2700EBD9DB /* secd-66-account-recovery.m in Sources */, + DC52EDF51D80D62E00B0A59C /* SecdTestKeychainUtilities.c in Sources */, + DC52EDF61D80D62E00B0A59C /* SOSTransportTestTransports.m in Sources */, + EB9C02481E8A15B40040D3C6 /* secd-37-pairing-initial-sync.m in Sources */, + 0CAD1E5E1E1C5D0600537693 /* secd-95-escrow-persistence.m in Sources */, + DC52EDB51D80D5C500B0A59C /* secd-03-corrupted-items.m in Sources */, + 0CAD1E5D1E1C5CF900537693 /* secd-80-views-alwayson.m in Sources */, + DC52EDB61D80D5C500B0A59C /* secd-04-corrupted-items.m in Sources */, + DC52EDB71D80D5C500B0A59C /* secd-05-corrupted-items.m in Sources */, + DC52EDBB1D80D5C500B0A59C /* secd-01-items.m in Sources */, + DC52EDBC1D80D5C500B0A59C /* secd-02-upgrade-while-locked.m in Sources */, + DC52EDBD1D80D5C500B0A59C /* secd-20-keychain_upgrade.m in Sources */, + DC52EDBE1D80D5C500B0A59C /* secd-21-transmogrify.m in Sources */, + DCFAEDD21D99991F005187E4 /* secd-668-ghosts.m in Sources */, + DC52EDBF1D80D5C500B0A59C /* secd-30-keychain-upgrade.m in Sources */, + DC52EDC11D80D5C500B0A59C /* secd-31-keychain-unreadable.m in Sources */, + 0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */, + DC52EDC21D80D5C500B0A59C /* secd-32-restore-bad-backup.m in Sources */, + DC52EDC31D80D5C500B0A59C /* secd-33-keychain-ctk.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 */, + DC52EDC51D80D5C500B0A59C /* secd-35-keychain-migrate-inet.m in Sources */, + DC52EDC61D80D5C500B0A59C /* secd-40-cc-gestalt.m in Sources */, + DC52EDC71D80D5C500B0A59C /* secd-50-account.m in Sources */, + DC52EDC81D80D5C500B0A59C /* secd-49-manifests.m in Sources */, + DC52EDC91D80D5C500B0A59C /* secd-50-message.m in Sources */, + DC52EDCA1D80D5C500B0A59C /* secd-51-account-inflate.m in Sources */, + DC52EDCC1D80D5C500B0A59C /* secd-52-account-changed.m in Sources */, + DC52EDCD1D80D5C500B0A59C /* secd-55-account-circle.m in Sources */, + DCFAEDD71D99A4AB005187E4 /* secd-154-engine-backoff.m in Sources */, + DC52EDCE1D80D5C500B0A59C /* secd-55-account-incompatibility.m in Sources */, + DC52EDCF1D80D5C500B0A59C /* secd-56-account-apply.m in Sources */, + DC52EDD01D80D5C500B0A59C /* secd-57-account-leave.m in Sources */, + DC52EDD11D80D5C500B0A59C /* secd-57-1-account-last-standing.m in Sources */, + DC52EDD21D80D5C500B0A59C /* secd-58-password-change.m in Sources */, + DC52EDD31D80D5C500B0A59C /* secd-59-account-cleanup.m in Sources */, + EB351540211A79E30097A87C /* secd-33-keychain-backup.m in Sources */, + DC52EDD41D80D5C500B0A59C /* secd-60-account-cloud-identity.m in Sources */, + DC52EDD51D80D5C500B0A59C /* secd60-account-cloud-exposure.m in Sources */, + DC52EDD61D80D5C500B0A59C /* secd-61-account-leave-not-in-kansas-anymore.m in Sources */, + 0C78826F20132069002B7475 /* SFSignInAnalytics.m in Sources */, + DC52EDD71D80D5C500B0A59C /* secd-62-account-backup.m in Sources */, + DC52EDD91D80D5C500B0A59C /* secd-63-account-resurrection.m in Sources */, + DC52EDDA1D80D5C500B0A59C /* secd-65-account-retirement-reset.m in Sources */, + DCDCC7E31D9B54EE006487E8 /* secd-202-recoverykey.m in Sources */, + DC52EDDB1D80D5C500B0A59C /* secd-64-circlereset.m in Sources */, + DC52EDDC1D80D5C500B0A59C /* secd-70-engine.m in Sources */, + 0C3C00731EF3636500AB19FE /* secd-155-otr-negotiation-monitor.m in Sources */, + 7281E08F1DFD0DBB0021E1B7 /* secd-210-keyinterest.m in Sources */, + 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 */, + 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 */, + 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 */, + DC52EDEB1D80D5C500B0A59C /* secd-83-item-match-policy.m in Sources */, + DC52EDEC1D80D5C500B0A59C /* secd-83-item-match-valid-on-date.m in Sources */, + DC52EDED1D80D5C600B0A59C /* secd-83-item-match-trusted.m in Sources */, + DC52EDF11D80D5C600B0A59C /* secd-100-initialsync.m in Sources */, + DC52EDF21D80D5C600B0A59C /* secd-130-other-peer-views.m in Sources */, + DC52EDF41D80D5C600B0A59C /* secd-200-logstate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5641D8B6E3D00070CB0 /* Sources */ = { + DC52EDFE1D80D6DD00B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5741D8B6E7700070CB0 /* main-tsa.m in Sources */, - DC0BC5751D8B6E7700070CB0 /* timestampclient.m in Sources */, + DC52EE611D80D79E00B0A59C /* si-71-mobile-store-policy.c in Sources */, + DC52EE601D80D79900B0A59C /* si-74-OTAPKISigner.c in Sources */, + D4AD87701E452CE000CA1B7F /* si-68-secmatchissuer.c in Sources */, + EB6928CA1D9C9E1800062A18 /* rk_01_recoverykey.m in Sources */, + D42CDC351DC12FE90090E2C9 /* si-66-smime.c in Sources */, + B61577F41F20513C004A3930 /* padding-00-mmcs.c in Sources */, + DC0B62291D90974600D43BCB /* si-25-cms-skid.m in Sources */, + 09CB49701F2F64E300C8E4DE /* si-44-seckey-fv.m in Sources */, + D48BD18D206C45F00075DDC9 /* si-89-cms-hash-agility.m in Sources */, + BE6215BE1DB6E69100961E15 /* si-84-sectrust-allowlist.m 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 */, + D4AA0D9A22FB959600D77FA4 /* si-29-cms-chain-mode.m in Sources */, + DC52EE451D80D71900B0A59C /* si-22-sectrust-iap.c in Sources */, + DC52EE471D80D71900B0A59C /* si-23-sectrust-ocsp.c in Sources */, + D48E4E241E42F0620011B4BA /* si-62-csr.m in Sources */, + 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 */, + DC52EE4C1D80D71900B0A59C /* si-24-sectrust-passbook.c in Sources */, + DC52EE4D1D80D71900B0A59C /* si-26-sectrust-copyproperties.c in Sources */, + 5E7793751E5F025A0074A2D1 /* si-44-seckey-aks.m in Sources */, + DC52EE4E1D80D71900B0A59C /* si-27-sectrust-exceptions.c in Sources */, + DC52EE4F1D80D71900B0A59C /* si-28-sectrustsettings.m in Sources */, + DC52EE531D80D73800B0A59C /* si-44-seckey-gen.m in Sources */, + DC52EE541D80D73800B0A59C /* si-44-seckey-rsa.m in Sources */, + DC52EE551D80D73800B0A59C /* si-44-seckey-ec.m in Sources */, + D4096E011ED5F0B5000AC459 /* si-60-cms.c in Sources */, + D4CFAA7E1E660BB3004746AA /* si-32-sectrust-pinning-required.m in Sources */, + BE9B8B4A202BB4A20081EF87 /* si-88-sectrust-valid.m in Sources */, + D48BD194206C47530075DDC9 /* si-35-cms-expiration-time.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 */, + 478014541FBF577000C4043D /* si-44-seckey-proxy.m in Sources */, + DCD45357209A5BA10086CBFC /* si-cms-signing-identity-p12.c in Sources */, + DC52EE581D80D73800B0A59C /* si-70-sectrust-unified.c in Sources */, + DC52EE5A1D80D73800B0A59C /* si-83-seccertificate-sighashalg.c in Sources */, + D47E69401E92F75D002C8CF6 /* si-61-pkcs12.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5871D8B70E700070CB0 /* Sources */ = { + DC52EE671D80D82600B0A59C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5A81D8B711000070CB0 /* cuPem.cpp in Sources */, - DC0BC5A21D8B711000070CB0 /* cuEnc64.c in Sources */, - DC0BC59E1D8B711000070CB0 /* cuCdsaUtils.cpp in Sources */, - DC0BC5A01D8B711000070CB0 /* cuDbUtils.cpp in Sources */, - DC0BC5A61D8B711000070CB0 /* cuOidParser.cpp in Sources */, - DC0BC5AA1D8B711000070CB0 /* cuPrintCert.cpp in Sources */, - DC0BC5AC1D8B711000070CB0 /* cuTimeStr.cpp in Sources */, - DC0BC5A41D8B711000070CB0 /* cuFileIo.c in Sources */, + EB78D3F91E600E93009AFE05 /* SOSCloudCircle.m in Sources */, + DC52EE7C1D80D89E00B0A59C /* SecItemBackup.c in Sources */, + 5F00F9562306146700B832E0 /* p12import.c in Sources */, + DC4269051E82EDC4002B7110 /* SecItem.m in Sources */, + 5F00F9582306147100B832E0 /* p12pbegen.c in Sources */, + 5F00F9592306147A00B832E0 /* SecImportExport.c in Sources */, + DC52EE7B1D80D89900B0A59C /* SecKeyAdaptors.m in Sources */, + DC52EE7A1D80D89400B0A59C /* SecCFAllocator.c in Sources */, + DC52EE791D80D88D00B0A59C /* SecItem.c in Sources */, + DC52EE781D80D88800B0A59C /* SecRSAKey.c in Sources */, + 478014701FBF5BD800C4043D /* SecKeyProxy.m in Sources */, + DC52EE771D80D88300B0A59C /* SecDH.c in Sources */, + DC52EE761D80D87F00B0A59C /* SecCTKKey.m in Sources */, + DC52EE741D80D86F00B0A59C /* SecAccessControl.m in Sources */, + DC52EE731D80D86800B0A59C /* SecKey.m in Sources */, + DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */, + DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */, + DC52EE701D80D84700B0A59C /* SecItemConstants.c in Sources */, + DC52EE6F1D80D83F00B0A59C /* SecPasswordGenerate.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5B21D8B71FD00070CB0 /* Sources */ = { + DC58C41F1D77BDEA003C25A4 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5BC1D8B723500070CB0 /* checkpw.c in Sources */, + DC58C43E1D77BED0003C25A4 /* csparser.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5C21D8B72E700070CB0 /* Sources */ = { + DC5ABDC11D832DAB00CF422C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5CF1D8B730D00070CB0 /* test-checkpw.c in Sources */, + DC5ABDCC1D832E4000CF422C /* srCdsaUtils.cpp in Sources */, + DC5ABDCD1D832E4000CF422C /* createFVMaster.c in Sources */, + DC5ABDCE1D832E4000CF422C /* mds_install.cpp in Sources */, + DC5ABDCF1D832E4000CF422C /* cmsutil.c in Sources */, + DC5ABDD01D832E4000CF422C /* db_commands.cpp in Sources */, + DC5ABDD11D832E4000CF422C /* display_error_code.c in Sources */, + DC5ABDD21D832E4000CF422C /* trusted_cert_dump.c in Sources */, + DC5ABDD31D832E4000CF422C /* identity_find.m in Sources */, + DC5ABDD41D832E4000CF422C /* identity_prefs.c in Sources */, + DC5ABDD51D832E4000CF422C /* key_create.c in Sources */, + DC5ABDD61D832E4000CF422C /* keychain_add.c in Sources */, + DC5ABDD71D832E4000CF422C /* keychain_create.c in Sources */, + DC5ABDD81D832E4000CF422C /* keychain_delete.c in Sources */, + DC5ABDD91D832E4000CF422C /* keychain_export.m in Sources */, + DC5ABDDA1D832E4000CF422C /* keychain_find.c in Sources */, + DC5ABDDB1D832E4000CF422C /* keychain_import.c in Sources */, + DC5ABDDC1D832E4000CF422C /* keychain_list.c in Sources */, + DC5ABDDD1D832E4000CF422C /* keychain_lock.c in Sources */, + DC5ABDDE1D832E4000CF422C /* keychain_recode.c in Sources */, + DC5ABDDF1D832E4000CF422C /* keychain_set_settings.c in Sources */, + DC5ABDE01D832E4000CF422C /* keychain_show_info.c in Sources */, + DC5ABDE11D832E4000CF422C /* keychain_unlock.c in Sources */, + DC5ABDE21D832E4000CF422C /* keychain_utilities.c in Sources */, + DC5ABDE31D832E4000CF422C /* leaks.c in Sources */, + DC5ABDE41D832E4000CF422C /* readline.c in Sources */, + DC5ABDE51D832E4000CF422C /* security.c in Sources */, + DC5ABDEE1D832E4E00CF422C /* smartcards.m in Sources */, + DC5ABDE61D832E4000CF422C /* trusted_cert_add.c in Sources */, + DC5ABDE71D832E4000CF422C /* trusted_cert_utils.c in Sources */, + DC5ABDE81D832E4000CF422C /* trust_settings_impexp.c in Sources */, + DC5ABDE91D832E4000CF422C /* user_trust_enable.cpp in Sources */, + F9F77E98223C2F9A00E5CBF6 /* requirement.c in Sources */, + DC5ABDEA1D832E4000CF422C /* authz.c in Sources */, + DC5ABDEB1D832E4000CF422C /* verify_cert.c in Sources */, + BE64A80022AF010B001209F3 /* trusted_cert_ssl.m in Sources */, + DC5ABDEC1D832E4000CF422C /* access_utils.c in Sources */, + DC5ABDED1D832E4000CF422C /* translocate.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5D81D8B73B000070CB0 /* Sources */ = { + DC5AC04C1D8352D900CF422C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5D91D8B73B000070CB0 /* test-checkpw.c in Sources */, + DC5AC1031D83552000CF422C /* selfServer.cpp in Sources */, + DC5AC1041D83552000CF422C /* selfUser.cpp in Sources */, + DC5AC0D81D8354CA00CF422C /* main.cpp in Sources */, + DC5AC0D91D8354CA00CF422C /* connection.cpp in Sources */, + DC5AC0DA1D8354CA00CF422C /* database.cpp in Sources */, + DC5AC0DB1D8354CA00CF422C /* key.cpp in Sources */, + DC5AC0DC1D8354CA00CF422C /* process.cpp in Sources */, + DC5AC0DD1D8354CA00CF422C /* server.cpp in Sources */, + DC5AC0DE1D8354CA00CF422C /* session.cpp in Sources */, + DC5AC0DF1D8354CA00CF422C /* structure.cpp in Sources */, + D4BD5E93228A720E001650A7 /* util.m in Sources */, + DC5AC0E01D8354CA00CF422C /* dbcrypto.cpp in Sources */, + DC5AC0E11D8354CA00CF422C /* localdatabase.cpp in Sources */, + DC5AC0E21D8354CA00CF422C /* localkey.cpp in Sources */, + DC5AC0E31D8354CA00CF422C /* kcdatabase.cpp in Sources */, + DC5AC0E41D8354CA00CF422C /* kckey.cpp in Sources */, + DC5AC0E51D8354CA00CF422C /* tempdatabase.cpp in Sources */, + DC5AC0E61D8354CA00CF422C /* tokendatabase.cpp in Sources */, + DC5AC0E71D8354CA00CF422C /* tokenkey.cpp in Sources */, + DC5AC0E81D8354CA00CF422C /* tokenaccess.cpp in Sources */, + DC5AC0E91D8354CA00CF422C /* pcscmonitor.cpp in Sources */, + DC5AC0EA1D8354CA00CF422C /* reader.cpp in Sources */, + DC5AC0EB1D8354CA00CF422C /* token.cpp in Sources */, + DC5AC0EC1D8354CA00CF422C /* tokend.cpp in Sources */, + DC5AC0ED1D8354CA00CF422C /* tokencache.cpp in Sources */, + DC5AC0EE1D8354CA00CF422C /* transition.cpp in Sources */, + DC5AC0EF1D8354CA00CF422C /* acls.cpp in Sources */, + DC5AC0F01D8354CA00CF422C /* tokenacl.cpp in Sources */, + DC5AC0F11D8354CA00CF422C /* acl_keychain.cpp in Sources */, + DC5AC0F21D8354CA00CF422C /* acl_partition.cpp in Sources */, + DC5AC0F31D8354CA00CF422C /* authhost.cpp in Sources */, + DC5AC0F41D8354CA00CF422C /* credential.cpp in Sources */, + DC5AC0F51D8354CA00CF422C /* clientid.cpp in Sources */, + DC5AC0F61D8354CA00CF422C /* codesigdb.cpp in Sources */, + DC5AC0F81D8354CA00CF422C /* agentquery.cpp in Sources */, + DC5AC0F91D8354CA00CF422C /* auditevents.cpp in Sources */, + DC5AC0FA1D8354CA00CF422C /* ccaudit_extensions.cpp in Sources */, + DC5AC0FB1D8354CA00CF422C /* child.cpp in Sources */, + DC5AC0FD1D8354CA00CF422C /* notifications.cpp in Sources */, + DC5AC0FE1D8354CA00CF422C /* SharedMemoryServer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5E41D8B742200070CB0 /* Sources */ = { + DC610A171D78F129002223DE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC5F11D8B745700070CB0 /* comcryption.c in Sources */, - DC0BC5F31D8B745700070CB0 /* comcryptPriv.c in Sources */, + DCD504BC20CB28BE00F37D26 /* SecFramework.c in Sources */, + 476541A21F33EDAD00413F65 /* SecdWatchdog.m in Sources */, + DCCD33D31E3FF0D800AA4AD1 /* spi.c in Sources */, + DC610A181D78F129002223DE /* main.m in Sources */, + DC5F35B01EE0F27C00900966 /* server_entitlement_helpers.c in Sources */, + DC4269121E82FDA1002B7110 /* server_security_helpers.m in Sources */, + DCB2215A1E8B08CB001598BC /* server_xpc.m in Sources */, + DC4269011E82038D002B7110 /* server_endpoint.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC5FA1D8B752B00070CB0 /* Sources */ = { + DC610A431D78F48F002223DE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC6661D8B755200070CB0 /* CryptKitAsn1.cpp in Sources */, - DC0BC6681D8B755200070CB0 /* CryptKitDER.cpp in Sources */, - DC0BC6981D8B755200070CB0 /* HmacSha1Legacy.c in Sources */, - DC0BC6511D8B755200070CB0 /* byteRep.c in Sources */, - DC0BC65D1D8B755200070CB0 /* ckSHA1.c in Sources */, - DC0BC6611D8B755200070CB0 /* ckutilities.c in Sources */, - DC0BC66C1D8B755200070CB0 /* curveParams.c in Sources */, - DC0BC6701D8B755200070CB0 /* elliptic.c in Sources */, - DC0BC6731D8B755200070CB0 /* ellipticProj.c in Sources */, - DC0BC6751D8B755200070CB0 /* enc64.c in Sources */, - DC0BC6771D8B755200070CB0 /* engineNSA127.c in Sources */, - DC0BC6781D8B755200070CB0 /* falloc.c in Sources */, - DC0BC67C1D8B755200070CB0 /* feeDES.c in Sources */, - DC0BC67E1D8B755200070CB0 /* feeDigitalSignature.c in Sources */, - DC0BC6801D8B755200070CB0 /* feeECDSA.c in Sources */, - DC0BC6821D8B755200070CB0 /* feeFEED.c in Sources */, - DC0BC6841D8B755200070CB0 /* feeFEEDExp.c in Sources */, - DC0BC6871D8B755200070CB0 /* feeHash.c in Sources */, - DC0BC6891D8B755200070CB0 /* feePublicKey.c in Sources */, - DC0BC68C1D8B755200070CB0 /* feeRandom.c in Sources */, - DC0BC68F1D8B755200070CB0 /* giantIntegers.c in Sources */, - DC0BC6931D8B755200070CB0 /* giantPort_PPC.c in Sources */, - DC0BC6961D8B755200070CB0 /* giantPort_PPC_Gnu.s in Sources */, - DC0BC69A1D8B755200070CB0 /* platform.c in Sources */, + DC610A501D78F715002223DE /* main.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC7471D8B771600070CB0 /* Sources */ = { + DC610A561D78F9D2002223DE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC79D1D8B773000070CB0 /* attachment.cpp in Sources */, - DC0BC7AE1D8B773000070CB0 /* modloader.cpp in Sources */, - DC0BC79F1D8B773000070CB0 /* cspattachment.cpp in Sources */, - DC0BC7A21D8B773000070CB0 /* cssmcontext.cpp in Sources */, - DC0BC7B21D8B773000070CB0 /* oidsalg.c in Sources */, - DC0BC7AA1D8B773000070CB0 /* modload_plugin.cpp in Sources */, - DC0BC7B41D8B773000070CB0 /* oidscrl.cpp in Sources */, - DC0BC79B1D8B773000070CB0 /* attachfactory.cpp in Sources */, - DC0BC7A51D8B773000070CB0 /* cssmmds.cpp in Sources */, - DC0BC7AC1D8B773000070CB0 /* modload_static.cpp in Sources */, - DC0BC7B51D8B773000070CB0 /* transition.cpp in Sources */, - DC0BC7A11D8B773000070CB0 /* cssm.cpp in Sources */, - DC0BC7B31D8B773000070CB0 /* oidscert.cpp in Sources */, - DC0BC7B01D8B773000070CB0 /* module.cpp in Sources */, - DC0BC7A71D8B773000070CB0 /* guids.cpp in Sources */, - DC0BC7A81D8B773000070CB0 /* manager.cpp in Sources */, + DC610A611D78F9F2002223DE /* FatDynamicValidation.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC89A1D8B7CBD00070CB0 /* Sources */ = { + DC610AAE1D7910C3002223DE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC8BC1D8B7CFF00070CB0 /* DbQuery.cpp in Sources */, - DC0BC8B81D8B7CFF00070CB0 /* AtomicFile.cpp in Sources */, - DC0BC8B61D8B7CFF00070CB0 /* AppleDatabase.cpp in Sources */, - DC0BC8C21D8B7CFF00070CB0 /* MetaRecord.cpp in Sources */, - DC0BC8BA1D8B7CFF00070CB0 /* DbIndex.cpp in Sources */, - DC0BC8BE1D8B7CFF00070CB0 /* DbValue.cpp in Sources */, - DC0BC8C51D8B7CFF00070CB0 /* SelectionPredicate.cpp in Sources */, - DC0BC8C01D8B7CFF00070CB0 /* MetaAttribute.cpp in Sources */, - DC0BC8C71D8B7CFF00070CB0 /* ReadWriteSection.cpp in Sources */, + DC610ABA1D7910F8002223DE /* gk_reset_check.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC8CE1D8B7DA200070CB0 /* Sources */ = { + DC6A828E1D87749900418608 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC8EF1D8B7DD000070CB0 /* ManifestSigner.cpp in Sources */, - DC0BC8F11D8B7DD000070CB0 /* Manifest.cpp in Sources */, - DC0BC8F41D8B7DD000070CB0 /* SecManifest.cpp in Sources */, - DC0BC8E91D8B7DD000070CB0 /* SecureDownloadInternal.c in Sources */, - DC0BC8E71D8B7DCF00070CB0 /* SecureDownload.cpp in Sources */, - DC0BC8ED1D8B7DD000070CB0 /* ManifestInternal.cpp in Sources */, - DC0BC8E51D8B7DCF00070CB0 /* Download.cpp in Sources */, - DC0BC8EB1D8B7DD000070CB0 /* AppleManifest.cpp in Sources */, + DC6A82B11D87769800418608 /* dictionary.cpp in Sources */, + DC6A82B21D87769800418608 /* sec_xdr.c in Sources */, + DC6A82B31D87769800418608 /* sec_xdr_array.c in Sources */, + DC6A82B41D87769800418608 /* sec_xdr_reference.c in Sources */, + DC6A82B51D87769800418608 /* sec_xdrmem.c in Sources */, + DC6A82B61D87769800418608 /* sec_xdr_sizeof.c in Sources */, + DC6A82B71D87769800418608 /* xdr_auth.c in Sources */, + DC6A82B81D87769800418608 /* xdr_cssm.c in Sources */, + DC6A82B91D87769800418608 /* xdr_dldb.cpp in Sources */, + DC6A82BA1D87769800418608 /* SharedMemoryClient.cpp in Sources */, + DC6A82BB1D87769800418608 /* eventlistener.cpp in Sources */, + DC6A82C41D8776D800418608 /* ssblob.cpp in Sources */, + DC6A82BC1D87769800418608 /* ssclient.cpp in Sources */, + DC6A82BD1D87769800418608 /* sstransit.cpp in Sources */, + DC6A82BE1D87769800418608 /* transition.cpp in Sources */, + DC6A82BF1D8776B300418608 /* ucspClient.cpp in Sources */, + DC6A82C01D8776B300418608 /* ucspNotifySender.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC8FB1D8B7E8000070CB0 /* Sources */ = { + DC7FC44421EE914C003C39B8 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC9201D8B7EA700070CB0 /* MDSDictionary.cpp in Sources */, - DC0BC91E1D8B7EA700070CB0 /* MDSDatabase.cpp in Sources */, - DC0BC9181D8B7EA700070CB0 /* MDSAttrParser.cpp in Sources */, - DC0BC9241D8B7EA700070CB0 /* MDSSchema.cpp in Sources */, - DC0BC9221D8B7EA700070CB0 /* MDSModule.cpp in Sources */, - DC0BC91C1D8B7EA700070CB0 /* MDSAttrUtils.cpp in Sources */, - DC0BC91A1D8B7EA700070CB0 /* MDSAttrStrings.cpp in Sources */, - DC0BC9261D8B7EA700070CB0 /* MDSSession.cpp in Sources */, - DC0BC9171D8B7EA700070CB0 /* mdsapi.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC9301D8B7F6A00070CB0 /* Sources */ = { + DC8834031D8A218F00CE0ACA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC95B1D8B7FFE00070CB0 /* ocspd_client.cpp in Sources */, - DC0BC9461D8B7FA700070CB0 /* ocspdDbSchema.cpp in Sources */, - DC0BC9581D8B7FFE00070CB0 /* ocspd.defs in Sources */, - DC0BC94A1D8B7FA700070CB0 /* ocspResponse.cpp in Sources */, - DC0BC95A1D8B7FFE00070CB0 /* ocspd_server.cpp in Sources */, - DC0BC94F1D8B7FE000070CB0 /* ocspdClient.cpp in Sources */, - DC0BC9481D8B7FA700070CB0 /* ocspExtensions.cpp in Sources */, - DC0BC9421D8B7FA700070CB0 /* ocspdUtils.cpp in Sources */, + DC88348D1D8A21AB00CE0ACA /* X509Templates.c in Sources */, + DC88345B1D8A21AA00CE0ACA /* keyTemplates.c in Sources */, + DC8834541D8A21AA00CE0ACA /* SecAsn1Templates.c in Sources */, + DC88348F1D8A21AB00CE0ACA /* osKeyTemplates.c in Sources */, + DC8834631D8A21AA00CE0ACA /* nsprPortX.c in Sources */, + DC88345D1D8A21AA00CE0ACA /* nameTemplates.c in Sources */, + DC88345F1D8A21AA00CE0ACA /* pkcs7Templates.c in Sources */, + DC88346B1D8A21AA00CE0ACA /* plarena.c in Sources */, + DC8834831D8A21AB00CE0ACA /* secasn1e.c in Sources */, + DC8834891D8A21AB00CE0ACA /* SecNssCoder.cpp in Sources */, + DC8834911D8A21AB00CE0ACA /* oidsalg.c in Sources */, + DC8834691D8A21AA00CE0ACA /* ocspTemplates.c in Sources */, + DC8834571D8A21AA00CE0ACA /* certExtensionTemplates.c in Sources */, + DC88348B1D8A21AB00CE0ACA /* secport.c in Sources */, + DC8834671D8A21AA00CE0ACA /* nssUtils.c in Sources */, + DC8834611D8A21AA00CE0ACA /* pkcs12Templates.c in Sources */, + DC8834591D8A21AA00CE0ACA /* csrTemplates.c in Sources */, + DC8834931D8A21AB00CE0ACA /* oidsattr.c in Sources */, + DC8834881D8A21AB00CE0ACA /* secErrorStr.c in Sources */, + DC8834961D8A21AB00CE0ACA /* oidsocsp.c in Sources */, + DC8834821D8A21AB00CE0ACA /* secasn1d.c in Sources */, + DC8834521D8A21AA00CE0ACA /* SecAsn1Coder.c in Sources */, + DC8834851D8A21AB00CE0ACA /* secasn1u.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC9681D8B810A00070CB0 /* Sources */ = { + DC99B86A20EACA470065B73B /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC9881D8B813800070CB0 /* pkcs12Crypto.cpp in Sources */, - DC0BC9921D8B813800070CB0 /* pkcs12Utils.cpp in Sources */, - DC0BC98B1D8B813800070CB0 /* pkcs12Decode.cpp in Sources */, - DC0BC9841D8B813800070CB0 /* pkcs12BagAttrs.cpp in Sources */, - DC0BC9861D8B813800070CB0 /* pkcs12Coder.cpp in Sources */, - DC0BC98C1D8B813800070CB0 /* pkcs12Encode.cpp in Sources */, - DC0BC9961D8B813800070CB0 /* SecPkcs12.cpp in Sources */, - DC0BC98E1D8B813800070CB0 /* pkcs12SafeBag.cpp in Sources */, - DC0BC98D1D8B813800070CB0 /* pkcs12Keychain.cpp in Sources */, - DC0BC9941D8B813800070CB0 /* pkcs7Templates.cpp in Sources */, - DC0BC9901D8B813800070CB0 /* pkcs12Templates.cpp in Sources */, + 1B8D2D96226E1FA500C94238 /* SetValueTransformer.swift in Sources */, + DC5F2BBE2310B941001ADA5D /* OctagonTests+CoreFollowUp.swift in Sources */, + DCB468E520EC262C00BA7E5B /* ContainerMap.swift in Sources */, + 0C4CDE6F22922E550050C499 /* OctagonTests+RecoveryKey.swift in Sources */, + EBDE5E0F22BA3DEA00A229C8 /* CKKSMockOctagonAdapter.m in Sources */, + DCB468DF20EC25FF00BA7E5B /* Client.swift in Sources */, + 0C5824A52286002D009E8C15 /* OctagonTests+HealthCheck.swift in Sources */, + DC27C3CE20EAFE9C00F7839C /* CloudKitMockXCTest.m in Sources */, + DCB9475821274F9D00ED9272 /* TPHObjcTranslation.m in Sources */, + DC27C3CB20EADF3500F7839C /* CloudKitKeychainSyncingMockXCTest.m in Sources */, + 0C87D3E4229368BD007853B5 /* OctagonTests+SOS.swift in Sources */, + DC27C3C920EADEE700F7839C /* MockCloudKit.m in Sources */, + 0CF70BE0218CF26600EC3515 /* BottledPeer.swift in Sources */, + DC99B86B20EACA470065B73B /* spi.c in Sources */, + DCDF03122284E34B008055BA /* OctagonTests+EscrowRecovery.swift in Sources */, + DCFF82712162834D00D54B02 /* OctagonTestsXPCConnections.swift in Sources */, + DC5BEACD2217509A001681F0 /* OctagonTests+CloudKitAccount.swift in Sources */, + 0CF70BDB218BEFF000EC3515 /* CuttlefishExtensionWorkaround.swift in Sources */, + DC07090422936DB2002711B9 /* OctagonTests+ErrorHandling.swift in Sources */, + DC99B86C20EACA470065B73B /* FakeCuttlefish.swift in Sources */, + 0CBEF3432242CA0600015691 /* TestsObjcTranslation.m in Sources */, + 5A04BB0222982733001848A0 /* OTFollowupTests.m in Sources */, + DCB24B45221B901700BE73FE /* CKKSMockSOSPresentAdapter.m in Sources */, + 0CE15E31222DF63600B7EAA4 /* RecoverKeySet.swift in Sources */, + 0CADDF0721545CF100DF8B06 /* OctagonPairingTests.swift in Sources */, + DC99B86D20EACA470065B73B /* SecdWatchdog.m in Sources */, + DC26666C21CAC97000F19960 /* OTControlCLI.m in Sources */, + DC99B86E20EACA470065B73B /* MockCuttlefish.swift in Sources */, + 0CF70BE3218CF2AA00EC3515 /* OTBottle.m in Sources */, + DC27C3CA20EADF1700F7839C /* CloudKitKeychainSyncingTestsBase.m in Sources */, + 0CF70BE4218CF2AA00EC3515 /* OTBottleContents.m in Sources */, + 0C61F1F92194FC82009566D4 /* OTAuthenticatedCiphertext+SF.m in Sources */, + DCB0C291222F5E130083AECB /* CuttlefishErrors.swift in Sources */, + DC99B86F20EACA470065B73B /* SecFramework.c in Sources */, + 0C5258BB21BB128000B32C96 /* FakeSOSControl.m in Sources */, + DC99B87020EACA470065B73B /* server_endpoint.m in Sources */, + 0CD5797A21498F8200C43496 /* OctagonPairingTests+Piggybacking.swift in Sources */, + DCAD8F8722C43ECA007C3872 /* Container_MachineIDs.swift in Sources */, + DC99B87120EACA470065B73B /* server_security_helpers.m in Sources */, + 0CF70BE1218CF27600EC3515 /* EscrowKeys.swift in Sources */, + DC7F79B622EA4ED4001FB69A /* OctagonTests+CKKS.swift in Sources */, + 0CBA047D214C4E4D005B3A2F /* OctagonPairingTests+ProxMultiClients.swift in Sources */, + DCF6320821C09DCE0030CCC0 /* CuttlefishAPIHelpers.swift in Sources */, + 0CE15E44222DF6A800B7EAA4 /* Recovery.m in Sources */, + DC725030229600C000493D88 /* OctagonTests+Reset.swift in Sources */, + 0C3E316B21372FA50093C04B /* OctagonPairingTests+ProximitySetup.swift in Sources */, + DC2819B922F8F6FE007829F5 /* OctagonTests+DeviceList.swift in Sources */, + 0CF70BE5218CF2AA00EC3515 /* OTPrivateKey.m in Sources */, + BECFA45920FEB90900B11002 /* Policy.swift in Sources */, + DC99B87220EACA470065B73B /* Cuttlefish.pb.swift in Sources */, + 0CF70BE2218CF2AA00EC3515 /* OTAuthenticatedCiphertext.m in Sources */, + DCB41E01216D5FE500F219E0 /* OctagonDataPersistenceTests.swift in Sources */, + DC85687E2284E7860088D3EF /* OctagonTestMocks.swift in Sources */, + DC99B87320EACA470065B73B /* Decrypter.swift in Sources */, + DC99B87420EACA470065B73B /* server_entitlement_helpers.c in Sources */, + DC99B87520EACA470065B73B /* TrustedPeersHelper.xcdatamodeld in Sources */, + 0CE15E2D222DF63600B7EAA4 /* RecoveryKey.swift in Sources */, + DC27C3C120EAD9C300F7839C /* OctagonTests.swift in Sources */, + 0CE15E3F222DF6A800B7EAA4 /* OTRecovery.m in Sources */, + DCB9475A2127534C00ED9272 /* OctagonTests+SOSUpgrade.swift in Sources */, + DC99B87720EACA470065B73B /* ContainerSync.swift in Sources */, + 0C61F1F62194FC79009566D4 /* OTPrivateKey+SF.m in Sources */, + DC391FA821C04DAE00772585 /* OctagonPeerKeys.swift in Sources */, + DC99B87820EACA470065B73B /* Container.swift in Sources */, + DC99B87920EACA470065B73B /* Utils.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC99C1D8B81BE00070CB0 /* Sources */ = { + DCB340681D8A24DF0054D16E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC9BE1D8B81EF00070CB0 /* SDCSPSession.cpp in Sources */, - DC0BC9B81D8B81EF00070CB0 /* SDCSPDLDatabase.cpp in Sources */, - DC0BC9C01D8B81EF00070CB0 /* SDDLSession.cpp in Sources */, - DC0BC9B51D8B81EF00070CB0 /* SDContext.cpp in Sources */, - DC0BC9BC1D8B81EF00070CB0 /* SDCSPDLSession.cpp in Sources */, - DC0BC9C21D8B81EF00070CB0 /* SDFactory.cpp in Sources */, - DC0BC9C41D8B81EF00070CB0 /* SDKey.cpp in Sources */, - DC0BC9BA1D8B81EF00070CB0 /* SDCSPDLPlugin.cpp in Sources */, - DC0BC9B71D8B81EF00070CB0 /* SDCSPDLBuiltin.cpp in Sources */, + DCB340881D8A24F70054D16E /* trampolineServer.cpp in Sources */, + DCB340841D8A24F70054D16E /* Authorization.cpp in Sources */, + DCB3407D1D8A24F70054D16E /* Authorization.c in Sources */, + DC0BC5831D8B709F00070CB0 /* authutilities.c in Sources */, + DCB340871D8A24F70054D16E /* trampolineClient.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BC9CA1D8B824700070CB0 /* Sources */ = { + DCB340901D8A267C0054D16E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BC9FA1D8B827200070CB0 /* sslRecord.c in Sources */, - DC0BC9F91D8B827200070CB0 /* sslContext.c in Sources */, - DC0BC9FC1D8B827200070CB0 /* tlsCallbacks.c in Sources */, - DC0BC9F71D8B827200070CB0 /* SSLRecordInternal.c in Sources */, - DC0BC9F61D8B827200070CB0 /* sslKeychain.c in Sources */, - DC0BCA111D8B827200070CB0 /* sslMemory.c in Sources */, - DC0BC9FB1D8B827200070CB0 /* sslTransport.c in Sources */, - DC0BC9F81D8B827200070CB0 /* sslCipherSpecs.c in Sources */, - DC0BCA101D8B827200070CB0 /* sslCrypto.c in Sources */, + DCB340CC1D8A26AE0054D16E /* dlclient.cpp in Sources */, + DCB340DF1D8A26AE0054D16E /* mdsclient.cpp in Sources */, + DCB340E91D8A26AE0054D16E /* tpclient.cpp in Sources */, + DCB340CA1D8A26AE0054D16E /* cssmclient.cpp in Sources */, + DCB340C61D8A26AE0054D16E /* cryptoclient.cpp in Sources */, + DCB340C21D8A26AE0054D16E /* aclclient.cpp in Sources */, + DCB340D51D8A26AE0054D16E /* DLDBList.cpp in Sources */, + DCB340C41D8A26AE0054D16E /* clclient.cpp in Sources */, + DCB340E71D8A26AE0054D16E /* signclient.cpp in Sources */, + DCB340D71D8A26AE0054D16E /* genkey.cpp in Sources */, + DCB340DD1D8A26AE0054D16E /* macclient.cpp in Sources */, + DCB340EB1D8A26AE0054D16E /* wrapkey.cpp in Sources */, + DCB340D91D8A26AE0054D16E /* keychainacl.cpp in Sources */, + DCB340CF1D8A26AE0054D16E /* dliterators.cpp in Sources */, + DCB340E11D8A26AE0054D16E /* mds_standard.cpp in Sources */, + DCB340D31D8A26AE0054D16E /* dl_standard.cpp in Sources */, + DCB340E51D8A26AE0054D16E /* securestorage.cpp in Sources */, + DCB340DB1D8A26AE0054D16E /* keyclient.cpp in Sources */, + DCB340D11D8A26AE0054D16E /* dlquery.cpp in Sources */, + DCB340C81D8A26AE0054D16E /* cspclient.cpp in Sources */, + DCB340CD1D8A26AE0054D16E /* dlclientpriv.cpp in Sources */, + DCB340E31D8A26AE0054D16E /* multidldb.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BCA151D8B82B000070CB0 /* Sources */ = { + DCB341321D8A2A010054D16E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCA721D8B82CD00070CB0 /* ssl-utils.c in Sources */, - DC0BCA6D1D8B82CD00070CB0 /* ssl-52-noconn.c in Sources */, - DC0BCA661D8B82CD00070CB0 /* ssl-45-tls12.c in Sources */, - DC0BCA691D8B82CD00070CB0 /* ssl-48-split.c in Sources */, - DC0BCA6F1D8B82CD00070CB0 /* ssl-54-dhe.c in Sources */, - DC0BCA651D8B82CD00070CB0 /* ssl-44-crashes.c in Sources */, - DC0BCA621D8B82CD00070CB0 /* ssl-41-clientauth.c in Sources */, - DC0BCA631D8B82CD00070CB0 /* ssl-42-ciphers.c in Sources */, - DC0BCA701D8B82CD00070CB0 /* ssl-55-sessioncache.c in Sources */, - DC0BCA671D8B82CD00070CB0 /* ssl-46-SSLGetSupportedCiphers.c in Sources */, - DC0BCA641D8B82CD00070CB0 /* ssl-43-ciphers.c in Sources */, - DC0BCA6C1D8B82CD00070CB0 /* ssl-51-state.c in Sources */, - DC0BCA6A1D8B82CD00070CB0 /* ssl-49-sni.c in Sources */, - DC0BCA6B1D8B82CD00070CB0 /* ssl-50-server.c in Sources */, - DC0BCA711D8B82CD00070CB0 /* ssl-56-renegotiate.c in Sources */, - DC0BCA6E1D8B82CD00070CB0 /* ssl-53-clientauth.c in Sources */, - DC0BCA601D8B82CD00070CB0 /* ssl-39-echo.c in Sources */, - DC0BCA681D8B82CD00070CB0 /* ssl-47-falsestart.c in Sources */, - DC0BCA611D8B82CD00070CB0 /* ssl-40-clientauth.c in Sources */, + DCB3416E1D8A2A340054D16E /* ACabstractsession.cpp in Sources */, + DCB341701D8A2A340054D16E /* CSPabstractsession.cpp in Sources */, + DCB341711D8A2A340054D16E /* DLabstractsession.cpp in Sources */, + DCB341641D8A2A340054D16E /* DatabaseSession.cpp in Sources */, + DCB3415D1D8A2A340054D16E /* CSPsession.cpp in Sources */, + DCB3415F1D8A2A340054D16E /* csputilities.cpp in Sources */, + DCB341661D8A2A340054D16E /* DbContext.cpp in Sources */, + DCB341621D8A2A340054D16E /* Database.cpp in Sources */, + DCB3416A1D8A2A340054D16E /* pluginsession.cpp in Sources */, + DCB341601D8A2A340054D16E /* cssmplugin.cpp in Sources */, + DCB341721D8A2A340054D16E /* TPabstractsession.cpp in Sources */, + DCB341681D8A2A340054D16E /* DLsession.cpp in Sources */, + DCB3416F1D8A2A340054D16E /* CLabstractsession.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BCA7B1D8B858600070CB0 /* Sources */ = { + DCB3417D1D8A2B860054D16E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCAC71D8B85BC00070CB0 /* c++utils.cpp in Sources */, - DC0BCAEF1D8B85BC00070CB0 /* Source.cpp in Sources */, - DC0BCACE1D8B85BC00070CB0 /* EncryptTransform.cpp in Sources */, - DC0BCAE81D8B85BC00070CB0 /* SecSignVerifyTransform.c in Sources */, - DC0BCAD21D8B85BC00070CB0 /* GroupTransform.cpp in Sources */, - DC0BCADD1D8B85BC00070CB0 /* SecCustomTransform.cpp in Sources */, - DC0BCAFA1D8B85BC00070CB0 /* SecExternalSourceTransform.cpp in Sources */, - DC0BCAF11D8B85BC00070CB0 /* StreamSource.cpp in Sources */, - DC0BCAE41D8B85BC00070CB0 /* SecGroupTransform.cpp in Sources */, - DC0BCAD61D8B85BC00070CB0 /* misc.c in Sources */, - DC0BCAE31D8B85BC00070CB0 /* SecEncryptTransform.cpp in Sources */, - DC0BCACA1D8B85BC00070CB0 /* Digest.cpp in Sources */, - DC0BCAC11D8B85BC00070CB0 /* SecMaskGenerationFunctionTransform.c in Sources */, - DC0BCAD41D8B85BC00070CB0 /* LinkedList.cpp in Sources */, - DC0BCAC81D8B85BC00070CB0 /* CoreFoundationBasics.cpp in Sources */, - DC0BCAED1D8B85BC00070CB0 /* SingleShotSource.cpp in Sources */, - DC0BCACF1D8B85BC00070CB0 /* CEncryptDecrypt.c in Sources */, - DC0BCAE61D8B85BC00070CB0 /* SecNullTransform.cpp in Sources */, - DC0BCADA1D8B85BC00070CB0 /* NullTransform.cpp in Sources */, - DC0BCACC1D8B85BC00070CB0 /* EncodeDecodeTransforms.c in Sources */, - DC0BCAEA1D8B85BC00070CB0 /* SecTransform.cpp in Sources */, - DC0BCAF31D8B85BC00070CB0 /* Transform.cpp in Sources */, - DC0BCAF51D8B85BC00070CB0 /* TransformFactory.cpp in Sources */, - DC0BCAD11D8B85BC00070CB0 /* EncryptTransformUtilities.cpp in Sources */, - DC0BCAFC1D8B85BC00070CB0 /* SecTransformReadTransform.cpp in Sources */, - DC0BCAD81D8B85BC00070CB0 /* Monitor.cpp in Sources */, - DC0BCADF1D8B85BC00070CB0 /* SecDigestTransform.cpp in Sources */, - DC0BCAC41D8B85BC00070CB0 /* SecCollectTransform.cpp in Sources */, - DC0BCAF71D8B85BC00070CB0 /* Utilities.cpp in Sources */, + DCB342341D8A2C6B0054D16E /* KeySchema.cpp in Sources */, + DCB342351D8A2C6B0054D16E /* Schema.cpp in Sources */, + DCB341F91D8A2BAD0054D16E /* callback.cpp in Sources */, + DCB341F21D8A2BAC0054D16E /* acl_secret.cpp in Sources */, + DCB342281D8A2BAD0054D16E /* osxverifier.cpp in Sources */, + DCB342231D8A2BAD0054D16E /* handletemplates.cpp in Sources */, + DCB3420A1D8A2BAD0054D16E /* cssmdates.cpp in Sources */, + DCB341EA1D8A2BAC0054D16E /* acl_preauth.cpp in Sources */, + DCB342061D8A2BAD0054D16E /* cssmcred.cpp in Sources */, + DCB341E81D8A2BAC0054D16E /* acl_password.cpp in Sources */, + DCB3421A1D8A2BAD0054D16E /* cssmtrust.cpp in Sources */, + DCB342161D8A2BAD0054D16E /* cssmlist.cpp in Sources */, + DCB341DD1D8A2BAC0054D16E /* objectacl.cpp in Sources */, + DCB342011D8A2BAD0054D16E /* cssmalloc.cpp in Sources */, + DCB3420E1D8A2BAD0054D16E /* cssmdbname.cpp in Sources */, + DCB341F01D8A2BAC0054D16E /* acl_protectedpw.cpp in Sources */, + DCB342211D8A2BAD0054D16E /* handleobject.cpp in Sources */, + DCB341EE1D8A2BAC0054D16E /* acl_prompted.cpp in Sources */, + DCB341E41D8A2BAC0054D16E /* acl_codesigning.cpp in Sources */, + DCB342121D8A2BAD0054D16E /* cssmerrors.cpp in Sources */, + DCB3421C1D8A2BAD0054D16E /* cssmwalkers.cpp in Sources */, + DCB341F61D8A2BAD0054D16E /* AuthorizationData.cpp in Sources */, + DCB3421E1D8A2BAD0054D16E /* db++.cpp in Sources */, + DCB3422E1D8A2BAD0054D16E /* walkers.cpp in Sources */, + DCB342181D8A2BAD0054D16E /* cssmpods.cpp in Sources */, + DCB342081D8A2BAD0054D16E /* cssmdata.cpp in Sources */, + DCB341F41D8A2BAC0054D16E /* acl_threshold.cpp in Sources */, + DCB341E11D8A2BAC0054D16E /* cssmacl.cpp in Sources */, + DCB3420C1D8A2BAD0054D16E /* cssmdb.cpp in Sources */, + DCB341DF1D8A2BAC0054D16E /* aclsubject.cpp in Sources */, + DCB342141D8A2BAD0054D16E /* cssmkey.cpp in Sources */, + DCB342101D8A2BAD0054D16E /* cssmendian.cpp in Sources */, + DCB342041D8A2BAD0054D16E /* cssmcert.cpp in Sources */, + DCB341EC1D8A2BAC0054D16E /* acl_process.cpp in Sources */, + DCB341FD1D8A2BAD0054D16E /* context.cpp in Sources */, + DCB341E61D8A2BAC0054D16E /* acl_comment.cpp in Sources */, + DCB341E21D8A2BAC0054D16E /* acl_any.cpp in Sources */, + DCB341FF1D8A2BAD0054D16E /* cssmaclpod.cpp in Sources */, + DCB3422A1D8A2BAD0054D16E /* u32handleobject.cpp in Sources */, + DCB341FB1D8A2BAD0054D16E /* constdata.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BCB031D8B894F00070CB0 /* Sources */ = { + DCB3423C1D8A32820054D16E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCB2B1D8B898100070CB0 /* SecTranslocate.cpp in Sources */, - DC0BCB271D8B898100070CB0 /* SecTranslocateShared.cpp in Sources */, - DC0BCB241D8B898100070CB0 /* SecTranslocateLSNotification.cpp in Sources */, - DC0BCB2C1D8B898100070CB0 /* SecTranslocateUtilities.cpp in Sources */, - DC0BCB221D8B898100070CB0 /* SecTranslocateDANotification.cpp in Sources */, - DC0BCB281D8B898100070CB0 /* SecTranslocateServer.cpp in Sources */, - DC0BCB2E1D8B898100070CB0 /* SecTranslocateInterface.cpp in Sources */, - DC0BCB1D1D8B898100070CB0 /* SecTranslocateClient.cpp in Sources */, - DC0BCB1F1D8B898100070CB0 /* SecTranslocateXPCServer.cpp in Sources */, + DCB3433D1D8A32A20054D16E /* ACL.cpp in Sources */, + DCB3433B1D8A32A20054D16E /* Access.cpp in Sources */, + DCB3436A1D8A32A20054D16E /* CCallbackMgr.cp in Sources */, + DCB3433F1D8A32A20054D16E /* Certificate.cpp in Sources */, + DCB343431D8A32A20054D16E /* CertificateValues.cpp in Sources */, + DCB343701D8A32A20054D16E /* DLDBListCFPref.cpp in Sources */, + DCB343721D8A32A20054D16E /* DynamicDLDBList.cpp in Sources */, + DCB343451D8A32A20054D16E /* ExtendedAttribute.cpp in Sources */, + DCB343471D8A32A20054D16E /* Globals.cpp in Sources */, + DCB343491D8A32A20054D16E /* Identity.cpp in Sources */, + DCB3434B1D8A32A20054D16E /* IdentityCursor.cpp in Sources */, + DCB3434D1D8A32A20054D16E /* Item.cpp in Sources */, + DCB3434F1D8A32A20054D16E /* KCCursor.cpp in Sources */, + DCB343741D8A32A20054D16E /* KCEventNotifier.cpp in Sources */, + DCB343771D8A32A20054D16E /* KCUtilities.cpp in Sources */, + DCB343531D8A32A20054D16E /* KeyItem.cpp in Sources */, + DCB343511D8A32A20054D16E /* Keychains.cpp in Sources */, + DCB343551D8A32A20054D16E /* Password.cpp in Sources */, + DCB343571D8A32A20054D16E /* Policies.cpp in Sources */, + DCB343591D8A32A20054D16E /* PolicyCursor.cpp in Sources */, + DCB3437A1D8A32A20054D16E /* PrimaryKey.cpp in Sources */, + DCB342FA1D8A32A20054D16E /* SecACL.cpp in Sources */, + DCB342F91D8A32A20054D16E /* SecAccess.cpp in Sources */, + DCB342FB1D8A32A20054D16E /* SecBase.cpp in Sources */, + DCB3435B1D8A32A20054D16E /* SecCFTypes.cpp in Sources */, + DCB342FD1D8A32A20054D16E /* SecCertificate.cpp in Sources */, + DCB342FE1D8A32A20054D16E /* SecCertificateBundle.cpp in Sources */, + DCB343921D8A32A20054D16E /* SecExport.cpp in Sources */, + DCB343931D8A32A20054D16E /* SecExternalRep.cpp in Sources */, + DCB343371D8A32A20054D16E /* SecFDERecoveryAsymmetricCrypto.cpp in Sources */, + DCB343001D8A32A20054D16E /* SecIdentity.cpp in Sources */, + DCB343011D8A32A20054D16E /* SecIdentitySearch.cpp in Sources */, + DCB343951D8A32A20054D16E /* SecImport.cpp in Sources */, + DCB343961D8A32A20054D16E /* SecImportExport.c in Sources */, + DCB343971D8A32A20054D16E /* SecImportExportAgg.cpp in Sources */, + DCB343991D8A32A20054D16E /* SecImportExportCrypto.cpp in Sources */, + DCB3439B1D8A32A20054D16E /* SecImportExportOpenSSH.cpp in Sources */, + DCB3439D1D8A32A20054D16E /* SecImportExportPem.cpp in Sources */, + DCB3439F1D8A32A20054D16E /* SecImportExportPkcs8.cpp in Sources */, + DCB343A11D8A32A20054D16E /* SecImportExportUtils.cpp in Sources */, + DCB343031D8A32A20054D16E /* SecItem.cpp in Sources */, + DCB343021D8A32A20054D16E /* SecItemConstants.c in Sources */, + DCB343041D8A32A20054D16E /* SecKey.cpp in Sources */, + DCB343051D8A32A20054D16E /* SecKeychain.cpp in Sources */, + DCB3435D1D8A32A20054D16E /* SecKeychainAddIToolsPassword.cpp in Sources */, + DCB343061D8A32A20054D16E /* SecKeychainItem.cpp in Sources */, + DCB343071D8A32A20054D16E /* SecKeychainItemExtendedAttributes.cpp in Sources */, + DCB343081D8A32A20054D16E /* SecKeychainSearch.cpp in Sources */, + DCB343A31D8A32A20054D16E /* SecNetscapeTemplates.cpp in Sources */, + DCB343091D8A32A20054D16E /* SecPassword.cpp in Sources */, + DCB343A51D8A32A20054D16E /* SecPkcs8Templates.cpp in Sources */, + DCB3430A1D8A32A20054D16E /* SecPolicy.cpp in Sources */, + DCB3430B1D8A32A20054D16E /* SecPolicySearch.cpp in Sources */, + DCB343361D8A32A20054D16E /* SecRandom.c in Sources */, + DCB343391D8A32A20054D16E /* SecRecoveryPassword.c in Sources */, + DCB3430C1D8A32A20054D16E /* SecTrust.cpp in Sources */, + DCB343671D8A32A20054D16E /* SecTrustOSXEntryPoints.cpp in Sources */, + DCB3430E1D8A32A20054D16E /* SecTrustSettings.cpp in Sources */, + DCB3430D1D8A32A20054D16E /* SecTrustedApplication.cpp in Sources */, + DCB343A71D8A32A20054D16E /* SecWrappedKeys.cpp in Sources */, + DCB3435E1D8A32A20054D16E /* StorageManager.cpp in Sources */, + DCB343901D8A32A20054D16E /* TokenLogin.cpp in Sources */, + DCB3435F1D8A32A20054D16E /* Trust.cpp in Sources */, + DCB3437E1D8A32A20054D16E /* TrustAdditions.cpp in Sources */, + DCB343801D8A32A20054D16E /* TrustItem.cpp in Sources */, + DCB343611D8A32A20054D16E /* TrustRevocation.cpp in Sources */, + DCB343641D8A32A20054D16E /* TrustSettings.cpp in Sources */, + DCB343861D8A32A20054D16E /* TrustSettingsUtils.cpp in Sources */, + DCB343821D8A32A20054D16E /* TrustStore.cpp in Sources */, + DCB343621D8A32A20054D16E /* TrustedApplication.cpp in Sources */, + DCB343841D8A32A20054D16E /* UnlockReferralItem.cpp in Sources */, + DCB3436C1D8A32A20054D16E /* cssmdatetime.cpp in Sources */, + DCB3436E1D8A32A20054D16E /* defaultcreds.cpp in Sources */, + DCB3438E1D8A32A20054D16E /* tsaDERUtilities.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BCBDA1D8C648C00070CB0 /* Sources */ = { + DCB343E91D8A34FD0054D16E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCC0D1D8C64B500070CB0 /* test-00-test.c in Sources */, - DC0BCC161D8C64B600070CB0 /* testcert.c in Sources */, - DC0BCC141D8C64B600070CB0 /* testmore.c in Sources */, - DC0BCC121D8C64B600070CB0 /* testenv.m in Sources */, - DC0BCC191D8C64B600070CB0 /* testpolicy.m in Sources */, + 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 */, + DCB344801D8A35270054D16E /* kc-05-find-existing-items-locked.c in Sources */, + DCB3447F1D8A35270054D16E /* kc-05-find-existing-items.c in Sources */, + DCB344811D8A35270054D16E /* kc-06-cert-search-email.m in Sources */, + DCB344841D8A35270054D16E /* kc-10-item-add-certificate.c in Sources */, + DCB344821D8A35270054D16E /* kc-10-item-add-generic.c in Sources */, + DCB344831D8A35270054D16E /* kc-10-item-add-internet.c in Sources */, + DCB344871D8A35270054D16E /* kc-12-item-create-keypair.c in Sources */, + DCB344861D8A35270054D16E /* kc-12-key-create-symmetric-and-use.m in Sources */, + DCB344851D8A35270054D16E /* kc-12-key-create-symmetric.c in Sources */, + DCB344891D8A35270054D16E /* kc-15-item-update-label-skimaad.m in Sources */, + DCB344881D8A35270054D16E /* kc-15-key-update-valueref.c in Sources */, + DCB3448A1D8A35270054D16E /* kc-16-item-update-password.c in Sources */, + DCB3448B1D8A35270054D16E /* kc-18-find-combined.c in Sources */, + DCB3448C1D8A35270054D16E /* kc-19-item-copy-internet.c in Sources */, + DCB344921D8A35270054D16E /* kc-20-identity-find-stress.c in Sources */, + DCB3448E1D8A35270054D16E /* kc-20-identity-key-attributes.c in Sources */, + DCB3448D1D8A35270054D16E /* kc-20-identity-persistent-refs.c in Sources */, + DCB344901D8A35270054D16E /* kc-20-item-add-stress.c in Sources */, + DCB3448F1D8A35270054D16E /* kc-20-item-find-stress.c in Sources */, + DCB344911D8A35270054D16E /* kc-20-key-find-stress.c in Sources */, + DCCBFA1E1DBA95CD001DD54D /* kc-20-item-delete-stress.c in Sources */, + DCB344931D8A35270054D16E /* kc-21-item-use-callback.c in Sources */, + DCB344941D8A35270054D16E /* kc-21-item-xattrs.c in Sources */, + DCB344951D8A35270054D16E /* kc-23-key-export-symmetric.m in Sources */, + DCB344961D8A35270054D16E /* kc-24-key-copy-keychains.c in Sources */, + DCB344971D8A35270054D16E /* kc-26-key-import-public.m in Sources */, + DCB344981D8A35270054D16E /* kc-27-key-non-extractable.c in Sources */, + DCB3449A1D8A35270054D16E /* kc-28-cert-sign.c in Sources */, + 6CA837642210CA8A002770F1 /* kc-45-change-password.c in Sources */, + DCB344991D8A35270054D16E /* kc-28-p12-import.m in Sources */, + DCB3449B1D8A35270054D16E /* kc-30-xara.c in Sources */, + DCB344A01D8A35270054D16E /* kc-40-seckey.m in Sources */, + DCB344A11D8A35270054D16E /* kc-41-sececkey.m in Sources */, + DCB344A31D8A35270054D16E /* kc-42-trust-revocation.c in Sources */, + DCB344A21D8A35270054D16E /* kc-43-seckey-interop.m in Sources */, + DCB344A41D8A35270054D16E /* si-20-sectrust-provisioning.c in Sources */, + DCB344A61D8A35270054D16E /* si-33-keychain-backup.c in Sources */, + DCB344A71D8A35270054D16E /* si-34-one-true-keychain.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BCC221D8C684F00070CB0 /* Sources */ = { + DCBF4A9921FFC82100539F0A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCD8D1D8C6A1E00070CB0 /* debugging.c in Sources */, - DC0BCD961D8C6A1E00070CB0 /* der_dictionary.c in Sources */, - DC0BCD751D8C6A1E00070CB0 /* iCloudKeychainTrace.c in Sources */, - DC0BCD821D8C6A1E00070CB0 /* SecCFWrappers.c in Sources */, - EB4B6E201DC0682A00AFC494 /* SecADWrapper.c in Sources */, - DC0BCD941D8C6A1E00070CB0 /* der_date.c in Sources */, - DC0BCD9F1D8C6A1F00070CB0 /* fileIo.c in Sources */, - DC0BCDA81D8C6A1F00070CB0 /* SecFileLocations.c in Sources */, - DC0BCDA61D8C6A1F00070CB0 /* SecDb.c in Sources */, - EB7AE6F81E86DACC00B80B15 /* SecPLWrappers.m in Sources */, - DC0BCD7B1D8C6A1E00070CB0 /* SecCoreCrypto.c in Sources */, - DC0BCDAF1D8C6A1F00070CB0 /* SecAppleAnchor.c in Sources */, - DC0BCDA41D8C6A1F00070CB0 /* iOSforOSX-SecAttr.c in Sources */, - DC0BCD881D8C6A1E00070CB0 /* SecTrace.c in Sources */, - DC0BCD9A1D8C6A1F00070CB0 /* der_plist_internal.c in Sources */, - DC0BCDAE1D8C6A1F00070CB0 /* SecSCTUtils.c in Sources */, - DC0BCD971D8C6A1E00070CB0 /* der_number.c in Sources */, - DC0BCDA51D8C6A1F00070CB0 /* iOSforOSX-SecRandom.c in Sources */, - DC0BCD841D8C6A1E00070CB0 /* SecCFError.c in Sources */, - DC0BCD981D8C6A1F00070CB0 /* der_plist.c in Sources */, - DC0BCD771D8C6A1E00070CB0 /* SecAKSWrappers.c in Sources */, - 72CDF5191EC679A8002D233B /* sec_action.c in Sources */, - DC0BCD901D8C6A1E00070CB0 /* der_array.c in Sources */, - DC0BCD7F1D8C6A1E00070CB0 /* SecCFCCWrappers.c in Sources */, - E7C787351DD0FEF90087FC34 /* NSURL+SOSPlistStore.m in Sources */, - DC0BCD9E1D8C6A1F00070CB0 /* der_string.c in Sources */, - DC0BCD911D8C6A1E00070CB0 /* der_boolean.c in Sources */, - DC0BCD931D8C6A1E00070CB0 /* der_data.c in Sources */, - E78CCDC71E737F6700C1CFAA /* SecNSAdditions.m in Sources */, - DC0BCD921D8C6A1E00070CB0 /* der_null.c in Sources */, - DC0BCD9C1D8C6A1F00070CB0 /* der_set.c in Sources */, - DC0BCDAC1D8C6A1F00070CB0 /* simulate_crash.c in Sources */, - DC0BCD791D8C6A1E00070CB0 /* SecBuffer.c in Sources */, - DC0BCDAB1D8C6A1F00070CB0 /* SecXPCError.c in Sources */, - DC0BCDB51D8C6A5B00070CB0 /* not_on_this_platorm.c in Sources */, - DC65E7C01D8CBB1500152EF0 /* readline.c in Sources */, - DA5B871D2065A8440093F083 /* SecAutorelease.m in Sources */, + DCBF4AE521FFC9B300539F0A /* SecEscrowRequestTests.m in Sources */, + DCBF4A9A21FFC82100539F0A /* SecdWatchdog.m in Sources */, + DCBF4AAE21FFC82100539F0A /* SecTask.c in Sources */, + DCBF4AB521FFC82100539F0A /* server_xpc.m in Sources */, + DCBF4AB621FFC82100539F0A /* server_security_helpers.m in Sources */, + DCBF4AB721FFC82100539F0A /* server_endpoint.m in Sources */, + DCBF4ABA21FFC82100539F0A /* spi.c in Sources */, + DCA9D84821FFEE9800B27421 /* EscrowRequestXPCProtocol.m in Sources */, + DCAB17CE21FFF75B00E1DFCF /* MockSynchronousEscrowServer.m in Sources */, + DCBF4ABB21FFC82100539F0A /* SecFramework.c in Sources */, + DCBF4ABE21FFC82100539F0A /* server_entitlement_helpers.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC0BCCF51D8C694700070CB0 /* Sources */ = { + DCC78EA51D8088E200865A7C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC0BCD6C1D8C69A000070CB0 /* su-12-cfboolean-der.c in Sources */, - DC0BCD701D8C69A000070CB0 /* su-17-cfset-der.c in Sources */, - DC0BCD731D8C69A000070CB0 /* su-41-secdb-stress.c in Sources */, - DC0BCD6A1D8C69A000070CB0 /* su-10-cfstring-der.c in Sources */, - DC0BCD6D1D8C69A000070CB0 /* su-13-cfnumber-der.c in Sources */, - DC0BCD6E1D8C69A000070CB0 /* su-14-cfarray-der.c in Sources */, - DC0BCD721D8C69A000070CB0 /* su-40-secdb.c in Sources */, - DC0BCD6B1D8C69A000070CB0 /* su-11-cfdata-der.c in Sources */, - DC0BCD691D8C69A000070CB0 /* su-08-secbuffer.c in Sources */, - DC0BCD6F1D8C69A000070CB0 /* su-15-cfdictionary-der.c in Sources */, - DC0BCD671D8C69A000070CB0 /* su-05-cfwrappers.c in Sources */, - DC0BCD711D8C69A000070CB0 /* su-16-cfdate-der.c in Sources */, - DC0BCD681D8C69A000070CB0 /* su-07-debugging.c in Sources */, + 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */, + DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */, + DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */, + DCC78EE61D808B2A00865A7C /* SecAccessControl.m in Sources */, + DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */, + DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */, + DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */, + BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, + DCC78EE21D808B0E00865A7C /* SecCTKKey.m in Sources */, + DCC78EE11D808B0900865A7C /* SecCertificate.c in Sources */, + DC4269041E82EDAC002B7110 /* SecItem.m in Sources */, + DCC78EDF1D808AF800865A7C /* SecCertificateRequest.c in Sources */, + DCC78EDE1D808AF100865A7C /* SecDH.c in Sources */, + DCC78EDD1D808AEC00865A7C /* SecDigest.c in Sources */, + DCC78EDC1D808AE500865A7C /* SecECKey.m in Sources */, + DCC78EDB1D808ADF00865A7C /* SecEMCS.m 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.m 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 */, + DCC78ECF1D808A8200865A7C /* SecOTRPacketData.c in Sources */, + DCC78ECE1D808A7B00865A7C /* SecOTRPackets.c in Sources */, + DCC78ECD1D808A7300865A7C /* SecOTRPublicIdentity.c in Sources */, + 4780146A1FBF5BD600C4043D /* SecKeyProxy.m in Sources */, + DCC78ECC1D808A6B00865A7C /* SecOTRSession.c in Sources */, + DCC78ECB1D808A6600865A7C /* SecOTRSessionAKE.c in Sources */, + DCC78ECA1D808A6000865A7C /* SecOTRUtils.c in Sources */, + DCC78EC91D808A5700865A7C /* SecPBKDF.c in Sources */, + DCC78EC81D808A5200865A7C /* SecPasswordGenerate.c in Sources */, + DCC78EC71D808A4D00865A7C /* SecPolicy.c in Sources */, + DCC78EC61D808A4700865A7C /* SecPolicyLeafCallbacks.c in Sources */, + DCC78EC51D808A4100865A7C /* SecRSAKey.c in Sources */, + DCC78EC41D808A3B00865A7C /* SecSCEP.c in Sources */, + DCC78EC31D808A2E00865A7C /* SecServerEncryptionSupport.c in Sources */, + DCC78EC21D808A2800865A7C /* SecSharedCredential.c in Sources */, + DCC78EC11D808A2200865A7C /* SecSignatureVerificationSupport.c in Sources */, + DCC78EC01D808A1C00865A7C /* SecTrust.c in Sources */, + DCC78EBE1D808A0E00865A7C /* SecTrustStore.c in Sources */, + DCC78EBD1D808A0400865A7C /* SecuritydXPC.c in Sources */, + 3D680BE42241BC0000C04821 /* SecExperiment.m in Sources */, + DCC78EBB1D8089C200865A7C /* p12import.c in Sources */, + D425EC1D1DD3C3CF00DE5DEC /* SecInternalRelease.c in Sources */, + DCC78EBA1D8089BD00865A7C /* p12pbegen.c in Sources */, + DCC78EB91D8089A700865A7C /* pbkdf2.c in Sources */, + DCC78EB81D80899C00865A7C /* vmdh.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC1788FF1D77980500B50D50 /* Sources */ = { + DCD0677A1D8CDF19007602F1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; 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 /* 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 */, - 6CE3654D1FA100E50012F6AB /* SFAnalytics.m in Sources */, - 6CAA8CFD1F83E7EB007B6E03 /* SFObjCType.m in Sources */, - DC1789A21D779DF400B50D50 /* SecBreadcrumb.c in Sources */, - 6CBF65411FA1481100A68667 /* SFAnalyticsActivityTracker.m in Sources */, + DCD069281D8CDFFF007602F1 /* ANTLRUtil.cpp in Sources */, + DCD069291D8CDFFF007602F1 /* ASTFactory.cpp in Sources */, + DCD0692A1D8CDFFF007602F1 /* ASTNULLType.cpp in Sources */, + DCD0692B1D8CDFFF007602F1 /* ASTRefCount.cpp in Sources */, + DCD0692C1D8CDFFF007602F1 /* BaseAST.cpp in Sources */, + DCD0692D1D8CDFFF007602F1 /* BitSet.cpp in Sources */, + DCD0692E1D8CDFFF007602F1 /* CharBuffer.cpp in Sources */, + DCD0692F1D8CDFFF007602F1 /* CharScanner.cpp in Sources */, + DCD0682A1D8CDF7E007602F1 /* Code.cpp in Sources */, + DCD068301D8CDF7E007602F1 /* CodeSigner.cpp in Sources */, + DCD069301D8CDFFF007602F1 /* CommonAST.cpp in Sources */, + DCD069311D8CDFFF007602F1 /* CommonASTWithHiddenTokens.cpp in Sources */, + DCD069321D8CDFFF007602F1 /* CommonHiddenStreamToken.cpp in Sources */, + DCD069331D8CDFFF007602F1 /* CommonToken.cpp in Sources */, + DCD069351D8CDFFF007602F1 /* InputBuffer.cpp in Sources */, + DCD069361D8CDFFF007602F1 /* LLkParser.cpp in Sources */, + DCD069371D8CDFFF007602F1 /* MismatchedCharException.cpp in Sources */, + DCD069381D8CDFFF007602F1 /* MismatchedTokenException.cpp in Sources */, + DCD069391D8CDFFF007602F1 /* NoViableAltException.cpp in Sources */, + DCD0693A1D8CDFFF007602F1 /* NoViableAltForCharException.cpp in Sources */, + DCD0693B1D8CDFFF007602F1 /* Parser.cpp in Sources */, + DCD0693C1D8CDFFF007602F1 /* RecognitionException.cpp in Sources */, + DCD0683A1D8CDF7E007602F1 /* RequirementLexer.cpp in Sources */, + DCD0683C1D8CDF7E007602F1 /* RequirementParser.cpp in Sources */, + DCD0682E1D8CDF7E007602F1 /* Requirements.cpp in Sources */, + DCD068841D8CDF7E007602F1 /* SecAssessment.cpp in Sources */, + DCD0681A1D8CDF7E007602F1 /* SecCode.cpp in Sources */, + DCD068241D8CDF7E007602F1 /* SecCodeHost.cpp in Sources */, + DCD068221D8CDF7E007602F1 /* SecCodeSigner.cpp in Sources */, + DCD068201D8CDF7E007602F1 /* SecRequirement.cpp in Sources */, + DCD0681D1D8CDF7E007602F1 /* SecStaticCode.cpp in Sources */, + 1F631C5622387FFE005920D8 /* legacydevid.cpp in Sources */, + DCD0682C1D8CDF7E007602F1 /* StaticCode.cpp in Sources */, + DCD0693D1D8CDFFF007602F1 /* String.cpp in Sources */, + DCD0693E1D8CDFFF007602F1 /* Token.cpp in Sources */, + DCD0693F1D8CDFFF007602F1 /* TokenBuffer.cpp in Sources */, + DCD069401D8CDFFF007602F1 /* TokenRefCount.cpp in Sources */, + DCD069411D8CDFFF007602F1 /* TokenStreamBasicFilter.cpp in Sources */, + DCD069421D8CDFFF007602F1 /* TokenStreamHiddenTokenFilter.cpp in Sources */, + DCD069431D8CDFFF007602F1 /* TokenStreamRewriteEngine.cpp in Sources */, + DCD069441D8CDFFF007602F1 /* TokenStreamSelector.cpp in Sources */, + DCD069451D8CDFFF007602F1 /* TreeParser.cpp in Sources */, + DCD0687F1D8CDF7E007602F1 /* antlrplugin.cpp in Sources */, + 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 */, + DCD0684E1D8CDF7E007602F1 /* cskernel.cpp in Sources */, + DCD068501D8CDF7E007602F1 /* csprocess.cpp in Sources */, + DCD068771D8CDF7E007602F1 /* csutilities.cpp in Sources */, + DCD068641D8CDF7E007602F1 /* detachedrep.cpp in Sources */, + DCD0687D1D8CDF7E007602F1 /* dirscanner.cpp in Sources */, + DCD068601D8CDF7E007602F1 /* diskimagerep.cpp in Sources */, + DCD068541D8CDF7E007602F1 /* diskrep.cpp in Sources */, + DCD0684C1D8CDF7E007602F1 /* drmaker.cpp in Sources */, + DCD068861D8CDF7E007602F1 /* evaluationmanager.cpp in Sources */, + DCD068561D8CDF7E007602F1 /* filediskrep.cpp in Sources */, + DCD0685A1D8CDF7E007602F1 /* kerneldiskrep.cpp in Sources */, + DCD0685C1D8CDF7E007602F1 /* machorep.cpp in Sources */, + DCD068881D8CDF7E007602F1 /* opaquewhitelist.cpp in Sources */, + DC5BD5841E8C6FD100C5EC49 /* SecTask.c in Sources */, + DCD068661D8CDF7E007602F1 /* piddiskrep.cpp in Sources */, + DCD0688A1D8CDF7E007602F1 /* policydb.cpp in Sources */, + DCD0688C1D8CDF7E007602F1 /* policyengine.cpp in Sources */, + DCD0687B1D8CDF7E007602F1 /* quarantine++.cpp in Sources */, + DCD0684A1D8CDF7E007602F1 /* reqdumper.cpp in Sources */, + DCD068461D8CDF7E007602F1 /* reqinterp.cpp in Sources */, + DCD068421D8CDF7E007602F1 /* reqmaker.cpp in Sources */, + DCD068481D8CDF7E007602F1 /* reqparser.cpp in Sources */, + DCD068441D8CDF7E007602F1 /* reqreader.cpp in Sources */, + DCD068401D8CDF7E007602F1 /* requirement.cpp in Sources */, + DCD068731D8CDF7E007602F1 /* resources.cpp in Sources */, + DCD068751D8CDF7E007602F1 /* sigblob.cpp in Sources */, + DCD068321D8CDF7E007602F1 /* signer.cpp in Sources */, + DCD068341D8CDF7E007602F1 /* signerutils.cpp in Sources */, + DCD068621D8CDF7E007602F1 /* singlediskrep.cpp in Sources */, + DCD0685E1D8CDF7E007602F1 /* slcrep.cpp in Sources */, + DCD068791D8CDF7E007602F1 /* xar++.cpp in Sources */, + DCD0688E1D8CDF7E007602F1 /* xpcengine.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC222C381E034D1F00B09171 /* Sources */ = { + DCD069E91D8CE21C007602F1 /* Sources */ = { 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 */, - BE3405AF1FD725F000933DAC /* OTBottleContents.proto in Sources */, - DC9FD3231F8587A500C8AAC8 /* CKKSSerializedKey.proto in Sources */, - DC222C3A1E034D1F00B09171 /* CKKSItemEncrypter.m in Sources */, - DC7A17F01E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */, - DCEA5D581E2826DB0089CF55 /* CKKSSIV.m in Sources */, - EBB407B41EBA46B300A541A5 /* CKKSPowerCollection.m in Sources */, - DCB5D93E1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m in Sources */, - 0CD9E8011FE05B6600F66C38 /* OTContextRecord.m in Sources */, - BEB0B0DE1FFC45D8007E6A83 /* OTPrivateKey+SF.m in Sources */, - DC222C3B1E034D1F00B09171 /* SOSChangeTracker.c in Sources */, - DC222C3D1E034D1F00B09171 /* SOSEngine.c in Sources */, - DC222C401E034D1F00B09171 /* SecDbItem.c in Sources */, - DCCD88EB1E42622200F5AA71 /* CKKSGroupOperation.m in Sources */, - DC222C411E034D1F00B09171 /* SecDbKeychainItem.m in Sources */, - 0C8BBEAA1FC9DBC000580909 /* OTLocalStore.m in Sources */, - 4733377C1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */, - 0CE1BCCF1FCE11690017230E /* OTBottledPeerSigned.m in Sources */, - DC222C421E034D1F00B09171 /* SecDbQuery.c in Sources */, - 6C3446471E25346C00F9522B /* CKKSRateLimiter.m in Sources */, - DCA4D2001E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */, - DCFB12C81E95A4C000510F5F /* CKKSCKAccountStateTracker.m in Sources */, - DC222C431E034D1F00B09171 /* SecItemBackupServer.c in Sources */, - DCE278E01ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */, - DC222C441E034D1F00B09171 /* SecItemDataSource.c in Sources */, - DC3D748F1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */, - 0C8BBF161FCB4B1C00580909 /* OTManager.m in Sources */, - 0C8BBEA61FC9DBB200580909 /* OTEscrowKeys.m in Sources */, - 526965D31E6E284500627F9D /* AsymKeybagBackup.m in Sources */, - DA6AA1661FE88AFB004565B0 /* CKKSControlServer.m in Sources */, - DCFE1C541F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */, - 47922D491FAA7C3D0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */, - DCD6C4B51EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */, - 6C588D811EAA20AC00D7E322 /* RateLimiter.m in Sources */, - DC94BCCD1F10448600E07CEB /* CloudKitCategories.m in Sources */, - DC5BB4FB1E0C90DF0010F836 /* CKKSIncomingQueueOperation.m in Sources */, - DC222C451E034D1F00B09171 /* CKKSIncomingQueueEntry.m in Sources */, - DC15F7691E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m in Sources */, - DC222C461E034D1F00B09171 /* SecItemDb.c in Sources */, - DC222C471E034D1F00B09171 /* SecItemSchema.c in Sources */, - DC9FD32D1F85990B00C8AAC8 /* CKKSPeer.m in Sources */, - DCEA5D881E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */, - DC2C5F611F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */, - DC222C481E034D1F00B09171 /* SecItemServer.c in Sources */, - DC18F7721E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */, - DC222C491E034D1F00B09171 /* SecKeybagSupport.c in Sources */, - 471A03F21F72E35C000A8904 /* SecDbKeychainItemV7.m in Sources */, - 0C8BBF181FCB4E5000580909 /* OTControlProtocol.m in Sources */, - EB4E0CDC1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */, - DC1DA6691E4555D80094CE7F /* CKKSScanLocalItemsOperation.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 */, - DC124DCE20059BA900BE8DAC /* OctagonControlServer.m in Sources */, - DC222C4D1E034D1F00B09171 /* CKKSOutgoingQueueEntry.m in Sources */, - DCBF2F881F913EF000ED0CA4 /* CKKSHealTLKSharesOperation.m in Sources */, - EB10A3E720356E6500E84270 /* OTConstants.m in Sources */, - 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 */, - D491112E209515400066A1E4 /* CKKSAnalytics.m in Sources */, - DC1447991F5766D200236DB4 /* NSOperationCategories.m in Sources */, - DC222C511E034D1F00B09171 /* CKKSItem.m in Sources */, - DCBDB3BE1E57CA7A00B61300 /* CKKSViewManager.m in Sources */, - DCFE1C2A1F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */, - 0C8BBEA81FC9DBB600580909 /* OTIdentity.m in Sources */, - DCAD9B471F8D939C00C5E2AE /* CKKSFixups.m in Sources */, - DCA4D2181E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, - DCE278EB1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, - DC222C541E034D1F00B09171 /* CKKSSQLDatabaseObject.m in Sources */, - DCEA5D981E3015840089CF55 /* CKKSZone.m in Sources */, - 0CE407AD1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */, - DCB837381ED5045100015C07 /* CKKSLockStateTracker.m in Sources */, - 47922D4D1FAA7C4B0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */, - DC4DB1531E24692100CD6769 /* CKKSKey.m in Sources */, - DC9082C51EA0277700D0C1C5 /* CKKSZoneChangeFetcher.m in Sources */, - 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 */, - DCBDB3B81E57C82300B61300 /* CKKSKeychainView.m in Sources */, - DC222C5A1E034D1F00B09171 /* iCloudTrace.c in Sources */, - DC5BB5011E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */, - 0C8BBEA01FC9DBA400580909 /* OTBottledPeer.m in Sources */, - 6C869A761F50CAF500957298 /* SOSEnsureBackup.m in Sources */, - BE2AD2BB1FDA080900739F96 /* OTBottledPeerRecord.m in Sources */, - 0C770EC51FCF7E2000B5F0E2 /* OTCloudStore.m in Sources */, - 5269658E1E6A154800627F9D /* SecBackupKeybagEntry.m in Sources */, - 0C36B3222007F2570029F7A2 /* OTPreflightInfo.m in Sources */, - DC222C5D1E034D1F00B09171 /* CKKSMirrorEntry.m in Sources */, - BEE4B1951FFD604B00777D39 /* OTAuthenticatedCiphertext+SF.m in Sources */, - DC54DD101EA7D9E800108E92 /* CKKSManifestLeafRecord.m in Sources */, - DCFE1C371F17ECE5007640C8 /* CKKSCondition.m in Sources */, - DC222C611E034D1F00B09171 /* swcagent_client.c in Sources */, - BEE4B19B1FFDAFE600777D39 /* SFECPublicKey+SPKI.m in Sources */, - DC222C621E034D1F00B09171 /* CKKSZoneStateEntry.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC3502B11E0208BE00BC0587 /* Sources */ = { + DCD06A4B1D8CE281007602F1 /* Sources */ = { 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 */, - DCD6C4B71EC5319600414FEE /* CKKSNearFutureSchedulerTests.m in Sources */, - DC08D1C41E64FA8C006237DA /* CloudKitKeychainSyncingMockXCTest.m in Sources */, - 47E553741EDF674700749715 /* CKKSManifestTests.m in Sources */, - 6C588D7F1EAA14AA00D7E322 /* RateLimiterTests.m in Sources */, - DC4DB15F1E2590B100CD6769 /* CKKSAESSIVEncryptionTests.m in Sources */, - DC3502E71E0214C800BC0587 /* MockCloudKit.m in Sources */, - 6CAA8D151F83ECD9007B6E03 /* SFAnalytics.m in Sources */, - DC6593D11ED8DAB900C19462 /* CKKSTests+CurrentPointerAPI.m in Sources */, - 6CBF65451FA2257500A68667 /* SFAnalyticsActivityTracker.m in Sources */, - DCA85B9A1E8D981100BA7241 /* client_endpoint.m in Sources */, - DCAD9B491F8D95F200C5E2AE /* CloudKitKeychainSyncingFixupTests.m in Sources */, - 0CA4EBF3202B8D9C002B1D96 /* CloudKitKeychainSyncingTestsBase.m in Sources */, - DC9A2C5F1EB3F557008FAC27 /* CKKSTests+Coalesce.m in Sources */, - DC222C8A1E089BAE00B09171 /* CKKSSQLTests.m in Sources */, - DC15F79C1E68EAD5003B9A40 /* CKKSTests+API.m in Sources */, - 4723C9D41F1531A30082882F /* CKKSLoggerTests.m in Sources */, - 6C73F48C2006B83D003D5D63 /* SOSAnalytics.m in Sources */, - DCBF2F7D1F90084D00ED0CA4 /* CKKSTLKSharingTests.m in Sources */, - DCFABF8E20081E2F001128B5 /* CKKSDeviceStateUploadTests.m in Sources */, - DC3502B81E0208BE00BC0587 /* CKKSTests.m in Sources */, - 6C3446301E24F6BE00F9522B /* CKKSRateLimiterTests.m in Sources */, - DCA85B961E8D980100BA7241 /* client.c in Sources */, - 6CAA8CFA1F83E7AC007B6E03 /* SFAnalyticsSQLiteStore.m in Sources */, - DCE7F2091F21726500DDB0F7 /* CKKSAPSReceiverTests.m in Sources */, - DC96053F1ECA2D6400AF9BDA /* SecTask.c in Sources */, - DC08D1CC1E64FCC5006237DA /* CKKSSOSTests.m in Sources */, - 6CDB5FF71FA78D2100410924 /* SFAnalyticsMultiSampler.m in Sources */, - 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 */, - DC5F35AC1EE0F27900900966 /* server_entitlement_helpers.c in Sources */, - DAEE055C1FAD3FC700DF27F3 /* AutoreleaseTest.c in Sources */, - DA19DAEF1FCFA420008E82EE /* CKKSControl.m in Sources */, - DA19DAF01FCFA425008E82EE /* CKKSControlProtocol.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC3A4B541D91E9FB00E46D4A /* Sources */ = { + DCD06A5F1D8CE2D5007602F1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC3A4B641D91EADC00E46D4A /* main.cpp in Sources */, + DCD06A751D8CE2F0007602F1 /* gkunpack.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52E7741D80BC8000B0A59C /* Sources */ = { + DCD06AAB1D8E0D53007602F1 /* Sources */ = { 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 */, - BE3405AD1FD725A700933DAC /* OTBottleContents.proto in Sources */, - DC9FD3361F86A34F00C8AAC8 /* CKKSSerializedKey.proto in Sources */, - 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 */, - BEB0B0DD1FFC45D7007E6A83 /* OTPrivateKey+SF.m in Sources */, - DC54DD0F1EA7D9E700108E92 /* CKKSManifestLeafRecord.m in Sources */, - DCDCCB901DF7B8D4006E840E /* CKKSItem.m in Sources */, - DC1ED8C11DD5197E002BDCFA /* CKKSItemEncrypter.m in Sources */, - DC6D2C921DD2835A00BE372D /* CKKSOutgoingQueueEntry.m in Sources */, - DC378B3D1DF0CA7200A3DAFA /* CKKSIncomingQueueEntry.m in Sources */, - 0C8BBEA91FC9DBBF00580909 /* OTLocalStore.m in Sources */, - 4733377B1FDAFBCC00E19F30 /* SFKeychainControlManager.m in Sources */, - 0CE1BCCE1FCE11680017230E /* OTBottledPeerSigned.m in Sources */, - DC5BB4FA1E0C90DE0010F836 /* CKKSIncomingQueueOperation.m in Sources */, - DC5BB5001E0C98320010F836 /* CKKSOutgoingQueueOperation.m in Sources */, - DC378B391DEFADB500A3DAFA /* CKKSZoneStateEntry.m in Sources */, - 526965D21E6E284400627F9D /* AsymKeybagBackup.m in Sources */, - 6C588D801EAA20AB00D7E322 /* RateLimiter.m in Sources */, - DC15F7681E67A6F6003B9A40 /* CKKSHealKeyHierarchyOperation.m in Sources */, - DCE278DF1ED789EF0083B485 /* CKKSCurrentItemPointer.m in Sources */, - DC3D748E1FD2217900AC57DA /* CKKSLocalSynchronizeOperation.m in Sources */, - 0C8BBF151FCB4B1B00580909 /* OTManager.m in Sources */, - 0C8BBEA51FC9DBB100580909 /* OTEscrowKeys.m in Sources */, - DCA4D1FF1E552DD50056214F /* CKKSCurrentKeyPointer.m in Sources */, - DA6AA1651FE88AFB004565B0 /* CKKSControlServer.m in Sources */, - DCFE1C531F1825F7007640C8 /* CKKSUpdateDeviceStateOperation.m in Sources */, - 47922D481FAA7C3C0008F7E0 /* SecDbKeychainSerializedMetadata.m in Sources */, - DCD6C4B41EC5302500414FEE /* CKKSNearFutureScheduler.m in Sources */, - DC378B2F1DEF9E0E00A3DAFA /* CKKSMirrorEntry.m in Sources */, - DC94BCCC1F10448600E07CEB /* CloudKitCategories.m in Sources */, - DC9FD32C1F85990A00C8AAC8 /* CKKSPeer.m in Sources */, - DC1ED8C61DD55476002BDCFA /* CKKS.m in Sources */, - DCB5D93D1E4A9A3400BE22AB /* CKKSSynchronizeOperation.m in Sources */, - DC762AA01E57A86A00B03A2C /* CKKSRecordHolder.m in Sources */, - DC52E7DF1D80BD8700B0A59C /* SOSChangeTracker.c in Sources */, - DC1DA6681E4555D80094CE7F /* CKKSScanLocalItemsOperation.m in Sources */, - DC18F7711E43E116006B8B43 /* CKKSFetchAllRecordZoneChangesOperation.m in Sources */, - DC2C5F601F0EB97E00FEBDA7 /* CKKSNotifier.m in Sources */, - DC52E7CF1D80BCFD00B0A59C /* SOSEngine.c in Sources */, - DC4DB1521E24692100CD6769 /* CKKSKey.m in Sources */, - DCBDB3BD1E57CA7A00B61300 /* CKKSViewManager.m in Sources */, - 471A03EC1F72E35B000A8904 /* SecDbKeychainItemV7.m in Sources */, - 0C8BBF171FCB4E5000580909 /* OTControlProtocol.m in Sources */, - EB4E0CDB1FF36A9700CDCACC /* CKKSReachabilityTracker.m in Sources */, - DC52E7C41D80BCAD00B0A59C /* SecDbItem.c in Sources */, - DC52E7D31D80BD1800B0A59C /* SecDbKeychainItem.m in Sources */, - DC52E7CC1D80BCDF00B0A59C /* SecDbQuery.c in Sources */, - DC14478C1F5764C600236DB4 /* CKKSResultOperation.m in Sources */, - 479DA1721EBBA8D10065C98F /* CKKSManifest.m in Sources */, - DC52E7CB1D80BCD800B0A59C /* SecItemBackupServer.c in Sources */, - DC52E7CD1D80BCE700B0A59C /* SecItemDataSource.c in Sources */, - DC124DCD20059BA900BE8DAC /* OctagonControlServer.m in Sources */, - DC52E7DE1D80BD7F00B0A59C /* SecItemDb.c in Sources */, - DC52E7E01D80BD8D00B0A59C /* SecItemSchema.c in Sources */, - EB10A3E820356E6500E84270 /* OTConstants.m in Sources */, - 0C5CFB382019610000913B9C /* OTRamping.m in Sources */, - DC52E7D71D80BD2D00B0A59C /* SecItemServer.c in Sources */, - 47922D441FAA7C2C0008F7E0 /* SecDbKeychainSerializedAKSWrappedKey.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 */, - DC52E7E11D80BD9300B0A59C /* SecLogSettingsServer.m in Sources */, - DCFE1C291F17E455007640C8 /* CKKSDeviceStateEntry.m in Sources */, - DCAD9B461F8D939C00C5E2AE /* CKKSFixups.m in Sources */, - 0C8BBEA71FC9DBB500580909 /* OTIdentity.m in Sources */, - DC52E7DC1D80BD4F00B0A59C /* SecOTRRemote.m in Sources */, - DCE278EA1ED7A5B40083B485 /* CKKSUpdateCurrentItemPointerOperation.m in Sources */, - DCD662F71E329B6800188186 /* CKKSNewTLKOperation.m in Sources */, - DCB837321ED5045000015C07 /* CKKSLockStateTracker.m in Sources */, - 0CE407AC1FD4769B00F59B31 /* OTCloudStoreState.m in Sources */, - 47922D4C1FAA7C4A0008F7E0 /* SecDbKeychainSerializedSecretData.m in Sources */, - DCBDB3B71E57C82300B61300 /* CKKSKeychainView.m in Sources */, - DC52E7D61D80BD2800B0A59C /* SecuritydXPC.c in Sources */, - 47922D561FAA7E0D0008F7E0 /* SecDbKeychainSerializedItemV7.m in Sources */, - 0CCCC7C920261D310024405E /* OT.m in Sources */, - DC7A17EF1E36ABC200EF14CE /* CKKSProcessReceivedKeysOperation.m in Sources */, - DC7341F51F8447AB00AB9BDF /* CKKSTLKShare.m in Sources */, - 0C5960811FB369C50095BA29 /* CKKSHealTLKSharesOperation.m in Sources */, - DCA4D2171E5684220056214F /* CKKSReencryptOutgoingItemsOperation.m in Sources */, - 5269658D1E6A154700627F9D /* SecBackupKeybagEntry.m in Sources */, - DC52E7D41D80BD1D00B0A59C /* iCloudTrace.c in Sources */, - DCEA5D871E2F14810089CF55 /* CKKSAPSReceiver.m in Sources */, - 0C8BBE9F1FC9DBA400580909 /* OTBottledPeer.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 */, - 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 */, + DA2C402E2189302F005F1CC3 /* mach_notify.defs in Sources */, + DCD06B9C1D8E0D7D007602F1 /* cfmach++.cpp in Sources */, + DCD06B5D1D8E0D7D007602F1 /* hashing.cpp in Sources */, + DCD06B8E1D8E0D7D007602F1 /* pcsc++.cpp in Sources */, + DCD06B4B1D8E0D7D007602F1 /* ccaudit.cpp in Sources */, + DCD06BAB1D8E0D7D007602F1 /* cfmunge.cpp in Sources */, + DCD06B6B1D8E0D7D007602F1 /* seccfobject.cpp in Sources */, + DCD06B741D8E0D7D007602F1 /* superblob.cpp in Sources */, + DCD06BA01D8E0D7D007602F1 /* dyldcache.cpp in Sources */, + DCD06B6E1D8E0D7D007602F1 /* simpleprefs.cpp in Sources */, + DCD06B621D8E0D7D007602F1 /* logging.cpp in Sources */, + DCD06B771D8E0D7D007602F1 /* threading.cpp in Sources */, + DCD06B7B1D8E0D7D007602F1 /* tqueue.cpp in Sources */, + DCD06B791D8E0D7D007602F1 /* timeflow.cpp in Sources */, + DCD06B7D1D8E0D7D007602F1 /* trackingallocator.cpp in Sources */, + DCD06B831D8E0D7D007602F1 /* utilities.cpp in Sources */, + DCD06BA31D8E0D7D007602F1 /* machserver.cpp in Sources */, + DCD06BAD1D8E0D7D007602F1 /* cfutilities.cpp in Sources */, + DCD06B431D8E0D7D007602F1 /* crc.c in Sources */, + DCD06B701D8E0D7D007602F1 /* sqlite++.cpp in Sources */, + DCD06B541D8E0D7D007602F1 /* dispatch.cpp in Sources */, + DCD06B3E1D8E0D7D007602F1 /* FileLockTransaction.cpp in Sources */, + DCD06B4A1D8E0D7D007602F1 /* blob.cpp in Sources */, + DCD06B591D8E0D7D007602F1 /* errors.cpp in Sources */, + DCD06B571D8E0D7D007602F1 /* endian.cpp in Sources */, + DCD06B7E1D8E0D7D007602F1 /* transactions.cpp in Sources */, + DCD06B921D8E0D7D007602F1 /* unix++.cpp in Sources */, + DCD06BA71D8E0D7D007602F1 /* coderepository.cpp in Sources */, + DCD06B481D8E0D7D007602F1 /* alloc.cpp in Sources */, + DCD06B8C1D8E0D7D007602F1 /* muscle++.cpp in Sources */, + DCD06B461D8E0D7D007602F1 /* adornments.cpp in Sources */, + DCD06B511D8E0D7D007602F1 /* debugging_internal.cpp in Sources */, + DCD06BA91D8E0D7D007602F1 /* cfclass.cpp in Sources */, + DCD06B981D8E0D7D007602F1 /* mach++.cpp in Sources */, + DCD06B941D8E0D7D007602F1 /* unixchild.cpp in Sources */, + DCD06B401D8E0D7D007602F1 /* CSPDLTransaction.cpp in Sources */, + DCD06B9E1D8E0D7D007602F1 /* macho++.cpp in Sources */, + DCD06B661D8E0D7D007602F1 /* osxcode.cpp in Sources */, + DCD06B5B1D8E0D7D007602F1 /* globalizer.cpp in Sources */, + DCD06B681D8E0D7D007602F1 /* powerwatch.cpp in Sources */, + DCD06B4E1D8E0D7D007602F1 /* daemon.cpp in Sources */, + DCD06B8A1D8E0D7D007602F1 /* kq++.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52E8BF1D80C25800B0A59C /* Sources */ = { + DCD66D5F1D8204A700DB1393 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 48E617211DBEC6BA0098EAAD /* SOSBackupInformation.m in Sources */, - DC52E8F11D80C34000B0A59C /* SOSAccount.m in Sources */, - DC52E8F31D80C34000B0A59C /* SOSAccountBackup.m in Sources */, - DCB332591F478C3C00178C30 /* SOSUserKeygen.m in Sources */, - DC52E8F41D80C34000B0A59C /* SOSAccountCircles.m in Sources */, - 0CD8CB0B1ECA50920076F37F /* SOSPeerOTRTimer.m in Sources */, - DC2670F51F3E711400816EED /* SOSAccountCloudParameters.m in Sources */, - DCDCC7E51D9B5526006487E8 /* SOSAccountSync.m in Sources */, - DC2670F81F3E723B00816EED /* SOSAccountDer.m in Sources */, - DC52E8F71D80C34000B0A59C /* SOSAccountCredentials.m in Sources */, - DC52E8F91D80C34000B0A59C /* SOSAccountFullPeerInfo.m in Sources */, - DC52E8FC1D80C34000B0A59C /* SOSAccountLog.m in Sources */, - DC52E8FA1D80C34000B0A59C /* SOSAccountPeers.m in Sources */, - DC52E8FB1D80C34000B0A59C /* SOSAccountPersistence.m in Sources */, - DC52E8FF1D80C34000B0A59C /* SOSAccountRingUpdate.m in Sources */, - DC52E8FE1D80C34000B0A59C /* SOSAccountRings.m in Sources */, - 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 */, - 0C4899121E0E105D00C6CF70 /* SOSTransportCircleCK.m in Sources */, - DC52E8DD1D80C31F00B0A59C /* SOSCoder.c in Sources */, - DC52E8DE1D80C31F00B0A59C /* SOSDigestVector.c in Sources */, - DC52E8E01D80C31F00B0A59C /* SOSManifest.c in Sources */, - DC52E8E11D80C31F00B0A59C /* SOSMessage.c in Sources */, - DC52E8E21D80C31F00B0A59C /* SOSPeer.m in Sources */, - 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 */, - 0CAC5DBF1EB3DA4C00AD884B /* SOSPeerRateLimiter.m in Sources */, - DAB27AE11FA29EE300DEBBDE /* SOSControlServer.m in Sources */, - DC52E8D01D80C2FD00B0A59C /* SOSTransportMessageKVS.m in Sources */, + D45917E41DC13E6700752D25 /* SecCertificateRequest.c in Sources */, + DCD66DC01D82054500DB1393 /* SecCertificate.c in Sources */, + DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */, + BEEB47DA1EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, + DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */, + DCD66DB61D82050900DB1393 /* SecKey.m 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.m in Sources */, + DCD66DB41D82050000DB1393 /* SecRSAKey.c in Sources */, + DCD66DB31D8204FB00DB1393 /* SecServerEncryptionSupport.c in Sources */, + D425EC231DD3FFF200DE5DEC /* SecInternalRelease.c in Sources */, + DCD66DB21D8204F500DB1393 /* SecSignatureVerificationSupport.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EA451D80CB7000B0A59C /* Sources */ = { + DCD66DC51D8205C400DB1393 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EAA21D80CCB200B0A59C /* keychain_backup.c in Sources */, - DC52EAA11D80CCAC00B0A59C /* SecurityTool.c in Sources */, - DC52EAA01D80CCA700B0A59C /* whoami.m in Sources */, - DC52EA9F1D80CCA100B0A59C /* digest_calc.c in Sources */, - 473337841FDB29C400E19F30 /* KeychainCheck.m in Sources */, - EBEEEE3C1EA31D9600E15F5C /* SOSControlHelper.m in Sources */, - DC52EA9E1D80CC9B00B0A59C /* leaks.c in Sources */, - EB48C1A61E573EEC00EC5E57 /* sos.m in Sources */, - DC52EA9D1D80CC9700B0A59C /* syncbubble.m in Sources */, - DC52EBC31D80CEBA00B0A59C /* print_cert.c in Sources */, + DCD66DDD1D8205FB00DB1393 /* SecOTRDHKey.c in Sources */, + DCD66DDE1D8205FB00DB1393 /* SecOTRFullIdentity.c in Sources */, + DCD66DDF1D8205FB00DB1393 /* SecOTRMath.c in Sources */, + DCD66DE01D8205FB00DB1393 /* SecOTRPacketData.c in Sources */, + DCD66DE11D8205FB00DB1393 /* SecOTRPackets.c in Sources */, + DCD66DE21D8205FB00DB1393 /* SecOTRPublicIdentity.c in Sources */, + DCD66DE31D8205FB00DB1393 /* SecOTRSession.c in Sources */, + DCD66DE41D8205FB00DB1393 /* SecOTRSessionAKE.c in Sources */, + DCD66DDC1D8205E500DB1393 /* SecOTRUtils.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EBC71D80CEF100B0A59C /* Sources */ = { + DCD8A1071E09EE0F00E4FA0A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EC1E1D80CF6700B0A59C /* verify_cert.c in Sources */, - D453C3901FEC66AE00DE349B /* trust_update.m in Sources */, - DC52EC1D1D80CF6200B0A59C /* keychain_util.c in Sources */, - DC52EC1C1D80CF5D00B0A59C /* add_internet_password.c in Sources */, - DC52EC1B1D80CF5600B0A59C /* codesign.c in Sources */, - DC52EC1A1D80CF5100B0A59C /* keychain_add.c in Sources */, - DC52EC191D80CF4C00B0A59C /* keychain_find.m in Sources */, - DC52EC181D80CF4700B0A59C /* log_control.c in Sources */, - DC52EC171D80CF4200B0A59C /* pkcs12_util.c in Sources */, - D484A1072167D707008653A9 /* ct_exceptions.m in Sources */, - DC52EC161D80CF3B00B0A59C /* scep.c in Sources */, - DC52EC151D80CF0B00B0A59C /* show_certificates.c in Sources */, - DC52EC141D80CF0500B0A59C /* spc.c in Sources */, + DCD8A19D1E09EEC800E4FA0A /* SOSBackupSliceKeyBag.m in Sources */, + DC2670FB1F3E72C000816EED /* SOSCircleDer.c in Sources */, + DCD8A1B31E09F12D00E4FA0A /* SOSCircle.c in Sources */, + DCD8A1FF1E09FA6100E4FA0A /* secViewDisplay.c in Sources */, + DC2FA72520E57AB500DB7518 /* SOSPeerInfo.m in Sources */, + DCD8A1B41E09F12D00E4FA0A /* SOSCircleV2.c in Sources */, + DCD8A1A01E09EF3500E4FA0A /* SOSCloudKeychainClient.c in Sources */, + DC752F1721C1B48400216089 /* SOSPiggyback.m in Sources */, + DCD8A1A11E09EF5C00E4FA0A /* SOSCloudKeychainConstants.c in Sources */, + DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */, + DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */, + DCD8A1B51E09F15400E4FA0A /* SOSGenCount.c in Sources */, + DCD8A19F1E09EF0F00E4FA0A /* SOSInternal.m in Sources */, + EBEEEE3F1EA31E6D00E15F5C /* SOSControlHelper.m in Sources */, + DCD8A1A61E09EFD700E4FA0A /* SOSKVSKeys.m in Sources */, + DCD8A1B61E09F16C00E4FA0A /* SOSKeyedPubKeyIdentifier.c in Sources */, + DCD8A1A41E09EF9000E4FA0A /* SOSPeerInfoCollections.c in Sources */, + DCD8A1B11E09F11900E4FA0A /* SOSPeerInfoDER.m in Sources */, + DCD8A1B21E09F11900E4FA0A /* SOSPeerInfoRingState.m in Sources */, + DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */, + DCD8A1BC1E09F1BB00E4FA0A /* SOSRingPeerInfoUtils.c in Sources */, + DCD8A1B71E09F19100E4FA0A /* SOSRingV0.m in Sources */, + DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */, + DCD8A19E1E09EEDA00E4FA0A /* SecRecoveryKey.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EC221D80CFB200B0A59C /* Sources */ = { + DCE4E6911D7A37FA00AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD7EE841F4E46F9007D9804 /* accountCirclesViewsPrint.m in Sources */, - 0C0CECA41DA45ED700C22FBC /* recovery_key.m in Sources */, - DC52EC3B1D80CFE900B0A59C /* syncbackup.m in Sources */, - DC52EC3A1D80CFE400B0A59C /* keychain_log.m in Sources */, - DC52EC391D80CFDF00B0A59C /* secViewDisplay.c in Sources */, - DC52EC381D80CFDB00B0A59C /* secToolFileIO.c in Sources */, - DC52EC371D80CFD400B0A59C /* keychain_sync_test.m in Sources */, - DC52EC361D80CFD000B0A59C /* keychain_sync.m in Sources */, - DC3C7C901D83957F00F6A832 /* NSFileHandle+Formatting.m in Sources */, - DCE5DC0F1EA80256006308A6 /* SOSSysdiagnose.m in Sources */, + DC8506A62097EE7300C712EC /* SecurityTool.c in Sources */, + DC3AA28D2097E24B007CA68A /* scep.c in Sources */, + DC3AA2912097E25B007CA68A /* trust_update.m in Sources */, + DC85069B2097E69500C712EC /* keychain_backup.c in Sources */, + 1BDEBEF92252DEB1009AD3D6 /* policy_dryrun.m in Sources */, + DC8506B52097F1FD00C712EC /* whoami.m in Sources */, + DC8506AB2097EEA600C712EC /* syncbubble.m in Sources */, + DC8506A92097EE8F00C712EC /* KeychainCheck.m in Sources */, + DC3AA2832097E21C007CA68A /* log_control.c in Sources */, + DC3AA27A2097DF84007CA68A /* not_on_this_platorm.c in Sources */, + DC3AA2802097E20B007CA68A /* keychain_util.c in Sources */, + DCE4E6921D7A37FA00AFB96E /* security_tool_commands.c in Sources */, + DC3AA2852097E22A007CA68A /* codesign.c in Sources */, + DC8506AD2097EEBC00C712EC /* sos.m in Sources */, + DCE4E6931D7A37FA00AFB96E /* NSFileHandle+Formatting.m in Sources */, + DC3AA2892097E23A007CA68A /* keychain_find.m in Sources */, + DC3AA2792097DF71007CA68A /* readline.c in Sources */, + DC3AA2822097E218007CA68A /* add_internet_password.c in Sources */, + DC8506B32097F1E000C712EC /* digest_calc.c in Sources */, + DC8506AF2097EEDB00C712EC /* leaks.c in Sources */, + DC3AA2902097E254007CA68A /* show_certificates.c in Sources */, + DC3AA2932097E263007CA68A /* spc.c in Sources */, + DC3AA27E2097E207007CA68A /* verify_cert.c in Sources */, + D4A3A598217A85D600F0A8DA /* ct_exceptions.m in Sources */, + DC3AA2882097E232007CA68A /* keychain_add.c in Sources */, + DC3AA28C2097E23F007CA68A /* pkcs12_util.c in Sources */, + DC8506B12097EEF300C712EC /* print_cert.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EC3F1D80D00800B0A59C /* Sources */ = { + DCE4E74C1D7A43B500AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EC4F1D80D02400B0A59C /* SecuritydXPC.c in Sources */, - DC52EC4E1D80D01F00B0A59C /* swcagent_client.c in Sources */, + DCE4E7B51D7A43FF00AFB96E /* main.m in Sources */, + DCE4E7B61D7A440A00AFB96E /* bc-10-knife-on-bread.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EC531D80D05200B0A59C /* Sources */ = { + DCE4E7C81D7A4AED00AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EC5D1D80D06300B0A59C /* SecLogging.c in Sources */, + DCE4E7E21D7A4B7F00AFB96E /* main.c in Sources */, + DCE4E7DF1D7A4B4C00AFB96E /* bc-10-knife-on-bread.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EC611D80D0C400B0A59C /* Sources */ = { + DCE4E7F21D7A4DA800AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EC7B1D80D15600B0A59C /* sc-30-peerinfo.c in Sources */, - DC52EC7A1D80D15200B0A59C /* sc-40-circle.c in Sources */, - DC52EC791D80D14D00B0A59C /* sc-45-digestvector.c in Sources */, - DC52EC781D80D14800B0A59C /* SOSRegressionUtilities.m in Sources */, - DC52EC771D80D14400B0A59C /* sc-130-resignationticket.c in Sources */, - DC52EC761D80D13F00B0A59C /* sc-150-ring.m in Sources */, - DC52EC751D80D13B00B0A59C /* sc-42-circlegencount.c in Sources */, - DC52EC741D80D13500B0A59C /* SOSTestDataSource.c in Sources */, - DC52EC731D80D12E00B0A59C /* sc-20-keynames.m in Sources */, - DC52EC721D80D12900B0A59C /* sc-150-backupkeyderivation.c in Sources */, - DC52EC711D80D12200B0A59C /* sc-153-backupslicekeybag.c in Sources */, - DC52EC6F1D80D11800B0A59C /* sc-25-soskeygen.c in Sources */, - DC52EC6E1D80D0F700B0A59C /* SOSTestDevice.c in Sources */, - DC52EC6D1D80D0F100B0A59C /* sc-31-peerinfo-simplefuzz.c in Sources */, + 1B995259226681FA00A2D6CD /* PolicyReporter.h in Sources */, + 1B99525A226681FA00A2D6CD /* PolicyReporter.m in Sources */, + DCCD33CE1E3FEF1700AA4AD1 /* spi.c in Sources */, + 476541701F33B59300413F65 /* SecdWatchdog.m in Sources */, + DCE4E8071D7A4DE200AFB96E /* server.c in Sources */, + D4BD5E85228A6854001650A7 /* util.m in Sources */, + DC5F35A61EE0F25000900966 /* server_entitlement_helpers.c in Sources */, + DC4269081E82FD8B002B7110 /* server_security_helpers.m in Sources */, + DCB221501E8B08A5001598BC /* server_xpc.m in Sources */, + DC6ACC461E81E08D00125DC5 /* server_endpoint.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EC7F1D80D1A800B0A59C /* Sources */ = { + DCE4E8381D7A57AE00AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52ECE81D80D2FA00B0A59C /* pbkdf2-00-hmac-sha1.c in Sources */, - DC52ECE91D80D2FA00B0A59C /* spbkdf-00-hmac-sha1.c in Sources */, - DC52ECE11D80D2F000B0A59C /* otr-00-identity.c in Sources */, - DC52ECE21D80D2F000B0A59C /* otr-30-negotiation.c in Sources */, - DC52ECE31D80D2F000B0A59C /* otr-40-edgecases.c in Sources */, - DC52ECE41D80D2F000B0A59C /* otr-50-roll.c in Sources */, - DC52ECE51D80D2F000B0A59C /* otr-60-slowroll.c in Sources */, - DC52ECE61D80D2F000B0A59C /* otr-otrdh.c in Sources */, - DC52ECE71D80D2F000B0A59C /* otr-packetdata.c in Sources */, - DC52EC9B1D80D22600B0A59C /* si-00-find-nothing.c in Sources */, - DC52EC9C1D80D22600B0A59C /* si-05-add.c in Sources */, - DC52EC9D1D80D22600B0A59C /* si-10-find-internet.c in Sources */, - DC52EC9E1D80D22600B0A59C /* si-11-update-data.c in Sources */, - DC52EC9F1D80D22600B0A59C /* si-12-item-stress.c in Sources */, - DC52ECA01D80D22600B0A59C /* si-13-item-system.m in Sources */, - DC52ECA11D80D22600B0A59C /* si-14-dateparse.c in Sources */, - DC52ECA21D80D22600B0A59C /* si-15-delete-access-group.m in Sources */, - DC52ECA51D80D22600B0A59C /* si-17-item-system-bluetooth.m in Sources */, - DC52ECB61D80D22600B0A59C /* si-30-keychain-upgrade.c in Sources */, - DC52ECB71D80D22600B0A59C /* si-31-keychain-bad.c in Sources */, - DC52ECB81D80D22600B0A59C /* si-31-keychain-unreadable.c in Sources */, - DC52ECB91D80D22600B0A59C /* si-33-keychain-backup.c in Sources */, - DC52ECBA1D80D22600B0A59C /* si-40-seckey-custom.c in Sources */, - DC52ECBB1D80D22600B0A59C /* si-40-seckey.c in Sources */, - DC52ECBC1D80D22600B0A59C /* si-41-sececkey.c in Sources */, - DC52ECBD1D80D22600B0A59C /* si-42-identity.c in Sources */, - DC52ECBE1D80D22600B0A59C /* si-43-persistent.c in Sources */, - DC52ECC31D80D22600B0A59C /* si-50-secrandom.c in Sources */, - DC52ECC71D80D22600B0A59C /* si-63-scep.m in Sources */, - DC52ECCD1D80D22600B0A59C /* si-69-keydesc.c in Sources */, - DC52ECD01D80D22600B0A59C /* si-72-syncableitems.c in Sources */, - DC52ECD11D80D22600B0A59C /* si-73-secpasswordgenerate.c in Sources */, - DC52ECD31D80D22600B0A59C /* si-76-shared-credentials.c in Sources */, - DC52ECD41D80D22600B0A59C /* si_77_SecAccessControl.c in Sources */, - DC52ECD51D80D22600B0A59C /* si-78-query-attrs.c in Sources */, - DC52ECD61D80D22600B0A59C /* si-80-empty-data.c in Sources */, - DC52ECD91D80D22600B0A59C /* si-82-token-ag.c in Sources */, - DC52ECDE1D80D22600B0A59C /* si-90-emcs.m in Sources */, - DC52ECDF1D80D22600B0A59C /* si-95-cms-basic.c in Sources */, - DC52EC981D80D1D100B0A59C /* vmdh-40.c in Sources */, - D4D718351E04A721000AE7A6 /* spbkdf-01-hmac-sha256.c in Sources */, - DC52EC991D80D1D100B0A59C /* vmdh-41-example.c in Sources */, - DC52EC9A1D80D1D100B0A59C /* vmdh-42-example2.c in Sources */, - DC52ECEA1D80D30900B0A59C /* so_01_serverencryption.c in Sources */, + D4BEECE81E93094500F76D1A /* trustd.c in Sources */, + DC5F35A91EE0F25300900966 /* server_entitlement_helpers.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52ED641D80D4CD00B0A59C /* Sources */ = { + DCE4E8901D7F34F600AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EDA01D80D4F700B0A59C /* sd-10-policytree.m in Sources */, - DC52ED9F1D80D4F200B0A59C /* SOSTransportTestTransports.m in Sources */, - DC52ED9E1D80D4ED00B0A59C /* secd-95-escrow-persistence.m in Sources */, + DCE4E8C21D7F353900AFB96E /* server.c in Sources */, + DCE4E8BA1D7F353900AFB96E /* credential.c in Sources */, + DCE4E8BF1D7F353900AFB96E /* object.c in Sources */, + DCE4E8B51D7F353900AFB96E /* authitems.c in Sources */, + DCE4E8B91D7F353900AFB96E /* crc.c in Sources */, + DCE4E8C31D7F353900AFB96E /* session.c in Sources */, + DCE4E8BC1D7F353900AFB96E /* engine.c in Sources */, + DCE4E8C41D7F353900AFB96E /* connection.c in Sources */, + DCE4E8C11D7F353900AFB96E /* rule.c in Sources */, + DCE4E8C01D7F353900AFB96E /* process.c in Sources */, + DCE4E8B31D7F353900AFB96E /* agent.c in Sources */, + DCE4E8BE1D7F353900AFB96E /* mechanism.c in Sources */, + DCE4E8B41D7F353900AFB96E /* authdb.c in Sources */, + DCE4E8B81D7F353900AFB96E /* ccaudit.c in Sources */, + DCE4E8BD1D7F353900AFB96E /* main.c in Sources */, + DCE4E8B71D7F353900AFB96E /* authutilities.c in Sources */, + DCE4E8B61D7F353900AFB96E /* authtoken.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EDA71D80D58400B0A59C /* Sources */ = { + DCE4E8D91D7F39DB00AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - E7C787211DCA4D430087FC34 /* CKDAKSLockMonitor.m in Sources */, - DC52EDFA1D80D66600B0A59C /* SOSRegressionUtilities.m in Sources */, - DCFAEDD61D99A47A005187E4 /* secd-36-ks-encrypt.m in Sources */, - 7281E08D1DFD0B520021E1B7 /* XPCNotificationDispatcher.m in Sources */, - DC52EDF91D80D66000B0A59C /* SOSTestDataSource.c in Sources */, - 7281E0911DFD0E510021E1B7 /* CKDSimulatedStore.m in Sources */, - E73A7E911DC81E0300A5B2D1 /* CKDSimulatedAccount.m in Sources */, - DC52EDF81D80D65C00B0A59C /* SOSTestDevice.c in Sources */, - DC52EDF71D80D65700B0A59C /* si-90-emcs.m in Sources */, - 483E798F1DC87605005C0008 /* secd-67-prefixedKeyIDs.m in Sources */, - 48CC589F1DA5FF2700EBD9DB /* secd-66-account-recovery.m in Sources */, - DC52EDF51D80D62E00B0A59C /* SecdTestKeychainUtilities.c in Sources */, - DC52EDF61D80D62E00B0A59C /* SOSTransportTestTransports.m in Sources */, - EB9C02481E8A15B40040D3C6 /* secd-37-pairing-initial-sync.m in Sources */, - 0CAD1E5E1E1C5D0600537693 /* secd-95-escrow-persistence.m in Sources */, - DC52EDB51D80D5C500B0A59C /* secd-03-corrupted-items.m in Sources */, - 0CAD1E5D1E1C5CF900537693 /* secd-80-views-alwayson.m in Sources */, - DC52EDB61D80D5C500B0A59C /* secd-04-corrupted-items.m in Sources */, - DC52EDB71D80D5C500B0A59C /* secd-05-corrupted-items.m in Sources */, - DC52EDBB1D80D5C500B0A59C /* secd-01-items.m in Sources */, - DC52EDBC1D80D5C500B0A59C /* secd-02-upgrade-while-locked.m in Sources */, - DC52EDBD1D80D5C500B0A59C /* secd-20-keychain_upgrade.m in Sources */, - DC52EDBE1D80D5C500B0A59C /* secd-21-transmogrify.m in Sources */, - DCFAEDD21D99991F005187E4 /* secd-668-ghosts.m in Sources */, - DC52EDBF1D80D5C500B0A59C /* secd-30-keychain-upgrade.m in Sources */, - DC52EDC01D80D5C500B0A59C /* secd-31-keychain-bad.m in Sources */, - DC52EDC11D80D5C500B0A59C /* secd-31-keychain-unreadable.m in Sources */, - 0CCDE7171EEB08220021A946 /* secd-156-timers.m in Sources */, - DC52EDC21D80D5C500B0A59C /* secd-32-restore-bad-backup.m in Sources */, - DC52EDC31D80D5C500B0A59C /* secd-33-keychain-ctk.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 */, - DC52EDC51D80D5C500B0A59C /* secd-35-keychain-migrate-inet.m in Sources */, - DC52EDC61D80D5C500B0A59C /* secd-40-cc-gestalt.m in Sources */, - DC52EDC71D80D5C500B0A59C /* secd-50-account.m in Sources */, - DC52EDC81D80D5C500B0A59C /* secd-49-manifests.m in Sources */, - DC52EDC91D80D5C500B0A59C /* secd-50-message.m in Sources */, - DC52EDCA1D80D5C500B0A59C /* secd-51-account-inflate.m in Sources */, - DC52EDCC1D80D5C500B0A59C /* secd-52-account-changed.m in Sources */, - DC52EDCD1D80D5C500B0A59C /* secd-55-account-circle.m in Sources */, - DCFAEDD71D99A4AB005187E4 /* secd-154-engine-backoff.m in Sources */, - DC52EDCE1D80D5C500B0A59C /* secd-55-account-incompatibility.m in Sources */, - DC52EDCF1D80D5C500B0A59C /* secd-56-account-apply.m in Sources */, - DC52EDD01D80D5C500B0A59C /* secd-57-account-leave.m in Sources */, - DC52EDD11D80D5C500B0A59C /* secd-57-1-account-last-standing.m in Sources */, - DC52EDD21D80D5C500B0A59C /* secd-58-password-change.m in Sources */, - 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 */, - 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 */, - DC52EDDA1D80D5C500B0A59C /* secd-65-account-retirement-reset.m in Sources */, - DCDCC7E31D9B54EE006487E8 /* secd-202-recoverykey.m in Sources */, - DC52EDDB1D80D5C500B0A59C /* secd-64-circlereset.m in Sources */, - DC52EDDC1D80D5C500B0A59C /* secd-70-engine.m in Sources */, - 0C3C00731EF3636500AB19FE /* secd-155-otr-negotiation-monitor.m in Sources */, - 7281E08F1DFD0DBB0021E1B7 /* secd-210-keyinterest.m in Sources */, - 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 */, - 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 */, - 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 */, - DC52EDEB1D80D5C500B0A59C /* secd-83-item-match-policy.m in Sources */, - DC52EDEC1D80D5C500B0A59C /* secd-83-item-match-valid-on-date.m in Sources */, - DC52EDED1D80D5C600B0A59C /* secd-83-item-match-trusted.m in Sources */, - DC52EDF11D80D5C600B0A59C /* secd-100-initialsync.m in Sources */, - DC52EDF21D80D5C600B0A59C /* secd-130-other-peer-views.m in Sources */, - DC52EDF41D80D5C600B0A59C /* secd-200-logstate.m in Sources */, + D49111302095154B0066A1E4 /* MainMenu.xib in Sources */, + DCE4E8F71D7F3A1100AFB96E /* KDCirclePeer.m in Sources */, + DCE4E8F91D7F3A1100AFB96E /* KDAppDelegate.m in Sources */, + DCE4E8F81D7F3A1100AFB96E /* main.m in Sources */, + DCE4E8F61D7F3A1100AFB96E /* KDSecCircle.m in Sources */, + DCE4E8FA1D7F3A1100AFB96E /* KDSecItems.m in Sources */, + DCE4E8FB1D7F3A1100AFB96E /* NSArray+mapWithBlock.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EDFE1D80D6DD00B0A59C /* Sources */ = { + DCE4E90D1D7F3D5300AFB96E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC52EE611D80D79E00B0A59C /* si-71-mobile-store-policy.c in Sources */, - DC52EE601D80D79900B0A59C /* si-74-OTAPKISigner.c in Sources */, - D4AD87701E452CE000CA1B7F /* si-68-secmatchissuer.c in Sources */, - EB6928CA1D9C9E1800062A18 /* rk_01_recoverykey.m in Sources */, - D42CDC351DC12FE90090E2C9 /* si-66-smime.c in Sources */, - DC52EE5F1D80D79400B0A59C /* si-85-sectrust-ssl-policy.c in Sources */, - D4AA64891E9727EB00D317ED /* si-18-certificate-parse.m in Sources */, - B61577F41F20513C004A3930 /* padding-00-mmcs.c in Sources */, - DC0B62291D90974600D43BCB /* si-25-cms-skid.m in Sources */, - DC52EE5E1D80D78C00B0A59C /* si-82-sectrust-ct.m in Sources */, - DC52EE5D1D80D76B00B0A59C /* si-87-sectrust-name-constraints.m in Sources */, - 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 */, - DC52EE471D80D71900B0A59C /* si-23-sectrust-ocsp.c in Sources */, - D48E4E241E42F0620011B4BA /* si-62-csr.m in Sources */, - 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 */, - 5E7793751E5F025A0074A2D1 /* si-44-seckey-aks.m in Sources */, - DC52EE4E1D80D71900B0A59C /* si-27-sectrust-exceptions.c in Sources */, - DC52EE4F1D80D71900B0A59C /* si-28-sectrustsettings.m in Sources */, - DC52EE531D80D73800B0A59C /* si-44-seckey-gen.m in Sources */, - DC52EE541D80D73800B0A59C /* si-44-seckey-rsa.m in Sources */, - 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 */, - DC52EE5B1D80D73800B0A59C /* si-97-sectrust-path-scoring.m in Sources */, - D47E69401E92F75D002C8CF6 /* si-61-pkcs12.c in Sources */, - BEB9E9EC1FFF195C00676593 /* si-88-sectrust-valid.m in Sources */, + D491112F2095154B0066A1E4 /* MainMenu.xib in Sources */, + DCE4E92B1D7F3D7C00AFB96E /* KDSecCircle.m in Sources */, + DCE4E92C1D7F3D7C00AFB96E /* KNPersistentState.m in Sources */, + DCE4E9311D7F3D7C00AFB96E /* KDCirclePeer.m in Sources */, + DCE4E92D1D7F3D7C00AFB96E /* NSArray+mapWithBlock.m in Sources */, + DCE4E92F1D7F3D7C00AFB96E /* NSString+compactDescription.m in Sources */, + DCE4E9301D7F3D7C00AFB96E /* main.m in Sources */, + DCE4E92E1D7F3D7C00AFB96E /* NSDictionary+compactDescription.m in Sources */, + DCE4E9321D7F3D7C00AFB96E /* KNAppDelegate.m in Sources */, + DCE4E9331D7F3D7C00AFB96E /* NSSet+compactDescription.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC52EE671D80D82600B0A59C /* Sources */ = { + DCF216D421ADD5B10029CCC1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - EB78D3F91E600E93009AFE05 /* SOSCloudCircle.m in Sources */, - DC52EE7C1D80D89E00B0A59C /* SecItemBackup.c in Sources */, - DC4269051E82EDC4002B7110 /* SecItem.m in Sources */, - EBEEEE3E1EA31DB100E15F5C /* SOSControlHelper.m 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.m in Sources */, - DC52EE741D80D86F00B0A59C /* SecAccessControl.m in Sources */, - DC52EE731D80D86800B0A59C /* SecKey.c in Sources */, - DC52EE721D80D86400B0A59C /* SecuritydXPC.c in Sources */, - DC52EE711D80D85F00B0A59C /* SecECKey.m in Sources */, - DC52EE701D80D84700B0A59C /* SecItemConstants.c in Sources */, - DC52EE6F1D80D83F00B0A59C /* SecPasswordGenerate.c in Sources */, + 0CE15E39222DF67800B7EAA4 /* OTRecovery.proto in Sources */, + DCE0775621ADD665002662FD /* OTPrivateKey.proto in Sources */, + DCE0775321ADD65E002662FD /* OTAuthenticatedCiphertext.proto in Sources */, + DCE0775521ADD663002662FD /* OTBottleContents.proto in Sources */, + DCE0775421ADD661002662FD /* OTBottle.proto in Sources */, + DCF216DE21ADD5F90029CCC1 /* CKKSSerializedKey.proto in Sources */, + DCF216DF21ADD5FB0029CCC1 /* OTPairingMessage.proto in Sources */, + DCF216E121ADD6060029CCC1 /* TPPBVoucher.proto in Sources */, + DCF216E021ADD5FD0029CCC1 /* OTAccountMetadataClassC.proto in Sources */, + DCE0774721ADD63A002662FD /* TPPBDispositionEntry.proto in Sources */, + DCE0774821ADD63C002662FD /* TPPBAncientEpoch.proto in Sources */, + DCE0774621ADD638002662FD /* TPPBDisposition.proto in Sources */, + DCE0774921ADD63E002662FD /* TPPBPolicyProhibits.proto in Sources */, + DCE0774A21ADD640002662FD /* TPPBUnknownMachineID.proto in Sources */, + 1B8341B92239AD3A002BF18A /* TPPBPolicyKeyViewMapping.proto in Sources */, + DCE0774C21ADD648002662FD /* TPPBPeerPermanentInfo.proto in Sources */, + DCE0774D21ADD64A002662FD /* TPPBPolicySecret.proto in Sources */, + DCE0774B21ADD642002662FD /* TPPBPeerStableInfo.proto in Sources */, + DCE0774E21ADD64C002662FD /* TPPBPolicyDocument.proto in Sources */, + 5A47FFB3228F5E5500F781B8 /* KCInitialMessageData.proto in Sources */, + DCE0775021ADD655002662FD /* TPPBPolicyModelToCategory.proto in Sources */, + DCE0775121ADD658002662FD /* TPPBPolicyIntroducersByCategory.proto in Sources */, + DCE0774F21ADD651002662FD /* TPPBPolicyCategoriesByView.proto in Sources */, + DC88466B22373A5E00738068 /* TPPBDictionaryMatchingRule.proto in Sources */, + DCE0775221ADD65A002662FD /* TPPBPolicyRedaction.proto in Sources */, + 6C9791CB21C325C30074C609 /* SecDbBackupRecoverySet.proto in Sources */, + DCE0774321ADD635002662FD /* TPPBPeerDynamicInfo.proto in Sources */, + DCE0775721ADD669002662FD /* SecDbKeychainSerializedItemV7.proto in Sources */, + DCE0775821ADD66B002662FD /* SecDbKeychainSerializedAKSWrappedKey.proto in Sources */, + DC90A4C721F279D4001300EB /* SecEscrowPendingRecord.proto in Sources */, + DCE0775921ADD66E002662FD /* SecDbKeychainSerializedMetadata.proto in Sources */, + DCE0775A21ADD671002662FD /* SecDbKeychainSerializedSecretData.proto in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC58C41F1D77BDEA003C25A4 /* Sources */ = { + DCF7830E1D88B4DE00E694BB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC58C43E1D77BED0003C25A4 /* csparser.cpp in Sources */, + DCF783F31D88B60D00E694BB /* pkcs12Derive.cpp in Sources */, + DCF784CE1D88B62E00E694BB /* rc2_skey.c in Sources */, + DCF7849F1D88B62D00E694BB /* bn_exp.c in Sources */, + DCF784F31D88B62E00E694BB /* rsa_pk1.c in Sources */, + DCF783EF1D88B60D00E694BB /* SHA1_MD5_Object.cpp in Sources */, + DCF784BE1D88B62E00E694BB /* dh_lib.c in Sources */, + DCF783D41D88B60D00E694BB /* cryptkitcsp.cpp in Sources */, + DCF784A11D88B62D00E694BB /* bn_gcd.c in Sources */, + DCF784BB1D88B62E00E694BB /* dh_err.c in Sources */, + DCF7849B1D88B62D00E694BB /* bn_blind.c in Sources */, + DCF784B61D88B62D00E694BB /* buf_err.c in Sources */, + DCF784B71D88B62D00E694BB /* buffer.c in Sources */, + DCF783E51D88B60D00E694BB /* DH_utils.cpp in Sources */, + DCF784041D88B60D00E694BB /* miscAlgFactory.cpp in Sources */, + DCF7849A1D88B62D00E694BB /* bn_asm.c in Sources */, + DCF783DB1D88B60D00E694BB /* FEEKeys.cpp in Sources */, + DCF784C51D88B62E00E694BB /* dsa_sign.c in Sources */, + DCF783A21D88B60D00E694BB /* gladmanContext.cpp in Sources */, + DCF783B51D88B60D00E694BB /* BlockCryptor.cpp in Sources */, + DCF784071D88B60D00E694BB /* RSA_DSA_signature.cpp in Sources */, + DCF784AB1D88B62D00E694BB /* bn_recp.c in Sources */, + DCF784AD1D88B62D00E694BB /* bn_sqr.c in Sources */, + DCF784091D88B60D00E694BB /* RSA_DSA_utils.cpp in Sources */, + DCF783D91D88B60D00E694BB /* FEECSPUtils.cpp in Sources */, + DCF784C01D88B62E00E694BB /* dsa_err.c in Sources */, + DCF784CF1D88B62E00E694BB /* rc5_enc.c in Sources */, + DCF784A71D88B62D00E694BB /* bn_prime.c in Sources */, + DCF7839E1D88B60D00E694BB /* aescsp.cpp in Sources */, + DCF784921D88B62D00E694BB /* bf_ecb.c in Sources */, + DCF783E71D88B60D00E694BB /* HMACSHA1.c in Sources */, + DCF784F61D88B62E00E694BB /* rsa_ssl.c in Sources */, + DCF783E31D88B60D00E694BB /* DH_keys.cpp in Sources */, + DCF784AC1D88B62D00E694BB /* bn_shift.c in Sources */, + DCF784A51D88B62D00E694BB /* bn_mpi.c in Sources */, + DCF784A61D88B62D00E694BB /* bn_mul.c in Sources */, + DCF784BC1D88B62E00E694BB /* dh_gen.c in Sources */, + DCF784061D88B60D00E694BB /* RSA_asymmetric.cpp in Sources */, + DCF784EC1D88B62E00E694BB /* rsa_chk.c in Sources */, + DCF783BC1D88B60D00E694BB /* MacContext.cpp in Sources */, + DCF783ED1D88B60D00E694BB /* MD2Object.cpp in Sources */, + DCF783A81D88B60D00E694BB /* vRijndael-alg-ref.c in Sources */, + DCF783AC1D88B60D00E694BB /* AppleCSPContext.cpp in Sources */, + DCF784BF1D88B62E00E694BB /* dsa_asn1.c in Sources */, + DCF783A01D88B60D00E694BB /* boxes-ref.c in Sources */, + DCF784151D88B60D00E694BB /* opensslUtils.cpp in Sources */, + DCF783B91D88B60D00E694BB /* deriveKey.cpp in Sources */, + DCF783FE1D88B60D00E694BB /* rc2Context.cpp in Sources */, + DCF784121D88B60D00E694BB /* opensshWrap.cpp in Sources */, + DCF783F11D88B60D00E694BB /* SHA2_Object.cpp in Sources */, + DCF784A91D88B62D00E694BB /* bn_print.c in Sources */, + DCF783A61D88B60D00E694BB /* rijndaelApi.c in Sources */, + DCF783BA1D88B60D00E694BB /* DigestContext.cpp in Sources */, + DCF784D11D88B62E00E694BB /* rc5_skey.c in Sources */, + DCF784CA1D88B62E00E694BB /* lhash.c in Sources */, + DCF784BD1D88B62E00E694BB /* dh_key.c in Sources */, + DCF784C71D88B62E00E694BB /* err.c in Sources */, + DCF783AE1D88B60D00E694BB /* AppleCSPKeys.cpp in Sources */, + DCF784CB1D88B62E00E694BB /* mem.c in Sources */, + DCF783D71D88B60D00E694BB /* FEEAsymmetricContext.cpp in Sources */, + DCF783E11D88B60D00E694BB /* DH_exchange.cpp in Sources */, + DCF783C31D88B60D00E694BB /* YarrowConnection.cpp in Sources */, + DCF784A41D88B62D00E694BB /* bn_mont.c in Sources */, + DCF783C11D88B60D00E694BB /* wrapKey.cpp in Sources */, + DCF783BF1D88B60D00E694BB /* SignatureContext.cpp in Sources */, + DCF784111D88B60D00E694BB /* opensshCoding.cpp in Sources */, + DCF784C11D88B62E00E694BB /* dsa_gen.c in Sources */, + DCF7840B1D88B60D00E694BB /* RSA_DSA_csp.cpp in Sources */, + DCF783F71D88B60D00E694BB /* bfContext.cpp in Sources */, + DCF783FB1D88B60D00E694BB /* desContext.cpp in Sources */, + DCF784CC1D88B62E00E694BB /* rc2_cbc.c in Sources */, + DCF784AA1D88B62D00E694BB /* bn_rand.c in Sources */, + DCF784BA1D88B62E00E694BB /* dh_check.c in Sources */, + DCF783A91D88B60D00E694BB /* AppleCSP.cpp in Sources */, + DCF784C31D88B62E00E694BB /* dsa_lib.c in Sources */, + DCF784971D88B62D00E694BB /* bio_lib.c in Sources */, + DCF784C91D88B62E00E694BB /* ex_data.c in Sources */, + DCF784C21D88B62E00E694BB /* dsa_key.c in Sources */, + DCF784A31D88B62D00E694BB /* bn_lib.c in Sources */, + DCF784961D88B62D00E694BB /* bf_skey.c in Sources */, + DCF784F01D88B62E00E694BB /* rsa_lib.c in Sources */, + DCF783AB1D88B60D00E694BB /* AppleCSPBuiltin.cpp in Sources */, + DCF783D11D88B60D00E694BB /* ascContext.cpp in Sources */, + DCF784981D88B62D00E694BB /* bss_file.c in Sources */, + DCF784C81D88B62E00E694BB /* err_prn.c in Sources */, + DCF784F11D88B62E00E694BB /* rsa_none.c in Sources */, + DCF784B81D88B62D00E694BB /* cryptlib.c in Sources */, + DCF783DF1D88B60D00E694BB /* DH_csp.cpp in Sources */, + DCF784A01D88B62D00E694BB /* bn_exp2.c in Sources */, + DCF7840D1D88B60D00E694BB /* RSA_DSA_keys.cpp in Sources */, + DCF783B21D88B60D00E694BB /* AppleCSPUtils.cpp in Sources */, + DCF784EE1D88B62E00E694BB /* rsa_err.c in Sources */, + DCF783F91D88B60D00E694BB /* castContext.cpp in Sources */, + DCF783F51D88B60D00E694BB /* pkcs8.cpp in Sources */, + DCF783C21D88B60D00E694BB /* wrapKeyCms.cpp in Sources */, + DCF7849E1D88B62D00E694BB /* bn_err.c in Sources */, + DCF784131D88B60D00E694BB /* opensslAsn1.cpp in Sources */, + DCF784991D88B62D00E694BB /* bn_add.c in Sources */, + DCF784001D88B60D00E694BB /* rc4Context.cpp in Sources */, + DCF783DD1D88B60D00E694BB /* FEESignatureObject.cpp in Sources */, + DCF784C61D88B62E00E694BB /* dsa_vrf.c in Sources */, + DCF784AE1D88B62D00E694BB /* bn_word.c in Sources */, + DCF783A41D88B60D00E694BB /* rijndael-alg-ref.c in Sources */, + DCF783E91D88B60D00E694BB /* pbkdDigest.cpp in Sources */, + DCF784021D88B60D00E694BB /* rc5Context.cpp in Sources */, + DCF783EB1D88B60D00E694BB /* pbkdf2.c in Sources */, + DCF783B71D88B60D00E694BB /* cspdebugging.c in Sources */, + DCF784ED1D88B62E00E694BB /* rsa_eay.c in Sources */, + DCF784EF1D88B62E00E694BB /* rsa_gen.c in Sources */, + DCF784F71D88B62E00E694BB /* stack.c in Sources */, + DCF7849C1D88B62D00E694BB /* bn_ctx.c in Sources */, + DCF784F51D88B62E00E694BB /* rsa_sign.c in Sources */, + DCF784F21D88B62E00E694BB /* rsa_null.c in Sources */, + DCF784931D88B62D00E694BB /* bf_enc.c in Sources */, + DCF784F41D88B62E00E694BB /* rsa_saos.c in Sources */, + DCF7849D1D88B62D00E694BB /* bn_div.c in Sources */, + DCF784C41D88B62E00E694BB /* dsa_ossl.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC5ABDC11D832DAB00CF422C /* Sources */ = { + DCF785601D88B95500E694BB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC5ABDCC1D832E4000CF422C /* srCdsaUtils.cpp in Sources */, - DC5ABDCD1D832E4000CF422C /* createFVMaster.c in Sources */, - DC5ABDCE1D832E4000CF422C /* mds_install.cpp in Sources */, - DC5ABDCF1D832E4000CF422C /* cmsutil.c in Sources */, - DC5ABDD01D832E4000CF422C /* db_commands.cpp in Sources */, - DC5ABDD11D832E4000CF422C /* display_error_code.c in Sources */, - DC5ABDD21D832E4000CF422C /* trusted_cert_dump.c in Sources */, - DC5ABDD31D832E4000CF422C /* identity_find.m in Sources */, - DC5ABDD41D832E4000CF422C /* identity_prefs.c in Sources */, - DC5ABDD51D832E4000CF422C /* key_create.c in Sources */, - DC5ABDD61D832E4000CF422C /* keychain_add.c in Sources */, - DC5ABDD71D832E4000CF422C /* keychain_create.c in Sources */, - DC5ABDD81D832E4000CF422C /* keychain_delete.c in Sources */, - DC5ABDD91D832E4000CF422C /* keychain_export.m in Sources */, - DC5ABDDA1D832E4000CF422C /* keychain_find.c in Sources */, - DC5ABDDB1D832E4000CF422C /* keychain_import.c in Sources */, - DC5ABDDC1D832E4000CF422C /* keychain_list.c in Sources */, - DC5ABDDD1D832E4000CF422C /* keychain_lock.c in Sources */, - DC5ABDDE1D832E4000CF422C /* keychain_recode.c in Sources */, - DC5ABDDF1D832E4000CF422C /* keychain_set_settings.c in Sources */, - DC5ABDE01D832E4000CF422C /* keychain_show_info.c in Sources */, - DC5ABDE11D832E4000CF422C /* keychain_unlock.c in Sources */, - DC5ABDE21D832E4000CF422C /* keychain_utilities.c in Sources */, - DC5ABDE31D832E4000CF422C /* leaks.c in Sources */, - DC5ABDE41D832E4000CF422C /* readline.c in Sources */, - DC5ABDE51D832E4000CF422C /* security.c in Sources */, - DC5ABDEE1D832E4E00CF422C /* smartcards.m in Sources */, - DC5ABDE61D832E4000CF422C /* trusted_cert_add.c in Sources */, - DC5ABDE71D832E4000CF422C /* trusted_cert_utils.c in Sources */, - DC5ABDE81D832E4000CF422C /* trust_settings_impexp.c in Sources */, - DC5ABDE91D832E4000CF422C /* user_trust_enable.cpp in Sources */, - DC5ABDEA1D832E4000CF422C /* authz.c in Sources */, - DC5ABDEB1D832E4000CF422C /* verify_cert.c in Sources */, - DC5ABDEC1D832E4000CF422C /* access_utils.c in Sources */, - DC5ABDED1D832E4000CF422C /* translocate.c in Sources */, - F9C8AFD222374D1100E7D6AE /* requirement.c in Sources */, + DCF787221D88BA0100E694BB /* SSCSPSession.cpp in Sources */, + DCF787261D88BA0100E694BB /* SSDLSession.cpp in Sources */, + DCF7872A1D88BA0100E694BB /* SSKey.cpp in Sources */, + DCF7871E1D88BA0100E694BB /* SSContext.cpp in Sources */, + DCF787201D88BA0100E694BB /* SSCSPDLSession.cpp in Sources */, + DCF7871C1D88BA0100E694BB /* CSPDLPlugin.cpp in Sources */, + DCF787241D88BA0100E694BB /* SSDatabase.cpp in Sources */, + DCF7871A1D88BA0100E694BB /* CSPDLDatabase.cpp in Sources */, + DCF787281D88BA0100E694BB /* SSFactory.cpp in Sources */, + DCF787301D88C18A00E694BB /* AppleCSPDLBuiltin.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC5AC04C1D8352D900CF422C /* Sources */ = { + DCF787AE1D88C86900E694BB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC5AC1031D83552000CF422C /* selfServer.cpp in Sources */, - DC5AC1041D83552000CF422C /* selfUser.cpp in Sources */, - DC5AC0D81D8354CA00CF422C /* main.cpp in Sources */, - DC5AC0D91D8354CA00CF422C /* connection.cpp in Sources */, - DC5AC0DA1D8354CA00CF422C /* database.cpp in Sources */, - DC5AC0DB1D8354CA00CF422C /* key.cpp in Sources */, - DC5AC0DC1D8354CA00CF422C /* process.cpp in Sources */, - DC5AC0DD1D8354CA00CF422C /* server.cpp in Sources */, - DC5AC0DE1D8354CA00CF422C /* session.cpp in Sources */, - DC5AC0DF1D8354CA00CF422C /* structure.cpp in Sources */, - DC5AC0E01D8354CA00CF422C /* dbcrypto.cpp in Sources */, - DC5AC0E11D8354CA00CF422C /* localdatabase.cpp in Sources */, - DC5AC0E21D8354CA00CF422C /* localkey.cpp in Sources */, - DC5AC0E31D8354CA00CF422C /* kcdatabase.cpp in Sources */, - DC5AC0E41D8354CA00CF422C /* kckey.cpp in Sources */, - DC5AC0E51D8354CA00CF422C /* tempdatabase.cpp in Sources */, - DC5AC0E61D8354CA00CF422C /* tokendatabase.cpp in Sources */, - DC5AC0E71D8354CA00CF422C /* tokenkey.cpp in Sources */, - DC5AC0E81D8354CA00CF422C /* tokenaccess.cpp in Sources */, - DC5AC0E91D8354CA00CF422C /* pcscmonitor.cpp in Sources */, - DC5AC0EA1D8354CA00CF422C /* reader.cpp in Sources */, - DC5AC0EB1D8354CA00CF422C /* token.cpp in Sources */, - DC5AC0EC1D8354CA00CF422C /* tokend.cpp in Sources */, - DC5AC0ED1D8354CA00CF422C /* tokencache.cpp in Sources */, - DC5AC0EE1D8354CA00CF422C /* transition.cpp in Sources */, - DC5AC0EF1D8354CA00CF422C /* acls.cpp in Sources */, - DC5AC0F01D8354CA00CF422C /* tokenacl.cpp in Sources */, - DC5AC0F11D8354CA00CF422C /* acl_keychain.cpp in Sources */, - DC5AC0F21D8354CA00CF422C /* acl_partition.cpp in Sources */, - DC5AC0F31D8354CA00CF422C /* authhost.cpp in Sources */, - DC5AC0F41D8354CA00CF422C /* credential.cpp in Sources */, - DC5AC0F51D8354CA00CF422C /* clientid.cpp in Sources */, - DC5AC0F61D8354CA00CF422C /* codesigdb.cpp in Sources */, - DC5AC0F71D8354CA00CF422C /* csproxy.cpp in Sources */, - DC5AC0F81D8354CA00CF422C /* agentquery.cpp in Sources */, - DC5AC0F91D8354CA00CF422C /* auditevents.cpp in Sources */, - DC5AC0FA1D8354CA00CF422C /* ccaudit_extensions.cpp in Sources */, - DC5AC0FB1D8354CA00CF422C /* child.cpp in Sources */, - DC5AC0FD1D8354CA00CF422C /* notifications.cpp in Sources */, - DC5AC0FE1D8354CA00CF422C /* SharedMemoryServer.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC610A171D78F129002223DE /* Sources */ = { + DCF788361D88C8C400E694BB /* Sources */ = { 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 */, - DC5F35B01EE0F27C00900966 /* server_entitlement_helpers.c in Sources */, - DC4269121E82FDA1002B7110 /* server_security_helpers.c in Sources */, - DCB2215A1E8B08CB001598BC /* server_xpc.m in Sources */, - DC4269011E82038D002B7110 /* server_endpoint.m in Sources */, + DCF788441D88C8FF00E694BB /* AppleDLBuiltin.cpp in Sources */, + DCF788411D88C8DE00E694BB /* AppleFileDL.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC610A431D78F48F002223DE /* Sources */ = { + DCF788491D88CA7200E694BB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC610A501D78F715002223DE /* main.c in Sources */, + DCF788751D88CABC00E694BB /* AppleX509CL.cpp in Sources */, + DCF788871D88CABC00E694BB /* clNssUtils.cpp in Sources */, + DCF788921D88CABC00E694BB /* DecodedItem.cpp in Sources */, + DCF788851D88CABC00E694BB /* clNameUtils.cpp in Sources */, + DCF788951D88CABC00E694BB /* Session_Cert.cpp in Sources */, + DCF788831D88CABC00E694BB /* CLFieldsCommon.cpp in Sources */, + DCF7888C1D88CABC00E694BB /* DecodedCert.cpp in Sources */, + DCF788771D88CABC00E694BB /* AppleX509CLBuiltin.cpp in Sources */, + DCF7887B1D88CABC00E694BB /* CertFields.cpp in Sources */, + DCF788791D88CABC00E694BB /* AppleX509CLSession.cpp in Sources */, + DCF7888A1D88CABC00E694BB /* CSPAttacher.cpp in Sources */, + DCF788801D88CABC00E694BB /* CLCrlExtensions.cpp in Sources */, + DCF788781D88CABC00E694BB /* AppleX509CLPlugin.cpp in Sources */, + DCF7887C1D88CABC00E694BB /* CLCachedEntry.cpp in Sources */, + DCF7888E1D88CABC00E694BB /* DecodedCrl.cpp in Sources */, + DCF788891D88CABC00E694BB /* CrlFields.cpp in Sources */, + DCF788981D88CABC00E694BB /* Session_CSR.cpp in Sources */, + DCF788961D88CABC00E694BB /* Session_CRL.cpp in Sources */, + DCF788901D88CABC00E694BB /* DecodedExtensions.cpp in Sources */, + DCF7887E1D88CABC00E694BB /* CLCertExtensions.cpp in Sources */, + DCF788971D88CABC00E694BB /* Session_Crypto.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC610A561D78F9D2002223DE /* Sources */ = { + DCF788991D88CB5200E694BB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC610A611D78F9F2002223DE /* FatDynamicValidation.c in Sources */, + DCF788A51D88CB6800E694BB /* AppleX509CLPlugin.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC610AAE1D7910C3002223DE /* Sources */ = { + DCF788BC1D88CD2400E694BB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC610ABA1D7910F8002223DE /* gk_reset_check.c in Sources */, + DCF789341D88CD6700E694BB /* TPDatabase.cpp in Sources */, + DCF7892B1D88CD6700E694BB /* TPCertInfo.cpp in Sources */, + DCF789211D88CD6700E694BB /* AppleTP.cpp in Sources */, + DCF789391D88CD6700E694BB /* ocspRequest.cpp in Sources */, + DCF789371D88CD6700E694BB /* TPNetwork.cpp in Sources */, + DCF789321D88CD6700E694BB /* tpCrlVerify.cpp in Sources */, + DCF789231D88CD6700E694BB /* AppleTPSession.cpp in Sources */, + DCF789281D88CD6700E694BB /* cuEnc64.c in Sources */, + DCF789411D88CD6700E694BB /* tpPolicies.cpp in Sources */, + DCF789481D88D17C00E694BB /* AppleX509TPBuiltin.cpp in Sources */, + DCF7893F1D88CD6700E694BB /* tpOcspVerify.cpp in Sources */, + DCF789301D88CD6700E694BB /* TPCrlInfo.cpp in Sources */, + DCF789431D88CD6700E694BB /* tpTime.c in Sources */, + DCF789261D88CD6700E694BB /* certGroupUtils.cpp in Sources */, + DCF7893B1D88CD6700E694BB /* tpOcspCache.cpp in Sources */, + DCF7892A1D88CD6700E694BB /* tpCertGroup.cpp in Sources */, + DCF7893D1D88CD6700E694BB /* tpOcspCertVfy.cpp in Sources */, + DCF7892F1D88CD6700E694BB /* tpCredRequest.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC6A828E1D87749900418608 /* Sources */ = { + E060D1982124780E0025B833 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; - files = ( - DC6A82B11D87769800418608 /* dictionary.cpp in Sources */, - DC6A82B21D87769800418608 /* sec_xdr.c in Sources */, - DC6A82B31D87769800418608 /* sec_xdr_array.c in Sources */, - DC6A82B41D87769800418608 /* sec_xdr_reference.c in Sources */, - DC6A82B51D87769800418608 /* sec_xdrmem.c in Sources */, - DC6A82B61D87769800418608 /* sec_xdr_sizeof.c in Sources */, - DC6A82B71D87769800418608 /* xdr_auth.c in Sources */, - DC6A82B81D87769800418608 /* xdr_cssm.c in Sources */, - DC6A82B91D87769800418608 /* xdr_dldb.cpp in Sources */, - DC6A82BA1D87769800418608 /* SharedMemoryClient.cpp in Sources */, - DC6A82BB1D87769800418608 /* eventlistener.cpp in Sources */, - DC6A82C41D8776D800418608 /* ssblob.cpp in Sources */, - DC6A82BC1D87769800418608 /* ssclient.cpp in Sources */, - DC6A82BD1D87769800418608 /* sstransit.cpp in Sources */, - DC6A82BE1D87769800418608 /* transition.cpp in Sources */, - DC6A82BF1D8776B300418608 /* ucspClient.cpp in Sources */, - DC6A82C01D8776B300418608 /* ucspNotifySender.cpp in Sources */, - DC6A82C11D8776B900418608 /* cshostingClient.cpp in Sources */, - DC6A82C21D8776B900418608 /* cshostingServer.cpp in Sources */, + files = ( + EB3F9C9D21FCFD67007B6EBA /* OctagonTestHarness.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC71D9C31D95BA6C0065FB93 /* Sources */ = { + E060D1A32124780F0025B833 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC71D9C41D95BA6C0065FB93 /* X509Templates.c in Sources */, - DC71D9C51D95BA6C0065FB93 /* keyTemplates.c in Sources */, - DC71D9C61D95BA6C0065FB93 /* SecAsn1Templates.c in Sources */, - DC71D9C71D95BA6C0065FB93 /* osKeyTemplates.c in Sources */, - DC71D9C81D95BA6C0065FB93 /* nsprPortX.c in Sources */, - DC71D9C91D95BA6C0065FB93 /* nameTemplates.c in Sources */, - DC71D9CA1D95BA6C0065FB93 /* pkcs7Templates.c in Sources */, - DC71D9CB1D95BA6C0065FB93 /* plarena.c in Sources */, - DC71D9CC1D95BA6C0065FB93 /* secasn1e.c in Sources */, - DC71D9CD1D95BA6C0065FB93 /* SecNssCoder.cpp in Sources */, - DC71D9CE1D95BA6C0065FB93 /* oidsalg.c in Sources */, - DC71D9CF1D95BA6C0065FB93 /* ocspTemplates.c in Sources */, - DC71D9D01D95BA6C0065FB93 /* certExtensionTemplates.c in Sources */, - DC71D9D11D95BA6C0065FB93 /* secport.c in Sources */, - DC71D9D21D95BA6C0065FB93 /* nssUtils.c in Sources */, - DC71D9D31D95BA6C0065FB93 /* pkcs12Templates.c in Sources */, - DC71D9D41D95BA6C0065FB93 /* csrTemplates.c in Sources */, - DC71D9D51D95BA6C0065FB93 /* oidsattr.c in Sources */, - DC71D9D61D95BA6C0065FB93 /* secErrorStr.c in Sources */, - DC71D9D71D95BA6C0065FB93 /* oidsocsp.c in Sources */, - DC71D9D81D95BA6C0065FB93 /* secasn1d.c in Sources */, - DC71D9D91D95BA6C0065FB93 /* SecAsn1Coder.c in Sources */, - DC71D9DA1D95BA6C0065FB93 /* secasn1u.c in Sources */, + E060D24721247C680025B833 /* OctagonTestHarnessXPCServiceProtocol.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DC8834031D8A218F00CE0ACA /* Sources */ = { + E060D1B3212478110025B833 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DC88348D1D8A21AB00CE0ACA /* X509Templates.c in Sources */, - DC88345B1D8A21AA00CE0ACA /* keyTemplates.c in Sources */, - DC8834541D8A21AA00CE0ACA /* SecAsn1Templates.c in Sources */, - DC88348F1D8A21AB00CE0ACA /* osKeyTemplates.c in Sources */, - DC8834631D8A21AA00CE0ACA /* nsprPortX.c in Sources */, - DC88345D1D8A21AA00CE0ACA /* nameTemplates.c in Sources */, - DC88345F1D8A21AA00CE0ACA /* pkcs7Templates.c in Sources */, - DC88346B1D8A21AA00CE0ACA /* plarena.c in Sources */, - DC8834831D8A21AB00CE0ACA /* secasn1e.c in Sources */, - DC8834891D8A21AB00CE0ACA /* SecNssCoder.cpp in Sources */, - DC8834911D8A21AB00CE0ACA /* oidsalg.c in Sources */, - DC8834691D8A21AA00CE0ACA /* ocspTemplates.c in Sources */, - DC8834571D8A21AA00CE0ACA /* certExtensionTemplates.c in Sources */, - DC88348B1D8A21AB00CE0ACA /* secport.c in Sources */, - DC8834671D8A21AA00CE0ACA /* nssUtils.c in Sources */, - DC8834611D8A21AA00CE0ACA /* pkcs12Templates.c in Sources */, - DC8834591D8A21AA00CE0ACA /* csrTemplates.c in Sources */, - DC8834931D8A21AB00CE0ACA /* oidsattr.c in Sources */, - DC8834881D8A21AB00CE0ACA /* secErrorStr.c in Sources */, - DC8834961D8A21AB00CE0ACA /* oidsocsp.c in Sources */, - DC8834821D8A21AB00CE0ACA /* secasn1d.c in Sources */, - DC8834521D8A21AA00CE0ACA /* SecAsn1Coder.c in Sources */, - DC8834851D8A21AB00CE0ACA /* secasn1u.c in Sources */, + E09E09EB215506650042C7D3 /* OctagonTestHarnessXPCService.m in Sources */, + EBFF95ED214C80880021CD14 /* SecRemoteDevice.m in Sources */, + E060D1BF212478120025B833 /* main.m in Sources */, + EBFF95EE214C80B90021CD14 /* OctagonTestHarnessXPCServiceDelegate.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCB340681D8A24DF0054D16E /* Sources */ = { + E710C73E1331946400F85568 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCB340881D8A24F70054D16E /* trampolineServer.cpp in Sources */, - DCB340841D8A24F70054D16E /* Authorization.cpp in Sources */, - DCB3407D1D8A24F70054D16E /* Authorization.c in Sources */, - DC0BC5831D8B709F00070CB0 /* authutilities.c in Sources */, - DCB340871D8A24F70054D16E /* trampolineClient.cpp in Sources */, + 476541A31F33EDCC00413F65 /* SecdWatchdog.m in Sources */, + 4CC92B1C15A3BF2F00C6D578 /* testmain.c in Sources */, + 0C78F1CC16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */, + DCCD33D11E3FEF2C00AA4AD1 /* spi.c in Sources */, + DCB221541E8B08BE001598BC /* server_xpc.m in Sources */, + DC42690D1E82FD9B002B7110 /* server_security_helpers.m in Sources */, + DC4268FC1E820370002B7110 /* server_endpoint.m in Sources */, + DC5F35AB1EE0F27100900966 /* server_entitlement_helpers.c in Sources */, + 0C78F1CE16A5E1BF00654E08 /* sectask_ipc.defs in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCB340901D8A267C0054D16E /* Sources */ = { + E7B01BC2166594AB000485F1 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCB340CC1D8A26AE0054D16E /* dlclient.cpp in Sources */, - DCB340DF1D8A26AE0054D16E /* mdsclient.cpp in Sources */, - DCB340E91D8A26AE0054D16E /* tpclient.cpp in Sources */, - DCB340CA1D8A26AE0054D16E /* cssmclient.cpp in Sources */, - DCB340C61D8A26AE0054D16E /* cryptoclient.cpp in Sources */, - DCB340C21D8A26AE0054D16E /* aclclient.cpp in Sources */, - DCB340D51D8A26AE0054D16E /* DLDBList.cpp in Sources */, - DCB340C41D8A26AE0054D16E /* clclient.cpp in Sources */, - DCB340E71D8A26AE0054D16E /* signclient.cpp in Sources */, - DCB340D71D8A26AE0054D16E /* genkey.cpp in Sources */, - DCB340DD1D8A26AE0054D16E /* macclient.cpp in Sources */, - DCB340EB1D8A26AE0054D16E /* wrapkey.cpp in Sources */, - DCB340D91D8A26AE0054D16E /* keychainacl.cpp in Sources */, - DCB340CF1D8A26AE0054D16E /* dliterators.cpp in Sources */, - DCB340E11D8A26AE0054D16E /* mds_standard.cpp in Sources */, - DCB340D31D8A26AE0054D16E /* dl_standard.cpp in Sources */, - DCB340E51D8A26AE0054D16E /* securestorage.cpp in Sources */, - DCB340DB1D8A26AE0054D16E /* keyclient.cpp in Sources */, - DCB340D11D8A26AE0054D16E /* dlquery.cpp in Sources */, - DCB340C81D8A26AE0054D16E /* cspclient.cpp in Sources */, - DCB340CD1D8A26AE0054D16E /* dlclientpriv.cpp in Sources */, - DCB340E31D8A26AE0054D16E /* multidldb.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCB341321D8A2A010054D16E /* Sources */ = { + E7D847C01C6BE9710025BB44 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCB3416E1D8A2A340054D16E /* ACabstractsession.cpp in Sources */, - DCB341701D8A2A340054D16E /* CSPabstractsession.cpp in Sources */, - DCB341711D8A2A340054D16E /* DLabstractsession.cpp in Sources */, - DCB341641D8A2A340054D16E /* DatabaseSession.cpp in Sources */, - DCB3415D1D8A2A340054D16E /* CSPsession.cpp in Sources */, - DCB3415F1D8A2A340054D16E /* csputilities.cpp in Sources */, - DCB341661D8A2A340054D16E /* DbContext.cpp in Sources */, - DCB341621D8A2A340054D16E /* Database.cpp in Sources */, - DCB3416A1D8A2A340054D16E /* pluginsession.cpp in Sources */, - DCB341601D8A2A340054D16E /* cssmplugin.cpp in Sources */, - DCB341721D8A2A340054D16E /* TPabstractsession.cpp in Sources */, - DCB341681D8A2A340054D16E /* DLsession.cpp in Sources */, - DCB3416F1D8A2A340054D16E /* CLabstractsession.cpp in Sources */, + EB413B801E663AEB00592085 /* PairingChannel.m in Sources */, + 0CB72D9E21E42FCF00D8BC9B /* OTPairingMessage.m in Sources */, + 0CB72DA121E42FCF00D8BC9B /* OTSponsorToApplicantRound2M2.m in Sources */, + E7F480151C73980D00390FDB /* KCJoiningRequestSecretSession.m in Sources */, + E7F480331C73FC4C00390FDB /* KCAESGCMDuplexSession.m in Sources */, + 0CB72D9F21E42FCF00D8BC9B /* OTSOSMessage.m in Sources */, + DC6063B221B09AB200069B82 /* KCJoiningRequestCircleSession.m in Sources */, + E794BB001C7598F900339A0F /* KCJoiningMessages.m in Sources */, + 5A47FFB9228F5F2A00F781B8 /* KCInitialMessageData.m in Sources */, + 0CB72DA021E42FCF00D8BC9B /* OTSponsorToApplicantRound1M2.m in Sources */, + E794BA6F1C7424D800339A0F /* KCDer.m in Sources */, + E7E3EFBA1CBC192A00E79A5D /* KCAccountKCCircleDelegate.m in Sources */, + E7F482AC1C7558F700390FDB /* KCJoiningAcceptSession.m in Sources */, + E71454F01C741E0800B5B20B /* KCError.m in Sources */, + E772FD471CC15EFA00D63E41 /* NSData+SecRandom.m in Sources */, + 0CB72D9D21E42FCF00D8BC9B /* OTApplicantToSponsorRound2M1.m in Sources */, + E7F482AA1C7554FB00390FDB /* NSError+KCCreationHelpers.m in Sources */, + E75C0E831C6FC31D00E6953B /* KCSRPContext.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCB3417D1D8A2B860054D16E /* Sources */ = { + E7D847CA1C6BE9720025BB44 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCB342341D8A2C6B0054D16E /* KeySchema.cpp in Sources */, - DCB342351D8A2C6B0054D16E /* Schema.cpp in Sources */, - DCB341F91D8A2BAD0054D16E /* callback.cpp in Sources */, - DCB341F21D8A2BAC0054D16E /* acl_secret.cpp in Sources */, - DCB342281D8A2BAD0054D16E /* osxverifier.cpp in Sources */, - DCB342231D8A2BAD0054D16E /* handletemplates.cpp in Sources */, - DCB3420A1D8A2BAD0054D16E /* cssmdates.cpp in Sources */, - DCB341EA1D8A2BAC0054D16E /* acl_preauth.cpp in Sources */, - DCB342061D8A2BAD0054D16E /* cssmcred.cpp in Sources */, - DCB341E81D8A2BAC0054D16E /* acl_password.cpp in Sources */, - DCB3421A1D8A2BAD0054D16E /* cssmtrust.cpp in Sources */, - DCB342161D8A2BAD0054D16E /* cssmlist.cpp in Sources */, - DCB341DD1D8A2BAC0054D16E /* objectacl.cpp in Sources */, - DCB342011D8A2BAD0054D16E /* cssmalloc.cpp in Sources */, - DCB3420E1D8A2BAD0054D16E /* cssmdbname.cpp in Sources */, - DCB341F01D8A2BAC0054D16E /* acl_protectedpw.cpp in Sources */, - DCB342211D8A2BAD0054D16E /* handleobject.cpp in Sources */, - DCB3422C1D8A2BAD0054D16E /* uniformrandom.cpp in Sources */, - DCB341EE1D8A2BAC0054D16E /* acl_prompted.cpp in Sources */, - DCB341E41D8A2BAC0054D16E /* acl_codesigning.cpp in Sources */, - DCB342121D8A2BAD0054D16E /* cssmerrors.cpp in Sources */, - DCB3421C1D8A2BAD0054D16E /* cssmwalkers.cpp in Sources */, - DCB341F61D8A2BAD0054D16E /* AuthorizationData.cpp in Sources */, - DCB3421E1D8A2BAD0054D16E /* db++.cpp in Sources */, - DCB3422E1D8A2BAD0054D16E /* walkers.cpp in Sources */, - DCB342181D8A2BAD0054D16E /* cssmpods.cpp in Sources */, - DCB342081D8A2BAD0054D16E /* cssmdata.cpp in Sources */, - DCB341F41D8A2BAC0054D16E /* acl_threshold.cpp in Sources */, - DCB341E11D8A2BAC0054D16E /* cssmacl.cpp in Sources */, - DCB3420C1D8A2BAD0054D16E /* cssmdb.cpp in Sources */, - DCB341DF1D8A2BAC0054D16E /* aclsubject.cpp in Sources */, - DCB342141D8A2BAD0054D16E /* cssmkey.cpp in Sources */, - DCB342101D8A2BAD0054D16E /* cssmendian.cpp in Sources */, - DCB342041D8A2BAD0054D16E /* cssmcert.cpp in Sources */, - DCB341EC1D8A2BAC0054D16E /* acl_process.cpp in Sources */, - DCB341FD1D8A2BAD0054D16E /* context.cpp in Sources */, - DCB341E61D8A2BAC0054D16E /* acl_comment.cpp in Sources */, - DCB341E21D8A2BAC0054D16E /* acl_any.cpp in Sources */, - DCB341FF1D8A2BAD0054D16E /* cssmaclpod.cpp in Sources */, - DCB3422A1D8A2BAD0054D16E /* u32handleobject.cpp in Sources */, - DCB341FB1D8A2BAD0054D16E /* constdata.cpp in Sources */, + E7F4809C1C74E85200390FDB /* KCDerTest.m in Sources */, + E7D848051C6BEFCD0025BB44 /* KCSRPTests.m in Sources */, + E7F4809E1C74E86D00390FDB /* KCAESGCMTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCB3423C1D8A32820054D16E /* Sources */ = { + EB0BC9371C3C791500785842 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCB3433D1D8A32A20054D16E /* ACL.cpp in Sources */, - DCB3433B1D8A32A20054D16E /* Access.cpp in Sources */, - DCB3436A1D8A32A20054D16E /* CCallbackMgr.cp in Sources */, - DCB3433F1D8A32A20054D16E /* Certificate.cpp in Sources */, - DCB343431D8A32A20054D16E /* CertificateValues.cpp in Sources */, - DCB343701D8A32A20054D16E /* DLDBListCFPref.cpp in Sources */, - DCB343721D8A32A20054D16E /* DynamicDLDBList.cpp in Sources */, - DCB343451D8A32A20054D16E /* ExtendedAttribute.cpp in Sources */, - DCB343471D8A32A20054D16E /* Globals.cpp in Sources */, - DCB343491D8A32A20054D16E /* Identity.cpp in Sources */, - DCB3434B1D8A32A20054D16E /* IdentityCursor.cpp in Sources */, - DCB3434D1D8A32A20054D16E /* Item.cpp in Sources */, - DCB3434F1D8A32A20054D16E /* KCCursor.cpp in Sources */, - DCB343741D8A32A20054D16E /* KCEventNotifier.cpp in Sources */, - DCB343771D8A32A20054D16E /* KCUtilities.cpp in Sources */, - DCB343531D8A32A20054D16E /* KeyItem.cpp in Sources */, - DCB343511D8A32A20054D16E /* Keychains.cpp in Sources */, - DCB343551D8A32A20054D16E /* Password.cpp in Sources */, - DCB343571D8A32A20054D16E /* Policies.cpp in Sources */, - DCB343591D8A32A20054D16E /* PolicyCursor.cpp in Sources */, - DCB3437A1D8A32A20054D16E /* PrimaryKey.cpp in Sources */, - DCB342FA1D8A32A20054D16E /* SecACL.cpp in Sources */, - DCB342F91D8A32A20054D16E /* SecAccess.cpp in Sources */, - DCB342FB1D8A32A20054D16E /* SecBase.cpp in Sources */, - DCB3435B1D8A32A20054D16E /* SecCFTypes.cpp in Sources */, - DCB342FD1D8A32A20054D16E /* SecCertificate.cpp in Sources */, - DCB342FE1D8A32A20054D16E /* SecCertificateBundle.cpp in Sources */, - DCB343921D8A32A20054D16E /* SecExport.cpp in Sources */, - DCB343931D8A32A20054D16E /* SecExternalRep.cpp in Sources */, - DCB343371D8A32A20054D16E /* SecFDERecoveryAsymmetricCrypto.cpp in Sources */, - DCB343001D8A32A20054D16E /* SecIdentity.cpp in Sources */, - DCB343011D8A32A20054D16E /* SecIdentitySearch.cpp in Sources */, - DCB343951D8A32A20054D16E /* SecImport.cpp in Sources */, - DCB343961D8A32A20054D16E /* SecImportExport.c in Sources */, - DCB343971D8A32A20054D16E /* SecImportExportAgg.cpp in Sources */, - DCB343991D8A32A20054D16E /* SecImportExportCrypto.cpp in Sources */, - DCB3439B1D8A32A20054D16E /* SecImportExportOpenSSH.cpp in Sources */, - DCB3439D1D8A32A20054D16E /* SecImportExportPem.cpp in Sources */, - DCB3439F1D8A32A20054D16E /* SecImportExportPkcs8.cpp in Sources */, - DCB343A11D8A32A20054D16E /* SecImportExportUtils.cpp in Sources */, - DCB343031D8A32A20054D16E /* SecItem.cpp in Sources */, - DCB343021D8A32A20054D16E /* SecItemConstants.c in Sources */, - DCB343041D8A32A20054D16E /* SecKey.cpp in Sources */, - DCB343051D8A32A20054D16E /* SecKeychain.cpp in Sources */, - DCB3435D1D8A32A20054D16E /* SecKeychainAddIToolsPassword.cpp in Sources */, - DCB343061D8A32A20054D16E /* SecKeychainItem.cpp in Sources */, - DCB343071D8A32A20054D16E /* SecKeychainItemExtendedAttributes.cpp in Sources */, - DCB343081D8A32A20054D16E /* SecKeychainSearch.cpp in Sources */, - DCB343A31D8A32A20054D16E /* SecNetscapeTemplates.cpp in Sources */, - DCB343091D8A32A20054D16E /* SecPassword.cpp in Sources */, - DCB343A51D8A32A20054D16E /* SecPkcs8Templates.cpp in Sources */, - DCB3430A1D8A32A20054D16E /* SecPolicy.cpp in Sources */, - DCB3430B1D8A32A20054D16E /* SecPolicySearch.cpp in Sources */, - DCB343361D8A32A20054D16E /* SecRandom.c in Sources */, - DCB343391D8A32A20054D16E /* SecRecoveryPassword.c in Sources */, - DCB3430C1D8A32A20054D16E /* SecTrust.cpp in Sources */, - DCB343671D8A32A20054D16E /* SecTrustOSXEntryPoints.cpp in Sources */, - DCB3430E1D8A32A20054D16E /* SecTrustSettings.cpp in Sources */, - DCB3430D1D8A32A20054D16E /* SecTrustedApplication.cpp in Sources */, - DCB343A71D8A32A20054D16E /* SecWrappedKeys.cpp in Sources */, - DCB3435E1D8A32A20054D16E /* StorageManager.cpp in Sources */, - DCB343901D8A32A20054D16E /* TokenLogin.cpp in Sources */, - DCB3435F1D8A32A20054D16E /* Trust.cpp in Sources */, - DCB3437E1D8A32A20054D16E /* TrustAdditions.cpp in Sources */, - DCB343801D8A32A20054D16E /* TrustItem.cpp in Sources */, - DCB343611D8A32A20054D16E /* TrustRevocation.cpp in Sources */, - DCB343641D8A32A20054D16E /* TrustSettings.cpp in Sources */, - DCB343861D8A32A20054D16E /* TrustSettingsUtils.cpp in Sources */, - DCB343821D8A32A20054D16E /* TrustStore.cpp in Sources */, - DCB343621D8A32A20054D16E /* TrustedApplication.cpp in Sources */, - DCB343841D8A32A20054D16E /* UnlockReferralItem.cpp in Sources */, - DCB3436C1D8A32A20054D16E /* cssmdatetime.cpp in Sources */, - DCB3436E1D8A32A20054D16E /* defaultcreds.cpp in Sources */, - DCB3438E1D8A32A20054D16E /* tsaDERUtilities.c in Sources */, + EB0BC9671C3C798600785842 /* secedumodetest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCB343E91D8A34FD0054D16E /* Sources */ = { + EB1055711E14DF430003C309 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 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 */, - DCB344801D8A35270054D16E /* kc-05-find-existing-items-locked.c in Sources */, - DCB3447F1D8A35270054D16E /* kc-05-find-existing-items.c in Sources */, - DCB344811D8A35270054D16E /* kc-06-cert-search-email.m in Sources */, - DCB344841D8A35270054D16E /* kc-10-item-add-certificate.c in Sources */, - DCB344821D8A35270054D16E /* kc-10-item-add-generic.c in Sources */, - DCB344831D8A35270054D16E /* kc-10-item-add-internet.c in Sources */, - DCB344871D8A35270054D16E /* kc-12-item-create-keypair.c in Sources */, - DCB344861D8A35270054D16E /* kc-12-key-create-symmetric-and-use.m in Sources */, - DCB344851D8A35270054D16E /* kc-12-key-create-symmetric.c in Sources */, - DCB344891D8A35270054D16E /* kc-15-item-update-label-skimaad.m in Sources */, - DCB344881D8A35270054D16E /* kc-15-key-update-valueref.c in Sources */, - DCB3448A1D8A35270054D16E /* kc-16-item-update-password.c in Sources */, - DCB3448B1D8A35270054D16E /* kc-18-find-combined.c in Sources */, - DCB3448C1D8A35270054D16E /* kc-19-item-copy-internet.c in Sources */, - DCB344921D8A35270054D16E /* kc-20-identity-find-stress.c in Sources */, - DCB3448E1D8A35270054D16E /* kc-20-identity-key-attributes.c in Sources */, - DCB3448D1D8A35270054D16E /* kc-20-identity-persistent-refs.c in Sources */, - DCB344901D8A35270054D16E /* kc-20-item-add-stress.c in Sources */, - DCB3448F1D8A35270054D16E /* kc-20-item-find-stress.c in Sources */, - DCB344911D8A35270054D16E /* kc-20-key-find-stress.c in Sources */, - DCCBFA1E1DBA95CD001DD54D /* kc-20-item-delete-stress.c in Sources */, - DCB344931D8A35270054D16E /* kc-21-item-use-callback.c in Sources */, - DCB344941D8A35270054D16E /* kc-21-item-xattrs.c in Sources */, - DCB344951D8A35270054D16E /* kc-23-key-export-symmetric.m in Sources */, - DCB344961D8A35270054D16E /* kc-24-key-copy-keychains.c in Sources */, - DCB344971D8A35270054D16E /* kc-26-key-import-public.m in Sources */, - DCB344981D8A35270054D16E /* kc-27-key-non-extractable.c in Sources */, - DCB3449A1D8A35270054D16E /* kc-28-cert-sign.c in Sources */, - 6CA837642210CA8A002770F1 /* kc-45-change-password.c in Sources */, - DCB344991D8A35270054D16E /* kc-28-p12-import.m in Sources */, - DCB3449B1D8A35270054D16E /* kc-30-xara.c in Sources */, - DCB344A01D8A35270054D16E /* kc-40-seckey.m in Sources */, - DCB344A11D8A35270054D16E /* kc-41-sececkey.m in Sources */, - DCB344A31D8A35270054D16E /* kc-42-trust-revocation.c in Sources */, - DCB344A21D8A35270054D16E /* kc-43-seckey-interop.m in Sources */, - DCB344A41D8A35270054D16E /* si-20-sectrust-provisioning.c in Sources */, - DCB344A61D8A35270054D16E /* si-33-keychain-backup.c in Sources */, - DCB344A71D8A35270054D16E /* si-34-one-true-keychain.c in Sources */, + EB1055791E14DF570003C309 /* SecCertificateFuzzer.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCC78EA51D8088E200865A7C /* Sources */ = { + EB108F251E6CE4D2003B0456 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0CAD1E581E1C5C6C00537693 /* SOSCloudCircle.m in Sources */, - DC5B391A20C08B70005B09F6 /* SecBase.c in Sources */, - DCC78EE71D808B2F00865A7C /* secViewDisplay.c in Sources */, - DCC78EE61D808B2A00865A7C /* SecAccessControl.m in Sources */, - DCC78EE51D808B2100865A7C /* SecBase64.c in Sources */, - DCC78EE41D808B1B00865A7C /* SecCFAllocator.c in Sources */, - DCC78EE31D808B1300865A7C /* SecCMS.c in Sources */, - BEEB47D91EA189F5004AA5C6 /* SecTrustStatusCodes.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.m in Sources */, - DCC78EDB1D808ADF00865A7C /* SecEMCS.m 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.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 */, - DCC78ECC1D808A6B00865A7C /* SecOTRSession.c in Sources */, - DCC78ECB1D808A6600865A7C /* SecOTRSessionAKE.c in Sources */, - DCC78ECA1D808A6000865A7C /* SecOTRUtils.c in Sources */, - DCC78EC91D808A5700865A7C /* SecPBKDF.c in Sources */, - DCC78EC81D808A5200865A7C /* SecPasswordGenerate.c in Sources */, - DCC78EC71D808A4D00865A7C /* SecPolicy.c in Sources */, - DCC78EC61D808A4700865A7C /* SecPolicyLeafCallbacks.c in Sources */, - DCC78EC51D808A4100865A7C /* SecRSAKey.c in Sources */, - DCC78EC41D808A3B00865A7C /* SecSCEP.c in Sources */, - DCC78EC31D808A2E00865A7C /* SecServerEncryptionSupport.c in Sources */, - DCC78EC21D808A2800865A7C /* SecSharedCredential.c in Sources */, - DCC78EC11D808A2200865A7C /* SecSignatureVerificationSupport.c in Sources */, - DCC78EC01D808A1C00865A7C /* SecTrust.c in Sources */, - DCC78EBE1D808A0E00865A7C /* SecTrustStore.c in Sources */, - DCC78EBD1D808A0400865A7C /* SecuritydXPC.c in Sources */, - DCC78EBC1D8089CD00865A7C /* verify_cert.c in Sources */, - DCC78EBB1D8089C200865A7C /* p12import.c in Sources */, - D425EC1D1DD3C3CF00DE5DEC /* SecInternalRelease.c in Sources */, - DCC78EBA1D8089BD00865A7C /* p12pbegen.c in Sources */, - DCC78EB91D8089A700865A7C /* pbkdf2.c in Sources */, - DCC78EB81D80899C00865A7C /* vmdh.c in Sources */, + 0C5258BA21BB062F00B32C96 /* FakeSOSControl.m in Sources */, + EB108F261E6CE4D2003B0456 /* KCPairingTest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD0677A1D8CDF19007602F1 /* Sources */ = { + EB27FF0D1E402CD300EC9E3A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD069281D8CDFFF007602F1 /* ANTLRUtil.cpp in Sources */, - DCD069291D8CDFFF007602F1 /* ASTFactory.cpp in Sources */, - DCD0692A1D8CDFFF007602F1 /* ASTNULLType.cpp in Sources */, - DCD0692B1D8CDFFF007602F1 /* ASTRefCount.cpp in Sources */, - DCD0692C1D8CDFFF007602F1 /* BaseAST.cpp in Sources */, - DCD0692D1D8CDFFF007602F1 /* BitSet.cpp in Sources */, - DCD0692E1D8CDFFF007602F1 /* CharBuffer.cpp in Sources */, - DCD0692F1D8CDFFF007602F1 /* CharScanner.cpp in Sources */, - DCD0682A1D8CDF7E007602F1 /* Code.cpp in Sources */, - DCD068301D8CDF7E007602F1 /* CodeSigner.cpp in Sources */, - DCD069301D8CDFFF007602F1 /* CommonAST.cpp in Sources */, - DCD069311D8CDFFF007602F1 /* CommonASTWithHiddenTokens.cpp in Sources */, - DCD069321D8CDFFF007602F1 /* CommonHiddenStreamToken.cpp in Sources */, - DCD069331D8CDFFF007602F1 /* CommonToken.cpp in Sources */, - DCD069351D8CDFFF007602F1 /* InputBuffer.cpp in Sources */, - DCD069361D8CDFFF007602F1 /* LLkParser.cpp in Sources */, - DCD069371D8CDFFF007602F1 /* MismatchedCharException.cpp in Sources */, - DCD069381D8CDFFF007602F1 /* MismatchedTokenException.cpp in Sources */, - DCD069391D8CDFFF007602F1 /* NoViableAltException.cpp in Sources */, - DCD0693A1D8CDFFF007602F1 /* NoViableAltForCharException.cpp in Sources */, - DCD0693B1D8CDFFF007602F1 /* Parser.cpp in Sources */, - DCD0693C1D8CDFFF007602F1 /* RecognitionException.cpp in Sources */, - DCD0683A1D8CDF7E007602F1 /* RequirementLexer.cpp in Sources */, - DCD0683C1D8CDF7E007602F1 /* RequirementParser.cpp in Sources */, - DCD0682E1D8CDF7E007602F1 /* Requirements.cpp in Sources */, - DCD068841D8CDF7E007602F1 /* SecAssessment.cpp in Sources */, - DCD0681A1D8CDF7E007602F1 /* SecCode.cpp in Sources */, - DCD068241D8CDF7E007602F1 /* SecCodeHost.cpp in Sources */, - DCD068221D8CDF7E007602F1 /* SecCodeSigner.cpp in Sources */, - DCD068201D8CDF7E007602F1 /* SecRequirement.cpp in Sources */, - DCD0681D1D8CDF7E007602F1 /* SecStaticCode.cpp in Sources */, - DCD0682C1D8CDF7E007602F1 /* StaticCode.cpp in Sources */, - DCD0693D1D8CDFFF007602F1 /* String.cpp in Sources */, - DCD0693E1D8CDFFF007602F1 /* Token.cpp in Sources */, - DCD0693F1D8CDFFF007602F1 /* TokenBuffer.cpp in Sources */, - DCD069401D8CDFFF007602F1 /* TokenRefCount.cpp in Sources */, - DCD069411D8CDFFF007602F1 /* TokenStreamBasicFilter.cpp in Sources */, - DCD069421D8CDFFF007602F1 /* TokenStreamHiddenTokenFilter.cpp in Sources */, - DCD069431D8CDFFF007602F1 /* TokenStreamRewriteEngine.cpp in Sources */, - DCD069441D8CDFFF007602F1 /* TokenStreamSelector.cpp in Sources */, - DCD069451D8CDFFF007602F1 /* TreeParser.cpp in Sources */, - DCD0687F1D8CDF7E007602F1 /* antlrplugin.cpp in Sources */, - 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 */, - DCD068521D8CDF7E007602F1 /* csgeneric.cpp in Sources */, - DCD0684E1D8CDF7E007602F1 /* cskernel.cpp in Sources */, - DCD068501D8CDF7E007602F1 /* csprocess.cpp in Sources */, - DCD068771D8CDF7E007602F1 /* csutilities.cpp in Sources */, - DCD068641D8CDF7E007602F1 /* detachedrep.cpp in Sources */, - DCD0687D1D8CDF7E007602F1 /* dirscanner.cpp in Sources */, - DCD068601D8CDF7E007602F1 /* diskimagerep.cpp in Sources */, - DCD068541D8CDF7E007602F1 /* diskrep.cpp in Sources */, - DCD0684C1D8CDF7E007602F1 /* drmaker.cpp in Sources */, - DCD068861D8CDF7E007602F1 /* evaluationmanager.cpp in Sources */, - DCD068561D8CDF7E007602F1 /* filediskrep.cpp in Sources */, - DCD0685A1D8CDF7E007602F1 /* kerneldiskrep.cpp in Sources */, - DCD0685C1D8CDF7E007602F1 /* machorep.cpp in Sources */, - DCD068881D8CDF7E007602F1 /* opaquewhitelist.cpp in Sources */, - DC5BD5841E8C6FD100C5EC49 /* SecTask.c in Sources */, - DCD068661D8CDF7E007602F1 /* piddiskrep.cpp in Sources */, - DCD0688A1D8CDF7E007602F1 /* policydb.cpp in Sources */, - DCD0688C1D8CDF7E007602F1 /* policyengine.cpp in Sources */, - DCD0687B1D8CDF7E007602F1 /* quarantine++.cpp in Sources */, - DCD0684A1D8CDF7E007602F1 /* reqdumper.cpp in Sources */, - DCD068461D8CDF7E007602F1 /* reqinterp.cpp in Sources */, - DCD068421D8CDF7E007602F1 /* reqmaker.cpp in Sources */, - DCD068481D8CDF7E007602F1 /* reqparser.cpp in Sources */, - DCD068441D8CDF7E007602F1 /* reqreader.cpp in Sources */, - DCD068401D8CDF7E007602F1 /* requirement.cpp in Sources */, - DCD068731D8CDF7E007602F1 /* resources.cpp in Sources */, - DCD068751D8CDF7E007602F1 /* sigblob.cpp in Sources */, - DCD068321D8CDF7E007602F1 /* signer.cpp in Sources */, - DCD068341D8CDF7E007602F1 /* signerutils.cpp in Sources */, - DCD068621D8CDF7E007602F1 /* singlediskrep.cpp in Sources */, - DCD0685E1D8CDF7E007602F1 /* slcrep.cpp in Sources */, - DCD068791D8CDF7E007602F1 /* xar++.cpp in Sources */, - DCD0688E1D8CDF7E007602F1 /* xpcengine.cpp in Sources */, + DC5BCC481E53820200649140 /* SecArgParse.c in Sources */, + EB27FF2D1E407FF600EC9E3A /* ckksctl.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD069E91D8CE21C007602F1 /* Sources */ = { + EB2D54A21F02A45E00E46890 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + EB2D54AB1F02A47200E46890 /* SecAtomicFile.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD06A4B1D8CE281007602F1 /* Sources */ = { + EB425C9F1C65846D000ECE53 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD06A531D8CE2A4007602F1 /* SecCodeHostLib.c in Sources */, + EB425CCF1C658554000ECE53 /* secbackuptest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD06A5F1D8CE2D5007602F1 /* Sources */ = { + EB433A211CC3243600A7EACE /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD06A751D8CE2F0007602F1 /* gkunpack.cpp in Sources */, + EB433A291CC3244C00A7EACE /* secitemstresstest.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD06AAB1D8E0D53007602F1 /* Sources */ = { + EB49B2AA202D877F003F34A0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD06B9C1D8E0D7D007602F1 /* cfmach++.cpp in Sources */, - DCD06B5D1D8E0D7D007602F1 /* hashing.cpp in Sources */, - DCD06B531D8E0D7D007602F1 /* devrandom.cpp in Sources */, - DCD06B8E1D8E0D7D007602F1 /* pcsc++.cpp in Sources */, - DCD06B4B1D8E0D7D007602F1 /* ccaudit.cpp in Sources */, - DCD06BAB1D8E0D7D007602F1 /* cfmunge.cpp in Sources */, - DCD06B6B1D8E0D7D007602F1 /* seccfobject.cpp in Sources */, - DCD06B741D8E0D7D007602F1 /* superblob.cpp in Sources */, - DCD06BA01D8E0D7D007602F1 /* dyldcache.cpp in Sources */, - DCD06B6E1D8E0D7D007602F1 /* simpleprefs.cpp in Sources */, - DCD06B621D8E0D7D007602F1 /* logging.cpp in Sources */, - DCD06B771D8E0D7D007602F1 /* threading.cpp in Sources */, - DCD06B7B1D8E0D7D007602F1 /* tqueue.cpp in Sources */, - DCD06B791D8E0D7D007602F1 /* timeflow.cpp in Sources */, - DCD06B7D1D8E0D7D007602F1 /* trackingallocator.cpp in Sources */, - DCD06B831D8E0D7D007602F1 /* utilities.cpp in Sources */, - DCD06BA31D8E0D7D007602F1 /* machserver.cpp in Sources */, - DCD06BAD1D8E0D7D007602F1 /* cfutilities.cpp in Sources */, - DCD06B9A1D8E0D7D007602F1 /* mach_notify.c in Sources */, - DCD06B431D8E0D7D007602F1 /* crc.c in Sources */, - DCD06B701D8E0D7D007602F1 /* sqlite++.cpp in Sources */, - DCD06B541D8E0D7D007602F1 /* dispatch.cpp in Sources */, - DCD06B3E1D8E0D7D007602F1 /* FileLockTransaction.cpp in Sources */, - DCD06B4A1D8E0D7D007602F1 /* blob.cpp in Sources */, - DCD06B591D8E0D7D007602F1 /* errors.cpp in Sources */, - DCD06B571D8E0D7D007602F1 /* endian.cpp in Sources */, - DCD06B7E1D8E0D7D007602F1 /* transactions.cpp in Sources */, - DCD06B921D8E0D7D007602F1 /* unix++.cpp in Sources */, - DCD06BA71D8E0D7D007602F1 /* coderepository.cpp in Sources */, - DCD06B481D8E0D7D007602F1 /* alloc.cpp in Sources */, - DCD06B961D8E0D7D007602F1 /* vproc++.cpp in Sources */, - DCD06B8C1D8E0D7D007602F1 /* muscle++.cpp in Sources */, - DCD06B461D8E0D7D007602F1 /* adornments.cpp in Sources */, - DCD06B511D8E0D7D007602F1 /* debugging_internal.cpp in Sources */, - DCD06B721D8E0D7D007602F1 /* streams.cpp in Sources */, - DCD06BA91D8E0D7D007602F1 /* cfclass.cpp in Sources */, - DCD06B981D8E0D7D007602F1 /* mach++.cpp in Sources */, - DCD06B941D8E0D7D007602F1 /* unixchild.cpp in Sources */, - DCD06B401D8E0D7D007602F1 /* CSPDLTransaction.cpp in Sources */, - DCD06B9E1D8E0D7D007602F1 /* macho++.cpp in Sources */, - DCD06B661D8E0D7D007602F1 /* osxcode.cpp in Sources */, - DCD06B5B1D8E0D7D007602F1 /* globalizer.cpp in Sources */, - DCD06B681D8E0D7D007602F1 /* powerwatch.cpp in Sources */, - DCD06B4E1D8E0D7D007602F1 /* daemon.cpp in Sources */, - DCD06BA51D8E0D7D007602F1 /* machrunloopserver.cpp in Sources */, - DCD06B8A1D8E0D7D007602F1 /* kq++.cpp in Sources */, + EB9B285921C77E7400173DC2 /* OTDefines.m in Sources */, + 6C32BB9920EAE6B00042DF59 /* LocalKeychainAnalytics.m in Sources */, + EB1E069D211E16260088F0B1 /* mockaksxcbase.m in Sources */, + 0CC3771320A222BC00B58D2D /* SFSignInAnalytics.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.m in Sources */, + EBC73F2B2099785900AE3350 /* SFObjCType.m in Sources */, + 480ADDB22155A0CE00318FC6 /* SOSAnalytics.m in Sources */, + EB49B2E0202DF5D7003F34A0 /* server_entitlement_helpers.c in Sources */, + 5A061196229ED6E8006AF14A /* NSDate+SFAnalytics.m 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 /* mockaksKeychain.m in Sources */, + DC5B391B20C08BDC005B09F6 /* SecFramework.c in Sources */, + EB1E069F211E17C00088F0B1 /* mockaksWatchDog.m in Sources */, + EB49B2D1202DF15F003F34A0 /* SFAnalyticsActivityTracker.m in Sources */, + EB49B2D0202DF14D003F34A0 /* SFAnalytics.m in Sources */, + EBC73F2820993FDA00AE3350 /* SFAnalyticsSampler.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD66D5F1D8204A700DB1393 /* Sources */ = { + EB69528D223B75C300F02C1C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D45917E41DC13E6700752D25 /* SecCertificateRequest.c in Sources */, - DCD66DC01D82054500DB1393 /* SecCertificate.c in Sources */, - DCD66DBF1D82053E00DB1393 /* SecDigest.c in Sources */, - BEEB47DA1EA189F5004AA5C6 /* SecTrustStatusCodes.c in Sources */, - DCD66DBE1D82053700DB1393 /* SecBase64.c in Sources */, - DCD66DB61D82050900DB1393 /* SecKey.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.m in Sources */, - DCD66DB41D82050000DB1393 /* SecRSAKey.c in Sources */, - DCD66DB31D8204FB00DB1393 /* SecServerEncryptionSupport.c in Sources */, - D425EC231DD3FFF200DE5DEC /* SecInternalRelease.c in Sources */, - DCD66DB21D8204F500DB1393 /* SecSignatureVerificationSupport.c in Sources */, + D4BD5E83228A6823001650A7 /* util.m in Sources */, + EB69528E223B75C300F02C1C /* SecDbItem.c in Sources */, + EB69528F223B75C300F02C1C /* SecAKSObjCWrappers.m in Sources */, + EB695290223B75C300F02C1C /* SFKeychainControlManager.m in Sources */, + EB695291223B75C300F02C1C /* SecDbKeychainSerializedSecretData.m in Sources */, + EB695294223B75C300F02C1C /* spi.c in Sources */, + EB695295223B75C300F02C1C /* SecItemDb.c in Sources */, + EB695296223B75C300F02C1C /* SecKeybagSupport.c in Sources */, + EB695297223B75C300F02C1C /* SecDbKeychainMetadataKeyStore.m in Sources */, + EB695298223B75C300F02C1C /* SecdWatchdog.m in Sources */, + EB69529A223B75C300F02C1C /* CheckV12DevEnabled.m in Sources */, + EB69529B223B75C300F02C1C /* SecDbBackupManager.m in Sources */, + EB69529C223B75C300F02C1C /* server.c in Sources */, + EB69529D223B75C300F02C1C /* SecItemSchema.c in Sources */, + EB69529E223B75C300F02C1C /* server_entitlement_helpers.c in Sources */, + EB69529F223B75C300F02C1C /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, + EB6952A0223B75C300F02C1C /* SecItemServer.c in Sources */, + EB6952A1223B75C300F02C1C /* SecDbKeychainItem.m in Sources */, + EB6952A2223B75C300F02C1C /* server_security_helpers.m in Sources */, + EB6952A3223B75C300F02C1C /* SecDbKeychainSerializedMetadata.m in Sources */, + EB6952A4223B75C300F02C1C /* server_xpc.m in Sources */, + EB6952A5223B75C300F02C1C /* SecDbKeychainSerializedItemV7.m in Sources */, + EB6952A6223B75C300F02C1C /* SecDbQuery.c in Sources */, + EB6952A7223B75C300F02C1C /* SecuritydXPC.c in Sources */, + EB6952A8223B75C300F02C1C /* server_endpoint.m in Sources */, + EB6952A9223B75C300F02C1C /* SecDbKeychainItemV7.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB74CC122207E48000F1BBAD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB74CC242207EB9800F1BBAD /* KeychainSettings.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD66DC51D8205C400DB1393 /* Sources */ = { + EB89086721F17D3C00F0DDDB /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD66DDD1D8205FB00DB1393 /* SecOTRDHKey.c in Sources */, - DCD66DDE1D8205FB00DB1393 /* SecOTRFullIdentity.c in Sources */, - DCD66DDF1D8205FB00DB1393 /* SecOTRMath.c in Sources */, - DCD66DE01D8205FB00DB1393 /* SecOTRPacketData.c in Sources */, - DCD66DE11D8205FB00DB1393 /* SecOTRPackets.c in Sources */, - DCD66DE21D8205FB00DB1393 /* SecOTRPublicIdentity.c in Sources */, - DCD66DE31D8205FB00DB1393 /* SecOTRSession.c in Sources */, - DCD66DE41D8205FB00DB1393 /* SecOTRSessionAKE.c in Sources */, - DCD66DDC1D8205E500DB1393 /* SecOTRUtils.c in Sources */, + EB8908AA21F18BBF00F0DDDB /* SecDbItem.c in Sources */, + EB8908BA21F1957300F0DDDB /* SecAKSObjCWrappers.m in Sources */, + EB8908BE21F2181600F0DDDB /* SFKeychainControlManager.m in Sources */, + EB8908B721F1943200F0DDDB /* SecDbKeychainSerializedSecretData.m in Sources */, + EB89086821F17D3C00F0DDDB /* spi.c in Sources */, + EB8908A721F1882300F0DDDB /* SecItemDb.c in Sources */, + EB8908AB21F18BFD00F0DDDB /* SecKeybagSupport.c in Sources */, + EB8908B121F18DB600F0DDDB /* SecDbKeychainMetadataKeyStore.m in Sources */, + EB89086921F17D3C00F0DDDB /* SecdWatchdog.m in Sources */, + EB8908B921F1953100F0DDDB /* CheckV12DevEnabled.m in Sources */, + 6C7094CC2239D21E00C5DAC6 /* SecDbBackupManager.m in Sources */, + EB89086A21F17D3C00F0DDDB /* server.c in Sources */, + EB8908AC21F18C4200F0DDDB /* SecItemSchema.c in Sources */, + D4BD5E87228A6856001650A7 /* util.m in Sources */, + EB89086B21F17D3C00F0DDDB /* server_entitlement_helpers.c in Sources */, + EB8908B821F1944500F0DDDB /* SecDbKeychainSerializedAKSWrappedKey.m in Sources */, + EB8908A921F1888300F0DDDB /* SecItemServer.c in Sources */, + EB8908AE21F18D0E00F0DDDB /* SecDbKeychainItem.m in Sources */, + EB89086C21F17D3C00F0DDDB /* server_security_helpers.m in Sources */, + EB8908B021F18D7B00F0DDDB /* SecDbKeychainSerializedMetadata.m in Sources */, + EB89086D21F17D3C00F0DDDB /* server_xpc.m in Sources */, + EB8908B221F18E1400F0DDDB /* SecDbKeychainSerializedItemV7.m in Sources */, + EB8908A821F1886100F0DDDB /* SecDbQuery.c in Sources */, + EB8908AD21F18CEF00F0DDDB /* SecuritydXPC.c in Sources */, + EB89086E21F17D3C00F0DDDB /* server_endpoint.m in Sources */, + EB8908AF21F18D3500F0DDDB /* SecDbKeychainItemV7.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EB9C1D761BDFD0E000F89272 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EB9C1D7E1BDFD0E100F89272 /* secbackupntest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + EBA9AA7E1CE30E58004E2B68 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + EBA9AA871CE30E6F004E2B68 /* secitemnotifications.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCD8A1071E09EE0F00E4FA0A /* Sources */ = { + EBB839A11E29665D00853BAC /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCD8A19D1E09EEC800E4FA0A /* SOSBackupSliceKeyBag.m in Sources */, - DC2670FB1F3E72C000816EED /* SOSCircleDer.c in Sources */, - EB75B4961E75A44100E469CC /* SOSPiggyback.m in Sources */, - DCD8A1B31E09F12D00E4FA0A /* SOSCircle.c in Sources */, - DCD8A1FF1E09FA6100E4FA0A /* secViewDisplay.c in Sources */, - DCD8A1B41E09F12D00E4FA0A /* SOSCircleV2.c in Sources */, - DCD8A1A01E09EF3500E4FA0A /* SOSCloudKeychainClient.c in Sources */, - DCD8A1DB1E09F5D100E4FA0A /* SOSAccountTrust.m in Sources */, - DCD8A1A11E09EF5C00E4FA0A /* SOSCloudKeychainConstants.c in Sources */, - DCD8A1A91E09F04700E4FA0A /* SOSECWrapUnwrap.c in Sources */, - DCD8A1BD1E09F1D600E4FA0A /* SOSFullPeerInfo.m in Sources */, - DCD8A1B51E09F15400E4FA0A /* SOSGenCount.c in Sources */, - DCD8A19F1E09EF0F00E4FA0A /* SOSInternal.m in Sources */, - EBEEEE3F1EA31E6D00E15F5C /* SOSControlHelper.m in Sources */, - DCD8A1A61E09EFD700E4FA0A /* SOSKVSKeys.m in Sources */, - DCD8A1B61E09F16C00E4FA0A /* SOSKeyedPubKeyIdentifier.c in Sources */, - DCD8A1321E09EE0F00E4FA0A /* SOSPeerInfo.m in Sources */, - DCD8A1A41E09EF9000E4FA0A /* SOSPeerInfoCollections.c in Sources */, - DCD8A1B11E09F11900E4FA0A /* SOSPeerInfoDER.m in Sources */, - 0CE7604C1E12F56800B4381E /* SOSAccountTrustClassic+Identity.m in Sources */, - DCD8A1B21E09F11900E4FA0A /* SOSPeerInfoRingState.m in Sources */, - 0CE7604E1E12F5BA00B4381E /* SOSAccountTrustClassic+Retirement.m in Sources */, - DCD8A1A51E09EFAE00E4FA0A /* SOSPeerInfoV2.m in Sources */, - DCD8A1C21E09F23B00E4FA0A /* SOSRecoveryKeyBag.m in Sources */, - DCD8A1B81E09F1BB00E4FA0A /* SOSRingBackup.m in Sources */, - DCD8A1B91E09F1BB00E4FA0A /* SOSRingBasic.m in Sources */, - DCD8A1BB1E09F1BB00E4FA0A /* SOSRingConcordanceTrust.c in Sources */, - DCD8A1AE1E09F0C500E4FA0A /* SOSRingDER.c in Sources */, - DCD8A1BC1E09F1BB00E4FA0A /* SOSRingPeerInfoUtils.c in Sources */, - DCD8A1BA1E09F1BB00E4FA0A /* SOSRingRecovery.m in Sources */, - DCD8A1B01E09F0F400E4FA0A /* SOSRingTypes.m in Sources */, - DCD8A1AF1E09F0DC00E4FA0A /* SOSRingUtils.c in Sources */, - DCD8A1B71E09F19100E4FA0A /* SOSRingV0.m in Sources */, - DCD8A1C71E09F2B400E4FA0A /* SOSTransport.m in Sources */, - DCD8A1511E09EE0F00E4FA0A /* SOSViews.m in Sources */, - DCD8A19E1E09EEDA00E4FA0A /* SecRecoveryKey.m in Sources */, + EBB839B01E2968AB00853BAC /* secfuzzer.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E6911D7A37FA00AFB96E /* Sources */ = { + EBB851E822F7912400424FD0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCE4E6921D7A37FA00AFB96E /* security_tool_commands.c in Sources */, - DCE4E6931D7A37FA00AFB96E /* NSFileHandle+Formatting.m in Sources */, + EBB8520A22F7914A00424FD0 /* SecTapToRadarTests.m in Sources */, + EBB8520922F7914A00424FD0 /* SecXPCHelperTests.m in Sources */, + EBB852D022F7A13D00424FD0 /* SecInternalRelease.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E74C1D7A43B500AFB96E /* Sources */ = { + EBCF73F41CE45F9C00BED7CA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCE4E7B51D7A43FF00AFB96E /* main.m in Sources */, - DCE4E7B61D7A440A00AFB96E /* bc-10-knife-on-bread.m in Sources */, + EBCF73FD1CE45FAC00BED7CA /* secitemfunctionality.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E7C81D7A4AED00AFB96E /* Sources */ = { + EBF3746E1DC055580065D840 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCE4E7E21D7A4B7F00AFB96E /* main.c in Sources */, - DCE4E7DF1D7A4B4C00AFB96E /* bc-10-knife-on-bread.m in Sources */, + EBF374751DC055590065D840 /* security-sysdiagnose.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E7F21D7A4DA800AFB96E /* Sources */ = { + F621D02A1ED6DCE7000EA569 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - DCCD33CE1E3FEF1700AA4AD1 /* spi.c in Sources */, - 476541701F33B59300413F65 /* SecdWatchdog.m in Sources */, - DCE4E8071D7A4DE200AFB96E /* server.c in Sources */, - DC5F35A61EE0F25000900966 /* server_entitlement_helpers.c in Sources */, - DC4269081E82FD8B002B7110 /* server_security_helpers.c in Sources */, - DCB221501E8B08A5001598BC /* server_xpc.m in Sources */, - DC6ACC461E81E08D00125DC5 /* server_endpoint.m in Sources */, + F619D71E1ED70BC1005B5F46 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E8381D7A57AE00AFB96E /* Sources */ = { + F667EC571E96E9B100203D5C /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D4BEECE81E93094500F76D1A /* trustd.c in Sources */, - DC5F35A91EE0F25300900966 /* server_entitlement_helpers.c in Sources */, + F667EC621E96EAD200203D5C /* main.m in Sources */, + F667EC611E96E9E700203D5C /* authdtests.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - DCE4E8901D7F34F600AFB96E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCE4E8C21D7F353900AFB96E /* server.c in Sources */, - DCE4E8BA1D7F353900AFB96E /* credential.c in Sources */, - DCE4E8BF1D7F353900AFB96E /* object.c in Sources */, - DCE4E8B51D7F353900AFB96E /* authitems.c in Sources */, - DCE4E8B91D7F353900AFB96E /* crc.c in Sources */, - DCE4E8C31D7F353900AFB96E /* session.c in Sources */, - DCE4E8BC1D7F353900AFB96E /* engine.c in Sources */, - DCE4E8C41D7F353900AFB96E /* connection.c in Sources */, - DCE4E8C11D7F353900AFB96E /* rule.c in Sources */, - DCE4E8C01D7F353900AFB96E /* process.c in Sources */, - DCE4E8B31D7F353900AFB96E /* agent.c in Sources */, - DCE4E8BE1D7F353900AFB96E /* mechanism.c in Sources */, - DCE4E8B41D7F353900AFB96E /* authdb.c in Sources */, - DCE4E8B81D7F353900AFB96E /* ccaudit.c in Sources */, - DCE4E8BD1D7F353900AFB96E /* main.c in Sources */, - DCE4E8B71D7F353900AFB96E /* authutilities.c in Sources */, - DCE4E8B61D7F353900AFB96E /* authtoken.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 0C10C93A1DD548B6000602A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = 0C10C9391DD548B6000602A8 /* PBXContainerItemProxy */; + }; + 0C10C93C1DD548BD000602A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 0C10C93B1DD548BD000602A8 /* PBXContainerItemProxy */; + }; + 0C2BCBBC1D0640B200ED7A2F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C2BCBA81D06401F00ED7A2F /* dtlsEchoClient */; + targetProxy = 0C2BCBBB1D0640B200ED7A2F /* PBXContainerItemProxy */; + }; + 0C2BCBD11D0648FA00ED7A2F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + 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 */; + }; + 0C604F0221B8E5090036C175 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */; + targetProxy = 0C604F0121B8E5090036C175 /* PBXContainerItemProxy */; + }; + 0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C8BBEFD1FCB446400580909 /* otctl */; + targetProxy = 0C78CCE41FCC97E7008B4B24 /* PBXContainerItemProxy */; + }; + 0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C8BBEFD1FCB446400580909 /* otctl */; + targetProxy = 0C78CCE61FCC97F1008B4B24 /* PBXContainerItemProxy */; + }; + 0C85DFD81FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = 0C85DFD91FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFDA1FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 0C85DFDB1FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFDC1FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = 0C85DFDD1FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFDE1FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = 0C85DFDF1FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C85DFE01FB38BB6000343A7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 0C85DFE11FB38BB6000343A7 /* PBXContainerItemProxy */; + }; + 0C9AEEBA20783FE000BF6237 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC1789031D77980500B50D50 /* Security_osx */; + targetProxy = 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */; + }; + 0CC593F82299EDFC006C34B5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = 0CC593F72299EDFC006C34B5 /* PBXContainerItemProxy */; + }; + 0CF09210219649DB002B0AEE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */; + targetProxy = 0CF0920F219649DB002B0AEE /* PBXContainerItemProxy */; + }; + 225394B61E30811400D3CD9B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 225394AC1E3080A600D3CD9B /* security_codesigning_ios */; + targetProxy = 225394B51E30811400D3CD9B /* PBXContainerItemProxy */; + }; + 225394DA1E30846800D3CD9B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD067561D8CDCF3007602F1 /* codesigning_DTrace */; + targetProxy = 225394D91E30846800D3CD9B /* PBXContainerItemProxy */; + }; + 226A8B451DEF58EE004C35E3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD06AA91D8E0D53007602F1 /* security_utilities */; + targetProxy = 226A8B441DEF58EE004C35E3 /* 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 */; + }; + 3DD258A2204B7DA800F5DA78 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 3DD258A1204B7DA800F5DA78 /* 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 */; + targetProxy = 478D426E1FD72A8100CAB645 /* PBXContainerItemProxy */; + }; + 478D426F1FD72A8100CAB645 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; + targetProxy = 478D42701FD72A8100CAB645 /* 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 */; + }; + 47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */; + }; + 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; + targetProxy = 47DE88D61FA7ADAC00DD3254 /* PBXContainerItemProxy */; + }; + 47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52EDA61D80D58400B0A59C /* secdRegressions */; + targetProxy = 47DE88D81FA7ADBB00DD3254 /* PBXContainerItemProxy */; + }; + 4C52D0EE16EFCD720079966E /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C52D0B316EFC61E0079966E /* CircleJoinRequested */; + targetProxy = 4C52D0ED16EFCD720079966E /* PBXContainerItemProxy */; + }; + 4C541FA10F250C5200E508AE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C541F840F250BF500E508AE /* Security_executables_ios */; + targetProxy = 4C541FA00F250C5200E508AE /* PBXContainerItemProxy */; + }; + 52D82BF616A627100078DFE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; + targetProxy = 52D82BF516A627100078DFE5 /* PBXContainerItemProxy */; + }; + 5346481B17331ED800FE9172 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */; + targetProxy = 5346481A17331ED800FE9172 /* PBXContainerItemProxy */; + }; + 6C4AA1AA2228B640006FA945 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; + targetProxy = 6C4AA1A92228B640006FA945 /* PBXContainerItemProxy */; + }; + 6C8FF4B6224C1A9800E5C812 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; + targetProxy = 6C8FF4B5224C1A9800E5C812 /* PBXContainerItemProxy */; + }; + 6C98082F1E788AEB00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = 6C9808301E788AEB00E70590 /* PBXContainerItemProxy */; + }; + 6C9808311E788AEB00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 6C9808321E788AEB00E70590 /* PBXContainerItemProxy */; + }; + 6C9808351E788AEB00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = 6C9808361E788AEB00E70590 /* PBXContainerItemProxy */; + }; + 6C9808371E788AEB00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = 6C9808381E788AEB00E70590 /* PBXContainerItemProxy */; + }; + 6C9808391E788AEB00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 6C98083A1E788AEB00E70590 /* PBXContainerItemProxy */; + }; + 6C98086B1E788AFD00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = 6C98086C1E788AFD00E70590 /* PBXContainerItemProxy */; + }; + 6C98086D1E788AFD00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 6C98086E1E788AFD00E70590 /* PBXContainerItemProxy */; + }; + 6C9808711E788AFD00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = 6C9808721E788AFD00E70590 /* PBXContainerItemProxy */; + }; + 6C9808731E788AFD00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = 6C9808741E788AFD00E70590 /* PBXContainerItemProxy */; + }; + 6C9808751E788AFD00E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = 6C9808761E788AFD00E70590 /* PBXContainerItemProxy */; + }; + 6C9808A01E788B9400E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CF4A0B31E45488B00ECD7B5 /* KeychainEntitledTestApp_mac */; + targetProxy = 6C98089F1E788B9400E70590 /* PBXContainerItemProxy */; + }; + 6C9808A41E788CB100E70590 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */; + targetProxy = 6C9808A31E788CB100E70590 /* PBXContainerItemProxy */; + }; + 6C9A49B21FAB647D00239D58 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 6C9A49B11FAB647D00239D58 /* PBXContainerItemProxy */; + }; + 6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; + targetProxy = 6CAA8D3C1F8431BC007B6E03 /* PBXContainerItemProxy */; + }; + 6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; + targetProxy = 6CAA8D3E1F8431C9007B6E03 /* PBXContainerItemProxy */; + }; + 873C14B221540FED003C9C00 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = 873C14B121540FED003C9C00 /* PBXContainerItemProxy */; + }; + 87EDC39E2141BB8A007B0E64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4771D971209A755800BA9772 /* KeychainDataclassOwner */; + targetProxy = 87EDC39D2141BB8A007B0E64 /* PBXContainerItemProxy */; + }; + 87EDC3A22141BB92007B0E64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C8BBEFD1FCB446400580909 /* otctl */; + targetProxy = 87EDC3A12141BB92007B0E64 /* PBXContainerItemProxy */; + }; + 87EDC3A42141BB9B007B0E64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB27FF101E402CD300EC9E3A /* ckksctl */; + targetProxy = 87EDC3A32141BB9B007B0E64 /* PBXContainerItemProxy */; + }; + 87EDC3A82141BBAA007B0E64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */; + targetProxy = 87EDC3A72141BBAA007B0E64 /* PBXContainerItemProxy */; + }; + 87EDC3B22141BBD5007B0E64 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */; + targetProxy = 87EDC3B12141BBD5007B0E64 /* PBXContainerItemProxy */; + }; + ACBAF6FE1E941E090007BA2F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = ACBAF6991E9417F40007BA2F /* security_transform_regressions */; + targetProxy = ACBAF6FD1E941E090007BA2F /* PBXContainerItemProxy */; + }; + BE061EB31EE5EAC800B22118 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BED208D41EDF950E00753952 /* manifeststresstest */; + targetProxy = BE061EB21EE5EAC800B22118 /* PBXContainerItemProxy */; + }; + BE197F631911742900BA91D1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BE197F2519116FD100BA91D1 /* SharedWebCredentialViewService */; + targetProxy = BE197F621911742900BA91D1 /* PBXContainerItemProxy */; + }; + BE4AC9B418B8020400B84964 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BE442BA018B7FDB800F24DAE /* swcagent */; + targetProxy = BE4AC9B318B8020400B84964 /* PBXContainerItemProxy */; + }; + BE9C38D31EB11605007E2AE1 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEF88C2F1EAFFC3F00357577 /* TrustedPeersTests */; + targetProxy = BE9C38D21EB11605007E2AE1 /* PBXContainerItemProxy */; + }; + BED01526206EEC710027A2B4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = BED01525206EEC710027A2B4 /* PBXContainerItemProxy */; + }; + D40B6A7F1E2B5F3D00CD6EE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D40B6A7E1E2B5F3D00CD6EE5 /* PBXContainerItemProxy */; + }; + D40B6A811E2B5F4700CD6EE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D40B6A801E2B5F4700CD6EE5 /* PBXContainerItemProxy */; + }; + D40B6A861E2B5F7600CD6EE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D40B6A851E2B5F7600CD6EE5 /* PBXContainerItemProxy */; + }; + D40B6A8C1E2B63D100CD6EE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D40B6A8B1E2B63D100CD6EE5 /* PBXContainerItemProxy */; + }; + D40B6A921E2B678D00CD6EE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D40B6A911E2B678D00CD6EE5 /* PBXContainerItemProxy */; + }; + D40B6A951E2B67FF00CD6EE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D40B6A941E2B67FF00CD6EE5 /* PBXContainerItemProxy */; + }; + D41257E61E941ACC00781F23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = D41257E51E941ACC00781F23 /* PBXContainerItemProxy */; + }; + D41257E81E941AD200781F23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D41257E71E941AD200781F23 /* PBXContainerItemProxy */; + }; + D41257F71E941E9600781F23 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D41257CE1E9410A300781F23 /* trustd_ios */; + targetProxy = D41257F61E941E9600781F23 /* PBXContainerItemProxy */; + }; + D41AD4521B9788B2008C7270 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; + targetProxy = D41AD4511B9788B2008C7270 /* PBXContainerItemProxy */; + }; + D42C83A5211636A3008D3D83 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D44D1F652115893000E76E1A /* CMS */; + targetProxy = D42C83A4211636A3008D3D83 /* PBXContainerItemProxy */; + }; + D437185421166DD800EA350A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D42C839721159146008D3D83 /* security_cms */; + targetProxy = D437185321166DD800EA350A /* PBXContainerItemProxy */; + }; + D437185921166FC800EA350A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D44D1F652115893000E76E1A /* CMS */; + targetProxy = D437185821166FC800EA350A /* PBXContainerItemProxy */; + }; + D437185B211670F600EA350A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4D1FDDB21165F8B003538E2 /* security_cms_regressions */; + targetProxy = D437185A211670F600EA350A /* PBXContainerItemProxy */; + }; + D437C33121EBF8A000DD1E06 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = D437C33021EBF8A000DD1E06 /* PBXContainerItemProxy */; + }; + D453A4A52122236D00850A26 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D453A4A62122236D00850A26 /* PBXContainerItemProxy */; + }; + D453A4C42122262400850A26 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = D453A4C32122262400850A26 /* PBXContainerItemProxy */; + }; + D453A4C8212226A900850A26 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = D453A4C7212226A900850A26 /* PBXContainerItemProxy */; + }; + D456A06822AF1866001119F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; + targetProxy = D456A06722AF1866001119F3 /* PBXContainerItemProxy */; + }; + D456A06B22AF1874001119F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; + targetProxy = D456A06A22AF1874001119F3 /* PBXContainerItemProxy */; + }; + D456A06D22AF3238001119F3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = D456A06C22AF3238001119F3 /* PBXContainerItemProxy */; + }; + D45D8F4F2224D72C00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCE4E68A1D7A37FA00AFB96E /* security2tool_macos */; + targetProxy = D45D8F4E2224D72C00D6C124 /* PBXContainerItemProxy */; + }; + D45D8F522224D76E00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCE4E8DC1D7F39DB00AFB96E /* Cloud Keychain Utility */; + targetProxy = D45D8F512224D76E00D6C124 /* PBXContainerItemProxy */; + }; + D45D8F542224D7C400D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F621D0271ED6DCE7000EA569 /* authorizationdump */; + targetProxy = D45D8F532224D7C400D6C124 /* PBXContainerItemProxy */; }; - DCE4E8D91D7F39DB00AFB96E /* Sources */ = { - 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 */, - DCE4E8F61D7F3A1100AFB96E /* KDSecCircle.m in Sources */, - DCE4E8FA1D7F3A1100AFB96E /* KDSecItems.m in Sources */, - DCE4E8FB1D7F3A1100AFB96E /* NSArray+mapWithBlock.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F562224D87C00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD06A541D8CE2D5007602F1 /* gkunpack */; + targetProxy = D45D8F552224D87C00D6C124 /* PBXContainerItemProxy */; }; - DCE4E90D1D7F3D5300AFB96E /* Sources */ = { - 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 */, - DCE4E92D1D7F3D7C00AFB96E /* NSArray+mapWithBlock.m in Sources */, - DCE4E92F1D7F3D7C00AFB96E /* NSString+compactDescription.m in Sources */, - DCE4E9301D7F3D7C00AFB96E /* main.m in Sources */, - DCE4E92E1D7F3D7C00AFB96E /* NSDictionary+compactDescription.m in Sources */, - DCE4E9321D7F3D7C00AFB96E /* KNAppDelegate.m in Sources */, - DCE4E9331D7F3D7C00AFB96E /* NSSet+compactDescription.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F582224D88F00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC610AAD1D7910C3002223DE /* gk_reset_check_macos */; + targetProxy = D45D8F572224D88F00D6C124 /* PBXContainerItemProxy */; }; - DCF7830E1D88B4DE00E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCF783F31D88B60D00E694BB /* pkcs12Derive.cpp in Sources */, - DCF784CE1D88B62E00E694BB /* rc2_skey.c in Sources */, - DCF7849F1D88B62D00E694BB /* bn_exp.c in Sources */, - DCF784F31D88B62E00E694BB /* rsa_pk1.c in Sources */, - DCF783EF1D88B60D00E694BB /* SHA1_MD5_Object.cpp in Sources */, - DCF784BE1D88B62E00E694BB /* dh_lib.c in Sources */, - DCF783D41D88B60D00E694BB /* cryptkitcsp.cpp in Sources */, - DCF784A11D88B62D00E694BB /* bn_gcd.c in Sources */, - DCF784BB1D88B62E00E694BB /* dh_err.c in Sources */, - DCF7849B1D88B62D00E694BB /* bn_blind.c in Sources */, - DCF784B61D88B62D00E694BB /* buf_err.c in Sources */, - DCF784B71D88B62D00E694BB /* buffer.c in Sources */, - DCF783E51D88B60D00E694BB /* DH_utils.cpp in Sources */, - DCF784041D88B60D00E694BB /* miscAlgFactory.cpp in Sources */, - DCF7849A1D88B62D00E694BB /* bn_asm.c in Sources */, - DCF783DB1D88B60D00E694BB /* FEEKeys.cpp in Sources */, - DCF784C51D88B62E00E694BB /* dsa_sign.c in Sources */, - DCF783A21D88B60D00E694BB /* gladmanContext.cpp in Sources */, - DCF783B51D88B60D00E694BB /* BlockCryptor.cpp in Sources */, - DCF784071D88B60D00E694BB /* RSA_DSA_signature.cpp in Sources */, - DCF784AB1D88B62D00E694BB /* bn_recp.c in Sources */, - DCF784AD1D88B62D00E694BB /* bn_sqr.c in Sources */, - DCF784091D88B60D00E694BB /* RSA_DSA_utils.cpp in Sources */, - DCF783D91D88B60D00E694BB /* FEECSPUtils.cpp in Sources */, - DCF784C01D88B62E00E694BB /* dsa_err.c in Sources */, - DCF784CF1D88B62E00E694BB /* rc5_enc.c in Sources */, - DCF784A71D88B62D00E694BB /* bn_prime.c in Sources */, - DCF7839E1D88B60D00E694BB /* aescsp.cpp in Sources */, - DCF783C61D88B60D00E694BB /* bsafeAsymmetric.cpp in Sources */, - DCF784921D88B62D00E694BB /* bf_ecb.c in Sources */, - DCF783E71D88B60D00E694BB /* HMACSHA1.c in Sources */, - DCF784F61D88B62E00E694BB /* rsa_ssl.c in Sources */, - DCF783CA1D88B60D00E694BB /* bsafeKeyGen.cpp in Sources */, - DCF783E31D88B60D00E694BB /* DH_keys.cpp in Sources */, - DCF784AC1D88B62D00E694BB /* bn_shift.c in Sources */, - DCF784A51D88B62D00E694BB /* bn_mpi.c in Sources */, - DCF784A61D88B62D00E694BB /* bn_mul.c in Sources */, - DCF784BC1D88B62E00E694BB /* dh_gen.c in Sources */, - DCF784061D88B60D00E694BB /* RSA_asymmetric.cpp in Sources */, - DCF784EC1D88B62E00E694BB /* rsa_chk.c in Sources */, - DCF783BC1D88B60D00E694BB /* MacContext.cpp in Sources */, - DCF783ED1D88B60D00E694BB /* MD2Object.cpp in Sources */, - DCF783A81D88B60D00E694BB /* vRijndael-alg-ref.c in Sources */, - DCF783AC1D88B60D00E694BB /* AppleCSPContext.cpp in Sources */, - DCF784BF1D88B62E00E694BB /* dsa_asn1.c in Sources */, - DCF783A01D88B60D00E694BB /* boxes-ref.c in Sources */, - DCF784151D88B60D00E694BB /* opensslUtils.cpp in Sources */, - DCF783B91D88B60D00E694BB /* deriveKey.cpp in Sources */, - DCF783FE1D88B60D00E694BB /* rc2Context.cpp in Sources */, - DCF784121D88B60D00E694BB /* opensshWrap.cpp in Sources */, - DCF783F11D88B60D00E694BB /* SHA2_Object.cpp in Sources */, - DCF784A91D88B62D00E694BB /* bn_print.c in Sources */, - DCF783A61D88B60D00E694BB /* rijndaelApi.c in Sources */, - DCF783BA1D88B60D00E694BB /* DigestContext.cpp in Sources */, - DCF784D11D88B62E00E694BB /* rc5_skey.c in Sources */, - DCF784CA1D88B62E00E694BB /* lhash.c in Sources */, - DCF784BD1D88B62E00E694BB /* dh_key.c in Sources */, - DCF784C71D88B62E00E694BB /* err.c in Sources */, - DCF783AE1D88B60D00E694BB /* AppleCSPKeys.cpp in Sources */, - DCF784CB1D88B62E00E694BB /* mem.c in Sources */, - DCF783D71D88B60D00E694BB /* FEEAsymmetricContext.cpp in Sources */, - DCF783D01D88B60D00E694BB /* miscalgorithms.cpp in Sources */, - DCF783E11D88B60D00E694BB /* DH_exchange.cpp in Sources */, - DCF783C31D88B60D00E694BB /* YarrowConnection.cpp in Sources */, - DCF784A41D88B62D00E694BB /* bn_mont.c in Sources */, - DCF783C11D88B60D00E694BB /* wrapKey.cpp in Sources */, - DCF783BF1D88B60D00E694BB /* SignatureContext.cpp in Sources */, - DCF784111D88B60D00E694BB /* opensshCoding.cpp in Sources */, - DCF784C11D88B62E00E694BB /* dsa_gen.c in Sources */, - DCF7840B1D88B60D00E694BB /* RSA_DSA_csp.cpp in Sources */, - DCF783F71D88B60D00E694BB /* bfContext.cpp in Sources */, - DCF783FB1D88B60D00E694BB /* desContext.cpp in Sources */, - DCF784CC1D88B62E00E694BB /* rc2_cbc.c in Sources */, - DCF784AA1D88B62D00E694BB /* bn_rand.c in Sources */, - DCF784BA1D88B62E00E694BB /* dh_check.c in Sources */, - DCF783A91D88B60D00E694BB /* AppleCSP.cpp in Sources */, - DCF784C31D88B62E00E694BB /* dsa_lib.c in Sources */, - DCF784971D88B62D00E694BB /* bio_lib.c in Sources */, - DCF784C91D88B62E00E694BB /* ex_data.c in Sources */, - DCF784C21D88B62E00E694BB /* dsa_key.c in Sources */, - DCF784A31D88B62D00E694BB /* bn_lib.c in Sources */, - DCF784961D88B62D00E694BB /* bf_skey.c in Sources */, - DCF784F01D88B62E00E694BB /* rsa_lib.c in Sources */, - DCF783AB1D88B60D00E694BB /* AppleCSPBuiltin.cpp in Sources */, - DCF783D11D88B60D00E694BB /* ascContext.cpp in Sources */, - DCF784981D88B62D00E694BB /* bss_file.c in Sources */, - DCF784C81D88B62E00E694BB /* err_prn.c in Sources */, - DCF784F11D88B62E00E694BB /* rsa_none.c in Sources */, - DCF784B81D88B62D00E694BB /* cryptlib.c in Sources */, - DCF783DF1D88B60D00E694BB /* DH_csp.cpp in Sources */, - DCF784A01D88B62D00E694BB /* bn_exp2.c in Sources */, - DCF7840D1D88B60D00E694BB /* RSA_DSA_keys.cpp in Sources */, - DCF783CB1D88B60D00E694BB /* bsafePKCS1.cpp in Sources */, - DCF783B21D88B60D00E694BB /* AppleCSPUtils.cpp in Sources */, - DCF784EE1D88B62E00E694BB /* rsa_err.c in Sources */, - DCF783F91D88B60D00E694BB /* castContext.cpp in Sources */, - DCF783F51D88B60D00E694BB /* pkcs8.cpp in Sources */, - DCF783C21D88B60D00E694BB /* wrapKeyCms.cpp in Sources */, - DCF7849E1D88B62D00E694BB /* bn_err.c in Sources */, - DCF784131D88B60D00E694BB /* opensslAsn1.cpp in Sources */, - DCF784991D88B62D00E694BB /* bn_add.c in Sources */, - DCF784001D88B60D00E694BB /* rc4Context.cpp in Sources */, - DCF783C71D88B60D00E694BB /* bsafeContext.cpp in Sources */, - DCF783DD1D88B60D00E694BB /* FEESignatureObject.cpp in Sources */, - DCF784C61D88B62E00E694BB /* dsa_vrf.c in Sources */, - DCF784AE1D88B62D00E694BB /* bn_word.c in Sources */, - DCF783A41D88B60D00E694BB /* rijndael-alg-ref.c in Sources */, - DCF783CF1D88B60D00E694BB /* memory.cpp in Sources */, - DCF783E91D88B60D00E694BB /* pbkdDigest.cpp in Sources */, - DCF784021D88B60D00E694BB /* rc5Context.cpp in Sources */, - DCF783EB1D88B60D00E694BB /* pbkdf2.c in Sources */, - DCF783B71D88B60D00E694BB /* cspdebugging.c in Sources */, - DCF784ED1D88B62E00E694BB /* rsa_eay.c in Sources */, - DCF784EF1D88B62E00E694BB /* rsa_gen.c in Sources */, - DCF783CD1D88B60D00E694BB /* bsafeSymmetric.cpp in Sources */, - DCF784F71D88B62E00E694BB /* stack.c in Sources */, - DCF7849C1D88B62D00E694BB /* bn_ctx.c in Sources */, - DCF784F51D88B62E00E694BB /* rsa_sign.c in Sources */, - DCF784F21D88B62E00E694BB /* rsa_null.c in Sources */, - DCF784931D88B62D00E694BB /* bf_enc.c in Sources */, - DCF784F41D88B62E00E694BB /* rsa_saos.c in Sources */, - DCF783C51D88B60D00E694BB /* algmaker.cpp in Sources */, - DCF7849D1D88B62D00E694BB /* bn_div.c in Sources */, - DCF784C41D88B62E00E694BB /* dsa_ossl.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F5A2224D8A100D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4CE5A54C09C796E100D27A3F /* sslViewer */; + targetProxy = D45D8F592224D8A100D6C124 /* PBXContainerItemProxy */; }; - DCF785601D88B95500E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCF787221D88BA0100E694BB /* SSCSPSession.cpp in Sources */, - DCF787261D88BA0100E694BB /* SSDLSession.cpp in Sources */, - DCF7872A1D88BA0100E694BB /* SSKey.cpp in Sources */, - DCF7871E1D88BA0100E694BB /* SSContext.cpp in Sources */, - DCF787201D88BA0100E694BB /* SSCSPDLSession.cpp in Sources */, - DCF7871C1D88BA0100E694BB /* CSPDLPlugin.cpp in Sources */, - DCF787241D88BA0100E694BB /* SSDatabase.cpp in Sources */, - DCF7871A1D88BA0100E694BB /* CSPDLDatabase.cpp in Sources */, - DCF787281D88BA0100E694BB /* SSFactory.cpp in Sources */, - DCF787301D88C18A00E694BB /* AppleCSPDLBuiltin.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F5C2224D9F100D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; + targetProxy = D45D8F5B2224D9F100D6C124 /* PBXContainerItemProxy */; }; - DCF787AE1D88C86900E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F5E2224DA1000D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = D45D8F5D2224DA1000D6C124 /* PBXContainerItemProxy */; }; - DCF788361D88C8C400E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCF788441D88C8FF00E694BB /* AppleDLBuiltin.cpp in Sources */, - DCF788411D88C8DE00E694BB /* AppleFileDL.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F602224DA6600D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 3DD1FFAC201FDB1D0086D049 /* SecureTransportTests_ios */; + targetProxy = D45D8F5F2224DA6600D6C124 /* PBXContainerItemProxy */; }; - DCF788491D88CA7200E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCF788751D88CABC00E694BB /* AppleX509CL.cpp in Sources */, - DCF788871D88CABC00E694BB /* clNssUtils.cpp in Sources */, - DCF788921D88CABC00E694BB /* DecodedItem.cpp in Sources */, - DCF788851D88CABC00E694BB /* clNameUtils.cpp in Sources */, - DCF788951D88CABC00E694BB /* Session_Cert.cpp in Sources */, - DCF788831D88CABC00E694BB /* CLFieldsCommon.cpp in Sources */, - DCF7888C1D88CABC00E694BB /* DecodedCert.cpp in Sources */, - DCF788771D88CABC00E694BB /* AppleX509CLBuiltin.cpp in Sources */, - DCF7887B1D88CABC00E694BB /* CertFields.cpp in Sources */, - DCF788791D88CABC00E694BB /* AppleX509CLSession.cpp in Sources */, - DCF7888A1D88CABC00E694BB /* CSPAttacher.cpp in Sources */, - DCF788801D88CABC00E694BB /* CLCrlExtensions.cpp in Sources */, - DCF788781D88CABC00E694BB /* AppleX509CLPlugin.cpp in Sources */, - DCF7887C1D88CABC00E694BB /* CLCachedEntry.cpp in Sources */, - DCF7888E1D88CABC00E694BB /* DecodedCrl.cpp in Sources */, - DCF788891D88CABC00E694BB /* CrlFields.cpp in Sources */, - DCF788981D88CABC00E694BB /* Session_CSR.cpp in Sources */, - DCF788961D88CABC00E694BB /* Session_CRL.cpp in Sources */, - DCF788901D88CABC00E694BB /* DecodedExtensions.cpp in Sources */, - DCF7887E1D88CABC00E694BB /* CLCertExtensions.cpp in Sources */, - DCF788971D88CABC00E694BB /* Session_Crypto.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F622224DA8400D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB108F181E6CE4D2003B0456 /* KCPairingTests */; + targetProxy = D45D8F612224DA8400D6C124 /* PBXContainerItemProxy */; }; - DCF788991D88CB5200E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCF788A51D88CB6800E694BB /* AppleX509CLPlugin.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F642224DA8E00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E7D847CD1C6BE9720025BB44 /* KeychainCircleTests */; + targetProxy = D45D8F632224DA8E00D6C124 /* PBXContainerItemProxy */; }; - DCF788BC1D88CD2400E694BB /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DCF789341D88CD6700E694BB /* TPDatabase.cpp in Sources */, - DCF7892B1D88CD6700E694BB /* TPCertInfo.cpp in Sources */, - DCF789211D88CD6700E694BB /* AppleTP.cpp in Sources */, - DCF789391D88CD6700E694BB /* ocspRequest.cpp in Sources */, - DCF789371D88CD6700E694BB /* TPNetwork.cpp in Sources */, - DCF789321D88CD6700E694BB /* tpCrlVerify.cpp in Sources */, - DCF789231D88CD6700E694BB /* AppleTPSession.cpp in Sources */, - DCF789281D88CD6700E694BB /* cuEnc64.c in Sources */, - DCF789411D88CD6700E694BB /* tpPolicies.cpp in Sources */, - DCF789481D88D17C00E694BB /* AppleX509TPBuiltin.cpp in Sources */, - DCF7893F1D88CD6700E694BB /* tpOcspVerify.cpp in Sources */, - DCF789301D88CD6700E694BB /* TPCrlInfo.cpp in Sources */, - DCF789431D88CD6700E694BB /* tpTime.c in Sources */, - DCF789261D88CD6700E694BB /* certGroupUtils.cpp in Sources */, - DCF7893B1D88CD6700E694BB /* tpOcspCache.cpp in Sources */, - DCF7892A1D88CD6700E694BB /* tpCertGroup.cpp in Sources */, - DCF7893D1D88CD6700E694BB /* tpOcspCertVfy.cpp in Sources */, - DCF7892F1D88CD6700E694BB /* tpCredRequest.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F662224DA9900D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D458C505214E20530043D982 /* TrustTests */; + targetProxy = D45D8F652224DA9900D6C124 /* PBXContainerItemProxy */; }; - E710C73E1331946400F85568 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 476541A31F33EDCC00413F65 /* SecdWatchdog.m in Sources */, - 4CC92B1C15A3BF2F00C6D578 /* testmain.c in Sources */, - 0C78F1CC16A5E1BF00654E08 /* sectask-10-sectask.c in Sources */, - DCCD33D11E3FEF2C00AA4AD1 /* spi.c in Sources */, - DCB221541E8B08BE001598BC /* server_xpc.m in Sources */, - DC42690D1E82FD9B002B7110 /* server_security_helpers.c in Sources */, - DC4268FC1E820370002B7110 /* server_endpoint.m in Sources */, - DC5F35AB1EE0F27100900966 /* server_entitlement_helpers.c in Sources */, - 0C78F1CE16A5E1BF00654E08 /* sectask_ipc.defs in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F6A2224DA9900D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D4707A0421136E69005BCFDA /* TrustTests_ios */; + targetProxy = D45D8F692224DA9900D6C124 /* PBXContainerItemProxy */; }; - E7B01BC2166594AB000485F1 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F6C2224DABA00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC05037521409A4000A8EDB7 /* OCMockUmbrella */; + targetProxy = D45D8F6B2224DABA00D6C124 /* PBXContainerItemProxy */; }; - E7D847C01C6BE9710025BB44 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB413B801E663AEB00592085 /* PairingChannel.m in Sources */, - E7F480151C73980D00390FDB /* KCJoiningRequestSession.m in Sources */, - E7F480331C73FC4C00390FDB /* KCAESGCMDuplexSession.m in Sources */, - E794BB001C7598F900339A0F /* KCJoiningMessages.m in Sources */, - E794BA6F1C7424D800339A0F /* KCDer.m in Sources */, - E7E3EFBA1CBC192A00E79A5D /* KCAccountKCCircleDelegate.m in Sources */, - E7F482AC1C7558F700390FDB /* KCJoiningAcceptSession.m in Sources */, - E71454F01C741E0800B5B20B /* KCError.m in Sources */, - E772FD471CC15EFA00D63E41 /* NSData+SecRandom.m in Sources */, - E7F482AA1C7554FB00390FDB /* NSError+KCCreationHelpers.m in Sources */, - E75C0E831C6FC31D00E6953B /* KCSRPContext.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F6E2224DB6400D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D41257CE1E9410A300781F23 /* trustd_ios */; + targetProxy = D45D8F6D2224DB6400D6C124 /* PBXContainerItemProxy */; }; - E7D847CA1C6BE9720025BB44 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - E7F4809C1C74E85200390FDB /* KCDerTest.m in Sources */, - E7F482701C74FDD100390FDB /* KCJoiningSessionTest.m in Sources */, - E7D848051C6BEFCD0025BB44 /* KCSRPTests.m in Sources */, - E7F4809E1C74E86D00390FDB /* KCAESGCMTest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F702224DB6D00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 790851B50CA9859F0083CC4D /* securityd_ios */; + targetProxy = D45D8F6F2224DB6D00D6C124 /* PBXContainerItemProxy */; }; - 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; + D45D8F722224DB9200D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB9C1D791BDFD0E000F89272 /* secbackupntest */; + targetProxy = D45D8F712224DB9200D6C124 /* PBXContainerItemProxy */; }; - EB0BC9371C3C791500785842 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB0BC9671C3C798600785842 /* secedumodetest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F742224DB9C00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5EBE24791B00CCAE0007DB0E /* secacltests */; + targetProxy = D45D8F732224DB9C00D6C124 /* PBXContainerItemProxy */; }; - EB1055711E14DF430003C309 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB1055791E14DF570003C309 /* SecCertificateFuzzer.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F782224DBB500D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; + targetProxy = D45D8F772224DBB500D6C124 /* PBXContainerItemProxy */; }; - EB108F251E6CE4D2003B0456 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB108F261E6CE4D2003B0456 /* KCPairingTest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F7A2224DBBD00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C6799F912F7C37C00712919 /* dtlsTests */; + targetProxy = D45D8F792224DBBD00D6C124 /* PBXContainerItemProxy */; }; - EB27FF0D1E402CD300EC9E3A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DC5BCC481E53820200649140 /* SecArgParse.c in Sources */, - EB27FF2D1E407FF600EC9E3A /* ckksctl.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F7C2224DBC600D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E710C7411331946400F85568 /* SecurityTests */; + targetProxy = D45D8F7B2224DBC600D6C124 /* PBXContainerItemProxy */; }; - EB2D54A21F02A45E00E46890 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB2D54AB1F02A47200E46890 /* SecAtomicFile.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F7E2224DBD900D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; + targetProxy = D45D8F7D2224DBD900D6C124 /* PBXContainerItemProxy */; }; - EB425C9F1C65846D000ECE53 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB425CCF1C658554000ECE53 /* secbackuptest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F822224DBE300D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; + targetProxy = D45D8F812224DBE300D6C124 /* PBXContainerItemProxy */; }; - EB433A211CC3243600A7EACE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB433A291CC3244C00A7EACE /* secitemstresstest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F842224DBEF00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9808681E788AFD00E70590 /* CKKSCloudKitTests_ios */; + targetProxy = D45D8F832224DBEF00D6C124 /* PBXContainerItemProxy */; }; - EB49B2AA202D877F003F34A0 /* Sources */ = { - 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; + D45D8F862224DBF800D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC3502B41E0208BE00BC0587 /* CKKSTests */; + targetProxy = D45D8F852224DBF800D6C124 /* PBXContainerItemProxy */; }; - EB9C1D761BDFD0E000F89272 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EB9C1D7E1BDFD0E100F89272 /* secbackupntest.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F882224DC3F00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = D45D8F872224DC3F00D6C124 /* PBXContainerItemProxy */; }; - EBA9AA7E1CE30E58004E2B68 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EBA9AA871CE30E6F004E2B68 /* secitemnotifications.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F8C2224DC7600D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; + targetProxy = D45D8F8B2224DC7600D6C124 /* PBXContainerItemProxy */; }; - EBB839A11E29665D00853BAC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EBB839B01E2968AB00853BAC /* secfuzzer.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F8E2224DC8E00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4CE5A54C09C796E100D27A3F /* sslViewer */; + targetProxy = D45D8F8D2224DC8E00D6C124 /* PBXContainerItemProxy */; }; - EBCF73F41CE45F9C00BED7CA /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EBCF73FD1CE45FAC00BED7CA /* secitemfunctionality.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F902224DC9900D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4CB740A20A47567C00D641BB /* securitytool_ios */; + targetProxy = D45D8F8F2224DC9900D6C124 /* PBXContainerItemProxy */; }; - EBF3746E1DC055580065D840 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - EBF374751DC055590065D840 /* security-sysdiagnose.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F922224DCCB00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7913B1FF0D172B3900601FE9 /* sslServer */; + targetProxy = D45D8F912224DCCB00D6C124 /* PBXContainerItemProxy */; }; - F621D02A1ED6DCE7000EA569 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F619D71E1ED70BC1005B5F46 /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F942224DCD700D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C9DE9D11181AC4800CF5C27 /* sslEcdsa */; + targetProxy = D45D8F932224DCD700D6C124 /* PBXContainerItemProxy */; }; - F667EC571E96E9B100203D5C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F667EC621E96EAD200203D5C /* main.m in Sources */, - F667EC611E96E9E700203D5C /* authdtests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; + D45D8F982224DD7B00D6C124 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = D41257CE1E9410A300781F23 /* trustd_ios */; + targetProxy = D45D8F972224DD7B00D6C124 /* PBXContainerItemProxy */; }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 0C10C93A1DD548B6000602A8 /* PBXTargetDependency */ = { + D45D8F9A2224DD8200D6C124 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; - targetProxy = 0C10C9391DD548B6000602A8 /* PBXContainerItemProxy */; + target = 790851B50CA9859F0083CC4D /* securityd_ios */; + targetProxy = D45D8F992224DD8200D6C124 /* PBXContainerItemProxy */; + }; + D469C4E5218BECCE008AC1FC /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCE4E9101D7F3D5300AFB96E /* Keychain Circle Notification */; + targetProxy = D469C4E4218BECCE008AC1FC /* PBXContainerItemProxy */; + }; + D476BC3922BD34280098E15A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; + targetProxy = D476BC3822BD34280098E15A /* PBXContainerItemProxy */; + }; + D476BC3C22BD34320098E15A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; + targetProxy = D476BC3B22BD34320098E15A /* PBXContainerItemProxy */; }; - 0C10C93C1DD548BD000602A8 /* PBXTargetDependency */ = { + D477EE7121ED48A500C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 0C10C93B1DD548BD000602A8 /* PBXContainerItemProxy */; + target = EB2D54A11F02A45E00E46890 /* secatomicfile */; + targetProxy = D477EE7021ED48A500C9AAFF /* PBXContainerItemProxy */; }; - 0C2BCBBC1D0640B200ED7A2F /* PBXTargetDependency */ = { + D477EE7321ED48AA00C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C2BCBA81D06401F00ED7A2F /* dtlsEchoClient */; - targetProxy = 0C2BCBBB1D0640B200ED7A2F /* PBXContainerItemProxy */; + target = BED208D41EDF950E00753952 /* manifeststresstest */; + targetProxy = D477EE7221ED48AA00C9AAFF /* PBXContainerItemProxy */; }; - 0C2BCBD11D0648FA00ED7A2F /* PBXTargetDependency */ = { + D477EE7521ED48B400C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C2BCBBD1D0648D100ED7A2F /* dtlsEchoServer */; - targetProxy = 0C2BCBD01D0648FA00ED7A2F /* PBXContainerItemProxy */; + target = F667EC561E96E9B100203D5C /* authdtest */; + targetProxy = D477EE7421ED48B400C9AAFF /* PBXContainerItemProxy */; }; - 0C3E2EA92073F5C400F5B95B /* PBXTargetDependency */ = { + D477EE7721ED48C000C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C32C0AE0A4975F6002891BD /* Security_ios */; - targetProxy = 0C3E2EA82073F5C400F5B95B /* PBXContainerItemProxy */; + target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; + targetProxy = D477EE7621ED48C000C9AAFF /* PBXContainerItemProxy */; }; - 0C5663EE20BE2E1A0035F362 /* PBXTargetDependency */ = { + D477EE7921ED48C000C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 0C5663ED20BE2E1A0035F362 /* PBXContainerItemProxy */; + target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; + targetProxy = D477EE7821ED48C000C9AAFF /* PBXContainerItemProxy */; }; - 0C664AB41759270C0092D3D9 /* PBXTargetDependency */ = { + D477EE7B21ED48C000C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; - targetProxy = 0C664AB31759270C0092D3D9 /* PBXContainerItemProxy */; + target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; + targetProxy = D477EE7A21ED48C000C9AAFF /* PBXContainerItemProxy */; }; - 0C78CCE51FCC97E7008B4B24 /* PBXTargetDependency */ = { + D477EE7D21ED48CB00C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C8BBEFD1FCB446400580909 /* otctl */; - targetProxy = 0C78CCE41FCC97E7008B4B24 /* PBXContainerItemProxy */; + target = EBB839A41E29665D00853BAC /* secfuzzer */; + targetProxy = D477EE7C21ED48CB00C9AAFF /* PBXContainerItemProxy */; }; - 0C78CCE71FCC97F1008B4B24 /* PBXTargetDependency */ = { + D477EE7F21ED48D500C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C8BBEFD1FCB446400580909 /* otctl */; - targetProxy = 0C78CCE61FCC97F1008B4B24 /* PBXContainerItemProxy */; + target = EB1055741E14DF430003C309 /* SecCertificateFuzzer */; + targetProxy = D477EE7E21ED48D500C9AAFF /* PBXContainerItemProxy */; }; - 0C85DFD41FB38BB6000343A7 /* PBXTargetDependency */ = { + D477EE8121ED48DF00C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; - targetProxy = 0C85DFD51FB38BB6000343A7 /* PBXContainerItemProxy */; + target = BEF88C2F1EAFFC3F00357577 /* TrustedPeersTests */; + targetProxy = D477EE8021ED48DF00C9AAFF /* PBXContainerItemProxy */; }; - 0C85DFD81FB38BB6000343A7 /* PBXTargetDependency */ = { + D477EE8321ED48E800C9AAFF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; - targetProxy = 0C85DFD91FB38BB6000343A7 /* PBXContainerItemProxy */; + target = 478D426C1FD72A8100CAB645 /* secdxctests_mac */; + targetProxy = D477EE8221ED48E800C9AAFF /* PBXContainerItemProxy */; }; - 0C85DFDA1FB38BB6000343A7 /* PBXTargetDependency */ = { + D4794E6B21222E72007C6725 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 0C85DFDB1FB38BB6000343A7 /* PBXContainerItemProxy */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = D4794E6A21222E72007C6725 /* PBXContainerItemProxy */; }; - 0C85DFDC1FB38BB6000343A7 /* PBXTargetDependency */ = { + D4A763CF2224BCD10063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = 0C85DFDD1FB38BB6000343A7 /* PBXContainerItemProxy */; + target = DCE4E7F51D7A4DA800AFB96E /* secd */; + targetProxy = D4A763CE2224BCD10063B2B9 /* PBXContainerItemProxy */; }; - 0C85DFDE1FB38BB6000343A7 /* PBXTargetDependency */ = { + D4A763D12224BCDE0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; - targetProxy = 0C85DFDF1FB38BB6000343A7 /* PBXContainerItemProxy */; + target = DCE4E82D1D7A57AE00AFB96E /* trustd_macos */; + targetProxy = D4A763D02224BCDE0063B2B9 /* PBXContainerItemProxy */; }; - 0C85DFE01FB38BB6000343A7 /* PBXTargetDependency */ = { + D4A763D32224BD640063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = 0C85DFE11FB38BB6000343A7 /* PBXContainerItemProxy */; + target = DC610A551D78F9D2002223DE /* codesign_tests_macos */; + targetProxy = D4A763D22224BD640063B2B9 /* PBXContainerItemProxy */; }; - 0C99B740131C984900584CF4 /* PBXTargetDependency */ = { + D4A763D52224BD6F0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C6799F912F7C37C00712919 /* dtlsTests */; - targetProxy = 0C99B73F131C984900584CF4 /* PBXContainerItemProxy */; + target = DC610A021D78F129002223DE /* secdtests_macos */; + targetProxy = D4A763D42224BD6F0063B2B9 /* PBXContainerItemProxy */; }; - 0C9AEEBA20783FE000BF6237 /* PBXTargetDependency */ = { + D4A763D92224BD990063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC1789031D77980500B50D50 /* Security_osx */; - targetProxy = 0C9AEEB920783FE000BF6237 /* PBXContainerItemProxy */; + target = DC3502B41E0208BE00BC0587 /* CKKSTests */; + targetProxy = D4A763D82224BD990063B2B9 /* PBXContainerItemProxy */; }; - 0CC827F2138712B100BD99B7 /* PBXTargetDependency */ = { + D4A763DB2224BDAB0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E710C7411331946400F85568 /* SecurityTests */; - targetProxy = 0CC827F1138712B100BD99B7 /* PBXContainerItemProxy */; + target = 6C98082C1E788AEB00E70590 /* CKKSCloudKitTests_mac */; + targetProxy = D4A763DA2224BDAB0063B2B9 /* PBXContainerItemProxy */; }; - 225394B61E30811400D3CD9B /* PBXTargetDependency */ = { + D4A763DD2224BDCC0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 225394AC1E3080A600D3CD9B /* security_codesigning_ios */; - targetProxy = 225394B51E30811400D3CD9B /* PBXContainerItemProxy */; + target = 6CF4A0B31E45488B00ECD7B5 /* KeychainEntitledTestApp_mac */; + targetProxy = D4A763DC2224BDCC0063B2B9 /* PBXContainerItemProxy */; }; - 225394DA1E30846800D3CD9B /* PBXTargetDependency */ = { + D4A763DF2224BDDC0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD067561D8CDCF3007602F1 /* codesigning_DTrace */; - targetProxy = 225394D91E30846800D3CD9B /* PBXContainerItemProxy */; + target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; + targetProxy = D4A763DE2224BDDC0063B2B9 /* PBXContainerItemProxy */; }; - 226A8B451DEF58EE004C35E3 /* PBXTargetDependency */ = { + D4A763E12224BDED0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD06AA91D8E0D53007602F1 /* security_utilities */; - targetProxy = 226A8B441DEF58EE004C35E3 /* PBXContainerItemProxy */; + target = 5EBE24791B00CCAE0007DB0E /* secacltests */; + targetProxy = D4A763E02224BDED0063B2B9 /* PBXContainerItemProxy */; }; - 3DD1FEF8201C07F30086D049 /* PBXTargetDependency */ = { + D4A763E32224BDF90063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 3DD1FEF9201C07F30086D049 /* PBXContainerItemProxy */; + target = DC610A461D78F48F002223DE /* SecTaskTest_macos */; + targetProxy = D4A763E22224BDF90063B2B9 /* PBXContainerItemProxy */; }; - 3DD1FF50201C09CD0086D049 /* PBXTargetDependency */ = { + D4A763E52224BE170063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BC9C81D8B824700070CB0 /* security_ssl */; - targetProxy = 3DD1FF4F201C09CD0086D049 /* PBXContainerItemProxy */; + target = DC5AC04F1D8352D900CF422C /* securityd_macos */; + targetProxy = D4A763E42224BE170063B2B9 /* PBXContainerItemProxy */; }; - 3DD1FFAF201FDB1D0086D049 /* PBXTargetDependency */ = { + D4A763E72224BE2F0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BC9C81D8B824700070CB0 /* security_ssl */; - targetProxy = 3DD1FFB0201FDB1D0086D049 /* PBXContainerItemProxy */; + target = DCE4E7CB1D7A4AED00AFB96E /* sectests_macos */; + targetProxy = D4A763E62224BE2F0063B2B9 /* PBXContainerItemProxy */; }; - 3DD1FFB1201FDB1D0086D049 /* PBXTargetDependency */ = { + D4A763E92224BE430063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 3DD1FFB2201FDB1D0086D049 /* PBXContainerItemProxy */; + target = EB9C1D791BDFD0E000F89272 /* secbackupntest */; + targetProxy = D4A763E82224BE430063B2B9 /* PBXContainerItemProxy */; }; - 438169E71B4EE4B300C54D58 /* PBXTargetDependency */ = { + D4A763EB2224BE580063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4381690B1B4EDCBD00C54D58 /* SOSCCAuthPlugin */; - targetProxy = 438169E61B4EE4B300C54D58 /* PBXContainerItemProxy */; + target = DCE4E7311D7A43B500AFB96E /* SecurityTestsOSX */; + targetProxy = D4A763EA2224BE580063B2B9 /* PBXContainerItemProxy */; }; - 4718AE03205B39620068EC3F /* PBXTargetDependency */ = { + D4A763ED2224BE630063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 4718AE04205B39620068EC3F /* PBXContainerItemProxy */; + target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; + targetProxy = D4A763EC2224BE630063B2B9 /* PBXContainerItemProxy */; }; - 4718AE05205B39620068EC3F /* PBXTargetDependency */ = { + D4A763EF2224BE6E0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = 4718AE06205B39620068EC3F /* PBXContainerItemProxy */; + target = D458C505214E20530043D982 /* TrustTests */; + targetProxy = D4A763EE2224BE6E0063B2B9 /* PBXContainerItemProxy */; }; - 4718AE09205B39620068EC3F /* PBXTargetDependency */ = { + D4A763F12224BE6E0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; - targetProxy = 4718AE0A205B39620068EC3F /* PBXContainerItemProxy */; + target = D453A4A42122236D00850A26 /* TrustTests_macos */; + targetProxy = D4A763F02224BE6E0063B2B9 /* PBXContainerItemProxy */; }; - 4718AE0B205B39620068EC3F /* PBXTargetDependency */ = { + D4A763F32224BE810063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = 4718AE0C205B39620068EC3F /* PBXContainerItemProxy */; + target = E7D847CD1C6BE9720025BB44 /* KeychainCircleTests */; + targetProxy = D4A763F22224BE810063B2B9 /* PBXContainerItemProxy */; }; - 4718AE0D205B39620068EC3F /* PBXTargetDependency */ = { + D4A763F52224BE8A0063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52EC3E1D80D00800B0A59C /* libSWCAgent */; - targetProxy = 4718AE0E205B39620068EC3F /* PBXContainerItemProxy */; + target = EB108F181E6CE4D2003B0456 /* KCPairingTests */; + targetProxy = D4A763F42224BE8A0063B2B9 /* PBXContainerItemProxy */; }; - 4718AEE6205B3A350068EC3F /* PBXTargetDependency */ = { + D4A763F72224BE980063B2B9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4718AE2E205B39C40068EC3F /* libsecurityd_bridge */; - targetProxy = 4718AEE5205B3A350068EC3F /* PBXContainerItemProxy */; + target = 3DD1FEF5201C07F30086D049 /* SecureTransportTests_macos */; + targetProxy = D4A763F62224BE980063B2B9 /* PBXContainerItemProxy */; }; - 47455B24205B3E2F008FE980 /* PBXTargetDependency */ = { + D4B68C6A211B6E3E009FED69 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4718AE02205B39620068EC3F /* securityd_bridge */; - targetProxy = 47455B23205B3E2F008FE980 /* PBXContainerItemProxy */; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D4B68C69211B6E3E009FED69 /* PBXContainerItemProxy */; }; - 4771D982209A76B100BA9772 /* PBXTargetDependency */ = { + D4BFFD592227574200163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4771D971209A755800BA9772 /* KeychainDataclassOwner */; - targetProxy = 4771D981209A76B100BA9772 /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = D4BFFD582227574200163B4B /* PBXContainerItemProxy */; }; - 478D426D1FD72A8100CAB645 /* PBXTargetDependency */ = { + D4BFFD5C2227574C00163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52EDA61D80D58400B0A59C /* secdRegressions */; - targetProxy = 478D426E1FD72A8100CAB645 /* PBXContainerItemProxy */; + targetProxy = D4BFFD5B2227574C00163B4B /* PBXContainerItemProxy */; }; - 478D426F1FD72A8100CAB645 /* PBXTargetDependency */ = { + D4BFFD5E2227575C00163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; - targetProxy = 478D42701FD72A8100CAB645 /* PBXContainerItemProxy */; + targetProxy = D4BFFD5D2227575C00163B4B /* PBXContainerItemProxy */; }; - 478D42731FD72A8100CAB645 /* PBXTargetDependency */ = { + D4BFFD602227576E00163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = 478D42741FD72A8100CAB645 /* PBXContainerItemProxy */; + targetProxy = D4BFFD5F2227576E00163B4B /* PBXContainerItemProxy */; }; - 47A6FC6A206B461700BD6C54 /* PBXTargetDependency */ = { + D4BFFD622227578900163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; - targetProxy = 47A6FC69206B461700BD6C54 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = D4BFFD612227578900163B4B /* PBXContainerItemProxy */; }; - 47A6FC6C206B462400BD6C54 /* PBXTargetDependency */ = { + D4BFFD6722275A4B00163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; - targetProxy = 47A6FC6B206B462400BD6C54 /* PBXContainerItemProxy */; + target = DC05037521409A4000A8EDB7 /* OCMockUmbrella */; + targetProxy = D4BFFD6622275A4B00163B4B /* PBXContainerItemProxy */; }; - 47C2F18C2059CBEA0062DE30 /* PBXTargetDependency */ = { + D4BFFD692227B30700163B4B /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47C2F1822059CB680062DE30 /* KeychainResources */; - targetProxy = 47C2F18B2059CBEA0062DE30 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = D4BFFD682227B30700163B4B /* PBXContainerItemProxy */; }; - 47C2F18E2059CBF40062DE30 /* PBXTargetDependency */ = { + D4E0E9512224DDE300A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47C2F1822059CB680062DE30 /* KeychainResources */; - targetProxy = 47C2F18D2059CBF40062DE30 /* PBXContainerItemProxy */; + target = DC05037521409A4000A8EDB7 /* OCMockUmbrella */; + targetProxy = D4E0E9502224DDE300A802E0 /* PBXContainerItemProxy */; }; - 47C2F1902059CBFC0062DE30 /* PBXTargetDependency */ = { + D4E0E9542224DDEA00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47C2F1822059CB680062DE30 /* KeychainResources */; - targetProxy = 47C2F18F2059CBFC0062DE30 /* PBXContainerItemProxy */; + target = EB108F181E6CE4D2003B0456 /* KCPairingTests */; + targetProxy = D4E0E9532224DDEA00A802E0 /* PBXContainerItemProxy */; }; - 47C2F1922059CC040062DE30 /* PBXTargetDependency */ = { + D4E0E9562224DDF000A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47C2F1822059CB680062DE30 /* KeychainResources */; - targetProxy = 47C2F1912059CC040062DE30 /* PBXContainerItemProxy */; + target = E7D847CD1C6BE9720025BB44 /* KeychainCircleTests */; + targetProxy = D4E0E9552224DDF000A802E0 /* PBXContainerItemProxy */; }; - 47C51B8B1EEA657D0032D9E5 /* PBXTargetDependency */ = { + D4E0E9582224DDFE00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC1789031D77980500B50D50 /* Security_osx */; - targetProxy = 47C51B8A1EEA657D0032D9E5 /* PBXContainerItemProxy */; + target = D458C505214E20530043D982 /* TrustTests */; + targetProxy = D4E0E9572224DDFE00A802E0 /* PBXContainerItemProxy */; }; - 47D991D020407F7E0078CAE2 /* PBXTargetDependency */ = { + D4E0E95A2224DDFE00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; - targetProxy = 47D991CF20407F7E0078CAE2 /* PBXContainerItemProxy */; + target = D4707A0421136E69005BCFDA /* TrustTests_ios */; + targetProxy = D4E0E9592224DDFE00A802E0 /* PBXContainerItemProxy */; }; - 47D991D720407F890078CAE2 /* PBXTargetDependency */ = { + D4E0E95C2224DE1000A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 478D426C1FD72A8100CAB645 /* secdxctests_mac */; - targetProxy = 47D991D620407F890078CAE2 /* PBXContainerItemProxy */; + target = BEF88C2F1EAFFC3F00357577 /* TrustedPeersTests */; + targetProxy = D4E0E95B2224DE1000A802E0 /* PBXContainerItemProxy */; }; - 47DE88CE1FA7AD6200DD3254 /* PBXTargetDependency */ = { + D4E0E95E2224DE1A00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = 47DE88CD1FA7AD6200DD3254 /* PBXContainerItemProxy */; + target = BED208D41EDF950E00753952 /* manifeststresstest */; + targetProxy = D4E0E95D2224DE1A00A802E0 /* PBXContainerItemProxy */; }; - 47DE88D71FA7ADAC00DD3254 /* PBXTargetDependency */ = { + D4E0E9602224DE2700A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; - targetProxy = 47DE88D61FA7ADAC00DD3254 /* PBXContainerItemProxy */; + target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; + targetProxy = D4E0E95F2224DE2700A802E0 /* PBXContainerItemProxy */; }; - 47DE88D91FA7ADBB00DD3254 /* PBXTargetDependency */ = { + D4E0E9622224DE3D00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52EDA61D80D58400B0A59C /* secdRegressions */; - targetProxy = 47DE88D81FA7ADBB00DD3254 /* PBXContainerItemProxy */; + target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; + targetProxy = D4E0E9612224DE3D00A802E0 /* PBXContainerItemProxy */; }; - 4809F7AE2061B6AA003E72D0 /* PBXTargetDependency */ = { + D4E0E9642224DE4900A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB056E3D1FE5E390000A771E /* DeviceSimulator */; - targetProxy = 4809F7AD2061B6AA003E72D0 /* PBXContainerItemProxy */; + target = E710C7411331946400F85568 /* SecurityTests */; + targetProxy = D4E0E9632224DE4900A802E0 /* PBXContainerItemProxy */; }; - 4809F7B02061B6B0003E72D0 /* PBXTargetDependency */ = { + D4E0E9662224DE5100A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB05C4F01FE5E48A00D68712 /* MultiDeviceSimulatorTests */; - targetProxy = 4809F7AF2061B6B0003E72D0 /* PBXContainerItemProxy */; + target = 5EBE24791B00CCAE0007DB0E /* secacltests */; + targetProxy = D4E0E9652224DE5100A802E0 /* PBXContainerItemProxy */; }; - 4C52D0EE16EFCD720079966E /* PBXTargetDependency */ = { + D4E0E9682224DE5700A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C52D0B316EFC61E0079966E /* CircleJoinRequested */; - targetProxy = 4C52D0ED16EFCD720079966E /* PBXContainerItemProxy */; + target = 0C6799F912F7C37C00712919 /* dtlsTests */; + targetProxy = D4E0E9672224DE5700A802E0 /* PBXContainerItemProxy */; }; - 4C541F8C0F250C0400E508AE /* PBXTargetDependency */ = { + D4E0E96A2224DE6800A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 790851B50CA9859F0083CC4D /* securityd_ios */; - targetProxy = 4C541F8B0F250C0400E508AE /* PBXContainerItemProxy */; + target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; + targetProxy = D4E0E9692224DE6800A802E0 /* PBXContainerItemProxy */; }; - 4C541F8E0F250C0900E508AE /* PBXTargetDependency */ = { + D4E0E96C2224DE7000A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CB740A20A47567C00D641BB /* securitytool_ios */; - targetProxy = 4C541F8D0F250C0900E508AE /* PBXContainerItemProxy */; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = D4E0E96B2224DE7000A802E0 /* PBXContainerItemProxy */; }; - 4C541F900F250C0E00E508AE /* PBXTargetDependency */ = { + D4E0E96E2224DE7A00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CE5A54C09C796E100D27A3F /* sslViewer */; - targetProxy = 4C541F8F0F250C0E00E508AE /* PBXContainerItemProxy */; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = D4E0E96D2224DE7A00A802E0 /* PBXContainerItemProxy */; }; - 4C541F920F250C1300E508AE /* PBXTargetDependency */ = { + D4E0E9702224DE8200A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 7913B1FF0D172B3900601FE9 /* sslServer */; - targetProxy = 4C541F910F250C1300E508AE /* PBXContainerItemProxy */; + target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; + targetProxy = D4E0E96F2224DE8200A802E0 /* PBXContainerItemProxy */; }; - 4C541FA10F250C5200E508AE /* PBXTargetDependency */ = { + D4E0E9722224DE8200A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C541F840F250BF500E508AE /* Security_executables_ios */; - targetProxy = 4C541FA00F250C5200E508AE /* PBXContainerItemProxy */; + target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; + targetProxy = D4E0E9712224DE8200A802E0 /* PBXContainerItemProxy */; }; - 4C9DE9EF1181ACA000CF5C27 /* PBXTargetDependency */ = { + D4E0E9742224DE8200A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C9DE9D11181AC4800CF5C27 /* sslEcdsa */; - targetProxy = 4C9DE9EE1181ACA000CF5C27 /* PBXContainerItemProxy */; + target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; + targetProxy = D4E0E9732224DE8200A802E0 /* PBXContainerItemProxy */; }; - 52D82BF616A627100078DFE5 /* PBXTargetDependency */ = { + D4E0E9762224DE9100A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; - targetProxy = 52D82BF516A627100078DFE5 /* PBXContainerItemProxy */; + target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; + targetProxy = D4E0E9752224DE9100A802E0 /* PBXContainerItemProxy */; }; - 5346481B17331ED800FE9172 /* PBXTargetDependency */ = { + D4E0E97A2224DEE600A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */; - targetProxy = 5346481A17331ED800FE9172 /* PBXContainerItemProxy */; + target = 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */; + targetProxy = D4E0E9792224DEE600A802E0 /* PBXContainerItemProxy */; }; - 5E10995419A5E80B00A60E2B /* PBXTargetDependency */ = { + D4E0E97C2224DF0300A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5E10992419A5E55800A60E2B /* ISACLProtectedItems */; - targetProxy = 5E10995319A5E80B00A60E2B /* PBXContainerItemProxy */; + target = 4CB740A20A47567C00D641BB /* securitytool_ios */; + targetProxy = D4E0E97B2224DF0300A802E0 /* PBXContainerItemProxy */; }; - 5EF7C2561B00EEF900E5E99C /* PBXTargetDependency */ = { + D4E0E97E2224DF0B00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5EBE24791B00CCAE0007DB0E /* secacltests */; - targetProxy = 5EF7C2551B00EEF900E5E99C /* PBXContainerItemProxy */; + target = 7913B1FF0D172B3900601FE9 /* sslServer */; + targetProxy = D4E0E97D2224DF0B00A802E0 /* PBXContainerItemProxy */; }; - 6C24EF4A1E415109000DE79F /* PBXTargetDependency */ = { + D4E0E9802224DF0B00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; - targetProxy = 6C24EF491E415109000DE79F /* PBXContainerItemProxy */; + target = 4C9DE9D11181AC4800CF5C27 /* sslEcdsa */; + targetProxy = D4E0E97F2224DF0B00A802E0 /* PBXContainerItemProxy */; }; - 6C24EF531E415132000DE79F /* PBXTargetDependency */ = { + D4E0E9822224DF0B00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; - targetProxy = 6C24EF521E415132000DE79F /* PBXContainerItemProxy */; + target = 4CE5A54C09C796E100D27A3F /* sslViewer */; + targetProxy = D4E0E9812224DF0B00A802E0 /* PBXContainerItemProxy */; }; - 6C7C38811FD88C4700DFFE68 /* PBXTargetDependency */ = { + D4E0E9862224DF4E00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; - targetProxy = 6C7C38801FD88C4700DFFE68 /* PBXContainerItemProxy */; + target = D41257CE1E9410A300781F23 /* trustd_ios */; + targetProxy = D4E0E9852224DF4E00A802E0 /* PBXContainerItemProxy */; }; - 6C7C38881FD88C5A00DFFE68 /* PBXTargetDependency */ = { + D4E0E9882224DF5800A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; - targetProxy = 6C7C38871FD88C5A00DFFE68 /* PBXContainerItemProxy */; + target = 790851B50CA9859F0083CC4D /* securityd_ios */; + targetProxy = D4E0E9872224DF5800A802E0 /* PBXContainerItemProxy */; }; - 6C98082F1E788AEB00E70590 /* PBXTargetDependency */ = { + D4E0E98A2224DF6F00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; - targetProxy = 6C9808301E788AEB00E70590 /* PBXContainerItemProxy */; + target = DC05037521409A4000A8EDB7 /* OCMockUmbrella */; + targetProxy = D4E0E9892224DF6F00A802E0 /* PBXContainerItemProxy */; }; - 6C9808311E788AEB00E70590 /* PBXTargetDependency */ = { + D4E0E98C2224DF7700A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 6C9808321E788AEB00E70590 /* PBXContainerItemProxy */; + target = EB108F181E6CE4D2003B0456 /* KCPairingTests */; + targetProxy = D4E0E98B2224DF7700A802E0 /* PBXContainerItemProxy */; }; - 6C9808351E788AEB00E70590 /* PBXTargetDependency */ = { + D4E0E98E2224DF7D00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = 6C9808361E788AEB00E70590 /* PBXContainerItemProxy */; + target = E7D847CD1C6BE9720025BB44 /* KeychainCircleTests */; + targetProxy = D4E0E98D2224DF7D00A802E0 /* PBXContainerItemProxy */; }; - 6C9808371E788AEB00E70590 /* PBXTargetDependency */ = { + D4E0E9902224DF8500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; - targetProxy = 6C9808381E788AEB00E70590 /* PBXContainerItemProxy */; + target = D458C505214E20530043D982 /* TrustTests */; + targetProxy = D4E0E98F2224DF8500A802E0 /* PBXContainerItemProxy */; }; - 6C9808391E788AEB00E70590 /* PBXTargetDependency */ = { + D4E0E9922224DF8500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = 6C98083A1E788AEB00E70590 /* PBXContainerItemProxy */; + target = D4707A0421136E69005BCFDA /* TrustTests_ios */; + targetProxy = D4E0E9912224DF8500A802E0 /* PBXContainerItemProxy */; }; - 6C98083B1E788AEB00E70590 /* PBXTargetDependency */ = { + D4E0E9942224DF8D00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; - targetProxy = 6C98083C1E788AEB00E70590 /* PBXContainerItemProxy */; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = D4E0E9932224DF8D00A802E0 /* PBXContainerItemProxy */; }; - 6C98086B1E788AFD00E70590 /* PBXTargetDependency */ = { + D4E0E9962224DF9300A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; - targetProxy = 6C98086C1E788AFD00E70590 /* PBXContainerItemProxy */; + target = BED208D41EDF950E00753952 /* manifeststresstest */; + targetProxy = D4E0E9952224DF9300A802E0 /* PBXContainerItemProxy */; }; - 6C98086D1E788AFD00E70590 /* PBXTargetDependency */ = { + D4E0E9982224DF9A00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 6C98086E1E788AFD00E70590 /* PBXContainerItemProxy */; + target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; + targetProxy = D4E0E9972224DF9A00A802E0 /* PBXContainerItemProxy */; }; - 6C9808711E788AFD00E70590 /* PBXTargetDependency */ = { + D4E0E99A2224DFAD00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = 6C9808721E788AFD00E70590 /* PBXContainerItemProxy */; + target = E710C7411331946400F85568 /* SecurityTests */; + targetProxy = D4E0E9992224DFAD00A802E0 /* PBXContainerItemProxy */; }; - 6C9808731E788AFD00E70590 /* PBXTargetDependency */ = { + D4E0E99C2224DFB500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; - targetProxy = 6C9808741E788AFD00E70590 /* PBXContainerItemProxy */; + target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; + targetProxy = D4E0E99B2224DFB500A802E0 /* PBXContainerItemProxy */; }; - 6C9808751E788AFD00E70590 /* PBXTargetDependency */ = { + D4E0E99E2224DFBA00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = 6C9808761E788AFD00E70590 /* PBXContainerItemProxy */; + target = 0C6799F912F7C37C00712919 /* dtlsTests */; + targetProxy = D4E0E99D2224DFBA00A802E0 /* PBXContainerItemProxy */; }; - 6C9808771E788AFD00E70590 /* PBXTargetDependency */ = { + D4E0E9A02224DFC500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; - targetProxy = 6C9808781E788AFD00E70590 /* PBXContainerItemProxy */; + target = 5EBE24791B00CCAE0007DB0E /* secacltests */; + targetProxy = D4E0E99F2224DFC500A802E0 /* PBXContainerItemProxy */; }; - 6C9808A01E788B9400E70590 /* PBXTargetDependency */ = { + D4E0E9A22224DFCB00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CF4A0B31E45488B00ECD7B5 /* KeychainEntitledTestApp_mac */; - targetProxy = 6C98089F1E788B9400E70590 /* PBXContainerItemProxy */; + target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; + targetProxy = D4E0E9A12224DFCB00A802E0 /* PBXContainerItemProxy */; }; - 6C9808A41E788CB100E70590 /* PBXTargetDependency */ = { + D4E0E9A42224DFD500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */; - targetProxy = 6C9808A31E788CB100E70590 /* PBXContainerItemProxy */; + target = EB49B2AD202D877F003F34A0 /* secdmockaks */; + targetProxy = D4E0E9A32224DFD500A802E0 /* PBXContainerItemProxy */; }; - 6C9A49B21FAB647D00239D58 /* PBXTargetDependency */ = { + D4E0E9A62224DFDD00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = 6C9A49B11FAB647D00239D58 /* PBXContainerItemProxy */; + target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; + targetProxy = D4E0E9A52224DFDD00A802E0 /* PBXContainerItemProxy */; }; - 6CAA8CE51F82FD08007B6E03 /* PBXTargetDependency */ = { + D4E0E9A82224DFDD00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; - targetProxy = 6CAA8CE41F82FD08007B6E03 /* PBXContainerItemProxy */; + target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; + targetProxy = D4E0E9A72224DFDD00A802E0 /* PBXContainerItemProxy */; }; - 6CAA8CE91F82FD13007B6E03 /* PBXTargetDependency */ = { + D4E0E9AA2224DFDD00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C9AA79D1F7C1D8F00D08296 /* supdctl */; - targetProxy = 6CAA8CE81F82FD13007B6E03 /* PBXContainerItemProxy */; + target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; + targetProxy = D4E0E9A92224DFDD00A802E0 /* PBXContainerItemProxy */; }; - 6CAA8D3D1F8431BC007B6E03 /* PBXTargetDependency */ = { + D4E0E9AC2224DFEB00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; - targetProxy = 6CAA8D3C1F8431BC007B6E03 /* PBXContainerItemProxy */; + target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; + targetProxy = D4E0E9AB2224DFEB00A802E0 /* PBXContainerItemProxy */; }; - 6CAA8D3F1F8431C9007B6E03 /* PBXTargetDependency */ = { + D4E0E9AE2224E00600A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CAA8D1F1F842FB3007B6E03 /* securityuploadd */; - targetProxy = 6CAA8D3E1F8431C9007B6E03 /* PBXContainerItemProxy */; + target = 4CB740A20A47567C00D641BB /* securitytool_ios */; + targetProxy = D4E0E9AD2224E00600A802E0 /* PBXContainerItemProxy */; }; - ACBAF6FE1E941E090007BA2F /* PBXTargetDependency */ = { + D4E0E9B02224E00F00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = ACBAF6991E9417F40007BA2F /* security_transform_regressions */; - targetProxy = ACBAF6FD1E941E090007BA2F /* PBXContainerItemProxy */; + target = 7913B1FF0D172B3900601FE9 /* sslServer */; + targetProxy = D4E0E9AF2224E00F00A802E0 /* PBXContainerItemProxy */; }; - BE061EAC1EE5EA5600B22118 /* PBXTargetDependency */ = { + D4E0E9B22224E00F00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BED208D41EDF950E00753952 /* manifeststresstest */; - targetProxy = BE061EAB1EE5EA5600B22118 /* PBXContainerItemProxy */; + target = 4C9DE9D11181AC4800CF5C27 /* sslEcdsa */; + targetProxy = D4E0E9B12224E00F00A802E0 /* PBXContainerItemProxy */; }; - BE061EB31EE5EAC800B22118 /* PBXTargetDependency */ = { + D4E0E9B42224E00F00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BED208D41EDF950E00753952 /* manifeststresstest */; - targetProxy = BE061EB21EE5EAC800B22118 /* PBXContainerItemProxy */; + target = 4CE5A54C09C796E100D27A3F /* sslViewer */; + targetProxy = D4E0E9B32224E00F00A802E0 /* PBXContainerItemProxy */; }; - BE061EB71EE5EB9000B22118 /* PBXTargetDependency */ = { + D4E0E9BC2224E15500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BED208D41EDF950E00753952 /* manifeststresstest */; - targetProxy = BE061EB61EE5EB9000B22118 /* PBXContainerItemProxy */; + target = E060D19B2124780E0025B833 /* OctagonTestHarness */; + targetProxy = D4E0E9BB2224E15500A802E0 /* PBXContainerItemProxy */; }; - BE061EB91EE5EBA000B22118 /* PBXTargetDependency */ = { + D4E0E9BE2224E15E00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BED208D41EDF950E00753952 /* manifeststresstest */; - targetProxy = BE061EB81EE5EBA000B22118 /* PBXContainerItemProxy */; + target = E060D19B2124780E0025B833 /* OctagonTestHarness */; + targetProxy = D4E0E9BD2224E15E00A802E0 /* PBXContainerItemProxy */; }; - BE197F631911742900BA91D1 /* PBXTargetDependency */ = { + D4E0E9C02224E16A00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BE197F2519116FD100BA91D1 /* SharedWebCredentialViewService */; - targetProxy = BE197F621911742900BA91D1 /* PBXContainerItemProxy */; + target = E060D19B2124780E0025B833 /* OctagonTestHarness */; + targetProxy = D4E0E9BF2224E16A00A802E0 /* PBXContainerItemProxy */; }; - BE4AC9B418B8020400B84964 /* PBXTargetDependency */ = { + D4E0E9C22224E17300A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BE442BA018B7FDB800F24DAE /* swcagent */; - targetProxy = BE4AC9B318B8020400B84964 /* PBXContainerItemProxy */; + target = E060D19B2124780E0025B833 /* OctagonTestHarness */; + targetProxy = D4E0E9C12224E17300A802E0 /* PBXContainerItemProxy */; }; - BE9C38C81EB115A7007E2AE1 /* PBXTargetDependency */ = { + D4E0E9C52224E71600A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; - targetProxy = BE9C38C71EB115A7007E2AE1 /* PBXContainerItemProxy */; + target = DC52EC3E1D80D00800B0A59C /* libSWCAgent */; + targetProxy = D4E0E9C42224E71600A802E0 /* PBXContainerItemProxy */; }; - BE9C38CF1EB115C9007E2AE1 /* PBXTargetDependency */ = { + D4E0E9C72224E76100A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; - targetProxy = BE9C38CE1EB115C9007E2AE1 /* PBXContainerItemProxy */; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = D4E0E9C62224E76100A802E0 /* PBXContainerItemProxy */; }; - BE9C38D11EB115F4007E2AE1 /* PBXTargetDependency */ = { + D4E0E9CB2224FB5700A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BEF88C2F1EAFFC3F00357577 /* TrustedPeersTests */; - targetProxy = BE9C38D01EB115F4007E2AE1 /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = D4E0E9CA2224FB5700A802E0 /* PBXContainerItemProxy */; }; - BE9C38D31EB11605007E2AE1 /* PBXTargetDependency */ = { + D4E0E9CF2224FD7A00A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BEF88C2F1EAFFC3F00357577 /* TrustedPeersTests */; - targetProxy = BE9C38D21EB11605007E2AE1 /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = D4E0E9CE2224FD7A00A802E0 /* PBXContainerItemProxy */; }; - BEF88C331EAFFC3F00357577 /* PBXTargetDependency */ = { + D4E0E9D12224FE3300A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; - targetProxy = BEF88C321EAFFC3F00357577 /* PBXContainerItemProxy */; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = D4E0E9D02224FE3300A802E0 /* PBXContainerItemProxy */; }; - D40B6A7F1E2B5F3D00CD6EE5 /* PBXTargetDependency */ = { + D4E0E9D32224FE3300A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D40B6A7E1E2B5F3D00CD6EE5 /* PBXContainerItemProxy */; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = D4E0E9D22224FE3300A802E0 /* PBXContainerItemProxy */; }; - D40B6A811E2B5F4700CD6EE5 /* PBXTargetDependency */ = { + D4E0E9D52224FE4100A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D40B6A801E2B5F4700CD6EE5 /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = D4E0E9D42224FE4100A802E0 /* PBXContainerItemProxy */; }; - D40B6A861E2B5F7600CD6EE5 /* PBXTargetDependency */ = { + D4E0E9D72225023600A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D40B6A851E2B5F7600CD6EE5 /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = D4E0E9D62225023600A802E0 /* PBXContainerItemProxy */; }; - D40B6A8C1E2B63D100CD6EE5 /* PBXTargetDependency */ = { + D4E0E9DB2225D14500A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D40B6A8B1E2B63D100CD6EE5 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = D4E0E9DA2225D14500A802E0 /* PBXContainerItemProxy */; }; - D40B6A921E2B678D00CD6EE5 /* PBXTargetDependency */ = { + D4E0E9DD2225D1E600A802E0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D40B6A911E2B678D00CD6EE5 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = D4E0E9DC2225D1E600A802E0 /* PBXContainerItemProxy */; }; - D40B6A951E2B67FF00CD6EE5 /* PBXTargetDependency */ = { + D4EB53B9223C3CE3009101F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D40B6A941E2B67FF00CD6EE5 /* PBXContainerItemProxy */; + target = D458C505214E20530043D982 /* TrustTests */; + targetProxy = D4EB53B8223C3CE3009101F8 /* PBXContainerItemProxy */; }; - D41257E61E941ACC00781F23 /* PBXTargetDependency */ = { + D4EB53BB223C3CE3009101F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC0BCC211D8C684F00070CB0 /* utilities */; - targetProxy = D41257E51E941ACC00781F23 /* PBXContainerItemProxy */; + target = D4707A0421136E69005BCFDA /* TrustTests_ios */; + targetProxy = D4EB53BA223C3CE3009101F8 /* PBXContainerItemProxy */; }; - D41257E81E941AD200781F23 /* PBXTargetDependency */ = { + D4EB53BE223C3D2B009101F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D4ADA3181E2B41670031CEA3 /* libtrustd */; - targetProxy = D41257E71E941AD200781F23 /* PBXContainerItemProxy */; + target = DAE40BC520CF3E46002D5674 /* secitemcanarytest */; + targetProxy = D4EB53BD223C3D2B009101F8 /* PBXContainerItemProxy */; }; - D41257F11E941E7D00781F23 /* PBXTargetDependency */ = { + D4EB53C9223C4AB5009101F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D41257CE1E9410A300781F23 /* trustd_ios */; - targetProxy = D41257F01E941E7D00781F23 /* PBXContainerItemProxy */; + target = 5E10992419A5E55800A60E2B /* ISACLProtectedItems */; + targetProxy = D4EB53C8223C4AB5009101F8 /* PBXContainerItemProxy */; }; - D41257F31E941E8600781F23 /* PBXTargetDependency */ = { + D4EB53CB223C4ABE009101F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D41257CE1E9410A300781F23 /* trustd_ios */; - targetProxy = D41257F21E941E8600781F23 /* PBXContainerItemProxy */; + target = 5E10992419A5E55800A60E2B /* ISACLProtectedItems */; + targetProxy = D4EB53CA223C4ABE009101F8 /* PBXContainerItemProxy */; }; - D41257F51E941E8E00781F23 /* PBXTargetDependency */ = { + D4F47B2D22270B23003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D41257CE1E9410A300781F23 /* trustd_ios */; - targetProxy = D41257F41E941E8E00781F23 /* PBXContainerItemProxy */; + target = D4F56B86217FA32000FCA6B7 /* Security_executables_core_ios */; + targetProxy = D4F47B2C22270B23003483E9 /* PBXContainerItemProxy */; }; - D41257F71E941E9600781F23 /* PBXTargetDependency */ = { + D4F47B3122270B38003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D41257CE1E9410A300781F23 /* trustd_ios */; - targetProxy = D41257F61E941E9600781F23 /* PBXContainerItemProxy */; + target = D4F56BC621813ECF00FCA6B7 /* Security_internal_ios */; + targetProxy = D4F47B3022270B38003483E9 /* PBXContainerItemProxy */; }; - D419C0261E57EACA008619D1 /* PBXTargetDependency */ = { + D4F47B3322270B4E003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CE5A54C09C796E100D27A3F /* sslViewer */; - targetProxy = D419C0251E57EACA008619D1 /* PBXContainerItemProxy */; + target = D4D1D40821ADC9720012C66C /* Security_executables_core_osx */; + targetProxy = D4F47B3222270B4E003483E9 /* PBXContainerItemProxy */; }; - D41AD43A1B96721E008C7270 /* PBXTargetDependency */ = { + D4F47B3722270B5D003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 790851B50CA9859F0083CC4D /* securityd_ios */; - targetProxy = D41AD4391B96721E008C7270 /* PBXContainerItemProxy */; + target = D4F56BC221813EC900FCA6B7 /* Security_internal_osx */; + targetProxy = D4F47B3622270B5D003483E9 /* PBXContainerItemProxy */; }; - D41AD43C1B96723B008C7270 /* PBXTargetDependency */ = { + D4F47B4522270BB6003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E710C7411331946400F85568 /* SecurityTests */; - targetProxy = D41AD43B1B96723B008C7270 /* PBXContainerItemProxy */; + target = D4F56B91217FA40800FCA6B7 /* Security_frameworks_watchos */; + targetProxy = D4F47B4422270BB6003483E9 /* PBXContainerItemProxy */; }; - D41AD43E1B967242008C7270 /* PBXTargetDependency */ = { + D4F47B4722270BB6003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; - targetProxy = D41AD43D1B967242008C7270 /* PBXContainerItemProxy */; + target = D4D1D3FC21AD0B3F0012C66C /* Security_executables_core_watchos */; + targetProxy = D4F47B4622270BB6003483E9 /* PBXContainerItemProxy */; }; - D41AD4401B96724C008C7270 /* PBXTargetDependency */ = { + D4F47B4922270BB6003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C6799F912F7C37C00712919 /* dtlsTests */; - targetProxy = D41AD43F1B96724C008C7270 /* PBXContainerItemProxy */; + target = D41AD42D1B967169008C7270 /* Security_executables_watchos */; + targetProxy = D4F47B4822270BB6003483E9 /* PBXContainerItemProxy */; }; - D41AD4421B97866C008C7270 /* PBXTargetDependency */ = { + D4F47B4B22270BB6003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 7913B1FF0D172B3900601FE9 /* sslServer */; - targetProxy = D41AD4411B97866C008C7270 /* PBXContainerItemProxy */; + target = D4F56BCE21813EE800FCA6B7 /* Security_internal_watchos */; + targetProxy = D4F47B4A22270BB6003483E9 /* PBXContainerItemProxy */; }; - D41AD4441B978681008C7270 /* PBXTargetDependency */ = { + D4F47B4D22270BB6003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C9DE9D11181AC4800CF5C27 /* sslEcdsa */; - targetProxy = D41AD4431B978681008C7270 /* PBXContainerItemProxy */; + target = D477EE6421ED479500C9AAFF /* Security_tests_watchos */; + targetProxy = D4F47B4C22270BB6003483E9 /* PBXContainerItemProxy */; }; - D41AD4461B9786A3008C7270 /* PBXTargetDependency */ = { + D4F47B4F22270BC0003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CB740A20A47567C00D641BB /* securitytool_ios */; - targetProxy = D41AD4451B9786A3008C7270 /* PBXContainerItemProxy */; + target = BEAA0040202B728B00E51F45 /* Security_executables_Swift */; + targetProxy = D4F47B4E22270BC0003483E9 /* PBXContainerItemProxy */; }; - D41AD44A1B9786D8008C7270 /* PBXTargetDependency */ = { + D4F47B5122270BD9003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = F93C49021AB8FCE00047E01A /* ckcdiagnose.sh */; - targetProxy = D41AD4491B9786D8008C7270 /* PBXContainerItemProxy */; + target = D4F56B8D217FA3F800FCA6B7 /* Security_frameworks_tvos */; + targetProxy = D4F47B5022270BD9003483E9 /* PBXContainerItemProxy */; }; - D41AD44C1B9786E2008C7270 /* PBXTargetDependency */ = { + D4F47B5322270BD9003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5EBE24791B00CCAE0007DB0E /* secacltests */; - targetProxy = D41AD44B1B9786E2008C7270 /* PBXContainerItemProxy */; + target = D4D1D40121AD0B4B0012C66C /* Security_executables_core_tvos */; + targetProxy = D4F47B5222270BD9003483E9 /* PBXContainerItemProxy */; }; - D41AD44E1B978791008C7270 /* PBXTargetDependency */ = { + D4F47B5522270BD9003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5E10992419A5E55800A60E2B /* ISACLProtectedItems */; - targetProxy = D41AD44D1B978791008C7270 /* PBXContainerItemProxy */; + target = D41AD4311B967179008C7270 /* Security_executables_tvos */; + targetProxy = D4F47B5422270BD9003483E9 /* PBXContainerItemProxy */; }; - D41AD4521B9788B2008C7270 /* PBXTargetDependency */ = { + D4F47B5722270BD9003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; - targetProxy = D41AD4511B9788B2008C7270 /* PBXContainerItemProxy */; + target = D4F56BCA21813EDC00FCA6B7 /* Security_internal_tvos */; + targetProxy = D4F47B5622270BD9003483E9 /* PBXContainerItemProxy */; }; - D41AD45C1B978A7A008C7270 /* PBXTargetDependency */ = { + D4F47B5922270BD9003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 790851B50CA9859F0083CC4D /* securityd_ios */; - targetProxy = D41AD45B1B978A7A008C7270 /* PBXContainerItemProxy */; + target = D477EE6021ED477B00C9AAFF /* Security_tests_tvos */; + targetProxy = D4F47B5822270BD9003483E9 /* PBXContainerItemProxy */; }; - D41AD45E1B978A7C008C7270 /* PBXTargetDependency */ = { + D4F47B5B22270BDE003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CB740A20A47567C00D641BB /* securitytool_ios */; - targetProxy = D41AD45D1B978A7C008C7270 /* PBXContainerItemProxy */; + target = BEAA0040202B728B00E51F45 /* Security_executables_Swift */; + targetProxy = D4F47B5A22270BDE003483E9 /* PBXContainerItemProxy */; }; - D41AD4601B978E18008C7270 /* PBXTargetDependency */ = { + D4F47B5D22270BEB003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E710C7411331946400F85568 /* SecurityTests */; - targetProxy = D41AD45F1B978E18008C7270 /* PBXContainerItemProxy */; + target = DC6D1C70208A547400AB21AF /* Security_frameworks_bridge */; + targetProxy = D4F47B5C22270BEB003483E9 /* PBXContainerItemProxy */; }; - D41AD4621B978E24008C7270 /* PBXTargetDependency */ = { + D4F47B5F22270BEB003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C0BDB2E175685B000BC1A7E /* secdtests_ios */; - targetProxy = D41AD4611B978E24008C7270 /* PBXContainerItemProxy */; + target = EB6A6FAE1B90F8810045DC68 /* Security_executables_bridge */; + targetProxy = D4F47B5E22270BEB003483E9 /* PBXContainerItemProxy */; }; - D41AD4661B978F19008C7270 /* PBXTargetDependency */ = { + D4F47B6122270BEB003483E9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C6799F912F7C37C00712919 /* dtlsTests */; - targetProxy = D41AD4651B978F19008C7270 /* PBXContainerItemProxy */; + target = D477EE5C21ED476D00C9AAFF /* Security_tests_bridge */; + targetProxy = D4F47B6022270BEB003483E9 /* PBXContainerItemProxy */; }; - D41AD4681B978F20008C7270 /* PBXTargetDependency */ = { + D4F56B9D217FCA7E00FCA6B7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 7913B1FF0D172B3900601FE9 /* sslServer */; - targetProxy = D41AD4671B978F20008C7270 /* PBXContainerItemProxy */; + target = 4C32C0AE0A4975F6002891BD /* Security_ios */; + targetProxy = D4F56B9C217FCA7E00FCA6B7 /* PBXContainerItemProxy */; }; - D41AD46A1B978F24008C7270 /* PBXTargetDependency */ = { + D4F56B9F217FCA8600FCA6B7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CE5A54C09C796E100D27A3F /* sslViewer */; - targetProxy = D41AD4691B978F24008C7270 /* PBXContainerItemProxy */; + target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; + targetProxy = D4F56B9E217FCA8600FCA6B7 /* PBXContainerItemProxy */; }; - D41AD46C1B978F28008C7270 /* PBXTargetDependency */ = { + D4F56BA5217FCAAA00FCA6B7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C9DE9D11181AC4800CF5C27 /* sslEcdsa */; - targetProxy = D41AD46B1B978F28008C7270 /* PBXContainerItemProxy */; + target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; + targetProxy = D4F56BA4217FCAAA00FCA6B7 /* PBXContainerItemProxy */; }; - D41AD46E1B978F4C008C7270 /* PBXTargetDependency */ = { + D4F56BA7217FCAB000FCA6B7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 5EBE24791B00CCAE0007DB0E /* secacltests */; - targetProxy = D41AD46D1B978F4C008C7270 /* PBXContainerItemProxy */; + target = 4C32C0AE0A4975F6002891BD /* Security_ios */; + targetProxy = D4F56BA6217FCAB000FCA6B7 /* PBXContainerItemProxy */; + }; + D4F56BAB217FCAF600FCA6B7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; + targetProxy = D4F56BAA217FCAF600FCA6B7 /* PBXContainerItemProxy */; + }; + D4F56BB32181306900FCA6B7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; + targetProxy = D4F56BB22181306900FCA6B7 /* PBXContainerItemProxy */; + }; + D4F56BB72181380600FCA6B7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; + targetProxy = D4F56BB62181380600FCA6B7 /* PBXContainerItemProxy */; + }; + D4F56BBB2181387600FCA6B7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; + targetProxy = D4F56BBA2181387600FCA6B7 /* PBXContainerItemProxy */; }; DA30D6821DF8C93500EC6B43 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DA30D6751DF8C8FB00EC6B43 /* KeychainSyncAccountUpdater */; targetProxy = DA30D6811DF8C93500EC6B43 /* PBXContainerItemProxy */; }; - DAE40BD520CF3ED5002D5674 /* PBXTargetDependency */ = { + DA41FE1D2241B64800838FB3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DAE40BC520CF3E46002D5674 /* secitemcanarytest */; - targetProxy = DAE40BD420CF3ED5002D5674 /* PBXContainerItemProxy */; + target = DA41FE0D2241ADC000838FB3 /* otpaird */; + targetProxy = DA41FE1C2241B64800838FB3 /* PBXContainerItemProxy */; + }; + DA41FE1F2241B65A00838FB3 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DA41FE0D2241ADC000838FB3 /* otpaird */; + targetProxy = DA41FE1E2241B65A00838FB3 /* PBXContainerItemProxy */; }; DC0067901D878132005AF8DB /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -32338,21 +38268,6 @@ target = DC52EC211D80CFB200B0A59C /* SOSCommands */; targetProxy = DC00AB911D821D6000513D74 /* PBXContainerItemProxy */; }; - DC00AB941D821D6500513D74 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC52EBC61D80CEF100B0A59C /* SecurityCommands */; - targetProxy = DC00AB931D821D6500513D74 /* PBXContainerItemProxy */; - }; - DC00AB961D821D6800513D74 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC52EA441D80CB7000B0A59C /* SecurityTool */; - targetProxy = DC00AB951D821D6800513D74 /* PBXContainerItemProxy */; - }; - DC00AB9E1D821DBB00513D74 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = DC00AB9D1D821DBB00513D74 /* PBXContainerItemProxy */; - }; DC00ABAA1D821DE600513D74 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; @@ -32443,6 +38358,36 @@ target = DC52EC601D80D0C400B0A59C /* SOSRegressions */; targetProxy = DC00ABEF1D821FBA00513D74 /* PBXContainerItemProxy */; }; + DC00C91620B3B73900628BEB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = DC00C91520B3B73900628BEB /* PBXContainerItemProxy */; + }; + DC00C91820B3B74600628BEB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = DC00C91720B3B74600628BEB /* PBXContainerItemProxy */; + }; + DC00C91A20B3B74E00628BEB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = DC00C91920B3B74E00628BEB /* PBXContainerItemProxy */; + }; + DC00C91F20B3B7A800628BEB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = DC00C91E20B3B7A800628BEB /* PBXContainerItemProxy */; + }; + DC00C92720B3B86800628BEB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = DC00C92620B3B86800628BEB /* PBXContainerItemProxy */; + }; + DC0503612140848100A8EDB7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BED987D22099145300607A5F /* TrustedPeersHelperUnitTests */; + targetProxy = DC0503602140848100A8EDB7 /* PBXContainerItemProxy */; + }; DC0984F71E1DB6D400140ADC /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; @@ -32563,30 +38508,25 @@ target = DC0BCCF41D8C694700070CB0 /* utilitiesRegressions */; targetProxy = DC0BCDBA1D8C6AF000070CB0 /* PBXContainerItemProxy */; }; - DC1789791D779C6700B50D50 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libsecurity_smime; - targetProxy = DC1789781D779C6700B50D50 /* PBXContainerItemProxy */; - }; DC178BF31D77ABE300B50D50 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC1789031D77980500B50D50 /* Security_osx */; targetProxy = DC178BF21D77ABE300B50D50 /* PBXContainerItemProxy */; }; - DC193C6020CB4C9D009C1A0F /* PBXTargetDependency */ = { + DC2671101F3E933700816EED /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = libsecurity_cms_regressions; - targetProxy = DC193C5F20CB4C9D009C1A0F /* PBXContainerItemProxy */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = DC26710F1F3E933700816EED /* PBXContainerItemProxy */; }; - DC222C791E034EE700B09171 /* PBXTargetDependency */ = { + DC27C3CD20EAFDF800F7839C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC222C371E034D1F00B09171 /* libsecurityd_ios_NO_AKS */; - targetProxy = DC222C781E034EE700B09171 /* PBXContainerItemProxy */; + target = DC99B85B20EACA470065B73B /* OctagonTests */; + targetProxy = DC27C3CC20EAFDF800F7839C /* PBXContainerItemProxy */; }; - DC2671101F3E933700816EED /* PBXTargetDependency */ = { + DC311E672124A9D2002F5EAE /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; - targetProxy = DC26710F1F3E933700816EED /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DC311E662124A9D2002F5EAE /* PBXContainerItemProxy */; }; DC34CD2D20326C2C00302481 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -32605,7 +38545,7 @@ }; DC3502C41E020D4D00BC0587 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC3502C31E020D4D00BC0587 /* PBXContainerItemProxy */; }; DC3502CE1E020E2200BC0587 /* PBXTargetDependency */ = { @@ -32618,35 +38558,40 @@ target = DCC78EA81D8088E200865A7C /* security */; targetProxy = DC3502D41E02117600BC0587 /* PBXContainerItemProxy */; }; + DC391FA321C03F8D00772585 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 0C8BBEFD1FCB446400580909 /* otctl */; + targetProxy = DC391FA221C03F8D00772585 /* PBXContainerItemProxy */; + }; DC3A4B6B1D91EBEE00E46D4A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC3A4B571D91E9FB00E46D4A /* CodeSigningHelper */; targetProxy = DC3A4B6A1D91EBEE00E46D4A /* PBXContainerItemProxy */; }; - DC5224F91E4029520021640A /* PBXTargetDependency */ = { + DC3E18CA212501C200073D80 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC3502B41E0208BE00BC0587 /* CKKSTests */; - targetProxy = DC5224F81E4029520021640A /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DC3E18C9212501C200073D80 /* PBXContainerItemProxy */; }; - DC5225001E40295C0021640A /* PBXTargetDependency */ = { + DC3E18CC2125020400073D80 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC3502B41E0208BE00BC0587 /* CKKSTests */; - targetProxy = DC5224FF1E40295C0021640A /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DC3E18CB2125020400073D80 /* PBXContainerItemProxy */; }; - DC52E84B1D80BF1100B0A59C /* PBXTargetDependency */ = { + DC3E18CE2125024C00073D80 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; - targetProxy = DC52E84A1D80BF1100B0A59C /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DC3E18CD2125024C00073D80 /* PBXContainerItemProxy */; }; - DC52EAA51D80CCF600B0A59C /* PBXTargetDependency */ = { + DC3E18E82125F9EF00073D80 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52EA441D80CB7000B0A59C /* SecurityTool */; - targetProxy = DC52EAA41D80CCF600B0A59C /* PBXContainerItemProxy */; + target = DC36895D21235F42003A3735 /* aks_mock */; + targetProxy = DC3E18E72125F9EF00073D80 /* PBXContainerItemProxy */; }; - DC52EC201D80CF7400B0A59C /* PBXTargetDependency */ = { + DC52E84B1D80BF1100B0A59C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC52EBC61D80CEF100B0A59C /* SecurityCommands */; - targetProxy = DC52EC1F1D80CF7400B0A59C /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DC52E84A1D80BF1100B0A59C /* PBXContainerItemProxy */; }; DC52EC3D1D80CFF000B0A59C /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -32698,26 +38643,11 @@ target = DC52EE661D80D82600B0A59C /* SecItemShimOSX */; targetProxy = DC52EE7D1D80D8B100B0A59C /* PBXContainerItemProxy */; }; - DC58C42A1D77BE03003C25A4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC1789031D77980500B50D50 /* Security_osx */; - targetProxy = DC58C4291D77BE03003C25A4 /* PBXContainerItemProxy */; - }; DC58C4431D77C1F8003C25A4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC58C4221D77BDEA003C25A4 /* csparser_osx */; targetProxy = DC58C4421D77C1F8003C25A4 /* PBXContainerItemProxy */; }; - DC59E9A61D91C710001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libCMSInstall; - targetProxy = DC59E9A51D91C710001BDDF5 /* PBXContainerItemProxy */; - }; - DC59E9A91D91C7CC001BDDF5 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - name = libCMS; - targetProxy = DC59E9A81D91C7CC001BDDF5 /* PBXContainerItemProxy */; - }; DC5ABE1C1D832F5E00CF422C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC5ABDC41D832DAB00CF422C /* securitytool_macos */; @@ -32733,45 +38663,20 @@ name = securityd_service; targetProxy = DC5AC0BE1D83534300CF422C /* PBXContainerItemProxy */; }; - DC5AC12F1D8356DA00CF422C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC5AC04F1D8352D900CF422C /* securityd_macos */; - targetProxy = DC5AC12E1D8356DA00CF422C /* PBXContainerItemProxy */; - }; - DC61096B1D78E60C002223DE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5EBE24791B00CCAE0007DB0E /* secacltests */; - targetProxy = DC61096A1D78E60C002223DE /* PBXContainerItemProxy */; - }; - DC61096D1D78E72C002223DE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EB9C1D791BDFD0E000F89272 /* secbackupntest */; - targetProxy = DC61096C1D78E72C002223DE /* PBXContainerItemProxy */; - }; - DC610A381D78F15C002223DE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC610A021D78F129002223DE /* secdtests_macos */; - targetProxy = DC610A371D78F15C002223DE /* PBXContainerItemProxy */; - }; - DC610A421D78F3A5002223DE /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93C49021AB8FCE00047E01A /* ckcdiagnose.sh */; - targetProxy = DC610A411D78F3A5002223DE /* PBXContainerItemProxy */; - }; - DC610A541D78F759002223DE /* PBXTargetDependency */ = { + DC6013372147222B00863C1A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC610A461D78F48F002223DE /* SecTaskTest_macos */; - targetProxy = DC610A531D78F759002223DE /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DC6013362147222B00863C1A /* PBXContainerItemProxy */; }; - DC610A6C1D78FAA2002223DE /* PBXTargetDependency */ = { + DC60133D214722C900863C1A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC610A551D78F9D2002223DE /* codesign_tests_macos */; - targetProxy = DC610A6B1D78FAA2002223DE /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DC60133C214722C900863C1A /* PBXContainerItemProxy */; }; - DC610ABC1D791139002223DE /* PBXTargetDependency */ = { + DC6063B021B0755D00069B82 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC610AAD1D7910C3002223DE /* gk_reset_check_macos */; - targetProxy = DC610ABB1D791139002223DE /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DC6063AF21B0755D00069B82 /* PBXContainerItemProxy */; }; DC63CAF31D90DF6000C03317 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -32788,10 +38693,25 @@ target = DC63CAE81D90D63500C03317 /* libsecurityd_macos_mig */; targetProxy = DC63CAF61D90DF7000C03317 /* PBXContainerItemProxy */; }; - DC63CAFA1D91A16700C03317 /* PBXTargetDependency */ = { + DC647C44208A85BE00D0F9F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; + targetProxy = DC647C43208A85BE00D0F9F8 /* PBXContainerItemProxy */; + }; + DC647C46208A85C900D0F9F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEF88C271EAFFC3F00357577 /* TrustedPeers */; + targetProxy = DC647C45208A85C900D0F9F8 /* PBXContainerItemProxy */; + }; + DC647C48208A864800D0F9F8 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = libsecurity_cms_regressions; - targetProxy = DC63CAF91D91A16700C03317 /* PBXContainerItemProxy */; + target = BEAA0040202B728B00E51F45 /* Security_executables_Swift */; + targetProxy = DC647C47208A864800D0F9F8 /* PBXContainerItemProxy */; + }; + DC647C4A208A865200D0F9F8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEAA0040202B728B00E51F45 /* Security_executables_Swift */; + targetProxy = DC647C49208A865200D0F9F8 /* PBXContainerItemProxy */; }; DC65E7221D8CB27900152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -32840,12 +38760,12 @@ }; DC65E7421D8CB3D400152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC65E7411D8CB3D400152EF0 /* PBXContainerItemProxy */; }; DC65E7441D8CB3E000152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC65E7431D8CB3E000152EF0 /* PBXContainerItemProxy */; }; DC65E7461D8CB3E700152EF0 /* PBXTargetDependency */ = { @@ -32870,7 +38790,7 @@ }; DC65E74E1D8CB41E00152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC65E74D1D8CB41E00152EF0 /* PBXContainerItemProxy */; }; DC65E7501D8CB42700152EF0 /* PBXTargetDependency */ = { @@ -32900,7 +38820,7 @@ }; DC65E75A1D8CB48900152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC65E7591D8CB48900152EF0 /* PBXContainerItemProxy */; }; DC65E75C1D8CB49200152EF0 /* PBXTargetDependency */ = { @@ -32915,7 +38835,7 @@ }; DC65E7601D8CB4A300152EF0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC65E75F1D8CB4A300152EF0 /* PBXContainerItemProxy */; }; DC65E7621D8CB4AA00152EF0 /* PBXTargetDependency */ = { @@ -32968,6 +38888,16 @@ target = DC0BCC211D8C684F00070CB0 /* utilities */; targetProxy = DC65E7731D8CB4FB00152EF0 /* PBXContainerItemProxy */; }; + DC69A5832165295F00512BD6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DC69A5822165295F00512BD6 /* PBXContainerItemProxy */; + }; + DC69A5872165298500512BD6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DC69A5862165298500512BD6 /* PBXContainerItemProxy */; + }; DC6BC2741D90D07800DD57B3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC6BC26C1D90CFEF00DD57B3 /* securityd_macos_startup */; @@ -32983,6 +38913,11 @@ target = DC6BC27C1D90D1EE00DD57B3 /* security_cssm_generator */; targetProxy = DC6BC2811D90D30F00DD57B3 /* PBXContainerItemProxy */; }; + DC6D1C73208A547400AB21AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 4C32C0AE0A4975F6002891BD /* Security_ios */; + targetProxy = DC6D1C74208A547400AB21AF /* PBXContainerItemProxy */; + }; DC71D8E41D959C000065FB93 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; @@ -32993,29 +38928,19 @@ target = DC0BCC211D8C684F00070CB0 /* utilities */; targetProxy = DC71D8EA1D959C130065FB93 /* PBXContainerItemProxy */; }; - DC71D9E11D95BAC40065FB93 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC71D99F1D95BA6C0065FB93 /* ASN1 */; - targetProxy = DC71D9E01D95BAC40065FB93 /* PBXContainerItemProxy */; - }; - DC71D9E31D95BAD50065FB93 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DC71D99F1D95BA6C0065FB93 /* ASN1 */; - targetProxy = DC71D9E21D95BAD50065FB93 /* PBXContainerItemProxy */; - }; DC71DA031D95BDEA0065FB93 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC71DA021D95BDEA0065FB93 /* PBXContainerItemProxy */; }; DC71DA051D95BDF90065FB93 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC71DA041D95BDF90065FB93 /* PBXContainerItemProxy */; }; DC71DA071D95BE2F0065FB93 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC71DA061D95BE2F0065FB93 /* PBXContainerItemProxy */; }; DC71DA0D1D95DD670065FB93 /* PBXTargetDependency */ = { @@ -33023,6 +38948,21 @@ target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; targetProxy = DC71DA0C1D95DD670065FB93 /* PBXContainerItemProxy */; }; + DC7479A022272361001E0E8C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */; + targetProxy = DC74799F22272361001E0E8C /* PBXContainerItemProxy */; + }; + DC7FC45221EE9208003C39B8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC7FC44721EE914C003C39B8 /* FeatureFlagsPlist */; + targetProxy = DC7FC45121EE9208003C39B8 /* PBXContainerItemProxy */; + }; + DC7FC45421EE921A003C39B8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC7FC44721EE914C003C39B8 /* FeatureFlagsPlist */; + targetProxy = DC7FC45321EE921A003C39B8 /* PBXContainerItemProxy */; + }; DC82FFEB1D90D4640085674B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC82FFE51D90D3F60085674B /* security_utilities_DTrace */; @@ -33035,9 +38975,39 @@ }; DC89998B1E410DBF00E6E604 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DC89998A1E410DBF00E6E604 /* PBXContainerItemProxy */; }; + DC93C4C9214713DC008F8362 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DC93C4C8214713DC008F8362 /* PBXContainerItemProxy */; + }; + DC93C4CD21471401008F8362 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DC93C4CC21471401008F8362 /* PBXContainerItemProxy */; + }; + DC99B85C20EACA470065B73B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = DC99B85D20EACA470065B73B /* PBXContainerItemProxy */; + }; + DC99B86220EACA470065B73B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = DC99B86320EACA470065B73B /* PBXContainerItemProxy */; + }; + DC99B86420EACA470065B73B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = DC99B86520EACA470065B73B /* PBXContainerItemProxy */; + }; + DCA232FC209A35840007B57D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEAA002A202A832500E51F45 /* TrustedPeersHelper */; + targetProxy = DCA232FB209A35840007B57D /* PBXContainerItemProxy */; + }; DCB332471F47857D00178C30 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52EC211D80CFB200B0A59C /* SOSCommands */; @@ -33045,7 +39015,7 @@ }; DCB340191D8A248C0054D16E /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DCB340181D8A248C0054D16E /* PBXContainerItemProxy */; }; DCB3408A1D8A25230054D16E /* PBXTargetDependency */ = { @@ -33078,40 +39048,85 @@ target = DCB343AD1D8A34FD0054D16E /* security_keychain_regressions */; targetProxy = DCB345B21D8A361F0054D16E /* PBXContainerItemProxy */; }; - DCB515D01ED3CC36001F1152 /* PBXTargetDependency */ = { + DCBF4A8B21FFC82100539F0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C9808681E788AFD00E70590 /* CKKSCloudKitTests_ios */; - targetProxy = DCB515CF1ED3CC36001F1152 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCBF4A8C21FFC82100539F0A /* PBXContainerItemProxy */; }; - DCB515D71ED3CC52001F1152 /* PBXTargetDependency */ = { + DCBF4A8D21FFC82100539F0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C98082C1E788AEB00E70590 /* CKKSCloudKitTests_mac */; - targetProxy = DCB515D61ED3CC52001F1152 /* PBXContainerItemProxy */; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DCBF4A8E21FFC82100539F0A /* PBXContainerItemProxy */; }; - DCB515D91ED3CC6B001F1152 /* PBXTargetDependency */ = { + DCBF4A8F21FFC82100539F0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CF4A0B31E45488B00ECD7B5 /* KeychainEntitledTestApp_mac */; - targetProxy = DCB515D81ED3CC6B001F1152 /* PBXContainerItemProxy */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = DCBF4A9021FFC82100539F0A /* PBXContainerItemProxy */; }; - DCB515DB1ED3CC73001F1152 /* PBXTargetDependency */ = { + DCBF4A9121FFC82100539F0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CF4A0DF1E4549F200ECD7B5 /* KeychainEntitledTestApp_ios */; - targetProxy = DCB515DA1ED3CC73001F1152 /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = DCBF4A9221FFC82100539F0A /* PBXContainerItemProxy */; }; - DCBE6E4A1D91E23D00A3E5E5 /* PBXTargetDependency */ = { + DCBF4A9321FFC82100539F0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD06A541D8CE2D5007602F1 /* gkunpack */; - targetProxy = DCBE6E491D91E23D00A3E5E5 /* PBXContainerItemProxy */; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = DCBF4A9421FFC82100539F0A /* PBXContainerItemProxy */; + }; + DCBF4A9521FFC82100539F0A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = DCBF4A9621FFC82100539F0A /* PBXContainerItemProxy */; + }; + DCBF4A9721FFC82100539F0A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = DCBF4A9821FFC82100539F0A /* PBXContainerItemProxy */; }; DCC093781D80ABC300F984E4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCC78EA81D8088E200865A7C /* security */; targetProxy = DCC093771D80ABC300F984E4 /* PBXContainerItemProxy */; }; - DCC5BF381D937329008D1E84 /* PBXTargetDependency */ = { + DCC5D6682087EDB300BBC127 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC0EF8EE208697C600AB9E95 /* tpctl */; + targetProxy = DCC5D6672087EDB300BBC127 /* PBXContainerItemProxy */; + }; + DCC5D66A2087EEE200BBC127 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BEAA0040202B728B00E51F45 /* Security_executables_Swift */; + targetProxy = DCC5D6692087EEE200BBC127 /* PBXContainerItemProxy */; + }; + DCC7A67B216435A40034967D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCC78EA81D8088E200865A7C /* security */; + targetProxy = DCC7A67A216435A40034967D /* PBXContainerItemProxy */; + }; + DCC7A67F216435B30034967D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E7731D80BC8000B0A59C /* libsecurityd_ios */; + targetProxy = DCC7A67E216435B30034967D /* PBXContainerItemProxy */; + }; + DCC7A682216446D30034967D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = DCC7A681216446D30034967D /* PBXContainerItemProxy */; + }; + DCC7A684216446D90034967D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = DCC7A683216446D90034967D /* PBXContainerItemProxy */; + }; + DCC7A686216446E50034967D /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; + targetProxy = DCC7A685216446E50034967D /* PBXContainerItemProxy */; + }; + DCC7A688216446EB0034967D /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = libsecurity_cms; - targetProxy = DCC5BF371D937329008D1E84 /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = DCC7A687216446EB0034967D /* PBXContainerItemProxy */; }; DCD067831D8CDF58007602F1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -33195,7 +39210,7 @@ }; DCD22D7D1D8CCA18001C9B81 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = DCD22D7C1D8CCA18001C9B81 /* PBXContainerItemProxy */; }; DCD22D7F1D8CCA2C001C9B81 /* PBXTargetDependency */ = { @@ -33223,6 +39238,31 @@ target = DCD66DC41D8205C400DB1393 /* SecOtrOSX */; targetProxy = DCD66DE51D82061F00DB1393 /* PBXContainerItemProxy */; }; + DCD6BF5421E919610015F7A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCD6BF5321E919610015F7A8 /* PBXContainerItemProxy */; + }; + DCD6BF5621E9196E0015F7A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCD6BF5521E9196E0015F7A8 /* PBXContainerItemProxy */; + }; + DCD6BF5821E919820015F7A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCD6BF5721E919820015F7A8 /* PBXContainerItemProxy */; + }; + DCD6BF5A21E919A60015F7A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCD6BF5921E919A60015F7A8 /* PBXContainerItemProxy */; + }; + DCD6BF5E21E919E10015F7A8 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCD6BF5D21E919E10015F7A8 /* PBXContainerItemProxy */; + }; DCD8A19C1E09EEA200E4FA0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; @@ -33258,11 +39298,6 @@ target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; targetProxy = DCD8A1F41E09F91F00E4FA0A /* PBXContainerItemProxy */; }; - DCD8A1F81E09F97300E4FA0A /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = DCD8A1F71E09F97300E4FA0A /* PBXContainerItemProxy */; - }; DCD8A1FB1E09F99700E4FA0A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; @@ -33278,76 +39313,66 @@ target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; targetProxy = DCD8A2021E09FAE500E4FA0A /* PBXContainerItemProxy */; }; - DCD8A2071E09FB1F00E4FA0A /* PBXTargetDependency */ = { + DCDA5E582124B9DC009B11B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = DCD8A2061E09FB1F00E4FA0A /* PBXContainerItemProxy */; + target = DC311E6E2124B8A8002F5EAE /* aks_real_witness */; + targetProxy = DCDA5E572124B9DC009B11B2 /* PBXContainerItemProxy */; }; - DCDB29761FD8839F00B5D242 /* PBXTargetDependency */ = { + DCDA5E5A2124BA2F009B11B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C85DFD11FB38BB6000343A7 /* OTTests */; - targetProxy = DCDB29751FD8839F00B5D242 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCDA5E592124BA2F009B11B2 /* PBXContainerItemProxy */; }; - DCDB29781FD883AB00B5D242 /* PBXTargetDependency */ = { + DCDA5E5C2124BA54009B11B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C85DFD11FB38BB6000343A7 /* OTTests */; - targetProxy = DCDB29771FD883AB00B5D242 /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCDA5E5B2124BA54009B11B2 /* PBXContainerItemProxy */; }; - DCE4E6AA1D7A38E700AFB96E /* PBXTargetDependency */ = { + DCDA5E5E2124BA79009B11B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCE4E68A1D7A37FA00AFB96E /* security2tool_macos */; - targetProxy = DCE4E6A91D7A38E700AFB96E /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCDA5E5D2124BA79009B11B2 /* PBXContainerItemProxy */; }; - DCE4E7B81D7A456500AFB96E /* PBXTargetDependency */ = { + DCDA5E622124BAD7009B11B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCE4E7311D7A43B500AFB96E /* SecurityTestsOSX */; - targetProxy = DCE4E7B71D7A456500AFB96E /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCDA5E612124BAD7009B11B2 /* PBXContainerItemProxy */; }; - DCE4E7BC1D7A45ED00AFB96E /* PBXTargetDependency */ = { + DCDA5E642124BCA9009B11B2 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = libsecurity_smime_regressions; - targetProxy = DCE4E7BB1D7A45ED00AFB96E /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = DCDA5E632124BCA9009B11B2 /* PBXContainerItemProxy */; }; - DCE4E7D81D7A4B3500AFB96E /* PBXTargetDependency */ = { + DCE0775C21ADD6A0002662FD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = libsecurity_smime_regressions; - targetProxy = DCE4E7D71D7A4B3500AFB96E /* PBXContainerItemProxy */; + target = DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */; + targetProxy = DCE0775B21ADD6A0002662FD /* PBXContainerItemProxy */; }; - DCE4E7F11D7A4BEC00AFB96E /* PBXTargetDependency */ = { + DCE0777E21ADEADA002662FD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCE4E7CB1D7A4AED00AFB96E /* sectests_macos */; - targetProxy = DCE4E7F01D7A4BEC00AFB96E /* PBXContainerItemProxy */; + target = DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */; + targetProxy = DCE0777D21ADEADA002662FD /* PBXContainerItemProxy */; }; - DCE4E82A1D7A4F2500AFB96E /* PBXTargetDependency */ = { + DCE0778421ADEDDA002662FD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DCE4E7F51D7A4DA800AFB96E /* secd */; - targetProxy = DCE4E8291D7A4F2500AFB96E /* PBXContainerItemProxy */; - }; - DCE4E8621D7A58BA00AFB96E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCE4E82D1D7A57AE00AFB96E /* trustd_macos */; - targetProxy = DCE4E8611D7A58BA00AFB96E /* PBXContainerItemProxy */; + target = DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */; + targetProxy = DCE0778321ADEDDA002662FD /* PBXContainerItemProxy */; }; DCE4E8D81D7F37F200AFB96E /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCE4E8931D7F34F600AFB96E /* authd */; targetProxy = DCE4E8D71D7F37F200AFB96E /* PBXContainerItemProxy */; }; - DCE4E90C1D7F3B4A00AFB96E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCE4E8DC1D7F39DB00AFB96E /* Cloud Keychain Utility */; - targetProxy = DCE4E90B1D7F3B4A00AFB96E /* PBXContainerItemProxy */; - }; - DCE4E9731D7F3FC200AFB96E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCE4E9101D7F3D5300AFB96E /* Keychain Circle Notification */; - targetProxy = DCE4E9721D7F3FC200AFB96E /* PBXContainerItemProxy */; - }; DCE5DC171EA804E5006308A6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC52EC211D80CFB200B0A59C /* SOSCommands */; targetProxy = DCE5DC161EA804E5006308A6 /* PBXContainerItemProxy */; }; + DCF19A6E21AE2CDC002E808F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = securitydservicectrl; + targetProxy = DCF19A6D21AE2CDC002E808F /* PBXContainerItemProxy */; + }; DCF785011D88B80600E694BB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DCF7830A1D88B4DE00E694BB /* security_apple_csp */; @@ -33378,121 +39403,46 @@ target = DCF788AB1D88CD2400E694BB /* security_apple_x509_tp */; targetProxy = DCF789451D88CD7C00E694BB /* PBXContainerItemProxy */; }; - E74583BE1BF66489001B54A4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; - targetProxy = E74583BD1BF66489001B54A4 /* PBXContainerItemProxy */; - }; - E745846D1BF68ECB001B54A4 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 05EF68BB194915A5007958C3 /* Security_executables_osx */; - targetProxy = E745846C1BF68ECB001B54A4 /* PBXContainerItemProxy */; - }; - E745846F1BF68ECB001B54A4 /* PBXTargetDependency */ = { + E060D1AB212478100025B833 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 05EF68C1194915FB007958C3 /* Security_kexts */; - targetProxy = E745846E1BF68ECB001B54A4 /* PBXContainerItemProxy */; + target = E060D1A62124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol */; + targetProxy = E060D1AA212478100025B833 /* PBXContainerItemProxy */; }; - E74584711BF68ECB001B54A4 /* PBXTargetDependency */ = { + E060D1BA212478120025B833 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 05EF68AF1949149C007958C3 /* Security_temporary_UI */; - targetProxy = E74584701BF68ECB001B54A4 /* PBXContainerItemProxy */; + target = E060D1B6212478110025B833 /* OctagonTestHarnessXPCService */; + targetProxy = E060D1B9212478120025B833 /* PBXContainerItemProxy */; }; - E79EEDD71CD3F9F800C2FBFC /* PBXTargetDependency */ = { + E060D1BC212478120025B833 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */; - targetProxy = E79EEDD61CD3F9F800C2FBFC /* PBXContainerItemProxy */; + target = E060D1A62124780F0025B833 /* OctagonTestHarnessXPCServiceProtocol */; + targetProxy = E060D1BB212478120025B833 /* PBXContainerItemProxy */; }; - E79EEDDF1CD3FFEA00C2FBFC /* PBXTargetDependency */ = { + E74583BE1BF66489001B54A4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E79EEDD81CD3FFC800C2FBFC /* Security_frameworks_osx */; - targetProxy = E79EEDDE1CD3FFEA00C2FBFC /* PBXContainerItemProxy */; + target = 52D82BDD16A621F70078DFE5 /* CloudKeychainProxy */; + targetProxy = E74583BD1BF66489001B54A4 /* PBXContainerItemProxy */; }; - E79EEDE51CD4001300C2FBFC /* PBXTargetDependency */ = { + E745846D1BF68ECB001B54A4 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 05EF68BB194915A5007958C3 /* Security_executables_osx */; - targetProxy = E79EEDE41CD4001300C2FBFC /* PBXContainerItemProxy */; + targetProxy = E745846C1BF68ECB001B54A4 /* PBXContainerItemProxy */; }; E79EEDE71CD4003900C2FBFC /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E79EEDD81CD3FFC800C2FBFC /* Security_frameworks_osx */; targetProxy = E79EEDE61CD4003900C2FBFC /* PBXContainerItemProxy */; }; - E7CFF6711C84F62900E3484E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; - targetProxy = E7CFF6701C84F62900E3484E /* PBXContainerItemProxy */; - }; - E7CFF6731C84F62900E3484E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E7D847CD1C6BE9720025BB44 /* KeychainCircleTests */; - targetProxy = E7CFF6721C84F62900E3484E /* PBXContainerItemProxy */; - }; - E7CFF6751C84F65D00E3484E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E7CFF6471C84F61200E3484E /* Security_KeychainCircle */; - targetProxy = E7CFF6741C84F65D00E3484E /* PBXContainerItemProxy */; - }; - E7CFF6771C84F66A00E3484E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E7CFF6471C84F61200E3484E /* Security_KeychainCircle */; - targetProxy = E7CFF6761C84F66A00E3484E /* PBXContainerItemProxy */; - }; - E7D847D11C6BE9720025BB44 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; - targetProxy = E7D847D01C6BE9720025BB44 /* PBXContainerItemProxy */; - }; - EB0D30FA1EF12BFB00C3C17D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E79EEDD21CD3F8AB00C2FBFC /* Security_tests_ios */; - targetProxy = EB0D30F91EF12BFB00C3C17D /* PBXContainerItemProxy */; - }; EB10557D1E14DFB60003C309 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EB1055741E14DF430003C309 /* SecCertificateFuzzer */; targetProxy = EB10557C1E14DFB60003C309 /* PBXContainerItemProxy */; }; - EB10557F1E14DFBE0003C309 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EB1055741E14DF430003C309 /* SecCertificateFuzzer */; - targetProxy = EB10557E1E14DFBE0003C309 /* PBXContainerItemProxy */; - }; EB108F1F1E6CE4D2003B0456 /* PBXTargetDependency */ = { isa = PBXTargetDependency; 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 */; - targetProxy = EB1C4CA61E85883900404981 /* PBXContainerItemProxy */; - }; - EB1C4CA91E85883900404981 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; - targetProxy = EB1C4CA81E85883900404981 /* PBXContainerItemProxy */; - }; - EB1C4CAB1E85883900404981 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; - targetProxy = EB1C4CAA1E85883900404981 /* PBXContainerItemProxy */; - }; EB1C4CB21E85884300404981 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; @@ -33518,6 +39468,11 @@ target = EB27FF101E402CD300EC9E3A /* ckksctl */; targetProxy = EB27FF271E40717400EC9E3A /* PBXContainerItemProxy */; }; + EB2ED4E922547DE900E98082 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EB27FF101E402CD300EC9E3A /* ckksctl */; + targetProxy = EB2ED4E822547DE900E98082 /* PBXContainerItemProxy */; + }; EB31EA831D3EF2FB008F952A /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 5346480017331E1100FE9172 /* KeychainSyncAccountNotification */; @@ -33548,155 +39503,160 @@ target = E79EEDD21CD3F8AB00C2FBFC /* Security_tests_ios */; targetProxy = EB58A05D1E74C51F009C10D7 /* PBXContainerItemProxy */; }; - EB58A0601E74C8D9009C10D7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EBB839A41E29665D00853BAC /* secfuzzer */; - targetProxy = EB58A05F1E74C8D9009C10D7 /* PBXContainerItemProxy */; - }; EB58A0621E74C8E4009C10D7 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = EBB839A41E29665D00853BAC /* secfuzzer */; targetProxy = EB58A0611E74C8E4009C10D7 /* PBXContainerItemProxy */; }; - EB636BCA20992D8900C1E21A /* PBXTargetDependency */ = { + EB63ADE11C3E74F900C45A69 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB49B2AD202D877F003F34A0 /* secdmockaks */; - targetProxy = EB636BC920992D8900C1E21A /* PBXContainerItemProxy */; + target = EB0BC9361C3C791500785842 /* secedumodetest */; + targetProxy = EB63ADE01C3E74F900C45A69 /* PBXContainerItemProxy */; }; - EB636BD120992DA300C1E21A /* PBXTargetDependency */ = { + EB694DAF2239E59600F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB49B2AD202D877F003F34A0 /* secdmockaks */; - targetProxy = EB636BD020992DA300C1E21A /* PBXContainerItemProxy */; + target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; + targetProxy = EB694DAE2239E59600F02C1C /* PBXContainerItemProxy */; }; - EB636BD320992DB400C1E21A /* PBXTargetDependency */ = { + EB694DC42239E5A200F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB49B2AD202D877F003F34A0 /* secdmockaks */; - targetProxy = EB636BD220992DB400C1E21A /* PBXContainerItemProxy */; + target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; + targetProxy = EB694DC32239E5A200F02C1C /* PBXContainerItemProxy */; }; - EB636BD520992DC000C1E21A /* PBXTargetDependency */ = { + EB694DC82239E5F200F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB49B2AD202D877F003F34A0 /* secdmockaks */; - targetProxy = EB636BD420992DC000C1E21A /* PBXContainerItemProxy */; + target = 5EBE24791B00CCAE0007DB0E /* secacltests */; + targetProxy = EB694DC72239E5F200F02C1C /* PBXContainerItemProxy */; }; - EB63ADE11C3E74F900C45A69 /* PBXTargetDependency */ = { + EB694DCE223A086C00F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB0BC9361C3C791500785842 /* secedumodetest */; - targetProxy = EB63ADE01C3E74F900C45A69 /* PBXContainerItemProxy */; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = EB694DCD223A086C00F02C1C /* PBXContainerItemProxy */; }; - EB6A6FAD1B90F84D0045DC68 /* PBXTargetDependency */ = { + EB694DD0223A087700F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */; - targetProxy = EB6A6FAC1B90F84D0045DC68 /* PBXContainerItemProxy */; + target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; + targetProxy = EB694DCF223A087700F02C1C /* PBXContainerItemProxy */; }; - EB6A6FB91B90F8D70045DC68 /* PBXTargetDependency */ = { + EB694E72223AB78E00F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C541F840F250BF500E508AE /* Security_executables_ios */; - targetProxy = EB6A6FB81B90F8D70045DC68 /* PBXContainerItemProxy */; + target = DC3502B41E0208BE00BC0587 /* CKKSTests */; + targetProxy = EB694E71223AB78E00F02C1C /* PBXContainerItemProxy */; }; - EB6A6FBB1B90F8EC0045DC68 /* PBXTargetDependency */ = { + EB694E87223AB79400F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */; - targetProxy = EB6A6FBA1B90F8EC0045DC68 /* PBXContainerItemProxy */; + target = DC3502B41E0208BE00BC0587 /* CKKSTests */; + targetProxy = EB694E86223AB79400F02C1C /* PBXContainerItemProxy */; }; - EB6A6FBD1B90F9170045DC68 /* PBXTargetDependency */ = { + EB694E89223AB79B00F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4C32C0AE0A4975F6002891BD /* Security_ios */; - targetProxy = EB6A6FBC1B90F9170045DC68 /* PBXContainerItemProxy */; + target = DC3502B41E0208BE00BC0587 /* CKKSTests */; + targetProxy = EB694E88223AB79B00F02C1C /* PBXContainerItemProxy */; }; - EB8910F120E0287600DE533F /* PBXTargetDependency */ = { + EB694E8B223AB7A200F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; - targetProxy = EB8910F020E0287600DE533F /* PBXContainerItemProxy */; + target = DC3502B41E0208BE00BC0587 /* CKKSTests */; + targetProxy = EB694E8A223AB7A200F02C1C /* PBXContainerItemProxy */; }; - EB8910F820E0287E00DE533F /* PBXTargetDependency */ = { + EB69527F223B75C300F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4727FBB61F9918580003AE36 /* secdxctests_ios */; - targetProxy = EB8910F720E0287E00DE533F /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = EB695280223B75C300F02C1C /* PBXContainerItemProxy */; }; - EB8910FE20E06DF500DE533F /* PBXTargetDependency */ = { + EB695283223B75C300F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; - targetProxy = EB8910FD20E06DF500DE533F /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = EB695284223B75C300F02C1C /* PBXContainerItemProxy */; }; - EB89FAFE20DBDAA800085498 /* PBXTargetDependency */ = { + EB695285223B75C300F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; - targetProxy = EB89FAFD20DBDAA800085498 /* PBXContainerItemProxy */; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = EB695286223B75C300F02C1C /* PBXContainerItemProxy */; }; - EB89FB0020DBDAA800085498 /* PBXTargetDependency */ = { + EB695287223B75C300F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; - targetProxy = EB89FAFF20DBDAA800085498 /* PBXContainerItemProxy */; + target = DC52EC3E1D80D00800B0A59C /* libSWCAgent */; + targetProxy = EB695288223B75C300F02C1C /* PBXContainerItemProxy */; }; - EB89FB0220DBDAA800085498 /* PBXTargetDependency */ = { + EB6952BB223B75FC00F02C1C /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; - targetProxy = EB89FB0120DBDAA800085498 /* PBXContainerItemProxy */; + target = EB69527E223B75C300F02C1C /* secitemd */; + targetProxy = EB6952BA223B75FC00F02C1C /* PBXContainerItemProxy */; }; - EB9C1DB71BDFD51800F89272 /* PBXTargetDependency */ = { + EB6A6FBB1B90F8EC0045DC68 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; - targetProxy = EB9C1DB61BDFD51800F89272 /* PBXContainerItemProxy */; + target = 0C7CFA2E14E1BA4800DF9D95 /* Security_frameworks_ios */; + targetProxy = EB6A6FBA1B90F8EC0045DC68 /* PBXContainerItemProxy */; }; - EB9FE08D1BFBC48F004FEAAF /* PBXTargetDependency */ = { + EB6A6FBD1B90F9170045DC68 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; - targetProxy = EB9FE08C1BFBC48F004FEAAF /* PBXContainerItemProxy */; + target = 4C32C0AE0A4975F6002891BD /* Security_ios */; + targetProxy = EB6A6FBC1B90F9170045DC68 /* PBXContainerItemProxy */; }; - EB9FE0B61BFBC499004FEAAF /* PBXTargetDependency */ = { + EB74CBD622077CC600F1BBAD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; - targetProxy = EB9FE0B51BFBC499004FEAAF /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = EB74CBD522077CC600F1BBAD /* PBXContainerItemProxy */; }; - EBA62C151EAD34C60096B33A /* PBXTargetDependency */ = { + EB74CC232207E99700F1BBAD /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; - targetProxy = EBA62C141EAD34C60096B33A /* PBXContainerItemProxy */; + target = EB74CC152207E48000F1BBAD /* KeychainSettings */; + targetProxy = EB74CC222207E99700F1BBAD /* PBXContainerItemProxy */; }; - EBA62C1C1EAD34CD0096B33A /* PBXTargetDependency */ = { + EB89085721F17D3C00F0DDDB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6CCDF7831E3C25FA003F2555 /* KeychainEntitledTestRunner */; - targetProxy = EBA62C1B1EAD34CD0096B33A /* PBXContainerItemProxy */; + target = DCDA5E4F2124B9C5009B11B2 /* aks_support */; + targetProxy = EB89085821F17D3C00F0DDDB /* PBXContainerItemProxy */; }; - EBA9AA891CE3E76C004E2B68 /* PBXTargetDependency */ = { + EB89085B21F17D3C00F0DDDB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EBA9AA7D1CE30E58004E2B68 /* secitemnotifications */; - targetProxy = EBA9AA881CE3E76C004E2B68 /* PBXContainerItemProxy */; + target = DC0BCC211D8C684F00070CB0 /* utilities */; + targetProxy = EB89085C21F17D3C00F0DDDB /* PBXContainerItemProxy */; }; - EBB696D41BE2085700715F16 /* PBXTargetDependency */ = { + EB89085D21F17D3C00F0DDDB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB9C1D791BDFD0E000F89272 /* secbackupntest */; - targetProxy = EBB696D31BE2085700715F16 /* PBXContainerItemProxy */; + target = D4ADA3181E2B41670031CEA3 /* libtrustd */; + targetProxy = EB89085E21F17D3C00F0DDDB /* PBXContainerItemProxy */; }; - EBC15EA91BE29AC3001C0C5B /* PBXTargetDependency */ = { + EB89086521F17D3C00F0DDDB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB9C1DAE1BDFD4DE00F89272 /* SecurityBatsTests */; - targetProxy = EBC15EA81BE29AC3001C0C5B /* PBXContainerItemProxy */; + target = DC52EC3E1D80D00800B0A59C /* libSWCAgent */; + targetProxy = EB89086621F17D3C00F0DDDB /* PBXContainerItemProxy */; }; - EBC73F52209A705A00AE3350 /* PBXTargetDependency */ = { + EB8908A221F17E3B00F0DDDB /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 6C46056B1F882B9B001421B6 /* KeychainAnalyticsTests */; - targetProxy = EBC73F51209A705A00AE3350 /* PBXContainerItemProxy */; + target = EB89085621F17D3C00F0DDDB /* recovery_securityd */; + targetProxy = EB8908A121F17E3B00F0DDDB /* PBXContainerItemProxy */; }; - EBC73F5D209A739600AE3350 /* PBXTargetDependency */ = { + EBA9AA891CE3E76C004E2B68 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 470415CE1E5E14B5001F3D95 /* seckeychainnetworkextensionstest */; - targetProxy = EBC73F5C209A739600AE3350 /* PBXContainerItemProxy */; + target = EBA9AA7D1CE30E58004E2B68 /* secitemnotifications */; + targetProxy = EBA9AA881CE3E76C004E2B68 /* PBXContainerItemProxy */; }; - EBC73F64209A73A100AE3350 /* PBXTargetDependency */ = { + EBB8521022F793A200424FD0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47702B1D1E5F409700B29577 /* seckeychainnetworkextensionsystemdaemontest */; - targetProxy = EBC73F63209A73A100AE3350 /* PBXContainerItemProxy */; + target = EBB851EB22F7912400424FD0 /* SecurityUtilitiesTests */; + targetProxy = EBB8520F22F793A200424FD0 /* PBXContainerItemProxy */; }; - EBC73F66209A73A100AE3350 /* PBXTargetDependency */ = { + EBB8521222F793AC00424FD0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 47702B2D1E5F492C00B29577 /* seckeychainnetworkextensionunauthorizedaccesstest */; - targetProxy = EBC73F65209A73A100AE3350 /* PBXContainerItemProxy */; + target = EBB851EB22F7912400424FD0 /* SecurityUtilitiesTests */; + targetProxy = EBB8521122F793AC00424FD0 /* PBXContainerItemProxy */; + }; + EBB8521622F793CF00424FD0 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = EBB851EB22F7912400424FD0 /* SecurityUtilitiesTests */; + targetProxy = EBB8521522F793CF00424FD0 /* PBXContainerItemProxy */; }; - EBCE15101FE638A2002E7CCC /* PBXTargetDependency */ = { + EBB8521822F793EF00424FD0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = EB056E3D1FE5E390000A771E /* DeviceSimulator */; - targetProxy = EBCE150F1FE638A2002E7CCC /* PBXContainerItemProxy */; + target = EBB851EB22F7912400424FD0 /* SecurityUtilitiesTests */; + targetProxy = EBB8521722F793EF00424FD0 /* PBXContainerItemProxy */; + }; + EBBC11B32200D3BB00F95738 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCF216D621ADD5B10029CCC1 /* protobuf_source_generation */; + targetProxy = EBBC11B22200D3BB00F95738 /* PBXContainerItemProxy */; }; EBCF743F1CE593A700BED7CA /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -33713,10 +39673,15 @@ target = DC0BC5501D8B6D2D00070CB0 /* XPCKeychainSandboxCheck */; targetProxy = EBD31B411E0A18A600FBE9FA /* PBXContainerItemProxy */; }; - EBD849361B242C8900C5FD1E /* PBXTargetDependency */ = { + EBD7DF8121FF475B0089F2DF /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = 4CE5A54C09C796E100D27A3F /* sslViewer */; - targetProxy = EBD849351B242C8900C5FD1E /* PBXContainerItemProxy */; + target = DC52E8BE1D80C25800B0A59C /* SecureObjectSyncServer */; + targetProxy = EBD7DF8021FF475B0089F2DF /* PBXContainerItemProxy */; + }; + EBD7DF8321FF475B0089F2DF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; + targetProxy = EBD7DF8221FF475B0089F2DF /* PBXContainerItemProxy */; }; EBF374821DC058B60065D840 /* PBXTargetDependency */ = { isa = PBXTargetDependency; @@ -33738,61 +39703,21 @@ target = EBF374711DC055580065D840 /* security-sysdiagnose */; targetProxy = EBF374871DC058CC0065D840 /* PBXContainerItemProxy */; }; - EBFBC2B01E76582C00A34469 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EB108F181E6CE4D2003B0456 /* KCPairingTests */; - targetProxy = EBFBC2AF1E76582C00A34469 /* PBXContainerItemProxy */; - }; - EBFBC2B21E76585500A34469 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = E7D847C41C6BE9710025BB44 /* KeychainCircle */; - targetProxy = EBFBC2B11E76585500A34469 /* PBXContainerItemProxy */; - }; - EBFBC2B41E76586700A34469 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCC78EA81D8088E200865A7C /* security */; - targetProxy = EBFBC2B31E76586700A34469 /* PBXContainerItemProxy */; - }; - EBFBC2B61E76587800A34469 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DCD8A1061E09EE0F00E4FA0A /* SecureObjectSyncFramework */; - targetProxy = EBFBC2B51E76587800A34469 /* PBXContainerItemProxy */; - }; EBFBC2BA1E76588A00A34469 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = DC8834011D8A218F00CE0ACA /* ASN1_not_installed */; + target = DC8834011D8A218F00CE0ACA /* ASN1 */; targetProxy = EBFBC2B91E76588A00A34469 /* PBXContainerItemProxy */; }; - EBFF18CE1F02BA66004E58FC /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = EB2D54A11F02A45E00E46890 /* secatomicfile */; - targetProxy = EBFF18CD1F02BA66004E58FC /* PBXContainerItemProxy */; - }; EBFF18D01F02C2FE004E58FC /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC0BC8981D8B7CBD00070CB0 /* security_filedb */; targetProxy = EBFF18CF1F02C2FE004E58FC /* PBXContainerItemProxy */; }; - F621D0831ED6ED5B000EA569 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F621D0271ED6DCE7000EA569 /* authorizationdump */; - targetProxy = F621D0821ED6ED5B000EA569 /* PBXContainerItemProxy */; - }; F667EC651E96EDCF00203D5C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DC0BCBD91D8C648C00070CB0 /* regressionBase */; targetProxy = F667EC641E96EDCF00203D5C /* PBXContainerItemProxy */; }; - F667EC671E96FA4600203D5C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F667EC561E96E9B100203D5C /* authdtest */; - targetProxy = F667EC661E96FA4600203D5C /* PBXContainerItemProxy */; - }; - F94E7AE21ACC8E7700F23132 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = F93C49021AB8FCE00047E01A /* ckcdiagnose.sh */; - targetProxy = F94E7AE11ACC8E7700F23132 /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -33828,30 +39753,6 @@ name = CloudKeychain.strings; sourceTree = ""; }; - 6CF4A0C11E45488B00ECD7B5 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6CF4A0C21E45488B00ECD7B5 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6CF4A0EB1E4549F300ECD7B5 /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6CF4A0EC1E4549F300ECD7B5 /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 6CF4A0F01E4549F300ECD7B5 /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 6CF4A0F11E4549F300ECD7B5 /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; BE197F2A19116FD100BA91D1 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -33882,7 +39783,7 @@ D4C263CD1F952F6C001317EA /* SecErrorMessages.strings */, ); name = SecErrorMessages.strings; - path = derived_src/en.lproj/; + path = derived_src/en.lproj; sourceTree = BUILT_PRODUCTS_DIR; }; DC0B622D1D909C4600D43BCB /* MainMenu.xib */ = { @@ -33899,8 +39800,9 @@ DC178A341D77A1F500B50D50 /* SecErrorMessages.strings */, ); name = SecErrorMessages.strings; - path = derived_src/en.lproj/; + path = derived_src/en.lproj; sourceTree = BUILT_PRODUCTS_DIR; + usesTabs = 0; }; DC178A381D77A1F500B50D50 /* InfoPlist.strings */ = { isa = PBXVariantGroup; @@ -33910,12 +39812,12 @@ name = InfoPlist.strings; sourceTree = ""; }; - DC178A3B1D77A1F500B50D50 /* authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings */ = { + DC178A3B1D77A1F500B50D50 /* authorization.dfr.prompts.strings */ = { isa = PBXVariantGroup; children = ( DC178A3C1D77A1F500B50D50 /* en */, ); - name = "authorization.dfr.prompts-BBBAA77A32-C4EBFEA440.strings"; + name = authorization.dfr.prompts.strings; sourceTree = ""; }; DC178A3D1D77A1F500B50D50 /* authorization.buttons.strings */ = { @@ -33969,34 +39871,6 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - 05EF68B11949149C007958C3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 05EF68B21949149C007958C3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - 05EF68B719491512007958C3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 05EF68B819491512007958C3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; 05EF68BD194915A5007958C3 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -34011,20 +39885,6 @@ }; name = Release; }; - 05EF68C3194915FB007958C3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 05EF68C4194915FB007958C3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; 0C0BDB35175685B000BC1A7E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -34045,21 +39905,15 @@ "$(OTHER_LDFLAGS_MOBILEASSET)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "$(inherited)", - "-framework", - MobileKeyBag, - "-laks", - "-lACM", - "-lImg4Decode", - "-lz", - "-lSystem", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMG4DECODE)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "-framework", - CrashReporterSupport, - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = secdtests; STRIP_STYLE = debugging; @@ -34086,21 +39940,15 @@ "$(OTHER_LDFLAGS_MOBILEASSET)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "$(inherited)", - "-framework", - MobileKeyBag, - "-laks", - "-lACM", - "-lImg4Decode", - "-lz", - "-lSystem", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMG4DECODE)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "-framework", - CrashReporterSupport, - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = secdtests; STRIP_STYLE = debugging; @@ -34183,13 +40031,15 @@ }; 0C85E0011FB38BB6000343A7 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; 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 = ""; + CODE_SIGN_IDENTITY = "-"; + GCC_GENERATE_TEST_COVERAGE_FILES = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -34197,13 +40047,25 @@ 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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34218,9 +40080,10 @@ "-ObjC", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34232,11 +40095,11 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OTTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -34246,13 +40109,15 @@ }; 0C85E0021FB38BB6000343A7 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; 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 = ""; + CODE_SIGN_IDENTITY = "-"; + GCC_GENERATE_TEST_COVERAGE_FILES = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -34260,13 +40125,220 @@ 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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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 = ( + "$(OTHER_LDFLAGS_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", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "$(OTHER_LDFLAGS_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", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + ); + 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/sbin; + 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/sbin; + 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 = "$(SECURITY_XCTEST_DIRECTORY)"; + 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 = ( + "$(OTHER_LDFLAGS_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*]" = ( + "$(OTHER_LDFLAGS_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_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; + }; + 0C9AEEB620783FBB00BF6237 /* Release */ = { + 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 = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34283,7 +40355,7 @@ "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34296,66 +40368,23 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(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 */ = { - 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 */ = { + 0CF4064E2072E3E3003D6A7F /* 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 = ""; @@ -34366,141 +40395,25 @@ 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)", - "$(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; - }; - 0C9AEEB620783FBB00BF6237 /* Release */ = { - 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", + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", ); - 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 = 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)", + "LD_RUNPATH_SEARCH_PATHS[sdk=iphonesimulator*]" = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SFTMTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - USE_XCTRUNNER = YES; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 0CF4064E2072E3E3003D6A7F /* 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", + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", ); - 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)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34517,7 +40430,7 @@ "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34529,8 +40442,7 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_CORECDP)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", @@ -34557,13 +40469,25 @@ 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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34580,7 +40504,7 @@ "$(OTHER_LDFLAGS_ACCOUNTS)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -34593,8 +40517,7 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "-ObjC", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", ); @@ -34628,7 +40551,6 @@ "$(inherited)", "$(PROJECT_DIR)", "$(PROJECT_DIR)/header_symlinks/iOS/**", - "$(PROJECT_DIR)/OSX/sec/ProjectHeaders", "$(PROJECT_DIR)/OSX/utilities", "$(PROJECT_DIR)/OSX/sec/ipc", "$(PROJECT_DIR)/OSX/sectask", @@ -34649,7 +40571,6 @@ "-Wno-unknown-pragmas", "$(inherited)", "-Wno-error=c++11-narrowing", - "-Wno-vla-extension", ); }; name = Debug; @@ -34677,7 +40598,6 @@ "$(inherited)", "$(PROJECT_DIR)", "$(PROJECT_DIR)/header_symlinks/iOS/**", - "$(PROJECT_DIR)/OSX/sec/ProjectHeaders", "$(PROJECT_DIR)/OSX/utilities", "$(PROJECT_DIR)/OSX/sec/ipc", "$(PROJECT_DIR)/OSX/sectask", @@ -34698,11 +40618,97 @@ "-Wno-unknown-pragmas", "$(inherited)", "-Wno-error=c++11-narrowing", - "-Wno-vla-extension", ); }; name = Release; }; + 3D58394B21890FFB000ACA44 /* 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 = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = ""; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + "$(OTHER_LDFLAGS_AOSKIT_FRAMEWORK)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-ObjC", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + ); + OTHER_TAPI_FLAGS_SOS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SecExperimentTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 3D58394C21890FFB000ACA44 /* 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 = ""; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = ""; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + "$(OTHER_LDFLAGS_AOSKIT_FRAMEWORK)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-ObjC", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + ); + OTHER_TAPI_FLAGS_SOS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SecExperimentTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; 3DD1FF4B201C07F30086D049 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -34726,15 +40732,19 @@ "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(inherited)", ); - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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)"; + PRODUCT_NAME = SecureTransport_macos_tests; }; name = Debug; }; @@ -34761,15 +40771,19 @@ "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(inherited)", ); - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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)"; + PRODUCT_NAME = SecureTransport_macos_tests; VALIDATE_PRODUCT = YES; }; name = Release; @@ -34797,15 +40811,20 @@ "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(inherited)", ); - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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)"; + PRODUCT_NAME = SecureTransport_ios_tests; + SDKROOT = iphoneos.internal; }; name = Debug; }; @@ -34832,15 +40851,20 @@ "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(inherited)", ); - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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)"; + PRODUCT_NAME = SecureTransport_ios_tests; + SDKROOT = iphoneos.internal; VALIDATE_PRODUCT = YES; }; name = Release; @@ -34933,7 +40957,6 @@ "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", @@ -34952,8 +40975,7 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", @@ -34964,7 +40986,6 @@ ); PRODUCT_NAME = securityd; STRIP_STYLE = debugging; - USE_HEADERMAP = NO; WARNING_CFLAGS = ( "$(inherited)", "-Wno-error=modules-ambiguous-internal-linkage", @@ -34992,7 +41013,6 @@ "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", @@ -35011,8 +41031,7 @@ "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_PREQUELITE)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", @@ -35023,7 +41042,6 @@ ); PRODUCT_NAME = securityd; STRIP_STYLE = debugging; - USE_HEADERMAP = NO; WARNING_CFLAGS = ( "$(inherited)", "-Wno-error=modules-ambiguous-internal-linkage", @@ -35107,19 +41125,22 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/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; - "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "-L$(SDKROOT)/usr/local/lib", - "-laks", - "-laks_acl", - "-framework", - MobileKeyBag, + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + "@loader_path/../Frameworks", ); - "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( - "-L$(SDKROOT)/usr/local/lib", - "-laks_acl", + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -35153,19 +41174,22 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/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; - "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "-L$(SDKROOT)/usr/local/lib", - "-laks", - "-laks_acl", - "-framework", - MobileKeyBag, + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + "@loader_path/../Frameworks", ); - "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( - "-L$(SDKROOT)/usr/local/lib", - "-laks_acl", + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -35288,7 +41312,6 @@ 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)"; @@ -35323,7 +41346,6 @@ 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)"; @@ -35360,9 +41382,21 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -35395,9 +41429,21 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = secdxctests/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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdxctests; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; @@ -35490,11 +41536,16 @@ GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - INFOPLIST_FILE = SecurityUnitTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + INFOPLIST_FILE = keychain/SecurityUnitTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecurityUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; + USES_XCTRUNNER = YES; }; name = Debug; }; @@ -35517,27 +41568,16 @@ ENABLE_NS_ASSERTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; - INFOPLIST_FILE = SecurityUnitTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + INFOPLIST_FILE = keychain/SecurityUnitTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = com.apple.SecurityUnitTests; PRODUCT_NAME = "$(TARGET_NAME)"; - }; - 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)"; + USES_XCTRUNNER = YES; }; name = Release; }; @@ -35571,7 +41611,7 @@ "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", - "$(PROJECT_DIR)/OSX/sec/ProjectHeaders", + "$(PROJECT_DIR)/OSX/include", "$(PROJECT_DIR)/OSX/sec", "$(PROJECT_DIR)/OSX/sec/SOSCircle", "$(PROJECT_DIR)/OSX/utilities", @@ -35588,11 +41628,10 @@ "-DDEBUG", ); OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); PRODUCT_NAME = "$(TARGET_NAME)"; - SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -35620,7 +41659,7 @@ "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", - "$(PROJECT_DIR)/OSX/sec/ProjectHeaders", + "$(PROJECT_DIR)/OSX/include", "$(PROJECT_DIR)/OSX/sec", "$(PROJECT_DIR)/OSX/sec/SOSCircle", "$(PROJECT_DIR)/OSX/utilities", @@ -35631,11 +41670,10 @@ ); INSTALL_PATH = /System/Library/Frameworks/Security.framework/CircleJoinRequested/; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); PRODUCT_NAME = "$(TARGET_NAME)"; - SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; VALIDATE_PRODUCT = YES; }; name = Release; @@ -35654,23 +41692,10 @@ }; name = Release; }; - 4C541F980F250C3000E508AE /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = phase1; - }; - name = Debug; - }; - 4C541F9B0F250C3000E508AE /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = phase1; - }; - name = Release; - }; 4C711D7413AFCD0900FE865D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_DEADCODE_DEADSTORES = NO; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; @@ -35693,25 +41718,15 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( - "$(inherited)", - "-framework", - MobileKeyBag, - "-laks", - "-lACM", - "-lImg4Decode", - "-lSystem", - "-lSecureKeyVaultForiapd", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_IMG4DECODE)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", - "$(OTHER_LDFLAGS_APS)", - "$(OTHER_LDFLAGS_CLOUDKIT)", - "$(OTHER_LDFLAGS_PROTOBUF)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_SECUREKEYVAULT)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = SecurityDevTests; @@ -35722,6 +41737,7 @@ 4C711D7513AFCD0900FE865D /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_DEADCODE_DEADSTORES = NO; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; @@ -35744,25 +41760,15 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "$(inherited)", - "-framework", - MobileKeyBag, - "-laks", - "-lACM", - "-lImg4Decode", - "-lSystem", - "-lSecureKeyVaultForiapd", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_IMG4DECODE)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", - "$(OTHER_LDFLAGS_APS)", - "$(OTHER_LDFLAGS_CLOUDKIT)", - "$(OTHER_LDFLAGS_PROTOBUF)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_SECUREKEYVAULT)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = SecurityDevTests; @@ -35857,10 +41863,9 @@ MACH_O_TYPE = mh_execute; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( - "-laks", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-ObjC", ); - "OTHER_LDFLAGS[sdk=embeddedsimulator*]" = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.cloudkeychainproxy3; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = NO; @@ -35898,10 +41903,9 @@ INSTALL_PATH = "$(SECURITY_FRAMEWORK_RESOURCES_DIR)"; MACH_O_TYPE = mh_execute; OTHER_LDFLAGS = ( - "-laks", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-ObjC", ); - "OTHER_LDFLAGS[sdk=embeddedsimulator*]" = "-ObjC"; PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.cloudkeychainproxy3; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = NO; @@ -35941,7 +41945,8 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; INFOPLIST_FILE = "KeychainSyncAccountNotification/KeychainSyncAccountNotification-Info.plist"; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Accounts/Notification"; - OTHER_LDFLAGS = "$(AOSKIT_FRAMEWORK)"; + MACH_O_TYPE = mh_dylib; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_APPLEACCOUNT)"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = bundle; @@ -35972,7 +41977,8 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; INFOPLIST_FILE = "KeychainSyncAccountNotification/KeychainSyncAccountNotification-Info.plist"; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Accounts/Notification"; - OTHER_LDFLAGS = "$(AOSKIT_FRAMEWORK)"; + MACH_O_TYPE = mh_dylib; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_APPLEACCOUNT)"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; VALIDATE_PRODUCT = YES; @@ -36063,7 +42069,9 @@ "$(SDKROOT)/usr/local/lib", ); OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36079,14 +42087,8 @@ "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", "$(OTHER_LDFLAGS_APPLEACCOUNT)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "$(inherited)", - "-lACM", - "-lImg4Decode", - "-lSystem", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -36104,7 +42106,9 @@ "$(SDKROOT)/usr/local/lib", ); OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36120,16 +42124,121 @@ "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); - "OTHER_LDFLAGS[sdk=embedded]" = ( + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 6C39237721F13E4D00D018AD /* 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_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; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = tests/SecDbBackupTests/Entitlements.plist; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Manual; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ""; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "$(SOURCE_ROOT)/tests/SecDbBackupTests/Info.plist"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "-lACM", - "-lImg4Decode", - "-lSystem", - "-framework", - CrashReporterSupport, + "@executable_path/Frameworks", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + "@loader_path/../Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdbbackuptests; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + USES_XCTRUNNER = YES; + }; + name = Debug; + }; + 6C39237821F13E4D00D018AD /* 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_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; + CLANG_WARN_STRICT_PROTOTYPES = NO; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = tests/SecDbBackupTests/Entitlements.plist; + CODE_SIGN_IDENTITY = "-"; + CODE_SIGN_STYLE = Manual; + COPY_PHASE_STRIP = NO; + DEVELOPMENT_TEAM = ""; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INFOPLIST_FILE = "$(SOURCE_ROOT)/tests/SecDbBackupTests/Info.plist"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.secdbbackuptests; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + USES_XCTRUNNER = YES; + VALIDATE_PRODUCT = YES; }; name = Release; }; @@ -36145,14 +42254,24 @@ 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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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", - "$(AOSKIT_FRAMEWORK)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", "$(OTHER_LDFLAGS_CRASHREPORTER)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( + "-ObjC", + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainAnalyticsTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -36171,12 +42290,22 @@ 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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", + ); + "OTHER_LDFLAGS[sdk=iphoneos*]" = ( "-ObjC", - "$(AOSKIT_FRAMEWORK)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_CRASHREPORTER)", "$(OTHER_LDFLAGS_APPLEACCOUNT)", ); @@ -36203,11 +42332,15 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = keychain/ckks/tests/CKKSCloudKitTestsInfo.plist; - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36220,9 +42353,11 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36237,6 +42372,7 @@ CrashReporterSupport, "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -36261,11 +42397,15 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = keychain/ckks/tests/CKKSCloudKitTestsInfo.plist; - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36278,9 +42418,11 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36291,10 +42433,10 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -36320,11 +42462,15 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = keychain/ckks/tests/CKKSCloudKitTestsInfo.plist; - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36337,9 +42483,11 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36350,10 +42498,11 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -36378,11 +42527,15 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = keychain/ckks/tests/CKKSCloudKitTestsInfo.plist; - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36395,9 +42548,11 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); "OTHER_LDFLAGS[sdk=iphoneos*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_MOBILEGESTALT)", @@ -36408,10 +42563,11 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSCloudKitTests; PRODUCT_NAME = CKKSCloudKitTests; @@ -36492,16 +42648,15 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; INSTALL_PATH = /usr/libexec; "LAUNCHD_PLIST[sdk=iphoneos*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; - "LAUNCHD_PLIST[sdk=iphonesimulator*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; + "LAUNCHD_PLIST[sdk=iphonesimulator*]" = "$(SRCROOT)/supd/securityuploadd-sim.plist"; "LAUNCHD_PLIST[sdk=macosx*]" = "$(SRCROOT)/supd/securityuploadd-osx.plist"; "LAUNCHD_PLIST_LOCATION[sdk=iphoneos*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; "LAUNCHD_PLIST_LOCATION[sdk=iphonesimulator*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; "LAUNCHD_PLIST_LOCATION[sdk=macosx*]" = "$(DSTROOT)/System/Library/LaunchAgents"; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( - "$(AOSKIT_FRAMEWORK)", - "$(OTHER_LDFLAGS_CRASHREPORTER)", "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -36529,16 +42684,15 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; INSTALL_PATH = /usr/libexec; "LAUNCHD_PLIST[sdk=iphoneos*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; - "LAUNCHD_PLIST[sdk=iphonesimulator*]" = "$(SRCROOT)/supd/securityuploadd-ios.plist"; + "LAUNCHD_PLIST[sdk=iphonesimulator*]" = "$(SRCROOT)/supd/securityuploadd-sim.plist"; "LAUNCHD_PLIST[sdk=macosx*]" = "$(SRCROOT)/supd/securityuploadd-osx.plist"; "LAUNCHD_PLIST_LOCATION[sdk=iphoneos*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; "LAUNCHD_PLIST_LOCATION[sdk=iphonesimulator*]" = "$(DSTROOT)/System/Library/LaunchDaemons"; "LAUNCHD_PLIST_LOCATION[sdk=macosx*]" = "$(DSTROOT)/System/Library/LaunchAgents"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( - "$(AOSKIT_FRAMEWORK)", - "$(OTHER_LDFLAGS_CRASHREPORTER)", "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_CRASHREPORTER)", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -36566,7 +42720,11 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; - LD_RUNPATH_SEARCH_PATHS = "/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + /Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks, + ); MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -36594,7 +42752,11 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; - LD_RUNPATH_SEARCH_PATHS = "/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + /Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks, + ); MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -36620,7 +42782,10 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = KeychainEntitledTestApp_mac/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.KeychainEntitledTestApp-mac"; @@ -36648,7 +42813,10 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = KeychainEntitledTestApp_mac/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.KeychainEntitledTestApp-mac"; @@ -36675,7 +42843,10 @@ INFOPLIST_FILE = KeychainEntitledTestApp_ios/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.KeychainEntitledTestApp-ios"; @@ -36703,7 +42874,10 @@ INFOPLIST_FILE = KeychainEntitledTestApp_ios/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; IPHONEOS_DEPLOYMENT_TARGET = 11.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; OTHER_CODE_SIGN_FLAGS = "--deep"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.KeychainEntitledTestApp-ios"; @@ -36765,34 +42939,30 @@ }; 792EFFDC0CBBF878007C00A0 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCC1849220EEEC4400F3B26C /* security_framework.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; - EXPORTED_SYMBOLS_FILE = "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp"; + EXPORTED_SYMBOLS_FILE = "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).exp"; FRAMEWORK_VERSION = B; 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", - ); MODULEMAP_FILE = Modules/Security.iOS.modulemap; OTHER_LDFLAGS = ( - "-laks", - "-Wl,-upward_framework,Foundation", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); - "OTHER_LDFLAGS[sdk=*simulator*]" = "-Wl,-upward_framework,Foundation"; - OTHER_TAPI_FLAGS = "-I$(PROJECT_DIR)/header_symlinks/iOS/ -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/ios_tapi_hacks.h $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) $(inherited)"; + OTHER_TAPI_FLAGS = "--verify-api-error-as-warning -I$(PROJECT_DIR)/header_symlinks/iOS/ -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/ios_tapi_hacks.h $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.${EXECUTABLE_NAME}"; PRODUCT_NAME = Security; STRIP_STYLE = debugging; SUPPORTS_TEXT_BASED_API = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; }; @@ -36800,30 +42970,25 @@ }; 792EFFDD0CBBF878007C00A0 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCC1849220EEEC4400F3B26C /* security_framework.xcconfig */; buildSettings = { COMBINE_HIDPI_IMAGES = YES; DEAD_CODE_STRIPPING = YES; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)"; - EXPORTED_SYMBOLS_FILE = "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).$(CURRENT_ARCH).exp"; + EXPORTED_SYMBOLS_FILE = "$(BUILT_PRODUCTS_DIR)/$(PRODUCT_NAME).exp"; FRAMEWORK_VERSION = B; 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", - ); MODULEMAP_FILE = Modules/Security.iOS.modulemap; OTHER_LDFLAGS = ( - "-laks", - "-Wl,-upward_framework,Foundation", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", ); - "OTHER_LDFLAGS[sdk=*simulator*]" = "-Wl,-upward_framework,Foundation"; - OTHER_TAPI_FLAGS = "-I$(PROJECT_DIR)/header_symlinks/iOS/ -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/ios_tapi_hacks.h $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) $(inherited)"; + OTHER_TAPI_FLAGS = "--verify-api-error-as-warning -I$(PROJECT_DIR)/header_symlinks/iOS/ -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/ios_tapi_hacks.h $(OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK) $(inherited)"; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.${EXECUTABLE_NAME}"; PRODUCT_NAME = Security; STRIP_STYLE = debugging; @@ -36837,46 +43002,35 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; - CODE_SIGN_ENTITLEMENTS = SecurityTool/entitlements.plist; + CODE_SIGN_ENTITLEMENTS = SecurityTool/sharedTool/iOS/entitlements.plist; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_SHADOW = NO; INSTALL_PATH = /usr/local/bin; "INSTALL_PATH[sdk=macosx*]" = /usr/bin; OTHER_LDFLAGS = ( - "-lsqlite3", - "-framework", - CFNetwork, - "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "$(OTHER_LDFLAGS_APS)", - "$(OTHER_LDFLAGS_CLOUDKIT)", - "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_PROTOBUF)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded][arch=*]" = ( "-lsqlite3", "-framework", CFNetwork, "-framework", IOKit, - "-framework", - MobileKeyBag, - "-laks", - "-lACM", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = security; + REEXPORTED_LIBRARY_PATHS = ""; STRIP_STYLE = debugging; - SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; @@ -36884,46 +43038,35 @@ isa = XCBuildConfiguration; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; - CODE_SIGN_ENTITLEMENTS = SecurityTool/entitlements.plist; + CODE_SIGN_ENTITLEMENTS = SecurityTool/sharedTool/iOS/entitlements.plist; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_SHADOW = NO; INSTALL_PATH = /usr/local/bin; "INSTALL_PATH[sdk=macosx*]" = /usr/bin; - "OTHER_LDFLAGS[sdk=embedded]" = ( + OTHER_LDFLAGS = ( "-lsqlite3", "-framework", CFNetwork, "-framework", IOKit, - "-framework", - MobileKeyBag, - "-laks", - "-lACM", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", - "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", - "$(OTHER_LDFLAGS_APS)", - "$(OTHER_LDFLAGS_CLOUDKIT)", - "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_PROTOBUF)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embeddedsimulator*][arch=*]" = ( - "-lsqlite3", - "-framework", - CFNetwork, "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = security; + REEXPORTED_LIBRARY_PATHS = ""; STRIP_STYLE = debugging; - SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Release; }; @@ -36973,40 +43116,32 @@ LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", "$(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_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( - "$(inherited)", - "-ObjC", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = securityd; + REEXPORTED_LIBRARY_NAMES = ""; STRIP_STYLE = debugging; USE_HEADERMAP = NO; WARNING_CFLAGS = ( @@ -37032,40 +43167,32 @@ LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", "$(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_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=iphonesimulator*]" = ( - "$(inherited)", - "-ObjC", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = securityd; + REEXPORTED_LIBRARY_NAMES = ""; STRIP_STYLE = debugging; USE_HEADERMAP = NO; WARNING_CFLAGS = ( @@ -37119,6 +43246,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE; CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = keychain/SecurityUnitTests/SecurityUnitTests.entitlements; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = YES; @@ -37159,17 +43287,20 @@ LLVM_LTO = YES_THIN; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ""; - RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx.internal; SECURITY_FRAMEWORK_RESOURCES_DIR = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/"; "SECURITY_FRAMEWORK_RESOURCES_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Resources"; + SECURITY_FRAMEWORK_XPCSERVICES_DIR = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/XPCServices"; + "SECURITY_FRAMEWORK_XPCSERVICES_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/XPCServices"; + SERVICETYPE_USER_OR_SYSTEM = System; + "SERVICETYPE_USER_OR_SYSTEM[sdk=macosx*]" = User; STRIP_INSTALLED_PRODUCT = NO; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos macosx appletvos appletvsimulator watchsimulator"; SUPPORTS_TEXT_BASED_API = YES; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; TAPI_VERIFY_MODE = ErrorsAndWarnings; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,3,4"; }; name = Debug; }; @@ -37203,6 +43334,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES_AGGRESSIVE; CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = keychain/SecurityUnitTests/SecurityUnitTests.entitlements; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEAD_CODE_STRIPPING = YES; @@ -37241,16 +43373,20 @@ "INSTALL_DAEMON_AGENT_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/LaunchAgents"; LLVM_LTO = YES; OTHER_LDFLAGS = ""; - RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = macosx.internal; SECURITY_FRAMEWORK_RESOURCES_DIR = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/"; "SECURITY_FRAMEWORK_RESOURCES_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/Resources"; + SECURITY_FRAMEWORK_XPCSERVICES_DIR = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/XPCServices"; + "SECURITY_FRAMEWORK_XPCSERVICES_DIR[sdk=macosx*]" = "$(SYSTEM_LIBRARY_DIR)/Frameworks/Security.framework/Versions/A/XPCServices"; + SERVICETYPE_USER_OR_SYSTEM = System; + "SERVICETYPE_USER_OR_SYSTEM[sdk=macosx*]" = User; SUPPORTED_PLATFORMS = "iphonesimulator iphoneos watchos macosx appletvos appletvsimulator watchsimulator"; SUPPORTS_TEXT_BASED_API = YES; + SWIFT_COMPILATION_MODE = wholemodule; Sim_Name = ""; "Sim_Name[sdk=embeddedsimulator*][arch=*]" = _sim; TAPI_VERIFY_MODE = ErrorsAndWarnings; - TARGETED_DEVICE_FAMILY = "1,2"; + TARGETED_DEVICE_FAMILY = "1,2,3,4"; }; name = Release; }; @@ -37330,7 +43466,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "$(TARGET_NAME)/$(TARGET_NAME)-Info.plist"; "INSTALL_PATH[sdk=embedded*]" = "$(LOCAL_APPS_DIR)"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -37371,7 +43510,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "$(TARGET_NAME)/$(TARGET_NAME)-Info.plist"; "INSTALL_PATH[sdk=embedded*]" = "$(LOCAL_APPS_DIR)"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; VALIDATE_PRODUCT = NO; @@ -37414,6 +43556,109 @@ }; name = Release; }; + BEAA0037202A832500E51F45 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = "keychain/TrustedPeersHelper/TrustedPeersHelper-entitlements.plist"; + DEFINES_MODULE = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/TrustedPeersHelper/Info.plist; + INFOPLIST_PREPROCESS = YES; + INSTALL_PATH = "$(SECURITY_FRAMEWORK_XPCSERVICES_DIR)"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "-framework", + Security, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersHelper; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + BEAA0038202A832500E51F45 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = "keychain/TrustedPeersHelper/TrustedPeersHelper-entitlements.plist"; + DEFINES_MODULE = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/TrustedPeersHelper/Info.plist; + INFOPLIST_PREPROCESS = YES; + INSTALL_PATH = "$(SECURITY_FRAMEWORK_XPCSERVICES_DIR)"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "-framework", + Security, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersHelper; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h"; + }; + name = Release; + }; + BEAA0042202B728B00E51F45 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + BEAA0043202B728B00E51F45 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + BECFA43220F91AFE00B11002 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + BECFA43320F91AFE00B11002 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; BED208DB1EDF950E00753952 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; @@ -37439,197 +43684,757 @@ "-framework", IOKit, ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - }; - name = Debug; - }; - BED208DC1EDF950E00753952 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CODE_SIGN_ENTITLEMENTS = RegressionTests/manifeststresstest/manifeststresstest.entitlements; - INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; - OTHER_LDFLAGS = ( - "-framework", - Security, + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + }; + name = Debug; + }; + BED208DC1EDF950E00753952 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CODE_SIGN_ENTITLEMENTS = RegressionTests/manifeststresstest/manifeststresstest.entitlements; + INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; + OTHER_LDFLAGS = ( + "-framework", + Security, + ); + "OTHER_LDFLAGS[sdk=embedded]" = ( + "-laks", + "-framework", + Security, + "-framework", + IOKit, + ); + "OTHER_LDFLAGS[sdk=macosx*]" = ( + "-laks", + "-framework", + Security, + "-framework", + IOKit, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + BED987DC2099145400607A5F /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = keychain/TrustedPeersHelperUnitTests/Info.plist; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib/security_libDER", + ); + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_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", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + "-framework", + Security, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersHelperUnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests-BridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + BED987DD2099145400607A5F /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */; + buildSettings = { + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "NDEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = keychain/TrustedPeersHelperUnitTests/Info.plist; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/../Frameworks", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib/security_libDER", + ); + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_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", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + "-framework", + Security, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersHelperUnitTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests-BridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Release; + }; + BEF88C391EAFFC4000357577 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CURRENT_PROJECT_VERSION = 1; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + FRAMEWORK_VERSION = A; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/trust/TrustedPeers/Info.plist; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_UPWARD_PROTOCOLBUFFER)", + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", + "$(OTHER_LDFLAGS_UPWARD_SECURITY)", + "$(OTHER_LDFLAGS_UPWARD_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeers; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + BEF88C3A1EAFFC4000357577 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CURRENT_PROJECT_VERSION = 1; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", + ); + FRAMEWORK_VERSION = A; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/trust/TrustedPeers/Info.plist; + INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; + OTHER_LDFLAGS = ( + "$(inherited)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_UPWARD_PROTOCOLBUFFER)", + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", + "$(OTHER_LDFLAGS_UPWARD_SECURITY)", + "$(OTHER_LDFLAGS_UPWARD_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeers; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + BEF88C3B1EAFFC4000357577 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + keychain/trust/TrustedPeers/, + "$(inherited)", + ); + INFOPLIST_FILE = keychain/trust/TrustedPeersTests/Info.plist; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + BEF88C3C1EAFFC4000357577 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + keychain/trust/TrustedPeers/, + "$(inherited)", + ); + INFOPLIST_FILE = keychain/trust/TrustedPeersTests/Info.plist; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D41257D71E9410A300781F23 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CODE_SIGN_ENTITLEMENTS = OSX/trustd/iOS/entitlements.plist; + GCC_PREPROCESSOR_DEFINITIONS = ( + "LIBTRUSTD=1", + "$(inherited)", + ); + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib", + ); + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + ); + PRODUCT_NAME = trustd; + STRIP_STYLE = debugging; + }; + name = Debug; + }; + D41257D81E9410A300781F23 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CODE_SIGN_ENTITLEMENTS = OSX/trustd/iOS/entitlements.plist; + ENABLE_NS_ASSERTIONS = NO; + GCC_PREPROCESSOR_DEFINITIONS = ( + "LIBTRUSTD=1", + "$(inherited)", + ); + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib", + ); + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + ); + PRODUCT_NAME = trustd; + STRIP_STYLE = debugging; + }; + name = Release; + }; + D41AD42F1B967169008C7270 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D41AD4301B967169008C7270 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D41AD4331B96717A008C7270 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D41AD4341B96717A008C7270 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D42C839A21159147008D3D83 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + D42C839B21159147008D3D83 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + ENABLE_NS_ASSERTIONS = NO; + EXECUTABLE_PREFIX = lib; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; + D44D1F672115893000E76E1A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */; + buildSettings = { + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + }; + name = Debug; + }; + D44D1F682115893000E76E1A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */; + buildSettings = { + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + }; + name = Release; + }; + D453A4BE2122236D00850A26 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; + 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; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "IS_TRUSTTESTS=1", + "LIBTRUSTD=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = tests/TrustTests/Info.plist; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustTests; + PRODUCT_NAME = TrustTests; + }; + name = Debug; + }; + D453A4BF2122236D00850A26 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; + 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; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "IS_TRUSTTESTS=1", + "LIBTRUSTD=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = tests/TrustTests/Info.plist; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-laks", - "-framework", - Security, - "-framework", - IOKit, + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, ); - "OTHER_LDFLAGS[sdk=macosx*]" = ( - "-laks", - "-framework", - Security, - "-framework", - IOKit, + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_IMG4DECODE)", ); - PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustTests; + PRODUCT_NAME = TrustTests; VALIDATE_PRODUCT = YES; }; name = Release; }; - BEF88C391EAFFC4000357577 /* Debug */ = { + D458C4F5214E1DE10043D982 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + 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; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CURRENT_PROJECT_VERSION = 1; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = tests/TrustTests/TestRunners/trusttests_entitlements.plist; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_DYNAMIC_NO_PIC = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - INFOPLIST_FILE = keychain/trust/TrustedPeers/Info.plist; - INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = ( - "-laks", - "-Wl,-upward_framework,Foundation", - "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + INFOPLIST_FILE = tests/TrustTests/TestRunners/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", ); - "OTHER_LDFLAGS[sdk=*simulator*]" = "-Wl,-upward_framework,Foundation"; - PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeers; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - VERSION_INFO_PREFIX = ""; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustTestsRunner; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos.internal; + VALIDATE_PRODUCT = NO; }; name = Debug; }; - BEF88C3A1EAFFC4000357577 /* Release */ = { + D458C4F6214E1DE10043D982 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BE8351D41EC0EEDD00ACD5FD /* framework_requiring_modern_objc_runtime.xcconfig */; buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + 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; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CURRENT_PROJECT_VERSION = 1; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = tests/TrustTests/TestRunners/trusttests_entitlements.plist; + CODE_SIGN_STYLE = Automatic; + ENABLE_NS_ASSERTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - INFOPLIST_FILE = keychain/trust/TrustedPeers/Info.plist; - INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = ( - "-laks", - "-Wl,-upward_framework,Foundation", - "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + INFOPLIST_FILE = tests/TrustTests/TestRunners/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", ); - "OTHER_LDFLAGS[sdk=*simulator*]" = "-Wl,-upward_framework,Foundation"; - PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeers; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SKIP_INSTALL = YES; - VERSION_INFO_PREFIX = ""; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustTestsRunner; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos.internal; + VALIDATE_PRODUCT = NO; }; name = Release; }; - BEF88C3B1EAFFC4000357577 /* Debug */ = { + D458C50E214E20540043D982 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - INFOPLIST_FILE = keychain/trust/TrustedPeersTests/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersTests; + 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = tests/TrustTests/TestRunners/trusttests_entitlements.plist; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + "$(PLATFORM_DIR)/Developer/AppleInternal/Library/Frameworks", + ); + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = tests/TrustTests/TestRunners/Info.plist; + INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; + LD_RUNPATH_SEARCH_PATHS = ( + /Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks, + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; - BEF88C3C1EAFFC4000357577 /* Release */ = { + D458C50F214E20540043D982 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - INFOPLIST_FILE = keychain/trust/TrustedPeersTests/Info.plist; - PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustedPeersTests; + 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = tests/TrustTests/TestRunners/trusttests_entitlements.plist; + CODE_SIGN_STYLE = Automatic; + ENABLE_NS_ASSERTIONS = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + "$(PLATFORM_DIR)/Developer/AppleInternal/Library/Frameworks", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = tests/TrustTests/TestRunners/Info.plist; + INSTALL_PATH = /AppleInternal/CoreOS/tests/Security; + LD_RUNPATH_SEARCH_PATHS = ( + /Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/Library/Frameworks, + /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework/Frameworks, + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; }; name = Release; }; - D41257D71E9410A300781F23 /* Debug */ = { + D4707A0B21136E6A005BCFDA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CODE_SIGN_ENTITLEMENTS = OSX/trustd/iOS/entitlements.plist; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; GCC_PREPROCESSOR_DEFINITIONS = ( + "IS_TRUSTTESTS=1", "LIBTRUSTD=1", "$(inherited)", ); - INSTALL_PATH = /usr/libexec; - LIBRARY_SEARCH_PATHS = ( + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = tests/TrustTests/Info.plist; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(SDKROOT)/usr/local/lib", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, ); - MTL_ENABLE_DEBUG_INFO = YES; - OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEASSET)"; - "OTHER_LDFLAGS[sdk=embedded]" = ( + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( "$(inherited)", - "-lImg4Decode", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, ); - PRODUCT_NAME = trustd; - STRIP_STYLE = debugging; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + "$(OTHER_LDFLAGS_OCMOCK)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustTests; + PRODUCT_NAME = TrustTests; }; name = Debug; }; - D41257D81E9410A300781F23 /* Release */ = { + D4707A0C21136E6A005BCFDA /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CODE_SIGN_ENTITLEMENTS = OSX/trustd/iOS/entitlements.plist; - ENABLE_NS_ASSERTIONS = 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; GCC_PREPROCESSOR_DEFINITIONS = ( + "IS_TRUSTTESTS=1", "LIBTRUSTD=1", "$(inherited)", ); - INSTALL_PATH = /usr/libexec; - LIBRARY_SEARCH_PATHS = ( + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = tests/TrustTests/Info.plist; + INSTALL_PATH = /AppleInternal/XCTests/com.apple.security/; + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(SDKROOT)/usr/local/lib", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, ); - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEASSET)"; - "OTHER_LDFLAGS[sdk=embedded]" = ( + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( "$(inherited)", - "-lImg4Decode", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, ); - PRODUCT_NAME = trustd; - STRIP_STYLE = debugging; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEASSET)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + "$(OTHER_LDFLAGS_OCMOCK)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.TrustTests; + PRODUCT_NAME = TrustTests; + VALIDATE_PRODUCT = YES; }; name = Release; }; - D41AD42F1B967169008C7270 /* Debug */ = { + D477EE5E21ED476D00C9AAFF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - D41AD4301B967169008C7270 /* Release */ = { + D477EE5F21ED476D00C9AAFF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; - D41AD4331B96717A008C7270 /* Debug */ = { + D477EE6221ED477C00C9AAFF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - D41AD4341B96717A008C7270 /* Release */ = { + D477EE6321ED477C00C9AAFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D477EE6621ED479500C9AAFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D477EE6721ED479500C9AAFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D477EE6A21ED47C600C9AAFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D477EE6B21ED47C600C9AAFF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D477EE6E21ED47DB00C9AAFF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D477EE6F21ED47DB00C9AAFF /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -37643,11 +44448,19 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; EXECUTABLE_PREFIX = ""; + "GCC_PREPROCESSOR_DEFINITIONS[sdk=embedded]" = ( + "$(inherited)", + "LIBTRUSTD=1", + ); + "GCC_PREPROCESSOR_DEFINITIONS[sdk=embeddedsimulator*]" = ( + "$(inherited)", + "LIBTRUSTD=1", + ); "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = ( "$(inherited)", "SECITEM_SHIM_OSX=1", "SEC_IOS_ON_OSX=1", - "TRUSTD_SERVER=1", + "LIBTRUSTD=1", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; MTL_ENABLE_DEBUG_INFO = YES; @@ -37664,11 +44477,20 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; EXECUTABLE_PREFIX = ""; + "GCC_PREPROCESSOR_DEFINITIONS[sdk=embedded]" = ( + "$(inherited)", + "LIBTRUSTD=1", + ); + "GCC_PREPROCESSOR_DEFINITIONS[sdk=embeddedsimulator*]" = ( + "$(inherited)", + "NO_SERVER=1", + "LIBTRUSTD=1", + ); "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*]" = ( "$(inherited)", - "TRUSTD_SERVER=1", "SECITEM_SHIM_OSX=1", "SEC_IOS_ON_OSX=1", + "LIBTRUSTD=1", ); GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; MTL_ENABLE_DEBUG_INFO = NO; @@ -37676,6 +44498,261 @@ }; name = Release; }; + D4D1D3FF21AD0B3F0012C66C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4D1D40021AD0B3F0012C66C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4D1D40421AD0B4B0012C66C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4D1D40521AD0B4B0012C66C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4D1D40B21ADC9720012C66C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4D1D40C21ADC9720012C66C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4D1FDDE21165F8B003538E2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + }; + name = Debug; + }; + D4D1FDDF21165F8B003538E2 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC0067911D87816C005AF8DB /* macos_legacy_lib.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + }; + name = Release; + }; + D4F47B3A22270B6F003483E9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F47B3B22270B6F003483E9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F47B3E22270B8A003483E9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F47B3F22270B8A003483E9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F47B4222270B97003483E9 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F47B4322270B97003483E9 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56B87217FA32000FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56B88217FA32000FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56B8F217FA3F800FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56B90217FA3F800FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56B93217FA40800FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56B94217FA40800FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56BC421813EC900FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56BC521813EC900FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56BC821813ECF00FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56BC921813ECF00FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56BCC21813EDC00FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56BCD21813EDC00FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + D4F56BD021813EE800FCA6B7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + D4F56BD121813EE800FCA6B7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + INSTALLHDRS_SCRIPT_PHASE = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; DA30D6791DF8C8FB00EC6B43 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -37698,6 +44775,58 @@ }; name = Release; }; + DA41FE122241ADC000838FB3 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = keychain/otpaird/otpaird.iphoneos.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=iphonesimulator*]" = keychain/otpaird/otpaird.iphoneos.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=watchos*]" = keychain/otpaird/otpaird.watchos.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=watchsimulator*]" = keychain/otpaird/otpaird.watchos.entitlements; + CREATE_INFOPLIST_SECTION_IN_BINARY = YES; + INFOPLIST_FILE = keychain/otpaird/Info.plist; + INSTALL_PATH = /usr/libexec; + OTHER_LDFLAGS = ( + "$(inherited)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_NANOREGISTRY_WATCH_ONLY)", + "-framework", + Security, + ); + "OTPAIRD_LAUNCHD_PLIST[sdk=iphoneos*]" = com.apple.security.otpaird.iphoneos.plist; + "OTPAIRD_LAUNCHD_PLIST[sdk=iphonesimulator*]" = com.apple.security.otpaird.iphoneos.plist; + "OTPAIRD_LAUNCHD_PLIST[sdk=watchos*]" = com.apple.security.otpaird.watchos.plist; + "OTPAIRD_LAUNCHD_PLIST[sdk=watchsimulator*]" = com.apple.security.otpaird.watchos.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.otpaird; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DA41FE132241ADC000838FB3 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + "CODE_SIGN_ENTITLEMENTS[sdk=iphoneos*]" = keychain/otpaird/otpaird.iphoneos.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=iphonesimulator*]" = keychain/otpaird/otpaird.iphoneos.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=watchos*]" = keychain/otpaird/otpaird.watchos.entitlements; + "CODE_SIGN_ENTITLEMENTS[sdk=watchsimulator*]" = keychain/otpaird/otpaird.watchos.entitlements; + CREATE_INFOPLIST_SECTION_IN_BINARY = YES; + INFOPLIST_FILE = keychain/otpaird/Info.plist; + INSTALL_PATH = /usr/libexec; + OTHER_LDFLAGS = ( + "$(inherited)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_NANOREGISTRY_WATCH_ONLY)", + "-framework", + Security, + ); + "OTPAIRD_LAUNCHD_PLIST[sdk=iphoneos*]" = com.apple.security.otpaird.iphoneos.plist; + "OTPAIRD_LAUNCHD_PLIST[sdk=iphonesimulator*]" = com.apple.security.otpaird.iphoneos.plist; + "OTPAIRD_LAUNCHD_PLIST[sdk=watchos*]" = com.apple.security.otpaird.watchos.plist; + "OTPAIRD_LAUNCHD_PLIST[sdk=watchsimulator*]" = com.apple.security.otpaird.watchos.plist; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.otpaird; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; DAE40BCC20CF3E46002D5674 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -37844,6 +44973,84 @@ }; name = Release; }; + DC05037B21409A4100A8EDB7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + FRAMEWORK_VERSION = A; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = OCMockUmbrella/Info.plist; + INSTALL_PATH = /AppleInternal/CoreOS/BATS/unit_tests/Frameworks; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OCMockUmbrella; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DC05037C21409A4100A8EDB7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/../../AppleInternal/Library/Frameworks", + ); + FRAMEWORK_VERSION = A; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = OCMockUmbrella/Info.plist; + INSTALL_PATH = /AppleInternal/CoreOS/BATS/unit_tests/Frameworks; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.OCMockUmbrella; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; DC0BC55E1D8B6D2E00070CB0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -38669,6 +45876,82 @@ }; name = Release; }; + DC0EF8F4208697C700AB9E95 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_ENTITLEMENTS = "keychain/tpctl/tpctl-entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/sbin; + "INSTALL_PATH[sdk=embedded]" = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "-framework", + Security, + "-framework", + SecurityFoundation, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/tpctl/tpctl-bridging-header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + DC0EF8F5208697C700AB9E95 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DC340C53208E7BAE004D7EEC /* swift_binary.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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_ENTITLEMENTS = "keychain/tpctl/tpctl-entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = /usr/sbin; + "INSTALL_PATH[sdk=embedded]" = /usr/local/bin; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "-framework", + Security, + "-framework", + SecurityFoundation, + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/tpctl/tpctl-bridging-header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; DC17890E1D77980500B50D50 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = DC178BB11D77A5F500B50D50 /* security_framework_macos.xcconfig */; @@ -38695,8 +45978,18 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OSX/include/", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)//usr/local/lib/security_libDER", + ); + MODULEMAP_PRIVATE_FILE = Modules/Security.macOS.private.modulemap; MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(inherited)", ); @@ -38732,8 +46025,18 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OSX/include/", + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)//usr/local/lib/security_libDER", + ); + MODULEMAP_PRIVATE_FILE = Modules/Security.macOS.private.modulemap; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(inherited)", ); @@ -38743,73 +46046,55 @@ }; name = Release; }; - DC222C751E034D1F00B09171 /* Debug */ = { + DC311E752124B8A8002F5EAE /* 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_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - EXECUTABLE_PREFIX = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - "USE_KEYSTORE=0", - "$(inherited)", - ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + EXECUTABLE_PREFIX = lib; + 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; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; }; name = Debug; }; - DC222C761E034D1F00B09171 /* Release */ = { + DC311E762124B8A8002F5EAE /* 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_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - EXECUTABLE_PREFIX = ""; - GCC_PREPROCESSOR_DEFINITIONS = ( - "USE_KEYSTORE=0", - "$(inherited)", - ); - GCC_TREAT_WARNINGS_AS_ERRORS = YES; + EXECUTABLE_PREFIX = lib; 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)"; + SKIP_INSTALL = YES; }; name = Release; }; DC3502BB1E0208BE00BC0587 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; 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 = ""; + CODE_SIGN_IDENTITY = "-"; GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -38817,44 +46102,44 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = keychain/ckks/tests/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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_ACCOUNTS)", "$(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_CORECDP)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", "$(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_MOCK_AKS_LIBRARY)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-ObjC", "-framework", - CrashReporterSupport, - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", + Security, + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -38863,13 +46148,14 @@ }; DC3502BC1E0208BE00BC0587 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; 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 = ""; + CODE_SIGN_IDENTITY = "-"; GCC_PREPROCESSOR_DEFINITIONS = ( "NO_SERVER=1", "$(inherited)", @@ -38877,44 +46163,44 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = keychain/ckks/tests/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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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_ACCOUNTS)", "$(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_CORECDP)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", "$(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_MOCK_AKS_LIBRARY)", "$(OTHER_LDFLAGS_PREQUELITE)", - "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "-ObjC", "-framework", - CrashReporterSupport, - "$(OTHER_LDFLAGS_IMCORE)", - "$(OTHER_LDFLAGS_ACCOUNTS)", + Security, + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.CKKSTests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -38922,6 +46208,47 @@ }; name = Release; }; + DC36896021235F42003A3735 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + DC36896121235F42003A3735 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + 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; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + EXECUTABLE_PREFIX = lib; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Release; + }; DC3A4B5C1D91E9FB00E46D4A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -38933,7 +46260,8 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_ENTITLEMENTS = OSX/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper.entitlements; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -38961,7 +46289,8 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = ""; + CODE_SIGN_ENTITLEMENTS = OSX/libsecurity_codesigning/CodeSigningHelper/CodeSigningHelper.entitlements; + CODE_SIGN_IDENTITY = "-"; COMBINE_HIDPI_IMAGES = YES; GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; @@ -38994,11 +46323,21 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; EXECUTABLE_PREFIX = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_KEYSTORE=1", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; @@ -39018,17 +46357,26 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; EXECUTABLE_PREFIX = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_KEYSTORE=1", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; }; name = Release; }; DC52E8C41D80C25800B0A59C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; + baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -39051,7 +46399,7 @@ }; DC52E8C51D80C25800B0A59C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; + baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -39071,90 +46419,6 @@ }; name = Release; }; - DC52EA4A1D80CB7000B0A59C /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = 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; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MTL_ENABLE_DEBUG_INFO = YES; - }; - name = Debug; - }; - DC52EA4B1D80CB7000B0A59C /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = 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; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MTL_ENABLE_DEBUG_INFO = NO; - }; - name = Release; - }; - DC52EBD31D80CEF100B0A59C /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = 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; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MTL_ENABLE_DEBUG_INFO = YES; - }; - name = Debug; - }; - DC52EBD41D80CEF100B0A59C /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; - buildSettings = { - CLANG_ANALYZER_NONNULL = 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; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MTL_ENABLE_DEBUG_INFO = NO; - }; - name = Release; - }; DC52EC321D80CFB200B0A59C /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; @@ -39173,7 +46437,6 @@ 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; }; @@ -39195,7 +46458,6 @@ 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; }; @@ -39346,6 +46608,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/OSX/regressions/", + "$(inherited)", + ); MTL_ENABLE_DEBUG_INFO = YES; }; name = Debug; @@ -39367,6 +46633,10 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + HEADER_SEARCH_PATHS = ( + "$(PROJECT_DIR)/OSX/regressions/", + "$(inherited)", + ); MTL_ENABLE_DEBUG_INFO = NO; }; name = Release; @@ -39415,7 +46685,7 @@ }; DC52EDAF1D80D58400B0A59C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; + baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -39437,7 +46707,7 @@ }; DC52EDB01D80D58400B0A59C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D47C56AB1DCA831C00E18518 /* lib_ios_x64.xcconfig */; + baseConfigurationReference = D47C56AF1DCA841D00E18518 /* lib_ios_x64_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -39475,6 +46745,11 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + ./OSX/regressions/, + ./OSX/shared_regressions/, + ); MTL_ENABLE_DEBUG_INFO = YES; }; name = Debug; @@ -39497,6 +46772,11 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + ./OSX/regressions/, + ./OSX/shared_regressions/, + ); MTL_ENABLE_DEBUG_INFO = NO; }; name = Release; @@ -39652,7 +46932,6 @@ PRODUCT_NAME = security; RUN_CLANG_STATIC_ANALYZER = NO; SUPPORTED_PLATFORMS = macosx; - USE_HEADERMAP = NO; }; name = Debug; }; @@ -39689,7 +46968,6 @@ PRODUCT_NAME = security; RUN_CLANG_STATIC_ANALYZER = NO; SUPPORTED_PLATFORMS = macosx; - USE_HEADERMAP = NO; }; name = Release; }; @@ -39708,6 +46986,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = securityd/src/securityd.entitlements; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", @@ -39752,6 +47031,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = securityd/src/securityd.entitlements; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks", @@ -39871,15 +47151,12 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /usr/local/bin; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-ObjC", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_IMCORE)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-lACM", - "-lImg4Decode", - "-ObjC", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = secdtests; STRIP_STYLE = debugging; @@ -39898,15 +47175,12 @@ GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INSTALL_PATH = /usr/local/bin; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-ObjC", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_IMCORE)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-lACM", - "-lImg4Decode", - "-ObjC", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = secdtests; STRIP_STYLE = debugging; @@ -40191,43 +47465,63 @@ }; name = Release; }; - DC71D9DD1D95BA6C0065FB93 /* Debug */ = { + DC6D1C76208A547400AB21AF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DC6D1C77208A547400AB21AF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + DC7FC44D21EE914D003C39B8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - CLANG_ENABLE_MODULES = NO; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - GCC_WARN_SHADOW = NO; - "HEADER_SEARCH_PATHS[sdk=embedded*]" = ( - "$(PROJECT_DIR)/header_symlinks/iOS", - "$(inherited)", - ); - MTL_ENABLE_DEBUG_INFO = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = featureflags/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.FeatureFlagsPlist; PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_asn1; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; }; name = Debug; }; - DC71D9DE1D95BA6C0065FB93 /* Release */ = { + DC7FC44E21EE914D003C39B8 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D47C56FB1DCA8F4900E18518 /* all_arches.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; - CLANG_ENABLE_MODULES = NO; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - GCC_WARN_SHADOW = NO; - "HEADER_SEARCH_PATHS[sdk=embedded*]" = ( - "$(PROJECT_DIR)/header_symlinks/iOS", - "$(inherited)", - ); + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = featureflags/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles"; MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.FeatureFlagsPlist; PRODUCT_NAME = "$(TARGET_NAME)"; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/security_asn1; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; }; name = Release; }; @@ -40929,81 +48223,190 @@ }; name = Release; }; - DC8E04B31D7F6EC9006D80EB /* Debug */ = { + DC8E04B31D7F6EC9006D80EB /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_MODULES = 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_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + DEBUGGING_SYMBOLS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DC8E04B41D7F6EC9006D80EB /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ENABLE_MODULES = 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_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVES = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + 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; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + DC99B89020EACA470065B73B /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 725D438D212CAA3B007B49E4 /* xcconfig/swift_binary_shim.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_ENABLE_MODULES = 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_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEBUGGING_SYMBOLS = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", "DEBUG=1", "$(inherited)", ); - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - MTL_ENABLE_DEBUG_INFO = YES; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; + INFOPLIST_FILE = "keychain/ot/tests/octagon/OctagonTests-Info.plist"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib/security_libDER", + ); + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOCK_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", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "-framework", + Security, + "$(OTHER_LDFLAGS_UserManagement)", + ); + OTHER_SWIFT_FLAGS = "-D OCTAGON_TEST_FILL_ZONEKEYS $(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.OctagonTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = ""; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/ot/tests/octagon/OctagonTests-BridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; - DC8E04B41D7F6EC9006D80EB /* Release */ = { + DC99B89120EACA470065B73B /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 725D438D212CAA3B007B49E4 /* xcconfig/swift_binary_shim.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_ENABLE_MODULES = 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_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_SUSPICIOUS_MOVES = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - 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; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "NDEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = "keychain/ot/tests/octagon/OctagonTests-Info.plist"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, + ); + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SDKROOT)/usr/local/lib/security_libDER", + ); + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOCK_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", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + "$(OTHER_LDFLAGS_ACCOUNTS)", + "-framework", + Security, + "$(OTHER_LDFLAGS_UserManagement)", + ); + OTHER_SWIFT_FLAGS = "-D OCTAGON_TEST_FILL_ZONEKEYS $(inherited)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.OctagonTests; PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + SWIFT_OBJC_BRIDGING_HEADER = "keychain/ot/tests/octagon/OctagonTests-BridgingHeader.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Release; }; @@ -41179,9 +48582,113 @@ }; name = Release; }; + DCBF4ADE21FFC82100539F0A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = "keychain/escrowrequest/tests/SecEscrowRequestsTests-Info.plist"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, + ); + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_MOCK_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "-ObjC", + "-framework", + Security, + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SecEscrowRequestTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DCBF4ADF21FFC82100539F0A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "NO_SERVER=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = "keychain/escrowrequest/tests/SecEscrowRequestsTests-Info.plist"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Frameworks, + ); + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = ( + "$(inherited)", + /AppleInternal/CoreOS/BATS/unit_tests/Frameworks/OCMockUmbrella.framework/Versions/A/Frameworks, + ); + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", + "$(OTHER_LDFLAGS_APPLESYSTEMINFO)", + "$(OTHER_LDFLAGS_APS)", + "$(OTHER_LDFLAGS_CLOUDKIT)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT)", + "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_MOCK_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_PREQUELITE)", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", + "-ObjC", + "-framework", + Security, + "$(OTHER_LDFLAGS_FOR_SECURITYD)", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SecEscrowRequestTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; DCC78EB01D8088E200865A7C /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */; + baseConfigurationReference = DC71D8DD1D94CF3C0065FB93 /* lib_ios_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -41204,7 +48711,7 @@ }; DCC78EB11D8088E200865A7C /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */; + baseConfigurationReference = DC71D8DD1D94CF3C0065FB93 /* lib_ios_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -41228,7 +48735,6 @@ DCD067581D8CDCF4007602F1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -41236,7 +48742,6 @@ DCD067591D8CDCF4007602F1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -41244,7 +48749,6 @@ DCD0675E1D8CDD6D007602F1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -41252,7 +48756,6 @@ DCD0675F1D8CDD6D007602F1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -41312,7 +48815,6 @@ DCD069691D8CE105007602F1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -41320,7 +48822,6 @@ DCD0696A1D8CE105007602F1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -41527,7 +49028,6 @@ DCD06A7D1D8CE330007602F1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -41535,7 +49035,6 @@ DCD06A7E1D8CE330007602F1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - DEVELOPMENT_TEAM = XPSUQMMH5W; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -41567,7 +49066,6 @@ "$(inherited)", "-Wno-sign-compare", "-Wno-deprecated-register", - "-Wno-vla-extension", ); }; name = Debug; @@ -41599,7 +49097,6 @@ "$(inherited)", "-Wno-sign-compare", "-Wno-deprecated-register", - "-Wno-vla-extension", ); }; name = Release; @@ -41690,7 +49187,7 @@ }; DCD8A1971E09EE0F00E4FA0A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */; + baseConfigurationReference = DC71D8DD1D94CF3C0065FB93 /* lib_ios_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -41714,7 +49211,7 @@ }; DCD8A1981E09EE0F00E4FA0A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DC8E04901D7F6780006D80EB /* lib_ios.xcconfig */; + baseConfigurationReference = DC71D8DD1D94CF3C0065FB93 /* lib_ios_shim.xcconfig */; buildSettings = { CLANG_ANALYZER_NONNULL = YES; CLANG_ENABLE_OBJC_ARC = YES; @@ -41735,11 +49232,31 @@ }; name = Release; }; + DCDA5E502124B9C6009B11B2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + DCDA5E512124B9C6009B11B2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; DCE4E6A21D7A37FA00AFB96E /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; - CODE_SIGN_ENTITLEMENTS = OSX/sec/SecurityTool/entitlements.plist; + CODE_SIGN_ENTITLEMENTS = SecurityTool/sharedTool/macOS/entitlements.plist; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_SHADOW = NO; OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", @@ -41747,18 +49264,24 @@ "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = security2; SUPPORTED_PLATFORMS = macosx; - SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Debug; }; DCE4E6A31D7A37FA00AFB96E /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; buildSettings = { CLANG_ENABLE_OBJC_ARC = YES; - CODE_SIGN_ENTITLEMENTS = OSX/sec/SecurityTool/entitlements.plist; + CODE_SIGN_ENTITLEMENTS = SecurityTool/sharedTool/macOS/entitlements.plist; + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + GCC_WARN_SHADOW = NO; OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_PROTOBUF)", @@ -41766,10 +49289,12 @@ "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = security2; SUPPORTED_PLATFORMS = macosx; - SYSTEM_FRAMEWORK_SEARCH_PATHS = "$(inherited) $(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; }; name = Release; }; @@ -41783,7 +49308,10 @@ HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OSX/SecurityTestsOSX/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security/; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); OTHER_LDFLAGS = ""; "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -41794,6 +49322,10 @@ "-lImg4Decode", "-lSystem", ); + "OTHER_LDFLAGS[sdk=macosx*]" = ( + "-framework", + EmbeddedOSSupportHost, + ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = macosx; @@ -41810,7 +49342,10 @@ HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OSX/SecurityTestsOSX/Info.plist; INSTALL_PATH = /AppleInternal/CoreOS/tests/Security/; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); OTHER_LDFLAGS = ""; "OTHER_LDFLAGS[sdk=embedded]" = ( "$(inherited)", @@ -41821,6 +49356,10 @@ "-lImg4Decode", "-lSystem", ); + "OTHER_LDFLAGS[sdk=macosx*]" = ( + "-framework", + EmbeddedOSSupportHost, + ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTED_PLATFORMS = macosx; @@ -41927,13 +49466,16 @@ MTL_ENABLE_DEBUG_INFO = YES; OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-ObjC", "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = "$(TARGET_NAME)"; - USE_HEADERMAP = NO; WARNING_CFLAGS = ( "$(inherited)", "-Wno-error=modules-ambiguous-internal-linkage", @@ -41979,13 +49521,16 @@ MTL_ENABLE_DEBUG_INFO = NO; OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-ObjC", "$(OTHER_LDFLAGS_IMCORE)", + "$(OTHER_LDFLAGS_CORECDP)", + "$(OTHER_LDFLAGS_APPLEACCOUNT)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_NAME = "$(TARGET_NAME)"; - USE_HEADERMAP = NO; WARNING_CFLAGS = ( "$(inherited)", "-Wno-error=modules-ambiguous-internal-linkage", @@ -42168,7 +49713,7 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = OSX/sec/SecurityTool/entitlements.plist; + CODE_SIGN_ENTITLEMENTS = SecurityTool/sharedTool/macOS/entitlements.plist; COMBINE_HIDPI_IMAGES = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_DYNAMIC_NO_PIC = NO; @@ -42187,7 +49732,10 @@ ); INFOPLIST_FILE = "OSX/Keychain/Keychain-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -42213,7 +49761,7 @@ CLANG_WARN_SUSPICIOUS_MOVES = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = OSX/sec/SecurityTool/entitlements.plist; + CODE_SIGN_ENTITLEMENTS = SecurityTool/sharedTool/macOS/entitlements.plist; COMBINE_HIDPI_IMAGES = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -42228,7 +49776,10 @@ ); INFOPLIST_FILE = "OSX/Keychain/Keychain-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:rfc1034identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -42269,11 +49820,13 @@ ); INFOPLIST_FILE = "OSX/Keychain Circle Notification/Keychain Circle Notification-Info.plist"; INSTALL_PATH = /System/Library/CoreServices; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); 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; }; @@ -42311,11 +49864,51 @@ ); INFOPLIST_FILE = "OSX/Keychain Circle Notification/Keychain Circle Notification-Info.plist"; INSTALL_PATH = /System/Library/CoreServices; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); 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; + }; + DCF216D821ADD5B10029CCC1 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + EXECUTABLE_PREFIX = lib; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + DCF216D921ADD5B10029CCC1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + EXECUTABLE_PREFIX = lib; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + MACOSX_DEPLOYMENT_TARGET = 10.14; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; }; name = Release; }; @@ -42662,9 +50255,252 @@ }; name = Release; }; + E060D1CB212478120025B833 /* 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.trieste.OctagonTestHarnessXPCServiceProtocol; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SUPPORTS_TEXT_BASED_API = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E060D1CC212478120025B833 /* 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.trieste.OctagonTestHarnessXPCServiceProtocol; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SUPPORTS_TEXT_BASED_API = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E060D1CE212478120025B833 /* 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "keychain/Trieste/$(TARGET_NAME)/Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/Trieste/OctagonTestHarnessXPCService/Info.plist; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", + "-framework", + Security, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.trieste.OctagonTestHarnessXPCService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SUPPORTS_TEXT_BASED_API = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + E060D1CF212478120025B833 /* 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_ENTITLEMENTS = "keychain/Trieste/$(TARGET_NAME)/Entitlements.plist"; + CODE_SIGN_STYLE = Automatic; + ENABLE_NS_ASSERTIONS = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INFOPLIST_FILE = keychain/Trieste/OctagonTestHarnessXPCService/Info.plist; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", + "-framework", + Security, + ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.trieste.OctagonTestHarnessXPCService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SUPPORTS_TEXT_BASED_API = NO; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + E060D1D3212478120025B833 /* 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + EXPORTED_SYMBOLS_FILE = keychain/Trieste/OctagonTestHarness/OctagonTestHarness.exp; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GENERATE_TEXT_BASED_STUBS = YES; + INFOPLIST_FILE = keychain/Trieste/OctagonTestHarness/Info.plist; + INSTALL_PATH = /AppleInternal/Library/Frameworks; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.trieste.OctagonTestHarness; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E060D1D4212478120025B833 /* 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_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_NS_ASSERTIONS = NO; + EXPORTED_SYMBOLS_FILE = keychain/Trieste/OctagonTestHarness/OctagonTestHarness.exp; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GENERATE_TEXT_BASED_STUBS = YES; + INFOPLIST_FILE = keychain/Trieste/OctagonTestHarness/Info.plist; + INSTALL_PATH = /AppleInternal/Library/Frameworks; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + OTHER_LDFLAGS = "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.trieste.OctagonTestHarness; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; E710C75D1331946500F85568 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_DEADCODE_DEADSTORES = NO; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; @@ -42675,7 +50511,10 @@ HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "SecurityTests/SecurityTests-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", @@ -42685,16 +50524,8 @@ "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "$(inherited)", - "-framework", - MobileKeyBag, - "-laks", - "-lACM", - "-lImg4Decode", - "-lSystem", - "-lSecureKeyVaultForiapd", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_APS)", @@ -42702,10 +50533,14 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_SECUREKEYVAULT)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -42716,6 +50551,7 @@ E710C75E1331946500F85568 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CLANG_ANALYZER_DEADCODE_DEADSTORES = NO; CLANG_ENABLE_OBJC_ARC = YES; CODE_SIGN_ENTITLEMENTS = "SecurityTests/SecurityTests-Entitlements.plist"; COMBINE_HIDPI_IMAGES = YES; @@ -42726,7 +50562,10 @@ HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = "SecurityTests/SecurityTests-Info.plist"; INSTALL_PATH = /AppleInternal/Applications; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); OTHER_LDFLAGS = ( "$(OTHER_LDFLAGS_APS)", "$(OTHER_LDFLAGS_CLOUDKIT)", @@ -42736,16 +50575,8 @@ "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "$(inherited)", - "-framework", - MobileKeyBag, - "-laks", - "-lACM", - "-lImg4Decode", - "-lSystem", - "-lSecureKeyVaultForiapd", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "$(OTHER_LDFLAGS_APS)", @@ -42753,10 +50584,14 @@ "$(OTHER_LDFLAGS_PREQUELITE)", "$(OTHER_LDFLAGS_PROTOBUF)", "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", - "-framework", - CrashReporterSupport, + "$(OTHER_LDFLAGS_CrashReporterSupport)", "$(OTHER_LDFLAGS_IMCORE)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_SECUREKEYVAULT)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_IMG4DECODE)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = "com.apple.security.${PRODUCT_NAME:identifier}"; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -42820,24 +50655,9 @@ }; name = Release; }; - E79EEDE21CD4000C00C2FBFC /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - E79EEDE31CD4000C00C2FBFC /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; E7B01BF0166594AB000485F1 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; @@ -42859,6 +50679,7 @@ "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", + "$(PROJECT_DIR)/OSX/include", "$(PROJECT_DIR)/OSX/sec", "$(PROJECT_DIR)/OSX/utilities", "$(BUILT_PRODUCTS_DIR)/usr/local/include", @@ -42889,7 +50710,6 @@ E7B01BF1166594AB000485F1 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_OBJC_ARC = YES; @@ -42904,6 +50724,7 @@ "$(SDKROOT)/usr/local/include/security_libDER", "$(PROJECT_DIR)/OSX/libsecurity_asn1", "$(PROJECT_DIR)/libsecurity_smime", + "$(PROJECT_DIR)/OSX/include", "$(PROJECT_DIR)/OSX/sec", "$(PROJECT_DIR)/OSX/utilities", "$(BUILT_PRODUCTS_DIR)/usr/local/include", @@ -42935,6 +50756,7 @@ E7CFF6481C84F61200E3484E /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + INSTALLHDRS_SCRIPT_PHASE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -42942,6 +50764,7 @@ E7CFF6491C84F61200E3484E /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + INSTALLHDRS_SCRIPT_PHASE = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; @@ -42980,17 +50803,23 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = KeychainCircle/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; - IS_ZIPPERED = YES; + IS_ZIPPERED = NO; + "IS_ZIPPERED[sdk=macosx*]" = YES; MODULEMAP_FILE = Modules/KeychainCircle.modulemap; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; - OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEGESTALT)"; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", + "$(OTHER_LDFLAGS_UPWARD_PROTOCOLBUFFER)", + ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainCircle.KeychainCircle; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_TEXT_BASED_API = YES; TAPI_VERIFY_MODE = ErrorsOnly; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WARNING_CFLAGS = "-Wno-objc-designated-initializers"; }; name = Debug; }; @@ -43025,10 +50854,15 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = KeychainCircle/Info.plist; INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks"; - IS_ZIPPERED = YES; + IS_ZIPPERED = NO; + "IS_ZIPPERED[sdk=macosx*]" = YES; MODULEMAP_FILE = Modules/KeychainCircle.modulemap; MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = "$(OTHER_LDFLAGS_MOBILEGESTALT)"; + OTHER_LDFLAGS = ( + "$(OTHER_LDFLAGS_MOBILEGESTALT)", + "$(OTHER_LDFLAGS_UPWARD_FOUNDATION)", + "$(OTHER_LDFLAGS_UPWARD_PROTOCOLBUFFER)", + ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.KeychainCircle.KeychainCircle; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_TEXT_BASED_API = YES; @@ -43069,7 +50903,7 @@ MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-lACM", "-framework", SystemConfiguration, @@ -43099,7 +50933,7 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", ); "OTHER_LDFLAGS[sdk=macosx*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-lACM", "-framework", @@ -43146,7 +50980,7 @@ INSTALL_PATH = /AppleInternal/Tests/Security/; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-lACM", "-framework", @@ -43177,7 +51011,7 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", ); "OTHER_LDFLAGS[sdk=macosx*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-lACM", "-framework", SystemConfiguration, @@ -43191,228 +51025,6 @@ }; 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 */; @@ -43682,11 +51294,11 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "KeychainCircle/Tests/KCPairingTest-Info.plist"; - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-lACM", "-framework", SystemConfiguration, @@ -43716,7 +51328,7 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", ); "OTHER_LDFLAGS[sdk=macosx*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-lACM", "-framework", @@ -43761,10 +51373,10 @@ GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; INFOPLIST_FILE = "KeychainCircle/Tests/KCPairingTest-Info.plist"; - INSTALL_PATH = /AppleInternal/XCTests/com.apple.security; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "$(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT)", "-lACM", "-framework", @@ -43795,7 +51407,7 @@ "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", ); "OTHER_LDFLAGS[sdk=macosx*]" = ( - "$(APPLE_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", "-lACM", "-framework", SystemConfiguration, @@ -44176,6 +51788,7 @@ }; EB49B2B3202D8780003F34A0 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -44203,8 +51816,14 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = tests/secdmockaks/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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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)", @@ -44218,6 +51837,10 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "-framework", + Security, + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -44227,6 +51850,7 @@ }; EB49B2B4202D8780003F34A0 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = DCE4E82B1D7A54D300AFB96E /* ios_on_macos.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -44254,8 +51878,14 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; INFOPLIST_FILE = tests/secdmockaks/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"; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + 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)", @@ -44269,6 +51899,10 @@ "$(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS)", "$(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS)", "$(OTHER_LDFLAGS_ACCOUNTS)", + "$(OTHER_LDFLAGS_UserManagement)", + "-framework", + Security, + "$(OTHER_LDFLAGS_FOR_SECURITYD)", ); PRODUCT_BUNDLE_IDENTIFIER = com.apple.Security.secdmockaks; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -44276,54 +51910,85 @@ }; name = Release; }; - EB6A6FAA1B90F83A0045DC68 /* Release */ = { + EB6952B7223B75C300F02C1C /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_MODULES = NO; 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_IDENTITY[sdk=embedded*]" = "iPhone Developer"; - 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; + CODE_SIGN_ENTITLEMENTS = OSX/sec/securityd/entitlements.plist; GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", + "SECD_SERVER=1", + "TARGET_DARWINOS=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; - IPHONEOS_DEPLOYMENT_TARGET = 9.3; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-laks", - "-framework", - IOKit, + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LLVM_LTO = NO; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + ); + PRODUCT_NAME = "$(TARGET_NAME)"; + REEXPORTED_LIBRARY_NAMES = ""; + STRIP_STYLE = debugging; + USE_HEADERMAP = YES; + WARNING_CFLAGS = ( + "$(inherited)", + "-Wno-error=modules-ambiguous-internal-linkage", ); - PRODUCT_NAME = phase1_ios; }; - name = Release; + name = Debug; }; - EB6A6FAB1B90F83A0045DC68 /* Release */ = { + EB6952B8223B75C300F02C1C /* 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", + "TARGET_DARWINOS=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LLVM_LTO = NO; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_UserManagement)", + "$(OTHER_LDFLAGS_ACM_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_ACL_LIBRARY)", + "$(OTHER_LDFLAGS_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_MOBILE_KEYBAG)", + ); PRODUCT_NAME = "$(TARGET_NAME)"; + REEXPORTED_LIBRARY_NAMES = ""; + STRIP_STYLE = debugging; + USE_HEADERMAP = YES; + WARNING_CFLAGS = ( + "$(inherited)", + "-Wno-error=modules-ambiguous-internal-linkage", + ); }; name = Release; }; @@ -44341,141 +52006,173 @@ }; name = Release; }; - EB6A6FB61B90F8C90045DC68 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - EB6A6FB71B90F8C90045DC68 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; - EB9C1D811BDFD0E100F89272 /* Debug */ = { + EB74CC1B2207E48100F1BBAD /* 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_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_STYLE = Automatic; 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; + INFOPLIST_FILE = keychain/KeychainSettings/Info.plist; + INSTALL_PATH = /AppleInternal/Library/PreferenceBundles/; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; OTHER_LDFLAGS = ( "-framework", - Security, - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-laks", - "-framework", - Security, - "-framework", - IOKit, - ); - "OTHER_LDFLAGS[sdk=macosx*]" = ( - "-laks", + AppleAccount, "-framework", - Security, + AuthKit, "-framework", - IOKit, + Accounts, ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainSettings; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SDKROOT = iphoneos.internal; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; }; name = Debug; }; - EB9C1D821BDFD0E100F89272 /* Release */ = { + EB74CC1C2207E48100F1BBAD /* 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_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = 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_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + CODE_SIGN_STYLE = Automatic; 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; + INFOPLIST_FILE = keychain/KeychainSettings/Info.plist; + INSTALL_PATH = /AppleInternal/Library/PreferenceBundles/; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = ( "-framework", - Security, - ); - "OTHER_LDFLAGS[sdk=embedded]" = ( - "-laks", - "-framework", - Security, - "-framework", - IOKit, - ); - "OTHER_LDFLAGS[sdk=macosx*]" = ( - "-laks", + AppleAccount, "-framework", - Security, + AuthKit, "-framework", - IOKit, + Accounts, ); + PRODUCT_BUNDLE_IDENTIFIER = com.apple.KeychainSettings; PRODUCT_NAME = "$(TARGET_NAME)"; - SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + SDKROOT = iphoneos.internal; + TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; + WRAPPER_EXTENSION = bundle; }; name = Release; }; - EB9C1DB01BDFD4DF00F89272 /* Debug */ = { + EB7E90F32193F90800B1FA21 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - EB9C1DB11BDFD4DF00F89272 /* Release */ = { + EB7E90F42193F90800B1FA21 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; - EBA9AA841CE30E58004E2B68 /* Debug */ = { + EB89088421F17D3C00F0DDDB /* 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", + "TARGET_DARWINOS=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LLVM_LTO = NO; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_MOCK_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_UserManagement)", + ); + PRODUCT_NAME = recovery_securityd; + REEXPORTED_LIBRARY_NAMES = ""; + STRIP_STYLE = debugging; + USE_HEADERMAP = YES; + WARNING_CFLAGS = ( + "$(inherited)", + "-Wno-error=modules-ambiguous-internal-linkage", + ); + }; + name = Debug; + }; + EB89088521F17D3C00F0DDDB /* 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", + "TARGET_DARWINOS=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = YES; + GCC_WARN_FOUR_CHARACTER_CONSTANTS = NO; + INSTALL_PATH = /usr/libexec; + LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/local/lib"; + LLVM_LTO = NO; + OTHER_CODE_SIGN_FLAGS = "$(OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION)"; + OTHER_LDFLAGS = ( + "$(inherited)", + "-ObjC", + "$(OTHER_LDFLAGS_PROTOBUF)", + "$(OTHER_LDFLAGS_SECURITYFOUNDATION)", + "$(OTHER_LDFLAGS_MOCK_AKS_LIBRARY)", + "$(OTHER_LDFLAGS_CrashReporterSupport)", + "$(OTHER_LDFLAGS_UserManagement)", + ); + PRODUCT_NAME = recovery_securityd; + REEXPORTED_LIBRARY_NAMES = ""; + STRIP_STYLE = debugging; + USE_HEADERMAP = YES; + WARNING_CFLAGS = ( + "$(inherited)", + "-Wno-error=modules-ambiguous-internal-linkage", + ); + }; + name = Release; + }; + EB9C1D811BDFD0E100F89272 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -44491,7 +52188,6 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemnotifications/secitemnotifications.entitlements; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -44531,7 +52227,7 @@ }; name = Debug; }; - EBA9AA851CE30E58004E2B68 /* Release */ = { + EB9C1D821BDFD0E100F89272 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; @@ -44547,7 +52243,6 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemnotifications/secitemnotifications.entitlements; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; @@ -44583,71 +52278,26 @@ }; name = Release; }; - EBB696031BE1F9DE00715F16 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = Security_executables_Bridge; - }; - name = Debug; - }; - EBB696041BE1F9DE00715F16 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - PRODUCT_NAME = phase1_ios; - }; - name = Debug; - }; - EBB839AA1E29665E00853BAC /* Debug */ = { + EB9C1DB01BDFD4DF00F89272 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - 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; - DEBUG_INFORMATION_FORMAT = dwarf; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - INSTALL_PATH = "$(SECURITY_FUZZER_BASE_DIR)"; - MTL_ENABLE_DEBUG_INFO = YES; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - EBB839AB1E29665E00853BAC /* Release */ = { + EB9C1DB11BDFD4DF00F89272 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - 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; - COPY_PHASE_STRIP = NO; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - INSTALL_PATH = "$(SECURITY_FUZZER_BASE_DIR)"; - MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; - EBBE20591C21380200B7A639 /* Debug */ = { + EBA9AA841CE30E58004E2B68 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -44658,14 +52308,13 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - DEBUGGING_SYMBOLS = YES; + CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemnotifications/secitemnotifications.entitlements; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu99; GCC_DYNAMIC_NO_PIC = NO; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -44673,21 +52322,38 @@ 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; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Security, + ); + "OTHER_LDFLAGS[sdk=embedded]" = ( + "-laks", + "-framework", + Security, + "-framework", + IOKit, + ); + "OTHER_LDFLAGS[sdk=macosx*]" = ( + "-laks", + "-framework", + Security, + "-framework", + IOKit, + ); PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; }; name = Debug; }; - EBBE205A1C21380200B7A639 /* Release */ = { + EBA9AA851CE30E58004E2B68 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; @@ -44698,6 +52364,7 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = RegressionTests/secitemnotifications/secitemnotifications.entitlements; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; @@ -44707,10 +52374,112 @@ 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; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; + OTHER_LDFLAGS = ( + "-framework", + Security, + ); + "OTHER_LDFLAGS[sdk=embedded]" = ( + "-laks", + "-framework", + Security, + "-framework", + IOKit, + ); + "OTHER_LDFLAGS[sdk=macosx*]" = ( + "-laks", + "-framework", + Security, + "-framework", + IOKit, + ); PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + EBB696031BE1F9DE00715F16 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + PRODUCT_NAME = Security_executables_Bridge; + }; + name = Debug; + }; + EBB839AA1E29665E00853BAC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + 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; + DEBUG_INFORMATION_FORMAT = dwarf; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = "$(SECURITY_FUZZER_BASE_DIR)"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + EBB839AB1E29665E00853BAC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + 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; + COPY_PHASE_STRIP = NO; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + INSTALL_PATH = "$(SECURITY_FUZZER_BASE_DIR)"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + EBB851F322F7912500424FD0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + INFOPLIST_FILE = OSX/utilities/test/Info.plist; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = "$(OCMOCK_RUNTIME_SEARCH_PATH)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SecurityUtilitiesTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + }; + name = Debug; + }; + EBB851F422F7912500424FD0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + ENABLE_NS_ASSERTIONS = NO; + INFOPLIST_FILE = OSX/utilities/test/Info.plist; + INSTALL_PATH = "$(SECURITY_XCTEST_DIRECTORY)"; + LD_RUNPATH_SEARCH_PATHS = "$(OCMOCK_RUNTIME_SEARCH_PATH)"; + PRODUCT_BUNDLE_IDENTIFIER = com.apple.security.SecurityUtilitiesTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = NO; + VALIDATE_PRODUCT = YES; }; name = Release; }; @@ -44903,7 +52672,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; RUN_CLANG_STATIC_ANALYZER = NO; SUPPORTED_PLATFORMS = macosx; - USE_HEADERMAP = NO; }; name = Debug; }; @@ -44940,7 +52708,6 @@ PRODUCT_NAME = "$(TARGET_NAME)"; RUN_CLANG_STATIC_ANALYZER = NO; SUPPORTED_PLATFORMS = macosx; - USE_HEADERMAP = NO; }; name = Release; }; @@ -44986,41 +52753,9 @@ }; name = Release; }; - F93C49041AB8FCE00047E01A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - F93C49051AB8FCE00047E01A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 05EF68B01949149C007958C3 /* Build configuration list for PBXAggregateTarget "Security_temporary_UI" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 05EF68B11949149C007958C3 /* Debug */, - 05EF68B21949149C007958C3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 05EF68B619491512007958C3 /* Build configuration list for PBXAggregateTarget "Security_frameworks" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 05EF68B719491512007958C3 /* Debug */, - 05EF68B819491512007958C3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 05EF68BC194915A5007958C3 /* Build configuration list for PBXAggregateTarget "Security_executables_osx" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45030,15 +52765,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 05EF68C2194915FB007958C3 /* Build configuration list for PBXAggregateTarget "Security_kexts" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 05EF68C3194915FB007958C3 /* Debug */, - 05EF68C4194915FB007958C3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 0C0BDB43175685B000BC1A7E /* Build configuration list for PBXNativeTarget "secdtests_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45129,7 +52855,16 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_macos_tests" */ = { + 3D58394A21890FFB000ACA44 /* Build configuration list for PBXNativeTarget "SecExperimentTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 3D58394B21890FFB000ACA44 /* Debug */, + 3D58394C21890FFB000ACA44 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 3DD1FF4A201C07F30086D049 /* Build configuration list for PBXNativeTarget "SecureTransportTests_macos" */ = { isa = XCConfigurationList; buildConfigurations = ( 3DD1FF4B201C07F30086D049 /* Debug */, @@ -45138,7 +52873,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransport_ios_tests" */ = { + 3DD1FFCD201FDB1D0086D049 /* Build configuration list for PBXNativeTarget "SecureTransportTests_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( 3DD1FFCE201FDB1D0086D049 /* Debug */, @@ -45246,15 +52981,6 @@ 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 = ( @@ -45282,15 +53008,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4C541FA20F250C8C00E508AE /* Build configuration list for PBXAggregateTarget "phase1" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 4C541F980F250C3000E508AE /* Debug */, - 4C541F9B0F250C3000E508AE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 4C541FA30F250C8C00E508AE /* Build configuration list for PBXAggregateTarget "Security_executables_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45309,7 +53026,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 4C91274A0ADBF4A100AF202E /* Build configuration list for PBXAggregateTarget "ios" */ = { + 4C91274A0ADBF4A100AF202E /* Build configuration list for PBXAggregateTarget "Security_all_ios" */ = { isa = XCConfigurationList; buildConfigurations = ( 792EFFE60CBBF878007C00A0 /* Debug */, @@ -45381,6 +53098,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 6C39237621F13E4D00D018AD /* Build configuration list for PBXNativeTarget "SecDbBackupTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6C39237721F13E4D00D018AD /* Debug */, + 6C39237821F13E4D00D018AD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 6C4605B51F882B9B001421B6 /* Build configuration list for PBXNativeTarget "KeychainAnalyticsTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45498,6 +53224,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + BEAA003E202A832500E51F45 /* Build configuration list for PBXNativeTarget "TrustedPeersHelper" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BEAA0037202A832500E51F45 /* Debug */, + BEAA0038202A832500E51F45 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BEAA0041202B728B00E51F45 /* Build configuration list for PBXAggregateTarget "Security_executables_Swift" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BEAA0042202B728B00E51F45 /* Debug */, + BEAA0043202B728B00E51F45 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + BECFA43920F91AFE00B11002 /* Build configuration list for PBXNativeTarget "tppolicy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BECFA43220F91AFE00B11002 /* Debug */, + BECFA43320F91AFE00B11002 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; BED208DA1EDF950E00753952 /* Build configuration list for PBXNativeTarget "manifeststresstest" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45507,6 +53260,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + BED987DB2099145400607A5F /* Build configuration list for PBXNativeTarget "TrustedPeersHelperUnitTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BED987DC2099145400607A5F /* Debug */, + BED987DD2099145400607A5F /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; BEF88C421EAFFC4000357577 /* Build configuration list for PBXNativeTarget "TrustedPeers" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45552,6 +53314,105 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D42C839921159147008D3D83 /* Build configuration list for PBXNativeTarget "security_cms" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D42C839A21159147008D3D83 /* Debug */, + D42C839B21159147008D3D83 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D44D1F6E2115893000E76E1A /* Build configuration list for PBXNativeTarget "CMS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D44D1F672115893000E76E1A /* Debug */, + D44D1F682115893000E76E1A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D453A4BD2122236D00850A26 /* Build configuration list for PBXNativeTarget "TrustTests_macos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D453A4BE2122236D00850A26 /* Debug */, + D453A4BF2122236D00850A26 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D458C4F4214E1DE10043D982 /* Build configuration list for PBXNativeTarget "TrustTestsRunner_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D458C4F5214E1DE10043D982 /* Debug */, + D458C4F6214E1DE10043D982 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D458C50D214E20540043D982 /* Build configuration list for PBXNativeTarget "TrustTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D458C50E214E20540043D982 /* Debug */, + D458C50F214E20540043D982 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4707A0A21136E6A005BCFDA /* Build configuration list for PBXNativeTarget "TrustTests_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4707A0B21136E6A005BCFDA /* Debug */, + D4707A0C21136E6A005BCFDA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D477EE5D21ED476D00C9AAFF /* Build configuration list for PBXAggregateTarget "Security_tests_bridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D477EE5E21ED476D00C9AAFF /* Debug */, + D477EE5F21ED476D00C9AAFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D477EE6121ED477C00C9AAFF /* Build configuration list for PBXAggregateTarget "Security_tests_tvos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D477EE6221ED477C00C9AAFF /* Debug */, + D477EE6321ED477C00C9AAFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D477EE6521ED479500C9AAFF /* Build configuration list for PBXAggregateTarget "Security_tests_watchos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D477EE6621ED479500C9AAFF /* Debug */, + D477EE6721ED479500C9AAFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D477EE6921ED47C600C9AAFF /* Build configuration list for PBXAggregateTarget "Security_executables_darwinos_only_osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D477EE6A21ED47C600C9AAFF /* Debug */, + D477EE6B21ED47C600C9AAFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D477EE6D21ED47DB00C9AAFF /* Build configuration list for PBXAggregateTarget "Security_executables_darwinos_only_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D477EE6E21ED47DB00C9AAFF /* Debug */, + D477EE6F21ED47DB00C9AAFF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; D4ADA31A1E2B41670031CEA3 /* Build configuration list for PBXNativeTarget "libtrustd" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45561,6 +53422,132 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + D4D1D3FE21AD0B3F0012C66C /* Build configuration list for PBXAggregateTarget "Security_executables_core_watchos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4D1D3FF21AD0B3F0012C66C /* Debug */, + D4D1D40021AD0B3F0012C66C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4D1D40321AD0B4B0012C66C /* Build configuration list for PBXAggregateTarget "Security_executables_core_tvos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4D1D40421AD0B4B0012C66C /* Debug */, + D4D1D40521AD0B4B0012C66C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4D1D40A21ADC9720012C66C /* Build configuration list for PBXAggregateTarget "Security_executables_core_osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4D1D40B21ADC9720012C66C /* Debug */, + D4D1D40C21ADC9720012C66C /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4D1FDDD21165F8B003538E2 /* Build configuration list for PBXNativeTarget "security_cms_regressions" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4D1FDDE21165F8B003538E2 /* Debug */, + D4D1FDDF21165F8B003538E2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F47B3922270B6F003483E9 /* Build configuration list for PBXAggregateTarget "Security_all_watchos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F47B3A22270B6F003483E9 /* Debug */, + D4F47B3B22270B6F003483E9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F47B3D22270B8A003483E9 /* Build configuration list for PBXAggregateTarget "Security_all_tvos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F47B3E22270B8A003483E9 /* Debug */, + D4F47B3F22270B8A003483E9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F47B4122270B97003483E9 /* Build configuration list for PBXAggregateTarget "Security_all_bridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F47B4222270B97003483E9 /* Debug */, + D4F47B4322270B97003483E9 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56B8B217FA32000FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_executables_core_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56B87217FA32000FCA6B7 /* Debug */, + D4F56B88217FA32000FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56B8E217FA3F800FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_frameworks_tvos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56B8F217FA3F800FCA6B7 /* Debug */, + D4F56B90217FA3F800FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56B92217FA40800FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_frameworks_watchos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56B93217FA40800FCA6B7 /* Debug */, + D4F56B94217FA40800FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56BC321813EC900FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_osx" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56BC421813EC900FCA6B7 /* Debug */, + D4F56BC521813EC900FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56BC721813ECF00FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_ios" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56BC821813ECF00FCA6B7 /* Debug */, + D4F56BC921813ECF00FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56BCB21813EDC00FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_tvos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56BCC21813EDC00FCA6B7 /* Debug */, + D4F56BCD21813EDC00FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + D4F56BCF21813EE800FCA6B7 /* Build configuration list for PBXAggregateTarget "Security_internal_watchos" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + D4F56BD021813EE800FCA6B7 /* Debug */, + D4F56BD121813EE800FCA6B7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DA30D6801DF8C8FB00EC6B43 /* Build configuration list for PBXNativeTarget "KeychainSyncAccountUpdater" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45570,6 +53557,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DA41FE152241ADC000838FB3 /* Build configuration list for PBXNativeTarget "otpaird" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA41FE122241ADC000838FB3 /* Debug */, + DA41FE132241ADC000838FB3 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DAE40BCB20CF3E46002D5674 /* Build configuration list for PBXNativeTarget "secitemcanarytest" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45606,6 +53602,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DC05037F21409A4100A8EDB7 /* Build configuration list for PBXNativeTarget "OCMockUmbrella" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DC05037B21409A4100A8EDB7 /* Debug */, + DC05037C21409A4100A8EDB7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DC0BC55D1D8B6D2E00070CB0 /* Build configuration list for PBXNativeTarget "XPCKeychainSandboxCheck" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45804,6 +53809,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DC0EF8F3208697C700AB9E95 /* Build configuration list for PBXNativeTarget "tpctl" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DC0EF8F4208697C700AB9E95 /* Debug */, + DC0EF8F5208697C700AB9E95 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DC17890D1D77980500B50D50 /* Build configuration list for PBXNativeTarget "Security_osx" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45813,11 +53827,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DC222C741E034D1F00B09171 /* Build configuration list for PBXNativeTarget "libsecurityd_ios_NO_AKS" */ = { + DC311E742124B8A8002F5EAE /* Build configuration list for PBXNativeTarget "aks_real_witness" */ = { isa = XCConfigurationList; buildConfigurations = ( - DC222C751E034D1F00B09171 /* Debug */, - DC222C761E034D1F00B09171 /* Release */, + DC311E752124B8A8002F5EAE /* Debug */, + DC311E762124B8A8002F5EAE /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -45831,6 +53845,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DC36895F21235F42003A3735 /* Build configuration list for PBXNativeTarget "aks_mock" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DC36896021235F42003A3735 /* Debug */, + DC36896121235F42003A3735 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DC3A4B5B1D91E9FB00E46D4A /* Build configuration list for PBXNativeTarget "CodeSigningHelper" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -45858,24 +53881,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DC52EA491D80CB7000B0A59C /* Build configuration list for PBXNativeTarget "SecurityTool" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DC52EA4A1D80CB7000B0A59C /* Debug */, - DC52EA4B1D80CB7000B0A59C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - DC52EBD21D80CEF100B0A59C /* Build configuration list for PBXNativeTarget "SecurityCommands" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DC52EBD31D80CEF100B0A59C /* Debug */, - DC52EBD41D80CEF100B0A59C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; DC52EC311D80CFB200B0A59C /* Build configuration list for PBXNativeTarget "SOSCommands" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46074,11 +54079,20 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DC71D9DC1D95BA6C0065FB93 /* Build configuration list for PBXNativeTarget "ASN1" */ = { + DC6D1C75208A547400AB21AF /* Build configuration list for PBXAggregateTarget "Security_frameworks_bridge" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DC6D1C76208A547400AB21AF /* Debug */, + DC6D1C77208A547400AB21AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + DC7FC44C21EE914D003C39B8 /* Build configuration list for PBXNativeTarget "FeatureFlagsPlist" */ = { isa = XCConfigurationList; buildConfigurations = ( - DC71D9DD1D95BA6C0065FB93 /* Debug */, - DC71D9DE1D95BA6C0065FB93 /* Release */, + DC7FC44D21EE914D003C39B8 /* Debug */, + DC7FC44E21EE914D003C39B8 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -46101,7 +54115,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - DC8834051D8A218F00CE0ACA /* Build configuration list for PBXNativeTarget "ASN1_not_installed" */ = { + DC8834051D8A218F00CE0ACA /* Build configuration list for PBXNativeTarget "ASN1" */ = { isa = XCConfigurationList; buildConfigurations = ( DC8834061D8A218F00CE0ACA /* Debug */, @@ -46191,6 +54205,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DC99B88F20EACA470065B73B /* Build configuration list for PBXNativeTarget "OctagonTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DC99B89020EACA470065B73B /* Debug */, + DC99B89120EACA470065B73B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DCB3406A1D8A24DF0054D16E /* Build configuration list for PBXNativeTarget "security_authorization" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46245,6 +54268,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DCBF4ADD21FFC82100539F0A /* Build configuration list for PBXNativeTarget "SecEscrowRequestTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCBF4ADE21FFC82100539F0A /* Debug */, + DCBF4ADF21FFC82100539F0A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DCC78EAF1D8088E200865A7C /* Build configuration list for PBXNativeTarget "security" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46371,6 +54403,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DCDA5E542124B9C6009B11B2 /* Build configuration list for PBXAggregateTarget "aks_support" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCDA5E502124B9C6009B11B2 /* Debug */, + DCDA5E512124B9C6009B11B2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DCE4E6A11D7A37FA00AFB96E /* Build configuration list for PBXNativeTarget "security2tool_macos" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46443,6 +54484,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + DCF216DC21ADD5B10029CCC1 /* Build configuration list for PBXNativeTarget "protobuf_source_generation" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCF216D821ADD5B10029CCC1 /* Debug */, + DCF216D921ADD5B10029CCC1 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DCF782BB1D88B44300E694BB /* Build configuration list for PBXLegacyTarget "==== macOS Libraries ======" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46515,6 +54565,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + E060D1CA212478120025B833 /* Build configuration list for PBXNativeTarget "OctagonTestHarnessXPCServiceProtocol" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E060D1CB212478120025B833 /* Debug */, + E060D1CC212478120025B833 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E060D1CD212478120025B833 /* Build configuration list for PBXNativeTarget "OctagonTestHarnessXPCService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E060D1CE212478120025B833 /* Debug */, + E060D1CF212478120025B833 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E060D1D2212478120025B833 /* Build configuration list for PBXNativeTarget "OctagonTestHarness" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + E060D1D3212478120025B833 /* Debug */, + E060D1D4212478120025B833 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; E710C75C1331946500F85568 /* Build configuration list for PBXNativeTarget "SecurityTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46524,7 +54601,7 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E74584671BF68EBA001B54A4 /* Build configuration list for PBXAggregateTarget "osx" */ = { + E74584671BF68EBA001B54A4 /* Build configuration list for PBXAggregateTarget "Security_all_osx" */ = { isa = XCConfigurationList; buildConfigurations = ( E74584681BF68EBA001B54A4 /* Debug */, @@ -46560,15 +54637,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - E79EEDE11CD4000C00C2FBFC /* Build configuration list for PBXAggregateTarget "Security_executables" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E79EEDE21CD4000C00C2FBFC /* Debug */, - E79EEDE31CD4000C00C2FBFC /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; E7B01BEF166594AB000485F1 /* Build configuration list for PBXNativeTarget "SyncDevTest2" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -46605,24 +54673,6 @@ 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 = ( @@ -46704,12 +54754,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB6A6FA91B90F83A0045DC68 /* Build configuration list for PBXAggregateTarget "phase1_ios" */ = { + EB6952B6223B75C300F02C1C /* Build configuration list for PBXNativeTarget "secitemd" */ = { isa = XCConfigurationList; buildConfigurations = ( - EB6A6FAA1B90F83A0045DC68 /* Release */, - EB6A6FAB1B90F83A0045DC68 /* Release */, - EBB696041BE1F9DE00715F16 /* Debug */, + EB6952B7223B75C300F02C1C /* Debug */, + EB6952B8223B75C300F02C1C /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -46724,11 +54773,29 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EB6A6FB51B90F8C90045DC68 /* Build configuration list for PBXAggregateTarget "phase2" */ = { + EB74CC1A2207E48100F1BBAD /* Build configuration list for PBXNativeTarget "KeychainSettings" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EB74CC1B2207E48100F1BBAD /* Debug */, + EB74CC1C2207E48100F1BBAD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EB7E90F22193F90800B1FA21 /* Build configuration list for PBXAggregateTarget "Build C2 Metrics" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + EB7E90F32193F90800B1FA21 /* Debug */, + EB7E90F42193F90800B1FA21 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + EB89088321F17D3C00F0DDDB /* Build configuration list for PBXNativeTarget "recovery_securityd" */ = { isa = XCConfigurationList; buildConfigurations = ( - EB6A6FB61B90F8C90045DC68 /* Debug */, - EB6A6FB71B90F8C90045DC68 /* Release */, + EB89088421F17D3C00F0DDDB /* Debug */, + EB89088521F17D3C00F0DDDB /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -46769,11 +54836,11 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EBBE20581C21380200B7A639 /* Build configuration list for PBXLegacyTarget "SecurityFeatures" */ = { + EBB8520822F7912500424FD0 /* Build configuration list for PBXNativeTarget "SecurityUtilitiesTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - EBBE20591C21380200B7A639 /* Debug */, - EBBE205A1C21380200B7A639 /* Release */, + EBB851F322F7912500424FD0 /* Debug */, + EBB851F422F7912500424FD0 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -46814,15 +54881,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - F93C49031AB8FCE00047E01A /* Build configuration list for PBXAggregateTarget "ckcdiagnose.sh" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - F93C49041AB8FCE00047E01A /* Debug */, - F93C49051AB8FCE00047E01A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ /* Begin XCVersionGroup section */ @@ -46836,6 +54894,17 @@ sourceTree = ""; versionGroupType = wrapper.xcdatamodel; }; + BE92249C204F203C0052E828 /* TrustedPeersHelper.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + DC3B222C22C408BE006D915C /* TrustedPeersHelper_2.xcdatamodel */, + BE92249D204F203C0052E828 /* TrustedPeersHelper.xcdatamodel */, + ); + currentVersion = DC3B222C22C408BE006D915C /* TrustedPeersHelper_2.xcdatamodel */; + path = TrustedPeersHelper.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 deleted file mode 100644 index 38f32efc..00000000 --- a/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/B3656633-AB83-4153-B404-DE14DBDC5ED6.plist +++ /dev/null @@ -1,52 +0,0 @@ - - - - - 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 deleted file mode 100644 index 50ad5a85..00000000 --- a/Security.xcodeproj/xcshareddata/xcbaselines/EB05C4F01FE5E48A00D68712.xcbaseline/Info.plist +++ /dev/null @@ -1,33 +0,0 @@ - - - - - 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 24511e3a..c30a62b4 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/CKKSTests.xcscheme @@ -3,8 +3,8 @@ LastUpgradeVersion = "1000" version = "1.3"> + parallelizeBuildables = "NO" + buildImplicitDependencies = "NO"> diff --git a/Security.xcodeproj/xcshareddata/xcschemes/OctagonTests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/OctagonTests.xcscheme new file mode 100644 index 00000000..34a200c9 --- /dev/null +++ b/Security.xcodeproj/xcshareddata/xcschemes/OctagonTests.xcscheme @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/TrustTests_ios.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/TrustTests_ios.xcscheme new file mode 100644 index 00000000..3fbabf06 --- /dev/null +++ b/Security.xcodeproj/xcshareddata/xcschemes/TrustTests_ios.xcscheme @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/TrustTests_macos.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/TrustTests_macos.xcscheme new file mode 100644 index 00000000..42212060 --- /dev/null +++ b/Security.xcodeproj/xcshareddata/xcschemes/TrustTests_macos.xcscheme @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/TrustedPeers.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/TrustedPeers.xcscheme index 752f6909..2f0c83a9 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/TrustedPeers.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/TrustedPeers.xcscheme @@ -3,8 +3,8 @@ LastUpgradeVersion = "1000" version = "1.3"> + parallelizeBuildables = "NO" + buildImplicitDependencies = "NO"> + version = "1.8"> @@ -15,8 +15,8 @@ @@ -41,6 +41,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -82,18 +91,17 @@ ReferencedContainer = "container:Security.xcodeproj"> + + + + - - - - - - - - - - - - - - - - @@ -270,10 +258,6 @@ argument = "si_24_sectrust_itms" isEnabled = "NO"> - - @@ -303,7 +287,7 @@ isEnabled = "NO"> - - - - @@ -462,14 +438,6 @@ argument = "si_84_sectrust_allowlist" isEnabled = "NO"> - - - - @@ -486,10 +454,6 @@ argument = "si_95_cms_basic" isEnabled = "NO"> - - @@ -744,8 +708,6 @@ isEnabled = "YES"> - - @@ -41,6 +41,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -53,17 +62,6 @@ - - - - - - - - - - - - - - - - @@ -259,7 +237,7 @@ isEnabled = "NO"> - - - - @@ -410,10 +380,6 @@ argument = "si_84_sectrust_allowlist" isEnabled = "NO"> - - @@ -587,8 +553,6 @@ isEnabled = "NO"> - - + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/osx - World.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/osx - World.xcscheme index c5f1a479..72291638 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/osx - World.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/osx - World.xcscheme @@ -15,8 +15,8 @@ @@ -27,6 +27,15 @@ selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -38,16 +47,6 @@ ReferencedContainer = "container:Security.xcodeproj"> - - - - + + + + + + + + - - - - - - - - - - - - - - - - @@ -301,10 +289,6 @@ argument = "si_24_sectrust_itms" isEnabled = "NO"> - - @@ -330,7 +314,7 @@ isEnabled = "NO"> - - - - @@ -429,14 +405,6 @@ argument = "si_84_sectrust_allowlist" isEnabled = "NO"> - - - - @@ -445,10 +413,6 @@ argument = "si_89_cms_hash_agility" isEnabled = "NO"> - - - - diff --git a/Security.xcodeproj/xcshareddata/xcschemes/osx - secdtests.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/osx - secdtests.xcscheme index 9904d080..471ef0c5 100644 --- a/Security.xcodeproj/xcshareddata/xcschemes/osx - secdtests.xcscheme +++ b/Security.xcodeproj/xcshareddata/xcschemes/osx - secdtests.xcscheme @@ -15,8 +15,8 @@ @@ -91,195 +91,199 @@ isEnabled = "NO"> + + diff --git a/Security.xcodeproj/xcshareddata/xcschemes/secdmockaks.xcscheme b/Security.xcodeproj/xcshareddata/xcschemes/secdmockaks.xcscheme new file mode 100644 index 00000000..bca98cce --- /dev/null +++ b/Security.xcodeproj/xcshareddata/xcschemes/secdmockaks.xcscheme @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SecurityTests/NOTE.txt b/SecurityTests/NOTE.txt index 85c74696..109889c3 100644 --- a/SecurityTests/NOTE.txt +++ b/SecurityTests/NOTE.txt @@ -1,4 +1,5 @@ -Much of the historical content of these SecurityTests has been archived to: - -https://stash.sd.apple.com/projects/COREOSINT/repos/securitytech/browse/Archive/SecurityTests +Most of the content in SecurityTests was specific to the legacy CDSA +implementation of Security, which has been superseded. +See Security-57740.31.2 (10.12.3) and earlier versions for the historical +content of this directory. diff --git a/SecurityTests/SecurityTests-Entitlements.plist b/SecurityTests/SecurityTests-Entitlements.plist index a44c8e8e..b116d812 100644 --- a/SecurityTests/SecurityTests-Entitlements.plist +++ b/SecurityTests/SecurityTests-Entitlements.plist @@ -16,6 +16,8 @@ com.apple.keystore.device + com.apple.private.applecredentialmanager.allow + restore-keychain migrate-keychain @@ -42,9 +44,9 @@ 123456.test.group2 com.apple.bluetooth - com.apple.developer.shared-web-credentials + com.apple.developer.associated-domains - localhost + webcredentials:localhost diff --git a/SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA certificates.pem b/SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA certificates.pem deleted file mode 100644 index 8298172b..00000000 --- a/SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA certificates.pem +++ /dev/null @@ -1,23 +0,0 @@ ------BEGIN CERTIFICATE----- -MIID1zCCAr+gAwIBAgIBATANBgkqhkiG9w0BAQsFADCBjjEhMB8GA1UEAwwYU1NM -IFRydXN0IFBvbGljeSBUZXN0IENBMRQwEgYDVQQKDAtBcHBsZSwgSW5jLjEdMBsG -A1UECwwUU2VjdXJpdHkgRW5naW5lZXJpbmcxEzARBgNVBAgMCkNhbGlmb3JuaWEx -CzAJBgNVBAYTAlVTMRIwEAYDVQQHDAlDdXBlcnRpbm8wHhcNMTUwODIwMDIwMTE5 -WhcNMjUwODE3MDIwMTE5WjCBjjEhMB8GA1UEAwwYU1NMIFRydXN0IFBvbGljeSBU -ZXN0IENBMRQwEgYDVQQKDAtBcHBsZSwgSW5jLjEdMBsGA1UECwwUU2VjdXJpdHkg -RW5naW5lZXJpbmcxEzARBgNVBAgMCkNhbGlmb3JuaWExCzAJBgNVBAYTAlVTMRIw -EAYDVQQHDAlDdXBlcnRpbm8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB -AQDfOz+87r4k8UR5izkBPdOc5PPRK0OD/kTz+Njz16PofdAbGB0Nfl2Js8fhPr5u -492fjULWsdJjaU0J6QkhEUIeePcgjFXzMuvU7f29pyWQCyRqhsE/vBnFPQJSEP7z -06yXLfWi9ZJHzC54IWxXyI2eBFmDF9hjXt/lJDs0CxVz7FBhku+rHOtC33ZrX2TR -ONzpNoJqs8xvSjuv0/Id8/TYD6Bd9d0hkh/xmA0ScoI+6sn0TAxDPx0YiuVNvZ9b -ETfRPK3bcqyQ0HJCErbhbxB3HmA7QjHcnN37NqteZfSrHA1/G/+w+kIKgi5DTCly -gsth9L+7NJ5DrO9QxcRYf2U5AgMBAAGjPjA8MBIGA1UdEwEB/wQIMAYBAf8CAQAw -DgYDVR0PAQH/BAQDAgKEMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3 -DQEBCwUAA4IBAQANTqxnwOD6Zi7DPpA0Tt9k+gYuTpmgkfaW4UFd9iNWvGT5ec1w -y9CjF4dkbD1yykterr/vhATUMPP/vKEoLtH9Q6MYzokAWT5qcHPKPDysavy5XHkU -18gZY203KPl41rkusnXRBZzO1IfgkvdG33NfVhz/lQSos6lMdAfGCrnNTBcfQHN9 -tnPHKB99R4YqoqGDi6RGhesZjF48pHOdBILnDio8g6EQzCeBHT4afRxL/UU5uxrF -rikiViwqdsgmn/BPSMidIMmdY8ThrXCpdbOy/zXriWqAEWB9q9XSpNMcNCHfvgpP -zHnKiIErBhEfMSJDk3YskFtfQj6XYUvMIm7w ------END CERTIFICATE----- diff --git a/SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA.certAuthorityConfig b/SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA.certAuthorityConfig deleted file mode 100644 index fb7ac885..00000000 --- a/SecurityTests/ssl-policy-certs/SSL Trust Policy Test CA/SSL Trust Policy Test CA.certAuthorityConfig +++ /dev/null @@ -1,112 +0,0 @@ - - - - - BasicConstraintsPresent - 1 - CACertificates - - - CAWebSiteURL - - CommonName - SSL Trust Policy Test CA - Country - US - DNSName - - EmailAddressOfCA - - EmailAddressOfCAAdmin - test@apple.com - ExtendedKUEAny - 0 - ExtendedKUECodeSigning - 0 - ExtendedKUECodeSigningApple - 0 - ExtendedKUECodeSigningDevelopment - 0 - ExtendedKUEDotMacEmailEncryption - 0 - ExtendedKUEDotMacEmailSigning - 0 - ExtendedKUEEmailProtection - 0 - ExtendedKUEIsCritical - 1 - ExtendedKUEPKINITClientAuth - 0 - ExtendedKUEPKINITServerAuth - 0 - ExtendedKUEPresent - 1 - ExtendedKUESSLClientAuth - 0 - ExtendedKUESSLServerAuth - 1 - ExtendedKUEiChatEncryption - 0 - ExtendedKUEiChatSigning - 0 - HashedPEMCertAuthorityCerts - - - IPAddress - - IssuerPublicKeyHash - - fxdsczh3NdDfinOF/wjeURam58Y= - - KeyAlgorithm - 1 - KeySize - 2048 - KeyUsageExtensionCRLSigning - 0 - KeyUsageExtensionCertSigning - 0 - KeyUsageExtensionDataEncipherment - 0 - KeyUsageExtensionDecipherOnly - 0 - KeyUsageExtensionEncipherOnly - 0 - KeyUsageExtensionIsCritical - 1 - KeyUsageExtensionIsEnabled - 1 - KeyUsageExtensionKeyAgreement - 0 - KeyUsageExtensionKeyEncipherment - 0 - KeyUsageExtensionNonRepudiation - 0 - KeyUsageExtensionSignature - 1 - LastSerialNumberUsed - 20 - Locality - Cupertino - Organization - Apple, Inc. - OrganizationUnit - Security Engineering - PathLengthConstraint - 0 - PathLengthConstraintPresent - 0 - RFC822Name - - State - California - SubjectAltNameIsCritical - 0 - SubjectAltNamePresent - 1 - URI - - ValidityPeriod - 3650 - - diff --git a/SecurityTests/ssl-policy-certs/SSLTrustPolicyTest.plist b/SecurityTests/ssl-policy-certs/SSLTrustPolicyTest.plist index 2512207f..e7217c5f 100644 --- a/SecurityTests/ssl-policy-certs/SSLTrustPolicyTest.plist +++ b/SecurityTests/ssl-policy-certs/SSLTrustPolicyTest.plist @@ -27,7 +27,7 @@ Hostname test.apple.com Result - kSecTrustResultUnspecified + kSecTrustResultRecoverableTrustFailure Test4 @@ -261,7 +261,7 @@ Hostname TEST.apple.com Result - kSecTrustResultUnspecified + kSecTrustResultRecoverableTrustFailure Test30 diff --git a/SecurityTests/ssl-policy-certs/SSLTrustPolicyTestCA.p12 b/SecurityTests/ssl-policy-certs/SSLTrustPolicyTestCA.p12 deleted file mode 100644 index 567978eb06a350cd8c32eec301e81c4f48df8842..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1498 zcmV<01tt10f(6zB0Ru3C1)T;7Duzgg_YDCD0ic2fjs$`QiZFr&hA@H!f(8jHhDe6@ z4FLxMpn?T+1cC)`FoFeZFoFeV1`8^NNQUM$Gz3Mz(3hW8Bt z3;_c$4g?6qFttlKH?KhcAqd!Bf2u?~r0;lXKS zk6Wr9D?g$D^8M{5LA7+oJp()KHOKNMsSQyUqd$_E@JC_ZNm6$RZWGcs3j;l$5rhP; z0k)55tzod0S}V%6Xl%VK5|;zHp`#3+4hSiBYyAnO9IY~T@(r&hhNN~%)w=6W(j-#T24$SX9Yoc0M!7el(R zBPC;z$wTi`eMvC-O(d9jvG@-y$I$)^VaF2XiJzsw{7vgVC)6aj zi)^}SY3*BC45YV$E49`m!EMs(TK$d8D4zocIzeGdM}?#ufpzm@<$_^FZra-{@=LJU z!RC_=RPp|x@o3kHsq*LhJ!E4K+~#|e-(VNaYPwVURAT9RD)bugwC8*He&3s?;R|dbt$c3i_oO}^f!#mRl=3qPTMv%VXJdQTtfoDAa2%4e`Q7Q~ zpfyp{LZ33HdT=xp5Jlh~JX8$s1k=97{}Iz9NMt1;z}k|UC)>wSz`OgQ3F?Qba$7!p zvUJDz`Xu13r(!A8tNqEvt?u-h6hZ5Q6xg-1+A+p&&+fHmeobUmY9HZ zVvscjmU0y^{!K*nIDNS(+8vj$7#7S9vJ`>25wHr_cH&MMZF7~4HiUIbDfhI`OP&+< z?(ZhaEjT_~5D=2Yt&*S1L6*P`i7bQq5$4y^xR4^p$g5Yy(?7Az{s2MH;^e7AG_6Dt#~_ zYQ|~I9kpI|5GKO~c+}7=Kb_GyEoFe-CiHTZ8&p|SRL2}>|Q39AS( zW-vbn2`Yw2hW8Bt2^29h9xwn?08;==03ZNV0CE6z0CNCz03ZNR0B-&LNQU, https://www.niap-ccevs.org/pp/pp_md_v2.0.pdf, FCS_TLSC_EXT.2.2, Assurance Activity Test 3 Test 4 --------- @@ -291,8 +289,8 @@ Certificate: ValidHostnameTest3.cer Hostname: TEST.apple.com CN: test.apple.com SAN not present -Expected Result:SUCCEED -Notes: +Expected Result:FAIL +Notes: , Test 30 --------- diff --git a/SecurityTests/testlist.h b/SecurityTests/testlist.h index 3d647278..c39e1c32 100644 --- a/SecurityTests/testlist.h +++ b/SecurityTests/testlist.h @@ -3,7 +3,7 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/Regressions/SOSCircle_regressions.h" #include #include #include diff --git a/SecurityTool/APPLE_LICENSE b/SecurityTool/APPLE_LICENSE deleted file mode 100644 index 71fe6fd7..00000000 --- a/SecurityTool/APPLE_LICENSE +++ /dev/null @@ -1,335 +0,0 @@ -APPLE PUBLIC SOURCE LICENSE -Version 2.0 - August 6, 2003 - -Please read this License carefully before downloading this software. By -downloading or using this software, you are agreeing to be bound by the terms -of this License. If you do not or cannot agree to the terms of this License, -please do not download or use the software. - -Apple Note: In January 2007, Apple changed its corporate name from "Apple -Computer, Inc." to "Apple Inc." This change has been reflected below and -copyright years updated, but no other changes have been made to the APSL 2.0. - -1. General; Definitions. This License applies to any program or other -work which Apple Inc. ("Apple") makes publicly available and which contains a -notice placed by Apple identifying such program or work as "Original Code" and -stating that it is subject to the terms of this Apple Public Source License -version 2.0 ("License"). As used in this License: - -1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is the -grantor of rights, (i) claims of patents that are now or hereafter acquired, -owned by or assigned to Apple and (ii) that cover subject matter contained in -the Original Code, but only to the extent necessary to use, reproduce and/or -distribute the Original Code without infringement; and (b) in the case where -You are the grantor of rights, (i) claims of patents that are now or hereafter -acquired, owned by or assigned to You and (ii) that cover subject matter in -Your Modifications, taken alone or in combination with Original Code. - -1.2 "Contributor" means any person or entity that creates or contributes to -the creation of Modifications. - -1.3 "Covered Code" means the Original Code, Modifications, the combination -of Original Code and any Modifications, and/or any respective portions thereof. - -1.4 "Externally Deploy" means: (a) to sublicense, distribute or otherwise -make Covered Code available, directly or indirectly, to anyone other than You; -and/or (b) to use Covered Code, alone or as part of a Larger Work, in any way -to provide a service, including but not limited to delivery of content, through -electronic communication with a client other than You. - -1.5 "Larger Work" means a work which combines Covered Code or portions -thereof with code not governed by the terms of this License. - -1.6 "Modifications" mean any addition to, deletion from, and/or change to, -the substance and/or structure of the Original Code, any previous -Modifications, the combination of Original Code and any previous Modifications, -and/or any respective portions thereof. When code is released as a series of -files, a Modification is: (a) any addition to or deletion from the contents of -a file containing Covered Code; and/or (b) any new file or other representation -of computer program statements that contains any part of Covered Code. - -1.7 "Original Code" means (a) the Source Code of a program or other work as -originally made available by Apple under this License, including the Source -Code of any updates or upgrades to such programs or works made available by -Apple under this License, and that has been expressly identified by Apple as -such in the header file(s) of such work; and (b) the object code compiled from -such Source Code and originally made available by Apple under this License - -1.8 "Source Code" means the human readable form of a program or other work -that is suitable for making modifications to it, including all modules it -contains, plus any associated interface definition files, scripts used to -control compilation and installation of an executable (object code). - -1.9 "You" or "Your" means an individual or a legal entity exercising rights -under this License. For legal entities, "You" or "Your" includes any entity -which controls, is controlled by, or is under common control with, You, where -"control" means (a) the power, direct or indirect, to cause the direction or -management of such entity, whether by contract or otherwise, or (b) ownership -of fifty percent (50%) or more of the outstanding shares or beneficial -ownership of such entity. - -2. Permitted Uses; Conditions & Restrictions. Subject to the terms and -conditions of this License, Apple hereby grants You, effective on the date You -accept this License and download the Original Code, a world-wide, royalty-free, -non-exclusive license, to the extent of Apple's Applicable Patent Rights and -copyrights covering the Original Code, to do the following: - -2.1 Unmodified Code. You may use, reproduce, display, perform, internally -distribute within Your organization, and Externally Deploy verbatim, unmodified -copies of the Original Code, for commercial or non-commercial purposes, -provided that in each instance: - -(a) You must retain and reproduce in all copies of Original Code the -copyright and other proprietary notices and disclaimers of Apple as they appear -in the Original Code, and keep intact all notices in the Original Code that -refer to this License; and - -(b) You must include a copy of this License with every copy of Source Code -of Covered Code and documentation You distribute or Externally Deploy, and You -may not offer or impose any terms on such Source Code that alter or restrict -this License or the recipients' rights hereunder, except as permitted under -Section 6. - -2.2 Modified Code. You may modify Covered Code and use, reproduce, -display, perform, internally distribute within Your organization, and -Externally Deploy Your Modifications and Covered Code, for commercial or -non-commercial purposes, provided that in each instance You also meet all of -these conditions: - -(a) You must satisfy all the conditions of Section 2.1 with respect to the -Source Code of the Covered Code; - -(b) You must duplicate, to the extent it does not already exist, the notice -in Exhibit A in each file of the Source Code of all Your Modifications, and -cause the modified files to carry prominent notices stating that You changed -the files and the date of any change; and - -(c) If You Externally Deploy Your Modifications, You must make Source Code -of all Your Externally Deployed Modifications either available to those to whom -You have Externally Deployed Your Modifications, or publicly available. Source -Code of Your Externally Deployed Modifications must be released under the terms -set forth in this License, including the license grants set forth in Section 3 -below, for as long as you Externally Deploy the Covered Code or twelve (12) -months from the date of initial External Deployment, whichever is longer. You -should preferably distribute the Source Code of Your Externally Deployed -Modifications electronically (e.g. download from a web site). - -2.3 Distribution of Executable Versions. In addition, if You Externally -Deploy Covered Code (Original Code and/or Modifications) in object code, -executable form only, You must include a prominent notice, in the code itself -as well as in related documentation, stating that Source Code of the Covered -Code is available under the terms of this License with information on how and -where to obtain such Source Code. - -2.4 Third Party Rights. You expressly acknowledge and agree that although -Apple and each Contributor grants the licenses to their respective portions of -the Covered Code set forth herein, no assurances are provided by Apple or any -Contributor that the Covered Code does not infringe the patent or other -intellectual property rights of any other entity. Apple and each Contributor -disclaim any liability to You for claims brought by any other entity based on -infringement of intellectual property rights or otherwise. As a condition to -exercising the rights and licenses granted hereunder, You hereby assume sole -responsibility to secure any other intellectual property rights needed, if any. -For example, if a third party patent license is required to allow You to -distribute the Covered Code, it is Your responsibility to acquire that license -before distributing the Covered Code. - -3. Your Grants. In consideration of, and as a condition to, the licenses -granted to You under this License, You hereby grant to any person or entity -receiving or distributing Covered Code under this License a non-exclusive, -royalty-free, perpetual, irrevocable license, under Your Applicable Patent -Rights and other intellectual property rights (other than patent) owned or -controlled by You, to use, reproduce, display, perform, modify, sublicense, -distribute and Externally Deploy Your Modifications of the same scope and -extent as Apple's licenses under Sections 2.1 and 2.2 above. - -4. Larger Works. You may create a Larger Work by combining Covered Code -with other code not governed by the terms of this License and distribute the -Larger Work as a single product. In each such instance, You must make sure the -requirements of this License are fulfilled for the Covered Code or any portion -thereof. - -5. Limitations on Patent License. Except as expressly stated in Section -2, no other patent rights, express or implied, are granted by Apple herein. -Modifications and/or Larger Works may require additional patent licenses from -Apple which Apple may grant in its sole discretion. - -6. Additional Terms. You may choose to offer, and to charge a fee for, -warranty, support, indemnity or liability obligations and/or other rights -consistent with the scope of the license granted herein ("Additional Terms") to -one or more recipients of Covered Code. However, You may do so only on Your own -behalf and as Your sole responsibility, and not on behalf of Apple or any -Contributor. You must obtain the recipient's agreement that any such Additional -Terms are offered by You alone, and You hereby agree to indemnify, defend and -hold Apple and every Contributor harmless for any liability incurred by or -claims asserted against Apple or such Contributor by reason of any such -Additional Terms. - -7. Versions of the License. Apple may publish revised and/or new versions -of this License from time to time. Each version will be given a distinguishing -version number. Once Original Code has been published under a particular -version of this License, You may continue to use it under the terms of that -version. You may also choose to use such Original Code under the terms of any -subsequent version of this License published by Apple. No one other than Apple -has the right to modify the terms applicable to Covered Code created under this -License. - -8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in -part pre-release, untested, or not fully tested works. The Covered Code may -contain errors that could cause failures or loss of data, and may be incomplete -or contain inaccuracies. You expressly acknowledge and agree that use of the -Covered Code, or any portion thereof, is at Your sole and entire risk. THE -COVERED CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF -ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" -FOR THE PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM -ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY, OF -SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR PURPOSE, OF ACCURACY, OF -QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE AND EACH -CONTRIBUTOR DOES NOT WARRANT AGAINST INTERFERENCE WITH YOUR ENJOYMENT OF THE -COVERED CODE, THAT THE FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR -REQUIREMENTS, THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR -ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO ORAL OR -WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE AUTHORIZED -REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. You acknowledge -that the Covered Code is not intended for use in the operation of nuclear -facilities, aircraft navigation, communication systems, or air traffic control -machines in which case the failure of the Covered Code could lead to death, -personal injury, or severe physical or environmental damage. - -9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO -EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, SPECIAL, -INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR -YOUR USE OR INABILITY TO USE THE COVERED CODE, OR ANY PORTION THEREOF, WHETHER -UNDER A THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS -LIABILITY OR OTHERWISE, EVEN IF APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF -THE POSSIBILITY OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL -PURPOSE OF ANY REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF -LIABILITY OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT -APPLY TO YOU. In no event shall Apple's total liability to You for all damages -(other than as may be required by applicable law) under this License exceed the -amount of fifty dollars ($50.00). - -10. Trademarks. This License does not grant any rights to use the -trademarks or trade names "Apple", "Mac", "Mac OS", "QuickTime", "QuickTime -Streaming Server" or any other trademarks, service marks, logos or trade names -belonging to Apple (collectively "Apple Marks") or to any trademark, service -mark, logo or trade name belonging to any Contributor. You agree not to use -any Apple Marks in or as part of the name of products derived from the Original -Code or to endorse or promote products derived from the Original Code other -than as expressly permitted by and in strict compliance at all times with -Apple's third party trademark usage guidelines which are posted at -http://www.apple.com/legal/guidelinesfor3rdparties.html. - -11. Ownership. Subject to the licenses granted under this License, each -Contributor retains all rights, title and interest in and to any Modifications -made by such Contributor. Apple retains all rights, title and interest in and -to the Original Code and any Modifications made by or on behalf of Apple -("Apple Modifications"), and such Apple Modifications will not be automatically -subject to this License. Apple may, at its sole discretion, choose to license -such Apple Modifications under this License, or on different terms from those -contained in this License or may choose not to license them at all. - -12. Termination. - -12.1 Termination. This License and the rights granted hereunder will -terminate: - -(a) automatically without notice from Apple if You fail to comply with any -term(s) of this License and fail to cure such breach within 30 days of becoming -aware of such breach; -(b) immediately in the event of the circumstances described in Section -13.5(b); or -(c) automatically without notice from Apple if You, at any time during the -term of this License, commence an action for patent infringement against Apple; -provided that Apple did not first commence an action for patent infringement -against You in that instance. - -12.2 Effect of Termination. Upon termination, You agree to immediately stop -any further use, reproduction, modification, sublicensing and distribution of -the Covered Code. All sublicenses to the Covered Code which have been properly -granted prior to termination shall survive any termination of this License. -Provisions which, by their nature, should remain in effect beyond the -termination of this License shall survive, including but not limited to -Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. No party will be liable to any other -for compensation, indemnity or damages of any sort solely as a result of -terminating this License in accordance with its terms, and termination of this -License will be without prejudice to any other right or remedy of any party. - -13. Miscellaneous. - -13.1 Government End Users. The Covered Code is a "commercial item" as -defined in FAR 2.101. Government software and technical data rights in the -Covered Code include only those rights customarily provided to the public as -defined in this License. This customary commercial license in technical data -and software is provided in accordance with FAR 12.211 (Technical Data) and -12.212 (Computer Software) and, for Department of Defense purchases, DFAR -252.227-7015 (Technical Data -- Commercial Items) and 227.7202-3 (Rights in -Commercial Computer Software or Computer Software Documentation). Accordingly, -all U.S. Government End Users acquire Covered Code with only those rights set -forth herein. - -13.2 Relationship of Parties. This License will not be construed as -creating an agency, partnership, joint venture or any other form of legal -association between or among You, Apple or any Contributor, and You will not -represent to the contrary, whether expressly, by implication, appearance or -otherwise. - -13.3 Independent Development. Nothing in this License will impair Apple's -right to acquire, license, develop, have others develop for it, market and/or -distribute technology or products that perform the same or similar functions -as, or otherwise compete with, Modifications, Larger Works, technology or -products that You may develop, produce, market or distribute. - -13.4 Waiver; Construction. Failure by Apple or any Contributor to enforce -any provision of this License will not be deemed a waiver of future enforcement -of that or any other provision. Any law or regulation which provides that the -language of a contract shall be construed against the drafter will not apply to -this License. - -13.5 Severability. (a) If for any reason a court of competent jurisdiction -finds any provision of this License, or portion thereof, to be unenforceable, -that provision of the License will be enforced to the maximum extent -permissible so as to effect the economic benefits and intent of the parties, -and the remainder of this License will continue in full force and effect. (b) -Notwithstanding the foregoing, if applicable law prohibits or restricts You -from fully and/or specifically complying with Sections 2 and/or 3 or prevents -the enforceability of either of those Sections, this License will immediately -terminate and You must immediately discontinue any use of the Covered Code and -destroy all copies of it that are in your possession or control. - -13.6 Dispute Resolution. Any litigation or other dispute resolution between -You and Apple relating to this License shall take place in the Northern -District of California, and You and Apple hereby consent to the personal -jurisdiction of, and venue in, the state and federal courts within that -District with respect to this License. The application of the United Nations -Convention on Contracts for the International Sale of Goods is expressly -excluded. - -13.7 Entire Agreement; Governing Law. This License constitutes the entire -agreement between the parties with respect to the subject matter hereof. This -License shall be governed by the laws of the United States and the State of -California, except that body of California law concerning conflicts of law. - -Where You are located in the province of Quebec, Canada, the following clause -applies: The parties hereby confirm that they have requested that this License -and all related documents be drafted in English. Les parties ont exigé que le -présent contrat et tous les documents connexes soient rédigés en anglais. - -EXHIBIT A. - -"Portions Copyright (c) 1999-2007 Apple Inc. All Rights Reserved. - -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." - diff --git a/OSX/libsecurity_cms/APPLE_LICENSE b/SecurityTool/macOS/APPLE_LICENSE similarity index 100% rename from OSX/libsecurity_cms/APPLE_LICENSE rename to SecurityTool/macOS/APPLE_LICENSE diff --git a/SecurityTool/access_utils.c b/SecurityTool/macOS/access_utils.c similarity index 100% rename from SecurityTool/access_utils.c rename to SecurityTool/macOS/access_utils.c diff --git a/SecurityTool/access_utils.h b/SecurityTool/macOS/access_utils.h similarity index 100% rename from SecurityTool/access_utils.h rename to SecurityTool/macOS/access_utils.h diff --git a/SecurityTool/authz.c b/SecurityTool/macOS/authz.c similarity index 100% rename from SecurityTool/authz.c rename to SecurityTool/macOS/authz.c diff --git a/SecurityTool/authz.h b/SecurityTool/macOS/authz.h similarity index 100% rename from SecurityTool/authz.h rename to SecurityTool/macOS/authz.h diff --git a/SecurityTool/cmsutil.c b/SecurityTool/macOS/cmsutil.c similarity index 100% rename from SecurityTool/cmsutil.c rename to SecurityTool/macOS/cmsutil.c diff --git a/SecurityTool/cmsutil.h b/SecurityTool/macOS/cmsutil.h similarity index 100% rename from SecurityTool/cmsutil.h rename to SecurityTool/macOS/cmsutil.h diff --git a/SecurityTool/createFVMaster.c b/SecurityTool/macOS/createFVMaster.c similarity index 100% rename from SecurityTool/createFVMaster.c rename to SecurityTool/macOS/createFVMaster.c diff --git a/SecurityTool/createFVMaster.h b/SecurityTool/macOS/createFVMaster.h similarity index 100% rename from SecurityTool/createFVMaster.h rename to SecurityTool/macOS/createFVMaster.h diff --git a/SecurityTool/db_commands.cpp b/SecurityTool/macOS/db_commands.cpp similarity index 100% rename from SecurityTool/db_commands.cpp rename to SecurityTool/macOS/db_commands.cpp diff --git a/SecurityTool/db_commands.h b/SecurityTool/macOS/db_commands.h similarity index 100% rename from SecurityTool/db_commands.h rename to SecurityTool/macOS/db_commands.h diff --git a/SecurityTool/display_error_code.c b/SecurityTool/macOS/display_error_code.c similarity index 100% rename from SecurityTool/display_error_code.c rename to SecurityTool/macOS/display_error_code.c diff --git a/SecurityTool/display_error_code.h b/SecurityTool/macOS/display_error_code.h similarity index 100% rename from SecurityTool/display_error_code.h rename to SecurityTool/macOS/display_error_code.h diff --git a/SecurityTool/identity_find.h b/SecurityTool/macOS/identity_find.h similarity index 100% rename from SecurityTool/identity_find.h rename to SecurityTool/macOS/identity_find.h diff --git a/SecurityTool/identity_find.m b/SecurityTool/macOS/identity_find.m similarity index 95% rename from SecurityTool/identity_find.m rename to SecurityTool/macOS/identity_find.m index 52c20e66..1b3e562f 100644 --- a/SecurityTool/identity_find.m +++ b/SecurityTool/macOS/identity_find.m @@ -1,15 +1,15 @@ /* - * Copyright (c) 2003-2010,2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2010,2012,2014-2019 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@ * * identity_find.c @@ -42,15 +42,17 @@ #include #include #include -#include +#include #include // cssmErrorString #include -// SecCertificateInferLabel, SecDigestGetData +// SecCertificateInferLabel, SecDigestGetData, SecCertificateCopyPublicKeySHA{1,256}Digest #include // SecIdentitySearchCreateWithPolicy #include +// kSecAttrCanSignRecover, kSecAttrCanVerifyRecover +#include static bool checkKeyUsageOperation(CSSM_KEYUSE keyUse, CSSM_KEYUSE keyOp, NSDictionary *keyAttrs, id secKeyOp) { if (keyUse & keyOp) { @@ -62,7 +64,7 @@ static bool checkKeyUsageOperation(CSSM_KEYUSE keyUse, CSSM_KEYUSE keyOp, NSDict static bool checkKeyUsage(CSSM_KEYUSE keyUse, NSDictionary *keyAttrs) { CSSM_KEYUSE keyOps[] = { CSSM_KEYUSE_ENCRYPT, CSSM_KEYUSE_DECRYPT, CSSM_KEYUSE_SIGN, CSSM_KEYUSE_VERIFY, CSSM_KEYUSE_SIGN_RECOVER, CSSM_KEYUSE_VERIFY_RECOVER, CSSM_KEYUSE_WRAP, CSSM_KEYUSE_UNWRAP, CSSM_KEYUSE_DERIVE }; id secKeyOps[] = { (id)kSecAttrCanEncrypt, (id)kSecAttrCanDecrypt, (id)kSecAttrCanSign, (id)kSecAttrCanVerify, (id)kSecAttrCanSignRecover, (id)kSecAttrCanVerifyRecover, (id)kSecAttrCanWrap, (id)kSecAttrCanUnwrap, (id)kSecAttrCanDerive }; - + if (keyUse & CSSM_KEYUSE_ANY) { for (size_t i = 0; i < sizeof(keyOps) / sizeof(CSSM_KEYUSE); ++i) { keyUse |= keyOps[i]; @@ -83,7 +85,7 @@ CopyMatchingIdentity(CFTypeRef keychainOrArray, { id identityRef; // check input hash string and convert to data - NSData *hashData; + NSData *hashData = nil; if (hash) { hashData = (__bridge_transfer NSData *)CFDataCreateFromHexString(kCFAllocatorDefault, (__bridge CFStringRef)[NSString stringWithUTF8String:hash]); } @@ -113,7 +115,7 @@ CopyMatchingIdentity(CFTypeRef keychainOrArray, if (SecItemCopyMatching((CFDictionaryRef)query, (void *)&identities) != errSecSuccess) { return NULL; } - + for (id candidate in identities) { id cert; if (SecIdentityCopyCertificate((__bridge SecIdentityRef)candidate, (void *)&cert) != errSecSuccess) @@ -128,11 +130,19 @@ CopyMatchingIdentity(CFTypeRef keychainOrArray, } } if (hashData) { - NSData *certDataHash = (__bridge NSData *)SecCertificateGetSHA1Digest((__bridge SecCertificateRef)cert); - if ([hashData isEqual:certDataHash]) { - identityRef = candidate; - break; - } + NSData *certDataHash = nil; + NSUInteger hashLength = [hashData length]; + if (hashLength == CC_SHA256_DIGEST_LENGTH) { + certDataHash = (__bridge NSData *)SecCertificateCopySHA256Digest((__bridge SecCertificateRef)cert); + } else if (hashLength == CC_SHA1_DIGEST_LENGTH) { + certDataHash = (__bridge NSData *)SecCertificateGetSHA1Digest((__bridge SecCertificateRef)cert); + } + BOOL matched = [hashData isEqual:certDataHash]; + certDataHash = nil; // ARC releases the hash + if (matched) { + identityRef = candidate; + break; + } } else { // copy certificate name NSString *commonName; diff --git a/SecurityTool/identity_prefs.c b/SecurityTool/macOS/identity_prefs.c similarity index 89% rename from SecurityTool/identity_prefs.c rename to SecurityTool/macOS/identity_prefs.c index c0e21840..153aa488 100644 --- a/SecurityTool/identity_prefs.c +++ b/SecurityTool/macOS/identity_prefs.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2003-2010,2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2010,2012,2014-2019 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@ * * identity_prefs.c @@ -37,11 +37,11 @@ #include #include #include +#include // SecCertificateInferLabel, SecDigestGetData #include - static int do_set_identity_preference(CFTypeRef keychainOrArray, const char *identity, @@ -138,17 +138,21 @@ do_get_identity_preference(const char *service, } if (printHash) { - uint8 sha1_hash[20]; - CSSM_DATA digest; - digest.Length = sizeof(sha1_hash); - digest.Data = sha1_hash; - if (SecDigestGetData(CSSM_ALGID_SHA1, &digest, &certData) == CSSM_OK) { - unsigned int i; - size_t len = digest.Length; - uint8 *cp = digest.Data; + uint8_t digest[CC_SHA256_DIGEST_LENGTH]; + unsigned int i; + if (certData.Data != NULL && certData.Length > 0) { + // print SHA-256 hash value + CC_SHA256(certData.Data, (CC_LONG)certData.Length, digest); + fprintf(stdout, "SHA-256 hash: "); + for (i=0; i #include #include +#include #include #include #include - // SecDigestGetData, SecKeychainSearchCreateForCertificateByEmail, SecCertificateFindByEmail #include @@ -287,7 +287,7 @@ cleanup: // Returns a SecKeychainItemRef for the certificate // in the specified keychain (or keychain list) // which is a unique match for either the specified name -// or SHA-1 hash. If more than one match exists, the +// or SHA-1/SHA-2 hash. If more than one match exists, the // certificate is not unique and none are returned. Caller is // responsible for releasing the item (with CFRelease). // @@ -306,36 +306,41 @@ find_unique_certificate(CFTypeRef keychainOrArray, } // check input hash string and convert to data - CSSM_DATA hashData = { 0, NULL }; + CFDataRef hashData = NULL; + CFIndex hashLength = 0; if (hash) { - CSSM_SIZE len = strlen(hash)/2; - hashData.Length = len; - hashData.Data = (uint8 *)malloc(hashData.Length); - fromHex(hash, &hashData); + CSSM_DATA hashCssmData = { 0, NULL }; + hashCssmData.Length = (CSSM_SIZE)strlen(hash)/2; + hashCssmData.Data = (uint8 *)malloc(hashCssmData.Length); + fromHex(hash, &hashCssmData); + hashLength = (CFIndex)hashCssmData.Length; + hashData = CFDataCreate(kCFAllocatorDefault, (const UInt8 *)hashCssmData.Data, hashLength); + free(hashCssmData.Data); } // filter candidates against the hash (or the name, if no hash provided) CFStringRef matchRef = (name) ? CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8) : NULL; Boolean exactMatch = FALSE; - - CSSM_DATA certData = { 0, NULL }; SecKeychainItemRef candidate = NULL; while (SecKeychainSearchCopyNext(searchRef, &candidate) == noErr) { SecCertificateRef cert = (SecCertificateRef)candidate; - if (SecCertificateGetData(cert, &certData) != noErr) { - safe_CFRelease(&candidate); - continue; - } - if (hash) { - uint8 candidate_sha1_hash[20]; - CSSM_DATA digest; - digest.Length = sizeof(candidate_sha1_hash); - digest.Data = candidate_sha1_hash; - if ((SecDigestGetData(CSSM_ALGID_SHA1, &digest, &certData) == CSSM_OK) && - (hashData.Length == digest.Length) && - (!memcmp(hashData.Data, digest.Data, digest.Length))) { + if (hashData) { + CFDataRef certHash = NULL; + if (hashLength == CC_SHA1_DIGEST_LENGTH) { + certHash = SecCertificateGetSHA1Digest(cert); + if (certHash) { CFRetain(certHash); } + } else if (hashLength == CC_SHA256_DIGEST_LENGTH) { + certHash = SecCertificateCopySHA256Digest(cert); + } + if (!certHash) { + safe_CFRelease(&candidate); + continue; // no hash, so no match is possible + } else if (CFEqual(certHash, hashData)) { exactMatch = TRUE; + } + safe_CFRelease(&certHash); + if (exactMatch) { uniqueItemRef = candidate; // currently retained break; // we're done - can't get more exact than this } @@ -395,15 +400,13 @@ find_unique_certificate(CFTypeRef keychainOrArray, safe_CFRelease(&searchRef); safe_CFRelease(&matchRef); - if (hashData.Data) { - free(hashData.Data); - } + safe_CFRelease(&hashData); return uniqueItemRef; } static OSStatus -do_password_item_printing( SecKeychainItemRef itemRef, +do_password_item_printing(SecKeychainItemRef itemRef, Boolean get_password, Boolean password_stdout) { @@ -423,7 +426,7 @@ do_password_item_printing( SecKeychainItemRef itemRef, fputc('\n', stderr); } } else { - char *password = (char *) passwordData; + uint8_t *password = (uint8_t *) passwordData; int doHex = 0; for(uint32_t i=0; i #include +#include #include "security_tool.h" #include "trusted_cert_utils.h" #include "requirement.h" -#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) { CFRelease(_cf); } } - int requirement_evaluate(int argc, char * const *argv) { int err = 0; diff --git a/SecurityTool/requirement.h b/SecurityTool/macOS/requirement.h similarity index 100% rename from SecurityTool/requirement.h rename to SecurityTool/macOS/requirement.h diff --git a/SecurityTool/security.1 b/SecurityTool/macOS/security.1 similarity index 97% rename from SecurityTool/security.1 rename to SecurityTool/macOS/security.1 index bf391cd9..b810df56 100644 --- a/SecurityTool/security.1 +++ b/SecurityTool/macOS/security.1 @@ -463,6 +463,8 @@ Specify an application which may access this item (multiple \& options are allowed) .It Fl U Update item if it already exists (if omitted, the item cannot already exist) +.It Fl X Ar password +Specify password data to be added as a hexadecimal string .El .It .Bl -item @@ -517,6 +519,8 @@ Specify an application which may access this item (multiple \& options are allowed) .It Fl U Update item if it already exists (if omitted, the item cannot already exist) +.It Fl X Ar password +Specify password data to be added as a hexadecimal string .El .It .Bl -item @@ -869,7 +873,7 @@ Show the email addresses in the certificate .It Fl p Output certificate in pem format. Default is to dump the attributes and keychain the cert is in. .It Fl Z -Print SHA-1 hash of the certificate +Print SHA-256 (and SHA-1) hash of the certificate .El .It .Sy Examples @@ -879,8 +883,8 @@ Exports all certificates from all keychains into a pem file called allcerts.pem. .It security> find-certificate -a -e me@foo.com -p > certs.pem Exports all certificates from all keychains with the email address me@foo.com into a pem file called certs.pem. -.It security> find-certificate -a -c MyName -Z login.keychain | grep ^SHA-1 -Print the SHA-1 hash of every certificate in 'login.keychain' whose common name includes 'MyName' +.It security> find-certificate -a -c MyName -Z login.keychain | grep ^SHA-256 +Print the SHA-256 hash of every certificate in 'login.keychain' whose common name includes 'MyName' .El .El .It @@ -939,13 +943,13 @@ Delete a certificate from a keychain. If no .It Fl c Ar name Specify certificate to delete by its common name .It Fl Z Ar hash -Specify certificate to delete by its SHA-1 hash +Specify certificate to delete by its SHA-256 (or SHA-1) hash .It Fl t Also delete user trust settings for this certificate .El .It The certificate to be deleted must be uniquely specified either by a -string found in its common name, or by its SHA-1 hash. +string found in its common name, or by its SHA-256 (or SHA-1) hash. .El .It .Nm delete-identity @@ -963,13 +967,13 @@ Delete a certificate and its private key from a keychain. If no .It Fl c Ar name Specify certificate to delete by its common name .It Fl Z Ar hash -Specify certificate to delete by its SHA-1 hash +Specify certificate to delete by its SHA-256 (or SHA-1) hash .It Fl t Also delete user trust settings for this identity certificate .El .It The identity to be deleted must be uniquely specified either by a -string found in its common name, or by its SHA-1 hash. +string found in its common name, or by its SHA-256 (or SHA-1) hash. .El .It .Nm set-identity-preference @@ -993,13 +997,13 @@ Specify service (may be a URL, RFC822 email address, DNS host, or other name) fo .It Fl u Ar keyUsage Specify key usage (optional) .It Fl Z Ar hash -Specify identity by SHA-1 hash of certificate (optional) +Specify identity by SHA-256 (or SHA-1) hash of certificate (optional) .El .It The identity is located by searching the specified keychain(s) for a certificate whose common name contains the given identity string. If no keychains are specified to search, the default search list is used. Different identity preferences can be set for individual key usages. You can differentiate between two identities which contain -the same string by providing a SHA-1 hash of the certificate (in addition to, or instead of, the name.) +the same string by providing a SHA-256 (or SHA-1) hash of the certificate in addition to, or instead of, the name. .It .Sy PARTIAL PATHS AND WILDCARDS .It @@ -1055,7 +1059,7 @@ Output identity certificate in pem format .It Fl c Print common name of the preferred identity certificate .It Fl Z -Print SHA-1 hash of the preferred identity certificate +Print SHA-256 (and SHA-1) hash of the preferred identity certificate .El .El .It @@ -1274,7 +1278,7 @@ Cert usage codes: .It .Nm install-mds .Bl -item -offset -indent -Install (or re-install) the Module Directory Services (MDS) database. This is a system tool which is not normally used by users. There are no options. +Install (or re-install) the Module Directory Services (MDS) database. This is a system tool which is not normally used by users. There are no options. .El .It .Nm add-trusted-cert @@ -1292,18 +1296,16 @@ certFile .Bl -item -offset -indent Add certificate (in DER or PEM format) from .Ar certFile Ns -\& to per-user or local Admin Trust Settings. When modifying per-user Trust Settings, user authentication is required via an authentication dialog. When modifying admin Trust Settings, the process must be running as root, or admin authentication is required. +\& to per-user or local Admin Trust Settings. When modifying per-user Trust Settings, user authentication is required via an authentication dialog. When modifying admin Trust Settings, the process must be running as root, or admin authentication is required. .It Options: .Bl -tag -compact -width -indent-indent .It Fl d -Add to admin cert store; default is user. +Add to admin cert store; default is user. .It Fl r Ar resultType resultType = trustRoot|trustAsRoot|deny|unspecified; default is trustRoot. .It Fl p Ar policy Specify policy constraint (ssl, smime, codeSign, IPSec, basic, swUpdate, pkgSign, eap, macappstore, appleID, timestamping). -.It Fl r Ar resultType -resultType = trustRoot|trustAsRoot|deny|unspecified; default is trustRoot. .It Fl a Ar appPath Specify application constraint. .It Fl s Ar policyString @@ -1431,15 +1433,19 @@ Import admin Trust Settings; default is user. .Op Fl s Ar sslHost .Op Fl q .Op Fl R Ar revCheckOption +.Op Fl P +.Op Fl t +.Op Fl v +.Op Ar url .Bl -item -offset -indent -Verify one or more certificates. +Verify one or more certificates. If a direct URL argument is provided, a TLS connection is attempted and the certificate presented by that server is evaluated according to standard SSL server policy; other certificates or policy options will be ignored in this case. .It Options: .Bl -tag -compact -width -indent-indent .It Fl c Ar certFile Certificate to verify, in DER or PEM format. Can be specified more than once; leaf certificate has to be specified first. .It Fl r Ar rootCertFile -Root certificate, in DER or PEM format. Can be specified more than once. If not specified, the system anchor certificates are used. If one root certificate is specified, and zero (non-root) certificates are specified, the root certificate is verified against itself. +Root certificate, in DER or PEM format. Can be specified more than once. If not specified, the system anchor certificates are used. If one root certificate is specified, and zero (non-root) certificates are specified, the root certificate is verified against itself. .It Fl p Ar policy Specify verification policy (ssl, smime, codeSign, IPSec, basic, swUpdate, pkgSign, eap, appleID, macappstore, timestamping). Default is basic. .It Fl C @@ -1464,12 +1470,19 @@ Specify SSL host name for the ssl policy. (This option is deprecated; use -n ins Quiet, no stdout or stderr. .It Fl R Ar revCheckOption Specify a revocation checking option for this evaluation (ocsp, crl, require, offline). Can be specified multiple times; e.g. to enable revocation checking via either OCSP or CRL methods and require a positive response, use "-R ocsp -R crl -R require". The offline option will consult previously cached responses, but will not make a request to a revocation server. +.It Fl P +Output the constructed certificate chain in PEM format. +.It Fl t +Output certificate contents as text. +.It Fl v +Specify verbose output, including per-certificate trust results. .El .It .Sy Examples .Bl -tag -width -indent .It security> verify-cert -c applestore0.cer -c applestore1.cer -p ssl -n store.apple.com .It security> verify-cert -r serverbasic.crt +.It security> verify-cert -v https://www.apple.com .El .\"marker. .El diff --git a/SecurityTool/security.c b/SecurityTool/macOS/security.c similarity index 96% rename from SecurityTool/security.c rename to SecurityTool/macOS/security.c index 798d2e65..6aba03ed 100644 --- a/SecurityTool/security.c +++ b/SecurityTool/macOS/security.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -225,6 +225,7 @@ const command commands[] = " -s Specify service name (required)\n" " -p Specify password to be added (legacy option, equivalent to -w)\n" " -w Specify password to be added\n" + " -X Specify password data to be added as a hexadecimal string\n" " -A Allow any application to access this item without warning (insecure, not recommended!)\n" " -T Specify an application which may access this item (multiple -T options are allowed)\n" " -U Update item if it already exists (if omitted, the item cannot already exist)\n" @@ -232,7 +233,7 @@ const command commands[] = "By default, the application which creates an item is trusted to access its data without warning.\n" "You can remove this default access by explicitly specifying an empty app pathname: -T \"\"\n" "If no keychain is specified, the password is added to the default keychain.\n" - "Use of the -p or -w options is insecure. Specify -w as the last option to be prompted.\n", + "Use of the -p or -w options is insecure. Specify -w as the last option to be prompted.\n", "Add a generic password item."}, { "add-internet-password", keychain_add_internet_password, @@ -249,7 +250,8 @@ const command commands[] = " -r Specify protocol (optional four-character SecProtocolType, e.g. \"http\", \"ftp \")\n" " -s Specify server name (required)\n" " -t Specify authentication type (as a four-character SecAuthenticationType, default is \"dflt\")\n" - " -w Specify password to be added\n" + " -w Specify password to be added\n" + " -X Specify password data to be added as a hexadecimal string\n" " -A Allow any application to access this item without warning (insecure, not recommended!)\n" " -T Specify an application which may access this item (multiple -T options are allowed)\n" " -U Update item if it already exists (if omitted, the item cannot already exist)\n" @@ -257,7 +259,7 @@ const command commands[] = "By default, the application which creates an item is trusted to access its data without warning.\n" "You can remove this default access by explicitly specifying an empty app pathname: -T \"\"\n" "If no keychain is specified, the password is added to the default keychain.\n" - "Use of the -p or -w options is insecure. Specify -w as the last option to be prompted.\n", + "Use of the -p or -w options is insecure. Specify -w as the last option to be prompted.\n", "Add an internet password item."}, { "add-certificates", keychain_add_certificates, @@ -413,7 +415,7 @@ const command commands[] = " -e Match on \"emailAddress\" when searching (optional)\n" " -m Show the email addresses in the certificate\n" " -p Output certificate in pem format\n" - " -Z Print SHA-1 hash of the certificate\n" + " -Z Print SHA-256 (and SHA-1) hash of the certificate\n" "If no keychains are specified to search, the default search list is used.", "Find a certificate item."}, @@ -431,20 +433,20 @@ const command commands[] = { "delete-certificate", keychain_delete_certificate, "[-c name] [-Z hash] [-t] [keychain...]\n" " -c Specify certificate to delete by its common name\n" - " -Z Specify certificate to delete by its SHA-1 hash value\n" + " -Z Specify certificate to delete by its SHA-256 (or SHA-1) hash value\n" " -t Also delete user trust settings for this certificate\n" "The certificate to be deleted must be uniquely specified either by a\n" - "string found in its common name, or by its SHA-1 hash.\n" + "string found in its common name, or by its SHA-256 (or SHA-1) hash.\n" "If no keychains are specified to search, the default search list is used.", "Delete a certificate from a keychain."}, { "delete-identity", keychain_delete_identity, "[-c name] [-Z hash] [-t] [keychain...]\n" " -c Specify certificate to delete by its common name\n" - " -Z Specify certificate to delete by its SHA-1 hash value\n" + " -Z Specify certificate to delete by its SHA-256 (or SHA-1) hash value\n" " -t Also delete user trust settings for this identity certificate\n" "The identity to be deleted must be uniquely specified either by a\n" - "string found in its common name, or by its SHA-1 hash.\n" + "string found in its common name, or by its SHA-256 (or SHA-1) hash.\n" "If no keychains are specified to search, the default search list is used.", "Delete an identity (certificate + private key) from a keychain."}, @@ -455,7 +457,7 @@ const command commands[] = " -s Specify service (may be a URL, RFC822 email address, DNS host, or\n" " other name) for which this identity is to be preferred\n" " -u Specify key usage (optional) - see man page for values\n" - " -Z Specify identity by SHA-1 hash of certificate (optional)\n", + " -Z Specify identity by SHA-256 (or SHA-1) hash of certificate (optional)\n", "Set the preferred identity to use for a service."}, { "get-identity-preference", get_identity_preference, @@ -465,7 +467,7 @@ const command commands[] = " -u Specify key usage (optional) - see man page for values\n" " -p Output identity certificate in pem format\n" " -c Print common name of the preferred identity certificate\n" - " -Z Print SHA-1 hash of the preferred identity certificate\n", + " -Z Print SHA-256 (and SHA-1) hash of the preferred identity certificate\n", "Get the preferred identity to use for a service."}, { "create-db", db_create, @@ -616,7 +618,7 @@ const command commands[] = "Import trust settings." }, { "verify-cert" , verify_cert, - " []\n" + "[] []\n" " -c certFile Certificate to verify. Can be specified multiple times, leaf first.\n" " -r rootCertFile Root Certificate. Can be specified multiple times.\n" " -p policy Verify Policy (basic, ssl, smime, codeSign, IPSec, swUpdate, pkgSign,\n" @@ -641,7 +643,12 @@ const command commands[] = " offline Consult cached responses only (no network requests).\n" " Can be specified multiple times; e.g. to enable revocation checking\n" " via either OCSP or CRL methods and require a positive response, use\n" - " \"-R ocsp -R crl -R require\".\n", + " \"-R ocsp -R crl -R require\".\n" + " -P Output the constructed certificate chain in PEM format.\n" + " -t Output certificate contents as text.\n" + " -v Specify verbose output, including per-certificate trust results.\n" + "Note: if a direct URL argument is provided, standard SSL server evaluation policy is used\n" + "and other certificates or policy options will be ignored.\n", "Verify certificate(s)." }, { "authorize" , authorize, diff --git a/SecurityTool/security_tool.h b/SecurityTool/macOS/security_tool.h similarity index 100% rename from SecurityTool/security_tool.h rename to SecurityTool/macOS/security_tool.h diff --git a/SecurityTool/smartcards.h b/SecurityTool/macOS/smartcards.h similarity index 100% rename from SecurityTool/smartcards.h rename to SecurityTool/macOS/smartcards.h diff --git a/SecurityTool/smartcards.m b/SecurityTool/macOS/smartcards.m similarity index 100% rename from SecurityTool/smartcards.m rename to SecurityTool/macOS/smartcards.m diff --git a/SecurityTool/srCdsaUtils.cpp b/SecurityTool/macOS/srCdsaUtils.cpp similarity index 100% rename from SecurityTool/srCdsaUtils.cpp rename to SecurityTool/macOS/srCdsaUtils.cpp diff --git a/SecurityTool/srCdsaUtils.h b/SecurityTool/macOS/srCdsaUtils.h similarity index 100% rename from SecurityTool/srCdsaUtils.h rename to SecurityTool/macOS/srCdsaUtils.h diff --git a/SecurityTool/translocate.c b/SecurityTool/macOS/translocate.c similarity index 100% rename from SecurityTool/translocate.c rename to SecurityTool/macOS/translocate.c diff --git a/SecurityTool/translocate.h b/SecurityTool/macOS/translocate.h similarity index 100% rename from SecurityTool/translocate.h rename to SecurityTool/macOS/translocate.h diff --git a/SecurityTool/trust_settings_impexp.c b/SecurityTool/macOS/trust_settings_impexp.c similarity index 100% rename from SecurityTool/trust_settings_impexp.c rename to SecurityTool/macOS/trust_settings_impexp.c diff --git a/SecurityTool/trust_settings_impexp.h b/SecurityTool/macOS/trust_settings_impexp.h similarity index 100% rename from SecurityTool/trust_settings_impexp.h rename to SecurityTool/macOS/trust_settings_impexp.h diff --git a/SecurityTool/trusted_cert_add.c b/SecurityTool/macOS/trusted_cert_add.c similarity index 92% rename from SecurityTool/trusted_cert_add.c rename to SecurityTool/macOS/trusted_cert_add.c index c2b1d12b..fb74c9ed 100644 --- a/SecurityTool/trusted_cert_add.c +++ b/SecurityTool/macOS/trusted_cert_add.c @@ -1,15 +1,15 @@ /* - * Copyright (c) 2006-2010,2012,2014 Apple Inc. All Rights Reserved. + * Copyright (c) 2006-2010,2012,2014-2019 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@ * * trust_cert_add.c @@ -84,6 +84,11 @@ #include #include + +#define MAX_POLICIES 16 /* upper limit on policies that can be set in one invocation */ +#define MAX_STRINGS 128 /* upper limit on per-policy strings */ +#define MAX_ERRORS 128 /* upper limit on per-policy allowed errors */ + /* r/w files as CFData */ static CFDataRef CF_RETURNS_RETAINED readFileData( const char *fileName) @@ -133,7 +138,8 @@ static int appendConstraintsToDict( /* OID string to an OID pointer */ const CSSM_OID *oid = NULL; if(policy != NULL) { - oid = policyStringToOid(policy); + bool tls = false; + oid = policyStringToOid(policy, &tls); if(oid == NULL) { return SHOW_USAGE_MESSAGE; } @@ -193,6 +199,9 @@ static int appendConstraintsToDict( int trusted_cert_add(int argc, char * const *argv) { + if (argc < 2) { + return SHOW_USAGE_MESSAGE; + } extern char *optarg; extern int optind; OSStatus ortn; @@ -219,14 +228,14 @@ trusted_cert_add(int argc, char * const *argv) CFMutableArrayRef trustSettings = NULL; int haveConstraints = 0; - const int maxPolicies = 16; // upper limit on policies that can be set in one invocation - char *policyNames[maxPolicies]; - char *policyStrings[maxPolicies]; - int allowedErrors[maxPolicies]; + char **policyNames = (char **)malloc(MAX_POLICIES * sizeof(char *)); + char **policyStrings = (char **)malloc(MAX_STRINGS * sizeof(char *)); + int *allowedErrors = (int *)malloc(MAX_ERRORS * sizeof(int)); int policyNameCount = 0, policyStringCount = 0, allowedErrorCount = 0; - - if(argc < 2) { - return SHOW_USAGE_MESSAGE; + if (!policyNames || !policyStrings || !allowedErrors) { + fprintf(stderr, "Not enough memory for operation.\n"); + ourRtn = 2; + goto errOut; } optind = 1; @@ -249,16 +258,18 @@ trusted_cert_add(int argc, char * const *argv) resultType = kSecTrustSettingsResultUnspecified; } else { - return SHOW_USAGE_MESSAGE; + ourRtn = SHOW_USAGE_MESSAGE; + goto errOut; } haveConstraints = 1; break; case 'p': - if (policyNameCount < maxPolicies) { + if (policyNameCount < MAX_POLICIES) { policyNames[policyNameCount++] = optarg; } else { fprintf(stderr, "Too many policy arguments.\n"); - return SHOW_USAGE_MESSAGE; + ourRtn = SHOW_USAGE_MESSAGE; + goto errOut; } haveConstraints = 1; break; @@ -267,16 +278,17 @@ trusted_cert_add(int argc, char * const *argv) haveConstraints = 1; break; case 's': - if (policyStringCount < maxPolicies) { + if (policyStringCount < MAX_STRINGS) { policyStrings[policyStringCount++] = optarg; } else { fprintf(stderr, "Too many policy string arguments.\n"); - return SHOW_USAGE_MESSAGE; + ourRtn = SHOW_USAGE_MESSAGE; + goto errOut; } haveConstraints = 1; break; case 'e': - if (allowedErrorCount < maxPolicies) { + if (allowedErrorCount < MAX_ERRORS) { if (!strcmp("certExpired", optarg)) allowErr = -2147409654; // 0x8001210A = CSSMERR_TP_CERT_EXPIRED else if (!strcmp("hostnameMismatch", optarg)) @@ -285,12 +297,14 @@ trusted_cert_add(int argc, char * const *argv) allowErr = (CSSM_RETURN)atoi(optarg); if (!allowErr) { fprintf(stderr, "Invalid value for allowed error.\n"); - return SHOW_USAGE_MESSAGE; + ourRtn = SHOW_USAGE_MESSAGE; + goto errOut; } allowedErrors[allowedErrorCount++] = allowErr; } else { fprintf(stderr, "Too many \"allowed error\" arguments.\n"); - return SHOW_USAGE_MESSAGE; + ourRtn = SHOW_USAGE_MESSAGE; + goto errOut; } haveConstraints = 1; break; @@ -301,7 +315,8 @@ trusted_cert_add(int argc, char * const *argv) case 'k': kcRef = keychain_open(optarg); if(kcRef == NULL) { - return 1; + ourRtn = 1; + goto errOut; } break; case 'i': @@ -312,7 +327,8 @@ trusted_cert_add(int argc, char * const *argv) break; default: case 'h': - return SHOW_USAGE_MESSAGE; + ourRtn = SHOW_USAGE_MESSAGE; + goto errOut; } } if(ourRtn) { @@ -527,6 +543,9 @@ errOut: CFRELEASE(kcRef); CFRELEASE(settingsIn); CFRELEASE(settingsOut); + free(policyNames); + free(policyStrings); + free(allowedErrors); return ourRtn; } diff --git a/SecurityTool/trusted_cert_add.h b/SecurityTool/macOS/trusted_cert_add.h similarity index 100% rename from SecurityTool/trusted_cert_add.h rename to SecurityTool/macOS/trusted_cert_add.h diff --git a/SecurityTool/trusted_cert_dump.c b/SecurityTool/macOS/trusted_cert_dump.c similarity index 94% rename from SecurityTool/trusted_cert_dump.c rename to SecurityTool/macOS/trusted_cert_dump.c index bee4303d..4123ede6 100644 --- a/SecurityTool/trusted_cert_dump.c +++ b/SecurityTool/macOS/trusted_cert_dump.c @@ -37,27 +37,6 @@ #include #include -// SecCertificateInferLabel -#include - - -/* print cert's label (the one SecCertificate infers) */ -static OSStatus printCertLabel( - SecCertificateRef certRef) -{ - OSStatus ortn; - CFStringRef label; - - ortn = SecCertificateInferLabel(certRef, &label); - if(ortn) { - cssmPerror("SecCertificateInferLabel", ortn); - return ortn; - } - printCfStr(label); - CFRelease(label); - return noErr; -} - /* * Display a Trust Settings array as obtained from * SecTrustSettingsCopyTrustSettings(). diff --git a/SecurityTool/trusted_cert_dump.h b/SecurityTool/macOS/trusted_cert_dump.h similarity index 100% rename from SecurityTool/trusted_cert_dump.h rename to SecurityTool/macOS/trusted_cert_dump.h diff --git a/OSX/sec/securityd/AsymKeybagBackup.h b/SecurityTool/macOS/trusted_cert_ssl.h similarity index 60% rename from OSX/sec/securityd/AsymKeybagBackup.h rename to SecurityTool/macOS/trusted_cert_ssl.h index 1ae8c5fc..ba0fb541 100644 --- a/OSX/sec/securityd/AsymKeybagBackup.h +++ b/SecurityTool/macOS/trusted_cert_ssl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -19,27 +19,31 @@ * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ + * + * trusted_cert_ssl.h */ -/*! - @header SecBackupServer - The functions provided in SecBackupServer provide an interface to - the backend for SecBackup SPIs in the server. - */ - -#ifndef SecBackupServer_h -#define SecBackupServer_h +#ifndef _TRUSTED_CERT_SSL_H_ +#define _TRUSTED_CERT_SSL_H_ 1 #include -#include -#include -#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void printErrorDetails(SecTrustRef trust); +void printExtendedResults(SecTrustRef trust); + +int evaluate_ssl(const char *urlstr, int verbose, SecTrustRef * CF_RETURNS_RETAINED trustRef); -__BEGIN_DECLS +CF_RETURNS_RETAINED CFStringRef CopyCertificateTextRepresentation(SecCertificateRef certificate); -bool _SecServerBackupKeybagAdd(SecurityClient *client, CFDataRef passcode, CFDataRef *identifier, CFDataRef *pathinfo, CFErrorRef *error); -bool _SecServerBackupKeybagDelete(CFDictionaryRef attributes, bool deleteAll, CFErrorRef *error); +#ifdef __cplusplus +} +#endif -__END_DECLS +#endif /* _TRUSTED_CERT_SSL_H_ */ -#endif /* SecBackupServer_h */ diff --git a/SecurityTool/macOS/trusted_cert_ssl.m b/SecurityTool/macOS/trusted_cert_ssl.m new file mode 100644 index 00000000..1b88b964 --- /dev/null +++ b/SecurityTool/macOS/trusted_cert_ssl.m @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2019 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@ + * + * verify_ssl.m + */ + + +#import "trusted_cert_ssl.h" +#include +#include + +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#include +#include +#include + +#if TARGET_OS_MAC +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +typedef CFTypeRef CFURLResponseRef; +CFDictionaryRef _CFURLResponseGetSSLCertificateContext(CFURLResponseRef); + +@interface NSURLResponse (URLResponseInternals) +- (CFURLResponseRef)_CFURLResponse; +@end + +@interface NSHTTPURLResponse (HTTPURLResponseInternals) +- (NSArray *)_peerCertificateChain; +@end + +@interface NSURLResponse (CertificateUtilities) +- (SecTrustRef)peerTrust; +- (NSArray *)peerCertificates; +@end + +@interface CertDownloader : NSObject +{ + @private + NSURL *_url; + NSURLRequest *_urlReq; + NSURLResponse *_urlRsp; + NSURLDownload *_urlDL; + SecTrustRef _trust; + BOOL _finished; +} + +- (id)initWithURLString:(const char *)urlstr; +- (void)dealloc; +- (BOOL)finished; +- (void)waitForDownloadToFinish; + +- (SecTrustRef)trustReference; + +- (void)downloadDidFinish:(NSURLDownload *)download; +- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error; + ++ (BOOL)isNetworkURL:(const char *)urlstr; + +@end + +static int _verbose = 0; + +#define ANSI_RED "\x1b[31m" +#define ANSI_GREEN "\x1b[32m" +#define ANSI_YELLOW "\x1b[33m" +#define ANSI_BLUE "\x1b[34m" +#define ANSI_MAGENTA "\x1b[35m" +#define ANSI_CYAN "\x1b[36m" +#define ANSI_RESET "\x1b[0m" + + +@implementation CertDownloader + +- (id)initWithURLString:(const char *)urlstr +{ + _finished = NO; + _url = [[NSURL alloc] initWithString:[NSString stringWithFormat:@"%s", urlstr]]; + _urlReq = [[NSURLRequest alloc] initWithURL:_url]; + _urlRsp = nil; + _trust = NULL; + + _urlDL = [[NSURLDownload alloc] initWithRequest:_urlReq delegate:self]; + + fprintf(stdout, "Opening connection to %s\n", urlstr); + fflush(stdout); + + return self; +} + +- (void)dealloc +{ + _urlDL = nil; + _urlReq = nil; + _urlRsp = nil; + _url = nil; + _trust = NULL; +} + +- (BOOL)finished +{ + return _finished; +} + +- (void)waitForDownloadToFinish +{ + // cycle the run loop while we're waiting for the _finished flag to be set + NSDate *cycleTime; + while (_finished == NO) { + cycleTime = [NSDate dateWithTimeIntervalSinceNow:0.1]; + [[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:cycleTime]; + } +} + +// NSURLDownloadDelegate delegate methods + +- (void)downloadDidFinish:(NSURLDownload *)download +{ + if (!_urlRsp) { + fprintf(stdout, "No response received from %s\n", [[_url absoluteString] UTF8String]); + fflush(stdout); + } + _finished = YES; +} + +- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response +{ + fprintf(stdout, "Received response from %s\n", [[_url absoluteString] UTF8String]); + fflush(stdout); + _urlRsp = response; +} + +- (void)download:(NSURLDownload *)download didFailWithError:(NSError *)error +{ + fprintf(stdout, "Failed connection to %s", [[_url absoluteString] UTF8String]); + if (!_verbose) { + fprintf(stdout, " (use -v option to see more information)"); + } + fprintf(stdout, "\n"); + fflush(stdout); + SecTrustRef tmp = _trust; + _trust = (SecTrustRef)CFBridgingRetain([[error userInfo] objectForKey:@"NSURLErrorFailingURLPeerTrustErrorKey"]); + if (tmp) { CFRelease(tmp); } + _finished = YES; + + if (_verbose) { + // dump the userInfo dictionary + NSLog(@"%@", [error userInfo]); + } +} + +- (SecTrustRef)trustReference +{ + // First, see if we already retained the SecTrustRef, e.g. during a failed connection. + SecTrustRef trust = _trust; + if (!trust) { + // If not, try to obtain the SecTrustRef from the response. + trust = [_urlRsp peerTrust]; + if (trust) { + if (_verbose > 1) { + fprintf(stdout, "Obtained SecTrustRef from the response\n"); + } + CFRetain(trust); + _trust = trust; + } + } + if (!trust) { + // We don't have a SecTrustRef, so build one ourselves for this host. + NSString *host = [_url host]; + if (_verbose > 1) { + fprintf(stdout, "Building our own SecTrustRef for \"%s\"\n", host ? [host UTF8String] : ""); + } + SecPolicyRef sslPolicy = SecPolicyCreateSSL(false, (__bridge CFStringRef)host); + SecPolicyRef revPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod); + NSArray *policies = [NSArray arrayWithObjects:(__bridge id)sslPolicy, (__bridge id)revPolicy, nil]; + NSArray *certs = [_urlRsp peerCertificates]; + if (certs) { + (void)SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, (__bridge CFArrayRef)policies, &trust); + _trust = trust; + } + } + + // Ensure that the trust has been evaluated + SecTrustResultType result = kSecTrustResultInvalid; + OSStatus status = SecTrustGetTrustResult(trust, &result); + bool needsEvaluation = (status != errSecSuccess || result == kSecTrustResultInvalid); + if (needsEvaluation) { + status = SecTrustEvaluate(trust, &result); + if (_verbose > 1) { + fprintf(stdout, "%s trust reference (status = %d, trust result = %d)\n", + (needsEvaluation) ? "Evaluated" : "Checked", + (int)status, (int)result); + } + } + return trust; +} + ++ (BOOL)isNetworkURL:(const char *)urlstr +{ + if (urlstr) { + NSArray *schemes = @[@"https",@"ldaps"]; + NSURL *url = [NSURL URLWithString:[NSString stringWithUTF8String:urlstr]]; + if (url && [schemes containsObject:[url scheme]]) { + return YES; + } + } + return NO; +} + +@end + +@implementation NSURLResponse (CertificateUtilities) + +- (SecTrustRef)peerTrust +{ + SecTrustRef trust = NULL; + + // Obtain the underlying SecTrustRef used by CFNetwork for the connection. + CFDictionaryRef certificateContext = _CFURLResponseGetSSLCertificateContext([self _CFURLResponse]); + if (_verbose && !certificateContext) { + fprintf(stdout, "Unable to get SSL certificate context!\n"); + fflush(stdout); + } else { + trust = (SecTrustRef) CFDictionaryGetValue(certificateContext, kCFStreamPropertySSLPeerTrust); + } + if (_verbose && !trust) { + fprintf(stdout, "Unable to get kCFStreamPropertySSLPeerTrust!\n"); + fflush(stdout); + } + return trust; +} + +- (NSArray *)peerCertificates +{ + NSArray *certificateChain = nil; + if ([self isKindOfClass:[NSHTTPURLResponse class]]) { + certificateChain = [(NSHTTPURLResponse *)self _peerCertificateChain]; + } + if (_verbose && certificateChain) { + fprintf(stdout, "Peer certificates: "); + fflush(stdout); + CFShow((__bridge CFArrayRef)certificateChain); + } + return certificateChain; +} + +@end + + +static NSString *errorStringForKey(NSString *key) +{ + NSString *errstr = nil; + // %%% note: these dictionary keys currently do not have exported constants + if (![key length] || [key isEqualToString:@"StatusCodes"]) { + return errstr; // skip empty and legacy numeric errors + } else if ([key isEqualToString:@"SSLHostname"]) { + errstr = @"Host name not found in Subject Alternative Name extension"; + } else if ([key isEqualToString:@"TemporalValidity"]) { + errstr = @"Certificate has expired, or is not yet valid (check date)"; + } else if ([key isEqualToString:@"KeySize"]) { + errstr = @"Certificate uses a key size which is considered too weak"; + } else if ([key isEqualToString:@"SignatureHashAlgorithms"]) { + errstr = @"Certificate uses a signing algorithm which is considered too weak"; + } else if ([key isEqualToString:@"KeyUsage"]) { + errstr = @"The Key Usage extension does not permit this use for the certificate"; + } else if ([key isEqualToString:@"ExtendedKeyUsage"]) { + errstr = @"The Extended Key Usage extension does not permit this use for the certificate"; + } else if ([key isEqualToString:@"Revocation"]) { + errstr = @"Certificate has been revoked and cannot be used"; + } else if ([key isEqualToString:@"BlackListedLeaf"]) { + errstr = @"Certificate has been blocked and cannot be used"; + } else if ([key isEqualToString:@"AnchorTrusted"]) { + errstr = @"The root of the certificate chain is not trusted"; + } else if ([key isEqualToString:@"MissingIntermediate"]) { + errstr = @"Unable to find next certificate in the chain"; + } else if ([key isEqualToString:@"NonEmptySubject"]) { + errstr = @"Certificate has no subject, and SAN is missing or not marked critical"; + } else if ([key isEqualToString:@"BasicCertificateProcessing"]) { + errstr = @"Certificate not standards compliant (RFC 5280|CABF Baseline Requirements)"; + } else if ([key isEqualToString:@"NameConstraints"]) { + errstr = @"Certificate violates name constraints placed on issuing CA"; + } else if ([key isEqualToString:@"PolicyConstraints"]) { + errstr = @"Certificate violates policy constraints placed on issuing CA"; + } else if ([key isEqualToString:@"CTRequired"]) { + errstr = @"Certificate Transparency validation is required but missing"; + } else if ([key isEqualToString:@"ValidityPeriodMaximums"]) { + errstr = @"Certificate exceeds maximum allowable validity period (normally 825 days)"; + } else if ([key isEqualToString:@"ServerAuthEKU"]) { + errstr = @"The Extended Key Usage extension does not permit server authentication"; + } else if ([key isEqualToString:@"UnparseableExtension"]) { + errstr = @"Unable to parse a standard extension (corrupt or invalid format detected)"; + } + + if (errstr) { + errstr = [NSString stringWithFormat:@"%@ [%@]", errstr, key]; + } else { + errstr = [NSString stringWithFormat:@"[%@]", key]; + } + return errstr; +} + +void printErrorDetails(SecTrustRef trust) +{ + CFDictionaryRef result = SecTrustCopyResult(trust); + CFArrayRef properties = SecTrustCopyProperties(trust); + NSArray *props = (__bridge NSArray *)properties; + NSArray *details = [(__bridge NSDictionary *)result objectForKey:@"TrustResultDetails"]; + if (!props || !details) { + if (result) { CFRelease(result); } + if (properties) { CFRelease(properties); } + return; + } + // Preflight to see if there are any errors to display + CFIndex errorCount = 0, chainLength = [details count]; + for (CFIndex chainIndex = 0; chainIndex < chainLength; chainIndex++) { + NSDictionary *certDetails = (NSDictionary *)[details objectAtIndex:chainIndex]; + errorCount += [certDetails count]; + } + if (!errorCount) { + if (result) { CFRelease(result); } + if (properties) { CFRelease(properties); } + return; + } + + // Display per-certificate errors + fprintf(stdout, "---\nCertificate errors\n"); + for (CFIndex chainIndex = 0; chainIndex < chainLength; chainIndex++) { + NSDictionary *certProps = (NSDictionary *)[props objectAtIndex:chainIndex]; + NSString *certTitle = (NSString *)[certProps objectForKey:(__bridge NSString*)kSecPropertyTypeTitle]; + fprintf(stdout, " %ld: %s\n", (long)chainIndex, [certTitle UTF8String]); + NSDictionary *certDetails = (NSDictionary *)[details objectAtIndex:chainIndex]; + NSEnumerator *keyEnumerator = [certDetails keyEnumerator]; + NSString *key; + while ((key = (NSString*)[keyEnumerator nextObject])) { + NSString *str = errorStringForKey(key); + if (!str) { continue; } + fprintf(stdout, ANSI_RED " %s" ANSI_RESET "\n", [str UTF8String]); + } + } + fflush(stdout); + + CFRelease(result); + CFRelease(properties); +} + +void printExtendedResults(SecTrustRef trust) +{ + CFDictionaryRef trustResults = SecTrustCopyResult(trust); + if (!trustResults) { return; } + fprintf(stdout, "---\n"); + + NSDictionary *results = (__bridge NSDictionary *)trustResults; + NSString *orgName = [results objectForKey:(NSString *)kSecTrustOrganizationName]; + CFBooleanRef isEV = (__bridge CFBooleanRef)[results objectForKey:(NSString *)kSecTrustExtendedValidation]; + if (isEV == kCFBooleanTrue) { + fprintf(stdout, "Extended Validation (EV) confirmed for \"" ANSI_GREEN "%s" ANSI_RESET "\"\n", [orgName UTF8String]); + } else { + fprintf(stdout, "No extended validation result found\n"); + } + CFBooleanRef isCT = (__bridge CFBooleanRef)[results objectForKey:(NSString *)kSecTrustCertificateTransparency]; + CFBooleanRef isCTW = (__bridge CFBooleanRef)[results objectForKey:(NSString *)kSecTrustCertificateTransparencyWhiteList]; + if (isCT == kCFBooleanTrue) { + fprintf(stdout, "Certificate Transparency (CT) status: " ANSI_GREEN "verified" ANSI_RESET "\n"); + } else if (isCTW == kCFBooleanTrue) { + fprintf(stdout, "Certificate Transparency requirement waived for approved EV certificate\n"); + } else { + fprintf(stdout, "Certificate Transparency (CT) status: " ANSI_RED "not verified" ANSI_RESET "\n"); + fprintf(stdout, "Unable to find at least 2 signed certificate timestamps (SCTs) from approved logs\n"); + } + fflush(stdout); + CFRelease(trustResults); +} + +int evaluate_ssl(const char *urlstr, int verbose, SecTrustRef * CF_RETURNS_RETAINED trustRef) +{ + @autoreleasepool { + _verbose = verbose; + if (trustRef) { + *trustRef = NULL; + } + if (![CertDownloader isNetworkURL:urlstr]) { + return 2; + } + CertDownloader *context = [[CertDownloader alloc] initWithURLString:urlstr]; + [context waitForDownloadToFinish]; + SecTrustRef trust = [context trustReference]; + if (trustRef && trust) { + CFRetain(trust); + *trustRef = trust; + } + } + return 0; +} + +static bool isHex(unichar c) +{ + return ((c >= 0x30 && c <= 0x39) || /* 0..9 */ + (c >= 0x41 && c <= 0x46) || /* A..F */ + (c >= 0x61 && c <= 0x66)); /* a..f */ +} + +static bool isEOL(unichar c) +{ + return (c == 0x0D || c == 0x0A); +} + +CF_RETURNS_RETAINED CFStringRef CopyCertificateTextRepresentation(SecCertificateRef certificate) +{ + if (!certificate) { + return NULL; + } + @autoreleasepool { + NSData *certData = [[[SFCertificateData alloc] initWithCertificate:certificate] tabDelimitedTextData]; + NSString *certStr = [[NSString alloc] initWithData:certData encoding:NSUnicodeStringEncoding]; + NSMutableString *outStr = [NSMutableString stringWithCapacity:0]; + [outStr appendString:certStr]; + + // process the output for readability by changing tabs to spaces + CFIndex index, count = [outStr length]; + for (index = 1; index < count; index++) { + unichar c = [outStr characterAtIndex:index]; + unichar p = [outStr characterAtIndex:index-1]; + if (isEOL(p)) { // start of line + while (c == 0x09) { // convert tabs to spaces until non-tab found + [outStr replaceCharactersInRange:NSMakeRange(index, 1) withString:@" "]; + c = [outStr characterAtIndex:++index]; + } + } else if (c == 0x09) { // tab found between label and value + if (p == 0x20) { // continue the run of spaces + [outStr replaceCharactersInRange:NSMakeRange(index, 1) withString:@" "]; + } else { // insert colon delimiter and space + [outStr replaceCharactersInRange:NSMakeRange(index, 1) withString:@": "]; + count++; // we inserted an extra character + } + } + } + // remove spaces in hexadecimal data representations for compactness + count = [outStr length]; + index = 0; + while (++index < count) { + unichar c = [outStr characterAtIndex:index]; + unichar p = [outStr characterAtIndex:index-1]; + // possible start of hex data run occurs after colon delimiter + if (p == 0x3A && c == 0x20) { + CFIndex start = index; + CFIndex len = 0; + while ((start+len+3 < count)) { + // scan for repeating three-character pattern + unichar first = [outStr characterAtIndex:start+len+0]; + if (first != 0x20) { + break; + } + unichar second = [outStr characterAtIndex:start+len+1]; + unichar third = [outStr characterAtIndex:start+len+2]; + unichar last = [outStr characterAtIndex:start+len+3]; + if (isHex(second) && isHex(third)) { + len += 3; + } else if (isEOL(second) && isHex(third) && isHex(last)) { + len += 4; // pattern continues on next line + } else { + break; + } + } + if (len > 0) { + // skip over the first space after the colon, which we want to keep + for (CFIndex idx = start+1; idx < count && idx < start+len; idx++) { + c = [outStr characterAtIndex:idx]; + if (c == 0x20 || isEOL(c)) { + [outStr deleteCharactersInRange:NSMakeRange(idx,1)]; + count--; // we removed a character from the total length + len--; // our substring also has one less character + } + } + } + } + } + return CFBridgingRetain(outStr); + } +} + diff --git a/SecurityTool/trusted_cert_utils.c b/SecurityTool/macOS/trusted_cert_utils.c similarity index 81% rename from SecurityTool/trusted_cert_utils.c rename to SecurityTool/macOS/trusted_cert_utils.c index 4a6f532e..2bbaf74e 100644 --- a/SecurityTool/trusted_cert_utils.c +++ b/SecurityTool/macOS/trusted_cert_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004,2006,2009-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2004,2006,2009-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -24,13 +24,16 @@ */ #include "trusted_cert_utils.h" +#include "trusted_cert_ssl.h" +#include "SecBase64.h" +#include #include #include -#include #include #include #include #include +#include #include static int indentSize = 0; @@ -98,6 +101,10 @@ void printHex( void printCfStr( CFStringRef cfstr) { + if(cfstr == NULL) { + printf(""); + return; + } CFDataRef strData = CFStringCreateExternalRepresentation(NULL, cfstr, kCFStringEncodingUTF8, true); CFIndex dex; @@ -109,7 +116,12 @@ void printCfStr( const char *cp = (const char *)CFDataGetBytePtr(strData); CFIndex len = CFDataGetLength(strData); for(dex=0; dex>\n"); + printf("<>\n"); return; } CFGregorianDate gregDate = CFAbsoluteTimeGetGregorianDate(absTime, NULL); @@ -392,12 +404,14 @@ int readCertFile( /* policy string --> CSSM_OID */ const CSSM_OID *policyStringToOid( - const char *policy) + const char *policy, + bool *useTLS) { - if(policy == NULL) { + if(!policy || !useTLS) { return NULL; } if(!strcmp(policy, "ssl")) { + *useTLS = true; return &CSSMOID_APPLE_TP_SSL; } else if(!strcmp(policy, "smime")) { @@ -407,6 +421,7 @@ const CSSM_OID *policyStringToOid( return &CSSMOID_APPLE_TP_CODE_SIGNING; } else if(!strcmp(policy, "IPSec")) { + *useTLS = true; return &CSSMOID_APPLE_TP_IP_SEC; } else if(!strcmp(policy, "basic")) { @@ -419,6 +434,7 @@ const CSSM_OID *policyStringToOid( return &CSSMOID_APPLE_TP_PACKAGE_SIGNING; } else if(!strcmp(policy, "eap")) { + *useTLS = true; return &CSSMOID_APPLE_TP_EAP; } else if(!strcmp(policy, "macappstore")) { @@ -460,3 +476,73 @@ CFOptionFlags revCheckOptionStringToFlags( } return result; } + +static size_t print_buffer_pem(FILE *stream, + const char *pem_name, size_t length, const uint8_t *bytes) +{ + size_t pem_name_len = strlen(pem_name); + size_t b64_len = SecBase64Encode2(NULL, length, NULL, 0, + kSecB64_F_LINE_LEN_USE_PARAM, 64, NULL); + char *buffer = malloc(33 + 2 * pem_name_len + b64_len); + char *p = buffer; + p += sprintf(buffer, "-----BEGIN %s-----\n", pem_name); + SecBase64Result result; + p += SecBase64Encode2(bytes, length, p, b64_len,\ + kSecB64_F_LINE_LEN_USE_PARAM, 64, &result); + if (result) { + free(buffer); + return result; + } + p += sprintf(p, "\n-----END %s-----\n", pem_name); + size_t res = fwrite(buffer, 1, p - buffer, stream); + fflush(stream); + bzero(buffer, p - buffer); + free(buffer); + return res; +} + +void printCertLabel(SecCertificateRef certRef) +{ + CFStringRef label = SecCertificateCopySubjectSummary(certRef); + printCfStr(label); + CFReleaseSafe(label); +} + +void printCertDescription(SecCertificateRef certRef) +{ + CFStringRef description = CFCopyDescription((CFTypeRef)certRef); + printCfStr(description); + CFReleaseSafe(description); +} + +void printCertText(SecCertificateRef certRef) +{ + CFStringRef certStr = CopyCertificateTextRepresentation(certRef); + printf("\n"); + printCfStr(certStr); + printf("\n\n"); + CFReleaseSafe(certStr); +} + +void printCertChain(SecTrustRef trustRef, bool printPem, bool printText) +{ + CFIndex idx, count = SecTrustGetCertificateCount(trustRef); + for (idx = 0; idx < count; idx++) { + SecCertificateRef cert = SecTrustGetCertificateAtIndex(trustRef, idx); + fprintf(stdout, " %ld: ", idx); + printCertLabel(cert); + fprintf(stdout, "\n "); + if (!cert) { continue; } + printCertDescription(cert); + fprintf(stdout, "\n"); + if (printText) { + printCertText(cert); + } + if (printPem) { + print_buffer_pem(stdout, "CERTIFICATE", + SecCertificateGetLength(cert), + SecCertificateGetBytePtr(cert)); + } + } +} + diff --git a/SecurityTool/trusted_cert_utils.h b/SecurityTool/macOS/trusted_cert_utils.h similarity index 85% rename from SecurityTool/trusted_cert_utils.h rename to SecurityTool/macOS/trusted_cert_utils.h index f4d8403a..70289084 100644 --- a/SecurityTool/trusted_cert_utils.h +++ b/SecurityTool/macOS/trusted_cert_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2004,2006,2014-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2003-2004,2006,2014-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -25,7 +25,9 @@ #ifndef _TRUSTED_CERT_UTILS_H_ #define _TRUSTED_CERT_UTILS_H_ 1 +#include #include +#include #include #ifdef __cplusplus @@ -45,6 +47,10 @@ void printCfNumber(CFNumberRef cfNum); void printResultType(CFNumberRef cfNum); void printKeyUsage(CFNumberRef cfNum); void printCssmErr(CFNumberRef cfNum); +void printCertLabel(SecCertificateRef certRef); +void printCertDescription(SecCertificateRef certRef); +void printCertText(SecCertificateRef certRef); +void printCertChain(SecTrustRef trustRef, bool printPem, bool printText); /* convert an OID to a SecPolicyRef */ extern SecPolicyRef oidToPolicy(const CSSM_OID *oid); @@ -65,7 +71,7 @@ extern SecTrustedApplicationRef appPathToAppRef(const char *appPath); int readCertFile(const char *fileName, SecCertificateRef *certRef); /* policy string --> CSSM_OID */ -const CSSM_OID *policyStringToOid(const char *policy); +const CSSM_OID *policyStringToOid(const char *policy, bool *useTLS); /* revocation option string --> revocation option flag */ CFOptionFlags revCheckOptionStringToFlags(const char *revCheckOption); diff --git a/SecurityTool/user_trust_enable.cpp b/SecurityTool/macOS/user_trust_enable.cpp similarity index 100% rename from SecurityTool/user_trust_enable.cpp rename to SecurityTool/macOS/user_trust_enable.cpp diff --git a/SecurityTool/user_trust_enable.h b/SecurityTool/macOS/user_trust_enable.h similarity index 100% rename from SecurityTool/user_trust_enable.h rename to SecurityTool/macOS/user_trust_enable.h diff --git a/SecurityTool/verify_cert.c b/SecurityTool/macOS/verify_cert.c similarity index 85% rename from SecurityTool/verify_cert.c rename to SecurityTool/macOS/verify_cert.c index 3e32b2c9..58618c7b 100644 --- a/SecurityTool/verify_cert.c +++ b/SecurityTool/macOS/verify_cert.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006,2010,2012,2014-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2006,2010,2012,2014-2019 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -33,6 +33,7 @@ #include #include #include +#include "trusted_cert_ssl.h" #include "trusted_cert_utils.h" #include "verify_cert.h" #include @@ -74,13 +75,20 @@ verify_cert(int argc, char * const *argv) int ourRtn = 0; bool quiet = false; bool client = false; + bool useTLS = false; + bool printPem = false; + bool printText = false; + bool printDetails = false; + int verbose = 0; SecPolicyRef policyRef = NULL; SecPolicyRef revPolicyRef = NULL; SecTrustRef trustRef = NULL; SecPolicySearchRef searchRef = NULL; + CFErrorRef errorRef = NULL; const char *emailAddrs = NULL; const char *sslHost = NULL; const char *name = NULL; + const char *url = NULL; CSSM_APPLE_TP_SSL_OPTIONS sslOpts; CSSM_APPLE_TP_SMIME_OPTIONS smimeOpts; CSSM_APPLE_TP_ACTION_FLAGS actionFlags = 0; @@ -101,7 +109,7 @@ verify_cert(int argc, char * const *argv) /* permit network cert fetch unless explicitly turned off with '-L' */ actionFlags |= CSSM_TP_ACTION_FETCH_CERT_FROM_NET; optind = 1; - while ((arg = getopt(argc, argv, "Cc:r:p:k:e:s:d:LlNnqR:")) != -1) { + while ((arg = getopt(argc, argv, "Cc:r:p:k:e:s:d:LlNnPqR:tv")) != -1) { switch (arg) { case 'C': client = true; @@ -121,7 +129,7 @@ verify_cert(int argc, char * const *argv) } break; case 'p': - policy = policyStringToOid(optarg); + policy = policyStringToOid(optarg, &useTLS); if(policy == NULL) { ourRtn = 2; goto errOut; @@ -200,13 +208,32 @@ verify_cert(int argc, char * const *argv) case 'R': revOptions |= revCheckOptionStringToFlags(optarg); break; + case 'P': + printPem = true; + break; + case 't': + printText = true; + break; + case 'v': + printDetails = true; + verbose++; + break; default: ourRtn = 2; goto errOut; } } if(optind != argc) { - ourRtn = 2; + if (argc > optind) { + url = argv[argc-1]; + } + if (url && *url != '\0') { + useTLS = true; + ourRtn = evaluate_ssl(url, verbose, &trustRef); + goto post_evaluate; + } else { + ourRtn = 2; + } goto errOut; } @@ -338,7 +365,9 @@ verify_cert(int argc, char * const *argv) } /* GO */ - ortn = SecTrustEvaluate(trustRef, &resultType); + (void)SecTrustEvaluateWithError(trustRef, &errorRef); +post_evaluate: + ortn = SecTrustGetTrustResult(trustRef, &resultType); if(ortn) { /* should never fail - error on this doesn't mean the cert verified badly */ cssmPerror("SecTrustEvaluate", ortn); @@ -371,21 +400,52 @@ verify_cert(int argc, char * const *argv) } break; } - if((ourRtn == 0) & !quiet) { printf("...certificate verification successful.\n"); } + if (printPem || printText || verbose) { + fprintf(stdout, "---\nCertificate chain\n"); + printCertChain(trustRef, printPem, printText); + } + if (verbose) { + printErrorDetails(trustRef); + } + if (useTLS) { + printExtendedResults(trustRef); + } + if (printDetails) { + CFArrayRef properties = SecTrustCopyProperties(trustRef); + if (verbose > 1) { + fprintf(stderr, "---\nCertificate chain properties\n"); + CFShow(properties); // output goes to stderr + } + if (properties) { + CFRelease(properties); + } + CFDictionaryRef result = SecTrustCopyResult(trustRef); + if (result) { + fprintf(stderr, "---\nTrust evaluation results\n"); + CFShow(result); // output goes to stderr + CFRelease(result); + } + if (errorRef) { + fprintf(stdout, "---\nTrust evaluation errors\n"); + CFShow(errorRef); + } + } + errOut: - CFReleaseNull(dateRef); /* cleanup */ CFRELEASE(certs); CFRELEASE(roots); CFRELEASE(keychains); CFRELEASE(policies); CFRELEASE(revPolicyRef); + CFRELEASE(dateRef); CFRELEASE(policyRef); CFRELEASE(trustRef); CFRELEASE(searchRef); + CFRELEASE(errorRef); CFRELEASE(cfActionData); return ourRtn; } diff --git a/SecurityTool/verify_cert.h b/SecurityTool/macOS/verify_cert.h similarity index 100% rename from SecurityTool/verify_cert.h rename to SecurityTool/macOS/verify_cert.h diff --git a/OSX/sec/SecurityTool/KeychainCheck.h b/SecurityTool/sharedTool/KeychainCheck.h similarity index 100% rename from OSX/sec/SecurityTool/KeychainCheck.h rename to SecurityTool/sharedTool/KeychainCheck.h diff --git a/OSX/sec/SecurityTool/KeychainCheck.m b/SecurityTool/sharedTool/KeychainCheck.m similarity index 83% rename from OSX/sec/SecurityTool/KeychainCheck.m rename to SecurityTool/sharedTool/KeychainCheck.m index 3786207d..724082bd 100644 --- a/OSX/sec/SecurityTool/KeychainCheck.m +++ b/SecurityTool/sharedTool/KeychainCheck.m @@ -123,3 +123,29 @@ int command_keychain_cleanup(int argc, char* const* argv) [keychainCheck cleanKeychain]; return 0; } + +int verify_backup_integrity(int argc, char * const *argv) { + int arg; + BOOL lightweight = NO; + + while ((arg = getopt(argc, argv, "l")) != -1) { + switch(arg) { + case 'l': + lightweight = YES; + break; + } + } + + NSLog(@"Running backup integrity validation in %@ mode", lightweight ? @"lightweight" : @"default"); + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + SecItemVerifyBackupIntegrity(lightweight, ^(NSDictionary* results, NSError *error) { + NSLog(@"%@", results); + dispatch_semaphore_signal(sema); + }); + + if (dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 30))) { + NSLog(@"Timed out waiting for backup integrity validation"); + } + + return 0; +} diff --git a/OSX/sec/SOSCircle/Tool/NSFileHandle+Formatting.h b/SecurityTool/sharedTool/NSFileHandle+Formatting.h similarity index 100% rename from OSX/sec/SOSCircle/Tool/NSFileHandle+Formatting.h rename to SecurityTool/sharedTool/NSFileHandle+Formatting.h diff --git a/OSX/sec/SOSCircle/Tool/NSFileHandle+Formatting.m b/SecurityTool/sharedTool/NSFileHandle+Formatting.m similarity index 100% rename from OSX/sec/SOSCircle/Tool/NSFileHandle+Formatting.m rename to SecurityTool/sharedTool/NSFileHandle+Formatting.m diff --git a/OSX/sec/Security/Tool/SecurityCommands.h b/SecurityTool/sharedTool/SecurityCommands.h similarity index 95% rename from OSX/sec/Security/Tool/SecurityCommands.h rename to SecurityTool/sharedTool/SecurityCommands.h index a49bc614..1792878a 100644 --- a/OSX/sec/Security/Tool/SecurityCommands.h +++ b/SecurityTool/sharedTool/SecurityCommands.h @@ -1,6 +1,6 @@ // This is a preprocessed file to define commands that we provide in Security part of the Sec module. -#include +#include "SecurityTool/sharedTool/security_tool_commands.h" #if TARGET_OS_IPHONE #define USE_SECURITY_ITEM "By default the synchronizable keys is not searched/update/deleted, use \"security item\" for that.\n" @@ -23,12 +23,13 @@ SECURITY_COMMAND("add-internet-password", keychain_add_internet_password, "Add an internet password item.") SECURITY_COMMAND("item", keychain_item, - "[-v][-a|-D|-u attr=value,...|[-q][-g] attr=value,...] [-d password | -f datafile] [attr=value,...]\n" + "[-v][-a|-D|-u attr=value,...|[-q][-j][-g] attr=value,...] [-d password | -f datafile] [attr=value,...]\n" "-q Query for item matching (default). Note: as default query skips items with ACL, you have to define 'u_AuthUI=u_AuthUIA' if you want to query items with ACL\n" "-g Get password data\n" "-a Add item to keychain\n" "-u Update item in keychain (require query to match)\n" "-D Delete item from keychain\n" + "-j When printing results, print JSON\n" "Add, query, update or delete items from the keychain. Extra attr=value pairs after options always apply to the query\n" "class=[genp|inet|cert|keys] is required for the query\n" "To search the synchronizable items (not searched by default) use sync=1 as an attr=value pair.\n" @@ -40,6 +41,10 @@ SECURITY_COMMAND("item", keychain_item, "SAC object for deleting item added by default\n", "Manipulate keychain items.") +SECURITY_COMMAND("policy-dryrun", policy_dryrun, + "", + "Try to evaluate policy old/new.") + SECURITY_COMMAND("keychain-item-digest", keychain_item_digest, "itemClass keychainAccessGroup\n" "Dump items reported by _SecItemDigest command\n", @@ -193,8 +198,9 @@ SECURITY_COMMAND_IOS("trust-store", trust_store_show_certificates, "Display user trust store certificates and trust settings.") SECURITY_COMMAND("check-trust-update", check_trust_update, - "[-s]\n" - " -s Check for Supplementals (Pinning DB and Trusted CT Logs) update\n", + "[-s][-e]\n" + " -s Check for Supplementals (Pinning DB and Trusted CT Logs) update\n" + " -e Check for SecExperiment update\n", "Check for data updates for trust and return current version.") SECURITY_COMMAND("add-ct-exceptions", add_ct_exceptions, @@ -216,4 +222,4 @@ SECURITY_COMMAND("show-ct-exceptions", show_ct_exceptions, " -d Output domain exceptions. Default is both domains and certs.\n" " -c Output certificate exceptions (as SPKI hash).\n" " Default is both domains and certs.\n", - "Display exceptions for Certificate Transparnecy enforcment in json.") + "Display exceptions for Certificate Transparency enforcement in json.") diff --git a/OSX/sec/SecurityTool/SecurityTool.c b/SecurityTool/sharedTool/SecurityTool.c similarity index 98% rename from OSX/sec/SecurityTool/SecurityTool.c rename to SecurityTool/sharedTool/SecurityTool.c index 571a34f9..847c4e1a 100644 --- a/OSX/sec/SecurityTool/SecurityTool.c +++ b/SecurityTool/sharedTool/SecurityTool.c @@ -26,8 +26,8 @@ #include "SecurityTool.h" #include "SecInternalReleasePriv.h" -#include -#include "SecurityTool/security_tool_commands.h" +#include "SecurityTool/sharedTool/readline.h" +#include "SecurityTool/sharedTool/security_tool_commands.h" #include "leaks.h" diff --git a/OSX/sec/SecurityTool/SecurityTool.h b/SecurityTool/sharedTool/SecurityTool.h similarity index 100% rename from OSX/sec/SecurityTool/SecurityTool.h rename to SecurityTool/sharedTool/SecurityTool.h diff --git a/OSX/sec/Security/Tool/add_internet_password.c b/SecurityTool/sharedTool/add_internet_password.c similarity index 99% rename from OSX/sec/Security/Tool/add_internet_password.c rename to SecurityTool/sharedTool/add_internet_password.c index 5758d7bf..1a8f54d8 100644 --- a/OSX/sec/Security/Tool/add_internet_password.c +++ b/SecurityTool/sharedTool/add_internet_password.c @@ -30,7 +30,7 @@ #include #include -#include +#include "SecurityTool/sharedTool/tool_errors.h" #include "SecurityCommands.h" diff --git a/OSX/sec/SecurityTool/builtin_commands.h b/SecurityTool/sharedTool/builtin_commands.h similarity index 88% rename from OSX/sec/SecurityTool/builtin_commands.h rename to SecurityTool/sharedTool/builtin_commands.h index e09dfa8b..8e57592a 100644 --- a/OSX/sec/SecurityTool/builtin_commands.h +++ b/SecurityTool/sharedTool/builtin_commands.h @@ -22,7 +22,7 @@ */ -#include "SecurityTool/security_tool_commands.h" +#include "SecurityTool/sharedTool/security_tool_commands.h" SECURITY_COMMAND("help", help, "[command ...]", @@ -68,3 +68,8 @@ SECURITY_COMMAND("keychain-check", command_keychain_check, SECURITY_COMMAND("keychain-cleanup", command_keychain_cleanup, "", "attempt to remove keychain items we can no longer decrypt") + +SECURITY_COMMAND("verify-backup-integrity", verify_backup_integrity, + "[-l]\n" + " -l Lightweight. Only verify backup infrastructure without verifying all keychain items.\n", + "Verify integrity of keychain backup key material.") diff --git a/OSX/sec/Security/Tool/codesign.c b/SecurityTool/sharedTool/codesign.c similarity index 99% rename from OSX/sec/Security/Tool/codesign.c rename to SecurityTool/sharedTool/codesign.c index 43e5cda5..3120be68 100644 --- a/OSX/sec/Security/Tool/codesign.c +++ b/SecurityTool/sharedTool/codesign.c @@ -22,7 +22,7 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include "SecurityCommands.h" @@ -425,4 +425,4 @@ out: return -1; } -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR diff --git a/OSX/sec/Security/Tool/ct_exceptions.m b/SecurityTool/sharedTool/ct_exceptions.m similarity index 100% rename from OSX/sec/Security/Tool/ct_exceptions.m rename to SecurityTool/sharedTool/ct_exceptions.m diff --git a/OSX/sec/SecurityTool/digest_calc.c b/SecurityTool/sharedTool/digest_calc.c similarity index 97% rename from OSX/sec/SecurityTool/digest_calc.c rename to SecurityTool/sharedTool/digest_calc.c index 09bb7af0..9abe57e1 100644 --- a/OSX/sec/SecurityTool/digest_calc.c +++ b/SecurityTool/sharedTool/digest_calc.c @@ -28,7 +28,7 @@ #include #include -#include +#include "SecurityTool/sharedTool/readline.h" #include #include @@ -67,7 +67,6 @@ extern int command_digest(int argc, char * const *argv) return SHOW_USAGE_MESSAGE; ccdigest_di_decl(di, ctx); - ccdigest_init(di, ctx); digest = malloc(di->output_size); require_quiet(digest, exit); @@ -80,6 +79,9 @@ extern int command_digest(int argc, char * const *argv) printf("error reading file\n"); continue; } + + ccdigest_init(di, ctx); + totalBytes = 0; while((nr = pread(fd, data, sizeof(data), totalBytes)) > 0){ ccdigest_update(di, ctx, nr, data); diff --git a/SecurityTool/entitlements.plist b/SecurityTool/sharedTool/iOS/entitlements.plist similarity index 79% rename from SecurityTool/entitlements.plist rename to SecurityTool/sharedTool/iOS/entitlements.plist index 76e6179f..ecb877f8 100644 --- a/SecurityTool/entitlements.plist +++ b/SecurityTool/sharedTool/iOS/entitlements.plist @@ -4,6 +4,8 @@ keychain-cloud-circle + restore-keychain + keychain-access-groups test @@ -11,15 +13,15 @@ modify-anchor-certificates - restore-keychain - - com.apple.private.syncbubble-keychain - - com.apple.private.system-keychain - application-identifier com.apple.security com.apple.private.keychain.keychaincontrol + com.apple.developer.icloud-services + + CloudKit + + com.apple.CloudKeychainProxy.client + diff --git a/OSX/sec/SecurityTool/security.1 b/SecurityTool/sharedTool/iOS/security.1 similarity index 99% rename from OSX/sec/SecurityTool/security.1 rename to SecurityTool/sharedTool/iOS/security.1 index 2b440afd..fe33b8a8 100644 --- a/OSX/sec/SecurityTool/security.1 +++ b/SecurityTool/sharedTool/iOS/security.1 @@ -115,7 +115,7 @@ Show the settings for keychain. .It Nm dump-keychain Dump the contents of one or more keychains. .It Nm create-keypair -Create an assymetric keypair. +Create an asymmetric keypair. .It Nm add-internet-password Add an internet password item. .It Nm add-certificates @@ -605,7 +605,7 @@ command or the option it's probably a good idea to set this environment variable before .Nm is started. Doing so will allow leaks to display symbolic backtraces. -.El +.El .Sh FILES .Bl -tag -width -indent .It Pa ~/Library/Preferences/com.apple.security.plist @@ -627,8 +627,6 @@ Propertylist file containing the a common keychain search list which is appended .Sh HISTORY .Nm was first introduced in Mac OS X version 10.3 -.Sh AUTHORS -.An "Michael Brouwer" .Sh BUGS .Nm still needs a lot more commands before it can be considered complete. diff --git a/OSX/sec/Security/Tool/keychain_add.c b/SecurityTool/sharedTool/keychain_add.c similarity index 94% rename from OSX/sec/Security/Tool/keychain_add.c rename to SecurityTool/sharedTool/keychain_add.c index decf795d..950936f9 100644 --- a/OSX/sec/Security/Tool/keychain_add.c +++ b/SecurityTool/sharedTool/keychain_add.c @@ -24,7 +24,7 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include "SecurityCommands.h" @@ -38,8 +38,8 @@ #include #include -#include -#include +#include "SecurityTool/sharedTool/readline.h" +#include "SecurityTool/sharedTool/tool_errors.h" #include @@ -130,4 +130,4 @@ keychain_add_certificates(int argc, char * const *argv) return result; } -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR diff --git a/OSX/sec/Security/Tool/keychain_backup.c b/SecurityTool/sharedTool/keychain_backup.c similarity index 95% rename from OSX/sec/Security/Tool/keychain_backup.c rename to SecurityTool/sharedTool/keychain_backup.c index c084dd28..b2147c7f 100644 --- a/OSX/sec/Security/Tool/keychain_backup.c +++ b/SecurityTool/sharedTool/keychain_backup.c @@ -24,7 +24,7 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include "SecurityCommands.h" @@ -33,8 +33,8 @@ #include -#include -#include +#include "SecurityTool/sharedTool/readline.h" +#include "SecurityTool/sharedTool/tool_errors.h" static int @@ -170,4 +170,4 @@ keychain_export(int argc, char * const *argv) return do_keychain_export(argv[0], keybag, password); } -#endif /* TARGET_OS_EMBEDDED */ +#endif /* TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */ diff --git a/OSX/sec/Security/Tool/keychain_find.m b/SecurityTool/sharedTool/keychain_find.m similarity index 86% rename from OSX/sec/Security/Tool/keychain_find.m rename to SecurityTool/sharedTool/keychain_find.m index 4f5c3fc7..b222187a 100644 --- a/OSX/sec/Security/Tool/keychain_find.m +++ b/SecurityTool/sharedTool/keychain_find.m @@ -29,8 +29,8 @@ #include #include -#include -#include +#include "SecurityTool/sharedTool/tool_errors.h" +#include "SecurityTool/sharedTool/readline.h" #include @@ -76,7 +76,7 @@ static bool isPrintableString(CFStringRef theString){ CFCharacterSetUnion(unacceptable, illegalSet); result = CFStringFindCharacterFromSet(theString, unacceptable, CFRangeMake(0, CFStringGetLength(theString)), 0, NULL); CFReleaseNull(unacceptable); - return result; + return !result; } static void display_item(const void *v_item, void *context) { @@ -153,11 +153,11 @@ static void display_item(const void *v_item, void *context) { static void display_results(CFTypeRef results) { - if (CFGetTypeID(results) == CFArrayGetTypeID()) { + if (results && CFGetTypeID(results) == CFArrayGetTypeID()) { CFArrayRef r_a = (CFArrayRef)results; CFArrayApplyFunction(r_a, CFRangeMake(0, CFArrayGetCount(r_a)), display_item, NULL); - } else if (CFGetTypeID(results) == CFDictionaryGetTypeID()) { + } else if (results && CFGetTypeID(results) == CFDictionaryGetTypeID()) { display_item(results, NULL); } else { fprintf(stderr, "SecItemCopyMatching returned unexpected results:"); @@ -165,6 +165,89 @@ static void display_results(CFTypeRef results) { } } +static NSDictionary* cleanNSDictionaryForJSON(NSDictionary* dict) { + if(!dict) { + return nil; + } + NSMutableDictionary* mutDict = [NSMutableDictionary dictionary]; + for(id key in dict.allKeys) { + id obj = dict[key]; + + if([obj isKindOfClass:[NSDictionary class]]) { + mutDict[key] = cleanNSDictionaryForJSON(obj); + + } else if([NSJSONSerialization isValidJSONObject:obj]) { + mutDict[key] = obj; + + } else if([obj isKindOfClass:[NSString class]]) { + mutDict[key] = obj; + + } else if([obj isKindOfClass:[NSNumber class]]) { + mutDict[key] = obj; + + } else if([obj isKindOfClass:[NSData class]]) { + mutDict[key] = [(NSData*)obj base64EncodedStringWithOptions:0]; + + } else if([obj isKindOfClass:[NSDate class]]) { + NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; + mutDict[key] = [dateFormat stringFromDate:obj]; + + } else if (SecAccessControlGetTypeID() == CFGetTypeID((__bridge CFTypeRef)obj)) { + NSMutableString* str = [NSMutableString string]; + display_sac_line((__bridge SecAccessControlRef)obj, (__bridge CFMutableStringRef)str); + mutDict[key] = str; + + } else { + NSLog(@"can't jsonify: %@ %@ %@", key, obj, [obj class]); + } + } + return mutDict; +} + +static void display_results_json(CFTypeRef cfitem) { + id item = (__bridge id)cfitem; + + if([item isKindOfClass:[NSArray class]]) { + NSArray* array = (NSArray*)item; + NSMutableArray* cleanArray = [NSMutableArray array]; + + for(id x in array) { + NSDictionary* cleanDictionary = cleanNSDictionaryForJSON((NSDictionary*)x); + [cleanArray addObject:cleanDictionary]; + + if(![NSJSONSerialization isValidJSONObject:cleanDictionary]) { + fprintf(stderr, "%s", [[NSString stringWithFormat:@"Can't JSONify: %@", x] UTF8String]); + } + } + + NSError* error = nil; + NSData *json = [NSJSONSerialization dataWithJSONObject:cleanArray + options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) + error:&error]; + if (!json) { + fprintf(stderr, "%s", [[NSString stringWithFormat:@"error: %@", error.localizedDescription] UTF8String]); + } else { + printf("%s\n", [[[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding] UTF8String]); + } + + } else if([item isKindOfClass:[NSDictionary class]]) { + NSError* error = nil; + NSData *json = [NSJSONSerialization dataWithJSONObject:cleanNSDictionaryForJSON(item) + options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) + error:&error]; + if (!json) { + fprintf(stderr, "%s", [[NSString stringWithFormat:@"error: %@", error.localizedDescription] UTF8String]); + } else { + printf("%s\n", [[[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding] UTF8String]); + } + + } else { + fprintf(stderr, "SecItemCopyMatching returned unexpected results (can't JSONify):"); + CFShow(cfitem); + } + +} + static OSStatus do_find_or_delete(CFDictionaryRef query, bool do_delete) { OSStatus result; if (do_delete) { @@ -496,14 +579,15 @@ int keychain_item(int argc, char * const *argv) { bool do_delete = false; bool do_add = false; bool verbose = false; + bool json = false; int limit = 0; query = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); #if TARGET_OS_OSX - CFDictionarySetValue(query, kSecAttrNoLegacy, kCFBooleanTrue); + CFDictionarySetValue(query, kSecUseDataProtectionKeychain, kCFBooleanTrue); #endif - while ((ch = getopt(argc, argv, "ad:Df:gq:u:vl:")) != -1) + while ((ch = getopt(argc, argv, "ad:Df:jgq:u:vl:")) != -1) { switch (ch) { @@ -536,6 +620,9 @@ int keychain_item(int argc, char * const *argv) { CFRelease(data); break; } + case 'j': + json = true; + break; case 'g': get_password = true; break; @@ -601,8 +688,13 @@ int keychain_item(int argc, char * const *argv) { CFDictionarySetValue(query, kSecReturnData, kCFBooleanTrue); } - if (verbose) - CFShow(query); + if (verbose) { + if(json) { + display_results_json(query); + } else { + CFShow(query); + } + } OSStatus error; bool useCredentialStore = [(__bridge id)CFDictionaryGetValue(query, kSecClass) isEqual:@"credential"]; @@ -713,7 +805,17 @@ int keychain_item(int argc, char * const *argv) { if (!do_delete && CFDictionaryGetValue(query, kSecUseAuthenticationUI) == NULL) { CFDictionarySetValue(query, kSecUseAuthenticationUI, kSecUseAuthenticationUISkip); } - do_find_or_delete(query, do_delete); + + CFTypeRef results = NULL; + OSStatus status = SecItemCopyMatching(query, &results); + if (status) { + sec_perror("SecItemCopyMatching", status); + } else if(json) { + display_results_json(results); + } else { + display_results(results); + } + CFReleaseNull(results); } } @@ -796,7 +898,7 @@ int keychain_item_digest(int argc, char * const *argv) { } -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR int keychain_roll_keys(int argc, char * const *argv) { diff --git a/OSX/sec/Security/Tool/keychain_util.c b/SecurityTool/sharedTool/keychain_util.c similarity index 99% rename from OSX/sec/Security/Tool/keychain_util.c rename to SecurityTool/sharedTool/keychain_util.c index 704a376b..d64f6159 100644 --- a/OSX/sec/Security/Tool/keychain_util.c +++ b/SecurityTool/sharedTool/keychain_util.c @@ -31,7 +31,7 @@ #include "security.h" #include "keychain_util.h" -#include "SecAccessControlPriv.h" +#include static CFStringRef createStringForValue(CFTypeRef value) { @@ -185,7 +185,7 @@ keychain_query_parse_string(CFMutableDictionaryRef q, CFStringRef s) { if(sac) { CFDictionarySetValue(q, key, sac); } else { - fprintf(stderr, "SecItemCopyMatching returned unexpected results:"); + fprintf(stderr, "failed to parse access control\n"); error = true; } } else { diff --git a/OSX/sec/Security/Tool/keychain_util.h b/SecurityTool/sharedTool/keychain_util.h similarity index 100% rename from OSX/sec/Security/Tool/keychain_util.h rename to SecurityTool/sharedTool/keychain_util.h diff --git a/OSX/sec/SecurityTool/leaks.c b/SecurityTool/sharedTool/leaks.c similarity index 99% rename from OSX/sec/SecurityTool/leaks.c rename to SecurityTool/sharedTool/leaks.c index e6ce54b8..7aedfb27 100644 --- a/OSX/sec/SecurityTool/leaks.c +++ b/SecurityTool/sharedTool/leaks.c @@ -63,7 +63,6 @@ leaks(int argc, char *const *argv) execv(argvec[0], argvec); fprintf(stderr, "exec: %s", strerror(errno)); _exit(1); - break; } default: { diff --git a/OSX/sec/SecurityTool/leaks.h b/SecurityTool/sharedTool/leaks.h similarity index 100% rename from OSX/sec/SecurityTool/leaks.h rename to SecurityTool/sharedTool/leaks.h diff --git a/OSX/sec/Security/Tool/log_control.c b/SecurityTool/sharedTool/log_control.c similarity index 99% rename from OSX/sec/Security/Tool/log_control.c rename to SecurityTool/sharedTool/log_control.c index 82a6a17c..0878d45a 100644 --- a/OSX/sec/Security/Tool/log_control.c +++ b/SecurityTool/sharedTool/log_control.c @@ -30,7 +30,7 @@ #include #include -#include +#include "SecurityTool/sharedTool/tool_errors.h" #include diff --git a/OSX/sec/SecurityTool/entitlements.plist b/SecurityTool/sharedTool/macOS/entitlements.plist similarity index 70% rename from OSX/sec/SecurityTool/entitlements.plist rename to SecurityTool/sharedTool/macOS/entitlements.plist index 02f42d08..dc75012f 100644 --- a/OSX/sec/SecurityTool/entitlements.plist +++ b/SecurityTool/sharedTool/macOS/entitlements.plist @@ -2,22 +2,32 @@ - keychain-cloud-circle + application-identifier + com.apple.security + com.apple.application-identifier + com.apple.security + com.apple.developer.icloud-services + + CloudKit + + com.apple.private.keychain.keychaincontrol - restore-keychain + com.apple.private.syncbubble-keychain + + com.apple.private.system-keychain keychain-access-groups test * + keychain-cloud-circle + modify-anchor-certificates - application-identifier - com.apple.security - com.apple.application-identifier - com.apple.security - com.apple.private.keychain.keychaincontrol + restore-keychain + + com.apple.CloudKeychainProxy.client diff --git a/OSX/security2/security2.1 b/SecurityTool/sharedTool/macOS/security2.1 similarity index 100% rename from OSX/security2/security2.1 rename to SecurityTool/sharedTool/macOS/security2.1 diff --git a/OSX/utilities/SecurityTool/not_on_this_platorm.c b/SecurityTool/sharedTool/not_on_this_platorm.c similarity index 100% rename from OSX/utilities/SecurityTool/not_on_this_platorm.c rename to SecurityTool/sharedTool/not_on_this_platorm.c diff --git a/OSX/sec/Security/Tool/pkcs12_util.c b/SecurityTool/sharedTool/pkcs12_util.c similarity index 98% rename from OSX/sec/Security/Tool/pkcs12_util.c rename to SecurityTool/sharedTool/pkcs12_util.c index 1fc1f145..1831dd64 100644 --- a/OSX/sec/Security/Tool/pkcs12_util.c +++ b/SecurityTool/sharedTool/pkcs12_util.c @@ -22,7 +22,7 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include #include @@ -48,7 +48,7 @@ #include #include "SecurityCommands.h" -#include "SecurityTool/print_cert.h" +#include "SecurityTool/sharedTool/print_cert.h" static void * read_file(const char * filename, size_t * data_length) @@ -376,4 +376,4 @@ extern int pkcs12_util(int argc, char * const *argv) return success ? 0 : -1; } -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR diff --git a/OSX/libsecurity_cdsa_utilities/lib/uniformrandom.cpp b/SecurityTool/sharedTool/policy_dryrun.h similarity index 77% rename from OSX/libsecurity_cdsa_utilities/lib/uniformrandom.cpp rename to SecurityTool/sharedTool/policy_dryrun.h index 92c6f507..c2e2149f 100644 --- a/OSX/libsecurity_cdsa_utilities/lib/uniformrandom.cpp +++ b/SecurityTool/sharedTool/policy_dryrun.h @@ -1,6 +1,6 @@ /* - * Copyright (c) 2000-2001,2003-2004,2006,2011,2014 Apple Inc. All Rights Reserved. - * + * Copyright (c) 2019 Apple Inc. All Rights Reserved. + * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code @@ -19,19 +19,19 @@ * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ + * + * policy_dryrun.h */ +#ifndef _POLICY_DRYRUN_H_ +#define _POLICY_DRYRUN_H_ -// -// uniformrandom - uniformly distributed random number operators -// - -#include - - -namespace Security { +#include +__BEGIN_DECLS +int policy_dryrun(int argc, char * const *argv); +__END_DECLS -} // end namespace Security +#endif /* _POLICY_DRYRUN_H_ */ diff --git a/SecurityTool/sharedTool/policy_dryrun.m b/SecurityTool/sharedTool/policy_dryrun.m new file mode 100644 index 00000000..dc1668ec --- /dev/null +++ b/SecurityTool/sharedTool/policy_dryrun.m @@ -0,0 +1,272 @@ +#import +#import +#import +#import +#import +#import +#import + +#include "policy_dryrun.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#import "TrustedPeers/TrustedPeers.h" + +#include "tool_errors.h" + +// Depends on a modern enough TrustedPeers framework. +// If the machine doesn't have one installed, set DYLD_FRAMEWORK_PATH + +// Stolen from keychain/SecureObjectSync/SOSEngine.c + +static NSString* getSOSView(id object, NSString* itemClass) { + if (![object isKindOfClass:[NSDictionary class]]) { + return nil; + } + + NSString *viewHint = object[(NSString*)kSecAttrSyncViewHint]; + if (viewHint != nil) { + return viewHint; + } else { + NSString *ag = object[(NSString*)kSecAttrAccessGroup]; + + if ([itemClass isEqualToString: (NSString*)kSecClassKey] && [ag isEqualToString: @"com.apple.security.sos"]) { + return (NSString*)kSOSViewiCloudIdentity; + } else if ([ag isEqualToString: @"com.apple.cfnetwork"]) { + return (NSString*)kSOSViewAutofillPasswords; + } else if ([ag isEqualToString: @"com.apple.safari.credit-cards"]) { + return (NSString*)kSOSViewSafariCreditCards; + } else if ([itemClass isEqualToString: (NSString*)kSecClassGenericPassword]) { + if ([ag isEqualToString: @"apple"] && + [object[(NSString*)kSecAttrService] isEqualToString: @"AirPort"]) { + return (NSString*)kSOSViewWiFi; + } else if ([ag isEqualToString: @"com.apple.sbd"]) { + return (NSString*)kSOSViewBackupBagV0; + } else { + return (NSString*)kSOSViewOtherSyncable; // (genp) + } + } else { + return (NSString*)kSOSViewOtherSyncable; // (inet || keys) + } + } +} + +static inline NSNumber *now_msecs() { + return @(((long)[[NSDate date] timeIntervalSince1970] * 1000)); +} + +static NSString* cloudKitDeviceID() { + __block NSString* ret = nil; + + if (!os_variant_has_internal_diagnostics("com.apple.security")) { + return nil; + } + CKContainer *container = [CKContainer containerWithIdentifier:@"com.apple.security.keychain"]; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + [container fetchCurrentDeviceIDWithCompletionHandler:^(NSString* deviceID, NSError* error) { + if (error != nil) { + NSLog(@"failed to fetch CK deviceID: %@", error); + } else { + ret = deviceID; + } + dispatch_semaphore_signal(sem); + }]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); + return ret; +} + +static void reportStats(unsigned expected_mismatches, unsigned real_mismatches, NSArray* reportedMismatches) { + NSError *error = nil; + NSURLSessionConfiguration *defaultConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + NSURLSession *session = [NSURLSession sessionWithConfiguration:defaultConfiguration]; + NSURL *endpoint = [NSURL URLWithString:@"https://xp.apple.com/report/2/xp_sear_keysync"]; + NSMutableURLRequest *req = [[NSMutableURLRequest alloc] init]; + req.URL = endpoint; + req.HTTPMethod = @"POST"; + NSMutableDictionary *dict = [@{ + @"expectedMismatches": @(expected_mismatches), + @"realMismatches": @(real_mismatches), + @"eventTime": now_msecs(), + @"topic": @"xp_sear_keysync", + @"eventType": @"policy-dryrun", + } mutableCopy]; + NSDictionary *version = CFBridgingRelease(_CFCopySystemVersionDictionary()); + NSString *build = version[(__bridge NSString *)_kCFSystemVersionBuildVersionKey]; + if (build != nil) { + dict[@"build"] = build; + } else { + NSLog(@"Unable to find out build version"); + } + NSString *product = version[(__bridge NSString *)_kCFSystemVersionProductNameKey]; + if (product != nil) { + dict[@"product"] = product; + } else { + NSLog(@"Unable to find out build product"); + } + NSString* ckDeviceID = cloudKitDeviceID(); + if (ckDeviceID) { + dict[@"SFAnalyticsDeviceID"] = ckDeviceID; + } else { + NSLog(@"Unable to fetch CK device ID"); + } + + dict[@"mismatches"] = reportedMismatches; + + NSArray* events = @[dict]; + NSDictionary *wrapper = @{ + @"postTime": @([[NSDate date] timeIntervalSince1970] * 1000), + @"events": events, + }; + NSData* data = [NSJSONSerialization dataWithJSONObject:wrapper options:0 error:&error]; + if (data == nil || error != nil) { + NSLog(@"failed to encode data: %@", error); + return; + } + NSLog(@"logging %@, %@", wrapper, data); + req.HTTPBody = data; + dispatch_semaphore_t sem = dispatch_semaphore_create(0); + NSURLSessionDataTask *task = [session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { + if (error != nil) { + NSLog(@"splunk upload failed: %@", error); + return; + } + NSHTTPURLResponse *httpResp = (NSHTTPURLResponse*)response; + if (httpResp.statusCode != 200) { + NSLog(@"HTTP Post error: %@", httpResp); + } + NSLog(@"%@", httpResp); + if (data != nil) { + size_t length = [data length]; + char *buf = malloc(length); + [data getBytes:buf length:length]; + NSLog(@"%.*s", (int)length, buf); + free(buf); + } + dispatch_semaphore_signal(sem); + }]; + [task resume]; + dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); +} + +int policy_dryrun(int argc, char * const *argv) { + @autoreleasepool { + NSError* error = nil; + // From Swift.policy, policy v5 + + TPPolicyDocument *tpd = [TPPolicyDocument policyDocWithHash:@"SHA256:O/ECQlWhvNlLmlDNh2+nal/yekUC87bXpV3k+6kznSo=" + data:[[NSData alloc] initWithBase64EncodedString: + @"CAUSDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSDAoEaVBvZBIEZnVsbBILCgNNYWMSBGZ1bGwSDAoEaU1hYxIEZnVsbBINCgdBcHBsZVRWEgJ0dhIOCgVXYXRjaBIFd2F0Y2gSFwoOQXVkaW9BY2Nlc3NvcnkSBWF1ZGlvGhsKDEFwcGxpY2F0aW9ucxIEZnVsbBIFd2F0Y2gaHwoQU2VjdXJlT2JqZWN0U3luYxIEZnVsbBIFd2F0Y2gaHAoNRGV2aWNlUGFpcmluZxIEZnVsbBIFd2F0Y2gaGgoLQ3JlZGl0Q2FyZHMSBGZ1bGwSBXdhdGNoGhUKBkhlYWx0aBIEZnVsbBIFd2F0Y2gaLQoTTGltaXRlZFBlZXJzQWxsb3dlZBIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxokChVQcm90ZWN0ZWRDbG91ZFN0b3JhZ2USBGZ1bGwSBXdhdGNoGhcKCEFwcGxlUGF5EgRmdWxsEgV3YXRjaBoZCgpBdXRvVW5sb2NrEgRmdWxsEgV3YXRjaBoWCgdNYW5hdGVlEgRmdWxsEgV3YXRjaBoYCglQYXNzd29yZHMSBGZ1bGwSBXdhdGNoGhUKBkVuZ3JhbRIEZnVsbBIFd2F0Y2gaHgoEV2lGaRIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxoTCgRIb21lEgRmdWxsEgV3YXRjaCIbCgVhdWRpbxIEZnVsbBIFd2F0Y2gSBWF1ZGlvIhMKBGZ1bGwSBGZ1bGwSBXdhdGNoIhUKAnR2EgRmdWxsEgV3YXRjaBICdHYiFAoFd2F0Y2gSBGZ1bGwSBXdhdGNoMiIKFgAEIhICBHZ3aHQKCl5BcHBsZVBheSQSCEFwcGxlUGF5MiYKGAAEIhQCBHZ3aHQKDF5BdXRvVW5sb2NrJBIKQXV0b1VubG9jazIeChQABCIQAgR2d2h0CgheRW5ncmFtJBIGRW5ncmFtMh4KFAAEIhACBHZ3aHQKCF5IZWFsdGgkEgZIZWFsdGgyGgoSAAQiDgIEdndodAoGXkhvbWUkEgRIb21lMiAKFQAEIhECBHZ3aHQKCV5NYW5hdGVlJBIHTWFuYXRlZTI4CiEABCIdAgR2d2h0ChVeTGltaXRlZFBlZXJzQWxsb3dlZCQSE0xpbWl0ZWRQZWVyc0FsbG93ZWQyXQpQAAISHgAEIhoCBHZ3aHQKEl5Db250aW51aXR5VW5sb2NrJBIVAAQiEQIEdndodAoJXkhvbWVLaXQkEhUABCIRAgR2d2h0CgleQXBwbGVUViQSCU5vdFN5bmNlZDIrChsABCIXAgRhZ3JwCg9eWzAtOUEtWl17MTB9XC4SDEFwcGxpY2F0aW9uczLFAQqwAQACEjQAAQoTAAQiDwIFY2xhc3MKBl5nZW5wJAobAAQiFwIEYWdycAoPXmNvbS5hcHBsZS5zYmQkEj0AAQoTAAQiDwIFY2xhc3MKBl5rZXlzJAokAAQiIAIEYWdycAoYXmNvbS5hcHBsZS5zZWN1cml0eS5zb3MkEhkABCIVAgR2d2h0Cg1eQmFja3VwQmFnVjAkEhwABCIYAgR2d2h0ChBeaUNsb3VkSWRlbnRpdHkkEhBTZWN1cmVPYmplY3RTeW5jMmMKWwACEhIABCIOAgR2d2h0CgZeV2lGaSQSQwABChMABCIPAgVjbGFzcwoGXmdlbnAkChMABCIPAgRhZ3JwCgdeYXBwbGUkChUABCIRAgRzdmNlCgleQWlyUG9ydCQSBFdpRmkynQMKgwMAAhIYAAQiFAIEdndodAoMXlBDUy1CYWNrdXAkEhoABCIWAgR2d2h0Cg5eUENTLUNsb3VkS2l0JBIYAAQiFAIEdndodAoMXlBDUy1Fc2Nyb3ckEhUABCIRAgR2d2h0CgleUENTLUZERSQSGgAEIhYCBHZ3aHQKDl5QQ1MtRmVsZHNwYXIkEhoABCIWAgR2d2h0Cg5eUENTLU1haWxEcm9wJBIaAAQiFgIEdndodAoOXlBDUy1NYWlsZHJvcCQSGwAEIhcCBHZ3aHQKD15QQ1MtTWFzdGVyS2V5JBIXAAQiEwIEdndodAoLXlBDUy1Ob3RlcyQSGAAEIhQCBHZ3aHQKDF5QQ1MtUGhvdG9zJBIZAAQiFQIEdndodAoNXlBDUy1TaGFyaW5nJBIeAAQiGgIEdndodAoSXlBDUy1pQ2xvdWRCYWNrdXAkEh0ABCIZAgR2d2h0ChFeUENTLWlDbG91ZERyaXZlJBIaAAQiFgIEdndodAoOXlBDUy1pTWVzc2FnZSQSFVByb3RlY3RlZENsb3VkU3RvcmFnZTI6CisABCInAgRhZ3JwCh9eY29tLmFwcGxlLnNhZmFyaS5jcmVkaXQtY2FyZHMkEgtDcmVkaXRDYXJkczIuCiEABCIdAgRhZ3JwChVeY29tLmFwcGxlLmNmbmV0d29yayQSCVBhc3N3b3JkczJtClwAAhIeAAQiGgIEdndodAoSXkFjY2Vzc29yeVBhaXJpbmckEhoABCIWAgR2d2h0Cg5eTmFub1JlZ2lzdHJ5JBIcAAQiGAIEdndodAoQXldhdGNoTWlncmF0aW9uJBINRGV2aWNlUGFpcmluZzIOCgIABhIIQmFja3N0b3A=" options:0]]; + TPPolicy *policy = [tpd policyWithSecrets:@{} decrypter:nil error:&error]; + if (error != nil) { + NSLog(@"policy error: %@", error); + return 1; + } + if (policy == nil) { + NSLog(@"policy is nil"); + return 1; + } + unsigned real_mismatches = 0; + unsigned expected_mismatches = 0; + NSMutableArray* reportedMismatches = [[NSMutableArray alloc] init]; + + NSArray* keychainClasses = @[(id)kSecClassInternetPassword, + (id)kSecClassGenericPassword, + (id)kSecClassKey, + (id)kSecClassCertificate]; + + for(NSString* itemClass in keychainClasses) { + NSLog(@"itemClass: %@", itemClass); + NSDictionary *query = @{ (id)kSecMatchLimit : (id)kSecMatchLimitAll, + (id)kSecClass : (id)itemClass, + (id)kSecReturnAttributes : @YES, + (id)kSecAttrSynchronizable: @YES, + (id)kSecUseDataProtectionKeychain: @YES, + (id)kSecUseAuthenticationUI : (id)kSecUseAuthenticationUISkip, + }; + + NSArray *result; + + OSStatus status = SecItemCopyMatching((CFDictionaryRef)query, (void*)&result); + if (status) { + if (status == errSecItemNotFound) { + NSLog(@"no items found matching: %@", query); + continue; + } else { + NSLog(@"SecItemCopyMatching(%@) failed: %d", query, (int)status); + return status; + } + } + + if (![result isKindOfClass:[NSArray class]]) { + NSLog(@"expected NSArray result from SecItemCopyMatching"); + return -1; + } + + for (id a in result) { + NSLog(@"%@", a); + NSString *oldView = getSOSView(a, itemClass); + if (oldView != nil) { + NSLog(@"old: %@", oldView); + } + + NSMutableDictionary* mutA = [a mutableCopy]; + mutA[(id)kSecClass] = (id)itemClass; + + NSString* newView = [policy mapKeyToView:mutA]; + if (newView != nil) { + NSLog(@"new: %@", newView); + } + if(oldView == nil ^ newView == nil) { + NSLog(@"real mismatch: old view (%@) != new view (%@)", oldView, newView); + ++real_mismatches; + [reportedMismatches addObject: a]; + + } else if (oldView && newView && ![oldView isEqualToString: newView]) { + if ([oldView hasPrefix:@"PCS-"] && [newView isEqualToString: @"ProtectedCloudStorage"]) { + NSLog(@"(expected PCS mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if([oldView isEqualToString:@"OtherSyncable"] && [newView isEqualToString: @"Applications"]) { + NSLog(@"(expected 3rd party mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if([oldView isEqualToString:@"OtherSyncable"] && [newView isEqualToString: @"Backstop"]) { + NSLog(@"(expected backstop mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if([newView isEqualToString:@"NotSynced"]) { + NSLog(@"(expected NotSynced mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if(([oldView isEqualToString:@"BackupBagV0"] || [oldView isEqualToString:@"iCloudIdentity"]) && [newView isEqualToString:@"SecureObjectSync"]) { + NSLog(@"(expected BackupBag - SecureObjectSync mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else if(([oldView isEqualToString:@"AccessoryPairing"] + || [oldView isEqualToString:@"NanoRegistry"] + || [oldView isEqualToString:@"WatchMigration"]) && [newView isEqualToString:@"DevicePairing"]) { + NSLog(@"(expected DevicePairing mismatch): old view (%@) != new view (%@)", oldView, newView); + ++expected_mismatches; + + } else { + NSLog(@"real mismatch: old view (%@) != new view (%@)", oldView, newView); + ++real_mismatches; + [reportedMismatches addObject: a]; + } + } + } + } + + NSLog(@"%d expected_mismatches", expected_mismatches); + NSLog(@"%d real_mismatches", real_mismatches); + reportStats(expected_mismatches, real_mismatches, reportedMismatches); + } + return 0; +} diff --git a/OSX/sec/SecurityTool/print_cert.c b/SecurityTool/sharedTool/print_cert.c similarity index 100% rename from OSX/sec/SecurityTool/print_cert.c rename to SecurityTool/sharedTool/print_cert.c diff --git a/OSX/sec/SecurityTool/print_cert.h b/SecurityTool/sharedTool/print_cert.h similarity index 100% rename from OSX/sec/SecurityTool/print_cert.h rename to SecurityTool/sharedTool/print_cert.h diff --git a/OSX/utilities/SecurityTool/readline.c b/SecurityTool/sharedTool/readline.c similarity index 100% rename from OSX/utilities/SecurityTool/readline.c rename to SecurityTool/sharedTool/readline.c diff --git a/OSX/utilities/SecurityTool/readline.h b/SecurityTool/sharedTool/readline.h similarity index 100% rename from OSX/utilities/SecurityTool/readline.h rename to SecurityTool/sharedTool/readline.h diff --git a/OSX/sec/Security/Tool/scep.c b/SecurityTool/sharedTool/scep.c similarity index 95% rename from OSX/sec/Security/Tool/scep.c rename to SecurityTool/sharedTool/scep.c index fd9e7a0e..304c9270 100644 --- a/OSX/sec/Security/Tool/scep.c +++ b/SecurityTool/sharedTool/scep.c @@ -24,7 +24,7 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include "SecurityCommands.h" @@ -274,6 +274,10 @@ extern int command_scep(int argc, char * const *argv) scep_subject_name = uuid_cfstring(), scep_subject_alt_name = NULL, scep_capabilities = NULL; + SecCertificateRef ca_certificate = NULL, ra_certificate = NULL; + CFArrayRef cert_array = NULL; + CFDataRef caps_data = NULL; + while ((ch = getopt(argc, argv, "vu:b:c:n:s:h:xo:")) != -1) { switch (ch) @@ -288,9 +292,11 @@ extern int command_scep(int argc, char * const *argv) key_bitsize = atoi(optarg); break; case 'c': + CFReleaseNull(scep_challenge); scep_challenge = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); break; case 'n': + CFReleaseNull(scep_instance_name); scep_instance_name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); break; case 's': @@ -298,15 +304,22 @@ extern int command_scep(int argc, char * const *argv) scep_subject_name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); break; case 'h': + CFReleaseNull(scep_subject_alt_name); scep_subject_alt_name = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); break; case 'x': validate_cert = false; break; case 'o': + CFReleaseNull(scep_capabilities); scep_capabilities = CFStringCreateWithCString(kCFAllocatorDefault, optarg, kCFStringEncodingUTF8); break; default: + CFReleaseNull(scep_subject_name); + CFReleaseNull(scep_capabilities); + CFReleaseNull(scep_challenge); + CFReleaseNull(scep_instance_name); + CFReleaseNull(scep_subject_alt_name); return SHOW_USAGE_MESSAGE; } } @@ -314,8 +327,14 @@ extern int command_scep(int argc, char * const *argv) argc -= optind; argv += optind; - if (argc != 1) + if (argc != 1) { + CFReleaseNull(scep_subject_name); + CFReleaseNull(scep_capabilities); + CFReleaseNull(scep_challenge); + CFReleaseNull(scep_instance_name); + CFReleaseNull(scep_subject_alt_name); return SHOW_USAGE_MESSAGE; + } CFDataRef scep_request = NULL; CFArrayRef issued_certs = NULL; @@ -374,7 +393,6 @@ extern int command_scep(int argc, char * const *argv) used to carry the certificates to the requester, with a Content-Type of application/x-x509-ca-ra-cert. */ - SecCertificateRef ca_certificate = NULL, ra_certificate = NULL; SecCertificateRef ra_encryption_certificate = NULL; CFArrayRef ra_certificates = NULL; CFTypeRef scep_certificates = NULL; @@ -388,7 +406,7 @@ extern int command_scep(int argc, char * const *argv) ca_certificate = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)data); fprintf(stderr, "GetCACert returned a single CA certificate.\n"); } else if (CFEqual(ctype, CFSTR("application/x-x509-ca-ra-cert"))) { - CFArrayRef cert_array = SecCMSCertificatesOnlyMessageCopyCertificates(data); + cert_array = SecCMSCertificatesOnlyMessageCopyCertificates(data); require_noerr(SecSCEPValidateCACertMessage(cert_array, NULL, @@ -401,7 +419,6 @@ extern int command_scep(int argc, char * const *argv) ra_certificates = CFArrayCreate(kCFAllocatorDefault, ra_certs, array_size(ra_certs), &kCFTypeArrayCallBacks); fprintf(stderr, "GetCACert returned a separate signing and encryption certificates for RA.\n"); } - CFRelease(cert_array); } } @@ -456,7 +473,7 @@ extern int command_scep(int argc, char * const *argv) if (!scep_capabilities) { CFURLRef ca_caps_url = scep_url_operation(scep_base_url, CFSTR("GetCACaps"), scep_instance_name); require(ca_caps_url, out); - CFDataRef caps_data = MCNetworkLoadRequest(ca_caps_url, NULL, NULL, NULL, validate_cert); + caps_data = MCNetworkLoadRequest(ca_caps_url, NULL, NULL, NULL, validate_cert); CFRelease(ca_caps_url); if (caps_data) { CFStringRef caps_data_string = CFStringCreateFromExternalRepresentation(kCFAllocatorDefault, caps_data, kCFStringEncodingASCII); @@ -609,6 +626,13 @@ out: CFReleaseSafe(issued_certs); CFReleaseSafe(data); CFReleaseSafe(ctype); + CFReleaseNull(ca_certificate); + CFReleaseNull(scep_capabilities); + CFReleaseNull(scep_challenge); + CFReleaseNull(scep_instance_name); + CFReleaseNull(scep_subject_alt_name); + CFReleaseNull(cert_array); + CFReleaseNull(caps_data); return result; } diff --git a/SecurityTool/security_tool_commands.c b/SecurityTool/sharedTool/security_tool_commands.c similarity index 73% rename from SecurityTool/security_tool_commands.c rename to SecurityTool/sharedTool/security_tool_commands.c index b2dde6c9..3171380e 100644 --- a/SecurityTool/security_tool_commands.c +++ b/SecurityTool/sharedTool/security_tool_commands.c @@ -24,20 +24,20 @@ #include -#include "SecurityTool/SecurityTool.h" +#include "SecurityTool/sharedTool/SecurityTool.h" -#include "SecurityTool/security_tool_commands.h" +#include "SecurityTool/sharedTool/security_tool_commands.h" -#include "SecurityTool/builtin_commands.h" -#include "SecurityTool/sub_commands.h" +#include "SecurityTool/sharedTool/builtin_commands.h" +#include "SecurityTool/sharedTool/sub_commands.h" -#include "SecurityTool/security_tool_commands_table.h" +#include "SecurityTool/sharedTool/security_tool_commands_table.h" const command commands[] = { -#include "SecurityTool/builtin_commands.h" +#include "SecurityTool/sharedTool/builtin_commands.h" -#include "SecurityTool/sub_commands.h" +#include "SecurityTool/sharedTool/sub_commands.h" {} }; diff --git a/OSX/utilities/SecurityTool/security_tool_commands.h b/SecurityTool/sharedTool/security_tool_commands.h similarity index 97% rename from OSX/utilities/SecurityTool/security_tool_commands.h rename to SecurityTool/sharedTool/security_tool_commands.h index b6d601c9..90fca292 100644 --- a/OSX/utilities/SecurityTool/security_tool_commands.h +++ b/SecurityTool/sharedTool/security_tool_commands.h @@ -29,7 +29,7 @@ #ifndef SECURITY_COMMAND #define SECURITY_COMMAND(name, function, parameters, description) int function(int argc, char * const *argv); -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #define SECURITY_COMMAND_IOS(name, function, parameters, description) int function(int argc, char * const *argv); #else #define SECURITY_COMMAND_IOS(name, function, parameters, description) extern int command_not_on_this_platform(int argc, char * const *argv); diff --git a/OSX/utilities/SecurityTool/security_tool_commands_table.h b/SecurityTool/sharedTool/security_tool_commands_table.h similarity index 95% rename from OSX/utilities/SecurityTool/security_tool_commands_table.h rename to SecurityTool/sharedTool/security_tool_commands_table.h index 844f225b..f5bef85a 100644 --- a/OSX/utilities/SecurityTool/security_tool_commands_table.h +++ b/SecurityTool/sharedTool/security_tool_commands_table.h @@ -31,13 +31,13 @@ #undef SECURITY_COMMAND_MAC #define SECURITY_COMMAND(name, function, parameters, description) { name, function, parameters, description }, -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #define SECURITY_COMMAND_IOS(name, function, parameters, description) { name, function, parameters, description }, #else #define SECURITY_COMMAND_IOS(name, function, parameters, description) { name, command_not_on_this_platform, "", "Not available on this platform" }, #endif -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #define SECURITY_COMMAND_MAC(name, function, parameters, description) { name, function, parameters, description }, #else #define SECURITY_COMMAND_MAC(name, function, parameters, description) { name, command_not_on_this_platform, "", "Not available on this platform" }, diff --git a/OSX/sec/Security/Tool/show_certificates.c b/SecurityTool/sharedTool/show_certificates.c similarity index 98% rename from OSX/sec/Security/Tool/show_certificates.c rename to SecurityTool/sharedTool/show_certificates.c index 8d7bb967..a3671b76 100644 --- a/OSX/sec/Security/Tool/show_certificates.c +++ b/SecurityTool/sharedTool/show_certificates.c @@ -24,12 +24,12 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include "SecurityCommands.h" #include "security.h" -#include "SecurityTool/print_cert.h" +#include "SecurityTool/sharedTool/print_cert.h" #include "SecBase64.h" #include #include @@ -39,7 +39,7 @@ #include #include -#include +#include "SecurityTool/sharedTool/tool_errors.h" #include @@ -55,7 +55,7 @@ #include #include -#include +#include "SecurityTool/sharedTool/readline.h" #include #include "keychain_util.h" @@ -492,4 +492,4 @@ int trust_store_show_certificates(int argc, char * const *argv) return result; } -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR diff --git a/OSX/sec/SecurityTool/sos.m b/SecurityTool/sharedTool/sos.m similarity index 67% rename from OSX/sec/SecurityTool/sos.m rename to SecurityTool/sharedTool/sos.m index 0b9b7448..ee18108f 100644 --- a/OSX/sec/SecurityTool/sos.m +++ b/SecurityTool/sharedTool/sos.m @@ -33,7 +33,7 @@ #import #import #import -#import +#include "keychain/SecureObjectSync/SOSControlHelper.h" #import #import #import @@ -58,9 +58,9 @@ _SOSControlSetupInterface(interface); self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0]; - if (self.connection == NULL) + if (self.connection == NULL){ return NULL; - + } self.connection.remoteObjectInterface = interface; [self.connection resume]; @@ -165,6 +165,10 @@ command_sos_stats(__unused int argc, __unused char * const * argv) return 0; } +static void printControlFailureMessage(NSError *error) { + printf("%s", [[NSString stringWithFormat:@"Failed to send messages to soscontrol object: %@\n", error] UTF8String]); +} + int command_sos_control(__unused int argc, __unused char * const * argv) { @@ -174,18 +178,29 @@ command_sos_control(__unused int argc, __unused char * const * argv) bool assertStashAccountKey = false; bool triggerSync = false; NSString *syncingPeer = NULL; + SOSAccountGhostBustingOptions gboptions = 0; + bool gbinfo = false; + bool gbtriggered = false; + bool circleHash = false; static struct option long_options[] = { /* These options set a flag. */ - {"assertStashAccountKey", no_argument, NULL, 'A'}, + {"assertStashAccountKey", no_argument, NULL, 'a'}, {"trigger-sync", optional_argument, NULL, 's'}, + {"circle-hash", optional_argument, NULL, 'H'}, + {"ghostbustByMID", optional_argument, NULL, 'M'}, + {"ghostbustBySerial", optional_argument, NULL, 'S'}, + {"ghostbustiCloudIdentities", optional_argument, NULL, 'I'}, + {"ghostbustByAge", optional_argument, NULL, 'A'}, + {"ghostbustInfo", optional_argument, NULL, 'G'}, + {"ghostbustTriggered", optional_argument, NULL, 'T'}, {0, 0, 0, 0} }; - while ((ch = getopt_long(argc, argv, "A", long_options, &option_index)) != -1) { + while ((ch = getopt_long(argc, argv, "asGHAMSIT", long_options, &option_index)) != -1) { switch (ch) { - case 'A': { + case 'a': { assertStashAccountKey = true; break; } @@ -196,6 +211,33 @@ command_sos_control(__unused int argc, __unused char * const * argv) } break; } + case 'A': { + gboptions |= SOSGhostBustSerialByAge; + break; + } + case 'G': { + gbinfo = true; + break; + } + case 'M': { + gboptions |= SOSGhostBustByMID; + break; + } + case 'S': { + gboptions |= SOSGhostBustBySerialNumber; + break; + } + case 'I': { + gboptions |= SOSGhostBustiCloudIdentities; + break; + } + case 'T': { + gbtriggered = true; + break; + } + case 'H': + circleHash = true; + break; case '?': default: { @@ -209,63 +251,89 @@ command_sos_control(__unused int argc, __unused char * const * argv) if (control == NULL) errx(1, "no SOS control object"); - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - if (triggerSync) { + if( gbtriggered) { + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); + }] ghostBustTriggerTimed:gboptions complete:^(bool ghostBusted, NSError *error) { + if (ghostBusted) { + printf("ghostbusted devices\n"); + } else if (error) { + printf("%s", [[NSString stringWithFormat:@"Failed ghostbusting: %@\n", error] UTF8String]); + } else { + printf("no ghosts found\n"); + } + }]; + } else if( gbinfo) { + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); + }] ghostBustInfo: ^(NSData *json, NSError *error) { + printf("%s\n", [[[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding] UTF8String]); + }]; + } else if (gboptions != 0) { + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); + }] ghostBust:gboptions complete:^(bool ghostBusted, NSError *error) { + if (ghostBusted) { + printf("ghostbusted devices\n"); + } else if (error) { + printf("%s", [[NSString stringWithFormat:@"Failed ghostbusting: %@\n", error] UTF8String]); + } else { + printf("no ghosts found\n"); + } + }]; + } else if (triggerSync) { NSMutableArray *peers = [NSMutableArray array]; if (syncingPeer) { [peers addObject:syncingPeer]; } - [[control.connection remoteObjectProxyWithErrorHandler:^(NSError *error) { - printf("%s", [[NSString stringWithFormat:@"Failed to sending messages to soscontrol object: %@\n", error] UTF8String]); - dispatch_semaphore_signal(sema); + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); }] triggerSync:peers complete:^(bool res, NSError *error) { if (res) { printf("starting to sync was successful\n"); } else { printf("%s", [[NSString stringWithFormat:@"Failed to start sync: %@\n", error] UTF8String]); } - dispatch_semaphore_signal(sema); }]; - dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); } else if (assertStashAccountKey) { - [[control.connection remoteObjectProxyWithErrorHandler:^(NSError *error) { - printf("%s", [[NSString stringWithFormat:@"Failed to sending messages to soscontrol object: %@\n", error] UTF8String]); - dispatch_semaphore_signal(sema); + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); }] assertStashedAccountCredential:^(BOOL res, NSError *error) { if (res) { printf("successfully asserted stashed credential\n"); } else { printf("%s", [[NSString stringWithFormat:@"failed to assert stashed credential: %@\n", error] UTF8String]); } - dispatch_semaphore_signal(sema); }]; - dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + } else if (circleHash) { + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); + }] circleHash:^(NSString *hash, NSError *error) { + if (hash) { + printf("%s", [[NSString stringWithFormat:@"circle hash: %@\n", hash] UTF8String]); + } else { + printf("%s", [[NSString stringWithFormat:@"failed to get circle digest: %@\n", error] UTF8String]); + } + }]; } else { - [[control.connection remoteObjectProxyWithErrorHandler:^(NSError *error) { - printf("%s", [[NSString stringWithFormat:@"Failed to sending messages to soscontrol object: %@\n", error] UTF8String]); - dispatch_semaphore_signal(sema); + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); }] userPublicKey:^(BOOL trusted, NSData *spki, NSError *error) { printf("trusted: %s\n", trusted ? "yes" : "no"); printf("userPublicKey: %s\n", [[spki base64EncodedStringWithOptions:0] UTF8String]); - dispatch_semaphore_signal(sema); }]; - dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); - [[control.connection remoteObjectProxyWithErrorHandler:^(NSError *error) { - printf("%s", [[NSString stringWithFormat:@"Failed to sending messages to soscontrol object: %@\n", error] UTF8String]); - dispatch_semaphore_signal(sema); + [[control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + printControlFailureMessage(error); }] stashedCredentialPublicKey:^(NSData *spki, NSError *error) { NSString *pkey = [spki base64EncodedStringWithOptions:0]; if (pkey == NULL) - pkey = @"no available"; + pkey = @"not available"; printf("cachedCredentialPublicKey: %s\n", [pkey UTF8String]); - dispatch_semaphore_signal(sema); }]; - dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); } } @@ -280,7 +348,7 @@ int command_watchdog(int argc, char* const * argv) if (argc < 3) { printf("getting watchdog parameters...\n"); [[control.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { - printf("%s", [[NSString stringWithFormat:@"Failed to sending messages to soscontrol object: %@\n", error] UTF8String]); + printControlFailureMessage(error); dispatch_semaphore_signal(semaphore); }] getWatchdogParameters:^(NSDictionary* parameters, NSError* error) { if (error) { @@ -301,7 +369,7 @@ int command_watchdog(int argc, char* const * argv) NSString* parameter = [[NSString alloc] initWithUTF8String:argv[1]]; NSInteger value = [[[NSString alloc] initWithUTF8String:argv[2]] integerValue]; [[control.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { - printf("%s", [[NSString stringWithFormat:@"Failed to sending messages to soscontrol object: %@\n", error] UTF8String]); + printControlFailureMessage(error); dispatch_semaphore_signal(semaphore); }] setWatchdogParmeters:@{parameter : @(value)} complete:^(NSError* error) { if (error) { diff --git a/OSX/sec/Security/Tool/spc.c b/SecurityTool/sharedTool/spc.c similarity index 99% rename from OSX/sec/Security/Tool/spc.c rename to SecurityTool/sharedTool/spc.c index 404454d9..70d18399 100644 --- a/OSX/sec/Security/Tool/spc.c +++ b/SecurityTool/sharedTool/spc.c @@ -28,7 +28,7 @@ */ #include -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include "SecurityCommands.h" @@ -714,4 +714,4 @@ out: } -#endif // TARGET_OS_EMBEDDED +#endif // TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR diff --git a/SecurityTool/sub_commands.h b/SecurityTool/sharedTool/sub_commands.h similarity index 75% rename from SecurityTool/sub_commands.h rename to SecurityTool/sharedTool/sub_commands.h index 3c719493..de949106 100644 --- a/SecurityTool/sub_commands.h +++ b/SecurityTool/sharedTool/sub_commands.h @@ -25,9 +25,9 @@ // This file can't be once, it gets included multiple times to get definitions and declarations. -#include "Security/Tool/SecurityCommands.h" -#include "SOSCircle/Tool/keychain_sync.h" -#include "SOSCircle/Tool/keychain_sync_test.h" -#include "SOSCircle/Tool/keychain_log.h" -#include "SOSCircle/Tool/syncbackup.h" -#include "SOSCircle/Tool/recovery_key.h" +#include "SecurityTool/sharedTool/SecurityCommands.h" +#include "keychain/SecureObjectSync/Tool/keychain_sync.h" +#include "keychain/SecureObjectSync/Tool/keychain_sync_test.h" +#include "keychain/SecureObjectSync/Tool/keychain_log.h" +#include "keychain/SecureObjectSync/Tool/syncbackup.h" +#include "keychain/SecureObjectSync/Tool/recovery_key.h" diff --git a/OSX/sec/SecurityTool/syncbubble.m b/SecurityTool/sharedTool/syncbubble.m similarity index 99% rename from OSX/sec/SecurityTool/syncbubble.m rename to SecurityTool/sharedTool/syncbubble.m index 2f0d8722..70295a8d 100644 --- a/OSX/sec/SecurityTool/syncbubble.m +++ b/SecurityTool/sharedTool/syncbubble.m @@ -58,6 +58,4 @@ command_bubble(__unused int argc, __unused char * const * argv) errx(1, "%s", [[NSString stringWithFormat:@"sync bubble failed to inflate: %@\n", error] UTF8String]); } } - - return 0; } diff --git a/OSX/sec/SecurityTool/tool_errors.h b/SecurityTool/sharedTool/tool_errors.h similarity index 97% rename from OSX/sec/SecurityTool/tool_errors.h rename to SecurityTool/sharedTool/tool_errors.h index 8c8ef6eb..2d1602ed 100644 --- a/OSX/sec/SecurityTool/tool_errors.h +++ b/SecurityTool/sharedTool/tool_errors.h @@ -32,7 +32,7 @@ #include #include -#include "SecurityTool/SecurityTool.h" +#include "SecurityTool/sharedTool/SecurityTool.h" static const char * sec_errstr(int err) diff --git a/OSX/sec/Security/Tool/trust_update.m b/SecurityTool/sharedTool/trust_update.m similarity index 69% rename from OSX/sec/Security/Tool/trust_update.m rename to SecurityTool/sharedTool/trust_update.m index adf5453a..17323408 100644 --- a/OSX/sec/Security/Tool/trust_update.m +++ b/SecurityTool/sharedTool/trust_update.m @@ -55,27 +55,49 @@ static int check_OTA_Supplementals_asset(void) { return 0; } +static int check_OTA_sec_experiment_asset(void) { + CFErrorRef error = NULL; + uint64_t version = SecTrustOTASecExperimentGetUpdatedAsset(&error); + if (error) { + CFStringRef errorDescription = CFErrorCopyDescription(error); + if (errorDescription) { + char *errMsg = CFStringToCString(errorDescription); + fprintf(stdout, "Update failed: %s\n", errMsg); + if (errMsg) { free(errMsg); } + CFRelease(errorDescription); + } else { + fprintf(stdout, "Update failed: no description\n"); + } + CFRelease(error); + } else { + fprintf(stdout, "Updated succeeded\n"); + } + if (version != 0) { + fprintf(stdout, "Asset Content Version: %llu\n", version); + } else { + return 1; + } + return 0; +} + int check_trust_update(int argc, char * const *argv) { int arg; - bool check_trust_supplementals = false; if (argc == 1) { return SHOW_USAGE_MESSAGE; } - while ((arg = getopt(argc, argv, "s")) != -1) { + while ((arg = getopt(argc, argv, "se")) != -1) { switch(arg) { case 's': - check_trust_supplementals = true; - break; + return check_OTA_Supplementals_asset(); + case 'e': + return check_OTA_sec_experiment_asset(); case '?': default: return SHOW_USAGE_MESSAGE; } } - if (check_trust_supplementals) { - return check_OTA_Supplementals_asset(); - } return 0; } diff --git a/OSX/sec/Security/Tool/verify_cert.c b/SecurityTool/sharedTool/verify_cert.c similarity index 100% rename from OSX/sec/Security/Tool/verify_cert.c rename to SecurityTool/sharedTool/verify_cert.c diff --git a/OSX/sec/SecurityTool/whoami.m b/SecurityTool/sharedTool/whoami.m similarity index 100% rename from OSX/sec/SecurityTool/whoami.m rename to SecurityTool/sharedTool/whoami.m diff --git a/SharedMocks/NSXPCConnectionMock.h b/SharedMocks/NSXPCConnectionMock.h new file mode 100644 index 00000000..aa4f448c --- /dev/null +++ b/SharedMocks/NSXPCConnectionMock.h @@ -0,0 +1,18 @@ +// +// NSXPCConnectionMock.h +// Security_ios +// +// Created by Love Hörnquist Åstrand on 12/16/18. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSXPCConnectionMock : NSObject +- (instancetype) initWithRealObject:(id)reality; +- (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler; +- (id)synchronousRemoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler; +@end + +NS_ASSUME_NONNULL_END diff --git a/SharedMocks/NSXPCConnectionMock.m b/SharedMocks/NSXPCConnectionMock.m new file mode 100644 index 00000000..f667d23c --- /dev/null +++ b/SharedMocks/NSXPCConnectionMock.m @@ -0,0 +1,34 @@ +// +// NSXPCConnectionMock.m +// Security_ios +// +// Created by Love Hörnquist Åstrand on 12/16/18. +// + +#import "NSXPCConnectionMock.h" + +@interface NSXPCConnectionMock () +@property id reality; +@end + +@implementation NSXPCConnectionMock +- (instancetype) initWithRealObject:(id)reality +{ + self = [super init]; + if (self) { + _reality = reality; + } + return self; +} +- (id)remoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler +{ + (void)failureHandler; + return _reality; +} +- (id)synchronousRemoteObjectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler +{ + (void)failureHandler; + return _reality; +} + +@end diff --git a/SharedWebCredentialViewService/SWCViewController.m b/SharedWebCredentialViewService/SWCViewController.m index f48c2a73..25e643ca 100755 --- a/SharedWebCredentialViewService/SWCViewController.m +++ b/SharedWebCredentialViewService/SWCViewController.m @@ -9,7 +9,7 @@ #import "SWCViewController.h" #import #import - +#import #import #import @@ -88,9 +88,9 @@ const NSString* SWC_SERVER_KEY = @"srvr"; self.selectionStyle = UITableViewCellSelectionStyleNone; - self.backgroundColor = [UIColor colorWithWhite:0.1 alpha:0.005]; + self.backgroundColor = [UIColor systemBackgroundColor]; - self.textLabel.textColor = [UIColor blackColor]; + self.textLabel.textColor = [UIColor labelColor]; self.textLabel.textAlignment = NSTextAlignmentLeft; self.textLabel.adjustsFontSizeToFitWidth = YES; self.textLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; @@ -98,7 +98,7 @@ const NSString* SWC_SERVER_KEY = @"srvr"; NSString *title = [dict objectForKey:SWC_ACCOUNT_KEY]; self.textLabel.text = title ? title : NSLocalizedString(@"--", nil); - self.detailTextLabel.textColor = [UIColor darkGrayColor]; + self.detailTextLabel.textColor = [UIColor secondaryLabelColor]; self.detailTextLabel.textAlignment = NSTextAlignmentLeft; self.detailTextLabel.adjustsFontSizeToFitWidth = YES; self.detailTextLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; @@ -107,11 +107,10 @@ const NSString* SWC_SERVER_KEY = @"srvr"; self.detailTextLabel.text = subtitle ? subtitle : NSLocalizedString(@"--", nil); self.backgroundView = [[UIView alloc] init]; - self.backgroundView.backgroundColor = self.backgroundColor; - - self.imageView.image = [self _checkmarkImage: NO]; + self.backgroundView.backgroundColor = [UIColor systemBackgroundColor]; + + self.imageView.image = [UIImage symbolImageNamed:@"checkmark"]; self.imageView.hidden = YES; - } return self; @@ -164,13 +163,13 @@ const NSString* SWC_SERVER_KEY = @"srvr"; if (!_bottomLine) { CGRect rectZero = CGRectMake(0, 0, 0, 0); _bottomLine = [[UIView alloc] initWithFrame:rectZero]; - _bottomLine.backgroundColor = [UIColor colorWithWhite:.5 alpha:.5]; + _bottomLine.backgroundColor = [UIColor separatorColor]; [self.backgroundView addSubview:_bottomLine]; } if (!_bottomLineSelected) { CGRect rectZero = CGRectMake(0, 0, 0, 0); _bottomLineSelected = [[UIView alloc] initWithFrame:rectZero]; - _bottomLineSelected.backgroundColor = [UIColor colorWithWhite:.5 alpha:.5]; + _bottomLineSelected.backgroundColor = [UIColor separatorColor]; [self.selectedBackgroundView addSubview: _bottomLineSelected]; } @@ -195,13 +194,13 @@ const NSString* SWC_SERVER_KEY = @"srvr"; if (!_topLine) { CGRect rectZero = CGRectMake(0, 0, 0, 0); _topLine = [[UIView alloc] initWithFrame:rectZero]; - _topLine.backgroundColor = [UIColor colorWithWhite:.5 alpha:.5]; + _topLine.backgroundColor = [UIColor separatorColor]; [self.backgroundView addSubview:_topLine]; } if (!_topLineSelected) { CGRect rectZero = CGRectMake(0, 0, 0, 0); _topLineSelected = [[UIView alloc] initWithFrame:rectZero]; - _topLineSelected.backgroundColor = [UIColor colorWithWhite:.5 alpha:.5]; + _topLineSelected.backgroundColor = [UIColor separatorColor]; [self.selectedBackgroundView addSubview: _topLineSelected]; } @@ -264,7 +263,7 @@ const NSString* SWC_SERVER_KEY = @"srvr"; _table = [[UITableView alloc] init]; [_table setTranslatesAutoresizingMaskIntoConstraints:NO]; [_table setAutoresizingMask:UIViewAutoresizingNone]; - [_table setBackgroundColor:[UIColor clearColor]]; + [_table setBackgroundColor:[UIColor systemBackgroundColor]]; [_table setSeparatorStyle:UITableViewCellSeparatorStyleNone]; } [_table sizeToFit]; @@ -313,8 +312,8 @@ const NSString* SWC_SERVER_KEY = @"srvr"; CGFloat scale = [[UIScreen mainScreen] scale]; table.layer.borderWidth = 1.0 / scale; - table.layer.borderColor = [UIColor colorWithWhite:.5 alpha:.5].CGColor; - + table.layer.borderColor = [UIColor opaqueSeparatorColor].CGColor; + [self setPreferredContentSize:CGSizeMake(0, manyCredentialsHeight + 20.0)]; } else if ([_credentials count] == 2) { diff --git a/base/SecBase.h b/base/SecBase.h index f23881ec..104b0315 100644 --- a/base/SecBase.h +++ b/base/SecBase.h @@ -26,7 +26,7 @@ #include #include -#include +#include // Truth table for following declarations: // @@ -71,24 +71,25 @@ #define SEC_DEPRECATED_ATTRIBUTE #endif +#define CSSM_DEPRECATED API_DEPRECATED("CSSM is not supported", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) + __BEGIN_DECLS CF_ASSUME_NONNULL_BEGIN CF_IMPLICIT_BRIDGING_ENABLED - -#if SEC_OS_IPHONE -#define SECTYPE(a) __##a -#elif SEC_OS_OSX -#define SECTYPE(a) Opaque##a##Ref -#endif +#define SECURITY_TYPE_UNIFICATION 1 /*! @typedef SecCertificateRef @abstract CFType representing a X.509 certificate. See SecCertificate.h for details. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecCertificate) *SecCertificateRef; +typedef struct CF_BRIDGED_TYPE(id) __SecCertificate *SecCertificateRef; + +#if TARGET_OS_OSX +typedef struct __SecCertificate OpaqueSecCertificateRef; +#endif /*! @typedef SecIdentityRef @@ -96,53 +97,61 @@ typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecCertificate) *SecCertificateRef; a SecKeyRef and an associated SecCertificateRef. See SecIdentity.h for details. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecIdentity) *SecIdentityRef; +typedef struct CF_BRIDGED_TYPE(id) __SecIdentity *SecIdentityRef; + +#if TARGET_OS_OSX +typedef struct __SecIdentity OpaqueSecIdentityRef; +#endif /*! @typedef SecKeyRef @abstract CFType representing a cryptographic key. See SecKey.h for details. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKey) *SecKeyRef; +typedef struct CF_BRIDGED_TYPE(id) __SecKey *SecKeyRef; + +#if TARGET_OS_OSX +typedef struct __SecKey OpaqueSecKeyRef; +#endif /*! @typedef SecPolicyRef @abstract CFType representing a X.509 certificate trust policy. See SecPolicy.h for details. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPolicy) *SecPolicyRef; +typedef struct CF_BRIDGED_TYPE(id) __SecPolicy *SecPolicyRef; /*! @typedef SecAccessControl @abstract CFType representing access control for an item. SecAccessControl.h for details. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccessControl) *SecAccessControlRef; +typedef struct CF_BRIDGED_TYPE(id) __SecAccessControl *SecAccessControlRef; /*! @typedef SecKeychainRef @abstract Contains information about a keychain. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychain) *SecKeychainRef +typedef struct CF_BRIDGED_TYPE(id) __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 API_UNAVAILABLE(ios); +typedef struct CF_BRIDGED_TYPE(id) __SecKeychainItem *SecKeychainItemRef API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecKeychainSearchRef @abstract Contains information about a keychain search. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecKeychainSearch) *SecKeychainSearchRef API_UNAVAILABLE(ios); +typedef struct CF_BRIDGED_TYPE(id) __SecKeychainSearch *SecKeychainSearchRef API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecKeychainAttrType @abstract Represents a keychain attribute type. */ -typedef OSType SecKeychainAttrType API_UNAVAILABLE(ios); +typedef OSType SecKeychainAttrType API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @struct SecKeychainAttribute @@ -151,19 +160,19 @@ typedef OSType SecKeychainAttrType API_UNAVAILABLE(ios); @field length The length of the buffer pointed to by data. @field data A pointer to the attribute data. */ -struct API_UNAVAILABLE(ios) SecKeychainAttribute +struct API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) SecKeychainAttribute { SecKeychainAttrType tag; UInt32 length; void * __nullable data; }; -typedef struct SecKeychainAttribute SecKeychainAttribute API_UNAVAILABLE(ios); +typedef struct SecKeychainAttribute SecKeychainAttribute API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecKeychainAttributePtr @abstract Represents a pointer to a keychain attribute structure. */ -typedef SecKeychainAttribute *SecKeychainAttributePtr API_UNAVAILABLE(ios); +typedef SecKeychainAttribute *SecKeychainAttributePtr API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecKeychainAttributeList @@ -171,42 +180,46 @@ typedef SecKeychainAttribute *SecKeychainAttributePtr API_UNAVAILABLE(ios); @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 API_UNAVAILABLE(ios) SecKeychainAttributeList +struct API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) SecKeychainAttributeList { UInt32 count; SecKeychainAttribute * __nullable attr; }; -typedef struct SecKeychainAttributeList SecKeychainAttributeList API_UNAVAILABLE(ios); +typedef struct SecKeychainAttributeList SecKeychainAttributeList API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecKeychainStatus @abstract Represents the status of a keychain. */ -typedef UInt32 SecKeychainStatus API_UNAVAILABLE(ios); +typedef UInt32 SecKeychainStatus API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecTrustedApplicationRef @abstract Contains information about a trusted application. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrustedApplication) *SecTrustedApplicationRef API_UNAVAILABLE(ios); +typedef struct CF_BRIDGED_TYPE(id) __SecTrustedApplication *SecTrustedApplicationRef API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecAccessRef @abstract Contains information about an access. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecAccess) *SecAccessRef API_UNAVAILABLE(ios); +typedef struct CF_BRIDGED_TYPE(id) __SecAccess *SecAccessRef API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); + +#if TARGET_OS_OSX +typedef struct __SecAccess OpaqueSecAccessRef; +#endif /*! @typedef SecACLRef @abstract Contains information about an access control list (ACL) entry. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecTrust) *SecACLRef API_UNAVAILABLE(ios); +typedef struct CF_BRIDGED_TYPE(id) __SecACL *SecACLRef API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecPasswordRef @abstract Contains information about a password. */ -typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef API_UNAVAILABLE(ios); +typedef struct CF_BRIDGED_TYPE(id) __SecPassword *SecPasswordRef API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @typedef SecKeychainAttributeInfo @@ -216,13 +229,13 @@ typedef struct CF_BRIDGED_TYPE(id) SECTYPE(SecPassword) *SecPasswordRef API_UNAV @field format A pointer to the first CSSM_DB_ATTRIBUTE_FORMAT in the array. @discussion Each tag and format item form a pair. */ -struct API_UNAVAILABLE(ios) SecKeychainAttributeInfo +struct API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) SecKeychainAttributeInfo { UInt32 count; UInt32 *tag; UInt32 * __nullable format; }; -typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo API_UNAVAILABLE(ios); +typedef struct SecKeychainAttributeInfo SecKeychainAttributeInfo API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecCopyErrorMessageString @@ -235,15 +248,13 @@ __nullable CFStringRef SecCopyErrorMessageString(OSStatus status, void * __nullable reserved) __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_11_3); -#undef SECTYPE - /*! @enum Security Error Codes @abstract Result codes returned from Security framework functions. @constant errSecSuccess No error. @constant errSecUnimplemented Function or operation not implemented. -@constant errSecDskFull Disk Full error. +@constant errSecDiskFull Disk Full error. @constant errSecIO I/O error. @constant errSecParam One or more parameters passed to a function were not valid. @constant errSecWrPerm Write permissions error. @@ -312,7 +323,7 @@ CF_ENUM(OSStatus) errSecSuccess = 0, /* No error. */ errSecUnimplemented = -4, /* Function or operation not implemented. */ errSecDiskFull = -34, /* The disk is full. */ - errSecDskFull = -34, + errSecDskFull __attribute__((deprecated("use errSecDiskFull"))) = errSecDiskFull, errSecIO = -36, /* I/O error. */ errSecOpWr = -49, /* File already open with write permission. */ errSecParam = -50, /* One or more parameters passed to a function were not valid. */ @@ -690,9 +701,190 @@ CF_ENUM(OSStatus) errSecTimestampWaiting = -67896, /* A timestamp transaction is waiting. */ errSecTimestampRevocationWarning = -67897, /* A timestamp authority revocation warning was issued. */ errSecTimestampRevocationNotification = -67898, /* A timestamp authority revocation notification was issued. */ + errSecCertificatePolicyNotAllowed = -67899, /* The requested policy is not allowed for this certificate. */ + errSecCertificateNameNotAllowed = -67900, /* The requested name is not allowed for this certificate. */ + errSecCertificateValidityPeriodTooLong = -67901, /* The validity period in the certificate exceeds the maximum allowed. */ }; +/*! + @enum SecureTransport Error Codes + @abstract Result codes returned from SecureTransport and SecProtocol functions. This is also the domain + for TLS errors in the network stack. + + @constant errSSLProtocol SSL protocol error + @constant errSSLNegotiation Cipher Suite negotiation failure + @constant errSSLFatalAlert Fatal alert + @constant errSSLWouldBlock I/O would block (not fatal) + @constant errSSLSessionNotFound attempt to restore an unknown session + @constant errSSLClosedGraceful connection closed gracefully + @constant errSSLClosedAbort connection closed via error + @constant errSSLXCertChainInvalid invalid certificate chain + @constant errSSLBadCert bad certificate format + @constant errSSLCrypto underlying cryptographic error + @constant errSSLInternal Internal error + @constant errSSLModuleAttach module attach failure + @constant errSSLUnknownRootCert valid cert chain, untrusted root + @constant errSSLNoRootCert cert chain not verified by root + @constant errSSLCertExpired chain had an expired cert + @constant errSSLCertNotYetValid chain had a cert not yet valid + @constant errSSLClosedNoNotify server closed session with no notification + @constant errSSLBufferOverflow insufficient buffer provided + @constant errSSLBadCipherSuite bad SSLCipherSuite + @constant errSSLPeerUnexpectedMsg unexpected message received + @constant errSSLPeerBadRecordMac bad MAC + @constant errSSLPeerDecryptionFail decryption failed + @constant errSSLPeerRecordOverflow record overflow + @constant errSSLPeerDecompressFail decompression failure + @constant errSSLPeerHandshakeFail handshake failure + @constant errSSLPeerBadCert misc. bad certificate + @constant errSSLPeerUnsupportedCert bad unsupported cert format + @constant errSSLPeerCertRevoked certificate revoked + @constant errSSLPeerCertExpired certificate expired + @constant errSSLPeerCertUnknown unknown certificate + @constant errSSLIllegalParam illegal parameter + @constant errSSLPeerUnknownCA unknown Cert Authority + @constant errSSLPeerAccessDenied access denied + @constant errSSLPeerDecodeError decoding error + @constant errSSLPeerDecryptError decryption error + @constant errSSLPeerExportRestriction export restriction + @constant errSSLPeerProtocolVersion bad protocol version + @constant errSSLPeerInsufficientSecurity insufficient security + @constant errSSLPeerInternalError internal error + @constant errSSLPeerUserCancelled user canceled + @constant errSSLPeerNoRenegotiation no renegotiation allowed + @constant errSSLPeerAuthCompleted peer cert is valid, or was ignored if verification disabled + @constant errSSLClientCertRequested server has requested a client cert + @constant errSSLHostNameMismatch peer host name mismatch + @constant errSSLConnectionRefused peer dropped connection before responding + @constant errSSLDecryptionFail decryption failure + @constant errSSLBadRecordMac bad MAC + @constant errSSLRecordOverflow record overflow + @constant errSSLBadConfiguration configuration error + @constant errSSLUnexpectedRecord unexpected (skipped) record in DTLS + @constant errSSLWeakPeerEphemeralDHKey weak ephemeral dh key + @constant errSSLClientHelloReceived SNI + @constant errSSLTransportReset transport (socket) shutdown, e.g., TCP RST or FIN. + @constant errSSLNetworkTimeout network timeout triggered + @constant errSSLConfigurationFailed TLS configuration failed + @constant errSSLUnsupportedExtension unsupported TLS extension + @constant errSSLUnexpectedMessage peer rejected unexpected message + @constant errSSLDecompressFail decompression failed + @constant errSSLHandshakeFail handshake failed + @constant errSSLDecodeError decode failed + @constant errSSLInappropriateFallback inappropriate fallback + @constant errSSLMissingExtension missing extension + @constant errSSLBadCertificateStatusResponse bad OCSP response + @constant errSSLCertificateRequired certificate required + @constant errSSLUnknownPSKIdentity unknown PSK identity + @constant errSSLUnrecognizedName unknown or unrecognized name + @constant errSSLATSViolation ATS violation + @constant errSSLATSMinimumVersionViolation ATS violation: minimum protocol version is not ATS compliant + @constant errSSLATSCiphersuiteViolation ATS violation: selected ciphersuite is not ATS compliant + @constant errSSLATSMinimumKeySizeViolation ATS violation: peer key size is not ATS compliant + @constant errSSLATSLeafCertificateHashAlgorithmViolation ATS violation: peer leaf certificate hash algorithm is not ATS compliant + @constant errSSLATSCertificateHashAlgorithmViolation ATS violation: peer certificate hash algorithm is not ATS compliant + @constant errSSLATSCertificateTrustViolation ATS violation: peer certificate is not issued by trusted peer + */ + +/* + Note: the comments that appear after these errors are used to create SecErrorMessages.strings. + The comments must not be multi-line, and should be in a form meaningful to an end user. If + a different or additional comment is needed, it can be put in the header doc format, or on a + line that does not start with errZZZ. + */ +CF_ENUM(OSStatus) { + errSSLProtocol = -9800, /* SSL protocol error */ + errSSLNegotiation = -9801, /* Cipher Suite negotiation failure */ + errSSLFatalAlert = -9802, /* Fatal alert */ + errSSLWouldBlock = -9803, /* I/O would block (not fatal) */ + errSSLSessionNotFound = -9804, /* attempt to restore an unknown session */ + errSSLClosedGraceful = -9805, /* connection closed gracefully */ + errSSLClosedAbort = -9806, /* connection closed via error */ + errSSLXCertChainInvalid = -9807, /* invalid certificate chain */ + errSSLBadCert = -9808, /* bad certificate format */ + errSSLCrypto = -9809, /* underlying cryptographic error */ + errSSLInternal = -9810, /* Internal error */ + errSSLModuleAttach = -9811, /* module attach failure */ + errSSLUnknownRootCert = -9812, /* valid cert chain, untrusted root */ + errSSLNoRootCert = -9813, /* cert chain not verified by root */ + errSSLCertExpired = -9814, /* chain had an expired cert */ + errSSLCertNotYetValid = -9815, /* chain had a cert not yet valid */ + errSSLClosedNoNotify = -9816, /* server closed session with no notification */ + errSSLBufferOverflow = -9817, /* insufficient buffer provided */ + errSSLBadCipherSuite = -9818, /* bad SSLCipherSuite */ + + /* fatal errors detected by peer */ + errSSLPeerUnexpectedMsg = -9819, /* unexpected message received */ + errSSLPeerBadRecordMac = -9820, /* bad MAC */ + errSSLPeerDecryptionFail = -9821, /* decryption failed */ + errSSLPeerRecordOverflow = -9822, /* record overflow */ + errSSLPeerDecompressFail = -9823, /* decompression failure */ + errSSLPeerHandshakeFail = -9824, /* handshake failure */ + errSSLPeerBadCert = -9825, /* misc. bad certificate */ + errSSLPeerUnsupportedCert = -9826, /* bad unsupported cert format */ + errSSLPeerCertRevoked = -9827, /* certificate revoked */ + errSSLPeerCertExpired = -9828, /* certificate expired */ + errSSLPeerCertUnknown = -9829, /* unknown certificate */ + errSSLIllegalParam = -9830, /* illegal parameter */ + errSSLPeerUnknownCA = -9831, /* unknown Cert Authority */ + errSSLPeerAccessDenied = -9832, /* access denied */ + errSSLPeerDecodeError = -9833, /* decoding error */ + errSSLPeerDecryptError = -9834, /* decryption error */ + errSSLPeerExportRestriction = -9835, /* export restriction */ + errSSLPeerProtocolVersion = -9836, /* bad protocol version */ + errSSLPeerInsufficientSecurity = -9837, /* insufficient security */ + errSSLPeerInternalError = -9838, /* internal error */ + errSSLPeerUserCancelled = -9839, /* user canceled */ + errSSLPeerNoRenegotiation = -9840, /* no renegotiation allowed */ + + /* non-fatal result codes */ + errSSLPeerAuthCompleted = -9841, /* peer cert is valid, or was ignored if verification disabled */ + errSSLClientCertRequested = -9842, /* server has requested a client cert */ + + /* more errors detected by us */ + errSSLHostNameMismatch = -9843, /* peer host name mismatch */ + errSSLConnectionRefused = -9844, /* peer dropped connection before responding */ + errSSLDecryptionFail = -9845, /* decryption failure */ + errSSLBadRecordMac = -9846, /* bad MAC */ + errSSLRecordOverflow = -9847, /* record overflow */ + errSSLBadConfiguration = -9848, /* configuration error */ + errSSLUnexpectedRecord = -9849, /* unexpected (skipped) record in DTLS */ + errSSLWeakPeerEphemeralDHKey = -9850, /* weak ephemeral dh key */ + + /* non-fatal result codes */ + errSSLClientHelloReceived = -9851, /* SNI */ + + /* fatal errors resulting from transport or networking errors */ + errSSLTransportReset = -9852, /* transport (socket) shutdown, e.g., TCP RST or FIN. */ + errSSLNetworkTimeout = -9853, /* network timeout triggered */ + + /* fatal errors resulting from software misconfiguration */ + errSSLConfigurationFailed = -9854, /* TLS configuration failed */ + + /* additional errors */ + errSSLUnsupportedExtension = -9855, /* unsupported TLS extension */ + errSSLUnexpectedMessage = -9856, /* peer rejected unexpected message */ + errSSLDecompressFail = -9857, /* decompression failed */ + errSSLHandshakeFail = -9858, /* handshake failed */ + errSSLDecodeError = -9859, /* decode failed */ + errSSLInappropriateFallback = -9860, /* inappropriate fallback */ + errSSLMissingExtension = -9861, /* missing extension */ + errSSLBadCertificateStatusResponse = -9862, /* bad OCSP response */ + errSSLCertificateRequired = -9863, /* certificate required */ + errSSLUnknownPSKIdentity = -9864, /* unknown PSK identity */ + errSSLUnrecognizedName = -9865, /* unknown or unrecognized name */ + + /* ATS compliance violation errors */ + errSSLATSViolation = -9880, /* ATS violation */ + errSSLATSMinimumVersionViolation = -9881, /* ATS violation: minimum protocol version is not ATS compliant */ + errSSLATSCiphersuiteViolation = -9882, /* ATS violation: selected ciphersuite is not ATS compliant */ + errSSLATSMinimumKeySizeViolation = -9883, /* ATS violation: peer key size is not ATS compliant */ + errSSLATSLeafCertificateHashAlgorithmViolation = -9884, /* ATS violation: peer leaf certificate hash algorithm is not ATS compliant */ + errSSLATSCertificateHashAlgorithmViolation = -9885, /* ATS violation: peer certificate hash algorithm is not ATS compliant */ + errSSLATSCertificateTrustViolation = -9886, /* ATS violation: peer certificate is not issued by trusted peer */ +}; + CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/base/Security.h b/base/Security.h index c5c4914c..e4e5435d 100644 --- a/base/Security.h +++ b/base/Security.h @@ -85,7 +85,6 @@ /* Code Signing */ #include #include -#include #include #include diff --git a/ckcdiagnose/ckcdiagnose.sh b/ckcdiagnose/ckcdiagnose.sh deleted file mode 100755 index d503b726..00000000 --- a/ckcdiagnose/ckcdiagnose.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/sh - -# Poor man's option parsing. -# Replace with shift/case once more options come along. -SHORT=0 -if [ "$1" == "-s" ]; then - SHORT=1 -fi - -PRODUCT_NAME=$(sw_vers -productName) -PRODUCT_VERSION=$(sw_vers -buildVersion) -HOSTNAME=$(hostname -s) -NOW=$(date "+%Y%m%d%H%M%S") - -case $PRODUCT_NAME in - *"OS X") - PROD=OSX - secd=secd - secexec=security2 - OUTPUTPARENT=/var/tmp - CRASHDIR=/Library/Logs/DiagnosticReports - CSDIR=$HOME/Library/Logs/CloudServices - SECLOGPATH=/var/log/module/com.apple.securityd - syd=/System/Library/PrivateFrameworks/SyncedDefaults.framework/Support/syncdefaultsd - kvsutil=/AppleInternal/Applications/kvsutil - ;; - *) - PROD=IOS - secd=securityd - secexec=security - OUTPUTPARENT=/Library/Logs/CrashReporter - CRASHDIR=/var/mobile/Library/Logs/CrashReporter - CSDIR=$CRASHDIR/DiagnosticLogs/CloudServices - SECLOGPATH=/var/mobile/Library/Logs/CrashReporter/DiagnosticLogs - syd=/System/Library/PrivateFrameworks/SyncedDefaults.framework/Support/syncdefaultsd - kvsutil=/usr/local/bin/kvsutil - ;; -esac - -if (( ! $SHORT )); then - OUTPUTBASE=ckcdiagnose_${HOSTNAME}_${PRODUCT_VERSION}_${NOW} -else - OUTPUTBASE=ckcdiagnose_snapshot_${HOSTNAME}_${PRODUCT_VERSION}_${NOW} -fi -OUTPUT=$OUTPUTPARENT/$OUTPUTBASE - -mkdir $OUTPUT - -if [ "$PROD" = "IOS" ]; then - while !(/usr/local/bin/profilectl cpstate | grep -Eq 'Unlocked|Disabled'); do - echo Please ensure that your device is unlocked and press Enter. >&2 - read enter - done -fi - -( -echo Outputting to $OUTPUT -set -x - -sw_vers > $OUTPUT/sw_vers.log - -$secexec sync -D > $OUTPUT/syncD.log -$secexec sync -i > $OUTPUT/synci.log -$secexec sync -L > $OUTPUT/syncL.log - -(( $SHORT )) || ([ -x $kvsutil ] && $kvsutil show com.apple.security.cloudkeychainproxy3 > $OUTPUT/kvsutil_show.txt 2>&1) - -if [ "$PROD" == "OSX" ]; then - $secexec item -g class=genp,nleg=1,svce="iCloud Keychain Account Meta-data" > $OUTPUT/ickcmetadata.log - $secexec item -g class=genp,nleg=1,acct=engine-state > $OUTPUT/engine-state.log -elif [ "$PROD" == "IOS" ]; then - $secexec item -g class=genp,svce="iCloud Keychain Account Meta-data" > $OUTPUT/ickcmetadata.log - $secexec item -g class=genp,acct=engine-state > $OUTPUT/engine-state.log -fi - -# In preparation, before getting any of the logs, query all classes, -# just in order to excercise the decryption and corruption -# verification for all items. This will log errors and simulated crashes -# if any of the items should turn out corrupted. -# The items are NOT saved in the diagnostic log, because they potentially -# contain very private items. -for class in genp inet cert keys; do - for sync in 0 1; do - for tomb in 0 1; do - - echo class=${class},sync=${sync},tomb=${tomb},u_AuthUI=u_AuthUIS: >> $OUTPUT/keychain-state.log - ${secexec} item -q class=${class},sync=${sync},tomb=${tomb},u_AuthUI=u_AuthUIS | grep '^acct'|wc -l 2>&1 >> $OUTPUT/keychain-state.log - done - done -done - -if (( ! $SHORT )); then - syslog -k Sender Seq syncdefaults > $OUTPUT/syslog_syncdefaults.log - syslog -k Sender Seq $secd > $OUTPUT/syslog_secd.log - syslog -k Sender Seq CloudKeychain > $OUTPUT/syslog_cloudkeychain.log -fi - -(( $SHORT )) || (sbdtool status > $OUTPUT/sbdtool_status.log 2>&1) - -if [ "$PROD" == "OSX" ]; then -(( $SHORT )) || plutil -p $HOME/Library/SyncedPreferences/com.apple.sbd.plist > $OUTPUT/sbd_kvs.txt -elif [ "$PROD" == "IOS" ]; then -(( $SHORT )) || plutil -p /var/mobile/Library/SyncedPreferences/com.apple.sbd.plist > $OUTPUT/sbd_kvs.txt -fi - -$syd status > $OUTPUT/syd_status.txt 2>&1 -$syd lastrequest > $OUTPUT/syd_lastrequest.txt 2>&1 -$syd serverlimits > $OUTPUT/syd_serverlimits.txt 2>&1 - -# Compare kvsutil and sync -D state, shows if store diverged from on-device state. -if (( ! $SHORT )); then - if [ -f $OUTPUT/kvsutil_show.txt ]; then - cat $OUTPUT/kvsutil_show.txt | grep -E '^ "?[o-]?ak.* = ' | sed -E 's/^ "?([^"]*)"? = \<.* (.*) (.*)\>.*$/\1 \2\3/g;s/^(.*) [0-9a-f]*([0-9a-f]{8})/\1 \2/g' | sort > $OUTPUT/kvs_keys.txt - cat $OUTPUT/syncD.log | grep -E 'contents = "?[o-]?ak' | sed -E 's/^.*contents = "?([^"]*)"?\} = .*bytes = .* ... [0-9a-f]+([0-9a-f]{8})\}/\1 \2/g' | sort > $OUTPUT/syncD_keys.txt - diff -u $OUTPUT/kvs_keys.txt $OUTPUT/syncD_keys.txt > $OUTPUT/kvs_syncD_diff.txt - fi -fi - -if [ "$PROD" = "IOS" ]; then - cp /private/var/preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist $OUTPUT/ - cp /var/mobile/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist $OUTPUT/ -else - cp ~/Library/Preferences/com.apple.security.cloudkeychainproxy3.keysToRegister.plist $OUTPUT/ - cp ~/Library/SyncedPreferences/com.apple.security.cloudkeychainproxy3.plist $OUTPUT/ -fi - -if (( ! $SHORT )); then - cp $SECLOGPATH/security.log* $OUTPUT/ - - cp $CRASHDIR/*${secd}* $OUTPUT/ - cp $CRASHDIR/*syncdefaults* $OUTPUT/ - cp $CRASHDIR/*CloudKeychain* $OUTPUT/ - - (cd $CSDIR && for x in *_*.asl; do syslog -f "$x" > "$OUTPUT/${x%%.asl}.log"; done) - - (cd $SECLOGPATH; gzcat -c -f security.log*) > $OUTPUT/security-complete.log - - # potential problems - (cd $SECLOGPATH; gzcat -c security.log.*.gz; cat security.log.*Z) | grep -E -- 'Invalid date.|-26275|[cC]orrupt|[cC]rash|Public Key not available' > $OUTPUT/problems.log - (cd $SECLOGPATH; gzcat -c security.log.*.gz; cat security.log.*Z) | cut -d ' ' -f 6- | sort |uniq -c | sort -n > $OUTPUT/security-sorted.log -fi - -) > $OUTPUT/ckcdiagnose.log 2>&1 - -tar czf $OUTPUT.tgz -C $OUTPUTPARENT $OUTPUTBASE - -rm -r $OUTPUT - -if (( ! $SHORT )); then - echo - echo "The file containing the diagnostic information is " - echo " $OUTPUT.tgz" - echo 'Please attach it to a Radar in "Security / iCloud Keychain"' - echo - - [ "$PROD" = "OSX" ] && open $OUTPUTPARENT -else - echo $OUTPUT.tgz -fi - - diff --git a/cssm/certextensions.h b/cssm/certextensions.h index cf0c799f..b60acce3 100644 --- a/cssm/certextensions.h +++ b/cssm/certextensions.h @@ -91,7 +91,7 @@ * nameAssigner [0] DirectoryString OPTIONAL, * partyName [1] DirectoryString } */ -#if SEC_OS_OSX + typedef enum __CE_GeneralNameType { GNT_OtherName = 0, GNT_RFC822Name, @@ -104,21 +104,7 @@ typedef enum __CE_GeneralNameType { GNT_RegisteredID } CE_GeneralNameType; -#elif SEC_OS_IPHONE - -typedef enum { - GNT_OtherName = 0, - GNT_RFC822Name, - GNT_DNSName, - GNT_X400Address, - GNT_DirectoryName, - GNT_EdiPartyName, - GNT_URI, - GNT_IPAddress, - GNT_RegisteredID -} SecCEGeneralNameType; - -#endif /* SEC_OS_IPHONE */ +#define SecCEGeneralNameType CE_GeneralNameType #if SEC_OS_OSX diff --git a/dtlsEcho/dtlsEchoClient.c b/dtlsEcho/dtlsEchoClient.c index 8b5cf6f9..7a2b553a 100644 --- a/dtlsEcho/dtlsEchoClient.c +++ b/dtlsEcho/dtlsEchoClient.c @@ -320,6 +320,9 @@ int main(int argc, char **argv) OSStatus ortn; SSLContextRef ctx = NULL; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + SSLClientCertificateState certState; SSLCipherSuite negCipher; SSLProtocol negVersion; @@ -417,5 +420,7 @@ int main(int argc, char **argv) SSLDisposeContext(ctx); +#pragma clang diagnostic pop + return ortn; } diff --git a/dtlsEcho/dtlsEchoServer.c b/dtlsEcho/dtlsEchoServer.c index b90c003f..1306b5a7 100644 --- a/dtlsEcho/dtlsEchoServer.c +++ b/dtlsEcho/dtlsEchoServer.c @@ -346,6 +346,9 @@ int main(int argc, char **argv) return ortn; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite); if(ortn) { printSslErrStr("SSLSetIOFuncs", ortn); @@ -432,5 +435,7 @@ int main(int argc, char **argv) SSLDisposeContext(ctx); +#pragma clang diagnostic pop + return ortn; } diff --git a/featureflags/Info.plist b/featureflags/Info.plist new file mode 100644 index 00000000..bc9fb4fc --- /dev/null +++ b/featureflags/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSHumanReadableCopyright + Copyright © 2019 Apple. All rights reserved. + NSPrincipalClass + + + diff --git a/featureflags/Security.plist b/featureflags/Security.plist new file mode 100644 index 00000000..339077b2 --- /dev/null +++ b/featureflags/Security.plist @@ -0,0 +1,41 @@ + + + + + octagonTrust + + Enabled + + + recoverykey + + Enabled + + + octagonSOSupgrade + + Enabled + + + octagon + + Enabled + + + CKKSViewsFromPolicy + + Enabled + + + securitydReportPolicy + + Enabled + + + octagonUseDeviceName + + Enabled + + + + diff --git a/header_symlinks/Security/CKKSControl.h b/header_symlinks/Security/CKKSControl.h new file mode 120000 index 00000000..dae0042e --- /dev/null +++ b/header_symlinks/Security/CKKSControl.h @@ -0,0 +1 @@ +./../keychain/ckks/CKKSControl.h \ No newline at end of file diff --git a/header_symlinks/Security/CKKSControlProtocol.h b/header_symlinks/Security/CKKSControlProtocol.h new file mode 120000 index 00000000..905fc20f --- /dev/null +++ b/header_symlinks/Security/CKKSControlProtocol.h @@ -0,0 +1 @@ +./../keychain/ckks/CKKSControlProtocol.h \ No newline at end of file diff --git a/header_symlinks/Security/CMSDecoder.h b/header_symlinks/Security/CMSDecoder.h new file mode 120000 index 00000000..57349a1b --- /dev/null +++ b/header_symlinks/Security/CMSDecoder.h @@ -0,0 +1 @@ +./../CMS/CMSDecoder.h \ No newline at end of file diff --git a/header_symlinks/Security/CMSEncoder.h b/header_symlinks/Security/CMSEncoder.h new file mode 120000 index 00000000..ef5b18eb --- /dev/null +++ b/header_symlinks/Security/CMSEncoder.h @@ -0,0 +1 @@ +./../CMS/CMSEncoder.h \ No newline at end of file diff --git a/header_symlinks/Security/CMSPrivate.h b/header_symlinks/Security/CMSPrivate.h new file mode 120000 index 00000000..5cb5142d --- /dev/null +++ b/header_symlinks/Security/CMSPrivate.h @@ -0,0 +1 @@ +./../CMS/CMSPrivate.h \ No newline at end of file diff --git a/header_symlinks/Security/CSCommonPriv.h b/header_symlinks/Security/CSCommonPriv.h deleted file mode 120000 index e8b33401..00000000 --- a/header_symlinks/Security/CSCommonPriv.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_codesigning/lib/CSCommonPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/CipherSuite.h b/header_symlinks/Security/CipherSuite.h new file mode 120000 index 00000000..92d09e54 --- /dev/null +++ b/header_symlinks/Security/CipherSuite.h @@ -0,0 +1 @@ +./../OSX/libsecurity_ssl/lib/CipherSuite.h \ No newline at end of file diff --git a/header_symlinks/Security/LocalKeychainAnalytics.h b/header_symlinks/Security/LocalKeychainAnalytics.h new file mode 120000 index 00000000..60fece8a --- /dev/null +++ b/header_symlinks/Security/LocalKeychainAnalytics.h @@ -0,0 +1 @@ +./../Analytics/Clients/LocalKeychainAnalytics.h \ No newline at end of file diff --git a/header_symlinks/Security/OTClique.h b/header_symlinks/Security/OTClique.h new file mode 120000 index 00000000..a3752a9e --- /dev/null +++ b/header_symlinks/Security/OTClique.h @@ -0,0 +1 @@ +./../keychain/ot/OTClique.h \ No newline at end of file diff --git a/header_symlinks/Security/OTControl.h b/header_symlinks/Security/OTControl.h new file mode 120000 index 00000000..3a43dbfd --- /dev/null +++ b/header_symlinks/Security/OTControl.h @@ -0,0 +1 @@ +./../keychain/ot/OTControl.h \ No newline at end of file diff --git a/header_symlinks/Security/OTControlProtocol.h b/header_symlinks/Security/OTControlProtocol.h new file mode 120000 index 00000000..3a3af9f5 --- /dev/null +++ b/header_symlinks/Security/OTControlProtocol.h @@ -0,0 +1 @@ +./../keychain/ot/OTControlProtocol.h \ No newline at end of file diff --git a/header_symlinks/Security/OTJoiningConfiguration.h b/header_symlinks/Security/OTJoiningConfiguration.h new file mode 120000 index 00000000..85eb0e3d --- /dev/null +++ b/header_symlinks/Security/OTJoiningConfiguration.h @@ -0,0 +1 @@ +./../keychain/ot/OTJoiningConfiguration.h \ No newline at end of file diff --git a/header_symlinks/Security/SFAnalytics.h b/header_symlinks/Security/SFAnalytics.h new file mode 120000 index 00000000..61462b44 --- /dev/null +++ b/header_symlinks/Security/SFAnalytics.h @@ -0,0 +1 @@ +./../Analytics/SFAnalytics.h \ No newline at end of file diff --git a/header_symlinks/Security/SFAnalyticsActivityTracker.h b/header_symlinks/Security/SFAnalyticsActivityTracker.h new file mode 120000 index 00000000..0459255b --- /dev/null +++ b/header_symlinks/Security/SFAnalyticsActivityTracker.h @@ -0,0 +1 @@ +./../Analytics/SFAnalyticsActivityTracker.h \ No newline at end of file diff --git a/header_symlinks/Security/SFAnalyticsDefines.h b/header_symlinks/Security/SFAnalyticsDefines.h new file mode 120000 index 00000000..3ce48c14 --- /dev/null +++ b/header_symlinks/Security/SFAnalyticsDefines.h @@ -0,0 +1 @@ +./../Analytics/SFAnalyticsDefines.h \ No newline at end of file diff --git a/header_symlinks/Security/SFAnalyticsMultiSampler.h b/header_symlinks/Security/SFAnalyticsMultiSampler.h new file mode 120000 index 00000000..b72b0cb6 --- /dev/null +++ b/header_symlinks/Security/SFAnalyticsMultiSampler.h @@ -0,0 +1 @@ +./../Analytics/SFAnalyticsMultiSampler.h \ No newline at end of file diff --git a/header_symlinks/Security/SFAnalyticsSQLiteStore.h b/header_symlinks/Security/SFAnalyticsSQLiteStore.h new file mode 120000 index 00000000..f3416035 --- /dev/null +++ b/header_symlinks/Security/SFAnalyticsSQLiteStore.h @@ -0,0 +1 @@ +./../Analytics/SFAnalyticsSQLiteStore.h \ No newline at end of file diff --git a/header_symlinks/Security/SFAnalyticsSampler.h b/header_symlinks/Security/SFAnalyticsSampler.h new file mode 120000 index 00000000..3c20396a --- /dev/null +++ b/header_symlinks/Security/SFAnalyticsSampler.h @@ -0,0 +1 @@ +./../Analytics/SFAnalyticsSampler.h \ No newline at end of file diff --git a/header_symlinks/Security/SFSQLite.h b/header_symlinks/Security/SFSQLite.h new file mode 120000 index 00000000..77e97714 --- /dev/null +++ b/header_symlinks/Security/SFSQLite.h @@ -0,0 +1 @@ +./../Analytics/SQLite/SFSQLite.h \ No newline at end of file diff --git a/header_symlinks/Security/SOSAnalytics.h b/header_symlinks/Security/SOSAnalytics.h new file mode 120000 index 00000000..3ab3e109 --- /dev/null +++ b/header_symlinks/Security/SOSAnalytics.h @@ -0,0 +1 @@ +./../Analytics/Clients/SOSAnalytics.h \ No newline at end of file diff --git a/header_symlinks/Security/SOSControlHelper.h b/header_symlinks/Security/SOSControlHelper.h new file mode 120000 index 00000000..bb567eae --- /dev/null +++ b/header_symlinks/Security/SOSControlHelper.h @@ -0,0 +1 @@ +./../keychain/SecureObjectSync/SOSControlHelper.h \ No newline at end of file diff --git a/header_symlinks/Security/SecAccessControl.h b/header_symlinks/Security/SecAccessControl.h new file mode 120000 index 00000000..cea7071f --- /dev/null +++ b/header_symlinks/Security/SecAccessControl.h @@ -0,0 +1 @@ +./../keychain/SecAccessControl.h \ No newline at end of file diff --git a/header_symlinks/Security/SecAccessControlPriv.h b/header_symlinks/Security/SecAccessControlPriv.h new file mode 120000 index 00000000..6f49ca6e --- /dev/null +++ b/header_symlinks/Security/SecAccessControlPriv.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecAccessControlPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecAsn1Coder.h b/header_symlinks/Security/SecAsn1Coder.h new file mode 120000 index 00000000..372846a5 --- /dev/null +++ b/header_symlinks/Security/SecAsn1Coder.h @@ -0,0 +1 @@ +./../OSX/libsecurity_asn1/lib/SecAsn1Coder.h \ No newline at end of file diff --git a/header_symlinks/Security/SecAsn1Templates.h b/header_symlinks/Security/SecAsn1Templates.h new file mode 120000 index 00000000..90820442 --- /dev/null +++ b/header_symlinks/Security/SecAsn1Templates.h @@ -0,0 +1 @@ +./../OSX/libsecurity_asn1/lib/SecAsn1Templates.h \ No newline at end of file diff --git a/header_symlinks/Security/SecAsn1Types.h b/header_symlinks/Security/SecAsn1Types.h new file mode 120000 index 00000000..ea0df8e0 --- /dev/null +++ b/header_symlinks/Security/SecAsn1Types.h @@ -0,0 +1 @@ +./../OSX/libsecurity_asn1/lib/SecAsn1Types.h \ No newline at end of file diff --git a/header_symlinks/Security/SecBase64.h b/header_symlinks/Security/SecBase64.h new file mode 120000 index 00000000..5daf5350 --- /dev/null +++ b/header_symlinks/Security/SecBase64.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecBase64.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCFAllocator.h b/header_symlinks/Security/SecCFAllocator.h new file mode 120000 index 00000000..fb2e11d2 --- /dev/null +++ b/header_symlinks/Security/SecCFAllocator.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecCFAllocator.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCMS.h b/header_symlinks/Security/SecCMS.h new file mode 120000 index 00000000..12de8923 --- /dev/null +++ b/header_symlinks/Security/SecCMS.h @@ -0,0 +1 @@ +./../CMS/SecCMS.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsBase.h b/header_symlinks/Security/SecCmsBase.h new file mode 120000 index 00000000..ce769774 --- /dev/null +++ b/header_symlinks/Security/SecCmsBase.h @@ -0,0 +1 @@ +./../CMS/SecCmsBase.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsContentInfo.h b/header_symlinks/Security/SecCmsContentInfo.h new file mode 120000 index 00000000..ad977fde --- /dev/null +++ b/header_symlinks/Security/SecCmsContentInfo.h @@ -0,0 +1 @@ +./../CMS/SecCmsContentInfo.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsDecoder.h b/header_symlinks/Security/SecCmsDecoder.h new file mode 120000 index 00000000..7f9eb70b --- /dev/null +++ b/header_symlinks/Security/SecCmsDecoder.h @@ -0,0 +1 @@ +./../CMS/SecCmsDecoder.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsDigestContext.h b/header_symlinks/Security/SecCmsDigestContext.h new file mode 120000 index 00000000..627927a0 --- /dev/null +++ b/header_symlinks/Security/SecCmsDigestContext.h @@ -0,0 +1 @@ +./../CMS/SecCmsDigestContext.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsDigestedData.h b/header_symlinks/Security/SecCmsDigestedData.h new file mode 120000 index 00000000..3bff8bec --- /dev/null +++ b/header_symlinks/Security/SecCmsDigestedData.h @@ -0,0 +1 @@ +./../CMS/SecCmsDigestedData.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsEncoder.h b/header_symlinks/Security/SecCmsEncoder.h new file mode 120000 index 00000000..b04171a1 --- /dev/null +++ b/header_symlinks/Security/SecCmsEncoder.h @@ -0,0 +1 @@ +./../CMS/SecCmsEncoder.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsEncryptedData.h b/header_symlinks/Security/SecCmsEncryptedData.h new file mode 120000 index 00000000..145db579 --- /dev/null +++ b/header_symlinks/Security/SecCmsEncryptedData.h @@ -0,0 +1 @@ +./../CMS/SecCmsEncryptedData.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsEnvelopedData.h b/header_symlinks/Security/SecCmsEnvelopedData.h new file mode 120000 index 00000000..9fb6a935 --- /dev/null +++ b/header_symlinks/Security/SecCmsEnvelopedData.h @@ -0,0 +1 @@ +./../CMS/SecCmsEnvelopedData.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsMessage.h b/header_symlinks/Security/SecCmsMessage.h new file mode 120000 index 00000000..eb4d0b07 --- /dev/null +++ b/header_symlinks/Security/SecCmsMessage.h @@ -0,0 +1 @@ +./../CMS/SecCmsMessage.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsRecipientInfo.h b/header_symlinks/Security/SecCmsRecipientInfo.h new file mode 120000 index 00000000..c700f5c6 --- /dev/null +++ b/header_symlinks/Security/SecCmsRecipientInfo.h @@ -0,0 +1 @@ +./../CMS/SecCmsRecipientInfo.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsSignedData.h b/header_symlinks/Security/SecCmsSignedData.h new file mode 120000 index 00000000..86a4255e --- /dev/null +++ b/header_symlinks/Security/SecCmsSignedData.h @@ -0,0 +1 @@ +./../CMS/SecCmsSignedData.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCmsSignerInfo.h b/header_symlinks/Security/SecCmsSignerInfo.h new file mode 120000 index 00000000..5c13d080 --- /dev/null +++ b/header_symlinks/Security/SecCmsSignerInfo.h @@ -0,0 +1 @@ +./../CMS/SecCmsSignerInfo.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCodeHost.h b/header_symlinks/Security/SecCodeHost.h deleted file mode 120000 index 577c81c2..00000000 --- a/header_symlinks/Security/SecCodeHost.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_codesigning/lib/SecCodeHost.h \ No newline at end of file diff --git a/header_symlinks/Security/SecCodeSigner.h b/header_symlinks/Security/SecCodeSigner.h deleted file mode 120000 index bfbce813..00000000 --- a/header_symlinks/Security/SecCodeSigner.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_codesigning/lib/SecCodeSigner.h \ No newline at end of file diff --git a/header_symlinks/Security/SecDH.h b/header_symlinks/Security/SecDH.h new file mode 120000 index 00000000..eca65e83 --- /dev/null +++ b/header_symlinks/Security/SecDH.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecDH.h \ No newline at end of file diff --git a/header_symlinks/Security/SecECKey.h b/header_symlinks/Security/SecECKey.h new file mode 120000 index 00000000..a110c066 --- /dev/null +++ b/header_symlinks/Security/SecECKey.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecECKey.h \ No newline at end of file diff --git a/header_symlinks/Security/SecEntitlements.h b/header_symlinks/Security/SecEntitlements.h new file mode 120000 index 00000000..18f5924d --- /dev/null +++ b/header_symlinks/Security/SecEntitlements.h @@ -0,0 +1 @@ +./../sectask/SecEntitlements.h \ No newline at end of file diff --git a/header_symlinks/Security/SecExperimentPriv.h b/header_symlinks/Security/SecExperimentPriv.h new file mode 120000 index 00000000..eac6c122 --- /dev/null +++ b/header_symlinks/Security/SecExperimentPriv.h @@ -0,0 +1 @@ +./../SecExperiment/SecExperimentPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecFramework.h b/header_symlinks/Security/SecFramework.h new file mode 120000 index 00000000..035d3846 --- /dev/null +++ b/header_symlinks/Security/SecFramework.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecFramework.h \ No newline at end of file diff --git a/header_symlinks/Security/SecImportExportPriv.h b/header_symlinks/Security/SecImportExportPriv.h new file mode 120000 index 00000000..fd3ad461 --- /dev/null +++ b/header_symlinks/Security/SecImportExportPriv.h @@ -0,0 +1 @@ +./../keychain/SecImportExportPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecInternalReleasePriv.h b/header_symlinks/Security/SecInternalReleasePriv.h new file mode 120000 index 00000000..ad4f79d4 --- /dev/null +++ b/header_symlinks/Security/SecInternalReleasePriv.h @@ -0,0 +1 @@ +./../OSX/utilities/SecInternalReleasePriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecItemBackup.h b/header_symlinks/Security/SecItemBackup.h new file mode 120000 index 00000000..fc34c6f4 --- /dev/null +++ b/header_symlinks/Security/SecItemBackup.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecItemBackup.h \ No newline at end of file diff --git a/header_symlinks/Security/SecLogging.h b/header_symlinks/Security/SecLogging.h new file mode 120000 index 00000000..c640db52 --- /dev/null +++ b/header_symlinks/Security/SecLogging.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecLogging.h \ No newline at end of file diff --git a/header_symlinks/Security/SecOTR.h b/header_symlinks/Security/SecOTR.h new file mode 120000 index 00000000..5b92f432 --- /dev/null +++ b/header_symlinks/Security/SecOTR.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecOTR.h \ No newline at end of file diff --git a/header_symlinks/Security/SecOTRSession.h b/header_symlinks/Security/SecOTRSession.h new file mode 120000 index 00000000..4ee8364e --- /dev/null +++ b/header_symlinks/Security/SecOTRSession.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecOTRSession.h \ No newline at end of file diff --git a/header_symlinks/Security/SecPaddingConfigurationsPriv.h b/header_symlinks/Security/SecPaddingConfigurationsPriv.h new file mode 120000 index 00000000..c7960dd9 --- /dev/null +++ b/header_symlinks/Security/SecPaddingConfigurationsPriv.h @@ -0,0 +1 @@ +./../OSX/utilities/SecPaddingConfigurationsPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecPasswordGenerate.h b/header_symlinks/Security/SecPasswordGenerate.h new file mode 120000 index 00000000..dbf80235 --- /dev/null +++ b/header_symlinks/Security/SecPasswordGenerate.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecPasswordGenerate.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocol.h b/header_symlinks/Security/SecProtocol.h deleted file mode 120000 index 191ce0ad..00000000 --- a/header_symlinks/Security/SecProtocol.h +++ /dev/null @@ -1 +0,0 @@ -./../protocol/SecProtocol.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocolConfiguration.h b/header_symlinks/Security/SecProtocolConfiguration.h new file mode 120000 index 00000000..866901f9 --- /dev/null +++ b/header_symlinks/Security/SecProtocolConfiguration.h @@ -0,0 +1 @@ +./../protocol/SecProtocolConfiguration.h \ No newline at end of file diff --git a/header_symlinks/Security/SecProtocolPriv.h b/header_symlinks/Security/SecProtocolPriv.h new file mode 120000 index 00000000..2e776c85 --- /dev/null +++ b/header_symlinks/Security/SecProtocolPriv.h @@ -0,0 +1 @@ +./../protocol/SecProtocolPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecRecoveryKey.h b/header_symlinks/Security/SecRecoveryKey.h new file mode 120000 index 00000000..1802c6ed --- /dev/null +++ b/header_symlinks/Security/SecRecoveryKey.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecRecoveryKey.h \ No newline at end of file diff --git a/header_symlinks/Security/SecRequirementPriv.h b/header_symlinks/Security/SecRequirementPriv.h deleted file mode 120000 index 42f5ece1..00000000 --- a/header_symlinks/Security/SecRequirementPriv.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_codesigning/lib/SecRequirementPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecSMIME.h b/header_symlinks/Security/SecSMIME.h new file mode 120000 index 00000000..ffbfd810 --- /dev/null +++ b/header_symlinks/Security/SecSMIME.h @@ -0,0 +1 @@ +./../CMS/SecSMIME.h \ No newline at end of file diff --git a/header_symlinks/Security/SecServerEncryptionSupport.h b/header_symlinks/Security/SecServerEncryptionSupport.h new file mode 120000 index 00000000..72eebbe4 --- /dev/null +++ b/header_symlinks/Security/SecServerEncryptionSupport.h @@ -0,0 +1 @@ +./../OSX/sec/Security/SecServerEncryptionSupport.h \ No newline at end of file diff --git a/header_symlinks/Security/SecStaticCodePriv.h b/header_symlinks/Security/SecStaticCodePriv.h deleted file mode 120000 index 1a626c64..00000000 --- a/header_symlinks/Security/SecStaticCodePriv.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecTaskPriv.h b/header_symlinks/Security/SecTaskPriv.h new file mode 120000 index 00000000..83d6218e --- /dev/null +++ b/header_symlinks/Security/SecTaskPriv.h @@ -0,0 +1 @@ +./../sectask/SecTaskPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/SecXPCError.h b/header_symlinks/Security/SecXPCError.h new file mode 120000 index 00000000..f91ca33f --- /dev/null +++ b/header_symlinks/Security/SecXPCError.h @@ -0,0 +1 @@ +./../OSX/utilities/SecXPCError.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureObjectSync/SOSBackupSliceKeyBag.h b/header_symlinks/Security/SecureObjectSync/SOSBackupSliceKeyBag.h new file mode 120000 index 00000000..f32a5ca6 --- /dev/null +++ b/header_symlinks/Security/SecureObjectSync/SOSBackupSliceKeyBag.h @@ -0,0 +1 @@ +./../..//keychain/SecureObjectSync/SOSBackupSliceKeyBag.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureObjectSync/SOSCloudCircle.h b/header_symlinks/Security/SecureObjectSync/SOSCloudCircle.h new file mode 120000 index 00000000..b4227868 --- /dev/null +++ b/header_symlinks/Security/SecureObjectSync/SOSCloudCircle.h @@ -0,0 +1 @@ +./../..//keychain/SecureObjectSync/SOSCloudCircle.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureObjectSync/SOSCloudCircleInternal.h b/header_symlinks/Security/SecureObjectSync/SOSCloudCircleInternal.h new file mode 120000 index 00000000..66e9f61c --- /dev/null +++ b/header_symlinks/Security/SecureObjectSync/SOSCloudCircleInternal.h @@ -0,0 +1 @@ +./../..//keychain/SecureObjectSync/SOSCloudCircleInternal.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureObjectSync/SOSPeerInfo.h b/header_symlinks/Security/SecureObjectSync/SOSPeerInfo.h new file mode 120000 index 00000000..e1ae38b7 --- /dev/null +++ b/header_symlinks/Security/SecureObjectSync/SOSPeerInfo.h @@ -0,0 +1 @@ +./../..//keychain/SecureObjectSync/SOSPeerInfo.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureObjectSync/SOSTypes.h b/header_symlinks/Security/SecureObjectSync/SOSTypes.h new file mode 120000 index 00000000..039591df --- /dev/null +++ b/header_symlinks/Security/SecureObjectSync/SOSTypes.h @@ -0,0 +1 @@ +./../..//keychain/SecureObjectSync/SOSTypes.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureObjectSync/SOSViews.h b/header_symlinks/Security/SecureObjectSync/SOSViews.h new file mode 120000 index 00000000..c2bddd7f --- /dev/null +++ b/header_symlinks/Security/SecureObjectSync/SOSViews.h @@ -0,0 +1 @@ +./../..//keychain/SecureObjectSync/SOSViews.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureTransport.h b/header_symlinks/Security/SecureTransport.h new file mode 120000 index 00000000..a6151180 --- /dev/null +++ b/header_symlinks/Security/SecureTransport.h @@ -0,0 +1 @@ +./../OSX/libsecurity_ssl/lib/SecureTransport.h \ No newline at end of file diff --git a/header_symlinks/Security/SecureTransportPriv.h b/header_symlinks/Security/SecureTransportPriv.h new file mode 120000 index 00000000..b9e9376f --- /dev/null +++ b/header_symlinks/Security/SecureTransportPriv.h @@ -0,0 +1 @@ +./../OSX/libsecurity_ssl/lib/SecureTransportPriv.h \ No newline at end of file diff --git a/header_symlinks/Security/X509Templates.h b/header_symlinks/Security/X509Templates.h index e0dff012..cf9c2899 120000 --- a/header_symlinks/Security/X509Templates.h +++ b/header_symlinks/Security/X509Templates.h @@ -1 +1 @@ -././../OSX/libsecurity_asn1/lib/X509Templates.h \ No newline at end of file +./../OSX/libsecurity_asn1/lib/X509Templates.h \ No newline at end of file diff --git a/header_symlinks/Security/certExtensionTemplates.h b/header_symlinks/Security/certExtensionTemplates.h new file mode 120000 index 00000000..4ec4d929 --- /dev/null +++ b/header_symlinks/Security/certExtensionTemplates.h @@ -0,0 +1 @@ +./OSX/libsecurity_asn1/lib/certExtensionTemplates.h \ No newline at end of file diff --git a/header_symlinks/Security/der_plist.h b/header_symlinks/Security/der_plist.h new file mode 120000 index 00000000..16e7e4fc --- /dev/null +++ b/header_symlinks/Security/der_plist.h @@ -0,0 +1 @@ +./../OSX/utilities/der_plist.h \ No newline at end of file diff --git a/header_symlinks/Security/keyTemplates.h b/header_symlinks/Security/keyTemplates.h deleted file mode 120000 index 6d9c1652..00000000 --- a/header_symlinks/Security/keyTemplates.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_asn1/lib/keyTemplates.h \ No newline at end of file diff --git a/header_symlinks/Security/nameTemplates.h b/header_symlinks/Security/nameTemplates.h index 9aa683b9..0691718a 120000 --- a/header_symlinks/Security/nameTemplates.h +++ b/header_symlinks/Security/nameTemplates.h @@ -1 +1 @@ -././../OSX/libsecurity_asn1/lib/nameTemplates.h \ No newline at end of file +./../OSX/libsecurity_asn1/lib/nameTemplates.h \ No newline at end of file diff --git a/header_symlinks/Security/ocspTemplates.h b/header_symlinks/Security/ocspTemplates.h new file mode 120000 index 00000000..3213480f --- /dev/null +++ b/header_symlinks/Security/ocspTemplates.h @@ -0,0 +1 @@ +./../OSX/libsecurity_asn1/lib/ocspTemplates.h \ No newline at end of file diff --git a/header_symlinks/Security/oidsalg.h b/header_symlinks/Security/oidsalg.h new file mode 120000 index 00000000..92f8421c --- /dev/null +++ b/header_symlinks/Security/oidsalg.h @@ -0,0 +1 @@ +./../OSX/libsecurity_asn1/lib/oidsalg.h \ No newline at end of file diff --git a/header_symlinks/Security/oidsattr.h b/header_symlinks/Security/oidsattr.h deleted file mode 120000 index 6a56c805..00000000 --- a/header_symlinks/Security/oidsattr.h +++ /dev/null @@ -1 +0,0 @@ -././../OSX/libsecurity_asn1/lib/oidsattr.h \ No newline at end of file diff --git a/header_symlinks/Security/secasn1t.h b/header_symlinks/Security/secasn1t.h new file mode 120000 index 00000000..db552393 --- /dev/null +++ b/header_symlinks/Security/secasn1t.h @@ -0,0 +1 @@ +./../OSX/libsecurity_asn1/lib/secasn1t.h \ No newline at end of file diff --git a/header_symlinks/Security/sslTypes.h b/header_symlinks/Security/sslTypes.h new file mode 120000 index 00000000..47ffee54 --- /dev/null +++ b/header_symlinks/Security/sslTypes.h @@ -0,0 +1 @@ +./../OSX/libsecurity_ssl/lib/sslTypes.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/NtlmGenerator.h b/header_symlinks/iOS/Security/NtlmGenerator.h new file mode 120000 index 00000000..e6c6e2f0 --- /dev/null +++ b/header_symlinks/iOS/Security/NtlmGenerator.h @@ -0,0 +1 @@ +./../../ntlm/NtlmGenerator.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecCertificateInternal.h b/header_symlinks/iOS/Security/SecCertificateInternal.h new file mode 120000 index 00000000..26c46dde --- /dev/null +++ b/header_symlinks/iOS/Security/SecCertificateInternal.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecCertificateInternal.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecECKeyPriv.h b/header_symlinks/iOS/Security/SecECKeyPriv.h new file mode 120000 index 00000000..83c1efb0 --- /dev/null +++ b/header_symlinks/iOS/Security/SecECKeyPriv.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecECKeyPriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecEMCSPriv.h b/header_symlinks/iOS/Security/SecEMCSPriv.h new file mode 120000 index 00000000..ecd3016a --- /dev/null +++ b/header_symlinks/iOS/Security/SecEMCSPriv.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecEMCSPriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecOTRDHKey.h b/header_symlinks/iOS/Security/SecOTRDHKey.h new file mode 120000 index 00000000..1aac049e --- /dev/null +++ b/header_symlinks/iOS/Security/SecOTRDHKey.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecOTRDHKey.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecOTRErrors.h b/header_symlinks/iOS/Security/SecOTRErrors.h new file mode 120000 index 00000000..5819154a --- /dev/null +++ b/header_symlinks/iOS/Security/SecOTRErrors.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecOTRErrors.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecOTRMath.h b/header_symlinks/iOS/Security/SecOTRMath.h new file mode 120000 index 00000000..622f6503 --- /dev/null +++ b/header_symlinks/iOS/Security/SecOTRMath.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecOTRMath.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecOTRPacketData.h b/header_symlinks/iOS/Security/SecOTRPacketData.h new file mode 120000 index 00000000..6c992cb2 --- /dev/null +++ b/header_symlinks/iOS/Security/SecOTRPacketData.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecOTRPacketData.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecOTRPackets.h b/header_symlinks/iOS/Security/SecOTRPackets.h new file mode 120000 index 00000000..5877eb8c --- /dev/null +++ b/header_symlinks/iOS/Security/SecOTRPackets.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecOTRPackets.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecOTRSessionPriv.h b/header_symlinks/iOS/Security/SecOTRSessionPriv.h new file mode 120000 index 00000000..f12554b7 --- /dev/null +++ b/header_symlinks/iOS/Security/SecOTRSessionPriv.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecOTRSessionPriv.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecPBKDF.h b/header_symlinks/iOS/Security/SecPBKDF.h new file mode 120000 index 00000000..9c790f55 --- /dev/null +++ b/header_symlinks/iOS/Security/SecPBKDF.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecPBKDF.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecRSAKey.h b/header_symlinks/iOS/Security/SecRSAKey.h new file mode 120000 index 00000000..177b154b --- /dev/null +++ b/header_symlinks/iOS/Security/SecRSAKey.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecRSAKey.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecSCEP.h b/header_symlinks/iOS/Security/SecSCEP.h new file mode 120000 index 00000000..1acc92cf --- /dev/null +++ b/header_symlinks/iOS/Security/SecSCEP.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecSCEP.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecTrustStore.h b/header_symlinks/iOS/Security/SecTrustStore.h new file mode 120000 index 00000000..27c2273b --- /dev/null +++ b/header_symlinks/iOS/Security/SecTrustStore.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/SecTrustStore.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/SecureObjectSync/SOSPeerInfoV2.h b/header_symlinks/iOS/Security/SecureObjectSync/SOSPeerInfoV2.h new file mode 120000 index 00000000..4608d78b --- /dev/null +++ b/header_symlinks/iOS/Security/SecureObjectSync/SOSPeerInfoV2.h @@ -0,0 +1 @@ +./../../..//keychain/SecureObjectSync/SOSPeerInfoV2.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/oidsbase.h b/header_symlinks/iOS/Security/oidsbase.h deleted file mode 120000 index bf5f1dda..00000000 --- a/header_symlinks/iOS/Security/oidsbase.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_cssm/lib/oidsbase.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/oidsocsp.h b/header_symlinks/iOS/Security/oidsocsp.h new file mode 120000 index 00000000..f15a00f3 --- /dev/null +++ b/header_symlinks/iOS/Security/oidsocsp.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/oidsocsp.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/osxcode.h b/header_symlinks/iOS/Security/osxcode.h deleted file mode 120000 index 16f8536a..00000000 --- a/header_symlinks/iOS/Security/osxcode.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_utilities/lib/osxcode.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/pbkdf2.h b/header_symlinks/iOS/Security/pbkdf2.h new file mode 120000 index 00000000..ce6b91c9 --- /dev/null +++ b/header_symlinks/iOS/Security/pbkdf2.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/pbkdf2.h \ No newline at end of file diff --git a/header_symlinks/iOS/Security/vmdh.h b/header_symlinks/iOS/Security/vmdh.h new file mode 120000 index 00000000..b3da57b4 --- /dev/null +++ b/header_symlinks/iOS/Security/vmdh.h @@ -0,0 +1 @@ +./../../OSX/sec/Security/vmdh.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CMSDecoder.h b/header_symlinks/macOS/Security/CMSDecoder.h deleted file mode 120000 index 3b5d8995..00000000 --- a/header_symlinks/macOS/Security/CMSDecoder.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_cms/lib/CMSDecoder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CMSEncoder.h b/header_symlinks/macOS/Security/CMSEncoder.h deleted file mode 120000 index 6be993dc..00000000 --- a/header_symlinks/macOS/Security/CMSEncoder.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_cms/lib/CMSEncoder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CMSPrivate.h b/header_symlinks/macOS/Security/CMSPrivate.h deleted file mode 120000 index 557fb87f..00000000 --- a/header_symlinks/macOS/Security/CMSPrivate.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_cms/lib/CMSPrivate.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CSCommonPriv.h b/header_symlinks/macOS/Security/CSCommonPriv.h new file mode 120000 index 00000000..fc11d821 --- /dev/null +++ b/header_symlinks/macOS/Security/CSCommonPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_codesigning/lib/CSCommonPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/CipherSuite.h b/header_symlinks/macOS/Security/CipherSuite.h deleted file mode 120000 index d3f4fef0..00000000 --- a/header_symlinks/macOS/Security/CipherSuite.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_ssl/lib/CipherSuite.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecASN1Coder.h b/header_symlinks/macOS/Security/SecASN1Coder.h deleted file mode 120000 index 1c2f34cf..00000000 --- a/header_symlinks/macOS/Security/SecASN1Coder.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/SecAsn1Coder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecASN1Templates.h b/header_symlinks/macOS/Security/SecASN1Templates.h deleted file mode 120000 index 79eb8e10..00000000 --- a/header_symlinks/macOS/Security/SecASN1Templates.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/SecAsn1Templates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecAccessControl.h b/header_symlinks/macOS/Security/SecAccessControl.h deleted file mode 120000 index 49bc4ad0..00000000 --- a/header_symlinks/macOS/Security/SecAccessControl.h +++ /dev/null @@ -1 +0,0 @@ -./../../keychain/SecAccessControl.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecAsn1Types.h b/header_symlinks/macOS/Security/SecAsn1Types.h deleted file mode 120000 index 02760d75..00000000 --- a/header_symlinks/macOS/Security/SecAsn1Types.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/SecAsn1Types.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecAssessment.h b/header_symlinks/macOS/Security/SecAssessment.h new file mode 120000 index 00000000..a228a1b7 --- /dev/null +++ b/header_symlinks/macOS/Security/SecAssessment.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_codesigning/lib/SecAssessment.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecBreadcrumb.h b/header_symlinks/macOS/Security/SecBreadcrumb.h new file mode 120000 index 00000000..fb71c7f4 --- /dev/null +++ b/header_symlinks/macOS/Security/SecBreadcrumb.h @@ -0,0 +1 @@ +./../../OSX/Breadcrumb/SecBreadcrumb.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsBase.h b/header_symlinks/macOS/Security/SecCmsBase.h deleted file mode 120000 index ec3117b2..00000000 --- a/header_symlinks/macOS/Security/SecCmsBase.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsBase.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsContentInfo.h b/header_symlinks/macOS/Security/SecCmsContentInfo.h deleted file mode 120000 index 91545181..00000000 --- a/header_symlinks/macOS/Security/SecCmsContentInfo.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsContentInfo.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsDecoder.h b/header_symlinks/macOS/Security/SecCmsDecoder.h deleted file mode 120000 index 0b2c542b..00000000 --- a/header_symlinks/macOS/Security/SecCmsDecoder.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsDecoder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsDigestContext.h b/header_symlinks/macOS/Security/SecCmsDigestContext.h deleted file mode 120000 index dc97ff4d..00000000 --- a/header_symlinks/macOS/Security/SecCmsDigestContext.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsDigestContext.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsDigestedData.h b/header_symlinks/macOS/Security/SecCmsDigestedData.h deleted file mode 120000 index 31c66b51..00000000 --- a/header_symlinks/macOS/Security/SecCmsDigestedData.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsDigestedData.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsEncoder.h b/header_symlinks/macOS/Security/SecCmsEncoder.h deleted file mode 120000 index 28887229..00000000 --- a/header_symlinks/macOS/Security/SecCmsEncoder.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsEncoder.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsEncryptedData.h b/header_symlinks/macOS/Security/SecCmsEncryptedData.h deleted file mode 120000 index cc59cb7f..00000000 --- a/header_symlinks/macOS/Security/SecCmsEncryptedData.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsEncryptedData.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsEnvelopedData.h b/header_symlinks/macOS/Security/SecCmsEnvelopedData.h deleted file mode 120000 index f619a96c..00000000 --- a/header_symlinks/macOS/Security/SecCmsEnvelopedData.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsEnvelopedData.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsMessage.h b/header_symlinks/macOS/Security/SecCmsMessage.h deleted file mode 120000 index 8cb491e3..00000000 --- a/header_symlinks/macOS/Security/SecCmsMessage.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsMessage.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsRecipientInfo.h b/header_symlinks/macOS/Security/SecCmsRecipientInfo.h deleted file mode 120000 index 071d0598..00000000 --- a/header_symlinks/macOS/Security/SecCmsRecipientInfo.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsRecipientInfo.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsSignedData.h b/header_symlinks/macOS/Security/SecCmsSignedData.h deleted file mode 120000 index d08307f3..00000000 --- a/header_symlinks/macOS/Security/SecCmsSignedData.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsSignedData.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCmsSignerInfo.h b/header_symlinks/macOS/Security/SecCmsSignerInfo.h deleted file mode 120000 index c97d42b9..00000000 --- a/header_symlinks/macOS/Security/SecCmsSignerInfo.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecCmsSignerInfo.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCodeHost.h b/header_symlinks/macOS/Security/SecCodeHost.h new file mode 120000 index 00000000..484bbaeb --- /dev/null +++ b/header_symlinks/macOS/Security/SecCodeHost.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_codesigning/lib/SecCodeHost.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecCodeSigner.h b/header_symlinks/macOS/Security/SecCodeSigner.h new file mode 120000 index 00000000..3f2e50d6 --- /dev/null +++ b/header_symlinks/macOS/Security/SecCodeSigner.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_codesigning/lib/SecCodeSigner.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecExternalSourceTransform.h b/header_symlinks/macOS/Security/SecExternalSourceTransform.h new file mode 120000 index 00000000..1b5f92f4 --- /dev/null +++ b/header_symlinks/macOS/Security/SecExternalSourceTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecExternalSourceTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecFDERecoveryAsymmetricCrypto.h b/header_symlinks/macOS/Security/SecFDERecoveryAsymmetricCrypto.h new file mode 120000 index 00000000..7b7298e4 --- /dev/null +++ b/header_symlinks/macOS/Security/SecFDERecoveryAsymmetricCrypto.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecFDERecoveryAsymmetricCrypto.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecKeychainItemExtendedAttributes.h b/header_symlinks/macOS/Security/SecKeychainItemExtendedAttributes.h new file mode 120000 index 00000000..e2ed81a7 --- /dev/null +++ b/header_symlinks/macOS/Security/SecKeychainItemExtendedAttributes.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecKeychainItemExtendedAttributes.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecManifest.h b/header_symlinks/macOS/Security/SecManifest.h new file mode 120000 index 00000000..24a308c3 --- /dev/null +++ b/header_symlinks/macOS/Security/SecManifest.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_manifest/lib/SecManifest.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecNullTransform.h b/header_symlinks/macOS/Security/SecNullTransform.h new file mode 120000 index 00000000..32228ed3 --- /dev/null +++ b/header_symlinks/macOS/Security/SecNullTransform.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecNullTransform.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecPassword.h b/header_symlinks/macOS/Security/SecPassword.h new file mode 120000 index 00000000..34071d37 --- /dev/null +++ b/header_symlinks/macOS/Security/SecPassword.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecPassword.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecRandomP.h b/header_symlinks/macOS/Security/SecRandomP.h new file mode 120000 index 00000000..96c8c2b8 --- /dev/null +++ b/header_symlinks/macOS/Security/SecRandomP.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecRandomP.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecRecoveryPassword.h b/header_symlinks/macOS/Security/SecRecoveryPassword.h new file mode 120000 index 00000000..b2d531d7 --- /dev/null +++ b/header_symlinks/macOS/Security/SecRecoveryPassword.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_keychain/lib/SecRecoveryPassword.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecRequirementPriv.h b/header_symlinks/macOS/Security/SecRequirementPriv.h new file mode 120000 index 00000000..dcfaa942 --- /dev/null +++ b/header_symlinks/macOS/Security/SecRequirementPriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_codesigning/lib/SecRequirementPriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecSMIME.h b/header_symlinks/macOS/Security/SecSMIME.h deleted file mode 120000 index 35059140..00000000 --- a/header_symlinks/macOS/Security/SecSMIME.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_smime/lib/SecSMIME.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecStaticCodePriv.h b/header_symlinks/macOS/Security/SecStaticCodePriv.h new file mode 120000 index 00000000..82e25d4a --- /dev/null +++ b/header_symlinks/macOS/Security/SecStaticCodePriv.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_codesigning/lib/SecStaticCodePriv.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecTransformInternal.h b/header_symlinks/macOS/Security/SecTransformInternal.h new file mode 120000 index 00000000..2a3991dd --- /dev/null +++ b/header_symlinks/macOS/Security/SecTransformInternal.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_transform/lib/SecTransformInternal.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecTranslocate.h b/header_symlinks/macOS/Security/SecTranslocate.h new file mode 120000 index 00000000..84ec701a --- /dev/null +++ b/header_symlinks/macOS/Security/SecTranslocate.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_translocate/lib/SecTranslocate.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecureDownload.h b/header_symlinks/macOS/Security/SecureDownload.h new file mode 120000 index 00000000..e2e3e71c --- /dev/null +++ b/header_symlinks/macOS/Security/SecureDownload.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_manifest/lib/SecureDownload.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecureDownloadInternal.h b/header_symlinks/macOS/Security/SecureDownloadInternal.h new file mode 120000 index 00000000..b7d81cc7 --- /dev/null +++ b/header_symlinks/macOS/Security/SecureDownloadInternal.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_manifest/lib/SecureDownloadInternal.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/SecureTransport.h b/header_symlinks/macOS/Security/SecureTransport.h deleted file mode 120000 index adb0d587..00000000 --- a/header_symlinks/macOS/Security/SecureTransport.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_ssl/lib/SecureTransport.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/asn1Templates.h b/header_symlinks/macOS/Security/asn1Templates.h new file mode 120000 index 00000000..2b0e3141 --- /dev/null +++ b/header_symlinks/macOS/Security/asn1Templates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/asn1Templates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/certExtensionTemplates.h b/header_symlinks/macOS/Security/certExtensionTemplates.h deleted file mode 120000 index 5910b0cb..00000000 --- a/header_symlinks/macOS/Security/certExtensionTemplates.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/certExtensionTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/eisl.h b/header_symlinks/macOS/Security/eisl.h new file mode 120000 index 00000000..47509723 --- /dev/null +++ b/header_symlinks/macOS/Security/eisl.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_cssm/lib/eisl.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/keyTemplates.h b/header_symlinks/macOS/Security/keyTemplates.h new file mode 120000 index 00000000..86bd66db --- /dev/null +++ b/header_symlinks/macOS/Security/keyTemplates.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/keyTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/ocspTemplates.h b/header_symlinks/macOS/Security/ocspTemplates.h deleted file mode 120000 index 5cdaef70..00000000 --- a/header_symlinks/macOS/Security/ocspTemplates.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/ocspTemplates.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oids.h b/header_symlinks/macOS/Security/oids.h deleted file mode 120000 index d5320bd2..00000000 --- a/header_symlinks/macOS/Security/oids.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_keychain/libDER/libDER/oids.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oidsalg.h b/header_symlinks/macOS/Security/oidsalg.h deleted file mode 120000 index 019d63f2..00000000 --- a/header_symlinks/macOS/Security/oidsalg.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/oidsalg.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/oidsattr.h b/header_symlinks/macOS/Security/oidsattr.h new file mode 120000 index 00000000..2c68f9a5 --- /dev/null +++ b/header_symlinks/macOS/Security/oidsattr.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_asn1/lib/oidsattr.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/secasn1t.h b/header_symlinks/macOS/Security/secasn1t.h deleted file mode 120000 index 941f15f3..00000000 --- a/header_symlinks/macOS/Security/secasn1t.h +++ /dev/null @@ -1 +0,0 @@ -./../../OSX/libsecurity_asn1/lib/secasn1t.h \ No newline at end of file diff --git a/header_symlinks/macOS/Security/tsaSupport.h b/header_symlinks/macOS/Security/tsaSupport.h new file mode 120000 index 00000000..001c1bb6 --- /dev/null +++ b/header_symlinks/macOS/Security/tsaSupport.h @@ -0,0 +1 @@ +./../../OSX/libsecurity_smime/lib/tsaSupport.h \ No newline at end of file diff --git a/keychain/CoreDataKeychain/SecCDKeychain.h b/keychain/CoreDataKeychain/SecCDKeychain.h index cc2488d5..8b4a1401 100644 --- a/keychain/CoreDataKeychain/SecCDKeychain.h +++ b/keychain/CoreDataKeychain/SecCDKeychain.h @@ -26,9 +26,13 @@ #if !TARGET_OS_BRIDGE #if USE_KEYSTORE +#if __has_include() #import +#endif +#if __has_include() #import #endif +#endif #import #import diff --git a/keychain/CoreDataKeychain/SecCDKeychain.m b/keychain/CoreDataKeychain/SecCDKeychain.m index ff0b9286..77ac9689 100644 --- a/keychain/CoreDataKeychain/SecCDKeychain.m +++ b/keychain/CoreDataKeychain/SecCDKeychain.m @@ -34,7 +34,7 @@ #import "SecItemServer.h" #import "SecItem.h" #import "SecItemPriv.h" -#import "SecBase.h" +#import #import "SFKeychainServer.h" #import "CloudKitCategories.h" #import "securityd_client.h" @@ -47,8 +47,10 @@ #import #import #if USE_KEYSTORE +#if __has_include() #import #endif +#endif #import #import @@ -304,7 +306,7 @@ SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate = (SecCDKey NSDictionary* databaseKeyQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"com.apple.security.securityd", (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecAttrService : @"com.apple.security.keychain.ak", (id)kSecReturnData : @(YES) }; @@ -437,12 +439,12 @@ SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate = (SecCDKey int token = 0; __weak __typeof(self) weakSelf = self; - notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int token) { + notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int t) { bool locked = true; - CFErrorRef error = NULL; - if (!SecAKSGetIsLocked(&locked, &error)) { - secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", error); - CFReleaseNull(error); + CFErrorRef blockError = NULL; + if (!SecAKSGetIsLocked(&locked, &blockError)) { + secerror("SecDbKeychainMetadataKeyStore: error getting lock state: %@", blockError); + CFReleaseNull(blockError); } if (locked) { @@ -929,12 +931,12 @@ SecCDKeychainLookupValueType* const SecCDKeychainLookupValueTypeDate = (SecCDKey _lookupAttributes = [NSSet setWithArray:lookupAttributes]; } else { - NSMutableSet* lookupAttributes = [[NSMutableSet alloc] init]; + NSMutableSet* newLookupAttributes = [[NSMutableSet alloc] init]; [_attributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id value, BOOL* stop) { SecCDKeychainLookupTuple* lookupTuple = [SecCDKeychainLookupTuple lookupTupleWithKey:key value:value]; - [lookupAttributes addObject:lookupTuple]; + [newLookupAttributes addObject:lookupTuple]; }]; - _lookupAttributes = lookupAttributes.copy; + _lookupAttributes = newLookupAttributes.copy; } } diff --git a/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m b/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m index ff923758..b79201ec 100644 --- a/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m +++ b/keychain/KeychainDataclassOwner/KeychainDataclassOwner.m @@ -23,11 +23,9 @@ #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 @@ -71,7 +69,7 @@ static NSString* const KeychainDataclass = @"KeychainDataclass"; if (action.type == ACDataclassActionDeleteSyncData) { NSDictionary* baseQuery = @{ (id)kSecAttrSynchronizable : @(YES), (id)kSecAttrAccessGroup : @"com.apple.cfnetwork", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecAttrTombstone : @(NO), (id)kSecUseTombstones : @(NO) }; NSMutableDictionary* inetQuery = baseQuery.mutableCopy; diff --git a/keychain/KeychainSettings/Info.plist b/keychain/KeychainSettings/Info.plist new file mode 100644 index 00000000..a1431d66 --- /dev/null +++ b/keychain/KeychainSettings/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + NSPrincipalClass + KeychainSettings + CFBundleDisplayName + Keychain 🔑⛓ + + diff --git a/keychain/KeychainSettings/KeychainSettings.h b/keychain/KeychainSettings/KeychainSettings.h new file mode 100644 index 00000000..032e7954 --- /dev/null +++ b/keychain/KeychainSettings/KeychainSettings.h @@ -0,0 +1,21 @@ +// +// KeychainSettings.h +// Security_ios +// + +#import +#import + + +NS_ASSUME_NONNULL_BEGIN + +@interface KeychainSettings : PSListController +@end + +@interface KeychainSettingsOctagonPeers : PSListController +@end + +@interface KeychainSettingsCKKSViews : PSListController +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/KeychainSettings/KeychainSettings.m b/keychain/KeychainSettings/KeychainSettings.m new file mode 100644 index 00000000..b27a1407 --- /dev/null +++ b/keychain/KeychainSettings/KeychainSettings.m @@ -0,0 +1,372 @@ +// +// KeychainSettings.m +// Security +// + +#import "KeychainSettings.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +#import +#import +#import +#import + +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" + + +@interface KeychainSettings () +@property (strong) OTControl* control; +@property (strong) NSDictionary* status; +@property (strong) NSString *statusError; + ++ (OTControl *)sharedOTControl; ++ (CKKSControl *)sharedCKKSControl; +@end + +@implementation KeychainSettings + +- (id)init { + if ((self = [super init]) != nil) { + [self updateCircleStatus]; + } + return self; +} + ++ (OTControl *)sharedOTControl +{ + static OTControl *control; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSError *error = nil; + + control = [OTControl controlObject:true error:&error]; + if(error || !control) { + os_log(OS_LOG_DEFAULT, "no OTControl, failed: %@", error); + } + }); + return control; +} + ++ (CKKSControl *)sharedCKKSControl +{ + static CKKSControl *control; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSError *error = nil; + + // Use a synchronous control object + control = [CKKSControl CKKSControlObject:true error:&error]; + if(error || !control) { + os_log(OS_LOG_DEFAULT, "no CKKSControl, failed: %@", error); + } + }); + return control; + +} + + +- (void)updateCircleStatus +{ + [[KeychainSettings sharedOTControl] status:NULL + context:OTDefaultContext + reply:^(NSDictionary* result, NSError* _Nullable error) { + @synchronized (self) { + self.statusError = nil; + if (error) { + self.status = nil; + self.statusError = [error description]; + } else { + self.status = result; + self.statusError = nil; + } + } + }]; +} + +- (NSArray *)specifiers { + if (!_specifiers) { + _specifiers = [self loadSpecifiersFromPlistName:@"KeychainSettings" target:self]; + } + return _specifiers; +} + +- (NSString *)octagonStatusString:(NSString *)key +{ + __block id status = nil; + @synchronized (self) { + if (self.status) { + id value = self.status[key]; + if ([value isKindOfClass:[NSString class]]) { + status = value; + } else if ([value isKindOfClass:[NSNumber class]]) { + NSNumber *number = value; + status = [number stringValue]; + } else { + status = [key description]; + } + } + if (status == nil && self.statusError) { + status = self.statusError; + } + } + if (status == nil) { + status = @""; + } + return status; + +} + +- (NSNumber *)octagonStatusNumber:(NSString *)key +{ + __block NSNumber *status = nil; + @synchronized (self) { + NSNumber *value = self.status[key]; + if ([value isKindOfClass:[NSNumber class]]) { + status = value; + } + + } + return status; + +} + +- (NSString *)octagonStateMachine:(PSSpecifier *)specifier +{ + return [self octagonStatusString:@"state"]; +} + +- (NSString *)prettyifyProtobufString:(NSString *)string +{ + return [string.capitalizedString stringByReplacingOccurrencesOfString:@"_" withString:@" "]; +} + +- (NSString *)octagonTrustState:(PSSpecifier *)specifier +{ + return [self prettyifyProtobufString:OTAccountMetadataClassC_TrustStateAsString([[self octagonStatusNumber:@"memoizedTrustState"] intValue])]; +} + +- (NSString *)octagonAccountState:(PSSpecifier *)specifier +{ + return [self prettyifyProtobufString:OTAccountMetadataClassC_AccountStateAsString([[self octagonStatusNumber:@"memoizedAccountState"] intValue])]; +} + +- (NSString *)ckksAggregateStatus:(PSSpecifier *)specifier +{ + __block NSString *status = NULL; + __block bool foundNonReady = false; + __block bool foundOne = false; + + void (^replyBlock)(NSArray * _Nullable result, NSError * _Nullable error) = ^(NSArray* result, NSError* _Nullable error){ + if (error) { + status = [NSString stringWithFormat:@"error: %@", error]; + } + for(NSDictionary* view in result) { + NSString* viewName = view[@"view"]; + if (viewName == NULL || [viewName isEqualToString:@"global"]) { + return; + } + foundOne = true; + NSString *viewStatus = view[@"keystate"]; + + if (![viewStatus isKindOfClass:[NSString class]] || + !([viewStatus isEqualToString:@"ready"] || [viewStatus isEqualToString:@"readypendingunlock"])) { + foundNonReady = true; + } + } + }; + + [[KeychainSettings sharedCKKSControl] rpcFastStatus:NULL reply: replyBlock]; + + if (status) { + /* something already provided status */ + } else if (foundNonReady) { + status = @"not ready"; + } else if (foundOne) { + status = @"ready"; + } else { + status = @"no status"; + } + + return status; +} + +- (NSString* _Nullable)primaryiCloudAccountAltDSID +{ + ACAccountStore *store = [[ACAccountStore alloc] init]; + ACAccount* primaryAccount = [store aa_primaryAppleAccount]; + if(!primaryAccount) { + return nil; + } + + return [primaryAccount aa_altDSID]; +} + +- (void) resetOctagon:(PSSpecifier *)specifier +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [[KeychainSettings sharedOTControl] resetAndEstablish:nil + context:OTDefaultContext + altDSID:[self primaryiCloudAccountAltDSID] + reply:^(NSError * _Nullable error) { + if(error) { + + } + dispatch_semaphore_signal(sema); + + }]; + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + secerror("timed out attempting to reset octagon"); + } +} + +@end + + +@implementation KeychainSettingsOctagonPeers + +- (void)addPeerIDs:(NSArray*)peerIDs + peers:(NSMutableDictionary*)peers + toSpecifiers:(NSMutableArray*)specifiers +{ + NSMutableArray* selectedPeers = [NSMutableArray array]; + + for (NSString *peerID in peerIDs) { + NSDictionary *peer = peers[peerID]; + if (peer) { + [selectedPeers addObject:peer]; + } + } + + [selectedPeers sortUsingComparator:^NSComparisonResult(NSDictionary *_Nonnull obj1, NSDictionary *_Nonnull obj2) { + return [obj1[@"stableInfo"][@"device_name"] compare: obj2[@"stableInfo"][@"device_name"]]; + }]; + + for (NSDictionary *peer in selectedPeers) { + PSSpecifier* spec = [PSSpecifier preferenceSpecifierNamed:peer[@"stableInfo"][@"device_name"] target:self set:nil get:nil detail:nil cell:PSTitleValueCell edit:nil]; + + [specifiers addObject:spec]; + } + +} + +- (PSSpecifier *)groupSpecifier:(NSString *)name +{ + return [PSSpecifier preferenceSpecifierNamed:name target:self set:nil get:nil detail:nil cell:PSGroupCell edit:nil]; +} + +- (NSArray *)specifiers { + + if (!_specifiers) { + NSMutableArray* specifiers = [NSMutableArray array]; + + [specifiers addObjectsFromArray: [self loadSpecifiersFromPlistName:@"KeychainSettingsOctagonPeers" target:self]]; + + void (^replyBlock)(NSDictionary* result, NSError* _Nullable error) = ^(NSDictionary* result, NSError* _Nullable error) { + NSDictionary* contextDump = result[@"contextDump"]; + + // Make it easy to find peer information + NSMutableDictionary* peers = [NSMutableDictionary dictionary]; + NSMutableArray* allPeerIDs = [NSMutableArray array]; + for(NSDictionary* peerInformation in contextDump[@"peers"]) { + NSString* peerID = peerInformation[@"peerID"]; + if(peerID) { + peers[peerID] = peerInformation; + [allPeerIDs addObject:peerID]; + } + } + + NSDictionary* egoInformation = contextDump[@"self"]; + NSString* egoPeerID = egoInformation[@"peerID"]; + NSDictionary* egoDynamicInfo = egoInformation[@"dynamicInfo"]; + + if(egoPeerID && egoInformation && egoDynamicInfo) { + + peers[egoPeerID] = egoInformation; + + [specifiers addObject:[self groupSpecifier:@"Me"]]; + [self addPeerIDs:@[egoPeerID] peers:peers toSpecifiers:specifiers]; + + NSArray* included = egoDynamicInfo[@"included"]; + [specifiers addObject:[self groupSpecifier:@"Included"]]; + [self addPeerIDs:included peers:peers toSpecifiers:specifiers]; + [peers removeObjectsForKeys:included]; + + NSArray* excluded = egoDynamicInfo[@"excluded"]; + [specifiers addObject:[self groupSpecifier:@"Excluded"]]; + [self addPeerIDs:excluded peers:peers toSpecifiers:specifiers]; + [peers removeObjectsForKeys:excluded]; + + } else { + [specifiers addObject:[self groupSpecifier:@"Me (untrusted)"]]; + } + + if (peers.count) { + [specifiers addObject:[self groupSpecifier:@"Other peers"]]; + [self addPeerIDs:peers.allKeys peers:peers toSpecifiers:specifiers]; + } + + }; + + [[KeychainSettings sharedOTControl] status:NULL context:OTDefaultContext reply:replyBlock]; + + _specifiers = specifiers; + } + + return _specifiers; +} + +@end + +@implementation KeychainSettingsCKKSViews + +- (NSArray *)specifiers { + + if (!_specifiers) { + NSMutableArray* specifiers = [NSMutableArray array]; + + [specifiers addObjectsFromArray: [self loadSpecifiersFromPlistName:@"KeychainSettingsCKKSViews" target:self]]; + + void (^replyBlock)(NSArray * _Nullable result, NSError * _Nullable error) = ^(NSArray* result, NSError* _Nullable error){ + + NSMutableArray* views = [NSMutableArray array]; + for(NSDictionary* view in result) { + NSString* viewName = view[@"view"]; + if (viewName == NULL || [viewName isEqualToString:@"global"]) { + return; + } + + [views addObject:view]; + } + + [views sortUsingComparator:^NSComparisonResult(NSDictionary *_Nonnull obj1, NSDictionary *_Nonnull obj2) { + return [obj1[@"view"] compare: obj2[@"view"]]; + }]; + + for (NSDictionary *view in views) { + NSString *description = [NSString stringWithFormat:@"%@ - %@", view[@"view"], view[@"keystate"]]; + PSSpecifier* spec = [PSSpecifier preferenceSpecifierNamed:description target:self set:nil get:nil detail:nil cell:PSTitleValueCell edit:nil]; + + [specifiers addObject:spec]; + } + }; + [[KeychainSettings sharedCKKSControl] rpcFastStatus:NULL reply: replyBlock]; + + _specifiers = specifiers; + } + + return _specifiers; +} + + + +@end diff --git a/keychain/KeychainSettings/KeychainSettings.plist b/keychain/KeychainSettings/KeychainSettings.plist new file mode 100644 index 00000000..43f2e3d0 --- /dev/null +++ b/keychain/KeychainSettings/KeychainSettings.plist @@ -0,0 +1,95 @@ + + + + + title + Keychain + items + + + cell + PSGroupCell + label + Octagon + + + cell + PSTitleValueCell + label + State machine + get + octagonStateMachine: + id + OnDemandPresent + + + cell + PSTitleValueCell + label + Trust state + get + octagonTrustState: + id + OnDemandPresent + + + cell + PSTitleValueCell + label + Account state + get + octagonAccountState: + id + OnDemandPresent + + + cell + PSLinkListCell + label + Peers + detail + KeychainSettingsOctagonPeers + + + cell + PSGroupCell + label + CloudKit Keychain Syncing + + + cell + PSTitleValueCell + label + CKKS aggregate status + get + ckksAggregateStatus: + id + OnDemandPresent + + + cell + PSLinkListCell + label + View information + detail + KeychainSettingsCKKSViews + + + cell + PSGroupCell + label + Tools + + + buttonAction + resetOctagon: + cell + PSButtonCell + id + KEYCHAIN_RESET_BUTTON + label + Reset Octagon trust + + + + diff --git a/keychain/KeychainSettings/KeychainSettingsCKKSViews.plist b/keychain/KeychainSettings/KeychainSettingsCKKSViews.plist new file mode 100644 index 00000000..a7e8263b --- /dev/null +++ b/keychain/KeychainSettings/KeychainSettingsCKKSViews.plist @@ -0,0 +1,17 @@ + + + + + title + CKKS views + items + + + cell + PSGroupCell + label + CKKS views + + + + diff --git a/OSX/libsecurity_cms/Info-security_cms.plist b/keychain/KeychainSettings/KeychainSettingsOctagonPeers.plist similarity index 65% rename from OSX/libsecurity_cms/Info-security_cms.plist rename to keychain/KeychainSettings/KeychainSettingsOctagonPeers.plist index 0c67376e..71e1ced9 100644 --- a/OSX/libsecurity_cms/Info-security_cms.plist +++ b/keychain/KeychainSettings/KeychainSettingsOctagonPeers.plist @@ -1,5 +1,10 @@ - + + title + Octagon peers + items + + diff --git a/keychain/SecAccessControl.h b/keychain/SecAccessControl.h index 3701baf3..5b66b242 100644 --- a/keychain/SecAccessControl.h +++ b/keychain/SecAccessControl.h @@ -70,7 +70,10 @@ __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); @constant kSecAccessControlDevicePasscode Constraint: Device passcode - + + @constant kSecAccessControlWatch + Constraint: Watch + @constant kSecAccessControlOr Constraint logic operation: when using more than one constraint, at least one of them must be satisfied. @@ -86,15 +89,16 @@ __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); */ typedef CF_OPTIONS(CFOptionFlags, SecAccessControlCreateFlags) { kSecAccessControlUserPresence = 1u << 0, - kSecAccessControlBiometryAny CF_ENUM_AVAILABLE(10_13_4, 11_3) = 1u << 1, + kSecAccessControlBiometryAny API_AVAILABLE(macos(10.13.4), ios(11.3)) = 1u << 1, kSecAccessControlTouchIDAny API_DEPRECATED_WITH_REPLACEMENT("kSecAccessControlBiometryAny", macos(10.12.1, 10.13.4), ios(9.0, 11.3)) = 1u << 1, - kSecAccessControlBiometryCurrentSet CF_ENUM_AVAILABLE(10_13_4, 11_3) = 1u << 3, + kSecAccessControlBiometryCurrentSet API_AVAILABLE(macos(10.13.4), ios(11.3)) = 1u << 3, kSecAccessControlTouchIDCurrentSet API_DEPRECATED_WITH_REPLACEMENT("kSecAccessControlBiometryCurrentSet", macos(10.12.1, 10.13.4), ios(9.0, 11.3)) = 1u << 3, - kSecAccessControlDevicePasscode CF_ENUM_AVAILABLE(10_11, 9_0) = 1u << 4, - kSecAccessControlOr CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 14, - kSecAccessControlAnd CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 15, - kSecAccessControlPrivateKeyUsage CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 30, - kSecAccessControlApplicationPassword CF_ENUM_AVAILABLE(10_12_1, 9_0) = 1u << 31, + kSecAccessControlDevicePasscode API_AVAILABLE(macos(10.11), ios(9.0)) = 1u << 4, + kSecAccessControlWatch API_AVAILABLE(macos(10.15), ios(NA), iosmac(13.0)) = 1u << 5, + kSecAccessControlOr API_AVAILABLE(macos(10.12.1), ios(9.0)) = 1u << 14, + kSecAccessControlAnd API_AVAILABLE(macos(10.12.1), ios(9.0)) = 1u << 15, + kSecAccessControlPrivateKeyUsage API_AVAILABLE(macos(10.12.1), ios(9.0)) = 1u << 30, + kSecAccessControlApplicationPassword API_AVAILABLE(macos(10.12.1), ios(9.0)) = 1u << 31, } __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); /*! @@ -115,7 +119,7 @@ typedef CF_OPTIONS(CFOptionFlags, SecAccessControlCreateFlags) { __nullable SecAccessControlRef SecAccessControlCreateWithFlags(CFAllocatorRef __nullable allocator, CFTypeRef protection, SecAccessControlCreateFlags flags, CFErrorRef *error) -__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0); +API_AVAILABLE(macos(10.10), ios(8.0)); CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/keychain/SecIdentityPriv.h b/keychain/SecIdentityPriv.h index 47697ca8..99a62abb 100644 --- a/keychain/SecIdentityPriv.h +++ b/keychain/SecIdentityPriv.h @@ -88,7 +88,7 @@ OSStatus SecIdentityFindPreferenceItem( CFTypeRef keychainOrArray, CFStringRef idString, SecKeychainItemRef *itemRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecIdentityCopyPreferred", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecIdentityAddPreferenceItem @@ -106,7 +106,7 @@ OSStatus SecIdentityAddPreferenceItem( SecIdentityRef identityRef, CFStringRef idString, SecKeychainItemRef *itemRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecIdentitySetPreference", macos(10.0, 10.5)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecIdentityUpdatePreferenceItem @@ -120,7 +120,7 @@ OSStatus SecIdentityAddPreferenceItem( OSStatus SecIdentityUpdatePreferenceItem( SecKeychainItemRef itemRef, SecIdentityRef identityRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecIdentitySetPreference", macos(10.0, 10.5)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecIdentityCopyFromPreferenceItem @@ -134,7 +134,7 @@ OSStatus SecIdentityUpdatePreferenceItem( OSStatus SecIdentityCopyFromPreferenceItem( SecKeychainItemRef itemRef, SecIdentityRef *identityRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecIdentityCopyPreference", macos(10.0, 10.5)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function ConvertArrayToKeyUsage diff --git a/keychain/SecImportExport.h b/keychain/SecImportExport.h index 7badf0ed..c6c91c6a 100644 --- a/keychain/SecImportExport.h +++ b/keychain/SecImportExport.h @@ -149,7 +149,7 @@ typedef CF_OPTIONS(uint32_t, SecKeyImportExportFlags) /* * Parameters specific to SecKeyRefs. */ -typedef struct +typedef struct API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) { /* for import and export */ uint32_t version; /* SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION */ @@ -166,10 +166,10 @@ typedef struct CSSM_KEYUSE keyUsage; /* CSSM_KEYUSE_DECRYPT, CSSM_KEYUSE_SIGN, * etc. */ CSSM_KEYATTR_FLAGS keyAttributes; /* CSSM_KEYATTR_PERMANENT, etc. */ -} SecKeyImportExportParameters; +} SecKeyImportExportParameters API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); -typedef struct +typedef struct API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac) { /* for import and export */ uint32_t version; /* SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION */ @@ -194,7 +194,7 @@ typedef struct * - kSecAttrIsSensitive for private keys * - kSecAttrIsExtractable by default */ -} SecItemImportExportKeyParameters; +} SecItemImportExportKeyParameters API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* * SecKeychainItemExport() @@ -254,7 +254,7 @@ OSStatus SecKeychainItemExport( SecItemImportExportFlags flags, /* kSecItemPemArmour, etc. */ const SecKeyImportExportParameters * __nullable keyParams, /* optional */ CFDataRef * __nonnull CF_RETURNS_RETAINED exportedData) /* external representation returned here */ - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecItemExport", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* * SecItemExport() @@ -472,7 +472,7 @@ OSStatus SecKeychainItemImport( const SecKeyImportExportParameters * __nullable keyParams, /* optional */ SecKeychainRef __nullable importKeychain, /* optional */ CFArrayRef * __nullable CF_RETURNS_RETAINED outItems) /* optional */ - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecItemImport", macos(10.0, 10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /* * SecItemImport() @@ -702,7 +702,6 @@ extern const CFStringRef kSecImportItemIdentity OSStatus SecPKCS12Import(CFDataRef pkcs12_data, CFDictionaryRef options, CFArrayRef * __nonnull CF_RETURNS_RETAINED items) API_AVAILABLE(macos(10.6), ios(2.0)); - CF_IMPLICIT_BRIDGING_DISABLED CF_ASSUME_NONNULL_END diff --git a/keychain/SecImportExportPriv.h b/keychain/SecImportExportPriv.h new file mode 100644 index 00000000..6d43101f --- /dev/null +++ b/keychain/SecImportExportPriv.h @@ -0,0 +1,21 @@ +#ifndef _SECURITY_SECIMPORTEXPORTPRIV_H_ +#define _SECURITY_SECIMPORTEXPORTPRIV_H_ + +#include + +__BEGIN_DECLS + +CF_ASSUME_NONNULL_BEGIN +CF_IMPLICIT_BRIDGING_ENABLED + +#if TARGET_OS_OSX +OSStatus SecPKCS12Import_ios(CFDataRef pkcs12_data, CFDictionaryRef options, CFArrayRef * __nonnull CF_RETURNS_RETAINED items) + SPI_AVAILABLE(macos(10.15), iosmac(13.0)) API_UNAVAILABLE(ios, watchos, tvos); +#endif + +CF_IMPLICIT_BRIDGING_DISABLED +CF_ASSUME_NONNULL_END + +__END_DECLS + +#endif /* !_SECURITY_SECIMPORTEXPORTPRIV_H_ */ diff --git a/keychain/SecItem.h b/keychain/SecItem.h index ba571b1b..f39dabbc 100644 --- a/keychain/SecItem.h +++ b/keychain/SecItem.h @@ -85,8 +85,8 @@ extern const CFStringRef kSecClassIdentity kSecClassGenericPassword item attributes: kSecAttrAccess (OS X only) kSecAttrAccessControl - kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable specified) - kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable specified) + kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable and/or kSecUseDataProtectionKeychain set) + kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable and/or kSecUseDataProtectionKeychain set) kSecAttrCreationDate kSecAttrModificationDate kSecAttrDescription @@ -104,8 +104,8 @@ extern const CFStringRef kSecClassIdentity kSecClassInternetPassword item attributes: kSecAttrAccess (OS X only) kSecAttrAccessControl - kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable specified) - kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable specified) + kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable and/or kSecUseDataProtectionKeychain set) + kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable and/or kSecUseDataProtectionKeychain set) kSecAttrCreationDate kSecAttrModificationDate kSecAttrDescription @@ -141,8 +141,8 @@ extern const CFStringRef kSecClassIdentity kSecClassKey item attributes: kSecAttrAccess (OS X only) kSecAttrAccessControl - kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable specified) - kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable specified) + kSecAttrAccessGroup (iOS; also OS X if kSecAttrSynchronizable and/or kSecUseDataProtectionKeychain set) + kSecAttrAccessible (iOS; also OS X if kSecAttrSynchronizable and/or kSecUseDataProtectionKeychain set) kSecAttrKeyClass kSecAttrLabel kSecAttrApplicationLabel @@ -444,7 +444,7 @@ extern const CFStringRef kSecClassIdentity words it is not possible to migrate existing items to, from or between tokens. Currently the only available value for this attribute is kSecAttrTokenIDSecureEnclave, which indicates that item (private key) is - backed by device's Secure Enclave. iOS only. + backed by device's Secure Enclave. */ extern const CFStringRef kSecAttrAccessible API_AVAILABLE(macos(10.9), ios(4.0)); @@ -608,7 +608,7 @@ extern const CFStringRef kSecAttrAccessibleWhenUnlocked extern const CFStringRef kSecAttrAccessibleAfterFirstUnlock API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleAlways - API_AVAILABLE(macos(10.9), ios(4.0)); + API_DEPRECATED("Use an accessibility level that provides some user protection, such as kSecAttrAccessibleAfterFirstUnlock", macos(10.9, 10.14), ios(4.0, 12.0)); extern const CFStringRef kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly API_AVAILABLE(macos(10.10), ios(8.0)); extern const CFStringRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly @@ -616,7 +616,7 @@ extern const CFStringRef kSecAttrAccessibleWhenUnlockedThisDeviceOnly extern const CFStringRef kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly API_AVAILABLE(macos(10.9), ios(4.0)); extern const CFStringRef kSecAttrAccessibleAlwaysThisDeviceOnly - API_AVAILABLE(macos(10.9), ios(4.0)); + API_DEPRECATED("Use an accessibility level that provides some user protection, such as kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly", macos(10.9, 10.14), ios(4.0, 12.0)); /*! @enum kSecAttrProtocol Value Constants @@ -1017,11 +1017,16 @@ extern const CFStringRef kSecValuePersistentRef will succeed without asking user for authentication. * If the specified context has not been previously authenticated, the new authentication will be started on this context, allowing caller to - eventually reuse the sucessfully authenticated context in subsequent + eventually reuse the successfully authenticated context in subsequent keychain operations. + @constant kSecUseDataProtectionKeychain Specifies a dictionary key whose value + is a CFBooleanRef. Set to kCFBooleanTrue to use kSecAttrAccessGroup and/or + kSecAttrAccessible on macOS without requiring the item to be marked synchronizable. */ extern const CFStringRef kSecUseItemList - API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(ios, tvos, watchos); + API_AVAILABLE(macos(10.6)) + API_DEPRECATED("Not implemented on this platform", ios(2.0, 12.0), tvos(9.0, 12.0), watchos(1.0, 5.0)) + API_UNAVAILABLE(bridgeos, iosmac); extern const CFStringRef kSecUseKeychain API_AVAILABLE(macos(10.7), ios(NA), bridgeos(NA)); extern const CFStringRef kSecUseOperationPrompt @@ -1032,6 +1037,8 @@ extern const CFStringRef kSecUseAuthenticationUI API_AVAILABLE(macos(10.11), ios(9.0)); extern const CFStringRef kSecUseAuthenticationContext API_AVAILABLE(macos(10.11), ios(9.0)); +extern const CFStringRef kSecUseDataProtectionKeychain + API_AVAILABLE(macos(10.15), ios(13.0)); /*! @enum kSecUseAuthenticationUI Value Constants @@ -1063,7 +1070,7 @@ extern const CFStringRef kSecUseAuthenticationUISkip @constant kSecAttrTokenIDSecureEnclave Specifies well-known identifier of the token implemented using device's Secure Enclave. The only keychain items supported by the Secure Enclave token are 256-bit elliptic curve keys - (kSecAttrKeyTypeEC). Keys must be generated on the secure enclave using + (kSecAttrKeyTypeECSecPrimeRandom). Keys must be generated on the secure enclave using SecKeyGenerateKeyPair call with kSecAttrTokenID set to kSecAttrTokenIDSecureEnclave in the parameters dictionary, it is not possible to import pregenerated keys to kSecAttrTokenIDSecureEnclave token. diff --git a/keychain/SecItemPriv.h b/keychain/SecItemPriv.h index 631491fb..c458816d 100644 --- a/keychain/SecItemPriv.h +++ b/keychain/SecItemPriv.h @@ -37,10 +37,14 @@ #include #include -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) +#if TARGET_OS_OSX #include #endif +#if __OBJC__ +#import +#endif + __BEGIN_DECLS /*! @@ -256,7 +260,8 @@ extern const CFStringRef kSecClassAppleSharePassword; a CFBooleanRef indicating that the item in question is a tombstone. @constant kSecAttrNoLegacy Specifies a dictionary key whose value is a CFBooleanRef indicating that the query must be run on the - syncable backend even for non syncable items. + syncable backend even for non syncable items. This attribute is deprecated + in favor of the kSecUseDataProtectionKeychain API attribute. */ extern const CFStringRef kSecAttrScriptCode; extern const CFStringRef kSecAttrAlias; @@ -279,7 +284,7 @@ extern const CFStringRef kSecAttrCanSignRecover; extern const CFStringRef kSecAttrCanVerifyRecover; extern const CFStringRef kSecAttrTombstone; extern const CFStringRef kSecAttrNoLegacy - __OSX_AVAILABLE(10.11) __IOS_AVAILABLE(9.3) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3); + __API_DEPRECATED_WITH_REPLACEMENT("kSecUseDataProtectionKeychain", macos(10.11, 10.15), ios(9.3, 13.0), tvos(9.3, 13.0), watchos(2.3, 6.0)); extern const CFStringRef kSecAttrSyncViewHint __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0); extern const CFStringRef kSecAttrMultiUser @@ -428,7 +433,7 @@ extern const CFStringRef kSecUseCallerName 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; + __OSX_AVAILABLE(10.14) API_UNAVAILABLE(ios, tvos, watchos, bridgeos, iosmac); extern const CFStringRef kSOSInternalAccessGroup __OSX_AVAILABLE(10.9) __IOS_AVAILABLE(7.0) __TVOS_AVAILABLE(9.3) __WATCHOS_AVAILABLE(2.3); @@ -516,9 +521,21 @@ void SecItemFetchCurrentItemAcrossAllDevices(CFStringRef accessGroup, bool fetchCloudValue, void (^complete)(CFDataRef persistentRef, CFErrorRef error)); - #if __OBJC__ +/*! + @function SecItemVerifyBackupIntegrity + @abstract Verifies the presence and integrity of all key material required + to restore a backup of the keychain. + @param lightweight Only verify the item keys wrapped by backup keys instead + of the default rigorous pass. This mode can be run in any + security class. + @param completion Called to indicate results: a dictionary containing information about the the infrastructure + and of the backup state of keychain items. Error is set when at least one failure occurred. + */ +void SecItemVerifyBackupIntegrity(BOOL lightweight, + void(^completion)(NSDictionary* resultsPerKeyclass, NSError* error)); void _SecItemFetchDigests(NSString *itemClass, NSString *accessGroup, void (^complete)(NSArray *, NSError *)); +void _SecKeychainDeleteMultiUser(NSString *musrUUID, void (^complete)(bool, NSError *)); #endif /*! @@ -578,11 +595,7 @@ XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyCKKSEndpoint(CFErrorRef *er XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopySFKeychainEndpoint(CFErrorRef* error); XPC_RETURNS_RETAINED xpc_endpoint_t _SecSecuritydCopyKeychainControlEndpoint(CFErrorRef* error); -#if SEC_OS_IPHONE bool _SecSyncBubbleTransfer(CFArrayRef services, uid_t uid, CFErrorRef *error); -#else /* SEC_OS_IPHONE */ -bool _SecSyncBubbleTransfer(CFArrayRef services, CFErrorRef *error); -#endif /* SEC_OS_IPHONE */ bool _SecSystemKeychainTransfer(CFErrorRef *error); bool _SecSyncDeleteUserViews(uid_t uid, CFErrorRef *error); @@ -666,6 +679,22 @@ SecCertificateRef SecItemCopyStoredCertificate(SecCertificateRef certificate, vo __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_NA); #endif /* SEC_OS_OSX */ +/*! + @enum kSecAttrTokenID Value Constants + @discussion Predefined item attribute constant used to get or set values + in a dictionary. The kSecAttrTokenID constant is the key and its value + can be kSecAttrTokenIDSecureEnclave or kSecAttrTokenIDSecureElement. + @constant kSecAttrTokenIDSecureElement Specifies well-known identifier of the + token implemented using device's Secure Element. The only keychain items + supported by the Secure Element token are 256-bit elliptic curve keys + (kSecAttrKeyTypeECSecPrimeRandom). Keys must be generated on the secure element using + SecKeyCreateRandomKey call with kSecAttrTokenID set to + kSecAttrTokenIDSecureElement in the parameters dictionary, it is not + possible to import pregenerated keys to kSecAttrTokenIDSecureElement token. + */ +extern const CFStringRef kSecAttrTokenIDSecureElement +SPI_AVAILABLE(ios(10.13)); + __END_DECLS #endif /* !_SECURITY_SECITEMPRIV_H_ */ diff --git a/keychain/SecKey.h b/keychain/SecKey.h index e5f4c624..021a672a 100644 --- a/keychain/SecKey.h +++ b/keychain/SecKey.h @@ -302,7 +302,7 @@ OSStatus SecKeyCreatePair( SecAccessRef _Nullable initialAccess, SecKeyRef* _Nullable CF_RETURNS_RETAINED publicKey, SecKeyRef* _Nullable CF_RETURNS_RETAINED privateKey) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecKeyGenerate @@ -327,7 +327,7 @@ OSStatus SecKeyGenerate( uint32 keyAttr, SecAccessRef _Nullable initialAccess, SecKeyRef* _Nullable CF_RETURNS_RETAINED keyRef) - DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; + CSSM_DEPRECATED; /*! @function SecKeyGetCSSMKey diff --git a/keychain/SecKeyPriv.h b/keychain/SecKeyPriv.h index 2507bc2e..1f22315a 100644 --- a/keychain/SecKeyPriv.h +++ b/keychain/SecKeyPriv.h @@ -38,9 +38,12 @@ #include #include +#if TARGET_OS_OSX +#include +#endif + #if SEC_OS_OSX #include -#include #include #endif @@ -221,12 +224,6 @@ struct __SecKey { const SecKeyDescriptor *key_class; -#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; -#endif - /* The actual key handled by class. */ void *key; }; @@ -375,7 +372,7 @@ API_DEPRECATED_WITH_REPLACEMENT("SecKeyGetAlgorithmId", ios(5.0, 9.0)) API_UNAVA 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); +API_DEPRECATED_WITH_REPLACEMENT("SecKeyGetAlgorithmId", macos(10.2, 10.8)) API_UNAVAILABLE(ios, tvos, watchos, bridgeos, iosmac); #endif #if !SEC_OS_OSX @@ -467,7 +464,7 @@ OSStatus SecKeyGetStrengthInBits(SecKeyRef key, const CSSM_X509_ALGORITHM_IDENTI @param publicKey Optional output pointer to the keychain item reference of the imported public key. The caller must call CFRelease on this value if it is returned. @param privateKey Optional output pointer to the keychain item reference of the imported private key. The caller must call CFRelease on this value if it is returned. @result A result code. See "Security Error Codes" (SecBase.h). - @deprecated in 10.5 and later. Use the SecKeychainItemImport function instead; see + @deprecated in 10.5 and later. Use the SecItemImport function instead; see */ OSStatus SecKeyImportPair( SecKeychainRef keychainRef, @@ -476,7 +473,7 @@ OSStatus SecKeyImportPair( SecAccessRef initialAccess, SecKeyRef* publicKey, SecKeyRef* privateKey) - DEPRECATED_IN_MAC_OS_X_VERSION_10_5_AND_LATER; + API_DEPRECATED_WITH_REPLACEMENT("SecItemImport", macos(10.0, 10.5)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); /*! @function SecKeyCreate @@ -507,6 +504,11 @@ SecKeyRef SecKeyCreate(CFAllocatorRef allocator, */ OSStatus SecKeyCreateWithCSSMKey(const CSSM_KEY *key, SecKeyRef* keyRef) API_DEPRECATED("CSSM_KEY is deprecated", macos(10.11, 10.14)); +// Alias macOS versions of this deprecated SPI to unique macOS names. Undecorated names are used for iosmac. +#define SecKeyRawSign SecKeyRawSign_macOS +#define SecKeyRawVerify SecKeyRawVerify_macOS + +CF_IMPLICIT_BRIDGING_ENABLED /*! @function SecKeyRawSign @@ -538,7 +540,8 @@ OSStatus SecKeyRawSign( const uint8_t *dataToSign, size_t dataToSignLen, uint8_t *sig, - size_t *sigLen); + size_t *sigLen) +SPI_DEPRECATED_WITH_REPLACEMENT("SecKeyCreateSignature", macos(10.7, 10.15)); /*! @@ -564,8 +567,10 @@ OSStatus SecKeyRawVerify( const uint8_t *signedData, size_t signedDataLen, const uint8_t *sig, - size_t sigLen); + size_t sigLen) +SPI_DEPRECATED_WITH_REPLACEMENT("SecKeyVerifySignature", macos(10.7, 10.15)); +CF_IMPLICIT_BRIDGING_DISABLED /*! @function SecKeyEncrypt @@ -595,7 +600,8 @@ OSStatus SecKeyEncrypt( const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, - size_t *cipherTextLen); + size_t *cipherTextLen) +SPI_DEPRECATED_WITH_REPLACEMENT("SecKeyCreateEncryptedData", macos(10.7, 10.15)); /*! @@ -623,7 +629,8 @@ OSStatus SecKeyDecrypt( const uint8_t *cipherText, size_t cipherTextLen, /* length of cipherText */ uint8_t *plainText, - size_t *plainTextLen); /* IN/OUT */ + size_t *plainTextLen) /* IN/OUT */ +SPI_DEPRECATED_WITH_REPLACEMENT("SecKeyCreateDecryptedData", macos(10.7, 10.15)); // SecAsn1AlgId is deprecated, but we still need to use it. #pragma clang diagnostic push @@ -704,7 +711,8 @@ OSStatus SecKeyRawVerifyOSX( const uint8_t *signedData, size_t signedDataLen, const uint8_t *sig, - size_t sigLen); + size_t sigLen) +SPI_DEPRECATED_WITH_REPLACEMENT("SecKeyVerifySignature", macos(10.7, 10.15)); #endif // SEC_OS_OSX_INCLUDES @@ -800,6 +808,7 @@ typedef CF_ENUM(uint32_t, SecKeyAttestationKeyType) kSecKeyAttestationKeyTypeGID = 1, kSecKeyAttestationKeyTypeUIKCommitted SPI_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 2, kSecKeyAttestationKeyTypeUIKProposed SPI_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 3, + kSecKeyAttestationKeyTypeSecureElement SPI_AVAILABLE(ios(13.0)) = 4, } SPI_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)); /*! diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.c similarity index 81% rename from OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c rename to keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.c index af3c99d3..f2412f5b 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.c +++ b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.c @@ -45,7 +45,7 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -160,46 +160,6 @@ static CFErrorRef makeError(CFIndex which) return CFErrorCreate(kCFAllocatorDefault, sErrorDomain, which, userInfo); } -// MARK: ----- DEBUG Utilities ----- - -//------------------------------------------------------------------------------------------------ -// DEBUG only -//------------------------------------------------------------------------------------------------ - -static void describeXPCObject(char *prefix, xpc_object_t object) -{ -//#ifndef NDEBUG - // This is useful for debugging. - if (object) - { - char *desc = xpc_copy_description(object); - secdebug(SOSCKCSCOPE, "%s%s\n", prefix, desc); - free(desc); - } - else - secdebug(SOSCKCSCOPE, "%s\n", prefix); -//#endif -} - -static void describeXPCType(char *prefix, xpc_type_t xtype) -{ - // Add others as necessary, e.g. XPC_TYPE_DOUBLE -#ifndef NDEBUG - // This is useful for debugging. - char msg[256]={0,}; - if (XPC_TYPE_CONNECTION == xtype) - strcpy(msg, "XPC_TYPE_CONNECTION"); - else if (XPC_TYPE_ERROR == xtype) - strcpy(msg, "XPC_TYPE_ERROR"); - else if (XPC_TYPE_DICTIONARY == xtype) - strcpy(msg, "XPC_TYPE_DICTIONARY"); - else - strcpy(msg, ""); - - secdebug(SOSCKCSCOPE, "%s type:%s\n", prefix, msg); -#endif -} - // MARK: ---------- SOSXPCCloudTransport ---------- typedef struct SOSXPCCloudTransport *SOSXPCCloudTransportRef; @@ -210,82 +170,53 @@ struct SOSXPCCloudTransport dispatch_queue_t xpc_queue; }; -static bool xpc_event_filter(const xpc_connection_t peer, xpc_object_t event, CFErrorRef *error) +static void teardownServiceConnection(SOSXPCCloudTransportRef transport) { - // return true if the type is XPC_TYPE_DICTIONARY (and therefore something more to process) - secdebug(SOSCKCSCOPE, "handle_connection_event\n"); - xpc_type_t xtype = xpc_get_type(event); - describeXPCType("handle_xpc_event", xtype); - if (XPC_TYPE_CONNECTION == xtype) - { - secdebug(SOSCKCSCOPE, "handle_xpc_event: XPC_TYPE_CONNECTION (unexpected)"); - // The client of an XPC service does not get connection events - // For now, we log this and keep going - describeXPCObject("handle_xpc_event: XPC_TYPE_CONNECTION, obj : ", event); - } - else - if (XPC_TYPE_ERROR == xtype) - { -#ifndef NDEBUG - const char *estr = xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION); -#endif - secdebug(SOSCKCSCOPE, "default: xpc error: %s\n", estr); - } - else - if (XPC_TYPE_DICTIONARY == xtype) - { - secdebug(SOSCKCSCOPE, "received dictionary event %p\n", event); - return true; - } - else - { - secdebug(SOSCKCSCOPE, "default: unexpected connection event %p\n", event); - describeXPCObject("handle_xpc_event: obj : ", event); - if (error) - *error = makeError(kSOSOUnexpectedXPCEvent); + secnotice(SOSCKCSCOPE, "CKP Transport: tearing down xpc connection"); + dispatch_assert_queue(transport->xpc_queue); + if (transport->serviceConnection) { + xpc_release(transport->serviceConnection); + transport->serviceConnection = NULL; } - return false; } static void setupServiceConnection(SOSXPCCloudTransportRef transport) { secnotice(SOSCKCSCOPE, "CKP Transport: setting up xpc connection"); - transport->serviceConnection = xpc_connection_create_mach_service(xpcServiceName, transport->xpc_queue, 0); + dispatch_assert_queue(transport->xpc_queue); - secdebug(SOSCKCSCOPE, "serviceConnection: %p\n", transport->serviceConnection); + transport->serviceConnection = xpc_connection_create_mach_service(kCKPServiceName, transport->xpc_queue, 0); + + secdebug(SOSCKCSCOPE, "serviceConnection: %@", transport->serviceConnection); xpc_connection_set_event_handler(transport->serviceConnection, ^(xpc_object_t event) { - secdebug(SOSCKCSCOPE, "CKP Transport, xpc_connection_set_event_handler\n"); + secdebug(SOSCKCSCOPE, "CKP Transport, xpc_connection_set_event_handler"); if(event == XPC_ERROR_CONNECTION_INVALID){ - secnotice(SOSCKCSCOPE, "CKP Transport: xpc connection invalid. Oh well."); + secnotice(SOSCKCSCOPE, "CKP Transport: xpc connection invalid. Will tear down connection."); + dispatch_async(transport->xpc_queue, ^{ + teardownServiceConnection(transport); + }); } }); xpc_connection_activate(transport->serviceConnection); } -static void teardownServiceConnection(SOSXPCCloudTransportRef transport) -{ - secnotice(SOSCKCSCOPE, "CKP Transport: tearing down xpc connection"); - dispatch_assert_queue(transport->xpc_queue); - xpc_release(transport->serviceConnection); - transport->serviceConnection = NULL; -} - static void SOSXPCCloudTransportInit(SOSXPCCloudTransportRef transport) { - secdebug(SOSCKCSCOPE, "initXPCConnection\n"); + secdebug(SOSCKCSCOPE, "initXPCConnection"); - transport->xpc_queue = dispatch_queue_create(xpcServiceName, DISPATCH_QUEUE_SERIAL); + transport->xpc_queue = dispatch_queue_create(kCKPServiceName, DISPATCH_QUEUE_SERIAL); - setupServiceConnection(transport); + dispatch_sync(transport->xpc_queue, ^{ + setupServiceConnection(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 Transport: desktopUp happened, reestablishing xpc connections"); teardownServiceConnection(transport); - setupServiceConnection(transport); }); } @@ -295,6 +226,10 @@ static bool messageToProxy(SOSXPCCloudTransportRef transport, xpc_object_t messa __block CFErrorRef connectionError = NULL; dispatch_sync(transport->xpc_queue, ^{ + if (transport->serviceConnection == NULL) { + setupServiceConnection(transport); + } + if (transport->serviceConnection && message) { xpc_connection_send_message_with_reply(transport->serviceConnection, message, processQueue, replyBlock); } else { @@ -308,42 +243,38 @@ static void talkWithKVS(SOSXPCCloudTransportRef transport, xpc_object_t message, { CFErrorRef messagingError = NULL; dispatch_retain(processQueue); - bool messaged = messageToProxy(transport, message, &messagingError, transport->xpc_queue, ^(xpc_object_t reply) - { - CFErrorRef serverError = NULL; - CFTypeRef object = NULL; - if (xpc_event_filter(transport->serviceConnection, 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 - } - else - secerror("missing value reply"); - - xpc_object_t xerror = xpc_dictionary_get_value(reply, kMessageKeyError); - if (xerror) - serverError = SecCreateCFErrorWithXPCObject(xerror); // use SecCFCreateErrorWithFormat? + bool messaged = messageToProxy(transport, message, &messagingError, transport->xpc_queue, ^(xpc_object_t reply) { + CFErrorRef serverError = NULL; + CFTypeRef object = NULL; + + if (xpc_get_type(reply) == XPC_TYPE_DICTIONARY) { + xpc_object_t xrv = xpc_dictionary_get_value(reply, kMessageKeyValue); + if (xrv) { + object = _CFXPCCreateCFObjectFromXPCObject(xrv); + } else { + secerror("missing value reply"); } - dispatch_async(processQueue, ^{ - if (replyBlock) - replyBlock(object, serverError); - CFReleaseSafe(object); - if (serverError) - { - secerror("callback error: %@", serverError); - CFReleaseSafe(serverError); - } - dispatch_release(processQueue); - }); + + xpc_object_t xerror = xpc_dictionary_get_value(reply, kMessageKeyError); + if (xerror) { + serverError = SecCreateCFErrorWithXPCObject(xerror); + } + } else { + serverError = makeError(kSOSMessageInvalid); + secerror("Odd reply from CloudKeychainProxy: %@: %@", reply, serverError); + } + dispatch_async(processQueue, ^{ + if (replyBlock) { + replyBlock(object, serverError); + } + CFReleaseSafe(object); + if (serverError) { + secerror("callback error: %@", serverError); + CFReleaseSafe(serverError); + } + dispatch_release(processQueue); }); + }); if (!messaged) { secerror("talkWithKVS error: %@", messagingError); @@ -544,36 +475,6 @@ static void SOSCloudTransportRequestSyncWithPeers(SOSCloudTransportRef transport } -static bool SOSCloudTransportHasPeerSyncPending(SOSCloudTransportRef transport, CFStringRef peerID, CFErrorRef* error) -{ - secdebug(SOSCKCSCOPE, "start"); - SOSXPCCloudTransportRef xpcTransport = (SOSXPCCloudTransportRef)transport; - - __block bool isSyncing = false; - - xpc_object_t xpcmessage = xpc_dictionary_create(NULL, NULL, 0); - - xpc_dictionary_set_uint64(xpcmessage, kMessageKeyVersion, kCKDXPCVersion); - xpc_dictionary_set_string(xpcmessage, kMessageKeyOperation, kOperationHasPendingSyncWithPeer); - - SecXPCDictionarySetCFObject(xpcmessage, kMessageKeyPeerID, peerID); - - dispatch_semaphore_t wait = dispatch_semaphore_create(0); - bool sent = messageToProxy(xpcTransport, xpcmessage, error, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(xpc_object_t reply) { - isSyncing = xpc_dictionary_get_bool(reply, kMessageKeyValue); - dispatch_semaphore_signal(wait); - }); - - if (sent) { - dispatch_semaphore_wait(wait, DISPATCH_TIME_FOREVER); - } - - dispatch_release(wait); - - return sent && isSyncing; -} - - static bool SOSCloudTransportHasPendingKey(SOSCloudTransportRef transport, CFStringRef keyName, CFErrorRef* error) { secdebug(SOSCKCSCOPE, "start"); @@ -660,7 +561,6 @@ static SOSCloudTransportRef SOSCloudTransportCreateXPCTransport(void) st->transport.synchronizeAndWait = SOSCloudTransportSyncAndWait; st->transport.clearAll = SOSCloudTransportClearAll; st->transport.requestSyncWithPeers = SOSCloudTransportRequestSyncWithPeers; - st->transport.hasPeerSyncPending = SOSCloudTransportHasPeerSyncPending; st->transport.hasPendingKey = SOSCloudTransportHasPendingKey; st->transport.requestEnsurePeerRegistration = SOSCloudTransportRequestEnsurePeerRegistration; st->transport.requestPerfCounters = SOSCloudTransportRequestPerfCounters; @@ -749,6 +649,7 @@ void SOSCloudKeychainSynchronize(dispatch_queue_t processQueue, CloudKeychainRep void SOSCloudKeychainClearAll(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) { SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); + secnotice("circleOps", "SOSCloudKeychainClearAll called"); if (cTransportRef) cTransportRef->clearAll(cTransportRef, processQueue, replyBlock); } @@ -766,12 +667,6 @@ bool SOSCloudKeychainHasPendingKey(CFStringRef keyName, CFErrorRef* error) { return cTransportRef && cTransportRef->hasPendingKey(cTransportRef, keyName, error); } -bool SOSCloudKeychainHasPendingSyncWithPeer(CFStringRef peerID, CFErrorRef* error) { - SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); - - return cTransportRef && cTransportRef->hasPeerSyncPending(cTransportRef, peerID, error); -} - void SOSCloudKeychainRequestEnsurePeerRegistration(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock) { SOSCloudTransportRef cTransportRef = SOSCloudTransportDefaultTransport(); diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h similarity index 95% rename from OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h rename to keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h index 9d20907e..2578f21a 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainClient.h +++ b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h @@ -47,14 +47,14 @@ __BEGIN_DECLS enum { - kSOSObjectMallocFailed = 1, - kAddDuplicateEntry, kSOSObjectNotFoundError = 1, kSOSObjectCantBeConvertedToXPCObject, kSOSOUnexpectedConnectionEvent, kSOSOXPCErrorEvent, kSOSOUnexpectedXPCEvent, - kSOSConnectionNotOpen + kSOSConnectionNotOpen, + kSOSNoServerReply, + kSOSMessageInvalid, }; typedef CFArrayRef (^CloudItemsChangedBlock)(CFDictionaryRef values); @@ -81,7 +81,6 @@ struct SOSCloudTransport bool (*hasPendingKey)(SOSCloudTransportRef transport, CFStringRef keyName, CFErrorRef* error); void (*requestSyncWithPeers)(SOSCloudTransportRef transport, CFArrayRef /* CFStringRef */ peers, CFArrayRef /* CFStringRef */ backupPeers, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); - bool (*hasPeerSyncPending)(SOSCloudTransportRef transport, CFStringRef peerID, CFErrorRef* error); void (*requestEnsurePeerRegistration)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void (*requestPerfCounters)(SOSCloudTransportRef transport, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); @@ -110,7 +109,6 @@ void SOSCloudKeychainGetAllObjectsFromCloud(dispatch_queue_t processQueue, Cloud bool SOSCloudKeychainHasPendingKey(CFStringRef keyName, CFErrorRef* error); void SOSCloudKeychainRequestSyncWithPeers(CFArrayRef /* CFStringRef */ peers, CFArrayRef /* CFStringRef */ backupPeers, dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); -bool SOSCloudKeychainHasPendingSyncWithPeer(CFStringRef peerID, CFErrorRef* error); void SOSCloudKeychainRequestEnsurePeerRegistration(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); void SOSCloudKeychainRequestPerfCounters(dispatch_queue_t processQueue, CloudKeychainReplyBlock replyBlock); diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainConstants.c similarity index 97% rename from OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c rename to keychain/SecureObjectSync/CKBridge/SOSCloudKeychainConstants.c index 7841f7a5..000ff014 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.c +++ b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainConstants.c @@ -40,7 +40,7 @@ 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 *kCKPServiceName = "com.apple.security.cloudkeychainproxy3"; //"CloudKeychainProxy"; const char *kMessageKeyOperation = "operation"; const char *kMessageKeyKey = "key"; diff --git a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainConstants.h similarity index 98% rename from OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h rename to keychain/SecureObjectSync/CKBridge/SOSCloudKeychainConstants.h index a9fda436..931ac3a8 100644 --- a/OSX/sec/SOSCircle/CKBridge/SOSCloudKeychainConstants.h +++ b/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainConstants.h @@ -30,7 +30,7 @@ __BEGIN_DECLS -extern const char *xpcServiceName; +extern const char *kCKPServiceName; extern const char *kMessageKeyOperation; extern const char *kMessageKeyKey; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/CKDSimulatedStore.h b/keychain/SecureObjectSync/CKDSimulatedStore.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/CKDSimulatedStore.h rename to keychain/SecureObjectSync/CKDSimulatedStore.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/CKDSimulatedStore.m b/keychain/SecureObjectSync/CKDSimulatedStore.m similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/CKDSimulatedStore.m rename to keychain/SecureObjectSync/CKDSimulatedStore.m diff --git a/OSX/sec/SOSCircle/Regressions/CKDSimulatedAccount.h b/keychain/SecureObjectSync/Regressions/CKDSimulatedAccount.h similarity index 100% rename from OSX/sec/SOSCircle/Regressions/CKDSimulatedAccount.h rename to keychain/SecureObjectSync/Regressions/CKDSimulatedAccount.h diff --git a/OSX/sec/SOSCircle/Regressions/CKDSimulatedAccount.m b/keychain/SecureObjectSync/Regressions/CKDSimulatedAccount.m similarity index 100% rename from OSX/sec/SOSCircle/Regressions/CKDSimulatedAccount.m rename to keychain/SecureObjectSync/Regressions/CKDSimulatedAccount.m diff --git a/OSX/sec/SOSCircle/Regressions/SOSCircle_regressions.h b/keychain/SecureObjectSync/Regressions/SOSCircle_regressions.h similarity index 100% rename from OSX/sec/SOSCircle/Regressions/SOSCircle_regressions.h rename to keychain/SecureObjectSync/Regressions/SOSCircle_regressions.h diff --git a/OSX/sec/SOSCircle/Regressions/SOSRegressionUtilities.h b/keychain/SecureObjectSync/Regressions/SOSRegressionUtilities.h similarity index 98% rename from OSX/sec/SOSCircle/Regressions/SOSRegressionUtilities.h rename to keychain/SecureObjectSync/Regressions/SOSRegressionUtilities.h index c13a49aa..d4810cc2 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSRegressionUtilities.h +++ b/keychain/SecureObjectSync/Regressions/SOSRegressionUtilities.h @@ -33,7 +33,7 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" __BEGIN_DECLS diff --git a/OSX/sec/SOSCircle/Regressions/SOSRegressionUtilities.m b/keychain/SecureObjectSync/Regressions/SOSRegressionUtilities.m similarity index 97% rename from OSX/sec/SOSCircle/Regressions/SOSRegressionUtilities.m rename to keychain/SecureObjectSync/Regressions/SOSRegressionUtilities.m index 8d733f84..1d343706 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSRegressionUtilities.m +++ b/keychain/SecureObjectSync/Regressions/SOSRegressionUtilities.m @@ -32,15 +32,15 @@ #include #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include "SOSRegressionUtilities.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #if TARGET_OS_IPHONE #include @@ -262,6 +262,7 @@ bool testClearAll(dispatch_queue_t processQueue, dispatch_group_t dgroup) dispatch_group_enter(dgroup); + secnotice("circleOps", "SOSCloudKeychainClearAll called by testClearAll"); SOSCloudKeychainClearAll(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef error) { result = true; diff --git a/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c b/keychain/SecureObjectSync/Regressions/SOSTestDataSource.c similarity index 99% rename from OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c rename to keychain/SecureObjectSync/Regressions/SOSTestDataSource.c index 0ab10983..e7e2ac8e 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.c +++ b/keychain/SecureObjectSync/Regressions/SOSTestDataSource.c @@ -25,8 +25,8 @@ #include "SOSTestDataSource.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSDataSource.h" +#include "keychain/SecureObjectSync/SOSDigestVector.h" #include #include diff --git a/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.h b/keychain/SecureObjectSync/Regressions/SOSTestDataSource.h similarity index 97% rename from OSX/sec/SOSCircle/Regressions/SOSTestDataSource.h rename to keychain/SecureObjectSync/Regressions/SOSTestDataSource.h index 6d0cc615..a49467ca 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSTestDataSource.h +++ b/keychain/SecureObjectSync/Regressions/SOSTestDataSource.h @@ -25,7 +25,7 @@ #ifndef _SEC_SOSTestDataSource_H_ #define _SEC_SOSTestDataSource_H_ -#include +#include "keychain/SecureObjectSync/SOSDataSource.h" extern CFStringRef sSOSDataSourceErrorDomain; diff --git a/OSX/sec/SOSCircle/Regressions/SOSTestDevice.c b/keychain/SecureObjectSync/Regressions/SOSTestDevice.c similarity index 99% rename from OSX/sec/SOSCircle/Regressions/SOSTestDevice.c rename to keychain/SecureObjectSync/Regressions/SOSTestDevice.c index 74147521..fb72a1c8 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSTestDevice.c +++ b/keychain/SecureObjectSync/Regressions/SOSTestDevice.c @@ -29,8 +29,8 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #include #include #include diff --git a/OSX/sec/SOSCircle/Regressions/SOSTestDevice.h b/keychain/SecureObjectSync/Regressions/SOSTestDevice.h similarity index 98% rename from OSX/sec/SOSCircle/Regressions/SOSTestDevice.h rename to keychain/SecureObjectSync/Regressions/SOSTestDevice.h index 33430d95..600bda7c 100644 --- a/OSX/sec/SOSCircle/Regressions/SOSTestDevice.h +++ b/keychain/SecureObjectSync/Regressions/SOSTestDevice.h @@ -21,7 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#include "keychain/SecureObjectSync/SOSMessage.h" #include #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-130-resignationticket.c b/keychain/SecureObjectSync/Regressions/sc-130-resignationticket.c similarity index 97% rename from OSX/sec/SOSCircle/Regressions/sc-130-resignationticket.c rename to keychain/SecureObjectSync/Regressions/sc-130-resignationticket.c index 5bb9b9e7..5ad7629b 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-130-resignationticket.c +++ b/keychain/SecureObjectSync/Regressions/sc-130-resignationticket.c @@ -25,10 +25,10 @@ #include #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-150-backupkeyderivation.c b/keychain/SecureObjectSync/Regressions/sc-150-backupkeyderivation.c similarity index 97% rename from OSX/sec/SOSCircle/Regressions/sc-150-backupkeyderivation.c rename to keychain/SecureObjectSync/Regressions/sc-150-backupkeyderivation.c index a1d3b59b..3120a20a 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-150-backupkeyderivation.c +++ b/keychain/SecureObjectSync/Regressions/sc-150-backupkeyderivation.c @@ -32,13 +32,13 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include #include #include "SOSCircle_regressions.h" #include "SOSRegressionUtilities.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #if 0 static inline CFMutableDataRef CFDataCreateMutableWithRandom(CFAllocatorRef allocator, CFIndex size) { diff --git a/OSX/sec/SOSCircle/Regressions/sc-150-ring.m b/keychain/SecureObjectSync/Regressions/sc-150-ring.m similarity index 96% rename from OSX/sec/SOSCircle/Regressions/sc-150-ring.m rename to keychain/SecureObjectSync/Regressions/sc-150-ring.m index 846ac3bc..c547a988 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-150-ring.m +++ b/keychain/SecureObjectSync/Regressions/sc-150-ring.m @@ -36,12 +36,12 @@ #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSRing.h" +#include "keychain/SecureObjectSync/SOSRingTypes.h" +#include "keychain/SecureObjectSync/SOSRingUtils.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c b/keychain/SecureObjectSync/Regressions/sc-153-backupslicekeybag.c similarity index 97% rename from OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c rename to keychain/SecureObjectSync/Regressions/sc-153-backupslicekeybag.c index c037d864..a1cefeba 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-153-backupslicekeybag.c +++ b/keychain/SecureObjectSync/Regressions/sc-153-backupslicekeybag.c @@ -23,17 +23,17 @@ #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include #include -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include "SOSCircle_regressions.h" #include "SOSRegressionUtilities.h" #define encode_decode_count 2 -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static CF_RETURNS_RETAINED SOSBackupSliceKeyBagRef EncodeDecode(SOSBackupSliceKeyBagRef bag) { SOSBackupSliceKeyBagRef result = NULL; @@ -78,7 +78,7 @@ static const uint8_t sEntropy2[] = { 0x3a, 0x91, 0x0d, 0xc1, 0x5f, 0x57, 0x98, 0x44 }; -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR #define tests_count (8 + encode_decode_count) #else #define tests_count (6) @@ -132,7 +132,7 @@ static void tests(void) SOSBackupSliceKeyBagRef vb2 = NULL; -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR vb = SOSBackupSliceKeyBagCreate(kCFAllocatorDefault, piSet, &localError); ok(vb != NULL, "Allocation: (%@)", localError); CFReleaseNull(localError); diff --git a/OSX/sec/SOSCircle/Regressions/sc-20-keynames.m b/keychain/SecureObjectSync/Regressions/sc-20-keynames.m similarity index 96% rename from OSX/sec/SOSCircle/Regressions/sc-20-keynames.m rename to keychain/SecureObjectSync/Regressions/sc-20-keynames.m index 3dbb1784..a3722490 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-20-keynames.m +++ b/keychain/SecureObjectSync/Regressions/sc-20-keynames.m @@ -27,11 +27,11 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include diff --git a/keychain/SecureObjectSync/Regressions/sc-25-soskeygen.c b/keychain/SecureObjectSync/Regressions/sc-25-soskeygen.c new file mode 100644 index 00000000..42859409 --- /dev/null +++ b/keychain/SecureObjectSync/Regressions/sc-25-soskeygen.c @@ -0,0 +1,289 @@ +// +// sc-25-soskeygen.c +// sec +// +// Created by Richard Murphy on 6/1/15. +// +// + +/* + * 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 "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" + +#include + +#include + +#include +#include +#include "SOSCircle_regressions.h" + +#include "SOSRegressionUtilities.h" +#include +#include +#include +#include +#include +#include +#include + + +#if TARGET_OS_WATCH +#define NPARMS 3 +#define NKEYS 3 +#else +#define NPARMS 10 +#define NKEYS 10 +#endif + + +#define TESTCOMPAT 1 +#if TESTCOMPAT == 1 + +static const uint8_t *der_expect_SecAsn1Oid(const SecAsn1Oid* secasn_oid, const uint8_t *der, const uint8_t *der_end) +{ + size_t len = 0; + der = ccder_decode_tl(CCDER_OBJECT_IDENTIFIER, &len, + der, der_end); + + if (secasn_oid->Length != len || memcmp(secasn_oid->Data, der, len) != 0) + der = NULL; + else + der += len; + + return der; +} + + +static const uint8_t *der_decode_pbkdf2_params(size_t *saltLen, const uint8_t **salt, + unsigned long *iterationCount, + unsigned long *keyLength, + const uint8_t *der, const uint8_t *der_end) +{ + const uint8_t * body_end = NULL; + der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &body_end, der, der_end); + + if (body_end != der_end) + der = NULL; + + size_t salt_size = 0; + const uint8_t *salt_bytes = NULL; + + der = ccder_decode_tl(CCDER_OCTET_STRING, &salt_size, der, body_end); + salt_bytes = der; + der += salt_size; + + uint64_t iteration_count = 0; + uint64_t key_len = 0; + der = ccder_decode_uint64(&iteration_count, der, body_end); + if (iteration_count > UINT32_MAX) + der = NULL; + + der = ccder_decode_uint64(&key_len, der, body_end); + if (key_len > UINT32_MAX) + der = NULL; + + der = der_expect_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1, der, body_end); + + if (der) { + if (salt) + *salt = salt_bytes; + if (saltLen) + *saltLen = salt_size; + if (iterationCount) + *iterationCount = (unsigned long)iteration_count; + if (keyLength) + *keyLength = (unsigned long) key_len; + } + + return der; +} +#define SALTMAX 16 +#define ITERATIONMIN 50000 + +static SecKeyRef ccec2SecKey(ccec_full_ctx_t fk) +{ + size_t export_size = ccec_x963_export_size(1, ccec_ctx_pub(fk)); + uint8_t export_keybytes[export_size]; + ccec_x963_export(1, export_keybytes, fk); + CFDataRef exportedkey = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, export_keybytes, export_size, kCFAllocatorNull); + + CFDictionaryRef keyattributes = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, + kSecValueData, exportedkey, + kSecAttrKeyType, kSecAttrKeyTypeEC, + kSecAttrKeyClass, kSecAttrKeyClassPrivate, + NULL); + + SecKeyRef retval = SecKeyCreateFromAttributeDictionary(keyattributes); + + CFRelease(keyattributes); + CFRelease(exportedkey); + cc_clear(export_size, export_keybytes); + return retval; +} + +static SecKeyRef SOSOldUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *error) +{ + size_t saltlen; + const uint8_t *salt = NULL; + + size_t iterations = 0; + size_t keysize = 0; + + const uint8_t *der = CFDataGetBytePtr(parameters); + const uint8_t *der_end = der + CFDataGetLength(parameters); + + der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end); + + if (der == NULL) { + SOSCreateErrorWithFormat(kSOSErrorDecodeFailure, NULL, error, NULL, + CFSTR("Bad paramter encoding, got: %@"), parameters); + return NULL; + } + if (keysize != 256) { + SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL, + CFSTR("Key size not supported, requested %zd."), keysize); + return NULL; + } + if (saltlen < 4) { + SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL, + CFSTR("Salt length not supported, requested %zd."), saltlen); + return NULL; + } + if (iterations < ITERATIONMIN) { + SOSCreateErrorWithFormat(kSOSErrorUnsupported, NULL, error, NULL, + CFSTR("Too few iterations, params suggested %zd."), iterations); + return NULL; + } + + debugDumpUserParameters(CFSTR("params-keygen"), parameters); + + + const uint8_t *password_bytes = CFDataGetBytePtr(password); + size_t password_length = CFDataGetLength(password); + + const size_t maxbytes = 128; + + ccec_const_cp_t cp = ccec_get_cp(keysize); + struct ccrng_pbkdf2_prng_state pbkdf2_prng; + + ccec_full_ctx_decl_cp(cp, tmpkey); + + secnotice("circleOps", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters); + + if (ccrng_pbkdf2_prng_init(&pbkdf2_prng, maxbytes, + password_length, password_bytes, + saltlen, salt, + iterations)) { + SOSCreateError(kSOSErrorProcessingFailure, CFSTR("prng init failed"), NULL, error); + return NULL; + } + + if (ccec_generate_key_legacy(cp, (struct ccrng_state *)&pbkdf2_prng, tmpkey)) { + SOSCreateError(kSOSErrorProcessingFailure, CFSTR("Keygen failed"), NULL, error); + return NULL; + } + + return ccec2SecKey(tmpkey); +} + + +static SecKeyRef createOldTestKey(CFDataRef cfpassword, CFDataRef parameters, CFErrorRef *error) { + SecKeyRef user_privkey = SOSOldUserKeygen(cfpassword, parameters, error); + ok(user_privkey, "No key!"); + ok(*error == NULL, "Error: (%@)", *error); + CFReleaseNull(*error); + return user_privkey; +} + +#endif /* TESTCOMPAT */ + +static SecKeyRef createTestKey(CFDataRef cfpassword, CFDataRef parameters, CFErrorRef *error) { + SecKeyRef user_privkey = SOSUserKeygen(cfpassword, parameters, error); + ok(user_privkey, "No key!"); + ok(*error == NULL, "Error: (%@)", *error); + CFReleaseNull(*error); + return user_privkey; +} + +static void tests(void) { + CFErrorRef error = NULL; + CFDataRef cfpassword = CFDataCreate(NULL, (uint8_t *) "FooFooFoo", 10); + + for(int j=0; j < NPARMS; j++) { + CFDataRef parameters = SOSUserKeyCreateGenerateParameters(&error); + ok(parameters, "No parameters!"); + ok(error == NULL, "Error: (%@)", error); + CFReleaseNull(error); + + SecKeyRef baseline_privkey = createTestKey(cfpassword, parameters, &error); + ok(baseline_privkey != NULL, "Failed to create baseline privkey"); + if(baseline_privkey) { + SecKeyRef baseline_pubkey = SecKeyCreatePublicFromPrivate(baseline_privkey); + + for(int i = 0; i < NKEYS; i++) { + SecKeyRef user_privkey = createTestKey(cfpassword, parameters, &error); + SecKeyRef user_pubkey = SecKeyCreatePublicFromPrivate(user_privkey); + ok(CFEqualSafe(baseline_privkey, user_privkey), "Private Keys Don't Match"); + ok(CFEqualSafe(baseline_pubkey, user_pubkey), "Public Keys Don't Match"); +#if TESTCOMPAT == 1 + SecKeyRef old_privkey = createOldTestKey(cfpassword, parameters, &error); + SecKeyRef old_pubkey = SecKeyCreatePublicFromPrivate(old_privkey); + ok(CFEqualSafe(old_privkey, user_privkey), "Old/New Private Keys Don't Match"); + ok(CFEqualSafe(old_pubkey, user_pubkey), "Old/New Public Keys Don't Match"); + CFReleaseNull(old_privkey); + CFReleaseNull(old_pubkey); +#endif /* TESTCOMPAT */ + CFReleaseNull(error); + CFReleaseNull(user_privkey); + CFReleaseNull(user_pubkey); + } + CFReleaseNull(baseline_pubkey); + } + CFReleaseNull(baseline_privkey); + CFReleaseNull(parameters); + } + CFReleaseNull(cfpassword); +} + +int sc_25_soskeygen(int argc, char *const *argv) +{ +#if TARGET_OS_WATCH + plan_tests(NKEYS*(4+NPARMS*4)); +#else + plan_tests(850); +#endif + + tests(); + + return 0; +} diff --git a/OSX/sec/SOSCircle/Regressions/sc-30-peerinfo.c b/keychain/SecureObjectSync/Regressions/sc-30-peerinfo.c similarity index 95% rename from OSX/sec/SOSCircle/Regressions/sc-30-peerinfo.c rename to keychain/SecureObjectSync/Regressions/sc-30-peerinfo.c index 83d40131..66c95929 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-30-peerinfo.c +++ b/keychain/SecureObjectSync/Regressions/sc-30-peerinfo.c @@ -27,13 +27,13 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" -#include +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-31-peerinfo-simplefuzz.c b/keychain/SecureObjectSync/Regressions/sc-31-peerinfo-simplefuzz.c similarity index 89% rename from OSX/sec/SOSCircle/Regressions/sc-31-peerinfo-simplefuzz.c rename to keychain/SecureObjectSync/Regressions/sc-31-peerinfo-simplefuzz.c index 9d1ff9d0..800a241d 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-31-peerinfo-simplefuzz.c +++ b/keychain/SecureObjectSync/Regressions/sc-31-peerinfo-simplefuzz.c @@ -10,13 +10,13 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" -#include +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-40-circle.c b/keychain/SecureObjectSync/Regressions/sc-40-circle.c similarity index 97% rename from OSX/sec/SOSCircle/Regressions/sc-40-circle.c rename to keychain/SecureObjectSync/Regressions/sc-40-circle.c index 2e706b00..365b88bf 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-40-circle.c +++ b/keychain/SecureObjectSync/Regressions/sc-40-circle.c @@ -27,12 +27,12 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-42-circlegencount.c b/keychain/SecureObjectSync/Regressions/sc-42-circlegencount.c similarity index 92% rename from OSX/sec/SOSCircle/Regressions/sc-42-circlegencount.c rename to keychain/SecureObjectSync/Regressions/sc-42-circlegencount.c index 4a22c974..87158469 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-42-circlegencount.c +++ b/keychain/SecureObjectSync/Regressions/sc-42-circlegencount.c @@ -13,11 +13,11 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-45-digestvector.c b/keychain/SecureObjectSync/Regressions/sc-45-digestvector.c similarity index 99% rename from OSX/sec/SOSCircle/Regressions/sc-45-digestvector.c rename to keychain/SecureObjectSync/Regressions/sc-45-digestvector.c index b6fe07f5..7f86e643 100644 --- a/OSX/sec/SOSCircle/Regressions/sc-45-digestvector.c +++ b/keychain/SecureObjectSync/Regressions/sc-45-digestvector.c @@ -24,7 +24,7 @@ #include "SOSCircle_regressions.h" -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" #include #include diff --git a/OSX/sec/SOSCircle/Regressions/sc-kvstool.m b/keychain/SecureObjectSync/Regressions/sc-kvstool.m similarity index 100% rename from OSX/sec/SOSCircle/Regressions/sc-kvstool.m rename to keychain/SecureObjectSync/Regressions/sc-kvstool.m diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSARCDefines.h b/keychain/SecureObjectSync/SOSARCDefines.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSARCDefines.h rename to keychain/SecureObjectSync/SOSARCDefines.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h b/keychain/SecureObjectSync/SOSAccount.h similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h rename to keychain/SecureObjectSync/SOSAccount.h index f19f91b2..a01d0384 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.h +++ b/keychain/SecureObjectSync/SOSAccount.h @@ -33,15 +33,15 @@ #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" #include #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSTransportCircle.h" +#include "keychain/SecureObjectSync/SOSRing.h" +#include "keychain/SecureObjectSync/SOSRecoveryKeyBag.h" +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" #include @class SOSAccount; @@ -197,7 +197,8 @@ CFStringRef SOSAccountCopyIncompatibilityInfo(SOSAccount* account, CFErrorRef* bool SOSAccountIsBackupRingEmpty(SOSAccount* account, CFStringRef viewName); bool SOSAccountNewBKSBForView(SOSAccount* account, CFStringRef viewName, CFErrorRef *error); - +void SOSAccountProcessBackupRings(SOSAccount* account, CFErrorRef *error); +bool SOSAccountValidateBackupRingForView(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); @@ -214,9 +215,13 @@ bool SOSAccountIsLastBackupPeer(SOSAccount* account, CFErrorRef *error); bool SOSAccountRegisterRecoveryPublicKey(SOSAccountTransaction* txn, CFDataRef recovery_key, CFErrorRef *error); CFDataRef SOSAccountCopyRecoveryPublicKey(SOSAccountTransaction* txn, CFErrorRef *error); bool SOSAccountClearRecoveryPublicKey(SOSAccountTransaction* txn, CFDataRef recovery_key, CFErrorRef *error); + + +// Internal calls that sets or clears Recovery Keys for the Account Object Provided by Clients bool SOSAccountSetRecoveryKey(SOSAccount* account, CFDataRef pubData, CFErrorRef *error); bool SOSAccountRemoveRecoveryKey(SOSAccount* account, CFErrorRef *error); -SOSRecoveryKeyBagRef SOSAccountCopyRecoveryKeyBag(CFAllocatorRef allocator, SOSAccount* account, CFErrorRef *error); + + CFDataRef SOSAccountCopyRecoveryPublic(CFAllocatorRef allocator, SOSAccount* account, CFErrorRef *error); bool SOSAccountRecoveryKeyIsInBackupAndCurrentInView(SOSAccount* account, CFStringRef viewname); bool SOSAccountSetRecoveryKeyBagEntry(CFAllocatorRef allocator, SOSAccount* account, SOSRecoveryKeyBagRef rkbg, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m b/keychain/SecureObjectSync/SOSAccount.m similarity index 91% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m rename to keychain/SecureObjectSync/SOSAccount.m index 2e1a1cf6..6c514ce6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccount.m +++ b/keychain/SecureObjectSync/SOSAccount.m @@ -9,46 +9,49 @@ #import -#include -#include -#include -#include -#import "Security/SecureObjectSync/SOSTransportCircle.h" -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#import -#import -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Identity.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" -#import "Security/SecureObjectSync/SOSPeerOTRTimer.h" -#import "Security/SecureObjectSync/SOSPeerRateLimiter.h" -#import "Security/SecureObjectSync/SOSTypes.h" +#import "keychain/SecureObjectSync/SOSAccount.h" +#import +#import "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#import "keychain/SecureObjectSync/SOSTransportCircle.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSTransportMessage.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#import "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#import "keychain/SecureObjectSync/SOSKVSKeys.h" +#import "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSPeerCoder.h" +#import "keychain/SecureObjectSync/SOSInternal.h" +#import "keychain/SecureObjectSync/SOSRing.h" +#import "keychain/SecureObjectSync/SOSRingUtils.h" +#import "keychain/SecureObjectSync/SOSRingRecovery.h" +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" +#import "keychain/SecureObjectSync/SOSAccountGhost.h" +#import "keychain/SecureObjectSync/SOSPiggyback.h" +#import "keychain/SecureObjectSync/SOSControlHelper.h" +#import "keychain/SecureObjectSync/SOSAuthKitHelpers.h" + + +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" +#import "keychain/SecureObjectSync/SOSPeerOTRTimer.h" +#import "keychain/SecureObjectSync/SOSPeerRateLimiter.h" +#import "keychain/SecureObjectSync/SOSTypes.h" #if OCTAGON #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSLockStateTracker.h" #import "keychain/ot/OTContext.h" +#import "keychain/ot/OTManager.h" #endif #include #include -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" +#include -#include #import "SecdWatchdog.h" @@ -124,7 +127,6 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.change_blocks = [NSMutableArray array]; self.waitForInitialSync_blocks = [NSMutableDictionary dictionary]; - self.isInitialSyncing = false; self.accountKeyIsTrusted = false; self.accountKeyDerivationParamters = nil; @@ -255,7 +257,6 @@ const CFStringRef kSOSAccountDebugScope = CFSTR("Scope"); self.deviceID = nil; self.waitForInitialSync_blocks = [NSMutableDictionary dictionary]; - self.isInitialSyncing = false; self.accountKeyIsTrusted = false; self.accountKeyDerivationParamters = NULL; self.accountKey = NULL; @@ -455,6 +456,8 @@ static bool Flush(CFErrorRef *error) { return; } + sleep(1); // make up for keygen time in password based version - let syncdefaults catch up + [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { SecKeyRef accountPrivateKey = NULL; CFErrorRef error = NULL; @@ -499,19 +502,178 @@ static bool Flush(CFErrorRef *error) { { __block CFErrorRef localError = NULL; __block NSData *applicationBlob = NULL; - SecAKSDoWhileUserBagLocked(&localError, ^{ + [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { + SOSPeerInfoRef application = SOSAccountCopyApplication(txn.account, &localError); + if (application) { + applicationBlob = CFBridgingRelease(SOSPeerInfoCopyEncodedData(application, kCFAllocatorDefault, &localError)); + CFReleaseNull(application); + } + }]; + complete(applicationBlob, (__bridge NSError *)localError); + CFReleaseNull(localError); +} + +- (void)circleHash:(void (^)(NSString *, NSError *))complete +{ + __block CFErrorRef localError = NULL; + __block NSString *circleHash = NULL; + SecAKSDoWithUserBagLockAssertion(&localError, ^{ [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { - SOSPeerInfoRef application = SOSAccountCopyApplication(txn.account, &localError); - if (application) { - applicationBlob = CFBridgingRelease(SOSPeerInfoCopyEncodedData(application, kCFAllocatorDefault, &localError)); - CFReleaseNull(application); - } + circleHash = CFBridgingRelease(SOSCircleCopyHashString(txn.account.trust.trustedCircle)); }]; }); - complete(applicationBlob, (__bridge NSError *)localError); + complete(circleHash, (__bridge NSError *)localError); CFReleaseNull(localError); + +} + + +#if TARGET_OS_OSX || TARGET_OS_IOS + + ++ (SOSAccountGhostBustingOptions) ghostBustGetRampSettings { + OTManager *otm = [OTManager manager]; + SOSAccountGhostBustingOptions options = ([otm ghostbustByMidEnabled] == YES ? SOSGhostBustByMID: 0) | + ([otm ghostbustBySerialEnabled] == YES ? SOSGhostBustBySerialNumber : 0) | + ([otm ghostbustByAgeEnabled] == YES ? SOSGhostBustSerialByAge: 0); + return options; } + +#define GHOSTBUSTDATE @"ghostbustdate" + +- (NSDate *) ghostBustGetDate { + if(! self.settings) { + self.settings = [[NSUserDefaults alloc] initWithSuiteName:SOSAccountUserDefaultsSuite]; + } + return [self.settings valueForKey:GHOSTBUSTDATE]; +} + +- (bool) ghostBustCheckDate { + NSDate *ghostBustDate = [self ghostBustGetDate]; + if(ghostBustDate && ([ghostBustDate timeIntervalSinceNow] <= 0)) return true; + return false; +} + +- (void) ghostBustFollowup { + if(! self.settings) { + self.settings = [[NSUserDefaults alloc] initWithSuiteName:SOSAccountUserDefaultsSuite]; + } + NSTimeInterval earliestGB = 60*60*24*3; // wait at least 3 days + NSTimeInterval latestGB = 60*60*24*7; // wait at most 7 days + NSDate *ghostBustDate = SOSCreateRandomDateBetweenNowPlus(earliestGB, latestGB); + [self.settings setValue:ghostBustDate forKey:GHOSTBUSTDATE]; +} + +// GhostBusting initial scheduling +- (void)ghostBustSchedule { + NSDate *ghostBustDate = [self ghostBustGetDate]; + if(!ghostBustDate) { + [self ghostBustFollowup]; + } +} + +- (void) ghostBust:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete { + __block bool result = false; + __block CFErrorRef localError = NULL; + + if([SOSAuthKitHelpers accountIsHSA2]) { + [SOSAuthKitHelpers activeMIDs:^(NSSet * _Nullable activeMIDs, NSError * _Nullable error) { + SOSAuthKitHelpers *akh = [[SOSAuthKitHelpers alloc] initWithActiveMIDS:activeMIDs]; + if(akh) { + SecAKSDoWithUserBagLockAssertion(&localError, ^{ + [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { + result = SOSAccountGhostBustCircle(txn.account, akh, options, 1); + [self ghostBustFollowup]; + }]; + }); + } + complete(result, NULL); + }]; + } else { + complete(false, NULL); + } +} + +- (void) ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete { + NSDate *ghostBustDate = [self ghostBustGetDate]; + if(([ghostBustDate timeIntervalSinceNow] <= 0)) { + if(options) { + [self ghostBust: options complete: complete]; + } else { + complete(false, nil); + } + } +} + +- (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { + // if no particular options are presented use the ramp options. + // If TLKs haven't been set yet this will cause a deadlock. THis interface should only be used by the security tool for internal testing. + if(options == 0) { + options = [SOSAccount ghostBustGetRampSettings]; + } + [self ghostBust: options complete: complete]; +} + +- (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete { + // If TLKs haven't been set yet this will cause a deadlock. THis interface should only be used by the security tool for internal testing. + NSMutableDictionary *gbInfoDictionary = [NSMutableDictionary new]; + SOSAccountGhostBustingOptions options = [SOSAccount ghostBustGetRampSettings]; + NSString *ghostBustDate = [[self ghostBustGetDate] description]; + + gbInfoDictionary[@"SOSGhostBustBySerialNumber"] = (SOSGhostBustBySerialNumber & options) ? @"ON": @"OFF"; + gbInfoDictionary[@"SOSGhostBustByMID"] = (SOSGhostBustByMID & options) ? @"ON": @"OFF"; + gbInfoDictionary[@"SOSGhostBustSerialByAge"] = (SOSGhostBustSerialByAge & options) ? @"ON": @"OFF"; + gbInfoDictionary[@"SOSAccountGhostBustDate"] = ghostBustDate; + + NSError *err = nil; + NSData *json = [NSJSONSerialization dataWithJSONObject:gbInfoDictionary + options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) + error:&err]; + if (!json) { + secnotice("ghostbust", "Error during ghostBustInfo JSONification: %@", err.localizedDescription); + } + complete(json, err); +} + +#else + ++ (SOSAccountGhostBustingOptions) ghostBustGetRampSettings { + return 0; +} + +- (NSDate *) ghostBustGetDate { + return nil; +} + +- (void) ghostBustFollowup { +} + +- (void)ghostBustSchedule { +} + +- (void) ghostBust:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete { + complete(false, NULL); +} + +- (void) ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete { + complete(false, NULL); +} + +- (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { + complete(false, nil); +} + +- (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete { + complete(nil, nil); +} + +- (bool) ghostBustCheckDate { + return false; +} + +#endif + - (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete { __block CFErrorRef localError = NULL; @@ -522,7 +684,8 @@ static bool Flush(CFErrorRef *error) { CFReleaseNull(localError); return; } - SecAKSDoWhileUserBagLocked(&localError, ^{ + + SecAKSDoWithUserBagLockAssertionSoftly(^{ [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { blob = CFBridgingRelease(SOSAccountCopyCircleJoiningBlob(txn.account, peer, &localError)); }]; @@ -539,11 +702,9 @@ static bool Flush(CFErrorRef *error) { __block CFErrorRef localError = NULL; __block bool res = false; - SecAKSDoWhileUserBagLocked(&localError, ^{ - [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { - res = SOSAccountJoinWithCircleJoiningBlob(txn.account, (__bridge CFDataRef)blob, version, &localError); - }]; - }); + [self performTransaction:^(SOSAccountTransaction * _Nonnull txn) { + res = SOSAccountJoinWithCircleJoiningBlob(txn.account, (__bridge CFDataRef)blob, version, &localError); + }]; complete(res, (__bridge NSError *)localError); CFReleaseNull(localError); @@ -584,7 +745,7 @@ static bool Flush(CFErrorRef *error) { secnotice("sync", "trigger a forced sync for %@", peers); - SecAKSDoWhileUserBagLocked(&localError, ^{ + SecAKSDoWithUserBagLockAssertion(&localError, ^{ [self performTransaction:^(SOSAccountTransaction *txn) { if ([peers count]) { NSSet *peersSet = [NSSet setWithArray:peers]; @@ -1266,63 +1427,47 @@ bool SOSAccountEnsureInBackupRings(SOSAccount* account) { __block CFErrorRef error = NULL; secnotice("backup", "Ensuring in rings"); - NSData *backupKey = nil; - if(!account.backup_key){ - result = true; - return result; + return true; } - backupKey = (__bridge_transfer NSData*)SOSPeerInfoV2DictionaryCopyData(account.peerInfo, sBackupKeyKey); - - bool updateBackupKey = ![backupKey isEqual:account.backup_key]; + if(!SOSBSKBIsGoodBackupPublic((__bridge CFDataRef)account.backup_key, &error)){ + secnotice("backupkey", "account backup key isn't valid: %@", error); + account.backup_key = nil; + CFReleaseNull(error); + return false; + } - if(updateBackupKey) { + NSData *peerBackupKey = (__bridge_transfer NSData*)SOSPeerInfoCopyBackupKey(account.peerInfo); + if(![peerBackupKey isEqual:account.backup_key]) { result = SOSAccountUpdatePeerInfo(account, CFSTR("Backup public key"), &error, ^bool(SOSFullPeerInfoRef fpi, CFErrorRef *error) { return SOSFullPeerInfoUpdateBackupKey(fpi, (__bridge CFDataRef)(account.backup_key), error); }); if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error); + secnotice("backupkey", "Failed to setup backup public key in peerInfo from account: %@", error); CFReleaseNull(error); return result; } } - if(!account.backup_key) - { - if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error); - } - CFReleaseNull(error); - return result; - } - if(!SOSBSKBIsGoodBackupPublic((__bridge CFDataRef)account.backup_key, &error)){ - if (!result) { - secnotice("backupkey", "Failed to setup backup public key: %@", error); - } - CFReleaseNull(error); - return result; + + // It's a good key, we're going with it. Stop backing up the old way. + CFErrorRef localError = NULL; + if (!SOSDeleteV0Keybag(&localError)) { + secerror("Failed to delete v0 keybag: %@", localError); } - - CFDataRef recoveryKeyBackFromRing = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, &error); + CFReleaseNull(localError); - if(updateBackupKey || recoveryKeyBackFromRing) { - // It's a good key, we're going with it. Stop backing up the old way. - CFErrorRef localError = NULL; - if (!SOSDeleteV0Keybag(&localError)) { - secerror("Failed to delete v0 keybag: %@", localError); + // Setup backups the new way. + SOSAccountForEachBackupView(account, ^(const void *value) { + CFStringRef viewName = asString(value, NULL); + bool resetRing = SOSAccountValidateBackupRingForView(account, viewName, NULL); + if(resetRing) { + SOSAccountUpdateBackupRing(account, viewName, NULL, ^SOSRingRef(SOSRingRef existing, CFErrorRef *error) { + SOSRingRef newRing = SOSAccountCreateBackupRingForView(account, viewName, error); + return newRing; + }); } - CFReleaseNull(localError); - - result = true; - - // Setup backups the new way. - SOSAccountForEachBackupView(account, ^(const void *value) { - CFStringRef viewName = (CFStringRef)value; - if(updateBackupKey || (recoveryKeyBackFromRing && !SOSAccountRecoveryKeyIsInBackupAndCurrentInView(account, viewName))) { - result &= SOSAccountNewBKSBForView(account, viewName, &error); - } - }); - } + }); if (!result) { secnotice("backupkey", "Failed to setup backup public key: %@", error); @@ -1389,7 +1534,7 @@ static bool SOSAccountJoinCircleWithAnalytics(SOSAccountTransaction* aTxn, SecKe // this also clears initial sync data result = [account.trust resetCircleToOffering:aTxn userKey:user_key err:error]; } else { - SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL); + SOSAccountInitializeInitialSync(account); if (use_cloud_peer) { cloud_full_peer = SOSCircleCopyiCloudFullPeerInfoRef(trust.trustedCircle, NULL); } @@ -1439,7 +1584,7 @@ static bool SOSAccountJoinCircle(SOSAccountTransaction* aTxn, SecKeyRef user_key // this also clears initial sync data result = [account.trust resetCircleToOffering:aTxn userKey:user_key err:error]; } else { - SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL); + SOSAccountInitializeInitialSync(account); if (use_cloud_peer) { cloud_full_peer = SOSCircleCopyiCloudFullPeerInfoRef(trust.trustedCircle, NULL); } @@ -1903,6 +2048,7 @@ void SOSAccountRecordRetiredPeersInCircle(SOSAccount* account) { if (![account isInCircle:NULL]) { return; } + __block bool updateRings = false; SOSAccountTrustClassic *trust = account.trust; [trust modifyCircle:account.circle_transport err:NULL action:^bool (SOSCircleRef circle) { __block bool updated = false; @@ -1916,10 +2062,14 @@ void SOSAccountRecordRetiredPeersInCircle(SOSAccount* account) { if (![account.trust cleanupAfterPeer:account.kvs_message_transport circleTransport:account.circle_transport seconds:RETIREMENT_FINALIZATION_SECONDS circle:circle cleanupPeer:retiree err:&cleanupError]) secerror("Error cleanup up after peer (%@): %@", retiree, cleanupError); CFReleaseSafe(cleanupError); + updateRings = true; } }); return updated; }]; + if(updateRings) { + SOSAccountProcessBackupRings(account, NULL); + } } static const uint64_t maxTimeToWaitInSeconds = 30ull * NSEC_PER_SEC; @@ -2159,7 +2309,7 @@ AddViewManagerResults(NSMutableArray *results, NSMutableSet *seenUUID) NSString *uuid = items[view]; NSDictionary *query = @{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrAccount : uuid, (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, @@ -2190,7 +2340,7 @@ SOSAccountGetAllTLKs(void) //try to grab tlk-piggy items NSDictionary* query = @{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrDescription: @"tlk", (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, @@ -2207,7 +2357,7 @@ SOSAccountGetAllTLKs(void) //try to grab tlk-piggy items query = @{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrDescription: @"tlk-piggy", (id)kSecAttrSynchronizable : (id)kSecAttrSynchronizableAny, @@ -2591,7 +2741,7 @@ bool SOSAccountJoinWithCircleJoiningBlob(SOSAccount* account, CFDataRef joining secnotice("circleOps", "clearing flag in account for piggyback v0"); SOSAccountClearValue(account, kSOSInitialSyncTimeoutV0, NULL); } - SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL); + SOSAccountInitializeInitialSync(account); pbNotice(CFSTR("Joining"), account, gencount, pubKey, signature, version); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m b/keychain/SecureObjectSync/SOSAccountBackup.m similarity index 79% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m rename to keychain/SecureObjectSync/SOSAccountBackup.m index 4e861bc1..3a631f1f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountBackup.m +++ b/keychain/SecureObjectSync/SOSAccountBackup.m @@ -7,13 +7,14 @@ #include "SOSCloudKeychainClient.h" #include -#include -#include + +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" @@ -138,7 +139,7 @@ CFStringRef SOSBackupCopyRingNameForView(CFStringRef viewName) { return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@-tomb"), viewName); } -static bool SOSAccountUpdateBackupRing(SOSAccount* account, CFStringRef viewName, CFErrorRef *error, +bool SOSAccountUpdateBackupRing(SOSAccount* account, CFStringRef viewName, CFErrorRef *error, SOSRingRef (^modify)(SOSRingRef existing, CFErrorRef *error)) { CFStringRef ringName = SOSBackupCopyRingNameForView(viewName); @@ -152,8 +153,6 @@ static bool SOSAccountUpdateBackupRing(SOSAccount* account, CFStringRef viewNam return result; } - - static bool SOSAccountSetKeybagForViewBackupRing(SOSAccount* account, CFStringRef viewName, SOSBackupSliceKeyBagRef keyBag, CFErrorRef *error) { CFMutableSetRef backupViewSet = CFSetCreateMutableForCFTypes(NULL); bool result = false; @@ -373,42 +372,11 @@ void SOSAccountForEachBackupView(SOSAccount* account, void (^operation)(const } -bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef cfBackupKey, CFErrorRef *error) -{ - 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); - }); - }); - - if ([backupKey isEqual:account.backup_key]) - return true; - - account.backup_key = [[NSData alloc] initWithData:backupKey]; - - account.circle_rings_retirements_need_attention = true; - - result = true; - - if (!result) { - secnotice("backupkey", "SetBackupPublic Failed: %@", error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space")); - } - return result; -} - static bool SOSAccountWithBSKBAndPeerInfosForView(SOSAccount* account, CFArrayRef retiree, CFStringRef viewName, CFErrorRef *error, bool (^action)(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error)) { __block SOSBackupSliceKeyBagRef bskb = NULL; bool result = false; - + SOSAccountWithBackupPeersForView(account, viewName, ^(CFSetRef peers) { CFMutableSetRef newPeerList = CFSetCreateMutableCopy(kCFAllocatorDefault, CFSetGetCount(peers), peers); CFArrayForEach(retiree, ^(const void *value) { @@ -429,50 +397,142 @@ static bool SOSAccountWithBSKBAndPeerInfosForView(SOSAccount* account, CFArrayR bskb = SOSBackupSliceKeyBagCreate(kCFAllocatorDefault, newPeerList, error); CFReleaseNull(newPeerList); }); - + require_quiet(bskb, exit); - + action(bskb, error); - + result = true; - + exit: CFReleaseNull(bskb); return result; } -bool SOSAccountRemoveBackupPublickey(SOSAccountTransaction* aTxn, CFErrorRef *error) -{ - SOSAccount* account = aTxn.account; - __block bool result = false; - __block CFArrayRef removals = NULL; +SOSRingRef SOSAccountCreateBackupRingForView(SOSAccount* account, CFStringRef ringBackupViewName, CFErrorRef *error) { + if(!account) return NULL; + if(!ringBackupViewName) return NULL; + SOSPeerInfoRef myPeerInfo = account.trust.peerInfo; + if(!myPeerInfo || !SOSPeerInfoHasBackupKey(myPeerInfo)) return NULL; + if(!SOSPeerInfoIsEnabledView(myPeerInfo, ringBackupViewName)) return NULL; + CFStringRef ringName = SOSBackupCopyRingNameForView(ringBackupViewName); + if(!ringName) return NULL; - account.backup_key = nil; + SOSRingRef newRing = SOSRingCreate(ringName, (__bridge CFStringRef) account.peerID, kSOSRingBackup, error); + CFReleaseNull(ringName); + CFMutableSetRef filteredPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + CFMutableSetRef filteredPeerInfos = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault); - if(!SOSAccountUpdatePeerInfo(account, CFSTR("Backup public key"), error, - ^bool(SOSFullPeerInfoRef fpi, CFErrorRef *error) { - return SOSFullPeerInfoUpdateBackupKey(fpi, NULL, error); - })){ - return result; - } - - removals = CFArrayCreateForCFTypes(kCFAllocatorDefault, - account.peerInfo, NULL); + SOSCircleForEachBackupCapablePeerForView(account.trust.trustedCircle, account.accountKey, ringBackupViewName, ^(SOSPeerInfoRef peer) { + CFSetAddValue(filteredPeerIDs, SOSPeerInfoGetPeerID(peer)); + CFSetAddValue(filteredPeerInfos, peer); + }); + CFMutableSetRef viewSet = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + CFSetAddValue(viewSet, ringBackupViewName); + + SOSBackupSliceKeyBagRef bskb = NULL; + CFDataRef recoveryKeyData = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); + if(recoveryKeyData) { + CFMutableDictionaryRef additionalKeys = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); + CFDictionaryAddValue(additionalKeys, bskbRkbgPrefix, recoveryKeyData); + bskb = SOSBackupSliceKeyBagCreateWithAdditionalKeys(kCFAllocatorDefault, filteredPeerInfos, additionalKeys, error); + CFReleaseNull(additionalKeys); + } else { + bskb = SOSBackupSliceKeyBagCreate(kCFAllocatorDefault, filteredPeerInfos, error); + } + if(bskb) { + SOSRingSetPeerIDs(newRing, filteredPeerIDs); + SOSRingSetBackupKeyBag(newRing, account.fullPeerInfo, viewSet, bskb, error); + SOSBackupRingSetViews(newRing, account.fullPeerInfo, viewSet, error); + } else { + CFReleaseNull(newRing); + } + + CFReleaseNull(viewSet); + CFReleaseNull(filteredPeerIDs); + CFReleaseNull(filteredPeerInfos); + CFReleaseNull(bskb); + CFReleaseNull(recoveryKeyData); + return newRing; +} + +void SOSAccountProcessBackupRings(SOSAccount* account, CFErrorRef *error) { SOSAccountForEachBackupView(account, ^(const void *value) { CFStringRef viewName = (CFStringRef)value; - result = SOSAccountWithBSKBAndPeerInfosForView(account, removals, viewName, error, ^(SOSBackupSliceKeyBagRef bskb, CFErrorRef *error) { - bool result = SOSAccountSetKeybagForViewBackupRing(account, viewName, bskb, error); - return result; + SOSAccountUpdateBackupRing(account, viewName, error, ^SOSRingRef(SOSRingRef existing, CFErrorRef *error) { + SOSRingRef newRing = SOSAccountCreateBackupRingForView(account, viewName, error); + return newRing; }); }); - +} + +bool SOSAccountValidateBackupRingForView(SOSAccount* account, CFStringRef viewName, CFErrorRef *error) { + bool fixBackupRing = false; + CFStringRef ringName = NULL; + SOSRingRef ring = NULL; + CFDataRef recoveryKeyData = NULL; + SOSBackupSliceKeyBagRef currentBSKB = NULL; + CFMutableSetRef filteredPeerIDs = NULL; + CFMutableSetRef filteredPeerInfos = NULL; + CFSetRef ringPeerIDSet = NULL; + + require_action_quiet(account && viewName, errOut, SecError(errSecParam, error, CFSTR("NULL account or viewName parameter"))); + ringName = SOSBackupCopyRingNameForView(viewName); + require_action_quiet(ringName, errOut, CFSTR("No RingName for View")); + ring = SOSAccountCopyRingNamed(account, ringName, error); + require_quiet(ring, errOut); + recoveryKeyData = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); + currentBSKB = SOSRingCopyBackupSliceKeyBag(ring, NULL); + filteredPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + filteredPeerInfos = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault); + + SOSCircleForEachBackupCapablePeerForView(account.trust.trustedCircle, account.accountKey, viewName, ^(SOSPeerInfoRef peer) { + CFSetAddValue(filteredPeerIDs, SOSPeerInfoGetPeerID(peer)); + CFSetAddValue(filteredPeerInfos, peer); + }); - result = true; + ringPeerIDSet = SOSRingCopyPeerIDs(ring); + if(!CFEqual(filteredPeerIDs, ringPeerIDSet)) { + fixBackupRing = true; + } - return result; - + fixBackupRing &= !currentBSKB || + !SOSBSKBAllPeersBackupKeysAreInKeyBag(currentBSKB, filteredPeerInfos) || + !SOSBSKBHasThisRecoveryKey(currentBSKB, recoveryKeyData); + +errOut: + CFReleaseNull(ringName); + CFReleaseNull(ring); + CFReleaseNull(ringPeerIDSet); + CFReleaseNull(recoveryKeyData); + CFReleaseNull(currentBSKB); + CFReleaseNull(filteredPeerIDs); + CFReleaseNull(filteredPeerInfos); + return fixBackupRing; +} + +bool SOSAccountSetBackupPublicKey(SOSAccountTransaction* aTxn, CFDataRef cfBackupKey, CFErrorRef *error) +{ + SOSAccount* account = aTxn.account; + __block bool result = false; + + account.backup_key = nil; + if(!SOSAccountUpdatePeerInfo(account, CFSTR("Backup public key"), error, ^bool(SOSFullPeerInfoRef fpi, CFErrorRef *error) { + return SOSFullPeerInfoUpdateBackupKey(fpi, cfBackupKey, error); + })){ + return result; + } + SOSAccountProcessBackupRings(account, NULL); + return true; + +} + + +bool SOSAccountRemoveBackupPublickey(SOSAccountTransaction* aTxn, CFErrorRef *error) +{ + return SOSAccountSetBackupPublicKey(aTxn, NULL, error); } bool SOSAccountSetBSKBagForAllSlices(SOSAccount* account, CFDataRef aks_bag, bool setupV0Only, CFErrorRef *error){ @@ -518,7 +578,6 @@ static CF_RETURNS_RETAINED CFMutableArrayRef SOSAccountIsRetiredPeerIDInBackupPe }); return removals; - } bool SOSAccountRemoveBackupPeers(SOSAccount* account, CFArrayRef peers, CFErrorRef *error){ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m b/keychain/SecureObjectSync/SOSAccountCircles.m similarity index 60% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m rename to keychain/SecureObjectSync/SOSAccountCircles.m index 5a2418c6..26e84b44 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCircles.m +++ b/keychain/SecureObjectSync/SOSAccountCircles.m @@ -3,16 +3,16 @@ // sec // -#import -#import -#import -#import -#import -#import -#import -#import - -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#import "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSTransportCircleCK.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" + +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include "SOSCloudKeychainClient.h" // diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCloudParameters.m b/keychain/SecureObjectSync/SOSAccountCloudParameters.m similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCloudParameters.m rename to keychain/SecureObjectSync/SOSAccountCloudParameters.m index 88cdf2fe..9da7355e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCloudParameters.m +++ b/keychain/SecureObjectSync/SOSAccountCloudParameters.m @@ -4,8 +4,8 @@ // #include "SOSAccountPriv.h" -#include -#include +#include "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#include "keychain/SecureObjectSync/SOSCircleDer.h" // // Cloud Paramters encode/decode // diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m b/keychain/SecureObjectSync/SOSAccountCredentials.m similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m rename to keychain/SecureObjectSync/SOSAccountCredentials.m index 39387635..a2d80366 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountCredentials.m +++ b/keychain/SecureObjectSync/SOSAccountCredentials.m @@ -27,8 +27,8 @@ #include "SOSAccountPriv.h" #include "SOSPeerInfoCollections.h" #include "SOSTransport.h" -#import -#import +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #define kPublicKeyAvailable "com.apple.security.publickeyavailable" // @@ -245,7 +245,7 @@ void SOSAccountStashAccountKey(SOSAccount* account) (__bridge id)kSecClass : (__bridge id)kSecClassInternetPassword, (__bridge id)kSecAttrAccount : SOSUserCredentialAccount, (__bridge id)kSecAttrAccessGroup : SOSUserCredentialAccessGroup, - (__bridge id)kSecAttrNoLegacy : @YES, + (__bridge id)kSecUseDataProtectionKeychain : @YES, }; status = SecItemUpdate((__bridge CFDictionaryRef)attributes, (__bridge CFDictionaryRef)@{ @@ -351,19 +351,28 @@ void SOSAccountSetParameters(SOSAccount* account, CFDataRef parameters) { bool SOSAccountValidateAccountCredential(SOSAccount* account, SecKeyRef accountPrivateKey, CFErrorRef *error) { - SecKeyRef publicCandidate = NULL; bool res = false; + SecKeyRef publicCandidate = SecKeyCreatePublicFromPrivate(accountPrivateKey); - publicCandidate = SecKeyCreatePublicFromPrivate(accountPrivateKey); - - require_action_quiet(CFEqualSafe(account.accountKey, publicCandidate), fail, - SOSCreateErrorWithFormat(kSOSErrorWrongPassword, NULL, error, NULL, CFSTR("account private key no doesn't match validated public key: candidate: %@ accountKey: %@"), publicCandidate, account.accountKey)); - - res = true; -fail: + if(CFEqualSafe(account.accountKey, publicCandidate)) { + res = true; + } else { + CFErrorRef localError = NULL; + CFStringRef accountHpub = SOSCopyIDOfKey(account.accountKey, NULL); + CFStringRef candidateHpub = SOSCopyIDOfKey(publicCandidate, NULL); + SOSCreateErrorWithFormat(kSOSErrorWrongPassword, NULL, &localError, NULL, CFSTR("Password generated pubkey doesn't match - candidate: %@ known: %@"), candidateHpub, accountHpub); + secnotice("circleop", "%@", localError); + if (error) { + *error = localError; + localError = NULL; + } else { + CFReleaseNull(localError); + } + CFReleaseNull(accountHpub); + CFReleaseNull(candidateHpub); + } CFReleaseNull(publicCandidate); return res; - } bool SOSAccountAssertStashedAccountCredential(SOSAccount* account, CFErrorRef *error) @@ -374,7 +383,6 @@ bool SOSAccountAssertStashedAccountCredential(SOSAccount* account, CFErrorRef *e require_action(account.accountKey, fail, SOSCreateError(kSOSErrorWrongPassword, CFSTR("account public key missing, can't check stashed copy"), NULL, error)); require_action(account.accountKeyIsTrusted, fail, SOSCreateError(kSOSErrorWrongPassword, CFSTR("public key no not valid, can't check stashed copy"), NULL, error)); - accountPrivateKey = SOSAccountCopyStashedUserPrivateKey(account, error); require_action_quiet(accountPrivateKey, fail, secnotice("circleOps", "Looked for a stashed private key, didn't find one")); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountDer.m b/keychain/SecureObjectSync/SOSAccountDer.m similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountDer.m rename to keychain/SecureObjectSync/SOSAccountDer.m index 4dce951a..3e27fd61 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountDer.m +++ b/keychain/SecureObjectSync/SOSAccountDer.m @@ -23,7 +23,7 @@ #include "SOSAccountPriv.h" -#include +#include "keychain/SecureObjectSync/SOSCircleDer.h" // // DER Encoding utilities diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m b/keychain/SecureObjectSync/SOSAccountFullPeerInfo.m similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m rename to keychain/SecureObjectSync/SOSAccountFullPeerInfo.m index 2acb59f7..834c75d7 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountFullPeerInfo.m +++ b/keychain/SecureObjectSync/SOSAccountFullPeerInfo.m @@ -25,16 +25,15 @@ #include #include "SOSAccountPriv.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include "SOSViews.h" #include "SOSPeerInfoV2.h" #include "SOSPeerInfoPriv.h" -#import -#import -#import -#include -#include - +#import "keychain/SecureObjectSync/SOSAccountPriv.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" static CFStringRef kicloud_identity_name = CFSTR("Cloud Identity"); @@ -200,12 +199,12 @@ fail: 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); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGetSet.m b/keychain/SecureObjectSync/SOSAccountGetSet.m similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGetSet.m rename to keychain/SecureObjectSync/SOSAccountGetSet.m index 5fd60977..dd28a81d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountGetSet.m +++ b/keychain/SecureObjectSync/SOSAccountGetSet.m @@ -8,8 +8,8 @@ #include -#import -#import +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" // // MARK: Generic Value manipulation diff --git a/keychain/SecureObjectSync/SOSAccountGhost.h b/keychain/SecureObjectSync/SOSAccountGhost.h new file mode 100644 index 00000000..e93eaafc --- /dev/null +++ b/keychain/SecureObjectSync/SOSAccountGhost.h @@ -0,0 +1,36 @@ +// +// SOSAccountGhost.h +// sec +// +// +// + +#ifndef SOSAccountGhost_h +#define SOSAccountGhost_h + +#include "SOSAccount.h" +#include "keychain/SecureObjectSync/SOSTypes.h" + +#define GHOSTBUST_PERIODIC 1 + +bool SOSAccountGhostResultsInReset(SOSAccount* account); +CF_RETURNS_RETAINED SOSCircleRef SOSAccountCloneCircleWithoutMyGhosts(SOSAccount* account, SOSCircleRef startCircle); + +#if __OBJC__ +@class SOSAuthKitHelpers; + +/* + * Ghostbust devices that are not in circle + * + * @param account account to operate on + * @param akh injection of parameters + * @param mincount if circle is smaller the + * + * @return true if there was a device busted + */ + +bool SOSAccountGhostBustCircle(SOSAccount *account, SOSAuthKitHelpers *akh, SOSAccountGhostBustingOptions options, int mincount); + +#endif + +#endif /* SOSAccountGhost_h */ diff --git a/keychain/SecureObjectSync/SOSAccountGhost.m b/keychain/SecureObjectSync/SOSAccountGhost.m new file mode 100644 index 00000000..a278a5a3 --- /dev/null +++ b/keychain/SecureObjectSync/SOSAccountGhost.m @@ -0,0 +1,336 @@ +// +// SOSAccountGhost.c +// sec +// +// Created by Richard Murphy on 4/12/16. +// +// + +#include "SOSAccountPriv.h" +#include "SOSAccountGhost.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#include +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSAuthKitHelpers.h" +#import "Analytics/Clients/SOSAnalytics.h" + +#define DETECT_IOS_ONLY 1 + +static bool sosGhostCheckValid(SOSPeerInfoRef pi) { +#if DETECT_IOS_ONLY + bool retval = false; + require_quiet(pi, retOut); + SOSPeerInfoDeviceClass peerClass = SOSPeerInfoGetClass(pi); + switch(peerClass) { + case SOSPeerInfo_iOS: + case SOSPeerInfo_tvOS: + case SOSPeerInfo_watchOS: + case SOSPeerInfo_macOS: + retval = true; + break; + case SOSPeerInfo_iCloud: + case SOSPeerInfo_unknown: + default: + retval = false; + break; + } +retOut: + return retval; +#else + return true; +#endif +} + +static CFSetRef SOSCircleCreateGhostsOfPeerSet(SOSCircleRef circle, SOSPeerInfoRef me) { + CFMutableSetRef ghosts = NULL; + require_quiet(me, errOut); + require_quiet(sosGhostCheckValid(me), errOut); + require_quiet(circle, errOut); + require_quiet(SOSPeerInfoSerialNumberIsSet(me), errOut); + CFStringRef mySerial = SOSPeerInfoCopySerialNumber(me); + require_quiet(mySerial, errOut); + CFStringRef myPeerID = SOSPeerInfoGetPeerID(me); + ghosts = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + require_quiet(ghosts, errOut1); + SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef pi) { + CFStringRef theirPeerID = SOSPeerInfoGetPeerID(pi); + if(!CFEqual(myPeerID, theirPeerID)) { + CFStringRef piSerial = SOSPeerInfoCopySerialNumber(pi); + if(CFEqualSafe(mySerial, piSerial)) { + CFSetAddValue(ghosts, theirPeerID); + } + CFReleaseNull(piSerial); + } + }); +errOut1: + CFReleaseNull(mySerial); +errOut: + return ghosts; +} + +static void SOSCircleClearMyGhosts(SOSCircleRef circle, SOSPeerInfoRef me) { + CFSetRef ghosts = SOSCircleCreateGhostsOfPeerSet(circle, me); + if(!ghosts || CFSetGetCount(ghosts) == 0) { + CFReleaseNull(ghosts); + return; + } + SOSCircleRemovePeersByIDUnsigned(circle, ghosts); + CFReleaseNull(ghosts); +} + +// This only works if you're in the circle and have the private key +CF_RETURNS_RETAINED SOSCircleRef SOSAccountCloneCircleWithoutMyGhosts(SOSAccount* account, SOSCircleRef startCircle) { + SOSCircleRef newCircle = NULL; + CFSetRef ghosts = NULL; + require_quiet(account, retOut); + SecKeyRef userPrivKey = SOSAccountGetPrivateCredential(account, NULL); + require_quiet(userPrivKey, retOut); + SOSPeerInfoRef me = account.peerInfo; + require_quiet(me, retOut); + bool iAmApplicant = SOSCircleHasApplicant(startCircle, me, NULL); + + ghosts = SOSCircleCreateGhostsOfPeerSet(startCircle, me); + require_quiet(ghosts, retOut); + require_quiet(CFSetGetCount(ghosts), retOut); + + CFStringSetPerformWithDescription(ghosts, ^(CFStringRef description) { + secnotice("ghostbust", "Removing peers: %@", description); + }); + + newCircle = SOSCircleCopyCircle(kCFAllocatorDefault, startCircle, NULL); + require_quiet(newCircle, retOut); + if(iAmApplicant) { + if(SOSCircleRemovePeersByIDUnsigned(newCircle, ghosts) && (SOSCircleCountPeers(newCircle) == 0)) { + secnotice("resetToOffering", "Reset to offering with last ghost and me as applicant"); + if(!SOSCircleResetToOffering(newCircle, userPrivKey, account.fullPeerInfo, NULL) || + ![account.trust addiCloudIdentity:newCircle key:userPrivKey err:NULL]){ + CFReleaseNull(newCircle); + } + account.notifyBackupOnExit = true; + } else { + CFReleaseNull(newCircle); + } + } else { + SOSCircleRemovePeersByID(newCircle, userPrivKey, account.fullPeerInfo, ghosts, NULL); + } +retOut: + CFReleaseNull(ghosts); + return newCircle; +} + + +static NSUInteger SOSGhostBustThinSerialClones(SOSCircleRef circle, NSString *myPeerID) { + NSUInteger gbcount = 0; + CFMutableArrayRef sortPeers = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); + SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) { + CFArrayAppendValue(sortPeers, peer); + }); + CFRange range = CFRangeMake(0, CFArrayGetCount(sortPeers)); + CFArraySortValues(sortPeers, range, SOSPeerInfoCompareByApplicationDate, NULL); + + NSMutableDictionary *latestPeers = [[NSMutableDictionary alloc] init]; + NSMutableSet *removals = [[NSMutableSet alloc] init]; + + for(CFIndex i = CFArrayGetCount(sortPeers); i > 0; i--) { + SOSPeerInfoRef pi = (SOSPeerInfoRef) CFArrayGetValueAtIndex(sortPeers, i-1); + + if(sosGhostCheckValid(pi)) { + NSString *serial = CFBridgingRelease(SOSPeerInfoV2DictionaryCopyString(pi, sSerialNumberKey)); + NSString *peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(pi); + if(serial != nil) { + if([latestPeers objectForKey:serial] != nil) { + if(peerID != myPeerID) { + [removals addObject:peerID]; + } else { + secnotice("ghostBust", "There is a more recent peer for this serial number"); + } + } else { + [latestPeers setObject:peerID forKey:serial]; + } + } else { + secnotice("ghostBust", "Removing peerID (%@) with no serial number", peerID); + [removals addObject:peerID]; + } + } + } + SOSCircleRemovePeersByIDUnsigned(circle, (__bridge CFSetRef)(removals)); + gbcount = [removals count]; + CFReleaseNull(sortPeers); + return gbcount; +} + +static void SOSCircleRemoveiCloudIdentities(SOSCircleRef circle) { + NSMutableSet *removals = [[NSMutableSet alloc] init]; + SOSCircleForEachiCloudIdentityPeer(circle, ^(SOSPeerInfoRef peer) { + NSString *peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peer); + [removals addObject:peerID]; + }); + SOSCircleRemovePeersByIDUnsigned(circle, (__bridge CFSetRef)(removals)); +} + +bool SOSAccountGhostResultsInReset(SOSAccount* account) { + if(!account.peerID || !account.trust.trustedCircle) return false; + SOSCircleRef newCircle = SOSCircleCopyCircle(kCFAllocatorDefault, account.trust.trustedCircle, NULL); + if(!newCircle) return false; + SOSCircleClearMyGhosts(newCircle, account.peerInfo); + SOSCircleRemoveRetired(newCircle, NULL); + SOSCircleRemoveiCloudIdentities(newCircle); + int npeers = SOSCircleCountPeers(newCircle); + CFReleaseNull(newCircle); + return npeers == 0; +} + +static NSUInteger SOSGhostBustThinByMIDList(SOSCircleRef circle, NSString *myPeerID, SOSAuthKitHelpers *akh, SOSAccountGhostBustingOptions options, NSMutableDictionary *attributes) { + __block unsigned int gbmid = 0; + __block unsigned int gbserial = 0; + + NSMutableSet *removals = [[NSMutableSet alloc] init]; + SOSCircleForEachPeer(circle, ^(SOSPeerInfoRef peer) { + NSString *peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peer); + if([peerID isEqualToString:myPeerID]) { + return; + } + if(options & SOSGhostBustByMID) { + NSString *mid = CFBridgingRelease(SOSPeerInfoV2DictionaryCopyString(peer, sMachineIDKey)); + if(![akh midIsValidInList:mid]) { + [removals addObject:peerID]; + gbmid++; + return; + } + } + if(options & SOSGhostBustBySerialNumber) { + NSString *serial = CFBridgingRelease(SOSPeerInfoV2DictionaryCopyString(peer, sSerialNumberKey)); + if(![akh serialIsValidInList: serial]) { + [removals addObject:peerID]; + gbserial++; + return; + } + } + }); + + // Now use the removal set to ghostbust the circle + SOSCircleRemovePeersByIDUnsigned(circle, (__bridge CFSetRef) removals); + attributes[@"byMID"] = @(gbmid); + attributes[@"bySerial"] = @(gbserial); + return [removals count]; +} + +static bool SOSGhostBustiCloudIdentityPrivateKeys(SOSAccount *account) { + __block bool cleaned = false; + SecKeyRef pubKey = NULL; + CFTypeRef queryResult = NULL; + CFDataRef pubKeyHash = NULL; + CFDictionaryRef query = NULL; + __block int removed = 0; + + SOSFullPeerInfoRef iCloudIdentity = SOSCircleCopyiCloudFullPeerInfoVerifier(account.trust.trustedCircle, NULL); + require_action_quiet(iCloudIdentity, retOut, secnotice("ghostBust", "No iCloud Identity FPI")); + pubKey = SOSFullPeerInfoCopyPubKey(iCloudIdentity, NULL); + require_action_quiet(pubKey, retOut, secnotice("ghostBust", "Can't get iCloud Identity pubkey")); + pubKeyHash = SecKeyCopyPublicKeyHash(pubKey); + require_action_quiet(pubKeyHash, retOut, secnotice("ghostBust", "Can't get iCloud Identity pubkey hash")); + query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, + kSecMatchLimit, kSecMatchLimitAll, + kSecClass, kSecClassKey, + kSecAttrKeyClass, kSecAttrKeyClassPrivate, + kSecAttrSynchronizable, kSecAttrSynchronizableAny, + kSecReturnAttributes, kCFBooleanTrue, + kSecAttrAccessGroup, kSOSInternalAccessGroup, + NULL); + require_action_quiet(errSecSuccess == SecItemCopyMatching(query, &queryResult), retOut, secnotice("ghostBust", "Can't get iCloud Identity private keys")); + require_action_quiet(CFGetTypeID(queryResult) == CFArrayGetTypeID(), retOut, cleaned = true); + CFArrayRef iCloudPrivKeys = queryResult; + secnotice("ghostBust", "Screening %ld icloud private keys", (long)CFArrayGetCount(iCloudPrivKeys)); + CFArrayForEach(iCloudPrivKeys, ^(const void *value) { + CFDictionaryRef privkey = asDictionary(value, NULL); + if(privkey) { + CFDataRef candidate = asData(CFDictionaryGetValue(privkey, kSecAttrApplicationLabel), NULL); + if(candidate && !CFEqual(pubKeyHash, candidate)) { + CFStringRef label = asString(CFDictionaryGetValue(privkey, kSecAttrLabel), NULL); + if(label) { + if(CFStringHasPrefix(label, CFSTR("Cloud Identity"))) { + + CFDictionaryRef delQuery = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, + kSecClass, kSecClassKey, + kSecAttrKeyClass, kSecAttrKeyClassPrivate, + kSecAttrSynchronizable, kSecAttrSynchronizableAny, + kSecAttrApplicationLabel, candidate, + NULL); + + OSStatus status = SecItemDelete(delQuery); + if(errSecSuccess == status) { + secnotice("ghostBust", "removed %@", label); + removed++; + cleaned = true; + } else { + secnotice("ghostbust", "Search for %@ returned %d", candidate, (int) status); + } + CFReleaseNull(delQuery); + } + } + } + } + }); + secnotice("ghostBust", "Removed %d icloud private keys", removed); +retOut: + CFReleaseNull(query); + CFReleaseNull(queryResult); + CFReleaseNull(pubKeyHash); + CFReleaseNull(pubKey); + CFReleaseNull(iCloudIdentity); + return cleaned; +} + +bool SOSAccountGhostBustCircle(SOSAccount *account, SOSAuthKitHelpers *akh, SOSAccountGhostBustingOptions options, int mincount) { + __block bool result = false; + CFErrorRef localError = NULL; + __block NSUInteger nbusted = 9999; + __block NSMutableDictionary *attributes =[NSMutableDictionary new]; + + if ([akh isUseful] && [account isInCircle:nil] && SOSCircleCountPeers(account.trust.trustedCircle) > mincount) { + if(options & SOSGhostBustiCloudIdentities) { + secnotice("ghostBust", "Callout to cleanup icloud identities"); + result = SOSGhostBustiCloudIdentityPrivateKeys(account); + } else { + [account.trust modifyCircle:account.circle_transport err:&localError action:^(SOSCircleRef circle) { + nbusted = SOSGhostBustThinByMIDList(circle, account.peerID, akh, options, attributes); + secnotice("ghostbust", "Removed %lu ghosts from circle by midlist && serialNumber", (unsigned long)nbusted); + if(options & SOSGhostBustSerialByAge) { + NSUInteger thinBusted = 9999; + thinBusted = SOSGhostBustThinSerialClones(circle, account.peerID); + nbusted += thinBusted; + attributes[@"byAge"] = @(thinBusted); + } + attributes[@"total"] = @(nbusted); + result = nbusted > 0; + if(result) { + SOSAccountRestartPrivateCredentialTimer(account); + if((SOSAccountGetPrivateCredential(account, NULL) != NULL) || SOSAccountAssertStashedAccountCredential(account, NULL)) { + result = SOSCircleGenerationSign(circle, SOSAccountGetPrivateCredential(account, NULL), account.fullPeerInfo, NULL); + } else { + result = false; + } + } + return result; + }]; + secnotice("circleOps", "Ghostbusting %@ (%@)", result ? CFSTR("Performed") : CFSTR("Not Performed"), localError); + } + } else { + secnotice("circleOps", "Ghostbusting skipped"); + } + CFReleaseNull(localError); + + if(result) { + [[SOSAnalytics logger] logSoftFailureForEventNamed:@"GhostBust" withAttributes:attributes]; + } else if(nbusted == 0){ + [[SOSAnalytics logger] logSuccessForEventNamed:@"GhostBust"]; + } else { + [[SOSAnalytics logger] logHardFailureForEventNamed:@"GhostBust" withAttributes:nil]; + } + return result; +} diff --git a/keychain/SecureObjectSync/SOSAccountLog.h b/keychain/SecureObjectSync/SOSAccountLog.h new file mode 100644 index 00000000..66382823 --- /dev/null +++ b/keychain/SecureObjectSync/SOSAccountLog.h @@ -0,0 +1,29 @@ +// +// SOSAccountLog.h +// sec +// +// Created by Richard Murphy on 6/1/16. +// +// + +#ifndef SOSAccountLog_h +#define SOSAccountLog_h + +#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSTransportCircle.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" + +//#include +@class SOSAccount; + +void SOSAccountLog(SOSAccount* account); +SOSAccount* SOSAccountCreateFromStringRef(CFStringRef hexString); + +#endif /* SOSAccountLog_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.m b/keychain/SecureObjectSync/SOSAccountLog.m similarity index 82% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.m rename to keychain/SecureObjectSync/SOSAccountLog.m index cc9eb52a..1eed7078 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountLog.m +++ b/keychain/SecureObjectSync/SOSAccountLog.m @@ -2,7 +2,7 @@ // SOSAccountLog.c // sec // -#import +#include "keychain/SecureObjectSync/SOSAccountPriv.h" #include "SOSAccountLog.h" #include #include @@ -14,10 +14,10 @@ #import #include #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" -#include -#include +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include // Keep these for later diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m b/keychain/SecureObjectSync/SOSAccountPeers.m similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m rename to keychain/SecureObjectSync/SOSAccountPeers.m index a64d5586..474335b3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPeers.m +++ b/keychain/SecureObjectSync/SOSAccountPeers.m @@ -23,11 +23,11 @@ #include "SOSAccountPriv.h" #include "SOSAccount.h" -#include -#include -#include -#import -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" bool SOSAccountIsMyPeerActive(SOSAccount* account, CFErrorRef* error) { SOSFullPeerInfoRef identity = NULL; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m b/keychain/SecureObjectSync/SOSAccountPersistence.m similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m rename to keychain/SecureObjectSync/SOSAccountPersistence.m index 24390737..5b63e744 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPersistence.m +++ b/keychain/SecureObjectSync/SOSAccountPersistence.m @@ -34,18 +34,18 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" -#include +#include "keychain/SecureObjectSync/SOSTransport.h" -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include -#import -#import -#import -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSCircleDer.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" @implementation SOSAccount (Persistence) @@ -452,7 +452,7 @@ static SOSAccount* SOSAccountCreateFromDER(CFAllocatorRef allocator, } SOSPeerInfoRef oldPI = CFRetainSafe(account.peerInfo); - if (oldPI) { + if (oldPI && [account isInCircle: nil] == kSOSCCInCircle) { SOSAccountCheckForAlwaysOnViews(account); } CFReleaseNull(oldPI); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h b/keychain/SecureObjectSync/SOSAccountPriv.h similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h rename to keychain/SecureObjectSync/SOSAccountPriv.h index 7b033e99..7300f540 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountPriv.h +++ b/keychain/SecureObjectSync/SOSAccountPriv.h @@ -25,21 +25,22 @@ #import -#include +#include "keychain/SecureObjectSync/SOSInternal.h" -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSCircleV2.h" +#include "keychain/SecureObjectSync/SOSRing.h" +#include "keychain/SecureObjectSync/SOSRingUtils.h" #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" #include -#include -#include -#include + +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSTransportCircle.h" #include @@ -88,7 +89,7 @@ typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flatt @property (nonatomic, assign) BOOL isListeningForSync; @property (nonatomic, assign) int lock_notification_token; @property (nonatomic, retain) CKKeyParameter* key_transport; -@property (nonatomic) SOSKVSCircleStorageTransport* circle_transport; +@property (nonatomic, retain) SOSKVSCircleStorageTransport* circle_transport; @property (nonatomic, retain) SOSMessageKVS* kvs_message_transport; @property (nonatomic, retain) SOSCKCircleStorage* ck_storage; @@ -100,9 +101,8 @@ typedef void (^SOSAccountSaveBlock)(CFDataRef flattenedAccount, CFErrorRef flatt @property (nonatomic, retain) NSMutableArray *change_blocks; @property (nonatomic, retain) NSMutableDictionary *waitForInitialSync_blocks; -@property (nonatomic, assign) BOOL isInitialSyncing; -@property (nonatomic) NSData* accountKeyDerivationParamters; +@property (nonatomic, retain) NSData* accountKeyDerivationParamters; @property (nonatomic, assign) BOOL accountKeyIsTrusted; @property (nonatomic) SecKeyRef accountKey; @@ -137,6 +137,11 @@ void SOSAccountAddSyncablePeerBlock(SOSAccount* a, -(void) flattenToSaveBlock; +-(void) ghostBustSchedule; ++ (SOSAccountGhostBustingOptions) ghostBustGetRampSettings; +- (bool) ghostBustCheckDate; + + void SOSAccountSetToNew(SOSAccount* a); bool SOSAccountIsMyPeerActive(SOSAccount* account, CFErrorRef* error); @@ -151,8 +156,9 @@ bool SOSAccountHandleOutOfSyncUpdate(SOSAccount* account, CFSetRef oldOOSViews, void SOSAccountEnsureSyncChecking(SOSAccount* account); void SOSAccountCancelSyncChecking(SOSAccount* account); - +void SOSAccountInitializeInitialSync(SOSAccount* account); CFMutableSetRef SOSAccountCopyOutstandingViews(SOSAccount* account); +CFSetRef SOSAccountCopyEnabledViews(SOSAccount* account); void SOSAccountNotifyEngines(SOSAccount* account); CFMutableSetRef SOSAccountCopyOutstandingViews(SOSAccount* account); bool SOSAccountIsViewOutstanding(SOSAccount* account, CFStringRef view); @@ -208,7 +214,6 @@ bool SOSAccountIsMyPeerInBackupAndCurrentInView(SOSAccount* account, CFStringRef bool SOSAccountUpdateOurPeerInBackup(SOSAccount* account, SOSRingRef oldRing, CFErrorRef *error); bool SOSAccountIsPeerInBackupAndCurrentInView(SOSAccount* account, SOSPeerInfoRef testPeer, CFStringRef viewname); 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)); @@ -216,6 +221,9 @@ bool SOSAccountUpdatePeerInfoAndPush(SOSAccount* account, CFStringRef updateDesc // Currently permitted backup rings. void SOSAccountForEachBackupRingName(SOSAccount* account, void (^operation)(CFStringRef value)); void SOSAccountForEachRingName(SOSAccount* account, void (^operation)(CFStringRef value)); +void SOSAccountForEachBackupView(SOSAccount* account, void (^operation)(const void *value)); +SOSRingRef SOSAccountCreateBackupRingForView(SOSAccount* account, CFStringRef ringBackupViewName, CFErrorRef *error); + // My Circle bool SOSAccountHasCircle(SOSAccount* account, CFErrorRef* error); @@ -304,7 +312,8 @@ bool SOSAccountUpdateNamedRing(SOSAccount* account, CFStringRef ringName, CFErro // CFStringRef SOSBackupCopyRingNameForView(CFStringRef viewName); - +bool SOSAccountUpdateBackupRing(SOSAccount* account, CFStringRef viewName, CFErrorRef *error, + SOSRingRef (^modify)(SOSRingRef existing, CFErrorRef *error)); // // Security tool test/debug functions // @@ -353,6 +362,8 @@ bool SOSAccountPopulateKVSWithBadKeys(SOSAccount* account, CFErrorRef* error); error: (NSError**) error; -(NSData*) encodedData: (NSError**) error; + + @end #endif /* SOSAccount_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m b/keychain/SecureObjectSync/SOSAccountRecovery.m similarity index 57% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m rename to keychain/SecureObjectSync/SOSAccountRecovery.m index e9757938..cd272013 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRecovery.m +++ b/keychain/SecureObjectSync/SOSAccountRecovery.m @@ -30,25 +30,34 @@ #include "SOSAccountPriv.h" #include "SOSCloudKeychainClient.h" -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include "SecADWrapper.h" -#include -#include +#include "keychain/SecureObjectSync/SOSRecoveryKeyBag.h" +#include "keychain/SecureObjectSync/SOSRingRecovery.h" CFStringRef kRecoveryRingKey = CFSTR("recoveryKeyBag"); +// When a recovery key is harvested from a recovery ring it's sent here bool SOSAccountSetRecoveryKeyBagEntry(CFAllocatorRef allocator, SOSAccount* account, SOSRecoveryKeyBagRef rkbg, CFErrorRef *error) { - CFDataRef rkbg_as_data = NULL; bool result = false; - rkbg_as_data = SOSRecoveryKeyBagCopyEncoded(rkbg, error); - result = rkbg_as_data && SOSAccountSetValue(account, kRecoveryRingKey, rkbg_as_data, error); - CFReleaseNull(rkbg_as_data); + if(rkbg == NULL) { + result = SOSAccountClearValue(account, kRecoveryRingKey, error); + } else { + CFDataRef recoverKeyData = SOSRecoveryKeyBagGetKeyData(rkbg, NULL); + if(CFEqualSafe(recoverKeyData, SOSRKNullKey())) { + result = SOSAccountClearValue(account, kRecoveryRingKey, error); + } else { + CFDataRef rkbg_as_data = SOSRecoveryKeyBagCopyEncoded(rkbg, error); + result = rkbg_as_data && SOSAccountSetValue(account, kRecoveryRingKey, rkbg_as_data, error); + CFReleaseNull(rkbg_as_data); + } + } return result; } @@ -61,30 +70,8 @@ errOut: return retval; } -SOSRecoveryKeyBagRef SOSAccountCopyRecoveryKeyBag(CFAllocatorRef allocator, SOSAccount* account, CFErrorRef *error) { - SOSRingRef recRing = NULL; - SOSRecoveryKeyBagRef rkbg = NULL; - require_action_quiet(account, errOut, SOSCreateError(kSOSErrorParam, CFSTR("No Account Object"), NULL, error)); - recRing = SOSAccountCopyRingNamed(account, kSOSRecoveryRing, error); - require_quiet(recRing, errOut); - rkbg = SOSRingCopyRecoveryKeyBag(recRing, error); -errOut: - CFReleaseNull(recRing); - return rkbg; -} - - -static CFDataRef SOSRKNullKey(void) { - static CFDataRef localNullKey = NULL; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - localNullKey = CFDataCreate(kCFAllocatorDefault, (const UInt8*) "nullkey", 8); - }); - return localNullKey; -} - CFDataRef SOSAccountCopyRecoveryPublic(CFAllocatorRef allocator, SOSAccount* account, CFErrorRef *error) { - SOSRecoveryKeyBagRef rkbg = SOSAccountCopyRecoveryKeyBag(allocator, account, error); + SOSRecoveryKeyBagRef rkbg = SOSAccountCopyRecoveryKeyBagEntry(allocator, account, error); CFDataRef recKey = NULL; require_quiet(rkbg, errOut); CFDataRef tmpKey = SOSRecoveryKeyBagGetKeyData(rkbg, error); @@ -108,69 +95,55 @@ static bool SOSAccountUpdateRecoveryRing(SOSAccount* account, CFErrorRef *error, return result; } -static bool SOSAccountSetKeybagForRecoveryRing(SOSAccount* account, SOSRecoveryKeyBagRef keyBag, CFErrorRef *error) { - bool result = SOSAccountUpdateRecoveryRing(account, error, ^SOSRingRef(SOSRingRef existing, CFErrorRef *error) { - SOSRingRef newRing = NULL; - CFSetRef peerSet = [account.trust copyPeerSetMatching:^bool(SOSPeerInfoRef peer) { - return true; - }]; - CFMutableSetRef cleared = CFSetCreateMutableForCFTypes(NULL); - - SOSRingSetPeerIDs(existing, cleared); - SOSRingAddAll(existing, peerSet); - - require_quiet(SOSRingSetRecoveryKeyBag(existing, account.fullPeerInfo, keyBag, error), exit); - - newRing = CFRetainSafe(existing); - exit: - CFReleaseNull(cleared); - return newRing; - }); - - SOSClearErrorIfTrue(result, error); - - if (!result) { - secnotice("recovery", "Got error setting keybag for recovery : %@", error ? (CFTypeRef) *error : (CFTypeRef) CFSTR("No error space.")); - } - return result; -} - bool SOSAccountRemoveRecoveryKey(SOSAccount* account, CFErrorRef *error) { - return SOSAccountSetRecoveryKey(account, SOSRKNullKey(), error); + return SOSAccountSetRecoveryKey(account, NULL, error); } + +// Recovery Setting From a Local Client goes through here bool SOSAccountSetRecoveryKey(SOSAccount* account, CFDataRef pubData, CFErrorRef *error) { __block bool result = false; CFDataRef oldRecoveryKey = NULL; SOSRecoveryKeyBagRef rkbg = NULL; - require_quiet([account isInCircle:error], exit); + if(![account isInCircle:error]) return false; oldRecoveryKey = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); // ok to fail here. don't collect error - require_action_quiet(!CFEqualSafe(pubData, oldRecoveryKey), exit, result = true); CFDataPerformWithHexString(pubData, ^(CFStringRef recoveryKeyString) { CFDataPerformWithHexString(oldRecoveryKey, ^(CFStringRef oldRecoveryKeyString) { secnotice("recovery", "SetRecoveryPublic: %@ from %@", recoveryKeyString, oldRecoveryKeyString); }); }); - - rkbg = SOSRecoveryKeyBagCreateForAccount(kCFAllocatorDefault, (__bridge CFTypeRef)account, pubData, error); - require_quiet(rkbg, exit); + CFReleaseNull(oldRecoveryKey); - result = SOSAccountSetKeybagForRecoveryRing(account, rkbg, error); + rkbg = SOSRecoveryKeyBagCreateForAccount(kCFAllocatorDefault, (__bridge CFTypeRef)account, pubData, error); SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, rkbg, NULL); - { - SOSAccountForEachBackupView(account, ^(const void *value) { - CFStringRef viewName = (CFStringRef)value; - SOSAccountNewBKSBForView(account, viewName, error); + SOSAccountUpdateRecoveryRing(account, error, ^SOSRingRef(SOSRingRef existing, CFErrorRef *error) { + SOSRingRef newRing = NULL; + CFMutableSetRef peerInfoIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + SOSCircleForEachValidSyncingPeer(account.trust.trustedCircle, account.accountKey, ^(SOSPeerInfoRef peer) { + CFSetAddValue(peerInfoIDs, SOSPeerInfoGetPeerID(peer)); }); - } + SOSRingSetPeerIDs(existing, peerInfoIDs); + if(rkbg) { + SOSRingSetRecoveryKeyBag(existing, account.fullPeerInfo, rkbg, error); + } else { + SOSRecoveryKeyBagRef ringrkbg = SOSRecoveryKeyBagCreateForAccount(kCFAllocatorDefault, (__bridge CFTypeRef)account, SOSRKNullKey(), error); + SOSRingSetRecoveryKeyBag(existing, account.fullPeerInfo, ringrkbg, error); + CFRelease(ringrkbg); + } + SOSRingGenerationSign(existing, NULL, account.trust.fullPeerInfo, error); + newRing = CFRetainSafe(existing); + return newRing; + }); + CFReleaseNull(rkbg); + if(SOSPeerInfoHasBackupKey(account.trust.peerInfo)) { + SOSAccountProcessBackupRings(account, error); + } account.circle_rings_retirements_need_attention = true; + result = true; -exit: - CFReleaseNull(oldRecoveryKey); - CFReleaseNull(rkbg); SOSClearErrorIfTrue(result, error); if (!result) { // if we're failing and something above failed to give an error - make a generic one. @@ -187,9 +160,9 @@ bool SOSAccountRecoveryKeyIsInBackupAndCurrentInView(SOSAccount* account, CFStri SOSRingRef ring = NULL; SOSBackupSliceKeyBagRef backupSlice = NULL; - CFDataRef rkbg = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); - require_quiet(rkbg, errOut); - + CFDataRef recoveryKeyFromAccount = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); + require_quiet(recoveryKeyFromAccount, errOut); + CFStringRef ringName = SOSBackupCopyRingNameForView(viewname); ring = [account.trust copyRing:ringName err:&bsError]; CFReleaseNull(ringName); @@ -203,11 +176,11 @@ bool SOSAccountRecoveryKeyIsInBackupAndCurrentInView(SOSAccount* account, CFStri backupSlice = SOSBackupSliceKeyBagCreateFromData(kCFAllocatorDefault, backupSliceData, &bsError); require_quiet(backupSlice, errOut); - result = SOSBKSBPrefixedKeyIsInKeyBag(backupSlice, bskbRkbgPrefix, rkbg); + result = SOSBKSBPrefixedKeyIsInKeyBag(backupSlice, bskbRkbgPrefix, recoveryKeyFromAccount); CFReleaseNull(backupSlice); errOut: CFReleaseNull(ring); - CFReleaseNull(rkbg); + CFReleaseNull(recoveryKeyFromAccount); if (bsError) { secnotice("backup", "Failed to find BKSB: %@, %@ (%@)", backupSliceData, backupSlice, bsError); @@ -224,35 +197,9 @@ static void sosRecoveryAlertAndNotify(SOSAccount* account, SOSRecoveryKeyBagRef void SOSAccountEnsureRecoveryRing(SOSAccount* account) { static SOSRecoveryKeyBagRef oldRingRKBG = NULL; - - if(![account isInCircle:NULL]) { - return; - } - - CFStringRef accountDSID = SOSAccountGetValue(account, kSOSDSIDKey, NULL); 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(acctRKBG == NULL && ringRKBG == NULL) { - // Nothing to do at this time - notify if this is a change down below. - } 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(!CFEqualSafe(acctRKBG, ringRKBG)) { - secnotice("recovery", "Harvesting account recovery key from ring"); - SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, NULL); + if(!CFEqualSafe(acctRKBG, oldRingRKBG)) { + sosRecoveryAlertAndNotify(account, oldRingRKBG, acctRKBG); + CFRetainAssign(oldRingRKBG, acctRKBG); } - - if(!CFEqualSafe(oldRingRKBG, ringRKBG)) { - sosRecoveryAlertAndNotify(account, oldRingRKBG, ringRKBG); - CFTransferRetained(oldRingRKBG, ringRKBG); - } - - CFReleaseNull(ringRKBG); - CFReleaseNull(acctRKBG); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m b/keychain/SecureObjectSync/SOSAccountRingUpdate.m similarity index 72% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m rename to keychain/SecureObjectSync/SOSAccountRingUpdate.m index d7409e06..44fa5177 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRingUpdate.m +++ b/keychain/SecureObjectSync/SOSAccountRingUpdate.m @@ -7,13 +7,13 @@ #include #include "SOSAccountPriv.h" -#include -#include +#include "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include -#include -#include -#include -#import +#include "keychain/SecureObjectSync/SOSRing.h" +#include "keychain/SecureObjectSync/SOSRingUtils.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" bool SOSAccountIsPeerRetired(SOSAccount* account, CFSetRef peers){ CFMutableArrayRef peerInfos = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m b/keychain/SecureObjectSync/SOSAccountRings.m similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m rename to keychain/SecureObjectSync/SOSAccountRings.m index 680c174c..30e18ed5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountRings.m +++ b/keychain/SecureObjectSync/SOSAccountRings.m @@ -4,10 +4,10 @@ // #include "SOSAccountPriv.h" -#include -#include -#import -#import +#import "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSRingUtils.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" #include "AssertMacros.h" @@ -217,6 +217,7 @@ bool SOSAccountUpdateNamedRing(SOSAccount* account, CFStringRef ringName, CFErro require_quiet(newRing, errOut); require_quiet(SOSAccountHasPublicKey(account, error), errOut); + require_quiet(SOSAccountHasCircle(account, error), errOut); result = [account.trust handleUpdateRing:account prospectiveRing:newRing transport:account.circle_transport userPublicKey:account.accountKey writeUpdate:true err:error]; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m b/keychain/SecureObjectSync/SOSAccountSync.m similarity index 61% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m rename to keychain/SecureObjectSync/SOSAccountSync.m index 73321514..2ee32bf6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountSync.m +++ b/keychain/SecureObjectSync/SOSAccountSync.m @@ -2,23 +2,23 @@ #include "SOSAccountPriv.h" #include "SOSAccount.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#import -#import -#import -#import -#import -#include -#include -#include +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSTransportCircle.h" +#include "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" + +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" +#include "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include @@ -26,16 +26,26 @@ // MARK: Engine Logging #define LOG_ENGINE_STATE_INTERVAL 20 +#define LOG_CATEGORY "account-sync" + +static bool SOSReadyToSync(SOSAccount *account, CFErrorRef *error) { + if (![account isInCircle:error]) { + secnotice(LOG_CATEGORY, "Not performing requested sync operation: not in circle yet"); + return false; + } + return true; +} void SOSAccountConsiderLoggingEngineState(SOSAccountTransaction* txn) { static int engineLogCountDown = 0; if(engineLogCountDown <= 0) { SOSAccount* acct = txn.account; - CFTypeRef engine = [acct.kvs_message_transport SOSTransportMessageGetEngine]; - - SOSEngineLogState((SOSEngineRef)engine); - engineLogCountDown = LOG_ENGINE_STATE_INTERVAL; + if(SOSReadyToSync(acct, NULL)) { + CFTypeRef engine = [acct.kvs_message_transport SOSTransportMessageGetEngine]; + SOSEngineLogState((SOSEngineRef)engine); + engineLogCountDown = LOG_ENGINE_STATE_INTERVAL; + } } else { engineLogCountDown--; } @@ -75,18 +85,13 @@ static bool SOSAccountSyncWithKVSPeers(SOSAccountTransaction* txn, CFSetRef peer CFErrorRef localError = NULL; bool result = false; - require_quiet([account isInCircle:error], xit); - - result =[account.kvs_message_transport SOSTransportMessageSyncWithPeers:account.kvs_message_transport p:peerIDs err:&localError]; - - if (result) - SetCloudKeychainTraceValueForKey(kCloudKeychainNumberOfTimesSyncedWithPeers, 1); - -xit: + if(SOSReadyToSync(account, error)) { + result =[account.kvs_message_transport SOSTransportMessageSyncWithPeers:account.kvs_message_transport p:peerIDs err:&localError]; + } if (!result) { // Tell account to update SOSEngine with current trusted peers if (isSOSErrorCoded(localError, kSOSErrorPeerNotFound)) { - secnotice("Account", "Arming account to update SOSEngine with current trusted peers"); + secnotice(LOG_CATEGORY, "Arming account to update SOSEngine with current trusted peers"); account.engine_peer_state_needs_repair = true; } CFErrorPropagate(localError, error); @@ -97,23 +102,23 @@ xit: } bool SOSAccountSyncWithKVSPeerWithMessage(SOSAccountTransaction* txn, CFStringRef peerid, CFDataRef message, CFErrorRef *error) { + //murfxx protect SOSAccount* account = txn.account; bool result = false; CFErrorRef localError = NULL; CFDictionaryRef encapsulatedMessage = NULL; - secnotice("KVS Transport","Syncing with KVS capable peer: %@", peerid); - secnotice("KVS Transport", "message: %@", message); + secnotice(LOG_CATEGORY,"Syncing with KVS capable peer: %@", peerid); + secnotice(LOG_CATEGORY, "message: %@", message); require_quiet(message, xit); require_quiet(peerid && CFStringGetLength(peerid) <= kSOSPeerIDLengthMax, xit); - - encapsulatedMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, peerid, message, NULL); - - result = [account.kvs_message_transport SOSTransportMessageSendMessages:account.kvs_message_transport pm:encapsulatedMessage err:&localError]; - secerror("KVS sync %s. (%@)", result ? "succeeded" : "failed", localError); - - SOSAccountConsiderLoggingEngineState(txn); + if(SOSReadyToSync(account, &localError)) { + encapsulatedMessage = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, peerid, message, NULL); + result = [account.kvs_message_transport SOSTransportMessageSendMessages:account.kvs_message_transport pm:encapsulatedMessage err:&localError]; + secnotice(LOG_CATEGORY, "KVS sync %s. (%@)", result ? "succeeded" : "failed", localError); + SOSAccountConsiderLoggingEngineState(txn); + } xit: CFReleaseNull(encapsulatedMessage); @@ -127,17 +132,18 @@ static bool SOSAccountSyncWithKVSPeer(SOSAccountTransaction* txn, CFStringRef pe { bool result = false; CFErrorRef localError = NULL; + SOSAccount* account = txn.account; - secnotice("KVS Transport","Syncing with KVS capable peer: %@", peerID); - - CFMutableSetRef peerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - CFSetAddValue(peerIDs, peerID); - - result = SOSAccountSyncWithKVSPeers(txn, peerIDs, &localError); - secerror("KVS sync %s. (%@)", result ? "succeeded" : "failed", localError); + if(SOSReadyToSync(account, error)) { + secnotice(LOG_CATEGORY,"Syncing with KVS capable peer: %@", peerID); + CFMutableSetRef peerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + CFSetAddValue(peerIDs, peerID); + result = SOSAccountSyncWithKVSPeers(txn, peerIDs, &localError); + secnotice(LOG_CATEGORY, "KVS sync %s. (%@)", result ? "succeeded" : "failed", localError); - CFReleaseNull(peerIDs); - CFErrorPropagate(localError, error); + CFReleaseNull(peerIDs); + CFErrorPropagate(localError, error); + } return result; } @@ -145,17 +151,19 @@ static bool SOSAccountSyncWithKVSPeer(SOSAccountTransaction* txn, CFStringRef pe CFSetRef SOSAccountSyncWithPeersOverKVS(SOSAccountTransaction* txn, CFSetRef peers) { CFMutableSetRef handled = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); - - CFSetForEach(peers, ^(const void *value) { - CFStringRef peerID = asString(value, NULL); - CFErrorRef localError = NULL; - if (peerID && SOSAccountSyncWithKVSPeer(txn, peerID, &localError)) { - CFSetAddValue(handled, peerID); - secnotice("KVS Transport", "synced with peer: %@", peerID); - } else { - secnotice("KVS Transport", "failed to sync with peer: %@ error: %@", peerID, localError); - } - }); + if(SOSReadyToSync(txn.account, NULL)) { + CFSetForEach(peers, ^(const void *value) { + CFStringRef peerID = asString(value, NULL); + CFErrorRef localError = NULL; + if (peerID && SOSAccountSyncWithKVSPeer(txn, peerID, &localError)) { + CFSetAddValue(handled, peerID); + secnotice(LOG_CATEGORY, "synced with peer: %@", peerID); + } else { + secnotice(LOG_CATEGORY, "failed to sync with peer: %@ error: %@", peerID, localError); + } + CFReleaseNull(localError); + }); + } return handled; } @@ -166,9 +174,7 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio CFMutableSetRef peersForKVS = NULL; SOSAccount* account = txn.account; - - if(![account isInCircle:error]) - { + if(!SOSReadyToSync(account, error)) { handledPeerIDs = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, peerIDs); CFReleaseNull(notMePeers); CFReleaseNull(peersForKVS); @@ -210,7 +216,7 @@ CF_RETURNS_RETAINED CFMutableSetRef SOSAccountSyncWithPeers(SOSAccountTransactio skip: CFReleaseNull(peerInfo); if (localError) { - secnotice("sync-with-peers", "Skipped peer ID: %@ due to %@", peerID, localError); + secnotice(LOG_CATEGORY, "Skipped peer ID: %@ due to %@", peerID, localError); } CFReleaseNull(localError); }); @@ -231,10 +237,14 @@ CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransactio CFErrorRef localError = NULL; SOSAccount* account = txn.account; + if(!SOSReadyToSync(account, error)) { + return CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + } + CFMutableSetRef handled = SOSAccountSyncWithPeers(txn, peers, &localError); if (!handled) { - secnotice("account-sync", "Peer Sync failed: %@", localError); + secnotice(LOG_CATEGORY, "Peer Sync failed: %@", localError); handled = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); } CFReleaseNull(localError); @@ -245,7 +255,7 @@ CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransactio if (engineHandled) { CFSetUnion(handled, engineHandled); } else { - secnotice("account-sync", "Engine Backup Sync failed: %@", localError); + secnotice(LOG_CATEGORY, "Engine Backup Sync failed: %@", localError); } CFReleaseNull(localError); CFReleaseNull(engineHandled); @@ -255,8 +265,13 @@ CF_RETURNS_RETAINED CFSetRef SOSAccountProcessSyncWithPeers(SOSAccountTransactio CF_RETURNS_RETAINED CFSetRef SOSAccountCopyBackupPeersAndForceSync(SOSAccountTransaction* txn, CFErrorRef *error) { - SOSEngineRef engine = (SOSEngineRef) [txn.account.kvs_message_transport SOSTransportMessageGetEngine]; + SOSAccount* account = txn.account; + + if(!SOSReadyToSync(account, error)) { + return false; + } + SOSEngineRef engine = (SOSEngineRef) [txn.account.kvs_message_transport SOSTransportMessageGetEngine]; NSArray* backupPeersArray = (NSArray*) CFBridgingRelease(SOSEngineCopyBackupPeerNames(engine, error)); NSSet* backupPeers = [[NSSet alloc] initWithArray: backupPeersArray]; return SOSEngineSyncWithBackupPeers(engine, (__bridge CFSetRef) backupPeers, true, error); @@ -267,8 +282,9 @@ bool SOSAccountRequestSyncWithAllPeers(SOSAccountTransaction* txn, CFErrorRef *e SOSAccount* account = txn.account; SOSAccountTrustClassic *trust = account.trust; - if (![account isInCircle:error]) + if(!SOSReadyToSync(account, error)) { return false; + } NSMutableSet* allSyncingPeers = [NSMutableSet set]; SOSCircleRef circle = trust.trustedCircle; @@ -288,27 +304,21 @@ bool SOSAccountRequestSyncWithAllPeers(SOSAccountTransaction* txn, CFErrorRef *e bool SOSAccountMessageFromPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef peer, CFErrorRef *error) { bool success = false; SOSAccount* account = txn.account; - 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)); - - success = SOSCloudKeychainHasPendingKey(peerMessage, error); - CFReleaseNull(peerMessage); - -xit: + if(SOSReadyToSync(account, error)) { + // 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)); + success = SOSCloudKeychainHasPendingKey(peerMessage, error); + CFReleaseNull(peerMessage); + } return success; } bool SOSAccountSendToPeerIsPending(SOSAccountTransaction* txn, SOSPeerInfoRef peer, CFErrorRef *error) { bool success = false; SOSAccount* account = txn.account; - require_quiet([account isInCircle:error], xit); - - success = SOSCCIsSyncPendingFor(SOSPeerInfoGetPeerID(peer), error); -xit: + if(SOSReadyToSync(account, error)) { + success = SOSCCIsSyncPendingFor(SOSPeerInfoGetPeerID(peer), error); + } return success; - - } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h b/keychain/SecureObjectSync/SOSAccountTransaction.h similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h rename to keychain/SecureObjectSync/SOSAccountTransaction.h index d31c4212..36ba7cb3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.h +++ b/keychain/SecureObjectSync/SOSAccountTransaction.h @@ -9,7 +9,7 @@ #define SOSAccountTransaction_h #include -#import +#include "keychain/SecureObjectSync/SOSAccountPriv.h" #include NS_ASSUME_NONNULL_BEGIN diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m b/keychain/SecureObjectSync/SOSAccountTransaction.m similarity index 73% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m rename to keychain/SecureObjectSync/SOSAccountTransaction.m index e256e359..7fa73312 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTransaction.m +++ b/keychain/SecureObjectSync/SOSAccountTransaction.m @@ -10,15 +10,15 @@ #import #include -#include -#include -#include -#import -#import -#import -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSTransportMessageKVS.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSTransportCircle.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" #import "Security/SecItemBackup.h" #include @@ -54,45 +54,99 @@ @implementation SOSAccountTransaction -static void SOSCircleSetCachedStatus(SOSAccount *account) { - static SOSCCStatus lastStatus = -2; - SOSCCStatus currentStatus = [account getCircleStatus:NULL]; - - if(lastStatus != currentStatus) { - lastStatus = currentStatus; - account.notifyCircleChangeOnExit = true; +- (uint64_t)currentTrustBitmask { + dispatch_assert_queue(_account.queue); + + // A couple of assumptions here, that circle status is 32 bit (it an int), and that we can store + // that in th lower half without sign extending it + uint64_t circleStatus = (((uint32_t)[_account.trust getCircleStatusOnly:NULL]) & 0xffffffff) | CC_STATISVALID; + if(_account.accountKeyIsTrusted) { + circleStatus |= CC_UKEY_TRUSTED; + if(_account.accountPrivateKey) { + circleStatus |= CC_CAN_AUTH; + } } - - 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; + } + return circleStatus; +} + +- (void) updateSOSCircleCachedStatus { + // clearly invalid, overwritten by cached value in notify_get_state() + // if its the second time we are launchded + static uint64_t lastStatus = 0; + + dispatch_assert_queue(_account.queue); + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // pull out what previous instance of securityd though the trust status + SOSCachedNotificationOperation(kSOSCCCircleChangedNotification, ^bool(int token, bool gtg) { + uint64_t state64; + if (notify_get_state(token, &state64) == NOTIFY_STATUS_OK) { + if (state64 & CC_STATISVALID) { + lastStatus = state64; + } } + return true; + }); + secnotice("sosnotify", "initial last circle status is: %llu", (unsigned long long)lastStatus); + }); + + uint64_t currentStatus = [self currentTrustBitmask]; + if (lastStatus & CC_STATISVALID) { + if(lastStatus != currentStatus) { + _account.notifyCircleChangeOnExit = true; } - // we might be in circle, but invalid - let client see this in bitmask. - if([account.trust isInCircleOnly:NULL]) { - circleStatus |= CC_PEER_IS_IN; - } - + } else { + _account.notifyCircleChangeOnExit = true; + } + + if(_account.notifyCircleChangeOnExit) { + // notify if last cache status was invalid, or it have changed, clients don't get update on changes in + // the metadata stored in the upper bits of above CC_MASK (at least not though this path) + bool firstLaunch = (lastStatus & CC_STATISVALID) == 0; + bool circleChanged = ((lastStatus & CC_MASK) != (currentStatus & CC_MASK)); + + bool circleStatusChanged = firstLaunch || circleChanged; + + lastStatus = currentStatus; + + secnotice("sosnotify", "new last circle status is: %llu (notify: %s)", + (unsigned long long)lastStatus, + circleStatusChanged ? "yes" : "no"); + SOSCachedNotificationOperation(kSOSCCCircleChangedNotification, ^bool(int token, bool gtg) { if(gtg) { - uint32_t status = notify_set_state(token, circleStatus); + uint32_t status = notify_set_state(token, currentStatus); if(status == NOTIFY_STATUS_OK) { - notify_post(kSOSCCCircleChangedNotification); - account.notifyCircleChangeOnExit = false; + self->_account.notifyCircleChangeOnExit = false; + + if (circleStatusChanged) { + secnotice("sosnotify", "posting kSOSCCCircleChangedNotification"); + notify_post(kSOSCCCircleChangedNotification); + } } return true; } return false; }); + + // preserve behavior from previous, this should be merged into SOSViewsSetCachedStatus() + if (firstLaunch) { + _account.notifyViewChangeOnExit = true; + } } } static void SOSViewsSetCachedStatus(SOSAccount *account) { static uint64_t lastViewBitmask = 0; - __block uint64_t viewBitMask = ([account getCircleStatus:NULL] == kSOSCCInCircle) ? SOSPeerInfoViewBitMask(account.peerInfo) :0; + CFSetRef piViews = SOSAccountCopyEnabledViews(account); + + __block uint64_t viewBitMask = (([account getCircleStatus:NULL] == kSOSCCInCircle) && piViews) ? SOSViewBitmaskFromSet(piViews) :0; + CFReleaseNull(piViews); if(viewBitMask != lastViewBitmask) { lastViewBitmask = viewBitMask; @@ -129,7 +183,7 @@ static void SOSViewsSetCachedStatus(SOSAccount *account) { } - (void) start { - SOSCircleSetCachedStatus(_account); + [self updateSOSCircleCachedStatus]; SOSViewsSetCachedStatus(_account); self.initialInCircle = [self.account isInCircle:NULL]; @@ -153,6 +207,10 @@ static void SOSViewsSetCachedStatus(SOSAccount *account) { } self.peersToRequestSync = nil; + if(self.account.key_interests_need_updating) { + SOSUpdateKeyInterest(self.account); + } + if(!self.quiet) { CFStringSetPerformWithDescription((__bridge CFSetRef) self.initialViews, ^(CFStringRef description) { secnotice("acct-txn", "Starting as:%s v:%@", self.initialInCircle ? "member" : "non-member", description); @@ -168,7 +226,7 @@ static void SOSViewsSetCachedStatus(SOSAccount *account) { - (void) finish { static int do_account_state_at_zero = 0; - bool doCircleChanged = false; + bool doCircleChanged = self.account.notifyCircleChangeOnExit; bool doViewChanged = false; @@ -243,11 +301,10 @@ static void SOSViewsSetCachedStatus(SOSAccount *account) { #endif } - if(self.account.key_interests_need_updating){ + if(self.account.key_interests_need_updating) { SOSUpdateKeyInterest(self.account); } - self.account.key_interests_need_updating = false; self.account.circle_rings_retirements_need_attention = false; self.account.engine_peer_state_needs_repair = false; @@ -322,7 +379,7 @@ static void SOSViewsSetCachedStatus(SOSAccount *account) { } if(doCircleChanged) { - SOSCircleSetCachedStatus(_account); + [self updateSOSCircleCachedStatus]; } if(doViewChanged) { SOSViewsSetCachedStatus(_account); @@ -381,9 +438,14 @@ __thread bool __hasAccountQueue = false; + (void)performOnQuietAccountQueue:(void (^)(void))action { SOSAccount* account = (__bridge SOSAccount*)GetSharedAccountRef(); - [account performTransaction:true action:^(SOSAccountTransaction * _Nonnull txn) { + if(account) { + [account performTransaction:true action:^(SOSAccountTransaction * _Nonnull txn) { + action(); + }]; + } else { + secnotice("acct-txn", "No account; running block on local thread"); action(); - }]; + } } - (void) performTransaction_Locked: (void (^)(SOSAccountTransaction* txn)) action { @@ -392,7 +454,7 @@ __thread bool __hasAccountQueue = false; - (void) performTransaction_Locked:(bool)quiet action:(void (^)(SOSAccountTransaction* txn))action { @autoreleasepool { - SOSAccountTransaction* transaction = [[SOSAccountTransaction new] initWithAccount:self quiet:quiet]; + SOSAccountTransaction* transaction = [[SOSAccountTransaction alloc] initWithAccount:self quiet:quiet]; action(transaction); [transaction finish]; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h b/keychain/SecureObjectSync/SOSAccountTrust.h similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h rename to keychain/SecureObjectSync/SOSAccountTrust.h index 4a87ee90..b881ff0a 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.h +++ b/keychain/SecureObjectSync/SOSAccountTrust.h @@ -6,9 +6,9 @@ #define SOSAccountTrust_h #import -#import -#import -#import +#import "keychain/SecureObjectSync/SOSCircle.h" +#import "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#import "keychain/SecureObjectSync/SOSRing.h" typedef bool (^SOSModifyCircleBlock)(SOSCircleRef circle); typedef void (^SOSIteratePeerBlock)(SOSPeerInfoRef peerInfo); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m b/keychain/SecureObjectSync/SOSAccountTrust.m similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m rename to keychain/SecureObjectSync/SOSAccountTrust.m index 9fa0ce11..8aafe173 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrust.m +++ b/keychain/SecureObjectSync/SOSAccountTrust.m @@ -2,8 +2,8 @@ // SOSAccountTrust.c // Security // -#import "Security/SecureObjectSync/SOSAccountPriv.h" -#import "Security/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountPriv.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" @implementation SOSAccountTrust @synthesize cachedOctagonEncryptionKey = _cachedOctagonEncryptionKey; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h b/keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h similarity index 86% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h index 8da930bc..fa7d5b1f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.h +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h @@ -6,8 +6,8 @@ #ifndef SOSAccountTrustClassic_Circle_h #define SOSAccountTrustClassic_Circle_h -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" @interface SOSAccountTrustClassic (Circle) //Circle @@ -32,7 +32,6 @@ -(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/keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.m similarity index 57% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.m index 6dcdf812..e9486c1d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Circle.m +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.m @@ -6,15 +6,15 @@ #import #include -#import "Security/SecureObjectSync/SOSAccount.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSTransportCircle.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Identity.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" +#import "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSTransportCircle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" -#import "Security/SecureObjectSync/SOSAccountGhost.h" -#import "Security/SecureObjectSync/SOSViews.h" +#import "keychain/SecureObjectSync/SOSAccountGhost.h" +#import "keychain/SecureObjectSync/SOSViews.h" @implementation SOSAccountTrustClassic (Circle) @@ -159,49 +159,66 @@ fail: return false; } -static bool SOSCirclePeerOctagonKeysChanged(SOSPeerInfoRef oldPeer, SOSPeerInfoRef newPeer) { - bool oldHasOctagonBits = oldPeer && (SOSPeerInfoHasOctagonSigningPubKey(oldPeer) || SOSPeerInfoHasOctagonEncryptionPubKey(oldPeer)); - bool newHasOctagonBits = newPeer && (SOSPeerInfoHasOctagonSigningPubKey(newPeer) || SOSPeerInfoHasOctagonEncryptionPubKey(newPeer)); +static bool publicKeysEqual(SecKeyRef pubKey1, SecKeyRef pubKey2) +{ + // If either pub key is NULL, then the keys are equal if both are NULL. + if(pubKey1 == NULL || pubKey2 == NULL) { + return pubKey1 == NULL && pubKey2 == NULL; + } + + NSData *key1SPKI = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(pubKey1)); + NSData *key2SPKI = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(pubKey2)); + + return !![key1SPKI isEqual:key2SPKI]; +} +static bool SOSCirclePeerOctagonKeysChanged(SOSPeerInfoRef oldPeer, SOSPeerInfoRef newPeer) { if(!oldPeer) { - if(newPeer && newHasOctagonBits) { - return true; - } else { - // New peer to circle has no octagon bits: no change - return false; - } - } else { - // Have an old peer - if(!newPeer) { - // We removed a peer. This is an octagon bits change if the old peer had octagon bits - return oldHasOctagonBits; - } + // We've run across some situations where a new peer which should have keys isn't returning yes here. + // Therefore, always return yes on peer addition. + return !!newPeer; + } - // This is a peer update: Did the keys change? - if(!oldHasOctagonBits && !newHasOctagonBits) { - // both peers have no keys: no change - return false; + CFErrorRef oldSigningKeyError = NULL; + SecKeyRef oldSigningKey = oldPeer ? SOSPeerInfoCopyOctagonSigningPublicKey(oldPeer, &oldSigningKeyError) : NULL; - } - SecKeyRef oldSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(oldPeer, NULL); - SecKeyRef newSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(newPeer, NULL); + CFErrorRef oldEncryptionKeyError = NULL; + SecKeyRef oldEncryptionKey = oldPeer ? SOSPeerInfoCopyOctagonEncryptionPublicKey(oldPeer, &oldEncryptionKeyError) : NULL; - bool signingKeyChanged = CFEqualSafe(oldSigningKey, newSigningKey); + CFErrorRef newSigningKeyError = NULL; + SecKeyRef newSigningKey = newPeer ? SOSPeerInfoCopyOctagonSigningPublicKey(newPeer, &newSigningKeyError) : NULL; - CFReleaseNull(oldSigningKey); - CFReleaseNull(newSigningKey); + CFErrorRef newEncryptionKeyError = NULL; + SecKeyRef newEncryptionKey = newPeer ? SOSPeerInfoCopyOctagonEncryptionPublicKey(newPeer, &newEncryptionKeyError) : NULL; + if(oldPeer && oldSigningKeyError) { + secerror("circleOps: Cannot fetch signing key for old %@: %@", oldPeer, oldSigningKeyError); + } + if(oldPeer && oldEncryptionKeyError) { + secerror("circleOps: Cannot fetch encryption key for old %@: %@", oldPeer, oldEncryptionKeyError); + } + if(newPeer && newSigningKeyError) { + secerror("circleOps: Cannot fetch signing key for new %@: %@", newPeer, newSigningKeyError); + } + if(newPeer && newEncryptionKeyError) { + secerror("circleOps: Cannot fetch encryption key for new %@: %@", newPeer, newEncryptionKeyError); + } - SecKeyRef oldEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(oldPeer, NULL); - SecKeyRef newEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(newPeer, NULL); + bool signingKeyChanged = !publicKeysEqual(oldSigningKey, newSigningKey); + bool encryptionKeyChanged = !publicKeysEqual(oldEncryptionKey, newEncryptionKey); - bool encryptionKeyChanged = CFEqualSafe(oldEncryptionKey, newEncryptionKey); + bool keysChanged = signingKeyChanged || encryptionKeyChanged; - CFReleaseNull(oldEncryptionKey); - CFReleaseNull(newEncryptionKey); + CFReleaseNull(oldSigningKeyError); + CFReleaseNull(oldSigningKey); + CFReleaseNull(oldEncryptionKeyError); + CFReleaseNull(oldEncryptionKey); - return signingKeyChanged || encryptionKeyChanged; - } + CFReleaseNull(newSigningKeyError); + CFReleaseNull(newSigningKey); + CFReleaseNull(newEncryptionKeyError); + CFReleaseNull(newEncryptionKey); + return keysChanged; } static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SOSCircleRef newCircle) @@ -222,415 +239,6 @@ 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; @@ -685,13 +293,6 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO SOSAccountScanForRetired(account, prospective_circle, error); SOSCircleRef newCircle = SOSAccountCloneCircleWithRetirement(account, prospective_circle, error); if(!newCircle) return false; - if([self ghostBustingOK: oldCircle updatingTo:newCircle]) { - SOSCircleRef ghostCleaned = SOSAccountCloneCircleWithoutMyGhosts(account, newCircle); - if(ghostCleaned) { - CFRetainAssign(newCircle, ghostCleaned); - writeUpdate = true; - } - } SOSFullPeerInfoRef me_full = self.fullPeerInfo; SOSPeerInfoRef me = SOSFullPeerInfoGetPeerInfo(me_full); @@ -825,12 +426,14 @@ static bool SOSCircleHasUpdatedPeerInfoWithOctagonKey(SOSCircleRef oldCircle, SO } } else { secnotice("signing", "Not countersigning, not in new circle"); + [account.trust resetRingDictionary]; } circle_action = accept; } if (circle_action == accept) { if(SOSCircleHasUpdatedPeerInfoWithOctagonKey(oldCircle, newCircle)){ + secnotice("circleOps", "Sending kSOSCCCircleOctagonKeysChangedNotification"); notify_post(kSOSCCCircleOctagonKeysChangedNotification); } if (me && SOSCircleHasActivePeer(oldCircle, me, NULL) && !SOSCircleHasPeer(newCircle, me, NULL)) { @@ -960,30 +563,6 @@ 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; @@ -1006,6 +585,14 @@ fail: -(void) generationSignatureUpdateWith:(SOSAccount*)account key:(SecKeyRef) privKey { + // rdar://51233857 - don't gensign if there isn't a change in the userKey + // also don't rebake the circle to fix the icloud identity if there isn't + // a change as that will mess up piggybacking. + if(SOSAccountFullPeerInfoVerify(account, privKey, NULL) && SOSCircleVerify(account.trust.trustedCircle, account.accountKey, NULL)) { + secnotice("updatingGenSignature", "no change to userKey - skipping gensign"); + return; + } + if (self.trustedCircle && self.fullPeerInfo) { [self modifyCircle:account.circle_transport err:NULL action:^(SOSCircleRef circle) { SOSPeerInfoRef myPI = account.peerInfo; @@ -1068,7 +655,7 @@ fail: result &= [self modifyCircle:account.circle_transport err:error action:^(SOSCircleRef circle) { return sosAccountLeaveCircle(account, circle, error); }]; - + account.backup_key = nil; self.departureCode = kSOSWithdrewMembership; return result; @@ -1126,10 +713,12 @@ fail: return result; }]; - [self setValueInExpansion:kSOSUnsyncedViewsKey value:kCFBooleanTrue err:NULL]; + SOSAccountInitializeInitialSync(account); SOSAccountUpdateOutOfSyncViews(aTxn, SOSViewsGetAllCurrent()); result = true; + + notify_post(kSOSCCCircleOctagonKeysChangedNotification); return result; } @@ -1190,7 +779,7 @@ void SOSAccountForEachCirclePeerExceptMe(SOSAccount* account, void (^action)(SOS return result; }]; - if (use_cloud_peer) { + if (use_cloud_peer || SOSAccountHasCompletedInitialSync(account)) { SOSAccountUpdateOutOfSyncViews(aTxn, SOSViewsGetAllCurrent()); } } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h b/keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h similarity index 89% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h index 88ccec8b..5d716757 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.h +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h @@ -8,10 +8,10 @@ #define SOSAccountTrustClassic_Expansion_h -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" #include -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" @interface SOSAccountTrustClassic (Expansion) @@ -20,7 +20,6 @@ -(bool) updateV2Dictionary:(SOSAccount*)account v2:(CFDictionaryRef) newV2Dict; -(bool) handleUpdateRing:(SOSAccount*)account prospectiveRing:(SOSRingRef)prospectiveRing transport:(SOSKVSCircleStorageTransport*)circleTransport userPublicKey:(SecKeyRef)userPublic writeUpdate:(bool)writeUpdate err:(CFErrorRef *)error; -(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; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m b/keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.m similarity index 62% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.m index fbf71a27..ef78b198 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Expansion.m +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.m @@ -5,14 +5,16 @@ #import -#import "Security/SecureObjectSync/SOSAccount.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" -#import "Security/SecureObjectSync/SOSViews.h" -#import "Security/SecureObjectSync/SOSPeerInfoV2.h" -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSViews.h" +#import "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSRingRecovery.h" #import "keychain/Signin Metrics/SFSignInAnalytics.h" @implementation SOSAccountTrustClassic (Expansion) @@ -203,39 +205,28 @@ errOut: -(bool) resetAccountToEmpty:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport err:(CFErrorRef*) error { - - __block bool result = true; - - result &= [self resetAllRings:account err:error]; - - self.fullPeerInfo = nil; - - self.departureCode = kSOSWithdrewMembership; - secnotice("circleOps", "Reset Circle to empty by client request"); - - result &= [self modifyCircle:circleTransport err:error action:^bool(SOSCircleRef circle) { - result = SOSCircleResetToEmpty(circle, error); - return result; - }]; - - if (!result) { - secerror("error: %@", error ? *error : NULL); - } - return result; + return [self resetAccountToEmptyWithAnalytics:account transport:circleTransport parentEvent:nil err:error ]; } -(bool) resetAccountToEmptyWithAnalytics:(SOSAccount*)account transport: (SOSCircleStorageTransport*)circleTransport parentEvent:(NSData*)parentEvent err:(CFErrorRef*) error { __block bool result = true; - + CFErrorRef resetError = NULL; NSError* localError = nil; - SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + SFSignInAnalytics* parent = nil; + SFSignInAnalytics *resetAllRingsEvent = nil; + bool doingAnalytics = parentEvent != nil; + + if(doingAnalytics) { + parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + resetAllRingsEvent = [parent newSubTaskForEvent:@"resetAllRingsEvent"]; + } - CFErrorRef resetError = NULL; - SFSignInAnalytics *resetAllRingsEvent = [parent newSubTaskForEvent:@"resetAllRingsEvent"]; result &= [self resetAllRings:account err:&resetError]; if(resetError){ - [resetAllRingsEvent logRecoverableError:(__bridge NSError*)resetError]; + if(doingAnalytics) { + [resetAllRingsEvent logRecoverableError:(__bridge NSError*)resetError]; + } secerror("reset all rings error: %@", resetError); if(error){ *error = resetError; @@ -243,22 +234,33 @@ errOut: CFReleaseNull(resetError); } } - [resetAllRingsEvent stopWithAttributes:nil]; + if(doingAnalytics) { + [resetAllRingsEvent stopWithAttributes:nil]; + } self.fullPeerInfo = nil; self.departureCode = kSOSWithdrewMembership; - secnotice("circleOps", "Reset Circle to empty by client request"); + secnotice("circleOps", "Reset Rings to empty by client request"); + + SFSignInAnalytics *resetCircleToEmptyEvent = nil; + if(doingAnalytics) { + resetCircleToEmptyEvent = [parent newSubTaskForEvent:@"resetCircleToEmptyEvent"]; + } - 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(doingAnalytics) { + [resetCircleToEmptyEvent stopWithAttributes:nil]; + } if (!result) { secerror("error: %@", error ? *error : NULL); + } else { + notify_post(kSOSCCCircleOctagonKeysChangedNotification); } return result; } @@ -303,82 +305,60 @@ errOut: return false; } -static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSliceKeyBagRef bskb) { - - if (SOSBSKBIsDirect(bskb) || account.backup_key == NULL) - return false; - - CFSetRef peers = SOSBSKBGetPeers(bskb); - - /* first scan for retired peers, and kick'em out!*/ - SOSAccountIsPeerRetired(account, peers); - - bool needsFix = true; - - SOSPeerInfoRef myPeer = account.peerInfo; - if (myPeer) { - SOSPeerInfoRef meInBag = (SOSPeerInfoRef) CFSetGetValue(peers, myPeer); - CFDataRef myBK = SOSPeerInfoCopyBackupKey(myPeer); - CFDataRef meInBagBK = SOSPeerInfoCopyBackupKey(meInBag); - needsFix = !(meInBag && CFEqualSafe(myBK, - meInBagBK)); - CFReleaseNull(myBK); - CFReleaseNull(meInBagBK); - } - - CFDataRef rkbg = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); - if(rkbg) needsFix |= !SOSBKSBPrefixedKeyIsInKeyBag(bskb, bskbRkbgPrefix, rkbg); - else needsFix |= SOSBSKBHasRecoveryKey(bskb); // if we don't have a recovery key - the bskb shouldn't - CFReleaseNull(rkbg); - - return needsFix; -} - --(bool) handleUpdateRing:(SOSAccount*)account prospectiveRing:(SOSRingRef)prospectiveRing transport:(SOSKVSCircleStorageTransport*)circleTransport userPublicKey:(SecKeyRef)userPublic writeUpdate:(bool)writeUpdate err:(CFErrorRef *)error +-(bool) handleUpdateRing:(SOSAccount*)account prospectiveRing:(SOSRingRef)prospectiveRing transport:(SOSKVSCircleStorageTransport*)circleTransport userPublicKey:(SecKeyRef)userPublic writeUpdate:(bool)localUpdate err:(CFErrorRef *)error { - bool success = true; + bool success = false; bool haveOldRing = true; + static uint recRingProcessed = 0; + static uint bckRingProcessed = 0; - const char * __unused localRemote = writeUpdate ? "local": "remote"; + const char * __unused localRemote = localUpdate ? "local": "remote"; SOSFullPeerInfoRef fpi = self.fullPeerInfo; SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi); CFStringRef peerID = SOSPeerInfoGetPeerID(pi); - bool peerActive = (fpi && pi && peerID && [self isInCircleOnly:NULL]); + SecKeyRef peerPrivKey = SOSFullPeerInfoCopyDeviceKey(fpi, NULL); + SecKeyRef peerPubKey = SOSFullPeerInfoCopyPubKey(fpi, NULL); + __block bool peerActive = (fpi && pi && peerID && [self isInCircleOnly:NULL]); + bool ringIsBackup = SOSRingGetType(prospectiveRing) == kSOSRingBackup; + bool ringIsRecovery = SOSRingGetType(prospectiveRing) == kSOSRingRecovery; + CFStringRef ringName = SOSRingGetName(prospectiveRing); + CFMutableSetRef peers = SOSCircleCopyPeers(self.trustedCircle, kCFAllocatorDefault); // retirement tickets and iCloud key filtered out + CFMutableSetRef filteredPeerIDs = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + CFMutableSetRef filteredPeerInfos = CFSetCreateMutableForSOSPeerInfosByID(kCFAllocatorDefault); + CFStringRef ringBackupViewName = NULL; + + SOSRingRef ringToPush = NULL; SOSRingRef newRing = NULL; SOSRingRef oldRing = NULL; - require_quiet(SOSAccountHasPublicKey(account, error), errOut); - secdebug("ringSigning", "start:[%s] %@", localRemote, prospectiveRing); - - - require_action_quiet(prospectiveRing, errOut, - SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("No Ring to work with"), NULL, error)); - + require_quiet(SOSAccountHasPublicKey(account, error), errOut); + require_action_quiet(peerPubKey, errOut, SOSCreateError(kSOSErrorPublicKeyAbsent, CFSTR("No device public key to work with"), NULL, error)); + require_action_quiet(peerPrivKey, errOut, SOSCreateError(kSOSErrorPrivateKeyAbsent, CFSTR("No device private key to work with"), NULL, error)); + require_action_quiet(prospectiveRing, errOut, SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("No Ring to work with"), NULL, error)); require_action_quiet(SOSRingIsStable(prospectiveRing), errOut, SOSCreateError(kSOSErrorIncompatibleCircle, CFSTR("You give rings a bad name"), NULL, error)); // We should at least have a sane ring system in the account object require_quiet([self checkForRings:error], errOut); - - CFStringRef ringName = SOSRingGetName(prospectiveRing); + + if(ringIsBackup) { + ringBackupViewName = SOSRingGetBackupView(prospectiveRing, NULL); + peerActive &= ringBackupViewName && SOSPeerInfoIsViewPermitted(pi, ringBackupViewName) && SOSPeerInfoHasBackupKey(pi); + } + require_action_quiet(peerActive, errOut, success = true); + oldRing = [self copyRing:ringName err:NULL]; - - newRing = CFRetainSafe(prospectiveRing); // TODO: SOSAccountCloneRingWithRetirement(account, prospectiveRing, error); - + newRing = SOSRingCopyRing(prospectiveRing, NULL); ringAction_t ringAction = ignore; - bool userTrustedoldRing = true; - - CFSetRef peers = SOSCircleCopyPeers(self.trustedCircle, kCFAllocatorDefault); - + bool userTrustedoldRing = (oldRing) ? SOSRingVerify(oldRing, peerPubKey, NULL): false; SecKeyRef oldKey = userPublic; - + if (!oldRing) { oldRing = CFRetainSafe(newRing); } SOSConcordanceStatus concstat = SOSRingConcordanceTrust(fpi, peers, oldRing, newRing, oldKey, userPublic, peerID, error); - CFReleaseNull(peers); CFStringRef concStr = NULL; switch(concstat) { @@ -414,10 +394,13 @@ static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSl break; case kSOSConcordanceMissingMe: - case kSOSConcordanceImNotWorthy: ringAction = modify; concStr = CFSTR("Incorrect membership for me"); break; + case kSOSConcordanceImNotWorthy: + ringAction = leave; + concStr = CFSTR("This peer shouldn't be in this ring since it isn't in view"); + break; case kSOSConcordanceInvalidMembership: ringAction = userTrustedoldRing ? revert : ignore; concStr = CFSTR("Invalid Ring Membership"); @@ -427,130 +410,131 @@ static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSl ringAction = ignore; break; } - + (void)concStr; - + secdebug("ringSigning", "Decided on action [%s] based on concordance state [%@] and [%s] circle.", actionstring[ringAction], concStr, userTrustedoldRing ? "trusted" : "untrusted"); - - SOSRingRef ringToPush = NULL; - bool iWasInOldRing = peerID && SOSRingHasPeerID(oldRing, peerID); - bool iAmInNewRing = peerID && SOSRingHasPeerID(newRing, peerID); - bool ringIsBackup = SOSRingGetType(newRing) == kSOSRingBackup; - bool ringIsRecovery = SOSRingGetType(newRing) == kSOSRingRecovery; - - if (ringIsBackup && peerActive) { - if (ringAction == accept || ringAction == countersign) { - CFErrorRef localError = NULL; - SOSBackupSliceKeyBagRef bskb = SOSRingCopyBackupSliceKeyBag(newRing, &localError); - - if(!bskb) { - secnotice("ringSigning", "Backup ring with no backup slice keybag (%@)", localError); - } else if (SOSAccountBackupSliceKeyBagNeedsFix(account, bskb)) { - ringAction = modify; - } - CFReleaseSafe(localError); - CFReleaseSafe(bskb); - } - - if (ringAction == modify) { - CFErrorRef updateError = NULL; - [self setRing:newRing ringName:ringName err:error]; - - if(SOSAccountUpdateOurPeerInBackup(account, newRing, &updateError)) { - secdebug("signing", "Modified backup ring to include us"); - } else { - secerror("Could not add ourselves to the backup: (%@)", updateError); - } - CFReleaseSafe(updateError); - - // Fall through to normal modify handling. - } - } - - if (ringIsRecovery && peerActive && (ringAction == modify)) { - [self setRing:newRing ringName:ringName err:error]; - } - - - if (ringAction == modify) { - ringAction = ignore; - } - - if (ringAction == leave) { - if (iWasInOldRing) { - if ([self leaveRing:circleTransport ring:newRing err:error]){ - ringToPush = newRing; - } else { - secdebug("ringSigning", "Can't leave ring %@", oldRing); - success = false; - } - ringAction = accept; + + // if we're ignoring this ring we're done + require_action_quiet(ringAction != ignore, errOut, success = true); + // can't really remove ourselves since we can't sign when we do - need to rely on other peers to remove us + require_action_quiet(ringAction != leave, leaveAndAccept, ringAction = accept); + + // This will take care of modify, but we're always going to do this scan if we get this far + CFSetRef ringPeerIDSet = SOSRingCopyPeerIDs(newRing); + if(CFSetGetCount(ringPeerIDSet) == 0) { // this is a reset ring + ringAction = accept; + } else { + // Get the peerIDs appropriate for the ring + if(ringIsBackup) { + SOSCircleForEachBackupCapablePeerForView(self.trustedCircle, userPublic, ringBackupViewName, ^(SOSPeerInfoRef peer) { + CFSetAddValue(filteredPeerIDs, SOSPeerInfoGetPeerID(peer)); + CFSetAddValue(filteredPeerInfos, peer); + }); } else { - // We are not in this ring, but we need to update account with it, since we got it from cloud - ringAction = accept; + SOSCircleForEachValidSyncingPeer(self.trustedCircle, userPublic, ^(SOSPeerInfoRef peer) { + CFSetAddValue(filteredPeerIDs, SOSPeerInfoGetPeerID(peer)); + CFSetAddValue(filteredPeerInfos, peer); + }); + } + + if(!CFEqual(filteredPeerIDs, ringPeerIDSet)) { + SOSRingSetPeerIDs(newRing, filteredPeerIDs); + SOSRingRemoveSignatures(newRing, NULL); + ringAction = countersign; } } - + CFReleaseNull(ringPeerIDSet); + if (ringAction == countersign) { - if (iAmInNewRing) { - if (SOSRingPeerTrusted(newRing, fpi, NULL)) { - secdebug("ringSigning", "Already concur with: %@", newRing); - } else { - CFErrorRef signingError = NULL; - - if (fpi && SOSRingConcordanceSign(newRing, fpi, &signingError)) { + bool stopCountersign = false; + CFIndex peerCount = CFSetGetCount(filteredPeerIDs); + + if(peerCount > 0) { + // Fix payloads if necessary + if (ringIsBackup && SOSPeerInfoHasBackupKey(pi)) { + __block bool fixBSKB = false; + CFDataRef recoveryKeyData = SOSAccountCopyRecoveryPublic(kCFAllocatorDefault, account, NULL); + SOSBackupSliceKeyBagRef currentBSKB = SOSRingCopyBackupSliceKeyBag(newRing, NULL); + + fixBSKB = !currentBSKB || + !SOSBSKBAllPeersBackupKeysAreInKeyBag(currentBSKB, filteredPeerInfos) || + !SOSBSKBHasThisRecoveryKey(currentBSKB, recoveryKeyData); + + if(fixBSKB) { + CFErrorRef localError = NULL; + CFSetRef viewSet = SOSRingGetBackupViewset(newRing, NULL); + SOSBackupSliceKeyBagRef bskb = NULL; + if(recoveryKeyData) { + CFMutableDictionaryRef additionalKeys = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); + CFDictionaryAddValue(additionalKeys, bskbRkbgPrefix, recoveryKeyData); + bskb = SOSBackupSliceKeyBagCreateWithAdditionalKeys(kCFAllocatorDefault, filteredPeerInfos, additionalKeys, error); + CFReleaseNull(additionalKeys); + } else { + bskb = SOSBackupSliceKeyBagCreate(kCFAllocatorDefault, filteredPeerInfos, error); + } + + if(SOSRingSetBackupKeyBag(newRing, fpi, viewSet, bskb, &localError) == false) { + stopCountersign = true; + secnotice("recovery", "Couldn't fix BSKB (%@)", localError); + } + SOSRingRemoveSignatures(newRing, NULL); + SOSRingGenerationSign(newRing, NULL, fpi, error); ringToPush = newRing; - } else { - secerror("Failed to concordance sign, error: %@ Old: %@ New: %@", signingError, oldRing, newRing); - success = false; + CFReleaseNull(localError); + CFReleaseNull(bskb); } - CFReleaseSafe(signingError); + CFReleaseNull(recoveryKeyData); + CFReleaseNull(currentBSKB); } + } + + if(stopCountersign) { + ringAction = ignore; + } else if (SOSRingPeerTrusted(newRing, fpi, NULL)) { + secdebug("ringSigning", "Already concur with: %@", newRing); + ringAction = accept; } else { - secdebug("ringSigning", "Not countersigning, not in ring: %@", newRing); + CFErrorRef signingError = NULL; + if (fpi && SOSRingConcordanceSign(newRing, fpi, &signingError)) { + ringToPush = newRing; + ringAction = accept; + } else { + secerror("Failed to concordance sign, error: %@ Old: %@ New: %@", signingError, oldRing, newRing); + success = false; + ringAction = ignore; + } + CFReleaseSafe(signingError); } - ringAction = accept; } + +leaveAndAccept: if (ringAction == accept) { - if (iWasInOldRing && !iAmInNewRing) { - - // Don't destroy evidence of other code determining reason for leaving. - //if(!SOSAccountHasLeft(account)) account.departure_code = kSOSMembershipRevoked; - // TODO: LeaveReason for rings + if(ringIsRecovery) { + if(!localUpdate) { // processing a remote ring - we accept the new recovery key here + if(SOSRingIsEmpty_Internal(newRing)) { // Reset ring will reset the recovery key + SOSRecoveryKeyBagRef ringRKBG = SOSRecoveryKeyBagCreateForAccount(kCFAllocatorDefault, (__bridge CFTypeRef)account, SOSRKNullKey(), error); + SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, error); + CFReleaseNull(ringRKBG); + } else { // normal ring recovery key harvest + SOSRecoveryKeyBagRef ringRKBG = SOSRingCopyRecoveryKeyBag(newRing, NULL); + SOSAccountSetRecoveryKeyBagEntry(kCFAllocatorDefault, account, ringRKBG, error); + CFReleaseNull(ringRKBG); + } + } } - if (pi && SOSRingHasRejection(newRing, peerID)) { - // TODO: ReasonForLeaving for rings SOSRingRemoveRejection(newRing, peerID); } - [self setRing:newRing ringName:ringName err:error]; - - if (pi && account.accountKeyIsTrusted - && SOSRingHasApplicant(oldRing, peerID) - && SOSRingCountPeers(newRing) > 0 - && !iAmInNewRing && !SOSRingHasApplicant(newRing, peerID)) { - // 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. - - if (SOSRingApply(newRing, userPublic, fpi, NULL)) - if(peerActive) writeUpdate = true; - } - - if (pi && SOSRingHasPeerID(oldRing, peerID)) { - [self cleanupRetirementTickets:account circle:self.trustedCircle time:RETIREMENT_FINALIZATION_SECONDS err:NULL]; - } - - account.circle_rings_retirements_need_attention = true; - - if (writeUpdate) + if (localUpdate) { ringToPush = newRing; - secnotice("circleop", "Setting account.key_interests_need_updating to true in handleUpdateRing"); - account.key_interests_need_updating = true; + } else if (ringToPush == NULL) { + success = true; + } } /* @@ -560,33 +544,40 @@ static bool SOSAccountBackupSliceKeyBagNeedsFix(SOSAccount* account, SOSBackupSl */ if (ringAction == revert) { - if(haveOldRing && peerActive && SOSRingHasPeerID(oldRing, peerID)) { + if(haveOldRing && SOSRingHasPeerID(oldRing, peerID)) { secdebug("ringSigning", "%@, Rejecting: %@ re-publishing %@", concStr, newRing, oldRing); ringToPush = oldRing; } else { - secdebug("ringSigning", "%@, Rejecting: %@ Have no old circle - would reset", concStr, newRing); + secdebug("ringSigning", "%@, Rejecting: %@ Have no old ring - would reset", concStr, newRing); } } - - + if (ringToPush != NULL) { + if(ringIsBackup) { + bckRingProcessed++; + } else if(ringIsRecovery) { + recRingProcessed++; + } secdebug("ringSigning", "Pushing:[%s] %@", localRemote, ringToPush); CFDataRef ringData = SOSRingCopyEncodedData(ringToPush, error); if (ringData) { - success &= [circleTransport kvsRingPostRing:SOSRingGetName(ringToPush) ring:ringData err:error]; + success = [circleTransport kvsRingPostRing:SOSRingGetName(ringToPush) ring:ringData err:error]; } else { success = false; } + secnotice("circleop", "Setting account.key_interests_need_updating to true in handleUpdateRing"); + account.key_interests_need_updating = true; CFReleaseNull(ringData); } - CFReleaseNull(oldRing); - CFReleaseNull(newRing); - return success; errOut: + CFReleaseNull(filteredPeerIDs); + CFReleaseNull(filteredPeerInfos); CFReleaseNull(oldRing); CFReleaseNull(newRing); - return false; - + CFReleaseNull(peers); + CFReleaseNull(peerPubKey); + CFReleaseNull(peerPrivKey); + return success; } -(SOSRingRef) copyRing:(CFStringRef)ringName err:(CFErrorRef *)error @@ -630,38 +621,5 @@ errOut: return retval; } --(bool) leaveRing:(SOSKVSCircleStorageTransport*)circle_transport ring:(SOSRingRef) ring err:(CFErrorRef*) error -{ - SOSFullPeerInfoRef fpi = self.fullPeerInfo; - if(!fpi) return false; - SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi); - CFStringRef peerID = SOSPeerInfoGetPeerID(pi); - - CFErrorRef localError = NULL; - - bool retval = false; - bool writeRing = false; - bool writePeerInfo = false; - - if(SOSRingHasPeerID(ring, peerID)) { - writePeerInfo = true; - } - - if(writePeerInfo || writeRing) { - SOSRingWithdraw(ring, NULL, fpi, error); - } - - if (writeRing) { - CFDataRef ring_data = SOSRingCopyEncodedData(ring, error); - - if (ring_data) { - [circle_transport kvsRingPostRing:SOSRingGetName(ring) ring:ring_data err:NULL]; - } - CFReleaseNull(ring_data); - } - retval = true; - CFReleaseNull(localError); - return retval; -} @end diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h b/keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h similarity index 93% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h index e7e78c2f..0bd9cd22 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.h +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h @@ -6,7 +6,7 @@ #ifndef SOSAccountTrustClassic_Identity_h #define SOSAccountTrustClassic_Identity_h -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" @class SOSAccountTrustClassic; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m b/keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.m similarity index 88% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.m index 16b29cf6..d72bd125 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Identity.m +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.m @@ -6,15 +6,15 @@ #import #include -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Identity.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" #if __OBJC2__ #import "Analytics/Clients/SOSAnalytics.h" #endif // __OBJC2__ -#import "Security/SecureObjectSync/SOSViews.h" +#import "keychain/SecureObjectSync/SOSViews.h" @implementation SOSAccountTrustClassic (Identity) @@ -222,6 +222,7 @@ require_action_quiet(self.trustedCircle, fail, SOSCreateErrorWithFormat(kSOSErrorNoCircle, NULL, error, NULL, CFSTR("Don't have circle"))); if (self.fullPeerInfo == NULL) { + bool skipInitialSync = false; // This will be set if the set of initial sync views is empty NSString* octagonKeyName; CFStringRef keyName = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("ID for %@-%@"), SOSPeerGestaltGetName(gestalt), SOSCircleGetName(self.trustedCircle)); SecKeyRef full_key = [self randomPermanentFullECKey:256 name:(__bridge NSString *)keyName error:NULL]; @@ -233,24 +234,38 @@ SecKeyRef octagonEncryptionFullKey = [self randomPermanentFullECKey:384 name:octagonKeyName error:NULL]; if (full_key && octagonSigningFullKey && octagonEncryptionFullKey) { - CFSetRef initialViews = SOSViewCopyViewSet(kViewSetInitial); - - self.fullPeerInfo = nil; + CFMutableSetRef initialViews = SOSViewCopyViewSet(kViewSetInitial); + CFMutableSetRef initialSyncDoneViews = SOSViewCopyViewSet(kViewSetAlwaysOn); + CFSetRef defaultViews = SOSViewCopyViewSet(kViewSetDefault); + CFSetRef backupViews = SOSViewCopyViewSet(kViewSetRequiredForBackup); + + CFSetUnion(initialSyncDoneViews, defaultViews); + + // If there are no "initialViews" then we're basically through initial sync - so setup alwaysOn and default views + if(CFSetGetCount(initialViews) == 0) { + skipInitialSync = true; + CFSetUnion(initialViews, initialSyncDoneViews); + } + CFSetUnion(initialViews, backupViews); // setting fullPeerInfo takes an extra ref, so... + self.fullPeerInfo = nil; SOSFullPeerInfoRef fpi = SOSFullPeerInfoCreateWithViews(kCFAllocatorDefault, gestalt, backup, initialViews, full_key, octagonSigningFullKey, octagonEncryptionFullKey, error); self.fullPeerInfo = fpi; CFReleaseNull(fpi); CFDictionaryRef v2dictionaryTestUpdates = [self getValueFromExpansion:kSOSTestV2Settings err:NULL]; if(v2dictionaryTestUpdates) SOSFullPeerInfoUpdateV2Dictionary(self.fullPeerInfo, v2dictionaryTestUpdates, NULL); + + if(!skipInitialSync) { + [self pendEnableViewSet:initialSyncDoneViews]; + [self setValueInExpansion:kSOSUnsyncedViewsKey value:kCFBooleanTrue err:NULL]; + } + CFReleaseNull(initialViews); - - CFSetRef pendingDefaultViews = SOSViewCopyViewSet(kViewSetDefault); - [self pendEnableViewSet:pendingDefaultViews]; - CFReleaseNull(pendingDefaultViews); - - [self setValueInExpansion:kSOSUnsyncedViewsKey value:kCFBooleanTrue err:NULL]; + CFReleaseNull(backupViews); + CFReleaseNull(initialSyncDoneViews); + CFReleaseNull(defaultViews); } else { secerror("No full_key: %@:", error ? *error : NULL); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Retirement.h b/keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h similarity index 83% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Retirement.h rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h index f2ee2dcf..3054b7f4 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Retirement.h +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h @@ -6,8 +6,8 @@ #ifndef SOSAccountTrustClassic_Retirement_h #define SOSAccountTrustClassic_Retirement_h -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" @interface SOSAccountTrustClassic (Retirement) //Retirement diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Retirement.m b/keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.m similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Retirement.m rename to keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.m index fbdde2e6..a3b0fab9 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic+Retirement.m +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.m @@ -7,10 +7,10 @@ // #import -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" -#import "Security/SecureObjectSync/SOSPeerInfoCollections.h" -#import "Security/SecureObjectSync/SOSTransportMessageKVS.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" +#import "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" @implementation SOSAccountTrustClassic (Retirement) diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h b/keychain/SecureObjectSync/SOSAccountTrustClassic.h similarity index 89% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h rename to keychain/SecureObjectSync/SOSAccountTrustClassic.h index fe1c260e..f9b7a9a7 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.h +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic.h @@ -6,10 +6,10 @@ #ifndef SOSAccountTrustClassic_h #define SOSAccountTrustClassic_h -#import -#import "Security/SecureObjectSync/SOSAccountTrust.h" -#import "Security/SecureObjectSync/SOSTypes.h" -#import "Security/SecureObjectSync/SOSTransportCircleKVS.h" +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSTypes.h" +#import "keychain/SecureObjectSync/SOSTransportCircleKVS.h" @class SOSAccount; @interface SOSAccountTrustClassic : SOSAccountTrust @@ -32,7 +32,6 @@ //Views -(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; @@ -59,6 +58,7 @@ -(CFMutableSetRef) copyPreApprovedHSA2Info; -(void) addRingDictionary; +-(void) resetRingDictionary; @end #endif /* SOSAccountTrustClassic_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m b/keychain/SecureObjectSync/SOSAccountTrustClassic.m similarity index 85% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m rename to keychain/SecureObjectSync/SOSAccountTrustClassic.m index 93d9df08..10459637 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountTrustClassic.m +++ b/keychain/SecureObjectSync/SOSAccountTrustClassic.m @@ -4,23 +4,23 @@ // #import -#import "Security/SecureObjectSync/SOSAccount.h" -#import "Security/SecureObjectSync/SOSViews.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Identity.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Circle.h" -#import "Security/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" - -#import "Security/SecureObjectSync/SOSPeerInfoV2.h" -#import "Security/SecureObjectSync/SOSPeerInfoCollections.h" -#import "Security/SecureObjectSync/SOSTransportMessageKVS.h" - -#include -#include -#include -#include -#include +#import "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSViews.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Retirement.h" + +#import "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" + +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" +#include "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#include "keychain/SecureObjectSync/SOSTransportCircle.h" +#include "keychain/SecureObjectSync/SOSCircleDer.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -92,14 +92,15 @@ extern CFStringRef kSOSAccountDebugScope; SOSViewResultCode retval = kSOSCCGeneralViewError; SOSViewResultCode currentStatus = kSOSCCGeneralViewError; bool alreadyInSync = SOSAccountHasCompletedInitialSync(account); - bool updateCircle = false; + CFSetRef alwaysOn = SOSViewCopyViewSet(kViewSetAlwaysOn); + 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((actionCode == kSOSCCViewEnable) || (actionCode == kSOSCCViewDisable), errOut, CFSTR("Invalid View Action")); currentStatus = [account.trust viewStatus:account name:viewname err:error]; require_action_quiet((currentStatus == kSOSCCViewNotMember) || (currentStatus == kSOSCCViewMember), errOut, CFSTR("View Membership Not Actionable")); - + if (CFEqualSafe(viewname, kSOSViewKeychainV0)) { retval = SOSAccountVirtualV0Behavior(account, actionCode); } else if ([account.trust isSyncingV0] && SOSViewsIsV0Subview(viewname)) { @@ -120,7 +121,9 @@ extern CFStringRef kSOSAccountDebugScope; updateCircle = false; } } else if(actionCode == kSOSCCViewDisable && currentStatus == kSOSCCViewMember) { - if(alreadyInSync) { + if(alwaysOn && CFSetContainsValue(alwaysOn, viewname)) { + retval = kSOSCCViewMember; + } else if(alreadyInSync) { retval = SOSFullPeerInfoUpdateViews(self.fullPeerInfo, actionCode, viewname, error); if(retval == kSOSCCViewNotMember) updateCircle = true; } else { @@ -142,6 +145,7 @@ extern CFStringRef kSOSAccountDebugScope; } errOut: + CFReleaseNull(alwaysOn); return retval; } #pragma clang diagnostic pop @@ -213,7 +217,12 @@ static bool SOSAccountScreenViewListForValidV0(SOSAccount* account, CFMutableSe bool updateCircle = false; SOSPeerInfoRef pi = NULL; NSError* localError = nil; - SFSignInAnalytics* parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + SFSignInAnalytics* parent = NULL; + bool doAnalytics = (parentEvent != NULL); + + if(doAnalytics) { + parent = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFSignInAnalytics class] fromData:parentEvent error:&localError]; + } SFSignInAnalytics *hasCompletedInitialSyncEvent = nil; SFSignInAnalytics *updatePeerInCircleEvent = nil; @@ -254,8 +263,9 @@ static bool SOSAccountScreenViewListForValidV0(SOSAccount* account, CFMutableSe 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(doAnalytics) { + hasCompletedInitialSyncEvent = [parent newSubTaskForEvent:@"hasCompletedInitialSyncEvent"]; + } if(SOSAccountHasCompletedInitialSync(account)) { if(enabledViews) updateCircle |= SOSViewSetEnable(pi, enabledViews); if(disabledViews) updateCircle |= SOSViewSetDisable(pi, disabledViews); @@ -266,96 +276,31 @@ static bool SOSAccountScreenViewListForValidV0(SOSAccount* account, CFMutableSe if(disabledViews) SOSAccountPendDisableViewSet(account, disabledViews); retval = true; } - [hasCompletedInitialSyncEvent stopWithAttributes:nil]; + if(doAnalytics) { + [hasCompletedInitialSyncEvent stopWithAttributes:nil]; + } if(updateCircle) { /* UPDATE FULLPEERINFO VIEWS */ require_quiet(SOSFullPeerInfoUpdateToThisPeer(fpi, pi, NULL), errOut); - updatePeerInCircleEvent = [parent newSubTaskForEvent:@"updatePeerInCircleEvent"]; + if(doAnalytics) { + 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]; + if(doAnalytics) { + [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; - bool updateCircle = false; - SOSPeerInfoRef pi = NULL; - 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")); - - 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; - } - - if(updateCircle) { - /* UPDATE FULLPEERINFO VIEWS */ - require_quiet(SOSFullPeerInfoUpdateToThisPeer(fpi, pi, NULL), errOut); - - 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); - - // Make sure we update the engine - account.circle_rings_retirements_need_attention = true; + if(doAnalytics) { + [updatePeerInCircleEvent stopWithAttributes:nil]; } - -errOut: CFReleaseNull(enabledViews); CFReleaseNull(disabledViews); CFReleaseNull(pi); @@ -621,7 +566,7 @@ static size_t der_sizeof_data_optional(CFDataRef data) require_quiet(accumulate_size(&sequence_size, der_sizeof_public_bytes(account.previousAccountKey, &failure)), fail); require_quiet(accumulate_size(&sequence_size, der_sizeof_data_or_null((__bridge CFDataRef)account.accountKeyDerivationParamters, &failure)), fail); require_quiet(accumulate_size(&sequence_size, SOSPeerInfoSetGetDEREncodedArraySize((__bridge CFSetRef)self.retirees, &failure)), fail); - accumulate_size(&sequence_size, der_sizeof_data_optional((__bridge CFDataRef)(account.backup_key))); + (void)accumulate_size(&sequence_size, der_sizeof_data_optional((__bridge CFDataRef)(account.backup_key))); require_quiet(accumulate_size(&sequence_size, der_sizeof_dictionary((__bridge CFDictionaryRef)(self.expansion), &failure)), fail); return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, sequence_size); @@ -844,5 +789,12 @@ static NSString* kSOSRingKey = @"trusted_rings"; } } +-(void) resetRingDictionary { + if(self.expansion) { + NSMutableDictionary *rings = [NSMutableDictionary dictionary]; + [self.expansion setObject:rings forKey:kSOSRingKey]; + } +} + @end diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m b/keychain/SecureObjectSync/SOSAccountUpdate.m similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m rename to keychain/SecureObjectSync/SOSAccountUpdate.m index e8f7de9d..9c0cad82 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountUpdate.m +++ b/keychain/SecureObjectSync/SOSAccountUpdate.m @@ -6,19 +6,19 @@ #include "SOSAccountPriv.h" #include "SOSAccountLog.h" -#include -#include +#include "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#include "keychain/SecureObjectSync/SOSTransport.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" #include -#include +#import "keychain/SecureObjectSync/SOSAccountGhost.h" -#import -#import -#import +#import "keychain/SecureObjectSync/SOSAccountTrust.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" static void DifferenceAndCall(CFSetRef old_members, CFSetRef new_members, void (^updatedCircle)(CFSetRef additions, CFSetRef removals)) { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m b/keychain/SecureObjectSync/SOSAccountViewSync.m similarity index 84% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m rename to keychain/SecureObjectSync/SOSAccountViewSync.m index 34ea0992..f619a750 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAccountViewSync.m +++ b/keychain/SecureObjectSync/SOSAccountViewSync.m @@ -9,15 +9,15 @@ #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include "SOSViews.h" #include "SOSAccountPriv.h" #include -#import -#import -#import -#import +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Circle.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Expansion.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic+Identity.h" // // MARK: Helpers @@ -37,6 +37,32 @@ static CFMutableSetRef SOSAccountCopyOtherPeersViews(SOSAccount* account) { // // MARK: Outstanding tracking // + +static bool isInitialSyncActive(void) { + static dispatch_once_t onceToken; + __block bool active = true; + + dispatch_once(&onceToken, ^{ + CFSetRef initialSyncViews = SOSViewCopyViewSet(kViewSetInitial); + active = CFSetGetCount(initialSyncViews) > 0; + CFReleaseNull(initialSyncViews); + }); + + return active; +} + +void SOSAccountInitializeInitialSync(SOSAccount* account) { + if(!account) { + return; + } + if(isInitialSyncActive()) { + SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanTrue, NULL); + } else { + SOSAccountSetValue(account, kSOSUnsyncedViewsKey, kCFBooleanFalse, NULL); + } +} + + CFMutableSetRef SOSAccountCopyOutstandingViews(SOSAccount* account) { CFSetRef initialSyncViews = SOSViewCopyViewSet(kViewSetAll); CFMutableSetRef result = SOSAccountCopyIntersectionWithOustanding(account, initialSyncViews); @@ -122,8 +148,46 @@ bool SOSAccountHasCompletedRequiredBackupSync(SOSAccount* account) { // MARK: Handling initial sync being done // +CFSetRef SOSAccountCopyEnabledViews(SOSAccount* account) { + if(!(account && account.peerInfo)) { + return NULL; + } + CFSetRef piViews = SOSPeerInfoCopyEnabledViews(account.peerInfo); + + if(SOSAccountHasCompletedInitialSync(account)) { + return piViews; + } + CFSetRef pendingEnabled = asSet(SOSAccountGetValue(account, kSOSPendingEnableViewsToBeSetKey, NULL), NULL); + CFSetRef pendingDisabled = asSet(SOSAccountGetValue(account, kSOSPendingDisableViewsToBeSetKey, NULL), NULL); + + CFMutableSetRef retvalViews = CFSetCreateMutableCopy(kCFAllocatorDefault, 0, piViews); + CFSetUnion(retvalViews, pendingEnabled); + CFSetSubtract(retvalViews, pendingDisabled); + + CFReleaseNull(piViews); + CFReleaseNull(pendingEnabled); + CFReleaseNull(pendingDisabled); + return retvalViews; +} + + static bool SOSAccountResolvePendingViewSets(SOSAccount* account, CFErrorRef *error) { - bool status = [account.trust updateViewSets:account enabled:asSet(SOSAccountGetValue(account, kSOSPendingEnableViewsToBeSetKey, NULL), NULL) disabled:asSet(SOSAccountGetValue(account, kSOSPendingDisableViewsToBeSetKey, NULL), NULL)]; + CFMutableSetRef newPending = SOSViewCopyViewSet(kViewSetAlwaysOn); + CFMutableSetRef defaultOn = SOSViewCopyViewSet(kViewSetDefault); + CFSetRef pendingOn = asSet(SOSAccountGetValue(account, kSOSPendingEnableViewsToBeSetKey, NULL), NULL); + CFSetRef pendingDisabled = asSet(SOSAccountGetValue(account, kSOSPendingDisableViewsToBeSetKey, NULL), NULL); + + if(defaultOn) { + CFSetUnion(newPending, defaultOn); + } + if(pendingOn) { + CFSetUnion(newPending, pendingOn); + } + CFReleaseNull(defaultOn); + + bool status = [account.trust updateViewSetsWithAnalytics:account enabled:newPending disabled:pendingDisabled parentEvent: NULL]; + CFReleaseNull(newPending); + if(status){ SOSAccountClearValue(account, kSOSPendingEnableViewsToBeSetKey, NULL); SOSAccountClearValue(account, kSOSPendingDisableViewsToBeSetKey, NULL); @@ -225,6 +289,7 @@ static bool SOSViewIntersectionWentEmpty(ViewSetKind kind, CFSetRef before, CFSe return result; } + bool SOSAccountHandleOutOfSyncUpdate(SOSAccount* account, CFSetRef oldOOSViews, CFSetRef newOOSViews) { bool actionTaken = false; diff --git a/keychain/SecureObjectSync/SOSAuthKitHelpers.h b/keychain/SecureObjectSync/SOSAuthKitHelpers.h new file mode 100644 index 00000000..d4831b47 --- /dev/null +++ b/keychain/SecureObjectSync/SOSAuthKitHelpers.h @@ -0,0 +1,33 @@ +// +// SOSAuthKitHelpers.h +// Security +// + +#ifndef SOSAuthKitHelpers_h +#define SOSAuthKitHelpers_h + +#import "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSTrustedDeviceAttributes.h" + +@interface SOSAuthKitHelpers : NSObject ++ (NSString * _Nullable)machineID; ++ (void) activeMIDs:(void(^_Nonnull)(NSSet * _Nullable activeMIDs, NSError * _Nullable error))complete; ++ (bool) updateMIDInPeerInfo: (SOSAccount *_Nonnull) account; ++ (bool) peerinfoHasMID: (SOSAccount *_Nonnull) account; ++ (bool) accountIsHSA2; +- (id _Nullable) initWithActiveMIDS: (NSSet *_Nullable) theMidList; +- (bool) midIsValidInList: (NSString *_Nullable) machineId; +- (bool) serialIsValidInList: (NSString *_Nullable) serialNumber; +- (bool) isUseful; + +#if __OBJC2__ + +@property (nonatomic, retain) NSSet * _Nullable midList; +@property (nonatomic, retain) NSSet * _Nullable machineIDs; +@property (nonatomic, retain) NSSet * _Nullable serialNumbers; + +#endif /* __OBJC2__ */ + +@end + +#endif /* SOSAuthKitHelpers_h */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m b/keychain/SecureObjectSync/SOSAuthKitHelpers.m similarity index 50% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m rename to keychain/SecureObjectSync/SOSAuthKitHelpers.m index 7eb82fb2..03ea585d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSAuthKitHelpers.m +++ b/keychain/SecureObjectSync/SOSAuthKitHelpers.m @@ -2,29 +2,24 @@ // SOSAuthKitHelpers.m // Security // -// Created by murf on 6/19/18. // #import #import "SOSAuthKitHelpers.h" #import -#import -#import -#import -#import -#import +#import "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSAccountPriv.h" +#import "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#import "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#import "keychain/SecureObjectSync/SOSPeerInfoPriv.h" -#if !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR +#if !TARGET_OS_BRIDGE && !TARGET_OS_SIMULATOR && __OBJC2__ #import #import #import +#import #define SUPPORT_MID 1 -#endif - -@implementation SOSAuthKitHelpers - -#if SUPPORT_MID SOFT_LINK_FRAMEWORK(PrivateFrameworks, AuthKit); SOFT_LINK_FRAMEWORK(Frameworks, Accounts); @@ -40,7 +35,21 @@ SOFT_LINK_CLASS(Accounts, ACAccountStore); SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *); #pragma clang diagnostic pop +static void *accountsFramework = NULL; +static void *appleAccountFramework = NULL; +static void +initAccountsFramework(void) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + accountsFramework = dlopen("/System/Library/Frameworks/Accounts.framework/Accounts", RTLD_LAZY); + appleAccountFramework = dlopen("/System/Library/PrivateFrameworks/AppleAccount.framework/AppleAccount", RTLD_LAZY); + }); +} + +@implementation SOSAuthKitHelpers + +@class SOSAuthKitHelpers; + (NSString *) machineID { NSError *error = nil; @@ -66,12 +75,75 @@ SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *); return retval; } +static ACAccount *GetPrimaryAccount(void) { + ACAccount *primaryAccount; + + initAccountsFramework(); + + ACAccountStore *store = [getACAccountStoreClass() new]; + + if(!store) { + secnotice("sosauthkit", "can't get store"); + return nil; + } + + primaryAccount = [store aa_primaryAppleAccount]; + + return primaryAccount; +} + + ++ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete { + ACAccount *primaryAccount; + AKDeviceListRequestContext *context; + + primaryAccount = GetPrimaryAccount(); + + 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 fetchDeviceListWithContext:error:] is not exposed, use a semaphore + 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 new]; + for(AKRemoteDevice *akdev in deviceList) { + SOSTrustedDeviceAttributes *newdev = [SOSTrustedDeviceAttributes new]; + newdev.machineID = akdev.machineId; + newdev.serialNumber = akdev.serialNumber; + [mids addObject:newdev]; + } + if([mids count] == 0) { + secnotice("sosauthkit", "found no devices in account"); + mids = nil; + } + complete(mids, error); + }]; +} + + (bool) peerinfoHasMID: (SOSAccount *) account { SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(account.fullPeerInfo); - if(!pi) return false; + if(!pi) return true; // if there's no PI then just say "we don't need one" return SOSPeerInfoV2DictionaryHasString(pi, sMachineIDKey); } + + + (bool) updateMIDInPeerInfo: (SOSAccount *) account { NSString *mid = [SOSAuthKitHelpers machineID]; if(!mid) return true; @@ -92,63 +164,83 @@ SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *); 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; - } ++ (bool) accountIsHSA2 { + bool hsa2 = false; + + ACAccount *primaryAccount = GetPrimaryAccount(); + AKAccountManager *manager = [getAKAccountManagerClass() new]; - context = [getAKDeviceListRequestContextClass() new]; - if (context == NULL) { - complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get AKDeviceListRequestContextClass"}]); - return; + if(manager && primaryAccount) { + ACAccount *account = [manager authKitAccountWithAltDSID:[manager altDSIDForAccount:primaryAccount]]; + AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount:account]; + if(securityLevel == AKAppleIDSecurityLevelHSA2) { + hsa2 = true; + } else { + secnotice("sosauthkit", "Security level is %lu", (unsigned long)securityLevel); + } + secnotice("sosauthkit", "Account %s HSA2", (hsa2) ? "is": "isn't" ); + } else { + secnotice("sosauthkit", "Failed to get manager"); } - context.altDSID = primaryAccount.aa_altDSID; - context.services = @[ getAKServiceNameiCloud() ]; + return hsa2; +} - AKAppleIDAuthenticationController *authController = [getAKAppleIDAuthenticationControllerClass() new]; - if(!authController) { - complete(NULL, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey : @"can't get authController"}]); - return; + +-(id) initWithActiveMIDS: (NSSet *) theMidList +{ + self = [super init]; + if(!self){ + return nil; } + NSMutableSet *MmachineIDs = [[NSMutableSet alloc] init]; + NSMutableSet *MserialNumbers = [[NSMutableSet alloc] init]; + _machineIDs = [[NSSet alloc] init]; + _serialNumbers = [[NSSet alloc] init]; - [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(!theMidList) return nil; + _midList = theMidList; + + for(SOSTrustedDeviceAttributes *dev in _midList) { + if(dev.machineID) { + [MmachineIDs addObject:dev.machineID]; } - if([mids count] == 0) { - secnotice("sosauthkit", "found not devices in account"); - mids = nil; + if(dev.serialNumber) { + [MserialNumbers addObject:dev.serialNumber]; } - complete(mids, error); - }]; + } + _machineIDs = MmachineIDs; + _serialNumbers = MserialNumbers; + return self; +} + +// if the ID passed in is null, the peer doesn't have one, we'll say true - we can't tell from the list +- (bool) midIsValidInList: (NSString *) machineId { + return (machineId) ? [_machineIDs containsObject:machineId]: true; +} + +- (bool) serialIsValidInList: (NSString *) serialNumber { + return (serialNumber) ? [_serialNumbers containsObject:serialNumber]: true; +} + +- (bool) isUseful { + return [ _machineIDs count ] > 0; } +#else -#else /* TARGET_OS_BRIDGE || TARGET_OS_SIMULATOR */ + +@implementation SOSAuthKitHelpers + +@class SOSAuthKitHelpers; + (NSString *) machineID { return nil; } -+ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete { - complete(NULL, NULL); ++ (void)activeMIDs:(void(^_Nonnull)(NSSet *activeMIDs, NSError *error))complete { + complete(nil, nil); } + (bool) updateMIDInPeerInfo: (SOSAccount *) account { @@ -156,6 +248,26 @@ SOFT_LINK_CONSTANT(AuthKit, AKServiceNameiCloud, const NSString *); } + (bool) peerinfoHasMID: (SOSAccount *) account { + return true; +} + ++ (bool) accountIsHSA2 { + return false; +} + +- (id _Nullable) initWithActiveMIDS: (NSSet *_Nullable) theMidList { + return nil; +} + +- (bool) midIsValidInList: (NSString *_Nullable) machineId { + return true; +} + +- (bool) serialIsValidInList: (NSString *_Nullable) serialNumber { + return true; +} + +- (bool) isUseful { return false; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupEvent.c b/keychain/SecureObjectSync/SOSBackupEvent.c similarity index 99% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSBackupEvent.c rename to keychain/SecureObjectSync/SOSBackupEvent.c index 10ecd658..87d69ea5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupEvent.c +++ b/keychain/SecureObjectSync/SOSBackupEvent.c @@ -25,7 +25,7 @@ * SOSBackupEvent.c - Implementation of a secure object syncing peer */ -#include +#include "keychain/SecureObjectSync/SOSBackupEvent.h" #include #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupEvent.h b/keychain/SecureObjectSync/SOSBackupEvent.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSBackupEvent.h rename to keychain/SecureObjectSync/SOSBackupEvent.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupInformation.h b/keychain/SecureObjectSync/SOSBackupInformation.h similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSBackupInformation.h rename to keychain/SecureObjectSync/SOSBackupInformation.h index a89ad1ff..b11d57b6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupInformation.h +++ b/keychain/SecureObjectSync/SOSBackupInformation.h @@ -30,7 +30,7 @@ #define SOSBackupInformation_h #include -#include +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" enum { noError = 0, diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupInformation.m b/keychain/SecureObjectSync/SOSBackupInformation.m similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSBackupInformation.m rename to keychain/SecureObjectSync/SOSBackupInformation.m diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h b/keychain/SecureObjectSync/SOSBackupSliceKeyBag.h similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h rename to keychain/SecureObjectSync/SOSBackupSliceKeyBag.h index 1b9a40c5..ae6ed51d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.h +++ b/keychain/SecureObjectSync/SOSBackupSliceKeyBag.h @@ -33,6 +33,8 @@ extern CFStringRef bskbRkbgPrefix; +CFDataRef SOSRKNullKey(void); + // We don't have a portable header (particularly for the SIM) so for now we define the one type we need. // This should be fixed when we get a portable AKS interface. typedef int32_t bskb_keybag_handle_t; @@ -60,6 +62,8 @@ int SOSBSKBCountPeers(SOSBackupSliceKeyBagRef backupSliceKeyBag); bool SOSBSKBPeerIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, SOSPeerInfoRef pi); bool SOSBKSBKeyIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, CFDataRef publicKey); +bool SOSBKSBPeerBackupKeyIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, SOSPeerInfoRef pi); +bool SOSBSKBAllPeersBackupKeysAreInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, CFSetRef peers); bool SOSBKSBPrefixedKeyIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, CFStringRef prefix, CFDataRef publicKey); // Keybag fetching @@ -99,5 +103,6 @@ bool SOSBSKBIsGoodBackupPublic(CFDataRef publicKey, CFErrorRef *error); CFDataRef SOSBSKBCopyRecoveryKey(SOSBackupSliceKeyBagRef bskb); bool SOSBSKBHasRecoveryKey(SOSBackupSliceKeyBagRef bskb); +bool SOSBSKBHasThisRecoveryKey(SOSBackupSliceKeyBagRef bskb, CFDataRef backupKey); #endif /* defined(_sec_SOSBackupSliceKeyBag_) */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m b/keychain/SecureObjectSync/SOSBackupSliceKeyBag.m similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m rename to keychain/SecureObjectSync/SOSBackupSliceKeyBag.m index e89c54e5..f41ad4b6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSBackupSliceKeyBag.m +++ b/keychain/SecureObjectSync/SOSBackupSliceKeyBag.m @@ -37,8 +37,8 @@ #include #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -46,14 +46,23 @@ #include -#include "SecRecoveryKey.h" +#include #include "SOSKeyedPubKeyIdentifier.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include "SecADWrapper.h" #include "SecCFAllocator.h" CFStringRef bskbRkbgPrefix = CFSTR("RK"); +CFDataRef SOSRKNullKey(void) { + static CFDataRef localNullKey = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + localNullKey = CFDataCreate(kCFAllocatorDefault, (const UInt8*) "nullkey", 8); + }); + return localNullKey; +} + // // MARK: Type creation // @@ -465,6 +474,36 @@ done: return result; } +bool SOSBKSBPeerBackupKeyIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, SOSPeerInfoRef pi) { + bool result = false; + CFDataRef bskbBackupKey = NULL; + + CFDataRef backupKey = SOSPeerInfoCopyBackupKey(pi); + SOSPeerInfoRef backupPI = asSOSPeerInfo(CFSetGetValue(backupSliceKeyBag->peers, pi)); + if(backupPI) { + bskbBackupKey = SOSPeerInfoCopyBackupKey(backupPI); + } + result = CFEqualSafe(backupKey, bskbBackupKey); + CFReleaseNull(bskbBackupKey); + CFReleaseNull(backupKey); + return result; +} + +// returns true if all peers in (peers) and only those peers have matching backupKeys in the BSKB +bool SOSBSKBAllPeersBackupKeysAreInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, CFSetRef peers) { + __block bool result = false; + if(backupSliceKeyBag && peers) { + result = (SOSBSKBCountPeers(backupSliceKeyBag) == CFSetGetCount(peers)); + if(result) { + CFSetForEach(peers, ^(const void *value) { + SOSPeerInfoRef pi = asSOSPeerInfo(value); + result &= pi && SOSBKSBPeerBackupKeyIsInKeyBag(backupSliceKeyBag, pi); + }); + } + } + return result; +} + bool SOSBKSBPrefixedKeyIsInKeyBag(SOSBackupSliceKeyBagRef backupSliceKeyBag, CFStringRef prefix, CFDataRef publicKey) { bool result = false; CFStringRef kpkid = SOSKeyedPubKeyIdentifierCreateWithData(prefix, publicKey); @@ -597,7 +636,7 @@ exit: return result; } -#include "SecRecoveryKey.h" +#include static bool SOSPerformWithRecoveryKeyFullKey(CFDataRef wrappingSecret, CFErrorRef *error, void (^operation)(ccec_full_ctx_t fullKey, CFStringRef keyID)) { bool result = false; @@ -689,25 +728,39 @@ static bool SOSBSKBHasPrefixedKey(SOSBackupSliceKeyBagRef bskb, CFStringRef pref } CFDataRef SOSBSKBCopyRecoveryKey(SOSBackupSliceKeyBagRef bskb) { + if(!bskb) return NULL; CFDictionaryRef keyDict = SOSBSKBCopyAdditionalKeysWithPrefix(kCFAllocatorDefault, bskb, bskbRkbgPrefix); if(!keyDict) return NULL; + CFDataRef result = NULL; if(CFDictionaryGetCount(keyDict) == 1) { __block CFDataRef keyData = NULL; CFDictionaryForEach(keyDict, ^(const void *key, const void *value) { keyData = asData(value, NULL); }); - return CFDataCreateCopy(kCFAllocatorDefault, keyData); + result = CFDataCreateCopy(kCFAllocatorDefault, keyData); } CFReleaseNull(keyDict); - return NULL; + return result; } bool SOSBSKBHasRecoveryKey(SOSBackupSliceKeyBagRef bskb) { if(!bskb) return false; - if(SOSBSKBHasPrefixedKey(bskb, bskbRkbgPrefix)) return true; + if(SOSBSKBHasPrefixedKey(bskb, bskbRkbgPrefix)) { + return true; + } // old way for RecoveryKeys int keyCount = (bskb->wrapped_keys != NULL) ? (int) CFDictionaryGetCount(bskb->wrapped_keys): 0; int peerCount = SOSBSKBCountPeers(bskb); return !SOSBSKBIsDirect(bskb) && ((keyCount - peerCount) > 0); } +bool SOSBSKBHasThisRecoveryKey(SOSBackupSliceKeyBagRef bskb, CFDataRef backupKey) { + if(backupKey) { + CFStringRef id = SOSKeyedPubKeyIdentifierCreateWithData(bskbRkbgPrefix, backupKey); + bool result = (bskb && id && CFDictionaryContainsKey(bskb->wrapped_keys, id)); + CFReleaseNull(id); + return result; + } else { + return CFDictionaryGetCount(bskb->wrapped_keys) == SOSBSKBCountPeers(bskb); + } +} diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSChangeTracker.c b/keychain/SecureObjectSync/SOSChangeTracker.c similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSChangeTracker.c rename to keychain/SecureObjectSync/SOSChangeTracker.c index cda061ef..483fd2e1 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSChangeTracker.c +++ b/keychain/SecureObjectSync/SOSChangeTracker.c @@ -25,11 +25,11 @@ * SOSChangeTracker.c - Implementation of a manifest caching change tracker that forwards changes to children */ -#include -#include -#include -#include -#include +#import "keychain/SecureObjectSync/SOSChangeTracker.h" +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSEnginePriv.h" +#include "keychain/SecureObjectSync/SOSManifest.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSChangeTracker.h b/keychain/SecureObjectSync/SOSChangeTracker.h similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSChangeTracker.h rename to keychain/SecureObjectSync/SOSChangeTracker.h index f49302c9..0b68d4bc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSChangeTracker.h +++ b/keychain/SecureObjectSync/SOSChangeTracker.h @@ -29,7 +29,7 @@ #ifndef _SEC_SOSCHANGETRACKER_H_ #define _SEC_SOSCHANGETRACKER_H_ -#include +#include "keychain/SecureObjectSync/SOSDataSource.h" __BEGIN_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c b/keychain/SecureObjectSync/SOSCircle.c similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c rename to keychain/SecureObjectSync/SOSCircle.c index b715e1ef..cba4a3b6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.c +++ b/keychain/SecureObjectSync/SOSCircle.c @@ -29,15 +29,17 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSTypes.h" +#include "keychain/SecureObjectSync/SOSPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSCloudCircle.h" +#include "keychain/SecureObjectSync/SOSCloudCircleInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSEnginePriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSGenCount.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include #include @@ -48,7 +50,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSCirclePriv.h" //#include "ckdUtilities.h" @@ -1309,6 +1311,12 @@ void SOSCircleForEachValidSyncingPeer(SOSCircleRef circle, SecKeyRef user_public SOSCircleForEachValidPeer(circle, user_public_key, action); } +void SOSCircleForEachBackupCapablePeerForView(SOSCircleRef circle, SecKeyRef user_public_key, CFStringRef viewName, void (^action)(SOSPeerInfoRef peer)) { + SOSCircleForEachPeerMatching(circle, action, ^bool(SOSPeerInfoRef peer) { + return (!isHiddenPeer(peer) && SOSPeerInfoIsEnabledView(peer, viewName) && SOSPeerInfoHasBackupKey(peer) && SOSPeerInfoApplicationVerify(peer, user_public_key, NULL)); + }); +} + void SOSCircleForEachApplicant(SOSCircleRef circle, void (^action)(SOSPeerInfoRef peer)) { CFSetForEach(circle->applicants, ^(const void*value) { action((SOSPeerInfoRef) value); } ); } @@ -1374,6 +1382,19 @@ CFMutableSetRef SOSCircleCopyPeers(SOSCircleRef circle, CFAllocatorRef allocator return result; } + +CFMutableSetRef SOSCircleCopyBackupCapablePeersForView(SOSCircleRef circle, CFAllocatorRef allocator, SecKeyRef userPubKey, CFStringRef viewName) { + SOSCircleAssertStable(circle); + + CFMutableSetRef result = CFSetCreateMutableForSOSPeerInfosByID(allocator); + + SOSCircleForEachBackupCapablePeerForView(circle, userPubKey, viewName, ^(SOSPeerInfoRef peer) { + CFSetAddValue(result, peer); + }); + + return result; +} + bool SOSCircleAppendConcurringPeers(SOSCircleRef circle, CFMutableArrayRef appendHere, CFErrorRef *error) { SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) { CFErrorRef localError = NULL; @@ -1432,6 +1453,27 @@ SOSFullPeerInfoRef SOSCircleCopyiCloudFullPeerInfoRef(SOSCircleRef circle, CFErr return cloud_full_peer; } +SOSFullPeerInfoRef SOSCircleCopyiCloudFullPeerInfoVerifier(SOSCircleRef circle, CFErrorRef *error) { + __block CFErrorRef searchError = NULL; + __block SOSFullPeerInfoRef cloud_full_peer = NULL; + SOSCircleForEachActivePeer(circle, ^(SOSPeerInfoRef peer) { + // There should only ever be one signing iCloud identity. If there are more we'll take the first one. + if (!cloud_full_peer && SOSPeerInfoIsCloudIdentity(peer) && SOSCircleVerifyPeerSignatureExists(circle, peer)) { + cloud_full_peer = SOSFullPeerInfoCreateCloudIdentity(kCFAllocatorDefault, peer, &searchError); + } + }); + // If we didn't find one at all, report the error. + if (cloud_full_peer == NULL && searchError == NULL) { + SOSErrorCreate(kSOSErrorNoiCloudPeer, &searchError, NULL, CFSTR("No iCloud identity PeerInfo found in circle")); + secnotice("icloud-identity", "No iCloud identity PeerInfo found in circle"); + } + if (error) { + CFTransferRetained(*error, searchError); + } + CFReleaseNull(searchError); + return cloud_full_peer; +} + void debugDumpCircle(CFStringRef message, SOSCircleRef circle) { CFErrorRef error; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h b/keychain/SecureObjectSync/SOSCircle.h similarity index 93% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h rename to keychain/SecureObjectSync/SOSCircle.h index 4ef6fddd..a8c442a0 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircle.h +++ b/keychain/SecureObjectSync/SOSCircle.h @@ -32,12 +32,12 @@ #define _SOSCIRCLE_H_ #include -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSConcordanceTrust.h" +#include "keychain/SecureObjectSync/SOSGenCount.h" +#include "keychain/SecureObjectSync/SOSPiggyback.h" __BEGIN_DECLS @@ -96,6 +96,7 @@ int64_t SOSCircleGetGenerationSint(SOSCircleRef circle); void SOSCircleGenerationIncrement(SOSCircleRef circle); CFMutableSetRef SOSCircleCopyPeers(SOSCircleRef circle, CFAllocatorRef allocator); +CFMutableSetRef SOSCircleCopyBackupCapablePeersForView(SOSCircleRef circle, CFAllocatorRef allocator, SecKeyRef userPubKey, CFStringRef viewName); bool SOSCircleAppendConcurringPeers(SOSCircleRef circle, CFMutableArrayRef appendHere, CFErrorRef *error); CFMutableArrayRef SOSCircleCopyConcurringPeers(SOSCircleRef circle, CFErrorRef* error); SOSPeerInfoRef SOSCircleCopyPeerWithID(SOSCircleRef circle, CFStringRef peerid, CFErrorRef *error); @@ -114,6 +115,7 @@ void SOSCircleForEachActivePeer(SOSCircleRef circle, void (^action)(SOSPeerInfoR void SOSCircleForEachActiveValidPeer(SOSCircleRef circle, SecKeyRef user_public_key, void (^action)(SOSPeerInfoRef peer)); void SOSCircleForEachValidPeer(SOSCircleRef circle, SecKeyRef user_public_key, void (^action)(SOSPeerInfoRef peer)); void SOSCircleForEachValidSyncingPeer(SOSCircleRef circle, SecKeyRef user_public_key, void (^action)(SOSPeerInfoRef peer)); +void SOSCircleForEachBackupCapablePeerForView(SOSCircleRef circle, SecKeyRef user_public_key, CFStringRef viewName, void (^action)(SOSPeerInfoRef peer)); bool SOSCircleHasPeerWithID(SOSCircleRef circle, CFStringRef peerid, CFErrorRef *error); @@ -154,6 +156,7 @@ bool SOSCircleAcceptRequests(SOSCircleRef circle, SecKeyRef user_privkey, SOSFul // Stuff above this line is really SOSCircleInfo below the line is the active SOSCircle functionality CF_RETURNS_RETAINED SOSFullPeerInfoRef SOSCircleCopyiCloudFullPeerInfoRef(SOSCircleRef circle, CFErrorRef *error); +CF_RETURNS_RETAINED SOSFullPeerInfoRef SOSCircleCopyiCloudFullPeerInfoVerifier(SOSCircleRef circle, CFErrorRef *error); bool SOSCircleConcordanceSign(SOSCircleRef circle, SOSFullPeerInfoRef peerinfo, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.c b/keychain/SecureObjectSync/SOSCircleDer.c similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.c rename to keychain/SecureObjectSync/SOSCircleDer.c index 1985c876..b44e9287 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.c +++ b/keychain/SecureObjectSync/SOSCircleDer.c @@ -13,15 +13,15 @@ #include #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSCirclePriv.h" #include #include #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.h b/keychain/SecureObjectSync/SOSCircleDer.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircleDer.h rename to keychain/SecureObjectSync/SOSCircleDer.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCirclePriv.h b/keychain/SecureObjectSync/SOSCirclePriv.h similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCirclePriv.h rename to keychain/SecureObjectSync/SOSCirclePriv.h index b673a2cf..79852a34 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCirclePriv.h +++ b/keychain/SecureObjectSync/SOSCirclePriv.h @@ -11,7 +11,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSGenCount.h" enum { kOnlyCompatibleVersion = 1, // Sometime in the future this name will be improved to reflect history. diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleRings.h b/keychain/SecureObjectSync/SOSCircleRings.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircleRings.h rename to keychain/SecureObjectSync/SOSCircleRings.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleV2.c b/keychain/SecureObjectSync/SOSCircleV2.c similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircleV2.c rename to keychain/SecureObjectSync/SOSCircleV2.c diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCircleV2.h b/keychain/SecureObjectSync/SOSCircleV2.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCircleV2.h rename to keychain/SecureObjectSync/SOSCircleV2.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h b/keychain/SecureObjectSync/SOSCloudCircle.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h rename to keychain/SecureObjectSync/SOSCloudCircle.h index 99f58033..bb26d2db 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.h +++ b/keychain/SecureObjectSync/SOSCloudCircle.h @@ -61,6 +61,8 @@ enum { kSOSErrorIncompatibleCircle = 5, // We saw an incompatible circle out there. kSOSInitialSyncFailed = 6, //we timed out when syncing during approving from another device kSOSEntitlementMissing = 7, + + KSOSCantParseSOSMessage = 8, }; // @@ -628,6 +630,14 @@ bool SOSCCViewSetWithAnalytics(CFSetRef enabledviews, CFSetRef disabledviews, CF */ SOSPeerInfoRef SOSCCCopyMyPeerWithNewDeviceRecoverySecret(CFDataRef secret, CFErrorRef *error); +/*! + @function SOSCopyDeviceBackupPublicKey + @param entropy user provided entropy + @param error what, if anything, went wrong creating the backup key + @result returns the public key bytes which will be eventually generated by a call to SOSCCCopyMyPeerWithNewDeviceRecoverySecret. Note that this function does not change any state. + */ +CFDataRef SOSCopyDeviceBackupPublicKey(CFDataRef entropy, CFErrorRef *error); + /*! @function SOSCCRegisterSingleRecoverySecret @param aks_bag TODO @@ -740,8 +750,16 @@ void SOSCCAccountGetAccountPrivateCredential(void (^complete)(NSData *data, NSEr void SOSCCAccountGetKeyCircleGeneration(void (^reply)(NSData *data, NSError *error)); +void SOSCCGhostBust(SOSAccountGhostBustingOptions options, void (^complete)(bool ghostsBusted, NSError *error)); + +void SOSCCGhostBustTriggerTimed(SOSAccountGhostBustingOptions options, void (^complete)(bool ghostsBusted, NSError *error)); + +void SOSCCGhostBustInfo(void (^complete)(NSData *json, NSError *error)); + CFDataRef SOSCCCopyInitialSyncData(CFErrorRef *error); - + +NSString * SOSCCCircleHash(NSError **error); + #endif __END_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m b/keychain/SecureObjectSync/SOSCloudCircle.m similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m rename to keychain/SecureObjectSync/SOSCloudCircle.m index 266de197..4fe74fe0 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircle.m +++ b/keychain/SecureObjectSync/SOSCloudCircle.m @@ -30,17 +30,18 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSCloudCircle.h" +#include "keychain/SecureObjectSync/SOSCloudCircleInternal.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSRing.h" #include #include -#include +#include "keychain/SecureObjectSync/SOSControlHelper.h" +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" #include #include @@ -65,7 +66,6 @@ #include #include -#include "SOSPeerInfoDER.h" const char * kSOSCCCircleChangedNotification = "com.apple.security.secureobjectsync.circlechanged"; const char * kSOSCCViewMembershipChangedNotification = "com.apple.security.secureobjectsync.viewschanged"; @@ -88,7 +88,7 @@ SOSCCStatus SOSCCThisDeviceIsInCircle(CFErrorRef *error) { SOSCCStatus retval = SOSGetCachedCircleStatus(error); if(retval != kSOSNoCachedValue) { - secnotice("circleOps", "Retrieved cached circle value %d", retval); + secdebug("circleOps", "Retrieved cached circle value %d", retval); return retval; } return SOSCCThisDeviceIsInCircleNonCached(error); @@ -697,7 +697,6 @@ bool SOSCCRequestToJoinCircleAfterRestoreWithAnalytics(CFDataRef parentEvent, CF bool SOSCCAccountHasPublicKey(CFErrorRef *error) { - // murfxx sec_trace_enter_api(NULL); sec_trace_return_bool_api(^{ do_if_registered(soscc_AccountHasPublicKey, error); @@ -1125,6 +1124,8 @@ bool SOSCCForEachEngineStateAsString(CFErrorRef* error, void (^block)(CFStringRe SOSCCForEachEngineStateAsStringFromArray(states, block); + CFReleaseNull(states); + return true; } @@ -1445,14 +1446,6 @@ CFStringRef SOSCCGetStatusDescription(SOSCCStatus status) }; } -#if 0 - kSOSCCGeneralViewError = -1, - kSOSCCViewMember = 0, - kSOSCCViewNotMember = 1, - kSOSCCViewNotQualified = 2, - kSOSCCNoSuchView = 3, -#endif - CFStringRef SOSCCGetViewResultDescription(SOSViewResultCode vrc) { @@ -1584,7 +1577,6 @@ 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) { @@ -1757,8 +1749,6 @@ bool SOSCCJoinWithCircleJoiningBlob(CFDataRef joiningBlob, PiggyBackProtocolVers return cfdata_and_int_error_request_returns_bool(kSecXPCOpJoinWithCircleJoiningBlob, joiningBlob, version, error); }, NULL) - - return false; } bool SOSCCIsThisDeviceLastBackup(CFErrorRef *error) { @@ -1822,9 +1812,9 @@ bool SOSCCSendToPeerIsPending(SOSPeerInfoRef peer, CFErrorRef *error) { _SOSControlSetupInterface(interface); self.connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydSOSServiceName) options:0]; - if (self.connection == NULL) + if (self.connection == NULL){ return NULL; - + } self.connection.remoteObjectInterface = interface; [self.connection resume]; @@ -1848,6 +1838,33 @@ SOSCCGetStatusObject(CFErrorRef *error) return control.connection.remoteObjectProxy; } + +static id +SOSCCGetSynchronousStatusObject(CFErrorRef *cferror) { + if (gSecurityd && gSecurityd->soscc_status) + return (__bridge id)gSecurityd->soscc_status(); + + static SecSOSStatus *control; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + control = [[SecSOSStatus alloc] init]; + }); + + __block NSError *localError = nil; + id synchronousRemoteObject = [control.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *error) { + secnotice("ghostbust", "An error occurred on the xpc connection to setup the background session: %@", error ); + if(error) { + localError = error; + } + }]; + if(cferror && localError) { + *cferror = (__bridge CFErrorRef)(localError); + } + return synchronousRemoteObject; +} + + + void SOSCCAccountGetPublicKey(void (^reply)(BOOL trusted, NSData *data, NSError *error)) { @@ -1890,4 +1907,71 @@ SOSCCAccountGetKeyCircleGeneration(void (^reply)(NSData *data, NSError *error)) }); } +NSString * +SOSCCCircleHash(NSError **error) +{ + CFErrorRef cferror = NULL; + id status = SOSCCGetSynchronousStatusObject(&cferror); + if (status == NULL) { + if (error) { + *error = (__bridge NSError *)cferror; + } + CFReleaseNull(cferror); + return NULL; + } + __block NSString *hash = NULL; + [status circleHash:^(NSString *circleHash, NSError *error) { + hash = circleHash; + }]; + return hash; +} + + + +void +SOSCCGhostBust(SOSAccountGhostBustingOptions options, void (^complete)(bool ghostsBusted, NSError *error)) { + CFErrorRef error = NULL; + id status = SOSCCGetSynchronousStatusObject(&error); + if (status == NULL) { + complete(false, (__bridge NSError *)error); + CFReleaseNull(error); + return; + } + secnotice("ghostbust", "API Called"); + [status ghostBust:options complete:^(bool ghostBusted, NSError *error) { + secnotice("ghostbust", "API returned: %d", ghostBusted); + complete(ghostBusted, error); + }]; +} + +void SOSCCGhostBustTriggerTimed(SOSAccountGhostBustingOptions options, void (^complete)(bool ghostsBusted, NSError *error)) { + CFErrorRef error = NULL; + id status = SOSCCGetSynchronousStatusObject(&error); + if (status == NULL) { + complete(false, (__bridge NSError *)error); + CFReleaseNull(error); + return; + } + secnotice("ghostbust", "API Trigger Timed Called"); + [status ghostBustTriggerTimed:options complete:^(bool ghostBusted, NSError *error) { + secnotice("ghostbust", "API Trigger Timed returned: %d", ghostBusted); + complete(ghostBusted, error); + }]; +} + +void SOSCCGhostBustInfo(void (^complete)(NSData *json, NSError *error)) { + CFErrorRef error = NULL; + id status = SOSCCGetSynchronousStatusObject(&error); + if (status == NULL) { + complete(false, (__bridge NSError *)error); + CFReleaseNull(error); + return; + } + secnotice("ghostbust", "API Info Called"); + [status ghostBustInfo:^(NSData *json, NSError *error) { + secnotice("ghostbust", "API Info returned"); + complete(json, error); + }]; +} + diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h b/keychain/SecureObjectSync/SOSCloudCircleInternal.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCloudCircleInternal.h rename to keychain/SecureObjectSync/SOSCloudCircleInternal.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCoder.c b/keychain/SecureObjectSync/SOSCoder.c similarity index 99% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCoder.c rename to keychain/SecureObjectSync/SOSCoder.c index fbabbb4c..109cffae 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCoder.c +++ b/keychain/SecureObjectSync/SOSCoder.c @@ -30,11 +30,11 @@ #include #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSCoder.h" #include #include @@ -592,7 +592,6 @@ SOSCoderStatus SOSCoderUnwrap(SOSCoderRef coder, CFDataRef codedMessage, CFMutab if(!SecOTRSGetIsReadyForMessages(coder->sessRef)) { CFStringAppend(action, CFSTR("not ready for data; resending DH packet")); - SetCloudKeychainTraceValueForKey(kCloudKeychainNumberOfTimesSyncFailed, 1); SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.restartotrnegotiation"), 1); result = SOSCoderResendDH(coder, error); } else { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSCoder.h b/keychain/SecureObjectSync/SOSCoder.h similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSCoder.h rename to keychain/SecureObjectSync/SOSCoder.h index 862d398a..bc45e481 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSCoder.h +++ b/keychain/SecureObjectSync/SOSCoder.h @@ -26,7 +26,7 @@ #define _SEC_SOSCODER_H_ -#include +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" #include typedef struct __OpaqueSOSCoder *SOSCoderRef; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSConcordanceTrust.h b/keychain/SecureObjectSync/SOSConcordanceTrust.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSConcordanceTrust.h rename to keychain/SecureObjectSync/SOSConcordanceTrust.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlHelper.h b/keychain/SecureObjectSync/SOSControlHelper.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSControlHelper.h rename to keychain/SecureObjectSync/SOSControlHelper.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlHelper.m b/keychain/SecureObjectSync/SOSControlHelper.m similarity index 90% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSControlHelper.m rename to keychain/SecureObjectSync/SOSControlHelper.m index 4ff588d1..a8335cac 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlHelper.m +++ b/keychain/SecureObjectSync/SOSControlHelper.m @@ -23,10 +23,11 @@ #import #import -#import -#import #import +#import "keychain/SecureObjectSync/SOSTypes.h" +#import "keychain/SecureObjectSync/SOSControlHelper.h" + void _SOSControlSetupInterface(NSXPCInterface *interface) { @@ -56,6 +57,7 @@ _SOSControlSetupInterface(NSXPCInterface *interface) [interface setClasses:errClasses forSelector:@selector(stashAccountCredential:complete:) argumentIndex:1 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(myPeerInfo:) argumentIndex:1 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(circleHash:) argumentIndex:1 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(circleJoiningBlob:complete:) argumentIndex:1 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(joinCircleWithBlob:version:complete:) argumentIndex:1 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(initialSyncCredentials:complete:) argumentIndex:1 ofReply:YES]; @@ -63,4 +65,5 @@ _SOSControlSetupInterface(NSXPCInterface *interface) [interface setClasses:errClasses forSelector:@selector(triggerSync:complete:) argumentIndex:1 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(getWatchdogParameters:) argumentIndex:1 ofReply:YES]; [interface setClasses:errClasses forSelector:@selector(setWatchdogParmeters:complete:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(ghostBust:complete:) argumentIndex:1 ofReply:YES]; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.h b/keychain/SecureObjectSync/SOSControlServer.h similarity index 50% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.h rename to keychain/SecureObjectSync/SOSControlServer.h index e1c217af..48443184 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.h +++ b/keychain/SecureObjectSync/SOSControlServer.h @@ -3,4 +3,14 @@ void SOSControlServerInitialize(void); +#if __OBJC2__ +@interface SOSClient : NSObject +@end + +SOSClient * +SOSControlServerInternalClient(void); + +#endif + + #endif /* !_SOSCONTROLSERVER_H_ */ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m b/keychain/SecureObjectSync/SOSControlServer.m similarity index 70% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m rename to keychain/SecureObjectSync/SOSControlServer.m index c6e92c90..6412bad3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSControlServer.m +++ b/keychain/SecureObjectSync/SOSControlServer.m @@ -9,11 +9,15 @@ @interface SOSControlServer : NSObject @end -@interface SOSClient : NSObject -@property (weak) NSXPCConnection * connection; +@interface SOSClient () @property (strong) SOSAccount * account; +- (instancetype)initSOSClientWithAccount:(SOSAccount *)account; +- (bool)checkEntitlement:(NSString *)entitlement; +@end -- (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account; +@interface SOSClientRemote : SOSClient +@property (weak) NSXPCConnection * connection; +- (instancetype)initSOSConnectionWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account; @end @implementation SOSControlServer @@ -27,8 +31,7 @@ return NO; } - - SOSClient *sosClient = [[SOSClient alloc] initWithConnection:newConnection account:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()]; + SOSClientRemote *sosClient = [[SOSClientRemote alloc] initSOSConnectionWithConnection:newConnection account:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()]; newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(SOSControlProtocol)]; _SOSControlSetupInterface(newConnection.exportedInterface); @@ -39,17 +42,20 @@ return YES; } +- (SOSClient *)internalSOSClient +{ + return [[SOSClient alloc] initSOSClientWithAccount:(__bridge SOSAccount *)SOSKeychainAccountGetSharedAccount()]; +} + @end @implementation SOSClient @synthesize account = _account; -@synthesize connection = _connection; -- (instancetype)initWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account +- (instancetype)initSOSClientWithAccount:(SOSAccount *)account { if ((self = [super init])) { - _connection = connection; _account = account; } return self; @@ -57,14 +63,6 @@ - (bool)checkEntitlement:(NSString *)entitlement { - NSXPCConnection *strongConnection = _connection; - - NSNumber *num = [strongConnection valueForEntitlement:entitlement]; - if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { - secerror("sos: Client pid: %d doesn't have entitlement: %@", - [strongConnection processIdentifier], entitlement); - return false; - } return true; } @@ -108,6 +106,12 @@ [self.account myPeerInfo:complete]; } +- (void)circleHash:(void (^)(NSString *, NSError *))complete +{ + [self.account circleHash:complete]; +} + + - (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete { [self.account circleJoiningBlob:applicant complete:complete]; @@ -158,22 +162,71 @@ [self.account setWatchdogParmeters:parameters complete:complete]; } +- (void) ghostBust:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { + [self.account ghostBust:options complete:complete]; +} + +- (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete { + [self.account ghostBustTriggerTimed:options complete:complete]; +} + +- (void) ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete { + [self.account ghostBustPeriodic:options complete:complete]; +} + +- (void) ghostBustInfo: (void(^)(NSData *json, NSError *error))complete { + [self.account ghostBustInfo:complete]; +} + +@end + +@implementation SOSClientRemote + +- (instancetype)initSOSConnectionWithConnection:(NSXPCConnection *)connection account:(SOSAccount *)account +{ + self = [super initSOSClientWithAccount:account]; + if (self) { + self.connection = connection; + } + return self; +} + +- (bool)checkEntitlement:(NSString *)entitlement +{ + NSXPCConnection *strongConnection = _connection; + + NSNumber *num = [strongConnection valueForEntitlement:entitlement]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("sos: Client pid: %d doesn't have entitlement: %@", + [strongConnection processIdentifier], entitlement); + return false; + } + return true; +} @end +static SOSControlServer *sosServer; + void SOSControlServerInitialize(void) { static dispatch_once_t once; - static SOSControlServer *server; static NSXPCListener *listener; dispatch_once(&once, ^{ @autoreleasepool { - server = [SOSControlServer new]; + sosServer = [SOSControlServer new]; listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydSOSServiceName)]; - listener.delegate = server; + listener.delegate = sosServer; [listener resume]; } }); } + +SOSClient * +SOSControlServerInternalClient(void) +{ + SOSControlServerInitialize(); + return [sosServer internalSOSClient]; +} diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSDataSource.h b/keychain/SecureObjectSync/SOSDataSource.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSDataSource.h rename to keychain/SecureObjectSync/SOSDataSource.h index 84a34ce4..39099b58 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSDataSource.h +++ b/keychain/SecureObjectSync/SOSDataSource.h @@ -33,11 +33,11 @@ #ifndef _SEC_SOSDATASOURCE_H_ #define _SEC_SOSDATASOURCE_H_ -#include +#include "keychain/SecureObjectSync/SOSManifest.h" #include -#include -#include -#include +#include "utilities/array_size.h" +#include "utilities/SecCFRelease.h" +#include "utilities/SecCFError.h" __BEGIN_DECLS @@ -63,7 +63,7 @@ static inline CFStringRef SOSDataSourceFactoryCopyName(SOSDataSourceFactoryRef d } static inline SOSDataSourceRef SOSDataSourceFactoryCreateDataSource(SOSDataSourceFactoryRef dsf, CFStringRef dataSourceName, CFErrorRef *error) { - SecRequirementError(dsf != NULL, error, CFSTR("No datasource")); + (void)SecRequirementError(dsf != NULL, error, CFSTR("No datasource")); return dsf ? dsf->create_datasource(dsf, dataSourceName, error) : NULL; } @@ -106,7 +106,7 @@ typedef CFOptionFlags SOSDataSourceTransactionType; enum SOSDataSourceTransactionPhase { kSOSDataSourceTransactionDidRollback = 0, // A transaction just got rolled back kSOSDataSourceTransactionWillCommit, // A transaction is about to commit. - kSOSDataSourceTransactionDidCommit, // A transaction sucessfully committed. + kSOSDataSourceTransactionDidCommit, // A transaction successfully committed. }; typedef CFOptionFlags SOSDataSourceTransactionPhase; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c b/keychain/SecureObjectSync/SOSDigestVector.c similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c rename to keychain/SecureObjectSync/SOSDigestVector.c index b23b682c..c63e2125 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.c +++ b/keychain/SecureObjectSync/SOSDigestVector.c @@ -22,7 +22,7 @@ */ -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" #include #include #include @@ -41,18 +41,16 @@ static bool SOSDigestVectorEnsureCapacity(struct SOSDigestVector *dv, size_t cou return true; // Too big if (count > kMaxDVCapacity) { - secerror("Requesting too much space for digest vectors: %ld", count); + secnotice("manifest", "Requesting too much space for digest vectors: %ld", count); return false; } - size_t capacity = (dv->capacity + 16) * 3 / 2; - size_t digestSize = sizeof(*(dv->digest)); - if (capacity < count) - capacity = count; - dv->digest = reallocf(dv->digest, digestSize * capacity); + size_t capacity = MIN(count + 100, kMaxDVCapacity); + dv->digest = reallocf(dv->digest, SOSDigestSize * capacity); if (dv->digest == NULL) { dv->count = 0; - secerror("reallocf failed requesting space for digest vectors: %ld (bytes)", digestSize * capacity); + dv->capacity = 0; + secnotice("manifest", "reallocf failed requesting space for digest vectors: %ld (bytes)", SOSDigestSize * capacity); return false; } dv->capacity = capacity; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.h b/keychain/SecureObjectSync/SOSDigestVector.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSDigestVector.h rename to keychain/SecureObjectSync/SOSDigestVector.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSECWrapUnwrap.c b/keychain/SecureObjectSync/SOSECWrapUnwrap.c similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSECWrapUnwrap.c rename to keychain/SecureObjectSync/SOSECWrapUnwrap.c index 6b84d445..7aea444d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSECWrapUnwrap.c +++ b/keychain/SecureObjectSync/SOSECWrapUnwrap.c @@ -5,7 +5,7 @@ // Copyright (c) 2014 Apple Inc. All rights reserved. // -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c b/keychain/SecureObjectSync/SOSEngine.c similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c rename to keychain/SecureObjectSync/SOSEngine.c index fe1b18c4..00a09107 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.c +++ b/keychain/SecureObjectSync/SOSEngine.c @@ -26,14 +26,14 @@ * SOSEngine.c - Implementation of a secure object syncing engine */ -#include -#include -#include -#include -#include +#import "keychain/SecureObjectSync/SOSChangeTracker.h" +#include "keychain/SecureObjectSync/SOSEnginePriv.h" +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSBackupEvent.h" +#include "keychain/SecureObjectSync/SOSPersist.h" #include #include @@ -68,7 +68,7 @@ #include -#include +#include "keychain/SecureObjectSync/SOSEnsureBackup.h" // // MARK: SOSEngine The Keychain database with syncable keychain support. @@ -93,7 +93,7 @@ static CFStringRef kSOSEngineTraceDateKey = CFSTR("traceDate"); // MARK: Engine state v2 //---------------------------------------------------------------------------------------- -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static const CFIndex kCurrentEngineVersion = 2; #endif // Keychain/datasource items @@ -173,7 +173,7 @@ static bool SOSEngineSetPeers_locked(SOSEngineRef engine, SOSPeerMetaRef myPeerM static void SOSEngineApplyPeerState(SOSEngineRef engine, CFDictionaryRef peerStateMap); static void SOSEngineSynthesizePeerMetas(SOSEngineRef engine, CFMutableArrayRef trustedPeersMetas, CFMutableArrayRef untrustedPeers); static bool SOSEngineLoadCoders(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef *error); -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static bool SOSEngineDeleteV0State(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef *error); #endif @@ -386,7 +386,7 @@ CFMutableArrayRef SOSEngineCopyPersistedManifestArray(SOSEngineRef engine, CFDic return manifests; } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static CFDictionaryRef SOSEngineCopyEncodedManifestCache_locked(SOSEngineRef engine, CFErrorRef *error) { CFMutableDictionaryRef mfc = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); SOSEngineForEachPeer_locked(engine, ^(SOSPeerRef peer) { @@ -486,7 +486,7 @@ static bool SOSEngineGCPeerState_locked(SOSEngineRef engine, CFErrorRef *error) //exit: return ok; } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static CFMutableDictionaryRef SOSEngineCopyPeerState_locked(SOSEngineRef engine, CFErrorRef *error) { CFMutableDictionaryRef peerState = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); CFDictionaryForEach(engine->peerMap, ^(const void *key, const void *value) { @@ -558,14 +558,19 @@ static bool SOSEngineSaveCoders(SOSEngineRef engine, SOSTransactionRef txn, CFEr bool ok = true; if (engine->codersNeedSaving) { - CFDataRef derCoders = SOSEngineCopyCoders(engine, error); + CFErrorRef localError = NULL; + CFDataRef derCoders = SOSEngineCopyCoders(engine, &localError); ok = derCoders && SOSDataSourceSetStateWithKey(engine->dataSource, txn, kSOSEngineCoders, - kSOSEngineProtectionDomainClassA, derCoders, error); + kSOSEngineProtectionDomainClassA, derCoders, &localError); if (ok) { engine->codersNeedSaving = false; secnotice("coder", "saved coders: %@", engine->coders); + } else { + if(error) CFTransferRetained(*error, localError); + secnotice("coder", "failed to save coders: %@ (%@)", engine->coders, localError); } CFReleaseSafe(derCoders); + CFReleaseSafe(localError); } return ok; } @@ -574,7 +579,7 @@ static bool SOSEngineSaveCoders(SOSEngineRef engine, SOSTransactionRef txn, CFEr bool SOSTestEngineSaveCoders(CFTypeRef engine, SOSTransactionRef txn, CFErrorRef *error){ return SOSEngineSaveCoders((SOSEngineRef)engine, txn, error); } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static CFDictionaryRef SOSEngineCopyBasicState(SOSEngineRef engine, CFErrorRef *error) { // Create a version of the in-memory engine state for saving to disk @@ -625,7 +630,7 @@ static bool SOSEngineSave(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef // Don't save engine state from tests if (!engine->dataSource) return true; -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR return SOSEngineDoSave(engine, txn, error); #endif return true; @@ -786,7 +791,7 @@ xit: CFReleaseNull(codersDict); return ok; } -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static bool SOSEngineDeleteV0State(SOSEngineRef engine, SOSTransactionRef txn, CFErrorRef *error) { // SOSDataSourceDeleteStateWithKey(engine->dataSource, kSOSEngineState, kSOSEngineProtectionDomainClassD, txn, error); @@ -1197,7 +1202,7 @@ static bool SOSEngineUpdateChanges_locked(SOSEngineRef engine, SOSTransactionRef if (deleted) { bool someoneCares = SOSChangeMapperIngestChange(&cm, false, deleted); if (someoneCares) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.delete"), 1); #endif mappedItemChanged = true; @@ -1206,7 +1211,7 @@ static bool SOSEngineUpdateChanges_locked(SOSEngineRef engine, SOSTransactionRef if (inserted) { bool someoneCares = SOSChangeMapperIngestChange(&cm, true, inserted); if (someoneCares) { -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR if (deleted == NULL) { SecADAddValueForScalarKey(CFSTR("com.apple.security.sos.add"), 1); } else { @@ -1689,55 +1694,6 @@ static void SOSEngineSetBackupBag(SOSEngineRef engine, SOSObjectRef bagItem) { CFReleaseSafe(untrustedPeerMetas); } -#define SECONDS_PER_DAY (86400.0) - -#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) -#define TRACE_INTERVAL (7 * SECONDS_PER_DAY) -#elif (TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR) -#define TRACE_INTERVAL (1 * SECONDS_PER_DAY) -#endif - -#ifdef TRACE_INTERVAL -static void SOSEngineCloudKeychainTrace(SOSEngineRef engine, CFAbsoluteTime now) { - CFAssignRetained(engine->lastTraceDate, CFDateCreate(kCFAllocatorDefault, now)); - CFIndex num_peers = engine->peerIDs ? 1 + CFArrayGetCount(engine->peerIDs) : 1; - SOSManifestRef manifest = SOSEngineCopyManifestWithViewNameSet_locked(engine, SOSViewsGetV0ViewSet(), NULL); - if (!manifest) - manifest = SOSDataSourceCopyManifestWithViewNameSet(engine->dataSource, SOSViewsGetV0ViewSet(), NULL); - size_t num_items = SOSManifestGetCount(manifest); - CFReleaseSafe(manifest); - - struct _SecServerKeyStats genpStats = { }; - struct _SecServerKeyStats inetStats = { }; - struct _SecServerKeyStats keysStats = { }; - - _SecServerGetKeyStats(genp_class(), &genpStats); - _SecServerGetKeyStats(inet_class(), &inetStats); - _SecServerGetKeyStats(keys_class(), &keysStats); - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - CloudKeychainTrace(num_peers, num_items, &genpStats, &inetStats, &keysStats); - }); -} -#endif - -static void SOSEngineCloudKeychainTraceIfNeeded(SOSEngineRef engine) { -#ifdef TRACE_INTERVAL - if (!engine->myID) - return; - CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); - if (engine->lastTraceDate) { - CFAbsoluteTime lastTraceTime = CFDateGetAbsoluteTime(engine->lastTraceDate); - if ((now - lastTraceTime) >= TRACE_INTERVAL) { - SOSEngineCloudKeychainTrace(engine, now); - } - } else { - SOSEngineCloudKeychainTrace(engine, now); - } -#endif -} - - static bool SOSEngineCircleChanged_locked(SOSEngineRef engine, SOSPeerMetaRef myPeerMeta, CFArrayRef trustedPeers, CFArrayRef untrustedPeers) { // Sanity check params // SOSEngineCircleChanged_sanitycheck(engine, myPeerID, trustedPeers, untrustedPeers); @@ -1796,9 +1752,6 @@ SOSEngineRef SOSEngineCreate(SOSDataSourceRef dataSource, CFErrorRef *error) { if (!SOSEngineInit(engine, error)) { secerror("engine failed to initialze %@ giving up", error ? *error : NULL); } - } else { - // Successfully loaded engine state, let's trace if we haven't in a while - SOSEngineCloudKeychainTraceIfNeeded(engine); } SOSEngineSetNotifyPhaseBlock(engine); return engine; @@ -2947,7 +2900,7 @@ bool SOSEngineWithPeerID(SOSEngineRef engine, CFStringRef peerID, CFErrorRef *er result = SOSErrorCreate(kSOSErrorPeerNotFound, error, NULL, CFSTR("Engine has no peer for %@"), peerID); } else { bool saveState = false; - SOSCoderRef coder = SOSEngineGetCoderInTx_locked(engine, txn, peerID, NULL); + SOSCoderRef coder = SOSEngineGetCoderInTx_locked(engine, txn, peerID, error); with(peer, coder, engine->dataSource, txn, &saveState); CFReleaseSafe(peer); if (saveState) diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h b/keychain/SecureObjectSync/SOSEngine.h similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h rename to keychain/SecureObjectSync/SOSEngine.h index 755732be..ea598b8b 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEngine.h +++ b/keychain/SecureObjectSync/SOSEngine.h @@ -30,9 +30,9 @@ #ifndef _SEC_SOSENGINE_H_ #define _SEC_SOSENGINE_H_ -#include -#include -#include +#include "keychain/SecureObjectSync/SOSDataSource.h" +#include "keychain/SecureObjectSync/SOSMessage.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #include __BEGIN_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnginePriv.h b/keychain/SecureObjectSync/SOSEnginePriv.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSEnginePriv.h rename to keychain/SecureObjectSync/SOSEnginePriv.h index b8166650..bf383c0d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnginePriv.h +++ b/keychain/SecureObjectSync/SOSEnginePriv.h @@ -9,7 +9,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSEngine.h" /* SOSEngine implementation. */ struct __OpaqueSOSEngine { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.h b/keychain/SecureObjectSync/SOSEnsureBackup.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.h rename to keychain/SecureObjectSync/SOSEnsureBackup.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m b/keychain/SecureObjectSync/SOSEnsureBackup.m similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m rename to keychain/SecureObjectSync/SOSEnsureBackup.m index e9389196..51ff0a03 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSEnsureBackup.m +++ b/keychain/SecureObjectSync/SOSEnsureBackup.m @@ -28,7 +28,7 @@ #if OCTAGON #import "keychain/ckks/CKKSLockStateTracker.h" #import "keychain/ckks/NSOperationCategories.h" -#include +#include "keychain/SecureObjectSync/SOSAccount.h" static NSOperationQueue *backupOperationQueue; static CKKSLockStateTracker *lockStateTracker; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in b/keychain/SecureObjectSync/SOSExports.exp-in similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in rename to keychain/SecureObjectSync/SOSExports.exp-in index 0de67ba6..66d25d5e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSExports.exp-in +++ b/keychain/SecureObjectSync/SOSExports.exp-in @@ -108,12 +108,19 @@ _kSOSCCCircleOctagonKeysChangedNotification _SOSCCSetLastDepartureReason _SOSCCAccountSetToNew +_SOSCCGhostBust +_SOSCCGhostBustInfo +_SOSCCGhostBustTriggerTimed + +_SOSCCCircleHash + // // Peer Info interfaces for SPI // _SOSPeerInfoApplicationVerify _SOSPeerInfoCompareByID +_SOSPeerInfoCompareByApplicationDate _SOSPeerInfoCopyAsApplication _SOSPeerInfoCopyBackupKey _SOSPeerInfoCopyDeviceID @@ -132,7 +139,6 @@ _SOSPeerInfoCopyWithPing _SOSPeerInfoCopyWithReplacedEscrowRecords _SOSPeerInfoCopyWithViewsChange _SOSPeerInfoCopySerialNumber -_SOSPeerInfoCopyOSVersion _SOSPeerInfoCreate _SOSPeerInfoCreateCloudIdentity _SOSPeerInfoCreateCopy @@ -157,8 +163,6 @@ _SOSPeerInfoGetRetirementDate _SOSPeerInfoGetTypeID _SOSPeerInfoGetVersion _SOSPeerInfoHasBackupKey -_SOSPeerInfoHasOctagonEncryptionPubKey -_SOSPeerInfoHasOctagonSigningPubKey _SOSPeerInfoInspectRetirementTicket _SOSPeerInfoIsCloudIdentity _SOSPeerInfoIsEnabledView @@ -170,6 +174,7 @@ _SOSPeerInfoPeerIDEqual _SOSPeerInfoRetireRetirementTicket _SOSPeerInfoSetOctagonEncryptionKey _SOSPeerInfoSetOctagonSigningKey +_SOSPeerInfoSetOctagonKeys _SOSPeerInfoUpdateDigestWithDescription _SOSPeerInfoUpdateDigestWithPublicKeyBytes _SOSPeerInfoUpgradeSignatures @@ -177,7 +182,7 @@ _SOSPeerInfoVersionHasV2Data _SOSPeerInfoVersionIsCurrent _SOSPeerInfoViewStatus _SOSPeerInfoWithEnabledViewSet - +_SOSPeerInfoSetOctagonKeysInDescription _SOSFullPeerInfoCreate _SOSFullPeerInfoPromoteToApplication _SOSFullPeerInfoGetPeerInfo @@ -210,15 +215,15 @@ _SOSPeerInfoSetEncodeToArrayDER _SOSPeerInfoSetFindByID _SOSPeerInfoSetGetDEREncodedArraySize -_SecCreateCFErrorWithXPCObject -_SecCreateXPCObjectWithCFError - // // Backup Key Bag SPI // +_SOSRKNullKey _SOSBKSBKeyIsInKeyBag _SOSBKSBPrefixedKeyIsInKeyBag +_SOSBKSBPeerBackupKeyIsInKeyBag +_SOSBSKBAllPeersBackupKeysAreInKeyBag _SOSBSKBCopyAKSBag _SOSBSKBCopyEncoded _SOSBSKBCopyRecoveryKey @@ -243,6 +248,7 @@ _bskbRkbgPrefix _SOSWrapToBackupSliceKeyBagForView _SOSBSKBHasRecoveryKey +_SOSBSKBHasThisRecoveryKey // // View SPI @@ -274,7 +280,7 @@ _SOSViewsXlateAction // Preferred symbols for viewHints // -#include "Security/SecureObjectSync/SOSViews.exp-in" +#include "keychain/SecureObjectSync/SOSViews.exp-in" _kSecUseSyncBubbleKeychain @@ -344,9 +350,11 @@ _SOSCircleCopyConcurringPeers _SOSCircleCopyEncodedData _SOSCircleCopyPeerWithID _SOSCircleCopyPeers +_SOSCircleCopyBackupCapablePeersForView _SOSCircleCopyRejectedApplicant _SOSCircleCopyRejectedApplicants _SOSCircleCopyiCloudFullPeerInfoRef +_SOSCircleCopyiCloudFullPeerInfoVerifier _SOSCircleCountActivePeers _SOSCircleCountActiveValidPeers _SOSCircleCountApplicants @@ -364,6 +372,7 @@ _SOSCircleForEachPeer _SOSCircleForEachRetiredPeer _SOSCircleForEachValidPeer _SOSCircleForEachValidSyncingPeer +_SOSCircleForEachBackupCapablePeerForView _SOSCircleForEachiCloudIdentityPeer _SOSCircleGenerationSign _SOSCircleGetDEREncodedSize @@ -421,7 +430,6 @@ _SOSFullPeerInfoCreateFromData _SOSFullPeerInfoCreateWithViews _SOSFullPeerInfoEncodeToDER _SOSFullPeerInfoGetDEREncodedSize -_SOSFullPeerInfoHaveOctagonKeys _SOSFullPeerInfoPing _SOSFullPeerInfoPrivKeyExists _SOSFullPeerInfoPromoteToRetiredAndCopy @@ -430,6 +438,7 @@ _SOSFullPeerInfoReplaceEscrowRecords _SOSFullPeerInfoUpdateBackupKey _SOSFullPeerInfoUpdateGestalt _SOSFullPeerInfoUpdateOctagonEncryptionKey +_SOSFullPeerInfoUpdateOctagonKeys _SOSFullPeerInfoUpdateOctagonSigningKey _SOSFullPeerInfoUpdateToCurrent _SOSFullPeerInfoUpdateToThisPeer @@ -443,6 +452,7 @@ _SOSPiggyBackBlobCreateFromDER _SOSPiggyBackBlobCreateFromData _SOSPiggyBackBlobCopyEncodedData _SOSPiggyBackAddToKeychain +_SOSPiggyCopyInitialSyncData _SOSCloudKeychainClearAll _SOSCloudKeychainGetAllObjectsFromCloud @@ -455,7 +465,6 @@ _SOSCloudCopyKVSState _SOSCloudKeychainFlush _SOSCloudKeychainHandleUpdateMessage _SOSCloudKeychainHasPendingKey -_SOSCloudKeychainHasPendingSyncWithPeer _SOSCloudKeychainRequestEnsurePeerRegistration _SOSCloudKeychainRequestPerfCounters _SOSCloudKeychainRequestSyncWithPeers @@ -484,7 +493,6 @@ _SOSRingKeyCreateWithRingName _kSOSKVSKeyParametersKey _sCirclePrefix _sDebugInfoPrefix -_sLastKeyParametersPushedPrefix _sRetirementPrefix @@ -520,8 +528,6 @@ _SOSPeerGestaltGetAnswer _SOSPeerGestaltGetName _SOSPeerGetGestalt -_SecCreateCFErrorWithXPCObject -_SecCreateXPCObjectWithCFError _CreateXPCObjectWithCFSetRef _kSOSErrorDomain @@ -562,6 +568,7 @@ _SOSPeerInfoPackV2Data _SOSPeerInfoSerialNumberIsSet _SOSPeerInfoSetSerialNumber _SOSPeerInfoSetTestSerialNumber +_SOSPeerInfoSign _SOSPeerInfoUpdateToV2 _SOSPeerInfoV2DictionaryCopyDictionary _SOSPeerInfoV2DictionaryForEachSetValue @@ -591,6 +598,7 @@ _SOSGetCachedCircleStatus _SOSCreateCachedViewStatus _SOSCachedViewBitmask _SOSGetCachedCircleBitmask +_SOSViewBitmaskFromSet _SOSPeerInfoViewBitMask _SOSViewCreateSetFromBitmask @@ -607,10 +615,4 @@ _SOSGestaltSerial __SOSControlSetupInterface - -#if !(TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) - -// Symbols only for embedded, typically for tests -_SOSCCGetOperationDescription - -#endif +_SOSCreateRandomDateBetweenNowPlus diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h b/keychain/SecureObjectSync/SOSFullPeerInfo.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h rename to keychain/SecureObjectSync/SOSFullPeerInfo.h index 83cdfcdf..2d265c6e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.h +++ b/keychain/SecureObjectSync/SOSFullPeerInfo.h @@ -63,7 +63,6 @@ SecKeyRef SOSFullPeerInfoCopyOctagonPublicSigningKey(SOSFullPeerInfoRef fullPeer SecKeyRef SOSFullPeerInfoCopyOctagonPublicEncryptionKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error); SecKeyRef SOSFullPeerInfoCopyOctagonSigningKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error); SecKeyRef SOSFullPeerInfoCopyOctagonEncryptionKey(SOSFullPeerInfoRef fullPeer, CFErrorRef* error); -bool SOSFullPeerInfoHaveOctagonKeys(SOSFullPeerInfoRef fullPeer); bool SOSFullPeerInfoPurgePersistentKey(SOSFullPeerInfoRef peer, CFErrorRef* error); @@ -111,6 +110,7 @@ CFDataRef SOSFullPeerInfoCopyEncodedData(SOSFullPeerInfoRef peer, CFAllocatorRef bool SOSFullPeerInfoUpdateOctagonSigningKey(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, CFErrorRef* error); bool SOSFullPeerInfoUpdateOctagonEncryptionKey(SOSFullPeerInfoRef peer, SecKeyRef octagonEncryptionKey, CFErrorRef* error); +bool SOSFullPeerInfoUpdateOctagonKeys(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, SecKeyRef octagonEncryptionKey, CFErrorRef* error); CFDataRef SOSPeerInfoCopyData(SOSPeerInfoRef fpi, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m b/keychain/SecureObjectSync/SOSFullPeerInfo.m similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m rename to keychain/SecureObjectSync/SOSFullPeerInfo.m index 30bf5d7d..d14f20e9 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSFullPeerInfo.m +++ b/keychain/SecureObjectSync/SOSFullPeerInfo.m @@ -24,15 +24,14 @@ #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" -#include +#include "keychain/SecureObjectSync/SOSCircle.h" -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -182,6 +181,12 @@ errOut: return retval; } +bool SOSFullPeerInfoUpdateOctagonKeys(SOSFullPeerInfoRef peer, SecKeyRef octagonSigningKey, SecKeyRef octagonEncryptionKey, CFErrorRef* error){ + return SOSFullPeerInfoUpdate(peer, error, ^SOSPeerInfoRef(SOSPeerInfoRef peer, SecKeyRef key, CFErrorRef *error) { + return SOSPeerInfoSetOctagonKeys(kCFAllocatorDefault, peer, octagonSigningKey, octagonEncryptionKey, 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); @@ -474,7 +479,6 @@ SecKeyRef SOSFullPeerInfoCopyOctagonPublicSigningKey(SOSFullPeerInfoRef fpi, CFE SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fpi); require_quiet(pi, errOut); retval = SOSPeerInfoCopyOctagonSigningPublicKey(pi, error); - errOut: return retval; } @@ -505,7 +509,7 @@ exit: static SecKeyRef SOSFullPeerInfoCopyMatchingOctagonSigningPrivateKey(SOSFullPeerInfoRef fpi, CFErrorRef* error) { - SecKeyRef retval = NULL; + SecKeyRef retval = NULL; SecKeyRef pub = SOSFullPeerInfoCopyOctagonPublicSigningKey(fpi, error); require_quiet(pub, exit); retval = SecKeyCopyMatchingPrivateKey(pub, error); @@ -616,18 +620,6 @@ SecKeyRef SOSFullPeerInfoCopyOctagonEncryptionKey(SOSFullPeerInfoRef fullPeer, C return SOSFullPeerInfoCopyMatchingOctagonEncryptionPrivateKey(fullPeer, error); } -bool SOSFullPeerInfoHaveOctagonKeys(SOSFullPeerInfoRef fullPeer) -{ - SOSPeerInfoRef pi = SOSFullPeerInfoGetPeerInfo(fullPeer); - if (pi == NULL) { - return false; - } - - return - SOSPeerInfoHasOctagonSigningPubKey(pi) && - SOSPeerInfoHasOctagonEncryptionPubKey(pi); -} - // // MARK: Encode and decode diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.c b/keychain/SecureObjectSync/SOSGenCount.c similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.c rename to keychain/SecureObjectSync/SOSGenCount.c diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.h b/keychain/SecureObjectSync/SOSGenCount.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSGenCount.h rename to keychain/SecureObjectSync/SOSGenCount.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h b/keychain/SecureObjectSync/SOSInternal.h similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h rename to keychain/SecureObjectSync/SOSInternal.h index 77249c8d..0460de82 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.h +++ b/keychain/SecureObjectSync/SOSInternal.h @@ -29,6 +29,8 @@ #include +#include + #include #include @@ -79,6 +81,7 @@ enum { kSOSErrorNoiCloudPeer = 1044, kSOSErrorParam = 1045, kSOSErrorNotInCircle = 1046, + kSOSErrorKeysNeedAttention = 1047, }; extern const CFStringRef SOSTransportMessageTypeIDSV2; @@ -119,7 +122,6 @@ ccec_const_cp_t SOSGetBackupKeyCurveParameters(void); bool SOSGenerateDeviceBackupFullKey(ccec_full_ctx_t generatedKey, ccec_const_cp_t cp, CFDataRef entropy, CFErrorRef* error); bool SOSPerformWithDeviceBackupFullKey(ccec_const_cp_t cp, CFDataRef entropy, CFErrorRef *error, void (^operation)(ccec_full_ctx_t fullKey)); -CFDataRef SOSCopyDeviceBackupPublicKey(CFDataRef entropy, CFErrorRef *error); // // Wrapping and Unwrapping @@ -147,6 +149,7 @@ CFStringRef SOSCopyIDOfKeyWithLength(SecKeyRef key, CFIndex len, CFErrorRef *err // // Der encoding accumulation // +OS_WARN_RESULT static inline bool accumulate_size(size_t *accumulator, size_t size) { *accumulator += size; return size != 0; @@ -172,6 +175,10 @@ SOSCCStatus SOSGetCachedCircleStatus(CFErrorRef *error); uint64_t SOSCachedViewBitmask(void); CFSetRef SOSCreateCachedViewStatus(void); +#if __OBJC__ +NSDate *SOSCreateRandomDateBetweenNowPlus(NSTimeInterval starting, NSTimeInterval ending); +#endif + __END_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m b/keychain/SecureObjectSync/SOSInternal.m similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m rename to keychain/SecureObjectSync/SOSInternal.m index f3222236..0506af6f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSInternal.m +++ b/keychain/SecureObjectSync/SOSInternal.m @@ -22,10 +22,10 @@ */ -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include "utilities/SecCFError.h" #include "utilities/SecCFRelease.h" @@ -429,3 +429,14 @@ CFSetRef SOSCreateCachedViewStatus(void) { return retval; } + +NSDate *SOSCreateRandomDateBetweenNowPlus(NSTimeInterval starting, NSTimeInterval ending) { + uint64_t randomTime; + uint64_t span = ending - starting; + NSTimeInterval resultInterval = (span/2) + starting; // fallback in case call below fails. + if(SecRandomCopyBytes(NULL, sizeof(randomTime), &randomTime) == 0) { + resultInterval = (randomTime % span) + starting; + } + return [[NSDate alloc] initWithTimeIntervalSinceNow:resultInterval]; +} + diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h b/keychain/SecureObjectSync/SOSKVSKeys.h similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h rename to keychain/SecureObjectSync/SOSKVSKeys.h index c0783bb5..84afb8c9 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.h +++ b/keychain/SecureObjectSync/SOSKVSKeys.h @@ -3,9 +3,9 @@ #ifndef SOSKVSKEYS_H #define SOSKVSKEYS_H -#include -#include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" // // MARK: Key formation // diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m b/keychain/SecureObjectSync/SOSKVSKeys.m similarity index 99% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m rename to keychain/SecureObjectSync/SOSKVSKeys.m index 155c73dc..af93d07c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKVSKeys.m +++ b/keychain/SecureObjectSync/SOSKVSKeys.m @@ -21,9 +21,9 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" #include void AppendCircleKeyName(CFMutableArrayRef array, CFStringRef name) { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKeyedPubKeyIdentifier.c b/keychain/SecureObjectSync/SOSKeyedPubKeyIdentifier.c similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSKeyedPubKeyIdentifier.c rename to keychain/SecureObjectSync/SOSKeyedPubKeyIdentifier.c index 8dd71be1..f3e018a6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSKeyedPubKeyIdentifier.c +++ b/keychain/SecureObjectSync/SOSKeyedPubKeyIdentifier.c @@ -28,7 +28,7 @@ #include "SOSKeyedPubKeyIdentifier.h" #include "AssertMacros.h" -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #define SEPARATOR CFSTR("-") diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSKeyedPubKeyIdentifier.h b/keychain/SecureObjectSync/SOSKeyedPubKeyIdentifier.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSKeyedPubKeyIdentifier.h rename to keychain/SecureObjectSync/SOSKeyedPubKeyIdentifier.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSManifest.c b/keychain/SecureObjectSync/SOSManifest.c similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSManifest.c rename to keychain/SecureObjectSync/SOSManifest.c index e1e79650..92b85f6c 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSManifest.c +++ b/keychain/SecureObjectSync/SOSManifest.c @@ -26,8 +26,8 @@ * SOSManifest.c - Manifest object and some manipulation around it */ -#include -#include +#include "keychain/SecureObjectSync/SOSManifest.h" +#include "keychain/SecureObjectSync/SOSDigestVector.h" #include #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSManifest.h b/keychain/SecureObjectSync/SOSManifest.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSManifest.h rename to keychain/SecureObjectSync/SOSManifest.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c b/keychain/SecureObjectSync/SOSMessage.c similarity index 99% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c rename to keychain/SecureObjectSync/SOSMessage.c index 4bc308db..cc9cfe13 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.c +++ b/keychain/SecureObjectSync/SOSMessage.c @@ -26,13 +26,13 @@ * SOSMessage.c - Creation and decoding of SOSMessage objects. */ -#include +#include "keychain/SecureObjectSync/SOSMessage.h" #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSManifest.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.h b/keychain/SecureObjectSync/SOSMessage.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.h rename to keychain/SecureObjectSync/SOSMessage.h index c3ad5195..e8bec1a7 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSMessage.h +++ b/keychain/SecureObjectSync/SOSMessage.h @@ -32,8 +32,8 @@ #ifndef _SEC_SOSMESSAGE_H_ #define _SEC_SOSMESSAGE_H_ -#include -#include +#include "keychain/SecureObjectSync/SOSDataSource.h" +#include "keychain/SecureObjectSync/SOSManifest.h" __BEGIN_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.h b/keychain/SecureObjectSync/SOSPeer.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.h rename to keychain/SecureObjectSync/SOSPeer.h index 3771023f..c1315968 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.h +++ b/keychain/SecureObjectSync/SOSPeer.h @@ -31,9 +31,9 @@ #ifndef _SOSPEER_H_ #define _SOSPEER_H_ -#include -#include // For SOSEngineRef -#include // TODO: Layer violation -> move to datasource or make schema based +#include "keychain/SecureObjectSync/SOSCoder.h" +#include "keychain/SecureObjectSync/SOSDataSource.h" // For SOSEngineRef +#include "utilities/SecAKSWrappers.h" // TODO: Layer violation -> move to datasource or make schema based __BEGIN_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m b/keychain/SecureObjectSync/SOSPeer.m similarity index 99% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m rename to keychain/SecureObjectSync/SOSPeer.m index 8c01228d..6b35c782 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeer.m +++ b/keychain/SecureObjectSync/SOSPeer.m @@ -25,14 +25,14 @@ /* * SOSPeer.c - Implementation of a secure object syncing peer */ -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeer.h" +#import "keychain/SecureObjectSync/SOSPeerRateLimiter.h" +#include "keychain/SecureObjectSync/SOSDigestVector.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSEngine.h" #include -#include +#import "keychain/SecureObjectSync/SOSChangeTracker.h" #include #include #include @@ -41,7 +41,7 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSBackupEvent.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h b/keychain/SecureObjectSync/SOSPeerCoder.h similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h rename to keychain/SecureObjectSync/SOSPeerCoder.h index 302b117f..6b008c92 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.h +++ b/keychain/SecureObjectSync/SOSPeerCoder.h @@ -24,9 +24,9 @@ #ifndef SOSPeerCoder_h #define SOSPeerCoder_h -#include -#include -#include +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSCoder.h" +#include "keychain/SecureObjectSync/SOSEngine.h" enum SOSCoderUnwrapStatus{ SOSCoderUnwrapError = 0, SOSCoderUnwrapDecoded = 1, diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m b/keychain/SecureObjectSync/SOSPeerCoder.m similarity index 86% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m rename to keychain/SecureObjectSync/SOSPeerCoder.m index 863ec788..2469a0de 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerCoder.m +++ b/keychain/SecureObjectSync/SOSPeerCoder.m @@ -21,24 +21,24 @@ * @APPLE_LICENSE_HEADER_END@ */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerCoder.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSCoder.h" +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSDataSource.h" +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSPeerOTRTimer.h" -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include #include #include -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" enum SOSCoderUnwrapStatus SOSPeerHandleCoderMessage(SOSPeerRef peer, SOSCoderRef coder, CFStringRef peer_id, CFDataRef codedMessage, CFDataRef *decodedMessage, bool *forceSave, CFErrorRef *error) { @@ -95,6 +95,7 @@ enum SOSCoderUnwrapStatus SOSPeerHandleCoderMessage(SOSPeerRef peer, SOSCoderRef } break; default: + secnotice("engine", "%@ engine unknown coder state: %d", peer_id, (int)coderStatus); assert(false); break; } @@ -109,8 +110,12 @@ xit: } bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, SOSTransactionRef txn, SOSPeerRef peer, SOSCoderRef coder, CFDataRef *message_to_send, CFStringRef peer_id, CFMutableArrayRef *attributeList, SOSEnginePeerMessageSentCallback **sentCallback, CFErrorRef *error) { bool ok = false; + + if(!coder) { + account.engine_peer_state_needs_repair = true; + } + require_action_quiet(coder, xit, secnotice("transport", "%@ getCoder: %@", peer_id, error ? *error : NULL)); secnotice("transport", "coder state: %@", coder); - require_action_quiet(coder, xit, secerror("%@ getCoder: %@", peer_id, error ? *error : NULL)); if (SOSCoderCanWrap(coder)) { secinfo("transport", "%@ Coder can wrap, getting message from engine", peer_id); @@ -153,7 +158,8 @@ bool SOSPeerCoderSendMessageIfNeeded(SOSAccount* account, SOSEngineRef engine, S ok = true; } /*if coder state is in awaiting for message, then set a timer and restart if failure*/ - if(*message_to_send != NULL && account.isInitialSyncing && !SOSPeerOTRTimerHaveReachedMaxRetryAllowance(account, (__bridge NSString*)peer_id)){ + BOOL initialSync = !SOSAccountHasCompletedInitialSync(account); + if(*message_to_send != NULL && initialSync && !SOSPeerOTRTimerHaveReachedMaxRetryAllowance(account, (__bridge NSString*)peer_id)){ if(SOSCoderIsCoderInAwaitingState(coder) && !SOSPeerTimerForPeerExist(peer) && SOSPeerOTRTimerHaveAnRTTAvailable(account, (__bridge NSString*)peer_id)){ secnotice("otrtimer", "coder is in awaiting state"); SOSPeerOTRTimerSetupAwaitingTimer(account, peer, engine, coder); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h b/keychain/SecureObjectSync/SOSPeerInfo.h similarity index 91% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h rename to keychain/SecureObjectSync/SOSPeerInfo.h index 05d6cd87..25389178 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.h +++ b/keychain/SecureObjectSync/SOSPeerInfo.h @@ -94,25 +94,10 @@ bool SOSPeerInfoUpdateDigestWithPublicKeyBytes(SOSPeerInfoRef peer, const struct bool SOSPeerInfoUpdateDigestWithDescription(SOSPeerInfoRef peer, const struct ccdigest_info *di, ccdigest_ctx_t ctx, CFErrorRef *error); - bool SOSPeerInfoApplicationVerify(SOSPeerInfoRef pi, SecKeyRef userkey, CFErrorRef *error); CF_RETURNS_RETAINED CFDateRef SOSPeerInfoGetApplicationDate(SOSPeerInfoRef pi); -// -// DER Import Export -// -SOSPeerInfoRef SOSPeerInfoCreateFromDER(CFAllocatorRef allocator, CFErrorRef* error, - const uint8_t** der_p, const uint8_t *der_end); - -SOSPeerInfoRef SOSPeerInfoCreateFromData(CFAllocatorRef allocator, CFErrorRef* error, - CFDataRef peerinfo_data); - -size_t SOSPeerInfoGetDEREncodedSize(SOSPeerInfoRef peer, CFErrorRef *error); -uint8_t* SOSPeerInfoEncodeToDER(SOSPeerInfoRef peer, CFErrorRef* error, - const uint8_t* der, uint8_t* der_end); - -CFDataRef SOSPeerInfoCopyEncodedData(SOSPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error); // // Transfered Data @@ -170,12 +155,12 @@ CFTypeRef SOSPeerGestaltGetAnswer(CFDictionaryRef gestalt, CFStringRef question) SecKeyRef SOSPeerInfoCopyPubKey(SOSPeerInfoRef peer, CFErrorRef *error); SecKeyRef SOSPeerInfoCopyOctagonSigningPublicKey(SOSPeerInfoRef peer, CFErrorRef* error); SecKeyRef SOSPeerInfoCopyOctagonEncryptionPublicKey(SOSPeerInfoRef peer, CFErrorRef* error); -bool SOSPeerInfoHasOctagonSigningPubKey(SOSPeerInfoRef peer); -bool SOSPeerInfoHasOctagonEncryptionPubKey(SOSPeerInfoRef peer); - +void SOSPeerInfoSetOctagonKeysInDescription(SOSPeerInfoRef peer, SecKeyRef octagonSigningKey, + SecKeyRef octagonEncryptionKey, CFErrorRef *error); CFDataRef SOSPeerInfoGetAutoAcceptInfo(SOSPeerInfoRef peer); CFComparisonResult SOSPeerInfoCompareByID(const void *val1, const void *val2, void *context); +CFComparisonResult SOSPeerInfoCompareByApplicationDate(const void *val1, const void *val2, void *context); SOSPeerInfoRef SOSPeerInfoCreateRetirementTicket(CFAllocatorRef allocator, SecKeyRef privKey, SOSPeerInfoRef peer, CFErrorRef *error); @@ -197,6 +182,7 @@ CFSetRef SOSPeerInfoGetPermittedViews(SOSPeerInfoRef peer); bool SOSPeerInfoIsEnabledView(SOSPeerInfoRef peer, CFStringRef viewName); CFMutableSetRef SOSPeerInfoCopyEnabledViews(SOSPeerInfoRef peer); void SOSPeerInfoWithEnabledViewSet(SOSPeerInfoRef pi, void (^operation)(CFSetRef enabled)); +uint64_t SOSViewBitmaskFromSet(CFSetRef views); uint64_t SOSPeerInfoViewBitMask(SOSPeerInfoRef pi); bool SOSPeerInfoKVSOnly(SOSPeerInfoRef pi); @@ -218,9 +204,15 @@ SOSPeerInfoSetOctagonEncryptionKey(CFAllocatorRef allocator, SecKeyRef signingKey, CFErrorRef *error); +SOSPeerInfoRef CF_RETURNS_RETAINED +SOSPeerInfoSetOctagonKeys(CFAllocatorRef allocator, + SOSPeerInfoRef toCopy, + SecKeyRef octagonSigningKey, + SecKeyRef octagonEncryptionKey, + SecKeyRef signingKey, + CFErrorRef *error); CFStringRef SOSPeerInfoCopySerialNumber(SOSPeerInfoRef pi); -CFStringRef SOSPeerInfoCopyOSVersion(SOSPeerInfoRef pi); void SOSPeerInfoLogState(char *category, SOSPeerInfoRef pi, SecKeyRef pubKey, CFStringRef myPID, char sigchr); @@ -236,6 +228,8 @@ typedef uint32_t SOSPeerInfoDeviceClass; SOSPeerInfoDeviceClass SOSPeerInfoGetClass(SOSPeerInfoRef pi); +bool SOSPeerInfoSign(SecKeyRef privKey, SOSPeerInfoRef peer, CFErrorRef *error); + __END_DECLS #endif diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m b/keychain/SecureObjectSync/SOSPeerInfo.m similarity index 88% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m rename to keychain/SecureObjectSync/SOSPeerInfo.m index ea95f3c2..f75c3321 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfo.m +++ b/keychain/SecureObjectSync/SOSPeerInfo.m @@ -26,11 +26,11 @@ #include #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSCircle.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -58,7 +58,7 @@ #include -#if TARGET_OS_IPHONE || TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE #include #endif @@ -593,6 +593,30 @@ CFComparisonResult SOSPeerInfoCompareByID(const void *val1, const void *val2, vo return CFStringCompare(v1, v2, 0); } + +CFComparisonResult SOSPeerInfoCompareByApplicationDate(const void *val1, const void *val2, void *context) { + // The code below is necessary but not sufficient; not returning a CFComparisonResult + // It probably is OK to say that a NULL is < + if (val1 == NULL || val2 == NULL) { + ptrdiff_t dv = val1 - val2; + return dv < 0 ? kCFCompareLessThan : dv == 0 ? kCFCompareEqualTo : kCFCompareGreaterThan; + } + + CFDateRef v1 = SOSPeerInfoGetApplicationDate((SOSPeerInfoRef) val1); + CFDateRef v2 = SOSPeerInfoGetApplicationDate((SOSPeerInfoRef) val2); + if (v1 == NULL || v2 == NULL) { + ptrdiff_t dv = (const void *)v1 - (const void *)v2; + CFReleaseNull(v1); + CFReleaseNull(v2); + return dv < 0 ? kCFCompareLessThan : dv == 0 ? kCFCompareEqualTo : kCFCompareGreaterThan; + } + + CFComparisonResult retval = CFDateCompare(v1, v2, 0); + CFReleaseNull(v1); + CFReleaseNull(v2); + return retval; +} + static CFHashCode SOSPeerInfoHash(CFTypeRef cf) { SOSPeerInfoRef peer = (SOSPeerInfoRef) cf; @@ -967,13 +991,20 @@ bool SOSPeerInfoRetireRetirementTicket(size_t max_seconds, SOSPeerInfoRef pi) { return false; } +static const void *SOSGetDescriptionValue(SOSPeerInfoRef pi, const void *key) { + if(pi && pi->description) { + return CFDictionaryGetValue(pi->description, key); + } + return NULL; +} + bool SOSPeerInfoIsRetirementTicket(SOSPeerInfoRef pi) { - CFDataRef flag = CFDictionaryGetValue(pi->description, sRetirementDate); + CFDataRef flag = SOSGetDescriptionValue(pi, sRetirementDate); return flag != NULL; } bool SOSPeerInfoIsCloudIdentity(SOSPeerInfoRef pi) { - CFTypeRef value = CFDictionaryGetValue(pi->description, sCloudIdentityKey); + CFTypeRef value = SOSGetDescriptionValue(pi, sCloudIdentityKey); return CFEqualSafe(value, kCFBooleanTrue); } @@ -986,6 +1017,78 @@ SOSPeerInfoRef SOSPeerInfoUpgradeSignatures(CFAllocatorRef allocator, SecKeyRef return retval; } +void SOSPeerInfoSetOctagonKeysInDescription(SOSPeerInfoRef peer, SecKeyRef octagonSigningKey, + SecKeyRef octagonEncryptionKey, CFErrorRef *error) +{ + CFDataRef signingPublicKeyBytes = NULL; + CFDataRef encryptionPublicKeyBytes = NULL; + + OSStatus copySigningKeyResult = SecKeyCopyPublicBytes(octagonSigningKey, &signingPublicKeyBytes); + OSStatus copyEncryptionKeyResult = SecKeyCopyPublicBytes(octagonEncryptionKey, &encryptionPublicKeyBytes); + + require_action_quiet(errSecSuccess == copySigningKeyResult, fail, SecError(copySigningKeyResult, error, CFSTR("failed to copy signing public key bytes"))); + require_action_quiet(errSecSuccess == copyEncryptionKeyResult, fail, SecError(copyEncryptionKeyResult, error, CFSTR("failed to copy encryption public key bytes"))); + + + CFDictionarySetValue(peer->description, sOctagonPeerSigningPublicKeyKey, signingPublicKeyBytes); + CFDictionarySetValue(peer->description, sOctagonPeerEncryptionPublicKeyKey, encryptionPublicKeyBytes); + +fail: + CFReleaseNull(signingPublicKeyBytes); + CFReleaseNull(encryptionPublicKeyBytes); +} + + +static SOSPeerInfoRef CF_RETURNS_RETAINED +SOSPeerInfoSetBothOctagonKeys(CFAllocatorRef allocator, + SOSPeerInfoRef toCopy, + CFStringRef descriptionSigningKey, + CFStringRef descriptionEncryptionKey, + SecKeyRef octagonSigningKey, + SecKeyRef octagonEncryptionKey, + SecKeyRef signingKey, + CFErrorRef *error) +{ + CFDataRef signingPublicKeyBytes = NULL; + CFDataRef encryptionPublicKeyBytes = NULL; + + SOSPeerInfoRef pi = NULL; + + OSStatus copySigningKeyResult = SecKeyCopyPublicBytes(octagonSigningKey, &signingPublicKeyBytes); + OSStatus copyEncryptionKeyResult = SecKeyCopyPublicBytes(octagonEncryptionKey, &encryptionPublicKeyBytes); + + require_action_quiet(0 == copySigningKeyResult, fail, SecError(copySigningKeyResult, error, CFSTR("failed to copy signing public key bytes"))); + require_action_quiet(0 == copyEncryptionKeyResult, fail, SecError(copyEncryptionKeyResult, error, CFSTR("failed to copy encryption public key bytes"))); + + pi = SOSPeerInfoCopyWithModification(allocator, toCopy, signingKey, error, + ^bool(SOSPeerInfoRef peerToModify, CFErrorRef *error) { + if(peerToModify && peerToModify->description && signingPublicKeyBytes && descriptionSigningKey && encryptionPublicKeyBytes && descriptionEncryptionKey) { + CFDictionarySetValue(peerToModify->description, descriptionSigningKey, signingPublicKeyBytes); + CFDictionarySetValue(peerToModify->description, descriptionEncryptionKey, encryptionPublicKeyBytes); + } else { + SecError(errSecParam, error, CFSTR("Bad key bytes or dictionary key")); + } + return true; + }); + require(pi, fail); + +fail: + CFReleaseNull(signingPublicKeyBytes); + CFReleaseNull(encryptionPublicKeyBytes); + return pi; +} + +SOSPeerInfoRef CF_RETURNS_RETAINED +SOSPeerInfoSetOctagonKeys(CFAllocatorRef allocator, + SOSPeerInfoRef toCopy, + SecKeyRef octagonSigningKey, + SecKeyRef octagonEncryptionKey, + SecKeyRef signingKey, + CFErrorRef *error) +{ + return SOSPeerInfoSetBothOctagonKeys(allocator, toCopy, sOctagonPeerSigningPublicKeyKey, sOctagonPeerEncryptionPublicKeyKey, octagonSigningKey, octagonEncryptionKey, signingKey, error); +} + static SOSPeerInfoRef CF_RETURNS_RETAINED SOSPeerInfoSetOctagonKey(CFAllocatorRef allocator, SOSPeerInfoRef toCopy, @@ -1088,21 +1191,3 @@ SOSPeerInfoDeviceClass SOSPeerInfoGetClass(SOSPeerInfoRef pi) { errOut: return retval; } - -bool SOSPeerInfoHasOctagonSigningPubKey(SOSPeerInfoRef peer){ - bool hasKey = false; - SecKeyRef pubKey = SOSPeerInfoCopyOctagonSigningPublicKey(peer, NULL); - if(pubKey) - hasKey = true; - CFReleaseNull(pubKey); - return hasKey; -} - -bool SOSPeerInfoHasOctagonEncryptionPubKey(SOSPeerInfoRef peer){ - bool hasKey = false; - SecKeyRef pubKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(peer, NULL); - if(pubKey) - hasKey = true; - CFReleaseNull(pubKey); - return hasKey; -} diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.c b/keychain/SecureObjectSync/SOSPeerInfoCollections.c similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.c rename to keychain/SecureObjectSync/SOSPeerInfoCollections.c index fe31fe8d..f4aa46db 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.c +++ b/keychain/SecureObjectSync/SOSPeerInfoCollections.c @@ -22,16 +22,16 @@ */ -#include +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" #include #include #include #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" // // PeerInfoSetby ID handling diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.h b/keychain/SecureObjectSync/SOSPeerInfoCollections.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoCollections.h rename to keychain/SecureObjectSync/SOSPeerInfoCollections.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.h b/keychain/SecureObjectSync/SOSPeerInfoDER.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.h rename to keychain/SecureObjectSync/SOSPeerInfoDER.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m b/keychain/SecureObjectSync/SOSPeerInfoDER.m similarity index 85% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m rename to keychain/SecureObjectSync/SOSPeerInfoDER.m index 2ee2e588..b71e7f93 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoDER.m +++ b/keychain/SecureObjectSync/SOSPeerInfoDER.m @@ -7,13 +7,13 @@ // #include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoDER.h" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -23,19 +23,31 @@ #include size_t SOSPeerInfoGetDEREncodedSize(SOSPeerInfoRef peer, CFErrorRef *error) { + if(!peer) { + SOSCreateError(kSOSErrorParam, CFSTR("No PeerInfo to encode"), NULL, error); + return 0; + } size_t plist_size = der_sizeof_plist(peer->description, error); - if (plist_size == 0) + if (plist_size == 0) { + SOSCreateError(kSOSErrorParam, CFSTR("No Description to encode"), NULL, error); return 0; + } size_t signature_size = der_sizeof_data(peer->signature, error); - if (signature_size == 0) + if (signature_size == 0) { + SOSCreateError(kSOSErrorParam, CFSTR("Peer not signed to encode"), NULL, error); return 0; + } return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, plist_size + signature_size); } uint8_t* SOSPeerInfoEncodeToDER(SOSPeerInfoRef peer, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) { + if(!peer) { + SOSCreateError(kSOSErrorParam, CFSTR("No PeerInfo to encode"), NULL, error); + return NULL; + } if(peer->version >= 2) SOSPeerInfoPackV2Data(peer); return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, der_encode_plist(peer->description, error, der, @@ -43,6 +55,10 @@ uint8_t* SOSPeerInfoEncodeToDER(SOSPeerInfoRef peer, CFErrorRef* error, const ui } CFDataRef SOSPeerInfoCopyEncodedData(SOSPeerInfoRef peer, CFAllocatorRef allocator, CFErrorRef *error) { + if(!peer) { + SOSCreateError(kSOSErrorParam, CFSTR("No PeerInfo to encode"), NULL, error); + return NULL; + } return CFDataCreateWithDER(kCFAllocatorDefault, SOSPeerInfoGetDEREncodedSize(peer, error), ^uint8_t*(size_t size, uint8_t *buffer) { return SOSPeerInfoEncodeToDER(peer, error, buffer, (uint8_t *) buffer + size); }); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h b/keychain/SecureObjectSync/SOSPeerInfoInternal.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoInternal.h rename to keychain/SecureObjectSync/SOSPeerInfoInternal.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h b/keychain/SecureObjectSync/SOSPeerInfoPriv.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoPriv.h rename to keychain/SecureObjectSync/SOSPeerInfoPriv.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoRingState.h b/keychain/SecureObjectSync/SOSPeerInfoRingState.h similarity index 72% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoRingState.h rename to keychain/SecureObjectSync/SOSPeerInfoRingState.h index c9971c92..e32fc4d6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoRingState.h +++ b/keychain/SecureObjectSync/SOSPeerInfoRingState.h @@ -16,12 +16,12 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSRingTypes.h" SOSRingStatus SOSPeerInfoGetRingState(SOSPeerInfoRef pi, CFStringRef ringname, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoRingState.m b/keychain/SecureObjectSync/SOSPeerInfoRingState.m similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoRingState.m rename to keychain/SecureObjectSync/SOSPeerInfoRingState.m diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h b/keychain/SecureObjectSync/SOSPeerInfoV2.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.h rename to keychain/SecureObjectSync/SOSPeerInfoV2.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m b/keychain/SecureObjectSync/SOSPeerInfoV2.m similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m rename to keychain/SecureObjectSync/SOSPeerInfoV2.m index 0a504884..84eec8a6 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerInfoV2.m +++ b/keychain/SecureObjectSync/SOSPeerInfoV2.m @@ -8,10 +8,10 @@ #include #include "SOSPeerInfoV2.h" -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" #include #include #include @@ -96,11 +96,6 @@ CFStringRef SOSPeerInfoCopySerialNumber(SOSPeerInfoRef pi) { return (retval ? retval : CFRetain(SOSSerialUnknown)); } -CFStringRef SOSPeerInfoCopyOSVersion(SOSPeerInfoRef pi) { - return SOSPeerInfoV2DictionaryCopyString(pi, kPIOSVersionKey); -} - - static bool SOSPeerInfoV2SanityCheck(SOSPeerInfoRef pi) { if(!pi) { return false; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.h b/keychain/SecureObjectSync/SOSPeerOTRTimer.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.h rename to keychain/SecureObjectSync/SOSPeerOTRTimer.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m b/keychain/SecureObjectSync/SOSPeerOTRTimer.m similarity index 91% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m rename to keychain/SecureObjectSync/SOSPeerOTRTimer.m index 03ca8a6c..5562db28 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerOTRTimer.m +++ b/keychain/SecureObjectSync/SOSPeerOTRTimer.m @@ -3,24 +3,24 @@ // #import -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerCoder.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSCoder.h" +#include "keychain/SecureObjectSync/SOSEngine.h" +#include "keychain/SecureObjectSync/SOSDataSource.h" +#include "keychain/SecureObjectSync/SOSAccountTransaction.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSPeerOTRTimer.h" +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include #include #include #include -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" //AGGD NSString* const SecSOSAggdMaxRenegotiation = @"com.apple.security.sos.otrrenegotiationmaxretries"; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.h b/keychain/SecureObjectSync/SOSPeerRateLimiter.h similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.h rename to keychain/SecureObjectSync/SOSPeerRateLimiter.h index 9690c0ae..e84dbbac 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.h +++ b/keychain/SecureObjectSync/SOSPeerRateLimiter.h @@ -3,7 +3,7 @@ // Security // #import "keychain/ckks/RateLimiter.h" -#include "Security/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeer.h" #ifndef SOSPeerRateLimiter_h #define SOSPeerRateLimiter_h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m b/keychain/SecureObjectSync/SOSPeerRateLimiter.m similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m rename to keychain/SecureObjectSync/SOSPeerRateLimiter.m index c67b3fd3..15d756f9 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPeerRateLimiter.m +++ b/keychain/SecureObjectSync/SOSPeerRateLimiter.m @@ -5,9 +5,9 @@ #import #import -#import "Security/SecureObjectSync/SOSPeerRateLimiter.h" +#import "keychain/SecureObjectSync/SOSPeerRateLimiter.h" -#include +#include "keychain/SecureObjectSync/SOSPeer.h" #include #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPersist.h b/keychain/SecureObjectSync/SOSPersist.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPersist.h rename to keychain/SecureObjectSync/SOSPersist.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.h b/keychain/SecureObjectSync/SOSPiggyback.h similarity index 93% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.h rename to keychain/SecureObjectSync/SOSPiggyback.h index 3257cdb4..ab5f3d84 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.h +++ b/keychain/SecureObjectSync/SOSPiggyback.h @@ -26,7 +26,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSCircle.h" __BEGIN_DECLS @@ -38,6 +38,7 @@ CFDataRef SOSPiggyBackBlobCopyEncodedData(SOSGenCountRef gencount, SecKeyRef pub #if __OBJC__ bool SOSPiggyBackAddToKeychain(NSArray* identity, NSArray* tlk); +NSDictionary * SOSPiggyCopyInitialSyncData(const uint8_t** der, const uint8_t *der_end); #endif __END_DECLS diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m b/keychain/SecureObjectSync/SOSPiggyback.m similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m rename to keychain/SecureObjectSync/SOSPiggyback.m index 66774675..5193395e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSPiggyback.m +++ b/keychain/SecureObjectSync/SOSPiggyback.m @@ -22,9 +22,9 @@ */ #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSCircleDer.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" #include #include @@ -104,7 +104,7 @@ bool SOSPiggyBackAddToKeychain(NSArray* identities, NSArray* identities, NSArray -#include -#include +#include "keychain/SecureObjectSync/SOSGenCount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSRecoveryKeyBag.h" #include #include #include @@ -44,7 +44,7 @@ #include -#include "SOSInternal.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #define CURRENT_RKB_VERSION 1 @@ -187,6 +187,7 @@ errOut: return retval; } + CFDataRef SOSRecoveryKeyCopyKeyForAccount(CFAllocatorRef allocator, CFTypeRef account, SOSRecoveryKeyBagRef recoveryKeyBag, CFErrorRef *error) { CFDataRef retval = NULL; require_action_quiet(recoveryKeyBag && recoveryKeyBag->recoveryKeyBag && recoveryKeyBag->accountDSID, @@ -205,20 +206,21 @@ errOut: CFDataRef SOSRecoveryKeyBagCopyEncoded(SOSRecoveryKeyBagRef RecoveryKeyBag, CFErrorRef* error) { CFDataRef result = NULL; CFMutableDataRef encoded = NULL; - + + require_quiet(RecoveryKeyBag, errOut); size_t encodedSize = der_sizeof_RecoveryKeyBag(RecoveryKeyBag, error); - require_quiet(encodedSize, fail); + require_quiet(encodedSize, errOut); encoded = CFDataCreateMutableWithScratch(kCFAllocatorDefault, encodedSize); - require_quiet(SecAllocationError(encoded, error, CFSTR("Failed to create scratch")), fail); + require_quiet(SecAllocationError(encoded, error, CFSTR("Failed to create scratch")), errOut); uint8_t *encode_to = CFDataGetMutableBytePtr(encoded); uint8_t *encode_to_end = encode_to + CFDataGetLength(encoded); - require_quiet(encode_to == der_encode_RecoveryKeyBag(RecoveryKeyBag, error, encode_to, encode_to_end), fail); + require_quiet(encode_to == der_encode_RecoveryKeyBag(RecoveryKeyBag, error, encode_to, encode_to_end), errOut); CFTransferRetained(result, encoded); -fail: +errOut: CFReleaseSafe(encoded); return result; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRing.h b/keychain/SecureObjectSync/SOSRing.h similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRing.h rename to keychain/SecureObjectSync/SOSRing.h index 97687345..25dd226b 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRing.h +++ b/keychain/SecureObjectSync/SOSRing.h @@ -11,9 +11,9 @@ #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSGenCount.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#include "keychain/SecureObjectSync/SOSConcordanceTrust.h" #include #include @@ -60,6 +60,7 @@ bool SOSRingReject(SOSRingRef ring, SecKeyRef user_privkey, SOSFullPeerInfoRef r bool SOSRingSetPayload(SOSRingRef ring, SecKeyRef user_privkey, CFDataRef payload, SOSFullPeerInfoRef requestor, CFErrorRef *error); CFDataRef SOSRingGetPayload(SOSRingRef ring, CFErrorRef *error); CFSetRef SOSRingGetBackupViewset(SOSRingRef ring, CFErrorRef *error); +CFStringRef SOSRingGetBackupView(SOSRingRef ring, CFErrorRef *error); bool SOSRingSetBackupKeyBag(SOSRingRef ring, SOSFullPeerInfoRef fpi, CFSetRef viewSet, SOSBackupSliceKeyBagRef bskb, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBackup.h b/keychain/SecureObjectSync/SOSRingBackup.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingBackup.h rename to keychain/SecureObjectSync/SOSRingBackup.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBackup.m b/keychain/SecureObjectSync/SOSRingBackup.m similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingBackup.m rename to keychain/SecureObjectSync/SOSRingBackup.m index 667af5d9..26582d44 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBackup.m +++ b/keychain/SecureObjectSync/SOSRingBackup.m @@ -10,10 +10,10 @@ #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.h b/keychain/SecureObjectSync/SOSRingBasic.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.h rename to keychain/SecureObjectSync/SOSRingBasic.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m b/keychain/SecureObjectSync/SOSRingBasic.m similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m rename to keychain/SecureObjectSync/SOSRingBasic.m index e92abdf9..6c0cfa21 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingBasic.m +++ b/keychain/SecureObjectSync/SOSRingBasic.m @@ -10,10 +10,10 @@ #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingConcordanceTrust.c b/keychain/SecureObjectSync/SOSRingConcordanceTrust.c similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingConcordanceTrust.c rename to keychain/SecureObjectSync/SOSRingConcordanceTrust.c index f8df2d60..2218db14 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingConcordanceTrust.c +++ b/keychain/SecureObjectSync/SOSRingConcordanceTrust.c @@ -8,11 +8,11 @@ #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingConcordanceTrust.h b/keychain/SecureObjectSync/SOSRingConcordanceTrust.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingConcordanceTrust.h rename to keychain/SecureObjectSync/SOSRingConcordanceTrust.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingDER.c b/keychain/SecureObjectSync/SOSRingDER.c similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingDER.c rename to keychain/SecureObjectSync/SOSRingDER.c index a7a4da84..66d6f70a 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingDER.c +++ b/keychain/SecureObjectSync/SOSRingDER.c @@ -9,11 +9,11 @@ #include "SOSRingDER.h" #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingDER.h b/keychain/SecureObjectSync/SOSRingDER.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingDER.h rename to keychain/SecureObjectSync/SOSRingDER.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingPeerInfoUtils.c b/keychain/SecureObjectSync/SOSRingPeerInfoUtils.c similarity index 71% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingPeerInfoUtils.c rename to keychain/SecureObjectSync/SOSRingPeerInfoUtils.c index 200d0eb7..a141de62 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingPeerInfoUtils.c +++ b/keychain/SecureObjectSync/SOSRingPeerInfoUtils.c @@ -9,11 +9,11 @@ #include "SOSRingPeerInfoUtils.h" #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingPeerInfoUtils.h b/keychain/SecureObjectSync/SOSRingPeerInfoUtils.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingPeerInfoUtils.h rename to keychain/SecureObjectSync/SOSRingPeerInfoUtils.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingRecovery.h b/keychain/SecureObjectSync/SOSRingRecovery.h similarity index 96% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingRecovery.h rename to keychain/SecureObjectSync/SOSRingRecovery.h index ac58dbf0..736f223f 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingRecovery.h +++ b/keychain/SecureObjectSync/SOSRingRecovery.h @@ -32,7 +32,7 @@ #include "SOSRingTypes.h" #include -#include +#include "keychain/SecureObjectSync/SOSRecoveryKeyBag.h" extern ringFuncStruct recovery; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingRecovery.m b/keychain/SecureObjectSync/SOSRingRecovery.m similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingRecovery.m rename to keychain/SecureObjectSync/SOSRingRecovery.m index 01241476..3a204d68 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingRecovery.m +++ b/keychain/SecureObjectSync/SOSRingRecovery.m @@ -31,12 +31,12 @@ #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include -#include +#include "keychain/SecureObjectSync/SOSRecoveryKeyBag.h" #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingTypes.h b/keychain/SecureObjectSync/SOSRingTypes.h similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingTypes.h rename to keychain/SecureObjectSync/SOSRingTypes.h index 8149b23f..0b7a7569 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingTypes.h +++ b/keychain/SecureObjectSync/SOSRingTypes.h @@ -31,8 +31,8 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSRingUtils.h" typedef struct ringfuncs_t { char *typeName; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingTypes.m b/keychain/SecureObjectSync/SOSRingTypes.m similarity index 94% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingTypes.m rename to keychain/SecureObjectSync/SOSRingTypes.m index 2259dd5a..5cee2f1e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingTypes.m +++ b/keychain/SecureObjectSync/SOSRingTypes.m @@ -30,8 +30,8 @@ #include "SOSRingBasic.h" #include "SOSRingBackup.h" #include "SOSRingRecovery.h" -#include -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSInternal.h" #include #include @@ -254,6 +254,22 @@ CFSetRef SOSRingGetBackupViewset(SOSRingRef ring, CFErrorRef *error) { return SOSRingGetBackupViewset_Internal(ring); } +// This returns one string with the view for the ring - we never used multi-view rings +CFStringRef SOSRingGetBackupView(SOSRingRef ring, CFErrorRef *error) { + __block CFStringRef result = NULL; + CFSetRef allTheViews = SOSRingGetBackupViewset(ring, error); + if(allTheViews) { + if(CFSetGetCount(allTheViews) == 1) { + CFSetForEach(allTheViews, ^(const void *value) { + result = asString(value, error); + }); + } + } else { + SOSCreateError(kSOSErrorParam, CFSTR("Wrong set count for one return"), NULL, error); + } + return result; +} + static bool isBackupRing(SOSRingRef ring, CFErrorRef *error) { SOSRingType type = SOSRingGetType(ring); if(kSOSRingBackup != type){ diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c b/keychain/SecureObjectSync/SOSRingUtils.c similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c rename to keychain/SecureObjectSync/SOSRingUtils.c index a83f8c47..e1592ccc 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.c +++ b/keychain/SecureObjectSync/SOSRingUtils.c @@ -28,11 +28,11 @@ #include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeer.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include @@ -631,7 +631,7 @@ fail: return result; } -static bool SOSRingRemoveSignatures(SOSRingRef ring, CFErrorRef *error) { +bool SOSRingRemoveSignatures(SOSRingRef ring, CFErrorRef *error) { CFDictionaryRemoveAllValues(ring->signatures); return true; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h b/keychain/SecureObjectSync/SOSRingUtils.h similarity index 98% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h rename to keychain/SecureObjectSync/SOSRingUtils.h index 2354ed50..64201e52 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingUtils.h +++ b/keychain/SecureObjectSync/SOSRingUtils.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSGenCount.h" #include "SOSRing.h" #define ALLOCATOR NULL @@ -60,6 +60,7 @@ CF_RETURNS_RETAINED SOSRingRef SOSRingAllocate(void); SOSRingRef SOSRingCreate_Internal(CFStringRef name, SOSRingType type, CFErrorRef *error); SOSRingRef SOSRingCopyRing(SOSRingRef original, CFErrorRef *error); +bool SOSRingRemoveSignatures(SOSRingRef ring, CFErrorRef *error); bool SOSRingVerifySignatureExists(SOSRingRef ring, SecKeyRef pubKey, CFErrorRef *error); bool SOSRingVerify(SOSRingRef ring, SecKeyRef pubKey, CFErrorRef *error); bool SOSRingVerifyPeerSigned(SOSRingRef ring, SOSPeerInfoRef peer, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingV0.h b/keychain/SecureObjectSync/SOSRingV0.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingV0.h rename to keychain/SecureObjectSync/SOSRingV0.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingV0.m b/keychain/SecureObjectSync/SOSRingV0.m similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSRingV0.m rename to keychain/SecureObjectSync/SOSRingV0.m index 95c58980..84579836 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSRingV0.m +++ b/keychain/SecureObjectSync/SOSRingV0.m @@ -10,10 +10,10 @@ #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" +#include "keychain/SecureObjectSync/SOSPeerInfoCollections.h" +#include "keychain/SecureObjectSync/SOSCircle.h" #include #include @@ -134,7 +134,7 @@ __unused static CFDataRef SOSRingGetPayload_V0(SOSRingRef ring, CFErrorRef *erro } -ringFuncStruct basic = { +ringFuncStruct ringsV0 = { "V0", 1, SOSRingCreate_V0, diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.h b/keychain/SecureObjectSync/SOSTransport.h similarity index 85% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.h rename to keychain/SecureObjectSync/SOSTransport.h index 2d03c55f..1f042295 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.h +++ b/keychain/SecureObjectSync/SOSTransport.h @@ -2,10 +2,10 @@ #ifndef SOSTransport_h #define SOSTransport_h -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSTransportCircle.h" +#include "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#include "keychain/SecureObjectSync/SOSAccount.h" CF_RETURNS_RETAINED CFMutableArrayRef SOSTransportDispatchMessages(SOSAccountTransaction* txn, CFDictionaryRef updates, CFErrorRef *error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m b/keychain/SecureObjectSync/SOSTransport.m similarity index 97% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m rename to keychain/SecureObjectSync/SOSTransport.m index 1d0c6e17..ce9a8d82 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransport.m +++ b/keychain/SecureObjectSync/SOSTransport.m @@ -1,15 +1,15 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#include "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#include "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSRing.h" + +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include #include #include @@ -101,6 +101,8 @@ void SOSUnregisterAllTransportKeyParameters() { // // Should we be dispatching back to our queue to handle later // + + void SOSUpdateKeyInterest(SOSAccount* account) { CFMutableArrayRef alwaysKeys = CFArrayCreateMutableForCFTypes(kCFAllocatorDefault); @@ -121,7 +123,6 @@ void SOSUpdateKeyInterest(SOSAccount* account) } CFReleaseNull(localError); } - }]; CFMutableDictionaryRef keyParamsDict = CFDictionaryCreateMutableForCFTypes(kCFAllocatorDefault); @@ -208,6 +209,9 @@ void SOSUpdateKeyInterest(SOSAccount* account) SOSCloudKeychainUpdateKeys(keyDict, uuid, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(CFDictionaryRef returnedValues, CFErrorRef error) { if (error) { secerror("Error updating keys: %@", error); + account.key_interests_need_updating = true; + } else { + account.key_interests_need_updating = false; } }); CFReleaseNull(uuid); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportBackupPeer.h b/keychain/SecureObjectSync/SOSTransportBackupPeer.h similarity index 91% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportBackupPeer.h rename to keychain/SecureObjectSync/SOSTransportBackupPeer.h index 033c43ac..ad7c3239 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportBackupPeer.h +++ b/keychain/SecureObjectSync/SOSTransportBackupPeer.h @@ -4,7 +4,7 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" typedef struct __OpaqueSOSTransportBackupPeer *SOSTransportBackupPeerRef; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportBackupPeer.m b/keychain/SecureObjectSync/SOSTransportBackupPeer.m similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportBackupPeer.m rename to keychain/SecureObjectSync/SOSTransportBackupPeer.m index d4bf019d..fff2dc09 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportBackupPeer.m +++ b/keychain/SecureObjectSync/SOSTransportBackupPeer.m @@ -1,5 +1,5 @@ #include -#include +#include "keychain/SecureObjectSync/SOSTransportBackupPeer.h" #include #include diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h b/keychain/SecureObjectSync/SOSTransportCircle.h similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h rename to keychain/SecureObjectSync/SOSTransportCircle.h index 95992173..a214ca1a 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.h +++ b/keychain/SecureObjectSync/SOSTransportCircle.h @@ -1,7 +1,7 @@ #ifndef SOSTransportCircle_h #define SOSTransportCircle_h -#import "Security/SecureObjectSync/SOSPeerInfo.h" +#import "keychain/SecureObjectSync/SOSPeerInfo.h" @class SOSAccount; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.m b/keychain/SecureObjectSync/SOSTransportCircle.m similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.m rename to keychain/SecureObjectSync/SOSTransportCircle.m index fe9349e4..49145ab1 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircle.m +++ b/keychain/SecureObjectSync/SOSTransportCircle.m @@ -1,5 +1,5 @@ -#import "Security/SecureObjectSync/SOSAccountPriv.h" -#include +#import "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSTransport.h" @implementation SOSCircleStorageTransport diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.h b/keychain/SecureObjectSync/SOSTransportCircleCK.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.h rename to keychain/SecureObjectSync/SOSTransportCircleCK.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m b/keychain/SecureObjectSync/SOSTransportCircleCK.m similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m rename to keychain/SecureObjectSync/SOSTransportCircleCK.m index 822abcc5..2e3a4cc5 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleCK.m +++ b/keychain/SecureObjectSync/SOSTransportCircleCK.m @@ -7,8 +7,8 @@ // #import -#import "Security/SecureObjectSync/SOSTransport.h" -#import "Security/SecureObjectSync/SOSAccountPriv.h" +#import "keychain/SecureObjectSync/SOSTransport.h" +#import "keychain/SecureObjectSync/SOSAccountPriv.h" #import "SOSTransportCircleCK.h" @implementation SOSCKCircleStorage diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.h b/keychain/SecureObjectSync/SOSTransportCircleKVS.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.h rename to keychain/SecureObjectSync/SOSTransportCircleKVS.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m b/keychain/SecureObjectSync/SOSTransportCircleKVS.m similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m rename to keychain/SecureObjectSync/SOSTransportCircleKVS.m index 56aaa5af..d3237e81 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportCircleKVS.m +++ b/keychain/SecureObjectSync/SOSTransportCircleKVS.m @@ -2,14 +2,14 @@ // SOSTransportCircleKVS.c // sec // -#include -#include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSTransportCircle.h" +#include "keychain/SecureObjectSync/SOSTransportCircleKVS.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include -#import "Security/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" @implementation SOSKVSCircleStorageTransport @@ -197,7 +197,7 @@ static bool SOSTransportCircleKVSUpdateRetirementRecords(CFDictionaryRef updates CFReleaseNull(retirement_key); }); - CFArrayAppendValue(alwaysKeys, circle_key); + CFArrayAppendValue(unlockedKeys, circle_key); // This is where circle interest is handled CFReleaseNull(circle_key); } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameter.h b/keychain/SecureObjectSync/SOSTransportKeyParameter.h similarity index 95% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameter.h rename to keychain/SecureObjectSync/SOSTransportKeyParameter.h index 6df1521e..427beba2 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameter.h +++ b/keychain/SecureObjectSync/SOSTransportKeyParameter.h @@ -2,7 +2,7 @@ #ifndef SOSTransportKeyParameter_h #define SOSTransportKeyParameter_h -#import +#include "keychain/SecureObjectSync/SOSAccountPriv.h" @interface CKKeyParameter : NSObject { diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameter.m b/keychain/SecureObjectSync/SOSTransportKeyParameter.m similarity index 87% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameter.m rename to keychain/SecureObjectSync/SOSTransportKeyParameter.m index 6f6816cc..784d6a55 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportKeyParameter.m +++ b/keychain/SecureObjectSync/SOSTransportKeyParameter.m @@ -1,11 +1,11 @@ -#include -#include -#include +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSTransportKeyParameter.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" @implementation CKKeyParameter @@ -63,7 +63,14 @@ static bool SOSTransportKeyParameterKVSUpdateKVS(CFDictionaryRef changes, CFErro -(bool) SOSTransportKeyParameterPublishCloudParameters:(CKKeyParameter*) transport data:(CFDataRef)newParameters err:(CFErrorRef*) error { - + if(newParameters) { + secnotice("circleOps", "Publishing Cloud Parameters"); + } else { + secnotice("circleOps", "Tried to publish nil Cloud Parameters"); + (void) SecRequirementError(newParameters != NULL, error, CFSTR("Tried to publish nil Cloud Parameters")); + return false; + } + bool waitForeverForSynchronization = true; CFDictionaryRef changes = NULL; CFDataRef timeData = NULL; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.h b/keychain/SecureObjectSync/SOSTransportMessage.h similarity index 89% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.h rename to keychain/SecureObjectSync/SOSTransportMessage.h index 2c583688..69fe2498 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.h +++ b/keychain/SecureObjectSync/SOSTransportMessage.h @@ -3,7 +3,7 @@ #define SOSTransportMessage_h #import -#import +#include "keychain/SecureObjectSync/SOSAccountPriv.h" @interface SOSMessage : NSObject { @@ -12,7 +12,7 @@ NSString *circleName; } @property (atomic) CFTypeRef engine; -@property (atomic) SOSAccount* account; +@property (strong, atomic) SOSAccount* account; @property (strong, atomic) NSString *circleName; -(id) initWithAccount:(SOSAccount*)acct andName:(NSString*)name; @@ -33,7 +33,7 @@ -(CFDictionaryRef)CF_RETURNS_RETAINED SOSTransportMessageHandlePeerMessageReturnsHandledCopy:(SOSMessage*) transport peerMessages:(CFMutableDictionaryRef) circle_peer_messages_table err:(CFErrorRef *)error; -(bool) SOSTransportMessageHandlePeerMessage:(SOSMessage*) transport id:(CFStringRef) peer_id cm:(CFDataRef) codedMessage err:(CFErrorRef *)error; --(bool) SOSTransportMessageSendMessageIfNeeded:(SOSMessage*) transport id:(CFStringRef) circle_id pID:(CFStringRef) peer_id err:(CFErrorRef *)error; +-(bool) SOSTransportMessageSendMessageIfNeeded:(SOSMessage*) transport circleName:(CFStringRef) circle_id pID:(CFStringRef) peer_id err:(CFErrorRef *)error; //for testing bool SOSEngineHandleCodedMessage(SOSAccount* account, SOSEngineRef engine, CFStringRef peerID, CFDataRef codedMessage, CFErrorRef*error); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m b/keychain/SecureObjectSync/SOSTransportMessage.m similarity index 82% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m rename to keychain/SecureObjectSync/SOSTransportMessage.m index b503757a..6b0f0482 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessage.m +++ b/keychain/SecureObjectSync/SOSTransportMessage.m @@ -1,17 +1,17 @@ -#include -#include -#include -#include -#include -#import "Security/SecureObjectSync/SOSPeerRateLimiter.h" -#import "Security/SecureObjectSync/SOSPeerOTRTimer.h" +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include "keychain/SecureObjectSync/SOSPeerCoder.h" +#include "keychain/SecureObjectSync/SOSEngine.h" +#import "keychain/SecureObjectSync/SOSPeerRateLimiter.h" +#import "keychain/SecureObjectSync/SOSPeerOTRTimer.h" #include #include #include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include // TODO: Remove this layer violation. static const CFStringRef kSecSOSMessageRTT = CFSTR("com.apple.security.sos.messagertt"); @@ -98,20 +98,38 @@ bool SOSEngineHandleCodedMessage(SOSAccount* account, SOSEngineRef engine, CFStr secnotice("otrtimer", "otr negotiation completed! clearing max retry counter"); SOSPeerOTRTimerClearMaxRetryCount(account, (__bridge NSString*)peerID); } - if (uwstatus == SOSCoderUnwrapDecoded) { - SOSMessageRef message = NULL; - if (decodedMessage && CFDataGetLength(decodedMessage)) { - // Only hand non empty messages to the engine, empty messages are an artifact - // of coder startup. - message = SOSMessageCreateWithData(kCFAllocatorDefault, decodedMessage, error); + switch (uwstatus) { + case SOSCoderUnwrapDecoded: { + SOSMessageRef message = NULL; + if (decodedMessage && CFDataGetLength(decodedMessage)) { + // Only hand non empty messages to the engine, empty messages are an artifact + // of coder startup. + message = SOSMessageCreateWithData(kCFAllocatorDefault, decodedMessage, error); + } + if (message) { + bool engineHandleMessageDoesNotGetToRollbackTransactions = true; + result = SOSEngineHandleMessage_locked(engine, peerID, message, txn, &engineHandleMessageDoesNotGetToRollbackTransactions, &somethingChanged, error); + CFReleaseSafe(message); + if (!result) { + secnotice("engine", "Failed to handle message from peer %@: %@", peerID, error != NULL ? *error : NULL); + } + } else { + secnotice("engine", "Failed to turn a data gram into an SOSMessage: %@", error != NULL ? *error : NULL); + result = SOSErrorCreate(KSOSCantParseSOSMessage, error, NULL, CFSTR("Failed to parse SOSMessage")); + } + break; + } + case SOSCoderUnwrapHandled: { + secnotice("engine", "coder handled a negotiation message"); + result = true; + break; } - if (message) { - bool engineHandleMessageDoesNotGetToRollbackTransactions = true; - result = SOSEngineHandleMessage_locked(engine, peerID, message, txn, &engineHandleMessageDoesNotGetToRollbackTransactions, &somethingChanged, error); - CFReleaseSafe(message); + case SOSCoderUnwrapError: + default: { + secnotice("engine", "coder handled a error message: %d (error: %@)", (int)uwstatus, error != NULL ? *error : NULL); + result = false; + break; } - } else { - result = uwstatus != SOSCoderUnwrapError; } CFReleaseNull(decodedMessage); }); @@ -133,30 +151,28 @@ bool SOSEngineHandleCodedMessage(SOSAccount* account, SOSEngineRef engine, CFStr -(void) SOSTransportMessageCalculateNextTimer:(SOSAccount*)account rtt:(int)rtt peerid:(NSString*)peerid { + const int minRTT = 60; + const int maxRTT = 3600; + int newrtt = rtt *2; + NSMutableDictionary *peerRTTs = (__bridge NSMutableDictionary*)SOSAccountGetValue(account,kSOSAccountPeerNegotiationTimeouts, NULL); - if(!peerRTTs){ + if(!peerRTTs) { peerRTTs = [NSMutableDictionary dictionary]; } - else{ - NSNumber *timeout = [peerRTTs objectForKey:peerid]; - if(timeout){ - if(timeout.intValue < (rtt * 2)){ - NSNumber* newTimeout = [[NSNumber alloc] initWithInt: (rtt * 2)]; - [peerRTTs setObject:newTimeout forKey:peerid]; - secnotice("otrtimer", "New OTR RTT: %d", [newTimeout intValue]); - } - } - else{ - if(rtt < 15){ - timeout = [[NSNumber alloc]initWithInt:(30 * 2)]; - } - else{ - timeout = [[NSNumber alloc]initWithInt:(rtt * 2)]; - } - [peerRTTs setObject:timeout forKey:peerid]; - secnotice("otrtimer", "setting initial timeout value to rtt*2: %d", [timeout intValue]); - } + + // if we already have a longer rtt than requested then bail, unless it got excessive previously + NSNumber *timeout = [peerRTTs objectForKey:peerid]; + if(timeout && (timeout.intValue >= rtt*2) && (newrtt <= maxRTT)) { + return; } + + // make sure newrtt is a value between minRTT and maxRTT + newrtt = MAX(newrtt, minRTT); + newrtt = MIN(newrtt, maxRTT); + + NSNumber* newTimeout = [[NSNumber alloc] initWithInt: (newrtt)]; + [peerRTTs setObject:newTimeout forKey:peerid]; + secnotice("otrtimer", "peerID: %@ New OTR RTT: %d", peerid, newrtt); SOSAccountSetValue(account,kSOSAccountPeerNegotiationTimeouts, (__bridge CFMutableDictionaryRef)peerRTTs, NULL); } @@ -169,7 +185,7 @@ bool SOSEngineHandleCodedMessage(SOSAccount* account, SOSEngineRef engine, CFStr if(storedDate){ NSDate* currentDate = [NSDate date]; int rtt = [currentDate timeIntervalSinceDate:storedDate]; - secnotice("otrtimer","current date: %@, stored date: %@", currentDate, storedDate); + secnotice("otrtimer","peerID: %@ current date: %@, stored date: %@", peerid, currentDate, storedDate); secnotice("otrtimer", "rtt: %d", rtt); [self SOSTransportMessageCalculateNextTimer:account rtt:rtt peerid:peerid]; @@ -359,12 +375,15 @@ static void SOSTransportSendPendingMessage(CFArrayRef attributes, SOSMessage* tr SOSAccountSetValue(account, kSOSAccountPeerLastSentTimestamp, (__bridge CFMutableDictionaryRef)peerRTTs, NULL); } } --(bool) SOSTransportMessageSendMessageIfNeeded:(SOSMessage*) transport id:(CFStringRef) circle_id pID:(CFStringRef) peer_id err:(CFErrorRef *)error +-(bool) SOSTransportMessageSendMessageIfNeeded:(SOSMessage*)transport + circleName:(CFStringRef)circle_id + pID:(CFStringRef)peer_id + err:(CFErrorRef *)error { __block bool ok = true; SOSAccount* account = transport.account; - BOOL initialSync = account.isInitialSyncing; + BOOL initialSyncDone = SOSAccountHasCompletedInitialSync(account); ok &= SOSEngineWithPeerID((SOSEngineRef)transport.engine, peer_id, error, ^(SOSPeerRef peer, SOSCoderRef coder, SOSDataSourceRef dataSource, SOSTransactionRef txn, bool *forceSaveState) { // Now under engine lock do stuff CFDataRef message_to_send = NULL; @@ -379,10 +398,10 @@ static void SOSTransportSendPendingMessage(CFArrayRef attributes, SOSMessage* tr CFArrayAppendValue(attributes, CFSTR("NoAttribute")); } - if(initialSync){ + if(!initialSyncDone){ secnotice("ratelimit","not going to rate limit, currently in initial sync"); } - if(!initialSync && message_to_send){ //need to judge the message if not in initial sync + if(initialSyncDone && message_to_send){ //need to judge the message if not in initial sync secnotice("ratelimit","not in initial sync!"); shouldSend = SOSPeerShouldSend(attributes, peer, transport, message_to_send); CFRange range = CFRangeMake(0, CFArrayGetCount(attributes)); diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.h b/keychain/SecureObjectSync/SOSTransportMessageKVS.h similarity index 86% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.h rename to keychain/SecureObjectSync/SOSTransportMessageKVS.h index 7ebfa435..b098512e 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.h +++ b/keychain/SecureObjectSync/SOSTransportMessageKVS.h @@ -2,8 +2,8 @@ #ifndef sec_SOSTransportMessageKVS_h #define sec_SOSTransportMessageKVS_h -#include -#import +#import "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" @class SOSMessage; @interface SOSMessageKVS : SOSMessage diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m b/keychain/SecureObjectSync/SOSTransportMessageKVS.m similarity index 91% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m rename to keychain/SecureObjectSync/SOSTransportMessageKVS.m index 9fb69094..68af1835 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTransportMessageKVS.m +++ b/keychain/SecureObjectSync/SOSTransportMessageKVS.m @@ -1,12 +1,12 @@ -#include -#import -#import -#include +#include "keychain/SecureObjectSync/SOSTransport.h" +#include "keychain/SecureObjectSync/SOSTransportMessage.h" +#import "keychain/SecureObjectSync/SOSTransportMessageKVS.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" @implementation SOSMessageKVS @@ -209,8 +209,17 @@ static bool sendToPeer(SOSMessage* transport, CFStringRef circleName, CFStringRe CFSetForEach(peers, ^(const void *value) { CFStringRef peerID = asString(value, NULL); + CFErrorRef localError = NULL; - result &= [ transport SOSTransportMessageSendMessageIfNeeded:transport id:(__bridge CFStringRef)(transport.circleName) pID:peerID err:error]; + result &= [ transport SOSTransportMessageSendMessageIfNeeded:transport + circleName:(__bridge CFStringRef)(transport.circleName) + pID:peerID + err:&localError]; + + if (!result && error && *error == NULL && localError) { + *error = (CFErrorRef)CFRetain(localError); + } + CFReleaseNull(localError); }); return result; diff --git a/keychain/SecureObjectSync/SOSTrustedDeviceAttributes.h b/keychain/SecureObjectSync/SOSTrustedDeviceAttributes.h new file mode 100644 index 00000000..796b5700 --- /dev/null +++ b/keychain/SecureObjectSync/SOSTrustedDeviceAttributes.h @@ -0,0 +1,27 @@ +// +// SOSTrustedDeviceAttributes.h +// Security +// + +#ifndef SOSTrustedDeviceAttributes_h +#define SOSTrustedDeviceAttributes_h + +#import +#define MACHINEID @"machineID" +#define SERIALNUMBER @"serialNumber" + +NS_ASSUME_NONNULL_BEGIN + +#if __OBJC2__ + +@interface SOSTrustedDeviceAttributes : NSObject + +@property NSString *machineID; +@property NSString *serialNumber; + +@end +#endif /* __OBJC2__ */ + +NS_ASSUME_NONNULL_END + +#endif /* SOSTrustedDeviceAttributes_h */ diff --git a/keychain/SecureObjectSync/SOSTrustedDeviceAttributes.m b/keychain/SecureObjectSync/SOSTrustedDeviceAttributes.m new file mode 100644 index 00000000..2eed7855 --- /dev/null +++ b/keychain/SecureObjectSync/SOSTrustedDeviceAttributes.m @@ -0,0 +1,27 @@ +// +// SOSTrustedDeviceAttributes.m +// Security +// +// + +#import "SOSTrustedDeviceAttributes.h" + + +@implementation SOSTrustedDeviceAttributes + ++ (BOOL)supportsSecureCoding { return YES; } + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + if(self = [super init]) { + _machineID = [aDecoder decodeObjectOfClass:[NSString class] forKey:MACHINEID]; + _serialNumber = [aDecoder decodeObjectOfClass:[NSString class] forKey:SERIALNUMBER]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:_machineID forKey:MACHINEID]; + [coder encodeObject:_serialNumber forKey:SERIALNUMBER]; +} + +@end diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h b/keychain/SecureObjectSync/SOSTypes.h similarity index 80% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h rename to keychain/SecureObjectSync/SOSTypes.h index b664a5b2..ba6bc9f3 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSTypes.h +++ b/keychain/SecureObjectSync/SOSTypes.h @@ -43,8 +43,9 @@ typedef enum SyncWithAllPeersReason { */ typedef enum{ - kPiggyV0 = 0, - kPiggyV1 = 1, + kPiggyV0 = 0, //first version of piggybacking, does not pad messages with keys + kPiggyV1 = 1, //tacks on initial sync credentials + kPiggyV2 = 2, //Octagon } PiggyBackProtocolVersion; typedef enum{ @@ -94,6 +95,14 @@ typedef int SOSViewActionCode; #define SOSControlInitialSyncFlagPCSNonCurrent (1 << 2) #define SOSControlInitialSyncFlagBluetoothMigration (1 << 3) +typedef NS_OPTIONS(uint32_t, SOSAccountGhostBustingOptions) { + SOSGhostBustBySerialNumber = 1, + SOSGhostBustByMID = 2, + SOSGhostBustSerialByAge = 4, + SOSGhostBustTriggerNow = 8, + SOSGhostBustiCloudIdentities = 16, +}; + @protocol SOSControlProtocol - (void)userPublicKey:(void ((^))(BOOL trusted, NSData *spki, NSError *error))complete; - (void)kvsPerformanceCounters:(void(^)(NSDictionary *))reply; @@ -103,8 +112,13 @@ typedef int SOSViewActionCode; - (void)assertStashedAccountCredential:(void(^)(BOOL result, NSError *error))complete; - (void)validatedStashedAccountCredential:(void(^)(NSData *credential, NSError *error))complete; - (void)stashAccountCredential:(NSData *)credential complete:(void(^)(bool success, NSError *error))complete; +- (void)ghostBust:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete; +- (void)ghostBustPeriodic:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool busted, NSError *error))complete; +- (void)ghostBustTriggerTimed:(SOSAccountGhostBustingOptions)options complete: (void(^)(bool ghostBusted, NSError *error))complete; +- (void)ghostBustInfo: (void(^)(NSData *json, NSError *error))complete; - (void)myPeerInfo:(void (^)(NSData *, NSError *))complete; +- (void)circleHash:(void (^)(NSString *, NSError *))complete; - (void)circleJoiningBlob:(NSData *)applicant complete:(void (^)(NSData *blob, NSError *))complete; - (void)joinCircleWithBlob:(NSData *)blob version:(PiggyBackProtocolVersion)version complete:(void (^)(bool success, NSError *))complete; - (void)initialSyncCredentials:(uint32_t)flags complete:(void (^)(NSArray *, NSError *))complete; diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h b/keychain/SecureObjectSync/SOSUserKeygen.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.h rename to keychain/SecureObjectSync/SOSUserKeygen.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m b/keychain/SecureObjectSync/SOSUserKeygen.m similarity index 88% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m rename to keychain/SecureObjectSync/SOSUserKeygen.m index 4e81b1c1..5e466ae7 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSUserKeygen.m +++ b/keychain/SecureObjectSync/SOSUserKeygen.m @@ -22,7 +22,7 @@ */ -#include +#include "keychain/SecureObjectSync/SOSUserKeygen.h" #include #include #include @@ -37,8 +37,8 @@ #include #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSAccount.h" #include #include #include @@ -252,31 +252,31 @@ SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *er CFSTR("Too few iterations, params suggested %zd."), iterations); return NULL; } - - debugDumpUserParameters(CFSTR("params-keygen"), parameters); - const uint8_t *password_bytes = CFDataGetBytePtr(password); size_t password_length = CFDataGetLength(password); - const size_t maxbytes = 128; - ccec_const_cp_t cp = ccec_get_cp(keysize); - struct ccrng_pbkdf2_prng_state pbkdf2_prng; - ccec_full_ctx_decl_cp(cp, tmpkey); secnotice("circleOps", "Generating key for: iterations %zd, keysize %zd: %@", iterations, keysize, parameters); - if (ccrng_pbkdf2_prng_init(&pbkdf2_prng, maxbytes, - password_length, password_bytes, - saltlen, salt, - iterations)) { - SOSCreateError(kSOSErrorProcessingFailure, CFSTR("prng init failed"), NULL, error); - return NULL; + size_t drbg_output_size=128; + uint8_t drbg_output[drbg_output_size]; + ccpbkdf2_hmac(ccsha256_di(), password_length, password_bytes, + saltlen, salt, + iterations, + drbg_output_size, drbg_output); + + int rngError = 0; + int keyError = -1; + struct ccrng_state *rng = ccrng(&rngError); + if(rng) { + keyError=ccec_generate_key_deterministic(cp, drbg_output_size, drbg_output, rng, CCEC_GENKEY_DETERMINISTIC_LEGACY, tmpkey); + cc_clear(drbg_output_size, drbg_output); } - if (ccec_generate_key_legacy(cp, (struct ccrng_state *)&pbkdf2_prng, tmpkey)) { + if(!rng || keyError != 0) { SOSCreateError(kSOSErrorProcessingFailure, CFSTR("Keygen failed"), NULL, error); return NULL; } @@ -286,26 +286,13 @@ SecKeyRef SOSUserKeygen(CFDataRef password, CFDataRef parameters, CFErrorRef *er void debugDumpUserParameters(CFStringRef message, CFDataRef parameters) { - size_t saltlen = 0; - const uint8_t *salt = NULL; - - size_t iterations = 0; - size_t keysize = 0; - - const uint8_t *der = CFDataGetBytePtr(parameters); - const uint8_t *der_end = der + CFDataGetLength(parameters); - - der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end); - if (der == NULL) { + CFStringRef keyparm = UserParametersDescription(parameters); + if (keyparm == NULL) { secnotice("circleOps", "failed to decode pbkdf2 params"); return; } - - BufferPerformWithHexString(salt, saltlen, ^(CFStringRef saltHex) { - CFDataPerformWithHexString(parameters, ^(CFStringRef parametersHex) { - secnotice("circleOps", "%@ ]", message, iterations, keysize, saltHex, parametersHex); - }); - }); + secnotice("circleOps", "%@ %@]", message, keyparm); + CFReleaseNull(keyparm); } CF_RETURNS_RETAINED CFStringRef UserParametersDescription(CFDataRef parameters){ @@ -321,6 +308,8 @@ CF_RETURNS_RETAINED CFStringRef UserParametersDescription(CFDataRef parameters){ if (parse_end != CFDataGetPastEndPtr(parameters)){ secdebug("circleOps", "failed to decode cloud parameters"); + CFReleaseNull(newParameters); + CFReleaseNull(newKey); return NULL; } @@ -334,8 +323,10 @@ CF_RETURNS_RETAINED CFStringRef UserParametersDescription(CFDataRef parameters){ const uint8_t *der_end = der + CFDataGetLength(newParameters); der = der_decode_pbkdf2_params(&saltlen, &salt, &iterations, &keysize, der, der_end); - if (der == NULL) { + if (der != NULL) { secdebug("circleOps", "failed to decode pbkdf2 params"); + CFReleaseNull(newParameters); + CFReleaseNull(newKey); return NULL; } diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.exp-in b/keychain/SecureObjectSync/SOSViews.exp-in similarity index 89% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSViews.exp-in rename to keychain/SecureObjectSync/SOSViews.exp-in index 5c0b5d43..eeaa1282 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.exp-in +++ b/keychain/SecureObjectSync/SOSViews.exp-in @@ -14,13 +14,13 @@ VIEWEXPORT(KeychainV0) // Views with ViewHints #undef DOVIEWMACRO #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) _k##SYSTEM##View##VIEWNAME -#include "Security/SecureObjectSync/ViewList.list" +#include "keychain/SecureObjectSync/ViewList.list" // V0 Subviews don't have view hints, they use queries #undef DOVIEWMACRO #define DO_EXPORT_(VIEWNAME) _kSecAttrViewHint##VIEWNAME #define DO_EXPORT_V(VIEWNAME) #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) DO_EXPORT_##V0SETTING(VIEWNAME) -#include "Security/SecureObjectSync/ViewList.list" +#include "keychain/SecureObjectSync/ViewList.list" #undef DOVIEWMACRO diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h b/keychain/SecureObjectSync/SOSViews.h similarity index 100% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSViews.h rename to keychain/SecureObjectSync/SOSViews.h diff --git a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m b/keychain/SecureObjectSync/SOSViews.m similarity index 92% rename from OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m rename to keychain/SecureObjectSync/SOSViews.m index 39bbeb68..4098335d 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/SOSViews.m +++ b/keychain/SecureObjectSync/SOSViews.m @@ -35,16 +35,16 @@ #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSAccountPriv.h" #define viewMemError CFSTR("Failed to get memory for views in PeerInfo") #define viewUnknownError CFSTR("Unknown view(%@) (ViewResultCode=%d)") @@ -65,7 +65,7 @@ const CFStringRef kSOSViewKeychainV0 = CFSTR("KeychainV0"); // i #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" +#include "keychain/SecureObjectSync/ViewList.list" // View Hints // Note that by definition, there cannot be a V0 view hint @@ -85,6 +85,9 @@ const CFStringRef kSOSViewHintPCSFeldspar = CFSTR("PCS-Feldspar"); const CFStringRef kSOSViewHintAppleTV = CFSTR("AppleTV"); const CFStringRef kSOSViewHintHomeKit = CFSTR("HomeKit"); +CFSetRef sTestViewSet = NULL; + + CFMutableSetRef SOSViewCopyViewSet(ViewSetKind setKind) { CFMutableSetRef result = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); @@ -116,8 +119,14 @@ CFMutableSetRef SOSViewCopyViewSet(ViewSetKind setKind) { #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \ DOVIEWMACRO_##SYSTEM(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) -#include "Security/SecureObjectSync/ViewList.list" - +#include "keychain/SecureObjectSync/ViewList.list" + if(setKind == kViewSetAlwaysOn && sTestViewSet != NULL) { + CFReleaseNull(result); + result = CFSetCreateMutableForCFTypes(kCFAllocatorDefault); + } + if(setKind == kViewSetAll && sTestViewSet != NULL) { + CFSetUnion(result, sTestViewSet); + } return result; } @@ -132,7 +141,7 @@ bool SOSViewInSOSSystem(CFStringRef view) { if(CFEqualSafe(view, k##SYSTEM##View##VIEWNAME)) { \ return __SYSTEM_##SYSTEM; \ } -#include "Security/SecureObjectSync/ViewList.list" +#include "keychain/SecureObjectSync/ViewList.list" return false; } @@ -147,7 +156,7 @@ bool SOSViewHintInSOSSystem(CFStringRef viewHint) { #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \ CHECK_VIEWHINT_##V0(VIEWNAME, SYSTEM) -#include "Security/SecureObjectSync/ViewList.list" +#include "keychain/SecureObjectSync/ViewList.list" return false; } @@ -166,7 +175,7 @@ if(CFEqualSafe(viewHint, kSecAttrViewHint##VIEWNAME)) { \ #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) \ DOVIEWMACRO_##SYSTEM(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULT, INITIAL, ALWAYSON, BACKUP, V0) -#include "Security/SecureObjectSync/ViewList.list" +#include "keychain/SecureObjectSync/ViewList.list" return false; } @@ -203,21 +212,30 @@ bool SOSViewsIsV0Subview(CFStringRef viewName) { return CFSetContainsValue(SOSViewsGetV0SubviewSet(), viewName); } -CFSetRef sTestViewSet = NULL; +static CFMutableSetRef sosAllViews = NULL; + void SOSViewsSetTestViewsSet(CFSetRef testViewNames) { - CFRetainAssign(sTestViewSet, testViewNames); + CFReleaseNull(sTestViewSet); + if(testViewNames) { + CFRetainAssign(sTestViewSet, testViewNames); + } + + CFReleaseNull(sosAllViews); + sosAllViews = SOSViewCopyViewSet(kViewSetAll); + CFSetAddValue(sosAllViews, kSOSViewKeychainV0); + if(sTestViewSet) CFSetUnion(sosAllViews, sTestViewSet); } + CFSetRef SOSViewsGetAllCurrent(void) { static dispatch_once_t dot; - static CFMutableSetRef allViews = NULL; dispatch_once(&dot, ^{ - allViews = SOSViewCopyViewSet(kViewSetAll); + sosAllViews = SOSViewCopyViewSet(kViewSetAll); - CFSetAddValue(allViews, kSOSViewKeychainV0); - if(sTestViewSet) CFSetUnion(allViews, sTestViewSet); + CFSetAddValue(sosAllViews, kSOSViewKeychainV0); + if(sTestViewSet) CFSetUnion(sosAllViews, sTestViewSet); }); - return allViews; + return sosAllViews; } static CFDictionaryRef SOSViewsGetBitmasks(void) { @@ -249,8 +267,9 @@ static CFDictionaryRef SOSViewsGetBitmasks(void) { return masks; } -static uint64_t SOSViewBitmaskFromSet(CFSetRef views) { +uint64_t SOSViewBitmaskFromSet(CFSetRef views) { __block uint64_t retval = 0; + if(!views) return retval; CFDictionaryRef masks = SOSViewsGetBitmasks(); if(masks) { CFSetForEach(views, ^(const void *viewName) { @@ -313,6 +332,7 @@ void SOSViewsForEachDefaultEnabledViewName(void (^operation)(CFStringRef viewNam } static bool SOSViewsIsKnownView(CFStringRef viewname) { + if(!viewname) return false; CFSetRef allViews = SOSViewsGetAllCurrent(); if(CFSetContainsValue(allViews, viewname)) return true; secnotice("views","Not a known view"); diff --git a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.h b/keychain/SecureObjectSync/Tool/accountCirclesViewsPrint.h similarity index 100% rename from OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.h rename to keychain/SecureObjectSync/Tool/accountCirclesViewsPrint.h diff --git a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m b/keychain/SecureObjectSync/Tool/accountCirclesViewsPrint.m similarity index 91% rename from OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m rename to keychain/SecureObjectSync/Tool/accountCirclesViewsPrint.m index b6add4ef..96b421a1 100644 --- a/OSX/sec/SOSCircle/Tool/accountCirclesViewsPrint.m +++ b/keychain/SecureObjectSync/Tool/accountCirclesViewsPrint.m @@ -35,18 +35,18 @@ #include #include #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include #include -#include +#include "SecurityTool/sharedTool/readline.h" #include "keychain_log.h" #include "secToolFileIO.h" @@ -97,11 +97,9 @@ getSOSCCLastDepartureReasonDescription(enum DepartureReason reason) } } -static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error)) { +static void printPeerInfos(char *label, CFStringRef mypeerID, CFArrayRef (^copyPeers)(CFErrorRef *error)) { CFErrorRef error = NULL; - CFArrayRef ppi = getArray(&error); - SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL); - CFStringRef mypeerID = SOSPeerInfoGetPeerID(me); + CFArrayRef ppi = copyPeers(&error); if(ppi) { printmsg(CFSTR("%s count: %ld\n"), label, (long)CFArrayGetCount(ppi)); @@ -109,7 +107,6 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error 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); @@ -117,12 +114,14 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error CFStringRef deviceID = CFSTR(""); CFStringRef machineID = CFSTR(""); CFDictionaryRef gestalt = SOSPeerInfoCopyPeerGestalt(peer); - CFStringRef osVersion = CFSTR("Unknown"); + CFStringRef osVersion = NULL; if(gestalt) { osVersion = CFDictionaryGetValue(gestalt, CFSTR("OSVersion")); + } else { + osVersion = CFSTR("Unknown"); } - if(version >= 2){ + if(SOSPeerInfoVersionHasV2Data(peer)){ CFDictionaryRef v2Dictionary = peer->v2Dictionary; if(v2Dictionary) { transportType = CFDictionaryGetValue(v2Dictionary, CFSTR("TransportType")); @@ -132,7 +131,7 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error } char *pname = CFStringToCString(peerName); char *dname = CFStringToCString(devtype); - char *tname = transportType ? CFStringToCString(transportType) : CFStringToCString(CFSTR("KVS")); + char *tname = CFStringToCString(transportType); char *iname = CFStringToCString(deviceID); char *mname = CFStringToCString(machineID); const char *me = CFEqualSafe(mypeerID, peerID) ? "me>" : " "; @@ -160,7 +159,6 @@ static void printPeerInfos(char *label, CFArrayRef (^getArray)(CFErrorRef *error } CFReleaseNull(ppi); CFReleaseNull(error); - CFReleaseNull(me); } void SOSCCDumpCircleInformation() @@ -169,6 +167,7 @@ void SOSCCDumpCircleInformation() CFArrayRef generations = NULL; bool is_accountKeyIsTrusted = false; __block int count = 0; + SOSCCStatus ccstatus = SOSCCThisDeviceIsInCircle(&error); printmsg(CFSTR("ccstatus: %s (%d)\n"), getSOSCCStatusDescription(ccstatus), ccstatus); @@ -210,13 +209,17 @@ void SOSCCDumpCircleInformation() } CFReleaseNull(generations); CFReleaseNull(error); + + SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL); + CFStringRef mypeerID = SOSPeerInfoGetPeerID(me); + + printPeerInfos(" Peers", mypeerID, ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); }); + printPeerInfos(" Invalid", mypeerID, ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); }); + printPeerInfos(" Retired", mypeerID, ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); }); + printPeerInfos(" Concur", mypeerID, ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); }); + printPeerInfos("Applicants", mypeerID, ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); }); - printPeerInfos(" Peers", ^(CFErrorRef *error) { return SOSCCCopyValidPeerPeerInfo(error); }); - printPeerInfos(" Invalid", ^(CFErrorRef *error) { return SOSCCCopyNotValidPeerPeerInfo(error); }); - printPeerInfos(" Retired", ^(CFErrorRef *error) { return SOSCCCopyRetirementPeerInfo(error); }); - printPeerInfos(" Concur", ^(CFErrorRef *error) { return SOSCCCopyConcurringPeerPeerInfo(error); }); - printPeerInfos("Applicants", ^(CFErrorRef *error) { return SOSCCCopyApplicantPeerInfo(error); }); - + CFReleaseNull(me); CFReleaseNull(error); } @@ -237,7 +240,12 @@ SOSCCDumpEngineInformation(void) void SOSCCDumpViewUnwarePeers(void) { - printPeerInfos("view-unaware", ^(CFErrorRef *error) { return SOSCCCopyViewUnawarePeerInfo(error); }); + SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(NULL); + CFStringRef mypeerID = SOSPeerInfoGetPeerID(me); + + printPeerInfos("view-unaware", mypeerID, ^(CFErrorRef *error) { return SOSCCCopyViewUnawarePeerInfo(error); }); + + CFReleaseNull(me); } /* KVS Dumping Support for iCloud Keychain */ diff --git a/OSX/sec/SOSCircle/Tool/keychain_log.h b/keychain/SecureObjectSync/Tool/keychain_log.h similarity index 96% rename from OSX/sec/SOSCircle/Tool/keychain_log.h rename to keychain/SecureObjectSync/Tool/keychain_log.h index e10ab237..713e85fd 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_log.h +++ b/keychain/SecureObjectSync/Tool/keychain_log.h @@ -29,7 +29,7 @@ */ -#include +#include "SecurityTool/sharedTool/security_tool_commands.h" SECURITY_COMMAND( "synclog", keychain_log, diff --git a/keychain/SecureObjectSync/Tool/keychain_log.m b/keychain/SecureObjectSync/Tool/keychain_log.m new file mode 100644 index 00000000..ee601a3e --- /dev/null +++ b/keychain/SecureObjectSync/Tool/keychain_log.m @@ -0,0 +1,134 @@ +// +// keychain_log.c +// sec +// +// Created by Richard Murphy on 1/26/16. +// +// + +#include "keychain_log.h" + +/* + * Copyright (c) 2003-2007,2009-2010,2013-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@ + * + * keychain_add.c + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" +#include +#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" + +#include +#include + +#include "SecurityTool/sharedTool/readline.h" +#include + +#include "keychain_log.h" +#include "secToolFileIO.h" +#include "secViewDisplay.h" +#include "accountCirclesViewsPrint.h" +#include + + +#include + +#define MAXKVSKEYTYPE kUnknownKey +#define DATE_LENGTH 18 + +static bool logmark(const char *optarg) { + if(!optarg) return false; + secnotice("mark", "%s", optarg); + return true; +} + + +// enable, disable, accept, reject, status, Reset, Clear +int +keychain_log(int argc, char * const *argv) +{ + /* + "Keychain Logging" + " -i info (current status)" + " -D [itemName] dump contents of KVS" + " -L list all known view and their status" + " -M string place a mark in the syslog - category \"mark\"" + + */ + SOSLogSetOutputTo(NULL, NULL); + + int ch, result = 0; + CFErrorRef error = NULL; + bool hadError = false; + + while ((ch = getopt(argc, argv, "DiLM:")) != -1) + switch (ch) { + + case 'i': + SOSCCDumpCircleInformation(); + SOSCCDumpEngineInformation(); + break; + + + case 'D': + (void)SOSCCDumpCircleKVSInformation(optarg); + break; + + case 'L': + hadError = !listviewcmd(&error); + break; + + case 'M': + hadError = !logmark(optarg); + break; + + case '?': + default: + return SHOW_USAGE_MESSAGE; + } + + if (hadError) + printerr(CFSTR("Error: %@\n"), error); + + return result; +} diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync.h b/keychain/SecureObjectSync/Tool/keychain_sync.h similarity index 98% rename from OSX/sec/SOSCircle/Tool/keychain_sync.h rename to keychain/SecureObjectSync/Tool/keychain_sync.h index a8918dc6..141de9d9 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync.h +++ b/keychain/SecureObjectSync/Tool/keychain_sync.h @@ -22,7 +22,7 @@ */ -#include +#include "SecurityTool/sharedTool/security_tool_commands.h" SECURITY_COMMAND( "sync", keychain_sync, diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync.m b/keychain/SecureObjectSync/Tool/keychain_sync.m similarity index 98% rename from OSX/sec/SOSCircle/Tool/keychain_sync.m rename to keychain/SecureObjectSync/Tool/keychain_sync.m index 8c013db4..f5172661 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync.m +++ b/keychain/SecureObjectSync/Tool/keychain_sync.m @@ -42,19 +42,19 @@ #include #include #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSPeerInfoPriv.h" +#include "keychain/SecureObjectSync/SOSPeerInfoV2.h" +#include "keychain/SecureObjectSync/SOSUserKeygen.h" +#include "keychain/SecureObjectSync/SOSKVSKeys.h" #include #include #include -#include +#include "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #include #include -#include +#include "SecurityTool/sharedTool/readline.h" #include #include "keychain_sync.h" @@ -78,7 +78,8 @@ static bool clearAllKVS(CFErrorRef *error) dispatch_queue_t processQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0); dispatch_time_t finishTime = dispatch_time(DISPATCH_TIME_NOW, maxTimeToWaitInSeconds); - + + secnotice("circleOps", "security tool called SOSCloudKeychainClearAll to clear KVS"); SOSCloudKeychainClearAll(processQueue, ^(CFDictionaryRef returnedValues, CFErrorRef cerror) { result = (cerror != NULL); diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync_test.h b/keychain/SecureObjectSync/Tool/keychain_sync_test.h similarity index 86% rename from OSX/sec/SOSCircle/Tool/keychain_sync_test.h rename to keychain/SecureObjectSync/Tool/keychain_sync_test.h index 8dfc474c..fad6438a 100644 --- a/OSX/sec/SOSCircle/Tool/keychain_sync_test.h +++ b/keychain/SecureObjectSync/Tool/keychain_sync_test.h @@ -4,7 +4,7 @@ // // -#include +#include "SecurityTool/sharedTool/security_tool_commands.h" SECURITY_COMMAND( "sync-test", keychain_sync_test, diff --git a/OSX/sec/SOSCircle/Tool/keychain_sync_test.m b/keychain/SecureObjectSync/Tool/keychain_sync_test.m similarity index 100% rename from OSX/sec/SOSCircle/Tool/keychain_sync_test.m rename to keychain/SecureObjectSync/Tool/keychain_sync_test.m diff --git a/OSX/sec/SOSCircle/Tool/recovery_key.h b/keychain/SecureObjectSync/Tool/recovery_key.h similarity index 96% rename from OSX/sec/SOSCircle/Tool/recovery_key.h rename to keychain/SecureObjectSync/Tool/recovery_key.h index b4af69df..cb4569d6 100644 --- a/OSX/sec/SOSCircle/Tool/recovery_key.h +++ b/keychain/SecureObjectSync/Tool/recovery_key.h @@ -22,7 +22,7 @@ */ -#include +#include "SecurityTool/sharedTool/security_tool_commands.h" SECURITY_COMMAND( "recovery", recovery_key, diff --git a/OSX/sec/SOSCircle/Tool/recovery_key.m b/keychain/SecureObjectSync/Tool/recovery_key.m similarity index 100% rename from OSX/sec/SOSCircle/Tool/recovery_key.m rename to keychain/SecureObjectSync/Tool/recovery_key.m diff --git a/OSX/sec/SOSCircle/Tool/secToolFileIO.c b/keychain/SecureObjectSync/Tool/secToolFileIO.c similarity index 100% rename from OSX/sec/SOSCircle/Tool/secToolFileIO.c rename to keychain/SecureObjectSync/Tool/secToolFileIO.c diff --git a/OSX/sec/SOSCircle/Tool/secToolFileIO.h b/keychain/SecureObjectSync/Tool/secToolFileIO.h similarity index 100% rename from OSX/sec/SOSCircle/Tool/secToolFileIO.h rename to keychain/SecureObjectSync/Tool/secToolFileIO.h diff --git a/OSX/sec/SOSCircle/Tool/secViewDisplay.c b/keychain/SecureObjectSync/Tool/secViewDisplay.c similarity index 98% rename from OSX/sec/SOSCircle/Tool/secViewDisplay.c rename to keychain/SecureObjectSync/Tool/secViewDisplay.c index ad0b02e2..b3b9e622 100644 --- a/OSX/sec/SOSCircle/Tool/secViewDisplay.c +++ b/keychain/SecureObjectSync/Tool/secViewDisplay.c @@ -43,7 +43,7 @@ static struct foo { #undef DOVIEWMACRO #define DOVIEWMACRO(VIEWNAME, DEFSTRING, CMDSTRING, SYSTEM, DEFAULTSETTING, INITIALSYNCSETTING, ALWAYSONSETTING, BACKUPSETTING, V0SETTING) \ { CMDSTRING, &k##SYSTEM##View##VIEWNAME, }, -#include "Security/SecureObjectSync/ViewList.list" +#include "keychain/SecureObjectSync/ViewList.list" }; static CFStringRef convertStringToView(char *viewname) { diff --git a/OSX/sec/SOSCircle/Tool/secViewDisplay.h b/keychain/SecureObjectSync/Tool/secViewDisplay.h similarity index 100% rename from OSX/sec/SOSCircle/Tool/secViewDisplay.h rename to keychain/SecureObjectSync/Tool/secViewDisplay.h diff --git a/OSX/sec/SOSCircle/Tool/syncbackup.h b/keychain/SecureObjectSync/Tool/syncbackup.h similarity index 95% rename from OSX/sec/SOSCircle/Tool/syncbackup.h rename to keychain/SecureObjectSync/Tool/syncbackup.h index 90510dca..ccacc3c3 100644 --- a/OSX/sec/SOSCircle/Tool/syncbackup.h +++ b/keychain/SecureObjectSync/Tool/syncbackup.h @@ -29,7 +29,7 @@ // -#include +#include "SecurityTool/sharedTool/security_tool_commands.h" SECURITY_COMMAND( "syncbackup", syncbackup, diff --git a/OSX/sec/SOSCircle/Tool/syncbackup.m b/keychain/SecureObjectSync/Tool/syncbackup.m similarity index 96% rename from OSX/sec/SOSCircle/Tool/syncbackup.m rename to keychain/SecureObjectSync/Tool/syncbackup.m index d2f13955..5216ad19 100644 --- a/OSX/sec/SOSCircle/Tool/syncbackup.m +++ b/keychain/SecureObjectSync/Tool/syncbackup.m @@ -38,13 +38,13 @@ #include #include -#include -#include +#include "keychain/SecureObjectSync/SOSBackupInformation.h" +#include "keychain/SecureObjectSync/SOSRecoveryKeyBag.h" #include #include -#include +#include "SecurityTool/sharedTool/readline.h" #include "secToolFileIO.h" diff --git a/OSX/sec/SOSCircle/SecureObjectSync/ViewList.list b/keychain/SecureObjectSync/ViewList.list similarity index 87% rename from OSX/sec/SOSCircle/SecureObjectSync/ViewList.list rename to keychain/SecureObjectSync/ViewList.list index 19b3cdd6..6f262578 100644 --- a/OSX/sec/SOSCircle/SecureObjectSync/ViewList.list +++ b/keychain/SecureObjectSync/ViewList.list @@ -20,25 +20,25 @@ DOVIEWMACRO(WiFi, "WiFi", "wifi", SOS, , , , , V) DOVIEWMACRO(AutofillPasswords, "Passwords", "passwords", SOS, , , , , V) DOVIEWMACRO(SafariCreditCards, "CreditCards", "creditcards", SOS, , , , , V) -DOVIEWMACRO(iCloudIdentity, "iCloudIdentity", "icloudidentity", SOS, D, I, A, B, V) -DOVIEWMACRO(BackupBagV0, "BackupBagV0", "backupv0", SOS, D, I, A, , V) +DOVIEWMACRO(iCloudIdentity, "iCloudIdentity", "icloudidentity", SOS, D, , A, B, V) +DOVIEWMACRO(BackupBagV0, "BackupBagV0", "backupv0", SOS, D, , A, , V) DOVIEWMACRO(OtherSyncable, "OtherSyncable", "othersyncable", SOS, , , , , V) DOVIEWMACRO(ContinuityUnlock, "ContinuityUnlock", "continuityunlock", SOS, D, , A, , ) DOVIEWMACRO(AppleTV, "AppleTV", "appletv", SOS, D, , A, , ) DOVIEWMACRO(HomeKit, "HomeKit", "homekit", SOS, D, , A, , ) DOVIEWMACRO(AccessoryPairing, "AccessoryPairing", "accessorypairing", SOS, D, , A, , ) -DOVIEWMACRO(PCSCloudKit, "PCS-CloudKit", "cloudkit", SOS, D, I, A, , ) -DOVIEWMACRO(PCSEscrow, "PCS-Escrow", "escrow", SOS, D, I, A, B, ) -DOVIEWMACRO(PCSFDE, "PCS-FDE", "fde", SOS, D, I, A, , ) -DOVIEWMACRO(PCSFeldspar, "PCS-Feldspar", "feldspar", SOS, D, I, A, , ) -DOVIEWMACRO(PCSMailDrop, "PCS-Maildrop", "maildrop", SOS, D, I, A, , ) -DOVIEWMACRO(PCSMasterKey, "PCS-MasterKey", "masterkey", SOS, D, I, A, B, ) -DOVIEWMACRO(PCSNotes, "PCS-Notes", "notes", SOS, D, I, A, , ) -DOVIEWMACRO(PCSPhotos, "PCS-Photos", "photos", SOS, D, I, A, , ) -DOVIEWMACRO(PCSSharing, "PCS-Sharing", "sharing", SOS, D, I, A, , ) -DOVIEWMACRO(PCSiCloudBackup, "PCS-Backup", "icloudbackup", SOS, D, I, A, , ) -DOVIEWMACRO(PCSiCloudDrive, "PCS-iCloudDrive", "iclouddrive", SOS, D, I, A, , ) -DOVIEWMACRO(PCSiMessage, "PCS-iMessage", "imessage", SOS, D, I, A, , ) +DOVIEWMACRO(PCSCloudKit, "PCS-CloudKit", "cloudkit", SOS, D, , A, , ) +DOVIEWMACRO(PCSEscrow, "PCS-Escrow", "escrow", SOS, D, , A, B, ) +DOVIEWMACRO(PCSFDE, "PCS-FDE", "fde", SOS, D, , A, , ) +DOVIEWMACRO(PCSFeldspar, "PCS-Feldspar", "feldspar", SOS, D, , A, , ) +DOVIEWMACRO(PCSMailDrop, "PCS-Maildrop", "maildrop", SOS, D, , A, , ) +DOVIEWMACRO(PCSMasterKey, "PCS-MasterKey", "masterkey", SOS, D, , A, B, ) +DOVIEWMACRO(PCSNotes, "PCS-Notes", "notes", SOS, D, , A, , ) +DOVIEWMACRO(PCSPhotos, "PCS-Photos", "photos", SOS, D, , A, , ) +DOVIEWMACRO(PCSSharing, "PCS-Sharing", "sharing", SOS, D, , A, , ) +DOVIEWMACRO(PCSiCloudBackup, "PCS-Backup", "icloudbackup", SOS, D, , A, , ) +DOVIEWMACRO(PCSiCloudDrive, "PCS-iCloudDrive", "iclouddrive", SOS, D, , A, , ) +DOVIEWMACRO(PCSiMessage, "PCS-iMessage", "imessage", SOS, D, , A, , ) DOVIEWMACRO(NanoRegistry, "NanoRegistry", "nanoregistry", SOS, D, , A, , ) DOVIEWMACRO(WatchMigration, "WatchMigration", "watchmigration", SOS, D, , A, , ) DOVIEWMACRO(Engram, "Engram", "engram", CKKS, D, , A, , ) diff --git a/MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist b/keychain/SecurityUnitTests/Info.plist similarity index 100% rename from MultiDeviceSimulator/MultiDeviceSimulatorTests/Info.plist rename to keychain/SecurityUnitTests/Info.plist diff --git a/keychain/SecurityUnitTests/SecItemTests.m b/keychain/SecurityUnitTests/SecItemTests.m new file mode 100644 index 00000000..998dc16b --- /dev/null +++ b/keychain/SecurityUnitTests/SecItemTests.m @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2019 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 + +@interface SecItemTests : XCTestCase + +@end + +@implementation SecItemTests + +- (void)setUp { + [self deleteAll]; +} + +- (void)tearDown { + [self deleteAll]; +} + + + +- (void)testAddGenericPassword { + NSDictionary *attrs; + + attrs = [self addGenericPassword:@"delete-me" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + XCTAssertNil(attrs[@"OSStatus"], "should have no error"); +} + +- (void)testAddTwoGenericPassword { + NSDictionary *attrs; + + attrs = [self addGenericPassword:@"delete-me" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + XCTAssertNil(attrs[@"OSStatus"], "should have no error"); + + attrs = [self addGenericPassword:@"delete-me2s" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + XCTAssertNil(attrs[@"OSStatus"], "should have no error"); +} + +- (void)testAddCollidingGenericPassword { + NSDictionary *attrs; + + attrs = [self addGenericPassword:@"delete-me" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + + attrs = [self addGenericPassword:@"delete-me" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + XCTAssertEqual(attrs[@"OSStatus"], @(errSecDuplicateItem), "should have duplicate item"); +} + + +- (void)testMoveGenericPassword { + NSDictionary *attrs; + + attrs = [self addGenericPassword:@"delete-me" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + + attrs = [self addGenericPassword:@"delete-me" service:@"delete-me"]; + XCTAssertNotNil(attrs, "should create genp"); + XCTAssertEqual(attrs[@"OSStatus"], @(errSecDuplicateItem), "should have duplicate item"); + + XCTAssertEqual([self moveGenericPassword:@"delete-me" service:@"delete-me" + newAccount:@"delete-me2" newService:@"delete-me2"], + noErr); + + XCTAssertEqual([self moveGenericPassword:@"delete-me" service:@"delete-me" + newAccount:@"delete-me2" newService:@"delete-me2"], + errSecItemNotFound); + +} + +//-MARK: helper functions + +- (void)deleteAll { + NSDictionary *allGenericPassword = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecUseDataProtectionKeychain : @(YES), + }; + (void)SecItemDelete((__bridge CFDictionaryRef)allGenericPassword); +} + + +- (NSDictionary *)addGenericPassword:(NSString *)account service:(NSString *)service +{ + NSDictionary* addQuery = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : account, + (id)kSecAttrService : service, + (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, + (id)kSecUseDataProtectionKeychain : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + CFTypeRef result = NULL; + + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)addQuery, &result); + if (status != 0) { + return @{ @"OSStatus": @(status) }; + } + if (result == NULL) { + return NULL; + } + if (CFGetTypeID(result) != CFDictionaryGetTypeID()) { + CFRelease(result); + return NULL; + } + + return (__bridge NSDictionary *)result; +} + + +- (OSStatus)moveGenericPassword:(NSString *)account service:(NSString *)service + newAccount:(NSString *)newAccount newService:(NSString *)newService +{ + NSDictionary* updateQuery = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : account, + (id)kSecAttrService : service, + (id)kSecAttrAccessible : (id)kSecAttrAccessibleAfterFirstUnlock, + (id)kSecUseDataProtectionKeychain : @(YES), + (id)kSecReturnAttributes : @(YES), + }; + NSDictionary *newAttributes = @{ + (id)kSecAttrAccount : newAccount, + (id)kSecAttrService : newService, + }; + + OSStatus status = SecItemUpdate((__bridge CFDictionaryRef)updateQuery, (__bridge CFDictionaryRef)newAttributes); + return status; +} + + +@end diff --git a/SecurityUnitTests/SecurityUnitTests.m b/keychain/SecurityUnitTests/SecKeyTests.m similarity index 96% rename from SecurityUnitTests/SecurityUnitTests.m rename to keychain/SecurityUnitTests/SecKeyTests.m index 0f5fe403..97348ac5 100644 --- a/SecurityUnitTests/SecurityUnitTests.m +++ b/keychain/SecurityUnitTests/SecKeyTests.m @@ -23,10 +23,10 @@ #import -@interface SecurityUnitTests : XCTestCase +@interface SecKeyTests : XCTestCase @end -@implementation SecurityUnitTests +@implementation SecKeyTests - (void)testSecKeyAttributesCanBeReadWithMatchingStringsAsKeys { diff --git a/keychain/SecurityUnitTests/SecurityUnitTests.entitlements b/keychain/SecurityUnitTests/SecurityUnitTests.entitlements new file mode 100644 index 00000000..e9828b04 --- /dev/null +++ b/keychain/SecurityUnitTests/SecurityUnitTests.entitlements @@ -0,0 +1,10 @@ + + + + + keychain-access-groups + + com.apple.security.securityUnitTests + + + diff --git a/keychain/Signin Metrics/SFSignInAnalytics.m b/keychain/Signin Metrics/SFSignInAnalytics.m index d134231e..3b079c97 100644 --- a/keychain/Signin Metrics/SFSignInAnalytics.m +++ b/keychain/Signin Metrics/SFSignInAnalytics.m @@ -27,14 +27,14 @@ #import "SFSignInAnalytics+Internal.h" #import -#import "SFAnalyticsDefines.h" -#import "SFAnalyticsSQLiteStore.h" -#import "SFAnalytics.h" +#import "Analytics/SFAnalyticsDefines.h" +#import "Analytics/SFAnalyticsSQLiteStore.h" +#import "Analytics/SFAnalytics.h" #import #import #import -#import +#import "utilities/debugging.h" #import //metrics database location @@ -55,6 +55,7 @@ static NSString* const SFSignInAnalyticsAttributeSignInUUID = @"signinUUID"; static NSString* const SFSignInAnalyticsAttributeEventName = @"eventName"; static NSString* const SFSignInAnalyticsAttributeSubsystemName = @"subsystemName"; static NSString* const SFSignInAnalyticsAttributeBuiltDependencyChains = @"dependencyChains"; +static NSString* const SFSignInAnalyticsAttributeTrackerTime = @"trackerTime"; @implementation SFSIALoggerObject + (NSString*)databasePath { @@ -157,9 +158,11 @@ static const NSString* signInLogSpace = @"com.apple.security.wiiss"; _stopped = NO; _builtDependencyChains = [NSMutableArray array]; - //make plist file containing uuid parent/child - _persistencePath = [NSString stringWithFormat:@"%@-%@.plist", SFSignInAnalyticsPersistedEventList, eventName]; - _persistedEventPlist = [NSURL fileURLWithPath:_persistencePath isDirectory:NO]; + if ([self writeResultsToTmp]) { + //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]; @@ -168,7 +171,8 @@ static const NSString* signInLogSpace = @"com.apple.security.wiiss"; [_tracker start]; NSError* error = nil; - if(![self writeDependencyList:&error]){ + + if(self.root.persistedEventPlist && ![self writeDependencyList:&error] ){ os_log(self.logObject, "attempting to write dependency list: %@", error); } @@ -266,7 +270,7 @@ static const NSString* signInLogSpace = @"com.apple.security.wiiss"; //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]){ + if(self.root.persistedEventPlist && ![newSubTask writeDependencyList:&error] ){ os_log(self.logObject, "attempting to write dependency list: %@", error); } } @@ -361,6 +365,7 @@ static const NSString* signInLogSpace = @"com.apple.security.wiiss"; mutableAttributes[SFSignInAnalyticsAttributeSignInUUID] = self.signin_uuid; mutableAttributes[SFSignInAnalyticsAttributeEventName] = self.eventName; mutableAttributes[SFSignInAnalyticsAttributeSubsystemName] = self.category; + mutableAttributes[SFSignInAnalyticsAttributeTrackerTime] = self.tracker.measurement; [mutableAttributes enumerateKeysAndObjectsUsingBlock:^(NSString* key, id obj, BOOL * stop) { os_log(self.logObject, "event: %@, %@ : %@", self.eventName, key, obj); @@ -421,8 +426,7 @@ static const NSString* signInLogSpace = @"com.apple.security.wiiss"; [[SFSIALoggerObject logger] logSoftFailureForEventNamed:SFSignInAnalyticsAttributeBuiltDependencyChains withAttributes:eventAttributes]; } - BOOL writingToTmp = [self writeResultsToTmp]; - if(writingToTmp){ //writing sign in analytics to /tmp + if([self writeResultsToTmp]){ //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]; @@ -437,17 +441,18 @@ static const NSString* signInLogSpace = @"com.apple.security.wiiss"; }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); + if (self.persistencePath) { + //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 diff --git a/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m b/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m index b9db4c95..8cafd23f 100644 --- a/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m +++ b/keychain/Signin Metrics/tests/SFSignInAnalyticsTests.m @@ -103,7 +103,7 @@ static NSString* _path; - (void)testLogError { - NSError* error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + 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"); @@ -493,7 +493,7 @@ static NSString* _path; - (void)testMultipleDBConnections { - NSError* error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + 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++){ diff --git a/keychain/Trieste/OctagonTestHarness/Info.plist b/keychain/Trieste/OctagonTestHarness/Info.plist new file mode 100644 index 00000000..e1fe4cfb --- /dev/null +++ b/keychain/Trieste/OctagonTestHarness/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.exp b/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.exp new file mode 100644 index 00000000..c4dd9558 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.exp @@ -0,0 +1,4 @@ +_FrameworkFacadeProtocol +_OBJC_CLASS_$_OctagonTestHarnessLoader +_OctagonTestHarnessVersionNumber +_OctagonTestHarnessVersionString diff --git a/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.h b/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.h new file mode 100644 index 00000000..4d91823d --- /dev/null +++ b/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.h @@ -0,0 +1,23 @@ +// +// OctagonTestHarness.h +// Security +// +// Copyright (c) 2018 - 2019 Apple Inc. All rights reserved. +// + +#import + +//! Project version number for OctagonTestHarness. +FOUNDATION_EXPORT double OctagonTestHarnessVersionNumber; + +//! Project version string for OctagonTestHarness. +FOUNDATION_EXPORT const unsigned char OctagonTestHarnessVersionString[]; + +// In this header, you should import all the public headers of your framework using statements like #import + +extern Protocol *FrameworkFacadeProtocol; + +@interface OctagonTestHarnessLoader : NSObject +@end + + diff --git a/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.m b/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.m new file mode 100644 index 00000000..e28a8230 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarness/OctagonTestHarness.m @@ -0,0 +1,18 @@ +// +// OctagonTestHarness.c +// Security +// +// Copyright (c) 2019 Apple Inc. All rights reserved. +// + +#import +#import "OctagonTestHarness.h" +#import "OctagonTestHarnessXPCServiceProtocol.h" + +Protocol *FrameworkFacadeProtocol = nil; + +@implementation OctagonTestHarnessLoader ++ (void)load { + FrameworkFacadeProtocol = @protocol(OctagonTestHarnessXPCServiceProtocol); +} +@end diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/Entitlements.plist b/keychain/Trieste/OctagonTestHarnessXPCService/Entitlements.plist new file mode 100644 index 00000000..f8ec5419 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/Entitlements.plist @@ -0,0 +1,12 @@ + + + + + application-identifier + com.apple.trieste.SecurityTestHarnessXPCService + com.apple.private.ckks + + com.apple.private.octagon + + + diff --git a/MultiDeviceSimulator/DeviceSimulator/Info.plist b/keychain/Trieste/OctagonTestHarnessXPCService/Info.plist similarity index 87% rename from MultiDeviceSimulator/DeviceSimulator/Info.plist rename to keychain/Trieste/OctagonTestHarnessXPCService/Info.plist index 612cb515..69478a7c 100644 --- a/MultiDeviceSimulator/DeviceSimulator/Info.plist +++ b/keychain/Trieste/OctagonTestHarnessXPCService/Info.plist @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - DeviceSimulator + OctagonTestHarnessXPCService CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -24,10 +24,6 @@ ServiceType Application - _MultipleInstances - - JoinExistingSession - diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.h b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.h new file mode 100644 index 00000000..db2714a0 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.h @@ -0,0 +1,7 @@ +// Copyright (c) 2018 Apple Inc. All rights reserved. + +#import +#import "OctagonTestHarnessXPCServiceProtocol.h" + +@interface OctagonTestHarnessXPCService : NSObject +@end diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.m b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.m new file mode 100644 index 00000000..235da5d3 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCService.m @@ -0,0 +1,58 @@ +// Copyright (c) 2018 Apple Inc. All rights reserved. + +#import "OctagonTestHarnessXPCService.h" + +#import +#import +#import +#import "SecDbKeychainItem.h" +#import "SecRemoteDevice.h" +#import "OTControl.h" + +@interface OctagonTestHarnessXPCService () +@property (strong) SecRemoteDevice *remoteDevice; +@end + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wprotocol" + +@implementation OctagonTestHarnessXPCService + +- (instancetype)init { + if ((self = [super init]) != NULL) { + self.remoteDevice = [SecRemoteDevice new]; + if (self.remoteDevice == nil) { + return nil; + } + } + return self; +} + +- (void)octagonReset:(NSString *)altDSID complete:(void (^)(NSNumber *, NSError *))complete { + NSError *error = nil; + + OTControl* rpc = [OTControl controlObject:true error:&error]; + if (rpc == nil) { + complete(@NO, error); + + return; + } + + [rpc resetAndEstablish:NULL context:OTDefaultContext altDSID:altDSID reply:^(NSError * _Nullable e) { + complete([NSNumber numberWithBool:e != NULL], e); + }]; +} + +/* Oh, ObjC, you are my friend */ +- (void)forwardInvocation:(NSInvocation *)invocation { + struct objc_method_description desc = protocol_getMethodDescription(@protocol(SecRemoteDeviceProtocol), [invocation selector], true, true); + if (desc.name == NULL) { + [super forwardInvocation:invocation]; + } else { + [invocation invokeWithTarget:self.remoteDevice]; + } +} + +@end + +#pragma clang diagnostic pop diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.h b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.h new file mode 100644 index 00000000..e8ffaa89 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.h @@ -0,0 +1,12 @@ +// +// OctagonTestHarnessXPCServiceDelegate.h +// Security +// +// Copyright (c) 2018 Apple Inc. All rights reserved. +// + +#import + +@interface OctagonTestHarnessXPCServiceDelegate : NSObject + +@end diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.m b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.m new file mode 100644 index 00000000..5d513634 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/OctagonTestHarnessXPCServiceDelegate.m @@ -0,0 +1,29 @@ +// +// OctagonTestHarnessXPCService.h +// Security +// +// Copyright (c) 2018 Apple Inc. All rights reserved. +// + +#import +#import "OctagonTestHarnessXPCService.h" +#import "OctagonTestHarnessXPCServiceDelegate.h" +#import "OctagonTestHarnessXPCServiceProtocol.h" + +@implementation OctagonTestHarnessXPCServiceDelegate + +- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection +{ +#if OCTAGON + newConnection.exportedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(OctagonTestHarnessXPCServiceProtocol)]; + newConnection.exportedObject = [OctagonTestHarnessXPCService new]; + + [newConnection resume]; + + return YES; +#else // OCTAGON + return NO; +#endif // OCTAGON +} + +@end diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.h b/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.h new file mode 100644 index 00000000..a5b0594d --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2017 - 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 "SecRemoteDeviceProtocol.h" + +// 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 SecRemoteDevice : NSObject +@property NSString *name; +@end diff --git a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m b/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.m similarity index 50% rename from MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m rename to keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.m index 5e7603af..d35615a5 100644 --- a/MultiDeviceSimulator/DeviceSimulator/DeviceSimulator.m +++ b/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDevice.m @@ -1,7 +1,26 @@ -// -// DeviceSimulator.m -// DeviceSimulator -// +/* + * Copyright (c) 2017 - 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 @@ -9,41 +28,86 @@ #import #import #import -#import +#import "keychain/SecureObjectSync/SOSTypes.h" +#import "keychain/SecureObjectSync/SOSInternal.h" +#import "keychain/SecureObjectSync/SOSAuthKitHelpers.h" +#import "OSX/sec/Security/SecItemShim.h" #import #import #import #import "keychain/ckks/CKKS.h" -#import "SOSCloudKeychainClient.h" - -#import "DeviceSimulatorProtocol.h" -#import "DeviceSimulator.h" - +#import "keychain/ot/OTManager.h" +#import "keychain/ot/OT.h" +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" +#import "keychain/SecureObjectSync/SOSControlServer.h" +#import "KeychainCircle/PairingChannel.h" + +#import "SharedMocks/NSXPCConnectionMock.h" + +#import "SecRemoteDeviceProtocol.h" +#import "SecRemoteDevice.h" + +@interface DevicePairingSimulator : NSObject +@property KCPairingChannelContext *remoteVersionContext; +@property KCPairingChannel *channel; +@property SecRemoteDevice *device; +@property (assign) bool initiator; +@property (assign) bool haveHandshakeCompleted; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initAsInitiator:(bool)initiator version:(KCPairingChannelContext *)peerVersionContext device:(SecRemoteDevice *)device; +@end -@implementation DeviceSimulator +@implementation DevicePairingSimulator -- (void)setDevice:(NSString *)name - version:(NSString *)version - model:(NSString *)model - testInstance:(NSString *)testUUID - network:(NSXPCListenerEndpoint *)network - complete:(void(^)(BOOL success))complete +- (instancetype)initAsInitiator:(bool)initiator version:(KCPairingChannelContext *)peerVersionContext device:(SecRemoteDevice *)device { - self.name = name; + self = [super init]; + if (self) { + self.remoteVersionContext = peerVersionContext; + self.initiator = initiator; + self.device = device; + self.channel = [[KCPairingChannel alloc] initAsInitiator:initiator version:peerVersionContext]; +#if SECD_SERVER + [self.channel setXPCConnectionObject:(NSXPCConnection *)[[NSXPCConnectionMock alloc] initWithRealObject:SOSControlServerInternalClient()]]; +#endif + } - SecCKKSDisable(); // for now - SecCKKSContainerName = [NSString stringWithFormat:@"com.apple.test.p01.B.%@.com.apple.security.keychain", testUUID]; + return self; +} - SOSCCSetGestalt_Server((__bridge CFStringRef)name, (__bridge CFStringRef)version, - (__bridge CFStringRef)model, (__bridge CFStringRef)deviceInstance); +- (void)exchangePacket:(NSData *)data complete:(void (^)(bool complete, NSData *result, NSError *error))complete +{ + os_log(NULL, "[%@] exchangePacket", self.device.name); - boot_securityd(network); + if (self.haveHandshakeCompleted || self.channel == NULL) { + abort(); + } + [self.channel exchangePacket:data complete:^void(BOOL handshakeComplete, NSData *packet, NSError *error) { + self.haveHandshakeCompleted = handshakeComplete; + os_log(NULL, "[%@] exchangePacket:complete: %d", self.device.name, handshakeComplete); + complete(handshakeComplete, packet, error); + }]; +} - complete(TRUE); +- (void)validateStart:(void(^)(bool result, NSError *error))complete +{ + if (self.channel == NULL) { + abort(); + } + [self.channel validateStart:^(bool result, NSError *error) { + complete(result, error); + }]; } +@end + +@implementation SecRemoteDevice - (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary *))reply { @@ -82,6 +146,16 @@ reply(status, result); } +- (void)setUserCredentials:(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); + complete(result, (__bridge NSError *)cferror); + CFReleaseNull(cferror); +} + - (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete { CFErrorRef cferror = NULL; @@ -89,10 +163,7 @@ (__bridge CFDataRef)[password dataUsingEncoding:NSUTF8StringEncoding], CFSTR("1"), &cferror); if (result) { - SOSCCStatus circleStat = SOSCCThisDeviceIsInCircle(&cferror); - if (circleStat == kSOSCCCircleAbsent) { - result = SOSCCResetToOffering(&cferror); - } + result = SOSCCResetToOffering(&cferror); } complete(result, (__bridge NSError *)cferror); CFReleaseNull(cferror); @@ -148,6 +219,33 @@ CFReleaseNull(peerInfo); } +- (void)sosPeerSerial:(void(^)(NSString * _Nullable peerSerial))complete { + CFErrorRef cferror = NULL; + CFStringRef peerSerial = NULL; + SOSPeerInfoRef peerInfo = SOSCCCopyMyPeerInfo(&cferror); + if (peerInfo) + peerSerial = SOSPeerInfoCopySerialNumber(peerInfo); + complete((__bridge NSString *)peerSerial); + CFReleaseNull(peerSerial); + CFReleaseNull(peerInfo); +} + +- (void)sosCirclePeerIDs:(void (^)(NSArray *))complete +{ + CFErrorRef error = NULL; + NSArray *array = CFBridgingRelease(SOSCCCopyConcurringPeerPeerInfo(&error)); + NSMutableArray *peerIDs = [NSMutableArray new]; + + if (array) { + [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + SOSPeerInfoRef peerInfo = (__bridge SOSPeerInfoRef)obj; + NSString *peerID = (__bridge NSString *)SOSPeerInfoGetPeerID(peerInfo); + [peerIDs addObject:peerID]; + }]; + } + complete(peerIDs); +} + - (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError *error))complete { CFErrorRef cferror = NULL; @@ -227,6 +325,22 @@ CFReleaseNull(cferror); } +- (void)sosGhostBust:(SOSAccountGhostBustingOptions)options complete:(void(^)(bool busted, NSError *error))complete { + os_log(NULL, "[%@] sosGhostBust", self.name); + SOSCCGhostBust(options, ^(bool busted, NSError *error) { + os_log(NULL, "[%@] sosGhostBust: %sbusted error: %@", self.name, busted ? "" : "no ", error); + complete(busted, error); + }); +} + +- (void)sosCircleHash: (void(^)(NSString *data, NSError * _Nullable error))complete +{ + NSError *error = NULL; + NSString *hash = SOSCCCircleHash(&error); + complete(hash, error); +} + + - (void)sosWaitForInitialSync:(void(^)(bool success, NSError *error))complete { CFErrorRef cferror = NULL; @@ -252,9 +366,29 @@ complete(result); } +- (void) deviceInfo:(nonnull void (^)(NSString * _Nullable, NSString * _Nullable, NSError * _Nullable))complete { +#if SECD_SERVER + __block NSString *deviceSerial = @""; + [self sosPeerSerial:^(NSString * _Nullable peerSerial) { + deviceSerial = peerSerial; + }]; + complete([SOSAuthKitHelpers machineID], deviceSerial, NULL); +#else + complete(@"", @"", NULL); +#endif + +} -//PRAGMA mark: - Diagnostics +// MARK: - Pairing + +- (void)pairingChannelSetup:(bool)initiator pairingContext:(KCPairingChannelContext *)context complete:(void (^)(id, NSError *))complete { + + DevicePairingSimulator *pairingSim = [[DevicePairingSimulator alloc] initAsInitiator:initiator version:context device:self]; + complete(pairingSim, nil); +} + +// MARK: - Diagnostics - (void)diagnosticsLeaks:(void(^)(bool success, NSString *outout, NSError *error))complete { @@ -282,4 +416,74 @@ } } +// MARK: - CKKS +- (void)selfPeersForView:(NSString *)view complete:(void (^)(NSArray *result, NSError *error))complete +{ + complete(@[], NULL); +} + +// MARK: - Octagon +- (void)otReset:(NSString *)altDSID complete:(void (^)(bool success, NSError *_Nullable error))complete +{ +#if OCTAGON + OTControl *ot = [self OTControl]; + + [ot resetAndEstablish:nil context:OTDefaultContext altDSID:altDSID reply:^(NSError * _Nullable error) { + complete(error == NULL, error); + }]; +#else + complete(false, [self octagonNotAvailableError]); +#endif +} + +- (void)otPeerID:(NSString *)altDSID complete:(void (^)(NSString *peerID, NSError *_Nullable error))complete +{ +#if OCTAGON + OTControl *ot = [self OTControl]; + [ot fetchEgoPeerID:nil context:OTDefaultContext reply:^(NSString * _Nullable peerID, NSError * _Nullable error) { + complete(peerID, error); + }]; +#else + complete(false, [self octagonNotAvailableError]); +#endif + +} + +- (void)otInCircle:(NSString *)altDSID complete:(void (^)(bool inCircle, NSError *_Nullable error))complete +{ +#if OCTAGON + OTControl *ot = [self OTControl]; + OTOperationConfiguration *configuration = [[OTOperationConfiguration alloc] init]; + [ot fetchCliqueStatus:nil context:OTDefaultContext configuration:configuration reply:^(CliqueStatus cliqueStatus, NSError * _Nullable error) { + os_log(NULL, "[%@] otInCircle: clique: %d error: %@", self.name, (int)cliqueStatus, error); + complete(cliqueStatus == CliqueStatusIn, error); + }]; +#else + complete(false, [self octagonNotAvailableError]); +#endif +} + + +//MARK: - Misc helpers + +#if OCTAGON + +- (OTControl *)OTControl +{ +#if SECD_SERVER + return [[OTControl alloc] initWithConnection:(NSXPCConnection *)[[NSXPCConnectionMock alloc] initWithRealObject:[OTManager manager]] sync:true]; +#else + NSError *error = NULL; + return [OTControl controlObject:true error:&error]; +#endif +} + +#else /* !OCTAGON */ + +- (NSError *)octagonNotAvailableError +{ + return [NSError errorWithDomain:@"DeviceSimulator" code:1 description:@"no octagon available"]; +} +#endif + @end diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDeviceProtocol.h b/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDeviceProtocol.h new file mode 100644 index 00000000..b2194038 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/SecRemoteDeviceProtocol.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2017 - 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 + +NS_ASSUME_NONNULL_BEGIN + +@class KCPairingChannelContext; + +@protocol DevicePairingProtocol +- (void)exchangePacket:(NSData *_Nullable)data complete:(void (^)(bool complete, NSData *_Nullable result, NSError *_Nullable error))complete; +- (void)validateStart:(void(^)(bool result, NSError * _Nullable error))complete; +@end + +@protocol SecRemoteDeviceProtocol + +// Local Keychain +- (void)secItemAdd:(NSDictionary *)input complete:(void (^)(OSStatus, NSDictionary * _Nullable))reply; +- (void)secItemCopyMatching:(NSDictionary *)input complete:(void (^)(OSStatus, NSArray* _Nullable))replyreply; + +// SOS trust +- (void)setUserCredentials:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *error))complete; +- (void)setupSOSCircle:(NSString *)username password:(NSString *)password complete:(void (^)(bool success, NSError *_Nullable error))complete; +- (void)sosCircleStatus:(void(^)(SOSCCStatus status, NSError *_Nullable error))complete; +- (void)sosCircleStatusNonCached:(void(^)(SOSCCStatus status, NSError *_Nullable error))complete; +- (void)sosViewStatus:(NSString *) view withCompletion: (void(^)(SOSViewResultCode status, NSError * _Nullable error))complete; +- (void)sosICKStatus: (void(^)(bool status))complete; +- (void)sosCachedViewBitmask: (void(^)(uint64_t bitmask))complete; +- (void)sosPeerID:(void(^)(NSString * _Nullable peerID))complete; +- (void)sosPeerSerial:(void(^)(NSString * _Nullable peerSerial))complete; +- (void)sosCirclePeerIDs:(void(^)(NSArray * _Nullable peerIDs))complete; +- (void)sosRequestToJoin:(void(^)(bool success, NSString *peerID, NSError * _Nullable error))complete; +- (void)sosLeaveCircle: (void(^)(bool success, NSError * _Nullable error))complete; +- (void)sosApprovePeer:(NSString *)peerID complete:(void(^)(BOOL success, NSError * _Nullable error))complete; +- (void)sosGhostBust:(SOSAccountGhostBustingOptions)options complete:(void(^)(bool busted, NSError *error))complete; +- (void)sosCircleHash: (void(^)(NSString *data, NSError * _Nullable error))complete; + + +// SOS syncing +- (void)sosWaitForInitialSync:(void(^)(bool success, NSError * _Nullable error))complete; +- (void)sosEnableAllViews:(void(^)(BOOL success, NSError * _Nullable error))complete; + +// IdMS interface +- (void)deviceInfo:(void (^)(NSString *_Nullable mid, NSString *_Nullable serial, NSError * _Nullable error))complete; + +// Pairing +- (void)pairingChannelSetup:(bool)initiator pairingContext:(KCPairingChannelContext * _Nullable)context complete:(void (^)(id _Nullable, NSError * _Nullable error))complete; + +// Diagnostics +- (void)diagnosticsLeaks:(void(^)(bool success, NSString *_Nullable outout, NSError * _Nullable error))complete; +- (void)diagnosticsCPUUsage:(void(^)(bool success, uint64_t user_usec, uint64_t sys_usec, NSError *_Nullable error))complete; +- (void)diagnosticsDiskUsage:(void(^)(bool success, uint64_t usage, NSError * _Nullable error))complete; + +// CKKS +- (void)selfPeersForView:(NSString *)view complete:(void (^)(NSArray *result, NSError *error))complete; + +// Octagon +- (void)otReset:(NSString *)altDSID complete:(void (^)(bool success, NSError *_Nullable error))complete; + +- (void)otPeerID:(NSString *)altDSID complete:(void (^)(NSString *peerID, NSError *_Nullable error))complete; +- (void)otInCircle:(NSString *)altDSID complete:(void (^)(bool inCircle, NSError *_Nullable error))complete; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/Trieste/OctagonTestHarnessXPCService/main.m b/keychain/Trieste/OctagonTestHarnessXPCService/main.m new file mode 100644 index 00000000..ceca97a8 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCService/main.m @@ -0,0 +1,38 @@ +// +// main.m +// Security +// +// Copyright (c) 2018 Apple Inc. All rights reserved. +// + +#import +#import +#import +#import + +#import "OctagonTestHarnessXPCServiceDelegate.h" + +static OctagonTestHarnessXPCServiceDelegate *delegate = nil; +static NSXPCListener *listener =nil; + +int main(int argc, const char *argv[]) { + + @autoreleasepool { + if (!SecIsInternalRelease()) { + NSLog(@"not internal device"); + return 1; + } + + delegate = [[OctagonTestHarnessXPCServiceDelegate alloc] init]; + listener = [[NSXPCListener alloc] initWithMachServiceName:@"com.apple.trieste.OctagonTestHarnessXPCService"]; + + listener.delegate = delegate; + + NSLog(@"Done listener initialization, resuming"); + + [listener resume]; + } + [[NSRunLoop mainRunLoop] run]; + + return 0; +} diff --git a/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Info.plist b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Info.plist new file mode 100644 index 00000000..e1fe4cfb --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + + diff --git a/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Package.swift b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Package.swift new file mode 100644 index 00000000..2d0a4d44 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Package.swift @@ -0,0 +1,15 @@ +// swift-tools-version:4.0 +import PackageDescription + +let package = Package( + name: "OctagonTestHarnessXPCServiceProtocol", + products: [ + .library(name: "OctagonTestHarnessXPCServiceProtocol", targets: ["OctagonTestHarnessXPCServiceProtocol"]), + ], + dependencies: [], + targets: [ + .target( + name: "OctagonTestHarnessXPCServiceProtocol", + dependencies: []), + ] +) diff --git a/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/OctagonTestHarnessXPCServiceProtocol.m b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/OctagonTestHarnessXPCServiceProtocol.m new file mode 100644 index 00000000..ca32ccab --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/OctagonTestHarnessXPCServiceProtocol.m @@ -0,0 +1,5 @@ +// Copyright (C) 2018 Apple Inc. All Rights Reserved. + +#import + +static NSString *name = @"OctagonTestHarnessXPCServiceProtocol"; // this is needed to appease our Swift Package Manager gods diff --git a/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/include/OctagonTestHarnessXPCServiceProtocol.h b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/include/OctagonTestHarnessXPCServiceProtocol.h new file mode 100644 index 00000000..1cce9364 --- /dev/null +++ b/keychain/Trieste/OctagonTestHarnessXPCServiceProtocol/Sources/OctagonTestHarnessXPCServiceProtocol/include/OctagonTestHarnessXPCServiceProtocol.h @@ -0,0 +1,10 @@ +// Copyright (C) 2018 Apple Inc. All Rights Reserved. + +#import + +@protocol OctagonTestHarnessXPCServiceProtocol + +// Trieste-compliant Octagon reset +- (void)octagonReset:(NSString *)altDSID complete:(void (^)(NSNumber *reset, NSError *error))complete; + +@end diff --git a/keychain/Trieste/OctagonTriesteTests/Package.swift b/keychain/Trieste/OctagonTriesteTests/Package.swift new file mode 100644 index 00000000..3f900fa5 --- /dev/null +++ b/keychain/Trieste/OctagonTriesteTests/Package.swift @@ -0,0 +1,28 @@ +// swift-tools-version:4.2 +import PackageDescription + +let package = Package( + name: "OctagonTrieste", + products: [ + .library(name: "OctagonTrieste", targets: ["OctagonTrieste"]), + .library(name: "OctagonTriesteTests", targets: ["OctagonTriesteTests"]), + ], + dependencies: [ + .package(url: "git@github.pie.apple.com:trieste/TriesteKit.git", .branch("master")), + .package(path: "../OctagonTestHarnessXPCServiceProtocol"), + ], + targets: [ + .target( + name: "OctagonTrieste", + dependencies: [ + "OctagonTestHarnessXPCServiceProtocol", + ]), + .testTarget( + name: "OctagonTriesteTests", + dependencies: [ + "CloudDeviceTest", + "CoreDeviceAutomation", + "OctagonTestHarnessXPCServiceProtocol", + ]), + ] +) diff --git a/keychain/Trieste/OctagonTriesteTests/Package.xcconfig b/keychain/Trieste/OctagonTriesteTests/Package.xcconfig new file mode 100644 index 00000000..7c1a5a6c --- /dev/null +++ b/keychain/Trieste/OctagonTriesteTests/Package.xcconfig @@ -0,0 +1,4 @@ +// Narrow the list of platforms in the Scheme menu in the toolbar to just macOS. + +MACOSX_DEPLOYMENT_TARGET=10.15 +SUPPORTED_PLATFORMS=macosx diff --git a/keychain/Trieste/OctagonTriesteTests/Sources/OctagonTrieste/Octagon.swift b/keychain/Trieste/OctagonTriesteTests/Sources/OctagonTrieste/Octagon.swift new file mode 100644 index 00000000..ccb3866f --- /dev/null +++ b/keychain/Trieste/OctagonTriesteTests/Sources/OctagonTrieste/Octagon.swift @@ -0,0 +1,3 @@ +// Copyright (C) 2018 Apple Inc. All Rights Reserved. + +let name = "Octagon" // this is needed to appease our Swift Package Manager gods diff --git a/keychain/Trieste/OctagonTriesteTests/Tests/OctagonTriesteTests/OctagonTests.swift b/keychain/Trieste/OctagonTriesteTests/Tests/OctagonTriesteTests/OctagonTests.swift new file mode 100644 index 00000000..a97ab461 --- /dev/null +++ b/keychain/Trieste/OctagonTriesteTests/Tests/OctagonTriesteTests/OctagonTests.swift @@ -0,0 +1,283 @@ +// Copyright (C) 2018 Apple Inc. All Rights Reserved. + +import CloudDeviceTest +import CoreDeviceAutomation +import CoreDeviceAutomationFrameworkFacade +import Foundation +import OctagonTestHarnessXPCServiceProtocol + +extension CDAIOSDevice { + func octagonFacade(block: @escaping (AnyObject) -> Void) throws { + try self.withFrameworkFacade(bundlePath: "/AppleInternal/Library/Frameworks/OctagonTestHarness.framework", + xpcService: "com.apple.trieste.OctagonTestHarnessXPCService", + ofType: OctagonTestHarnessXPCServiceProtocol.self, + block: block) + } +} + +final class OctagonTests: CDTTestCase { + + let username: String? = nil + let password: String? = nil + var signedIn: Bool = false + + let ckksTool = "/usr/sbin/ckksctl" + let securityTool = "/usr/local/bin/security" + + private func getDevice() throws -> CDAIOSDevice { + let common = CDAIOSCapabilities( + .buildTrain("Yukon"), + .location(country: "SE", building: "AP1"), + .installedFrameworkFacade(true), + .allowAnyCodeSignature(true) + ) + + if let rawPrkitUrl = ProcessInfo.processInfo.environment["PRKIT_URL"] { + if let prkitUrl = URL(string: rawPrkitUrl) { + let capabilities = common + + let device = try self.trieste.getIOSDevice(capabilities: capabilities) + + addTeardownBlock { + device.relinquish() + } + + try device.installPRKit(at: prkitUrl) + + return device + } else { + throw CDTFail("PRKIT_URL was set, but can't be parsed as URL, aborting: '\(rawPrkitUrl)'") + } + } else { + let device: CDAIOSDevice + + if !ProcessInfo.processInfo.environment.keys.contains("NO_XCODE") { + let capabilities = common.merging(CDAIOSCapabilities( + .setup(.complete), + .collectSysdiagnose() + )) + + device = try self.trieste.getIOSDevice(capabilities: capabilities) + + let targets = CDAInstalledXcodeTargetsSpec( + CDAInstalledXcodeTargetsSpec.Target(projectFile: "Security.xcodeproj", configuration: "Debug", scheme: "OctagonTestHarness", sdk: "iphoneos13.0.internal", roots: + CDAInstalledXcodeTargetsSpec.Root(product: "OctagonTestHarness.framework", installDirectory: "/AppleInternal/Library/Frameworks"), + CDAInstalledXcodeTargetsSpec.Root(product: "Security.framework", installDirectory: "/System/Library/Frameworks") + ) + ) + + try device.installXcodeTargets(targets, rebootWhenDone: true) + } else { + let capabilities = common.merging(CDAIOSCapabilities( + .setup(.complete), + .collectSysdiagnose() + )) + + device = try self.trieste.getIOSDevice(capabilities: capabilities) + } + + addTeardownBlock { + if (self.signedIn) { + do { + let listAccounts = try device.executeFile(atPath: "/usr/local/bin/accounts_tool", withArguments: ["--no-confirmation", "deleteAccountsForUsername", self.username!]) + XCTAssertEqual(listAccounts.returnCode, 0, "deleteAccountsForUsername") + print("accounts_tool deleteAccountsForUsername\n\(String(data: listAccounts.standardOutput, encoding: .utf8)!)\n") + } catch { + } + } + + device.relinquish() + } + + if (self.username != nil) { + CDALog(at: .infoLevel, "Signing in to iCloud here \(self.username!)") + + let listAccounts = try device.executeFile(atPath: "/usr/local/bin/accounts_tool", withArguments: ["listAccounts", "-v"]) + print("accounts_tool listAccounts -v\n\(String(data: listAccounts.standardOutput, encoding: .utf8)!)\n") + + let result = try device.executeFile(atPath: "/usr/local/bin/appleAccountSetupTool", withArguments: [self.username!, self.password!]) + XCTAssertEqual(result.returnCode, 0, "appleAccountSetupTool failed") + print("appleAccountSetupTool\n\(String(data: result.standardOutput, encoding: .utf8)!)\n") + + let enableKVS = try device.executeFile(atPath: "/bin/sh", withArguments: ["-c", "accounts_tool enableDataclass $(accounts_tool listAccountsForType com.apple.account.AppleAccount | grep identifier: | cut -f2 -d: ) com.apple.Dataclass.KeyValue"]) + XCTAssertEqual(enableKVS.returnCode, 0, "enableKVS failed") + print("enableKVS\n\(String(data: enableKVS.standardOutput, encoding: .utf8)!)\n") + + self.signedIn = true + } + + return device + } + } + + func compareCKKSZone(name zone: String, status1: NSDictionary, status2: NSDictionary) -> Bool { + + let zone1 = status1[zone] as! NSDictionary + let zone2 = status2[zone] as! NSDictionary + + let keystate1 = zone1["keystate"] as! NSString + let keystate2 = zone2["keystate"] as! NSString + + XCTAssertEqual(keystate1, "ready", "keystate should be ready for zone \(zone)") + XCTAssertEqual(keystate2, "ready", "keystate should be ready for zone \(zone)") + + let ckaccountstatus1 = zone1["ckaccountstatus"] as! NSString + let ckaccountstatus2 = zone2["ckaccountstatus"] as! NSString + + XCTAssertEqual(ckaccountstatus1, "logged in", "ckaccountstatus should be 'logged in' for zone \(zone)") + XCTAssertEqual(ckaccountstatus2, "logged in", "ckaccountstatus should be 'logged in' for zone \(zone)") + + let currentTLK1 = zone1["currentTLK"] as? NSString + let currentTLK2 = zone2["currentTLK"] as? NSString + + XCTAssertEqual(currentTLK1, currentTLK2, "TLK for zone \(zone) should be the same") + + return true + } + + func compareCKKSStatus(c1: NSDictionary, c2: NSDictionary) -> Bool { + + let status1 = c1["status"] as! NSDictionary + let status2 = c2["status"] as! NSDictionary + + XCTAssert(compareCKKSZone(name: "ApplePay", status1: status1, status2: status2)) + XCTAssert(compareCKKSZone(name: "Home", status1: status1, status2: status2)) + XCTAssert(compareCKKSZone(name: "Manatee", status1: status1, status2: status2)) + XCTAssert(compareCKKSZone(name: "AutoUnlock", status1: status1, status2: status2)) + + return true + } + + func sosStatus(_ device: CDAIOSDevice, verbose: Bool = false) throws { + let result = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-i"]) + if (verbose) { + print("security sync -i\n\(String(data: result.standardOutput, encoding: .utf8)!)\n") + } + } + func ckksStatus(_ device: CDAIOSDevice, verbose: Bool = false) throws -> NSDictionary { + let ckks = try device.executeFile(atPath: self.ckksTool, withArguments: ["status", "--json"]) + if (verbose) { + print("ckks status\n\(String(data: ckks.standardOutput, encoding: .utf8)!)\n") + } + + return try JSONSerialization.jsonObject(with: ckks.standardOutput) as! NSDictionary + } + + func sosApplication(_ device: CDAIOSDevice, verbose: Bool = false) throws { + if (self.password != nil) { + + print("submitting application\n") + + let password = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-P", self.password!]) + XCTAssertEqual(password.returnCode, 0, "setting password worked") + + let application = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-e"]) + XCTAssertEqual(application.returnCode, 0, "submissing application worked password worked") + + try self.sosStatus(device, verbose: true) + + print("waiting after application done\n") + sleep(4) + } + } + + func sosApprove(_ device: CDAIOSDevice, verbose: Bool = false) throws { + if (self.password != nil) { + + print("approving applications\n") + + let password = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-P", self.password!]) + XCTAssertEqual(password.returnCode, 0, "setting password worked") + + let approve = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-a"]) + XCTAssertEqual(approve.returnCode, 0, "submissing application worked password worked") + + try self.sosStatus(device, verbose: true) + + print("waiting after approving applications\n") + sleep(4) + } + } + + func forceResetSOS(_ device: CDAIOSDevice, resetCKKS: Bool = false) throws { + if (self.password != nil) { + _ = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-P", self.password!]) + _ = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-R"]) + _ = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-C"]) + _ = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-P", self.password!]) + _ = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-R"]) + _ = try device.executeFile(atPath: securityTool, withArguments: ["sync", "-O"]) + + try self.sosStatus(device, verbose: true) + + print("sleeping some to allow cdpd, cloudd and friends to catch up \n") + sleep(4) + + if (resetCKKS) { + _ = try device.executeFile(atPath: self.ckksTool, withArguments: ["reset-cloudkit"]) + + print("sleeps some after ckksctl reset (should be removed)\n") + sleep(4) + } + } + } + + func testBasiciCloudSignInSignOut() throws { + let device = try getDevice() + + let result = try device.executeFile(atPath: "/usr/local/bin/accounts_tool", withArguments: ["listAccounts", "-v"]) + print("accounts_tool listAccounts -v\n\(String(data: result.standardOutput, encoding: .utf8)!)\n") + + try forceResetSOS(device, resetCKKS: true) + + _ = try self.ckksStatus(device) + } + + func test2DeviceSOS() throws { + if (self.password == nil) { + print("this test only works with password") + return + } + + let device1 = try getDevice() + let device2 = try getDevice() + + try forceResetSOS(device1, resetCKKS: true) + try sosApplication(device2) + try sosApprove(device1, verbose: true) + try sosStatus(device2, verbose: true) + + print("waiting some \(Date())") + Thread.sleep(until: Date().addingTimeInterval(30.0)) // CK really really slow to get us data + print("waiting done \(Date())") + + let ckks1 = try ckksStatus(device1) + let ckks2 = try ckksStatus(device2) + + print("comparing status \(Date())") + XCTAssert(self.compareCKKSStatus(c1: ckks1, c2: ckks2), "compare of CKKS status") + + print("Done \(Date())") + } + + func testOctagonReset() throws { + let device = try getDevice() + + try forceResetSOS(device, resetCKKS: true) + + CDALog(at: .infoLevel, "Obtained signed in device \(device)") + + try device.octagonFacade { octagon in + CDALog(at: .infoLevel, "Obtained framework facade \(octagon)") + + for i in 0..<2 { + CDALog(at: .infoLevel, "Reset \(i)") + octagon.octagonReset("altDSID", complete: { _, error in + CDTAssert(error == nil, "Octagon wasn't reset, error was \(String(describing: error))") + }) + } + } + + CDALog(at: .infoLevel, "Done running") + } +} diff --git a/keychain/Trieste/OctagonTriesteTests/remake-local-project.sh b/keychain/Trieste/OctagonTriesteTests/remake-local-project.sh new file mode 100755 index 00000000..8f1ac44e --- /dev/null +++ b/keychain/Trieste/OctagonTriesteTests/remake-local-project.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +swift package generate-xcodeproj --xcconfig-overrides Package.xcconfig diff --git a/keychain/TrustedPeersHelper/BottledPeer/BottledPeer.swift b/keychain/TrustedPeersHelper/BottledPeer/BottledPeer.swift new file mode 100644 index 00000000..ff8a8929 --- /dev/null +++ b/keychain/TrustedPeersHelper/BottledPeer/BottledPeer.swift @@ -0,0 +1,280 @@ +/* + * Copyright (c) 2019 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 Foundation +import SecurityFoundation + +class BottledPeer: NSObject { + + public var escrowKeys: EscrowKeys + public var secret: Data + public var peerID: String + public var bottleID: String + public var peerKeys: OctagonSelfPeerKeys + + public var signatureUsingEscrowKey: Data + public var signatureUsingPeerKey: Data + public var escrowSigningPublicKey: Data + public var escrowSigningSPKI: Data + public var peersigningSPKI: Data + + public var contents: Data + + public class func encryptionOperation() -> (_SFAuthenticatedEncryptionOperation) { + let keySpecifier = _SFAESKeySpecifier.init(bitSize: TPHObjectiveC.aes256BitSize()) + return _SFAuthenticatedEncryptionOperation.init(keySpecifier: keySpecifier) + } + + // Given a peer's details including private key material, and + // the keys generated from the escrow secret, encrypt the peer private keys, + // make a bottled peer object and serialize it into data. + public init (peerID: String, bottleID: String, peerSigningKey: _SFECKeyPair, peerEncryptionKey: _SFECKeyPair, bottleSalt: String) throws { + + let secret = try BottledPeer.makeMeSomeEntropy(requiredLength: Int(OTMasterSecretLength)) + + self.secret = secret + self.escrowKeys = try EscrowKeys(secret: secret, bottleSalt: bottleSalt) + + // Serialize the peer private keys into "contents" + guard let contentsObj = OTBottleContents() else { + throw Error.OTErrorBottleCreation + } + guard let signingPK = OTPrivateKey() else { + throw Error.OTErrorPrivateKeyCreation + } + signingPK.keyType = OTPrivateKey_KeyType.EC_NIST_CURVES + signingPK.keyData = peerSigningKey.keyData + + guard let encryptionPK = OTPrivateKey() else { + throw Error.OTErrorPrivateKeyCreation + } + encryptionPK.keyType = OTPrivateKey_KeyType.EC_NIST_CURVES + encryptionPK.keyData = peerEncryptionKey.keyData + + contentsObj.peerSigningPrivKey = signingPK + contentsObj.peerEncryptionPrivKey = encryptionPK + guard let clearContentsData = contentsObj.data else { + throw Error.OTErrorBottleCreation + } + + // Encrypt the contents + let op = BottledPeer.encryptionOperation() + let cipher = try op.encrypt(clearContentsData, with: escrowKeys.symmetricKey) + + let escrowSigningECPubKey: _SFECPublicKey = (escrowKeys.signingKey.publicKey as! _SFECPublicKey) + let escrowEncryptionECPubKey: _SFECPublicKey = escrowKeys.encryptionKey.publicKey as! _SFECPublicKey + + let peerSigningECPublicKey: _SFECPublicKey = peerSigningKey.publicKey as! _SFECPublicKey + let peerEncryptionECPublicKey: _SFECPublicKey = peerEncryptionKey.publicKey as! _SFECPublicKey + + // Serialize the whole thing + guard let obj = OTBottle() else { + throw Error.OTErrorBottleCreation + } + obj.peerID = peerID + obj.bottleID = bottleID + obj.escrowedSigningSPKI = escrowSigningECPubKey.encodeSubjectPublicKeyInfo() + obj.escrowedEncryptionSPKI = escrowEncryptionECPubKey.encodeSubjectPublicKeyInfo() + obj.peerSigningSPKI = peerSigningECPublicKey.encodeSubjectPublicKeyInfo() + obj.peerEncryptionSPKI = peerEncryptionECPublicKey.encodeSubjectPublicKeyInfo() + + guard let authObj = OTAuthenticatedCiphertext() else { + throw Error.OTErrorAuthCipherTextCreation + } + authObj.ciphertext = cipher.ciphertext + authObj.authenticationCode = cipher.authenticationCode + authObj.initializationVector = cipher.initializationVector + + obj.contents = authObj + + self.peerID = peerID + self.bottleID = bottleID + + try self.peerKeys = OctagonSelfPeerKeys(peerID: peerID, signingKey: peerSigningKey, encryptionKey: peerEncryptionKey) + self.contents = obj.data + + let escrowedSigningECPublicKey = escrowKeys.signingKey.publicKey as! _SFECPublicKey + + self.escrowSigningPublicKey = escrowedSigningECPublicKey.keyData + self.escrowSigningSPKI = escrowedSigningECPublicKey.encodeSubjectPublicKeyInfo() + self.peersigningSPKI = peerSigningECPublicKey.encodeSubjectPublicKeyInfo() + + let xso = BottledPeer.signingOperation() + + let signedByEscrowKey = try xso.sign(self.contents, with: escrowKeys.signingKey) + self.signatureUsingEscrowKey = signedByEscrowKey.signature + + let signedByPeerKey = try xso.sign(self.contents, with: peerSigningKey) + self.signatureUsingPeerKey = signedByPeerKey.signature + } + + // Deserialize a bottle (data) and decrypt the contents (peer keys) + // using the keys generated from the escrow secret, and signatures from signing keys + public init (contents: Data, secret: Data, bottleSalt: String, signatureUsingEscrow: Data, signatureUsingPeerKey: Data) throws { + + self.secret = secret + self.escrowKeys = try EscrowKeys(secret: self.secret, bottleSalt: bottleSalt) + + guard let escrowSigningECKey: _SFECPublicKey = escrowKeys.signingKey.publicKey() as? _SFECPublicKey else { + os_log("escrow key not an SFECPublicKey?", log: tplogDebug, type: .default) + throw Error.OTErrorBottleCreation + } + self.escrowSigningSPKI = escrowSigningECKey.encodeSubjectPublicKeyInfo() + + // Deserialize the whole thing + guard let obj = OTBottle(data: contents) else { + os_log("Unable to deserialize bottle", log: tplogDebug, type: .default) + throw Error.OTErrorDeserializationFailure + } + + // First, the easy check: did the entropy create the keys that are supposed to be in the bottle? + guard obj.escrowedSigningSPKI == self.escrowSigningSPKI else { + os_log("Bottled SPKI does not match re-created SPKI", log: tplogDebug, type: .default) + throw Error.OTErrorEntropyKeyMismatch + } + + // Second, does the signature verify on the given data? + let xso = BottledPeer.signingOperation() + + let escrowSigned = _SFSignedData.init(data: contents, signature: signatureUsingEscrow) + try xso.verify(escrowSigned, with: escrowSigningECKey) + + // Now, decrypt contents + let op = BottledPeer.encryptionOperation() + let ac: OTAuthenticatedCiphertext = obj.contents as OTAuthenticatedCiphertext + + let ciphertext = _SFAuthenticatedCiphertext.init(ciphertext: ac.ciphertext, authenticationCode: ac.authenticationCode, initializationVector: ac.initializationVector) + + let clearContentsData = try op.decrypt(ciphertext, with: escrowKeys.symmetricKey) + if clearContentsData.count == 0 { + throw Error.OTErrorDecryptionFailure + } + + // Deserialize contents into private peer keys + guard let contentsObj = OTBottleContents(data: clearContentsData) else { + throw Error.OTErrorDeserializationFailure + } + + self.peerID = obj.peerID + self.bottleID = obj.bottleID + + try self.peerKeys = OctagonSelfPeerKeys(peerID: peerID, + signingKey: try contentsObj.peerSigningPrivKey.asECKeyPair(), + encryptionKey: try contentsObj.peerEncryptionPrivKey.asECKeyPair()) + self.contents = contents + + self.peersigningSPKI = obj.peerSigningSPKI + + let peerSigningPubKey = _SFECPublicKey(subjectPublicKeyInfo: obj.peerSigningSPKI) + let peerEncryptionPubKey = _SFECPublicKey(subjectPublicKeyInfo: obj.peerEncryptionSPKI) + + // Check the private keys match the public keys + if self.peerKeys.signingKey.publicKey != peerSigningPubKey { + throw Error.OTErrorKeyMismatch + } + if self.peerKeys.encryptionKey.publicKey != peerEncryptionPubKey { + throw Error.OTErrorKeyMismatch + } + + self.escrowSigningSPKI = escrowSigningECKey.encodeSubjectPublicKeyInfo() + + self.signatureUsingPeerKey = signatureUsingPeerKey + self.signatureUsingEscrowKey = signatureUsingEscrow + + self.escrowSigningPublicKey = escrowSigningECKey.keyData + + let peerSigned = _SFSignedData.init(data: self.contents, signature: signatureUsingPeerKey) + guard let peerPublicKey = self.peerKeys.publicSigningKey else { + throw Error.OTErrorKeyMismatch + } + try xso.verify(peerSigned, with: peerPublicKey) + } + + public func escrowSigningPublicKeyHash() -> String { + return TPHObjectiveC.digest(usingSha384: self.escrowSigningPublicKey) + } + + public class func signingOperation() -> (_SFEC_X962SigningOperation) { + let keySpecifier = _SFECKeySpecifier.init(curve: SFEllipticCurve.nistp384) + let digestOperation = _SFSHA384DigestOperation.init() + return _SFEC_X962SigningOperation.init(keySpecifier: keySpecifier, digestOperation: digestOperation) + } + + public class func verifyBottleSignature(data: Data, signature: Data, pubKey: _SFECPublicKey) throws -> (Bool) { + let xso = BottledPeer.signingOperation() + let peerSigned = _SFSignedData.init(data: data, signature: signature) + try xso.verify(peerSigned, with: pubKey) + return true + } + + public class func makeMeSomeEntropy(requiredLength: Int) throws -> Data { + let bytesPointer = UnsafeMutableRawPointer.allocate(byteCount: requiredLength, alignment: 1) + + if SecRandomCopyBytes(kSecRandomDefault, requiredLength, bytesPointer) != 0 { + throw Error.OTErrorEntropyCreation + } + return Data(bytes: bytesPointer, count: requiredLength) + } +} + +extension BottledPeer { + enum Error: Swift.Error { + case OTErrorDeserializationFailure + case OTErrorDecryptionFailure + case OTErrorKeyInstantiation + case OTErrorKeyMismatch + case OTErrorBottleCreation + case OTErrorAuthCipherTextCreation + case OTErrorPrivateKeyCreation + case OTErrorEscrowKeyCreation + case OTErrorEntropyCreation + case OTErrorEntropyKeyMismatch + } +} + +extension BottledPeer.Error: LocalizedError { + public var errorDescription: String? { + switch self { + case .OTErrorDeserializationFailure: + return "Failed to deserialize bottle peer" + case .OTErrorDecryptionFailure: + return "could not decrypt bottle contents" + case .OTErrorKeyInstantiation: + return "Failed to instantiate octagon peer keys" + case .OTErrorKeyMismatch: + return "public and private peer signing keys do not match" + case .OTErrorBottleCreation: + return "failed to create bottle" + case .OTErrorAuthCipherTextCreation: + return "failed to create authenticated ciphertext" + case .OTErrorPrivateKeyCreation: + return "failed to create private key" + case .OTErrorEscrowKeyCreation: + return "failed to create escrow keys" + case .OTErrorEntropyCreation: + return "failed to create entropy" + case .OTErrorEntropyKeyMismatch: + return "keys generated by the entropy+salt do not match the bottle contents" + } + } +} diff --git a/keychain/TrustedPeersHelper/BottledPeer/EscrowKeys.swift b/keychain/TrustedPeersHelper/BottledPeer/EscrowKeys.swift new file mode 100644 index 00000000..7308bfd6 --- /dev/null +++ b/keychain/TrustedPeersHelper/BottledPeer/EscrowKeys.swift @@ -0,0 +1,381 @@ +/* + * Copyright (c) 2019 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 Foundation +import SecurityFoundation + +let OT_ESCROW_SIGNING_HKDF_SIZE = 56 +let OT_ESCROW_ENCRYPTION_HKDF_SIZE = 56 +let OT_ESCROW_SYMMETRIC_HKDF_SIZE = 32 + +enum escrowKeyType: Int { + case kOTEscrowKeySigning = 1 + case kOTEscrowKeyEncryption = 2 + case kOTEscrowKeySymmetric = 3 +} + +class EscrowKeys: NSObject { + public var encryptionKey: _SFECKeyPair + public var signingKey: _SFECKeyPair + public var symmetricKey: _SFAESKey + + public var secret: Data + public var bottleSalt: String + + public init (secret: Data, bottleSalt: String) throws { + self.secret = secret + self.bottleSalt = bottleSalt + + let encryptionKeyData = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeyEncryption, masterSecret: secret, bottleSalt: bottleSalt) + self.encryptionKey = _SFECKeyPair.init(secKey: try EscrowKeys.createSecKey(keyData: encryptionKeyData)) + + let signingKeyData = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeySigning, masterSecret: secret, bottleSalt: bottleSalt) + self.signingKey = _SFECKeyPair.init(secKey: try EscrowKeys.createSecKey(keyData: signingKeyData)) + + let symmetricKeyData = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeySymmetric, masterSecret: secret, bottleSalt: bottleSalt) + let specifier = _SFAESKeySpecifier.init(bitSize: TPHObjectiveC.aes256BitSize()) + self.symmetricKey = try _SFAESKey.init(data: symmetricKeyData, specifier: specifier) + + let escrowSigningPubKeyHash = try EscrowKeys.hashEscrowedSigningPublicKey(keyData: self.signingKey.publicKey().spki()) + _ = try EscrowKeys.storeEscrowedSigningKeyPair(keyData: self.signingKey.keyData, label: escrowSigningPubKeyHash) + _ = try EscrowKeys.storeEscrowedEncryptionKeyPair(keyData: self.encryptionKey.keyData, label: escrowSigningPubKeyHash) + _ = try EscrowKeys.storeEscrowedSymmetricKey(keyData: self.symmetricKey.keyData, label: escrowSigningPubKeyHash) + } + + class func generateEscrowKey(keyType: escrowKeyType, masterSecret: Data, bottleSalt: String) throws -> (Data) { + var keyLength: Int + var info: Data + var infoLength: Int + var derivedKey: Data + var finalKey = Data() + + switch keyType { + case escrowKeyType.kOTEscrowKeySymmetric: + keyLength = OT_ESCROW_SYMMETRIC_HKDF_SIZE + + let infoString = Array("Escrow Symmetric Key".utf8) + info = Data(bytes: infoString, count: infoString.count) + infoLength = info.count + + break + case escrowKeyType.kOTEscrowKeyEncryption: + keyLength = OT_ESCROW_ENCRYPTION_HKDF_SIZE + + let infoString = Array("Escrow Encryption Private Key".utf8) + info = Data(bytes: infoString, count: infoString.count) + infoLength = info.count + + break + case escrowKeyType.kOTEscrowKeySigning: + keyLength = OT_ESCROW_SIGNING_HKDF_SIZE + + let infoString = Array("Escrow Signing Private Key".utf8) + info = Data(bytes: infoString, count: infoString.count) + infoLength = info.count + + break + } + + guard let cp = ccec_cp_384() else { + throw EscrowKeysError.keyGeneration + } + var status: Int32 = 0 + + let fullKey = TPHObjectiveC.ccec384Context() + defer { TPHObjectiveC.contextFree(fullKey) } + + derivedKey = Data(count: keyLength) + + var masterSecretMutable = masterSecret + let masterSecretLength = masterSecret.count + let derivedKeySize = derivedKey.count + + let bottleSaltData = Data(bytes: Array(bottleSalt.utf8), count: bottleSalt.utf8.count) + + try derivedKey.withUnsafeMutableBytes { (derivedKeyBytes: UnsafeMutablePointer) throws ->Void in + try masterSecretMutable.withUnsafeMutableBytes { (masterSecretBytes: UnsafeMutablePointer) throws ->Void in + try bottleSaltData.withUnsafeBytes { (bottleSaltBytes: UnsafePointer) throws -> Void in + try info.withUnsafeBytes { (infoBytes: UnsafePointer) throws -> Void in + status = cchkdf(ccsha384_di(), + masterSecretLength, masterSecretBytes, + bottleSaltData.count, bottleSaltBytes, + infoLength, infoBytes, + keyLength, derivedKeyBytes) + if status != 0 { + throw EscrowKeysError.corecryptoKeyGeneration(corecryptoError: status) + } + + if(keyType == escrowKeyType.kOTEscrowKeySymmetric) { + finalKey = Data(buffer: UnsafeBufferPointer(start: derivedKeyBytes, count: derivedKeySize)) + return + } else if(keyType == escrowKeyType.kOTEscrowKeyEncryption || keyType == escrowKeyType.kOTEscrowKeySigning) { + status = ccec_generate_key_deterministic(cp, + derivedKeySize, derivedKeyBytes, + ccDRBGGetRngState(), + UInt32(CCEC_GENKEY_DETERMINISTIC_FIPS), + fullKey) + + guard status == 0 else { + throw EscrowKeysError.corecryptoKeyGeneration(corecryptoError: status) + } + + let space = ccec_x963_export_size(1, ccec_ctx_pub(fullKey)) + var key = Data(count: space) + key.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in + ccec_x963_export(1, bytes, fullKey) + } + finalKey = Data(key) + } + } + } + } + } + return finalKey + } + + class func createSecKey(keyData: Data) throws -> (SecKey) { + let keyAttributes = [kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrKeyType: kSecAttrKeyTypeEC] + guard let key = SecKeyCreateWithData(keyData as CFData, keyAttributes as CFDictionary, nil) else { + throw EscrowKeysError.keyGeneration + } + + return key + } + + class func setKeyMaterialInKeychain(query: Dictionary) throws -> (Bool) { + var result = false + + var results: CFTypeRef? + var status = SecItemAdd(query as CFDictionary, &results) + + if status == errSecSuccess { + result = true + } else if status == errSecDuplicateItem { + var updateQuery: Dictionary = query + updateQuery[kSecClass] = nil + + status = SecItemUpdate(query as CFDictionary, updateQuery as CFDictionary) + + if status != errSecSuccess { + throw EscrowKeysError.failedToSaveToKeychain(errorCode: status) + } else { + result = true + } + } else { + throw EscrowKeysError.failedToSaveToKeychain(errorCode: status) + } + + return result + } + + class func hashEscrowedSigningPublicKey(keyData: Data) throws -> (String) { + let di = ccsha384_di() + var result = Data(count: TPHObjectiveC.ccsha384_diSize()) + + let derivedKeySize = keyData.count + var keyDataMutable = keyData + result.withUnsafeMutableBytes {(resultBytes: UnsafeMutablePointer) -> Void in + keyDataMutable.withUnsafeMutableBytes {(keyDataBytes: UnsafeMutablePointer) -> Void in + ccdigest(di, derivedKeySize, keyDataBytes, resultBytes) + } + } + let hash = result.base64EncodedString(options: []) + + return hash + } + + class func storeEscrowedEncryptionKeyPair(keyData: Data, label: String) throws -> (Bool) { + + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrSynchronizable: kCFBooleanFalse, + kSecAttrLabel: label, + kSecAttrApplicationLabel: String(format: "Escrowed Encryption Key-%@", NSUUID().uuidString), + kSecValueData: keyData, + ] + return try EscrowKeys.setKeyMaterialInKeychain(query: query) + } + + class func storeEscrowedSigningKeyPair(keyData: Data, label: String) throws -> (Bool) { + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrSynchronizable: kCFBooleanFalse, + kSecAttrApplicationLabel: String(format: "Escrowed Signing Key-%@", NSUUID().uuidString), + kSecAttrLabel: label, + kSecValueData: keyData, + ] + return try EscrowKeys.setKeyMaterialInKeychain(query: query) + } + + class func storeEscrowedSymmetricKey(keyData: Data, label: String) throws -> (Bool) { + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrSynchronizable: kCFBooleanFalse, + kSecAttrApplicationLabel: String(format: "Escrowed Symmetric Key-%@", NSUUID().uuidString), + kSecAttrLabel: label, + kSecValueData: keyData, + ] + return try EscrowKeys.setKeyMaterialInKeychain(query: query) + } + + class func retrieveEscrowKeysFromKeychain(label: String) throws -> [Dictionary ]? { + var keySet: [Dictionary]? + + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrLabel: label, + kSecReturnAttributes: true, + kSecReturnData: true, + kSecAttrSynchronizable: kCFBooleanFalse, + kSecMatchLimit: kSecMatchLimitAll, + ] + + var result: CFTypeRef? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status != errSecSuccess || result == nil { + throw EscrowKeysError.itemDoesNotExist + } + + if result != nil { + if let dictionaryArray = result as? [Dictionary] { + keySet = dictionaryArray + } else { + if let dictionary = result as? Dictionary { + keySet = [dictionary] + } else { + keySet = nil + } + } + } + return keySet + } + + class func findEscrowKeysForLabel(label: String) throws -> (_SFECKeyPair?, _SFECKeyPair?, _SFAESKey?) { + var signingKey: _SFECKeyPair? + var encryptionKey: _SFECKeyPair? + var symmetricKey: _SFAESKey? + + let keySet = try retrieveEscrowKeysFromKeychain(label: label) + if keySet == nil { + throw EscrowKeysError.itemDoesNotExist + } + for item in keySet! { + let keyTypeData = item[kSecAttrApplicationLabel as CFString] as! Data + let keyType = String(data: keyTypeData, encoding: .utf8)! + + if keyType.range(of: "Symmetric") != nil { + let keyData = item[kSecValueData as CFString] as! Data + let specifier = _SFAESKeySpecifier.init(bitSize: TPHObjectiveC.aes256BitSize()) + symmetricKey = try _SFAESKey.init(data: keyData, specifier: specifier) + } else if keyType.range(of: "Encryption") != nil { + let keyData = item[kSecValueData as CFString] as! Data + let encryptionSecKey = try EscrowKeys.createSecKey(keyData: keyData) + encryptionKey = _SFECKeyPair.init(secKey: encryptionSecKey) + } else if keyType.range(of: "Signing") != nil { + let keyData = item[kSecValueData as CFString] as! Data + let signingSecKey = try EscrowKeys.createSecKey(keyData: keyData) + signingKey = _SFECKeyPair.init(secKey: signingSecKey) + } else { + throw EscrowKeysError.unsupportedKeyType(keyType: keyType) + } + } + + return (signingKey, encryptionKey, symmetricKey) + } +} + +enum EscrowKeysError: Error { + case keyGeneration + case itemDoesNotExist + case failedToSaveToKeychain(errorCode: OSStatus) + case unsupportedKeyType(keyType: String) + case corecryptoKeyGeneration(corecryptoError: Int32) +} + +extension EscrowKeysError: LocalizedError { + public var errorDescription: String? { + switch self { + case .keyGeneration: + return "Key generation failed" + case .itemDoesNotExist: + return "Item does not exist" + case .failedToSaveToKeychain(errorCode: let osError): + return "Failed to save item to keychain: \(osError)" + case .unsupportedKeyType(keyType: let keyType): + return "Unsupported Key Type \(keyType)" + case .corecryptoKeyGeneration(corecryptoError: let corecryptoError): + return "Key generation error \(corecryptoError)" + } + } +} + +extension EscrowKeysError: CustomNSError { + + public static var errorDomain: String { + return "com.apple.security.trustedpeers.EscrowKeys" + } + + public var errorCode: Int { + switch self { + case .keyGeneration: + return 1 + case .itemDoesNotExist: + return 2 + case .failedToSaveToKeychain: + return 3 + case .unsupportedKeyType: + return 4 + case .corecryptoKeyGeneration: + return 5 + } + } + + public var errorUserInfo: [String: Any] { + var userInfo: [String: Any] = [:] + if let desc = self.errorDescription { + userInfo[NSLocalizedDescriptionKey] = desc + } + switch self { + case .failedToSaveToKeychain(errorCode: let osError): + userInfo[NSUnderlyingErrorKey] = NSError.init(domain: NSOSStatusErrorDomain, code: Int(osError), userInfo: nil) + case .corecryptoKeyGeneration(corecryptoError: let corecryptoError): + userInfo[NSUnderlyingErrorKey] = NSError.init(domain: "corecrypto", code: Int(corecryptoError), userInfo: nil) + default: + break + } + return userInfo + } +} + + diff --git a/keychain/TrustedPeersHelper/Client.swift b/keychain/TrustedPeersHelper/Client.swift new file mode 100644 index 00000000..fc8327ac --- /dev/null +++ b/keychain/TrustedPeersHelper/Client.swift @@ -0,0 +1,617 @@ +/* + * 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 Foundation + +class Client: TrustedPeersHelperProtocol { + + let endpoint: NSXPCListenerEndpoint? + let containerMap: ContainerMap + + init(endpoint: NSXPCListenerEndpoint?, containerMap: ContainerMap) { + self.endpoint = endpoint + self.containerMap = containerMap + } + + func ping(reply: @escaping (() -> Void)) { + reply() + } + + func logComplete(function: String, container: ContainerName, error: Error?) { + if let error = error { + os_log("%@ errored for %@: %@", log: tplogDebug, type: .default, function, container.description, error as CVarArg) + } else { + os_log("%@ finished for %@", log: tplogDebug, type: .default, function, container.description) + } + } + + internal func getContainer(withContainer container: String, context: String) throws -> Container { + let containerName = ContainerName(container: container, context: context) + return try self.containerMap.findOrCreate(name: containerName) + } + + func dump(withContainer container: String, context: String, reply: @escaping ([AnyHashable: Any]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Dumping for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.dump { result, error in + self.logComplete(function: "Dumping", container: container.name, error: error) + reply(result, CKXPCSuitableError(error)) + } + } catch { + os_log("Dumping failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, CKXPCSuitableError(error)) + } + } + + func dumpEgoPeer(withContainer container: String, + context: String, + reply: @escaping (String?, TPPeerPermanentInfo?, TPPeerStableInfo?, TPPeerDynamicInfo?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Dumping peer for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.dumpEgoPeer { peerID, perm, stable, dyn, error in + self.logComplete(function: "Dumping peer", container: container.name, error: error) + reply(peerID, perm, stable, dyn, CKXPCSuitableError(error)) + } + } catch { + os_log("Dumping peer failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, nil, nil, CKXPCSuitableError(error)) + } + } + + func trustStatus(withContainer container: String, context: String, reply: @escaping (TrustedPeersHelperEgoPeerStatus, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + let container = try self.containerMap.findOrCreate(name: containerName) + container.trustStatus(reply: reply) + } catch { + os_log("Trust status failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(TrustedPeersHelperEgoPeerStatus(egoPeerID: nil, status: TPPeerStatus.unknown, peerCountsByModelID: [:], isExcluded: false, isLocked: false), CKXPCSuitableError(error)) + } + } + + func fetchTrustState(withContainer container: String, context: String, reply: @escaping (TrustedPeersHelperPeerState?, [TrustedPeersHelperPeer]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Fetch Trust State for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.fetchTrustState(reply: reply) + } catch { + os_log("Fetch Trust State failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func reset(withContainer container: String, context: String, reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Resetting for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.reset { error in + self.logComplete(function: "Resetting", container: container.name, error: error) + reply(CKXPCSuitableError(error)) } + } catch { + os_log("Resetting failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func localReset(withContainer container: String, context: String, reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Performing local reset for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.localReset { error in + self.logComplete(function: "Local reset", container: container.name, error: error) + reply(CKXPCSuitableError(error)) + } + } catch { + os_log("Local reset failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func setAllowedMachineIDsWithContainer(_ container: String, + context: String, + allowedMachineIDs: Set, + reply: @escaping (Bool, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Setting allowed machineIDs for %@ to %@", log: tplogDebug, type: .default, containerName.description, allowedMachineIDs) + let container = try self.containerMap.findOrCreate(name: containerName) + container.setAllowedMachineIDs(allowedMachineIDs) { differences, error in + self.logComplete(function: "Setting allowed machineIDs", container: container.name, error: error) + reply(differences, CKXPCSuitableError(error)) + } + } catch { + os_log("Setting allowed machineIDs failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(false, CKXPCSuitableError(error)) + } + } + + func addAllowedMachineIDs(withContainer container: String, + context: String, + machineIDs: [String], + reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Adding allowed machineIDs for %@: %@", log: tplogDebug, type: .default, containerName.description, machineIDs) + let container = try self.containerMap.findOrCreate(name: containerName) + container.addAllow(machineIDs) { error in + self.logComplete(function: "Adding allowed machineIDs", container: container.name, error: error) + reply(CKXPCSuitableError(error)) + } + } catch { + os_log("Adding allowed machineID failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func removeAllowedMachineIDs(withContainer container: String, + context: String, + machineIDs: [String], + reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Removing allowed machineIDs for %@: %@", log: tplogDebug, type: .default, containerName.description, machineIDs) + let container = try self.containerMap.findOrCreate(name: containerName) + container.removeAllow(machineIDs) { error in + self.logComplete(function: "Removing allowed machineIDs", container: container.name, error: error) + reply(CKXPCSuitableError(error)) + } + } catch { + os_log("Removing allowed machineID failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func fetchEgoEpoch(withContainer container: String, context: String, reply: @escaping (UInt64, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("retrieving epoch for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.getEgoEpoch { epoch, error in + reply(epoch, CKXPCSuitableError(error)) + } + } catch { + os_log("Epoch retrieval failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(0, CKXPCSuitableError(error)) + } + } + + func prepare(withContainer container: String, + context: String, + epoch: UInt64, + machineID: String, + bottleSalt: String, + bottleID: String, + modelID: String, + deviceName: String?, + serialNumber: String, + osVersion: String, + policyVersion: NSNumber?, + policySecrets: [String: Data]?, + signingPrivKeyPersistentRef: Data?, + encPrivKeyPersistentRef: Data?, + reply: @escaping (String?, Data?, Data?, Data?, Data?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Preparing new identity for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.prepare(epoch: epoch, + machineID: machineID, + bottleSalt: bottleSalt, + bottleID: bottleID, + modelID: modelID, + deviceName: deviceName, + serialNumber: serialNumber, + osVersion: osVersion, + policyVersion: policyVersion?.uint64Value, + policySecrets: policySecrets, + signingPrivateKeyPersistentRef: signingPrivKeyPersistentRef, + encryptionPrivateKeyPersistentRef: encPrivKeyPersistentRef) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + self.logComplete(function: "Prepare", container: container.name, error: error) + reply(peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, CKXPCSuitableError(error)) + } + } catch { + os_log("Prepare failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, nil, nil, nil, CKXPCSuitableError(error)) + } + } + + func establish(withContainer container: String, + context: String, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]?, + reply: @escaping (String?, [CKRecord]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Establishing %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.establish(ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys) { peerID, keyHierarchyRecords, error in + self.logComplete(function: "Establishing", container: container.name, error: error) + reply(peerID, keyHierarchyRecords, CKXPCSuitableError(error)) } + } catch { + os_log("Establishing failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func vouch(withContainer container: String, + context: String, + peerID: String, + permanentInfo: Data, + permanentInfoSig: Data, + stableInfo: Data, + stableInfoSig: Data, + ckksKeys: [CKKSKeychainBackedKeySet], + reply: @escaping (Data?, Data?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Vouching %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.vouch(peerID: peerID, + permanentInfo: permanentInfo, + permanentInfoSig: permanentInfoSig, + stableInfo: stableInfo, + stableInfoSig: stableInfoSig, + ckksKeys: ckksKeys) { voucher, voucherSig, error in + self.logComplete(function: "Vouching", container: container.name, error: error) + reply(voucher, voucherSig, CKXPCSuitableError(error)) } + } catch { + os_log("Vouching failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func vouchWithBottle(withContainer container: String, + context: String, + bottleID: String, + entropy: Data, + bottleSalt: String, + tlkShares: [CKKSTLKShare], + reply: @escaping (Data?, Data?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Vouching With Bottle %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.vouchWithBottle(bottleID: bottleID, entropy: entropy, bottleSalt: bottleSalt, tlkShares: tlkShares) { voucher, voucherSig, error in + self.logComplete(function: "Vouching With Bottle", container: container.name, error: error) + reply(voucher, voucherSig, CKXPCSuitableError(error)) } + } catch { + os_log("Vouching with Bottle failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func vouchWithRecoveryKey(withContainer container: String, + context: String, + recoveryKey: String, + salt: String, + tlkShares: [CKKSTLKShare], + reply: @escaping (Data?, Data?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Vouching With Recovery Key %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.vouchWithRecoveryKey(recoveryKey: recoveryKey, salt: salt, tlkShares: tlkShares) { voucher, voucherSig, error in + self.logComplete(function: "Vouching With Recovery Key", container: container.name, error: error) + reply(voucher, voucherSig, CKXPCSuitableError(error)) } + } catch { + os_log("Vouching with Recovery Key failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func join(withContainer container: String, + context: String, + voucherData: Data, + voucherSig: Data, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data], + reply: @escaping (String?, [CKRecord]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Joining %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.join(voucherData: voucherData, + voucherSig: voucherSig, + ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys) { peerID, keyHierarchyRecords, error in reply(peerID, keyHierarchyRecords, CKXPCSuitableError(error)) } + } catch { + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func preflightPreapprovedJoin(withContainer container: String, + context: String, + reply: @escaping (Bool, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Attempting to preflight a preapproved join for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.preflightPreapprovedJoin() { success, error in reply(success, CKXPCSuitableError(error)) } + } catch { + reply(false, CKXPCSuitableError(error)) + } + } + + func attemptPreapprovedJoin(withContainer container: String, + context: String, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data], + reply: @escaping (String?, [CKRecord]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Attempting a preapproved join for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.preapprovedJoin(ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys) { peerID, keyHierarchyRecords, error in reply(peerID, keyHierarchyRecords, CKXPCSuitableError(error)) } + } catch { + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func update(withContainer container: String, + context: String, + deviceName: String?, + serialNumber: String?, + osVersion: String?, + policyVersion: NSNumber?, + policySecrets: [String: Data]?, + reply: @escaping (TrustedPeersHelperPeerState?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Updating %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.update(deviceName: deviceName, + serialNumber: serialNumber, + osVersion: osVersion, + policyVersion: policyVersion?.uint64Value, + policySecrets: policySecrets) { state, error in reply(state, CKXPCSuitableError(error)) } + } catch { + reply(nil, CKXPCSuitableError(error)) + } + } + + func setPreapprovedKeysWithContainer(_ container: String, + context: String, + preapprovedKeys: [Data], + reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Updating %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.set(preapprovedKeys: preapprovedKeys) { error in reply(CKXPCSuitableError(error)) } + } catch { + reply(CKXPCSuitableError(error)) + } + } + + func updateTLKs(withContainer container: String, + context: String, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + reply: @escaping ([CKRecord]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Updating TLKs for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.updateTLKs(ckksKeys: ckksKeys, + tlkShares: tlkShares, + reply: reply) + } catch { + reply(nil, CKXPCSuitableError(error)) + } + } + + func departByDistrustingSelf(withContainer container: String, + context: String, + reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Departing %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.departByDistrustingSelf { error in + reply(CKXPCSuitableError(error)) + } + } catch { + reply(CKXPCSuitableError(error)) + } + } + + func distrustPeerIDs(withContainer container: String, + context: String, + peerIDs: Set, + reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Distrusting %@ in %@", log: tplogDebug, type: .default, peerIDs, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.distrust(peerIDs: peerIDs) { error in + reply(CKXPCSuitableError(error)) + } + } catch { + reply(CKXPCSuitableError(error)) + } + } + + func fetchViableBottles(withContainer container: String, context: String, reply: @escaping ([String]?, [String]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("fetchViableBottles in %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.fetchViableBottles { sortedBottleIDs, partialBottleIDs, error in + reply(sortedBottleIDs, partialBottleIDs, CKXPCSuitableError(error)) + } + } catch { + reply(nil, nil, CKXPCSuitableError(error)) + } + } + + func fetchEscrowContents(withContainer container: String, context: String, reply: @escaping (Data?, String?, Data?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("fetchEscrowContents in %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.fetchEscrowContents { entropy, bottleID, signingPublicKey, error in + reply(entropy, bottleID, signingPublicKey, CKXPCSuitableError(error)) + } + } catch { + reply(nil, nil, nil, CKXPCSuitableError(error)) + } + } + + func fetchPolicy(withContainer container: String, + context: String, + reply: @escaping (TPPolicy?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Fetching policy for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.fetchPolicy { policy, error in + reply(policy, CKXPCSuitableError(error)) + } + } catch { + reply(nil, CKXPCSuitableError(error)) + } + } + + func fetchPolicyDocuments(withContainer container: String, + context: String, + keys: [NSNumber: String], + reply: @escaping ([NSNumber: [String]]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Fetching policy documents %@ with keys: %@", log: tplogDebug, type: .default, containerName.description, keys) + let container = try self.containerMap.findOrCreate(name: containerName) + container.fetchPolicyDocuments(keys: keys) { entries, error in + reply(entries, CKXPCSuitableError(error)) + } + } catch { + reply(nil, CKXPCSuitableError(error)) + } + } + + func validatePeers(withContainer container: String, context: String, reply: @escaping ([AnyHashable: Any]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("ValidatePeers for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + let request = ValidatePeersRequest() + container.validatePeers(request: request) { result, error in + self.logComplete(function: "validatePeers", container: container.name, error: error) + reply(result, CKXPCSuitableError(error)) + } + } catch { + os_log("ValidatePeers failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, CKXPCSuitableError(error)) + } + } + + func setRecoveryKeyWithContainer(_ container: String, context: String, recoveryKey: String, salt: String, ckksKeys: [CKKSKeychainBackedKeySet], reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("SetRecoveryKey for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.setRecoveryKey(recoveryKey: recoveryKey, salt: salt, ckksKeys: ckksKeys) { error in + self.logComplete(function: "setRecoveryKey", container: container.name, error: error) + reply(CKXPCSuitableError(error)) + } + } catch { + os_log("SetRecoveryKey failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func reportHealth(withContainer container: String, context: String, stateMachineState: String, trustState: String, reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("ReportHealth for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + let request = ReportHealthRequest.with { + $0.stateMachineState = stateMachineState + } + container.reportHealth(request: request) { error in + self.logComplete(function: "reportHealth", container: container.name, error: error) + reply(CKXPCSuitableError(error)) + } + } catch { + os_log("ReportHealth failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func pushHealthInquiry(withContainer container: String, context: String, reply: @escaping (Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("PushHealthInquiry for %@", log: tplogDebug, type: .default, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.pushHealthInquiry { error in + self.logComplete(function: "pushHealthInquiry", container: container.name, error: error) + reply(CKXPCSuitableError(error)) + } + } catch { + os_log("PushHealthInquiry failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(CKXPCSuitableError(error)) + } + } + + func getViewsWithContainer(_ container: String, context: String, inViews: [String], reply: @escaping ([String]?, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("GetViews (%@) for %@", log: tplogDebug, type: .default, inViews, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.getViews(inViews: inViews) { outViews, error in + reply(outViews, CKXPCSuitableError(error)) + } + } catch { + os_log("GetViews failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(nil, CKXPCSuitableError(error)) + } + } + + func requestHealthCheck(withContainer container: String, context: String, requiresEscrowCheck: Bool, reply: @escaping (Bool, Bool, Bool, Error?) -> Void) { + do { + let containerName = ContainerName(container: container, context: context) + os_log("Health Check! requiring escrow check? %d for %@", log: tplogDebug, type: .default, requiresEscrowCheck, containerName.description) + let container = try self.containerMap.findOrCreate(name: containerName) + container.requestHealthCheck(requiresEscrowCheck: requiresEscrowCheck) { postRepair, postEscrow, postReset, error in + reply(postRepair, postEscrow, postReset, CKXPCSuitableError(error)) + } + } catch { + os_log("Health Check! failed for (%@, %@): %@", log: tplogDebug, type: .default, container, context, error as CVarArg) + reply(false, false, false, CKXPCSuitableError(error)) + } + } +} diff --git a/keychain/TrustedPeersHelper/Container.swift b/keychain/TrustedPeersHelper/Container.swift new file mode 100644 index 00000000..271e6c1a --- /dev/null +++ b/keychain/TrustedPeersHelper/Container.swift @@ -0,0 +1,3926 @@ +/* + * 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 CloudKitCode +import CoreData +import Foundation +import os +import Security +import SecurityFoundation + +let tplogDebug = OSLog(subsystem: "com.apple.security.trustedpeers", category: "debug") +let tplogTrace = OSLog(subsystem: "com.apple.security.trustedpeers", category: "trace") + +let egoIdentitiesAccessGroup = "com.apple.security.egoIdentities" + +public enum ContainerError: Error { + case unableToCreateKeyPair + case noPreparedIdentity + case failedToStoreIdentity + case needsAuthentication + case missingStableInfo + case missingDynamicInfo + case nonMember + case invalidPermanentInfoOrSig + case invalidStableInfoOrSig + case invalidVoucherOrSig + case sponsorNotRegistered(String) + case unknownPolicyVersion(UInt64) + case preparedIdentityNotOnAllowedList(String) + case couldNotLoadAllowedList + case noPeersPreapprovePreparedIdentity + case policyDocumentDoesNotValidate + case tooManyBottlesForPeer + case noBottleForPeer + case restoreBottleFailed + case noBottlesForEscrowRecordID + case bottleDoesNotContainContents + case bottleDoesNotContainEscrowKeySignature + case bottleDoesNotContainerPeerKeySignature + case bottleDoesNotContainPeerID + case failedToCreateBottledPeer + case signatureVerificationFailed + case bottleDoesNotContainerEscrowKeySPKI + case failedToFetchEscrowContents + case failedToCreateRecoveryKey + case untrustedRecoveryKeys + case noBottlesPresent + case recoveryKeysNotEnrolled + case bottleCreatingPeerNotFound + case unknownCloudKitError + case cloudkitResponseMissing + case failedToLoadSecret(errorCode: Int) + case failedToLoadSecretDueToType + case failedToAssembleBottle + case invalidPeerID + case failedToStoreSecret(errorCode: Int) +} + +extension ContainerError: LocalizedError { + public var errorDescription: String? { + switch self { + case .unableToCreateKeyPair: + return "unable to create key pair" + case .noPreparedIdentity: + return "no prepared identity" + case .failedToStoreIdentity: + return "failed to stored identity" + case .needsAuthentication: + return "needs authentication" + case .missingStableInfo: + return "missing stable info" + case .missingDynamicInfo: + return "missing dynamic info" + case .nonMember: + return "non member" + case .invalidPermanentInfoOrSig: + return "invalid permanent info or signature" + case .invalidStableInfoOrSig: + return "invalid stable info or signature" + case .invalidVoucherOrSig: + return "invalid voucher or signature" + case .sponsorNotRegistered(let s): + return "sponsor not registered: \(s)" + case .unknownPolicyVersion(let v): + return "unknown policy version: \(v)" + case .preparedIdentityNotOnAllowedList(let id): + return "prepared identity (\(id)) not on allowed machineID list" + case .couldNotLoadAllowedList: + return "could not load allowed machineID list" + case .noPeersPreapprovePreparedIdentity: + return "no peers preapprove prepared identity" + case .policyDocumentDoesNotValidate: + return "policy document from server doesn't validate" + case .tooManyBottlesForPeer: + return "too many bottles exist for peer" + case .noBottleForPeer: + return "no bottle exists for peer" + case .restoreBottleFailed: + return "failed to restore bottle" + case .noBottlesForEscrowRecordID: + return "0 bottles exist for escrow record id" + case .bottleDoesNotContainContents: + return "bottle does not contain encrypted contents" + case .bottleDoesNotContainEscrowKeySignature: + return "bottle does not contain escrow signature" + case .bottleDoesNotContainerPeerKeySignature: + return "bottle does not contain peer signature" + case .bottleDoesNotContainPeerID: + return "bottle does not contain peer id" + case .failedToCreateBottledPeer: + return "failed to create a bottled peer" + case .signatureVerificationFailed: + return "failed to verify signature" + case .bottleDoesNotContainerEscrowKeySPKI: + return "bottle does not contain escrowed key spki" + case .failedToFetchEscrowContents: + return "failed to fetch escrow contents" + case .failedToCreateRecoveryKey: + return "failed to create recovery keys" + case .untrustedRecoveryKeys: + return "untrusted recovery keys" + case .noBottlesPresent: + return "no bottle present" + case .recoveryKeysNotEnrolled: + return "recovery key is not enrolled with octagon" + case .bottleCreatingPeerNotFound: + return "The peer that created the bottle was not found" + case .unknownCloudKitError: + return "unknown error from cloudkit" + case .cloudkitResponseMissing: + return "Response missing from CloudKit" + case .failedToLoadSecret(errorCode: let errorCode): + return "failed to load secret: \(errorCode)" + case .failedToLoadSecretDueToType: + return "Failed to load secret due to type mismatch (value was not dictionary)" + case .failedToAssembleBottle: + return "failed to assemble bottle for peer" + case .invalidPeerID: + return "peerID is invalid" + case .failedToStoreSecret(errorCode: let errorCode): + return "failed to store the secret in the keychain \(errorCode)" + } + } +} + +extension ContainerError: CustomNSError { + + public static var errorDomain: String { + return "com.apple.security.trustedpeers.container" + } + + public var errorCode: Int { + switch self { + case .unableToCreateKeyPair: + return 0 + case .noPreparedIdentity: + return 1 + case .failedToStoreIdentity: + return 2 + case .needsAuthentication: + return 3 + case .missingStableInfo: + return 4 + case .missingDynamicInfo: + return 5 + case .nonMember: + return 6 + case .invalidPermanentInfoOrSig: + return 7 + case .invalidVoucherOrSig: + return 8 + case .invalidStableInfoOrSig: + return 9 + case .sponsorNotRegistered: + return 11 + case .unknownPolicyVersion: + return 12 + case .preparedIdentityNotOnAllowedList: + return 13 + case .noPeersPreapprovePreparedIdentity: + return 14 + case .policyDocumentDoesNotValidate: + return 15 + // 16 was invalidPeerID and failedToAssembleBottle + case .tooManyBottlesForPeer: + return 17 + case .noBottleForPeer: + return 18 + case .restoreBottleFailed: + return 19 + case .noBottlesForEscrowRecordID: + return 20 + case .bottleDoesNotContainContents: + return 21 + case .bottleDoesNotContainEscrowKeySignature: + return 22 + case .bottleDoesNotContainerPeerKeySignature: + return 23 + case .bottleDoesNotContainPeerID: + return 24 + case .failedToCreateBottledPeer: + return 25 + case .signatureVerificationFailed: + return 26 + // 27 was failedToLoadSecret* + case .bottleDoesNotContainerEscrowKeySPKI: + return 28 + case .failedToFetchEscrowContents: + return 29 + case .couldNotLoadAllowedList: + return 30 + case .failedToCreateRecoveryKey: + return 31 + case .untrustedRecoveryKeys: + return 32 + case .noBottlesPresent: + return 33 + case .recoveryKeysNotEnrolled: + return 34 + case .bottleCreatingPeerNotFound: + return 35 + case .unknownCloudKitError: + return 36 + case .cloudkitResponseMissing: + return 37 + case .failedToLoadSecret: + return 38 + case .failedToLoadSecretDueToType: + return 39 + case .failedToStoreSecret: + return 40 + case .failedToAssembleBottle: + return 41 + case .invalidPeerID: + return 42 + } + } + + public var underlyingError: NSError? { + switch self { + case .failedToLoadSecret(errorCode: let errorCode): + return NSError(domain: "securityd", code: errorCode) + case .failedToStoreSecret(errorCode: let errorCode): + return NSError(domain: "securityd", code: errorCode) + default: + return nil + } + } + + public var errorUserInfo: [String: Any] { + var ret = [String: Any]() + if let desc = self.errorDescription { + ret[NSLocalizedDescriptionKey] = desc + } + if let underlyingError = self.underlyingError { + ret[NSUnderlyingErrorKey] = underlyingError + } + return ret + } +} + +internal func traceError(_ error: Error?) -> String { + if let error = error { + return "error: \(String(describing: error))" + } else { + return "success" + } +} + +func saveSecret(_ secret: Data, label: String) throws { + + let query: [CFString: Any] = [ + kSecClass: kSecClassInternetPassword, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrSynchronizable: kCFBooleanFalse, + kSecAttrDescription: label, + kSecAttrPath: label, + kSecValueData: secret, + ] + + var results: CFTypeRef? + var status = SecItemAdd(query as CFDictionary, &results) + + if status == errSecSuccess { + return + } + + if status == errSecDuplicateItem { + // Add every primary key attribute to this find dictionary + var findQuery: [CFString: Any] = [:] + findQuery[kSecClass] = query[kSecClass] + findQuery[kSecAttrSynchronizable] = query[kSecAttrSynchronizable] + findQuery[kSecAttrAccessGroup] = query[kSecAttrAccessGroup] + findQuery[kSecAttrServer] = query[kSecAttrDescription] + findQuery[kSecAttrPath] = query[kSecAttrPath] + findQuery[kSecUseDataProtectionKeychain] = query[kSecUseDataProtectionKeychain]; + + var updateQuery: [CFString: Any] = query + updateQuery[kSecClass] = nil + + status = SecItemUpdate(findQuery as CFDictionary, updateQuery as CFDictionary) + + if status != errSecSuccess { + throw ContainerError.failedToStoreSecret(errorCode: Int(status)) + } + } else { + throw ContainerError.failedToStoreSecret(errorCode: Int(status)) + } +} + +func loadSecret(label: String) throws -> (Data?) { + var secret: Data? + + let query: [CFString: Any] = [ + kSecClass: kSecClassInternetPassword, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrDescription: label, + kSecReturnAttributes: true, + kSecReturnData: true, + kSecAttrSynchronizable: kCFBooleanFalse, + kSecMatchLimit: kSecMatchLimitOne, + ] + + var result: CFTypeRef? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status != errSecSuccess || result == nil { + throw ContainerError.failedToLoadSecret(errorCode: Int(status)) + } + + if result != nil { + if let dictionary = result as? [CFString: Any] { + secret = dictionary[kSecValueData] as? Data + } else { + throw ContainerError.failedToLoadSecretDueToType + } + } + return secret +} + +func saveEgoKeyPair(_ keyPair: _SFECKeyPair, identifier: String, resultHandler: @escaping (Bool, Error?) -> Void) { + let keychainManager = _SFKeychainManager.default() + let signingIdentity = _SFIdentity(keyPair: keyPair) + let accessibility = SFAccessibilityMakeWithMode(SFAccessibilityMode.accessibleWhenUnlocked) // class A + let accessPolicy = _SFAccessPolicy(accessibility: accessibility, + sharingPolicy: SFSharingPolicy.thisDeviceOnly) + accessPolicy.accessGroup = egoIdentitiesAccessGroup + keychainManager.setIdentity(signingIdentity, + forIdentifier: identifier, + accessPolicy: accessPolicy, + resultHandler: resultHandler) +} + +func loadEgoKeyPair(identifier: String, resultHandler: @escaping (_SFECKeyPair?, Error?) -> Void) { + let keychainManager = _SFKeychainManager.default() + + // FIXME constrain to egoIdentitiesAccessGroup, + keychainManager.identity(forIdentifier: identifier) { result in + switch result.resultType { + case .valueAvailable: + resultHandler(result.value?.keyPair as? _SFECKeyPair, nil) + case .needsAuthentication: + resultHandler(nil, ContainerError.needsAuthentication) + case .error: + resultHandler(nil, result.error) + } + } +} + +func loadEgoKeys(peerID: String, resultHandler: @escaping (OctagonSelfPeerKeys?, Error?) -> Void) { + loadEgoKeyPair(identifier: signingKeyIdentifier(peerID: peerID)) { signingKey, error in + guard let signingKey = signingKey else { + os_log("Unable to load signing key: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + resultHandler(nil, error) + return + } + + loadEgoKeyPair(identifier: encryptionKeyIdentifier(peerID: peerID)) { encryptionKey, error in + guard let encryptionKey = encryptionKey else { + os_log("Unable to load encryption key: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + resultHandler(nil, error) + return + } + + do { + resultHandler(try OctagonSelfPeerKeys(peerID: peerID, signingKey: signingKey, encryptionKey: encryptionKey), nil) + } catch { + resultHandler(nil, error) + } + } + } +} + +func removeEgoKeysSync(peerID: String) throws -> Bool { + var resultSema = DispatchSemaphore(value: 0) + + let keychainManager = _SFKeychainManager.default() + + var retresultForSigningDeletion: Bool = false + var reterrorForSigningDeletion: Error? = nil + + //remove signing keys + keychainManager.removeItem(withIdentifier: signingKeyIdentifier(peerID: peerID)) { result, error in + retresultForSigningDeletion = result + reterrorForSigningDeletion = error + resultSema.signal() + } + + resultSema.wait() + + if let error = reterrorForSigningDeletion { + throw error + } + + if retresultForSigningDeletion == false { + return retresultForSigningDeletion + } + + // now let's do the same thing with the encryption keys + resultSema = DispatchSemaphore(value: 0) + var retresultForEncryptionDeletion: Bool = false + var reterrorForEncryptionDeletion: Error? = nil + + keychainManager.removeItem(withIdentifier: encryptionKeyIdentifier(peerID: peerID)) { result, error in + retresultForEncryptionDeletion = result + reterrorForEncryptionDeletion = error + resultSema.signal() + } + resultSema.wait() + + if let error = reterrorForEncryptionDeletion { + throw error + } + + return retresultForEncryptionDeletion && retresultForSigningDeletion +} + +func loadEgoKeysSync(peerID: String) throws -> OctagonSelfPeerKeys { + // Gotta promote to synchronous; 'antipattern' ahoy + let resultSema = DispatchSemaphore(value: 0) + + var result: OctagonSelfPeerKeys? + var reserror: Error? + + loadEgoKeys(peerID: peerID) { keys, error in + result = keys + reserror = error + resultSema.signal() + } + resultSema.wait() + + if let error = reserror { + throw error + } + + if let result = result { + return result + } + + abort() +} + +func signingKeyIdentifier(peerID: String) -> String { + return "signing-key " + peerID +} + +func encryptionKeyIdentifier(peerID: String) -> String { + return "encryption-key " + peerID +} + +func makeTLKShares(ckksTLKs: [CKKSKeychainBackedKey]?, asPeer: CKKSSelfPeer, toPeer: CKKSPeer, epoch: Int) throws -> [TLKShare] { + return try (ckksTLKs ?? []).map { tlk in + os_log("Making TLKShare for %@ for key %@", log: tplogDebug, type: .default, toPeer.description, tlk) + // Not being able to convert a TLK to a TLKShare is a failure, but not having a TLK is only half bad + do { + return TLKShare.convert(ckksTLKShare: try CKKSTLKShare(tlk, as: asPeer, to: toPeer, epoch: epoch, poisoned: 0)) + } catch { + let nserror = error as NSError + if nserror.domain == "securityd" && nserror.code == errSecItemNotFound { + os_log("No TLK contents for %@, no TLK share possible", log: tplogDebug, type: .default, tlk) + return nil + } else { + throw error + } + } + }.compactMap { $0 } +} + +func extract(tlkShares: [CKKSTLKShare], peer: CKKSSelfPeer) { + os_log("Attempting to recover %d TLK shares for peer %@", log: tplogDebug, type: .default, tlkShares.count, peer.peerID) + for share in tlkShares { + guard share.receiverPeerID == peer.peerID else { + os_log("Skipping %@ (wrong peerID)", log: tplogDebug, type: .default, share) + continue + } + + do { + // TODO: how should we handle peer sets here? + let key = try share.recoverTLK(peer, + trustedPeers: [peer as! AnyHashable], + ckrecord: nil) + + try key.saveMaterialToKeychain() + os_log("Recovered %@ (from %@)", log: tplogDebug, type: .default, key, share) + } catch { + os_log("Failed to recover share %@: %@", log: tplogDebug, type: .default, share, error as CVarArg) + } + } + +} + +struct ContainerState { + var egoPeerID: String? + var peers: [String: TPPeer] = [:] + var vouchers: [TPVoucher] = [] + var bottles = Set() + var recoverySigningKey: Data? + var recoveryEncryptionKey: Data? +} + +internal struct StableChanges { + let deviceName: String? + let serialNumber: String? + let osVersion: String? + let policyVersion: UInt64? + let policySecrets: [String: Data]? + let recoverySigningPubKey: Data? + var recoveryEncryptionPubKey: Data? +} + +// CoreData doesn't handle creating an identical model from an identical URL. Help it out. +private var nsObjectModels: [URL: NSManagedObjectModel] = [:] +private let nsObjectModelsQueue = DispatchQueue(label: "com.apple.security.TrustedPeersHelper.nsObjectModels") +func getOrMakeModel(url: URL) -> NSManagedObjectModel { + return nsObjectModelsQueue.sync { + if let model = nsObjectModels[url] { + return model + } + let newModel = NSManagedObjectModel(contentsOf: url)! + nsObjectModels[url] = newModel + return newModel + } +} + +struct ContainerName: Hashable, CustomStringConvertible { + let container: String + let context: String + + func asSingleString() -> String { + // Just to be nice, hide the fact that multiple contexts exist on most machines + if self.context == OTDefaultContext { + return self.container + } else { + return self.container + "-" + self.context + } + } + + var description: String { + return "Container(\(self.container),\(self.context))" + } +} + +/// This maps to a Cuttlefish service backed by a CloudKit container, +/// and a corresponding local Core Data persistent container. +/// +/// Methods may be invoked concurrently. +class Container: NSObject { + let name: ContainerName + + private let cuttlefish: CuttlefishAPIAsync + + // Only one request (from Client) is permitted to be in progress at a time. + // That includes while waiting for network, i.e. one request must complete + // before the next can begin. Otherwise two requests could in parallel be + // fetching updates from Cuttlefish, with ensuing changeToken overwrites etc. + // This applies for mutating requests -- requests that can only read the current + // state (on the moc queue) do not need to. + internal let semaphore = DispatchSemaphore(value: 1) + + // All Core Data access happens through moc: NSManagedObjectContext. The + // moc insists on having its own queue, and all operations must happen on + // that queue. + internal let moc: NSManagedObjectContext + + // Rather than Container having its own dispatch queue, we use moc's queue + // to synchronise access to our own state as well. So the following instance + // variables must only be accessed within blocks executed by calling + // moc.perform() or moc.performAndWait(). + internal var containerMO: ContainerMO + internal var model: TPModel + + /** + Construct a Container. + + - Parameter name: The name the CloudKit container to which requests will be routed. + + The "real" container that drives CKKS etc should be named `"com.apple.security.keychain"`. + Use other names for test containers such as for rawfish (rawhide-style testing for cuttlefish) + + - Parameter persistentStoreURL: The location the local Core Data database for this container will be stored. + + - Parameter cuttlefish: Interface to cuttlefish. + */ + init(name: ContainerName, persistentStoreDescription: NSPersistentStoreDescription, cuttlefish: CuttlefishAPIAsync) throws { + var initError: Error? + var containerMO: ContainerMO? + var model: TPModel? + + // Set up Core Data stack + let url = Bundle(for: type(of: self)).url(forResource: "TrustedPeersHelper", withExtension: "momd")! + let mom = getOrMakeModel(url: url) + let persistentContainer = NSPersistentContainer(name: "TrustedPeersHelper", managedObjectModel: mom) + persistentContainer.persistentStoreDescriptions = [persistentStoreDescription] + + persistentContainer.loadPersistentStores { _, error in + initError = error + } + if let initError = initError { + throw initError + } + + let moc = persistentContainer.newBackgroundContext() + moc.mergePolicy = NSMergePolicy.mergeByPropertyStoreTrump + + moc.performAndWait { + // Fetch an existing ContainerMO record if it exists, or create and save one + do { + let containerFetch = NSFetchRequest(entityName: "Container") + containerFetch.predicate = NSPredicate(format: "name == %@", name.asSingleString()) + let fetchedContainers = try moc.fetch(containerFetch) + if let container = fetchedContainers.first as? ContainerMO { + containerMO = container + } else { + containerMO = ContainerMO(context: moc) + containerMO!.name = name.asSingleString() + } + + // Perform upgrades as needed + Container.onqueueUpgradeMachineIDSetToModel(container: containerMO!, moc: moc) + Container.onqueueUpgradeMachineIDSetToUseStatus(container: containerMO!, moc: moc) + + model = Container.loadModel(from: containerMO!) + Container.ensureEgoConsistency(from: containerMO!, model: model!) + try moc.save() + } catch { + initError = error + return + } + } + if let initError = initError { + throw initError + } + + self.name = name + self.moc = moc + self.containerMO = containerMO! + self.cuttlefish = cuttlefish + self.model = model! + + super.init() + } + + // Must be on containerMO's moc queue to call this + internal static func loadModel(from containerMO: ContainerMO) -> TPModel { + // Populate model from persistent store + let model = TPModel(decrypter: Decrypter()) + let keyFactory = TPECPublicKeyFactory() + let peers = containerMO.peers as? Set + peers?.forEach { peer in + guard let permanentInfo = TPPeerPermanentInfo(peerID: peer.peerID!, + data: peer.permanentInfo! as Data, + sig: peer.permanentInfoSig! as Data, + keyFactory: keyFactory) else { + return + } + model.registerPeer(with: permanentInfo) + if let data = peer.stableInfo, let sig = peer.stableInfoSig { + if let stableInfo = TPPeerStableInfo(data: data as Data, sig: sig as Data) { + do { + try model.update(stableInfo, forPeerWithID: permanentInfo.peerID) + } catch { + os_log("loadModel unable to update stable info for peer(%@): %@", log: tplogDebug, type: .default, peer, error as CVarArg) + } + } else { + os_log("loadModel: peer %@ has unparseable stable info", log: tplogDebug, type: .default, permanentInfo.peerID) + } + } else { + os_log("loadModel: peer %@ has no stable info", log: tplogDebug, type: .default, permanentInfo.peerID) + } + if let data = peer.dynamicInfo, let sig = peer.dynamicInfoSig { + if let dynamicInfo = TPPeerDynamicInfo(data: data as Data, sig: sig as Data) { + do { + try model.update(dynamicInfo, forPeerWithID: permanentInfo.peerID) + } catch { + os_log("loadModel unable to update dynamic info for peer(%@): %@", log: tplogDebug, type: .default, peer, error as CVarArg) + } + } else { + os_log("loadModel: peer %@ has unparseable dynamic info", log: tplogDebug, type: .default, permanentInfo.peerID) + } + } else { + os_log("loadModel: peer %@ has no dynamic info", log: tplogDebug, type: .default, permanentInfo.peerID) + } + peer.vouchers?.forEach { + let v = $0 as! VoucherMO + if let data = v.voucherInfo, let sig = v.voucherInfoSig { + if let voucher = TPVoucher(infoWith: data, sig: sig) { + model.register(voucher) + } + } + } + } + + // Register persisted policies (cached from cuttlefish) + let policies = containerMO.policies as? Set + policies?.forEach { policyMO in + if let policyHash = policyMO.policyHash, + let policyData = policyMO.policyData { + if let policyDoc = TPPolicyDocument.policyDoc(withHash: policyHash, data: policyData) { + model.register(policyDoc) + } + } + } + + // Register built-in policies + builtInPolicyDocuments().forEach { policyDoc in + model.register(policyDoc) + } + + let knownMachines = containerMO.machines as? Set ?? Set() + let allowedMachineIDs = Set(knownMachines.filter { $0.status == TPMachineIDStatus.allowed.rawValue }.compactMap { $0.machineID }) + let disallowedMachineIDs = Set(knownMachines.filter { $0.status == TPMachineIDStatus.disallowed.rawValue }.compactMap { $0.machineID }) + + os_log("loadModel: allowedMachineIDs: %@", log: tplogDebug, type: .default, allowedMachineIDs) + os_log("loadModel: disallowedMachineIDs: %@", log: tplogDebug, type: .default, disallowedMachineIDs) + + if allowedMachineIDs.count == 0 { + os_log("loadModel: no allowedMachineIDs?", log: tplogDebug, type: .default) + } + + return model + } + + // Must be on containerMO's moc queue to call this + internal static func ensureEgoConsistency(from containerMO: ContainerMO, model: TPModel) { + guard let egoPeerID = containerMO.egoPeerID, + let egoStableData = containerMO.egoPeerStableInfo, + let egoStableSig = containerMO.egoPeerStableInfoSig + else { + os_log("ensureEgoConsistency failed to find ego peer information", log: tplogDebug, type: .error) + return + } + + guard let containerEgoStableInfo = TPPeerStableInfo(data: egoStableData, sig: egoStableSig) else { + os_log("ensureEgoConsistency failed to create TPPeerStableInfo from container", log: tplogDebug, type: .error) + return + } + + guard let modelStableInfo = model.getStableInfoForPeer(withID: egoPeerID) else { + os_log("ensureEgoConsistency failed to create TPPeerStableInfo from model", log: tplogDebug, type: .error) + return + } + + if modelStableInfo.clock > containerEgoStableInfo.clock { + containerMO.egoPeerStableInfo = modelStableInfo.data + containerMO.egoPeerStableInfoSig = modelStableInfo.sig + } + + } + + static func dictionaryRepresentation(bottle: BottleMO) -> [String: Any] { + var dict: [String: String] = [:] + + dict["bottleID"] = bottle.bottleID + dict["peerID"] = bottle.peerID + dict["signingSPKI"] = bottle.escrowedSigningSPKI?.base64EncodedString() + dict["signatureUsingPeerKey"] = bottle.signatureUsingPeerKey?.base64EncodedString() + dict["signatureUsingSPKI"] = bottle.signatureUsingEscrowKey?.base64EncodedString() + // ignore the bottle contents; they're mostly unreadable + + return dict + } + + static func peerdictionaryRepresentation(peer: TPPeer) -> [String: Any] { + var peerDict: [String: Any] = [ + "permanentInfo": peer.permanentInfo.dictionaryRepresentation(), + "peerID": peer.peerID, + ] + if let stableInfo = peer.stableInfo { + peerDict["stableInfo"] = stableInfo.dictionaryRepresentation() + } + if let dynamicInfo = peer.dynamicInfo { + peerDict["dynamicInfo"] = dynamicInfo.dictionaryRepresentation() + } + + return peerDict + } + + func onQueueDetermineLocalTrustStatus(reply: @escaping (TrustedPeersHelperEgoPeerStatus, Error?) -> Void) { + let peerCountsByModelID = self.model.peerCountsByModelID() + + if let egoPeerID = self.containerMO.egoPeerID { + var status = self.model.statusOfPeer(withID: egoPeerID) + var isExcluded: Bool = (status == .excluded) + + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, loadError in + var returnError = loadError + + guard returnError == nil else { + var isLocked = false + if let error = (loadError as NSError?) { + os_log("trust status: Unable to load ego keys: %@", log: tplogDebug, type: .default, error as CVarArg) + if error.code == errSecItemNotFound && error.domain == NSOSStatusErrorDomain { + os_log("trust status: Lost the ego key pair, returning 'excluded' in hopes of fixing up the identity", log: tplogDebug, type: .debug) + isExcluded = true + status = .excluded + } else if error.code == errSecInteractionNotAllowed && error.domain == NSOSStatusErrorDomain { + // we have an item, but can't read it, suppressing error + isLocked = true + returnError = nil + } + } + + let egoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: egoPeerID, + status: status, + peerCountsByModelID: peerCountsByModelID, + isExcluded: isExcluded, + isLocked: isLocked) + reply(egoStatus, returnError) + return + } + + //ensure egoPeerKeys are populated + guard egoPeerKeys != nil else { + os_log("trust status: No error but Ego Peer Keys are nil", log: tplogDebug, type: .default) + let egoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: egoPeerID, + status: .excluded, + peerCountsByModelID: peerCountsByModelID, + isExcluded: true, + isLocked: false) + + reply(egoStatus, loadError) + return + } + + let egoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: egoPeerID, + status: status, + peerCountsByModelID: peerCountsByModelID, + isExcluded: isExcluded, + isLocked: false) + reply(egoStatus, nil) + return + } + + } else { + // With no ego peer ID, either return 'excluded' if there are extant peers, or 'unknown' to signal no peers at all + if self.model.allPeerIDs().isEmpty { + os_log("No existing peers in account", log: tplogDebug, type: .debug) + let egoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: nil, + status: .unknown, + peerCountsByModelID: peerCountsByModelID, + isExcluded: false, + isLocked: false) + reply(egoStatus, nil) + return + } else { + os_log("Existing peers in account, but we don't have a peer ID. We are excluded.", log: tplogDebug, type: .debug) + let egoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: nil, + status: .excluded, + peerCountsByModelID: peerCountsByModelID, + isExcluded: true, + isLocked: false) + reply(egoStatus, nil) + return + } + } + } + + func trustStatus(reply: @escaping (TrustedPeersHelperEgoPeerStatus, Error?) -> Void) { + self.semaphore.wait() + let reply: (TrustedPeersHelperEgoPeerStatus, Error?) -> Void = { + // Suppress logging of successful replies here; it's not that useful + let logType: OSLogType = $1 == nil ? .debug : .info + os_log("trustStatus complete: %@ %@", + log: tplogTrace, type: logType, TPPeerStatusToString($0.egoStatus), traceError($1)) + + self.semaphore.signal() + reply($0, $1) + } + self.moc.performAndWait { + // Knowledge of your peer status only exists if you know about other peers. If you haven't fetched, fetch. + if self.containerMO.changeToken == nil { + self.fetchAndPersistChanges { fetchError in + guard fetchError == nil else { + if let error = fetchError { + os_log("Unable to fetch changes, trust status is unknown: %@", log: tplogDebug, type: .default, error as CVarArg) + } + + let egoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: nil, + status: .unknown, + peerCountsByModelID: [:], + isExcluded: false, + isLocked: false) + reply(egoStatus, fetchError) + return + } + + self.moc.performAndWait { + self.onQueueDetermineLocalTrustStatus(reply: reply) + } + } + } else { + self.onQueueDetermineLocalTrustStatus(reply: reply) + } + } + } + + func fetchTrustState(reply: @escaping (TrustedPeersHelperPeerState?, [TrustedPeersHelperPeer]?, Error?) -> Void) { + let reply: (TrustedPeersHelperPeerState?, [TrustedPeersHelperPeer]?, Error?) -> Void = { + os_log("fetch trust state complete: %@ %@", + log: tplogTrace, type: .info, String(reflecting: $0), traceError($2)) + reply($0, $1, $2) + } + + self.moc.performAndWait { + if let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig { + + let keyFactory = TPECPublicKeyFactory() + guard let permanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + os_log("fetchTrustState failed to create TPPeerPermanentInfo", log: tplogDebug, type: .error) + reply(nil, nil, ContainerError.invalidPermanentInfoOrSig) + return + } + + let isPreapproved = self.model.hasPeerPreapprovingKey(permanentInfo.signingPubKey.spki()) + os_log("fetchTrustState: ego peer is %@", log: tplogDebug, type: .default, isPreapproved ? "preapproved" : "not yet preapproved") + + let egoPeerStatus = TrustedPeersHelperPeerState(peerID: egoPeerID, + isPreapproved: isPreapproved, + status: self.model.statusOfPeer(withID: egoPeerID), + memberChanges: false, + unknownMachineIDs: self.onqueueFullIDMSListWouldBeHelpful()) + + var tphPeers: [TrustedPeersHelperPeer] = [] + + if let egoPeer = self.model.peer(withID: egoPeerID) { + egoPeer.trustedPeerIDs.forEach { trustedPeerID in + if let peer = self.model.peer(withID: trustedPeerID) { + let peerViews = try? self.model.getViewsForPeer(peer.permanentInfo, + stableInfo: peer.stableInfo, + inViews: Set()) + + tphPeers.append(TrustedPeersHelperPeer(peerID: trustedPeerID, + signingSPKI: peer.permanentInfo.signingPubKey.spki(), + encryptionSPKI: peer.permanentInfo.encryptionPubKey.spki(), + viewList: peerViews ?? Set())) + } else { + os_log("No peer for trusted ID %@", log: tplogDebug, type: .default, trustedPeerID) + } + } + } else { + os_log("No ego peer in model; no trusted peers", log: tplogDebug, type: .default) + } + + os_log("Returning trust state: %@ %@", log: tplogDebug, type: .default, egoPeerStatus, tphPeers) + reply(egoPeerStatus, tphPeers, nil) + } else { + // With no ego peer ID, there are no trusted peers + os_log("No peer ID => no trusted peers", log: tplogDebug, type: .debug) + reply(TrustedPeersHelperPeerState(peerID: nil, isPreapproved: false, status: .unknown, memberChanges: false, unknownMachineIDs: false), [], nil) + } + } + } + + func dump(reply: @escaping ([AnyHashable: Any]?, Error?) -> Void) { + let reply: ([AnyHashable: Any]?, Error?) -> Void = { + os_log("dump complete: %@", + log: tplogTrace, type: .info, traceError($1)) + reply($0, $1) + } + self.moc.performAndWait { + var d: [AnyHashable: Any] = [:] + + if let egoPeerID = self.containerMO.egoPeerID { + if let peer = self.model.peer(withID: egoPeerID) { + d["self"] = Container.peerdictionaryRepresentation(peer: peer) + } else { + d["self"] = ["peerID": egoPeerID] + } + } else { + d["self"] = [:] + } + + d["peers"] = self.model.allPeers().filter { $0.peerID != self.containerMO.egoPeerID }.map { peer in + Container.peerdictionaryRepresentation(peer: peer) + } + + d["vouchers"] = self.model.allVouchers().map { $0.dictionaryRepresentation() } + + if let bottles = self.containerMO.bottles as? Set { + d["bottles"] = bottles.map { Container.dictionaryRepresentation(bottle: $0) } + } else { + d["bottles"] = [] + } + + let midList = self.onqueueCurrentMIDList() + d["machineIDsAllowed"] = midList.machineIDs(in: .allowed).sorted() + d["machineIDsDisallowed"] = midList.machineIDs(in: .disallowed).sorted() + + reply(d, nil) + } + } + + func dumpEgoPeer(reply: @escaping (String?, TPPeerPermanentInfo?, TPPeerStableInfo?, TPPeerDynamicInfo?, Error?) -> Void) { + let reply: (String?, TPPeerPermanentInfo?, TPPeerStableInfo?, TPPeerDynamicInfo?, Error?) -> Void = { + os_log("dumpEgoPeer complete: %@", log: tplogTrace, type: .info, traceError($4)) + reply($0, $1, $2, $3, $4) + } + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + reply(nil, nil, nil, nil, ContainerError.noPreparedIdentity) + return + } + + guard let peer = self.model.peer(withID: egoPeerID) else { + reply(egoPeerID, nil, nil, nil, nil) + return + } + + reply(egoPeerID, peer.permanentInfo, peer.stableInfo, peer.dynamicInfo, nil) + } + } + + func validatePeers(request: ValidatePeersRequest, reply: @escaping ([AnyHashable: Any]?, Error?) -> Void) { + self.semaphore.wait() + let reply: ([AnyHashable: Any]?, Error?) -> Void = { + os_log("validatePeers complete %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + self.cuttlefish.validatePeers(request) { response, error in + os_log("ValidatePeers(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("validatePeers failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, error ?? ContainerError.cloudkitResponseMissing) + return + } + + var info: [AnyHashable: Any] = [:] + info["health"] = response.validatorsHealth as AnyObject + info["results"] = try? JSONSerialization.jsonObject(with: response.jsonUTF8Data()) + + reply(info, nil) + } + } + + func getViews(inViews: [String], reply: @escaping ([String]?, Error?) -> Void) { + let reply: ([String]?, Error?) -> Void = { + os_log("getViews complete %@", log: tplogTrace, type: .info, traceError($1)) + reply($0, $1) + } + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig, + let egoStableData = self.containerMO.egoPeerStableInfo, + let egoStableSig = self.containerMO.egoPeerStableInfoSig + else { + os_log("getViews failed to find ego peer information", log: tplogDebug, type: .error) + reply(nil, ContainerError.noPreparedIdentity) + return + } + guard let stableInfo = TPPeerStableInfo(data: egoStableData, sig: egoStableSig) else { + os_log("getViews failed to create TPPeerStableInfo", log: tplogDebug, type: .error) + reply(nil, ContainerError.invalidStableInfoOrSig) + return + } + + let keyFactory = TPECPublicKeyFactory() + guard let permanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + os_log("getViews failed to create TPPeerPermanentInfo", log: tplogDebug, type: .error) + reply(nil, ContainerError.invalidPermanentInfoOrSig) + return + } + + do { + let views = try self.model.getViewsForPeer(permanentInfo, stableInfo: stableInfo, inViews: Set(inViews)) + reply(Array(views), nil) + } catch { + reply(nil, error) + return + } + } + } + + func reset(reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("reset complete %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + let request = ResetRequest() + self.cuttlefish.reset(request) { response, error in + os_log("Reset(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("reset failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error ?? ContainerError.cloudkitResponseMissing) + return + } + + // Erase container's persisted state + self.moc.performAndWait { + self.moc.delete(self.containerMO) + self.containerMO = ContainerMO(context: self.moc) + self.containerMO.name = self.name.asSingleString() + self.model = Container.loadModel(from: self.containerMO) + do { + try self.onQueuePersist(changes: response.changes) + os_log("reset succeded", log: tplogDebug, type: .default) + reply(nil) + } catch { + os_log("reset persist failed: %@", log: tplogDebug, type: .default, (error as CVarArg)) + reply(error) + } + } + } + } + } + + func localReset(reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("localReset complete %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + do { + // Erase container's persisted state + self.moc.delete(self.containerMO) + self.containerMO = ContainerMO(context: self.moc) + self.containerMO.name = self.name.asSingleString() + self.model = Container.loadModel(from: self.containerMO) + try self.moc.save() + } catch { + reply(error) + return + } + reply(nil) + } + } + + func loadOrCreateKeyPair(privateKeyPersistentRef: Data?) throws -> _SFECKeyPair { + if let privateKeyPersistentRef = privateKeyPersistentRef { + return try TPHObjectiveC.fetchKeyPair(withPrivateKeyPersistentRef: privateKeyPersistentRef) + } else { + let keySpecifier = _SFECKeySpecifier(curve: SFEllipticCurve.nistp384) + guard let keyPair = _SFECKeyPair(randomKeyPairWith: keySpecifier) else { + throw ContainerError.unableToCreateKeyPair + } + return keyPair + } + } + + // policyVersion should only be non-nil for testing, to override prevailingPolicyVersion + func prepare(epoch: UInt64, + machineID: String, + bottleSalt: String, + bottleID: String, + modelID: String, + deviceName: String?, + serialNumber: String, + osVersion: String, + policyVersion: UInt64?, + policySecrets: [String: Data]?, + signingPrivateKeyPersistentRef: Data?, + encryptionPrivateKeyPersistentRef: Data?, + reply: @escaping (String?, Data?, Data?, Data?, Data?, Error?) -> Void) { + self.semaphore.wait() + let reply: (String?, Data?, Data?, Data?, Data?, Error?) -> Void = { + os_log("prepare complete peerID: %@ %@", + log: tplogTrace, type: .info, ($0 ?? "NULL") as CVarArg, traceError($5)) + self.semaphore.signal() + reply($0, $1, $2, $3, $4, $5) + } + + // Create a new peer identity with random keys, and store the keys in keychain + let permanentInfo: TPPeerPermanentInfo + let signingKeyPair: _SFECKeyPair + let encryptionKeyPair: _SFECKeyPair + do { + signingKeyPair = try self.loadOrCreateKeyPair(privateKeyPersistentRef: signingPrivateKeyPersistentRef) + encryptionKeyPair = try self.loadOrCreateKeyPair(privateKeyPersistentRef: encryptionPrivateKeyPersistentRef) + + permanentInfo = try TPPeerPermanentInfo(machineID: machineID, + modelID: modelID, + epoch: 1, + signing: signingKeyPair, + encryptionKeyPair: encryptionKeyPair, + peerIDHashAlgo: TPHashAlgo.SHA256) + + } catch { + reply(nil, nil, nil, nil, nil, error) + return + } + + let peerID = permanentInfo.peerID + + let bottle: BottledPeer + do { + bottle = try BottledPeer(peerID: peerID, + bottleID: bottleID, + peerSigningKey: signingKeyPair, + peerEncryptionKey: encryptionKeyPair, + bottleSalt: bottleSalt) + + _ = try saveSecret(bottle.secret, label: peerID) + } catch { + os_log("bottle creation failed: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, nil, nil, nil, error) + return + } + + saveEgoKeyPair(signingKeyPair, identifier: signingKeyIdentifier(peerID: peerID)) { success, error in + guard success else { + os_log("Unable to save signing key: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + reply(nil, nil, nil, nil, nil, error ?? ContainerError.failedToStoreIdentity) + return + } + saveEgoKeyPair(encryptionKeyPair, identifier: encryptionKeyIdentifier(peerID: peerID)) { success, error in + guard success else { + os_log("Unable to save encryption key: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + reply(nil, nil, nil, nil, nil, error ?? ContainerError.failedToStoreIdentity) + return + } + + // Save the prepared identity as containerMO.egoPeer* and its bottle + self.moc.performAndWait { + do { + let policyVersion = policyVersion ?? prevailingPolicyVersion + let policyDoc = try self.getPolicyDoc(policyVersion) + + let stableInfo = TPPeerStableInfo(clock: 1, + policyVersion: policyDoc.policyVersion, + policyHash: policyDoc.policyHash, + policySecrets: policySecrets, + deviceName: deviceName, + serialNumber: serialNumber, + osVersion: osVersion, + signing: signingKeyPair, + recoverySigningPubKey: nil, + recoveryEncryptionPubKey: nil, + error: nil) + + self.containerMO.egoPeerID = permanentInfo.peerID + self.containerMO.egoPeerPermanentInfo = permanentInfo.data + self.containerMO.egoPeerPermanentInfoSig = permanentInfo.sig + self.containerMO.egoPeerStableInfo = stableInfo.data + self.containerMO.egoPeerStableInfoSig = stableInfo.sig + + let bottleMO = BottleMO(context: self.moc) + bottleMO.peerID = bottle.peerID + bottleMO.bottleID = bottle.bottleID + bottleMO.escrowedSigningSPKI = bottle.escrowSigningSPKI + bottleMO.signatureUsingEscrowKey = bottle.signatureUsingEscrowKey + bottleMO.signatureUsingPeerKey = bottle.signatureUsingPeerKey + bottleMO.contents = bottle.contents + + self.containerMO.addToBottles(bottleMO) + + try self.moc.save() + + reply(permanentInfo.peerID, permanentInfo.data, permanentInfo.sig, stableInfo.data, stableInfo.sig, nil) + } catch { + reply(nil, nil, nil, nil, nil, error) + } + } + } + } + } + func getEgoEpoch(reply: @escaping (UInt64, Error?) -> Void) { + let reply: (UInt64, Error?) -> Void = { + os_log("getEgoEpoch complete: %d %@", log: tplogTrace, type: .info, $0, traceError($1)) + reply($0, $1) + } + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + reply(0, ContainerError.noPreparedIdentity) + return + } + guard let egoPeer = self.model.peer(withID: egoPeerID) else { + reply(0, ContainerError.noPreparedIdentity) + return + } + + reply(egoPeer.permanentInfo.epoch, nil) + } + } + func establish(ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]?, + reply: @escaping (String?, [CKRecord], Error?) -> Void) { + self.semaphore.wait() + let reply: (String?, [CKRecord], Error?) -> Void = { + os_log("establish complete peer: %@ %@", + log: tplogTrace, type: .default, ($0 ?? "NULL") as CVarArg, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.moc.performAndWait { + self.onqueueEstablish(ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys, + reply: reply) + } + } + + func onqueueTTRUntrusted() -> Void { + let ttr = SecTapToRadar(tapToRadar: "Device not IDMS trusted", + description: "Device not IDMS trusted", + radar: "52874119") + ttr.trigger() + } + + func onqueueEstablish(ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]?, + reply: @escaping (String?, [CKRecord], Error?) -> Void) { + // Fetch ego peer identity from local storage. + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig, + let egoStableData = self.containerMO.egoPeerStableInfo, + let egoStableSig = self.containerMO.egoPeerStableInfoSig + else { + reply(nil, [], ContainerError.noPreparedIdentity) + return + } + + let keyFactory = TPECPublicKeyFactory() + guard let selfPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + reply(nil, [], ContainerError.invalidPermanentInfoOrSig) + return + } + guard let selfStableInfo = TPPeerStableInfo(data: egoStableData, sig: egoStableSig) else { + os_log("cannot create TPPeerStableInfo", log: tplogDebug, type: .default) + reply(nil, [], ContainerError.invalidStableInfoOrSig) + return + } + guard self.onqueueMachineIDAllowedByIDMS(machineID: selfPermanentInfo.machineID) else { + os_log("establish: self machineID %@ not on list", log: tplogDebug, type: .debug, selfPermanentInfo.machineID) + self.onqueueTTRUntrusted() + reply(nil, [], ContainerError.preparedIdentityNotOnAllowedList(selfPermanentInfo.machineID)) + return + } + + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, error in + guard let egoPeerKeys = egoPeerKeys else { + os_log("Don't have my own peer keys; can't establish: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + reply(nil, [], error) + return + } + self.moc.performAndWait { + let viewKeys: [ViewKeys] = ckksKeys.map(ViewKeys.convert) + let allTLKShares: [TLKShare] + do { + let octagonShares = try makeTLKShares(ckksTLKs: ckksKeys.map { $0.tlk }, asPeer: egoPeerKeys, toPeer: egoPeerKeys, epoch: Int(selfPermanentInfo.epoch)) + let sosShares = tlkShares.map { TLKShare.convert(ckksTLKShare: $0) } + + allTLKShares = octagonShares + sosShares + } catch { + os_log("Unable to make TLKShares for self: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, [], error) + return + } + + let dynamicInfo: TPPeerDynamicInfo + do { + dynamicInfo = try self.model.dynamicInfo(forJoiningPeerID: egoPeerID, + peerPermanentInfo: selfPermanentInfo, + peerStableInfo: selfStableInfo, + sponsorID: nil, + preapprovedKeys: preapprovedKeys, + signing: egoPeerKeys.signingKey, + currentMachineIDs: self.onqueueCurrentMIDList()) + + os_log("dynamic info: %@", log: tplogDebug, type: .default, dynamicInfo) + } catch { + reply(nil, [], error) + return + } + + let peer = Peer.with { + $0.peerID = egoPeerID + $0.permanentInfoAndSig.peerPermanentInfo = egoPermData + $0.permanentInfoAndSig.sig = egoPermSig + $0.stableInfoAndSig.peerStableInfo = egoStableData + $0.stableInfoAndSig.sig = egoStableSig + $0.dynamicInfoAndSig = SignedPeerDynamicInfo(dynamicInfo) + } + + let bottle: Bottle + do { + bottle = try self.assembleBottle(egoPeerID: egoPeerID) + } catch { + reply(nil, [], error) + return + } + os_log("Beginning establish for peer %@", log: tplogDebug, type: .default, egoPeerID) + os_log("Establish permanentInfo: %@", log: tplogDebug, type: .debug, egoPermData.base64EncodedString()) + os_log("Establish permanentInfoSig: %@", log: tplogDebug, type: .debug, egoPermSig.base64EncodedString()) + os_log("Establish stableInfo: %@", log: tplogDebug, type: .debug, egoStableData.base64EncodedString()) + os_log("Establish stableInfoSig: %@", log: tplogDebug, type: .debug, egoStableSig.base64EncodedString()) + os_log("Establish dynamicInfo: %@", log: tplogDebug, type: .debug, peer.dynamicInfoAndSig.peerDynamicInfo.base64EncodedString()) + os_log("Establish dynamicInfoSig: %@", log: tplogDebug, type: .debug, peer.dynamicInfoAndSig.sig.base64EncodedString()) + + os_log("Establish introducing %d key sets, %d tlk shares", log: tplogDebug, type: .default, viewKeys.count, allTLKShares.count) + + do { + os_log("Establish bottle: %@", log: tplogDebug, type: .debug, try bottle.serializedData().base64EncodedString()) + os_log("Establish peer: %@", log: tplogDebug, type: .debug, try peer.serializedData().base64EncodedString()) + } catch { + os_log("Establish unable to encode bottle/peer: %@", log: tplogDebug, type: .debug, error as CVarArg) + } + + let request = EstablishRequest.with { + $0.peer = peer + $0.bottle = bottle + $0.viewKeys = viewKeys + $0.tlkShares = allTLKShares + } + self.cuttlefish.establish(request) { response, error in + os_log("Establish(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + os_log("Establish: viewKeys: %@", String(describing: viewKeys)) + guard let response = response, error == nil else { + os_log("establish failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, [], error ?? ContainerError.cloudkitResponseMissing) + return + } + + do { + os_log("Establish returned changes: %@", log: tplogDebug, type: .default, try response.changes.jsonString()) + } catch { + os_log("Establish returned changes, but they can't be serialized", log: tplogDebug, type: .default) + } + + let keyHierarchyRecords = response.zoneKeyHierarchyRecords.compactMap { CKRecord($0) } + + do { + try self.persist(changes: response.changes) + + guard response.changes.more == false else { + os_log("establish succeeded, but more changes need fetching...", log: tplogDebug, type: .default) + + self.fetchAndPersistChanges { fetchError in + guard fetchError == nil else { + // This is an odd error condition: we might be able to fetch again and be in a good state... + os_log("fetch-after-establish failed: %@", log: tplogDebug, type: .default, (fetchError as CVarArg?) ?? "no error") + reply(nil, keyHierarchyRecords, fetchError) + return; + } + + os_log("fetch-after-establish succeeded", log: tplogDebug, type: .default) + reply(egoPeerID, keyHierarchyRecords, nil) + } + return + } + + os_log("establish succeeded", log: tplogDebug, type: .default) + reply(egoPeerID, keyHierarchyRecords, nil) + } catch { + os_log("establish handling failed: %@", log: tplogDebug, type: .default, (error as CVarArg)) + reply(nil, keyHierarchyRecords, error) + } + } + } + } + } + + func setRecoveryKey(recoveryKey: String, salt: String, ckksKeys: [CKKSKeychainBackedKeySet], reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("setRecoveryKey complete: %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + os_log("beginning a setRecoveryKey", log: tplogDebug, type: .default) + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("no prepared identity, cannot set recovery key", log: tplogDebug, type: .default) + reply(ContainerError.noPreparedIdentity) + return + } + + var recoveryKeys: RecoveryKey + do { + recoveryKeys = try RecoveryKey(recoveryKeyString: recoveryKey, recoverySalt: salt) + } catch { + os_log("failed to create recovery keys: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(ContainerError.failedToCreateRecoveryKey) + return + } + + let signingPublicKey: Data = recoveryKeys.peerKeys.signingVerificationKey.keyData + let encryptionPublicKey: Data = recoveryKeys.peerKeys.encryptionVerificationKey.keyData + + os_log("setRecoveryKey signingPubKey: %@", log: tplogDebug, type: .debug, signingPublicKey.base64EncodedString()) + os_log("setRecoveryKey encryptionPubKey: %@", log: tplogDebug, type: .debug, encryptionPublicKey.base64EncodedString()) + + guard let stableInfoData = self.containerMO.egoPeerStableInfo else { + os_log("stableInfo does not exist", log: tplogDebug, type: .default) + reply(ContainerError.nonMember) + return + } + guard let stableInfoSig = self.containerMO.egoPeerStableInfoSig else { + os_log("stableInfoSig does not exist", log: tplogDebug, type: .default) + reply(ContainerError.nonMember) + return + } + guard let permInfoData = self.containerMO.egoPeerPermanentInfo else { + os_log("permanentInfo does not exist", log: tplogDebug, type: .default) + reply(ContainerError.nonMember) + return + } + guard let permInfoSig = self.containerMO.egoPeerPermanentInfoSig else { + os_log("permInfoSig does not exist", log: tplogDebug, type: .default) + reply(ContainerError.nonMember) + return + } + guard let stableInfo = TPPeerStableInfo(data: stableInfoData, sig: stableInfoSig) else { + os_log("cannot create TPPeerStableInfo", log: tplogDebug, type: .default) + reply(ContainerError.invalidStableInfoOrSig) + return + } + let keyFactory = TPECPublicKeyFactory() + guard let permanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: permInfoData, sig: permInfoSig, keyFactory: keyFactory) else { + os_log("cannot create TPPeerPermanentInfo", log: tplogDebug, type: .default) + reply(ContainerError.invalidStableInfoOrSig) + return + } + + loadEgoKeyPair(identifier: signingKeyIdentifier(peerID: egoPeerID)) { signingKeyPair, error in + guard let signingKeyPair = signingKeyPair else { + os_log("handle: no signing key pair: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error) + return + } + self.moc.performAndWait { + do { + let tlkShares = try makeTLKShares(ckksTLKs: ckksKeys.map { $0.tlk }, + asPeer: recoveryKeys.peerKeys, + toPeer: recoveryKeys.peerKeys, + epoch: Int(permanentInfo.epoch)) + + let policyVersion = stableInfo.policyVersion + let policyDoc = try self.getPolicyDoc(policyVersion) + + let updatedStableInfo = TPPeerStableInfo(clock: stableInfo.clock + 1, + policyVersion: policyDoc.policyVersion, + policyHash: policyDoc.policyHash, + policySecrets: stableInfo.policySecrets, + deviceName: stableInfo.deviceName, + serialNumber: stableInfo.serialNumber, + osVersion: stableInfo.osVersion, + signing: signingKeyPair, + recoverySigningPubKey: signingPublicKey, + recoveryEncryptionPubKey: encryptionPublicKey, + error: nil) + let signedStableInfo = SignedPeerStableInfo(updatedStableInfo) + + let request = SetRecoveryKeyRequest.with { + $0.peerID = egoPeerID + $0.recoverySigningPubKey = signingPublicKey + $0.recoveryEncryptionPubKey = encryptionPublicKey + $0.stableInfoAndSig = signedStableInfo + $0.tlkShares = tlkShares + $0.changeToken = self.containerMO.changeToken ?? "" + } + + self.cuttlefish.setRecoveryKey(request) { response, error in + os_log("SetRecoveryKey(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("setRecoveryKey failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error ?? ContainerError.cloudkitResponseMissing) + return + } + + self.moc.performAndWait { + do { + self.containerMO.egoPeerStableInfo = updatedStableInfo.data + self.containerMO.egoPeerStableInfoSig = updatedStableInfo.sig + try self.onQueuePersist(changes: response.changes) + + os_log("setRecoveryKey succeeded", log: tplogDebug, type: .default) + reply(nil) + } catch { + os_log("setRecoveryKey handling failed: %@", log: tplogDebug, type: .default, (error as CVarArg)) + reply(error) + } + } + } + } catch { + reply(error) + } + } + } + } + } + + func currentSetContainerBottleID(bottleMOs: Set, bottleID: String) -> (Bool) { + let bmos = bottleMOs.filter { + $0.bottleID == bottleID + } + return !bmos.isEmpty + } + + func findBottleForEscrowRecordID(bottleID: String, reply: @escaping (BottleMO?, Error?) -> Void) { + + var bmo: BottleMO? + var bottles: Set = [] + var shouldPerformFetch = false + + if let containerBottles = self.containerMO.bottles as? Set { + if self.currentSetContainerBottleID(bottleMOs: containerBottles, bottleID: bottleID) == false { + shouldPerformFetch = true + } else { + bottles = containerBottles + } + } else { + shouldPerformFetch = true + } + + if shouldPerformFetch == true { + self.fetchViableBottlesWithSemaphore { _, _, error in + guard error == nil else { + os_log("fetchViableBottles failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, error) + return + } + + guard let newBottles = self.containerMO.bottles as? Set else { + os_log("no bottles on container: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, ContainerError.noBottlesPresent) + return + } + + guard self.currentSetContainerBottleID(bottleMOs: newBottles, bottleID: bottleID) == true else { + reply(nil, ContainerError.noBottlesForEscrowRecordID) + return + } + + os_log("findBottleForEscrowRecordID found bottle: %@", log: tplogDebug, type: .default, newBottles) + + bottles = newBottles.filter { + $0.bottleID == bottleID + } + if bottles.count > 1 { + reply(nil, ContainerError.tooManyBottlesForPeer) + return + } + bmo = bottles.removeFirst() + reply(bmo, nil) + } + } else { + var filteredBottles = bottles.filter { + $0.bottleID == bottleID + } + if filteredBottles.count > 1 { + reply(nil, ContainerError.tooManyBottlesForPeer) + return + } + bmo = filteredBottles.removeFirst() + reply(bmo, nil) + } + } + + func onqueueRecoverBottle(managedBottle: BottleMO, entropy: Data, bottleSalt: String) throws -> BottledPeer { + guard let bottledContents = managedBottle.contents else { + throw ContainerError.bottleDoesNotContainContents + } + guard let signatureUsingEscrowKey = managedBottle.signatureUsingEscrowKey else { + throw ContainerError.bottleDoesNotContainEscrowKeySignature + } + + guard let signatureUsingPeerKey = managedBottle.signatureUsingPeerKey else { + throw ContainerError.bottleDoesNotContainerPeerKeySignature + } + guard let sponsorPeerID = managedBottle.peerID else { + throw ContainerError.bottleDoesNotContainPeerID + } + + //verify bottle signature using peer + do { + guard let sponsorPeer = self.model.peer(withID: sponsorPeerID) else { + os_log("recover bottle: Unable to find peer that created the bottle", log: tplogDebug, type: .default) + throw ContainerError.bottleCreatingPeerNotFound + } + guard let signingKey: _SFECPublicKey = sponsorPeer.permanentInfo.signingPubKey as? _SFECPublicKey else { + os_log("recover bottle: Unable to create a sponsor public key", log: tplogDebug, type: .default) + throw ContainerError.signatureVerificationFailed + } + + _ = try BottledPeer.verifyBottleSignature(data: bottledContents, signature: signatureUsingPeerKey, pubKey: signingKey) + } catch { + os_log("Verification of bottled signature failed: %@", log: tplogDebug, type: .default, error as CVarArg) + throw ContainerError.failedToCreateBottledPeer + } + + do { + return try BottledPeer(contents: bottledContents, + secret: entropy, + bottleSalt: bottleSalt, + signatureUsingEscrow: signatureUsingEscrowKey, + signatureUsingPeerKey: signatureUsingPeerKey) + } catch { + os_log("Creation of Bottled Peer failed with bottle salt: %@,\nAttempting with empty bottle salt", bottleSalt) + + do { + return try BottledPeer(contents: bottledContents, + secret: entropy, + bottleSalt: "", + signatureUsingEscrow: signatureUsingEscrowKey, + signatureUsingPeerKey: signatureUsingPeerKey) + } catch { + os_log("Creation of Bottled Peer failed: %@", log: tplogDebug, type: .default, error as CVarArg) + throw ContainerError.failedToCreateBottledPeer + } + } + } + + func vouchWithBottle(bottleID: String, + entropy: Data, + bottleSalt: String, + tlkShares: [CKKSTLKShare], + reply: @escaping (Data?, Data?, Error?) -> Void) { + self.semaphore.wait() + let reply: (Data?, Data?, Error?) -> Void = { + os_log("vouchWithBottle complete: %@", + log: tplogTrace, type: .info, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.fetchAndPersistChanges { error in + guard error == nil else { + os_log("vouchWithBottle unable to fetch changes: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "") + reply(nil, nil, error) + return + } + + self.findBottleForEscrowRecordID(bottleID: bottleID) { returnedBMO, error in + self.moc.performAndWait { + guard error == nil else { + os_log("vouchWithBottle unable to find bottle for escrow record id: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "") + reply(nil, nil, error) + return + } + + guard let bmo: BottleMO = returnedBMO else { + os_log("vouchWithBottle bottle is nil: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "") + reply(nil, nil, error) + return + } + + guard let bottledContents = bmo.contents else { + reply(nil, nil, ContainerError.bottleDoesNotContainContents) + return + } + guard let signatureUsingEscrowKey = bmo.signatureUsingEscrowKey else { + reply(nil, nil, ContainerError.bottleDoesNotContainEscrowKeySignature) + return + } + + guard let signatureUsingPeerKey = bmo.signatureUsingPeerKey else { + reply(nil, nil, ContainerError.bottleDoesNotContainerPeerKeySignature) + return + } + guard let sponsorPeerID = bmo.peerID else { + reply(nil, nil, ContainerError.bottleDoesNotContainPeerID) + return + } + + //verify bottle signature using peer + do { + guard let sponsorPeer = self.model.peer(withID: sponsorPeerID) else { + os_log("vouchWithBottle: Unable to find peer that created the bottle", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.bottleCreatingPeerNotFound) + return + } + guard let signingKey: _SFECPublicKey = sponsorPeer.permanentInfo.signingPubKey as? _SFECPublicKey else { + os_log("vouchWithBottle: Unable to create a sponsor public key", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.signatureVerificationFailed) + return + } + + _ = try BottledPeer.verifyBottleSignature(data: bottledContents, signature: signatureUsingPeerKey, pubKey: signingKey) + } catch { + os_log("vouchWithBottle: Verification of bottled signature failed: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, ContainerError.failedToCreateBottledPeer) + return + } + + //create bottled peer + let bottledPeer: BottledPeer + do { + bottledPeer = try BottledPeer(contents: bottledContents, + secret: entropy, + bottleSalt: bottleSalt, + signatureUsingEscrow: signatureUsingEscrowKey, + signatureUsingPeerKey: signatureUsingPeerKey) + } catch { + os_log("Creation of Bottled Peer failed with bottle salt: %@,\nAttempting with empty bottle salt", bottleSalt) + + do { + bottledPeer = try BottledPeer(contents: bottledContents, + secret: entropy, + bottleSalt: "", + signatureUsingEscrow: signatureUsingEscrowKey, + signatureUsingPeerKey: signatureUsingPeerKey) + } catch { + + os_log("Creation of Bottled Peer failed: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, ContainerError.failedToCreateBottledPeer) + return + } + } + + os_log("Have a bottle for peer %@", log: tplogDebug, type: .default, bottledPeer.peerID) + + // Extract any TLKs we have been given + extract(tlkShares: tlkShares, peer: bottledPeer.peerKeys) + + self.moc.performAndWait { + // I must have an ego identity in order to vouch using bottle + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("As a nonmember, can't vouch for someone else", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let permanentInfo = self.containerMO.egoPeerPermanentInfo else { + os_log("permanentInfo does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let permanentInfoSig = self.containerMO.egoPeerPermanentInfoSig else { + os_log("permanentInfoSig does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let stableInfo = self.containerMO.egoPeerStableInfo else { + os_log("stableInfo does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let stableInfoSig = self.containerMO.egoPeerStableInfoSig else { + os_log("stableInfoSig does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + let keyFactory = TPECPublicKeyFactory() + guard let beneficiaryPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: permanentInfo, sig: permanentInfoSig, keyFactory: keyFactory) else { + os_log("Invalid permenent info or signature; can't vouch for them", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.invalidPermanentInfoOrSig) + return + } + guard let beneficiaryStableInfo = TPPeerStableInfo(data: stableInfo, sig: stableInfoSig) else { + os_log("Invalid stableinfo or signature; van't vouch for them", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.invalidStableInfoOrSig) + return + } + + do { + let voucher = try self.model.createVoucher(forCandidate: beneficiaryPermanentInfo, + stableInfo: beneficiaryStableInfo, + withSponsorID: sponsorPeerID, + reason: TPVoucherReason.restore, + signing: bottledPeer.peerKeys.signingKey) + reply(voucher.data, voucher.sig, nil) + return + } catch { + os_log("Error creating voucher: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, error) + return + } + } + } + } + } + } + + func vouchWithRecoveryKey(recoveryKey: String, + salt: String, + tlkShares: [CKKSTLKShare], + reply: @escaping (Data?, Data?, Error?) -> Void) { + self.semaphore.wait() + let reply: (Data?, Data?, Error?) -> Void = { + os_log("vouchWithRecoveryKey complete: %@", + log: tplogTrace, type: .info, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.moc.performAndWait { + os_log("beginning a vouchWithRecoveryKey", log: tplogDebug, type: .default) + + // I must have an ego identity in order to vouch using bottle + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("As a nonmember, can't vouch for someone else", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let permanentInfo = self.containerMO.egoPeerPermanentInfo else { + os_log("permanentInfo does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let permanentInfoSig = self.containerMO.egoPeerPermanentInfoSig else { + os_log("permanentInfoSig does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let stableInfo = self.containerMO.egoPeerStableInfo else { + os_log("stableInfo does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + guard let stableInfoSig = self.containerMO.egoPeerStableInfoSig else { + os_log("stableInfoSig does not exist", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + let keyFactory = TPECPublicKeyFactory() + guard let beneficiaryPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: permanentInfo, sig: permanentInfoSig, keyFactory: keyFactory) else { + os_log("Invalid permenent info or signature; can't vouch for them", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.invalidPermanentInfoOrSig) + return + } + guard let beneficiaryStableInfo = TPPeerStableInfo(data: stableInfo, sig: stableInfoSig) else { + os_log("Invalid stableinfo or signature; van't vouch for them", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.invalidStableInfoOrSig) + return + } + + //create recovery key set + var recoveryKeys: RecoveryKey + do { + recoveryKeys = try RecoveryKey(recoveryKeyString: recoveryKey, recoverySalt: salt) + } catch { + os_log("failed to create recovery keys: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, ContainerError.failedToCreateRecoveryKey) + return + } + + extract(tlkShares: tlkShares, peer: recoveryKeys.peerKeys) + + let signingPublicKey: Data = recoveryKeys.peerKeys.signingKey.publicKey.keyData + let encryptionPublicKey: Data = recoveryKeys.peerKeys.encryptionKey.publicKey.keyData + + os_log("vouchWithRecoveryKey signingPubKey: %@", log: tplogDebug, type: .debug, signingPublicKey.base64EncodedString()) + os_log("vouchWithRecoveryKey encryptionPubKey: %@", log: tplogDebug, type: .debug, encryptionPublicKey.base64EncodedString()) + + guard self.model.isRecoveryKeyEnrolled() else { + os_log("Recovery Key is not enrolled", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.recoveryKeysNotEnrolled) + return + } + + //find matching peer containing recovery keys + guard let sponsorPeerID = self.model.peerIDThatTrustsRecoveryKeys(TPRecoveryKeyPair(signingSPKI: signingPublicKey, encryptionSPKI: encryptionPublicKey)) else { + os_log("Untrusted recovery key set", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.untrustedRecoveryKeys) + return + } + + do { + let voucher = try self.model.createVoucher(forCandidate: beneficiaryPermanentInfo, + stableInfo: beneficiaryStableInfo, + withSponsorID: sponsorPeerID, + reason: TPVoucherReason.recoveryKey, + signing: recoveryKeys.peerKeys.signingKey) + reply(voucher.data, voucher.sig, nil) + return + } catch { + os_log("Error creating voucher using recovery key set: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, error) + return + } + } + } + + func vouch(peerID: String, + permanentInfo: Data, + permanentInfoSig: Data, + stableInfo: Data, + stableInfoSig: Data, + ckksKeys: [CKKSKeychainBackedKeySet], + reply: @escaping (Data?, Data?, Error?) -> Void) { + self.semaphore.wait() + let reply: (Data?, Data?, Error?) -> Void = { + os_log("vouch complete: %@", log: tplogTrace, type: .info, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.moc.performAndWait { + // I must have an ego identity in order to vouch for someone else. + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig else { + os_log("As a nonmember, can't vouch for someone else", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.nonMember) + return + } + + let keyFactory = TPECPublicKeyFactory() + + guard let selfPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + reply(nil, nil, ContainerError.invalidPermanentInfoOrSig) + return + } + + guard let beneficiaryPermanentInfo = TPPeerPermanentInfo(peerID: peerID, data: permanentInfo, sig: permanentInfoSig, keyFactory: keyFactory) else { + os_log("Invalid permenent info or signature; can't vouch for them", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.invalidPermanentInfoOrSig) + return + } + + guard let beneficiaryStableInfo = TPPeerStableInfo(data: stableInfo, sig: stableInfoSig) else { + os_log("Invalid stableinfo or signature; van't vouch for them", log: tplogDebug, type: .default) + reply(nil, nil, ContainerError.invalidStableInfoOrSig) + return + } + + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, error in + guard let egoPeerKeys = egoPeerKeys else { + os_log("Don't have my own keys: can't vouch for %@: %@", log: tplogDebug, type: .default, beneficiaryPermanentInfo, (error as CVarArg?) ?? "no error") + reply(nil, nil, error) + return + } + self.moc.performAndWait { + let voucher: TPVoucher + do { + voucher = try self.model.createVoucher(forCandidate: beneficiaryPermanentInfo, + stableInfo: beneficiaryStableInfo, + withSponsorID: egoPeerID, + reason: TPVoucherReason.secureChannel, + signing: egoPeerKeys.signingKey) + + } catch { + os_log("Error creating voucher: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, nil, error) + return + } + + // And generate and upload any tlkShares + // Note that this might not be the whole list: Octagon: Limited Peers + let tlkShares: [TLKShare] + do { + // Note: we only want to send up TLKs for uploaded ckks zones + let ckksTLKs = ckksKeys.filter { !$0.newUpload }.map { $0.tlk } + + tlkShares = try makeTLKShares(ckksTLKs: ckksTLKs, + asPeer: egoPeerKeys, + toPeer: beneficiaryPermanentInfo, + epoch: Int(selfPermanentInfo.epoch)) + } catch { + os_log("Unable to make TLKShares for beneficiary %@: %@", log: tplogDebug, type: .default, beneficiaryPermanentInfo, error as CVarArg) + reply(nil, nil, error) + return + } + + guard !tlkShares.isEmpty else { + os_log("No TLKShares to upload for new peer, returning voucher", log: tplogDebug, type: .default) + reply(voucher.data, voucher.sig, nil) + return + } + + self.cuttlefish.updateTrust(changeToken: self.containerMO.changeToken ?? "", + peerID: egoPeerID, + stableInfoAndSig: nil, + dynamicInfoAndSig: nil, + tlkShares: tlkShares, + viewKeys: []) { response, error in + guard let response = response, error == nil else { + os_log("Unable to upload new tlkshares: %@", log: tplogDebug, type: .default, error as CVarArg? ?? "no error") + reply(voucher.data, voucher.sig, error ?? ContainerError.cloudkitResponseMissing) + return + } + + let newKeyRecords = response.zoneKeyHierarchyRecords.map(CKRecord.init) + os_log("Uploaded new tlkshares: %@", log: tplogDebug, type: .default, newKeyRecords) + // We don't need to save these; CKKS will refetch them as needed + + reply(voucher.data, voucher.sig, nil) + } + } + } + } + } + + func departByDistrustingSelf(reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("departByDistrustingSelf complete: %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("No dynamic info for self?", log: tplogDebug, type: .default) + reply(ContainerError.noPreparedIdentity) + return + } + + self.onqueueDistrust(peerIDs: [egoPeerID], reply: reply) + } + } + + func distrust(peerIDs: Set, + reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("distrust complete: %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("No dynamic info for self?", log: tplogDebug, type: .default) + reply(ContainerError.noPreparedIdentity) + return + } + + guard !peerIDs.contains(egoPeerID) else { + os_log("Self-distrust via peerID not allowed", log: tplogDebug, type: .default) + reply(ContainerError.invalidPeerID) + return + } + + self.onqueueDistrust(peerIDs: peerIDs, reply: reply) + } + } + + func onqueueDistrust(peerIDs: Set, + reply: @escaping (Error?) -> Void) { + + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("No dynamic info for self?", log: tplogDebug, type: .default) + reply(ContainerError.noPreparedIdentity) + return + } + + loadEgoKeyPair(identifier: signingKeyIdentifier(peerID: egoPeerID)) { signingKeyPair, error in + guard let signingKeyPair = signingKeyPair else { + os_log("No longer have signing key pair; can't sign distrust: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "nil") + reply(error) + return + } + + self.moc.performAndWait { + let dynamicInfo: TPPeerDynamicInfo + do { + dynamicInfo = try self.model.calculateDynamicInfoForPeer(withID: egoPeerID, + addingPeerIDs: nil, + removingPeerIDs: Array(peerIDs), + preapprovedKeys: nil, + signing: signingKeyPair, + currentMachineIDs: self.onqueueCurrentMIDList()) + + } catch { + os_log("Error preparing dynamic info: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "nil") + reply(error) + return + } + + let signedDynamicInfo = SignedPeerDynamicInfo(dynamicInfo) + os_log("attempting distrust for %@ with: %@", log: tplogDebug, type: .default, peerIDs, dynamicInfo) + + let request = UpdateTrustRequest.with { + $0.changeToken = self.containerMO.changeToken ?? "" + $0.peerID = egoPeerID + $0.dynamicInfoAndSig = signedDynamicInfo + } + self.cuttlefish.updateTrust(request) { response, error in + os_log("UpdateTrust(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("updateTrust failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error ?? ContainerError.cloudkitResponseMissing) + return + } + + do { + try self.persist(changes: response.changes) + os_log("distrust succeeded", log: tplogDebug, type: .default) + reply(nil) + } catch { + os_log("distrust handling failed: %@", log: tplogDebug, type: .default, (error as CVarArg)) + reply(error) + } + } + } + } + } + + func fetchEscrowContents(reply: @escaping (Data?, String?, Data?, Error?) -> Void) { + self.semaphore.wait() + let reply: (Data?, String?, Data?, Error?) -> Void = { + os_log("fetchEscrowContents complete: %@", log: tplogTrace, type: .info, traceError($3)) + self.semaphore.signal() + reply($0, $1, $2, $3) + } + os_log("beginning a fetchEscrowContents", log: tplogDebug, type: .default) + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("fetchEscrowContents failed", log: tplogDebug, type: .default) + reply (nil, nil, nil, ContainerError.noPreparedIdentity) + return + } + + guard let bottles = self.containerMO.bottles as? Set else { + os_log("fetchEscrowContents failed", log: tplogDebug, type: .default) + reply (nil, nil, nil, ContainerError.noBottleForPeer) + return + } + + var bmoSet = bottles.filter { $0.peerID == egoPeerID } + let bmo = bmoSet.removeFirst() + let bottleID = bmo.bottleID + var entropy: Data + + do { + guard let loaded = try loadSecret(label: egoPeerID) else { + os_log("fetchEscrowContents failed to load entropy", log: tplogDebug, type: .default) + reply (nil, nil, nil, ContainerError.failedToFetchEscrowContents) + return + } + entropy = loaded + } catch { + os_log("fetchEscrowContents failed to load entropy: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply (nil, nil, nil, error) + return + } + + guard let signingPublicKey = bmo.escrowedSigningSPKI else { + os_log("fetchEscrowContents no escrow signing spki", log: tplogDebug, type: .default) + reply (nil, nil, nil, ContainerError.bottleDoesNotContainerEscrowKeySPKI) + return + } + reply(entropy, bottleID, signingPublicKey, nil) + } + } + + func fetchViableBottles(reply: @escaping ([String]?, [String]?, Error?) -> Void) { + self.semaphore.wait() + let reply: ([String]?, [String]?, Error?) -> Void = { + os_log("fetchViableBottles complete: %@", log: tplogTrace, type: .info, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.fetchViableBottlesWithSemaphore(reply: reply) + } + + func onqueueCachedBottlesContainEgoPeerBottle(cachedBottles: TPCachedViableBottles) -> Bool { + guard let egoPeerID = self.containerMO.egoPeerID else { + os_log("bottleForEgoPeer: No identity.", log: tplogDebug, type: .default) + return false + } + guard let bottles: Set = self.containerMO.bottles as? Set else { + os_log("bottleForEgoPeer: No Bottles.", log: tplogDebug, type: .default) + return false + } + var matchesCached: Bool = false + for bottle in bottles { + guard let bottleID: String = bottle.bottleID else { + continue + } + if bottle.peerID == egoPeerID && (cachedBottles.viableBottles.contains(bottleID) || cachedBottles.partialBottles.contains(bottleID)) { + matchesCached = true + break + } + } + return matchesCached + } + + func fetchViableBottlesWithSemaphore(reply: @escaping ([String]?, [String]?, Error?) -> Void) { + os_log("beginning a fetchViableBottles", log: tplogDebug, type: .default) + + let cachedBottles:TPCachedViableBottles = self.model.currentCachedViableBottlesSet() + self.moc.performAndWait { + if self.onqueueCachedBottlesContainEgoPeerBottle(cachedBottles: cachedBottles) + && (cachedBottles.viableBottles.count > 0 || cachedBottles.partialBottles.count > 0) { + os_log("returning from fetchViableBottles, using cached bottles", log: tplogDebug, type: .default) + reply (cachedBottles.viableBottles, cachedBottles.partialBottles, nil) + return + } + + self.cuttlefish.fetchViableBottles { response, error in + guard error == nil else { + os_log("fetchViableBottles failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, nil, error) + return + } + + self.moc.performAndWait { + + guard let escrowPairs = response?.viableBottles else { + os_log("fetchViableBottles returned no viable bottles: %@", log: tplogDebug, type: .default) + reply([], [], nil) + return + } + + var partialPairs: [EscrowPair] = [] + if let partial = response?.partialBottles { + partialPairs = partial + } else { + os_log("fetchViableBottles returned no partially viable bottles, but that's ok: %@", log: tplogDebug, type: .default) + } + + let viableBottleIDs = escrowPairs.compactMap { $0.bottle.bottleID } + os_log("fetchViableBottles returned viable bottles: %@", log: tplogDebug, type: .default, viableBottleIDs) + + let partialBottleIDs = partialPairs.compactMap { $0.bottle.bottleID } + os_log("fetchViableBottles returned partial bottles: %@", log: tplogDebug, type: .default, partialBottleIDs) + + escrowPairs.forEach { pair in + let bottle = pair.bottle + + // Save this bottle only if we don't already have it + if let existingBottles = self.containerMO.bottles as? Set { + let matchingBottles: Set = existingBottles.filter { existing in + existing.peerID == bottle.peerID && + existing.bottleID == bottle.bottleID && + existing.escrowedSigningSPKI == bottle.escrowedSigningSpki && + existing.signatureUsingEscrowKey == bottle.signatureUsingEscrowKey && + existing.signatureUsingPeerKey == bottle.signatureUsingPeerKey && + existing.contents == bottle.contents + } + if !matchingBottles.isEmpty { + os_log("fetchViableBottles already knows about bottle", log: tplogDebug, type: .default, bottle.bottleID) + return + } + } + + let bmo = BottleMO(context: self.moc) + bmo.peerID = bottle.peerID + bmo.bottleID = bottle.bottleID + bmo.escrowedSigningSPKI = bottle.escrowedSigningSpki + bmo.signatureUsingEscrowKey = bottle.signatureUsingEscrowKey + bmo.signatureUsingPeerKey = bottle.signatureUsingPeerKey + bmo.contents = bottle.contents + + os_log("fetchViableBottles saving new bottle: %@", log: tplogDebug, type: .default, bmo) + self.containerMO.addToBottles(bmo) + } + + partialPairs.forEach { pair in + let bottle = pair.bottle + + // Save this bottle only if we don't already have it + if let existingBottles = self.containerMO.bottles as? Set { + let matchingBottles: Set = existingBottles.filter { existing in + existing.peerID == bottle.peerID && + existing.bottleID == bottle.bottleID && + existing.escrowedSigningSPKI == bottle.escrowedSigningSpki && + existing.signatureUsingEscrowKey == bottle.signatureUsingEscrowKey && + existing.signatureUsingPeerKey == bottle.signatureUsingPeerKey && + existing.contents == bottle.contents + } + if !matchingBottles.isEmpty { + os_log("fetchViableBottles already knows about bottle", log: tplogDebug, type: .default, bottle.bottleID) + return + } + } + + let bmo = BottleMO(context: self.moc) + bmo.peerID = bottle.peerID + bmo.bottleID = bottle.bottleID + bmo.escrowedSigningSPKI = bottle.escrowedSigningSpki + bmo.signatureUsingEscrowKey = bottle.signatureUsingEscrowKey + bmo.signatureUsingPeerKey = bottle.signatureUsingPeerKey + bmo.contents = bottle.contents + + os_log("fetchViableBottles saving new bottle: %@", log: tplogDebug, type: .default, bmo) + self.containerMO.addToBottles(bmo) + } + + do { + try self.moc.save() + os_log("fetchViableBottles saved bottles", log: tplogDebug, type: .default) + let cached = TPCachedViableBottles.init(viableBottles: viableBottleIDs, partialBottles: partialBottleIDs) + self.model.setViableBottles(cached) + reply(viableBottleIDs, partialBottleIDs, nil) + } catch { + os_log("fetchViableBottles unable to save bottles: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, nil, error) + } + + } + } + } + } + + func fetchPolicy(reply: @escaping (TPPolicy?, Error?) -> Void) { + self.semaphore.wait() + let reply: (TPPolicy?, Error?) -> Void = { + os_log("fetchPolicy complete: %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + self.moc.performAndWait { + var keys: [NSNumber: String] = [:] + + guard let stableInfoData = self.containerMO.egoPeerStableInfo, + let stableInfoSig = self.containerMO.egoPeerStableInfoSig else { + os_log("fetchPolicy failed to find ego peer stableinfodata/sig", log: tplogDebug, type: .error) + reply(nil, ContainerError.noPreparedIdentity) + return + } + guard let stableInfo = TPPeerStableInfo(data: stableInfoData, sig: stableInfoSig) else { + os_log("fetchPolicy failed to create TPPeerStableInfo", log: tplogDebug, type: .error) + reply(nil, ContainerError.invalidStableInfoOrSig) + return + } + + let policyVersionCounter = stableInfo.policyVersion + let policyVersion = NSNumber(value: policyVersionCounter) + keys[policyVersion] = stableInfo.policyHash + + if let policyDocument = self.model.policy(withVersion: policyVersionCounter) { + os_log("fetchPolicy: have a local version of policy %@: %@", log: tplogDebug, type: .default, policyVersion, policyDocument) + do { + let policy = try policyDocument.policy(withSecrets: stableInfo.policySecrets, decrypter: Decrypter()) + reply(policy, nil) + return + } catch { + os_log("TPPolicyDocument failed: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, error) + return + } + } + + self.fetchPolicyDocuments(keys: keys) { result, error in + guard error == nil else { + reply(nil, error) + return + } + guard let result = result else { + os_log("fetchPolicy: nil policies returned") + reply(nil, ContainerError.policyDocumentDoesNotValidate) + return + } + guard result.count == 1 else { + os_log("fetchPolicy: wrong length returned") + reply(nil, ContainerError.policyDocumentDoesNotValidate) + return + } + guard let r = result[policyVersion] else { + os_log("fetchPolicy: version not found") + reply(nil, ContainerError.unknownPolicyVersion(policyVersion.uint64Value)) + return + } + guard let data = r[1].data(using: .utf8) else { + os_log("fetchPolicy: failed to convert data") + reply(nil, ContainerError.unknownPolicyVersion(policyVersion.uint64Value)) + return + } + guard let pd = TPPolicyDocument.policyDoc(withHash: r[0], data: data) else { + os_log("fetchPolicy: pd is nil") + reply(nil, ContainerError.policyDocumentDoesNotValidate) + return + } + do { + let policy = try pd.policy(withSecrets: stableInfo.policySecrets, decrypter: Decrypter()) + reply(policy, nil) + } catch { + os_log("TPPolicyDocument: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, error) + } + } + } + } + + // All-or-nothing: return an error in case full list cannot be returned. + // Completion handler data format: [version : [hash, data]] + func fetchPolicyDocuments(keys: [NSNumber: String], + reply: @escaping ([NSNumber: [String]]?, Error?) -> Void) { + self.semaphore.wait() + let reply: ([NSNumber: [String]]?, Error?) -> Void = { + os_log("fetchPolicyDocuments complete: %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + var keys = keys + var docs: [NSNumber: [String]] = [:] + + self.moc.performAndWait { + for (version, hash) in keys { + if let policydoc = try? self.getPolicyDoc(version.uint64Value), policydoc.policyHash == hash { + docs[version] = [policydoc.policyHash, policydoc.protobuf.base64EncodedString()] + keys[version] = nil + } + } + } + + if keys.isEmpty { + reply(docs, nil) + return + } + + let request = FetchPolicyDocumentsRequest.with { + $0.keys = keys.map { key, value in + PolicyDocumentKey.with { $0.version = key.uint64Value; $0.hash = value }} + } + + self.cuttlefish.fetchPolicyDocuments(request) { response, error in + os_log("FetchPolicyDocuments(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("FetchPolicyDocuments failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, error ?? ContainerError.cloudkitResponseMissing) + return + } + + self.moc.performAndWait { + for mapEntry in response.entries { + // TODO: validate the policy's signature + + guard let doc = TPPolicyDocument.policyDoc(withHash: mapEntry.key.hash, data: mapEntry.value) else { + os_log("Can't make policy document with hash %@ and data %@", + log: tplogDebug, type: .default, mapEntry.key.hash, mapEntry.value.base64EncodedString()) + reply(nil, ContainerError.policyDocumentDoesNotValidate) + return + } + + guard let hash = keys[NSNumber(value: doc.policyVersion)], hash == doc.policyHash else { + os_log("Requested hash %@ does not match fetched hash %@", log: tplogDebug, type: .default, + keys[NSNumber(value: doc.policyVersion)] ?? "", doc.policyHash) + reply(nil, ContainerError.policyDocumentDoesNotValidate) + return + } + keys[NSNumber(value: doc.policyVersion)] = nil // Server responses should be unique, let's enforce + docs[NSNumber(value: doc.policyVersion)] = [doc.policyHash, doc.protobuf.base64EncodedString()] + self.model.register(doc) + } + + do { + try self.moc.save() // if this fails callers might make bad data assumptions + } catch { + reply(nil, error) + return + } + + if !keys.isEmpty { + let (unknownVersion, _) = keys.first! + reply(nil, ContainerError.unknownPolicyVersion(unknownVersion.uint64Value)) + return + } + + reply(docs, nil) + } + } + } + + // Must be on moc queue to call this. + // Caller is responsible for saving the moc afterwards. + @discardableResult + private func registerPeerMO(permanentInfo: TPPeerPermanentInfo, + stableInfo: TPPeerStableInfo? = nil, + dynamicInfo: TPPeerDynamicInfo? = nil, + vouchers: [TPVoucher]? = nil, + isEgoPeer: Bool = false) throws -> PeerMO { + let peerID = permanentInfo.peerID + + let peer = PeerMO(context: self.moc) + peer.peerID = peerID + peer.permanentInfo = permanentInfo.data + peer.permanentInfoSig = permanentInfo.sig + peer.stableInfo = stableInfo?.data + peer.stableInfoSig = stableInfo?.sig + peer.dynamicInfo = dynamicInfo?.data + peer.dynamicInfoSig = dynamicInfo?.sig + peer.isEgoPeer = isEgoPeer + self.containerMO.addToPeers(peer) + + self.model.registerPeer(with: permanentInfo) + if let stableInfo = stableInfo { + try self.model.update(stableInfo, forPeerWithID: peerID) + } + if let dynamicInfo = dynamicInfo { + try self.model.update(dynamicInfo, forPeerWithID: peerID) + } + vouchers?.forEach { voucher in + self.model.register(voucher) + let voucherMO = VoucherMO(context: self.moc) + voucherMO.voucherInfo = voucher.data + voucherMO.voucherInfoSig = voucher.sig + peer.addToVouchers(voucherMO) + } + return peer + } + + /* Returns any new CKKS keys that need uploading, as well as any TLKShares necessary for those keys */ + func makeSharesForNewKeySets(ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + egoPeerKeys: OctagonSelfPeerKeys, + egoPeerDynamicInfo: TPPeerDynamicInfo, + epoch: Int) throws -> ([ViewKeys], [TLKShare]) { + let newCKKSKeys = ckksKeys.filter { $0.newUpload } + let newViewKeys: [ViewKeys] = newCKKSKeys.map(ViewKeys.convert) + + let octagonSelfShares = try makeTLKShares(ckksTLKs: ckksKeys.map { $0.tlk }, + asPeer: egoPeerKeys, + toPeer: egoPeerKeys, + epoch: epoch) + let extraShares = tlkShares.map { TLKShare.convert(ckksTLKShare: $0) } + + var peerShares: [TLKShare] = [] + + for keyset in newCKKSKeys { + do { + let peerIDsWithAccess = try self.model.getPeerIDsTrustedByPeer(with: egoPeerDynamicInfo, + toAccessView: keyset.tlk.zoneID.zoneName) + os_log("Planning to share %@ with peers %@", log: tplogDebug, type: .default, String(describing: keyset.tlk), peerIDsWithAccess) + + let peers = peerIDsWithAccess.compactMap { self.model.peer(withID: $0) } + let viewPeerShares = try peers.map { receivingPeer in + TLKShare.convert(ckksTLKShare: try CKKSTLKShare(keyset.tlk, + as: egoPeerKeys, + to: receivingPeer.permanentInfo, + epoch: epoch, + poisoned: 0)) + } + + peerShares = peerShares + viewPeerShares + + } catch { + os_log("Unable to create TLKShares for keyset %@: %@", log: tplogDebug, type: .default, String(describing: keyset), error as CVarArg) + } + } + + return (newViewKeys, octagonSelfShares + peerShares + extraShares) + } + + func onqueuePreparePeerForJoining(egoPeerID: String, + peerPermanentInfo: TPPeerPermanentInfo, + stableInfo: TPPeerStableInfo, + sponsorID: String?, + preapprovedKeys: [Data]?, + vouchers: [SignedVoucher], + egoPeerKeys: OctagonSelfPeerKeys) throws -> (Peer, TPPeerDynamicInfo) { + let dynamicInfo = try self.model.dynamicInfo(forJoiningPeerID: egoPeerID, + peerPermanentInfo: peerPermanentInfo, + peerStableInfo: stableInfo, + sponsorID: sponsorID, + preapprovedKeys: preapprovedKeys, + signing: egoPeerKeys.signingKey, + currentMachineIDs: self.onqueueCurrentMIDList()) + + let newStableInfo = try self.createNewStableInfoIfNeeded(stableChanges: nil, + egoPeerID: egoPeerID, + dynamicInfo: dynamicInfo, + signingKeyPair: egoPeerKeys.signingKey) + + let peer = Peer.with { + $0.peerID = egoPeerID + $0.permanentInfoAndSig = SignedPeerPermanentInfo(peerPermanentInfo) + $0.stableInfoAndSig = SignedPeerStableInfo(newStableInfo ?? stableInfo) + $0.dynamicInfoAndSig = SignedPeerDynamicInfo(dynamicInfo) + $0.vouchers = vouchers + } + + return (peer, dynamicInfo) + } + + func join(voucherData: Data, + voucherSig: Data, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]?, + reply: @escaping (String?, [CKRecord], Error?) -> Void) { + self.semaphore.wait() + let reply: (String?, [CKRecord], Error?) -> Void = { + os_log("join complete: %@", log: tplogTrace, type: .info, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.fetchAndPersistChanges { error in + guard error == nil else { + reply(nil, [], error) + return + } + self.moc.performAndWait { + guard let voucher = TPVoucher(infoWith: voucherData, sig: voucherSig) else { + reply(nil, [], ContainerError.invalidVoucherOrSig) + return + } + guard let sponsor = self.model.peer(withID: voucher.sponsorID) else { + reply(nil, [], ContainerError.sponsorNotRegistered(voucher.sponsorID)) + return + } + + // Fetch ego peer identity from local storage. + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig, + let egoStableData = self.containerMO.egoPeerStableInfo, + let egoStableSig = self.containerMO.egoPeerStableInfoSig + else { + reply(nil, [], ContainerError.noPreparedIdentity) + return + } + + let keyFactory = TPECPublicKeyFactory() + guard let selfPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + reply(nil, [], ContainerError.invalidPermanentInfoOrSig) + return + } + guard let selfStableInfo = TPPeerStableInfo(data: egoStableData, sig: egoStableSig) else { + reply(nil, [], ContainerError.invalidStableInfoOrSig) + return + } + guard self.onqueueMachineIDAllowedByIDMS(machineID: selfPermanentInfo.machineID) else { + os_log("join: self machineID %@ not on list", log: tplogDebug, type: .debug, selfPermanentInfo.machineID) + self.onqueueTTRUntrusted() + reply(nil, [], ContainerError.preparedIdentityNotOnAllowedList(selfPermanentInfo.machineID)) + return + } + + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, error in + guard let egoPeerKeys = egoPeerKeys else { + os_log("Don't have my own peer keys; can't join: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + reply(nil, [], error) + return + } + self.moc.performAndWait { + let peer: Peer + let newDynamicInfo: TPPeerDynamicInfo + do { + (peer, newDynamicInfo) = try self.onqueuePreparePeerForJoining(egoPeerID: egoPeerID, + peerPermanentInfo: selfPermanentInfo, + stableInfo: selfStableInfo, + sponsorID: sponsor.peerID, + preapprovedKeys: preapprovedKeys, + vouchers: [SignedVoucher.with { + $0.voucher = voucher.data + $0.sig = voucher.sig + }, ], + egoPeerKeys: egoPeerKeys) + } catch { + os_log("Unable to create peer for joining: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, [], error) + return + } + + let allTLKShares: [TLKShare] + let viewKeys: [ViewKeys] + do { + (viewKeys, allTLKShares) = try self.makeSharesForNewKeySets(ckksKeys: ckksKeys, + tlkShares: tlkShares, + egoPeerKeys: egoPeerKeys, + egoPeerDynamicInfo: newDynamicInfo, + epoch: Int(selfPermanentInfo.epoch)) + } catch { + os_log("Unable to process keys before joining: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, [], error) + return + } + + do { + try self.model.checkIntroduction(forCandidate: selfPermanentInfo, + stableInfo: peer.stableInfoAndSig.toStableInfo(), + withSponsorID: sponsor.peerID) + } catch { + os_log("Error checking introduction: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, [], error) + return + } + + var bottle: Bottle + do { + bottle = try self.assembleBottle(egoPeerID: egoPeerID) + } catch { + reply(nil, [], error) + return + } + + os_log("Beginning join for peer %@", log: tplogDebug, type: .default, egoPeerID) + os_log("Join permanentInfo: %@", log: tplogDebug, type: .debug, egoPermData.base64EncodedString()) + os_log("Join permanentInfoSig: %@", log: tplogDebug, type: .debug, egoPermSig.base64EncodedString()) + os_log("Join stableInfo: %@", log: tplogDebug, type: .debug, peer.stableInfoAndSig.peerStableInfo.base64EncodedString()) + os_log("Join stableInfoSig: %@", log: tplogDebug, type: .debug, peer.stableInfoAndSig.sig.base64EncodedString()) + os_log("Join dynamicInfo: %@", log: tplogDebug, type: .debug, peer.dynamicInfoAndSig.peerDynamicInfo.base64EncodedString()) + os_log("Join dynamicInfoSig: %@", log: tplogDebug, type: .debug, peer.dynamicInfoAndSig.sig.base64EncodedString()) + + os_log("Join vouchers: %@", log: tplogDebug, type: .debug, peer.vouchers.map { $0.voucher.base64EncodedString() }) + os_log("Join voucher signatures: %@", log: tplogDebug, type: .debug, peer.vouchers.map { $0.sig.base64EncodedString() }) + + os_log("Uploading %d tlk shares", log: tplogDebug, type: .default, allTLKShares.count) + + do { + os_log("Join peer: %@", log: tplogDebug, type: .debug, try peer.serializedData().base64EncodedString()) + } catch { + os_log("Join unable to encode peer: %@", log: tplogDebug, type: .debug, error as CVarArg) + } + + let changeToken = self.containerMO.changeToken ?? "" + let request = JoinWithVoucherRequest.with { + $0.changeToken = changeToken + $0.peer = peer + $0.bottle = bottle + $0.tlkShares = allTLKShares + $0.viewKeys = viewKeys + } + self.cuttlefish.joinWithVoucher(request) { response, error in + os_log("JoinWithVoucher(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("joinWithVoucher failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, [], error ?? ContainerError.cloudkitResponseMissing) + return + } + + self.moc.performAndWait { + do { + self.containerMO.egoPeerStableInfo = peer.stableInfoAndSig.peerStableInfo + self.containerMO.egoPeerStableInfoSig = peer.stableInfoAndSig.sig + try self.onQueuePersist(changes: response.changes) + os_log("JoinWithVoucher succeeded", log: tplogDebug) + + let keyHierarchyRecords = response.zoneKeyHierarchyRecords.compactMap { CKRecord($0) } + reply(egoPeerID, keyHierarchyRecords, nil) + } catch { + os_log("JoinWithVoucher failed: %@", log: tplogDebug, String(describing: error)) + reply(nil, [], error) + } + } + } + } + } + } + } + } + + func requestHealthCheck(requiresEscrowCheck: Bool, reply: @escaping (Bool, Bool, Bool, Error?) -> Void) { + self.semaphore.wait() + let reply: (Bool, Bool, Bool, Error?) -> Void = { + os_log("health check complete: %@", log: tplogTrace, type: .info, traceError($3)) + self.semaphore.signal() + reply($0, $1, $2, $3) + } + + os_log("requestHealthCheck requiring escrow check: %d", log: tplogDebug, type: .default, requiresEscrowCheck) + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + // No identity, nothing to do + os_log("requestHealthCheck: No identity.", log: tplogDebug, type: .default) + reply(false, false, false, ContainerError.noPreparedIdentity) + return + } + let request = GetRepairActionRequest.with { + $0.peerID = egoPeerID + $0.requiresEscrowCheck = requiresEscrowCheck + } + + self.cuttlefish.getRepairAction(request) { response, error in + guard error == nil else { + reply(false, false, false, error) + return + } + guard let action = response?.repairAction else { + os_log("repair response is empty, returning false: %@", log: tplogDebug, type: .default) + reply(false, false, false, nil) + return + } + var postRepairAccount: Bool = false + var postRepairEscrow: Bool = false + var resetOctagon: Bool = false + + switch action { + case .noAction: + break + case .postRepairAccount: + postRepairAccount = true + break + case .postRepairEscrow: + postRepairEscrow = true + break + case .resetOctagon: + resetOctagon = true + break + case .UNRECOGNIZED: + break + } + reply(postRepairAccount, postRepairEscrow, resetOctagon, nil) + } + } + } + + func preflightPreapprovedJoin(reply: @escaping (Bool, Error?) -> Void) { + self.semaphore.wait() + let reply: (Bool, Error?) -> Void = { + os_log("preflightPreapprovedJoin complete: %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + self.fetchAndPersistChanges { error in + guard error == nil else { + os_log("preflightPreapprovedJoin unable to fetch changes: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "") + reply(false, error) + return + } + + // We explicitly ignore the machine ID list here; we're only interested in the peer states: do they preapprove us? + + guard !self.model.allPeerIDs().isEmpty else { + // If, after fetch and handle changes, there's no peers, then we can likely establish. + reply(true, nil) + return + } + + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig + else { + os_log("preflightPreapprovedJoin: no prepared identity", log: tplogDebug, type: .debug) + reply(false, ContainerError.noPreparedIdentity) + return + } + + let keyFactory = TPECPublicKeyFactory() + guard let egoPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + os_log("preflightPreapprovedJoin: invalid permanent info", log: tplogDebug, type: .debug) + reply(false, ContainerError.invalidPermanentInfoOrSig) + return + } + + guard self.model.hasPeerPreapprovingKey(egoPermanentInfo.signingPubKey.spki()) else { + os_log("preflightPreapprovedJoin: no peers preapprove our key", log: tplogDebug, type: .debug) + reply(false, ContainerError.noPeersPreapprovePreparedIdentity) + return + } + + reply(true, nil) + } + } + + func preapprovedJoin(ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]?, + reply: @escaping (String?, [CKRecord], Error?) -> Void) { + self.semaphore.wait() + let reply: (String?, [CKRecord], Error?) -> Void = { + os_log("preapprovedJoin complete: %@", log: tplogTrace, type: .info, traceError($2)) + self.semaphore.signal() + reply($0, $1, $2) + } + + self.fetchAndPersistChangesIfNeeded { error in + guard error == nil else { + os_log("preapprovedJoin unable to fetch changes: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "") + reply(nil, [], error) + return + } + self.moc.performAndWait { + // If, after fetch and handle changes, there's no peers, then fire off an establish + // Note that if the establish fails, retrying this call might work. + // That's up to the caller. + if self.model.allPeerIDs().isEmpty { + os_log("preapprovedJoin but no existing peers, attempting establish", log: tplogDebug, type: .debug) + self.onqueueEstablish(ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys, + reply: reply) + return + } + + // Fetch ego peer identity from local storage. + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig, + let egoStableData = self.containerMO.egoPeerStableInfo, + let egoStableSig = self.containerMO.egoPeerStableInfoSig + else { + os_log("preapprovedJoin: no prepared identity", log: tplogDebug, type: .debug) + reply(nil, [], ContainerError.noPreparedIdentity) + return + } + + let keyFactory = TPECPublicKeyFactory() + guard let selfPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: keyFactory) else { + reply(nil, [], ContainerError.invalidPermanentInfoOrSig) + return + } + guard let selfStableInfo = TPPeerStableInfo(data: egoStableData, sig: egoStableSig) else { + reply(nil, [], ContainerError.invalidStableInfoOrSig) + return + } + + guard self.onqueueMachineIDAllowedByIDMS(machineID: selfPermanentInfo.machineID) else { + os_log("preapprovedJoin: self machineID %@ (me) not on list", log: tplogDebug, type: .debug, selfPermanentInfo.machineID) + self.onqueueTTRUntrusted() + reply(nil, [], ContainerError.preparedIdentityNotOnAllowedList(selfPermanentInfo.machineID)) + return + } + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, error in + guard let egoPeerKeys = egoPeerKeys else { + os_log("preapprovedJoin: Don't have my own keys: can't join", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, [], error) + return + } + + guard self.model.hasPeerPreapprovingKey(egoPeerKeys.signingKey.publicKey().spki()) else { + os_log("preapprovedJoin: no peers preapprove our key", log: tplogDebug, type: .debug) + reply(nil, [], ContainerError.noPeersPreapprovePreparedIdentity) + return + } + + self.moc.performAndWait { + + let peer: Peer + let newDynamicInfo: TPPeerDynamicInfo + do { + (peer, newDynamicInfo) = try self.onqueuePreparePeerForJoining(egoPeerID: egoPeerID, + peerPermanentInfo: selfPermanentInfo, + stableInfo: selfStableInfo, + sponsorID: nil, + preapprovedKeys: preapprovedKeys, + vouchers: [], + egoPeerKeys: egoPeerKeys) + } catch { + os_log("Unable to create peer for joining: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, [], error) + return + } + + let allTLKShares: [TLKShare] + let viewKeys: [ViewKeys] + do { + (viewKeys, allTLKShares) = try self.makeSharesForNewKeySets(ckksKeys: ckksKeys, + tlkShares: tlkShares, + egoPeerKeys: egoPeerKeys, + egoPeerDynamicInfo: newDynamicInfo, + epoch: Int(selfPermanentInfo.epoch)) + } catch { + os_log("Unable to process keys before joining: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, [], error) + return + } + + var bottle: Bottle + do { + bottle = try self.assembleBottle(egoPeerID: egoPeerID) + } catch { + reply(nil, [], error) + return + } + + os_log("Beginning preapprovedJoin for peer %@", log: tplogDebug, type: .default, egoPeerID) + os_log("preapprovedJoin permanentInfo: %@", log: tplogDebug, type: .debug, egoPermData.base64EncodedString()) + os_log("preapprovedJoin permanentInfoSig: %@", log: tplogDebug, type: .debug, egoPermSig.base64EncodedString()) + os_log("preapprovedJoin stableInfo: %@", log: tplogDebug, type: .debug, egoStableData.base64EncodedString()) + os_log("preapprovedJoin stableInfoSig: %@", log: tplogDebug, type: .debug, egoStableSig.base64EncodedString()) + os_log("preapprovedJoin dynamicInfo: %@", log: tplogDebug, type: .debug, peer.dynamicInfoAndSig.peerDynamicInfo.base64EncodedString()) + os_log("preapprovedJoin dynamicInfoSig: %@", log: tplogDebug, type: .debug, peer.dynamicInfoAndSig.sig.base64EncodedString()) + + os_log("preapprovedJoin vouchers: %@", log: tplogDebug, type: .debug, peer.vouchers.map { $0.voucher.base64EncodedString() }) + os_log("preapprovedJoin voucher signatures: %@", log: tplogDebug, type: .debug, peer.vouchers.map { $0.sig.base64EncodedString() }) + + os_log("preapprovedJoin: uploading %d tlk shares", log: tplogDebug, type: .default, allTLKShares.count) + + do { + os_log("preapprovedJoin peer: %@", log: tplogDebug, type: .debug, try peer.serializedData().base64EncodedString()) + } catch { + os_log("preapprovedJoin unable to encode peer: %@", log: tplogDebug, type: .debug, error as CVarArg) + } + + let changeToken = self.containerMO.changeToken ?? "" + let request = JoinWithVoucherRequest.with { + $0.changeToken = changeToken + $0.peer = peer + $0.bottle = bottle + $0.tlkShares = allTLKShares + $0.viewKeys = viewKeys + } + self.cuttlefish.joinWithVoucher(request) { response, error in + os_log("preapprovedJoin(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("preapprovedJoin failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, [], error ?? ContainerError.cloudkitResponseMissing) + return + } + + self.moc.performAndWait { + do { + self.containerMO.egoPeerStableInfo = peer.stableInfoAndSig.peerStableInfo + self.containerMO.egoPeerStableInfoSig = peer.stableInfoAndSig.sig + try self.onQueuePersist(changes: response.changes) + os_log("preapprovedJoin succeeded", log: tplogDebug) + + let keyHierarchyRecords = response.zoneKeyHierarchyRecords.compactMap { CKRecord($0) } + reply(egoPeerID, keyHierarchyRecords, nil) + } catch { + os_log("preapprovedJoin failed: %@", log: tplogDebug, String(describing: error)) + reply(nil, [], error) + } + } + } + } + } + } + } + } + + func update(deviceName: String?, + serialNumber: String?, + osVersion: String?, + policyVersion: UInt64?, + policySecrets: [String: Data]?, + reply: @escaping (TrustedPeersHelperPeerState?, Error?) -> Void) { + self.semaphore.wait() + let reply: (TrustedPeersHelperPeerState?, Error?) -> Void = { + os_log("update complete: %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + // Get (and save) the latest from cuttlefish + let stableChanges = StableChanges(deviceName: deviceName, + serialNumber: serialNumber, + osVersion: osVersion, + policyVersion: policyVersion, + policySecrets: policySecrets, + recoverySigningPubKey: nil, + recoveryEncryptionPubKey: nil) + self.fetchChangesAndUpdateTrustIfNeeded(stableChanges: stableChanges, reply: reply) + } + + func set(preapprovedKeys: [Data], + reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("setPreapprovedKeys complete: %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + os_log("setPreapprovedKeys: %@", log: tplogDebug, type: .default, preapprovedKeys) + + guard let egoPeerID = self.containerMO.egoPeerID else { + // No identity, nothing to do + os_log("setPreapprovedKeys: No identity.", log: tplogDebug, type: .default) + reply(ContainerError.noPreparedIdentity) + return + } + loadEgoKeyPair(identifier: signingKeyIdentifier(peerID: egoPeerID)) { signingKeyPair, error in + guard let signingKeyPair = signingKeyPair else { + os_log("setPreapprovedKeys: no signing key pair: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error ?? ContainerError.unableToCreateKeyPair) + return + } + + self.moc.performAndWait { + let dynamicInfo: TPPeerDynamicInfo + do { + dynamicInfo = try self.model.calculateDynamicInfoForPeer(withID: egoPeerID, + addingPeerIDs: nil, + removingPeerIDs: nil, + preapprovedKeys: preapprovedKeys, + signing: signingKeyPair, + currentMachineIDs: self.onqueueCurrentMIDList()) + } catch { + os_log("setPreapprovedKeys: couldn't calculate dynamic info: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(error) + return + } + + os_log("setPreapprovedKeys: produced a dynamicInfo: %@", log: tplogDebug, type: .default, dynamicInfo) + + if dynamicInfo == self.model.peer(withID: egoPeerID)?.dynamicInfo { + os_log("setPreapprovedKeys: no change; nothing to do.", log: tplogDebug, type: .default) + reply(nil) + return + } + + os_log("setPreapprovedKeys: attempting updateTrust for %@ with: %@", log: tplogDebug, type: .default, egoPeerID, dynamicInfo) + let request = UpdateTrustRequest.with { + $0.changeToken = self.containerMO.changeToken ?? "" + $0.peerID = egoPeerID + $0.dynamicInfoAndSig = SignedPeerDynamicInfo(dynamicInfo) + } + + self.cuttlefish.updateTrust(request) { response, error in + os_log("setPreapprovedKeys(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("setPreapprovedKeys failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error ?? ContainerError.cloudkitResponseMissing) + return + } + os_log("setPreapprovedKeys: updateTrust suceeded", log: tplogDebug, type: .default) + + do { + try self.persist(changes: response.changes) + } catch { + os_log("setPreapprovedKeys: could not persist changes: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(error) + return + } + + reply(nil) + } + } + } + } + } + + func updateTLKs(ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + reply: @escaping ([CKRecord]?, Error?) -> Void) { + self.semaphore.wait() + let reply: ([CKRecord]?, Error?) -> Void = { + os_log("updateTLKs complete: %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + os_log("Uploading some new TLKs: %@", log: tplogDebug, type: .default, ckksKeys) + + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID, + let egoPermData = self.containerMO.egoPeerPermanentInfo, + let egoPermSig = self.containerMO.egoPeerPermanentInfoSig + else { + os_log("Have no self identity, can't make tlk shares", log: tplogDebug, type: .default) + reply(nil, ContainerError.noPreparedIdentity) + return + } + + guard let selfPermanentInfo = TPPeerPermanentInfo(peerID: egoPeerID, data: egoPermData, sig: egoPermSig, keyFactory: TPECPublicKeyFactory()) else { + os_log("Couldn't parse self identity", log: tplogDebug, type: .default, ckksKeys) + reply(nil, ContainerError.invalidPermanentInfoOrSig) + return + } + + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, error in + guard let egoPeerKeys = egoPeerKeys else { + os_log("Don't have my own peer keys; can't upload new TLKs: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "error missing") + reply(nil, error) + return + } + self.moc.performAndWait { + guard let egoPeerDynamicInfo = self.model.getDynamicInfoForPeer(withID: egoPeerID) else { + os_log("Unable to fetch dynamic info for self", log: tplogDebug, type: .default) + reply(nil, ContainerError.missingDynamicInfo) + return + } + + let allTLKShares: [TLKShare] + let viewKeys: [ViewKeys] + do { + (viewKeys, allTLKShares) = try self.makeSharesForNewKeySets(ckksKeys: ckksKeys, + tlkShares: tlkShares, + egoPeerKeys: egoPeerKeys, + egoPeerDynamicInfo: egoPeerDynamicInfo, + epoch: Int(selfPermanentInfo.epoch)) + } catch { + os_log("Unable to process keys before uploading: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, error) + return + } + + let request = UpdateTrustRequest.with { + $0.changeToken = self.containerMO.changeToken ?? "" + $0.peerID = egoPeerID + $0.tlkShares = allTLKShares + $0.viewKeys = viewKeys + } + + self.cuttlefish.updateTrust(request) { response, error in + os_log("UpdateTrust(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + + guard error == nil else { + reply(nil, error) + return + } + + let keyHierarchyRecords = response?.zoneKeyHierarchyRecords.compactMap { CKRecord($0) } ?? [] + os_log("Recevied %d CKRecords back", log: tplogDebug, type: .default, keyHierarchyRecords.count) + reply(keyHierarchyRecords, nil) + } + } + } + } + } + + func getState(reply: @escaping (ContainerState) -> Void) { + self.semaphore.wait() + let reply: (ContainerState) -> Void = { + os_log("getState complete: %@", log: tplogTrace, type: .info, $0.egoPeerID ?? "") + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + var state = ContainerState() + state.egoPeerID = self.containerMO.egoPeerID + + if self.containerMO.bottles != nil { + self.containerMO.bottles!.forEach { bottle in + state.bottles.insert(bottle as! BottleMO) + } + } + + self.model.allPeers().forEach { peer in + state.peers[peer.peerID] = peer + } + state.vouchers = Array(self.model.allVouchers()) + reply(state) + } + } + + // This will only fetch changes if no changes have ever been fetched before + private func fetchAndPersistChangesIfNeeded(reply: @escaping (Error?) -> Void) { + self.moc.performAndWait { + if self.containerMO.changeToken == nil { + self.onqueueFetchAndPersistChanges(reply: reply) + } else { + reply(nil) + } + } + } + + private func fetchAndPersistChanges(reply: @escaping (Error?) -> Void) { + self.moc.performAndWait { + self.onqueueFetchAndPersistChanges(reply: reply) + } + } + + private func onqueueFetchAndPersistChanges(reply: @escaping (Error?) -> Void) { + let request = FetchChangesRequest.with { + $0.changeToken = self.containerMO.changeToken ?? "" + } + os_log("Fetching with change token: %@", log: tplogDebug, type: .default, request.changeToken.count > 0 ? request.changeToken : "empty") + + self.cuttlefish.fetchChanges(request) { response, error in + os_log("FetchChanges(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + switch error { + case CuttlefishErrorMatcher(code: CuttlefishErrorCode.changeTokenExpired): + os_log("change token is expired; resetting local CK storage", log: tplogDebug, type: .default) + + self.moc.performAndWait { + do { + try self.deleteLocalCloudKitData() + } catch { + os_log("Failed to reset local data: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(error) + return + } + + self.fetchAndPersistChanges(reply: reply) + } + + return + default: + os_log("Fetch error is an unknown error: %@", log: tplogDebug, type: .default, String(describing: error)) + } + + os_log("Could not fetch changes: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(error) + return + } + + do { + try self.persist(changes: response.changes) + } catch { + os_log("Could not persist changes: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(error) + return + } + + if response.changes.more { + os_log("persist: More changes indicated. Fetching...", log: tplogDebug, type: .default) + self.fetchAndPersistChanges(reply: reply) + return + } else { + os_log("persist: no more changes!", log: tplogDebug, type: .default) + reply(nil) + } + } + } + + // + // Check for delta update in trust lists, that should lead to update of TLKShares + // + private func haveTrustMemberChanges(newDynamicInfo: TPPeerDynamicInfo, oldDynamicInfo: TPPeerDynamicInfo?) -> Bool { + guard let oldDynamicInfo = oldDynamicInfo else { + return true + } + if (newDynamicInfo.includedPeerIDs != oldDynamicInfo.includedPeerIDs) { + return true + } + if (newDynamicInfo.excludedPeerIDs != oldDynamicInfo.excludedPeerIDs) { + return true + } + if (newDynamicInfo.preapprovals != oldDynamicInfo.preapprovals) { + return true + } + return false + } + + // Fetch and persist changes from Cuttlefish. If this results + // in us calculating a new dynamicInfo then give the new dynamicInfo + // to Cuttlefish. If Cuttlefish returns more changes then persist + // them locally, update dynamicInfo if needed, and keep doing that + // until dynamicInfo is unchanged and there are no more changes to fetch. + // + // Must be holding the semaphore to call this, and it remains + // the caller's responsibility to release it after it completes + // (i.e. after reply is invoked). + internal func fetchChangesAndUpdateTrustIfNeeded(stableChanges: StableChanges? = nil, + changesPending: Bool = false, + reply: @escaping (TrustedPeersHelperPeerState?, Error?) -> Void) { + self.fetchAndPersistChanges { error in + if let error = error { + os_log("fetchChangesAndUpdateTrustIfNeeded: fetching failed: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(nil, error) + } + + self.updateTrustIfNeeded(stableChanges: stableChanges, changesPending: changesPending, reply: reply) + } + } + + // If this results in us calculating a new dynamicInfo then, + // upload the new dynamicInfo + // to Cuttlefish. If Cuttlefish returns more changes then persist + // them locally, update dynamicInfo if needed, and keep doing that + // until dynamicInfo is unchanged and there are no more changes to fetch. + // + // Must be holding the semaphore to call this, and it remains + // the caller's responsibility to release it after it completes + // (i.e. after reply is invoked). + private func updateTrustIfNeeded(stableChanges: StableChanges? = nil, + changesPending: Bool = false, + reply: @escaping (TrustedPeersHelperPeerState?, Error?) -> Void) { + self.moc.performAndWait { + guard let egoPeerID = self.containerMO.egoPeerID else { + // No identity, nothing to do + os_log("updateTrustIfNeeded: No identity.", log: tplogDebug, type: .default) + reply(TrustedPeersHelperPeerState(peerID: nil, isPreapproved: false, status: .unknown, memberChanges: changesPending, unknownMachineIDs: false), nil) + return + } + loadEgoKeyPair(identifier: signingKeyIdentifier(peerID: egoPeerID)) { signingKeyPair, error in + guard let signingKeyPair = signingKeyPair else { + os_log("updateTrustIfNeeded: no signing key pair: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(TrustedPeersHelperPeerState(peerID: nil, isPreapproved: false, status: .unknown, memberChanges: changesPending, unknownMachineIDs: false), error) + return + } + guard self.model.hasPeer(withID: egoPeerID) else { + // Not in circle, nothing to do + let isPreapproved = self.model.hasPeerPreapprovingKey(signingKeyPair.publicKey().spki()) + os_log("updateTrustIfNeeded: ego peer is not in model, is %@", log: tplogDebug, type: .default, isPreapproved ? "preapproved" : "not yet preapproved") + reply(TrustedPeersHelperPeerState(peerID: egoPeerID, + isPreapproved: isPreapproved, + status: .unknown, + memberChanges: changesPending, + unknownMachineIDs: false), + nil) + return + } + self.moc.performAndWait { + let dynamicInfo: TPPeerDynamicInfo + var stableInfo: TPPeerStableInfo? + do { + // FIXME We should be able to calculate the contents of dynamicInfo without the signingKeyPair, + // and then only load the key if it has changed and we need to sign a new one. This would also + // help make our detection of change immune from non-canonical serialization of dynamicInfo. + dynamicInfo = try self.model.calculateDynamicInfoForPeer(withID: egoPeerID, + addingPeerIDs: nil, + removingPeerIDs: nil, + preapprovedKeys: nil, + signing: signingKeyPair, + currentMachineIDs: self.onqueueCurrentMIDList()) + + stableInfo = try self.createNewStableInfoIfNeeded(stableChanges: stableChanges, + egoPeerID: egoPeerID, + dynamicInfo: dynamicInfo, + signingKeyPair: signingKeyPair) + } catch { + os_log("updateTrustIfNeeded: couldn't calculate dynamic info: %@", log: tplogDebug, type: .default, error as CVarArg) + reply(TrustedPeersHelperPeerState(peerID: egoPeerID, + isPreapproved: false, + status: self.model.statusOfPeer(withID: egoPeerID), + memberChanges: changesPending, + unknownMachineIDs: false), + error) + return + } + + os_log("updateTrustIfNeeded: produced a stableInfo: %@", log: tplogDebug, type: .default, String(describing: stableInfo)) + os_log("updateTrustIfNeeded: produced a dynamicInfo: %@", log: tplogDebug, type: .default, dynamicInfo) + + let peer = self.model.peer(withID: egoPeerID) + if (stableInfo == nil || stableInfo == peer?.stableInfo) && + dynamicInfo == peer?.dynamicInfo { + os_log("updateTrustIfNeeded: complete.", log: tplogDebug, type: .default) + // No change to the dynamicInfo: update the MID list now that we've reached a steady state + do { + self.onqueueUpdateMachineIDListFromModel(dynamicInfo: dynamicInfo) + try self.moc.save() + } catch { + os_log("updateTrustIfNeeded: unable to remove untrusted MachineIDs: %@", log: tplogDebug, type: .default, error as CVarArg) + } + + reply(TrustedPeersHelperPeerState(peerID: egoPeerID, + isPreapproved: false, + status: self.model.statusOfPeer(withID: egoPeerID), + memberChanges: changesPending, + unknownMachineIDs: self.onqueueFullIDMSListWouldBeHelpful()), + nil) + return + } + // Check if we change that should trigger a notification that should trigger TLKShare updates + let haveChanges = changesPending || self.haveTrustMemberChanges(newDynamicInfo: dynamicInfo, oldDynamicInfo: peer?.dynamicInfo) + + let signedDynamicInfo = SignedPeerDynamicInfo(dynamicInfo) + os_log("updateTrustIfNeeded: attempting updateTrust for %@ with: %@", log: tplogDebug, type: .default, egoPeerID, dynamicInfo) + var request = UpdateTrustRequest.with { + $0.changeToken = self.containerMO.changeToken ?? "" + $0.peerID = egoPeerID + $0.dynamicInfoAndSig = signedDynamicInfo + } + if let stableInfo = stableInfo { + request.stableInfoAndSig = SignedPeerStableInfo(stableInfo) + } + self.cuttlefish.updateTrust(request) { response, error in + os_log("UpdateTrust(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard let response = response, error == nil else { + os_log("UpdateTrust failed: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(nil, error ?? ContainerError.cloudkitResponseMissing) + return + } + + do { + try self.persist(changes: response.changes) + } catch { + os_log("updateTrust failed: %@", log: tplogDebug, String(describing: error)) + reply(nil, error) + return + } + + if response.changes.more { + self.fetchChangesAndUpdateTrustIfNeeded(stableChanges: stableChanges, + changesPending: haveChanges, + reply: reply) + } else { + self.updateTrustIfNeeded(stableChanges: stableChanges, + changesPending: haveChanges, + reply: reply) + } + } + } + } + } + } + + + private func persist(changes: Changes) throws { + // This is some nonsense: I can't figure out how to tell swift to throw an exception across performAndWait. + // So, do it ourself + var outsideBlockError: Error? + + self.moc.performAndWait { + os_log("persist: Received %d peer differences, more: %d", log: tplogDebug, type: .default, + changes.differences.count, + changes.more) + os_log("persist: New change token: %@", log: tplogDebug, type: .default, changes.changeToken) + + do { + try self.onQueuePersist(changes: changes) + } catch { + outsideBlockError = error + } + } + + if let outsideBlockError = outsideBlockError { + throw outsideBlockError + } + } + + // Must be on moc queue to call this. + // Changes are registered in the model and stored in moc. + private func onQueuePersist(changes: Changes) throws { + self.containerMO.changeToken = changes.changeToken + self.containerMO.moreChanges = changes.more + + if changes.differences.count > 0 { + self.model.clearViableBottles() + } + + try changes.differences.forEach { peerDifference in + if let operation = peerDifference.operation { + switch operation { + case .add(let peer): + try self.addOrUpdate(peer: peer) + + case .update(let peer): + try self.addOrUpdate(peer: peer) + // Update containerMO ego data if it has changed. + if peer.peerID == self.containerMO.egoPeerID { + guard let stableInfoAndSig:TPPeerStableInfo = peer.stableInfoAndSig.toStableInfo() else { + break + } + self.containerMO.egoPeerStableInfo = stableInfoAndSig.data + self.containerMO.egoPeerStableInfoSig = stableInfoAndSig.sig + } + + case .remove(let peer): + self.model.deletePeer(withID: peer.peerID) + if let peerMO = try self.fetchPeerMO(peerID: peer.peerID) { + self.moc.delete(peerMO) + } + } + } + } + + let signingKey = changes.recoverySigningPubKey + let encryptionKey = changes.recoveryEncryptionPubKey + + if signingKey.count > 0 && encryptionKey.count > 0 { + self.addOrUpdate(signingKey: signingKey, encryptionKey: encryptionKey) + } + try self.moc.save() + } + + // Must be on moc queue to call this + // Deletes all things that should come back from CloudKit. Keeps the egoPeer data, though. + private func deleteLocalCloudKitData() throws { + os_log("Deleting all CloudKit data", log: tplogDebug, type: .default) + + do { + let peerRequest = NSFetchRequest(entityName: "Peer") + peerRequest.predicate = NSPredicate(format: "container == %@", self.containerMO) + try self.moc.execute(NSBatchDeleteRequest(fetchRequest: peerRequest)) + + let bottleRequest = NSFetchRequest(entityName: "Bottle") + bottleRequest.predicate = NSPredicate(format: "container == %@", self.containerMO) + try self.moc.execute(NSBatchDeleteRequest(fetchRequest: bottleRequest)) + + self.containerMO.peers = nil + self.containerMO.bottles = nil + self.containerMO.changeToken = nil + self.containerMO.moreChanges = false + + self.model = Container.loadModel(from: self.containerMO) + try self.moc.save() + } catch { + os_log("Local delete failed: %@", log: tplogDebug, type: .default, error as CVarArg) + throw error + } + + os_log("Saved model with %d peers", log: tplogDebug, type: .default, self.model.allPeerIDs().count) + } + + // Must be on moc queue to call this. + private func addOrUpdate(signingKey: Data, encryptionKey: Data) { + self.model.setRecoveryKeys( + TPRecoveryKeyPair(signingSPKI: signingKey, encryptionSPKI: encryptionKey)) + } + + // Must be on moc queue to call this. + private func addOrUpdate(peer: Peer) throws { + if !self.model.hasPeer(withID: peer.peerID) { + // Add: + guard let permanentInfo = peer.permanentInfoAndSig.toPermanentInfo(peerID: peer.peerID) else { + // Ignoring bad peer + return + } + let stableInfo = peer.stableInfoAndSig.toStableInfo() + let dynamicInfo = peer.dynamicInfoAndSig.toDynamicInfo() + let vouchers = peer.vouchers.compactMap { + TPVoucher(infoWith: $0.voucher, sig: $0.sig) + } + let isEgoPeer = peer.peerID == self.containerMO.egoPeerID + try self.registerPeerMO(permanentInfo: permanentInfo, + stableInfo: stableInfo, + dynamicInfo: dynamicInfo, + vouchers: vouchers, + isEgoPeer: isEgoPeer) + } else { + // Update: + // The assertion here is that every peer registered in model is also present in containerMO + let peerMO = try self.fetchPeerMO(peerID: peer.peerID)! + + if let stableInfo = peer.stableInfoAndSig.toStableInfo() { + try self.model.update(stableInfo, forPeerWithID: peer.peerID) + // Pull the stableInfo back out of the model, and persist that. + // The model checks signatures and clocks to prevent replay attacks. + let modelPeer = self.model.peer(withID: peer.peerID) + peerMO.stableInfo = modelPeer?.stableInfo?.data + peerMO.stableInfoSig = modelPeer?.stableInfo?.sig + } + if let dynamicInfo = peer.dynamicInfoAndSig.toDynamicInfo() { + try self.model.update(dynamicInfo, forPeerWithID: peer.peerID) + // Pull the dynamicInfo back out of the model, and persist that. + // The model checks signatures and clocks to prevent replay attacks. + let modelPeer = self.model.peer(withID: peer.peerID) + peerMO.dynamicInfo = modelPeer?.dynamicInfo?.data + peerMO.dynamicInfoSig = modelPeer?.dynamicInfo?.sig + } + peer.vouchers.forEach { + if let voucher = TPVoucher(infoWith: $0.voucher, sig: $0.sig) { + self.model.register(voucher) + let voucherMO = VoucherMO(context: self.moc) + voucherMO.voucherInfo = voucher.data + voucherMO.voucherInfoSig = voucher.sig + peerMO.addToVouchers(voucherMO) + } + } + } + } + + // Must be on moc queue to call this. + private func fetchPeerMO(peerID: String) throws -> PeerMO? { + let fetch = NSFetchRequest(entityName: "Peer") + fetch.predicate = NSPredicate(format: "peerID == %@ && container == %@", peerID, self.containerMO) + let peers = try self.moc.fetch(fetch) + return peers.first as? PeerMO + } + + // Must be on moc queue to call this. + private func getPolicyDoc(_ policyVersion: UInt64) throws -> TPPolicyDocument { + guard let policyDoc = self.model.policy(withVersion: policyVersion) else { + throw ContainerError.unknownPolicyVersion(policyVersion) + } + assert(policyVersion == policyDoc.policyVersion) + if policyVersion == prevailingPolicyVersion { + assert(policyDoc.policyHash == prevailingPolicyHash) + } + return policyDoc + } + + // Must be on moc queue to call this. + private func createNewStableInfoIfNeeded(stableChanges: StableChanges?, + egoPeerID: String, + dynamicInfo: TPPeerDynamicInfo, + signingKeyPair: _SFECKeyPair) throws -> TPPeerStableInfo? { + func noChange(_ change: T?, _ existing: T?) -> Bool { + return (nil == change) || change == existing + } + let existingStableInfo = self.model.peer(withID: egoPeerID)?.stableInfo + if noChange(stableChanges?.deviceName, existingStableInfo?.deviceName) && + noChange(stableChanges?.serialNumber, existingStableInfo?.serialNumber) && + noChange(stableChanges?.osVersion, existingStableInfo?.osVersion) && + noChange(stableChanges?.policyVersion, existingStableInfo?.policyVersion) && + noChange(stableChanges?.policySecrets, existingStableInfo?.policySecrets) && + noChange(stableChanges?.recoverySigningPubKey, existingStableInfo?.recoverySigningPublicKey) && + noChange(stableChanges?.recoveryEncryptionPubKey, existingStableInfo?.recoveryEncryptionPublicKey) && + self.model.doesPeerRecoveryKeyMatchPeers(egoPeerID) { + return nil + } + let policyHash: String? + if let policyVersion = stableChanges?.policyVersion { + let policyDoc = try self.getPolicyDoc(policyVersion) + policyHash = policyDoc.policyHash + } else { + policyHash = nil + } + + // Determine which recovery key we'd like to be using, given our current idea of who to trust + let newRecoveryKeys = self.model.bestRecoveryKey(with: dynamicInfo) + + return try self.model.createStableInfo(withPolicyVersion: stableChanges?.policyVersion ?? existingStableInfo?.policyVersion ?? prevailingPolicyVersion, + policyHash: policyHash ?? existingStableInfo?.policyHash ?? prevailingPolicyHash, + policySecrets: stableChanges?.policySecrets ?? existingStableInfo?.policySecrets, + deviceName: stableChanges?.deviceName ?? existingStableInfo?.deviceName ?? "", + serialNumber: stableChanges?.serialNumber ?? existingStableInfo?.serialNumber ?? "", + osVersion: stableChanges?.osVersion ?? existingStableInfo?.osVersion ?? "", + signing: signingKeyPair, + recoverySigningPubKey: newRecoveryKeys?.signingSPKI ?? existingStableInfo?.recoverySigningPublicKey, + recoveryEncryptionPubKey: newRecoveryKeys?.encryptionSPKI ?? existingStableInfo?.recoveryEncryptionPublicKey) + } + + private func assembleBottle(egoPeerID: String) throws -> Bottle { + let bottleMoSet = containerMO.bottles as? Set + + var bottleMOs = bottleMoSet?.filter { + $0.peerID == egoPeerID + } + + if let count = bottleMOs?.count { + if count > 1 { + throw ContainerError.tooManyBottlesForPeer + } else if count == 0 { + throw ContainerError.noBottleForPeer + } + } else { + throw ContainerError.failedToAssembleBottle + } + + let BM: BottleMO? = (bottleMOs?.removeFirst()) + + let bottle = try Bottle.with { + $0.peerID = egoPeerID + + if let bottledPeerData = BM?.contents { + $0.contents = bottledPeerData + } else { + throw ContainerError.failedToAssembleBottle + } + + if let bottledPeerEscrowSigningSPKI = BM?.escrowedSigningSPKI { + $0.escrowedSigningSpki = bottledPeerEscrowSigningSPKI + } else { + throw ContainerError.failedToAssembleBottle + } + + if let bottledPeerSignatureUsingEscrowKey = BM?.signatureUsingEscrowKey { + $0.signatureUsingEscrowKey = bottledPeerSignatureUsingEscrowKey + } else { + throw ContainerError.failedToAssembleBottle + } + + if let bottledPeerSignatureUsingPeerKey = BM?.signatureUsingPeerKey { + $0.signatureUsingPeerKey = bottledPeerSignatureUsingPeerKey + } else { + throw ContainerError.failedToAssembleBottle + } + + if let bID = BM?.bottleID { + $0.bottleID = bID + } else { + throw ContainerError.failedToAssembleBottle + } + } + + return bottle + } + + func reportHealth(request: ReportHealthRequest, reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("reportHealth complete %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + var updatedRequest = request + + if let egoPeerID = self.containerMO.egoPeerID { + loadEgoKeys(peerID: egoPeerID) { egoPeerKeys, _ in + updatedRequest.octagonEgoIdentity = (egoPeerKeys != nil) + } + } + + self.moc.performAndWait { + self.cuttlefish.reportHealth(updatedRequest) { response, error in + os_log("reportHealth(%@): %@, error: %@", log: tplogDebug, "\(String(describing: request))", "\(String(describing: response))", "\(String(describing: error))") + guard error == nil else { + reply(error) + return + } + reply(nil) + } + } + } + + func pushHealthInquiry(reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("reportHealth complete %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + self.moc.performAndWait { + self.cuttlefish.pushHealthInquiry(HealthInquiryRequest()) { response, error in + os_log("pushHealthInquiry(): %@, error: %@", log: tplogDebug, "\(String(describing: response))", "\(String(describing: error))") + guard error == nil else { + reply(error) + return + } + reply(nil) + } + } + } +} diff --git a/keychain/TrustedPeersHelper/ContainerMap.swift b/keychain/TrustedPeersHelper/ContainerMap.swift new file mode 100644 index 00000000..83cfbbb3 --- /dev/null +++ b/keychain/TrustedPeersHelper/ContainerMap.swift @@ -0,0 +1,233 @@ +/* + * 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 CloudKit +import CloudKit_Private +import CloudKitCode +import CloudKitCodeProtobuf +import CoreData +import Foundation + +// TODO: merge into CodeConnection + +let CuttlefishPushTopicBundleIdentifier = "com.apple.security.cuttlefish" + +public class RetryingInvocable: CloudKitCode.Invocable { + private let underlyingInvocable: CloudKitCode.Invocable + + internal init(retry: CloudKitCode.Invocable) { + self.underlyingInvocable = retry + } + + private func retryableError(error: Error?) -> Bool { + switch error { + case let error as NSError where error.domain == NSURLErrorDomain && error.code == NSURLErrorTimedOut: + return true + case let error as NSError where error.domain == CKErrorDomain && error.code == CKError.networkFailure.rawValue: + return true + case CuttlefishErrorMatcher(code: CuttlefishErrorCode.retryableServerFailure): + return true + default: + return false + } + } + + public func invoke(function: String, + request: RequestType, + completion: @escaping (ResponseType?, Error?) -> Void) where RequestType : Message, ResponseType : Message { + let now = Date() + let deadline = Date(timeInterval: 30, since: now) + let delay = TimeInterval(5) + + self.invokeRetry(function: function, + request: request, + deadline: deadline, + delay: delay, + completion: completion) + } + + private func invokeRetry( + function: String, + request: RequestType, + deadline: Date, + delay: TimeInterval, + completion: @escaping (ResponseType?, Error?) -> Void) { + + self.underlyingInvocable.invoke(function: function, + request: request) { (response: ResponseType?, error: Error?) in + if self.retryableError(error: error) { + let now = Date() + let cutoff = Date(timeInterval: delay, since: now) + guard cutoff.compare(deadline) == ComparisonResult.orderedDescending else { + Thread.sleep(forTimeInterval: delay) + os_log("%{public}@ error: %{public}@ (retrying, now=%{public}@, deadline=%{public}@)", log: tplogDebug, + function, + "\(String(describing: error))", + "\(String(describing: now))", + "\(String(describing: deadline))") + self.invokeRetry(function: function, + request: request, + deadline: deadline, + delay: delay, + completion: completion) + return + } + } + completion(response, error) + } + } +} + +public class MyCodeConnection: CloudKitCode.Invocable { + private let serviceName: String + private let container: CKContainer + private let databaseScope: CKDatabase.Scope + private let local: Bool + private let queue: DispatchQueue + + internal init(service: String, container: CKContainer, databaseScope: CKDatabase.Scope, local: Bool) { + self.serviceName = service + self.container = container + self.databaseScope = databaseScope + self.local = local + self.queue = DispatchQueue(label: "MyCodeConnection", qos: .userInitiated) + } + + /// Temporary stand-in until xcinverness moves to a swift-grpc plugin. + /// Intended to be used by protoc-generated code only + public func invoke( + function: String, request: RequestType, + completion: @escaping (ResponseType?, Error?) -> Void) { + + // Hack to fool CloudKit, real solution is tracked in + self.queue.async { + + let operation = CodeOperation( + service: self.serviceName, + functionName: function, + request: request, + destinationServer: self.local ? .local : .default) + + // As each UUID finishes, log it. + let requestCompletion = { (requestInfo: CKRequestInfo?) -> Void in + if let requestUUID = requestInfo?.requestUUID { + os_log("ckoperation request finished: %{public}@ %{public}@", log: tplogDebug, function, requestUUID) + } + } + operation.requestCompletedBlock = requestCompletion + + let loggingCompletion = { (response: ResponseType?, error: Error?) -> Void in + os_log("%@(%@): %@, error: %@", + log: tplogDebug, + function, + "\(String(describing: request))", + "\(String(describing: response))", + "\(String(describing: error))") + completion(response, error) + } + operation.codeOperationCompletionBlock = loggingCompletion + + /* Same convenience API properties that we specify in CKContainer / CKDatabase */ + operation.queuePriority = .low + + // One alternative here would be to not set any QoS and trust the + // QoS propagation to do what's right. But there is also some benefit in + // just using a lower CPU QoS because it should be hard to measure for the + // casual adopter. + operation.qualityOfService = .userInitiated + + operation.configuration.discretionaryNetworkBehavior = .nonDiscretionary + operation.configuration.automaticallyRetryNetworkFailures = false + operation.configuration.isCloudKitSupportOperation = true + + operation.configuration.sourceApplicationBundleIdentifier = CuttlefishPushTopicBundleIdentifier + + let database = self.container.database(with: self.databaseScope) + + database.add(operation) + } + } +} + +protocol ContainerNameToCuttlefishInvocable { + func client(container: String) -> CloudKitCode.Invocable +} + +class CKCodeCuttlefishInvocableCreator: ContainerNameToCuttlefishInvocable { + func client(container: String) -> CloudKitCode.Invocable { + // Set up Cuttlefish client connection + let ckContainer = CKContainer(identifier: container) + + // Cuttlefish is using its own push topic. + // To register for this push topic, we need to issue CK operations with a specific bundle identifier + ckContainer.sourceApplicationBundleIdentifier = CuttlefishPushTopicBundleIdentifier + + let ckDatabase = ckContainer.privateCloudDatabase + return MyCodeConnection(service: "Cuttlefish", container: ckContainer, + databaseScope: ckDatabase.databaseScope, local: false) + } +} + +// A collection of Containers. +// When a Container of a given name is requested, it is created if it did not already exist. +// Methods may be invoked concurrently. +class ContainerMap { + private let queue = DispatchQueue(label: "com.apple.security.TrustedPeersHelper.ContainerMap") + + let invocableCreator: ContainerNameToCuttlefishInvocable + + init(invocableCreator: ContainerNameToCuttlefishInvocable) { + self.invocableCreator = invocableCreator + } + + // Only access containers while executing on queue + private var containers: [ContainerName: Container] = [:] + + func findOrCreate(name: ContainerName) throws -> Container { + return try queue.sync { + if let container = self.containers[name] { + return container + } else { + + // Set up Core Data stack + let persistentStoreURL = ContainerMap.urlForPersistentStore(name: name) + let description = NSPersistentStoreDescription(url: persistentStoreURL) + + // Wrap whatever we're given in a magically-retrying layer + let cuttlefishInvocable = self.invocableCreator.client(container: name.container) + let retryingInvocable = RetryingInvocable(retry: cuttlefishInvocable) + let cuttlefish = CuttlefishAPIAsyncClient(invocable: retryingInvocable) + + let container = try Container(name: name, persistentStoreDescription: description, + cuttlefish: cuttlefish) + self.containers[name] = container + return container + } + } + } + + static func urlForPersistentStore(name: ContainerName) -> URL { + let filename = name.container + "-" + name.context + ".TrustedPeersHelper.db" + return SecCopyURLForFileInKeychainDirectory(filename as CFString) as URL + } +} diff --git a/keychain/TrustedPeersHelper/Container_MachineIDs.swift b/keychain/TrustedPeersHelper/Container_MachineIDs.swift new file mode 100644 index 00000000..7c015f98 --- /dev/null +++ b/keychain/TrustedPeersHelper/Container_MachineIDs.swift @@ -0,0 +1,373 @@ + +import CoreData +import Foundation + +extension MachineMO { + func modifiedInPast(hours: Int) -> Bool { + guard let modifiedDate = self.modified else { + return false + } + + let dateLimit = Date(timeIntervalSinceNow: -60*60*TimeInterval(hours)) + return modifiedDate.compare(dateLimit) == ComparisonResult.orderedDescending + } + + func modifiedDate() -> String { + guard let modifiedDate = self.modified else { + return "unknown" + } + + let dateFormatter = ISO8601DateFormatter() + return dateFormatter.string(from: modifiedDate) + } + + func asTPMachineID() -> TPMachineID { + return TPMachineID(machineID: self.machineID ?? "unknown", + status: TPMachineIDStatus(rawValue: UInt(self.status)) ?? .unknown, + modified: self.modified ?? Date()) + } +} + +// You get two days of grace before you're removed +let cutoffHours = 48 + +extension Container { + // CoreData suggests not using heavyweight migrations, so we have two locations to store the machine ID list. + // Perform our own migration from the no-longer-used field. + internal static func onqueueUpgradeMachineIDSetToModel(container: ContainerMO, moc: NSManagedObjectContext) { + let knownMachineMOs = container.machines as? Set ?? Set() + let knownMachineIDs = Set(knownMachineMOs.compactMap { $0.machineID }) + + let allowedMachineIDs = container.allowedMachineIDs as? Set ?? Set() + let missingIDs = allowedMachineIDs.filter { !knownMachineIDs.contains($0) } + + missingIDs.forEach { id in + let mid = MachineMO(context: moc) + mid.machineID = id + mid.seenOnFullList = true + mid.status = Int64(TPMachineIDStatus.allowed.rawValue) + mid.modified = Date() + container.addToMachines(mid) + } + + container.allowedMachineIDs = Set() as NSSet + } + + internal static func onqueueUpgradeMachineIDSetToUseStatus(container: ContainerMO, moc: NSManagedObjectContext) { + let knownMachineMOs = container.machines as? Set ?? Set() + + // Once we run this upgrade, we will set the allowed bool to false, since it's unused. + // Therefore, if we have a single record with "allowed" set, we haven't run the upgrade. + let runUpgrade = knownMachineMOs.filter { $0.allowed }.count > 0 + if runUpgrade { + knownMachineMOs.forEach { mo in + if mo.allowed { + mo.status = Int64(TPMachineIDStatus.allowed.rawValue) + } else { + mo.status = Int64(TPMachineIDStatus.disallowed.rawValue) + } + mo.allowed = false + } + } + } + + func setAllowedMachineIDs(_ allowedMachineIDs: Set, reply: @escaping (Bool, Error?) -> Void) { + self.semaphore.wait() + let reply: (Bool, Error?) -> Void = { + os_log("setAllowedMachineIDs complete: %@", log: tplogTrace, type: .info, traceError($1)) + self.semaphore.signal() + reply($0, $1) + } + + os_log("Setting allowed machine IDs: %@", log: tplogDebug, type: .default, allowedMachineIDs) + + // Note: we currently ignore any machineIDs that are set in the model, but never appeared on the + // Trusted Devices list. We should give them a grace period (1wk?) then kick them out. + + self.moc.performAndWait { + do { + var differences = false + + var knownMachines = containerMO.machines as? Set ?? Set() + let knownMachineIDs = Set(knownMachines.compactMap { $0.machineID } ) + + + knownMachines.forEach { machine in + guard let mid = machine.machineID else { + os_log("Machine has no ID: %@", log: tplogDebug, type: .default, machine) + return + } + if allowedMachineIDs.contains(mid) { + if machine.status == TPMachineIDStatus.allowed.rawValue { + os_log("Machine ID still trusted: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + } else { + os_log("Machine ID newly retrusted: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + differences = true + } + machine.status = Int64(TPMachineIDStatus.allowed.rawValue) + machine.seenOnFullList = true + machine.modified = Date() + } else { + // This machine ID is not on the list. What, if anything, should be done? + if machine.status == TPMachineIDStatus.allowed.rawValue { + // IDMS sometimes has list consistency issues. So, if we see a device 'disappear' from the list, it may or may not + // actually have disappered: we may have received an 'add' push and then fetched the list too quickly. + // To hack around this, we track whether we've seen the machine on the full list yet. If we haven't, this was likely + // the result of an 'add' push, and will be given 48 hours of grace before being removed. + if machine.seenOnFullList { + machine.status = Int64(TPMachineIDStatus.disallowed.rawValue) + machine.modified = Date() + os_log("Newly distrusted machine ID: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + differences = true + + } else { + if machine.modifiedInPast(hours: cutoffHours) { + os_log("Allowed-but-unseen machine ID isn't on full list, last modified %@, ignoring: %@", log: tplogDebug, type: .default, machine.modifiedDate(), String(describing: machine.machineID)) + } else { + os_log("Allowed-but-unseen machine ID isn't on full list, last modified %@, distrusting: %@", log: tplogDebug, type: .default, machine.modifiedDate(), String(describing: machine.machineID)) + machine.status = Int64(TPMachineIDStatus.disallowed.rawValue) + machine.modified = Date() + differences = true + } + } + + } else if machine.status == TPMachineIDStatus.unknown.rawValue { + if machine.modifiedInPast(hours: cutoffHours) { + os_log("Unknown machine ID last modified %@; leaving unknown: %@", log: tplogDebug, type: .default, machine.modifiedDate(), String(describing: machine.machineID)) + } else { + os_log("Unknown machine ID last modified %@; distrusting: %@", log: tplogDebug, type: .default, machine.modifiedDate(), String(describing: machine.machineID)) + machine.status = Int64(TPMachineIDStatus.disallowed.rawValue) + machine.modified = Date() + differences = true + } + } + } + } + + // Do we need to create any further objects? + allowedMachineIDs.forEach { machineID in + if(!knownMachineIDs.contains(machineID)) { + // We didn't know about this machine before; it's newly trusted! + let machine = MachineMO(context: self.moc) + machine.machineID = machineID + machine.container = containerMO + machine.seenOnFullList = true + machine.modified = Date() + machine.status = Int64(TPMachineIDStatus.allowed.rawValue) + os_log("Newly trusted machine ID: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + differences = true + + self.containerMO.addToMachines(machine) + knownMachines.insert(machine) + } + } + + // Now, are there any machine IDs in the model that aren't in the list? If so, add them as "unknown" + let modelMachineIDs = self.model.allMachineIDs() + modelMachineIDs.forEach { peerMachineID in + if !knownMachineIDs.contains(peerMachineID) && !allowedMachineIDs.contains(peerMachineID) { + os_log("Peer machineID is unknown, beginning grace period: %@", log: tplogDebug, type: .default, peerMachineID) + let machine = MachineMO(context: self.moc) + machine.machineID = peerMachineID + machine.container = containerMO + machine.seenOnFullList = false + machine.modified = Date() + machine.status = Int64(TPMachineIDStatus.unknown.rawValue) + differences = true + + self.containerMO.addToMachines(machine) + } + } + + // We no longer use allowed machine IDs. + self.containerMO.allowedMachineIDs = NSSet() + + try self.moc.save() + + reply(differences, nil) + } catch { + os_log("Error setting machine ID list: %@", log: tplogDebug, type: .default, (error as CVarArg?) ?? "no error") + reply(false, error) + } + } + } + + func addAllow(_ machineIDs: [String], reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("addAllow complete: %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + os_log("Adding allowed machine IDs: %@", log: tplogDebug, type: .default, machineIDs) + + self.moc.performAndWait { + do { + var knownMachines = containerMO.machines as? Set ?? Set() + let knownMachineIDs = Set(knownMachines.compactMap { $0.machineID } ) + + // We treat an add push as authoritative (even though we should really confirm it with a full list fetch). + // We can get away with this as we're using this list as a deny-list, and if we accidentally don't deny someone fast enough, that's okay. + machineIDs.forEach { machineID in + if knownMachineIDs.contains(machineID) { + knownMachines.forEach { machine in + if machine.machineID == machineID { + machine.status = Int64(TPMachineIDStatus.allowed.rawValue) + machine.modified = Date() + os_log("Continue to trust machine ID: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + } + } + + } else { + let machine = MachineMO(context: self.moc) + machine.machineID = machineID + machine.container = containerMO + machine.seenOnFullList = false + machine.modified = Date() + machine.status = Int64(TPMachineIDStatus.allowed.rawValue) + os_log("Newly trusted machine ID: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + self.containerMO.addToMachines(machine) + + knownMachines.insert(machine) + } + } + + try self.moc.save() + reply(nil) + } catch { + reply(error) + } + } + } + + func removeAllow(_ machineIDs: [String], reply: @escaping (Error?) -> Void) { + self.semaphore.wait() + let reply: (Error?) -> Void = { + os_log("removeAllow complete: %@", log: tplogTrace, type: .info, traceError($0)) + self.semaphore.signal() + reply($0) + } + + os_log("Removing allowed machine IDs: %@", log: tplogDebug, type: .default, machineIDs) + + self.moc.performAndWait { + do { + var knownMachines = containerMO.machines as? Set ?? Set() + let knownMachineIDs = Set(knownMachines.compactMap { $0.machineID } ) + + // This is an odd approach: we'd like to confirm that this MID was actually removed (and not just a delayed push). + // So, let's set the status to "unknown", and its modification date to the distant past. + // The next time we fetch the full list, we'll confirm the removal (or, if the removal push was spurious, re-add the MID as trusted). + machineIDs.forEach { machineID in + if knownMachineIDs.contains(machineID) { + knownMachines.forEach { machine in + if machine.machineID == machineID { + machine.status = Int64(TPMachineIDStatus.unknown.rawValue) + machine.modified = Date.distantPast + os_log("Now suspicious of machine ID: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + } + } + + } else { + let machine = MachineMO(context: self.moc) + machine.machineID = machineID + machine.container = containerMO + machine.status = Int64(TPMachineIDStatus.unknown.rawValue) + machine.modified = Date.distantPast + os_log("Suspicious of new machine ID: %@", log: tplogDebug, type: .default, String(describing: machine.machineID)) + self.containerMO.addToMachines(machine) + + knownMachines.insert(machine) + } + } + + try self.moc.save() + reply(nil) + } catch { + reply(error) + } + } + } + + func onqueueMachineIDAllowedByIDMS(machineID: String) -> Bool { + // For Demo accounts, if the list is entirely empty, then everything is allowed + let machines = containerMO.machines as? Set ?? Set() + if machines.count == 0 { + os_log("machineID list is empty; allowing %@", log: tplogDebug, type: .debug, machineID) + return true + } + + // Note: this function rejects grey devices: machineIDs that are neither allowed nor disallowed + for mo in machines { + if mo.machineID == machineID { + if mo.status == TPMachineIDStatus.allowed.rawValue { + return true + } else { + os_log("machineID %@ not explicitly allowed: %@", log: tplogDebug, type: .debug, machineID, mo) + return false + } + } + } + + // Didn't find it? reject. + os_log("machineID %@ not found on list", log: tplogDebug, type: .debug, machineID) + return false + } + + func onqueueCurrentMIDList() -> TPMachineIDList { + let machines = containerMO.machines as? Set ?? Set() + return TPMachineIDList(entries: machines.map { $0.asTPMachineID() }) + } + + func onqueueUpdateMachineIDListFromModel(dynamicInfo: TPPeerDynamicInfo) { + // This function is intended to be called once the model is in a steady state of adds and deletes. + // + // First, we should ensure that we've written down the MIDs of all trusted peers. That way, if they + // aren't on the MID list now, we'll start the timer for them to be removed if they never make it. + // (But! don't do this if we think this is a Demo account. Those don't have a list, and we shouldn't make one.) + + // Second, we should remove all disallowed MIDs, as those values have been used. + // We don't want to automatically kick out new peers if they rejoin with the same MID. + + let machines = containerMO.machines as? Set ?? Set() + let knownMachineIDs = Set(machines.compactMap { $0.machineID } ) + + // Peers trust themselves. So if the ego peer is in Octagon, its machineID will be in this set + let trustedMachineIDs = Set(dynamicInfo.includedPeerIDs.compactMap { self.model.peer(withID: $0)?.permanentInfo.machineID }) + + // if this account is not a demo account... + if machines.count > 0 { + for peerMachineID in trustedMachineIDs.subtracting(knownMachineIDs) { + os_log("Peer machineID is unknown, beginning grace period: %@", log: tplogDebug, type: .default, peerMachineID) + let machine = MachineMO(context: self.moc) + machine.machineID = peerMachineID + machine.container = self.containerMO + machine.seenOnFullList = false + machine.modified = Date() + machine.status = Int64(TPMachineIDStatus.unknown.rawValue) + + self.containerMO.addToMachines(machine) + } + } else { + os_log("Believe we're in a demo account; not starting an unknown machine ID timer", log: tplogDebug, type: .default) + } + + for mo in (machines) { + if mo.status == TPMachineIDStatus.disallowed.rawValue { + os_log("Dropping knowledge of machineID %@", log: tplogDebug, type: .debug, String(describing: mo.machineID)) + self.containerMO.removeFromMachines(mo) + } + } + } + + // Computes if a full list fetch would be 'useful' + // Useful means that there's an unknown MID whose modification date is before the cutoff + // A full list fetch would either confirm it as 'untrusted' or make it trusted again + func onqueueFullIDMSListWouldBeHelpful() -> Bool { + let unknownMOs = (containerMO.machines as? Set ?? Set()).filter { $0.status == TPMachineIDStatus.unknown.rawValue } + let outdatedMOs = unknownMOs.filter { !$0.modifiedInPast(hours: cutoffHours) } + + return outdatedMOs.count > 0 + } +} diff --git a/keychain/TrustedPeersHelper/CuttlefishAPIHelpers.swift b/keychain/TrustedPeersHelper/CuttlefishAPIHelpers.swift new file mode 100644 index 00000000..708d1881 --- /dev/null +++ b/keychain/TrustedPeersHelper/CuttlefishAPIHelpers.swift @@ -0,0 +1,55 @@ +import Foundation + +extension ViewKey { + static func convert(ckksKey: CKKSKeychainBackedKey) -> ViewKey { + let kc: ViewKeyClass + switch ckksKey.keyclass { + case SecCKKSKeyClassTLK: + kc = .tlk + case SecCKKSKeyClassA: + kc = .classA + case SecCKKSKeyClassC: + kc = .classC + default: + kc = .tlk + } + + return ViewKey.with { + $0.uuid = ckksKey.uuid + $0.parentkeyUuid = ckksKey.parentKeyUUID + $0.keyclass = kc + $0.wrappedkeyBase64 = ckksKey.wrappedkey.base64WrappedKey() + $0.uploadOsversion = SecCKKSHostOSVersion() + } + } +} + +// TODO: We need to support key rolling as well... +extension ViewKeys { + static func convert(ckksKeySet: CKKSKeychainBackedKeySet) -> ViewKeys { + return ViewKeys.with { + $0.view = ckksKeySet.tlk.zoneID.zoneName + $0.newTlk = ViewKey.convert(ckksKey: ckksKeySet.tlk) + $0.newClassA = ViewKey.convert(ckksKey: ckksKeySet.classA) + $0.newClassC = ViewKey.convert(ckksKey: ckksKeySet.classC) + } + } +} + +extension TLKShare { + static func convert(ckksTLKShare: CKKSTLKShare) -> TLKShare { + return TLKShare.with { + $0.view = ckksTLKShare.zoneID.zoneName + $0.curve = Int64(ckksTLKShare.curve.rawValue) + $0.epoch = Int64(ckksTLKShare.epoch) + $0.keyUuid = ckksTLKShare.tlkUUID + $0.poisoned = Int64(ckksTLKShare.poisoned) + $0.receiver = ckksTLKShare.receiverPeerID + $0.receiverPublicEncryptionKey = ckksTLKShare.receiverPublicEncryptionKeySPKI.base64EncodedString() + $0.sender = ckksTLKShare.senderPeerID + $0.signature = ckksTLKShare.signature?.base64EncodedString() ?? "" + $0.version = Int64(ckksTLKShare.version.rawValue) + $0.wrappedkey = ckksTLKShare.wrappedTLK?.base64EncodedString() ?? "" + } + } +} diff --git a/keychain/TrustedPeersHelper/CuttlefishErrors.swift b/keychain/TrustedPeersHelper/CuttlefishErrors.swift new file mode 100644 index 00000000..138c7c6d --- /dev/null +++ b/keychain/TrustedPeersHelper/CuttlefishErrors.swift @@ -0,0 +1,32 @@ +import Foundation + +let CuttlefishErrorDomain = "CuttlefishError" +enum CuttlefishErrorCode: Int { + case establishFailed = 1001 + case invalidChangeToken = 1005 + case resultGraphNotFullyReachable = 1007 + case changeTokenExpired = 1018 + case transactionalFailure = 1019 + case retryableServerFailure = 1021 + case keyHierarchyAlreadyExists = 1033 +} + +struct CuttlefishErrorMatcher { + let code: CuttlefishErrorCode +} + +// Use a 'pattern match operator' to make pretty case statements matching Cuttlefish errors +func ~=(pattern: CuttlefishErrorMatcher, value: Error?) -> Bool { + guard let value = value else { + return false + } + + let error = value as NSError + + guard let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError else { + return false + } + + return error.domain == CKInternalErrorDomain && error.code == CKInternalErrorCode.errorInternalPluginError.rawValue && + underlyingError.domain == CuttlefishErrorDomain && underlyingError.code == pattern.code.rawValue +} diff --git a/keychain/TrustedPeersHelper/Decrypter.swift b/keychain/TrustedPeersHelper/Decrypter.swift new file mode 100644 index 00000000..2deca30e --- /dev/null +++ b/keychain/TrustedPeersHelper/Decrypter.swift @@ -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@ + */ + +import Foundation + +class Decrypter: NSObject, TPDecrypter { + func decryptData(_ ciphertext: Data, withKey key: Data) throws -> Data { + // FIXME This is just a stub, as TPDecrypter interface will change anyway + // TrustedPeers: TPPolicyDocument use protobufs not plists + return Data() + } +} diff --git a/keychain/TrustedPeersHelper/Info.plist b/keychain/TrustedPeersHelper/Info.plist new file mode 100644 index 00000000..518ed0b0 --- /dev/null +++ b/keychain/TrustedPeersHelper/Info.plist @@ -0,0 +1,29 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + TrustedPeersHelper + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + XPC! + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + XPCService + + ServiceType + $(SERVICETYPE_USER_OR_SYSTEM) + + + diff --git a/keychain/TrustedPeersHelper/OctagonPeerKeys.swift b/keychain/TrustedPeersHelper/OctagonPeerKeys.swift new file mode 100644 index 00000000..535ef221 --- /dev/null +++ b/keychain/TrustedPeersHelper/OctagonPeerKeys.swift @@ -0,0 +1,57 @@ +import Foundation + +enum OctagonSelfPeerKeysError: Error { + case noPublicKeys +} + +class OctagonSelfPeerKeys: NSObject, CKKSSelfPeer { + var encryptionKey: _SFECKeyPair + var signingKey: _SFECKeyPair + var peerID: String + + // Here for conformance with CKKSPeer + var publicEncryptionKey: _SFECPublicKey? + var publicSigningKey: _SFECPublicKey? + + var encryptionVerificationKey: _SFECPublicKey + var signingVerificationKey: _SFECPublicKey + + func matchesPeer(_ peer: CKKSPeer) -> Bool { + return false + } + + init(peerID: String, signingKey: _SFECKeyPair, encryptionKey: _SFECKeyPair) throws { + self.peerID = peerID + self.signingKey = signingKey + self.encryptionKey = encryptionKey + + self.publicEncryptionKey = encryptionKey.publicKey as? _SFECPublicKey + self.publicSigningKey = signingKey.publicKey as? _SFECPublicKey + + guard let encryptionVerificationKey = self.publicEncryptionKey, + let signingVerificationKey = self.publicSigningKey else { + throw OctagonSelfPeerKeysError.noPublicKeys + } + + self.encryptionVerificationKey = encryptionVerificationKey + self.signingVerificationKey = signingVerificationKey + } + + override var description: String { + return "" + } +} + +extension TPPeerPermanentInfo: CKKSPeer { + public var publicEncryptionKey: _SFECPublicKey? { + return self.encryptionPubKey as? _SFECPublicKey + } + + public var publicSigningKey: _SFECPublicKey? { + return self.signingPubKey as? _SFECPublicKey + } + + public func matchesPeer(_ peer: CKKSPeer) -> Bool { + return self.peerID == peer.peerID + } +} diff --git a/keychain/TrustedPeersHelper/Policy.swift b/keychain/TrustedPeersHelper/Policy.swift new file mode 100644 index 00000000..2cbece09 --- /dev/null +++ b/keychain/TrustedPeersHelper/Policy.swift @@ -0,0 +1,456 @@ +/* + * 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 Foundation + +struct RawPolicy { + let policyVersion: Int + let policyHash: String + let policyData: String + let plaintextPolicy: TPPolicyDocument +} + +let prevailingPolicyVersion: UInt64 = 5 +let prevailingPolicyHash: String = "SHA256:O/ECQlWhvNlLmlDNh2+nal/yekUC87bXpV3k+6kznSo=" + +func builtInPolicyDocuments() -> [TPPolicyDocument] { + + // These bytes are generated by tppolicy + let rawPolicies = [ + RawPolicy( + policyVersion: 1, + policyHash: "SHA256:TLXrcQmY4ue3oP5pCX1pwsi9BF8cKfohlJBilCroeBs=", + policyData: "CAESDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSCwoDTWFjEgRmdWxsEgwKBGlNYWMSBGZ1bGwSDQoHQXBwbGVUVhICdHYSDgoFV2F0Y2gSBXdhdGNoGhEKCVBDU0VzY3JvdxIEZnVsbBoXCgRXaUZpEgRmdWxsEgJ0dhIFd2F0Y2gaGQoRU2FmYXJpQ3JlZGl0Q2FyZHMSBGZ1bGwiDAoEZnVsbBIEZnVsbCIUCgV3YXRjaBIEZnVsbBIFd2F0Y2giDgoCdHYSBGZ1bGwSAnR2", + plaintextPolicy: try! TPPolicyDocument(version: 1, + modelToCategory: [ + ["prefix": "iPhone", "category": "full"], + ["prefix": "iPad", "category": "full"], + ["prefix": "Mac", "category": "full"], + ["prefix": "iMac", "category": "full"], + ["prefix": "AppleTV", "category": "tv"], + ["prefix": "Watch", "category": "watch"], + ], + categoriesByView: [ + "PCSEscrow": ["full"], + "WiFi": ["full", "tv", "watch"], + "SafariCreditCards": ["full"], + ], + introducersByCategory: [ + "full": ["full"], + "watch": ["full", "watch"], + "tv": ["full", "tv"], + ], + redactions: [:], + keyViewMapping: [], + hashAlgo: .SHA256) + ), + + RawPolicy( + policyVersion: 2, + policyHash: "SHA256:ZL1WBUCyO155rHBJQeghomCCKGmfjtS0jvsK+UEvx5o=", + policyData: "CAISDgoGaUN5Y2xlEgRmdWxsEg4KBmlQaG9uZRIEZnVsbBIMCgRpUGFkEgRmdWxsEgsKA01hYxIEZnVsbBIMCgRpTWFjEgRmdWxsEg0KB0FwcGxlVFYSAnR2Eg4KBVdhdGNoEgV3YXRjaBoRCglQQ1NFc2Nyb3cSBGZ1bGwaFwoEV2lGaRIEZnVsbBICdHYSBXdhdGNoGhkKEVNhZmFyaUNyZWRpdENhcmRzEgRmdWxsIgwKBGZ1bGwSBGZ1bGwiFAoFd2F0Y2gSBGZ1bGwSBXdhdGNoIg4KAnR2EgRmdWxsEgJ0dg==", + plaintextPolicy: try! TPPolicyDocument(version: 2, + modelToCategory: [ + ["prefix": "iCycle", "category": "full"], + ["prefix": "iPhone", "category": "full"], + ["prefix": "iPad", "category": "full"], + ["prefix": "Mac", "category": "full"], + ["prefix": "iMac", "category": "full"], + ["prefix": "AppleTV", "category": "tv"], + ["prefix": "Watch", "category": "watch"], + ], + categoriesByView: [ + "PCSEscrow": ["full"], + "WiFi": ["full", "tv", "watch"], + "SafariCreditCards": ["full"], + ], + introducersByCategory: [ + "full": ["full"], + "tv": ["full", "tv"], + "watch": ["full", "watch"], + ], + redactions: [:], + keyViewMapping: [], + hashAlgo: .SHA256) + ), + + RawPolicy(policyVersion: 3, + policyHash: "SHA256:JZzazSuHXrUhiOfSgElsg6vYKpnvvEPVpciR8FewRWg=", + policyData: "CAMSDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSCwoDTWFjEgRmdWxsEgwKBGlNYWMSBGZ1bGwSDQoHQXBwbGVUVhICdHYSDgoFV2F0Y2gSBXdhdGNoEhcKDkF1ZGlvQWNjZXNzb3J5EgVhdWRpbxocCg1EZXZpY2VQYWlyaW5nEgRmdWxsEgV3YXRjaBoXCghBcHBsZVBheRIEZnVsbBIFd2F0Y2gaJAoVUHJvdGVjdGVkQ2xvdWRTdG9yYWdlEgRmdWxsEgV3YXRjaBoXCghCYWNrc3RvcBIEZnVsbBIFd2F0Y2gaGQoKQXV0b1VubG9jaxIEZnVsbBIFd2F0Y2gaHwoQU2VjdXJlT2JqZWN0U3luYxIEZnVsbBIFd2F0Y2gaIAoRU2FmYXJpQ3JlZGl0Q2FyZHMSBGZ1bGwSBXdhdGNoGhMKBEhvbWUSBGZ1bGwSBXdhdGNoGh4KD1NhZmFyaVBhc3N3b3JkcxIEZnVsbBIFd2F0Y2gaGwoMQXBwbGljYXRpb25zEgRmdWxsEgV3YXRjaBoVCgZFbmdyYW0SBGZ1bGwSBXdhdGNoGi0KE0xpbWl0ZWRQZWVyc0FsbG93ZWQSBGZ1bGwSBXdhdGNoEgJ0dhIFYXVkaW8aFgoHTWFuYXRlZRIEZnVsbBIFd2F0Y2gaHgoEV2lGaRIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxoVCgZIZWFsdGgSBGZ1bGwSBXdhdGNoIhMKBGZ1bGwSBGZ1bGwSBXdhdGNoIhsKBWF1ZGlvEgRmdWxsEgV3YXRjaBIFYXVkaW8iFAoFd2F0Y2gSBGZ1bGwSBXdhdGNoIhUKAnR2EgRmdWxsEgV3YXRjaBICdHYyIgoWAAQiEgIEdndodAoKXkFwcGxlUGF5JBIIQXBwbGVQYXkyJgoYAAQiFAIEdndodAoMXkF1dG9VbmxvY2skEgpBdXRvVW5sb2NrMh4KFAAEIhACBHZ3aHQKCF5FbmdyYW0kEgZFbmdyYW0yHgoUAAQiEAIEdndodAoIXkhlYWx0aCQSBkhlYWx0aDIaChIABCIOAgR2d2h0CgZeSG9tZSQSBEhvbWUyIAoVAAQiEQIEdndodAoJXk1hbmF0ZWUkEgdNYW5hdGVlMjgKIQAEIh0CBHZ3aHQKFV5MaW1pdGVkUGVlcnNBbGxvd2VkJBITTGltaXRlZFBlZXJzQWxsb3dlZDJdClAAAhIeAAQiGgIEdndodAoSXkNvbnRpbnVpdHlVbmxvY2skEhUABCIRAgR2d2h0CgleSG9tZUtpdCQSFQAEIhECBHZ3aHQKCV5BcHBsZVRWJBIJTm90U3luY2VkMisKGwAEIhcCBGFncnAKD15bMC05QS1aXXsxMH1cLhIMQXBwbGljYXRpb25zMsUBCrABAAISNAABChMABCIPAgVjbGFzcwoGXmdlbnAkChsABCIXAgRhZ3JwCg9eY29tLmFwcGxlLnNiZCQSPQABChMABCIPAgVjbGFzcwoGXmtleXMkCiQABCIgAgRhZ3JwChheY29tLmFwcGxlLnNlY3VyaXR5LnNvcyQSGQAEIhUCBHZ3aHQKDV5CYWNrdXBCYWdWMCQSHAAEIhgCBHZ3aHQKEF5pQ2xvdWRJZGVudGl0eSQSEFNlY3VyZU9iamVjdFN5bmMyYwpbAAISEgAEIg4CBHZ3aHQKBl5XaUZpJBJDAAEKEwAEIg8CBWNsYXNzCgZeZ2VucCQKEwAEIg8CBGFncnAKB15hcHBsZSQKFQAEIhECBHN2Y2UKCV5BaXJQb3J0JBIEV2lGaTLbAgrBAgACEhkABCIVAgR2d2h0Cg1eUENTQ2xvdWRLaXQkEhcABCITAgR2d2h0CgteUENTRXNjcm93JBIUAAQiEAIEdndodAoIXlBDU0ZERSQSGQAEIhUCBHZ3aHQKDV5QQ1NGZWxkc3BhciQSGQAEIhUCBHZ3aHQKDV5QQ1NNYWlsRHJvcCQSGgAEIhYCBHZ3aHQKDl5QQ1NNYXN0ZXJLZXkkEhYABCISAgR2d2h0CgpeUENTTm90ZXMkEhcABCITAgR2d2h0CgteUENTUGhvdG9zJBIYAAQiFAIEdndodAoMXlBDU1NoYXJpbmckEh0ABCIZAgR2d2h0ChFeUENTaUNsb3VkQmFja3VwJBIcAAQiGAIEdndodAoQXlBDU2lDbG91ZERyaXZlJBIZAAQiFQIEdndodAoNXlBDU2lNZXNzYWdlJBIVUHJvdGVjdGVkQ2xvdWRTdG9yYWdlMkAKKwAEIicCBGFncnAKH15jb20uYXBwbGUuc2FmYXJpLmNyZWRpdC1jYXJkcyQSEVNhZmFyaUNyZWRpdENhcmRzMjQKIQAEIh0CBGFncnAKFV5jb20uYXBwbGUuY2ZuZXR3b3JrJBIPU2FmYXJpUGFzc3dvcmRzMm0KXAACEh4ABCIaAgR2d2h0ChJeQWNjZXNzb3J5UGFpcmluZyQSGgAEIhYCBHZ3aHQKDl5OYW5vUmVnaXN0cnkkEhwABCIYAgR2d2h0ChBeV2F0Y2hNaWdyYXRpb24kEg1EZXZpY2VQYWlyaW5nMi0KIQAEIh0CBGFncnAKFV5jb20uYXBwbGUuY2ZuZXR3b3JrJBIIQmFja3N0b3A=", + plaintextPolicy: try! TPPolicyDocument(version: 3, + modelToCategory: [ + ["prefix": "iPhone", "category": "full"], + ["prefix": "iPad", "category": "full"], + ["prefix": "Mac", "category": "full"], + ["prefix": "iMac", "category": "full"], + ["prefix": "AppleTV", "category": "tv"], + ["prefix": "Watch", "category": "watch"], + ["prefix": "AudioAccessory", "category": "audio"], + ], + categoriesByView: [ + "AutoUnlock": ["full", "watch"], + "ApplePay": ["full", "watch"], + "Engram": ["full", "watch"], + "Health": ["full", "watch"], + "Home": ["full", "watch"], + "LimitedPeersAllowed": ["full", "watch", "tv", "audio"], + "Manatee": ["full", "watch"], + + "Applications": ["full", "watch"], + "SecureObjectSync": ["full", "watch"], + "WiFi": ["full", "watch", "tv", "audio"], + "ProtectedCloudStorage": ["full", "watch"], + "SafariCreditCards": ["full", "watch"], + "SafariPasswords": ["full", "watch"], + "DevicePairing": ["full", "watch"], + "Backstop": ["full", "watch"], + ], + introducersByCategory: [ + "full": ["full", "watch"], + "watch": ["full", "watch"], + "tv": ["full", "watch", "tv"], + "audio": ["full", "watch", "audio"], + ], + redactions: [:], + keyViewMapping: [ + TPPBPolicyKeyViewMapping(view: "ApplePay", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^ApplePay$")), + TPPBPolicyKeyViewMapping(view: "AutoUnlock", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AutoUnlock$")), + TPPBPolicyKeyViewMapping(view: "Engram", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Engram$")), + TPPBPolicyKeyViewMapping(view: "Health", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Health$")), + TPPBPolicyKeyViewMapping(view: "Home", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Home$")), + TPPBPolicyKeyViewMapping(view: "Manatee", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Manatee$")), + TPPBPolicyKeyViewMapping(view: "LimitedPeersAllowed", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^LimitedPeersAllowed$")), + + // These items will not be synced by Octagon + TPPBPolicyKeyViewMapping(view: "NotSynced", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^ContinuityUnlock$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^HomeKit$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AppleTV$"), + ])), + + TPPBPolicyKeyViewMapping(view: "Applications", matchingRule: + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^[0-9A-Z]{10}\\.")), + + TPPBPolicyKeyViewMapping(view: "SecureObjectSync", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^genp$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.sbd$"), + ]), + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^keys$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.security.sos$"), + ]), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^BackupBagV0$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^iCloudIdentity$"), + ])), + + TPPBPolicyKeyViewMapping(view: "WiFi", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^WiFi$"), + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^genp$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^apple$"), + TPDictionaryMatchingRule.fieldMatch("svce", fieldRegex: "^AirPort$"), + ]), + ])), + + TPPBPolicyKeyViewMapping(view: "ProtectedCloudStorage", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSCloudKit$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSEscrow$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSFDE$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSFeldspar$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSMailDrop$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSMasterKey$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSNotes$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSPhotos$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSSharing$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSiCloudBackup$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSiCloudDrive$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCSiMessage$"), + ])), + + TPPBPolicyKeyViewMapping(view: "SafariCreditCards", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.safari.credit-cards$")), + + TPPBPolicyKeyViewMapping(view: "SafariPasswords", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.cfnetwork$")), + + TPPBPolicyKeyViewMapping(view: "DevicePairing", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AccessoryPairing$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^NanoRegistry$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^WatchMigration$"), + ])), + + TPPBPolicyKeyViewMapping(view: "Backstop", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.cfnetwork$")), + ], + hashAlgo: .SHA256) + ), + RawPolicy(policyVersion: 4, + policyHash: "SHA256:Tjdu5QrWGvKWMx7k3VWFrEWSsBDPZAwCql9ybDkvFs8=", + policyData: "CAQSDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSCwoDTWFjEgRmdWxsEgwKBGlNYWMSBGZ1bGwSDQoHQXBwbGVUVhICdHYSDgoFV2F0Y2gSBXdhdGNoEhcKDkF1ZGlvQWNjZXNzb3J5EgVhdWRpbxoTCgRIb21lEgRmdWxsEgV3YXRjaBobCgxBcHBsaWNhdGlvbnMSBGZ1bGwSBXdhdGNoGh4KBFdpRmkSBGZ1bGwSBXdhdGNoEgJ0dhIFYXVkaW8aGQoKQXV0b1VubG9jaxIEZnVsbBIFd2F0Y2gaFwoIQXBwbGVQYXkSBGZ1bGwSBXdhdGNoGhUKBkhlYWx0aBIEZnVsbBIFd2F0Y2gaFgoHTWFuYXRlZRIEZnVsbBIFd2F0Y2gaLQoTTGltaXRlZFBlZXJzQWxsb3dlZBIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxokChVQcm90ZWN0ZWRDbG91ZFN0b3JhZ2USBGZ1bGwSBXdhdGNoGhgKCVBhc3N3b3JkcxIEZnVsbBIFd2F0Y2gaHAoNRGV2aWNlUGFpcmluZxIEZnVsbBIFd2F0Y2gaHwoQU2VjdXJlT2JqZWN0U3luYxIEZnVsbBIFd2F0Y2gaFQoGRW5ncmFtEgRmdWxsEgV3YXRjaBoaCgtDcmVkaXRDYXJkcxIEZnVsbBIFd2F0Y2giGwoFYXVkaW8SBGZ1bGwSBXdhdGNoEgVhdWRpbyITCgRmdWxsEgRmdWxsEgV3YXRjaCIUCgV3YXRjaBIEZnVsbBIFd2F0Y2giFQoCdHYSBGZ1bGwSBXdhdGNoEgJ0djIiChYABCISAgR2d2h0CgpeQXBwbGVQYXkkEghBcHBsZVBheTImChgABCIUAgR2d2h0CgxeQXV0b1VubG9jayQSCkF1dG9VbmxvY2syHgoUAAQiEAIEdndodAoIXkVuZ3JhbSQSBkVuZ3JhbTIeChQABCIQAgR2d2h0CgheSGVhbHRoJBIGSGVhbHRoMhoKEgAEIg4CBHZ3aHQKBl5Ib21lJBIESG9tZTIgChUABCIRAgR2d2h0CgleTWFuYXRlZSQSB01hbmF0ZWUyOAohAAQiHQIEdndodAoVXkxpbWl0ZWRQZWVyc0FsbG93ZWQkEhNMaW1pdGVkUGVlcnNBbGxvd2VkMl0KUAACEh4ABCIaAgR2d2h0ChJeQ29udGludWl0eVVubG9jayQSFQAEIhECBHZ3aHQKCV5Ib21lS2l0JBIVAAQiEQIEdndodAoJXkFwcGxlVFYkEglOb3RTeW5jZWQyKwobAAQiFwIEYWdycAoPXlswLTlBLVpdezEwfVwuEgxBcHBsaWNhdGlvbnMyxQEKsAEAAhI0AAEKEwAEIg8CBWNsYXNzCgZeZ2VucCQKGwAEIhcCBGFncnAKD15jb20uYXBwbGUuc2JkJBI9AAEKEwAEIg8CBWNsYXNzCgZea2V5cyQKJAAEIiACBGFncnAKGF5jb20uYXBwbGUuc2VjdXJpdHkuc29zJBIZAAQiFQIEdndodAoNXkJhY2t1cEJhZ1YwJBIcAAQiGAIEdndodAoQXmlDbG91ZElkZW50aXR5JBIQU2VjdXJlT2JqZWN0U3luYzJjClsAAhISAAQiDgIEdndodAoGXldpRmkkEkMAAQoTAAQiDwIFY2xhc3MKBl5nZW5wJAoTAAQiDwIEYWdycAoHXmFwcGxlJAoVAAQiEQIEc3ZjZQoJXkFpclBvcnQkEgRXaUZpMucCCs0CAAISGgAEIhYCBHZ3aHQKDl5QQ1MtQ2xvdWRLaXQkEhgABCIUAgR2d2h0CgxeUENTLUVzY3JvdyQSFQAEIhECBHZ3aHQKCV5QQ1MtRkRFJBIaAAQiFgIEdndodAoOXlBDUy1GZWxkc3BhciQSGgAEIhYCBHZ3aHQKDl5QQ1MtTWFpbERyb3AkEhsABCIXAgR2d2h0Cg9eUENTLU1hc3RlcktleSQSFwAEIhMCBHZ3aHQKC15QQ1MtTm90ZXMkEhgABCIUAgR2d2h0CgxeUENTLVBob3RvcyQSGQAEIhUCBHZ3aHQKDV5QQ1MtU2hhcmluZyQSHgAEIhoCBHZ3aHQKEl5QQ1MtaUNsb3VkQmFja3VwJBIdAAQiGQIEdndodAoRXlBDUy1pQ2xvdWREcml2ZSQSGgAEIhYCBHZ3aHQKDl5QQ1MtaU1lc3NhZ2UkEhVQcm90ZWN0ZWRDbG91ZFN0b3JhZ2UyOgorAAQiJwIEYWdycAofXmNvbS5hcHBsZS5zYWZhcmkuY3JlZGl0LWNhcmRzJBILQ3JlZGl0Q2FyZHMyLgohAAQiHQIEYWdycAoVXmNvbS5hcHBsZS5jZm5ldHdvcmskEglQYXNzd29yZHMybQpcAAISHgAEIhoCBHZ3aHQKEl5BY2Nlc3NvcnlQYWlyaW5nJBIaAAQiFgIEdndodAoOXk5hbm9SZWdpc3RyeSQSHAAEIhgCBHZ3aHQKEF5XYXRjaE1pZ3JhdGlvbiQSDURldmljZVBhaXJpbmc=", + plaintextPolicy: try! TPPolicyDocument(version: 4, + modelToCategory: [ + ["prefix": "iPhone", "category": "full"], + ["prefix": "iPad", "category": "full"], + ["prefix": "Mac", "category": "full"], + ["prefix": "iMac", "category": "full"], + ["prefix": "AppleTV", "category": "tv"], + ["prefix": "Watch", "category": "watch"], + ["prefix": "AudioAccessory", "category": "audio"], + ], + categoriesByView: [ + "AutoUnlock": ["full", "watch"], + "ApplePay": ["full", "watch"], + "Engram": ["full", "watch"], + "Health": ["full", "watch"], + "Home": ["full", "watch"], + "LimitedPeersAllowed": ["full", "watch", "tv", "audio"], + "Manatee": ["full", "watch"], + "Applications": ["full", "watch"], + "SecureObjectSync": ["full", "watch"], + "WiFi": ["full", "watch", "tv", "audio"], + "ProtectedCloudStorage": ["full", "watch"], + "CreditCards": ["full", "watch"], + "Passwords": ["full", "watch"], + "DevicePairing": ["full", "watch"], + ], + introducersByCategory: [ + "full": ["full", "watch"], + "watch": ["full", "watch"], + "tv": ["full", "watch", "tv"], + "audio": ["full", "watch", "audio"], + ], + redactions: [:], + keyViewMapping: [ + TPPBPolicyKeyViewMapping(view: "ApplePay", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^ApplePay$")), + TPPBPolicyKeyViewMapping(view: "AutoUnlock", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AutoUnlock$")), + TPPBPolicyKeyViewMapping(view: "Engram", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Engram$")), + TPPBPolicyKeyViewMapping(view: "Health", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Health$")), + TPPBPolicyKeyViewMapping(view: "Home", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Home$")), + TPPBPolicyKeyViewMapping(view: "Manatee", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Manatee$")), + TPPBPolicyKeyViewMapping(view: "LimitedPeersAllowed", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^LimitedPeersAllowed$")), + + // These items will not be synced by Octagon + TPPBPolicyKeyViewMapping(view: "NotSynced", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^ContinuityUnlock$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^HomeKit$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AppleTV$"), + ])), + + TPPBPolicyKeyViewMapping(view: "Applications", matchingRule: + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^[0-9A-Z]{10}\\.")), + + TPPBPolicyKeyViewMapping(view: "SecureObjectSync", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^genp$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.sbd$"), + ]), + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^keys$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.security.sos$"), + ]), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^BackupBagV0$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^iCloudIdentity$"), + ])), + + TPPBPolicyKeyViewMapping(view: "WiFi", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^WiFi$"), + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^genp$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^apple$"), + TPDictionaryMatchingRule.fieldMatch("svce", fieldRegex: "^AirPort$"), + ]), + ])), + + TPPBPolicyKeyViewMapping(view: "ProtectedCloudStorage", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-CloudKit$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Escrow$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-FDE$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Feldspar$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-MailDrop$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-MasterKey$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Notes$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Photos$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Sharing$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-iCloudBackup$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-iCloudDrive$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-iMessage$"), + ])), + + TPPBPolicyKeyViewMapping(view: "CreditCards", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.safari.credit-cards$")), + + TPPBPolicyKeyViewMapping(view: "Passwords", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.cfnetwork$")), + + TPPBPolicyKeyViewMapping(view: "DevicePairing", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AccessoryPairing$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^NanoRegistry$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^WatchMigration$"), + ])), + ], + hashAlgo: .SHA256) + ), + + RawPolicy(policyVersion: 5, + policyHash: "SHA256:O/ECQlWhvNlLmlDNh2+nal/yekUC87bXpV3k+6kznSo=", + policyData: "CAUSDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSDAoEaVBvZBIEZnVsbBILCgNNYWMSBGZ1bGwSDAoEaU1hYxIEZnVsbBINCgdBcHBsZVRWEgJ0dhIOCgVXYXRjaBIFd2F0Y2gSFwoOQXVkaW9BY2Nlc3NvcnkSBWF1ZGlvGhsKDEFwcGxpY2F0aW9ucxIEZnVsbBIFd2F0Y2gaHwoQU2VjdXJlT2JqZWN0U3luYxIEZnVsbBIFd2F0Y2gaHAoNRGV2aWNlUGFpcmluZxIEZnVsbBIFd2F0Y2gaGgoLQ3JlZGl0Q2FyZHMSBGZ1bGwSBXdhdGNoGhUKBkhlYWx0aBIEZnVsbBIFd2F0Y2gaLQoTTGltaXRlZFBlZXJzQWxsb3dlZBIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxokChVQcm90ZWN0ZWRDbG91ZFN0b3JhZ2USBGZ1bGwSBXdhdGNoGhcKCEFwcGxlUGF5EgRmdWxsEgV3YXRjaBoZCgpBdXRvVW5sb2NrEgRmdWxsEgV3YXRjaBoWCgdNYW5hdGVlEgRmdWxsEgV3YXRjaBoYCglQYXNzd29yZHMSBGZ1bGwSBXdhdGNoGhUKBkVuZ3JhbRIEZnVsbBIFd2F0Y2gaHgoEV2lGaRIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxoTCgRIb21lEgRmdWxsEgV3YXRjaCIbCgVhdWRpbxIEZnVsbBIFd2F0Y2gSBWF1ZGlvIhMKBGZ1bGwSBGZ1bGwSBXdhdGNoIhUKAnR2EgRmdWxsEgV3YXRjaBICdHYiFAoFd2F0Y2gSBGZ1bGwSBXdhdGNoMiIKFgAEIhICBHZ3aHQKCl5BcHBsZVBheSQSCEFwcGxlUGF5MiYKGAAEIhQCBHZ3aHQKDF5BdXRvVW5sb2NrJBIKQXV0b1VubG9jazIeChQABCIQAgR2d2h0CgheRW5ncmFtJBIGRW5ncmFtMh4KFAAEIhACBHZ3aHQKCF5IZWFsdGgkEgZIZWFsdGgyGgoSAAQiDgIEdndodAoGXkhvbWUkEgRIb21lMiAKFQAEIhECBHZ3aHQKCV5NYW5hdGVlJBIHTWFuYXRlZTI4CiEABCIdAgR2d2h0ChVeTGltaXRlZFBlZXJzQWxsb3dlZCQSE0xpbWl0ZWRQZWVyc0FsbG93ZWQyXQpQAAISHgAEIhoCBHZ3aHQKEl5Db250aW51aXR5VW5sb2NrJBIVAAQiEQIEdndodAoJXkhvbWVLaXQkEhUABCIRAgR2d2h0CgleQXBwbGVUViQSCU5vdFN5bmNlZDIrChsABCIXAgRhZ3JwCg9eWzAtOUEtWl17MTB9XC4SDEFwcGxpY2F0aW9uczLFAQqwAQACEjQAAQoTAAQiDwIFY2xhc3MKBl5nZW5wJAobAAQiFwIEYWdycAoPXmNvbS5hcHBsZS5zYmQkEj0AAQoTAAQiDwIFY2xhc3MKBl5rZXlzJAokAAQiIAIEYWdycAoYXmNvbS5hcHBsZS5zZWN1cml0eS5zb3MkEhkABCIVAgR2d2h0Cg1eQmFja3VwQmFnVjAkEhwABCIYAgR2d2h0ChBeaUNsb3VkSWRlbnRpdHkkEhBTZWN1cmVPYmplY3RTeW5jMmMKWwACEhIABCIOAgR2d2h0CgZeV2lGaSQSQwABChMABCIPAgVjbGFzcwoGXmdlbnAkChMABCIPAgRhZ3JwCgdeYXBwbGUkChUABCIRAgRzdmNlCgleQWlyUG9ydCQSBFdpRmkynQMKgwMAAhIYAAQiFAIEdndodAoMXlBDUy1CYWNrdXAkEhoABCIWAgR2d2h0Cg5eUENTLUNsb3VkS2l0JBIYAAQiFAIEdndodAoMXlBDUy1Fc2Nyb3ckEhUABCIRAgR2d2h0CgleUENTLUZERSQSGgAEIhYCBHZ3aHQKDl5QQ1MtRmVsZHNwYXIkEhoABCIWAgR2d2h0Cg5eUENTLU1haWxEcm9wJBIaAAQiFgIEdndodAoOXlBDUy1NYWlsZHJvcCQSGwAEIhcCBHZ3aHQKD15QQ1MtTWFzdGVyS2V5JBIXAAQiEwIEdndodAoLXlBDUy1Ob3RlcyQSGAAEIhQCBHZ3aHQKDF5QQ1MtUGhvdG9zJBIZAAQiFQIEdndodAoNXlBDUy1TaGFyaW5nJBIeAAQiGgIEdndodAoSXlBDUy1pQ2xvdWRCYWNrdXAkEh0ABCIZAgR2d2h0ChFeUENTLWlDbG91ZERyaXZlJBIaAAQiFgIEdndodAoOXlBDUy1pTWVzc2FnZSQSFVByb3RlY3RlZENsb3VkU3RvcmFnZTI6CisABCInAgRhZ3JwCh9eY29tLmFwcGxlLnNhZmFyaS5jcmVkaXQtY2FyZHMkEgtDcmVkaXRDYXJkczIuCiEABCIdAgRhZ3JwChVeY29tLmFwcGxlLmNmbmV0d29yayQSCVBhc3N3b3JkczJtClwAAhIeAAQiGgIEdndodAoSXkFjY2Vzc29yeVBhaXJpbmckEhoABCIWAgR2d2h0Cg5eTmFub1JlZ2lzdHJ5JBIcAAQiGAIEdndodAoQXldhdGNoTWlncmF0aW9uJBINRGV2aWNlUGFpcmluZzIOCgIABhIIQmFja3N0b3A=", + plaintextPolicy: try! TPPolicyDocument(version: 5, + modelToCategory: [ + ["prefix": "iPhone", "category": "full"], + ["prefix": "iPad", "category": "full"], + ["prefix": "iPod", "category": "full"], + ["prefix": "Mac", "category": "full"], + ["prefix": "iMac", "category": "full"], + ["prefix": "AppleTV", "category": "tv"], + ["prefix": "Watch", "category": "watch"], + ["prefix": "AudioAccessory", "category": "audio"], + ], + categoriesByView: [ + "AutoUnlock": ["full", "watch"], + "ApplePay": ["full", "watch"], + "Engram": ["full", "watch"], + "Health": ["full", "watch"], + "Home": ["full", "watch"], + "LimitedPeersAllowed": ["full", "watch", "tv", "audio"], + "Manatee": ["full", "watch"], + "Applications": ["full", "watch"], + "SecureObjectSync": ["full", "watch"], + "WiFi": ["full", "watch", "tv", "audio"], + "ProtectedCloudStorage": ["full", "watch"], + "CreditCards": ["full", "watch"], + "Passwords": ["full", "watch"], + "DevicePairing": ["full", "watch"], + ], + introducersByCategory: [ + "full": ["full", "watch"], + "watch": ["full", "watch"], + "tv": ["full", "watch", "tv"], + "audio": ["full", "watch", "audio"], + ], + redactions: [:], + keyViewMapping: [ + TPPBPolicyKeyViewMapping(view: "ApplePay", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^ApplePay$")), + TPPBPolicyKeyViewMapping(view: "AutoUnlock", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AutoUnlock$")), + TPPBPolicyKeyViewMapping(view: "Engram", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Engram$")), + TPPBPolicyKeyViewMapping(view: "Health", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Health$")), + TPPBPolicyKeyViewMapping(view: "Home", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Home$")), + TPPBPolicyKeyViewMapping(view: "Manatee", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^Manatee$")), + TPPBPolicyKeyViewMapping(view: "LimitedPeersAllowed", matchingRule: TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^LimitedPeersAllowed$")), + + // These items will not be synced by Octagon + TPPBPolicyKeyViewMapping(view: "NotSynced", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^ContinuityUnlock$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^HomeKit$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AppleTV$"), + ])), + + TPPBPolicyKeyViewMapping(view: "Applications", matchingRule: + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^[0-9A-Z]{10}\\.")), + + TPPBPolicyKeyViewMapping(view: "SecureObjectSync", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^genp$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.sbd$"), + ]), + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^keys$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.security.sos$"), + ]), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^BackupBagV0$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^iCloudIdentity$"), + ])), + + TPPBPolicyKeyViewMapping(view: "WiFi", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^WiFi$"), + TPDictionaryMatchingRule.andMatch([ + TPDictionaryMatchingRule.fieldMatch("class", fieldRegex: "^genp$"), + TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^apple$"), + TPDictionaryMatchingRule.fieldMatch("svce", fieldRegex: "^AirPort$"), + ]), + ])), + + TPPBPolicyKeyViewMapping(view: "ProtectedCloudStorage", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Backup$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-CloudKit$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Escrow$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-FDE$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Feldspar$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-MailDrop$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Maildrop$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-MasterKey$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Notes$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Photos$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-Sharing$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-iCloudBackup$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-iCloudDrive$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^PCS-iMessage$"), + ])), + + TPPBPolicyKeyViewMapping(view: "CreditCards", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.safari.credit-cards$")), + + TPPBPolicyKeyViewMapping(view: "Passwords", + matchingRule: TPDictionaryMatchingRule.fieldMatch("agrp", fieldRegex: "^com.apple.cfnetwork$")), + + TPPBPolicyKeyViewMapping(view: "DevicePairing", matchingRule: + TPDictionaryMatchingRule.orMatch([ + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^AccessoryPairing$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^NanoRegistry$"), + TPDictionaryMatchingRule.fieldMatch("vwht", fieldRegex: "^WatchMigration$"), + ])), + + TPPBPolicyKeyViewMapping(view: "Backstop", matchingRule: + TPDictionaryMatchingRule.trueMatch()), + ], + hashAlgo: .SHA256) + ), + ] + + assert(rawPolicies.filter { prevailingPolicyVersion == $0.policyVersion }.count == 1) + + return rawPolicies.map { raw in + let data = Data(base64Encoded: raw.policyData)! + let doc = TPPolicyDocument.policyDoc(withHash: raw.policyHash, data: data)! + assert(doc.policyVersion == raw.policyVersion) + if raw.policyVersion == prevailingPolicyVersion { + assert(prevailingPolicyHash == raw.policyHash) + } + assert(doc.isEqual(to: raw.plaintextPolicy)) + return doc + } +} diff --git a/keychain/TrustedPeersHelper/RecoveryKey/RecoverKeySet.swift b/keychain/TrustedPeersHelper/RecoveryKey/RecoverKeySet.swift new file mode 100644 index 00000000..2ed38843 --- /dev/null +++ b/keychain/TrustedPeersHelper/RecoveryKey/RecoverKeySet.swift @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2019 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 Foundation +import SecurityFoundation + +let OT_RECOVERY_SIGNING_HKDF_SIZE = 56 +let OT_RECOVERY_ENCRYPTION_HKDF_SIZE = 56 + +enum recoveryKeyType: Int { + case kOTRecoveryKeySigning = 1 + case kOTRecoveryKeyEncryption = 2 +} + +class RecoveryKeySet: NSObject { + public var encryptionKey: _SFECKeyPair + public var signingKey: _SFECKeyPair + + public var secret: Data + public var recoverySalt: String + + public init (secret: Data, recoverySalt: String) throws { + self.secret = secret + self.recoverySalt = recoverySalt + + let encryptionKeyData = try RecoveryKeySet.generateRecoveryKey(keyType: recoveryKeyType.kOTRecoveryKeyEncryption, masterSecret: secret, recoverySalt: recoverySalt) + self.encryptionKey = _SFECKeyPair.init(secKey: try RecoveryKeySet.createSecKey(keyData: encryptionKeyData)) + + let signingKeyData = try RecoveryKeySet.generateRecoveryKey(keyType: recoveryKeyType.kOTRecoveryKeySigning, masterSecret: secret, recoverySalt: recoverySalt) + self.signingKey = _SFECKeyPair.init(secKey: try RecoveryKeySet.createSecKey(keyData: signingKeyData)) + + let RecoverySigningPubKeyHash = try RecoveryKeySet.hashRecoveryedSigningPublicKey(keyData: self.signingKey.publicKey().spki()) + _ = try RecoveryKeySet.storeRecoveryedSigningKeyPair(keyData: self.signingKey.keyData, label: RecoverySigningPubKeyHash) + _ = try RecoveryKeySet.storeRecoveryedEncryptionKeyPair(keyData: self.encryptionKey.keyData, label: RecoverySigningPubKeyHash) + } + + class func generateMasterKeyString() -> (String?) { + return SecRKCreateRecoveryKeyString(nil) as String + } + + class func generateRecoveryKey(keyType: recoveryKeyType, masterSecret: Data, recoverySalt: String) throws -> (Data) { + var keyLength: Int + var info: Data + var infoLength: Int + var derivedKey: Data + var finalKey = Data() + + switch keyType { + case recoveryKeyType.kOTRecoveryKeyEncryption: + keyLength = OT_RECOVERY_ENCRYPTION_HKDF_SIZE + + let infoString = Array("Recovery Encryption Private Key".utf8) + info = Data(bytes: infoString, count: infoString.count) + infoLength = info.count + + break + case recoveryKeyType.kOTRecoveryKeySigning: + keyLength = OT_RECOVERY_SIGNING_HKDF_SIZE + + let infoString = Array("Recovery Signing Private Key".utf8) + info = Data(bytes: infoString, count: infoString.count) + infoLength = info.count + + break + } + + guard let cp = ccec_cp_384() else { + throw RecoveryKeySetError.keyGeneration + } + var status: Int32 = 0 + + let fullKey = TPHObjectiveC.ccec384Context() + defer { TPHObjectiveC.contextFree(fullKey) } + + derivedKey = Data(count: keyLength) + + var masterSecretMutable = masterSecret + let masterSecretLength = masterSecret.count + let derivedKeySize = derivedKey.count + + let bottleSaltData = Data(bytes: Array(recoverySalt.utf8), count: recoverySalt.utf8.count) + + try derivedKey.withUnsafeMutableBytes { (derivedKeyBytes: UnsafeMutablePointer) throws ->Void in + try masterSecretMutable.withUnsafeMutableBytes { (masterSecretBytes: UnsafeMutablePointer) throws ->Void in + try bottleSaltData.withUnsafeBytes { (bottleSaltBytes: UnsafePointer) throws -> Void in + try info.withUnsafeBytes { (infoBytes: UnsafePointer) throws -> Void in + status = cchkdf(ccsha384_di(), + masterSecretLength, masterSecretBytes, + bottleSaltData.count, bottleSaltBytes, + infoLength, infoBytes, + keyLength, derivedKeyBytes) + if status != 0 { + throw RecoveryKeySetError.corecryptoKeyGeneration(corecryptoError: status) + } + + if(keyType == recoveryKeyType.kOTRecoveryKeyEncryption || keyType == recoveryKeyType.kOTRecoveryKeySigning) { + status = ccec_generate_key_deterministic(cp, + derivedKeySize, derivedKeyBytes, + ccDRBGGetRngState(), + UInt32(CCEC_GENKEY_DETERMINISTIC_FIPS), + fullKey) + + guard status == 0 else { + throw RecoveryKeySetError.corecryptoKeyGeneration(corecryptoError: status) + } + + let space = ccec_x963_export_size(1, ccec_ctx_pub(fullKey)) + var key = Data(count: space) + key.withUnsafeMutableBytes { (bytes: UnsafeMutablePointer) -> Void in + ccec_x963_export(1, bytes, fullKey) + } + finalKey = Data(key) + } + } + } + } + } + return finalKey + } + + class func createSecKey(keyData: Data) throws -> (SecKey) { + let keyAttributes = [kSecAttrKeyClass: kSecAttrKeyClassPrivate, kSecAttrKeyType: kSecAttrKeyTypeEC] + + guard let key = SecKeyCreateWithData(keyData as CFData, keyAttributes as CFDictionary, nil) else { + throw RecoveryKeySetError.keyGeneration + } + + return key + } + + class func setKeyMaterialInKeychain(query: Dictionary) throws -> (Bool) { + var result = false + + var results: CFTypeRef? + var status = SecItemAdd(query as CFDictionary, &results) + + if status == errSecSuccess { + result = true + } else if status == errSecDuplicateItem { + var updateQuery: Dictionary = query + updateQuery[kSecClass] = nil + + status = SecItemUpdate(query as CFDictionary, updateQuery as CFDictionary) + + if status != errSecSuccess { + throw RecoveryKeySetError.failedToSaveToKeychain(errorCode: status) + } else { + result = true + } + } else { + throw RecoveryKeySetError.failedToSaveToKeychain(errorCode: status) + } + + return result + } + + class func hashRecoveryedSigningPublicKey(keyData: Data) throws -> (String) { + let di = ccsha384_di() + var result = Data(count: TPHObjectiveC.ccsha384_diSize()) + + let derivedKeySize = keyData.count + var keyDataMutable = keyData + result.withUnsafeMutableBytes {(resultBytes: UnsafeMutablePointer) -> Void in + keyDataMutable.withUnsafeMutableBytes {(keyDataBytes: UnsafeMutablePointer) -> Void in + ccdigest(di, derivedKeySize, keyDataBytes, resultBytes) + } + } + let hash = result.base64EncodedString(options: []) + + return hash + } + + class func storeRecoveryedEncryptionKeyPair(keyData: Data, label: String) throws -> (Bool) { + + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrSynchronizable: kCFBooleanFalse, + kSecAttrLabel: label, + kSecAttrApplicationLabel: String(format: "Recoveryed Encryption Key-%@", NSUUID().uuidString), + kSecValueData: keyData, + ] + return try RecoveryKeySet.setKeyMaterialInKeychain(query: query) + } + + class func storeRecoveryedSigningKeyPair(keyData: Data, label: String) throws -> (Bool) { + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessible: kSecAttrAccessibleWhenUnlocked, + kSecUseDataProtectionKeychain: true, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrSynchronizable: kCFBooleanFalse, + kSecAttrApplicationLabel: String(format: "Recoveryed Signing Key-%@", NSUUID().uuidString), + kSecAttrLabel: label, + kSecValueData: keyData, + ] + return try RecoveryKeySet.setKeyMaterialInKeychain(query: query) + } + + class func retrieveRecoveryKeysFromKeychain(label: String) throws -> [Dictionary ]? { + var keySet: [Dictionary]? + + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrLabel: label, + kSecReturnAttributes: true, + kSecReturnData: true, + kSecAttrSynchronizable: kCFBooleanFalse, + kSecMatchLimit: kSecMatchLimitAll, + ] + + var result: CFTypeRef? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status != errSecSuccess || result == nil { + throw RecoveryKeySetError.itemDoesNotExist + } + + if result != nil { + if let dictionaryArray = result as? [Dictionary] { + keySet = dictionaryArray + } else { + if let dictionary = result as? Dictionary { + keySet = [dictionary] + } else { + keySet = nil + } + } + } + return keySet + } + + class func findRecoveryKeysForLabel(label: String) throws -> (_SFECKeyPair?, _SFECKeyPair?) { + var signingKey: _SFECKeyPair? + var encryptionKey: _SFECKeyPair? + + let keySet = try retrieveRecoveryKeysFromKeychain(label: label) + if keySet == nil { + throw RecoveryKeySetError.itemDoesNotExist + } + for item in keySet! { + let keyTypeData = item[kSecAttrApplicationLabel as CFString] as! Data + let keyType = String(data: keyTypeData, encoding: .utf8)! + + if keyType.range(of: "Encryption") != nil { + let keyData = item[kSecValueData as CFString] as! Data + let encryptionSecKey = try RecoveryKeySet.createSecKey(keyData: keyData) + encryptionKey = _SFECKeyPair.init(secKey: encryptionSecKey) + } else if keyType.range(of: "Signing") != nil { + let keyData = item[kSecValueData as CFString] as! Data + let signingSecKey = try RecoveryKeySet.createSecKey(keyData: keyData) + signingKey = _SFECKeyPair.init(secKey: signingSecKey) + } else { + throw RecoveryKeySetError.unsupportedKeyType(keyType: keyType) + } + } + + return (signingKey, encryptionKey) + } +} + +enum RecoveryKeySetError: Error { + case keyGeneration + case itemDoesNotExist + case failedToSaveToKeychain(errorCode: OSStatus) + case unsupportedKeyType(keyType: String) + case corecryptoKeyGeneration(corecryptoError: Int32) +} + +extension RecoveryKeySetError: LocalizedError { + public var errorDescription: String? { + switch self { + case .keyGeneration: + return "Key generation failed" + case .itemDoesNotExist: + return "Item does not exist" + case .failedToSaveToKeychain(errorCode: let osError): + return "Failed to save item to keychain: \(osError)" + case .unsupportedKeyType(keyType: let keyType): + return "Unsupported Key Type \(keyType)" + case .corecryptoKeyGeneration(corecryptoError: let corecryptoError): + return "Key generation crypto failed \(corecryptoError)" + } + } +} + +extension RecoveryKeySetError: CustomNSError { + + public static var errorDomain: String { + return "com.apple.security.trustedpeers.RecoveryKeySetError" + } + + public var errorCode: Int { + switch self { + case .keyGeneration: + return 1 + case .itemDoesNotExist: + return 2 + case .failedToSaveToKeychain: + return 3 + case .unsupportedKeyType: + return 4 + case .corecryptoKeyGeneration: + return 5 + } + } + + public var errorUserInfo: [String: Any] { + var userInfo: [String: Any] = [:] + if let desc = self.errorDescription { + userInfo[NSLocalizedDescriptionKey] = desc + } + switch self { + case .failedToSaveToKeychain(errorCode: let osError): + userInfo[NSUnderlyingErrorKey] = NSError.init(domain: NSOSStatusErrorDomain, code: Int(osError), userInfo: nil) + case .corecryptoKeyGeneration(corecryptoError: let corecryptoError): + userInfo[NSUnderlyingErrorKey] = NSError.init(domain: "corecrypto", code: Int(corecryptoError), userInfo: nil) + default: + break + } + return userInfo + } +} diff --git a/keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift b/keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift new file mode 100644 index 00000000..35cd9b3f --- /dev/null +++ b/keychain/TrustedPeersHelper/RecoveryKey/RecoveryKey.swift @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019 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 Foundation +import SecurityFoundation + +class RecoveryKey: NSObject { + public var recoveryKeys: RecoveryKeySet + public var secret: Data + + public var peerKeys: OctagonSelfPeerKeys + + public init(recoveryKeyString: String, recoverySalt: String) throws { + self.secret = Data(bytes: Array(recoveryKeyString.utf8), count: recoveryKeyString.utf8.count) + self.recoveryKeys = try RecoveryKeySet(secret: self.secret, recoverySalt: recoverySalt) + + let hash = try RecoveryKeySet.hashRecoveryedSigningPublicKey(keyData: self.recoveryKeys.signingKey.publicKey.keyData) + let peerID = "RK-" + hash + + try self.peerKeys = OctagonSelfPeerKeys(peerID: peerID, signingKey: self.recoveryKeys.signingKey, encryptionKey: self.recoveryKeys.encryptionKey) + } +} + +extension RecoveryKey { + enum Error: Swift.Error { + case OTErrorDeserializationFailure + case OTErrorDecryptionFailure + case OTErrorKeyInstantiation + case OTErrorKeyMismatch + case OTErrorRecoveryCreation + case OTErrorAuthCipherTextCreation + case OTErrorPrivateKeyCreation + case OTErrorRecoveryKeyCreation + case OTErrorEntropyCreation + case OTErrorEntropyKeyMismatch + } +} + +extension RecoveryKey.Error: LocalizedError { + public var errorDescription: String? { + switch self { + case .OTErrorDeserializationFailure: + return "Failed to deserialize Recovery peer" + case .OTErrorDecryptionFailure: + return "could not decrypt Recovery contents" + case .OTErrorKeyInstantiation: + return "Failed to instantiate octagon peer keys" + case .OTErrorKeyMismatch: + return "public and private peer signing keys do not match" + case .OTErrorRecoveryCreation: + return "failed to create Recovery" + case .OTErrorAuthCipherTextCreation: + return "failed to create authenticated ciphertext" + case .OTErrorPrivateKeyCreation: + return "failed to create private key" + case .OTErrorRecoveryKeyCreation: + return "failed to create recovery keys" + case .OTErrorEntropyCreation: + return "failed to create entropy" + case .OTErrorEntropyKeyMismatch: + return "keys generated by the entropy+salt do not match the Recovery contents" + } + } +} diff --git a/keychain/TrustedPeersHelper/SetValueTransformer.swift b/keychain/TrustedPeersHelper/SetValueTransformer.swift new file mode 100644 index 00000000..ced7dd28 --- /dev/null +++ b/keychain/TrustedPeersHelper/SetValueTransformer.swift @@ -0,0 +1,38 @@ +import CoreData +import Foundation + +@objc(SetValueTransformer) +class SetValueTransformer: ValueTransformer { + override class func transformedValueClass() -> AnyClass { + return NSData.self + } + + override class func allowsReverseTransformation() -> Bool { + return true + } + + override func transformedValue(_ value: Any?) -> Any? { + do { + guard let value = value else { return nil } + return try NSKeyedArchiver.archivedData(withRootObject: value, requiringSecureCoding: true) + } catch { + os_log("Failed to serialize a Set: %@", log: tplogDebug, type: .default, error as CVarArg) + return nil + } + } + + override func reverseTransformedValue(_ value: Any?) -> Any? { + do { + guard let dataOp = value as? Data? else { return nil } + guard let data = dataOp else { return nil } + + let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data) + return unarchiver.decodeObject(of: [NSSet.self], forKey:NSKeyedArchiveRootObjectKey) + } catch { + os_log("Failed to deserialize a purported Set: %@", log: tplogDebug, type: .default, error as CVarArg) + return nil + } + } + + static let name = NSValueTransformerName(rawValue: "SetValueTransformer") +} diff --git a/keychain/TrustedPeersHelper/TPHObjcTranslation.h b/keychain/TrustedPeersHelper/TPHObjcTranslation.h new file mode 100644 index 00000000..5aaff695 --- /dev/null +++ b/keychain/TrustedPeersHelper/TPHObjcTranslation.h @@ -0,0 +1,24 @@ + +#ifndef TPHObjcTranslation_h +#define TPHObjcTranslation_h + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +// This file is for translation of C/Obj-C APIs into swift-friendly things + +@interface TPHObjectiveC : NSObject + ++ (SFECKeyPair* _Nullable)fetchKeyPairWithPrivateKeyPersistentRef:(NSData*)persistentRef error:(NSError**)error; ++ (ccec_full_ctx_t)ccec384Context; ++ (size_t) ccsha384_diSize; ++ (void)contextFree:(void*) context; ++ (SFAESKeyBitSize)aes256BitSize; ++ (NSString*)digestUsingSha384:(NSData*) data; +@end + +NS_ASSUME_NONNULL_END + +#endif /* TPHObjcTranslation_h */ diff --git a/keychain/TrustedPeersHelper/TPHObjcTranslation.m b/keychain/TrustedPeersHelper/TPHObjcTranslation.m new file mode 100644 index 00000000..5254fe76 --- /dev/null +++ b/keychain/TrustedPeersHelper/TPHObjcTranslation.m @@ -0,0 +1,61 @@ +#import "keychain/TrustedPeersHelper/TPHObjcTranslation.h" + +#import +#import + +#import +#import +#import +#import + +@implementation TPHObjectiveC : NSObject + ++ (SFECKeyPair* _Nullable)fetchKeyPairWithPrivateKeyPersistentRef:(NSData *)persistentRef error:(NSError**)error +{ + SecKeyRef seckey = NULL; + OSStatus status = SecKeyFindWithPersistentRef((__bridge CFDataRef)persistentRef, &seckey); + + if(status) { + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + userInfo:nil]; + } + return nil; + } + + return [[SFECKeyPair alloc] initWithSecKey: seckey]; +} + ++ (ccec_full_ctx_t)ccec384Context +{ + ccec_const_cp_t cp = ccec_cp_384(); + size_t size = ccec_full_ctx_size(ccec_ccn_size(cp)); + ccec_full_ctx_t heapContext = (ccec_full_ctx_t)malloc(size); + ccec_ctx_init(cp, heapContext); + return heapContext; +} + ++ (void)contextFree:(void*) context +{ + free(context); +} + ++ (size_t) ccsha384_diSize{ + return ccsha384_di()->output_size; +} + ++ (SFAESKeyBitSize)aes256BitSize{ + return SFAESKeyBitSize256; +} + ++ (NSString*)digestUsingSha384:(NSData*) data { + const struct ccdigest_info *di = ccsha384_di(); + NSMutableData* result = [[NSMutableData alloc] initWithLength:ccsha384_di()->output_size]; + + ccdigest(di, [data length], [data bytes], [result mutableBytes]); + + return [result base64EncodedStringWithOptions:0]; +} + +@end diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h b/keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h new file mode 100644 index 00000000..d46c031d --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h @@ -0,0 +1,57 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import +#import +#import +#import + +#import +#import +#import + +#import "utilities/SecFileLocations.h" +#import "utilities/SecTapToRadar.h" + +#import +#import +#import +#import +#import +#import +#import +#import + +#import +#import + +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/TrustedPeersHelper/TPHObjcTranslation.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTBottleContents.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTBottle.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTPrivateKey.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTAuthenticatedCiphertext.h" +#import "keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.h" +#import "keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.h" + +#import "keychain/ckks/CKKSKeychainBackedKey.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSTLKShare.h" + +#import +#include +#include +#import +#import + +#import +#import +#import + +#import +#import +#include diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelper-entitlements.plist b/keychain/TrustedPeersHelper/TrustedPeersHelper-entitlements.plist new file mode 100644 index 00000000..555752c4 --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelper-entitlements.plist @@ -0,0 +1,39 @@ + + + + + application-identifier + com.apple.TrustedPeersHelper + com.apple.application-identifier + com.apple.TrustedPeersHelper + com.apple.developer.aps-environment + serverPreferred + aps-environment + serverPreferred + com.apple.developer.icloud-container-environment + Production + com.apple.developer.icloud-services + + CloudKit + + com.apple.private.appleaccount.app-hidden-from-icloud-settings + + com.apple.private.cloudkit.allowUnverifiedAccount + + com.apple.private.cloudkit.buddyAccess + + com.apple.private.cloudkit.systemService + + com.apple.private.cloudkit.supportservice + + com.apple.private.cloudkit.prefix + com.apple.security.cuttlefish + keychain-access-groups + + com.apple.security.sos + com.apple.security.ckks + com.apple.security.octagon + com.apple.security.egoIdentities + + + diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/.xccurrentversion b/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/.xccurrentversion new file mode 100644 index 00000000..d9c22648 --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/.xccurrentversion @@ -0,0 +1,8 @@ + + + + + _XCCurrentVersionName + TrustedPeersHelper_2.xcdatamodel + + diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper.xcdatamodel/contents b/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper.xcdatamodel/contents new file mode 100644 index 00000000..0b236d67 --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper.xcdatamodel/contents @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper_2.xcdatamodel/contents b/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper_2.xcdatamodel/contents new file mode 100644 index 00000000..34e02638 --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelper.xcdatamodeld/TrustedPeersHelper_2.xcdatamodel/contents @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h b/keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h new file mode 100644 index 00000000..c313182d --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h @@ -0,0 +1,348 @@ +/* + * 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 "keychain/ckks/CKKSKeychainBackedKey.h" +#import "keychain/ckks/CKKSTLKShare.h" + +NS_ASSUME_NONNULL_BEGIN + +// Any client hoping to use the TrustedPeersHelperProtocol should have an entitlement +// 'com.apple.private.trustedpeershelper.client' set to boolean YES. + +@interface TrustedPeersHelperPeerState : NSObject +@property (nullable) NSString* peerID; +@property BOOL identityIsPreapproved; +@property TPPeerStatus peerStatus; +@property BOOL memberChanges; +@property BOOL unknownMachineIDsPresent; + +- (instancetype)initWithPeerID:(NSString* _Nullable)peerID + isPreapproved:(BOOL)isPreapproved + status:(TPPeerStatus)peerStatus + memberChanges:(BOOL)memberChanges + unknownMachineIDs:(BOOL)unknownMachineIDs; +@end +@interface TrustedPeersHelperPeer : NSObject +@property (nullable) NSString* peerID; +@property (nullable) NSData* signingSPKI; +@property (nullable) NSData* encryptionSPKI; +@property (nullable) NSSet* viewList; + +- (instancetype)initWithPeerID:(NSString*)peerID + signingSPKI:(NSData*)signingSPKI + encryptionSPKI:(NSData*)encryptionSPKI + viewList:(NSSet*)viewList; +@end + +@interface TrustedPeersHelperEgoPeerStatus : NSObject +@property TPPeerStatus egoStatus; +@property NSString* _Nullable egoPeerID; +@property (assign) uint64_t numberOfPeersInOctagon; +@property NSDictionary* peerCountsByModelID; +@property BOOL isExcluded; +@property BOOL isLocked; + +- (instancetype)initWithEgoPeerID:(NSString* _Nullable)egoPeerID + status:(TPPeerStatus)egoStatus + peerCountsByModelID:(NSDictionary*)peerCountsByModelID + isExcluded:(BOOL)isExcluded + isLocked:(BOOL)isLocked; + +@end + +// This protocol describes the interface of the TrustedPeersHelper XPC service. +@protocol TrustedPeersHelperProtocol + +// This is used by a unit test which exercises the XPC-service plumbing. +- (void)pingWithReply:(void (^)(void))reply; + +- (void)dumpWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply; + +- (void)departByDistrustingSelfWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSError * _Nullable))reply; + +- (void)distrustPeerIDsWithContainer:(NSString *)container + context:(NSString *)context + peerIDs:(NSSet*)peerIDs + reply:(void (^)(NSError * _Nullable))reply; + +- (void)trustStatusWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(TrustedPeersHelperEgoPeerStatus *status, + NSError* _Nullable error))reply; + +- (void)resetWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)localResetWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSError * _Nullable error))reply; + +// The following three machine ID list manipulation functions do not attempt to apply the results to the model +// If you'd like that to occur, please call update() + +// TODO: how should we communicate TLK rolling when the update() call will remove a peer? +// Octagon: must be able to roll TLKs when a peer departs due to machine ID list + +// listDifferences: False if the allowedMachineIDs list passed in exactly matches the previous state, +// True if there were any differences +- (void)setAllowedMachineIDsWithContainer:(NSString *)container + context:(NSString *)context + allowedMachineIDs:(NSSet *)allowedMachineIDs + reply:(void (^)(BOOL listDifferences, NSError * _Nullable error))reply; + +- (void)addAllowedMachineIDsWithContainer:(NSString *)container + context:(NSString *)context + machineIDs:(NSArray *)machineIDs + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)removeAllowedMachineIDsWithContainer:(NSString *)container + context:(NSString *)context + machineIDs:(NSArray *)machineIDs + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)fetchEgoEpochWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(unsigned long long epoch, + NSError * _Nullable error))reply; + +- (void)prepareWithContainer:(NSString *)container + context:(NSString *)context + epoch:(unsigned long long)epoch + machineID:(NSString *)machineID + bottleSalt:(NSString *)bottleSalt + bottleID:(NSString *)bottleID + modelID:(NSString *)modelID + deviceName:(nullable NSString*)deviceName + serialNumber:(NSString *)serialNumber + osVersion:(NSString *)osVersion + policyVersion:(nullable NSNumber *)policyVersion + policySecrets:(nullable NSDictionary *)policySecrets + signingPrivKeyPersistentRef:(nullable NSData *)spkPr + encPrivKeyPersistentRef:(nullable NSData*)epkPr + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply; + +// If there already are existing CKKSViews, please pass in their key sets anyway. +// This function will create a self TLK Share for those TLKs. +- (void)establishWithContainer:(NSString *)container + context:(NSString *)context + ckksKeys:(NSArray *)viewKeySets + tlkShares:(NSArray *)tlkShares + preapprovedKeys:(nullable NSArray *)preapprovedKeys + reply:(void (^)(NSString * _Nullable peerID, + NSArray* _Nullable keyHierarchyRecords, + NSError * _Nullable error))reply; + +// Returns a voucher for the given peer ID using our own identity +// If TLK CKKSViewKeys are given, TLKShares will be created and uploaded for this new peer before this call returns. +- (void)vouchWithContainer:(NSString *)container + context:(NSString *)context + peerID:(NSString *)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + ckksKeys:(NSArray *)viewKeySets + reply:(void (^)(NSData * _Nullable voucher, + NSData * _Nullable voucherSig, + NSError * _Nullable error))reply; + +// Returns a voucher for our own identity, created by the identity inside this bottle +- (void)vouchWithBottleWithContainer:(NSString *)container + context:(NSString *)context + bottleID:(NSString*)bottleID + entropy:(NSData*)entropy + bottleSalt:(NSString*)bottleSalt + tlkShares:(NSArray *)tlkShares + reply:(void (^)(NSData * _Nullable voucher, + NSData * _Nullable voucherSig, + NSError * _Nullable error))reply; + +// Returns a voucher for our own identity, using recovery key +- (void)vouchWithRecoveryKeyWithContainer:(NSString *)container + context:(NSString *)context + recoveryKey:(NSString*)recoveryKey + salt:(NSString*)salt + tlkShares:(NSArray *)tlkShares + reply:(void (^)(NSData * _Nullable voucher, + NSData * _Nullable voucherSig, + NSError * _Nullable error))reply; + +// As of right now, join and attemptPreapprovedJoin will upload TLKShares for any TLKs that this peer already has. +// Note that in The Future, a device might decide to join an existing Octagon set while introducing a new view. +// These interfaces will have to change... +- (void)joinWithContainer:(NSString *)container + context:(NSString *)context + voucherData:(NSData *)voucherData + voucherSig:(NSData *)voucherSig + ckksKeys:(NSArray *)viewKeySets + tlkShares:(NSArray *)tlkShares + preapprovedKeys:(NSArray *)preapprovedKeys + reply:(void (^)(NSString * _Nullable peerID, + NSArray* _Nullable keyHierarchyRecords, + NSError * _Nullable error))reply; + +// Preflighting a preapproved join suggests whether or not you expect to succeed in an immediate preapprovedJoin() call +// This only inspects the Octagon model, and ignores the trusted device list, so that you can preflight the preapprovedJoin() +// before fetching that list. +// This will return YES if there are no existing peers, or if the existing peers preapprove your prepared identity. +// This will return NO otherwise. +- (void)preflightPreapprovedJoinWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(BOOL launchOkay, + NSError * _Nullable error))reply; + +// A preapproved join might do a join, but it also might do an establish. +// Therefore, it needs all the TLKs and TLKShares as establish does +- (void)attemptPreapprovedJoinWithContainer:(NSString *)container + context:(NSString *)context + ckksKeys:(NSArray *)ckksKeys + tlkShares:(NSArray *)tlkShares + preapprovedKeys:(NSArray *)preapprovedKeys + reply:(void (^)(NSString * _Nullable peerID, + NSArray* _Nullable keyHierarchyRecords, + NSError * _Nullable error))reply; + +// TODO: if the new policy causes someone to lose access to a view, how should this API work? +- (void)updateWithContainer:(NSString *)container + context:(NSString *)context + deviceName:(nullable NSString *)deviceName + serialNumber:(nullable NSString *)serialNumber + osVersion:(nullable NSString *)osVersion + policyVersion:(nullable NSNumber *)policyVersion + policySecrets:(nullable NSDictionary *)policySecrets + reply:(void (^)(TrustedPeersHelperPeerState* _Nullable peerState, NSError * _Nullable error))reply; + +- (void)setPreapprovedKeysWithContainer:(NSString *)container + context:(NSString *)context + preapprovedKeys:(NSArray *)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply; + +/* Rather thin pass-through for uploading new TLKs (for zones which may have disappeared) */ +- (void)updateTLKsWithContainer:(NSString *)container + context:(NSString *)context + ckksKeys:(NSArray *)ckksKeys + tlkShares:(NSArray *)tlkShares + reply:(void (^)(NSArray* _Nullable keyHierarchyRecords, NSError * _Nullable error))reply; + +- (void)fetchViableBottlesWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray* _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply; + +- (void)fetchEscrowContentsWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; + +// The argument contains N [version:hash] keys, +// the reply block contains 0<=N [version:[hash, data]] entries. +- (void)fetchPolicyDocumentsWithContainer:(NSString*)container + context:(NSString*)context + keys:(NSDictionary*)keys + reply:(void (^)(NSDictionary*>* _Nullable entries, + NSError * _Nullable error))reply; + +// Fetch the policy for current peer. +- (void)fetchPolicyWithContainer:(NSString*)container + context:(NSString*)context + reply:(void (^)(TPPolicy * _Nullable policy, + NSError * _Nullable error))reply; + +- (void)validatePeersWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply; + + +// TODO: merge this and trustStatusWithContainer +- (void)fetchTrustStateWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(TrustedPeersHelperPeerState* _Nullable selfPeerState, + NSArray* _Nullable trustedPeers, + NSError* _Nullable error))reply; + +- (void)setRecoveryKeyWithContainer:(NSString *)container + context:(NSString *)context + recoveryKey:(NSString *)recoveryKey + salt:(NSString *)salt + ckksKeys:(NSArray *)ckksKeys + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)reportHealthWithContainer:(NSString *)container + context:(NSString *)context + stateMachineState:(NSString *)state + trustState:(NSString *)trustState + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)pushHealthInquiryWithContainer:(NSString *)container + context:(NSString *)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)getViewsWithContainer:(NSString *)container + context:(NSString *)context + inViews:(NSArray*)inViews + reply:(void (^)(NSArray* _Nullable, NSError* _Nullable))reply; + +- (void)requestHealthCheckWithContainer:(NSString *)container + context:(NSString *)context + requiresEscrowCheck:(BOOL)requiresEscrowCheck + reply:(void (^)(BOOL postRepairCFU, BOOL postEscrowCFU, BOOL resetOctagon, NSError* _Nullable))reply; +@end + +/* + To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this: + + _connectionToService = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.TrustedPeersHelper"]; + _connectionToService.remoteObjectInterface = TrustedPeersHelperSetupProtocol([NSXPCInterface interfaceWithProtocol:@protocol(TrustedPeersHelperProtocol)]); + [_connectionToService resume]; + +Once you have a connection to the service, you can use it like this: + + [[_connectionToService remoteObjectProxy] upperCaseString:@"hello" withReply:^(NSString *aString) { + // We have received a response. Update our text field, but do it on the main thread. + NSLog(@"Result string was: %@", aString); + }]; + + And, when you are finished with the service, clean up the connection like this: + + [_connectionToService invalidate]; +*/ + + +// Use this at protocol creation time to tell NSXPC to do its job +NSXPCInterface* TrustedPeersHelperSetupProtocol(NSXPCInterface* interface); + +NS_ASSUME_NONNULL_END diff --git a/keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.m b/keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.m new file mode 100644 index 00000000..a912a227 --- /dev/null +++ b/keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.m @@ -0,0 +1,300 @@ + +#import + +#if OCTAGON +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "utilities/debugging.h" +#import +#import +#endif + +NSXPCInterface* TrustedPeersHelperSetupProtocol(NSXPCInterface* interface) +{ +#if OCTAGON + static NSMutableSet *errClasses; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + errClasses = [NSMutableSet setWithSet:CKAcceptableValueClasses()]; + + char *classes[] = { + "CKPrettyError", + "CKRecordID", + "NSArray", + "NSData", + "NSDate", + "NSDictionary", + "NSError", + "NSNull", + "NSNumber", + "NSOrderedSet", + "NSSet", + "NSString", + "NSURL", + }; + + for (unsigned n = 0; n < sizeof(classes)/sizeof(classes[0]); n++) { + Class cls = objc_getClass(classes[n]); + if (cls) { + [errClasses addObject:cls]; + } + } + }); + + @try { + NSSet* arrayOfKeySets = [NSSet setWithArray:@[[NSArray class], [CKKSKeychainBackedKeySet class]]]; + NSSet* arrayOfTLKShares = [NSSet setWithArray:@[[NSArray class], [CKKSTLKShare class]]]; + NSSet* arrayOfCKRecords = [NSSet setWithArray:@[[NSArray class], [CKRecord class]]]; + NSSet* arrayOfStrings = [NSSet setWithArray:@[[NSArray class], [NSString class]]]; + NSSet* trustedPeersHelperPeerState = [NSSet setWithObject:[TrustedPeersHelperPeerState class]]; + + NSSet* arrayOfTrustedPeersHelperPeer = [NSSet setWithArray:@[[NSArray class], [TrustedPeersHelperPeer class]]]; + + [interface setClasses:arrayOfStrings forSelector:@selector(addAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:2 ofReply:NO]; + [interface setClasses:arrayOfStrings forSelector:@selector(removeAllowedMachineIDsWithContainer:context:machineIDs:reply:) argumentIndex:2 ofReply:NO]; + + [interface setClasses:arrayOfKeySets forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:2 ofReply:NO]; + [interface setClasses:arrayOfTLKShares forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:NO]; + [interface setClasses:arrayOfCKRecords forSelector:@selector(establishWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES]; + + [interface setClasses:arrayOfKeySets forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:4 ofReply:NO]; + [interface setClasses:arrayOfTLKShares forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:5 ofReply:NO]; + [interface setClasses:arrayOfCKRecords forSelector:@selector(joinWithContainer:context:voucherData:voucherSig:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES]; + + [interface setClasses:arrayOfKeySets forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:2 ofReply:NO]; + [interface setClasses:arrayOfTLKShares forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:3 ofReply:NO]; + [interface setClasses:arrayOfCKRecords forSelector:@selector(attemptPreapprovedJoinWithContainer:context:ckksKeys:tlkShares:preapprovedKeys:reply:) argumentIndex:1 ofReply:YES]; + + [interface setClasses:arrayOfKeySets forSelector:@selector(vouchWithContainer: + context: + peerID: + permanentInfo: + permanentInfoSig: + stableInfo: + stableInfoSig: + ckksKeys: + reply:) argumentIndex:7 ofReply:NO]; + + [interface setClasses:arrayOfTLKShares forSelector:@selector(vouchWithBottleWithContainer: + context: + bottleID: + entropy: + bottleSalt: + tlkShares: + reply:) argumentIndex:5 ofReply:NO]; + [interface setClasses:arrayOfKeySets forSelector:@selector(setRecoveryKeyWithContainer: + context: + recoveryKey: + salt: + ckksKeys: + reply:) argumentIndex:4 ofReply:NO]; + [interface setClasses:arrayOfTLKShares forSelector:@selector(vouchWithRecoveryKeyWithContainer: + context: + recoveryKey: + salt: + tlkShares: + reply:) argumentIndex:4 ofReply:NO]; + + [interface setClasses:[NSSet setWithObject:[TPPolicy class]] forSelector:@selector(fetchPolicyWithContainer: + context: + reply:) argumentIndex:0 ofReply:YES]; + + [interface setClasses:trustedPeersHelperPeerState forSelector:@selector(updateWithContainer: + context: + deviceName: + serialNumber: + osVersion: + policyVersion: + policySecrets: + reply:) argumentIndex:0 ofReply:YES]; + + [interface setClasses:trustedPeersHelperPeerState forSelector:@selector(fetchTrustStateWithContainer: + context: + reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:arrayOfTrustedPeersHelperPeer forSelector:@selector(fetchTrustStateWithContainer: + context: + reply:) argumentIndex:1 ofReply:YES]; + + [interface setClasses:arrayOfKeySets forSelector:@selector(updateTLKsWithContainer: + context: + ckksKeys: + tlkShares: + reply:) argumentIndex:2 ofReply:NO]; + [interface setClasses:arrayOfTLKShares forSelector:@selector(updateTLKsWithContainer: + context: + ckksKeys: + tlkShares: + reply:) argumentIndex:3 ofReply:NO]; + [interface setClasses:arrayOfCKRecords forSelector:@selector(updateTLKsWithContainer: + context: + ckksKeys: + tlkShares: + reply:) argumentIndex:0 ofReply:YES]; + } + @catch(NSException* e) { + secerror("TrustedPeersHelperSetupProtocol failed, continuing, but you might crash later: %@", e); +#if DEBUG + @throw e; +#endif + } +#endif + + return interface; +} + +@implementation TrustedPeersHelperPeerState + +- (instancetype)initWithPeerID:(NSString* _Nullable)peerID + isPreapproved:(BOOL)isPreapproved + status:(TPPeerStatus)peerStatus + memberChanges:(BOOL)memberChanges + unknownMachineIDs:(BOOL)unknownMachineIDs +{ + if((self = [super init])) { + _peerID = peerID; + _identityIsPreapproved = isPreapproved; + _peerStatus = peerStatus; + _memberChanges = memberChanges; + _unknownMachineIDsPresent = unknownMachineIDs; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", + self.peerID, + self.identityIsPreapproved, + (int64_t)self.peerStatus, + self.memberChanges ? @"YES" : @"NO", + self.unknownMachineIDsPresent ? @"YES" : @"NO"]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)initWithCoder:(NSCoder *)coder { + if ((self = [super init])) { + _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"]; + _identityIsPreapproved = [coder decodeBoolForKey:@"identityIsPreapproved"]; + _peerStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"peerStatus"]; + _memberChanges = (BOOL)[coder decodeInt64ForKey:@"memberChanges"]; + _unknownMachineIDsPresent = (BOOL)[coder decodeInt64ForKey:@"unknownMachineIDs"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.peerID forKey:@"peerID"]; + [coder encodeBool:self.identityIsPreapproved forKey:@"identityIsPreapproved"]; + [coder encodeInt64:(int64_t)self.peerStatus forKey:@"peerStatus"]; + [coder encodeInt64:(int64_t)self.memberChanges forKey:@"memberChanges"]; + [coder encodeInt64:(int64_t)self.unknownMachineIDsPresent forKey:@"unknownMachineIDs"]; + +} +@end + +@implementation TrustedPeersHelperEgoPeerStatus + +- (instancetype)initWithEgoPeerID:(NSString* _Nullable)egoPeerID + status:(TPPeerStatus)egoStatus + peerCountsByModelID:(NSDictionary*)peerCountsByModelID + isExcluded:(BOOL)isExcluded + isLocked:(BOOL)isLocked +{ + if((self = [super init])) { + _egoPeerID = egoPeerID; + _egoStatus = egoStatus; + _peerCountsByModelID = peerCountsByModelID; + _numberOfPeersInOctagon = 0; + for(NSNumber* n in peerCountsByModelID.allValues) { + _numberOfPeersInOctagon += [n unsignedIntegerValue]; + } + _isExcluded = isExcluded; + _isLocked = isLocked; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.egoPeerID]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)initWithCoder:(NSCoder *)coder { + if ((self = [super init])) { + _egoPeerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"]; + _egoStatus = (TPPeerStatus)[coder decodeInt64ForKey:@"egoStatus"]; + _peerCountsByModelID = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSDictionary class], [NSString class], [NSNumber class]]] forKey:@"peerCountsByModelID"]; + _numberOfPeersInOctagon = 0; + for(NSNumber* n in _peerCountsByModelID.allValues) { + _numberOfPeersInOctagon += [n unsignedIntegerValue]; + } + + _isExcluded = (BOOL)[coder decodeBoolForKey:@"isExcluded"]; + _isLocked = (BOOL)[coder decodeBoolForKey:@"isLocked"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.egoPeerID forKey:@"peerID"]; + [coder encodeInt64:self.egoStatus forKey:@"egoStatus"]; + [coder encodeObject:self.peerCountsByModelID forKey:@"peerCountsByModelID"]; + [coder encodeBool:self.isExcluded forKey:@"isExcluded"]; + [coder encodeBool:self.isLocked forKey:@"isLocked"]; +} + +@end + + +@implementation TrustedPeersHelperPeer +- (instancetype)initWithPeerID:(NSString*)peerID + signingSPKI:(NSData*)signingSPKI + encryptionSPKI:(NSData*)encryptionSPKI + viewList:(NSSet*)viewList +{ + if((self = [super init])) { + _peerID = peerID; + _signingSPKI = signingSPKI; + _encryptionSPKI = encryptionSPKI; + _viewList = viewList; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", + self.peerID, + self.signingSPKI, + self.encryptionSPKI, + (unsigned long)self.viewList.count]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)initWithCoder:(NSCoder *)coder { + if ((self = [super init])) { + _peerID = [coder decodeObjectOfClass:[NSString class] forKey:@"peerID"]; + _signingSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"signingSPKI"]; + _encryptionSPKI = [coder decodeObjectOfClass:[NSData class] forKey:@"encryptionSPKI"]; + _viewList = [coder decodeObjectOfClasses:[NSSet setWithArray:@[[NSSet class], [NSString class]]] forKey:@"viewList"]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.peerID forKey:@"peerID"]; + [coder encodeObject:self.signingSPKI forKey:@"signingSPKI"]; + [coder encodeObject:self.encryptionSPKI forKey:@"encryptionSPKI"]; + [coder encodeObject:self.viewList forKey:@"viewList"]; +} +@end diff --git a/keychain/TrustedPeersHelper/Utils.swift b/keychain/TrustedPeersHelper/Utils.swift new file mode 100644 index 00000000..6293393d --- /dev/null +++ b/keychain/TrustedPeersHelper/Utils.swift @@ -0,0 +1,60 @@ +/* + * 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 Foundation + +extension SignedPeerPermanentInfo { + init(_ permanentInfo: TPPeerPermanentInfo) { + self.peerPermanentInfo = permanentInfo.data + self.sig = permanentInfo.sig + } + + func toPermanentInfo(peerID: String) -> TPPeerPermanentInfo? { + return TPPeerPermanentInfo(peerID: peerID, + data: self.peerPermanentInfo, + sig: self.sig, + keyFactory: TPECPublicKeyFactory()) + } +} + +extension SignedPeerStableInfo { + init(_ stableInfo: TPPeerStableInfo) { + self.peerStableInfo = stableInfo.data + self.sig = stableInfo.sig + } + + func toStableInfo() -> TPPeerStableInfo? { + return TPPeerStableInfo(data: self.peerStableInfo, sig: self.sig) + } +} + +extension SignedPeerDynamicInfo { + init(_ dynamicInfo: TPPeerDynamicInfo) { + self.peerDynamicInfo = dynamicInfo.data + self.sig = dynamicInfo.sig + } + + func toDynamicInfo() -> TPPeerDynamicInfo? { + return TPPeerDynamicInfo(data: self.peerDynamicInfo, sig: self.sig) + } +} diff --git a/keychain/ot/OTAuthenticatedCiphertext+SF.h b/keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.h similarity index 93% rename from keychain/ot/OTAuthenticatedCiphertext+SF.h rename to keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.h index 799dac23..29bfde51 100644 --- a/keychain/ot/OTAuthenticatedCiphertext+SF.h +++ b/keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.h @@ -21,12 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if OCTAGON #import #import -#import "OTAuthenticatedCiphertext.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTAuthenticatedCiphertext.h" NS_ASSUME_NONNULL_BEGIN @@ -39,4 +38,3 @@ NS_ASSUME_NONNULL_BEGIN @end NS_ASSUME_NONNULL_END -#endif diff --git a/keychain/ot/OTAuthenticatedCiphertext+SF.m b/keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.m similarity index 98% rename from keychain/ot/OTAuthenticatedCiphertext+SF.m rename to keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.m index 10ee1063..21790d3d 100644 --- a/keychain/ot/OTAuthenticatedCiphertext+SF.m +++ b/keychain/TrustedPeersHelper/categories/OTAuthenticatedCiphertext+SF.m @@ -21,7 +21,6 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if OCTAGON #import "OTAuthenticatedCiphertext+SF.h" @@ -44,5 +43,3 @@ } @end - -#endif diff --git a/keychain/ot/OTPrivateKey+SF.h b/keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.h similarity index 89% rename from keychain/ot/OTPrivateKey+SF.h rename to keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.h index 7b281409..89fa955e 100644 --- a/keychain/ot/OTPrivateKey+SF.h +++ b/keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.h @@ -21,12 +21,10 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if OCTAGON - #import #import -#import "OTPrivateKey.h" +#import "keychain/TrustedPeersHelper/proto/generated_source/OTPrivateKey.h" NS_ASSUME_NONNULL_BEGIN @@ -34,9 +32,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)fromECKeyPair:(SFECKeyPair *)keyPair; -- (nullable SFECKeyPair *)asECKeyPair; +- (SFECKeyPair * _Nullable)asECKeyPair:(NSError**)error; @end NS_ASSUME_NONNULL_END -#endif diff --git a/keychain/ot/OTPrivateKey+SF.m b/keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.m similarity index 64% rename from keychain/ot/OTPrivateKey+SF.m rename to keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.m index f12ab72d..b2607898 100644 --- a/keychain/ot/OTPrivateKey+SF.m +++ b/keychain/TrustedPeersHelper/categories/OTPrivateKey+SF.m @@ -21,12 +21,11 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if OCTAGON #import "OTPrivateKey+SF.h" - -#import "OTEscrowKeys.h" #import +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" @implementation OTPrivateKey (SecurityFoundation) @@ -37,15 +36,27 @@ pk.keyData = keyPair.keyData; return pk; } ++ (SecKeyRef) createSecKey:(NSData*)keyData +{ + NSDictionary *keyAttributes = @{ + (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPrivate, + (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC, + }; + + SecKeyRef key = SecKeyCreateWithData((__bridge CFDataRef)keyData, (__bridge CFDictionaryRef)keyAttributes, NULL); + return key; +} -- (nullable SFECKeyPair *)asECKeyPair +- (SFECKeyPair * _Nullable)asECKeyPair:(NSError**)error { if (self.keyType != OTPrivateKey_KeyType_EC_NIST_CURVES) { + if(error){ + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNotSupported userInfo:nil]; + } return nil; } - return [[SFECKeyPair alloc] initWithSecKey:[OTEscrowKeys createSecKey:self.keyData]]; + return [[SFECKeyPair alloc] initWithSecKey:[OTPrivateKey createSecKey:self.keyData]]; } @end -#endif diff --git a/keychain/TrustedPeersHelper/main.swift b/keychain/TrustedPeersHelper/main.swift new file mode 100644 index 00000000..7111e5b9 --- /dev/null +++ b/keychain/TrustedPeersHelper/main.swift @@ -0,0 +1,69 @@ +/* + * 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 Foundation +import os.log + +let containerMap = ContainerMap(invocableCreator: CKCodeCuttlefishInvocableCreator()) + +class ServiceDelegate: NSObject, NSXPCListenerDelegate { + func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { + let tphEntitlement = "com.apple.private.trustedpeershelper.client" + + os_log("Received a new client: %@", log: tplogDebug, type: .default, newConnection) + switch newConnection.value(forEntitlement: tphEntitlement) { + case 1 as Int: + os_log("client has entitlement '%@'", log: tplogDebug, type: .default, tphEntitlement) + case true as Bool: + os_log("client has entitlement '%@'", log: tplogDebug, type: .default, tphEntitlement) + + case let someInt as Int: + os_log("client(%@) has wrong integer value for '%@' (%d), rejecting", log: tplogDebug, type: .default, newConnection, tphEntitlement, someInt) + return false + + case let someBool as Bool: + os_log("client(%@) has wrong boolean value for '%@' (%d), rejecting", log: tplogDebug, type: .default, newConnection, tphEntitlement, someBool) + return false + + default: + os_log("client(%@) is missing entitlement '%@', rejecting", log: tplogDebug, type: .default, newConnection, tphEntitlement) + return false + } + + newConnection.exportedInterface = TrustedPeersHelperSetupProtocol(NSXPCInterface(with: TrustedPeersHelperProtocol.self)) + let exportedObject = Client(endpoint: newConnection.endpoint, containerMap: containerMap) + newConnection.exportedObject = exportedObject + newConnection.resume() + + return true + } +} + +os_log("Starting up", log: tplogDebug, type: .default) + +ValueTransformer.setValueTransformer(SetValueTransformer(), forName: SetValueTransformer.name) + +let delegate = ServiceDelegate() +let listener = NSXPCListener.service() +listener.delegate = delegate +listener.resume() diff --git a/keychain/ot/proto/OTAuthenticatedCiphertext.proto b/keychain/TrustedPeersHelper/proto/OTAuthenticatedCiphertext.proto similarity index 100% rename from keychain/ot/proto/OTAuthenticatedCiphertext.proto rename to keychain/TrustedPeersHelper/proto/OTAuthenticatedCiphertext.proto diff --git a/keychain/ot/proto/OTBottle.proto b/keychain/TrustedPeersHelper/proto/OTBottle.proto similarity index 98% rename from keychain/ot/proto/OTBottle.proto rename to keychain/TrustedPeersHelper/proto/OTBottle.proto index bbcc0e97..2f55525b 100644 --- a/keychain/ot/proto/OTBottle.proto +++ b/keychain/TrustedPeersHelper/proto/OTBottle.proto @@ -32,7 +32,7 @@ import "OTAuthenticatedCiphertext.proto"; message Bottle { optional string peerID = 1; - optional string spID = 2; + optional string bottleID = 2; // Tags 3, 4, 5 and 6 were briefly used during development for the raw public key data, with nothing to specify the key type. // They are replaced with the following, encoded as SubjectPublicKeyInfo: diff --git a/keychain/ot/proto/OTBottleContents.proto b/keychain/TrustedPeersHelper/proto/OTBottleContents.proto similarity index 100% rename from keychain/ot/proto/OTBottleContents.proto rename to keychain/TrustedPeersHelper/proto/OTBottleContents.proto diff --git a/keychain/ot/proto/OTPrivateKey.proto b/keychain/TrustedPeersHelper/proto/OTPrivateKey.proto similarity index 100% rename from keychain/ot/proto/OTPrivateKey.proto rename to keychain/TrustedPeersHelper/proto/OTPrivateKey.proto diff --git a/keychain/TrustedPeersHelper/proto/OTRecovery.proto b/keychain/TrustedPeersHelper/proto/OTRecovery.proto new file mode 100644 index 00000000..27f638d0 --- /dev/null +++ b/keychain/TrustedPeersHelper/proto/OTRecovery.proto @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019 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@ + */ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +message Recovery { + optional string peerID = 1; + + // as SubjectPublicKeyInfo (SPKI): + optional bytes signingSPKI = 2; + optional bytes encryptionSPKI = 3; +} + diff --git a/keychain/ot/proto/source/OTAuthenticatedCiphertext.h b/keychain/TrustedPeersHelper/proto/generated_source/OTAuthenticatedCiphertext.h similarity index 100% rename from keychain/ot/proto/source/OTAuthenticatedCiphertext.h rename to keychain/TrustedPeersHelper/proto/generated_source/OTAuthenticatedCiphertext.h diff --git a/keychain/ot/proto/source/OTAuthenticatedCiphertext.m b/keychain/TrustedPeersHelper/proto/generated_source/OTAuthenticatedCiphertext.m similarity index 100% rename from keychain/ot/proto/source/OTAuthenticatedCiphertext.m rename to keychain/TrustedPeersHelper/proto/generated_source/OTAuthenticatedCiphertext.m diff --git a/keychain/ot/proto/source/OTBottle.h b/keychain/TrustedPeersHelper/proto/generated_source/OTBottle.h similarity index 95% rename from keychain/ot/proto/source/OTBottle.h rename to keychain/TrustedPeersHelper/proto/generated_source/OTBottle.h index e4eda9bd..1cd42860 100644 --- a/keychain/ot/proto/source/OTBottle.h +++ b/keychain/TrustedPeersHelper/proto/generated_source/OTBottle.h @@ -16,6 +16,7 @@ __attribute__((visibility("hidden"))) @interface OTBottle : PBCodable { + NSString *_bottleID; OTAuthenticatedCiphertext *_contents; NSData *_escrowedEncryptionSPKI; NSData *_escrowedSigningSPKI; @@ -27,15 +28,14 @@ __attribute__((visibility("hidden"))) NSData *_reserved5; NSData *_reserved6; NSData *_reserved7; - NSString *_spID; } @property (nonatomic, readonly) BOOL hasPeerID; @property (nonatomic, retain) NSString *peerID; -@property (nonatomic, readonly) BOOL hasSpID; -@property (nonatomic, retain) NSString *spID; +@property (nonatomic, readonly) BOOL hasBottleID; +@property (nonatomic, retain) NSString *bottleID; @property (nonatomic, readonly) BOOL hasReserved3; /** diff --git a/keychain/ot/proto/source/OTBottle.m b/keychain/TrustedPeersHelper/proto/generated_source/OTBottle.m similarity index 94% rename from keychain/ot/proto/source/OTBottle.m rename to keychain/TrustedPeersHelper/proto/generated_source/OTBottle.m index 0799e2ed..5d73a9be 100644 --- a/keychain/ot/proto/source/OTBottle.m +++ b/keychain/TrustedPeersHelper/proto/generated_source/OTBottle.m @@ -20,11 +20,11 @@ return _peerID != nil; } @synthesize peerID = _peerID; -- (BOOL)hasSpID +- (BOOL)hasBottleID { - return _spID != nil; + return _bottleID != nil; } -@synthesize spID = _spID; +@synthesize bottleID = _bottleID; - (BOOL)hasReserved3 { return _reserved3 != nil; @@ -88,9 +88,9 @@ { [dict setObject:self->_peerID forKey:@"peerID"]; } - if (self->_spID) + if (self->_bottleID) { - [dict setObject:self->_spID forKey:@"spID"]; + [dict setObject:self->_bottleID forKey:@"bottleID"]; } if (self->_reserved3) { @@ -157,10 +157,10 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB self->_peerID = new_peerID; } break; - case 2 /* spID */: + case 2 /* bottleID */: { - NSString *new_spID = PBReaderReadString(reader); - self->_spID = new_spID; + NSString *new_bottleID = PBReaderReadString(reader); + self->_bottleID = new_bottleID; } break; case 3 /* reserved3 */: @@ -257,11 +257,11 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB PBDataWriterWriteStringField(writer, self->_peerID, 1); } } - /* spID */ + /* bottleID */ { - if (self->_spID) + if (self->_bottleID) { - PBDataWriterWriteStringField(writer, self->_spID, 2); + PBDataWriterWriteStringField(writer, self->_bottleID, 2); } } /* reserved3 */ @@ -342,9 +342,9 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB { other.peerID = _peerID; } - if (_spID) + if (_bottleID) { - other.spID = _spID; + other.bottleID = _bottleID; } if (_reserved3) { @@ -392,7 +392,7 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB { OTBottle *copy = [[[self class] allocWithZone:zone] init]; copy->_peerID = [_peerID copyWithZone:zone]; - copy->_spID = [_spID copyWithZone:zone]; + copy->_bottleID = [_bottleID copyWithZone:zone]; copy->_reserved3 = [_reserved3 copyWithZone:zone]; copy->_reserved4 = [_reserved4 copyWithZone:zone]; copy->_reserved5 = [_reserved5 copyWithZone:zone]; @@ -413,7 +413,7 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB && ((!self->_peerID && !other->_peerID) || [self->_peerID isEqual:other->_peerID]) && - ((!self->_spID && !other->_spID) || [self->_spID isEqual:other->_spID]) + ((!self->_bottleID && !other->_bottleID) || [self->_bottleID isEqual:other->_bottleID]) && ((!self->_reserved3 && !other->_reserved3) || [self->_reserved3 isEqual:other->_reserved3]) && @@ -443,7 +443,7 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB ^ [self->_peerID hash] ^ - [self->_spID hash] + [self->_bottleID hash] ^ [self->_reserved3 hash] ^ @@ -473,9 +473,9 @@ BOOL OTBottleReadFrom(__unsafe_unretained OTBottle *self, __unsafe_unretained PB { [self setPeerID:other->_peerID]; } - if (other->_spID) + if (other->_bottleID) { - [self setSpID:other->_spID]; + [self setBottleID:other->_bottleID]; } if (other->_reserved3) { diff --git a/keychain/ot/proto/source/OTBottleContents.h b/keychain/TrustedPeersHelper/proto/generated_source/OTBottleContents.h similarity index 100% rename from keychain/ot/proto/source/OTBottleContents.h rename to keychain/TrustedPeersHelper/proto/generated_source/OTBottleContents.h diff --git a/keychain/ot/proto/source/OTBottleContents.m b/keychain/TrustedPeersHelper/proto/generated_source/OTBottleContents.m similarity index 100% rename from keychain/ot/proto/source/OTBottleContents.m rename to keychain/TrustedPeersHelper/proto/generated_source/OTBottleContents.m diff --git a/keychain/ot/proto/source/OTPrivateKey.h b/keychain/TrustedPeersHelper/proto/generated_source/OTPrivateKey.h similarity index 100% rename from keychain/ot/proto/source/OTPrivateKey.h rename to keychain/TrustedPeersHelper/proto/generated_source/OTPrivateKey.h diff --git a/keychain/ot/proto/source/OTPrivateKey.m b/keychain/TrustedPeersHelper/proto/generated_source/OTPrivateKey.m similarity index 100% rename from keychain/ot/proto/source/OTPrivateKey.m rename to keychain/TrustedPeersHelper/proto/generated_source/OTPrivateKey.m diff --git a/keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.h b/keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.h new file mode 100644 index 00000000..8e09da1d --- /dev/null +++ b/keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.h @@ -0,0 +1,45 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTRecovery.proto + +#import +#import + +#ifdef __cplusplus +#define OTRECOVERY_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTRECOVERY_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTRecovery : PBCodable +{ + NSData *_encryptionSPKI; + NSString *_peerID; + NSData *_signingSPKI; +} + + +@property (nonatomic, readonly) BOOL hasPeerID; +@property (nonatomic, retain) NSString *peerID; + +@property (nonatomic, readonly) BOOL hasSigningSPKI; +/** as SubjectPublicKeyInfo (SPKI): */ +@property (nonatomic, retain) NSData *signingSPKI; + +@property (nonatomic, readonly) BOOL hasEncryptionSPKI; +@property (nonatomic, retain) NSData *encryptionSPKI; + +// Performs a shallow copy into other +- (void)copyTo:(OTRecovery *)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:(OTRecovery *)other; + +OTRECOVERY_FUNCTION BOOL OTRecoveryReadFrom(__unsafe_unretained OTRecovery *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.m b/keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.m new file mode 100644 index 00000000..7991b260 --- /dev/null +++ b/keychain/TrustedPeersHelper/proto/generated_source/OTRecovery.m @@ -0,0 +1,194 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTRecovery.proto + +#import "OTRecovery.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 OTRecovery + +- (BOOL)hasPeerID +{ + return _peerID != nil; +} +@synthesize peerID = _peerID; +- (BOOL)hasSigningSPKI +{ + return _signingSPKI != nil; +} +@synthesize signingSPKI = _signingSPKI; +- (BOOL)hasEncryptionSPKI +{ + return _encryptionSPKI != nil; +} +@synthesize encryptionSPKI = _encryptionSPKI; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_peerID) + { + [dict setObject:self->_peerID forKey:@"peerID"]; + } + if (self->_signingSPKI) + { + [dict setObject:self->_signingSPKI forKey:@"signingSPKI"]; + } + if (self->_encryptionSPKI) + { + [dict setObject:self->_encryptionSPKI forKey:@"encryptionSPKI"]; + } + return dict; +} + +BOOL OTRecoveryReadFrom(__unsafe_unretained OTRecovery *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 /* peerID */: + { + NSString *new_peerID = PBReaderReadString(reader); + self->_peerID = new_peerID; + } + break; + case 2 /* signingSPKI */: + { + NSData *new_signingSPKI = PBReaderReadData(reader); + self->_signingSPKI = new_signingSPKI; + } + break; + case 3 /* encryptionSPKI */: + { + NSData *new_encryptionSPKI = PBReaderReadData(reader); + self->_encryptionSPKI = new_encryptionSPKI; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTRecoveryReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* peerID */ + { + if (self->_peerID) + { + PBDataWriterWriteStringField(writer, self->_peerID, 1); + } + } + /* signingSPKI */ + { + if (self->_signingSPKI) + { + PBDataWriterWriteDataField(writer, self->_signingSPKI, 2); + } + } + /* encryptionSPKI */ + { + if (self->_encryptionSPKI) + { + PBDataWriterWriteDataField(writer, self->_encryptionSPKI, 3); + } + } +} + +- (void)copyTo:(OTRecovery *)other +{ + if (_peerID) + { + other.peerID = _peerID; + } + if (_signingSPKI) + { + other.signingSPKI = _signingSPKI; + } + if (_encryptionSPKI) + { + other.encryptionSPKI = _encryptionSPKI; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTRecovery *copy = [[[self class] allocWithZone:zone] init]; + copy->_peerID = [_peerID copyWithZone:zone]; + copy->_signingSPKI = [_signingSPKI copyWithZone:zone]; + copy->_encryptionSPKI = [_encryptionSPKI copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTRecovery *other = (OTRecovery *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_peerID && !other->_peerID) || [self->_peerID isEqual:other->_peerID]) + && + ((!self->_signingSPKI && !other->_signingSPKI) || [self->_signingSPKI isEqual:other->_signingSPKI]) + && + ((!self->_encryptionSPKI && !other->_encryptionSPKI) || [self->_encryptionSPKI isEqual:other->_encryptionSPKI]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_peerID hash] + ^ + [self->_signingSPKI hash] + ^ + [self->_encryptionSPKI hash] + ; +} + +- (void)mergeFrom:(OTRecovery *)other +{ + if (other->_peerID) + { + [self setPeerID:other->_peerID]; + } + if (other->_signingSPKI) + { + [self setSigningSPKI:other->_signingSPKI]; + } + if (other->_encryptionSPKI) + { + [self setEncryptionSPKI:other->_encryptionSPKI]; + } +} + +@end + diff --git a/keychain/TrustedPeersHelper/proto/generated_source/Recovery.h b/keychain/TrustedPeersHelper/proto/generated_source/Recovery.h new file mode 100644 index 00000000..8c37ffa9 --- /dev/null +++ b/keychain/TrustedPeersHelper/proto/generated_source/Recovery.h @@ -0,0 +1,45 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTRecovery.proto + +#import +#import + +#ifdef __cplusplus +#define RECOVERY_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define RECOVERY_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface Recovery : PBCodable +{ + NSData *_encryptionSPKI; + NSString *_peerID; + NSData *_signingSPKI; +} + + +@property (nonatomic, readonly) BOOL hasPeerID; +@property (nonatomic, retain) NSString *peerID; + +@property (nonatomic, readonly) BOOL hasSigningSPKI; +/** as SubjectPublicKeyInfo (SPKI): */ +@property (nonatomic, retain) NSData *signingSPKI; + +@property (nonatomic, readonly) BOOL hasEncryptionSPKI; +@property (nonatomic, retain) NSData *encryptionSPKI; + +// Performs a shallow copy into other +- (void)copyTo:(Recovery *)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:(Recovery *)other; + +RECOVERY_FUNCTION BOOL RecoveryReadFrom(__unsafe_unretained Recovery *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/TrustedPeersHelper/proto/generated_source/Recovery.m b/keychain/TrustedPeersHelper/proto/generated_source/Recovery.m new file mode 100644 index 00000000..3fe93792 --- /dev/null +++ b/keychain/TrustedPeersHelper/proto/generated_source/Recovery.m @@ -0,0 +1,194 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTRecovery.proto + +#import "Recovery.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 Recovery + +- (BOOL)hasPeerID +{ + return _peerID != nil; +} +@synthesize peerID = _peerID; +- (BOOL)hasSigningSPKI +{ + return _signingSPKI != nil; +} +@synthesize signingSPKI = _signingSPKI; +- (BOOL)hasEncryptionSPKI +{ + return _encryptionSPKI != nil; +} +@synthesize encryptionSPKI = _encryptionSPKI; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_peerID) + { + [dict setObject:self->_peerID forKey:@"peerID"]; + } + if (self->_signingSPKI) + { + [dict setObject:self->_signingSPKI forKey:@"signingSPKI"]; + } + if (self->_encryptionSPKI) + { + [dict setObject:self->_encryptionSPKI forKey:@"encryptionSPKI"]; + } + return dict; +} + +BOOL RecoveryReadFrom(__unsafe_unretained Recovery *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 /* peerID */: + { + NSString *new_peerID = PBReaderReadString(reader); + self->_peerID = new_peerID; + } + break; + case 2 /* signingSPKI */: + { + NSData *new_signingSPKI = PBReaderReadData(reader); + self->_signingSPKI = new_signingSPKI; + } + break; + case 3 /* encryptionSPKI */: + { + NSData *new_encryptionSPKI = PBReaderReadData(reader); + self->_encryptionSPKI = new_encryptionSPKI; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return RecoveryReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* peerID */ + { + if (self->_peerID) + { + PBDataWriterWriteStringField(writer, self->_peerID, 1); + } + } + /* signingSPKI */ + { + if (self->_signingSPKI) + { + PBDataWriterWriteDataField(writer, self->_signingSPKI, 2); + } + } + /* encryptionSPKI */ + { + if (self->_encryptionSPKI) + { + PBDataWriterWriteDataField(writer, self->_encryptionSPKI, 3); + } + } +} + +- (void)copyTo:(Recovery *)other +{ + if (_peerID) + { + other.peerID = _peerID; + } + if (_signingSPKI) + { + other.signingSPKI = _signingSPKI; + } + if (_encryptionSPKI) + { + other.encryptionSPKI = _encryptionSPKI; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + Recovery *copy = [[[self class] allocWithZone:zone] init]; + copy->_peerID = [_peerID copyWithZone:zone]; + copy->_signingSPKI = [_signingSPKI copyWithZone:zone]; + copy->_encryptionSPKI = [_encryptionSPKI copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + Recovery *other = (Recovery *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_peerID && !other->_peerID) || [self->_peerID isEqual:other->_peerID]) + && + ((!self->_signingSPKI && !other->_signingSPKI) || [self->_signingSPKI isEqual:other->_signingSPKI]) + && + ((!self->_encryptionSPKI && !other->_encryptionSPKI) || [self->_encryptionSPKI isEqual:other->_encryptionSPKI]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_peerID hash] + ^ + [self->_signingSPKI hash] + ^ + [self->_encryptionSPKI hash] + ; +} + +- (void)mergeFrom:(Recovery *)other +{ + if (other->_peerID) + { + [self setPeerID:other->_peerID]; + } + if (other->_signingSPKI) + { + [self setSigningSPKI:other->_signingSPKI]; + } + if (other->_encryptionSPKI) + { + [self setEncryptionSPKI:other->_encryptionSPKI]; + } +} + +@end + diff --git a/keychain/TrustedPeersHelperUnitTests/ContainerSync.swift b/keychain/TrustedPeersHelperUnitTests/ContainerSync.swift new file mode 100644 index 00000000..17ab441f --- /dev/null +++ b/keychain/TrustedPeersHelperUnitTests/ContainerSync.swift @@ -0,0 +1,374 @@ +// +// SessionSync.swift +// Security_ios +// +// Created by Ben Williamson on 6/8/18. +// + +import XCTest + +extension Container { + + func dumpSync(test: XCTestCase) -> ([AnyHashable: Any]?, Error?) { + let expectation = XCTestExpectation(description: "dump replied") + var reta: [AnyHashable: Any]?, reterr: Error? + self.dump { a, err in + reta = a + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, reterr) + } + + func resetSync(test: XCTestCase) -> Error? { + let expectation = XCTestExpectation(description: "reset replied") + var reterr: Error? + self.reset { error in + reterr = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func localResetSync(test: XCTestCase) -> Error? { + let expectation = XCTestExpectation(description: "reset replied") + var reterr: Error? + self.localReset { error in + reterr = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func prepareSync(test: XCTestCase, + epoch: UInt64, + machineID: String, + bottleSalt: String, + bottleID: String, + modelID: String, + deviceName: String = "test device name", + serialNumber: String = "456", + osVersion: String = "123", + policyVersion: UInt64? = nil, + policySecrets: [String: Data]? = nil, + signingPrivateKeyPersistentRef: Data? = nil, + encryptionPrivateKeyPersistentRef: Data? = nil + ) -> (String?, Data?, Data?, Data?, Data?, Error?) { + let expectation = XCTestExpectation(description: "prepare replied") + var reta: String?, retb: Data?, retc: Data?, retd: Data?, rete: Data?, reterr: Error? + self.prepare(epoch: epoch, + machineID: machineID, + bottleSalt: bottleSalt, + bottleID: bottleID, + modelID: modelID, + deviceName: deviceName, + serialNumber: serialNumber, + osVersion: osVersion, + policyVersion: policyVersion, + policySecrets: policySecrets, + signingPrivateKeyPersistentRef: signingPrivateKeyPersistentRef, + encryptionPrivateKeyPersistentRef: encryptionPrivateKeyPersistentRef + ) { a, b, c, d, e, err in + reta = a + retb = b + retc = c + retd = d + rete = e + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, retb, retc, retd, rete, reterr) + } + + func establishSync(test: XCTestCase, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]?) -> (String?, [CKRecord], Error?) { + let expectation = XCTestExpectation(description: "prepare replied") + var reta: String?, retkhr: [CKRecord]?, reterr: Error? + self.establish(ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys) { a, khr, err in + reta = a + retkhr = khr + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, retkhr!, reterr) + } + + func vouchSync(test: XCTestCase, + peerID: String, + permanentInfo: Data, + permanentInfoSig: Data, + stableInfo: Data, + stableInfoSig: Data, + ckksKeys: [CKKSKeychainBackedKeySet]) -> (Data?, Data?, Error?) { + let expectation = XCTestExpectation(description: "vouch replied") + var reta: Data?, retb: Data?, reterr: Error? + self.vouch(peerID: peerID, + permanentInfo: permanentInfo, + permanentInfoSig: permanentInfoSig, + stableInfo: stableInfo, + stableInfoSig: stableInfoSig, + ckksKeys: ckksKeys) { a, b, err in + reta = a + retb = b + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, retb, reterr) + } + + func vouchWithBottleSync(test: XCTestCase, b: String, entropy: Data, bottleSalt: String, tlkShares: [CKKSTLKShare]) -> (Data?, Data?, Error?) { + let expectation = XCTestExpectation(description: "vouchWithBottle replied") + var reta: Data?, retb: Data?, reterr: Error? + self.vouchWithBottle(bottleID: b, entropy: entropy, bottleSalt: bottleSalt, tlkShares: tlkShares) { a, b, err in + reta = a + retb = b + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, retb, reterr) + } + + func joinSync(test: XCTestCase, + voucherData: Data, + voucherSig: Data, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]? = nil) -> (String?, [CKRecord]?, Error?) { + let expectation = XCTestExpectation(description: "join replied") + var reta: String?, retkhr: [CKRecord]?, reterr: Error? + self.join(voucherData: voucherData, + voucherSig: voucherSig, + ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys) { a, khr, err in + reta = a + retkhr = khr + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, retkhr, reterr) + } + + func preapprovedJoinSync(test: XCTestCase, + ckksKeys: [CKKSKeychainBackedKeySet], + tlkShares: [CKKSTLKShare], + preapprovedKeys: [Data]? = nil) -> (String?, [CKRecord]?, Error?) { + let expectation = XCTestExpectation(description: "preapprovedjoin replied") + var reta: String? + var retkhr: [CKRecord]? + var reterr: Error? + self.preapprovedJoin(ckksKeys: ckksKeys, + tlkShares: tlkShares, + preapprovedKeys: preapprovedKeys) { a, khr, err in + reta = a + retkhr = khr + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, retkhr, reterr) + } + + func updateSync(test: XCTestCase, + deviceName: String? = nil, + serialNumner: String? = nil, + osVersion: String? = nil, + policyVersion: UInt64? = nil, + policySecrets: [String: Data]? = nil) -> (TrustedPeersHelperPeerState?, Error?) { + let expectation = XCTestExpectation(description: "update replied") + var reterr: Error? + var retstate: TrustedPeersHelperPeerState? + self.update(deviceName: deviceName, + serialNumber: serialNumner, + osVersion: osVersion, + policyVersion: policyVersion, + policySecrets: policySecrets) { state, err in + retstate = state + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (retstate, reterr) + } + + func setAllowedMachineIDsSync(test: XCTestCase, allowedMachineIDs: Set, listDifference: Bool = true) -> (Error?) { + let expectation = XCTestExpectation(description: "setAllowedMachineIDs replied") + var reterr: Error? + self.setAllowedMachineIDs(allowedMachineIDs) { differences, err in + XCTAssertEqual(differences, listDifference, "Reported list difference should match expectation") + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func addAllowedMachineIDsSync(test: XCTestCase, machineIDs: [String]) -> Error? { + let expectation = XCTestExpectation(description: "addAllow replied") + var reterr: Error? + self.addAllow(machineIDs) { err in + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func removeAllowedMachineIDsSync(test: XCTestCase, machineIDs: [String]) -> Error? { + let expectation = XCTestExpectation(description: "removeAllow replied") + var reterr: Error? + self.removeAllow(machineIDs) { err in + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func departByDistrustingSelfSync(test: XCTestCase) -> Error? { + let expectation = XCTestExpectation(description: "departByDistrustingSelf replied") + var reterr: Error? + self.departByDistrustingSelf { error in + reterr = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func distrustSync(test: XCTestCase, peerIDs: Set) -> Error? { + let expectation = XCTestExpectation(description: "distrustSync replied") + var reterr: Error? + self.distrust(peerIDs: peerIDs) { error in + reterr = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return reterr + } + + func getStateSync(test: XCTestCase) -> ContainerState { + let expectation = XCTestExpectation(description: "getState replied") + var retstate: ContainerState? + self.getState { state in + retstate = state + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return retstate! + } + + func loadSecretSync(test: XCTestCase, + label: String) -> (Data?) { + var secret: Data? + do { + secret = try loadSecret(label: label) + } catch { + + } + return secret + } + + func setRecoveryKeySync(test: XCTestCase, recoveryKey: String, recoverySalt: String, ckksKeys: [CKKSKeychainBackedKeySet]) -> (Error?) { + let expectation = XCTestExpectation(description: "setRecoveryKey replied") + var reterr: Error? + + self.setRecoveryKey(recoveryKey: recoveryKey, salt: recoverySalt, ckksKeys: ckksKeys) { error in + reterr = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reterr) + } + + func fetchViableBottlesSync(test: XCTestCase) -> ([String]?, [String]?, Error?) { + let expectation = XCTestExpectation(description: "fetchViableBottles replied") + var retescrowRecordIDs: [String]? + var retpartialEscrowRecordIDs: [String]? + var reterror: Error? + self.fetchViableBottles { escrowRecordIDs, partialEscrowRecordIDs, error in + retescrowRecordIDs = escrowRecordIDs + retpartialEscrowRecordIDs = partialEscrowRecordIDs + reterror = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (retescrowRecordIDs, retpartialEscrowRecordIDs, reterror) + } + + func trustStatusSync(test: XCTestCase) -> (TrustedPeersHelperEgoPeerStatus, Error?) { + let expectation = XCTestExpectation(description: "trustStatus replied") + var retEgoStatus = TrustedPeersHelperEgoPeerStatus(egoPeerID: nil, status: .unknown, peerCountsByModelID: [:], isExcluded: false, isLocked: false) + var reterror: Error? + self.trustStatus { egoStatus, error in + retEgoStatus = egoStatus + reterror = error + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (retEgoStatus, reterror) + } + + func fetchPolicyDocumentsSync(test: XCTestCase, + keys: [NSNumber: String]) -> ([NSNumber: [String]]?, Error?) { + let expectation = XCTestExpectation(description: "fetchPolicyDocuments replied") + var reta: [NSNumber: [String]]?, reterr: Error? + self.fetchPolicyDocuments(keys: keys) { a, err in + reta = a + reterr = err + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (reta, reterr) + } + + func fetchEscrowContentsSync(test: XCTestCase) -> (Data?, String?, Data?, Error?) { + let expectation = XCTestExpectation(description: "fetchEscrowContents replied") + var retentropy: Data? + var retbottleID: String? + var retspki: Data? + var reterror: Error? + + self.fetchEscrowContents { entropy, bottleID, spki, error in + retentropy = entropy + retbottleID = bottleID + retspki = spki + reterror = error + + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (retentropy, retbottleID, retspki, reterror) + } + + func requestHealthCheckSync(requiresEscrowCheck: Bool, test: XCTestCase) -> (Bool, Bool, Bool, Error?) { + let expectation = XCTestExpectation(description: "requestHealthCheck replied") + var retrepairaccount: Bool = false + var retrepairescrow: Bool = false + var retresetoctagon: Bool = false + var reterror: Error? + + self.requestHealthCheck(requiresEscrowCheck: requiresEscrowCheck) { repairAccount, repairEscrow, resetOctagon, error in + retrepairaccount = repairAccount + retrepairescrow = repairEscrow + retresetoctagon = resetOctagon + reterror = error + + expectation.fulfill() + } + test.wait(for: [expectation], timeout: 10.0) + return (retrepairaccount, retrepairescrow, retresetoctagon, reterror) + } +} diff --git a/keychain/TrustedPeersHelperUnitTests/FakeCuttlefish.swift b/keychain/TrustedPeersHelperUnitTests/FakeCuttlefish.swift new file mode 100644 index 00000000..fce8f219 --- /dev/null +++ b/keychain/TrustedPeersHelperUnitTests/FakeCuttlefish.swift @@ -0,0 +1,758 @@ +// +// FakeCuttlefish.swift +// Security +// +// Created by Ben Williamson on 5/23/18. +// + +import CloudKitCode +import Foundation + +enum FakeCuttlefishError: Error { + case notEmpty + case unknownChangeToken + case unknownPeerID +} + +enum FakeCuttlefishOpinion { + case trusts + case trustsByPreapproval + case excludes +} + +struct FakeCuttlefishAssertion: CustomStringConvertible { + let peer: String + let opinion: FakeCuttlefishOpinion + let target: String + + func check(peer: Peer?, target: Peer?) -> Bool { + guard let peer = peer else { + return false + } + + guard peer.hasDynamicInfoAndSig else { + // No opinions? You've failed this assertion. + return false + } + + let dynamicInfo = TPPeerDynamicInfo(data: peer.dynamicInfoAndSig.peerDynamicInfo, sig: peer.dynamicInfoAndSig.sig) + guard let realDynamicInfo = dynamicInfo else { + return false + } + + let targetPermanentInfo: TPPeerPermanentInfo? = + target != nil ? TPPeerPermanentInfo(peerID: self.target, + data: target!.permanentInfoAndSig.peerPermanentInfo, + sig: target!.permanentInfoAndSig.sig, + keyFactory: TPECPublicKeyFactory()) + : nil + + switch self.opinion { + case .trusts: + return realDynamicInfo.includedPeerIDs.contains(self.target) + case .trustsByPreapproval: + guard let pubSignSPKI = targetPermanentInfo?.signingPubKey.spki() else { + return false + } + let hash = TPHashBuilder.hash(with: .SHA256, of: pubSignSPKI) + return realDynamicInfo.preapprovals.contains(hash) + case .excludes: + return realDynamicInfo.excludedPeerIDs.contains(self.target) + } + } + + var description: String { + return "DCA:(\(self.peer)\(self.opinion)\(self.target))" + } +} + +@objc class FakeCuttlefishNotify: NSObject { + let pushes: (Data) -> Void + let containerName: String + @objc init(_ containerName: String, pushes: @escaping (Data) -> Void) { + self.containerName = containerName + self.pushes = pushes + } + + @objc public func notify(_ function: String) throws { + let notification: [String: Dictionary] = [ + "aps": ["content-available": 1], + "cf": [ + "f": function, + "c": self.containerName, + ], + ] + let payload: Data + do { + payload = try JSONSerialization.data(withJSONObject: notification) + } catch { + throw error + } + self.pushes(payload) + } +} + +extension ViewKey { + func fakeRecord(zoneID: CKRecordZone.ID) -> CKRecord { + let recordID = CKRecord.ID(__recordName: self.uuid, zoneID: zoneID) + let record = CKRecord(recordType: SecCKRecordIntermediateKeyType, recordID: recordID) + + record[SecCKRecordWrappedKeyKey] = self.wrappedkeyBase64 + + switch(self.keyclass) { + case .tlk: + record[SecCKRecordKeyClassKey] = "tlk" + case .classA: + record[SecCKRecordKeyClassKey] = "classA" + case .classC: + record[SecCKRecordKeyClassKey] = "classC" + case .UNRECOGNIZED: + abort() + } + + if self.parentkeyUuid.count > 0 { + // TODO: no idea how to tell it about the 'verify' action + record[SecCKRecordParentKeyRefKey] = CKRecord.Reference(recordID: CKRecord.ID(__recordName: self.parentkeyUuid, zoneID: zoneID), action: .none) + } + + return record + } + + func fakeKeyPointer(zoneID: CKRecordZone.ID) -> CKRecord { + let recordName: String + switch(self.keyclass) { + case .tlk: + recordName = "tlk" + case .classA: + recordName = "classA" + case .classC: + recordName = "classC" + case .UNRECOGNIZED: + abort() + } + + let recordID = CKRecord.ID(__recordName: recordName, zoneID: zoneID) + let record = CKRecord(recordType: SecCKRecordCurrentKeyType, recordID: recordID) + + // TODO: no idea how to tell it about the 'verify' action + record[SecCKRecordParentKeyRefKey] = CKRecord.Reference(recordID: CKRecord.ID(__recordName: self.uuid, zoneID: zoneID), action: .none) + + return record + } +} + +extension TLKShare { + func fakeRecord(zoneID: CKRecordZone.ID) -> CKRecord { + let recordID = CKRecord.ID(__recordName: "tlkshare-\(self.keyUuid)::\(self.receiver)::\(self.sender)", zoneID: zoneID) + let record = CKRecord(recordType: SecCKRecordTLKShareType, recordID: recordID) + + record[SecCKRecordSenderPeerID] = self.sender + record[SecCKRecordReceiverPeerID] = self.receiver + record[SecCKRecordReceiverPublicEncryptionKey] = self.receiverPublicEncryptionKey + record[SecCKRecordCurve] = self.curve + record[SecCKRecordVersion] = self.version + record[SecCKRecordEpoch] = self.epoch + record[SecCKRecordPoisoned] = self.poisoned + + // TODO: no idea how to tell it about the 'verify' action + record[SecCKRecordParentKeyRefKey] = CKRecord.Reference(recordID: CKRecord.ID(__recordName: self.keyUuid, zoneID: zoneID), action: .none) + + record[SecCKRecordWrappedKeyKey] = self.wrappedkey + record[SecCKRecordSignature] = self.signature + + return record + } +} + +class FakeCuttlefishServer: CuttlefishAPIAsync { + + struct State { + var peersByID: [String: Peer] = [:] + var recoverySigningPubKey: Data? + var recoveryEncryptionPubKey: Data? + var bottles: [Bottle] = [] + + var viewKeys: [CKRecordZone.ID: ViewKeys] = [:] + var tlkShares: [CKRecordZone.ID: [TLKShare]] = [:] + + init() { + } + } + + var state = State() + var snapshotsByChangeToken: [String: State] = [:] + var currentChange: Int = 0 + var currentChangeToken: String = "" + let notify: FakeCuttlefishNotify? + + //var fakeCKZones: [CKRecordZone.ID: FakeCKZone] + var fakeCKZones: NSMutableDictionary + + // @property (nullable) NSMutableDictionary* keys; + var ckksZoneKeys: NSMutableDictionary + + var nextFetchErrors: [Error] = [] + var fetchViableBottlesError: [Error] = [] + var nextJoinErrors: [Error] = [] + var nextUpdateTrustErrors: [Error] = [] + var returnNoActionResponse: Bool = false + var returnRepairAccountResponse: Bool = false + var returnRepairEscrowResponse: Bool = false + var returnResetOctagonResponse: Bool = false + var returnRepairErrorResponse: Error? + var fetchChangesCalledCount: Int = 0 + + var nextEstablishReturnsMoreChanges: Bool = false + + var establishListener: ((EstablishRequest) -> NSError?)? + var updateListener: ((UpdateTrustRequest) -> NSError?)? + var fetchChangesListener: ((FetchChangesRequest) -> NSError?)? + var joinListener: ((JoinWithVoucherRequest) -> NSError?)? + var healthListener: ((GetRepairActionRequest) -> NSError?)? + var fetchViableBottlesListener: ((FetchViableBottlesRequest) -> NSError?)? + + var fetchViableBottlesDontReturnBottleWithID: String? + + init(_ notify: FakeCuttlefishNotify?, ckZones: NSMutableDictionary, ckksZoneKeys: NSMutableDictionary) { + self.notify = notify + self.fakeCKZones = ckZones + self.ckksZoneKeys = ckksZoneKeys + } + + func deleteAllPeers() { + self.state.peersByID.removeAll() + self.makeSnapshot() + } + + func pushNotify(_ function: String) { + if let notify = self.notify { + do { + try notify.notify(function) + } catch { + } + } + } + + static func makeCloudKitCuttlefishError(code: CuttlefishErrorCode) -> NSError { + return CKPrettyError(domain: CKInternalErrorDomain, + code: CKInternalErrorCode.errorInternalPluginError.rawValue, + userInfo: [NSUnderlyingErrorKey: NSError(domain: CuttlefishErrorDomain, + code: code.rawValue, + userInfo: nil)]) + } + + func makeSnapshot() { + self.currentChange += 1 + self.currentChangeToken = "change\(self.currentChange)" + self.snapshotsByChangeToken[self.currentChangeToken] = self.state + } + + func changesSince(snapshot: State) -> Changes { + return Changes.with { changes in + changes.changeToken = self.currentChangeToken + + changes.differences = self.state.peersByID.compactMap({ (key: String, value: Peer) -> PeerDifference? in + let old = snapshot.peersByID[key] + if old == nil { + return PeerDifference.with { + $0.add = value + } + } else if old != value { + return PeerDifference.with { + $0.update = value + } + } else { + return nil + } + }) + snapshot.peersByID.forEach { (key: String, _: Peer) in + if nil == self.state.peersByID[key] { + changes.differences.append(PeerDifference.with { + $0.remove = Peer.with { + $0.peerID = key + } + }) + } + } + + if self.state.recoverySigningPubKey != snapshot.recoverySigningPubKey { + changes.recoverySigningPubKey = self.state.recoverySigningPubKey ?? Data() + } + if self.state.recoveryEncryptionPubKey != snapshot.recoveryEncryptionPubKey { + changes.recoveryEncryptionPubKey = self.state.recoveryEncryptionPubKey ?? Data() + } + + } + } + + func reset(_ request: ResetRequest, completion: @escaping (ResetResponse?, Error?) -> Void) { + print("FakeCuttlefish: reset called") + self.state = State() + self.makeSnapshot() + completion(ResetResponse.with { + $0.changes = self.changesSince(snapshot: State()) + }, nil) + self.pushNotify("reset") + } + + func newKeysConflict(viewKeys: [ViewKeys]) -> Bool { + #if OCTAGON_TEST_FILL_ZONEKEYS + for keys in viewKeys { + let rzid = CKRecordZone.ID(zoneName: keys.view) + + if let currentViewKeys = self.ckksZoneKeys[rzid] as? CKKSCurrentKeySet { + // Uploading the current view keys is okay. Fail only if they don't match + if keys.newTlk.uuid != currentViewKeys.tlk!.uuid || + keys.newClassA.uuid != currentViewKeys.classA!.uuid || + keys.newClassC.uuid != currentViewKeys.classC!.uuid { + return true + } + } + } + #endif + + return false + } + + func store(viewKeys: [ViewKeys]) -> [CKRecord] { + var allRecords: [CKRecord] = [] + + viewKeys.forEach { viewKeys in + let rzid = CKRecordZone.ID(zoneName: viewKeys.view) + self.state.viewKeys[rzid] = viewKeys + + // Real cuttlefish makes these zones for you + if self.fakeCKZones[rzid] == nil { + self.fakeCKZones[rzid] = FakeCKZone(zone: rzid) + } + + if let fakeZone = self.fakeCKZones[rzid] as? FakeCKZone { + fakeZone.queue.sync { + let tlkRecord = viewKeys.newTlk.fakeRecord(zoneID: rzid) + let classARecord = viewKeys.newClassA.fakeRecord(zoneID: rzid) + let classCRecord = viewKeys.newClassC.fakeRecord(zoneID: rzid) + + let tlkPointerRecord = viewKeys.newTlk.fakeKeyPointer(zoneID: rzid) + let classAPointerRecord = viewKeys.newClassA.fakeKeyPointer(zoneID: rzid) + let classCPointerRecord = viewKeys.newClassC.fakeKeyPointer(zoneID: rzid) + + // Some tests don't link everything needed to make zonekeys + // Those tests don't get this nice behavior + #if OCTAGON_TEST_FILL_ZONEKEYS + let zoneKeys = self.ckksZoneKeys[rzid] as? ZoneKeys ?? ZoneKeys(forZoneName: rzid.zoneName) + self.ckksZoneKeys[rzid] = zoneKeys + + zoneKeys.tlk = CKKSKey(ckRecord: tlkRecord) + zoneKeys.classA = CKKSKey(ckRecord: classARecord) + zoneKeys.classC = CKKSKey(ckRecord: classCRecord) + + zoneKeys.currentTLKPointer = CKKSCurrentKeyPointer(ckRecord: tlkPointerRecord) + zoneKeys.currentClassAPointer = CKKSCurrentKeyPointer(ckRecord: classAPointerRecord) + zoneKeys.currentClassCPointer = CKKSCurrentKeyPointer(ckRecord: classCPointerRecord) + #endif + + let zoneRecords = [tlkRecord, + classARecord, + classCRecord, + tlkPointerRecord, + classAPointerRecord, + classCPointerRecord, ] + // TODO a rolled tlk too + + zoneRecords.forEach { record in + fakeZone._onqueueAdd(toZone: record) + } + allRecords.append(contentsOf: zoneRecords) + } + } else { + // we made the zone above, shoudn't ever get here + print("Received an unexpected zone id: \(rzid)") + abort() + } + } + return allRecords + } + + func store(tlkShares: [TLKShare]) -> [CKRecord] { + var allRecords: [CKRecord] = [] + + tlkShares.forEach { share in + let rzid = CKRecordZone.ID(zoneName: share.view) + + var c = self.state.tlkShares[rzid] ?? [] + c.append(share) + self.state.tlkShares[rzid] = c + + if let fakeZone = self.fakeCKZones[rzid] as? FakeCKZone { + let record = share.fakeRecord(zoneID: rzid) + fakeZone.add(toZone: record) + allRecords.append(record) + + } else { + print("Received an unexpected zone id: \(rzid)") + } + } + + return allRecords + } + + func establish(_ request: EstablishRequest, completion: @escaping (EstablishResponse?, Error?) -> Void) { + print("FakeCuttlefish: establish called") + if !self.state.peersByID.isEmpty { + completion(nil, FakeCuttlefishError.notEmpty) + } + + // Before performing write, check if we should error + if let establishListener = self.establishListener { + let possibleError = establishListener(request) + guard possibleError == nil else { + completion(nil, possibleError) + return; + } + } + + // Also check if we should bail due to conflicting viewKeys + if self.newKeysConflict(viewKeys: request.viewKeys) { + completion(nil, FakeCuttlefishServer.makeCloudKitCuttlefishError(code: .keyHierarchyAlreadyExists)) + return + } + + self.state.peersByID[request.peer.peerID] = request.peer + self.state.bottles.append(request.bottle) + + var keyRecords: [CKRecord] = [] + keyRecords.append(contentsOf: store(viewKeys: request.viewKeys)) + keyRecords.append(contentsOf: store(tlkShares: request.tlkShares)) + + self.makeSnapshot() + + + let response = EstablishResponse.with { + if self.nextEstablishReturnsMoreChanges { + $0.changes = Changes.with { + $0.more = true + } + self.nextEstablishReturnsMoreChanges = false + } else { + $0.changes = self.changesSince(snapshot: State()) + } + $0.zoneKeyHierarchyRecords = keyRecords.map { try! CloudKitCode.Ckcode_RecordTransport($0) } + } + + completion(response, nil) + self.pushNotify("establish") + } + + func joinWithVoucher(_ request: JoinWithVoucherRequest, completion: @escaping (JoinWithVoucherResponse?, Error?) -> Void) { + print("FakeCuttlefish: joinWithVoucher called") + + if let joinListener = self.joinListener { + let possibleError = joinListener(request) + guard possibleError == nil else { + completion(nil, possibleError) + return; + } + } + + if let injectedError = self.nextJoinErrors.first { + print("FakeCuttlefish: erroring with injected error: ", String(describing: injectedError)) + self.nextJoinErrors.removeFirst() + completion(nil, injectedError) + return + } + + // Also check if we should bail due to conflicting viewKeys + if self.newKeysConflict(viewKeys: request.viewKeys) { + completion(nil, FakeCuttlefishServer.makeCloudKitCuttlefishError(code: .keyHierarchyAlreadyExists)) + return + } + + guard let snapshot = self.snapshotsByChangeToken[request.changeToken] else { + completion(nil, FakeCuttlefishError.unknownChangeToken) + return + } + self.state.peersByID[request.peer.peerID] = request.peer + self.state.bottles.append(request.bottle) + + var keyRecords: [CKRecord] = [] + keyRecords.append(contentsOf: store(viewKeys: request.viewKeys)) + keyRecords.append(contentsOf: store(tlkShares: request.tlkShares)) + + self.makeSnapshot() + + completion(JoinWithVoucherResponse.with { + $0.changes = self.changesSince(snapshot: snapshot) + $0.zoneKeyHierarchyRecords = keyRecords.map { try! CloudKitCode.Ckcode_RecordTransport($0) } + }, nil) + self.pushNotify("joinWithVoucher") + } + + func updateTrust(_ request: UpdateTrustRequest, completion: @escaping (UpdateTrustResponse?, Error?) -> Void) { + print("FakeCuttlefish: updateTrust called: changeToken: ", request.changeToken, "peerID: ", request.peerID) + + if let injectedError = self.nextUpdateTrustErrors.first { + print("FakeCuttlefish: updateTrust erroring with injected error: ", String(describing: injectedError)) + self.nextUpdateTrustErrors.removeFirst() + completion(nil, injectedError) + return + } + + guard let snapshot = self.snapshotsByChangeToken[request.changeToken] else { + completion(nil, FakeCuttlefishError.unknownChangeToken) + return + } + guard var peer = self.state.peersByID[request.peerID] else { + completion(nil, FakeCuttlefishError.unknownPeerID) + return + } + if request.hasStableInfoAndSig { + peer.stableInfoAndSig = request.stableInfoAndSig + } + if request.hasDynamicInfoAndSig { + peer.dynamicInfoAndSig = request.dynamicInfoAndSig + } + self.state.peersByID[request.peerID] = peer + + // Before performing write, check if we should error + if let updateListener = self.updateListener { + let possibleError = updateListener(request) + guard possibleError == nil else { + completion(nil, possibleError) + return; + } + } + + // Also check if we should bail due to conflicting viewKeys + if self.newKeysConflict(viewKeys: request.viewKeys) { + completion(nil, FakeCuttlefishServer.makeCloudKitCuttlefishError(code: .keyHierarchyAlreadyExists)) + return + } + + var keyRecords: [CKRecord] = [] + keyRecords.append(contentsOf: store(viewKeys: request.viewKeys)) + keyRecords.append(contentsOf: store(tlkShares: request.tlkShares)) + + let newDynamicInfo = TPPeerDynamicInfo(data: peer.dynamicInfoAndSig.peerDynamicInfo, + sig: peer.dynamicInfoAndSig.sig) + print("FakeCuttlefish: new peer dynamicInfo: ", request.peerID, String(describing: newDynamicInfo?.dictionaryRepresentation())) + + self.makeSnapshot() + let response = UpdateTrustResponse.with { + $0.changes = self.changesSince(snapshot: snapshot) + $0.zoneKeyHierarchyRecords = keyRecords.map { try! CloudKitCode.Ckcode_RecordTransport($0) } + } + + completion(response, nil) + self.pushNotify("updateTrust") + } + + func setRecoveryKey(_ request: SetRecoveryKeyRequest, completion: @escaping (SetRecoveryKeyResponse?, Error?) -> Void) { + print("FakeCuttlefish: setRecoveryKey called") + guard let snapshot = self.snapshotsByChangeToken[request.changeToken] else { + completion(nil, FakeCuttlefishError.unknownChangeToken) + return + } + self.state.recoverySigningPubKey = request.recoverySigningPubKey + self.state.recoveryEncryptionPubKey = request.recoveryEncryptionPubKey + self.state.peersByID[request.peerID]?.stableInfoAndSig = request.stableInfoAndSig + self.makeSnapshot() + completion(SetRecoveryKeyResponse.with { + $0.changes = self.changesSince(snapshot: snapshot) + }, nil) + self.pushNotify("setRecoveryKey") + } + + func fetchChanges(_ request: FetchChangesRequest, completion: @escaping (FetchChangesResponse?, Error?) -> Void) { + print("FakeCuttlefish: fetchChanges called: ", request.changeToken) + + self.fetchChangesCalledCount += 1 + + if let fetchChangesListener = self.fetchChangesListener { + let possibleError = fetchChangesListener(request) + guard possibleError == nil else { + completion(nil, possibleError) + return; + } + } + + if let injectedError = self.nextFetchErrors.first { + print("FakeCuttlefish: fetchChanges erroring with injected error: ", String(describing: injectedError)) + self.nextFetchErrors.removeFirst() + completion(nil, injectedError) + return + } + + let snapshot: State + if request.changeToken == "" { + snapshot = State() + } else { + guard let s = self.snapshotsByChangeToken[request.changeToken] else { + completion(nil, FakeCuttlefishError.unknownChangeToken) + return + } + snapshot = s + } + let response = FetchChangesResponse.with { + $0.changes = self.changesSince(snapshot: snapshot) + } + + completion(response, nil) + } + + func fetchViableBottles(_ request: FetchViableBottlesRequest, completion: @escaping (FetchViableBottlesResponse?, Error?) -> Void) { + print("FakeCuttlefish: fetchViableBottles called") + + if let fetchViableBottlesListener = self.fetchViableBottlesListener { + let possibleError = fetchViableBottlesListener(request) + guard possibleError == nil else { + completion(nil, possibleError) + return; + } + } + + if let injectedError = self.fetchViableBottlesError.first { + print("FakeCuttlefish: fetchViableBottles erroring with injected error: ", String(describing: injectedError)) + self.fetchViableBottlesError.removeFirst() + completion(nil, injectedError) + return + } + + let bottles = self.state.bottles.filter { $0.bottleID != fetchViableBottlesDontReturnBottleWithID } + completion(FetchViableBottlesResponse.with { + $0.viableBottles = bottles.compactMap { bottle in + EscrowPair.with { + $0.escrowRecordID = bottle.bottleID + $0.bottle = bottle + } + } + }, nil) + } + + func fetchPolicyDocuments(_ request: FetchPolicyDocumentsRequest, + completion: @escaping (FetchPolicyDocumentsResponse?, Error?) -> Void) { + print("FakeCuttlefish: fetchPolicyDocuments called") + var response = FetchPolicyDocumentsResponse() + + let policies = builtInPolicyDocuments() + let dummyPolicies = Dictionary(uniqueKeysWithValues: policies.map({ ($0.policyVersion, ($0.policyHash, $0.protobuf)) })) + for key in request.keys { + guard let (hash, data) = dummyPolicies[key.version] else { + continue + } + if hash == key.hash { + response.entries.append(PolicyDocumentMapEntry.with { $0.key = key; $0.value = data }) + } + } + completion(response, nil) + } + + func assertCuttlefishState(_ assertion: FakeCuttlefishAssertion) -> Bool { + return assertion.check(peer: self.state.peersByID[assertion.peer], target: self.state.peersByID[assertion.target]) + } + + func validatePeers(_: ValidatePeersRequest, completion: @escaping (ValidatePeersResponse?, Error?) -> Void) { + var response = ValidatePeersResponse() + response.validatorsHealth = 0.0 + response.results = [] + completion(response, nil) + } + func reportHealth(_: ReportHealthRequest, completion: @escaping (ReportHealthResponse?, Error?) -> Void) { + completion(ReportHealthResponse(), nil) + } + func pushHealthInquiry(_: HealthInquiryRequest, completion: @escaping (HealthInquiryResponse?, Error?) -> Void) { + completion(HealthInquiryResponse(), nil) + } + + func getRepairAction(_ request: GetRepairActionRequest, completion: @escaping (GetRepairActionResponse?, Error?) -> Void) { + print("FakeCuttlefish: getRepairAction called") + + if let healthListener = self.healthListener { + let possibleError = healthListener(request) + guard possibleError == nil else { + completion(nil, possibleError) + return; + } + } + + if self.returnRepairEscrowResponse { + let response = GetRepairActionResponse.with { + $0.repairAction = .postRepairEscrow + } + completion(response, nil) + } + else if self.returnRepairAccountResponse { + let response = GetRepairActionResponse.with { + $0.repairAction = .postRepairAccount + } + completion(response, nil) + } + else if self.returnResetOctagonResponse { + let response = GetRepairActionResponse.with { + $0.repairAction = .resetOctagon + } + completion(response, nil) + } + else if self.returnNoActionResponse { + let response = GetRepairActionResponse.with { + $0.repairAction = .noAction + } + completion(response, nil) + } else if self.returnRepairErrorResponse != nil { + let response = GetRepairActionResponse.with { + $0.repairAction = .noAction + } + completion(response, self.returnRepairErrorResponse) + } + else { + completion(GetRepairActionResponse(), nil) + } + } +} + +extension FakeCuttlefishServer : CloudKitCode.Invocable { + func invoke(function: String, + request: RequestType, + completion: @escaping (ResponseType?, Error?) -> Void) { + // Ideally we'd pattern match on both request and completion, but that crashes the swift compiler at this time () + switch request { + case let request as ResetRequest: + self.reset(request, completion: completion as! (ResetResponse?, Error?) -> Void) + return + case let request as EstablishRequest: + self.establish(request, completion: completion as! (EstablishResponse?, Error?) -> Void) + return + case let request as JoinWithVoucherRequest: + self.joinWithVoucher(request, completion: completion as! (JoinWithVoucherResponse?, Error?) -> Void) + return + case let request as UpdateTrustRequest: + self.updateTrust(request, completion: completion as! (UpdateTrustResponse?, Error?) -> Void) + return + case let request as SetRecoveryKeyRequest: + self.setRecoveryKey(request, completion: completion as! (SetRecoveryKeyResponse?, Error?) -> Void) + return + case let request as FetchChangesRequest: + self.fetchChanges(request, completion: completion as! (FetchChangesResponse?, Error?) -> Void) + return + case let request as FetchViableBottlesRequest: + self.fetchViableBottles(request, completion: completion as! (FetchViableBottlesResponse?, Error?) -> Void) + return + case let request as FetchPolicyDocumentsRequest: + self.fetchPolicyDocuments(request, completion: completion as! (FetchPolicyDocumentsResponse?, Error?) -> Void) + return + case let request as ValidatePeersRequest: + self.validatePeers(request, completion: completion as! (ValidatePeersResponse?, Error?) -> Void) + return + case let request as ReportHealthRequest: + self.reportHealth(request, completion: completion as! (ReportHealthResponse?, Error?) -> Void) + return + case let request as HealthInquiryRequest: + self.pushHealthInquiry(request, completion: completion as! (HealthInquiryResponse?, Error?) -> Void) + return + case let request as GetRepairActionRequest: + self.getRepairAction(request, completion: completion as! (GetRepairActionResponse?, Error?) -> Void) + return + default: + abort() + } + } +} diff --git a/SecurityUnitTests/Info.plist b/keychain/TrustedPeersHelperUnitTests/Info.plist similarity index 100% rename from SecurityUnitTests/Info.plist rename to keychain/TrustedPeersHelperUnitTests/Info.plist diff --git a/keychain/TrustedPeersHelperUnitTests/MockCuttlefish.swift b/keychain/TrustedPeersHelperUnitTests/MockCuttlefish.swift new file mode 100644 index 00000000..5c0ee671 --- /dev/null +++ b/keychain/TrustedPeersHelperUnitTests/MockCuttlefish.swift @@ -0,0 +1,169 @@ +// +// MockCuttlefish.swift +// TrustedPeersHelperUnitTests +// +// Created by Ben Williamson on 5/1/18. +// + +import Foundation +import XCTest + +enum Handler { + case reset((ResetRequest, @escaping (ResetResponse?, Error?) -> Void) -> Void) + case establish((EstablishRequest, @escaping (EstablishResponse?, Error?) -> Void) -> Void) + case joinWithVoucher((JoinWithVoucherRequest, @escaping (JoinWithVoucherResponse?, Error?) -> Void) -> Void) + case updateTrust((UpdateTrustRequest, @escaping (UpdateTrustResponse?, Error?) -> Void) -> Void) + case setRecoveryKey((SetRecoveryKeyRequest, @escaping (SetRecoveryKeyResponse?, Error?) -> Void) -> Void) + case fetchChanges((FetchChangesRequest, @escaping (FetchChangesResponse?, Error?) -> Void) -> Void) + case fetchViableBottles((FetchViableBottlesRequest, @escaping (FetchViableBottlesResponse?, Error?) -> Void) ->Void) + case fetchPolicyDocuments((FetchPolicyDocumentsRequest, + @escaping (FetchPolicyDocumentsResponse?, Error?) -> Void) -> Void) +} + +class MockCuttlefishAPIAsyncClient: CuttlefishAPIAsync { + + var handlers: [Handler] = [] + var index: Int = 0 + + func expect(_ handler: Handler) { + self.handlers.append(handler) + } + + func next() -> Handler { + if index >= handlers.count { + XCTFail("MockCuttlefish: Not expecting any more calls.") + self.dump() + abort() + } + return handlers[index] + } + + func dump() { + print("---") + for i in 0 ..< handlers.count { + print("\(i) \(i == index ? "->" : " ") \(handlers[i])") + } + print("---") + } + + func reset(_ request: ResetRequest, completion: @escaping (ResetResponse?, Error?) -> Void) { + print("MockCuttlefish: reset called") + if case .reset(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: reset") + print("Unexpected: reset") + self.dump() + abort() + } + } + + func establish(_ request: EstablishRequest, completion: @escaping (EstablishResponse?, Error?) -> Void) { + print("MockCuttlefish: establish called") + if case .establish(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: establish") + print("Unexpected: establish") + self.dump() + abort() + } + } + + func joinWithVoucher(_ request: JoinWithVoucherRequest, + completion: @escaping (JoinWithVoucherResponse?, Error?) -> Void) { + print("MockCuttlefish: joinWithVoucher called") + if case .joinWithVoucher(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: joinWithVoucher") + print("Unexpected: joinWithVoucher") + self.dump() + abort() + } + } + + func updateTrust(_ request: UpdateTrustRequest, completion: @escaping (UpdateTrustResponse?, Error?) -> Void) { + print("MockCuttlefish: updateTrust called") + if case .updateTrust(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: updateTrust") + print("Unexpected: updateTrust") + self.dump() + abort() + } + } + + func setRecoveryKey(_ request: SetRecoveryKeyRequest, + completion: @escaping (SetRecoveryKeyResponse?, Error?) -> Void) { + print("MockCuttlefish: setRecoveryKey called") + if case .setRecoveryKey(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: setRecoveryKey") + print("Unexpected: setRecoveryKey") + self.dump() + abort() + } + } + + func fetchChanges(_ request: FetchChangesRequest, completion: @escaping (FetchChangesResponse?, Error?) -> Void) { + print("MockCuttlefish: fetchChanges called") + if case .fetchChanges(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: fetchChanges") + print("Unexpected: fetchChanges") + self.dump() + abort() + } + } + + func fetchViableBottles(_ request: FetchViableBottlesRequest, completion: @escaping (FetchViableBottlesResponse?, Error?) -> Void) { + print("MockCuttlefish: fetchViableBottles called") + if case .fetchViableBottles(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: fetchViableBottles") + self.dump() + abort() + } + } + + func fetchPolicyDocuments(_ request: FetchPolicyDocumentsRequest, + completion: @escaping (FetchPolicyDocumentsResponse?, Error?) -> Void) { + print("MockCuttlefish: fetchPolicyDocuments called") + if case .fetchPolicyDocuments(let f) = next() { + index += 1 + f(request, completion) + } else { + XCTFail("Unexpected: fetchPolicyDocuments") + print("Unexpected: fetchPolicyDocuments") + self.dump() + abort() + } + } + + func validatePeers(_: ValidatePeersRequest, completion: @escaping (ValidatePeersResponse?, Error?) -> Void) { + completion(ValidatePeersResponse(), nil) + } + func reportHealth(_: ReportHealthRequest, completion: @escaping (ReportHealthResponse?, Error?) -> Void) { + print("MockCuttlefish: reportHealth called") + completion(ReportHealthResponse(), nil) + } + func pushHealthInquiry(_: HealthInquiryRequest, completion: @escaping (HealthInquiryResponse?, Error?) -> Void) { + completion(HealthInquiryResponse(), nil) + } + func getRepairAction(_: GetRepairActionRequest, completion: @escaping (GetRepairActionResponse?, Error?) -> Void) { + completion(GetRepairActionResponse(), nil) + + } +} diff --git a/keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests-BridgingHeader.h b/keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests-BridgingHeader.h new file mode 100644 index 00000000..b74e57ec --- /dev/null +++ b/keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests-BridgingHeader.h @@ -0,0 +1,23 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import "utilities/SecFileLocations.h" +#import "utilities/SecCFError.h" + + +#import "securityd/SecItemServer.h" +#import "securityd/spi.h" + +#import +#import "keychain/ckks/CKKS.h" + +#import +#import +#import +#import + +#import "keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h" + +#import "keychain/ckks/tests/MockCloudKit.h" diff --git a/keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests.swift b/keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests.swift new file mode 100644 index 00000000..0c6f1ef1 --- /dev/null +++ b/keychain/TrustedPeersHelperUnitTests/TrustedPeersHelperUnitTests.swift @@ -0,0 +1,2409 @@ +// +// TrustedPeersHelperUnitTests.swift +// TrustedPeersHelperUnitTests +// +// Created by Ben Williamson on 5/1/18. +// + +import CoreData +import XCTest + +let testDSID = "123456789" + +let signingKey_384 = Data(base64Encoded: "BOQbPoiBnzuA0Cgc2QegjKGJqDtpkRenHwAxkYKJH1xELdaoIh8ifSch8sl18tpBYVUpEfdxz2ZSKif+dx7UPfu8WeTtpHkqm3M+9PTjr/KNNJCSR1PQNB5Jh+sRiQ+cpJnoTzm+IZSIukylamAcL3eA0nMUM0Zc2u4TijrbTgVND22WzSirUkwSK3mA/prk9A==") + +let encryptionKey_384 = Data(base64Encoded: "BE1RuazBWmSEx0XVGhobbrdSE6fRQOrUrYEQnBkGl4zJq9GCeRoYvbuWNYFcOH0ijCRz9pYILsTn3ajT1OknlvcKmuQ7SeoGWzk9cBZzT5bBEwozn2gZxn80DQoDkmejywlH3D0/cuV6Bxexu5KMAFGqg6eN6th4sQABL5EuI9zKPuxHStM/b9B1LyqcnRKQHA==") + +let symmetricKey_384 = Data(base64Encoded: "MfHje3Y/mWV0q+grjwZ4VxuqB7OreYHLxYkeeCiNjjY=") + +class TrustedPeersHelperUnitTests: XCTestCase { + + var tmpPath: String! + var tmpURL: URL! + var cuttlefish: FakeCuttlefishServer! + + var manateeKeySet: CKKSKeychainBackedKeySet! + + override static func setUp() { + super.setUp() + + SecTapToRadar.disableTTRsEntirely() + + // Turn on NO_SERVER stuff + securityd_init_local_spi() + + SecCKKSDisable() + } + + override func setUp() { + super.setUp() + + let testName = self.name.components(separatedBy: CharacterSet(charactersIn: " ]"))[1] + cuttlefish = FakeCuttlefishServer(nil, ckZones: [:], ckksZoneKeys: [:]) + + // Make a new fake keychain + tmpPath = String(format: "/tmp/%@-%X", testName, arc4random()) + tmpURL = URL(fileURLWithPath: tmpPath, isDirectory: true) + do { + try FileManager.default.createDirectory(atPath: String(format: "%@/Library/Keychains", tmpPath), withIntermediateDirectories: true, attributes: nil) + SetCustomHomeURLString(tmpPath as CFString) + SecKeychainDbReset(nil) + } catch { + XCTFail("setUp failed: \(error)") + } + + // Actually load the database. + kc_with_dbt(true, nil) { _ in + false + } + + // Now that the keychain is alive, perform test setup + do { + self.manateeKeySet = try self.makeFakeKeyHierarchy(zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } catch { + XCTFail("Creation of fake key hierarchies failed: \(error)") + } + } + + override func tearDown() { + // Put teardown code here. This method is called after the invocation of each test method in the class. + cuttlefish = nil + super.tearDown() + } + + func makeFakeKeyHierarchy(zoneID: CKRecordZone.ID) throws -> CKKSKeychainBackedKeySet { + // Remember, these keys come into TPH having round-tripped through an NSEncoding + let tlk = try CKKSKeychainBackedKey.randomKeyWrapped(bySelf: zoneID) + let classA = try CKKSKeychainBackedKey.randomKeyWrapped(byParent: tlk, keyclass: SecCKKSKeyClassA) + let classC = try CKKSKeychainBackedKey.randomKeyWrapped(byParent: tlk, keyclass: SecCKKSKeyClassC) + + XCTAssertNoThrow(try tlk.saveMaterialToKeychain(), "Should be able to save TLK to keychain") + XCTAssertNoThrow(try classA.saveMaterialToKeychain(), "Should be able to save classA key to keychain") + XCTAssertNoThrow(try classC.saveMaterialToKeychain(), "Should be able to save classC key to keychain") + + let tlkData = try NSKeyedArchiver.archivedData(withRootObject: tlk, requiringSecureCoding: true) + let classAData = try NSKeyedArchiver.archivedData(withRootObject: classA, requiringSecureCoding: true) + let classCData = try NSKeyedArchiver.archivedData(withRootObject: classC, requiringSecureCoding: true) + + let decodedTLK = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [CKKSKeychainBackedKey.classForKeyedUnarchiver()], from: tlkData) as! CKKSKeychainBackedKey + let decodedClassA = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [CKKSKeychainBackedKey.classForKeyedUnarchiver()], from: classAData) as! CKKSKeychainBackedKey + let decodedClassC = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [CKKSKeychainBackedKey.classForKeyedUnarchiver()], from: classCData) as! CKKSKeychainBackedKey + + return CKKSKeychainBackedKeySet(tlk: decodedTLK, classA: decodedClassA, classC: decodedClassC, newUpload: false) + } + + func assertTLKShareFor(peerID: String, keyUUID: String, zoneID: CKRecordZone.ID) { + let matches = self.cuttlefish.state.tlkShares[zoneID]?.filter { tlkShare in + tlkShare.receiver == peerID && + tlkShare.keyUuid == keyUUID + } + + XCTAssertEqual(matches?.count ?? 0, 1, "Should have one tlk share matching \(peerID) and \(keyUUID)") + } + + func assertNoTLKShareFor(peerID: String, keyUUID: String, zoneID: CKRecordZone.ID) { + let matches = self.cuttlefish.state.tlkShares[zoneID]?.filter { tlkShare in + tlkShare.receiver == peerID && + tlkShare.keyUuid == keyUUID + } + + XCTAssertEqual(matches?.count ?? 0, 0, "Should have no tlk share matching \(peerID) and \(keyUUID)") + } + + func assertTrusts(context: Container, peerIDs: [String]) { + let state = context.getStateSync(test: self) + guard let egoPeerID = state.egoPeerID else { + XCTFail("context should have an ego peer ID") + return + } + + guard let dynamicInfo = state.peers[egoPeerID]?.dynamicInfo else { + XCTFail("No dynamicInfo for ego peer") + return + } + + _ = peerIDs.map { + XCTAssertTrue(dynamicInfo.includedPeerIDs.contains($0), "Peer should trust \($0)") + XCTAssertFalse(dynamicInfo.excludedPeerIDs.contains($0), "Peer should not distrust \($0)") + } + } + + func assertDistrusts(context: Container, peerIDs: [String]) { + let state = context.getStateSync(test: self) + guard let egoPeerID = state.egoPeerID else { + XCTFail("context should have an ego peer ID") + return + } + + guard let dynamicInfo = state.peers[egoPeerID]?.dynamicInfo else { + XCTFail("No dynamicInfo for ego peer") + return + } + + _ = peerIDs.map { + XCTAssertFalse(dynamicInfo.includedPeerIDs.contains($0), "Peer should not trust \($0)") + XCTAssertTrue(dynamicInfo.excludedPeerIDs.contains($0), "Peer should distrust \($0)") + } + } + + func tmpStoreDescription(name: String) -> NSPersistentStoreDescription { + let tmpStoreURL = URL(fileURLWithPath: name, relativeTo: tmpURL) + return NSPersistentStoreDescription(url: tmpStoreURL) + } + + func establish(reload: Bool, + store: NSPersistentStoreDescription) throws -> (Container, String) { + return try self.establish(reload: reload, contextID: OTDefaultContext, store: store) + } + + func establish(reload: Bool, + contextID: String, + store: NSPersistentStoreDescription) throws -> (Container, String) { + var container = try Container(name: ContainerName(container: "test", context: contextID), persistentStoreDescription: store, cuttlefish: cuttlefish) + + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb", "ccc"]), "should be able to set allowed machine IDs") + + let (peerID, permanentInfo, permanentInfoSig, _, _, error) = container.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = container.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == peerID } .isEmpty, "should have a bottle for peer") + let secret = container.loadSecretSync(test: self, label: peerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNotNil(peerID) + XCTAssertNotNil(permanentInfo) + XCTAssertNotNil(permanentInfoSig) + XCTAssertNil(error) + + _ = container.dumpSync(test: self) + + if (reload) { + do { + container = try Container(name: ContainerName(container: "test", context: contextID), persistentStoreDescription: store, cuttlefish: cuttlefish) + } catch { + XCTFail() + } + } + + let (peerID2, _, error2) = container.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error2) + XCTAssertNotNil(peerID2) + + _ = container.dumpSync(test: self) + + return (container, peerID!) + } + + func testEstablishWithReload() throws { + let description = tmpStoreDescription(name: "container.db") + let (_, peerID) = try establish(reload: true, store: description) + + assertTLKShareFor(peerID: peerID, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + + func testEstablishNoReload() throws { + let description = tmpStoreDescription(name: "container.db") + _ = try establish(reload: false, store: description) + } + + func testEstablishNotOnAllowListErrors() throws { + let description = tmpStoreDescription(name: "container.db") + let container = try Container(name: ContainerName(container: "test", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let (peerID, permanentInfo, permanentInfoSig, _, _, error) = container.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = container.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == peerID } .isEmpty, "should have a bottle for peer") + let secret = container.loadSecretSync(test: self, label: peerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNotNil(peerID) + XCTAssertNotNil(permanentInfo) + XCTAssertNotNil(permanentInfoSig) + XCTAssertNil(error) + + // Note that an empty machine ID list means "all are allowed", so an establish now will succeed + + // Now set up a machine ID list that positively does not have our peer + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa"]), "should be able to set allowed machine IDs") + + let (peerID3, _, error3) = container.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNotNil(peerID3, "Should get a peer when you establish a now allow-listed peer") + XCTAssertNil(error3, "Should not get an error when you establish a now allow-listed peer") + } + + func joinByVoucher(sponsor: Container, + containerID: String, + machineID: String, + machineIDs: Set, + store: NSPersistentStoreDescription) throws -> (Container, String) { + let c = try Container(name: ContainerName(container: containerID, context: OTDefaultContext), + persistentStoreDescription: store, + cuttlefish: cuttlefish) + + XCTAssertNil(c.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs), "Should be able to set machine IDs") + + print("preparing \(containerID)") + let (peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error) = + c.prepareSync(test: self, epoch: 1, machineID: machineID, bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + XCTAssertNil(error) + XCTAssertNotNil(peerID) + XCTAssertNotNil(permanentInfo) + XCTAssertNotNil(permanentInfoSig) + XCTAssertNotNil(stableInfo) + XCTAssertNotNil(stableInfoSig) + + do { + assertNoTLKShareFor(peerID: peerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("\(sponsor) vouches for \(containerID)") + let (voucherData, voucherSig, vouchError) = + sponsor.vouchSync(test: self, + peerID: peerID!, + permanentInfo: permanentInfo!, + permanentInfoSig: permanentInfoSig!, + stableInfo: stableInfo!, + stableInfoSig: stableInfoSig!, + ckksKeys: [self.manateeKeySet]) + XCTAssertNil(vouchError) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + // As part of the join, the sponsor should have uploaded a tlk share + assertTLKShareFor(peerID: peerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("\(containerID) joins") + let (joinedPeerID, _, joinError) = c.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: []) + XCTAssertNil(joinError) + XCTAssertEqual(joinedPeerID, peerID!) + } + + return (c, peerID!) + } + + func testJoin() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerC = try Container(name: ContainerName(container: "c", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb", "ccc"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerC.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + + print("preparing B") + let (bPeerID, bPermanentInfo, bPermanentInfoSig, bStableInfo, bStableInfoSig, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + XCTAssertNotNil(bPeerID) + XCTAssertNotNil(bPermanentInfo) + XCTAssertNotNil(bPermanentInfoSig) + + do { + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + print("A vouches for B, but doesn't provide any TLKShares") + let (_, _, errorVouchingWithoutTLKs) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: []) + XCTAssertNil(errorVouchingWithoutTLKs, "Should be no error vouching without uploading TLKShares") + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("A vouches for B, but doesn't only has provisional TLKs at the time") + let provisionalManateeKeySet = try self.makeFakeKeyHierarchy(zoneID: CKRecordZone.ID(zoneName: "Manatee")) + provisionalManateeKeySet.newUpload = true + + let (_, _, errorVouchingWithProvisionalTLKs) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: [provisionalManateeKeySet]) + XCTAssertNil(errorVouchingWithProvisionalTLKs, "Should be no error vouching without uploading TLKShares for a non-existent key") + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("A vouches for B") + let (voucherData, voucherSig, error3) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: [self.manateeKeySet]) + XCTAssertNil(error3) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + // As part of the vouch, A should have uploaded a tlkshare for B + assertTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("B joins") + let (peerID, _, error) = containerB.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: []) + XCTAssertNil(error) + XCTAssertEqual(peerID, bPeerID!) + } + + _ = containerA.dumpSync(test: self) + _ = containerB.dumpSync(test: self) + _ = containerC.dumpSync(test: self) + + print("preparing C") + let (cPeerID, cPermanentInfo, cPermanentInfoSig, cStableInfo, cStableInfoSig, error4) = + containerC.prepareSync(test: self, epoch: 1, machineID: "ccc", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerC.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == cPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerC.loadSecretSync(test: self, label: cPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error4) + XCTAssertNotNil(cPeerID) + XCTAssertNotNil(cPermanentInfo) + XCTAssertNotNil(cPermanentInfoSig) + + do { + // C, when it joins, will create a new CKKS zone. It should also upload TLKShares for A and B. + let provisionalEngramKeySet = try self.makeFakeKeyHierarchy(zoneID: CKRecordZone.ID(zoneName: "Engram")) + provisionalEngramKeySet.newUpload = true + + assertNoTLKShareFor(peerID: cPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + assertNoTLKShareFor(peerID: cPeerID!, keyUUID: provisionalEngramKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Engram")) + + print("B vouches for C") + let (voucherData, voucherSig, error) = + containerB.vouchSync(test: self, + peerID: cPeerID!, + permanentInfo: cPermanentInfo!, + permanentInfoSig: cPermanentInfoSig!, + stableInfo: cStableInfo!, + stableInfoSig: cStableInfoSig!, + ckksKeys: [self.manateeKeySet]) + XCTAssertNil(error) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + assertTLKShareFor(peerID: cPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("C joins") + let (peerID, _, error2) = containerC.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [self.manateeKeySet, provisionalEngramKeySet], + tlkShares: []) + XCTAssertNil(error2) + XCTAssertEqual(peerID, cPeerID!) + + assertTLKShareFor(peerID: cPeerID!, keyUUID: provisionalEngramKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Engram")) + assertTLKShareFor(peerID: aPeerID!, keyUUID: provisionalEngramKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Engram")) + assertTLKShareFor(peerID: bPeerID!, keyUUID: provisionalEngramKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Engram")) + } + + print("A updates") + do { + let (_, error) = containerA.updateSync(test: self) + XCTAssertNil(error) + } + + do { + let state = containerA.getStateSync(test: self) + let a = state.peers[aPeerID!]! + XCTAssertTrue(a.dynamicInfo!.includedPeerIDs.contains(cPeerID!)) + } + + _ = containerA.dumpSync(test: self) + _ = containerB.dumpSync(test: self) + _ = containerC.dumpSync(test: self) + } + + func testJoinWithoutAllowListErrors() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let (peerID, permanentInfo, permanentInfoSig, _, _, error) = containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == peerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: peerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error, "Should not have an error after preparing A") + XCTAssertNotNil(peerID, "Should have a peer ID after preparing A") + XCTAssertNotNil(permanentInfo, "Should have a permanent info after preparing A") + XCTAssertNotNil(permanentInfoSig, "Should have a signature after preparing A") + + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa"]), "should be able to set allowed machine IDs") + + let (peerID2, _, error2) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNotNil(peerID2, "Should get a peer when you establish a now allow-listed peer") + XCTAssertNil(error2, "Should not get an error when you establish a now allow-listed peer") + + print("preparing B") + let (bPeerID, bPermanentInfo, bPermanentInfoSig, bStableInfo, bStableInfoSig, errorPrepareB) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == peerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: peerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(errorPrepareB, "Should not have an error after preparing B") + XCTAssertNotNil(bPeerID, "Should have a peer ID after preparing B") + XCTAssertNotNil(bPermanentInfo, "Should have a permanent info after preparing B") + XCTAssertNotNil(bPermanentInfoSig, "Should have a signature after preparing B") + + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa"]), "should be able to set allowed machine IDs on container B") + + do { + print("A vouches for B") + let (voucherData, voucherSig, error3) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: []) + XCTAssertNil(error3, "Should be no error vouching for B") + XCTAssertNotNil(voucherData, "Should have a voucher from A") + XCTAssertNotNil(voucherSig, "Should have a signature from A") + + print("B joins") + let (peerID, _, error) = containerB.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: []) + XCTAssertNotNil(error, "Should have an error joining with an unapproved machine ID") + XCTAssertNil(peerID, "Should not receive a peer ID joining with an unapproved machine ID") + } + } + + func testReset() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + assertNoTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + assertTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + + print("reset A") + do { + let error = containerA.resetSync(test: self) + XCTAssertNil(error) + } + do { + let (dict, error) = containerA.dumpSync(test: self) + XCTAssertNil(error) + XCTAssertNotNil(dict) + let peers: Array = dict!["peers"] as! Array + XCTAssertEqual(0, peers.count) + } + } + + func testResetLocal() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error, "Should be no error preparing an identity") + XCTAssertNotNil(aPeerID, "Should have a peer ID after preparing") + XCTAssertNotNil(aPermanentInfo, "Should have a permanentInfo after preparing") + XCTAssertNotNil(aPermanentInfoSig, "Should have a permanentInfoSign after preparing") + + do { + let (dict, error) = containerA.dumpSync(test: self) + XCTAssertNil(error, "Should be no error dumping") + XCTAssertNotNil(dict, "Should receive a dump dictionary") + + let selfInfo: [AnyHashable: Any]? = dict!["self"] as! [AnyHashable: Any]? + XCTAssertNotNil(selfInfo, "Should have a self dictionary") + + let selfPeer: String? = selfInfo!["peerID"] as! String? + XCTAssertNotNil(selfPeer, "self peer should be part of the dump") + } + + do { + let error = containerA.localResetSync(test: self) + XCTAssertNil(error, "local-reset shouldn't error") + } + do { + let (dict, error) = containerA.dumpSync(test: self) + + XCTAssertNil(error, "Should be no error dumping") + XCTAssertNotNil(dict, "Should receive a dump dictionary") + + let selfInfo: [AnyHashable: Any]? = dict!["self"] as! [AnyHashable: Any]? + XCTAssertNotNil(selfInfo, "Should have a self dictionary") + + let selfPeer: String? = selfInfo!["peerID"] as! String? + XCTAssertNil(selfPeer, "self peer should not be part of the dump") + } + } + + func testReplayAttack() throws { + let description = tmpStoreDescription(name: "container.db") + var containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerC = try Container(name: ContainerName(container: "c", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]))) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]))) + XCTAssertNil(containerC.setAllowedMachineIDsSync(test: self, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]))) + + print("preparing") + let (peerID, _, _, _, _, _) = containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == peerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: peerID!) + XCTAssertNotNil(secret, "secret should not be nil") + } + let (bPeerID, bPermanentInfo, bPermanentInfoSig, bStableInfo, bStableInfoSig, _) = containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + } + let (cPeerID, cPermanentInfo, cPermanentInfoSig, cStableInfo, cStableInfoSig, _) = containerC.prepareSync(test: self, epoch: 1, machineID: "ccc", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerC.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == cPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerC.loadSecretSync(test: self, label: cPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + } + print("establishing A") + _ = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + + do { + print("A vouches for B") + let (voucherData, voucherSig, _) = containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: []) + + print("B joins") + _ = containerB.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: []) + } + + print("A updates") + _ = containerA.updateSync(test: self) + let earlyClock: TPCounter + do { + let state = containerA.getStateSync(test: self) + let b = state.peers[bPeerID!]! + earlyClock = b.dynamicInfo!.clock + } + + // Take a snapshot + let snapshot = cuttlefish.state + + do { + print("B vouches for C") + let (voucherData, voucherSig, _) = containerB.vouchSync(test: self, peerID: cPeerID!, + permanentInfo: cPermanentInfo!, + permanentInfoSig: cPermanentInfoSig!, + stableInfo: cStableInfo!, + stableInfoSig: cStableInfoSig!, + ckksKeys: []) + + print("C joins") + _ = containerC.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: []) + } + + print("B updates") + _ = containerB.updateSync(test: self) + + print("A updates") + _ = containerA.updateSync(test: self) + let lateClock: TPCounter + do { + let state = containerA.getStateSync(test: self) + let b = state.peers[bPeerID!]! + lateClock = b.dynamicInfo!.clock + XCTAssertTrue(earlyClock < lateClock) + } + + print("Reverting cuttlefish to the snapshot") + cuttlefish.state = snapshot + cuttlefish.makeSnapshot() + + print("A updates, fetching the old snapshot from cuttlefish") + _ = containerA.updateSync(test: self) + + print("Reload A. Now we see whether it persisted the replayed snapshot in the previous step.") + containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + do { + let state = containerA.getStateSync(test: self) + let b = state.peers[bPeerID!]! + XCTAssertEqual(lateClock, b.dynamicInfo!.clock) + } + } + + // TODO: need a real configurable mock cuttlefish + func testFetchPolicyDocuments() throws { + + // 1 is known locally via builtin, 3 is not but is known to cuttlefish + let policies = + [ + 1: ("SHA256:TLXrcQmY4ue3oP5pCX1pwsi9BF8cKfohlJBilCroeBs=", + "CAESDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSCwoDTWFjEgRmdWxsEgwKBGlNYWMSBGZ1bGwSDQoHQXBwbGVUVhICdHYS" + + "DgoFV2F0Y2gSBXdhdGNoGhEKCVBDU0VzY3JvdxIEZnVsbBoXCgRXaUZpEgRmdWxsEgJ0dhIFd2F0Y2gaGQoRU2FmYXJpQ3JlZGl0" + + "Q2FyZHMSBGZ1bGwiDAoEZnVsbBIEZnVsbCIUCgV3YXRjaBIEZnVsbBIFd2F0Y2giDgoCdHYSBGZ1bGwSAnR2"), + 3: ("SHA256:JZzazSuHXrUhiOfSgElsg6vYKpnvvEPVpciR8FewRWg=", + "CAMSDgoGaVBob25lEgRmdWxsEgwKBGlQYWQSBGZ1bGwSCwoDTWFjEgRmdWxsEgwKBGlNYWMSBGZ1bGwSDQoHQXBwbGVUVhICdHYSDgoFV2F0Y2gSBXdhdGNoEhcKDkF1ZGlvQWNjZXNzb3J5EgVhdWRpbxocCg1EZXZpY2VQYWlyaW5nEgRmdWxsEgV3YXRjaBoXCghBcHBsZVBheRIEZnVsbBIFd2F0Y2gaJAoVUHJvdGVjdGVkQ2xvdWRTdG9yYWdlEgRmdWxsEgV3YXRjaBoXCghCYWNrc3RvcBIEZnVsbBIFd2F0Y2gaGQoKQXV0b1VubG9jaxIEZnVsbBIFd2F0Y2gaHwoQU2VjdXJlT2JqZWN0U3luYxIEZnVsbBIFd2F0Y2gaIAoRU2FmYXJpQ3JlZGl0Q2FyZHMSBGZ1bGwSBXdhdGNoGhMKBEhvbWUSBGZ1bGwSBXdhdGNoGh4KD1NhZmFyaVBhc3N3b3JkcxIEZnVsbBIFd2F0Y2gaGwoMQXBwbGljYXRpb25zEgRmdWxsEgV3YXRjaBoVCgZFbmdyYW0SBGZ1bGwSBXdhdGNoGi0KE0xpbWl0ZWRQZWVyc0FsbG93ZWQSBGZ1bGwSBXdhdGNoEgJ0dhIFYXVkaW8aFgoHTWFuYXRlZRIEZnVsbBIFd2F0Y2gaHgoEV2lGaRIEZnVsbBIFd2F0Y2gSAnR2EgVhdWRpbxoVCgZIZWFsdGgSBGZ1bGwSBXdhdGNoIhMKBGZ1bGwSBGZ1bGwSBXdhdGNoIhsKBWF1ZGlvEgRmdWxsEgV3YXRjaBIFYXVkaW8iFAoFd2F0Y2gSBGZ1bGwSBXdhdGNoIhUKAnR2EgRmdWxsEgV3YXRjaBICdHYyIgoWAAQiEgIEdndodAoKXkFwcGxlUGF5JBIIQXBwbGVQYXkyJgoYAAQiFAIEdndodAoMXkF1dG9VbmxvY2skEgpBdXRvVW5sb2NrMh4KFAAEIhACBHZ3aHQKCF5FbmdyYW0kEgZFbmdyYW0yHgoUAAQiEAIEdndodAoIXkhlYWx0aCQSBkhlYWx0aDIaChIABCIOAgR2d2h0CgZeSG9tZSQSBEhvbWUyIAoVAAQiEQIEdndodAoJXk1hbmF0ZWUkEgdNYW5hdGVlMjgKIQAEIh0CBHZ3aHQKFV5MaW1pdGVkUGVlcnNBbGxvd2VkJBITTGltaXRlZFBlZXJzQWxsb3dlZDJdClAAAhIeAAQiGgIEdndodAoSXkNvbnRpbnVpdHlVbmxvY2skEhUABCIRAgR2d2h0CgleSG9tZUtpdCQSFQAEIhECBHZ3aHQKCV5BcHBsZVRWJBIJTm90U3luY2VkMisKGwAEIhcCBGFncnAKD15bMC05QS1aXXsxMH1cLhIMQXBwbGljYXRpb25zMsUBCrABAAISNAABChMABCIPAgVjbGFzcwoGXmdlbnAkChsABCIXAgRhZ3JwCg9eY29tLmFwcGxlLnNiZCQSPQABChMABCIPAgVjbGFzcwoGXmtleXMkCiQABCIgAgRhZ3JwChheY29tLmFwcGxlLnNlY3VyaXR5LnNvcyQSGQAEIhUCBHZ3aHQKDV5CYWNrdXBCYWdWMCQSHAAEIhgCBHZ3aHQKEF5pQ2xvdWRJZGVudGl0eSQSEFNlY3VyZU9iamVjdFN5bmMyYwpbAAISEgAEIg4CBHZ3aHQKBl5XaUZpJBJDAAEKEwAEIg8CBWNsYXNzCgZeZ2VucCQKEwAEIg8CBGFncnAKB15hcHBsZSQKFQAEIhECBHN2Y2UKCV5BaXJQb3J0JBIEV2lGaTLbAgrBAgACEhkABCIVAgR2d2h0Cg1eUENTQ2xvdWRLaXQkEhcABCITAgR2d2h0CgteUENTRXNjcm93JBIUAAQiEAIEdndodAoIXlBDU0ZERSQSGQAEIhUCBHZ3aHQKDV5QQ1NGZWxkc3BhciQSGQAEIhUCBHZ3aHQKDV5QQ1NNYWlsRHJvcCQSGgAEIhYCBHZ3aHQKDl5QQ1NNYXN0ZXJLZXkkEhYABCISAgR2d2h0CgpeUENTTm90ZXMkEhcABCITAgR2d2h0CgteUENTUGhvdG9zJBIYAAQiFAIEdndodAoMXlBDU1NoYXJpbmckEh0ABCIZAgR2d2h0ChFeUENTaUNsb3VkQmFja3VwJBIcAAQiGAIEdndodAoQXlBDU2lDbG91ZERyaXZlJBIZAAQiFQIEdndodAoNXlBDU2lNZXNzYWdlJBIVUHJvdGVjdGVkQ2xvdWRTdG9yYWdlMkAKKwAEIicCBGFncnAKH15jb20uYXBwbGUuc2FmYXJpLmNyZWRpdC1jYXJkcyQSEVNhZmFyaUNyZWRpdENhcmRzMjQKIQAEIh0CBGFncnAKFV5jb20uYXBwbGUuY2ZuZXR3b3JrJBIPU2FmYXJpUGFzc3dvcmRzMm0KXAACEh4ABCIaAgR2d2h0ChJeQWNjZXNzb3J5UGFpcmluZyQSGgAEIhYCBHZ3aHQKDl5OYW5vUmVnaXN0cnkkEhwABCIYAgR2d2h0ChBeV2F0Y2hNaWdyYXRpb24kEg1EZXZpY2VQYWlyaW5nMi0KIQAEIh0CBGFncnAKFV5jb20uYXBwbGUuY2ZuZXR3b3JrJBIIQmFja3N0b3A="), + ] + let (request1, data1) = policies[1]! + let (request3, data3) = policies[3]! + + let description = tmpStoreDescription(name: "container.db") + let container = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + // nothing + let (response1, error1) = container.fetchPolicyDocumentsSync(test: self, keys: [:]) + XCTAssertNil(error1, "No error querying for an empty list") + XCTAssertEqual(response1, [:], "Received empty dictionary") + + // local stuff + let (response2, error2) = container.fetchPolicyDocumentsSync(test: self, keys: [1: request1]) + XCTAssertNil(error2, "No error getting locally known policy document") + XCTAssertEqual(response2?.count, 1, "Got one response for request for one locally known policy") + XCTAssertEqual(response2?[1]?[0], request1, "retrieved hash matches request hash") + XCTAssertEqual(response2?[1]?[1], data1, "retrieved data matches known data") + + // fetch remote + let (response3, error3) = container.fetchPolicyDocumentsSync(test: self, keys: [1: request1, 3: request3]) + XCTAssertNil(error3, "No error fetching local + remote policy") + XCTAssertEqual(response3?.count, 2, "Got two responses for local+remote policy request") + XCTAssertEqual(response3?[1]?[0], request1, "retrieved hash matches local request hash") + XCTAssertEqual(response3?[1]?[1], data1, "retrieved data matches local known data") + XCTAssertEqual(response3?[3]?[0], request3, "retrieved hash matches remote request hash") + XCTAssertEqual(response3?[3]?[1], data3, "retrieved data matches remote known data") + + // invalid version + let (response4, error4) = container.fetchPolicyDocumentsSync(test: self, keys: [9000: "not a hash"]) + XCTAssertNil(response4, "No response for wrong [version: hash] combination") + XCTAssertNotNil(error4, "Expected error fetching invalid policy version") + + // valid + invalid + let (response5, error5) = container.fetchPolicyDocumentsSync(test: self, keys: [9000: "not a hash", + 1: request1, + 3: request3, ]) + XCTAssertNil(response5, "No response for valid + unknown [version: hash] combination") + XCTAssertNotNil(error5, "Expected error fetching valid + invalid policy version") + } + + func testEscrowKeys() throws { + + XCTAssertThrowsError(try EscrowKeys.retrieveEscrowKeysFromKeychain(label: "hash"), "retrieveEscrowKeysFromKeychain should throw error") + XCTAssertThrowsError(try EscrowKeys.findEscrowKeysForLabel(label: "hash"), "findEscrowKeysForLabel should throw error") + + let secretString = "i'm a secret!" + XCTAssertNotNil(secretString, "secretString should not be nil") + + let secretData: Data? = secretString.data(using: .utf8) + XCTAssertNotNil(secretData, "secretData should not be nil") + + let keys = try EscrowKeys(secret: secretData!, bottleSalt: "123456789") + XCTAssertNotNil(keys, "keys should not be nil") + + XCTAssertNotNil(keys.secret, "secret should not be nil") + XCTAssertNotNil(keys.bottleSalt, "bottleSalt should not be nil") + XCTAssertNotNil(keys.encryptionKey, "encryptionKey should not be nil") + XCTAssertNotNil(keys.signingKey, "signingKey should not be nil") + XCTAssertNotNil(keys.symmetricKey, "symmetricKey should not be nil") + + let hash = try EscrowKeys.hashEscrowedSigningPublicKey(keyData: keys.signingKey.publicKey().spki()) + XCTAssertNotNil(hash, "hash should not be nil") + + let result = try EscrowKeys.storeEscrowedSigningKeyPair(keyData: keys.signingKey.keyData, label: "Signing Key") + XCTAssertTrue(result, "result should be true") + + let escrowKey = try EscrowKeys.retrieveEscrowKeysFromKeychain(label: hash) + XCTAssertNotNil(escrowKey, "escrowKey should not be nil") + + let (signingKey, encryptionKey, symmetricKey) = try EscrowKeys.findEscrowKeysForLabel(label: hash) + XCTAssertNotNil(signingKey, "signingKey should not be nil") + XCTAssertNotNil(encryptionKey, "encryptionKey should not be nil") + XCTAssertNotNil(symmetricKey, "symmetricKey should not be nil") + } + + func testEscrowKeyTestVectors() { + + let secretString = "I'm a secretI'm a secretI'm a secretI'm a secretI'm a secretI'm a secret" + + let secret = secretString.data(using: .utf8) + + do { + let testv1 = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeySigning, masterSecret: secret!, bottleSalt: testDSID) + XCTAssertEqual(testv1, signingKey_384, "signing keys should match") + + let testv2 = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeyEncryption, masterSecret: secret!, bottleSalt: testDSID) + XCTAssertEqual(testv2, encryptionKey_384, "encryption keys should match") + + let testv3 = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeySymmetric, masterSecret: secret!, bottleSalt: testDSID) + XCTAssertEqual(testv3, symmetricKey_384, "symmetric keys should match") + + let newSecretString = "I'm f secretI'm a secretI'm a secretI'm a secretI'm a secretI'm a secret" + let newSecret = newSecretString.data(using: .utf8) + + let testv4 = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeySigning, masterSecret: newSecret!, bottleSalt: testDSID) + XCTAssertNotEqual(testv4, signingKey_384, "signing keys should not match") + + let testv5 = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeyEncryption, masterSecret: newSecret!, bottleSalt: testDSID) + XCTAssertNotEqual(testv5, encryptionKey_384, "encryption keys should not match") + + let testv6 = try EscrowKeys.generateEscrowKey(keyType: escrowKeyType.kOTEscrowKeySymmetric, masterSecret: newSecret!, bottleSalt: testDSID) + XCTAssertNotEqual(testv6, symmetricKey_384, "symmetric keys should not match") + } catch { + XCTFail("error testing escrow key test vectors \(error)") + } + } + + func testJoiningWithBottle() throws { + var bottleA: BottleMO + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + + bottleA = state.bottles.removeFirst() + + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + assertNoTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + assertTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + _ = containerB.updateSync(test: self) + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B prepares to join via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleA.bottleID!, entropy: entropy, bottleSalt: "123456789", tlkShares: []) + + XCTAssertNil(error3) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + // Before B joins, there should be no TLKShares for B + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("B joins") + let (peerID, _, error) = containerB.joinSync(test: self, voucherData: voucherData!, voucherSig: voucherSig!, ckksKeys: [self.manateeKeySet], tlkShares: []) + XCTAssertNil(error) + XCTAssertEqual(peerID, bPeerID!) + + // But afterward, it has one! + assertTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + } + + func testJoiningWithBottleAndEmptyBottleSalt() throws { + var bottleA: BottleMO + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + + bottleA = state.bottles.removeFirst() + + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + assertNoTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + assertTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + _ = containerB.updateSync(test: self) + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B prepares to join via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleA.bottleID!, entropy: entropy, bottleSalt: "123456789", tlkShares: []) + + XCTAssertNil(error3) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + // Before B joins, there should be no TLKShares for B + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("B joins") + let (peerID, _, error) = containerB.joinSync(test: self, voucherData: voucherData!, voucherSig: voucherSig!, ckksKeys: [self.manateeKeySet], tlkShares: []) + XCTAssertNil(error) + XCTAssertEqual(peerID, bPeerID!) + + // But afterward, it has one! + assertTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + } + + func testJoiningWithWrongEscrowRecordForBottle() throws { + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + _ = containerB.updateSync(test: self) + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B joins via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: "wrong escrow record", entropy: entropy, bottleSalt: "123456789", tlkShares: []) + + XCTAssertNotNil(error3) + XCTAssertNil(voucherData) + XCTAssertNil(voucherSig) + } + } + + func testJoiningWithWrongBottle() throws { + var bottleB: BottleMO + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + bottleB = state.bottles.removeFirst() + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B joins via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleB.bottleID!, entropy: entropy, bottleSalt: "123456789", tlkShares: []) + + XCTAssertNotNil(error3) + XCTAssertNil(voucherData) + XCTAssertNil(voucherSig) + } + } + + func testJoiningWithBottleAndBadSalt() throws { + var bottleA: BottleMO + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + bottleA = state.bottles.removeFirst() + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + _ = containerB.updateSync(test: self) + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B joins via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleA.bottleID!, entropy: entropy, bottleSalt: "987654321", tlkShares: []) + + XCTAssertNotNil(error3) + XCTAssertNil(voucherData) + XCTAssertNil(voucherSig) + } + } + + func testJoiningWithBottleAndBadSecret() throws { + var bottleA: BottleMO + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + bottleA = state.bottles.removeFirst() + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + _ = containerB.updateSync(test: self) + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B joins via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleA.bottleID!, entropy: Data(count: Int(OTMasterSecretLength)), bottleSalt: "123456789", tlkShares: []) + + XCTAssertNotNil(error3) + XCTAssertNil(voucherData) + XCTAssertNil(voucherSig) + } + } + + func testJoiningWithNoFetchAllBottles() throws { + var bottleA: BottleMO + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + bottleA = state.bottles.removeFirst() + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B joins via bottle") + + // And the first container fetches again, which should succeed + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.changeTokenExpired.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.cuttlefish.fetchViableBottlesError.append(ckError) + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleA.bottleID!, entropy: entropy, bottleSalt: "123456789", tlkShares: []) + + XCTAssertNotNil(error3) + XCTAssertNil(voucherData) + XCTAssertNil(voucherSig) + } + } + + func testJoinByPreapproval() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("preparing B") + let (bPeerID, bPermanentInfo, bPermanentInfoSig, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + XCTAssertNotNil(bPeerID) + XCTAssertNotNil(bPermanentInfo) + XCTAssertNotNil(bPermanentInfoSig) + + // Now, A establishes preapproving B + // Note: secd is responsible for passing in TLKShares to these preapproved keys in sosTLKShares + + let bPermanentInfoParsed = TPPeerPermanentInfo(peerID: bPeerID!, data: bPermanentInfo!, sig: bPermanentInfoSig!, keyFactory: TPECPublicKeyFactory()) + XCTAssertNotNil(bPermanentInfoParsed, "Should have parsed B's permanent info") + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: [bPermanentInfoParsed!.signingPubKey.spki()]) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + + do { + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("B joins by preapproval, and uploads all TLKShares that it has") + let (bJoinedPeerID, _, bJoinedError) = containerB.preapprovedJoinSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: []) + XCTAssertNil(bJoinedError, "Should be no error joining by preapproval") + XCTAssertNotNil(bJoinedPeerID, "Should have a peer ID out of join") + + assertTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + + _ = containerA.dumpSync(test: self) + _ = containerB.dumpSync(test: self) + } + + func testDepart() throws { + let description = tmpStoreDescription(name: "container.db") + let (container, peerID) = try establish(reload: false, store: description) + + XCTAssertNil(container.departByDistrustingSelfSync(test: self), "Should be no error distrusting self") + assertDistrusts(context: container, peerIDs: [peerID]) + } + + func testDistrustPeers() throws { + let store = tmpStoreDescription(name: "container.db") + let (c, peerID1) = try establish(reload: false, store: store) + + let (c2, peerID2) = try joinByVoucher(sponsor: c, + containerID: "second", + machineID: "bbb", + machineIDs: ["aaa", "bbb", "ccc"], + store: store) + + let (c3, peerID3) = try joinByVoucher(sponsor: c, + containerID: "third", + machineID: "ccc", + machineIDs: ["aaa", "bbb", "ccc"], + store: store) + + let (_, cUpdateError) = c.updateSync(test: self) + XCTAssertNil(cUpdateError, "Should be able to update first container") + assertTrusts(context: c, peerIDs: [peerID1, peerID2, peerID3]) + + // You can't distrust yourself via peerID. + XCTAssertNotNil(c.distrustSync(test: self, peerIDs: Set([peerID1, peerID2, peerID3])), "Should error trying to distrust yourself via peer ID") + assertTrusts(context: c, peerIDs: [peerID1, peerID2, peerID3]) + + // Passing in nonsense should error too + XCTAssertNotNil(c.distrustSync(test: self, peerIDs: Set(["not a real peer ID"])), "Should error when passing in unknown peer IDs") + + // Now, distrust both peers. + XCTAssertNil(c.distrustSync(test: self, peerIDs: Set([peerID2, peerID3])), "Should be no error distrusting peers") + assertDistrusts(context: c, peerIDs: [peerID2, peerID3]) + + // peers should accept their fates + let (_, c2UpdateError) = c2.updateSync(test: self) + XCTAssertNil(c2UpdateError, "Should be able to update second container") + assertDistrusts(context: c2, peerIDs: [peerID2]) + + let (_, c3UpdateError) = c3.updateSync(test: self) + XCTAssertNil(c3UpdateError, "Should be able to update third container") + assertDistrusts(context: c3, peerIDs: [peerID3]) + } + + func testFetchWithBadChangeToken() throws { + let (c, peerID1) = try establish(reload: false, store: tmpStoreDescription(name: "container.db")) + + // But all that goes away, and a new peer establishes + self.cuttlefish.state = FakeCuttlefishServer.State() + let (_, peerID2) = try establish(reload: false, contextID: "second", store: tmpStoreDescription(name: "container-peer2.db")) + + // And the first container fetches again, which should succeed + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.changeTokenExpired.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.cuttlefish.nextFetchErrors.append(ckError) + _ = c.updateSync(test: self) + + // and c's model should only include peerID2 + c.moc.performAndWait { + let modelPeers = c.model.allPeerIDs() + XCTAssertEqual(modelPeers.count, 1, "Model should have one peer") + XCTAssert(modelPeers.contains(peerID2), "Model should contain peer 2") + XCTAssertFalse(modelPeers.contains(peerID1), "Model should no longer container peer 1 (ego peer)") + } + } + + func testFetchEscrowContents() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let (entropyA, bottleIDA, spkiA, errorA) = containerA.fetchEscrowContentsSync(test: self) + XCTAssertNotNil(errorA, "Should be an error fetching escrow contents") + XCTAssertEqual(errorA.debugDescription, "Optional(TrustedPeersHelperUnitTests.ContainerError.noPreparedIdentity)", "error should be no prepared identity") + XCTAssertNil(entropyA, "Should not have some entropy to bottle") + XCTAssertNil(bottleIDA, "Should not have a bottleID") + XCTAssertNil(spkiA, "Should not have an SPKI") + + let (c, peerID) = try establish(reload: false, store: description) + XCTAssertNotNil(peerID, "establish should return a peer id") + + let (entropy, bottleID, spki, error) = c.fetchEscrowContentsSync(test: self) + XCTAssertNil(error, "Should be no error fetching escrow contents") + XCTAssertNotNil(entropy, "Should have some entropy to bottle") + XCTAssertNotNil(bottleID, "Should have a bottleID") + XCTAssertNotNil(spki, "Should have an SPKI") + } + + func testBottles() { + do { + let peerSigningKey = _SFECKeyPair.init(randomKeyPairWith: _SFECKeySpecifier.init(curve: SFEllipticCurve.nistp384))! + let peerEncryptionKey = _SFECKeyPair.init(randomKeyPairWith: _SFECKeySpecifier.init(curve: SFEllipticCurve.nistp384))! + let bottle = try BottledPeer(peerID: "peerID", bottleID: UUID().uuidString, peerSigningKey: peerSigningKey, peerEncryptionKey: peerEncryptionKey, bottleSalt: "123456789") + + let keys = bottle.escrowKeys + XCTAssertNotNil(keys, "keys should not be nil") + + XCTAssertNotNil(bottle, "bottle should not be nil") + + XCTAssertNotNil(bottle.escrowSigningPublicKeyHash(), "escrowSigningPublicKeyHash should not be nil") + + XCTAssertThrowsError(try BottledPeer.verifyBottleSignature(data: bottle.contents, signature: bottle.signatureUsingPeerKey, pubKey: keys.signingKey.publicKey() as! _SFECPublicKey)) + XCTAssertThrowsError(try BottledPeer.verifyBottleSignature(data: bottle.contents, signature: bottle.signatureUsingEscrowKey, pubKey: peerSigningKey.publicKey() as! _SFECPublicKey)) + + XCTAssertNotNil(BottledPeer.signingOperation(), "signing operation should not be nil") + + let verifyBottleEscrowSignature = try BottledPeer.verifyBottleSignature(data: bottle.contents, signature: bottle.signatureUsingEscrowKey, pubKey: keys.signingKey.publicKey() as! _SFECPublicKey) + XCTAssertNotNil(verifyBottleEscrowSignature, "verifyBottleEscrowSignature should not be nil") + + let verifyBottlePeerSignature = try BottledPeer.verifyBottleSignature(data: bottle.contents, signature: bottle.signatureUsingPeerKey, pubKey: peerSigningKey.publicKey() as! _SFECPublicKey) + XCTAssertNotNil(verifyBottlePeerSignature, "verifyBottlePeerSignature should not be nil") + + let deserializedBottle = try BottledPeer(contents: bottle.contents, secret: bottle.secret, bottleSalt: "123456789", signatureUsingEscrow: bottle.signatureUsingEscrowKey, signatureUsingPeerKey: bottle.signatureUsingPeerKey) + XCTAssertNotNil(deserializedBottle, "deserializedBottle should not be nil") + + XCTAssertEqual(deserializedBottle.contents, bottle.contents, "bottle data should be equal") + + } catch { + XCTFail("error testing bottles \(error)") + } + } + + func testFetchBottles() throws { + let store = tmpStoreDescription(name: "container.db") + let (c, _) = try establish(reload: false, store: store) + + let (bottles, _, fetchError) = c.fetchViableBottlesSync(test: self) + XCTAssertNil(fetchError, "should be no error fetching viable bottles") + XCTAssertNotNil(bottles, "should have fetched some bottles") + XCTAssertEqual(bottles!.count, 1, "should have fetched one bottle") + + do { + let state = c.getStateSync(test: self) + XCTAssertEqual(state.bottles.count, 1, "first container should have a bottle for peer") + } + + let c2 = try Container(name: ContainerName(container: "test", context: "newcomer"), persistentStoreDescription: store, cuttlefish: self.cuttlefish) + do { + let state = c2.getStateSync(test: self) + XCTAssertEqual(state.bottles.count, 0, "before fetch, second container should not have any stored bottles") + } + + let (c2bottles, _, c2FetchError) = c2.fetchViableBottlesSync(test: self) + XCTAssertNil(c2FetchError, "should be no error fetching viable bottles") + XCTAssertNotNil(c2bottles, "should have fetched some bottles") + XCTAssertEqual(c2bottles!.count, 1, "should have fetched one bottle") + + do { + let state = c2.getStateSync(test: self) + XCTAssertEqual(state.bottles.count, 1, "after fetch, second container should have one stored bottles") + } + } + + func testTrustStatus() throws { + let store = tmpStoreDescription(name: "container.db") + + let preC = try Container(name: ContainerName(container: "preC", context: "preCContext"), + persistentStoreDescription: store, + cuttlefish: self.cuttlefish) + let (preEgoStatus, precStatusError) = preC.trustStatusSync(test: self) + XCTAssertNil(precStatusError, "No error fetching status") + XCTAssertEqual(preEgoStatus.egoStatus, .unknown, "Before establish, trust status should be 'unknown'") + XCTAssertNil(preEgoStatus.egoPeerID, "should not have a peer ID") + XCTAssertEqual(preEgoStatus.numberOfPeersInOctagon, 0, "should not see number of peers") + XCTAssertFalse(preEgoStatus.isExcluded, "should be excluded") + + let (c, _) = try establish(reload: false, store: store) + let (cEgoStatus, cStatusError) = c.trustStatusSync(test: self) + XCTAssertNil(cStatusError, "Should be no error fetching trust status directly after establish") + XCTAssertEqual(cEgoStatus.egoStatus, [.fullyReciprocated, .selfTrust], "After establish, should be fully reciprocated") + XCTAssertNotNil(cEgoStatus.egoPeerID, "should have a peer ID") + XCTAssertEqual(cEgoStatus.numberOfPeersInOctagon, 1, "should be 1 peer") + XCTAssertFalse(cEgoStatus.isExcluded, "should not be excluded") + + let c2 = try Container(name: ContainerName(container: "differentContainer", context: "a different context"), + persistentStoreDescription: store, + cuttlefish: self.cuttlefish) + + let (egoStatus, statusError) = c2.trustStatusSync(test: self) + XCTAssertNil(statusError, "No error fetching status") + XCTAssertEqual(egoStatus.egoStatus, .excluded, "After establish, other container should be 'excluded'") + XCTAssertNil(egoStatus.egoPeerID, "should not have a peerID") + XCTAssertEqual(egoStatus.numberOfPeersInOctagon, 1, "should be 1 peer") + XCTAssertTrue(egoStatus.isExcluded, "should not be excluded") + } + + func testTrustStatusWhenMissingIdentityKeys() throws { + let store = tmpStoreDescription(name: "container.db") + let (c, _) = try establish(reload: false, store: store) + let (cEgoStatus, cStatusError) = c.trustStatusSync(test: self) + XCTAssertNil(cStatusError, "Should be no error fetching trust status directly after establish") + XCTAssertEqual(cEgoStatus.egoStatus, [.fullyReciprocated, .selfTrust], "After establish, should be fully reciprocated") + XCTAssertNotNil(cEgoStatus.egoPeerID, "should have a peer ID") + XCTAssertEqual(cEgoStatus.numberOfPeersInOctagon, 1, "should be 1 peer") + XCTAssertFalse(cEgoStatus.isExcluded, "should not be excluded") + + let result = try removeEgoKeysSync(peerID: cEgoStatus.egoPeerID!) + XCTAssertTrue(result, "result should be true") + + let (distrustedStatus, distrustedError) = c.trustStatusSync(test: self) + XCTAssertNotNil(distrustedError, "error should not be nil") + XCTAssertEqual(distrustedStatus.egoStatus, [.excluded], "trust status should be excluded") + XCTAssertTrue(distrustedStatus.isExcluded, "should be excluded") + } + + func testSetRecoveryKey() throws { + let store = tmpStoreDescription(name: "container.db") + + let c = try Container(name: ContainerName(container: "c", context: "context"), + persistentStoreDescription: store, + cuttlefish: self.cuttlefish) + + let machineIDs = Set(["aaa", "bbb", "ccc"]) + XCTAssertNil(c.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing peer A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + c.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = c.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = c.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = c.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: nil) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + let (setRecoveryError) = c.setRecoveryKeySync(test: self, recoveryKey: recoveryKey!, recoverySalt: "altDSID", ckksKeys: []) + XCTAssertNil(setRecoveryError, "error should be nil") + } + + func roundTripThroughSetValueTransformer(set: Set) { + let t = SetValueTransformer() + + let transformedSet = t.transformedValue(set) as? Data + XCTAssertNotNil(transformedSet, "SVT should return some data") + + let recoveredSet = t.reverseTransformedValue(transformedSet) as? Set + XCTAssertNotNil(recoveredSet, "SVT should return some recovered set") + + XCTAssertEqual(set, recoveredSet, "Recovered set should be the same as original") + } + + func testSetValueTransformer() { + roundTripThroughSetValueTransformer(set: Set([])) + roundTripThroughSetValueTransformer(set: Set(["asdf"])) + roundTripThroughSetValueTransformer(set: Set(["asdf", "three", "test"])) + } + + func testGetRepairSuggestion() throws { + let store = tmpStoreDescription(name: "container.db") + + let c = try Container(name: ContainerName(container: "c", context: "context"), + persistentStoreDescription: store, + cuttlefish: self.cuttlefish) + + let machineIDs = Set(["aaa", "bbb", "ccc"]) + XCTAssertNil(c.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing peer A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + c.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = c.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = c.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = c.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: nil) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + let (repairAccount, repairEscrow, resetOctagon, healthError) = c.requestHealthCheckSync(requiresEscrowCheck: true, test: self) + XCTAssertEqual(repairAccount, false, "") + XCTAssertEqual(repairEscrow, false, "") + XCTAssertEqual(resetOctagon, false, "") + XCTAssertNil(healthError) + } + + func testFetchChangesFailDuringVouchWithBottle() throws { + var bottleA: BottleMO + var entropy: Data + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, _, _, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + var state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + + bottleA = state.bottles.removeFirst() + + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + + print("establishing A") + do { + assertNoTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + assertTLKShareFor(peerID: aPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + } + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + entropy = secret! + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + + _ = containerB.updateSync(test: self) + + print("preparing B") + let (bPeerID, _, _, _, _, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + + do { + print("B prepares to join via bottle") + + let (voucherData, voucherSig, error3) = containerB.vouchWithBottleSync(test: self, b: bottleA.bottleID!, entropy: entropy, bottleSalt: "123456789", tlkShares: []) + + XCTAssertNil(error3) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + // And the first container fetches again, which should succeed + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.changeTokenExpired.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.cuttlefish.nextFetchErrors.append(ckError) + + // Before B joins, there should be no TLKShares for B + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("B joins") + let (peerID, _, error) = containerB.joinSync(test: self, voucherData: voucherData!, voucherSig: voucherSig!, ckksKeys: [self.manateeKeySet], tlkShares: []) + XCTAssertNotNil(error) + XCTAssertNil(peerID) + } + } + + func testDistrustedPeerRecoveryKeyNotSet() throws { + let description = tmpStoreDescription(name: "container.db") + let containerA = try Container(name: ContainerName(container: "a", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + let containerB = try Container(name: ContainerName(container: "b", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + + let machineIDs = Set(["aaa", "bbb"]) + XCTAssertNil(containerA.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + XCTAssertNil(containerB.setAllowedMachineIDsSync(test: self, allowedMachineIDs: machineIDs)) + + print("preparing peer A") + let (aPeerID, aPermanentInfo, aPermanentInfoSig, aStableInfo, aStableInfoSig, error) = + containerA.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerA.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == aPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerA.loadSecretSync(test: self, label: aPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error) + XCTAssertNotNil(aPeerID) + XCTAssertNotNil(aPermanentInfo) + XCTAssertNotNil(aPermanentInfoSig) + XCTAssertNotNil(aStableInfo) + XCTAssertNotNil(aStableInfoSig) + + print("establishing A") + do { + let (peerID, _, error) = containerA.establishSync(test: self, ckksKeys: [], tlkShares: [], preapprovedKeys: nil) + XCTAssertNil(error) + XCTAssertNotNil(peerID) + } + + print("preparing B") + let (bPeerID, bPermanentInfo, bPermanentInfoSig, bStableInfo, bStableInfoSig, error2) = + containerB.prepareSync(test: self, epoch: 1, machineID: "bbb", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + do { + let state = containerB.getStateSync(test: self) + XCTAssertFalse( state.bottles.filter { $0.peerID == bPeerID } .isEmpty, "should have a bottle for peer") + let secret = containerB.loadSecretSync(test: self, label: bPeerID!) + XCTAssertNotNil(secret, "secret should not be nil") + XCTAssertNil(error, "error should be nil") + } + XCTAssertNil(error2) + XCTAssertNotNil(bPeerID) + XCTAssertNotNil(bPermanentInfo) + XCTAssertNotNil(bPermanentInfoSig) + + do { + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + print("A vouches for B, but doesn't provide any TLKShares") + let (_, _, errorVouchingWithoutTLKs) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: []) + XCTAssertNil(errorVouchingWithoutTLKs, "Should be no error vouching without uploading TLKShares") + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("A vouches for B, but doesn't only has provisional TLKs at the time") + let provisionalManateeKeySet = try self.makeFakeKeyHierarchy(zoneID: CKRecordZone.ID(zoneName: "Manatee")) + provisionalManateeKeySet.newUpload = true + + let (_, _, errorVouchingWithProvisionalTLKs) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: [provisionalManateeKeySet]) + XCTAssertNil(errorVouchingWithProvisionalTLKs, "Should be no error vouching without uploading TLKShares for a non-existent key") + assertNoTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("A vouches for B") + let (voucherData, voucherSig, error3) = + containerA.vouchSync(test: self, + peerID: bPeerID!, + permanentInfo: bPermanentInfo!, + permanentInfoSig: bPermanentInfoSig!, + stableInfo: bStableInfo!, + stableInfoSig: bStableInfoSig!, + ckksKeys: [self.manateeKeySet]) + XCTAssertNil(error3) + XCTAssertNotNil(voucherData) + XCTAssertNotNil(voucherSig) + + // As part of the vouch, A should have uploaded a tlkshare for B + assertTLKShareFor(peerID: bPeerID!, keyUUID: self.manateeKeySet.tlk.uuid, zoneID: CKRecordZone.ID(zoneName: "Manatee")) + + print("B joins") + let (peerID, _, error) = containerB.joinSync(test: self, + voucherData: voucherData!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: []) + XCTAssertNil(error) + XCTAssertEqual(peerID, bPeerID!) + } + + print("A updates") + do { + let (_, error) = containerA.updateSync(test: self) + XCTAssertNil(error) + } + print("B updates") + do { + let (_, error) = containerB.updateSync(test: self) + XCTAssertNil(error) + } + + // Now, A distrusts B. + XCTAssertNil(containerA.distrustSync(test: self, peerIDs: Set([bPeerID!])), "Should be no error distrusting peers") + assertDistrusts(context: containerA, peerIDs: [bPeerID!]) + + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + let (setRecoveryError) = containerB.setRecoveryKeySync(test: self, recoveryKey: recoveryKey!, recoverySalt: "altDSID", ckksKeys: []) + XCTAssertNil(setRecoveryError, "error should be nil") + + print("A updates") + do { + let (_, error) = containerA.updateSync(test: self) + XCTAssertNil(error) + } + print("B updates") + do { + let (_, error) = containerB.updateSync(test: self) + XCTAssertNil(error) + } + + do { + let (dict, error) = containerA.dumpSync(test: self) + + XCTAssertNil(error, "Should be no error dumping") + XCTAssertNotNil(dict, "Should receive a dump dictionary") + + let selfInfo: [AnyHashable: Any]? = dict!["self"] as! [AnyHashable: Any]? + XCTAssertNotNil(selfInfo, "Should have a self dictionary") + + let stableInfo: [AnyHashable: Any]? = selfInfo!["stableInfo"] as! [AnyHashable: Any]? + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + + let recoverySigningPublicKey: Data? = stableInfo!["recovery_signing_public_key"] as! Data? + XCTAssertNil(recoverySigningPublicKey, "recoverySigningPublicKey should be nil") + + let recoveryEncryptionPublicKey: Data? = stableInfo!["recovery_encryption_public_key"] as! Data? + XCTAssertNil(recoveryEncryptionPublicKey, "recoveryEncryptionPublicKey should be nil") + + } + } + + func assert(container: Container, + allowedMachineIDs: Set, + disallowedMachineIDs: Set, + unknownMachineIDs: Set = Set(), + persistentStore: NSPersistentStoreDescription, + cuttlefish: FakeCuttlefishServer) throws { + + let midList = container.onqueueCurrentMIDList() + XCTAssertEqual(midList.machineIDs(in: .allowed), allowedMachineIDs, "List of allowed machine IDs should match") + XCTAssertEqual(midList.machineIDs(in: .disallowed), disallowedMachineIDs, "List of disallowed machine IDs should match") + XCTAssertEqual(midList.machineIDs(in: .unknown), unknownMachineIDs, "List of unknown machine IDs should match") + + // if we reload the container, does it still match? + let reloadedContainer = try Container(name: ContainerName(container: "test", context: OTDefaultContext), persistentStoreDescription: persistentStore, cuttlefish: cuttlefish) + + let reloadedMidList = reloadedContainer.onqueueCurrentMIDList() + XCTAssertEqual(reloadedMidList.machineIDs(in: .allowed), allowedMachineIDs, "List of allowed machine IDs on a reloaded container should match") + XCTAssertEqual(reloadedMidList.machineIDs(in: .disallowed), disallowedMachineIDs, "List of disallowed machine IDs on a reloaded container should match") + XCTAssertEqual(reloadedMidList.machineIDs(in: .unknown), unknownMachineIDs, "List of unknown machine IDs on a reloaded container should match") + } + + func testAllowListManipulation() throws { + let description = tmpStoreDescription(name: "container.db") + let container = try Container(name: ContainerName(container: "test", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + let (peerID, permanentInfo, permanentInfoSig, _, _, error) = container.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + + XCTAssertNil(error) + XCTAssertNotNil(peerID) + XCTAssertNotNil(permanentInfo) + XCTAssertNotNil(permanentInfoSig) + + try self.assert(container: container, allowedMachineIDs: [], disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb", "ccc"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]), disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb"]), disallowedMachineIDs: Set(["ccc"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + XCTAssertNil(container.addAllowedMachineIDsSync(test: self, machineIDs: ["zzz", "kkk"]), "should be able to add allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "zzz", "kkk"]), disallowedMachineIDs: Set(["ccc"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Receivng a 'remove' push should send the MIDs to the 'unknown' list + XCTAssertNil(container.removeAllowedMachineIDsSync(test: self, machineIDs: ["bbb", "fff"]), "should be able to remove allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "zzz", "kkk"]), disallowedMachineIDs: Set(["ccc"]), unknownMachineIDs: Set(["bbb", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertTrue(container.onqueueFullIDMSListWouldBeHelpful(), "Container should think it could use an IDMS list set: there's machine IDs pending removal") + + // once they're unknown, a full list set will make them disallowed + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "zzz", "kkk"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "zzz", "kkk"]), disallowedMachineIDs: Set(["bbb", "ccc", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Resetting the list to what it is doesn't change the list + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "zzz", "kkk"], listDifference: false), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "zzz", "kkk"]), disallowedMachineIDs: Set(["bbb", "ccc", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // But changing it to something completely new does + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["xxx", "mmm"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["xxx", "mmm"]), disallowedMachineIDs: Set(["aaa", "zzz", "kkk", "bbb", "ccc", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // And, readding a previously disallowed machine ID works too + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["xxx", "mmm", "aaa"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["xxx", "mmm", "aaa"]), disallowedMachineIDs: Set(["zzz", "kkk", "bbb", "ccc", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // A update() before establish() doesn't change the list, since it isn't actually changing anything + let (_, updateError) = container.updateSync(test: self) + XCTAssertNil(updateError, "Should not be an error updating the container without first establishing") + try self.assert(container: container, allowedMachineIDs: Set(["xxx", "mmm", "aaa"]), disallowedMachineIDs: Set(["zzz", "kkk", "bbb", "ccc", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + + let (_, _, establishError) = container.establishSync(test: self, ckksKeys: [self.manateeKeySet], tlkShares: [], preapprovedKeys: []) + XCTAssertNil(establishError, "Should be able to establish() with no error") + try self.assert(container: container, allowedMachineIDs: Set(["xxx", "mmm", "aaa"]), disallowedMachineIDs: Set(["zzz", "kkk", "bbb", "ccc", "fff"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // But a successful update() does remove all disallowed machine IDs, as they're no longer relevant + let (_, updateError2) = container.updateSync(test: self) + XCTAssertNil(updateError2, "Should not be an error updating the container after establishing") + try self.assert(container: container, allowedMachineIDs: Set(["xxx", "mmm", "aaa"]), disallowedMachineIDs: Set([]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + } + + func testAllowListManipulationWithAddsAndRemoves() throws { + let description = tmpStoreDescription(name: "container.db") + let container = try Container(name: ContainerName(container: "test", context: OTDefaultContext), persistentStoreDescription: description, cuttlefish: cuttlefish) + + try self.assert(container: container, allowedMachineIDs: [], disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb", "ccc"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]), disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Now, an 'add' comes in for some peers + XCTAssertNil(container.addAllowedMachineIDsSync(test: self, machineIDs: ["ddd", "eee"]), "should be able to receive an add push") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc", "ddd", "eee"]), disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // But, the next time we ask IDMS, they still haven't made it to the full list, and in fact, C has disappeared. + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ddd", "eee"]), disallowedMachineIDs: Set(["ccc"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // And a remove comes in for E. It becomes 'unknown' + XCTAssertNil(container.removeAllowedMachineIDsSync(test: self, machineIDs: ["eee"]), "should be able to receive an add push") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ddd"]), disallowedMachineIDs: Set(["ccc"]), unknownMachineIDs: Set(["eee"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertTrue(container.onqueueFullIDMSListWouldBeHelpful(), "Container should think it could use an IDMS list set: there's machine IDs pending removal") + + // and a list set after the remove confirms the removal + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ddd"]), disallowedMachineIDs: Set(["ccc", "eee"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Then a new list set includes D! Hurray IDMS. Note that this is not a "list change", because the list doesn't actually change + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb", "ddd"], listDifference: false), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ddd"]), disallowedMachineIDs: Set(["ccc", "eee"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // And another list set no longer includes D, so it should now be disallowed + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb"]), disallowedMachineIDs: Set(["ccc", "ddd", "eee"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // And just to check the 48 hour boundary... + XCTAssertNil(container.addAllowedMachineIDsSync(test: self, machineIDs: ["xxx"]), "should be able to receive an add push") + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"], listDifference: false), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "xxx"]), disallowedMachineIDs: Set(["ccc", "ddd", "eee"]), persistentStore: description, cuttlefish: self.cuttlefish) + + container.moc.performAndWait { + let knownMachineMOs = container.containerMO.machines as? Set ?? Set() + + knownMachineMOs.forEach { + if $0.machineID == "xxx" { + $0.modified = Date(timeIntervalSinceNow: -60*60*72) + } + } + + try! container.moc.save() + } + + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Setting the list again should kick out X, since it was 'added' too long ago + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb"]), disallowedMachineIDs: Set(["ccc", "ddd", "eee", "xxx"]), persistentStore: description, cuttlefish: self.cuttlefish) + } + + func testAllowSetUpgrade() throws { + let containerName = ContainerName(container: "test", context: OTDefaultContext) + + let description = tmpStoreDescription(name: "container.db") + let url = Bundle(for: type(of: self)).url(forResource: "TrustedPeersHelper", withExtension: "momd")! + let mom = getOrMakeModel(url: url) + let persistentContainer = NSPersistentContainer(name: "TrustedPeersHelper", managedObjectModel: mom) + persistentContainer.persistentStoreDescriptions = [description] + + persistentContainer.loadPersistentStores { _, error in + XCTAssertNil(error, "Should be no error loading persistent stores") + } + + let moc = persistentContainer.newBackgroundContext() + moc.performAndWait { + let containerMO = ContainerMO(context: moc) + containerMO.name = containerName.asSingleString() + containerMO.allowedMachineIDs = Set(["aaa", "bbb", "ccc"]) as NSSet + + XCTAssertNoThrow(try! moc.save()) + } + + // Now TPH boots up with a preexisting model + let container = try Container(name: containerName, persistentStoreDescription: description, cuttlefish: cuttlefish) + + let (peerID, permanentInfo, permanentInfoSig, _, _, error) = container.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + + XCTAssertNil(error) + XCTAssertNotNil(peerID) + XCTAssertNotNil(permanentInfo) + XCTAssertNotNil(permanentInfoSig) + + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]), disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + + // Setting a new list should work fine + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb", "ddd"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ddd"]), disallowedMachineIDs: ["ccc"], persistentStore: description, cuttlefish: self.cuttlefish) + + XCTAssertEqual(container.containerMO.allowedMachineIDs, Set() as NSSet, "Set of allowed machine IDs should now be empty") + } + + func testAllowStatusUpgrade() throws { + let containerName = ContainerName(container: "test", context: OTDefaultContext) + + let description = tmpStoreDescription(name: "container.db") + let url = Bundle(for: type(of: self)).url(forResource: "TrustedPeersHelper", withExtension: "momd")! + let mom = getOrMakeModel(url: url) + let persistentContainer = NSPersistentContainer(name: "TrustedPeersHelper", managedObjectModel: mom) + persistentContainer.persistentStoreDescriptions = [description] + + persistentContainer.loadPersistentStores { _, error in + XCTAssertNil(error, "Should be no error loading persistent stores") + } + + let moc = persistentContainer.newBackgroundContext() + moc.performAndWait { + let containerMO = ContainerMO(context: moc) + containerMO.name = containerName.asSingleString() + + let machine = MachineMO(context: moc) + machine.allowed = true + machine.modified = Date() + machine.machineID = "aaa" + containerMO.addToMachines(machine) + + let machineB = MachineMO(context: moc) + machineB.allowed = false + machineB.modified = Date() + machineB.machineID = "bbb" + containerMO.addToMachines(machineB) + + try! moc.save() + } + + // Now TPH boots up with a preexisting model + let container = try Container(name: containerName, persistentStoreDescription: description, cuttlefish: cuttlefish) + try self.assert(container: container, allowedMachineIDs: Set(["aaa"]), disallowedMachineIDs: ["bbb"], persistentStore: description, cuttlefish: self.cuttlefish) + + // Setting a new list should work fine + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "ddd"]), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "ddd"]), disallowedMachineIDs: ["bbb"], persistentStore: description, cuttlefish: self.cuttlefish) + + XCTAssertEqual(container.containerMO.allowedMachineIDs, Set() as NSSet, "Set of allowed machine IDs should now be empty") + } + + func testMachineIDListSetWithUnknownMachineIDs() throws { + let description = tmpStoreDescription(name: "container.db") + let (container, _) = try establish(reload: false, store: description) + + container.moc.performAndWait { + let knownMachineMOs = container.containerMO.machines as? Set ?? Set() + + knownMachineMOs.forEach { + container.containerMO.removeFromMachines($0) + } + + try! container.moc.save() + } + + // and set the machine ID list to something that doesn't include 'aaa' + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["bbb", "ccc"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["bbb", "ccc"]), disallowedMachineIDs: [], unknownMachineIDs: Set(["aaa"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // But check that it exists, and set its modification date to a while ago for an upcoming test + container.moc.performAndWait { + let knownMachineMOs = container.containerMO.machines as? Set ?? Set() + + let aaaMOs = knownMachineMOs.filter { $0.machineID == "aaa" } + XCTAssert(aaaMOs.count == 1, "Should have one machine MO for aaa") + + let aaaMO = aaaMOs.first! + XCTAssertEqual(aaaMO.status, Int64(TPMachineIDStatus.unknown.rawValue), "Status of aaa MO should be 'unknown'") + XCTAssertFalse(aaaMO.allowed, "allowed should no longer be a used field") + + aaaMO.modified = Date(timeIntervalSinceNow: -60) + try! container.moc.save() + } + + // With it 'modified' only 60s ago, we shouldn't want a list fetch + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Setting it again is fine... + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["bbb", "ccc"], listDifference: false), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["bbb", "ccc"]), disallowedMachineIDs: [], unknownMachineIDs: Set(["aaa"]), persistentStore: description, cuttlefish: self.cuttlefish) + + // And doesn't reset the modified date on the record + container.moc.performAndWait { + let knownMachineMOs = container.containerMO.machines as? Set ?? Set() + + let aaaMOs = knownMachineMOs.filter { $0.machineID == "aaa" } + XCTAssert(aaaMOs.count == 1, "Should have one machine MO for aaa") + + let aaaMO = aaaMOs.first! + XCTAssertEqual(aaaMO.status, Int64(TPMachineIDStatus.unknown.rawValue), "Status of aaa MO should be 'unknown'") + XCTAssertFalse(aaaMO.allowed, "allowed should no longer be a used field") + + XCTAssertLessThan(aaaMO.modified!, Date(timeIntervalSinceNow: -5), "Modification date of record should still be its previously on-disk value") + } + + // And can be promoted to 'allowed' + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb"]), disallowedMachineIDs: ["ccc"], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + } + + func testMachineIDListSetDisallowedOldUnknownMachineIDs() throws { + let description = tmpStoreDescription(name: "container.db") + let (container, _) = try establish(reload: false, store: description) + + container.moc.performAndWait { + let knownMachineMOs = container.containerMO.machines as? Set ?? Set() + + knownMachineMOs.forEach { + container.containerMO.removeFromMachines($0) + } + + try! container.moc.save() + } + + // and set the machine ID list to something that doesn't include 'aaa' + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["bbb", "ccc"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["bbb", "ccc"]), disallowedMachineIDs: [], unknownMachineIDs: Set(["aaa"]), persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // But an entry for "aaa" should exist, as a peer in the model claims it as their MID + container.moc.performAndWait { + let knownMachineMOs = container.containerMO.machines as? Set ?? Set() + + let aaaMOs = knownMachineMOs.filter { $0.machineID == "aaa" } + XCTAssertEqual(aaaMOs.count, 1, "Should have one machine MO for aaa") + + let aaaMO = aaaMOs.first! + XCTAssertEqual(aaaMO.status, Int64(TPMachineIDStatus.unknown.rawValue), "Status of aaa MO should be 'unknown'") + XCTAssertFalse(aaaMO.allowed, "allowed should no longer be a used field") + + // Pretend that aaa was added 49 hours ago + aaaMO.modified = Date(timeIntervalSinceNow: -60*60*49) + try! container.moc.save() + } + + XCTAssertTrue(container.onqueueFullIDMSListWouldBeHelpful(), "Container should think it could use an IDMS list set: there's machine IDs pending removal") + + // And, setting the list again should disallow aaa, since it is so old + // Note that this _should_ return a list difference, since A is promoted to disallowed + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["bbb", "ccc"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["bbb", "ccc"]), disallowedMachineIDs: ["aaa"], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // Setting ths list again has no change + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["bbb", "ccc"], listDifference: false), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["bbb", "ccc"]), disallowedMachineIDs: ["aaa"], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + + // But A can appear again, no problem. + XCTAssertNil(container.setAllowedMachineIDsSync(test: self, allowedMachineIDs: ["aaa", "bbb", "ccc"], listDifference: true), "should be able to set allowed machine IDs") + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]), disallowedMachineIDs: [], persistentStore: description, cuttlefish: self.cuttlefish) + XCTAssertFalse(container.onqueueFullIDMSListWouldBeHelpful(), "Container shouldn't think it could use an IDMS list set") + } + + func testMachineIDListHandlingWithPeers() throws { + let description = tmpStoreDescription(name: "container.db") + let (container, peerID1) = try establish(reload: false, store: description) + + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]), disallowedMachineIDs: [], unknownMachineIDs: Set(), persistentStore: description, cuttlefish: self.cuttlefish) + + let unknownMachineID = "not-on-list" + let (_, peerID2) = try self.joinByVoucher(sponsor: container, + containerID: "second", + machineID: unknownMachineID, + machineIDs: Set([unknownMachineID, "aaa", "bbb", "ccc"]), + store: description) + + // And the first container accepts the join... + let (_, cUpdateError) = container.updateSync(test: self) + XCTAssertNil(cUpdateError, "Should be able to update first container") + assertTrusts(context: container, peerIDs: [peerID1, peerID2]) + + try self.assert(container: container, allowedMachineIDs: Set(["aaa", "bbb", "ccc"]), disallowedMachineIDs: [], unknownMachineIDs: Set([unknownMachineID]), persistentStore: description, cuttlefish: self.cuttlefish) + } + + func testContainerAndModelConsistency() throws{ + + let preTestContainerName = ContainerName(container: "testToCreatePrepareData", context: "context") + let description = tmpStoreDescription(name: "container.db") + let containerTest = try Container(name: preTestContainerName, persistentStoreDescription: description, cuttlefish: cuttlefish) + let (peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error) = containerTest.prepareSync(test: self, epoch: 1, machineID: "aaa", bottleSalt: "123456789", bottleID: UUID().uuidString, modelID: "iPhone1,1") + XCTAssertNil(error) + XCTAssertNotNil(peerID) + XCTAssertNotNil(permanentInfo) + XCTAssertNotNil(permanentInfoSig) + XCTAssertNotNil(stableInfo) + XCTAssertNotNil(stableInfoSig) + + let containerName = ContainerName(container: "test", context: OTDefaultContext) + let url = Bundle(for: type(of: self)).url(forResource: "TrustedPeersHelper", withExtension: "momd")! + let mom = getOrMakeModel(url: url) + let persistentContainer = NSPersistentContainer(name: "TrustedPeersHelper", managedObjectModel: mom) + persistentContainer.persistentStoreDescriptions = [description] + + persistentContainer.loadPersistentStores { _, error in + XCTAssertNil(error, "Should be no error loading persistent stores") + } + + let moc = persistentContainer.newBackgroundContext() + moc.performAndWait { + let containerMO = ContainerMO(context: moc) + containerMO.name = containerName.asSingleString() + containerMO.allowedMachineIDs = Set(["aaa"]) as NSSet + containerMO.egoPeerID = peerID + containerMO.egoPeerPermanentInfo = permanentInfo + containerMO.egoPeerPermanentInfoSig = permanentInfoSig + containerMO.egoPeerStableInfoSig = stableInfoSig + containerMO.egoPeerStableInfo = stableInfo + let containerEgoStableInfo = TPPeerStableInfo(data: stableInfo!, sig: stableInfoSig!) + do{ + let peerKeys: OctagonSelfPeerKeys = try loadEgoKeysSync(peerID: containerMO.egoPeerID!) + let info3: TPPeerStableInfo = TPPeerStableInfo(clock: containerEgoStableInfo!.clock + 2, + policyVersion:containerEgoStableInfo!.policyVersion, + policyHash:containerEgoStableInfo!.policyHash, + policySecrets:containerEgoStableInfo!.policySecrets, + deviceName:containerEgoStableInfo!.deviceName, + serialNumber:containerEgoStableInfo!.serialNumber, + osVersion:containerEgoStableInfo!.osVersion, + signing:peerKeys.signingKey, + recoverySigningPubKey:containerEgoStableInfo!.recoverySigningPublicKey, + recoveryEncryptionPubKey:containerEgoStableInfo!.recoveryEncryptionPublicKey, + error:nil) + + //setting the containerMO's ego stable info to an old clock + containerMO.egoPeerStableInfo = containerEgoStableInfo!.data + containerMO.egoPeerStableInfoSig = containerEgoStableInfo!.sig + + //now we are adding the ego stable info with a clock of 3 to the list of peers + let peer = PeerMO(context: moc) + peer.peerID = peerID + peer.permanentInfo = permanentInfo + peer.permanentInfoSig = permanentInfoSig + peer.stableInfo = info3.data + peer.stableInfoSig = info3.sig + peer.isEgoPeer = true + peer.container = containerMO + + containerMO.addToPeers(peer) + + //at this point the containerMO's egoStableInfo should have a clock of 1 + //the saved ego peer in the peer list has a clock of 3 + + } catch { + XCTFail("load ego keys failed: \(error)") + } + XCTAssertNoThrow(try! moc.save()) + } + + // Now TPH boots up with a preexisting model + let container = try Container(name: containerName, persistentStoreDescription: description, cuttlefish: cuttlefish) + + let stableInfoAfterBoot = TPPeerStableInfo(data: container.containerMO.egoPeerStableInfo!, sig: container.containerMO.egoPeerStableInfoSig!) + XCTAssertNotNil(stableInfoAfterBoot) + + //after boot the clock should be updated to the one that was saved in the model + XCTAssertEqual(stableInfoAfterBoot!.clock, 3, "clock should be updated to 3") + } +} diff --git a/keychain/analytics/C2Metric.proto b/keychain/analytics/C2Metric.proto new file mode 100644 index 00000000..1634dd04 --- /dev/null +++ b/keychain/analytics/C2Metric.proto @@ -0,0 +1,186 @@ +package SecC2MP; + +option java_package="com.apple.edge.metricsedge.model"; +option java_outer_classname = "C2Metric"; + +option (objc_class_default_visibility) = "hidden"; + +message Error { + optional string error_domain = 1; + optional int64 error_code = 2; + optional string error_description = 3; + optional Error underlying_error = 4; +} + +message CloudKitOperationGroupInfo { + optional string operation_group_id = 1; + optional string operation_group_name = 2; + + optional bool operation_group_triggered = 101; +} + +message CloudKitOperationInfo { + optional string operation_id = 1; + optional string operation_type = 2; + + optional bool operation_triggered = 101; + + optional uint32 operation_group_index = 201; // Index of associated Metric.CloudKitInfo.operation_group +} + +message Metric { + enum Type { + none_type = 0; + + network_event_type = 200; + generic_event_type = 201; + } + optional Type metric_type = 1; + + message DeviceInfo { + optional string product_name = 101; + optional string product_type = 102; + optional string product_version = 103; + optional string product_build = 104; + optional bool is_apple_internal = 105; + + optional string process_name = 201; + optional string process_version = 202; + optional string process_uuid = 203; + + optional string user_default_test_name = 301; + message InternalTestConfig { + optional string key = 101; + optional string value = 102; + } + repeated InternalTestConfig internal_test_config = 302; + } + optional DeviceInfo device_info = 2; + + message CloudKitInfo { + optional string client_process_version = 102; + optional string client_bundle_id = 103; + + optional string container = 201; + optional string environment = 202; + optional bool anonymous = 203; + + repeated CloudKitOperationGroupInfo operation_group = 301; + optional uint64 report_operation_group_frequency = 302; + optional uint64 report_operation_group_frequency_base = 303; + + repeated CloudKitOperationInfo client_operation = 401; + optional uint64 report_client_operation_frequency = 402; + optional uint64 report_client_operation_frequency_base = 403; + } + optional CloudKitInfo cloudkit_info = 3; + + message ServerInfo { + optional string service_name = 102; + optional string partition = 103; + optional string service_build = 104; + optional string service_instance = 105; + } + optional ServerInfo server_info = 4; + + enum Trigger { + none_trigger = 0; + + user_default_trigger = 1; + frequency_trigger = 2; + response_header_trigger = 4; // Can only trigger NetworkStatistic metrics. + client_operation_frequency_trigger = 8; + operation_group_frequency_trigger = 16; + push_trigger = 32; + } + optional uint64 triggers = 100; + optional uint64 report_frequency = 101; + optional uint64 report_frequency_base = 102; + + optional NetworkEvent network_event = 200; + optional GenericEvent generic_event = 201; +} + +message NetworkEvent { + enum Trigger { // Deprecated. Use Metric.Trigger instead. + none_trigger = 0; + + user_default_trigger = 1; + frequency_trigger = 2; + response_header_trigger = 4; + } + optional uint64 triggers = 1; // Deprecated. Use Metric.triggers instead. + optional uint64 report_frequency = 2; // Deprecated. Use Metric.report_frequency instead. + optional uint64 report_frequency_base = 3; // Deprecated. Use Metric.report_frequency_base instead. + + optional string network_task_description = 101; + optional string network_hostname = 102; + optional string network_remote_addresss_and_port = 103; + optional string network_connection_uuid = 104; + optional bool network_connection_reused = 105; + optional string network_interface_identifier = 106; + optional string network_protocol_name = 107; + optional uint32 network_request_header_size = 108; + optional uint64 network_request_body_bytes_sent = 109; + optional uint32 network_response_header_size = 110; + optional uint64 network_response_body_bytes_received = 111; + optional uint32 network_previous_attempt_count = 112; + optional Error network_fatal_error = 113; + optional uint64 network_status_code = 114; + optional string network_request_uri = 115; + + optional uint64 timestamp_c2_init = 201; + optional uint64 timestamp_c2_start = 202; + optional uint64 timestamp_c2_now = 203; + optional uint64 timestamp_dns_start = 204; + optional uint64 timestamp_dns_end = 205; + optional uint64 timestamp_tcp_start = 206; + optional uint64 timestamp_tcp_end = 207; + optional uint64 timestamp_ssl_start = 208; + optional uint64 timestamp_request_start = 209; + optional uint64 timestamp_request_end = 210; + optional uint64 timestamp_response_start = 211; + optional uint64 timestamp_response_end = 212; + + optional string options_quality_of_service = 301; + optional bool options_out_of_process = 302; + optional bool options_out_of_process_force_discretionary = 303; + optional bool options_allow_expensive_access = 304; + optional bool options_allow_power_nap_scheduling = 305; + optional uint32 options_timeout_interval_for_request = 306; + optional uint32 options_timeout_interval_for_resource = 307; + optional string options_source_application_bundle_identifier = 308; + optional string options_source_application_secondary_identifier = 309; + optional bool options_apple_id_context = 310; + optional bool options_tls_pinning_required = 311; +} + +message GenericEvent { + enum Type { + none = 0; + + cloudkit = 101; + cloudkit_client = 201; + server = 301; + } + optional Type type = 1; + + optional string name = 101; + + optional uint64 timestamp_start = 201; + optional uint64 timestamp_end = 202; + + message GenericEventMetric { + optional string key = 101; + + message GenericEventMetricValue { + optional string string_value = 101; + optional double double_value = 102; + optional uint64 date_value = 103; + + optional Error error_value = 201; + } + optional GenericEventMetricValue value = 201; + } + repeated GenericEventMetric metric = 301; +} diff --git a/keychain/analytics/C2Metric/SECC2MPCloudKitInfo.h b/keychain/analytics/C2Metric/SECC2MPCloudKitInfo.h new file mode 100644 index 00000000..0a001ec3 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPCloudKitInfo.h @@ -0,0 +1,94 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPCloudKitOperationGroupInfo; +@class SECC2MPCloudKitOperationInfo; + +#ifdef __cplusplus +#define SECC2MPCLOUDKITINFO_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPCLOUDKITINFO_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPCloudKitInfo : PBCodable +{ + uint64_t _reportClientOperationFrequency; + uint64_t _reportClientOperationFrequencyBase; + uint64_t _reportOperationGroupFrequency; + uint64_t _reportOperationGroupFrequencyBase; + NSString *_clientBundleId; + NSMutableArray *_clientOperations; + NSString *_clientProcessVersion; + NSString *_container; + NSString *_environment; + NSMutableArray *_operationGroups; + BOOL _anonymous; + struct { + int reportClientOperationFrequency:1; + int reportClientOperationFrequencyBase:1; + int reportOperationGroupFrequency:1; + int reportOperationGroupFrequencyBase:1; + int anonymous:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasClientProcessVersion; +@property (nonatomic, retain) NSString *clientProcessVersion; + +@property (nonatomic, readonly) BOOL hasClientBundleId; +@property (nonatomic, retain) NSString *clientBundleId; + +@property (nonatomic, readonly) BOOL hasContainer; +@property (nonatomic, retain) NSString *container; + +@property (nonatomic, readonly) BOOL hasEnvironment; +@property (nonatomic, retain) NSString *environment; + +@property (nonatomic) BOOL hasAnonymous; +@property (nonatomic) BOOL anonymous; + +@property (nonatomic, retain) NSMutableArray *operationGroups; +- (void)clearOperationGroups; +- (void)addOperationGroup:(SECC2MPCloudKitOperationGroupInfo *)i; +- (NSUInteger)operationGroupsCount; +- (SECC2MPCloudKitOperationGroupInfo *)operationGroupAtIndex:(NSUInteger)idx; ++ (Class)operationGroupType; + +@property (nonatomic) BOOL hasReportOperationGroupFrequency; +@property (nonatomic) uint64_t reportOperationGroupFrequency; + +@property (nonatomic) BOOL hasReportOperationGroupFrequencyBase; +@property (nonatomic) uint64_t reportOperationGroupFrequencyBase; + +@property (nonatomic, retain) NSMutableArray *clientOperations; +- (void)clearClientOperations; +- (void)addClientOperation:(SECC2MPCloudKitOperationInfo *)i; +- (NSUInteger)clientOperationsCount; +- (SECC2MPCloudKitOperationInfo *)clientOperationAtIndex:(NSUInteger)idx; ++ (Class)clientOperationType; + +@property (nonatomic) BOOL hasReportClientOperationFrequency; +@property (nonatomic) uint64_t reportClientOperationFrequency; + +@property (nonatomic) BOOL hasReportClientOperationFrequencyBase; +@property (nonatomic) uint64_t reportClientOperationFrequencyBase; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPCloudKitInfo *)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:(SECC2MPCloudKitInfo *)other; + +SECC2MPCLOUDKITINFO_FUNCTION BOOL SECC2MPCloudKitInfoReadFrom(__unsafe_unretained SECC2MPCloudKitInfo *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPCloudKitInfo.m b/keychain/analytics/C2Metric/SECC2MPCloudKitInfo.m new file mode 100644 index 00000000..3f50f1a2 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPCloudKitInfo.m @@ -0,0 +1,644 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPCloudKitInfo.h" +#import +#import +#import + +#import "SECC2MPCloudKitOperationGroupInfo.h" +#import "SECC2MPCloudKitOperationInfo.h" + +#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 SECC2MPCloudKitInfo + +- (BOOL)hasClientProcessVersion +{ + return _clientProcessVersion != nil; +} +@synthesize clientProcessVersion = _clientProcessVersion; +- (BOOL)hasClientBundleId +{ + return _clientBundleId != nil; +} +@synthesize clientBundleId = _clientBundleId; +- (BOOL)hasContainer +{ + return _container != nil; +} +@synthesize container = _container; +- (BOOL)hasEnvironment +{ + return _environment != nil; +} +@synthesize environment = _environment; +@synthesize anonymous = _anonymous; +- (void)setAnonymous:(BOOL)v +{ + _has.anonymous = YES; + _anonymous = v; +} +- (void)setHasAnonymous:(BOOL)f +{ + _has.anonymous = f; +} +- (BOOL)hasAnonymous +{ + return _has.anonymous; +} +@synthesize operationGroups = _operationGroups; +- (void)clearOperationGroups +{ + [_operationGroups removeAllObjects]; +} +- (void)addOperationGroup:(SECC2MPCloudKitOperationGroupInfo *)i +{ + if (!_operationGroups) + { + _operationGroups = [[NSMutableArray alloc] init]; + } + [_operationGroups addObject:i]; +} +- (NSUInteger)operationGroupsCount +{ + return [_operationGroups count]; +} +- (SECC2MPCloudKitOperationGroupInfo *)operationGroupAtIndex:(NSUInteger)idx +{ + return [_operationGroups objectAtIndex:idx]; +} ++ (Class)operationGroupType +{ + return [SECC2MPCloudKitOperationGroupInfo class]; +} +@synthesize reportOperationGroupFrequency = _reportOperationGroupFrequency; +- (void)setReportOperationGroupFrequency:(uint64_t)v +{ + _has.reportOperationGroupFrequency = YES; + _reportOperationGroupFrequency = v; +} +- (void)setHasReportOperationGroupFrequency:(BOOL)f +{ + _has.reportOperationGroupFrequency = f; +} +- (BOOL)hasReportOperationGroupFrequency +{ + return _has.reportOperationGroupFrequency; +} +@synthesize reportOperationGroupFrequencyBase = _reportOperationGroupFrequencyBase; +- (void)setReportOperationGroupFrequencyBase:(uint64_t)v +{ + _has.reportOperationGroupFrequencyBase = YES; + _reportOperationGroupFrequencyBase = v; +} +- (void)setHasReportOperationGroupFrequencyBase:(BOOL)f +{ + _has.reportOperationGroupFrequencyBase = f; +} +- (BOOL)hasReportOperationGroupFrequencyBase +{ + return _has.reportOperationGroupFrequencyBase; +} +@synthesize clientOperations = _clientOperations; +- (void)clearClientOperations +{ + [_clientOperations removeAllObjects]; +} +- (void)addClientOperation:(SECC2MPCloudKitOperationInfo *)i +{ + if (!_clientOperations) + { + _clientOperations = [[NSMutableArray alloc] init]; + } + [_clientOperations addObject:i]; +} +- (NSUInteger)clientOperationsCount +{ + return [_clientOperations count]; +} +- (SECC2MPCloudKitOperationInfo *)clientOperationAtIndex:(NSUInteger)idx +{ + return [_clientOperations objectAtIndex:idx]; +} ++ (Class)clientOperationType +{ + return [SECC2MPCloudKitOperationInfo class]; +} +@synthesize reportClientOperationFrequency = _reportClientOperationFrequency; +- (void)setReportClientOperationFrequency:(uint64_t)v +{ + _has.reportClientOperationFrequency = YES; + _reportClientOperationFrequency = v; +} +- (void)setHasReportClientOperationFrequency:(BOOL)f +{ + _has.reportClientOperationFrequency = f; +} +- (BOOL)hasReportClientOperationFrequency +{ + return _has.reportClientOperationFrequency; +} +@synthesize reportClientOperationFrequencyBase = _reportClientOperationFrequencyBase; +- (void)setReportClientOperationFrequencyBase:(uint64_t)v +{ + _has.reportClientOperationFrequencyBase = YES; + _reportClientOperationFrequencyBase = v; +} +- (void)setHasReportClientOperationFrequencyBase:(BOOL)f +{ + _has.reportClientOperationFrequencyBase = f; +} +- (BOOL)hasReportClientOperationFrequencyBase +{ + return _has.reportClientOperationFrequencyBase; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_clientProcessVersion) + { + [dict setObject:self->_clientProcessVersion forKey:@"client_process_version"]; + } + if (self->_clientBundleId) + { + [dict setObject:self->_clientBundleId forKey:@"client_bundle_id"]; + } + if (self->_container) + { + [dict setObject:self->_container forKey:@"container"]; + } + if (self->_environment) + { + [dict setObject:self->_environment forKey:@"environment"]; + } + if (self->_has.anonymous) + { + [dict setObject:[NSNumber numberWithBool:self->_anonymous] forKey:@"anonymous"]; + } + if ([self->_operationGroups count]) + { + NSMutableArray *operationGroupsDictReprs = [[NSMutableArray alloc] initWithCapacity:[self->_operationGroups count]]; + for (SECC2MPCloudKitOperationGroupInfo *i_operationGroup in self->_operationGroups) + { + [operationGroupsDictReprs addObject:[i_operationGroup dictionaryRepresentation]]; + } + [dict setObject:operationGroupsDictReprs forKey:@"operation_group"]; + } + if (self->_has.reportOperationGroupFrequency) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportOperationGroupFrequency] forKey:@"report_operation_group_frequency"]; + } + if (self->_has.reportOperationGroupFrequencyBase) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportOperationGroupFrequencyBase] forKey:@"report_operation_group_frequency_base"]; + } + if ([self->_clientOperations count]) + { + NSMutableArray *clientOperationsDictReprs = [[NSMutableArray alloc] initWithCapacity:[self->_clientOperations count]]; + for (SECC2MPCloudKitOperationInfo *i_clientOperation in self->_clientOperations) + { + [clientOperationsDictReprs addObject:[i_clientOperation dictionaryRepresentation]]; + } + [dict setObject:clientOperationsDictReprs forKey:@"client_operation"]; + } + if (self->_has.reportClientOperationFrequency) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportClientOperationFrequency] forKey:@"report_client_operation_frequency"]; + } + if (self->_has.reportClientOperationFrequencyBase) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportClientOperationFrequencyBase] forKey:@"report_client_operation_frequency_base"]; + } + return dict; +} + +BOOL SECC2MPCloudKitInfoReadFrom(__unsafe_unretained SECC2MPCloudKitInfo *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 102 /* clientProcessVersion */: + { + NSString *new_clientProcessVersion = PBReaderReadString(reader); + self->_clientProcessVersion = new_clientProcessVersion; + } + break; + case 103 /* clientBundleId */: + { + NSString *new_clientBundleId = PBReaderReadString(reader); + self->_clientBundleId = new_clientBundleId; + } + break; + case 201 /* container */: + { + NSString *new_container = PBReaderReadString(reader); + self->_container = new_container; + } + break; + case 202 /* environment */: + { + NSString *new_environment = PBReaderReadString(reader); + self->_environment = new_environment; + } + break; + case 203 /* anonymous */: + { + self->_has.anonymous = YES; + self->_anonymous = PBReaderReadBOOL(reader); + } + break; + case 301 /* operationGroups */: + { + SECC2MPCloudKitOperationGroupInfo *new_operationGroup = [[SECC2MPCloudKitOperationGroupInfo alloc] init]; + [self addOperationGroup:new_operationGroup]; + PBDataReaderMark mark_operationGroup; + BOOL markError = !PBReaderPlaceMark(reader, &mark_operationGroup); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPCloudKitOperationGroupInfoReadFrom(new_operationGroup, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_operationGroup); + } + break; + case 302 /* reportOperationGroupFrequency */: + { + self->_has.reportOperationGroupFrequency = YES; + self->_reportOperationGroupFrequency = PBReaderReadUint64(reader); + } + break; + case 303 /* reportOperationGroupFrequencyBase */: + { + self->_has.reportOperationGroupFrequencyBase = YES; + self->_reportOperationGroupFrequencyBase = PBReaderReadUint64(reader); + } + break; + case 401 /* clientOperations */: + { + SECC2MPCloudKitOperationInfo *new_clientOperation = [[SECC2MPCloudKitOperationInfo alloc] init]; + [self addClientOperation:new_clientOperation]; + PBDataReaderMark mark_clientOperation; + BOOL markError = !PBReaderPlaceMark(reader, &mark_clientOperation); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPCloudKitOperationInfoReadFrom(new_clientOperation, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_clientOperation); + } + break; + case 402 /* reportClientOperationFrequency */: + { + self->_has.reportClientOperationFrequency = YES; + self->_reportClientOperationFrequency = PBReaderReadUint64(reader); + } + break; + case 403 /* reportClientOperationFrequencyBase */: + { + self->_has.reportClientOperationFrequencyBase = YES; + self->_reportClientOperationFrequencyBase = PBReaderReadUint64(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPCloudKitInfoReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* clientProcessVersion */ + { + if (self->_clientProcessVersion) + { + PBDataWriterWriteStringField(writer, self->_clientProcessVersion, 102); + } + } + /* clientBundleId */ + { + if (self->_clientBundleId) + { + PBDataWriterWriteStringField(writer, self->_clientBundleId, 103); + } + } + /* container */ + { + if (self->_container) + { + PBDataWriterWriteStringField(writer, self->_container, 201); + } + } + /* environment */ + { + if (self->_environment) + { + PBDataWriterWriteStringField(writer, self->_environment, 202); + } + } + /* anonymous */ + { + if (self->_has.anonymous) + { + PBDataWriterWriteBOOLField(writer, self->_anonymous, 203); + } + } + /* operationGroups */ + { + for (SECC2MPCloudKitOperationGroupInfo *i_operationGroup in self->_operationGroups) + { + PBDataWriterWriteSubmessage(writer, i_operationGroup, 301); + } + } + /* reportOperationGroupFrequency */ + { + if (self->_has.reportOperationGroupFrequency) + { + PBDataWriterWriteUint64Field(writer, self->_reportOperationGroupFrequency, 302); + } + } + /* reportOperationGroupFrequencyBase */ + { + if (self->_has.reportOperationGroupFrequencyBase) + { + PBDataWriterWriteUint64Field(writer, self->_reportOperationGroupFrequencyBase, 303); + } + } + /* clientOperations */ + { + for (SECC2MPCloudKitOperationInfo *i_clientOperation in self->_clientOperations) + { + PBDataWriterWriteSubmessage(writer, i_clientOperation, 401); + } + } + /* reportClientOperationFrequency */ + { + if (self->_has.reportClientOperationFrequency) + { + PBDataWriterWriteUint64Field(writer, self->_reportClientOperationFrequency, 402); + } + } + /* reportClientOperationFrequencyBase */ + { + if (self->_has.reportClientOperationFrequencyBase) + { + PBDataWriterWriteUint64Field(writer, self->_reportClientOperationFrequencyBase, 403); + } + } +} + +- (void)copyTo:(SECC2MPCloudKitInfo *)other +{ + if (_clientProcessVersion) + { + other.clientProcessVersion = _clientProcessVersion; + } + if (_clientBundleId) + { + other.clientBundleId = _clientBundleId; + } + if (_container) + { + other.container = _container; + } + if (_environment) + { + other.environment = _environment; + } + if (self->_has.anonymous) + { + other->_anonymous = _anonymous; + other->_has.anonymous = YES; + } + if ([self operationGroupsCount]) + { + [other clearOperationGroups]; + NSUInteger operationGroupsCnt = [self operationGroupsCount]; + for (NSUInteger i = 0; i < operationGroupsCnt; i++) + { + [other addOperationGroup:[self operationGroupAtIndex:i]]; + } + } + if (self->_has.reportOperationGroupFrequency) + { + other->_reportOperationGroupFrequency = _reportOperationGroupFrequency; + other->_has.reportOperationGroupFrequency = YES; + } + if (self->_has.reportOperationGroupFrequencyBase) + { + other->_reportOperationGroupFrequencyBase = _reportOperationGroupFrequencyBase; + other->_has.reportOperationGroupFrequencyBase = YES; + } + if ([self clientOperationsCount]) + { + [other clearClientOperations]; + NSUInteger clientOperationsCnt = [self clientOperationsCount]; + for (NSUInteger i = 0; i < clientOperationsCnt; i++) + { + [other addClientOperation:[self clientOperationAtIndex:i]]; + } + } + if (self->_has.reportClientOperationFrequency) + { + other->_reportClientOperationFrequency = _reportClientOperationFrequency; + other->_has.reportClientOperationFrequency = YES; + } + if (self->_has.reportClientOperationFrequencyBase) + { + other->_reportClientOperationFrequencyBase = _reportClientOperationFrequencyBase; + other->_has.reportClientOperationFrequencyBase = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPCloudKitInfo *copy = [[[self class] allocWithZone:zone] init]; + copy->_clientProcessVersion = [_clientProcessVersion copyWithZone:zone]; + copy->_clientBundleId = [_clientBundleId copyWithZone:zone]; + copy->_container = [_container copyWithZone:zone]; + copy->_environment = [_environment copyWithZone:zone]; + if (self->_has.anonymous) + { + copy->_anonymous = _anonymous; + copy->_has.anonymous = YES; + } + for (SECC2MPCloudKitOperationGroupInfo *v in _operationGroups) + { + SECC2MPCloudKitOperationGroupInfo *vCopy = [v copyWithZone:zone]; + [copy addOperationGroup:vCopy]; + } + if (self->_has.reportOperationGroupFrequency) + { + copy->_reportOperationGroupFrequency = _reportOperationGroupFrequency; + copy->_has.reportOperationGroupFrequency = YES; + } + if (self->_has.reportOperationGroupFrequencyBase) + { + copy->_reportOperationGroupFrequencyBase = _reportOperationGroupFrequencyBase; + copy->_has.reportOperationGroupFrequencyBase = YES; + } + for (SECC2MPCloudKitOperationInfo *v in _clientOperations) + { + SECC2MPCloudKitOperationInfo *vCopy = [v copyWithZone:zone]; + [copy addClientOperation:vCopy]; + } + if (self->_has.reportClientOperationFrequency) + { + copy->_reportClientOperationFrequency = _reportClientOperationFrequency; + copy->_has.reportClientOperationFrequency = YES; + } + if (self->_has.reportClientOperationFrequencyBase) + { + copy->_reportClientOperationFrequencyBase = _reportClientOperationFrequencyBase; + copy->_has.reportClientOperationFrequencyBase = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPCloudKitInfo *other = (SECC2MPCloudKitInfo *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_clientProcessVersion && !other->_clientProcessVersion) || [self->_clientProcessVersion isEqual:other->_clientProcessVersion]) + && + ((!self->_clientBundleId && !other->_clientBundleId) || [self->_clientBundleId isEqual:other->_clientBundleId]) + && + ((!self->_container && !other->_container) || [self->_container isEqual:other->_container]) + && + ((!self->_environment && !other->_environment) || [self->_environment isEqual:other->_environment]) + && + ((self->_has.anonymous && other->_has.anonymous && ((self->_anonymous && other->_anonymous) || (!self->_anonymous && !other->_anonymous))) || (!self->_has.anonymous && !other->_has.anonymous)) + && + ((!self->_operationGroups && !other->_operationGroups) || [self->_operationGroups isEqual:other->_operationGroups]) + && + ((self->_has.reportOperationGroupFrequency && other->_has.reportOperationGroupFrequency && self->_reportOperationGroupFrequency == other->_reportOperationGroupFrequency) || (!self->_has.reportOperationGroupFrequency && !other->_has.reportOperationGroupFrequency)) + && + ((self->_has.reportOperationGroupFrequencyBase && other->_has.reportOperationGroupFrequencyBase && self->_reportOperationGroupFrequencyBase == other->_reportOperationGroupFrequencyBase) || (!self->_has.reportOperationGroupFrequencyBase && !other->_has.reportOperationGroupFrequencyBase)) + && + ((!self->_clientOperations && !other->_clientOperations) || [self->_clientOperations isEqual:other->_clientOperations]) + && + ((self->_has.reportClientOperationFrequency && other->_has.reportClientOperationFrequency && self->_reportClientOperationFrequency == other->_reportClientOperationFrequency) || (!self->_has.reportClientOperationFrequency && !other->_has.reportClientOperationFrequency)) + && + ((self->_has.reportClientOperationFrequencyBase && other->_has.reportClientOperationFrequencyBase && self->_reportClientOperationFrequencyBase == other->_reportClientOperationFrequencyBase) || (!self->_has.reportClientOperationFrequencyBase && !other->_has.reportClientOperationFrequencyBase)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_clientProcessVersion hash] + ^ + [self->_clientBundleId hash] + ^ + [self->_container hash] + ^ + [self->_environment hash] + ^ + (self->_has.anonymous ? PBHashInt((NSUInteger)self->_anonymous) : 0) + ^ + [self->_operationGroups hash] + ^ + (self->_has.reportOperationGroupFrequency ? PBHashInt((NSUInteger)self->_reportOperationGroupFrequency) : 0) + ^ + (self->_has.reportOperationGroupFrequencyBase ? PBHashInt((NSUInteger)self->_reportOperationGroupFrequencyBase) : 0) + ^ + [self->_clientOperations hash] + ^ + (self->_has.reportClientOperationFrequency ? PBHashInt((NSUInteger)self->_reportClientOperationFrequency) : 0) + ^ + (self->_has.reportClientOperationFrequencyBase ? PBHashInt((NSUInteger)self->_reportClientOperationFrequencyBase) : 0) + ; +} + +- (void)mergeFrom:(SECC2MPCloudKitInfo *)other +{ + if (other->_clientProcessVersion) + { + [self setClientProcessVersion:other->_clientProcessVersion]; + } + if (other->_clientBundleId) + { + [self setClientBundleId:other->_clientBundleId]; + } + if (other->_container) + { + [self setContainer:other->_container]; + } + if (other->_environment) + { + [self setEnvironment:other->_environment]; + } + if (other->_has.anonymous) + { + self->_anonymous = other->_anonymous; + self->_has.anonymous = YES; + } + for (SECC2MPCloudKitOperationGroupInfo *iter_operationGroups in other->_operationGroups) + { + [self addOperationGroup:iter_operationGroups]; + } + if (other->_has.reportOperationGroupFrequency) + { + self->_reportOperationGroupFrequency = other->_reportOperationGroupFrequency; + self->_has.reportOperationGroupFrequency = YES; + } + if (other->_has.reportOperationGroupFrequencyBase) + { + self->_reportOperationGroupFrequencyBase = other->_reportOperationGroupFrequencyBase; + self->_has.reportOperationGroupFrequencyBase = YES; + } + for (SECC2MPCloudKitOperationInfo *iter_clientOperations in other->_clientOperations) + { + [self addClientOperation:iter_clientOperations]; + } + if (other->_has.reportClientOperationFrequency) + { + self->_reportClientOperationFrequency = other->_reportClientOperationFrequency; + self->_has.reportClientOperationFrequency = YES; + } + if (other->_has.reportClientOperationFrequencyBase) + { + self->_reportClientOperationFrequencyBase = other->_reportClientOperationFrequencyBase; + self->_has.reportClientOperationFrequencyBase = YES; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.h b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.h new file mode 100644 index 00000000..3dd99ffc --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.h @@ -0,0 +1,47 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +#ifdef __cplusplus +#define SECC2MPCLOUDKITOPERATIONGROUPINFO_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPCLOUDKITOPERATIONGROUPINFO_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPCloudKitOperationGroupInfo : PBCodable +{ + NSString *_operationGroupId; + NSString *_operationGroupName; + BOOL _operationGroupTriggered; + struct { + int operationGroupTriggered:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasOperationGroupId; +@property (nonatomic, retain) NSString *operationGroupId; + +@property (nonatomic, readonly) BOOL hasOperationGroupName; +@property (nonatomic, retain) NSString *operationGroupName; + +@property (nonatomic) BOOL hasOperationGroupTriggered; +@property (nonatomic) BOOL operationGroupTriggered; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPCloudKitOperationGroupInfo *)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:(SECC2MPCloudKitOperationGroupInfo *)other; + +SECC2MPCLOUDKITOPERATIONGROUPINFO_FUNCTION BOOL SECC2MPCloudKitOperationGroupInfoReadFrom(__unsafe_unretained SECC2MPCloudKitOperationGroupInfo *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.m b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.m new file mode 100644 index 00000000..7be3d9bd --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationGroupInfo.m @@ -0,0 +1,209 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPCloudKitOperationGroupInfo.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 SECC2MPCloudKitOperationGroupInfo + +- (BOOL)hasOperationGroupId +{ + return _operationGroupId != nil; +} +@synthesize operationGroupId = _operationGroupId; +- (BOOL)hasOperationGroupName +{ + return _operationGroupName != nil; +} +@synthesize operationGroupName = _operationGroupName; +@synthesize operationGroupTriggered = _operationGroupTriggered; +- (void)setOperationGroupTriggered:(BOOL)v +{ + _has.operationGroupTriggered = YES; + _operationGroupTriggered = v; +} +- (void)setHasOperationGroupTriggered:(BOOL)f +{ + _has.operationGroupTriggered = f; +} +- (BOOL)hasOperationGroupTriggered +{ + return _has.operationGroupTriggered; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_operationGroupId) + { + [dict setObject:self->_operationGroupId forKey:@"operation_group_id"]; + } + if (self->_operationGroupName) + { + [dict setObject:self->_operationGroupName forKey:@"operation_group_name"]; + } + if (self->_has.operationGroupTriggered) + { + [dict setObject:[NSNumber numberWithBool:self->_operationGroupTriggered] forKey:@"operation_group_triggered"]; + } + return dict; +} + +BOOL SECC2MPCloudKitOperationGroupInfoReadFrom(__unsafe_unretained SECC2MPCloudKitOperationGroupInfo *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 /* operationGroupId */: + { + NSString *new_operationGroupId = PBReaderReadString(reader); + self->_operationGroupId = new_operationGroupId; + } + break; + case 2 /* operationGroupName */: + { + NSString *new_operationGroupName = PBReaderReadString(reader); + self->_operationGroupName = new_operationGroupName; + } + break; + case 101 /* operationGroupTriggered */: + { + self->_has.operationGroupTriggered = YES; + self->_operationGroupTriggered = PBReaderReadBOOL(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPCloudKitOperationGroupInfoReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* operationGroupId */ + { + if (self->_operationGroupId) + { + PBDataWriterWriteStringField(writer, self->_operationGroupId, 1); + } + } + /* operationGroupName */ + { + if (self->_operationGroupName) + { + PBDataWriterWriteStringField(writer, self->_operationGroupName, 2); + } + } + /* operationGroupTriggered */ + { + if (self->_has.operationGroupTriggered) + { + PBDataWriterWriteBOOLField(writer, self->_operationGroupTriggered, 101); + } + } +} + +- (void)copyTo:(SECC2MPCloudKitOperationGroupInfo *)other +{ + if (_operationGroupId) + { + other.operationGroupId = _operationGroupId; + } + if (_operationGroupName) + { + other.operationGroupName = _operationGroupName; + } + if (self->_has.operationGroupTriggered) + { + other->_operationGroupTriggered = _operationGroupTriggered; + other->_has.operationGroupTriggered = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPCloudKitOperationGroupInfo *copy = [[[self class] allocWithZone:zone] init]; + copy->_operationGroupId = [_operationGroupId copyWithZone:zone]; + copy->_operationGroupName = [_operationGroupName copyWithZone:zone]; + if (self->_has.operationGroupTriggered) + { + copy->_operationGroupTriggered = _operationGroupTriggered; + copy->_has.operationGroupTriggered = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPCloudKitOperationGroupInfo *other = (SECC2MPCloudKitOperationGroupInfo *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_operationGroupId && !other->_operationGroupId) || [self->_operationGroupId isEqual:other->_operationGroupId]) + && + ((!self->_operationGroupName && !other->_operationGroupName) || [self->_operationGroupName isEqual:other->_operationGroupName]) + && + ((self->_has.operationGroupTriggered && other->_has.operationGroupTriggered && ((self->_operationGroupTriggered && other->_operationGroupTriggered) || (!self->_operationGroupTriggered && !other->_operationGroupTriggered))) || (!self->_has.operationGroupTriggered && !other->_has.operationGroupTriggered)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_operationGroupId hash] + ^ + [self->_operationGroupName hash] + ^ + (self->_has.operationGroupTriggered ? PBHashInt((NSUInteger)self->_operationGroupTriggered) : 0) + ; +} + +- (void)mergeFrom:(SECC2MPCloudKitOperationGroupInfo *)other +{ + if (other->_operationGroupId) + { + [self setOperationGroupId:other->_operationGroupId]; + } + if (other->_operationGroupName) + { + [self setOperationGroupName:other->_operationGroupName]; + } + if (other->_has.operationGroupTriggered) + { + self->_operationGroupTriggered = other->_operationGroupTriggered; + self->_has.operationGroupTriggered = YES; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.h b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.h new file mode 100644 index 00000000..a318db0b --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.h @@ -0,0 +1,53 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +#ifdef __cplusplus +#define SECC2MPCLOUDKITOPERATIONINFO_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPCLOUDKITOPERATIONINFO_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPCloudKitOperationInfo : PBCodable +{ + uint32_t _operationGroupIndex; + NSString *_operationId; + NSString *_operationType; + BOOL _operationTriggered; + struct { + int operationGroupIndex:1; + int operationTriggered:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasOperationId; +@property (nonatomic, retain) NSString *operationId; + +@property (nonatomic, readonly) BOOL hasOperationType; +@property (nonatomic, retain) NSString *operationType; + +@property (nonatomic) BOOL hasOperationTriggered; +@property (nonatomic) BOOL operationTriggered; + +@property (nonatomic) BOOL hasOperationGroupIndex; +/** Index of associated Metric.CloudKitInfo.operation_group */ +@property (nonatomic) uint32_t operationGroupIndex; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPCloudKitOperationInfo *)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:(SECC2MPCloudKitOperationInfo *)other; + +SECC2MPCLOUDKITOPERATIONINFO_FUNCTION BOOL SECC2MPCloudKitOperationInfoReadFrom(__unsafe_unretained SECC2MPCloudKitOperationInfo *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.m b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.m new file mode 100644 index 00000000..a66c662a --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPCloudKitOperationInfo.m @@ -0,0 +1,259 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPCloudKitOperationInfo.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 SECC2MPCloudKitOperationInfo + +- (BOOL)hasOperationId +{ + return _operationId != nil; +} +@synthesize operationId = _operationId; +- (BOOL)hasOperationType +{ + return _operationType != nil; +} +@synthesize operationType = _operationType; +@synthesize operationTriggered = _operationTriggered; +- (void)setOperationTriggered:(BOOL)v +{ + _has.operationTriggered = YES; + _operationTriggered = v; +} +- (void)setHasOperationTriggered:(BOOL)f +{ + _has.operationTriggered = f; +} +- (BOOL)hasOperationTriggered +{ + return _has.operationTriggered; +} +@synthesize operationGroupIndex = _operationGroupIndex; +- (void)setOperationGroupIndex:(uint32_t)v +{ + _has.operationGroupIndex = YES; + _operationGroupIndex = v; +} +- (void)setHasOperationGroupIndex:(BOOL)f +{ + _has.operationGroupIndex = f; +} +- (BOOL)hasOperationGroupIndex +{ + return _has.operationGroupIndex; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_operationId) + { + [dict setObject:self->_operationId forKey:@"operation_id"]; + } + if (self->_operationType) + { + [dict setObject:self->_operationType forKey:@"operation_type"]; + } + if (self->_has.operationTriggered) + { + [dict setObject:[NSNumber numberWithBool:self->_operationTriggered] forKey:@"operation_triggered"]; + } + if (self->_has.operationGroupIndex) + { + [dict setObject:[NSNumber numberWithUnsignedInt:self->_operationGroupIndex] forKey:@"operation_group_index"]; + } + return dict; +} + +BOOL SECC2MPCloudKitOperationInfoReadFrom(__unsafe_unretained SECC2MPCloudKitOperationInfo *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 /* operationId */: + { + NSString *new_operationId = PBReaderReadString(reader); + self->_operationId = new_operationId; + } + break; + case 2 /* operationType */: + { + NSString *new_operationType = PBReaderReadString(reader); + self->_operationType = new_operationType; + } + break; + case 101 /* operationTriggered */: + { + self->_has.operationTriggered = YES; + self->_operationTriggered = PBReaderReadBOOL(reader); + } + break; + case 201 /* operationGroupIndex */: + { + self->_has.operationGroupIndex = YES; + self->_operationGroupIndex = PBReaderReadUint32(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPCloudKitOperationInfoReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* operationId */ + { + if (self->_operationId) + { + PBDataWriterWriteStringField(writer, self->_operationId, 1); + } + } + /* operationType */ + { + if (self->_operationType) + { + PBDataWriterWriteStringField(writer, self->_operationType, 2); + } + } + /* operationTriggered */ + { + if (self->_has.operationTriggered) + { + PBDataWriterWriteBOOLField(writer, self->_operationTriggered, 101); + } + } + /* operationGroupIndex */ + { + if (self->_has.operationGroupIndex) + { + PBDataWriterWriteUint32Field(writer, self->_operationGroupIndex, 201); + } + } +} + +- (void)copyTo:(SECC2MPCloudKitOperationInfo *)other +{ + if (_operationId) + { + other.operationId = _operationId; + } + if (_operationType) + { + other.operationType = _operationType; + } + if (self->_has.operationTriggered) + { + other->_operationTriggered = _operationTriggered; + other->_has.operationTriggered = YES; + } + if (self->_has.operationGroupIndex) + { + other->_operationGroupIndex = _operationGroupIndex; + other->_has.operationGroupIndex = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPCloudKitOperationInfo *copy = [[[self class] allocWithZone:zone] init]; + copy->_operationId = [_operationId copyWithZone:zone]; + copy->_operationType = [_operationType copyWithZone:zone]; + if (self->_has.operationTriggered) + { + copy->_operationTriggered = _operationTriggered; + copy->_has.operationTriggered = YES; + } + if (self->_has.operationGroupIndex) + { + copy->_operationGroupIndex = _operationGroupIndex; + copy->_has.operationGroupIndex = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPCloudKitOperationInfo *other = (SECC2MPCloudKitOperationInfo *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_operationId && !other->_operationId) || [self->_operationId isEqual:other->_operationId]) + && + ((!self->_operationType && !other->_operationType) || [self->_operationType isEqual:other->_operationType]) + && + ((self->_has.operationTriggered && other->_has.operationTriggered && ((self->_operationTriggered && other->_operationTriggered) || (!self->_operationTriggered && !other->_operationTriggered))) || (!self->_has.operationTriggered && !other->_has.operationTriggered)) + && + ((self->_has.operationGroupIndex && other->_has.operationGroupIndex && self->_operationGroupIndex == other->_operationGroupIndex) || (!self->_has.operationGroupIndex && !other->_has.operationGroupIndex)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_operationId hash] + ^ + [self->_operationType hash] + ^ + (self->_has.operationTriggered ? PBHashInt((NSUInteger)self->_operationTriggered) : 0) + ^ + (self->_has.operationGroupIndex ? PBHashInt((NSUInteger)self->_operationGroupIndex) : 0) + ; +} + +- (void)mergeFrom:(SECC2MPCloudKitOperationInfo *)other +{ + if (other->_operationId) + { + [self setOperationId:other->_operationId]; + } + if (other->_operationType) + { + [self setOperationType:other->_operationType]; + } + if (other->_has.operationTriggered) + { + self->_operationTriggered = other->_operationTriggered; + self->_has.operationTriggered = YES; + } + if (other->_has.operationGroupIndex) + { + self->_operationGroupIndex = other->_operationGroupIndex; + self->_has.operationGroupIndex = YES; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPDeviceInfo.h b/keychain/analytics/C2Metric/SECC2MPDeviceInfo.h new file mode 100644 index 00000000..f77e2a54 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPDeviceInfo.h @@ -0,0 +1,81 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPInternalTestConfig; + +#ifdef __cplusplus +#define SECC2MPDEVICEINFO_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPDEVICEINFO_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPDeviceInfo : PBCodable +{ + NSMutableArray *_internalTestConfigs; + NSString *_processName; + NSString *_processUuid; + NSString *_processVersion; + NSString *_productBuild; + NSString *_productName; + NSString *_productType; + NSString *_productVersion; + NSString *_userDefaultTestName; + BOOL _isAppleInternal; + struct { + int isAppleInternal:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasProductName; +@property (nonatomic, retain) NSString *productName; + +@property (nonatomic, readonly) BOOL hasProductType; +@property (nonatomic, retain) NSString *productType; + +@property (nonatomic, readonly) BOOL hasProductVersion; +@property (nonatomic, retain) NSString *productVersion; + +@property (nonatomic, readonly) BOOL hasProductBuild; +@property (nonatomic, retain) NSString *productBuild; + +@property (nonatomic) BOOL hasIsAppleInternal; +@property (nonatomic) BOOL isAppleInternal; + +@property (nonatomic, readonly) BOOL hasProcessName; +@property (nonatomic, retain) NSString *processName; + +@property (nonatomic, readonly) BOOL hasProcessVersion; +@property (nonatomic, retain) NSString *processVersion; + +@property (nonatomic, readonly) BOOL hasProcessUuid; +@property (nonatomic, retain) NSString *processUuid; + +@property (nonatomic, readonly) BOOL hasUserDefaultTestName; +@property (nonatomic, retain) NSString *userDefaultTestName; + +@property (nonatomic, retain) NSMutableArray *internalTestConfigs; +- (void)clearInternalTestConfigs; +- (void)addInternalTestConfig:(SECC2MPInternalTestConfig *)i; +- (NSUInteger)internalTestConfigsCount; +- (SECC2MPInternalTestConfig *)internalTestConfigAtIndex:(NSUInteger)idx; ++ (Class)internalTestConfigType; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPDeviceInfo *)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:(SECC2MPDeviceInfo *)other; + +SECC2MPDEVICEINFO_FUNCTION BOOL SECC2MPDeviceInfoReadFrom(__unsafe_unretained SECC2MPDeviceInfo *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPDeviceInfo.m b/keychain/analytics/C2Metric/SECC2MPDeviceInfo.m new file mode 100644 index 00000000..2649c535 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPDeviceInfo.m @@ -0,0 +1,502 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPDeviceInfo.h" +#import +#import +#import + +#import "SECC2MPInternalTestConfig.h" + +#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 SECC2MPDeviceInfo + +- (BOOL)hasProductName +{ + return _productName != nil; +} +@synthesize productName = _productName; +- (BOOL)hasProductType +{ + return _productType != nil; +} +@synthesize productType = _productType; +- (BOOL)hasProductVersion +{ + return _productVersion != nil; +} +@synthesize productVersion = _productVersion; +- (BOOL)hasProductBuild +{ + return _productBuild != nil; +} +@synthesize productBuild = _productBuild; +@synthesize isAppleInternal = _isAppleInternal; +- (void)setIsAppleInternal:(BOOL)v +{ + _has.isAppleInternal = YES; + _isAppleInternal = v; +} +- (void)setHasIsAppleInternal:(BOOL)f +{ + _has.isAppleInternal = f; +} +- (BOOL)hasIsAppleInternal +{ + return _has.isAppleInternal; +} +- (BOOL)hasProcessName +{ + return _processName != nil; +} +@synthesize processName = _processName; +- (BOOL)hasProcessVersion +{ + return _processVersion != nil; +} +@synthesize processVersion = _processVersion; +- (BOOL)hasProcessUuid +{ + return _processUuid != nil; +} +@synthesize processUuid = _processUuid; +- (BOOL)hasUserDefaultTestName +{ + return _userDefaultTestName != nil; +} +@synthesize userDefaultTestName = _userDefaultTestName; +@synthesize internalTestConfigs = _internalTestConfigs; +- (void)clearInternalTestConfigs +{ + [_internalTestConfigs removeAllObjects]; +} +- (void)addInternalTestConfig:(SECC2MPInternalTestConfig *)i +{ + if (!_internalTestConfigs) + { + _internalTestConfigs = [[NSMutableArray alloc] init]; + } + [_internalTestConfigs addObject:i]; +} +- (NSUInteger)internalTestConfigsCount +{ + return [_internalTestConfigs count]; +} +- (SECC2MPInternalTestConfig *)internalTestConfigAtIndex:(NSUInteger)idx +{ + return [_internalTestConfigs objectAtIndex:idx]; +} ++ (Class)internalTestConfigType +{ + return [SECC2MPInternalTestConfig class]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_productName) + { + [dict setObject:self->_productName forKey:@"product_name"]; + } + if (self->_productType) + { + [dict setObject:self->_productType forKey:@"product_type"]; + } + if (self->_productVersion) + { + [dict setObject:self->_productVersion forKey:@"product_version"]; + } + if (self->_productBuild) + { + [dict setObject:self->_productBuild forKey:@"product_build"]; + } + if (self->_has.isAppleInternal) + { + [dict setObject:[NSNumber numberWithBool:self->_isAppleInternal] forKey:@"is_apple_internal"]; + } + if (self->_processName) + { + [dict setObject:self->_processName forKey:@"process_name"]; + } + if (self->_processVersion) + { + [dict setObject:self->_processVersion forKey:@"process_version"]; + } + if (self->_processUuid) + { + [dict setObject:self->_processUuid forKey:@"process_uuid"]; + } + if (self->_userDefaultTestName) + { + [dict setObject:self->_userDefaultTestName forKey:@"user_default_test_name"]; + } + if ([self->_internalTestConfigs count]) + { + NSMutableArray *internalTestConfigsDictReprs = [[NSMutableArray alloc] initWithCapacity:[self->_internalTestConfigs count]]; + for (SECC2MPInternalTestConfig *i_internalTestConfig in self->_internalTestConfigs) + { + [internalTestConfigsDictReprs addObject:[i_internalTestConfig dictionaryRepresentation]]; + } + [dict setObject:internalTestConfigsDictReprs forKey:@"internal_test_config"]; + } + return dict; +} + +BOOL SECC2MPDeviceInfoReadFrom(__unsafe_unretained SECC2MPDeviceInfo *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 101 /* productName */: + { + NSString *new_productName = PBReaderReadString(reader); + self->_productName = new_productName; + } + break; + case 102 /* productType */: + { + NSString *new_productType = PBReaderReadString(reader); + self->_productType = new_productType; + } + break; + case 103 /* productVersion */: + { + NSString *new_productVersion = PBReaderReadString(reader); + self->_productVersion = new_productVersion; + } + break; + case 104 /* productBuild */: + { + NSString *new_productBuild = PBReaderReadString(reader); + self->_productBuild = new_productBuild; + } + break; + case 105 /* isAppleInternal */: + { + self->_has.isAppleInternal = YES; + self->_isAppleInternal = PBReaderReadBOOL(reader); + } + break; + case 201 /* processName */: + { + NSString *new_processName = PBReaderReadString(reader); + self->_processName = new_processName; + } + break; + case 202 /* processVersion */: + { + NSString *new_processVersion = PBReaderReadString(reader); + self->_processVersion = new_processVersion; + } + break; + case 203 /* processUuid */: + { + NSString *new_processUuid = PBReaderReadString(reader); + self->_processUuid = new_processUuid; + } + break; + case 301 /* userDefaultTestName */: + { + NSString *new_userDefaultTestName = PBReaderReadString(reader); + self->_userDefaultTestName = new_userDefaultTestName; + } + break; + case 302 /* internalTestConfigs */: + { + SECC2MPInternalTestConfig *new_internalTestConfig = [[SECC2MPInternalTestConfig alloc] init]; + [self addInternalTestConfig:new_internalTestConfig]; + PBDataReaderMark mark_internalTestConfig; + BOOL markError = !PBReaderPlaceMark(reader, &mark_internalTestConfig); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPInternalTestConfigReadFrom(new_internalTestConfig, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_internalTestConfig); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPDeviceInfoReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* productName */ + { + if (self->_productName) + { + PBDataWriterWriteStringField(writer, self->_productName, 101); + } + } + /* productType */ + { + if (self->_productType) + { + PBDataWriterWriteStringField(writer, self->_productType, 102); + } + } + /* productVersion */ + { + if (self->_productVersion) + { + PBDataWriterWriteStringField(writer, self->_productVersion, 103); + } + } + /* productBuild */ + { + if (self->_productBuild) + { + PBDataWriterWriteStringField(writer, self->_productBuild, 104); + } + } + /* isAppleInternal */ + { + if (self->_has.isAppleInternal) + { + PBDataWriterWriteBOOLField(writer, self->_isAppleInternal, 105); + } + } + /* processName */ + { + if (self->_processName) + { + PBDataWriterWriteStringField(writer, self->_processName, 201); + } + } + /* processVersion */ + { + if (self->_processVersion) + { + PBDataWriterWriteStringField(writer, self->_processVersion, 202); + } + } + /* processUuid */ + { + if (self->_processUuid) + { + PBDataWriterWriteStringField(writer, self->_processUuid, 203); + } + } + /* userDefaultTestName */ + { + if (self->_userDefaultTestName) + { + PBDataWriterWriteStringField(writer, self->_userDefaultTestName, 301); + } + } + /* internalTestConfigs */ + { + for (SECC2MPInternalTestConfig *i_internalTestConfig in self->_internalTestConfigs) + { + PBDataWriterWriteSubmessage(writer, i_internalTestConfig, 302); + } + } +} + +- (void)copyTo:(SECC2MPDeviceInfo *)other +{ + if (_productName) + { + other.productName = _productName; + } + if (_productType) + { + other.productType = _productType; + } + if (_productVersion) + { + other.productVersion = _productVersion; + } + if (_productBuild) + { + other.productBuild = _productBuild; + } + if (self->_has.isAppleInternal) + { + other->_isAppleInternal = _isAppleInternal; + other->_has.isAppleInternal = YES; + } + if (_processName) + { + other.processName = _processName; + } + if (_processVersion) + { + other.processVersion = _processVersion; + } + if (_processUuid) + { + other.processUuid = _processUuid; + } + if (_userDefaultTestName) + { + other.userDefaultTestName = _userDefaultTestName; + } + if ([self internalTestConfigsCount]) + { + [other clearInternalTestConfigs]; + NSUInteger internalTestConfigsCnt = [self internalTestConfigsCount]; + for (NSUInteger i = 0; i < internalTestConfigsCnt; i++) + { + [other addInternalTestConfig:[self internalTestConfigAtIndex:i]]; + } + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPDeviceInfo *copy = [[[self class] allocWithZone:zone] init]; + copy->_productName = [_productName copyWithZone:zone]; + copy->_productType = [_productType copyWithZone:zone]; + copy->_productVersion = [_productVersion copyWithZone:zone]; + copy->_productBuild = [_productBuild copyWithZone:zone]; + if (self->_has.isAppleInternal) + { + copy->_isAppleInternal = _isAppleInternal; + copy->_has.isAppleInternal = YES; + } + copy->_processName = [_processName copyWithZone:zone]; + copy->_processVersion = [_processVersion copyWithZone:zone]; + copy->_processUuid = [_processUuid copyWithZone:zone]; + copy->_userDefaultTestName = [_userDefaultTestName copyWithZone:zone]; + for (SECC2MPInternalTestConfig *v in _internalTestConfigs) + { + SECC2MPInternalTestConfig *vCopy = [v copyWithZone:zone]; + [copy addInternalTestConfig:vCopy]; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPDeviceInfo *other = (SECC2MPDeviceInfo *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_productName && !other->_productName) || [self->_productName isEqual:other->_productName]) + && + ((!self->_productType && !other->_productType) || [self->_productType isEqual:other->_productType]) + && + ((!self->_productVersion && !other->_productVersion) || [self->_productVersion isEqual:other->_productVersion]) + && + ((!self->_productBuild && !other->_productBuild) || [self->_productBuild isEqual:other->_productBuild]) + && + ((self->_has.isAppleInternal && other->_has.isAppleInternal && ((self->_isAppleInternal && other->_isAppleInternal) || (!self->_isAppleInternal && !other->_isAppleInternal))) || (!self->_has.isAppleInternal && !other->_has.isAppleInternal)) + && + ((!self->_processName && !other->_processName) || [self->_processName isEqual:other->_processName]) + && + ((!self->_processVersion && !other->_processVersion) || [self->_processVersion isEqual:other->_processVersion]) + && + ((!self->_processUuid && !other->_processUuid) || [self->_processUuid isEqual:other->_processUuid]) + && + ((!self->_userDefaultTestName && !other->_userDefaultTestName) || [self->_userDefaultTestName isEqual:other->_userDefaultTestName]) + && + ((!self->_internalTestConfigs && !other->_internalTestConfigs) || [self->_internalTestConfigs isEqual:other->_internalTestConfigs]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_productName hash] + ^ + [self->_productType hash] + ^ + [self->_productVersion hash] + ^ + [self->_productBuild hash] + ^ + (self->_has.isAppleInternal ? PBHashInt((NSUInteger)self->_isAppleInternal) : 0) + ^ + [self->_processName hash] + ^ + [self->_processVersion hash] + ^ + [self->_processUuid hash] + ^ + [self->_userDefaultTestName hash] + ^ + [self->_internalTestConfigs hash] + ; +} + +- (void)mergeFrom:(SECC2MPDeviceInfo *)other +{ + if (other->_productName) + { + [self setProductName:other->_productName]; + } + if (other->_productType) + { + [self setProductType:other->_productType]; + } + if (other->_productVersion) + { + [self setProductVersion:other->_productVersion]; + } + if (other->_productBuild) + { + [self setProductBuild:other->_productBuild]; + } + if (other->_has.isAppleInternal) + { + self->_isAppleInternal = other->_isAppleInternal; + self->_has.isAppleInternal = YES; + } + if (other->_processName) + { + [self setProcessName:other->_processName]; + } + if (other->_processVersion) + { + [self setProcessVersion:other->_processVersion]; + } + if (other->_processUuid) + { + [self setProcessUuid:other->_processUuid]; + } + if (other->_userDefaultTestName) + { + [self setUserDefaultTestName:other->_userDefaultTestName]; + } + for (SECC2MPInternalTestConfig *iter_internalTestConfigs in other->_internalTestConfigs) + { + [self addInternalTestConfig:iter_internalTestConfigs]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPError.h b/keychain/analytics/C2Metric/SECC2MPError.h new file mode 100644 index 00000000..8442ab82 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPError.h @@ -0,0 +1,53 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPError; + +#ifdef __cplusplus +#define SECC2MPERROR_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPERROR_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPError : PBCodable +{ + int64_t _errorCode; + NSString *_errorDescription; + NSString *_errorDomain; + SECC2MPError *_underlyingError; + struct { + int errorCode:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasErrorDomain; +@property (nonatomic, retain) NSString *errorDomain; + +@property (nonatomic) BOOL hasErrorCode; +@property (nonatomic) int64_t errorCode; + +@property (nonatomic, readonly) BOOL hasErrorDescription; +@property (nonatomic, retain) NSString *errorDescription; + +@property (nonatomic, readonly) BOOL hasUnderlyingError; +@property (nonatomic, retain) SECC2MPError *underlyingError; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPError *)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:(SECC2MPError *)other; + +SECC2MPERROR_FUNCTION BOOL SECC2MPErrorReadFrom(__unsafe_unretained SECC2MPError *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPError.m b/keychain/analytics/C2Metric/SECC2MPError.m new file mode 100644 index 00000000..b71864c8 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPError.m @@ -0,0 +1,262 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPError.h" +#import +#import +#import + +#import "SECC2MPError.h" + +#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 SECC2MPError + +- (BOOL)hasErrorDomain +{ + return _errorDomain != nil; +} +@synthesize errorDomain = _errorDomain; +@synthesize errorCode = _errorCode; +- (void)setErrorCode:(int64_t)v +{ + _has.errorCode = YES; + _errorCode = v; +} +- (void)setHasErrorCode:(BOOL)f +{ + _has.errorCode = f; +} +- (BOOL)hasErrorCode +{ + return _has.errorCode; +} +- (BOOL)hasErrorDescription +{ + return _errorDescription != nil; +} +@synthesize errorDescription = _errorDescription; +- (BOOL)hasUnderlyingError +{ + return _underlyingError != nil; +} +@synthesize underlyingError = _underlyingError; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_errorDomain) + { + [dict setObject:self->_errorDomain forKey:@"error_domain"]; + } + if (self->_has.errorCode) + { + [dict setObject:[NSNumber numberWithLongLong:self->_errorCode] forKey:@"error_code"]; + } + if (self->_errorDescription) + { + [dict setObject:self->_errorDescription forKey:@"error_description"]; + } + if (self->_underlyingError) + { + [dict setObject:[_underlyingError dictionaryRepresentation] forKey:@"underlying_error"]; + } + return dict; +} + +BOOL SECC2MPErrorReadFrom(__unsafe_unretained SECC2MPError *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 /* errorDomain */: + { + NSString *new_errorDomain = PBReaderReadString(reader); + self->_errorDomain = new_errorDomain; + } + break; + case 2 /* errorCode */: + { + self->_has.errorCode = YES; + self->_errorCode = PBReaderReadInt64(reader); + } + break; + case 3 /* errorDescription */: + { + NSString *new_errorDescription = PBReaderReadString(reader); + self->_errorDescription = new_errorDescription; + } + break; + case 4 /* underlyingError */: + { + SECC2MPError *new_underlyingError = [[SECC2MPError alloc] init]; + self->_underlyingError = new_underlyingError; + PBDataReaderMark mark_underlyingError; + BOOL markError = !PBReaderPlaceMark(reader, &mark_underlyingError); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPErrorReadFrom(new_underlyingError, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_underlyingError); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPErrorReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* errorDomain */ + { + if (self->_errorDomain) + { + PBDataWriterWriteStringField(writer, self->_errorDomain, 1); + } + } + /* errorCode */ + { + if (self->_has.errorCode) + { + PBDataWriterWriteInt64Field(writer, self->_errorCode, 2); + } + } + /* errorDescription */ + { + if (self->_errorDescription) + { + PBDataWriterWriteStringField(writer, self->_errorDescription, 3); + } + } + /* underlyingError */ + { + if (self->_underlyingError != nil) + { + PBDataWriterWriteSubmessage(writer, self->_underlyingError, 4); + } + } +} + +- (void)copyTo:(SECC2MPError *)other +{ + if (_errorDomain) + { + other.errorDomain = _errorDomain; + } + if (self->_has.errorCode) + { + other->_errorCode = _errorCode; + other->_has.errorCode = YES; + } + if (_errorDescription) + { + other.errorDescription = _errorDescription; + } + if (_underlyingError) + { + other.underlyingError = _underlyingError; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPError *copy = [[[self class] allocWithZone:zone] init]; + copy->_errorDomain = [_errorDomain copyWithZone:zone]; + if (self->_has.errorCode) + { + copy->_errorCode = _errorCode; + copy->_has.errorCode = YES; + } + copy->_errorDescription = [_errorDescription copyWithZone:zone]; + copy->_underlyingError = [_underlyingError copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPError *other = (SECC2MPError *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_errorDomain && !other->_errorDomain) || [self->_errorDomain isEqual:other->_errorDomain]) + && + ((self->_has.errorCode && other->_has.errorCode && self->_errorCode == other->_errorCode) || (!self->_has.errorCode && !other->_has.errorCode)) + && + ((!self->_errorDescription && !other->_errorDescription) || [self->_errorDescription isEqual:other->_errorDescription]) + && + ((!self->_underlyingError && !other->_underlyingError) || [self->_underlyingError isEqual:other->_underlyingError]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_errorDomain hash] + ^ + (self->_has.errorCode ? PBHashInt((NSUInteger)self->_errorCode) : 0) + ^ + [self->_errorDescription hash] + ^ + [self->_underlyingError hash] + ; +} + +- (void)mergeFrom:(SECC2MPError *)other +{ + if (other->_errorDomain) + { + [self setErrorDomain:other->_errorDomain]; + } + if (other->_has.errorCode) + { + self->_errorCode = other->_errorCode; + self->_has.errorCode = YES; + } + if (other->_errorDescription) + { + [self setErrorDescription:other->_errorDescription]; + } + if (self->_underlyingError && other->_underlyingError) + { + [self->_underlyingError mergeFrom:other->_underlyingError]; + } + else if (!self->_underlyingError && other->_underlyingError) + { + [self setUnderlyingError:other->_underlyingError]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPGenericEvent.h b/keychain/analytics/C2Metric/SECC2MPGenericEvent.h new file mode 100644 index 00000000..56398e29 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPGenericEvent.h @@ -0,0 +1,95 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPGenericEventMetric; + +typedef NS_ENUM(int32_t, SECC2MPGenericEvent_Type) { + SECC2MPGenericEvent_Type_none = 0, + SECC2MPGenericEvent_Type_cloudkit = 101, + SECC2MPGenericEvent_Type_cloudkit_client = 201, + SECC2MPGenericEvent_Type_server = 301, +}; +#ifdef __OBJC__ +NS_INLINE NSString *SECC2MPGenericEvent_TypeAsString(SECC2MPGenericEvent_Type value) +{ + switch (value) + { + case SECC2MPGenericEvent_Type_none: return @"none"; + case SECC2MPGenericEvent_Type_cloudkit: return @"cloudkit"; + case SECC2MPGenericEvent_Type_cloudkit_client: return @"cloudkit_client"; + case SECC2MPGenericEvent_Type_server: return @"server"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE SECC2MPGenericEvent_Type StringAsSECC2MPGenericEvent_Type(NSString *value) +{ + if ([value isEqualToString:@"none"]) return SECC2MPGenericEvent_Type_none; + if ([value isEqualToString:@"cloudkit"]) return SECC2MPGenericEvent_Type_cloudkit; + if ([value isEqualToString:@"cloudkit_client"]) return SECC2MPGenericEvent_Type_cloudkit_client; + if ([value isEqualToString:@"server"]) return SECC2MPGenericEvent_Type_server; + return SECC2MPGenericEvent_Type_none; +} +#endif /* __OBJC__ */ + +#ifdef __cplusplus +#define SECC2MPGENERICEVENT_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPGENERICEVENT_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPGenericEvent : PBCodable +{ + uint64_t _timestampEnd; + uint64_t _timestampStart; + NSMutableArray *_metrics; + NSString *_name; + SECC2MPGenericEvent_Type _type; + struct { + int timestampEnd:1; + int timestampStart:1; + int type:1; + } _has; +} + + +@property (nonatomic) BOOL hasType; +@property (nonatomic) SECC2MPGenericEvent_Type type; +- (NSString *)typeAsString:(SECC2MPGenericEvent_Type)value; +- (SECC2MPGenericEvent_Type)StringAsType:(NSString *)str; + +@property (nonatomic, readonly) BOOL hasName; +@property (nonatomic, retain) NSString *name; + +@property (nonatomic) BOOL hasTimestampStart; +@property (nonatomic) uint64_t timestampStart; + +@property (nonatomic) BOOL hasTimestampEnd; +@property (nonatomic) uint64_t timestampEnd; + +@property (nonatomic, retain) NSMutableArray *metrics; +- (void)clearMetrics; +- (void)addMetric:(SECC2MPGenericEventMetric *)i; +- (NSUInteger)metricsCount; +- (SECC2MPGenericEventMetric *)metricAtIndex:(NSUInteger)idx; ++ (Class)metricType; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPGenericEvent *)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:(SECC2MPGenericEvent *)other; + +SECC2MPGENERICEVENT_FUNCTION BOOL SECC2MPGenericEventReadFrom(__unsafe_unretained SECC2MPGenericEvent *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPGenericEvent.m b/keychain/analytics/C2Metric/SECC2MPGenericEvent.m new file mode 100644 index 00000000..2544f4a5 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPGenericEvent.m @@ -0,0 +1,369 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPGenericEvent.h" +#import +#import +#import + +#import "SECC2MPGenericEventMetric.h" + +#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 SECC2MPGenericEvent + +@synthesize type = _type; +- (SECC2MPGenericEvent_Type)type +{ + return _has.type ? _type : SECC2MPGenericEvent_Type_none; +} +- (void)setType:(SECC2MPGenericEvent_Type)v +{ + _has.type = YES; + _type = v; +} +- (void)setHasType:(BOOL)f +{ + _has.type = f; +} +- (BOOL)hasType +{ + return _has.type; +} +- (NSString *)typeAsString:(SECC2MPGenericEvent_Type)value +{ + return SECC2MPGenericEvent_TypeAsString(value); +} +- (SECC2MPGenericEvent_Type)StringAsType:(NSString *)str +{ + return StringAsSECC2MPGenericEvent_Type(str); +} +- (BOOL)hasName +{ + return _name != nil; +} +@synthesize name = _name; +@synthesize timestampStart = _timestampStart; +- (void)setTimestampStart:(uint64_t)v +{ + _has.timestampStart = YES; + _timestampStart = v; +} +- (void)setHasTimestampStart:(BOOL)f +{ + _has.timestampStart = f; +} +- (BOOL)hasTimestampStart +{ + return _has.timestampStart; +} +@synthesize timestampEnd = _timestampEnd; +- (void)setTimestampEnd:(uint64_t)v +{ + _has.timestampEnd = YES; + _timestampEnd = v; +} +- (void)setHasTimestampEnd:(BOOL)f +{ + _has.timestampEnd = f; +} +- (BOOL)hasTimestampEnd +{ + return _has.timestampEnd; +} +@synthesize metrics = _metrics; +- (void)clearMetrics +{ + [_metrics removeAllObjects]; +} +- (void)addMetric:(SECC2MPGenericEventMetric *)i +{ + if (!_metrics) + { + _metrics = [[NSMutableArray alloc] init]; + } + [_metrics addObject:i]; +} +- (NSUInteger)metricsCount +{ + return [_metrics count]; +} +- (SECC2MPGenericEventMetric *)metricAtIndex:(NSUInteger)idx +{ + return [_metrics objectAtIndex:idx]; +} ++ (Class)metricType +{ + return [SECC2MPGenericEventMetric class]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.type) + { + [dict setObject:SECC2MPGenericEvent_TypeAsString(self->_type) forKey:@"type"]; + } + if (self->_name) + { + [dict setObject:self->_name forKey:@"name"]; + } + if (self->_has.timestampStart) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampStart] forKey:@"timestamp_start"]; + } + if (self->_has.timestampEnd) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampEnd] forKey:@"timestamp_end"]; + } + if ([self->_metrics count]) + { + NSMutableArray *metricsDictReprs = [[NSMutableArray alloc] initWithCapacity:[self->_metrics count]]; + for (SECC2MPGenericEventMetric *i_metric in self->_metrics) + { + [metricsDictReprs addObject:[i_metric dictionaryRepresentation]]; + } + [dict setObject:metricsDictReprs forKey:@"metric"]; + } + return dict; +} + +BOOL SECC2MPGenericEventReadFrom(__unsafe_unretained SECC2MPGenericEvent *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 /* type */: + { + self->_has.type = YES; + self->_type = PBReaderReadInt32(reader); + } + break; + case 101 /* name */: + { + NSString *new_name = PBReaderReadString(reader); + self->_name = new_name; + } + break; + case 201 /* timestampStart */: + { + self->_has.timestampStart = YES; + self->_timestampStart = PBReaderReadUint64(reader); + } + break; + case 202 /* timestampEnd */: + { + self->_has.timestampEnd = YES; + self->_timestampEnd = PBReaderReadUint64(reader); + } + break; + case 301 /* metrics */: + { + SECC2MPGenericEventMetric *new_metric = [[SECC2MPGenericEventMetric alloc] init]; + [self addMetric:new_metric]; + PBDataReaderMark mark_metric; + BOOL markError = !PBReaderPlaceMark(reader, &mark_metric); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPGenericEventMetricReadFrom(new_metric, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_metric); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPGenericEventReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* type */ + { + if (self->_has.type) + { + PBDataWriterWriteInt32Field(writer, self->_type, 1); + } + } + /* name */ + { + if (self->_name) + { + PBDataWriterWriteStringField(writer, self->_name, 101); + } + } + /* timestampStart */ + { + if (self->_has.timestampStart) + { + PBDataWriterWriteUint64Field(writer, self->_timestampStart, 201); + } + } + /* timestampEnd */ + { + if (self->_has.timestampEnd) + { + PBDataWriterWriteUint64Field(writer, self->_timestampEnd, 202); + } + } + /* metrics */ + { + for (SECC2MPGenericEventMetric *i_metric in self->_metrics) + { + PBDataWriterWriteSubmessage(writer, i_metric, 301); + } + } +} + +- (void)copyTo:(SECC2MPGenericEvent *)other +{ + if (self->_has.type) + { + other->_type = _type; + other->_has.type = YES; + } + if (_name) + { + other.name = _name; + } + if (self->_has.timestampStart) + { + other->_timestampStart = _timestampStart; + other->_has.timestampStart = YES; + } + if (self->_has.timestampEnd) + { + other->_timestampEnd = _timestampEnd; + other->_has.timestampEnd = YES; + } + if ([self metricsCount]) + { + [other clearMetrics]; + NSUInteger metricsCnt = [self metricsCount]; + for (NSUInteger i = 0; i < metricsCnt; i++) + { + [other addMetric:[self metricAtIndex:i]]; + } + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPGenericEvent *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.type) + { + copy->_type = _type; + copy->_has.type = YES; + } + copy->_name = [_name copyWithZone:zone]; + if (self->_has.timestampStart) + { + copy->_timestampStart = _timestampStart; + copy->_has.timestampStart = YES; + } + if (self->_has.timestampEnd) + { + copy->_timestampEnd = _timestampEnd; + copy->_has.timestampEnd = YES; + } + for (SECC2MPGenericEventMetric *v in _metrics) + { + SECC2MPGenericEventMetric *vCopy = [v copyWithZone:zone]; + [copy addMetric:vCopy]; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPGenericEvent *other = (SECC2MPGenericEvent *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.type && other->_has.type && self->_type == other->_type) || (!self->_has.type && !other->_has.type)) + && + ((!self->_name && !other->_name) || [self->_name isEqual:other->_name]) + && + ((self->_has.timestampStart && other->_has.timestampStart && self->_timestampStart == other->_timestampStart) || (!self->_has.timestampStart && !other->_has.timestampStart)) + && + ((self->_has.timestampEnd && other->_has.timestampEnd && self->_timestampEnd == other->_timestampEnd) || (!self->_has.timestampEnd && !other->_has.timestampEnd)) + && + ((!self->_metrics && !other->_metrics) || [self->_metrics isEqual:other->_metrics]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.type ? PBHashInt((NSUInteger)self->_type) : 0) + ^ + [self->_name hash] + ^ + (self->_has.timestampStart ? PBHashInt((NSUInteger)self->_timestampStart) : 0) + ^ + (self->_has.timestampEnd ? PBHashInt((NSUInteger)self->_timestampEnd) : 0) + ^ + [self->_metrics hash] + ; +} + +- (void)mergeFrom:(SECC2MPGenericEvent *)other +{ + if (other->_has.type) + { + self->_type = other->_type; + self->_has.type = YES; + } + if (other->_name) + { + [self setName:other->_name]; + } + if (other->_has.timestampStart) + { + self->_timestampStart = other->_timestampStart; + self->_has.timestampStart = YES; + } + if (other->_has.timestampEnd) + { + self->_timestampEnd = other->_timestampEnd; + self->_has.timestampEnd = YES; + } + for (SECC2MPGenericEventMetric *iter_metrics in other->_metrics) + { + [self addMetric:iter_metrics]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPGenericEventMetric.h b/keychain/analytics/C2Metric/SECC2MPGenericEventMetric.h new file mode 100644 index 00000000..cd9c2706 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPGenericEventMetric.h @@ -0,0 +1,42 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPGenericEventMetricValue; + +#ifdef __cplusplus +#define SECC2MPGENERICEVENTMETRIC_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPGENERICEVENTMETRIC_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPGenericEventMetric : PBCodable +{ + NSString *_key; + SECC2MPGenericEventMetricValue *_value; +} + + +@property (nonatomic, readonly) BOOL hasKey; +@property (nonatomic, retain) NSString *key; + +@property (nonatomic, readonly) BOOL hasValue; +@property (nonatomic, retain) SECC2MPGenericEventMetricValue *value; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPGenericEventMetric *)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:(SECC2MPGenericEventMetric *)other; + +SECC2MPGENERICEVENTMETRIC_FUNCTION BOOL SECC2MPGenericEventMetricReadFrom(__unsafe_unretained SECC2MPGenericEventMetric *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPGenericEventMetric.m b/keychain/analytics/C2Metric/SECC2MPGenericEventMetric.m new file mode 100644 index 00000000..0475ab5e --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPGenericEventMetric.m @@ -0,0 +1,177 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPGenericEventMetric.h" +#import +#import +#import + +#import "SECC2MPGenericEventMetricValue.h" + +#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 SECC2MPGenericEventMetric + +- (BOOL)hasKey +{ + return _key != nil; +} +@synthesize key = _key; +- (BOOL)hasValue +{ + return _value != nil; +} +@synthesize value = _value; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_key) + { + [dict setObject:self->_key forKey:@"key"]; + } + if (self->_value) + { + [dict setObject:[_value dictionaryRepresentation] forKey:@"value"]; + } + return dict; +} + +BOOL SECC2MPGenericEventMetricReadFrom(__unsafe_unretained SECC2MPGenericEventMetric *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 101 /* key */: + { + NSString *new_key = PBReaderReadString(reader); + self->_key = new_key; + } + break; + case 201 /* value */: + { + SECC2MPGenericEventMetricValue *new_value = [[SECC2MPGenericEventMetricValue alloc] init]; + self->_value = new_value; + PBDataReaderMark mark_value; + BOOL markError = !PBReaderPlaceMark(reader, &mark_value); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPGenericEventMetricValueReadFrom(new_value, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_value); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPGenericEventMetricReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* key */ + { + if (self->_key) + { + PBDataWriterWriteStringField(writer, self->_key, 101); + } + } + /* value */ + { + if (self->_value != nil) + { + PBDataWriterWriteSubmessage(writer, self->_value, 201); + } + } +} + +- (void)copyTo:(SECC2MPGenericEventMetric *)other +{ + if (_key) + { + other.key = _key; + } + if (_value) + { + other.value = _value; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPGenericEventMetric *copy = [[[self class] allocWithZone:zone] init]; + copy->_key = [_key copyWithZone:zone]; + copy->_value = [_value copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPGenericEventMetric *other = (SECC2MPGenericEventMetric *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_key && !other->_key) || [self->_key isEqual:other->_key]) + && + ((!self->_value && !other->_value) || [self->_value isEqual:other->_value]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_key hash] + ^ + [self->_value hash] + ; +} + +- (void)mergeFrom:(SECC2MPGenericEventMetric *)other +{ + if (other->_key) + { + [self setKey:other->_key]; + } + if (self->_value && other->_value) + { + [self->_value mergeFrom:other->_value]; + } + else if (!self->_value && other->_value) + { + [self setValue:other->_value]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.h b/keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.h new file mode 100644 index 00000000..691bf0d2 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.h @@ -0,0 +1,54 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPError; + +#ifdef __cplusplus +#define SECC2MPGENERICEVENTMETRICVALUE_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPGENERICEVENTMETRICVALUE_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPGenericEventMetricValue : PBCodable +{ + uint64_t _dateValue; + double _doubleValue; + SECC2MPError *_errorValue; + NSString *_stringValue; + struct { + int dateValue:1; + int doubleValue:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasStringValue; +@property (nonatomic, retain) NSString *stringValue; + +@property (nonatomic) BOOL hasDoubleValue; +@property (nonatomic) double doubleValue; + +@property (nonatomic) BOOL hasDateValue; +@property (nonatomic) uint64_t dateValue; + +@property (nonatomic, readonly) BOOL hasErrorValue; +@property (nonatomic, retain) SECC2MPError *errorValue; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPGenericEventMetricValue *)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:(SECC2MPGenericEventMetricValue *)other; + +SECC2MPGENERICEVENTMETRICVALUE_FUNCTION BOOL SECC2MPGenericEventMetricValueReadFrom(__unsafe_unretained SECC2MPGenericEventMetricValue *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.m b/keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.m new file mode 100644 index 00000000..13aa076c --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.m @@ -0,0 +1,277 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPGenericEventMetricValue.h" +#import +#import +#import + +#import "SECC2MPError.h" + +#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 SECC2MPGenericEventMetricValue + +- (BOOL)hasStringValue +{ + return _stringValue != nil; +} +@synthesize stringValue = _stringValue; +@synthesize doubleValue = _doubleValue; +- (void)setDoubleValue:(double)v +{ + _has.doubleValue = YES; + _doubleValue = v; +} +- (void)setHasDoubleValue:(BOOL)f +{ + _has.doubleValue = f; +} +- (BOOL)hasDoubleValue +{ + return _has.doubleValue; +} +@synthesize dateValue = _dateValue; +- (void)setDateValue:(uint64_t)v +{ + _has.dateValue = YES; + _dateValue = v; +} +- (void)setHasDateValue:(BOOL)f +{ + _has.dateValue = f; +} +- (BOOL)hasDateValue +{ + return _has.dateValue; +} +- (BOOL)hasErrorValue +{ + return _errorValue != nil; +} +@synthesize errorValue = _errorValue; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_stringValue) + { + [dict setObject:self->_stringValue forKey:@"string_value"]; + } + if (self->_has.doubleValue) + { + [dict setObject:[NSNumber numberWithDouble:self->_doubleValue] forKey:@"double_value"]; + } + if (self->_has.dateValue) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_dateValue] forKey:@"date_value"]; + } + if (self->_errorValue) + { + [dict setObject:[_errorValue dictionaryRepresentation] forKey:@"error_value"]; + } + return dict; +} + +BOOL SECC2MPGenericEventMetricValueReadFrom(__unsafe_unretained SECC2MPGenericEventMetricValue *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 101 /* stringValue */: + { + NSString *new_stringValue = PBReaderReadString(reader); + self->_stringValue = new_stringValue; + } + break; + case 102 /* doubleValue */: + { + self->_has.doubleValue = YES; + self->_doubleValue = PBReaderReadDouble(reader); + } + break; + case 103 /* dateValue */: + { + self->_has.dateValue = YES; + self->_dateValue = PBReaderReadUint64(reader); + } + break; + case 201 /* errorValue */: + { + SECC2MPError *new_errorValue = [[SECC2MPError alloc] init]; + self->_errorValue = new_errorValue; + PBDataReaderMark mark_errorValue; + BOOL markError = !PBReaderPlaceMark(reader, &mark_errorValue); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPErrorReadFrom(new_errorValue, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_errorValue); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPGenericEventMetricValueReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* stringValue */ + { + if (self->_stringValue) + { + PBDataWriterWriteStringField(writer, self->_stringValue, 101); + } + } + /* doubleValue */ + { + if (self->_has.doubleValue) + { + PBDataWriterWriteDoubleField(writer, self->_doubleValue, 102); + } + } + /* dateValue */ + { + if (self->_has.dateValue) + { + PBDataWriterWriteUint64Field(writer, self->_dateValue, 103); + } + } + /* errorValue */ + { + if (self->_errorValue != nil) + { + PBDataWriterWriteSubmessage(writer, self->_errorValue, 201); + } + } +} + +- (void)copyTo:(SECC2MPGenericEventMetricValue *)other +{ + if (_stringValue) + { + other.stringValue = _stringValue; + } + if (self->_has.doubleValue) + { + other->_doubleValue = _doubleValue; + other->_has.doubleValue = YES; + } + if (self->_has.dateValue) + { + other->_dateValue = _dateValue; + other->_has.dateValue = YES; + } + if (_errorValue) + { + other.errorValue = _errorValue; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPGenericEventMetricValue *copy = [[[self class] allocWithZone:zone] init]; + copy->_stringValue = [_stringValue copyWithZone:zone]; + if (self->_has.doubleValue) + { + copy->_doubleValue = _doubleValue; + copy->_has.doubleValue = YES; + } + if (self->_has.dateValue) + { + copy->_dateValue = _dateValue; + copy->_has.dateValue = YES; + } + copy->_errorValue = [_errorValue copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPGenericEventMetricValue *other = (SECC2MPGenericEventMetricValue *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_stringValue && !other->_stringValue) || [self->_stringValue isEqual:other->_stringValue]) + && + ((self->_has.doubleValue && other->_has.doubleValue && self->_doubleValue == other->_doubleValue) || (!self->_has.doubleValue && !other->_has.doubleValue)) + && + ((self->_has.dateValue && other->_has.dateValue && self->_dateValue == other->_dateValue) || (!self->_has.dateValue && !other->_has.dateValue)) + && + ((!self->_errorValue && !other->_errorValue) || [self->_errorValue isEqual:other->_errorValue]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_stringValue hash] + ^ + (self->_has.doubleValue ? PBHashDouble(self->_doubleValue) : 0) + ^ + (self->_has.dateValue ? PBHashInt((NSUInteger)self->_dateValue) : 0) + ^ + [self->_errorValue hash] + ; +} + +- (void)mergeFrom:(SECC2MPGenericEventMetricValue *)other +{ + if (other->_stringValue) + { + [self setStringValue:other->_stringValue]; + } + if (other->_has.doubleValue) + { + self->_doubleValue = other->_doubleValue; + self->_has.doubleValue = YES; + } + if (other->_has.dateValue) + { + self->_dateValue = other->_dateValue; + self->_has.dateValue = YES; + } + if (self->_errorValue && other->_errorValue) + { + [self->_errorValue mergeFrom:other->_errorValue]; + } + else if (!self->_errorValue && other->_errorValue) + { + [self setErrorValue:other->_errorValue]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPInternalTestConfig.h b/keychain/analytics/C2Metric/SECC2MPInternalTestConfig.h new file mode 100644 index 00000000..43265b7a --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPInternalTestConfig.h @@ -0,0 +1,40 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +#ifdef __cplusplus +#define SECC2MPINTERNALTESTCONFIG_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPINTERNALTESTCONFIG_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPInternalTestConfig : PBCodable +{ + NSString *_key; + NSString *_value; +} + + +@property (nonatomic, readonly) BOOL hasKey; +@property (nonatomic, retain) NSString *key; + +@property (nonatomic, readonly) BOOL hasValue; +@property (nonatomic, retain) NSString *value; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPInternalTestConfig *)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:(SECC2MPInternalTestConfig *)other; + +SECC2MPINTERNALTESTCONFIG_FUNCTION BOOL SECC2MPInternalTestConfigReadFrom(__unsafe_unretained SECC2MPInternalTestConfig *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPInternalTestConfig.m b/keychain/analytics/C2Metric/SECC2MPInternalTestConfig.m new file mode 100644 index 00000000..09a855c9 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPInternalTestConfig.m @@ -0,0 +1,159 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPInternalTestConfig.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 SECC2MPInternalTestConfig + +- (BOOL)hasKey +{ + return _key != nil; +} +@synthesize key = _key; +- (BOOL)hasValue +{ + return _value != nil; +} +@synthesize value = _value; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_key) + { + [dict setObject:self->_key forKey:@"key"]; + } + if (self->_value) + { + [dict setObject:self->_value forKey:@"value"]; + } + return dict; +} + +BOOL SECC2MPInternalTestConfigReadFrom(__unsafe_unretained SECC2MPInternalTestConfig *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 101 /* key */: + { + NSString *new_key = PBReaderReadString(reader); + self->_key = new_key; + } + break; + case 102 /* value */: + { + NSString *new_value = PBReaderReadString(reader); + self->_value = new_value; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPInternalTestConfigReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* key */ + { + if (self->_key) + { + PBDataWriterWriteStringField(writer, self->_key, 101); + } + } + /* value */ + { + if (self->_value) + { + PBDataWriterWriteStringField(writer, self->_value, 102); + } + } +} + +- (void)copyTo:(SECC2MPInternalTestConfig *)other +{ + if (_key) + { + other.key = _key; + } + if (_value) + { + other.value = _value; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPInternalTestConfig *copy = [[[self class] allocWithZone:zone] init]; + copy->_key = [_key copyWithZone:zone]; + copy->_value = [_value copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPInternalTestConfig *other = (SECC2MPInternalTestConfig *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_key && !other->_key) || [self->_key isEqual:other->_key]) + && + ((!self->_value && !other->_value) || [self->_value isEqual:other->_value]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_key hash] + ^ + [self->_value hash] + ; +} + +- (void)mergeFrom:(SECC2MPInternalTestConfig *)other +{ + if (other->_key) + { + [self setKey:other->_key]; + } + if (other->_value) + { + [self setValue:other->_value]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPMetric.h b/keychain/analytics/C2Metric/SECC2MPMetric.h new file mode 100644 index 00000000..866752e4 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPMetric.h @@ -0,0 +1,149 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPDeviceInfo; +@class SECC2MPCloudKitInfo; +@class SECC2MPServerInfo; +@class SECC2MPNetworkEvent; +@class SECC2MPGenericEvent; + +typedef NS_ENUM(int32_t, SECC2MPMetric_Type) { + SECC2MPMetric_Type_none_type = 0, + SECC2MPMetric_Type_network_event_type = 200, + SECC2MPMetric_Type_generic_event_type = 201, +}; +#ifdef __OBJC__ +NS_INLINE NSString *SECC2MPMetric_TypeAsString(SECC2MPMetric_Type value) +{ + switch (value) + { + case SECC2MPMetric_Type_none_type: return @"none_type"; + case SECC2MPMetric_Type_network_event_type: return @"network_event_type"; + case SECC2MPMetric_Type_generic_event_type: return @"generic_event_type"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE SECC2MPMetric_Type StringAsSECC2MPMetric_Type(NSString *value) +{ + if ([value isEqualToString:@"none_type"]) return SECC2MPMetric_Type_none_type; + if ([value isEqualToString:@"network_event_type"]) return SECC2MPMetric_Type_network_event_type; + if ([value isEqualToString:@"generic_event_type"]) return SECC2MPMetric_Type_generic_event_type; + return SECC2MPMetric_Type_none_type; +} +#endif /* __OBJC__ */ +typedef NS_ENUM(int32_t, SECC2MPMetric_Trigger) { + SECC2MPMetric_Trigger_none_trigger = 0, + SECC2MPMetric_Trigger_user_default_trigger = 1, + SECC2MPMetric_Trigger_frequency_trigger = 2, + /** Can only trigger NetworkStatistic metrics. */ + SECC2MPMetric_Trigger_response_header_trigger = 4, + SECC2MPMetric_Trigger_client_operation_frequency_trigger = 8, + SECC2MPMetric_Trigger_operation_group_frequency_trigger = 16, + SECC2MPMetric_Trigger_push_trigger = 32, +}; +#ifdef __OBJC__ +NS_INLINE NSString *SECC2MPMetric_TriggerAsString(SECC2MPMetric_Trigger value) +{ + switch (value) + { + case SECC2MPMetric_Trigger_none_trigger: return @"none_trigger"; + case SECC2MPMetric_Trigger_user_default_trigger: return @"user_default_trigger"; + case SECC2MPMetric_Trigger_frequency_trigger: return @"frequency_trigger"; + case SECC2MPMetric_Trigger_response_header_trigger: return @"response_header_trigger"; + case SECC2MPMetric_Trigger_client_operation_frequency_trigger: return @"client_operation_frequency_trigger"; + case SECC2MPMetric_Trigger_operation_group_frequency_trigger: return @"operation_group_frequency_trigger"; + case SECC2MPMetric_Trigger_push_trigger: return @"push_trigger"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE SECC2MPMetric_Trigger StringAsSECC2MPMetric_Trigger(NSString *value) +{ + if ([value isEqualToString:@"none_trigger"]) return SECC2MPMetric_Trigger_none_trigger; + if ([value isEqualToString:@"user_default_trigger"]) return SECC2MPMetric_Trigger_user_default_trigger; + if ([value isEqualToString:@"frequency_trigger"]) return SECC2MPMetric_Trigger_frequency_trigger; + if ([value isEqualToString:@"response_header_trigger"]) return SECC2MPMetric_Trigger_response_header_trigger; + if ([value isEqualToString:@"client_operation_frequency_trigger"]) return SECC2MPMetric_Trigger_client_operation_frequency_trigger; + if ([value isEqualToString:@"operation_group_frequency_trigger"]) return SECC2MPMetric_Trigger_operation_group_frequency_trigger; + if ([value isEqualToString:@"push_trigger"]) return SECC2MPMetric_Trigger_push_trigger; + return SECC2MPMetric_Trigger_none_trigger; +} +#endif /* __OBJC__ */ + +#ifdef __cplusplus +#define SECC2MPMETRIC_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPMETRIC_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +/** Deprecated. Use Metric.Trigger instead. */ +__attribute__((visibility("hidden"))) +@interface SECC2MPMetric : PBCodable +{ + uint64_t _reportFrequency; + uint64_t _reportFrequencyBase; + uint64_t _triggers; + SECC2MPCloudKitInfo *_cloudkitInfo; + SECC2MPDeviceInfo *_deviceInfo; + SECC2MPGenericEvent *_genericEvent; + SECC2MPMetric_Type _metricType; + SECC2MPNetworkEvent *_networkEvent; + SECC2MPServerInfo *_serverInfo; + struct { + int reportFrequency:1; + int reportFrequencyBase:1; + int triggers:1; + int metricType:1; + } _has; +} + + +@property (nonatomic) BOOL hasMetricType; +@property (nonatomic) SECC2MPMetric_Type metricType; +- (NSString *)metricTypeAsString:(SECC2MPMetric_Type)value; +- (SECC2MPMetric_Type)StringAsMetricType:(NSString *)str; + +@property (nonatomic, readonly) BOOL hasDeviceInfo; +@property (nonatomic, retain) SECC2MPDeviceInfo *deviceInfo; + +@property (nonatomic, readonly) BOOL hasCloudkitInfo; +@property (nonatomic, retain) SECC2MPCloudKitInfo *cloudkitInfo; + +@property (nonatomic, readonly) BOOL hasServerInfo; +@property (nonatomic, retain) SECC2MPServerInfo *serverInfo; + +@property (nonatomic) BOOL hasTriggers; +@property (nonatomic) uint64_t triggers; + +@property (nonatomic) BOOL hasReportFrequency; +@property (nonatomic) uint64_t reportFrequency; + +@property (nonatomic) BOOL hasReportFrequencyBase; +@property (nonatomic) uint64_t reportFrequencyBase; + +@property (nonatomic, readonly) BOOL hasNetworkEvent; +@property (nonatomic, retain) SECC2MPNetworkEvent *networkEvent; + +@property (nonatomic, readonly) BOOL hasGenericEvent; +@property (nonatomic, retain) SECC2MPGenericEvent *genericEvent; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPMetric *)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:(SECC2MPMetric *)other; + +SECC2MPMETRIC_FUNCTION BOOL SECC2MPMetricReadFrom(__unsafe_unretained SECC2MPMetric *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPMetric.m b/keychain/analytics/C2Metric/SECC2MPMetric.m new file mode 100644 index 00000000..cb858403 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPMetric.m @@ -0,0 +1,562 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPMetric.h" +#import +#import +#import + +#import "SECC2MPCloudKitInfo.h" +#import "SECC2MPDeviceInfo.h" +#import "SECC2MPGenericEvent.h" +#import "SECC2MPNetworkEvent.h" +#import "SECC2MPServerInfo.h" + +#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 SECC2MPMetric + +@synthesize metricType = _metricType; +- (SECC2MPMetric_Type)metricType +{ + return _has.metricType ? _metricType : SECC2MPMetric_Type_none_type; +} +- (void)setMetricType:(SECC2MPMetric_Type)v +{ + _has.metricType = YES; + _metricType = v; +} +- (void)setHasMetricType:(BOOL)f +{ + _has.metricType = f; +} +- (BOOL)hasMetricType +{ + return _has.metricType; +} +- (NSString *)metricTypeAsString:(SECC2MPMetric_Type)value +{ + return SECC2MPMetric_TypeAsString(value); +} +- (SECC2MPMetric_Type)StringAsMetricType:(NSString *)str +{ + return StringAsSECC2MPMetric_Type(str); +} +- (BOOL)hasDeviceInfo +{ + return _deviceInfo != nil; +} +@synthesize deviceInfo = _deviceInfo; +- (BOOL)hasCloudkitInfo +{ + return _cloudkitInfo != nil; +} +@synthesize cloudkitInfo = _cloudkitInfo; +- (BOOL)hasServerInfo +{ + return _serverInfo != nil; +} +@synthesize serverInfo = _serverInfo; +@synthesize triggers = _triggers; +- (void)setTriggers:(uint64_t)v +{ + _has.triggers = YES; + _triggers = v; +} +- (void)setHasTriggers:(BOOL)f +{ + _has.triggers = f; +} +- (BOOL)hasTriggers +{ + return _has.triggers; +} +@synthesize reportFrequency = _reportFrequency; +- (void)setReportFrequency:(uint64_t)v +{ + _has.reportFrequency = YES; + _reportFrequency = v; +} +- (void)setHasReportFrequency:(BOOL)f +{ + _has.reportFrequency = f; +} +- (BOOL)hasReportFrequency +{ + return _has.reportFrequency; +} +@synthesize reportFrequencyBase = _reportFrequencyBase; +- (void)setReportFrequencyBase:(uint64_t)v +{ + _has.reportFrequencyBase = YES; + _reportFrequencyBase = v; +} +- (void)setHasReportFrequencyBase:(BOOL)f +{ + _has.reportFrequencyBase = f; +} +- (BOOL)hasReportFrequencyBase +{ + return _has.reportFrequencyBase; +} +- (BOOL)hasNetworkEvent +{ + return _networkEvent != nil; +} +@synthesize networkEvent = _networkEvent; +- (BOOL)hasGenericEvent +{ + return _genericEvent != nil; +} +@synthesize genericEvent = _genericEvent; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.metricType) + { + [dict setObject:SECC2MPMetric_TypeAsString(self->_metricType) forKey:@"metric_type"]; + } + if (self->_deviceInfo) + { + [dict setObject:[_deviceInfo dictionaryRepresentation] forKey:@"device_info"]; + } + if (self->_cloudkitInfo) + { + [dict setObject:[_cloudkitInfo dictionaryRepresentation] forKey:@"cloudkit_info"]; + } + if (self->_serverInfo) + { + [dict setObject:[_serverInfo dictionaryRepresentation] forKey:@"server_info"]; + } + if (self->_has.triggers) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_triggers] forKey:@"triggers"]; + } + if (self->_has.reportFrequency) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportFrequency] forKey:@"report_frequency"]; + } + if (self->_has.reportFrequencyBase) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportFrequencyBase] forKey:@"report_frequency_base"]; + } + if (self->_networkEvent) + { + [dict setObject:[_networkEvent dictionaryRepresentation] forKey:@"network_event"]; + } + if (self->_genericEvent) + { + [dict setObject:[_genericEvent dictionaryRepresentation] forKey:@"generic_event"]; + } + return dict; +} + +BOOL SECC2MPMetricReadFrom(__unsafe_unretained SECC2MPMetric *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 /* metricType */: + { + self->_has.metricType = YES; + self->_metricType = PBReaderReadInt32(reader); + } + break; + case 2 /* deviceInfo */: + { + SECC2MPDeviceInfo *new_deviceInfo = [[SECC2MPDeviceInfo alloc] init]; + self->_deviceInfo = new_deviceInfo; + PBDataReaderMark mark_deviceInfo; + BOOL markError = !PBReaderPlaceMark(reader, &mark_deviceInfo); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPDeviceInfoReadFrom(new_deviceInfo, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_deviceInfo); + } + break; + case 3 /* cloudkitInfo */: + { + SECC2MPCloudKitInfo *new_cloudkitInfo = [[SECC2MPCloudKitInfo alloc] init]; + self->_cloudkitInfo = new_cloudkitInfo; + PBDataReaderMark mark_cloudkitInfo; + BOOL markError = !PBReaderPlaceMark(reader, &mark_cloudkitInfo); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPCloudKitInfoReadFrom(new_cloudkitInfo, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_cloudkitInfo); + } + break; + case 4 /* serverInfo */: + { + SECC2MPServerInfo *new_serverInfo = [[SECC2MPServerInfo alloc] init]; + self->_serverInfo = new_serverInfo; + PBDataReaderMark mark_serverInfo; + BOOL markError = !PBReaderPlaceMark(reader, &mark_serverInfo); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPServerInfoReadFrom(new_serverInfo, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_serverInfo); + } + break; + case 100 /* triggers */: + { + self->_has.triggers = YES; + self->_triggers = PBReaderReadUint64(reader); + } + break; + case 101 /* reportFrequency */: + { + self->_has.reportFrequency = YES; + self->_reportFrequency = PBReaderReadUint64(reader); + } + break; + case 102 /* reportFrequencyBase */: + { + self->_has.reportFrequencyBase = YES; + self->_reportFrequencyBase = PBReaderReadUint64(reader); + } + break; + case 200 /* networkEvent */: + { + SECC2MPNetworkEvent *new_networkEvent = [[SECC2MPNetworkEvent alloc] init]; + self->_networkEvent = new_networkEvent; + PBDataReaderMark mark_networkEvent; + BOOL markError = !PBReaderPlaceMark(reader, &mark_networkEvent); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPNetworkEventReadFrom(new_networkEvent, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_networkEvent); + } + break; + case 201 /* genericEvent */: + { + SECC2MPGenericEvent *new_genericEvent = [[SECC2MPGenericEvent alloc] init]; + self->_genericEvent = new_genericEvent; + PBDataReaderMark mark_genericEvent; + BOOL markError = !PBReaderPlaceMark(reader, &mark_genericEvent); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPGenericEventReadFrom(new_genericEvent, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_genericEvent); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPMetricReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* metricType */ + { + if (self->_has.metricType) + { + PBDataWriterWriteInt32Field(writer, self->_metricType, 1); + } + } + /* deviceInfo */ + { + if (self->_deviceInfo != nil) + { + PBDataWriterWriteSubmessage(writer, self->_deviceInfo, 2); + } + } + /* cloudkitInfo */ + { + if (self->_cloudkitInfo != nil) + { + PBDataWriterWriteSubmessage(writer, self->_cloudkitInfo, 3); + } + } + /* serverInfo */ + { + if (self->_serverInfo != nil) + { + PBDataWriterWriteSubmessage(writer, self->_serverInfo, 4); + } + } + /* triggers */ + { + if (self->_has.triggers) + { + PBDataWriterWriteUint64Field(writer, self->_triggers, 100); + } + } + /* reportFrequency */ + { + if (self->_has.reportFrequency) + { + PBDataWriterWriteUint64Field(writer, self->_reportFrequency, 101); + } + } + /* reportFrequencyBase */ + { + if (self->_has.reportFrequencyBase) + { + PBDataWriterWriteUint64Field(writer, self->_reportFrequencyBase, 102); + } + } + /* networkEvent */ + { + if (self->_networkEvent != nil) + { + PBDataWriterWriteSubmessage(writer, self->_networkEvent, 200); + } + } + /* genericEvent */ + { + if (self->_genericEvent != nil) + { + PBDataWriterWriteSubmessage(writer, self->_genericEvent, 201); + } + } +} + +- (void)copyTo:(SECC2MPMetric *)other +{ + if (self->_has.metricType) + { + other->_metricType = _metricType; + other->_has.metricType = YES; + } + if (_deviceInfo) + { + other.deviceInfo = _deviceInfo; + } + if (_cloudkitInfo) + { + other.cloudkitInfo = _cloudkitInfo; + } + if (_serverInfo) + { + other.serverInfo = _serverInfo; + } + if (self->_has.triggers) + { + other->_triggers = _triggers; + other->_has.triggers = YES; + } + if (self->_has.reportFrequency) + { + other->_reportFrequency = _reportFrequency; + other->_has.reportFrequency = YES; + } + if (self->_has.reportFrequencyBase) + { + other->_reportFrequencyBase = _reportFrequencyBase; + other->_has.reportFrequencyBase = YES; + } + if (_networkEvent) + { + other.networkEvent = _networkEvent; + } + if (_genericEvent) + { + other.genericEvent = _genericEvent; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPMetric *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.metricType) + { + copy->_metricType = _metricType; + copy->_has.metricType = YES; + } + copy->_deviceInfo = [_deviceInfo copyWithZone:zone]; + copy->_cloudkitInfo = [_cloudkitInfo copyWithZone:zone]; + copy->_serverInfo = [_serverInfo copyWithZone:zone]; + if (self->_has.triggers) + { + copy->_triggers = _triggers; + copy->_has.triggers = YES; + } + if (self->_has.reportFrequency) + { + copy->_reportFrequency = _reportFrequency; + copy->_has.reportFrequency = YES; + } + if (self->_has.reportFrequencyBase) + { + copy->_reportFrequencyBase = _reportFrequencyBase; + copy->_has.reportFrequencyBase = YES; + } + copy->_networkEvent = [_networkEvent copyWithZone:zone]; + copy->_genericEvent = [_genericEvent copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPMetric *other = (SECC2MPMetric *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.metricType && other->_has.metricType && self->_metricType == other->_metricType) || (!self->_has.metricType && !other->_has.metricType)) + && + ((!self->_deviceInfo && !other->_deviceInfo) || [self->_deviceInfo isEqual:other->_deviceInfo]) + && + ((!self->_cloudkitInfo && !other->_cloudkitInfo) || [self->_cloudkitInfo isEqual:other->_cloudkitInfo]) + && + ((!self->_serverInfo && !other->_serverInfo) || [self->_serverInfo isEqual:other->_serverInfo]) + && + ((self->_has.triggers && other->_has.triggers && self->_triggers == other->_triggers) || (!self->_has.triggers && !other->_has.triggers)) + && + ((self->_has.reportFrequency && other->_has.reportFrequency && self->_reportFrequency == other->_reportFrequency) || (!self->_has.reportFrequency && !other->_has.reportFrequency)) + && + ((self->_has.reportFrequencyBase && other->_has.reportFrequencyBase && self->_reportFrequencyBase == other->_reportFrequencyBase) || (!self->_has.reportFrequencyBase && !other->_has.reportFrequencyBase)) + && + ((!self->_networkEvent && !other->_networkEvent) || [self->_networkEvent isEqual:other->_networkEvent]) + && + ((!self->_genericEvent && !other->_genericEvent) || [self->_genericEvent isEqual:other->_genericEvent]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.metricType ? PBHashInt((NSUInteger)self->_metricType) : 0) + ^ + [self->_deviceInfo hash] + ^ + [self->_cloudkitInfo hash] + ^ + [self->_serverInfo hash] + ^ + (self->_has.triggers ? PBHashInt((NSUInteger)self->_triggers) : 0) + ^ + (self->_has.reportFrequency ? PBHashInt((NSUInteger)self->_reportFrequency) : 0) + ^ + (self->_has.reportFrequencyBase ? PBHashInt((NSUInteger)self->_reportFrequencyBase) : 0) + ^ + [self->_networkEvent hash] + ^ + [self->_genericEvent hash] + ; +} + +- (void)mergeFrom:(SECC2MPMetric *)other +{ + if (other->_has.metricType) + { + self->_metricType = other->_metricType; + self->_has.metricType = YES; + } + if (self->_deviceInfo && other->_deviceInfo) + { + [self->_deviceInfo mergeFrom:other->_deviceInfo]; + } + else if (!self->_deviceInfo && other->_deviceInfo) + { + [self setDeviceInfo:other->_deviceInfo]; + } + if (self->_cloudkitInfo && other->_cloudkitInfo) + { + [self->_cloudkitInfo mergeFrom:other->_cloudkitInfo]; + } + else if (!self->_cloudkitInfo && other->_cloudkitInfo) + { + [self setCloudkitInfo:other->_cloudkitInfo]; + } + if (self->_serverInfo && other->_serverInfo) + { + [self->_serverInfo mergeFrom:other->_serverInfo]; + } + else if (!self->_serverInfo && other->_serverInfo) + { + [self setServerInfo:other->_serverInfo]; + } + if (other->_has.triggers) + { + self->_triggers = other->_triggers; + self->_has.triggers = YES; + } + if (other->_has.reportFrequency) + { + self->_reportFrequency = other->_reportFrequency; + self->_has.reportFrequency = YES; + } + if (other->_has.reportFrequencyBase) + { + self->_reportFrequencyBase = other->_reportFrequencyBase; + self->_has.reportFrequencyBase = YES; + } + if (self->_networkEvent && other->_networkEvent) + { + [self->_networkEvent mergeFrom:other->_networkEvent]; + } + else if (!self->_networkEvent && other->_networkEvent) + { + [self setNetworkEvent:other->_networkEvent]; + } + if (self->_genericEvent && other->_genericEvent) + { + [self->_genericEvent mergeFrom:other->_genericEvent]; + } + else if (!self->_genericEvent && other->_genericEvent) + { + [self setGenericEvent:other->_genericEvent]; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPNetworkEvent.h b/keychain/analytics/C2Metric/SECC2MPNetworkEvent.h new file mode 100644 index 00000000..9482cfec --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPNetworkEvent.h @@ -0,0 +1,263 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +@class SECC2MPError; + +typedef NS_ENUM(int32_t, SECC2MPNetworkEvent_Trigger) { + SECC2MPNetworkEvent_Trigger_none_trigger = 0, + SECC2MPNetworkEvent_Trigger_user_default_trigger = 1, + SECC2MPNetworkEvent_Trigger_frequency_trigger = 2, + SECC2MPNetworkEvent_Trigger_response_header_trigger = 4, +}; +#ifdef __OBJC__ +NS_INLINE NSString *SECC2MPNetworkEvent_TriggerAsString(SECC2MPNetworkEvent_Trigger value) +{ + switch (value) + { + case SECC2MPNetworkEvent_Trigger_none_trigger: return @"none_trigger"; + case SECC2MPNetworkEvent_Trigger_user_default_trigger: return @"user_default_trigger"; + case SECC2MPNetworkEvent_Trigger_frequency_trigger: return @"frequency_trigger"; + case SECC2MPNetworkEvent_Trigger_response_header_trigger: return @"response_header_trigger"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE SECC2MPNetworkEvent_Trigger StringAsSECC2MPNetworkEvent_Trigger(NSString *value) +{ + if ([value isEqualToString:@"none_trigger"]) return SECC2MPNetworkEvent_Trigger_none_trigger; + if ([value isEqualToString:@"user_default_trigger"]) return SECC2MPNetworkEvent_Trigger_user_default_trigger; + if ([value isEqualToString:@"frequency_trigger"]) return SECC2MPNetworkEvent_Trigger_frequency_trigger; + if ([value isEqualToString:@"response_header_trigger"]) return SECC2MPNetworkEvent_Trigger_response_header_trigger; + return SECC2MPNetworkEvent_Trigger_none_trigger; +} +#endif /* __OBJC__ */ + +#ifdef __cplusplus +#define SECC2MPNETWORKEVENT_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPNETWORKEVENT_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPNetworkEvent : PBCodable +{ + uint64_t _networkRequestBodyBytesSent; + uint64_t _networkResponseBodyBytesReceived; + uint64_t _networkStatusCode; + uint64_t _reportFrequency; + uint64_t _reportFrequencyBase; + uint64_t _timestampC2Init; + uint64_t _timestampC2Now; + uint64_t _timestampC2Start; + uint64_t _timestampDnsEnd; + uint64_t _timestampDnsStart; + uint64_t _timestampRequestEnd; + uint64_t _timestampRequestStart; + uint64_t _timestampResponseEnd; + uint64_t _timestampResponseStart; + uint64_t _timestampSslStart; + uint64_t _timestampTcpEnd; + uint64_t _timestampTcpStart; + uint64_t _triggers; + NSString *_networkConnectionUuid; + SECC2MPError *_networkFatalError; + NSString *_networkHostname; + NSString *_networkInterfaceIdentifier; + uint32_t _networkPreviousAttemptCount; + NSString *_networkProtocolName; + NSString *_networkRemoteAddresssAndPort; + uint32_t _networkRequestHeaderSize; + NSString *_networkRequestUri; + uint32_t _networkResponseHeaderSize; + NSString *_networkTaskDescription; + NSString *_optionsQualityOfService; + NSString *_optionsSourceApplicationBundleIdentifier; + NSString *_optionsSourceApplicationSecondaryIdentifier; + uint32_t _optionsTimeoutIntervalForRequest; + uint32_t _optionsTimeoutIntervalForResource; + BOOL _networkConnectionReused; + BOOL _optionsAllowExpensiveAccess; + BOOL _optionsAllowPowerNapScheduling; + BOOL _optionsAppleIdContext; + BOOL _optionsOutOfProcess; + BOOL _optionsOutOfProcessForceDiscretionary; + BOOL _optionsTlsPinningRequired; + struct { + int networkRequestBodyBytesSent:1; + int networkResponseBodyBytesReceived:1; + int networkStatusCode:1; + int reportFrequency:1; + int reportFrequencyBase:1; + int timestampC2Init:1; + int timestampC2Now:1; + int timestampC2Start:1; + int timestampDnsEnd:1; + int timestampDnsStart:1; + int timestampRequestEnd:1; + int timestampRequestStart:1; + int timestampResponseEnd:1; + int timestampResponseStart:1; + int timestampSslStart:1; + int timestampTcpEnd:1; + int timestampTcpStart:1; + int triggers:1; + int networkPreviousAttemptCount:1; + int networkRequestHeaderSize:1; + int networkResponseHeaderSize:1; + int optionsTimeoutIntervalForRequest:1; + int optionsTimeoutIntervalForResource:1; + int networkConnectionReused:1; + int optionsAllowExpensiveAccess:1; + int optionsAllowPowerNapScheduling:1; + int optionsAppleIdContext:1; + int optionsOutOfProcess:1; + int optionsOutOfProcessForceDiscretionary:1; + int optionsTlsPinningRequired:1; + } _has; +} + + +@property (nonatomic) BOOL hasTriggers; +/** Deprecated. Use Metric.triggers instead. */ +@property (nonatomic) uint64_t triggers; + +@property (nonatomic) BOOL hasReportFrequency; +/** Deprecated. Use Metric.report_frequency instead. */ +@property (nonatomic) uint64_t reportFrequency; + +@property (nonatomic) BOOL hasReportFrequencyBase; +/** Deprecated. Use Metric.report_frequency_base instead. */ +@property (nonatomic) uint64_t reportFrequencyBase; + +@property (nonatomic, readonly) BOOL hasNetworkTaskDescription; +@property (nonatomic, retain) NSString *networkTaskDescription; + +@property (nonatomic, readonly) BOOL hasNetworkHostname; +@property (nonatomic, retain) NSString *networkHostname; + +@property (nonatomic, readonly) BOOL hasNetworkRemoteAddresssAndPort; +@property (nonatomic, retain) NSString *networkRemoteAddresssAndPort; + +@property (nonatomic, readonly) BOOL hasNetworkConnectionUuid; +@property (nonatomic, retain) NSString *networkConnectionUuid; + +@property (nonatomic) BOOL hasNetworkConnectionReused; +@property (nonatomic) BOOL networkConnectionReused; + +@property (nonatomic, readonly) BOOL hasNetworkInterfaceIdentifier; +@property (nonatomic, retain) NSString *networkInterfaceIdentifier; + +@property (nonatomic, readonly) BOOL hasNetworkProtocolName; +@property (nonatomic, retain) NSString *networkProtocolName; + +@property (nonatomic) BOOL hasNetworkRequestHeaderSize; +@property (nonatomic) uint32_t networkRequestHeaderSize; + +@property (nonatomic) BOOL hasNetworkRequestBodyBytesSent; +@property (nonatomic) uint64_t networkRequestBodyBytesSent; + +@property (nonatomic) BOOL hasNetworkResponseHeaderSize; +@property (nonatomic) uint32_t networkResponseHeaderSize; + +@property (nonatomic) BOOL hasNetworkResponseBodyBytesReceived; +@property (nonatomic) uint64_t networkResponseBodyBytesReceived; + +@property (nonatomic) BOOL hasNetworkPreviousAttemptCount; +@property (nonatomic) uint32_t networkPreviousAttemptCount; + +@property (nonatomic, readonly) BOOL hasNetworkFatalError; +@property (nonatomic, retain) SECC2MPError *networkFatalError; + +@property (nonatomic) BOOL hasNetworkStatusCode; +@property (nonatomic) uint64_t networkStatusCode; + +@property (nonatomic, readonly) BOOL hasNetworkRequestUri; +@property (nonatomic, retain) NSString *networkRequestUri; + +@property (nonatomic) BOOL hasTimestampC2Init; +@property (nonatomic) uint64_t timestampC2Init; + +@property (nonatomic) BOOL hasTimestampC2Start; +@property (nonatomic) uint64_t timestampC2Start; + +@property (nonatomic) BOOL hasTimestampC2Now; +@property (nonatomic) uint64_t timestampC2Now; + +@property (nonatomic) BOOL hasTimestampDnsStart; +@property (nonatomic) uint64_t timestampDnsStart; + +@property (nonatomic) BOOL hasTimestampDnsEnd; +@property (nonatomic) uint64_t timestampDnsEnd; + +@property (nonatomic) BOOL hasTimestampTcpStart; +@property (nonatomic) uint64_t timestampTcpStart; + +@property (nonatomic) BOOL hasTimestampTcpEnd; +@property (nonatomic) uint64_t timestampTcpEnd; + +@property (nonatomic) BOOL hasTimestampSslStart; +@property (nonatomic) uint64_t timestampSslStart; + +@property (nonatomic) BOOL hasTimestampRequestStart; +@property (nonatomic) uint64_t timestampRequestStart; + +@property (nonatomic) BOOL hasTimestampRequestEnd; +@property (nonatomic) uint64_t timestampRequestEnd; + +@property (nonatomic) BOOL hasTimestampResponseStart; +@property (nonatomic) uint64_t timestampResponseStart; + +@property (nonatomic) BOOL hasTimestampResponseEnd; +@property (nonatomic) uint64_t timestampResponseEnd; + +@property (nonatomic, readonly) BOOL hasOptionsQualityOfService; +@property (nonatomic, retain) NSString *optionsQualityOfService; + +@property (nonatomic) BOOL hasOptionsOutOfProcess; +@property (nonatomic) BOOL optionsOutOfProcess; + +@property (nonatomic) BOOL hasOptionsOutOfProcessForceDiscretionary; +@property (nonatomic) BOOL optionsOutOfProcessForceDiscretionary; + +@property (nonatomic) BOOL hasOptionsAllowExpensiveAccess; +@property (nonatomic) BOOL optionsAllowExpensiveAccess; + +@property (nonatomic) BOOL hasOptionsAllowPowerNapScheduling; +@property (nonatomic) BOOL optionsAllowPowerNapScheduling; + +@property (nonatomic) BOOL hasOptionsTimeoutIntervalForRequest; +@property (nonatomic) uint32_t optionsTimeoutIntervalForRequest; + +@property (nonatomic) BOOL hasOptionsTimeoutIntervalForResource; +@property (nonatomic) uint32_t optionsTimeoutIntervalForResource; + +@property (nonatomic, readonly) BOOL hasOptionsSourceApplicationBundleIdentifier; +@property (nonatomic, retain) NSString *optionsSourceApplicationBundleIdentifier; + +@property (nonatomic, readonly) BOOL hasOptionsSourceApplicationSecondaryIdentifier; +@property (nonatomic, retain) NSString *optionsSourceApplicationSecondaryIdentifier; + +@property (nonatomic) BOOL hasOptionsAppleIdContext; +@property (nonatomic) BOOL optionsAppleIdContext; + +@property (nonatomic) BOOL hasOptionsTlsPinningRequired; +@property (nonatomic) BOOL optionsTlsPinningRequired; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPNetworkEvent *)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:(SECC2MPNetworkEvent *)other; + +SECC2MPNETWORKEVENT_FUNCTION BOOL SECC2MPNetworkEventReadFrom(__unsafe_unretained SECC2MPNetworkEvent *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPNetworkEvent.m b/keychain/analytics/C2Metric/SECC2MPNetworkEvent.m new file mode 100644 index 00000000..f1b3c7d6 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPNetworkEvent.m @@ -0,0 +1,1992 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPNetworkEvent.h" +#import +#import +#import + +#import "SECC2MPError.h" + +#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 SECC2MPNetworkEvent + +@synthesize triggers = _triggers; +- (void)setTriggers:(uint64_t)v +{ + _has.triggers = YES; + _triggers = v; +} +- (void)setHasTriggers:(BOOL)f +{ + _has.triggers = f; +} +- (BOOL)hasTriggers +{ + return _has.triggers; +} +@synthesize reportFrequency = _reportFrequency; +- (void)setReportFrequency:(uint64_t)v +{ + _has.reportFrequency = YES; + _reportFrequency = v; +} +- (void)setHasReportFrequency:(BOOL)f +{ + _has.reportFrequency = f; +} +- (BOOL)hasReportFrequency +{ + return _has.reportFrequency; +} +@synthesize reportFrequencyBase = _reportFrequencyBase; +- (void)setReportFrequencyBase:(uint64_t)v +{ + _has.reportFrequencyBase = YES; + _reportFrequencyBase = v; +} +- (void)setHasReportFrequencyBase:(BOOL)f +{ + _has.reportFrequencyBase = f; +} +- (BOOL)hasReportFrequencyBase +{ + return _has.reportFrequencyBase; +} +- (BOOL)hasNetworkTaskDescription +{ + return _networkTaskDescription != nil; +} +@synthesize networkTaskDescription = _networkTaskDescription; +- (BOOL)hasNetworkHostname +{ + return _networkHostname != nil; +} +@synthesize networkHostname = _networkHostname; +- (BOOL)hasNetworkRemoteAddresssAndPort +{ + return _networkRemoteAddresssAndPort != nil; +} +@synthesize networkRemoteAddresssAndPort = _networkRemoteAddresssAndPort; +- (BOOL)hasNetworkConnectionUuid +{ + return _networkConnectionUuid != nil; +} +@synthesize networkConnectionUuid = _networkConnectionUuid; +@synthesize networkConnectionReused = _networkConnectionReused; +- (void)setNetworkConnectionReused:(BOOL)v +{ + _has.networkConnectionReused = YES; + _networkConnectionReused = v; +} +- (void)setHasNetworkConnectionReused:(BOOL)f +{ + _has.networkConnectionReused = f; +} +- (BOOL)hasNetworkConnectionReused +{ + return _has.networkConnectionReused; +} +- (BOOL)hasNetworkInterfaceIdentifier +{ + return _networkInterfaceIdentifier != nil; +} +@synthesize networkInterfaceIdentifier = _networkInterfaceIdentifier; +- (BOOL)hasNetworkProtocolName +{ + return _networkProtocolName != nil; +} +@synthesize networkProtocolName = _networkProtocolName; +@synthesize networkRequestHeaderSize = _networkRequestHeaderSize; +- (void)setNetworkRequestHeaderSize:(uint32_t)v +{ + _has.networkRequestHeaderSize = YES; + _networkRequestHeaderSize = v; +} +- (void)setHasNetworkRequestHeaderSize:(BOOL)f +{ + _has.networkRequestHeaderSize = f; +} +- (BOOL)hasNetworkRequestHeaderSize +{ + return _has.networkRequestHeaderSize; +} +@synthesize networkRequestBodyBytesSent = _networkRequestBodyBytesSent; +- (void)setNetworkRequestBodyBytesSent:(uint64_t)v +{ + _has.networkRequestBodyBytesSent = YES; + _networkRequestBodyBytesSent = v; +} +- (void)setHasNetworkRequestBodyBytesSent:(BOOL)f +{ + _has.networkRequestBodyBytesSent = f; +} +- (BOOL)hasNetworkRequestBodyBytesSent +{ + return _has.networkRequestBodyBytesSent; +} +@synthesize networkResponseHeaderSize = _networkResponseHeaderSize; +- (void)setNetworkResponseHeaderSize:(uint32_t)v +{ + _has.networkResponseHeaderSize = YES; + _networkResponseHeaderSize = v; +} +- (void)setHasNetworkResponseHeaderSize:(BOOL)f +{ + _has.networkResponseHeaderSize = f; +} +- (BOOL)hasNetworkResponseHeaderSize +{ + return _has.networkResponseHeaderSize; +} +@synthesize networkResponseBodyBytesReceived = _networkResponseBodyBytesReceived; +- (void)setNetworkResponseBodyBytesReceived:(uint64_t)v +{ + _has.networkResponseBodyBytesReceived = YES; + _networkResponseBodyBytesReceived = v; +} +- (void)setHasNetworkResponseBodyBytesReceived:(BOOL)f +{ + _has.networkResponseBodyBytesReceived = f; +} +- (BOOL)hasNetworkResponseBodyBytesReceived +{ + return _has.networkResponseBodyBytesReceived; +} +@synthesize networkPreviousAttemptCount = _networkPreviousAttemptCount; +- (void)setNetworkPreviousAttemptCount:(uint32_t)v +{ + _has.networkPreviousAttemptCount = YES; + _networkPreviousAttemptCount = v; +} +- (void)setHasNetworkPreviousAttemptCount:(BOOL)f +{ + _has.networkPreviousAttemptCount = f; +} +- (BOOL)hasNetworkPreviousAttemptCount +{ + return _has.networkPreviousAttemptCount; +} +- (BOOL)hasNetworkFatalError +{ + return _networkFatalError != nil; +} +@synthesize networkFatalError = _networkFatalError; +@synthesize networkStatusCode = _networkStatusCode; +- (void)setNetworkStatusCode:(uint64_t)v +{ + _has.networkStatusCode = YES; + _networkStatusCode = v; +} +- (void)setHasNetworkStatusCode:(BOOL)f +{ + _has.networkStatusCode = f; +} +- (BOOL)hasNetworkStatusCode +{ + return _has.networkStatusCode; +} +- (BOOL)hasNetworkRequestUri +{ + return _networkRequestUri != nil; +} +@synthesize networkRequestUri = _networkRequestUri; +@synthesize timestampC2Init = _timestampC2Init; +- (void)setTimestampC2Init:(uint64_t)v +{ + _has.timestampC2Init = YES; + _timestampC2Init = v; +} +- (void)setHasTimestampC2Init:(BOOL)f +{ + _has.timestampC2Init = f; +} +- (BOOL)hasTimestampC2Init +{ + return _has.timestampC2Init; +} +@synthesize timestampC2Start = _timestampC2Start; +- (void)setTimestampC2Start:(uint64_t)v +{ + _has.timestampC2Start = YES; + _timestampC2Start = v; +} +- (void)setHasTimestampC2Start:(BOOL)f +{ + _has.timestampC2Start = f; +} +- (BOOL)hasTimestampC2Start +{ + return _has.timestampC2Start; +} +@synthesize timestampC2Now = _timestampC2Now; +- (void)setTimestampC2Now:(uint64_t)v +{ + _has.timestampC2Now = YES; + _timestampC2Now = v; +} +- (void)setHasTimestampC2Now:(BOOL)f +{ + _has.timestampC2Now = f; +} +- (BOOL)hasTimestampC2Now +{ + return _has.timestampC2Now; +} +@synthesize timestampDnsStart = _timestampDnsStart; +- (void)setTimestampDnsStart:(uint64_t)v +{ + _has.timestampDnsStart = YES; + _timestampDnsStart = v; +} +- (void)setHasTimestampDnsStart:(BOOL)f +{ + _has.timestampDnsStart = f; +} +- (BOOL)hasTimestampDnsStart +{ + return _has.timestampDnsStart; +} +@synthesize timestampDnsEnd = _timestampDnsEnd; +- (void)setTimestampDnsEnd:(uint64_t)v +{ + _has.timestampDnsEnd = YES; + _timestampDnsEnd = v; +} +- (void)setHasTimestampDnsEnd:(BOOL)f +{ + _has.timestampDnsEnd = f; +} +- (BOOL)hasTimestampDnsEnd +{ + return _has.timestampDnsEnd; +} +@synthesize timestampTcpStart = _timestampTcpStart; +- (void)setTimestampTcpStart:(uint64_t)v +{ + _has.timestampTcpStart = YES; + _timestampTcpStart = v; +} +- (void)setHasTimestampTcpStart:(BOOL)f +{ + _has.timestampTcpStart = f; +} +- (BOOL)hasTimestampTcpStart +{ + return _has.timestampTcpStart; +} +@synthesize timestampTcpEnd = _timestampTcpEnd; +- (void)setTimestampTcpEnd:(uint64_t)v +{ + _has.timestampTcpEnd = YES; + _timestampTcpEnd = v; +} +- (void)setHasTimestampTcpEnd:(BOOL)f +{ + _has.timestampTcpEnd = f; +} +- (BOOL)hasTimestampTcpEnd +{ + return _has.timestampTcpEnd; +} +@synthesize timestampSslStart = _timestampSslStart; +- (void)setTimestampSslStart:(uint64_t)v +{ + _has.timestampSslStart = YES; + _timestampSslStart = v; +} +- (void)setHasTimestampSslStart:(BOOL)f +{ + _has.timestampSslStart = f; +} +- (BOOL)hasTimestampSslStart +{ + return _has.timestampSslStart; +} +@synthesize timestampRequestStart = _timestampRequestStart; +- (void)setTimestampRequestStart:(uint64_t)v +{ + _has.timestampRequestStart = YES; + _timestampRequestStart = v; +} +- (void)setHasTimestampRequestStart:(BOOL)f +{ + _has.timestampRequestStart = f; +} +- (BOOL)hasTimestampRequestStart +{ + return _has.timestampRequestStart; +} +@synthesize timestampRequestEnd = _timestampRequestEnd; +- (void)setTimestampRequestEnd:(uint64_t)v +{ + _has.timestampRequestEnd = YES; + _timestampRequestEnd = v; +} +- (void)setHasTimestampRequestEnd:(BOOL)f +{ + _has.timestampRequestEnd = f; +} +- (BOOL)hasTimestampRequestEnd +{ + return _has.timestampRequestEnd; +} +@synthesize timestampResponseStart = _timestampResponseStart; +- (void)setTimestampResponseStart:(uint64_t)v +{ + _has.timestampResponseStart = YES; + _timestampResponseStart = v; +} +- (void)setHasTimestampResponseStart:(BOOL)f +{ + _has.timestampResponseStart = f; +} +- (BOOL)hasTimestampResponseStart +{ + return _has.timestampResponseStart; +} +@synthesize timestampResponseEnd = _timestampResponseEnd; +- (void)setTimestampResponseEnd:(uint64_t)v +{ + _has.timestampResponseEnd = YES; + _timestampResponseEnd = v; +} +- (void)setHasTimestampResponseEnd:(BOOL)f +{ + _has.timestampResponseEnd = f; +} +- (BOOL)hasTimestampResponseEnd +{ + return _has.timestampResponseEnd; +} +- (BOOL)hasOptionsQualityOfService +{ + return _optionsQualityOfService != nil; +} +@synthesize optionsQualityOfService = _optionsQualityOfService; +@synthesize optionsOutOfProcess = _optionsOutOfProcess; +- (void)setOptionsOutOfProcess:(BOOL)v +{ + _has.optionsOutOfProcess = YES; + _optionsOutOfProcess = v; +} +- (void)setHasOptionsOutOfProcess:(BOOL)f +{ + _has.optionsOutOfProcess = f; +} +- (BOOL)hasOptionsOutOfProcess +{ + return _has.optionsOutOfProcess; +} +@synthesize optionsOutOfProcessForceDiscretionary = _optionsOutOfProcessForceDiscretionary; +- (void)setOptionsOutOfProcessForceDiscretionary:(BOOL)v +{ + _has.optionsOutOfProcessForceDiscretionary = YES; + _optionsOutOfProcessForceDiscretionary = v; +} +- (void)setHasOptionsOutOfProcessForceDiscretionary:(BOOL)f +{ + _has.optionsOutOfProcessForceDiscretionary = f; +} +- (BOOL)hasOptionsOutOfProcessForceDiscretionary +{ + return _has.optionsOutOfProcessForceDiscretionary; +} +@synthesize optionsAllowExpensiveAccess = _optionsAllowExpensiveAccess; +- (void)setOptionsAllowExpensiveAccess:(BOOL)v +{ + _has.optionsAllowExpensiveAccess = YES; + _optionsAllowExpensiveAccess = v; +} +- (void)setHasOptionsAllowExpensiveAccess:(BOOL)f +{ + _has.optionsAllowExpensiveAccess = f; +} +- (BOOL)hasOptionsAllowExpensiveAccess +{ + return _has.optionsAllowExpensiveAccess; +} +@synthesize optionsAllowPowerNapScheduling = _optionsAllowPowerNapScheduling; +- (void)setOptionsAllowPowerNapScheduling:(BOOL)v +{ + _has.optionsAllowPowerNapScheduling = YES; + _optionsAllowPowerNapScheduling = v; +} +- (void)setHasOptionsAllowPowerNapScheduling:(BOOL)f +{ + _has.optionsAllowPowerNapScheduling = f; +} +- (BOOL)hasOptionsAllowPowerNapScheduling +{ + return _has.optionsAllowPowerNapScheduling; +} +@synthesize optionsTimeoutIntervalForRequest = _optionsTimeoutIntervalForRequest; +- (void)setOptionsTimeoutIntervalForRequest:(uint32_t)v +{ + _has.optionsTimeoutIntervalForRequest = YES; + _optionsTimeoutIntervalForRequest = v; +} +- (void)setHasOptionsTimeoutIntervalForRequest:(BOOL)f +{ + _has.optionsTimeoutIntervalForRequest = f; +} +- (BOOL)hasOptionsTimeoutIntervalForRequest +{ + return _has.optionsTimeoutIntervalForRequest; +} +@synthesize optionsTimeoutIntervalForResource = _optionsTimeoutIntervalForResource; +- (void)setOptionsTimeoutIntervalForResource:(uint32_t)v +{ + _has.optionsTimeoutIntervalForResource = YES; + _optionsTimeoutIntervalForResource = v; +} +- (void)setHasOptionsTimeoutIntervalForResource:(BOOL)f +{ + _has.optionsTimeoutIntervalForResource = f; +} +- (BOOL)hasOptionsTimeoutIntervalForResource +{ + return _has.optionsTimeoutIntervalForResource; +} +- (BOOL)hasOptionsSourceApplicationBundleIdentifier +{ + return _optionsSourceApplicationBundleIdentifier != nil; +} +@synthesize optionsSourceApplicationBundleIdentifier = _optionsSourceApplicationBundleIdentifier; +- (BOOL)hasOptionsSourceApplicationSecondaryIdentifier +{ + return _optionsSourceApplicationSecondaryIdentifier != nil; +} +@synthesize optionsSourceApplicationSecondaryIdentifier = _optionsSourceApplicationSecondaryIdentifier; +@synthesize optionsAppleIdContext = _optionsAppleIdContext; +- (void)setOptionsAppleIdContext:(BOOL)v +{ + _has.optionsAppleIdContext = YES; + _optionsAppleIdContext = v; +} +- (void)setHasOptionsAppleIdContext:(BOOL)f +{ + _has.optionsAppleIdContext = f; +} +- (BOOL)hasOptionsAppleIdContext +{ + return _has.optionsAppleIdContext; +} +@synthesize optionsTlsPinningRequired = _optionsTlsPinningRequired; +- (void)setOptionsTlsPinningRequired:(BOOL)v +{ + _has.optionsTlsPinningRequired = YES; + _optionsTlsPinningRequired = v; +} +- (void)setHasOptionsTlsPinningRequired:(BOOL)f +{ + _has.optionsTlsPinningRequired = f; +} +- (BOOL)hasOptionsTlsPinningRequired +{ + return _has.optionsTlsPinningRequired; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.triggers) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_triggers] forKey:@"triggers"]; + } + if (self->_has.reportFrequency) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportFrequency] forKey:@"report_frequency"]; + } + if (self->_has.reportFrequencyBase) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_reportFrequencyBase] forKey:@"report_frequency_base"]; + } + if (self->_networkTaskDescription) + { + [dict setObject:self->_networkTaskDescription forKey:@"network_task_description"]; + } + if (self->_networkHostname) + { + [dict setObject:self->_networkHostname forKey:@"network_hostname"]; + } + if (self->_networkRemoteAddresssAndPort) + { + [dict setObject:self->_networkRemoteAddresssAndPort forKey:@"network_remote_addresss_and_port"]; + } + if (self->_networkConnectionUuid) + { + [dict setObject:self->_networkConnectionUuid forKey:@"network_connection_uuid"]; + } + if (self->_has.networkConnectionReused) + { + [dict setObject:[NSNumber numberWithBool:self->_networkConnectionReused] forKey:@"network_connection_reused"]; + } + if (self->_networkInterfaceIdentifier) + { + [dict setObject:self->_networkInterfaceIdentifier forKey:@"network_interface_identifier"]; + } + if (self->_networkProtocolName) + { + [dict setObject:self->_networkProtocolName forKey:@"network_protocol_name"]; + } + if (self->_has.networkRequestHeaderSize) + { + [dict setObject:[NSNumber numberWithUnsignedInt:self->_networkRequestHeaderSize] forKey:@"network_request_header_size"]; + } + if (self->_has.networkRequestBodyBytesSent) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_networkRequestBodyBytesSent] forKey:@"network_request_body_bytes_sent"]; + } + if (self->_has.networkResponseHeaderSize) + { + [dict setObject:[NSNumber numberWithUnsignedInt:self->_networkResponseHeaderSize] forKey:@"network_response_header_size"]; + } + if (self->_has.networkResponseBodyBytesReceived) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_networkResponseBodyBytesReceived] forKey:@"network_response_body_bytes_received"]; + } + if (self->_has.networkPreviousAttemptCount) + { + [dict setObject:[NSNumber numberWithUnsignedInt:self->_networkPreviousAttemptCount] forKey:@"network_previous_attempt_count"]; + } + if (self->_networkFatalError) + { + [dict setObject:[_networkFatalError dictionaryRepresentation] forKey:@"network_fatal_error"]; + } + if (self->_has.networkStatusCode) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_networkStatusCode] forKey:@"network_status_code"]; + } + if (self->_networkRequestUri) + { + [dict setObject:self->_networkRequestUri forKey:@"network_request_uri"]; + } + if (self->_has.timestampC2Init) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampC2Init] forKey:@"timestamp_c2_init"]; + } + if (self->_has.timestampC2Start) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampC2Start] forKey:@"timestamp_c2_start"]; + } + if (self->_has.timestampC2Now) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampC2Now] forKey:@"timestamp_c2_now"]; + } + if (self->_has.timestampDnsStart) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampDnsStart] forKey:@"timestamp_dns_start"]; + } + if (self->_has.timestampDnsEnd) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampDnsEnd] forKey:@"timestamp_dns_end"]; + } + if (self->_has.timestampTcpStart) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampTcpStart] forKey:@"timestamp_tcp_start"]; + } + if (self->_has.timestampTcpEnd) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampTcpEnd] forKey:@"timestamp_tcp_end"]; + } + if (self->_has.timestampSslStart) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampSslStart] forKey:@"timestamp_ssl_start"]; + } + if (self->_has.timestampRequestStart) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampRequestStart] forKey:@"timestamp_request_start"]; + } + if (self->_has.timestampRequestEnd) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampRequestEnd] forKey:@"timestamp_request_end"]; + } + if (self->_has.timestampResponseStart) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampResponseStart] forKey:@"timestamp_response_start"]; + } + if (self->_has.timestampResponseEnd) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_timestampResponseEnd] forKey:@"timestamp_response_end"]; + } + if (self->_optionsQualityOfService) + { + [dict setObject:self->_optionsQualityOfService forKey:@"options_quality_of_service"]; + } + if (self->_has.optionsOutOfProcess) + { + [dict setObject:[NSNumber numberWithBool:self->_optionsOutOfProcess] forKey:@"options_out_of_process"]; + } + if (self->_has.optionsOutOfProcessForceDiscretionary) + { + [dict setObject:[NSNumber numberWithBool:self->_optionsOutOfProcessForceDiscretionary] forKey:@"options_out_of_process_force_discretionary"]; + } + if (self->_has.optionsAllowExpensiveAccess) + { + [dict setObject:[NSNumber numberWithBool:self->_optionsAllowExpensiveAccess] forKey:@"options_allow_expensive_access"]; + } + if (self->_has.optionsAllowPowerNapScheduling) + { + [dict setObject:[NSNumber numberWithBool:self->_optionsAllowPowerNapScheduling] forKey:@"options_allow_power_nap_scheduling"]; + } + if (self->_has.optionsTimeoutIntervalForRequest) + { + [dict setObject:[NSNumber numberWithUnsignedInt:self->_optionsTimeoutIntervalForRequest] forKey:@"options_timeout_interval_for_request"]; + } + if (self->_has.optionsTimeoutIntervalForResource) + { + [dict setObject:[NSNumber numberWithUnsignedInt:self->_optionsTimeoutIntervalForResource] forKey:@"options_timeout_interval_for_resource"]; + } + if (self->_optionsSourceApplicationBundleIdentifier) + { + [dict setObject:self->_optionsSourceApplicationBundleIdentifier forKey:@"options_source_application_bundle_identifier"]; + } + if (self->_optionsSourceApplicationSecondaryIdentifier) + { + [dict setObject:self->_optionsSourceApplicationSecondaryIdentifier forKey:@"options_source_application_secondary_identifier"]; + } + if (self->_has.optionsAppleIdContext) + { + [dict setObject:[NSNumber numberWithBool:self->_optionsAppleIdContext] forKey:@"options_apple_id_context"]; + } + if (self->_has.optionsTlsPinningRequired) + { + [dict setObject:[NSNumber numberWithBool:self->_optionsTlsPinningRequired] forKey:@"options_tls_pinning_required"]; + } + return dict; +} + +BOOL SECC2MPNetworkEventReadFrom(__unsafe_unretained SECC2MPNetworkEvent *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 /* triggers */: + { + self->_has.triggers = YES; + self->_triggers = PBReaderReadUint64(reader); + } + break; + case 2 /* reportFrequency */: + { + self->_has.reportFrequency = YES; + self->_reportFrequency = PBReaderReadUint64(reader); + } + break; + case 3 /* reportFrequencyBase */: + { + self->_has.reportFrequencyBase = YES; + self->_reportFrequencyBase = PBReaderReadUint64(reader); + } + break; + case 101 /* networkTaskDescription */: + { + NSString *new_networkTaskDescription = PBReaderReadString(reader); + self->_networkTaskDescription = new_networkTaskDescription; + } + break; + case 102 /* networkHostname */: + { + NSString *new_networkHostname = PBReaderReadString(reader); + self->_networkHostname = new_networkHostname; + } + break; + case 103 /* networkRemoteAddresssAndPort */: + { + NSString *new_networkRemoteAddresssAndPort = PBReaderReadString(reader); + self->_networkRemoteAddresssAndPort = new_networkRemoteAddresssAndPort; + } + break; + case 104 /* networkConnectionUuid */: + { + NSString *new_networkConnectionUuid = PBReaderReadString(reader); + self->_networkConnectionUuid = new_networkConnectionUuid; + } + break; + case 105 /* networkConnectionReused */: + { + self->_has.networkConnectionReused = YES; + self->_networkConnectionReused = PBReaderReadBOOL(reader); + } + break; + case 106 /* networkInterfaceIdentifier */: + { + NSString *new_networkInterfaceIdentifier = PBReaderReadString(reader); + self->_networkInterfaceIdentifier = new_networkInterfaceIdentifier; + } + break; + case 107 /* networkProtocolName */: + { + NSString *new_networkProtocolName = PBReaderReadString(reader); + self->_networkProtocolName = new_networkProtocolName; + } + break; + case 108 /* networkRequestHeaderSize */: + { + self->_has.networkRequestHeaderSize = YES; + self->_networkRequestHeaderSize = PBReaderReadUint32(reader); + } + break; + case 109 /* networkRequestBodyBytesSent */: + { + self->_has.networkRequestBodyBytesSent = YES; + self->_networkRequestBodyBytesSent = PBReaderReadUint64(reader); + } + break; + case 110 /* networkResponseHeaderSize */: + { + self->_has.networkResponseHeaderSize = YES; + self->_networkResponseHeaderSize = PBReaderReadUint32(reader); + } + break; + case 111 /* networkResponseBodyBytesReceived */: + { + self->_has.networkResponseBodyBytesReceived = YES; + self->_networkResponseBodyBytesReceived = PBReaderReadUint64(reader); + } + break; + case 112 /* networkPreviousAttemptCount */: + { + self->_has.networkPreviousAttemptCount = YES; + self->_networkPreviousAttemptCount = PBReaderReadUint32(reader); + } + break; + case 113 /* networkFatalError */: + { + SECC2MPError *new_networkFatalError = [[SECC2MPError alloc] init]; + self->_networkFatalError = new_networkFatalError; + PBDataReaderMark mark_networkFatalError; + BOOL markError = !PBReaderPlaceMark(reader, &mark_networkFatalError); + if (markError) + { + return NO; + } + BOOL inError = !SECC2MPErrorReadFrom(new_networkFatalError, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_networkFatalError); + } + break; + case 114 /* networkStatusCode */: + { + self->_has.networkStatusCode = YES; + self->_networkStatusCode = PBReaderReadUint64(reader); + } + break; + case 115 /* networkRequestUri */: + { + NSString *new_networkRequestUri = PBReaderReadString(reader); + self->_networkRequestUri = new_networkRequestUri; + } + break; + case 201 /* timestampC2Init */: + { + self->_has.timestampC2Init = YES; + self->_timestampC2Init = PBReaderReadUint64(reader); + } + break; + case 202 /* timestampC2Start */: + { + self->_has.timestampC2Start = YES; + self->_timestampC2Start = PBReaderReadUint64(reader); + } + break; + case 203 /* timestampC2Now */: + { + self->_has.timestampC2Now = YES; + self->_timestampC2Now = PBReaderReadUint64(reader); + } + break; + case 204 /* timestampDnsStart */: + { + self->_has.timestampDnsStart = YES; + self->_timestampDnsStart = PBReaderReadUint64(reader); + } + break; + case 205 /* timestampDnsEnd */: + { + self->_has.timestampDnsEnd = YES; + self->_timestampDnsEnd = PBReaderReadUint64(reader); + } + break; + case 206 /* timestampTcpStart */: + { + self->_has.timestampTcpStart = YES; + self->_timestampTcpStart = PBReaderReadUint64(reader); + } + break; + case 207 /* timestampTcpEnd */: + { + self->_has.timestampTcpEnd = YES; + self->_timestampTcpEnd = PBReaderReadUint64(reader); + } + break; + case 208 /* timestampSslStart */: + { + self->_has.timestampSslStart = YES; + self->_timestampSslStart = PBReaderReadUint64(reader); + } + break; + case 209 /* timestampRequestStart */: + { + self->_has.timestampRequestStart = YES; + self->_timestampRequestStart = PBReaderReadUint64(reader); + } + break; + case 210 /* timestampRequestEnd */: + { + self->_has.timestampRequestEnd = YES; + self->_timestampRequestEnd = PBReaderReadUint64(reader); + } + break; + case 211 /* timestampResponseStart */: + { + self->_has.timestampResponseStart = YES; + self->_timestampResponseStart = PBReaderReadUint64(reader); + } + break; + case 212 /* timestampResponseEnd */: + { + self->_has.timestampResponseEnd = YES; + self->_timestampResponseEnd = PBReaderReadUint64(reader); + } + break; + case 301 /* optionsQualityOfService */: + { + NSString *new_optionsQualityOfService = PBReaderReadString(reader); + self->_optionsQualityOfService = new_optionsQualityOfService; + } + break; + case 302 /* optionsOutOfProcess */: + { + self->_has.optionsOutOfProcess = YES; + self->_optionsOutOfProcess = PBReaderReadBOOL(reader); + } + break; + case 303 /* optionsOutOfProcessForceDiscretionary */: + { + self->_has.optionsOutOfProcessForceDiscretionary = YES; + self->_optionsOutOfProcessForceDiscretionary = PBReaderReadBOOL(reader); + } + break; + case 304 /* optionsAllowExpensiveAccess */: + { + self->_has.optionsAllowExpensiveAccess = YES; + self->_optionsAllowExpensiveAccess = PBReaderReadBOOL(reader); + } + break; + case 305 /* optionsAllowPowerNapScheduling */: + { + self->_has.optionsAllowPowerNapScheduling = YES; + self->_optionsAllowPowerNapScheduling = PBReaderReadBOOL(reader); + } + break; + case 306 /* optionsTimeoutIntervalForRequest */: + { + self->_has.optionsTimeoutIntervalForRequest = YES; + self->_optionsTimeoutIntervalForRequest = PBReaderReadUint32(reader); + } + break; + case 307 /* optionsTimeoutIntervalForResource */: + { + self->_has.optionsTimeoutIntervalForResource = YES; + self->_optionsTimeoutIntervalForResource = PBReaderReadUint32(reader); + } + break; + case 308 /* optionsSourceApplicationBundleIdentifier */: + { + NSString *new_optionsSourceApplicationBundleIdentifier = PBReaderReadString(reader); + self->_optionsSourceApplicationBundleIdentifier = new_optionsSourceApplicationBundleIdentifier; + } + break; + case 309 /* optionsSourceApplicationSecondaryIdentifier */: + { + NSString *new_optionsSourceApplicationSecondaryIdentifier = PBReaderReadString(reader); + self->_optionsSourceApplicationSecondaryIdentifier = new_optionsSourceApplicationSecondaryIdentifier; + } + break; + case 310 /* optionsAppleIdContext */: + { + self->_has.optionsAppleIdContext = YES; + self->_optionsAppleIdContext = PBReaderReadBOOL(reader); + } + break; + case 311 /* optionsTlsPinningRequired */: + { + self->_has.optionsTlsPinningRequired = YES; + self->_optionsTlsPinningRequired = PBReaderReadBOOL(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPNetworkEventReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* triggers */ + { + if (self->_has.triggers) + { + PBDataWriterWriteUint64Field(writer, self->_triggers, 1); + } + } + /* reportFrequency */ + { + if (self->_has.reportFrequency) + { + PBDataWriterWriteUint64Field(writer, self->_reportFrequency, 2); + } + } + /* reportFrequencyBase */ + { + if (self->_has.reportFrequencyBase) + { + PBDataWriterWriteUint64Field(writer, self->_reportFrequencyBase, 3); + } + } + /* networkTaskDescription */ + { + if (self->_networkTaskDescription) + { + PBDataWriterWriteStringField(writer, self->_networkTaskDescription, 101); + } + } + /* networkHostname */ + { + if (self->_networkHostname) + { + PBDataWriterWriteStringField(writer, self->_networkHostname, 102); + } + } + /* networkRemoteAddresssAndPort */ + { + if (self->_networkRemoteAddresssAndPort) + { + PBDataWriterWriteStringField(writer, self->_networkRemoteAddresssAndPort, 103); + } + } + /* networkConnectionUuid */ + { + if (self->_networkConnectionUuid) + { + PBDataWriterWriteStringField(writer, self->_networkConnectionUuid, 104); + } + } + /* networkConnectionReused */ + { + if (self->_has.networkConnectionReused) + { + PBDataWriterWriteBOOLField(writer, self->_networkConnectionReused, 105); + } + } + /* networkInterfaceIdentifier */ + { + if (self->_networkInterfaceIdentifier) + { + PBDataWriterWriteStringField(writer, self->_networkInterfaceIdentifier, 106); + } + } + /* networkProtocolName */ + { + if (self->_networkProtocolName) + { + PBDataWriterWriteStringField(writer, self->_networkProtocolName, 107); + } + } + /* networkRequestHeaderSize */ + { + if (self->_has.networkRequestHeaderSize) + { + PBDataWriterWriteUint32Field(writer, self->_networkRequestHeaderSize, 108); + } + } + /* networkRequestBodyBytesSent */ + { + if (self->_has.networkRequestBodyBytesSent) + { + PBDataWriterWriteUint64Field(writer, self->_networkRequestBodyBytesSent, 109); + } + } + /* networkResponseHeaderSize */ + { + if (self->_has.networkResponseHeaderSize) + { + PBDataWriterWriteUint32Field(writer, self->_networkResponseHeaderSize, 110); + } + } + /* networkResponseBodyBytesReceived */ + { + if (self->_has.networkResponseBodyBytesReceived) + { + PBDataWriterWriteUint64Field(writer, self->_networkResponseBodyBytesReceived, 111); + } + } + /* networkPreviousAttemptCount */ + { + if (self->_has.networkPreviousAttemptCount) + { + PBDataWriterWriteUint32Field(writer, self->_networkPreviousAttemptCount, 112); + } + } + /* networkFatalError */ + { + if (self->_networkFatalError != nil) + { + PBDataWriterWriteSubmessage(writer, self->_networkFatalError, 113); + } + } + /* networkStatusCode */ + { + if (self->_has.networkStatusCode) + { + PBDataWriterWriteUint64Field(writer, self->_networkStatusCode, 114); + } + } + /* networkRequestUri */ + { + if (self->_networkRequestUri) + { + PBDataWriterWriteStringField(writer, self->_networkRequestUri, 115); + } + } + /* timestampC2Init */ + { + if (self->_has.timestampC2Init) + { + PBDataWriterWriteUint64Field(writer, self->_timestampC2Init, 201); + } + } + /* timestampC2Start */ + { + if (self->_has.timestampC2Start) + { + PBDataWriterWriteUint64Field(writer, self->_timestampC2Start, 202); + } + } + /* timestampC2Now */ + { + if (self->_has.timestampC2Now) + { + PBDataWriterWriteUint64Field(writer, self->_timestampC2Now, 203); + } + } + /* timestampDnsStart */ + { + if (self->_has.timestampDnsStart) + { + PBDataWriterWriteUint64Field(writer, self->_timestampDnsStart, 204); + } + } + /* timestampDnsEnd */ + { + if (self->_has.timestampDnsEnd) + { + PBDataWriterWriteUint64Field(writer, self->_timestampDnsEnd, 205); + } + } + /* timestampTcpStart */ + { + if (self->_has.timestampTcpStart) + { + PBDataWriterWriteUint64Field(writer, self->_timestampTcpStart, 206); + } + } + /* timestampTcpEnd */ + { + if (self->_has.timestampTcpEnd) + { + PBDataWriterWriteUint64Field(writer, self->_timestampTcpEnd, 207); + } + } + /* timestampSslStart */ + { + if (self->_has.timestampSslStart) + { + PBDataWriterWriteUint64Field(writer, self->_timestampSslStart, 208); + } + } + /* timestampRequestStart */ + { + if (self->_has.timestampRequestStart) + { + PBDataWriterWriteUint64Field(writer, self->_timestampRequestStart, 209); + } + } + /* timestampRequestEnd */ + { + if (self->_has.timestampRequestEnd) + { + PBDataWriterWriteUint64Field(writer, self->_timestampRequestEnd, 210); + } + } + /* timestampResponseStart */ + { + if (self->_has.timestampResponseStart) + { + PBDataWriterWriteUint64Field(writer, self->_timestampResponseStart, 211); + } + } + /* timestampResponseEnd */ + { + if (self->_has.timestampResponseEnd) + { + PBDataWriterWriteUint64Field(writer, self->_timestampResponseEnd, 212); + } + } + /* optionsQualityOfService */ + { + if (self->_optionsQualityOfService) + { + PBDataWriterWriteStringField(writer, self->_optionsQualityOfService, 301); + } + } + /* optionsOutOfProcess */ + { + if (self->_has.optionsOutOfProcess) + { + PBDataWriterWriteBOOLField(writer, self->_optionsOutOfProcess, 302); + } + } + /* optionsOutOfProcessForceDiscretionary */ + { + if (self->_has.optionsOutOfProcessForceDiscretionary) + { + PBDataWriterWriteBOOLField(writer, self->_optionsOutOfProcessForceDiscretionary, 303); + } + } + /* optionsAllowExpensiveAccess */ + { + if (self->_has.optionsAllowExpensiveAccess) + { + PBDataWriterWriteBOOLField(writer, self->_optionsAllowExpensiveAccess, 304); + } + } + /* optionsAllowPowerNapScheduling */ + { + if (self->_has.optionsAllowPowerNapScheduling) + { + PBDataWriterWriteBOOLField(writer, self->_optionsAllowPowerNapScheduling, 305); + } + } + /* optionsTimeoutIntervalForRequest */ + { + if (self->_has.optionsTimeoutIntervalForRequest) + { + PBDataWriterWriteUint32Field(writer, self->_optionsTimeoutIntervalForRequest, 306); + } + } + /* optionsTimeoutIntervalForResource */ + { + if (self->_has.optionsTimeoutIntervalForResource) + { + PBDataWriterWriteUint32Field(writer, self->_optionsTimeoutIntervalForResource, 307); + } + } + /* optionsSourceApplicationBundleIdentifier */ + { + if (self->_optionsSourceApplicationBundleIdentifier) + { + PBDataWriterWriteStringField(writer, self->_optionsSourceApplicationBundleIdentifier, 308); + } + } + /* optionsSourceApplicationSecondaryIdentifier */ + { + if (self->_optionsSourceApplicationSecondaryIdentifier) + { + PBDataWriterWriteStringField(writer, self->_optionsSourceApplicationSecondaryIdentifier, 309); + } + } + /* optionsAppleIdContext */ + { + if (self->_has.optionsAppleIdContext) + { + PBDataWriterWriteBOOLField(writer, self->_optionsAppleIdContext, 310); + } + } + /* optionsTlsPinningRequired */ + { + if (self->_has.optionsTlsPinningRequired) + { + PBDataWriterWriteBOOLField(writer, self->_optionsTlsPinningRequired, 311); + } + } +} + +- (void)copyTo:(SECC2MPNetworkEvent *)other +{ + if (self->_has.triggers) + { + other->_triggers = _triggers; + other->_has.triggers = YES; + } + if (self->_has.reportFrequency) + { + other->_reportFrequency = _reportFrequency; + other->_has.reportFrequency = YES; + } + if (self->_has.reportFrequencyBase) + { + other->_reportFrequencyBase = _reportFrequencyBase; + other->_has.reportFrequencyBase = YES; + } + if (_networkTaskDescription) + { + other.networkTaskDescription = _networkTaskDescription; + } + if (_networkHostname) + { + other.networkHostname = _networkHostname; + } + if (_networkRemoteAddresssAndPort) + { + other.networkRemoteAddresssAndPort = _networkRemoteAddresssAndPort; + } + if (_networkConnectionUuid) + { + other.networkConnectionUuid = _networkConnectionUuid; + } + if (self->_has.networkConnectionReused) + { + other->_networkConnectionReused = _networkConnectionReused; + other->_has.networkConnectionReused = YES; + } + if (_networkInterfaceIdentifier) + { + other.networkInterfaceIdentifier = _networkInterfaceIdentifier; + } + if (_networkProtocolName) + { + other.networkProtocolName = _networkProtocolName; + } + if (self->_has.networkRequestHeaderSize) + { + other->_networkRequestHeaderSize = _networkRequestHeaderSize; + other->_has.networkRequestHeaderSize = YES; + } + if (self->_has.networkRequestBodyBytesSent) + { + other->_networkRequestBodyBytesSent = _networkRequestBodyBytesSent; + other->_has.networkRequestBodyBytesSent = YES; + } + if (self->_has.networkResponseHeaderSize) + { + other->_networkResponseHeaderSize = _networkResponseHeaderSize; + other->_has.networkResponseHeaderSize = YES; + } + if (self->_has.networkResponseBodyBytesReceived) + { + other->_networkResponseBodyBytesReceived = _networkResponseBodyBytesReceived; + other->_has.networkResponseBodyBytesReceived = YES; + } + if (self->_has.networkPreviousAttemptCount) + { + other->_networkPreviousAttemptCount = _networkPreviousAttemptCount; + other->_has.networkPreviousAttemptCount = YES; + } + if (_networkFatalError) + { + other.networkFatalError = _networkFatalError; + } + if (self->_has.networkStatusCode) + { + other->_networkStatusCode = _networkStatusCode; + other->_has.networkStatusCode = YES; + } + if (_networkRequestUri) + { + other.networkRequestUri = _networkRequestUri; + } + if (self->_has.timestampC2Init) + { + other->_timestampC2Init = _timestampC2Init; + other->_has.timestampC2Init = YES; + } + if (self->_has.timestampC2Start) + { + other->_timestampC2Start = _timestampC2Start; + other->_has.timestampC2Start = YES; + } + if (self->_has.timestampC2Now) + { + other->_timestampC2Now = _timestampC2Now; + other->_has.timestampC2Now = YES; + } + if (self->_has.timestampDnsStart) + { + other->_timestampDnsStart = _timestampDnsStart; + other->_has.timestampDnsStart = YES; + } + if (self->_has.timestampDnsEnd) + { + other->_timestampDnsEnd = _timestampDnsEnd; + other->_has.timestampDnsEnd = YES; + } + if (self->_has.timestampTcpStart) + { + other->_timestampTcpStart = _timestampTcpStart; + other->_has.timestampTcpStart = YES; + } + if (self->_has.timestampTcpEnd) + { + other->_timestampTcpEnd = _timestampTcpEnd; + other->_has.timestampTcpEnd = YES; + } + if (self->_has.timestampSslStart) + { + other->_timestampSslStart = _timestampSslStart; + other->_has.timestampSslStart = YES; + } + if (self->_has.timestampRequestStart) + { + other->_timestampRequestStart = _timestampRequestStart; + other->_has.timestampRequestStart = YES; + } + if (self->_has.timestampRequestEnd) + { + other->_timestampRequestEnd = _timestampRequestEnd; + other->_has.timestampRequestEnd = YES; + } + if (self->_has.timestampResponseStart) + { + other->_timestampResponseStart = _timestampResponseStart; + other->_has.timestampResponseStart = YES; + } + if (self->_has.timestampResponseEnd) + { + other->_timestampResponseEnd = _timestampResponseEnd; + other->_has.timestampResponseEnd = YES; + } + if (_optionsQualityOfService) + { + other.optionsQualityOfService = _optionsQualityOfService; + } + if (self->_has.optionsOutOfProcess) + { + other->_optionsOutOfProcess = _optionsOutOfProcess; + other->_has.optionsOutOfProcess = YES; + } + if (self->_has.optionsOutOfProcessForceDiscretionary) + { + other->_optionsOutOfProcessForceDiscretionary = _optionsOutOfProcessForceDiscretionary; + other->_has.optionsOutOfProcessForceDiscretionary = YES; + } + if (self->_has.optionsAllowExpensiveAccess) + { + other->_optionsAllowExpensiveAccess = _optionsAllowExpensiveAccess; + other->_has.optionsAllowExpensiveAccess = YES; + } + if (self->_has.optionsAllowPowerNapScheduling) + { + other->_optionsAllowPowerNapScheduling = _optionsAllowPowerNapScheduling; + other->_has.optionsAllowPowerNapScheduling = YES; + } + if (self->_has.optionsTimeoutIntervalForRequest) + { + other->_optionsTimeoutIntervalForRequest = _optionsTimeoutIntervalForRequest; + other->_has.optionsTimeoutIntervalForRequest = YES; + } + if (self->_has.optionsTimeoutIntervalForResource) + { + other->_optionsTimeoutIntervalForResource = _optionsTimeoutIntervalForResource; + other->_has.optionsTimeoutIntervalForResource = YES; + } + if (_optionsSourceApplicationBundleIdentifier) + { + other.optionsSourceApplicationBundleIdentifier = _optionsSourceApplicationBundleIdentifier; + } + if (_optionsSourceApplicationSecondaryIdentifier) + { + other.optionsSourceApplicationSecondaryIdentifier = _optionsSourceApplicationSecondaryIdentifier; + } + if (self->_has.optionsAppleIdContext) + { + other->_optionsAppleIdContext = _optionsAppleIdContext; + other->_has.optionsAppleIdContext = YES; + } + if (self->_has.optionsTlsPinningRequired) + { + other->_optionsTlsPinningRequired = _optionsTlsPinningRequired; + other->_has.optionsTlsPinningRequired = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPNetworkEvent *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.triggers) + { + copy->_triggers = _triggers; + copy->_has.triggers = YES; + } + if (self->_has.reportFrequency) + { + copy->_reportFrequency = _reportFrequency; + copy->_has.reportFrequency = YES; + } + if (self->_has.reportFrequencyBase) + { + copy->_reportFrequencyBase = _reportFrequencyBase; + copy->_has.reportFrequencyBase = YES; + } + copy->_networkTaskDescription = [_networkTaskDescription copyWithZone:zone]; + copy->_networkHostname = [_networkHostname copyWithZone:zone]; + copy->_networkRemoteAddresssAndPort = [_networkRemoteAddresssAndPort copyWithZone:zone]; + copy->_networkConnectionUuid = [_networkConnectionUuid copyWithZone:zone]; + if (self->_has.networkConnectionReused) + { + copy->_networkConnectionReused = _networkConnectionReused; + copy->_has.networkConnectionReused = YES; + } + copy->_networkInterfaceIdentifier = [_networkInterfaceIdentifier copyWithZone:zone]; + copy->_networkProtocolName = [_networkProtocolName copyWithZone:zone]; + if (self->_has.networkRequestHeaderSize) + { + copy->_networkRequestHeaderSize = _networkRequestHeaderSize; + copy->_has.networkRequestHeaderSize = YES; + } + if (self->_has.networkRequestBodyBytesSent) + { + copy->_networkRequestBodyBytesSent = _networkRequestBodyBytesSent; + copy->_has.networkRequestBodyBytesSent = YES; + } + if (self->_has.networkResponseHeaderSize) + { + copy->_networkResponseHeaderSize = _networkResponseHeaderSize; + copy->_has.networkResponseHeaderSize = YES; + } + if (self->_has.networkResponseBodyBytesReceived) + { + copy->_networkResponseBodyBytesReceived = _networkResponseBodyBytesReceived; + copy->_has.networkResponseBodyBytesReceived = YES; + } + if (self->_has.networkPreviousAttemptCount) + { + copy->_networkPreviousAttemptCount = _networkPreviousAttemptCount; + copy->_has.networkPreviousAttemptCount = YES; + } + copy->_networkFatalError = [_networkFatalError copyWithZone:zone]; + if (self->_has.networkStatusCode) + { + copy->_networkStatusCode = _networkStatusCode; + copy->_has.networkStatusCode = YES; + } + copy->_networkRequestUri = [_networkRequestUri copyWithZone:zone]; + if (self->_has.timestampC2Init) + { + copy->_timestampC2Init = _timestampC2Init; + copy->_has.timestampC2Init = YES; + } + if (self->_has.timestampC2Start) + { + copy->_timestampC2Start = _timestampC2Start; + copy->_has.timestampC2Start = YES; + } + if (self->_has.timestampC2Now) + { + copy->_timestampC2Now = _timestampC2Now; + copy->_has.timestampC2Now = YES; + } + if (self->_has.timestampDnsStart) + { + copy->_timestampDnsStart = _timestampDnsStart; + copy->_has.timestampDnsStart = YES; + } + if (self->_has.timestampDnsEnd) + { + copy->_timestampDnsEnd = _timestampDnsEnd; + copy->_has.timestampDnsEnd = YES; + } + if (self->_has.timestampTcpStart) + { + copy->_timestampTcpStart = _timestampTcpStart; + copy->_has.timestampTcpStart = YES; + } + if (self->_has.timestampTcpEnd) + { + copy->_timestampTcpEnd = _timestampTcpEnd; + copy->_has.timestampTcpEnd = YES; + } + if (self->_has.timestampSslStart) + { + copy->_timestampSslStart = _timestampSslStart; + copy->_has.timestampSslStart = YES; + } + if (self->_has.timestampRequestStart) + { + copy->_timestampRequestStart = _timestampRequestStart; + copy->_has.timestampRequestStart = YES; + } + if (self->_has.timestampRequestEnd) + { + copy->_timestampRequestEnd = _timestampRequestEnd; + copy->_has.timestampRequestEnd = YES; + } + if (self->_has.timestampResponseStart) + { + copy->_timestampResponseStart = _timestampResponseStart; + copy->_has.timestampResponseStart = YES; + } + if (self->_has.timestampResponseEnd) + { + copy->_timestampResponseEnd = _timestampResponseEnd; + copy->_has.timestampResponseEnd = YES; + } + copy->_optionsQualityOfService = [_optionsQualityOfService copyWithZone:zone]; + if (self->_has.optionsOutOfProcess) + { + copy->_optionsOutOfProcess = _optionsOutOfProcess; + copy->_has.optionsOutOfProcess = YES; + } + if (self->_has.optionsOutOfProcessForceDiscretionary) + { + copy->_optionsOutOfProcessForceDiscretionary = _optionsOutOfProcessForceDiscretionary; + copy->_has.optionsOutOfProcessForceDiscretionary = YES; + } + if (self->_has.optionsAllowExpensiveAccess) + { + copy->_optionsAllowExpensiveAccess = _optionsAllowExpensiveAccess; + copy->_has.optionsAllowExpensiveAccess = YES; + } + if (self->_has.optionsAllowPowerNapScheduling) + { + copy->_optionsAllowPowerNapScheduling = _optionsAllowPowerNapScheduling; + copy->_has.optionsAllowPowerNapScheduling = YES; + } + if (self->_has.optionsTimeoutIntervalForRequest) + { + copy->_optionsTimeoutIntervalForRequest = _optionsTimeoutIntervalForRequest; + copy->_has.optionsTimeoutIntervalForRequest = YES; + } + if (self->_has.optionsTimeoutIntervalForResource) + { + copy->_optionsTimeoutIntervalForResource = _optionsTimeoutIntervalForResource; + copy->_has.optionsTimeoutIntervalForResource = YES; + } + copy->_optionsSourceApplicationBundleIdentifier = [_optionsSourceApplicationBundleIdentifier copyWithZone:zone]; + copy->_optionsSourceApplicationSecondaryIdentifier = [_optionsSourceApplicationSecondaryIdentifier copyWithZone:zone]; + if (self->_has.optionsAppleIdContext) + { + copy->_optionsAppleIdContext = _optionsAppleIdContext; + copy->_has.optionsAppleIdContext = YES; + } + if (self->_has.optionsTlsPinningRequired) + { + copy->_optionsTlsPinningRequired = _optionsTlsPinningRequired; + copy->_has.optionsTlsPinningRequired = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPNetworkEvent *other = (SECC2MPNetworkEvent *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.triggers && other->_has.triggers && self->_triggers == other->_triggers) || (!self->_has.triggers && !other->_has.triggers)) + && + ((self->_has.reportFrequency && other->_has.reportFrequency && self->_reportFrequency == other->_reportFrequency) || (!self->_has.reportFrequency && !other->_has.reportFrequency)) + && + ((self->_has.reportFrequencyBase && other->_has.reportFrequencyBase && self->_reportFrequencyBase == other->_reportFrequencyBase) || (!self->_has.reportFrequencyBase && !other->_has.reportFrequencyBase)) + && + ((!self->_networkTaskDescription && !other->_networkTaskDescription) || [self->_networkTaskDescription isEqual:other->_networkTaskDescription]) + && + ((!self->_networkHostname && !other->_networkHostname) || [self->_networkHostname isEqual:other->_networkHostname]) + && + ((!self->_networkRemoteAddresssAndPort && !other->_networkRemoteAddresssAndPort) || [self->_networkRemoteAddresssAndPort isEqual:other->_networkRemoteAddresssAndPort]) + && + ((!self->_networkConnectionUuid && !other->_networkConnectionUuid) || [self->_networkConnectionUuid isEqual:other->_networkConnectionUuid]) + && + ((self->_has.networkConnectionReused && other->_has.networkConnectionReused && ((self->_networkConnectionReused && other->_networkConnectionReused) || (!self->_networkConnectionReused && !other->_networkConnectionReused))) || (!self->_has.networkConnectionReused && !other->_has.networkConnectionReused)) + && + ((!self->_networkInterfaceIdentifier && !other->_networkInterfaceIdentifier) || [self->_networkInterfaceIdentifier isEqual:other->_networkInterfaceIdentifier]) + && + ((!self->_networkProtocolName && !other->_networkProtocolName) || [self->_networkProtocolName isEqual:other->_networkProtocolName]) + && + ((self->_has.networkRequestHeaderSize && other->_has.networkRequestHeaderSize && self->_networkRequestHeaderSize == other->_networkRequestHeaderSize) || (!self->_has.networkRequestHeaderSize && !other->_has.networkRequestHeaderSize)) + && + ((self->_has.networkRequestBodyBytesSent && other->_has.networkRequestBodyBytesSent && self->_networkRequestBodyBytesSent == other->_networkRequestBodyBytesSent) || (!self->_has.networkRequestBodyBytesSent && !other->_has.networkRequestBodyBytesSent)) + && + ((self->_has.networkResponseHeaderSize && other->_has.networkResponseHeaderSize && self->_networkResponseHeaderSize == other->_networkResponseHeaderSize) || (!self->_has.networkResponseHeaderSize && !other->_has.networkResponseHeaderSize)) + && + ((self->_has.networkResponseBodyBytesReceived && other->_has.networkResponseBodyBytesReceived && self->_networkResponseBodyBytesReceived == other->_networkResponseBodyBytesReceived) || (!self->_has.networkResponseBodyBytesReceived && !other->_has.networkResponseBodyBytesReceived)) + && + ((self->_has.networkPreviousAttemptCount && other->_has.networkPreviousAttemptCount && self->_networkPreviousAttemptCount == other->_networkPreviousAttemptCount) || (!self->_has.networkPreviousAttemptCount && !other->_has.networkPreviousAttemptCount)) + && + ((!self->_networkFatalError && !other->_networkFatalError) || [self->_networkFatalError isEqual:other->_networkFatalError]) + && + ((self->_has.networkStatusCode && other->_has.networkStatusCode && self->_networkStatusCode == other->_networkStatusCode) || (!self->_has.networkStatusCode && !other->_has.networkStatusCode)) + && + ((!self->_networkRequestUri && !other->_networkRequestUri) || [self->_networkRequestUri isEqual:other->_networkRequestUri]) + && + ((self->_has.timestampC2Init && other->_has.timestampC2Init && self->_timestampC2Init == other->_timestampC2Init) || (!self->_has.timestampC2Init && !other->_has.timestampC2Init)) + && + ((self->_has.timestampC2Start && other->_has.timestampC2Start && self->_timestampC2Start == other->_timestampC2Start) || (!self->_has.timestampC2Start && !other->_has.timestampC2Start)) + && + ((self->_has.timestampC2Now && other->_has.timestampC2Now && self->_timestampC2Now == other->_timestampC2Now) || (!self->_has.timestampC2Now && !other->_has.timestampC2Now)) + && + ((self->_has.timestampDnsStart && other->_has.timestampDnsStart && self->_timestampDnsStart == other->_timestampDnsStart) || (!self->_has.timestampDnsStart && !other->_has.timestampDnsStart)) + && + ((self->_has.timestampDnsEnd && other->_has.timestampDnsEnd && self->_timestampDnsEnd == other->_timestampDnsEnd) || (!self->_has.timestampDnsEnd && !other->_has.timestampDnsEnd)) + && + ((self->_has.timestampTcpStart && other->_has.timestampTcpStart && self->_timestampTcpStart == other->_timestampTcpStart) || (!self->_has.timestampTcpStart && !other->_has.timestampTcpStart)) + && + ((self->_has.timestampTcpEnd && other->_has.timestampTcpEnd && self->_timestampTcpEnd == other->_timestampTcpEnd) || (!self->_has.timestampTcpEnd && !other->_has.timestampTcpEnd)) + && + ((self->_has.timestampSslStart && other->_has.timestampSslStart && self->_timestampSslStart == other->_timestampSslStart) || (!self->_has.timestampSslStart && !other->_has.timestampSslStart)) + && + ((self->_has.timestampRequestStart && other->_has.timestampRequestStart && self->_timestampRequestStart == other->_timestampRequestStart) || (!self->_has.timestampRequestStart && !other->_has.timestampRequestStart)) + && + ((self->_has.timestampRequestEnd && other->_has.timestampRequestEnd && self->_timestampRequestEnd == other->_timestampRequestEnd) || (!self->_has.timestampRequestEnd && !other->_has.timestampRequestEnd)) + && + ((self->_has.timestampResponseStart && other->_has.timestampResponseStart && self->_timestampResponseStart == other->_timestampResponseStart) || (!self->_has.timestampResponseStart && !other->_has.timestampResponseStart)) + && + ((self->_has.timestampResponseEnd && other->_has.timestampResponseEnd && self->_timestampResponseEnd == other->_timestampResponseEnd) || (!self->_has.timestampResponseEnd && !other->_has.timestampResponseEnd)) + && + ((!self->_optionsQualityOfService && !other->_optionsQualityOfService) || [self->_optionsQualityOfService isEqual:other->_optionsQualityOfService]) + && + ((self->_has.optionsOutOfProcess && other->_has.optionsOutOfProcess && ((self->_optionsOutOfProcess && other->_optionsOutOfProcess) || (!self->_optionsOutOfProcess && !other->_optionsOutOfProcess))) || (!self->_has.optionsOutOfProcess && !other->_has.optionsOutOfProcess)) + && + ((self->_has.optionsOutOfProcessForceDiscretionary && other->_has.optionsOutOfProcessForceDiscretionary && ((self->_optionsOutOfProcessForceDiscretionary && other->_optionsOutOfProcessForceDiscretionary) || (!self->_optionsOutOfProcessForceDiscretionary && !other->_optionsOutOfProcessForceDiscretionary))) || (!self->_has.optionsOutOfProcessForceDiscretionary && !other->_has.optionsOutOfProcessForceDiscretionary)) + && + ((self->_has.optionsAllowExpensiveAccess && other->_has.optionsAllowExpensiveAccess && ((self->_optionsAllowExpensiveAccess && other->_optionsAllowExpensiveAccess) || (!self->_optionsAllowExpensiveAccess && !other->_optionsAllowExpensiveAccess))) || (!self->_has.optionsAllowExpensiveAccess && !other->_has.optionsAllowExpensiveAccess)) + && + ((self->_has.optionsAllowPowerNapScheduling && other->_has.optionsAllowPowerNapScheduling && ((self->_optionsAllowPowerNapScheduling && other->_optionsAllowPowerNapScheduling) || (!self->_optionsAllowPowerNapScheduling && !other->_optionsAllowPowerNapScheduling))) || (!self->_has.optionsAllowPowerNapScheduling && !other->_has.optionsAllowPowerNapScheduling)) + && + ((self->_has.optionsTimeoutIntervalForRequest && other->_has.optionsTimeoutIntervalForRequest && self->_optionsTimeoutIntervalForRequest == other->_optionsTimeoutIntervalForRequest) || (!self->_has.optionsTimeoutIntervalForRequest && !other->_has.optionsTimeoutIntervalForRequest)) + && + ((self->_has.optionsTimeoutIntervalForResource && other->_has.optionsTimeoutIntervalForResource && self->_optionsTimeoutIntervalForResource == other->_optionsTimeoutIntervalForResource) || (!self->_has.optionsTimeoutIntervalForResource && !other->_has.optionsTimeoutIntervalForResource)) + && + ((!self->_optionsSourceApplicationBundleIdentifier && !other->_optionsSourceApplicationBundleIdentifier) || [self->_optionsSourceApplicationBundleIdentifier isEqual:other->_optionsSourceApplicationBundleIdentifier]) + && + ((!self->_optionsSourceApplicationSecondaryIdentifier && !other->_optionsSourceApplicationSecondaryIdentifier) || [self->_optionsSourceApplicationSecondaryIdentifier isEqual:other->_optionsSourceApplicationSecondaryIdentifier]) + && + ((self->_has.optionsAppleIdContext && other->_has.optionsAppleIdContext && ((self->_optionsAppleIdContext && other->_optionsAppleIdContext) || (!self->_optionsAppleIdContext && !other->_optionsAppleIdContext))) || (!self->_has.optionsAppleIdContext && !other->_has.optionsAppleIdContext)) + && + ((self->_has.optionsTlsPinningRequired && other->_has.optionsTlsPinningRequired && ((self->_optionsTlsPinningRequired && other->_optionsTlsPinningRequired) || (!self->_optionsTlsPinningRequired && !other->_optionsTlsPinningRequired))) || (!self->_has.optionsTlsPinningRequired && !other->_has.optionsTlsPinningRequired)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.triggers ? PBHashInt((NSUInteger)self->_triggers) : 0) + ^ + (self->_has.reportFrequency ? PBHashInt((NSUInteger)self->_reportFrequency) : 0) + ^ + (self->_has.reportFrequencyBase ? PBHashInt((NSUInteger)self->_reportFrequencyBase) : 0) + ^ + [self->_networkTaskDescription hash] + ^ + [self->_networkHostname hash] + ^ + [self->_networkRemoteAddresssAndPort hash] + ^ + [self->_networkConnectionUuid hash] + ^ + (self->_has.networkConnectionReused ? PBHashInt((NSUInteger)self->_networkConnectionReused) : 0) + ^ + [self->_networkInterfaceIdentifier hash] + ^ + [self->_networkProtocolName hash] + ^ + (self->_has.networkRequestHeaderSize ? PBHashInt((NSUInteger)self->_networkRequestHeaderSize) : 0) + ^ + (self->_has.networkRequestBodyBytesSent ? PBHashInt((NSUInteger)self->_networkRequestBodyBytesSent) : 0) + ^ + (self->_has.networkResponseHeaderSize ? PBHashInt((NSUInteger)self->_networkResponseHeaderSize) : 0) + ^ + (self->_has.networkResponseBodyBytesReceived ? PBHashInt((NSUInteger)self->_networkResponseBodyBytesReceived) : 0) + ^ + (self->_has.networkPreviousAttemptCount ? PBHashInt((NSUInteger)self->_networkPreviousAttemptCount) : 0) + ^ + [self->_networkFatalError hash] + ^ + (self->_has.networkStatusCode ? PBHashInt((NSUInteger)self->_networkStatusCode) : 0) + ^ + [self->_networkRequestUri hash] + ^ + (self->_has.timestampC2Init ? PBHashInt((NSUInteger)self->_timestampC2Init) : 0) + ^ + (self->_has.timestampC2Start ? PBHashInt((NSUInteger)self->_timestampC2Start) : 0) + ^ + (self->_has.timestampC2Now ? PBHashInt((NSUInteger)self->_timestampC2Now) : 0) + ^ + (self->_has.timestampDnsStart ? PBHashInt((NSUInteger)self->_timestampDnsStart) : 0) + ^ + (self->_has.timestampDnsEnd ? PBHashInt((NSUInteger)self->_timestampDnsEnd) : 0) + ^ + (self->_has.timestampTcpStart ? PBHashInt((NSUInteger)self->_timestampTcpStart) : 0) + ^ + (self->_has.timestampTcpEnd ? PBHashInt((NSUInteger)self->_timestampTcpEnd) : 0) + ^ + (self->_has.timestampSslStart ? PBHashInt((NSUInteger)self->_timestampSslStart) : 0) + ^ + (self->_has.timestampRequestStart ? PBHashInt((NSUInteger)self->_timestampRequestStart) : 0) + ^ + (self->_has.timestampRequestEnd ? PBHashInt((NSUInteger)self->_timestampRequestEnd) : 0) + ^ + (self->_has.timestampResponseStart ? PBHashInt((NSUInteger)self->_timestampResponseStart) : 0) + ^ + (self->_has.timestampResponseEnd ? PBHashInt((NSUInteger)self->_timestampResponseEnd) : 0) + ^ + [self->_optionsQualityOfService hash] + ^ + (self->_has.optionsOutOfProcess ? PBHashInt((NSUInteger)self->_optionsOutOfProcess) : 0) + ^ + (self->_has.optionsOutOfProcessForceDiscretionary ? PBHashInt((NSUInteger)self->_optionsOutOfProcessForceDiscretionary) : 0) + ^ + (self->_has.optionsAllowExpensiveAccess ? PBHashInt((NSUInteger)self->_optionsAllowExpensiveAccess) : 0) + ^ + (self->_has.optionsAllowPowerNapScheduling ? PBHashInt((NSUInteger)self->_optionsAllowPowerNapScheduling) : 0) + ^ + (self->_has.optionsTimeoutIntervalForRequest ? PBHashInt((NSUInteger)self->_optionsTimeoutIntervalForRequest) : 0) + ^ + (self->_has.optionsTimeoutIntervalForResource ? PBHashInt((NSUInteger)self->_optionsTimeoutIntervalForResource) : 0) + ^ + [self->_optionsSourceApplicationBundleIdentifier hash] + ^ + [self->_optionsSourceApplicationSecondaryIdentifier hash] + ^ + (self->_has.optionsAppleIdContext ? PBHashInt((NSUInteger)self->_optionsAppleIdContext) : 0) + ^ + (self->_has.optionsTlsPinningRequired ? PBHashInt((NSUInteger)self->_optionsTlsPinningRequired) : 0) + ; +} + +- (void)mergeFrom:(SECC2MPNetworkEvent *)other +{ + if (other->_has.triggers) + { + self->_triggers = other->_triggers; + self->_has.triggers = YES; + } + if (other->_has.reportFrequency) + { + self->_reportFrequency = other->_reportFrequency; + self->_has.reportFrequency = YES; + } + if (other->_has.reportFrequencyBase) + { + self->_reportFrequencyBase = other->_reportFrequencyBase; + self->_has.reportFrequencyBase = YES; + } + if (other->_networkTaskDescription) + { + [self setNetworkTaskDescription:other->_networkTaskDescription]; + } + if (other->_networkHostname) + { + [self setNetworkHostname:other->_networkHostname]; + } + if (other->_networkRemoteAddresssAndPort) + { + [self setNetworkRemoteAddresssAndPort:other->_networkRemoteAddresssAndPort]; + } + if (other->_networkConnectionUuid) + { + [self setNetworkConnectionUuid:other->_networkConnectionUuid]; + } + if (other->_has.networkConnectionReused) + { + self->_networkConnectionReused = other->_networkConnectionReused; + self->_has.networkConnectionReused = YES; + } + if (other->_networkInterfaceIdentifier) + { + [self setNetworkInterfaceIdentifier:other->_networkInterfaceIdentifier]; + } + if (other->_networkProtocolName) + { + [self setNetworkProtocolName:other->_networkProtocolName]; + } + if (other->_has.networkRequestHeaderSize) + { + self->_networkRequestHeaderSize = other->_networkRequestHeaderSize; + self->_has.networkRequestHeaderSize = YES; + } + if (other->_has.networkRequestBodyBytesSent) + { + self->_networkRequestBodyBytesSent = other->_networkRequestBodyBytesSent; + self->_has.networkRequestBodyBytesSent = YES; + } + if (other->_has.networkResponseHeaderSize) + { + self->_networkResponseHeaderSize = other->_networkResponseHeaderSize; + self->_has.networkResponseHeaderSize = YES; + } + if (other->_has.networkResponseBodyBytesReceived) + { + self->_networkResponseBodyBytesReceived = other->_networkResponseBodyBytesReceived; + self->_has.networkResponseBodyBytesReceived = YES; + } + if (other->_has.networkPreviousAttemptCount) + { + self->_networkPreviousAttemptCount = other->_networkPreviousAttemptCount; + self->_has.networkPreviousAttemptCount = YES; + } + if (self->_networkFatalError && other->_networkFatalError) + { + [self->_networkFatalError mergeFrom:other->_networkFatalError]; + } + else if (!self->_networkFatalError && other->_networkFatalError) + { + [self setNetworkFatalError:other->_networkFatalError]; + } + if (other->_has.networkStatusCode) + { + self->_networkStatusCode = other->_networkStatusCode; + self->_has.networkStatusCode = YES; + } + if (other->_networkRequestUri) + { + [self setNetworkRequestUri:other->_networkRequestUri]; + } + if (other->_has.timestampC2Init) + { + self->_timestampC2Init = other->_timestampC2Init; + self->_has.timestampC2Init = YES; + } + if (other->_has.timestampC2Start) + { + self->_timestampC2Start = other->_timestampC2Start; + self->_has.timestampC2Start = YES; + } + if (other->_has.timestampC2Now) + { + self->_timestampC2Now = other->_timestampC2Now; + self->_has.timestampC2Now = YES; + } + if (other->_has.timestampDnsStart) + { + self->_timestampDnsStart = other->_timestampDnsStart; + self->_has.timestampDnsStart = YES; + } + if (other->_has.timestampDnsEnd) + { + self->_timestampDnsEnd = other->_timestampDnsEnd; + self->_has.timestampDnsEnd = YES; + } + if (other->_has.timestampTcpStart) + { + self->_timestampTcpStart = other->_timestampTcpStart; + self->_has.timestampTcpStart = YES; + } + if (other->_has.timestampTcpEnd) + { + self->_timestampTcpEnd = other->_timestampTcpEnd; + self->_has.timestampTcpEnd = YES; + } + if (other->_has.timestampSslStart) + { + self->_timestampSslStart = other->_timestampSslStart; + self->_has.timestampSslStart = YES; + } + if (other->_has.timestampRequestStart) + { + self->_timestampRequestStart = other->_timestampRequestStart; + self->_has.timestampRequestStart = YES; + } + if (other->_has.timestampRequestEnd) + { + self->_timestampRequestEnd = other->_timestampRequestEnd; + self->_has.timestampRequestEnd = YES; + } + if (other->_has.timestampResponseStart) + { + self->_timestampResponseStart = other->_timestampResponseStart; + self->_has.timestampResponseStart = YES; + } + if (other->_has.timestampResponseEnd) + { + self->_timestampResponseEnd = other->_timestampResponseEnd; + self->_has.timestampResponseEnd = YES; + } + if (other->_optionsQualityOfService) + { + [self setOptionsQualityOfService:other->_optionsQualityOfService]; + } + if (other->_has.optionsOutOfProcess) + { + self->_optionsOutOfProcess = other->_optionsOutOfProcess; + self->_has.optionsOutOfProcess = YES; + } + if (other->_has.optionsOutOfProcessForceDiscretionary) + { + self->_optionsOutOfProcessForceDiscretionary = other->_optionsOutOfProcessForceDiscretionary; + self->_has.optionsOutOfProcessForceDiscretionary = YES; + } + if (other->_has.optionsAllowExpensiveAccess) + { + self->_optionsAllowExpensiveAccess = other->_optionsAllowExpensiveAccess; + self->_has.optionsAllowExpensiveAccess = YES; + } + if (other->_has.optionsAllowPowerNapScheduling) + { + self->_optionsAllowPowerNapScheduling = other->_optionsAllowPowerNapScheduling; + self->_has.optionsAllowPowerNapScheduling = YES; + } + if (other->_has.optionsTimeoutIntervalForRequest) + { + self->_optionsTimeoutIntervalForRequest = other->_optionsTimeoutIntervalForRequest; + self->_has.optionsTimeoutIntervalForRequest = YES; + } + if (other->_has.optionsTimeoutIntervalForResource) + { + self->_optionsTimeoutIntervalForResource = other->_optionsTimeoutIntervalForResource; + self->_has.optionsTimeoutIntervalForResource = YES; + } + if (other->_optionsSourceApplicationBundleIdentifier) + { + [self setOptionsSourceApplicationBundleIdentifier:other->_optionsSourceApplicationBundleIdentifier]; + } + if (other->_optionsSourceApplicationSecondaryIdentifier) + { + [self setOptionsSourceApplicationSecondaryIdentifier:other->_optionsSourceApplicationSecondaryIdentifier]; + } + if (other->_has.optionsAppleIdContext) + { + self->_optionsAppleIdContext = other->_optionsAppleIdContext; + self->_has.optionsAppleIdContext = YES; + } + if (other->_has.optionsTlsPinningRequired) + { + self->_optionsTlsPinningRequired = other->_optionsTlsPinningRequired; + self->_has.optionsTlsPinningRequired = YES; + } +} + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPServerInfo.h b/keychain/analytics/C2Metric/SECC2MPServerInfo.h new file mode 100644 index 00000000..8b249c80 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPServerInfo.h @@ -0,0 +1,48 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import +#import + +#ifdef __cplusplus +#define SECC2MPSERVERINFO_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECC2MPSERVERINFO_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SECC2MPServerInfo : PBCodable +{ + NSString *_partition; + NSString *_serviceBuild; + NSString *_serviceInstance; + NSString *_serviceName; +} + + +@property (nonatomic, readonly) BOOL hasServiceName; +@property (nonatomic, retain) NSString *serviceName; + +@property (nonatomic, readonly) BOOL hasPartition; +@property (nonatomic, retain) NSString *partition; + +@property (nonatomic, readonly) BOOL hasServiceBuild; +@property (nonatomic, retain) NSString *serviceBuild; + +@property (nonatomic, readonly) BOOL hasServiceInstance; +@property (nonatomic, retain) NSString *serviceInstance; + +// Performs a shallow copy into other +- (void)copyTo:(SECC2MPServerInfo *)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:(SECC2MPServerInfo *)other; + +SECC2MPSERVERINFO_FUNCTION BOOL SECC2MPServerInfoReadFrom(__unsafe_unretained SECC2MPServerInfo *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/analytics/C2Metric/SECC2MPServerInfo.m b/keychain/analytics/C2Metric/SECC2MPServerInfo.m new file mode 100644 index 00000000..00052ed4 --- /dev/null +++ b/keychain/analytics/C2Metric/SECC2MPServerInfo.m @@ -0,0 +1,229 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from C2Metric.proto + +#import "SECC2MPServerInfo.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 SECC2MPServerInfo + +- (BOOL)hasServiceName +{ + return _serviceName != nil; +} +@synthesize serviceName = _serviceName; +- (BOOL)hasPartition +{ + return _partition != nil; +} +@synthesize partition = _partition; +- (BOOL)hasServiceBuild +{ + return _serviceBuild != nil; +} +@synthesize serviceBuild = _serviceBuild; +- (BOOL)hasServiceInstance +{ + return _serviceInstance != nil; +} +@synthesize serviceInstance = _serviceInstance; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_serviceName) + { + [dict setObject:self->_serviceName forKey:@"service_name"]; + } + if (self->_partition) + { + [dict setObject:self->_partition forKey:@"partition"]; + } + if (self->_serviceBuild) + { + [dict setObject:self->_serviceBuild forKey:@"service_build"]; + } + if (self->_serviceInstance) + { + [dict setObject:self->_serviceInstance forKey:@"service_instance"]; + } + return dict; +} + +BOOL SECC2MPServerInfoReadFrom(__unsafe_unretained SECC2MPServerInfo *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 102 /* serviceName */: + { + NSString *new_serviceName = PBReaderReadString(reader); + self->_serviceName = new_serviceName; + } + break; + case 103 /* partition */: + { + NSString *new_partition = PBReaderReadString(reader); + self->_partition = new_partition; + } + break; + case 104 /* serviceBuild */: + { + NSString *new_serviceBuild = PBReaderReadString(reader); + self->_serviceBuild = new_serviceBuild; + } + break; + case 105 /* serviceInstance */: + { + NSString *new_serviceInstance = PBReaderReadString(reader); + self->_serviceInstance = new_serviceInstance; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SECC2MPServerInfoReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* serviceName */ + { + if (self->_serviceName) + { + PBDataWriterWriteStringField(writer, self->_serviceName, 102); + } + } + /* partition */ + { + if (self->_partition) + { + PBDataWriterWriteStringField(writer, self->_partition, 103); + } + } + /* serviceBuild */ + { + if (self->_serviceBuild) + { + PBDataWriterWriteStringField(writer, self->_serviceBuild, 104); + } + } + /* serviceInstance */ + { + if (self->_serviceInstance) + { + PBDataWriterWriteStringField(writer, self->_serviceInstance, 105); + } + } +} + +- (void)copyTo:(SECC2MPServerInfo *)other +{ + if (_serviceName) + { + other.serviceName = _serviceName; + } + if (_partition) + { + other.partition = _partition; + } + if (_serviceBuild) + { + other.serviceBuild = _serviceBuild; + } + if (_serviceInstance) + { + other.serviceInstance = _serviceInstance; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SECC2MPServerInfo *copy = [[[self class] allocWithZone:zone] init]; + copy->_serviceName = [_serviceName copyWithZone:zone]; + copy->_partition = [_partition copyWithZone:zone]; + copy->_serviceBuild = [_serviceBuild copyWithZone:zone]; + copy->_serviceInstance = [_serviceInstance copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SECC2MPServerInfo *other = (SECC2MPServerInfo *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_serviceName && !other->_serviceName) || [self->_serviceName isEqual:other->_serviceName]) + && + ((!self->_partition && !other->_partition) || [self->_partition isEqual:other->_partition]) + && + ((!self->_serviceBuild && !other->_serviceBuild) || [self->_serviceBuild isEqual:other->_serviceBuild]) + && + ((!self->_serviceInstance && !other->_serviceInstance) || [self->_serviceInstance isEqual:other->_serviceInstance]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_serviceName hash] + ^ + [self->_partition hash] + ^ + [self->_serviceBuild hash] + ^ + [self->_serviceInstance hash] + ; +} + +- (void)mergeFrom:(SECC2MPServerInfo *)other +{ + if (other->_serviceName) + { + [self setServiceName:other->_serviceName]; + } + if (other->_partition) + { + [self setPartition:other->_partition]; + } + if (other->_serviceBuild) + { + [self setServiceBuild:other->_serviceBuild]; + } + if (other->_serviceInstance) + { + [self setServiceInstance:other->_serviceInstance]; + } +} + +@end + diff --git a/keychain/analytics/CKKSLaunchSequence.h b/keychain/analytics/CKKSLaunchSequence.h new file mode 100644 index 00000000..a658532c --- /dev/null +++ b/keychain/analytics/CKKSLaunchSequence.h @@ -0,0 +1,34 @@ +// +// CKKSLaunchSequence.h +// +// Takes a sequence of events and report their time relative from the starting point +// Duplicate events are counted. +// +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CKKSLaunchSequence : NSObject +@property (readonly) bool launched; +@property (assign) bool firstLaunch; + +- (instancetype)init NS_UNAVAILABLE; + +// name should be dns reverse notation, com.apple.label +- (instancetype)initWithRocketName:(NSString *)name; + +// value must be a valid JSON compatible type +- (void)addAttribute:(NSString *)key value:(id)value; +- (void)addEvent:(NSString *)eventname; + +- (void)launch; + +- (void)addDependantLaunch:(NSString *)name child:(CKKSLaunchSequence *)child; + +// For including in human readable diagnostics +- (NSArray *)eventsByTime; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/analytics/CKKSLaunchSequence.m b/keychain/analytics/CKKSLaunchSequence.m new file mode 100644 index 00000000..36468195 --- /dev/null +++ b/keychain/analytics/CKKSLaunchSequence.m @@ -0,0 +1,227 @@ +// +// CKKSLaunchSequence.m +// + +#import "keychain/analytics/CKKSLaunchSequence.h" +#import +#import + +enum { CKKSMaxLaunchEvents = 100 }; + +@interface CKKSLaunchEvent : NSObject +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithName:(NSString *)name; +@property (strong) NSString *name; // "human friendly" name, included in metrics +@property (strong) NSDate *date; // first, or last time this event happend (depends on usecase) +@property (assign) unsigned counter; //times this event happened, zero indexed +@end + + +@interface CKKSLaunchSequence () { + bool _firstLaunch; +} +@property (readwrite) bool launched; +@property (strong) NSString* name; +@property (strong) NSMutableDictionary* events; // key is uniqifier, event.name is "human friendly" +@property (strong) NSMutableDictionary* attributes; + +@property (strong) NSBlockOperation *launchOperation; +@property (strong) NSMutableDictionary *dependantLaunches; +@end + + +@implementation CKKSLaunchEvent + +- (instancetype)initWithName:(NSString *)name { + if ((self = [super init]) != NULL) { + _name = name; + _date = [NSDate date]; + _counter = 1; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone +{ + CKKSLaunchEvent *copy = [[[self class] alloc] init]; + + copy.name = [self.name copyWithZone:zone]; + copy.date = [self.date copyWithZone:zone]; + copy.counter = self.counter; + + return copy; +} + +@end + +@implementation CKKSLaunchSequence + +- (instancetype)initWithRocketName:(NSString *)name { + if ((self = [super init]) != NULL) { + _name = name; + _events = [NSMutableDictionary dictionary]; + _events[@"started"] = [[CKKSLaunchEvent alloc] initWithName:@"started"]; + _launchOperation = [[NSBlockOperation alloc] init]; + _dependantLaunches = [NSMutableDictionary dictionary]; + } + return self; +} + +- (bool)firstLaunch { + @synchronized(self) { + return _firstLaunch; + } +} + +- (void)setFirstLaunch:(bool)firstLaunch +{ + @synchronized (self) { + if (self.launched) { + return; + } + _firstLaunch = firstLaunch; + } +} + +- (void)addDependantLaunch:(NSString *)name child:(CKKSLaunchSequence *)child +{ + @synchronized (self) { + if (self.launched) { + return; + } + if (self.dependantLaunches[name]) { + return; + } + self.dependantLaunches[name] = child; + [self.launchOperation addDependency:child.launchOperation]; + } +} + + +- (void)addAttribute:(NSString *)key value:(id)value { + if (![key isKindOfClass:[NSString class]]) { + return; + } + @synchronized(self) { + if (self.launched) { + return; + } + if (self.attributes == nil) { + self.attributes = [NSMutableDictionary dictionary]; + } + self.attributes[key] = value; + } +} + + +- (void)addEvent:(NSString *)eventname { + if (![eventname isKindOfClass:[NSString class]]) { + return; + } + @synchronized(self) { + if (self.launched) { + return; + } + if (self.events.count > CKKSMaxLaunchEvents) { + return; + } + CKKSLaunchEvent *event = self.events[eventname]; + if (event) { + event.counter++; + } else { + event = [[CKKSLaunchEvent alloc] initWithName:eventname]; + } + self.events[eventname] = event; + } +} + +- (void)reportMetric { + + NSMutableDictionary *metric = [NSMutableDictionary dictionary]; + os_assert(self.launched); + + @synchronized(self) { + /* don't need to lock children, at this point, they have launched and will no longer mutate */ + [self.dependantLaunches enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull childKey, CKKSLaunchSequence *_Nonnull child, BOOL * _Nonnull stop) { + os_assert(child.launched); + [child.events enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, CKKSLaunchEvent * _Nonnull obj, BOOL * _Nonnull stop) { + CKKSLaunchEvent *childEvent = [obj copy]; + childEvent.name = [NSString stringWithFormat:@"c:%@-%@", childKey, childEvent.name]; + self.events[[NSString stringWithFormat:@"c:%@-%@", childKey, key]] = childEvent; + }]; + self.attributes[[NSString stringWithFormat:@"c:%@", childKey]] = child.attributes; + }]; + + CKKSLaunchEvent *event = [[CKKSLaunchEvent alloc] initWithName:(self.firstLaunch ? @"first-launch" : @"re-launch")]; + self.events[event.name] = event; + + metric[@"events"] = [self eventsRelativeTime]; + if (self.attributes.count) { + metric[@"attributes"] = self.attributes; + } + + } + [SecCoreAnalytics sendEvent:self.name event:metric]; +} + +- (void)launch { + @synchronized(self) { + if (self.launched) { + return; + } + self.launched = true; + } + + __weak typeof(self) weakSelf = self; + + [self.launchOperation addExecutionBlock:^{ + [weakSelf reportMetric]; + }]; + + [[NSOperationQueue mainQueue] addOperation:self.launchOperation]; +} + +- (NSArray *) eventsRelativeTime +{ + NSMutableArray* array = [NSMutableArray array]; + [self.events enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull __unused name, CKKSLaunchEvent * _Nonnull event, BOOL * _Nonnull __unused stop) { + [array addObject:event]; + }]; + [array sortUsingComparator:^NSComparisonResult(CKKSLaunchEvent * _Nonnull obj1, CKKSLaunchEvent *_Nonnull obj2) { + return [obj1.date compare:obj2.date]; + }]; + NSDate *firstEvent = array[0].date; + NSMutableArray *result = [NSMutableArray array]; + [array enumerateObjectsUsingBlock:^(CKKSLaunchEvent * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary *event = [NSMutableDictionary dictionary]; + event[@"name"] = obj.name; + event[@"time"] = @([obj.date timeIntervalSinceDate:firstEvent]); + if (obj.counter) { + event[@"counter"] = @(obj.counter); + } + [result addObject:event]; + }]; + return result; +} + +- (NSArray *) eventsByTime { + @synchronized (self) { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss.SSSZ"; + + NSMutableArray* array = [NSMutableArray array]; + [self.events enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull name, CKKSLaunchEvent * _Nonnull event, BOOL * _Nonnull stop) { + NSString *str = [NSString stringWithFormat:@"%@ - %@:%u", [dateFormatter stringFromDate:event.date], event.name, event.counter]; + [array addObject:str]; + }]; + + [array sortUsingSelector:@selector(compare:)]; + + for (NSString *attribute in self.attributes) { + [array addObject:[NSString stringWithFormat:@"attr: %@: %@", attribute, [self.attributes[attribute] description]]]; + } + return array; + } +} + +@end diff --git a/keychain/analytics/CKKSPowerCollection.h b/keychain/analytics/CKKSPowerCollection.h index 0df6e511..b41f7d14 100644 --- a/keychain/analytics/CKKSPowerCollection.h +++ b/keychain/analytics/CKKSPowerCollection.h @@ -35,6 +35,7 @@ extern CKKSPowerEvent* const kCKKSPowerEventIncommingQueue; extern CKKSPowerEvent* const kCKKSPowerEventTLKShareProcessing; extern CKKSPowerEvent* const kCKKSPowerEventScanLocalItems; extern CKKSPowerEvent* const kCKKSPowerEventFetchAllChanges; +extern CKKSPowerEvent* const kCKKSPowerEventReencryptOutgoing; @protocol OTPowerEventType @end diff --git a/keychain/analytics/CKKSPowerCollection.m b/keychain/analytics/CKKSPowerCollection.m index 273a677a..e1628d63 100644 --- a/keychain/analytics/CKKSPowerCollection.m +++ b/keychain/analytics/CKKSPowerCollection.m @@ -32,6 +32,7 @@ CKKSPowerEvent* const kCKKSPowerEventIncommingQueue = (CKKSPowerEvent*)@"process CKKSPowerEvent* const kCKKSPowerEventTLKShareProcessing = (CKKSPowerEvent*)@"TLKShareProcessing"; CKKSPowerEvent* const kCKKSPowerEventScanLocalItems = (CKKSPowerEvent*)@"scanLocalItems"; CKKSPowerEvent* const kCKKSPowerEventFetchAllChanges = (CKKSPowerEvent*)@"fetchAllChanges"; +CKKSPowerEvent* const kCKKSPowerEventReencryptOutgoing = (CKKSPowerEvent *)@"reencryptOutgoing"; OTPowerEvent* const kOTPowerEventRestore = (OTPowerEvent *)@"restoreBottledPeer"; OTPowerEvent* const kOTPowerEventEnroll = (OTPowerEvent *)@"enrollBottledPeer"; diff --git a/keychain/analytics/SecC2DeviceInfo.h b/keychain/analytics/SecC2DeviceInfo.h new file mode 100644 index 00000000..7cb71de0 --- /dev/null +++ b/keychain/analytics/SecC2DeviceInfo.h @@ -0,0 +1,35 @@ +/* + * 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 + +@interface SecC2DeviceInfo : NSObject ++ (BOOL)isAppleInternal; ++ (NSString*)buildVersion; ++ (NSString*)productName; ++ (NSString*)productType; ++ (NSString*)productVersion; ++ (NSString*)processName; ++ (NSString*)processVersion; ++ (NSString*)processUUID; +@end diff --git a/keychain/analytics/SecC2DeviceInfo.m b/keychain/analytics/SecC2DeviceInfo.m new file mode 100644 index 00000000..87f05a19 --- /dev/null +++ b/keychain/analytics/SecC2DeviceInfo.m @@ -0,0 +1,205 @@ +/* + * 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 "SecC2DeviceInfo.h" + +#import +#import +#import +#if TARGET_OS_IPHONE +#import +#else +#import +#endif + +static NSString* C2MetricBuildVersion(void); +static NSString* C2MetricProductName(void); +static NSString* C2MetricProductType(void); +static NSString* C2MetricProductVersion(void); +static NSString* C2MetricProcessName(void); +static NSString* C2MetricProcessVersion(void); +static NSString* C2MetricProcessUUID(void); + +@implementation SecC2DeviceInfo + ++ (BOOL) isAppleInternal { + return os_variant_has_internal_content("com.apple.security.analytics"); +} + ++ (NSString*) buildVersion { + return C2MetricBuildVersion(); +} + ++ (NSString*) productName { + return C2MetricProductName(); +} + ++ (NSString*) productType { + return C2MetricProductType(); +} + ++ (NSString*) productVersion { + return C2MetricProductVersion(); +} + ++ (NSString*) processName { + return C2MetricProcessName(); +} + ++ (NSString*) processVersion { + return C2MetricProcessVersion(); +} + ++ (NSString*) processUUID { + return C2MetricProcessUUID(); +} + +@end + +/* Stolen without remorse from CloudKit. */ + +#pragma mark - NSBundleInfoDictionary Constants + +static NSDictionary *processInfoDict() { + static NSDictionary *processInfoDict = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSBundle *processBundle = [NSBundle mainBundle]; + processInfoDict = [processBundle infoDictionary]; + }); + return processInfoDict; +} + +static NSString* C2MetricProcessName() { + return processInfoDict()[(NSString *)kCFBundleIdentifierKey]; +} + +static NSString* C2MetricProcessVersion() { + return processInfoDict()[(NSString *)_kCFBundleShortVersionStringKey]; +} + +static NSString* C2MetricProcessUUID() { + static NSString* processUUIDString; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + processUUIDString = [[NSUUID UUID] UUIDString]; + }); + return processUUIDString; +} + +#pragma mark - MobileGestalt Constants + +#if TARGET_OS_IPHONE + +static NSMutableDictionary* _CKCachedGestaltValues = nil; + +static NSArray* _CKCachedLockdownKeys() { + return @[(NSString *)kMGQUniqueDeviceID, + (NSString *)kMGQBuildVersion, + (NSString *)kMGQProductName, + (NSString *)kMGQProductType, + (NSString *)kMGQProductVersion]; +} + +static NSDictionary* _CKGetCachedGestaltValues() { + static dispatch_once_t pred; + dispatch_once(&pred, ^{ + _CKCachedGestaltValues = [[NSMutableDictionary alloc] initWithCapacity:0]; + + for (NSString *key in _CKCachedLockdownKeys()) { + NSString *value = CFBridgingRelease(MGCopyAnswer((__bridge CFStringRef)key, NULL)); + if (value) { + _CKCachedGestaltValues[key] = value; + } else { + os_log(OS_LOG_DEFAULT, "Error getting %@ from MobileGestalt", key); + } + } + }); + return _CKCachedGestaltValues; +} + +static NSString* _CKGetCachedGestaltValue(NSString *key) { + return _CKGetCachedGestaltValues()[key]; +} + +static NSString* C2MetricBuildVersion() { + return _CKGetCachedGestaltValue((NSString *)kMGQBuildVersion); +} + +static NSString* C2MetricProductName() { + return _CKGetCachedGestaltValue((NSString *)kMGQProductName); +} + +static NSString* C2MetricProductType() { + return _CKGetCachedGestaltValue((NSString *)kMGQProductType); +} + +static NSString* C2MetricProductVersion() { + return _CKGetCachedGestaltValue((NSString *)kMGQProductVersion); +} + +#else + +static CFStringRef CKCopySysctl(int mib[2]) { + char sysctlString[128]; + size_t len = sizeof(sysctlString); + + // add the system product + if (sysctl(mib, 2, sysctlString, &len, 0, 0) >= 0) { + return CFStringCreateWithCString(kCFAllocatorDefault, sysctlString, kCFStringEncodingUTF8); + } + + return NULL; +} + +static NSDictionary* systemVersionDict() { + static NSDictionary *sysVers = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sysVers = (__bridge NSDictionary *)_CFCopySystemVersionDictionary(); + }); + return sysVers; +} + +static NSString* C2MetricBuildVersion() { + return systemVersionDict()[(NSString *)_kCFSystemVersionBuildVersionKey]; +} + +static NSString* C2MetricProductName() { + return systemVersionDict()[(NSString *)_kCFSystemVersionProductNameKey]; +} + +static NSString* C2MetricProductType() { + static dispatch_once_t onceToken; + static NSString *productType = nil; + dispatch_once(&onceToken, ^{ + productType = (__bridge NSString *)CKCopySysctl((int[2]) { CTL_HW, HW_MODEL }); + }); + return productType; +} + +static NSString* C2MetricProductVersion() { + return systemVersionDict()[(NSString *)_kCFSystemVersionProductVersionKey]; +} + +#endif diff --git a/keychain/analytics/SecEventMetric.h b/keychain/analytics/SecEventMetric.h new file mode 100644 index 00000000..308d1b75 --- /dev/null +++ b/keychain/analytics/SecEventMetric.h @@ -0,0 +1,61 @@ +/* + * 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 __OBJC2__ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol SecMetricValue +@end + +@interface SecEventMetric : NSObject +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithEventName:(NSString *)name; + +/* Set metric attributes */ +- (void)setObject:(nullable __kindof id)object forKeyedSubscript:(NSString *)key; +- (void)setMetricValue:(nullable __kindof id)metric forKey:(NSString *)key; + +@property (readonly) NSString *eventName; + +@end + +@interface NSString (SecMetricValue) +@end + +@interface NSNumber (SecMetricValue) +@end + +@interface NSDate (SecMetricValue) +@end + +@interface NSError (SecMetricValue) +@end + + + +NS_ASSUME_NONNULL_END + +#endif /* __OBJC2__ */ diff --git a/keychain/analytics/SecEventMetric.m b/keychain/analytics/SecEventMetric.m new file mode 100644 index 00000000..f40e458d --- /dev/null +++ b/keychain/analytics/SecEventMetric.m @@ -0,0 +1,169 @@ +/* + * 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 "keychain/analytics/SecEventMetric.h" +#import "keychain/analytics/SecC2DeviceInfo.h" +#import "keychain/analytics/C2Metric/SECC2MPMetric.h" +#import "keychain/analytics/C2Metric/SECC2MPGenericEvent.h" +#import "keychain/analytics/C2Metric/SECC2MPGenericEventMetric.h" +#import "keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.h" +#import "keychain/analytics/C2Metric/SECC2MPError.h" + +#import + +@interface SecEventMetric () +@property NSString *eventName; +@property NSMutableDictionary *attributes; +@end + +@implementation SecEventMetric + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)initWithEventName:(NSString *)name +{ + if ((self = [super init]) == NULL) { + return self; + } + self.eventName = name; + self.attributes = [NSMutableDictionary dictionary]; + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)coder { + self = [super init]; + if (self) { + NSMutableSet *attributeClasses = [[[self class] supportedAttributeClasses] mutableCopy]; + [attributeClasses addObject:[NSDictionary class]]; + + _eventName = [coder decodeObjectOfClass:[NSString class] forKey:@"eventName"]; + _attributes = [coder decodeObjectOfClasses:attributeClasses forKey:@"attributes"]; + + if (!_eventName || !_attributes) { + return NULL; + } + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.eventName forKey:@"eventName"]; + [coder encodeObject:self.attributes forKey:@"attributes"]; +} + ++ (NSSet *)supportedAttributeClasses { + static NSSet *supported = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSArray *clss = @[ + [NSString class], + [NSNumber class], + [NSDate class], + [NSError class], + ]; + supported = [NSSet setWithArray:clss]; + }); + return supported; +} + +- (void)setObject:(nullable id)object forKeyedSubscript:(NSString *)key { + bool found = false; + if (key == NULL) { + return; + } + if (object) { + for (Class cls in [[self class] supportedAttributeClasses]) { + if ([object isKindOfClass:cls]) { + found = true; + break; + } + } + if (!found) { + os_log(OS_LOG_DEFAULT, "genericMetric %{public}@ with unhandled metric type: %{public}@", key, NSStringFromClass([object class])); + return; + } + } + @synchronized(self) { + self.attributes[key] = object; + } +} +- (void)setMetricValue:(nullable id)metric forKey:(NSString *)key { + self[key] = metric; +} + +- (uint64_t)convertTimeIntervalToServerTime:(NSTimeInterval)timeInterval +{ + return (uint64_t)((timeInterval + NSTimeIntervalSince1970) * 1000.); +} + +- (SECC2MPGenericEvent *)genericEvent { + SECC2MPGenericEvent* genericEvent = [[SECC2MPGenericEvent alloc] init]; + + genericEvent.name = self.eventName; + genericEvent.type = SECC2MPGenericEvent_Type_cloudkit_client; + + genericEvent.timestampStart = 0; + genericEvent.timestampEnd = 0; + [self.attributes enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { + SECC2MPGenericEventMetric* metric = [[SECC2MPGenericEventMetric alloc] init]; + metric.key = key; + + metric.value = [[SECC2MPGenericEventMetricValue alloc] init]; + if ([obj isKindOfClass:[NSError class]]) { + metric.value.errorValue = [self generateError:obj]; + } else if ([obj isKindOfClass:[NSDate class]]) { + metric.value.dateValue = [self convertTimeIntervalToServerTime:[obj timeIntervalSinceReferenceDate]]; + } else if ([obj isKindOfClass:[NSNumber class]]) { + metric.value.doubleValue = [obj doubleValue]; + } else if ([obj isKindOfClass:[NSString class]]) { + metric.value.stringValue = obj; + } else { + // should never happen since setObject:forKeyedSubscript: validates the input and rejects invalid input + return; + } + if (metric.value) { + [genericEvent addMetric:metric]; + } + }]; + return genericEvent; +} + +- (SECC2MPError*) generateError:(NSError*)error +{ + SECC2MPError* generatedError = [[SECC2MPError alloc] init]; + generatedError.errorDomain = error.domain; + generatedError.errorCode = error.code; + if ([SecC2DeviceInfo isAppleInternal]) { + generatedError.errorDescription = error.userInfo[NSLocalizedDescriptionKey]; + } + NSError* underlyingError = error.userInfo[NSUnderlyingErrorKey]; + if (underlyingError) { + generatedError.underlyingError = [self generateError:underlyingError]; + } + return generatedError; +} + +@end diff --git a/keychain/analytics/SecEventMetric_private.h b/keychain/analytics/SecEventMetric_private.h new file mode 100644 index 00000000..e11319da --- /dev/null +++ b/keychain/analytics/SecEventMetric_private.h @@ -0,0 +1,38 @@ +/* + * 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 __OBJC2__ + +#import + +@class SECC2MPGenericEvent; + +NS_ASSUME_NONNULL_BEGIN + +@interface SecEventMetric (protobuf) +- (SECC2MPGenericEvent *)genericEvent; +@end + +NS_ASSUME_NONNULL_END + +#endif /* __OBJC2__ */ diff --git a/keychain/analytics/SecMetrics.h b/keychain/analytics/SecMetrics.h new file mode 100644 index 00000000..eae8d2a3 --- /dev/null +++ b/keychain/analytics/SecMetrics.h @@ -0,0 +1,39 @@ +/* + * 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 __OBJC2__ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class SecEventMetric; + +@interface SecMetrics : NSObject ++ (SecMetrics *)managerObject; +- (void)submitEvent:(SecEventMetric *)event; +@end + +NS_ASSUME_NONNULL_END + +#endif /* __OBJC2__ */ diff --git a/keychain/analytics/SecMetrics.m b/keychain/analytics/SecMetrics.m new file mode 100644 index 00000000..5aa7ef4c --- /dev/null +++ b/keychain/analytics/SecMetrics.m @@ -0,0 +1,288 @@ +/* + * 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 +#import +#import +#import +#import +#import + +#import "keychain/analytics/SecMetrics.h" +#import "keychain/analytics/SecEventMetric.h" +#import "keychain/analytics/SecEventMetric_private.h" +#import "keychain/analytics/SecC2DeviceInfo.h" + +#import "keychain/analytics/C2Metric/SECC2MPMetric.h" +#import "keychain/analytics/C2Metric/SECC2MPGenericEvent.h" +#import "keychain/analytics/C2Metric/SECC2MPGenericEventMetric.h" +#import "keychain/analytics/C2Metric/SECC2MPGenericEventMetricValue.h" +#import "keychain/analytics/C2Metric/SECC2MPDeviceInfo.h" +#import + + + +@interface SecMetrics () +@property (strong) NSMutableDictionary *taskMap; +@property (strong) NSURLSession *URLSession; +@property (strong) os_transaction_t transaction; +@property (assign) long lostEvents; +@end + + +static NSString *securtitydPushTopic = @"com.apple.private.alloy.keychain.metrics"; + +@implementation SecMetrics + ++ (NSURL *)c2MetricsEndpoint { + ACAccountStore *store = [[ACAccountStore alloc] init]; + ACAccount* primaryAccount = [store aa_primaryAppleAccount]; + if(!primaryAccount) { + return nil; + } + NSString *urlString = [primaryAccount propertiesForDataclass:ACAccountDataclassCKMetricsService][@"url"]; + if (urlString == NULL) { + return nil; + } + + NSURL *url = [[[NSURL alloc] initWithString:urlString] URLByAppendingPathComponent:@"c2"]; + + if (url) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + os_log(OS_LOG_DEFAULT, "metrics URL is: %@", url); + }); + } + + return url; +} + ++ (SecMetrics *)managerObject { + static SecMetrics *manager; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [[SecMetrics alloc] init]; + }); + return manager; +} + +- (instancetype)init +{ + if ((self = [super init]) == NULL) { + return self; + } + + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; + + self.URLSession = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:NULL]; + self.taskMap = [NSMutableDictionary dictionary]; + return self; +} + +- (void)submitEvent:(SecEventMetric *)metric +{ + [self sendEvent:metric pushTopic:securtitydPushTopic]; +} + + +- (void)sendEvent:(SecEventMetric *)event pushTopic:(NSString *)pushTopic +{ + bool tooMany = false; + + @synchronized(self) { + if ([self.taskMap count] > 5) { + self.lostEvents++; + tooMany = true; + } + } + if (tooMany) { + os_log(OS_LOG_DEFAULT, "metrics %@ dropped on floor since too many are pending", event.eventName); + return; + } + + SECC2MPGenericEvent *genericEvent = [event genericEvent]; + if (genericEvent == NULL) { + return; + } + + NSMutableURLRequest *request = [self requestForGenericEvent:genericEvent]; + if (request == NULL) { + return; + } + + NSURLSessionDataTask *task = [self.URLSession dataTaskWithRequest:request]; + if (pushTopic) { +#if !TARGET_OS_BRIDGE + task._APSRelayTopic = pushTopic; +#endif + } + + @synchronized(self) { + if ([self.taskMap count] == 0) { + self.transaction = os_transaction_create("com.apple.security.c2metric.upload"); + } + self.taskMap[@(task.taskIdentifier)] = event; + } + + [task resume]; +} + +- (SecEventMetric *)getEvent:(NSURLSessionTask *)task +{ + @synchronized(self) { + return self.taskMap[@(task.taskIdentifier)]; + } +} + +//MARK: - URLSession Callbacks + +- (void) URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task + didCompleteWithError:(nullable NSError *)error +{ + SecEventMetric *event = [self getEvent:task]; + + os_log(OS_LOG_DEFAULT, "metrics %@ transfer %@ completed with: %@", + event.eventName, task.originalRequest.URL, error ? [error description] : @"success"); + + @synchronized(self) { + [self.taskMap removeObjectForKey:@(task.taskIdentifier)]; + if (self.lostEvents || error) { + NSMutableDictionary *event = [NSMutableDictionary dictionary]; + + if (self.lostEvents) { + event[@"counter"] = @(self.lostEvents); + } + if (error) { + event[@"error_code"] = @(error.code); + event[@"error_domain"] = error.domain; + } + [SecCoreAnalytics sendEvent:@"com.apple.security.push.channel.dropped" event:event]; + self.lostEvents = 0; + } + + if (self.taskMap.count == 0) { + self.transaction = NULL; + } + } +} + +//MARK: - FOO + + +- (NSMutableURLRequest*)requestForGenericEvent:(SECC2MPGenericEvent*)genericEvent +{ + NSURL* metricURL = [[self class] c2MetricsEndpoint]; + if (!metricURL) { + return nil; + } + + NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:metricURL]; + if (!request) { + return nil; + } + + SECC2MPMetric* metrics = [[SECC2MPMetric alloc] init]; + if (!metrics) { + return nil; + } + metrics.deviceInfo = [self generateDeviceInfo]; + metrics.reportFrequency = 0; + metrics.reportFrequencyBase = 0; + + metrics.metricType = SECC2MPMetric_Type_generic_event_type; + metrics.genericEvent = genericEvent; + + PBDataWriter* protobufWriter = [[PBDataWriter alloc] init]; + if (!protobufWriter) { + return nil; + } + [metrics writeTo:protobufWriter]; + NSData* metricData = [protobufWriter immutableData]; + if (!metricData) { + return nil; + } + NSData* compressedData = [self gzipEncode:metricData]; + if (!compressedData) { + return nil; + } + [request setHTTPMethod:@"POST"]; + [request setHTTPBody:compressedData]; + [request setValue:@"application/protobuf" forHTTPHeaderField:@"Content-Type"]; + [request setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; + + return request; +} + +#define CHUNK 1024 + +- (NSData*) gzipEncode:(NSData*)bodyData { + unsigned have; + unsigned char outBytes[CHUNK] = {0}; + NSMutableData *compressedData = [NSMutableData data]; + + /* allocate deflate state */ + z_stream _zlibStream; + _zlibStream.zalloc = Z_NULL; + _zlibStream.zfree = Z_NULL; + _zlibStream.opaque = Z_NULL; + + // generate gzip header/trailer, use defaults for all other values + int ret = deflateInit2(&_zlibStream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY); + if (ret != Z_OK) { + return NULL; + } + + NS_VALID_UNTIL_END_OF_SCOPE NSData *arcSafeBodyData = bodyData; + _zlibStream.next_in = (Bytef *)[arcSafeBodyData bytes]; + _zlibStream.avail_in = (unsigned int)[arcSafeBodyData length]; + do { + _zlibStream.avail_out = CHUNK; + _zlibStream.next_out = outBytes; + ret = deflate(&_zlibStream, Z_FINISH); + assert(ret != Z_STREAM_ERROR); + have = CHUNK - _zlibStream.avail_out; + [compressedData appendBytes:outBytes length:have]; + } while (_zlibStream.avail_out == 0); + assert(_zlibStream.avail_in == 0); + deflateEnd(&_zlibStream); + + return compressedData; +} + + +- (SECC2MPDeviceInfo*) generateDeviceInfo { + SECC2MPDeviceInfo* deviceInfo = [[SECC2MPDeviceInfo alloc] init]; + deviceInfo.productName = [SecC2DeviceInfo productName]; + deviceInfo.productType = [SecC2DeviceInfo productType]; + deviceInfo.productVersion = [SecC2DeviceInfo productVersion]; + deviceInfo.productBuild = [SecC2DeviceInfo buildVersion]; + deviceInfo.processName = [SecC2DeviceInfo processName]; + deviceInfo.processVersion = [SecC2DeviceInfo processVersion]; + deviceInfo.processUuid = [SecC2DeviceInfo processUUID]; + return deviceInfo; +} + +@end diff --git a/keychain/ot/SFPublicKey+SPKI.h b/keychain/analytics/TestResourceUsage.h similarity index 81% rename from keychain/ot/SFPublicKey+SPKI.h rename to keychain/analytics/TestResourceUsage.h index 4d8218f3..dd00fecd 100644 --- a/keychain/ot/SFPublicKey+SPKI.h +++ b/keychain/analytics/TestResourceUsage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2018 Apple Inc. All Rights Reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -21,18 +21,16 @@ * @APPLE_LICENSE_HEADER_END@ */ -#if OCTAGON -#import +#import NS_ASSUME_NONNULL_BEGIN -@interface SFPublicKey (OTSubjectPublicKeyInfo) +@interface TestResourceUsage : NSObject -- (NSData *)asSPKI; -+ (instancetype)fromSPKI:(NSData *)spki; +- (instancetype)init NS_UNAVAILABLE; ++ (void)monitorTestResourceUsage; @end NS_ASSUME_NONNULL_END -#endif diff --git a/keychain/analytics/TestResourceUsage.m b/keychain/analytics/TestResourceUsage.m new file mode 100644 index 00000000..eb4cea5b --- /dev/null +++ b/keychain/analytics/TestResourceUsage.m @@ -0,0 +1,109 @@ +/* + * 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 "TestResourceUsage.h" +#import +#import +#import +#import +#import + +@interface TestResourceUsage () +@property (assign) rusage_info_current startResource; +@property (assign) uint64_t startMachTime; +@property (assign) uint64_t stopMachTime; +@end + + +@implementation TestResourceUsage + ++ (TestResourceUsage *)sharedManager +{ + static TestResourceUsage *manager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + manager = [TestResourceUsage new]; + }); + return manager; +} + ++ (void)monitorTestResourceUsage +{ + static dispatch_once_t onceToken; + TestResourceUsage *manager = [TestResourceUsage sharedManager]; + dispatch_once(&onceToken, ^{ + [[XCTestObservationCenter sharedTestObservationCenter] addTestObserver:manager]; + }); +} + +- (void)testCaseWillStart:(XCTestCase *)testCase +{ + proc_pid_rusage(getpid(), RUSAGE_INFO_CURRENT, (rusage_info_t *)&_startResource); + _startMachTime = mach_absolute_time(); +} + +- (void)testCaseDidFinish:(XCTestCase *)testCase +{ + _stopMachTime = mach_absolute_time(); + + rusage_info_current endResource; + proc_pid_rusage(getpid(), RUSAGE_INFO_CURRENT, (rusage_info_t *)&endResource); + + uint64_t startUserTime = [self nsecondsFromMachTime:self.startResource.ri_user_time]; + uint64_t endUserTime = [self nsecondsFromMachTime:endResource.ri_user_time]; + uint64_t startSysrTime = [self nsecondsFromMachTime:self.startResource.ri_system_time]; + uint64_t endSysTime = [self nsecondsFromMachTime:endResource.ri_system_time]; + + uint64_t diskUsage = endResource.ri_logical_writes - self.startResource.ri_logical_writes; + + [self BATSUnitTestToken:@"DiskUsage" value:@(diskUsage) testcase:testCase]; + [self BATSUnitTestToken:@"CPUUserTime" value:@(endUserTime - startUserTime) testcase:testCase]; + [self BATSUnitTestToken:@"CPUSysTime" value:@(endSysTime - startSysrTime) testcase:testCase]; + [self BATSUnitTestToken:@"WallTime" value:@(_stopMachTime - _startMachTime) testcase:testCase]; +} + +- (void)BATSUnitTestToken:(NSString *)name value:(id)value testcase:(XCTestCase *)testCase +{ + printf("%s", [[NSString stringWithFormat:@"[RESULT_KEY] TestResourceUsage:%s:%@\n[RESULT_VALUE] %@\n", + object_getClassName([testCase class]), name, value] UTF8String]); +} + +- (uint64_t)nsecondsFromMachTime:(uint64_t)machTime +{ + static dispatch_once_t once; + static uint64_t ratio; + dispatch_once(&once, ^{ + mach_timebase_info_data_t tbi; + if (os_assumes_zero(mach_timebase_info(&tbi)) == KERN_SUCCESS) { + ratio = tbi.numer / tbi.denom; + } else { + ratio = 1; + } + }); + + return (machTime * ratio); +} + + + +@end diff --git a/keychain/analytics/Tests/CKKSLaunchSequenceTests.m b/keychain/analytics/Tests/CKKSLaunchSequenceTests.m new file mode 100644 index 00000000..eed2a258 --- /dev/null +++ b/keychain/analytics/Tests/CKKSLaunchSequenceTests.m @@ -0,0 +1,59 @@ +// +// CKKSLaunchSequenceTests.m +// + +#import +#import +#import "keychain/analytics/CKKSLaunchSequence.h" +#import + + +@interface CKKSLaunchSequenceTests : XCTestCase +@property (strong) XCTestExpectation *launchExpection; +@end + +@implementation CKKSLaunchSequenceTests + +- (void)mockSendEvent:(NSDictionary *)name event:(NSDictionary *)event { + NSLog(@"CAEvent: %@", event); + [self.launchExpection fulfill]; +} + +- (void)testLaunch { + + id credentialStoreMock = OCMClassMock([SecCoreAnalytics class]); + OCMStub([credentialStoreMock sendEvent:[OCMArg any] event:[OCMArg any]]).andCall(self, @selector(mockSendEvent:event:)); + + CKKSLaunchSequence *launch = [[CKKSLaunchSequence alloc] initWithRocketName:@"rocket"]; + [launch addEvent:@"keyword1"]; + usleep(1000); + [launch addEvent:@"keyword2"]; + [launch addAttribute:@"attribute" value:@"value"]; + + self.launchExpection = [self expectationWithDescription:@"launch"]; + + [launch launch]; + + [self waitForExpectations:@[self.launchExpection] timeout:0.2]; + + self.launchExpection = [self expectationWithDescription:@"launch"]; + self.launchExpection.inverted = true; + + [launch launch]; + + [self waitForExpectations:@[self.launchExpection] timeout:0.2]; + self.launchExpection = nil; + + NSArray *res = [launch eventsByTime]; + XCTAssert(res.count > 0, "should have event"); + bool found = false; + for (NSString *event in res) { + found |= [event hasPrefix:@"attr:"]; + } + XCTAssert(found, "should have an attribute"); + + + +} + +@end diff --git a/keychain/ckks/CKKS.h b/keychain/ckks/CKKS.h index 3b1d4568..88584fcb 100644 --- a/keychain/ckks/CKKS.h +++ b/keychain/ckks/CKKS.h @@ -25,9 +25,9 @@ #define CKKS_h #include -#include -#include -#include +#include "ipc/securityd_client.h" +#include "utilities/SecCFWrappers.h" +#include "utilities/SecDb.h" #include #ifdef __OBJC__ @@ -61,7 +61,6 @@ extern CKKSItemState* const SecCKKSStateUnauthenticated; extern CKKSItemState* const SecCKKSStateInFlight; extern CKKSItemState* const SecCKKSStateReencrypt; extern CKKSItemState* const SecCKKSStateError; -extern CKKSItemState* const SecCKKSStateZoneMismatch; // an item has appeared that's in the wrong zone extern CKKSItemState* const SecCKKSStateDeleted; // meta-state: please delete this item! /* Processed States */ @@ -184,8 +183,16 @@ extern CKKSZoneKeyState* const SecCKKSZoneKeyStateFetchComplete; extern CKKSZoneKeyState* const SecCKKSZoneKeyStateNeedFullRefetch; // We've received a wrapped TLK, but we don't have its contents yet. Wait until they arrive. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLK; + +// No keys exist for this zone yet, and we're waiting to make some. Please call the "make TLKs" API. +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLKCreation; +// No keys exist for this zone yet, but we've made some. Octagon should upload them. +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLKUpload; + // We've received a wrapped TLK, but we can't process it until the keybag unlocks. Wait until then. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForUnlock; +// We've done some CK ops, but are waiting for the trust system to tell us to continue +extern CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTrust; // Things are unhealthy, but we're not sure entirely why. extern CKKSZoneKeyState* const SecCKKSZoneKeyStateUnhealthy; // Something has gone horribly wrong with the current key pointers. @@ -323,6 +330,13 @@ typedef CF_ENUM(CFIndex, CKKSErrorCode) { CKKSiCloudGreyMode = 41, CKKSNoFetchesRequested = 50, + + CKKSNoMetric = 51, + + CKKSLackingTrust = 52, + CKKSKeysMissing = 53, + + CKKSCircularKeyReference = 54, }; typedef CF_ENUM(CFIndex, CKKSResultDescriptionErrorCode) { @@ -336,9 +350,11 @@ typedef CF_ENUM(CFIndex, CKKSResultDescriptionErrorCode) { CKKSResultDescriptionPendingZoneChangeFetchScheduling = 1000, CKKSResultDescriptionPendingViewChangedScheduling = 1001, - CKKSResultDescriptionPendingZoneInitializeScheduling = 1002, + CKKSResultDescriptionPendingZoneInitializeScheduling = 1002, // No longer used CKKSResultDescriptionPendingOutgoingQueueScheduling = 1003, CKKSResultDescriptionPendingKeyHierachyPokeScheduling = 1004, + CKKSResultDescriptionPendingCloudKitRetryAfter = 1005, + CKKSResultDescriptionPendingFlag = 1006, }; // These errors are returned by the CKKS server extension. diff --git a/keychain/ckks/CKKS.m b/keychain/ckks/CKKS.m index 7d13cb38..9c1e5ea1 100644 --- a/keychain/ckks/CKKS.m +++ b/keychain/ckks/CKKS.m @@ -23,7 +23,6 @@ #include #import -#include #if OCTAGON #import #endif @@ -39,113 +38,6 @@ #import "keychain/ckks/CKKSKey.h" #import "keychain/ot/OTManager.h" -const SecCKKSItemEncryptionVersion currentCKKSItemEncryptionVersion = CKKSItemEncryptionVersion2; - -NSString* const SecCKKSActionAdd = @"add"; -NSString* const SecCKKSActionDelete = @"delete"; -NSString* const SecCKKSActionModify = @"modify"; - -CKKSItemState* const SecCKKSStateNew = (CKKSItemState*) @"new"; -CKKSItemState* const SecCKKSStateUnauthenticated = (CKKSItemState*) @"unauthenticated"; -CKKSItemState* const SecCKKSStateInFlight = (CKKSItemState*) @"inflight"; -CKKSItemState* const SecCKKSStateReencrypt = (CKKSItemState*) @"reencrypt"; -CKKSItemState* const SecCKKSStateError = (CKKSItemState*) @"error"; -CKKSItemState* const SecCKKSStateZoneMismatch = (CKKSItemState*) @"zone_mismatch"; -CKKSItemState* const SecCKKSStateDeleted = (CKKSItemState*) @"deleted"; - -CKKSProcessedState* const SecCKKSProcessedStateLocal = (CKKSProcessedState*) @"local"; -CKKSProcessedState* const SecCKKSProcessedStateRemote = (CKKSProcessedState*) @"remote"; - -CKKSKeyClass* const SecCKKSKeyClassTLK = (CKKSKeyClass*) @"tlk"; -CKKSKeyClass* const SecCKKSKeyClassA = (CKKSKeyClass*) @"classA"; -CKKSKeyClass* const SecCKKSKeyClassC = (CKKSKeyClass*) @"classC"; - -NSString* SecCKKSContainerName = @"com.apple.security.keychain"; -bool SecCKKSContainerUsePCS = false; - -NSString* const SecCKKSSubscriptionID = @"keychain-changes"; -NSString* const SecCKKSAPSNamedPort = @"com.apple.securityd.aps"; - -NSString* const SecCKRecordItemType = @"item"; -NSString* const SecCKRecordHostOSVersionKey = @"uploadver"; -NSString* const SecCKRecordEncryptionVersionKey = @"encver"; -NSString* const SecCKRecordDataKey = @"data"; -NSString* const SecCKRecordParentKeyRefKey = @"parentkeyref"; -NSString* const SecCKRecordWrappedKeyKey = @"wrappedkey"; -NSString* const SecCKRecordGenerationCountKey = @"gen"; - -NSString* const SecCKRecordPCSServiceIdentifier = @"pcsservice"; -NSString* const SecCKRecordPCSPublicKey = @"pcspublickey"; -NSString* const SecCKRecordPCSPublicIdentity = @"pcspublicidentity"; -NSString* const SecCKRecordServerWasCurrent = @"server_wascurrent"; - -NSString* const SecCKRecordIntermediateKeyType = @"synckey"; -NSString* const SecCKRecordKeyClassKey = @"class"; - -NSString* const SecCKRecordTLKShareType = @"tlkshare"; -NSString* const SecCKRecordSenderPeerID = @"sender"; -NSString* const SecCKRecordReceiverPeerID = @"receiver"; -NSString* const SecCKRecordReceiverPublicEncryptionKey = @"receiverPublicEncryptionKey"; -NSString* const SecCKRecordCurve = @"curve"; -NSString* const SecCKRecordEpoch = @"epoch"; -NSString* const SecCKRecordPoisoned = @"poisoned"; -NSString* const SecCKRecordSignature = @"signature"; -NSString* const SecCKRecordVersion = @"version"; - -NSString* const SecCKRecordCurrentKeyType = @"currentkey"; - -NSString* const SecCKRecordCurrentItemType = @"currentitem"; -NSString* const SecCKRecordItemRefKey = @"item"; - -NSString* const SecCKRecordDeviceStateType = @"devicestate"; -NSString* const SecCKRecordOctagonPeerID = @"octagonpeerid"; -NSString* const SecCKRecordOctagonStatus = @"octagonstatus"; -NSString* const SecCKRecordCirclePeerID = @"peerid"; -NSString* const SecCKRecordCircleStatus = @"circle"; -NSString* const SecCKRecordKeyState = @"keystate"; -NSString* const SecCKRecordCurrentTLK = @"currentTLK"; -NSString* const SecCKRecordCurrentClassA = @"currentClassA"; -NSString* const SecCKRecordCurrentClassC = @"currentClassC"; -NSString* const SecCKSRecordLastUnlockTime = @"lastunlock"; -NSString* const SecCKSRecordOSVersionKey = @"osver"; - -NSString* const SecCKRecordManifestType = @"manifest"; -NSString* const SecCKRecordManifestDigestValueKey = @"digest_value"; -NSString* const SecCKRecordManifestGenerationCountKey = @"generation_count"; -NSString* const SecCKRecordManifestLeafRecordIDsKey = @"leaf_records"; -NSString* const SecCKRecordManifestPeerManifestRecordIDsKey = @"peer_manifests"; -NSString* const SecCKRecordManifestCurrentItemsKey = @"current_items"; -NSString* const SecCKRecordManifestSignaturesKey = @"signatures"; -NSString* const SecCKRecordManifestSignerIDKey = @"signer_id"; -NSString* const SecCKRecordManifestSchemaKey = @"schema"; - -NSString* const SecCKRecordManifestLeafType = @"manifest_leaf"; -NSString* const SecCKRecordManifestLeafDERKey = @"der"; -NSString* const SecCKRecordManifestLeafDigestKey = @"digest"; - -CKKSZoneKeyState* const SecCKKSZoneKeyStateReady = (CKKSZoneKeyState*) @"ready"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateReadyPendingUnlock = (CKKSZoneKeyState*) @"readypendingunlock"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateError = (CKKSZoneKeyState*) @"error"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateCancelled = (CKKSZoneKeyState*) @"cancelled"; - -CKKSZoneKeyState* const SecCKKSZoneKeyStateInitializing = (CKKSZoneKeyState*) @"initializing"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateInitialized = (CKKSZoneKeyState*) @"initialized"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateFetch = (CKKSZoneKeyState*) @"fetching"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateFetchComplete = (CKKSZoneKeyState*) @"fetchcomplete"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateNeedFullRefetch = (CKKSZoneKeyState*) @"needrefetch"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLK = (CKKSZoneKeyState*) @"waitfortlk"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForUnlock = (CKKSZoneKeyState*) @"waitforunlock"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateUnhealthy = (CKKSZoneKeyState*) @"unhealthy"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateBadCurrentPointers = (CKKSZoneKeyState*) @"badcurrentpointers"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateNewTLKsFailed = (CKKSZoneKeyState*) @"newtlksfailed"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKShares = (CKKSZoneKeyState*) @"healtlkshares"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed = (CKKSZoneKeyState*) @"healtlksharesfailed"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation = (CKKSZoneKeyState*) @"waitforfixupoperation"; -CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone = (CKKSZoneKeyState*) @"resetzone"; -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; @@ -174,6 +66,10 @@ NSDictionary* CKKSZoneKeyStateMap(void) { SecCKKSZoneKeyStateResettingLocalData: @18U, SecCKKSZoneKeyStateLoggedOut: @19U, SecCKKSZoneKeyStateZoneCreationFailed: @20U, + SecCKKSZoneKeyStateWaitForTrust: @21U, + SecCKKSZoneKeyStateWaitForTLKUpload: @22U, + SecCKKSZoneKeyStateWaitForTLKCreation: @23U, + SecCKKSZoneKeyStateProcess: @24U, }; }); return map; @@ -214,27 +110,19 @@ bool CKKSKeyStateTransient(CKKSZoneKeyState* state) { // Easier to compare against a blacklist of end states bool nontransient = [state isEqualToString:SecCKKSZoneKeyStateReady] || [state isEqualToString:SecCKKSZoneKeyStateReadyPendingUnlock] || + [state isEqualToString:SecCKKSZoneKeyStateWaitForTrust] || [state isEqualToString:SecCKKSZoneKeyStateWaitForTLK] || + [state isEqualToString:SecCKKSZoneKeyStateWaitForTLKCreation] || + [state isEqualToString:SecCKKSZoneKeyStateWaitForTLKUpload] || [state isEqualToString:SecCKKSZoneKeyStateWaitForUnlock] || [state isEqualToString:SecCKKSZoneKeyStateError] || [state isEqualToString:SecCKKSZoneKeyStateCancelled]; return !nontransient; } -const NSUInteger SecCKKSItemPaddingBlockSize = 20; - -NSString* const SecCKKSAggdPropagationDelay = @"com.apple.security.ckks.propagationdelay"; -NSString* const SecCKKSAggdPrimaryKeyConflict = @"com.apple.security.ckks.pkconflict"; -NSString* const SecCKKSAggdViewKeyCount = @"com.apple.security.ckks.keycount"; -NSString* const SecCKKSAggdItemReencryption = @"com.apple.security.ckks.reencrypt"; - -NSString* const SecCKKSUserDefaultsSuite = @"com.apple.security.ckks"; - -NSString* const CKKSErrorDomain = @"CKKSErrorDomain"; -NSString* const CKKSServerExtensionErrorDomain = @"CKKSServerExtensionErrorDomain"; - #if OCTAGON -static bool enableCKKS = true; +// If you want CKKS to run in your daemon/tests, you must call SecCKKSEnable before bringing up the keychain db +static bool enableCKKS = false; static bool testCKKS = false; bool SecCKKSIsEnabled(void) { @@ -422,13 +310,21 @@ void SecCKKSInitialize(SecDbRef db) { #if OCTAGON @autoreleasepool { CKKSViewManager* manager = [CKKSViewManager manager]; - [manager initializeZones]; + [manager createViews]; + [manager setupAnalytics]; SecDbAddNotifyPhaseBlock(db, ^(SecDbConnectionRef dbconn, SecDbTransactionPhase phase, SecDbTransactionSource source, CFArrayRef changes) { SecCKKSNotifyBlock(dbconn, phase, source, changes); }); [manager.completedSecCKKSInitialize fulfill]; + + if(!SecCKKSTestsEnabled()) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [OctagonAPSReceiver receiverForEnvironment:APSEnvironmentProduction namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[APSConnection class]]; + }); + } } #endif } @@ -492,47 +388,3 @@ void SecCKKSPerformLocalResync() { }]; #endif } - -NSString* SecCKKSHostOSVersion() -{ -#ifdef PLATFORM - // Use complicated macro magic to get the string value passed in as preprocessor define PLATFORM. -#define PLATFORM_VALUE(f) #f -#define PLATFORM_OBJCSTR(f) @PLATFORM_VALUE(f) - NSString* platform = (PLATFORM_OBJCSTR(PLATFORM)); -#undef PLATFORM_OBJCSTR -#undef PLATFORM_VALUE -#else - NSString* platform = "unknown"; -#warning No PLATFORM defined; why? -#endif - - NSString* osversion = nil; - - // If we can get the build information from sysctl, use it. - char release[256]; - size_t releasesize = sizeof(release); - bool haveSysctlInfo = true; - haveSysctlInfo &= (0 == sysctlbyname("kern.osrelease", release, &releasesize, NULL, 0)); - - char version[256]; - size_t versionsize = sizeof(version); - haveSysctlInfo &= (0 == sysctlbyname("kern.osversion", version, &versionsize, NULL, 0)); - - if(haveSysctlInfo) { - // Null-terminate for extra safety - release[sizeof(release)-1] = '\0'; - version[sizeof(version)-1] = '\0'; - osversion = [NSString stringWithFormat:@"%s (%s)", release, version]; - } - - if(!osversion) { - // Otherwise, use the not-really-supported fallback. - osversion = [[NSProcessInfo processInfo] operatingSystemVersionString]; - - // subtly improve osversion (but it's okay if that does nothing) - osversion = [osversion stringByReplacingOccurrencesOfString:@"Version" withString:@""]; - } - - return [NSString stringWithFormat:@"%@ %@", platform, osversion]; -} diff --git a/keychain/ckks/CKKSAPSReceiver.m b/keychain/ckks/CKKSAPSReceiver.m deleted file mode 100644 index 76833561..00000000 --- a/keychain/ckks/CKKSAPSReceiver.m +++ /dev/null @@ -1,206 +0,0 @@ -/* - * 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@ - */ - -#if OCTAGON - -#import "keychain/ckks/CKKSAPSReceiver.h" -#import "keychain/ckks/CKKSCondition.h" -#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 notifications for a CKRecordZoneID that hasn't been registered yet, send them a their updates when they register -@property NSMutableDictionary*>* undeliveredUpdates; -@end - -@implementation CKKSAPSReceiver - -+ (instancetype)receiverForEnvironment:(NSString *)environmentName - namedDelegatePort:(NSString*)namedDelegatePort - apsConnectionClass:(Class)apsConnectionClass { - static NSMutableDictionary* environmentMap = nil; - - if(environmentName == nil) { - secnotice("ckkspush", "No push environment; not bringing up APS."); - return nil; - } - - @synchronized([self class]) { - if(environmentMap == nil) { - environmentMap = [[NSMutableDictionary alloc] init]; - } - - CKKSAPSReceiver* recv = [environmentMap valueForKey: environmentName]; - - if(recv == nil) { - recv = [[CKKSAPSReceiver alloc] initWithEnvironmentName: environmentName namedDelegatePort:namedDelegatePort apsConnectionClass: apsConnectionClass]; - [environmentMap setValue: recv forKey: environmentName]; - } - - return recv; - } -} - -+ (dispatch_queue_t)apsDeliveryQueue { - static dispatch_queue_t aps_dispatch_queue; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - aps_dispatch_queue = dispatch_queue_create("aps-callback-queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - }); - return aps_dispatch_queue; -} - -- (instancetype)initWithEnvironmentName:(NSString*)environmentName - namedDelegatePort:(NSString*)namedDelegatePort - apsConnectionClass:(Class)apsConnectionClass { - if(self = [super init]) { - _apsConnectionClass = apsConnectionClass; - _apsConnection = NULL; - - _undeliveredUpdates = [NSMutableDictionary dictionary]; - - // APS might be slow. This doesn't need to happen immediately, so let it happen later. - __weak __typeof(self) weakSelf = self; - dispatch_async([CKKSAPSReceiver apsDeliveryQueue], ^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { - return; - } - strongSelf.apsConnection = [[strongSelf.apsConnectionClass alloc] initWithEnvironmentName:environmentName namedDelegatePort:namedDelegatePort queue:[CKKSAPSReceiver apsDeliveryQueue]]; - strongSelf.apsConnection.delegate = strongSelf; - - // The following string should match: [[NSBundle mainBundle] bundleIdentifier] - NSString* topic = [kCKPushTopicPrefix stringByAppendingString:@"com.apple.securityd"]; - [strongSelf.apsConnection setEnabledTopics:@[topic]]; - }); - - _zoneMap = [NSMapTable strongToWeakObjectsMapTable]; - } - return self; -} - -- (CKKSCondition*)registerReceiver:(id)receiver forZoneID:(CKRecordZoneID *)zoneID { - CKKSCondition* finished = [[CKKSCondition alloc] init]; - - __weak __typeof(self) weakSelf = self; - dispatch_async([CKKSAPSReceiver apsDeliveryQueue], ^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { - secerror("ckks: received registration for released CKKSAPSReceiver"); - return; - } - - [self.zoneMap setObject:receiver forKey: zoneID]; - - NSMutableSet* currentPendingMessages = self.undeliveredUpdates[zoneID]; - [self.undeliveredUpdates removeObjectForKey:zoneID]; - - for(CKRecordZoneNotification* message in currentPendingMessages.allObjects) { - // Now, send the receiver its notification! - secerror("ckks: sending stored push(%@) to newly-registered zone(%@): %@", message, zoneID, receiver); - [receiver notifyZoneChange:message]; - } - - [finished fulfill]; - }); - - return finished; -} - -#pragma mark - APS Delegate callbacks - -- (void)connection:(APSConnection *)connection didReceivePublicToken:(NSData *)publicToken { - // no-op. - secnotice("ckkspush", "CKKSAPSDelegate initiated: %@", connection); -} - -- (void)connection:(APSConnection *)connection didReceiveToken:(NSData *)token forTopic:(NSString *)topic identifier:(NSString *)identifier { - secnotice("ckkspush", "Received per-topic push token \"%@\" for topic \"%@\" identifier \"%@\" on connection %@", token, topic, identifier, connection); -} - -- (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]; - if(recv) { - [recv notifyZoneChange:rznotification]; - } else { - secerror("ckks: received push for unregistered zone: %@", rznotification); - if(rznotification.recordZoneID) { - NSMutableSet* currentPendingMessages = self.undeliveredUpdates[rznotification.recordZoneID]; - if(currentPendingMessages) { - [currentPendingMessages addObject:rznotification]; - } else { - self.undeliveredUpdates[rznotification.recordZoneID] = [NSMutableSet setWithObject:rznotification]; - } - } - } - } else { - secerror("ckks: unexpected notification: %@", notification); - } -} - -@end - -#endif // OCTAGON diff --git a/keychain/ckks/CKKSCKAccountStateTracker.h b/keychain/ckks/CKKSAccountStateTracker.h similarity index 64% rename from keychain/ckks/CKKSCKAccountStateTracker.h rename to keychain/ckks/CKKSAccountStateTracker.h index b5c6ff3f..e83a8a24 100644 --- a/keychain/ckks/CKKSCKAccountStateTracker.h +++ b/keychain/ckks/CKKSAccountStateTracker.h @@ -29,19 +29,22 @@ #include #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ot/OTClique.h" NS_ASSUME_NONNULL_BEGIN /* * Implements a 'debouncer' to store the current CK account and circle state, and receive updates to it. * - * Will only be considered "logged in" if we both have a CK account and are 'in circle'. + * You can register for CK account changes, SOS account changes, or to be informed only when both are in + * a valid state. * * It will notify listeners on account state changes, so multiple repeated account state notifications with the same state are filtered by this class. * Listeners can also get the 'current' state, no matter what it is. They will also then be atomically added to the notification queue, and so will * always receive the next update, preventing them from getting a stale state and missing an immediate update. */ +// This enum represents the combined states of a CK account and the SOS account typedef NS_ENUM(NSInteger, CKKSAccountStatus) { /* Set at initialization. This means we haven't figured out what the account state is. */ CKKSAccountStatusUnknown = 0, @@ -50,6 +53,7 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { /* No iCloud account is logged in on this device, or we're out of circle */ CKKSAccountStatusNoAccount = 3, }; +NSString* CKKSAccountStatusToString(CKKSAccountStatus status); @interface SOSAccountStatus : NSObject @property SOSCCStatus status; @@ -57,56 +61,71 @@ typedef NS_ENUM(NSInteger, CKKSAccountStatus) { - (instancetype)init:(SOSCCStatus)status error:error; @end -/* CliqueStatus */ - -typedef NS_ENUM(NSInteger, CliqueStatus) { - CliqueStatusIn = 0, /*There is a clique and I am in it*/ - CliqueStatusNotIn = 1, /*There is a clique and I am not in it - you should get a voucher to join or tell another peer to trust us*/ - CliqueStatusPending = 2, /*For compatibility, keeping the pending state */ - CliqueStatusAbsent = 3, /*There is no clique - you can establish one */ - CliqueStatusNoCloudKitAccount = 4, /* no cloudkit account present */ - CliqueStatusError = -1 /*unable to determine circle status, inspect CFError to find out why */ -}; -NSString* OTCliqueStatusToString(CliqueStatus status); -CliqueStatus OTCliqueStatusFromString(NSString* str); - @interface OTCliqueStatusWrapper : NSObject @property (readonly) CliqueStatus status; - (instancetype)initWithStatus:(CliqueStatus)status; @end -/* End of clique status */ +@protocol CKKSOctagonStatusMemoizer +- (void)triggerOctagonStatusFetch; + +@property (readonly, nullable) OTCliqueStatusWrapper* octagonStatus; +@property (readonly, nullable) NSString* octagonPeerID; + +// A little bit of a abstraction violation, but it'll do. +- (void)setHSA2iCloudAccountStatus:(CKKSAccountStatus)status; +@end + +#pragma mark -- Listener Protocols -@protocol CKKSAccountStateListener -- (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus; +@protocol CKKSCloudKitAccountStateListener +- (void)cloudkitAccountStateChange:(CKAccountInfo* _Nullable)oldAccountInfo to:(CKAccountInfo*)currentAccountInfo; +@end +@protocol CKKSCloudKitAccountStateTrackingProvider +- (dispatch_semaphore_t)registerForNotificationsOfCloudKitAccountStatusChange:(id)listener; @end -@interface CKKSCKAccountStateTracker : NSObject +#pragma mark -- Tracker + +@interface CKKSAccountStateTracker : NSObject @property CKKSCondition* finishedInitialDispatches; // If you use these, please be aware they could change out from under you at any time @property (nullable) CKAccountInfo* currentCKAccountInfo; -@property (nullable) SOSAccountStatus* currentCircleStatus; +@property CKKSCondition* ckAccountInfoInitialized; -@property (readonly,atomic) CKKSAccountStatus currentComputedAccountStatus; -@property (nullable,readonly,atomic) NSError* currentAccountError; -@property CKKSCondition* currentComputedAccountStatusValid; // Fetched and memoized from CloudKit; we can't afford deadlocks with their callbacks @property (nullable, copy) NSString* ckdeviceID; @property (nullable) NSError* ckdeviceIDError; @property CKKSCondition* ckdeviceIDInitialized; -// Fetched and memoized from the Account when we're in-circle; our threading model is strange +// Fetched and memoized from SOS. Not otherwise used. +@property (nullable) SOSAccountStatus* currentCircleStatus; @property (nullable) NSString* accountCirclePeerID; @property (nullable) NSError* accountCirclePeerIDError; @property CKKSCondition* accountCirclePeerIDInitialized; +// Filled and memoized for quick reference. Don't use for anything vital. +// This will only fetch the status for the default context. +@property (readonly, nullable) OTCliqueStatusWrapper* octagonStatus; +@property (readonly, nullable) NSString* octagonPeerID; +@property (readonly) CKKSCondition* octagonInformationInitialized; + +// Filled by Octagon, as it's fairly hard to compute. +@property (readonly) CKKSAccountStatus hsa2iCloudAccountStatus; +@property (readonly) CKKSCondition* hsa2iCloudAccountInitialized; + - (instancetype)init:(CKContainer*)container nsnotificationCenterClass:(Class)nsnotificationCenterClass; -- (dispatch_semaphore_t)notifyOnAccountStatusChange:(id)listener; +- (dispatch_semaphore_t)registerForNotificationsOfCloudKitAccountStatusChange:(id)listener; + +// Call this to refetch the Octagon status +- (void)triggerOctagonStatusFetch; // Methods useful for testing: +- (void)performInitialDispatches; // Call this to simulate a notification (and pause the calling thread until all notifications are delivered) - (void)notifyCKAccountStatusChangeAndWaitForSignal; @@ -114,6 +133,8 @@ CliqueStatus OTCliqueStatusFromString(NSString* str); - (dispatch_group_t _Nullable)checkForAllDeliveries; +- (void)setHSA2iCloudAccountStatus:(CKKSAccountStatus)status; + + (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/CKKSAccountStateTracker.m similarity index 51% rename from keychain/ckks/CKKSCKAccountStateTracker.m rename to keychain/ckks/CKKSAccountStateTracker.m index 17a732b9..34c411e5 100644 --- a/keychain/ckks/CKKSCKAccountStateTracker.m +++ b/keychain/ckks/CKKSAccountStateTracker.m @@ -27,96 +27,127 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #include +#import "keychain/ot/OTManager.h" +#import "keychain/ot/OTConstants.h" #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CloudKitCategories.h" -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #import "keychain/ckks/CKKSAnalytics.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" -@interface CKKSCKAccountStateTracker () -@property (readonly) Class nsnotificationCenterClass; -@property CKKSAccountStatus currentComputedAccountStatus; -@property (nullable, atomic) NSError* currentAccountError; +NSString* CKKSAccountStatusToString(CKKSAccountStatus status) +{ + switch(status) { + case CKKSAccountStatusAvailable: + return @"available"; + case CKKSAccountStatusNoAccount: + return @"no account"; + case CKKSAccountStatusUnknown: + return @"unknown"; + } +} + +@interface CKKSAccountStateTracker () +@property (readonly) Class nsnotificationCenterClass; @property dispatch_queue_t queue; -@property NSMapTable>* changeListeners; -@property CKContainer* container; // used only for fetching the CKAccountStatus +@property NSMapTable>* ckChangeListeners; -/* We have initialization races. We should report CKKSAccountStatusUnknown until both of - * these are true, otherwise on a race, it looks like we logged out. */ +@property CKContainer* container; // used only for fetching the CKAccountStatus @property bool firstCKAccountFetch; -@property bool firstSOSCircleFetch; + +// make writable +@property (nullable) OTCliqueStatusWrapper* octagonStatus; +@property (nullable) NSString* octagonPeerID; +@property CKKSCondition* octagonInformationInitialized; + +@property CKKSAccountStatus hsa2iCloudAccountStatus; +@property CKKSCondition* hsa2iCloudAccountInitialized; @end -@implementation CKKSCKAccountStateTracker +@implementation CKKSAccountStateTracker +@synthesize octagonPeerID = _octagonPeerID; -(instancetype)init: (CKContainer*) container nsnotificationCenterClass: (Class) nsnotificationCenterClass { if((self = [super init])) { _nsnotificationCenterClass = nsnotificationCenterClass; - _changeListeners = [NSMapTable strongToWeakObjectsMapTable]; // Backwards from how we'd like, but it's the best way to have weak pointers to CKKSAccountStateListener. + // These map tables are backwards from how we'd like, but it's the best way to have weak pointers to CKKSCombinedAccountStateListener. + _ckChangeListeners = [NSMapTable strongToWeakObjectsMapTable]; + _currentCKAccountInfo = nil; - _currentCircleStatus = [[SOSAccountStatus alloc] init:kSOSCCError error:nil]; + _ckAccountInfoInitialized = [[CKKSCondition alloc] init]; - _currentComputedAccountStatus = CKKSAccountStatusUnknown; - _currentComputedAccountStatusValid = [[CKKSCondition alloc] init]; + _currentCircleStatus = [[SOSAccountStatus alloc] init:kSOSCCError error:nil]; _container = container; _queue = dispatch_queue_create("ck-account-state", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _firstCKAccountFetch = false; - _firstSOSCircleFetch = false; _finishedInitialDispatches = [[CKKSCondition alloc] init]; _ckdeviceIDInitialized = [[CKKSCondition alloc] init]; + _octagonInformationInitialized = [[CKKSCondition alloc] init]; + + _hsa2iCloudAccountStatus = CKKSAccountStatusUnknown; + _hsa2iCloudAccountInitialized = [[CKKSCondition alloc] init]; + id notificationCenter = [self.nsnotificationCenterClass defaultCenter]; secinfo("ckksaccount", "Registering with notification center %@", notificationCenter); [notificationCenter addObserver:self selector:@selector(notifyCKAccountStatusChange:) name:CKAccountChangedNotification object:NULL]; - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // If this is a live server, register with notify if(!SecCKKSTestsEnabled()) { int token = 0; notify_register_dispatch(kSOSCCCircleChangedNotification, &token, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^(int t) { - [weakSelf notifyCircleChange:nil]; + STRONGIFY(self); + [self notifyCircleChange:nil]; }); - } - // Fire off a fetch of the account status. Do not go on our local queue, because notifyCKAccountStatusChange will attempt to go back on it for thread-safety. - dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { - return; - } - @autoreleasepool { - [strongSelf notifyCKAccountStatusChange:nil]; - [strongSelf notifyCircleChange:nil]; - [strongSelf.finishedInitialDispatches fulfill]; - } - }); + // Fire off a fetch of the account status. Do not go on our local queue, because notifyCKAccountStatusChange will attempt to go back on it for thread-safety. + // Note: if you're in the tests, you must call performInitialDispatches yourself! + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ + STRONGIFY(self); + if(!self) { + return; + } + @autoreleasepool { + [self performInitialDispatches]; + } + }); + } } return self; } +- (void)performInitialDispatches +{ + @autoreleasepool { + [self notifyCKAccountStatusChange:nil]; + [self notifyCircleChange:nil]; + [self.finishedInitialDispatches fulfill]; + } +} + -(void)dealloc { id notificationCenter = [self.nsnotificationCenterClass defaultCenter]; [notificationCenter removeObserver:self]; } -(NSString*)descriptionInternal: (NSString*) selfString { - return [NSString stringWithFormat:@"<%@: %@ (%@ %@) %@>", - selfString, - [self currentStatus], - self.currentCKAccountInfo, - self.currentCircleStatus, - self.currentAccountError ?: @""]; + return [NSString stringWithFormat:@"<%@: %@, hsa2: %@>", + selfString, + self.currentCKAccountInfo, + CKKSAccountStatusToString(self.hsa2iCloudAccountStatus)]; } -(NSString*)description { @@ -127,14 +158,14 @@ return [self descriptionInternal: [super description]]; } --(dispatch_semaphore_t)notifyOnAccountStatusChange:(id)listener { +- (dispatch_semaphore_t)registerForNotificationsOfCloudKitAccountStatusChange:(id)listener { // signals when we've successfully delivered the first account status dispatch_semaphore_t finishedSema = dispatch_semaphore_create(0); dispatch_async(self.queue, ^{ bool alreadyRegisteredListener = false; - NSEnumerator *enumerator = [self.changeListeners objectEnumerator]; - id value; + NSEnumerator *enumerator = [self.ckChangeListeners objectEnumerator]; + id value; while ((value = [enumerator nextObject])) { // do pointer comparison @@ -145,21 +176,22 @@ NSString* queueName = [NSString stringWithFormat: @"ck-account-state-%@", listener]; dispatch_queue_t objQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - [self.changeListeners setObject: listener forKey: objQueue]; + [self.ckChangeListeners setObject:listener forKey: objQueue]; - secinfo("ckksaccount", "adding a new listener: %@", listener); + secinfo("ckksaccount-ck", "adding a new listener: %@", listener); // If we know the current account status, let this listener know - if(self.currentComputedAccountStatus != CKKSAccountStatusUnknown) { - secinfo("ckksaccount", "notifying new listener %@ of current state %d", listener, (int)self.currentComputedAccountStatus); + if(self.firstCKAccountFetch) { + secinfo("ckksaccount-ck", "notifying new listener %@ of current state %@", listener, self.currentCKAccountInfo); dispatch_group_t g = dispatch_group_create(); if(!g) { - secnotice("ckksaccount", "Unable to get dispatch group."); + secnotice("ckksaccount-ck", "Unable to get dispatch group."); + dispatch_semaphore_signal(finishedSema); return; } - [self _onqueueDeliverCurrentState:listener listenerQueue:objQueue oldStatus:CKKSAccountStatusUnknown group:g]; + [self _onqueueDeliverCurrentCloudKitState:listener listenerQueue:objQueue oldStatus:nil group:g]; dispatch_group_notify(g, self.queue, ^{ dispatch_semaphore_signal(finishedSema); @@ -189,54 +221,42 @@ dispatch_sync(self.queue, ^{ self.firstCKAccountFetch = true; secnotice("ckksaccount", "received CK Account info: %@", ckAccountInfo); - [self _onqueueUpdateAccountState:ckAccountInfo circle:self.currentCircleStatus deliveredSemaphore:finishedSema]; + [self _onqueueUpdateAccountState:ckAccountInfo deliveredSemaphore:finishedSema]; }); }]; return finishedSema; } --(dispatch_semaphore_t)notifyCircleChange:(__unused id)object { - dispatch_semaphore_t finishedSema = dispatch_semaphore_create(0); - - SOSAccountStatus* circleStatus = [CKKSCKAccountStateTracker getCircleStatus]; - dispatch_sync(self.queue, ^{ - self.firstSOSCircleFetch = true; - - [self _onqueueUpdateAccountState:self.currentCKAccountInfo circle:circleStatus deliveredSemaphore:finishedSema]; - }); - return finishedSema; -} - // Takes the new ckAccountInfo we're moving to --(void)_onqueueUpdateCKDeviceID: (CKAccountInfo*)ckAccountInfo { +-(void)_onqueueUpdateCKDeviceID:(CKAccountInfo*)ckAccountInfo { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // If we're in an account, opportunistically fill in the device id if(ckAccountInfo.accountStatus == CKAccountStatusAvailable) { [self.container fetchCurrentDeviceIDWithCompletionHandler:^(NSString* deviceID, NSError* ckerror) { - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckksaccount: Received fetchCurrentDeviceIDWithCompletionHandler callback with null AccountStateTracker"); return; } // Make sure you synchronize here; if we've logged out before the callback returns, don't record the result - dispatch_async(strongSelf.queue, ^{ - __strong __typeof(self) innerStrongSelf = weakSelf; - if(innerStrongSelf.currentCKAccountInfo.accountStatus == CKAccountStatusAvailable) { + dispatch_async(self.queue, ^{ + STRONGIFY(self); + if(self.currentCKAccountInfo.accountStatus == CKAccountStatusAvailable) { secnotice("ckksaccount", "CloudKit deviceID is: %@ %@", deviceID, ckerror); - innerStrongSelf.ckdeviceID = deviceID; - innerStrongSelf.ckdeviceIDError = ckerror; - [innerStrongSelf.ckdeviceIDInitialized fulfill]; + self.ckdeviceID = deviceID; + self.ckdeviceIDError = ckerror; + [self.ckdeviceIDInitialized fulfill]; } else { // Logged out! No ckdeviceid. secerror("ckksaccount: Logged back out but still received a fetchCurrentDeviceIDWithCompletionHandler callback"); - innerStrongSelf.ckdeviceID = nil; - innerStrongSelf.ckdeviceIDError = nil; + self.ckdeviceID = nil; + self.ckdeviceIDError = nil; // Don't touch the ckdeviceIDInitialized object; it should have been reset when the logout happened. } }); @@ -249,8 +269,28 @@ } } +- (dispatch_semaphore_t)notifyCircleChange:(__unused id)object { + dispatch_semaphore_t finishedSema = dispatch_semaphore_create(0); + + SOSAccountStatus* sosstatus = [CKKSAccountStateTracker getCircleStatus]; + dispatch_sync(self.queue, ^{ + if(self.currentCircleStatus == nil || ![self.currentCircleStatus isEqual:sosstatus]) { + secnotice("ckksaccount", "moving to circle status: %@", sosstatus); + self.currentCircleStatus = sosstatus; + + if (sosstatus.status == kSOSCCInCircle) { + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle]; + } + [self _onqueueUpdateCirclePeerID:sosstatus]; + } + dispatch_semaphore_signal(finishedSema); + }); + + return finishedSema; +} + // Pulled out for mocking purposes -+(void)fetchCirclePeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))callback { ++ (void)fetchCirclePeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))callback { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ CFErrorRef cferror = nil; SOSPeerInfoRef egoPeerInfo = SOSCCCopyMyPeerInfo(&cferror); @@ -262,33 +302,33 @@ } // Takes the new ckAccountInfo we're moving to --(void)_onqueueUpdateCirclePeerID: (SOSAccountStatus*)sosstatus { +- (void)_onqueueUpdateCirclePeerID:(SOSAccountStatus*)sosstatus { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // If we're in a circle, fetch the peer id if(sosstatus.status == kSOSCCInCircle) { - [CKKSCKAccountStateTracker fetchCirclePeerID:^(NSString* peerID, NSError* error) { - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + [CKKSAccountStateTracker fetchCirclePeerID:^(NSString* peerID, NSError* error) { + STRONGIFY(self); + if(!self) { secerror("ckksaccount: Received fetchCirclePeerID callback with null AccountStateTracker"); return; } - dispatch_async(strongSelf.queue, ^{ - __strong __typeof(self) innerstrongSelf = weakSelf; + dispatch_async(self.queue, ^{ + STRONGIFY(self); - if(innerstrongSelf.currentCircleStatus && innerstrongSelf.currentCircleStatus.status == kSOSCCInCircle) { + if(self.currentCircleStatus && self.currentCircleStatus.status == kSOSCCInCircle) { secnotice("ckksaccount", "Circle peerID is: %@ %@", peerID, error); // Still in circle. Proceed. - innerstrongSelf.accountCirclePeerID = peerID; - innerstrongSelf.accountCirclePeerIDError = error; - [innerstrongSelf.accountCirclePeerIDInitialized fulfill]; + self.accountCirclePeerID = peerID; + self.accountCirclePeerIDError = error; + [self.accountCirclePeerIDInitialized fulfill]; } else { secerror("ckksaccount: Out of circle but still received a fetchCirclePeerID callback"); // Not in-circle. Throw away circle id. - strongSelf.accountCirclePeerID = nil; - strongSelf.accountCirclePeerIDError = nil; + self.accountCirclePeerID = nil; + self.accountCirclePeerIDError = nil; // Don't touch the accountCirclePeerIDInitialized object; it should have been reset when the logout happened. } }); @@ -302,158 +342,80 @@ } } -- (bool)_onqueueDetermineLoggedIn:(NSError**)error { - // We are logged in if we are: - // in CKAccountStatusAvailable - // and supportsDeviceToDeviceEncryption == true - // and the iCloud account is not in grey mode - // and in circle +- (void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo + deliveredSemaphore:(dispatch_semaphore_t)finishedSema +{ + // Launder the finishedSema into a dispatch_group. + // _onqueueUpdateAccountState:circle:dispatchGroup: will then add any blocks it thinks is necessary, + // then the group will fire the semaphore. dispatch_assert_queue(self.queue); - if(self.currentCKAccountInfo) { - if(self.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable) { - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNotLoggedIn - description:@"iCloud account is logged out"]; - } - return false; - } else if(!self.currentCKAccountInfo.supportsDeviceToDeviceEncryption) { - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNotHSA2 - description:@"iCloud account is not HSA2"]; - } - return false; - } else if(!self.currentCKAccountInfo.hasValidCredentials) { - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSiCloudGreyMode - description:@"iCloud account is in grey mode"]; - } - return false; - } - } else { - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNotLoggedIn - description:@"No current iCloud account status"]; - } - return false; - } - if(self.currentCircleStatus.status != kSOSCCInCircle) { - if(error) { - *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain - code:kSOSErrorNotInCircle - description:@"Not in circle"]; - } - return false; + dispatch_group_t g = dispatch_group_create(); + if(!g) { + secnotice("ckksaccount", "Unable to get dispatch group."); + dispatch_semaphore_signal(finishedSema); + return; } - return true; + [self _onqueueUpdateAccountState:ckAccountInfo + dispatchGroup:g]; + + dispatch_group_notify(g, self.queue, ^{ + dispatch_semaphore_signal(finishedSema); + }); } --(void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo circle:(SOSAccountStatus*)sosstatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema { +- (void)_onqueueUpdateAccountState:(CKAccountInfo*)ckAccountInfo + dispatchGroup:(dispatch_group_t)g +{ dispatch_assert_queue(self.queue); - if([self.currentCKAccountInfo isEqual: ckAccountInfo] && self.currentCircleStatus.status == sosstatus.status) { + if([self.currentCKAccountInfo isEqual: ckAccountInfo]) { // no-op. - secinfo("ckksaccount", "received another notification of CK Account State %@ and Circle status %d", ckAccountInfo, (int)sosstatus); - dispatch_semaphore_signal(finishedSema); + secinfo("ckksaccount", "received another notification of CK Account State %@", ckAccountInfo); return; } if((self.currentCKAccountInfo == nil && ckAccountInfo != nil) || - ![self.currentCKAccountInfo isEqual: ckAccountInfo]) { + !(self.currentCKAccountInfo == ckAccountInfo || [self.currentCKAccountInfo isEqual: ckAccountInfo])) { secnotice("ckksaccount", "moving to CK Account info: %@", ckAccountInfo); + CKAccountInfo* oldAccountInfo = self.currentCKAccountInfo; self.currentCKAccountInfo = ckAccountInfo; + [self.ckAccountInfoInitialized fulfill]; [self _onqueueUpdateCKDeviceID: ckAccountInfo]; - } - if(![self.currentCircleStatus isEqual:sosstatus]) { - secnotice("ckksaccount", "moving to circle status: %@", sosstatus); - self.currentCircleStatus = sosstatus; - if (sosstatus.status == kSOSCCInCircle) { - [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle]; - } - [self _onqueueUpdateCirclePeerID: sosstatus]; - } - - if(!self.firstSOSCircleFetch || !self.firstCKAccountFetch) { - secnotice("ckksaccount", "Haven't received updates from all sources; not passing update along: %@", self); - dispatch_semaphore_signal(finishedSema); - 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; - if([self _onqueueDetermineLoggedIn:&error]) { - self.currentComputedAccountStatus = CKKSAccountStatusAvailable; - self.currentAccountError = nil; - } else { - self.currentComputedAccountStatus = CKKSAccountStatusNoAccount; - self.currentAccountError = error; - } - [self.currentComputedAccountStatusValid fulfill]; - - if(oldComputedStatus == self.currentComputedAccountStatus) { - secnotice("ckksaccount", "No change in computed account status: %@ (%@ %@)", - [self currentStatus], - self.currentCKAccountInfo, - self.currentCircleStatus); - dispatch_semaphore_signal(finishedSema); - return; + [self _onqueueDeliverCloudKitStateChanges:oldAccountInfo dispatchGroup:g]; } - - secnotice("ckksaccount", "New computed account status: %@ (%@ %@)", - [self currentStatus], - self.currentCKAccountInfo, - self.currentCircleStatus); - - [self _onqueueDeliverStateChanges:oldComputedStatus deliveredSemaphore:finishedSema]; } --(void)_onqueueDeliverStateChanges:(CKKSAccountStatus)oldStatus deliveredSemaphore:(dispatch_semaphore_t)finishedSema { +- (void)_onqueueDeliverCloudKitStateChanges:(CKAccountInfo*)oldStatus + dispatchGroup:(dispatch_group_t)g +{ dispatch_assert_queue(self.queue); - dispatch_group_t g = dispatch_group_create(); - if(!g) { - secnotice("ckksaccount", "Unable to get dispatch group."); - return; - } - - NSEnumerator *enumerator = [self.changeListeners keyEnumerator]; + NSEnumerator *enumerator = [self.ckChangeListeners keyEnumerator]; dispatch_queue_t dq; // Queue up the changes for each listener. while ((dq = [enumerator nextObject])) { - id listener = [self.changeListeners objectForKey: dq]; - [self _onqueueDeliverCurrentState:listener listenerQueue:dq oldStatus:oldStatus group:g]; + id listener = [self.ckChangeListeners objectForKey: dq]; + [self _onqueueDeliverCurrentCloudKitState:listener listenerQueue:dq oldStatus:oldStatus group:g]; } - - dispatch_group_notify(g, self.queue, ^{ - dispatch_semaphore_signal(finishedSema); - }); } --(void)_onqueueDeliverCurrentState:(id)listener listenerQueue:(dispatch_queue_t)listenerQueue oldStatus:(CKKSAccountStatus)oldStatus group:(dispatch_group_t)g { +- (void)_onqueueDeliverCurrentCloudKitState:(id)listener + listenerQueue:(dispatch_queue_t)listenerQueue + oldStatus:(CKAccountInfo* _Nullable)oldStatus + group:(dispatch_group_t)g +{ dispatch_assert_queue(self.queue); __weak __typeof(listener) weakListener = listener; if(listener) { dispatch_group_async(g, listenerQueue, ^{ - [weakListener ckAccountStatusChange:oldStatus to:self.currentComputedAccountStatus]; + [weakListener cloudkitAccountStateChange:oldStatus to:self.currentCKAccountInfo]; }); } } @@ -475,19 +437,19 @@ } dispatch_sync(self.queue, ^{ - NSEnumerator *enumerator = [self.changeListeners keyEnumerator]; + NSEnumerator *enumerator = [self.ckChangeListeners keyEnumerator]; dispatch_queue_t dq; // Queue up the changes for each listener. while ((dq = [enumerator nextObject])) { - id listener = [self.changeListeners objectForKey: dq]; + id listener = [self.ckChangeListeners objectForKey: dq]; secinfo("ckksaccountblock", "Starting blocking for listener %@", listener); - __weak __typeof(listener) weakListener = listener; + WEAKIFY(listener); dispatch_group_async(g, dq, ^{ - __strong __typeof(listener) strongListener = weakListener; + STRONGIFY(listener); // Do nothing in particular. It's just important that this block runs. - secinfo("ckksaccountblock", "Done blocking for listener %@", strongListener); + secinfo("ckksaccountblock", "Done blocking for listener %@", listener); }); } }); @@ -508,11 +470,7 @@ return [[SOSAccountStatus alloc] init:status error:nil]; } --(NSString*)currentStatus { - return [CKKSCKAccountStateTracker stringFromAccountStatus:self.currentComputedAccountStatus]; -} - -+(NSString*)stringFromAccountStatus: (CKKSAccountStatus) status { ++ (NSString*)stringFromAccountStatus: (CKKSAccountStatus) status { switch(status) { case CKKSAccountStatusUnknown: return @"account state unknown"; case CKKSAccountStatusAvailable: return @"logged in"; @@ -520,6 +478,51 @@ } } +- (void)triggerOctagonStatusFetch +{ + WEAKIFY(self); + + __block CKKSCondition* blockPointer = nil; + dispatch_sync(self.queue, ^{ + self.octagonInformationInitialized = [[CKKSCondition alloc] initToChain:self.octagonInformationInitialized]; + blockPointer = self.octagonInformationInitialized; + }); + + // Explicitly do not use the OTClique API, as that might include SOS status as well + OTOperationConfiguration* config = [[OTOperationConfiguration alloc] init]; + config.timeoutWaitForCKAccount = 100*NSEC_PER_MSEC; + [[OTManager manager] fetchTrustStatus:nil + context:OTDefaultContext + configuration:config + reply:^(CliqueStatus status, NSString * _Nullable peerID, NSNumber * _Nullable numberOfPeersInOctagon, BOOL isExcluded, NSError * _Nullable error) { + STRONGIFY(self); + + dispatch_sync(self.queue, ^{ + if(error) { + secerror("ckksaccount: error getting octagon status: %@", error); + self.octagonStatus = [[OTCliqueStatusWrapper alloc] initWithStatus:CliqueStatusError]; + } else { + secnotice("ckksaccount", "Caching octagon status as (%@, %@)", OTCliqueStatusToString(status), peerID); + self.octagonStatus = [[OTCliqueStatusWrapper alloc] initWithStatus:status]; + } + + self.octagonPeerID = peerID; + [blockPointer fulfill]; + }); + }]; +} + + +- (void)setHSA2iCloudAccountStatus:(CKKSAccountStatus)status +{ + self.hsa2iCloudAccountStatus = status; + if(status == CKKSAccountStatusUnknown) { + self.hsa2iCloudAccountInitialized = [[CKKSCondition alloc] initToChain:self.hsa2iCloudAccountInitialized]; + } else { + [self.hsa2iCloudAccountInitialized fulfill]; + } +} + @end @implementation SOSAccountStatus @@ -578,42 +581,5 @@ } @end -NSString* OTCliqueStatusToString(CliqueStatus status) -{ - switch(status) { - case CliqueStatusIn: - return @"CliqueStatusIn"; - case CliqueStatusNotIn: - return @"CliqueStatusNotIn"; - case CliqueStatusPending: - return @"CliqueStatusPending"; - case CliqueStatusAbsent: - return @"CliqueStatusAbsent"; - case CliqueStatusNoCloudKitAccount: - return @"CliqueStatusNoCloudKitAccount"; - case CliqueStatusError: - return @"CliqueStatusError"; - }; -} -CliqueStatus OTCliqueStatusFromString(NSString* str) -{ - if([str isEqualToString: @"CliqueStatusIn"]) { - return CliqueStatusIn; - } else if([str isEqualToString: @"CliqueStatusNotIn"]) { - return CliqueStatusNotIn; - } else if([str isEqualToString: @"CliqueStatusPending"]) { - return CliqueStatusPending; - } else if([str isEqualToString: @"CliqueStatusAbsent"]) { - return CliqueStatusAbsent; - } else if([str isEqualToString: @"CliqueStatusNoCloudKitAccount"]) { - return CliqueStatusNoCloudKitAccount; - } else if([str isEqualToString: @"CliqueStatusError"]) { - return CliqueStatusError; - } - - return CliqueStatusError; -} - - #endif // OCTAGON diff --git a/keychain/ckks/CKKSAnalytics.h b/keychain/ckks/CKKSAnalytics.h index 37962904..ae6b6b9f 100644 --- a/keychain/ckks/CKKSAnalytics.h +++ b/keychain/ckks/CKKSAnalytics.h @@ -38,6 +38,27 @@ extern NSString* const CKKSAnalyticsLastUnlock; extern NSString* const CKKSAnalyticsLastKeystateReady; extern NSString* const CKKSAnalyticsLastInCircle; +extern NSString* const OctagonAnalyticsStateMachineState; +extern NSString* const OctagonAnalyticIcloudAccountState; +extern NSString* const OctagonAnalyticsTrustState; +extern NSString* const OctagonAnalyticsLastHealthCheck; +extern NSString* const OctagonAnalyticsSOSStatus; +extern NSString* const OctagonAnalyticsDateOfLastPreflightPreapprovedJoin; +extern NSString* const OctagonAnalyticsLastKeystateReady; +extern NSString* const OctagonAnalyticsLastCoreFollowup; +extern NSString* const OctagonAnalyticsCoreFollowupStatus; +extern NSString* const OctagonAnalyticsCoreFollowupFailureCount; +extern NSString* const OctagonAnalyticsCoreFollowupLastFailureTime; +extern NSString* const OctagonAnalyticsPrerecordPending; +extern NSString* const OctagonAnalyticsCDPStateRun; + +extern NSString* const OctagonAnalyticsKVSProvisioned; +extern NSString* const OctagonAnalyticsKVSEnabled; +extern NSString* const OctagonAnalyticsKeychainSyncProvisioned; +extern NSString* const OctagonAnalyticsKeychainSyncEnabled; +extern NSString* const OctagonAnalyticsCloudKitProvisioned; +extern NSString* const OctagonAnalyticsCloudKitEnabled; + @class CKKSKeychainView; @protocol CKKSAnalyticsFailableEvent @@ -49,6 +70,7 @@ extern CKKSAnalyticsFailableEvent* const CKKSEventProcessOutgoingQueue; extern CKKSAnalyticsFailableEvent* const CKKSEventUploadChanges; extern CKKSAnalyticsFailableEvent* const CKKSEventStateError; extern CKKSAnalyticsFailableEvent* const CKKSEventProcessHealKeyHierarchy; +extern CKKSAnalyticsFailableEvent* const CKKSEventProcessReencryption; extern CKKSAnalyticsFailableEvent* const OctagonEventPreflightBottle; extern CKKSAnalyticsFailableEvent* const OctagonEventLaunchBottle; @@ -59,12 +81,80 @@ extern CKKSAnalyticsFailableEvent* const OctagonEventRestoreBottle; extern CKKSAnalyticsFailableEvent* const OctagonEventRamp; extern CKKSAnalyticsFailableEvent* const OctagonEventBottleCheck; extern CKKSAnalyticsFailableEvent* const OctagonEventCoreFollowUp; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpdateBottle; + +extern CKKSAnalyticsFailableEvent* const OctagonEventRecoverBottle; +extern CKKSAnalyticsFailableEvent* const OctagonEventFetchAllBottles; +extern CKKSAnalyticsFailableEvent* const OctagonEventFetchEscrowContents; extern CKKSAnalyticsFailableEvent* const OctagonEventRestoredSignedBottlePeer; extern CKKSAnalyticsFailableEvent* const OctagonEventRestoredOctagonPeerEncryptionKey; extern CKKSAnalyticsFailableEvent* const OctagonEventRestoredOctagonPeerSigningKey; extern CKKSAnalyticsFailableEvent* const OctagonEventRestoreComplete; +/* Initial health check */ +extern CKKSAnalyticsFailableEvent* const OctagonEventCheckTrustState; + +/* Outer calls as seen by the client */ +extern CKKSAnalyticsFailableEvent* const OctagonEventBottledPeerRestore; +extern CKKSAnalyticsFailableEvent* const OctagonEventFetchEscrowContents; +extern CKKSAnalyticsFailableEvent* const OctagonEventResetAndEstablish; +extern CKKSAnalyticsFailableEvent* const OctagonEventEstablish; +extern CKKSAnalyticsFailableEvent* const OctagonEventLeaveClique; +extern CKKSAnalyticsFailableEvent* const OctagonEventRemoveFriendsInClique; +extern CKKSAnalyticsFailableEvent* const OctagonEventRecoveryKey; + +/* Inner calls as seen by TPH and securityd */ +/* inner: Upgrade */ +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradeFetchDeviceIDs; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradeSetAllowList; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradeSilentEscrow; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradePreapprovedJoin; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradePreflightPreapprovedJoin; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradePrepare; +extern CKKSAnalyticsFailableEvent* const OctagonEventUpgradePreapprovedJoinAfterPairing; + +/* inner: join with voucher */ +extern CKKSAnalyticsFailableEvent* const OctagonEventJoinWithVoucher; + +/* inner: join with bottle */ +extern CKKSAnalyticsFailableEvent* const OctagonEventVoucherWithBottle; + +/* inner: join with recovery key */ +extern CKKSAnalyticsFailableEvent* const OctagonEventVoucherWithRecoveryKey; +extern CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyValidationFailed; +extern CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyFailed; +extern CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyCircleReset; +extern CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyCircleResetFailed; +extern CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyEnrollFailed; + +/* inner: set recovery key */ +extern CKKSAnalyticsFailableEvent* const OctagonEventSetRecoveryKey; +extern CKKSAnalyticsFailableEvent* const OctagonEventSetRecoveryKeyValidationFailed; + +/* inner: reset */ +extern CKKSAnalyticsFailableEvent* const OctagonEventReset; + +/* inner: prepare */ +extern CKKSAnalyticsFailableEvent* const OctagonEventPrepareIdentity; + +/* inner: establish */ +extern CKKSAnalyticsFailableEvent* const OctagonEventEstablishIdentity; + +/* inner: fetchviews */ +extern CKKSAnalyticsFailableEvent* const OctagonEventFetchViews; + +/* state machine */ +extern CKKSAnalyticsFailableEvent* const OctagonEventStateTransition; + +/* become untrusted */ +extern CKKSAnalyticsFailableEvent* const OctagonEventCheckTrustForCFU; + +/* watchOS only: pairing with companion */ +extern CKKSAnalyticsFailableEvent* const OctagonEventCompanionPairing; + +/* trust state from trusted peers helper*/ +extern CKKSAnalyticsFailableEvent* const OctagonEventTPHHealthCheckStatus; @protocol CKKSAnalyticsSignpostEvent @end @@ -78,12 +168,26 @@ extern CKKSAnalyticsSignpostEvent* const CKKSEventMissingLocalItemsFound; @end typedef NSString CKKSAnalyticsActivity; extern CKKSAnalyticsActivity* const CKKSActivityOTFetchRampState; -extern CKKSAnalyticsActivity* const CKKSActivityOctagonSignIn; extern CKKSAnalyticsActivity* const CKKSActivityOctagonPreflightBottle; extern CKKSAnalyticsActivity* const CKKSActivityOctagonLaunchBottle; extern CKKSAnalyticsActivity* const CKKSActivityOctagonRestore; extern CKKSAnalyticsActivity* const CKKSActivityScrubBottle; extern CKKSAnalyticsActivity* const CKKSActivityBottleCheck; +extern CKKSAnalyticsActivity* const CKKSActivityOctagonUpdateBottle; + +extern CKKSAnalyticsActivity* const OctagonActivityAccountAvailable; +extern CKKSAnalyticsActivity* const OctagonActivityAccountNotAvailable; +extern CKKSAnalyticsActivity* const OctagonActivityResetAndEstablish; +extern CKKSAnalyticsActivity* const OctagonActivityEstablish; +extern CKKSAnalyticsActivity* const OctagonActivityFetchAllViableBottles; +extern CKKSAnalyticsActivity* const OctagonActivityFetchEscrowContents; +extern CKKSAnalyticsActivity* const OctagonActivityBottledPeerRestore; +extern CKKSAnalyticsActivity* const OctagonActivitySetRecoveryKey; +extern CKKSAnalyticsActivity* const OctagonActivityLeaveClique; +extern CKKSAnalyticsActivity* const OctagonActivityRemoveFriendsInClique; +extern CKKSAnalyticsActivity* const OctagonActivityJoinWithRecoveryKey; +extern CKKSAnalyticsActivity* const OctagonSOSAdapterUpdateKeys; + @interface CKKSAnalytics : SFAnalytics @@ -100,6 +204,9 @@ extern CKKSAnalyticsActivity* const CKKSActivityBottleCheck; zoneName:(NSString*)zoneName withAttributes:(NSDictionary *)attributes; +- (void)logRecoverableError:(NSError*)error + forEvent:(CKKSAnalyticsFailableEvent*)event + withAttributes:(NSDictionary *)attributes; - (void)logUnrecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event @@ -120,8 +227,13 @@ extern CKKSAnalyticsActivity* const CKKSActivityBottleCheck; @interface CKKSAnalytics (UnitTesting) -- (NSDate*)dateOfLastSuccessForEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view; -- (NSDictionary *)errorChain:(NSError *)error depth:(NSUInteger)depth; +- (NSDate*)dateOfLastSuccessForEvent:(CKKSAnalyticsFailableEvent*)event + inView:(CKKSKeychainView*)view; +- (NSDictionary *)errorChain:(NSError *)error + depth:(NSUInteger)depth; +- (NSDictionary *)createErrorAttributes:(NSError *)error + depth:(NSUInteger)depth + attributes:(NSDictionary *)attributes; @end diff --git a/keychain/ckks/CKKSAnalytics.m b/keychain/ckks/CKKSAnalytics.m index b512a7e8..8b37272d 100644 --- a/keychain/ckks/CKKSAnalytics.m +++ b/keychain/ckks/CKKSAnalytics.m @@ -47,6 +47,27 @@ NSString* const CKKSAnalyticsLastUnlock = @"lastUnlock"; NSString* const CKKSAnalyticsLastKeystateReady = @"lastKSR"; NSString* const CKKSAnalyticsLastInCircle = @"lastInCircle"; +NSString* const OctagonAnalyticsStateMachineState = @"OASMState"; +NSString* const OctagonAnalyticIcloudAccountState = @"OAiC"; +NSString* const OctagonAnalyticsTrustState = @"OATrust"; +NSString* const OctagonAnalyticsLastHealthCheck = @"OAHealthCheck"; +NSString* const OctagonAnalyticsSOSStatus = @"OASOSStatus"; +NSString* const OctagonAnalyticsDateOfLastPreflightPreapprovedJoin = @"OALastPPJ"; +NSString* const OctagonAnalyticsLastKeystateReady = @"OALastKSR"; +NSString* const OctagonAnalyticsLastCoreFollowup = @"OALastCFU"; +NSString* const OctagonAnalyticsCoreFollowupStatus = @"OACFUStatus"; +NSString* const OctagonAnalyticsCoreFollowupFailureCount = @"OACFUTFailureCount"; +NSString* const OctagonAnalyticsCoreFollowupLastFailureTime = @"OACFULastFailureTime"; +NSString* const OctagonAnalyticsPrerecordPending = @"OAPrerecordPending"; +NSString* const OctagonAnalyticsCDPStateRun = @"OACDPStateRun"; + +NSString* const OctagonAnalyticsKVSProvisioned = @"OADCKVSProvisioned"; +NSString* const OctagonAnalyticsKVSEnabled = @"OADCKVSEnabled"; +NSString* const OctagonAnalyticsKeychainSyncProvisioned = @"OADCKCSProvisioned"; +NSString* const OctagonAnalyticsKeychainSyncEnabled = @"OADCKCSEnabled"; +NSString* const OctagonAnalyticsCloudKitProvisioned = @"OADCCKProvisioned"; +NSString* const OctagonAnalyticsCloudKitEnabled = @"OADCCKEnabled"; + static NSString* const CKKSAnalyticsAttributeRecoverableError = @"recoverableError"; static NSString* const CKKSAnalyticsAttributeZoneName = @"zone"; static NSString* const CKKSAnalyticsAttributeErrorDomain = @"errorDomain"; @@ -59,6 +80,7 @@ CKKSAnalyticsFailableEvent* const CKKSEventProcessOutgoingQueue = (CKKSAnalytics CKKSAnalyticsFailableEvent* const CKKSEventUploadChanges = (CKKSAnalyticsFailableEvent*)@"CKKSEventUploadChanges"; CKKSAnalyticsFailableEvent* const CKKSEventStateError = (CKKSAnalyticsFailableEvent*)@"CKKSEventStateError"; CKKSAnalyticsFailableEvent* const CKKSEventProcessHealKeyHierarchy = (CKKSAnalyticsFailableEvent *)@"CKKSEventProcessHealKeyHierarchy"; +CKKSAnalyticsFailableEvent* const CKKSEventProcessReencryption = (CKKSAnalyticsFailableEvent *)@"CKKSEventProcessReencryption"; NSString* const OctagonEventFailureReason = @"FailureReason"; @@ -71,19 +93,87 @@ CKKSAnalyticsFailableEvent* const OctagonEventSignOut = (CKKSAnalyticsFailableEv CKKSAnalyticsFailableEvent* const OctagonEventRamp = (CKKSAnalyticsFailableEvent *)@"OctagonEventRamp"; CKKSAnalyticsFailableEvent* const OctagonEventBottleCheck = (CKKSAnalyticsFailableEvent *)@"OctagonEventBottleCheck"; CKKSAnalyticsFailableEvent* const OctagonEventCoreFollowUp = (CKKSAnalyticsFailableEvent *)@"OctagonEventCoreFollowUp"; +CKKSAnalyticsFailableEvent* const OctagonEventUpdateBottle = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpdateBottle"; + +CKKSAnalyticsFailableEvent* const OctagonEventCheckTrustState = (CKKSAnalyticsFailableEvent *)@"OctagonEventCheckTrustState"; + +CKKSAnalyticsFailableEvent* const OctagonEventBottledPeerRestore = (CKKSAnalyticsFailableEvent*)@"OctagonEventBottledPeerRestore"; +CKKSAnalyticsFailableEvent* const OctagonEventRecoveryKey = (CKKSAnalyticsFailableEvent*)@"OctagonEventRecoveryKey"; + +CKKSAnalyticsFailableEvent* const OctagonEventFetchAllBottles = (CKKSAnalyticsFailableEvent*)@"OctagonEventFetchAllBottles"; +CKKSAnalyticsFailableEvent* const OctagonEventFetchEscrowContents = (CKKSAnalyticsFailableEvent*)@"OctagonEventFetchEscrowContents"; +CKKSAnalyticsFailableEvent* const OctagonEventResetAndEstablish = (CKKSAnalyticsFailableEvent*)@"OctagonEventResetAndEstablish"; +CKKSAnalyticsFailableEvent* const OctagonEventEstablish = (CKKSAnalyticsFailableEvent*)@"OctagonEventEstablish"; +CKKSAnalyticsFailableEvent* const OctagonEventLeaveClique = (CKKSAnalyticsFailableEvent*)@"OctagonEventLeaveClique"; +CKKSAnalyticsFailableEvent* const OctagonEventRemoveFriendsInClique = (CKKSAnalyticsFailableEvent*)@"OctagonEventRemoveFriendsInClique"; + +CKKSAnalyticsFailableEvent* const OctagonEventUpgradeFetchDeviceIDs = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradeFetchDeviceIDs"; +CKKSAnalyticsFailableEvent* const OctagonEventUpgradeSetAllowList = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradeSetAllowList"; +CKKSAnalyticsFailableEvent* const OctagonEventUpgradeSilentEscrow = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradeSilentEscrow"; +CKKSAnalyticsFailableEvent* const OctagonEventUpgradePreapprovedJoin = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradePreapprovedJoin"; +CKKSAnalyticsFailableEvent* const OctagonEventUpgradePreflightPreapprovedJoin = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradePreflightPreapprovedJoin"; +CKKSAnalyticsFailableEvent* const OctagonEventUpgradePreapprovedJoinAfterPairing = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradePreapprovedJoinAfterPairing"; +CKKSAnalyticsFailableEvent* const OctagonEventUpgradePrepare = (CKKSAnalyticsFailableEvent*)@"OctagonEventUpgradePrepare"; + +CKKSAnalyticsFailableEvent* const OctagonEventJoinWithVoucher = (CKKSAnalyticsFailableEvent*)@"OctagonEventJoinWithVoucher"; + +CKKSAnalyticsFailableEvent* const OctagonEventVoucherWithBottle = (CKKSAnalyticsFailableEvent*)@"OctagonEventVoucherWithBottle"; + +CKKSAnalyticsFailableEvent* const OctagonEventVoucherWithRecoveryKey = (CKKSAnalyticsFailableEvent*)@"OctagonEventVoucherWithRecoveryKey"; + +CKKSAnalyticsFailableEvent* const OctagonEventSetRecoveryKey = (CKKSAnalyticsFailableEvent*)@"OctagonEventSetRecoveryKey"; + +CKKSAnalyticsFailableEvent* const OctagonEventSetRecoveryKeyValidationFailed = (CKKSAnalyticsFailableEvent*)@"OctagonEventSetRecoveryKeyValidationFailed"; +CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyValidationFailed = (CKKSAnalyticsFailableEvent*)@"OctagonEventJoinRecoveryKeyValidationFailed"; +CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyCircleReset = (CKKSAnalyticsFailableEvent*)@"OctagonEventJoinRecoveryKeyCircleReset"; +CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyCircleResetFailed = (CKKSAnalyticsFailableEvent*)@"OctagonEventJoinRecoveryKeyCircleResetFailed"; +CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyEnrollFailed = (CKKSAnalyticsFailableEvent*)@"OctagonEventJoinRecoveryKeyEnrollFailed"; +CKKSAnalyticsFailableEvent* const OctagonEventJoinRecoveryKeyFailed = (CKKSAnalyticsFailableEvent*)@"OctagonEventJoinRecoveryKeyFailed"; + +CKKSAnalyticsFailableEvent* const OctagonEventReset = (CKKSAnalyticsFailableEvent*)@"OctagonEventReset"; + +CKKSAnalyticsFailableEvent* const OctagonEventPrepareIdentity = (CKKSAnalyticsFailableEvent*)@"OctagonEventPrepareIdentity"; + +CKKSAnalyticsFailableEvent* const OctagonEventEstablishIdentity = (CKKSAnalyticsFailableEvent*)@"OctagonEventEstablishIdentity"; +CKKSAnalyticsFailableEvent* const OctagonEventFetchViews = (CKKSAnalyticsFailableEvent*)@"OctagonEventFetchViews"; + +CKKSAnalyticsFailableEvent* const OctagonEventStateTransition = (CKKSAnalyticsFailableEvent*)@"OctagonEventStateTransition"; + +CKKSAnalyticsFailableEvent* const OctagonEventCompanionPairing = (CKKSAnalyticsFailableEvent*)@"OctagonEventCompanionPairing"; + +CKKSAnalyticsFailableEvent* const OctagonEventCheckTrustForCFU = (CKKSAnalyticsFailableEvent*)@"OctagonEventCheckTrustForCFU"; CKKSAnalyticsSignpostEvent* const CKKSEventPushNotificationReceived = (CKKSAnalyticsSignpostEvent*)@"CKKSEventPushNotificationReceived"; CKKSAnalyticsSignpostEvent* const CKKSEventItemAddedToOutgoingQueue = (CKKSAnalyticsSignpostEvent*)@"CKKSEventItemAddedToOutgoingQueue"; CKKSAnalyticsSignpostEvent* const CKKSEventMissingLocalItemsFound = (CKKSAnalyticsSignpostEvent*)@"CKKSEventMissingLocalItemsFound"; CKKSAnalyticsSignpostEvent* const CKKSEventReachabilityTimerExpired = (CKKSAnalyticsSignpostEvent *)@"CKKSEventReachabilityTimerExpired"; +CKKSAnalyticsFailableEvent* const OctagonEventTPHHealthCheckStatus = (CKKSAnalyticsFailableEvent*)@"OctagonEventTPHHealthCheckStatus"; + CKKSAnalyticsActivity* const CKKSActivityOTFetchRampState = (CKKSAnalyticsActivity *)@"CKKSActivityOTFetchRampState"; -CKKSAnalyticsActivity* const CKKSActivityOctagonSignIn = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonSignIn"; CKKSAnalyticsActivity* const CKKSActivityOctagonPreflightBottle = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonPreflightBottle"; CKKSAnalyticsActivity* const CKKSActivityOctagonLaunchBottle = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonLaunchBottle"; CKKSAnalyticsActivity* const CKKSActivityOctagonRestore = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonRestore"; CKKSAnalyticsActivity* const CKKSActivityScrubBottle = (CKKSAnalyticsActivity *)@"CKKSActivityScrubBottle"; CKKSAnalyticsActivity* const CKKSActivityBottleCheck = (CKKSAnalyticsActivity *)@"CKKSActivityBottleCheck"; +CKKSAnalyticsActivity* const CKKSActivityOctagonUpdateBottle = (CKKSAnalyticsActivity *)@"CKKSActivityOctagonUpdateBottle"; + +CKKSAnalyticsActivity* const OctagonActivityAccountAvailable = (CKKSAnalyticsActivity *)@"OctagonActivityAccountAvailable"; +CKKSAnalyticsActivity* const OctagonActivityAccountNotAvailable = (CKKSAnalyticsActivity *)@"OctagonActivityAccountNotAvailable"; +CKKSAnalyticsActivity* const OctagonActivityResetAndEstablish = (CKKSAnalyticsActivity *)@"OctagonActivityResetAndEstablish"; +CKKSAnalyticsActivity* const OctagonActivityEstablish = (CKKSAnalyticsActivity *)@"OctagonActivityEstablish"; +CKKSAnalyticsActivity* const OctagonSOSAdapterUpdateKeys = (CKKSAnalyticsActivity*)@"OctagonSOSAdapterUpdateKeys"; + +CKKSAnalyticsActivity* const OctagonActivityFetchAllViableBottles = (CKKSAnalyticsActivity *)@"OctagonActivityFetchAllViableBottles"; +CKKSAnalyticsActivity* const OctagonActivityFetchEscrowContents = (CKKSAnalyticsActivity *)@"OctagonActivityFetchEscrowContents"; +CKKSAnalyticsActivity* const OctagonActivityBottledPeerRestore = (CKKSAnalyticsActivity *)@"OctagonActivityBottledPeerRestore"; +CKKSAnalyticsActivity* const OctagonActivitySetRecoveryKey = (CKKSAnalyticsActivity *)@"OctagonActivitySetRecoveryKey"; +CKKSAnalyticsActivity* const OctagonActivityJoinWithRecoveryKey = (CKKSAnalyticsActivity *)@"OctagonActivityJoinWithRecoveryKey"; + +CKKSAnalyticsActivity* const OctagonActivityLeaveClique = (CKKSAnalyticsActivity *)@"OctagonActivityLeaveClique"; +CKKSAnalyticsActivity* const OctagonActivityRemoveFriendsInClique = (CKKSAnalyticsActivity *)@"OctagonActivityRemoveFriendsInClique"; + + @implementation CKKSAnalytics @@ -163,6 +253,30 @@ CKKSAnalyticsActivity* const CKKSActivityBottleCheck = (CKKSAnalyticsActivity *) return errorDictionary; } + +- (NSDictionary *)createErrorAttributes:(NSError *)error + depth:(NSUInteger)depth + attributes:(NSDictionary *)attributes +{ + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + /* Don't allow caller to overwrite our attributes, lets merge them first */ + if (attributes) { + [eventAttributes setValuesForKeysWithDictionary:attributes]; + } + + [eventAttributes setValuesForKeysWithDictionary:@{ + CKKSAnalyticsAttributeRecoverableError : @(YES), + CKKSAnalyticsAttributeErrorDomain : error.domain, + CKKSAnalyticsAttributeErrorCode : @(error.code) + }]; + + eventAttributes[CKKSAnalyticsAttributeErrorChain] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:0]; + [self addCKPartialError:eventAttributes error:error depth:0]; + + return eventAttributes; +} + - (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event zoneName:(NSString*)zoneName withAttributes:(NSDictionary *)attributes { if (error == nil){ @@ -187,6 +301,31 @@ CKKSAnalyticsActivity* const CKKSActivityBottleCheck = (CKKSAnalyticsActivity *) [super logSoftFailureForEventNamed:event withAttributes:eventAttributes]; } + +- (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event withAttributes:(NSDictionary *)attributes +{ + if (error == nil){ + return; + } + NSMutableDictionary* eventAttributes = [NSMutableDictionary dictionary]; + + /* Don't allow caller to overwrite our attributes, lets merge them first */ + if (attributes) { + [eventAttributes setValuesForKeysWithDictionary:attributes]; + } + + [eventAttributes setValuesForKeysWithDictionary:@{ + CKKSAnalyticsAttributeRecoverableError : @(YES), + CKKSAnalyticsAttributeErrorDomain : error.domain, + CKKSAnalyticsAttributeErrorCode : @(error.code) + }]; + + eventAttributes[CKKSAnalyticsAttributeErrorChain] = [self errorChain:error.userInfo[NSUnderlyingErrorKey] depth:0]; + [self addCKPartialError:eventAttributes error:error depth:0]; + + [super logSoftFailureForEventNamed:event withAttributes:eventAttributes]; +} + - (void)logRecoverableError:(NSError*)error forEvent:(CKKSAnalyticsFailableEvent*)event inView:(CKKSKeychainView*)view withAttributes:(NSDictionary *)attributes { if (error == nil){ diff --git a/keychain/ckks/CKKSCloudKitClassDependencies.h b/keychain/ckks/CKKSCloudKitClassDependencies.h new file mode 100644 index 00000000..a0d75fe1 --- /dev/null +++ b/keychain/ckks/CKKSCloudKitClassDependencies.h @@ -0,0 +1,40 @@ + +#import + +#if OCTAGON + +#import "keychain/ckks/CKKSNotifier.h" +#import "keychain/ckks/CloudKitDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CKKSCloudKitClassDependencies : NSObject +@property (readonly) Class fetchRecordZoneChangesOperationClass; +@property (readonly) Class fetchRecordsOperationClass; +@property (readonly) Class queryOperationClass; +@property (readonly) Class modifySubscriptionsOperationClass; +@property (readonly) Class modifyRecordZonesOperationClass; +@property (readonly) Class apsConnectionClass; +@property (readonly) Class nsnotificationCenterClass; +@property (readonly) Class nsdistributednotificationCenterClass; +@property (readonly) Class notifierClass; + +- (instancetype)init NS_UNAVAILABLE; + ++ (CKKSCloudKitClassDependencies*) forLiveCloudKit; + +- (instancetype)initWithFetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass + fetchRecordsOperationClass:(Class)fetchRecordsOperationClass + queryOperationClass:(Class)queryOperationClass + modifySubscriptionsOperationClass:(Class)modifySubscriptionsOperationClass + modifyRecordZonesOperationClass:(Class)modifyRecordZonesOperationClass + apsConnectionClass:(Class)apsConnectionClass + nsnotificationCenterClass:(Class)nsnotificationCenterClass + nsdistributednotificationCenterClass:(Class)nsdistributednotificationCenterClass + notifierClass:(Class)notifierClass; +@end + + +NS_ASSUME_NONNULL_END + +#endif // Octagon diff --git a/keychain/ckks/CKKSCloudKitClassDependencies.m b/keychain/ckks/CKKSCloudKitClassDependencies.m new file mode 100644 index 00000000..c62e1e78 --- /dev/null +++ b/keychain/ckks/CKKSCloudKitClassDependencies.m @@ -0,0 +1,44 @@ + +#import "keychain/ckks/CKKSCloudKitClassDependencies.h" + +@implementation CKKSCloudKitClassDependencies + ++ (CKKSCloudKitClassDependencies*) forLiveCloudKit +{ + return [[CKKSCloudKitClassDependencies alloc] initWithFetchRecordZoneChangesOperationClass:[CKFetchRecordZoneChangesOperation class] + fetchRecordsOperationClass:[CKFetchRecordsOperation class] + queryOperationClass:[CKQueryOperation class] + modifySubscriptionsOperationClass:[CKModifySubscriptionsOperation class] + modifyRecordZonesOperationClass:[CKModifyRecordZonesOperation class] + apsConnectionClass:[APSConnection class] + nsnotificationCenterClass:[NSNotificationCenter class] + nsdistributednotificationCenterClass:[NSDistributedNotificationCenter class] + notifierClass:[CKKSNotifyPostNotifier class]]; +} + +- (instancetype)initWithFetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass + fetchRecordsOperationClass:(Class)fetchRecordsOperationClass + queryOperationClass:(Class)queryOperationClass + modifySubscriptionsOperationClass:(Class)modifySubscriptionsOperationClass + modifyRecordZonesOperationClass:(Class)modifyRecordZonesOperationClass + apsConnectionClass:(Class)apsConnectionClass + nsnotificationCenterClass:(Class)nsnotificationCenterClass + nsdistributednotificationCenterClass:(Class)nsdistributednotificationCenterClass + notifierClass:(Class)notifierClass +{ + if(self = [super init]) { + _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass; + _fetchRecordsOperationClass = fetchRecordsOperationClass; + _queryOperationClass = queryOperationClass; + _modifySubscriptionsOperationClass = modifySubscriptionsOperationClass; + _modifyRecordZonesOperationClass = modifyRecordZonesOperationClass; + _apsConnectionClass = apsConnectionClass; + _nsnotificationCenterClass = nsnotificationCenterClass; + _nsdistributednotificationCenterClass = nsdistributednotificationCenterClass; + _notifierClass = notifierClass; + } + return self; +} + +@end + diff --git a/keychain/ckks/CKKSConstants.m b/keychain/ckks/CKKSConstants.m new file mode 100644 index 00000000..f680d81b --- /dev/null +++ b/keychain/ckks/CKKSConstants.m @@ -0,0 +1,172 @@ + +#import +#include + +#import "keychain/ckks/CKKS.h" + +const SecCKKSItemEncryptionVersion currentCKKSItemEncryptionVersion = CKKSItemEncryptionVersion2; + +NSString* const SecCKKSActionAdd = @"add"; +NSString* const SecCKKSActionDelete = @"delete"; +NSString* const SecCKKSActionModify = @"modify"; + +CKKSItemState* const SecCKKSStateNew = (CKKSItemState*) @"new"; +CKKSItemState* const SecCKKSStateUnauthenticated = (CKKSItemState*) @"unauthenticated"; +CKKSItemState* const SecCKKSStateInFlight = (CKKSItemState*) @"inflight"; +CKKSItemState* const SecCKKSStateReencrypt = (CKKSItemState*) @"reencrypt"; +CKKSItemState* const SecCKKSStateError = (CKKSItemState*) @"error"; +CKKSItemState* const SecCKKSStateDeleted = (CKKSItemState*) @"deleted"; + +CKKSProcessedState* const SecCKKSProcessedStateLocal = (CKKSProcessedState*) @"local"; +CKKSProcessedState* const SecCKKSProcessedStateRemote = (CKKSProcessedState*) @"remote"; + +CKKSKeyClass* const SecCKKSKeyClassTLK = (CKKSKeyClass*) @"tlk"; +CKKSKeyClass* const SecCKKSKeyClassA = (CKKSKeyClass*) @"classA"; +CKKSKeyClass* const SecCKKSKeyClassC = (CKKSKeyClass*) @"classC"; + +NSString* SecCKKSContainerName = @"com.apple.security.keychain"; +bool SecCKKSContainerUsePCS = false; + +NSString* const SecCKKSSubscriptionID = @"keychain-changes"; +NSString* const SecCKKSAPSNamedPort = @"com.apple.securityd.aps"; + +NSString* const SecCKRecordItemType = @"item"; +NSString* const SecCKRecordHostOSVersionKey = @"uploadver"; +NSString* const SecCKRecordEncryptionVersionKey = @"encver"; +NSString* const SecCKRecordDataKey = @"data"; +NSString* const SecCKRecordParentKeyRefKey = @"parentkeyref"; +NSString* const SecCKRecordWrappedKeyKey = @"wrappedkey"; +NSString* const SecCKRecordGenerationCountKey = @"gen"; + +NSString* const SecCKRecordPCSServiceIdentifier = @"pcsservice"; +NSString* const SecCKRecordPCSPublicKey = @"pcspublickey"; +NSString* const SecCKRecordPCSPublicIdentity = @"pcspublicidentity"; +NSString* const SecCKRecordServerWasCurrent = @"server_wascurrent"; + +NSString* const SecCKRecordIntermediateKeyType = @"synckey"; +NSString* const SecCKRecordKeyClassKey = @"class"; + +NSString* const SecCKRecordTLKShareType = @"tlkshare"; +NSString* const SecCKRecordSenderPeerID = @"sender"; +NSString* const SecCKRecordReceiverPeerID = @"receiver"; +NSString* const SecCKRecordReceiverPublicEncryptionKey = @"receiverPublicEncryptionKey"; +NSString* const SecCKRecordCurve = @"curve"; +NSString* const SecCKRecordEpoch = @"epoch"; +NSString* const SecCKRecordPoisoned = @"poisoned"; +NSString* const SecCKRecordSignature = @"signature"; +NSString* const SecCKRecordVersion = @"version"; + +NSString* const SecCKRecordCurrentKeyType = @"currentkey"; + +NSString* const SecCKRecordCurrentItemType = @"currentitem"; +NSString* const SecCKRecordItemRefKey = @"item"; + +NSString* const SecCKRecordDeviceStateType = @"devicestate"; +NSString* const SecCKRecordOctagonPeerID = @"octagonpeerid"; +NSString* const SecCKRecordOctagonStatus = @"octagonstatus"; +NSString* const SecCKRecordCirclePeerID = @"peerid"; +NSString* const SecCKRecordCircleStatus = @"circle"; +NSString* const SecCKRecordKeyState = @"keystate"; +NSString* const SecCKRecordCurrentTLK = @"currentTLK"; +NSString* const SecCKRecordCurrentClassA = @"currentClassA"; +NSString* const SecCKRecordCurrentClassC = @"currentClassC"; +NSString* const SecCKSRecordLastUnlockTime = @"lastunlock"; +NSString* const SecCKSRecordOSVersionKey = @"osver"; + +NSString* const SecCKRecordManifestType = @"manifest"; +NSString* const SecCKRecordManifestDigestValueKey = @"digest_value"; +NSString* const SecCKRecordManifestGenerationCountKey = @"generation_count"; +NSString* const SecCKRecordManifestLeafRecordIDsKey = @"leaf_records"; +NSString* const SecCKRecordManifestPeerManifestRecordIDsKey = @"peer_manifests"; +NSString* const SecCKRecordManifestCurrentItemsKey = @"current_items"; +NSString* const SecCKRecordManifestSignaturesKey = @"signatures"; +NSString* const SecCKRecordManifestSignerIDKey = @"signer_id"; +NSString* const SecCKRecordManifestSchemaKey = @"schema"; + +NSString* const SecCKRecordManifestLeafType = @"manifest_leaf"; +NSString* const SecCKRecordManifestLeafDERKey = @"der"; +NSString* const SecCKRecordManifestLeafDigestKey = @"digest"; + +CKKSZoneKeyState* const SecCKKSZoneKeyStateReady = (CKKSZoneKeyState*) @"ready"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateReadyPendingUnlock = (CKKSZoneKeyState*) @"readypendingunlock"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateError = (CKKSZoneKeyState*) @"error"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateCancelled = (CKKSZoneKeyState*) @"cancelled"; + +CKKSZoneKeyState* const SecCKKSZoneKeyStateInitializing = (CKKSZoneKeyState*) @"initializing"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateInitialized = (CKKSZoneKeyState*) @"initialized"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateFetch = (CKKSZoneKeyState*) @"fetching"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateFetchComplete = (CKKSZoneKeyState*) @"fetchcomplete"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateNeedFullRefetch = (CKKSZoneKeyState*) @"needrefetch"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLK = (CKKSZoneKeyState*) @"waitfortlk"; + +CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLKCreation = (CKKSZoneKeyState*) @"waitfortlkcreation"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTLKUpload = (CKKSZoneKeyState*) @"waitfortlkupload"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForUnlock = (CKKSZoneKeyState*) @"waitforunlock"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForTrust = (CKKSZoneKeyState*) @"waitfortrust"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateUnhealthy = (CKKSZoneKeyState*) @"unhealthy"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateBadCurrentPointers = (CKKSZoneKeyState*) @"badcurrentpointers"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateNewTLKsFailed = (CKKSZoneKeyState*) @"newtlksfailed"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKShares = (CKKSZoneKeyState*) @"healtlkshares"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateHealTLKSharesFailed = (CKKSZoneKeyState*) @"healtlksharesfailed"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateWaitForFixupOperation = (CKKSZoneKeyState*) @"waitforfixupoperation"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingZone = (CKKSZoneKeyState*) @"resetzone"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateResettingLocalData = (CKKSZoneKeyState*) @"resetlocal"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateLoggedOut = (CKKSZoneKeyState*) @"loggedout"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateZoneCreationFailed = (CKKSZoneKeyState*) @"zonecreationfailed"; +CKKSZoneKeyState* const SecCKKSZoneKeyStateProcess = (CKKSZoneKeyState*) @"process"; + +NSString* const CKKSErrorDomain = @"CKKSErrorDomain"; +NSString* const CKKSServerExtensionErrorDomain = @"CKKSServerExtensionErrorDomain"; + +const NSUInteger SecCKKSItemPaddingBlockSize = 20; + +NSString* const SecCKKSAggdPropagationDelay = @"com.apple.security.ckks.propagationdelay"; +NSString* const SecCKKSAggdPrimaryKeyConflict = @"com.apple.security.ckks.pkconflict"; +NSString* const SecCKKSAggdViewKeyCount = @"com.apple.security.ckks.keycount"; +NSString* const SecCKKSAggdItemReencryption = @"com.apple.security.ckks.reencrypt"; + +NSString* const SecCKKSUserDefaultsSuite = @"com.apple.security.ckks"; + +NSString* SecCKKSHostOSVersion() +{ +#ifdef PLATFORM + // Use complicated macro magic to get the string value passed in as preprocessor define PLATFORM. +#define PLATFORM_VALUE(f) #f +#define PLATFORM_OBJCSTR(f) @PLATFORM_VALUE(f) + NSString* platform = (PLATFORM_OBJCSTR(PLATFORM)); +#undef PLATFORM_OBJCSTR +#undef PLATFORM_VALUE +#else + NSString* platform = "unknown"; +#warning No PLATFORM defined; why? +#endif + + NSString* osversion = nil; + + // If we can get the build information from sysctl, use it. + char release[256]; + size_t releasesize = sizeof(release); + bool haveSysctlInfo = true; + haveSysctlInfo &= (0 == sysctlbyname("kern.osrelease", release, &releasesize, NULL, 0)); + + char version[256]; + size_t versionsize = sizeof(version); + haveSysctlInfo &= (0 == sysctlbyname("kern.osversion", version, &versionsize, NULL, 0)); + + if(haveSysctlInfo) { + // Null-terminate for extra safety + release[sizeof(release)-1] = '\0'; + version[sizeof(version)-1] = '\0'; + osversion = [NSString stringWithFormat:@"%s (%s)", release, version]; + } + + if(!osversion) { + // Otherwise, use the not-really-supported fallback. + osversion = [[NSProcessInfo processInfo] operatingSystemVersionString]; + + // subtly improve osversion (but it's okay if that does nothing) + osversion = [osversion stringByReplacingOccurrencesOfString:@"Version" withString:@""]; + } + + return [NSString stringWithFormat:@"%@ %@", platform, osversion]; +} diff --git a/keychain/ckks/CKKSControl.h b/keychain/ckks/CKKSControl.h index 98849613..7a071d0a 100644 --- a/keychain/ckks/CKKSControl.h +++ b/keychain/ckks/CKKSControl.h @@ -33,10 +33,13 @@ typedef NS_ENUM(NSUInteger, CKKSKnownBadState) { CKKSKnownStatePossiblyGood = 0, // State might be good: give your operation a shot! CKKSKnownStateTLKsMissing = 1, // CKKS doesn't have the TLKs: your operation will likely not succeed CKKSKnownStateWaitForUnlock = 2, // CKKS has some important things to do, but the device is locked. Your operation will likely not succeed + CKKSKnownStateWaitForOctagon = 3, // CKKS has important things to do, but Octagon hasn't done them yet. Your operation will likely not succeed }; @interface CKKSControl : NSObject +@property (readonly,assign) BOOL synchronous; + - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithConnection:(NSXPCConnection*)connection; @@ -45,21 +48,22 @@ typedef NS_ENUM(NSUInteger, CKKSKnownBadState) { - (void)rpcFastStatus:(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 __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; - (void)rpcPushOutgoingChanges:(NSString* _Nullable)viewName reply:(void (^)(NSError* _Nullable error))reply; +- (void)rpcCKMetric:(NSString *)eventName attributes:(NSDictionary *)attributes reply:(void(^)(NSError* error))reply; -- (void)rpcPerformanceCounters:(void(^)(NSDictionary *,NSError*))reply; -- (void)rpcGetCKDeviceIDWithReply:(void (^)(NSString* ckdeviceID))reply; +- (void)rpcPerformanceCounters: (void(^)(NSDictionary *,NSError*))reply; +- (void)rpcGetCKDeviceIDWithReply: (void (^)(NSString* ckdeviceID))reply; // convenience wrapper for rpcStatus:reply: - (void)rpcTLKMissing:(NSString* _Nullable)viewName reply:(void (^)(bool missing))reply; - (void)rpcKnownBadState:(NSString* _Nullable)viewName reply:(void (^)(CKKSKnownBadState))reply; + (CKKSControl* _Nullable)controlObject:(NSError* _Nullable __autoreleasing* _Nullable)error; ++ (CKKSControl* _Nullable)CKKSControlObject:(BOOL)sync error:(NSError* _Nullable __autoreleasing* _Nullable)error; @end diff --git a/keychain/ckks/CKKSControl.m b/keychain/ckks/CKKSControl.m index 1407f25c..f4d75de7 100644 --- a/keychain/ckks/CKKSControl.m +++ b/keychain/ckks/CKKSControl.m @@ -35,6 +35,7 @@ #include @interface CKKSControl () +@property (readwrite,assign) BOOL synchronous; @property xpc_endpoint_t endpoint; @property NSXPCConnection *connection; @end @@ -48,8 +49,17 @@ return self; } +- (id)objectProxyWithErrorHandler:(void(^)(NSError * _Nonnull error))failureHandler +{ + if (self.synchronous) { + return [self.connection synchronousRemoteObjectProxyWithErrorHandler:failureHandler]; + } else { + return [self.connection remoteObjectProxyWithErrorHandler:failureHandler]; + } +} + - (void)rpcStatus:(NSString*)viewName reply:(void(^)(NSArray* result, NSError* error)) reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self objectProxyWithErrorHandler: ^(NSError* error) { reply(nil, error); }] rpcStatus:viewName reply:^(NSArray* result, NSError* error){ @@ -58,7 +68,7 @@ } - (void)rpcFastStatus:(NSString*)viewName reply:(void(^)(NSArray* result, NSError* error)) reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self objectProxyWithErrorHandler: ^(NSError* error) { reply(nil, error); }] rpcFastStatus:viewName reply:^(NSArray* result, NSError* error){ @@ -68,23 +78,15 @@ - (void)rpcResetLocal:(NSString*)viewName reply:(void(^)(NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + [[self objectProxyWithErrorHandler:^(NSError* error) { reply(error); }] rpcResetLocal:viewName reply:^(NSError* error){ reply(error); }]; } -- (void)rpcResetCloudKit:(NSString*)viewName reply:(void(^)(NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { - reply(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) { + [[self objectProxyWithErrorHandler:^(NSError* error) { reply(error); }] rpcResetCloudKit:viewName reason:reason reply:^(NSError* error){ reply(error); @@ -93,36 +95,44 @@ - (void)rpcResync:(NSString*)viewName reply:(void(^)(NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + [[self objectProxyWithErrorHandler:^(NSError* error) { reply(error); }] rpcResync:viewName reply:^(NSError* error){ reply(error); }]; } - (void)rpcFetchAndProcessChanges:(NSString*)viewName reply:(void(^)(NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + [[self objectProxyWithErrorHandler:^(NSError* error) { reply(error); }] rpcFetchAndProcessChanges:viewName reply:^(NSError* error){ reply(error); }]; } - (void)rpcFetchAndProcessClassAChanges:(NSString*)viewName reply:(void(^)(NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + [[self objectProxyWithErrorHandler:^(NSError* error) { reply(error); }] rpcFetchAndProcessClassAChanges:viewName reply:^(NSError* error){ reply(error); }]; } - (void)rpcPushOutgoingChanges:(NSString*)viewName reply:(void(^)(NSError* error))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError* error) { + [[self objectProxyWithErrorHandler:^(NSError* error) { reply(error); }] rpcPushOutgoingChanges:viewName reply:^(NSError* error){ reply(error); }]; } +- (void)rpcCKMetric:(NSString *)eventName attributes:(NSDictionary *)attributes reply:(void(^)(NSError* error))reply { + [[self objectProxyWithErrorHandler:^(NSError* error) { + reply(error); + }] rpcCKMetric:eventName attributes:attributes reply:^(NSError* error){ + reply(error); + }]; +} + - (void)rpcPerformanceCounters:(void(^)(NSDictionary *,NSError*))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self objectProxyWithErrorHandler: ^(NSError* error) { reply(nil, error); }] performanceCounters:^(NSDictionary *counters){ reply(counters, nil); @@ -130,7 +140,7 @@ } - (void)rpcGetCKDeviceIDWithReply:(void (^)(NSString *))reply { - [[self.connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + [[self objectProxyWithErrorHandler:^(NSError * _Nonnull error) { reply(nil); }] rpcGetCKDeviceIDWithReply:^(NSString *ckdeviceID) { reply(ckdeviceID); @@ -163,6 +173,7 @@ [self rpcFastStatus:viewName reply:^(NSArray* results, NSError* blockError) { bool tlkMissing = false; bool waitForUnlock = false; + bool waitForOctagon = false; CKKSKnownBadState response = CKKSKnownStatePossiblyGood; @@ -181,17 +192,27 @@ if ([keystate isEqualToString:@"waitforunlock"]) { waitForUnlock = true; } + + if([keystate isEqualToString:@"waitfortlkcreation"] || + [keystate isEqualToString:@"waitfortlkupload"]) { + waitForOctagon = true; + } } response = (tlkMissing ? CKKSKnownStateTLKsMissing : (waitForUnlock ? CKKSKnownStateWaitForUnlock : - CKKSKnownStatePossiblyGood)); + (waitForOctagon ? CKKSKnownStateWaitForOctagon : + CKKSKnownStatePossiblyGood))); reply(response); }]; } + (CKKSControl*)controlObject:(NSError* __autoreleasing *)error { + return [CKKSControl CKKSControlObject:NO error:error]; +} + ++ (CKKSControl*)CKKSControlObject:(BOOL)synchronous error:(NSError* __autoreleasing *)error { NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydCKKSServiceName) options:0]; @@ -207,6 +228,7 @@ [connection resume]; CKKSControl* c = [[CKKSControl alloc] initWithConnection:connection]; + c.synchronous = synchronous; return c; } diff --git a/keychain/ckks/CKKSControlProtocol.h b/keychain/ckks/CKKSControlProtocol.h index 5b7054ca..d96fae7b 100644 --- a/keychain/ckks/CKKSControlProtocol.h +++ b/keychain/ckks/CKKSControlProtocol.h @@ -26,7 +26,6 @@ @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 __deprecated_msg("use rpcResetCloudKit:reason:reply"); /** * Reset CloudKit zone with a caller provided reason, the reason will be logged in the operation group @@ -47,6 +46,7 @@ - (void)rpcFetchAndProcessClassAChanges:(NSString*)viewName reply: (void(^)(NSError* result)) reply; - (void)rpcPushOutgoingChanges:(NSString*)viewName reply: (void(^)(NSError* result)) reply; - (void)rpcGetCKDeviceIDWithReply: (void (^)(NSString* ckdeviceID))reply; +- (void)rpcCKMetric:(NSString *)eventName attributes:(NSDictionary *)attributes reply:(void(^)(NSError* result)) reply; @end NSXPCInterface* CKKSSetupControlProtocol(NSXPCInterface* interface); diff --git a/keychain/ckks/CKKSControlProtocol.m b/keychain/ckks/CKKSControlProtocol.m index de2a7b2b..648b8253 100644 --- a/keychain/ckks/CKKSControlProtocol.m +++ b/keychain/ckks/CKKSControlProtocol.m @@ -93,8 +93,6 @@ 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]; diff --git a/keychain/ckks/CKKSCurrentItemPointer.h b/keychain/ckks/CKKSCurrentItemPointer.h index afc5b61a..8d9c4d5d 100644 --- a/keychain/ckks/CKKSCurrentItemPointer.h +++ b/keychain/ckks/CKKSCurrentItemPointer.h @@ -29,6 +29,8 @@ #if OCTAGON +NS_ASSUME_NONNULL_BEGIN + @interface CKKSCurrentItemPointer : CKKSCKRecordHolder @property CKKSProcessedState* state; @@ -39,7 +41,7 @@ currentItemUUID:(NSString*)currentItemUUID state:(CKKSProcessedState*)state zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord; + encodedCKRecord:(NSData* _Nullable)encodedrecord; + (instancetype)fromDatabase:(NSString*)identifier state:(CKKSProcessedState*)state @@ -56,4 +58,6 @@ @end +NS_ASSUME_NONNULL_END + #endif diff --git a/keychain/ckks/CKKSCurrentItemPointer.m b/keychain/ckks/CKKSCurrentItemPointer.m index 646a5291..cf03a4a3 100644 --- a/keychain/ckks/CKKSCurrentItemPointer.m +++ b/keychain/ckks/CKKSCurrentItemPointer.m @@ -52,6 +52,13 @@ } - (CKRecord*)updateCKRecord: (CKRecord*) record zoneID: (CKRecordZoneID*) zoneID { + if(![record.recordType isEqualToString: SecCKRecordCurrentItemType]) { + @throw [NSException + exceptionWithName:@"WrongCKRecordTypeException" + reason:[NSString stringWithFormat: @"CKRecordType (%@) was not %@", record.recordType, SecCKRecordCurrentItemType] + userInfo:nil]; + } + // The record name should already match identifier... if(![record.recordID.recordName isEqualToString: self.identifier]) { @throw [NSException @@ -148,12 +155,12 @@ }; } -+ (instancetype)fromDatabaseRow: (NSDictionary*) row { - return [[CKKSCurrentItemPointer alloc] initForIdentifier:row[@"identifier"] - currentItemUUID:CKKSNSNullToNil(row[@"currentItemUUID"]) - state:CKKSNSNullToNil(row[@"state"]) - zoneID:[[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"] ownerName:CKCurrentUserDefaultName] - encodedCKRecord:[[NSData alloc] initWithBase64EncodedString: row[@"ckrecord"] options:0]]; ++ (instancetype)fromDatabaseRow:(NSDictionary*) row { + return [[CKKSCurrentItemPointer alloc] initForIdentifier:row[@"identifier"].asString + currentItemUUID:row[@"currentItemUUID"].asString + state:(CKKSProcessedState*)row[@"state"].asString + zoneID:[[CKRecordZoneID alloc] initWithZoneName:row[@"ckzone"].asString ownerName:CKCurrentUserDefaultName] + encodedCKRecord:row[@"ckrecord"].asBase64DecodedData]; } @end diff --git a/keychain/ckks/CKKSCurrentKeyPointer.h b/keychain/ckks/CKKSCurrentKeyPointer.h index 99bfb5e8..7f8cc8cf 100644 --- a/keychain/ckks/CKKSCurrentKeyPointer.h +++ b/keychain/ckks/CKKSCurrentKeyPointer.h @@ -26,20 +26,22 @@ #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSItem.h" #import "keychain/ckks/CKKSKey.h" -#import "keychain/ckks/CKKSTLKShare.h" - +#import "keychain/ckks/CKKSTLKShareRecord.h" +#import "keychain/ckks/CKKSResultOperation.h" #if OCTAGON +NS_ASSUME_NONNULL_BEGIN + @interface CKKSCurrentKeyPointer : CKKSCKRecordHolder @property CKKSKeyClass* keyclass; @property NSString* currentKeyUUID; - (instancetype)initForClass:(CKKSKeyClass*)keyclass - currentKeyUUID:(NSString*)currentKeyUUID + currentKeyUUID:(NSString* _Nullable)currentKeyUUID zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord; + encodedCKRecord:(NSData* _Nullable)encodedrecord; + (instancetype)fromDatabase:(CKKSKeyClass*)keyclass zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; + (instancetype)tryFromDatabase:(CKKSKeyClass*)keyclass zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; @@ -55,18 +57,32 @@ @end @interface CKKSCurrentKeySet : NSObject -@property NSError* error; -@property CKKSKey* tlk; -@property CKKSKey* classA; -@property CKKSKey* classC; -@property CKKSCurrentKeyPointer* currentTLKPointer; -@property CKKSCurrentKeyPointer* currentClassAPointer; -@property CKKSCurrentKeyPointer* currentClassCPointer; - -@property NSArray* tlkShares; - -- (instancetype)init; -- (instancetype)initForZone:(CKRecordZoneID*)zoneID; + +@property NSString* viewName; +@property (nullable) NSError* error; +@property (nullable) CKKSKey* tlk; +@property (nullable) CKKSKey* classA; +@property (nullable) CKKSKey* classC; +@property (nullable) CKKSCurrentKeyPointer* currentTLKPointer; +@property (nullable) CKKSCurrentKeyPointer* currentClassAPointer; +@property (nullable) CKKSCurrentKeyPointer* currentClassCPointer; + +// Set to true if this is a 'proposed' key set, i.e., not yet uploaded to CloudKit +@property BOOL proposed; + +// The tlkShares property holds all existing tlkShares for this key +@property NSArray* tlkShares; + +// This array (if present) holds any new TLKShares that should be uploaded +@property (nullable) NSArray* pendingTLKShares; + +- (instancetype)initForZoneName:(NSString*)zoneName; + ++ (CKKSCurrentKeySet*)loadForZone:(CKRecordZoneID*)zoneID; + +- (CKKSKeychainBackedKeySet* _Nullable)asKeychainBackedSet:(NSError**)error; @end +NS_ASSUME_NONNULL_END + #endif diff --git a/keychain/ckks/CKKSCurrentKeyPointer.m b/keychain/ckks/CKKSCurrentKeyPointer.m index 0d556eb1..78a935ad 100644 --- a/keychain/ckks/CKKSCurrentKeyPointer.m +++ b/keychain/ckks/CKKSCurrentKeyPointer.m @@ -25,6 +25,8 @@ #if OCTAGON +#import "keychain/categories/NSError+UsefulConstructors.h" + @implementation CKKSCurrentKeyPointer - (instancetype)initForClass:(CKKSKeyClass*)keyclass @@ -73,6 +75,13 @@ } - (CKRecord*) updateCKRecord: (CKRecord*) record zoneID: (CKRecordZoneID*) zoneID { + if(![record.recordType isEqualToString: SecCKRecordCurrentKeyType]) { + @throw [NSException + exceptionWithName:@"WrongCKRecordTypeException" + reason:[NSString stringWithFormat: @"CKRecordType (%@) was not %@", record.recordType, SecCKRecordCurrentKeyType] + userInfo:nil]; + } + // The record name should already match keyclass... if(![record.recordID.recordName isEqualToString: self.keyclass]) { @throw [NSException @@ -186,54 +195,64 @@ }; } -+ (instancetype) fromDatabaseRow: (NSDictionary*) row { - return [[CKKSCurrentKeyPointer alloc] initForClass: row[@"keyclass"] - currentKeyUUID: [row[@"currentKeyUUID"] isEqual: [NSNull null]] ? nil : row[@"currentKeyUUID"] - zoneID: [[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"] ownerName:CKCurrentUserDefaultName] - encodedCKRecord: [[NSData alloc] initWithBase64EncodedString: row[@"ckrecord"] options:0]]; ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + return [[CKKSCurrentKeyPointer alloc] initForClass:(CKKSKeyClass*)row[@"keyclass"].asString + currentKeyUUID:row[@"currentKeyUUID"].asString + zoneID:[[CKRecordZoneID alloc] initWithZoneName:row[@"ckzone"].asString ownerName:CKCurrentUserDefaultName] + encodedCKRecord:row[@"ckrecord"].asBase64DecodedData]; } @end @implementation CKKSCurrentKeySet --(instancetype)init { +-(instancetype)initForZoneName:(NSString*)zoneName { if((self = [super init])) { + _viewName = zoneName; } return self; } --(instancetype)initForZone:(CKRecordZoneID*)zoneID { - if((self = [super init])) { - NSError* error = nil; - _currentTLKPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassTLK zoneID:zoneID error:&error]; - _currentClassAPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassA zoneID:zoneID error:&error]; - _currentClassCPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassC zoneID:zoneID error:&error]; - _tlk = _currentTLKPointer.currentKeyUUID ? [CKKSKey tryFromDatabase:_currentTLKPointer.currentKeyUUID zoneID:zoneID error:&error] : nil; - _classA = _currentClassAPointer.currentKeyUUID ? [CKKSKey tryFromDatabase:_currentClassAPointer.currentKeyUUID zoneID:zoneID error:&error] : nil; - _classC = _currentClassCPointer.currentKeyUUID ? [CKKSKey tryFromDatabase:_currentClassCPointer.currentKeyUUID zoneID:zoneID error:&error] : nil; ++ (CKKSCurrentKeySet*)loadForZone:(CKRecordZoneID*)zoneID +{ + CKKSCurrentKeySet* set = [[CKKSCurrentKeySet alloc] initForZoneName:zoneID.zoneName]; + NSError* error = nil; - _tlkShares = [CKKSTLKShare allForUUID:_currentTLKPointer.currentKeyUUID zoneID:zoneID error:&error]; + set.currentTLKPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassTLK zoneID:zoneID error:&error]; + set.currentClassAPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassA zoneID:zoneID error:&error]; + set.currentClassCPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassC zoneID:zoneID error:&error]; - _error = error; + set.tlk = set.currentTLKPointer.currentKeyUUID ? [CKKSKey tryFromDatabase:set.currentTLKPointer.currentKeyUUID zoneID:zoneID error:&error] : nil; + set.classA = set.currentClassAPointer.currentKeyUUID ? [CKKSKey tryFromDatabase:set.currentClassAPointer.currentKeyUUID zoneID:zoneID error:&error] : nil; + set.classC = set.currentClassCPointer.currentKeyUUID ? [CKKSKey tryFromDatabase:set.currentClassCPointer.currentKeyUUID zoneID:zoneID error:&error] : nil; - } + set.tlkShares = [CKKSTLKShareRecord allForUUID:set.currentTLKPointer.currentKeyUUID zoneID:zoneID error:&error]; + set.pendingTLKShares = nil; - return self; + set.proposed = NO; + + set.error = error; + + return set; } + -(NSString*)description { if(self.error) { - return [NSString stringWithFormat:@"", + return [NSString stringWithFormat:@"", + self.viewName, self.currentTLKPointer.currentKeyUUID, self.tlk, self.currentClassAPointer.currentKeyUUID, self.classA, self.currentClassCPointer.currentKeyUUID, self.classC, + self.proposed, self.error]; } else { - return [NSString stringWithFormat:@"", + return [NSString stringWithFormat:@"", + self.viewName, self.currentTLKPointer.currentKeyUUID, self.tlk, self.currentClassAPointer.currentKeyUUID, self.classA, - self.currentClassCPointer.currentKeyUUID, self.classC]; + self.currentClassCPointer.currentKeyUUID, self.classC, + self.proposed]; } } - (instancetype)copyWithZone:(NSZone*)zone { @@ -244,10 +263,30 @@ copy.tlk = [self.tlk copyWithZone:zone]; copy.classA = [self.classA copyWithZone:zone]; copy.classC = [self.classC copyWithZone:zone]; + copy.proposed = self.proposed; copy.error = [self.error copyWithZone:zone]; return copy; } + +- (CKKSKeychainBackedKeySet* _Nullable)asKeychainBackedSet:(NSError**)error +{ + if(!self.tlk.keycore || + !self.classA.keycore || + !self.classC.keycore) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSKeysMissing + description:@"unable to make keychain backed set; key is missing"]; + } + return nil; + } + + return [[CKKSKeychainBackedKeySet alloc] initWithTLK:self.tlk.keycore + classA:self.classA.keycore + classC:self.classC.keycore + newUpload:self.proposed]; +} @end #endif // OCTAGON diff --git a/keychain/ckks/CKKSDeviceStateEntry.h b/keychain/ckks/CKKSDeviceStateEntry.h index d2215ad4..16230793 100644 --- a/keychain/ckks/CKKSDeviceStateEntry.h +++ b/keychain/ckks/CKKSDeviceStateEntry.h @@ -32,9 +32,11 @@ #import #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSRecordHolder.h" -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #import "keychain/ckks/CKKSSQLDatabaseObject.h" +#import "keychain/ot/OTClique.h" + NS_ASSUME_NONNULL_BEGIN /* @@ -73,7 +75,7 @@ NS_ASSUME_NONNULL_BEGIN + (NSArray*)allInZone:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; - (instancetype)init NS_UNAVAILABLE; -- (instancetype)initForDevice:(NSString* _Nullable)device +- (instancetype)initForDevice:(NSString*)device osVersion:(NSString* _Nullable)osVersion lastUnlockTime:(NSDate* _Nullable)lastUnlockTime octagonPeerID:(NSString* _Nullable)octagonPeerID diff --git a/keychain/ckks/CKKSDeviceStateEntry.m b/keychain/ckks/CKKSDeviceStateEntry.m index 9c33721c..557de53c 100644 --- a/keychain/ckks/CKKSDeviceStateEntry.m +++ b/keychain/ckks/CKKSDeviceStateEntry.m @@ -31,7 +31,7 @@ #import #import "keychain/ckks/CKKSDeviceStateEntry.h" #import "keychain/ckks/CKKSKeychainView.h" -#include +#include "keychain/SecureObjectSync/SOSAccount.h" @implementation CKKSDeviceStateEntry @@ -121,7 +121,7 @@ return [NSNumber numberWithInt:(int)status.status]; } -+ (OTCliqueStatusWrapper* _Nullable)cktypeToOTCliqueStatusWrapper:(id)object { +- (OTCliqueStatusWrapper* _Nullable)cktypeToOTCliqueStatusWrapper:(id)object { if(object == nil) { return nil; } @@ -294,7 +294,7 @@ } if((!(self.octagonStatus == nil && record[SecCKRecordOctagonStatus] == nil)) && - [self.octagonStatus isEqual: [CKKSDeviceStateEntry cktypeToOTCliqueStatusWrapper:record[SecCKRecordOctagonStatus]]]) { + [self.octagonStatus isEqual: [self cktypeToOTCliqueStatusWrapper:record[SecCKRecordOctagonStatus]]]) { return false; } @@ -334,7 +334,7 @@ self.device = [CKKSDeviceStateEntry nameFromCKRecordID: record.recordID]; self.octagonPeerID = record[SecCKRecordOctagonPeerID]; - self.octagonStatus = [CKKSDeviceStateEntry cktypeToOTCliqueStatusWrapper:record[SecCKRecordOctagonStatus]]; + self.octagonStatus = [self cktypeToOTCliqueStatusWrapper:record[SecCKRecordOctagonStatus]]; self.circlePeerID = record[SecCKRecordCirclePeerID]; @@ -354,9 +354,10 @@ } + (NSArray*)sqlColumns { - // NOTE: due to schedule reasons, in this release we can't modify the DB schema, so octagon status and peer ID can't be stored - // in normal columns. So, they're stored in the ckrecord field. Good luck! - return @[@"device", @"ckzone", @"osversion", @"lastunlock", @"peerid", @"circlestatus", @"keystate", @"currentTLK", @"currentClassA", @"currentClassC", @"ckrecord"]; + return @[@"device", @"ckzone", @"osversion", @"lastunlock", + @"peerid", @"circlestatus", + @"octagonpeerid", @"octagonstatus", + @"keystate", @"currentTLK", @"currentClassA", @"currentClassC", @"ckrecord"]; } - (NSDictionary*)whereClauseToFindSelf { @@ -372,6 +373,8 @@ @"lastunlock": CKKSNilToNSNull(self.lastUnlockTime ? [dateFormat stringFromDate:self.lastUnlockTime] : nil), @"peerid": CKKSNilToNSNull(self.circlePeerID), @"circlestatus": (__bridge NSString*)SOSAccountGetSOSCCStatusString(self.circleStatus), + @"octagonpeerid": CKKSNilToNSNull(self.octagonPeerID), + @"octagonstatus": CKKSNilToNSNull(self.octagonStatus ? OTCliqueStatusToString(self.octagonStatus.status) : nil), @"keystate": CKKSNilToNSNull(self.keyState), @"currentTLK": CKKSNilToNSNull(self.currentTLKUUID), @"currentClassA": CKKSNilToNSNull(self.currentClassAUUID), @@ -380,34 +383,27 @@ }; } -+ (instancetype)fromDatabaseRow:(NSDictionary*)row { - NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; - - CKKSDeviceStateEntry* entry = - [[CKKSDeviceStateEntry alloc] initForDevice:row[@"device"] - osVersion:CKKSNSNullToNil(row[@"osversion"]) - lastUnlockTime:[row[@"lastunlock"] isEqual: [NSNull null]] ? nil : [dateFormat dateFromString: row[@"lastunlock"]] - octagonPeerID:nil - octagonStatus:nil - circlePeerID:CKKSNSNullToNil(row[@"peerid"]) - circleStatus:SOSAccountGetSOSCCStatusFromString((__bridge CFStringRef) CKKSNSNullToNil(row[@"circlestatus"])) - keyState:CKKSNSNullToNil(row[@"keystate"]) - currentTLKUUID:CKKSNSNullToNil(row[@"currentTLK"]) - currentClassAUUID:CKKSNSNullToNil(row[@"currentClassA"]) - currentClassCUUID:CKKSNSNullToNil(row[@"currentClassC"]) - zoneID:[[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"] ownerName:CKCurrentUserDefaultName] - encodedCKRecord:CKKSUnbase64NullableString(row[@"ckrecord"]) - ]; - - // NOTE: due to schedule reasons, in this release we can't modify the DB schema, so octagon status and peer ID can't be stored - // in normal columns. So, if they're stored in the ckrecord field, use that! - CKRecord* record = entry.storedCKRecord; - if(record) { - entry.octagonPeerID = record[SecCKRecordOctagonPeerID]; - entry.octagonStatus = [self cktypeToOTCliqueStatusWrapper:record[SecCKRecordOctagonStatus]]; ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + OTCliqueStatusWrapper* octagonStatus = nil; + NSString* octagonStatusString = row[@"octagonstatus"].asString; + if(octagonStatusString) { + octagonStatus = [[OTCliqueStatusWrapper alloc] initWithStatus:OTCliqueStatusFromString(octagonStatusString)]; } - return entry; + return [[CKKSDeviceStateEntry alloc] initForDevice:row[@"device"].asString + osVersion:row[@"osversion"].asString + lastUnlockTime:row[@"lastunlock"].asISO8601Date + octagonPeerID:row[@"octagonpeerid"].asString + octagonStatus:octagonStatus + circlePeerID:row[@"peerid"].asString + circleStatus:SOSAccountGetSOSCCStatusFromString((__bridge CFStringRef) row[@"circlestatus"].asString) + keyState:(CKKSZoneKeyState*)row[@"keystate"].asString + currentTLKUUID:row[@"currentTLK"].asString + currentClassAUUID:row[@"currentClassA"].asString + currentClassCUUID:row[@"currentClassC"].asString + zoneID:[[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"].asString ownerName:CKCurrentUserDefaultName] + encodedCKRecord:row[@"ckrecord"].asBase64DecodedData + ]; } @end diff --git a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h index 46393ef6..082ec101 100644 --- a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h +++ b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h @@ -54,7 +54,10 @@ extern CKKSFetchBecause* const CKKSFetchBecauseResync; @protocol CKKSChangeFetcherClient - (CKRecordZoneID*)zoneID; - (CKKSCloudKitFetchRequest*)participateInFetch; -- (bool)notifyFetchError:(NSError*)error; + +// Return false if this is a 'fatal' error and you don't want another fetch to be tried +- (bool)shouldRetryAfterFetchError:(NSError*)error; + - (void)changesFetched:(NSArray*)changedRecords deletedRecordIDs:(NSArray*)deleted oldChangeToken:(CKServerChangeToken* _Nullable)oldChangeToken @@ -85,7 +88,7 @@ extern CKKSFetchBecause* const CKKSFetchBecauseResync; @property NSMutableDictionary* modifications; @property NSMutableDictionary* deletions; -@property NSMutableDictionary* changeTokens; +@property NSMutableDictionary* changeTokens; - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithContainer:(CKContainer*)container diff --git a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m index 42c20308..1304cb87 100644 --- a/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m +++ b/keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.m @@ -33,11 +33,10 @@ #import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSKeychainView.h" -#import "keychain/ckks/CKKSZoneStateEntry.h" -#import "keychain/ckks/CKKSFetchAllRecordZoneChangesOperation.h" -#import "keychain/ckks/CKKSMirrorEntry.h" -#import "keychain/ckks/CKKSManifest.h" -#import "keychain/ckks/CKKSManifestLeafRecord.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/analytics/SecEventMetric.h" +#import "keychain/analytics/SecMetrics.h" #import "NSError+UsefulConstructors.h" #import "CKKSPowerCollection.h" #include @@ -64,6 +63,13 @@ @property CKOperationGroup* ckoperationGroup; @property (assign) NSUInteger fetchedItems; @property bool forceResync; + +@property bool moreComing; + +// Holds the original change token that the client believes they have synced to +@property NSMutableDictionary* originalChangeTokens; + +@property CKKSResultOperation* fetchCompletedOperation; @end @implementation CKKSFetchAllRecordZoneChangesOperation @@ -100,16 +106,19 @@ _modifications = [[NSMutableDictionary alloc] init]; _deletions = [[NSMutableDictionary alloc] init]; + _changeTokens = [[NSMutableDictionary alloc] init]; + _originalChangeTokens = [[NSMutableDictionary alloc] init]; + + _fetchCompletedOperation = [CKKSResultOperation named:@"record-zone-changes-completed" withBlock:^{}]; + + _moreComing = false; } return self; } -- (void)groupStart { - __weak __typeof(self) weakSelf = self; - +- (void)queryClientsForChangeTokens +{ // Ask all our clients for their change tags - self.allClientOptions = [NSMutableDictionary dictionary]; - self.fetchedZoneIDs = [NSMutableArray array]; // Unused until [ Changes to discretionary-ness (explicit or derived from QoS) should be "live"] has happened and we can determine network // discretionaryness. @@ -125,7 +134,14 @@ CKFetchRecordZoneChangesConfiguration* options = [[CKFetchRecordZoneChangesConfiguration alloc] init]; if(!self.forceResync) { - options.previousServerChangeToken = clientPreference.changeToken; + if (self.changeTokens[clientZoneID]) { + options.previousServerChangeToken = self.changeTokens[clientZoneID]; + secnotice("ckksfetch", "Using cached change token for %@: %@", clientZoneID, self.changeTokens[clientZoneID]); + } else { + options.previousServerChangeToken = clientPreference.changeToken; + } + + self.originalChangeTokens[clientZoneID] = options.previousServerChangeToken; } //if(options.previousServerChangeToken == nil) { @@ -135,6 +151,13 @@ self.allClientOptions[client.zoneID] = options; } } +} + +- (void)groupStart { + self.allClientOptions = [NSMutableDictionary dictionary]; + self.fetchedZoneIDs = [NSMutableArray array]; + + [self queryClientsForChangeTokens]; if(self.fetchedZoneIDs.count == 0) { // No clients actually want to fetch right now, so quit @@ -143,6 +166,13 @@ return; } + [self performFetch]; +} + +- (void)performFetch +{ + WEAKIFY(self); + // 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 @@ -160,127 +190,105 @@ // networkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; //} - secnotice("ckks", "Beginning fetch with discretionary network (%d): %@", (int)networkBehavior, self.allClientOptions); + secnotice("ckksfetch", "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.fetchAllChanges = NO; self.fetchRecordZoneChangesOperation.configuration.discretionaryNetworkBehavior = networkBehavior; + self.fetchRecordZoneChangesOperation.configuration.isCloudKitSupportOperation = YES; self.fetchRecordZoneChangesOperation.group = self.ckoperationGroup; secnotice("ckksfetch", "Operation group is %@", self.ckoperationGroup); self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) { - __strong __typeof(weakSelf) strongSelf = weakSelf; + STRONGIFY(self); 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.modifications[record.recordID] = record; + [self.deletions removeObjectForKey:record.recordID]; + self.fetchedItems++; }; self.fetchRecordZoneChangesOperation.recordWithIDWasDeletedBlock = ^(CKRecordID *recordID, NSString *recordType) { - __strong __typeof(weakSelf) strongSelf = weakSelf; + STRONGIFY(self); 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.modifications removeObjectForKey: recordID]; + self.deletions[recordID] = [[CKKSCloudKitDeletion alloc] initWithRecordID:recordID recordType:recordType]; + self.fetchedItems++; }; self.fetchRecordZoneChangesOperation.recordZoneChangeTokensUpdatedBlock = ^(CKRecordZoneID *recordZoneID, CKServerChangeToken *serverChangeToken, NSData *clientChangeTokenData) { - __strong __typeof(weakSelf) strongSelf = weakSelf; + STRONGIFY(self); - secinfo("ckksfetch", "Received a new server change token for %@: %@ %@", recordZoneID, serverChangeToken, clientChangeTokenData); - strongSelf.changeTokens[recordZoneID] = serverChangeToken; + secinfo("ckksfetch", "Received a new server change token (via block) for %@: %@ %@", recordZoneID, serverChangeToken, clientChangeTokenData); + self.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; - } + STRONGIFY(self); - id client = strongSelf.clientMap[recordZoneID]; - if(!client) { - secerror("ckksfetch: no client registered for %@, so why did we get any data?", recordZoneID); - return; - } + secnotice("ckksfetch", "Received a new server change token for %@: %@ %@", recordZoneID, serverChangeToken, clientChangeTokenData); + self.changeTokens[recordZoneID] = serverChangeToken; + self.allClientOptions[recordZoneID].previousServerChangeToken = serverChangeToken; - // First, filter the modifications and deletions for this zone - NSMutableArray* zoneModifications = [NSMutableArray array]; - NSMutableArray* zoneDeletions = [NSMutableArray array]; - - [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]; - } - }]; - - [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"); + self.moreComing |= moreComing; + if(moreComing) { + secnotice("ckksfetch", "more changes pending for %@, will start a new fetch at change token %@", recordZoneID, self.changeTokens[recordZoneID]); } - }; - // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. - CKKSResultOperation* recordZoneChangesCompletedOperation = [CKKSResultOperation named:@"record-zone-changes-completed" withBlock:^{}]; + ckksnotice("ckksfetch", recordZoneID, "Record zone fetch complete: changeToken=%@ clientChangeTokenData=%@ moreComing=%@ error=%@", serverChangeToken, clientChangeTokenData, + moreComing ? @"YES" : @"NO", + recordZoneError); + }; // 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) { + STRONGIFY(self); + if(!self) { secerror("ckksfetch: received callback for released object"); return; } - secnotice("ckksfetch", "Record zone changes fetch complete: error=%@", operationError); + // If we were told that there were moreChanges coming for any zone, we'd like to fetch again. + // This is true if we recieve no error or a network timeout. Any other error should cause a failure. + if(self.moreComing && (operationError == nil || [CKKSReachabilityTracker isNetworkFailureError:operationError])) { + secnotice("ckksfetch", "Must issue another fetch (with potential error %@)", operationError); + self.moreComing = false; + [self performFetch]; + return; + } + if(operationError) { - strongSelf.error = operationError; + self.error = operationError; + } else { + secnotice("ckksfetch", "Advising clients of fetched changes"); + [self sendAllChangesToClients]; } + secnotice("ckksfetch", "Record zone changes fetch complete: error=%@", operationError); + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventFetchAllChanges - count:strongSelf.fetchedItems]; + count:self.fetchedItems]; // Count record changes per zone NSMutableDictionary* recordChangesPerZone = [NSMutableDictionary dictionary]; - NSNumber* totalModifications = [NSNumber numberWithUnsignedLong:strongSelf.modifications.count]; - NSNumber* totalDeletions = [NSNumber numberWithUnsignedLong:strongSelf.deletions.count]; + NSNumber* totalModifications = [NSNumber numberWithUnsignedLong:self.modifications.count]; + NSNumber* totalDeletions = [NSNumber numberWithUnsignedLong:self.deletions.count]; - for(CKRecordID* recordID in strongSelf.modifications) { + for(CKRecordID* recordID in self.modifications) { NSNumber* last = recordChangesPerZone[recordID.zoneID]; recordChangesPerZone[recordID.zoneID] = [NSNumber numberWithUnsignedLong:1+(last ? [last unsignedLongValue] : 0)]; } - for(CKRecordID* recordID in strongSelf.deletions) { + for(CKRecordID* recordID in self.deletions) { NSNumber* last = recordChangesPerZone[recordID.zoneID]; recordChangesPerZone[recordID.zoneID] = [NSNumber numberWithUnsignedLong:1+(last ? [last unsignedLongValue] : 0)]; } - for(CKRecordZoneNotification* rz in strongSelf.apnsPushes) { + for(CKRecordZoneNotification* rz in self.apnsPushes) { if(rz.ckksPushTracingEnabled) { secnotice("ckksfetch", "Submitting post-fetch CKEventMetric due to notification %@", rz); @@ -301,38 +309,98 @@ metric[zoneID.zoneName] = recordChangesPerZone[zoneID]; } + SecEventMetric *metric2 = [[SecEventMetric alloc] initWithEventName:@"APNSPushMetrics"]; + metric2[@"push_token_uuid"] = rz.ckksPushTracingUUID; + metric2[@"push_received_date"] = rz.ckksPushReceivedDate; + metric2[@"push_event_name"] = @"CKKS Push-webtunnel"; + + metric2[@"fetch_error"] = operationError; + + metric2[@"total_modifications"] = totalModifications; + metric2[@"total_deletions"] = totalDeletions; + for(CKRecordZoneID* zoneID in recordChangesPerZone) { + metric2[zoneID.zoneName] = recordChangesPerZone[zoneID]; + } + // 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; + CKContainer* container = self.container; + CKDatabaseOperation* rzcOperation = self.fetchRecordZoneChangesOperation; CKKSResultOperation* launchMetricOp = [CKKSResultOperation named:@"submit-metric" withBlock:^{ if(![metric associateWithCompletedOperation:rzcOperation]) { secerror("ckksfetch: Couldn't associate metric with operation: %@ %@", metric, rzcOperation); } [container submitEventMetric:metric]; + [[SecMetrics managerObject] submitEvent:metric2]; secnotice("ckksfetch", "Metric submitted: %@", metric); }]; - [launchMetricOp addSuccessDependency:recordZoneChangesCompletedOperation]; + [launchMetricOp addSuccessDependency:self.fetchCompletedOperation]; - [strongSelf.operationQueue addOperation:launchMetricOp]; + [self.operationQueue addOperation:launchMetricOp]; } } // Don't need these any more; save some memory - [strongSelf.modifications removeAllObjects]; - [strongSelf.deletions removeAllObjects]; + [self.modifications removeAllObjects]; + [self.deletions removeAllObjects]; // Trigger the fake 'we're done' operation. - [strongSelf runBeforeGroupFinished: recordZoneChangesCompletedOperation]; + [self runBeforeGroupFinished: self.fetchCompletedOperation]; }; - [self dependOnBeforeGroupFinished:recordZoneChangesCompletedOperation]; + [self dependOnBeforeGroupFinished:self.fetchCompletedOperation]; [self dependOnBeforeGroupFinished:self.fetchRecordZoneChangesOperation]; - [self.container.privateCloudDatabase addOperation:self.fetchRecordZoneChangesOperation]; } +- (void)sendAllChangesToClients +{ + for(CKRecordZoneID* clientZoneID in self.clientMap) { + [self sendChangesToClient:clientZoneID]; + } +} + +- (void)sendChangesToClient:(CKRecordZoneID*)recordZoneID +{ + id client = self.clientMap[recordZoneID]; + if(!client) { + secerror("ckksfetch: no client registered for %@, so why did we get any data?", recordZoneID); + return; + } + + // First, filter the modifications and deletions for this zone + NSMutableArray* zoneModifications = [NSMutableArray array]; + NSMutableArray* zoneDeletions = [NSMutableArray array]; + + [self.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]; + } + }]; + + [self.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, "Delivering fetched changes: changed=%lu deleted=%lu", + (unsigned long)zoneModifications.count, (unsigned long)zoneDeletions.count); + + // Tell the client about these changes! + [client changesFetched:zoneModifications + deletedRecordIDs:zoneDeletions + oldChangeToken:self.originalChangeTokens[recordZoneID] + newChangeToken:self.changeTokens[recordZoneID]]; +} + - (void)cancel { [self.fetchRecordZoneChangesOperation cancel]; [super cancel]; diff --git a/keychain/ckks/CKKSFixups.h b/keychain/ckks/CKKSFixups.h index 3db29c4a..98e48dd7 100644 --- a/keychain/ckks/CKKSFixups.h +++ b/keychain/ckks/CKKSFixups.h @@ -28,6 +28,8 @@ #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSResultOperation.h" +NS_ASSUME_NONNULL_BEGIN + // Sometimes things go wrong. // Sometimes you have to clean up after your past self. // This contains the fixes. @@ -37,8 +39,9 @@ typedef NS_ENUM(NSUInteger, CKKSFixup) { CKKSFixupRefetchCurrentItemPointers, CKKSFixupFetchTLKShares, CKKSFixupLocalReload, + CKKSFixupResaveDeviceStateEntries, }; -#define CKKSCurrentFixupNumber (CKKSFixupLocalReload) +#define CKKSCurrentFixupNumber (CKKSFixupResaveDeviceStateEntries) @interface CKKSFixups : NSObject +(CKKSGroupOperation*)fixup:(CKKSFixup)lastfixup for:(CKKSKeychainView*)keychainView; @@ -61,4 +64,11 @@ typedef NS_ENUM(NSUInteger, CKKSFixup) { ckoperationGroup:(CKOperationGroup*)ckoperationGroup; @end +@interface CKKSFixupResaveDeviceStateEntriesOperation: CKKSGroupOperation +@property (weak) CKKSKeychainView* ckks; +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)keychainView; +@end + +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSFixups.m b/keychain/ckks/CKKSFixups.m index 2f20fc78..927cf56e 100644 --- a/keychain/ckks/CKKSFixups.m +++ b/keychain/ckks/CKKSFixups.m @@ -28,6 +28,7 @@ #import "keychain/ckks/CKKSCurrentItemPointer.h" #import "keychain/ckks/CKKSZoneStateEntry.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" @implementation CKKSFixups +(CKKSGroupOperation*)fixup:(CKKSFixup)lastfixup for:(CKKSKeychainView*)keychainView @@ -66,6 +67,14 @@ previousOp = localSync; } + if(lastfixup < CKKSFixupResaveDeviceStateEntries) { + CKKSResultOperation* resave = [[CKKSFixupResaveDeviceStateEntriesOperation alloc] initWithCKKSKeychainView:keychainView]; + + [resave addNullableSuccessDependency:previousOp]; + [fixups runBeforeGroupFinished:resave]; + previousOp = resave; + } + (void)previousOp; return fixups; } @@ -126,12 +135,12 @@ ckksnotice("ckksfixup", ckks, "No existing CIPs; fixup complete"); } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); NSBlockOperation* doneOp = [NSBlockOperation named:@"fetch-records-operation-complete" withBlock:^{}]; - id fetch = [[ckks.fetchRecordsOperationClass alloc] initWithRecordIDs: [recordIDs allObjects]]; + id fetch = [[ckks.cloudKitClassDependencies.fetchRecordsOperationClass alloc] initWithRecordIDs: [recordIDs allObjects]]; fetch.fetchRecordsCompletionBlock = ^(NSDictionary * _Nullable recordsByRecordID, NSError * _Nullable error) { - __strong __typeof(self) strongSelf = weakSelf; - CKKSKeychainView* strongCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; [strongCKKS dispatchSync:^bool{ if(error) { @@ -147,11 +156,11 @@ [strongCKKS _onqueueCKRecordDeleted: recordID recordType:SecCKRecordCurrentItemType resync:true]; } else { ckkserror("ckksfixup", strongCKKS, "Unknown error for %@: %@", recordID, error); - strongSelf.error = error; + self.error = error; } } } else { - strongSelf.error = error; + self.error = error; } } else { ckksnotice("ckksfixup", strongCKKS, "Finished record fetch successfully"); @@ -163,7 +172,7 @@ [self.ckks _onqueueCKRecordChanged:record resync:true]; } - if(!strongSelf.error) { + if(!self.error) { // Now, update the zone state entry to be at this level NSError* localerror = nil; CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry fromDatabase:strongCKKS.zoneName error:&localerror]; @@ -176,7 +185,7 @@ } } - [strongSelf runBeforeGroupFinished:doneOp]; + [self runBeforeGroupFinished:doneOp]; return true; }]; }; @@ -221,19 +230,19 @@ } [ckks dispatchSyncWithAccountKeys:^bool { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); NSBlockOperation* doneOp = [NSBlockOperation named:@"fetch-records-operation-complete" withBlock:^{}]; NSPredicate *yes = [NSPredicate predicateWithValue:YES]; CKQuery *query = [[CKQuery alloc] initWithRecordType:SecCKRecordTLKShareType predicate:yes]; - id fetch = [[ckks.queryOperationClass alloc] initWithQuery:query]; + id fetch = [[ckks.cloudKitClassDependencies.queryOperationClass alloc] initWithQuery:query]; fetch.zoneID = ckks.zoneID; fetch.desiredKeys = nil; fetch.recordFetchedBlock = ^(CKRecord * _Nonnull record) { - __strong __typeof(self) strongSelf = weakSelf; - CKKSKeychainView* strongCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; [strongCKKS dispatchSync:^bool{ ckksnotice("ckksfixup", strongCKKS, "Recieved tlk share record from query: %@", record); @@ -243,13 +252,13 @@ }; fetch.queryCompletionBlock = ^(CKQueryCursor * _Nullable cursor, NSError * _Nullable error) { - __strong __typeof(self) strongSelf = weakSelf; - CKKSKeychainView* strongCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; [strongCKKS dispatchSync:^bool{ if(error) { ckkserror("ckksfixup", strongCKKS, "Couldn't fetch all TLKShare records: %@", error); - strongSelf.error = error; + self.error = error; return false; } @@ -266,7 +275,7 @@ } return true; }]; - [strongSelf runBeforeGroupFinished:doneOp]; + [self runBeforeGroupFinished:doneOp]; }; [ckks.database addOperation: fetch]; @@ -303,7 +312,7 @@ } - (void)groupStart { CKKSKeychainView* ckks = self.ckks; - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); if(!ckks) { ckkserror("ckksfixup", ckks, "no CKKS object"); self.error = [NSError errorWithDomain:CKKSErrorDomain code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"no CKKS object"}]; @@ -314,12 +323,12 @@ [self runBeforeGroupFinished:reload]; CKKSResultOperation* cleanup = [CKKSResultOperation named:@"local-reload-cleanup" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - __strong __typeof(self.ckks) strongCKKS = strongSelf.ckks; + STRONGIFY(self); + __strong __typeof(self.ckks) strongCKKS = self.ckks; [strongCKKS dispatchSync:^bool{ if(reload.error) { ckkserror("ckksfixup", strongCKKS, "Couldn't perform a reload: %@", reload.error); - strongSelf.error = reload.error; + self.error = reload.error; return false; } @@ -342,4 +351,78 @@ } @end +#pragma mark - CKKSFixupResaveDeviceStateEntriesOperation + +@implementation CKKSFixupResaveDeviceStateEntriesOperation: CKKSGroupOperation + +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)keychainView +{ + if((self = [super init])) { + _ckks = keychainView; + } + return self; +} + +- (NSString*)description { + return [NSString stringWithFormat:@"", self.ckks]; +} + +- (void)groupStart { + CKKSKeychainView* ckks = self.ckks; + + if(!ckks) { + ckkserror("ckksfixup", ckks, "no CKKS object"); + self.error = [NSError errorWithDomain:CKKSErrorDomain code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"no CKKS object"}]; + return; + } + + // This operation simply loads all CDSEs, remakes them from their CKRecord, and resaves them + [ckks dispatchSync:^bool { + NSError* error = nil; + NSArray* cdses = [CKKSDeviceStateEntry allInZone:ckks.zoneID + error:&error]; + + if(error) { + ckkserror("ckksfixup", ckks, "Unable to fetch all CDSEs: %@", error); + self.error = error; + return false; + } + + for(CKKSDeviceStateEntry* cdse in cdses) { + CKRecord* record = cdse.storedCKRecord; + + if(record) { + [cdse setFromCKRecord:record]; + [cdse saveToDatabase:&error]; + if(error) { + ckkserror("ckksfixup", ckks, "Unable to save CDSE: %@", error); + self.error = error; + return false; + } + } else { + ckksnotice("ckksfixup", ckks, "Saved CDSE has no stored record: %@", cdse); + } + } + + ckksnotice("ckksfixup", ckks, "Successfully performed a ResaveDeviceState fixup"); + + NSError* localerror = nil; + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry fromDatabase:ckks.zoneName error:&localerror]; + ckse.lastFixup = CKKSFixupResaveDeviceStateEntries; + [ckse saveToDatabase:&localerror]; + if(localerror) { + ckkserror("ckksfixup", ckks, "Couldn't save CKKSZoneStateEntry(%@): %@", ckse, localerror); + self.error = localerror; + return false; + } + + ckksnotice("ckksfixup", ckks, "Updated zone fixup state to CKKSFixupResaveDeviceStateEntries"); + + return true; + }]; +} + + +@end + #endif // OCTAGON diff --git a/keychain/ckks/CKKSGroupOperation.h b/keychain/ckks/CKKSGroupOperation.h index ccbd4a17..98988e1b 100644 --- a/keychain/ckks/CKKSGroupOperation.h +++ b/keychain/ckks/CKKSGroupOperation.h @@ -27,6 +27,8 @@ #include #import "keychain/ckks/CKKSResultOperation.h" +NS_ASSUME_NONNULL_BEGIN + @interface CKKSGroupOperation : CKKSResultOperation { BOOL executing; @@ -48,4 +50,6 @@ - (void)dependOnBeforeGroupFinished:(NSOperation*)suboperation; @end +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSGroupOperation.m b/keychain/ckks/CKKSGroupOperation.m index 66a6ba40..d85e9fad 100644 --- a/keychain/ckks/CKKSGroupOperation.m +++ b/keychain/ckks/CKKSGroupOperation.m @@ -24,6 +24,7 @@ #if OCTAGON #import "CKKSGroupOperation.h" +#import "keychain/ot/ObjCImprovements.h" #include @interface CKKSGroupOperation() @@ -39,7 +40,7 @@ - (instancetype)init { if(self = [super init]) { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); _fillInError = true; @@ -50,31 +51,31 @@ // At start, we'll call this method (for subclasses) _startOperation = [NSBlockOperation blockOperationWithBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckks: received callback for released object"); return; } - if(![strongSelf allDependentsSuccessful]) { - secdebug("ckksgroup", "Not running due to some failed dependent: %@", strongSelf.error); - [strongSelf cancel]; + if(![self allDependentsSuccessful]) { + secdebug("ckksgroup", "Not running due to some failed dependent: %@", self.error); + [self cancel]; return; } - [strongSelf groupStart]; + [self groupStart]; }]; [self.startOperation removeDependenciesUponCompletion]; // The finish operation will 'finish' us _finishOperation = [NSBlockOperation blockOperationWithBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckks: received callback for released object"); return; } - [strongSelf completeOperation]; + [self completeOperation]; }]; [self.finishOperation removeDependenciesUponCompletion]; @@ -297,21 +298,21 @@ } + (instancetype)operationWithBlock:(void (^)(void))block { - CKKSGroupOperation* op = [[CKKSGroupOperation alloc] init]; + CKKSGroupOperation* op = [[self alloc] init]; NSBlockOperation* blockOp = [NSBlockOperation blockOperationWithBlock:block]; [op runBeforeGroupFinished:blockOp]; return op; } -+(instancetype)named:(NSString*)name withBlock:(void(^)(void)) block { - CKKSGroupOperation* blockOp = [CKKSGroupOperation operationWithBlock: block]; ++ (instancetype)named:(NSString*)name withBlock:(void(^)(void)) block { + CKKSGroupOperation* blockOp = [self operationWithBlock: block]; blockOp.name = name; return blockOp; } + (instancetype)named:(NSString*)name withBlockTakingSelf:(void(^)(CKKSGroupOperation* strongOp))block { - CKKSGroupOperation* op = [[CKKSGroupOperation alloc] init]; + CKKSGroupOperation* op = [[self alloc] init]; __weak __typeof(op) weakOp = op; [op runBeforeGroupFinished:[NSBlockOperation blockOperationWithBlock:^{ __strong __typeof(op) strongOp = weakOp; diff --git a/keychain/ckks/CKKSHealKeyHierarchyOperation.h b/keychain/ckks/CKKSHealKeyHierarchyOperation.h index 496f833b..2e30b8c3 100644 --- a/keychain/ckks/CKKSHealKeyHierarchyOperation.h +++ b/keychain/ckks/CKKSHealKeyHierarchyOperation.h @@ -26,6 +26,8 @@ #if OCTAGON +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; @interface CKKSHealKeyHierarchyOperation : CKKSGroupOperation @@ -36,4 +38,6 @@ @end +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSHealKeyHierarchyOperation.m b/keychain/ckks/CKKSHealKeyHierarchyOperation.m index afc9862a..21351856 100644 --- a/keychain/ckks/CKKSHealKeyHierarchyOperation.m +++ b/keychain/ckks/CKKSHealKeyHierarchyOperation.m @@ -29,6 +29,7 @@ #import "CKKSAnalytics.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" #if OCTAGON @@ -59,7 +60,7 @@ * The answer "nothing, everything is terrible" is acceptable. */ - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSKeychainView* ckks = self.ckks; if(!ckks) { @@ -81,7 +82,7 @@ NSError* error = nil; - CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] initForZone:ckks.zoneID]; + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:ckks.zoneID]; bool changedCurrentTLK = false; bool changedCurrentClassA = false; @@ -157,6 +158,13 @@ } } + if(!newTLK) { + // We don't have any TLKs lying around, but we're supposed to heal the key hierarchy. This isn't any good; let's wait for TLK creation. + ckkserror("ckksheal", ckks, "No possible TLK found. Waiting for creation."); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForTLKCreation withError:nil]; + return true; + } + if(![ckks _onqueueWithAccountKeysCheckTLK: newTLK error: &error]) { // Was this error "I've never seen that TLK before in my life"? If so, enter the "wait for TLK sync" state. if(error && [error.domain isEqualToString: @"securityd"] && error.code == errSecItemNotFound) { @@ -271,14 +279,14 @@ } // We've selected a new TLK. Compute any TLKShares that should go along with it. - NSSet* tlkShares = [ckks _onqueueCreateMissingKeyShares:keyset.tlk + NSSet* tlkShares = [ckks _onqueueCreateMissingKeyShares:keyset.tlk error:&error]; if(error) { ckkserror("ckksshare", ckks, "Unable to create TLK shares for new tlk: %@", error); return false; } - for(CKKSTLKShare* share in tlkShares) { + for(CKKSTLKShareRecord* share in tlkShares) { CKRecord* record = [share CKRecordWithZoneID:ckks.zoneID]; [recordsToSave addObject: record]; } @@ -306,13 +314,14 @@ // This needs to happen for CKKS to be usable by PCS/cloudd. Make it happen. modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO; modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + modifyRecordsOp.configuration.isCloudKitSupportOperation = YES; modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckksheal", ckks, "Operation group is %@", self.ckoperationGroup); modifyRecordsOp.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* blockCKKS = self.ckks; // These should all fail or succeed as one. Do the hard work in the records completion block. if(!error) { @@ -323,9 +332,9 @@ }; modifyRecordsOp.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf) { + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; + if(!self) { secerror("ckks: received callback for released object"); return; } @@ -366,7 +375,7 @@ [keyset.currentClassCPointer saveToDatabase: &localerror]; // save all the TLKShares, too - for(CKKSTLKShare* share in tlkShares) { + for(CKKSTLKShareRecord* share in tlkShares) { [share saveToDatabase:&localerror]; } @@ -389,7 +398,7 @@ }]; // Notify that we're done - [strongSelf.operationQueue addOperation: strongSelf.cloudkitModifyOperationFinished]; + [self.operationQueue addOperation: self.cloudkitModifyOperationFinished]; }; [ckks.database addOperation: modifyRecordsOp]; @@ -402,7 +411,7 @@ ckksnotice("ckkskey", ckks, "Failed to load TLK from keychain, keybag is locked. Entering waitforunlock: %@", error); [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:nil]; return false; - } else if(error && error.code == errSecItemNotFound) { + } else if(error && [error.domain isEqualToString: @"securityd"] && error.code == errSecItemNotFound) { ckkserror("ckksheal", ckks, "CKKS couldn't find TLK, triggering move to wait state: %@", error); [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateWaitForTLK withError: nil]; diff --git a/keychain/ckks/CKKSHealTLKSharesOperation.h b/keychain/ckks/CKKSHealTLKSharesOperation.h index 4786d6ea..9dc61050 100644 --- a/keychain/ckks/CKKSHealTLKSharesOperation.h +++ b/keychain/ckks/CKKSHealTLKSharesOperation.h @@ -26,6 +26,8 @@ #if OCTAGON +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; @interface CKKSHealTLKSharesOperation : CKKSGroupOperation @@ -35,4 +37,5 @@ - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks ckoperationGroup:(CKOperationGroup*)ckoperationGroup; @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSHealTLKSharesOperation.m b/keychain/ckks/CKKSHealTLKSharesOperation.m index 378cff06..a407f466 100644 --- a/keychain/ckks/CKKSHealTLKSharesOperation.m +++ b/keychain/ckks/CKKSHealTLKSharesOperation.m @@ -31,7 +31,8 @@ #import "keychain/ckks/CKKSKey.h" #import "keychain/ckks/CKKSHealTLKSharesOperation.h" #import "keychain/ckks/CKKSGroupOperation.h" -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" +#import "keychain/ot/ObjCImprovements.h" #import "CKKSPowerCollection.h" @@ -60,7 +61,7 @@ * Attempt to figure out what it is, and what we can do about it. */ - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSKeychainView* ckks = self.ckks; if(!ckks) { @@ -81,7 +82,7 @@ NSError* error = nil; - CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] initForZone:ckks.zoneID]; + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:ckks.zoneID]; if(keyset.error) { self.error = keyset.error; @@ -108,10 +109,11 @@ return true; } - NSSet* newShares = [ckks _onqueueCreateMissingKeyShares:keyset.tlk + NSSet* newShares = [ckks _onqueueCreateMissingKeyShares:keyset.tlk error:&error]; if(error) { ckkserror("ckksshare", ckks, "Unable to create shares: %@", error); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateUnhealthy withError:nil]; return false; } @@ -121,13 +123,23 @@ return true; } + // Let's double-check: if we upload these TLKShares, will the world be right? + BOOL newSharesSufficient = [ckks _onqueueAreNewSharesSufficient:newShares + currentTLK:keyset.tlk + error:&error]; + if(!newSharesSufficient || error) { + ckksnotice("ckksshare", ckks, "New shares won't resolve the share issue; erroring to avoid infinite loops"); + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:error]; + return true; + } + // Fire up our CloudKit operation! NSMutableArray* recordsToSave = [[NSMutableArray alloc] init]; NSMutableArray* recordIDsToDelete = [[NSMutableArray alloc] init]; NSMutableDictionary* attemptedRecords = [[NSMutableDictionary alloc] init]; - for(CKKSTLKShare* share in newShares) { + for(CKKSTLKShareRecord* share in newShares) { CKRecord* record = [share CKRecordWithZoneID:ckks.zoneID]; [recordsToSave addObject: record]; attemptedRecords[record.recordID] = record; @@ -147,26 +159,27 @@ // very important: get the TLKShares off-device ASAP modifyRecordsOp.configuration.automaticallyRetryNetworkFailures = NO; modifyRecordsOp.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + modifyRecordsOp.configuration.isCloudKitSupportOperation = YES; modifyRecordsOp.group = self.ckoperationGroup; ckksnotice("ckksshare", ckks, "Operation group is %@", self.ckoperationGroup); modifyRecordsOp.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* blockCKKS = self.ckks; // These should all fail or succeed as one. Do the hard work in the records completion block. if(!error) { - ckksinfo("ckksshare", blockCKKS, "Successfully completed upload for record %@", record.recordID.recordName); + ckksnotice("ckksshare", blockCKKS, "Successfully completed upload for record %@", record.recordID.recordName); } else { ckkserror("ckksshare", blockCKKS, "error on row: %@ %@", record.recordID, error); } }; modifyRecordsOp.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf) { + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; + if(!self) { secerror("ckks: received callback for released object"); return; } @@ -179,13 +192,16 @@ // Save the new CKRecords to the database for(CKRecord* record in savedRecords) { - CKKSTLKShare* savedShare = [[CKKSTLKShare alloc] initWithCKRecord:record]; - [savedShare saveToDatabase:&localerror]; + CKKSTLKShareRecord* savedShare = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + bool saved = [savedShare saveToDatabase:&localerror]; - if(localerror) { + if(!saved || localerror != nil) { + // erroring means we were unable to save the new TLKShare records to the database. This will cause us to try to reupload them. Fail. // No recovery from this, really... ckkserror("ckksshare", strongCKKS, "Couldn't save new TLKShare record to database: %@", localerror); - localerror = nil; + [strongCKKS _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError: localerror]; + return true; + } else { ckksnotice("ckksshare", strongCKKS, "Successfully completed upload for %@", savedShare); } @@ -203,7 +219,7 @@ }]; // Notify that we're done - [strongSelf.operationQueue addOperation: strongSelf.cloudkitModifyOperationFinished]; + [self.operationQueue addOperation: self.cloudkitModifyOperationFinished]; }; [ckks.database addOperation: modifyRecordsOp]; diff --git a/keychain/ckks/CKKSIncomingQueueEntry.m b/keychain/ckks/CKKSIncomingQueueEntry.m index 94e6b5fa..0d38c781 100644 --- a/keychain/ckks/CKKSIncomingQueueEntry.m +++ b/keychain/ckks/CKKSIncomingQueueEntry.m @@ -119,10 +119,10 @@ } -+ (instancetype)fromDatabaseRow: (NSDictionary*) row { ++ (instancetype)fromDatabaseRow:(NSDictionary*) row { return [[CKKSIncomingQueueEntry alloc] initWithCKKSItem: [CKKSItem fromDatabaseRow: row] - action: row[@"action"] - state: row[@"state"]]; + action:row[@"action"].asString + state:row[@"state"].asString]; } + (NSDictionary*)countsByStateInZone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { @@ -134,8 +134,8 @@ groupBy: @[@"state"] orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[row[@"state"]] = [NSNumber numberWithInteger: [row[@"count(rowid)"] integerValue]]; + processRow: ^(NSDictionary* row) { + results[row[@"state"].asString] = row[@"count(rowid)"].asNSNumberInteger; } error: error]; return results; @@ -150,8 +150,8 @@ groupBy: nil orderBy: nil limit: -1 - processRow: ^(NSDictionary* row) { - result = [row[@"count(*)"] integerValue]; + processRow: ^(NSDictionary* row) { + result = row[@"count(*)"].asNSInteger; } error: error]; return result; diff --git a/keychain/ckks/CKKSIncomingQueueOperation.h b/keychain/ckks/CKKSIncomingQueueOperation.h index ff8a6f09..8b897285 100644 --- a/keychain/ckks/CKKSIncomingQueueOperation.h +++ b/keychain/ckks/CKKSIncomingQueueOperation.h @@ -24,8 +24,10 @@ #import #import "keychain/ckks/CKKSGroupOperation.h" #if OCTAGON +NS_ASSUME_NONNULL_BEGIN @class CKKSKeychainView; +@class CKKSItem; @interface CKKSIncomingQueueOperation : CKKSResultOperation @property (weak) CKKSKeychainView* ckks; @@ -40,6 +42,10 @@ - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks errorOnClassAFailure:(bool)errorOnClassAFailure; +// Use this to turn a CKKS item into a keychain dictionary suitable for keychain insertion ++ (NSDictionary* _Nullable)decryptCKKSItemToAttributes:(CKKSItem*)item error:(NSError**)error; + @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSIncomingQueueOperation.m b/keychain/ckks/CKKSIncomingQueueOperation.m index f3f53f19..2aed9402 100644 --- a/keychain/ckks/CKKSIncomingQueueOperation.m +++ b/keychain/ckks/CKKSIncomingQueueOperation.m @@ -31,12 +31,14 @@ #import "CKKSAnalytics.h" #import "CKKSPowerCollection.h" #import "keychain/ckks/CKKSCurrentItemPointer.h" +#import "keychain/ot/ObjCImprovements.h" #include #include #include #include +#import #if OCTAGON @@ -68,13 +70,12 @@ [self linearDependencies:ckks.incomingQueueOperations]; if ([CKKSManifest shouldSyncManifests]) { - __weak __typeof(self) weakSelf = self; - __weak CKKSKeychainView* weakCKKS = ckks; + WEAKIFY(self); CKKSResultOperation* updateManifestOperation = [CKKSResultOperation operationWithBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - __strong CKKSKeychainView* strongCKKS = weakCKKS; + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; __block NSError* error = nil; - if (!strongCKKS || !strongSelf) { + if (!strongCKKS || !self) { ckkserror("ckksincoming", strongCKKS, "update manifest operation fired for released object"); return; } @@ -82,7 +83,7 @@ [strongCKKS dispatchSyncWithAccountKeys:^bool{ strongCKKS.latestManifest = [CKKSManifest latestTrustedManifestForZone:strongCKKS.zoneName error:&error]; if (error) { - strongSelf.error = error; + self.error = error; ckkserror("ckksincoming", strongCKKS, "failed to get latest manifest: %@", error); return false; } @@ -159,7 +160,8 @@ // 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]; + NSDictionary* attributes = [CKKSIncomingQueueOperation decryptCKKSItemToAttributes:iqe.item error:&error]; + if(!attributes || error) { if([ckks.lockStateTracker isLockedError:error]) { NSError* localerror = nil; @@ -186,23 +188,6 @@ continue; } - // 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" @@ -227,23 +212,6 @@ continue; } - - // Now, filter: if this item was added locally, would it go to this view? - // In this release, this is based solely on viewhint - NSString* viewHint = attributes[(id)kSecAttrSyncViewHint]; - bool itemIsForView = [viewHint isEqualToString: ckks.zoneName]; - if(!itemIsForView) { - - ckkserror("ckksincoming", ckks, "ViewHint in decrypted item (%@) does not match (%@), skipping item", viewHint, ckks.zoneName); - iqe.state = SecCKKSStateZoneMismatch; - [iqe saveToDatabase:&error]; - if(error) { - ckkserror("ckksincoming", ckks, "Couldn't save zone mismatch IQE to database: %@", error); - self.error = error; - } - continue; - } - if([iqe.action isEqualToString: SecCKKSActionAdd] || [iqe.action isEqualToString: SecCKKSActionModify]) { BOOL requireManifestValidation = [CKKSManifest shouldEnforceManifests]; BOOL manifestValidatesItem = [manifest validateItem:iqe.item withError:&error]; @@ -299,6 +267,33 @@ return true; } ++ (NSDictionary* _Nullable)decryptCKKSItemToAttributes:(CKKSItem*)item error:(NSError**)error +{ + NSMutableDictionary* attributes = [[CKKSItemEncrypter decryptItemToDictionary:item error:error] mutableCopy]; + if(!attributes) { + return nil; + } + + // Add the UUID (which isn't stored encrypted) + attributes[(__bridge NSString*)kSecAttrUUID] = item.uuid; + + // Add the PCS plaintext fields, if they exist + if(item.plaintextPCSServiceIdentifier) { + attributes[(__bridge NSString*)kSecAttrPCSPlaintextServiceIdentifier] = item.plaintextPCSServiceIdentifier; + } + if(item.plaintextPCSPublicKey) { + attributes[(__bridge NSString*)kSecAttrPCSPlaintextPublicKey] = item.plaintextPCSPublicKey; + } + if(item.plaintextPCSPublicIdentity) { + attributes[(__bridge NSString*)kSecAttrPCSPlaintextPublicIdentity] = item.plaintextPCSPublicIdentity; + } + + // This item is also synchronizable (by definition) + [attributes setValue:@(YES) forKey:(__bridge NSString*)kSecAttrSynchronizable]; + + return attributes; +} + - (bool)_onqueueUpdateIQE:(CKKSIncomingQueueEntry*)iqe withState:(NSString*)newState error:(NSError**)error { if (![iqe.state isEqualToString:newState]) { @@ -326,24 +321,24 @@ return; } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); self.completionBlock = ^(void) { - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf) { + STRONGIFY(self); + if (!self) { ckkserror("ckksincoming", ckks, "received callback for released object"); return; } CKKSAnalytics* logger = [CKKSAnalytics logger]; - if (!strongSelf.error) { + if (!self.error) { [logger logSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:ckks]; - if (!strongSelf.pendingClassAEntries) { + if (!self.pendingClassAEntries) { [logger logSuccessForEvent:CKKSEventProcessIncomingQueueClassA inView:ckks]; } } else { - [logger logRecoverableError:strongSelf.error - forEvent:strongSelf.errorOnClassAFailure ? CKKSEventProcessIncomingQueueClassA : CKKSEventProcessIncomingQueueClassC + [logger logRecoverableError:self.error + forEvent:self.errorOnClassAFailure ? CKKSEventProcessIncomingQueueClassA : CKKSEventProcessIncomingQueueClassC inView:ckks withAttributes:NULL]; } @@ -554,37 +549,26 @@ CFComparisonResult compare = CFStringCompare(itemUUID, olditemUUID, 0); CKKSOutgoingQueueEntry* oqe = nil; - switch(compare) { - case kCFCompareLessThan: - // item wins; delete olditem - ckksnotice("ckksincoming", ckks, "Primary key conflict; replacing %@ with CK item %@", olditem, item); - if(replace) { - *replace = CFRetainSafe(item); - moddate = (__bridge NSDate*) CFDictionaryGetValue(item->attributes, kSecAttrModificationDate); - } - + if (compare == kCFCompareGreaterThan) { + // olditem wins; don't change olditem; delete item + ckksnotice("ckksincoming", ckks, "Primary key conflict; dropping CK item %@", item); + oqe = [CKKSOutgoingQueueEntry withItem:item action:SecCKKSActionDelete ckks:ckks error:&error]; + [oqe saveToDatabase: &error]; + self.newOutgoingEntries = true; + moddate = nil; + } else { + // item wins + ckksnotice("ckksincoming", ckks, "Primary key conflict; replacing %@ with CK item %@", olditem, item); + if(replace) { + *replace = CFRetainSafe(item); + moddate = (__bridge NSDate*) CFDictionaryGetValue(item->attributes, kSecAttrModificationDate); + } + // delete olditem if UUID differs (same UUID is the normal update case) + if (compare != kCFCompareEqualTo) { oqe = [CKKSOutgoingQueueEntry withItem:olditem action:SecCKKSActionDelete ckks:ckks error:&error]; [oqe saveToDatabase: &error]; self.newOutgoingEntries = true; - break; - case kCFCompareGreaterThan: - // olditem wins; don't change olditem; delete item - ckksnotice("ckksincoming", ckks, "Primary key conflict; dropping CK item %@", item); - - oqe = [CKKSOutgoingQueueEntry withItem:item action:SecCKKSActionDelete ckks:ckks error:&error]; - [oqe saveToDatabase: &error]; - self.newOutgoingEntries = true; - moddate = nil; - break; - - case kCFCompareEqualTo: - // remote item wins; this is the normal update case - ckksnotice("ckksincoming", ckks, "Primary key conflict; replacing %@ with CK item %@", olditem, item); - if(replace) { - *replace = CFRetainSafe(item); - moddate = (__bridge NSDate*) CFDictionaryGetValue(item->attributes, kSecAttrModificationDate); - } - break; + } } }); @@ -631,9 +615,12 @@ } if(moddate) { - // Log the number of seconds it took to propagate this change - uint64_t secondsDelay = (uint64_t) ([[NSDate date] timeIntervalSinceDate:moddate]); - SecADClientPushValueForDistributionKey((__bridge CFStringRef) SecCKKSAggdPropagationDelay, secondsDelay); + // Log the number of ms it took to propagate this change + uint64_t delayInMS = [[NSDate date] timeIntervalSinceDate:moddate] * 1000; + [SecCoreAnalytics sendEvent:@"com.apple.ckks.item.propagation" event:@{ + @"time" : @(delayInMS) + }]; + } } else { diff --git a/keychain/ckks/CKKSItem.m b/keychain/ckks/CKKSItem.m index 88d9841b..144b04fc 100644 --- a/keychain/ckks/CKKSItem.m +++ b/keychain/ckks/CKKSItem.m @@ -428,32 +428,32 @@ 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), @"encitem": self.base64encitem, @"wrappedkey": [self.wrappedkey base64WrappedKey], - @"gencount": [NSNumber numberWithInteger:self.generationCount], - @"encver": [NSNumber numberWithInteger:self.encver], + @"gencount": [[NSNumber numberWithInteger:self.generationCount] stringValue], + @"encver": [[NSNumber numberWithInteger:self.encver] stringValue], @"ckrecord": CKKSNilToNSNull([self.encodedCKRecord base64EncodedStringWithOptions:0]), @"pcss": CKKSNilToNSNull(self.plaintextPCSServiceIdentifier), @"pcsk": CKKSNilToNSNull([self.plaintextPCSPublicKey base64EncodedStringWithOptions:0]), @"pcsi": CKKSNilToNSNull([self.plaintextPCSPublicIdentity base64EncodedStringWithOptions:0])}; } -+ (instancetype)fromDatabaseRow: (NSDictionary*) row { - return [[CKKSItem alloc] initWithUUID:row[@"UUID"] - parentKeyUUID:row[@"parentKeyUUID"] - zoneID:[[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"] ownerName:CKCurrentUserDefaultName] - encodedCKRecord:CKKSUnbase64NullableString(row[@"ckrecord"]) - encItem:CKKSUnbase64NullableString(row[@"encitem"]) - wrappedkey:CKKSIsNull(row[@"wrappedkey"]) ? nil : [[CKKSWrappedAESSIVKey alloc] initWithBase64: row[@"wrappedkey"]] - generationCount:[row[@"gencount"] integerValue] - encver:[row[@"encver"] integerValue] - plaintextPCSServiceIdentifier:CKKSIsNull(row[@"pcss"]) ? nil : [NSNumber numberWithInteger: [row[@"pcss"] integerValue]] - plaintextPCSPublicKey:CKKSUnbase64NullableString(row[@"pcsk"]) - plaintextPCSPublicIdentity:CKKSUnbase64NullableString(row[@"pcsi"]) ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + return [[CKKSItem alloc] initWithUUID:row[@"UUID"].asString + parentKeyUUID:row[@"parentKeyUUID"].asString + zoneID:[[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"].asString ownerName:CKCurrentUserDefaultName] + encodedCKRecord:row[@"ckrecord"].asBase64DecodedData + encItem:row[@"encitem"].asBase64DecodedData + wrappedkey:row[@"wrappedkey"].asString == nil ? nil : [[CKKSWrappedAESSIVKey alloc] initWithBase64:row[@"wrappedkey"].asString] + generationCount:row[@"gencount"].asNSInteger + encver:row[@"encver"].asNSInteger + plaintextPCSServiceIdentifier:row[@"pcss"].asNSNumberInteger + plaintextPCSPublicKey:row[@"pcsk"].asBase64DecodedData + plaintextPCSPublicIdentity:row[@"pcsi"].asBase64DecodedData ]; } @@ -464,7 +464,7 @@ plaintextPCSServiceIdentifier: (NSNumber*) pcsServiceIdentifier @implementation CKKSSQLDatabaseObject (CKKSZoneExtras) + (NSArray*)allUUIDs:(CKRecordZoneID*)zoneID error:(NSError * __autoreleasing *)error { - __block NSMutableArray* uuids = [[NSMutableArray alloc] init]; + __block NSMutableArray* uuids = [[NSMutableArray alloc] init]; [CKKSSQLDatabaseObject queryDatabaseTable: [self sqlTable] where:@{@"ckzone": CKKSNilToNSNull(zoneID.zoneName)} @@ -472,8 +472,8 @@ plaintextPCSServiceIdentifier: (NSNumber*) pcsServiceIdentifier groupBy: nil orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - [uuids addObject: row[@"UUID"]]; + processRow:^(NSDictionary* row) { + [uuids addObject: row[@"UUID"].asString]; } error: error]; return uuids; diff --git a/keychain/ckks/CKKSKey.h b/keychain/ckks/CKKSKey.h index ae5842fd..766e5479 100644 --- a/keychain/ckks/CKKSKey.h +++ b/keychain/ckks/CKKSKey.h @@ -26,62 +26,66 @@ #import #import "keychain/ckks/CKKSItem.h" +#import "keychain/ckks/CKKSKeychainBackedKey.h" #import "keychain/ckks/CKKSSIV.h" #import "keychain/ckks/CKKSPeer.h" -#import "keychain/ckks/proto/source/CKKSSerializedKey.h" +#import "keychain/ckks/proto/generated_source/CKKSSerializedKey.h" -@interface CKKSKey : CKKSItem +NS_ASSUME_NONNULL_BEGIN -@property (readonly) CKKSAESSIVKey* aessivkey; +@interface CKKSKey : CKKSCKRecordHolder +@property CKKSKeychainBackedKey* keycore; -@property (copy) CKKSProcessedState* state; +@property NSString* uuid; +@property NSString* parentKeyUUID; @property (copy) CKKSKeyClass* keyclass; + +@property (copy) CKKSWrappedAESSIVKey* wrappedkey; +@property (nullable, readonly) CKKSAESSIVKey* aessivkey; + +@property (copy) CKKSProcessedState* state; @property bool currentkey; // Fetches and attempts to unwrap this key for use -+ (instancetype)loadKeyWithUUID:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)loadKeyWithUUID:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; // Creates new random keys, in the parent's zone -+ (instancetype)randomKeyWrappedByParent:(CKKSKey*)parentKey error:(NSError* __autoreleasing*)error; -+ (instancetype)randomKeyWrappedByParent:(CKKSKey*)parentKey - keyclass:(CKKSKeyClass*)keyclass - error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)randomKeyWrappedByParent:(CKKSKey*)parentKey error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)randomKeyWrappedByParent:(CKKSKey*)parentKey + keyclass:(CKKSKeyClass*)keyclass + error:(NSError* __autoreleasing*)error; // Creates a new random key that wraps itself -+ (instancetype)randomKeyWrappedBySelf:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)randomKeyWrappedBySelf:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; /* Helper functions for persisting key material in the keychain */ -- (bool)saveKeyMaterialToKeychain:(NSError* __autoreleasing*)error; -- (bool)saveKeyMaterialToKeychain:(bool)stashTLK +- (BOOL)saveKeyMaterialToKeychain:(NSError* __autoreleasing*)error; +- (BOOL)saveKeyMaterialToKeychain:(bool)stashTLK error:(NSError* __autoreleasing*)error; // call this to not stash a non-syncable TLK, if that's what you want -- (bool)loadKeyMaterialFromKeychain:(NSError* __autoreleasing*)error; -- (bool)deleteKeyMaterialFromKeychain:(NSError* __autoreleasing*)error; -+ (NSString*)isItemKeyForKeychainView:(SecDbItemRef)item; - -// Class methods to help tests -+ (NSDictionary*)setKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing*)error; -+ (NSDictionary*)queryKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing*)error; +- (BOOL)loadKeyMaterialFromKeychain:(NSError* __autoreleasing*)error; +- (BOOL)deleteKeyMaterialFromKeychain:(NSError* __autoreleasing*)error; ++ (NSString* _Nullable)isItemKeyForKeychainView:(SecDbItemRef)item; -+ (instancetype)keyFromKeychain:(NSString*)uuid - parentKeyUUID:(NSString*)parentKeyUUID - keyclass:(CKKSKeyClass*)keyclass - state:(CKKSProcessedState*)state - zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord - currentkey:(NSInteger)currentkey - error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)keyFromKeychain:(NSString*)uuid + parentKeyUUID:(NSString*)parentKeyUUID + keyclass:(CKKSKeyClass*)keyclass + state:(CKKSProcessedState*)state + zoneID:(CKRecordZoneID*)zoneID + encodedCKRecord:(NSData* _Nullable)encodedrecord + currentkey:(NSInteger)currentkey + error:(NSError* __autoreleasing*)error; -+ (instancetype)fromDatabase:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (instancetype)tryFromDatabase:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (instancetype)tryFromDatabaseAnyState:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)fromDatabase:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)tryFromDatabase:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)tryFromDatabaseAnyState:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (NSArray*)selfWrappedKeys:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSArray* _Nullable)selfWrappedKeys:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (instancetype)currentKeyForClass:(CKKSKeyClass*)keyclass zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; -+ (NSArray*)currentKeysForClass:(CKKSKeyClass*)keyclass ++ (instancetype _Nullable)currentKeyForClass:(CKKSKeyClass*)keyclass zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSArray* _Nullable)currentKeysForClass:(CKKSKeyClass*)keyclass state:(CKKSProcessedState*)state zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; @@ -99,7 +103,7 @@ keyclass:(CKKSKeyClass*)keyclass state:(CKKSProcessedState*)state zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord + encodedCKRecord:(NSData* _Nullable)encodedrecord currentkey:(NSInteger)currentkey; - (instancetype)initWrappedBy:(CKKSKey*)wrappingKey @@ -108,24 +112,24 @@ keyclass:(CKKSKeyClass*)keyclass state:(CKKSProcessedState*)state zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord + encodedCKRecord:(NSData* _Nullable)encodedrecord currentkey:(NSInteger)currentkey; -- (instancetype)initWithWrappedAESKey:(CKKSWrappedAESSIVKey*)wrappedaeskey +- (instancetype)initWithWrappedAESKey:(CKKSWrappedAESSIVKey* _Nullable)wrappedaeskey uuid:(NSString*)uuid parentKeyUUID:(NSString*)parentKeyUUID keyclass:(CKKSKeyClass*)keyclass state:(CKKSProcessedState*)state zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedrecord + encodedCKRecord:(NSData* _Nullable)encodedrecord currentkey:(NSInteger)currentkey; +- (instancetype)initWithKeyCore:(CKKSKeychainBackedKey*)core; + /* Returns true if we believe this key wraps itself. */ - (bool)wrapsSelf; -- (void)zeroKeys; - -- (CKKSKey*)topKeyInAnyState:(NSError* __autoreleasing*)error; +- (CKKSKey* _Nullable)topKeyInAnyState:(NSError* __autoreleasing*)error; // Attempts checks if the AES key is already loaded, or attempts to load it from the keychain. Returns false if it fails. - (CKKSAESSIVKey*)ensureKeyLoaded:(NSError* __autoreleasing*)error; @@ -141,19 +145,20 @@ - (CKKSAESSIVKey*)unwrapAESKey:(CKKSWrappedAESSIVKey*)keyToUnwrap error:(NSError* __autoreleasing*)error; - (bool)wrapUnder:(CKKSKey*)wrappingKey error:(NSError* __autoreleasing*)error; -- (bool)unwrapSelfWithAESKey:(CKKSAESSIVKey*)unwrappingKey error:(NSError* __autoreleasing*)error; -- (NSData*)encryptData:(NSData*)plaintext - authenticatedData:(NSDictionary*)ad - error:(NSError* __autoreleasing*)error; -- (NSData*)decryptData:(NSData*)ciphertext - authenticatedData:(NSDictionary*)ad - error:(NSError* __autoreleasing*)error; +- (NSData* _Nullable)encryptData:(NSData*)plaintext + authenticatedData:(NSDictionary* _Nullable)ad + error:(NSError* __autoreleasing*)error; +- (NSData* _Nullable)decryptData:(NSData*)ciphertext + authenticatedData:(NSDictionary* _Nullable)ad + error:(NSError* __autoreleasing*)error; -- (NSData*)serializeAsProtobuf:(NSError* __autoreleasing*)error; -+ (CKKSKey*)loadFromProtobuf:(NSData*)data error:(NSError* __autoreleasing*)error; +- (NSData* _Nullable)serializeAsProtobuf:(NSError* __autoreleasing*)error; ++ (CKKSKey* _Nullable)loadFromProtobuf:(NSData*)data error:(NSError* __autoreleasing*)error; + (NSDictionary*)countsByClass:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; @end +NS_ASSUME_NONNULL_END + #endif diff --git a/keychain/ckks/CKKSKey.m b/keychain/ckks/CKKSKey.m index 441080b9..8cfa8b41 100644 --- a/keychain/ckks/CKKSKey.m +++ b/keychain/ckks/CKKSKey.m @@ -31,13 +31,12 @@ #include #include #include +#include "OSX/sec/Security/SecItemShim.h" #include #include -@interface CKKSKey () -@property CKKSAESSIVKey* aessivkey; -@end +#import @implementation CKKSKey @@ -54,28 +53,20 @@ encodedCKRecord: (NSData*) encodedrecord currentkey: (NSInteger) currentkey { - if(self = [super initWithUUID: uuid - parentKeyUUID: uuid - zoneID: zoneID - encodedCKRecord: encodedrecord - encItem: nil - wrappedkey: nil - generationCount: 0 - encver: currentCKKSItemEncryptionVersion]) { - _keyclass = keyclass; - _currentkey = !!currentkey; - _aessivkey = aeskey; - _state = state; - - self.ckRecordType = SecCKRecordIntermediateKeyType; - - // Wrap the key with the key. Not particularly useful, but there you go. - NSError* error = nil; - [self wrapUnder: self error:&error]; - if(error != nil) { - secerror("CKKSKey: Couldn't self-wrap key: %@", error); + if((self = [super initWithCKRecordType:SecCKRecordIntermediateKeyType + encodedCKRecord:encodedrecord + zoneID:zoneID])) { + + _keycore = [[CKKSKeychainBackedKey alloc] initSelfWrappedWithAESKey:aeskey + uuid:uuid + keyclass:keyclass + zoneID:zoneID]; + if(!_keycore) { return nil; } + + _currentkey = !!currentkey; + _state = state; } return self; } @@ -89,28 +80,20 @@ encodedCKRecord: (NSData*) encodedrecord currentkey: (NSInteger) currentkey { - if(self = [super initWithUUID: uuid - parentKeyUUID: wrappingKey.uuid - zoneID: zoneID - encodedCKRecord: encodedrecord - encItem:nil - wrappedkey:nil - generationCount:0 - encver: - currentCKKSItemEncryptionVersion]) { - _keyclass = keyclass; - _currentkey = !!currentkey; - _aessivkey = aeskey; - _state = state; - - self.ckRecordType = SecCKRecordIntermediateKeyType; - - NSError* error = nil; - [self wrapUnder: wrappingKey error:&error]; - if(error != nil) { - secerror("CKKSKey: Couldn't wrap key with key: %@", error); + if((self = [super initWithCKRecordType:SecCKRecordIntermediateKeyType + encodedCKRecord:encodedrecord + zoneID:zoneID])) { + _keycore = [[CKKSKeychainBackedKey alloc] initWrappedBy:wrappingKey.keycore + AESKey:aeskey + uuid:uuid + keyclass:keyclass + zoneID:zoneID]; + if(!_keycore) { return nil; } + + _currentkey = !!currentkey; + _state = state; } return self; } @@ -124,49 +107,100 @@ encodedCKRecord: (NSData*) encodedrecord currentkey: (NSInteger) currentkey { - if(self = [super initWithUUID:uuid - parentKeyUUID:parentKeyUUID - zoneID:zoneID - encodedCKRecord:encodedrecord - encItem:nil - wrappedkey:wrappedaeskey - generationCount:0 - encver:currentCKKSItemEncryptionVersion]) { - _keyclass = keyclass; + if((self = [super initWithCKRecordType:SecCKRecordIntermediateKeyType + encodedCKRecord:encodedrecord + zoneID:zoneID])) { + + _keycore = [[CKKSKeychainBackedKey alloc] initWithWrappedAESKey:wrappedaeskey + uuid:uuid + parentKeyUUID:parentKeyUUID + keyclass:keyclass + zoneID:zoneID]; + _currentkey = !!currentkey; - _aessivkey = nil; _state = state; + } + return self; +} - self.ckRecordType = SecCKRecordIntermediateKeyType; +- (instancetype)initWithKeyCore:(CKKSKeychainBackedKey*)core +{ + if((self = [super initWithCKRecordType:SecCKRecordIntermediateKeyType + encodedCKRecord:nil + zoneID:core.zoneID])) { + _keycore = core; + _currentkey = false; + _state = SecCKKSProcessedStateRemote; } return self; } - (void)dealloc { - [self zeroKeys]; } -- (void)zeroKeys { - [self.aessivkey zeroKey]; +- (BOOL)isEqual:(id)object { + if(![object isKindOfClass:[CKKSKey class]]) { + return NO; + } + + CKKSKey* obj = (CKKSKey*)object; + + // Equality ignores state, currentkey, and CK record differences. Be careful... + return [self.keycore isEqual:obj.keycore] ? YES : NO; +} + +// These used to be properties on CKKSKey, but are now properties on the actual key inside +- (NSString*)uuid +{ + return self.keycore.uuid; } -- (bool)wrapsSelf { - return [self.uuid isEqual: self.parentKeyUUID]; +- (void)setUuid:(NSString *)uuid +{ + self.keycore.uuid = uuid; } -- (bool)wrapUnder: (CKKSKey*) wrappingKey error: (NSError * __autoreleasing *) error { - self.wrappedkey = [wrappingKey wrapAESKey: self.aessivkey error:error]; - if(self.wrappedkey == nil) { - secerror("CKKSKey: couldn't wrap key: %@", error ? *error : @"unknown error"); - } else { - self.parentKeyUUID = wrappingKey.uuid; - } - return (self.wrappedkey != nil); +- (NSString*)parentKeyUUID +{ + return self.keycore.parentKeyUUID; +} + +- (void)setParentKeyUUID:(NSString *)parentKeyUUID +{ + self.keycore.parentKeyUUID = parentKeyUUID; +} + +- (CKKSKeyClass*)keyclass +{ + return self.keycore.keyclass; +} + +- (void)setKeyclass:(CKKSKeyClass*)keyclass +{ + self.keycore.keyclass = keyclass; +} + +- (CKKSWrappedAESSIVKey*)wrappedkey +{ + return self.keycore.wrappedkey; +} + +- (void)setWrappedkey:(CKKSWrappedAESSIVKey*)wrappedkey +{ + self.keycore.wrappedkey = wrappedkey; } -- (bool)unwrapSelfWithAESKey: (CKKSAESSIVKey*) unwrappingKey error: (NSError * __autoreleasing *) error { - _aessivkey = [unwrappingKey unwrapAESKey:self.wrappedkey error:error]; - return (_aessivkey != nil); +- (CKKSAESSIVKey*)aessivkey +{ + return self.keycore.aessivkey; +} + +- (bool)wrapsSelf { + return [self.keycore wrapsSelf]; +} + +- (bool)wrapUnder: (CKKSKey*) wrappingKey error: (NSError * __autoreleasing *) error { + return [self.keycore wrapUnder:wrappingKey.keycore error:error]; } + (instancetype) loadKeyWithUUID: (NSString*) uuid zoneID:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { @@ -184,7 +218,10 @@ } + (CKKSKey*) randomKeyWrappedByParent: (CKKSKey*) parentKey keyclass:(CKKSKeyClass*)keyclass error: (NSError * __autoreleasing *) error { - CKKSAESSIVKey* aessivkey = [CKKSAESSIVKey randomKey]; + CKKSAESSIVKey* aessivkey = [CKKSAESSIVKey randomKey:error]; + if(aessivkey == nil) { + return nil; + } CKKSKey* key = [[CKKSKey alloc] initWrappedBy: parentKey AESKey: aessivkey @@ -198,7 +235,11 @@ } + (instancetype)randomKeyWrappedBySelf: (CKRecordZoneID*) zoneID error: (NSError * __autoreleasing *) error { - CKKSAESSIVKey* aessivkey = [CKKSAESSIVKey randomKey]; + CKKSAESSIVKey* aessivkey = [CKKSAESSIVKey randomKey:error]; + if(aessivkey == nil) { + return nil; + } + NSString* uuid = [[NSUUID UUID] UUIDString]; CKKSKey* key = [[CKKSKey alloc] initSelfWrappedWithAESKey: aessivkey @@ -213,35 +254,46 @@ } - (CKKSKey*)topKeyInAnyState: (NSError * __autoreleasing *) error { - // Recursively find the top-level key in the hierarchy, preferring 'remote' keys. - if([self wrapsSelf]) { - return self; - } + NSMutableSet* seenUUID = [[NSMutableSet alloc] init]; + CKKSKey* key = self; - CKKSKey* remoteParent = [CKKSKey tryFromDatabaseWhere: @{@"UUID": self.parentKeyUUID, @"state": SecCKKSProcessedStateRemote} error: error]; - if(remoteParent) { - return [remoteParent topKeyInAnyState: error]; - } + // Find the top-level key in the hierarchy. + while (key) { + if([key wrapsSelf]) { + return key; + } + + // Check for circular references. + if([seenUUID containsObject:key.uuid]) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSCircularKeyReference + description:@"Circular reference in key hierarchy"]; + return nil; + } + + [seenUUID addObject:key.uuid]; + + // Prefer 'remote' parents. + CKKSKey* parent = [CKKSKey tryFromDatabaseWhere: @{@"UUID": key.parentKeyUUID, @"state": SecCKKSProcessedStateRemote} error: error]; - // No remote parent. Fall back to anything. - CKKSKey* parent = [CKKSKey fromDatabaseWhere: @{@"UUID": self.parentKeyUUID} error: error]; - if(parent) { - return [parent topKeyInAnyState: error]; + // No remote parent. Fall back to anything. + if(parent == nil) { + parent = [CKKSKey fromDatabaseWhere: @{@"UUID": key.parentKeyUUID} error: error]; + } + + key = parent; } - // No good. Error is already filled. + // Couldn't get the parent. Error is already filled. return nil; } - (CKKSAESSIVKey*)ensureKeyLoaded: (NSError * __autoreleasing *) error { - if(self.aessivkey) { - return self.aessivkey; - } - - // Attempt to load this key from the keychain NSError* keychainError = nil; - if([self loadKeyMaterialFromKeychain:&keychainError]) { - return self.aessivkey; + + CKKSAESSIVKey* sivkey = [self.keycore ensureKeyLoaded:&keychainError]; + if(sivkey) { + return sivkey; } // Uhh, okay, if that didn't work, try to unwrap via the key hierarchy @@ -264,7 +316,6 @@ return nil; } - - (CKKSAESSIVKey*)unwrapViaKeyHierarchy: (NSError * __autoreleasing *) error { if(self.aessivkey) { return self.aessivkey; @@ -273,7 +324,7 @@ NSError* localerror = nil; // Attempt to load this key from the keychain - if([self loadKeyMaterialFromKeychain:&localerror]) { + if([self.keycore loadKeyMaterialFromKeychain:&localerror]) { // Rad. Success! return self.aessivkey; } @@ -297,396 +348,45 @@ return nil; } - _aessivkey = [parent unwrapAESKey:self.wrappedkey error:error]; + self.keycore.aessivkey = [parent unwrapAESKey:self.wrappedkey error:error]; return self.aessivkey; } - (bool)trySelfWrappedKeyCandidate:(CKKSAESSIVKey*)candidate error:(NSError * __autoreleasing *) error { - if(![self wrapsSelf]) { - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSKeyNotSelfWrapped userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"%@ is not self-wrapped", self]}]; - } - return false; - } - - CKKSAESSIVKey* unwrapped = [candidate unwrapAESKey:self.wrappedkey error:error]; - if(unwrapped && [unwrapped isEqual: candidate]) { - _aessivkey = unwrapped; - return true; - } - - return false; + return [self.keycore trySelfWrappedKeyCandidate:candidate error:error]; } - (CKKSWrappedAESSIVKey*)wrapAESKey: (CKKSAESSIVKey*) keyToWrap error: (NSError * __autoreleasing *) error { - CKKSAESSIVKey* key = [self ensureKeyLoaded: error]; - CKKSWrappedAESSIVKey* wrappedkey = [key wrapAESKey: keyToWrap error:error]; - return wrappedkey; + return [self.keycore wrapAESKey:keyToWrap error:error]; } - (CKKSAESSIVKey*)unwrapAESKey: (CKKSWrappedAESSIVKey*) keyToUnwrap error: (NSError * __autoreleasing *) error { - CKKSAESSIVKey* key = [self ensureKeyLoaded: error]; - CKKSAESSIVKey* unwrappedkey = [key unwrapAESKey: keyToUnwrap error:error]; - return unwrappedkey; + return [self.keycore unwrapAESKey:keyToUnwrap error:error]; } - (NSData*)encryptData: (NSData*) plaintext authenticatedData: (NSDictionary*) ad error: (NSError * __autoreleasing *) error { - CKKSAESSIVKey* key = [self ensureKeyLoaded: error]; - NSData* data = [key encryptData: plaintext authenticatedData:ad error:error]; - return data; + return [self.keycore encryptData:plaintext authenticatedData:ad error:error]; } - (NSData*)decryptData: (NSData*) ciphertext authenticatedData: (NSDictionary*) ad error: (NSError * __autoreleasing *) error { - CKKSAESSIVKey* key = [self ensureKeyLoaded: error]; - NSData* data = [key decryptData: ciphertext authenticatedData:ad error:error]; - return data; + return [self.keycore decryptData:ciphertext authenticatedData:ad error:error]; } /* Functions to load and save keys from the keychain (where we get to store actual key material!) */ -- (bool)saveKeyMaterialToKeychain: (NSError * __autoreleasing *) error { - return [self saveKeyMaterialToKeychain: true error: error]; -} - -- (bool)saveKeyMaterialToKeychain: (bool)stashTLK error:(NSError * __autoreleasing *) error { - - // Note that we only store the key class, view, UUID, parentKeyUUID, and key material in the keychain - // Any other metadata must be stored elsewhere and filled in at load time. - - if(![self ensureKeyLoaded:error]) { - // No key material, nothing to save to keychain. - return false; - } - - // iOS keychains can't store symmetric keys, so we're reduced to storing this key as a password - NSData* keydata = [[[NSData alloc] initWithBytes:self.aessivkey->key length:self.aessivkey->size] base64EncodedDataWithOptions:0]; - NSMutableDictionary* query = [@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup: @"com.apple.security.ckks", - (id)kSecAttrDescription: self.keyclass, - (id)kSecAttrServer: self.zoneID.zoneName, - (id)kSecAttrAccount: self.uuid, - (id)kSecAttrPath: self.parentKeyUUID, - (id)kSecAttrIsInvisible: @YES, - (id)kSecValueData : keydata, - } mutableCopy]; - - // Only TLKs are synchronizable. Other keyclasses must synchronize via key hierarchy. - if([self.keyclass isEqualToString: SecCKKSKeyClassTLK]) { - // Use PCS-MasterKey view so they'll be initial-synced under SOS. - query[(id)kSecAttrSyncViewHint] = (id)kSecAttrViewHintPCSMasterKey; - query[(id)kSecAttrSynchronizable] = (id)kCFBooleanTrue; - } - - // Class C keys are accessible after first unlock; TLKs and Class A keys are accessible only when unlocked - if([self.keyclass isEqualToString: SecCKKSKeyClassC]) { - query[(id)kSecAttrAccessible] = (id)kSecAttrAccessibleAfterFirstUnlock; - } else { - query[(id)kSecAttrAccessible] = (id)kSecAttrAccessibleWhenUnlocked; - } - - NSError* localError = nil; - [CKKSKey setKeyMaterialInKeychain:query error:&localError]; - - if(localError && error) { - *error = [NSError errorWithDomain:@"securityd" - code:localError.code - userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Couldn't save %@ to keychain: %d", self, (int)localError.code], - NSUnderlyingErrorKey: localError, - }]; - } - - // TLKs are synchronizable. Stash them nonsyncably nearby. - // Don't report errors here. - if(stashTLK && [self.keyclass isEqualToString: SecCKKSKeyClassTLK]) { - query = [@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup: @"com.apple.security.ckks", - (id)kSecAttrDescription: [self.keyclass stringByAppendingString: @"-nonsync"], - (id)kSecAttrServer: self.zoneID.zoneName, - (id)kSecAttrAccount: self.uuid, - (id)kSecAttrPath: self.parentKeyUUID, - (id)kSecAttrIsInvisible: @YES, - (id)kSecValueData : keydata, - } mutableCopy]; - query[(id)kSecAttrSynchronizable] = (id)kCFBooleanFalse; - - NSError* stashError = nil; - [CKKSKey setKeyMaterialInKeychain:query error:&localError]; - - if(stashError) { - secerror("ckkskey: Couldn't stash %@ to keychain: %@", self, stashError); - } - } - - return localError == nil; -} - -+ (NSDictionary*)setKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing *)error { - CFTypeRef result = NULL; - OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &result); - - NSError* localerror = nil; - - // Did SecItemAdd fall over due to an existing item? - if(status == errSecDuplicateItem) { - // Add every primary key attribute to this find dictionary - NSMutableDictionary* findQuery = [[NSMutableDictionary alloc] init]; - findQuery[(id)kSecClass] = query[(id)kSecClass]; - findQuery[(id)kSecAttrSynchronizable] = query[(id)kSecAttrSynchronizable]; - findQuery[(id)kSecAttrSyncViewHint] = query[(id)kSecAttrSyncViewHint]; - findQuery[(id)kSecAttrAccessGroup] = query[(id)kSecAttrAccessGroup]; - findQuery[(id)kSecAttrAccount] = query[(id)kSecAttrAccount]; - findQuery[(id)kSecAttrServer] = query[(id)kSecAttrServer]; - findQuery[(id)kSecAttrPath] = query[(id)kSecAttrPath]; - - NSMutableDictionary* updateQuery = [query mutableCopy]; - updateQuery[(id)kSecClass] = nil; - - status = SecItemUpdate((__bridge CFDictionaryRef)findQuery, (__bridge CFDictionaryRef)updateQuery); - - if(status) { - localerror = [NSError errorWithDomain:@"securityd" - code:status - description:[NSString stringWithFormat:@"SecItemUpdate: %d", (int)status]]; - } - } else { - localerror = [NSError errorWithDomain:@"securityd" - code:status - description: [NSString stringWithFormat:@"SecItemAdd: %d", (int)status]]; - } - - if(status) { - CFReleaseNull(result); - - if(error) { - *error = localerror; - } - return false; - } - - NSDictionary* resultDict = CFBridgingRelease(result); - return resultDict; +- (BOOL)saveKeyMaterialToKeychain: (NSError * __autoreleasing *) error { + return [self.keycore saveKeyMaterialToKeychain:true error: error]; } -+ (NSDictionary*)queryKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing *)error { - CFTypeRef result = NULL; - OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); - - if(status) { - CFReleaseNull(result); - - if(error) { - *error = [NSError errorWithDomain:@"securityd" - code:status - userInfo:@{NSLocalizedDescriptionKey: - [NSString stringWithFormat:@"SecItemCopyMatching: %d", (int)status]}]; - } - return false; - } - - NSDictionary* resultDict = CFBridgingRelease(result); - return resultDict; -} - -+ (NSDictionary*)fetchKeyMaterialItemFromKeychain:(CKKSKey*)key resave:(bool*)resavePtr error:(NSError* __autoreleasing *)error { - NSMutableDictionary* query = [@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup : @"com.apple.security.ckks", - (id)kSecAttrDescription: key.keyclass, - (id)kSecAttrAccount: key.uuid, - (id)kSecAttrServer: key.zoneID.zoneName, - (id)kSecAttrPath: key.parentKeyUUID, - (id)kSecReturnAttributes: @YES, - (id)kSecReturnData: @YES, - } mutableCopy]; - - // Synchronizable items are only found if you request synchronizable items. Only TLKs are synchronizable. - if([key.keyclass isEqualToString: SecCKKSKeyClassTLK]) { - query[(id)kSecAttrSynchronizable] = (id)kCFBooleanTrue; - } - - NSError* localError = nil; - NSDictionary* result = [self queryKeyMaterialInKeychain:query error:&localError]; - NSError* originalError = localError; - - // If we found the item or errored in some interesting way, return. - if(result) { - return result; - } - if(localError && localError.code != errSecItemNotFound) { - if(error) { - *error = [NSError errorWithDomain:@"securityd" - code:localError.code - userInfo:@{NSLocalizedDescriptionKey: - [NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", key, (int)localError.code], - NSUnderlyingErrorKey: localError, - }]; - } - return result; - } - localError = nil; - - if([key.keyclass isEqualToString: SecCKKSKeyClassTLK]) { - //didn't find a regular tlk? how about a piggy? - query = [@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup : @"com.apple.security.ckks", - (id)kSecAttrDescription: [key.keyclass stringByAppendingString: @"-piggy"], - (id)kSecAttrSynchronizable : (id)kSecAttrSynchronizableAny, - (id)kSecAttrAccount: [NSString stringWithFormat: @"%@-piggy", key.uuid], - (id)kSecAttrServer: key.zoneID.zoneName, - (id)kSecReturnAttributes: @YES, - (id)kSecReturnData: @YES, - (id)kSecMatchLimit: (id)kSecMatchLimitOne, - } mutableCopy]; - - result = [self queryKeyMaterialInKeychain:query error:&localError]; - if(localError == nil) { - secnotice("ckkskey", "loaded a piggy TLK (%@)", key.uuid); - - if(resavePtr) { - *resavePtr = true; - } - - return result; - } - - if(localError && localError.code != errSecItemNotFound) { - if(error) { - *error = [NSError errorWithDomain:@"securityd" - code:localError.code - userInfo:@{NSLocalizedDescriptionKey: - [NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", key, (int)localError.code], - NSUnderlyingErrorKey: localError, - }]; - } - return nil; - } - } - - localError = nil; - - // Try to load a stashed TLK - if([key.keyclass isEqualToString: SecCKKSKeyClassTLK]) { - localError = nil; - - // Try to look for the non-syncable stashed tlk and resurrect it. - query = [@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup : @"com.apple.security.ckks", - (id)kSecAttrDescription: [key.keyclass stringByAppendingString: @"-nonsync"], - (id)kSecAttrServer: key.zoneID.zoneName, - (id)kSecAttrAccount: key.uuid, - (id)kSecReturnAttributes: @YES, - (id)kSecReturnData: @YES, - (id)kSecAttrSynchronizable: @NO, - } mutableCopy]; - - result = [self queryKeyMaterialInKeychain:query error:&localError]; - if(localError == nil) { - secnotice("ckkskey", "loaded a stashed TLK (%@)", key.uuid); - - if(resavePtr) { - *resavePtr = true; - } - - return result; - } - - if(localError && localError.code != errSecItemNotFound) { - if(error) { - *error = [NSError errorWithDomain:@"securityd" - code:localError.code - userInfo:@{NSLocalizedDescriptionKey: - [NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", key, (int)localError.code], - NSUnderlyingErrorKey: localError, - }]; - } - return nil; - } - } - - // We didn't early-return. Use whatever error the original fetch produced. - if(error) { - *error = [NSError errorWithDomain:@"securityd" - code:originalError ? originalError.code : errSecParam - description:[NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", key, (int)originalError.code] - underlying:originalError]; - } - - return result; +- (BOOL)saveKeyMaterialToKeychain: (bool)stashTLK error:(NSError * __autoreleasing *) error { + return [self.keycore saveKeyMaterialToKeychain:stashTLK error:error]; } -- (bool)loadKeyMaterialFromKeychain: (NSError * __autoreleasing *) error { - bool resave = false; - NSDictionary* result = [CKKSKey fetchKeyMaterialItemFromKeychain:self resave:&resave error:error]; - if(!result) { - return false; - } - - NSData* b64keymaterial = result[(id)kSecValueData]; - NSData* keymaterial = [[NSData alloc] initWithBase64EncodedData:b64keymaterial options:0]; - if(!keymaterial) { - secnotice("ckkskey", "Unable to unbase64 key: %@", self); - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSKeyUnknownFormat - description:[NSString stringWithFormat:@"unable to unbase64 key: %@", self]]; - } - return false; - } - - CKKSAESSIVKey* key = [[CKKSAESSIVKey alloc] initWithBytes: (uint8_t*) keymaterial.bytes len:keymaterial.length]; - self.aessivkey = key; - - if(resave) { - secnotice("ckkskey", "Resaving %@ as per request", self); - NSError* resaveError = nil; - [self saveKeyMaterialToKeychain:&resaveError]; - if(resaveError) { - secnotice("ckkskey", "Resaving %@ failed: %@", self, resaveError); - } - } - - return !!(self.aessivkey); +- (BOOL)loadKeyMaterialFromKeychain: (NSError * __autoreleasing *) error { + return [self.keycore loadKeyMaterialFromKeychain:error]; } -- (bool)deleteKeyMaterialFromKeychain: (NSError * __autoreleasing *) error { - - NSMutableDictionary* query = [@{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrAccessGroup : @"com.apple.security.ckks", - (id)kSecAttrDescription: self.keyclass, - (id)kSecAttrAccount: self.uuid, - (id)kSecAttrServer: self.zoneID.zoneName, - (id)kSecReturnData: @YES, - } mutableCopy]; - - // Synchronizable items are only found if you request synchronizable items. Only TLKs are synchronizable. - if([self.keyclass isEqualToString: SecCKKSKeyClassTLK]) { - query[(id)kSecAttrSynchronizable] = (id)kCFBooleanTrue; - } - - OSStatus status = SecItemDelete((__bridge CFDictionaryRef) query); - - if(status) { - if(error) { - *error = [NSError errorWithDomain:@"securityd" - code:status - userInfo:@{NSLocalizedDescriptionKey: - [NSString stringWithFormat:@"Couldn't delete %@ from keychain: %d", self, (int)status]}]; - } - return false; - } - return true; +- (BOOL)deleteKeyMaterialFromKeychain: (NSError * __autoreleasing *) error { + return [self.keycore deleteKeyMaterialFromKeychain:error]; } + (instancetype)keyFromKeychain: (NSString*) uuid @@ -713,7 +413,7 @@ return key; } -+ (NSString*)isItemKeyForKeychainView: (SecDbItemRef) item { ++ (NSString* _Nullable)isItemKeyForKeychainView:(SecDbItemRef)item { NSString* accessgroup = (__bridge NSString*) SecDbItemGetCachedValueWithName(item, kSecAttrAccessGroup); NSString* description = (__bridge NSString*) SecDbItemGetCachedValueWithName(item, kSecAttrDescription); @@ -762,7 +462,10 @@ return [self allWhere: @{@"UUID": [CKKSSQLWhereObject op:@"=" string:@"parentKeyUUID"], @"state": SecCKKSProcessedStateLocal, @"ckzone":zoneID.zoneName} error:error]; } -+ (instancetype) currentKeyForClass: (CKKSKeyClass*) keyclass zoneID:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { ++ (instancetype _Nullable)currentKeyForClass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID + error:(NSError *__autoreleasing*)error +{ // Load the CurrentKey record, and find the key for it CKKSCurrentKeyPointer* ckp = [CKKSCurrentKeyPointer fromDatabase:keyclass zoneID:zoneID error:error]; if(!ckp) { @@ -814,6 +517,11 @@ #pragma mark - CKRecord handling +- (NSString*)CKRecordName +{ + return self.keycore.uuid; +} + - (void) setFromCKRecord: (CKRecord*) record { if(![record.recordType isEqual: SecCKRecordIntermediateKeyType]) { @throw [NSException @@ -824,16 +532,30 @@ [self setStoredCKRecord: record]; - self.uuid = [[record recordID] recordName]; + NSString* uuid = record.recordID.recordName; + NSString* parentKeyUUID = nil; + if(record[SecCKRecordParentKeyRefKey] != nil) { - self.parentKeyUUID = [record[SecCKRecordParentKeyRefKey] recordID].recordName; + parentKeyUUID = [record[SecCKRecordParentKeyRefKey] recordID].recordName; } else { // We wrap ourself. - self.parentKeyUUID = self.uuid; + parentKeyUUID = uuid; } + NSString* keyclass = record[SecCKRecordKeyClassKey]; + CKKSWrappedAESSIVKey* wrappedkey = + [[CKKSWrappedAESSIVKey alloc] initWithBase64:record[SecCKRecordWrappedKeyKey]]; + + self.keycore = [[CKKSKeychainBackedKey alloc] initWithWrappedAESKey:wrappedkey + uuid:uuid + parentKeyUUID:parentKeyUUID + keyclass:(CKKSKeyClass *)keyclass + zoneID:record.recordID.zoneID]; + self.keyclass = record[SecCKRecordKeyClassKey]; self.wrappedkey = [[CKKSWrappedAESSIVKey alloc] initWithBase64: record[SecCKRecordWrappedKeyKey]]; + + self.state = SecCKKSProcessedStateRemote; } - (CKRecord*) updateCKRecord: (CKRecord*) record zoneID: (CKRecordZoneID*) zoneID { @@ -935,15 +657,15 @@ @"currentkey": self.currentkey ? @"1" : @"0"}; } -+ (instancetype) fromDatabaseRow: (NSDictionary*) row { - return [[CKKSKey alloc] initWithWrappedAESKey: row[@"wrappedkey"] ? [[CKKSWrappedAESSIVKey alloc] initWithBase64: row[@"wrappedkey"]] : nil - uuid: row[@"UUID"] - parentKeyUUID: row[@"parentKeyUUID"] - keyclass: row[@"keyclass"] - state: row[@"state"] - zoneID: [[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"] ownerName:CKCurrentUserDefaultName] - encodedCKRecord: [[NSData alloc] initWithBase64EncodedString: row[@"ckrecord"] options:0] - currentkey: [row[@"currentkey"] integerValue]]; ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + return [[CKKSKey alloc] initWithWrappedAESKey:row[@"wrappedkey"].asString ? [[CKKSWrappedAESSIVKey alloc] initWithBase64: row[@"wrappedkey"].asString] : nil + uuid:row[@"UUID"].asString + parentKeyUUID:row[@"parentKeyUUID"].asString + keyclass:(CKKSKeyClass*)row[@"keyclass"].asString + state:(CKKSProcessedState*)row[@"state"].asString + zoneID:[[CKRecordZoneID alloc] initWithZoneName:row[@"ckzone"].asString ownerName:CKCurrentUserDefaultName] + encodedCKRecord:row[@"ckrecord"].asBase64DecodedData + currentkey:row[@"currentkey"].asNSInteger]; } @@ -956,9 +678,9 @@ groupBy: @[@"keyclass", @"state"] orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[[NSString stringWithFormat: @"%@-%@", row[@"state"], row[@"keyclass"]]] = - [NSNumber numberWithInteger: [row[@"count(rowid)"] integerValue]]; + processRow: ^(NSDictionary* row) { + results[[NSString stringWithFormat: @"%@-%@", row[@"state"].asString, row[@"keyclass"].asString]] = + row[@"count(rowid)"].asNSNumberInteger; } error: error]; return results; @@ -966,9 +688,9 @@ - (instancetype)copyWithZone:(NSZone *)zone { CKKSKey *keyCopy = [super copyWithZone:zone]; - keyCopy->_aessivkey = _aessivkey; + keyCopy->_keycore = [_keycore copyWithZone:zone]; + keyCopy->_state = _state; - keyCopy->_keyclass = _keyclass; keyCopy->_currentkey = _currentkey; return keyCopy; } @@ -982,7 +704,7 @@ proto.uuid = self.uuid; proto.zoneName = self.zoneID.zoneName; proto.keyclass = self.keyclass; - proto.key = [[NSData alloc] initWithBytes:self.aessivkey->key length:self.aessivkey->size]; + proto.key = [NSData _newZeroingDataWithBytes:self.aessivkey->key length:self.aessivkey->size]; return proto.data; } diff --git a/keychain/ckks/CKKSKeychainBackedKey.h b/keychain/ckks/CKKSKeychainBackedKey.h new file mode 100644 index 00000000..4e2dbc0d --- /dev/null +++ b/keychain/ckks/CKKSKeychainBackedKey.h @@ -0,0 +1,155 @@ +/* + * 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 "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSRecordHolder.h" +#import "keychain/ckks/CKKSSIV.h" +#import "keychain/ckks/proto/generated_source/CKKSSerializedKey.h" + +NS_ASSUME_NONNULL_BEGIN + +// Important note: while this class does conform to NSSecureCoding, +// for safety reasons encoding a CKKSKeychainBackedKey will ~not~ +// encode the aessivkey. If you want your receiver to have access +// to the original key material, they must successfully call +// loadKeyMaterialFromKeychain. + +@interface CKKSKeychainBackedKey : NSObject +@property NSString* uuid; +@property NSString* parentKeyUUID; +@property CKKSKeyClass* keyclass; +@property CKRecordZoneID* zoneID; + +// Actual key material +@property CKKSWrappedAESSIVKey* wrappedkey; +@property (nullable) CKKSAESSIVKey* aessivkey; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype _Nullable)initSelfWrappedWithAESKey:(CKKSAESSIVKey*)aeskey + uuid:(NSString*)uuid + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID; + +- (instancetype _Nullable)initWrappedBy:(CKKSKeychainBackedKey*)wrappingKey + AESKey:(CKKSAESSIVKey*)aessivkey + uuid:(NSString*)uuid + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID; + +- (instancetype)initWithWrappedAESKey:(CKKSWrappedAESSIVKey* _Nullable)wrappedaeskey + uuid:(NSString*)uuid + parentKeyUUID:(NSString*)parentKeyUUID + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID; + +// Creates new random keys, in the parent's zone ++ (instancetype _Nullable)randomKeyWrappedByParent:(CKKSKeychainBackedKey*)parentKey + error:(NSError* __autoreleasing*)error; + ++ (instancetype _Nullable)randomKeyWrappedByParent:(CKKSKeychainBackedKey*)parentKey + keyclass:(CKKSKeyClass*)keyclass + error:(NSError* __autoreleasing*)error; + +// Creates a new random key that wraps itself ++ (instancetype _Nullable)randomKeyWrappedBySelf:(CKRecordZoneID*)zoneID + error:(NSError* __autoreleasing*)error; + +/* Helper functions for persisting key material in the keychain */ +- (BOOL)saveKeyMaterialToKeychain:(NSError* __autoreleasing*)error; +- (BOOL)saveKeyMaterialToKeychain:(bool)stashTLK + error:(NSError* __autoreleasing*)error; // call this to not stash a non-syncable TLK, if that's what you want + +- (BOOL)loadKeyMaterialFromKeychain:(NSError* __autoreleasing*)error; +- (BOOL)deleteKeyMaterialFromKeychain:(NSError* __autoreleasing*)error; + +// Class methods to help tests ++ (NSDictionary* _Nullable)setKeyMaterialInKeychain:(NSDictionary*)query + error:(NSError* __autoreleasing*)error; + ++ (NSDictionary* _Nullable)queryKeyMaterialInKeychain:(NSDictionary*)query + error:(NSError* __autoreleasing*)error; + ++ (instancetype _Nullable)keyFromKeychain:(NSString*)uuid + parentKeyUUID:(NSString*)parentKeyUUID + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID + error:(NSError* __autoreleasing*)error; + +/* Returns true if we believe this key wraps itself. */ +- (bool)wrapsSelf; + +// Attempts checks if the AES key is already loaded, or attempts to load it from the keychain. Returns nil if it fails. +- (CKKSAESSIVKey* _Nullable)ensureKeyLoaded:(NSError* __autoreleasing*)error; + +// On a self-wrapped key, determine if this AES-SIV key is the self-wrapped key. +// If it is, save the key as this CKKSKey's unwrapped key. +- (bool)trySelfWrappedKeyCandidate:(CKKSAESSIVKey*)candidate + error:(NSError* __autoreleasing*)error; + +- (CKKSWrappedAESSIVKey* _Nullable)wrapAESKey:(CKKSAESSIVKey*)keyToWrap + error:(NSError* __autoreleasing*)error; + +- (CKKSAESSIVKey* _Nullable)unwrapAESKey:(CKKSWrappedAESSIVKey*)keyToUnwrap + error:(NSError* __autoreleasing*)error; + +- (bool)wrapUnder:(CKKSKeychainBackedKey*)wrappingKey + error:(NSError* __autoreleasing*)error; + +- (bool)unwrapSelfWithAESKey:(CKKSAESSIVKey*)unwrappingKey + error:(NSError* __autoreleasing*)error; + +- (NSData* _Nullable)encryptData:(NSData*)plaintext + authenticatedData:(NSDictionary* _Nullable)ad + error:(NSError* __autoreleasing*)error; + +- (NSData* _Nullable)decryptData:(NSData*)ciphertext + authenticatedData:(NSDictionary* _Nullable)ad + error:(NSError* __autoreleasing*)error; + +- (NSData* _Nullable)serializeAsProtobuf:(NSError* __autoreleasing*)error; + ++ (CKKSKeychainBackedKey* _Nullable)loadFromProtobuf:(NSData*)data + error:(NSError* __autoreleasing*)error; +@end + +// Useful when sending keys across interface boundaries +@interface CKKSKeychainBackedKeySet : NSObject +@property CKKSKeychainBackedKey* tlk; +@property CKKSKeychainBackedKey* classA; +@property CKKSKeychainBackedKey* classC; +@property BOOL newUpload; + +- (instancetype)initWithTLK:(CKKSKeychainBackedKey*)tlk + classA:(CKKSKeychainBackedKey*)classA + classC:(CKKSKeychainBackedKey*)classC + newUpload:(BOOL)newUpload; +@end + + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ckks/CKKSKeychainBackedKey.m b/keychain/ckks/CKKSKeychainBackedKey.m new file mode 100644 index 00000000..8552ee42 --- /dev/null +++ b/keychain/ckks/CKKSKeychainBackedKey.m @@ -0,0 +1,801 @@ + +#if OCTAGON + +#import "keychain/ckks/CKKSKeychainBackedKey.h" + +#include +#include +#include +#include + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSItem.h" + +@implementation CKKSKeychainBackedKey + +- (instancetype)initSelfWrappedWithAESKey:(CKKSAESSIVKey*)aeskey + uuid:(NSString*)uuid + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID +{ + if((self = [super init])) { + _uuid = uuid; + _parentKeyUUID = uuid; + _zoneID = zoneID; + + _keyclass = keyclass; + _aessivkey = aeskey; + + // Wrap the key with the key. Not particularly useful, but there you go. + NSError* error = nil; + [self wrapUnder:self error:&error]; + if(error != nil) { + secerror("CKKSKeychainBackedKey: Couldn't self-wrap key: %@", error); + return nil; + } + } + return self; +} + +- (instancetype _Nullable)initWrappedBy:(CKKSKeychainBackedKey*)wrappingKey + AESKey:(CKKSAESSIVKey*)aessivkey + uuid:(NSString*)uuid + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID +{ + if((self = [super init])) { + _uuid = uuid; + _parentKeyUUID = uuid; + _zoneID = zoneID; + + _keyclass = keyclass; + _aessivkey = aessivkey; + + NSError* error = nil; + [self wrapUnder:wrappingKey error:&error]; + if(error != nil) { + secerror("CKKSKeychainBackedKey: Couldn't wrap key with key: %@", error); + return nil; + } + } + return self; +} + +- (instancetype)initWithWrappedAESKey:(CKKSWrappedAESSIVKey*)wrappedaeskey + uuid:(NSString*)uuid + parentKeyUUID:(NSString*)parentKeyUUID + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID +{ + if((self = [super init])) { + _uuid = uuid; + _parentKeyUUID = parentKeyUUID; + _zoneID = zoneID; + + _wrappedkey = wrappedaeskey; + + _keyclass = keyclass; + _aessivkey = nil; + } + return self; +} + +- (instancetype)copyWithZone:(NSZone*)zone +{ + CKKSKeychainBackedKey* c = + [[CKKSKeychainBackedKey allocWithZone:zone] initWithWrappedAESKey:self.wrappedkey + uuid:self.uuid + parentKeyUUID:self.parentKeyUUID + keyclass:self.keyclass + zoneID:self.zoneID]; + c.aessivkey = [self.aessivkey copy]; + return c; +} + + +- (BOOL)isEqual:(id)object +{ + if(![object isKindOfClass:[CKKSKeychainBackedKey class]]) { + return NO; + } + + CKKSKeychainBackedKey* obj = (CKKSKeychainBackedKey*)object; + + return ([self.uuid isEqual:obj.uuid] && [self.parentKeyUUID isEqual:obj.parentKeyUUID] && + [self.zoneID isEqual:obj.zoneID] && [self.wrappedkey isEqual:obj.wrappedkey] && + [self.keyclass isEqual:obj.keyclass] && true) + ? YES + : NO; +} + +- (bool)wrapsSelf +{ + return [self.uuid isEqual:self.parentKeyUUID]; +} + +- (bool)wrapUnder:(CKKSKeychainBackedKey*)wrappingKey + error:(NSError* __autoreleasing*)error +{ + NSError* localError = nil; + self.wrappedkey = [wrappingKey wrapAESKey:self.aessivkey error:&localError]; + if(self.wrappedkey == nil) { + secerror("CKKSKeychainBackedKey: couldn't wrap key: %@", localError); + if(error) { + *error = localError; + } + } else { + self.parentKeyUUID = wrappingKey.uuid; + } + return (self.wrappedkey != nil); +} + +- (bool)unwrapSelfWithAESKey:(CKKSAESSIVKey*)unwrappingKey + error:(NSError* __autoreleasing*)error +{ + _aessivkey = [unwrappingKey unwrapAESKey:self.wrappedkey error:error]; + return (_aessivkey != nil); +} + ++ (CKKSKeychainBackedKey* _Nullable)randomKeyWrappedByParent:(CKKSKeychainBackedKey*)parentKey + error:(NSError* __autoreleasing*)error +{ + return + [self randomKeyWrappedByParent:parentKey keyclass:parentKey.keyclass error:error]; +} + ++ (CKKSKeychainBackedKey* _Nullable)randomKeyWrappedByParent:(CKKSKeychainBackedKey*)parentKey + keyclass:(CKKSKeyClass*)keyclass + error:(NSError* __autoreleasing*)error +{ + CKKSAESSIVKey* aessivkey = [CKKSAESSIVKey randomKey:error]; + if(aessivkey == nil) { + return nil; + } + + CKKSKeychainBackedKey* key = + [[CKKSKeychainBackedKey alloc] initWrappedBy:parentKey + AESKey:aessivkey + uuid:[[NSUUID UUID] UUIDString] + keyclass:keyclass + zoneID:parentKey.zoneID]; + return key; +} + ++ (instancetype _Nullable)randomKeyWrappedBySelf:(CKRecordZoneID*)zoneID + error:(NSError* __autoreleasing*)error +{ + CKKSAESSIVKey* aessivkey = [CKKSAESSIVKey randomKey:error]; + if(aessivkey == nil) { + return nil; + } + + NSString* uuid = [[NSUUID UUID] UUIDString]; + + CKKSKeychainBackedKey* key = + [[CKKSKeychainBackedKey alloc] initSelfWrappedWithAESKey:aessivkey + uuid:uuid + keyclass:SecCKKSKeyClassTLK + zoneID:zoneID]; + return key; +} + +- (CKKSAESSIVKey*)ensureKeyLoaded:(NSError* __autoreleasing*)error +{ + if(self.aessivkey) { + return self.aessivkey; + } + + // Attempt to load this key from the keychain + if([self loadKeyMaterialFromKeychain:error]) { + return self.aessivkey; + } + + return nil; +} + +- (bool)trySelfWrappedKeyCandidate:(CKKSAESSIVKey*)candidate + error:(NSError* __autoreleasing*)error +{ + if(![self wrapsSelf]) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSKeyNotSelfWrapped + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"%@ is not self-wrapped", self] + }]; + } + return false; + } + + CKKSAESSIVKey* unwrapped = [candidate unwrapAESKey:self.wrappedkey error:error]; + if(unwrapped && [unwrapped isEqual:candidate]) { + _aessivkey = unwrapped; + return true; + } + + return false; +} + +- (CKKSWrappedAESSIVKey*)wrapAESKey:(CKKSAESSIVKey*)keyToWrap + error:(NSError* __autoreleasing*)error +{ + CKKSAESSIVKey* key = [self ensureKeyLoaded:error]; + CKKSWrappedAESSIVKey* wrappedkey = [key wrapAESKey:keyToWrap error:error]; + return wrappedkey; +} + +- (CKKSAESSIVKey*)unwrapAESKey:(CKKSWrappedAESSIVKey*)keyToUnwrap + error:(NSError* __autoreleasing*)error +{ + CKKSAESSIVKey* key = [self ensureKeyLoaded:error]; + CKKSAESSIVKey* unwrappedkey = [key unwrapAESKey:keyToUnwrap error:error]; + return unwrappedkey; +} + +- (NSData*)encryptData:(NSData*)plaintext + authenticatedData:(NSDictionary*)ad + error:(NSError* __autoreleasing*)error +{ + CKKSAESSIVKey* key = [self ensureKeyLoaded:error]; + NSData* data = [key encryptData:plaintext authenticatedData:ad error:error]; + return data; +} + +- (NSData*)decryptData:(NSData*)ciphertext + authenticatedData:(NSDictionary*)ad + error:(NSError* __autoreleasing*)error +{ + CKKSAESSIVKey* key = [self ensureKeyLoaded:error]; + NSData* data = [key decryptData:ciphertext authenticatedData:ad error:error]; + return data; +} + +/* Functions to load and save keys from the keychain (where we get to store actual key material!) */ +- (BOOL)saveKeyMaterialToKeychain:(NSError* __autoreleasing*)error +{ + return [self saveKeyMaterialToKeychain:true error:error]; +} + +- (BOOL)saveKeyMaterialToKeychain:(bool)stashTLK error:(NSError* __autoreleasing*)error +{ + // Note that we only store the key class, view, UUID, parentKeyUUID, and key material in the keychain + // Any other metadata must be stored elsewhere and filled in at load time. + + if(![self ensureKeyLoaded:error]) { + // No key material, nothing to save to keychain. + return NO; + } + + // iOS keychains can't store symmetric keys, so we're reduced to storing this key as a password + NSData* keydata = + [[[NSData alloc] initWithBytes:self.aessivkey->key length:self.aessivkey->size] + base64EncodedDataWithOptions:0]; + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrDescription : self.keyclass, + (id)kSecAttrServer : self.zoneID.zoneName, + (id)kSecAttrAccount : self.uuid, + (id)kSecAttrPath : self.parentKeyUUID, + (id)kSecAttrIsInvisible : @YES, + (id)kSecValueData : keydata, + } mutableCopy]; + + // Only TLKs are synchronizable. Other keyclasses must synchronize via key hierarchy. + if([self.keyclass isEqualToString:SecCKKSKeyClassTLK]) { + // Use PCS-MasterKey view so they'll be initial-synced under SOS. + query[(id)kSecAttrSyncViewHint] = (id)kSecAttrViewHintPCSMasterKey; + query[(id)kSecAttrSynchronizable] = (id)kCFBooleanTrue; + } + + // Class C keys are accessible after first unlock; TLKs and Class A keys are accessible only when unlocked + if([self.keyclass isEqualToString:SecCKKSKeyClassC]) { + query[(id)kSecAttrAccessible] = (id)kSecAttrAccessibleAfterFirstUnlock; + } else { + query[(id)kSecAttrAccessible] = (id)kSecAttrAccessibleWhenUnlocked; + } + + NSError* localError = nil; + [CKKSKeychainBackedKey setKeyMaterialInKeychain:query error:&localError]; + + if(localError && error) { + *error = [NSError errorWithDomain:@"securityd" + code:localError.code + userInfo:@{ + NSLocalizedDescriptionKey : + [NSString stringWithFormat:@"Couldn't save %@ to keychain: %d", + self, + (int)localError.code], + NSUnderlyingErrorKey : localError, + }]; + } + + // TLKs are synchronizable. Stash them nonsyncably nearby. + // Don't report errors here. + if(stashTLK && [self.keyclass isEqualToString:SecCKKSKeyClassTLK]) { + query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrDescription : [self.keyclass stringByAppendingString:@"-nonsync"], + (id)kSecAttrServer : self.zoneID.zoneName, + (id)kSecAttrAccount : self.uuid, + (id)kSecAttrPath : self.parentKeyUUID, + (id)kSecAttrIsInvisible : @YES, + (id)kSecValueData : keydata, + } mutableCopy]; + query[(id)kSecAttrSynchronizable] = (id)kCFBooleanFalse; + + NSError* stashError = nil; + [CKKSKeychainBackedKey setKeyMaterialInKeychain:query error:&localError]; + + if(stashError) { + secerror("CKKSKeychainBackedKey: Couldn't stash %@ to keychain: %@", self, stashError); + } + } + + return (localError == nil) ? YES : NO; +} + ++ (NSDictionary*)setKeyMaterialInKeychain:(NSDictionary*)query + error:(NSError* __autoreleasing*)error +{ + CFTypeRef result = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &result); + + NSError* localerror = nil; + + // Did SecItemAdd fall over due to an existing item? + if(status == errSecDuplicateItem) { + // Add every primary key attribute to this find dictionary + NSMutableDictionary* findQuery = [[NSMutableDictionary alloc] init]; + findQuery[(id)kSecClass] = query[(id)kSecClass]; + findQuery[(id)kSecAttrSynchronizable] = query[(id)kSecAttrSynchronizable]; + findQuery[(id)kSecAttrSyncViewHint] = query[(id)kSecAttrSyncViewHint]; + findQuery[(id)kSecAttrAccessGroup] = query[(id)kSecAttrAccessGroup]; + findQuery[(id)kSecAttrAccount] = query[(id)kSecAttrAccount]; + findQuery[(id)kSecAttrServer] = query[(id)kSecAttrServer]; + findQuery[(id)kSecAttrPath] = query[(id)kSecAttrPath]; + findQuery[(id)kSecUseDataProtectionKeychain] = query[(id)kSecUseDataProtectionKeychain]; + + NSMutableDictionary* updateQuery = [query mutableCopy]; + updateQuery[(id)kSecClass] = nil; + + status = SecItemUpdate((__bridge CFDictionaryRef)findQuery, (__bridge CFDictionaryRef)updateQuery); + + if(status) { + localerror = [NSError + errorWithDomain:@"securityd" + code:status + description:[NSString stringWithFormat:@"SecItemUpdate: %d", (int)status]]; + } + } else { + localerror = [NSError + errorWithDomain:@"securityd" + code:status + description:[NSString stringWithFormat:@"SecItemAdd: %d", (int)status]]; + } + + if(status) { + CFReleaseNull(result); + + if(error) { + *error = localerror; + } + return nil; + } + + NSDictionary* resultDict = CFBridgingRelease(result); + return resultDict; +} + ++ (NSDictionary*)queryKeyMaterialInKeychain:(NSDictionary*)query + error:(NSError* __autoreleasing*)error +{ + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if(status) { + CFReleaseNull(result); + + if(error) { + *error = [NSError + errorWithDomain:@"securityd" + code:status + userInfo:@{ + NSLocalizedDescriptionKey : + [NSString stringWithFormat:@"SecItemCopyMatching: %d", (int)status] + }]; + } + return nil; + } + + NSDictionary* resultDict = CFBridgingRelease(result); + return resultDict; +} + ++ (NSDictionary*)fetchKeyMaterialItemFromKeychain:(CKKSKeychainBackedKey*)key + resave:(bool*)resavePtr + error:(NSError* __autoreleasing*)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrDescription : key.keyclass, + (id)kSecAttrAccount : key.uuid, + (id)kSecAttrServer : key.zoneID.zoneName, + (id)kSecAttrPath : key.parentKeyUUID, + (id)kSecReturnAttributes : @YES, + (id)kSecReturnData : @YES, + } mutableCopy]; + + // Synchronizable items are only found if you request synchronizable items. Only TLKs are synchronizable. + if([key.keyclass isEqualToString:SecCKKSKeyClassTLK]) { + query[(id)kSecAttrSynchronizable] = (id)kCFBooleanTrue; + } + + NSError* localError = nil; + NSDictionary* result = [self queryKeyMaterialInKeychain:query error:&localError]; + NSError* originalError = localError; + + // If we found the item or errored in some interesting way, return. + if(result) { + return result; + } + if(localError && localError.code != errSecItemNotFound) { + if(error) { + *error = [NSError errorWithDomain:@"securityd" + code:localError.code + userInfo:@{ + NSLocalizedDescriptionKey : + [NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", + key, + (int)localError.code], + NSUnderlyingErrorKey : localError, + }]; + } + return result; + } + localError = nil; + + if([key.keyclass isEqualToString:SecCKKSKeyClassTLK]) { + //didn't find a regular tlk? how about a piggy? + query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrDescription : [key.keyclass stringByAppendingString:@"-piggy"], + (id)kSecAttrSynchronizable : (id)kSecAttrSynchronizableAny, + (id)kSecAttrAccount : [NSString stringWithFormat:@"%@-piggy", key.uuid], + (id)kSecAttrServer : key.zoneID.zoneName, + (id)kSecReturnAttributes : @YES, + (id)kSecReturnData : @YES, + (id)kSecMatchLimit : (id)kSecMatchLimitOne, + } mutableCopy]; + + result = [self queryKeyMaterialInKeychain:query error:&localError]; + if(localError == nil) { + secnotice("CKKSKeychainBackedKey", "loaded a piggy TLK (%@)", key.uuid); + + if(resavePtr) { + *resavePtr = true; + } + + return result; + } + + if(localError && localError.code != errSecItemNotFound) { + if(error) { + *error = [NSError errorWithDomain:@"securityd" + code:localError.code + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Couldn't load %@ from keychain: %d", + key, + (int)localError.code], + NSUnderlyingErrorKey : localError, + }]; + } + return nil; + } + } + + localError = nil; + + // Try to load a stashed TLK + if([key.keyclass isEqualToString:SecCKKSKeyClassTLK]) { + localError = nil; + + // Try to look for the non-syncable stashed tlk and resurrect it. + query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrDescription : [key.keyclass stringByAppendingString:@"-nonsync"], + (id)kSecAttrServer : key.zoneID.zoneName, + (id)kSecAttrAccount : key.uuid, + (id)kSecReturnAttributes : @YES, + (id)kSecReturnData : @YES, + (id)kSecAttrSynchronizable : @NO, + } mutableCopy]; + + result = [self queryKeyMaterialInKeychain:query error:&localError]; + if(localError == nil) { + secnotice("CKKSKeychainBackedKey", "loaded a stashed TLK (%@)", key.uuid); + + if(resavePtr) { + *resavePtr = true; + } + + return result; + } + + if(localError && localError.code != errSecItemNotFound) { + if(error) { + *error = [NSError errorWithDomain:@"securityd" + code:localError.code + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Couldn't load %@ from keychain: %d", + key, + (int)localError.code], + NSUnderlyingErrorKey : localError, + }]; + } + return nil; + } + } + + // We didn't early-return. Use whatever error the original fetch produced. + if(error) { + *error = [NSError errorWithDomain:@"securityd" + code:originalError ? originalError.code : errSecParam + description:[NSString stringWithFormat:@"Couldn't load %@ from keychain: %d", + key, + (int)originalError.code] + underlying:originalError]; + } + + return result; +} + +- (BOOL)loadKeyMaterialFromKeychain:(NSError* __autoreleasing*)error +{ + bool resave = false; + NSDictionary* result = [CKKSKeychainBackedKey fetchKeyMaterialItemFromKeychain:self + resave:&resave + error:error]; + if(!result) { + return NO; + } + + NSData* b64keymaterial = result[(id)kSecValueData]; + NSMutableData* keymaterial = + [[NSMutableData alloc] initWithBase64EncodedData:b64keymaterial options:0]; + if(!keymaterial) { + secnotice("CKKSKeychainBackedKey", "Unable to unbase64 key: %@", self); + if(error) { + *error = [NSError + errorWithDomain:CKKSErrorDomain + code:CKKSKeyUnknownFormat + description:[NSString stringWithFormat:@"unable to unbase64 key: %@", self]]; + } + return NO; + } + + CKKSAESSIVKey* key = [[CKKSAESSIVKey alloc] initWithBytes:(uint8_t*)keymaterial.bytes + len:keymaterial.length]; + memset_s(keymaterial.mutableBytes, keymaterial.length, 0, keymaterial.length); + self.aessivkey = key; + + if(resave) { + secnotice("CKKSKeychainBackedKey", "Resaving %@ as per request", self); + NSError* resaveError = nil; + [self saveKeyMaterialToKeychain:&resaveError]; + if(resaveError) { + secnotice("CKKSKeychainBackedKey", "Resaving %@ failed: %@", self, resaveError); + } + } + + return !!(self.aessivkey) ? YES : NO; +} + +- (BOOL)deleteKeyMaterialFromKeychain:(NSError* __autoreleasing*)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrDescription : self.keyclass, + (id)kSecAttrAccount : self.uuid, + (id)kSecAttrServer : self.zoneID.zoneName, + (id)kSecReturnData : @YES, + } mutableCopy]; + + // Synchronizable items are only found if you request synchronizable items. Only TLKs are synchronizable. + if([self.keyclass isEqualToString:SecCKKSKeyClassTLK]) { + query[(id)kSecAttrSynchronizable] = (id)kCFBooleanTrue; + } + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + + if(status) { + if(error) { + *error = [NSError + errorWithDomain:@"securityd" + code:status + userInfo:@{ + NSLocalizedDescriptionKey : [NSString + stringWithFormat:@"Couldn't delete %@ from keychain: %d", self, (int)status] + }]; + } + return NO; + } + return YES; +} + ++ (instancetype _Nullable)keyFromKeychain:(NSString*)uuid + parentKeyUUID:(NSString*)parentKeyUUID + keyclass:(CKKSKeyClass*)keyclass + zoneID:(CKRecordZoneID*)zoneID + error:(NSError* __autoreleasing*)error +{ + CKKSKeychainBackedKey* key = [[CKKSKeychainBackedKey alloc] initWithWrappedAESKey:nil + uuid:uuid + parentKeyUUID:parentKeyUUID + keyclass:keyclass + zoneID:zoneID]; + + if(![key loadKeyMaterialFromKeychain:error]) { + return nil; + } + + return key; +} + +#pragma mark Utility + +- (NSString*)description +{ + return [NSString stringWithFormat:@"<%@(%@): %@ (%@)>", + NSStringFromClass([self class]), + self.zoneID.zoneName, + self.uuid, + self.keyclass]; +} + +- (NSData*)serializeAsProtobuf:(NSError* __autoreleasing*)error +{ + if(![self ensureKeyLoaded:error]) { + return nil; + } + CKKSSerializedKey* proto = [[CKKSSerializedKey alloc] init]; + + proto.uuid = self.uuid; + proto.zoneName = self.zoneID.zoneName; + proto.keyclass = self.keyclass; + proto.key = + [[NSData alloc] initWithBytes:self.aessivkey->key length:self.aessivkey->size]; + + return proto.data; +} + ++ (CKKSKeychainBackedKey*)loadFromProtobuf:(NSData*)data + error:(NSError* __autoreleasing*)error +{ + CKKSSerializedKey* key = [[CKKSSerializedKey alloc] initWithData:data]; + if(key && key.uuid && key.zoneName && key.keyclass && key.key) { + return [[CKKSKeychainBackedKey alloc] + initSelfWrappedWithAESKey:[[CKKSAESSIVKey alloc] + initWithBytes:(uint8_t*)key.key.bytes + len:key.key.length] + uuid:key.uuid + keyclass:(CKKSKeyClass*)key.keyclass // TODO sanitize + zoneID:[[CKRecordZoneID alloc] initWithZoneName:key.zoneName + ownerName:CKCurrentUserDefaultName]]; + } + + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSProtobufFailure + description:@"Data failed to parse as a CKKSSerializedKey"]; + } + return nil; +} + +#pragma mark NSSecureCoding + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder*)coder +{ + [coder encodeObject:self.uuid forKey:@"uuid"]; + [coder encodeObject:self.parentKeyUUID forKey:@"parentKeyUUID"]; + [coder encodeObject:self.keyclass forKey:@"keyclass"]; + [coder encodeObject:self.zoneID forKey:@"zoneID"]; + [coder encodeObject:self.wrappedkey forKey:@"wrappedkey"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder*)decoder +{ + self = [super init]; + if(self) { + _uuid = [decoder decodeObjectOfClass:[NSString class] forKey:@"uuid"]; + _parentKeyUUID = + [decoder decodeObjectOfClass:[NSString class] forKey:@"parentKeyUUID"]; + _keyclass = (CKKSKeyClass*)[decoder decodeObjectOfClass:[NSString class] + forKey:@"keyclass"]; + _zoneID = [decoder decodeObjectOfClass:[CKRecordZoneID class] forKey:@"zoneID"]; + + _wrappedkey = [decoder decodeObjectOfClass:[CKKSWrappedAESSIVKey class] + forKey:@"wrappedkey"]; + } + return self; +} + +@end + +#pragma mark - CKKSKeychainBackedKeySet + +@implementation CKKSKeychainBackedKeySet + +- (instancetype)initWithTLK:(CKKSKeychainBackedKey*)tlk + classA:(CKKSKeychainBackedKey*)classA + classC:(CKKSKeychainBackedKey*)classC + newUpload:(BOOL)newUpload +{ + if((self = [super init])) { + _tlk = tlk; + _classA = classA; + _classC = classC; + _newUpload = newUpload; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat: @"", + self.tlk, + self.classA, + self.classC, + self.newUpload]; +} + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder*)coder +{ + [coder encodeObject:self.tlk forKey:@"tlk"]; + [coder encodeObject:self.classA forKey:@"classA"]; + [coder encodeObject:self.classC forKey:@"classC"]; + [coder encodeBool:self.newUpload forKey:@"newUpload"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder*)decoder +{ + self = [super init]; + if(self) { + _tlk = [decoder decodeObjectOfClass:[CKKSKeychainBackedKey class] forKey:@"tlk"]; + _classA = [decoder decodeObjectOfClass:[CKKSKeychainBackedKey class] forKey:@"classA"]; + _classC = [decoder decodeObjectOfClass:[CKKSKeychainBackedKey class] forKey:@"classC"]; + _newUpload = [decoder decodeBoolForKey:@"newUpload"]; + } + return self; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSKeychainView.h b/keychain/ckks/CKKSKeychainView.h index b5ab8e2d..37e28163 100644 --- a/keychain/ckks/CKKSKeychainView.h +++ b/keychain/ckks/CKKSKeychainView.h @@ -25,7 +25,8 @@ #import #include -#import "keychain/ckks/CKKSAPSReceiver.h" +#import "keychain/analytics/CKKSLaunchSequence.h" +#import "keychain/ckks/OctagonAPSReceiver.h" #import "keychain/ckks/CKKSLockStateTracker.h" #import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/ckks/CloudKitDependencies.h" @@ -45,12 +46,14 @@ #import "keychain/ckks/CKKSProcessReceivedKeysOperation.h" #import "keychain/ckks/CKKSReencryptOutgoingItemsOperation.h" #import "keychain/ckks/CKKSScanLocalItemsOperation.h" -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" #import "keychain/ckks/CKKSUpdateDeviceStateOperation.h" #import "keychain/ckks/CKKSZone.h" +#import "keychain/ckks/CKKSZoneModifier.h" #import "keychain/ckks/CKKSZoneChangeFetcher.h" #import "keychain/ckks/CKKSSynchronizeOperation.h" #import "keychain/ckks/CKKSLocalSynchronizeOperation.h" +#import "keychain/ckks/CKKSProvideKeySetOperation.h" #include "CKKS.h" @@ -64,8 +67,34 @@ NS_ASSUME_NONNULL_BEGIN @class CKKSEgoManifest; @class CKKSOutgoingQueueEntry; @class CKKSZoneChangeFetcher; +@class CKKSCurrentKeySet; -@interface CKKSKeychainView : CKKSZone +@interface CKKSPeerProviderState : NSObject +@property NSString* peerProviderID; + +// The peer provider believes trust in this state is essential. Any subsystem using +// a peer provider state should fail and pause if this is YES and there are trust errors. +@property BOOL essential; + +@property (nonatomic, readonly, nullable) CKKSSelves* currentSelfPeers; +@property (nonatomic, readonly, nullable) NSError* currentSelfPeersError; +@property (nonatomic, readonly, nullable) NSSet>* currentTrustedPeers; +@property (nonatomic, readonly, nullable) NSSet* currentTrustedPeerIDs; +@property (nonatomic, readonly, nullable) NSError* currentTrustedPeersError; + +- (instancetype)initWithPeerProviderID:(NSString*)providerID + essential:(BOOL)essential + selfPeers:(CKKSSelves* _Nullable)selfPeers + selfPeersError:(NSError* _Nullable)selfPeersError + trustedPeers:(NSSet>* _Nullable)currentTrustedPeers + trustedPeersError:(NSError* _Nullable)trustedPeersError; + ++ (CKKSPeerProviderState*)noPeersState:(id)provider; +@end + +@interface CKKSKeychainView : CKKSZone { CKKSZoneKeyState* _keyHierarchyState; } @@ -74,6 +103,11 @@ NS_ASSUME_NONNULL_BEGIN @property CKKSCondition* loggedOut; @property CKKSCondition* accountStateKnown; +@property CKKSAccountStatus trustStatus; +@property (nullable) CKKSResultOperation* trustDependency; + +@property (nullable) CKKSLaunchSequence *launch; + @property CKKSLockStateTracker* lockStateTracker; @property CKKSZoneKeyState* keyHierarchyState; @@ -88,7 +122,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable) CKKSManifest* latestManifest; @property (nullable) CKKSResultOperation* keyStateReadyDependency; -// Wait for the key state to become 'nontransient': no pending operation is expected to advance it (at least until user intervenes) +// Wait for the key state to become 'nontransient': no pending operation is expected to advance it (at least until intervention) @property (nullable) CKKSResultOperation* keyStateNonTransientDependency; // True if we believe there's any items in the keychain which haven't been brought up in CKKS yet @@ -103,6 +137,9 @@ NS_ASSUME_NONNULL_BEGIN @property (weak) CKKSNearFutureScheduler* savedTLKNotifier; +@property (nullable) CKKSNearFutureScheduler* suggestTLKUpload; + + /* Used for debugging: just what happened last time we ran this? */ @property CKKSIncomingQueueOperation* lastIncomingQueueOperation; @property CKKSNewTLKOperation* lastNewTLKOperation; @@ -123,31 +160,35 @@ NS_ASSUME_NONNULL_BEGIN /* Trigger this to tell the whole machine that this view has changed */ @property CKKSNearFutureScheduler* notifyViewChangedScheduler; +/* Trigger this to tell the whole machine that this view is more ready then before */ +@property CKKSNearFutureScheduler* notifyViewReadyScheduler; + /* trigger this to request key state machine poking */ @property CKKSNearFutureScheduler* pokeKeyStateMachineScheduler; +// The current list of peer providers. If empty, CKKS will consider itself untrusted, and halt operation +@property (readonly) NSArray>* currentPeerProviders; + // These are available when you're in a dispatchSyncWithAccountKeys call, but at no other time // These must be pre-fetched before you get on the CKKS queue, otherwise we end up with CKKS<->SQLite<->SOSAccountQueue deadlocks -@property (nonatomic, readonly) CKKSSelves* currentSelfPeers; -@property (nonatomic, readonly) NSError* currentSelfPeersError; -@property (nonatomic, readonly) NSSet>* currentTrustedPeers; -@property (nonatomic, readonly) NSError* currentTrustedPeersError; + +// They will be in a parallel array with currentPeerProviders above +@property (readonly) NSArray* currentTrustStates; - (instancetype)initWithContainer:(CKContainer*)container - zoneName:(NSString*)zoneName - accountTracker:(CKKSCKAccountStateTracker*)accountTracker - lockStateTracker:(CKKSLockStateTracker*)lockStateTracker - reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker - changeFetcher:(CKKSZoneChangeFetcher*)fetcher - savedTLKNotifier:(CKKSNearFutureScheduler*)savedTLKNotifier - peerProvider:(id)peerProvider - fetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:(Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass:(Class)modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:(Class)modifyRecordZonesOperationClass - apsConnectionClass:(Class)apsConnectionClass - notifierClass:(Class)notifierClass; + zoneName:(NSString*)zoneName + accountTracker:(CKKSAccountStateTracker*)accountTracker + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker + changeFetcher:(CKKSZoneChangeFetcher*)fetcher + zoneModifier:(CKKSZoneModifier*)zoneModifier + savedTLKNotifier:(CKKSNearFutureScheduler*)savedTLKNotifier + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies; + +/* Trust state management */ +- (void)beginTrustedOperation:(NSArray>*)peerProviders + suggestTLKUpload:(CKKSNearFutureScheduler*)suggestTLKUpload; +- (void)endTrustedOperation; /* Synchronous operations */ @@ -172,6 +213,9 @@ NS_ASSUME_NONNULL_BEGIN - (bool)outgoingQueueEmpty:(NSError* __autoreleasing*)error; +- (CKKSResultOperation*)findKeySet; +- (void)receiveTLKUploadRecords:(NSArray*)records; + - (CKKSResultOperation*)waitForFetchAndIncomingQueueProcessing; - (void)waitForKeyHierarchyReadiness; - (void)cancelAllOperations; @@ -180,11 +224,18 @@ NS_ASSUME_NONNULL_BEGIN - (bool)_onqueueWithAccountKeysCheckTLK:(CKKSKey*)proposedTLK error:(NSError* __autoreleasing*)error; +- (BOOL)otherDevicesReportHavingTLKs:(CKKSCurrentKeySet*)keyset; + +- (NSSet*)_onqueuePriorityOutgoingQueueUUIDs; + /* Asynchronous kickoffs */ - (CKKSOutgoingQueueOperation*)processOutgoingQueue:(CKOperationGroup* _Nullable)ckoperationGroup; - (CKKSOutgoingQueueOperation*)processOutgoingQueueAfter:(CKKSResultOperation* _Nullable)after ckoperationGroup:(CKOperationGroup* _Nullable)ckoperationGroup; +- (CKKSOutgoingQueueOperation*)processOutgoingQueueAfter:(CKKSResultOperation*)after + requiredDelay:(uint64_t)requiredDelay + ckoperationGroup:(CKOperationGroup*)ckoperationGroup; - (CKKSIncomingQueueOperation*)processIncomingQueue:(bool)failOnClassA; - (CKKSIncomingQueueOperation*)processIncomingQueue:(bool)failOnClassA after:(CKKSResultOperation* _Nullable)after; @@ -251,10 +302,18 @@ NS_ASSUME_NONNULL_BEGIN // For this key, who doesn't yet have a CKKSTLKShare for it, shared to their current Octagon keys? // Note that we really want a record sharing the TLK to ourselves, so this function might return // a non-empty set even if all peers have the TLK: it wants us to make a record for ourself. -- (NSSet>* _Nullable)_onqueueFindPeersMissingShare:(CKKSKey*)key error:(NSError* __autoreleasing*)error; +// If you pass in a non-empty set in afterUploading, those records will be included in the calculation. +- (NSSet>*)_onqueueFindPeers:(CKKSPeerProviderState*)trustState + missingShare:(CKKSKey*)key + afterUploading:(NSSet* _Nullable)newShares + error:(NSError* __autoreleasing*)error; + +- (BOOL)_onqueueAreNewSharesSufficient:(NSSet*)newShares + currentTLK:(CKKSKey*)key + error:(NSError* __autoreleasing*)error; // For this key, share it to all trusted peers who don't have it yet -- (NSSet* _Nullable)_onqueueCreateMissingKeyShares:(CKKSKey*)key error:(NSError* __autoreleasing*)error; +- (NSSet* _Nullable)_onqueueCreateMissingKeyShares:(CKKSKey*)key error:(NSError* __autoreleasing*)error; - (bool)_onqueueUpdateLatestManifestWithError:(NSError**)error; diff --git a/keychain/ckks/CKKSKeychainView.m b/keychain/ckks/CKKSKeychainView.m index 89cd02ad..35f32e7a 100644 --- a/keychain/ckks/CKKSKeychainView.m +++ b/keychain/ckks/CKKSKeychainView.m @@ -32,7 +32,7 @@ #endif #import "CKKS.h" -#import "CKKSAPSReceiver.h" +#import "OctagonAPSReceiver.h" #import "CKKSIncomingQueueEntry.h" #import "CKKSOutgoingQueueEntry.h" #import "CKKSCurrentKeyPointer.h" @@ -54,6 +54,8 @@ #import "CKKSManifestLeafRecord.h" #import "CKKSZoneChangeFetcher.h" #import "CKKSAnalytics.h" +#import "keychain/analytics/CKKSLaunchSequence.h" +#import "keychain/ckks/CKKSCloudKitClassDependencies.h" #import "keychain/ckks/CKKSDeviceStateEntry.h" #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKSCurrentItemPointer.h" @@ -61,12 +63,18 @@ #import "keychain/ckks/CKKSUpdateDeviceStateOperation.h" #import "keychain/ckks/CKKSNotifier.h" #import "keychain/ckks/CloudKitCategories.h" -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" #import "keychain/ckks/CKKSHealTLKSharesOperation.h" #import "keychain/ckks/CKKSLocalSynchronizeOperation.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" +#import "keychain/ot/ObjCImprovements.h" + #include +#include #include #include #include @@ -74,12 +82,64 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSAccountTransaction.h" #include #include #include #if OCTAGON +@implementation CKKSPeerProviderState +- (instancetype)initWithPeerProviderID:(NSString*)providerID + essential:(BOOL)essential + selfPeers:(CKKSSelves* _Nullable)selfPeers + selfPeersError:(NSError* _Nullable)selfPeersError + trustedPeers:(NSSet>* _Nullable)currentTrustedPeers + trustedPeersError:(NSError* _Nullable)trustedPeersError +{ + if((self = [super init])) { + _peerProviderID = providerID; + _essential = essential; + _currentSelfPeers = selfPeers; + _currentSelfPeersError = selfPeersError; + _currentTrustedPeers = currentTrustedPeers; + _currentTrustedPeersError = trustedPeersError; + + if(_currentTrustedPeers) { + NSMutableSet* trustedPeerIDs = [NSMutableSet set]; + for(id peer in _currentTrustedPeers) { + [trustedPeerIDs addObject:peer.peerID]; + } + _currentTrustedPeerIDs = trustedPeerIDs; + } + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", + self.peerProviderID, + self.currentSelfPeers, + self.currentSelfPeersError ?: @"", + self.currentTrustedPeers, + self.currentTrustedPeersError ?: @""]; +} + ++ (CKKSPeerProviderState*)noPeersState:(id)provider +{ + return [[CKKSPeerProviderState alloc] initWithPeerProviderID:provider.providerID + essential:provider.essential + selfPeers:nil + selfPeersError:[NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"No current self peer available"] + trustedPeers:nil + trustedPeersError:[NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"No current trusted peers available"]]; +} +@end + @interface CKKSKeychainView() @property bool keyStateFetchRequested; @property bool keyStateFullRefetchRequested; @@ -92,12 +152,14 @@ @property bool keyStateLocalResetRequested; @property NSHashTable* localResetOperations; +@property bool tlkCreationRequested; +@property NSHashTable*>* keysetProviderOperations; + + @property (atomic) NSString *activeTLK; @property (readonly) Class notifierClass; -@property CKKSNearFutureScheduler* initializeScheduler; - // Slows down all outgoing queue operations @property CKKSNearFutureScheduler* outgoingQueueOperationScheduler; @@ -106,89 +168,101 @@ @property NSMutableDictionary* pendingSyncCallbacks; -@property id currentPeerProvider; - // An extra queue for semaphore-waiting-based NSOperations @property NSOperationQueue* waitingQueue; // Make these readwrite -@property (nonatomic, readwrite) CKKSSelves* currentSelfPeers; -@property (nonatomic, readwrite) NSError* currentSelfPeersError; -@property (nonatomic, readwrite) NSSet>* currentTrustedPeers; -@property (nonatomic, readwrite) NSError* currentTrustedPeersError; +@property NSArray>* currentPeerProviders; +@property NSArray* currentTrustStates; + @end #endif @implementation CKKSKeychainView #if OCTAGON -- (instancetype)initWithContainer: (CKContainer*) container - zoneName: (NSString*) zoneName - accountTracker:(CKKSCKAccountStateTracker*) accountTracker - lockStateTracker:(CKKSLockStateTracker*) lockStateTracker - reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker - changeFetcher:(CKKSZoneChangeFetcher*)fetcher - savedTLKNotifier:(CKKSNearFutureScheduler*) savedTLKNotifier - peerProvider:(id)peerProvider - fetchRecordZoneChangesOperationClass: (Class) fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass: (Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass: (Class) modifySubscriptionsOperationClass - modifyRecordZonesOperationClass: (Class) modifyRecordZonesOperationClass - apsConnectionClass: (Class) apsConnectionClass - notifierClass: (Class) notifierClass +- (instancetype)initWithContainer:(CKContainer*)container + zoneName:(NSString*)zoneName + accountTracker:(CKKSAccountStateTracker*)accountTracker + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker + changeFetcher:(CKKSZoneChangeFetcher*)fetcher + zoneModifier:(CKKSZoneModifier*)zoneModifier + savedTLKNotifier:(CKKSNearFutureScheduler*)savedTLKNotifier + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies { if(self = [super initWithContainer:container zoneName:zoneName accountTracker:accountTracker reachabilityTracker:reachabilityTracker - fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:fetchRecordsOperationClass - queryOperationClass:queryOperationClass - modifySubscriptionsOperationClass:modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:modifyRecordZonesOperationClass - apsConnectionClass:apsConnectionClass]) { - __weak __typeof(self) weakSelf = self; + zoneModifier:zoneModifier + cloudKitClassDependencies:cloudKitClassDependencies]) { + WEAKIFY(self); _loggedIn = [[CKKSCondition alloc] init]; _loggedOut = [[CKKSCondition alloc] init]; _accountStateKnown = [[CKKSCondition alloc] init]; + _trustStatus = CKKSAccountStatusUnknown; + _trustDependency = [CKKSResultOperation named:@"wait-for-trust" withBlock:^{}]; + _incomingQueueOperations = [NSHashTable weakObjectsHashTable]; _outgoingQueueOperations = [NSHashTable weakObjectsHashTable]; _cloudkitDeleteZoneOperations = [NSHashTable weakObjectsHashTable]; _localResetOperations = [NSHashTable weakObjectsHashTable]; + _keysetProviderOperations = [NSHashTable weakObjectsHashTable]; + + _currentPeerProviders = @[]; + _currentTrustStates = @[]; + + _launch = [[CKKSLaunchSequence alloc] initWithRocketName:@"com.apple.security.ckks.launch"]; + [_launch addAttribute:@"view" value:zoneName]; _zoneChangeFetcher = fetcher; [fetcher registerClient:self]; - _notifierClass = notifierClass; + _notifierClass = cloudKitClassDependencies.notifierClass; _notifyViewChangedScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-notify-scheduler", self.zoneName] initialDelay:250*NSEC_PER_MSEC continuingDelay:1*NSEC_PER_SEC keepProcessAlive:true dependencyDescriptionCode:CKKSResultDescriptionPendingViewChangedScheduling block:^{ - __strong __typeof(self) strongSelf = weakSelf; - [strongSelf.notifierClass post:[NSString stringWithFormat:@"com.apple.security.view-change.%@", strongSelf.zoneName]]; + STRONGIFY(self); + [self.notifierClass post:[NSString stringWithFormat:@"com.apple.security.view-change.%@", self.zoneName]]; // Ugly, but: the Manatee and Engram views need to send a fake 'PCS' view change. // TODO: make this data-driven somehow - if([strongSelf.zoneName isEqualToString:@"Manatee"] || - [strongSelf.zoneName isEqualToString:@"Engram"] || - [strongSelf.zoneName isEqualToString:@"ApplePay"] || - [strongSelf.zoneName isEqualToString:@"LimitedPeersAllowed"]) { - [strongSelf.notifierClass post:@"com.apple.security.view-change.PCS"]; + if([self.zoneName isEqualToString:@"Manatee"] || + [self.zoneName isEqualToString:@"Engram"] || + [self.zoneName isEqualToString:@"ApplePay"] || + [self.zoneName isEqualToString:@"Home"] || + [self.zoneName isEqualToString:@"LimitedPeersAllowed"]) { + [self.notifierClass post:@"com.apple.security.view-change.PCS"]; } }]; + _notifyViewReadyScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-ready-scheduler", self.zoneName] + initialDelay:250*NSEC_PER_MSEC + continuingDelay:120*NSEC_PER_SEC + keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionPendingViewChangedScheduling + block:^{ + STRONGIFY(self); + NSDistributedNotificationCenter *center = [self.cloudKitClassDependencies.nsdistributednotificationCenterClass defaultCenter]; + + [center postNotificationName:@"com.apple.security.view-become-ready" + object:nil + userInfo:@{ @"view" : self.zoneName } + options:0]; + }]; + + _pendingSyncCallbacks = [[NSMutableDictionary alloc] init]; _lockStateTracker = lockStateTracker; _savedTLKNotifier = savedTLKNotifier; - _currentPeerProvider = peerProvider; - [_currentPeerProvider registerForPeerChangeUpdates:self]; _keyHierarchyConditions = [[NSMutableDictionary alloc] init]; [CKKSZoneKeyStateMap() enumerateKeysAndObjectsUsingBlock:^(CKKSZoneKeyState * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) { @@ -203,6 +277,7 @@ _keyStateMachineOperation = nil; _keyStateFetchRequested = false; _keyStateProcessRequested = false; + _tlkCreationRequested = false; _waitingQueue = [[NSOperationQueue alloc] init]; _waitingQueue.maxConcurrentOperationCount = 5; @@ -211,14 +286,6 @@ _keyStateNonTransientDependency = [self createKeyStateNontransientDependency]; - dispatch_time_t initializeDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 600 : NSEC_PER_SEC * 30; - _initializeScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-zone-initializer", self.zoneName] - initialDelay:0 - continuingDelay:initializeDelay - keepProcessAlive:false - dependencyDescriptionCode:CKKSResultDescriptionPendingZoneInitializeScheduling - block:^{}]; - dispatch_time_t initialOutgoingQueueDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 200 : NSEC_PER_SEC * 1; dispatch_time_t continuingOutgoingQueueDelay = SecCKKSReduceRateLimiting() ? NSEC_PER_MSEC * 200 : NSEC_PER_SEC * 30; _outgoingQueueOperationScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat: @"%@-outgoing-queue-scheduler", self.zoneName] @@ -237,11 +304,11 @@ keepProcessAlive:true dependencyDescriptionCode:CKKSResultDescriptionPendingKeyHierachyPokeScheduling block:^{ - __strong __typeof(self) strongSelf = weakSelf; - [strongSelf dispatchSyncWithAccountKeys: ^bool{ - __strong __typeof(weakSelf) strongBlockSelf = weakSelf; + STRONGIFY(self); + [self dispatchSyncWithAccountKeys: ^bool{ + STRONGIFY(self); - [strongBlockSelf _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; return true; }]; }]; @@ -297,12 +364,7 @@ self.keyHierarchyOperationGroup = group; - NSOperation* oldKSRD = self.keyStateReadyDependency; - self.keyStateReadyDependency = [self createKeyStateReadyDependency:resetMessage ckoperationGroup:self.keyHierarchyOperationGroup]; - if(oldKSRD) { - [oldKSRD addDependency:self.keyStateReadyDependency]; - [self.waitingQueue addOperation:oldKSRD]; - } + [self ensureKeyStateReadyDependency:resetMessage]; NSOperation* oldKSNTD = self.keyStateNonTransientDependency; self.keyStateNonTransientDependency = [self createKeyStateNontransientDependency]; @@ -312,60 +374,69 @@ } } +- (void)ensureKeyStateReadyDependency:(NSString*)resetMessage { + NSOperation* oldKSRD = self.keyStateReadyDependency; + self.keyStateReadyDependency = [self createKeyStateReadyDependency:resetMessage ckoperationGroup:self.keyHierarchyOperationGroup]; + if(oldKSRD) { + [oldKSRD addDependency:self.keyStateReadyDependency]; + [self.waitingQueue addOperation:oldKSRD]; + } +} + - (CKKSResultOperation*)createPendingInitializationOperation { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* initializationOp = [CKKSGroupOperation named:@"view-initialization" withBlockTakingSelf:^(CKKSGroupOperation * _Nonnull strongOp) { - __strong __typeof(weakSelf) strongSelf = weakSelf; + STRONGIFY(self); __block CKKSResultOperation* zoneCreationOperation = nil; - [strongSelf dispatchSync:^bool { + [self dispatchSync:^bool { CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; zoneCreationOperation = [self handleCKLogin:ckse.ckzonecreated zoneSubscribed:ckse.ckzonesubscribed]; return true; }]; CKKSResultOperation* viewInitializationOperation = [CKKSResultOperation named:@"view-initialization" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongInternalOp) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); + STRONGIFY(self); + if(!self) { + ckkserror("ckks", self, "received callback for released object"); return; } - [strongSelf dispatchSyncWithAccountKeys: ^bool { - ckksnotice("ckks", strongSelf, "Zone setup progress: %@ %d %@ %d %@", - [CKKSCKAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus], - strongSelf.zoneCreated, strongSelf.zoneCreatedError, strongSelf.zoneSubscribed, strongSelf.zoneSubscribedError); + [self dispatchSyncWithAccountKeys: ^bool { + ckksnotice("ckks", self, "Zone setup progress: %@ %d %@ %d %@", + [CKKSAccountStateTracker stringFromAccountStatus:self.accountStatus], + self.zoneCreated, self.zoneCreatedError, self.zoneSubscribed, self.zoneSubscribedError); NSError* error = nil; - CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: strongSelf.zoneName]; - ckse.ckzonecreated = strongSelf.zoneCreated; - ckse.ckzonesubscribed = strongSelf.zoneSubscribed; + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state: self.zoneName]; + ckse.ckzonecreated = self.zoneCreated; + ckse.ckzonesubscribed = self.zoneSubscribed; // Although, if the zone subscribed error says there's no zone, mark down that there's no zone - if(strongSelf.zoneSubscribedError && - [strongSelf.zoneSubscribedError.domain isEqualToString:CKErrorDomain] && strongSelf.zoneSubscribedError.code == CKErrorPartialFailure) { - NSError* subscriptionError = strongSelf.zoneSubscribedError.userInfo[CKPartialErrorsByItemIDKey][strongSelf.zoneID]; + if(self.zoneSubscribedError && + [self.zoneSubscribedError.domain isEqualToString:CKErrorDomain] && self.zoneSubscribedError.code == CKErrorPartialFailure) { + NSError* subscriptionError = self.zoneSubscribedError.userInfo[CKPartialErrorsByItemIDKey][self.zoneID]; if(subscriptionError && [subscriptionError.domain isEqualToString:CKErrorDomain] && subscriptionError.code == CKErrorZoneNotFound) { - ckkserror("ckks", strongSelf, "zone subscription error appears to say the zone doesn't exist, fixing status: %@", strongSelf.zoneSubscribedError); + ckkserror("ckks", self, "zone subscription error appears to say the zone doesn't exist, fixing status: %@", self.zoneSubscribedError); ckse.ckzonecreated = false; } } [ckse saveToDatabase: &error]; if(error) { - ckkserror("ckks", strongSelf, "couldn't save zone creation status for %@: %@", strongSelf.zoneName, error); + ckkserror("ckks", self, "couldn't save zone creation status for %@: %@", self.zoneName, error); } - if(!strongSelf.zoneCreated || !strongSelf.zoneSubscribed) { + if(!self.zoneCreated || !self.zoneSubscribed) { // Go into 'zonecreationfailed' - strongInternalOp.error = strongSelf.zoneCreatedError ? strongSelf.zoneCreatedError : strongSelf.zoneSubscribedError; - [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateZoneCreationFailed withError:strongInternalOp.error]; + strongInternalOp.error = self.zoneCreatedError ? self.zoneCreatedError : self.zoneSubscribedError; + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateZoneCreationFailed withError:strongInternalOp.error]; return true; } else { - [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitialized withError:nil]; + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitialized withError:nil]; } return true; @@ -380,6 +451,8 @@ } - (void)_onqueuePerformKeyStateInitialized:(CKKSZoneStateEntry*)ckse { + CKKSOutgoingQueueOperation* outgoingOperation = nil; + NSOperation* initialProcess = nil; // Check if we believe we've synced this zone before. if(ckse.changeToken == nil) { @@ -394,7 +467,7 @@ fetch.name = @"initial-fetch"; // Next, try to process them (replacing local entries) - CKKSIncomingQueueOperation* initialProcess = [self processIncomingQueue:true after:fetch]; + initialProcess = [self processIncomingQueue:true after:fetch]; initialProcess.name = @"initial-process-incoming-queue"; // If all that succeeds, iterate through all keychain items and find the ones which need to be uploaded @@ -434,7 +507,6 @@ [offset setHour:-24]; NSDate* deadline = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:now options:0]; - NSOperation* initialProcess = nil; if(ckse.lastFetchTime == nil || [ckse.lastFetchTime compare: deadline] == NSOrderedAscending) { initialProcess = [self fetchAndProcessCKChanges:CKKSFetchBecauseSecuritydRestart after:self.lastFixupOperation]; @@ -456,8 +528,42 @@ } // Process outgoing queue after re-start - [self processOutgoingQueueAfter:self.lastFixupOperation ckoperationGroup:self.keyHierarchyOperationGroup]; - } + outgoingOperation = [self processOutgoingQueueAfter:self.lastFixupOperation ckoperationGroup:self.keyHierarchyOperationGroup]; + } + + /* + * Launch time is determined by when the zone have: + * 1. keystate have become ready + * 2. scan local items (if needed) + * 3. processed all outgoing item (if needed) + */ + + WEAKIFY(self); + NSBlockOperation *seemReady = [NSBlockOperation named:[NSString stringWithFormat:@"seemsReadyForSyncing-%@", self.zoneName] withBlock:^void{ + STRONGIFY(self); + NSError *error = nil; + ckksnotice("launch", self, "Launch complete"); + NSNumber *zoneSize = [CKKSMirrorEntry counts:self.zoneID error:&error]; + if (zoneSize) { + zoneSize = @(SecBucket1Significant([zoneSize longValue])); + [self.launch addAttribute:@"zonesize" value:zoneSize]; + } + [self.launch launch]; + + /* + * Since we think we are ready, signal to CK that its to check for PCS identities again, and create the + * since before we completed this operation, we would probably have failed with a timeout because + * we where busy downloading items from CloudKit and then processing them. + */ + [self.notifyViewReadyScheduler trigger]; + }]; + + [seemReady addNullableDependency:self.keyStateReadyDependency]; + [seemReady addNullableDependency:outgoingOperation]; + [seemReady addNullableDependency:self.initialScanOperation]; + [seemReady addNullableDependency:initialProcess]; + + [self scheduleOperation: seemReady]; } - (bool)_onqueueResetLocalData: (NSError * __autoreleasing *) error { @@ -510,7 +616,7 @@ } } - [CKKSTLKShare deleteAll:self.zoneID error: &localerror]; + [CKKSTLKShareRecord deleteAll:self.zoneID error: &localerror]; if(localerror) { ckkserror("ckks", self, "couldn't delete all CKKSTLKShare: %@", localerror); if(error && !setError) { @@ -549,13 +655,13 @@ @synchronized(self.localResetOperations) { CKKSResultOperation* pendingResetLocalOperation = (CKKSResultOperation*) [self findFirstPendingOperation:self.localResetOperations]; if(!pendingResetLocalOperation) { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); pendingResetLocalOperation = [CKKSResultOperation named:@"reset-local" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); __block NSError* error = nil; - [strongSelf dispatchSync: ^bool{ - [strongSelf _onqueueResetLocalData: &error]; + [self dispatchSync: ^bool{ + [self _onqueueResetLocalData: &error]; return true; }]; @@ -574,16 +680,16 @@ // 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) { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSGroupOperation* resetOperationGroup = [CKKSGroupOperation named:@"local-reset" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); __block CKKSResultOperation* resetOperation = nil; - [strongSelf dispatchSyncWithAccountKeys:^bool { - strongSelf.keyStateLocalResetRequested = true; - resetOperation = [strongSelf createPendingResetLocalDataOperation]; - [strongSelf _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + [self dispatchSyncWithAccountKeys:^bool { + self.keyStateLocalResetRequested = true; + resetOperation = [self createPendingResetLocalDataOperation]; + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; return true; }]; @@ -592,12 +698,12 @@ [self scheduleOperationWithoutDependencies:resetOperationGroup]; CKKSGroupOperation* viewReset = [CKKSGroupOperation named:@"local-data-reset" withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { - __strong __typeof(weakSelf) strongSelf = weakSelf; + STRONGIFY(self); // Now that the local reset finished, wait for the key hierarchy state machine to churn - ckksnotice("ckksreset", strongSelf, "waiting for key hierarchy to become ready (after local reset)"); + ckksnotice("ckksreset", self, "waiting for key hierarchy to become nontransient (after local reset)"); CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-local-reset" withBlock:^{}]; [waitOp timeout: 60*NSEC_PER_SEC]; - [waitOp addNullableDependency:strongSelf.keyStateReadyDependency]; + [waitOp addNullableDependency:self.keyStateNonTransientDependency]; [strongOp runBeforeGroupFinished:waitOp]; }]; @@ -607,14 +713,14 @@ return viewReset; } else { // Since we're logged out, we must run the reset ourselves - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* pendingResetLocalOperation = [CKKSResultOperation named:@"reset-local" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); __block NSError* error = nil; - [strongSelf dispatchSync: ^bool{ - [strongSelf _onqueueResetLocalData: &error]; + [self dispatchSync: ^bool{ + [self _onqueueResetLocalData: &error]; return true; }]; @@ -637,43 +743,51 @@ } - (CKKSResultOperation*)resetCloudKitZone:(CKOperationGroup*)operationGroup { + [self.accountStateKnown wait:(SecCKKSTestsEnabled() ? 1*NSEC_PER_SEC : 10*NSEC_PER_SEC)]; + // Not overly thread-safe, but a single read is okay - if(self.accountStatus == CKKSAccountStatusAvailable) { - // Actually running the delete operation will be handled by the CKKS key state machine - ckksnotice("ckksreset", self, "Requesting reset of CK zone (logged in)"); - - __block CKKSResultOperation* deleteOperation = nil; - [self dispatchSyncWithAccountKeys:^bool { - self.keyStateCloudKitDeleteRequested = true; - deleteOperation = [self createPendingDeleteZoneOperation:operationGroup]; - [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; - return true; + if(self.accountStatus != CKKSAccountStatusAvailable) { + // No CK account? goodbye! + ckksnotice("ckksreset", self, "Requesting reset of CK zone, but no CK account exists"); + CKKSResultOperation* errorOp = [CKKSResultOperation named:@"fail" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull op) { + op.error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotLoggedIn + description:@"User is not signed into iCloud."]; }]; - __weak __typeof(self) weakSelf = self; - CKKSGroupOperation* viewReset = [CKKSGroupOperation named:[NSString stringWithFormat:@"cloudkit-view-reset-%@", self.zoneName] - withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { - __strong __typeof(self) strongSelf = weakSelf; - // Now that the delete finished, wait for the key hierarchy state machine - ckksnotice("ckksreset", strongSelf, "waiting for key hierarchy to become ready (after cloudkit reset)"); - CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-reset" withBlock:^{}]; - [waitOp timeout: 60*NSEC_PER_SEC]; - [waitOp addNullableDependency:strongSelf.keyStateReadyDependency]; + [self scheduleOperationWithoutDependencies:errorOp]; + return errorOp; + } - [strongOp runBeforeGroupFinished:waitOp]; - }]; + // Actually running the delete operation will be handled by the CKKS key state machine + ckksnotice("ckksreset", self, "Requesting reset of CK zone (logged in)"); + + __block CKKSResultOperation* deleteOperation = nil; + [self dispatchSyncWithAccountKeys:^bool { + self.keyStateCloudKitDeleteRequested = true; + deleteOperation = [self createPendingDeleteZoneOperation:operationGroup]; + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + return true; + }]; - [viewReset addDependency:deleteOperation]; - [self.waitingQueue addOperation:viewReset]; + WEAKIFY(self); + CKKSGroupOperation* viewReset = [CKKSGroupOperation named:[NSString stringWithFormat:@"cloudkit-view-reset-%@", self.zoneName] + withBlockTakingSelf:^(CKKSGroupOperation *strongOp) { + STRONGIFY(self); + // Now that the delete finished, wait for the key hierarchy state machine + ckksnotice("ckksreset", self, "waiting for key hierarchy to become nontransient (after cloudkit reset)"); + CKKSResultOperation* waitOp = [CKKSResultOperation named:@"waiting-for-reset" withBlock:^{}]; + [waitOp timeout: 60*NSEC_PER_SEC]; + [waitOp addNullableDependency:self.keyStateNonTransientDependency]; + + [strongOp runBeforeGroupFinished:waitOp]; + }]; - return viewReset; - } else { - // Since we're logged out, we just need to run this ourselves - ckksnotice("ckksreset", self, "Requesting reset of CK zone (logged out)"); - CKKSResultOperation* deleteOperation = [self createPendingDeleteZoneOperation:operationGroup]; - [self scheduleOperationWithoutDependencies:deleteOperation]; - return deleteOperation; - } + [viewReset timeout:30*NSEC_PER_SEC]; + [viewReset addDependency:deleteOperation]; + [self.waitingQueue addOperation:viewReset]; + + return viewReset; } - (void)_onqueueKeyStateMachineRequestFetch { @@ -706,18 +820,18 @@ } - (CKKSResultOperation*)createKeyStateReadyDependency:(NSString*)message ckoperationGroup:(CKOperationGroup*)group { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* keyStateReadyDependency = [CKKSResultOperation operationWithBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { return; } - ckksnotice("ckkskey", strongSelf, "%@", message); + ckksnotice("ckkskey", self, "%@", message); - [strongSelf dispatchSync:^bool { - if(strongSelf.droppedItems) { + [self dispatchSync:^bool { + if(self.droppedItems) { // While we weren't in 'ready', keychain modifications might have come in and were dropped on the floor. Find them! - ckksnotice("ckkskey", strongSelf, "Launching scan operation for missed items"); + ckksnotice("ckkskey", self, "Launching scan operation for missed items"); [self scanLocalItems:@"ready-again-scan" ckoperationGroup:group after:nil]; } return true; @@ -729,10 +843,10 @@ } - (CKKSResultOperation*)createKeyStateNontransientDependency { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); return [CKKSResultOperation named:[NSString stringWithFormat: @"%@-key-state-nontransient", self.zoneName] withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - ckksnotice("ckkskey", strongSelf, "Key state is now non-transient"); + STRONGIFY(self); + ckksnotice("ckkskey", self, "Key state is now non-transient"); }]; } @@ -742,7 +856,7 @@ // Note that this function cannot rely on doing any database work; it might get rolled back, especially in an error state - (void)_onqueueAdvanceKeyStateMachineToState: (CKKSZoneKeyState*) state withError: (NSError*) error { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // Resetting back to 'loggedout' takes all precedence. if([state isEqual:SecCKKSZoneKeyStateLoggedOut]) { @@ -752,10 +866,13 @@ resetMessage:@"Key state has become ready for the first time (after reset)." ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"key-state-after-logout"]]; - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:nil]; + self.launch = nil; return; } + [self.launch addEvent:state]; + // Resetting back to 'initialized' also takes precedence if([state isEqual:SecCKKSZoneKeyStateInitializing]) { ckksnotice("ckkskey", self, "Resetting the key hierarchy state machine back to '%@'", state); @@ -766,11 +883,42 @@ // Begin initialization, but rate-limit it self.keyStateMachineOperation = [self createPendingInitializationOperation]; - [self.keyStateMachineOperation addNullableDependency:self.initializeScheduler.operationDependency]; - [self.initializeScheduler trigger]; + [self.keyStateMachineOperation addNullableDependency:self.zoneModifier.cloudkitRetryAfter.operationDependency]; + [self.zoneModifier.cloudkitRetryAfter trigger]; [self scheduleOperation:self.keyStateMachineOperation]; - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:nil]; + return; + } + + // Resetting to 'waitfortrust' also takes precedence + if([state isEqualToString:SecCKKSZoneKeyStateWaitForTrust]) { + if([self.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateLoggedOut]) { + ckksnotice("ckks", self, "Asked to waitfortrust, but we're already in loggedout. Ignoring..."); + return; + } + + ckksnotice("ckks", self, "Entering waitfortrust"); + self.keyHierarchyState = SecCKKSZoneKeyStateWaitForTrust; + self.keyHierarchyError = nil; + self.keyStateMachineOperation = nil; + + [self ensureKeyStateReadyDependency:@"Key state has become ready for the first time (after lacking trust)."]; + + if(self.trustStatus == CKKSAccountStatusAvailable) { + // Note: we go to initialized here, since to enter waitfortrust CKKS has already gone through initializing + // initialized should refetch only if needed. + ckksnotice("ckks", self, "CKKS is trusted, moving to initialized"); + self.keyStateMachineOperation = [self operationToEnterState:SecCKKSZoneKeyStateInitialized + keyStateError:nil + named:@"re-enter initialized"]; + [self scheduleOperation:self.keyStateMachineOperation]; + } + + // In wait for trust, we might have a keyset. Who knows! + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:self.zoneID]; + [self _onqueueHandleKeyStateNonTransientDependency:keyset]; + return; } @@ -790,12 +938,12 @@ // After the next unlock, fake that we received the last zone transition CKKSZoneKeyState* lastState = self.keyHierarchyState; self.keyStateMachineOperation = [NSBlockOperation named:@"key-state-after-unlock" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { return; } - [strongSelf dispatchSync:^bool{ - [strongSelf _onqueueAdvanceKeyStateMachineToState:lastState withError:nil]; + [self dispatchSyncWithAccountKeys:^bool{ + [self _onqueueAdvanceKeyStateMachineToState:lastState withError:nil]; return true; }]; }]; @@ -806,7 +954,7 @@ [self.keyStateMachineOperation addNullableDependency:self.lockStateTracker.unlockDependency]; [self scheduleOperation:self.keyStateMachineOperation]; - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:nil]; return; } else { @@ -822,7 +970,7 @@ self.keyHierarchyState = SecCKKSZoneKeyStateError; self.keyHierarchyError = error; - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:nil]; return; } } @@ -860,9 +1008,17 @@ } #if DEBUG - // During testing, keep the developer honest: this function should always have the self identities - if(self.currentSelfPeersError) { - NSAssert(self.currentSelfPeersError.code != CKKSNoPeersAvailable, @"Must have viable (or errored) self peers to advance key state"); + // During testing, keep the developer honest: this function should always have the self identities, unless the account has lost trust + if(self.trustStatus == CKKSAccountStatusAvailable && ![state isEqualToString:SecCKKSZoneKeyStateLoggedOut]) { + bool hasSelfIdentities = false; + NSAssert(self.currentTrustStates.count > 0, @"Should have at least one trust state"); + for(CKKSPeerProviderState* state in self.currentTrustStates) { + if(state.currentSelfPeersError == nil || state.currentSelfPeersError.code != CKKSNoPeersAvailable) { + hasSelfIdentities = true; + } + } + + NSAssert(hasSelfIdentities, @"Must have viable (or errored) self peers to advance key state"); } #endif @@ -871,7 +1027,7 @@ NSError* nextError = nil; // Many of our decisions below will be based on what keys exist. Help them out. - CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] initForZone:self.zoneID]; + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:self.zoneID]; NSError* localerror = nil; NSArray* localKeys = [CKKSKey localKeys:self.zoneID error:&localerror]; NSArray* remoteKeys = [CKKSKey remoteKeys:self.zoneID error: &localerror]; @@ -885,7 +1041,7 @@ ckkserror("ckkskey", self, "couldn't fetch keys and OQEs from local database, entering error state: %@", localerror); self.keyHierarchyState = SecCKKSZoneKeyStateError; self.keyHierarchyError = localerror; - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:nil]; return; } @@ -904,7 +1060,23 @@ CKKSResultOperation* deleteOp = [self createPendingDeleteZoneOperation:self.keyHierarchyOperationGroup]; [op runBeforeGroupFinished: deleteOp]; - NSOperation* nextStateOp = [self operationToEnterState:SecCKKSZoneKeyStateResettingLocalData keyStateError:nil named:@"state-resetting-local"]; + NSOperation* nextStateOp = [CKKSResultOperation named:@"inspect-zone-delete" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull op) { + STRONGIFY(self); + [self dispatchSyncWithAccountKeys:^bool { + // Did the delete op succeed? + if(deleteOp.error == nil) { + ckksnotice("ckkskey", self, "Zone deletion operation complete! Proceeding to reset local data"); + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateResettingLocalData withError:nil]; + return true; + } + + ckksnotice("ckkskey", self, "Zone deletion operation failed, will retry: %@", deleteOp.error); + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateResettingZone withError:nil]; + + return true; + }]; + }]; + [nextStateOp addDependency:deleteOp]; [op runBeforeGroupFinished:nextStateOp]; @@ -929,12 +1101,25 @@ self.keyStateMachineOperation = op; self.keyStateLocalResetRequested = false; - } else if([state isEqualToString:SecCKKSZoneKeyStateZoneCreationFailed]) { - //Prepare to go back into initializing, as soon as the initializeScheduler is happy + //Prepare to go back into initializing, as soon as the cloudkitRetryAfter is happy self.keyStateMachineOperation = [self operationToEnterState:SecCKKSZoneKeyStateInitializing keyStateError:nil named:@"recover-from-cloudkit-failure"]; - [self.keyStateMachineOperation addNullableDependency:self.initializeScheduler.operationDependency]; - [self.initializeScheduler trigger]; + [self.keyStateMachineOperation addNullableDependency:self.zoneModifier.cloudkitRetryAfter.operationDependency]; + [self.zoneModifier.cloudkitRetryAfter trigger]; + + } else if([state isEqualToString:SecCKKSZoneKeyStateWaitForTrust]) { + // Actually entering this state should have been handled above, so let's check if we can exit it here... + if(self.trustStatus == CKKSAccountStatusAvailable) { + ckksnotice("ckkskey", self, "Beginning trusted state machine operation"); + nextState = SecCKKSZoneKeyStateInitialized; + + } else if (self.tlkCreationRequested) { + ckksnotice("ckkskey", self, "No trust, but TLK creation is requested. Moving to fetchcomplete."); + nextState = SecCKKSZoneKeyStateFetchComplete; + + } else { + ckksnotice("ckkskey", self, "Remaining in 'waitfortrust'"); + } } else if([state isEqualToString: SecCKKSZoneKeyStateReady]) { if(self.keyStateProcessRequested || [remoteKeys count] > 0) { @@ -951,10 +1136,18 @@ // In ready, but someone has requested a fetch. Kick it off. ckksnotice("ckkskey", self, "Kicking off a key refetch based on request:%d", self.keyStateFetchRequested); nextState = SecCKKSZoneKeyStateFetch; // Don't go to 'ready', go to 'initialized', since we want to fetch again + } else if (self.trustStatus != CKKSAccountStatusAvailable) { + ckksnotice("ckkskey", self, "Asked to go into ready, but there's no trust; going into waitfortrust"); + nextState = SecCKKSZoneKeyStateWaitForTrust; + } else if (self.trustedPeersSetChanged) { + ckksnotice("ckkskey", self, "Received a nudge that the trusted peers set might have changed! Reprocessing."); + nextState = SecCKKSZoneKeyStateProcess; + self.trustedPeersSetChanged = false; } + // TODO: kick off a key roll if one has been requested - if(!self.keyStateMachineOperation) { + if(!self.keyStateMachineOperation && !nextState) { // We think we're ready. Double check. CKKSZoneKeyState* checkedstate = [self _onqueueEnsureKeyHierarchyHealth:keyset error:&hierarchyError]; if(![checkedstate isEqualToString:SecCKKSZoneKeyStateReady] || hierarchyError) { @@ -968,7 +1161,14 @@ } } else if([state isEqualToString: SecCKKSZoneKeyStateInitialized]) { - // We're initialized and CloudKit is ready. See what needs done... + // We're initialized and CloudKit is ready. If we're trusted, see what needs done. Otherwise, wait. + + // Note: we might be still 'untrusted' at this point. The state machine is responsible for not entering 'ready' until + // we are trusted. + // This is acceptable only if the key state machine does not make new TLKs without being trusted! + + // Set this state, for test use + self.keyHierarchyState = SecCKKSZoneKeyStateInitialized; CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.zoneName]; [self _onqueuePerformKeyStateInitialized:ckse]; @@ -1016,10 +1216,10 @@ ckksnotice("ckkskey", self, "Waiting for the fixup operation: %@", self.lastFixupOperation); self.keyStateMachineOperation = [NSBlockOperation named:@"key-state-after-fixup" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - [strongSelf dispatchSyncWithAccountKeys:^bool{ + STRONGIFY(self); + [self dispatchSyncWithAccountKeys:^bool{ ckksnotice("ckkskey", self, "Fixup operation complete! Restarting key hierarchy machinery"); - [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitialized withError:nil]; + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitialized withError:nil]; return true; }]; }]; @@ -1029,12 +1229,12 @@ // We've just completed a fetch of everything. Are there any remote keys? if(remoteKeys.count > 0u) { // Process the keys we received. - self.keyStateMachineOperation = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView: self]; + self.keyStateMachineOperation = [[CKKSProcessReceivedKeysStateMachineOperation alloc] initWithCKKSKeychainView: self]; } else if( (keyset.currentTLKPointer || keyset.currentClassAPointer || keyset.currentClassCPointer) && !(keyset.tlk && keyset.classA && keyset.classC)) { // Huh. We appear to have current key pointers, but the keys themselves don't exist. That's weird. // Transfer to the "unhealthy" state to request a fix - ckksnotice("ckkskey", self, "We appear to have current key pointers but no keys to match them. Moving to 'unhealthy'"); + ckksnotice("ckkskey", self, "We appear to have current key pointers but no keys to match them: %@ Moving to 'unhealthy'", keyset); nextState = SecCKKSZoneKeyStateUnhealthy; } else { // No remote keys, and the pointers look sane? Do we have an existing key hierarchy? @@ -1042,15 +1242,55 @@ if([checkedstate isEqualToString:SecCKKSZoneKeyStateReady] && !hierarchyError) { ckksnotice("ckkskey", self, "After fetch, everything looks good."); nextState = checkedstate; + } else if(localKeys.count == 0 && remoteKeys.count == 0) { - ckksnotice("ckkskey", self, "After fetch, we don't have any key hierarchy. Making a new one: %@", hierarchyError); - self.keyStateMachineOperation = [[CKKSNewTLKOperation alloc] initWithCKKSKeychainView: self ckoperationGroup:self.keyHierarchyOperationGroup]; + ckksnotice("ckkskey", self, "After fetch, we don't have any key hierarchy. Entering a waiting state: %@", hierarchyError ?: @"no error"); + nextState = SecCKKSZoneKeyStateWaitForTLKCreation; } else { - ckksnotice("ckkskey", self, "After fetch, we have a possibly unhealthy key hierarchy. Moving to %@: %@", checkedstate, hierarchyError); + ckksnotice("ckkskey", self, "After fetch, we have a possibly unhealthy key hierarchy. Moving to %@: %@", checkedstate, hierarchyError ?: @"no error"); nextState = checkedstate; } } + } else if([state isEqualToString:SecCKKSZoneKeyStateWaitForTLKCreation]) { + + if(self.tlkCreationRequested) { + self.tlkCreationRequested = false; + ckksnotice("ckkskey", self, "TLK creation requested; kicking off operation"); + self.keyStateMachineOperation = [[CKKSNewTLKOperation alloc] initWithCKKSKeychainView: self ckoperationGroup:self.keyHierarchyOperationGroup]; + + } else if(self.keyStateProcessRequested) { + ckksnotice("ckkskey", self, "We believe we need to create TLKs but we also received a key nudge; moving to key state Process."); + nextState = SecCKKSZoneKeyStateProcess; + + } else { + ckksnotice("ckkskey", self, "We believe we need to create TLKs; waiting for Octagon (via %@)", self.suggestTLKUpload); + [self.suggestTLKUpload trigger]; + } + + + } else if([state isEqualToString:SecCKKSZoneKeyStateWaitForTLKUpload]) { + ckksnotice("ckkskey", self, "We believe we have TLKs that need uploading"); + + + if(self.keyStateProcessRequested) { + if(keyset.currentTLKPointer.currentKeyUUID) { + ckksnotice("ckkskey", self, "Received a nudge that our TLK records might be here (and there's some current TLK pointer)"); + nextState = SecCKKSZoneKeyStateProcess; + } else { + ckksnotice("ckkskey", self, "Received a nudge that our TLK records might be here, but there's no TLK pointer. Staying in WaitForTLKUpload."); + self.keyStateProcessRequested = false; + } + } + + if(nextState == nil) { + ckksnotice("ckkskey", self, "Alerting any listener of our proposed keyset: %@", self.lastNewTLKOperation.keyset); + [self _onqueueRunKeysetProviderOperations:self.lastNewTLKOperation.keyset]; + + ckksnotice("ckkskey", self, "Notifying Octagon again, just in case"); + [self.suggestTLKUpload trigger]; + } + } else if([state isEqualToString: SecCKKSZoneKeyStateWaitForTLK]) { // We're in a hold state: waiting for the TLK bytes to arrive. @@ -1067,11 +1307,17 @@ } else { // Should we nuke this zone? - if([self _onqueueOtherDevicesReportHavingTLKs:keyset]) { - ckksnotice("ckkskey", self, "Other devices report having TLK(%@). Entering a waiting state", keyset.currentTLKPointer); + if(self.trustStatus == CKKSAccountStatusAvailable) { + if([self _onqueueOtherDevicesReportHavingTLKs:keyset]) { + ckksnotice("ckkskey", self, "Other devices report having TLK(%@). Entering a waiting state", keyset.currentTLKPointer); + } else { + ckksnotice("ckkskey", self, "No other devices have TLK(%@). Beginning zone reset...", keyset.currentTLKPointer); + self.keyHierarchyOperationGroup = [CKOperationGroup CKKSGroupWithName:@"tlk-missing"]; + nextState = SecCKKSZoneKeyStateResettingZone; + } } else { - ckksnotice("ckkskey", self, "No other devices have TLK(%@). Beginning zone reset...", keyset.currentTLKPointer); - nextState = SecCKKSZoneKeyStateResettingZone; + ckksnotice("ckkskey", self, "This device isn't trusted, so don't modify the existing TLK(%@)", keyset.currentTLKPointer); + nextState = SecCKKSZoneKeyStateWaitForTrust; } } @@ -1099,8 +1345,14 @@ [self _onqueueKeyHierarchyFetch]; } else if([state isEqualToString:SecCKKSZoneKeyStateUnhealthy]) { - ckksnotice("ckkskey", self, "Looks like the key hierarchy is unhealthy. Launching fix."); - self.keyStateMachineOperation = [[CKKSHealKeyHierarchyOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:self.keyHierarchyOperationGroup]; + if(self.trustStatus != CKKSAccountStatusAvailable) { + ckksnotice("ckkskey", self, "Looks like the key hierarchy is unhealthy, but we're untrusted."); + nextState = SecCKKSZoneKeyStateWaitForTrust; + + } else { + ckksnotice("ckkskey", self, "Looks like the key hierarchy is unhealthy. Launching fix."); + self.keyStateMachineOperation = [[CKKSHealKeyHierarchyOperation alloc] initWithCKKSKeychainView:self ckoperationGroup:self.keyHierarchyOperationGroup]; + } } else if([state isEqualToString:SecCKKSZoneKeyStateHealTLKShares]) { ckksnotice("ckksshare", self, "Key hierarchy is okay, but not shared appropriately. Launching fix."); @@ -1109,7 +1361,7 @@ } else if([state isEqualToString:SecCKKSZoneKeyStateProcess]) { ckksnotice("ckksshare", self, "Launching key state process"); - self.keyStateMachineOperation = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView: self]; + self.keyStateMachineOperation = [[CKKSProcessReceivedKeysStateMachineOperation alloc] initWithCKKSKeychainView: self]; // Since we're starting a reprocess, this is answering all previous requests. self.keyStateProcessRequested = false; @@ -1117,7 +1369,7 @@ } else { ckkserror("ckks", self, "asked to advance state machine to unknown state: %@", state); self.keyHierarchyState = state; - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:keyset]; return; } @@ -1128,6 +1380,7 @@ // Ready enough! [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastKeystateReady inView:self]; + if(self.keyStateReadyDependency) { [self scheduleOperation: self.keyStateReadyDependency]; self.keyStateReadyDependency = nil; @@ -1167,7 +1420,7 @@ } else if(![state isEqualToString: nextState]) { ckksnotice("ckkskey", self, "Staying in state %@, but proceeding to %@ as soon as possible", self.keyHierarchyState, nextState); - self.keyStateMachineOperation = [self operationToEnterState:nextState keyStateError:nextError named:@"next-key-state"]; + self.keyStateMachineOperation = [self operationToEnterState:nextState keyStateError:nextError named:[NSString stringWithFormat:@"next-key-state-%@", nextState]]; [self scheduleOperation: self.keyStateMachineOperation]; } else { @@ -1180,10 +1433,10 @@ } } - [self _onqueueHandleKeyStateNonTransientDependency]; + [self _onqueueHandleKeyStateNonTransientDependency:keyset]; } -- (void)_onqueueHandleKeyStateNonTransientDependency { +- (void)_onqueueHandleKeyStateNonTransientDependency:(CKKSCurrentKeySet* _Nullable)keyset { dispatch_assert_queue(self.queue); if(CKKSKeyStateTransient(self.keyHierarchyState)) { @@ -1196,24 +1449,40 @@ [self scheduleOperation: self.keyStateNonTransientDependency]; self.keyStateNonTransientDependency = nil; } + + if(keyset && keyset.currentTLKPointer.currentKeyUUID) { + [self _onqueueRunKeysetProviderOperations:keyset]; + } else { + ckksnotice("ckkskey", self, "State machine is nontransient, but no keyset..."); + } } } - (NSOperation*)operationToEnterState:(CKKSZoneKeyState*)state keyStateError:(NSError* _Nullable)keyStateError named:(NSString*)name { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); return [NSBlockOperation named:name withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { return; } - [strongSelf dispatchSyncWithAccountKeys:^bool{ - [strongSelf _onqueueAdvanceKeyStateMachineToState:state withError:keyStateError]; + [self dispatchSyncWithAccountKeys:^bool{ + [self _onqueueAdvanceKeyStateMachineToState:state withError:keyStateError]; return true; }]; }]; } +- (BOOL)otherDevicesReportHavingTLKs:(CKKSCurrentKeySet*)keyset +{ + __block BOOL report = false; + [self dispatchSync:^bool{ + report = [self _onqueueOtherDevicesReportHavingTLKs:keyset]; + return true; + }]; + return report ? YES : NO; +} + - (bool)_onqueueOtherDevicesReportHavingTLKs:(CKKSCurrentKeySet*)keyset { dispatch_assert_queue(self.queue); @@ -1229,9 +1498,12 @@ [untrustedOffset setDay:-4]; NSDate* untrustedDeadline = [[NSCalendar currentCalendar] dateByAddingComponents:untrustedOffset toDate:now options:0]; + NSMutableSet* trustedPeerIDs = [NSMutableSet set]; - for(id peer in self.currentTrustedPeers) { - [trustedPeerIDs addObject:peer.peerID]; + for(CKKSPeerProviderState* trustState in self.currentTrustStates) { + for(id peer in trustState.currentTrustedPeers) { + [trustedPeerIDs addObject:peer.peerID]; + } } NSError* localerror = nil; @@ -1243,12 +1515,12 @@ return true; } for(CKKSDeviceStateEntry* device in allDeviceStates) { - if(device.octagonPeerID != nil) { - ckksnotice("ckkskey", self, "An Octagon-capable device has been in this account; not resetting: (%@)", device); - return true; - } + // The peerIDs in CDSEs aren't written with the peer prefix. Make sure we match both. + NSString* sosPeerID = device.circlePeerID ? [CKKSSOSPeerPrefix stringByAppendingString:device.circlePeerID] : nil; - if([trustedPeerIDs containsObject:device.circlePeerID] || [trustedPeerIDs containsObject:device.octagonPeerID]) { + if([trustedPeerIDs containsObject:device.circlePeerID] || + [trustedPeerIDs containsObject:sosPeerID] || + [trustedPeerIDs containsObject:device.octagonPeerID]) { // Is this a recent DSE? If it's older than the deadline, skip it if([device.storedCKRecord.modificationDate compare:trustedDeadline] == NSOrderedAscending) { ckksnotice("ckkskey", self, "Trusted device state (%@) is too old; ignoring", device); @@ -1271,7 +1543,7 @@ } } - NSArray* tlkShares = [CKKSTLKShare allForUUID:keyset.currentTLKPointer.currentKeyUUID + NSArray* tlkShares = [CKKSTLKShareRecord allForUUID:keyset.currentTLKPointer.currentKeyUUID zoneID:self.zoneID error:&localerror]; if(localerror) { @@ -1280,7 +1552,7 @@ return false; } - for(CKKSTLKShare* tlkShare in tlkShares) { + for(CKKSTLKShareRecord* tlkShare in tlkShares) { if([trustedPeerIDs containsObject:tlkShare.senderPeerID] && [tlkShare.storedCKRecord.modificationDate compare:trustedDeadline] == NSOrderedDescending) { ckksnotice("ckkskey", self, "Trusted TLK Share (%@) created recently; other devices have keys and should send them to us", tlkShare); @@ -1289,7 +1561,7 @@ } // Okay, how about the untrusted deadline? - for(CKKSTLKShare* tlkShare in tlkShares) { + for(CKKSTLKShareRecord* tlkShare in tlkShares) { if([tlkShare.storedCKRecord.modificationDate compare:untrustedDeadline] == NSOrderedDescending) { ckksnotice("ckkskey", self, "Untrusted TLK Share (%@) created very recently; other devices might have keys and should rejoin the circle (and send them to us)", tlkShare); return true; @@ -1302,7 +1574,11 @@ // For this key, who doesn't yet have a valid CKKSTLKShare for it? // Note that we really want a record sharing the TLK to ourselves, so this function might return // a non-empty set even if all peers have the TLK: it wants us to make a record for ourself. -- (NSSet>*)_onqueueFindPeersMissingShare:(CKKSKey*)key error:(NSError* __autoreleasing*)error { +- (NSSet>*)_onqueueFindPeers:(CKKSPeerProviderState*)trustState + missingShare:(CKKSKey*)key + afterUploading:(NSSet* _Nullable)newShares + error:(NSError* __autoreleasing*)error +{ dispatch_assert_queue(self.queue); if(!key) { @@ -1310,32 +1586,49 @@ return [NSSet set]; } - if(self.currentTrustedPeersError) { - ckkserror("ckksshare", self, "Couldn't find missing shares because trusted peers aren't available: %@", self.currentTrustedPeersError); + if(trustState.currentTrustedPeersError) { + ckkserror("ckksshare", self, "Couldn't find missing shares because trusted peers aren't available: %@", trustState.currentTrustedPeersError); if(error) { - *error = self.currentTrustedPeersError; + *error = trustState.currentTrustedPeersError; } return [NSSet set]; } - if(self.currentSelfPeersError) { - ckkserror("ckksshare", self, "Couldn't find missing shares because self peers aren't available: %@", self.currentSelfPeersError); + if(trustState.currentSelfPeersError) { + ckkserror("ckksshare", self, "Couldn't find missing shares because self peers aren't available: %@", trustState.currentSelfPeersError); if(error) { - *error = self.currentSelfPeersError; + *error = trustState.currentSelfPeersError; } return [NSSet set]; } NSMutableSet>* peersMissingShares = [NSMutableSet set]; - NSMutableSet* trustedPeerIDs = [NSMutableSet set]; - for(id peer in self.currentTrustedPeers) { - [trustedPeerIDs addObject:peer.peerID]; + // Ensure that the 'self peer' is one of the current trusted peers. Otherwise, any TLKShare we create + // won't be considered trusted the next time through... + if(![trustState.currentTrustedPeerIDs containsObject:trustState.currentSelfPeers.currentSelf.peerID]) { + ckkserror("ckksshare", self, "current self peer (%@) is not in the set of trusted peers: %@", + trustState.currentSelfPeers.currentSelf.peerID, + trustState.currentTrustedPeerIDs); + + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSLackingTrust + description:[NSString stringWithFormat:@"current self peer (%@) is not in the set of trusted peers", + trustState.currentSelfPeers.currentSelf.peerID]]; + } + + return nil; } - for(id peer in self.currentTrustedPeers) { + for(id peer in trustState.currentTrustedPeers) { + if(![peer shouldHaveView:self.zoneName]) { + ckkserror("ckksshare", self, "Peer (%@) is not supposed to have view, skipping", peer); + continue; + } + NSError* peerError = nil; // Find all the shares for this peer for this key - NSArray* currentPeerShares = [CKKSTLKShare allFor:peer.peerID + NSArray* currentPeerShares = [CKKSTLKShareRecord allFor:peer.peerID keyUUID:key.uuid zoneID:self.zoneID error:&peerError]; @@ -1348,25 +1641,34 @@ return nil; } + // Include the new shares, too.... + NSArray* possiblePeerShares = newShares ? [currentPeerShares arrayByAddingObjectsFromArray:[newShares allObjects]] : currentPeerShares; + // Determine if we think this peer has enough things shared to them bool alreadyShared = false; - for(CKKSTLKShare* existingPeerShare in currentPeerShares) { + for(CKKSTLKShareRecord* existingPeerShare in possiblePeerShares) { + // Ensure this share is to this peer... + if(![existingPeerShare.share.receiverPeerID isEqualToString:peer.peerID]) { + continue; + } + // If an SOS Peer sent this share, is its signature still valid? Or did the signing key change? if([existingPeerShare.senderPeerID hasPrefix:CKKSSOSPeerPrefix]) { NSError* signatureError = nil; - if(![existingPeerShare signatureVerifiesWithPeerSet:self.currentTrustedPeers error:&signatureError]) { + if(![existingPeerShare signatureVerifiesWithPeerSet:trustState.currentTrustedPeers error:&signatureError]) { ckksnotice("ckksshare", self, "Existing TLKShare's signature doesn't verify with current peer set: %@ %@", signatureError, existingPeerShare); continue; } } - if([existingPeerShare.tlkUUID isEqualToString: key.uuid] && [trustedPeerIDs containsObject:existingPeerShare.senderPeerID]) { - + if([existingPeerShare.tlkUUID isEqualToString:key.uuid] && [trustState.currentTrustedPeerIDs containsObject:existingPeerShare.senderPeerID]) { // Was this shared to us? - if([peer.peerID isEqualToString: self.currentSelfPeers.currentSelf.peerID]) { + if([peer.peerID isEqualToString: trustState.currentSelfPeers.currentSelf.peerID]) { // We only count this as 'found' if we did the sharing and it's to our current keys - if([existingPeerShare.senderPeerID isEqualToString:self.currentSelfPeers.currentSelf.peerID] && - [existingPeerShare.receiver.publicEncryptionKey isEqual:self.currentSelfPeers.currentSelf.publicEncryptionKey]) { + NSData* currentKey = trustState.currentSelfPeers.currentSelf.publicEncryptionKey.keyData; + + if([existingPeerShare.senderPeerID isEqualToString:trustState.currentSelfPeers.currentSelf.peerID] && + [existingPeerShare.share.receiverPublicEncryptionKeySPKI isEqual:currentKey]) { ckksnotice("ckksshare", self, "Local peer %@ is shared %@ via self: %@", peer, key, existingPeerShare); alreadyShared = true; break; @@ -1376,7 +1678,9 @@ } else { // Was this shared to the remote peer's current keys? - if([peer.publicEncryptionKey isEqual: existingPeerShare.receiver.publicEncryptionKey]) { + NSData* currentKeySPKI = peer.publicEncryptionKey.keyData; + + if([existingPeerShare.share.receiverPublicEncryptionKeySPKI isEqual:currentKeySPKI]) { // Some other peer has a trusted share. Cool! ckksnotice("ckksshare", self, "Peer %@ is shared %@ via trusted %@", peer, key, existingPeerShare); alreadyShared = true; @@ -1399,33 +1703,105 @@ if(peersMissingShares.count > 0u) { // Log each and every one of the things ckksnotice("ckksshare", self, "Missing TLK shares for %lu peers: %@", (unsigned long)peersMissingShares.count, peersMissingShares); - ckksnotice("ckksshare", self, "Self peers are (%@) %@", self.currentSelfPeersError ?: @"no error", self.currentSelfPeers); - ckksnotice("ckksshare", self, "Trusted peers are (%@) %@", self.currentTrustedPeersError ?: @"no error", self.currentTrustedPeers); + ckksnotice("ckksshare", self, "Self peers are (%@) %@", trustState.currentSelfPeersError ?: @"no error", trustState.currentSelfPeers); + ckksnotice("ckksshare", self, "Trusted peers are (%@) %@", trustState.currentTrustedPeersError ?: @"no error", trustState.currentTrustedPeers); } return peersMissingShares; } -- (NSSet*)_onqueueCreateMissingKeyShares:(CKKSKey*)key error:(NSError* __autoreleasing*)error { +- (BOOL)_onqueueAreNewSharesSufficient:(NSSet*)newShares + currentTLK:(CKKSKey*)key + error:(NSError* __autoreleasing*)error +{ + dispatch_assert_queue(self.queue); + + for(CKKSPeerProviderState* trustState in self.currentTrustStates) { + NSError* localError = nil; + NSSet>* peersMissingShares = [self _onqueueFindPeers:trustState + missingShare:key + afterUploading:newShares + error:&localError]; + if(peersMissingShares == nil || localError) { + if(trustState.essential) { + if(error) { + *error = localError; + } + return NO; + } else { + ckksnotice("ckksshare", self, "Failed to find peers for nonessential system: %@", trustState); + // Not a hard failure. + } + } + + if(peersMissingShares.count > 0) { + ckksnotice("ckksshare", self, "New share set is missing shares for peers: %@", peersMissingShares); + return NO; + } + } + + return YES; +} + +- (NSSet*)_onqueueCreateMissingKeyShares:(CKKSKey*)key + error:(NSError* __autoreleasing*)error +{ + NSError* localerror = nil; + NSSet* newShares = nil; + + // If any one of our trust states succeed, this function doesn't have an error + for(CKKSPeerProviderState* trustState in self.currentTrustStates) { + NSError* stateError = nil; + + NSSet* newTrustShares = [self _onqueueCreateMissingKeyShares:key + peers:trustState + error:&stateError]; + + + if(newTrustShares && !stateError) { + newShares = newShares ? [newShares setByAddingObjectsFromSet:newTrustShares] : newTrustShares; + } else { + ckksnotice("ckksshare", self, "Unable to create shares for trust set %@: %@", trustState, stateError); + if(localerror == nil) { + localerror = stateError; + } + } + } + + // Only report an error if none of the trust states were able to succeed + if(newShares) { + return newShares; + } else { + if(error && localerror) { + *error = localerror; + } + return nil; + } +} + +- (NSSet*)_onqueueCreateMissingKeyShares:(CKKSKey*)key + peers:(CKKSPeerProviderState*)trustState + error:(NSError* __autoreleasing*)error +{ dispatch_assert_queue(self.queue); - if(self.currentTrustedPeersError) { - ckkserror("ckksshare", self, "Couldn't create missing shares because trusted peers aren't available: %@", self.currentTrustedPeersError); + if(trustState.currentTrustedPeersError) { + ckkserror("ckksshare", self, "Couldn't create missing shares because trusted peers aren't available: %@", trustState.currentTrustedPeersError); if(error) { - *error = self.currentTrustedPeersError; + *error = trustState.currentTrustedPeersError; } return nil; } - if(self.currentSelfPeersError) { - ckkserror("ckksshare", self, "Couldn't create missing shares because self peers aren't available: %@", self.currentSelfPeersError); + if(trustState.currentSelfPeersError) { + ckkserror("ckksshare", self, "Couldn't create missing shares because self peers aren't available: %@", trustState.currentSelfPeersError); if(error) { - *error = self.currentSelfPeersError; + *error = trustState.currentSelfPeersError; } return nil; } - NSSet>* remainingPeers = [self _onqueueFindPeersMissingShare:key error:error]; - NSMutableSet* newShares = [NSMutableSet set]; + NSSet>* remainingPeers = [self _onqueueFindPeers:trustState missingShare:key afterUploading:nil error:error]; + NSMutableSet* newShares = [NSMutableSet set]; if(!remainingPeers) { return nil; @@ -1444,9 +1820,9 @@ } // Create a share for this peer. - ckksnotice("ckksshare", self, "Creating share of %@ as %@ for %@", key, self.currentSelfPeers.currentSelf, peer); - CKKSTLKShare* newShare = [CKKSTLKShare share:key - as:self.currentSelfPeers.currentSelf + ckksnotice("ckksshare", self, "Creating share of %@ as %@ for %@", key, trustState.currentSelfPeers.currentSelf, peer); + CKKSTLKShareRecord* newShare = [CKKSTLKShareRecord share:key + as:trustState.currentSelfPeers.currentSelf to:peer epoch:-1 poisoned:0 @@ -1469,6 +1845,11 @@ - (CKKSZoneKeyState*)_onqueueEnsureKeyHierarchyHealth:(CKKSCurrentKeySet*)set error:(NSError* __autoreleasing *)error { dispatch_assert_queue(self.queue); + if(!set.currentTLKPointer && !set.currentClassAPointer && !set.currentClassCPointer) { + ckkserror("ckkskey", self, "Error examining existing key hierarchy (missing all CKPs, likely no hierarchy exists): %@", set); + return SecCKKSZoneKeyStateWaitForTLKCreation; + } + // Check keyset if(!set.tlk || !set.classA || !set.classC) { ckkserror("ckkskey", self, "Error examining existing key hierarchy (missing at least one key): %@", set); @@ -1548,32 +1929,62 @@ self.activeTLK = [set.tlk uuid]; // Now that we're pretty sure we have the keys, are they shared appropriately? + // We need trust in order to proceed here + if(self.currentTrustStates.count == 0u) { + ckkserror("ckkskey", self, "Can't check TLKShares due to missing trust states"); + return SecCKKSZoneKeyStateWaitForTrust; + } + // Check that every trusted peer has at least one TLK share - NSSet>* missingShares = [self _onqueueFindPeersMissingShare:set.tlk error:&localerror]; - if(localerror && [self.lockStateTracker isLockedError: localerror]) { - ckkserror("ckkskey", self, "Couldn't find missing TLK shares due to lock state: %@", localerror); - probablyOkIfUnlocked = true; - } else if([localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoPeersAvailable) { - ckkserror("ckkskey", self, "Couldn't find missing TLK shares due to missing peers, likely due to lock state: %@", localerror); - probablyOkIfUnlocked = true; + // If any trust state check works, don't error out + bool anyTrustStateSucceeded = false; + for(CKKSPeerProviderState* trustState in self.currentTrustStates) { + NSSet>* missingShares = [self _onqueueFindPeers:trustState missingShare:set.tlk afterUploading:nil error:&localerror]; + if(localerror && [self.lockStateTracker isLockedError: localerror]) { + ckkserror("ckkskey", self, "Couldn't find missing TLK shares due to lock state: %@", localerror); + probablyOkIfUnlocked = true; + + } else if(([localerror.domain isEqualToString:TrustedPeersHelperErrorDomain] && localerror.code == TrustedPeersHelperErrorNoPreparedIdentity) || + ([localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSLackingTrust) || + ([localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoPeersAvailable)) { + ckkserror("ckkskey", self, "Couldn't find missing TLK shares due some trust issue: %@", localerror); + + if(trustState.essential) { + ckkserror("ckkskey", self, "Trust state is considered essential; entering waitfortrust: %@", trustState); + + // Octagon can reinform us when it thinks we should start again + self.trustStatus = CKKSAccountStatusUnknown; + return SecCKKSZoneKeyStateWaitForTrust; + } else { + ckkserror("ckkskey", self, "Peer provider is considered nonessential; ignoring error: %@", trustState); + continue; + } - } else if(localerror) { - if(error) { - *error = localerror; + } else if(localerror) { + ckkserror("ckkskey", self, "Error finding missing TLK shares: %@", localerror); + continue; } - ckkserror("ckkskey", self, "Error finding missing TLK shares: %@", localerror); - return SecCKKSZoneKeyStateError; + + if(!missingShares || missingShares.count != 0u) { + localerror = [NSError errorWithDomain:CKKSErrorDomain code:CKKSMissingTLKShare + description:[NSString stringWithFormat:@"Missing shares for %lu peers", (unsigned long)missingShares.count]]; + if(error) { + *error = localerror; + } + return SecCKKSZoneKeyStateHealTLKShares; + } else { + ckksnotice("ckksshare", self, "TLK (%@) is shared correctly for trust state %@", set.tlk, trustState.peerProviderID); + } + + anyTrustStateSucceeded |= true; } - if(!missingShares || missingShares.count != 0u) { - localerror = [NSError errorWithDomain:CKKSErrorDomain code:CKKSMissingTLKShare - description:[NSString stringWithFormat:@"Missing shares for %lu peers", (unsigned long)missingShares.count]]; + if(!anyTrustStateSucceeded) { if(error) { *error = localerror; } - return SecCKKSZoneKeyStateHealTLKShares; - } else { - ckksnotice("ckksshare", self, "TLK (%@) is shared correctly", set.tlk); + + return SecCKKSZoneKeyStateError; } // Got to the bottom? Cool! All keys are present and accounted for. @@ -1583,16 +1994,17 @@ - (void)_onqueueKeyHierarchyFetch { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); self.keyStateMachineOperation = [NSBlockOperation blockOperationWithBlock: ^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); + STRONGIFY(self); + if(!self) { + ckkserror("ckks", self, "received callback for released object"); return; } + [self.launch addEvent:@"fetch-complete"]; - [strongSelf dispatchSyncWithAccountKeys: ^bool{ - [strongSelf _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateFetchComplete withError: nil]; + [self dispatchSyncWithAccountKeys: ^bool{ + [self _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateFetchComplete withError: nil]; return true; }]; }]; @@ -1607,16 +2019,16 @@ - (void)_onqueueKeyHierarchyRefetch { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); self.keyStateMachineOperation = [NSBlockOperation blockOperationWithBlock: ^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); + STRONGIFY(self); + if(!self) { + ckkserror("ckks", self, "received callback for released object"); return; } - [strongSelf dispatchSyncWithAccountKeys: ^bool{ - [strongSelf _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateFetchComplete withError: nil]; + [self dispatchSyncWithAccountKeys: ^bool{ + [self _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateFetchComplete withError: nil]; return true; }]; }]; @@ -1672,6 +2084,14 @@ return; } + // It's possible to ask for an item to be deleted without adding a corresponding tombstone. + // This is arguably a bug, as it generates an out-of-sync state, but it is in the API contract. + // CKKS should ignore these, but log very upset messages. + if(isDelete && !addedTombstone) { + ckksnotice("ckks", self, "Client has asked for an item deletion to not sync. Keychain is now out of sync with account"); + return; + } + // Only synchronize items which can transfer between devices NSString* protection = (__bridge NSString*)SecDbItemGetCachedValueWithName(added ? added : deleted, kSecAttrAccessible); if(! ([protection isEqualToString: (__bridge NSString*)kSecAttrAccessibleWhenUnlocked] || @@ -1690,6 +2110,7 @@ if(self.accountStatus == CKKSAccountStatusNoAccount) { // No account; CKKS shouldn't attempt anything. self.droppedItems = true; + ckksnotice("ckks", self, "Dropping sync item modification due to CK account state; will scan to find changes later"); if(syncCallback) { // We're positively not logged into CloudKit, and therefore don't expect this item to be synced anytime particularly soon. @@ -1829,14 +2250,14 @@ hash:oldItemSHA1 ckoperationGroup:[CKOperationGroup CKKSGroupWithName:@"currentitem-api"]]; - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* returnCallback = [CKKSResultOperation operationWithBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); if(ucipo.error) { - ckkserror("ckkscurrent", strongSelf, "Failed setting a current item pointer for %@ with %@", ucipo.currentPointerIdentifier, ucipo.error); + ckkserror("ckkscurrent", self, "Failed setting a current item pointer for %@ with %@", ucipo.currentPointerIdentifier, ucipo.error); } else { - ckksnotice("ckkscurrent", strongSelf, "Finished setting a current item pointer for %@", ucipo.currentPointerIdentifier); + ckksnotice("ckkscurrent", self, "Finished setting a current item pointer for %@", ucipo.currentPointerIdentifier); } complete(ucipo.error); }]; @@ -1885,7 +2306,7 @@ fetchAndProcess = [self fetchAndProcessCKChanges:CKKSFetchBecauseCurrentItemFetchRequest]; } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* getCurrentItem = [CKKSResultOperation named:@"get-current-item-pointer" withBlock:^{ if(fetchAndProcess.error) { ckksnotice("ckkscurrent", self, "Rejecting current item pointer get since fetch failed: %@", fetchAndProcess.error); @@ -1893,31 +2314,31 @@ return; } - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); - [strongSelf dispatchSync: ^bool { + [self dispatchSync: ^bool { NSError* error = nil; NSString* currentIdentifier = [NSString stringWithFormat:@"%@-%@", accessGroup, identifier]; CKKSCurrentItemPointer* cip = [CKKSCurrentItemPointer fromDatabase:currentIdentifier state:SecCKKSProcessedStateLocal - zoneID:strongSelf.zoneID + zoneID:self.zoneID error:&error]; if(!cip || error) { - ckkserror("ckkscurrent", strongSelf, "No current item pointer for %@", currentIdentifier); + ckkserror("ckkscurrent", self, "No current item pointer for %@", currentIdentifier); complete(nil, error); return false; } if(!cip.currentItemUUID) { - ckkserror("ckkscurrent", strongSelf, "Current item pointer is empty %@", cip); + ckkserror("ckkscurrent", self, "Current item pointer is empty %@", cip); complete(nil, [NSError errorWithDomain:CKKSErrorDomain code:errSecInternalError description:@"Current item pointer is empty"]); return false; } - ckksinfo("ckkscurrent", strongSelf, "Retrieved current item pointer: %@", cip); + ckksinfo("ckkscurrent", self, "Retrieved current item pointer: %@", cip); complete(cip.currentItemUUID, NULL); return true; }]; @@ -1972,6 +2393,90 @@ return key; } +- (CKKSResultOperation*)findKeySet +{ + __block CKKSResultOperation* keysetOp = nil; + + [self dispatchSyncWithAccountKeys:^bool { + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:self.zoneID]; + if(keyset.currentTLKPointer.currentKeyUUID && keyset.tlk.uuid) { + ckksnotice("ckks", self, "Already have keyset %@", keyset); + + keysetOp = [[CKKSProvideKeySetOperation alloc] initWithZoneName:self.zoneName keySet:keyset]; + [self scheduleOperationWithoutDependencies:keysetOp]; + return true; + } else if([self.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKUpload]) { + CKKSCurrentKeySet* proposedKeySet = self.lastNewTLKOperation.keyset; + ckksnotice("ckks", self, "Already have proposed keyset %@", proposedKeySet); + + keysetOp = [[CKKSProvideKeySetOperation alloc] initWithZoneName:self.zoneName keySet:proposedKeySet]; + [self scheduleOperationWithoutDependencies:keysetOp]; + return true; + } else { + // No existing keyset (including keys) exists. + // The state machine will know what to do! + self.tlkCreationRequested = true; + + ckksnotice("ckks", self, "Received a keyset request; forwarding to state machine"); + + keysetOp = (CKKSProvideKeySetOperation*) [self findFirstPendingOperation:self.keysetProviderOperations]; + if(!keysetOp) { + keysetOp = [[CKKSProvideKeySetOperation alloc] initWithZoneName:self.zoneName]; + [self.keysetProviderOperations addObject:keysetOp]; + + // This is an abuse of operations: they should generally run when added to a queue, not wait, but this allows recipients to set timeouts + [self scheduleOperationWithoutDependencies:keysetOp]; + } + + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + } + + return true; + }]; + + return keysetOp; +} + +- (void)_onqueueRunKeysetProviderOperations:(CKKSCurrentKeySet*)keyset +{ + ckksnotice("ckkskey", self, "Providing keyset (%@) to listeners", keyset); + + // We have some keyset; they can ask again if they want a new one + self.tlkCreationRequested = false; + + for(CKKSResultOperation* op in self.keysetProviderOperations) { + if([op isPending]) { + [op provideKeySet:keyset]; + } + } +} + +- (void)receiveTLKUploadRecords:(NSArray*)records +{ + // First, filter for records matching this zone + NSMutableArray* zoneRecords = [NSMutableArray array]; + for(CKRecord* record in records) { + if([record.recordID.zoneID isEqual:self.zoneID]) { + [zoneRecords addObject:record]; + } + } + + ckksnotice("ckkskey", self, "Received a set of %lu TLK upload records", (unsigned long)zoneRecords.count); + + if(!zoneRecords || zoneRecords.count == 0) { + return; + } + + [self dispatchSyncWithAccountKeys:^bool { + + for(CKRecord* record in zoneRecords) { + [self _onqueueCKRecordChanged:record resync:false]; + } + + return true; + }]; +} + // Use the following method to find the first pending operation in a weak collection - (NSOperation*)findFirstPendingOperation: (NSHashTable*) table { return [self findFirstPendingOperation:table ofClass:nil]; @@ -2002,11 +2507,23 @@ } } +- (NSSet*)_onqueuePriorityOutgoingQueueUUIDs +{ + return [self.pendingSyncCallbacks.allKeys copy]; +} + - (CKKSOutgoingQueueOperation*)processOutgoingQueue:(CKOperationGroup*)ckoperationGroup { return [self processOutgoingQueueAfter:nil ckoperationGroup:ckoperationGroup]; } - (CKKSOutgoingQueueOperation*)processOutgoingQueueAfter:(CKKSResultOperation*)after ckoperationGroup:(CKOperationGroup*)ckoperationGroup { + return [self processOutgoingQueueAfter:after requiredDelay:DISPATCH_TIME_FOREVER ckoperationGroup:ckoperationGroup]; +} + +- (CKKSOutgoingQueueOperation*)processOutgoingQueueAfter:(CKKSResultOperation*)after + requiredDelay:(uint64_t)requiredDelay + ckoperationGroup:(CKOperationGroup*)ckoperationGroup +{ CKKSOutgoingQueueOperation* outgoingop = (CKKSOutgoingQueueOperation*) [self findFirstPendingOperation:self.outgoingQueueOperations ofClass:[CKKSOutgoingQueueOperation class]]; @@ -2025,7 +2542,7 @@ ckksnotice("ckksoutgoing", self, "Returning existing %@", outgoingop); // Shouldn't be necessary, but can't hurt - [self.outgoingQueueOperationScheduler trigger]; + [self.outgoingQueueOperationScheduler triggerAt:requiredDelay]; return outgoingop; } } @@ -2034,7 +2551,8 @@ op.name = @"outgoing-queue-operation"; [op addNullableDependency:after]; [op addNullableDependency:self.outgoingQueueOperationScheduler.operationDependency]; - [self.outgoingQueueOperationScheduler trigger]; + + [self.outgoingQueueOperationScheduler triggerAt:requiredDelay]; [self scheduleOperation: op]; ckksnotice("ckksoutgoing", self, "Scheduled %@", op); @@ -2044,12 +2562,12 @@ - (void)processIncomingQueueAfterNextUnlock { // Thread races aren't so important here; we might end up with two or three copies of this operation, but that's okay. if(![self.processIncomingQueueAfterNextUnlockOperation isPending]) { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* restartIncomingQueueOperation = [CKKSResultOperation operationWithBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); // This IQO shouldn't error if the keybag has locked again. It will simply try again later. - [strongSelf processIncomingQueue:false]; + [self processIncomingQueue:false]; }]; restartIncomingQueueOperation.name = @"reprocess-incoming-queue-after-unlock"; @@ -2125,12 +2643,12 @@ waitForKeyHierarchyInitialization:(uint64_t)timeout ckoperationGroup:(CKOperationGroup*)ckoperationGroup { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // If securityd just started, the key state might be in some transient early state. Wait a bit. CKKSResultOperation* waitForKeyReady = [CKKSResultOperation named:@"device-state-wait" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - ckksnotice("ckksdevice", strongSelf, "Finished waiting for key hierarchy transient state, currently %@", strongSelf.keyHierarchyState); + STRONGIFY(self); + ckksnotice("ckksdevice", self, "Finished waiting for key hierarchy transient state, currently %@", self.keyHierarchyState); }]; [waitForKeyReady addNullableDependency:self.keyStateNonTransientDependency]; @@ -2157,11 +2675,15 @@ - (CKKSDeviceStateEntry*)_onqueueCurrentDeviceStateEntry: (NSError* __autoreleasing*)error { NSError* localerror = nil; - CKKSCKAccountStateTracker* accountTracker = self.accountTracker; + CKKSAccountStateTracker* accountTracker = self.accountTracker; + CKKSAccountStatus hsa2Status = accountTracker.hsa2iCloudAccountStatus; - // We must have an iCloud account (with d2de on) to even create one of these - if(accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable || accountTracker.currentCKAccountInfo.supportsDeviceToDeviceEncryption != YES) { - ckkserror("ckksdevice", self, "No iCloud account active: %@", accountTracker.currentCKAccountInfo); + // We must have an HSA2 iCloud account and a CloudKit account to even create one of these + if(hsa2Status != CKKSAccountStatusAvailable || + accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable) { + ckkserror("ckksdevice", self, "No iCloud account active: %@ hsa2 account:%@", + accountTracker.currentCKAccountInfo, + CKKSAccountStatusToString(hsa2Status)); localerror = [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No active HSA2 iCloud account: %@", accountTracker.currentCKAccountInfo]}]; @@ -2171,7 +2693,19 @@ return nil; } - CKKSDeviceStateEntry* oldcdse = [CKKSDeviceStateEntry tryFromDatabase:accountTracker.ckdeviceID zoneID:self.zoneID error:&localerror]; + NSString* ckdeviceID = accountTracker.ckdeviceID; + if(ckdeviceID == nil) { + ckkserror("ckksdevice", self, "No CK device ID available; cannot make device state entry"); + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNotLoggedIn + userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"No CK device ID: %@", accountTracker.currentCKAccountInfo]}]; + if(error) { + *error = localerror; + } + return nil; + } + + CKKSDeviceStateEntry* oldcdse = [CKKSDeviceStateEntry tryFromDatabase:ckdeviceID zoneID:self.zoneID error:&localerror]; if(localerror) { ckkserror("ckksdevice", self, "Couldn't read old CKKSDeviceStateEntry from database: %@", localerror); if(error) { @@ -2227,8 +2761,14 @@ } // We'd like to have the circle peer ID. Give the account state tracker a fighting chance, but not having it is not an error - if([accountTracker.accountCirclePeerIDInitialized wait:500*NSEC_PER_MSEC] != 0 && !accountTracker.accountCirclePeerID) { - ckkserror("ckksdevice", self, "No peer ID available"); + // But, if the platform doesn't have SOS, don't bother + if(OctagonPlatformSupportsSOS() && [accountTracker.accountCirclePeerIDInitialized wait:500*NSEC_PER_MSEC] != 0 && !accountTracker.accountCirclePeerID) { + ckkserror("ckksdevice", self, "No SOS peer ID available"); + } + + // We'd also like the Octagon status + if([accountTracker.octagonInformationInitialized wait:500*NSEC_PER_MSEC] != 0 && !accountTracker.octagonPeerID) { + ckkserror("ckksdevice", self, "No octagon peer ID available"); } // Reset the last unlock time to 'day' granularity in UTC @@ -2238,11 +2778,11 @@ lastUnlockDay = lastUnlockDay ? [calendar startOfDayForDate:lastUnlockDay] : nil; // We only really want the oldcdse for its encodedCKRecord, so make a new cdse here - CKKSDeviceStateEntry* newcdse = [[CKKSDeviceStateEntry alloc] initForDevice:accountTracker.ckdeviceID + CKKSDeviceStateEntry* newcdse = [[CKKSDeviceStateEntry alloc] initForDevice:ckdeviceID osVersion:SecCKKSHostOSVersion() lastUnlockTime:lastUnlockDay - octagonPeerID:nil - octagonStatus:nil + octagonPeerID:accountTracker.octagonPeerID + octagonStatus:accountTracker.octagonStatus circlePeerID:accountTracker.accountCirclePeerID circleStatus:accountTracker.currentCircleStatus.status keyState:self.keyHierarchyState @@ -2407,7 +2947,7 @@ } else if([recordType isEqual: SecCKRecordTLKShareType]) { NSError* error = nil; ckksinfo("ckks", self, "CloudKit notification: deleted tlk share record(%@): %@", recordType, recordID); - CKKSTLKShare* share = [CKKSTLKShare tryFromDatabaseFromCKRecordID:recordID error:&error]; + CKKSTLKShareRecord* share = [CKKSTLKShareRecord tryFromDatabaseFromCKRecordID:recordID error:&error]; [share deleteFromDatabase:&error]; if(error) { @@ -2634,7 +3174,7 @@ } // CKKSTLKShares get saved with no modification - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; [share saveToDatabase:&error]; if(error) { ckkserror("ckksshare", self, "Couldn't save new TLK share to database: %@ %@", share, error); @@ -2893,16 +3433,21 @@ NSError* localerror = nil; if(![proposedTLK wrapsSelf]) { - ckkserror("ckksshare", self, "Potential TLK %@ does not wrap self; skipping TLK share checking", proposedTLK); + localerror = [NSError errorWithDomain:CKKSErrorDomain code:CKKSKeyNotSelfWrapped description:[NSString stringWithFormat:@"Potential TLK %@ doesn't wrap itself: %@", proposedTLK, proposedTLK.parentKeyUUID] underlying:NULL]; + ckkserror("ckksshare", self, "%@", localerror); + if (error) { + *error = localerror; + } } else { bool tlkShares = [self _onqueueWithAccountKeysCheckTLKFromShares:proposedTLK error:&localerror]; // We only want to error out if a positive error occurred. "No shares" is okay. if(!tlkShares || localerror) { bool noTrustedTLKShares = [localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoTrustedTLKShares; bool noSelfPeer = [localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSNoEncryptionKey; + bool noTrust = [localerror.domain isEqualToString:CKKSErrorDomain] && localerror.code == CKKSLackingTrust; // If this error was something worse than 'couldn't unwrap for reasons including there not being data', report it - if(!(noTrustedTLKShares || noSelfPeer)) { + if(!(noTrustedTLKShares || noSelfPeer || noTrust)) { if(error) { *error = localerror; } @@ -2924,38 +3469,75 @@ // This version only examines if this TLK is recoverable from TLK shares - (bool)_onqueueWithAccountKeysCheckTLKFromShares:(CKKSKey*)proposedTLK error:(NSError* __autoreleasing *)error { + // But being recoverable from any trust set is okay + NSError* localerror = nil; + + if(self.currentTrustStates.count == 0u) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSLackingTrust + description:@"No current trust states; can't check TLK"]; + } + return false; + } + + for(CKKSPeerProviderState* trustState in self.currentTrustStates) { + ckkserror("ckksshare", self, "Checking TLK from trust state %@", trustState); + bool recovered = [self _onqueueWithAccountKeysWithPeers:trustState + checkTLK:proposedTLK + error:&localerror]; + + if(recovered) { + ckkserror("ckksshare", self, "Recovered the TLK"); + return true; + } + + ckkserror("ckksshare", self, "Unable to recover TLK from trust set: %@", localerror); + } + + // Only report the last error + if(error && localerror) { + *error = localerror; + } + return false; +} + +- (bool)_onqueueWithAccountKeysWithPeers:(CKKSPeerProviderState*)trustState + checkTLK:(CKKSKey*)proposedTLK + error:(NSError* __autoreleasing *)error +{ NSError* localerror = NULL; - if(!self.currentSelfPeers.currentSelf || self.currentSelfPeersError) { - ckkserror("ckksshare", self, "Couldn't fetch self peers: %@", self.currentSelfPeersError); + if(!trustState.currentSelfPeers.currentSelf || trustState.currentSelfPeersError) { + ckkserror("ckksshare", self, "Don't have self peers for %@: %@", trustState.peerProviderID, trustState.currentSelfPeersError); if(error) { - if([self.lockStateTracker isLockedError:self.currentSelfPeersError]) { + if([self.lockStateTracker isLockedError:trustState.currentSelfPeersError]) { // Locked error should propagate - *error = self.currentSelfPeersError; + *error = trustState.currentSelfPeersError; } else { *error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSNoEncryptionKey description:@"No current self peer" - underlying:self.currentSelfPeersError]; + underlying:trustState.currentSelfPeersError]; } } return false; } - if(!self.currentTrustedPeers || self.currentTrustedPeersError) { - ckkserror("ckksshare", self, "Couldn't fetch trusted peers: %@", self.currentTrustedPeersError); + if(!trustState.currentTrustedPeers || trustState.currentTrustedPeersError) { + ckkserror("ckksshare", self, "Don't have trusted peers: %@", trustState.currentTrustedPeersError); if(error) { *error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSNoPeersAvailable description:@"No trusted peers" - underlying:self.currentTrustedPeersError]; + underlying:trustState.currentTrustedPeersError]; } return false; } NSError* lastShareError = nil; - for(id selfPeer in self.currentSelfPeers.allSelves) { - NSArray* possibleShares = [CKKSTLKShare allFor:selfPeer.peerID + for(id selfPeer in trustState.currentSelfPeers.allSelves) { + NSArray* possibleShares = [CKKSTLKShareRecord allFor:selfPeer.peerID keyUUID:proposedTLK.uuid zoneID:self.zoneID error:&localerror]; @@ -2968,18 +3550,18 @@ continue; } - for(CKKSTLKShare* possibleShare in possibleShares) { + for(CKKSTLKShareRecord* possibleShare in possibleShares) { NSError* possibleShareError = nil; ckksnotice("ckksshare", self, "Checking possible TLK share %@ as %@", possibleShare, selfPeer); CKKSKey* possibleKey = [possibleShare recoverTLK:selfPeer - trustedPeers:self.currentTrustedPeers + trustedPeers:trustState.currentTrustedPeers error:&possibleShareError]; if(possibleShareError) { ckkserror("ckksshare", self, "Unable to unwrap TLKShare(%@) as %@: %@", possibleShare, selfPeer, possibleShareError); - ckkserror("ckksshare", self, "Current trust set: %@", self.currentTrustedPeers); + ckkserror("ckksshare", self, "Current trust set: %@", trustState.currentTrustedPeers); lastShareError = possibleShareError; continue; } @@ -2987,7 +3569,7 @@ bool result = [proposedTLK trySelfWrappedKeyCandidate:possibleKey.aessivkey error:&possibleShareError]; if(possibleShareError) { ckkserror("ckksshare", self, "Unwrapped TLKShare(%@) does not unwrap proposed TLK(%@) as %@: %@", - possibleShare, proposedTLK, self.currentSelfPeers.currentSelf, possibleShareError); + possibleShare, proposedTLK, trustState.currentSelfPeers.currentSelf, possibleShareError); lastShareError = possibleShareError; continue; } @@ -3059,20 +3641,40 @@ } - (void)dispatchSyncWithAccountKeys:(bool (^)(void))block +{ + [self dispatchSyncWithPeerProviders:self.currentPeerProviders override:false block:block]; +} + +- (void)dispatchSyncWithPeerProviders:(NSArray>*)peerProviders + override:(bool)overridePeerProviders + block:(bool (^)(void))block { [SOSAccount performOnQuietAccountQueue: ^{ - NSError* selfPeersError = nil; - CKKSSelves* currentSelfPeers = [self.currentPeerProvider fetchSelfPeers:&selfPeersError]; + NSArray>* actualPeerProviders = overridePeerProviders ? peerProviders : self.currentPeerProviders; + NSMutableArray* trustStates = [NSMutableArray array]; - NSError* trustedPeersError = nil; - NSSet>* currentTrustedPeers = [self.currentPeerProvider fetchTrustedPeers:&trustedPeersError]; + for(id provider in actualPeerProviders) { + ckksnotice("ckks", self, "Fetching account keys for provider %@", provider); - [self dispatchSync:^bool{ - self.currentSelfPeers = currentSelfPeers; - self.currentSelfPeersError = selfPeersError; + NSError* selfPeersError = nil; + CKKSSelves* currentSelfPeers = [provider fetchSelfPeers:&selfPeersError]; + + NSError* trustedPeersError = nil; + NSSet>* currentTrustedPeers = [provider fetchTrustedPeers:&trustedPeersError]; + + [trustStates addObject:[[CKKSPeerProviderState alloc] initWithPeerProviderID:provider.providerID + essential:provider.essential + selfPeers:currentSelfPeers + selfPeersError:selfPeersError + trustedPeers:currentTrustedPeers + trustedPeersError:trustedPeersError]]; + } - self.currentTrustedPeers = currentTrustedPeers; - self.currentTrustedPeersError = trustedPeersError; + [self dispatchSync:^bool{ + if(overridePeerProviders) { + self.currentPeerProviders = peerProviders; + } + self.currentTrustStates = trustStates; __block bool result = false; [SOSAccount performWhileHoldingAccountQueue:^{ // so any calls through SOS account will know they can perform their work without dispatching to the account queue, which we already hold @@ -3080,10 +3682,12 @@ }]; // Forget the peers; they might have class A key material - self.currentSelfPeers = nil; - self.currentSelfPeersError = [NSError errorWithDomain:CKKSErrorDomain code:CKKSNoPeersAvailable description:@"No current self peer available"]; - self.currentTrustedPeers = nil; - self.currentTrustedPeersError = [NSError errorWithDomain:CKKSErrorDomain code:CKKSNoPeersAvailable description:@"No current trusted peers available"]; + NSMutableArray* noTrustStates = [NSMutableArray array]; + for(id provider in peerProviders) { + (void)provider; + [noTrustStates addObject:[CKKSPeerProviderState noPeersState:provider]]; + } + self.currentTrustStates = noTrustStates; return result; }]; @@ -3109,22 +3713,22 @@ return; } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* login = [CKKSResultOperation named:@"ckks-login" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; + STRONGIFY(self); - [strongSelf dispatchSyncWithAccountKeys:^bool{ - [strongSelf superHandleCKLogin]; + [self dispatchSyncWithAccountKeys:^bool{ + [self superHandleCKLogin]; // Reset key hierarchy state machine to initializing - [strongSelf _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitializing withError:nil]; + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitializing withError:nil]; return true; }]; // Change our condition variables to reflect that we think we're logged in - strongSelf.loggedOut = [[CKKSCondition alloc] initToChain:strongSelf.loggedOut]; - [strongSelf.loggedIn fulfill]; - [strongSelf.accountStateKnown fulfill]; + self.loggedOut = [[CKKSCondition alloc] initToChain:self.loggedOut]; + [self.loggedIn fulfill]; + [self.accountStateKnown fulfill]; }]; [self scheduleAccountStatusOperation:login]; @@ -3135,32 +3739,32 @@ } - (void)handleCKLogout { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* logout = [CKKSResultOperation named:@"ckks-logout" withBlock: ^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { return; } - [strongSelf dispatchSync:^bool { - ckksnotice("ckks", strongSelf, "received a notification of CK logout"); - [strongSelf superHandleCKLogout]; + [self dispatchSync:^bool { + ckksnotice("ckks", self, "received a notification of CK logout"); + [self superHandleCKLogout]; NSError* error = nil; - [strongSelf _onqueueResetLocalData: &error]; + [self _onqueueResetLocalData: &error]; if(error) { - ckkserror("ckks", strongSelf, "error while resetting local data: %@", error); + ckkserror("ckks", self, "error while resetting local data: %@", error); } [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateLoggedOut withError:nil]; - strongSelf.loggedIn = [[CKKSCondition alloc] initToChain: strongSelf.loggedIn]; - [strongSelf.loggedOut fulfill]; - [strongSelf.accountStateKnown fulfill]; + self.loggedIn = [[CKKSCondition alloc] initToChain: self.loggedIn]; + [self.loggedOut fulfill]; + [self.accountStateKnown fulfill]; // Tell all pending sync clients that we don't expect to ever sync - for(NSString* callbackUUID in strongSelf.pendingSyncCallbacks.allKeys) { - [strongSelf callSyncCallbackWithErrorNoAccount:strongSelf.pendingSyncCallbacks[callbackUUID]]; - strongSelf.pendingSyncCallbacks[callbackUUID] = nil; + for(NSString* callbackUUID in self.pendingSyncCallbacks.allKeys) { + [self callSyncCallbackWithErrorNoAccount:self.pendingSyncCallbacks[callbackUUID]]; + self.pendingSyncCallbacks[callbackUUID] = nil; } return true; @@ -3180,6 +3784,65 @@ }); } +#pragma mark - Trust operations + +- (void)beginTrustedOperation:(NSArray>*)peerProviders + suggestTLKUpload:(CKKSNearFutureScheduler*)suggestTLKUpload +{ + for(id peerProvider in peerProviders) { + [peerProvider registerForPeerChangeUpdates:self]; + } + + [self.launch addEvent:@"beginTrusted"]; + + [self dispatchSyncWithPeerProviders:peerProviders override:true block:^bool { + ckksnotice("ckkstrust", self, "Beginning trusted operation"); + CKKSAccountStatus oldTrustStatus = self.trustStatus; + + self.suggestTLKUpload = suggestTLKUpload; + + self.trustStatus = CKKSAccountStatusAvailable; + if(self.trustDependency) { + [self scheduleOperation: self.trustDependency]; + self.trustDependency = nil; + } + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + + if(oldTrustStatus == CKKSAccountStatusNoAccount) { + ckksnotice("ckkstrust", self, "Moving from an untrusted status; we need to process incoming queue and scan for any new items"); + + // Next, try to process them (replacing local entries) + CKKSIncomingQueueOperation* initialProcess = [self processIncomingQueue:true after:nil]; + initialProcess.name = @"initial-process-incoming-queue"; + + // If all that succeeds, iterate through all keychain items and find the ones which need to be uploaded + self.initialScanOperation = [self scanLocalItems:@"newly-trusted-scan" + ckoperationGroup:nil + after:initialProcess]; + } + + return true; + }]; +} + +- (void)endTrustedOperation +{ + [self.launch addEvent:@"endTrusted"]; + + [self dispatchSyncWithPeerProviders:nil override:true block:^bool { + ckksnotice("ckkstrust", self, "Ending trusted operation"); + + self.suggestTLKUpload = nil; + + self.trustStatus = CKKSAccountStatusNoAccount; + if(!self.trustDependency) { + self.trustDependency = [CKKSResultOperation named:@"wait-for-trust" withBlock:^{}]; + } + [self _onqueueAdvanceKeyStateMachineToState:nil withError:nil]; + return true; + }]; +} + #pragma mark - CKKSChangeFetcherClient - (CKKSCloudKitFetchRequest*)participateInFetch @@ -3199,6 +3862,7 @@ } request.participateInFetch = true; + [self.launch addEvent:@"fetch"]; if([self.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateNeedFullRefetch]) { // We want to return a nil change tag (to force a resync) @@ -3215,6 +3879,10 @@ return true; }]; + if (request.changeToken == nil) { + self.launch.firstLaunch = true; + } + return request; } @@ -3223,6 +3891,8 @@ oldChangeToken:(CKServerChangeToken*)oldChangeToken newChangeToken:(CKServerChangeToken*)newChangeToken { + [self.launch addEvent:@"changes-fetched"]; + [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]; @@ -3290,77 +3960,72 @@ }]; } -// 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; - - bool isChangeTokenExpiredError = false; - if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorChangeTokenExpired)) { - isChangeTokenExpiredError = true; - } else if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) { +- (bool)ckErrorOrPartialError:(NSError *)error isError:(CKErrorCode)errorCode +{ + if((error.code == errorCode) && [error.domain isEqualToString:CKErrorDomain]) { + return true; + } else if((error.code == CKErrorPartialFailure) && [error.domain isEqualToString:CKErrorDomain]) { NSDictionary* partialErrors = error.userInfo[CKPartialErrorsByItemIDKey]; - for(CKRecordZoneID* zoneID in partialErrors) { - NSError* partialError = partialErrors[zoneID]; - if([zoneID isEqual:self.zoneID] && [partialError.domain isEqualToString:CKErrorDomain] && (partialError.code == CKErrorChangeTokenExpired)) { - isChangeTokenExpiredError = true; - } + + NSError* partialError = partialErrors[self.zoneID]; + if ((partialError.code == errorCode) && [partialError.domain isEqualToString:CKErrorDomain]) { + return true; } } + return false; +} + +- (bool)shouldRetryAfterFetchError:(NSError*)error { + bool isChangeTokenExpiredError = [self ckErrorOrPartialError:error isError:CKErrorChangeTokenExpired]; if(isChangeTokenExpiredError) { 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; - if(!strongSelf) { - ckkserror("ckks", strongSelf, "received callback for released object"); - return; - } - if(resetOp.error) { - ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended with error: %@", strongSelf.zoneID, error); + // This is a bit scary: we might confuse some poor key hierarchy state machine operation. But, if a key state machine + // operation is waiting for a successful fetch, we need to do this reset + [self dispatchSyncWithAccountKeys:^bool{ + NSError* error = nil; + [self _onqueueResetLocalData:&error]; + + if(error) { + ckksnotice("ckksreset", self, "CloudKit-inspired local reset of %@ ended with error: %@", self.zoneID, error); } else { - ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended successfully", strongSelf.zoneID); + ckksnotice("ckksreset", self, "CloudKit-inspired local reset of %@ ended successfully", self.zoneID); } - }]; - [resetHandler addDependency:resetOp]; - [self scheduleOperation:resetHandler]; - return false; - } - - bool isDeletedZoneError = false; - if([error.domain isEqualToString:CKErrorDomain] && ((error.code == CKErrorUserDeletedZone) || (error.code == CKErrorZoneNotFound))) { - isDeletedZoneError = true; - } else if([error.domain isEqualToString:CKErrorDomain] && (error.code == CKErrorPartialFailure)) { - NSDictionary* partialErrors = error.userInfo[CKPartialErrorsByItemIDKey]; - 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 we're in the middle of a fetch for the key state, then the retried fetch (which should succeed) will be sufficient to progress + // Otherwise, we need to poke the key hierarchy state machine: all of its data is gone + if(![self.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateFetch]) { + [self _onqueueKeyStateMachineRequestFetch]; } - } + + return true; + }]; + + return true; } + bool isDeletedZoneError = [self ckErrorOrPartialError:error isError:CKErrorZoneNotFound]; if(isDeletedZoneError) { 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; - if(!strongSelf) { - ckkserror("ckksreset", strongSelf, "received callback for released object"); - return; - } - if(resetOp.error) { - ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended with error: %@", strongSelf.zoneID, resetOp.error); + /* + * If someone delete our zone, lets just start over from the begining + */ + [self dispatchSync: ^bool{ + NSError* resetError = nil; + + [self _onqueueResetLocalData: &resetError]; + if(resetError) { + ckksnotice("ckksreset", self, "CloudKit-inspired local reset of %@ ended with error: %@", self.zoneID, resetError); } else { - ckksnotice("ckksreset", strongSelf, "CloudKit-inspired local reset of %@ ended successfully", strongSelf.zoneID); + ckksnotice("ckksreset", self, "CloudKit-inspired local reset of %@ ended successfully", self.zoneID); } + + [self _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateInitializing withError:nil]; + return true; }]; - [resetHandler addDependency:resetOp]; - [self scheduleOperation:resetHandler]; return false; } @@ -3374,13 +4039,15 @@ #pragma mark CKKSPeerUpdateListener -- (void)selfPeerChanged { +- (void)selfPeerChanged:(id)provider +{ // Currently, we have no idea what to do with this. Kick off a key reprocess? ckkserror("ckks", self, "Received update that our self identity has changed"); [self keyStateMachineRequestProcess]; } -- (void)trustedPeerSetChanged { +- (void)trustedPeerSetChanged:(id)provider +{ // 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"); @@ -3467,7 +4134,7 @@ manifest = [CKKSManifest latestTrustedManifestForZone:self.zoneName error:&error]; [self dispatchSync: ^bool { - CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] initForZone:self.zoneID]; + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:self.zoneID]; if(keyset.error) { error = keyset.error; } @@ -3487,7 +4154,7 @@ [mutDeviceStates addObject: [obj description]]; }]; - NSArray* tlkShares = [CKKSTLKShare allForUUID:keyset.currentTLKPointer.currentKeyUUID zoneID:self.zoneID error:&error]; + NSArray* tlkShares = [CKKSTLKShareRecord allForUUID:keyset.currentTLKPointer.currentKeyUUID zoneID:self.zoneID error:&error]; NSMutableArray* mutTLKShares = [[NSMutableArray alloc] init]; [tlkShares enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { [mutTLKShares addObject: [obj description]]; @@ -3526,17 +4193,16 @@ self.accountStatus == CKAccountStatusAvailable ? @"logged in" : self.accountStatus == CKAccountStatusRestricted ? @"restricted" : self.accountStatus == CKAccountStatusNoAccount ? @"logged out" : @"unknown", - @"lockstatetracker": stringify(self.lockStateTracker), @"accounttracker": stringify(self.accountTracker), @"fetcher": stringify(self.zoneChangeFetcher), @"zoneCreated": boolstr(self.zoneCreated), @"zoneCreatedError": stringify(self.zoneCreatedError), @"zoneSubscribed": boolstr(self.zoneSubscribed), @"zoneSubscribedError": stringify(self.zoneSubscribedError), - @"zoneInitializeScheduler": stringify(self.initializeScheduler), @"keystate": CKKSNilToNSNull(self.keyHierarchyState), @"keyStateError": stringify(self.keyHierarchyError), @"statusError": [NSNull null], + @"launchSequence": CKKSNilToNSNull([self.launch eventsByTime]), @"zoneSetupOperation": stringify(self.zoneSetupOperation), @"keyStateOperation": stringify(self.keyStateMachineOperation), diff --git a/keychain/ckks/CKKSListenerCollection.h b/keychain/ckks/CKKSListenerCollection.h new file mode 100644 index 00000000..5e98b2a1 --- /dev/null +++ b/keychain/ckks/CKKSListenerCollection.h @@ -0,0 +1,19 @@ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/* + * This class holds a set of weak pointers to 'listener' objects, and offers the chance to dispatch updates + * to them on each listener's own serial dispatch queue + */ + +@interface CKKSListenerCollection<__covariant ListenerType> : NSObject +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithName:(NSString*)name; + +- (void)registerListener:(ListenerType)listener; +- (void)iterateListeners:(void (^)(ListenerType))block; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/CKKSListenerCollection.m b/keychain/ckks/CKKSListenerCollection.m new file mode 100644 index 00000000..a19ad8c7 --- /dev/null +++ b/keychain/ckks/CKKSListenerCollection.m @@ -0,0 +1,75 @@ + +#if OCTAGON + +#import "keychain/ckks/CKKSListenerCollection.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface CKKSListenerCollection () +@property NSString* name; +@property NSMapTable* listeners; +@end + +@implementation CKKSListenerCollection + +- (instancetype)initWithName:(NSString*)name +{ + if((self = [super init])) { + _name = name; + // Backwards from how we'd like, but it's the best way to have weak pointers to ListenerTypes. + _listeners = [NSMapTable strongToWeakObjectsMapTable]; + } + return self; +} + +- (NSString*)description +{ + @synchronized(self.listeners) { + return [NSString stringWithFormat:@"", self.name, [[self.listeners objectEnumerator] allObjects]]; + } +} + +- (void)registerListener:(id)listener +{ + @synchronized(self.listeners) { + bool alreadyRegisteredListener = false; + NSEnumerator *enumerator = [self.listeners objectEnumerator]; + id value; + + while ((value = [enumerator nextObject])) { + // actually use pointer comparison + alreadyRegisteredListener |= (value == listener); + } + + if(listener && !alreadyRegisteredListener) { + NSString* queueName = [NSString stringWithFormat: @"%@-%@", self.name, listener]; + + dispatch_queue_t objQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + [self.listeners setObject: listener forKey: objQueue]; + } + } +} + +- (void)iterateListeners:(void (^)(id))block +{ + @synchronized(self.listeners) { + NSEnumerator *enumerator = [self.listeners keyEnumerator]; + dispatch_queue_t dq; + + // Queue up the changes for each listener. + while ((dq = [enumerator nextObject])) { + id listener = [self.listeners objectForKey: dq]; + WEAKIFY(listener); + + if(listener) { + dispatch_async(dq, ^{ + STRONGIFY(listener); + block(listener); + }); + } + } + } +} + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSLocalSynchronizeOperation.h b/keychain/ckks/CKKSLocalSynchronizeOperation.h index 65e3d559..027fa524 100644 --- a/keychain/ckks/CKKSLocalSynchronizeOperation.h +++ b/keychain/ckks/CKKSLocalSynchronizeOperation.h @@ -25,6 +25,7 @@ #import "keychain/ckks/CKKSGroupOperation.h" #if OCTAGON +NS_ASSUME_NONNULL_BEGIN @class CKKSKeychainView; @@ -43,5 +44,6 @@ - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks; @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSLocalSynchronizeOperation.m b/keychain/ckks/CKKSLocalSynchronizeOperation.m index ef73c11f..fe5c09d0 100644 --- a/keychain/ckks/CKKSLocalSynchronizeOperation.m +++ b/keychain/ckks/CKKSLocalSynchronizeOperation.m @@ -30,6 +30,7 @@ #import "keychain/ckks/CKKSIncomingQueueEntry.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" #if OCTAGON @@ -54,7 +55,7 @@ } - (void)groupStart { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); /* * A local synchronize is very similar to a CloudKit synchronize, but it won't cause any (non-essential) @@ -119,8 +120,8 @@ CKKSResultOperation* restart = [[CKKSResultOperation alloc] init]; restart.name = [NSString stringWithFormat: @"resync-step%u-consider-restart", self.restartCount * steps + 6]; [restart addExecutionBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckksresync: received callback for released object"); return; } @@ -132,17 +133,17 @@ } if(scan.recordsFound > 0 || iqes.count > 0) { - if(strongSelf.restartCount >= 3) { + if(self.restartCount >= 3) { // we've restarted too many times. Fail and stop. ckkserror("ckksresync", ckks, "restarted synchronization too often; Failing"); - strongSelf.error = [NSError errorWithDomain:@"securityd" + self.error = [NSError errorWithDomain:@"securityd" code:2 userInfo:@{NSLocalizedDescriptionKey: @"resynchronization restarted too many times; churn in database?"}]; } else { // restart the sync operation. - strongSelf.restartCount += 1; + self.restartCount += 1; ckkserror("ckksresync", ckks, "restarting synchronization operation due to new local items"); - [strongSelf groupStart]; + [self groupStart]; } } }]; diff --git a/keychain/ckks/CKKSLockStateTracker.h b/keychain/ckks/CKKSLockStateTracker.h index 502ac6f6..7e64f2f5 100644 --- a/keychain/ckks/CKKSLockStateTracker.h +++ b/keychain/ckks/CKKSLockStateTracker.h @@ -49,6 +49,9 @@ NS_ASSUME_NONNULL_BEGIN // Ask AKS if the user's keybag is locked + (bool)queryAKSLocked; + +// Call this to get a CKKSLockStateTracker to use. This tracker will likely be tracking real AKS. ++ (CKKSLockStateTracker*)globalTracker; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/CKKSLockStateTracker.m b/keychain/ckks/CKKSLockStateTracker.m index 8502be87..46e6cb2a 100644 --- a/keychain/ckks/CKKSLockStateTracker.m +++ b/keychain/ckks/CKKSLockStateTracker.m @@ -31,12 +31,14 @@ #import "keychain/ckks/CKKSResultOperation.h" #import "keychain/ckks/CKKSGroupOperation.h" #import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ot/ObjCImprovements.h" @interface CKKSLockStateTracker () -@property (readwrite) bool isLocked; +@property bool queueIsLocked; @property dispatch_queue_t queue; @property NSOperationQueue* operationQueue; @property NSHashTable> *observers; +@property (assign) int notify_token; @property (nullable) NSDate* lastUnlockedTime; @@ -49,32 +51,49 @@ _queue = dispatch_queue_create("lock-state-tracker", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _operationQueue = [[NSOperationQueue alloc] init]; - _isLocked = true; + _notify_token = NOTIFY_TOKEN_INVALID; + _queueIsLocked = true; _observers = [NSHashTable weakObjectsHashTable]; [self resetUnlockDependency]; - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // If this is a live server, register with notify if(!SecCKKSTestsEnabled()) { - int token = 0; - notify_register_dispatch(kUserKeybagStateChangeNotification, &token, _queue, ^(int t) { - [weakSelf _onqueueRecheck]; + notify_register_dispatch(kUserKeybagStateChangeNotification, &_notify_token, _queue, ^(int t) { + STRONGIFY(self); + [self _onqueueRecheck]; }); } dispatch_async(_queue, ^{ - [weakSelf _onqueueRecheck]; + STRONGIFY(self); + [self _onqueueRecheck]; }); } return self; } +- (void)dealloc { + if (_notify_token != NOTIFY_TOKEN_INVALID) { + notify_cancel(_notify_token); + } +} + +- (bool)isLocked { + // if checking close after launch ``isLocked'' needs to be blocked on the initial fetch operation + __block bool locked; + dispatch_sync(_queue, ^{ + locked = self->_queueIsLocked; + }); + return locked; +} + - (NSDate*)lastUnlockTime { // If unlocked, the last unlock time is now. Otherwise, used the cached value. __block NSDate* date = nil; dispatch_sync(self.queue, ^{ - if(self.isLocked) { + if(self.queueIsLocked) { date = self.lastUnlockedTime; } else { date = [NSDate date]; @@ -85,9 +104,10 @@ } -(NSString*)description { + bool isLocked = self.isLocked; return [NSString stringWithFormat: @"", - self.isLocked ? @"locked" : @"unlocked", - self.isLocked ? self.lastUnlockedTime : @"now"]; + isLocked ? @"locked" : @"unlocked", + isLocked ? self.lastUnlockedTime : @"now"]; } -(void)resetUnlockDependency { @@ -116,12 +136,12 @@ dispatch_assert_queue(self.queue); static bool first = true; - bool wasLocked = self.isLocked; - self.isLocked = [CKKSLockStateTracker queryAKSLocked]; + bool wasLocked = self.queueIsLocked; + self.queueIsLocked = [CKKSLockStateTracker queryAKSLocked]; - if(wasLocked != self.isLocked || first) { + if(wasLocked != self.queueIsLocked || first) { first = false; - if(self.isLocked) { + if(self.queueIsLocked) { // We're locked now. [self resetUnlockDependency]; @@ -134,11 +154,12 @@ self.lastUnlockedTime = [NSDate date]; } - bool isUnlocked = (self.isLocked == false); + bool isUnlocked = (self.queueIsLocked == false); for (id observer in _observers) { __strong typeof(observer) strongObserver = observer; - if (strongObserver == NULL) + if (strongObserver == nil) { return; + } dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ [strongObserver lockStateChangeNotification:isUnlocked]; }); @@ -153,21 +174,47 @@ } -(bool)isLockedError:(NSError *)error { - return ([error.domain isEqualToString:@"securityd"] || [error.domain isEqualToString:(__bridge NSString*)kSecErrorDomain]) - && error.code == errSecInteractionNotAllowed; + bool isLockedError = error.code == errSecInteractionNotAllowed && + ([error.domain isEqualToString:@"securityd"] || [error.domain isEqualToString:(__bridge NSString*)kSecErrorDomain]); + + /* + * If we are locked, and the the current lock state track disagree, lets double check + * if we are actually locked since we might have missed a lock state notification, + * and cause spinning to happen. + * + * We don't update the local variable, since the error code was a locked error. + */ + if (isLockedError) { + dispatch_sync(self.queue, ^{ + if (self.queueIsLocked == false) { + [self _onqueueRecheck]; + } + }); + } + return isLockedError; } -(void)addLockStateObserver:(id)object { dispatch_async(self.queue, ^{ [self->_observers addObject:object]; - bool isUnlocked = (self.isLocked == false); + bool isUnlocked = (self.queueIsLocked == false); dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ [object lockStateChangeNotification:isUnlocked]; }); }); } ++ (CKKSLockStateTracker*)globalTracker +{ + static CKKSLockStateTracker* tracker; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + tracker = [[CKKSLockStateTracker alloc] init]; + }); + return tracker; +} + @end diff --git a/keychain/ckks/CKKSManifest.m b/keychain/ckks/CKKSManifest.m index 3e8bd659..38ab0eb5 100644 --- a/keychain/ckks/CKKSManifest.m +++ b/keychain/ckks/CKKSManifest.m @@ -53,6 +53,8 @@ static NSString* const CKKSManifestEC384SignatureKey = @"CKKSManifestEC384Signat static NSString* const CKKSManifestErrorDomain = @"CKKSManifestErrorDomain"; +static NSString* const manifestRecordNameDelimiter = @":-:"; + #define NUM_MANIFEST_LEAF_RECORDS 72 #define BITS_PER_UUID_CHAR 36 @@ -393,49 +395,47 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) return [[self alloc] initWithDigestValue:pendingManifest.digestValue zone:pendingManifest.zoneName generationCount:pendingManifest.generationCount leafRecordIDs:pendingManifest.committedLeafRecordIDs peerManifestIDs:pendingManifest.peerManifestIDs currentItems:pendingManifest.currentItems futureData:pendingManifest.futureData signatures:pendingManifest.signatures signerID:pendingManifest.signerID schema:pendingManifest.schema encodedRecord:pendingManifest.encodedCKRecord]; } -+ (instancetype)fromDatabaseRow:(NSDictionary*)row ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { - NSString* digestBase64String = row[@"digest"]; - NSData* digest = [digestBase64String isKindOfClass:[NSString class]] ? [[NSData alloc] initWithBase64EncodedString:digestBase64String options:0] : nil; + NSData* digest = row[@"digest"].asBase64DecodedData; - NSString* zone = row[@"ckzone"]; - NSUInteger generationCount = [row[@"gencount"] integerValue]; - NSString* signerID = row[@"signerID"]; + NSString* zone = row[@"ckzone"].asString; + NSUInteger generationCount = row[@"gencount"].asNSInteger; + NSString* signerID = row[@"signerID"].asString; - NSString* encodedRecordBase64String = row[@"ckrecord"]; - NSData* encodedRecord = [encodedRecordBase64String isKindOfClass:[NSString class]] ? [[NSData alloc] initWithBase64EncodedString:encodedRecordBase64String options:0] : nil; + NSData* encodedRecord = row[@"ckrecord"].asBase64DecodedData; - NSData* leafRecordIDData = [[NSData alloc] initWithBase64EncodedString:row[@"leafIDs"] options:0]; + NSData* leafRecordIDData = row[@"leafIDs"].asBase64DecodedData; NSArray* leafRecordIDs = (__bridge_transfer NSArray*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)leafRecordIDData, 0, NULL, NULL); if (![leafRecordIDs isKindOfClass:[NSArray class]]) { leafRecordIDs = [NSArray array]; } - NSData* peerManifestIDData = [[NSData alloc] initWithBase64EncodedString:row[@"peerManifests"] options:0]; + NSData* peerManifestIDData = row[@"peerManifests"].asBase64DecodedData; NSArray* peerManifestIDs = (__bridge_transfer NSArray*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)peerManifestIDData, 0, NULL, NULL); if (![peerManifestIDs isKindOfClass:[NSArray class]]) { peerManifestIDs = [NSArray array]; } - NSData* currentItemsData = [[NSData alloc] initWithBase64EncodedString:row[@"currentItems"] options:0]; + NSData* currentItemsData = row[@"currentItems"].asBase64DecodedData; NSDictionary* currentItemsDict = (__bridge_transfer NSDictionary*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)currentItemsData, 0, NULL, NULL); if (![currentItemsDict isKindOfClass:[NSDictionary class]]) { currentItemsDict = [NSDictionary dictionary]; } - NSData* futureData = [[NSData alloc] initWithBase64EncodedString:row[@"futureData"] options:0]; + NSData* futureData = row[@"futureData"].asBase64DecodedData; NSDictionary* futureDataDict = (__bridge_transfer NSDictionary*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)futureData, 0, NULL, NULL); if (![futureDataDict isKindOfClass:[NSDictionary class]]) { futureDataDict = [NSDictionary dictionary]; } - NSData* signaturesData = [[NSData alloc] initWithBase64EncodedString:row[@"signatures"] options:0]; + NSData* signaturesData = row[@"signatures"].asBase64DecodedData; NSDictionary* signatures = (__bridge_transfer NSDictionary*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)signaturesData, 0, NULL, NULL); if (![signatures isKindOfClass:[NSDictionary class]]) { signatures = [NSDictionary dictionary]; } - NSData* schemaData = [[NSData alloc] initWithBase64EncodedString:row[@"schema"] options:0]; + NSData* schemaData = row[@"schema"].asBase64DecodedData; NSDictionary* schemaDict = (__bridge_transfer NSDictionary*)CFPropertyListCreateWithDERData(NULL, (__bridge CFDataRef)schemaData, 0, NULL, NULL); if (![schemaDict isKindOfClass:[NSDictionary class]]) { schemaDict = __thisBuildsSchema; @@ -457,8 +457,8 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) + (NSUInteger)greatestKnownGenerationCount { __block NSUInteger result = 0; - [self queryMaxValueForField:@"gencount" inTable:self.sqlTable where:nil columns:@[@"gencount"] processRow:^(NSDictionary* row) { - result = [row[@"gencount"] integerValue]; + [self queryMaxValueForField:@"gencount" inTable:self.sqlTable where:nil columns:@[@"gencount"] processRow:^(NSDictionary* row) { + result = row[@"gencount"].asNSInteger; }]; [CKKSPendingManifest queryMaxValueForField:@"gencount" inTable:[CKKSPendingManifest sqlTable] where:nil columns:@[@"gencount"] processRow:^(NSDictionary* row) { @@ -470,6 +470,16 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) - (instancetype)initWithDigestValue:(NSData*)digestValue zone:(NSString*)zone generationCount:(NSUInteger)generationCount leafRecordIDs:(NSArray*)leafRecordIDs peerManifestIDs:(NSArray*)peerManifestIDs currentItems:(NSDictionary*)currentItems futureData:(NSDictionary*)futureData signatures:(NSDictionary*)signatures signerID:(NSString*)signerID schema:(NSDictionary*)schema helper:(CKKSManifestInjectionPointHelper*)helper { + if ([zone containsString:manifestRecordNameDelimiter]) { + secerror("zone contains delimiter: %@", zone); + return nil; + } + if ([signerID containsString:manifestRecordNameDelimiter]) { + secerror("signerID contains delimiter: %@", signerID); + return nil; + } + + if (self = [super init]) { _digestValue = digestValue; _zoneName = zone; @@ -708,12 +718,15 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) - (NSString*)CKRecordName { - return [NSString stringWithFormat:@"Manifest:-:%@:-:%@:-:%lu", _zoneName, _signerID, (unsigned long)_generationCount]; + return [NSString stringWithFormat:@"Manifest%@%@%@%@%@%lu", + manifestRecordNameDelimiter, _zoneName, + manifestRecordNameDelimiter, _signerID, + manifestRecordNameDelimiter, (unsigned long)_generationCount]; } + (NSDictionary*)whereClauseForRecordName:(NSString*)recordName { - NSArray* components = [recordName componentsSeparatedByString:@":-:"]; + NSArray* components = [recordName componentsSeparatedByString:manifestRecordNameDelimiter]; if (components.count < 4) { secerror("CKKSManifest: could not parse components from record name: %@", recordName); } @@ -726,7 +739,10 @@ static NSUInteger LeafBucketIndexForUUID(NSString* uuid) - (CKRecord*)updateCKRecord:(CKRecord*)record zoneID:(CKRecordZoneID*)zoneID { if (![record.recordType isEqualToString:SecCKRecordManifestType]) { - @throw [NSException exceptionWithName:@"WrongCKRecordTypeException" reason:[NSString stringWithFormat:@"CKRecorType (%@) was not %@", record.recordType, SecCKRecordManifestType] userInfo:nil]; + @throw [NSException + exceptionWithName:@"WrongCKRecordTypeException" + reason:[NSString stringWithFormat:@"CKRecordType (%@) was not %@", record.recordType, SecCKRecordManifestType] + userInfo:nil]; } NSData* signatureDERData = [self derDataFromSignatureDict:self.signatures error:nil]; diff --git a/keychain/ckks/CKKSManifestLeafRecord.m b/keychain/ckks/CKKSManifestLeafRecord.m index ac39b869..a35b519b 100644 --- a/keychain/ckks/CKKSManifestLeafRecord.m +++ b/keychain/ckks/CKKSManifestLeafRecord.m @@ -30,6 +30,8 @@ #import #import +static NSString * const manifestLeafRecordNameDelimiter = @":-:"; + @interface CKKSManifestLeafRecord () { NSString* _uuid; NSMutableDictionary* _recordDigestDict; @@ -79,7 +81,7 @@ static NSDictionary* RecordDigestDictFromDER(NSData* data, NSError** error) + (NSString*)leafUUIDForRecordID:(NSString*)recordID { - NSArray* components = [recordID componentsSeparatedByString:@":-:"]; + NSArray* components = [recordID componentsSeparatedByString:manifestLeafRecordNameDelimiter]; return components.count > 1 ? components[1] : recordID; } @@ -99,19 +101,16 @@ static NSDictionary* RecordDigestDictFromDER(NSData* data, NSError** error) return [[self alloc] initWithUUID:pendingRecord.uuid digest:pendingRecord.digestValue recordDigestDict:pendingRecord.recordDigestDict zone:pendingRecord.zoneName encodedRecord:pendingRecord.encodedCKRecord]; } -+ (instancetype)fromDatabaseRow:(NSDictionary*)row ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { - NSString* zone = row[@"ckzone"]; - NSString* uuid = row[@"UUID"]; - - NSString* digestBase64String = row[@"digest"]; - NSData* digest = [digestBase64String isKindOfClass:[NSString class]] ? [[NSData alloc] initWithBase64EncodedString:digestBase64String options:0] : nil; + NSString* zone = row[@"ckzone"].asString; + NSString* uuid = row[@"UUID"].asString; - NSString* encodedRecordBase64String = row[@"ckrecord"]; - NSData* encodedRecord = [encodedRecordBase64String isKindOfClass:[NSString class]] ? [[NSData alloc] initWithBase64EncodedString:encodedRecordBase64String options:0] : nil; + NSData* digest = row[@"digest"].asBase64DecodedData; - NSString* entryDigestBase64String = row[@"entryDigests"]; - NSData* entryDigestData = [entryDigestBase64String isKindOfClass:[NSString class]] ? [[NSData alloc] initWithBase64EncodedString:row[@"entryDigests"] options:0] : nil; + NSData* encodedRecord = row[@"ckrecord"].asBase64DecodedData; + + NSData* entryDigestData = row[@"entryDigests"].asBase64DecodedData; NSDictionary* entryDigestsDict = entryDigestData ? RecordDigestDictFromDER(entryDigestData, nil) : @{}; return [[self alloc] initWithUUID:uuid digest:digest recordDigestDict:entryDigestsDict zone:zone encodedRecord:encodedRecord]; @@ -148,6 +147,11 @@ static NSDictionary* RecordDigestDictFromDER(NSData* data, NSError** error) - (instancetype)initWithUUID:(NSString*)uuid digest:(NSData*)digest recordDigestDict:(NSDictionary*)recordDigestDict zone:(NSString*)zone { + if ([uuid containsString:manifestLeafRecordNameDelimiter]) { + secerror("uuid contains delimiter: %@", uuid); + return nil; + } + if (self = [super init]) { _uuid = uuid; _digestValue = digest; @@ -196,7 +200,8 @@ static NSDictionary* RecordDigestDictFromDER(NSData* data, NSError** error) - (NSString*)CKRecordName { - return [NSString stringWithFormat:@"ManifestLeafRecord:-:%@", _uuid]; + return [NSString stringWithFormat:@"ManifestLeafRecord%@%@", + manifestLeafRecordNameDelimiter, _uuid]; } - (NSString*)ckRecordType diff --git a/keychain/ckks/CKKSMirrorEntry.h b/keychain/ckks/CKKSMirrorEntry.h index 3b2a8dc1..dcaf1fbe 100644 --- a/keychain/ckks/CKKSMirrorEntry.h +++ b/keychain/ckks/CKKSMirrorEntry.h @@ -33,6 +33,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + @class CKKSWrappedAESSIVKey; @interface CKKSMirrorEntry : CKKSSQLDatabaseObject @@ -51,8 +53,10 @@ + (instancetype)tryFromDatabase:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; + (NSDictionary*)countsByParentKey:(CKRecordZoneID*)zoneID error:(NSError* __autoreleasing*)error; ++ (NSNumber*)counts:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error; @end +NS_ASSUME_NONNULL_END #endif #endif /* CKKSOutgoingQueueEntry_h */ diff --git a/keychain/ckks/CKKSMirrorEntry.m b/keychain/ckks/CKKSMirrorEntry.m index 6a4e4ec7..e77c3043 100644 --- a/keychain/ckks/CKKSMirrorEntry.m +++ b/keychain/ckks/CKKSMirrorEntry.m @@ -119,17 +119,17 @@ return [self.item whereClauseToFindSelf]; } -- (NSDictionary*)sqlValues { +- (NSDictionary*)sqlValues { NSMutableDictionary* values = [[self.item sqlValues] mutableCopy]; - values[@"wascurrent"] = [NSNumber numberWithUnsignedLongLong:self.wasCurrent]; + values[@"wascurrent"] = [[NSNumber numberWithUnsignedLongLong:self.wasCurrent] stringValue]; return values; } -+ (instancetype) fromDatabaseRow: (NSDictionary*) row { ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { CKKSMirrorEntry* ckme = [[CKKSMirrorEntry alloc] initWithCKKSItem: [CKKSItem fromDatabaseRow:row]]; // This appears to be the best way to get an unsigned long long out of a string. - ckme.wasCurrent = [[[[NSNumberFormatter alloc] init] numberFromString:CKKSNSNullToNil(row[@"wascurrent"])] unsignedLongLongValue]; + ckme.wasCurrent = [[[[NSNumberFormatter alloc] init] numberFromString:row[@"wascurrent"].asString] unsignedLongLongValue]; return ckme; } @@ -142,13 +142,30 @@ groupBy: @[@"parentKeyUUID"] orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[row[@"parentKeyUUID"]] = [NSNumber numberWithInteger: [row[@"count(rowid)"] integerValue]]; + processRow: ^(NSDictionary* row) { + results[row[@"parentKeyUUID"].asString] = row[@"count(rowid)"].asNSNumberInteger; } error: error]; return results; } ++ (NSNumber*)counts:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { + __block NSNumber *result = nil; + + [CKKSSQLDatabaseObject queryDatabaseTable: [[self class] sqlTable] + where: @{@"ckzone": CKKSNilToNSNull(zoneID.zoneName)} + columns: @[@"count(rowid)"] + groupBy:nil + orderBy:nil + limit: -1 + processRow: ^(NSDictionary* row) { + result = row[@"count(rowid)"].asNSNumberInteger; + } + error: error]; + return result; + +} + @end diff --git a/keychain/ckks/CKKSNearFutureScheduler.h b/keychain/ckks/CKKSNearFutureScheduler.h index 166830bf..44c3e9c3 100644 --- a/keychain/ckks/CKKSNearFutureScheduler.h +++ b/keychain/ckks/CKKSNearFutureScheduler.h @@ -53,7 +53,7 @@ NS_ASSUME_NONNULL_BEGIN delay:(dispatch_time_t)ns keepProcessAlive:(bool)keepProcessAlive dependencyDescriptionCode:(NSInteger)code - block:(void (^_Nonnull)(void))futureOperation; + block:(void (^_Nonnull)(void))futureBlock; - (instancetype)initWithName:(NSString*)name initialDelay:(dispatch_time_t)initialDelay @@ -69,6 +69,9 @@ NS_ASSUME_NONNULL_BEGIN // Don't trigger again until at least this much time has passed. - (void)waitUntil:(uint64_t)delay; +// Trigger at this time (unless further instructions are given) +- (void)triggerAt:(uint64_t)delay; + - (void)changeDelays:(dispatch_time_t)initialDelay continuingDelay:(dispatch_time_t)continuingDelay; @end diff --git a/keychain/ckks/CKKSNearFutureScheduler.m b/keychain/ckks/CKKSNearFutureScheduler.m index d562e058..2b3fb6b0 100644 --- a/keychain/ckks/CKKSNearFutureScheduler.m +++ b/keychain/ckks/CKKSNearFutureScheduler.m @@ -27,6 +27,7 @@ #import "CKKSCondition.h" #import "keychain/ckks/NSOperationCategories.h" #import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ot/ObjCImprovements.h" #include @interface CKKSNearFutureScheduler () @@ -131,7 +132,17 @@ -(void)waitUntil:(uint64_t)delay { dispatch_sync(self.queue, ^{ - [self _onqueueTrigger:delay]; + [self _onqueueTrigger:delay maximumDelay:DISPATCH_TIME_FOREVER]; + }); +} + +- (void)triggerAt:(uint64_t)delay { + WEAKIFY(self); + dispatch_async(self.queue, ^{ + STRONGIFY(self); + self.liveRequest = true; + [self.liveRequestReceived fulfill]; + [self _onqueueTrigger:(delay == DISPATCH_TIME_FOREVER ? DISPATCH_TIME_NOW : delay) maximumDelay:delay]; }); } @@ -159,26 +170,27 @@ } -(void)trigger { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); dispatch_async(self.queue, ^{ + STRONGIFY(self); // The timer tick should call the block! self.liveRequest = true; [self.liveRequestReceived fulfill]; - [weakSelf _onqueueTrigger:DISPATCH_TIME_NOW]; + [self _onqueueTrigger:DISPATCH_TIME_NOW maximumDelay:DISPATCH_TIME_FOREVER]; }); } --(void)_onqueueTrigger:(dispatch_time_t)requestedDelay { +-(void)_onqueueTrigger:(dispatch_time_t)requestedDelay maximumDelay:(dispatch_time_t)maximumDelay { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // If we don't have one already, set up an os_transaction if(self.keepProcessAlive && self.transaction == nil) { self.transaction = os_transaction_create([[NSString stringWithFormat:@"com.apple.securityd.%@",self.name] UTF8String]); } - if(requestedDelay != DISPATCH_TIME_NOW) { + if(requestedDelay != DISPATCH_TIME_NOW && self.predictedNextFireTime != nil) { NSDate* delayTime = [NSDate dateWithTimeIntervalSinceNow: (NSTimeInterval) ((double) requestedDelay) / (double) NSEC_PER_SEC]; if([delayTime compare:self.predictedNextFireTime] != NSOrderedDescending) { // The next fire time is after this delay. Do nothing with the request. @@ -189,6 +201,17 @@ } } + if(maximumDelay != DISPATCH_TIME_FOREVER && self.predictedNextFireTime != nil) { + NSDate* delayTime = [NSDate dateWithTimeIntervalSinceNow: (NSTimeInterval) ((double) requestedDelay) / (double) NSEC_PER_SEC]; + if([delayTime compare:self.predictedNextFireTime] != NSOrderedDescending) { + // Need to cancel the timer and reset it below. + dispatch_source_cancel(self.timer); + self.predictedNextFireTime = nil; + } else { + // The next fire time is before the maximum delay. Do nothing with the request. + } + } + // Check if the timer is alive if(self.timer != nil && 0 == dispatch_source_testcancel(self.timer)) { // timer is alive, do nothing @@ -199,10 +222,17 @@ (dispatch_source_timer_flags_t)0, self.queue); dispatch_source_set_event_handler(self.timer, ^{ - [weakSelf _onqueueTimerTick]; + STRONGIFY(self); + [self _onqueueTimerTick]; }); - dispatch_time_t actualDelay = self.initialDelay > requestedDelay ? self.initialDelay : requestedDelay; + dispatch_time_t actualDelay = self.initialDelay; + if(requestedDelay != DISPATCH_TIME_NOW) { + actualDelay = MAX(actualDelay, requestedDelay); + } + if(maximumDelay != DISPATCH_TIME_FOREVER) { + actualDelay = MIN(actualDelay, maximumDelay); + } dispatch_source_set_timer(self.timer, dispatch_walltime(NULL, actualDelay), @@ -216,9 +246,9 @@ -(void)cancel { dispatch_sync(self.queue, ^{ - if(self.timer != nil && 0 == dispatch_source_testcancel(self.timer)) { - dispatch_source_cancel(self.timer); - } + if(self.timer != nil && 0 == dispatch_source_testcancel(self.timer)) { + dispatch_source_cancel(self.timer); + } }); } diff --git a/keychain/ckks/CKKSNewTLKOperation.h b/keychain/ckks/CKKSNewTLKOperation.h index f75052e7..fb831ffe 100644 --- a/keychain/ckks/CKKSNewTLKOperation.h +++ b/keychain/ckks/CKKSNewTLKOperation.h @@ -21,14 +21,17 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import #import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ckks/CKKSProvideKeySetOperation.h" -#if OCTAGON +NS_ASSUME_NONNULL_BEGIN @class CKKSKeychainView; -@interface CKKSNewTLKOperation : CKKSGroupOperation +@interface CKKSNewTLKOperation : CKKSGroupOperation @property (weak) CKKSKeychainView* ckks; - (instancetype)init NS_UNAVAILABLE; @@ -36,4 +39,6 @@ @end +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSNewTLKOperation.m b/keychain/ckks/CKKSNewTLKOperation.m index 4d35f5a1..2cc46843 100644 --- a/keychain/ckks/CKKSNewTLKOperation.m +++ b/keychain/ckks/CKKSNewTLKOperation.m @@ -32,14 +32,17 @@ #if OCTAGON -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" @interface CKKSNewTLKOperation () @property NSBlockOperation* cloudkitModifyOperationFinished; @property CKOperationGroup* ckoperationGroup; + +@property (nullable) CKKSCurrentKeySet* keyset; @end @implementation CKKSNewTLKOperation +@synthesize keyset; - (instancetype)init { return nil; @@ -67,8 +70,6 @@ * items as if a different peer uploaded them). */ - __weak __typeof(self) weakSelf = self; - CKKSKeychainView* ckks = self.ckks; if(self.cancelled) { @@ -90,29 +91,6 @@ ckks.lastNewTLKOperation = self; - if(ckks.currentSelfPeersError) { - if([ckks.lockStateTracker isLockedError: ckks.currentSelfPeersError]) { - ckkserror("ckksshare", ckks, "Can't create new TLKs: keychain is locked so self peers are unavailable: %@", ckks.currentSelfPeersError); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:nil]; - } else { - ckkserror("ckkstlk", ckks, "Couldn't create new TLKs because self peers aren't available: %@", ckks.currentSelfPeersError); - [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateNewTLKsFailed withError: ckks.currentSelfPeersError]; - } - self.error = ckks.currentSelfPeersError; - return false; - } - if(ckks.currentTrustedPeersError) { - if([ckks.lockStateTracker isLockedError: ckks.currentTrustedPeersError]) { - ckkserror("ckksshare", ckks, "Can't create new TLKs: keychain is locked so trusted peers are unavailable: %@", ckks.currentTrustedPeersError); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:nil]; - } else { - ckkserror("ckkstlk", ckks, "Couldn't create new TLKs because trusted peers aren't available: %@", ckks.currentTrustedPeersError); - [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateNewTLKsFailed withError: ckks.currentTrustedPeersError]; - } - self.error = ckks.currentTrustedPeersError; - return false; - } - NSError* error = nil; ckksinfo("ckkstlk", ckks, "Generating new TLK"); @@ -125,9 +103,6 @@ CKKSKey* newClassCKey = nil; CKKSKey* wrappedOldTLK = nil; - NSMutableArray* recordsToSave = [[NSMutableArray alloc] init]; - NSMutableArray* recordIDsToDelete = [[NSMutableArray alloc] init]; - // Now, prepare data for the operation: // We must find the current TLK (to wrap it to the new TLK). @@ -154,7 +129,14 @@ // / | \ // oldTLK classA classC - newTLK = [[CKKSKey alloc] initSelfWrappedWithAESKey:[CKKSAESSIVKey randomKey] + CKKSAESSIVKey* newAESKey = [CKKSAESSIVKey randomKey:&error]; + if(error) { + ckkserror("ckkstlk", ckks, "Couldn't create new TLK: %@", error); + self.error = error; + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:error]; + return false; + } + newTLK = [[CKKSKey alloc] initSelfWrappedWithAESKey:newAESKey uuid:[[NSUUID UUID] UUIDString] keyclass:SecCKKSKeyClassTLK state:SecCKKSProcessedStateLocal @@ -204,20 +186,24 @@ wrappedOldTLK.currentkey = false; } - [recordsToSave addObject: [newTLK CKRecordWithZoneID: ckks.zoneID]]; - [recordsToSave addObject: [newClassAKey CKRecordWithZoneID: ckks.zoneID]]; - [recordsToSave addObject: [newClassCKey CKRecordWithZoneID: ckks.zoneID]]; + CKKSCurrentKeySet* keyset = [[CKKSCurrentKeySet alloc] init]; + + keyset.tlk = newTLK; + keyset.classA = newClassAKey; + keyset.classC = newClassCKey; + + keyset.currentTLKPointer = currentTLKPointer; + keyset.currentClassAPointer = currentClassAPointer; + keyset.currentClassCPointer = currentClassCPointer; - [recordsToSave addObject: [currentTLKPointer CKRecordWithZoneID: ckks.zoneID]]; - [recordsToSave addObject: [currentClassAPointer CKRecordWithZoneID: ckks.zoneID]]; - [recordsToSave addObject: [currentClassCPointer CKRecordWithZoneID: ckks.zoneID]]; + keyset.proposed = YES; if(wrappedOldTLK) { - [recordsToSave addObject: [wrappedOldTLK CKRecordWithZoneID: ckks.zoneID]]; + // TODO o no } // Save the proposed keys to the keychain. Note that we might reject this TLK later, but in that case, this TLK is just orphaned. No worries! - ckksnotice("ckkstlk", ckks, "Saving new keys %@ to database %@", recordsToSave, ckks.database); + ckksnotice("ckkstlk", ckks, "Saving new keys %@ to keychain", keyset); [newTLK saveKeyMaterialToKeychain: &error]; [newClassAKey saveKeyMaterialToKeychain: &error]; @@ -230,158 +216,43 @@ } // Generate the TLK sharing records for all trusted peers - NSMutableSet* tlkShares = [NSMutableSet set]; - for(id trustedPeer in ckks.currentTrustedPeers) { - if(!trustedPeer.publicEncryptionKey) { - ckksnotice("ckkstlk", ckks, "No need to make TLK for %@; they don't have any encryption keys", trustedPeer); + NSMutableSet* tlkShares = [NSMutableSet set]; + for(CKKSPeerProviderState* trustState in ckks.currentTrustStates) { + if(trustState.currentSelfPeers.currentSelf == nil || trustState.currentSelfPeersError) { + if(trustState.essential) { + ckksnotice("ckkstlk", ckks, "Fatal error: unable to generate TLK shares for (%@): %@", newTLK, trustState.currentSelfPeersError); + self.error = trustState.currentSelfPeersError; + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:trustState.currentSelfPeersError]; + return false; + } + ckksnotice("ckkstlk", ckks, "Unable to generate TLK shares for (%@): %@", newTLK, trustState); continue; } - ckksnotice("ckkstlk", ckks, "Generating TLK(%@) share for %@", newTLK, trustedPeer); - CKKSTLKShare* share = [CKKSTLKShare share:newTLK as:ckks.currentSelfPeers.currentSelf to:trustedPeer epoch:-1 poisoned:0 error:&error]; - - [tlkShares addObject:share]; - [recordsToSave addObject: [share CKRecordWithZoneID: ckks.zoneID]]; - } - - // Use the spare operation trick to wait for the CKModifyRecordsOperation to complete - self.cloudkitModifyOperationFinished = [NSBlockOperation named:@"newtlk-cloudkit-modify-operation-finished" withBlock:^{}]; - [self dependOnBeforeGroupFinished: self.cloudkitModifyOperationFinished]; - - CKModifyRecordsOperation* modifyRecordsOp = nil; - - // Get the CloudKit operation ready... - 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 - - // 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); - - NSMutableDictionary* attemptedRecords = [[NSMutableDictionary alloc] init]; - for(CKRecord* record in recordsToSave) { - attemptedRecords[record] = record; - } + for(id trustedPeer in trustState.currentTrustedPeers) { + if(!trustedPeer.publicEncryptionKey) { + ckksnotice("ckkstlk", ckks, "No need to make TLK for %@; they don't have any encryption keys", trustedPeer); + continue; + } - modifyRecordsOp.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + ckksnotice("ckkstlk", ckks, "Generating TLK(%@) share for %@", newTLK, trustedPeer); + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:newTLK as:trustState.currentSelfPeers.currentSelf to:trustedPeer epoch:-1 poisoned:0 error:&error]; - // These should all fail or succeed as one. Do the hard work in the records completion block. - if(!error) { - ckksnotice("ckkstlk", blockCKKS, "Successfully completed upload for %@", record.recordID.recordName); - } else { - ckkserror("ckkstlk", blockCKKS, "error on row: %@ %@", error, record); + [tlkShares addObject:share]; } - }; - + } - modifyRecordsOp.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *ckerror) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf || !strongCKKS) { - ckkserror("ckkstlk", strongCKKS, "received callback for released object"); - return; - } + keyset.pendingTLKShares = [tlkShares allObjects]; - [strongCKKS dispatchSyncWithAccountKeys: ^bool{ - if(ckerror == nil) { - ckksnotice("ckkstlk", strongCKKS, "Completed TLK CloudKit operation"); - - // Success. Persist the keys to the CKKS database. - NSError* localerror = nil; - - // Save the new CKRecords to the before persisting to database - for(CKRecord* record in savedRecords) { - if([newTLK matchesCKRecord: record]) { - newTLK.storedCKRecord = record; - } else if([newClassAKey matchesCKRecord: record]) { - newClassAKey.storedCKRecord = record; - } else if([newClassCKey matchesCKRecord: record]) { - newClassCKey.storedCKRecord = record; - } else if([wrappedOldTLK matchesCKRecord: record]) { - wrappedOldTLK.storedCKRecord = record; - - } else if([currentTLKPointer matchesCKRecord: record]) { - currentTLKPointer.storedCKRecord = record; - } else if([currentClassAPointer matchesCKRecord: record]) { - currentClassAPointer.storedCKRecord = record; - } else if([currentClassCPointer matchesCKRecord: record]) { - currentClassCPointer.storedCKRecord = record; - } - - for(CKKSTLKShare* share in tlkShares) { - if([share matchesCKRecord: record]) { - share.storedCKRecord = record; - } - } - } - - [newTLK saveToDatabaseAsOnlyCurrentKeyForClassAndState: &localerror]; - [newClassAKey saveToDatabaseAsOnlyCurrentKeyForClassAndState: &localerror]; - [newClassCKey saveToDatabaseAsOnlyCurrentKeyForClassAndState: &localerror]; - - [currentTLKPointer saveToDatabase: &localerror]; - [currentClassAPointer saveToDatabase: &localerror]; - [currentClassCPointer saveToDatabase: &localerror]; - - [wrappedOldTLK saveToDatabase: &localerror]; - - for(CKKSTLKShare* share in tlkShares) { - [share saveToDatabase:&localerror]; - } - - // TLKs are already saved in the local keychain; fire off a backup - CKKSNearFutureScheduler* tlkNotifier = strongCKKS.savedTLKNotifier; - ckksnotice("ckkstlk", strongCKKS, "triggering new TLK notification: %@", tlkNotifier); - [tlkNotifier trigger]; - - if(localerror != nil) { - ckkserror("ckkstlk", strongCKKS, "couldn't save new key hierarchy to database; this is very bad: %@", localerror); - [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateError withError: localerror]; - return false; - } else { - // Everything is groovy. - [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateReady withError: nil]; - } - } else { - ckkserror("ckkstlk", strongCKKS, "couldn't save new key hierarchy to CloudKit: %@", ckerror); - [strongCKKS _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateNewTLKsFailed withError: nil]; - - [strongCKKS _onqueueCKWriteFailed:ckerror attemptedRecordsChanged:attemptedRecords]; - - // Delete these keys from the keychain only if CloudKit positively told us the write failed. - // Other failures _might_ leave the writes written to cloudkit; who can say? - if([ckerror ckksIsCKErrorRecordChangedError]) { - NSError* localerror = nil; - [newTLK deleteKeyMaterialFromKeychain: &localerror]; - [newClassAKey deleteKeyMaterialFromKeychain: &localerror]; - [newClassCKey deleteKeyMaterialFromKeychain: &localerror]; - if(localerror) { - ckkserror("ckkstlk", strongCKKS, "couldn't delete now-useless key material from keychain: %@", localerror); - } - } else { - ckksnotice("ckkstlk", strongCKKS, "Error is too scary; not deleting likely-useless key material from keychain"); - } - } - return true; - }]; + self.keyset = keyset; - // Notify that we're done - [strongSelf.operationQueue addOperation: strongSelf.cloudkitModifyOperationFinished]; - }; + [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForTLKUpload withError:nil]; - [ckks.database addOperation: modifyRecordsOp]; return true; }]; } - (void)cancel { - [self.cloudkitModifyOperationFinished cancel]; [super cancel]; } diff --git a/keychain/ckks/CKKSOutgoingQueueEntry.h b/keychain/ckks/CKKSOutgoingQueueEntry.h index a4a91c21..05e6a00c 100644 --- a/keychain/ckks/CKKSOutgoingQueueEntry.h +++ b/keychain/ckks/CKKSOutgoingQueueEntry.h @@ -33,6 +33,8 @@ #if OCTAGON #import +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; @interface CKKSOutgoingQueueEntry : CKKSSQLDatabaseObject @@ -48,7 +50,7 @@ - (instancetype)initWithCKKSItem:(CKKSItem*)item action:(NSString*)action state:(NSString*)state - waitUntil:(NSDate*)waitUntil + waitUntil:(NSDate* _Nullable)waitUntil accessGroup:(NSString*)accessgroup; + (instancetype)withItem:(SecDbItemRef)item @@ -78,5 +80,6 @@ @end +NS_ASSUME_NONNULL_END #endif #endif /* CKKSOutgoingQueueEntry_h */ diff --git a/keychain/ckks/CKKSOutgoingQueueEntry.m b/keychain/ckks/CKKSOutgoingQueueEntry.m index 0868af4f..7ebfd83d 100644 --- a/keychain/ckks/CKKSOutgoingQueueEntry.m +++ b/keychain/ckks/CKKSOutgoingQueueEntry.m @@ -298,14 +298,12 @@ } -+ (instancetype)fromDatabaseRow: (NSDictionary*) row { - NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; - ++ (instancetype)fromDatabaseRow:(NSDictionary*) row { return [[CKKSOutgoingQueueEntry alloc] initWithCKKSItem:[CKKSItem fromDatabaseRow: row] - action:row[@"action"] - state:row[@"state"] - waitUntil:[row[@"waituntil"] isEqual: [NSNull null]] ? nil : [dateFormat dateFromString: row[@"waituntil"]] - accessGroup:row[@"accessgroup"]]; + action:row[@"action"].asString + state:row[@"state"].asString + waitUntil:row[@"waituntil"].asISO8601Date + accessGroup:row[@"accessgroup"].asString]; } + (NSDictionary*)countsByStateInZone:(CKRecordZoneID*)zoneID error: (NSError * __autoreleasing *) error { @@ -317,8 +315,8 @@ groupBy: @[@"state"] orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[row[@"state"]] = [NSNumber numberWithInteger: [row[@"count(rowid)"] integerValue]]; + processRow: ^(NSDictionary* row) { + results[row[@"state"].asString] = row[@"count(rowid)"].asNSNumberInteger; } error: error]; return results; @@ -333,8 +331,8 @@ groupBy: nil orderBy: nil limit: -1 - processRow: ^(NSDictionary* row) { - result = [row[@"count(*)"] integerValue]; + processRow: ^(NSDictionary* row) { + result = row[@"count(*)"].asNSInteger; } error: error]; return result; diff --git a/keychain/ckks/CKKSOutgoingQueueOperation.h b/keychain/ckks/CKKSOutgoingQueueOperation.h index 32348f45..9bce4142 100644 --- a/keychain/ckks/CKKSOutgoingQueueOperation.h +++ b/keychain/ckks/CKKSOutgoingQueueOperation.h @@ -28,6 +28,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; @@ -41,4 +43,6 @@ - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks ckoperationGroup:(CKOperationGroup*)ckoperationGroup; @end + +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSOutgoingQueueOperation.m b/keychain/ckks/CKKSOutgoingQueueOperation.m index 7da9132a..3cd1e853 100644 --- a/keychain/ckks/CKKSOutgoingQueueOperation.m +++ b/keychain/ckks/CKKSOutgoingQueueOperation.m @@ -35,6 +35,7 @@ #import "CKKSReencryptOutgoingItemsOperation.h" #import "CKKSManifest.h" #import "CKKSAnalytics.h" +#import "keychain/ot/ObjCImprovements.h" #include #include @@ -71,7 +72,7 @@ - (void) groupStart { // Synchronous, on some thread. Get back on the CKKS queue for thread-safety. - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSKeychainView* ckks = self.ckks; if(!ckks) { @@ -88,16 +89,62 @@ NSError* error = nil; + NSSet* priorityUUIDs = [ckks _onqueuePriorityOutgoingQueueUUIDs]; - // We only actually care about queue items in the 'new' state - NSArray * queueEntries = [CKKSOutgoingQueueEntry fetch:SecCKKSOutgoingQueueItemsAtOnce state: SecCKKSStateNew zoneID:ckks.zoneID error:&error]; + NSMutableArray* priorityEntries = [NSMutableArray array]; + NSMutableSet* priorityEntryUUIDs = [NSMutableSet set]; + + for(NSString* uuid in priorityUUIDs) { + NSError* priorityFetchError = nil; + CKKSOutgoingQueueEntry* oqe = [CKKSOutgoingQueueEntry tryFromDatabase:uuid zoneID:ckks.zoneID error:&priorityFetchError]; + + if(priorityFetchError) { + ckkserror("ckksoutgoing", ckks, "Unable to fetch priority uuid %@: %@", uuid, priorityFetchError); + continue; + } + + if(!oqe) { + continue; + } + + if(![oqe.state isEqualToString:SecCKKSStateNew]) { + ckksnotice("ckksoutgoing", ckks, "Priority uuid %@ is not in 'new': %@", uuid, oqe); + continue; + } + + if(oqe) { + ckksnotice("ckksoutgoing", ckks, "Found OQE to fetch priority uuid %@: %@", uuid, priorityFetchError); + [priorityEntries addObject:oqe]; + [priorityEntryUUIDs addObject:oqe.uuid]; + } + } + // We only actually care about queue items in the 'new' state + NSArray * newEntries = [CKKSOutgoingQueueEntry fetch:SecCKKSOutgoingQueueItemsAtOnce + state:SecCKKSStateNew + zoneID:ckks.zoneID + error:&error]; if(error != nil) { ckkserror("ckksoutgoing", ckks, "Error fetching outgoing queue records: %@", error); self.error = error; return false; } + // Build our list of oqes to transmit + NSMutableArray* queueEntries = [priorityEntries mutableCopy]; + for(CKKSOutgoingQueueEntry* oqe in newEntries) { + if(queueEntries.count >= SecCKKSOutgoingQueueItemsAtOnce) { + break; + } else { + // We only need to add this OQE if it wasn't already there + if(![priorityEntryUUIDs containsObject:oqe.uuid]) { + [queueEntries addObject:oqe]; + } + } + } + + bool fullUpload = queueEntries.count >= SecCKKSOutgoingQueueItemsAtOnce; + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventOutgoingQueue zone:ckks.zoneName count:[queueEntries count]]; ckksinfo("ckksoutgoing", ckks, "processing outgoing queue: %@", queueEntries); @@ -264,9 +311,9 @@ } void (^modifyRecordsCompletionBlock)(NSArray*, NSArray*, NSError*) = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *ckerror) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf || !strongCKKS) { + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; + if(!self || !strongCKKS) { ckkserror("ckksoutgoing", strongCKKS, "received callback for released object"); return; } @@ -291,10 +338,10 @@ bool askForReencrypt = false; - if([strongSelf _onqueueIsErrorBadEtagOnKeyPointersOnly:ckerror]) { + if([self _onqueueIsErrorBadEtagOnKeyPointersOnly:ckerror]) { // The current key pointers have updated without our knowledge, so CloudKit failed this operation. Mark all records as 'needs reencryption' and kick that off. ckksnotice("ckksoutgoing", strongCKKS, "Error is simply due to current key pointers changing; marking all records as 'needs reencrypt'"); - [strongSelf _onqueueModifyAllRecords:failedRecords.allKeys as:SecCKKSStateReencrypt]; + [self _onqueueModifyAllRecords:failedRecords.allKeys as:SecCKKSStateReencrypt]; askForReencrypt = true; } else { // Iterate all failures, and reset each item @@ -303,7 +350,7 @@ ckksnotice("ckksoutgoing", strongCKKS, "failed record: %@ %@", recordID, recordError); - if(recordError.code == CKErrorServerRecordChanged) { + if([recordError.domain isEqualToString: CKErrorDomain] && recordError.code == CKErrorServerRecordChanged) { if([recordID.recordName isEqualToString: SecCKKSKeyClassA] || [recordID.recordName isEqualToString: SecCKKSKeyClassC]) { // Note that _onqueueCKWriteFailed is responsible for kicking the key state machine, so we don't need to do it here. @@ -311,10 +358,10 @@ } else { // CKErrorServerRecordChanged on an item update means that we've been overwritten. if([recordIDsModified containsObject:recordID]) { - [strongSelf _onqueueModifyRecordAsError:recordID recordError:recordError]; + [self _onqueueModifyRecordAsError:recordID recordError:recordError]; } } - } else if(recordError.code == CKErrorBatchRequestFailed) { + } else if([recordError.domain isEqualToString: CKErrorDomain] && recordError.code == CKErrorBatchRequestFailed) { // Also fine. This record only didn't succeed because something else failed. // OQEs should be placed back into the 'new' state, unless they've been overwritten by a new OQE. Other records should be ignored. @@ -331,7 +378,7 @@ // Some unknown error occurred on this record. If it's an OQE, move it to the error state. ckkserror("ckksoutgoing", strongCKKS, "Unknown error on row: %@ %@", recordID, recordError); if([recordIDsModified containsObject:recordID]) { - [strongSelf _onqueueModifyRecordAsError:recordID recordError:recordError]; + [self _onqueueModifyRecordAsError:recordID recordError:recordError]; } } } @@ -341,16 +388,16 @@ // This will wait for the key hierarchy to become 'ready' ckkserror("ckksoutgoing", strongCKKS, "Starting new Reencrypt items operation"); CKKSReencryptOutgoingItemsOperation* op = [[CKKSReencryptOutgoingItemsOperation alloc] initWithCKKSKeychainView:strongCKKS - ckoperationGroup:strongSelf.ckoperationGroup]; + ckoperationGroup:self.ckoperationGroup]; [strongCKKS scheduleOperation: op]; } } else { // Some non-partial error occured. We should place all "inflight" OQEs back into the outgoing queue. ckksnotice("ckks", strongCKKS, "Error is scary: putting all inflight OQEs back into state 'new'"); - [strongSelf _onqueueModifyAllRecords:[recordIDsModified allObjects] as:SecCKKSStateNew]; + [self _onqueueModifyAllRecords:[recordIDsModified allObjects] as:SecCKKSStateNew]; } - strongSelf.error = ckerror; + self.error = ckerror; return true; } @@ -365,14 +412,14 @@ [strongCKKS _onqueueChangeOutgoingQueueEntry:oqe toState:SecCKKSStateDeleted error:&error]; if(error) { ckkserror("ckksoutgoing", strongCKKS, "Couldn't update %@ in outgoingqueue: %@", record.recordID.recordName, error); - strongSelf.error = error; + self.error = error; } error = nil; CKKSMirrorEntry* ckme = [[CKKSMirrorEntry alloc] initWithCKRecord: record]; [ckme saveToDatabase: &error]; if(error) { ckkserror("ckksoutgoing", strongCKKS, "Couldn't save %@ to ckmirror: %@", record.recordID.recordName, error); - strongSelf.error = error; + self.error = error; } [plstats storedOQE:oqe]; @@ -383,7 +430,7 @@ [currentkey saveToDatabase: &error]; if(error) { ckkserror("ckksoutgoing", strongCKKS, "Couldn't save %@ to currentkey: %@", record.recordID.recordName, error); - strongSelf.error = error; + self.error = error; } } else if ([record.recordType isEqualToString:SecCKRecordDeviceStateType]) { @@ -391,7 +438,7 @@ [newcdse saveToDatabase:&error]; if(error) { ckkserror("ckksoutgoing", strongCKKS, "Couldn't save %@ to ckdevicestate: %@", record.recordID.recordName, error); - strongSelf.error = error; + self.error = error; } } else if ([record.recordType isEqualToString:SecCKRecordManifestType]) { @@ -409,14 +456,14 @@ [strongCKKS _onqueueChangeOutgoingQueueEntry:oqe toState:SecCKKSStateDeleted error:&error]; if(error) { ckkserror("ckksoutgoing", strongCKKS, "Couldn't delete %@ from outgoingqueue: %@", ckrecordID.recordName, error); - strongSelf.error = error; + self.error = error; } error = nil; CKKSMirrorEntry* ckme = [CKKSMirrorEntry tryFromDatabase: ckrecordID.recordName zoneID:strongCKKS.zoneID error:&error]; [ckme deleteFromDatabase: &error]; if(error) { ckkserror("ckksoutgoing", strongCKKS, "Couldn't delete %@ from ckmirror: %@", ckrecordID.recordName, error); - strongSelf.error = error; + self.error = error; } [plstats deletedOQE:oqe]; @@ -424,9 +471,9 @@ [plstats commit]; - if(strongSelf.error) { - ckkserror("ckksoutgoing", strongCKKS, "Operation failed; rolling back: %@", strongSelf.error); - [logger logRecoverableError:strongSelf.error + if(self.error) { + ckkserror("ckksoutgoing", strongCKKS, "Operation failed; rolling back: %@", self.error); + [logger logRecoverableError:self.error forEvent:CKKSEventProcessOutgoingQueue inView:strongCKKS withAttributes:NULL]; @@ -437,7 +484,7 @@ return true; }]; - [strongSelf.operationQueue addOperation: modifyComplete]; + [self.operationQueue addOperation: modifyComplete]; // Kick off another queue process. We expect it to exit instantly, but who knows! // If we think the network is iffy, though, wait for it to come back CKKSResultOperation* possibleNetworkDependency = nil; @@ -446,7 +493,9 @@ possibleNetworkDependency = reachabilityTracker.reachabilityDependency; } - [strongCKKS processOutgoingQueueAfter:possibleNetworkDependency ckoperationGroup:strongSelf.ckoperationGroup]; + [strongCKKS processOutgoingQueueAfter:possibleNetworkDependency + requiredDelay:fullUpload && !ckerror ? NSEC_PER_MSEC * 100 : DISPATCH_TIME_FOREVER + ckoperationGroup:self.ckoperationGroup]; }; ckksinfo("ckksoutgoing", ckks, "Current keys to update: %@", currentKeysToSave); @@ -478,6 +527,7 @@ // 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.configuration.isCloudKitSupportOperation = YES; self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.group = self.ckoperationGroup; @@ -485,8 +535,8 @@ ckksnotice("ckksoutgoing", ckks, "Beginning upload for %@ %@", recordsToSave.allKeys, recordIDsToDelete); self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* blockCKKS = self.ckks; if(!error) { ckksnotice("ckksoutgoing", blockCKKS, "Record upload successful for %@ (%@)", record.recordID.recordName, record.recordChangeTag); @@ -575,7 +625,7 @@ for(CKRecordID* recordID in failedRecords) { NSError* recordError = failedRecords[recordID]; - if(recordError.code == CKErrorServerRecordChanged) { + if([recordError.domain isEqualToString: CKErrorDomain] && recordError.code == CKErrorServerRecordChanged) { if([recordID.recordName isEqualToString: SecCKKSKeyClassA] || [recordID.recordName isEqualToString: SecCKKSKeyClassC]) { // this is fine! diff --git a/keychain/ckks/CKKSPeer.h b/keychain/ckks/CKKSPeer.h index bb96afd1..1270faa5 100644 --- a/keychain/ckks/CKKSPeer.h +++ b/keychain/ckks/CKKSPeer.h @@ -40,6 +40,10 @@ NS_ASSUME_NONNULL_BEGIN - (bool)matchesPeer:(id)peer; @end +@protocol CKKSRemotePeerProtocol +- (BOOL)shouldHaveView:(NSString*)viewName; +@end + @protocol CKKSSelfPeer @property (readonly) SFECKeyPair* encryptionKey; @property (readonly) SFECKeyPair* signingKey; @@ -58,34 +62,52 @@ NS_ASSUME_NONNULL_BEGIN @protocol CKKSPeerUpdateListener; @protocol CKKSPeerProvider +@property (readonly) NSString* providerID; +@property BOOL essential; + - (CKKSSelves* _Nullable)fetchSelfPeers:(NSError* _Nullable __autoreleasing* _Nullable)error; -- (NSSet>* _Nullable)fetchTrustedPeers:(NSError* _Nullable __autoreleasing* _Nullable)error; +- (NSSet>* _Nullable)fetchTrustedPeers:(NSError* _Nullable __autoreleasing* _Nullable)error; // Trusted peers should include self peers - (void)registerForPeerChangeUpdates:(id)listener; +- (void)sendSelfPeerChangedUpdate; +- (void)sendTrustedPeerSetChangedUpdate; @end // A CKKSPeerUpdateListener wants to be notified when a CKKSPeerProvider has new information @protocol CKKSPeerUpdateListener -- (void)selfPeerChanged; -- (void)trustedPeerSetChanged; +- (void)selfPeerChanged:(id _Nullable)provider; +- (void)trustedPeerSetChanged:(id _Nullable)provider; @end extern NSString* const CKKSSOSPeerPrefix; -// These should be replaced by Octagon peers, when those exist -@interface CKKSSOSPeer : NSObject +@interface CKKSActualPeer : NSObject @property (readonly) NSString* peerID; @property (nullable, readonly) SFECPublicKey* publicEncryptionKey; @property (nullable, readonly) SFECPublicKey* publicSigningKey; +@property (nullable, readonly) NSSet* viewList; + +- (instancetype)initWithPeerID:(NSString*)syncingPeerID + encryptionPublicKey:(SFECPublicKey* _Nullable)encryptionKey + signingPublicKey:(SFECPublicKey* _Nullable)signingKey + viewList:(NSSet* _Nullable)viewList; +@end +@protocol CKKSSOSPeerProtocol +@end + +@interface CKKSSOSPeer : NSObject - (instancetype)initWithSOSPeerID:(NSString*)syncingPeerID encryptionPublicKey:(SFECPublicKey* _Nullable)encryptionKey - signingPublicKey:(SFECPublicKey* _Nullable)signingKey; + signingPublicKey:(SFECPublicKey* _Nullable)signingKey + viewList:(NSSet* _Nullable)viewList; @end -@interface CKKSSOSSelfPeer : NSObject +@interface CKKSSOSSelfPeer : NSObject @property (readonly) NSString* peerID; +@property (nullable, readonly) NSSet* viewList; + @property (readonly) SFECPublicKey* publicEncryptionKey; @property (readonly) SFECPublicKey* publicSigningKey; @@ -94,8 +116,11 @@ extern NSString* const CKKSSOSPeerPrefix; - (instancetype)initWithSOSPeerID:(NSString*)syncingPeerID encryptionKey:(SFECKeyPair*)encryptionKey - signingKey:(SFECKeyPair*)signingKey; + signingKey:(SFECKeyPair*)signingKey + viewList:(NSSet* _Nullable)viewList; @end +NSSet* CKKSPeerClasses(void); + NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSPeer.m b/keychain/ckks/CKKSPeer.m index 43fbb70c..4904574f 100644 --- a/keychain/ckks/CKKSPeer.m +++ b/keychain/ckks/CKKSPeer.m @@ -24,6 +24,7 @@ #if OCTAGON #import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSViewManager.h" NSString* const CKKSSOSPeerPrefix = @"spid-"; @@ -48,22 +49,101 @@ NSString* const CKKSSOSPeerPrefix = @"spid-"; @end +#pragma mark - CKKSActualPeer + +@implementation CKKSActualPeer +- (NSString*)description { + // Return the first 16 bytes of the public keys (for reading purposes) + return [NSString stringWithFormat:@"", + self.peerID, + [self.publicEncryptionKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicEncryptionKey.keyData.length))], + [self.publicSigningKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicSigningKey.keyData.length))], + (int)self.viewList.count]; +} + +- (instancetype)initWithPeerID:(NSString*)syncingPeerID + encryptionPublicKey:(SFECPublicKey*)encryptionKey + signingPublicKey:(SFECPublicKey*)signingKey + viewList:(NSSet*)viewList +{ + if((self = [super init])) { + _peerID = syncingPeerID; + + _publicEncryptionKey = encryptionKey; + _publicSigningKey = signingKey; + _viewList = viewList; + } + return self; +} + +- (bool)matchesPeer:(id)peer { + return (self.peerID == nil && peer.peerID == nil) || + [self.peerID isEqualToString:peer.peerID]; +} + +- (BOOL)shouldHaveView:(NSString *)viewName +{ + return [self.viewList containsObject:viewName]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder*)coder +{ + [coder encodeObject:self.peerID forKey:@"peerID"]; + [coder encodeObject:self.publicEncryptionKey.encodeSubjectPublicKeyInfo forKey:@"encryptionKey"]; + [coder encodeObject:self.publicSigningKey.encodeSubjectPublicKeyInfo forKey:@"signingKey"]; + [coder encodeObject:self.viewList forKey:@"viewList"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder*)decoder +{ + self = [super init]; + if(self) { + _peerID = [decoder decodeObjectOfClass:[NSString class] forKey:@"peerID"]; + + NSData* encryptionSPKI = [decoder decodeObjectOfClass:[NSData class] forKey:@"encryptionKey"]; + if(encryptionSPKI) { + _publicEncryptionKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:encryptionSPKI]; + } + + NSData* signingSPKI = [decoder decodeObjectOfClass:[NSData class] forKey:@"signingKey"]; + if(signingSPKI) { + _publicSigningKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:signingSPKI]; + } + + _viewList = [decoder decodeObjectOfClasses:[NSSet setWithArray:@[[NSSet class], [NSString class]]] forKey:@"viewList"]; + } + return self; +} +@end + +#pragma mark - CKKSSOSPeer + @interface CKKSSOSPeer () @property NSString* spid; +@property NSSet* viewList; @end @implementation CKKSSOSPeer +@synthesize publicEncryptionKey = _publicEncryptionKey; +@synthesize publicSigningKey = _publicSigningKey; + - (NSString*)description { // Return the first 16 bytes of the public keys (for reading purposes) - return [NSString stringWithFormat:@"", + return [NSString stringWithFormat:@"", self.peerID, [self.publicEncryptionKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicEncryptionKey.keyData.length))], - [self.publicSigningKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicSigningKey.keyData.length))]]; + [self.publicSigningKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicSigningKey.keyData.length))], + (int)self.viewList.count]; } - (instancetype)initWithSOSPeerID:(NSString*)syncingPeerID encryptionPublicKey:(SFECPublicKey*)encryptionKey signingPublicKey:(SFECPublicKey*)signingKey + viewList:(NSSet* _Nullable)viewList { if((self = [super init])) { if([syncingPeerID hasPrefix:CKKSSOSPeerPrefix]) { @@ -73,6 +153,7 @@ NSString* const CKKSSOSPeerPrefix = @"spid-"; } _publicEncryptionKey = encryptionKey; _publicSigningKey = signingKey; + _viewList = viewList; } return self; } @@ -85,6 +166,41 @@ NSString* const CKKSSOSPeerPrefix = @"spid-"; return (self.peerID == nil && peer.peerID == nil) || [self.peerID isEqualToString:peer.peerID]; } + +- (BOOL)shouldHaveView:(NSString *)viewName +{ + return [self.viewList containsObject:viewName]; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder*)coder +{ + [coder encodeObject:self.spid forKey:@"spid"]; + [coder encodeObject:self.publicEncryptionKey.encodeSubjectPublicKeyInfo forKey:@"encryptionKey"]; + [coder encodeObject:self.publicSigningKey.encodeSubjectPublicKeyInfo forKey:@"signingKey"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder*)decoder +{ + self = [super init]; + if(self) { + _spid = [decoder decodeObjectOfClass:[NSString class] forKey:@"spid"]; + + NSData* encryptionSPKI = [decoder decodeObjectOfClass:[NSData class] forKey:@"encryptionKey"]; + if(encryptionSPKI) { + _publicEncryptionKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:encryptionSPKI]; + } + + NSData* signingSPKI = [decoder decodeObjectOfClass:[NSData class] forKey:@"signingKey"]; + if(signingSPKI) { + _publicSigningKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:signingSPKI]; + } + } + return self; +} @end @interface CKKSSOSSelfPeer () @@ -93,15 +209,17 @@ NSString* const CKKSSOSPeerPrefix = @"spid-"; @implementation CKKSSOSSelfPeer - (NSString*)description { - return [NSString stringWithFormat:@"", + return [NSString stringWithFormat:@"", self.peerID, [self.publicEncryptionKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicEncryptionKey.keyData.length))], - [self.publicSigningKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicSigningKey.keyData.length))]]; + [self.publicSigningKey.keyData subdataWithRange:NSMakeRange(0, MIN(16u,self.publicSigningKey.keyData.length))], + (int)self.viewList.count]; } - (instancetype)initWithSOSPeerID:(NSString*)syncingPeerID encryptionKey:(SFECKeyPair*)encryptionKey signingKey:(SFECKeyPair*)signingKey + viewList:(NSSet* _Nullable)viewList { if((self = [super init])) { if([syncingPeerID hasPrefix:CKKSSOSPeerPrefix]) { @@ -111,6 +229,7 @@ NSString* const CKKSSOSPeerPrefix = @"spid-"; } _encryptionKey = encryptionKey; _signingKey = signingKey; + _viewList = viewList; } return self; } @@ -129,6 +248,16 @@ NSString* const CKKSSOSPeerPrefix = @"spid-"; return (self.peerID == nil && peer.peerID == nil) || [self.peerID isEqualToString:peer.peerID]; } + +- (BOOL)shouldHaveView:(NSString *)viewName +{ + return [self.viewList containsObject:viewName]; +} @end +NSSet* CKKSPeerClasses(void) +{ + return [NSSet setWithArray:@[[CKKSSOSPeer class], [CKKSActualPeer class]]]; +} + #endif // OCTAGON diff --git a/keychain/ckks/CKKSProcessReceivedKeysOperation.h b/keychain/ckks/CKKSProcessReceivedKeysOperation.h index 55a67c9e..362843ec 100644 --- a/keychain/ckks/CKKSProcessReceivedKeysOperation.h +++ b/keychain/ckks/CKKSProcessReceivedKeysOperation.h @@ -23,12 +23,34 @@ #import +#if OCTAGON + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSGroupOperation.h" + +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; -@interface CKKSProcessReceivedKeysOperation : NSOperation +// CKKS's state machine depends on its operations performing callbacks to move the state, but this means +// the operations cannot be reused outside of the state machine context. +// Therefore, split this operation into two: one which does the work, and another which does the CKKS state manipulation. + +@interface CKKSProcessReceivedKeysOperation : CKKSResultOperation @property (weak) CKKSKeychainView* ckks; +@property CKKSZoneKeyState* nextState; + - (instancetype)init NS_UNAVAILABLE; - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks; +@end +@interface CKKSProcessReceivedKeysStateMachineOperation : CKKSResultOperation +@property (weak) CKKSKeychainView* ckks; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks; @end + +NS_ASSUME_NONNULL_END +#endif // OCTAGON diff --git a/keychain/ckks/CKKSProcessReceivedKeysOperation.m b/keychain/ckks/CKKSProcessReceivedKeysOperation.m index c2debc1b..3ccc4fe1 100644 --- a/keychain/ckks/CKKSProcessReceivedKeysOperation.m +++ b/keychain/ckks/CKKSProcessReceivedKeysOperation.m @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON + #import #import "CKKSKeychainView.h" @@ -30,8 +32,6 @@ #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" -#if OCTAGON - @implementation CKKSProcessReceivedKeysOperation - (instancetype)init { @@ -40,14 +40,14 @@ - (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks { if(self = [super init]) { _ckks = ckks; + _nextState = SecCKKSZoneKeyStateError; } return self; } -- (void) main { +- (void)main { // Synchronous, on some thread. Get back on the CKKS queue for SQL thread-safety. - // Take a strong reference. CKKSKeychainView* ckks = self.ckks; if(!ckks) { secerror("ckkskeys: No CKKS object"); @@ -60,169 +60,214 @@ } [ckks dispatchSyncWithAccountKeys: ^bool{ - if(self.cancelled) { - ckksinfo("ckkskey", ckks, "CKKSProcessReceivedKeysOperation cancelled, quitting"); - return false; - } + return [self _onqueueMain:ckks]; + }]; +} - ckks.lastProcessReceivedKeysOperation = self; +- (bool)_onqueueMain:(CKKSKeychainView*)ckks +{ + if(self.cancelled) { + ckksinfo("ckkskey", ckks, "CKKSProcessReceivedKeysOperation cancelled, quitting"); + return false; + } - NSError* error = nil; - CKKSKey* tlk = nil; - CKKSKey* topKey = nil; + ckks.lastProcessReceivedKeysOperation = self; - // The synckeys table contains everything that's in CloudKit, if looked at correctly. - // Updates from CloudKit are marked 'remote'; everything else is 'local'. + NSError* error = nil; + CKKSKey* tlk = nil; + CKKSKey* topKey = nil; - // Step 1. Find all remote keys. - NSArray* remoteKeys = [CKKSKey remoteKeys:ckks.zoneID error:&error]; - if(!remoteKeys) { - ckkserror("ckkskey", ckks, "couldn't fetch list of remote keys: %@", error); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:error]; - return false; - } + // The synckeys table contains everything that's in CloudKit, if looked at correctly. + // Updates from CloudKit are marked 'remote'; everything else is 'local'. - if([remoteKeys count] == 0u) { - ckksnotice("ckkskey", ckks, "No remote keys? Quitting."); - // Not a ready state, more of a quizzical one? The key state machine will know what to do. - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateReady withError:error]; - return false; + // Step 1. Find all remote keys. + NSArray* remoteKeys = [CKKSKey remoteKeys:ckks.zoneID error:&error]; + if(!remoteKeys) { + ckkserror("ckkskey", ckks, "couldn't fetch list of remote keys: %@", error); + self.error = error; + self.nextState = SecCKKSZoneKeyStateError; + return false; + } + + if([remoteKeys count] == 0u) { + ckksnotice("ckkskey", ckks, "No remote keys? Quitting."); + // Not a ready state, more of a quizzical one? The key state machine will know what to do. + self.error = error; + self.nextState = SecCKKSZoneKeyStateReady; + return false; + } + + ckksinfo("ckkskey", ckks, "remote keys: %@", remoteKeys); + + // current TLK record: + CKKSCurrentKeyPointer* currentTLKPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassTLK zoneID:ckks.zoneID error:&error]; + CKKSCurrentKeyPointer* currentClassAPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassA zoneID:ckks.zoneID error:&error]; + CKKSCurrentKeyPointer* currentClassCPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassC zoneID:ckks.zoneID error:&error]; + + // Do these pointers point at anything? + NSError* localerror = nil; + CKKSKey* suggestedTLK = currentTLKPointer.currentKeyUUID ? [CKKSKey tryFromDatabaseAnyState:currentTLKPointer.currentKeyUUID zoneID:ckks.zoneID error:&localerror] : nil; + CKKSKey* suggestedClassA = currentClassAPointer.currentKeyUUID ? [CKKSKey tryFromDatabaseAnyState:currentClassAPointer.currentKeyUUID zoneID:ckks.zoneID error:&localerror] : nil; + CKKSKey* suggestedClassC = currentClassCPointer.currentKeyUUID ? [CKKSKey tryFromDatabaseAnyState:currentClassCPointer.currentKeyUUID zoneID:ckks.zoneID error:&localerror] : nil; + + if(!currentTLKPointer || !currentClassAPointer || !currentClassCPointer || + !currentTLKPointer.currentKeyUUID || !currentClassAPointer.currentKeyUUID || !currentClassCPointer.currentKeyUUID || + !suggestedTLK || !suggestedClassA || !suggestedClassC) { + ckkserror("ckkskey", ckks, "no current pointer for some keyclass: tlk:%@ a:%@ c:%@ %@ %@", + currentTLKPointer, currentClassAPointer, currentClassCPointer, error, localerror); + self.error = error; + self.nextState = SecCKKSZoneKeyStateBadCurrentPointers; + return true; + } + + for(CKKSKey* key in remoteKeys) { + // Find the active TLK. + if([key.uuid isEqualToString: currentTLKPointer.currentKeyUUID]) { + if([key wrapsSelf]) { + tlk = key; + } else { + NSError *newError = [NSError errorWithDomain:CKKSErrorDomain code:CKKSKeyNotSelfWrapped description:[NSString stringWithFormat: @"current TLK doesn't wrap itself: %@ %@", key, key.parentKeyUUID] underlying:error]; + ckkserror("ckkskey", ckks, "%@", error); + self.error = newError; + self.nextState = SecCKKSZoneKeyStateUnhealthy; + return true; + } } + } + + if(!tlk) { + ckkserror("ckkskey", ckks, "couldn't find active TLK: %@", currentTLKPointer); + self.error = error; + self.nextState = SecCKKSZoneKeyStateUnhealthy; + return true; + } - ckksinfo("ckkskey", ckks, "remote keys: %@", remoteKeys); - - // current TLK record: - CKKSCurrentKeyPointer* currentTLKPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassTLK zoneID:ckks.zoneID error:&error]; - CKKSCurrentKeyPointer* currentClassAPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassA zoneID:ckks.zoneID error:&error]; - CKKSCurrentKeyPointer* currentClassCPointer = [CKKSCurrentKeyPointer tryFromDatabase: SecCKKSKeyClassC zoneID:ckks.zoneID error:&error]; - - // Do these pointers point at anything? - NSError* localerror = nil; - CKKSKey* suggestedTLK = currentTLKPointer.currentKeyUUID ? [CKKSKey tryFromDatabaseAnyState:currentTLKPointer.currentKeyUUID zoneID:ckks.zoneID error:&localerror] : nil; - CKKSKey* suggestedClassA = currentClassAPointer.currentKeyUUID ? [CKKSKey tryFromDatabaseAnyState:currentClassAPointer.currentKeyUUID zoneID:ckks.zoneID error:&localerror] : nil; - CKKSKey* suggestedClassC = currentClassCPointer.currentKeyUUID ? [CKKSKey tryFromDatabaseAnyState:currentClassCPointer.currentKeyUUID zoneID:ckks.zoneID error:&localerror] : nil; - - if(!currentTLKPointer || !currentClassAPointer || !currentClassCPointer || - !currentTLKPointer.currentKeyUUID || !currentClassAPointer.currentKeyUUID || !currentClassCPointer.currentKeyUUID || - !suggestedTLK || !suggestedClassA || !suggestedClassC) { - ckkserror("ckkskey", ckks, "no current pointer for some keyclass: tlk:%@ a:%@ c:%@ %@ %@", - currentTLKPointer, currentClassAPointer, currentClassCPointer, error, localerror); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateBadCurrentPointers withError:error]; + // This key is our proposed TLK. Check with the CKKS object. + if(![ckks _onqueueWithAccountKeysCheckTLK: tlk error: &error]) { + // Was this error "I've never seen that TLK before in my life"? If so, enter the "wait for TLK sync" state. + if(error && [error.domain isEqualToString: @"securityd"] && error.code == errSecItemNotFound) { + ckksnotice("ckkskey", ckks, "Received a TLK which we don't have in the local keychain(%@). Entering waitfortlk.", tlk); + self.nextState = SecCKKSZoneKeyStateWaitForTLK; + return true; + } else if(error && [ckks.lockStateTracker isLockedError:error]) { + // TODO: _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError should handle this. But, we don't have tests, so, leave this in until 33204154 + ckksnotice("ckkskey", ckks, "Received a TLK(%@), but keybag appears to be locked. Entering a waiting state.", tlk); + self.nextState = SecCKKSZoneKeyStateWaitForUnlock; + return true; + } else { + // Otherwise, something has gone horribly wrong. enter error state. + ckkserror("ckkskey", ckks, "CKKS claims %@ is not a valid TLK: %@", tlk, error); + self.error = [NSError errorWithDomain:CKKSErrorDomain code:CKKSInvalidTLK description:@"invalid TLK from CloudKit" underlying:error]; + self.nextState = SecCKKSZoneKeyStateError; return true; } + } - for(CKKSKey* key in remoteKeys) { - // Find the active TLK. - if([key.uuid isEqualToString: currentTLKPointer.currentKeyUUID]) { - if([key wrapsSelf]) { - tlk = key; - } else { - ckkserror("ckkskey", ckks, "current TLK doesn't wrap itself: %@ %@", key, key.parentKeyUUID); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateUnhealthy withError:error]; - return true; - } - } + // Ensure that new keys wrap to the TLK. + for(CKKSKey* key in remoteKeys) { + if(key == tlk) { + continue; } - if(!tlk) { - ckkserror("ckkskey", ckks, "couldn't find active TLK: %@", currentTLKPointer); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateUnhealthy withError:error]; + topKey = [key topKeyInAnyState:&error]; + + if(error != nil || ![topKey.uuid isEqual: tlk.uuid]) { + ckkserror("ckkskey", ckks, "new key %@ is orphaned (%@)", key, error); + // TODO: possibly re-fetch. Maybe not an actual error state. + self.error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSOrphanedKey + description:[NSString stringWithFormat:@"orphaned key(%@) in hierarchy", topKey] + underlying:error]; + self.nextState = SecCKKSZoneKeyStateError; return true; + } - // This key is our proposed TLK. Check with the CKKS object. - if(![ckks _onqueueWithAccountKeysCheckTLK: tlk error: &error]) { - // Was this error "I've never seen that TLK before in my life"? If so, enter the "wait for TLK sync" state. - if(error && [error.domain isEqualToString: @"securityd"] && error.code == errSecItemNotFound) { - ckksnotice("ckkskey", ckks, "Received a TLK which we don't have in the local keychain(%@). Entering waitfortlk.", tlk); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForTLK withError:nil]; - return true; - } else if(error && [ckks.lockStateTracker isLockedError:error]) { - // TODO: _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError should handle this. But, we don't have tests, so, leave this in until 33204154 - ckksnotice("ckkskey", ckks, "Received a TLK(%@), but keybag appears to be locked. Entering a waiting state.", tlk); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:nil]; + // Okay, it wraps to the TLK. Can we unwrap it? + if(![key unwrapViaKeyHierarchy:&error] || error != nil) { + if(error && [ckks.lockStateTracker isLockedError:error]) { + ckksnotice("ckkskey", ckks, "Couldn't unwrap new key (%@), but keybag appears to be locked. Entering waitforunlock.", key); + self.error = error; + self.nextState = SecCKKSZoneKeyStateWaitForUnlock; return true; } else { - // Otherwise, something has gone horribly wrong. enter error state. - ckkserror("ckkskey", ckks, "CKKS claims %@ is not a valid TLK: %@", tlk, error); - NSError* newError = [NSError errorWithDomain:CKKSErrorDomain code:CKKSInvalidTLK description:@"invalid TLK from CloudKit" underlying:error]; - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError:newError]; + ckkserror("ckkskey", ckks, "new key %@ claims to wrap to TLK, but we can't unwrap it: %@", topKey, error); + self.error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSOrphanedKey + description:[NSString stringWithFormat:@"unwrappable key(%@) in hierarchy: %@", topKey, error] + underlying:error]; + self.nextState = SecCKKSZoneKeyStateError; return true; } } - // Ensure that new keys wrap to the TLK. - for(CKKSKey* key in remoteKeys) { - if(key == tlk) { - continue; - } + ckksnotice("ckkskey", ckks, "New key %@ wraps to tlk %@", key, tlk); + } - topKey = [key topKeyInAnyState:&error]; - if(error != nil || ![topKey.uuid isEqual: tlk.uuid]) { - ckkserror("ckkskey", ckks, "new key %@ is orphaned (%@)", key, error); - // TODO: possibly re-fetch. Maybe not an actual error state. - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError - withError:[NSError errorWithDomain:CKKSErrorDomain - code:CKKSOrphanedKey - description:[NSString stringWithFormat:@"orphaned key(%@) in hierarchy", topKey] - underlying:error]]; - return true; + // We're happy with this key hierarchy. Save it. + for(CKKSKey* key in remoteKeys) { + key.state = SecCKKSProcessedStateLocal; - } + if([key.uuid isEqualToString: currentClassAPointer.currentKeyUUID] || + [key.uuid isEqualToString: currentClassCPointer.currentKeyUUID]) { + [key saveToDatabaseAsOnlyCurrentKeyForClassAndState: &error]; + } else { + [key saveToDatabase: &error]; + } - // Okay, it wraps to the TLK. Can we unwrap it? - if(![key unwrapViaKeyHierarchy:&error] || error != nil) { - if(error && [ckks.lockStateTracker isLockedError:error]) { - ckksnotice("ckkskey", ckks, "Couldn't unwrap new key (%@), but keybag appears to be locked. Entering waitforunlock.", key); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForUnlock withError:error]; - return true; - } else { - ckkserror("ckkskey", ckks, "new key %@ claims to wrap to TLK, but we can't unwrap it: %@", topKey, error); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError - withError:[NSError errorWithDomain:CKKSErrorDomain - code:CKKSOrphanedKey - description:[NSString stringWithFormat:@"unwrappable key(%@) in hierarchy: %@", topKey, error] - underlying:error]]; - return true; - } - } + [key saveKeyMaterialToKeychain: &error]; - ckksnotice("ckkskey", ckks, "New key %@ wraps to tlk %@", key, tlk); + if(error) { + ckkserror("ckkskey", ckks, "couldn't save newly local key %@ to database: %@", key, error); + self.error = error; + self.nextState = SecCKKSZoneKeyStateError; + return false; } + } + // New key hierarchy? Get it backed up! + // TLKs are now saved in the local keychain; fire off a backup + CKKSNearFutureScheduler* tlkNotifier = ckks.savedTLKNotifier; + ckksnotice("ckkstlk", ckks, "triggering new TLK notification: %@", tlkNotifier); + [tlkNotifier trigger]; + + if(!error) { + ckksnotice("ckkskey", ckks, "Accepted new key hierarchy"); + self.nextState = SecCKKSZoneKeyStateReady; + } else { + ckkserror("ckkskey", ckks, "error accepting new key hierarchy: %@", error); + self.error = error; + self.nextState = SecCKKSZoneKeyStateError; + } + return true; +} - // We're happy with this key hierarchy. Save it. - for(CKKSKey* key in remoteKeys) { - key.state = SecCKKSProcessedStateLocal; +@end; - if([key.uuid isEqualToString: currentClassAPointer.currentKeyUUID] || - [key.uuid isEqualToString: currentClassCPointer.currentKeyUUID]) { - [key saveToDatabaseAsOnlyCurrentKeyForClassAndState: &error]; - } else { - [key saveToDatabase: &error]; - } +@implementation CKKSProcessReceivedKeysStateMachineOperation +- (instancetype)initWithCKKSKeychainView:(CKKSKeychainView*)ckks { + if(self = [super init]) { + _ckks = ckks; + } + return self; +} - [key saveKeyMaterialToKeychain: &error]; +- (void)main +{ + CKKSKeychainView* ckks = self.ckks; - if(error) { - ckkserror("ckkskey", ckks, "couldn't save newly local key %@ to database: %@", key, error); - [ckks _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateError withError: error]; - return false; - } - } + // The following is an abuse of operations, but we need the state machine advancement to be in the same txion as the decision + CKKSProcessReceivedKeysOperation* op = [[CKKSProcessReceivedKeysOperation alloc] initWithCKKSKeychainView:ckks]; - if(!error) { - ckksnotice("ckkskey", ckks, "Accepted new key hierarchy"); - [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateReady withError: nil]; - } else { - ckkserror("ckkskey", ckks, "error accepting new key hierarchy: %@", error); - [ckks _onqueueAdvanceKeyStateMachineToState: SecCKKSZoneKeyStateError withError: error]; - } - return true; + [ckks dispatchSyncWithAccountKeys:^bool { + bool ret = [op _onqueueMain:ckks]; + ckksnotice("ckkskey", ckks, "Finished processing received keys, moving to state %@", op.nextState); + [ckks _onqueueAdvanceKeyStateMachineToState:op.nextState withError:op.error]; + return ret; }]; } -@end; +@end #endif diff --git a/keychain/ckks/CKKSProvideKeySetOperation.h b/keychain/ckks/CKKSProvideKeySetOperation.h new file mode 100644 index 00000000..5ea8c2fe --- /dev/null +++ b/keychain/ckks/CKKSProvideKeySetOperation.h @@ -0,0 +1,33 @@ + +#if OCTAGON + +#import + +#import "keychain/ckks/CKKSCurrentKeyPointer.h" +#import "keychain/ckks/CKKSGroupOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol CKKSKeySetContainerProtocol +@property (readonly, nullable) CKKSCurrentKeySet* keyset; +@end + +@protocol CKKSKeySetProviderOperationProtocol +@property NSString* zoneName; +- (void)provideKeySet:(CKKSCurrentKeySet*)keyset; +@end + +// This is an odd operation: +// If you call initWithZoneName:keySet: and then add the operation to a queue, it will finish immediately. +// If you call initWithZoneName: and then add the operation to a queue, it will not start until provideKeySet runs. +// But! -timeout: will work, and the operation will finish +@interface CKKSProvideKeySetOperation : CKKSGroupOperation +- (instancetype)initWithZoneName:(NSString*)zoneName; +- (instancetype)initWithZoneName:(NSString*)zoneName keySet:(CKKSCurrentKeySet*)set; + +- (void)provideKeySet:(CKKSCurrentKeySet*)keyset; +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ckks/CKKSProvideKeySetOperation.m b/keychain/ckks/CKKSProvideKeySetOperation.m new file mode 100644 index 00000000..0ea2aa79 --- /dev/null +++ b/keychain/ckks/CKKSProvideKeySetOperation.m @@ -0,0 +1,48 @@ + +#if OCTAGON + +#import "CKKSProvideKeySetOperation.h" + +@interface CKKSProvideKeySetOperation () +@property (nullable) CKKSCurrentKeySet* keyset; + +@property (nullable) NSOperation* startDependency; +@end + +@implementation CKKSProvideKeySetOperation +@synthesize zoneName = _zoneName; +@synthesize keyset = _keyset; + +- (instancetype)initWithZoneName:(NSString*)zoneName +{ + if((self = [super init])) { + _zoneName = zoneName; + _keyset = nil; + _startDependency = [NSBlockOperation blockOperationWithBlock:^{}]; + + [self addDependency:_startDependency]; + } + return self; +} + +- (instancetype)initWithZoneName:(NSString*)zoneName keySet:(CKKSCurrentKeySet*)set +{ + if((self = [super init])) { + _zoneName = zoneName; + _keyset = set; + _startDependency = nil; + } + return self; +} + +- (void)provideKeySet:(CKKSCurrentKeySet *)keyset +{ + self.keyset = keyset; + if(self.startDependency) { + [[NSOperationQueue currentQueue] addOperation:self.startDependency]; + self.startDependency = nil; + } +} +@end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSRateLimiter.h b/keychain/ckks/CKKSRateLimiter.h index 5d290773..7921e45f 100644 --- a/keychain/ckks/CKKSRateLimiter.h +++ b/keychain/ckks/CKKSRateLimiter.h @@ -47,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN at:(NSDate*)time limitTime:(NSDate* _Nonnull __autoreleasing* _Nonnull)limitTime; -- (instancetype _Nullable)init; +- (instancetype)init; - (instancetype _Nullable)initWithCoder:(NSCoder* _Nullable)coder NS_DESIGNATED_INITIALIZER; - (NSUInteger)stateSize; - (void)reset; diff --git a/keychain/ckks/CKKSRateLimiter.m b/keychain/ckks/CKKSRateLimiter.m index 93ad4a4c..7eb34b36 100644 --- a/keychain/ckks/CKKSRateLimiter.m +++ b/keychain/ckks/CKKSRateLimiter.m @@ -48,14 +48,31 @@ typedef NS_ENUM(int, BucketType) { self = [super init]; if (self) { if (coder) { - _buckets = [coder decodeObjectOfClasses:[NSSet setWithObjects:[NSMutableDictionary class], - [NSString class], - [NSDate class], - nil] - forKey:@"buckets"]; + NSDictionary *encoded; + encoded = [coder decodeObjectOfClasses:[NSSet setWithObjects:[NSDictionary class], + [NSString class], + [NSDate class], + nil] + forKey:@"buckets"]; + + // Strongly enforce types for the dictionary + if (![encoded isKindOfClass:[NSDictionary class]]) { + return nil; + } + for (id key in encoded) { + if (![key isKindOfClass:[NSString class]]) { + return nil; + } + if (![encoded[key] isKindOfClass:[NSDate class]]) { + return nil; + } + } + _buckets = [encoded mutableCopy]; } else { _buckets = [NSMutableDictionary new]; } + + _overloadUntil = nil; // this should be done from a downloadable plist, rdar://problem/29945628 _config = [NSDictionary dictionaryWithObjectsAndKeys: @@ -185,7 +202,7 @@ 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]]; + self.overloadUntil = [self.buckets[@"All"] dateByAddingTimeInterval:[self.config[@"overloadDuration"] unsignedIntValue]]; seccritical("RateLimiter overloaded until %@", self.overloadUntil); } else { self.overloadUntil = nil; diff --git a/keychain/ckks/CKKSReachabilityTracker.h b/keychain/ckks/CKKSReachabilityTracker.h index 3b23dd2e..a492ac0a 100644 --- a/keychain/ckks/CKKSReachabilityTracker.h +++ b/keychain/ckks/CKKSReachabilityTracker.h @@ -24,23 +24,28 @@ #if OCTAGON #import -#import + +NS_ASSUME_NONNULL_BEGIN @class CKKSResultOperation; @interface CKKSReachabilityTracker : NSObject -@property CKKSResultOperation* reachabilityDependency; -@property (readonly) bool currentReachability; // get current reachability value w/o recheck +@property (nullable) CKKSResultOperation* reachabilityDependency; +@property (readonly) bool currentReachability; // get current reachability value - (instancetype)init; -- (void)recheck; + - (bool)isNetworkError:(NSError *)error; ++ (bool)isNetworkError:(NSError *)error; ++ (bool)isNetworkFailureError:(NSError *)error; -// only for testing override, the method will be call sync on an internal queue, -// so take that into consideration when you mock this class method. -+ (SCNetworkReachabilityFlags)getReachabilityFlags:(SCNetworkReachabilityRef)target; +// For testing only: +- (void)setNetworkReachability:(bool)reachable; @end + +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSReachabilityTracker.m b/keychain/ckks/CKKSReachabilityTracker.m index 3fd193ac..d13ecc3c 100644 --- a/keychain/ckks/CKKSReachabilityTracker.m +++ b/keychain/ckks/CKKSReachabilityTracker.m @@ -31,11 +31,14 @@ #import #import +#import + #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" +#import "keychain/ot/ObjCImprovements.h" // force reachability timeout every now and then #define REACHABILITY_TIMEOUT (12 * 3600 * NSEC_PER_SEC) @@ -44,21 +47,12 @@ @property bool haveNetwork; @property dispatch_queue_t queue; @property NSOperationQueue* operationQueue; -@property (assign) SCNetworkReachabilityRef reachability; +@property nw_path_monitor_t networkMonitor; @property dispatch_source_t timer; @end @implementation CKKSReachabilityTracker -static void -callout(SCNetworkReachabilityRef reachability, - SCNetworkReachabilityFlags flags, - void *context) -{ - CKKSReachabilityTracker *tracker = (__bridge id)context; - [tracker _onqueueRecheck:flags]; -} - - (instancetype)init { if((self = [super init])) { _queue = dispatch_queue_create("reachabiltity-tracker", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); @@ -68,31 +62,29 @@ callout(SCNetworkReachabilityRef reachability, [self _onQueueResetReachabilityDependency]; }); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); if(!SecCKKSTestsEnabled()) { - struct sockaddr_in zeroAddress; - bzero(&zeroAddress, sizeof(zeroAddress)); - zeroAddress.sin_len = sizeof(zeroAddress); - zeroAddress.sin_family = AF_INET; - - _reachability = SCNetworkReachabilityCreateWithAddress(NULL, (struct sockaddr *)&zeroAddress); - - SCNetworkReachabilityContext context = {0, (__bridge void *)(self), NULL, NULL, NULL}; - SCNetworkReachabilitySetDispatchQueue(_reachability, _queue); - SCNetworkReachabilitySetCallback(_reachability, callout, &context); + _networkMonitor = nw_path_monitor_create(); + nw_path_monitor_set_queue(self.networkMonitor, _queue); + nw_path_monitor_set_update_handler(self.networkMonitor, ^(nw_path_t _Nonnull path) { + STRONGIFY(self); + bool networkAvailable = (nw_path_get_status(path) == nw_path_status_satisfied); + + secinfo("ckksnetwork", "nw_path update: network is %@", networkAvailable ? @"available" : @"unavailable"); + [self _onqueueSetNetworkReachability:networkAvailable]; + }); + nw_path_monitor_start(self.networkMonitor); } - - [weakSelf recheck]; } return self; } --(NSString*)description { +- (NSString*)description { return [NSString stringWithFormat: @"", self.haveNetwork ? @"online" : @"offline"]; } --(bool)currentReachability { +- (bool)currentReachability { __block bool currentReachability = false; dispatch_sync(self.queue, ^{ currentReachability = self.haveNetwork; @@ -100,10 +92,10 @@ callout(SCNetworkReachabilityRef reachability, return currentReachability; } --(void)_onQueueRunreachabilityDependency +- (void)_onQueueRunReachabilityDependency { dispatch_assert_queue(self.queue); - // We're have network now, or timer expired, either way, execute dependency + // We have network now, or the timer expired. Either way, execute dependency if (self.reachabilityDependency) { [self.operationQueue addOperation: self.reachabilityDependency]; self.reachabilityDependency = nil; @@ -114,19 +106,16 @@ callout(SCNetworkReachabilityRef reachability, } } --(void)_onQueueResetReachabilityDependency { +- (void)_onQueueResetReachabilityDependency { dispatch_assert_queue(self.queue); if(self.reachabilityDependency == nil || ![self.reachabilityDependency isPending]) { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); secnotice("ckksnetwork", "Network unavailable"); self.reachabilityDependency = [CKKSResultOperation named:@"network-available-dependency" withBlock: ^{ - __typeof(self) strongSelf = weakSelf; - if (strongSelf == nil) { - return; - } - if (strongSelf.haveNetwork) { + STRONGIFY(self); + if (self.haveNetwork) { secnotice("ckksnetwork", "Network available"); } else { secnotice("ckksnetwork", "Network still not available, retrying after waiting %2.1f hours", @@ -142,13 +131,13 @@ callout(SCNetworkReachabilityRef reachability, (dispatch_source_timer_flags_t)0, self.queue); dispatch_source_set_event_handler(self.timer, ^{ - __typeof(self) strongSelf = weakSelf; - if (strongSelf == nil) { + STRONGIFY(self); + if (self == nil) { return; } - if (strongSelf.timer) { + if (self.timer) { [[CKKSAnalytics logger] noteEvent:CKKSEventReachabilityTimerExpired]; - [strongSelf _onQueueRunreachabilityDependency]; + [self _onQueueRunReachabilityDependency]; } }); @@ -160,51 +149,65 @@ callout(SCNetworkReachabilityRef reachability, } } --(void)_onqueueRecheck:(SCNetworkReachabilityFlags)flags { +- (void)_onqueueSetNetworkReachability:(bool)haveNetwork { dispatch_assert_queue(self.queue); - const SCNetworkReachabilityFlags reachabilityFlags = - kSCNetworkReachabilityFlagsReachable - | kSCNetworkReachabilityFlagsConnectionAutomatic -#if TARGET_OS_IPHONE - | kSCNetworkReachabilityFlagsIsWWAN -#endif - ; - bool hadNetwork = self.haveNetwork; - self.haveNetwork = !!(flags & reachabilityFlags); + self.haveNetwork = !!(haveNetwork); if(hadNetwork != self.haveNetwork) { if(self.haveNetwork) { // We're have network now - [self _onQueueRunreachabilityDependency]; + [self _onQueueRunReachabilityDependency]; } else { [self _onQueueResetReachabilityDependency]; } } } -+ (SCNetworkReachabilityFlags)getReachabilityFlags:(SCNetworkReachabilityRef)target +- (void)setNetworkReachability:(bool)reachable { - SCNetworkReachabilityFlags flags; - if (SCNetworkReachabilityGetFlags(target, &flags)) - return flags; - return 0; -} - --(void)recheck { dispatch_sync(self.queue, ^{ - SCNetworkReachabilityFlags flags = [CKKSReachabilityTracker getReachabilityFlags:self.reachability]; - [self _onqueueRecheck:flags]; + [self _onqueueSetNetworkReachability:reachable]; }); } --(bool)isNetworkError:(NSError *)error { - if (error == nil) +- (bool)isNetworkError:(NSError *)error { + return [CKKSReachabilityTracker isNetworkError:error]; +} + ++ (bool)isNetworkError:(NSError *)error { + if (error == nil) { return false; - return ([error.domain isEqualToString:CKErrorDomain] && - (error.code == CKErrorNetworkUnavailable - || error.code == CKErrorNetworkFailure)); + } + + if([CKKSReachabilityTracker isNetworkFailureError:error]) { + return true; + } + + if ([error.domain isEqualToString:CKErrorDomain] && + (error.code == CKErrorNetworkUnavailable)) { + return true; + } + + if ([error.domain isEqualToString:NSURLErrorDomain] && + error.code == NSURLErrorTimedOut) { + return true; + } + + return false; +} + ++ (bool)isNetworkFailureError:(NSError *)error +{ + if (error == nil) { + return false; + } + if ([error.domain isEqualToString:CKErrorDomain] && error.code == CKErrorNetworkFailure) { + return true; + } + + return false; } @end diff --git a/keychain/ckks/CKKSRecordHolder.h b/keychain/ckks/CKKSRecordHolder.h index 81e24714..5c52de66 100644 --- a/keychain/ckks/CKKSRecordHolder.h +++ b/keychain/ckks/CKKSRecordHolder.h @@ -30,8 +30,6 @@ NS_ASSUME_NONNULL_BEGIN -@class CKKSWrappedAESSIVKey; - // Helper class that includes a single encoded CKRecord @interface CKKSCKRecordHolder : CKKSSQLDatabaseObject @@ -40,8 +38,8 @@ NS_ASSUME_NONNULL_BEGIN encodedCKRecord:(NSData* _Nullable)encodedCKRecord zoneID:(CKRecordZoneID*)zoneID; -@property (copy) CKRecordZoneID* zoneID; -@property (copy) NSString* ckRecordType; +@property CKRecordZoneID* zoneID; +@property NSString* ckRecordType; @property (nullable, copy) NSData* encodedCKRecord; @property (nullable, getter=storedCKRecord, setter=setStoredCKRecord:) CKRecord* storedCKRecord; diff --git a/keychain/ckks/CKKSRecordHolder.m b/keychain/ckks/CKKSRecordHolder.m index 34bca844..6d424fa6 100644 --- a/keychain/ckks/CKKSRecordHolder.m +++ b/keychain/ckks/CKKSRecordHolder.m @@ -41,7 +41,7 @@ - (instancetype) initWithCKRecord: (CKRecord*) record { if(self = [super init]) { - self.zoneID = record.recordID.zoneID; + _zoneID = record.recordID.zoneID; [self setFromCKRecord:record]; } return self; diff --git a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.h b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.h index 6cd17a24..e8947de5 100644 --- a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.h +++ b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.h @@ -26,6 +26,8 @@ #import #import "keychain/ckks/CKKSGroupOperation.h" +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; @interface CKKSReencryptOutgoingItemsOperation : CKKSResultOperation @@ -37,4 +39,6 @@ @end +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m index 410cfbf2..6727f3bb 100644 --- a/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m +++ b/keychain/ckks/CKKSReencryptOutgoingItemsOperation.m @@ -29,7 +29,9 @@ #import "keychain/ckks/CKKSReencryptOutgoingItemsOperation.h" #import "keychain/ckks/CKKSItemEncrypter.h" #import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKSAnalytics.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/analytics/CKKSPowerCollection.h" #if OCTAGON @@ -83,6 +85,8 @@ return false; } + [CKKSPowerCollection CKKSPowerEvent:kCKKSPowerEventReencryptOutgoing zone:ckks.zoneName count:oqes.count]; + for(CKKSOutgoingQueueEntry* oqe in oqes) { // If there's already a 'new' item replacing this one, drop the reencryption on the floor CKKSOutgoingQueueEntry* newOQE = [CKKSOutgoingQueueEntry tryFromDatabase:oqe.uuid state:SecCKKSStateNew zoneID:oqe.item.zoneID error:&error]; @@ -110,7 +114,7 @@ NSDictionary* item = [CKKSItemEncrypter decryptItemToDictionary: oqe.item error:&error]; if(error) { if ([error.domain isEqualToString:@"securityd"] && error.code == errSecItemNotFound) { - ckkserror("ckksreencrypt", ckks, "Coudn't find key in keychain; attempting to poke key hierarchy: %@", error); + ckkserror("ckksreencrypt", ckks, "Couldn't find key in keychain; attempting to poke key hierarchy: %@", error); [ckks.pokeKeyStateMachineScheduler trigger]; } else { ckkserror("ckksreencrypt", ckks, "Couldn't decrypt item %@: %@", oqe, error); @@ -178,6 +182,13 @@ newItems = true; } + CKKSAnalytics* logger = [CKKSAnalytics logger]; + if (self.error) { + [logger logRecoverableError:error forEvent:CKKSEventProcessReencryption inView:ckks withAttributes:nil]; + } else { + [logger logSuccessForEvent:CKKSEventProcessReencryption inView:ckks]; + } + if(newItems) { [ckks processOutgoingQueue:self.ckoperationGroup]; } diff --git a/keychain/ckks/CKKSResultOperation.m b/keychain/ckks/CKKSResultOperation.m index e36f1af6..1c107b4f 100644 --- a/keychain/ckks/CKKSResultOperation.m +++ b/keychain/ckks/CKKSResultOperation.m @@ -27,6 +27,7 @@ #import "keychain/ckks/NSOperationCategories.h" #import "keychain/ckks/CKKSCondition.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" #include @interface CKKSResultOperation() @@ -39,15 +40,16 @@ @implementation CKKSResultOperation - (instancetype)init { if(self = [super init]) { + WEAKIFY(self); _error = nil; _successDependencies = [[NSMutableArray alloc] init]; _timeoutCanOccur = true; _timeoutQueue = dispatch_queue_create("result-operation-timeout", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _completionHandlerDidRunCondition = [[CKKSCondition alloc] init]; - __weak __typeof(self) weakSelf = self; _finishingBlock = ^(void) { - weakSelf.finishDate = [NSDate dateWithTimeIntervalSinceNow:0]; + STRONGIFY(self); + self.finishDate = [NSDate dateWithTimeIntervalSinceNow:0]; }; self.completionBlock = ^{}; // our _finishing block gets added in the method override } @@ -62,14 +64,22 @@ @"pending"); } + - (NSString*)description { + static __thread unsigned __descriptionRecursion = 0; NSString* state = [self operationStateString]; + NSString *desc = NULL; - if(self.error) { - return [NSString stringWithFormat: @"<%@: %@ error:%@>", [self selfname], state, self.error]; + __descriptionRecursion++; + if(__descriptionRecursion > 10) { + desc = [NSString stringWithFormat: @"<%@: %@ recursion>", [self selfname], state]; + } else if(self.error) { + desc = [NSString stringWithFormat: @"<%@: %@ error:%@>", [self selfname], state, self.error]; } else { - return [NSString stringWithFormat: @"<%@: %@%@>", [self selfname], state, [self pendingDependenciesString:@" dep:"]]; + desc = [NSString stringWithFormat: @"<%@: %@%@>", [self selfname], state, [self pendingDependenciesString:@" dep:"]]; } + __descriptionRecursion--; + return desc; } - (NSString*)debugDescription { @@ -78,21 +88,21 @@ - (void)setCompletionBlock:(void (^)(void))completionBlock { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); [super setCompletionBlock:^(void) { - __strong __typeof(self) strongSelf = weakSelf; - if (!strongSelf) { + STRONGIFY(self); + if (!self) { secerror("ckksresultoperation: completion handler called on deallocated operation instance"); completionBlock(); // go ahead and still behave as things would if this method override were not here return; } - strongSelf.finishingBlock(); + self.finishingBlock(); completionBlock(); - [strongSelf.completionHandlerDidRunCondition fulfill]; + [self.completionHandlerDidRunCondition fulfill]; - for (NSOperation *op in strongSelf.dependencies) { - [strongSelf removeDependency:op]; + for (NSOperation *op in self.dependencies) { + [self removeDependency:op]; } }]; } @@ -163,13 +173,13 @@ } - (instancetype)timeout:(dispatch_time_t)timeout { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeout), self.timeoutQueue, ^{ - __strong __typeof(self) strongSelf = weakSelf; - if(strongSelf.timeoutCanOccur) { - strongSelf.error = [self _onqueueTimeoutError]; - strongSelf.timeoutCanOccur = false; - [strongSelf cancel]; + STRONGIFY(self); + if(self.timeoutCanOccur) { + self.error = [self _onqueueTimeoutError]; + self.timeoutCanOccur = false; + [self cancel]; } }); @@ -236,20 +246,20 @@ } + (CKKSResultOperation*)operationWithBlock:(void (^)(void))block { - CKKSResultOperation* op = [[CKKSResultOperation alloc] init]; + CKKSResultOperation* op = [[self alloc] init]; [op addExecutionBlock: block]; return op; } -+(instancetype)named:(NSString*)name withBlock:(void(^)(void)) block { - CKKSResultOperation* blockOp = [CKKSResultOperation operationWithBlock: block]; ++ (instancetype)named:(NSString*)name withBlock:(void(^)(void)) block { + CKKSResultOperation* blockOp = [self operationWithBlock: block]; blockOp.name = name; return blockOp; } + (instancetype)named:(NSString*)name withBlockTakingSelf:(void(^)(CKKSResultOperation* op))block { - CKKSResultOperation* op = [[CKKSResultOperation alloc] init]; + CKKSResultOperation* op = [[self alloc] init]; __weak __typeof(op) weakOp = op; [op addExecutionBlock:^{ __strong __typeof(op) strongOp = weakOp; diff --git a/keychain/ckks/CKKSSIV.h b/keychain/ckks/CKKSSIV.h index db1cc3a9..718954e8 100644 --- a/keychain/ckks/CKKSSIV.h +++ b/keychain/ckks/CKKSSIV.h @@ -25,6 +25,8 @@ #import +NS_ASSUME_NONNULL_BEGIN + // For AES-SIV 512. #define CKKSKeySize (512 / 8) @@ -39,33 +41,38 @@ - (instancetype)init; - (instancetype)initWithBytes:(uint8_t*)bytes len:(size_t)len; - (void)zeroKey; -- (instancetype)copyWithZone:(NSZone*)zone; +- (instancetype)copyWithZone:(NSZone* _Nullable)zone; // Mostly for testing. - (instancetype)initWithBase64:(NSString*)base64bytes; -- (BOOL)isEqual:(id)object; +- (BOOL)isEqual:(id _Nullable)object; @end -@interface CKKSWrappedAESSIVKey : CKKSBaseAESSIVKey +@interface CKKSWrappedAESSIVKey : CKKSBaseAESSIVKey - (instancetype)initWithData:(NSData*)data; - (NSData*)wrappedData; - (NSString*)base64WrappedKey; @end @interface CKKSAESSIVKey : CKKSBaseAESSIVKey -+ (instancetype)randomKey; ++ (instancetype _Nullable)randomKey:(NSError*__autoreleasing*)error; + +- (CKKSWrappedAESSIVKey* _Nullable)wrapAESKey:(CKKSAESSIVKey*)keyToWrap + error:(NSError* __autoreleasing*)error; -- (CKKSWrappedAESSIVKey*)wrapAESKey:(CKKSAESSIVKey*)keyToWrap error:(NSError* __autoreleasing*)error; -- (CKKSAESSIVKey*)unwrapAESKey:(CKKSWrappedAESSIVKey*)keyToUnwrap error:(NSError* __autoreleasing*)error; +- (CKKSAESSIVKey* _Nullable)unwrapAESKey:(CKKSWrappedAESSIVKey*)keyToUnwrap + error:(NSError* __autoreleasing*)error; // Encrypt and decrypt data into buffers. Adds a nonce for ciphertext protection. -- (NSData*)encryptData:(NSData*)plaintext - authenticatedData:(NSDictionary*)ad - error:(NSError* __autoreleasing*)error; -- (NSData*)decryptData:(NSData*)ciphertext - authenticatedData:(NSDictionary*)ad - error:(NSError* __autoreleasing*)error; +- (NSData* _Nullable)encryptData:(NSData*)plaintext + authenticatedData:(NSDictionary* _Nullable)ad + error:(NSError* __autoreleasing*)error; +- (NSData* _Nullable)decryptData:(NSData*)ciphertext + authenticatedData:(NSDictionary* _Nullable)ad + error:(NSError* __autoreleasing*)error; @end +NS_ASSUME_NONNULL_END + #endif // OCTAGON diff --git a/keychain/ckks/CKKSSIV.m b/keychain/ckks/CKKSSIV.m index cba130bb..dde5f3c1 100644 --- a/keychain/ckks/CKKSSIV.m +++ b/keychain/ckks/CKKSSIV.m @@ -28,6 +28,7 @@ #import #import +#import #import "CKKSSIV.h" @@ -145,6 +146,27 @@ return [[self wrappedData] base64EncodedStringWithOptions:0]; } ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder *)coder { + [coder encodeBytes:self->key length:self->size forKey:@"wrappedkey"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder { + self = [super init]; + if (self) { + NSUInteger len = 0; + const uint8_t * bytes = [decoder decodeBytesForKey:@"wrappedkey" returnedLength:&len]; + + if(bytes) { + memcpy(self->key, bytes, (size_t) len <= CKKSWrappedKeySize ? len : CKKSWrappedKeySize); + } + } + return self; +} + @end @implementation CKKSAESSIVKey @@ -177,15 +199,18 @@ return self; } -+ (instancetype)randomKey { ++ (instancetype _Nullable)randomKey:(NSError* __autoreleasing *)error +{ CKKSAESSIVKey* key = [[CKKSAESSIVKey alloc] init]; CCRNGStatus status = CCRandomGenerateBytes(key->key, key->size); if(status != kCCSuccess) { - @throw [NSException - exceptionWithName:@"randomnessException" - reason:[NSString stringWithFormat: @"CCRandomGenerateBytes failed with %d", status] - userInfo:nil]; + if(error) { + *error = [NSError errorWithDomain:@"corecrypto" + code:status + description:[NSString stringWithFormat: @"CCRandomGenerateBytes failed with %d", status]]; + } + return nil; } return key; @@ -196,7 +221,7 @@ bool success = false; if(!keyToWrap) { - localerror = [NSError errorWithDomain:@"securityd" + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam description:@"No key given"]; if(error) { @@ -209,14 +234,15 @@ uint8_t buffer[CKKSWrappedKeySize] = {}; size_t ciphertextLength = ccsiv_ciphertext_size(ccaes_siv_encrypt_mode(), CKKSKeySize); - require_action_quiet(ciphertextLength == CKKSWrappedKeySize, out, localerror = [NSError errorWithDomain:@"securityd" + require_action_quiet(ciphertextLength == CKKSWrappedKeySize, out, localerror = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey: @"wrapped key size does not match key size"}]); success = [self doSIV: ccaes_siv_encrypt_mode() nonce: nil - text: [[NSData alloc] initWithBytesNoCopy: (void*) (keyToWrap->key) length: keyToWrap->size freeWhenDone: NO] - buffer: buffer bufferLength: sizeof(buffer) + text: [NSData _newZeroingDataWithBytes:(void*) (keyToWrap->key) length:keyToWrap->size] + buffer: buffer + bufferLength: sizeof(buffer) authenticatedData: nil error: error]; require_quiet(success, out); @@ -238,7 +264,7 @@ out: uint8_t buffer[CKKSKeySize] = {}; size_t plaintextLength = ccsiv_plaintext_size(ccaes_siv_decrypt_mode(), CKKSWrappedKeySize); - require_action_quiet(plaintextLength == CKKSKeySize, out, localerror = [NSError errorWithDomain:@"securityd" + require_action_quiet(plaintextLength == CKKSKeySize, out, localerror = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam userInfo:@{NSLocalizedDescriptionKey: @"unwrapped key size does not match key size"}]); @@ -321,7 +347,7 @@ out: nonceLength = (128/8); if(ciphertext.length <= nonceLength) { if(error) { - *error = [NSError errorWithDomain:@"securityd" + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:4 userInfo:@{NSLocalizedDescriptionKey: @"ciphertext too short"}]; } @@ -361,7 +387,7 @@ out: ccsiv_ctx_decl(mode->size, ctx); - require_action_quiet(mode, out, localerror = [NSError errorWithDomain:@"securityd" + require_action_quiet(mode, out, localerror = [NSError errorWithDomain:NSOSStatusErrorDomain code:1 userInfo:@{NSLocalizedDescriptionKey: @"no mode given"}]); diff --git a/keychain/ckks/CKKSSQLDatabaseObject.h b/keychain/ckks/CKKSSQLDatabaseObject.h index efa8c45c..976404b5 100644 --- a/keychain/ckks/CKKSSQLDatabaseObject.h +++ b/keychain/ckks/CKKSSQLDatabaseObject.h @@ -29,11 +29,6 @@ id o = (obj); \ o ? o : [NSNull null]; \ }) -#define CKKSNSNullToNil(obj) \ - ({ \ - id o = (obj); \ - ([o isEqual:[NSNull null]]) ? nil : o; \ - }) #define CKKSIsNull(x) \ ({ \ @@ -44,6 +39,20 @@ NS_ASSUME_NONNULL_BEGIN +// A holder of a possibly-present string value. +// Also includes some convenience methods for parsing the string in different manners. +// If the value is nil, then the convenience methods return nil (or false/0). +@interface CKKSSQLResult : NSObject +- (instancetype)init:(NSString* _Nullable)value; + +- (BOOL)asBOOL; +- (NSInteger)asNSInteger; +- (NSString* _Nullable)asString; +- (NSNumber* _Nullable)asNSNumberInteger; +- (NSDate* _Nullable)asISO8601Date; +- (NSData* _Nullable)asBase64DecodedData; +@end + @interface CKKSSQLDatabaseObject : NSObject @property (copy) NSDictionary* originalSelfWhereClause; @@ -90,23 +99,25 @@ NS_ASSUME_NONNULL_BEGIN groupBy:(NSArray* _Nullable)groupColumns orderBy:(NSArray* _Nullable)orderColumns limit:(ssize_t)limit - processRow:(void (^)(NSDictionary*))processRow + processRow:(void (^)(NSDictionary*))processRow error:(NSError* _Nullable __autoreleasing* _Nullable)error; + (bool)queryMaxValueForField:(NSString*)maxField inTable:(NSString*)table where:(NSDictionary* _Nullable)whereDict columns:(NSArray*)names - processRow:(void (^)(NSDictionary*))processRow; + processRow:(void (^)(NSDictionary*))processRow; // Note: if you don't use the SQLDatabase methods of loading yourself, // make sure you call this directly after loading. - (instancetype)memoizeOriginalSelfWhereClause; ++ (NSString *)quotedString:(NSString *)string; + #pragma mark - Subclasses must implement the following: // Given a row from the database, make this object -+ (instancetype _Nullable)fromDatabaseRow:(NSDictionary*)row; ++ (instancetype _Nullable)fromDatabaseRow:(NSDictionary*)row; // Return the columns, in order, that this row wants to fetch + (NSArray*)sqlColumns; diff --git a/keychain/ckks/CKKSSQLDatabaseObject.m b/keychain/ckks/CKKSSQLDatabaseObject.m index 8e6ab086..6313ac65 100644 --- a/keychain/ckks/CKKSSQLDatabaseObject.m +++ b/keychain/ckks/CKKSSQLDatabaseObject.m @@ -28,6 +28,61 @@ #import "keychain/ckks/CKKS.h" #import "CKKSKeychainView.h" +@interface CKKSSQLResult () +@property (nullable) NSString* stringValue; +@end + +@implementation CKKSSQLResult +- (instancetype)init:(NSString* _Nullable)value +{ + if((self = [super init])) { + _stringValue = value; + } + return self; +} + +- (BOOL)asBOOL +{ + return [self.stringValue boolValue]; +} + +- (NSInteger)asNSInteger +{ + return [self.stringValue integerValue]; +} + +- (NSString* _Nullable)asString +{ + return self.stringValue; +} + +- (NSNumber* _Nullable)asNSNumberInteger +{ + if(self.stringValue == nil) { + return nil; + } + return [NSNumber numberWithInteger: [self.stringValue integerValue]]; +} + +- (NSDate* _Nullable)asISO8601Date +{ + if(self.stringValue == nil) { + return nil; + } + + NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; + return [dateFormat dateFromString:self.stringValue]; +} + +- (NSData* _Nullable)asBase64DecodedData +{ + if(self.stringValue == nil) { + return nil; + } + return [[NSData alloc] initWithBase64EncodedString:self.stringValue options:0]; +} +@end + @implementation CKKSSQLDatabaseObject + (bool) saveToDatabaseTable: (NSString*) table row: (NSDictionary*) row connection: (SecDbConnectionRef) dbconn error: (NSError * __autoreleasing *) error { @@ -180,14 +235,14 @@ return status; } -+ (bool) queryDatabaseTable:(NSString*) table - where:(NSDictionary*) whereDict - columns:(NSArray*) names - groupBy:(NSArray*) groupColumns - orderBy:(NSArray*) orderColumns - limit:(ssize_t)limit - processRow:(void (^)(NSDictionary*)) processRow - error:(NSError * __autoreleasing *) error { ++ (bool)queryDatabaseTable:(NSString*)table + where:(NSDictionary*)whereDict + columns:(NSArray*)names + groupBy:(NSArray*)groupColumns + orderBy:(NSArray*)orderColumns + limit:(ssize_t)limit + processRow:(void (^)(NSDictionary*)) processRow + error:(NSError * __autoreleasing *) error { __block CFErrorRef cferror = NULL; kc_with_dbt(true, &cferror, ^bool (SecDbConnectionRef dbconn) { @@ -209,11 +264,11 @@ }]; SecDbStep(dbconn, stmt, &cferror, ^(bool *stop) { - __block NSMutableDictionary* row = [[NSMutableDictionary alloc] init]; + __block NSMutableDictionary* row = [[NSMutableDictionary alloc] init]; [names enumerateObjectsUsingBlock:^(id _Nonnull name, NSUInteger i, BOOL * _Nonnull stop) { const char * col = (const char *) sqlite3_column_text(stmt, (int)i); - row[name] = col ? [NSString stringWithUTF8String:col] : [NSNull null]; + row[name] = [[CKKSSQLResult alloc] init:col ? [NSString stringWithUTF8String:col] : nil]; }]; processRow(row); @@ -227,15 +282,38 @@ return ret; } -+ (bool)queryMaxValueForField:(NSString*)maxField inTable:(NSString*)table where:(NSDictionary*)whereDict columns:(NSArray*)names processRow:(void (^)(NSDictionary*))processRow ++ (NSString *)quotedString:(NSString *)string +{ + char *quotedMaxField = sqlite3_mprintf("%q", [string UTF8String]); + if (quotedMaxField == NULL) { + abort(); + } + NSString *rstring = [NSString stringWithUTF8String:quotedMaxField]; + sqlite3_free(quotedMaxField); + return rstring; +} + ++ (bool)queryMaxValueForField:(NSString*)maxField + inTable:(NSString*)table + where:(NSDictionary*)whereDict + columns:(NSArray*)names + processRow:(void (^)(NSDictionary*))processRow { __block CFErrorRef cferror = NULL; - + kc_with_dbt(false, &cferror, ^bool(SecDbConnectionRef dbconn) { - NSString* columns = [[names componentsJoinedByString:@", "] stringByAppendingFormat:@", %@", maxField]; + NSString *quotedMaxField = [self quotedString:maxField]; + NSString *quotedTable = [self quotedString:table]; + + NSMutableArray* quotedNames = [NSMutableArray array]; + for (NSString *element in names) { + [quotedNames addObject:[self quotedString:element]]; + } + + NSString* columns = [[quotedNames componentsJoinedByString:@", "] stringByAppendingFormat:@", %@", quotedMaxField]; NSString* whereClause = [CKKSSQLDatabaseObject makeWhereClause:whereDict]; - NSString* sql = [[NSString alloc] initWithFormat:@"SELECT %@ FROM %@%@", columns, table, whereClause]; + NSString* sql = [[NSString alloc] initWithFormat:@"SELECT %@ FROM %@%@", columns, quotedTable, whereClause]; SecDbPrepare(dbconn, (__bridge CFStringRef)sql, &cferror, ^(sqlite3_stmt* stmt) { [whereDict.allKeys enumerateObjectsUsingBlock:^(id _Nonnull key, NSUInteger i, BOOL* _Nonnull stop) { if ([whereDict[key] class] != [CKKSSQLWhereObject class]) { @@ -244,11 +322,11 @@ }]; SecDbStep(dbconn, stmt, &cferror, ^(bool*stop) { - __block NSMutableDictionary* row = [[NSMutableDictionary alloc] init]; + __block NSMutableDictionary* row = [[NSMutableDictionary alloc] init]; [names enumerateObjectsUsingBlock:^(id _Nonnull name, NSUInteger i, BOOL * _Nonnull stop) { const char * col = (const char *) sqlite3_column_text(stmt, (int)i); - row[name] = col ? [NSString stringWithUTF8String:col] : [NSNull null]; + row[name] = [[CKKSSQLResult alloc] init:col ? [NSString stringWithUTF8String:col] : nil]; }]; processRow(row); @@ -338,7 +416,7 @@ groupBy: nil orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { + processRow: ^(NSDictionary* row) { ret = [[self fromDatabaseRow: row] memoizeOriginalSelfWhereClause]; } error: error]; @@ -359,7 +437,7 @@ groupBy: nil orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { + processRow: ^(NSDictionary* row) { [items addObject: [[self fromDatabaseRow: row] memoizeOriginalSelfWhereClause]]; } error: error]; @@ -387,7 +465,7 @@ groupBy:nil orderBy:orderColumns limit: (ssize_t) count - processRow: ^(NSDictionary* row) { + processRow: ^(NSDictionary* row) { [items addObject: [[self fromDatabaseRow: row] memoizeOriginalSelfWhereClause]]; } error: error]; @@ -402,7 +480,7 @@ #pragma mark - Subclass methods -+ (instancetype) fromDatabaseRow:(NSDictionary *)row { ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:[NSString stringWithFormat:@"A subclass must override %@", NSStringFromSelector(_cmd)] userInfo:nil]; diff --git a/keychain/ckks/CKKSScanLocalItemsOperation.h b/keychain/ckks/CKKSScanLocalItemsOperation.h index 2f2d2705..a35a240d 100644 --- a/keychain/ckks/CKKSScanLocalItemsOperation.h +++ b/keychain/ckks/CKKSScanLocalItemsOperation.h @@ -27,6 +27,8 @@ #if OCTAGON +NS_ASSUME_NONNULL_BEGIN + @class CKKSKeychainView; @class CKKSEgoManifest; @@ -43,4 +45,5 @@ @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSScanLocalItemsOperation.m b/keychain/ckks/CKKSScanLocalItemsOperation.m index 132c7dd5..6c4fe803 100644 --- a/keychain/ckks/CKKSScanLocalItemsOperation.m +++ b/keychain/ckks/CKKSScanLocalItemsOperation.m @@ -34,6 +34,7 @@ #import "keychain/ckks/CKKSKey.h" #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSManifest.h" +#import "keychain/ckks/CKKSItemEncrypter.h" #import "CKKSPowerCollection.h" @@ -73,6 +74,8 @@ return; } + [ckks.launch addEvent:@"scan-local-items"]; + [ckks dispatchSyncWithAccountKeys: ^bool{ if(self.cancelled) { ckksnotice("ckksscan", ckks, "CKKSScanLocalItemsOperation cancelled, quitting"); @@ -189,7 +192,13 @@ } [mirrorUUIDs removeObject:uuid]; ckksinfo("ckksscan", ckks, "Existing mirror entry with UUID %@", uuid); - return; + + if([self areEquivalent:item ckksItem:ckme.item]) { + // Fair enough. + return; + } else { + ckksnotice("ckksscan", ckks, "Existing mirror entry with UUID %@ does not match local item", uuid); + } } // We don't care about the oqe state here, just that one exists @@ -329,6 +338,49 @@ }]; } +- (BOOL)areEquivalent:(SecDbItemRef)item ckksItem:(CKKSItem*)ckksItem +{ + CKKSKeychainView* ckks = self.ckks; + + NSError* localerror = nil; + NSDictionary* attributes = [CKKSIncomingQueueOperation decryptCKKSItemToAttributes:ckksItem error:&localerror]; + if(!attributes || localerror) { + ckksnotice("ckksscan", ckks, "Could not decrypt item for comparison: %@", localerror); + return YES; + } + + CFErrorRef cferror = NULL; + NSDictionary* objdict = (NSMutableDictionary*)CFBridgingRelease(SecDbItemCopyPListWithMask(item, kSecDbSyncFlag, &cferror)); + localerror = (NSError*)CFBridgingRelease(cferror); + + if(!objdict || localerror) { + ckksnotice("ckksscan", ckks, "Could not get item contents for comparison: %@", localerror); + + // Fail open: assert that this item doesn't match + return NO; + } + + for(id key in objdict) { + // Okay, but seriously storing dates as floats was a mistake. + // Don't compare cdat and mdat, as they'll usually be different. + // Also don't compare the sha1, as it hashes that double. + if([key isEqual:(__bridge id)kSecAttrCreationDate] || + [key isEqual:(__bridge id)kSecAttrModificationDate] || + [key isEqual:(__bridge id)kSecAttrSHA1]) { + continue; + } + + id value = objdict[key]; + id attributesValue = attributes[key]; + + if(![value isEqual:attributesValue]) { + return NO; + } + } + + return YES; +} + @end; #endif diff --git a/keychain/ckks/CKKSSynchronizeOperation.h b/keychain/ckks/CKKSSynchronizeOperation.h index cb6cbd6b..0d510232 100644 --- a/keychain/ckks/CKKSSynchronizeOperation.h +++ b/keychain/ckks/CKKSSynchronizeOperation.h @@ -25,6 +25,7 @@ #import "keychain/ckks/CKKSGroupOperation.h" #if OCTAGON +NS_ASSUME_NONNULL_BEGIN @class CKKSKeychainView; @@ -36,4 +37,5 @@ @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSSynchronizeOperation.m b/keychain/ckks/CKKSSynchronizeOperation.m index 85c6b41d..f507bcb6 100644 --- a/keychain/ckks/CKKSSynchronizeOperation.m +++ b/keychain/ckks/CKKSSynchronizeOperation.m @@ -28,6 +28,7 @@ #import "CKKSScanLocalItemsOperation.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" #if OCTAGON @@ -49,7 +50,7 @@ } - (void)groupStart { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); /* * Synchronizations (or resynchronizations) are complicated beasts. We will: @@ -83,89 +84,67 @@ ckks.lastSynchronizeOperation = self; - uint32_t steps = 7; + uint32_t steps = 5; - ckksinfo("ckksresync", ckks, "Beginning resynchronize (attempt %u)", self.restartCount); + ckksnotice("ckksresync", ckks, "Beginning resynchronize (attempt %u)", self.restartCount); CKOperationGroup* operationGroup = [CKOperationGroup CKKSGroupWithName:@"ckks-resync"]; // Step 1 - CKKSOutgoingQueueOperation* outgoingOp = [ckks processOutgoingQueue: operationGroup]; - outgoingOp.name = [NSString stringWithFormat: @"resync-step%u-outgoing", self.restartCount * steps + 1]; - [self dependOnBeforeGroupFinished:outgoingOp]; - - // Step 2 CKKSFetchAllRecordZoneChangesOperation* fetchOp = [[CKKSFetchAllRecordZoneChangesOperation alloc] initWithContainer:ckks.container - fetchClass:ckks.fetchRecordZoneChangesOperationClass + fetchClass:ckks.cloudKitClassDependencies.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]; + fetchOp.name = [NSString stringWithFormat: @"resync-step%u-fetch", self.restartCount * steps + 1]; [self runBeforeGroupFinished: fetchOp]; - // Step 3 + // Step 2 CKKSIncomingQueueOperation* incomingOp = [[CKKSIncomingQueueOperation alloc] initWithCKKSKeychainView:ckks errorOnClassAFailure:true]; - incomingOp.name = [NSString stringWithFormat: @"resync-step%u-incoming", self.restartCount * steps + 3]; + incomingOp.name = [NSString stringWithFormat: @"resync-step%u-incoming", self.restartCount * steps + 2]; [incomingOp addSuccessDependency:fetchOp]; [self runBeforeGroupFinished:incomingOp]; - // Now, get serious: - - // Step 4 - 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]; - [self runBeforeGroupFinished: fetchAllOp]; - - // Step 5 - CKKSIncomingQueueOperation* incomingResyncOp = [[CKKSIncomingQueueOperation alloc] initWithCKKSKeychainView:ckks errorOnClassAFailure:true]; - incomingResyncOp.name = [NSString stringWithFormat: @"resync-step%u-incoming", self.restartCount * steps + 5]; - [incomingResyncOp addSuccessDependency: fetchAllOp]; - [self runBeforeGroupFinished:incomingResyncOp]; - - // Step 6 + // Step 3 CKKSScanLocalItemsOperation* scan = [[CKKSScanLocalItemsOperation alloc] initWithCKKSKeychainView:ckks ckoperationGroup:operationGroup]; - scan.name = [NSString stringWithFormat: @"resync-step%u-scan", self.restartCount * steps + 6]; - [scan addSuccessDependency: incomingResyncOp]; + scan.name = [NSString stringWithFormat: @"resync-step%u-scan", self.restartCount * steps + 3]; + [scan addSuccessDependency: incomingOp]; [self runBeforeGroupFinished: scan]; - // Step 7: + // Step 4 + CKKSOutgoingQueueOperation* outgoingOp = [ckks processOutgoingQueue: operationGroup]; + outgoingOp.name = [NSString stringWithFormat: @"resync-step%u-outgoing", self.restartCount * steps + 4]; + [self dependOnBeforeGroupFinished:outgoingOp]; + + // Step 5: CKKSResultOperation* restart = [[CKKSResultOperation alloc] init]; - restart.name = [NSString stringWithFormat: @"resync-step%u-consider-restart", self.restartCount * steps + 7]; + restart.name = [NSString stringWithFormat: @"resync-step%u-consider-restart", self.restartCount * steps + 5]; [restart addExecutionBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckksresync: received callback for released object"); return; } if(scan.recordsFound > 0) { - if(strongSelf.restartCount >= 3) { + if(self.restartCount >= 3) { // we've restarted too many times. Fail and stop. ckkserror("ckksresync", ckks, "restarted synchronization too often; Failing"); - strongSelf.error = [NSError errorWithDomain:@"securityd" + self.error = [NSError errorWithDomain:@"securityd" code:2 userInfo:@{NSLocalizedDescriptionKey: @"resynchronization restarted too many times; churn in database?"}]; } else { // restart the sync operation. - strongSelf.restartCount += 1; + self.restartCount += 1; ckkserror("ckksresync", ckks, "restarting synchronization operation due to new local items"); - [strongSelf groupStart]; + [self groupStart]; } } }]; - [restart addSuccessDependency: scan]; + [restart addSuccessDependency: outgoingOp]; [self runBeforeGroupFinished: restart]; return true; diff --git a/keychain/ckks/CKKSTLKShare.h b/keychain/ckks/CKKSTLKShare.h index 18f590a8..eb4de292 100644 --- a/keychain/ckks/CKKSTLKShare.h +++ b/keychain/ckks/CKKSTLKShare.h @@ -24,15 +24,13 @@ #if OCTAGON #import +#import +#import #import "keychain/ckks/CKKS.h" -#import "keychain/ckks/CKKSItem.h" -#import "keychain/ckks/CKKSKey.h" +#import "keychain/ckks/CKKSKeychainBackedKey.h" #import "keychain/ckks/CKKSPeer.h" -#import -#import - NS_ASSUME_NONNULL_BEGIN typedef NS_ENUM(NSUInteger, SecCKKSTLKShareVersion) { @@ -42,14 +40,19 @@ typedef NS_ENUM(NSUInteger, SecCKKSTLKShareVersion) { #define SecCKKSTLKShareCurrentVersion SecCKKSTLKShareVersion0 +// Note that a CKKSTLKShare attempts to be forward-compatible with newly-signed fields +// To use this functionality, pass in a CKRecord to its interfaces. If it has extra data, +// that data will be signed or its signature verified. -@interface CKKSTLKShare : CKKSCKRecordHolder +@interface CKKSTLKShare : NSObject @property SFEllipticCurve curve; @property SecCKKSTLKShareVersion version; @property NSString* tlkUUID; -@property id receiver; +@property NSString* receiverPeerID; +@property NSData* receiverPublicEncryptionKeySPKI; + @property NSString* senderPeerID; @property NSInteger epoch; @@ -58,46 +61,60 @@ typedef NS_ENUM(NSUInteger, SecCKKSTLKShareVersion) { @property (nullable) NSData* wrappedTLK; @property (nullable) NSData* signature; -- (instancetype)init NS_UNAVAILABLE; - -- (CKKSKey* _Nullable)recoverTLK:(id)recoverer trustedPeers:(NSSet>*)peers error:(NSError**)error; +@property CKRecordZoneID* zoneID; -+ (CKKSTLKShare* _Nullable)share:(CKKSKey*)key +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)init:(CKKSKeychainBackedKey*)key + sender:(id)sender + receiver:(id)receiver + curve:(SFEllipticCurve)curve + version:(SecCKKSTLKShareVersion)version + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + zoneID:(CKRecordZoneID*)zoneID; +- (instancetype)initForKey:(NSString*)tlkUUID + senderPeerID:(NSString*)senderPeerID + recieverPeerID:(NSString*)receiverPeerID + receiverEncPublicKeySPKI:(NSData*)publicKeySPKI + curve:(SFEllipticCurve)curve + version:(SecCKKSTLKShareVersion)version + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + wrappedKey:(NSData*)wrappedKey + signature:(NSData*)signature + zoneID:(CKRecordZoneID*)zoneID; + +- (CKKSKeychainBackedKey* _Nullable)recoverTLK:(id)recoverer + trustedPeers:(NSSet>*)peers + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError* __autoreleasing*)error; + ++ (CKKSTLKShare* _Nullable)share:(CKKSKeychainBackedKey*)key as:(id)sender to:(id)receiver epoch:(NSInteger)epoch poisoned:(NSInteger)poisoned error:(NSError**)error; -- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet error:(NSError**)error; - -// Database loading -+ (instancetype _Nullable)fromDatabase:(NSString*)uuid - receiverPeerID:(NSString*)receiverPeerID - senderPeerID:(NSString*)senderPeerID - zoneID:(CKRecordZoneID*)zoneID - error:(NSError* __autoreleasing*)error; -+ (instancetype _Nullable)tryFromDatabase:(NSString*)uuid - receiverPeerID:(NSString*)receiverPeerID - senderPeerID:(NSString*)senderPeerID - zoneID:(CKRecordZoneID*)zoneID - error:(NSError**)error; -+ (NSArray*)allFor:(NSString*)receiverPeerID - keyUUID:(NSString*)uuid - zoneID:(CKRecordZoneID*)zoneID - error:(NSError* __autoreleasing*)error; -+ (NSArray*)allForUUID:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError**)error; -+ (NSArray*)allInZone:(CKRecordZoneID*)zoneID error:(NSError**)error; -+ (instancetype _Nullable)tryFromDatabaseFromCKRecordID:(CKRecordID*)recordID error:(NSError**)error; - -// Returns a prefix that all every CKKSTLKShare CKRecord will have -+ (NSString*)ckrecordPrefix; +- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError**)error; // For tests -- (CKKSKey* _Nullable)unwrapUsing:(id)localPeer error:(NSError**)error; -- (NSData* _Nullable)signRecord:(SFECKeyPair*)signingKey error:(NSError**)error; -- (bool)verifySignature:(NSData*)signature verifyingPeer:(id)peer error:(NSError**)error; -- (NSData*)dataForSigning; +- (CKKSKeychainBackedKey* _Nullable)unwrapUsing:(id)localPeer + error:(NSError**)error; + +- (NSData* _Nullable)signRecord:(SFECKeyPair*)signingKey + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError**)error; + +- (bool)verifySignature:(NSData*)signature + verifyingPeer:(id)peer + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError**)error; + +// Pass in a CKRecord for forward-compatible signatures +- (NSData*)dataForSigning:(CKRecord* _Nullable)record; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/CKKSTLKShare.m b/keychain/ckks/CKKSTLKShare.m index 53877108..f1019b9f 100644 --- a/keychain/ckks/CKKSTLKShare.m +++ b/keychain/ckks/CKKSTLKShare.m @@ -23,40 +23,41 @@ #if OCTAGON -#import - #import "keychain/ckks/CKKSTLKShare.h" -#import "keychain/ckks/CKKSPeer.h" -#import "keychain/ckks/CloudKitCategories.h" -#import "keychain/categories/NSError+UsefulConstructors.h" -#import +#import +#import #import +#import #import -#import + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CloudKitCategories.h" @interface CKKSTLKShare () @end @implementation CKKSTLKShare --(instancetype)init:(CKKSKey*)key - sender:(id)sender - receiver:(id)receiver - curve:(SFEllipticCurve)curve - version:(SecCKKSTLKShareVersion)version - epoch:(NSInteger)epoch - poisoned:(NSInteger)poisoned - zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedCKRecord +- (instancetype)init:(CKKSKeychainBackedKey*)key + sender:(id)sender + receiver:(id)receiver + curve:(SFEllipticCurve)curve + version:(SecCKKSTLKShareVersion)version + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + zoneID:(CKRecordZoneID*)zoneID { - if((self = [super initWithCKRecordType:SecCKRecordTLKShareType - encodedCKRecord:encodedCKRecord - zoneID:zoneID])) { + if((self = [super init])) { + _zoneID = zoneID; + _curve = curve; _version = version; _tlkUUID = key.uuid; - _receiver = receiver; + _receiverPeerID = receiver.peerID; + _receiverPublicEncryptionKeySPKI = receiver.publicEncryptionKey.keyData; + _senderPeerID = sender.peerID; _epoch = epoch; @@ -68,7 +69,7 @@ - (instancetype)initForKey:(NSString*)tlkUUID senderPeerID:(NSString*)senderPeerID recieverPeerID:(NSString*)receiverPeerID - receiverEncPublicKey:(SFECPublicKey*)publicKey + receiverEncPublicKeySPKI:(NSData*)publicKeySPKI curve:(SFEllipticCurve)curve version:(SecCKKSTLKShareVersion)version epoch:(NSInteger)epoch @@ -76,15 +77,14 @@ wrappedKey:(NSData*)wrappedKey signature:(NSData*)signature zoneID:(CKRecordZoneID*)zoneID - encodedCKRecord:(NSData*)encodedCKRecord { - if((self = [super initWithCKRecordType:SecCKRecordTLKShareType - encodedCKRecord:encodedCKRecord - zoneID:zoneID])) { + if((self = [super init])) { + _zoneID = zoneID; _tlkUUID = tlkUUID; _senderPeerID = senderPeerID; - _receiver = [[CKKSSOSPeer alloc] initWithSOSPeerID:receiverPeerID encryptionPublicKey:publicKey signingPublicKey:nil]; + _receiverPeerID = receiverPeerID; + _receiverPublicEncryptionKeySPKI = publicKeySPKI; _curve = curve; _version = version; @@ -97,36 +97,48 @@ return self; } -- (NSString*)description { - return [NSString stringWithFormat:@"", self.tlkUUID, self.receiver, self.senderPeerID]; +- (NSString*)description +{ + return [NSString stringWithFormat:@"", + self.tlkUUID, + self.receiverPeerID, + self.senderPeerID]; } -- (NSData*)wrap:(CKKSKey*)key publicKey:(SFECPublicKey*)receiverPublicKey error:(NSError* __autoreleasing *)error { +- (NSData*)wrap:(CKKSKeychainBackedKey*)key + publicKey:(SFECPublicKey*)receiverPublicKey + error:(NSError* __autoreleasing*)error +{ NSData* plaintext = [key serializeAsProtobuf:error]; if(!plaintext) { return nil; } SFIESOperation* sfieso = [[SFIESOperation alloc] initWithCurve:self.curve]; - SFIESCiphertext* ciphertext = [sfieso encrypt:plaintext withKey:receiverPublicKey error:error]; + SFIESCiphertext* ciphertext = + [sfieso encrypt:plaintext withKey:receiverPublicKey error:error]; // Now use NSCoding to turn the ciphertext into something transportable - NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; [ciphertext encodeWithCoder:archiver]; return archiver.encodedData; } -- (CKKSKey*)unwrapUsing:(id)localPeer error:(NSError * __autoreleasing *)error { +- (CKKSKeychainBackedKey* _Nullable)unwrapUsing:(id)localPeer + error:(NSError* __autoreleasing*)error +{ // Unwrap the ciphertext using NSSecureCoding - NSKeyedUnarchiver *coder = [[NSKeyedUnarchiver alloc] initForReadingFromData:self.wrappedTLK error:nil]; + NSKeyedUnarchiver* coder = + [[NSKeyedUnarchiver alloc] initForReadingFromData:self.wrappedTLK error:nil]; SFIESCiphertext* ciphertext = [[SFIESCiphertext alloc] initWithCoder:coder]; [coder finishDecoding]; SFIESOperation* sfieso = [[SFIESOperation alloc] initWithCurve:self.curve]; NSError* localerror = nil; - NSData* plaintext = [sfieso decrypt:ciphertext withKey:localPeer.encryptionKey error:&localerror]; + NSData* plaintext = + [sfieso decrypt:ciphertext withKey:localPeer.encryptionKey error:&localerror]; if(!plaintext || localerror) { if(error) { *error = localerror; @@ -134,12 +146,13 @@ return nil; } - return [CKKSKey loadFromProtobuf:plaintext error:error]; + return [CKKSKeychainBackedKey loadFromProtobuf:plaintext error:error]; } // Serialize this record in some format suitable for signing. // This record must serialize exactly the same on the other side for the signature to verify. -- (NSData*)dataForSigning { +- (NSData*)dataForSigning:(CKRecord* _Nullable)record +{ // Ideally, we'd put this as DER or some other structured, versioned format. // For now, though, do the straightforward thing and concatenate the fields of interest. NSMutableData* dataToSign = [[NSMutableData alloc] init]; @@ -149,7 +162,7 @@ // We only include the peer IDs in the signature; the receiver doesn't care if we signed the receiverPublicKey field; // if it's wrong or doesn't match, the receiver will simply fail to decrypt the encrypted record. - [dataToSign appendData:[self.receiver.peerID dataUsingEncoding:NSUTF8StringEncoding]]; + [dataToSign appendData:[self.receiverPeerID dataUsingEncoding:NSUTF8StringEncoding]]; [dataToSign appendData:[self.senderPeerID dataUsingEncoding:NSUTF8StringEncoding]]; [dataToSign appendData:self.wrappedTLK]; @@ -163,21 +176,18 @@ uint64_t poisoned = OSSwapHostToLittleConstInt64(self.poisoned); [dataToSign appendBytes:&poisoned length:sizeof(poisoned)]; - // If we have a CKRecord saved here, add any unknown fields (that don't start with server_) to the signed data + // If we have a CKRecord passed in, add any unknown fields (that don't start with server_) to the signed data // in sorted order by CKRecord key - CKRecord* record = self.storedCKRecord; if(record) { - NSMutableDictionary* extraData = [NSMutableDictionary dictionary]; + NSMutableDictionary* extraData = [NSMutableDictionary dictionary]; for(NSString* key in record.allKeys) { if([key isEqualToString:SecCKRecordSenderPeerID] || [key isEqualToString:SecCKRecordReceiverPeerID] || [key isEqualToString:SecCKRecordReceiverPublicEncryptionKey] || - [key isEqualToString:SecCKRecordCurve] || - [key isEqualToString:SecCKRecordEpoch] || + [key isEqualToString:SecCKRecordCurve] || [key isEqualToString:SecCKRecordEpoch] || [key isEqualToString:SecCKRecordPoisoned] || - [key isEqualToString:SecCKRecordSignature] || - [key isEqualToString:SecCKRecordVersion] || + [key isEqualToString:SecCKRecordSignature] || [key isEqualToString:SecCKRecordVersion] || [key isEqualToString:SecCKRecordParentKeyRefKey] || [key isEqualToString:SecCKRecordWrappedKeyKey]) { // This version of CKKS knows about this data field. Ignore them with prejudice. @@ -197,15 +207,15 @@ id obj = extraData[extraKey]; // Skip CKReferences, NSArray, CLLocation, and CKAsset. - if([obj isKindOfClass: [NSString class]]) { - [dataToSign appendData: [obj dataUsingEncoding: NSUTF8StringEncoding]]; - } else if([obj isKindOfClass: [NSData class]]) { - [dataToSign appendData: obj]; + if([obj isKindOfClass:[NSString class]]) { + [dataToSign appendData:[obj dataUsingEncoding:NSUTF8StringEncoding]]; + } else if([obj isKindOfClass:[NSData class]]) { + [dataToSign appendData:obj]; } else if([obj isKindOfClass:[NSDate class]]) { - NSISO8601DateFormatter *formatter = [[NSISO8601DateFormatter alloc] init]; - NSString* str = [formatter stringForObjectValue: obj]; - [dataToSign appendData: [str dataUsingEncoding: NSUTF8StringEncoding]]; - } else if([obj isKindOfClass: [NSNumber class]]) { + NSISO8601DateFormatter* formatter = [[NSISO8601DateFormatter alloc] init]; + NSString* str = [formatter stringForObjectValue:obj]; + [dataToSign appendData:[str dataUsingEncoding:NSUTF8StringEncoding]]; + } else if([obj isKindOfClass:[NSNumber class]]) { // Add an NSNumber uint64_t n64 = OSSwapHostToLittleConstInt64([obj unsignedLongLongValue]); [dataToSign appendBytes:&n64 length:sizeof(n64)]; @@ -217,44 +227,61 @@ } // Returns the signature, but not the signed data itself; -- (NSData*)signRecord:(SFECKeyPair*)signingKey error:(NSError* __autoreleasing *)error { +- (NSData* _Nullable)signRecord:(SFECKeyPair*)signingKey + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError* __autoreleasing*)error +{ // TODO: the digest operation can't be changed, as we don't have a good way of communicating it, like self.curve - SFEC_X962SigningOperation* xso = [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:[[SFECKeySpecifier alloc] initWithCurve:self.curve] - digestOperation:[[SFSHA256DigestOperation alloc] init]]; + SFEC_X962SigningOperation* xso = [[SFEC_X962SigningOperation alloc] + initWithKeySpecifier:[[SFECKeySpecifier alloc] initWithCurve:self.curve] + digestOperation:[[SFSHA256DigestOperation alloc] init]]; - NSData* data = [self dataForSigning]; + NSData* data = [self dataForSigning:ckrecord]; SFSignedData* signedData = [xso sign:data withKey:signingKey error:error]; return signedData.signature; } -- (bool)verifySignature:(NSData*)signature verifyingPeer:(id)peer error:(NSError* __autoreleasing *)error { +- (bool)verifySignature:(NSData*)signature + verifyingPeer:(id)peer + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError* __autoreleasing*)error +{ if(!peer.publicSigningKey) { secerror("ckksshare: no signing key for peer: %@", peer); if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNoSigningKey - description:[NSString stringWithFormat:@"Peer(%@) has no signing key", peer]]; + *error = [NSError + errorWithDomain:CKKSErrorDomain + code:CKKSNoSigningKey + description:[NSString stringWithFormat:@"Peer(%@) has no signing key", peer]]; } return false; } // TODO: the digest operation can't be changed, as we don't have a good way of communicating it, like self.curve - SFEC_X962SigningOperation* xso = [[SFEC_X962SigningOperation alloc] initWithKeySpecifier:[[SFECKeySpecifier alloc] initWithCurve:self.curve] - digestOperation:[[SFSHA256DigestOperation alloc] init]]; - SFSignedData* signedData = [[SFSignedData alloc] initWithData:[self dataForSigning] signature:signature]; + SFEC_X962SigningOperation* xso = [[SFEC_X962SigningOperation alloc] + initWithKeySpecifier:[[SFECKeySpecifier alloc] initWithCurve:self.curve] + digestOperation:[[SFSHA256DigestOperation alloc] init]]; + SFSignedData* signedData = + [[SFSignedData alloc] initWithData:[self dataForSigning:ckrecord] signature:signature]; bool ret = [xso verify:signedData withKey:peer.publicSigningKey error:error]; return ret; } -- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet error:(NSError**)error { +- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError**)error +{ NSError* lastVerificationError = nil; for(id peer in peerSet) { - if([peer.peerID isEqualToString: self.senderPeerID]) { + if([peer.peerID isEqualToString:self.senderPeerID]) { // Does the signature verify using this peer? NSError* localerror = nil; - bool isSigned = [self verifySignature:self.signature verifyingPeer:peer error:&localerror]; + bool isSigned = [self verifySignature:self.signature + verifyingPeer:peer + ckrecord:ckrecord + error:&localerror]; if(localerror) { secerror("ckksshare: signature didn't verify for %@ %@: %@", self, peer, localerror); lastVerificationError = localerror; @@ -269,15 +296,17 @@ if(lastVerificationError) { *error = lastVerificationError; } else { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNoTrustedTLKShares - description:[NSString stringWithFormat:@"No TLK share from %@", self.senderPeerID]]; + *error = [NSError + errorWithDomain:CKKSErrorDomain + code:CKKSNoTrustedTLKShares + description:[NSString stringWithFormat:@"No TLK share from %@", self.senderPeerID]]; } } return false; } -- (instancetype)copyWithZone:(NSZone *)zone { +- (instancetype)copyWithZone:(NSZone*)zone +{ CKKSTLKShare* share = [[[self class] allocWithZone:zone] init]; share.curve = self.curve; share.version = self.version; @@ -288,67 +317,93 @@ share.wrappedTLK = [self.wrappedTLK copy]; share.signature = [self.signature copy]; - share.receiver = self.receiver; + share.receiverPeerID = [self.receiverPeerID copy]; + share.receiverPublicEncryptionKeySPKI = [self.receiverPublicEncryptionKeySPKI copy]; + return share; } -- (BOOL)isEqual:(id)object { ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder*)coder +{ + [coder encodeObject:self.zoneID forKey:@"zoneID"]; + [coder encodeInt64:(int64_t)self.curve forKey:@"curve"]; + [coder encodeInt64:self.version forKey:@"version"]; + [coder encodeObject:self.tlkUUID forKey:@"tlkUUID"]; + [coder encodeObject:self.senderPeerID forKey:@"senderPeerID"]; + [coder encodeInt64:self.epoch forKey:@"epoch"]; + [coder encodeInt64:self.poisoned forKey:@"poisoned"]; + [coder encodeObject:self.wrappedTLK forKey:@"wrappedTLK"]; + [coder encodeObject:self.signature forKey:@"signature"]; + + [coder encodeObject:self.receiverPeerID forKey:@"receiverPeerID"]; + [coder encodeObject:self.receiverPublicEncryptionKeySPKI forKey:@"receiverSPKI"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder*)decoder +{ + self = [super init]; + if(self) { + _zoneID = [decoder decodeObjectOfClass:[CKRecordZoneID class] forKey:@"zoneID"]; + _curve = (SFEllipticCurve) [decoder decodeInt64ForKey:@"curve"]; + _version = (SecCKKSTLKShareVersion)[decoder decodeInt64ForKey:@"version"]; + _tlkUUID = [decoder decodeObjectOfClass:[NSString class] forKey:@"tlkUUID"]; + _senderPeerID = [decoder decodeObjectOfClass:[NSString class] forKey:@"senderPeerID"]; + _epoch = (NSInteger)[decoder decodeInt64ForKey:@"epoch"]; + _poisoned = (NSInteger)[decoder decodeInt64ForKey:@"poisoned"]; + _wrappedTLK = [decoder decodeObjectOfClass:[NSData class] forKey:@"wrappedTLK"]; + _signature = [decoder decodeObjectOfClass:[NSData class] forKey:@"signature"]; + + + _receiverPeerID = [decoder decodeObjectOfClass:[NSString class] forKey:@"receiverPeerID"]; + _receiverPublicEncryptionKeySPKI = [decoder decodeObjectOfClass:[NSData class] forKey:@"receiverSPKI"]; + } + return self; +} + +- (BOOL)isEqual:(id)object +{ if(![object isKindOfClass:[CKKSTLKShare class]]) { return NO; } - CKKSTLKShare* obj = (CKKSTLKShare*) object; + CKKSTLKShare* obj = (CKKSTLKShare*)object; - // Note that for purposes of CKKSTLK equality, we only care about the receiver's peer ID and publicEncryptionKey - // SFKeys should support [isEqual:] - return ([self.tlkUUID isEqualToString:obj.tlkUUID] && - [self.zoneID isEqual: obj.zoneID] && + return ([self.tlkUUID isEqualToString:obj.tlkUUID] && [self.zoneID isEqual:obj.zoneID] && [self.senderPeerID isEqualToString:obj.senderPeerID] && - ((self.receiver.peerID == nil && obj.receiver.peerID == nil) || [self.receiver.peerID isEqual: obj.receiver.peerID]) && - ((self.receiver.publicEncryptionKey == nil && obj.receiver.publicEncryptionKey == nil) - || [self.receiver.publicEncryptionKey.keyData isEqual: obj.receiver.publicEncryptionKey.keyData]) && - self.epoch == obj.epoch && - self.curve == obj.curve && - self.poisoned == obj.poisoned && - ((self.wrappedTLK == nil && obj.wrappedTLK == nil) || [self.wrappedTLK isEqual: obj.wrappedTLK]) && - ((self.signature == nil && obj.signature == nil) || [self.signature isEqual: obj.signature]) && - true) ? YES : NO; + ((self.receiverPeerID == nil && obj.receiverPeerID == nil) || + [self.receiverPeerID isEqual:obj.receiverPeerID]) && + ((self.receiverPublicEncryptionKeySPKI == nil && obj.receiverPublicEncryptionKeySPKI == nil) || + [self.receiverPublicEncryptionKeySPKI isEqual:obj.receiverPublicEncryptionKeySPKI]) && + self.epoch == obj.epoch && self.curve == obj.curve && self.poisoned == obj.poisoned && + ((self.wrappedTLK == nil && obj.wrappedTLK == nil) || [self.wrappedTLK isEqual:obj.wrappedTLK]) && + ((self.signature == nil && obj.signature == nil) || [self.signature isEqual:obj.signature]) && true) + ? YES + : NO; } -+ (CKKSTLKShare*)share:(CKKSKey*)key - as:(id)sender - to:(id)receiver - epoch:(NSInteger)epoch - poisoned:(NSInteger)poisoned - error:(NSError* __autoreleasing *)error ++ (CKKSTLKShare* _Nullable)share:(CKKSKeychainBackedKey*)key + as:(id)sender + to:(id)receiver + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + error:(NSError* __autoreleasing*)error { NSError* localerror = nil; - - // Load any existing TLK Share, so we can update it - CKKSTLKShare* oldShare = [CKKSTLKShare tryFromDatabase:key.uuid - receiverPeerID:receiver.peerID - senderPeerID:sender.peerID - zoneID:key.zoneID - error:&localerror]; - if(localerror) { - secerror("ckksshare: couldn't load old share for %@: %@", key, localerror); - if(error) { - *error = localerror; - } - return nil; - } - CKKSTLKShare* share = [[CKKSTLKShare alloc] init:key - sender:sender - receiver:receiver - curve:SFEllipticCurveNistp384 - version:SecCKKSTLKShareCurrentVersion - epoch:epoch - poisoned:poisoned - zoneID:key.zoneID - encodedCKRecord:oldShare.encodedCKRecord]; - - share.wrappedTLK = [share wrap:key publicKey:receiver.publicEncryptionKey error:&localerror]; + sender:sender + receiver:receiver + curve:SFEllipticCurveNistp384 + version:SecCKKSTLKShareCurrentVersion + epoch:epoch + poisoned:poisoned + zoneID:key.zoneID]; + + share.wrappedTLK = + [share wrap:key publicKey:receiver.publicEncryptionKey error:&localerror]; if(localerror) { secerror("ckksshare: couldn't share %@ (wrap failed): %@", key, localerror); if(error) { @@ -357,7 +412,9 @@ return nil; } - share.signature = [share signRecord:sender.signingKey error:&localerror]; + share.signature = [share signRecord:sender.signingKey + ckrecord:nil + error:&localerror]; if(localerror) { secerror("ckksshare: couldn't share %@ (signing failed): %@", key, localerror); if(error) { @@ -369,35 +426,40 @@ return share; } -- (CKKSKey*)recoverTLK:(id)recoverer - trustedPeers:(NSSet>*)peers - error:(NSError* __autoreleasing *)error +- (CKKSKeychainBackedKey* _Nullable)recoverTLK:(id)recoverer + trustedPeers:(NSSet>*)peers + ckrecord:(CKRecord* _Nullable)ckrecord + error:(NSError* __autoreleasing*)error { NSError* localerror = nil; id peer = nil; for(id p in peers) { - if([p.peerID isEqualToString: self.senderPeerID]) { + if([p.peerID isEqualToString:self.senderPeerID]) { peer = p; } } if(!peer) { - localerror = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNoTrustedPeer - description:[NSString stringWithFormat:@"No trusted peer signed %@", self]]; + localerror = [NSError + errorWithDomain:CKKSErrorDomain + code:CKKSNoTrustedPeer + description:[NSString stringWithFormat:@"No trusted peer signed %@", self]]; if(error) { *error = localerror; } return nil; } - bool isSigned = [self verifySignature:self.signature verifyingPeer:peer error:error]; + bool isSigned = [self verifySignature:self.signature + verifyingPeer:peer + ckrecord:ckrecord + error:error]; if(!isSigned) { return nil; } - CKKSKey* tlkTrial = [self unwrapUsing:recoverer error:error]; + CKKSKeychainBackedKey* tlkTrial = [self unwrapUsing:recoverer error:error]; if(!tlkTrial) { return nil; } @@ -405,7 +467,8 @@ if(![self.tlkUUID isEqualToString:tlkTrial.uuid]) { localerror = [NSError errorWithDomain:CKKSErrorDomain code:CKKSDataMismatch - description:[NSString stringWithFormat:@"Signed UUID doesn't match unsigned UUID for %@", self]]; + description:[NSString stringWithFormat:@"Signed UUID doesn't match unsigned UUID for %@", + self]]; if(error) { *error = localerror; } @@ -415,241 +478,6 @@ return tlkTrial; } -#pragma mark - Database Operations - -+ (instancetype)fromDatabase:(NSString*)uuid - receiverPeerID:(NSString*)receiverPeerID - senderPeerID:(NSString*)senderPeerID - zoneID:(CKRecordZoneID*)zoneID - error:(NSError * __autoreleasing *)error { - return [self fromDatabaseWhere: @{@"uuid":CKKSNilToNSNull(uuid), - @"recvpeerid":CKKSNilToNSNull(receiverPeerID), - @"senderpeerid":CKKSNilToNSNull(senderPeerID), - @"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; -} - -+ (instancetype)tryFromDatabase:(NSString*)uuid - receiverPeerID:(NSString*)receiverPeerID - senderPeerID:(NSString*)senderPeerID - zoneID:(CKRecordZoneID*)zoneID - error:(NSError * __autoreleasing *)error { - return [self tryFromDatabaseWhere: @{@"uuid":CKKSNilToNSNull(uuid), - @"recvpeerid":CKKSNilToNSNull(receiverPeerID), - @"senderpeerid":CKKSNilToNSNull(senderPeerID), - @"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; -} - -+ (NSArray*)allFor:(NSString*)receiverPeerID - keyUUID:(NSString*)uuid - zoneID:(CKRecordZoneID*)zoneID - error:(NSError * __autoreleasing *)error { - return [self allWhere:@{@"recvpeerid":CKKSNilToNSNull(receiverPeerID), - @"uuid":uuid, - @"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; -} - -+ (NSArray*)allForUUID:(NSString*)uuid - zoneID:(CKRecordZoneID*)zoneID - error:(NSError * __autoreleasing *)error { - return [self allWhere:@{@"uuid":CKKSNilToNSNull(uuid), - @"ckzone":CKKSNilToNSNull(zoneID.zoneName)} error:error]; -} - -+ (NSArray*)allInZone:(CKRecordZoneID*)zoneID - error:(NSError * __autoreleasing *)error { - return [self allWhere:@{@"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; -} - -+ (instancetype)tryFromDatabaseFromCKRecordID:(CKRecordID*)recordID - error:(NSError * __autoreleasing *)error { - // Welp. Try to parse! - NSError *localerror = NULL; - NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^tlkshare-(?[0-9A-Fa-f-]*)::(?.*)::(?.*)$" - options:NSRegularExpressionCaseInsensitive - error:&localerror]; - if(localerror) { - if(error) { - *error = localerror; - } - return nil; - } - - NSTextCheckingResult* regexmatch = [regex firstMatchInString:recordID.recordName options:0 range:NSMakeRange(0, recordID.recordName.length)]; - if(!regexmatch) { - if(error) { - *error = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNoSuchRecord - description:[NSString stringWithFormat:@"Couldn't parse '%@' as a TLKShare ID", recordID.recordName]]; - } - return nil; - } - - NSString* uuid = [recordID.recordName substringWithRange:[regexmatch rangeWithName:@"uuid"]]; - NSString* receiver = [recordID.recordName substringWithRange:[regexmatch rangeWithName:@"receiver"]]; - NSString* sender = [recordID.recordName substringWithRange:[regexmatch rangeWithName:@"sender"]]; - - return [self tryFromDatabaseWhere: @{@"uuid":CKKSNilToNSNull(uuid), - @"recvpeerid":CKKSNilToNSNull(receiver), - @"senderpeerid":CKKSNilToNSNull(sender), - @"ckzone": CKKSNilToNSNull(recordID.zoneID.zoneName)} error:error]; -} - -#pragma mark - CKKSCKRecordHolder methods - -+ (NSString*)ckrecordPrefix { - return @"tlkshare"; -} - -- (NSString*)CKRecordName { - return [NSString stringWithFormat:@"tlkshare-%@::%@::%@", self.tlkUUID, self.receiver.peerID, self.senderPeerID]; -} - -- (CKRecord*)updateCKRecord:(CKRecord*)record zoneID:(CKRecordZoneID*)zoneID { - if(![record.recordID.recordName isEqualToString: [self CKRecordName]]) { - @throw [NSException - exceptionWithName:@"WrongCKRecordNameException" - reason:[NSString stringWithFormat: @"CKRecord name (%@) was not %@", record.recordID.recordName, [self CKRecordName]] - userInfo:nil]; - } - if(![record.recordType isEqualToString: SecCKRecordTLKShareType]) { - @throw [NSException - exceptionWithName:@"WrongCKRecordTypeException" - reason:[NSString stringWithFormat: @"CKRecordType (%@) was not %@", record.recordType, SecCKRecordTLKShareType] - userInfo:nil]; - } - - record[SecCKRecordSenderPeerID] = self.senderPeerID; - record[SecCKRecordReceiverPeerID] = self.receiver.peerID; - record[SecCKRecordReceiverPublicEncryptionKey] = [self.receiver.publicEncryptionKey.keyData base64EncodedStringWithOptions:0]; - record[SecCKRecordCurve] = [NSNumber numberWithUnsignedInteger:(NSUInteger)self.curve]; - record[SecCKRecordVersion] = [NSNumber numberWithUnsignedInteger:(NSUInteger)self.version]; - record[SecCKRecordEpoch] = [NSNumber numberWithLong:(long)self.epoch]; - record[SecCKRecordPoisoned] = [NSNumber numberWithLong:(long)self.poisoned]; - - record[SecCKRecordParentKeyRefKey] = [[CKReference alloc] initWithRecordID: [[CKRecordID alloc] initWithRecordName: self.tlkUUID zoneID: zoneID] - action: CKReferenceActionValidate]; - - record[SecCKRecordWrappedKeyKey] = [self.wrappedTLK base64EncodedStringWithOptions:0]; - record[SecCKRecordSignature] = [self.signature base64EncodedStringWithOptions:0]; - - return record; -} - -- (bool)matchesCKRecord:(CKRecord*)record { - if(![record.recordType isEqualToString: SecCKRecordTLKShareType]) { - return false; - } - - if(![record.recordID.recordName isEqualToString: [self CKRecordName]]) { - return false; - } - - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - return [self isEqual: share]; -} - -- (void)setFromCKRecord: (CKRecord*) record { - if(![record.recordType isEqualToString: SecCKRecordTLKShareType]) { - @throw [NSException - exceptionWithName:@"WrongCKRecordTypeException" - reason:[NSString stringWithFormat: @"CKRecordType (%@) was not %@", record.recordType, SecCKRecordDeviceStateType] - userInfo:nil]; - } - - [self setStoredCKRecord:record]; - - self.senderPeerID = record[SecCKRecordSenderPeerID]; - self.curve = [record[SecCKRecordCurve] longValue]; // TODO: sanitize - self.version = [record[SecCKRecordVersion] longValue]; - - NSData* pubkeydata = CKKSUnbase64NullableString(record[SecCKRecordReceiverPublicEncryptionKey]); - NSError* error = nil; - SFECPublicKey* receiverPublicKey = pubkeydata ? [[SFECPublicKey alloc] initWithData:pubkeydata - specifier:[[SFECKeySpecifier alloc] initWithCurve:self.curve] - error:&error] : nil; - - if(error) { - ckkserror("ckksshare", record.recordID.zoneID, "Couldn't make public key from data: %@", error); - receiverPublicKey = nil; - } - - self.receiver = [[CKKSSOSPeer alloc] initWithSOSPeerID:record[SecCKRecordReceiverPeerID] encryptionPublicKey:receiverPublicKey signingPublicKey:nil]; - - self.epoch = [record[SecCKRecordEpoch] longValue]; - self.poisoned = [record[SecCKRecordPoisoned] longValue]; - - self.tlkUUID = ((CKReference*)record[SecCKRecordParentKeyRefKey]).recordID.recordName; - - self.wrappedTLK = CKKSUnbase64NullableString(record[SecCKRecordWrappedKeyKey]); - self.signature = CKKSUnbase64NullableString(record[SecCKRecordSignature]); -} - -#pragma mark - CKKSSQLDatabaseObject methods - -+ (NSString*)sqlTable { - return @"tlkshare"; -} - -+ (NSArray*)sqlColumns { - return @[@"ckzone", @"uuid", @"senderpeerid", @"recvpeerid", @"recvpubenckey", @"poisoned", @"epoch", @"curve", @"version", @"wrappedkey", @"signature", @"ckrecord"]; -} - -- (NSDictionary*)whereClauseToFindSelf { - return @{@"uuid":self.tlkUUID, - @"senderpeerid":self.senderPeerID, - @"recvpeerid":self.receiver.peerID, - @"ckzone":self.zoneID.zoneName, - }; -} - -- (NSDictionary*)sqlValues { - return @{@"uuid": self.tlkUUID, - @"senderpeerid": self.senderPeerID, - @"recvpeerid": self.receiver.peerID, - @"recvpubenckey": CKKSNilToNSNull([self.receiver.publicEncryptionKey.keyData base64EncodedStringWithOptions:0]), - @"poisoned": [NSString stringWithFormat:@"%ld", (long)self.poisoned], - @"epoch": [NSString stringWithFormat:@"%ld", (long)self.epoch], - @"curve": [NSString stringWithFormat:@"%ld", (long)self.curve], - @"version": [NSString stringWithFormat:@"%ld", (long)self.version], - @"wrappedkey": CKKSNilToNSNull([self.wrappedTLK base64EncodedStringWithOptions:0]), - @"signature": CKKSNilToNSNull([self.signature base64EncodedStringWithOptions:0]), - @"ckzone": CKKSNilToNSNull(self.zoneID.zoneName), - @"ckrecord": CKKSNilToNSNull([self.encodedCKRecord base64EncodedStringWithOptions:0]), - }; -} - -+ (instancetype)fromDatabaseRow:(NSDictionary*)row { - CKRecordZoneID* zoneID = [[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"] ownerName:CKCurrentUserDefaultName]; - - SFEllipticCurve curve = (SFEllipticCurve)[row[@"curve"] integerValue]; // TODO: sanitize - SecCKKSTLKShareVersion version = (SecCKKSTLKShareVersion)[row[@"version"] integerValue]; // TODO: sanitize - - NSData* keydata = CKKSUnbase64NullableString(row[@"recvpubenckey"]); - NSError* error = nil; - SFECPublicKey* receiverPublicKey = keydata ? [[SFECPublicKey alloc] initWithData:keydata - specifier:[[SFECKeySpecifier alloc] initWithCurve:curve] - error:&error] : nil; - - if(error) { - ckkserror("ckksshare", zoneID, "Couldn't make public key from data: %@", error); - receiverPublicKey = nil; - } - - return [[CKKSTLKShare alloc] initForKey:row[@"uuid"] - senderPeerID:row[@"senderpeerid"] - recieverPeerID:row[@"recvpeerid"] - receiverEncPublicKey:receiverPublicKey - curve:curve - version:version - epoch:[row[@"epoch"] integerValue] - poisoned:[row[@"poisoned"] integerValue] - wrappedKey:CKKSUnbase64NullableString(row[@"wrappedkey"]) - signature:CKKSUnbase64NullableString(row[@"signature"]) - zoneID:zoneID - encodedCKRecord:CKKSUnbase64NullableString(row[@"ckrecord"]) - ]; -} - @end -#endif // OCTAGON +#endif // OCTAGON diff --git a/keychain/ckks/CKKSTLKShareRecord.h b/keychain/ckks/CKKSTLKShareRecord.h new file mode 100644 index 00000000..9fd54c0c --- /dev/null +++ b/keychain/ckks/CKKSTLKShareRecord.h @@ -0,0 +1,98 @@ +/* + * 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 OCTAGON + +#import + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSItem.h" +#import "keychain/ckks/CKKSKey.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSTLKShare.h" + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CKKSTLKShareRecord : CKKSCKRecordHolder +@property CKKSTLKShare* share; + +// Passthroughs to the underlying share +@property (readonly) NSString* tlkUUID; + +@property (readonly) NSString* senderPeerID; + +@property (readonly) NSInteger epoch; +@property (readonly) NSInteger poisoned; + +@property (readonly, nullable) NSData* wrappedTLK; +@property (readonly, nullable) NSData* signature; + +- (instancetype)init NS_UNAVAILABLE; + +- (CKKSKey* _Nullable)recoverTLK:(id)recoverer trustedPeers:(NSSet>*)peers error:(NSError**)error; + ++ (CKKSTLKShareRecord* _Nullable)share:(CKKSKey*)key + as:(id)sender + to:(id)receiver + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + error:(NSError**)error; + +- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet error:(NSError**)error; + +- (NSData*)dataForSigning; + +// Database loading ++ (instancetype _Nullable)fromDatabase:(NSString*)uuid + receiverPeerID:(NSString*)receiverPeerID + senderPeerID:(NSString*)senderPeerID + zoneID:(CKRecordZoneID*)zoneID + error:(NSError* __autoreleasing*)error; ++ (instancetype _Nullable)tryFromDatabase:(NSString*)uuid + receiverPeerID:(NSString*)receiverPeerID + senderPeerID:(NSString*)senderPeerID + zoneID:(CKRecordZoneID*)zoneID + error:(NSError**)error; ++ (NSArray*)allFor:(NSString*)receiverPeerID + keyUUID:(NSString*)uuid + zoneID:(CKRecordZoneID*)zoneID + error:(NSError* __autoreleasing*)error; ++ (NSArray*)allForUUID:(NSString*)uuid zoneID:(CKRecordZoneID*)zoneID error:(NSError**)error; ++ (NSArray*)allInZone:(CKRecordZoneID*)zoneID error:(NSError**)error; ++ (instancetype _Nullable)tryFromDatabaseFromCKRecordID:(CKRecordID*)recordID error:(NSError**)error; + +// Returns a prefix that all every CKKSTLKShare CKRecord will have ++ (NSString*)ckrecordPrefix; + +// For tests +- (CKKSKey* _Nullable)unwrapUsing:(id)localPeer error:(NSError**)error; +- (NSData* _Nullable)signRecord:(SFECKeyPair*)signingKey error:(NSError**)error; +- (bool)verifySignature:(NSData*)signature verifyingPeer:(id)peer error:(NSError**)error; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSTLKShareRecord.m b/keychain/ckks/CKKSTLKShareRecord.m new file mode 100644 index 00000000..ac6ee5ad --- /dev/null +++ b/keychain/ckks/CKKSTLKShareRecord.m @@ -0,0 +1,475 @@ +/* + * 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 OCTAGON + +#import + +#import "keychain/ckks/CKKSTLKShareRecord.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import +#import +#import +#import + +@interface CKKSTLKShareRecord () +@end + +@implementation CKKSTLKShareRecord + +- (instancetype)init:(CKKSTLKShare*)share + zoneID:(CKRecordZoneID*)zoneID + encodedCKRecord:(NSData*)encodedCKRecord +{ + if((self = [super initWithCKRecordType:SecCKRecordTLKShareType + encodedCKRecord:encodedCKRecord + zoneID:zoneID])) { + _share = share; + } + return self; +} + +-(instancetype)init:(CKKSKey*)key + sender:(id)sender + receiver:(id)receiver + curve:(SFEllipticCurve)curve + version:(SecCKKSTLKShareVersion)version + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + zoneID:(CKRecordZoneID*)zoneID + encodedCKRecord:(NSData*)encodedCKRecord +{ + if((self = [super initWithCKRecordType:SecCKRecordTLKShareType + encodedCKRecord:encodedCKRecord + zoneID:zoneID])) { + + _share = [[CKKSTLKShare alloc] init:key.keycore + sender:sender + receiver:receiver + curve:curve + version:version + epoch:epoch + poisoned:poisoned + zoneID:zoneID]; + } + return self; +} + +- (instancetype)initForKey:(NSString*)tlkUUID + senderPeerID:(NSString*)senderPeerID + recieverPeerID:(NSString*)receiverPeerID + receiverEncPublicKeySPKI:(NSData*)publicKeySPKI + curve:(SFEllipticCurve)curve + version:(SecCKKSTLKShareVersion)version + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + wrappedKey:(NSData*)wrappedKey + signature:(NSData*)signature + zoneID:(CKRecordZoneID*)zoneID + encodedCKRecord:(NSData*)encodedCKRecord +{ + if((self = [super initWithCKRecordType:SecCKRecordTLKShareType + encodedCKRecord:encodedCKRecord + zoneID:zoneID])) { + + _share = [[CKKSTLKShare alloc] initForKey:tlkUUID + senderPeerID:senderPeerID + recieverPeerID:receiverPeerID + receiverEncPublicKeySPKI:publicKeySPKI + curve:curve + version:version + epoch:epoch + poisoned:poisoned + wrappedKey:wrappedKey + signature:signature + zoneID:zoneID]; + } + return self; +} + +- (NSString*)description { + return [NSString stringWithFormat:@"", + self.share.tlkUUID, + self.share.receiverPeerID, + self.share.senderPeerID]; +} + +- (NSString*)tlkUUID +{ + return self.share.tlkUUID; +} + +- (NSString*)senderPeerID +{ + return self.share.senderPeerID; +} +- (NSInteger)epoch +{ + return self.share.epoch; +} + +- (NSInteger)poisoned +{ + return self.share.poisoned; +} + +- (NSData*)wrappedTLK +{ + return self.share.wrappedTLK; +} +- (NSData*)signature +{ + return self.share.signature; +} + +- (CKKSKey*)unwrapUsing:(id)localPeer + error:(NSError * __autoreleasing *)error +{ + CKKSKeychainBackedKey* realkey = [self.share unwrapUsing:localPeer + error:error]; + + if(!realkey) { + return nil; + } + + return [[CKKSKey alloc] initWithKeyCore:realkey]; +} + +- (NSData*)dataForSigning +{ + return [self.share dataForSigning:self.storedCKRecord]; +} + +// Returns the signature, but not the signed data itself; +- (NSData*)signRecord:(SFECKeyPair*)signingKey + error:(NSError* __autoreleasing *)error +{ + return [self.share signRecord:signingKey + ckrecord:self.storedCKRecord + error:error]; +} + +- (bool)verifySignature:(NSData*)signature + verifyingPeer:(id)peer + error:(NSError* __autoreleasing *)error +{ + return [self.share verifySignature:signature + verifyingPeer:peer + ckrecord:self.storedCKRecord + error:error]; +} + +- (bool)signatureVerifiesWithPeerSet:(NSSet>*)peerSet + error:(NSError**)error +{ + return [self.share signatureVerifiesWithPeerSet:peerSet + ckrecord:self.storedCKRecord + error:error]; +} + +- (instancetype)copyWithZone:(NSZone *)zone { + CKKSTLKShareRecord* shareRecord = [[[self class] allocWithZone:zone] init]; + shareRecord.share = [self.share copyWithZone:zone]; + return shareRecord; +} + +- (BOOL)isEqual:(id)object { + if(![object isKindOfClass:[CKKSTLKShareRecord class]]) { + return NO; + } + + CKKSTLKShareRecord* obj = (CKKSTLKShareRecord*) object; + return [self.share isEqual: obj.share]; +} + ++ (CKKSTLKShareRecord*)share:(CKKSKey*)key + as:(id)sender + to:(id)receiver + epoch:(NSInteger)epoch + poisoned:(NSInteger)poisoned + error:(NSError* __autoreleasing *)error +{ + NSError* localerror = nil; + // Load any existing TLK Share, so we can update it + CKKSTLKShareRecord* oldShare = [CKKSTLKShareRecord tryFromDatabase:key.uuid + receiverPeerID:receiver.peerID + senderPeerID:sender.peerID + zoneID:key.zoneID + error:&localerror]; + if(localerror) { + secerror("ckksshare: couldn't load old share for %@: %@", key, localerror); + if(error) { + *error = localerror; + } + return nil; + } + + CKKSTLKShare* share = [CKKSTLKShare share:key.keycore + as:sender + to:receiver + epoch:epoch + poisoned:poisoned + error:error]; + if(!share) { + return nil; + } + + CKKSTLKShareRecord* sharerecord = [[CKKSTLKShareRecord alloc] init:share + zoneID:key.zoneID + encodedCKRecord:oldShare.encodedCKRecord]; + return sharerecord; +} + +- (CKKSKey*)recoverTLK:(id)recoverer + trustedPeers:(NSSet>*)peers + error:(NSError* __autoreleasing *)error +{ + CKKSKeychainBackedKey* realkey = [self.share recoverTLK:recoverer + trustedPeers:peers + ckrecord:self.storedCKRecord + error:error]; + if(!realkey) { + return nil; + } + return [[CKKSKey alloc] initWithKeyCore:realkey]; +} + +#pragma mark - Database Operations + ++ (instancetype)fromDatabase:(NSString*)uuid + receiverPeerID:(NSString*)receiverPeerID + senderPeerID:(NSString*)senderPeerID + zoneID:(CKRecordZoneID*)zoneID + error:(NSError * __autoreleasing *)error { + return [self fromDatabaseWhere: @{@"uuid":CKKSNilToNSNull(uuid), + @"recvpeerid":CKKSNilToNSNull(receiverPeerID), + @"senderpeerid":CKKSNilToNSNull(senderPeerID), + @"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; +} + ++ (instancetype)tryFromDatabase:(NSString*)uuid + receiverPeerID:(NSString*)receiverPeerID + senderPeerID:(NSString*)senderPeerID + zoneID:(CKRecordZoneID*)zoneID + error:(NSError * __autoreleasing *)error { + return [self tryFromDatabaseWhere: @{@"uuid":CKKSNilToNSNull(uuid), + @"recvpeerid":CKKSNilToNSNull(receiverPeerID), + @"senderpeerid":CKKSNilToNSNull(senderPeerID), + @"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; +} + ++ (NSArray*)allFor:(NSString*)receiverPeerID + keyUUID:(NSString*)uuid + zoneID:(CKRecordZoneID*)zoneID + error:(NSError * __autoreleasing *)error { + return [self allWhere:@{@"recvpeerid":CKKSNilToNSNull(receiverPeerID), + @"uuid":uuid, + @"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; +} + ++ (NSArray*)allForUUID:(NSString*)uuid + zoneID:(CKRecordZoneID*)zoneID + error:(NSError * __autoreleasing *)error { + return [self allWhere:@{@"uuid":CKKSNilToNSNull(uuid), + @"ckzone":CKKSNilToNSNull(zoneID.zoneName)} error:error]; +} + ++ (NSArray*)allInZone:(CKRecordZoneID*)zoneID + error:(NSError * __autoreleasing *)error { + return [self allWhere:@{@"ckzone": CKKSNilToNSNull(zoneID.zoneName)} error:error]; +} + ++ (instancetype)tryFromDatabaseFromCKRecordID:(CKRecordID*)recordID + error:(NSError * __autoreleasing *)error { + // Welp. Try to parse! + NSError *localerror = NULL; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"^tlkshare-(?[0-9A-Fa-f-]*)::(?.*)::(?.*)$" + options:NSRegularExpressionCaseInsensitive + error:&localerror]; + if(localerror) { + if(error) { + *error = localerror; + } + return nil; + } + + NSTextCheckingResult* regexmatch = [regex firstMatchInString:recordID.recordName options:0 range:NSMakeRange(0, recordID.recordName.length)]; + if(!regexmatch) { + if(error) { + *error = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoSuchRecord + description:[NSString stringWithFormat:@"Couldn't parse '%@' as a TLKShare ID", recordID.recordName]]; + } + return nil; + } + + NSString* uuid = [recordID.recordName substringWithRange:[regexmatch rangeWithName:@"uuid"]]; + NSString* receiver = [recordID.recordName substringWithRange:[regexmatch rangeWithName:@"receiver"]]; + NSString* sender = [recordID.recordName substringWithRange:[regexmatch rangeWithName:@"sender"]]; + + return [self tryFromDatabaseWhere: @{@"uuid":CKKSNilToNSNull(uuid), + @"recvpeerid":CKKSNilToNSNull(receiver), + @"senderpeerid":CKKSNilToNSNull(sender), + @"ckzone": CKKSNilToNSNull(recordID.zoneID.zoneName)} error:error]; +} + +#pragma mark - CKKSCKRecordHolder methods + ++ (NSString*)ckrecordPrefix { + return @"tlkshare"; +} + +- (NSString*)CKRecordName { + return [NSString stringWithFormat:@"tlkshare-%@::%@::%@", self.share.tlkUUID, self.share.receiverPeerID, self.share.senderPeerID]; +} + +- (CKRecord*)updateCKRecord:(CKRecord*)record zoneID:(CKRecordZoneID*)zoneID { + if(![record.recordID.recordName isEqualToString: [self CKRecordName]]) { + @throw [NSException + exceptionWithName:@"WrongCKRecordNameException" + reason:[NSString stringWithFormat: @"CKRecord name (%@) was not %@", record.recordID.recordName, [self CKRecordName]] + userInfo:nil]; + } + if(![record.recordType isEqualToString: SecCKRecordTLKShareType]) { + @throw [NSException + exceptionWithName:@"WrongCKRecordTypeException" + reason:[NSString stringWithFormat: @"CKRecordType (%@) was not %@", record.recordType, SecCKRecordTLKShareType] + userInfo:nil]; + } + + record[SecCKRecordSenderPeerID] = self.share.senderPeerID; + record[SecCKRecordReceiverPeerID] = self.share.receiverPeerID; + record[SecCKRecordReceiverPublicEncryptionKey] = [self.share.receiverPublicEncryptionKeySPKI base64EncodedStringWithOptions:0]; + record[SecCKRecordCurve] = [NSNumber numberWithUnsignedInteger:(NSUInteger)self.share.curve]; + record[SecCKRecordVersion] = [NSNumber numberWithUnsignedInteger:(NSUInteger)self.share.version]; + record[SecCKRecordEpoch] = [NSNumber numberWithLong:(long)self.share.epoch]; + record[SecCKRecordPoisoned] = [NSNumber numberWithLong:(long)self.share.poisoned]; + + record[SecCKRecordParentKeyRefKey] = [[CKReference alloc] initWithRecordID: [[CKRecordID alloc] initWithRecordName: self.share.tlkUUID zoneID: zoneID] + action: CKReferenceActionValidate]; + + record[SecCKRecordWrappedKeyKey] = [self.share.wrappedTLK base64EncodedStringWithOptions:0]; + record[SecCKRecordSignature] = [self.share.signature base64EncodedStringWithOptions:0]; + + return record; +} + +- (bool)matchesCKRecord:(CKRecord*)record { + if(![record.recordType isEqualToString: SecCKRecordTLKShareType]) { + return false; + } + + if(![record.recordID.recordName isEqualToString: [self CKRecordName]]) { + return false; + } + + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + return [self isEqual: share]; +} + +- (void)setFromCKRecord: (CKRecord*) record { + if(![record.recordType isEqualToString: SecCKRecordTLKShareType]) { + @throw [NSException + exceptionWithName:@"WrongCKRecordTypeException" + reason:[NSString stringWithFormat: @"CKRecordType (%@) was not %@", record.recordType, SecCKRecordDeviceStateType] + userInfo:nil]; + } + + [self setStoredCKRecord:record]; + + NSData* pubkeydata = CKKSUnbase64NullableString(record[SecCKRecordReceiverPublicEncryptionKey]); + + self.share = [[CKKSTLKShare alloc] initForKey:((CKReference*)record[SecCKRecordParentKeyRefKey]).recordID.recordName + senderPeerID:record[SecCKRecordSenderPeerID] + recieverPeerID:record[SecCKRecordReceiverPeerID] + receiverEncPublicKeySPKI:pubkeydata + curve:[record[SecCKRecordCurve] longValue] // TODO: sanitize + version:[record[SecCKRecordVersion] longValue] + epoch:[record[SecCKRecordEpoch] longValue] + poisoned:[record[SecCKRecordPoisoned] longValue] + wrappedKey:[[NSData alloc] initWithBase64EncodedString:record[SecCKRecordWrappedKeyKey] options:0] + signature:[[NSData alloc] initWithBase64EncodedString:record[SecCKRecordSignature] options:0] + zoneID:record.recordID.zoneID]; +} + +#pragma mark - CKKSSQLDatabaseObject methods + ++ (NSString*)sqlTable { + return @"tlkshare"; +} + ++ (NSArray*)sqlColumns { + return @[@"ckzone", @"uuid", @"senderpeerid", @"recvpeerid", @"recvpubenckey", @"poisoned", @"epoch", @"curve", @"version", @"wrappedkey", @"signature", @"ckrecord"]; +} + +- (NSDictionary*)whereClauseToFindSelf { + return @{@"uuid":self.share.tlkUUID, + @"senderpeerid":self.share.senderPeerID, + @"recvpeerid":self.share.receiverPeerID, + @"ckzone":self.zoneID.zoneName, + }; +} + +- (NSDictionary*)sqlValues { + return @{@"uuid": self.share.tlkUUID, + @"senderpeerid": self.share.senderPeerID, + @"recvpeerid": self.share.receiverPeerID, + @"recvpubenckey": CKKSNilToNSNull([self.share.receiverPublicEncryptionKeySPKI base64EncodedStringWithOptions:0]), + @"poisoned": [NSString stringWithFormat:@"%ld", (long)self.share.poisoned], + @"epoch": [NSString stringWithFormat:@"%ld", (long)self.share.epoch], + @"curve": [NSString stringWithFormat:@"%ld", (long)self.share.curve], + @"version": [NSString stringWithFormat:@"%ld", (long)self.share.version], + @"wrappedkey": CKKSNilToNSNull([self.share.wrappedTLK base64EncodedStringWithOptions:0]), + @"signature": CKKSNilToNSNull([self.share.signature base64EncodedStringWithOptions:0]), + @"ckzone": CKKSNilToNSNull(self.zoneID.zoneName), + @"ckrecord": CKKSNilToNSNull([self.encodedCKRecord base64EncodedStringWithOptions:0]), + }; +} + ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + CKRecordZoneID* zoneID = [[CKRecordZoneID alloc] initWithZoneName: row[@"ckzone"].asString ownerName:CKCurrentUserDefaultName]; + + SFEllipticCurve curve = (SFEllipticCurve)row[@"curve"].asNSInteger; // TODO: sanitize + SecCKKSTLKShareVersion version = (SecCKKSTLKShareVersion)row[@"version"].asNSInteger; // TODO: sanitize + + return [[CKKSTLKShareRecord alloc] initForKey:row[@"uuid"].asString + senderPeerID:row[@"senderpeerid"].asString + recieverPeerID:row[@"recvpeerid"].asString + receiverEncPublicKeySPKI:row[@"recvpubenckey"].asBase64DecodedData + curve:curve + version:version + epoch:row[@"epoch"].asNSInteger + poisoned:row[@"poisoned"].asNSInteger + wrappedKey:row[@"wrappedkey"].asBase64DecodedData + signature:row[@"signature"].asBase64DecodedData + zoneID:zoneID + encodedCKRecord:row[@"ckrecord"].asBase64DecodedData + ]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m index ec3fc8b6..aeb57d81 100644 --- a/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m +++ b/keychain/ckks/CKKSUpdateCurrentItemPointerOperation.m @@ -31,6 +31,7 @@ #import "keychain/ckks/CKKSManifest.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" #include #include @@ -98,7 +99,7 @@ return; } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); [ckks dispatchSyncWithAccountKeys:^bool { if(self.cancelled) { @@ -278,13 +279,14 @@ // 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.configuration.isCloudKitSupportOperation = YES; self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; self.modifyRecordsOperation.group = self.ckoperationGroup; self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* blockCKKS = self.ckks; if(!error) { ckksnotice("ckkscurrent", blockCKKS, "Current pointer upload successful for %@: %@", record.recordID.recordName, record); @@ -294,11 +296,11 @@ }; self.modifyRecordsOperation.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *ckerror) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf || !strongCKKS) { + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; + if(!self || !strongCKKS) { ckkserror("ckkscurrent", strongCKKS, "received callback for released object"); - strongSelf.error = [NSError errorWithDomain:CKKSErrorDomain + self.error = [NSError errorWithDomain:CKKSErrorDomain code:errSecInternalError description:@"no CKKS object"]; [strongCKKS scheduleOperation: modifyComplete]; @@ -307,7 +309,7 @@ if(ckerror) { ckkserror("ckkscurrent", strongCKKS, "CloudKit returned an error: %@", ckerror); - strongSelf.error = ckerror; + self.error = ckerror; [strongCKKS dispatchSync:^bool { return [strongCKKS _onqueueCKWriteFailed:ckerror attemptedRecordsChanged:recordsToSave]; @@ -338,7 +340,7 @@ [manifest saveToDatabase:&error]; if (error) { ckkserror("ckkscurrent", strongCKKS, "Couldn't save %@ to manifest: %@", record.recordID.recordName, error); - strongSelf.error = error; + self.error = error; } } @@ -348,7 +350,7 @@ return true; }]; - strongSelf.error = error; + self.error = error; [strongCKKS scheduleOperation: modifyComplete]; }; diff --git a/keychain/ckks/CKKSUpdateDeviceStateOperation.h b/keychain/ckks/CKKSUpdateDeviceStateOperation.h index 59507bb5..5e21ed6e 100644 --- a/keychain/ckks/CKKSUpdateDeviceStateOperation.h +++ b/keychain/ckks/CKKSUpdateDeviceStateOperation.h @@ -27,6 +27,8 @@ #import "keychain/ckks/CKKSDeviceStateEntry.h" #import "keychain/ckks/CKKSGroupOperation.h" +NS_ASSUME_NONNULL_BEGIN + @interface CKKSUpdateDeviceStateOperation : CKKSGroupOperation @property (weak) CKKSKeychainView* ckks; @@ -36,4 +38,5 @@ ckoperationGroup:(CKOperationGroup*)group; @end +NS_ASSUME_NONNULL_END #endif // OCTAGON diff --git a/keychain/ckks/CKKSUpdateDeviceStateOperation.m b/keychain/ckks/CKKSUpdateDeviceStateOperation.m index 6223fcf0..7905d589 100644 --- a/keychain/ckks/CKKSUpdateDeviceStateOperation.m +++ b/keychain/ckks/CKKSUpdateDeviceStateOperation.m @@ -30,6 +30,7 @@ #import "keychain/ckks/CKKSKey.h" #import "keychain/ckks/CKKSLockStateTracker.h" #import "keychain/ckks/CKKSSQLDatabaseObject.h" +#import "keychain/ot/ObjCImprovements.h" @interface CKKSUpdateDeviceStateOperation () @property CKModifyRecordsOperation* modifyRecordsOperation; @@ -56,14 +57,14 @@ return; } - CKKSCKAccountStateTracker* accountTracker = ckks.accountTracker; + CKKSAccountStateTracker* accountTracker = ckks.accountTracker; if(!accountTracker) { ckkserror("ckksdevice", ckks, "no AccountTracker object"); self.error = [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"no AccountTracker object"}]; return; } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // We must have the ck device ID to run this operation. if([accountTracker.ckdeviceIDInitialized wait:200*NSEC_PER_SEC]) { @@ -72,7 +73,8 @@ return; } - if(!accountTracker.ckdeviceID) { + NSString* ckdeviceID = accountTracker.ckdeviceID; + if(!ckdeviceID) { ckkserror("ckksdevice", ckks, "CK device ID not initialized, quitting"); self.error = [NSError errorWithDomain:@"securityd" code:errSecInternalError @@ -80,11 +82,16 @@ return; } + // We'd also really like to know the HSA2-ness of the world + if([accountTracker.hsa2iCloudAccountInitialized wait:500*NSEC_PER_MSEC]) { + ckkserror("ckksdevice", ckks, "Not quite sure if the account isa HSA2 or not. Probably will quit?"); + } + [ckks dispatchSyncWithAccountKeys:^bool { NSError* error = nil; CKKSDeviceStateEntry* cdse = [ckks _onqueueCurrentDeviceStateEntry:&error]; - if(error) { + if(error || !cdse) { ckkserror("ckksdevice", ckks, "Error creating device state entry; quitting: %@", error); return false; } @@ -129,8 +136,8 @@ self.modifyRecordsOperation.group = self.group; self.modifyRecordsOperation.perRecordCompletionBlock = ^(CKRecord *record, NSError * _Nullable error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) blockCKKS = strongSelf.ckks; + STRONGIFY(self); + CKKSKeychainView* blockCKKS = self.ckks; if(!error) { ckksnotice("ckksdevice", blockCKKS, "Device state record upload successful for %@: %@", record.recordID.recordName, record); @@ -140,19 +147,19 @@ }; self.modifyRecordsOperation.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *ckerror) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - __strong __typeof(strongSelf.ckks) strongCKKS = strongSelf.ckks; - if(!strongSelf || !strongCKKS) { + STRONGIFY(self); + CKKSKeychainView* strongCKKS = self.ckks; + if(!self || !strongCKKS) { ckkserror("ckksdevice", strongCKKS, "received callback for released object"); - strongSelf.error = [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"no CKKS object"}]; - [strongSelf runBeforeGroupFinished:modifyComplete]; + self.error = [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"no CKKS object"}]; + [self runBeforeGroupFinished:modifyComplete]; return; } if(ckerror) { ckkserror("ckksdevice", strongCKKS, "CloudKit returned an error: %@", ckerror); - strongSelf.error = ckerror; - [strongSelf runBeforeGroupFinished:modifyComplete]; + self.error = ckerror; + [self runBeforeGroupFinished:modifyComplete]; return; } @@ -172,8 +179,8 @@ return true; }]; - strongSelf.error = error; - [strongSelf runBeforeGroupFinished:modifyComplete]; + self.error = error; + [self runBeforeGroupFinished:modifyComplete]; }; [self dependOnBeforeGroupFinished: self.modifyRecordsOperation]; diff --git a/keychain/ckks/CKKSViewManager.h b/keychain/ckks/CKKSViewManager.h index 7a63416e..82c8ac34 100644 --- a/keychain/ckks/CKKSViewManager.h +++ b/keychain/ckks/CKKSViewManager.h @@ -28,8 +28,9 @@ #include #import "keychain/ckks/CKKS.h" -#import "keychain/ckks/CKKSAPSReceiver.h" -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/OctagonAPSReceiver.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" +#import "keychain/ckks/CKKSCloudKitClassDependencies.h" #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CKKSControlProtocol.h" #import "keychain/ckks/CKKSLockStateTracker.h" @@ -39,47 +40,50 @@ #import "keychain/ckks/CKKSRateLimiter.h" #import "keychain/ckks/CloudKitDependencies.h" #import "keychain/ckks/CKKSZoneChangeFetcher.h" +#import "keychain/ckks/CKKSZoneModifier.h" + +#import "keychain/ot/OTSOSAdapter.h" #import "keychain/ot/OTDefines.h" NS_ASSUME_NONNULL_BEGIN -@class CKKSKeychainView, CKKSRateLimiter; +@class CKKSKeychainView, CKKSRateLimiter, TPPolicy; -@interface CKKSViewManager : NSObject +@interface CKKSViewManager : NSObject @property CKContainer* container; -@property CKKSCKAccountStateTracker* accountTracker; +@property CKKSAccountStateTracker* accountTracker; @property CKKSLockStateTracker* lockStateTracker; @property CKKSReachabilityTracker *reachabilityTracker; @property CKKSZoneChangeFetcher* zoneChangeFetcher; -@property bool initializeNewZones; +@property CKKSZoneModifier* zoneModifier; // Signaled when SecCKKSInitialize is complete, as it's async and likes to fire after tests are complete @property CKKSCondition* completedSecCKKSInitialize; @property CKKSRateLimiter* globalRateLimiter; -- (instancetype)initCloudKitWithContainerName:(NSString*)containerName usePCS:(bool)usePCS; +@property id sosPeerAdapter; + +@property (nullable) TPPolicy* policy; + +@property NSMutableDictionary* views; + - (instancetype)initWithContainerName:(NSString*)containerName - usePCS:(bool)usePCS - fetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:(Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass:(Class)modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:(Class)modifyRecordZonesOperationClass - apsConnectionClass:(Class)apsConnectionClass - nsnotificationCenterClass:(Class)nsnotificationCenterClass - notifierClass:(Class)notifierClass; + usePCS:(bool)usePCS + sosAdapter:(id _Nullable)sosAdapter + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies; - (CKKSKeychainView*)findView:(NSString*)viewName; - (CKKSKeychainView*)findOrCreateView:(NSString*)viewName; - (void)setView:(CKKSKeychainView*)obj; - (void)clearView:(NSString*)viewName; +- (NSSet*)currentViews; + - (NSDictionary*)activeTLKs; -// Call this to bring zones up (and to do so automatically in the future) -- (void)initializeZones; +- (void)setupAnalytics; - (NSString*)viewNameForItem:(SecDbItemRef)item; @@ -103,8 +107,6 @@ NS_ASSUME_NONNULL_BEGIN fetchCloudValue:(bool)fetchCloudValue complete:(void (^)(NSString* uuid, NSError* operror))complete; -- (NSString*)viewNameForAttributes:(NSDictionary*)item; - - (void)registerSyncStatusCallback:(NSString*)uuid callback:(SecBoolNSErrorCallback)callback; // Cancels pending operations owned by this view manager @@ -121,23 +123,28 @@ NS_ASSUME_NONNULL_BEGIN - (CKKSKeychainView*)restartZone:(NSString*)viewName; // Returns the viewList for a CKKSViewManager -- (NSSet*)viewList; +- (NSSet*)viewList; + +- (NSSet*)defaultViewList; + +- (void)setViewList:(NSSet* _Nullable)newViewList; + +- (void)clearAllViews; + +// Create all views, but don't begin CK/network operations +- (void)createViews; + +// Call this to begin CK operation of all views +- (void)beginCloudKitOperationOfAllViews; // Notify sbd to re-backup. - (void)notifyNewTLKsInKeychain; - (void)syncBackupAndNotifyAboutSync; -// Fetch peers from SOS -- (CKKSSelves* _Nullable)fetchSelfPeers:(NSError* __autoreleasing*)error; -- (NSSet>* _Nullable)fetchTrustedPeers:(NSError* __autoreleasing*)error; - -// For mocking purposes -- (id _Nullable)currentSOSSelf:(NSError**)error; -- (NSSet>*)pastSelves:(NSError**)error; -- (NSArray* _Nullable)loadRestoredBottledKeysOfType:(OctagonKeyType)keyType error:(NSError**)error; - -- (void)sendSelfPeerChangedUpdate; -- (void)sendTrustedPeerSetChangedUpdate; +// For testing +- (void)setOverrideCKKSViewsFromPolicy:(BOOL)value; +- (BOOL)useCKKSViewsFromPolicy; +- (void)haltAll; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/CKKSViewManager.m b/keychain/ckks/CKKSViewManager.m index 2de04ab9..1db3c5df 100644 --- a/keychain/ckks/CKKSViewManager.m +++ b/keychain/ckks/CKKSViewManager.m @@ -21,6 +21,8 @@ * @APPLE_LICENSE_HEADER_END@ */ +#import + #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSSynchronizeOperation.h" @@ -29,10 +31,17 @@ #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKSNotifier.h" #import "keychain/ckks/CKKSCondition.h" +#import "keychain/ckks/CKKSListenerCollection.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/analytics/SecEventMetric.h" +#import "keychain/analytics/SecMetrics.h" #import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/ObjCImprovements.h" + +#import "TPPolicy.h" #import "SecEntitlements.h" @@ -44,7 +53,7 @@ #import #import -#include +#include "keychain/SecureObjectSync/SOSAccount.h" #include #if OCTAGON @@ -62,22 +71,17 @@ @property NSXPCListener *listener; // Once you set these, all CKKSKeychainViews created will use them -@property (readonly) Class fetchRecordZoneChangesOperationClass; -@property (readonly) Class fetchRecordsOperationClass; -@property (readonly) Class queryOperationClass; -@property (readonly) Class modifySubscriptionsOperationClass; -@property (readonly) Class modifyRecordZonesOperationClass; -@property (readonly) Class apsConnectionClass; -@property (readonly) Class notifierClass; -@property (readonly) Class nsnotificationCenterClass; - -@property NSMutableDictionary* views; +@property CKKSCloudKitClassDependencies* cloudKitClassDependencies; @property NSMutableDictionary* pendingSyncCallbacks; @property CKKSNearFutureScheduler* savedTLKNotifier;; @property NSOperationQueue* operationQueue; -@property NSMapTable>* peerChangeListeners; +@property CKKSListenerCollection>* peerChangeListenerCollection; + +@property (nonatomic) BOOL overrideCKKSViewsFromPolicy; +@property (nonatomic) BOOL valueCKKSViewsFromPolicy; + #endif @end @@ -89,84 +93,54 @@ @implementation CKKSViewManager #if OCTAGON -- (instancetype)initCloudKitWithContainerName: (NSString*) containerName usePCS:(bool)usePCS { - return [self initWithContainerName:containerName - usePCS:usePCS - fetchRecordZoneChangesOperationClass:[CKFetchRecordZoneChangesOperation class] - fetchRecordsOperationClass:[CKFetchRecordsOperation class] - queryOperationClass:[CKQueryOperation class] - modifySubscriptionsOperationClass:[CKModifySubscriptionsOperation class] - modifyRecordZonesOperationClass:[CKModifyRecordZonesOperation class] - apsConnectionClass:[APSConnection class] - nsnotificationCenterClass:[NSNotificationCenter class] - notifierClass:[CKKSNotifyPostNotifier class]]; -} +NSSet* _viewList; - (instancetype)initWithContainerName: (NSString*) containerName usePCS: (bool)usePCS - fetchRecordZoneChangesOperationClass: (Class) fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass: (Class)fetchRecordsOperationClass - queryOperationClass: (Class)queryOperationClass - modifySubscriptionsOperationClass: (Class) modifySubscriptionsOperationClass - modifyRecordZonesOperationClass: (Class) modifyRecordZonesOperationClass - apsConnectionClass: (Class) apsConnectionClass - nsnotificationCenterClass: (Class) nsnotificationCenterClass - notifierClass: (Class) notifierClass + sosAdapter:(id _Nullable)sosAdapter + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies { if(self = [super init]) { - _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass; - _fetchRecordsOperationClass = fetchRecordsOperationClass; - _queryOperationClass = queryOperationClass; - _modifySubscriptionsOperationClass = modifySubscriptionsOperationClass; - _modifyRecordZonesOperationClass = modifyRecordZonesOperationClass; - _apsConnectionClass = apsConnectionClass; - _nsnotificationCenterClass = nsnotificationCenterClass; - _notifierClass = notifierClass; + _cloudKitClassDependencies = cloudKitClassDependencies; + _sosPeerAdapter = sosAdapter; + _viewList = nil; _container = [self makeCKContainer: containerName usePCS:usePCS]; - _accountTracker = [[CKKSCKAccountStateTracker alloc] init:self.container nsnotificationCenterClass:nsnotificationCenterClass]; + _accountTracker = [[CKKSAccountStateTracker alloc] init:self.container nsnotificationCenterClass:cloudKitClassDependencies.nsnotificationCenterClass]; _lockStateTracker = [[CKKSLockStateTracker alloc] init]; [_lockStateTracker addLockStateObserver:self]; _reachabilityTracker = [[CKKSReachabilityTracker alloc] init]; _zoneChangeFetcher = [[CKKSZoneChangeFetcher alloc] initWithContainer:_container - fetchClass:fetchRecordZoneChangesOperationClass + fetchClass:cloudKitClassDependencies.fetchRecordZoneChangesOperationClass reachabilityTracker:_reachabilityTracker]; + _zoneModifier = [[CKKSZoneModifier alloc] initWithContainer:_container + reachabilityTracker:_reachabilityTracker + cloudkitDependencies:cloudKitClassDependencies]; + _operationQueue = [[NSOperationQueue alloc] init]; - // Backwards from how we'd like, but it's the best way to have weak pointers to CKKSPeerUpdateListener. - _peerChangeListeners = [NSMapTable strongToWeakObjectsMapTable]; + _peerChangeListenerCollection = [[CKKSListenerCollection alloc] initWithName:@"sos-peer-set"]; _views = [[NSMutableDictionary alloc] init]; _pendingSyncCallbacks = [[NSMutableDictionary alloc] init]; - _initializeNewZones = false; - _completedSecCKKSInitialize = [[CKKSCondition alloc] init]; - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); _savedTLKNotifier = [[CKKSNearFutureScheduler alloc] initWithName:@"newtlks" delay:5*NSEC_PER_SEC keepProcessAlive:true dependencyDescriptionCode:CKKSResultDescriptionNone block:^{ - [weakSelf notifyNewTLKsInKeychain]; + STRONGIFY(self); + [self notifyNewTLKsInKeychain]; }]; _listener = [NSXPCListener anonymousListener]; _listener.delegate = self; [_listener resume]; - - // If this is a live server, register with notify - if(!SecCKKSTestsEnabled()) { - int token = 0; - notify_register_dispatch(kSOSCCCircleOctagonKeysChangedNotification, &token, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^(int t) { - // Since SOS doesn't change the self peer, we can reliably just send "trusted peers changed"; it'll be mostly right - secnotice("ckksshare", "Received a notification that the SOS Octagon peer set changed"); - [weakSelf sendTrustedPeerSetChangedUpdate]; - }); - } } return self; } @@ -185,7 +159,7 @@ - (void)setupAnalytics { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // Tests shouldn't continue here; it leads to entitlement crashes with CloudKit if the mocks aren't enabled when this function runs if(SecCKKSTestsEnabled()) { @@ -193,19 +167,25 @@ } [[CKKSAnalytics logger] AddMultiSamplerForName:@"CKKS-healthSummary" withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { return nil; } + NSError* sosCircleError = nil; + SOSCCStatus sosStatus = [self.sosPeerAdapter circleStatus:&sosCircleError]; + if(sosCircleError) { + secerror("CKKSViewManager: couldn't fetch sos status for SF report: %@", sosCircleError); + } + NSMutableDictionary* values = [NSMutableDictionary dictionary]; - BOOL inCircle = (strongSelf.accountTracker.currentCircleStatus.status == kSOSCCInCircle); + BOOL inCircle = (sosStatus == kSOSCCInCircle); if (inCircle) { [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:CKKSAnalyticsLastInCircle]; } values[CKKSAnalyticsInCircle] = @(inCircle); - BOOL validCredentials = strongSelf.accountTracker.currentCKAccountInfo.hasValidCredentials; + BOOL validCredentials = self.accountTracker.currentCKAccountInfo.hasValidCredentials; if (!validCredentials) { values[CKKSAnalyticsValidCredentials] = @(validCredentials); } @@ -220,13 +200,19 @@ for (NSString* viewName in [self viewList]) { [[CKKSAnalytics logger] AddMultiSamplerForName:[NSString stringWithFormat:@"CKKS-%@-healthSummary", viewName] withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { return nil; } - BOOL inCircle = strongSelf.accountTracker && strongSelf.accountTracker.currentCircleStatus.status == kSOSCCInCircle; + + NSError* sosCircleError = nil; + SOSCCStatus sosStatus = [self.sosPeerAdapter circleStatus:&sosCircleError]; + if(sosCircleError) { + secerror("CKKSViewManager: couldn't fetch sos status for SF report: %@", sosCircleError); + } + BOOL inCircle = (sosStatus == kSOSCCInCircle); NSMutableDictionary* values = [NSMutableDictionary dictionary]; - CKKSKeychainView* view = [strongSelf findOrCreateView:viewName]; + CKKSKeychainView* view = [self findOrCreateView:viewName]; NSDate* dateOfLastSyncClassA = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassA inView:view]; NSDate* dateOfLastSyncClassC = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:view]; NSDate* dateOfLastKSR = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastKeystateReady inView:view]; @@ -313,9 +299,42 @@ dispatch_once_t globalZoneStateQueueOnce; } } -// Mostly exists to be mocked out. --(NSSet*)viewList { - return CFBridgingRelease(SOSViewCopyViewSet(kViewSetCKKS)); +- (NSSet*)defaultViewList { + NSSet* fullList = [OTSOSActualAdapter sosCKKSViewList]; + + // Not a great hack: if this platform is an aTV or a HomePod, then filter its list of views + bool filter = false; + +#if TARGET_OS_TV + filter = true; +#elif TARGET_OS_WATCH + filter = false; +#elif TARGET_OS_IOS + filter = !OctagonPlatformSupportsSOS(); +#elif TARGET_OS_OSX + filter = false; +#endif + + if(filter) { + // For now, use a hardcoded allow list for TV/HomePod + NSMutableSet* allowList = [NSMutableSet setWithArray:@[@"Home", @"LimitedPeersAllowed"]]; + [allowList intersectSet:fullList]; + return allowList; + } + + return fullList; +} + +-(NSSet*)viewList { + if (_viewList) { + return _viewList; + } else { + return [self defaultViewList]; + } +} + +- (void)setViewList:(NSSet* _Nullable)newViewList { + _viewList = newViewList; } - (void)setView: (CKKSKeychainView*) obj { @@ -377,21 +396,39 @@ dispatch_once_t globalZoneStateQueueOnce; lockStateTracker: self.lockStateTracker reachabilityTracker: self.reachabilityTracker changeFetcher:self.zoneChangeFetcher + zoneModifier:self.zoneModifier savedTLKNotifier: self.savedTLKNotifier - peerProvider:self - fetchRecordZoneChangesOperationClass: self.fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass: self.fetchRecordsOperationClass - queryOperationClass:self.queryOperationClass - modifySubscriptionsOperationClass: self.modifySubscriptionsOperationClass - modifyRecordZonesOperationClass: self.modifyRecordZonesOperationClass - apsConnectionClass: self.apsConnectionClass - notifierClass: self.notifierClass]; - - if(self.initializeNewZones) { - [self.views[viewName] initializeZone]; + cloudKitClassDependencies:self.cloudKitClassDependencies]; + return self.views[viewName]; + } +} + +- (NSSet*)currentViews +{ + @synchronized (self.views) { + NSMutableSet* viewObjects = [NSMutableSet set]; + for(NSString* viewName in self.views) { + [viewObjects addObject:self.views[viewName]]; } + return viewObjects; + } +} - return self.views[viewName]; +- (void)createViews +{ + // In the future, the CKKSViewManager needs to persist its policy property through daemon restarts + // and load it here, before creating whatever views it was told to (in a previous daemon lifetime) + for (NSString* viewName in self.viewList) { + CKKSKeychainView* view = [self findOrCreateView:viewName]; + (void)view; + } +} + +- (void)beginCloudKitOperationOfAllViews +{ + for (NSString* viewName in self.viewList) { + CKKSKeychainView* view = [self findView:viewName]; + [view beginCloudKitOperation]; } } @@ -418,25 +455,6 @@ dispatch_once_t globalZoneStateQueueOnce; return [self findOrCreateView: viewName]; } -// Allows all views to begin initializing, and opens the floodgates so that new views will be initalized immediately -- (void)initializeZones { - if(!SecCKKSIsEnabled()) { - secnotice("ckks", "Not initializing CKKS view set as CKKS is disabled"); - return; - } - - @synchronized(self.views) { - self.initializeNewZones = true; - - NSSet* viewSet = [self viewList]; - for(NSString* s in viewSet) { - [self findOrCreateView:s]; // initializes any newly-created views - } - } - - [self setupAnalytics]; -} - - (NSString*)viewNameForViewHint: (NSString*) viewHint { // For now, choose view based on viewhints. if(viewHint && ![viewHint isEqual: [NSNull null]]) { @@ -451,21 +469,50 @@ dispatch_once_t globalZoneStateQueueOnce; } } -- (NSString*)viewNameForItem: (SecDbItemRef) item { - CFErrorRef cferror = NULL; - NSString* viewHint = (__bridge NSString*) SecDbItemGetValue(item, &v7vwht, &cferror); +- (void) setOverrideCKKSViewsFromPolicy:(BOOL)value { + _overrideCKKSViewsFromPolicy = YES; + _valueCKKSViewsFromPolicy = value; +} - if(cferror) { - secerror("ckks: Couldn't fetch the viewhint for some reason: %@", cferror); - CFReleaseNull(cferror); - viewHint = nil; +- (BOOL)useCKKSViewsFromPolicy { + if (self.overrideCKKSViewsFromPolicy) { + return self.valueCKKSViewsFromPolicy; + } else { + return os_feature_enabled(Security, CKKSViewsFromPolicy); } - - return [self viewNameForViewHint: viewHint]; } -- (NSString*)viewNameForAttributes: (NSDictionary*) item { - return [self viewNameForViewHint: item[(id)kSecAttrSyncViewHint]]; +- (NSString*)viewNameForItem: (SecDbItemRef) item { + if ([self useCKKSViewsFromPolicy]) { + CFErrorRef cferror = NULL; + NSMutableDictionary *dict = (__bridge_transfer NSMutableDictionary*) SecDbItemCopyPListWithMask(item, ~0, &cferror); + + if(cferror) { + secerror("ckks: Couldn't fetch attributes from item: %@", cferror); + CFReleaseNull(cferror); + return [self viewNameForViewHint: nil]; + } + TPPolicy* policy = self.policy; + if (policy == nil) { + return [self viewNameForViewHint: nil]; + } + NSString* view = [policy mapKeyToView:dict]; + if (view == nil) { + return [self viewNameForViewHint: nil]; + } + return view; + } else { + CFErrorRef cferror = NULL; + NSString* viewHint = (__bridge NSString*) SecDbItemGetValue(item, &v7vwht, &cferror); + + if(cferror) { + secerror("ckks: Couldn't fetch the viewhint for some reason: %@", cferror); + CFReleaseNull(cferror); + viewHint = nil; + } + + return [self viewNameForViewHint: viewHint]; + } } - (void)registerSyncStatusCallback: (NSString*) uuid callback: (SecBoolNSErrorCallback) callback { @@ -520,7 +567,11 @@ dispatch_once_t globalZoneStateQueueOnce; } if(!view) { - secinfo("ckks", "No CKKS view for %@, skipping: %@", viewName, modified); + if(viewName) { + secnotice("ckks", "No CKKS view for %@, skipping: %@", viewName, modified); + } else { + secinfo("ckks", "No CKKS view for %@, skipping: %@", viewName, modified); + } if(syncCallback) { syncCallback(false, [NSError errorWithDomain:@"securityd" code:kSOSCCNoSuchView @@ -605,7 +656,11 @@ dispatch_once_t globalZoneStateQueueOnce; [manager clearAllViews]; manager = nil; } else if (manager == nil && SecCKKSIsEnabled()) { - manager = [[CKKSViewManager alloc] initCloudKitWithContainerName:SecCKKSContainerName usePCS:SecCKKSContainerUsePCS]; + // The CKKSViewManager doesn't do much with its adapter, so leave as nonessentialq + manager = [[CKKSViewManager alloc] initWithContainerName:SecCKKSContainerName + usePCS:SecCKKSContainerUsePCS + sosAdapter:[[OTSOSActualAdapter alloc] initAsEssential:NO] + cloudKitClassDependencies:[CKKSCloudKitClassDependencies forLiveCloudKit]]; } } } @@ -712,13 +767,6 @@ 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]; @@ -728,7 +776,12 @@ dispatch_once_t globalZoneStateQueueOnce; return; } - CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-reset-zones-waiter" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull strongOp) { + CKKSResultOperation* op = [CKKSResultOperation named:@"cloudkit-reset-zones-waiter" withBlock:^() {}]; + + // Use the completion block instead of the operation block, so that it runs even if the cancel fires + __weak __typeof(op) weakOp = op; + [op setCompletionBlock:^{ + __strong __typeof(op) strongOp = weakOp; if(!strongOp.error) { secnotice("ckksreset", "Completed rpcResetCloudKit"); } else { @@ -759,9 +812,12 @@ dispatch_once_t globalZoneStateQueueOnce; CKKSResultOperation* op = [[CKKSResultOperation alloc] init]; op.name = @"rpc-resync-cloudkit"; __weak __typeof(op) weakOp = op; - [op addExecutionBlock:^{ + + // Use the completion block instead of the operation block, so that it runs even if the cancel fires + [op setCompletionBlock:^{ __strong __typeof(op) strongOp = weakOp; secnotice("ckks", "Ending rsync-CloudKit rpc with %@", strongOp.error); + reply(CKXPCSuitableError(strongOp.error)); }]; for(CKKSKeychainView* view in actualViews) { @@ -773,8 +829,6 @@ dispatch_once_t globalZoneStateQueueOnce; [op timeout:120*NSEC_PER_SEC]; [self.operationQueue addOperation:op]; - [op waitUntilFinished]; - reply(CKXPCSuitableError(op.error)); } - (void)rpcResyncLocal:(NSString*)viewName reply:(void(^)(NSError* result))reply { @@ -789,7 +843,8 @@ dispatch_once_t globalZoneStateQueueOnce; CKKSResultOperation* op = [[CKKSResultOperation alloc] init]; op.name = @"rpc-resync-local"; __weak __typeof(op) weakOp = op; - [op addExecutionBlock:^{ + // Use the completion block instead of the operation block, so that it runs even if the cancel fires + [op setCompletionBlock:^{ __strong __typeof(op) strongOp = weakOp; secnotice("ckks", "Ending rsync-local rpc with %@", strongOp.error); reply(CKXPCSuitableError(strongOp.error)); @@ -806,9 +861,8 @@ dispatch_once_t globalZoneStateQueueOnce; } - (void)rpcStatus: (NSString*)viewName - global:(bool)reportGlobal + fast:(bool)fast reply:(void(^)(NSArray* result, NSError* error)) reply - viewBlock:(NSDictionary * (^)(CKKSKeychainView* view))viewBlock { NSMutableArray* a = [[NSMutableArray alloc] init]; @@ -820,44 +874,36 @@ dispatch_once_t globalZoneStateQueueOnce; return; } - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* statusOp = [CKKSResultOperation named:@"status-rpc" withBlock:^{ - __strong __typeof(self) strongSelf = weakSelf; - - if (reportGlobal) { - // The first element is always the current global state (non-view-specific) - NSError* selfPeersError = nil; - CKKSSelves* selves = [strongSelf fetchSelfPeers:&selfPeersError]; - NSError* trustedPeersError = nil; - NSSet>* peers = [strongSelf fetchTrustedPeers:&trustedPeersError]; + STRONGIFY(self); + if (fast == false) { // Get account state, even wait for it a little [self.accountTracker.ckdeviceIDInitialized wait:1*NSEC_PER_SEC]; NSString *deviceID = self.accountTracker.ckdeviceID; NSError *deviceIDError = self.accountTracker.ckdeviceIDError; - NSMutableArray* mutTrustedPeers = [[NSMutableArray alloc] init]; - [peers enumerateObjectsUsingBlock:^(id _Nonnull obj, BOOL * _Nonnull stop) { - [mutTrustedPeers addObject: [obj description]]; - }]; - #define stringify(obj) CKKSNilToNSNull([obj description]) NSDictionary* global = @{ @"view": @"global", - @"selfPeers": stringify(selves), - @"selfPeersError": CKKSNilToNSNull(selfPeersError), - @"trustedPeers": CKKSNilToNSNull(mutTrustedPeers), - @"trustedPeersError": CKKSNilToNSNull(trustedPeersError), - @"reachability": strongSelf.reachabilityTracker.currentReachability ? @"network" : @"no-network", + @"reachability": self.reachabilityTracker.currentReachability ? @"network" : @"no-network", @"ckdeviceID": CKKSNilToNSNull(deviceID), @"ckdeviceIDError": CKKSNilToNSNull(deviceIDError), + @"lockstatetracker": stringify(self.lockStateTracker), + @"cloudkitRetryAfter": stringify(self.zoneModifier.cloudkitRetryAfter), }; [a addObject: global]; } for(CKKSKeychainView* view in actualViews) { + NSDictionary* status = nil; ckksnotice("ckks", view, "Fetching status for %@", view.zoneName); - NSDictionary* status = viewBlock(view); + if (fast) { + status = [view fastStatus]; + } else { + status = [view status]; + } ckksinfo("ckks", view, "Status is %@", status); if(status) { [a addObject: status]; @@ -867,17 +913,17 @@ dispatch_once_t globalZoneStateQueueOnce; }]; // If we're signed in, give the views a few seconds to enter what they consider to be a non-transient state (in case this daemon just launched) - if([self.accountTracker.currentComputedAccountStatusValid wait:5*NSEC_PER_SEC]) { - secerror("ckks status: Haven't yet figured out login state"); + if([self.accountTracker.ckAccountInfoInitialized wait:5*NSEC_PER_SEC]) { + secerror("ckks status: Haven't yet figured out cloudkit account state"); } - if(self.accountTracker.currentComputedAccountStatus == CKKSAccountStatusAvailable) { + if(self.accountTracker.currentCKAccountInfo.accountStatus == CKAccountStatusAvailable) { CKKSResultOperation* blockOp = [CKKSResultOperation named:@"wait-for-status" withBlock:^{}]; [blockOp timeout:8*NSEC_PER_SEC]; for(CKKSKeychainView* view in actualViews) { [blockOp addNullableDependency:view.keyStateNonTransientDependency]; - [statusOp addDependency:blockOp]; } + [statusOp addDependency:blockOp]; [self.operationQueue addOperation:blockOp]; } [self.operationQueue addOperation:statusOp]; @@ -887,16 +933,12 @@ dispatch_once_t globalZoneStateQueueOnce; - (void)rpcStatus:(NSString*)viewName reply:(void (^)(NSArray* result, NSError* error))reply { - [self rpcStatus:viewName global:true reply:reply viewBlock:^NSDictionary *(CKKSKeychainView *view) { - return [view status]; - }]; + [self rpcStatus:viewName fast:false reply:reply]; } - (void)rpcFastStatus:(NSString*)viewName reply:(void (^)(NSArray* result, NSError* error))reply { - [self rpcStatus:viewName global:false reply:reply viewBlock:^NSDictionary *(CKKSKeychainView *view) { - return [view fastStatus]; - }]; + [self rpcStatus:viewName fast:true reply:reply]; } - (void)rpcFetchAndProcessChanges:(NSString*)viewName reply: (void(^)(NSError* result))reply { @@ -967,9 +1009,28 @@ dispatch_once_t globalZoneStateQueueOnce; reply(self.accountTracker.ckdeviceID); } +- (void)rpcCKMetric:(NSString *)eventName attributes:(NSDictionary *)attributes reply:(void (^)(NSError *))reply +{ + if (eventName == NULL) { + reply([NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoMetric + description:@"No metric name"]); + return; + } + SecEventMetric *metric = [[SecEventMetric alloc] initWithEventName:eventName]; + [attributes enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull __unused stop) { + metric[key] = obj; + }]; + [[SecMetrics managerObject] submitEvent:metric]; + reply(NULL); + +} + -(void)xpc24HrNotification { // XPC has poked us and said we should do some cleanup! + [[CKKSAnalytics logger] dailyCoreAnalyticsMetrics:@"com.apple.security.CKKSHealthSummary"]; + // For now, poke the views and tell them to update their device states if they'd like NSArray* actualViews = nil; @synchronized(self.views) { @@ -986,326 +1047,17 @@ dispatch_once_t globalZoneStateQueueOnce; } } -- (NSArray * _Nullable)loadRestoredBottledKeysOfType:(OctagonKeyType)keyType error:(NSError**)error -{ - CFTypeRef result = NULL; - NSMutableArray* bottledPeerKeychainItems = nil; - - NSDictionary* query = @{ - (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, - (id)kSecAttrType : [[NSNumber alloc]initWithInt: keyType], - (id)kSecAttrServer : (keyType == 1) ? @"Octagon Signing Key" : @"Octagon Encryption Key", - (id)kSecAttrAccessGroup: @"com.apple.security.ckks", - (id)kSecMatchLimit : (id)kSecMatchLimitAll, - (id)kSecReturnAttributes: @YES, - (id)kSecReturnData: @YES, - }; - OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); - - if(status == errSecSuccess && result && isArray(result)) { - bottledPeerKeychainItems = CFBridgingRelease(result); - result = NULL; - } else { - if(error) { - *error = [NSError errorWithDomain:NSOSStatusErrorDomain - code:status - description:@"could not load bottled peer keys"]; - } - CFReleaseNull(result); - } - - return bottledPeerKeychainItems; -} - --(NSDictionary *) keychainItemForPeerID:(NSString*)neededPeerID - keychainItems:(NSArray *)keychainItems - escrowSigningPubKeyHash:(NSString *)hashWeNeedToMatch +- (void)haltAll { - NSDictionary* peerItem = nil; - - for(NSDictionary* item in keychainItems){ - if(item && [item count] > 0){ - NSString* peerIDFromItem = [item objectForKey:(id)kSecAttrAccount]; - NSString* hashToConsider = [item objectForKey:(id)kSecAttrLabel]; - if([peerIDFromItem isEqualToString:neededPeerID] && - [hashWeNeedToMatch isEqualToString:hashToConsider]) - { - peerItem = [item copy]; - break; - } - } - } + [self.zoneModifier halt]; - return peerItem; -} - -- (NSSet>*)pastSelves:(NSError**)error -{ - NSError* localError = nil; - - // get bottled peer identities from the keychain - NSMutableSet>* allSelves = [NSMutableSet set]; - NSArray* signingKeys = [self loadRestoredBottledKeysOfType:OctagonSigningKey error:&localError]; - if(!signingKeys) { - // Item not found isn't actually an error here - if(error && !(localError && [localError.domain isEqualToString: NSOSStatusErrorDomain] && localError.code == errSecItemNotFound)) { - *error = localError; - } - - return allSelves; - } - - NSArray* encryptionKeys = [self loadRestoredBottledKeysOfType:OctagonEncryptionKey error:&localError]; - if(!encryptionKeys) { - if(error && !(localError && [localError.domain isEqualToString: NSOSStatusErrorDomain] && localError.code == errSecItemNotFound)) { - *error = localError; - } - return allSelves; - } - - for(NSDictionary* signingKey in signingKeys) { - NSError* peerError = nil; - NSString* peerid = signingKey[(id)kSecAttrAccount]; - NSString* hash = signingKey[(id)kSecAttrLabel]; // escrow signing pub key hash - - //use peer id AND escrow signing public key hash to look up the matching item in encryptionKeys list - NSDictionary* encryptionKeyItem = [self keychainItemForPeerID:peerid keychainItems:encryptionKeys escrowSigningPubKeyHash:hash]; - if(!encryptionKeyItem) { - secerror("octagon: no encryption key available to pair with signing key %@,%@", peerid, hash); - continue; - } - - NSData* signingKeyData = signingKey[(id)kSecValueData]; - if(!signingKeyData) { - secerror("octagon: no signing key data for %@,%@", peerid,hash); - continue; - } - - SFECKeyPair* restoredSigningKey = [[SFECKeyPair alloc] initWithData:signingKeyData - specifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384] - error:&peerError]; - if(!restoredSigningKey) { - secerror("octagon: couldn't make signing key for %@,%@: %@", peerid, hash, peerError); - continue; - } - - NSData* encryptionKeyData = [encryptionKeyItem objectForKey:(id)kSecValueData]; - if(!encryptionKeyData) { - secerror("octagon: no encryption key data for %@,%@", peerid,hash); - continue; - } - - SFECKeyPair* restoredEncryptionKey = [[SFECKeyPair alloc] initWithData:encryptionKeyData - specifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384] - error:&peerError]; - if(!restoredEncryptionKey) { - secerror("octagon: couldn't make encryption key for %@,%@: %@", peerid,hash, peerError); - continue; - } - - //create the SOS self peer - CKKSSOSSelfPeer* restoredIdentity = [[CKKSSOSSelfPeer alloc]initWithSOSPeerID:peerid encryptionKey:restoredEncryptionKey signingKey:restoredSigningKey]; - - if(restoredIdentity){ - secnotice("octagon","adding bottled peer identity: %@", restoredIdentity); - [allSelves addObject:restoredIdentity]; - } else { - secerror("octagon: could not create restored identity from: %@: %@", peerid, peerError); - } - } - return allSelves; -} - -- (id _Nullable)currentSOSSelf:(NSError**)error -{ - __block SFECKeyPair* signingPrivateKey = nil; - __block SFECKeyPair* encryptionPrivateKey = nil; - - __block NSError* localerror = nil; - - // Wait for this to initialize, but don't worry if it isn't. - [self.accountTracker.accountCirclePeerIDInitialized wait:500*NSEC_PER_MSEC]; - NSString* peerID = self.accountTracker.accountCirclePeerID; - if(!peerID || self.accountTracker.accountCirclePeerIDError) { - secerror("ckkspeer: Error fetching self peer : %@", self.accountTracker.accountCirclePeerIDError); - if(error) { - *error = self.accountTracker.accountCirclePeerIDError; - } - return nil; - } - - SOSCCPerformWithAllOctagonKeys(^(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef cferror) { - if(cferror) { - localerror = (__bridge NSError*)cferror; - return; - } - if (!cferror && octagonEncryptionKey && octagonSigningKey) { - signingPrivateKey = [[SFECKeyPair alloc] initWithSecKey:octagonSigningKey]; - encryptionPrivateKey = [[SFECKeyPair alloc] initWithSecKey:octagonEncryptionKey]; - } else { - localerror = [NSError errorWithDomain:CKKSErrorDomain - code:CKKSNoPeersAvailable - description:@"Not all SOS peer keys available, but no error returned"]; - } - }); - - if(localerror) { - if(![self.lockStateTracker isLockedError:localerror]) { - secerror("ckkspeer: Error fetching self encryption keys: %@", localerror); - } - if(error) { - *error = localerror; - } - return nil; - } - - CKKSSOSSelfPeer* selfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:peerID - encryptionKey:encryptionPrivateKey - signingKey:signingPrivateKey]; - return selfPeer; -} - -#pragma mark - CKKSPeerProvider implementation - -- (CKKSSelves*)fetchSelfPeers:(NSError* __autoreleasing *)error { - NSError* localError = nil; - - id selfPeer = [self currentSOSSelf:&localError]; - if(!selfPeer || localError) { - if(![self.lockStateTracker isLockedError:localError]) { - secerror("ckks: Error fetching current SOS self: %@", localError); - } - if(error) { - *error = localError; - } - return nil; - } - - NSSet>* allSelves = [self pastSelves:&localError]; - if(!allSelves || localError) { - secerror("ckks: Error fetching past selves: %@", localError); - if(error) { - *error = localError; - } - return nil; - } - - CKKSSelves* selves = [[CKKSSelves alloc] initWithCurrent:selfPeer allSelves:allSelves]; - return selves; -} - -- (NSSet>*)fetchTrustedPeers:(NSError* __autoreleasing *)error { - __block NSMutableSet>* peerSet = [NSMutableSet set]; - - SOSCCPerformWithTrustedPeers(^(CFSetRef sosPeerInfoRefs, CFErrorRef cfTrustedPeersError) { - if(cfTrustedPeersError) { - secerror("ckks: Error fetching trusted peers: %@", cfTrustedPeersError); - if(error) { - *error = (__bridge NSError*)cfTrustedPeersError; - } - } - - CFSetForEach(sosPeerInfoRefs, ^(const void* voidPeer) { - CFErrorRef cfPeerError = NULL; - SOSPeerInfoRef sosPeerInfoRef = (SOSPeerInfoRef)voidPeer; - - if(!sosPeerInfoRef) { - return; - } - - CFStringRef cfpeerID = SOSPeerInfoGetPeerID(sosPeerInfoRef); - SecKeyRef cfOctagonSigningKey = NULL, cfOctagonEncryptionKey = NULL; - - cfOctagonSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(sosPeerInfoRef, &cfPeerError); - if (cfOctagonSigningKey) { - cfOctagonEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(sosPeerInfoRef, &cfPeerError); - } - - if(cfOctagonSigningKey == NULL || cfOctagonEncryptionKey == NULL) { - // Don't log non-debug for -50; it almost always just means this peer didn't have octagon keys - if(cfPeerError == NULL - || !(CFEqualSafe(CFErrorGetDomain(cfPeerError), kCFErrorDomainOSStatus) && (CFErrorGetCode(cfPeerError) == errSecParam))) - { - secerror("ckkspeer: error fetching octagon keys for peer: %@ %@", sosPeerInfoRef, cfPeerError); - } else { - secinfo("ckkspeer", "Peer(%@) doesn't have Octagon keys, but this is expected: %@", cfpeerID, cfPeerError); - } - } - - // Add all peers to the trust set: old-style SOS peers will just have null keys - SFECPublicKey* signingPublicKey = cfOctagonSigningKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonSigningKey] : nil; - SFECPublicKey* encryptionPublicKey = cfOctagonEncryptionKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonEncryptionKey] : nil; - - CKKSSOSPeer* peer = [[CKKSSOSPeer alloc] initWithSOSPeerID:(__bridge NSString*)cfpeerID - encryptionPublicKey:encryptionPublicKey - signingPublicKey:signingPublicKey]; - [peerSet addObject:peer]; - - CFReleaseNull(cfOctagonSigningKey); - CFReleaseNull(cfOctagonEncryptionKey); - CFReleaseNull(cfPeerError); - }); - }); - - return peerSet; -} - -- (void)registerForPeerChangeUpdates:(id)listener { - @synchronized(self.peerChangeListeners) { - bool alreadyRegisteredListener = false; - NSEnumerator *enumerator = [self.peerChangeListeners objectEnumerator]; - id value; - - while ((value = [enumerator nextObject])) { - // do pointer comparison - alreadyRegisteredListener |= (value == listener); - } - - if(listener && !alreadyRegisteredListener) { - NSString* queueName = [NSString stringWithFormat: @"ck-peer-change-%@", listener]; - - dispatch_queue_t objQueue = dispatch_queue_create([queueName UTF8String], DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - [self.peerChangeListeners setObject: listener forKey: objQueue]; - } - } -} - -- (void)iteratePeerListenersOnTheirQueue:(void (^)(id))block { - @synchronized(self.peerChangeListeners) { - NSEnumerator *enumerator = [self.peerChangeListeners keyEnumerator]; - dispatch_queue_t dq; - - // Queue up the changes for each listener. - while ((dq = [enumerator nextObject])) { - id listener = [self.peerChangeListeners objectForKey: dq]; - __weak id weakListener = listener; - - if(listener) { - dispatch_async(dq, ^{ - __strong id strongListener = weakListener; - block(strongListener); - }); - } + @synchronized(self.views) { + for(CKKSKeychainView* view in self.views.allValues) { + [view halt]; } } -} - -- (void)sendSelfPeerChangedUpdate { - [self.completedSecCKKSInitialize wait:5*NSEC_PER_SEC]; // Wait for bringup, but don't worry if this times out - [self iteratePeerListenersOnTheirQueue: ^(id listener) { - [listener selfPeerChanged]; - }]; } -- (void)sendTrustedPeerSetChangedUpdate { - [self.completedSecCKKSInitialize wait:5*NSEC_PER_SEC]; // Wait for bringup, but don't worry if this times out - - [self iteratePeerListenersOnTheirQueue: ^(id listener) { - [listener trustedPeerSetChanged]; - }]; -} #endif // OCTAGON @end diff --git a/keychain/ckks/CKKSZone.h b/keychain/ckks/CKKSZone.h index 8938c2ee..5869326c 100644 --- a/keychain/ckks/CKKSZone.h +++ b/keychain/ckks/CKKSZone.h @@ -24,15 +24,18 @@ #import #if OCTAGON -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/ckks/CloudKitDependencies.h" -#import "keychain/ckks/CKKSAPSReceiver.h" +#import "keychain/ckks/CKKSCloudKitClassDependencies.h" +#import "keychain/ckks/OctagonAPSReceiver.h" #import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CKKSZoneModifier.h" NS_ASSUME_NONNULL_BEGIN -@interface CKKSZone : NSObject +@interface CKKSZone : NSObject { CKContainer* _container; CKDatabase* _database; @@ -57,32 +60,25 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) CKContainer* container; @property (readonly) CKDatabase* database; -@property (weak) CKKSCKAccountStateTracker* accountTracker; +@property (weak) CKKSAccountStateTracker* accountTracker; @property (weak) CKKSReachabilityTracker* reachabilityTracker; @property (readonly) CKRecordZone* zone; @property (readonly) CKRecordZoneID* zoneID; +@property (readonly) CKKSZoneModifier* zoneModifier; + // Dependencies (for injection) -@property (readonly) Class fetchRecordZoneChangesOperationClass; -@property (readonly) Class fetchRecordsOperationClass; -@property (readonly) Class queryOperationClass; -@property (readonly) Class modifySubscriptionsOperationClass; -@property (readonly) Class modifyRecordZonesOperationClass; -@property (readonly) Class apsConnectionClass; +@property (readonly) CKKSCloudKitClassDependencies* cloudKitClassDependencies; @property dispatch_queue_t queue; - (instancetype)initWithContainer:(CKContainer*)container - zoneName:(NSString*)zoneName - accountTracker:(CKKSCKAccountStateTracker*)accountTracker - reachabilityTracker:(CKKSReachabilityTracker *)reachabilityTracker - fetchRecordZoneChangesOperationClass:(Class)fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:(Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass:(Class)modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:(Class)modifyRecordZonesOperationClass - apsConnectionClass:(Class)apsConnectionClass; + zoneName:(NSString*)zoneName + accountTracker:(CKKSAccountStateTracker*)accountTracker + reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker + zoneModifier:(CKKSZoneModifier*)zoneModifier + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies; - (CKKSResultOperation* _Nullable)deleteCloudKitZoneOperation:(CKOperationGroup* _Nullable)ckoperationGroup; @@ -105,7 +101,7 @@ NS_ASSUME_NONNULL_BEGIN // Call this when you're ready for this zone to kick off operations // based on iCloud account status -- (void)initializeZone; +- (void)beginCloudKitOperation; // Cancels all operations (no matter what they are). - (void)cancelAllOperations; diff --git a/keychain/ckks/CKKSZone.m b/keychain/ckks/CKKSZone.m index 3a5dda69..b51bf477 100644 --- a/keychain/ckks/CKKSZone.m +++ b/keychain/ckks/CKKSZone.m @@ -27,12 +27,14 @@ #if OCTAGON #import "CloudKitDependencies.h" -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" #import #import +#import "keychain/ot/ObjCImprovements.h" + #import "CKKSKeychainView.h" #import "CKKSZone.h" @@ -51,22 +53,16 @@ // Make writable @property bool halted; -@property bool zoneCreateNetworkFailure; -@property bool zoneSubscriptionNetworkFailure; @end @implementation CKKSZone -- (instancetype)initWithContainer: (CKContainer*) container - zoneName: (NSString*) zoneName - accountTracker:(CKKSCKAccountStateTracker*) accountTracker - reachabilityTracker:(CKKSReachabilityTracker *) reachabilityTracker - fetchRecordZoneChangesOperationClass: (Class) fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass: (Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass: (Class) modifySubscriptionsOperationClass - modifyRecordZonesOperationClass: (Class) modifyRecordZonesOperationClass - apsConnectionClass: (Class) apsConnectionClass +- (instancetype)initWithContainer:(CKContainer*)container + zoneName:(NSString*)zoneName + accountTracker:(CKKSAccountStateTracker*)accountTracker + reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker + zoneModifier:(CKKSZoneModifier*)zoneModifier + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies { if(self = [super init]) { _container = container; @@ -74,6 +70,8 @@ _accountTracker = accountTracker; _reachabilityTracker = reachabilityTracker; + _zoneModifier = zoneModifier; + _halted = false; _database = [_container privateCloudDatabase]; @@ -85,12 +83,7 @@ _accountOperations = [NSHashTable weakObjectsHashTable]; - _fetchRecordZoneChangesOperationClass = fetchRecordZoneChangesOperationClass; - _fetchRecordsOperationClass = fetchRecordsOperationClass; - _queryOperationClass = queryOperationClass; - _modifySubscriptionsOperationClass = modifySubscriptionsOperationClass; - _modifyRecordZonesOperationClass = modifyRecordZonesOperationClass; - _apsConnectionClass = apsConnectionClass; + _cloudKitClassDependencies = cloudKitClassDependencies; _queue = dispatch_queue_create([[NSString stringWithFormat:@"CKKSQueue.%@.zone.%@", container.containerIdentifier, zoneName] UTF8String], DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _operationQueue = [[NSOperationQueue alloc] init]; @@ -99,16 +92,17 @@ } - (CKKSResultOperation*)createAccountLoggedInDependency:(NSString*)message { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSResultOperation* accountLoggedInDependency = [CKKSResultOperation named:@"account-logged-in-dependency" withBlock:^{ - ckksnotice("ckkszone", weakSelf, "%@", message); + STRONGIFY(self); + ckksnotice("ckkszone", self, "%@", message); }]; accountLoggedInDependency.descriptionErrorCode = CKKSResultDescriptionPendingAccountLoggedIn; return accountLoggedInDependency; } -- (void)initializeZone { - [self.accountTracker notifyOnAccountStatusChange:self]; +- (void)beginCloudKitOperation { + [self.accountTracker registerForNotificationsOfCloudKitAccountStatusChange:self]; } - (void)resetSetup { @@ -126,12 +120,35 @@ return [self.zone zoneID]; } +- (CKKSAccountStatus)accountStatusFromCKAccountInfo:(CKAccountInfo*)info +{ + if(!info) { + return CKKSAccountStatusUnknown; + } + if(info.accountStatus == CKAccountStatusAvailable && + info.hasValidCredentials) { + return CKKSAccountStatusAvailable; + } else { + return CKKSAccountStatusNoAccount; + } +} + --(void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus { +- (void)cloudkitAccountStateChange:(CKAccountInfo* _Nullable)oldAccountInfo to:(CKAccountInfo*)currentAccountInfo +{ ckksnotice("ckkszone", self, "%@ Received notification of CloudKit account status change, moving from %@ to %@", self.zoneID.zoneName, - [CKKSCKAccountStateTracker stringFromAccountStatus: oldStatus], - [CKKSCKAccountStateTracker stringFromAccountStatus: currentStatus]); + oldAccountInfo, + currentAccountInfo); + + // Filter for device2device encryption and cloudkit grey mode + CKKSAccountStatus oldStatus = [self accountStatusFromCKAccountInfo:oldAccountInfo]; + CKKSAccountStatus currentStatus = [self accountStatusFromCKAccountInfo:currentAccountInfo]; + + if(oldStatus == currentStatus) { + ckksnotice("ckkszone", self, "Computed status of new CK account info is same as old status: %@", [CKKSAccountStateTracker stringFromAccountStatus:currentStatus]); + return; + } switch(currentStatus) { case CKKSAccountStatusAvailable: { @@ -148,7 +165,9 @@ case CKKSAccountStatusNoAccount: { ckksnotice("ckkszone", self, "Logging out of iCloud. Shutting down."); - self.accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account logged in again."]; + if(!self.accountLoggedInDependency) { + self.accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account logged in again."]; + } [self handleCKLogout]; } @@ -158,7 +177,9 @@ // We really don't expect to receive this as a notification, but, okay! ckksnotice("ckkszone", self, "Account status has become undetermined. Pausing for %@", self.zoneID.zoneName); - self.accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account return from 'unknown'."]; + if(!self.accountLoggedInDependency) { + self.accountLoggedInDependency = [self createAccountLoggedInDependency:@"CloudKit account logged in again."]; + } [self handleCKLogout]; } @@ -185,163 +206,91 @@ ckksnotice("ckkszone", self, "Setting up zone %@", self.zoneName); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); // First, check the account status. If it's sufficient, add the necessary CloudKit operations to this operation __weak CKKSGroupOperation* weakZoneSetupOperation = self.zoneSetupOperation; [self.zoneSetupOperation runBeforeGroupFinished:[CKKSResultOperation named:[NSString stringWithFormat:@"zone-setup-%@", self.zoneName] withBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; + STRONGIFY(self); __strong __typeof(self.zoneSetupOperation) zoneSetupOperation = weakZoneSetupOperation; - __strong __typeof(self.reachabilityTracker) reachabilityTracker = self.reachabilityTracker; - if(!strongSelf || !zoneSetupOperation) { - ckkserror("ckkszone", strongSelf, "received callback for released object"); + if(!self || !zoneSetupOperation) { + ckkserror("ckkszone", self, "received callback for released object"); return; } - if(strongSelf.accountStatus != CKKSAccountStatusAvailable) { - ckkserror("ckkszone", strongSelf, "Zone doesn't believe it's logged in; quitting setup"); + if(self.accountStatus != CKKSAccountStatusAvailable) { + ckkserror("ckkszone", self, "Zone doesn't believe it's logged in; quitting setup"); return; } NSBlockOperation* setupCompleteOperation = [NSBlockOperation blockOperationWithBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckkszone: received callback for released object"); return; } - ckksnotice("ckkszone", strongSelf, "%@: Setup complete", strongSelf.zoneName); + ckksnotice("ckkszone", self, "%@: Setup complete", self.zoneName); }]; setupCompleteOperation.name = @"zone-setup-complete-operation"; // We have an account, so fetch the push environment and bring up APS - [strongSelf.container serverPreferredPushEnvironmentWithCompletionHandler: ^(NSString *apsPushEnvString, NSError *error) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { + [self.container serverPreferredPushEnvironmentWithCompletionHandler: ^(NSString *apsPushEnvString, NSError *error) { + STRONGIFY(self); + if(!self) { secerror("ckkszone: received callback for released object"); return; } if(error || (apsPushEnvString == nil)) { - ckkserror("ckkszone", strongSelf, "Received error fetching preferred push environment (%@). Keychain syncing is highly degraded: %@", apsPushEnvString, error); + ckkserror("ckkszone", self, "Received error fetching preferred push environment (%@). Keychain syncing is highly degraded: %@", apsPushEnvString, error); } else { - CKKSAPSReceiver* aps = [CKKSAPSReceiver receiverForEnvironment:apsPushEnvString + OctagonAPSReceiver* aps = [OctagonAPSReceiver receiverForEnvironment:apsPushEnvString namedDelegatePort:SecCKKSAPSNamedPort - apsConnectionClass:strongSelf.apsConnectionClass]; - [aps registerReceiver:strongSelf forZoneID:strongSelf.zoneID]; + apsConnectionClass:self.cloudKitClassDependencies.apsConnectionClass]; + [aps registerReceiver:self forZoneID:self.zoneID]; } }]; - NSBlockOperation* modifyRecordZonesCompleteOperation = nil; - if(!zoneCreated) { - ckksnotice("ckkszone", strongSelf, "Creating CloudKit zone '%@'", strongSelf.zoneName); - CKDatabaseOperation* zoneCreationOperation = [[strongSelf.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: @[strongSelf.zone] recordZoneIDsToDelete: nil]; - 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"];; - - // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. - modifyRecordZonesCompleteOperation = [[NSBlockOperation alloc] init]; - modifyRecordZonesCompleteOperation.name = @"zone-creation-finished"; - - zoneCreationOperation.modifyRecordZonesCompletionBlock = ^(NSArray *savedRecordZones, NSArray *deletedRecordZoneIDs, NSError *operationError) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - secerror("ckkszone: received callback for released object"); - return; - } - - __strong __typeof(weakSelf) strongSubSelf = weakSelf; + if(!zoneCreated || !zoneSubscribed) { + ckksnotice("ckkszone", self, "Asking to create and subscribe to CloudKit zone '%@'", self.zoneName); + CKKSZoneModifyOperations* zoneOps = [self.zoneModifier createZone:self.zone]; - if(!operationError) { - ckksnotice("ckkszone", strongSubSelf, "Successfully created zone %@", strongSubSelf.zoneName); - strongSubSelf.zoneCreated = true; - strongSubSelf.zoneSetupOperationGroup = nil; + CKKSResultOperation* handleModificationsOperation = [CKKSResultOperation named:@"handle-modification" withBlock:^{ + STRONGIFY(self); + if([zoneOps.savedRecordZones containsObject:self.zone]) { + ckksnotice("ckkszone", self, "Successfully created '%@'", self.zoneName); + self.zoneCreated = true; } else { - ckkserror("ckkszone", strongSubSelf, "Couldn't create zone %@; %@", strongSubSelf.zoneName, operationError); - } - strongSubSelf.zoneCreatedError = operationError; - if ([reachabilityTracker isNetworkError:operationError]){ - strongSelf.zoneCreateNetworkFailure = true; - } - [strongSubSelf.operationQueue addOperation: modifyRecordZonesCompleteOperation]; - }; - - if (strongSelf.zoneCreateNetworkFailure) { - [zoneCreationOperation addNullableDependency:reachabilityTracker.reachabilityDependency]; - strongSelf.zoneCreateNetworkFailure = false; - } - ckksnotice("ckkszone", strongSelf, "Adding CKKSModifyRecordZonesOperation: %@ %@", zoneCreationOperation, zoneCreationOperation.dependencies); - strongSelf.zoneCreationOperation = zoneCreationOperation; - [setupCompleteOperation addDependency: modifyRecordZonesCompleteOperation]; - [zoneSetupOperation runBeforeGroupFinished: zoneCreationOperation]; - [zoneSetupOperation dependOnBeforeGroupFinished: modifyRecordZonesCompleteOperation]; - } else { - ckksnotice("ckkszone", strongSelf, "no need to create the zone '%@'", strongSelf.zoneName); - } - - if(!zoneSubscribed) { - ckksnotice("ckkszone", strongSelf, "Creating CloudKit record zone subscription for %@", strongSelf.zoneName); - CKRecordZoneSubscription* subscription = [[CKRecordZoneSubscription alloc] initWithZoneID: strongSelf.zoneID subscriptionID:[@"zone:" stringByAppendingString: strongSelf.zoneName]]; - CKNotificationInfo* notificationInfo = [[CKNotificationInfo alloc] init]; - - notificationInfo.shouldSendContentAvailable = false; - subscription.notificationInfo = notificationInfo; - - CKDatabaseOperation* zoneSubscriptionOperation = [[strongSelf.modifySubscriptionsOperationClass alloc] initWithSubscriptionsToSave: @[subscription] subscriptionIDsToDelete: nil]; - - zoneSubscriptionOperation.configuration.automaticallyRetryNetworkFailures = NO; - zoneSubscriptionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; - zoneSubscriptionOperation.database = strongSelf.database; - zoneSubscriptionOperation.name = @"zone-subscription-operation"; - - // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. - NSBlockOperation* zoneSubscriptionCompleteOperation = [[NSBlockOperation alloc] init]; - zoneSubscriptionCompleteOperation.name = @"zone-subscription-complete"; - zoneSubscriptionOperation.modifySubscriptionsCompletionBlock = ^(NSArray * _Nullable savedSubscriptions, NSArray * _Nullable deletedSubscriptionIDs, NSError * _Nullable operationError) { - __strong __typeof(weakSelf) strongSubSelf = weakSelf; - if(!strongSubSelf) { - ckkserror("ckkszone", strongSubSelf, "received callback for released object"); - return; + ckksnotice("ckkszone", self, "Failed to create '%@'", self.zoneName); + self.zoneCreatedError = zoneOps.zoneModificationOperation.error; } - if(!operationError) { - ckksnotice("ckkszone", strongSubSelf, "Successfully subscribed to %@", savedSubscriptions); - - // Success; write that down. TODO: actually ensure that the saved subscription matches what we asked for - for(CKSubscription* sub in savedSubscriptions) { - ckksnotice("ckkszone", strongSubSelf, "Successfully subscribed to %@", sub.subscriptionID); - strongSubSelf.zoneSubscribed = true; + bool createdSubscription = false; + for(CKSubscription* subscription in zoneOps.savedSubscriptions) { + if([subscription.zoneID isEqual:self.zoneID]) { + createdSubscription = true; + break; } - } else { - ckkserror("ckkszone", strongSubSelf, "Couldn't create cloudkit zone subscription; keychain syncing is severely degraded: %@", operationError); } - strongSubSelf.zoneSubscribedError = operationError; - strongSubSelf.zoneSubscriptionOperation = nil; - if ([reachabilityTracker isNetworkError:operationError]){ - strongSelf.zoneSubscriptionNetworkFailure = true; + if(createdSubscription) { + ckksnotice("ckkszone", self, "Successfully subscribed '%@'", self.zoneName); + self.zoneSubscribed = true; + } else { + ckksnotice("ckkszone", self, "Failed to subscribe to '%@'", self.zoneName); + self.zoneSubscribedError = zoneOps.zoneSubscriptionOperation.error; } - - [strongSubSelf.operationQueue addOperation: zoneSubscriptionCompleteOperation]; - }; - - if (strongSelf.zoneSubscriptionNetworkFailure) { - [zoneSubscriptionOperation addNullableDependency:reachabilityTracker.reachabilityDependency]; - strongSelf.zoneSubscriptionNetworkFailure = false; - } - [zoneSubscriptionOperation addNullableDependency:modifyRecordZonesCompleteOperation]; - strongSelf.zoneSubscriptionOperation = zoneSubscriptionOperation; - [setupCompleteOperation addDependency: zoneSubscriptionCompleteOperation]; - [zoneSetupOperation runBeforeGroupFinished:zoneSubscriptionOperation]; - [zoneSetupOperation dependOnBeforeGroupFinished: zoneSubscriptionCompleteOperation]; + }]; + [setupCompleteOperation addDependency:zoneOps.zoneModificationOperation]; + [handleModificationsOperation addDependency:zoneOps.zoneModificationOperation]; + [handleModificationsOperation addDependency:zoneOps.zoneSubscriptionOperation]; + [zoneSetupOperation runBeforeGroupFinished:handleModificationsOperation]; } else { - ckksnotice("ckkszone", strongSelf, "no need to create database subscription"); + ckksnotice("ckkszone", self, "no need to create or subscribe to the zone '%@'", self.zoneName); } - [strongSelf.zoneSetupOperation runBeforeGroupFinished:setupCompleteOperation]; + [self.zoneSetupOperation runBeforeGroupFinished:setupCompleteOperation]; }]]; [self scheduleAccountStatusOperation:self.zoneSetupOperation]; @@ -355,6 +304,8 @@ return nil; } + WEAKIFY(self); + // We want to delete this zone and this subscription from CloudKit. // Step 1: cancel setup operations (if they exist) @@ -365,29 +316,17 @@ // Step 2: Try to delete the zone - CKDatabaseOperation* zoneDeletionOperation = [[self.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave: nil recordZoneIDsToDelete: @[self.zoneID]]; - zoneDeletionOperation.configuration.automaticallyRetryNetworkFailures = NO; - zoneDeletionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; - zoneDeletionOperation.database = self.database; - zoneDeletionOperation.group = ckoperationGroup; - - CKKSGroupOperation* zoneDeletionGroupOperation = [[CKKSGroupOperation alloc] init]; - zoneDeletionGroupOperation.name = [NSString stringWithFormat:@"cloudkit-zone-delete-%@", self.zoneName]; + CKKSZoneModifyOperations* zoneOps = [self.zoneModifier deleteZone:self.zoneID]; - CKKSResultOperation* doneOp = [CKKSResultOperation named:@"zone-reset-watcher" withBlock:^{}]; - [zoneDeletionGroupOperation dependOnBeforeGroupFinished:doneOp]; + CKKSResultOperation* afterModification = [CKKSResultOperation named:@"after-modification" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull op) { + STRONGIFY(self); - __weak __typeof(self) weakSelf = self; + bool fatalError = false; - zoneDeletionOperation.modifyRecordZonesCompletionBlock = ^(NSArray *savedRecordZones, NSArray *deletedRecordZoneIDs, NSError *operationError) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if(!strongSelf) { - ckkserror("ckkszone", strongSelf, "received callback for released object"); - return; - } + NSError* operationError = zoneOps.zoneModificationOperation.error; + bool removed = [zoneOps.deletedRecordZoneIDs containsObject:self.zoneID]; - bool fatalError = false; - if(operationError) { + if(!removed && operationError) { // Okay, but if this error is either 'ZoneNotFound' or 'UserDeletedZone', that's fine by us: the zone is deleted. NSDictionary* partialErrors = operationError.userInfo[CKPartialErrorsByItemIDKey]; if([operationError.domain isEqualToString:CKErrorDomain] && operationError.code == CKErrorPartialFailure && partialErrors) { @@ -396,7 +335,7 @@ if(errorZone && [errorZone.domain isEqualToString:CKErrorDomain] && (errorZone.code == CKErrorZoneNotFound || errorZone.code == CKErrorUserDeletedZone)) { - ckksnotice("ckkszone", strongSelf, "Attempted to delete zone %@, but it's already missing. This is okay: %@", errorZoneID, errorZone); + ckksnotice("ckkszone", self, "Attempted to delete zone %@, but it's already missing. This is okay: %@", errorZoneID, errorZone); } else { fatalError = true; } @@ -405,30 +344,19 @@ } else { fatalError = true; } - } - if(operationError) { - ckksnotice("ckkszone", strongSelf, "deletion of record zones %@ completed with error: %@", deletedRecordZoneIDs, operationError); - } else { - ckksnotice("ckkszone", strongSelf, "deletion of record zones %@ completed successfully", deletedRecordZoneIDs); - } + ckksnotice("ckkszone", self, "deletion of record zone %@ completed with error: %@", self.zoneID, operationError); - if(operationError && fatalError) { - // If the error wasn't actually a problem, don't report it upward. - doneOp.error = operationError; + if(fatalError) { + op.error = operationError; + } + } else { + ckksnotice("ckkszone", self, "deletion of record zone %@ completed successfully", self.zoneID); } - [zoneDeletionGroupOperation runBeforeGroupFinished:doneOp]; - }; - - // If the zone creation operation is still pending, wait for it to complete before attempting zone deletion - [zoneDeletionOperation addNullableDependency: self.zoneCreationOperation]; - [zoneDeletionGroupOperation runBeforeGroupFinished:zoneDeletionOperation]; + }]; - [zoneDeletionGroupOperation runBeforeGroupFinished:[CKKSResultOperation named:@"print-log-message" withBlock:^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - ckksnotice("ckkszone", strongSelf, "deleting zones %@ with dependencies %@", zoneDeletionOperation.recordZoneIDsToDelete, zoneDeletionOperation.dependencies); - }]]; - return zoneDeletionGroupOperation; + [afterModification addDependency:zoneOps.zoneModificationOperation]; + return afterModification; } - (void)notifyZoneChange: (CKRecordZoneNotification*) notification { @@ -452,9 +380,7 @@ return false; } - if(self.accountLoggedInDependency) { - [op addDependency: self.accountLoggedInDependency]; - } + [op addNullableDependency:self.accountLoggedInDependency]; [self.operationQueue addOperation: op]; return true; diff --git a/keychain/ckks/CKKSZoneChangeFetcher.m b/keychain/ckks/CKKSZoneChangeFetcher.m index 2d60816c..8b9fe2f5 100644 --- a/keychain/ckks/CKKSZoneChangeFetcher.m +++ b/keychain/ckks/CKKSZoneChangeFetcher.m @@ -34,6 +34,9 @@ #import "keychain/ckks/CloudKitCategories.h" #import "keychain/ckks/CKKSReachabilityTracker.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/analytics/SecEventMetric.h" +#import "keychain/analytics/SecMetrics.h" +#import "keychain/ot/ObjCImprovements.h" CKKSFetchBecause* const CKKSFetchBecauseAPNS = (CKKSFetchBecause*) @"apns"; CKKSFetchBecause* const CKKSFetchBecauseAPIFetchRequest = (CKKSFetchBecause*) @"api"; @@ -45,6 +48,7 @@ CKKSFetchBecause* const CKKSFetchBecauseNetwork = (CKKSFetchBecause*) @"network" CKKSFetchBecause* const CKKSFetchBecauseKeyHierarchy = (CKKSFetchBecause*) @"keyhierarchy"; CKKSFetchBecause* const CKKSFetchBecauseTesting = (CKKSFetchBecause*) @"testing"; CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; +CKKSFetchBecause* const CKKSFetchBecauseMoreComing = (CKKSFetchBecause*) @"more-coming"; #pragma mark - CKKSZoneChangeFetchDependencyOperation @interface CKKSZoneChangeFetchDependencyOperation : CKKSResultOperation @@ -129,17 +133,18 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; // If we're testing, for the initial delay, use 0.2 second. Otherwise, 2s. dispatch_time_t initialDelay = (SecCKKSReduceRateLimiting() ? 200 * NSEC_PER_MSEC : 2 * NSEC_PER_SEC); - // If we're testing, for the initial delay, use 2 second. Otherwise, 30s. + // If we're testing, for the continuing delay, use 2 second. Otherwise, 30s. dispatch_time_t continuingDelay = (SecCKKSReduceRateLimiting() ? 2 * NSEC_PER_SEC : 30 * NSEC_PER_SEC); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); _fetchScheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"zone-change-fetch-scheduler" initialDelay:initialDelay continuingDelay:continuingDelay keepProcessAlive:false dependencyDescriptionCode:CKKSResultDescriptionPendingZoneChangeFetchScheduling block:^{ - [weakSelf maybeCreateNewFetch]; + STRONGIFY(self); + [self maybeCreateNewFetch]; }]; } return self; @@ -199,6 +204,14 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; metric[@"push_event_name"] = @"CKKS APNS Push Received"; [self.container submitEventMetric:metric]; + + SecEventMetric *metric2 = [[SecEventMetric alloc] initWithEventName:@"APNSPushMetrics"]; + metric2[@"push_token_uuid"] = notification.ckksPushTracingUUID; + metric2[@"push_received_date"] = notification.ckksPushReceivedDate; + metric2[@"push_event_name"] = @"CKKS APNS Push Received-webtunnel"; + + [[SecMetrics managerObject] submitEvent:metric2]; + } } @@ -209,32 +222,38 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; return dependency; } +-(void)maybeCreateNewFetchOnQueue { + dispatch_assert_queue(self.queue); + if(self.newRequests && + (self.currentFetch == nil || [self.currentFetch isFinished]) && + (self.currentProcessResult == nil || [self.currentProcessResult isFinished])) { + [self _onqueueCreateNewFetch]; + } +} + -(void)maybeCreateNewFetch { dispatch_sync(self.queue, ^{ - if(self.newRequests && - (self.currentFetch == nil || [self.currentFetch isFinished]) && - (self.currentProcessResult == nil || [self.currentProcessResult isFinished])) { - [self _onqueueCreateNewFetch]; - } + [self maybeCreateNewFetchOnQueue]; }); } -(void)_onqueueCreateNewFetch { dispatch_assert_queue(self.queue); - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); CKKSZoneChangeFetchDependencyOperation* dependency = self.successfulFetchDependency; - - secnotice("ckksfetcher", "Starting a new fetch"); - NSMutableSet* lastFetchReasons = self.currentFetchReasons; self.currentFetchReasons = [[NSMutableSet alloc] init]; + NSString *reasonsString = [[lastFetchReasons sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES]]] componentsJoinedByString:@","]; + + secnotice("ckksfetcher", "Starting a new fetch, reasons: %@", reasonsString); + NSMutableSet* lastAPNSPushes = self.apnsPushes; self.apnsPushes = [[NSMutableSet alloc] init]; - CKOperationGroup* operationGroup = [CKOperationGroup CKKSGroupWithName: [[lastFetchReasons sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES]]] componentsJoinedByString:@","]]; + CKOperationGroup* operationGroup = [CKOperationGroup CKKSGroupWithName: reasonsString]; NSMutableArray>* clients = [NSMutableArray array]; @synchronized(self.clientMap) { @@ -246,6 +265,7 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; } if(clients.count == 0u) { + secnotice("ckksfetcher", "No clients"); // Nothing to do, really. } @@ -258,43 +278,60 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; ckoperationGroup:operationGroup]; if ([lastFetchReasons containsObject:CKKSFetchBecauseNetwork]) { + secnotice("ckksfetcher", "blocking fetch on network reachability"); [fetchAllChanges addNullableDependency: self.reachabilityTracker.reachabilityDependency]; // wait on network, if its unavailable } [fetchAllChanges addNullableDependency: self.holdOperation]; self.currentProcessResult = [CKKSResultOperation operationWithBlock: ^{ - __strong __typeof(self) strongSelf = weakSelf; - if(!strongSelf) { + STRONGIFY(self); + if(!self) { secerror("ckksfetcher: Received a null self pointer; strange."); return; } - dispatch_sync(strongSelf.queue, ^{ + bool attemptAnotherFetch = false; + if(fetchAllChanges.error != nil) { + secerror("ckksfetcher: Interrogating clients about fetch error: %@", fetchAllChanges.error); + + // Check in with clients: should we keep fetching for them? + @synchronized(self.clientMap) { + for(CKRecordZoneID* zoneID in fetchAllChanges.fetchedZoneIDs) { + id client = [self.clientMap objectForKey:zoneID]; + if(client) { + attemptAnotherFetch |= [client shouldRetryAfterFetchError:fetchAllChanges.error]; + } + } + } + } + + dispatch_sync(self.queue, ^{ self.lastCKFetchError = fetchAllChanges.error; if(!fetchAllChanges.error) { - // success! notify the listeners. - [self.operationQueue addOperation: dependency]; + if (attemptAnotherFetch) { + [dependency chainDependency:self.successfulFetchDependency]; + [self.operationQueue addOperation: dependency]; + + [self.currentFetchReasons unionSet:lastFetchReasons]; + [self.apnsPushes unionSet:lastAPNSPushes]; - // Did new people show up and want another fetch? - if(strongSelf.newRequests) { - [strongSelf.fetchScheduler trigger]; + self.newRequests = true; + [self.fetchScheduler trigger]; + } else { + // success! notify the listeners. + [self.operationQueue addOperation: dependency]; + self.currentFetch = nil; + + // Did new people show up and want another fetch? + if(self.newRequests) { + [self.fetchScheduler trigger]; + } } } else { // The operation errored. Chain the dependency on the current one... - [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]; - } - } - } + [dependency chainDependency:self.successfulFetchDependency]; + [self.operationQueue addOperation: dependency]; if(!attemptAnotherFetch) { secerror("ckksfetcher: All clients thought %@ is a fatal error. Not restarting fetch.", fetchAllChanges.error); @@ -302,29 +339,35 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; } // And in a bit, try the fetch again. - NSNumber* delaySeconds = fetchAllChanges.error.userInfo[CKErrorRetryAfterKey]; - if([fetchAllChanges.error.domain isEqual: CKErrorDomain] && delaySeconds) { - secnotice("ckksfetcher", "Fetch failed with rate-limiting error, restarting in %@ seconds: %@", delaySeconds, fetchAllChanges.error); - [strongSelf.fetchScheduler waitUntil: NSEC_PER_SEC * [delaySeconds unsignedLongValue]]; + NSTimeInterval delay = CKRetryAfterSecondsForError(fetchAllChanges.error); + if (delay) { + secnotice("ckksfetcher", "Fetch failed with rate-limiting error, restarting in %.1f seconds: %@", delay, fetchAllChanges.error); + [self.fetchScheduler waitUntil:NSEC_PER_SEC * delay]; } else { 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]; + [self.currentFetchReasons unionSet:lastFetchReasons]; + [self.apnsPushes unionSet:lastAPNSPushes]; // If its a network error, make next try depend on network availability if ([self.reachabilityTracker isNetworkError:fetchAllChanges.error]) { - [strongSelf.currentFetchReasons addObject:CKKSFetchBecauseNetwork]; + [self.currentFetchReasons addObject:CKKSFetchBecauseNetwork]; } else { - [strongSelf.currentFetchReasons addObject:CKKSFetchBecausePreviousFetchFailed]; + [self.currentFetchReasons addObject:CKKSFetchBecausePreviousFetchFailed]; } - strongSelf.newRequests = true; - [strongSelf.fetchScheduler trigger]; + self.newRequests = true; + [self.fetchScheduler trigger]; } }); }]; + + // creata a new fetch dependency, for all those who come in while this operation is executing + self.newRequests = false; + self.successfulFetchDependency = [self createSuccesfulFetchDependency]; + + // now let new new fetch go and process it's results self.currentProcessResult.name = @"zone-change-fetcher-worker"; [self.currentProcessResult addDependency: fetchAllChanges]; @@ -332,10 +375,6 @@ CKKSFetchBecause* const CKKSFetchBecauseResync = (CKKSFetchBecause*) @"resync"; self.currentFetch = fetchAllChanges; [self.operationQueue addOperation:self.currentFetch]; - - // creata a new fetch dependency, for all those who come in while this operation is executing - self.newRequests = false; - self.successfulFetchDependency = [self createSuccesfulFetchDependency]; } -(CKKSZoneChangeFetchDependencyOperation*)createSuccesfulFetchDependency { diff --git a/keychain/ckks/CKKSZoneModifier.h b/keychain/ckks/CKKSZoneModifier.h new file mode 100644 index 00000000..b42abac6 --- /dev/null +++ b/keychain/ckks/CKKSZoneModifier.h @@ -0,0 +1,65 @@ +#if OCTAGON + +#import +#import + +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" +#import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ckks/CKKSCloudKitClassDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CKKSZoneModifyOperations : NSObject +@property CKKSResultOperation* zoneModificationOperation; +@property CKKSResultOperation* zoneSubscriptionOperation; + +@property (readonly) NSMutableArray* zonesToCreate; +@property (readonly) NSMutableArray* subscriptionsToSubscribe; +@property (readonly) NSMutableArray* zoneIDsToDelete; + +- (instancetype)init NS_UNAVAILABLE; + +// After the operations run, these properties will be filled in: +// Note that your zone may or may not succeed even if the whole operation fails +@property (nullable) NSArray* savedRecordZones; +@property (nullable) NSArray* deletedRecordZoneIDs; +// The error from the zone modifcation, if any, will be on the zoneModificationOperation + +@property (nullable) NSArray* savedSubscriptions; +@property (nullable) NSArray* deletedSubscriptionIDs; +// The error from the zone subscription, if any, will be on the zoneSubscriptionOperation +@end + + +@interface CKKSZoneModifier : NSObject +@property (readonly) CKKSReachabilityTracker* reachabilityTracker; +@property (readonly) CKKSCloudKitClassDependencies* cloudKitClassDependencies; +@property (readonly) CKContainer* container; +@property (readonly) CKDatabase* database; + +// Block on this to schedule operations for directly after a CloudKit retryAfter delay expires +@property (readonly) CKKSNearFutureScheduler* cloudkitRetryAfter; + +// Send every CK error here: it will update the cloudkitRetryAfter scheduler +- (void)inspectErrorForRetryAfter:(NSError*)ckerror; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithContainer:(CKContainer*)container + reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker + cloudkitDependencies:(CKKSCloudKitClassDependencies*)_cloudKitClassDependencies; + +- (CKKSZoneModifyOperations*)createZone:(CKRecordZone*)zone; + +// Note that on a zone delete, we do not run the subscription operation +// It may or may not run, depending on if any other zone creations have been requested +- (CKKSZoneModifyOperations*)deleteZone:(CKRecordZoneID*)zoneID; + +// For tests only +- (void)halt; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ckks/CKKSZoneModifier.m b/keychain/ckks/CKKSZoneModifier.m new file mode 100644 index 00000000..66d5d134 --- /dev/null +++ b/keychain/ckks/CKKSZoneModifier.m @@ -0,0 +1,310 @@ +#if OCTAGON + +#import + +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CKKSReachabilityTracker.h" +#import "keychain/ckks/CKKSZoneModifier.h" + +#import "utilities/debugging.h" +#import "keychain/ot/ObjCImprovements.h" + +@implementation CKKSZoneModifyOperations + +- (instancetype)init +{ + return nil; +} + +- (instancetype)initWithZoneModificationOperation:(CKKSResultOperation*)zoneModificationOperationDependency + zoneSubscriptionOperation:(CKKSResultOperation*)zoneSubscriptionOperationDependency +{ + if((self = [super init])) { + _zoneModificationOperation = zoneModificationOperationDependency; + _zoneSubscriptionOperation = zoneSubscriptionOperationDependency; + + _zonesToCreate = [NSMutableArray array]; + _subscriptionsToSubscribe = [NSMutableArray array]; + _zoneIDsToDelete = [NSMutableArray array]; + } + return self; +} +@end + +// CKKSZoneModifier + +@interface CKKSZoneModifier () + +// Returned to clients that call createZone/deleteZone before it launches +@property CKKSZoneModifyOperations* pendingOperations; + +@property bool halted; + +@property NSOperationQueue* operationQueue; +@property dispatch_queue_t queue; + +// Used to linearize all CK operations to avoid tripping over our own feet +@property NSHashTable* ckOperations; +@property CKKSZoneModifyOperations* inflightOperations; + +// Set to true if the last CK operation finished with a network error +// Cleared if the last CK operation didn't +// Used as an heuristic to wait on the reachability tracker +@property bool networkFailure; +@end + +@implementation CKKSZoneModifier +- (instancetype)init +{ + return nil; +} + +- (instancetype)initWithContainer:(CKContainer*)container + reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker + cloudkitDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies +{ + if((self = [super init])) { + _container = container; + _reachabilityTracker = reachabilityTracker; + _cloudKitClassDependencies = cloudKitClassDependencies; + + _database = [_container privateCloudDatabase]; + _operationQueue = [[NSOperationQueue alloc] init]; + _queue = dispatch_queue_create([[NSString stringWithFormat:@"CKKSZoneModifier.%@", container.containerIdentifier] UTF8String], + DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + + WEAKIFY(self); + + // This does double-duty: if there's pending zone creation/deletions, it launches them + _cloudkitRetryAfter = [[CKKSNearFutureScheduler alloc] initWithName:@"zonemodifier-ckretryafter" + initialDelay:100*NSEC_PER_MSEC + continuingDelay:100*NSEC_PER_MSEC + keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionPendingCloudKitRetryAfter + block:^{ + STRONGIFY(self); + [self launchOperations]; + }]; + + _ckOperations = [NSHashTable weakObjectsHashTable]; + } + return self; +} + +- (void)_onqueueCreatePendingObjects +{ + dispatch_assert_queue(self.queue); + + if(!self.pendingOperations) { + CKKSResultOperation* zoneModificationOperationDependency = [CKKSResultOperation named:@"zone-modification" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull op) { + }]; + + CKKSResultOperation* zoneSubscriptionOperationDependency = [CKKSResultOperation named:@"zone-subscription" withBlockTakingSelf:^(CKKSResultOperation * _Nonnull op) { + }]; + + self.pendingOperations = [[CKKSZoneModifyOperations alloc] initWithZoneModificationOperation:zoneModificationOperationDependency + zoneSubscriptionOperation:zoneSubscriptionOperationDependency]; + } +} + +- (CKKSZoneModifyOperations*)createZone:(CKRecordZone*)zone +{ + __block CKKSZoneModifyOperations* ops = nil; + + dispatch_sync(self.queue, ^{ + [self _onqueueCreatePendingObjects]; + ops = self.pendingOperations; + + [ops.zonesToCreate addObject:zone]; + CKRecordZoneSubscription* subscription = [[CKRecordZoneSubscription alloc] initWithZoneID:zone.zoneID + subscriptionID:[@"zone:" stringByAppendingString: zone.zoneID.zoneName]]; + [ops.subscriptionsToSubscribe addObject:subscription]; + }); + + [self.cloudkitRetryAfter trigger]; + + return ops; +} + +- (CKKSZoneModifyOperations*)deleteZone:(CKRecordZoneID*)zoneID +{ + __block CKKSZoneModifyOperations* ops = nil; + + dispatch_sync(self.queue, ^{ + [self _onqueueCreatePendingObjects]; + ops = self.pendingOperations; + + [ops.zoneIDsToDelete addObject:zoneID]; + }); + + [self.cloudkitRetryAfter trigger]; + + return ops; +} + +- (void)halt +{ + dispatch_sync(self.queue, ^{ + self.halted = true; + }); +} + +// Called by the NearFutureScheduler +- (void)launchOperations +{ + dispatch_sync(self.queue, ^{ + if(self.halted) { + secnotice("ckkszonemodifier", "Halted; not launching operations"); + return; + } + + CKKSZoneModifyOperations* ops = self.pendingOperations; + if(!ops) { + secinfo("ckkszonemodifier", "No pending zone modification operations; quitting"); + return; + } + + if(self.inflightOperations && (![self.inflightOperations.zoneModificationOperation isFinished] || + ![self.inflightOperations.zoneSubscriptionOperation isFinished])) { + secnotice("ckkszonemodifier", "Have in-flight zone modification operations, will retry later"); + + WEAKIFY(self); + CKKSResultOperation* retrigger = [CKKSResultOperation named:@"retry" withBlock:^{ + STRONGIFY(self); + [self.cloudkitRetryAfter trigger]; + }]; + [retrigger addNullableDependency:self.inflightOperations.zoneModificationOperation]; + [retrigger addNullableDependency:self.inflightOperations.zoneSubscriptionOperation]; + [self.operationQueue addOperation:retrigger]; + return; + } + + self.pendingOperations = nil; + self.inflightOperations = ops; + + CKDatabaseOperation* modifyZonesOperation = [self createModifyZonesOperation:ops]; + CKDatabaseOperation* zoneSubscriptionOperation = [self createModifySubscriptionsOperation:ops]; + + [self.operationQueue addOperation:modifyZonesOperation]; + if(zoneSubscriptionOperation) { + [self.operationQueue addOperation:zoneSubscriptionOperation]; + } + }); +} + +- (CKDatabaseOperation*)createModifyZonesOperation:(CKKSZoneModifyOperations*)ops +{ + secnotice("ckkszonemodifier", "Attempting to create zones %@, delete zones %@", ops.zonesToCreate, ops.zoneIDsToDelete); + + CKDatabaseOperation* zoneModifyOperation = [[self.cloudKitClassDependencies.modifyRecordZonesOperationClass alloc] initWithRecordZonesToSave:ops.zonesToCreate recordZoneIDsToDelete:ops.zoneIDsToDelete]; + [zoneModifyOperation linearDependencies:self.ckOperations]; + + zoneModifyOperation.configuration.automaticallyRetryNetworkFailures = NO; + zoneModifyOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + zoneModifyOperation.configuration.isCloudKitSupportOperation = YES; + zoneModifyOperation.database = self.database; + zoneModifyOperation.name = @"zone-creation-operation"; + zoneModifyOperation.group = [CKOperationGroup CKKSGroupWithName:@"zone-creation"];; + + // We will use the zoneCreationOperation operation in ops to signal completion + WEAKIFY(self); + + zoneModifyOperation.modifyRecordZonesCompletionBlock = ^(NSArray *savedRecordZones, + NSArray *deletedRecordZoneIDs, + NSError *operationError) { + STRONGIFY(self); + + if(operationError) { + secerror("ckkszonemodifier: Zone modification failed: %@", operationError); + [self inspectErrorForRetryAfter:operationError]; + + if ([self.reachabilityTracker isNetworkError:operationError]){ + self.networkFailure = true; + } + } + secnotice("ckkszonemodifier", "created zones: %@", savedRecordZones); + secnotice("ckkszonemodifier", "deleted zones: %@", deletedRecordZoneIDs); + + ops.savedRecordZones = savedRecordZones; + ops.deletedRecordZoneIDs = deletedRecordZoneIDs; + ops.zoneModificationOperation.error = operationError; + + [self.operationQueue addOperation:ops.zoneModificationOperation]; + }; + + if(self.networkFailure) { + secnotice("ckkszonemodifier", "Waiting for reachabilty before issuing zone creation"); + [zoneModifyOperation addNullableDependency:self.reachabilityTracker.reachabilityDependency]; + } + + return zoneModifyOperation; +} + +- (CKDatabaseOperation* _Nullable)createModifySubscriptionsOperation:(CKKSZoneModifyOperations*)ops +{ + if(ops.subscriptionsToSubscribe.count == 0) { + [self.operationQueue addOperation: ops.zoneSubscriptionOperation]; + return nil; + } + + CKDatabaseOperation* zoneSubscriptionOperation = [[self.cloudKitClassDependencies.modifySubscriptionsOperationClass alloc] initWithSubscriptionsToSave:ops.subscriptionsToSubscribe subscriptionIDsToDelete:nil]; + [zoneSubscriptionOperation linearDependencies:self.ckOperations]; + + zoneSubscriptionOperation.configuration.automaticallyRetryNetworkFailures = NO; + zoneSubscriptionOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + zoneSubscriptionOperation.configuration.isCloudKitSupportOperation = YES; + zoneSubscriptionOperation.database = self.database; + zoneSubscriptionOperation.name = @"zone-subscription-operation"; + + // Completion blocks don't count for dependencies. Use this intermediate operation hack instead. + NSBlockOperation* zoneSubscriptionCompleteOperation = [[NSBlockOperation alloc] init]; + zoneSubscriptionCompleteOperation.name = @"zone-subscription-complete"; + + WEAKIFY(self); + zoneSubscriptionOperation.modifySubscriptionsCompletionBlock = ^(NSArray * _Nullable savedSubscriptions, + NSArray * _Nullable deletedSubscriptionIDs, + NSError * _Nullable operationError) { + STRONGIFY(self); + + if(operationError) { + secerror("ckkszonemodifier: Couldn't create cloudkit zone subscription; keychain syncing is severely degraded: %@", operationError); + [self inspectErrorForRetryAfter:operationError]; + + if ([self.reachabilityTracker isNetworkError:operationError]){ + self.networkFailure = true; + } + } + secnotice("ckkszonemodifier", "Successfully subscribed to %@", savedSubscriptions); + + ops.savedSubscriptions = savedSubscriptions; + ops.deletedSubscriptionIDs = deletedSubscriptionIDs; + ops.zoneSubscriptionOperation.error = operationError; + + [self.operationQueue addOperation: ops.zoneSubscriptionOperation]; + }; + + [zoneSubscriptionOperation addNullableDependency:ops.zoneModificationOperation]; + + if(self.networkFailure) { + secnotice("ckkszonemodifier", "Waiting for reachabilty before issuing zone subscription"); + [zoneSubscriptionOperation addNullableDependency:self.reachabilityTracker.reachabilityDependency]; + } + + return zoneSubscriptionOperation; +} + +- (void)inspectErrorForRetryAfter:(NSError*)ckerror +{ + NSTimeInterval delay = CKRetryAfterSecondsForError(ckerror); + if(delay) { + uint64_t ns_delay = NSEC_PER_SEC * ((uint64_t) delay); + secnotice("ckkszonemodifier", "CK operation failed with rate-limit, scheduling delay for %.1f seconds: %@", delay, ckerror); + [self.cloudkitRetryAfter waitUntil:ns_delay]; + } +} + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/CKKSZoneStateEntry.h b/keychain/ckks/CKKSZoneStateEntry.h index e66f16bf..fb44ce17 100644 --- a/keychain/ckks/CKKSZoneStateEntry.h +++ b/keychain/ckks/CKKSZoneStateEntry.h @@ -33,6 +33,8 @@ #import #import "keychain/ckks/CKKSFixups.h" +NS_ASSUME_NONNULL_BEGIN + /* * This class hold the state for a particular zone: has the zone been created, have we subscribed to it, * what's the current change token, etc. @@ -51,14 +53,14 @@ @property NSString* ckzone; @property bool ckzonecreated; @property bool ckzonesubscribed; -@property (getter=getChangeToken, setter=setChangeToken:) CKServerChangeToken* changeToken; -@property NSData* encodedChangeToken; -@property NSDate* lastFetchTime; +@property (nullable, getter=getChangeToken, setter=setChangeToken:) CKServerChangeToken* changeToken; +@property (nullable) NSData* encodedChangeToken; +@property (nullable) NSDate* lastFetchTime; @property CKKSFixup lastFixup; -@property CKKSRateLimiter* rateLimiter; -@property NSData* encodedRateLimiter; +@property (nullable) CKKSRateLimiter* rateLimiter; +@property (nullable) NSData* encodedRateLimiter; + (instancetype)state:(NSString*)ckzone; @@ -68,16 +70,17 @@ - (instancetype)initWithCKZone:(NSString*)ckzone zoneCreated:(bool)ckzonecreated zoneSubscribed:(bool)ckzonesubscribed - changeToken:(NSData*)changetoken - lastFetch:(NSDate*)lastFetch + changeToken:(NSData* _Nullable)changetoken + lastFetch:(NSDate* _Nullable)lastFetch lastFixup:(CKKSFixup)lastFixup - encodedRateLimiter:(NSData*)encodedRateLimiter; + encodedRateLimiter:(NSData* _Nullable)encodedRateLimiter; - (CKServerChangeToken*)getChangeToken; -- (void)setChangeToken:(CKServerChangeToken*)token; +- (void)setChangeToken:(CKServerChangeToken* _Nullable)token; - (BOOL)isEqual:(id)object; @end +NS_ASSUME_NONNULL_END #endif #endif /* CKKSZoneStateEntry_h */ diff --git a/keychain/ckks/CKKSZoneStateEntry.m b/keychain/ckks/CKKSZoneStateEntry.m index 14e0fc00..bb03f474 100644 --- a/keychain/ckks/CKKSZoneStateEntry.m +++ b/keychain/ckks/CKKSZoneStateEntry.m @@ -167,18 +167,14 @@ }; } -+ (instancetype) fromDatabaseRow: (NSDictionary*) row { - NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; - - return [[CKKSZoneStateEntry alloc] initWithCKZone: row[@"ckzone"] - zoneCreated: [row[@"ckzonecreated"] boolValue] - zoneSubscribed: [row[@"ckzonesubscribed"] boolValue] - changeToken: ![row[@"changetoken"] isEqual: [NSNull null]] ? - [[NSData alloc] initWithBase64EncodedString: row[@"changetoken"] options:0] : - nil - lastFetch: [row[@"lastfetch"] isEqual: [NSNull null]] ? nil : [dateFormat dateFromString: row[@"lastfetch"]] - lastFixup:(CKKSFixup)[row[@"lastFixup"] integerValue] - encodedRateLimiter: [row[@"ratelimiter"] isEqual: [NSNull null]] ? nil : [[NSData alloc] initWithBase64EncodedString: row[@"ratelimiter"] options:0] ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + return [[CKKSZoneStateEntry alloc] initWithCKZone:row[@"ckzone"].asString + zoneCreated:row[@"ckzonecreated"].asBOOL + zoneSubscribed:row[@"ckzonesubscribed"].asBOOL + changeToken:row[@"changetoken"].asBase64DecodedData + lastFetch:row[@"lastfetch"].asISO8601Date + lastFixup:(CKKSFixup)row[@"lastFixup"].asNSInteger + encodedRateLimiter:row[@"ratelimiter"].asBase64DecodedData ]; } diff --git a/keychain/ckks/CloudKitCategories.h b/keychain/ckks/CloudKitCategories.h index 01132680..45fad55a 100644 --- a/keychain/ckks/CloudKitCategories.h +++ b/keychain/ckks/CloudKitCategories.h @@ -27,6 +27,8 @@ #import #import +#import "keychain/ot/OTDefines.h" + NS_ASSUME_NONNULL_BEGIN @interface CKOperationGroup (CKKS) @@ -38,6 +40,7 @@ NS_ASSUME_NONNULL_BEGIN // 1) An atomic write failed // 2) Every single suberror is either CKErrorServerRecordChanged or CKErrorUnknownItem - (bool)ckksIsCKErrorRecordChangedError; +- (BOOL)isCuttlefishError:(CuttlefishErrorCode)cuttlefishError; @end // Ensure we don't print addresses @interface CKAccountInfo (CKKS) diff --git a/keychain/ckks/CloudKitCategories.m b/keychain/ckks/CloudKitCategories.m index 5f82c453..ed46d93d 100644 --- a/keychain/ckks/CloudKitCategories.m +++ b/keychain/ckks/CloudKitCategories.m @@ -54,6 +54,31 @@ return false; } +- (BOOL)isCuttlefishError:(CuttlefishErrorCode)cuttlefishError +{ + NSError *error = self; + NSError* underlyingError = error.userInfo[NSUnderlyingErrorKey]; + + // This funny code is becase CodeOperation was not wrapping underlying errors with CKError, and then they fixed that in + // if you find this code, it probably time to always check for CKErrorDomain/CKErrorServerRejectedRequest + if ([error.domain isEqualToString:CKErrorDomain] && error.code == CKErrorServerRejectedRequest && underlyingError) { + error = underlyingError; + } + + if([error.domain isEqualToString:CKInternalErrorDomain] && error.code == CKErrorInternalPluginError) { + NSError* underlyingError = error.userInfo[NSUnderlyingErrorKey]; + if(underlyingError && + [underlyingError.domain isEqualToString:CuttlefishErrorDomain] && + underlyingError.code == cuttlefishError) { + return YES; + } + } + return NO; +} + + + + @end @implementation CKAccountInfo (CKKS) diff --git a/keychain/ckks/CloudKitDependencies.h b/keychain/ckks/CloudKitDependencies.h index 6b37c555..ae9ad1c3 100644 --- a/keychain/ckks/CloudKitDependencies.h +++ b/keychain/ckks/CloudKitDependencies.h @@ -27,6 +27,7 @@ #import #import #import +#import NS_ASSUME_NONNULL_BEGIN @@ -149,18 +150,19 @@ NS_ASSUME_NONNULL_BEGIN @end /* APSConnection */ -@protocol CKKSAPSConnection +@protocol OctagonAPSConnection + (instancetype)alloc; - (id)initWithEnvironmentName:(NSString*)environmentName namedDelegatePort:(NSString*)namedDelegatePort queue:(dispatch_queue_t)queue; -- (void)setEnabledTopics:(NSArray*)enabledTopics; +- (void)setEnabledTopics:(NSArray *)enabledTopics; +- (void)setDarkWakeTopics:(NSArray *)darkWakeTopics; @property (nonatomic, readwrite, assign) id delegate; @end -@interface APSConnection (SecCKKSAPSConnection) +@interface APSConnection (SecOctagonAPSConnection) @end /* NSNotificationCenter */ @@ -169,7 +171,17 @@ NS_ASSUME_NONNULL_BEGIN - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject; - (void)removeObserver:(id)observer; @end -@interface NSNotificationCenter () +@interface NSNotificationCenter (CKKSMock) +@end + +@protocol CKKSNSDistributedNotificationCenter ++ (instancetype)defaultCenter; +- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject; +- (void)removeObserver:(id)observer; +- (void)postNotificationName:(NSNotificationName)name object:(nullable NSString *)object userInfo:(nullable NSDictionary *)userInfo options:(NSDistributedNotificationOptions)options; +@end + +@interface NSDistributedNotificationCenter (CKKSMock) @end /* Since CKDatabase doesn't share any types with NSOperationQueue, tell the type system about addOperation */ diff --git a/keychain/ckks/NSOperationCategories.h b/keychain/ckks/NSOperationCategories.h index 9740dd31..48a2b623 100644 --- a/keychain/ckks/NSOperationCategories.h +++ b/keychain/ckks/NSOperationCategories.h @@ -21,7 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import "keychain/ckks/NSOperationCategories.h" +NS_ASSUME_NONNULL_BEGIN @interface NSOperation (CKKSUsefulPrintingOperation) - (NSString*)description; @@ -31,7 +31,7 @@ - (NSString*)selfname; // If op is nonnull, op becomes a dependency of this operation -- (void)addNullableDependency:(NSOperation*)op; +- (void)addNullableDependency:(NSOperation* _Nullable)op; // Add all operations in this collection as dependencies, then add yourself to the collection - (void)linearDependencies:(NSHashTable*)collection; @@ -49,3 +49,5 @@ @interface NSBlockOperation (CKKSUsefulConstructorOperation) + (instancetype)named:(NSString*)name withBlock:(void (^)(void))block; @end + +NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/NSOperationCategories.m b/keychain/ckks/NSOperationCategories.m index 5d9d2c7d..d69f47a6 100644 --- a/keychain/ckks/NSOperationCategories.m +++ b/keychain/ckks/NSOperationCategories.m @@ -23,6 +23,7 @@ #import #import "keychain/ckks/NSOperationCategories.h" +#import "keychain/ot/ObjCImprovements.h" @implementation NSOperation (CKKSUsefulPrintingOperation) - (NSString*)selfname { @@ -118,11 +119,11 @@ - (void)removeDependenciesUponCompletion { - __weak __typeof(self) weakSelf = self; + WEAKIFY(self); self.completionBlock = ^{ - __strong __typeof(weakSelf) strongSelf = weakSelf; - for (NSOperation *op in strongSelf.dependencies) { - [strongSelf removeDependency:op]; + STRONGIFY(self); + for (NSOperation *op in self.dependencies) { + [self removeDependency:op]; } }; } diff --git a/keychain/ckks/CKKSAPSReceiver.h b/keychain/ckks/OctagonAPSReceiver.h similarity index 75% rename from keychain/ckks/CKKSAPSReceiver.h rename to keychain/ckks/OctagonAPSReceiver.h index 9b1b714e..cf33ac99 100644 --- a/keychain/ckks/CKKSAPSReceiver.h +++ b/keychain/ckks/OctagonAPSReceiver.h @@ -43,26 +43,35 @@ NS_ASSUME_NONNULL_BEGIN - (void)notifyZoneChange:(CKRecordZoneNotification* _Nullable)notification; @end -@interface CKKSAPSReceiver : NSObject +@protocol OctagonCuttlefishUpdateReceiver +- (void)notifyContainerChange:(APSIncomingMessage* _Nullable)notification; +@end -@property NSMapTable>* zoneMap; +@interface OctagonAPSReceiver : NSObject // class dependencies (for injection) -@property (readonly) Class apsConnectionClass; -@property (nullable) id apsConnection; +@property (readonly) Class apsConnectionClass; +@property (nullable) id apsConnection; + +@property (readonly) BOOL haveStalePushes; + (instancetype)receiverForEnvironment:(NSString*)environmentName namedDelegatePort:(NSString*)namedDelegatePort - apsConnectionClass:(Class)apsConnectionClass; + apsConnectionClass:(Class)apsConnectionClass; + - (CKKSCondition*)registerReceiver:(id)receiver forZoneID:(CKRecordZoneID*)zoneID; +- (CKKSCondition*)registerCuttlefishReceiver:(id)receiver forContainerName:(NSString*)containerName; // Test support: - (instancetype)initWithEnvironmentName:(NSString*)environmentName namedDelegatePort:(NSString*)namedDelegatePort - apsConnectionClass:(Class)apsConnectionClass; + apsConnectionClass:(Class)apsConnectionClass; // This is the queue that APNS will use send the notifications to us + (dispatch_queue_t)apsDeliveryQueue; +// timeout for stale push cache, in nanoseconds ++ (int64_t)stalePushTimeout; + @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/OctagonAPSReceiver.m b/keychain/ckks/OctagonAPSReceiver.m new file mode 100644 index 00000000..fbd0c175 --- /dev/null +++ b/keychain/ckks/OctagonAPSReceiver.m @@ -0,0 +1,376 @@ +/* + * 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@ + */ + +#if OCTAGON + +#import "keychain/ckks/OctagonAPSReceiver.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSCondition.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/analytics/SecMetrics.h" +#import "keychain/analytics/SecEventMetric.h" +#import "keychain/ot/ObjCImprovements.h" +#import +#include +#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 OctagonAPSReceiver() + +@property CKKSNearFutureScheduler *clearStalePushNotifications; + +// If we receive notifications for a record zone that hasn't been registered yet, send them a their updates when they register +@property NSMutableDictionary*>* undeliveredUpdates; + +// Same, but for cuttlefish containers (and only remember that a push was received; don't remember the pushes themselves) +@property NSMutableSet* undeliveredCuttlefishUpdates; + +@property NSMapTable>* zoneMap; +@property NSMapTable>* octagonContainerMap; +@end + +@implementation OctagonAPSReceiver + ++ (instancetype)receiverForEnvironment:(NSString *)environmentName + namedDelegatePort:(NSString*)namedDelegatePort + apsConnectionClass:(Class)apsConnectionClass { + static NSMutableDictionary* environmentMap = nil; + + if(environmentName == nil) { + secnotice("octagonpush", "No push environment; not bringing up APS."); + return nil; + } + + @synchronized([self class]) { + if(environmentMap == nil) { + environmentMap = [[NSMutableDictionary alloc] init]; + } + + OctagonAPSReceiver* recv = [environmentMap valueForKey: environmentName]; + + if(recv == nil) { + recv = [[OctagonAPSReceiver alloc] initWithEnvironmentName: environmentName namedDelegatePort:namedDelegatePort apsConnectionClass: apsConnectionClass]; + [environmentMap setValue: recv forKey: environmentName]; + } + + return recv; + } +} + ++ (dispatch_queue_t)apsDeliveryQueue { + static dispatch_queue_t aps_dispatch_queue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + aps_dispatch_queue = dispatch_queue_create("aps-callback-queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + }); + return aps_dispatch_queue; +} + ++ (int64_t)stalePushTimeout { + return 5*60*NSEC_PER_MSEC; +} + +- (BOOL) haveStalePushes +{ + __block BOOL haveStalePushes = NO; + dispatch_sync([OctagonAPSReceiver apsDeliveryQueue], ^{ + haveStalePushes = (self.undeliveredUpdates.count || self.undeliveredCuttlefishUpdates.count); + }); + return haveStalePushes; +} + +- (NSSet*)cuttlefishPushTopics +{ + NSString* cuttlefishTopic = [kCKPushTopicPrefix stringByAppendingString:@"com.apple.security.cuttlefish"]; + + // Currently cuttlefish pushes are sent to TPH. System XPC services can't properly register to be woken + // at push time, so receive them for it. + NSString* tphTopic = [kCKPushTopicPrefix stringByAppendingString:@"com.apple.TrustedPeersHelper"]; + NSString* securitydTopic = [kCKPushTopicPrefix stringByAppendingString:@"com.apple.securityd"]; + + return [NSSet setWithArray:@[cuttlefishTopic, tphTopic, securitydTopic]]; +} + +- (instancetype)initWithEnvironmentName:(NSString*)environmentName + namedDelegatePort:(NSString*)namedDelegatePort + apsConnectionClass:(Class)apsConnectionClass { + if(self = [super init]) { + _apsConnectionClass = apsConnectionClass; + _apsConnection = NULL; + + _undeliveredUpdates = [NSMutableDictionary dictionary]; + _undeliveredCuttlefishUpdates = [[NSMutableSet alloc] init]; + + // APS might be slow. This doesn't need to happen immediately, so let it happen later. + WEAKIFY(self); + dispatch_async([OctagonAPSReceiver apsDeliveryQueue], ^{ + STRONGIFY(self); + if(!self) { + return; + } + self.apsConnection = [[self.apsConnectionClass alloc] initWithEnvironmentName:environmentName namedDelegatePort:namedDelegatePort queue:[OctagonAPSReceiver apsDeliveryQueue]]; + self.apsConnection.delegate = self; + + // The following string should match: [[NSBundle mainBundle] bundleIdentifier] + NSString* ckksTopic = [kCKPushTopicPrefix stringByAppendingString:@"com.apple.securityd"]; + + NSArray* topics = [@[ckksTopic] arrayByAddingObjectsFromArray:[self cuttlefishPushTopics].allObjects]; + [self.apsConnection setEnabledTopics:topics]; +#if TARGET_OS_OSX + [self.apsConnection setDarkWakeTopics:topics]; +#endif + }); + + _zoneMap = [NSMapTable strongToWeakObjectsMapTable]; + _octagonContainerMap = [NSMapTable strongToWeakObjectsMapTable]; + + void (^clearPushBlock)(void) = ^{ + dispatch_async([OctagonAPSReceiver apsDeliveryQueue], ^{ + NSDictionary*> *droppedUpdates; + STRONGIFY(self); + if (self == nil) { + return; + } + + droppedUpdates = self.undeliveredUpdates; + + self.undeliveredUpdates = [NSMutableDictionary dictionary]; + [self.undeliveredCuttlefishUpdates removeAllObjects]; + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{ + STRONGIFY(self); + [self reportDroppedPushes:droppedUpdates]; + }); + }); + }; + + _clearStalePushNotifications = [[CKKSNearFutureScheduler alloc] initWithName: @"clearStalePushNotifications" + delay:[[self class] stalePushTimeout] + keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:clearPushBlock]; + } + return self; +} + +// Report that pushes we are dropping +- (void)reportDroppedPushes:(NSDictionary*>*)notifications +{ + bool hasBeenUnlocked = false; + CFErrorRef error = NULL; + + /* + * Let server know that device is not unlocked yet + */ + + (void)SecAKSGetHasBeenUnlocked(&hasBeenUnlocked, &error); + CFReleaseNull(error); + + NSString *eventName = @"CKKS APNS Push Dropped"; + if (!hasBeenUnlocked) { + eventName = @"CKKS APNS Push Dropped - never unlocked"; + } + + for (NSString *zone in notifications) { + for (CKRecordZoneNotification *notification in notifications[zone]) { + if (notification.ckksPushTracingEnabled) { + secnotice("apsnotification", "Submitting initial CKEventMetric due to notification %@", notification); + + SecEventMetric *metric = [[SecEventMetric alloc] initWithEventName:@"APNSPushMetrics"]; + metric[@"push_token_uuid"] = notification.ckksPushTracingUUID; + metric[@"push_received_date"] = notification.ckksPushReceivedDate; + + metric[@"push_event_name"] = eventName; + + [[SecMetrics managerObject] submitEvent:metric]; + } + } + } +} + + + +- (CKKSCondition*)registerReceiver:(id)receiver forZoneID:(CKRecordZoneID *)zoneID { + CKKSCondition* finished = [[CKKSCondition alloc] init]; + + WEAKIFY(self); + dispatch_async([OctagonAPSReceiver apsDeliveryQueue], ^{ + STRONGIFY(self); + if(!self) { + secerror("ckks: received registration for released OctagonAPSReceiver"); + return; + } + + [self.zoneMap setObject:receiver forKey: zoneID.zoneName]; + + NSMutableSet* currentPendingMessages = self.undeliveredUpdates[zoneID.zoneName]; + [self.undeliveredUpdates removeObjectForKey:zoneID.zoneName]; + + for(CKRecordZoneNotification* message in currentPendingMessages.allObjects) { + // Now, send the receiver its notification! + secerror("ckks: sending stored push(%@) to newly-registered zone(%@): %@", message, zoneID.zoneName, receiver); + [receiver notifyZoneChange:message]; + } + + [finished fulfill]; + }); + + return finished; +} + +- (CKKSCondition*)registerCuttlefishReceiver:(id)receiver + forContainerName:(NSString*)containerName +{ + CKKSCondition* finished = [[CKKSCondition alloc] init]; + + WEAKIFY(self); + dispatch_async([OctagonAPSReceiver apsDeliveryQueue], ^{ + STRONGIFY(self); + if(!self) { + secerror("octagon: received registration for released OctagonAPSReceiver"); + return; + } + + [self.octagonContainerMap setObject:receiver forKey:containerName]; + if([self.undeliveredCuttlefishUpdates containsObject:containerName]) { + [self.undeliveredCuttlefishUpdates removeObject:containerName]; + + // Now, send the receiver its fake notification! + secerror("octagon: sending fake push to newly-registered cuttlefish receiver(%@): %@", containerName, receiver); + [receiver notifyContainerChange:nil]; + } + + [finished fulfill]; + }); + + return finished; +} + +#pragma mark - APS Delegate callbacks + +- (void)connection:(APSConnection *)connection didReceivePublicToken:(NSData *)publicToken { + // no-op. + secnotice("octagonpush", "OctagonAPSDelegate initiated: %@", connection); +} + +- (void)connection:(APSConnection *)connection didReceiveToken:(NSData *)token forTopic:(NSString *)topic identifier:(NSString *)identifier { + secnotice("octagonpush", "Received per-topic push token \"%@\" for topic \"%@\" identifier \"%@\" on connection %@", token, topic, identifier, connection); +} + +- (void)connection:(APSConnection *)connection didReceiveIncomingMessage:(APSIncomingMessage *)message { + secnotice("octagonpush", "OctagonAPSDelegate received a message(%@): %@ ", message.topic, message.userInfo); + + // Report back through APS that we received a message + if(message.tracingEnabled) { + [connection confirmReceiptForMessage:message]; + } + + NSSet* cuttlefishTopics = [self cuttlefishPushTopics]; + + // Separate and handle cuttlefish notifications + if([cuttlefishTopics containsObject:message.topic] && [message.userInfo objectForKey:@"cf"]) { + NSDictionary* cfInfo = message.userInfo[@"cf"]; + NSString* container = cfInfo[@"c"]; + + secnotice("octagonpush", "Received a cuttlefish push to container %@", container); + + if(container) { + id receiver = [self.octagonContainerMap objectForKey:container]; + + if(receiver) { + [receiver notifyContainerChange:message]; + } else { + secerror("octagonpush: received cuttlefish push for unregistered container: %@", container); + [self.undeliveredCuttlefishUpdates addObject:container]; + [self.clearStalePushNotifications trigger]; + } + } else { + // APS stripped the container. Send a push to all registered containers. + @synchronized(self.octagonContainerMap) { + for(id receiver in [self.octagonContainerMap objectEnumerator]) { + [receiver notifyContainerChange:nil]; + } + } + } + + return; + } + + 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.zoneName]; + if(recv) { + [recv notifyZoneChange:rznotification]; + } else { + secerror("ckks: received push for unregistered zone: %@", rznotification); + if(rznotification.recordZoneID) { + NSMutableSet* currentPendingMessages = self.undeliveredUpdates[rznotification.recordZoneID.zoneName]; + if(currentPendingMessages) { + [currentPendingMessages addObject:rznotification]; + } else { + self.undeliveredUpdates[rznotification.recordZoneID.zoneName] = [NSMutableSet setWithObject:rznotification]; + [self.clearStalePushNotifications trigger]; + } + } + } + } else { + secerror("ckks: unexpected notification: %@", notification); + } +} + +@end + +#endif // OCTAGON diff --git a/keychain/ckks/RateLimiter.h b/keychain/ckks/RateLimiter.h index 9d8f1f5c..5cc43ec9 100644 --- a/keychain/ckks/RateLimiter.h +++ b/keychain/ckks/RateLimiter.h @@ -40,8 +40,6 @@ typedef NS_ENUM(NSInteger, RateLimiterBadness) { }; - (instancetype _Nullable)initWithConfig:(NSDictionary*)config; -- (instancetype _Nullable)initWithPlistFromURL:(NSURL*)url; -- (instancetype _Nullable)initWithAssetType:(NSString*)type; // Not implemented yet - (instancetype _Nullable)initWithCoder:(NSCoder*)coder; - (instancetype _Nullable)init NS_UNAVAILABLE; @@ -56,7 +54,7 @@ typedef NS_ENUM(NSInteger, RateLimiterBadness) { * At badness 5 judge:at: has determined there is too much activity so the caller should hold off altogether. The limitTime object will indicate when * this overloaded state will end. */ -- (NSInteger)judge:(id)obj at:(NSDate*)time limitTime:(NSDate* _Nonnull __autoreleasing* _Nonnull)limitTime; +- (RateLimiterBadness)judge:(id)obj at:(NSDate*)time limitTime:(NSDate* _Nonnull __autoreleasing* _Nonnull)limitTime; - (void)reset; - (NSString*)diagnostics; diff --git a/keychain/ckks/RateLimiter.m b/keychain/ckks/RateLimiter.m index 67a5ac81..1dd84320 100644 --- a/keychain/ckks/RateLimiter.m +++ b/keychain/ckks/RateLimiter.m @@ -46,25 +46,6 @@ return self; } -- (instancetype)initWithPlistFromURL:(NSURL *)url { - self = [super init]; - if (self) { - _config = [NSDictionary dictionaryWithContentsOfURL:url]; - if (!_config) { - secerror("RateLimiter[?]: could not read config from %@", url); - return nil; - } - _assetType = nil; - [self reset]; - } - return self; -} - -// TODO implement MobileAsset loading -- (instancetype)initWithAssetType:(NSString *)type { - return nil; -} - - (instancetype)initWithCoder:(NSCoder *)coder { if (!coder) { return nil; @@ -94,7 +75,7 @@ return self; } -- (NSInteger)judge:(id _Nonnull)obj at:(NSDate * _Nonnull)time limitTime:(NSDate * _Nullable __autoreleasing * _Nonnull)limitTime { +- (RateLimiterBadness)judge:(id _Nonnull)obj at:(NSDate * _Nonnull)time limitTime:(NSDate * _Nullable __autoreleasing * _Nonnull)limitTime { //sudo defaults write /Library/Preferences/com.apple.security DisableKeychainRateLimiting -bool YES NSNumber *disabled = CFBridgingRelease(CFPreferencesCopyValue(CFSTR("DisableKeychainRateLimiting"), @@ -223,7 +204,7 @@ if ([self stateSize] > [self.config[@"general"][@"maxStateSize"] unsignedIntegerValue]) { // Trimming did not reduce size (enough), we need to take measures - self.overloadUntil = [time dateByAddingTimeInterval:[self.config[@"general"][@"overloadDuration"] intValue]]; + self.overloadUntil = [time dateByAddingTimeInterval:[self.config[@"general"][@"overloadDuration"] unsignedIntValue]]; secerror("RateLimiter[%@] state size %lu exceeds max %lu, overloaded until %@", self.config[@"general"][@"name"], (unsigned long)[self stateSize], @@ -280,19 +261,4 @@ return YES; } -- (NSArray *)topOffenders:(int)num { - NSInteger idx = [self.config[@"general"][@"topOffendersPropertyIndex"] integerValue]; - NSDate *now = [NSDate date]; - NSSet *contenderkeys = [self.groups[idx] keysOfEntriesPassingTest:^BOOL(NSString *key, NSDate *obj, BOOL *stop) { - return [now timeIntervalSinceDate:obj] > 0 ? YES : NO; - }]; - if ([contenderkeys count] == 0) { - return [NSArray new]; - } - NSDictionary *contenders = [NSDictionary dictionaryWithObjects:[self.groups[idx] objectsForKeys:[contenderkeys allObjects] - notFoundMarker:[NSDate date]] - forKeys:[contenderkeys allObjects]]; - return [[[contenders keysSortedByValueUsingSelector:@selector(compare:)] reverseObjectEnumerator] allObjects]; -} - @end diff --git a/keychain/ckks/proto/source/CKKSSerializedKey.h b/keychain/ckks/proto/generated_source/CKKSSerializedKey.h similarity index 100% rename from keychain/ckks/proto/source/CKKSSerializedKey.h rename to keychain/ckks/proto/generated_source/CKKSSerializedKey.h diff --git a/keychain/ckks/proto/source/CKKSSerializedKey.m b/keychain/ckks/proto/generated_source/CKKSSerializedKey.m similarity index 100% rename from keychain/ckks/proto/source/CKKSSerializedKey.m rename to keychain/ckks/proto/generated_source/CKKSSerializedKey.m diff --git a/keychain/ckks/tests/CKKSAESSIVEncryptionTests.m b/keychain/ckks/tests/CKKSAESSIVEncryptionTests.m index 570c4c8c..7420cd8f 100644 --- a/keychain/ckks/tests/CKKSAESSIVEncryptionTests.m +++ b/keychain/ckks/tests/CKKSAESSIVEncryptionTests.m @@ -35,6 +35,7 @@ #include #include +#include "OSX/sec/Security/SecItemShim.h" @interface CloudKitKeychainAESSIVEncryptionTests : CloudKitMockXCTest @end @@ -62,8 +63,12 @@ } - (void)testKeyGeneration { - CKKSAESSIVKey* key1 = [CKKSAESSIVKey randomKey]; - CKKSAESSIVKey* key2 = [CKKSAESSIVKey randomKey]; + NSError* error = nil; + CKKSAESSIVKey* key1 = [CKKSAESSIVKey randomKey:&error]; + XCTAssertNil(error, "Should be no error creating random key"); + CKKSAESSIVKey* key2 = [CKKSAESSIVKey randomKey:&error]; + XCTAssertNil(error, "Should be no error creating random key"); + CKKSAESSIVKey* fixedkey1 = [[CKKSAESSIVKey alloc] initWithBase64: @"uImdbZ7Zg+6WJXScTnRBfNmoU1UiMkSYxWc+d1Vuq3IFn2RmTRkTdWTe3HmeWo1pAomqy+upK8KHg2PGiRGhqg=="]; XCTAssertNotNil(fixedkey1, "fixedkey1 generated from base64"); CKKSAESSIVKey* fixedkey2 = [[CKKSAESSIVKey alloc] initWithBase64: @"uImdbZ7Zg+6WJXScTnRBfNmoU1UiMkSYxWc+d1Vuq3IFn2RmTRkTdWTe3HmeWo1pAomqy+upK8KHg2PGiRGhqg=="]; @@ -275,7 +280,7 @@ NSMutableDictionary* query = [@{ (id)kSecClass : (id)kSecClassInternetPassword, (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup: @"com.apple.security.ckks", (id)kSecAttrDescription: tlk.keyclass, (id)kSecAttrServer: tlk.zoneID.zoneName, @@ -779,7 +784,7 @@ uuid:@"f5e7f20f-0885-48f9-b75d-9f0cfd2171b6" keyclass:SecCKKSKeyClassC state:SecCKKSProcessedStateLocal - zoneID:nil + zoneID:[[CKRecordZoneID alloc] initWithZoneName:@"testzone" ownerName:CKCurrentUserDefaultName] encodedCKRecord:nil currentkey:true]; @@ -788,6 +793,40 @@ XCTAssertTrue([self encryptAndDecryptDictionary:aligned_80 key:key], "Roundtrip with aligned data succeeds"); } +- (void)testCKKSKeychainBackedKeySerialization { + NSError* error = nil; + CKKSKeychainBackedKey* tlk = [self fakeTLK:self.testZoneID].keycore; + CKKSKeychainBackedKey* classC = [CKKSKeychainBackedKey randomKeyWrappedByParent:tlk keyclass:SecCKKSKeyClassC error:&error]; + XCTAssertNil(error, "Should be no error creating classC key"); + + XCTAssertTrue([tlk saveKeyMaterialToKeychain:&error], "Should be able to save tlk key material to keychain"); + XCTAssertNil(error, "Should be no error saving key material"); + + XCTAssertTrue([classC saveKeyMaterialToKeychain:&error], "Should be able to save classC key material to keychain"); + XCTAssertNil(error, "Should be no error saving key material"); + + NSKeyedArchiver* encoder = [[NSKeyedArchiver alloc] initRequiringSecureCoding:YES]; + [encoder encodeObject:tlk forKey:@"tlk"]; + [encoder encodeObject:classC forKey:@"classC"]; + NSData* data = encoder.encodedData; + XCTAssertNotNil(data, "encoding should have produced some data"); + + NSKeyedUnarchiver* decoder = [[NSKeyedUnarchiver alloc] initForReadingFromData:data error:nil]; + CKKSKeychainBackedKey* decodedTLK = [decoder decodeObjectOfClass: [CKKSKeychainBackedKey class] forKey:@"tlk"]; + CKKSKeychainBackedKey* decodedClassC = [decoder decodeObjectOfClass: [CKKSKeychainBackedKey class] forKey:@"classC"]; + + XCTAssertEqualObjects(tlk, decodedTLK, "TLKs should transit NSSecureCoding without changes"); + XCTAssertEqualObjects(classC, decodedClassC, "Class C keys should transit NSSecureCoding without changes"); + + // Now, check that they can load the key material + + XCTAssertTrue([decodedTLK loadKeyMaterialFromKeychain:&error], "Should be able to load tlk key material from keychain"); + XCTAssertNil(error, "Should be no error from loading key material"); + + XCTAssertTrue([decodedClassC loadKeyMaterialFromKeychain:&error], "Should be able to load classC key material from keychain"); + XCTAssertNil(error, "Should be no error from loading key material"); +} + @end #endif // OCTAGON diff --git a/keychain/ckks/tests/CKKSAPSHandlingTests.m b/keychain/ckks/tests/CKKSAPSHandlingTests.m index bcdedb93..34b0a322 100644 --- a/keychain/ckks/tests/CKKSAPSHandlingTests.m +++ b/keychain/ckks/tests/CKKSAPSHandlingTests.m @@ -33,10 +33,10 @@ #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/OctagonAPSReceiver.h" #import "keychain/ckks/CKKSKey.h" #import "keychain/ckks/CKKSPeer.h" -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CloudKitCategories.h" @@ -44,7 +44,7 @@ #import "keychain/ckks/tests/CKKSTests.h" #import "keychain/ot/OTDefines.h" -#import "keychain/ckks/tests/CKKSAPSReceiverTests.h" +#import "keychain/ckks/tests/OctagonAPSReceiverTests.h" @interface CKKSAPSHandlingTests : CloudKitKeychainSyncingTestsBase @property CKRecordZoneID* manateeZoneID; @@ -70,9 +70,9 @@ [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]; + self.manateeView = [[CKKSViewManager manager] findOrCreateView:@"Manatee"]; XCTAssertNotNil(self.manateeView, "CKKSViewManager created the Manatee view"); + [self.ckksViews addObject:self.manateeView]; } - (void)tearDown { @@ -88,7 +88,7 @@ } + (APSIncomingMessage*)messageWithTracingEnabledForZoneID:(CKRecordZoneID*)zoneID { - APSIncomingMessage* apsMessage = [CKKSAPSReceiverTests messageForZoneID:zoneID]; + APSIncomingMessage* apsMessage = [OctagonAPSReceiverTests messageForZoneID:zoneID]; NSUUID* nsuuid = [NSUUID UUID]; uuid_t uuid = {0}; [nsuuid getUUIDBytes:(unsigned char*)&uuid]; @@ -144,7 +144,7 @@ // 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 + OctagonAPSReceiver* apsReceiver = [OctagonAPSReceiver receiverForEnvironment:self.apsEnvironment namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[FakeAPSConnection class]]; XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver"); @@ -209,7 +209,7 @@ // 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 + OctagonAPSReceiver* apsReceiver = [OctagonAPSReceiver receiverForEnvironment:self.apsEnvironment namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[FakeAPSConnection class]]; XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver"); @@ -237,6 +237,14 @@ [self.ckksZones addObject:pushTestZone]; self.zones[pushTestZone] = [[FakeCKZone alloc] initZone: pushTestZone]; + NSMutableSet* viewList = [self.mockSOSAdapter.selfPeer.viewList mutableCopy]; + [viewList addObject:@"PushTestZone"]; + CKKSSOSSelfPeer* newSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:self.mockSOSAdapter.selfPeer.peerID + encryptionKey:self.mockSOSAdapter.selfPeer.encryptionKey + signingKey:self.mockSOSAdapter.selfPeer.signingKey + viewList:viewList]; + self.mockSOSAdapter.selfPeer = newSelfPeer; + for(CKRecordZoneID* zoneID in self.ckksZones) { [self putFakeKeyHierarchyInCloudKit:zoneID]; [self saveTLKMaterialToKeychain:zoneID]; @@ -250,7 +258,7 @@ // 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 + OctagonAPSReceiver* apsReceiver = [OctagonAPSReceiver receiverForEnvironment:self.apsEnvironment namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[FakeAPSConnection class]]; XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver"); @@ -266,7 +274,8 @@ OCMExpect([self.mockContainerExpectations submitEventMetric:[OCMArg any]]); // Launch! - [self.injectedManager findOrCreateView:pushTestZone.zoneName]; + CKKSKeychainView* pushTestView = [self.injectedManager findOrCreateView:pushTestZone.zoneName]; + [self.ckksViews addObject:pushTestView]; [self startCKKSSubsystem]; @@ -276,6 +285,38 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } +- (int64_t)stalePushTimeoutShort +{ + return 10 * NSEC_PER_SEC; +} + +- (void)testDropStalePushes { + CKRecordZoneID* pushTestZone = [[CKRecordZoneID alloc] initWithZoneName:@"PushTestZone" ownerName:CKCurrentUserDefaultName]; + + id nearFutureSchduler = OCMClassMock([OctagonAPSReceiver class]); + OCMStub([nearFutureSchduler stalePushTimeout]).andCall(self, @selector(stalePushTimeoutShort)); + + APSIncomingMessage* apsMessage = [CKKSAPSHandlingTests messageWithTracingEnabledForZoneID:pushTestZone]; + + OctagonAPSReceiver* apsReceiver = [OctagonAPSReceiver receiverForEnvironment:self.apsEnvironment + namedDelegatePort:SecCKKSAPSNamedPort + apsConnectionClass:[FakeAPSConnection class]]; + XCTAssertNotNil(apsReceiver, "Should have gotten an APS receiver"); + + [apsReceiver connection:nil didReceiveIncomingMessage:apsMessage]; + + XCTAssertEqual(apsReceiver.haveStalePushes, YES, "should have stale pushes"); + + XCTestExpectation *expection = [self expectationWithDescription:@"no push"]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, [self stalePushTimeoutShort] + 2), dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ + XCTAssertEqual(apsReceiver.haveStalePushes, NO, "should have cleared out stale pushes"); + [expection fulfill]; + }); + + [self waitForExpectations: @[expection] timeout:([self stalePushTimeoutShort] * 4)/NSEC_PER_SEC]; +} + + @end #endif diff --git a/keychain/ckks/tests/CKKSCloudKitTests.m b/keychain/ckks/tests/CKKSCloudKitTests.m index 2702077a..e7586ea8 100644 --- a/keychain/ckks/tests/CKKSCloudKitTests.m +++ b/keychain/ckks/tests/CKKSCloudKitTests.m @@ -85,16 +85,20 @@ self.operationQueue = [NSOperationQueue new]; + CKKSCloudKitClassDependencies* cloudKitClassDependencies = [[CKKSCloudKitClassDependencies alloc] initWithFetchRecordZoneChangesOperationClass:[CKFetchRecordZoneChangesOperation class] + fetchRecordsOperationClass:[CKFetchRecordsOperation class] + queryOperationClass:[CKQueryOperation class] + modifySubscriptionsOperationClass:[CKModifySubscriptionsOperation class] + modifyRecordZonesOperationClass:[CKModifyRecordZonesOperation class] + apsConnectionClass:[APSConnection class] + nsnotificationCenterClass:[NSNotificationCenter class] + nsdistributednotificationCenterClass:[NSDistributedNotificationCenter class] + notifierClass:[FakeCKKSNotifier class]]; + CKKSViewManager* manager = [[CKKSViewManager alloc] initWithContainerName:containerName usePCS:SecCKKSContainerUsePCS - fetchRecordZoneChangesOperationClass:[CKFetchRecordZoneChangesOperation class] - fetchRecordsOperationClass:[CKFetchRecordsOperation class] - queryOperationClass:[CKQueryOperation class] - modifySubscriptionsOperationClass:[CKModifySubscriptionsOperation class] - modifyRecordZonesOperationClass:[CKModifyRecordZonesOperation class] - apsConnectionClass:[APSConnection class] - nsnotificationCenterClass:[NSNotificationCenter class] - notifierClass:[FakeCKKSNotifier class]]; + sosAdapter:nil + cloudKitClassDependencies:cloudKitClassDependencies]; [CKKSViewManager resetManager:false setTo:manager]; // Make a new fake keychain @@ -184,6 +188,7 @@ CKFetchRecordZoneChangesOperation *op = [[CKFetchRecordZoneChangesOperation alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}]; op.configuration.automaticallyRetryNetworkFailures = NO; op.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + op.configuration.isCloudKitSupportOperation = YES; op.configuration.container = self.container; __block NSMutableDictionary *data = [NSMutableDictionary new]; @@ -277,6 +282,7 @@ CKModifyRecordsOperation *op = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:records recordIDsToDelete:nil]; op.configuration.automaticallyRetryNetworkFailures = NO; op.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + op.configuration.isCloudKitSupportOperation = YES; 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 2c1fa981..8d0c019a 100644 --- a/keychain/ckks/tests/CKKSDeviceStateUploadTests.m +++ b/keychain/ckks/tests/CKKSDeviceStateUploadTests.m @@ -46,7 +46,7 @@ @implementation CloudKitKeychainSyncingDeviceStateUploadTests -- (void)testDeviceStateUploadGood { +- (void)testDeviceStateUploadGoodSOSOnly { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. [self startCKKSSubsystem]; @@ -69,7 +69,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertNil(record[SecCKRecordOctagonPeerID], "octagon peer ID should be missing"); @@ -115,7 +115,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertNil(record[SecCKRecordOctagonPeerID], "octagon peer ID should be missing"); @@ -190,6 +190,104 @@ [op waitUntilFinished]; } +- (void)testDeviceStateDoNotUploadIfNoDeviceID { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + + [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: @1} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record) { + return [record.recordType isEqualToString: SecCKRecordDeviceStateType]; + } + runAfterModification:nil]; + + CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [op waitUntilFinished]; + + // Device ID goes away + NSString* oldDeviceID = self.accountStateTracker.ckdeviceID; + self.accountStateTracker.ckdeviceID = nil; + + [self.keychainView dispatchSync:^bool { + NSError* error = nil; + CKKSDeviceStateEntry* cdse = [CKKSDeviceStateEntry fromDatabase:oldDeviceID zoneID:self.keychainZoneID error:&error]; + XCTAssertNil(error, "No error fetching device state entry"); + XCTAssertNotNil(cdse, "Fetched device state entry"); + + CKRecord* record = cdse.storedCKRecord; + + NSDate* m = record.modificationDate; + XCTAssertNotNil(m, "Have modification date"); + + return true; + }]; + + // It shouldn't try to upload a new CDSE; there's no device ID + op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + [op waitUntilFinished]; + + // And add a new keychain item, and expect it to sync, but without a device state + [self expectCKModifyRecords:@{SecCKRecordItemType: @1, + SecCKRecordCurrentKeyType: @1, + } + deletedRecordTypeCounts:@{} + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + return YES; + } + runAfterModification:nil]; + + [self addGenericPassword: @"data" account: @"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +// Note that CKKS shouldn't even be functioning in SA, but pretend that it is +- (void)testDeviceStateDoNotUploadIfSAAccount { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + + [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: @1} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record) { + return [record.recordType isEqualToString: SecCKRecordDeviceStateType]; + } + runAfterModification:nil]; + + CKKSUpdateDeviceStateOperation* op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [op waitUntilFinished]; + + // The account downgrades, I guess? + + self.fakeHSA2AccountStatus = CKKSAccountStatusNoAccount; + [self.accountStateTracker setHSA2iCloudAccountStatus:self.fakeHSA2AccountStatus]; + + // It shouldn't try to upload a new CDSE; the account is SA + op = [self.keychainView updateDeviceState:false waitForKeyHierarchyInitialization:2*NSEC_PER_SEC ckoperationGroup:nil]; + [op waitUntilFinished]; + + // And add a new keychain item, and expect it to sync, but without a device state + [self expectCKModifyRecords:@{SecCKRecordItemType: @1, + SecCKRecordCurrentKeyType: @1, + } + deletedRecordTypeCounts:@{} + zoneID:self.keychainZoneID + checkModifiedRecord: ^BOOL (CKRecord* record){ + return YES; + } + runAfterModification:nil]; + + [self addGenericPassword: @"data" account: @"account-delete-me"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + - (void)testDeviceStateUploadRateLimitedAfterNormalUpload { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -228,7 +326,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertNil(record[SecCKRecordOctagonPeerID], "octagon peer ID should be missing"); @@ -276,7 +374,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID should matche what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID should matche what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device should be in circle"); XCTAssertNil(record[SecCKRecordOctagonPeerID], "octagon peer ID should be missing"); @@ -451,7 +549,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device is in waitfortlk"); @@ -505,7 +603,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:threeDaysAgo toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to three days ago (%@)", record[SecCKSRecordLastUnlockTime], threeDaysAgo); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForUnlock), "Device is in waitforunlock"); @@ -535,6 +633,7 @@ // And restart CKKS... self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateWaitForTLK, "CKKS entered waitfortlk"); @@ -552,7 +651,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTLK), "Device is in waitfortlk"); @@ -573,16 +672,17 @@ - (void)testDeviceStateUploadBadCircleState { - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; // This test has stuff in CloudKit, but no TLKs. - [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + // It should NOT reset the CK zone. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + self.zones[self.keychainZoneID].flag = true; [self startCKKSSubsystem]; - 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"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "CKKS entered waitfortrust"); __weak __typeof(self) weakSelf = self; [self expectCKModifyRecords: @{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} @@ -600,7 +700,7 @@ XCTAssertNil(record[SecCKRecordCirclePeerID], "no peer ID if device is not in circle"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCNotInCircle], "device is not in circle"); - XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateLoggedOut), "Device is in keystate:loggedout"); + XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateWaitForTrust), "Device is in keystate:waitfortrust"); XCTAssertNil(record[SecCKRecordCurrentTLK] , "No TLK"); XCTAssertNil(record[SecCKRecordCurrentClassA], "No class A key"); @@ -617,6 +717,10 @@ [op waitUntilFinished]; XCTAssertNil(op.error, "No error uploading 'out of circle' device state"); + + FakeCKZone* keychainZone = self.zones[self.keychainZoneID]; + XCTAssertNotNil(keychainZone, "Should still have a keychain zone"); + XCTAssertTrue(keychainZone.flag, "keychain zone should not have been recreated"); } - (void)testDeviceStateUploadWithTardyNetworkAfterRestart { @@ -649,7 +753,7 @@ XCTAssertTrue([self.utcCalendar isDate:record[SecCKSRecordLastUnlockTime] equalToDate:[NSDate date] toUnitGranularity:NSCalendarUnitDay], "last unlock date (%@) similar to Now (%@)", record[SecCKSRecordLastUnlockTime], [NSDate date]); - XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.circlePeerID, "peer ID matches what we gave it"); + XCTAssertEqualObjects(record[SecCKRecordCirclePeerID], strongSelf.mockSOSAdapter.selfPeer.peerID, "peer ID matches what we gave it"); XCTAssertEqualObjects(record[SecCKRecordCircleStatus], [NSNumber numberWithInt:kSOSCCInCircle], "device is in circle"); XCTAssertEqualObjects(record[SecCKRecordKeyState], CKKSZoneKeyToNumber(SecCKKSZoneKeyStateReady), "Device is in ready"); diff --git a/keychain/ckks/tests/CKKSFetchTests.m b/keychain/ckks/tests/CKKSFetchTests.m new file mode 100644 index 00000000..2a7a1adf --- /dev/null +++ b/keychain/ckks/tests/CKKSFetchTests.m @@ -0,0 +1,194 @@ + +#if OCTAGON + +#import +#import +#import +#import + +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSKeychainView.h" + +#import "keychain/ckks/tests/MockCloudKit.h" + +@interface CloudKitKeychainFetchTests : CloudKitKeychainSyncingTestsBase +@end + +@implementation CloudKitKeychainFetchTests + +- (void)testMoreComing { + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + FakeCKZone* ckzone = self.zones[self.keychainZoneID]; + + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D00" withAccount:@"account0"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D01" withAccount:@"account1"]]; + CKServerChangeToken* ck1 = ckzone.currentChangeToken; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D02" withAccount:@"account2"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D03" withAccount:@"account3"]]; + + ckzone.limitFetchTo = ck1; + + self.silentFetchesAllowed = false; + [self expectCKFetch]; + [self expectCKFetchWithFilter:^BOOL(FakeCKFetchRecordZoneChangesOperation * _Nonnull frzco) { + // Assert that the fetch is happening with the change token we paused at before + CKServerChangeToken* changeToken = frzco.configurationsByRecordZoneID[self.keychainZoneID].previousServerChangeToken; + if(changeToken && [changeToken isEqual:ck1]) { + return YES; + } else { + return NO; + } + } runBeforeFinished:^{}]; + + // Trigger a notification (with hilariously fake data) + [self.keychainView notifyZoneChange:nil]; + + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + NSTimeInterval delta = [ckzone.fetchRecordZoneChangesTimestamps[2] timeIntervalSinceDate:ckzone.fetchRecordZoneChangesTimestamps[1]]; + XCTAssertLessThan(delta, 2, "operation 1 and 2 should be back-to-back"); + + [self findGenericPassword: @"account0" expecting:errSecSuccess]; + [self findGenericPassword: @"account1" expecting:errSecSuccess]; + [self findGenericPassword: @"account2" expecting:errSecSuccess]; + [self findGenericPassword: @"account3" expecting:errSecSuccess]; +} + +- (void)testMoreComingRepeated { + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + FakeCKZone* ckzone = self.zones[self.keychainZoneID]; + + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D00" withAccount:@"account0"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D01" withAccount:@"account1"]]; + CKServerChangeToken* ck1 = ckzone.currentChangeToken; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D02" withAccount:@"account2"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D03" withAccount:@"account3"]]; + CKServerChangeToken* ck2 = ckzone.currentChangeToken; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D04" withAccount:@"account4"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D05" withAccount:@"account5"]]; + + ckzone.limitFetchTo = ck1; + + self.silentFetchesAllowed = false; + // This fetch will return up to ck1. + [self expectCKFetchWithFilter:^BOOL(FakeCKFetchRecordZoneChangesOperation * _Nonnull frzco) { + return YES; + } runBeforeFinished:^{ + ckzone.limitFetchTo = ck2; + }]; + + // This fetch will return up to ck2. + [self expectCKFetchWithFilter:^BOOL(FakeCKFetchRecordZoneChangesOperation * _Nonnull frzco) { + // Assert that the fetch is happening with the change token we paused at before + CKServerChangeToken* changeToken = frzco.configurationsByRecordZoneID[self.keychainZoneID].previousServerChangeToken; + if(changeToken && [changeToken isEqual:ck1]) { + return YES; + } else { + return NO; + } + } runBeforeFinished:^{}]; + + // This fetch will return the final two items. + [self expectCKFetchWithFilter:^BOOL(FakeCKFetchRecordZoneChangesOperation * _Nonnull frzco) { + // Assert that the fetch is happening with the change token we paused at before + CKServerChangeToken* changeToken = frzco.configurationsByRecordZoneID[self.keychainZoneID].previousServerChangeToken; + if(changeToken && [changeToken isEqual:ck2]) { + return YES; + } else { + return NO; + } + } runBeforeFinished:^{}]; + + // Trigger a notification (with hilariously fake data) + [self.keychainView notifyZoneChange:nil]; + + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + NSTimeInterval delta = [ckzone.fetchRecordZoneChangesTimestamps[2] timeIntervalSinceDate:ckzone.fetchRecordZoneChangesTimestamps[1]]; + XCTAssertLessThan(delta, 2, "operation 1 and 2 should be back-to-back"); + + delta = [ckzone.fetchRecordZoneChangesTimestamps[3] timeIntervalSinceDate:ckzone.fetchRecordZoneChangesTimestamps[2]]; + XCTAssertLessThan(delta, 2, "operation 2 and 3 should be back-to-back"); + + [self findGenericPassword: @"account0" expecting:errSecSuccess]; + [self findGenericPassword: @"account1" expecting:errSecSuccess]; + [self findGenericPassword: @"account2" expecting:errSecSuccess]; + [self findGenericPassword: @"account3" expecting:errSecSuccess]; + [self findGenericPassword: @"account4" expecting:errSecSuccess]; + [self findGenericPassword: @"account5" expecting:errSecSuccess]; +} + +- (void)testMoreComingDespitePartialTimeout { + [self putFakeKeyHierarchyInCloudKit: self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + FakeCKZone* ckzone = self.zones[self.keychainZoneID]; + + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D00" withAccount:@"account0"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D01" withAccount:@"account1"]]; + CKServerChangeToken* ck1 = ckzone.currentChangeToken; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D02" withAccount:@"account2"]]; + [self.keychainZone addToZone: [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-0000-0000-0000-5A507ACB2D03" withAccount:@"account3"]]; + + // The fetch fails with partial results + ckzone.limitFetchTo = ck1; + ckzone.limitFetchError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkFailure userInfo:@{CKErrorRetryAfterKey : [NSNumber numberWithInt:4]}]; + + self.silentFetchesAllowed = false; + [self expectCKFetch]; + [self expectCKFetchWithFilter:^BOOL(FakeCKFetchRecordZoneChangesOperation * _Nonnull frzco) { + // Assert that the fetch is happening with the change token we paused at before + CKServerChangeToken* changeToken = frzco.configurationsByRecordZoneID[self.keychainZoneID].previousServerChangeToken; + if(changeToken && [changeToken isEqual:ck1]) { + return YES; + } else { + return NO; + } + } runBeforeFinished:^{}]; + + // Trigger a notification (with hilariously fake data) + [self.keychainView notifyZoneChange:nil]; + + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + [self findGenericPassword: @"account0" expecting:errSecSuccess]; + [self findGenericPassword: @"account1" expecting:errSecSuccess]; + [self findGenericPassword: @"account2" expecting:errSecSuccess]; + [self findGenericPassword: @"account3" expecting:errSecSuccess]; +} + +@end + +#endif // OCTAGON + diff --git a/keychain/ckks/tests/CKKSLoggerTests.m b/keychain/ckks/tests/CKKSLoggerTests.m index 610d8a68..692f1a05 100644 --- a/keychain/ckks/tests/CKKSLoggerTests.m +++ b/keychain/ckks/tests/CKKSLoggerTests.m @@ -158,6 +158,31 @@ static NSString* tablePath = nil; return [NSTemporaryDirectory() stringByAppendingPathComponent:@"test_ckks_analytics_v2.db"]; } +static void _XCTAssertTimeDiffWithInterval(CKKSAnalyticsTests* self, const char* filename, int line, NSDate* a, NSDate* b, int delta, NSString * _Nullable format, ...) NS_FORMAT_FUNCTION(7,8); + +/* + * Check if [a,b] are within expected time difference. + * The actual acceptable range is (-1.0, d.0] -- to deal with rounding errors when stored in SQLite. + */ + +#define XCTAssertTimeDiffWithInterval(a, b, delta, ...) \ + _XCTAssertTimeDiffWithInterval(self, __FILE__, __LINE__, a, b, delta, @"" __VA_ARGS__) + +static void _XCTAssertTimeDiffWithInterval(CKKSAnalyticsTests* self, const char* filename, int line, NSDate* a, NSDate* b, int delta, NSString * _Nullable format, ...) { + NSTimeInterval interval = [b timeIntervalSinceDate:a]; + if (interval <= -1.0 || interval > delta) { + NSString *comparison = [[NSString alloc] initWithFormat:@"time diff not expected (a=%@(%f), b=%@(%f), delta = %f) -- valid range (-1.0, %d.0]: ", a, [a timeIntervalSince1970], b, [b timeIntervalSince1970], interval, delta]; + NSString *arg = [[NSString alloc] init]; + if (format) { + va_list args; + va_start(args, format); + va_end(args); + arg = [[NSString alloc] initWithFormat: format arguments: args]; + } + [self recordFailureWithDescription: [comparison stringByAppendingString: arg] inFile: [NSString stringWithUTF8String: filename] atLine: line expected: YES]; + } +} + - (void)testLastSuccessfulXDate { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -171,41 +196,37 @@ static NSString* tablePath = nil; [[[self.keychainView waitForFetchAndIncomingQueueProcessing] completionHandlerDidRunCondition] wait:4 * NSEC_PER_SEC]; NSDate* nowDate = [NSDate date]; - NSTimeInterval timeInterval; /* * Check last sync date for class A */ NSDate* syncADate = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassA inView:self.keychainView]; XCTAssertNotNil(syncADate, "Failed to get a last successful A sync date"); - timeInterval = [nowDate timeIntervalSinceDate:syncADate]; - XCTAssertTrue(timeInterval >= 0.0 && timeInterval <= 15.0, "Last sync date does not look like a reasonable one"); + XCTAssertTimeDiffWithInterval(syncADate, nowDate, 15, "Last sync A date should be recent"); /* * Check last sync date for class C */ NSDate *syncCDate = [[CKKSAnalytics logger] dateOfLastSuccessForEvent:CKKSEventProcessIncomingQueueClassC inView:self.keychainView]; XCTAssertNotNil(syncCDate, "Failed to get a last successful C sync date"); - timeInterval = [nowDate timeIntervalSinceDate:syncCDate]; - XCTAssertTrue(timeInterval >= 0.0 && timeInterval <= 15.0, "Last sync date does not look like a reasonable one"); + XCTAssertTimeDiffWithInterval(syncCDate, nowDate, 15, "Last sync C date should be recent"); /* * Check last unlock date */ NSDate* unlockDate = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastUnlock]; XCTAssertNotNil(unlockDate, "Failed to get a last unlock date"); - timeInterval = [nowDate timeIntervalSinceDate:unlockDate]; - NSLog(@"timeinterval: %f\n", timeInterval); - XCTAssertTrue(timeInterval >= 0.0 && timeInterval <= 15.0, "Last unlock date does not look like a reasonable one"); + XCTAssertTimeDiffWithInterval(unlockDate, nowDate, 15, "Last unlock date should be recent"); - sleep(1); // wait to be a differnt second + sleep(2); // wait to be a different second (+/- 1s) self.aksLockState = true; [self.lockStateTracker recheck]; NSDate* newUnlockDate = [[CKKSAnalytics logger] datePropertyForKey:CKKSAnalyticsLastUnlock]; XCTAssertNotNil(newUnlockDate, "Failed to get a last unlock date"); - XCTAssertEqualObjects(newUnlockDate, unlockDate, "unlock date not the same"); + + XCTAssertTimeDiffWithInterval(newUnlockDate, unlockDate, 1, "unlock dates not the same (within one second)"); sleep(1); // wait to be a differnt second diff --git a/keychain/ckks/tests/CKKSMockOctagonAdapter.h b/keychain/ckks/tests/CKKSMockOctagonAdapter.h new file mode 100644 index 00000000..20861d17 --- /dev/null +++ b/keychain/ckks/tests/CKKSMockOctagonAdapter.h @@ -0,0 +1,44 @@ +// +// CKKSMockOctagonAdapter.h +// Security +// +// Created by Love Hörnquist Åstrand on 6/19/19. +// + +#import + +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSListenerCollection.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CKKSMockOctagonPeer : NSObject + +@property NSString* peerID; +@property (nullable) SFECPublicKey* publicEncryptionKey; +@property (nullable) SFECPublicKey* publicSigningKey; +@property (nullable) NSSet* viewList; + +- (instancetype)initWithOctagonPeerID:(NSString*)syncingPeerID + publicEncryptionKey:(SFECPublicKey* _Nullable)publicEncryptionKey + publicSigningKey:(SFECPublicKey* _Nullable)publicSigningKey + viewList:(NSSet* _Nullable)viewList; +@end + +@interface CKKSMockOctagonAdapter : NSObject +@property CKKSListenerCollection* peerChangeListeners; +@property OctagonSelfPeer* selfOTPeer; +@property (nullable) NSSet* selfViewList; + +@property NSMutableSet>* trustedPeers; +@property (readonly) NSString* providerID; + +- (instancetype)initWithSelfPeer:(OctagonSelfPeer*)selfPeer + trustedPeers:(NSSet>*)trustedPeers + essential:(BOOL)essential; + +@end + + +NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/tests/CKKSMockOctagonAdapter.m b/keychain/ckks/tests/CKKSMockOctagonAdapter.m new file mode 100644 index 00000000..89c511b2 --- /dev/null +++ b/keychain/ckks/tests/CKKSMockOctagonAdapter.m @@ -0,0 +1,133 @@ +/* + * 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 OCTAGON + +#import +#import +#import +#import + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSKey.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import "keychain/ot/OctagonCKKSPeerAdapter.h" + +#import "keychain/ckks/CKKSListenerCollection.h" +#import "keychain/ckks/tests/CKKSMockOctagonAdapter.h" + +@implementation CKKSMockOctagonPeer + +@synthesize publicSigningKey = _publicSigningKey; +@synthesize publicEncryptionKey = _publicEncryptionKey; + + +- (instancetype)initWithOctagonPeerID:(NSString*)syncingPeerID + publicEncryptionKey:(SFECPublicKey* _Nullable)publicEncryptionKey + publicSigningKey:(SFECPublicKey* _Nullable)publicSigningKey + viewList:(NSSet* _Nullable)viewList +{ + if((self = [super init])) { + _peerID = syncingPeerID; + _publicEncryptionKey = publicEncryptionKey; + _publicSigningKey = publicSigningKey; + _viewList = viewList; + } + return self; +} + +- (bool)matchesPeer:(nonnull id)peer { + NSString* otherPeerID = peer.peerID; + + if(self.peerID == nil && otherPeerID == nil) { + return true; + } + + return [self.peerID isEqualToString:otherPeerID]; +} + +- (BOOL)shouldHaveView:(nonnull NSString *)viewName { + return [self.viewList containsObject: viewName]; +} + +@end + + +@implementation CKKSMockOctagonAdapter +@synthesize essential = _essential; + +- (instancetype)initWithSelfPeer:(OctagonSelfPeer*)selfPeer + trustedPeers:(NSSet>*)trustedPeers + essential:(BOOL)essential +{ + if((self = [super init])) { + _essential = essential; + + _peerChangeListeners = [[CKKSListenerCollection alloc] initWithName:@"ckks-mock-sos"]; + + _selfOTPeer = selfPeer; + _trustedPeers = [trustedPeers mutableCopy]; + } + return self; +} + +- (NSString*)providerID +{ + return [NSString stringWithFormat:@"[CKKSMockOctagonAdapter: %@]", self.selfOTPeer.peerID]; +} + +- (CKKSSelves * _Nullable)fetchSelfPeers:(NSError * _Nullable __autoreleasing * _Nullable)error { + return [[CKKSSelves alloc] initWithCurrent:self.selfOTPeer allSelves:nil]; +} + +- (NSSet> * _Nullable)fetchTrustedPeers:(NSError * _Nullable __autoreleasing * _Nullable)error { + // include the self peer + CKKSMockOctagonPeer *s = [[CKKSMockOctagonPeer alloc] initWithOctagonPeerID:self.selfOTPeer.peerID + publicEncryptionKey:self.selfOTPeer.publicEncryptionKey + publicSigningKey:self.selfOTPeer.publicSigningKey + viewList:self.selfViewList]; + return [self.trustedPeers setByAddingObject: s]; +} + +- (void)registerForPeerChangeUpdates:(nonnull id)listener { + [self.peerChangeListeners registerListener:listener]; +} + +- (void)sendSelfPeerChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener selfPeerChanged:self]; + }]; +} + +- (void)sendTrustedPeerSetChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener trustedPeerSetChanged:self]; + }]; +} + +@end + +#endif diff --git a/keychain/ckks/tests/CKKSMockSOSPresentAdapter.h b/keychain/ckks/tests/CKKSMockSOSPresentAdapter.h new file mode 100644 index 00000000..85c47833 --- /dev/null +++ b/keychain/ckks/tests/CKKSMockSOSPresentAdapter.h @@ -0,0 +1,32 @@ + +#import +#if OCTAGON + +#import "keychain/ot/OTSOSAdapter.h" +#include "keychain/SecureObjectSync/SOSAccount.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface CKKSMockSOSPresentAdapter : NSObject + +// If you fill these in, the OTSOSAdapter methods will error with these errors. +@property (nullable) NSError* selfPeerError; +@property (nullable) NSError* trustedPeersError; + +@property bool excludeSelfPeerFromTrustSet; + +@property SOSCCStatus circleStatus; +@property CKKSSOSSelfPeer* selfPeer; +@property NSMutableSet>* trustedPeers; + +- (instancetype)initWithSelfPeer:(CKKSSOSSelfPeer*)selfPeer + trustedPeers:(NSSet>*)trustedPeers + essential:(BOOL)essential; + +- (NSSet>*)allPeers; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ckks/tests/CKKSMockSOSPresentAdapter.m b/keychain/ckks/tests/CKKSMockSOSPresentAdapter.m new file mode 100644 index 00000000..03491e76 --- /dev/null +++ b/keychain/ckks/tests/CKKSMockSOSPresentAdapter.m @@ -0,0 +1,135 @@ +#import "keychain/ckks/CKKSListenerCollection.h" +#import "keychain/ckks/tests/CKKSMockSOSPresentAdapter.h" + +@interface CKKSMockSOSPresentAdapter() +@property CKKSListenerCollection* peerChangeListeners; +@end + +@implementation CKKSMockSOSPresentAdapter +@synthesize essential = _essential; +@synthesize sosEnabled = _sosEnabled; + +- (instancetype)initWithSelfPeer:(CKKSSOSSelfPeer*)selfPeer + trustedPeers:(NSSet*)trustedPeers + essential:(BOOL)essential +{ + if((self = [super init])) { + _sosEnabled = true; + _essential = essential; + + _circleStatus = kSOSCCInCircle; + + _excludeSelfPeerFromTrustSet = false; + + _peerChangeListeners = [[CKKSListenerCollection alloc] initWithName:@"ckks-mock-sos"]; + + _selfPeer = selfPeer; + _trustedPeers = [trustedPeers mutableCopy]; + } + return self; +} + +- (NSString*)providerID +{ + return [NSString stringWithFormat:@"[CKKSMockSOSPresentAdapter: %@]", self.selfPeer.peerID]; +} + +- (SOSCCStatus)circleStatus:(NSError * _Nullable __autoreleasing * _Nullable)error +{ + if(!self.sosEnabled || self.circleStatus == kSOSCCError) { + if(error && self.circleStatus == kSOSCCError) { + *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:self.circleStatus userInfo:nil]; + } + return kSOSCCError; + } + + return self.circleStatus; +} + +// I currently don't understand when SOS returns a self or not. I've seen it return a self while not in kSOSCCInCircle, +// which seems wrong. So, always return a self, unless we're in an obvious error state. +- (id _Nullable)currentSOSSelf:(NSError * _Nullable __autoreleasing * _Nullable)error +{ + if(self.selfPeerError) { + if(error) { + *error = self.selfPeerError; + } + return nil; + } + + if(self.sosEnabled && self.circleStatus == kSOSCCInCircle) { + return self.selfPeer; + } else { + if(error) { + *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:self.circleStatus userInfo:nil]; + } + return nil; + } +} + +- (CKKSSelves * _Nullable)fetchSelfPeers:(NSError *__autoreleasing _Nullable * _Nullable)error +{ + id peer = [self currentSOSSelf:error]; + if(!peer) { + return nil; + } + + return [[CKKSSelves alloc] initWithCurrent:peer allSelves:nil]; +} + +- (NSSet> * _Nullable)fetchTrustedPeers:(NSError * _Nullable __autoreleasing * _Nullable)error +{ + if(self.trustedPeersError) { + if(*error) { + *error = self.trustedPeersError; + } + return nil; + } + + // TODO: I'm actually not entirely sure what SOS does if it's not in circle? + if(self.sosEnabled && self.circleStatus == kSOSCCInCircle) { + if(self.excludeSelfPeerFromTrustSet) { + return self.trustedPeers; + } else { + return [self allPeers]; + } + } else { + if(error) { + *error = [NSError errorWithDomain:(__bridge NSString*)kSOSErrorDomain code:kSOSCCNotInCircle userInfo:nil]; + } + return nil; + } +} + +- (void)updateOctagonKeySetWithAccount:(nonnull id)currentSelfPeer error:(NSError *__autoreleasing _Nullable * _Nullable)error { + return; +} + +- (void)registerForPeerChangeUpdates:(nonnull id)listener { + [self.peerChangeListeners registerListener:listener]; +} + +- (void)sendSelfPeerChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener selfPeerChanged:self]; + }]; +} + +- (void)sendTrustedPeerSetChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener trustedPeerSetChanged:self]; + }]; +} + +- (NSSet>*)allPeers +{ + // include the self peer, but as a CKKSSOSPeer object instead of a self peer + CKKSSOSPeer* s = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.selfPeer.peerID + encryptionPublicKey:self.selfPeer.publicEncryptionKey + signingPublicKey:self.selfPeer.publicSigningKey + viewList:self.selfPeer.viewList]; + + return [self.trustedPeers setByAddingObject: s]; +} + +@end diff --git a/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m b/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m index a0df21e4..b5ae45f4 100644 --- a/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m +++ b/keychain/ckks/tests/CKKSNearFutureSchedulerTests.m @@ -497,6 +497,75 @@ [self waitForExpectations: @[second] timeout:0.4]; } +- (void)testTriggerAtFromNoTimer { + XCTestExpectation *first = [self expectationWithDescription:@"FutureScheduler fired (one)"]; + first.inverted = YES; + + XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"]; + second.assertForOverFulfill = YES; + + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"test" + delay:1*NSEC_PER_MSEC + keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + [first fulfill]; + [second fulfill]; + }]; + + [scheduler triggerAt:300*NSEC_PER_MSEC]; + [self waitForExpectations: @[first] timeout:0.1]; + [self waitForExpectations: @[second] timeout:2]; +} + +- (void)testTriggerAtShortensTriggerDelay { + XCTestExpectation *first = [self expectationWithDescription:@"FutureScheduler fired (one)"]; + first.inverted = YES; + + XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"]; + second.assertForOverFulfill = YES; + + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"test" + delay:10*NSEC_PER_SEC + keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + [first fulfill]; + [second fulfill]; + }]; + + // Triggers a 10 second invocation, then invoke a triggerAt + [scheduler trigger]; + [scheduler triggerAt:300*NSEC_PER_MSEC]; + + [self waitForExpectations: @[first] timeout:0.1]; + [self waitForExpectations: @[second] timeout:2]; +} + +- (void)testTriggerAtLengthensTriggerDelay { + XCTestExpectation *first = [self expectationWithDescription:@"FutureScheduler fired (one)"]; + first.inverted = YES; + + XCTestExpectation *second = [self expectationWithDescription:@"FutureScheduler fired (two)"]; + second.assertForOverFulfill = YES; + + CKKSNearFutureScheduler* scheduler = [[CKKSNearFutureScheduler alloc] initWithName:@"test" + delay:400*NSEC_PER_MSEC + keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + [first fulfill]; + [second fulfill]; + }]; + + // Triggers a 400 millisecond invocation, then invoke a triggerAt + [scheduler trigger]; + [scheduler triggerAt:1*NSEC_PER_SEC]; + + [self waitForExpectations: @[first] timeout:0.5]; + [self waitForExpectations: @[second] timeout:2]; +} + @end #endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSOperationTests.m b/keychain/ckks/tests/CKKSOperationTests.m index fd460dc5..913a7901 100644 --- a/keychain/ckks/tests/CKKSOperationTests.m +++ b/keychain/ckks/tests/CKKSOperationTests.m @@ -304,7 +304,8 @@ [self.queue addOperation:operation]; [self.queue waitUntilAllOperationsAreFinished]; - sleep(0.1); // wait for the completion block to have time to fire + + XCTAssertEqual([operation.completionHandlerDidRunCondition wait:4 * NSEC_PER_SEC], 0, "Completion block should fire in a reasonable amount of time"); XCTAssertNotNil(operation.finishDate, "Result operation has a finish date after everything is done"); NSTimeInterval timeIntervalSinceFinishDate = [[NSDate date] timeIntervalSinceDate:operation.finishDate]; XCTAssertTrue(timeIntervalSinceFinishDate >= 0.0 && timeIntervalSinceFinishDate <= 10.0, "Result operation finish datelooks reasonable"); diff --git a/keychain/ckks/tests/CKKSRateLimiterTests.m b/keychain/ckks/tests/CKKSRateLimiterTests.m index e0472a47..46f13ec6 100644 --- a/keychain/ckks/tests/CKKSRateLimiterTests.m +++ b/keychain/ckks/tests/CKKSRateLimiterTests.m @@ -64,7 +64,7 @@ self.oqe = nil; } -- (int) get:(NSDictionary *)dict key:(NSString *)key { +- (int)get:(NSDictionary *)dict key:(NSString *)key { id obj = dict[key]; XCTAssertNotNil(obj, "Key %@ is in the dictionary", key); XCTAssert([obj isKindOfClass:[NSNumber class]], "Value for %@ is an NSNumber (%@)", key, [obj class]); @@ -72,7 +72,15 @@ return [obj intValue]; } -- (void) testConfig { +- (unsigned)getUnsigned:(NSDictionary *)dict key:(NSString *)key { + id obj = dict[key]; + XCTAssertNotNil(obj, "Key %@ is in the dictionary", key); + XCTAssert([obj isKindOfClass:[NSNumber class]], "Value for %@ is an NSNumber (%@)", key, [obj class]); + XCTAssertGreaterThan([obj unsignedIntValue], 0, "Value for %@ is at least non-zero", key); + return [obj unsignedIntValue]; +} + +- (void)testConfig { [self get:[self.rl config] key:@"rateAll"]; [self get:[self.rl config] key:@"rateGroup"]; [self get:[self.rl config] key:@"rateUUID"]; @@ -83,7 +91,7 @@ [self get:[self.rl config] key:@"trimTime"]; } -- (void) testBasics { +- (void)testBasics { NSDate *date = [NSDate date]; NSDate *limit = nil; @@ -242,7 +250,7 @@ NSDate *limit = nil; int trimSize = [self get:[self.rl config] key:@"trimSize"]; //int rateAll = [self get:[self.rl config] key:@"rateAll"];; - int overloadDuration = [self get:[self.rl config] key:@"overloadDuration"];; + unsigned overloadDuration = [self getUnsigned:[self.rl config] key:@"overloadDuration"];; for (int idx = 0; idx < (trimSize / 2); ++idx) { self.oqe.accessgroup = [NSString stringWithFormat:@"%d", idx]; diff --git a/keychain/ckks/tests/CKKSSOSTests.m b/keychain/ckks/tests/CKKSSOSTests.m index 664d69de..7ac4dbac 100644 --- a/keychain/ckks/tests/CKKSSOSTests.m +++ b/keychain/ckks/tests/CKKSSOSTests.m @@ -32,6 +32,8 @@ #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" +#import "keychain/ckks/tests/CKKSTests+MultiZone.h" + #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSKeychainView.h" #import "keychain/ckks/CKKSCurrentKeyPointer.h" @@ -49,407 +51,20 @@ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" #include -#include -#include -#include -#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" #pragma clang diagnostic pop #include #include #pragma clang diagnostic pop -@interface CloudKitKeychainSyncingSOSIntegrationTests : CloudKitKeychainSyncingMockXCTest - -@property CKRecordZoneID* engramZoneID; -@property CKKSKeychainView* engramView; -@property FakeCKZone* engramZone; -@property (readonly) ZoneKeys* engramZoneKeys; - -@property CKRecordZoneID* manateeZoneID; -@property CKKSKeychainView* manateeView; -@property FakeCKZone* manateeZone; -@property (readonly) ZoneKeys* manateeZoneKeys; - -@property CKRecordZoneID* autoUnlockZoneID; -@property CKKSKeychainView* autoUnlockView; -@property FakeCKZone* autoUnlockZone; -@property (readonly) ZoneKeys* autoUnlockZoneKeys; - -@property CKRecordZoneID* healthZoneID; -@property CKKSKeychainView* healthView; -@property FakeCKZone* healthZone; -@property (readonly) ZoneKeys* healthZoneKeys; - -@property CKRecordZoneID* applepayZoneID; -@property CKKSKeychainView* applepayView; -@property FakeCKZone* applepayZone; -@property (readonly) ZoneKeys* applepayZoneKeys; - -@property CKRecordZoneID* homeZoneID; -@property CKKSKeychainView* homeView; -@property FakeCKZone* homeZone; -@property (readonly) ZoneKeys* homeZoneKeys; - -@property CKRecordZoneID* limitedZoneID; -@property CKKSKeychainView* limitedView; -@property FakeCKZone* limitedZone; -@property (readonly) ZoneKeys* limitedZoneKeys; - +@interface CloudKitKeychainSyncingSOSIntegrationTests : CloudKitKeychainSyncingMultiZoneTestsBase @end @implementation CloudKitKeychainSyncingSOSIntegrationTests -+ (void)setUp { - SecCKKSEnable(); - SecCKKSResetSyncing(); - [super setUp]; -} - -- (void)setUp { - // No manifests. - (void)[CKKSManifest shouldSyncManifests]; // initialize. - SecCKKSSetSyncManifests(false); - SecCKKSSetEnforceManifests(false); - - [super setUp]; - SecCKKSTestSetDisableSOS(false); - - // Wait for the ViewManager to be brought up - 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]; - - self.manateeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Manatee" ownerName:CKCurrentUserDefaultName]; - 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]; - - self.autoUnlockZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"AutoUnlock" ownerName:CKCurrentUserDefaultName]; - 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]; - - self.healthZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Health" ownerName:CKCurrentUserDefaultName]; - 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]; - - self.applepayZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"ApplePay" ownerName:CKCurrentUserDefaultName]; - 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.homeZoneID]; - self.zones[self.homeZoneID] = self.homeZone; - self.homeView = [[CKKSViewManager manager] findView:@"Home"]; - XCTAssertNotNil(self.homeView, "CKKSViewManager created the Home view"); - [self.ckksZones addObject:self.homeZoneID]; - - self.limitedZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"LimitedPeersAllowed" ownerName:CKCurrentUserDefaultName]; - self.limitedZone = [[FakeCKZone alloc] initZone: self.limitedZoneID]; - self.zones[self.limitedZoneID] = self.limitedZone; - self.limitedView = [[CKKSViewManager manager] findView:@"LimitedPeersAllowed"]; - XCTAssertNotNil(self.limitedView, "CKKSViewManager created the LimitedPeersAllowed view"); - [self.ckksZones addObject:self.limitedZoneID]; -} - -+ (void)tearDown { - SecCKKSTestSetDisableSOS(true); - [super tearDown]; - SecCKKSResetSyncing(); -} - -- (void)tearDown { - // If the test didn't already do this, allow each zone to spin up - self.accountStatus = CKAccountStatusNoAccount; - [self startCKKSSubsystem]; - - [self.engramView halt]; - [self.engramView waitUntilAllOperationsAreFinished]; - self.engramView = nil; - - [self.manateeView halt]; - [self.manateeView waitUntilAllOperationsAreFinished]; - self.manateeView = nil; - - [self.autoUnlockView halt]; - [self.autoUnlockView waitUntilAllOperationsAreFinished]; - self.autoUnlockView = nil; - - [self.healthView halt]; - [self.healthView waitUntilAllOperationsAreFinished]; - self.healthView = nil; - - [self.applepayView halt]; - [self.applepayView waitUntilAllOperationsAreFinished]; - self.applepayView = nil; - - [self.homeView halt]; - [self.homeView waitUntilAllOperationsAreFinished]; - self.homeView = nil; - - [super tearDown]; -} - -- (ZoneKeys*)engramZoneKeys { - return self.keys[self.engramZoneID]; -} - -- (ZoneKeys*)manateeZoneKeys { - return self.keys[self.manateeZoneID]; -} - --(void)saveFakeKeyHierarchiesToLocalDatabase { - for(CKRecordZoneID* zoneID in self.ckksZones) { - [self createAndSaveFakeKeyHierarchy: zoneID]; - } -} - --(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. - - [self startCKKSSubsystem]; - - XCTestExpectation* engramChanged = [self expectChangeForView:self.engramZoneID.zoneName]; - XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; - XCTestExpectation* manateeChanged = [self expectChangeForView:self.manateeZoneID.zoneName]; - - // We expect a single record to be uploaded to the engram view. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.engramZoneID]; - [self addGenericPassword: @"data" account: @"account-delete-me-engram" viewHint:(NSString*) kSecAttrViewHintEngram]; - - OCMVerifyAllWithDelay(self.mockDatabase, 20); - [self waitForExpectations:@[engramChanged] timeout:1]; - [self waitForExpectations:@[pcsChanged] timeout:1]; - - pcsChanged = [self expectChangeForView:@"PCS"]; - - // We expect a single record to be uploaded to the manatee view. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID]; - [self addGenericPassword: @"data" account: @"account-delete-me-manatee" viewHint:(NSString*) kSecAttrViewHintManatee]; - - OCMVerifyAllWithDelay(self.mockDatabase, 20); - [self waitForExpectations:@[manateeChanged] timeout:1]; - [self waitForExpectations:@[pcsChanged] timeout:1]; -} - --(void)testAddAutoUnlockItems { - [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. - - [self startCKKSSubsystem]; - - XCTestExpectation* autoUnlockChanged = [self expectChangeForView:self.autoUnlockZoneID.zoneName]; - // AutoUnlock is NOT is PCS view, so it should not send the fake 'PCS' view notification - XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; - pcsChanged.inverted = YES; - - // We expect a single record to be uploaded to the AutoUnlock view. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.autoUnlockZoneID]; - [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintAutoUnlock]; - - OCMVerifyAllWithDelay(self.mockDatabase, 20); - [self waitForExpectations:@[autoUnlockChanged] timeout:1]; - [self waitForExpectations:@[pcsChanged] timeout:0.2]; -} - --(void)testAddHealthItems { - [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. - - [self startCKKSSubsystem]; - - XCTestExpectation* healthChanged = [self expectChangeForView:self.healthZoneID.zoneName]; - // Health is NOT is PCS view, so it should not send the fake 'PCS' view notification - XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; - pcsChanged.inverted = YES; - - // We expect a single record to be uploaded to the Health view. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.healthZoneID]; - [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintHealth]; - - OCMVerifyAllWithDelay(self.mockDatabase, 20); - [self waitForExpectations:@[healthChanged] timeout:1]; - [self waitForExpectations:@[pcsChanged] timeout:0.2]; -} - --(void)testAddApplePayItems { - [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. - - [self startCKKSSubsystem]; - - XCTestExpectation* applepayChanged = [self expectChangeForView:self.applepayZoneID.zoneName]; - XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; - - - // We expect a single record to be uploaded to the ApplePay view. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.applepayZoneID]; - [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintApplePay]; - - 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)testAddLimitedPeersAllowedItems { - [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. - - [self startCKKSSubsystem]; - - XCTestExpectation* limitedChanged = [self expectChangeForView:self.limitedZoneID.zoneName]; - // LimitedPeersAllowed is a PCS view, so it should send the fake 'PCS' view notification - XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; - - // We expect a single record to be uploaded to the LimitedPeersOkay view. - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.limitedZoneID]; - [self addGenericPassword: @"data" account: @"account-delete-me-limited-peers" viewHint:(NSString*) kSecAttrViewHintLimitedPeersAllowed]; - - OCMVerifyAllWithDelay(self.mockDatabase, 20); - [self waitForExpectations:@[limitedChanged] timeout:1]; - [self waitForExpectations:@[pcsChanged] timeout:0.2]; - - [self waitForKeyHierarchyReadinesses]; - - // Let's also test that an item added by a future peer (lacking the right viewhint) doesn't sync - NSMutableDictionary* item = [[self fakeRecordDictionary:@"asdf" zoneID:self.limitedZoneID] mutableCopy]; - item[(id)kSecAttrSyncViewHint] = @"new-view"; - - CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:@"37E6CA21-A586-44E1-9A1C-3EE464C78EB5" zoneID:self.limitedZoneID]; - CKRecord* ckr = [self newRecord:ckrid withNewItemData:item]; - [self.limitedZone addToZone:ckr]; - ckr = [self createFakeRecord:self.limitedZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2AAA" withAccount:@"asdf-exist"]; - [self.limitedZone addToZone:ckr]; - - [self.limitedView notifyZoneChange:nil]; - [self.limitedView waitForFetchAndIncomingQueueProcessing]; - - [self findGenericPassword:@"asdf-exist" expecting:errSecSuccess]; - [self findGenericPassword:@"asdf" expecting:errSecItemNotFound]; - - NSError *error = NULL; - XCTAssertEqual([CKKSIncomingQueueEntry countByState:SecCKKSStateZoneMismatch zone:self.limitedZoneID error:&error], - 1, - "Expected a ZoneMismatch entry in incoming queue: %@", error); - XCTAssertNil(error, "Should be no error fetching incoming queue entries"); -} - --(void)testAddOtherViewHintItem { - [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. - - [self startCKKSSubsystem]; - - // We expect no uploads to CKKS. - [self addGenericPassword: @"data" account: @"account-delete-me-no-viewhint"]; - [self addGenericPassword: @"data" account: @"account-delete-me-password" viewHint:(NSString*) kSOSViewAutofillPasswords]; - - sleep(1); - OCMVerifyAllWithDelay(self.mockDatabase, 20); -} - -- (void)testReceiveItemInView { - [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. - [self startCKKSSubsystem]; - - for(CKRecordZoneID* zoneID in self.ckksZones) { - [self expectCKKSTLKSelfShareUpload:zoneID]; - } - - [self waitForKeyHierarchyReadinesses]; - - [self findGenericPassword:@"account-delete-me" expecting:errSecItemNotFound]; - - CKRecord* ckr = [self createFakeRecord:self.engramZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85"]; - [self.engramZone addToZone: ckr]; - - XCTestExpectation* engramChanged = [self expectChangeForView:self.engramZoneID.zoneName]; - XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; - - // Trigger a notification (with hilariously fake data) - [self.engramView notifyZoneChange:nil]; - - [self.engramView waitForFetchAndIncomingQueueProcessing]; - [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; - - [self waitForExpectations:@[engramChanged] timeout:1]; - [self waitForExpectations:@[pcsChanged] timeout:1]; -} - (void)testFindManateePiggyTLKs { [self saveFakeKeyHierarchyToLocalDatabase:self.manateeZoneID]; @@ -652,7 +267,7 @@ // Ensure that the manatee syncable TLK is created from a piggy NSDictionary* query = @{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrDescription: SecCKKSKeyClassTLK, (id)kSecAttrAccount: strongSelf.manateeZoneKeys.tlk.uuid, @@ -670,54 +285,6 @@ }]; } -- (void)putFakeDeviceStatusesInCloudKit { - [self putFakeDeviceStatusInCloudKit: self.engramZoneID]; - [self putFakeDeviceStatusInCloudKit: self.manateeZoneID]; - [self putFakeDeviceStatusInCloudKit: self.autoUnlockZoneID]; - [self putFakeDeviceStatusInCloudKit: self.healthZoneID]; - [self putFakeDeviceStatusInCloudKit: self.applepayZoneID]; - [self putFakeDeviceStatusInCloudKit: self.homeZoneID]; - [self putFakeDeviceStatusInCloudKit: self.limitedZoneID]; -} - --(void)putFakeKeyHierachiesInCloudKit{ - [self putFakeKeyHierarchyInCloudKit: self.engramZoneID]; - [self putFakeKeyHierarchyInCloudKit: self.manateeZoneID]; - [self putFakeKeyHierarchyInCloudKit: self.autoUnlockZoneID]; - [self putFakeKeyHierarchyInCloudKit: self.healthZoneID]; - [self putFakeKeyHierarchyInCloudKit: self.applepayZoneID]; - [self putFakeKeyHierarchyInCloudKit: self.homeZoneID]; - [self putFakeKeyHierarchyInCloudKit: self.limitedZoneID]; -} --(void)saveTLKsToKeychain{ - [self saveTLKMaterialToKeychain:self.engramZoneID]; - [self saveTLKMaterialToKeychain:self.manateeZoneID]; - [self saveTLKMaterialToKeychain:self.autoUnlockZoneID]; - [self saveTLKMaterialToKeychain:self.healthZoneID]; - [self saveTLKMaterialToKeychain:self.applepayZoneID]; - [self saveTLKMaterialToKeychain:self.homeZoneID]; - [self saveTLKMaterialToKeychain:self.limitedZoneID]; -} --(void)deleteTLKMaterialsFromKeychain{ - [self deleteTLKMaterialFromKeychain: self.engramZoneID]; - [self deleteTLKMaterialFromKeychain: self.manateeZoneID]; - [self deleteTLKMaterialFromKeychain: self.autoUnlockZoneID]; - [self deleteTLKMaterialFromKeychain: self.healthZoneID]; - [self deleteTLKMaterialFromKeychain: self.applepayZoneID]; - [self deleteTLKMaterialFromKeychain: self.homeZoneID]; - [self deleteTLKMaterialFromKeychain:self.limitedZoneID]; -} - --(void)waitForKeyHierarchyReadinesses { - [self.manateeView waitForKeyHierarchyReadiness]; - [self.engramView waitForKeyHierarchyReadiness]; - [self.autoUnlockView waitForKeyHierarchyReadiness]; - [self.healthView waitForKeyHierarchyReadiness]; - [self.applepayView waitForKeyHierarchyReadiness]; - [self.homeView waitForKeyHierarchyReadiness]; - [self.limitedView waitForKeyHierarchyReadiness]; -} - -(void)testAcceptExistingAndUsePiggyKeyHierarchy { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierachiesInCloudKit]; diff --git a/keychain/ckks/tests/CKKSSQLTests.m b/keychain/ckks/tests/CKKSSQLTests.m index 71d6acc3..76db6ebd 100644 --- a/keychain/ckks/tests/CKKSSQLTests.m +++ b/keychain/ckks/tests/CKKSSQLTests.m @@ -398,7 +398,7 @@ XCTAssertNil(error, "no error saving TLK to database"); CKKSKey* wrappedKey = [[CKKSKey alloc] initWrappedBy: tlk - AESKey:[CKKSAESSIVKey randomKey] + AESKey:[CKKSAESSIVKey randomKey:&error] uuid:@"157A3171-0677-451B-9EAE-0DDC4D4315B0" keyclass:SecCKKSKeyClassC state: SecCKKSProcessedStateLocal @@ -440,8 +440,8 @@ groupBy: @[@"action"] orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[row[@"action"]] = row[@"count(rowid)"]; + processRow: ^(NSDictionary* row) { + results[row[@"action"].asString] = row[@"count(rowid)"].asString; } error: &error]; @@ -460,8 +460,8 @@ groupBy: @[@"action"] orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[row[@"action"]] = row[@"count(rowid)"]; + processRow: ^(NSDictionary* row) { + results[row[@"action"].asString] = row[@"count(rowid)"].asString; } error: &error]; @@ -477,7 +477,7 @@ [self addTestZoneEntries]; NSError* error = nil; - __block NSMutableArray* rows = [[NSMutableArray alloc] init]; + __block NSMutableArray*>* rows = [[NSMutableArray alloc] init]; [CKKSSQLDatabaseObject queryDatabaseTable: [CKKSOutgoingQueueEntry sqlTable] where: nil @@ -485,7 +485,7 @@ groupBy:nil orderBy:@[@"uuid"] limit:-1 - processRow: ^(NSDictionary* row) { + processRow:^(NSDictionary* row) { [rows addObject:row]; } error: &error]; @@ -493,8 +493,8 @@ XCTAssertNil(error, "no error doing order by query"); XCTAssertEqual(rows.count, 3u, "got three items"); - XCTAssertEqual([rows[0][@"uuid"] compare: rows[1][@"uuid"]], NSOrderedAscending, "first order is fine"); - XCTAssertEqual([rows[1][@"uuid"] compare: rows[2][@"uuid"]], NSOrderedAscending, "second order is fine"); + XCTAssertEqual([rows[0][@"uuid"].asString compare: rows[1][@"uuid"].asString], NSOrderedAscending, "first order is fine"); + XCTAssertEqual([rows[1][@"uuid"].asString compare: rows[2][@"uuid"].asString], NSOrderedAscending, "second order is fine"); // Check that order-by + limit works to page __block NSString* lastUUID = nil; @@ -509,9 +509,9 @@ groupBy:nil orderBy:@[@"uuid"] limit:1 - processRow: ^(NSDictionary* row) { + processRow: ^(NSDictionary* row) { XCTAssertNil(uuid, "Only one row returned"); - uuid = row[@"UUID"]; + uuid = row[@"UUID"].asString; } error: &error]; XCTAssertNil(error, "No error doing SQL"); @@ -536,8 +536,8 @@ groupBy: nil orderBy:nil limit: -1 - processRow: ^(NSDictionary* row) { - results[row[@"uuid"]] = row[@"action"]; + processRow: ^(NSDictionary* row) { + results[row[@"uuid"].asString] = row[@"action"].asString; } error: &error]; @@ -551,8 +551,8 @@ groupBy: nil orderBy:nil limit: 1 - processRow: ^(NSDictionary* row) { - results[row[@"uuid"]] = row[@"action"]; + processRow: ^(NSDictionary* row) { + results[row[@"uuid"].asString] = row[@"action"].asString; } error: &error]; @@ -568,8 +568,8 @@ groupBy: nil orderBy:nil limit: 3 - processRow: ^(NSDictionary* row) { - results[row[@"uuid"]] = row[@"action"]; + processRow: ^(NSDictionary* row) { + results[row[@"uuid"].asString] = row[@"action"].asString; } error: &error]; @@ -584,8 +584,8 @@ groupBy: nil orderBy:nil limit: 1 - processRow: ^(NSDictionary* row) { - results[row[@"uuid"]] = row[@"action"]; + processRow: ^(NSDictionary* row) { + results[row[@"uuid"].asString] = row[@"action"].asString; } error: &error]; @@ -594,6 +594,16 @@ results = [[NSMutableDictionary alloc] init]; } +- (void)testQuoting { + XCTAssertEqualObjects([CKKSSQLDatabaseObject quotedString:@"hej"], @"hej", "no quote"); + XCTAssertEqualObjects([CKKSSQLDatabaseObject quotedString:@"hej'"], @"hej''", "single quote"); + XCTAssertEqualObjects([CKKSSQLDatabaseObject quotedString:@"'hej'"], @"''hej''", "two single quote"); + XCTAssertEqualObjects([CKKSSQLDatabaseObject quotedString:@"hej\""], @"hej\"", "double quote"); + XCTAssertEqualObjects([CKKSSQLDatabaseObject quotedString:@"\"hej\""], @"\"hej\"", "double quote"); + XCTAssertEqualObjects([CKKSSQLDatabaseObject quotedString:@"'\"hej\""], @"''\"hej\"", "double quote"); +} + + @end #endif diff --git a/keychain/ckks/tests/CKKSTLKSharingEncryptionTests.m b/keychain/ckks/tests/CKKSTLKSharingEncryptionTests.m index 665b5e04..67b08ac5 100644 --- a/keychain/ckks/tests/CKKSTLKSharingEncryptionTests.m +++ b/keychain/ckks/tests/CKKSTLKSharingEncryptionTests.m @@ -26,7 +26,7 @@ #import #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSKey.h" -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" #import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/tests/CloudKitMockXCTest.h" @@ -54,17 +54,20 @@ self.localPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"local" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; XCTAssertNotNil(self.localPeer, "Should be able to make a new local peer"); self.remotePeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; XCTAssertNotNil(self.remotePeer, "Should be able to make a new remote peer"); self.remotePeer2 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; XCTAssertNotNil(self.remotePeer2, "Should be able to make a new remote peer"); [super setUp]; @@ -76,7 +79,7 @@ - (void)testKeyWrapAndUnwrap { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -93,7 +96,7 @@ - (void)testTLKShareSignAndVerify { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -110,7 +113,7 @@ - (void)testTLKShareSignAndFailVerify { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -122,26 +125,26 @@ XCTAssertNil(error, "Should have been no error signing a CKKSTLKShare"); XCTAssertNotNil(signature, "Should have received a signature blob"); - CKKSTLKShare* shareEpoch = [share copy]; + CKKSTLKShareRecord* shareEpoch = [share copy]; XCTAssertTrue([shareEpoch verifySignature:signature verifyingPeer:self.localPeer error:&error], "Signature should verify using the local peer's signing key"); error = nil; - shareEpoch.epoch = 1; + shareEpoch.share.epoch = 1; XCTAssertFalse([shareEpoch verifySignature:signature verifyingPeer:self.localPeer error:&error], "After epoch change, signature should no longer verify"); XCTAssertNotNil(error, "Signature verification after epoch change should have produced an error"); error = nil; - CKKSTLKShare* sharePoisoned = [share copy]; + CKKSTLKShareRecord* sharePoisoned = [share copy]; XCTAssertTrue([sharePoisoned verifySignature:signature verifyingPeer:self.localPeer error:&error], "Signature should verify using the local peer's signing key"); error = nil; - sharePoisoned.poisoned = 1; + sharePoisoned.share.poisoned = 1; XCTAssertFalse([sharePoisoned verifySignature:signature verifyingPeer:self.localPeer error:&error], "After poison change, signature should no longer verify"); XCTAssertNotNil(error, "Signature verification after poison change should have produced an error"); error = nil; - CKKSTLKShare* shareData = [share copy]; + CKKSTLKShareRecord* shareData = [share copy]; XCTAssertTrue([shareData verifySignature:signature verifyingPeer:self.localPeer error:&error], "Signature should verify using the local peer's signing key"); error = nil; - shareData.wrappedTLK = [NSMutableData dataWithLength:shareData.wrappedTLK.length]; + shareData.share.wrappedTLK = [NSMutableData dataWithLength:shareData.wrappedTLK.length]; XCTAssertFalse([shareData verifySignature:signature verifyingPeer:self.localPeer error:&error], "After data change, signature should no longer verify"); XCTAssertNotNil(error, "Signature verification due to data change should have produced an error"); error = nil; @@ -149,7 +152,7 @@ - (void)testKeyShareAndRecover { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -166,7 +169,7 @@ - (void)testKeyShareAndFailRecovery { NSError* error = nil; CKKSKey* key = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -186,15 +189,15 @@ XCTAssertNotNil(error, "Should have produced an error when failing to extract with the wrong key"); error = nil; - CKKSTLKShare* shareSignature = [share copy]; - shareSignature.signature = [NSMutableData dataWithLength:shareSignature.signature.length]; + CKKSTLKShareRecord* shareSignature = [share copy]; + shareSignature.share.signature = [NSMutableData dataWithLength:shareSignature.signature.length]; key = [shareSignature recoverTLK:self.remotePeer trustedPeers:peers error:&error]; XCTAssertNil(key, "No key should have been extracted when signature fails to verify"); XCTAssertNotNil(error, "Should have produced an error when failing to extract a key with an invalid signature"); error = nil; - CKKSTLKShare* shareUUID = [share copy]; - shareUUID.tlkUUID = [[NSUUID UUID] UUIDString]; + CKKSTLKShareRecord* shareUUID = [share copy]; + shareUUID.share.tlkUUID = [[NSUUID UUID] UUIDString]; key = [shareUUID recoverTLK:self.remotePeer trustedPeers:peers error:&error]; XCTAssertNil(key, "No key should have been extracted when uuid has changed"); XCTAssertNotNil(error, "Should have produced an error when failing to extract a key after uuid has changed"); @@ -203,7 +206,7 @@ - (void)testKeyShareSaveAndLoad { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -214,7 +217,7 @@ [share saveToDatabase:&error]; XCTAssertNil(error, "Shouldn't be an error saving a TLKShare record to the database"); - CKKSTLKShare* loadedShare = [CKKSTLKShare fromDatabase:self.tlk.uuid + CKKSTLKShareRecord* loadedShare = [CKKSTLKShareRecord fromDatabase:self.tlk.uuid receiverPeerID:self.remotePeer.peerID senderPeerID:self.localPeer.peerID zoneID:self.tlk.zoneID @@ -228,7 +231,7 @@ XCTAssertNotNil(record, "Should be able to turn a share into a CKRecord"); XCTAssertTrue([share matchesCKRecord: record], "Should be able to compare a CKRecord with a TLKShare"); - CKKSTLKShare* fromCKRecord = [[CKKSTLKShare alloc] initWithCKRecord:record]; + CKKSTLKShareRecord* fromCKRecord = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; XCTAssertNotNil(fromCKRecord, "Should be able to turn a CKRecord into a TLK share"); XCTAssertEqualObjects(share, fromCKRecord, "TLK shares sent through CloudKit should be identical"); @@ -236,7 +239,7 @@ - (void)testKeyShareSignExtraFieldsInCKRecord { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.tlk as:self.localPeer to:self.remotePeer epoch:-1 @@ -252,14 +255,14 @@ record[@"extra_field"] = @"asdf"; record[@"another_field"] = [NSNumber numberWithInt:5]; record[@"data"] = [@"asdfdata" dataUsingEncoding:NSUTF8StringEncoding]; - CKKSTLKShare* share2 = [share copy]; + CKKSTLKShareRecord* share2 = [share copy]; share2.storedCKRecord = record; XCTAssertNotNil([share dataForSigning], "TLKShares should be able to produce some data to sign"); XCTAssertNotNil([share2 dataForSigning], "TLKShares should be able to produce some data to sign (that includes extra fields)"); XCTAssertNotEqualObjects([share dataForSigning], [share2 dataForSigning], "TLKShares should prepare to sign extra unknown data"); - share2.signature = [share2 signRecord:self.localPeer.signingKey error:&error]; + share2.share.signature = [share2 signRecord:self.localPeer.signingKey error:&error]; XCTAssertNil(error, "Shouldn't be an error signing a record with extra fields"); XCTAssertNotEqualObjects(share.signature, share2.signature, "Signatures should be different for different data"); @@ -282,7 +285,7 @@ [share2 saveToDatabase:&error]; XCTAssertNil(error, "No error saving share2 to database"); - CKKSTLKShare* loadedShare2 = [CKKSTLKShare tryFromDatabaseFromCKRecordID:record.recordID error:&error]; + CKKSTLKShareRecord* loadedShare2 = [CKKSTLKShareRecord tryFromDatabaseFromCKRecordID:record.recordID error:&error]; XCTAssertNil(error, "No error loading loadedShare2 from database"); XCTAssertNotNil(loadedShare2, "Should have received a CKKSTLKShare from the database"); diff --git a/keychain/ckks/tests/CKKSTLKSharingTests.m b/keychain/ckks/tests/CKKSTLKSharingTests.m index 2a381983..ece1aebd 100644 --- a/keychain/ckks/tests/CKKSTLKSharingTests.m +++ b/keychain/ckks/tests/CKKSTLKSharingTests.m @@ -26,16 +26,17 @@ #import #import #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/CKKSKey.h" #import "keychain/ckks/CKKSPeer.h" -#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSTLKShareRecord.h" #import "keychain/ckks/CKKSViewManager.h" #import "keychain/ckks/CloudKitCategories.h" #import "keychain/categories/NSError+UsefulConstructors.h" @@ -43,18 +44,23 @@ #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/tests/CKKSTests.h" #import "keychain/ot/OTDefines.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" + +#import "keychain/ckks/tests/CKKSMockOctagonAdapter.h" + +@class OctagonSelfPeer; @interface CloudKitKeychainSyncingTLKSharingTests : CloudKitKeychainSyncingTestsBase @property CKKSSOSSelfPeer* remotePeer1; @property CKKSSOSPeer* remotePeer2; +@property OctagonSelfPeer* selfOTPeer1; +@property id remoteOTPeer2; @property CKKSSOSSelfPeer* untrustedPeer; @property (nullable) NSMutableSet>* pastSelfPeers; -// Used to test a single code path. If true, no past self peers will be valid -@property bool breakLoadSelfPeerEncryptionKey; @end @implementation CloudKitKeychainSyncingTLKSharingTests @@ -64,26 +70,41 @@ self.pastSelfPeers = [NSMutableSet set]; - // Use the upsetting old-style mocks so we can ignore the enum - [[[[self.mockCKKSViewManager stub] andCall:@selector(fakeLoadRestoredBottledKeysOfType:error:) - onObject:self] ignoringNonObjectArgs] - loadRestoredBottledKeysOfType:0 error:[OCMArg anyObjectRef]]; - self.remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote-peer1" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; self.remotePeer2 = [[CKKSSOSPeer alloc] initWithSOSPeerID:@"remote-peer2" encryptionPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey - signingPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey]; + signingPublicKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]].publicKey + viewList:self.managedViewList]; // Local SOS trusts these peers - [self.currentPeers addObject:self.remotePeer1]; - [self.currentPeers addObject:self.remotePeer2]; + [self.mockSOSAdapter.trustedPeers addObject:self.remotePeer1]; + [self.mockSOSAdapter.trustedPeers addObject:self.remotePeer2]; self.untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; + + /* + * Octagon glue + */ + SFKeyPair *signingKeyPair = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + SFKeyPair *encrytionKeyPair = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + self.selfOTPeer1 = [[OctagonSelfPeer alloc] initWithPeerID:@"SHA256:ot-self-peer" + signingIdentity:[[SFIdentity alloc] initWithKeyPair: signingKeyPair] + encryptionIdentity:[[SFIdentity alloc] initWithKeyPair: encrytionKeyPair]]; + self.remoteOTPeer2 = nil; + + self.mockOctagonAdapter = [[CKKSMockOctagonAdapter alloc] initWithSelfPeer:self.selfOTPeer1 + trustedPeers:[NSSet set] + essential:YES]; + self.mockOctagonAdapter.selfViewList = self.managedViewList; + } - (void)tearDown { @@ -91,57 +112,12 @@ self.remotePeer1 = nil; self.remotePeer2 = nil; self.untrustedPeer = nil; + self.selfOTPeer1 = nil; + self.remoteOTPeer2 = nil; [super tearDown]; } - -- (NSArray* _Nullable)fakeLoadRestoredBottledKeysOfType:(OctagonKeyType)keyType error:(NSError**)error { - if(self.aksLockState) { - if(error) { - *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; - } - return nil; - } else { - if(self.breakLoadSelfPeerEncryptionKey && keyType == OctagonEncryptionKey) { - if(error) { - *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecItemNotFound userInfo:nil]; - } - return nil; - } - - // Convert self.pastSelfPeers into an array of dictionaries - NSMutableArray* keys = [NSMutableArray array]; - - for(id peer in self.pastSelfPeers) { - SFECKeyPair* key = nil; - - switch(keyType) { - case OctagonSigningKey: - key = peer.signingKey; - break; - case OctagonEncryptionKey: - key = peer.encryptionKey; - break; - } - - XCTAssertNotNil(key, "Should have a key at this point"); - - NSData* signingPublicKeyHashBytes = [SFSHA384DigestOperation digest:peer.signingKey.publicKey.keyData]; - NSString* signingPublicKeyHash = [signingPublicKeyHashBytes base64EncodedStringWithOptions:0]; - - NSDictionary* dict = @{ - (id)kSecAttrAccount : peer.peerID, - (id)kSecAttrLabel : signingPublicKeyHash, - (id)kSecValueData : key.keyData, - }; - [keys addObject:dict]; - } - - return keys; - } -} - - (void)testAcceptExistingTLKSharedKeyHierarchy { // Test starts with no keys in CKKS database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -176,7 +152,8 @@ }]; } -- (void)testAcceptExistingTLKSharedKeyHierarchyForPastSelf { +/* As part of 48178481, we disabled CKKS 'past selves' for SOS */ +- (void)DISABLEDtestAcceptExistingTLKSharedKeyHierarchyForPastSelf { // Test starts with no keys in CKKS database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -184,18 +161,19 @@ [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; // Self rolls its keys and ID... - [self.pastSelfPeers addObject:self.currentSelfPeer]; - self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"new-local-peer" + [self.pastSelfPeers addObject:self.mockSOSAdapter.selfPeer]; + self.mockSOSAdapter.selfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"new-local-peer" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; // The CKKS subsystem should accept the keys, and share the TLK back to itself [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match current self"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match current self"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.mockSOSAdapter.selfPeer.peerID, "Receiver peerID on TLKShare should match current self"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.mockSOSAdapter.selfPeer.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); return TRUE; }]; [self startCKKSSubsystem]; @@ -223,26 +201,6 @@ }]; } -- (void)testDontCrashOnHalfBottle { - self.breakLoadSelfPeerEncryptionKey = true; - - // Test starts with no keys in CKKS database, but one in our fake CloudKit. - [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; - - // Test also starts with the TLK shared to all trusted peers from peer1 - [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; - - // Self rolls its keys and ID... - [self.pastSelfPeers addObject:self.currentSelfPeer]; - self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"new-local-peer" - encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; - - // CKKS should enter 'waitfortlk' without crashing - [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); -} - - (void)testAcceptExistingTLKSharedKeyHierarchyAndUse { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -297,9 +255,9 @@ XCTAssertNotNil(strongSelf, "self exists"); NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:strongSelf.keychainZoneKeys.tlk - as:strongSelf.currentSelfPeer - to:strongSelf.currentSelfPeer + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:strongSelf.keychainZoneKeys.tlk + as:strongSelf.mockSOSAdapter.selfPeer + to:strongSelf.mockSOSAdapter.selfPeer epoch:-1 poisoned:0 error:&error]; @@ -338,7 +296,7 @@ // Make another share, but from an untrusted peer to some other peer. local shouldn't necessarily care. NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:self.keychainZoneKeys.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.keychainZoneKeys.tlk as:self.untrustedPeer to:self.remotePeer1 epoch:-1 @@ -355,7 +313,7 @@ [self.keychainView dispatchSync:^bool { NSError* blockerror = nil; - CKKSTLKShare* localshare = [CKKSTLKShare tryFromDatabaseFromCKRecordID:shareCKRecord.recordID error:&blockerror]; + CKKSTLKShareRecord* localshare = [CKKSTLKShareRecord tryFromDatabaseFromCKRecordID:shareCKRecord.recordID error:&blockerror]; XCTAssertNil(blockerror, "Shouldn't error finding TLKShare record in database"); XCTAssertNotNil(localshare, "Should be able to find a TLKShare record in database"); return true; @@ -369,7 +327,7 @@ // Should be gone now. [self.keychainView dispatchSync:^bool { NSError* blockerror = nil; - CKKSTLKShare* localshare = [CKKSTLKShare tryFromDatabaseFromCKRecordID:shareCKRecord.recordID error:&blockerror]; + CKKSTLKShareRecord* localshare = [CKKSTLKShareRecord tryFromDatabaseFromCKRecordID:shareCKRecord.recordID error:&blockerror]; XCTAssertNil(blockerror, "Shouldn't error trying to find non-existent TLKShare record in database"); XCTAssertNil(localshare, "Shouldn't be able to find a TLKShare record in database"); @@ -468,7 +426,7 @@ // Now, delete all the TLK Shares, so CKKS will upload them again [self.keychainView dispatchSync:^bool { NSError* error = nil; - [CKKSTLKShare deleteAll:self.keychainZoneID error:&error]; + [CKKSTLKShareRecord deleteAll:self.keychainZoneID error:&error]; XCTAssertNil(error, "Shouldn't be an error deleting all TLKShares"); NSArray* records = [self.zones[self.keychainZoneID].currentDatabase allValues]; @@ -484,6 +442,7 @@ // Restart. We expect an upload of 3 TLK shares. [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; self.keychainView = [self.injectedManager restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); @@ -628,14 +587,14 @@ // The CKKS subsystem should go into waitfortlk, since it doesn't trust this peer, but the peer is active [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should become waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:2000*NSEC_PER_SEC], "Key state should become waitfortlk"); // Wait to be sure we really get into that state [self.keychainView waitForOperationsOfClass:[CKKSProcessReceivedKeysOperation class]]; // Now, trust the previously-untrusted peer - [self.currentPeers addObject: self.untrustedPeer]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter.trustedPeers addObject: self.untrustedPeer]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; // 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]; @@ -652,10 +611,10 @@ - (void)testSendNewTLKSharesOnTrustSetAddition { // step 1: add a new peer; we should share the TLK with them // start with no trusted peers - [self.currentPeers removeAllObjects]; + [self.mockSOSAdapter.trustedPeers removeAllObjects]; - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; @@ -664,8 +623,8 @@ // Cool! New peer arrives! [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; - [self.currentPeers addObject:self.remotePeer1]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter.trustedPeers addObject:self.remotePeer1]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -676,8 +635,8 @@ [self.keychainView waitForFetchAndIncomingQueueProcessing]; // CKKS should not upload a tlk share for this peer - [self.currentPeers addObject:self.remotePeer2]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter.trustedPeers addObject:self.remotePeer2]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; [self.keychainView waitUntilAllOperationsAreFinished]; } @@ -685,10 +644,10 @@ - (void)testFillInMissingPeerSharesAfterUnlock { // step 1: add a new peer; we should share the TLK with them // start with no trusted peers - [self.currentPeers removeAllObjects]; + [self.mockSOSAdapter.trustedPeers removeAllObjects]; - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -702,8 +661,8 @@ [self.lockStateTracker recheck]; // New peer arrives! This can't actually happen (since we have to be unlocked to accept a new peer), but this will exercise CKKS - [self.currentPeers addObject:self.remotePeer1]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter.trustedPeers addObject:self.remotePeer1]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; // CKKS should notice that it has things to do... XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); @@ -722,10 +681,10 @@ - (void)testAddItemDuringNewTLKSharesOnTrustSetAddition { // step 1: add a new peer; we should share the TLK with them // start with no trusted peers - [self.currentPeers removeAllObjects]; + [self.mockSOSAdapter.trustedPeers removeAllObjects]; - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -734,8 +693,8 @@ [self holdCloudKitModifications]; [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; - [self.currentPeers addObject:self.remotePeer1]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter.trustedPeers addObject:self.remotePeer1]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -762,9 +721,10 @@ [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; // self no longer has that key pair, but it does have a new one with the same peer ID.... - self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:self.currentSelfPeer.peerID + self.mockSOSAdapter.selfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:self.mockSOSAdapter.selfPeer.peerID encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; self.pastSelfPeers = [NSMutableSet set]; // CKKS should become very upset, and enter waitfortlk. @@ -779,8 +739,8 @@ // step 1: add a new peer; we should share the TLK with them // start with no trusted peers - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); @@ -788,15 +748,15 @@ // Remote peer rolls its encryption key... [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.remotePeer1.peerID, "Receiver peerID on TLKShare should match remote peer"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer1.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.remotePeer1.peerID, "Receiver peerID on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.remotePeer1.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); return TRUE; }]; self.remotePeer1.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -810,7 +770,7 @@ // This recovers from the remote peer losing its Octagon keys and making new ones // For this test, only have one peer - self.currentPeers = [NSMutableSet setWithObject:self.remotePeer1]; + self.mockSOSAdapter.trustedPeers = [NSMutableSet setWithObject:self.remotePeer1]; // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -828,10 +788,10 @@ // 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 checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match self peer"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match self peer"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.mockSOSAdapter.selfPeer.peerID, "Receiver peerID on TLKShare should match self peer"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.mockSOSAdapter.selfPeer.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match self peer"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); return TRUE; }]; @@ -849,7 +809,7 @@ // This recovers from the local peer losing its Octagon keys and making new ones // For this test, only have one peer - self.currentPeers = [NSMutableSet setWithObject:self.remotePeer1]; + self.mockSOSAdapter.trustedPeers = [NSMutableSet setWithObject:self.remotePeer1]; // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -864,15 +824,15 @@ // 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 checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.remotePeer1.peerID, "Receiver peerID on TLKShare should match remote peer"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer1.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.remotePeer1.peerID, "Receiver peerID on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.remotePeer1.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); return TRUE; }]; self.remotePeer1.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -896,17 +856,20 @@ [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.remotePeer2.peerID, "Receiver peerID on TLKShare should match remote peer"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer2.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.remotePeer2.peerID, "Receiver peerID on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.remotePeer2.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match remote peer"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); return TRUE; }]; - CKKSSOSPeer* brokenRemotePeer1 = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.remotePeer1.peerID encryptionPublicKey:nil signingPublicKey:nil]; - [self.currentPeers removeObject:self.remotePeer1]; - [self.currentPeers addObject:brokenRemotePeer1]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + CKKSSOSPeer* brokenRemotePeer1 = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.remotePeer1.peerID + encryptionPublicKey:nil + signingPublicKey:nil + viewList:self.managedViewList]; + [self.mockSOSAdapter.trustedPeers removeObject:self.remotePeer1]; + [self.mockSOSAdapter.trustedPeers addObject:brokenRemotePeer1]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -936,26 +899,27 @@ [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:2 zoneID:self.keychainZoneID checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - if([share.receiver.peerID isEqualToString:self.remotePeer1.peerID]) { + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + if([share.share.receiverPeerID isEqualToString:self.remotePeer1.peerID]) { [peer1Share fulfill]; - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer1.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer1"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.remotePeer1.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match remote peer1"); } - if([share.receiver.peerID isEqualToString:self.remotePeer2.peerID]) { + if([share.share.receiverPeerID isEqualToString:self.remotePeer2.peerID]) { [peer2Share fulfill]; - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.remotePeer2.publicEncryptionKey, "Receiver encryption key on TLKShare should match remote peer2"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.remotePeer2.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match remote peer2"); } - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); return TRUE; }]; CKKSSOSPeer* brokenRemotePeer1 = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.remotePeer1.peerID encryptionPublicKey:self.remotePeer1.publicEncryptionKey - signingPublicKey:nil]; - [self.currentPeers removeObject:self.remotePeer1]; - [self.currentPeers addObject:brokenRemotePeer1]; - [self.injectedManager sendTrustedPeerSetChangedUpdate]; + signingPublicKey:nil + viewList:self.managedViewList]; + [self.mockSOSAdapter.trustedPeers removeObject:self.remotePeer1]; + [self.mockSOSAdapter.trustedPeers addObject:brokenRemotePeer1]; + [self.mockSOSAdapter sendTrustedPeerSetChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -981,19 +945,19 @@ // Local peer rolls its encryption key (and loses the old ones) [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match current self"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match current self"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.mockSOSAdapter.selfPeer.peerID, "Receiver peerID on TLKShare should match current self"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.mockSOSAdapter.selfPeer.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); NSError* signatureVerifyError = nil; - XCTAssertTrue([share verifySignature:share.signature verifyingPeer:self.currentSelfPeer error:&signatureVerifyError], "New share's signature should verify"); + XCTAssertTrue([share verifySignature:share.signature verifyingPeer:self.mockSOSAdapter.selfPeer error:&signatureVerifyError], "New share's signature should verify"); XCTAssertNil(signatureVerifyError, "Should be no error verifying signature on new TLKShare"); return TRUE; }]; - self.currentSelfPeer.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.mockSOSAdapter.selfPeer.encryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; self.pastSelfPeers = [NSMutableSet set]; - [self.injectedManager sendSelfPeerChangedUpdate]; + [self.mockSOSAdapter sendSelfPeerChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); @@ -1001,19 +965,19 @@ // Now, local peer loses and rolls its signing key (and loses the old one) [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID checkModifiedRecord:^BOOL(CKRecord* _Nonnull record) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:record]; - XCTAssertEqualObjects(share.receiver.peerID, self.currentSelfPeer.peerID, "Receiver peerID on TLKShare should match current self"); - XCTAssertEqualObjects(share.receiver.publicEncryptionKey, self.currentSelfPeer.publicEncryptionKey, "Receiver encryption key on TLKShare should match current self"); - XCTAssertEqualObjects(share.senderPeerID, self.currentSelfPeer.peerID, "Sender of TLKShare should match current self"); + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:record]; + XCTAssertEqualObjects(share.share.receiverPeerID, self.mockSOSAdapter.selfPeer.peerID, "Receiver peerID on TLKShare should match current self"); + XCTAssertEqualObjects(share.share.receiverPublicEncryptionKeySPKI, self.mockSOSAdapter.selfPeer.publicEncryptionKey.keyData, "Receiver encryption key on TLKShare should match current self"); + XCTAssertEqualObjects(share.senderPeerID, self.mockSOSAdapter.selfPeer.peerID, "Sender of TLKShare should match current self"); NSError* signatureVerifyError = nil; - XCTAssertTrue([share verifySignature:share.signature verifyingPeer:self.currentSelfPeer error:&signatureVerifyError], "New share's signature should verify"); + XCTAssertTrue([share verifySignature:share.signature verifyingPeer:self.mockSOSAdapter.selfPeer error:&signatureVerifyError], "New share's signature should verify"); XCTAssertNil(signatureVerifyError, "Should be no error verifying signature on new TLKShare"); return TRUE; }]; - self.currentSelfPeer.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + self.mockSOSAdapter.selfPeer.signingKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; self.pastSelfPeers = [NSMutableSet set]; - [self.injectedManager sendSelfPeerChangedUpdate]; + [self.mockSOSAdapter sendSelfPeerChangedUpdate]; OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); @@ -1049,7 +1013,8 @@ // CKKS shouldn't reset this zone, due to a very recent (but untrusted) TLK Share. You can hit this getting a circle reset; the device with the TLKs will have a CFU. CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:untrustedPeer to:untrustedPeer zoneID:self.keychainZoneID]; NSDateComponents* offset = [[NSDateComponents alloc] init]; @@ -1078,7 +1043,8 @@ // CKKS shouldn't reset this zone, due to a recent TLK Share (indicating the presence of TLKs) CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:untrustedPeer to:untrustedPeer zoneID:self.keychainZoneID]; NSDateComponents* offset = [[NSDateComponents alloc] init]; @@ -1093,9 +1059,8 @@ self.silentZoneDeletesAllowed = true; self.keychainZone.flag = true; - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:3 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + [self performOctagonTLKUpload:self.ckksViews]; // Then we should reset. OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -1105,7 +1070,7 @@ XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); } -- (void)testNoSelfEncryptionKeys { +- (void)testNoSOSSelfEncryptionKeys { // If you lose your local encryption keys, CKKS should do something reasonable // Test also starts with the TLK shared to all trusted peers from peer1 @@ -1114,10 +1079,9 @@ [self saveTLKSharesInLocalDatabase:self.keychainZoneID]; // But, we lost our local keys :( - id oldSelfPeer = self.currentSelfPeer; + CKKSSOSSelfPeer* oldSelfPeer = self.mockSOSAdapter.selfPeer; - self.currentSelfPeer = nil; - self.currentSelfPeerError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam description:@"injected test failure"]; + self.mockSOSAdapter.selfPeerError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam description:@"injected test failure"]; // CKKS subsystem should realize that it can't read the shares it has, and enter waitfortlk [self startCKKSSubsystem]; @@ -1138,14 +1102,178 @@ // It'll also upload itself a TLK share [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; - self.currentSelfPeer = oldSelfPeer; - self.currentSelfPeerError = nil; + self.mockSOSAdapter.selfPeer = oldSelfPeer; + self.mockSOSAdapter.selfPeerError = nil; + + [self.mockSOSAdapter sendSelfPeerChangedUpdate]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready''"); + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; +} + +- (void)testNoSOSSelfEncryptionKeysDuringCreation { + // If you lose your local encryption keys, CKKS should do something reasonable + + // But, things don't exist :( + self.mockSOSAdapter.selfPeerError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecParam description:@"injected test failure"]; + + [self startCKKSSubsystem]; + + NSMutableArray*>* keysetOps = [NSMutableArray array]; + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:40*NSEC_PER_SEC], @"key state should enter 'waitfortlkcreation' (view %@)", view); + [keysetOps addObject: [view findKeySet]]; + } + + // Now that we've kicked them all off, wait for them to not crash + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateError] wait:40*NSEC_PER_SEC], @"key state should enter 'error'"); + } + + /* + // Fetching status should be quick + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcStatus:@"keychain" reply:^(NSArray* result, NSError* error) { + XCTAssertNil(error, "should be no error fetching status for keychain"); + [callbackOccurs fulfill]; + }]; + [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 + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + + self.mockSOSAdapter.selfPeer = oldSelfPeer; + self.mockSOSAdapter.selfPeerError = nil; - [self.injectedManager sendSelfPeerChangedUpdate]; + [self.mockSOSAdapter sendSelfPeerChangedUpdate]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready''"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications];*/ +} + + +- (void)testNoOctagonSelfEncryptionKeys { + // If you lose your local encryption keys, CKKS should do something reasonable + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + [self saveTLKSharesInLocalDatabase:self.keychainZoneID]; + + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; + + // But, we lose our local keys :( + self.mockSOSAdapter.selfPeerError = [NSError errorWithDomain:TrustedPeersHelperErrorDomain + code:1 + description:@"injected test failure (Octagon key loss)"]; + + // Kick off TLK checking + [self.keychainView trustedPeerSetChanged:self.mockSOSAdapter]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "Key state should become 'untrusted'"); + + // Fetching status should be quick + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + [self.ckksControl rpcStatus:@"keychain" reply:^(NSArray* result, NSError* error) { + XCTAssertNil(error, "should be no error fetching status for keychain"); + [callbackOccurs fulfill]; + }]; + [self waitForExpectations:@[callbackOccurs] timeout:20]; + + // and it should pause, and not spin infinitely + XCTAssertNotEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitialized] wait:2*NSEC_PER_SEC], "Key state should not become 'initialized'"); +} + +- (void)testLoseTrustIfSelfPeerNotTrusted { + // If you decide you don't trust yourself, CKKS should do something reasonable + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + [self saveTLKSharesInLocalDatabase:self.keychainZoneID]; + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready'"); + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + self.mockSOSAdapter.excludeSelfPeerFromTrustSet = true; + + // Kick off TLK checking + [self.keychainView trustedPeerSetChanged:self.mockSOSAdapter]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "Key state should become 'untrusted'"); + + // and it should pause, and not spin infinitely + XCTAssertNotEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitialized] wait:2*NSEC_PER_SEC], "Key state should not become 'initialized'"); +} + +- (void)testDontLoseTrustIfNonessentialTrustStateIsBroken { + // if a non-essential but broken peer provider exists, CKKS shouldn't pay it any mind + + // Test also starts with the TLK shared to all trusted peers from peer1 + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putTLKSharesInCloudKit:self.keychainZoneKeys.tlk from:self.remotePeer1 zoneID:self.keychainZoneID]; + [self saveTLKSharesInLocalDatabase:self.keychainZoneID]; + + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready'"); + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + // To fake this, make another mock SOS adapter, but make it nonessential + CKKSSOSSelfPeer* brokenSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"local-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; + CKKSMockSOSPresentAdapter* brokenAdapter = [[CKKSMockSOSPresentAdapter alloc] initWithSelfPeer:brokenSelfPeer + trustedPeers:[NSSet set] + essential:NO]; + brokenAdapter.excludeSelfPeerFromTrustSet = true; + + [self.keychainView endTrustedOperation]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "Key state should become 'waitfortrust'"); + + [self.keychainView beginTrustedOperation:@[self.mockSOSAdapter, brokenAdapter] suggestTLKUpload:self.suggestTLKUpload]; + + // CKKS should ignore the non-essential and broken peer adapter + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become 'ready'"); +} + +- (void)testTLKSharesForOctagonPeer { + // Launch first for SOS only + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self expectCKModifyKeyRecords:0 currentKeyPointerRecords:0 tlkShareRecords:3 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + [self.keychainView endTrustedOperation]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "Key state should become 'waitfortrust'"); + + // Spin up Octagon. We expect an upload of 3 TLK shares, this time for the octagon peer + [self expectCKModifyKeyRecords: 0 currentKeyPointerRecords:0 tlkShareRecords:1 zoneID:self.keychainZoneID]; + [self.keychainView beginTrustedOperation:@[self.mockSOSAdapter, self.mockOctagonAdapter] suggestTLKUpload:self.suggestTLKUpload]; + [self.mockOctagonAdapter sendTrustedPeerSetChangedUpdate]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); } @end diff --git a/keychain/ckks/tests/CKKSTests+API.m b/keychain/ckks/tests/CKKSTests+API.m index 951dd0f6..0b8ad45e 100644 --- a/keychain/ckks/tests/CKKSTests+API.m +++ b/keychain/ckks/tests/CKKSTests+API.m @@ -28,6 +28,8 @@ #import #include +#include "OSX/sec/Security/SecItemShim.h" + #include #include #import @@ -62,7 +64,6 @@ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecReturnPersistentRef: @YES, (id)kSecReturnAttributes: @YES, - (id)kSecAttrSyncViewHint: @"keychain", (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccount : account, @@ -194,6 +195,65 @@ [self waitForExpectationsWithTimeout:5.0 handler:nil]; } +- (void)testAddAndNotifyOnSyncSkipsQueue { + // Use the PCS plaintext fields to determine which object is which + SecResetLocalSecuritydXPCFakeEntitlements(); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSPlaintextFields, kCFBooleanTrue); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSWriteCurrentItemPointers, kCFBooleanTrue); + SecAddLocalSecuritydXPCFakeEntitlement(kSecEntitlementPrivateCKKSReadCurrentItemPointers, kCFBooleanTrue); + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + [self startCKKSSubsystem]; + [self.keychainView waitForKeyHierarchyReadiness]; + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 40); + + self.keychainView.holdOutgoingQueueOperation = [CKKSGroupOperation named:@"outgoing-hold" withBlock: ^{ + secnotice("ckks", "releasing outgoing-queue hold"); + }]; + + for(size_t count = 0; count < 150; count++) { + [self addGenericPassword:@"data" account:[NSString stringWithFormat:@"account-delete-me-%03lu", count]]; + } + + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlock, + (id)kSecAttrAccount : @"testaccount", + (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, + (id)kSecAttrPCSPlaintextPublicKey : [@"asdf" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecValueData : (id) [@"asdf" dataUsingEncoding:NSUTF8StringEncoding], + } mutableCopy]; + + XCTestExpectation* blockExpectation = [self expectationWithDescription: @"callback occurs"]; + + XCTAssertEqual(errSecSuccess, _SecItemAddAndNotifyOnSync((__bridge CFDictionaryRef) query, NULL, ^(bool didSync, CFErrorRef error) { + XCTAssertTrue(didSync, "Item synced properly"); + XCTAssertNil((__bridge NSError*)error, "No error syncing item"); + + [blockExpectation fulfill]; + }), @"_SecItemAddAndNotifyOnSync succeeded"); + + // Release the hounds + [self.operationQueue addOperation:self.keychainView.holdOutgoingQueueOperation]; + + XCTestExpectation* firstQueueOperation = [self expectationWithDescription: @"found the item in the first queue iteration"]; + [self expectCKModifyItemRecords:SecCKKSOutgoingQueueItemsAtOnce + currentKeyPointerRecords:1 + zoneID:self.keychainZoneID + checkItem:^BOOL(CKRecord * _Nonnull record) { + if(record[SecCKRecordPCSPublicKey]) { + [firstQueueOperation fulfill]; + } + return YES; + }]; + [self expectCKModifyItemRecords:51 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + + [self waitForExpectationsWithTimeout:5.0 handler:nil]; +} + - (void)testAddAndNotifyOnSyncFailure { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -729,9 +789,9 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } --(void)testResetLocalWhileLoggedOut { +-(void)testResetLocalWhileUntrusted { // We're "logged in to" cloudkit but not in circle. - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.silentFetchesAllowed = false; @@ -742,7 +802,7 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.loggedOut wait:500*NSEC_PER_MSEC], "Should have been told of a 'logout' event on startup"); + XCTAssertEqual(0, [self.keychainView.loggedIn wait:500*NSEC_PER_MSEC], "Should have been told of a 'login' event on startup"); NSData* changeTokenData = [[[NSUUID UUID] UUIDString] dataUsingEncoding:NSUTF8StringEncoding]; CKServerChangeToken* changeToken = [[CKServerChangeToken alloc] initWithData:changeTokenData]; @@ -756,26 +816,33 @@ return true; }]; + // after the reset, CKKS should refetch what's available + [self expectCKFetch]; + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"local reset callback occurs"]; [self.injectedManager rpcResetLocal:nil reply:^(NSError* result) { XCTAssertNil(result, "no error resetting local"); secnotice("ckks", "Received a rpcResetLocal callback"); + + [self.keychainView dispatchSync: ^bool{ + CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.keychainView.zoneName]; + XCTAssertNotEqualObjects(changeToken, ckse.changeToken, "Change token is reset"); + return true; + }]; + [resetExpectation fulfill]; }]; [self waitForExpectations:@[resetExpectation] timeout:20]; - [self.keychainView dispatchSync: ^bool{ - CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:self.keychainView.zoneName]; - XCTAssertNotEqualObjects(changeToken, ckse.changeToken, "Change token is reset"); - return true; - }]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], @"Key state should arrive at 'waitfortrust''"); - // Now log in, and see what happens! It should re-fetch, pick up the old key hierarchy, and use it + // Now regain trust, and see what happens! It should use the existing fetch, pick up the old key hierarchy, and use it [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; - self.silentFetchesAllowed = true; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];; + + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; [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" @@ -845,6 +912,65 @@ } -(void)testResetCloudKitZone { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + + self.silentZoneDeletesAllowed = true; + + // Test starts with nothing in database, but one in our fake CloudKit. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychainSimulatingSOS:self.keychainZoneID]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + // 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, 20); + [self waitForCKModifications]; + + // During the reset, Octagon will upload the key hierarchy, and then CKKS will upload the class C item + [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 reason:@"reset-test" reply:^(NSError* result) { + XCTAssertNil(result, "no error resetting cloudkit"); + secnotice("ckks", "Received a resetCloudKit callback"); + [resetExpectation fulfill]; + }]; + + // Sneak in and perform Octagon's duties + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + + [self waitForExpectations:@[resetExpectation] timeout:20]; + + 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" + account:@"account-class-A" + viewHint:nil + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testResetCloudKitZoneCloudKitRejects { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + + self.nextModifyRecordZonesError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain + code:CKErrorZoneBusy + userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + NSUnderlyingErrorKey: [[CKPrettyError alloc] initWithDomain:CKErrorDomain + code:2029 + userInfo:nil], + }]; self.silentZoneDeletesAllowed = true; // Test starts with nothing in database, but one in our fake CloudKit. @@ -861,9 +987,8 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; - // After the reset, we expect a key hierarchy upload, and then the class C item upload - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + // During the reset, Octagon will upload the key hierarchy, and then CKKS will upload the class C item + [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 reason:@"reset-test" reply:^(NSError* result) { @@ -871,6 +996,11 @@ secnotice("ckks", "Received a resetCloudKit callback"); [resetExpectation fulfill]; }]; + + // Sneak in and perform Octagon's duties + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + [self waitForExpectations:@[resetExpectation] timeout:20]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -883,9 +1013,14 @@ expecting:errSecSuccess message:@"Adding class A item"]; OCMVerifyAllWithDelay(self.mockDatabase, 20); + + XCTAssertNil(self.nextModifyRecordZonesError, "Record zone modification error should have been cleared"); } - (void)testResetCloudKitZoneDuringWaitForTLK { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + self.silentZoneDeletesAllowed = true; // Test starts with nothing in database, but one in our fake CloudKit. @@ -903,6 +1038,9 @@ // 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]; + self.ckksViews = [NSMutableSet setWithObject:self.keychainView]; + + [self beginSOSTrustedViewOperation:self.keychainView]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); CKKSOutgoingQueueOperation* outgoingOp = [self.keychainView processOutgoingQueue:nil]; @@ -910,7 +1048,6 @@ // Now, reset everything. The outgoingOp should get cancelled. // We expect a key hierarchy upload, and then the class C item upload - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; @@ -919,6 +1056,11 @@ XCTAssertNil(result, "no error resetting cloudkit"); [resetExpectation fulfill]; }]; + + // Sneak in and perform Octagon's duties + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + [self waitForExpectations:@[resetExpectation] timeout:20]; XCTAssertTrue([outgoingOp isCancelled], "old stuck ProcessOutgoingQueue should be cancelled"); @@ -954,6 +1096,7 @@ // 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]; + [self beginSOSTrustedViewOperation:self.keychainView]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "CKKS entered waitfortlk"); CKKSOutgoingQueueOperation* outgoingOp = [self.keychainView processOutgoingQueue:nil]; @@ -986,13 +1129,12 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); }*/ --(void)testResetCloudKitZoneWhileLoggedOut { +-(void)testResetCloudKitZoneWhileUntrusted { self.silentZoneDeletesAllowed = true; // We're "logged in to" cloudkit but not in circle. - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - self.silentFetchesAllowed = false; // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -1000,6 +1142,9 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; + // Since CKKS is untrusted, it'll fetch the zone but then get stuck + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "CKKS entered 'waitfortrust'"); + CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85"]; [self.keychainZone addToZone: ckr]; @@ -1012,6 +1157,7 @@ secnotice("ckks", "Received a resetCloudKit callback"); [resetExpectation fulfill]; }]; + [self waitForExpectations:@[resetExpectation] timeout:20]; XCTAssertNil(self.keychainZone.currentDatabase, "No zone anymore!"); @@ -1019,10 +1165,12 @@ // 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 = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil];; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + [self performOctagonTLKUpload:self.ckksViews]; - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; 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"]]; @@ -1036,6 +1184,9 @@ } - (void)testResetCloudKitZoneMultipleTimes { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + self.silentZoneDeletesAllowed = true; // Test starts with nothing in database, but one in our fake CloudKit. @@ -1077,12 +1228,15 @@ }]; // After the reset(s), we expect a key hierarchy upload, and then the class C item upload - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID checkItem:[self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; // And let the resets flow [self releaseCloudKitFetchHold]; + + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + [self waitForExpectations:@[resetExpectation0, resetExpectation1, resetExpectation2] timeout:20]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); @@ -1237,7 +1391,11 @@ } - (void)testRPCKnownBadStateWhenInWaitForUnlock { - // Bring CKKS up in 'waitfortunlok' + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + + // Bring CKKS up in 'waitforunlock' self.aksLockState = true; [self.lockStateTracker recheck]; [self startCKKSSubsystem]; @@ -1257,6 +1415,26 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } +- (void)testRPCKnownBadStateWhenInWaitForUpload { + // Bring CKKS up in 'waitfortupload' + self.aksLockState = true; + [self.lockStateTracker recheck]; + [self startCKKSSubsystem]; + + // Wait for the key hierarchy state machine to get stuck waiting for Octagon. No uploads should occur. + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitfortlkcreation"); + + XCTestExpectation* callbackOccurs = [self expectationWithDescription:@"callback-occurs"]; + + [self.ckksControl rpcKnownBadState:@"keychain" reply:^(CKKSKnownBadState result) { + XCTAssertEqual(result, CKKSKnownStateWaitForOctagon, "known state should be wait for Octagon"); + [callbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[callbackOccurs] timeout:20]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} - (void)testRPCKnownBadStateWhenInGoodState { // Bring CKKS up in 'ready' diff --git a/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m b/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m index c7fedf83..d96cb296 100644 --- a/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m +++ b/keychain/ckks/tests/CKKSTests+CurrentPointerAPI.m @@ -141,7 +141,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -194,7 +194,7 @@ PCSPublicKey:publicKey PCSPublicIdentity:publicIdentity]]; - result = [self pcsAddItem:@"OTHER-ITEM" + result = [self pcsAddItem:@"tOTHER-ITEM" data:[@"asdfasdf" dataUsingEncoding:NSUTF8StringEncoding] serviceIdentifier:(NSNumber*)servIdentifier publicKey:(NSData*)publicKey @@ -205,7 +205,7 @@ // Check that the record is where we expect it [self waitForCKModifications]; - CKRecordID* pcsOtherItemRecordID = [[CKRecordID alloc] initWithRecordName: @"11D16E4E-F9F7-6940-938C-78BAC4D56953" zoneID:self.keychainZoneID]; + CKRecordID* pcsOtherItemRecordID = [[CKRecordID alloc] initWithRecordName: @"878BEAA6-1EE9-1079-1025-E6832AC8F2F3" zoneID:self.keychainZoneID]; CKRecord* recordOther = self.keychainZone.currentDatabase[pcsOtherItemRecordID]; XCTAssertNotNil(recordOther, "Found other record in CloudKit at expected UUID"); @@ -343,7 +343,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -390,7 +390,8 @@ // Entirely signed out of iCloud. all current record writes should fail. self.accountStatus = CKAccountStatusNoAccount; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; + + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.silentFetchesAllowed = false; @@ -544,11 +545,11 @@ // Check that the records are where we expect them in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); - CKRecordID* pcsItemRecordID2 = [[CKRecordID alloc] initWithRecordName: @"10E76B80-CE1C-A52A-B0CB-462A2EBA05AF" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID2 = [[CKRecordID alloc] initWithRecordName: @"3AB8E78D-75AF-CFEF-F833-FA3E3E90978A" zoneID:self.keychainZoneID]; CKRecord* record2 = self.keychainZone.currentDatabase[pcsItemRecordID2]; XCTAssertNotNil(record2, "Found 2nd record in CloudKit at expected UUID"); @@ -557,7 +558,7 @@ // Another machine comes along and updates the pointer! CKKSCurrentItemPointer* cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:@"com.apple.security.ckks-pcsservice" - currentItemUUID:@"50184A35-4480-E8BA-769B-567CF72F1EC0" + currentItemUUID:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" state:SecCKKSProcessedStateRemote zoneID:self.keychainZoneID encodedCKRecord:nil]; @@ -634,7 +635,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -643,7 +644,7 @@ // Another machine comes along and updates the pointer! CKKSCurrentItemPointer* cip = [[CKKSCurrentItemPointer alloc] initForIdentifier:@"com.apple.security.ckks-pcsservice" - currentItemUUID:@"50184A35-4480-E8BA-769B-567CF72F1EC0" + currentItemUUID:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" state:SecCKKSProcessedStateRemote zoneID:self.keychainZoneID encodedCKRecord:nil]; @@ -707,7 +708,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - NSString* recordUUID = @"50184A35-4480-E8BA-769B-567CF72F1EC0"; + NSString* recordUUID = @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3"; CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName:recordUUID zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -786,7 +787,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -826,7 +827,7 @@ // Check that the number is on the CKKSMirrorEntry [self.keychainView dispatchSync: ^bool { NSError* error = nil; - CKKSMirrorEntry* ckme = [CKKSMirrorEntry fromDatabase:@"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID error:&error]; + CKKSMirrorEntry* ckme = [CKKSMirrorEntry fromDatabase:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID error:&error]; XCTAssertNil(error, "no error fetching ckme"); XCTAssertNotNil(ckme, "Received a ckme"); @@ -872,7 +873,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -893,7 +894,7 @@ XCTAssertNotNil(error, "Error setting current item when the write fails"); [setCurrentExpectation fulfill]; }); - OCMVerifyAllWithDelay(self.mockDatabase, 20); + OCMVerifyAllWithDelay(self.mockDatabase, 40); [self waitForExpectationsWithTimeout:8.0 handler:nil]; @@ -935,7 +936,7 @@ // Check that the record is where we expect it in CloudKit [self waitForCKModifications]; - CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* pcsItemRecordID = [[CKRecordID alloc] initWithRecordName: @"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* record = self.keychainZone.currentDatabase[pcsItemRecordID]; XCTAssertNotNil(record, "Found record in CloudKit at expected UUID"); @@ -1053,8 +1054,7 @@ XCTAssertNil(error, "Error should be nil parsing base64 item"); item[@"v_Data"] = [@"conflictingdata" dataUsingEncoding:NSUTF8StringEncoding]; - item[@"vwht"] = self.keychainZoneID.zoneName; - CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:@"50184A35-4480-E8BA-769B-567CF72F1EC0" zoneID:self.keychainZoneID]; + CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:@"DD7C2F9B-B22D-3B90-C299-E3B48174BFA3" zoneID:self.keychainZoneID]; CKRecord* mismatchedRecord = [self newRecord:ckrid withNewItemData:item]; [self.keychainZone addToZone: mismatchedRecord]; diff --git a/keychain/ckks/tests/CKKSTests+LockStateTracker.m b/keychain/ckks/tests/CKKSTests+LockStateTracker.m new file mode 100644 index 00000000..3219d033 --- /dev/null +++ b/keychain/ckks/tests/CKKSTests+LockStateTracker.m @@ -0,0 +1,109 @@ +#if OCTAGON + +#import +#import + +#import "keychain/ckks/CKKSLockStateTracker.h" +#import "tests/secdmockaks/mockaks.h" + +@interface CKKSTests_LockStateTracker : XCTestCase +@property bool aksLockState; +@property (nullable) id mockLockStateTracker; +@property CKKSLockStateTracker* lockStateTracker; +@end + +@implementation CKKSTests_LockStateTracker + +@synthesize aksLockState = _aksLockState; + +- (void)setUp { + [super setUp]; + + self.aksLockState = false; // Lie and say AKS is always unlocked + self.mockLockStateTracker = OCMClassMock([CKKSLockStateTracker class]); + OCMStub([self.mockLockStateTracker queryAKSLocked]).andCall(self, @selector(aksLockState)); + + self.lockStateTracker = [[CKKSLockStateTracker alloc] init]; + + + [SecMockAKS reset]; +} + +- (void)tearDown { + [self.mockLockStateTracker stopMocking]; + self.lockStateTracker = nil; +} + +- (bool)aksLockState +{ + return _aksLockState; +} + +- (void)setAksLockState:(bool)aksLockState +{ + + if(aksLockState) { + [SecMockAKS lockClassA]; + } else { + [SecMockAKS unlockAllClasses]; + } + _aksLockState = aksLockState; +} + +- (void)testLockedBehindOurBack { + + /* + * check that we detect that lock errors force a recheck + */ + + NSError *lockError = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; + NSError *fileError = [NSError errorWithDomain:NSOSStatusErrorDomain code:ENOENT userInfo:nil]; + + XCTAssertFalse([self.lockStateTracker isLocked], "should start out unlocked"); + XCTAssertTrue([self.lockStateTracker isLockedError:lockError], "errSecInteractionNotAllowed is a lock errors"); + XCTAssertFalse([self.lockStateTracker isLocked], "should be unlocked after lock failure"); + + XCTAssertFalse([self.lockStateTracker isLockedError:fileError], "file errors are not lock errors"); + XCTAssertFalse([self.lockStateTracker isLocked], "should be unlocked after lock failure"); + + self.aksLockState = true; + XCTAssertFalse([self.lockStateTracker isLocked], "should be reporting unlocked since we 'missed' the notification"); + + XCTAssertFalse([self.lockStateTracker isLockedError:fileError], "file errors are not lock errors"); + XCTAssertFalse([self.lockStateTracker isLocked], "should be 'unlocked' after file errors"); + + XCTAssertTrue([self.lockStateTracker isLockedError:lockError], "errSecInteractionNotAllowed is a lock errors"); + XCTAssertTrue([self.lockStateTracker isLocked], "should be locked after lock failure"); + + self.aksLockState = false; + [self.lockStateTracker recheck]; + + XCTAssertFalse([self.lockStateTracker isLocked], "should be unlocked"); +} + +- (void)testWaitForUnlock { + + self.aksLockState = true; + [self.lockStateTracker recheck]; + + XCTestExpectation* expectation = [self expectationWithDescription: @"unlock occurs"]; + + NSBlockOperation *unlockEvent = [NSBlockOperation blockOperationWithBlock:^{ + [expectation fulfill]; + }]; + [unlockEvent addDependency:[self.lockStateTracker unlockDependency]]; + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + + [queue addOperation:unlockEvent]; + + self.aksLockState = false; + [self.lockStateTracker recheck]; + + [self waitForExpectations:@[expectation] timeout:5]; + +} + + +@end + +#endif /* OCTAGON */ diff --git a/keychain/ckks/tests/CKKSTests+MultiZone.h b/keychain/ckks/tests/CKKSTests+MultiZone.h new file mode 100644 index 00000000..1d0b619b --- /dev/null +++ b/keychain/ckks/tests/CKKSTests+MultiZone.h @@ -0,0 +1,58 @@ + +#ifndef CKKSTests_MultiZone_h +#define CKKSTests_MultiZone_h + +#if OCTAGON + +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" + +@interface CloudKitKeychainSyncingMultiZoneTestsBase : CloudKitKeychainSyncingMockXCTest + +@property CKRecordZoneID* engramZoneID; +@property CKKSKeychainView* engramView; +@property FakeCKZone* engramZone; +@property (readonly) ZoneKeys* engramZoneKeys; + +@property CKRecordZoneID* manateeZoneID; +@property CKKSKeychainView* manateeView; +@property FakeCKZone* manateeZone; +@property (readonly) ZoneKeys* manateeZoneKeys; + +@property CKRecordZoneID* autoUnlockZoneID; +@property CKKSKeychainView* autoUnlockView; +@property FakeCKZone* autoUnlockZone; +@property (readonly) ZoneKeys* autoUnlockZoneKeys; + +@property CKRecordZoneID* healthZoneID; +@property CKKSKeychainView* healthView; +@property FakeCKZone* healthZone; +@property (readonly) ZoneKeys* healthZoneKeys; + +@property CKRecordZoneID* applepayZoneID; +@property CKKSKeychainView* applepayView; +@property FakeCKZone* applepayZone; +@property (readonly) ZoneKeys* applepayZoneKeys; + +@property CKRecordZoneID* homeZoneID; +@property CKKSKeychainView* homeView; +@property FakeCKZone* homeZone; +@property (readonly) ZoneKeys* homeZoneKeys; + +@property CKRecordZoneID* limitedZoneID; +@property CKKSKeychainView* limitedView; +@property FakeCKZone* limitedZone; +@property (readonly) ZoneKeys* limitedZoneKeys; + +- (void)saveFakeKeyHierarchiesToLocalDatabase; +- (void)putFakeDeviceStatusesInCloudKit; +- (void)putFakeKeyHierachiesInCloudKit; +- (void)saveTLKsToKeychain; +- (void)deleteTLKMaterialsFromKeychain; +- (void)waitForKeyHierarchyReadinesses; +- (void)expectCKKSTLKSelfShareUploads; + +@end + +#endif // OCTAGON +#endif /* CKKSTests_MultiZone_h */ diff --git a/keychain/ckks/tests/CKKSTests+MultiZone.m b/keychain/ckks/tests/CKKSTests+MultiZone.m new file mode 100644 index 00000000..e121b309 --- /dev/null +++ b/keychain/ckks/tests/CKKSTests+MultiZone.m @@ -0,0 +1,693 @@ + +#if OCTAGON + +#import +#import +#import +#import + +#include + +#import "keychain/ckks/tests/CloudKitMockXCTest.h" +#import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSKeychainView.h" +#import "keychain/ckks/CKKSCurrentKeyPointer.h" +#import "keychain/ckks/CKKSItemEncrypter.h" +#import "keychain/ckks/CKKSKey.h" +#import "keychain/ckks/CKKSOutgoingQueueEntry.h" +#import "keychain/ckks/CKKSIncomingQueueEntry.h" +#import "keychain/ckks/CKKSSynchronizeOperation.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSZoneStateEntry.h" +#import "keychain/ckks/CKKSManifest.h" + +#import "keychain/ckks/tests/MockCloudKit.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#include +#include "keychain/SecureObjectSync/SOSAccountPriv.h" +#include "keychain/SecureObjectSync/SOSAccount.h" +#include "keychain/SecureObjectSync/SOSInternal.h" +#include "keychain/SecureObjectSync/SOSFullPeerInfo.h" +#pragma clang diagnostic pop + +#include +#include +#pragma clang diagnostic pop + +@interface CloudKitKeychainSyncingMultiZoneTestsBase : CloudKitKeychainSyncingMockXCTest + +@property CKRecordZoneID* engramZoneID; +@property CKKSKeychainView* engramView; +@property FakeCKZone* engramZone; +@property (readonly) ZoneKeys* engramZoneKeys; + +@property CKRecordZoneID* manateeZoneID; +@property CKKSKeychainView* manateeView; +@property FakeCKZone* manateeZone; +@property (readonly) ZoneKeys* manateeZoneKeys; + +@property CKRecordZoneID* autoUnlockZoneID; +@property CKKSKeychainView* autoUnlockView; +@property FakeCKZone* autoUnlockZone; +@property (readonly) ZoneKeys* autoUnlockZoneKeys; + +@property CKRecordZoneID* healthZoneID; +@property CKKSKeychainView* healthView; +@property FakeCKZone* healthZone; +@property (readonly) ZoneKeys* healthZoneKeys; + +@property CKRecordZoneID* applepayZoneID; +@property CKKSKeychainView* applepayView; +@property FakeCKZone* applepayZone; +@property (readonly) ZoneKeys* applepayZoneKeys; + +@property CKRecordZoneID* homeZoneID; +@property CKKSKeychainView* homeView; +@property FakeCKZone* homeZone; +@property (readonly) ZoneKeys* homeZoneKeys; + +@property CKRecordZoneID* limitedZoneID; +@property CKKSKeychainView* limitedView; +@property FakeCKZone* limitedZone; +@property (readonly) ZoneKeys* limitedZoneKeys; + +@end + +@implementation CloudKitKeychainSyncingMultiZoneTestsBase ++ (void)setUp { + SecCKKSEnable(); + SecCKKSResetSyncing(); + [super setUp]; +} + +- (void)setUp { + SecCKKSSetSyncManifests(false); + SecCKKSSetEnforceManifests(false); + + [super setUp]; + SecCKKSTestSetDisableSOS(false); + + // Wait for the ViewManager to be brought up + 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] findOrCreateView:@"Engram"]; + XCTAssertNotNil(self.engramView, "CKKSViewManager created the Engram view"); + [self.ckksViews addObject:self.engramView]; + [self.ckksZones addObject:self.engramZoneID]; + + self.manateeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Manatee" ownerName:CKCurrentUserDefaultName]; + self.manateeZone = [[FakeCKZone alloc] initZone: self.manateeZoneID]; + self.zones[self.manateeZoneID] = self.manateeZone; + self.manateeView = [[CKKSViewManager manager] findOrCreateView:@"Manatee"]; + XCTAssertNotNil(self.manateeView, "CKKSViewManager created the Manatee view"); + [self.ckksViews addObject:self.manateeView]; + [self.ckksZones addObject:self.manateeZoneID]; + + self.autoUnlockZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"AutoUnlock" ownerName:CKCurrentUserDefaultName]; + self.autoUnlockZone = [[FakeCKZone alloc] initZone: self.autoUnlockZoneID]; + self.zones[self.autoUnlockZoneID] = self.autoUnlockZone; + self.autoUnlockView = [[CKKSViewManager manager] findOrCreateView:@"AutoUnlock"]; + XCTAssertNotNil(self.autoUnlockView, "CKKSViewManager created the AutoUnlock view"); + [self.ckksViews addObject:self.autoUnlockView]; + [self.ckksZones addObject:self.autoUnlockZoneID]; + + self.healthZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Health" ownerName:CKCurrentUserDefaultName]; + self.healthZone = [[FakeCKZone alloc] initZone: self.healthZoneID]; + self.zones[self.healthZoneID] = self.healthZone; + self.healthView = [[CKKSViewManager manager] findOrCreateView:@"Health"]; + XCTAssertNotNil(self.healthView, "CKKSViewManager created the Health view"); + [self.ckksViews addObject:self.healthView]; + [self.ckksZones addObject:self.healthZoneID]; + + self.applepayZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"ApplePay" ownerName:CKCurrentUserDefaultName]; + self.applepayZone = [[FakeCKZone alloc] initZone: self.applepayZoneID]; + self.zones[self.applepayZoneID] = self.applepayZone; + self.applepayView = [[CKKSViewManager manager] findOrCreateView:@"ApplePay"]; + XCTAssertNotNil(self.applepayView, "CKKSViewManager created the ApplePay view"); + [self.ckksViews addObject:self.applepayView]; + [self.ckksZones addObject:self.applepayZoneID]; + + self.homeZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"Home" ownerName:CKCurrentUserDefaultName]; + self.homeZone = [[FakeCKZone alloc] initZone: self.homeZoneID]; + self.zones[self.homeZoneID] = self.homeZone; + self.homeView = [[CKKSViewManager manager] findOrCreateView:@"Home"]; + XCTAssertNotNil(self.homeView, "CKKSViewManager created the Home view"); + [self.ckksViews addObject:self.homeView]; + [self.ckksZones addObject:self.homeZoneID]; + + self.limitedZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"LimitedPeersAllowed" ownerName:CKCurrentUserDefaultName]; + self.limitedZone = [[FakeCKZone alloc] initZone: self.limitedZoneID]; + self.zones[self.limitedZoneID] = self.limitedZone; + self.limitedView = [[CKKSViewManager manager] findOrCreateView:@"LimitedPeersAllowed"]; + XCTAssertNotNil(self.limitedView, "should have a limited ckks view"); + XCTAssertNotNil(self.limitedView, "CKKSViewManager created the LimitedPeersAllowed view"); + [self.ckksViews addObject:self.limitedView]; + [self.ckksZones addObject:self.limitedZoneID]; +} + ++ (void)tearDown { + SecCKKSTestSetDisableSOS(true); + [super tearDown]; + SecCKKSResetSyncing(); +} + +- (void)tearDown { + // If the test didn't already do this, allow each zone to spin up + self.accountStatus = CKAccountStatusNoAccount; + [self startCKKSSubsystem]; + + [self.engramView halt]; + [self.engramView waitUntilAllOperationsAreFinished]; + self.engramView = nil; + + [self.manateeView halt]; + [self.manateeView waitUntilAllOperationsAreFinished]; + self.manateeView = nil; + + [self.autoUnlockView halt]; + [self.autoUnlockView waitUntilAllOperationsAreFinished]; + self.autoUnlockView = nil; + + [self.healthView halt]; + [self.healthView waitUntilAllOperationsAreFinished]; + self.healthView = nil; + + [self.applepayView halt]; + [self.applepayView waitUntilAllOperationsAreFinished]; + self.applepayView = nil; + + [self.homeView halt]; + [self.homeView waitUntilAllOperationsAreFinished]; + self.homeView = nil; + + [super tearDown]; +} + +- (ZoneKeys*)engramZoneKeys { + return self.keys[self.engramZoneID]; +} + +- (ZoneKeys*)manateeZoneKeys { + return self.keys[self.manateeZoneID]; +} + +- (void)saveFakeKeyHierarchiesToLocalDatabase { + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self createAndSaveFakeKeyHierarchy: zoneID]; + } +} + +- (void)putFakeDeviceStatusesInCloudKit { + [self putFakeDeviceStatusInCloudKit: self.engramZoneID]; + [self putFakeDeviceStatusInCloudKit: self.manateeZoneID]; + [self putFakeDeviceStatusInCloudKit: self.autoUnlockZoneID]; + [self putFakeDeviceStatusInCloudKit: self.healthZoneID]; + [self putFakeDeviceStatusInCloudKit: self.applepayZoneID]; + [self putFakeDeviceStatusInCloudKit: self.homeZoneID]; + [self putFakeDeviceStatusInCloudKit: self.limitedZoneID]; +} + +- (void)putFakeKeyHierachiesInCloudKit{ + [self putFakeKeyHierarchyInCloudKit: self.engramZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.manateeZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.autoUnlockZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.healthZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.applepayZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.homeZoneID]; + [self putFakeKeyHierarchyInCloudKit: self.limitedZoneID]; +} + +- (void)saveTLKsToKeychain{ + [self saveTLKMaterialToKeychain:self.engramZoneID]; + [self saveTLKMaterialToKeychain:self.manateeZoneID]; + [self saveTLKMaterialToKeychain:self.autoUnlockZoneID]; + [self saveTLKMaterialToKeychain:self.healthZoneID]; + [self saveTLKMaterialToKeychain:self.applepayZoneID]; + [self saveTLKMaterialToKeychain:self.homeZoneID]; + [self saveTLKMaterialToKeychain:self.limitedZoneID]; +} + +- (void)deleteTLKMaterialsFromKeychain{ + [self deleteTLKMaterialFromKeychain: self.engramZoneID]; + [self deleteTLKMaterialFromKeychain: self.manateeZoneID]; + [self deleteTLKMaterialFromKeychain: self.autoUnlockZoneID]; + [self deleteTLKMaterialFromKeychain: self.healthZoneID]; + [self deleteTLKMaterialFromKeychain: self.applepayZoneID]; + [self deleteTLKMaterialFromKeychain: self.homeZoneID]; + [self deleteTLKMaterialFromKeychain:self.limitedZoneID]; +} + +- (void)waitForKeyHierarchyReadinesses { + [self.manateeView waitForKeyHierarchyReadiness]; + [self.engramView waitForKeyHierarchyReadiness]; + [self.autoUnlockView waitForKeyHierarchyReadiness]; + [self.healthView waitForKeyHierarchyReadiness]; + [self.applepayView waitForKeyHierarchyReadiness]; + [self.homeView waitForKeyHierarchyReadiness]; + [self.limitedView waitForKeyHierarchyReadiness]; +} + +- (void)expectCKKSTLKSelfShareUploads { + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self expectCKKSTLKSelfShareUpload:zoneID]; + } + +} + +@end + +@interface CloudKitKeychainSyncingMultiZoneTests : CloudKitKeychainSyncingMultiZoneTestsBase +@end + +@implementation CloudKitKeychainSyncingMultiZoneTests + +- (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]; + [self performOctagonTLKUpload:self.ckksViews]; + + 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. + + [self startCKKSSubsystem]; + + XCTestExpectation* engramChanged = [self expectChangeForView:self.engramZoneID.zoneName]; + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + XCTestExpectation* manateeChanged = [self expectChangeForView:self.manateeZoneID.zoneName]; + + // We expect a single record to be uploaded to the engram view. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.engramZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-engram" viewHint:(NSString*) kSecAttrViewHintEngram]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations:@[engramChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:1]; + + pcsChanged = [self expectChangeForView:@"PCS"]; + + // We expect a single record to be uploaded to the manatee view. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-manatee" viewHint:(NSString*) kSecAttrViewHintManatee]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations:@[manateeChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:1]; +} + +- (void)testAddAutoUnlockItems { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + XCTestExpectation* autoUnlockChanged = [self expectChangeForView:self.autoUnlockZoneID.zoneName]; + // AutoUnlock is NOT is PCS view, so it should not send the fake 'PCS' view notification + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + pcsChanged.inverted = YES; + + // We expect a single record to be uploaded to the AutoUnlock view. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.autoUnlockZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintAutoUnlock]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations:@[autoUnlockChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:0.2]; +} + +- (void)testAddHealthItems { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + XCTestExpectation* healthChanged = [self expectChangeForView:self.healthZoneID.zoneName]; + // Health is NOT is PCS view, so it should not send the fake 'PCS' view notification + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + pcsChanged.inverted = YES; + + // We expect a single record to be uploaded to the Health view. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.healthZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintHealth]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations:@[healthChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:0.2]; +} + +- (void)testAddApplePayItems { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + XCTestExpectation* applepayChanged = [self expectChangeForView:self.applepayZoneID.zoneName]; + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + + // We expect a single record to be uploaded to the ApplePay view. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.applepayZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-autounlock" viewHint:(NSString*) kSecAttrViewHintApplePay]; + + 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 a now PCS view, so it should send the fake 'PCS' view notification + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + + // We expect a single record to be uploaded to the 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)testAddLimitedPeersAllowedItems { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + XCTestExpectation* limitedChanged = [self expectChangeForView:self.limitedZoneID.zoneName]; + // LimitedPeersAllowed is a PCS view, so it should send the fake 'PCS' view notification + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + + // We expect a single record to be uploaded to the LimitedPeersOkay view. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.limitedZoneID]; + [self addGenericPassword: @"data" account: @"account-delete-me-limited-peers" viewHint:(NSString*) kSecAttrViewHintLimitedPeersAllowed]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForExpectations:@[limitedChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:0.2]; +} + +- (void)testAddOtherViewHintItem { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + + [self startCKKSSubsystem]; + + // We expect no uploads to CKKS. + [self addGenericPassword: @"data" account: @"account-delete-me-no-viewhint"]; + [self addGenericPassword: @"data" account: @"account-delete-me-password" viewHint:(NSString*) kSOSViewAutofillPasswords]; + + sleep(1); + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testReceiveItemInView { + [self saveFakeKeyHierarchiesToLocalDatabase]; // Make life easy for this test. + [self startCKKSSubsystem]; + + for(CKRecordZoneID* zoneID in self.ckksZones) { + [self expectCKKSTLKSelfShareUpload:zoneID]; + } + + [self waitForKeyHierarchyReadinesses]; + + [self findGenericPassword:@"account-delete-me" expecting:errSecItemNotFound]; + + CKRecord* ckr = [self createFakeRecord:self.engramZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85"]; + [self.engramZone addToZone: ckr]; + + XCTestExpectation* engramChanged = [self expectChangeForView:self.engramZoneID.zoneName]; + XCTestExpectation* pcsChanged = [self expectChangeForView:@"PCS"]; + + // Trigger a notification (with hilariously fake data) + [self.engramView notifyZoneChange:nil]; + + [self.engramView waitForFetchAndIncomingQueueProcessing]; + [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; + + [self waitForExpectations:@[engramChanged] timeout:1]; + [self waitForExpectations:@[pcsChanged] timeout:1]; +} + +- (void)testRecoverFromCloudKitOldChangeTokenInKeyHierarchyFetch { + [self putFakeKeyHierachiesInCloudKit]; + [self saveTLKsToKeychain]; + + + [self expectCKKSTLKSelfShareUploads]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + [self waitForKeyHierarchyReadinesses]; + + // We expect a single record to be uploaded + [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" viewHint:(id)kSecAttrViewHintManatee]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + // Delete all old database states, to destroy the change tag validity + [self.manateeZone.pastDatabases removeAllObjects]; + + // We expect a total local flush and refetch + self.silentFetchesAllowed = false; + [self expectCKFetch]; // one to fail with a CKErrorChangeTokenExpired error + [self expectCKFetch]; // and one to succeed + + [self.manateeView dispatchSyncWithAccountKeys: ^bool { + [self.manateeView _onqueueKeyStateMachineRequestFetch]; + return true; + }]; + + XCTAssertEqual(0, [self.manateeView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS should enter 'ready'"); + + [self.manateeView waitForFetchAndIncomingQueueProcessing]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + // And check that a new upload happens just fine. + [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.manateeZoneID checkItem: [self checkClassABlock:self.manateeZoneID message:@"Object was encrypted under class A key in hierarchy"]]; + [self addGenericPassword:@"asdf" + account:@"account-class-A" + viewHint:(id)kSecAttrViewHintManatee + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testResetAllCloudKitZones { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + + [self putFakeKeyHierachiesInCloudKit]; + [self saveTLKsToKeychain]; + [self expectCKKSTLKSelfShareUploads]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + [self waitForKeyHierarchyReadinesses]; + + // We expect a single record to be uploaded + [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" viewHint:(id)kSecAttrViewHintManatee]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + // During the reset, Octagon will upload the key hierarchy, and then CKKS will upload the class C item + + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.manateeZoneID checkItem:[self checkClassCBlock:self.manateeZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + // CKKS should issue exactly one deletion for all of these + self.silentZoneDeletesAllowed = true; + + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-all-test" reply:^(NSError* result) { + XCTAssertNil(result, "no error resetting cloudkit"); + secnotice("ckks", "Received a resetCloudKit callback"); + [resetExpectation fulfill]; + }]; + + // Sneak in and perform Octagon's duties + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + + [self waitForExpectations:@[resetExpectation] timeout:20]; + + 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"]]; + [self addGenericPassword:@"asdf" + account:@"account-class-A" + viewHint:(id)kSecAttrViewHintManatee + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testResetAllCloudKitZonesWithPartialZonesMissing { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + + [self putFakeKeyHierachiesInCloudKit]; + [self saveTLKsToKeychain]; + [self expectCKKSTLKSelfShareUploads]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + [self waitForKeyHierarchyReadinesses]; + + // We expect a single record to be uploaded + [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" viewHint:(id)kSecAttrViewHintManatee]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + self.zones[self.manateeZoneID] = nil; + self.keys[self.manateeZoneID] = nil; + self.zones[self.applepayZoneID] = nil; + self.keys[self.applepayZoneID] = nil; + + // During the reset, Octagon will upload the key hierarchy, and then CKKS will upload the class C item + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.manateeZoneID checkItem:[self checkClassCBlock:self.manateeZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + // CKKS should issue exactly one deletion for all of these + self.silentZoneDeletesAllowed = true; + + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-all-test" reply:^(NSError* result) { + XCTAssertNil(result, "no error resetting cloudkit"); + secnotice("ckks", "Received a resetCloudKit callback"); + [resetExpectation fulfill]; + }]; + + // Sneak in and perform Octagon's duties + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + + [self waitForExpectations:@[resetExpectation] timeout:20]; + + 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"]]; + [self addGenericPassword:@"asdf" + account:@"account-class-A" + viewHint:(id)kSecAttrViewHintManatee + access:(id)kSecAttrAccessibleWhenUnlocked + expecting:errSecSuccess + message:@"Adding class A item"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testResetMultiCloudKitZoneCloudKitRejects { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + + [self putFakeKeyHierachiesInCloudKit]; + [self saveTLKsToKeychain]; + [self expectCKKSTLKSelfShareUploads]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + [self waitForKeyHierarchyReadinesses]; + + // We expect a single record to be uploaded + [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" viewHint:(id)kSecAttrViewHintManatee]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + self.nextModifyRecordZonesError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain + code:CKErrorZoneBusy + userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + NSUnderlyingErrorKey: [[CKPrettyError alloc] initWithDomain:CKErrorDomain + code:2029 + userInfo:nil], + }]; + self.silentZoneDeletesAllowed = true; + + // During the reset, Octagon will upload the key hierarchy, and then CKKS will upload the class C item + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.manateeZoneID checkItem:[self checkClassCBlock:self.manateeZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + + XCTestExpectation* resetExpectation = [self expectationWithDescription: @"reset callback occurs"]; + [self.injectedManager rpcResetCloudKit:nil reason:@"reset-test" reply:^(NSError* result) { + XCTAssertNil(result, "no error resetting cloudkit"); + secnotice("ckks", "Received a resetCloudKit callback"); + [resetExpectation fulfill]; + }]; + + // Sneak in and perform Octagon's duties + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + + [self waitForExpectations:@[resetExpectation] timeout:20]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + XCTAssertNil(self.nextModifyRecordZonesError, "zone modification error should have been cleared"); +} + +- (void)testMultiZoneDeviceStateUploadGood { + [self putFakeKeyHierachiesInCloudKit]; + [self saveTLKsToKeychain]; + [self expectCKKSTLKSelfShareUploads]; + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + [self waitForKeyHierarchyReadinesses]; + + for(CKKSKeychainView* view in self.ckksViews) { + [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:view.zoneID + checkModifiedRecord:nil + runAfterModification:nil]; + } + + [self.injectedManager xpc24HrNotification]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +@end + +#endif // OCTAGON + diff --git a/keychain/ckks/tests/CKKSTests.h b/keychain/ckks/tests/CKKSTests.h index 1fcb10a9..456c178d 100644 --- a/keychain/ckks/tests/CKKSTests.h +++ b/keychain/ckks/tests/CKKSTests.h @@ -28,6 +28,7 @@ #import #include +#include "OSX/sec/Security/SecItemShim.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h" diff --git a/keychain/ckks/tests/CKKSTests.m b/keychain/ckks/tests/CKKSTests.m index a0147c12..58bb0e16 100644 --- a/keychain/ckks/tests/CKKSTests.m +++ b/keychain/ckks/tests/CKKSTests.m @@ -33,7 +33,7 @@ #include #include #include -#include +#include "keychain/SecureObjectSync/SOSInternal.h" #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h" @@ -52,10 +52,12 @@ #import "keychain/ckks/CKKSHealKeyHierarchyOperation.h" #import "keychain/ckks/CKKSZoneChangeFetcher.h" #import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ckks/CKKSPeer.h" #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/tests/CKKSTests.h" +#import // break abstraction @interface CKKSLockStateTracker () @@ -363,6 +365,7 @@ [self.keychainView waitForFetchAndIncomingQueueProcessing]; self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; [self.keychainView waitForKeyHierarchyReadiness]; OCMVerifyAllWithDelay(self.mockDatabase, 20); } @@ -376,7 +379,9 @@ // We expect a single record to be uploaded, but need to hold the operation from finishing until we can modify the item locally - NSError* greyMode = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNotAuthenticated userInfo:@{}]; + NSError* greyMode = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNotAuthenticated userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + }]; [self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID blockAfterReject:nil withError:greyMode]; [self addGenericPassword: @"data" account: account]; @@ -486,6 +491,53 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } +- (void)testDeleteItemWithoutTombstones { + // The keychain API allows a client to ask for an inconsistent sync state: + // They can ask for a local item deletion without propagating the deletion off-device. + // This is the only halfway reasonable way to do keychain item deletions on account signout with the current API + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + NSString* account = @"account-delete-me"; + + [self startCKKSSubsystem]; + + // We expect a single record to be uploaded. + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + [self addGenericPassword: @"data" account: account]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; + + [self deleteGenericPasswordWithoutTombstones:account]; + [self findGenericPassword:account expecting:errSecItemNotFound]; + + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; + + // Ensure nothing is in the outgoing queue + [self.keychainView dispatchSync:^bool { + NSError* error = nil; + NSArray* uuids = [CKKSOutgoingQueueEntry allUUIDs:self.keychainZoneID + error:&error]; + XCTAssertNil(error, "should be no error fetching uuids"); + XCTAssertEqual(uuids.count, 0u, "There should be zero OQEs"); + return false; + }]; + + // And a simple fetch doesn't bring it back + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + [self findGenericPassword:account expecting:errSecItemNotFound]; + + // but a resync does + CKKSSynchronizeOperation* resyncOperation = [self.keychainView resyncWithCloud]; + [resyncOperation waitUntilFinished]; + XCTAssertNil(resyncOperation.error, "No error during the resync operation"); + + + [self findGenericPassword:account expecting:errSecSuccess]; + + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + - (void)testReceiveItem { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -580,7 +632,7 @@ [self expectCKDeleteItemRecords:1 zoneID:self.keychainZoneID]; // Trigger a notification (with hilariously fake data) - [self.keychainView notifyZoneChange:nil]; + [self.keychainView notifyZoneChange:nil];; OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(errSecSuccess, SecItemCopyMatching((__bridge CFDictionaryRef) query, &item), "item should exist now"); @@ -948,19 +1000,87 @@ [self expectCKModifyItemRecords: SecCKKSOutgoingQueueItemsAtOnce currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self expectCKModifyItemRecords: 50 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; - OCMVerifyAllWithDelay(self.mockDatabase, 20); + OCMVerifyAllWithDelay(self.mockDatabase, 40); } - (void)testUploadInitialKeyHierarchy { - // 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]; + // Test starts with nothing in database. CKKS should get into the "please upload my keys" state, then Octagon should perform the upload // Spin up CKKS subsystem. [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); +} + +- (void)testDoNotErrorIfNudgedWhileWaitingForTLKUpload { + // Test starts with nothing in database. CKKS should get into the "please upload my keys" state, then Octagon should perform the upload + + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + NSMutableArray*>* keysetOps = [NSMutableArray array]; + + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:40*NSEC_PER_SEC], @"key state should enter 'waitfortlkcreation' (view %@)", view); + [keysetOps addObject: [view findKeySet]]; + } + + // Now that we've kicked them all off, wait for them to resolve (and nudge each one, as if a key was saved) + for(CKKSKeychainView* view in self.ckksViews) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKUpload] wait:40*NSEC_PER_SEC], @"key state should enter 'waitfortlkupload'"); + + CKKSCondition* viewProcess = view.keyHierarchyConditions[SecCKKSZoneKeyStateProcess]; + [view keyStateMachineRequestProcess]; + XCTAssertNotEqual(0, [viewProcess wait:500*NSEC_PER_MSEC], "CKKS should not reprocess the key hierarchy, even if nudged"); + } + + // The views should remain in waitfortlkcreation, and not go through process into an error + + NSMutableArray* keyHierarchyRecords = [NSMutableArray array]; + + for(CKKSResultOperation* keysetOp in keysetOps) { + // Wait until finished is usually a bad idea. We could rip this out into an operation if we'd like. + [keysetOp waitUntilFinished]; + XCTAssertNil(keysetOp.error, "Should be no error fetching keyset from CKKS"); + + NSArray* records = [self putKeySetInCloudKit:keysetOp.keyset]; + [keyHierarchyRecords addObjectsFromArray:records]; + } + + // Tell our views about our shiny new records! + for(CKKSKeychainView* view in self.ckksViews) { + [view receiveTLKUploadRecords: keyHierarchyRecords]; + } + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); +} + +- (void)testProvideKeysetFromNoTrust { + + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortlkcreation'"); + // I'm not sure how CKKS ends up in 'waitfortrust' without a keyset, so force that state + // In 52301278, it occurred with some complex interaction of zone deletions, fetches, and trust operations + [self.keychainView dispatchSyncWithAccountKeys:^bool{ + [self.keychainView _onqueueAdvanceKeyStateMachineToState:SecCKKSZoneKeyStateWaitForTrust withError:nil]; + return true; + }]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], @"Key state should become 'waitfortrust'"); + + CKKSResultOperation* keysetOp = [self.keychainView findKeySet]; + [keysetOp timeout:20*NSEC_PER_SEC]; + [keysetOp waitUntilFinished]; + + XCTAssertNil(keysetOp.error, "Should be no error fetching a keyset"); } +// This test no longer is very interesting, since Octagon needs to handle lock states, not CKKS... - (void)testUploadInitialKeyHierarchyAfterLockedStart { // 'Lock' the keybag self.aksLockState = true; @@ -969,15 +1089,13 @@ [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:20*NSEC_PER_SEC], @"Key state should get stuck in waitforunlock"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitfortlkcreation"); // After unlock, the key hierarchy should be created. - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - self.aksLockState = false; [self.lockStateTracker recheck]; - OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self performOctagonTLKUpload:self.ckksViews]; // 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"]]; @@ -988,22 +1106,13 @@ - (void)testLockImmediatelyAfterUploadingInitialKeyHierarchy { - // Upon upload, block fetches __weak __typeof(self) weakSelf = self; - [self expectCKModifyRecords: @{ - SecCKRecordIntermediateKeyType: [NSNumber numberWithUnsignedInteger: 3], - SecCKRecordCurrentKeyType: [NSNumber numberWithUnsignedInteger: 3], - SecCKRecordTLKShareType: [NSNumber numberWithUnsignedInteger: 1], - } - deletedRecordTypeCounts:nil - zoneID:self.keychainZoneID - checkModifiedRecord:nil - runAfterModification:^{ - __strong __typeof(self) strongSelf = weakSelf; - [strongSelf holdCloudKitFetches]; - }]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews afterUpload:^{ + __strong __typeof(self) strongSelf = weakSelf; + [strongSelf holdCloudKitFetches]; + }]; // Should enter 'ready' XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -1041,7 +1150,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:20*NSEC_PER_SEC], @"Key state should get stuck in fetchcomplete"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], @"Key state should get stuck in waitfortlkcreation"); // Now, another device comes along and creates the hierarchy; we download it; and it and sends us the TLK [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -1085,10 +1194,8 @@ } - (void)testUploadAndUseKeyHierarchy { - // 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]; - [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; NSDictionary *query = @{(id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", @@ -1123,20 +1230,21 @@ } - (void)testUploadInitialKeyHierarchyTriggersBackup { - // 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]; - // We also expect the view manager's notifyNewTLKsInKeychain call to fire (after some delay) OCMExpect([self.mockCKKSViewManager notifyNewTLKsInKeychain]); // Spin up CKKS subsystem. [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); OCMVerifyAllWithDelay(self.mockCKKSViewManager, 10); } - (void)testResetCloudKitZoneFromNoTLK { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + self.silentZoneDeletesAllowed = true; // If CKKS sees a zone it's never going to be able to read, it should reset that zone @@ -1144,13 +1252,13 @@ // explicitly do not save a fake device status here self.keychainZone.flag = true; - // It'll eventually upload a new key hierarchy - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; - [self startCKKSSubsystem]; 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' + // But then, it'll fire off the reset and reach 'ready', with a little help from octagon + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -1159,12 +1267,16 @@ } - (void)testResetCloudKitZoneFromNoTLKWithOtherWaitForTLKDevices { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + self.silentZoneDeletesAllowed = true; // If CKKS sees a zone it's never going to be able to read, it should reset that zone [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; // Save a fake device status here, but modify its key state to be 'waitfortlk': it has no idea what the TLK is either [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self putFakeOctagonOnlyDeviceStatusInCloudKit:self.keychainZoneID]; for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { if([record.recordType isEqualToString:SecCKRecordDeviceStateType]) { @@ -1174,12 +1286,12 @@ self.keychainZone.flag = true; - // It'll eventually upload a new key hierarchy - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; - [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + // But then, it'll fire off the reset and reach 'ready' OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -1189,17 +1301,22 @@ } - (void)testResetCloudKitZoneFromNoTLKIgnoringInactiveDevices { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + self.silentZoneDeletesAllowed = true; // If CKKS sees a zone it's never going to be able to read, it should reset that zone [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; // Save a fake device status here, but modify its creation and modification times to be months ago [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + [self putFakeOctagonOnlyDeviceStatusInCloudKit:self.keychainZoneID]; // Put a 'in-circle' TLKShare record, but also modify its creation and modification times CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"untrusted-peer" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; [self putTLKShareInCloudKit:self.keychainZoneKeys.tlk from:untrustedPeer to:untrustedPeer zoneID:self.keychainZoneID]; for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { @@ -1211,12 +1328,12 @@ self.keychainZone.flag = true; - // It'll eventually upload a new key hierarchy - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; - [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + // But then, it'll fire off the reset and reach 'ready' OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -1225,12 +1342,37 @@ XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); } +- (void)testDoNotResetCloudKitZoneDuringBadCircleState { + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + // This test has stuff in CloudKit, but no TLKs. + // CKKS should NOT reset the CK zone. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + self.zones[self.keychainZoneID].flag = true; + + [self startCKKSSubsystem]; + + // But since we're out of circle, this test needs to initialize the zone itself + [self.keychainView beginCloudKitOperation]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "CKKS entered waitfortrust"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + FakeCKZone* keychainZone = self.zones[self.keychainZoneID]; + XCTAssertNotNil(keychainZone, "Should still have a keychain zone"); + XCTAssertTrue(keychainZone.flag, "keychain zone should not have been recreated"); +} + - (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToRecentDeviceState { [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; // CKKS shouldn't reset this zone, due to a recent device status claiming to have TLKs [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; + // Also, CKKS _should_ be able to return the key hierarchy if asked before it starts + CKKSResultOperation* keysetOp = [self.keychainView findKeySet]; + NSDateComponents* offset = [[NSDateComponents alloc] init]; [offset setDay:-5]; NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; @@ -1247,6 +1389,19 @@ 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 that the keyset op ran and has results + CKKSResultOperation* waitOp = [CKKSResultOperation named:@"test op" withBlock:^{}]; + [waitOp addDependency:keysetOp]; + [waitOp timeout:2*NSEC_PER_SEC]; + [self.operationQueue addOperation:waitOp]; + [waitOp waitUntilFinished]; + + XCTAssert(keysetOp.finished, "Keyset op should have finished"); + XCTAssertNil(keysetOp.error, "keyset op should not have errored"); + XCTAssertNotNil(keysetOp.keyset, "keyset op should have a keyset"); + XCTAssertNotNil(keysetOp.keyset.currentTLKPointer, "keyset should have a current TLK pointer"); + XCTAssertEqualObjects(keysetOp.keyset.currentTLKPointer.currentKeyUUID, self.keychainZoneKeys.tlk.uuid, "keyset should match what's in zone"); } - (void)testDoNotCloudKitZoneFromWaitForTLKDueToRecentButUntrustedDeviceState { @@ -1255,7 +1410,7 @@ // CKKS should reset this zone, even though to a recent device status claiming to have TLKs. The device isn't trusted self.silentZoneDeletesAllowed = true; [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; - [self.currentPeers removeObject:self.remoteSOSOnlyPeer]; + [self.mockSOSAdapter.trustedPeers removeObject:self.remoteSOSOnlyPeer]; self.keychainZone.flag = true; [self startCKKSSubsystem]; @@ -1268,12 +1423,15 @@ } - (void)testResetCloudKitZoneFromWaitForTLKDueToLessRecentAndUntrustedDeviceState { + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMExpect([self.suggestTLKUpload trigger]); + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; // CKKS should reset this zone, even though to a recent device status claiming to have TLKs. The device isn't trusted self.silentZoneDeletesAllowed = true; [self putFakeDeviceStatusInCloudKit:self.keychainZoneID]; - [self.currentPeers removeObject:self.remoteSOSOnlyPeer]; + [self.mockSOSAdapter.trustedPeers removeObject:self.remoteSOSOnlyPeer]; NSDateComponents* offset = [[NSDateComponents alloc] init]; [offset setDay:-5]; @@ -1286,10 +1444,12 @@ } self.keychainZone.flag = true; - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:20*NSEC_PER_SEC], @"Key state should become 'resetzone'"); + OCMVerifyAllWithDelay(self.suggestTLKUpload, 10); + [self performOctagonTLKUpload:self.ckksViews]; + // Then we should reset. OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -1298,33 +1458,6 @@ XCTAssertFalse(self.keychainZone.flag, "Zone flag should have been reset to false"); } -- (void)testDoNotResetCloudKitZoneFromWaitForTLKDueToAncientOctagonDeviceState { - [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; - - // CKKS should not reset this zone, because some Octagon device appeared on this account ever - self.silentZoneDeletesAllowed = true; - [self putFakeOctagonOnlyDeviceStatusInCloudKit:self.keychainZoneID]; - - NSDateComponents* offset = [[NSDateComponents alloc] init]; - [offset setDay:-46]; - NSDate* updateTime = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:[NSDate date] options:0]; - for(CKRecord* record in self.keychainZone.currentDatabase.allValues) { - if([record.recordType isEqualToString:SecCKRecordDeviceStateType] || [record.recordType isEqualToString:SecCKRecordTLKShareType]) { - record.creationDate = updateTime; - record.modificationDate = updateTime; - } - } - - self.keychainZone.flag = true; - [self startCKKSSubsystem]; - - 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' - XCTAssertNotEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateResettingZone] wait:100*NSEC_PER_MSEC], @"Key state should not become 'resetzone'"); -} - - (void)testAcceptExistingKeyHierarchy { // 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) @@ -1368,7 +1501,7 @@ self.keychainZone.flag = true; [self startCKKSSubsystem]; - XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:20*NSEC_PER_SEC], "Key state should have become waitfortlk"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLK] wait:200*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]; @@ -1490,8 +1623,8 @@ } - (void)testRestartWhileLocked { - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); @@ -1501,6 +1634,8 @@ [self.keychainView halt]; self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self.keychainView beginCloudKitOperation]; + [self beginSOSTrustedViewOperation:self.keychainView]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], @"Key state should become 'readypendingunlock'"); @@ -1780,13 +1915,11 @@ SecCKKSTestSetDisableAutomaticUUID(false); [self addGenericPassword: @"data" account: @"account-delete-me-with-UUID" expecting:errSecSuccess message: @"Add item (w/ UUID) to keychain"]; - // We expect an upload of the key hierarchy - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - // We then expect an upload of the added items [self expectCKModifyItemRecords: 2 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); } @@ -1870,12 +2003,14 @@ [self addGenericPassword: @"data" account: @"second"]; [self addGenericPassword: @"data" account: @"third"]; [self addGenericPassword: @"data" account: @"fourth"]; - NSUInteger passwordCount = 4u; + [self addGenericPassword: @"data" account: @"fifth"]; + NSUInteger passwordCount = 5u; [self checkGenericPassword: @"data" account: @"first"]; [self checkGenericPassword: @"data" account: @"second"]; [self checkGenericPassword: @"data" account: @"third"]; [self checkGenericPassword: @"data" account: @"fourth"]; + [self checkGenericPassword: @"data" account: @"fifth"]; [self expectCKModifyItemRecords: passwordCount currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; @@ -1951,7 +2086,17 @@ NSString* insyncAccount = [[self decryptRecord: items[3]] objectForKey: (__bridge id) kSecAttrAccount]; XCTAssertNotNil(insyncAccount, "Received an account for the in-sync object"); - // The fifth record gets magically added to CloudKit, but CKKS has never heard of it + // The fifth record is updated locally, but CKKS didn't get the notification, and so the local CKMirror and CloudKit don't have it + // Expected outcome: local change should be steamrolled by the cloud version + CKRecord* localDataChanged = items[4]; + NSMutableDictionary* localDataDictionary = [[self decryptRecord: localDataChanged] mutableCopy]; + NSString* localDataChangedAccount = [localDataDictionary objectForKey: (__bridge id) kSecAttrAccount]; + SecCKKSDisable(); + [self updateGenericPassword:@"newpassword" account:localDataChangedAccount]; + [self checkGenericPassword:@"newpassword" account:localDataChangedAccount]; + SecCKKSEnable(); + + // The sixth record gets magically added to CloudKit, but CKKS has never heard of it // (emulates a lost record on the client, but that CloudKit already believes it's sent the record for) // Expected outcome: added to local keychain NSString* remoteOnlyAccount = @"remote-only"; @@ -1965,6 +2110,7 @@ ckksnotice("ckksresync", self.keychainView, "Remote deletion: %@ %@", remoteDelete.recordID.recordName, remoteDeleteAccount); ckksnotice("ckksresync", self.keychainView, "Remote data changed: %@ %@", remoteDataChanged.recordID.recordName, remoteDataChangedAccount); ckksnotice("ckksresync", self.keychainView, "in-sync: %@ %@", items[3].recordID.recordName, insyncAccount); + ckksnotice("ckksresync", self.keychainView, "local update: %@ %@", items[4].recordID.recordName, localDataChangedAccount); ckksnotice("ckksresync", self.keychainView, "Remote only: %@ %@", ckr.recordID.recordName, remoteOnlyAccount); CKKSSynchronizeOperation* resyncOperation = [self.keychainView resyncWithCloud]; @@ -1978,12 +2124,14 @@ [self findGenericPassword: remoteDeleteAccount expecting: errSecItemNotFound]; [self findGenericPassword: remoteDataChangedAccount expecting: errSecSuccess]; [self findGenericPassword: insyncAccount expecting: errSecSuccess]; + [self findGenericPassword: localDataChangedAccount expecting: errSecSuccess]; [self findGenericPassword: remoteOnlyAccount expecting: errSecSuccess]; [self checkGenericPassword: @"data" account: deleteAccount]; //[self checkGenericPassword: @"data" account: remoteDeleteAccount]; [self checkGenericPassword: @"CloudKitWins" account: remoteDataChangedAccount]; [self checkGenericPassword: @"data" account: insyncAccount]; + [self checkGenericPassword:@"data" account:localDataChangedAccount]; [self checkGenericPassword: @"data" account: remoteOnlyAccount]; [self.keychainView dispatchSync:^bool{ @@ -2008,6 +2156,10 @@ XCTAssertNil(error); XCTAssertNotNil(ckme); + ckme = [CKKSMirrorEntry tryFromDatabase:items[4].recordID.recordName zoneID:strongSelf.keychainZoneID error:&error]; + XCTAssertNil(error); + XCTAssertNotNil(ckme); + ckme = [CKKSMirrorEntry tryFromDatabase:ckr.recordID.recordName zoneID:strongSelf.keychainZoneID error:&error]; XCTAssertNil(error); XCTAssertNotNil(ckme); @@ -2100,6 +2252,48 @@ [self findGenericPassword: @"fourth" expecting: errSecSuccess]; } +- (void)testScanItemsChangedInLocalKeychain { + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + + // Add and sync two passwords + NSString* itemAccount = @"first"; + [self addGenericPassword:@"data" account:itemAccount]; + [self addGenericPassword:@"data" account:@"second"]; + + [self checkGenericPassword:@"data" account:itemAccount]; + [self checkGenericPassword:@"data" account:@"second"]; + + [self expectCKModifyItemRecords:2 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + [self startCKKSSubsystem]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + [self.keychainView waitForFetchAndIncomingQueueProcessing]; + + [self.keychainView waitForOperationsOfClass:[CKKSScanLocalItemsOperation class]]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; + + // Now, have CKKS miss an update + SecCKKSDisable(); + [self updateGenericPassword:@"newpassword" account:itemAccount]; + [self checkGenericPassword:@"newpassword" account:itemAccount]; + SecCKKSEnable(); + + // Now, where are we.... + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem:[self checkPasswordBlock:self.keychainZoneID account:itemAccount password:@"newpassword"]]; + + CKKSScanLocalItemsOperation* scanLocal = [self.keychainView scanLocalItems:@"test-scan"]; + [scanLocal waitUntilFinished]; + + XCTAssertEqual(scanLocal.recordsAdded, 1u, "Should have added a single record"); + + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + // And ensure that all four items are present again + [self findGenericPassword: @"first" expecting: errSecSuccess]; + [self findGenericPassword: @"second" expecting: errSecSuccess]; +} + - (void)testResyncLocal { [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; @@ -2190,19 +2384,17 @@ } - (void)testMultipleZoneAdd { - // 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]; - // Bring up a new zone: we expect a key hierarchy upload. - [self.injectedManager findOrCreateView:(id)kSecAttrViewHintAppleTV]; + CKKSKeychainView* atvView = [self.injectedManager findOrCreateView:(id)kSecAttrViewHintAppleTV]; + [self.ckksViews addObject:atvView]; CKRecordZoneID* appleTVZoneID = [[CKRecordZoneID alloc] initWithZoneName:(__bridge NSString*) kSecAttrViewHintAppleTV ownerName:CKCurrentUserDefaultName]; - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:appleTVZoneID]; // We also expect the view manager's notifyNewTLKsInKeychain call to fire once (after some delay) OCMExpect([self.mockCKKSViewManager notifyNewTLKsInKeychain]); // Let the horses loose [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; // We expect a single record to be uploaded to the 'keychain' view [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID]; @@ -2223,22 +2415,23 @@ } - (void)testMultipleZoneDelete { - // 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]; - [self startCKKSSubsystem]; + // Bring up a new zone: we expect a key hierarchy and an item. + CKKSKeychainView* atvView = [self.injectedManager findOrCreateView:(id)kSecAttrViewHintAppleTV]; + XCTAssertNotNil(atvView, "Should have a new ATV view"); + [self.ckksViews addObject:atvView]; + [self beginSOSTrustedViewOperation:atvView]; + CKRecordZoneID* appleTVZoneID = [[CKRecordZoneID alloc] initWithZoneName:(__bridge NSString*) kSecAttrViewHintAppleTV ownerName:CKCurrentUserDefaultName]; + + [self performOctagonTLKUpload:self.ckksViews]; + // 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, 20); - // Bring up a new zone: we expect a key hierarchy and an item. - [self.injectedManager findOrCreateView:(id)kSecAttrViewHintAppleTV]; - CKRecordZoneID* appleTVZoneID = [[CKRecordZoneID alloc] initWithZoneName:(__bridge NSString*) kSecAttrViewHintAppleTV ownerName:CKCurrentUserDefaultName]; - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:appleTVZoneID]; [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:appleTVZoneID]; - [self addGenericPassword: @"atv" account: @"tvaccount" viewHint:(__bridge NSString*) kSecAttrViewHintAppleTV @@ -2260,21 +2453,21 @@ - (void)testRestartWithoutRefetch { // Restarting the CKKS operation should check that it's been 15 minutes since the last fetch before it fetches again. Simulate this. - - // 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]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; - [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should arrive at ready"); + // Tear down the CKKS object and disallow fetches [self.keychainView halt]; self.silentFetchesAllowed = false; self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; - [self.keychainView waitForKeyHierarchyReadiness]; + [self beginSOSTrustedViewOperation:self.keychainView]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should arrive at ready"); 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 @@ -2296,6 +2489,7 @@ [self expectCKFetch]; self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; [self.keychainView waitForKeyHierarchyReadiness]; OCMVerifyAllWithDelay(self.mockDatabase, 20); } @@ -2308,10 +2502,8 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - // The CKKS subsystem should figure out the issue, and fix it. - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; - - [self.keychainView waitForKeyHierarchyReadiness]; + // CKKS should figure it out, and fix it + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID @@ -2329,8 +2521,8 @@ // Spin up CKKS subsystem. [self startCKKSSubsystem]; - // The CKKS subsystem should figure out the issue, and fix it. - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + // The CKKS subsystem should figure out the issue, and fix it before Octagon uploads its items + [self performOctagonTLKUpload:self.ckksViews]; [self.keychainView waitForKeyHierarchyReadiness]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -2354,9 +2546,9 @@ [self startCKKSSubsystem]; // The CKKS subsystem should figure out the issue, and fix it. - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + [self performOctagonTLKUpload:self.ckksViews]; - [self.keychainView waitForKeyHierarchyReadiness]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should arrive at ready"); OCMVerifyAllWithDelay(self.mockDatabase, 20); [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID @@ -2417,6 +2609,7 @@ XCTAssertNil(error, "Should have received no error deleting the new TLK from the keychain"); self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; [self.keychainView waitForKeyHierarchyReadiness]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -2428,6 +2621,8 @@ [self checkNSyncableTLKsInKeychain: 1]; } +/* + // Octagon: tests for CK exceptions out of cuttlefish - (void)testRecoverFromTLKWriteFailure { // We need to handle the case where a device's first TLK write doesn't go through (due to whatever reason). // Test starts with nothing in CloudKit, and will fail the first TLK write. @@ -2450,7 +2645,11 @@ // A network failure creating new TLKs shouldn't delete the 'failed' syncable one. [self checkNSyncableTLKsInKeychain: 2]; } + */ +// This test needs to be moved and rewritten now that Octagon handles TLK uploads +// Octagon: tests for CK exceptions out of cuttlefish +/* - (void)testRecoverFromTLKRace { // We need to handle the case where a device's first TLK write doesn't go through (due to whatever reason). // Test starts with nothing in CloudKit, and will fail the first TLK write. @@ -2477,6 +2676,7 @@ // A race failure creating new TLKs should delete the old syncable one. [self checkNSyncableTLKsInKeychain: 1]; } + */ - (void)testRecoverFromNullCurrentKeyPointers { // The current key pointers in cloudkit shouldn't ever not exist if keys do. But, if they don't, CKKS must recover. @@ -2525,6 +2725,8 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } +/* + // Octagon: tests for CK exceptions out of cuttlefish - (void)testRecoverFromBadChangeTag { // We received a report where a machine appeared to have an up-to-date change tag, but was continuously attempting to create a new TLK hierarchy. No idea why. @@ -2560,13 +2762,13 @@ [self createClassCItemAndWaitForUpload:self.keychainZoneID account:@"account-delete-me"]; [self createClassAItemAndWaitForUpload:self.keychainZoneID account:@"account-delete-me-class-a"]; } + */ - (void)testRecoverFromDeletedKeysNewItem { - // 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]; - [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; + [self performOctagonTLKUpload:self.ckksViews]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should arrive at ready"); // We expect a single class C record to be uploaded. [self expectCKModifyItemRecords: 1 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID @@ -2582,7 +2784,7 @@ SecCKKSTestSetDisableKeyNotifications(true); XCTAssertEqual(errSecSuccess, SecItemDelete((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, }), @"Deleting local keys"); @@ -2612,11 +2814,10 @@ } - (void)testRecoverFromDeletedKeysReceive { - // 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]; - [self startCKKSSubsystem]; - [self.keychainView waitForKeyHierarchyReadiness]; + [self performOctagonTLKUpload:self.ckksViews]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should arrive at ready"); [self waitForCKModifications]; [self.keychainView waitUntilAllOperationsAreFinished]; @@ -2629,7 +2830,7 @@ SecCKKSTestSetDisableKeyNotifications(true); XCTAssertEqual(errSecSuccess, SecItemDelete((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, }), @"Deleting local keys"); @@ -2647,10 +2848,9 @@ - (void)testRecoverDeletedTLK { // If the TLK disappears halfway through, well, that's no good. But we should recover using TLK sharing - // 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]; - [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should have returned to ready"); OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -2663,7 +2863,7 @@ SecCKKSTestSetDisableKeyNotifications(true); XCTAssertEqual(errSecSuccess, SecItemDelete((__bridge CFDictionaryRef)@{ (id)kSecClass : (id)kSecClassInternetPassword, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", (id)kSecAttrSynchronizable : (id)kSecAttrSynchronizableAny, }), @"Deleting CKKS keys"); @@ -2765,6 +2965,8 @@ [self findGenericPassword:accountShouldExist expecting:errSecSuccess]; [self findGenericPassword:accountWillExist expecting:errSecItemNotFound]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReadyPendingUnlock] wait:20*NSEC_PER_SEC], "Key state should have returned to readypendingunlock"); + self.aksLockState = false; [self.lockStateTracker recheck]; @@ -2847,6 +3049,71 @@ "current Class C pointer should now point to proper Class C key"); } +- (void)testRecoverFromDesyncedKeyRecordsViaResync { + // We need to set up a desynced situation to test our resync. + // First, let CKKS start up and send several items to CloudKit (that we'll then desync!) + __block NSError* error = nil; + + // Test starts with keys in CloudKit (so we can create items later) + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + [self addGenericPassword: @"data" account: @"first"]; + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID]; + + [self startCKKSSubsystem]; + + // Wait for uploads to happen + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + // Now, delete most of the key records are from on-disk, but the change token is not changed + [self.keychainView dispatchSync:^bool{ + CKKSCurrentKeySet* keyset = [CKKSCurrentKeySet loadForZone:self.keychainZoneID]; + + XCTAssertNotNil(keyset.currentTLKPointer, @"should be a TLK pointer"); + XCTAssertNotNil(keyset.currentClassAPointer, @"should be a class A pointer"); + XCTAssertNotNil(keyset.currentClassCPointer, @"should be a class C pointer"); + + [keyset.currentTLKPointer deleteFromDatabase:&error]; + XCTAssertNil(error, "Should be no error deleting TLK pointer from database"); + [keyset.currentClassAPointer deleteFromDatabase:&error]; + XCTAssertNil(error, "Should be no error deleting class A pointer from database"); + + XCTAssertNotNil(keyset.tlk, @"should be a TLK"); + XCTAssertNotNil(keyset.classA, @"should be a classA key"); + XCTAssertNotNil(keyset.classC, @"should be a classC key"); + + [keyset.tlk deleteFromDatabase:&error]; + XCTAssertNil(error, "Should be no error deleting TLK from database"); + + [keyset.classA deleteFromDatabase:&error]; + XCTAssertNil(error, "Should be no error deleting classA from database"); + + [keyset.classC deleteFromDatabase:&error]; + XCTAssertNil(error, "Should be no error deleting classC from database"); + + return true; + }]; + + // A restart should realize there's an issue, and pause for help + // Ideally we'd try a refetch here to see if we're very wrong, but that's hard to avoid making into an infinite loop + [self.keychainView halt]; + self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self.keychainView beginCloudKitOperation]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], @"key state should enter 'waitfortlkcreation'"); + + // But, a resync should fix you back up + CKKSSynchronizeOperation* resyncOperation = [self.keychainView resyncWithCloud]; + [resyncOperation waitUntilFinished]; + XCTAssertNil(resyncOperation.error, "No error during the resync operation"); + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); +} + - (void)testRecoverFromCloudKitFetchFail { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -2889,8 +3156,7 @@ XCTAssertEqualObjects(self.keychainView.keyHierarchyState, SecCKKSZoneKeyStateReady, "CKKS entered ready"); // Network is unavailable - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; CKRecord* ckr = [self createFakeRecord: self.keychainZoneID recordName:@"7B598D31-F9C5-481E-98AC-5A507ACB2D85"]; [self.keychainZone addToZone:ckr]; @@ -2898,8 +3164,7 @@ [self findGenericPassword:@"account-delete-me" expecting:errSecItemNotFound]; // Say network is available - self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:true]; [self.keychainView waitForFetchAndIncomingQueueProcessing]; @@ -2914,8 +3179,7 @@ [self.keychainZone addToZone:ckr]; // Network is unavailable - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; // Spin up CKKS subsystem. [self startCKKSSubsystem]; @@ -2930,8 +3194,7 @@ [self findGenericPassword:@"account-delete-me" expecting:errSecItemNotFound]; // Say network is available - self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:true]; [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -2947,10 +3210,11 @@ XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:8*NSEC_PER_SEC], "CKKS entered ready"); // Network is now unavailable - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; - NSError* noNetwork = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkUnavailable userInfo:@{}]; + NSError* noNetwork = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkUnavailable userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + }]; [self failNextCKAtomicModifyItemRecordsUpdateFailure:self.keychainZoneID blockAfterReject:nil withError:noNetwork]; [self addGenericPassword: @"data" account: @"account-delete-me"]; @@ -2961,8 +3225,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.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:true]; [self findGenericPassword:@"account-delete-me" expecting:errSecSuccess]; @@ -2998,6 +3261,20 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } +- (void)testHandleZoneDeletedWhileFetching { + // Test starts with no keys in database, a key hierarchy in our fake CloudKit, and the TLK safely in the local keychain. + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + + // The first CKRecordZoneChanges should fail with a 'zone not found' error (race between zone creation as part of initalization and zone deletion from another device) + [self.keychainZone failNextFetchWith:[[NSError alloc] initWithDomain:CKErrorDomain code:CKErrorZoneNotFound userInfo:@{}]]; + + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:10*NSEC_PER_SEC], @"Key state should become 'ready'"); +} + - (void)testRecoverFromCloudKitOldChangeToken { // Test starts with nothing in database, but one in our fake CloudKit. [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; @@ -3051,7 +3328,7 @@ lastUnlockTime:[NSDate date] octagonPeerID:nil octagonStatus:nil - circlePeerID:self.circlePeerID + circlePeerID:self.mockSOSAdapter.selfPeer.peerID circleStatus:kSOSCCInCircle keyState:SecCKKSZoneKeyStateWaitForTLK currentTLKUUID:nil @@ -3134,14 +3411,16 @@ // 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 + self.keys[self.keychainZoneID] = nil; [self.keychainZone failNextFetchWith:[[NSError alloc] initWithDomain:CKErrorDomain code:CKErrorUserDeletedZone userInfo:@{}]]; - // We expect CKKS to recreate the zone, then perform a key hierarchy upload, and then the class C item upload - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + // We expect CKKS to recreate the zone, then have octagon reupload the keys, and then the class C item upload [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]; + [self performOctagonTLKUpload:self.ckksViews]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); // And check that a new upload occurs. @@ -3180,12 +3459,14 @@ // The next CKRecordZoneChanges will fail with a 'zone not found' error. self.zones[self.keychainZoneID] = nil; // delete the zone + self.keys[self.keychainZoneID] = nil; - // We expect CKKS to reset itself and recover, then a key hierarchy upload, and then the class C item upload - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords: 1 zoneID:self.keychainZoneID]; + // We expect CKKS to reset itself and recover, then have octagon upload the keys, and then the class C item upload [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]; + + [self performOctagonTLKUpload:self.ckksViews]; OCMVerifyAllWithDelay(self.mockDatabase, 20); [self waitForCKModifications]; @@ -3211,10 +3492,9 @@ [fetchReturns fulfill]; }]; - // start 'login'. CKKS Should upload a key hierarchy - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS should enter 'ready'"); // We expect a single record to be uploaded @@ -3230,8 +3510,7 @@ - (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 = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil];; - [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; self.silentFetchesAllowed = false; [self startCKKSSubsystem]; @@ -3239,7 +3518,7 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); [self addGenericPassword: @"data" account: @"account-delete-me"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; // simulate a NSNotification callback (but still logged out) self.accountStatus = CKAccountStatusNoAccount; @@ -3249,7 +3528,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-2"]; [self addGenericPassword: @"data" account: @"account-delete-me-3"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; OCMVerifyAllWithDelay(self.mockDatabase, 20); // Test that there are no items in the database (since we never logged in) @@ -3258,81 +3537,132 @@ - (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 = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; - [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; self.accountStatus = CKAccountStatusAvailable; - self.supportsDeviceToDeviceEncryption = NO; self.silentFetchesAllowed = false; + + // Octagon does not initialize the ckks views when not in an HSA2 account + self.automaticallyBeginCKKSViewCloudKitOperation = false; [self startCKKSSubsystem]; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - 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"); - XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotHSA2, "Account tracker error should be upset about HSA2"); OCMVerifyAllWithDelay(self.mockDatabase, 20); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS should enter 'loggedout'"); // 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.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self endSOSTrustedOperationForAllViews]; [self addGenericPassword: @"data" account: @"account-delete-me-2"]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; [self addGenericPassword: @"data" account: @"account-delete-me-3"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; 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]; } +- (void)testEarlyLogin +{ + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; + + // Octagon should initialize these views + self.automaticallyBeginCKKSViewCloudKitOperation = true; + + self.accountStatus = CKAccountStatusAvailable; + //[self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + [self startCKKSSubsystem]; + + // CKKS should end up in 'waitfortlkcreation', as there's no trust and no TLKs + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], "CKKS entered 'waitfortlkcreation'"); + + // Now, renotify the account status, and ensure that CKKS doesn't reenter 'initializing' + CKKSCondition* initializing = self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateInitializing]; + + [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + + XCTAssertNotEqual(0, [initializing wait:500*NSEC_PER_MSEC], "CKKS should not enter initializing when the device HSA status changes"); +} + - (void)testNoCircle { // Test starts with nothing in database and the user logged into CloudKit, but out of Circle. - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; - [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; self.accountStatus = CKAccountStatusAvailable; - self.silentFetchesAllowed = false; [self startCKKSSubsystem]; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); - 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, 20); [self addGenericPassword: @"data" account: @"account-delete-me"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], "CKKS entered 'waitfortlkcreation'"); // simulate a NSNotification callback (but still logged out) self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'loggedout'"); + // There should be no further uploads, even when we save keychain items [self addGenericPassword: @"data" account: @"account-delete-me-2"]; [self addGenericPassword: @"data" account: @"account-delete-me-3"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; OCMVerifyAllWithDelay(self.mockDatabase, 20); // Test that there are no items in the database (since we never logged in) [self checkNoCKKSData: self.keychainView]; } +- (void)testCircleDepartAndRejoin { + // Test starts with CKKS in ready + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready"); + + // But then, trust departs + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self endSOSTrustedOperationForAllViews]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "CKKS entered 'waitfortrust'"); + + // There should be no further uploads, even when we save keychain items + [self addGenericPassword: @"data" account: @"account-delete-me-2"]; + [self addGenericPassword: @"data" account: @"account-delete-me-3"]; + + // Then trust returns. We expect two uploads + [self expectCKModifyItemRecords:2 currentKeyPointerRecords: 1 zoneID:self.keychainZoneID + checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 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 = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; - [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; // Before we inform CKKS of its account state.... XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK shouldn't know the account state"); @@ -3343,32 +3673,21 @@ XCTAssertNotEqual(0, [self.keychainView.loggedIn wait:100*NSEC_PER_MSEC], "'login' event shouldn't have happened"); XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKK should know the account state"); - [self.keychainView waitUntilAllOperationsAreFinished]; 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"); - XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotLoggedIn, "Account tracker error should just be 'no account'"); - // simulate a cloudkit login and NSNotification callback self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - XCTAssertNotNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's no account"); - 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"); - // No writes yet, since we're not in circle - [self.keychainView waitUntilAllOperationsAreFinished]; - 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]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:20*NSEC_PER_SEC], "CKKS entered 'waitfortlkcreation'"); + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedOperationForAllViews]; - XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); + [self performOctagonTLKUpload:self.ckksViews]; 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"); @@ -3386,11 +3705,9 @@ } - (void)testCloudKitLogoutLogin { - // 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:50*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; 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"); @@ -3408,12 +3725,9 @@ // simulate a cloudkit logout and NSNotification callback self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - - 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"); - XCTAssertEqual(self.accountStateTracker.currentAccountError.code, CKKSNotLoggedIn, "Account tracker error should just believe we're not logged in"); + [self endSOSTrustedOperationForAllViews]; // 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'"); @@ -3425,7 +3739,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-2"]; [self addGenericPassword: @"data" account: @"account-delete-me-3"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; OCMVerifyAllWithDelay(self.mockDatabase, 20); XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); @@ -3435,9 +3749,10 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); + [self beginSOSTrustedViewOperation:self.keychainView]; 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"); @@ -3452,8 +3767,10 @@ // Logout again self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; + + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self endSOSTrustedOperationForAllViews]; // 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'"); @@ -3465,7 +3782,7 @@ [self addGenericPassword: @"data" account: @"account-delete-me-5"]; [self addGenericPassword: @"data" account: @"account-delete-me-6"]; - [self.keychainView waitUntilAllOperationsAreFinished]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; OCMVerifyAllWithDelay(self.mockDatabase, 20); // simulate a cloudkit login @@ -3474,8 +3791,10 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; 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"); @@ -3490,8 +3809,10 @@ // Logout again self.accountStatus = CKAccountStatusNoAccount; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCNotInCircle error:nil]; + + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self endSOSTrustedOperationForAllViews]; // 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'"); @@ -3505,8 +3826,10 @@ self.accountStatus = CKAccountStatusAvailable; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; XCTestExpectation *operationRun = [self expectationWithDescription:@"operation run"]; NSOperation* op = [NSBlockOperation named:@"test" withBlock:^{ @@ -3521,16 +3844,14 @@ 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]; + [self waitForExpectations: @[operationRun] timeout:10]; 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:50*NSEC_PER_MSEC], "CKK shouldn't know the account state"); [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; 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"); @@ -3544,10 +3865,6 @@ self.iCloudHasValidCredentials = false; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - 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"); - 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: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"); @@ -3577,8 +3894,6 @@ self.iCloudHasValidCredentials = true; [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - XCTAssertNil(self.accountStateTracker.currentAccountError, "Account state tracker should believe there's an account"); - 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"); @@ -3594,31 +3909,28 @@ - (void)testCloudKitLoginRace { // Test starts with nothing in database, and 'in circle', but securityd hasn't received notification if we're logged into CloudKit. - // CKKS should not call handleLogout. + // CKKS should call handleLogout, as the CK account is not present. - id partialKVMock = OCMPartialMock(self.keychainView); - OCMReject([partialKVMock handleCKLogout]); // note: don't unblock the ck account state object yet... - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; - // Add a keychain item, but make sure it doesn't upload yet. + // Add a keychain item, and make sure it doesn't upload yet. [self addGenericPassword: @"data" account: @"account-delete-me"]; + [self.keychainView waitForOperationsOfClass:[CKKSOutgoingQueueOperation class]]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'loggedout'"); - [self.keychainView waitUntilAllOperationsAreFinished]; OCMVerifyAllWithDelay(self.mockDatabase, 20); - // Now that we're here (and handleCKLogout hasn't been called), bring the account up - - // 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]; + // Now that we're here (and logged out), bring the account up // 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.accountStatus = CKAccountStatusAvailable; - [self startCKAccountStatusMock]; + [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; // simulate another NSNotification callback [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; @@ -3634,11 +3946,10 @@ [self.keychainView waitUntilAllOperationsAreFinished]; [self waitForCKModifications]; [self.keychainView halt]; - - [partialKVMock stopMocking]; } - (void)testDontLogOutIfBeforeFirstUnlock { + /* // test starts as if a previously logged-in device has just rebooted self.aksLockState = true; self.accountStatus = CKAccountStatusAvailable; @@ -3651,28 +3962,27 @@ 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.currentComputedAccountStatus, CKKSAccountStatusUnknown, "Account tracker status should just be 'no account'"); - XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS shouldn't know the account state yet"); + XCTAssertEqual(self.accountStateTracker.currentComputedAccountStatus, CKKSAccountStatusUnknown, "Account tracker status should just be 'unknown'"); + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS should not yet know the CK account state"); [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"); + XCTAssertEqual(0, [self.keychainView.loggedIn wait:8*NSEC_PER_SEC], "'login' event should have happened"); + XCTAssertNotEqual(0, [self.keychainView.loggedOut wait:10*NSEC_PER_MSEC], "Should not have been told of a CK 'logout' event on startup"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:1*NSEC_PER_SEC], "CKKS should know the account state"); // And assume another CK status change [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; XCTAssertEqual(self.accountStateTracker.currentComputedAccountStatus, CKKSAccountStatusUnknown, "Account tracker status should just be 'no account'"); - XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS shouldn't know the account state yet"); + XCTAssertEqual(0, [self.keychainView.accountStateKnown wait:50*NSEC_PER_MSEC], "CKKS should know the CK account state"); [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"); + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; 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"); @@ -3686,13 +3996,13 @@ [self addGenericPassword: @"data" account: @"account-delete-me"]; OCMVerifyAllWithDelay(self.mockDatabase, 20); - [self waitForCKModifications]; + [self waitForCKModifications];*/ } - (void)testSyncableItemsAddedWhileLoggedOut { // Test that once CKKS is up and 'logged out', nothing happens when syncable items are added self.accountStatus = CKAccountStatusNoAccount; - [self startCKAccountStatusMock]; + [self startCKKSSubsystem]; XCTAssertEqual([self.keychainView.loggedOut wait:500*NSEC_PER_MSEC], 0, "CKKS should be told that it's logged out"); @@ -3710,6 +4020,128 @@ [pokeKeyStateMachineScheduler stopMocking]; } +- (void)testUploadSyncableItemsAddedWhileUntrusted { + self.mockSOSAdapter.circleStatus = kSOSCCNotInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + + [self startCKKSSubsystem]; + + XCTAssertEqual([self.keychainView.loggedIn wait:500*NSEC_PER_MSEC], 0, "CKKS should be told that it's logged in"); + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "CKKS entered waitfortrust"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + [self addGenericPassword: @"data" account: @"account-delete-me-2"]; + + sleep(2); + + NSError* error = nil; + NSDictionary* currentOQEs = [CKKSOutgoingQueueEntry countsByStateInZone:self.keychainZoneID error:&error]; + XCTAssertNil(error, "Should be no error coutning OQEs"); + XCTAssertEqual(0, currentOQEs.count, "Should be no OQEs"); + + // Now, insert a restart to simulate securityd restarting (and throwing away all pending operations), then a real sign in + self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self endSOSTrustedViewOperation:self.keychainView]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] wait:20*NSEC_PER_SEC], "CKKS entered waitfortrust"); + + // Okay! Upon sign in, this item should 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 putSelfTLKSharesInCloudKit:self.keychainZoneID]; + self.mockSOSAdapter.circleStatus = kSOSCCInCircle; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +// Note that this test assumes that the keychainView object was created at daemon restart. +// I don't really know how to write a test for that... +- (void)testSyncableItemAddedOnDaemonRestartBeforeCloudKitAccountKnown { + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready"); + + // Daemon restarts + self.automaticallyBeginCKKSViewCloudKitOperation = false; + self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + [self addGenericPassword: @"data" account: @"account-delete-me-2"]; + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:100*NSEC_PER_MSEC], "CKKS should still have no idea what the account state is"); + XCTAssertEqual(self.keychainView.accountStatus, CKKSAccountStatusUnknown, "Account status should be unknown"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); + + [self.keychainView beginCloudKitOperation]; + + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testSyncableItemModifiedOnDaemonRestartBeforeCloudKitAccountKnown { + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self startCKKSSubsystem]; + + 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-2"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + // Daemon restarts + self.automaticallyBeginCKKSViewCloudKitOperation = false; + self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + [self updateGenericPassword:@"newdata" account: @"account-delete-me-2"]; + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:100*NSEC_PER_MSEC], "CKKS should still have no idea what the account state is"); + XCTAssertEqual(self.keychainView.accountStatus, CKKSAccountStatusUnknown, "Account status should be unknown"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); + + [self.keychainView beginCloudKitOperation]; + + [self expectCKModifyItemRecords:1 currentKeyPointerRecords:1 zoneID:self.keychainZoneID + checkItem: [self checkClassCBlock:self.keychainZoneID message:@"Object was encrypted under class C key in hierarchy"]]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} + +- (void)testSyncableItemDeletedOnDaemonRestartBeforeCloudKitAccountKnown { + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self startCKKSSubsystem]; + + 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-2"]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + // Daemon restarts + self.automaticallyBeginCKKSViewCloudKitOperation = false; + self.keychainView = [[CKKSViewManager manager] restartZone: self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + [self deleteGenericPassword:@"account-delete-me-2"]; + XCTAssertNotEqual(0, [self.keychainView.accountStateKnown wait:100*NSEC_PER_MSEC], "CKKS should still have no idea what the account state is"); + XCTAssertEqual(self.keychainView.accountStatus, CKKSAccountStatusUnknown, "Account status should be unknown"); + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateLoggedOut] wait:20*NSEC_PER_SEC], "CKKS entered 'logged out'"); + + [self.keychainView beginCloudKitOperation]; + + [self expectCKDeleteItemRecords:1 zoneID:self.keychainZoneID]; + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "CKKS entered ready"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); +} - (void)testNotStuckAfterReset { [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. @@ -3735,6 +4167,90 @@ XCTAssertNotNil(interface, "Received a configured CKKS interface"); } +- (void)testMetricsUpload { + + XCTestExpectation *upload = [self expectationWithDescription:@"CAMetrics"]; + XCTestExpectation *collection = [self expectationWithDescription:@"CAMetrics"]; + + id saMock = OCMClassMock([SecCoreAnalytics class]); + OCMStub([saMock sendEvent:[OCMArg any] event:[OCMArg any]]).andDo(^(NSInvocation* invocation) { + [upload fulfill]; + }); + + NSString *sampleSampler = @"stuff"; + + [[CKKSAnalytics logger] AddMultiSamplerForName:sampleSampler withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ + [collection fulfill]; + return @{ @"hej" : @1 }; + }]; + + + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should have arrived at ready"); + + [self expectCKModifyRecords:@{SecCKRecordDeviceStateType: [NSNumber numberWithInt:1]} + deletedRecordTypeCounts:nil + zoneID:self.keychainZoneID + checkModifiedRecord:nil + runAfterModification:nil]; + + [self.injectedManager xpc24HrNotification]; + + [self waitForExpectations: @[upload, collection] timeout:10]; + [[CKKSAnalytics logger] removeMultiSamplerForName:sampleSampler]; +} + +- (void)testSaveManyTLKShares { + // Spin up CKKS subsystem. + [self startCKKSSubsystem]; + + [self performOctagonTLKUpload:self.ckksViews]; + OCMVerifyAllWithDelay(self.mockDatabase, 20); + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"key state should enter 'ready'"); + + NSMutableArray* peers = [NSMutableArray array]; + + for(int i = 0; i < 20; i++) { + CKKSSOSSelfPeer* untrustedPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:[NSString stringWithFormat:@"untrusted-peer-%d", i] + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; + + [peers addObject:untrustedPeer]; + } + + NSMutableArray* tlkShareRecords = [NSMutableArray array]; + + for(CKKSSOSSelfPeer* peer1 in peers) { + for(CKKSSOSSelfPeer* peer2 in peers) { + NSError* error = nil; + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.keychainZoneKeys.tlk + as:peer1 + to:peer2 + epoch:-1 + poisoned:0 + error:&error]; + XCTAssertNil(error, "Should have been no error sharing a CKKSKey"); + XCTAssertNotNil(share, "Should be able to create a share"); + + CKRecord* shareRecord = [share CKRecordWithZoneID:self.keychainZoneID]; + [tlkShareRecords addObject:shareRecord]; + } + } + + [self measureBlock:^{ + [self.keychainView dispatchSyncWithAccountKeys:^bool{ + for(CKRecord* record in tlkShareRecords) { + [self.keychainView _onqueueCKRecordChanged:record resync:false]; + } + return true; + }]; + }]; +} + @end #endif // OCTAGON diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m b/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m index 0f5ad14b..fddf4ca6 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingFixupTests.m @@ -51,8 +51,8 @@ id mockFixups = OCMClassMock([CKKSFixups class]); OCMReject([[[mockFixups stub] ignoringNonObjectArgs] fixup:0 for:[OCMArg any]]); - [self expectCKModifyKeyRecords: 3 currentKeyPointerRecords: 3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; @@ -66,9 +66,8 @@ id mockFixups = OCMClassMock([CKKSFixups class]); OCMExpect([mockFixups fixup:CKKSCurrentFixupNumber for:[OCMArg any]]); - // 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]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; @@ -78,6 +77,7 @@ [self.keychainView halt]; self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; [self.keychainView waitForKeyHierarchyReadiness]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -89,9 +89,8 @@ // Due to CKKS: current item pointer CKRecord resurrection, // CKKS needs to refetch all current item pointers if it restarts and hasn't yet. - // Test starts with no keys in database. We expect some sort of TLK/key hierarchy upload. - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; @@ -160,6 +159,7 @@ // Bring CKKS back up self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; [self.keychainView waitForKeyHierarchyReadiness]; [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; @@ -211,12 +211,10 @@ // In CKKSTLK: TLKShare CloudKit upload/download on TLK change, trust set addition, // we added the TLKShare CKRecord type. Upgrading devices must fetch all such records when they come online for the first time. - // Test starts with nothing in database. We expect some sort of TLK/key hierarchy upload. // Note that this already does TLK sharing, and so technically doesn't need to do the fixup, but we'll fix that later. - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; - [self.keychainView waitForKeyHierarchyReadiness]; [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -230,11 +228,12 @@ CKKSSOSSelfPeer* remotePeer1 = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"remote-peer1" encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; - CKKSTLKShare* share = [CKKSTLKShare share:self.keychainZoneKeys.tlk + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:self.keychainZoneKeys.tlk as:remotePeer1 - to:self.currentSelfPeer + to:self.mockSOSAdapter.selfPeer epoch:-1 poisoned:0 error:&error]; @@ -253,8 +252,11 @@ [self holdCloudKitFetches]; self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForFixupOperation] wait:20*NSEC_PER_SEC], "Key state should become waitforfixup"); + + self.silentFetchesAllowed = true; [self releaseCloudKitFetchHold]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], "Key state should become ready"); @@ -266,7 +268,7 @@ // and check that the share made it [self.keychainView dispatchSync:^bool { NSError* blockerror = nil; - CKKSTLKShare* localshare = [CKKSTLKShare tryFromDatabaseFromCKRecordID:shareCKRecord.recordID error:&blockerror]; + CKKSTLKShareRecord* localshare = [CKKSTLKShareRecord tryFromDatabaseFromCKRecordID:shareCKRecord.recordID error:&blockerror]; XCTAssertNil(blockerror, "Shouldn't error finding new TLKShare record in database"); XCTAssertNotNil(localshare, "Should be able to find a new TLKShare record in database"); return true; @@ -277,8 +279,8 @@ // In Server Generated CloudKit "Manatee Identity Lost" // items could be deleted from the local keychain after CKKS believed they were already synced, and therefore wouldn't resync - [self expectCKModifyKeyRecords:3 currentKeyPointerRecords:3 tlkShareRecords:1 zoneID:self.keychainZoneID]; [self startCKKSSubsystem]; + [self performOctagonTLKUpload:self.ckksViews]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); OCMVerifyAllWithDelay(self.mockDatabase, 20); @@ -331,6 +333,7 @@ [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; self.keychainView.holdFixupOperation = [CKKSResultOperation named:@"hold-fixup" withBlock:^{}]; self.accountStatus = CKAccountStatusAvailable; @@ -349,6 +352,67 @@ [self checkGenericPassword: @"data" account: @"first"]; } +- (void)testFixupResaveDeviceStateEntries { + // In , we introduced a new field to DeviceStateEntries. But, Peace couldn't change the DB schema to match newer Yukons + [self putFakeKeyHierarchyInCloudKit:self.keychainZoneID]; + [self putFakeOctagonOnlyDeviceStatusInCloudKit:self.keychainZoneID]; + [self saveTLKMaterialToKeychain:self.keychainZoneID]; + [self expectCKKSTLKSelfShareUpload:self.keychainZoneID]; + + [self startCKKSSubsystem]; + + XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:20*NSEC_PER_SEC], @"Key state should become 'ready'"); + OCMVerifyAllWithDelay(self.mockDatabase, 20); + [self waitForCKModifications]; + + + // Modify the sqlite DB to simulate how earlier verions would save these records + [self.keychainView dispatchSync:^bool { + NSError* error = nil; + CKKSDeviceStateEntry* cdse = [CKKSDeviceStateEntry fromDatabase:self.remoteSOSOnlyPeer.peerID zoneID:self.keychainZoneID error:&error]; + XCTAssertNil(error, "Should have no error pulling CKKSDeviceStateEntry from database"); + + XCTAssertNotNil(cdse.octagonPeerID, "CDSE should have an octagon peer ID"); + XCTAssertNotNil(cdse.octagonStatus, "CDSE should have an octagon status"); + cdse.octagonPeerID = nil; + cdse.octagonStatus = nil; + + [cdse saveToDatabase:&error]; + XCTAssertNil(error, "No error saving modified CDSE back to database"); + return true; + }]; + + // Tear down the CKKS object + [self.keychainView halt]; + [self setFixupNumber:CKKSFixupFetchTLKShares ckks:self.keychainView]; + + // Now, restart CKKS + self.silentFetchesAllowed = false; + self.accountStatus = CKAccountStatusCouldNotDetermine; + [self.accountStateTracker notifyCircleStatusChangeAndWaitForSignal]; + + self.keychainView = [[CKKSViewManager manager] restartZone:self.keychainZoneID.zoneName]; + [self beginSOSTrustedViewOperation:self.keychainView]; + + 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"); + + [self.keychainView waitForOperationsOfClass:[CKKSIncomingQueueOperation class]]; + + // And all CDSEs should have an octagon peer ID again! + [self.keychainView dispatchSync:^bool { + NSError* error = nil; + CKKSDeviceStateEntry* cdse = [CKKSDeviceStateEntry fromDatabase:self.remoteSOSOnlyPeer.peerID zoneID:self.keychainZoneID error:&error]; + XCTAssertNil(error, "Should have no error pulling CKKSDeviceStateEntry from database"); + + XCTAssertNotNil(cdse.octagonPeerID, "CDSE should have an octagon peer ID"); + XCTAssertNotNil(cdse.octagonStatus, "CDSE should have an octagon status"); + return false; + }]; +} + @end #endif // OCTAGON diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h index 32020bd3..e1d7ef68 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h +++ b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.h @@ -28,6 +28,10 @@ #import "keychain/ckks/CKKSControl.h" #import "keychain/ckks/CKKSCurrentKeyPointer.h" #import "keychain/ckks/CKKSItem.h" +#import "keychain/ckks/tests/CKKSMockSOSPresentAdapter.h" +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#include "OSX/sec/Security/SecItemShim.h" NS_ASSUME_NONNULL_BEGIN @@ -47,19 +51,20 @@ NS_ASSUME_NONNULL_BEGIN @interface CloudKitKeychainSyncingMockXCTest : CloudKitMockXCTest @property CKKSControl* ckksControl; - -@property (nullable) id mockCKKSKey; - -@property (nullable) CKKSSOSSelfPeer* currentSelfPeer; -@property (nullable) NSError* currentSelfPeerError; -@property (nullable) NSMutableSet>* currentPeers; -@property (nullable) NSError* currentPeersError; +@property OTCuttlefishAccountStateHolder *accountMetaDataStore; +@property (nullable) id mockCKKSKeychainBackedKey; @property (nullable) NSError* keychainFetchError; // A single trusted SOSPeer, but without any CKKS keys @property CKKSSOSPeer* remoteSOSOnlyPeer; +// Set this to false after calling -setUp if you want to initialize the views yourself +@property bool automaticallyBeginCKKSViewCloudKitOperation; + +// Fill this in before allowing initialization to use your own mock instead of a default stub +@property id suggestTLKUpload; + @property NSMutableSet* ckksViews; @property NSMutableSet* ckksZones; @property (nullable) NSMutableDictionary* keys; @@ -75,15 +80,23 @@ NS_ASSUME_NONNULL_BEGIN - (void)putFakeDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID zonekeys:(ZoneKeys*)zonekeys; -- (void)putFakeOctagonOnlyDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID zonekeys:(ZoneKeys*)zonekeys; - (void)putFakeOctagonOnlyDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID; +- (void)putFakeOctagonOnlyDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID + zonekeys:(ZoneKeys*)zonekeys; - (void)SOSPiggyBackAddToKeychain:(NSDictionary*)piggydata; - (NSMutableDictionary*)SOSPiggyBackCopyFromKeychain; - (NSMutableArray*)SOSPiggyICloudIdentities; +// Octagon is responsible for telling CKKS that it's trusted. +// But, in these tests, use these to pretend that SOS is the only trust source around. +- (void)beginSOSTrustedOperationForAllViews; +- (void)beginSOSTrustedViewOperation:(CKKSKeychainView*)view; +- (void)endSOSTrustedOperationForAllViews; +- (void)endSOSTrustedViewOperation:(CKKSKeychainView*)view; + - (void)putTLKShareInCloudKit:(CKKSKey*)key - from:(CKKSSOSSelfPeer*)sharingPeer + from:(id)sharingPeer to:(id)receivingPeer zoneID:(CKRecordZoneID*)zoneID; - (void)putTLKSharesInCloudKit:(CKKSKey*)key from:(CKKSSOSSelfPeer*)sharingPeer zoneID:(CKRecordZoneID*)zoneID; @@ -97,6 +110,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)rollFakeKeyHierarchyInCloudKit:(CKRecordZoneID*)zoneID; +- (NSArray*)putKeySetInCloudKit:(CKKSCurrentKeySet*)keyset; +- (void)performOctagonTLKUpload:(NSSet*)views; +- (void)performOctagonTLKUpload:(NSSet*)views afterUpload:(void (^_Nullable)(void))afterUpload; + - (NSDictionary*)fakeRecordDictionary:(NSString* _Nullable)account zoneID:(CKRecordZoneID*)zoneID; - (CKRecord*)createFakeRecord:(CKRecordZoneID*)zoneID recordName:(NSString*)recordName; - (CKRecord*)createFakeRecord:(CKRecordZoneID*)zoneID recordName:(NSString*)recordName withAccount:(NSString* _Nullable)account; @@ -127,6 +144,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)checkNoCKKSData:(CKKSKeychainView*)view; - (void)deleteGenericPassword:(NSString*)account; +- (void)deleteGenericPasswordWithoutTombstones:(NSString*)account; - (void)findGenericPassword:(NSString*)account expecting:(OSStatus)status; - (void)checkGenericPassword:(NSString*)password account:(NSString*)account; @@ -150,6 +168,9 @@ NS_ASSUME_NONNULL_BEGIN // Add expectations that CKKS will upload a single TLK share - (void)expectCKKSTLKSelfShareUpload:(CKRecordZoneID*)zoneID; + +// Can't call OCMVerifyMock due to Swift? Use this. +- (void)verifyDatabaseMocks; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m index 200b7954..34477abf 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingMockXCTest.m @@ -43,12 +43,15 @@ #import "keychain/ckks/CKKSZoneStateEntry.h" #import "keychain/ckks/CKKSManifest.h" #import "keychain/ckks/CKKSPeer.h" +#import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ot/OTDefines.h" +#import "tests/secdmockaks/mockaks.h" + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#import "Security/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSAccount.h" #pragma clang diagnostic pop @implementation ZoneKeys @@ -96,57 +99,54 @@ XCTAssertFalse([CKKSManifest shouldSyncManifests], "Manifests syncing is disabled"); XCTAssertFalse([CKKSManifest shouldEnforceManifests], "Manifests enforcement is disabled"); + // Use our superclass to create a fake keychain [super setUp]; + + self.automaticallyBeginCKKSViewCloudKitOperation = true; + self.suggestTLKUpload = OCMClassMock([CKKSNearFutureScheduler class]); + OCMStub([self.suggestTLKUpload trigger]); + self.ckksZones = [NSMutableSet set]; self.ckksViews = [NSMutableSet set]; self.keys = [[NSMutableDictionary alloc] init]; + [SecMockAKS reset]; + + // Set up a remote peer with no keys + self.remoteSOSOnlyPeer = [[CKKSSOSPeer alloc] initWithSOSPeerID:@"remote-peer-with-no-keys" + encryptionPublicKey:nil + signingPublicKey:nil + viewList:self.managedViewList]; + NSMutableSet>* currentPeers = [NSMutableSet setWithObject:self.remoteSOSOnlyPeer]; + self.mockSOSAdapter.trustedPeers = currentPeers; + // Fake out whether class A keys can be loaded from the keychain. - self.mockCKKSKey = OCMClassMock([CKKSKey class]); + self.mockCKKSKeychainBackedKey = OCMClassMock([CKKSKeychainBackedKey class]); __weak __typeof(self) weakSelf = self; BOOL (^shouldFailKeychainQuery)(NSDictionary* query) = ^BOOL(NSDictionary* query) { __strong __typeof(self) strongSelf = weakSelf; - NSString* description = query[(id)kSecAttrDescription]; - bool isTLK = [description isEqualToString: SecCKKSKeyClassTLK] || - [description isEqualToString: [SecCKKSKeyClassTLK stringByAppendingString: @"-nonsync"]] || - [description isEqualToString: [SecCKKSKeyClassTLK stringByAppendingString: @"-piggy"]]; - bool isClassA = [description isEqualToString: SecCKKSKeyClassA]; - - return ((isTLK || isClassA) && strongSelf.aksLockState) || self.keychainFetchError; + return !!strongSelf.keychainFetchError; }; - OCMStub([self.mockCKKSKey setKeyMaterialInKeychain:[OCMArg checkWithBlock:shouldFailKeychainQuery] error:[OCMArg anyObjectRef]] - ).andCall(self, @selector(handleLockSetKeyMaterialInKeychain:error:)); - - OCMStub([self.mockCKKSKey queryKeyMaterialInKeychain:[OCMArg checkWithBlock:shouldFailKeychainQuery] error:[OCMArg anyObjectRef]] - ).andCall(self, @selector(handleLockLoadKeyMaterialFromKeychain:error:)); - - // Fake out SOS peers - self.currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"local-peer" - encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] - signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]]; - - // One trusted non-self peer, but it doesn't have any Octagon keys. Your test can change this if it wants. - // However, note that [self putFakeDeviceStatusInCloudKit:] will likely not do what you want. - self.remoteSOSOnlyPeer = [[CKKSSOSPeer alloc] initWithSOSPeerID:@"remote-peer-with-no-keys" - encryptionPublicKey:nil - signingPublicKey:nil]; - self.currentPeers = [NSMutableSet set]; - [self.currentPeers addObject:self.remoteSOSOnlyPeer]; + OCMStub([self.mockCKKSKeychainBackedKey setKeyMaterialInKeychain:[OCMArg checkWithBlock:shouldFailKeychainQuery] error:[OCMArg anyObjectRef]] + ).andCall(self, @selector(handleFailedSetKeyMaterialInKeychain:error:)); - OCMStub([self.mockCKKSViewManager currentSOSSelf:[OCMArg anyObjectRef]]).andCall(self, @selector(currentSOSSelf:)); - OCMStub([self.mockCKKSViewManager fetchTrustedPeers:[OCMArg anyObjectRef]]).andCall(self, @selector(fetchTrustedPeers:)); + OCMStub([self.mockCKKSKeychainBackedKey queryKeyMaterialInKeychain:[OCMArg checkWithBlock:shouldFailKeychainQuery] error:[OCMArg anyObjectRef]] + ).andCall(self, @selector(handleFailedLoadKeyMaterialFromKeychain:error:)); // Bring up a fake CKKSControl object id mockConnection = OCMPartialMock([[NSXPCConnection alloc] init]); OCMStub([mockConnection remoteObjectProxyWithErrorHandler:[OCMArg any]]).andCall(self, @selector(injectedManager)); self.ckksControl = [[CKKSControl alloc] initWithConnection:mockConnection]; XCTAssertNotNil(self.ckksControl, "Should have received control object"); + + self.accountMetaDataStore = OCMPartialMock([[OTCuttlefishAccountStateHolder alloc]init]); + OCMStub([self.accountMetaDataStore loadOrCreateAccountMetadata:[OCMArg anyObjectRef]]).andCall(self, @selector(loadOrCreateAccountMetadata:)); } - (void)tearDown { - [self.mockCKKSKey stopMocking]; - self.mockCKKSKey = nil; + [self.mockCKKSKeychainBackedKey stopMocking]; + self.mockCKKSKeychainBackedKey = nil; // Make sure the key state machine won't be poked after teardown for(CKKSKeychainView* view in self.ckksViews) { @@ -155,41 +155,49 @@ [super tearDown]; self.keys = nil; - - self.currentSelfPeer = nil; - self.currentPeers = nil; } -- (id _Nullable)currentSOSSelf:(NSError**)error { - if(self.currentSelfPeerError) { - if(error) { - *error = self.currentSelfPeerError; - } - return nil; - } else if(self.aksLockState) { - if(error) { - *error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain code:errSecInteractionNotAllowed userInfo:nil]; - } - return nil; +- (void)startCKKSSubsystem +{ + [super startCKKSSubsystem]; + if(self.mockSOSAdapter.circleStatus == kSOSCCInCircle) { + [self beginSOSTrustedOperationForAllViews]; } else { - return self.currentSelfPeer; + [self endSOSTrustedOperationForAllViews]; } } -- (NSSet>*)fetchTrustedPeers:(NSError* __autoreleasing *)error { - if(self.currentPeersError) { - if(error) { - *error = self.currentPeersError; - } - return nil; +- (void)beginSOSTrustedOperationForAllViews { + for(CKKSKeychainView* view in self.ckksViews) { + [self beginSOSTrustedViewOperation:view]; + } +} + +- (void)beginSOSTrustedViewOperation:(CKKSKeychainView*)view +{ + if(self.automaticallyBeginCKKSViewCloudKitOperation) { + [view beginCloudKitOperation]; + } + + [view beginTrustedOperation:@[self.mockSOSAdapter] suggestTLKUpload:self.suggestTLKUpload]; +} + +- (void)endSOSTrustedOperationForAllViews { + for(CKKSKeychainView* view in self.ckksViews) { + [self endSOSTrustedViewOperation:view]; } +} - // Trusted Peers include ourselves, but as a CKKSSOSPeer object instead of a self peer - CKKSSOSPeer* s = [[CKKSSOSPeer alloc] initWithSOSPeerID:self.currentSelfPeer.peerID - encryptionPublicKey:self.currentSelfPeer.publicEncryptionKey - signingPublicKey:self.currentSelfPeer.publicSigningKey]; +- (void)endSOSTrustedViewOperation:(CKKSKeychainView*)view +{ + if(self.automaticallyBeginCKKSViewCloudKitOperation) { + [view beginCloudKitOperation]; + } + [view endTrustedOperation]; +} - return [self.currentPeers setByAddingObject: s]; +- (void)verifyDatabaseMocks { + OCMVerifyAllWithDelay(self.mockDatabase, 20); } - (void)createClassCItemAndWaitForUpload:(CKRecordZoneID*)zoneID account:(NSString*)account { @@ -215,42 +223,21 @@ OCMVerifyAllWithDelay(self.mockDatabase, 20); } -// Helpers to handle 'locked' keychain loading and saving --(bool)handleLockLoadKeyMaterialFromKeychain:(NSDictionary*)query error:(NSError * __autoreleasing *) error { - if(self.keychainFetchError) { - if(error) { - *error = self.keychainFetchError; - } - return false; - } - - // I think the behavior is: errSecItemNotFound if the item doesn't exist, otherwise errSecInteractionNotAllowed. - XCTAssertTrue(self.aksLockState, "Failing a read when keychain is locked"); +// Helpers to handle 'failed' keychain loading and saving +- (bool)handleFailedLoadKeyMaterialFromKeychain:(NSDictionary*)query error:(NSError * __autoreleasing *) error { + NSAssert(self.keychainFetchError != nil, @"must have a keychain error to error with"); - OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL); - if(status == errSecItemNotFound) { - if(error) { - *error = [NSError errorWithDomain:@"securityd" code:status userInfo:nil]; - } - } else { - if(error) { - *error = [NSError errorWithDomain:@"securityd" code:errSecInteractionNotAllowed userInfo:nil]; - } + if(error) { + *error = self.keychainFetchError; } return false; } --(bool)handleLockSetKeyMaterialInKeychain:(NSDictionary*)query error:(NSError * __autoreleasing *) error { - if(self.keychainFetchError) { - if(error) { - *error = self.keychainFetchError; - } - return false; - } +- (bool)handleFailedSetKeyMaterialInKeychain:(NSDictionary*)query error:(NSError * __autoreleasing *) error { + NSAssert(self.keychainFetchError != nil, @"must have a keychain error to error with"); - XCTAssertTrue(self.aksLockState, "Failing a write only when keychain is locked"); if(error) { - *error = [NSError errorWithDomain:@"securityd" code:errSecInteractionNotAllowed userInfo:nil]; + *error = self.keychainFetchError; } return false; } @@ -320,12 +307,18 @@ } - (void)putFakeDeviceStatusInCloudKit:(CKRecordZoneID*)zoneID zonekeys:(ZoneKeys*)zonekeys { + // SOS peer IDs are written bare, missing the CKKSSOSPeerPrefix. Strip it here. + NSString* peerID = self.remoteSOSOnlyPeer.peerID; + if([peerID hasPrefix:CKKSSOSPeerPrefix]) { + peerID = [peerID substringFromIndex:CKKSSOSPeerPrefix.length]; + } + CKKSDeviceStateEntry* dse = [[CKKSDeviceStateEntry alloc] initForDevice:self.remoteSOSOnlyPeer.peerID osVersion:@"faux-version" lastUnlockTime:nil octagonPeerID:nil octagonStatus:nil - circlePeerID:self.remoteSOSOnlyPeer.peerID + circlePeerID:peerID circleStatus:kSOSCCInCircle keyState:SecCKKSZoneKeyStateReady currentTLKUUID:zonekeys.tlk.uuid @@ -361,11 +354,12 @@ [self putFakeOctagonOnlyDeviceStatusInCloudKit:zoneID zonekeys:self.keys[zoneID]]; } - - (void)putFakeKeyHierarchyInCloudKit: (CKRecordZoneID*)zoneID { ZoneKeys* zonekeys = [self createFakeKeyHierarchy: zoneID oldTLK:nil]; + XCTAssertNotNil(zonekeys, "failed to create fake key hierarchy for zoneID=%@", zoneID); FakeCKZone* zone = self.zones[zoneID]; + XCTAssertNotNil(zone, "failed to find zone %@", zoneID); dispatch_sync(zone.queue, ^{ [zone _onqueueAddToZone:zonekeys.tlk zoneID:zoneID]; @@ -395,6 +389,96 @@ [self putFakeKeyHierarchyInCloudKit: zoneID]; } +- (void)ensureZoneDeletionAllowed:(FakeCKZone*)zone { + [super ensureZoneDeletionAllowed:zone]; + + // Here's a hack: if we're deleting this zone, also drop the keys that used to be in it + self.keys[zone.zoneID] = nil; +} + +- (NSArray*)putKeySetInCloudKit:(CKKSCurrentKeySet*)keyset +{ + XCTAssertNotNil(keyset.tlk, "Should have a TLK to put a key set in CloudKit"); + CKRecordZoneID* zoneID = keyset.tlk.zoneID; + XCTAssertNotNil(zoneID, "Should have a zoneID to put a key set in CloudKit"); + + ZoneKeys* zonekeys = self.keys[zoneID]; + XCTAssertNil(zonekeys, "Should not already have zone keys when putting keyset in cloudkit"); + zonekeys = [[ZoneKeys alloc] initForZoneName:zoneID.zoneName]; + + FakeCKZone* zone = self.zones[zoneID]; + // Cuttlefish makes this for you, but for now assert if there's an issue + XCTAssertNotNil(zone, "Should already have a fakeckzone before putting a keyset in it"); + + __block NSMutableArray* newRecords = [NSMutableArray array]; + dispatch_sync(zone.queue, ^{ + [newRecords addObject:[zone _onqueueAddToZone:keyset.tlk zoneID:zoneID]]; + [newRecords addObject:[zone _onqueueAddToZone:keyset.classA zoneID:zoneID]]; + [newRecords addObject:[zone _onqueueAddToZone:keyset.classC zoneID:zoneID]]; + + [newRecords addObject:[zone _onqueueAddToZone:keyset.currentTLKPointer zoneID:zoneID]]; + [newRecords addObject:[zone _onqueueAddToZone:keyset.currentClassAPointer zoneID:zoneID]]; + [newRecords addObject:[zone _onqueueAddToZone:keyset.currentClassCPointer zoneID:zoneID]]; + + // TODO handle a rolled TLK + //if(zonekeys.rolledTLK) { + // [zone _onqueueAddToZone:zonekeys.rolledTLK zoneID:zoneID]; + //} + + zonekeys.tlk = keyset.tlk; + zonekeys.classA = keyset.classA; + zonekeys.classC = keyset.classC; + self.keys[zoneID] = zonekeys; + + // Octagon uploads the pending TLKshares, not all of them + for(CKKSTLKShareRecord* tlkshare in keyset.pendingTLKShares) { + [newRecords addObject:[zone _onqueueAddToZone:tlkshare zoneID:zoneID]]; + } + }); + + return newRecords; +} + +- (void)performOctagonTLKUpload:(NSSet*)views +{ + [self performOctagonTLKUpload:views afterUpload:nil]; +} + +- (void)performOctagonTLKUpload:(NSSet*)views afterUpload:(void (^_Nullable)(void))afterUpload +{ + NSMutableArray*>* keysetOps = [NSMutableArray array]; + + for(CKKSKeychainView* view in views) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKCreation] wait:40*NSEC_PER_SEC], @"key state should enter 'waitfortlkcreation' (view %@)", view); + [keysetOps addObject: [view findKeySet]]; + } + + // Now that we've kicked them all off, wait for them to resolve + for(CKKSKeychainView* view in views) { + XCTAssertEqual(0, [view.keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTLKUpload] wait:40*NSEC_PER_SEC], @"key state should enter 'waitfortlkupload'"); + } + + NSMutableArray* keyHierarchyRecords = [NSMutableArray array]; + + for(CKKSResultOperation* keysetOp in keysetOps) { + // Wait until finished is usually a bad idea. We could rip this out into an operation if we'd like. + [keysetOp waitUntilFinished]; + XCTAssertNil(keysetOp.error, "Should be no error fetching keyset from CKKS"); + + NSArray* records = [self putKeySetInCloudKit:keysetOp.keyset]; + [keyHierarchyRecords addObjectsFromArray:records]; + } + + if(afterUpload) { + afterUpload(); + } + + // Tell our views about our shiny new records! + for(CKKSKeychainView* view in views) { + [view receiveTLKUploadRecords: keyHierarchyRecords]; + } +} + - (void)saveTLKMaterialToKeychainSimulatingSOS: (CKRecordZoneID*)zoneID { XCTAssertNotNil(self.keys[zoneID].tlk, "Have a TLK to save for zone %@", zoneID); @@ -532,12 +616,12 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) - (void)putTLKShareInCloudKit:(CKKSKey*)key - from:(CKKSSOSSelfPeer*)sharingPeer + from:(id)sharingPeer to:(id)receivingPeer zoneID:(CKRecordZoneID*)zoneID { NSError* error = nil; - CKKSTLKShare* share = [CKKSTLKShare share:key + CKKSTLKShareRecord* share = [CKKSTLKShareRecord share:key as:sharingPeer to:receivingPeer epoch:-1 @@ -559,10 +643,10 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) } - (void)putTLKSharesInCloudKit:(CKKSKey*)key - from:(CKKSSOSSelfPeer*)sharingPeer + from:(id)sharingPeer zoneID:(CKRecordZoneID*)zoneID { - NSSet* peers = [self.currentPeers setByAddingObject:self.currentSelfPeer]; + NSSet* peers = [self.mockSOSAdapter.trustedPeers setByAddingObject:self.mockSOSAdapter.selfPeer]; for(id peer in peers) { // Can only send to peers with encryption keys @@ -575,14 +659,14 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) - (void)putSelfTLKSharesInCloudKit:(CKRecordZoneID*)zoneID { CKKSKey* tlk = self.keys[zoneID].tlk; XCTAssertNotNil(tlk, "Should have a TLK for zone %@", zoneID); - [self putTLKSharesInCloudKit:tlk from:self.currentSelfPeer zoneID:zoneID]; + [self putTLKSharesInCloudKit:tlk from:self.mockSOSAdapter.selfPeer zoneID:zoneID]; } - (void)saveTLKSharesInLocalDatabase:(CKRecordZoneID*)zoneID { ZoneKeys* keys = self.keys[zoneID]; XCTAssertNotNil(keys, "Have a zonekeys object for this zone"); - for(CKKSTLKShare* share in keys.tlkShares) { + for(CKKSTLKShareRecord* share in keys.tlkShares) { NSError* error = nil; [share saveToDatabase:&error]; XCTAssertNil(error, "Shouldn't have been an error saving a TLKShare to the database"); @@ -657,10 +741,10 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) XCTAssertNotNil(zonekeys.classA, "Have the current Class A key"); XCTAssertNotNil(zonekeys.classC, "Have the current Class C key"); - NSMutableArray* shares = [NSMutableArray array]; + NSMutableArray* shares = [NSMutableArray array]; for(CKRecordID* recordID in strongSelf.zones[zoneID].currentDatabase.allKeys) { - if([recordID.recordName hasPrefix: [CKKSTLKShare ckrecordPrefix]]) { - CKKSTLKShare* share = [[CKKSTLKShare alloc] initWithCKRecord:strongSelf.zones[zoneID].currentDatabase[recordID]]; + if([recordID.recordName hasPrefix: [CKKSTLKShareRecord ckrecordPrefix]]) { + CKKSTLKShareRecord* share = [[CKKSTLKShareRecord alloc] initWithCKRecord:strongSelf.zones[zoneID].currentDatabase[recordID]]; XCTAssertNotNil(share, "Should be able to parse a CKKSTLKShare CKRecord into a CKKSTLKShare"); [shares addObject:share]; } @@ -897,7 +981,12 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) } - (CKRecord*)createFakeRecord: (CKRecordZoneID*)zoneID recordName:(NSString*)recordName withAccount: (NSString*) account key:(CKKSKey*)key { - NSDictionary* item = [self fakeRecordDictionary: account zoneID:zoneID]; + NSMutableDictionary* item = [[self fakeRecordDictionary: account zoneID:zoneID] mutableCopy]; + + // class c items should be class c + if([key.keyclass isEqualToString:SecCKKSKeyClassC]) { + item[(__bridge NSString*)kSecAttrAccessible] = @"ck"; + } CKRecordID* ckrid = [[CKRecordID alloc] initWithRecordName:recordName zoneID:zoneID]; if(key) { @@ -1021,6 +1110,17 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) XCTAssertEqual(errSecSuccess, SecItemDelete((__bridge CFDictionaryRef) query), @"Deleting item %@", account); } +- (void)deleteGenericPasswordWithoutTombstones:(NSString*)account { + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : account, + (id)kSecAttrSynchronizable : (id)kCFBooleanTrue, + (id)kSecUseTombstones: @NO, + }; + + XCTAssertEqual(errSecSuccess, SecItemDelete((__bridge CFDictionaryRef) query), @"Deleting item %@", account); +} + - (void)findGenericPassword: (NSString*) account expecting: (OSStatus) status { NSDictionary *query = @{(id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccessGroup : @"com.apple.security.ckks", @@ -1082,6 +1182,14 @@ static CFDictionaryRef SOSCreatePeerGestaltFromName(CFStringRef name) } } +- (OTAccountMetadataClassC*)loadOrCreateAccountMetadata:(NSError**)error +{ + if(error) { + *error = [NSError errorWithDomain:@"securityd" code:errSecInteractionNotAllowed userInfo:nil]; + } + return nil; +} + @end #endif // OCTAGON diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h index 97822f9f..2c669584 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h +++ b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h @@ -39,18 +39,25 @@ #import "keychain/ckks/tests/CloudKitMockXCTest.h" #import "keychain/ckks/tests/MockCloudKit.h" +#import "keychain/ot/OTFollowup.h" +#import +#import + NS_ASSUME_NONNULL_BEGIN @interface CloudKitKeychainSyncingTestsBase : CloudKitKeychainSyncingMockXCTest @property (nullable) CKRecordZoneID* keychainZoneID; @property (nullable) CKKSKeychainView* keychainView; @property (nullable) FakeCKZone* keychainZone; - @property (nullable, readonly) ZoneKeys* keychainZoneKeys; @property NSCalendar* utcCalendar; +- (NSSet*)managedViewList; + + - (ZoneKeys*)keychainZoneKeys; + @end NS_ASSUME_NONNULL_END diff --git a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m index a50ce905..35640b3c 100644 --- a/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m +++ b/keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.m @@ -31,8 +31,13 @@ return self.keys[self.keychainZoneID]; } +- (BOOL)mockPostFollowUpWithContext:(CDPFollowUpContext *)context error:(NSError **)error { + secnotice("octagon", "mock cdp posting follow up"); + return YES; +} + // Override our base class --(NSSet*)managedViewList { +- (NSSet*)managedViewList { return [NSSet setWithObject:@"keychain"]; } @@ -48,23 +53,30 @@ [super setUp]; - self.keychainZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"keychain" ownerName:CKCurrentUserDefaultName]; - self.keychainZone = [[FakeCKZone alloc] initZone: self.keychainZoneID]; + if(SecCKKSIsEnabled()) { + self.keychainZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"keychain" ownerName:CKCurrentUserDefaultName]; + self.keychainZone = [[FakeCKZone alloc] initZone: self.keychainZoneID]; - [self.ckksZones addObject:self.keychainZoneID]; + [self.ckksZones addObject:self.keychainZoneID]; - // Wait for the ViewManager to be brought up - XCTAssertEqual(0, [self.injectedManager.completedSecCKKSInitialize wait:20*NSEC_PER_SEC], "No timeout waiting for SecCKKSInitialize"); + // Wait for the ViewManager to be brought up + 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"); + self.keychainView = [[CKKSViewManager manager] findOrCreateView:@"keychain"]; + XCTAssertNotNil(self.keychainView, "CKKSViewManager created the keychain view"); + [self.ckksViews addObject:self.keychainView]; + } // Check that your environment is set up correctly XCTAssertFalse([CKKSManifest shouldSyncManifests], "Manifests syncing is disabled"); XCTAssertFalse([CKKSManifest shouldEnforceManifests], "Manifests enforcement is disabled"); + + self.aksLockState = false; // Lie and say AKS is always unlocked + self.mockLockStateTracker = OCMClassMock([CKKSLockStateTracker class]); + OCMStub([self.mockLockStateTracker queryAKSLocked]).andCall(self, @selector(aksLockState)); } + + (void)tearDown { [super tearDown]; SecCKKSResetSyncing(); @@ -81,6 +93,8 @@ self.keychainView = nil; self.keychainZoneID = nil; + [self.injectedManager haltAll]; + [super tearDown]; } diff --git a/keychain/ckks/tests/CloudKitMockXCTest.h b/keychain/ckks/tests/CloudKitMockXCTest.h index 3845ac96..a108921e 100644 --- a/keychain/ckks/tests/CloudKitMockXCTest.h +++ b/keychain/ckks/tests/CloudKitMockXCTest.h @@ -30,7 +30,9 @@ #import #import -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/tests/CKKSMockSOSPresentAdapter.h" +#import "keychain/ckks/tests/CKKSMockOctagonAdapter.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #import "keychain/ckks/tests/MockCloudKit.h" NS_ASSUME_NONNULL_BEGIN @@ -42,6 +44,7 @@ NS_ASSUME_NONNULL_BEGIN @class FakeCKZone; @class CKKSLockStateTracker; @class CKKSReachabilityTracker; +@class SOSCKKSPeerAdapter; @interface CloudKitMockXCTest : XCTestCase @@ -59,28 +62,34 @@ NS_ASSUME_NONNULL_BEGIN @property (nullable) id mockAccountStateTracker; +@property (nullable) id mockTTR; +@property BOOL isTTRRatelimited; +@property (nullable) XCTestExpectation *ttrExpectation; + +// The CloudKit account status @property CKAccountStatus accountStatus; -@property BOOL supportsDeviceToDeviceEncryption; + +// The current HSA2-ness of the world +// Set to 'unknown' to not inject any answer into +@property CKKSAccountStatus fakeHSA2AccountStatus; + @property BOOL iCloudHasValidCredentials; -@property SOSAccountStatus* circleStatus; + @property (readonly) NSString* ckDeviceID; -@property (readonly) CKKSCKAccountStateTracker* accountStateTracker; +@property (readonly) CKKSAccountStateTracker* accountStateTracker; -@property NSString* apsEnvironment; -@property NSString* circlePeerID; +@property NSString* apsEnvironment; @property bool aksLockState; // The current 'AKS lock state' @property (readonly) CKKSLockStateTracker* lockStateTracker; @property (nullable) id mockLockStateTracker; -@property SCNetworkReachabilityFlags reachabilityFlags; // The current 'network reachability flags' @property (readonly) CKKSReachabilityTracker *reachabilityTracker; -@property (nullable) id mockReachabilityTracker; @property (nullable) NSMutableDictionary* zones; -@property (nullable) NSOperationQueue* operationQueue; +@property NSOperationQueue* operationQueue; @property (nullable) NSBlockOperation* ckaccountHoldOperation; @property (nullable) NSBlockOperation* ckModifyHoldOperation; @@ -89,9 +98,16 @@ NS_ASSUME_NONNULL_BEGIN @property bool silentFetchesAllowed; @property bool silentZoneDeletesAllowed; +@property CKKSMockSOSPresentAdapter* mockSOSAdapter; +@property (nullable) CKKSMockOctagonAdapter *mockOctagonAdapter; + +-(NSSet*)managedViewList; @property (nullable) id mockCKKSViewManager; @property (nullable) CKKSViewManager* injectedManager; +// Fill this in to fail the next modifyzones operation +@property (nullable) NSError* nextModifyRecordZonesError; + - (CKKSKey*)fakeTLK:(CKRecordZoneID*)zoneID; - (void)expectCKModifyItemRecords:(NSUInteger)expectedNumberOfRecords @@ -139,6 +155,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)failNextZoneSubscription:(CKRecordZoneID*)zoneID; - (void)failNextZoneSubscription:(CKRecordZoneID*)zoneID withError:(NSError*)error; +- (NSError* _Nullable)shouldFailModifyRecordZonesOperation; +- (void)ensureZoneDeletionAllowed:(FakeCKZone*)zone; + // Use this to assert that a fetch occurs (especially if silentFetchesAllowed = false) - (void)expectCKFetch; @@ -146,6 +165,10 @@ NS_ASSUME_NONNULL_BEGIN // This way, you can modify the CK zone to cause later collisions. - (void)expectCKFetchAndRunBeforeFinished:(void (^_Nullable)(void))blockAfterFetch; +// Introspect the fetch object before allowing it to proceed +- (void)expectCKFetchWithFilter:(BOOL (^)(FakeCKFetchRecordZoneChangesOperation*))operationMatch + runBeforeFinished:(void (^)(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 497a334b..f2caddc4 100644 --- a/keychain/ckks/tests/CloudKitMockXCTest.m +++ b/keychain/ckks/tests/CloudKitMockXCTest.m @@ -32,7 +32,7 @@ #import #import -#include "OSX/sec/securityd/Regressions/SecdTestKeychainUtilities.h" +#include "securityd/Regressions/SecdTestKeychainUtilities.h" #include #include @@ -54,6 +54,9 @@ #include "keychain/ckks/CKKSLockStateTracker.h" #include "keychain/ckks/CKKSReachabilityTracker.h" +#import "tests/secdmockaks/mockaks.h" +#import "utilities/SecTapToRadar.h" + #import "MockCloudKit.h" @interface BoolHolder : NSObject @@ -70,9 +73,11 @@ @implementation CloudKitMockXCTest +@synthesize aksLockState = _aksLockState; + (void)setUp { // Turn on testing + SecCKKSEnable(); SecCKKSTestsEnable(); SecCKKSSetReduceRateLimiting(true); [super setUp]; @@ -82,6 +87,21 @@ #endif } +- (BOOL)isRateLimited:(SecTapToRadar *)ttrRequest +{ + return self.isTTRRatelimited; +} + +- (BOOL)askUserIfTTR:(SecTapToRadar *)ttrRequest +{ + return YES; +} + +- (void)triggerTapToRadar:(SecTapToRadar *)ttrRequest +{ + [self.ttrExpectation fulfill]; +} + - (void)setUp { [super setUp]; @@ -125,11 +145,12 @@ OCMStub([self.mockContainer fetchCurrentDeviceIDWithCompletionHandler: ([OCMArg invokeBlockWithArgs:self.ckDeviceID, [NSNull null], nil])]); self.accountStatus = CKAccountStatusAvailable; - self.supportsDeviceToDeviceEncryption = YES; self.iCloudHasValidCredentials = YES; + self.fakeHSA2AccountStatus = CKKSAccountStatusAvailable; + // Inject a fake operation dependency so we won't respond with the CloudKit account status immediately - // The CKKSCKAccountStateTracker won't send any login/logout calls without that information, so this blocks all CKKS setup + // The CKKSAccountStateTracker won't send any login/logout calls without that information, so this blocks all CKKS setup self.ckaccountHoldOperation = [NSBlockOperation named:@"ckaccount-hold" withBlock:^{ secnotice("ckks", "CKKS CK account status test hold released"); }]; @@ -160,7 +181,6 @@ __strong __typeof(self) blockStrongSelf = weakSelf; CKAccountInfo* account = [[CKAccountInfo alloc] init]; account.accountStatus = blockStrongSelf.accountStatus; - account.supportsDeviceToDeviceEncryption = blockStrongSelf.supportsDeviceToDeviceEncryption; account.hasValidCredentials = blockStrongSelf.iCloudHasValidCredentials; account.accountPartition = CKAccountPartitionTypeProduction; passedBlock((CKAccountInfo*)account, nil); @@ -173,19 +193,29 @@ return NO; }]]); - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; - self.mockAccountStateTracker = OCMClassMock([CKKSCKAccountStateTracker class]); + self.mockAccountStateTracker = OCMClassMock([CKKSAccountStateTracker class]); OCMStub([self.mockAccountStateTracker getCircleStatus]).andCall(self, @selector(circleStatus)); + // Fake out SOS peers + // One trusted non-self peer, but it doesn't have any Octagon keys. Your test can change this if it wants. + // However, note that [self putFakeDeviceStatusInCloudKit:] will likely not do what you want after you change this + CKKSSOSSelfPeer* currentSelfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:@"local-peer" + encryptionKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + signingKey:[[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]] + viewList:self.managedViewList]; + + self.mockSOSAdapter = [[CKKSMockSOSPresentAdapter alloc] initWithSelfPeer:currentSelfPeer + trustedPeers:[NSSet set] + essential:YES]; + // If we're in circle, come up with a fake circle id. Otherwise, return an error. - self.circlePeerID = [NSString stringWithFormat:@"fake-circle-id-%@", testName]; OCMStub([self.mockAccountStateTracker fetchCirclePeerID: [OCMArg checkWithBlock:^BOOL(void (^passedBlock) (NSString* peerID, NSError * error)) { __strong __typeof(self) strongSelf = weakSelf; if(passedBlock && strongSelf) { - if(strongSelf.circleStatus.status == kSOSCCInCircle) { - passedBlock(strongSelf.circlePeerID, nil); + if(strongSelf.mockSOSAdapter.circleStatus == kSOSCCInCircle) { + passedBlock(strongSelf.mockSOSAdapter.selfPeer.peerID, nil); } else { passedBlock(nil, [NSError errorWithDomain:@"securityd" code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey:@"no account, no circle id"}]); } @@ -199,12 +229,16 @@ self.mockLockStateTracker = OCMClassMock([CKKSLockStateTracker class]); OCMStub([self.mockLockStateTracker queryAKSLocked]).andCall(self, @selector(aksLockState)); - self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; // Lie and say network is available - self.mockReachabilityTracker = OCMClassMock([CKKSReachabilityTracker class]); - OCMStub([self.mockReachabilityTracker getReachabilityFlags:[OCMArg anyPointer]]).andCall(self, @selector(reachabilityFlags)); + self.mockTTR = OCMClassMock([SecTapToRadar class]); + OCMStub([self.mockTTR isRateLimited:[OCMArg any]]).andCall(self, @selector(isRateLimited:)); + OCMStub([self.mockTTR askUserIfTTR:[OCMArg any]]).andCall(self, @selector(askUserIfTTR:)); + OCMStub([self.mockTTR triggerTapToRadar:[OCMArg any]]).andCall(self, @selector(triggerTapToRadar:)); + self.isTTRRatelimited = true; self.mockFakeCKModifyRecordZonesOperation = OCMClassMock([FakeCKModifyRecordZonesOperation class]); OCMStub([self.mockFakeCKModifyRecordZonesOperation ckdb]).andReturn(self.zones); + OCMStub([self.mockFakeCKModifyRecordZonesOperation shouldFailModifyRecordZonesOperation]).andCall(self, @selector(shouldFailModifyRecordZonesOperation)); + OCMStub([self.mockFakeCKModifyRecordZonesOperation ensureZoneDeletionAllowed:[OCMArg any]]).andCall(self, @selector(ensureZoneDeletionAllowed:)); self.mockFakeCKModifySubscriptionsOperation = OCMClassMock([FakeCKModifySubscriptionsOperation class]); @@ -212,6 +246,7 @@ self.mockFakeCKFetchRecordZoneChangesOperation = OCMClassMock([FakeCKFetchRecordZoneChangesOperation class]); OCMStub([self.mockFakeCKFetchRecordZoneChangesOperation ckdb]).andReturn(self.zones); + OCMStub([self.mockFakeCKFetchRecordZoneChangesOperation isNetworkReachable]).andCall(self, @selector(isNetworkReachable)); self.mockFakeCKFetchRecordsOperation = OCMClassMock([FakeCKFetchRecordsOperation class]); OCMStub([self.mockFakeCKFetchRecordsOperation ckdb]).andReturn(self.zones); @@ -265,29 +300,35 @@ return matches; }]]); - self.testZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"testzone" ownerName:CKCurrentUserDefaultName]; // We don't want to use class mocks here, because they don't play well with partial mocks + CKKSCloudKitClassDependencies* cloudKitClassDependencies = [[CKKSCloudKitClassDependencies alloc] initWithFetchRecordZoneChangesOperationClass:[FakeCKFetchRecordZoneChangesOperation class] + fetchRecordsOperationClass:[FakeCKFetchRecordsOperation class] + queryOperationClass:[FakeCKQueryOperation class] + modifySubscriptionsOperationClass:[FakeCKModifySubscriptionsOperation class] + modifyRecordZonesOperationClass:[FakeCKModifyRecordZonesOperation class] + apsConnectionClass:[FakeAPSConnection class] + nsnotificationCenterClass:[FakeNSNotificationCenter class] + nsdistributednotificationCenterClass:[FakeNSDistributedNotificationCenter class] + notifierClass:[FakeCKKSNotifier class]]; + self.mockCKKSViewManager = OCMPartialMock( [[CKKSViewManager alloc] initWithContainerName:SecCKKSContainerName usePCS:SecCKKSContainerUsePCS - fetchRecordZoneChangesOperationClass:[FakeCKFetchRecordZoneChangesOperation class] - fetchRecordsOperationClass:[FakeCKFetchRecordsOperation class] - queryOperationClass:[FakeCKQueryOperation class] - modifySubscriptionsOperationClass:[FakeCKModifySubscriptionsOperation class] - modifyRecordZonesOperationClass:[FakeCKModifyRecordZonesOperation class] - apsConnectionClass:[FakeAPSConnection class] - nsnotificationCenterClass:[FakeNSNotificationCenter class] - notifierClass:[FakeCKKSNotifier class]]); - - OCMStub([self.mockCKKSViewManager viewList]).andCall(self, @selector(managedViewList)); + sosAdapter:self.mockSOSAdapter + cloudKitClassDependencies:cloudKitClassDependencies]); + + OCMStub([self.mockCKKSViewManager defaultViewList]).andCall(self, @selector(managedViewList)); OCMStub([self.mockCKKSViewManager syncBackupAndNotifyAboutSync]); self.injectedManager = self.mockCKKSViewManager; [CKKSViewManager resetManager:false setTo:self.injectedManager]; + // Lie and say network is available + [self.reachabilityTracker setNetworkReachability:true]; + // Make a new fake keychain NSString* tmp_dir = [NSString stringWithFormat: @"/tmp/%@.%X", testName, arc4random()]; [[NSFileManager defaultManager] createDirectoryAtPath:[NSString stringWithFormat: @"%@/Library/Keychains", tmp_dir] withIntermediateDirectories:YES attributes:nil error:NULL]; @@ -299,6 +340,32 @@ kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); } +- (SOSAccountStatus*)circleStatus { + NSError* error = nil; + SOSCCStatus status = [self.mockSOSAdapter circleStatus:&error]; + return [[SOSAccountStatus alloc] init:status error:error]; +} + +- (bool)aksLockState +{ + return _aksLockState; +} + +- (void)setAksLockState:(bool)aksLockState +{ + + if(aksLockState) { + [SecMockAKS lockClassA]; + } else { + [SecMockAKS unlockAllClasses]; + } + _aksLockState = aksLockState; +} + +- (bool)isNetworkReachable { + return self.reachabilityTracker.currentReachability; +} + - (void)ckcontainerSubmitEventMetric:(CKEventMetric*)metric { @try { [self.mockContainerExpectations submitEventMetric:metric]; @@ -315,12 +382,20 @@ } } +- (NSError* _Nullable)shouldFailModifyRecordZonesOperation { + NSError* error = self.nextModifyRecordZonesError; + if(error) { + self.nextModifyRecordZonesError = nil; + return error; + } + return nil; +} - (void)ensureZoneDeletionAllowed:(FakeCKZone*)zone { XCTAssertTrue(self.silentZoneDeletesAllowed, "Should be allowing zone deletes"); } --(CKKSCKAccountStateTracker*)accountStateTracker { +-(CKKSAccountStateTracker*)accountStateTracker { return self.injectedManager.accountTracker; } @@ -341,6 +416,15 @@ } -(void)expectCKFetchAndRunBeforeFinished: (void (^)(void))blockAfterFetch { + [self expectCKFetchWithFilter:^BOOL(FakeCKFetchRecordZoneChangesOperation * op) { + return YES; + } + runBeforeFinished:blockAfterFetch]; +} + +- (void)expectCKFetchWithFilter:(BOOL (^)(FakeCKFetchRecordZoneChangesOperation*))operationMatch + runBeforeFinished:(void (^)(void))blockAfterFetch +{ // Create an object for the block to retain and modify BoolHolder* runAlready = [[BoolHolder alloc] init]; @@ -354,11 +438,11 @@ secnotice("fakecloudkit", "Received an operation (%@), checking if it's a fetch changes", obj); BOOL matches = NO; if ([obj isKindOfClass: [FakeCKFetchRecordZoneChangesOperation class]]) { - matches = YES; + FakeCKFetchRecordZoneChangesOperation *frzco = (FakeCKFetchRecordZoneChangesOperation *)obj; + matches = operationMatch(frzco); runAlready.state = true; secnotice("fakecloudkit", "Running fetch changes: %@", obj); - FakeCKFetchRecordZoneChangesOperation *frzco = (FakeCKFetchRecordZoneChangesOperation *)obj; frzco.blockAfterFetch = blockAfterFetch; [frzco addNullableDependency: strongSelf.ckFetchHoldOperation]; [strongSelf.operationQueue addOperation: frzco]; @@ -415,6 +499,9 @@ } - (void)startCKKSSubsystem { + if(self.fakeHSA2AccountStatus != CKKSAccountStatusUnknown) { + [self.accountStateTracker setHSA2iCloudAccountStatus:self.fakeHSA2AccountStatus]; + } [self startCKAccountStatusMock]; } @@ -425,6 +512,8 @@ if([self.ckaccountHoldOperation isPending]) { [self.operationQueue addOperation: self.ckaccountHoldOperation]; } + + [self.accountStateTracker performInitialDispatches]; } -(void)holdCloudKitModifications { @@ -716,7 +805,11 @@ - (void)failNextZoneCreation:(CKRecordZoneID*)zoneID { XCTAssertNil(self.zones[zoneID], "Zone does not exist yet"); self.zones[zoneID] = [[FakeCKZone alloc] initZone: zoneID]; - self.zones[zoneID].creationError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorNetworkUnavailable userInfo:@{}]; + self.zones[zoneID].creationError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain + code:CKErrorNetworkUnavailable + userInfo:@{ + CKErrorRetryAfterKey: @(0.5), + }]; } // Report success, but don't actually create the zone. @@ -928,13 +1021,13 @@ [statusReturned fulfill]; }]; [self waitForExpectations: @[statusReturned] timeout:20]; - } - // Make sure this happens before teardown. - XCTAssertEqual(0, [self.accountStateTracker.finishedInitialDispatches wait:20*NSEC_PER_SEC], "Account state tracker initialized itself"); + // Make sure this happens before teardown. + 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, 10*NSEC_PER_SEC)), "Account state tracker finished delivering everything"); + dispatch_group_t accountChangesDelivered = [self.accountStateTracker checkForAllDeliveries]; + XCTAssertEqual(0, dispatch_group_wait(accountChangesDelivered, dispatch_time(DISPATCH_TIME_NOW, 10*NSEC_PER_SEC)), "Account state tracker finished delivering everything"); + } } [super tearDown]; @@ -951,9 +1044,6 @@ [self.mockLockStateTracker stopMocking]; self.mockLockStateTracker = nil; - [self.mockReachabilityTracker stopMocking]; - self.mockReachabilityTracker = nil; - [self.mockFakeCKModifyRecordZonesOperation stopMocking]; self.mockFakeCKModifyRecordZonesOperation = nil; @@ -978,9 +1068,15 @@ [self.mockContainer stopMocking]; self.mockContainer = nil; + [self.mockTTR stopMocking]; + self.mockTTR = nil; + self.ttrExpectation = nil; + self.isTTRRatelimited = true; + self.zones = nil; - self.operationQueue = nil; + _mockSOSAdapter = nil; + _mockOctagonAdapter = nil; SecCKKSTestResetFlags(); } diff --git a/keychain/ckks/tests/MockCloudKit.h b/keychain/ckks/tests/MockCloudKit.h index 3aca53f6..b551e87a 100644 --- a/keychain/ckks/tests/MockCloudKit.h +++ b/keychain/ckks/tests/MockCloudKit.h @@ -24,6 +24,7 @@ #if OCTAGON #import +#import #import #import "keychain/ckks/CKKSNotifier.h" @@ -36,8 +37,12 @@ NS_ASSUME_NONNULL_BEGIN typedef NSMutableDictionary FakeCKDatabase; +@interface FakeCKOperation : NSBlockOperation +@property (nonatomic, assign, readonly) BOOL isFinishingOnCallbackQueue; +@end + -@interface FakeCKModifyRecordZonesOperation : NSBlockOperation { +@interface FakeCKModifyRecordZonesOperation : FakeCKOperation { CKOperationConfiguration* _configuration; } @property (nullable) NSError* creationError; @@ -46,10 +51,13 @@ typedef NSMutableDictionary FakeCKDatabase; @property (nonatomic, copy, null_resettable) CKOperationConfiguration *configuration; + (FakeCKDatabase*)ckdb; -+(void)ensureZoneDeletionAllowed:(FakeCKZone*)zone; + ++ (NSError* _Nullable)shouldFailModifyRecordZonesOperation; + ++ (void)ensureZoneDeletionAllowed:(FakeCKZone*)zone; @end -@interface FakeCKModifySubscriptionsOperation : NSBlockOperation { +@interface FakeCKModifySubscriptionsOperation : FakeCKOperation { CKOperationConfiguration* _configuration; } @property (nullable) NSError* subscriptionError; @@ -59,7 +67,7 @@ typedef NSMutableDictionary FakeCKDatabase; + (FakeCKDatabase*)ckdb; @end -@interface FakeCKFetchRecordZoneChangesOperation : NSOperation { +@interface FakeCKFetchRecordZoneChangesOperation : FakeCKOperation { CKOperationConfiguration* _configuration; } @@ -69,15 +77,15 @@ typedef NSMutableDictionary FakeCKDatabase; @property (nullable) void (^blockAfterFetch)(void); @end -@interface FakeCKFetchRecordsOperation : NSBlockOperation +@interface FakeCKFetchRecordsOperation : FakeCKOperation + (FakeCKDatabase*)ckdb; @end -@interface FakeCKQueryOperation : NSBlockOperation +@interface FakeCKQueryOperation : FakeCKOperation + (FakeCKDatabase*)ckdb; @end -@interface FakeAPSConnection : NSObject +@interface FakeAPSConnection : NSObject @end @interface FakeNSNotificationCenter : NSObject @@ -85,6 +93,9 @@ typedef NSMutableDictionary FakeCKDatabase; - (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject; @end +@interface FakeNSDistributedNotificationCenter : NSObject +@end + @interface FakeCKZone : NSObject // Used while mocking: database is the contents of the current current CloudKit database, pastDatabase is the state of the world in the past at different change tokens @property CKRecordZoneID* zoneID; @@ -92,6 +103,10 @@ typedef NSMutableDictionary FakeCKDatabase; @property NSMutableDictionary* currentDatabase; @property NSMutableDictionary*>* pastDatabases; @property bool flag; // used however you'd like in a test +@property (nullable) CKServerChangeToken* limitFetchTo; // Only return partial results up until here (if asking for current change token) +@property (nullable) NSError* limitFetchError; // If limitFetchTo fires, finish the operation with this error (likely a network timeout) +@property int fetchRecordZoneChangesOperationCount; +@property NSMutableArray* fetchRecordZoneChangesTimestamps; // Usually nil. If set, trying to 'create' this zone should fail. @property (nullable) NSError* creationError; @@ -112,8 +127,8 @@ typedef NSMutableDictionary FakeCKDatabase; - (void)addToZone:(CKRecord*)record; // If you want a transaction of adding, use these -- (void)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID; -- (void)_onqueueAddToZone:(CKRecord*)record; +- (CKRecord*)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID; +- (CKRecord*)_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 cac58a90..cb56d641 100644 --- a/keychain/ckks/tests/MockCloudKit.m +++ b/keychain/ckks/tests/MockCloudKit.m @@ -32,7 +32,15 @@ #import #include #import +#import +@implementation FakeCKOperation + +- (BOOL)isFinishingOnCallbackQueue +{ + return NO; +} +@end @implementation FakeCKModifyRecordZonesOperation @synthesize database = _database; @@ -82,6 +90,12 @@ // No error handling whatsoever FakeCKDatabase* ckdb = [FakeCKModifyRecordZonesOperation ckdb]; + NSError* possibleError = [FakeCKModifyRecordZonesOperation shouldFailModifyRecordZonesOperation]; + if(possibleError) { + self.creationError = possibleError; + return; + } + for(CKRecordZone* zone in self.recordZonesToSave) { bool skipCreation = false; FakeCKZone* fakezone = ckdb[zone.zoneID]; @@ -101,7 +115,8 @@ skipCreation = true; } else if(fakezone) { - continue; + // Don't remake the zone, but report to the client that it was created + skipCreation = true; } if(!skipCreation) { @@ -120,18 +135,22 @@ FakeCKZone* zone = ckdb[zoneID]; if(zone) { - // The zone exists. Its deletion will succeed. + // The zone exists. [FakeCKModifyRecordZonesOperation ensureZoneDeletionAllowed:zone]; + ckdb[zoneID] = nil; if(!self.recordZoneIDsDeleted) { self.recordZoneIDsDeleted = [[NSMutableArray alloc] init]; } [self.recordZoneIDsDeleted addObject:zoneID]; + } else { // The zone does not exist! CloudKit will tell us that the deletion failed. if(!self.creationError) { - self.creationError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorPartialFailure userInfo:nil]; + self.creationError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorPartialFailure userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + }]; } // There really should be a better way to do this... @@ -153,6 +172,12 @@ userInfo:nil]; } ++ (NSError* _Nullable)shouldFailModifyRecordZonesOperation +{ + // Should be mocked out! + return nil; +} + +(void)ensureZoneDeletionAllowed:(FakeCKZone*)zone { // Shouldn't ever be called; will be mocked out (void)zone; @@ -209,7 +234,9 @@ // This is an error: the zone doesn't exist self.subscriptionError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorPartialFailure - userInfo:@{CKPartialErrorsByItemIDKey: + userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + CKPartialErrorsByItemIDKey: @{subscription.zoneID:[[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorZoneNotFound userInfo:@{}]} @@ -286,6 +313,12 @@ return self; } ++ (bool)isNetworkReachable +{ + // For mocking purposes. + return true; +} + - (void)main { // iterate through database, and return items that aren't in lastDatabase FakeCKDatabase* ckdb = [FakeCKFetchRecordZoneChangesOperation ckdb]; @@ -309,8 +342,11 @@ return; } - SCNetworkReachabilityFlags reachabilityFlags = [CKKSReachabilityTracker getReachabilityFlags:NULL]; - if ((reachabilityFlags & kSCNetworkReachabilityFlagsReachable) == 0) { + ++zone.fetchRecordZoneChangesOperationCount; + [zone.fetchRecordZoneChangesTimestamps addObject: [NSDate date]]; + + bool networkReachable = [FakeCKFetchRecordZoneChangesOperation isNetworkReachable]; + if (!networkReachable) { NSError *networkError = [NSError errorWithDomain:CKErrorDomain code:CKErrorNetworkFailure userInfo:NULL]; self.fetchRecordZoneChangesCompletionBlock(networkError); return; @@ -328,6 +364,9 @@ __block NSMutableDictionary* lastDatabase = nil; __block NSDictionary* currentDatabase = nil; __block CKServerChangeToken* currentChangeToken = nil; + __block bool moreComing = false; + + __block NSError* opError = nil; dispatch_sync(zone.queue, ^{ lastDatabase = fetchToken ? zone.pastDatabases[fetchToken] : nil; @@ -339,6 +378,14 @@ currentDatabase = zone.currentDatabase; currentChangeToken = zone.currentChangeToken; + + if (zone.limitFetchTo != nil) { + currentDatabase = zone.pastDatabases[zone.limitFetchTo]; + currentChangeToken = zone.limitFetchTo; + zone.limitFetchTo = nil; + opError = zone.limitFetchError; + moreComing = true; + } }); ckksnotice("fakeck", zone.zoneID, "FakeCKFetchRecordZoneChangesOperation(%@): database is currently %@ change token %@ database then: %@", zone.zoneID, currentDatabase, fetchToken, lastDatabase); @@ -370,7 +417,7 @@ }]; self.recordZoneChangeTokensUpdatedBlock(zoneID, currentChangeToken, nil); - self.recordZoneFetchCompletionBlock(zoneID, currentChangeToken, nil, NO, nil); + self.recordZoneFetchCompletionBlock(zoneID, currentChangeToken, nil, moreComing, opError); if(self.blockAfterFetch) { self.blockAfterFetch(); @@ -507,7 +554,9 @@ // I'm really not sure if this is right, but... NSError* zoneNotFoundError = [[CKPrettyError alloc] initWithDomain:CKErrorDomain code:CKErrorZoneNotFound - userInfo:@{}]; + userInfo:@{ + CKErrorRetryAfterKey: @(0.2), + }]; self.queryCompletionBlock(nil, zoneNotFoundError); return; } @@ -551,12 +600,16 @@ return self; } -- (void)setEnabledTopics:(NSArray *)enabledTopics { +- (void)setEnabledTopics:(NSArray *)enabledTopics { +} + +- (void)setDarkWakeTopics:(NSArray *)darkWakeTopics { } @end // Do literally nothing + @implementation FakeNSNotificationCenter + (instancetype)defaultCenter { return [[FakeNSNotificationCenter alloc] init]; @@ -567,6 +620,21 @@ } @end +@implementation FakeNSDistributedNotificationCenter ++ (instancetype)defaultCenter +{ + return [[FakeNSDistributedNotificationCenter alloc] init]; +} +- (void)addObserver:(id)observer selector:(SEL)aSelector name:(nullable NSNotificationName)aName object:(nullable id)anObject { +} +- (void)removeObserver:(id)observer { +} +- (void)postNotificationName:(NSNotificationName)name object:(nullable NSString *)object userInfo:(nullable NSDictionary *)userInfo options:(NSDistributedNotificationOptions)options +{ +} +@end + + @interface FakeCKZone () @property NSMutableArray* fetchErrors; @end @@ -583,6 +651,9 @@ _queue = dispatch_queue_create("fake-ckzone", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _limitFetchTo = nil; + _fetchRecordZoneChangesOperationCount = 0; + _fetchRecordZoneChangesTimestamps = [[NSMutableArray alloc] init]; dispatch_sync(_queue, ^{ [self _onqueueRollChangeToken]; }); @@ -603,7 +674,7 @@ }); } -- (void)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID { +- (CKRecord*)_onqueueAddToZone:(CKKSCKRecordHolder*)item zoneID:(CKRecordZoneID*)zoneID { dispatch_assert_queue(self.queue); CKRecord* record = [item CKRecordWithZoneID: zoneID]; @@ -611,6 +682,7 @@ // Save off the etag item.storedCKRecord = record; + return record; } - (void)addToZone: (CKRecord*) record { @@ -619,7 +691,7 @@ }); } -- (void)_onqueueAddToZone:(CKRecord*)record { +- (CKRecord*)_onqueueAddToZone:(CKRecord*)record { dispatch_assert_queue(self.queue); // Save off this current databse @@ -631,6 +703,7 @@ ckksnotice("fakeck", self.zoneID, "change tag: %@ %@", record.recordChangeTag, record.recordID); record.modificationDate = [NSDate date]; self.currentDatabase[record.recordID] = record; + return record; } - (NSError * _Nullable)errorFromSavingRecord:(CKRecord*) record { diff --git a/keychain/ckks/tests/CKKSAPSReceiverTests.h b/keychain/ckks/tests/OctagonAPSReceiverTests.h similarity index 95% rename from keychain/ckks/tests/CKKSAPSReceiverTests.h rename to keychain/ckks/tests/OctagonAPSReceiverTests.h index d6cc6bf5..77f8504b 100644 --- a/keychain/ckks/tests/CKKSAPSReceiverTests.h +++ b/keychain/ckks/tests/OctagonAPSReceiverTests.h @@ -23,7 +23,7 @@ #if OCTAGON -@interface CKKSAPSReceiverTests : XCTestCase +@interface OctagonAPSReceiverTests : XCTestCase @property CKRecordZoneID* testZoneID; + (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID; diff --git a/keychain/ckks/tests/CKKSAPSReceiverTests.m b/keychain/ckks/tests/OctagonAPSReceiverTests.m similarity index 88% rename from keychain/ckks/tests/CKKSAPSReceiverTests.m rename to keychain/ckks/tests/OctagonAPSReceiverTests.m index fd3555a5..12ae14e6 100644 --- a/keychain/ckks/tests/CKKSAPSReceiverTests.m +++ b/keychain/ckks/tests/OctagonAPSReceiverTests.m @@ -26,8 +26,8 @@ #import #import #import "keychain/ckks/CKKS.h" -#import "keychain/ckks/CKKSAPSReceiver.h" -#import "keychain/ckks/tests/CKKSAPSReceiverTests.h" +#import "keychain/ckks/OctagonAPSReceiver.h" +#import "keychain/ckks/tests/OctagonAPSReceiverTests.h" #import "keychain/ckks/tests/MockCloudKit.h" #import "keychain/ckks/CKKSCondition.h" @@ -62,13 +62,14 @@ @end -@implementation CKKSAPSReceiverTests +@implementation OctagonAPSReceiverTests + (APSIncomingMessage*)messageForZoneID:(CKRecordZoneID*)zoneID { // reverse engineered from source code. Ugly. NSMutableDictionary* zoneInfo = [[NSMutableDictionary alloc] init]; zoneInfo[@"zid"] = zoneID.zoneName; // kCKNotificationCKRecordZoneRecordZoneIDKey + zoneInfo[@"zoid"] = CKCurrentUserDefaultName; // kCKNotificationCKRecordZoneRecordZoneOwnerIDKey NSMutableDictionary* ckinfo = [[NSMutableDictionary alloc] init]; ckinfo[@"fet"] = zoneInfo; // kCKNotificationCKRecordZoneKey @@ -85,7 +86,7 @@ self.testZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"testzone" ownerName:CKCurrentUserDefaultName]; // Make sure our helpers work properly - APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID]; + APSIncomingMessage* message = [OctagonAPSReceiverTests messageForZoneID:self.testZoneID]; XCTAssertNotNil(message, "Should have received a APSIncomingMessage"); CKNotification* notification = [CKNotification notificationFromRemoteNotificationDictionary:message.userInfo]; @@ -106,11 +107,11 @@ - (void)testRegisterAndReceive { __weak __typeof(self)weakSelf = self; - CKKSAPSReceiver* apsr = [[CKKSAPSReceiver alloc] initWithEnvironmentName:@"testenvironment" + OctagonAPSReceiver* apsr = [[OctagonAPSReceiver alloc] initWithEnvironmentName:@"testenvironment" namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[FakeAPSConnection class]]; - XCTAssertNotNil(apsr, "Should have received a CKKSAPSReceiver"); + XCTAssertNotNil(apsr, "Should have received a OctagonAPSReceiver"); CKKSAPSNotificationReceiver* anr = [[CKKSAPSNotificationReceiver alloc] initWithExpectation:[self expectationWithDescription:@"receive notification"] block: @@ -122,7 +123,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 = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID]; + APSIncomingMessage* message = [OctagonAPSReceiverTests messageForZoneID:self.testZoneID]; XCTAssertNotNil(message, "Should have received a APSIncomingMessage"); [apsr connection:apsr.apsConnection didReceiveIncomingMessage:message]; @@ -133,11 +134,11 @@ - (void)testRegisterMultipleAndReceive { __weak __typeof(self)weakSelf = self; - CKKSAPSReceiver* apsr = [[CKKSAPSReceiver alloc] initWithEnvironmentName:@"testenvironment" + OctagonAPSReceiver* apsr = [[OctagonAPSReceiver alloc] initWithEnvironmentName:@"testenvironment" namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[FakeAPSConnection class]]; - XCTAssertNotNil(apsr, "Should have received a CKKSAPSReceiver"); + XCTAssertNotNil(apsr, "Should have received a OctagonAPSReceiver"); CKRecordZoneID* otherZoneID = [[CKRecordZoneID alloc] initWithZoneName:@"otherzone" ownerName:CKCurrentUserDefaultName]; @@ -160,20 +161,20 @@ 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:[CKKSAPSReceiverTests messageForZoneID:self.testZoneID]]; - [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[CKKSAPSReceiverTests messageForZoneID:otherZoneID]]; + [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[OctagonAPSReceiverTests messageForZoneID:self.testZoneID]]; + [apsr connection:apsr.apsConnection didReceiveIncomingMessage:[OctagonAPSReceiverTests messageForZoneID:otherZoneID]]; [self waitForExpectationsWithTimeout:5.0 handler:nil]; } - (void)testReceiveNotificationIfRegisteredAfterDelivery { - CKKSAPSReceiver* apsr = [[CKKSAPSReceiver alloc] initWithEnvironmentName:@"testenvironment" + OctagonAPSReceiver* apsr = [[OctagonAPSReceiver alloc] initWithEnvironmentName:@"testenvironment" namedDelegatePort:SecCKKSAPSNamedPort apsConnectionClass:[FakeAPSConnection class]]; - XCTAssertNotNil(apsr, "Should have received a CKKSAPSReceiver"); + XCTAssertNotNil(apsr, "Should have received a OctagonAPSReceiver"); // Receives a notification for the test zone - APSIncomingMessage* message = [CKKSAPSReceiverTests messageForZoneID:self.testZoneID]; + APSIncomingMessage* message = [OctagonAPSReceiverTests messageForZoneID:self.testZoneID]; XCTAssertNotNil(message, "Should have received a APSIncomingMessage"); [apsr connection:apsr.apsConnection didReceiveIncomingMessage:message]; diff --git a/keychain/ckks/tests/RateLimiterTests.m b/keychain/ckks/tests/RateLimiterTests.m index 00ceb9ee..67f906bc 100644 --- a/keychain/ckks/tests/RateLimiterTests.m +++ b/keychain/ckks/tests/RateLimiterTests.m @@ -57,7 +57,6 @@ @interface RateLimiterTests : XCTestCase @property NSDictionary *config; -@property NSString *filepath; @property NSDate *time; @property RateLimiter *RL; @property TestObject *obj; @@ -126,23 +125,11 @@ if (!_config) { XCTFail(@"Could not deserialize property list: %@", err); } - _filepath = [NSString stringWithFormat:@"/tmp/ratelimitertests_%@.plist", [[NSUUID UUID] UUIDString]]; - if (![configData writeToFile:_filepath atomically:NO]) { - XCTFail(@"Could not write plist to %@", _filepath); - } _RL = [[RateLimiter alloc] initWithConfig:_config]; _obj = [TestObject new]; _time = [NSDate date]; } -- (void)tearDown { - NSError *err = nil; - if (![[NSFileManager defaultManager] removeItemAtPath:_filepath error:&err]) { - XCTFail(@"Couldn't delete file %@: %@", _filepath, err); - } - [super tearDown]; -} - - (void)testInitWithConfig { self.RL = [[RateLimiter alloc] initWithConfig:self.config]; XCTAssertNotNil(self.RL, @"RateLimiter with config succeeds"); @@ -150,15 +137,6 @@ XCTAssertEqualObjects(self.config, self.RL.config, @"config was copied properly"); } -- (void)testInitWithPlist { - RateLimiter *RL = [[RateLimiter alloc] initWithPlistFromURL:[NSURL URLWithString:[NSString stringWithFormat:@"file://%@", self.filepath]]]; - XCTAssertNotNil(RL, @"RateLimiter with plist succeeds"); - XCTAssertNil(RL.assetType, @"initWithPlist means no assetType"); - XCTAssertEqualObjects(self.config, RL.config, @"config was loaded properly"); - RL = [[RateLimiter alloc] initWithPlistFromURL:[NSURL URLWithString:[NSString stringWithFormat:@"file://%@.nonexisting", self.filepath]]]; - XCTAssertNil(RL, "Cannot instantiate RateLimiter with invalid plist URL"); -} - - (void)testEncodingAndDecoding { NSDate* date = [NSDate date]; NSDate* limit = nil; @@ -179,11 +157,6 @@ XCTAssertNil(RL2.assetType, @"assetType remains nil"); } -- (void)testInitWithAssetType { - // Not implemented yet, expect nil - XCTAssertNil([[RateLimiter alloc] initWithAssetType:@"test"]); -} - - (void)testReset { NSDate *limitTime = nil; [self.RL judge:[TestObject new] at:self.time limitTime:&limitTime]; @@ -231,7 +204,7 @@ // While check is performed at the start of the loop, so now stateSize > maxStateSize. Judge should realize this right away, try to cope, fail and throw a fit XCTAssertEqual([self.RL judge:self.obj at:self.time limitTime:&limitTime], RateLimiterBadnessOverloaded, @"RateLimiter overloaded"); - XCTAssertEqualObjects(limitTime, [self.time dateByAddingTimeInterval:[self.config[@"general"][@"overloadDuration"] intValue]], @"Overload duration matches expectations"); + XCTAssertEqualObjects(limitTime, [self.time dateByAddingTimeInterval:[self.config[@"general"][@"overloadDuration"] unsignedIntValue]], @"Overload duration matches expectations"); } - (void)testTrimmingDueToTime { diff --git a/keychain/ckks/tests/testrunner/KeychainCKKS.plist b/keychain/ckks/tests/testrunner/KeychainCKKS.plist index 9424b386..7e285bc2 100644 --- a/keychain/ckks/tests/testrunner/KeychainCKKS.plist +++ b/keychain/ckks/tests/testrunner/KeychainCKKS.plist @@ -13,6 +13,10 @@ CKKSTests WorkingDirectory /AppleInternal/XCTests/com.apple.security/ + ShowSubtestResults + + Timeout + 1200 Command BATS_XCTEST_CMD CKKSTests.xctest diff --git a/keychain/ckksctl/ckksctl.m b/keychain/ckksctl/ckksctl.m index 19d91bab..7b200d99 100644 --- a/keychain/ckksctl/ckksctl.m +++ b/keychain/ckksctl/ckksctl.m @@ -33,21 +33,53 @@ static void nsprintf(NSString *fmt, ...) #endif } -static NSDictionary* flattenNSErrorsInDictionary(NSDictionary* dict) { +// Mutual recursion to set up an object for jsonification +static NSDictionary* cleanDictionaryForJSON(NSDictionary* dict); + +static id cleanObjectForJSON(id obj) { + if(!obj) { + return nil; + } + if([obj isKindOfClass:[NSError class]]) { + NSError* obje = (NSError*) obj; + NSMutableDictionary* newErrorDict = [@{@"code": @(obje.code), @"domain": obje.domain} mutableCopy]; + newErrorDict[@"userInfo"] = cleanDictionaryForJSON(obje.userInfo); + return newErrorDict; + } else if([NSJSONSerialization isValidJSONObject:obj]) { + return obj; + + } else if ([obj isKindOfClass: [NSNumber class]]) { + return obj; + + } else if([obj isKindOfClass: [NSData class]]) { + NSData* dataObj = (NSData*)obj; + return [dataObj base64EncodedStringWithOptions:0]; + + } else if ([obj isKindOfClass: [NSDictionary class]]) { + return cleanDictionaryForJSON((NSDictionary*) obj); + + } else if ([obj isKindOfClass: [NSArray class]]) { + NSArray* arrayObj = (NSArray*)obj; + NSMutableArray* cleanArray = [NSMutableArray arrayWithCapacity:arrayObj.count]; + + for(id x in arrayObj) { + [cleanArray addObject: cleanObjectForJSON(x)]; + } + return cleanArray; + + } else { + return [obj description]; + } +} + +static NSDictionary* cleanDictionaryForJSON(NSDictionary* dict) { if(!dict) { return nil; } NSMutableDictionary* mutDict = [dict mutableCopy]; for(id key in mutDict.allKeys) { id obj = mutDict[key]; - if([obj isKindOfClass:[NSError class]]) { - NSError* obje = (NSError*) obj; - NSMutableDictionary* newErrorDict = [@{@"code": @(obje.code), @"domain": obje.domain} mutableCopy]; - newErrorDict[@"userInfo"] = flattenNSErrorsInDictionary(obje.userInfo); - mutDict[key] = newErrorDict; - } else if(![NSJSONSerialization isValidJSONObject:obj]) { - mutDict[key] = [obj description]; - } + mutDict[key] = cleanObjectForJSON(obj); } return mutDict; } @@ -57,18 +89,7 @@ static void print_result(NSDictionary *dict, bool json_flag) if (json_flag) { NSError *err; - // NSErrors don't know how to JSON-ify themselves, for some reason - // This will flatten a single layer of them - if(![NSJSONSerialization isValidJSONObject:dict]) { - dict = flattenNSErrorsInDictionary(dict); - } - - if(![NSJSONSerialization isValidJSONObject:dict]) { - printf("Still unsure how to JSONify the following object:\n"); - print_dict(dict, 0); - } - - NSData *json = [NSJSONSerialization dataWithJSONObject:dict + NSData *json = [NSJSONSerialization dataWithJSONObject:cleanDictionaryForJSON(dict) options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) error:&err]; if (!json) { @@ -272,34 +293,26 @@ static void print_entry(id k, id v, int ind) printf("ERROR FETCHING STATUS: %s\n", [[error description] UTF8String]); } -#define pop(d, key) ({ id x = d[key]; d[key] = nil; x; }) +#define pop(d, key, cls) ({ id x = d[key]; d[key] = nil; [x isKindOfClass: [cls class]] ? x : nil; }) // First result is always global state // Ideally, this would come in another parameter, but we can't change the protocol until // CKKS: remove PCS's use of CKKSControlProtocol NSMutableDictionary* global = [result[0] mutableCopy]; if(global) { - NSString* selfPeers = pop(global, @"selfPeers"); - NSString* selfPeersError = pop(global, @"selfPeersError"); - NSArray* trustedPeers = pop(global, @"trustedPeers"); - NSString* trustedPeersError = pop(global, @"trustedPeersError"); - NSString* reachability = pop(global, @"reachability"); - NSString* ckdeviceID = pop(global, @"ckdeviceID"); - NSString* ckdeviceIDError = pop(global, @"ckdeviceIDError"); + NSString* reachability = pop(global, @"reachability", NSString); + NSString* ckdeviceID = pop(global, @"ckdeviceID", NSString); + NSString* ckdeviceIDError = pop(global, @"ckdeviceIDError", NSString); + NSString* lockStateTracker = pop(global,@"lockstatetracker", NSString); + NSString* retry = pop(global,@"cloudkitRetryAfter", NSString); printf("================================================================================\n\n"); printf("Global state:\n\n"); - printf("Current self: %s\n", [[selfPeers description] UTF8String]); - if(![selfPeersError isEqual: [NSNull null]]) { - printf("Self Peers Error: %s\n", [[selfPeersError description] UTF8String]); - } - printf("Trusted peers: %s\n", [[trustedPeers description] UTF8String]); - if(![trustedPeersError isEqual: [NSNull null]]) { - printf("Trusted Peers Error: %s\n", [[trustedPeersError description] UTF8String]); - } printf("Reachability: %s\n", [[reachability description] UTF8String]); + printf("Retry: %s\n", [[retry description] UTF8String]); printf("CK DeviceID: %s\n", [[ckdeviceID description] UTF8String]); printf("CK DeviceID Error: %s\n", [[ckdeviceIDError description] UTF8String]); + printf("Lock state: %s\n", [[lockStateTracker description] UTF8String]); printf("\n"); } @@ -313,49 +326,48 @@ static void print_entry(id k, id v, int ind) for(NSDictionary* viewStatus in remainingViews) { NSMutableDictionary* status = [viewStatus mutableCopy]; - NSString* viewName = pop(status,@"view"); - NSString* accountStatus = pop(status,@"ckaccountstatus"); - NSString* lockStateTracker = pop(status,@"lockstatetracker"); - NSString* accountTracker = pop(status,@"accounttracker"); - NSString* fetcher = pop(status,@"fetcher"); - NSString* zoneCreated = pop(status,@"zoneCreated"); - NSString* zoneCreatedError = pop(status,@"zoneCreatedError"); - NSString* zoneSubscribed = pop(status,@"zoneSubscribed"); - NSString* zoneSubscribedError = pop(status,@"zoneSubscribedError"); - NSString* zoneInitializeScheduler = pop(status,@"zoneInitializeScheduler"); - NSString* keystate = pop(status,@"keystate"); - NSString* keyStateError = pop(status,@"keyStateError"); - NSString* statusError = pop(status,@"statusError"); - NSString* currentTLK = pop(status,@"currentTLK"); - NSString* currentClassA = pop(status,@"currentClassA"); - NSString* currentClassC = pop(status,@"currentClassC"); - NSString* currentTLKPtr = pop(status,@"currentTLKPtr"); - NSString* currentClassAPtr = pop(status,@"currentClassAPtr"); - NSString* currentClassCPtr = pop(status,@"currentClassCPtr"); - NSString* currentManifestGeneration = pop(status,@"currentManifestGen"); - - NSDictionary* oqe = pop(status,@"oqe"); - NSDictionary* iqe = pop(status,@"iqe"); - NSDictionary* keys = pop(status,@"keys"); - NSDictionary* ckmirror = pop(status,@"ckmirror"); - NSArray* devicestates = pop(status, @"devicestates"); - NSArray* tlkshares = pop(status, @"tlkshares"); - - - NSString* zoneSetupOperation = pop(status,@"zoneSetupOperation"); - NSString* keyStateOperation = pop(status,@"keyStateOperation"); - NSString* lastIncomingQueueOperation = pop(status,@"lastIncomingQueueOperation"); - NSString* lastNewTLKOperation = pop(status,@"lastNewTLKOperation"); - NSString* lastOutgoingQueueOperation = pop(status,@"lastOutgoingQueueOperation"); - NSString* lastProcessReceivedKeysOperation = pop(status,@"lastProcessReceivedKeysOperation"); - NSString* lastReencryptOutgoingItemsOperation = pop(status,@"lastReencryptOutgoingItemsOperation"); - NSString* lastScanLocalItemsOperation = pop(status,@"lastScanLocalItemsOperation"); + NSString* viewName = pop(status,@"view", NSString); + NSString* accountStatus = pop(status,@"ckaccountstatus", NSString); + NSString* accountTracker = pop(status,@"accounttracker", NSString); + NSString* fetcher = pop(status,@"fetcher", NSString); + NSString* zoneCreated = pop(status,@"zoneCreated", NSString); + NSString* zoneCreatedError = pop(status,@"zoneCreatedError", NSString); + NSString* zoneSubscribed = pop(status,@"zoneSubscribed", NSString); + NSString* zoneSubscribedError = pop(status,@"zoneSubscribedError", NSString); + NSString* zoneInitializeScheduler = pop(status,@"zoneInitializeScheduler", NSString); + NSString* keystate = pop(status,@"keystate", NSString); + NSString* keyStateError = pop(status,@"keyStateError", NSString); + NSString* statusError = pop(status,@"statusError", NSString); + NSString* currentTLK = pop(status,@"currentTLK", NSString); + NSString* currentClassA = pop(status,@"currentClassA", NSString); + NSString* currentClassC = pop(status,@"currentClassC", NSString); + NSString* currentTLKPtr = pop(status,@"currentTLKPtr", NSString); + NSString* currentClassAPtr = pop(status,@"currentClassAPtr", NSString); + NSString* currentClassCPtr = pop(status,@"currentClassCPtr", NSString); + NSString* currentManifestGeneration = pop(status,@"currentManifestGen", NSString); + NSArray* launchSequence = pop(status, @"launchSequence", NSArray); + + NSDictionary* oqe = pop(status,@"oqe", NSDictionary); + NSDictionary* iqe = pop(status,@"iqe", NSDictionary); + NSDictionary* keys = pop(status,@"keys", NSDictionary); + NSDictionary* ckmirror = pop(status,@"ckmirror", NSDictionary); + NSArray* devicestates = pop(status, @"devicestates", NSArray); + NSArray* tlkshares = pop(status, @"tlkshares", NSArray); + + NSString* zoneSetupOperation = pop(status,@"zoneSetupOperation", NSString); + NSString* keyStateOperation = pop(status,@"keyStateOperation", NSString); + NSString* lastIncomingQueueOperation = pop(status,@"lastIncomingQueueOperation", NSString); + NSString* lastNewTLKOperation = pop(status,@"lastNewTLKOperation", NSString); + NSString* lastOutgoingQueueOperation = pop(status,@"lastOutgoingQueueOperation", NSString); + NSString* lastProcessReceivedKeysOperation = pop(status,@"lastProcessReceivedKeysOperation", NSString); + NSString* lastReencryptOutgoingItemsOperation = pop(status,@"lastReencryptOutgoingItemsOperation", NSString); + NSString* lastScanLocalItemsOperation = pop(status,@"lastScanLocalItemsOperation", NSString); printf("================================================================================\n\n"); printf("View: %s\n\n", [viewName UTF8String]); - if(![statusError isEqual: [NSNull null]]) { + if(statusError != nil) { printf("ERROR FETCHING STATUS: %s\n\n", [statusError UTF8String]); } @@ -373,18 +385,16 @@ static void print_entry(id k, id v, int ind) } printf("Key state: %s\n", [keystate UTF8String]); - if(![keyStateError isEqual: [NSNull null]]) { + if(keyStateError != nil) { printf("Key State Error: %s\n", [keyStateError UTF8String]); } - printf("Lock state: %s\n", [lockStateTracker UTF8String]); - - printf("Current TLK: %s\n", ![currentTLK isEqual: [NSNull null]] + printf("Current TLK: %s\n", currentTLK != nil ? [currentTLK UTF8String] : [[NSString stringWithFormat:@"missing; pointer is %@", currentTLKPtr] UTF8String]); - printf("Current ClassA: %s\n", ![currentClassA isEqual: [NSNull null]] + printf("Current ClassA: %s\n", currentClassA != nil ? [currentClassA UTF8String] : [[NSString stringWithFormat:@"missing; pointer is %@", currentClassAPtr] UTF8String]); - printf("Current ClassC: %s\n", ![currentClassC isEqual: [NSNull null]] + printf("Current ClassC: %s\n", currentClassC != nil ? [currentClassC UTF8String] : [[NSString stringWithFormat:@"missing; pointer is %@", currentClassCPtr] UTF8String]); @@ -393,20 +403,25 @@ static void print_entry(id k, id v, int ind) printf("Outgoing Queue counts: %s\n", [[oqe description] UTF8String]); printf("Incoming Queue counts: %s\n", [[iqe description] UTF8String]); printf("Key counts: %s\n", [[keys description] UTF8String]); - printf("latest manifest generation: %s\n", [currentManifestGeneration isEqual:[NSNull null]] ? "null" : currentManifestGeneration.UTF8String); + printf("latest manifest generation: %s\n", currentManifestGeneration == nil ? "null" : currentManifestGeneration.UTF8String); printf("Item counts (by key): %s\n", [[ckmirror description] UTF8String]); printf("Peer states: %s\n", [[devicestates description] UTF8String]); printf("zone change fetcher: %s\n", [[fetcher description] UTF8String]); - printf("zoneSetupOperation: %s\n", [zoneSetupOperation isEqual: [NSNull null]] ? "never" : [zoneSetupOperation UTF8String]); - printf("keyStateOperation: %s\n", [keyStateOperation isEqual: [NSNull null]] ? "never" : [keyStateOperation UTF8String]); - 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("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]); + printf("zoneSetupOperation: %s\n", zoneSetupOperation == nil ? "never" : [zoneSetupOperation UTF8String]); + printf("keyStateOperation: %s\n", keyStateOperation == nil ? "never" : [keyStateOperation UTF8String]); + printf("lastIncomingQueueOperation: %s\n", lastIncomingQueueOperation == nil ? "never" : [lastIncomingQueueOperation UTF8String]); + printf("lastNewTLKOperation: %s\n", lastNewTLKOperation == nil ? "never" : [lastNewTLKOperation UTF8String]); + printf("lastOutgoingQueueOperation: %s\n", lastOutgoingQueueOperation == nil ? "never" : [lastOutgoingQueueOperation UTF8String]); + printf("lastProcessReceivedKeysOperation: %s\n", lastProcessReceivedKeysOperation == nil ? "never" : [lastProcessReceivedKeysOperation UTF8String]); + printf("lastReencryptOutgoingItemsOperation: %s\n", lastReencryptOutgoingItemsOperation == nil ? "never" : [lastReencryptOutgoingItemsOperation UTF8String]); + printf("lastScanLocalItemsOperation: %s\n", lastScanLocalItemsOperation == nil ? "never" : [lastScanLocalItemsOperation UTF8String]); + + printf("Launch sequence:\n"); + for (NSString *event in launchSequence) { + printf("\t%s\n", [[event description] UTF8String]); + } if(status.allKeys.count > 0u) { printf("\nExtra information: %s\n", [[status description] UTF8String]); @@ -460,7 +475,31 @@ static void print_entry(id k, id v, int ind) printf("Complete.\n"); ret = 0; } + dispatch_semaphore_signal(sema); + }]; + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { + printf("\n\nError: timed out waiting for response\n"); + return -1; + } + +#endif // OCTAGON + return ret; +} + +- (long)ckmetric { + __block long ret = 0; +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.control rpcCKMetric:@"testMetric" attributes:@{ @"testAttribute" : @"value" } reply:^(NSError* error) { + if(error) { + printf("Error sending metric: %s\n", [[error description] UTF8String]); + ret = (error.code == 0 ? -1 : error.code); + } else { + printf("Complete.\n"); + ret = 0; + } dispatch_semaphore_signal(sema); }]; @@ -470,6 +509,7 @@ static void print_entry(id k, id v, int ind) } #endif // OCTAGON return ret; + } @end @@ -483,6 +523,7 @@ static int resetCloudKit = false; static int fetch = false; static int push = false; static int json = false; +static int ckmetric = false; static char* viewArg = NULL; @@ -499,6 +540,7 @@ int main(int argc, char **argv) { .command="resync", .flag=&resync, .flagval=true, .description="Resync all data with what's in CloudKit"}, { .command="reset", .flag=&reset, .flagval=true, .description="All local data will be wiped, and data refetched from CloudKit"}, { .command="reset-cloudkit", .flag=&resetCloudKit, .flagval=true, .description="All data in CloudKit will be removed and replaced with what's local"}, + { .command="ckmetric", .flag=&ckmetric, .flagval=true, .description="Push CloudKit metric"}, {} }; @@ -517,7 +559,7 @@ int main(int argc, char **argv) @autoreleasepool { NSError* error = nil; - CKKSControl* rpc = [CKKSControl controlObject:&error]; + CKKSControl* rpc = [CKKSControl CKKSControlObject:false error:&error]; if(error || !rpc) { errx(1, "no CKKSControl failed: %s", [[error description] UTF8String]); } @@ -559,6 +601,8 @@ int main(int argc, char **argv) return (int)[ctl resetCloudKit:view]; } else if(resync) { return (int)[ctl resync:view]; + } else if(ckmetric) { + return (int)[ctl ckmetric]; } else { print_usage(&args); return -1; diff --git a/keychain/escrowrequest/EscrowRequestController.h b/keychain/escrowrequest/EscrowRequestController.h new file mode 100644 index 00000000..c5da139f --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestController.h @@ -0,0 +1,29 @@ + +#import +#import "keychain/ot/OctagonStateMachine.h" + +NS_ASSUME_NONNULL_BEGIN + +extern OctagonState* const EscrowRequestStateNothingToDo; +extern OctagonState* const EscrowRequestStateTriggerCloudServices; +extern OctagonState* const EscrowRequestStateAttemptEscrowUpload; +extern OctagonState* const EscrowRequestStateWaitForUnlock; + +@class CKKSLockStateTracker; + +@interface EscrowRequestController : NSObject +@property OctagonStateMachine* stateMachine; + +// Use this for testing: if set to true, we will always attempt to trigger CloudServices if needed, even if we've done it recently +@property bool forceIgnoreCloudServicesRateLimiting; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithLockStateTracker:(CKKSLockStateTracker*)lockStateTracker; + +- (void)triggerEscrowUpdateRPC:(nonnull NSString *)reason + reply:(nonnull void (^)(NSError * _Nullable))reply; + +- (void)storePrerecordsInEscrowRPC:(void (^)(uint64_t count, NSError* _Nullable error))reply; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/EscrowRequestController.m b/keychain/escrowrequest/EscrowRequestController.m new file mode 100644 index 00000000..f985e503 --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestController.m @@ -0,0 +1,227 @@ + +#import "utilities/debugging.h" + +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ot/OTStates.h" +#import "keychain/escrowrequest/EscrowRequestController.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" + +#import "keychain/ckks/CKKSLockStateTracker.h" + +#import "keychain/ot/ObjCImprovements.h" + +#import "keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h" +#import "keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h" + +#import "keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h" +#import "keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h" + +OctagonState* const EscrowRequestStateNothingToDo = (OctagonState*)@"nothing_to_do"; +OctagonState* const EscrowRequestStateTriggerCloudServices = (OctagonState*)@"trigger_cloudservices"; + +OctagonState* const EscrowRequestStateAttemptEscrowUpload = (OctagonState*)@"trigger_escrow_upload"; +OctagonState* const EscrowRequestStateWaitForUnlock = (OctagonState*)@"wait_for_unlock"; + +@interface EscrowRequestController () +@property dispatch_queue_t queue; +@property CKKSLockStateTracker* lockStateTracker; +@property bool haveRecordedDate; +@end + +@implementation EscrowRequestController + +- (instancetype)initWithLockStateTracker:(CKKSLockStateTracker*)lockStateTracker +{ + if((self = [super init])) { + _queue = dispatch_queue_create("EscrowRequestControllerQueue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + _lockStateTracker = lockStateTracker; + + _stateMachine = [[OctagonStateMachine alloc] initWithName:@"escrowrequest" + states:[NSSet setWithArray:@[EscrowRequestStateNothingToDo, + EscrowRequestStateTriggerCloudServices, + EscrowRequestStateAttemptEscrowUpload, + EscrowRequestStateWaitForUnlock]] + initialState:EscrowRequestStateNothingToDo + queue:_queue + stateEngine:self + lockStateTracker:lockStateTracker]; + + _forceIgnoreCloudServicesRateLimiting = false; + } + + return self; +} + +- (CKKSResultOperation * _Nullable)_onqueueNextStateMachineTransition:(nonnull OctagonState *)currentState + flags:(nonnull OctagonFlags *)flags + pendingFlags:(nonnull id)pendingFlagHandler +{ + if([flags _onqueueContains:OctagonFlagEscrowRequestInformCloudServicesOperation]) { + [flags _onqueueRemoveFlag:OctagonFlagEscrowRequestInformCloudServicesOperation]; + return [[EscrowRequestInformCloudServicesOperation alloc] initWithIntendedState:EscrowRequestStateNothingToDo + errorState:EscrowRequestStateNothingToDo + lockStateTracker:self.lockStateTracker]; + } + + if([currentState isEqualToString:EscrowRequestStateTriggerCloudServices]) { + return [[EscrowRequestInformCloudServicesOperation alloc] initWithIntendedState:EscrowRequestStateNothingToDo + errorState:EscrowRequestStateNothingToDo + lockStateTracker:self.lockStateTracker]; + } + + if([currentState isEqualToString:EscrowRequestStateAttemptEscrowUpload]) { + return [[EscrowRequestPerformEscrowEnrollOperation alloc] initWithIntendedState:EscrowRequestStateNothingToDo + errorState:EscrowRequestStateNothingToDo + enforceRateLimiting:true + lockStateTracker:self.lockStateTracker]; + } + + if([currentState isEqualToString:EscrowRequestStateWaitForUnlock]) { + secnotice("escrowrequest", "waiting for unlock before continuing with state machine"); + OctagonStateTransitionOperation* op = [OctagonStateTransitionOperation named:@"wait-for-unlock" + entering:EscrowRequestStateNothingToDo]; + [op addNullableDependency:self.lockStateTracker.unlockDependency]; + return op; + } + + NSError* error = nil; + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + if(error) { + if([self.lockStateTracker isLockedError:error]) { + return [OctagonStateTransitionOperation named:@"wait-for-unlock" + entering:EscrowRequestStateWaitForUnlock]; + } + secnotice("escrowrequest", "failed to fetch records from keychain, nothing to do: %@", error); + return nil; + } + + // First, do we need to poke CloudServices? + for(SecEscrowPendingRecord* record in records) { + // Completed records don't need anything. + if(record.hasUploadCompleted && record.uploadCompleted) { + continue; + } + + if (!self.haveRecordedDate) { + NSDate *date = [[CKKSAnalytics logger] datePropertyForKey:ESRPendingSince]; + if (date == NULL) { + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:ESRPendingSince]; + } + self.haveRecordedDate = true; + } + + uint64_t fiveMinutesAgo = ((uint64_t)[[NSDate date] timeIntervalSince1970] * 1000) - (1000*60*5); + + if(!record.certCached) { + if(!self.forceIgnoreCloudServicesRateLimiting && (record.hasLastCloudServicesTriggerTime && record.lastCloudServicesTriggerTime >= fiveMinutesAgo)) { + secnotice("escrowrequest", "Request %@ needs to cache a certificate, but that has been attempted recently. Holding off...", record.uuid); + continue; + } + + secnotice("escrowrequest", "Request %@ needs a cached certififcate", record.uuid); + + return [OctagonStateTransitionOperation named:@"escrow-request-cache-cert" + entering:EscrowRequestStateTriggerCloudServices]; + } + + if(record.hasSerializedPrerecord) { + if([record escrowAttemptedWithinLastSeconds:5*60]) { + secnotice("escrowrequest", "Request %@ needs to be stored, but has been attempted recently. Holding off...", record.uuid); + continue; + } + + secnotice("escrowrequest", "Request %@ needs to be stored!", record.uuid); + + return [OctagonStateTransitionOperation named:@"escrow-request-attempt-escrow-upload" + entering:EscrowRequestStateAttemptEscrowUpload]; + } + } + + + return nil; +} + +- (void)triggerEscrowUpdateRPC:(nonnull NSString *)reason + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + [self.stateMachine startOperation]; + + NSError* error = nil; + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + if(error && !([error.domain isEqualToString:NSOSStatusErrorDomain] && error.code == errSecItemNotFound)) { + secnotice("escrowrequest", "failed to fetch records from keychain: %@", error); + reply(error); + return; + } + error = nil; + + secnotice("escrowrequest", "Investigating a new escrow request"); + + BOOL escrowRequestExists = NO; + for(SecEscrowPendingRecord* existingRecord in records) { + if(existingRecord.uploadCompleted) { + continue; + } + + if (existingRecord.hasAltDSID) { + continue; + } + + secnotice("escrowrequest", "Retriggering an existing escrow request: %@", existingRecord); + existingRecord.hasCertCached = false; + existingRecord.serializedPrerecord = nil; + + [existingRecord saveToKeychain:&error]; + if(error) { + secerror("escrowrequest: Unable to save modified request to keychain: %@", error); + reply(error); + return; + } + + secnotice("escrowrequest", "Retriggering an existing escrow request complete"); + escrowRequestExists = YES; + } + + if(escrowRequestExists == NO){ + secnotice("escrowrequest", "Creating a new escrow request"); + + SecEscrowPendingRecord* record = [[SecEscrowPendingRecord alloc] init]; + record.uuid = [[NSUUID UUID] UUIDString]; + record.altDSID = nil; + record.triggerRequestTime = ((uint64_t)[[NSDate date] timeIntervalSince1970] * 1000); + secnotice("escrowrequest", "beginning a new escrow request (%@)", record.uuid); + + [record saveToKeychain:&error]; + + if(error) { + secerror("escrowrequest: unable to save escrow update request: %@", error); + reply(error); + return; + } + } + + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:ESRPendingSince]; + self.haveRecordedDate = true; + + [self.stateMachine handleFlag:OctagonFlagEscrowRequestInformCloudServicesOperation]; + + reply(nil); +} + +- (void)storePrerecordsInEscrowRPC:(void (^)(uint64_t count, NSError* _Nullable error))reply +{ + EscrowRequestPerformEscrowEnrollOperation* op = [[EscrowRequestPerformEscrowEnrollOperation alloc] initWithIntendedState:EscrowRequestStateNothingToDo + errorState:EscrowRequestStateNothingToDo + enforceRateLimiting:false + lockStateTracker:self.lockStateTracker]; + [self.stateMachine startOperation]; + [self.stateMachine doSimpleStateMachineRPC:@"trigger-escrow-store" + op:op + sourceStates:[NSSet setWithObject:EscrowRequestStateNothingToDo] + reply:^(NSError * _Nullable error) { + secnotice("escrowrequest", "Uploaded %d records with error %@", (int)op.numberOfRecordsUploaded, error); + reply(op.numberOfRecordsUploaded, error); + }]; +} + +@end diff --git a/keychain/escrowrequest/EscrowRequestServer.h b/keychain/escrowrequest/EscrowRequestServer.h new file mode 100644 index 00000000..b0950f54 --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestServer.h @@ -0,0 +1,26 @@ + +#import +#import +#import +#import "keychain/escrowrequest/EscrowRequestXPCProtocol.h" +#import "keychain/escrowrequest/EscrowRequestController.h" + +@class SecEscrowPendingRecord; +@class CKKSLockStateTracker; + +NS_ASSUME_NONNULL_BEGIN + +extern NSString* ESRPendingSince; + +// For securityd->securityd communication, the EscrowRequestServer can pretend to be SecEscrowRequest +@interface EscrowRequestServer : NSObject +@property EscrowRequestController* controller; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithLockStateTracker:(CKKSLockStateTracker*)lockStateTracker; + ++ (EscrowRequestServer*)server; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/EscrowRequestServer.m b/keychain/escrowrequest/EscrowRequestServer.m new file mode 100644 index 00000000..c7bc82db --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestServer.m @@ -0,0 +1,295 @@ + +#import "utilities/debugging.h" + +#import "keychain/escrowrequest/EscrowRequestController.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" +#import "keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h" +#import "keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h" + +#import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/CKKSAnalytics.h" + +NSString* ESRPendingSince = @"ERSPending"; + +@implementation EscrowRequestServer + +- (instancetype)initWithLockStateTracker:(CKKSLockStateTracker*)lockStateTracker +{ + if((self = [super init])) { + _controller = [[EscrowRequestController alloc] initWithLockStateTracker:lockStateTracker]; + } + return self; +} + ++ (EscrowRequestServer*)server +{ + static EscrowRequestServer* server; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + server = [[EscrowRequestServer alloc] initWithLockStateTracker:[CKKSLockStateTracker globalTracker]]; + [server setupAnalytics]; + }); + return server; +} + + ++ (id _Nullable)request:(NSError *__autoreleasing _Nullable * _Nullable)error { + return [EscrowRequestServer server]; +} + +- (BOOL)triggerEscrowUpdate:(nonnull NSString *)reason + error:(NSError * _Nullable __autoreleasing * _Nullable)error +{ + // Magical async code style to sync conversion only happens with NSXPC. + // Use a semaphore here, since we don't have any other option. + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + __block NSError* updateError = nil; + [self triggerEscrowUpdate:reason reply:^(NSError * _Nullable operationError) { + updateError = operationError; + dispatch_semaphore_signal(sema); + }]; + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + + if(error && updateError) { + *error = updateError; + } + return updateError == nil ? YES : NO; +} + +- (NSDictionary *)fetchStatuses:(NSError **)error +{ + __block NSDictionary *status = nil; + + __block NSError* updateError = nil; + [self fetchRequestStatuses:^(NSDictionary * _Nullable requestUUID, NSError * _Nullable blockError) { + status = requestUUID; + updateError = blockError; + }]; + + if(error && updateError) { + *error = updateError; + } + return status; +} + +- (bool)pendingEscrowUpload:(NSError *__autoreleasing _Nullable * _Nullable)error { + __block NSDictionary *result = nil; + __block NSError* updateError = nil; + + [self fetchRequestStatuses:^(NSDictionary * requestUUID, NSError *blockError) { + result = requestUUID; + updateError = blockError; + }]; + + if(updateError) { + secnotice("escrow", "failed to fetch escrow statuses: %@", updateError); + if(error) { + *error = updateError; + } + return NO; + } + if(result == nil || (result && [result count] == 0)) { + return NO; + } + + BOOL inProgress = NO; + for(NSString* status in result.allValues) { + if([status isEqualToString:SecEscrowRequestHavePrecord] || + [status isEqualToString:SecEscrowRequestPendingPasscode] || + [status isEqualToString:SecEscrowRequestPendingCertificate]) { + inProgress = YES; + } + } + + return inProgress; +} + +- (void)cachePrerecord:(NSString*)uuid + serializedPrerecord:(nonnull NSData *)prerecord + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + NSError* error = nil; + SecEscrowPendingRecord* record = [SecEscrowPendingRecord loadFromKeychain:uuid error:&error]; + + if(error) { + secerror("escrowrequest: unable to load uuid %@: %@", uuid, error); + reply(error); + return; + } + + record.serializedPrerecord = prerecord; + + [record saveToKeychain:&error]; + if(error) { + secerror("escrowrequest: unable to save new prerecord for uuid %@: %@", uuid, error); + reply(error); + return; + } + + secnotice("escrowrequest", "saved new prerecord for uuid %@", uuid); + + // Poke the EscrowRequestController, so it will upload the record + [self.controller.stateMachine pokeStateMachine]; + + reply(nil); +} + +- (void)fetchPrerecord:(nonnull NSString *)prerecordUUID + reply:(nonnull void (^)(NSData * _Nullable, NSError * _Nullable))reply +{ + NSError* error = nil; + SecEscrowPendingRecord* record = [SecEscrowPendingRecord loadFromKeychain:prerecordUUID error:&error]; + + if(error) { + secerror("escrowrequest: unable to load prerecord with uuid %@: %@", prerecordUUID, error); + reply(nil, error); + return; + } + + if(record.hasSerializedPrerecord) { + secnotice("escrowrequest", "fetched prerecord for uuid %@", prerecordUUID); + reply(record.serializedPrerecord, nil); + } else { + secerror("escrowrequest: no prerecord for uuid %@: %@", prerecordUUID, error); + // TODO: fill in error + reply(nil, error); + } +} + +- (void)fetchRequestWaitingOnPasscode:(nonnull void (^)(NSString * _Nullable, NSError * _Nullable))reply +{ + NSError* error = nil; + + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + + if(error && [error.domain isEqualToString:NSOSStatusErrorDomain] && error.code == errSecItemNotFound) { + // Fair enough! There are no requests waiting for a passcode. + [[CKKSAnalytics logger] setDateProperty:nil forKey:ESRPendingSince]; + reply(nil, nil); + return; + } + + if(!records || error) { + reply(nil, error); + return; + } + + // Are any of these requests pending? + for(SecEscrowPendingRecord* record in records) { + if(!record.certCached) { + secnotice("escrowrequest", "Escrow request %@ doesn't yet have a certificate cached", record.uuid); + continue; + } + + if(record.hasSerializedPrerecord) { + secnotice("escrowrequest", "Escrow request %@ already has a prerecord; no passcode needed", record.uuid); + continue; + } + + secnotice("escrowrequest", "Escrow request %@ is pending a passcode", record.uuid); + reply(record.uuid, nil); + return; + } + + secnotice("escrowrequest", "No escrow requests need a passcode"); + reply(nil, nil); +} + +- (void)triggerEscrowUpdate:(nonnull NSString *)reason + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + secnotice("escrowrequest", "Triggering an escrow update request due to '%@'", reason); + + [self.controller triggerEscrowUpdateRPC:reason + reply:reply]; +} + +- (void)fetchRequestStatuses:(void (^)(NSDictionary* _Nullable requestUUID, NSError* _Nullable error))reply +{ + NSError* error = nil; + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + + if(error && [error.domain isEqualToString:NSOSStatusErrorDomain] && error.code == errSecItemNotFound) { + // Fair enough! There are no requests waiting for a passcode. + secnotice("escrowrequest", "no extant requests"); + reply(@{}, nil); + return; + } + + if(error) { + secerror("escrowrequest: failed to load requests: %@", error); + reply(nil, error); + } + + secnotice("escrowrequest", "found requests: %@", records); + + NSMutableDictionary* d = [NSMutableDictionary dictionary]; + for(SecEscrowPendingRecord* record in records) { + if(record.uploadCompleted) { + d[record.uuid] = @"complete"; + } else if(record.hasSerializedPrerecord) { + d[record.uuid] = SecEscrowRequestHavePrecord; + } else if(record.certCached) { + d[record.uuid] = SecEscrowRequestPendingPasscode; + } else { + d[record.uuid] = SecEscrowRequestPendingCertificate; + } + } + + reply(d, nil); +} + +- (void)resetAllRequests:(void (^)(NSError* _Nullable error))reply +{ + secnotice("escrowrequest", "deleting all requests"); + + NSError* error = nil; + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + + if(error && [error.domain isEqualToString:NSOSStatusErrorDomain] && error.code == errSecItemNotFound) { + // Fair enough! There are no requests waiting for a passcode. + secnotice("escrowrequest", "no extant requests; nothing to delete"); + reply(nil); + return; + } + + if(error) { + secnotice("escrowrequest", "error fetching records: %@", error); + reply(error); + return; + } + + for(SecEscrowPendingRecord* record in records) { + [record deleteFromKeychain:&error]; + if(error) { + secnotice("escrowrequest", "Unable to delete %@: %@", record, error); + } + } + + // Report the last error, if any. + reply(error); +} + +- (void)storePrerecordsInEscrow:(void (^)(uint64_t count, NSError* _Nullable error))reply +{ + secnotice("escrowrequest", "attempting to store a prerecord in escrow"); + + [self.controller storePrerecordsInEscrowRPC:reply]; +} + +- (void)setupAnalytics +{ + [[CKKSAnalytics logger] AddMultiSamplerForName:@"escorwrequest-healthSummary" withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport block:^NSDictionary *{ + NSMutableDictionary* values = [NSMutableDictionary dictionary]; + + NSDate *date = [[CKKSAnalytics logger] datePropertyForKey:ESRPendingSince]; + if (date) { + values[ESRPendingSince] = @([CKKSAnalytics fuzzyDaysSinceDate:date]); + } + + return values; + }]; +} + +@end diff --git a/keychain/escrowrequest/EscrowRequestServerHelpers.h b/keychain/escrowrequest/EscrowRequestServerHelpers.h new file mode 100644 index 00000000..77aaf2cf --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestServerHelpers.h @@ -0,0 +1,10 @@ + +#ifndef EscrowRequestServerHelpers_h +#define EscrowRequestServerHelpers_h + +#include +bool EscrowRequestServerIsEnabled(void); +void EscrowRequestServerSetEnabled(bool enabled); +void EscrowRequestServerInitialize(void); + +#endif /* EscrowRequestServerHelpers_h */ diff --git a/keychain/escrowrequest/EscrowRequestServerHelpers.m b/keychain/escrowrequest/EscrowRequestServerHelpers.m new file mode 100644 index 00000000..a1bd9b38 --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestServerHelpers.m @@ -0,0 +1,21 @@ + +#import + +#import "utilities/debugging.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" +#import "keychain/escrowrequest/EscrowRequestServerHelpers.h" + +// False by default, to avoid turning this on in tests that don't want it +static bool EscrowRequestServerEnabled = false; +bool EscrowRequestServerIsEnabled(void) { + return EscrowRequestServerEnabled; +} +void EscrowRequestServerSetEnabled(bool enabled) { + EscrowRequestServerEnabled = enabled; +} + +void EscrowRequestServerInitialize(void) { + secnotice("escrowrequest", "performing EscrowRequestServerInitialize"); + EscrowRequestServer* server = [EscrowRequestServer server]; + [server.controller.stateMachine startOperation]; +} diff --git a/keychain/escrowrequest/EscrowRequestXPCProtocol.h b/keychain/escrowrequest/EscrowRequestXPCProtocol.h new file mode 100644 index 00000000..1f3646eb --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestXPCProtocol.h @@ -0,0 +1,32 @@ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +NSXPCInterface* SecEscrowRequestSetupControlProtocol(NSXPCInterface* interface); + + +@protocol EscrowRequestXPCProtocol + +- (void)triggerEscrowUpdate:(NSString*)reason + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)cachePrerecord:(NSString*)uuid + serializedPrerecord:(nonnull NSData *)prerecord + reply:(nonnull void (^)(NSError * _Nullable))reply; + +- (void)fetchPrerecord:(NSString*)prerecordUUID + reply:(void (^)(NSData* _Nullable serializedPrerecord, NSError* _Nullable error))reply; + +- (void)fetchRequestWaitingOnPasscode:(void (^)(NSString* _Nullable requestUUID, NSError* _Nullable error))reply; + +- (void)fetchRequestStatuses:(void (^)(NSDictionary* _Nullable requestUUID, NSError* _Nullable error))reply; + +- (void)resetAllRequests:(void (^)(NSError* _Nullable error))reply; + +- (void)storePrerecordsInEscrow:(void (^)(uint64_t count, NSError* _Nullable error))reply; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/EscrowRequestXPCProtocol.m b/keychain/escrowrequest/EscrowRequestXPCProtocol.m new file mode 100644 index 00000000..2bdaa7ae --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestXPCProtocol.m @@ -0,0 +1,53 @@ + +#import +#import + +#import "keychain/escrowrequest/EscrowRequestXPCProtocol.h" +#import "utilities/debugging.h" + +NSXPCInterface* SecEscrowRequestSetupControlProtocol(NSXPCInterface* interface) { + static NSMutableSet *errClasses; + + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + errClasses = [NSMutableSet set]; + char *classes[] = { + "NSArray", + "NSData", + "NSDate", + "NSDictionary", + "NSError", + "NSNull", + "NSNumber", + "NSOrderedSet", + "NSSet", + "NSString", + "NSURL", + }; + + for (unsigned n = 0; n < sizeof(classes)/sizeof(classes[0]); n++) { + Class cls = objc_getClass(classes[n]); + if (cls) { + [errClasses addObject:cls]; + } + } + }); + + @try { + [interface setClasses:errClasses forSelector:@selector(triggerEscrowUpdate:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(cachePrerecord:serializedPrerecord:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(fetchPrerecord:reply:) argumentIndex:1 ofReply:YES]; + [interface setClasses:errClasses forSelector:@selector(fetchRequestWaitingOnPasscode:) argumentIndex:1 ofReply:YES]; + + } + @catch(NSException* e) { + secerror("SecEscrowRequestSetupControlProtocol failed, continuing, but you might crash later: %@", e); +#if DEBUG + @throw e; +#endif + } + + return interface; +} + diff --git a/keychain/escrowrequest/EscrowRequestXPCServer.h b/keychain/escrowrequest/EscrowRequestXPCServer.h new file mode 100644 index 00000000..56fcc42f --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestXPCServer.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 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@ + */ + +#define kSecuritydEscrowRequestServiceName "com.apple.security.escrow-update" + +__BEGIN_DECLS + +void EscrowRequestXPCServerInitialize(void); + +__END_DECLS diff --git a/keychain/escrowrequest/EscrowRequestXPCServer.m b/keychain/escrowrequest/EscrowRequestXPCServer.m new file mode 100644 index 00000000..96c5a668 --- /dev/null +++ b/keychain/escrowrequest/EscrowRequestXPCServer.m @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2019 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 "utilities/debugging.h" +#import +#import "keychain/escrowrequest/EscrowRequestServer.h" +#import "keychain/escrowrequest/EscrowRequestXPCServer.h" +#import "keychain/escrowrequest/EscrowRequestXPCProtocol.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +@interface EscrowRequestXPCServer : NSObject +@end + +@implementation EscrowRequestXPCServer + +- (BOOL)listener:(__unused NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection *)newConnection +{ + NSNumber *num = [newConnection valueForEntitlement:kSecEntitlementPrivateEscrowRequest]; + if (![num isKindOfClass:[NSNumber class]] || ![num boolValue]) { + secerror("escrow-update: Client pid: %d doesn't have entitlement: %@", + [newConnection processIdentifier], kSecEntitlementPrivateEscrowRequest); + return NO; + } + + secnotice("escrowrequest", "received connection from client pid %d", [newConnection processIdentifier]); + newConnection.exportedInterface = SecEscrowRequestSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(EscrowRequestXPCProtocol)]); + + newConnection.exportedObject = [EscrowRequestServer server]; + + [newConnection resume]; + + return YES; +} +@end + +void +EscrowRequestXPCServerInitialize(void) +{ + static dispatch_once_t once; + static EscrowRequestXPCServer *server; + static NSXPCListener *listener; + + dispatch_once(&once, ^{ + @autoreleasepool { + server = [EscrowRequestXPCServer new]; + + listener = [[NSXPCListener alloc] initWithMachServiceName:@(kSecuritydEscrowRequestServiceName)]; + listener.delegate = server; + [listener resume]; + } + }); +} diff --git a/keychain/escrowrequest/Framework/SecEscrowRequest.h b/keychain/escrowrequest/Framework/SecEscrowRequest.h new file mode 100644 index 00000000..db3e2b54 --- /dev/null +++ b/keychain/escrowrequest/Framework/SecEscrowRequest.h @@ -0,0 +1,45 @@ + +#import + +NS_ASSUME_NONNULL_BEGIN + +extern NSString* const SecEscrowRequestHavePrecord; +extern NSString* const SecEscrowRequestPendingPasscode; +extern NSString* const SecEscrowRequestPendingCertificate; + +@protocol SecEscrowRequestable ++ (id _Nullable)request:(NSError* _Nullable *)error; +- (BOOL)triggerEscrowUpdate:(NSString*)reason + error:(NSError**)error; +- (NSDictionary *_Nullable)fetchStatuses:(NSError **)error; + +- (bool)pendingEscrowUpload:(NSError**)error; + +@end + +@interface SecEscrowRequest : NSObject ++ (SecEscrowRequest* _Nullable)request:(NSError* _Nullable *)error; +- (instancetype)initWithConnection:(NSXPCConnection*)connection; + + +- (BOOL)triggerEscrowUpdate:(NSString*)reason + error:(NSError**)error; + +- (BOOL)cachePrerecord:(NSString*)uuid + serializedPrerecord:(NSData*)prerecord + error:(NSError**)error; + +- (NSData* _Nullable)fetchPrerecord:(NSString*)prerecordUUID + error:(NSError**)error; + +// Returns a UUIDs of an escrow request which is ready to receive the device passcode. +// For a request to be in this state, sbd must have successfully cached a certificate in beginHSA2PasscodeRequest. +- (NSString* _Nullable)fetchRequestWaitingOnPasscode:(NSError**)error; + +// Reset and delete all pending requests. +- (BOOL)resetAllRequests:(NSError**)error; + +- (uint64_t)storePrerecordsInEscrow:(NSError**)error; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/Framework/SecEscrowRequest.m b/keychain/escrowrequest/Framework/SecEscrowRequest.m new file mode 100644 index 00000000..8432a1f1 --- /dev/null +++ b/keychain/escrowrequest/Framework/SecEscrowRequest.m @@ -0,0 +1,248 @@ + +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" + +#import "keychain/escrowrequest/EscrowRequestXPCProtocol.h" +#import "keychain/escrowrequest/EscrowRequestXPCServer.h" + +#import "utilities/debugging.h" + +NSString* const SecEscrowRequestHavePrecord = @"have_prerecord"; +NSString* const SecEscrowRequestPendingPasscode = @"pending_passcode"; +NSString* const SecEscrowRequestPendingCertificate = @"pending_certificate"; + +@interface SecEscrowRequest () +@property NSXPCConnection *connection; +@end + +@implementation SecEscrowRequest + ++ (SecEscrowRequest* _Nullable)request:(NSError* _Nullable *)error +{ + NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydEscrowRequestServiceName) options:0]; + + if (connection == nil) { + if(error) { + *error = [NSError errorWithDomain:@"securityd" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Couldn't create connection (no reason given)"}]; + } + return nil; + } + + NSXPCInterface *interface = SecEscrowRequestSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(EscrowRequestXPCProtocol)]); + connection.remoteObjectInterface = interface; + [connection resume]; + + SecEscrowRequest* c = [[SecEscrowRequest alloc] initWithConnection:connection]; + return c; +} + +- (instancetype)initWithConnection:(NSXPCConnection*)connection { + if(self = [super init]) { + _connection = connection; + } + return self; +} + +- (void)dealloc +{ + [self.connection invalidate]; +} + +// Actual implementation + +- (BOOL)triggerEscrowUpdate:(NSString*)reason error:(NSError**)error +{ + __block NSError* localError = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "triggerEscrowUpdate: Failed to get XPC connection: %@", xpcError); + }]; + + [c triggerEscrowUpdate:reason + reply:^(NSError * _Nullable xpcError) { + localError = xpcError; + + secnotice("escrow", "Triggered escrow update for '%@': %@", reason, xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return localError == nil; +} + +- (BOOL)cachePrerecord:(NSString*)uuid + serializedPrerecord:(NSData*)prerecord + error:(NSError**)error +{ + __block NSError* localError = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "cachePrerecord: Failed to get XPC connection: %@", xpcError); + }]; + + [c cachePrerecord:uuid + serializedPrerecord:prerecord + reply:^(NSError * _Nullable xpcError) { + localError = xpcError; + + secnotice("escrow", "Cached prerecord for %@: %@", uuid, xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return localError == nil; +} + +- (NSData* _Nullable)fetchPrerecord:(NSString*)prerecordUUID + error:(NSError**)error +{ + __block NSError* localError = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "fetchprerecord: Failed to get XPC connection: %@", xpcError); + }]; + + __block NSData* prerecord = nil; + [c fetchPrerecord:prerecordUUID reply:^(NSData * _Nullable requestContents, NSError * _Nullable xpcError) { + prerecord = requestContents; + localError = xpcError; + + secnotice("escrow", "Received prerecord for %@: %@", prerecordUUID, xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return prerecord; +} + +- (NSString* _Nullable)fetchRequestWaitingOnPasscode:(NSError**)error +{ + __block NSError* localError = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "fetchRequestWaitingOnPasscode: Failed to get XPC connection: %@", xpcError); + }]; + + __block NSString* uuid = nil; + [c fetchRequestWaitingOnPasscode:^(NSString * _Nullable requestUUID, NSError * _Nullable xpcError) { + uuid = requestUUID; + localError = xpcError; + + secnotice("escrow", "Received request waiting on passcode: %@ %@", requestUUID, xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return uuid; +} + +- (NSDictionary * _Nullable)fetchStatuses:(NSError**)error +{ + __block NSError* localError = nil; + __block NSDictionary* statuses = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "requestStatuses: Failed to get XPC connection: %@", xpcError); + }]; + + [c fetchRequestStatuses:^(NSDictionary * _Nullable fetchedStatuses, NSError * _Nullable xpcError) { + statuses = fetchedStatuses; + localError = xpcError; + + secnotice("escrow", "Received statuses: %@ %@", statuses, xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return statuses; +} + +- (BOOL)resetAllRequests:(NSError**)error +{ + __block NSError* localError = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "resetAllRequests: Failed to get XPC connection: %@", xpcError); + }]; + + [c resetAllRequests:^(NSError * _Nullable xpcError) { + localError = xpcError; + + secnotice("escrow", "resetAllRequests: %@", xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return localError == nil; +} + +- (uint64_t)storePrerecordsInEscrow:(NSError**)error +{ + __block NSError* localError = nil; + + NSXPCConnection* c = [self.connection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("escrow", "fetchRequestWaitingOnPasscode: Failed to get XPC connection: %@", xpcError); + }]; + + __block uint64_t count = 0; + [c storePrerecordsInEscrow:^(uint64_t requestCount, NSError * _Nullable xpcError) { + count = requestCount; + localError = xpcError; + + secnotice("escrow", "Stored %d records: %@", (int)requestCount, xpcError); + }]; + + if(error && localError) { + *error = localError; + } + + return count; +} + +- (bool)pendingEscrowUpload:(NSError**)error +{ + NSError* localError = nil; + + NSDictionary* result = [self fetchStatuses:&localError]; + if(localError) { + secnotice("escrow", "failed to fetch escrow statuses: %@", localError); + if(error) { + *error = localError; + } + return NO; + } + if(result == nil || (result && [result count] == 0)) { + return NO; + } + + BOOL inProgress = NO; + for(NSString* status in result.allValues) { + if([status isEqualToString:SecEscrowRequestHavePrecord] || + [status isEqualToString:SecEscrowRequestPendingPasscode] || + [status isEqualToString:SecEscrowRequestPendingCertificate]) { + inProgress = YES; + } + } + + return inProgress; +} + +@end diff --git a/keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h b/keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h new file mode 100644 index 00000000..80c0acf7 --- /dev/null +++ b/keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h @@ -0,0 +1,21 @@ + +#import +#import "keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SecEscrowPendingRecord (KeychainSupport) + +- (BOOL)saveToKeychain:(NSError**)error; +- (BOOL)deleteFromKeychain:(NSError**)error; + ++ (SecEscrowPendingRecord* _Nullable)loadFromKeychain:(NSString*)uuid error:(NSError**)error; ++ (NSArray* _Nullable)loadAllFromKeychain:(NSError**)error; +@end + +@interface SecEscrowPendingRecord (EscrowAttemptTimeout) +- (BOOL)escrowAttemptedWithinLastSeconds:(NSTimeInterval)timeInterval; +@end + +NS_ASSUME_NONNULL_END + diff --git a/keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.m b/keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.m new file mode 100644 index 00000000..b4bea60e --- /dev/null +++ b/keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.m @@ -0,0 +1,191 @@ + +#import +#import +#import "OSX/sec/Security/SecItemShim.h" + +#import "OSX/utilities/SecCFRelease.h" +#import "utilities/debugging.h" + +#import "SecEscrowPendingRecord+KeychainSupport.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +@implementation SecEscrowPendingRecord (KeychainSupport) + +- (BOOL)saveToKeychain:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly, + (id)kSecAttrAccessGroup: @"com.apple.sbd", + (id)kSecAttrServer: @"escrow-prerecord", + (id)kSecAttrDescription: [NSString stringWithFormat:@"Escrow Prerecord: %@", self.uuid], + (id)kSecAttrAccount: self.uuid, + (id)kSecValueData : self.data, + (id)kSecAttrIsInvisible: @YES, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrSynchronizable : @NO, + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &result); + + NSError* localerror = nil; + + // Did SecItemAdd fall over due to an existing item? + if(status == errSecDuplicateItem) { + // Add every primary key attribute to this find dictionary + NSMutableDictionary* findQuery = [[NSMutableDictionary alloc] init]; + findQuery[(id)kSecClass] = query[(id)kSecClass]; + findQuery[(id)kSecAttrSynchronizable] = query[(id)kSecAttrSynchronizable]; + findQuery[(id)kSecAttrSyncViewHint] = query[(id)kSecAttrSyncViewHint]; + findQuery[(id)kSecAttrAccessGroup] = query[(id)kSecAttrAccessGroup]; + findQuery[(id)kSecAttrAccount] = query[(id)kSecAttrAccount]; + findQuery[(id)kSecAttrServer] = query[(id)kSecAttrServer]; + findQuery[(id)kSecAttrPath] = query[(id)kSecAttrPath]; + findQuery[(id)kSecUseDataProtectionKeychain] = query[(id)kSecUseDataProtectionKeychain]; + + NSMutableDictionary* updateQuery = [query mutableCopy]; + updateQuery[(id)kSecClass] = nil; + + status = SecItemUpdate((__bridge CFDictionaryRef)findQuery, (__bridge CFDictionaryRef)updateQuery); + + if(status) { + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemUpdate: %d", (int)status]]; + } + } else if(status != 0) { + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemAdd: %d", (int)status]]; + } + + if(localerror) { + if(error) { + *error = localerror; + } + return false; + } else { + return true; + } +} + +- (BOOL)deleteFromKeychain:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessGroup: @"com.apple.sbd", + (id)kSecAttrServer: @"escrow-prerecord", + (id)kSecAttrAccount: self.uuid, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrSynchronizable : @NO, + } mutableCopy]; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + + if(status != errSecSuccess) { + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemAdd: %d", (int)status]];; + } + return false; + } + + return true; +} + ++ (SecEscrowPendingRecord* _Nullable)loadFromKeychain:(NSString*)uuid error:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessGroup: @"com.apple.sbd", + (id)kSecAttrServer: @"escrow-prerecord", + (id)kSecAttrAccount: uuid, + (id)kSecMatchLimit : (id)kSecMatchLimitOne, + (id)kSecAttrSynchronizable : @NO, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecReturnAttributes: @YES, + (id)kSecReturnData: @YES, + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if(status) { + CFReleaseNull(result); + + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + userInfo:@{NSLocalizedDescriptionKey: + [NSString stringWithFormat:@"SecItemCopyMatching: %d", (int)status]}]; + } + return nil; + } + + NSDictionary* resultDict = (NSDictionary*) CFBridgingRelease(result); + SecEscrowPendingRecord* record = [[SecEscrowPendingRecord alloc] initWithData:resultDict[(id)kSecValueData]]; + + //TODO: if no record, add an error here + + return record; +} + ++ (NSArray* _Nullable)loadAllFromKeychain:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessGroup: @"com.apple.sbd", + (id)kSecAttrServer: @"escrow-prerecord", + (id)kSecMatchLimit : (id)kSecMatchLimitAll, + (id)kSecAttrSynchronizable : @NO, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecReturnAttributes: @YES, + (id)kSecReturnData: @YES, + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if(status) { + CFReleaseNull(result); + + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + userInfo:@{NSLocalizedDescriptionKey: + [NSString stringWithFormat:@"SecItemCopyMatching: %d", (int)status]}]; + } + return nil; + } + + NSMutableArray* records = [NSMutableArray array]; + NSDictionary* resultArray = CFBridgingRelease(result); + + for(NSDictionary* item in resultArray) { + SecEscrowPendingRecord* record = [[SecEscrowPendingRecord alloc] initWithData:item[(id)kSecValueData]]; + if(record) { + [records addObject: record]; + } else { + secerror("escrowrequest: Unable to deserialize keychain item"); + } + } + + return records; +} + +@end + +@implementation SecEscrowPendingRecord (EscrowAttemptTimeout) +- (BOOL)escrowAttemptedWithinLastSeconds:(NSTimeInterval)timeInterval +{ + NSDate* limitDate = [NSDate dateWithTimeIntervalSinceNow:-timeInterval]; + uint64_t limitMillis = [limitDate timeIntervalSince1970] * 1000; + + if(self.hasLastEscrowAttemptTime && self.lastEscrowAttemptTime >= limitMillis) { + return YES; + } + return NO; +} +@end diff --git a/keychain/escrowrequest/SecEscrowPendingRecord.proto b/keychain/escrowrequest/SecEscrowPendingRecord.proto new file mode 100644 index 00000000..62995265 --- /dev/null +++ b/keychain/escrowrequest/SecEscrowPendingRecord.proto @@ -0,0 +1,34 @@ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +message SecEscrowPendingRecord { + optional string uuid = 1; + + // True if CloudServices has informed us that it's successfully cached a certificate for this request + optional bool certCached = 2; + + // CloudServices is responsible for serialization and understanding what it has stored here. + // This is a shame, but allows knowledge of what's in a escrow record to live in CloudServices, not securityd. + optional bytes serializedPrerecord = 3; + + // Holds the time, in milliseconds since 1970, that the last SBD trigger was attempted + optional uint64 lastCloudServicesTriggerTime = 4; + + // Holds the time, in milliseconds since 1970, that the last escrow upload was attempted + optional uint64 lastEscrowAttemptTime = 5; + + // If set to true, then this pending record is complete, and can be garbage collected + optional bool uploadCompleted = 6; + + // Number of upload retries + optional uint64 uploadRetries = 7; + + // altDSID for requesting user (will be used for cleanup) + optional string altDSID = 8; + + // Request was generated at the time, ms since 1970 + optional uint64 triggerRequestTime = 9; +} diff --git a/keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h b/keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h new file mode 100644 index 00000000..a8851c0e --- /dev/null +++ b/keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h @@ -0,0 +1,87 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecEscrowPendingRecord.proto + +#import +#import + +#ifdef __cplusplus +#define SECESCROWPENDINGRECORD_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define SECESCROWPENDINGRECORD_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface SecEscrowPendingRecord : PBCodable +{ + uint64_t _lastCloudServicesTriggerTime; + uint64_t _lastEscrowAttemptTime; + uint64_t _triggerRequestTime; + uint64_t _uploadRetries; + NSString *_altDSID; + NSData *_serializedPrerecord; + NSString *_uuid; + BOOL _certCached; + BOOL _uploadCompleted; + struct { + int lastCloudServicesTriggerTime:1; + int lastEscrowAttemptTime:1; + int triggerRequestTime:1; + int uploadRetries:1; + int certCached:1; + int uploadCompleted:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasUuid; +@property (nonatomic, retain) NSString *uuid; + +@property (nonatomic) BOOL hasCertCached; +/** True if CloudServices has informed us that it's successfully cached a certificate for this request */ +@property (nonatomic) BOOL certCached; + +@property (nonatomic, readonly) BOOL hasSerializedPrerecord; +/** + * CloudServices is responsible for serialization and understanding what it has stored here. + * This is a shame, but allows knowledge of what's in a escrow record to live in CloudServices, not securityd. + */ +@property (nonatomic, retain) NSData *serializedPrerecord; + +@property (nonatomic) BOOL hasLastCloudServicesTriggerTime; +/** Holds the time, in milliseconds since 1970, that the last SBD trigger was attempted */ +@property (nonatomic) uint64_t lastCloudServicesTriggerTime; + +@property (nonatomic) BOOL hasLastEscrowAttemptTime; +/** Holds the time, in milliseconds since 1970, that the last escrow upload was attempted */ +@property (nonatomic) uint64_t lastEscrowAttemptTime; + +@property (nonatomic) BOOL hasUploadCompleted; +/** If set to true, then this pending record is complete, and can be garbage collected */ +@property (nonatomic) BOOL uploadCompleted; + +@property (nonatomic) BOOL hasUploadRetries; +/** Number of upload retries */ +@property (nonatomic) uint64_t uploadRetries; + +@property (nonatomic, readonly) BOOL hasAltDSID; +/** altDSID for requesting user (will be used for cleanup) */ +@property (nonatomic, retain) NSString *altDSID; + +@property (nonatomic) BOOL hasTriggerRequestTime; +/** Request was generated at the time, ms since 1970 */ +@property (nonatomic) uint64_t triggerRequestTime; + +// Performs a shallow copy into other +- (void)copyTo:(SecEscrowPendingRecord *)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:(SecEscrowPendingRecord *)other; + +SECESCROWPENDINGRECORD_FUNCTION BOOL SecEscrowPendingRecordReadFrom(__unsafe_unretained SecEscrowPendingRecord *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/escrowrequest/generated_source/SecEscrowPendingRecord.m b/keychain/escrowrequest/generated_source/SecEscrowPendingRecord.m new file mode 100644 index 00000000..689908a9 --- /dev/null +++ b/keychain/escrowrequest/generated_source/SecEscrowPendingRecord.m @@ -0,0 +1,494 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from SecEscrowPendingRecord.proto + +#import "SecEscrowPendingRecord.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 SecEscrowPendingRecord + +- (BOOL)hasUuid +{ + return _uuid != nil; +} +@synthesize uuid = _uuid; +@synthesize certCached = _certCached; +- (void)setCertCached:(BOOL)v +{ + _has.certCached = YES; + _certCached = v; +} +- (void)setHasCertCached:(BOOL)f +{ + _has.certCached = f; +} +- (BOOL)hasCertCached +{ + return _has.certCached; +} +- (BOOL)hasSerializedPrerecord +{ + return _serializedPrerecord != nil; +} +@synthesize serializedPrerecord = _serializedPrerecord; +@synthesize lastCloudServicesTriggerTime = _lastCloudServicesTriggerTime; +- (void)setLastCloudServicesTriggerTime:(uint64_t)v +{ + _has.lastCloudServicesTriggerTime = YES; + _lastCloudServicesTriggerTime = v; +} +- (void)setHasLastCloudServicesTriggerTime:(BOOL)f +{ + _has.lastCloudServicesTriggerTime = f; +} +- (BOOL)hasLastCloudServicesTriggerTime +{ + return _has.lastCloudServicesTriggerTime; +} +@synthesize lastEscrowAttemptTime = _lastEscrowAttemptTime; +- (void)setLastEscrowAttemptTime:(uint64_t)v +{ + _has.lastEscrowAttemptTime = YES; + _lastEscrowAttemptTime = v; +} +- (void)setHasLastEscrowAttemptTime:(BOOL)f +{ + _has.lastEscrowAttemptTime = f; +} +- (BOOL)hasLastEscrowAttemptTime +{ + return _has.lastEscrowAttemptTime; +} +@synthesize uploadCompleted = _uploadCompleted; +- (void)setUploadCompleted:(BOOL)v +{ + _has.uploadCompleted = YES; + _uploadCompleted = v; +} +- (void)setHasUploadCompleted:(BOOL)f +{ + _has.uploadCompleted = f; +} +- (BOOL)hasUploadCompleted +{ + return _has.uploadCompleted; +} +@synthesize uploadRetries = _uploadRetries; +- (void)setUploadRetries:(uint64_t)v +{ + _has.uploadRetries = YES; + _uploadRetries = v; +} +- (void)setHasUploadRetries:(BOOL)f +{ + _has.uploadRetries = f; +} +- (BOOL)hasUploadRetries +{ + return _has.uploadRetries; +} +- (BOOL)hasAltDSID +{ + return _altDSID != nil; +} +@synthesize altDSID = _altDSID; +@synthesize triggerRequestTime = _triggerRequestTime; +- (void)setTriggerRequestTime:(uint64_t)v +{ + _has.triggerRequestTime = YES; + _triggerRequestTime = v; +} +- (void)setHasTriggerRequestTime:(BOOL)f +{ + _has.triggerRequestTime = f; +} +- (BOOL)hasTriggerRequestTime +{ + return _has.triggerRequestTime; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_uuid) + { + [dict setObject:self->_uuid forKey:@"uuid"]; + } + if (self->_has.certCached) + { + [dict setObject:[NSNumber numberWithBool:self->_certCached] forKey:@"certCached"]; + } + if (self->_serializedPrerecord) + { + [dict setObject:self->_serializedPrerecord forKey:@"serializedPrerecord"]; + } + if (self->_has.lastCloudServicesTriggerTime) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_lastCloudServicesTriggerTime] forKey:@"lastCloudServicesTriggerTime"]; + } + if (self->_has.lastEscrowAttemptTime) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_lastEscrowAttemptTime] forKey:@"lastEscrowAttemptTime"]; + } + if (self->_has.uploadCompleted) + { + [dict setObject:[NSNumber numberWithBool:self->_uploadCompleted] forKey:@"uploadCompleted"]; + } + if (self->_has.uploadRetries) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_uploadRetries] forKey:@"uploadRetries"]; + } + if (self->_altDSID) + { + [dict setObject:self->_altDSID forKey:@"altDSID"]; + } + if (self->_has.triggerRequestTime) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_triggerRequestTime] forKey:@"triggerRequestTime"]; + } + return dict; +} + +BOOL SecEscrowPendingRecordReadFrom(__unsafe_unretained SecEscrowPendingRecord *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 /* uuid */: + { + NSString *new_uuid = PBReaderReadString(reader); + self->_uuid = new_uuid; + } + break; + case 2 /* certCached */: + { + self->_has.certCached = YES; + self->_certCached = PBReaderReadBOOL(reader); + } + break; + case 3 /* serializedPrerecord */: + { + NSData *new_serializedPrerecord = PBReaderReadData(reader); + self->_serializedPrerecord = new_serializedPrerecord; + } + break; + case 4 /* lastCloudServicesTriggerTime */: + { + self->_has.lastCloudServicesTriggerTime = YES; + self->_lastCloudServicesTriggerTime = PBReaderReadUint64(reader); + } + break; + case 5 /* lastEscrowAttemptTime */: + { + self->_has.lastEscrowAttemptTime = YES; + self->_lastEscrowAttemptTime = PBReaderReadUint64(reader); + } + break; + case 6 /* uploadCompleted */: + { + self->_has.uploadCompleted = YES; + self->_uploadCompleted = PBReaderReadBOOL(reader); + } + break; + case 7 /* uploadRetries */: + { + self->_has.uploadRetries = YES; + self->_uploadRetries = PBReaderReadUint64(reader); + } + break; + case 8 /* altDSID */: + { + NSString *new_altDSID = PBReaderReadString(reader); + self->_altDSID = new_altDSID; + } + break; + case 9 /* triggerRequestTime */: + { + self->_has.triggerRequestTime = YES; + self->_triggerRequestTime = PBReaderReadUint64(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return SecEscrowPendingRecordReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* uuid */ + { + if (self->_uuid) + { + PBDataWriterWriteStringField(writer, self->_uuid, 1); + } + } + /* certCached */ + { + if (self->_has.certCached) + { + PBDataWriterWriteBOOLField(writer, self->_certCached, 2); + } + } + /* serializedPrerecord */ + { + if (self->_serializedPrerecord) + { + PBDataWriterWriteDataField(writer, self->_serializedPrerecord, 3); + } + } + /* lastCloudServicesTriggerTime */ + { + if (self->_has.lastCloudServicesTriggerTime) + { + PBDataWriterWriteUint64Field(writer, self->_lastCloudServicesTriggerTime, 4); + } + } + /* lastEscrowAttemptTime */ + { + if (self->_has.lastEscrowAttemptTime) + { + PBDataWriterWriteUint64Field(writer, self->_lastEscrowAttemptTime, 5); + } + } + /* uploadCompleted */ + { + if (self->_has.uploadCompleted) + { + PBDataWriterWriteBOOLField(writer, self->_uploadCompleted, 6); + } + } + /* uploadRetries */ + { + if (self->_has.uploadRetries) + { + PBDataWriterWriteUint64Field(writer, self->_uploadRetries, 7); + } + } + /* altDSID */ + { + if (self->_altDSID) + { + PBDataWriterWriteStringField(writer, self->_altDSID, 8); + } + } + /* triggerRequestTime */ + { + if (self->_has.triggerRequestTime) + { + PBDataWriterWriteUint64Field(writer, self->_triggerRequestTime, 9); + } + } +} + +- (void)copyTo:(SecEscrowPendingRecord *)other +{ + if (_uuid) + { + other.uuid = _uuid; + } + if (self->_has.certCached) + { + other->_certCached = _certCached; + other->_has.certCached = YES; + } + if (_serializedPrerecord) + { + other.serializedPrerecord = _serializedPrerecord; + } + if (self->_has.lastCloudServicesTriggerTime) + { + other->_lastCloudServicesTriggerTime = _lastCloudServicesTriggerTime; + other->_has.lastCloudServicesTriggerTime = YES; + } + if (self->_has.lastEscrowAttemptTime) + { + other->_lastEscrowAttemptTime = _lastEscrowAttemptTime; + other->_has.lastEscrowAttemptTime = YES; + } + if (self->_has.uploadCompleted) + { + other->_uploadCompleted = _uploadCompleted; + other->_has.uploadCompleted = YES; + } + if (self->_has.uploadRetries) + { + other->_uploadRetries = _uploadRetries; + other->_has.uploadRetries = YES; + } + if (_altDSID) + { + other.altDSID = _altDSID; + } + if (self->_has.triggerRequestTime) + { + other->_triggerRequestTime = _triggerRequestTime; + other->_has.triggerRequestTime = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + SecEscrowPendingRecord *copy = [[[self class] allocWithZone:zone] init]; + copy->_uuid = [_uuid copyWithZone:zone]; + if (self->_has.certCached) + { + copy->_certCached = _certCached; + copy->_has.certCached = YES; + } + copy->_serializedPrerecord = [_serializedPrerecord copyWithZone:zone]; + if (self->_has.lastCloudServicesTriggerTime) + { + copy->_lastCloudServicesTriggerTime = _lastCloudServicesTriggerTime; + copy->_has.lastCloudServicesTriggerTime = YES; + } + if (self->_has.lastEscrowAttemptTime) + { + copy->_lastEscrowAttemptTime = _lastEscrowAttemptTime; + copy->_has.lastEscrowAttemptTime = YES; + } + if (self->_has.uploadCompleted) + { + copy->_uploadCompleted = _uploadCompleted; + copy->_has.uploadCompleted = YES; + } + if (self->_has.uploadRetries) + { + copy->_uploadRetries = _uploadRetries; + copy->_has.uploadRetries = YES; + } + copy->_altDSID = [_altDSID copyWithZone:zone]; + if (self->_has.triggerRequestTime) + { + copy->_triggerRequestTime = _triggerRequestTime; + copy->_has.triggerRequestTime = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + SecEscrowPendingRecord *other = (SecEscrowPendingRecord *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_uuid && !other->_uuid) || [self->_uuid isEqual:other->_uuid]) + && + ((self->_has.certCached && other->_has.certCached && ((self->_certCached && other->_certCached) || (!self->_certCached && !other->_certCached))) || (!self->_has.certCached && !other->_has.certCached)) + && + ((!self->_serializedPrerecord && !other->_serializedPrerecord) || [self->_serializedPrerecord isEqual:other->_serializedPrerecord]) + && + ((self->_has.lastCloudServicesTriggerTime && other->_has.lastCloudServicesTriggerTime && self->_lastCloudServicesTriggerTime == other->_lastCloudServicesTriggerTime) || (!self->_has.lastCloudServicesTriggerTime && !other->_has.lastCloudServicesTriggerTime)) + && + ((self->_has.lastEscrowAttemptTime && other->_has.lastEscrowAttemptTime && self->_lastEscrowAttemptTime == other->_lastEscrowAttemptTime) || (!self->_has.lastEscrowAttemptTime && !other->_has.lastEscrowAttemptTime)) + && + ((self->_has.uploadCompleted && other->_has.uploadCompleted && ((self->_uploadCompleted && other->_uploadCompleted) || (!self->_uploadCompleted && !other->_uploadCompleted))) || (!self->_has.uploadCompleted && !other->_has.uploadCompleted)) + && + ((self->_has.uploadRetries && other->_has.uploadRetries && self->_uploadRetries == other->_uploadRetries) || (!self->_has.uploadRetries && !other->_has.uploadRetries)) + && + ((!self->_altDSID && !other->_altDSID) || [self->_altDSID isEqual:other->_altDSID]) + && + ((self->_has.triggerRequestTime && other->_has.triggerRequestTime && self->_triggerRequestTime == other->_triggerRequestTime) || (!self->_has.triggerRequestTime && !other->_has.triggerRequestTime)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_uuid hash] + ^ + (self->_has.certCached ? PBHashInt((NSUInteger)self->_certCached) : 0) + ^ + [self->_serializedPrerecord hash] + ^ + (self->_has.lastCloudServicesTriggerTime ? PBHashInt((NSUInteger)self->_lastCloudServicesTriggerTime) : 0) + ^ + (self->_has.lastEscrowAttemptTime ? PBHashInt((NSUInteger)self->_lastEscrowAttemptTime) : 0) + ^ + (self->_has.uploadCompleted ? PBHashInt((NSUInteger)self->_uploadCompleted) : 0) + ^ + (self->_has.uploadRetries ? PBHashInt((NSUInteger)self->_uploadRetries) : 0) + ^ + [self->_altDSID hash] + ^ + (self->_has.triggerRequestTime ? PBHashInt((NSUInteger)self->_triggerRequestTime) : 0) + ; +} + +- (void)mergeFrom:(SecEscrowPendingRecord *)other +{ + if (other->_uuid) + { + [self setUuid:other->_uuid]; + } + if (other->_has.certCached) + { + self->_certCached = other->_certCached; + self->_has.certCached = YES; + } + if (other->_serializedPrerecord) + { + [self setSerializedPrerecord:other->_serializedPrerecord]; + } + if (other->_has.lastCloudServicesTriggerTime) + { + self->_lastCloudServicesTriggerTime = other->_lastCloudServicesTriggerTime; + self->_has.lastCloudServicesTriggerTime = YES; + } + if (other->_has.lastEscrowAttemptTime) + { + self->_lastEscrowAttemptTime = other->_lastEscrowAttemptTime; + self->_has.lastEscrowAttemptTime = YES; + } + if (other->_has.uploadCompleted) + { + self->_uploadCompleted = other->_uploadCompleted; + self->_has.uploadCompleted = YES; + } + if (other->_has.uploadRetries) + { + self->_uploadRetries = other->_uploadRetries; + self->_has.uploadRetries = YES; + } + if (other->_altDSID) + { + [self setAltDSID:other->_altDSID]; + } + if (other->_has.triggerRequestTime) + { + self->_triggerRequestTime = other->_triggerRequestTime; + self->_has.triggerRequestTime = YES; + } +} + +@end + diff --git a/keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h b/keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h new file mode 100644 index 00000000..86469fd2 --- /dev/null +++ b/keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h @@ -0,0 +1,19 @@ + +#import + +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ckks/CKKSResultOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface EscrowRequestInformCloudServicesOperation : CKKSResultOperation + +- (instancetype)initWithIntendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker; + ++ (NSData* _Nullable)triggerCloudServicesPasscodeRequest:(NSString*)uuid error:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.m b/keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.m new file mode 100644 index 00000000..dc579380 --- /dev/null +++ b/keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.m @@ -0,0 +1,135 @@ + +#import + +#import "utilities/debugging.h" +#import "keychain/ckks/CKKSLockStateTracker.h" + +#import "keychain/escrowrequest/EscrowRequestController.h" +#import "keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h" +#import "keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h" +#import "keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h" + +@interface EscrowRequestInformCloudServicesOperation() +@property CKKSLockStateTracker* lockStateTracker; +@end + +@implementation EscrowRequestInformCloudServicesOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithIntendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker +{ + if((self = [super init])) { + _intendedState = intendedState; + _nextState = errorState; + _lockStateTracker = lockStateTracker; + } + return self; +} + +- (void)main +{ + secnotice("escrowrequest", "Telling CloudServices about any pending requests"); + + NSError* error = nil; + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + if(error && !([error.domain isEqualToString:NSOSStatusErrorDomain] && error.code == errSecItemNotFound)) { + secnotice("escrowrequest", "failed to fetch records from keychain: %@", error); + if([self.lockStateTracker isLockedError:error]) { + secnotice("escrowrequest", "Trying again after unlock"); + self.nextState = EscrowRequestStateWaitForUnlock; + } else { + self.nextState = EscrowRequestStateNothingToDo; + } + self.error = error; + return; + } + error = nil; + + SecEscrowPendingRecord* record = nil; + + for(SecEscrowPendingRecord* existingRecord in records) { + if(!existingRecord.hasCertCached) { + record = existingRecord; + break; + } + } + + if(!record) { + secnotice("escrowrequest", "No pending escrow request needs a certificate"); + self.nextState = EscrowRequestStateNothingToDo; + return; + } + + // Next, see if CloudServices can cache a certificate + NSData* cachedCert = [EscrowRequestInformCloudServicesOperation triggerCloudServicesPasscodeRequest:record.uuid error:&error]; + record.lastCloudServicesTriggerTime = (uint64_t) ([[NSDate date] timeIntervalSince1970] * 1000); + + if(!cachedCert || error) { + secerror("escrowrequest: cloudservices reports an issue caching the certificate, so we'll have to try again later: %@", error); + self.error = error; + // TODO: wait for network? + self.nextState = EscrowRequestStateNothingToDo; + + NSError* saveCacheTimeError = nil; + [record saveToKeychain:&saveCacheTimeError]; + if(saveCacheTimeError) { + secerror("escrowrequest: unable to save the last attempt time: %@", saveCacheTimeError); + } + + return; + } + + record.certCached = true; + [record saveToKeychain:&error]; + + if(error) { + // Ignore this error, since we've successfully triggered the update. We'll probably re-cache the certificate later, but that's okay. + secerror("escrowrequest: unable to save escrow update request certificate status, so we'll have to try again later: %@", error); + self.error = error; + + if([self.lockStateTracker isLockedError:error]) { + secnotice("escrowrequest", "Trying again after unlock"); + self.nextState = EscrowRequestStateWaitForUnlock; + } else { + self.nextState = EscrowRequestStateNothingToDo; + } + + return; + } + + secnotice("escrowrequest", "CloudService successfully cached a certificate; request is ready for passcode"); + self.nextState = EscrowRequestStateNothingToDo; +} + +// Separated into a class method for mocking +// Returns any cert that CS has cached ++ (NSData* _Nullable)triggerCloudServicesPasscodeRequest:(NSString*)uuid error:(NSError**)error +{ + SecureBackup* sb = [[SecureBackup alloc] init]; + + NSError* localError = nil; + SecureBackupBeginPasscodeRequestResults* results = [sb beginHSA2PasscodeRequest:true + uuid:uuid + error:error]; + + if(!results || localError) { + secerror("escrowrequest: unable to begin passcode request: %@", localError); + if(error) { + *error = localError; + } + return nil; + } + + if(!results.cert) { + secerror("escrowrequest: sbd failed to cache a certificate"); + // TODO fill in error + return nil; + } + + return results.cert; +} + +@end diff --git a/keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h b/keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h new file mode 100644 index 00000000..79037813 --- /dev/null +++ b/keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h @@ -0,0 +1,25 @@ + +#import +#import + +#import "keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h" +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ckks/CKKSGroupOperation.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface EscrowRequestPerformEscrowEnrollOperation : CKKSGroupOperation + +@property uint64_t numberOfRecordsUploaded; + +- (instancetype)initWithIntendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + enforceRateLimiting:(bool)enforceRateLimiting + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker; + ++ (void)cdpUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(BOOL didUpdate, NSError* _Nullable error))reply; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.m b/keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.m new file mode 100644 index 00000000..758884c0 --- /dev/null +++ b/keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.m @@ -0,0 +1,184 @@ + +#import +#import +#import + +#import "utilities/debugging.h" + +#import "keychain/ot/ObjCImprovements.h" + +#import "keychain/escrowrequest/EscrowRequestController.h" +#import "keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h" +#import "keychain/escrowrequest/generated_source/SecEscrowPendingRecord.h" +#import "keychain/escrowrequest/SecEscrowPendingRecord+KeychainSupport.h" + +#import "keychain/ckks/CKKSLockStateTracker.h" + +@interface EscrowRequestPerformEscrowEnrollOperation () +@property bool enforceRateLimiting; +@property CKKSLockStateTracker* lockStateTracker; +@end + +@implementation EscrowRequestPerformEscrowEnrollOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithIntendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + enforceRateLimiting:(bool)enforceRateLimiting + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker +{ + if((self = [super init])) { + _intendedState = intendedState; + _nextState = errorState; + _enforceRateLimiting = enforceRateLimiting; + _lockStateTracker = lockStateTracker; + } + return self; +} + +- (BOOL)checkFatalError:(NSError *)error +{ + if (error == nil) { + return NO; + } + + if (error.code == kSecureBackupInternalError && [error.domain isEqualToString:kSecureBackupErrorDomain]) { // SOS peer ID mismatch!!!, the error code is wrong though + return YES; + } + + if ([error.domain isEqualToString:kSecureBackupErrorDomain] && error.code == kSecureBackupNotInSyncCircleError) { + // One or more peers is missing (likely the SOS peer) + return YES; + } + + if( [error.domain isEqualToString:CDPStateErrorDomain] && error.code == CDPStateErrorNoPeerIdFound) { + // CDP is unhappy about the self peer. I don't understand why we get both this and kSecureBackupNotInSyncCircleError + return YES; + } + + return NO; +} + +- (void)groupStart +{ + secnotice("escrowrequest", "Attempting to escrow any pending prerecords"); + + NSError* error = nil; + NSArray* records = [SecEscrowPendingRecord loadAllFromKeychain:&error]; + if(error && !([error.domain isEqualToString:NSOSStatusErrorDomain] && error.code == errSecItemNotFound)) { + secnotice("escrowrequest", "failed to fetch records from keychain: %@", error); + self.error = error; + + if([self.lockStateTracker isLockedError: error]) { + secnotice("escrowrequest", "Will retry after unlock"); + self.nextState = EscrowRequestStateWaitForUnlock; + } else { + self.nextState = EscrowRequestStateNothingToDo; + } + return; + } + error = nil; + + SecEscrowPendingRecord* record = nil; + + for(SecEscrowPendingRecord* existingRecord in records) { + if(self.enforceRateLimiting && [existingRecord escrowAttemptedWithinLastSeconds:5*60]) { + secnotice("escrowrequest", "Skipping pending escrow request (%@); it's rate limited", existingRecord); + continue; + } + + if(existingRecord.hasSerializedPrerecord) { + record = existingRecord; + break; + } + } + + if(record == nil && record.uuid == nil) { + secnotice("escrowrequest", "No pending escrow request has a prerecord"); + self.nextState = EscrowRequestStateNothingToDo; + return; + } + + secnotice("escrowrequest", "escrow request have pre-record uploading: %@", record.uuid); + + // Ask CDP to escrow the escrow-record. Use the "finish operation" trick to wait + CKKSResultOperation* finishOp = [CKKSResultOperation named:@"cdp-finish" withBlock:^{}]; + [self dependOnBeforeGroupFinished: finishOp]; + + /* + * Update and save the preRecord an extra time (before we crash) + */ + + record.lastEscrowAttemptTime = (uint64_t) ([[NSDate date] timeIntervalSince1970] * 1000); + record.uploadRetries += 1; + + // Save the last escrow attempt time to keychain + NSError* saveError = nil; + [record saveToKeychain:&saveError]; + if(saveError) { + secerror("escrowrequest: unable to save last escrow time: %@", error); + } + + WEAKIFY(self); + + [EscrowRequestPerformEscrowEnrollOperation cdpUploadPrerecord:record + secretType:CDPComplexDeviceSecretType + reply:^(BOOL didUpdate, NSError * _Nullable error) { + STRONGIFY(self); + + //* check for fatal errors that definatly should make us give up + if ([self checkFatalError:error]) { + secerror("escrowrequest: fatal error for record: %@, dropping: %@", record.uuid, error); + NSError* deleteError = nil; + [record deleteFromKeychain:&deleteError]; + if(saveError) { + secerror("escrowrequest: unable to delete last escrow time: %@", deleteError); + } + + self.error = error; + [self.operationQueue addOperation:finishOp]; + return; + } + + if(error || !didUpdate) { + secerror("escrowrequest: prerecord %@ upload failed: %@", record.uuid, error); + + self.error = error; + [self.operationQueue addOperation:finishOp]; + return; + } + + self.numberOfRecordsUploaded = 1; + secerror("escrowrequest: prerecord %@ upload succeeded", record.uuid); + + record.uploadCompleted = true; + NSError* saveError = nil; + [record saveToKeychain:&saveError]; + if(saveError) { + secerror("escrowrequest: unable to save last escrow time: %@", error); + } + + if(saveError) { + secerror("escrowrequest: unable to save completion of prerecord %@ in keychain", record.uuid); + } + + self.nextState = EscrowRequestStateNothingToDo; + [self.operationQueue addOperation:finishOp]; + }]; +} + ++ (void)cdpUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(BOOL didUpdate, NSError* _Nullable error))reply +{ + CDPStateController *controller = [[CDPStateController alloc] initWithContext:nil]; + [controller attemptToEscrowPreRecord:@"unknown-local-passcode" + preRecordUUID:recordToSend.uuid + secretType:secretType + completion:^(BOOL didUpdate, NSError *error) { + reply(didUpdate, error); + }]; +} + +@end diff --git a/keychain/escrowrequest/tests/MockSynchronousEscrowServer.h b/keychain/escrowrequest/tests/MockSynchronousEscrowServer.h new file mode 100644 index 00000000..1e7e88ef --- /dev/null +++ b/keychain/escrowrequest/tests/MockSynchronousEscrowServer.h @@ -0,0 +1,15 @@ + +#import + +#import "keychain/escrowrequest/EscrowRequestXPCProtocol.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface MockSynchronousEscrowServer : NSObject + +- (instancetype)initWithServer:(EscrowRequestServer*)server; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/escrowrequest/tests/MockSynchronousEscrowServer.m b/keychain/escrowrequest/tests/MockSynchronousEscrowServer.m new file mode 100644 index 00000000..40ac3185 --- /dev/null +++ b/keychain/escrowrequest/tests/MockSynchronousEscrowServer.m @@ -0,0 +1,108 @@ + +#import "MockSynchronousEscrowServer.h" + +@interface MockSynchronousEscrowServer () +@property EscrowRequestServer* server; +@end + +@implementation MockSynchronousEscrowServer + +- (instancetype)initWithServer:(EscrowRequestServer*)server +{ + if((self = [super init])) { + _server = server; + } + return self; +} + +- (void)cachePrerecord:(NSString*)uuid + serializedPrerecord:(nonnull NSData *)prerecord + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server cachePrerecord:uuid + serializedPrerecord:prerecord + reply:^(NSError * _Nullable error) { + reply(error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +- (void)fetchPrerecord:(nonnull NSString *)prerecordUUID + reply:(nonnull void (^)(NSData * _Nullable, NSError * _Nullable))reply +{ + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server fetchPrerecord:prerecordUUID + reply:^(NSData* contents, NSError * _Nullable error) { + reply(contents, error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +- (void)fetchRequestWaitingOnPasscode:(nonnull void (^)(NSString * _Nullable, NSError * _Nullable))reply +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server fetchRequestWaitingOnPasscode:^(NSString* uuid, NSError * _Nullable error) { + reply(uuid, error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +- (void)triggerEscrowUpdate:(nonnull NSString *)reason + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server triggerEscrowUpdate:reason reply:^(NSError * _Nullable error) { + reply(error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +- (void)fetchRequestStatuses:(nonnull void (^)(NSDictionary * _Nullable, NSError * _Nullable))reply { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server fetchRequestStatuses:^(NSDictionary * dict, NSError * _Nullable error) { + reply(dict, error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +- (void)resetAllRequests:(nonnull void (^)(NSError * _Nullable))reply { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server resetAllRequests:^(NSError * _Nullable error) { + reply(error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +- (void)storePrerecordsInEscrow:(nonnull void (^)(uint64_t, NSError * _Nullable))reply { + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [self.server storePrerecordsInEscrow:^(uint64_t x, NSError * _Nullable error) { + reply(x, error); + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); +} + +@end diff --git a/keychain/escrowrequest/tests/SecEscrowRequestTests.m b/keychain/escrowrequest/tests/SecEscrowRequestTests.m new file mode 100644 index 00000000..68dc2daf --- /dev/null +++ b/keychain/escrowrequest/tests/SecEscrowRequestTests.m @@ -0,0 +1,871 @@ + +#import +#import +#import +#import +#import + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" + +#import "keychain/escrowrequest/EscrowRequestServerHelpers.h" +#import "keychain/escrowrequest/operations/EscrowRequestInformCloudServicesOperation.h" +#import "keychain/escrowrequest/operations/EscrowRequestPerformEscrowEnrollOperation.h" +#import "keychain/escrowrequest/EscrowRequestServerHelpers.h" + +#import "keychain/escrowrequest/tests/MockSynchronousEscrowServer.h" + +#include "keychain/ckks/CKKS.h" +#include "keychain/ckks/CKKSLockStateTracker.h" +#include "securityd/SecItemServer.h" +#include "securityd/spi.h" +#include "utilities/SecFileLocations.h" + +#include "tests/secdmockaks/mockaks.h" + +@interface SecEscrowRequestTests : XCTestCase +@property SecEscrowRequest* escrowRequest; +@property EscrowRequestServer* escrowServer; +@property CKKSLockStateTracker* lockStateTracker; + +@property id escrowRequestServerClassMock; +@property id escrowRequestInformCloudServicesOperationMock; +@property id escrowRequestPerformEscrowEnrollOperationMock; +@end + +@implementation SecEscrowRequestTests + ++ (void)setUp { + securityd_init_local_spi(); + EscrowRequestServerSetEnabled(true); +} + +- (void)setUp { + NSString* testName = [self.name componentsSeparatedByString:@" "][1]; + testName = [testName stringByReplacingOccurrencesOfString:@"]" withString:@""]; + secnotice("secescrowtest", "Beginning test %@", testName); + + [SecMockAKS unlockAllClasses]; + + // Make a new fake keychain + NSString* tmp_dir = [NSString stringWithFormat: @"/tmp/%@.%X", testName, arc4random()]; + [[NSFileManager defaultManager] createDirectoryAtPath:[NSString stringWithFormat: @"%@/Library/Keychains", tmp_dir] withIntermediateDirectories:YES attributes:nil error:NULL]; + + SecCKKSDisable(); + SecCKKSTestDisableSOS(); + + // Mock out the SBD layer + self.escrowRequestServerClassMock = OCMClassMock([EscrowRequestServer class]); + self.escrowRequestInformCloudServicesOperationMock = OCMClassMock([EscrowRequestInformCloudServicesOperation class]); + self.escrowRequestPerformEscrowEnrollOperationMock = OCMClassMock([EscrowRequestPerformEscrowEnrollOperation class]); + + self.lockStateTracker = [[CKKSLockStateTracker alloc] init]; + self.escrowServer = [[EscrowRequestServer alloc] initWithLockStateTracker:self.lockStateTracker]; + + id mockConnection = OCMPartialMock([[NSXPCConnection alloc] init]); + OCMStub([mockConnection remoteObjectProxyWithErrorHandler:[OCMArg any]]).andCall(self, @selector(escrowServer)); + OCMStub([mockConnection synchronousRemoteObjectProxyWithErrorHandler:[OCMArg any]]).andCall(self, @selector(synchronousEscrowServer)); + self.escrowRequest = [[SecEscrowRequest alloc] initWithConnection:mockConnection]; + + SetCustomHomeURLString((__bridge CFStringRef) tmp_dir); + SecKeychainDbReset(NULL); + + // Actually load the database. + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); +} + + +- (NSData* _Nullable)mockTriggerCloudServicesPasscodeRequest:(NSString*)uuid error:(NSError**)error +{ + return [@"certdata" dataUsingEncoding:NSUTF8StringEncoding]; +} + +- (NSData* _Nullable)mockTriggerCloudServicesPasscodeRequestAndLockClassA:(NSString*)uuid error:(NSError**)error +{ + [SecMockAKS lockClassA]; + [self.lockStateTracker recheck]; + return [@"certdata" dataUsingEncoding:NSUTF8StringEncoding]; +} + +- (NSData* _Nullable)mockFailTriggerCloudServicesPasscodeRequest:(NSString*)uuid error:(NSError**)error +{ + if(error) { + *error = [NSError errorWithDomain:@"NSURLErrorDomain" + code:-1009 + description:@"The internet connection appears to be offline (mock)"]; + } + return nil; +} + +- (void)mockcdpUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(bool didUpdate, NSError* _Nullable error))reply +{ + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^ { + reply(YES, nil); + }); +} + +- (void)mockFailcdpUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(bool didUpdate, NSError* _Nullable error))reply +{ + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^ { + reply(NO, [NSError errorWithDomain:@"EscrowServiceErrorDomain" code:-6570 description:@"mock CLUBH error"]); + }); +} + +- (void)mockcdpFailBadPeerUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(bool didUpdate, NSError* _Nullable error))reply +{ + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^ { + reply(NO, [NSError errorWithDomain:kSecureBackupErrorDomain code:kSecureBackupInternalError description:@"SOS peer ID mismatch"]); + }); +} + +- (void)mockcdpFailNoSOSPeerUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(bool didUpdate, NSError* _Nullable error))reply +{ + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^ { + reply(NO, [NSError errorWithDomain:kSecureBackupErrorDomain code:kSecureBackupNotInSyncCircleError description:@"SOS peer not present"]); + }); +} + +- (void)mockcdpFailNoCDPPeerUploadPrerecord:(SecEscrowPendingRecord*)recordToSend + secretType:(CDPDeviceSecretType)secretType + reply:(void (^)(bool didUpdate, NSError* _Nullable error))reply +{ + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^ { + reply(NO, [NSError errorWithDomain:CDPStateErrorDomain code:CDPStateErrorNoPeerIdFound description:@"SOS peer not present"]); + }); +} + + +- (id)synchronousEscrowServer +{ + return [[MockSynchronousEscrowServer alloc] initWithServer:self.escrowServer]; +} + +- (void)tearDown { + [self.escrowServer.controller.stateMachine haltOperation]; +} + +- (void)allCloudServicesCallsSucceed { + OCMStub([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); +} + +- (void)testStateMachineEntersNothingToDo +{ + [self.escrowServer.controller.stateMachine startOperation]; + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.stateConditions[EscrowRequestStateNothingToDo] wait:10*NSEC_PER_SEC], "State machine enters NothingToDo"); +} + +- (void)testTriggerUpdate { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + XCTAssertNil([self.escrowRequest fetchRequestWaitingOnPasscode:&error], @"Should be no pending updates"); + XCTAssertNil(error, @"Should be no error fetching pending updates"); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should churn through"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); +} + +- (void)testTriggerUpdateWhileLocked { + [self allCloudServicesCallsSucceed]; + + [SecMockAKS lockClassA]; + + NSError* error = nil; + + XCTAssertNil([self.escrowRequest fetchRequestWaitingOnPasscode:&error], @"Should be no pending updates"); + XCTAssertNil(error, @"Should be no error fetching pending updates"); + + XCTAssertFalse([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should not be able to trigger an update when locked"); + XCTAssertNotNil(error, @"Should be an error triggering an escrow update (while locked)"); + error = nil; + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should churn through"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNil(pendingUUID, "Should be no pending request UUID after a failed trigger"); +} + +- (void)testMultipleTriggers { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 1, @"Should be one in-flight status"); +} + +- (void)testFetchUpdateWhileLocked { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + XCTAssertNil([self.escrowRequest fetchRequestWaitingOnPasscode:&error], @"Should be no pending updates"); + XCTAssertNil(error, @"Should be no error fetching pending updates"); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should churn through"); + error = nil; + + [SecMockAKS lockClassA]; + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNotNil(error, @"Should be an error fetching a pending UUID while the device is locked"); + XCTAssertNil(pendingUUID, "Should be no pending request UUID while device is locked"); +} + +- (void)testReaskCloudServicesWhenLocked { + // In this test, CloudServices is able to succeed (and cache a certificate), but we can't write down that the operation succeeded. + NSError* error = nil; + + // No rate limiting for us! + self.escrowServer.controller.forceIgnoreCloudServicesRateLimiting = true; + + // Pause the state machine for a bit... + [self.escrowServer.controller.stateMachine startOperation]; + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause"); + [self.escrowServer.controller.stateMachine haltOperation]; + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + // First, let's ensure that we properly handle the case where the device is locked when we go to ask CloudServices about things + + [SecMockAKS lockClassA]; + [self.lockStateTracker recheck]; + [self.escrowServer.controller.stateMachine startOperation]; + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.stateConditions[EscrowRequestStateWaitForUnlock] wait:10*NSEC_PER_SEC], "State machine enters waitforunlock"); + + // Now, we should call CloudServices, but the device locks between CS success and us writing it down + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequestAndLockClassA:error:)); + [SecMockAKS unlockAllClasses]; + [self.lockStateTracker recheck]; + + OCMVerifyAllWithDelay(self.escrowRequestInformCloudServicesOperationMock, 10); + // and we should be back in wait for unlock: + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.stateConditions[EscrowRequestStateWaitForUnlock] wait:10*NSEC_PER_SEC], "State machine enters waitforunlock"); + + // Then, unlock one last time, and let everything succeed + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + [SecMockAKS unlockAllClasses]; + [self.lockStateTracker recheck]; + + OCMVerifyAllWithDelay(self.escrowRequestInformCloudServicesOperationMock, 10); +} + +- (void)testRateLimitSBDTriggerWhenFailing { + + // Trigger an escrow update, which should call CloudServices and fail + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockFailTriggerCloudServicesPasscodeRequest:error:)); + + NSError* error = nil; + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + // And, the state machine should pause + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + // But, there should be no pending requests (as we need to retry CloudServices) + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNil(pendingUUID, "Should be no pending request UUID after a failed trigger"); + + + // But, the controller will recover at some point (for now, disable rate limiting) + [self allCloudServicesCallsSucceed]; + self.escrowServer.controller.forceIgnoreCloudServicesRateLimiting = true; + [self.escrowServer.controller.stateMachine pokeStateMachine]; + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after the state machine retries certificate caching"); +} + +- (void)testRateLimitSBDUploadWhenFailing { + + // Trigger an escrow update, which should call CloudServices + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + NSError* error = nil; + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAllWithDelay(self.escrowRequestInformCloudServicesOperationMock, 5); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockFailcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + // Wait for the upload to fail... + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + ////////////////////////// + // Trigger another update, to check coalescing + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test2" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + OCMVerifyAllWithDelay(self.escrowRequestInformCloudServicesOperationMock, 5); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + NSString* pendingUUIDTheSecond = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNotNil(pendingUUIDTheSecond, @"Should have a request waiting on passcode"); + XCTAssertEqualObjects(pendingUUID, pendingUUIDTheSecond, @"In-flight request should have been restarted"); + ////////////// + + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockFailcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUIDTheSecond + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 1, @"Should be one in-flight status"); + + // But if escrow plays nice again, kick state machine, and make sure we don't touch escrow proxy + [[[[self.escrowRequestPerformEscrowEnrollOperationMock stub] andCall:@selector(mockcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + + [self.escrowServer.controller.stateMachine startOperation]; + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + /* item should still be in flight */ + statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 1, @"Should be one in-flight status"); +} + + +- (void)testPrerecordCaching { + NSError* error = nil; + + // Trigger an escrow update, which should call CloudServices + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + // Now, there should be a pending request + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + // Caching a prerecord will attempt an upload via the state machine. But, since we're testing prerecord fetching, we don't want that to happen. + // So, let the upload fail. + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockFailcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + // Wait for the upload to fail... + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + NSString* nowPendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNil(nowPendingUUID, "Should be no pending request UUID after a prerecord cache"); + + NSData* d2 = [self.escrowRequest fetchPrerecord:pendingUUID + error:&error]; + XCTAssertNotNil(d2, @"Should be able to retrieve a cached prerecord"); + XCTAssertNil(error, @"Should be no error fetching a cached prerecord"); + + XCTAssertEqualObjects(d,d2, @"Cached prerecord should be equal to original"); +} + +- (void)testPrerecordCachingWhileLocked { + NSError* error = nil; + + // Trigger an escrow update, which should call CloudServices + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + + // Now, there should be a pending request + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + [SecMockAKS lockClassA]; + // Caching a prerecord will fail, and should not invoke CDP. + // So, let the upload fail. + [[[self.escrowRequestPerformEscrowEnrollOperationMock reject] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertFalse([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be not able to cache a prerecord while the device is locked"); + XCTAssertNotNil(error, @"Should be an error caching a prerecord while the device is locked"); + + // Ensure we don't invoke CDP + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should rest"); + OCMVerifyAll(self.escrowRequestPerformEscrowEnrollOperationMock); + + // And now, when we unlock, there's still a pending request + error = nil; + [SecMockAKS unlockAllClasses]; + pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); +} + +- (void)testEscrowUploadViaStateMachine { + // This test should call CloudServices, which will succeed. It should then tell CoreCDP to upload the record. + [self allCloudServicesCallsSucceed]; + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + [self.escrowServer.controller.stateMachine startOperation]; + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.stateConditions[EscrowRequestStateNothingToDo] wait:10*NSEC_PER_SEC], "State machine enters NothingToDo when started"); + + NSError* error = nil; + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + OCMVerifyAll(self.escrowRequestServerClassMock); + + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + // Don't call the "do it" RPC, but it should happen anyway + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); +} + +- (void)testEscrowUploadViaRPCAfterFailure { + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockFailcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + NSError* error = nil; + + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + + // Now, the state machine should try and fail the upload + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + // And pause for a while + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + // But if escrow plays nice again, a 'try again' RPC should succeed + [[[[self.escrowRequestPerformEscrowEnrollOperationMock stub] andCall:@selector(mockcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + uint64_t records = [self.escrowRequest storePrerecordsInEscrow:&error]; + XCTAssertNil(error, @"Should be no error storing prerecords in escrow"); + XCTAssertEqual(records, 1, @"Should have stored one record in escrow"); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 1, @"Should be one in-flight status"); + for(id key in statuses.keyEnumerator) { + XCTAssertEqualObjects(statuses[key], @"complete", "Record should be in 'complete' state"); + } +} + +- (void)testEscrowUploadViaStateMachineAfterFailureDueToLockState { + // This test should call CloudServices, which will succeed. It should then tell CDP to upload the record, which will fail due to lock state. + [self allCloudServicesCallsSucceed]; + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + [self.escrowServer.controller.stateMachine startOperation]; + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.stateConditions[EscrowRequestStateNothingToDo] wait:10*NSEC_PER_SEC], "State machine enters NothingToDo when started"); + + NSError* error = nil; + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + // We need to lock directly after the prerecord is cached, but before the CDP attempt is attempted + [self.escrowServer.controller.stateMachine haltOperation]; + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + [SecMockAKS lockClassA]; + [self.escrowServer.controller.stateMachine startOperation]; + + // The state machine should notice the unlock, and try again + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.stateConditions[EscrowRequestStateWaitForUnlock] wait:10*NSEC_PER_SEC], "State machine enters waitforunlock"); + + // The upload should be tried after an unlock + [SecMockAKS unlockAllClasses]; + [self.lockStateTracker recheck]; + + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); +} + +- (void)testEscrowUploadBadPeerFailure { + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpFailBadPeerUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + NSError* error = nil; + + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + + // Now, the state machine should try and fail the upload + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 0, @"Should be zero in-flight status"); +} + +- (void)testEscrowUploadNoSOSPeerFailure { + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpFailNoSOSPeerUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + NSError* error = nil; + + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + + // Now, the state machine should try and fail the upload + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 0, @"Should be zero in-flight status"); +} + +- (void)testEscrowUploadNoCDPSOSPeerFailure { + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpFailNoCDPPeerUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + NSError* error = nil; + + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + + // Now, the state machine should try and fail the upload + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 0, @"Should be zero in-flight status"); +} + +- (void)testPendingPreRecordsCheck { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 1, @"Should be one in-flight status"); + + BOOL result = [self.escrowRequest pendingEscrowUpload:&error]; + XCTAssertNil(error, @"Should be no error checking for pending uploads"); + XCTAssertEqual(result, true, @"pendingEscrowUpload should return true"); + +} + +- (void)testClearedPreRecordsCheck { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpFailNoCDPPeerUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + + // Now, the state machine should try and fail the upload + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 0, @"Should be zero in-flight status"); + + BOOL result = [self.escrowRequest pendingEscrowUpload:&error]; + XCTAssertNil(error, @"Should be no error checking for pending uploads"); + XCTAssertEqual(result, false, @"pendingEscrowUpload should return true"); +} + +- (void)testServerPendingPreRecordsCheck { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + XCTAssertTrue([self.escrowServer triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertTrue([self.escrowServer triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + XCTAssertTrue([self.escrowServer triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + NSDictionary* statuses = [self.escrowServer fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 1, @"Should be one in-flight status"); + + BOOL result = [self.escrowServer pendingEscrowUpload:&error]; + XCTAssertNil(error, @"Should be no error checking for pending uploads"); + XCTAssertEqual(result, true, @"pendingEscrowUpload should return true"); + +} + +- (void)testServerClearedPreRecordsCheck { + [self allCloudServicesCallsSucceed]; + + NSError* error = nil; + + [[[[self.escrowRequestPerformEscrowEnrollOperationMock expect] andCall:@selector(mockcdpFailNoCDPPeerUploadPrerecord:secretType:reply:) + onObject:self] ignoringNonObjectArgs] + cdpUploadPrerecord:[OCMArg any] secretType:0 reply:[OCMArg any]]; + + OCMExpect([self.escrowRequestInformCloudServicesOperationMock triggerCloudServicesPasscodeRequest:[OCMArg any] error:[OCMArg anyObjectRef]]).andCall(self, @selector(mockTriggerCloudServicesPasscodeRequest:error:)); + + XCTAssertTrue([self.escrowRequest triggerEscrowUpdate:@"test" error:&error], @"Should be able to trigger an update"); + XCTAssertNil(error, @"Should be no error triggering an escrow update"); + + OCMVerifyAll(self.escrowRequestServerClassMock); + + XCTAssertEqual(0, [self.escrowServer.controller.stateMachine.paused wait:10*NSEC_PER_SEC], @"State machine should pause within some time"); + + NSString* pendingUUID = [self.escrowRequest fetchRequestWaitingOnPasscode:&error]; + XCTAssertNil(error, @"Should be no error fetching a pending UUID"); + XCTAssertNotNil(pendingUUID, "Should be a pending request UUID after a trigger"); + + NSData* d = [[NSData alloc]initWithBase64EncodedString:@"YXNkZgo=" options:0]; + XCTAssertTrue([self.escrowRequest cachePrerecord:pendingUUID + serializedPrerecord:d + error:&error], @"Should be able to cache a prerecord"); + XCTAssertNil(error, @"Should be no error caching a prerecord"); + + + // Now, the state machine should try and fail the upload + OCMVerifyAllWithDelay(self.escrowRequestPerformEscrowEnrollOperationMock, 10); + + NSDictionary* statuses = [self.escrowServer fetchStatuses:&error]; + XCTAssertNotNil(statuses, @"Should be able to fetch statuses"); + XCTAssertNil(error, @"Should be no error fetching statuses"); + + XCTAssertEqual(statuses.count, 0, @"Should be zero in-flight status"); + + BOOL result = [self.escrowServer pendingEscrowUpload:&error]; + XCTAssertNil(error, @"Should be no error checking for pending uploads"); + XCTAssertEqual(result, false, @"pendingEscrowUpload should return true"); +} + +@end diff --git a/keychain/escrowrequest/tests/SecEscrowRequestsTests-Info.plist b/keychain/escrowrequest/tests/SecEscrowRequestsTests-Info.plist new file mode 100644 index 00000000..6c6c23c4 --- /dev/null +++ b/keychain/escrowrequest/tests/SecEscrowRequestsTests-Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/keychain/ot/OT.h b/keychain/ot/OT.h index 939ebfe8..bdc42fb8 100644 --- a/keychain/ot/OT.h +++ b/keychain/ot/OT.h @@ -31,7 +31,12 @@ NS_ASSUME_NONNULL_BEGIN CF_ASSUME_NONNULL_BEGIN #endif -bool SecOTIsEnabled(void); +void OctagonInitialize(void); + +// The octagon tests want to disable automatic initialization, for test bringup ordering reasons. +bool OctagonShouldPerformInitialization(void); +void OctagonSetShouldPerformInitialization(bool value); +void SecOctagon24hrNotification(void); CF_ASSUME_NONNULL_END #endif /* OT_h */ diff --git a/keychain/ot/OT.m b/keychain/ot/OT.m index e0e8bf85..c5246045 100644 --- a/keychain/ot/OT.m +++ b/keychain/ot/OT.m @@ -21,27 +21,38 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import "OT.h" -#import -#import +#import "keychain/ot/OT.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTManager.h" -bool SecOTIsEnabled(void) { +#import "utilities/debugging.h" - 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; - } - } +void OctagonInitialize(void) +{ + OTManager* manager = [OTManager manager]; + [manager initializeOctagon]; +} + +// If you want octagon to be initialized in your daemon/tests, you must set this to be true +static bool OctagonPerformInitialization = false; +bool OctagonShouldPerformInitialization(void) +{ + return OctagonPerformInitialization; +} - CFReleaseNull(enabled); - return userDefaultsShouldBottledPeer; +void OctagonSetShouldPerformInitialization(bool value) +{ + OctagonPerformInitialization = value; +} + +void SecOctagon24hrNotification(void) { +#if OCTAGON + @autoreleasepool { + [[OTManager manager] xpc24HrNotification:OTCKContainerName context:OTDefaultContext skipRateLimitingCheck:NO reply: ^(NSError * error) { + if(error){ + secerror("error attempting to check octagon health: %@", error); + } + }]; + } +#endif } diff --git a/keychain/ot/OTAuthKitAdapter.h b/keychain/ot/OTAuthKitAdapter.h new file mode 100644 index 00000000..d2e4053c --- /dev/null +++ b/keychain/ot/OTAuthKitAdapter.h @@ -0,0 +1,35 @@ + +#if OCTAGON + +#import +#import "keychain/ot/OTDefines.h" +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol OTAuthKitAdapterNotifier +- (void)machinesAdded:(NSArray*)machineIDs altDSID:(NSString*)altDSID; +- (void)machinesRemoved:(NSArray*)machineIDs altDSID:(NSString*)altDSID; +- (void)incompleteNotificationOfMachineIDListChange; +@end + +@protocol OTAuthKitAdapter + +// Returns nil if there is no such primary account +- (NSString* _Nullable)primaryiCloudAccountAltDSID; + +- (BOOL)accountIsHSA2ByAltDSID:(NSString*)altDSID; + +- (NSString* _Nullable)machineID:(NSError**)error; +- (void)fetchCurrentDeviceList:(void (^)(NSSet* _Nullable machineIDs, NSError* _Nullable error))complete; +- (void)registerNotification:(id)notifier; +@end + +@interface OTAuthKitActualAdapter : NSObject +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON + diff --git a/keychain/ot/OTAuthKitAdapter.m b/keychain/ot/OTAuthKitAdapter.m new file mode 100644 index 00000000..939e58c5 --- /dev/null +++ b/keychain/ot/OTAuthKitAdapter.m @@ -0,0 +1,178 @@ +#if OCTAGON + +#import "OTAuthKitAdapter.h" + +#import "utilities/SecCFError.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import +#import +#import +#import +#import +#import +#import "keychain/ckks/CKKSListenerCollection.h" + +#import + +@interface OTAuthKitActualAdapter () +@property CKKSListenerCollection* notifiers; +@end + +@implementation OTAuthKitActualAdapter + +- (NSString* _Nullable)primaryiCloudAccountAltDSID +{ + ACAccountStore *store = [[ACAccountStore alloc] init]; + ACAccount* primaryAccount = [store aa_primaryAppleAccount]; + if(!primaryAccount) { + return nil; + } + + return [primaryAccount aa_altDSID]; +} + +- (BOOL)accountIsHSA2ByAltDSID:(NSString*)altDSID +{ + bool hsa2 = false; + + AKAccountManager *manager = [AKAccountManager sharedInstance]; + ACAccount *authKitAccount = [manager authKitAccountWithAltDSID:altDSID]; + AKAppleIDSecurityLevel securityLevel = [manager securityLevelForAccount:authKitAccount]; + if(securityLevel == AKAppleIDSecurityLevelHSA2) { + hsa2 = true; + } + secnotice("security-authkit", "Security level for altDSID %@ is %lu", altDSID, (unsigned long)securityLevel); + return hsa2; +} + +- (NSString* _Nullable)machineID:(NSError**)error +{ + AKAnisetteProvisioningController* anisetteController = [[AKAnisetteProvisioningController alloc] init]; + NSError* localError = nil; + AKAnisetteData* anisetteData = [anisetteController anisetteDataWithError:&localError]; + if(!anisetteData) { + secnotice("authkit", "Unable to fetch data: %@", localError); + if(error) { + *error = localError; + } + return nil; + } + + NSString* machineID = anisetteData.machineID; + if(!machineID) { + secnotice("authkit", "Anisette data does not have machineID"); + if(error) { + // TODO: this is a terrible error + *error = [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain + code:errSecParam + description:@"Anisette data does not have machineID"]; + } + return nil; + } + + secnotice("authkit", "fetched current machine ID as: %@", machineID); + + return machineID; +} + +- (void)fetchCurrentDeviceList:(void (^)(NSSet* _Nullable machineIDs, NSError* _Nullable error))complete +{ + ACAccountStore *store = [[ACAccountStore alloc] init]; + ACAccount* primaryAccount = [store aa_primaryAppleAccount]; + if(primaryAccount == nil) { + secnotice("authkit", "can't get account"); + complete(nil, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain + code:errSecParam + description:@"no primary account"]); + return; + } + + AKDeviceListRequestContext* context = [[AKDeviceListRequestContext alloc] init]; + if (context == nil) { + complete(nil, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain + code:errSecParam + description:@"can't get AKDeviceListRequestContextClass"]); + return; + } + context.altDSID = primaryAccount.aa_altDSID; + + AKAppleIDAuthenticationController *authController = [[AKAppleIDAuthenticationController alloc] init]; + if(authController == nil) { + complete(nil, [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain + code:errSecParam + description:@"can't get authController"]); + return; + } + + [authController fetchDeviceListWithContext:context completion:^(NSArray *deviceList, NSError *error) { + if (deviceList) { + NSMutableSet *mids = [[NSMutableSet alloc] init]; + + for (AKRemoteDevice *device in deviceList) { + [mids addObject:device.machineId]; + } + + secnotice("authkit", "Current machine ID list: %@", mids); + complete(mids, error); + } else { + secnotice("authkit", "received no device list: %@", error); + complete(nil, error); + } + }]; +} + +- (void)registerNotification:(id)newNotifier +{ + if (self.notifiers == nil) { + self.notifiers = [[CKKSListenerCollection alloc] initWithName:@"otauthkitadapter-notifiers"]; + [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(notifyAKDeviceList:) name:AKDeviceListChangedNotification object:nil]; + } + [self.notifiers registerListener:newNotifier]; +} + +- (void)notifyAKDeviceList:(NSNotification* _Nullable)notification +{ + AKDeviceListDeltaMessagePayload *payload = nil; + NSDictionary *userInfo = nil; + if (notification != nil) { + userInfo = [notification userInfo]; + if (userInfo != nil) { + payload = [[AKDeviceListDeltaMessagePayload alloc] initWithResponseBody:userInfo]; + } + } + + secnotice("authkit", "received notifyAKDeviceList: %@, read payload: %@", + notification.userInfo, + // Logging the payload logs an address, so clean it up here. + payload ? @"YES" : @"NO"); + + [self.notifiers iterateListeners:^(id listener) { + NSString* altDSID = payload.altDSID; + NSArray* machineIDs = payload.machineIDs; + + if (altDSID == nil || machineIDs == nil || machineIDs.count == 0) { + secnotice("authkit", "partial push or no machine IDs in list; treating as incomplete"); + [listener incompleteNotificationOfMachineIDListChange]; + return; + } + switch (payload.operation) { + case AKDeviceListDeltaOperationAdd: + [listener machinesAdded:machineIDs altDSID:altDSID]; + return; + break; + case AKDeviceListDeltaOperationRemove: + [listener machinesRemoved:machineIDs altDSID:altDSID]; + return; + break; + case AKDeviceListDeltaOperationUnknown: + default: + break; + } + [listener incompleteNotificationOfMachineIDListChange]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTBottledPeer.m b/keychain/ot/OTBottledPeer.m index 0d3992d5..69e07cf9 100644 --- a/keychain/ot/OTBottledPeer.m +++ b/keychain/ot/OTBottledPeer.m @@ -40,14 +40,16 @@ #import +#if 0 #import "OTBottle.h" #import "OTBottleContents.h" +#endif + #import "OTDefines.h" #import "OTPrivateKey.h" #import "OTPrivateKey+SF.h" #import "OTAuthenticatedCiphertext.h" #import "OTAuthenticatedCiphertext+SF.h" -#import "SFPublicKey+SPKI.h" @interface OTBottledPeer () @@ -79,6 +81,7 @@ { self = [super init]; if (self) { +#if 0 // Serialize the peer private keys into "contents" OTBottleContents *contentsObj = [[OTBottleContents alloc] init]; contentsObj.peerSigningPrivKey = [OTPrivateKey fromECKeyPair:peerSigningKey]; @@ -96,10 +99,10 @@ OTBottle *obj = [[OTBottle alloc] init]; obj.peerID = peerID; obj.spID = spID; - obj.escrowedSigningSPKI = [escrowKeys.signingKey.publicKey asSPKI]; - obj.escrowedEncryptionSPKI = [escrowKeys.encryptionKey.publicKey asSPKI]; - obj.peerSigningSPKI = [peerSigningKey.publicKey asSPKI]; - obj.peerEncryptionSPKI = [peerEncryptionKey.publicKey asSPKI]; + obj.escrowedSigningSPKI = [escrowKeys.signingKey.publicKey encodeSubjectPublicKeyInfo]; + obj.escrowedEncryptionSPKI = [escrowKeys.encryptionKey.publicKey encodeSubjectPublicKeyInfo]; + obj.peerSigningSPKI = [peerSigningKey.publicKey encodeSubjectPublicKeyInfo]; + obj.peerEncryptionSPKI = [peerEncryptionKey.publicKey encodeSubjectPublicKeyInfo]; obj.contents = [OTAuthenticatedCiphertext fromSFAuthenticatedCiphertext:cipher]; _peerID = [peerID copy]; @@ -107,6 +110,7 @@ _peerSigningKey = peerSigningKey; _peerEncryptionKey = peerEncryptionKey; _data = obj.data; +#endif } return self; } @@ -119,17 +123,17 @@ { self = [super init]; if (self) { +#if 0 NSError* localError =nil; - // Deserialize the whole thing OTBottle *obj = [[OTBottle alloc] initWithData:data]; if (!obj) { secerror("octagon: failed to deserialize data into OTBottle"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorDeserializationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorDeserializationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; } return nil; - } + // Decrypt contents SFAuthenticatedEncryptionOperation *op = [OTBottledPeer encryptionOperation]; @@ -148,43 +152,48 @@ if (!contentsObj) { secerror("octagon: could not deserialize bottle contents"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorDeserializationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle contents"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorDeserializationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle contents"}]; } return nil; } _peerID = obj.peerID; _spID = obj.spID; + if (self.keyType != OTPrivateKey_KeyType_EC_NIST_CURVES) { + return nil; + } + return [[SFECKeyPair alloc] initWithSecKey:[EscrowKeys createSecKey:self.keyData]]; + _peerSigningKey = [contentsObj.peerSigningPrivKey asECKeyPair]; _peerEncryptionKey = [contentsObj.peerEncryptionPrivKey asECKeyPair]; if (!_peerSigningKey || !_peerEncryptionKey) { secerror("octagon: could not get private EC keys from bottle contents"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to instantiate octagon peer keys"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to instantiate octagon peer keys"}]; } return nil; } _data = [data copy]; - SFECPublicKey *peerSigningPubKey = [SFECPublicKey fromSPKI:obj.peerSigningSPKI]; - SFECPublicKey *peerEncryptionPubKey = [SFECPublicKey fromSPKI:obj.peerEncryptionSPKI]; + SFECPublicKey *peerSigningPubKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:obj.peerSigningSPKI]; + SFECPublicKey *peerEncryptionPubKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:obj.peerEncryptionSPKI]; // Check the private keys match the public keys if (![_peerSigningKey.publicKey isEqual:peerSigningPubKey]) { secerror("octagon: public and private peer signing keys do not match"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"public and private peer signing keys do not match"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"public and private peer signing keys do not match"}]; } return nil; } if (![_peerEncryptionKey.publicKey isEqual:peerEncryptionPubKey]) { secerror("octagon: public and private peer encryption keys do not match"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"public and private peer encryption keys do not match"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorPrivateKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"public and private peer encryption keys do not match"}]; } return nil; } - +#endif } return self; } diff --git a/keychain/ot/OTBottledPeerRecord.h b/keychain/ot/OTBottledPeerRecord.h index 43c7802d..18390f91 100644 --- a/keychain/ot/OTBottledPeerRecord.h +++ b/keychain/ot/OTBottledPeerRecord.h @@ -20,6 +20,7 @@ * * @APPLE_LICENSE_HEADER_END@ */ +#if OCTAGON #import @@ -40,4 +41,4 @@ + (NSString*) constructRecordID:(NSString*)escrowRecordID escrowSigningSPKI:(NSData*)escrowSigningSPKI; @end - +#endif diff --git a/keychain/ot/OTBottledPeerRecord.m b/keychain/ot/OTBottledPeerRecord.m index b7646eef..5dd5f270 100644 --- a/keychain/ot/OTBottledPeerRecord.m +++ b/keychain/ot/OTBottledPeerRecord.m @@ -21,7 +21,7 @@ * @APPLE_LICENSE_HEADER_END@ */ - +#if OCTAGON #import "OTBottledPeerRecord.h" #import #import @@ -49,3 +49,4 @@ static NSString* OTCKRecordName = @"bp-"; } @end +#endif diff --git a/keychain/ot/OTBottledPeerSigned.m b/keychain/ot/OTBottledPeerSigned.m index a639fe73..eeef3d06 100644 --- a/keychain/ot/OTBottledPeerSigned.m +++ b/keychain/ot/OTBottledPeerSigned.m @@ -25,7 +25,6 @@ #import #import "OTBottledPeer.h" #import "OTBottledPeerSigned.h" -#import "SFPublicKey+SPKI.h" #import "OTIdentity.h" #import @@ -58,7 +57,7 @@ self = [super init]; if (self) { _bp = bp; - _escrowSigningSPKI = [escrowedSigningKey.publicKey asSPKI]; + _escrowSigningSPKI = [escrowedSigningKey.publicKey encodeSubjectPublicKeyInfo]; SFEC_X962SigningOperation* xso = [OTBottledPeerSigned signingOperation]; _signatureUsingEscrowKey = [xso sign:bp.data withKey:escrowedSigningKey error:error].signature; if (!_signatureUsingEscrowKey) { @@ -92,7 +91,7 @@ self = [super init]; if (self) { _bp = bp; - _escrowSigningSPKI = [escrowedSigningPubKey asSPKI]; + _escrowSigningSPKI = [escrowedSigningPubKey encodeSubjectPublicKeyInfo]; _signatureUsingPeerKey = signatureUsingPeerKey; _signatureUsingEscrowKey = signatureUsingEscrow; _escrowSigningPublicKey = [escrowedSigningPubKey keyData]; @@ -152,7 +151,7 @@ OTBottledPeerRecord *rec = [[OTBottledPeerRecord alloc] init]; rec.spID = self.bp.spID; rec.escrowRecordID = [escrowRecordID copy]; - rec.peerSigningSPKI = [self.bp.peerSigningKey.publicKey asSPKI]; + rec.peerSigningSPKI = [self.bp.peerSigningKey.publicKey encodeSubjectPublicKeyInfo]; rec.escrowedSigningSPKI = self.escrowSigningSPKI; rec.bottle = self.bp.data; rec.signatureUsingPeerKey = self.signatureUsingPeerKey; diff --git a/keychain/ot/OTBottledPeerState.h b/keychain/ot/OTBottledPeerState.h new file mode 100644 index 00000000..eb0ec436 --- /dev/null +++ b/keychain/ot/OTBottledPeerState.h @@ -0,0 +1,59 @@ +/* + * 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 OCTAGON + +#ifndef OTBottledPeerState_h +#define OTBottledPeerState_h + +#import + +NS_ASSUME_NONNULL_BEGIN + +/* Bottled Peer States */ +@protocol SecOTBottledPeerState +@end +typedef NSString OTBottledPeerState; + +// Octagon Trust currently logged out +extern OTBottledPeerState* const SecOTBottledPeerStateLoggedOut; + +// Octagon Trust currently signed in +extern OTBottledPeerState* const SecOTBottledPeerStateSignedIn; + +// Octagon Trust: check bottle states +extern OTBottledPeerState* const SecOTBottledPeerStateInventoryCheck; + +// Octagon Trust: update bottles for current peerid with current octagon keys +extern OTBottledPeerState* const SecOTBottledPeerStateUpdateBottles; + +// Octagon Trust: bottles exist for the current octagon key set and have been writte to cloudkit +extern OTBottledPeerState* const SecOTBottledPeerStateCleanBottles; + +// Octagon Trust: bottles for current peerid have been updated and persited locally, but not commited to cloudkit +extern OTBottledPeerState* const SecOTBottledPeerStateDirtyBottles; + +NS_ASSUME_NONNULL_END + +#endif /* OTBottledPeerState_h */ +#endif diff --git a/keychain/ot/OTBottledPeerState.m b/keychain/ot/OTBottledPeerState.m new file mode 100644 index 00000000..3c697b2e --- /dev/null +++ b/keychain/ot/OTBottledPeerState.m @@ -0,0 +1,35 @@ +/* + * 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 OCTAGON + +#import "keychain/ot/OTBottledPeerState.h" + +OTBottledPeerState* const SecOTBottledPeerStateLoggedOut = (OTBottledPeerState*) @"loggedout"; +OTBottledPeerState* const SecOTBottledPeerStateSignedIn = (OTBottledPeerState*) @"signedin"; +OTBottledPeerState* const SecOTBottledPeerStateInventoryCheck = (OTBottledPeerState*) @"inventorycheck"; +OTBottledPeerState* const SecOTBottledPeerStateUpdateBottles = (OTBottledPeerState*) @"updatebottles"; +OTBottledPeerState* const SecOTBottledPeerStateCleanBottles = (OTBottledPeerState*) @"cleanbottles"; +OTBottledPeerState* const SecOTBottledPeerStateDirtyBottles = (OTBottledPeerState*) @"dirtybottles"; + +#endif diff --git a/keychain/ot/OTCheckHealthOperation.h b/keychain/ot/OTCheckHealthOperation.h new file mode 100644 index 00000000..e3463e6d --- /dev/null +++ b/keychain/ot/OTCheckHealthOperation.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2019 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "OTDeviceInformation.h" +#import "keychain/ot/OTOperationDependencies.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + + +@interface OTCheckHealthOperation : CKKSGroupOperation +@property OctagonState* nextState; + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + deviceInfo:(nonnull OTDeviceInformation *)deviceInfo + skipRateLimitedCheck:(BOOL)skipRateLimitedCheck; + +@property OTDeviceInformation* deviceInfo; +@property (weak) OTCuttlefishContext* cuttlefishContext; + +@property BOOL skipRateLimitingCheck; +@property BOOL postRepairCFU; +@property BOOL postEscrowCFU; +@property BOOL resetOctagon; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTCheckHealthOperation.m b/keychain/ot/OTCheckHealthOperation.m new file mode 100644 index 00000000..b1edee94 --- /dev/null +++ b/keychain/ot/OTCheckHealthOperation.m @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2019 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 "keychain/ot/OTCheckHealthOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import + +#if !TARGET_OS_SIMULATOR +#import +#endif + +#if TARGET_OS_MAC && !TARGET_OS_SIMULATOR +#include +#endif + +@interface OTCheckHealthOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishOp; +@property BOOL requiresEscrowCheck; +@end + +@implementation OTCheckHealthOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + deviceInfo:(nonnull OTDeviceInformation *)deviceInfo + skipRateLimitedCheck:(BOOL)skipRateLimitedCheck +{ + if((self = [super init])) { + _deps = dependencies; + _intendedState = intendedState; + _nextState = errorState; + _postRepairCFU = NO; + _postEscrowCFU = NO; + _resetOctagon = NO; + _skipRateLimitingCheck = skipRateLimitedCheck; + } + return self; +} + +- (BOOL) checkIfPasscodeIsSetForDevice +{ + BOOL passcodeIsSet = NO; +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR + int lockState = MKBGetDeviceLockState(NULL); + if (lockState != kMobileKeyBagDisabled && lockState >= 0) { + passcodeIsSet = YES; + } +#elif TARGET_OS_MAC && !TARGET_OS_SIMULATOR + NSDictionary *options = @{ (id)kKeyBagDeviceHandle : [[NSNumber alloc] initWithInt: getuid()] }; + int lockState = MKBGetDeviceLockState((__bridge CFDictionaryRef)(options)); + if (lockState != kMobileKeyBagDisabled && lockState >= 0) { + passcodeIsSet = YES; + } +#else +#endif + return passcodeIsSet; +} + +- (void)groupStart +{ + secnotice("octagon-health", "Beginning cuttlefish health checkup"); + + self.finishOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishOp]; + + if(self.skipRateLimitingCheck == NO) { + secnotice("octagon-health", "running rate limiting checks!"); + NSDate* lastUpdate = nil; + NSError* accountLoadError = nil; + self.error = nil; + + lastUpdate = [self.deps.stateHolder lastHealthCheckupDate:&accountLoadError]; + if([self.deps.viewManager.lockStateTracker isLockedError: accountLoadError]) { + secnotice("octagon-health", "device is locked, not performing cuttlefish check"); + [self runBeforeGroupFinished:self.finishOp]; + return; + } + secnotice("octagon-health", "last health check timestamp: %@", lastUpdate); + + // Only query cuttlefish for trust status every 3 days (1 day for internal installs) + NSDateComponents* offset = [[NSDateComponents alloc] init]; + if(SecIsInternalRelease()) { + [offset setHour:-23]; + } else { + [offset setHour:-3*24]; + } + NSDate *now = [NSDate date]; + NSDate* deadline = [[NSCalendar currentCalendar] dateByAddingComponents:offset toDate:now options:0]; + + if(lastUpdate == nil || [lastUpdate compare: deadline] == NSOrderedAscending) { + secnotice("octagon-health", "Not rate-limiting: last updated %@ vs %@", lastUpdate, deadline); + } else { + secnotice("octagon-health", "Last update is within 3 days (%@); rate-limiting this operation", lastUpdate); + NSString *description = [NSString stringWithFormat:@"Rate-limited the OTCheckHealthOperation:%@", lastUpdate]; + NSError *rateLimitedError = [NSError errorWithDomain:@"securityd" + code:errSecInternalError + userInfo:@{NSLocalizedDescriptionKey: description}]; + secnotice("octagon-health", "rate limited! %@", rateLimitedError); + self.nextState = self.intendedState; //not setting the error on the results op as I don't want a CFU posted. + [self runBeforeGroupFinished:self.finishOp]; + return; + } + NSError* persistedError = nil; + BOOL persisted = [self.deps.stateHolder persistLastHealthCheck:now error:&persistedError]; + + if([self.deps.viewManager.lockStateTracker isLockedError: persistedError]) { + secnotice("octagon-health", "device is locked, not performing cuttlefish check"); + [self runBeforeGroupFinished:self.finishOp]; + return; + } + if(persisted == NO || persistedError) { + secerror("octagon-health: failed to persist last health check value:%@", persistedError); + [self runBeforeGroupFinished:self.finishOp]; + return; + } + } else { + secnotice("octagon-health", "NOT running rate limiting checks!"); + } + WEAKIFY(self); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon-health: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishOp]; + return; + + }] requestHealthCheckWithContainer:self.deps.containerName + context:self.deps.contextID + requiresEscrowCheck: [self checkIfPasscodeIsSetForDevice] + reply:^(BOOL postRepairCFU, BOOL postEscrowCFU, BOOL resetOctagon, NSError *error) { + STRONGIFY(self); + if(error) { + secerror("octagon-health: error: %@", error); + self.error = error; + } else { + secnotice("octagon-health", "cuttlefish came back with these suggestions\n: post repair? %d\n, post escrow? %d\n, reset octagon? %d", postRepairCFU, postEscrowCFU, resetOctagon); + self.postEscrowCFU = postEscrowCFU; + self.postRepairCFU = postRepairCFU; + self.resetOctagon = resetOctagon; + + self.nextState = self.intendedState; + } + [self runBeforeGroupFinished:self.finishOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTClientStateMachine.h b/keychain/ot/OTClientStateMachine.h new file mode 100644 index 00000000..98c96195 --- /dev/null +++ b/keychain/ot/OTClientStateMachine.h @@ -0,0 +1,83 @@ +/* + * 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 OCTAGON +#import +#import + +#import "keychain/ckks/OctagonAPSReceiver.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import + +NS_ASSUME_NONNULL_BEGIN + +/* Piggybacking and ProximitySetup as Acceptor, Octagon only */ +extern OctagonState* const OctagonStateAcceptorBeginClientJoin; +extern OctagonState* const OctagonStateAcceptorEpochPrepared; +extern OctagonState* const OctagonStateAcceptorAwaitingIdentity; +extern OctagonState* const OctagonStateAcceptorVoucherPrepared; +extern OctagonState* const OctagonStateAcceptorDone; + +NSDictionary* OctagonClientStateMap(void); + +@interface OTClientStateMachine : NSObject + +@property (readonly) id cuttlefishXPCConnection; + +@property (readonly) NSString* containerName; +@property (readonly) NSString* contextID; +@property (readonly) NSString* clientName; + +@property (readonly) OctagonState* currentState; +@property NSMutableDictionary* stateConditions; + +- (instancetype)initWithContainerName:(NSString*)containerName + contextID:(NSString*)contextID + clientName:(NSString*)clientName + cuttlefish:(id)cuttlefish; + +- (void)startOctagonStateMachine; +- (void)notifyContainerChange; + +- (void)rpcEpoch:(OTCuttlefishContext*)cuttlefishContext + reply:(void (^)(uint64_t epoch, + NSError * _Nullable error))reply; + +- (void)rpcVoucher:(OTCuttlefishContext*)cuttlefishContext + peerID:(NSString*)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + reply:(void (^)(NSData* voucher, NSData* voucherSig, NSError * _Nullable error))reply; +@end + +NS_ASSUME_NONNULL_END +#endif + diff --git a/keychain/ot/OTClientStateMachine.m b/keychain/ot/OTClientStateMachine.m new file mode 100644 index 00000000..8570fa0d --- /dev/null +++ b/keychain/ot/OTClientStateMachine.m @@ -0,0 +1,369 @@ +/* + * 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 OCTAGON + +#import + +#import + +#include +#include + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ckks/CKKSResultOperation.h" + +#import "keychain/ckks/OctagonAPSReceiver.h" + +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import "keychain/ot/ObjCImprovements.h" + +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTContext.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTPrepareOperation.h" +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OTEpochOperation.h" +#import "keychain/ot/OTClientVoucherOperation.h" +#import "keychain/ot/OTStates.h" + +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" + +#define otclientnotice(scope, format, ...) __extension__({ \ + os_log(secLogObjForCFScope((__bridge CFStringRef)(scope)), format, ##__VA_ARGS__); \ + }) + +/*Piggybacking and ProximitySetup as Acceptor Octagon only*/ +OctagonState* const OctagonStateAcceptorBeginClientJoin = (OctagonState*)@"client_join"; +OctagonState* const OctagonStateAcceptorBeginAwaitEpochRequest = (OctagonState*)@"await_epoch_request"; +OctagonState* const OctagonStateAcceptorEpochPrepared = (OctagonState*)@"epoch_prepared"; +OctagonState* const OctagonStateAcceptorAwaitingIdentity = (OctagonState*)@"await_identity"; +OctagonState* const OctagonStateAcceptorVoucherPrepared = (OctagonState*)@"voucher_prepared"; +OctagonState* const OctagonStateAcceptorDone = (OctagonState*)@"done"; + +NSDictionary* OctagonClientStateMap(void) { + static NSDictionary* map = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + map = @{ + OctagonStateAcceptorBeginClientJoin: @0U, + OctagonStateAcceptorBeginAwaitEpochRequest: @1U, + OctagonStateAcceptorEpochPrepared: @2U, + OctagonStateAcceptorAwaitingIdentity: @3U, + OctagonStateAcceptorVoucherPrepared: @4U, + OctagonStateAcceptorDone: @5U, + }; + }); + return map; +} + +@interface OTClientStateMachine () +{ + OctagonState* _currentState; +} + +@property dispatch_queue_t queue; +@property NSOperationQueue* operationQueue; + +// Make writable +@property OctagonState* currentState; +@property NSString* clientScope; + +// Set this to an operation to pause the state machine in-flight +@property NSOperation* holdStateMachineOperation; + +@property CKKSResultOperation* nextClientStateMachineCycleOperation; + +@property NSMutableArray*>*>* stateMachineClientRequests; + +@end + +@implementation OTClientStateMachine + +- (instancetype)initWithContainerName:(NSString*)containerName + contextID:(NSString*)contextID + clientName:(NSString*)clientName + cuttlefish:(id)cuttlefish +{ + if ((self = [super init])) { + _containerName = containerName; + _clientName = clientName; + _contextID = contextID; + + _queue = dispatch_queue_create("com.apple.security.otclientstatemachine", DISPATCH_QUEUE_SERIAL); + _operationQueue = [[NSOperationQueue alloc] init]; + + _stateConditions = [[NSMutableDictionary alloc] init]; + [OctagonClientStateMap() enumerateKeysAndObjectsUsingBlock:^(OctagonState * _Nonnull key, NSNumber * _Nonnull obj, BOOL * _Nonnull stop) { + self.stateConditions[key] = [[CKKSCondition alloc] init]; + }]; + + // Use the setter method to set the condition variables + self.currentState = OctagonStateMachineNotStarted; + + _stateMachineClientRequests = [NSMutableArray array]; + _holdStateMachineOperation = [NSBlockOperation blockOperationWithBlock:^{}]; + + OctagonStateTransitionOperation* beginClientJoin = [OctagonStateTransitionOperation named:@"initialize-client" + entering:OctagonStateAcceptorBeginClientJoin]; + [beginClientJoin addDependency:_holdStateMachineOperation]; + [_operationQueue addOperation:beginClientJoin]; + + CKKSResultOperation* startStateMachineOp = [self createOperationToFinishAttemptForClient:beginClientJoin clientName:clientName]; + [_operationQueue addOperation:startStateMachineOp]; + + _cuttlefishXPCConnection = cuttlefish; + + _clientScope = [NSString stringWithFormat:@"octagon-client-%@-state", clientName]; + } + return self; +} + +- (void)dealloc +{ + // TODO: how to invalidate this? + //[self.cuttlefishXPCConnection invalidate]; +} + +- (OctagonState* _Nonnull)currentState { + return _currentState; +} + +- (void)setCurrentState:(OctagonState* _Nonnull)state { + if((state == nil && _currentState == nil) || ([state isEqualToString:_currentState])) { + // No change, do nothing. + } else { + // Fixup the condition variables as part of setting this state + if(_currentState) { + self.stateConditions[_currentState] = [[CKKSCondition alloc] init]; + } + + _currentState = state; + + if(state) { + [self.stateConditions[state] fulfill]; + } + } +} + +- (void)startOctagonStateMachine { + dispatch_sync(self.queue, ^{ + if(self.holdStateMachineOperation) { + [self.operationQueue addOperation: self.holdStateMachineOperation]; + self.holdStateMachineOperation = nil; + } + }); +} + +#pragma mark --- Client State Machine Machinery + +- (CKKSResultOperation*)createOperationToFinishAttemptForClient:(CKKSResultOperation*)attempt clientName:(NSString*)clientName +{ + WEAKIFY(self); + + CKKSResultOperation* followUp = [CKKSResultOperation named:@"octagon-state-follow-up" withBlock:^{ + STRONGIFY(self); + + dispatch_sync(self.queue, ^{ + otclientnotice(self.clientScope, "Finishing state transition attempt %@", attempt); + + self.currentState = attempt.nextState; + self.nextClientStateMachineCycleOperation = nil; + + [self _onqueueStartNextClientStateMachineOperation:clientName]; + }); + }]; + [followUp addNullableDependency:self.holdStateMachineOperation]; + [followUp addNullableDependency:attempt]; + return followUp; +} + +- (void)_onqueuePokeClientStateMachine:(NSString*)clientName +{ + dispatch_assert_queue(self.queue); + if(!self.nextClientStateMachineCycleOperation) { + [self _onqueueStartNextClientStateMachineOperation:clientName]; + } +} + +- (void)_onqueueStartNextClientStateMachineOperation:(NSString*)clientName { + dispatch_assert_queue(self.queue); + + CKKSResultOperation* nextAttempt = [self _onqueueNextClientStateMachineTransition:clientName]; + if(nextAttempt) { + otclientnotice(self.clientScope, "Beginning client state transition attempt %@", nextAttempt); + + self.nextClientStateMachineCycleOperation = [self createOperationToFinishAttemptForClient:nextAttempt clientName:clientName]; + [self.operationQueue addOperation:self.nextClientStateMachineCycleOperation]; + + [nextAttempt addNullableDependency:self.holdStateMachineOperation]; + [self.operationQueue addOperation:nextAttempt]; + } +} + +- (void)handleExternalClientStateMachineRequest:(OctagonStateTransitionRequest*>*)request client:(NSString*)clientName +{ + dispatch_sync(self.queue, ^{ + [self.stateMachineClientRequests addObject:request]; + + [self _onqueuePokeClientStateMachine:clientName]; + }); +} +-(BOOL) isAcceptorWaitingForFirstMessage +{ + BOOL isWaitingForFirstMessage = NO; + + if([self.currentState isEqualToString:OctagonStateAcceptorBeginClientJoin] || [self.currentState isEqualToString:OctagonStateMachineNotStarted]){ + isWaitingForFirstMessage = YES; + } + return isWaitingForFirstMessage; +} +#pragma mark --- Client State Machine Transitions +- (CKKSResultOperation* _Nullable)_onqueueNextClientStateMachineTransition:(NSString*)clientName +{ + dispatch_assert_queue(self.queue); + + // Check requests: do any of them want to come from this state? + for(OctagonStateTransitionRequest* request in self.stateMachineClientRequests) { + if([request.sourceStates containsObject:self.currentState]) { + CKKSResultOperation* attempt = [request _onqueueStart]; + + if(attempt) { + otclientnotice(self.clientScope, "Running client %@ state machine request %@ (from %@)", clientName, request, self.currentState); + return attempt; + } + } + } + if([self.currentState isEqualToString: OctagonStateAcceptorVoucherPrepared]){ + return [OctagonStateTransitionOperation named:@"octagon-voucher-prepared" + intending:OctagonStateAcceptorDone + errorState:OctagonStateError + timeout:10*NSEC_PER_SEC + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + otclientnotice(self.clientScope, "moving to state done for %@", clientName); + op.nextState = OctagonStateAcceptorDone; + }]; + }else if([self.currentState isEqualToString: OctagonStateAcceptorDone]){ + otclientnotice(self.clientScope, "removing client connection for %@", clientName); + } + + return nil; +} + +- (void)notifyContainerChange +{ + secerror("OTCuttlefishContext: received a cuttlefish push notification (%@)", self.containerName); + [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon: Can't talk with TrustedPeersHelper, update is lost: %@", error); + + }] updateWithContainer:self.containerName + context:self.contextID + deviceName:nil + serialNumber:nil + osVersion:nil + policyVersion:nil + policySecrets:nil + reply:^(TrustedPeersHelperPeerState* peerState, NSError* error) { + if(error) { + secerror("OTCuttlefishContext: updating errored: %@", error); + } else { + secerror("OTCuttlefishContext: update complete"); + } + }]; +} + +#pragma mark --- External Interfaces + +- (void)rpcEpoch:(OTCuttlefishContext*)cuttlefishContext + reply:(void (^)(uint64_t epoch, + NSError * _Nullable error))reply +{ + OTEpochOperation* pendingOp = [[OTEpochOperation alloc] initForCuttlefishContext:cuttlefishContext + intendedState:OctagonStateAcceptorAwaitingIdentity + errorState:OctagonStateAcceptorDone]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"rpcEpoch" + sourceStates:[NSSet setWithArray:@[OctagonStateAcceptorBeginClientJoin]] + serialQueue:self.queue + timeout:2*NSEC_PER_SEC + transitionOp:pendingOp]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"rpcEpoch-callback" + withBlock:^{ + secnotice("otrpc", "Returning an epoch call: %llu %@", pendingOp.epoch, pendingOp.error); + reply(pendingOp.epoch, + pendingOp.error); + }]; + [callback addDependency:pendingOp]; + [self.operationQueue addOperation: callback]; + + [self handleExternalClientStateMachineRequest:request client:self.clientName]; + + return; +} + +- (void)rpcVoucher:(OTCuttlefishContext*)cuttlefishContext + peerID:(NSString*)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + reply:(void (^)(NSData* voucher, NSData* voucherSig, NSError * _Nullable error))reply +{ + OTClientVoucherOperation* pendingOp = [[OTClientVoucherOperation alloc] initWithDependencies:cuttlefishContext.operationDependencies + intendedState:OctagonStateAcceptorVoucherPrepared + errorState:OctagonStateAcceptorDone + deviceInfo:[cuttlefishContext prepareInformation] + peerID:peerID + permanentInfo:permanentInfo + permanentInfoSig:permanentInfoSig + stableInfo:stableInfo + stableInfoSig:stableInfoSig]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"rpcVoucher" + sourceStates:[NSSet setWithArray:@[OctagonStateAcceptorAwaitingIdentity]] + serialQueue:self.queue + timeout:2*NSEC_PER_SEC + + transitionOp:pendingOp]; + CKKSResultOperation* callback = [CKKSResultOperation named:@"rpcVoucher-callback" + withBlock:^{ + secnotice("otrpc", "Returning a voucher call: %@, %@, %@", pendingOp.voucher, pendingOp.voucherSig, pendingOp.error); + reply(pendingOp.voucher, pendingOp.voucherSig, pendingOp.error); + }]; + [callback addDependency:pendingOp]; + [self.operationQueue addOperation: callback]; + + [self handleExternalClientStateMachineRequest:request client:self.clientName]; + + return; +} + +@end +#endif diff --git a/keychain/ot/OTClientVoucherOperation.h b/keychain/ot/OTClientVoucherOperation.h new file mode 100644 index 00000000..069e0664 --- /dev/null +++ b/keychain/ot/OTClientVoucherOperation.h @@ -0,0 +1,64 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "OTDeviceInformation.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTClientVoucherOperation : CKKSGroupOperation +@property OctagonState* nextState; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + deviceInfo:(nonnull OTDeviceInformation *)deviceInfo + peerID:(nonnull NSString *)peerID + permanentInfo:(nonnull NSData *)permanentInfo + permanentInfoSig:(nonnull NSData *)permanentInfoSig + stableInfo:(nonnull NSData *)stableInfo + stableInfoSig:(nonnull NSData *)stableInfoSig; + +@property (weak) OTCuttlefishContext* cuttlefishContext; +@property (nonatomic) NSString* peerID; +@property (nonatomic) NSData* permanentInfo; +@property (nonatomic) NSData* permanentInfoSig; +@property (nonatomic) NSData* stableInfo; +@property (nonatomic) NSData* stableInfoSig; +@property OTDeviceInformation* deviceInfo; + +@property (nonatomic) NSData* voucher; +@property (nonatomic) NSData* voucherSig; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTClientVoucherOperation.m b/keychain/ot/OTClientVoucherOperation.m new file mode 100644 index 00000000..0f3d4039 --- /dev/null +++ b/keychain/ot/OTClientVoucherOperation.m @@ -0,0 +1,131 @@ +/* + * 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 "keychain/ot/OTClientVoucherOperation.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTClientVoucherOperation () +@property OTOperationDependencies* operationDependencies; +@property NSOperation* finishedOp; +@end + +@implementation OTClientVoucherOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + deviceInfo:(nonnull OTDeviceInformation *)deviceInfo + peerID:(nonnull NSString *)peerID + permanentInfo:(nonnull NSData *)permanentInfo + permanentInfoSig:(nonnull NSData *)permanentInfoSig + stableInfo:(nonnull NSData *)stableInfo + stableInfoSig:(nonnull NSData *)stableInfoSig +{ + if((self = [super init])) { + _intendedState = intendedState; + _nextState = errorState; + + _operationDependencies = dependencies; + + self.peerID = peerID; + self.permanentInfo = permanentInfo; + self.permanentInfoSig = permanentInfoSig; + self.stableInfo = stableInfo; + self.stableInfoSig = stableInfoSig; + self.deviceInfo = deviceInfo; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "creating voucher"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + WEAKIFY(self); + + // Acquire the CKKS TLKs to pass in + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.operationDependencies]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"vouch-with-keys" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets +{ + WEAKIFY(self); + + secnotice("octagon", "vouching with %d keysets", (int)viewKeySets.count); + + [[self.operationDependencies.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] vouchWithContainer:self.deviceInfo.containerName + context:self.deviceInfo.contextID + peerID:self.peerID + permanentInfo:self.permanentInfo + permanentInfoSig:self.permanentInfoSig + stableInfo:self.stableInfo + stableInfoSig:self.stableInfoSig + ckksKeys:viewKeySets + reply:^(NSData * _Nullable voucher, + NSData * _Nullable voucherSig, + NSError * _Nullable error) + { + if(error){ + secerror("octagon: Error preparing voucher: %@", error); + self.error = error; + }else{ + self.voucher = voucher; + self.voucherSig = voucherSig; + self.nextState = self.intendedState; + } + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTClique.h b/keychain/ot/OTClique.h new file mode 100644 index 00000000..4e8100cc --- /dev/null +++ b/keychain/ot/OTClique.h @@ -0,0 +1,321 @@ +/* + * 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 OTClique_h +#define OTClique_h + +typedef NS_ENUM(NSInteger, CliqueStatus) { + CliqueStatusIn = 0, /*There is a clique and I am in it*/ + CliqueStatusNotIn = 1, /*There is a clique and I am not in it - you should get a voucher to join or tell another peer to trust us*/ + CliqueStatusPending = 2, /*For compatibility, keeping the pending state */ + CliqueStatusAbsent = 3, /*There is no clique - you can establish one */ + CliqueStatusNoCloudKitAccount = 4, /* no cloudkit account present */ + CliqueStatusError = -1 /*unable to determine circle status, inspect CFError to find out why */ +}; + +#import + +#if __OBJC2__ + +#import +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +NSString* OTCliqueStatusToString(CliqueStatus status); +CliqueStatus OTCliqueStatusFromString(NSString* str); + +@class KCPairingChannelContext; +@class KCPairingChannel; +@class OTPairingChannel; +@class OTPairingChannelContext; +@class OTControl; + +extern NSString* kSecEntitlementPrivateOctagonEscrow; + +@interface OTConfigurationContext : NSObject +@property (nonatomic, copy, nullable) NSString* context; +@property (nonatomic, copy) NSString* dsid; +@property (nonatomic, copy) NSString* altDSID; +@property (nonatomic, strong, nullable) SFSignInAnalytics* analytics; + + +// Use this to inject your own OTControl object. It must be configured as synchronous. +@property (nullable, strong) OTControl* otControl; +// Use this to inject your own SecureBackup object. It must conform to the OctagonEscrowRecoverer protocol. +@property (nullable, strong) id sbd; + +// Create a new synchronous OTControl if one doesn't already exist in context. +- (OTControl* _Nullable)makeOTControl:(NSError**)error; +@end + +// OTBottleIDs: an Obj-C Tuple + +@interface OTBottleIDs : NSObject +@property (strong) NSArray* preferredBottleIDs; +@property (strong) NSArray* partialRecoveryBottleIDs; +@end + +@interface OTOperationConfiguration : NSObject +@property (nonatomic, assign) uint64_t timeoutWaitForCKAccount; +@property (nonatomic, assign) NSQualityOfService qualityOfService; +@property (nonatomic, assign) BOOL discretionaryNetwork; +@property (nonatomic, assign) BOOL useCachedAccountStatus; +@end + +typedef NSString* OTCliqueCFUType NS_STRING_ENUM; +extern OTCliqueCFUType OTCliqueCFTypeRepair; +extern OTCliqueCFUType OTCliqueCFTypePasscode; +extern OTCliqueCFUType OTCliqueCFTypeUpgrade; + +typedef NSString* OTCliqueCDPContextType NS_STRING_ENUM; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeNone; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeSignIn; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeRepair; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeFinishPasscodeChange; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeRecoveryKeyGenerate; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeRecoveryKeyNew; +extern OTCliqueCDPContextType OTCliqueCDPContextTypeUpdatePasscode; + + +// OTClique + +@interface OTClique : NSObject + ++ (BOOL)platformSupportsSOS; + +@property (nonatomic, readonly, nullable) NSString* cliqueMemberIdentifier; + +- (instancetype) init NS_UNAVAILABLE; + +// MARK: Clique SPI + +/* * + * @abstract, initializes a clique object given a context. A clique object enables octagon trust operations for a given context and dsid. + * @param ctx, a unique string that is used as a way to retrieve current trust state + * @return an instance of octagon trust + */ +- (instancetype _Nullable)initWithContextData:(OTConfigurationContext *)ctx error:(NSError * __autoreleasing * _Nonnull)error; + +/* * + * @abstract Establish a new clique, reset protected data + * Reset the clique + * Delete backups + * Delete all CKKS data + * + * @param ctx, context containing parameters to setup OTClique + * @return clique, returns a new clique instance + * @param error, error gets filled if something goes horribly wrong + */ ++ (instancetype _Nullable)newFriendsWithContextData:(OTConfigurationContext*)data error:(NSError * __autoreleasing *)error; + +/* + * @abstract Perform a SecureBackup escrow/keychain recovery and attempt to use the information therein to join this account. + * You do not need to call joinAfterRestore after calling this method. + * @param data The OTClique configuration data + * @param sbdRecoveryArguments the grab bag of things you'd normally pass to SecureBackup's recoverWithInfo. + * @param error Reports any error along the process, including 'incorrect secret' and 'couldn't rejoin account'. + * @return a fresh new OTClique, if the account rejoin was successful. Otherwise, nil. + */ ++ (OTClique* _Nullable)performEscrowRecoveryWithContextData:(OTConfigurationContext*)data + escrowArguments:(NSDictionary*)sbdRecoveryArguments + error:(NSError**)error; + +/* * + * @abstract Create pairing channel with + * + * @param ctx, context containing parameters to setup OTClique + * @param pairingChannelContext, context containing parameters to setup the pairing channel as the initiator + * @return clique, An instance of an OTClique + * @return error, error gets filled if something goes horribly wrong + */ +- (KCPairingChannel *)setupPairingChannelAsInitiator:(KCPairingChannelContext *)ctx; + +- (KCPairingChannel * _Nullable)setupPairingChannelAsInitator:(KCPairingChannelContext *)ctx error:(NSError * __autoreleasing *)error __deprecated_msg("setupPairingChannelAsInitiator:error: deprecated, use setupPairingChannelAsInitiator:"); + +/* * + * @abstract Configure this peer as the acceptor during piggybacking + * + * @param ctx, context containing parameters to setup OTClique + * @param pairingChannelContext, context containing parameters to setup the pairing channel as the acceptor + * @param error, error gets filled if something goes horribly wrong + * @return KCPairingChannel, An instance of an OTClique + */ +- (KCPairingChannel *)setupPairingChannelAsAcceptor:(KCPairingChannelContext *)ctx; + +- (KCPairingChannel * _Nullable)setupPairingChannelAsAcceptor:(KCPairingChannelContext *)ctx error:(NSError * __autoreleasing *)error __deprecated_msg("setupPairingChannelAsAcceptor:error: deprecated, use setupPairingChannelAsAcceptor:"); + +/* * + * @abstract Get the cached status of clique - returns one of: + * There is no clique - you can establish one + * There is a clique and I am not in it - you should get a voucher to join or tell another peer to trust us + * There is a clique and I am in it + * @param error, error gets filled if something goes horribly wrong + * @return cached cliqueStatus, value will represent one of the above + */ +- (CliqueStatus)cachedCliqueStatus:(BOOL)useCached error:(NSError * __autoreleasing *)error + __deprecated_msg("use fetchCliqueStatus:"); + +/* * + * @abstract Get status of clique - returns one of: + * There is no clique - you can establish one + * There is a clique and I am not in it - you should get a voucher to join or tell another peer to trust us + * There is a clique and I am in it + * @param error, error gets filled if something goes horribly wrong + * @return cliqueStatus, value will represent one of the above + */ +- (CliqueStatus)fetchCliqueStatus:(NSError * __autoreleasing * _Nonnull)error; + +/* * + * @abstract Get status of clique - returns one of: + * There is no clique - you can establish one + * There is a clique and I am not in it - you should get a voucher to join or tell another peer to trust us + * There is a clique and I am in it + * @param configuration, behavior of operations performed follow up this operation + * @param error, error gets filled if something goes horribly wrong + * @return cliqueStatus, value will represent one of the above + */ +- (CliqueStatus)fetchCliqueStatus:(OTOperationConfiguration *)configuration error:(NSError * __autoreleasing * _Nonnull)error; + +/* * + * @abstract Exclude given a member identifier + * @param friendIdentifiers, friends to remove + * @param error, error gets filled if something goes horribly wrong + * @return BOOL, YES if successful. No if call failed. + */ +- (BOOL)removeFriendsInClique:(NSArray*)friendIdentifiers error:(NSError * __autoreleasing *)error; + + /* * + * @abstract Depart (exclude self) + * Un-enroll from escrow + * @param error, error gets filled if something goes horribly wrong + * @return BOOL, YES if successful. No if call failed. + */ +- (BOOL)leaveClique:(NSError * __autoreleasing *)error; + +/* * + * @abstract Get list of peerIDs and device names + * @param error, error gets filled if something goes horribly wrong + * @return friends, list of peer ids and their mapping to device names of all devices currently in the clique, + * ex: NSDictionary[peerID, device Name]; + */ +- (NSDictionary* _Nullable)peerDeviceNamesByPeerID:(NSError * __autoreleasing *)error; + + + +/* SOS glue */ + +- (BOOL)joinAfterRestore:(NSError * __autoreleasing *)error; + +- (BOOL)safariPasswordSyncingEnabled:(NSError *__autoreleasing*)error; + +- (BOOL)isLastFriend:(NSError *__autoreleasing*)error; + +- (BOOL)waitForInitialSync:(NSError *__autoreleasing*)error; + +- (NSArray*)copyViewUnawarePeerInfo:(NSError *__autoreleasing*)error; + +- (BOOL)viewSet:(NSSet*)enabledViews disabledViews:(NSSet*)disabledViews; + +- (BOOL)setUserCredentialsAndDSID:(NSString*)userLabel + password:(NSData*)userPassword + error:(NSError *__autoreleasing*)error; + +- (BOOL)tryUserCredentialsAndDSID:(NSString*)userLabel + password:(NSData*)userPassword + error:(NSError *__autoreleasing*)error; + +- (NSArray*)copyPeerPeerInfo:(NSError *__autoreleasing*)error; + +- (BOOL)peersHaveViewsEnabled:(NSArray*)viewNames error:(NSError *__autoreleasing*)error; + +- (BOOL)requestToJoinCircle:(NSError *__autoreleasing*)error; + +- (BOOL)accountUserKeyAvailable; + +/* test only */ +- (void)setPairingDefault:(BOOL)defaults; +- (void)removePairingDefault; +/* Internal/sbd only */ + + +/* + * @abstract Ask for the list of best bottle IDs to restore for this account + * Ideally, we will replace this with a findOptimalEscrowRecordIDsWithContextData, but we're gated on + * Cuttlefish being able to read EscrowProxy (to get real escrow record IDs): + * [CUTTLEFISH] Cuttlefish needs to call Escrow Proxy to validate unmigrated accounts + * @param data The OTClique configuration data + * @param error Reports any error along the process + * @return A pair of lists of escrow record IDs + */ ++ (OTBottleIDs* _Nullable)findOptimalBottleIDsWithContextData:(OTConfigurationContext*)data + error:(NSError**)error; + +// This call is a noop. ++ (instancetype _Nullable)recoverWithContextData:(OTConfigurationContext*)data + bottleID:(NSString*)bottleID + escrowedEntropy:(NSData*)entropy + error:(NSError**)error __deprecated_msg("recoverWithContextData:bottleID:escrowedEntropy:error: deprecated, use performEscrowRecoveryWithContextData:escrowArguments:error"); + +// used by sbd to fill in the escrow record +// You must have the entitlement "com.apple.private.octagon.escrow-content" to use this +// Also known as kSecEntitlementPrivateOctagonEscrow +- (void)fetchEscrowContents:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; + +// used by sbd to enroll a recovery key in octagon ++ (void)setNewRecoveryKeyWithData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(SecRecoveryKey * _Nullable rk, + NSError* _Nullable error))reply; + +// used by sbd to recover octagon data by providing a ++ (void)recoverOctagonUsingData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(NSError* _Nullable error))reply; + + +// CoreCDP will call this function when they failed to complete a successful CDP state machine run. +// Errors provided may be propagated from layers beneath CoreCDP, or contain the CoreCDP cause of failure. +- (void)performedFailureCDPStateMachineRun:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + reply:(void(^)(NSError* _Nullable error))reply; + +// CoreCDP will call this function when they complete a successful CDP state machine run. +- (void)performedSuccessfulCDPStateMachineRun:(OTCliqueCDPContextType)type + reply:(void(^)(NSError* _Nullable error))reply; + +// CoreCDP will call this function when they are upgrading an account from SA to HSA2 +- (BOOL)waitForOctagonUpgrade:(NSError** _Nullable)error; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* OBJC2 */ +#endif /* OctagonTrust_h */ diff --git a/keychain/ot/OTClique.m b/keychain/ot/OTClique.m new file mode 100644 index 00000000..918077d4 --- /dev/null +++ b/keychain/ot/OTClique.m @@ -0,0 +1,1439 @@ +/* + * 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 __OBJC2__ + +#import +#import + +#import "keychain/ot/OTClique.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTDefines.h" + +#import +#import + +#import "keychain/SecureObjectSync/SOSCloudCircle.h" +#import "KeychainCircle/PairingChannel.h" +#import + +const NSString* kSecEntitlementPrivateOctagonEscrow = @"com.apple.private.octagon.escrow-content"; + +#if OCTAGON +#import +#import +#import +#import +#import +#import "keychain/ot/OTControl.h" +#import "keychain/ot/categories/OctagonEscrowRecoverer.h" + +SOFT_LINK_FRAMEWORK(PrivateFrameworks, KeychainCircle); +SOFT_LINK_FRAMEWORK(PrivateFrameworks, CloudServices); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wstrict-prototypes" +SOFT_LINK_CLASS(KeychainCircle, KCPairingChannel); +SOFT_LINK_CLASS(KeychainCircle, OTPairingChannel); +SOFT_LINK_CLASS(CloudServices, SecureBackup); +SOFT_LINK_CONSTANT(CloudServices, kSecureBackupErrorDomain, NSErrorDomain); + +#pragma clang diagnostic pop +#endif + +OTCliqueCFUType OTCliqueCFTypeRepair = @"typeRepair"; +OTCliqueCFUType OTCliqueCFTypePasscode = @"typePasscode"; +OTCliqueCFUType OTCliqueCFTypeUpgrade = @"typeUpgrade"; + +OTCliqueCDPContextType OTCliqueCDPContextTypeNone = @"cdpContextTypeNone"; +OTCliqueCDPContextType OTCliqueCDPContextTypeSignIn = @"cdpContextTypeSignIn"; +OTCliqueCDPContextType OTCliqueCDPContextTypeRepair = @"cdpContextTypeRepair"; +OTCliqueCDPContextType OTCliqueCDPContextTypeFinishPasscodeChange = @"cdpContextTypeFinishPasscodeChange"; +OTCliqueCDPContextType OTCliqueCDPContextTypeRecoveryKeyGenerate = @"cdpContextTypeRecoveryKeyGenerate"; +OTCliqueCDPContextType OTCliqueCDPContextTypeRecoveryKeyNew = @"cdpContextTypeRecoveryKeyNew"; +OTCliqueCDPContextType OTCliqueCDPContextTypeUpdatePasscode = @"cdpContextTypeUpdatePasscode"; + +NSString* OTCliqueStatusToString(CliqueStatus status) +{ + switch(status) { + case CliqueStatusIn: + return @"CliqueStatusIn"; + case CliqueStatusNotIn: + return @"CliqueStatusNotIn"; + case CliqueStatusPending: + return @"CliqueStatusPending"; + case CliqueStatusAbsent: + return @"CliqueStatusAbsent"; + case CliqueStatusNoCloudKitAccount: + return @"CliqueStatusNoCloudKitAccount"; + case CliqueStatusError: + return @"CliqueStatusError"; + }; +} +CliqueStatus OTCliqueStatusFromString(NSString* str) +{ + if([str isEqualToString: @"CliqueStatusIn"]) { + return CliqueStatusIn; + } else if([str isEqualToString: @"CliqueStatusNotIn"]) { + return CliqueStatusNotIn; + } else if([str isEqualToString: @"CliqueStatusPending"]) { + return CliqueStatusPending; + } else if([str isEqualToString: @"CliqueStatusAbsent"]) { + return CliqueStatusAbsent; + } else if([str isEqualToString: @"CliqueStatusNoCloudKitAccount"]) { + return CliqueStatusNoCloudKitAccount; + } else if([str isEqualToString: @"CliqueStatusError"]) { + return CliqueStatusError; + } + + return CliqueStatusError; +} + + +@implementation OTConfigurationContext +- (OTControl* _Nullable)makeOTControl:(NSError**)error +{ +#if OCTAGON + if (self.otControl) { + return self.otControl; + } + return [OTControl controlObject:true error:error]; +#else + return nil; +#endif +} +@end + +@implementation OTBottleIDs +@end + +@implementation OTOperationConfiguration + +- (instancetype)init { + if ((self = [super init]) == nil) { + return nil; + } + _timeoutWaitForCKAccount = 10 * NSEC_PER_SEC; + _qualityOfService = NSQualityOfServiceDefault; + _discretionaryNetwork = NO; + _useCachedAccountStatus = NO; + return self; +} + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (void)encodeWithCoder:(nonnull NSCoder *)coder { + [coder encodeObject:@(_timeoutWaitForCKAccount) forKey:@"timeoutWaitForCKAccount"]; + [coder encodeObject:@(_qualityOfService) forKey:@"qualityOfService"]; + [coder encodeObject:@(_discretionaryNetwork) forKey:@"discretionaryNetwork"]; + [coder encodeObject:@(_useCachedAccountStatus) forKey:@"useCachedAccountStatus"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)coder { + _timeoutWaitForCKAccount = [[coder decodeObjectOfClass:[NSNumber class] forKey:@"timeoutWaitForCKAccount"] unsignedLongLongValue]; + _qualityOfService = [[coder decodeObjectOfClass:[NSNumber class] forKey:@"qualityOfService"] integerValue]; + _discretionaryNetwork = [[coder decodeObjectOfClass:[NSNumber class] forKey:@"discretionaryNetwork"] boolValue]; + _useCachedAccountStatus = [[coder decodeObjectOfClass:[NSNumber class] forKey:@"useCachedAccountStatus"] boolValue]; + return self; +} + +@end + + +@interface OTClique () +@property (nonatomic, copy) NSString* cliqueMemberIdentifier; +@property (nonatomic, strong) OTConfigurationContext *ctx; +@property (nonatomic, strong) NSMutableDictionary *defaults; +@end + +@implementation OTClique + ++ (BOOL)platformSupportsSOS +{ + return OctagonPlatformSupportsSOS(); +} + +// defaults write com.apple.security.octagon enable -bool YES +-(BOOL)isOctagonPairingEnabled { + BOOL nsDefaults = self.defaults[OTDefaultsOctagonEnable] ? [self.defaults[OTDefaultsOctagonEnable] boolValue] : OctagonIsEnabled(); + secnotice("octagon", "pairing is %@", nsDefaults ? @"on" : @"off"); + return nsDefaults; +} + +- (void)setPairingDefault:(BOOL)defaults +{ + self.defaults[OTDefaultsOctagonEnable] = @(defaults); +} + +- (void)removePairingDefault +{ + [self.defaults removeObjectForKey:OTDefaultsOctagonEnable]; +} + +- (instancetype)initWithContextData:(OTConfigurationContext *)ctx error:(NSError * __autoreleasing *)error +{ +#if OCTAGON + self = [super init]; + if(self){ + _ctx = [[OTConfigurationContext alloc]init]; + _ctx.context = ctx.context ?: OTDefaultContext; + _ctx.dsid = [ctx.dsid copy]; + _ctx.altDSID = [ctx.altDSID copy]; + _ctx.analytics = ctx.analytics; + _ctx.otControl = ctx.otControl; + + self.defaults = [NSMutableDictionary dictionary]; + } + return self; +#else + NSAssert(false, @"OTClique is not implemented on this platform"); + return nil; +#endif // OCTAGON +} + +- (NSString* _Nullable)cliqueMemberIdentifier +{ +#if OCTAGON + __block NSString* retPeerID = nil; + + if(OctagonIsEnabled()) { + NSError* localError = nil; + OTControl* control = [self makeOTControl:&localError]; + if(!control) { + secerror("octagon: Failed to create OTControl: %@", localError); + return nil; + } + + [control fetchEgoPeerID:nil + context:self.ctx.context + reply:^(NSString* peerID, NSError* error) { + if(error) { + secerror("octagon: Failed to fetch octagon peer ID: %@", error); + } + retPeerID = peerID; + }]; + secnotice("clique", "cliqueMemberIdentifier(octagon) received %@", retPeerID); + } + + if(OctagonPlatformSupportsSOS()) { + CFErrorRef error = NULL; + SOSPeerInfoRef me = SOSCCCopyMyPeerInfo(&error); + retPeerID = (NSString*)CFBridgingRelease(CFRetainSafe(SOSPeerInfoGetPeerID(me))); + CFReleaseNull(me); + } + + secnotice("clique", "cliqueMemberIdentifier complete: %@", retPeerID); + return retPeerID; +#else + return nil; +#endif +} + +#if OCTAGON +- (OTControl* _Nullable)makeOTControl:(NSError**)error +{ + return [self.ctx makeOTControl:error]; +} + +- (BOOL)establish:(NSError**)error +{ + secnotice("clique-establish", "establish started"); + + OTControl* control = [self makeOTControl:error]; + if(!control) { + return false; + } + + __block BOOL success = NO; + __block NSError* localError = nil; + //only establish + [control establish:nil context:self.ctx.context altDSID:self.ctx.altDSID reply:^(NSError * _Nullable operationError) { + + if(operationError) { + secnotice("clique-establish", "reenact establish returned an error: %@", operationError); + } + success = !!operationError; + localError = operationError; + }]; + + if(localError && error) { + *error = localError; + } + secnotice("clique-establish", "establish complete: %@", success ? @"YES" : @"NO"); + + return success; +} + +- (BOOL)resetAndEstablish:(NSError**)error +{ + secnotice("clique-resetandestablish", "resetAndEstablish started"); + + OTControl* control = [self makeOTControl:error]; + + if(!control) { + return false; + } + + __block BOOL success = NO; + __block NSError* localError = nil; + [control resetAndEstablish:nil context:self.ctx.context altDSID:self.ctx.altDSID reply:^(NSError * _Nullable operationError) { + + if(operationError) { + secnotice("clique-resetandestablish", "resetAndEstablish returned an error: %@", operationError); + } + success = !!operationError; + localError = operationError; + }]; + + if(localError && error) { + *error = localError; + } + + secnotice("clique-resetandestablish", "establish complete: %@", success ? @"YES" : @"NO"); + + return success; +} +#endif // OCTAGON + ++ (OTClique*)newFriendsWithContextData:(OTConfigurationContext*)data error:(NSError * __autoreleasing *)error +{ +#if OCTAGON + secnotice("clique-newfriends", "makeNewFriends invoked using context: %@, dsid: %@", data.context, data.dsid); + bool result = false; + + OTClique* clique = [[OTClique alloc] initWithContextData:data error:error]; + + if(OctagonIsEnabled()) { + NSError* localError = nil; + [clique resetAndEstablish:&localError]; + + if(localError) { + secnotice("clique-newfriends", "account reset failed: %@", localError); + if(error) { + *error = localError; + } + return nil; + } else { + secnotice("clique-newfriends", "Octagon account reset succeeded"); + } + } + + if(OctagonPlatformSupportsSOS()) { + CFErrorRef resetError = NULL; + NSData* analyticsData = nil; + if(data.analytics) { + NSError* encodingError = nil; + analyticsData = [NSKeyedArchiver archivedDataWithRootObject:data.analytics requiringSecureCoding:YES error:&encodingError]; + + if(encodingError) { + secnotice("clique-newfriends", "newFriendsWithContextData: unable to serialize analytics: %@", encodingError); + } + } + + if(analyticsData) { + result = SOSCCResetToEmptyWithAnalytics((__bridge CFDataRef)analyticsData, &resetError); + } else { + result = SOSCCResetToEmpty(&resetError); + } + + if(!result || resetError){ + secnotice("clique-newfriends", "newFriendsWithContextData: resetToOffering failed: %@", resetError); + if(error) { + *error = CFBridgingRelease(resetError); + } + return nil; + } + secnotice("clique-newfriends", "newFriendsWithContextData: reset the SOS circle"); + } else { + secnotice("clique-newfriends", "newFriendsWithContextData: SOS disabled on this platform"); + } + secnotice("clique-newfriends", "makeNewFriends complete"); + + return clique; + +#else // !OCTAGON + if (error) + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]; + return NULL; +#endif +} + ++ (OTClique* _Nullable)performEscrowRecoveryWithContextData:(OTConfigurationContext*)data + escrowArguments:(NSDictionary*)sbdRecoveryArguments + error:(NSError**)error +{ +#if OCTAGON + secnotice("clique-recovery", "attempting an escrow recovery for context:%@, altdsid:%@", data.context, data.altDSID); + + id sb = data.sbd ?: [[getSecureBackupClass() alloc] init]; + + NSDictionary* recoveredInformation = nil; + NSError* recoverError = [sb recoverWithInfo:sbdRecoveryArguments results:&recoveredInformation]; + + if(recoverError) { + secnotice("clique-recovery", "sbd escrow recovery failed: %@", recoverError); + if(OctagonPlatformSupportsSOS()) { + if(recoverError.code == 17 /* kSecureBackupRestoringLegacyBackupKeychainError */ && [recoverError.domain isEqualToString:getkSecureBackupErrorDomain()]) { /* XXX */ + secnotice("clique-recovery", "Can't restore legacy backup with no keybag. Resetting SOS to offering"); + CFErrorRef blowItAwayError = NULL; + bool successfulReset = SOSCCResetToOffering(&blowItAwayError); + if(!successfulReset || blowItAwayError) { + secerror("clique-recovery: failed to reset to offering:%@", blowItAwayError); + } else { + secnotice("clique-recovery", "resetting SOS circle successful"); + } + } else { + if(error) { + *error = recoverError; + } + return nil; + } + } else { + if(error){ + *error = recoverError; + } + return nil; + } + } + + NSError* localError = nil; + OTClique* clique = [[OTClique alloc] initWithContextData:data + error:&localError]; + + if(!clique || localError) { + secnotice("clique-recovery", "unable to create otclique: %@", localError); + if(error) { + *error = localError; + } + return nil; + } + + OTControl* control = [clique makeOTControl:&localError]; + if (!control) { + secnotice("clique-recovery", "unable to create otcontrol: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + + NSString *bottleID = recoveredInformation[@"bottleID"]; + NSString *isValid = recoveredInformation[@"bottleValid"]; + NSData *bottledPeerEntropy = recoveredInformation[@"EscrowServiceEscrowData"][@"BottledPeerEntropy"]; + bool shouldResetOctagon = false; + + if(bottledPeerEntropy && bottleID && [isValid isEqualToString:@"valid"]){ + secnotice("clique-recovery", "recovering from bottle: %@", bottleID); + __block NSError* restoreBottleError = nil; + + //restore bottle! + [control restore:OTCKContainerName + contextID:data.context + bottleSalt:data.altDSID + entropy:bottledPeerEntropy + bottleID:bottleID + reply:^(NSError * _Nullable restoreError) { + if(restoreError) { + secnotice("clique-recovery", "restore bottle errored: %@", restoreError); + } else { + secnotice("clique-recovery", "restoring bottle succeeded"); + } + restoreBottleError = restoreError; + }]; + + if(restoreBottleError) { + if(error){ + *error = restoreBottleError; + } + return nil; + } + } else { + shouldResetOctagon = true; + } + + if(OctagonPlatformSupportsSOS()) { + secnotice("clique-recovery", "attempting joinAfterRestore"); + [clique joinAfterRestore:&localError]; + secnotice("clique-recovery", "joinAfterRestore: %@", localError); + } + + if(shouldResetOctagon) { + secnotice("clique-recovery", "bottle %@ is not valid, resetting octagon", bottleID); + NSError* resetError = nil; + [clique resetAndEstablish:&resetError]; + if(resetError) { + secnotice("clique-recovery", "failed to reset octagon: %@", resetError); + } else{ + secnotice("clique-recovery", "reset octagon succeeded"); + } + } + + secnotice("clique-recovery", "recovery complete: %@", clique); + + return clique; +#else + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]; + } + return NULL; +#endif +} + + +- (KCPairingChannel *)setupPairingChannelAsInitiator:(KCPairingChannelContext *)ctx +{ +#if OCTAGON + return [getKCPairingChannelClass() pairingChannelInitiator:ctx]; +#else + return NULL; +#endif +} + +- (KCPairingChannel * _Nullable)setupPairingChannelAsInitator:(KCPairingChannelContext *)ctx error:(NSError * __autoreleasing *)error +{ + if (error) { + *error = nil; + } + return [self setupPairingChannelAsInitiator:ctx]; +} + +- (KCPairingChannel *)setupPairingChannelAsAcceptor:(KCPairingChannelContext *)ctx +{ +#if OCTAGON + return [getKCPairingChannelClass() pairingChannelAcceptor:ctx]; +#else + return NULL; +#endif +} + +- (KCPairingChannel * _Nullable)setupPairingChannelAsAcceptor:(KCPairingChannelContext *)ctx error:(NSError * __autoreleasing *)error +{ + if (error) { + *error = nil; + } + + return [self setupPairingChannelAsAcceptor:ctx]; +} + + +- (CliqueStatus)_fetchCliqueStatus:(OTOperationConfiguration *)configuration error:(NSError * __autoreleasing *)error +{ +#if OCTAGON + __block CliqueStatus sosStatus = CliqueStatusError; + __block CliqueStatus octagonStatus = CliqueStatusError; + + // Octagon is supreme. + + if(OctagonIsEnabled()) { + OTControl* control = [self makeOTControl:error]; + if(!control) { + secnotice("clique-status", "cliqueStatus noOTControl"); + return CliqueStatusError; + } + + __block NSError* localError = nil; + [control fetchCliqueStatus:nil context:self.ctx.context configuration:configuration reply:^(CliqueStatus cliqueStatus, NSError * _Nullable fetchError) { + if(fetchError){ + octagonStatus = CliqueStatusError; + localError = fetchError; + secnotice("clique-status", "octagon clique status errored: %@", fetchError); + } else { + octagonStatus = cliqueStatus; + } + }]; + + if(OctagonAuthoritativeTrustIsEnabled() || !OctagonPlatformSupportsSOS()) { + secnotice("clique-status", "cliqueStatus(%{public}scached)(context:%@, altDSID:%@) returning %@ (error: %@)", + configuration.useCachedAccountStatus ? "" : "non-", + self.ctx.context, self.ctx.altDSID, + OTCliqueStatusToString(octagonStatus), localError); + if (localError && error) { + *error = localError; + } + return octagonStatus; + } + } + + if(OctagonPlatformSupportsSOS()) { + CFErrorRef circleStatusError = NULL; + sosStatus = kSOSCCError; + if(configuration.useCachedAccountStatus){ + sosStatus = SOSCCThisDeviceIsInCircle(&circleStatusError); + } else { + sosStatus = SOSCCThisDeviceIsInCircleNonCached(&circleStatusError); + } + secnotice("clique-status", "sos clique status is %d (%@)", (int)sosStatus, circleStatusError); + + if (error) { + *error = (NSError*)CFBridgingRelease(circleStatusError); + } else { + CFBridgingRelease(circleStatusError); + } + } + secnotice("clique-status", "cliqueStatus(%{public}scached)(context:%@, altDSID:%@) complete: %@", + configuration.useCachedAccountStatus ? "" : "non-", + self.ctx.context, self.ctx.altDSID, + OTCliqueStatusToString(octagonStatus)); + return octagonStatus; +#else // !OCTAGON + if(error){ + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]; + } + return (CliqueStatus)kSOSCCError; +#endif +} + +// Don't change rules for CoreCDP, and preserve legacy behavior for now +// preserve old behavior until CoreCDP can move to -fetchCliqueStatus:error: +#define LEGACY_WAITING_BEHAVIOR (TARGET_OS_OSX || TARGET_OS_IOS) + +- (CliqueStatus)fetchCliqueStatus:(OTOperationConfiguration *)configuration error:(NSError * __autoreleasing * _Nonnull)error +{ + return [self _fetchCliqueStatus:configuration error:error]; +} + +- (CliqueStatus)fetchCliqueStatus:(NSError * __autoreleasing *)error +{ + OTOperationConfiguration *configuration = [[OTOperationConfiguration alloc] init]; +#if LEGACY_WAITING_BEHAVIOR + configuration.timeoutWaitForCKAccount = 0; +#endif + return [self _fetchCliqueStatus:configuration error:error]; +} + +- (CliqueStatus)cachedCliqueStatus:(BOOL)usedCached error:(NSError * __autoreleasing *)error +{ + OTOperationConfiguration *configuration = [[OTOperationConfiguration alloc] init]; +#if LEGACY_WAITING_BEHAVIOR + configuration.timeoutWaitForCKAccount = 0; +#endif + if (usedCached) { + configuration.useCachedAccountStatus = YES; + } + return [self _fetchCliqueStatus:configuration error:error]; +} + + +- (BOOL)removeFriendsInClique:(NSArray*)friendIdentifiers error:(NSError * __autoreleasing *)error +{ +#if OCTAGON + secnotice("clique-removefriends", "removeFriendsInClique invoked using context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + + // Annoying: we must sort friendIdentifiers into octagon/sos lists. + NSMutableArray* octagonIdentifiers = [NSMutableArray array]; + NSMutableArray* sosIdentifiers = [NSMutableArray array]; + + for(NSString* friendIdentifier in friendIdentifiers) { + if([friendIdentifier hasPrefix:@"SHA256:"]) { + [octagonIdentifiers addObject: friendIdentifier]; + } else { + [sosIdentifiers addObject: friendIdentifier]; + } + } + + // Ensure that we don't have any peers on the wrong platform + if(!OctagonIsEnabled() && octagonIdentifiers.count > 0) { + NSError *localError = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + userInfo:@{NSLocalizedDescriptionKey: @"Octagon is disabled; can't distrust any Octagon peers"}]; + secnotice("clique-removefriends", "removeFriendsInClique failed:%@", localError); + if(error) { + *error = localError; + } + return NO; + } + + if(!OctagonPlatformSupportsSOS() && sosIdentifiers.count > 0) { + NSError *localError = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + userInfo:@{NSLocalizedDescriptionKey: @"SOS is not available on this platform; can't distrust any SOS peers"}]; + secnotice("clique-removefriends", "removeFriendsInClique failed:%@", localError); + if(error) { + *error = localError; + } + return NO; + } + + + __block NSError* localError = nil; + bool result = true; + + if(OctagonIsEnabled() && octagonIdentifiers.count > 0) { + OTControl* control = [self makeOTControl:error]; + if(!control) { + return NO; + } + + secnotice("clique-removefriends", "octagon: removing octagon friends: %@", octagonIdentifiers); + + [control removeFriendsInClique:nil + context:self.ctx.context + peerIDs:octagonIdentifiers + reply:^(NSError* replyError) { + if(replyError) { + secnotice("clique-removefriends", "removeFriendsInClique failed: unable to remove friends: %@", replyError); + localError = replyError; + } else { + secnotice("clique-removefriends", "octagon: friends removed: %@", octagonIdentifiers); + } + }]; + } + + if(OctagonPlatformSupportsSOS() && sosIdentifiers.count > 0) { + CFErrorRef removeFriendError = NULL; + NSData* analyticsData = nil; + + secnotice("clique-removefriends", "removing sos friends: %@", sosIdentifiers); + + if(self.ctx.analytics){ + NSError* encodingError = nil; + analyticsData = [NSKeyedArchiver archivedDataWithRootObject:self.ctx.analytics requiringSecureCoding:YES error:&encodingError]; + } + + if(analyticsData) { + result = SOSCCRemovePeersFromCircleWithAnalytics((__bridge CFArrayRef)friendIdentifiers, (__bridge CFDataRef)analyticsData, &removeFriendError); + } else { + result = SOSCCRemovePeersFromCircle((__bridge CFArrayRef)friendIdentifiers, &removeFriendError); + } + + if(removeFriendError) { + secnotice("clique-removefriends", "removeFriendsInClique failed: unable to remove friends: %@", removeFriendError); + localError = CFBridgingRelease(removeFriendError); + } + } + + if(error && localError) { + *error = localError; + } + secnotice("clique-removefriends", "removeFriendsInClique complete: %d", result); + + return result && localError == nil; +#else // !OCTAGON + return NO; +#endif +} + +- (BOOL)leaveClique:(NSError * __autoreleasing *)error +{ +#if OCTAGON + secnotice("clique-leaveClique", "leaveClique invoked using context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef removeThisDeviceError = NULL; + bool result = false; + + if(OctagonIsEnabled()) { + OTControl* control = [self makeOTControl:error]; + if(!control) { + return false; + } + + __block NSError* localError = nil; + [control leaveClique:nil context:self.ctx.context reply:^(NSError * _Nullable leaveError) { + if(leaveError) { + secnotice("clique-leaveClique", "leaveClique errored: %@", leaveError); + localError = leaveError; + } else { + secnotice("clique-leaveClique", "leaveClique success."); + } + }]; + + if(error) { + *error = localError; + } + result = !localError; + } + + if(OctagonPlatformSupportsSOS()) { + NSData* analyticsData = nil; + + if(self.ctx.analytics) { + NSError* encodingError = nil; + analyticsData = [NSKeyedArchiver archivedDataWithRootObject:self.ctx.analytics requiringSecureCoding:YES error:&encodingError]; + if(!analyticsData){ + secnotice("clique-leaveClique", "leaveClique unable to archive analytics object: %@", encodingError); + } + } + + if(analyticsData) { + result &= SOSCCRemoveThisDeviceFromCircleWithAnalytics((__bridge CFDataRef)analyticsData, &removeThisDeviceError); + } else { + result &= SOSCCRemoveThisDeviceFromCircle(&removeThisDeviceError); + } + + if (error) { + *error = (NSError*)CFBridgingRelease(removeThisDeviceError); + } else { + CFBridgingRelease(removeThisDeviceError); + } + } + secnotice("clique-leaveClique", "leaveClique complete: %d", result); + + return result ? YES : NO; +#else // !OCTAGON + return NO; +#endif +} + +- (NSDictionary* _Nullable)peerDeviceNamesByPeerID:(NSError * __autoreleasing *)error +{ +#if OCTAGON + secnotice("clique", "peerDeviceNamesByPeerID invoked using context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + + NSMutableDictionary* retPeers = [NSMutableDictionary dictionary]; + + if(OctagonIsEnabled()) { + OTControl* control = [self makeOTControl:error]; + if(!control) { + return nil; + } + + __block NSError* localError = nil; + __block NSDictionary* localPeers = nil; + + [control peerDeviceNamesByPeerID:nil context:OTDefaultContext reply:^(NSDictionary* peers, NSError* controlError) { + if(controlError) { + secnotice("clique", "peerDeviceNamesByPeerID errored: %@", controlError); + } else { + secnotice("clique", "peerDeviceNamesByPeerID succeeded: %@", peers); + } + localError = controlError; + localPeers = peers; + }]; + + if(error && localError) { + *error = localError; + } + if(localError) { + return nil; + } + [retPeers addEntriesFromDictionary:localPeers]; + secnotice("clique", "Received %lu Octagon peers", (unsigned long)localPeers.count); + } + + if(OctagonPlatformSupportsSOS()) { + CFErrorRef peerErrorRef = NULL; + NSMutableDictionary* peerMapping = [NSMutableDictionary dictionary]; + NSArray* arrayOfPeerRefs = CFBridgingRelease(SOSCCCopyPeerPeerInfo(&peerErrorRef)); + if(arrayOfPeerRefs){ + [arrayOfPeerRefs enumerateObjectsUsingBlock:^(id peerRef, NSUInteger idx, BOOL * stop) { + SOSPeerInfoRef peer = (__bridge SOSPeerInfoRef)peerRef; + if(peer){ + [peerMapping setObject:(__bridge NSString*)SOSPeerInfoGetPeerName(peer) forKey:(__bridge NSString*)SOSPeerInfoGetPeerID(peer)]; + } + }]; + } + if (error) { + *error = (NSError*)CFBridgingRelease(peerErrorRef); + } else { + CFBridgingRelease(peerErrorRef); + } + + [retPeers addEntriesFromDictionary:peerMapping]; + secnotice("clique", "Received %lu SOS peers", (unsigned long)peerMapping.count); + } + + return retPeers; +#else // !OCTAGON + return NULL; +#endif +} + +- (BOOL)joinAfterRestore:(NSError * __autoreleasing *)error +{ + secnotice("clique-recovery", "joinAfterRestore for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef restoreError = NULL; + + bool res = SOSCCRequestToJoinCircleAfterRestore(&restoreError); + if (error) { + *error = (NSError*)CFBridgingRelease(restoreError); + } else { + CFBridgingRelease(restoreError); + } + secnotice("clique-recovery", "joinAfterRestore complete: %d %@", res, error ? *error : @"no error pointer provided"); + return res; +} + +- (BOOL)safariPasswordSyncingEnabled:(NSError **)error +{ + secnotice("clique-safari", "safariPasswordSyncingEnabled for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + + CFErrorRef viewErrorRef = NULL; + + SOSViewResultCode result = SOSCCView(kSOSViewAutofillPasswords, kSOSCCViewQuery, &viewErrorRef); + + BOOL viewMember = result == kSOSCCViewMember; + if (error) { + *error = (NSError*)CFBridgingRelease(viewErrorRef); + } else { + CFBridgingRelease(viewErrorRef); + } + + secnotice("clique-safari", "safariPasswordSyncingEnabled complete: %@", viewMember ? @"YES" : @"NO"); + + return viewMember; +} + +- (BOOL)isLastFriend:(NSError **)error +{ + secnotice("clique-isLastFriend", "is last friend"); + return NO; +} + +- (BOOL)waitForInitialSync:(NSError *__autoreleasing*)error +{ + secnotice("clique-legacy", "waitForInitialSync for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef initialSyncErrorRef = NULL; + bool result = false; + if(self.ctx.analytics){ + NSError* encodingError = nil; + NSData* analyticsData = [NSKeyedArchiver archivedDataWithRootObject:self.ctx.analytics requiringSecureCoding:YES error:&encodingError]; + if(!encodingError && analyticsData){ + result = SOSCCWaitForInitialSyncWithAnalytics((__bridge CFDataRef)analyticsData, &initialSyncErrorRef); + }else{ + result = SOSCCWaitForInitialSync(&initialSyncErrorRef); + } + }else{ + result = SOSCCWaitForInitialSync(&initialSyncErrorRef); + } + + BOOL initialSyncResult = (result == true); + if (error) { + *error = (NSError*)CFBridgingRelease(initialSyncErrorRef); + } else { + CFBridgingRelease(initialSyncErrorRef); + } + secnotice("clique-legacy", "waitForInitialSync waited: %d %@", initialSyncResult, error ? *error : @"no error pointer provided"); + return initialSyncResult; +} + +- (NSArray*)copyViewUnawarePeerInfo:(NSError *__autoreleasing*)error +{ + secnotice("clique-legacy", "copyViewUnawarePeerInfo for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef copyViewUnawarePeerInfoErrorRef = NULL; + CFArrayRef peerListRef = SOSCCCopyViewUnawarePeerInfo(©ViewUnawarePeerInfoErrorRef); + + NSArray* peerList = (peerListRef ? (NSArray*)(CFBridgingRelease(peerListRef)) : nil); + if (error) { + *error = (NSError*)CFBridgingRelease(copyViewUnawarePeerInfoErrorRef); + } else { + CFBridgingRelease(copyViewUnawarePeerInfoErrorRef); + } + return peerList; +} + +- (BOOL)viewSet:(NSSet*)enabledViews disabledViews:(NSSet*)disabledViews +{ + secnotice("clique-legacy", "viewSet for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + bool result = false; + if(self.ctx.analytics){ + NSError* encodingError = nil; + NSData* analyticsData = [NSKeyedArchiver archivedDataWithRootObject:self.ctx.analytics requiringSecureCoding:YES error:&encodingError]; + if(!encodingError && analyticsData){ + result = SOSCCViewSetWithAnalytics((__bridge CFSetRef)enabledViews, (__bridge CFSetRef)disabledViews, (__bridge CFDataRef)analyticsData); + }else{ + result = SOSCCViewSet((__bridge CFSetRef)enabledViews, (__bridge CFSetRef)disabledViews); + } + }else{ + result = SOSCCViewSet((__bridge CFSetRef)enabledViews, (__bridge CFSetRef)disabledViews); + } + + BOOL viewSetResult = (result == true); + return viewSetResult; +} + +- (BOOL)setUserCredentialsAndDSID:(NSString*)userLabel + password:(NSData*)userPassword + error:(NSError *__autoreleasing*)error +{ + secnotice("clique-legacy", "setUserCredentialsAndDSID for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef setCredentialsErrorRef = NULL; + bool result = false; + if(self.ctx.analytics){ + NSError* encodingError = nil; + NSData* analyticsData = [NSKeyedArchiver archivedDataWithRootObject:self.ctx.analytics requiringSecureCoding:YES error:&encodingError]; + if(!encodingError && analyticsData){ + result = SOSCCSetUserCredentialsAndDSIDWithAnalytics((__bridge CFStringRef)userLabel, + (__bridge CFDataRef)userPassword, + (__bridge CFStringRef)self.ctx.dsid, + (__bridge CFDataRef)analyticsData, + &setCredentialsErrorRef); + }else{ + result = SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef)userLabel, + (__bridge CFDataRef)userPassword, + (__bridge CFStringRef)self.ctx.dsid, + &setCredentialsErrorRef); + } + }else{ + result = SOSCCSetUserCredentialsAndDSID((__bridge CFStringRef)userLabel, + (__bridge CFDataRef)userPassword, + (__bridge CFStringRef)self.ctx.dsid, + &setCredentialsErrorRef); + } + + BOOL setCredentialsResult = (result == true); + if (error) { + *error = (NSError*)CFBridgingRelease(setCredentialsErrorRef); + } else { + CFBridgingRelease(setCredentialsErrorRef); + } + secnotice("clique-legacy", "setUserCredentialsAndDSID results: %d %@", setCredentialsResult, setCredentialsErrorRef); + return setCredentialsResult; +} + +- (BOOL)tryUserCredentialsAndDSID:(NSString*)userLabel + password:(NSData*)userPassword + error:(NSError *__autoreleasing*)error +{ + secnotice("clique-legacy", "tryUserCredentialsAndDSID for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef tryCredentialsErrorRef = NULL; + bool result = SOSCCTryUserCredentialsAndDSID((__bridge CFStringRef)userLabel, + (__bridge CFDataRef)userPassword, + (__bridge CFStringRef)self.ctx.dsid, + &tryCredentialsErrorRef); + + BOOL tryCredentialsResult = (result == true); + if (error) { + *error = (NSError*)CFBridgingRelease(tryCredentialsErrorRef); + } else { + CFBridgingRelease(tryCredentialsErrorRef); + } + secnotice("clique-legacy", "tryUserCredentialsAndDSID results: %d %@", tryCredentialsResult, tryCredentialsErrorRef); + return tryCredentialsResult; + +} + +- (NSArray*)copyPeerPeerInfo:(NSError *__autoreleasing*)error +{ + secnotice("clique-legacy", "copyPeerPeerInfo for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef copyPeerErrorRef = NULL; + CFArrayRef result = SOSCCCopyPeerPeerInfo(©PeerErrorRef); + + NSArray* peerList = (result ? (NSArray*)(CFBridgingRelease(result)) : nil); + + if (error) { + *error = (NSError*)CFBridgingRelease(copyPeerErrorRef); + } else { + CFBridgingRelease(copyPeerErrorRef); + } + secnotice("clique-legacy", "copyPeerPeerInfo results: %@", peerList); + + return peerList; + +} + +- (BOOL)peersHaveViewsEnabled:(NSArray*)viewNames error:(NSError *__autoreleasing*)error +{ + secnotice("clique-legacy", "peersHaveViewsEnabled for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + CFErrorRef viewsEnabledErrorRef = NULL; + BOOL viewsEnabledResult = NO; + + CFBooleanRef result = SOSCCPeersHaveViewsEnabled((__bridge CFArrayRef)viewNames, &viewsEnabledErrorRef); + if(result){ + viewsEnabledResult = CFBooleanGetValue(result); + } + if (error) { + *error = (NSError*)CFBridgingRelease(viewsEnabledErrorRef); + } else { + CFBridgingRelease(viewsEnabledErrorRef); + } + secnotice("clique-legacy", "peersHaveViewsEnabled results: %@", viewsEnabledResult ? @"YES" : @"NO"); + + return viewsEnabledResult; +} + +- (BOOL)requestToJoinCircle:(NSError *__autoreleasing*)error +{ + bool result = false; + CFErrorRef joinErrorRef = NULL; + +#if OCTAGON + secnotice("clique-legacy", "requestToJoinCircle for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + + if(OctagonIsEnabled()) { + NSError* localError = nil; + [self resetAndEstablish:&localError]; + + if(localError) { + secnotice("clique-legacy", "account reset failed: %@", localError); + if(error) { + *error = localError; + } + return NO; + } else { + secnotice("clique-legacy", "account reset succeeded"); + } + + // If we didn't early-exit, and we aren't going to invoke SOS below, we succeeded. + if(!OctagonPlatformSupportsSOS()) { + secnotice("clique-legacy", "sos requestToJoinCircle results: %d %@", result, joinErrorRef); + return YES; + } + } +#endif // OCTAGON + + if(OctagonPlatformSupportsSOS()) { + NSData* analyticsData = nil; + if(self.ctx.analytics){ + NSError* encodingError = nil; + analyticsData = [NSKeyedArchiver archivedDataWithRootObject:self.ctx.analytics requiringSecureCoding:YES error:&encodingError]; + } + + if(analyticsData){ + result = SOSCCRequestToJoinCircleWithAnalytics((__bridge CFDataRef)analyticsData, &joinErrorRef); + } else { + result = SOSCCRequestToJoinCircle(&joinErrorRef); + } + + secnotice("clique-legacy", "sos requestToJoinCircle complete: %d %@", result, joinErrorRef); + } + + if (error) { + *error = (NSError*)CFBridgingRelease(joinErrorRef); + } else { + CFBridgingRelease(joinErrorRef); + } + return result ? YES : NO; +} + +- (BOOL)accountUserKeyAvailable +{ + secnotice("clique-legacy", "accountUserKeyAvailable for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + BOOL canAuthenticate = (BOOL)SOSCCCanAuthenticate(NULL); + if (canAuthenticate == NO) { + secnotice("clique-legacy", "Security requires credentials..."); + } + return canAuthenticate; +} + +// MARK: SBD interfaces ++ (OTBottleIDs* _Nullable)findOptimalBottleIDsWithContextData:(OTConfigurationContext*)data + error:(NSError**)error +{ +#if OCTAGON + secnotice("clique-findbottle", "finding optimal bottles for context:%@, altdsid:%@", data.context, data.altDSID); + + if(OctagonIsEnabled()) { + __block NSError* localError = nil; + __block NSArray* localViableBottleIDs = nil; + __block NSArray* localPartiallyViableBottleIDs = nil; + + OTControl *control = [data makeOTControl:&localError]; + if (!control) { + secnotice("clique-findbottle", "unable to create otcontrol: %@", localError); + if (error) { + *error = localError; + } + return nil; + } + [control fetchAllViableBottles:OTCKContainerName + context:data.context + reply:^(NSArray * _Nullable sortedBottleIDs, + NSArray * _Nullable sortedPartialBottleIDs, + NSError * _Nullable fetchError) { + if(fetchError) { + secnotice("clique-findbottle", "findOptimalBottleIDsWithContextData errored: %@", fetchError); + } else { + secnotice("clique-findbottle", "findOptimalBottleIDsWithContextData succeeded: %@, %@", sortedBottleIDs, sortedPartialBottleIDs); + } + localError = fetchError; + localViableBottleIDs = sortedBottleIDs; + localPartiallyViableBottleIDs = sortedPartialBottleIDs; + }]; + + if(error && localError) { + *error = localError; + } + OTBottleIDs* bottleIDs = [[OTBottleIDs alloc] init]; + bottleIDs.preferredBottleIDs = localViableBottleIDs; + bottleIDs.partialRecoveryBottleIDs = localPartiallyViableBottleIDs; + + secnotice("clique-findbottle", "findOptimalBottleIDsWithContextData complete"); + + return bottleIDs; + } else { + // With octagon off, fail with 'unimplemented' + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + userInfo:@{NSLocalizedDescriptionKey: @"optimal bottle IDs unimplemented"}]; + } + return nil; + } +#else // !OCTAGON + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]; + } + return NULL; +#endif +} + ++ (OTClique* _Nullable)recoverWithContextData:(OTConfigurationContext*)data + bottleID:(NSString*)bottleID + escrowedEntropy:(NSData*)entropy + error:(NSError**)error +{ +#if OCTAGON + secnotice("octagon", "replaced by performEscrowRecoveryWithContextData:escrowArguments:error: remove call"); + return nil; +#else // !OCTAGON + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]; + } + return NULL; +#endif +} + +// used by sbd to fill in the escrow record +// TODO: what extra entitlement do you need to call this? +- (void)fetchEscrowContents:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ +#if OCTAGON + secnotice("clique-fetchescrow", "fetching entropy for bottling for context:%@, altdsid:%@", self.ctx.context, self.ctx.altDSID); + + if(OctagonIsEnabled()) { + NSError* controlError = nil; + OTControl* control = [self makeOTControl:&controlError]; + if (!control) { + reply(nil, nil, nil, controlError); + return; + } + [control fetchEscrowContents:OTCKContainerName + contextID:self.ctx.context + reply:^(NSData * _Nullable entropy, + NSString * _Nullable bottleID, + NSData * _Nullable signingPublicKey, + NSError * _Nullable error) { + if(error){ + secnotice("clique-fetchescrow", "fetchEscrowContents errored: %@", error); + } else{ + secnotice("clique-fetchescrow","fetchEscrowContents succeeded"); + } + reply (entropy, bottleID, signingPublicKey, error); + }]; + + return; + } else { + // With octagon off, fail with 'unimplemented' + reply(nil, nil, nil, [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + userInfo:@{NSLocalizedDescriptionKey: @"fetchEscrowRecordContents unimplemented"}]); + } +#else // !OCTAGON + reply(nil, nil, nil, [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]); +#endif +} + ++ (void)setNewRecoveryKeyWithData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey reply:(nonnull void (^)(SecRecoveryKey *rk, NSError *error))reply +{ +#if OCTAGON + secnotice("octagon-setrecoverykey", "setNewRecoveryKeyWithData invoked for context: %@", ctx.context); + //set the recovery key for SOS + NSError* createRecoveryKeyError = nil; + NSMutableDictionary *userInfo = [NSMutableDictionary new]; + NSError* retError = nil; + + SecRecoveryKey *rk = SecRKCreateRecoveryKeyWithError(recoveryKey, &createRecoveryKeyError); + if (rk == nil) { + secerror("octagon-setrecoverykey, SecRKCreateRecoveryKeyWithError() failed: %@", createRecoveryKeyError); + userInfo[NSLocalizedDescriptionKey] = @"SecRKCreateRecoveryKeyWithError() failed"; + userInfo[NSUnderlyingErrorKey] = createRecoveryKeyError; + retError = [NSError errorWithDomain:getkSecureBackupErrorDomain() code:kSecureBackupInternalError userInfo:userInfo]; + reply(nil, retError); + return; + } + if(OctagonPlatformSupportsSOS()) { + CFErrorRef registerError = nil; + if (!SecRKRegisterBackupPublicKey(rk, ®isterError)) { + secerror("octagon-setrecoverykey, SecRKRegisterBackupPublicKey() failed: %@", registerError); + NSError *underlyingError = CFBridgingRelease(registerError); + userInfo[NSLocalizedDescriptionKey] = @"SecRKRegisterBackupPublicKey() failed"; + userInfo[NSUnderlyingErrorKey] = underlyingError; + retError = [NSError errorWithDomain:getkSecureBackupErrorDomain() code:kSecureBackupInternalError userInfo:userInfo]; + reply(nil,retError); + return; + } else { + secnotice("octagon-setrecoverykey", "successfully registered recovery key for SOS"); + } + } + + //set the recovery key for Octagon + if(OctagonRecoveryKeyIsEnabled()) { + NSError* controlError = nil; + OTControl* control = [ctx makeOTControl:&controlError]; + if(!control) { + secnotice("octagon-setrecoverykey", "failed to fetch OTControl object: %@", controlError); + reply(nil, controlError); + return; + } + [control createRecoveryKey:OTCKContainerName contextID:ctx.context recoveryKey:recoveryKey reply:^(NSError * createError) { + if(createError){ + secerror("octagon-setrecoverykey, failed to create octagon recovery key"); + reply(nil, createError); + return; + } else { + secnotice("octagon-setrecoverykey", "successfully set octagon recovery key"); + reply(rk, nil); + return; + } + }]; + } +#else // !OCTAGON + reply(nil, [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]); +#endif +} + ++ (void)recoverOctagonUsingData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(NSError* _Nullable error))reply +{ +#if OCTAGON + if(OctagonRecoveryKeyIsEnabled()) { + NSError* controlError = nil; + OTControl* control = [ctx makeOTControl:&controlError]; + + secnotice("clique-recoverykey", "join using recovery key"); + + if(!control) { + secnotice("clique-recoverykey", "failed to fetch OTControl object: %@", controlError); + reply(controlError); + return; + } + [control joinWithRecoveryKey:OTCKContainerName contextID:ctx.context recoveryKey:recoveryKey reply:^(NSError *joinError) { + if(joinError){ + secnotice("clique-recoverykey", "failed to join using recovery key: %@", joinError); + reply(joinError); + return; + } + secnotice("clique-recoverykey", "successfully joined using recovery key"); + reply(nil); + }]; + } + +#else // !OCTAGON + reply([NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]); +#endif +} + +- (void)performedCDPStateMachineRun:(OTCliqueCDPContextType)type + success:(BOOL)success + error:(NSError * _Nullable)error + reply:(void(^)(NSError* _Nullable error))reply +{ +#if OCTAGON + NSError* controlError = nil; + OTControl* control = [self makeOTControl:&controlError]; + if(!control) { + secnotice("clique-cdp-sm", "octagon, failed to fetch OTControl object: %@", controlError); + reply(controlError); + return; + } + + [control postCDPFollowupResult:success type:type error:error containerName:OTCKContainerName contextName:OTDefaultContext reply:^(NSError *postError) { + if(postError){ + secnotice("clique-cdp-sm", "failed to post %@ result: %@ ", type, postError); + reply(postError); + return; + } + if (success) { + secnotice("clique-cdp-sm", "posted success: %@", type); + } else { + secnotice("clique-cdp-sm", "posted error: %@: %@", type, error); + } + reply(NULL); + }]; +#else // !OCTAGON + reply([NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]); +#endif +} + +- (BOOL)waitForOctagonUpgrade:(NSError** _Nullable)error +{ +#if OCTAGON + OTControl* control = nil; + + if (!OctagonIsEnabled()) { + secnotice("clique-waitforoctagonupgrade", "cannot upgrade, octagon is not enabled"); + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:@{NSLocalizedDescriptionKey: @"Octagon is not enabled"}]; + } + return NO; + } + + NSError *controlError = nil; + control = [self makeOTControl:&controlError]; + if (!control) { + secnotice("clique-waitforoctagonupgrade", "octagon, failed to fetch OTControl object: %@", controlError); + if (error) { + *error = controlError; + } + return NO; + } + + __block BOOL ret = NO; + __block NSError* blockError = nil; + + [control waitForOctagonUpgrade:OTCKContainerName context:OTDefaultContext reply:^(NSError *postError) { + if(postError){ + secnotice("clique-waitforoctagonupgrade", "error from control: %@", postError); + blockError = postError; + ret = NO; + } else { + secnotice("clique-waitforoctagonupgrade", "successfully upgraded to octagon"); + ret = YES; + } + }]; + + if (blockError && error) { + *error = blockError; + } + + return ret; +#else // !OCTAGON + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecUnimplemented userInfo:nil]; + } + return NO; +#endif +} + +- (void)performedFailureCDPStateMachineRun:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + reply:(void(^)(NSError* _Nullable error))reply +{ + [self performedCDPStateMachineRun:type success:NO error:error reply:reply]; +} + +- (void)performedSuccessfulCDPStateMachineRun:(OTCliqueCDPContextType)type + reply:(void(^)(NSError* _Nullable error))reply +{ + [self performedCDPStateMachineRun:type success:YES error:nil reply:reply]; +} + +@end + +#endif /* OBJC2 */ diff --git a/keychain/ot/OTCloudStore.h b/keychain/ot/OTCloudStore.h index 0670aa8b..4b6ecb29 100644 --- a/keychain/ot/OTCloudStore.h +++ b/keychain/ot/OTCloudStore.h @@ -31,16 +31,18 @@ #import "keychain/ckks/CKKSZone.h" #import "keychain/ckks/CloudKitDependencies.h" +#import "keychain/ckks/CKKSCloudKitClassDependencies.h" #import "keychain/ckks/CKKSCondition.h" #import "keychain/ckks/CKKSZoneChangeFetcher.h" #import "keychain/ckks/CKKSNotifier.h" #import "keychain/ckks/CKKSSQLDatabaseObject.h" #import "keychain/ckks/CKKSRecordHolder.h" +#import "keychain/ckks/CKKSZoneModifier.h" #import "OTBottledPeerRecord.h" NS_ASSUME_NONNULL_BEGIN -@interface OTCloudStore : CKKSZone +@interface OTCloudStore : CKKSZone @property (nonatomic, readonly) NSString* contextID; @property (nonatomic, readonly) NSString* dsid; @@ -53,17 +55,13 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype) initWithContainer:(CKContainer*) container zoneName:(NSString*)zoneName - accountTracker:(nullable CKKSCKAccountStateTracker*)tracker + accountTracker:(nullable CKKSAccountStateTracker*)accountTracker reachabilityTracker:(nullable CKKSReachabilityTracker*)reachabilityTracker localStore:(OTLocalStore*)localStore contextID:(NSString*)contextID dsid:(NSString*)dsid -fetchRecordZoneChangesOperationClass:(Class) fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:(Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass:(Class) modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:(Class) modifyRecordZonesOperationClass - apsConnectionClass:(Class) apsConnectionClass + zoneModifier:(CKKSZoneModifier*)zoneModifier + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies operationQueue:(nullable NSOperationQueue *)operationQueue; diff --git a/keychain/ot/OTCloudStore.m b/keychain/ot/OTCloudStore.m index 3abbdfcd..241b732a 100644 --- a/keychain/ot/OTCloudStore.m +++ b/keychain/ot/OTCloudStore.m @@ -27,6 +27,7 @@ #import #import +#import "keychain/ot/OTConstants.h" #import "keychain/ot/OTCloudStore.h" #import "keychain/ot/OTCloudStoreState.h" #import "keychain/ckks/CKKSZoneStateEntry.h" @@ -35,6 +36,8 @@ #import "keychain/ckks/CKKSReachabilityTracker.h" #import +#import "keychain/ckks/CKKSZoneModifier.h" + NS_ASSUME_NONNULL_BEGIN @@ -78,7 +81,6 @@ static NSString* const bottledPeerTable = @"bp"; static NSString* const octagonZoneName = @"OctagonTrustZone"; /* Octagon Cloud Kit defines */ -static NSString* OTCKContainerName = @"com.apple.security.keychain"; static NSString* OTCKZoneName = @"OctagonTrust"; static NSString* OTCKRecordName = @"bp-"; static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; @@ -94,7 +96,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; @property (nonatomic, strong) NSError* error; @end -@class CKKSAPSReceiver; +@class OctagonAPSReceiver; @interface OTCloudStore() @@ -111,17 +113,13 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; - (instancetype) initWithContainer:(CKContainer*) container zoneName:(NSString*)zoneName - accountTracker:(nullable CKKSCKAccountStateTracker*)accountTracker + accountTracker:(nullable CKKSAccountStateTracker*)accountTracker reachabilityTracker:(nullable CKKSReachabilityTracker*)reachabilityTracker localStore:(OTLocalStore*)localStore contextID:(NSString*)contextID dsid:(NSString*)dsid -fetchRecordZoneChangesOperationClass:(Class) fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:(Class)fetchRecordsOperationClass - queryOperationClass:(Class)queryOperationClass - modifySubscriptionsOperationClass:(Class) modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:(Class) modifyRecordZonesOperationClass - apsConnectionClass:(Class) apsConnectionClass + zoneModifier:(CKKSZoneModifier*)zoneModifier + cloudKitClassDependencies:(CKKSCloudKitClassDependencies*)cloudKitClassDependencies operationQueue:(nullable NSOperationQueue *)operationQueue { @@ -129,12 +127,8 @@ fetchRecordZoneChangesOperationClass:(Class zoneName:zoneName accountTracker:accountTracker reachabilityTracker:reachabilityTracker -fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass - fetchRecordsOperationClass:fetchRecordsOperationClass - queryOperationClass:queryOperationClass - modifySubscriptionsOperationClass:modifySubscriptionsOperationClass - modifyRecordZonesOperationClass:modifyRecordZonesOperationClass - apsConnectionClass:apsConnectionClass]; + zoneModifier:zoneModifier + cloudKitClassDependencies:cloudKitClassDependencies]; if(self){ if (!operationQueue) { @@ -146,7 +140,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass _dsid = [dsid copy]; _operationQueue = operationQueue; self.queue = dispatch_queue_create([[NSString stringWithFormat:@"OctagonTrustQueue.%@.zone.%@", container.containerIdentifier, zoneName] UTF8String], DISPATCH_QUEUE_SERIAL); - [self initializeZone]; + [self beginCloudKitOperation]; } return self; @@ -165,7 +159,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass CKFetchRecordZoneChangesConfiguration* options = [[CKFetchRecordZoneChangesConfiguration alloc] init]; options.previousServerChangeToken = state.changeToken; - self.fetchRecordZoneChangesOperation = [[[self.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}]; + self.fetchRecordZoneChangesOperation = [[[self.cloudKitClassDependencies.fetchRecordZoneChangesOperationClass class] alloc] initWithRecordZoneIDs:@[self.zoneID] configurationsByRecordZoneID:@{self.zoneID : options}]; self.fetchRecordZoneChangesOperation.recordChangedBlock = ^(CKRecord *record) { secinfo("octagon", "CloudKit notification: record changed(%@): %@", [record recordType], record); @@ -173,7 +167,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass if(!strongSelf) { secnotice("octagon", "received callback for released object"); - fetchOp.error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; + fetchOp.error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; @@ -257,7 +251,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass __strong __typeof(weakSelf) strongSelf = weakSelf; if(!strongSelf) { secnotice("octagon", "received callback for released object"); - fetchOp.error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; + fetchOp.error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; fetchOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerFetchRecords; return; } @@ -390,7 +384,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass if(record == nil){ secerror("octagon: failed to create cloud kit record"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"failed to create cloud kit record"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"failed to create cloud kit record"}]; } return nil; } @@ -420,6 +414,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass // Currently done during buddy. User is waiting. self.modifyRecordsOperation.configuration.automaticallyRetryNetworkFailures = NO; self.modifyRecordsOperation.configuration.discretionaryNetworkBehavior = CKOperationDiscretionaryNetworkBehaviorNonDiscretionary; + self.modifyRecordsOperation.configuration.isCloudKitSupportOperation = YES; self.modifyRecordsOperation.savePolicy = CKRecordSaveIfServerRecordUnchanged; @@ -451,7 +446,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass } if(!strongSelf) { secerror("octagon: received callback for released object"); - modifyOp.error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; + modifyOp.error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTCloudStore userInfo:@{NSLocalizedDescriptionKey: @"received callback for released object"}]; modifyOp.descriptionErrorCode = CKKSResultDescriptionPendingBottledPeerModifyRecords; [strongSelf.operationQueue addOperation:modifyOp]; return; @@ -593,7 +588,7 @@ fetchRecordZoneChangesOperationClass:fetchRecordZoneChangesOperationClass [strongSelf dispatchSync: ^bool { ckksnotice("octagon", strongSelf, "Zone setup progress: %@ %d %@ %d %@", - [CKKSCKAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus], + [CKKSAccountStateTracker stringFromAccountStatus:strongSelf.accountStatus], strongSelf.zoneCreated, strongSelf.zoneCreatedError, strongSelf.zoneSubscribed, strongSelf.zoneSubscribedError); NSError* error = nil; diff --git a/keychain/ot/OTCloudStoreState.m b/keychain/ot/OTCloudStoreState.m index ac61ea81..63b3ab74 100644 --- a/keychain/ot/OTCloudStoreState.m +++ b/keychain/ot/OTCloudStoreState.m @@ -97,7 +97,7 @@ } } -- (void) setChangeToken: (CKServerChangeToken*) token { +- (void)setChangeToken: (CKServerChangeToken*) token { self.encodedChangeToken = token ? [NSKeyedArchiver archivedDataWithRootObject:token requiringSecureCoding:YES error:nil] : nil; } @@ -136,16 +136,12 @@ }; } -+ (instancetype) fromDatabaseRow: (NSDictionary*) row { - NSISO8601DateFormatter* dateFormat = [[NSISO8601DateFormatter alloc] init]; - - return [[OTCloudStoreState alloc] initWithCKZone: row[@"ckzone"] - zoneCreated: [row[@"ckzonecreated"] boolValue] - zoneSubscribed: [row[@"ckzonesubscribed"] boolValue] - changeToken: ![row[@"changetoken"] isEqual: [NSNull null]] ? - [[NSData alloc] initWithBase64EncodedString: row[@"changetoken"] options:0] : - nil - lastFetch: [row[@"lastfetch"] isEqual: [NSNull null]] ? nil : [dateFormat dateFromString: row[@"lastfetch"]] ++ (instancetype)fromDatabaseRow:(NSDictionary*)row { + return [[OTCloudStoreState alloc] initWithCKZone:row[@"ckzone"].asString + zoneCreated:row[@"ckzonecreated"].asBOOL + zoneSubscribed:row[@"ckzonesubscribed"].asBOOL + changeToken:row[@"changetoken"].asBase64DecodedData + lastFetch:row[@"lastfetch"].asISO8601Date ]; } diff --git a/keychain/ot/OTConstants.h b/keychain/ot/OTConstants.h index 5b3010c3..3518f397 100644 --- a/keychain/ot/OTConstants.h +++ b/keychain/ot/OTConstants.h @@ -24,8 +24,43 @@ #ifndef OTConstants_h #define OTConstants_h +#include + +bool OctagonIsEnabled(void); + +#if __OBJC__ + #import extern NSString* OTDefaultContext; +extern NSString* const OctagonErrorDomain; + +/* used for defaults writes */ +extern NSString* OTDefaultsDomain; +extern NSString* OTDefaultsOctagonEnable; + +extern NSString* OTProtocolPairing; +extern NSString* OTProtocolPiggybacking; + +extern const char * OTTrustStatusChangeNotification; + + +BOOL OctagonPlatformSupportsSOS(void); + +// Used for testing. +void OctagonSetIsEnabled(BOOL value); +void OctagonSetPlatformSupportsSOS(BOOL value); + +BOOL OctagonPerformSOSUpgrade(void); +void OctagonSetSOSUpgrade(BOOL value); + +BOOL OctagonRecoveryKeyIsEnabled(void); +void OctagonRecoveryKeySetIsEnabled(BOOL value); + +BOOL OctagonAuthoritativeTrustIsEnabled(void); +void OctagonAuthoritativeTrustSetIsEnabled(BOOL value); + +#endif // __OBJC__ + #endif /* OTConstants_h */ diff --git a/keychain/ot/OTConstants.m b/keychain/ot/OTConstants.m index 5e2e40f2..4368cc5c 100644 --- a/keychain/ot/OTConstants.m +++ b/keychain/ot/OTConstants.m @@ -21,8 +21,165 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import "OTConstants.h" +#include +#if TARGET_OS_IOS +#include +#endif + +#import + +#import "keychain/ot/OTConstants.h" +#import "utilities/debugging.h" + +NSString* const OctagonErrorDomain = @"com.apple.security.octagon"; NSString* OTDefaultContext = @"defaultContext"; +NSString* OTDefaultsDomain = @"com.apple.security.octagon"; +NSString* OTDefaultsOctagonEnable = @"enable"; + +NSString* OTProtocolPairing = @"OctagonPairing"; +NSString* OTProtocolPiggybacking = @"OctagonPiggybacking"; + +const char * OTTrustStatusChangeNotification = "com.apple.security.octagon.trust-status-change"; + +// I don't recommend using this command, but it does describe the plist that will enable this feature: +// +// defaults write /System/Library/FeatureFlags/Domain/Security octagon -dict Enabled -bool YES +// +static bool OctagonEnabledOverrideSet = false; +static bool OctagonEnabledOverride = false; + +static bool OctagonRecoveryKeyEnabledOverrideSet = false; +static bool OctagonRecoveryKeyEnabledOverride = false; + +static bool OctagonAuthoritativeTrustEnabledOverrideSet = false; +static bool OctagonAuthoritativeTrustEnabledOverride = false; + +bool OctagonIsEnabled(void) +{ + if(OctagonEnabledOverrideSet) { + secnotice("octagon", "Octagon is %@ (overridden)", OctagonEnabledOverride ? @"enabled" : @"disabled"); + return OctagonEnabledOverride; + } + + static bool octagonEnabled = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + octagonEnabled = os_feature_enabled(Security, octagon); + secnotice("octagon", "Octagon is %@ (via feature flags)", octagonEnabled ? @"enabled" : @"disabled"); + }); + + return octagonEnabled; +} + +void OctagonSetIsEnabled(BOOL value) +{ + OctagonEnabledOverrideSet = true; + OctagonEnabledOverride = value; +} + +static bool OctagonOverridePlatformSOS = false; +static bool OctagonPlatformSOSOverrideValue = false; +static bool OctagonPlatformSOSUpgrade = false; + +BOOL OctagonPlatformSupportsSOS(void) +{ + if(OctagonOverridePlatformSOS) { + return OctagonPlatformSOSOverrideValue ? YES : NO; + } + +#if TARGET_OS_OSX + return YES; +#elif TARGET_OS_IOS + static bool isSOSCapable = false; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Only iPhones, iPads, and iPods support SOS. + CFStringRef deviceClass = MGCopyAnswer(kMGQDeviceClass, NULL); + + isSOSCapable = deviceClass && (CFEqual(deviceClass, kMGDeviceClassiPhone) || + CFEqual(deviceClass, kMGDeviceClassiPad) || + CFEqual(deviceClass, kMGDeviceClassiPod)); + + if(deviceClass) { + CFRelease(deviceClass); + } else { + secerror("octagon: Unable to determine device class. Guessing SOS status as Not Supported"); + isSOSCapable = false; + } + + secnotice("octagon", "SOS is %@ on this platform" , isSOSCapable ? @"supported" : @"not supported"); + }); + + return isSOSCapable ? YES : NO; +#else + return NO; +#endif +} + +void OctagonSetPlatformSupportsSOS(BOOL value) +{ + OctagonPlatformSOSOverrideValue = value; + OctagonOverridePlatformSOS = YES; +} + +void OctagonSetSOSUpgrade(BOOL value) +{ + OctagonPlatformSOSUpgrade = value; +} + +BOOL OctagonPerformSOSUpgrade() +{ + if(OctagonPlatformSOSUpgrade){ + return OctagonPlatformSOSUpgrade; + } + return os_feature_enabled(Security, octagonSOSupgrade); +} + +BOOL OctagonRecoveryKeyIsEnabled(void) +{ + if(OctagonRecoveryKeyEnabledOverrideSet) { + secnotice("octagon", "Octagon RecoveryKey is %@ (overridden)", OctagonRecoveryKeyEnabledOverride ? @"enabled" : @"disabled"); + return OctagonRecoveryKeyEnabledOverride; + } + + static bool octagonRecoveryKeyEnabled = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + octagonRecoveryKeyEnabled = os_feature_enabled(Security, recoverykey); + secnotice("octagon", "Octagon is %@ (via feature flags)", octagonRecoveryKeyEnabled ? @"enabled" : @"disabled"); + }); + + return octagonRecoveryKeyEnabled; +} + +void OctagonRecoveryKeySetIsEnabled(BOOL value) +{ + OctagonRecoveryKeyEnabledOverrideSet = true; + OctagonRecoveryKeyEnabledOverride = value; +} + + +BOOL OctagonAuthoritativeTrustIsEnabled(void) +{ + if(OctagonAuthoritativeTrustEnabledOverrideSet) { + secnotice("octagon", "Authoritative Octagon Trust is %@ (overridden)", OctagonAuthoritativeTrustEnabledOverride ? @"enabled" : @"disabled"); + return OctagonAuthoritativeTrustEnabledOverride; + } + + static bool octagonAuthoritativeTrustEnabled = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + octagonAuthoritativeTrustEnabled = os_feature_enabled(Security, octagonTrust); + secnotice("octagon", "Authoritative Octagon Trust is %@ (via feature flags)", octagonAuthoritativeTrustEnabled ? @"enabled" : @"disabled"); + }); + return octagonAuthoritativeTrustEnabled; +} +void OctagonAuthoritativeTrustSetIsEnabled(BOOL value) +{ + OctagonAuthoritativeTrustEnabledOverrideSet = true; + OctagonAuthoritativeTrustEnabledOverride = value; +} diff --git a/keychain/ot/OTContext.h b/keychain/ot/OTContext.h index e8ee0b75..3f75b375 100644 --- a/keychain/ot/OTContext.h +++ b/keychain/ot/OTContext.h @@ -48,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) OTCloudStore* cloudStore; @property (nonatomic, readonly) CKKSLockStateTracker* lockStateTracker; -@property (nonatomic, readonly) CKKSCKAccountStateTracker* accountTracker; +@property (nonatomic, readonly) CKKSAccountStateTracker* accountTracker; @property (nonatomic, readonly) CKKSReachabilityTracker *reachabilityTracker; - (nullable instancetype) initWithContextID:(NSString*)contextID @@ -70,6 +70,11 @@ NS_ASSUME_NONNULL_BEGIN bottleID:(NSString*)bottleID error:(NSError**)error; +-(BOOL)updateAllBottlesForPeerID:(NSString*)peerID + newSigningKey:(SFECKeyPair*)newSigningKey + newEncryptionKey:(SFECKeyPair*)newEncryptionKey + error:(NSError**)error; + -(OctagonBottleCheckState)doesThisDeviceHaveABottle:(NSError**)error; @end diff --git a/keychain/ot/OTContext.m b/keychain/ot/OTContext.m index e16b3ea9..ee9a3ed0 100644 --- a/keychain/ot/OTContext.m +++ b/keychain/ot/OTContext.m @@ -23,7 +23,10 @@ #if OCTAGON #import "OTContext.h" -#import "SFPublicKey+SPKI.h" +#import + +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTDefines.h" #include #include @@ -34,7 +37,6 @@ #import -NSString* OTCKContainerName = @"com.apple.security.keychain"; NSString* OTCKZoneName = @"OctagonTrust"; static NSString* const kOTRampZoneName = @"metadata_zone"; @@ -55,7 +57,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; @property (nonatomic, strong) dispatch_queue_t queue; @property (nonatomic, weak) id identityProvider; -@property (nonatomic, strong) CKKSCKAccountStateTracker* accountTracker; +@property (nonatomic, strong) CKKSAccountStateTracker* accountTracker; @property (nonatomic, strong) CKKSLockStateTracker* lockStateTracker; @property (nonatomic, strong) CKKSReachabilityTracker *reachabilityTracker; @@ -116,12 +118,8 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; localStore:_localStore contextID:contextID dsid:dsid - fetchRecordZoneChangesOperationClass:[CKFetchRecordZoneChangesOperation class] - fetchRecordsOperationClass:[CKFetchRecordsOperation class] - queryOperationClass:[CKQueryOperation class] - modifySubscriptionsOperationClass:[CKModifySubscriptionsOperation class] - modifyRecordZonesOperationClass:[CKModifyRecordZonesOperation class] - apsConnectionClass:[APSConnection class] + zoneModifier:[CKKSViewManager manager].zoneModifier + cloudKitClassDependencies:[CKKSCloudKitClassDependencies forLiveCloudKit] operationQueue:nil]; } else{ _cloudStore = cloudStore; @@ -252,7 +250,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; if (!identity.spID) { secerror("octagon: cannot enroll without a spID"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorNoIdentity userInfo:@{NSLocalizedDescriptionKey: @"OTIdentity does not have an SOS peer id"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNoIdentity userInfo:@{NSLocalizedDescriptionKey: @"OTIdentity does not have an SOS peer id"}]; } return nil; } @@ -262,7 +260,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; if(!info.escrowedSigningSPKI){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEscrowSigningSPKI userInfo:@{NSLocalizedDescriptionKey: @"Escrowed spinging SPKI is nil"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEscrowSigningSPKI userInfo:@{NSLocalizedDescriptionKey: @"Escrowed spinging SPKI is nil"}]; } secerror("octagon: Escrowed spinging SPKI is nil"); return nil; @@ -271,7 +269,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; info.bottleID = bprec.recordName; if(!info.bottleID){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"BottleID is nil"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorBottleID userInfo:@{NSLocalizedDescriptionKey: @"BottleID is nil"}]; } secerror("octagon: BottleID is nil"); return nil; @@ -344,7 +342,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } } NSString* recordName = [OTBottledPeerRecord constructRecordID:escrowRecordID - escrowSigningSPKI:[escrowKeys.signingKey.publicKey asSPKI]]; + escrowSigningSPKI:[escrowKeys.signingKey.publicKey encodeSubjectPublicKeyInfo]]; OTBottledPeerRecord* rec = [self.localStore readLocalBottledPeerRecordWithRecordID:recordName error:&localError]; if (!rec) { @@ -369,17 +367,138 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; return bps; } --(BOOL)bottleExistsLocallyForIdentity:(OTIdentity*)identity logger:(CKKSAnalytics*)logger error:(NSError**)error +-(BOOL)updateBottleForPeerID:(NSString*)peerID + newSigningKey:(SFECKeyPair*)signingKey + newEncryptionKey:(SFECKeyPair*)encryptionKey + escrowKeySet:(OTEscrowKeys*)keySet + error:(NSError**)error +{ + NSError* localError = nil; + + //let's rebottle our bottles! + OTBottledPeer *bp = [[OTBottledPeer alloc] initWithPeerID:nil + spID:peerID + peerSigningKey:signingKey + peerEncryptionKey:encryptionKey + escrowKeys:keySet + error:&localError]; + if (!bp || localError !=nil) { + secerror("octagon: unable to create a bottled peer: %@", localError); + if (error) { + *error = localError; + } + return NO; + } + OTBottledPeerSigned* bpSigned = [[OTBottledPeerSigned alloc] initWithBottledPeer:bp + escrowedSigningKey:keySet.signingKey + peerSigningKey:signingKey + error:&localError]; + if(!bpSigned || localError){ + secerror("octagon: unable to create a signed bottled peer: %@", localError); + if (error) { + *error = localError; + } + return NO; + } + + OTBottledPeerRecord *newRecord = [bpSigned asRecord:peerID]; + + BOOL uploaded = [self.cloudStore uploadBottledPeerRecord:newRecord escrowRecordID:peerID error:&localError]; + if(!uploaded || localError){ + secerror("octagon: unable to upload bottled peer: %@", localError); + if (error) { + *error = localError; + } + return NO; + } + + return YES; +} + +-(BOOL)updateAllBottlesForPeerID:(NSString*)peerID + newSigningKey:(SFECKeyPair*)newSigningKey + newEncryptionKey:(SFECKeyPair*)newEncryptionKey + error:(NSError**)error +{ + BOOL result = NO; + BOOL atLeastOneHasBeenUpdated = NO; + + NSError* localError = nil; + + SFECKeyPair *escrowSigningKey = nil; + SFECKeyPair *escrowEncryptionKey = nil; + SFAESKey *escrowSymmetricKey = nil; + + result = [self.cloudStore downloadBottledPeerRecord:&localError]; + if(!result || localError){ + secnotice("octagon", "could not download bottles from cloudkit: %@", localError); + } + + secnotice("octagon", "checking local store for downloaded bottles"); + + NSArray* bottles = [self.localStore readLocalBottledPeerRecordsWithMatchingPeerID:peerID error:&localError]; + if(!bottles || localError){ + secnotice("octagon", "peer %@ enrolled 0 bottles", peerID); + if (error) { + *error = localError; + } + return result; + } + + //iterate through all the bottles and attempt to update all the bottles + for(OTBottledPeerRecord* bottle in bottles){ + + NSString* escrowSigningPubKeyHash = [OTEscrowKeys hashEscrowedSigningPublicKey:bottle.escrowedSigningSPKI]; + + BOOL foundKeys = [OTEscrowKeys findEscrowKeysForLabel:escrowSigningPubKeyHash + foundSigningKey:&escrowSigningKey + foundEncryptionKey:&escrowEncryptionKey + foundSymmetricKey:&escrowSymmetricKey + error:&localError]; + if(!foundKeys){ + secnotice("octagon", "found 0 persisted escrow keys for label: %@", escrowSigningPubKeyHash); + continue; + } + + OTEscrowKeys *retrievedKeySet = [[OTEscrowKeys alloc]initWithSigningKey:escrowSigningKey encryptionKey:escrowEncryptionKey symmetricKey:escrowSymmetricKey]; + + if(!retrievedKeySet){ + secnotice("octagon", "failed to create escrow keys"); + continue; + } + + BOOL updated = [self updateBottleForPeerID:peerID newSigningKey:newSigningKey newEncryptionKey:newEncryptionKey escrowKeySet:retrievedKeySet error:&localError]; + + if(!updated || localError){ + secnotice("octagon", "could not updated bottle for peerid: %@ for escrowed signing public key hash: %@", peerID, escrowSigningPubKeyHash); + }else{ + atLeastOneHasBeenUpdated = YES; + } + } + + if(!atLeastOneHasBeenUpdated){ + secerror("octagon: no bottles were updated for : %@", peerID); + result = NO; + + localError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorBottleUpdate userInfo:@{NSLocalizedDescriptionKey: @"bottle update failed, 0 bottles updated."}]; + if(error){ + *error = localError; + } + }else{ + result = YES; + secnotice("octagon", "bottles were updated for : %@", peerID); + } + return result; +} + +-(BOOL)bottleExistsLocallyForIdentity:(OTIdentity*)identity + error:(NSError**)error { NSError* localError = nil; //read all the local bp records NSArray* bottles = [self.localStore readLocalBottledPeerRecordsWithMatchingPeerID:identity.spID error:&localError]; if(!bottles || [bottles count] == 0 || localError != nil){ secerror("octagon: there are no eligible bottle peer records: %@", localError); - [logger logRecoverableError:localError - forEvent:OctagonEventBottleCheck - zoneName:kOTRampZoneName - withAttributes:NULL]; if(error){ *error = localError; } @@ -389,7 +508,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; BOOL hasBottle = NO; //if check all the records if the peer signing public key matches the bottled one! for(OTBottledPeerRecord* bottle in bottles){ - NSData* bottledSigningSPKIData = [[SFECPublicKey fromSPKI:bottle.peerSigningSPKI] keyData]; + NSData* bottledSigningSPKIData = [[SFECPublicKey keyWithSubjectPublicKeyInfo:bottle.peerSigningSPKI] keyData]; NSData* currentIdentitySPKIData = [identity.peerSigningKey.publicKey keyData]; //spIDs are the same AND check bottle signature @@ -407,7 +526,8 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; return hasBottle; } --(BOOL)queryCloudKitForBottle:(OTIdentity*)identity logger:(CKKSAnalytics*)logger error:(NSError**)error +-(BOOL)queryCloudKitForBottle:(OTIdentity*)identity + error:(NSError**)error { NSError* localError = nil; BOOL hasBottle = NO; @@ -415,16 +535,12 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; BOOL fetched = [self.cloudStore downloadBottledPeerRecord:&localError]; if(fetched == NO || localError != nil){ //couldn't download bottles secerror("octagon: 0 bottled peers downloaded: %@", localError); - [logger logRecoverableError:localError - forEvent:OctagonEventBottleCheck - zoneName:kOTRampZoneName - withAttributes:NULL]; if(error){ *error = localError; } return NO; }else{ //downloaded bottles, let's check local store - hasBottle = [self bottleExistsLocallyForIdentity:identity logger:logger error:&localError]; + hasBottle = [self bottleExistsLocallyForIdentity:identity error:&localError]; } if(error){ @@ -445,9 +561,12 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; return UNCLEAR; } + // Wait until the account tracker has had a chance to figure out the state + [self.accountTracker.ckAccountInfoInitialized wait:5*NSEC_PER_SEC]; + if(self.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNotSignedIn userInfo:@{NSLocalizedDescriptionKey: @"iCloud account is logged out"}]; } @@ -457,9 +576,6 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; NSError* localError = nil; OctagonBottleCheckState bottleStatus = NOBOTTLE; - CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityBottleCheck withAction:nil]; - [tracker start]; //get our current identity OTIdentity* identity = [self.identityProvider currentIdentity:&localError]; @@ -472,11 +588,6 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; if(!identity && localError != nil){ secerror("octagon: do not have an identity: %@", localError); - [logger logRecoverableError:localError - forEvent:OctagonEventBottleCheck - zoneName:kOTRampZoneName - withAttributes:NULL]; - [tracker stop]; if(error){ *error = localError; } @@ -484,22 +595,21 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } //check locally first - BOOL bottleExistsLocally = [self bottleExistsLocallyForIdentity:identity logger:logger error:&localError]; + BOOL bottleExistsLocally = [self bottleExistsLocallyForIdentity:identity error:&localError]; //no bottle and we have no network if(!bottleExistsLocally && !self.reachabilityTracker.currentReachability){ secnotice("octagon", "no network, can't query"); - localError = [NSError errorWithDomain:octagonErrorDomain + localError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNoNetwork userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; - [tracker stop]; if(error){ *error = localError; } return UNCLEAR; } else if(!bottleExistsLocally){ - if([self queryCloudKitForBottle:identity logger:logger error:&localError]){ + if([self queryCloudKitForBottle:identity error:&localError]){ bottleStatus = BOTTLE; } }else if(bottleExistsLocally){ @@ -507,21 +617,14 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } if(bottleStatus == NOBOTTLE){ - localError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorNoBottlePeerRecords userInfo:@{NSLocalizedDescriptionKey: @"Peer %@ does not have any bottled records"}]; + localError = [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNoBottlePeerRecords + userInfo:@{NSLocalizedDescriptionKey: @"Peer does not have any bottled records"}]; secerror("octagon: this device does not have any bottled peers: %@", localError); - [logger logRecoverableError:localError - forEvent:OctagonEventBottleCheck - zoneName:kOTRampZoneName - withAttributes:@{ OctagonEventAttributeFailureReason : @"does not have bottle"}]; if(error){ *error = localError; } } - else{ - [logger logSuccessForEventNamed:OctagonEventBottleCheck]; - } - - [tracker stop]; return bottleStatus; } diff --git a/keychain/ot/OTContextRecord.h b/keychain/ot/OTContextRecord.h index 9fe05570..48a5f5dc 100644 --- a/keychain/ot/OTContextRecord.h +++ b/keychain/ot/OTContextRecord.h @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong) NSData* recoveryEncryptionSPKI; --(BOOL)isEqual:(OTContextRecord*)record; +-(BOOL)isEqual:(OTContextRecord* _Nullable)record; @end diff --git a/keychain/ot/OTControl.h b/keychain/ot/OTControl.h index 428c905b..1adc056c 100644 --- a/keychain/ot/OTControl.h +++ b/keychain/ot/OTControl.h @@ -21,27 +21,86 @@ * @APPLE_LICENSE_HEADER_END@ */ -// You must be 64-bit to use this class. #if __OBJC2__ +#ifndef OTCONTROL_H +#define OTCONTROL_H + #import +#import +#if !TARGET_OS_BRIDGE // SecurityFoundation not mastered on BridgeOS +#import +#else +@class SFECKeyPair; +#endif + #import +#import + +#if !TARGET_OS_BRIDGE // SecurityFoundation not mastered on BridgeOS +#import +#else +@class SFECKeyPair; +#endif NS_ASSUME_NONNULL_BEGIN +@class OTJoiningConfiguration; + + @interface OTControl : NSObject + +@property (assign) BOOL synchronous; + + (OTControl* _Nullable)controlObject:(NSError* _Nullable __autoreleasing* _Nullable)error; -- (instancetype)initWithConnection:(NSXPCConnection*)connection; ++ (OTControl* _Nullable)controlObject:(bool)sync error:(NSError* _Nullable *)error; + +- (instancetype)initWithConnection:(NSXPCConnection*)connection sync:(bool)sync; - (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID reply:(void (^)(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error))reply; - (void)encryptionKey:(void (^)(NSData* result, NSError* _Nullable error))reply; - (void)signingKey:(void (^)(NSData* result, NSError* _Nullable error))reply; - (void)listOfRecords:(void (^)(NSArray* list, NSError* _Nullable error))reply; -- (void)signOut:(void (^)(BOOL result, NSError * _Nullable error))reply; -- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable error))reply; - (void)reset:(void (^)(BOOL result, NSError* _Nullable error))reply; +- (void)signIn:(NSString*)dsid container:(NSString* _Nullable)container context:(NSString*)contextID reply:(void (^)(NSError * _Nullable error))reply; +- (void)signOut:(NSString* _Nullable)container context:(NSString*)contextID reply:(void (^)(NSError * _Nullable error))reply; +- (void)notifyIDMSTrustLevelChangeForContainer:(NSString* _Nullable)container context:(NSString*)contextID reply:(void (^)(NSError * _Nullable error))reply; + +- (void)handleIdentityChangeForSigningKey:(SFECKeyPair* _Nonnull)peerSigningKey + ForEncryptionKey:(SFECKeyPair* _Nonnull)encryptionKey + ForPeerID:(NSString*)peerID + reply:(void (^)(BOOL result, + NSError* _Nullable error))reply; + +- (void)rpcEpochWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(uint64_t epoch, + NSError * _Nullable error))reply; + +- (void)rpcPrepareIdentityAsApplicantWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply; +- (void)rpcVoucherWithConfiguration:(OTJoiningConfiguration*)config + peerID:(NSString*)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + reply:(void (^)(NSData* voucher, NSData* voucherSig, NSError * _Nullable error))reply; + +- (void)rpcJoinWithConfiguration:(OTJoiningConfiguration*)config + vouchData:(NSData*)vouchData + vouchSig:(NSData*)vouchSig + preapprovedKeys:(NSArray* _Nullable)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply; + + + // Call this to 'preflight' a bottled peer entry. This will create sufficient entropy, derive and save all relevant keys, // then return the entropy to the caller. If something goes wrong during this process, do not store the returned entropy. - (void)preflightBottledPeer:(NSString*)contextID @@ -49,21 +108,129 @@ NS_ASSUME_NONNULL_BEGIN reply:(void (^)(NSData* _Nullable entropy, NSString* _Nullable bottleID, NSData* _Nullable signingPublicKey, - NSError* _Nullable error))reply; + NSError* _Nullable error))reply + API_DEPRECATED("Use OTClique API", macos(10.14, 10.15), ios(4, 17)); // Call this to 'launch' a preflighted bottled peer entry. This indicates that you've successfully stored the entropy, // and we should save the bottled peer entry off-device for later retrieval. - (void)launchBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID - reply:(void (^ _Nullable)(NSError* _Nullable error))reply; + reply:(void (^ _Nullable)(NSError* _Nullable error))reply + API_DEPRECATED("No longer needed", macos(10.14, 10.15), ios(4, 17)); // Call this to scrub the launch of a preflighted bottled peer entry. This indicates you've terminally failed to store the // preflighted entropy, and this bottled peer will never be used again and can be deleted. - (void)scrubBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID - reply:(void (^ _Nullable)(NSError* _Nullable error))reply; + reply:(void (^ _Nullable)(NSError* _Nullable error))reply + API_DEPRECATED("No longer needed", macos(10.14, 10.15), ios(4, 17)); + +- (void)status:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply; + +- (void)fetchEgoPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))reply; + +- (void)fetchCliqueStatus:(NSString* _Nullable)container + context:(NSString*)context + configuration:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus cliqueStatus, NSError* _Nullable error))reply; + +- (void)fetchTrustStatus:(NSString* _Nullable)container + context:(NSString*)context + configuration:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus status, + NSString* _Nullable peerID, + NSNumber * _Nullable numberOfOctagonPeers, + BOOL isExcluded, + NSError * _Nullable error))reply; + +// Likely won't be used once Octagon is turned on for good +- (void)startOctagonStateMachine:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)resetAndEstablish:(NSString* _Nullable)container + context:(NSString*)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)establish:(NSString* _Nullable)container + context:(NSString*)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)leaveClique:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)removeFriendsInClique:(NSString* _Nullable)container + context:(NSString*)context + peerIDs:(NSArray*)peerIDs + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)peerDeviceNamesByPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable peers, NSError* _Nullable error))reply; + +- (void)fetchAllViableBottles:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray * _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply; + +-(void)restore:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + bottleSalt:(NSString *)bottleSalt + entropy:(NSData *)entropy + bottleID:(NSString *)bottleID + reply:(void (^)(NSError * _Nullable))reply; + +- (void)fetchEscrowContents:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; + +- (void) createRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString *)recoveryKey + reply:(void (^)( NSError * _Nullable))reply; + +- (void) joinWithRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable))reply; + +- (void)healthCheck:(NSString* _Nullable)container + context:(NSString *)context +skipRateLimitingCheck:(BOOL)skipRateLimitingCheck + reply:(void (^)(NSError *_Nullable error))reply; + +- (void)attemptSosUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)waitForOctagonUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)postCDPFollowupResult:(BOOL)success + type:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + containerName:(NSString* _Nullable)containerName + contextName:(NSString *)contextName + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)tapToRadar:(NSString *)action + description:(NSString *)description + radar:(NSString *)radar + reply:(void (^)(NSError* _Nullable error))reply; @end NS_ASSUME_NONNULL_END + +#endif // OTCONTROL_H #endif // __OBJC__ diff --git a/keychain/ot/OTControl.m b/keychain/ot/OTControl.m index b8921485..adc3df22 100644 --- a/keychain/ot/OTControl.m +++ b/keychain/ot/OTControl.m @@ -27,8 +27,11 @@ #import #import +#import +#import "keychain/ot/OTClique.h" #import "keychain/ot/OTControl.h" +#import "keychain/ot/OTDefines.h" #import "keychain/ot/OTControlProtocol.h" #import "keychain/ot/OctagonControlServer.h" @@ -40,31 +43,45 @@ @interface OTControl () @property NSXPCConnection *connection; +@property bool sync; @end @implementation OTControl -- (instancetype)initWithConnection:(NSXPCConnection*)connection { +- (instancetype)initWithConnection:(NSXPCConnection*)connection sync:(bool)sync { if(self = [super init]) { _connection = connection; + _sync = sync; } return self; } +- (void)dealloc { + [self.connection invalidate]; +} + +- (NSXPCConnection*)getConnection:(void (^)(NSError *error))handler +{ + if(self.sync) { + return [self.connection synchronousRemoteObjectProxyWithErrorHandler: handler]; + } else { + return [self.connection remoteObjectProxyWithErrorHandler: handler]; + } +} + - (void)restore:(NSString *)contextID dsid:(NSString *)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID reply:(void (^)(NSData* signingKeyData, NSData* encryptionKeyData, NSError* _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self getConnection: ^(NSError* error) { reply(nil, nil, error); }] restore:contextID dsid:dsid secret:secret escrowRecordID:escrowRecordID reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError *error) { reply(signingKeyData, encryptionKeyData, error); }]; - } -(void)reset:(void (^)(BOOL result, NSError* _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self getConnection: ^(NSError* error) { reply(NO, error); }] reset:^(BOOL result, NSError * _Nullable error) { reply(result, error); @@ -73,7 +90,11 @@ - (void)signingKey:(void (^)(NSData* result, NSError* _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [self octagonSigningPublicKey:reply]; +} + +- (void)octagonSigningPublicKey:(nonnull void (^)(NSData * _Nullable, NSError * _Nullable))reply { + [[self getConnection: ^(NSError* error) { reply(nil, error); }] octagonSigningPublicKey:^(NSData *signingKey, NSError * _Nullable error) { reply(signingKey, error); @@ -83,17 +104,26 @@ - (void)encryptionKey:(void (^)(NSData* result, NSError* _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [self octagonEncryptionPublicKey:reply]; +} + +- (void)octagonEncryptionPublicKey:(nonnull void (^)(NSData * _Nullable, NSError * _Nullable))reply +{ + [[self getConnection: ^(NSError* error) { reply(nil, error); }] octagonEncryptionPublicKey:^(NSData *encryptionKey, NSError * _Nullable error) { reply(encryptionKey, error); }]; - } - (void)listOfRecords:(void (^)(NSArray* list, NSError* _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [self listOfEligibleBottledPeerRecords:reply]; +} + +- (void)listOfEligibleBottledPeerRecords:(nonnull void (^)(NSArray * _Nullable, NSError * _Nullable))reply +{ + [[self getConnection: ^(NSError* error) { reply(nil, error); }] listOfEligibleBottledPeerRecords:^(NSArray *list, NSError * _Nullable error) { reply(list, error); @@ -101,24 +131,120 @@ } -- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable error))reply{ - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { - reply(NO, error); - }] signIn:dsid reply:^(BOOL result, NSError * _Nullable error) { - reply(result, error); +- (void)signIn:(NSString*)altDSID container:(NSString* _Nullable)container context:(NSString*)contextID reply:(void (^)(NSError * _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] signIn:altDSID container:container context:contextID reply:^(NSError * _Nullable error) { + reply(error); + }]; +} + +- (void)signOut:(NSString* _Nullable)container context:(NSString*)contextID reply:(void (^)(NSError * _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] signOut:container context:contextID reply:^(NSError * _Nullable error) { + reply(error); }]; } -- (void)signOut:(void (^)(BOOL result, NSError * _Nullable error))reply +- (void)notifyIDMSTrustLevelChangeForContainer:(NSString* _Nullable)container context:(NSString*)contextID reply:(void (^)(NSError * _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self getConnection: ^(NSError* error) { + reply(error); + }] notifyIDMSTrustLevelChangeForContainer:container context:contextID reply:^(NSError * _Nullable error) { + reply(error); + }]; +} + +- (void)handleIdentityChangeForSigningKey:(SFECKeyPair* _Nonnull)peerSigningKey + ForEncryptionKey:(SFECKeyPair* _Nonnull)encryptionKey + ForPeerID:(NSString*)peerID + reply:(void (^)(BOOL result, + NSError* _Nullable error))reply +{ +#if OCTAGON + [[self getConnection: ^(NSError* error) { reply(NO, error); - }] signOut:^(BOOL result, NSError * _Nullable error) { + }] handleIdentityChangeForSigningKey:peerSigningKey ForEncryptionKey:encryptionKey ForPeerID:peerID reply:^(BOOL result, NSError* _Nullable error) { reply(result, error); + }]; +#else + reply(NO, NULL); +#endif +} + +- (void)rpcEpochWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(uint64_t epoch, + NSError * _Nullable error))reply +{ +#if OCTAGON + [[self getConnection: ^(NSError* error) { + reply(0, error); + }] rpcEpochWithConfiguration:config reply:^(uint64_t epoch, + NSError * _Nullable error) { + reply(epoch, error); }]; - +#else + reply(0, NULL); +#endif +} + +- (void)rpcPrepareIdentityAsApplicantWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply +{ +#if OCTAGON + [[self getConnection: ^(NSError* error) { + reply(nil, nil, nil, nil, nil, error); + }] rpcPrepareIdentityAsApplicantWithConfiguration:config reply:^(NSString* pID, NSData* pI, NSData* piSig, NSData* si, NSData* siSig, NSError* e) { + reply(pID, pI, piSig, si, siSig, e); + }]; +#else + reply(NULL, NULL, NULL, NULL, NULL, NULL); +#endif +} + +- (void)rpcVoucherWithConfiguration:(OTJoiningConfiguration*)config + peerID:(NSString*)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + reply:(void (^)(NSData* voucher, NSData* voucherSig, NSError * _Nullable error))reply +{ +#if OCTAGON + [[self getConnection: ^(NSError* error) { + reply(nil, nil, error); + }] rpcVoucherWithConfiguration:config peerID:peerID permanentInfo:permanentInfo permanentInfoSig:permanentInfoSig stableInfo:stableInfo stableInfoSig:stableInfoSig reply:^(NSData* voucher, NSData* voucherSig, NSError * _Nullable error) { + reply(voucher, voucherSig, error); + }]; +#else + reply(NULL, NULL, NULL); +#endif } +- (void)rpcJoinWithConfiguration:(OTJoiningConfiguration*)config + vouchData:(NSData*)vouchData + vouchSig:(NSData*)vouchSig + preapprovedKeys:(NSArray* _Nullable)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply +{ +#if OCTAGON + [[self getConnection: ^(NSError* error) { + reply(error); + }] rpcJoinWithConfiguration:config vouchData:vouchData vouchSig:vouchSig preapprovedKeys:preapprovedKeys reply:^(NSError* e) { + reply(e); + }]; +#else + reply(NULL); +#endif +} - (void)preflightBottledPeer:(NSString*)contextID dsid:(NSString*)dsid @@ -127,7 +253,7 @@ NSData* _Nullable signingPublicKey, NSError* _Nullable error))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self getConnection: ^(NSError* error) { reply(nil, nil, nil, error); }] preflightBottledPeer:contextID dsid:dsid reply:^(NSData* _Nullable entropy, NSString* _Nullable bottleID, @@ -141,7 +267,7 @@ bottleID:(NSString*)bottleID reply:(void (^ _Nullable)(NSError* _Nullable))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self getConnection: ^(NSError* error) { reply(error); }] launchBottledPeer:contextID bottleID:bottleID reply:^(NSError * _Nullable error) { reply(error); @@ -152,18 +278,220 @@ bottleID:(NSString*)bottleID reply:(void (^ _Nullable)(NSError* _Nullable))reply { - [[self.connection remoteObjectProxyWithErrorHandler: ^(NSError* error) { + [[self getConnection: ^(NSError* error) { reply(error); }] scrubBottledPeer:contextID bottleID:bottleID reply:reply]; } +- (void)status:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(nil, error); + }] status:container context:context reply:reply]; +} + +- (void)fetchEgoPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(nil, error); + }] fetchEgoPeerID:container context:context reply:reply]; +} + +- (void)fetchCliqueStatus:(NSString* _Nullable)container + context:(NSString*)context + configuration:(OTOperationConfiguration*)configuration + reply:(void (^)(CliqueStatus cliqueStatus, NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(CliqueStatusError, error); + }] fetchCliqueStatus:container context:context configuration:configuration reply:reply]; +} + +- (void)fetchTrustStatus:(NSString* _Nullable)container + context:(NSString*)context + configuration:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus status, NSString* peerID, NSNumber * _Nullable numberOfOctagonPeers, BOOL isExcluded, NSError * _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(CliqueStatusError, false, NULL, false, error); + }] fetchTrustStatus:container context:context configuration:configuration reply:reply]; +} + +- (void)startOctagonStateMachine:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] startOctagonStateMachine:container context:context reply:reply]; +} + +- (void)resetAndEstablish:(NSString* _Nullable)container + context:(NSString*)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] resetAndEstablish:container context:context altDSID:altDSID reply:reply]; +} + +- (void)establish:(NSString* _Nullable)container + context:(NSString*)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] establish:container context:context altDSID:altDSID reply:reply]; +} + +- (void)leaveClique:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] leaveClique:container context:context reply:reply]; +} + +- (void)removeFriendsInClique:(NSString* _Nullable)container + context:(NSString*)context + peerIDs:(NSArray*)peerIDs + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] removeFriendsInClique:container context:context peerIDs:peerIDs reply:reply]; +} + +- (void)peerDeviceNamesByPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable peers, NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(nil, error); + }] peerDeviceNamesByPeerID:container context:context reply:reply]; +} + +- (void)fetchAllViableBottles:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray * _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply +{ + [[self getConnection:^(NSError *error) { + reply(nil, nil, error); + }] fetchAllViableBottles:container context:context reply:reply]; +} + +-(void)restore:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + bottleSalt:(NSString *)bottleSalt + entropy:(NSData *)entropy +bottleID:(NSString *)bottleID + reply:(void (^)(NSError * _Nullable))reply +{ + [[self getConnection:^(NSError *error) { + reply(error); + }] restore:containerName contextID:contextID bottleSalt:bottleSalt entropy:entropy bottleID:bottleID reply:reply]; +} + +- (void)fetchEscrowContents:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + [[self getConnection:^(NSError *error) { + reply(nil, nil, nil, error); + }] fetchEscrowContents:containerName contextID:contextID reply:reply]; +} + +- (void) createRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString *)recoveryKey + reply:(void (^)( NSError * error))reply +{ + [[self getConnection:^(NSError *error) { + reply(error); + }] createRecoveryKey:containerName contextID:contextID recoveryKey:recoveryKey reply:reply]; +} + +- (void) joinWithRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable))reply +{ + [[self getConnection:^(NSError *error) { + reply(error); + }] joinWithRecoveryKey:containerName contextID:contextID recoveryKey:recoveryKey reply:reply]; +} + +- (void)healthCheck:(NSString *)container + context:(NSString *)context +skipRateLimitingCheck:(BOOL)skipRateLimitingCheck + reply:(void (^)(NSError *_Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] healthCheck:container context:context skipRateLimitingCheck:skipRateLimitingCheck reply:reply]; +} + +- (void)attemptSosUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] attemptSosUpgrade:container context:context reply:reply]; +} + +- (void)waitForOctagonUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* error) { + reply(error); + }] waitForOctagonUpgrade:container context:context reply:reply]; +} + +- (void)postCDPFollowupResult:(BOOL)success + type:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + containerName:(NSString* _Nullable)containerName + contextName:(NSString *)contextName + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* connectionError) { + reply(connectionError); + }] postCDPFollowupResult:success type:type error:[SecXPCHelper cleanseErrorForXPC:error] containerName:containerName contextName:contextName reply:reply]; +} + +- (void)tapToRadar:(NSString *)action + description:(NSString *)description + radar:(NSString *)radar + reply:(void (^)(NSError* _Nullable error))reply +{ + [[self getConnection: ^(NSError* connectionError) { + reply(connectionError); + }] tapToRadar:action description:description radar:radar reply:reply]; +} + + (OTControl*)controlObject:(NSError* __autoreleasing *)error { + return [OTControl controlObject:false error:error]; +} ++ (OTControl*)controlObject:(bool)sync error:(NSError**)error +{ NSXPCConnection* connection = [[NSXPCConnection alloc] initWithMachServiceName:@(kSecuritydOctagonServiceName) options:0]; if (connection == nil) { if(error) { - *error = [NSError errorWithDomain:@"securityd" code:-1 userInfo:@{NSLocalizedDescriptionKey: @"Couldn't create connection (no reason given)"}]; + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecInternalError userInfo:@{NSLocalizedDescriptionKey: @"Couldn't create connection (no reason given)"}]; } return nil; } @@ -172,7 +500,7 @@ connection.remoteObjectInterface = interface; [connection resume]; - OTControl* c = [[OTControl alloc] initWithConnection:connection]; + OTControl* c = [[OTControl alloc] initWithConnection:connection sync:sync]; return c; } diff --git a/keychain/ot/OTControlProtocol.h b/keychain/ot/OTControlProtocol.h index 2cc27dda..458c9595 100644 --- a/keychain/ot/OTControlProtocol.h +++ b/keychain/ot/OTControlProtocol.h @@ -23,19 +23,71 @@ #import -NS_ASSUME_NONNULL_BEGIN +#ifndef SECURITY_OT_OTCONTROLPROTOCOL_H +#define SECURITY_OT_OTCONTROLPROTOCOL_H 1 + +#import @class SFECKeyPair; -@protocol OTControlProtocol +NS_ASSUME_NONNULL_BEGIN + +@class OTJoiningConfiguration; + +typedef void (^OTNextJoinCompleteBlock)(BOOL finished, NSData* _Nullable message, NSError* _Nullable error); + +@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;; -- (void)octagonSigningPublicKey:(void (^)(NSData* _Nullable signingKey, NSError * _Nullable))reply;; -- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError *))reply; -- (void)signOut:(void (^)(BOOL result, NSError * _Nullable signedOutError))reply; -- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable signedInError))reply; +- (void)octagonEncryptionPublicKey:(void (^)(NSData* _Nullable encryptionKey, NSError * _Nullable))reply; +- (void)octagonSigningPublicKey:(void (^)(NSData* _Nullable signingKey, NSError * _Nullable))reply; +- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* _Nullable listOfRecords, NSError * _Nullable))reply; + +// If you're not sure about container, pass nil. If you're not sure about context, pass OTDefaultContext. +- (void)signIn:(NSString*)altDSID + container:(NSString* _Nullable)container + context:(NSString*)contextID + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)signOut:(NSString* _Nullable)container + context:(NSString*)contextID + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)notifyIDMSTrustLevelChangeForContainer:(NSString* _Nullable)container + context:(NSString*)contextID + reply:(void (^)(NSError * _Nullable error))reply; + - (void)reset:(void (^)(BOOL result, NSError * _Nullable error))reply; -- (void)scheduleCFUForFuture; + +- (void)handleIdentityChangeForSigningKey:(SFECKeyPair*)peerSigningKey + ForEncryptionKey:(SFECKeyPair*)encryptionKey + ForPeerID:(NSString*)peerID + reply:(void (^)(BOOL result, + NSError* _Nullable error))reply; + +- (void)rpcEpochWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(uint64_t epoch, + NSError * _Nullable error))reply; + +- (void)rpcPrepareIdentityAsApplicantWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply; +- (void)rpcVoucherWithConfiguration:(OTJoiningConfiguration*)config + peerID:(NSString*)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + reply:(void (^)(NSData* voucher, NSData* voucherSig, NSError * _Nullable error))reply; + +- (void)rpcJoinWithConfiguration:(OTJoiningConfiguration*)config + vouchData:(NSData*)vouchData + vouchSig:(NSData*)vouchSig + preapprovedKeys:(NSArray* _Nullable)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply; - (void)preflightBottledPeer:(NSString*)contextID dsid:(NSString*)dsid @@ -49,8 +101,114 @@ NS_ASSUME_NONNULL_BEGIN - (void)scrubBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID reply:(void (^ _Nullable)(NSError* _Nullable error))reply; + +- (void)status:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply; + +- (void)fetchEgoPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))reply; + +- (void)fetchCliqueStatus:(NSString* _Nullable)container + context:(NSString*)context + configuration:(OTOperationConfiguration*)configuration + reply:(void (^)(CliqueStatus cliqueStatus, NSError* _Nullable error))reply; + +- (void)fetchTrustStatus:(NSString* _Nullable)container + context:(NSString*)context + configuration:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus status, + NSString* _Nullable peerID, + NSNumber* _Nullable numberOfPeersInOctagon, + BOOL isExcluded, + NSError* _Nullable error))reply; + +// Likely won't be used once Octagon is turned on for good +- (void)startOctagonStateMachine:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)resetAndEstablish:(NSString* _Nullable)container + context:(NSString*)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)establish:(NSString * _Nullable)container + context:(NSString *)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError * _Nullable))reply; + +- (void)leaveClique:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)removeFriendsInClique:(NSString* _Nullable)container + context:(NSString*)context + peerIDs:(NSArray*)peerIDs + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)peerDeviceNamesByPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable peers, NSError* _Nullable error))reply; + +- (void)fetchAllViableBottles:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray * _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply; + +-(void)restore:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + bottleSalt:(NSString *)bottleSalt + entropy:(NSData *)entropy + bottleID:(NSString *)bottleID + reply:(void (^)(NSError * _Nullable))reply; + +- (void)fetchEscrowContents:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; + +- (void) createRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString *)recoveryKey + reply:(void (^)( NSError * _Nullable))reply; + +- (void) joinWithRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable))reply; + +- (void)healthCheck:(NSString * _Nullable)container + context:(NSString *)context +skipRateLimitingCheck:(BOOL)skipRateLimitingCheck + reply:(void (^)(NSError *_Nullable error))reply; + +- (void)attemptSosUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)waitForOctagonUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)postCDPFollowupResult:(BOOL)success + type:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + containerName:(NSString* _Nullable)containerName + contextName:(NSString *)contextName + reply:(void (^)(NSError* _Nullable error))reply; + +- (void)tapToRadar:(NSString *)action + description:(NSString *)description + radar:(NSString *)radar + reply:(void (^)(NSError* _Nullable error))reply; + @end NSXPCInterface* OTSetupControlProtocol(NSXPCInterface* interface); NS_ASSUME_NONNULL_END + +#endif /* SECURITY_OT_OTCONTROLPROTOCOL_H */ diff --git a/keychain/ot/OTControlProtocol.m b/keychain/ot/OTControlProtocol.m index 1868ea72..003f186a 100644 --- a/keychain/ot/OTControlProtocol.m +++ b/keychain/ot/OTControlProtocol.m @@ -22,59 +22,70 @@ */ #import - +#import "keychain/ot/OTClique.h" #import "keychain/ot/OTControlProtocol.h" +#import "keychain/ot/OTJoiningConfiguration.h" +#import #if OCTAGON #import #import #import #include +#import #import #endif // OCTAGON + NSXPCInterface* OTSetupControlProtocol(NSXPCInterface* interface) { #if OCTAGON - static NSMutableSet *errClasses; - - static dispatch_once_t onceToken; + NSSet *errorClasses = [SecXPCHelper safeErrorClasses]; - dispatch_once(&onceToken, ^{ - errClasses = [NSMutableSet set]; - char *classes[] = { - "NSArray", - "NSData", - "NSDate", - "NSDictionary", - "NSError", - "NSNull", - "NSNumber", - "NSOrderedSet", - "NSSet", - "NSString", - "NSURL", - }; - - for (unsigned n = 0; n < sizeof(classes)/sizeof(classes[0]); n++) { - Class cls = objc_getClass(classes[n]); - if (cls) { - [errClasses addObject:cls]; - } - } - }); - @try { - [interface setClasses:errClasses forSelector:@selector(restore:dsid:secret:escrowRecordID:reply:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(octagonEncryptionPublicKey:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(octagonSigningPublicKey:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(listOfEligibleBottledPeerRecords:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(signOut:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(signIn:reply:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(reset:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(restore:dsid:secret:escrowRecordID:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(octagonEncryptionPublicKey:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(octagonSigningPublicKey:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(listOfEligibleBottledPeerRecords:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(signOut:context:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(signIn:container:context:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(reset:) argumentIndex:0 ofReply:YES]; + + [interface setClasses:errorClasses forSelector:@selector(preflightBottledPeer:dsid:reply:) argumentIndex:3 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(launchBottledPeer:bottleID:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(scrubBottledPeer:bottleID:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(handleIdentityChangeForSigningKey:ForEncryptionKey:ForPeerID:reply:) argumentIndex:1 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(fetchCliqueStatus:context:configuration:reply:) argumentIndex:1 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(fetchTrustStatus:context:configuration:reply:) argumentIndex:4 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(fetchEscrowContents:contextID:reply:) argumentIndex:3 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(fetchAllViableBottles:context:reply:) argumentIndex:2 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(createRecoveryKey:contextID:recoveryKey:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(joinWithRecoveryKey:contextID:recoveryKey:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(healthCheck:context:skipRateLimitingCheck:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(attemptSosUpgrade:context:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(waitForOctagonUpgrade:context:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(postCDPFollowupResult:type:error:containerName:contextName:reply:) argumentIndex:2 ofReply:NO]; + [interface setClasses:errorClasses forSelector:@selector(postCDPFollowupResult:type:error:containerName:contextName:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses forSelector:@selector(tapToRadar:description:radar:reply:) argumentIndex:0 ofReply:YES]; + +#if __OBJC2__ - [interface setClasses:errClasses forSelector:@selector(preflightBottledPeer:dsid:reply:) argumentIndex:3 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(launchBottledPeer:bottleID:reply:) argumentIndex:0 ofReply:YES]; - [interface setClasses:errClasses forSelector:@selector(scrubBottledPeer:bottleID:reply:) argumentIndex:0 ofReply:YES]; + [interface setClasses:errorClasses + forSelector:@selector(rpcEpochWithConfiguration:reply:) + argumentIndex:1 + ofReply:YES]; + [interface setClasses:errorClasses + forSelector:@selector(rpcPrepareIdentityAsApplicantWithConfiguration:reply:) + argumentIndex:5 + ofReply:YES]; + [interface setClasses:errorClasses + forSelector:@selector(rpcVoucherWithConfiguration:peerID:permanentInfo:permanentInfoSig:stableInfo:stableInfoSig:reply:) + argumentIndex:2 + ofReply:YES]; + [interface setClasses:errorClasses + forSelector:@selector(rpcJoinWithConfiguration:vouchData:vouchSig:preapprovedKeys:reply:) + argumentIndex:0 + ofReply:YES]; +#endif /* __OBJC2__ */ } @catch(NSException* e) { secerror("OTSetupControlProtocol failed, continuing, but you might crash later: %@", e); diff --git a/keychain/ot/OTCuttlefishAccountStateHolder.h b/keychain/ot/OTCuttlefishAccountStateHolder.h new file mode 100644 index 00000000..4630b7f9 --- /dev/null +++ b/keychain/ot/OTCuttlefishAccountStateHolder.h @@ -0,0 +1,52 @@ + +#import +#import + +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" + +extern NSString* _Nonnull OTCuttlefishContextErrorDomain; +typedef NS_ENUM(uint32_t, OTCuttlefishContextErrors) { + OTCCNoExistingPeerID = 0, +}; + +NS_ASSUME_NONNULL_BEGIN + +@protocol OTCuttlefishAccountStateHolderNotifier +- (void)accountStateUpdated:(OTAccountMetadataClassC*)newState from:(OTAccountMetadataClassC*)oldState; +@end + +@interface OTCuttlefishAccountStateHolder : NSObject + +// If you already know you're on this queue, call the _onqueue versions below. +- (instancetype)initWithQueue:(dispatch_queue_t)queue + container:(NSString*)containerName + context:(NSString*)contextID; + +- (OTAccountMetadataClassC* _Nullable)loadOrCreateAccountMetadata:(NSError**)error; +- (OTAccountMetadataClassC* _Nullable)_onqueueLoadOrCreateAccountMetadata:(NSError**)error; + +- (void)registerNotification:(id)notifier; + +- (BOOL)persistNewEgoPeerID:(NSString*)peerID error:(NSError**)error; +- (NSString * _Nullable)getEgoPeerID:(NSError **)error; + +- (BOOL)persistNewTrustState:(OTAccountMetadataClassC_TrustState)newState + error:(NSError**)error; + +- (BOOL)persistNewEpoch:(uint64_t)epoch error:(NSError**)error; + +- (BOOL)persistAccountChanges:(OTAccountMetadataClassC* (^)(OTAccountMetadataClassC* metadata))makeChanges + error:(NSError**)error; + +- (BOOL)_onqueuePersistAccountChanges:(OTAccountMetadataClassC* (^)(OTAccountMetadataClassC* metadata))makeChanges + error:(NSError**)error; + +- (NSDate *)lastHealthCheckupDate:(NSError * _Nullable *)error; +- (BOOL)persistLastHealthCheck:(NSDate*)lastCheck error:(NSError**)error; + +- (OTAccountMetadataClassC_AttemptedAJoinState)fetchPersistedJoinAttempt:(NSError * _Nullable *)error; +- (BOOL)persistOctagonJoinAttempt:(OTAccountMetadataClassC_AttemptedAJoinState)attempt error:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/ot/OTCuttlefishAccountStateHolder.m b/keychain/ot/OTCuttlefishAccountStateHolder.m new file mode 100644 index 00000000..2455c543 --- /dev/null +++ b/keychain/ot/OTCuttlefishAccountStateHolder.m @@ -0,0 +1,260 @@ + +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTCuttlefishAccountStateHolder () +@property dispatch_queue_t queue; +@property dispatch_queue_t notifyQueue; + +@property NSString* containerName; +@property NSString* contextID; + +@property NSMutableSet>* monitors; +@end + +@implementation OTCuttlefishAccountStateHolder + +- (instancetype)initWithQueue:(dispatch_queue_t)queue + container:(NSString*)containerName + context:(NSString*)contextID +{ + if((self = [super init])) { + _queue = queue; + _notifyQueue = dispatch_queue_create("OTCuttlefishAccountStateHolderNotifier", NULL); + _containerName = containerName; + _contextID = contextID; + _monitors = [NSMutableSet set]; + } + return self; +} + +- (void)registerNotification:(id)notifier +{ + [self.monitors addObject:notifier]; +} + +- (OTAccountMetadataClassC* _Nullable)loadOrCreateAccountMetadata:(NSError**)error +{ + __block OTAccountMetadataClassC* metadata = nil; + __block NSError* localError = nil; + dispatch_sync(self.queue, ^{ + metadata = [self _onqueueLoadOrCreateAccountMetadata:&localError]; + }); + + if(error && localError) { + *error = localError; + } + return metadata; +} + +- (OTAccountMetadataClassC* _Nullable)_onqueueLoadOrCreateAccountMetadata:(NSError**)error +{ + dispatch_assert_queue(self.queue); + + NSError* localError = nil; + OTAccountMetadataClassC* current = [OTAccountMetadataClassC loadFromKeychainForContainer:self.containerName contextID:self.contextID error:&localError]; + + if(!current || localError) { + if([localError.domain isEqualToString:NSOSStatusErrorDomain] && localError.code == errSecItemNotFound) { + // That's okay, this is the first time we're saving this. + current = [[OTAccountMetadataClassC alloc] init]; + current.attemptedJoin = OTAccountMetadataClassC_AttemptedAJoinState_NOTATTEMPTED; + } else { + // No good. + if(error) { + *error = localError; + } + return nil; + } + } + + return current; +} + +- (NSString * _Nullable)getEgoPeerID:(NSError * _Nullable *)error { + NSError* localError = nil; + + OTAccountMetadataClassC* current = [self loadOrCreateAccountMetadata:&localError]; + + if(localError || !current) { + if(error) { + *error = localError; + } + return nil; + } + + if(!current.peerID) { + if(error) { + *error = [NSError errorWithDomain:OTCuttlefishContextErrorDomain + code:OTCCNoExistingPeerID + description:@"No existing ego peer ID"]; + } + + return nil; + } + + return current.peerID; +} + +- (OTAccountMetadataClassC_AttemptedAJoinState)fetchPersistedJoinAttempt:(NSError * _Nullable *)error { + NSError* localError = nil; + OTAccountMetadataClassC* current = [self loadOrCreateAccountMetadata:&localError]; + + if(localError || !current) { + if(error) { + *error = localError; + } + return OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN; + } + return current.attemptedJoin; +} + +- (NSDate *)lastHealthCheckupDate:(NSError * _Nullable *)error { + NSError* localError = nil; + + OTAccountMetadataClassC* current = [self loadOrCreateAccountMetadata:&localError]; + + if(localError || !current) { + if(error) { + *error = localError; + } + return NULL; + } + + return [NSDate dateWithTimeIntervalSince1970: ((NSTimeInterval)current.lastHealthCheckup) / 1000.0]; +} + + +- (BOOL)persistNewEgoPeerID:(NSString*)peerID error:(NSError**)error { + return [self persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.peerID = peerID; + return metadata; + } error:error]; +} + +- (BOOL)persistNewTrustState:(OTAccountMetadataClassC_TrustState)newState + error:(NSError**)error +{ + return [self persistAccountChanges:^(OTAccountMetadataClassC *metadata) { + metadata.trustState = newState; + return metadata; + } error:error]; +} + +- (BOOL)persistNewAccountState:(OTAccountMetadataClassC_AccountState)newState + optionalAltDSID:(NSString* _Nullable)altDSID + error:(NSError**)error +{ + return [self persistAccountChanges:^(OTAccountMetadataClassC *metadata) { + metadata.icloudAccountState = newState; + metadata.altDSID = altDSID; + return metadata; + } error:error]; +} + +- (BOOL)persistNewEpoch:(uint64_t)epoch + error:(NSError**)error +{ + return [self persistAccountChanges:^(OTAccountMetadataClassC *metadata) { + metadata.epoch = epoch; + return metadata; + } error:error]; +} + +- (BOOL)persistAccountChanges:(OTAccountMetadataClassC* (^)(OTAccountMetadataClassC*))makeChanges + error:(NSError**)error +{ + __block NSError* localError = nil; + __block OTAccountMetadataClassC* newState = nil; + __block OTAccountMetadataClassC* oldState = nil; + + dispatch_sync(self.queue, ^void { + oldState = [self _onqueueLoadOrCreateAccountMetadata:&localError]; + if(!oldState) { + return; + } + + newState = makeChanges([oldState copy]); + if(![newState saveToKeychainForContainer:self.containerName contextID:self.contextID error:&localError]) { + newState = nil; + } + }); + + if(localError && error) { + *error = localError; + } + + if (newState) { + [self asyncNotifyAccountStateChanges:newState from:oldState]; + return YES; + } else { + return NO; + } +} + +- (BOOL)persistLastHealthCheck:(NSDate*)lastCheck + error:(NSError**)error +{ + return [self persistAccountChanges:^(OTAccountMetadataClassC *metadata) { + metadata.lastHealthCheckup = (uint64_t) ([lastCheck timeIntervalSince1970] * 1000); + return metadata; + } error:error]; +} + +- (BOOL)persistOctagonJoinAttempt:(OTAccountMetadataClassC_AttemptedAJoinState)attempt + error:(NSError**)error +{ + return [self persistAccountChanges:^(OTAccountMetadataClassC *metadata) { + metadata.attemptedJoin = attempt; + return metadata; + } error:error]; +} + +- (BOOL)_onqueuePersistAccountChanges:(OTAccountMetadataClassC* (^)(OTAccountMetadataClassC* metadata))makeChanges + error:(NSError**)error +{ + __block NSError* localError = nil; + dispatch_assert_queue(self.queue); + + OTAccountMetadataClassC *oldState = nil; + OTAccountMetadataClassC *newState = nil; + + oldState = [self _onqueueLoadOrCreateAccountMetadata:&localError]; + if(oldState) { + newState = makeChanges([oldState copy]); + + if(![newState saveToKeychainForContainer:self.containerName contextID:self.contextID error:&localError]) { + newState = nil; + } + } + + if (error && localError) { + *error = localError; + } + + if (newState) { + [self asyncNotifyAccountStateChanges:newState from:oldState]; + return YES; + } else { + return NO; + } +} + +- (void)asyncNotifyAccountStateChanges:(OTAccountMetadataClassC *)newState from:(OTAccountMetadataClassC *)oldState +{ + WEAKIFY(self); + + dispatch_async(self.notifyQueue, ^{ + STRONGIFY(self); + + for (id monitor in self.monitors) { + [monitor accountStateUpdated:newState from:oldState]; + } + }); +} + + +@end diff --git a/keychain/ot/OTCuttlefishContext.h b/keychain/ot/OTCuttlefishContext.h new file mode 100644 index 00000000..db45bada --- /dev/null +++ b/keychain/ot/OTCuttlefishContext.h @@ -0,0 +1,197 @@ +/* + * 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 OCTAGON +#ifndef OTCUTTLEFISH_CONTEXT +#define OTCUTTLEFISH_CONTEXT + +#import +#import +#import +#import + +#import "keychain/ckks/OctagonAPSReceiver.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" +#import "keychain/ckks/CKKSCondition.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "OTDeviceInformation.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTClique.h" +#import "keychain/ot/OTFollowup.h" +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OTAuthKitAdapter.h" +#import "keychain/ot/OTDeviceInformationAdapter.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import +#import "keychain/ot/OTJoiningConfiguration.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" + +#import + +#import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSKeychainView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTCuttlefishContext : NSObject + +@property (readonly) id cuttlefishXPCConnection; +@property (readonly) OTFollowup *followupHandler; + +@property (readonly) NSString *containerName; +@property (readonly) NSString *contextID; +@property (readonly) NSString *altDSID; +@property (nonatomic,strong) NSString *_Nullable pairingUUID; +@property (nonatomic, readonly) CKKSLockStateTracker *lockStateTracker; +@property (nonatomic, readonly) OTCuttlefishAccountStateHolder* accountMetadataStore; +@property (readonly) OctagonStateMachine* stateMachine; +@property (readonly) BOOL postedRepairCFU; +@property (readonly) BOOL postedEscrowRepairCFU; +@property (readonly) BOOL postedRecoveryKeyCFU; +@property (nullable, nonatomic) CKKSNearFutureScheduler* apsRateLimiter; + +@property (readonly, nullable) CKKSViewManager* viewManager; + +// Dependencies (for injection) +@property id authKitAdapter; + +@property dispatch_queue_t queue; + +- (instancetype)initWithContainerName:(NSString*)containerName + contextID:(NSString*)contextID + cuttlefish:(id)cuttlefish + sosAdapter:(id)sosAdapter + authKitAdapter:(id)authKitAdapter + ckksViewManager:(CKKSViewManager* _Nullable)viewManager + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + accountStateTracker:(id)accountStateTracker + deviceInformationAdapter:(id)deviceInformationAdapter + apsConnectionClass:(Class)apsConnectionClass + escrowRequestClass:(Class)escrowRequestClass + cdpd:(id)cdpd; + +// Call one of these when the account state changes. OTCuttlefishContext is responsible for maintaining this state across daemon restarts. +- (BOOL)accountAvailable:(NSString*)altDSID error:(NSError**)error; +- (BOOL)accountNoLongerAvailable:(NSError**)error; +- (BOOL)idmsTrustLevelChanged:(NSError**)error; + +- (void)startOctagonStateMachine; +- (void)handlePairingRestart:(OTJoiningConfiguration*)config; + +- (void)rpcPrepareIdentityAsApplicantWithConfiguration:(OTJoiningConfiguration*)config + epoch:(uint64_t)epoch + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply; +- (void)rpcJoin:(NSData*)vouchData + vouchSig:(NSData*)vouchSig +preapprovedKeys:(NSArray* _Nullable)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)rpcResetAndEstablish:(nonnull void (^)(NSError * _Nullable))reply; + +- (void)localReset:(nonnull void (^)(NSError * _Nullable))reply; + +- (void)rpcEstablish:(nonnull NSString *)altDSID + reply:(nonnull void (^)(NSError * _Nullable))reply; + +- (void)rpcLeaveClique:(nonnull void (^)(NSError * _Nullable))reply; + + +-(void)joinWithBottle:(NSString*)bottleID + entropy:(NSData *)entropy + bottleSalt:(NSString *)bottleSalt + reply:(void (^)(NSError * _Nullable error))reply; + +-(void)joinWithRecoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable error))reply; + +- (void)rpcRemoveFriendsInClique:(NSArray*)peerIDs + reply:(void (^)(NSError*))reply; + +- (void)notifyContainerChange:(APSIncomingMessage* _Nullable)notification; +- (void)notifyContainerChangeWithUserInfo:(NSDictionary*)userInfo; + +- (void)rpcStatus:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply; +- (void)rpcFetchEgoPeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))reply; +- (void)rpcTrustStatus:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus status, + NSString* _Nullable peerID, + NSDictionary* _Nullable peerCountByModelID, + BOOL isExcluded, + NSError * _Nullable))reply; +- (void)rpcFetchDeviceNamesByPeerID:(void (^)(NSDictionary* _Nullable peers, NSError* _Nullable error))reply; +- (void)rpcFetchAllViableBottles:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray* _Nullable sortedPartialEscrowRecordIDs, NSError* _Nullable error))reply; +- (void)fetchEscrowContents:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply; +- (void)rpcSetRecoveryKey:(NSString*)recoveryKey reply:(void (^)(NSError * _Nullable error))reply; + +- (void)requestTrustedDeviceListRefresh; + +- (OTDeviceInformation*)prepareInformation; + +// called when circle changed notification fires +- (void) moveToCheckTrustedState; + +- (OTOperationDependencies*)operationDependencies; + +- (void)attemptSOSUpgrade:(void (^)(NSError* _Nullable error))reply; + +- (void)waitForOctagonUpgrade:(void (^)(NSError* error))reply; + +- (void)clearPendingCFUFlags; + +// For testing. +- (void)setPostedBool:(BOOL)posted; +- (OTAccountMetadataClassC_AccountState)currentMemoizedAccountState; +- (OTAccountMetadataClassC_TrustState)currentMemoizedTrustState; +- (NSDate* _Nullable) currentMemoizedLastHealthCheck; +- (void) checkTrustStatusAndPostRepairCFUIfNecessary:(void (^ _Nullable)(CliqueStatus status, BOOL posted, BOOL hasIdentity, NSError * _Nullable error))reply; +- (void) setAccountStateHolder:(OTCuttlefishAccountStateHolder*)accountMetadataStore; + +// Octagon Health Check Helpers +- (void)checkOctagonHealth:(BOOL)skipRateLimitingCheck reply:(void (^)(NSError * _Nullable error))reply; +- (BOOL)postRepairCFU:(NSError**)error; +- (void)postConfirmPasscodeCFU:(NSError**)error; +- (void)postRecoveryKeyCFU:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END +#endif // OTCUTTLEFISH_CONTEXT +#endif + diff --git a/keychain/ot/OTCuttlefishContext.m b/keychain/ot/OTCuttlefishContext.m new file mode 100644 index 00000000..b8fd2275 --- /dev/null +++ b/keychain/ot/OTCuttlefishContext.m @@ -0,0 +1,2682 @@ +/* + * 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 OCTAGON + +#include + +#import + +#import + +#include +#include +#import + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ckks/CKKSResultOperation.h" + +#import "keychain/ckks/OctagonAPSReceiver.h" +#import "keychain/analytics/CKKSLaunchSequence.h" +#import "keychain/ot/OTDeviceInformationAdapter.h" + + +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" +#import "keychain/ot/OctagonCheckTrustStateOperation.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/OTFollowup.h" +#import "keychain/ot/OTAuthKitAdapter.h" +#import "keychain/ot/OTContext.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTClique.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTPrepareOperation.h" +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OTSOSUpgradeOperation.h" +#import "keychain/ot/OTUpdateTPHOperation.h" +#import "keychain/ot/OTEpochOperation.h" +#import "keychain/ot/OTClientVoucherOperation.h" +#import "keychain/ot/OTLeaveCliqueOperation.h" +#import "keychain/ot/OTRemovePeersOperation.h" +#import "keychain/ot/OTJoinWithVoucherOperation.h" +#import "keychain/ot/OTVouchWithBottleOperation.h" +#import "keychain/ot/OTVouchWithRecoveryKeyOperation.h" +#import "keychain/ot/OTEstablishOperation.h" +#import "keychain/ot/OTLocalCKKSResetOperation.h" +#import "keychain/ot/OTUpdateTrustedDeviceListOperation.h" +#import "keychain/ot/OTSOSUpdatePreapprovalsOperation.h" +#import "keychain/ot/OTResetOperation.h" +#import "keychain/ot/OTLocalCuttlefishReset.h" +#import "keychain/ot/OTSetRecoveryKeyOperation.h" +#import "keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h" +#import "keychain/ot/OTUploadNewCKKSTLKsOperation.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import "keychain/ot/OTTriggerEscrowUpdateOperation.h" +#import "keychain/ot/OTCheckHealthOperation.h" +#import "keychain/ot/OTEnsureOctagonKeyConsistency.h" +#import "keychain/ot/OTDetermineHSA2AccountStatusOperation.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" + +#if TARGET_OS_WATCH +#import "keychain/otpaird/OTPairingClient.h" +#endif /* TARGET_OS_WATCH */ + +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSKeychainView.h" + +#import "utilities/SecTapToRadar.h" + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import +#import + +NSString* OTCuttlefishContextErrorDomain = @"otcuttlefish"; +static dispatch_time_t OctagonStateTransitionDefaultTimeout = 10*NSEC_PER_SEC; + +@class CKKSLockStateTracker; + +@interface OTCuttlefishContext () +{ + NSData* _vouchData; + NSData* _vouchSig; + NSString* _bottleID; + NSString* _bottleSalt; + NSData* _entropy; + NSArray* _preapprovedKeys; + NSString* _recoveryKey; + BOOL _skipRateLimitingCheck; +} + +@property CKKSLaunchSequence* launchSequence; +@property NSOperationQueue* operationQueue; +@property (nonatomic, strong) OTCuttlefishAccountStateHolder *accountMetadataStore; +@property OTFollowup *followupHandler; + +@property (readonly) id accountStateTracker; +@property CKAccountInfo* cloudKitAccountInfo; +@property CKKSCondition *cloudKitAccountStateKnown; + +@property BOOL getViewsSuccess; + +@property CKKSNearFutureScheduler* suggestTLKUploadNotifier; + +// Dependencies (for injection) +@property id sosAdapter; +@property id octagonAdapter; +@property id deviceAdapter; +@property (readonly) Class apsConnectionClass; +@property (readonly) Class escrowRequestClass; + +@property (nonatomic) BOOL postedRepairCFU; +@property (nonatomic) BOOL postedEscrowRepairCFU; +@property (nonatomic) BOOL postedRecoveryKeyCFU; + +@property (nonatomic) BOOL initialBecomeUntrustedPosted; + +@end + +@implementation OTCuttlefishContext + +- (instancetype)initWithContainerName:(NSString*)containerName + contextID:(NSString*)contextID + cuttlefish:(id)cuttlefish + sosAdapter:(id)sosAdapter + authKitAdapter:(id)authKitAdapter + ckksViewManager:(CKKSViewManager* _Nullable)viewManager + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + accountStateTracker:(id)accountStateTracker + deviceInformationAdapter:(id)deviceInformationAdapter + apsConnectionClass:(Class)apsConnectionClass + escrowRequestClass:(Class)escrowRequestClass + cdpd:(id)cdpd +{ + if ((self = [super init])) { + WEAKIFY(self); + + _containerName = containerName; + _contextID = contextID; + + _viewManager = viewManager; + _postedRepairCFU = NO; + _postedRecoveryKeyCFU = NO; + _postedEscrowRepairCFU = NO; + + _initialBecomeUntrustedPosted = NO; + + _apsConnectionClass = apsConnectionClass; + _launchSequence = [[CKKSLaunchSequence alloc] initWithRocketName:@"com.apple.octagon.launch"]; + + _queue = dispatch_queue_create("com.apple.security.otcuttlefishcontext", DISPATCH_QUEUE_SERIAL); + _operationQueue = [[NSOperationQueue alloc] init]; + _cloudKitAccountStateKnown = [[CKKSCondition alloc] init]; + + _accountMetadataStore = [[OTCuttlefishAccountStateHolder alloc] initWithQueue:_queue + container:_containerName + context:_contextID]; + [_accountMetadataStore registerNotification:self]; + + _stateMachine = [[OctagonStateMachine alloc] initWithName:@"octagon" + states:[NSSet setWithArray:[OctagonStateMap() allKeys]] + initialState:OctagonStateInitializing + queue:_queue + stateEngine:self + lockStateTracker:lockStateTracker]; + + _sosAdapter = sosAdapter; + [_sosAdapter registerForPeerChangeUpdates:self]; + _authKitAdapter = authKitAdapter; + _deviceAdapter = deviceInformationAdapter; + _cuttlefishXPCConnection = cuttlefish; + _lockStateTracker = lockStateTracker; + _accountStateTracker = accountStateTracker; + + _followupHandler = [[OTFollowup alloc] initWithFollowupController:cdpd]; + + [accountStateTracker registerForNotificationsOfCloudKitAccountStatusChange:self]; + [_authKitAdapter registerNotification:self]; + + _escrowRequestClass = escrowRequestClass; + + _suggestTLKUploadNotifier = [[CKKSNearFutureScheduler alloc] initWithName:@"octagon-tlk-request" + delay:500*NSEC_PER_MSEC + keepProcessAlive:false + dependencyDescriptionCode:0 + block:^{ + STRONGIFY(self); + secnotice("octagon-ckks", "Adding flag for CKKS TLK upload"); + [self.stateMachine handleFlag:OctagonFlagCKKSRequestsTLKUpload]; + }]; + } + return self; +} + +- (void)dealloc +{ + // TODO: how to invalidate this? + //[self.cuttlefishXPCConnection invalidate]; +} + +- (void)notifyTrustChanged:(OTAccountMetadataClassC_TrustState)trustState { + + secnotice("octagon", "Changing trust status to: %@", + (trustState == OTAccountMetadataClassC_TrustState_TRUSTED) ? @"Trusted" : @"Untrusted"); + + /* + * We are posting the legacy SOS notification if we don't use SOS + * need to rework clients to use a new signal instead of SOS. + */ + if (!OctagonPlatformSupportsSOS()) { + notify_post(kSOSCCCircleChangedNotification); + } + + notify_post(OTTrustStatusChangeNotification); +} + +- (void)accountStateUpdated:(OTAccountMetadataClassC*)newState from:(OTAccountMetadataClassC *)oldState +{ + if (newState.icloudAccountState == OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE && oldState.icloudAccountState != OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE) { + [self.launchSequence addEvent:@"iCloudAccount"]; + } + + if (newState.trustState == OTAccountMetadataClassC_TrustState_TRUSTED && oldState.trustState != OTAccountMetadataClassC_TrustState_TRUSTED) { + [self.launchSequence addEvent:@"Trusted"]; + } + if (newState.trustState != OTAccountMetadataClassC_TrustState_TRUSTED && oldState.trustState == OTAccountMetadataClassC_TrustState_TRUSTED) { + [self.launchSequence addEvent:@"Untrusted"]; + [self notifyTrustChanged:newState.trustState]; + } +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.containerName, self.contextID]; +} + +- (void)machinesAdded:(NSArray*)machineIDs altDSID:(NSString*)altDSID +{ + WEAKIFY(self); + dispatch_sync(self.queue, ^{ + NSError* metadataError = nil; + OTAccountMetadataClassC* accountMetadata = [self.accountMetadataStore _onqueueLoadOrCreateAccountMetadata:&metadataError]; + + if(!accountMetadata || metadataError) { + secerror("octagon-authkit: Unable to load account metadata: %@", metadataError); + [self requestTrustedDeviceListRefresh]; + return; + } + + if(!altDSID || ![accountMetadata.altDSID isEqualToString:altDSID]) { + secnotice("octagon-authkit", "Machines-added push is for wrong altDSID (%@); current altDSID (%@)", altDSID, accountMetadata.altDSID); + return; + } + + secnotice("octagon-authkit", "adding machines for altDSID(%@): %@", altDSID, machineIDs); + + [[self.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon-authkit: Can't talk with TrustedPeersHelper: %@", error); + }] addAllowedMachineIDsWithContainer:self.containerName + context:self.contextID + machineIDs:machineIDs + reply:^(NSError* error) { + if (error) { + secerror("octagon-authkit: addAllow errored: %@", error); + STRONGIFY(self); + [self requestTrustedDeviceListRefresh]; + } else { + secnotice("octagon-authkit", "addAllow succeeded"); + + OctagonPendingFlag *pendingFlag = [[OctagonPendingFlag alloc] initWithFlag:OctagonFlagCuttlefishNotification + conditions:OctagonPendingConditionsDeviceUnlocked]; + [self.stateMachine handlePendingFlag:pendingFlag]; + } + }]; + }); +} + +- (void)machinesRemoved:(NSArray*)machineIDs altDSID:(NSString*)altDSID +{ + WEAKIFY(self); + dispatch_sync(self.queue, ^{ + NSError* metadataError = nil; + OTAccountMetadataClassC* accountMetadata = [self.accountMetadataStore _onqueueLoadOrCreateAccountMetadata:&metadataError]; + + if(!accountMetadata || metadataError) { + secerror("octagon-authkit: Unable to load account metadata: %@", metadataError); + [self requestTrustedDeviceListRefresh]; + return; + } + + if(!altDSID || ![accountMetadata.altDSID isEqualToString:altDSID]) { + secnotice("octagon-authkit", "Machines-removed push is for wrong altDSID (%@); current altDSID (%@)", altDSID, accountMetadata.altDSID); + return; + } + + secnotice("octagon-authkit", "removing machines for altDSID(%@): %@", altDSID, machineIDs); + + [[self.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon-authkit: Can't talk with TrustedPeersHelper: %@", error); + }] removeAllowedMachineIDsWithContainer:self.containerName + context:self.contextID + machineIDs:machineIDs + reply:^(NSError* _Nullable error) { + STRONGIFY(self); + if (error) { + secerror("octagon-authkit: removeAllow errored: %@", error); + } else { + secnotice("octagon-authkit", "removeAllow succeeded"); + } + + // We don't necessarily trust remove pushes; they could be delayed past when an add has occurred. + // Request that the full list be rechecked. + [self requestTrustedDeviceListRefresh]; + }]; + }); +} + +- (void)incompleteNotificationOfMachineIDListChange +{ + secnotice("octagon", "incomplete machine ID list notification -- refreshing device list"); + [self requestTrustedDeviceListRefresh]; +} + + +- (void)cloudkitAccountStateChange:(CKAccountInfo* _Nullable)oldAccountInfo + to:(CKAccountInfo*)currentAccountInfo +{ + dispatch_sync(self.queue, ^{ + // We don't persist the CK account state; rather, we fetch it anew on every daemon launch. + // But, we also have to integrate it into our asynchronous state machine. + // So, record the current CK account value, and trigger state machine reprocessing. + + secnotice("octagon", "Told of a new CK account status: %@", currentAccountInfo); + self.cloudKitAccountInfo = currentAccountInfo; + [self.stateMachine _onqueuePokeStateMachine]; + + // But, having the state machine perform the signout is confusing: it would need to make decisions based + // on things other than the current state. So, use the RPC mechanism to give it input. + // If we receive a sign-in before the sign-out rpc runs, the state machine will be sufficient to get back into + // the in-account state. + + // Also let other clients now that we have CK account status + [self.cloudKitAccountStateKnown fulfill]; + }); + + if(!(currentAccountInfo.accountStatus == CKAccountStatusAvailable)) { + secnotice("octagon", "Informed that the CK account is now unavailable: %@", currentAccountInfo); + + // Add a state machine request to return to OctagonStateWaitingForCloudKitAccount + [self.stateMachine doSimpleStateMachineRPC:@"cloudkit-account-gone" + op:[OctagonStateTransitionOperation named:@"cloudkit-account-gone" + entering:OctagonStateWaitingForCloudKitAccount] + sourceStates:OctagonInAccountStates() + reply:^(NSError* error) {}]; + } +} + +- (BOOL)accountAvailable:(NSString*)altDSID error:(NSError**)error +{ + __block NSError* localError = nil; + secnotice("octagon", "Account available with altDSID: %@ %@", altDSID, self); + + self.launchSequence.firstLaunch = true; + + dispatch_sync(self.queue, ^{ + [self.accountMetadataStore _onqueuePersistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + // Do not set the account available bit here, since we need to check if it's HSA2. The initializing state should do that for us... + metadata.altDSID = altDSID; + + return metadata; + } error:&localError]; + + if(localError) { + secerror("octagon: unable to persist new account availability: %@", localError); + } + }); + + [self.stateMachine handleFlag:OctagonFlagAccountIsAvailable]; + + if(localError) { + if(error) { + *error = localError; + } + return NO; + } + return YES; +} +- (void) moveToCheckTrustedState +{ + CKKSResultOperation* checkTrust + = [OctagonStateTransitionOperation named:[NSString stringWithFormat:@"%@", @"check-trust-state"] + entering:OctagonStateCheckTrustState]; + + NSSet* sourceStates = [NSSet setWithArray: @[OctagonStateUntrusted]]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"check-trust-state" + sourceStates:sourceStates + serialQueue:self.queue + timeout:OctagonStateTransitionDefaultTimeout + transitionOp:checkTrust]; + [self.stateMachine handleExternalRequest:request]; +} + + +- (BOOL)idmsTrustLevelChanged:(NSError**)error +{ + // Cool! If we believe there's no sufficient iCloud account, let's try checking again + CKKSResultOperation* checkHSA2 = [OctagonStateTransitionOperation named:[NSString stringWithFormat:@"%@", @"check-hsa2-status"] + entering:OctagonStateDetermineiCloudAccountState]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"check-hsa2-state" + sourceStates:[NSSet setWithArray: @[OctagonStateWaitForHSA2]] + serialQueue:self.queue + timeout:OctagonStateTransitionDefaultTimeout + transitionOp:checkHSA2]; + [self.stateMachine handleExternalRequest:request]; + return YES; +} + +- (BOOL)accountNoLongerAvailable:(NSError**)error +{ + OctagonStateTransitionOperation* attemptOp = [OctagonStateTransitionOperation named:@"octagon-account-gone" + intending:OctagonStateNoAccountDoReset + errorState:OctagonStateNoAccountDoReset + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + __block NSError* localError = nil; + + secnotice("octagon", "Account now unavailable: %@", self); + [self.accountMetadataStore persistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT; + metadata.altDSID = nil; + metadata.trustState = OTAccountMetadataClassC_TrustState_UNKNOWN; + + return metadata; + } error:&localError]; + + if(localError) { + secerror("octagon: unable to persist new account availability: %@", localError); + } + + [self.accountStateTracker setHSA2iCloudAccountStatus:CKKSAccountStatusNoAccount]; + + // Bring CKKS down, too + for (id key in self.viewManager.views) { + CKKSKeychainView* view = self.viewManager.views[key]; + secnotice("octagon-ckks", "Informing %@ of new untrusted status (due to account disappearance)", view); + [view endTrustedOperation]; + } + + op.error = localError; + }]; + + // Signout works from literally any state. Goodbye, account! + NSSet* sourceStates = [NSSet setWithArray: OctagonStateMap().allKeys]; + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"account-not-available" + sourceStates:sourceStates + serialQueue:self.queue + timeout:OctagonStateTransitionDefaultTimeout + transitionOp:attemptOp]; + [self.stateMachine handleExternalRequest:request]; + + return YES; +} + +- (void)resetOctagonStateMachine +{ + OctagonStateTransitionOperation* op = [OctagonStateTransitionOperation named:@"resetting-state-machine" + entering:OctagonStateInitializing]; + NSMutableSet* sourceStates = [NSMutableSet setWithArray: OctagonStateMap().allKeys]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"resetting-state-machine" + sourceStates:sourceStates + serialQueue:self.queue + timeout:OctagonStateTransitionDefaultTimeout + transitionOp:op]; + + [self.stateMachine handleExternalRequest:request]; + +} + +- (void)localReset:(nonnull void (^)(NSError * _Nullable))reply +{ + OTLocalResetOperation* pendingOp = [[OTLocalResetOperation alloc] init:self.containerName + contextID:self.contextID + intendedState:OctagonStateBecomeUntrusted + errorState:OctagonStateError + cuttlefishXPC:self.cuttlefishXPCConnection]; + + NSMutableSet* sourceStates = [NSMutableSet setWithArray: OctagonStateMap().allKeys]; + [self.stateMachine doSimpleStateMachineRPC:@"local-reset" op:pendingOp sourceStates:sourceStates reply:reply]; +} + +- (NSDictionary*)establishStatePathDictionary +{ + return @{ + OctagonStateReEnactDeviceList: @{ + OctagonStateReEnactPrepare: @{ + OctagonStateReEnactReadyToEstablish: @{ + OctagonStateEscrowTriggerUpdate: @{ + OctagonStateBecomeReady: @{ + OctagonStateReady: [OctagonStateTransitionPathStep success], + }, + }, + + // Error handling extra states: + OctagonStateEstablishCKKSReset: @{ + OctagonStateEstablishAfterCKKSReset: @{ + OctagonStateEscrowTriggerUpdate: @{ + OctagonStateBecomeReady: @{ + OctagonStateReady: [OctagonStateTransitionPathStep success], + }, + }, + }, + }, + }, + }, + }, + }; +} + +- (void)rpcEstablish:(nonnull NSString *)altDSID + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + // The reset flow can split into an error-handling path halfway through; this is okay + OctagonStateTransitionPath* path = [OctagonStateTransitionPath pathFromDictionary:[self establishStatePathDictionary]]; + + [self.stateMachine doWatchedStateMachineRPC:@"establish" + sourceStates:OctagonInAccountStates() + path:path + reply:reply]; +} + +- (void)rpcResetAndEstablish:(nonnull void (^)(NSError * _Nullable))reply +{ + // The reset flow can split into an error-handling path halfway through; this is okay + OctagonStateTransitionPath* path = [OctagonStateTransitionPath pathFromDictionary: @{ + OctagonStateResetBecomeUntrusted: @{ + OctagonStateResetAndEstablish: @{ + OctagonStateResetAnyMissingTLKCKKSViews: [self establishStatePathDictionary] + }, + }, + }]; + + // Now, take the state machine from any in-account state to the beginning of the reset flow. + [self.stateMachine doWatchedStateMachineRPC:@"rpc-reset-and-establish" + sourceStates:OctagonInAccountStates() + path:path + reply:reply]; +} + +- (void)rpcLeaveClique:(nonnull void (^)(NSError * _Nullable))reply +{ + OTLeaveCliqueOperation* op = [[OTLeaveCliqueOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeUntrusted + errorState:OctagonStateError]; + + NSSet* sourceStates = [NSSet setWithObject: OctagonStateReady]; + [self.stateMachine doSimpleStateMachineRPC:@"leave-clique" op:op sourceStates:sourceStates reply:reply]; +} + +- (void)rpcRemoveFriendsInClique:(NSArray*)peerIDs + reply:(void (^)(NSError*))reply +{ + OTRemovePeersOperation* op = [[OTRemovePeersOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + errorState:OctagonStateBecomeReady + peerIDs:peerIDs]; + + NSSet* sourceStates = [NSSet setWithObject: OctagonStateReady]; + [self.stateMachine doSimpleStateMachineRPC:@"remove-friends" op:op sourceStates:sourceStates reply:reply]; +} + +- (OTDeviceInformation*)prepareInformation +{ + NSError* error = nil; + NSString* machineID = [self.authKitAdapter machineID:&error]; + + if(!machineID || error) { + secerror("octagon: Unable to fetch machine ID; expect signin to fail: %@", error); + } + + return [[OTDeviceInformation alloc] initForContainerName:self.containerName + contextID:self.contextID + epoch:0 + machineID:machineID + modelID:self.deviceAdapter.modelID + deviceName:self.deviceAdapter.deviceName + serialNumber:self.deviceAdapter.serialNumber + osVersion:self.deviceAdapter.osVersion]; +} + +- (OTOperationDependencies*)operationDependencies +{ + return [[OTOperationDependencies alloc] initForContainer:self.containerName + contextID:self.contextID + stateHolder:self.accountMetadataStore + flagHandler:self.stateMachine + sosAdapter:self.sosAdapter + octagonAdapter:self.octagonAdapter + authKitAdapter:self.authKitAdapter + viewManager:self.viewManager + lockStateTracker:self.lockStateTracker + cuttlefishXPC:self.cuttlefishXPCConnection + escrowRequestClass:self.escrowRequestClass]; +} + +- (void)startOctagonStateMachine +{ + [self.stateMachine startOperation]; +} + +- (void)handlePairingRestart:(OTJoiningConfiguration*)config +{ + if(self.pairingUUID == nil){ + secnotice("octagon-pairing", "received new pairing UUID (%@)", config.pairingUUID); + self.pairingUUID = config.pairingUUID; + } + + if(![self.pairingUUID isEqualToString:config.pairingUUID]){ + secnotice("octagon-pairing", "current pairing UUID (%@) does not match config UUID (%@)", self.pairingUUID, config.pairingUUID); + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [self localReset:^(NSError * _Nullable localResetError) { + if(localResetError) { + secerror("localReset returned an error: %@", localResetError); + }else{ + secnotice("octagon", "localReset succeeded"); + self.pairingUUID = config.pairingUUID; + } + dispatch_semaphore_signal(sema); + }]; + if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 10))) { + secerror("octagon: Timed out waiting for local reset to complete"); + } + } +} + +#pragma mark --- State Machine Transitions + +- (CKKSResultOperation* _Nullable)_onqueueNextStateMachineTransition:(OctagonState*)currentState + flags:(nonnull OctagonFlags *)flags + pendingFlags:(nonnull id)pendingFlagHandler +{ + dispatch_assert_queue(self.queue); + + WEAKIFY(self); + + [self.launchSequence addEvent:currentState]; + + // If We're initializing, or there was some recent update to the account state, + // attempt to see what state we should enter. + if([currentState isEqualToString: OctagonStateInitializing]) { + return [self initializingOperation]; + } + + if([currentState isEqualToString:OctagonStateWaitForHSA2]) { + secnotice("octagon", "Waiting for an HSA2 account"); + return nil; + } + + if([currentState isEqualToString:OctagonStateWaitingForCloudKitAccount]) { + // Here, integrate the memoized CK account state into our state machine + if(self.cloudKitAccountInfo && self.cloudKitAccountInfo.accountStatus == CKAccountStatusAvailable) { + secnotice("octagon", "CloudKit reports an account is available!"); + return [OctagonStateTransitionOperation named:@"ck-available" + entering:OctagonStateCloudKitNewlyAvailable]; + } else { + secnotice("octagon", "Waiting for a CloudKit account; current state is %@", self.cloudKitAccountInfo ?: @"uninitialized"); + return nil; + } + } + + if([currentState isEqualToString:OctagonStateCloudKitNewlyAvailable]) { + return [self cloudKitAccountNewlyAvailableOperation]; + } + + if([currentState isEqualToString:OctagonStateCheckTrustState]) { + return [[OctagonCheckTrustStateOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeUntrusted + errorState:OctagonStateBecomeUntrusted]; + } +#pragma mark --- Octagon Health Check States + if([currentState isEqualToString:OctagonStateHSA2HealthCheck]) { + return [[OTDetermineHSA2AccountStatusOperation alloc] initWithDependencies:self.operationDependencies + stateIfHSA2:OctagonStateSecurityTrustCheck + stateIfNotHSA2:OctagonStateWaitForHSA2 + stateIfNoAccount:OctagonStateNoAccount + errorState:OctagonStateError]; + } + + if([currentState isEqualToString:OctagonStateSecurityTrustCheck]) { + return [self evaluateSecdOctagonTrust]; + } + + if([currentState isEqualToString:OctagonStateTPHTrustCheck]) { + return [self evaluateTPHOctagonTrust]; + } + + if([currentState isEqualToString:OctagonStateCuttlefishTrustCheck]) { + return [self cuttlefishTrustEvaluation]; + } + + if ([currentState isEqualToString:OctagonStatePostRepairCFU]) { + return [self postRepairCFUAndBecomeUntrusted]; + } + +#pragma mark --- Watch Pairing States + +#if TARGET_OS_WATCH + if([currentState isEqualToString:OctagonStateStartCompanionPairing]) { + return [self startCompanionPairingOperation]; + } +#endif /* TARGET_OS_WATCH */ + + if([currentState isEqualToString:OctagonStateBecomeUntrusted]) { + return [self becomeUntrustedOperation:OctagonStateUntrusted]; + } + + if([currentState isEqualToString:OctagonStateBecomeReady]) { + return [self becomeReadyOperation]; + } + + if([currentState isEqualToString:OctagonStateNoAccount]) { + // We only want to move out of untrusted if something useful has happened! + if([flags _onqueueContains:OctagonFlagAccountIsAvailable]) { + [flags _onqueueRemoveFlag:OctagonFlagAccountIsAvailable]; + secnotice("octagon", "Account is available! Attempting initializing op!"); + return [OctagonStateTransitionOperation named:@"account-probably-present" + entering:OctagonStateInitializing]; + } + } + + if([currentState isEqualToString:OctagonStateUntrusted]) { + // We only want to move out of untrusted if something useful has happened! + if([flags _onqueueContains:OctagonFlagEgoPeerPreapproved]) { + [flags _onqueueRemoveFlag:OctagonFlagEgoPeerPreapproved]; + if(self.sosAdapter.sosEnabled) { + secnotice("octagon", "Preapproved flag is high. Attempt SOS upgrade again!"); + return [OctagonStateTransitionOperation named:@"ck-available" + entering:OctagonStateAttemptSOSUpgrade]; + + } else { + secnotice("octagon", "We are untrusted, but it seems someone preapproves us now. Unfortunately, this platform doesn't support SOS."); + } + } + + if([flags _onqueueContains:OctagonFlagAttemptSOSUpgrade]) { + [flags _onqueueRemoveFlag:OctagonFlagAttemptSOSUpgrade]; + if(self.sosAdapter.sosEnabled) { + secnotice("octagon", "Attempt SOS upgrade again!"); + return [OctagonStateTransitionOperation named:@"attempt-sos-upgrade" + entering:OctagonStateAttemptSOSUpgrade]; + + } else { + secnotice("octagon", "We are untrusted, but this platform doesn't support SOS."); + } + } + + if([flags _onqueueContains:OctagonFlagCuttlefishNotification]) { + [flags _onqueueRemoveFlag:OctagonFlagCuttlefishNotification]; + secnotice("octagon", "Updating TPH (while untrusted) due to push"); + return [OctagonStateTransitionOperation named:@"untrusted-update" + entering:OctagonStateUntrustedUpdated]; + } + } + + if([currentState isEqualToString:OctagonStateUntrustedUpdated]) { + return [[OTUpdateTPHOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateUntrusted + errorState:OctagonStateError + retryFlag:OctagonFlagCuttlefishNotification]; + } + + if([currentState isEqualToString:OctagonStateDetermineiCloudAccountState]) { + secnotice("octagon", "Determine iCloud account status"); + + // TODO replace with OTDetermineHSA2AccountStatusOperation in Octagon: ensure Octagon operations can't occur on SA accounts + return [OctagonStateTransitionOperation named:@"octagon-determine-icloud-state" + intending:OctagonStateNoAccount + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + STRONGIFY(self); + + NSString* primaryAccountAltDSID = self.authKitAdapter.primaryiCloudAccountAltDSID; + + dispatch_sync(self.queue, ^{ + NSError* error = nil; + + if(primaryAccountAltDSID != nil) { + secnotice("octagon", "iCloud account is present; checking HSA2 status"); + + bool hsa2 = [self.authKitAdapter accountIsHSA2ByAltDSID:primaryAccountAltDSID]; + secnotice("octagon", "HSA2 is %@", hsa2 ? @"enabled" : @"disabled"); + + [self.accountMetadataStore _onqueuePersistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) { + if(hsa2) { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE; + } else { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT; + } + metadata.altDSID = primaryAccountAltDSID; + return metadata; + } error:&error]; + + // If there's an HSA2 account, return to 'initializing' here, as we want to centralize decisions on what to do next + if(hsa2) { + op.nextState = OctagonStateInitializing; + } else { + [self.accountStateTracker setHSA2iCloudAccountStatus:CKKSAccountStatusNoAccount]; + op.nextState = OctagonStateWaitForHSA2; + } + + } else { + secnotice("octagon", "iCloud account is not present"); + + [self.accountMetadataStore _onqueuePersistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT; + metadata.altDSID = nil; + return metadata; + } error:&error]; + + op.nextState = OctagonStateNoAccount; + } + + if(error) { + secerror("octagon: unable to save new account state: %@", error); + } + }); + }]; + } + + if([currentState isEqualToString:OctagonStateNoAccountDoReset]) { + secnotice("octagon", "Attempting local-reset as part of signout"); + return [[OTLocalResetOperation alloc] init:self.containerName + contextID:self.contextID + intendedState:OctagonStateNoAccount + errorState:OctagonStateNoAccount + cuttlefishXPC:self.cuttlefishXPCConnection]; + } + + if([currentState isEqualToString:OctagonStateEnsureConsistency]) { + + secnotice("octagon", "Ensuring consistency of things that might've changed"); + if(self.sosAdapter.sosEnabled) { + return [[OTEnsureOctagonKeyConsistency alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateEnsureUpdatePreapprovals + errorState:OctagonStateBecomeReady]; + } + + // Add further consistency checks here. + return [OctagonStateTransitionOperation named:@"no-consistency-checks" + entering:OctagonStateBecomeReady]; + } + + if([currentState isEqualToString:OctagonStateEnsureUpdatePreapprovals]) { + secnotice("octagon", "SOS is enabled; ensuring preapprovals are correct"); + return [[OTSOSUpdatePreapprovalsOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + sosNotPresentState:OctagonStateBecomeReady + errorState:OctagonStateBecomeReady]; + } + + if([currentState isEqualToString:OctagonStateAttemptSOSUpgrade] && OctagonPerformSOSUpgrade()) { + secnotice("octagon", "Investigating SOS status"); + return [[OTSOSUpgradeOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + ckksConflictState:OctagonStateSOSUpgradeCKKSReset + errorState:OctagonStateBecomeUntrusted + deviceInfo:self.prepareInformation]; + + } else if([currentState isEqualToString:OctagonStateSOSUpgradeCKKSReset]) { + return [[OTLocalCKKSResetOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateSOSUpgradeAfterCKKSReset + errorState:OctagonStateBecomeUntrusted]; + + } else if([currentState isEqualToString:OctagonStateSOSUpgradeAfterCKKSReset]) { + return [[OTSOSUpgradeOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + ckksConflictState:OctagonStateBecomeUntrusted + errorState:OctagonStateBecomeUntrusted + deviceInfo:self.prepareInformation]; + + + } else if([currentState isEqualToString:OctagonStateCreateIdentityForRecoveryKey]) { + OTPrepareOperation* op = [[OTPrepareOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateVouchWithRecoveryKey + errorState:OctagonStateBecomeUntrusted + deviceInfo:[self prepareInformation] + epoch:1]; + return op; + + } else if([currentState isEqualToString:OctagonStateInitiatorCreateIdentity]) { + OTPrepareOperation* op = [[OTPrepareOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateInitiatorVouchWithBottle + errorState:OctagonStateBecomeUntrusted + deviceInfo:[self prepareInformation] + epoch:1]; + return op; + + } else if([currentState isEqualToString:OctagonStateInitiatorVouchWithBottle]) { + OTVouchWithBottleOperation* pendingOp = [[OTVouchWithBottleOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateInitiatorUpdateDeviceList + errorState:OctagonStateBecomeUntrusted + bottleID:_bottleID + entropy:_entropy + bottleSalt:_bottleSalt]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"vouchWithBottle-callback" + withBlock:^{ + secnotice("otrpc", "Returning a vouch with bottle call: %@, %@ %@", pendingOp.voucher, pendingOp.voucherSig, pendingOp.error); + self->_vouchSig = pendingOp.voucherSig; + self->_vouchData = pendingOp.voucher; + }]; + [callback addDependency:pendingOp]; + [self.operationQueue addOperation: callback]; + + return pendingOp; + + } else if([currentState isEqualToString:OctagonStateVouchWithRecoveryKey]) { + OTVouchWithRecoveryKeyOperation* pendingOp = [[OTVouchWithRecoveryKeyOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateInitiatorUpdateDeviceList + errorState:OctagonStateBecomeUntrusted + recoveryKey:_recoveryKey]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"vouchWithRecoveryKey-callback" + withBlock:^{ + secnotice("otrpc", "Returning a vouch with recovery key call: %@, %@ %@", pendingOp.voucher, pendingOp.voucherSig, pendingOp.error); + self->_vouchSig = pendingOp.voucherSig; + self->_vouchData = pendingOp.voucher; + }]; + [callback addDependency:pendingOp]; + [self.operationQueue addOperation: callback]; + + return pendingOp; + + } else if([currentState isEqualToString:OctagonStateInitiatorUpdateDeviceList]) { + // As part of the 'initiate' flow, we need to update the trusted device list-you're probably on it already + OTUpdateTrustedDeviceListOperation* op = [[OTUpdateTrustedDeviceListOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateInitiatorJoin + listUpdatesState:OctagonStateInitiatorJoin + errorState:OctagonStateError + retryFlag:nil]; + return op; + + } else if ([currentState isEqualToString:OctagonStateInitiatorJoin]){ + OTJoinWithVoucherOperation* op = [[OTJoinWithVoucherOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + ckksConflictState:OctagonStateInitiatorJoinCKKSReset + errorState:OctagonStateError + voucherData:_vouchData + voucherSig:_vouchSig + preapprovedKeys:_preapprovedKeys]; + return op; + + } else if([currentState isEqualToString:OctagonStateInitiatorJoinCKKSReset]) { + return [[OTLocalCKKSResetOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateInitiatorJoinAfterCKKSReset + errorState:OctagonStateBecomeUntrusted]; + + } else if ([currentState isEqualToString:OctagonStateInitiatorJoinAfterCKKSReset]){ + return [[OTJoinWithVoucherOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + ckksConflictState:OctagonStateBecomeUntrusted + errorState:OctagonStateError + voucherData:_vouchData + voucherSig:_vouchSig + preapprovedKeys:_preapprovedKeys]; + + } else if([currentState isEqualToString:OctagonStateResetBecomeUntrusted]) { + return [self becomeUntrustedOperation:OctagonStateResetAndEstablish]; + + } else if([currentState isEqualToString:OctagonStateResetAndEstablish]) { + return [[OTResetOperation alloc] init:self.containerName + contextID:self.contextID + intendedState:OctagonStateResetAnyMissingTLKCKKSViews + errorState:OctagonStateError + cuttlefishXPC:self.cuttlefishXPCConnection]; + + } else if([currentState isEqualToString:OctagonStateResetAnyMissingTLKCKKSViews]) { + return [[OTResetCKKSZonesLackingTLKsOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReEnactDeviceList + errorState:OctagonStateError]; + + } else if([currentState isEqualToString:OctagonStateReEnactDeviceList]) { + return [[OTUpdateTrustedDeviceListOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReEnactPrepare + listUpdatesState:OctagonStateReEnactPrepare + errorState:OctagonStateError + retryFlag:nil]; + + } else if([currentState isEqualToString:OctagonStateReEnactPrepare]) { + // Note: Resetting the account returns epoch to 0. + return [[OTPrepareOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReEnactReadyToEstablish + errorState:OctagonStateError + deviceInfo:[self prepareInformation] + epoch:0]; + + } else if([currentState isEqualToString:OctagonStateReEnactReadyToEstablish]) { + return [[OTEstablishOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateEscrowTriggerUpdate + ckksConflictState:OctagonStateEstablishCKKSReset + errorState:OctagonStateBecomeUntrusted]; + + } else if([currentState isEqualToString:OctagonStateEstablishCKKSReset]) { + return [[OTLocalCKKSResetOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateEstablishAfterCKKSReset + errorState:OctagonStateBecomeUntrusted]; + + } else if([currentState isEqualToString:OctagonStateEstablishAfterCKKSReset]) { + // If CKKS fails again, just go to "become untrusted" + return [[OTEstablishOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateEscrowTriggerUpdate + ckksConflictState:OctagonStateBecomeUntrusted + errorState:OctagonStateBecomeUntrusted]; + + } else if ([currentState isEqualToString:OctagonStateEscrowTriggerUpdate]){ + + return [[OTTriggerEscrowUpdateOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + errorState:OctagonStateError]; + + } else if([currentState isEqualToString: OctagonStateWaitForUnlock]) { + if([flags _onqueueContains:OctagonFlagUnlocked]) { + [flags _onqueueRemoveFlag:OctagonFlagUnlocked]; + return [OctagonStateTransitionOperation named:[NSString stringWithFormat:@"%@", @"initializing-after-unlock"] + entering:OctagonStateInitializing]; + } + + secnotice("octagon", "Requested to enter wait for unlock"); + [pendingFlagHandler _onqueueHandlePendingFlag:[[OctagonPendingFlag alloc] initWithFlag:OctagonFlagUnlocked + conditions:OctagonPendingConditionsDeviceUnlocked]]; + return nil; + + } else if([currentState isEqualToString: OctagonStateUpdateSOSPreapprovals]) { + secnotice("octagon", "Updating SOS preapprovals"); + + // TODO: if this update fails, we need to redo it later. + return [[OTSOSUpdatePreapprovalsOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReady + sosNotPresentState:OctagonStateReady + errorState:OctagonStateReady]; + + } else if([currentState isEqualToString: OctagonStateAssistCKKSTLKUpload]) { + return [[OTUploadNewCKKSTLKsOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReady + errorState:OctagonStateReady]; + + } else if([currentState isEqualToString:OctagonStateReady]) { + if([flags _onqueueContains:OctagonFlagPerformHealthCheck]) { + [flags _onqueueRemoveFlag:OctagonFlagPerformHealthCheck]; + return [self cuttlefishTrustEvaluation]; + } + + if([flags _onqueueContains:OctagonFlagCKKSRequestsTLKUpload]) { + [flags _onqueueRemoveFlag:OctagonFlagCKKSRequestsTLKUpload]; + return [OctagonStateTransitionOperation named:@"ckks-assist" + entering:OctagonStateAssistCKKSTLKUpload]; + } + + if([flags _onqueueContains:OctagonFlagCuttlefishNotification]) { + [flags _onqueueRemoveFlag:OctagonFlagCuttlefishNotification]; + secnotice("octagon", "Updating TPH (while ready) due to push"); + return [OctagonStateTransitionOperation named:@"octagon-update" + entering:OctagonStateReadyUpdated]; + } + + if([flags _onqueueContains:OctagonFlagFetchAuthKitMachineIDList]) { + [flags _onqueueRemoveFlag:OctagonFlagFetchAuthKitMachineIDList]; + secnotice("octagon", "Received an suggestion to update the machine ID list (while ready); updating trusted device list"); + + // If the cached list changes due to this fetch, go into 'updated'. Otherwise, back into ready with you! + return [[OTUpdateTrustedDeviceListOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReady + listUpdatesState:OctagonStateReadyUpdated + errorState:OctagonStateReady + retryFlag:OctagonFlagFetchAuthKitMachineIDList]; + } + + if([flags _onqueueContains:OctagonFlagAttemptSOSUpdatePreapprovals]) { + [flags _onqueueRemoveFlag:OctagonFlagAttemptSOSUpdatePreapprovals]; + if(self.sosAdapter.sosEnabled) { + secnotice("octagon", "Attempt SOS Update preapprovals again!"); + return [OctagonStateTransitionOperation named:@"attempt-sos-update-preapproval" + entering:OctagonStateUpdateSOSPreapprovals]; + } else { + secnotice("octagon", "We are untrusted, but this platform doesn't support SOS."); + } + } + + secnotice("octagon", "Entering state ready"); + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:OctagonAnalyticsLastKeystateReady]; + [self.launchSequence launch]; + return nil; + } else if([currentState isEqualToString:OctagonStateReadyUpdated]) { + return [[OTUpdateTPHOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateReady + errorState:OctagonStateError + retryFlag:OctagonFlagCuttlefishNotification]; + + } else if ([currentState isEqualToString:OctagonStateError]) { + if([flags _onqueueContains:OctagonFlagPerformHealthCheck]) { + [flags _onqueueRemoveFlag:OctagonFlagPerformHealthCheck]; + return [self cuttlefishTrustEvaluation]; + } + } + + return nil; +} + +- (CKKSResultOperation* _Nullable)initializingOperation +{ + WEAKIFY(self); + return [OctagonStateTransitionOperation named:@"octagon-initializing" + intending:OctagonStateNoAccount + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + STRONGIFY(self); + NSError* localError = nil; + OTAccountMetadataClassC* account = [self.accountMetadataStore loadOrCreateAccountMetadata:&localError]; + if(localError && [self.lockStateTracker isLockedError:localError]){ + secnotice("octagon", "Device is locked! pending initialization on unlock"); + op.nextState = OctagonStateWaitForUnlock; + return; + } + + if(localError || !account) { + secnotice("octagon", "Error loading account data: %@", localError); + op.nextState = OctagonStateNoAccount; + + } else if(account.icloudAccountState == OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE) { + secnotice("octagon", "An HSA2 iCloud account exists; waiting for CloudKit to confirm"); + + // Inform the account state tracker of our HSA2 account + [self.accountStateTracker setHSA2iCloudAccountStatus:CKKSAccountStatusAvailable]; + + // This seems an odd place to do this, but CKKS currently also tracks the CloudKit account state. + // Since we think we have an HSA2 account, let CKKS figure out its own CloudKit state + secnotice("octagon-ckks", "Initializing CKKS views"); + [self.viewManager createViews]; + [self.viewManager beginCloudKitOperationOfAllViews]; + + op.nextState = OctagonStateWaitingForCloudKitAccount; + + } else if(account.icloudAccountState == OTAccountMetadataClassC_AccountState_NO_ACCOUNT && account.altDSID != nil) { + secnotice("octagon", "An iCloud account exists, but doesn't appear to be HSA2. Let's check!"); + op.nextState = OctagonStateDetermineiCloudAccountState; + + } else if(account.icloudAccountState == OTAccountMetadataClassC_AccountState_NO_ACCOUNT) { + [self.accountStateTracker setHSA2iCloudAccountStatus:CKKSAccountStatusNoAccount]; + + secnotice("octagon", "No iCloud account available."); + op.nextState = OctagonStateNoAccount; + + } else { + secnotice("octagon", "Unknown account state (%@). Determining...", [account icloudAccountStateAsString:account.icloudAccountState]); + op.nextState = OctagonStateDetermineiCloudAccountState; + } + }]; +} + +- (CKKSResultOperation* _Nullable)evaluateSecdOctagonTrust +{ + return [OctagonStateTransitionOperation named:@"octagon-health-securityd-trust-check" + intending:OctagonStateTPHTrustCheck + errorState:OctagonStatePostRepairCFU + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + NSError* localError = nil; + OTAccountMetadataClassC* account = [self.accountMetadataStore loadOrCreateAccountMetadata:&localError]; + if(account.peerID && account.trustState == OTAccountMetadataClassC_TrustState_TRUSTED) { + secnotice("octagon-health", "peer is trusted: %@", account.peerID); + op.nextState = OctagonStateTPHTrustCheck; + + } else { + secnotice("octagon-health", "trust state (%@). checking in with TPH", [account trustStateAsString:account.trustState]); + op.nextState = [self repairAccountIfTrustedByTPHWithIntededState:OctagonStateTPHTrustCheck errorState:OctagonStatePostRepairCFU]; + } + }]; +} + +- (CKKSResultOperation* _Nullable)evaluateTPHOctagonTrust +{ + return [OctagonStateTransitionOperation named:@"octagon-health-tph-trust-check" + intending:OctagonStateCuttlefishTrustCheck + errorState:OctagonStatePostRepairCFU + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + [self checkTrustStatusAndPostRepairCFUIfNecessary:^(CliqueStatus status, BOOL posted, BOOL hasIdentity, NSError *trustFromTPHError) { + + [[CKKSAnalytics logger] logResultForEvent:OctagonEventTPHHealthCheckStatus hardFailure:false result:trustFromTPHError]; + if(trustFromTPHError) { + secerror("octagon-health: hit an error asking TPH for trust status: %@", trustFromTPHError); + op.error = trustFromTPHError; + op.nextState = OctagonStateError; + } else { + if(hasIdentity == NO) { + op.nextState = OctagonStateUntrusted; + } else if(hasIdentity == YES && status == CliqueStatusIn){ + secnotice("octagon-health", "TPH says we're trusted and in"); + op.nextState = OctagonStateCuttlefishTrustCheck; + } else if (hasIdentity == YES && status != CliqueStatusIn){ + secnotice("octagon-health", "TPH says we have an identity but we are not in Octagon, posted CFU: %d", !!posted); + op.nextState = OctagonStatePostRepairCFU; + } else { + secnotice("octagon-health", "weird shouldn't hit this catch all.. assuming untrusted"); + op.nextState = OctagonStateUntrusted; + } + } + }]; + }]; +} + +- (CKKSResultOperation* _Nullable)cuttlefishTrustEvaluation +{ + + OTCheckHealthOperation* op = [[OTCheckHealthOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + errorState:OctagonStateBecomeReady + deviceInfo:self.prepareInformation + skipRateLimitedCheck:_skipRateLimitingCheck]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"rpcHealthCheck" + withBlock:^{ + secnotice("octagon-health", "Returning from cuttlefish trust check call: postRepairCFU(%d), postEscrowCFU(%d), resetOctagon(%d)", + op.postRepairCFU, op.postEscrowCFU, op.resetOctagon); + if(op.postRepairCFU) { + secnotice("octagon-health", "Posting Repair CFU"); + NSError* postRepairCFUError = nil; + [self postRepairCFU:&postRepairCFUError]; + if(postRepairCFUError) { + op.error = postRepairCFUError; + } + } + if(op.postEscrowCFU) { + //hold up, perhaps we already are pending an upload. + NSError* shouldPostError = nil; + BOOL shouldPost = [self shouldPostConfirmPasscodeCFU:&shouldPostError]; + if(shouldPostError) { + secerror("octagon-health, hit an error evaluating prerecord status: %@", shouldPostError); + op.error = shouldPostError; + } + if(shouldPost) { + secnotice("octagon-health", "Posting Escrow CFU"); + NSError* postEscrowCFUError = nil; + [self postConfirmPasscodeCFU:&postEscrowCFUError]; + if(postEscrowCFUError) { + op.error = postEscrowCFUError; + } + } else { + secnotice("octagon-health", "Not posting confirm passcode CFU, already pending a prerecord upload"); + } + } + if (op.resetOctagon) { + secnotice("octagon-health", "Resetting Octagon as per Cuttlefish request"); + // uh oh let's reset octagon.. + + [self rpcResetAndEstablish:^(NSError *error) { + if(error){ + secerror("octagon-health: failed to reset octagon: %@", error); + op.error = error; + } else { + secnotice("octagon-health", "successfully reset octagon"); + } + }]; + } + }]; + [callback addDependency:op]; + [self.operationQueue addOperation: callback]; + return op; +} + +- (CKKSResultOperation* _Nullable)postRepairCFUAndBecomeUntrusted +{ + return [OctagonStateTransitionOperation named:@"octagon-health-post-repair-cfu" + intending:OctagonStateUntrusted + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + [self checkTrustStatusAndPostRepairCFUIfNecessary:^(CliqueStatus status, + BOOL posted, + BOOL hasIdentity, + NSError * _Nullable postError) { + if(postError) { + secerror("ocagon-health: failed to post repair cfu via state machine: %@", postError); + } else { + secnotice("octagon-health", "posted repair cfu via state machine"); + } + }]; + op.nextState = OctagonStateUntrusted; + }]; +} + +- (CKKSResultOperation* _Nullable)cloudKitAccountNewlyAvailableOperation +{ + WEAKIFY(self); + return [OctagonStateTransitionOperation named:@"octagon-icloud-account-available" + intending:OctagonStateCheckTrustState + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + STRONGIFY(self); + // Register with APS, but don't bother to wait until it's complete. + secnotice("octagon", "iCloud sign in occurred. Attemping to register with APS..."); + + CKContainer* ckContainer = [CKContainer containerWithIdentifier:self.containerName]; + [ckContainer serverPreferredPushEnvironmentWithCompletionHandler: ^(NSString *apsPushEnvString, NSError *error) { + STRONGIFY(self); + + if(!self) { + secerror("octagonpush: received callback for released object"); + return; + } + + if(error || (apsPushEnvString == nil)) { + secerror("octagonpush: Received error fetching preferred push environment (%@): %@", apsPushEnvString, error); + } else { + secnotice("octagonpush", "Registering for environment '%@'", apsPushEnvString); + + OctagonAPSReceiver* aps = [OctagonAPSReceiver receiverForEnvironment:apsPushEnvString + namedDelegatePort:SecCKKSAPSNamedPort + apsConnectionClass:self.apsConnectionClass]; + [aps registerCuttlefishReceiver:self forContainerName:self.containerName]; + } + }]; + + op.nextState = op.intendedState; + }]; +} + +- (OctagonState*) repairAccountIfTrustedByTPHWithIntededState:(OctagonState*)intendedState errorState:(OctagonState*)errorState +{ + __block OctagonState* nextState = intendedState; + + //let's check in with TPH real quick to make sure it agrees with our local assessment + secnotice("octagon-health", "repairAccountIfTrustedByTPHWithIntededState: calling into TPH for trust status"); + + OTOperationConfiguration *config = [[OTOperationConfiguration alloc]init]; + + [self rpcTrustStatus:config reply:^(CliqueStatus status, + NSString* egoPeerID, + NSDictionary* _Nullable peerCountByModelID, + BOOL isExcluded, + NSError * _Nullable error) { + BOOL hasIdentity = egoPeerID != nil; + secnotice("octagon-health", "repairAccountIfTrustedByTPHWithIntededState status: %ld, peerID: %@, isExcluded: %d error: %@", (long)status, egoPeerID, isExcluded, error); + + if (error) { + secnotice("octagon-health", "got an error from tph, returning to become_ready state: %@", error); + nextState = OctagonStateBecomeReady; + return; + } + + if(OctagonAuthoritativeTrustIsEnabled() && hasIdentity && status == CliqueStatusIn) { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + [self rpcStatus:^(NSDictionary *dump, NSError *dumpError) { + if(dumpError) { + secerror("octagon-health: error fetching ego peer id!: %@", dumpError); + nextState = errorState; + } else { + NSDictionary* egoInformation = dump[@"self"]; + NSString* peerID = egoInformation[@"peerID"]; + NSError* persistError = nil; + BOOL persisted = [self.accountMetadataStore persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.trustState = OTAccountMetadataClassC_TrustState_TRUSTED; + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE; + metadata.peerID = peerID; + return metadata; + } error:&persistError]; + if(!persisted || persistError) { + secerror("octagon-health: couldn't persist results: %@", persistError); + nextState = errorState; + } else { + secnotice("octagon-health", "added trusted identity to account metadata"); + nextState = intendedState; + } + } + dispatch_semaphore_signal(sema); + }]; + if (0 != dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 10))) { + secerror("octagon: Timed out checking trust status"); + } + } else if (OctagonAuthoritativeTrustIsEnabled() && (self.postedRepairCFU == NO) && hasIdentity && status != CliqueStatusIn){ + nextState = errorState; + } + }]; + + return nextState; +} + +- (BOOL) didDeviceAttemptToJoinOctagon:(NSError**)error +{ + NSError* fetchAttemptError = nil; + OTAccountMetadataClassC_AttemptedAJoinState attemptedAJoin = [self.accountMetadataStore fetchPersistedJoinAttempt:&fetchAttemptError]; + if(fetchAttemptError) { + secerror("octagon: failed to fetch data indicating device attempted to join octagon, assuming it did: %@", fetchAttemptError); + if(error){ + *error = fetchAttemptError; + } + return YES; + } + BOOL attempted = YES; + switch (attemptedAJoin) { + case OTAccountMetadataClassC_AttemptedAJoinState_NOTATTEMPTED: + attempted = NO; + break; + case OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED: + case OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN: + default: + break; + } + return attempted; +} + +- (void)checkTrustStatusAndPostRepairCFUIfNecessary:(void (^ _Nullable)(CliqueStatus status, BOOL posted, BOOL hasIdentity, NSError * _Nullable error))reply +{ + WEAKIFY(self); + OTOperationConfiguration *configuration = [[OTOperationConfiguration alloc] init]; + [self rpcTrustStatus:configuration reply:^(CliqueStatus status, + NSString* _Nullable egoPeerID, + NSDictionary* _Nullable peerCountByModelID, + BOOL isExcluded, + NSError * _Nullable error) { + STRONGIFY(self); + + secnotice("octagon", "clique status: %@, egoPeerID: %@, peerCountByModelID: %@, isExcluded: %d error: %@", OTCliqueStatusToString(status), egoPeerID, peerCountByModelID, isExcluded, error); + + BOOL hasIdentity = egoPeerID != nil; + if (error && error.code != errSecInteractionNotAllowed) { + reply(status, NO, hasIdentity, error); + return; + } + +#if TARGET_OS_TV + // Are there any iphones or iPads? about? Only iOS devices can repair apple TVs. + bool phonePeerPresent = false; + for(NSString* modelID in peerCountByModelID.allKeys) { + bool iPhone = [modelID hasPrefix:@"iPhone"]; + bool iPad = [modelID hasPrefix:@"iPad"]; + if(!iPhone && !iPad) { + continue; + } + + int count = [peerCountByModelID[modelID] intValue]; + if(count > 0) { + secnotice("octagon", "Have %d peers with model %@", count, modelID); + phonePeerPresent = true; + break; + } + } + if(!phonePeerPresent) { + secnotice("octagon", "No iOS peers in account; not posting CFU"); + reply(status, NO, hasIdentity, nil); + return; + } +#endif + + // On platforms with SOS, we only want to post a CFU if we've attempted to join at least once. + // This prevents us from posting a CFU, then performing an SOS upgrade and succeeding. + if(self.sosAdapter.sosEnabled) { + NSError* fetchAttemptError = nil; + BOOL attemptedToJoin = [self didDeviceAttemptToJoinOctagon:&fetchAttemptError]; + if(fetchAttemptError){ + secerror("octagon: failed to retrieve joining attempt information: %@", fetchAttemptError); + attemptedToJoin = YES; + } + + if(!attemptedToJoin) { + secnotice("octagon", "SOS is enabled and we haven't attempted to join; not posting CFU"); + reply(status, NO, hasIdentity, nil); + return; + } + } + + if(OctagonAuthoritativeTrustIsEnabled() && (status == CliqueStatusNotIn || status == CliqueStatusAbsent || isExcluded)) { + NSError* localError = nil; + BOOL posted = [self postRepairCFU:&localError]; + reply(status, posted, hasIdentity, localError); + return; + } + reply(status, NO, hasIdentity, nil); + return; + }]; +} + +#if TARGET_OS_WATCH +- (CKKSResultOperation* _Nullable)startCompanionPairingOperation +{ + WEAKIFY(self); + return [OctagonStateTransitionOperation named:@"start-companion-pairing" + intending:OctagonStateBecomeUntrusted + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + STRONGIFY(self); + OTPairingInitiateWithCompletion(self.queue, ^(bool success, NSError *error) { + if (success) { + secnotice("octagon", "companion pairing succeeded"); + } else { + if (error == nil) { + error = [NSError errorWithDomain:(__bridge NSString *)kSecErrorDomain code:errSecInternalError userInfo:nil]; + } + secnotice("octagon", "companion pairing failed: %@", error); + } + [[CKKSAnalytics logger] logResultForEvent:OctagonEventCompanionPairing hardFailure:false result:error]; + }); + op.nextState = op.intendedState; + }]; +} +#endif /* TARGET_OS_WATCH */ + +- (CKKSResultOperation* _Nullable)becomeUntrustedOperation:(OctagonState*)intendedState +{ + WEAKIFY(self); + return [OctagonStateTransitionOperation named:@"octagon-become-untrusted" + intending:intendedState + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + STRONGIFY(self); + NSError* localError = nil; + + [self.accountStateTracker triggerOctagonStatusFetch]; + + [self checkTrustStatusAndPostRepairCFUIfNecessary:^(CliqueStatus status, BOOL posted, BOOL hasIdentity, NSError * _Nullable postError) { + + [[CKKSAnalytics logger] logResultForEvent:OctagonEventCheckTrustForCFU hardFailure:false result:postError]; + if(postError){ + secerror("octagon: cfu failed to post"); + } else { + secnotice("octagon", "clique status: %@, posted cfu: %d", OTCliqueStatusToString(status), !!posted); + } + }]; + + [self.accountMetadataStore persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.trustState = OTAccountMetadataClassC_TrustState_UNTRUSTED; + return metadata; + } error:&localError]; + + if(localError) { + secnotice("octagon", "Unable to set trust state: %@", localError); + op.nextState = OctagonStateError; + } else { + op.nextState = op.intendedState; + } + + for (id key in self.viewManager.views) { + CKKSKeychainView* view = self.viewManager.views[key]; + secnotice("octagon-ckks", "Informing %@ of new untrusted status", view); + [view endTrustedOperation]; + } + + /* + * Initial notification that we let the world know that trust is up and doing something + */ + if (!self.initialBecomeUntrustedPosted) { + [self notifyTrustChanged:OTAccountMetadataClassC_TrustState_UNTRUSTED]; + self.initialBecomeUntrustedPosted = YES; + } + + self.octagonAdapter = nil; + }]; +} + +- (CKKSResultOperation* _Nullable)becomeReadyOperation +{ + WEAKIFY(self); + return [OctagonStateTransitionOperation named:@"octagon-ready" + intending:OctagonStateReady + errorState:OctagonStateError + timeout:OctagonStateTransitionDefaultTimeout + withBlockTakingSelf:^(OctagonStateTransitionOperation * _Nonnull op) { + STRONGIFY(self); + + // Note: we don't modify the account metadata store here; that will have been done + // by a join or upgrade operation, possibly long ago + + [self.accountStateTracker triggerOctagonStatusFetch]; + + NSError* localError = nil; + NSString* peerID = [self.accountMetadataStore getEgoPeerID:&localError]; + if(!peerID || localError) { + secerror("octagon-ckks: No peer ID to pass to CKKS. Syncing will be disabled."); + } else { + OctagonCKKSPeerAdapter* octagonAdapter = [[OctagonCKKSPeerAdapter alloc] initWithPeerID:peerID operationDependencies:[self operationDependencies]]; + + // This octagon adapter must be able to load the self peer keys, or we're in trouble. + NSError* egoPeerKeysError = nil; + CKKSSelves* selves = [octagonAdapter fetchSelfPeers:&egoPeerKeysError]; + if(!selves || egoPeerKeysError) { + secerror("octagon-ckks: Unable to fetch self peers for %@: %@", octagonAdapter, egoPeerKeysError); + + if([self.lockStateTracker isLockedError:egoPeerKeysError]) { + secnotice("octagon-ckks", "Waiting for device unlock to proceed"); + op.nextState = OctagonStateWaitForUnlock; + } else { + secnotice("octagon-ckks", "Error is scary; becoming untrusted"); + op.nextState = OctagonStateBecomeUntrusted; + } + return; + } + + // stash a reference to the adapter so we can provided updates later + self.octagonAdapter = octagonAdapter; + + // Start all our CKKS views! + for (id key in self.viewManager.views) { + CKKSKeychainView* view = self.viewManager.views[key]; + secnotice("octagon-ckks", "Informing CKKS view '%@' of trusted operation with self peer %@", view.zoneName, peerID); + + NSArray>* peerProviders = nil; + + if(self.sosAdapter.sosEnabled) { + peerProviders = @[self.octagonAdapter, self.sosAdapter]; + + } else { + peerProviders = @[self.octagonAdapter]; + } + + [view beginTrustedOperation:peerProviders + suggestTLKUpload:self.suggestTLKUploadNotifier]; + } + } + [self notifyTrustChanged:OTAccountMetadataClassC_TrustState_TRUSTED]; + + op.nextState = op.intendedState; + }]; +} + +#pragma mark --- Utilities to run at times + +- (NSString * _Nullable)extractStringKey:(NSString * _Nonnull)key fromDictionary:(NSDictionary * _Nonnull)d +{ + NSString *value = d[key]; + if ([value isKindOfClass:[NSString class]]) { + return value; + } + return NULL; +} + +- (void)handleHealthRequest +{ + NSString *trustState = OTAccountMetadataClassC_TrustStateAsString(self.currentMemoizedTrustState); + OctagonState* currentState = [self.stateMachine waitForState:OctagonStateReady wait:3*NSEC_PER_SEC]; + + [[self.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon: Can't talk with TrustedPeersHelper, report is lost: %@", error); + }] reportHealthWithContainer:self.containerName context:self.contextID stateMachineState:currentState trustState:trustState reply:^(NSError * _Nullable error) { + if (error) { + secerror("octagon: health report is lost: %@", error); + } + }]; +} + +- (void)handleTTRRequest:(NSDictionary *)cfDictionary +{ + NSString *serialNumber = [self extractStringKey:@"s" fromDictionary:cfDictionary]; + NSString *ckDeviceId = [self extractStringKey:@"D" fromDictionary:cfDictionary]; + NSString *alert = [self extractStringKey:@"a" fromDictionary:cfDictionary]; + NSString *description = [self extractStringKey:@"d" fromDictionary:cfDictionary]; + NSString *radar = [self extractStringKey:@"R" fromDictionary:cfDictionary]; + NSString *componentName = [self extractStringKey:@"n" fromDictionary:cfDictionary]; + NSString *componentVersion = [self extractStringKey:@"v" fromDictionary:cfDictionary]; + NSString *componentID = [self extractStringKey:@"I" fromDictionary:cfDictionary]; + + if (serialNumber) { + if (![self.deviceAdapter.serialNumber isEqualToString:serialNumber]) { + secnotice("octagon", "TTR request not for me (sn)"); + return; + } + } + if (ckDeviceId) { + NSString *selfDeviceID = self.viewManager.accountTracker.ckdeviceID; + if (![selfDeviceID isEqualToString:serialNumber]) { + secnotice("octagon", "TTR request not for me (deviceId)"); + return; + } + } + + if (alert == NULL || description == NULL || radar == NULL) { + secerror("octagon: invalid type of TTR requeat: %@", cfDictionary); + return; + } + + SecTapToRadar *ttr = [[SecTapToRadar alloc] initTapToRadar:alert + description:description + radar:radar]; + if (componentName && componentVersion && componentID) { + ttr.componentName = componentName; + ttr.componentVersion = componentVersion; + ttr.componentID = componentID; + } + [ttr trigger]; +} + +// We can't make a APSIncomingMessage in the tests (no public constructor), +// but we don't really care about anything in it but the userInfo dictionary anyway +- (void)notifyContainerChange:(APSIncomingMessage* _Nullable)notification +{ + [self notifyContainerChangeWithUserInfo:notification.userInfo]; +} + +- (void)notifyContainerChangeWithUserInfo:(NSDictionary*)userInfo +{ + secerror("OTCuttlefishContext: received a cuttlefish push notification (%@): %@", + self.containerName, userInfo); + + NSDictionary *cfDictionary = userInfo[@"cf"]; + if ([cfDictionary isKindOfClass:[NSDictionary class]]) { + NSString *command = [self extractStringKey:@"k" fromDictionary:cfDictionary]; + if(command) { + if ([command isEqualToString:@"h"]) { + [self handleHealthRequest]; + } else if ([command isEqualToString:@"r"]) { + [self handleTTRRequest:cfDictionary]; + } else { + secerror("octagon: unknown command: %@", command); + } + return; + } + } + + if (self.apsRateLimiter == nil) { + secnotice("octagon", "creating aps rate limiter"); + // If we're testing, for the initial delay, use 0.2 second. Otherwise, 2s. + dispatch_time_t initialDelay = (SecCKKSReduceRateLimiting() ? 200 * NSEC_PER_MSEC : 2 * NSEC_PER_SEC); + + // If we're testing, for the initial delay, use 2 second. Otherwise, 30s. + dispatch_time_t continuingDelay = (SecCKKSReduceRateLimiting() ? 2 * NSEC_PER_SEC : 30 * NSEC_PER_SEC); + + WEAKIFY(self); + self.apsRateLimiter = [[CKKSNearFutureScheduler alloc] initWithName:@"aps-push-ratelimiter" + initialDelay:initialDelay + continuingDelay:continuingDelay + keepProcessAlive:YES + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + STRONGIFY(self); + if (self == nil) { + return; + } + secnotice("octagon-push-ratelimited", "notifying container of change for context: %@", self.contextID); + OctagonPendingFlag *pendingFlag = [[OctagonPendingFlag alloc] initWithFlag:OctagonFlagCuttlefishNotification + conditions:OctagonPendingConditionsDeviceUnlocked]; + + [self.stateMachine handlePendingFlag:pendingFlag]; + }]; + } + + [self.apsRateLimiter trigger]; +} + +- (OTAccountMetadataClassC_TrustState)currentMemoizedTrustState +{ + NSError* localError = nil; + OTAccountMetadataClassC* accountMetadata = [self.accountMetadataStore loadOrCreateAccountMetadata:&localError]; + + if(!accountMetadata) { + secnotice("octagon", "Unable to fetch account metadata: %@", localError); + return OTAccountMetadataClassC_TrustState_UNKNOWN; + } + + return accountMetadata.trustState; +} + +- (OTAccountMetadataClassC_AccountState)currentMemoizedAccountState +{ + NSError* localError = nil; + OTAccountMetadataClassC* accountMetadata = [self.accountMetadataStore loadOrCreateAccountMetadata:&localError]; + + if(!accountMetadata) { + secnotice("octagon", "Unable to fetch account metadata: %@", localError); + return OTAccountMetadataClassC_AccountState_UNKNOWN; + } + + return accountMetadata.icloudAccountState; +} + +- (NSDate* _Nullable) currentMemoizedLastHealthCheck +{ + NSError* localError = nil; + OTAccountMetadataClassC* accountMetadata = [self.accountMetadataStore loadOrCreateAccountMetadata:&localError]; + + if(!accountMetadata) { + secnotice("octagon", "Unable to fetch account metadata: %@", localError); + return nil; + } + if(accountMetadata.lastHealthCheckup == 0) { + return nil; + } + return [[NSDate alloc] initWithTimeIntervalSince1970: accountMetadata.lastHealthCheckup]; +} + +- (void)requestTrustedDeviceListRefresh +{ + [self.stateMachine handleFlag:OctagonFlagFetchAuthKitMachineIDList]; +} + +#pragma mark --- SOS update handling + + +- (void)selfPeerChanged:(id)provider +{ + // Currently, we register for peer changes with just our SOS peer adapter, so the only reason this is called is to receive SOS updates + // Ignore SOS self peer updates for now. +} + +- (void)trustedPeerSetChanged:(id)provider +{ + // Currently, we register for peer changes with just our SOS peer adapter, so the only reason this is called is to receive SOS updates + secnotice("octagon-sos", "Received an update of an SOS trust set change"); + + if(!self.sosAdapter.sosEnabled) { + secnotice("octagon-sos", "This platform doesn't support SOS. This is probably a bug?"); + } + + //OTUpdatePreapprovalsOperation* op = [[OTUpdatePreapprovalsOperation alloc] initWithDependencies:self.operationDependencies]; + + [self.stateMachine doSimpleStateMachineRPC:@"update-sos-preapprovals" + op:[OctagonStateTransitionOperation named:@"sos-peers-changed" + entering:OctagonStateUpdateSOSPreapprovals] + sourceStates:[NSSet setWithObject:OctagonStateReady] + reply:^(NSError* error) {}]; +} + +#pragma mark --- External Interfaces + +//Check for account +- (CKKSAccountStatus)checkForCKAccount:(OTOperationConfiguration * _Nullable)configuration { + +#if TARGET_OS_WATCH + // Watches can be very, very slow getting the CK account state + uint64_t timeout = (90 * NSEC_PER_SEC); +#else + uint64_t timeout = (10 * NSEC_PER_SEC); +#endif + if (configuration.timeoutWaitForCKAccount != 0) { + timeout = configuration.timeoutWaitForCKAccount; + } + if (timeout) { + /* wait if account is not present yet */ + if([self.cloudKitAccountStateKnown wait:timeout] != 0) { + secnotice("octagon-ck", "Unable to determine CloudKit account state?"); + return CKKSAccountStatusUnknown; + } + } + + __block bool haveAccount = true; + dispatch_sync(self.queue, ^{ + if (self.cloudKitAccountInfo == NULL || self.cloudKitAccountInfo.accountStatus != CKKSAccountStatusAvailable) { + haveAccount = false; + } + }); + return haveAccount ? CKKSAccountStatusAvailable : CKKSAccountStatusNoAccount; +} + +- (NSError *)errorNoiCloudAccount +{ + return [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNotSignedIn + description:@"User is not signed into iCloud."]; +} + +//Initiator interfaces + +- (void)rpcPrepareIdentityAsApplicantWithConfiguration:(OTJoiningConfiguration*)config + epoch:(uint64_t)epoch + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply +{ + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply(NULL, NULL, NULL, NULL, NULL, [self errorNoiCloudAccount]); + return; + } + + secnotice("otrpc", "Preparing identity as applicant"); + OTPrepareOperation* pendingOp = [[OTPrepareOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateInitiatorAwaitingVoucher + errorState:OctagonStateBecomeUntrusted + deviceInfo:[self prepareInformation] + epoch:epoch]; + + + dispatch_time_t timeOut = 0; + if(config.timeout != 0) { + timeOut = config.timeout; + } else if(!OctagonPlatformSupportsSOS()){ + // Non-iphone non-mac platforms can be slow; heuristically slow them down + timeOut = 60*NSEC_PER_SEC; + } else { + timeOut = 2*NSEC_PER_SEC; + } + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"prepareForApplicant" + sourceStates:[NSSet setWithArray:@[OctagonStateUntrusted, OctagonStateNoAccount, OctagonStateMachineNotStarted]] + serialQueue:self.queue + timeout:timeOut + transitionOp:pendingOp]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"rpcPrepare-callback" + withBlock:^{ + secnotice("otrpc", "Returning a prepare call: %@ %@", pendingOp.peerID, pendingOp.error); + reply(pendingOp.peerID, + pendingOp.permanentInfo, + pendingOp.permanentInfoSig, + pendingOp.stableInfo, + pendingOp.stableInfoSig, + pendingOp.error); + }]; + [callback addDependency:pendingOp]; + [self.operationQueue addOperation: callback]; + + [self.stateMachine handleExternalRequest:request]; + + return; +} + +-(void)joinWithBottle:(NSString*)bottleID + entropy:(NSData *)entropy + bottleSalt:(NSString *)bottleSalt + reply:(void (^)(NSError * _Nullable error))reply +{ + _bottleID = bottleID; + _entropy = entropy; + _bottleSalt = bottleSalt; + OTOperationConfiguration *configuration = [[OTOperationConfiguration alloc] init]; + + if ([self checkForCKAccount:configuration] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply([self errorNoiCloudAccount]); + return; + } + + OctagonStateTransitionPath* path = [OctagonStateTransitionPath pathFromDictionary:@{ + OctagonStateInitiatorCreateIdentity: @{ + OctagonStateInitiatorVouchWithBottle: [self joinStatePathDictionary], + }, + }]; + + [self.stateMachine doWatchedStateMachineRPC:@"rpc-join-with-bottle" + sourceStates:OctagonInAccountStates() + path:path + reply:^(NSError *joinError) { + if(joinError) { + if([joinError isCuttlefishError: CuttlefishErrorResultGraphNotFullyReachable]){ + secnotice("octagon", "setting flag for cuttlefish health check"); + [self.stateMachine handleFlag:OctagonFlagPerformHealthCheck]; + } + reply(joinError); + } else { + reply(nil); + } + }]; +} + +-(void)joinWithRecoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable error))reply +{ + _recoveryKey = recoveryKey; + OTOperationConfiguration *configuration = [[OTOperationConfiguration alloc] init]; + + if ([self checkForCKAccount:configuration] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply([self errorNoiCloudAccount]); + return; + } + + OctagonStateTransitionPath* path = [OctagonStateTransitionPath pathFromDictionary:@{ + OctagonStateCreateIdentityForRecoveryKey: @{ + OctagonStateVouchWithRecoveryKey: [self joinStatePathDictionary], + }, + }]; + + [self.stateMachine doWatchedStateMachineRPC:@"rpc-join-with-recovery-key" + sourceStates:OctagonInAccountStates() + path:path + reply:reply]; +} + +- (NSDictionary*)joinStatePathDictionary +{ + return @{ + OctagonStateInitiatorUpdateDeviceList: @{ + OctagonStateInitiatorJoin: @{ + OctagonStateBecomeReady: @{ + OctagonStateReady: [OctagonStateTransitionPathStep success], + }, + + OctagonStateInitiatorJoinCKKSReset: @{ + OctagonStateInitiatorJoinAfterCKKSReset: @{ + OctagonStateBecomeReady: @{ + OctagonStateReady: [OctagonStateTransitionPathStep success] + }, + }, + }, + }, + }, + }; +} + +- (void)rpcJoin:(NSData*)vouchData + vouchSig:(NSData*)vouchSig +preapprovedKeys:(NSArray* _Nullable)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply +{ + + _vouchData = vouchData; + _vouchSig = vouchSig; + _preapprovedKeys = preapprovedKeys; + + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply([self errorNoiCloudAccount]); + return; + } + + NSMutableSet* sourceStates = [NSMutableSet setWithObject:OctagonStateInitiatorAwaitingVoucher]; + + OctagonStateTransitionPath* path = [OctagonStateTransitionPath pathFromDictionary:[self joinStatePathDictionary]]; + + [self.stateMachine doWatchedStateMachineRPC:@"rpc-join" + sourceStates:sourceStates + path:path + reply:reply]; +} + +- (NSDictionary *)ckksPeerStatus:(id)peer +{ + NSMutableDictionary *peerStatus = [NSMutableDictionary dictionary]; + + if (peer.peerID) { + peerStatus[@"peerID"] = peer.peerID; + } + NSData *spki = peer.publicSigningKey.encodeSubjectPublicKeyInfo; + if (spki) { + peerStatus[@"signingSPKI"] = [spki base64EncodedStringWithOptions:0]; + peerStatus[@"signingSPKIHash"] = [TPHashBuilder hashWithAlgo:kTPHashAlgoSHA256 ofData:spki]; + } + return peerStatus; +} + +- (NSArray *)sosTrustedPeersStatus +{ + NSError *localError = nil; + NSSet>* _Nullable peers = [self.sosAdapter fetchTrustedPeers:&localError]; + if (peers == nil || localError) { + secnotice("octagon", "No SOS peers present: %@, skipping in status", localError); + return nil; + } + NSMutableArray* trustedSOSPeers = [NSMutableArray array]; + + for (id peer in peers) { + NSDictionary *peerStatus = [self ckksPeerStatus:peer]; + if (peerStatus) { + [trustedSOSPeers addObject:peerStatus]; + } + } + return trustedSOSPeers; +} + +- (NSDictionary *)sosSelvesStatus +{ + NSError *localError = nil; + + CKKSSelves* selves = [self.sosAdapter fetchSelfPeers:&localError]; + if (selves == nil || localError) { + secnotice("octagon", "No SOS selves present: %@, skipping in status", localError); + return nil; + } + NSMutableDictionary* selvesSOSPeers = [NSMutableDictionary dictionary]; + + selvesSOSPeers[@"currentSelf"] = [self ckksPeerStatus:selves.currentSelf]; + + /* + * If we have past selves, include them too + */ + NSMutableSet* pastSelves = [selves.allSelves mutableCopy]; + [pastSelves removeObject:selves.currentSelf]; + if (pastSelves.count) { + NSMutableArray* pastSelvesStatus = [NSMutableArray array]; + + for (id peer in pastSelves) { + NSDictionary *peerStatus = [self ckksPeerStatus:peer]; + if (peerStatus) { + [pastSelvesStatus addObject:peerStatus]; + } + } + selvesSOSPeers[@"pastSelves"] = pastSelvesStatus; + } + return selvesSOSPeers; +} + +- (void)rpcStatus:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply +{ + __block NSMutableDictionary* result = [NSMutableDictionary dictionary]; + + result[@"containerName"] = self.containerName; + result[@"contextID"] = self.contextID; + + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply(NULL, [self errorNoiCloudAccount]); + return; + } + + if([self.stateMachine.paused wait:3*NSEC_PER_SEC] != 0) { + secnotice("octagon", "Returning status of unpaused state machine for container (%@) and context (%@)", self.containerName, self.contextID); + result[@"stateUnpaused"] = @1; + } + + // This will try to allow the state machine to pause + result[@"state"] = self.stateMachine.currentState; + result[@"statePendingFlags"] = [self.stateMachine dumpPendingFlags]; + result[@"stateFlags"] = [self.stateMachine.flags dumpFlags]; + + result[@"memoizedTrustState"] = @(self.currentMemoizedTrustState); + result[@"memoizedAccountState"] = @(self.currentMemoizedAccountState); + result[@"octagonLaunchSeqence"] = [self.launchSequence eventsByTime]; + result[@"memoizedlastHealthCheck"] = self.currentMemoizedLastHealthCheck ? self.currentMemoizedLastHealthCheck : @"Never checked"; + if (self.sosAdapter.sosEnabled) { + result[@"sosTrustedPeersStatus"] = [self sosTrustedPeersStatus]; + result[@"sosSelvesStatus"] = [self sosSelvesStatus]; + } + + { + NSError *error; + id request = [self.escrowRequestClass request:&error]; + result[@"escrowRequest"] = [request fetchStatuses:&error]; + } + + result[@"CoreFollowUp"] = [self.followupHandler sysdiagnoseStatus]; + + [[self.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secnotice("octagon", "Unable to dump state for status RPC: %@", error); + reply(nil, error); + }] dumpWithContainer:self.containerName + context:self.contextID + reply:^(NSDictionary * _Nullable dump, NSError * _Nullable dumpError) { + secnotice("octagon", "Finished dump for status RPC"); + if(dumpError) { + result[@"contextDumpError"] = dumpError; + } else { + result[@"contextDump"] = dump; + } + reply(result, nil); + }]; +} + +- (void)rpcFetchEgoPeerID:(void (^)(NSString* peerID, NSError* error))reply +{ + // We've memoized this peer ID. Use the memorized version... + NSError* localError = nil; + NSString* peerID = [self.accountMetadataStore getEgoPeerID:&localError]; + + if(peerID) { + secnotice("octagon", "Returning peer ID: %@", peerID); + } else { + secnotice("octagon", "Unable to fetch peer ID: %@", localError); + } + reply(peerID, localError); +} + +- (void)rpcFetchDeviceNamesByPeerID:(void (^)(NSDictionary* _Nullable peers, NSError* _Nullable error))reply +{ + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply(NULL, [self errorNoiCloudAccount]); + return; + } + + // As this isn't a state-modifying operation, we don't need to go through the state machine. + [[self.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secnotice("octagon", "Unable to fetch peers: %@", error); + reply(nil, error); + }] dumpWithContainer:self.containerName + context:self.contextID + reply:^(NSDictionary * _Nullable dump, NSError * _Nullable dumpError) { + // Pull out our peers + if(dumpError) { + secnotice("octagon", "Unable to dump info: %@", dumpError); + reply(nil, dumpError); + return; + } + + NSDictionary* selfInfo = dump[@"self"]; + NSArray* peers = dump[@"peers"]; + NSArray* trustedPeerIDs = selfInfo[@"dynamicInfo"][@"included"]; + + NSMutableDictionary* peerMap = [NSMutableDictionary dictionary]; + + for(NSString* peerID in trustedPeerIDs) { + NSDictionary* peerMatchingID = nil; + + for(NSDictionary* peer in peers) { + if([peer[@"peerID"] isEqualToString:peerID]) { + peerMatchingID = peer; + break; + } + } + + if(!peerMatchingID) { + secerror("octagon: have a trusted peer ID without peer information: %@", peerID); + continue; + } + + peerMap[peerID] = peerMatchingID[@"stableInfo"][@"device_name"]; + } + + reply(peerMap, nil); + }]; +} + +- (void)rpcSetRecoveryKey:(NSString*)recoveryKey reply:(void (^)(NSError * _Nullable error))reply +{ + OTSetRecoveryKeyOperation *pendingOp = [[OTSetRecoveryKeyOperation alloc] initWithDependencies:self.operationDependencies + recoveryKey:recoveryKey]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"setRecoveryKey-callback" + withBlock:^{ + secnotice("otrpc", "Returning a set recovery key call: %@", pendingOp.error); + reply(pendingOp.error); + }]; + + [callback addDependency:pendingOp]; + [self.operationQueue addOperation:callback]; + [self.operationQueue addOperation:pendingOp]; +} + +- (void)rpcTrustStatusCachedStatus:(OTAccountMetadataClassC*)account + reply:(void (^)(CliqueStatus status, + NSString* egoPeerID, + NSDictionary* _Nullable peerCountByModelID, + BOOL isExcluded, + NSError *error))reply +{ + CliqueStatus status = CliqueStatusAbsent; + + if (account.trustState == OTAccountMetadataClassC_TrustState_TRUSTED) { + status = CliqueStatusIn; + } else if (account.trustState == OTAccountMetadataClassC_TrustState_UNTRUSTED) { + status = CliqueStatusNotIn; + } + + secnotice("octagon", "returning cached clique status: %@", OTCliqueStatusToString(status)); + reply(status, account.peerID, nil, NO, NULL); +} + + +- (void)rpcTrustStatus:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus status, + NSString* _Nullable peerID, + NSDictionary* _Nullable peerCountByModelID, + BOOL isExcluded, + NSError *error))reply +{ + __block NSError* localError = nil; + + OTAccountMetadataClassC* account = [self.accountMetadataStore loadOrCreateAccountMetadata:&localError]; + if(localError && [self.lockStateTracker isLockedError:localError]){ + secnotice("octagon", "Device is locked! pending initialization on unlock"); + reply(CliqueStatusError, nil, nil, NO, localError); + return; + } + + if(account.icloudAccountState == OTAccountMetadataClassC_AccountState_NO_ACCOUNT) { + secnotice("octagon", "no account! returning clique status 'no account'"); + reply(CliqueStatusNoCloudKitAccount, nil, nil, NO, NULL); + return; + } + + if (configuration.useCachedAccountStatus) { + [self rpcTrustStatusCachedStatus:account reply:reply]; + return; + } + + CKKSAccountStatus ckAccountStatus = [self checkForCKAccount:configuration]; + if(ckAccountStatus == CKKSAccountStatusNoAccount) { + secnotice("octagon", "No cloudkit account present"); + reply(CliqueStatusNoCloudKitAccount, nil, nil, NO, NULL); + return; + } else if(ckAccountStatus == CKKSAccountStatusUnknown) { + secnotice("octagon", "Unknown cloudkit account status, returning cached trust value"); + [self rpcTrustStatusCachedStatus:account reply:reply]; + return; + } + + NSXPCConnection* c = [self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError *xpcError) { + localError = xpcError; + secnotice("octagon", "rpcTrustStatus: Failed to get XPC connection: %@", xpcError); + }]; + + if(localError){ + reply(CliqueStatusError, nil, nil, NO, localError); + return; + } + __block NSString* peerID = nil; + __block NSDictionary* peerModelCounts = nil; + __block BOOL excluded = NO; + __block CliqueStatus trustStatus = CliqueStatusError; + + [c trustStatusWithContainer:self.containerName context:self.contextID reply:^(TrustedPeersHelperEgoPeerStatus *egoStatus, + NSError *xpcError) { + TPPeerStatus status = egoStatus.egoStatus; + peerID = egoStatus.egoPeerID; + excluded = egoStatus.isExcluded; + peerModelCounts = egoStatus.peerCountsByModelID; + localError = xpcError; + + if(xpcError) { + secnotice("octagon", "error fetching trust status: %@", xpcError); + } else { + secnotice("octagon", "trust status: %@", TPPeerStatusToString(status)); + + if((status&TPPeerStatusExcluded) == TPPeerStatusExcluded){ + trustStatus = CliqueStatusNotIn; + } + else if((status&TPPeerStatusPartiallyReciprocated) == TPPeerStatusPartiallyReciprocated){ + trustStatus = CliqueStatusIn; + } + else if((status&TPPeerStatusAncientEpoch) == TPPeerStatusAncientEpoch){ + //FIX ME HANDLE THIS CASE + trustStatus= CliqueStatusIn; + } + else if((status&TPPeerStatusOutdatedEpoch) == TPPeerStatusOutdatedEpoch){ + //FIX ME HANDLE THIS CASE + trustStatus = CliqueStatusIn; + } + else if((status&TPPeerStatusFullyReciprocated) == TPPeerStatusFullyReciprocated){ + trustStatus = CliqueStatusIn; + } + else if((status&TPPeerStatusUnknown) == TPPeerStatusUnknown){ + trustStatus = CliqueStatusAbsent; + } + else if ((status&TPPeerStatusSelfTrust) == TPPeerStatusSelfTrust) { + trustStatus = CliqueStatusIn; + } + else { + secnotice("octagon", "TPPeerStatus is empty"); + trustStatus = CliqueStatusAbsent; + } + } + }]; + + if(trustStatus == CliqueStatusIn && self.postedRepairCFU == YES){ + NSError* clearError = nil; + [self.followupHandler clearFollowUp:OTFollowupContextTypeStateRepair error:&clearError]; + // TODO(caw): should we clear this flag if `clearFollowUpForContext` fails? + self.postedRepairCFU = NO; + } + reply(trustStatus, peerID, peerModelCounts, excluded, localError); +} + +- (void)rpcFetchAllViableBottles:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray* _Nullable sortedPartialEscrowRecordIDs, NSError* _Nullable error))reply +{ + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply(NULL, NULL, [self errorNoiCloudAccount]); + return; + } + + // As this isn't a state-modifying operation, we don't need to go through the state machine. + [[self.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + reply(nil, nil, error); + }] fetchViableBottlesWithContainer:self.containerName + context:self.contextID + reply:^(NSArray* _Nullable sortedEscrowRecordIDs, NSArray* _Nullable sortedPartialEscrowRecordIDs, NSError * _Nullable error) { + if(error){ + secerror("octagon: error fetching all viable bottles: %@", error); + reply(nil, nil, error); + }else{ + secnotice("octagon", "fetched viable bottles: %@", sortedEscrowRecordIDs); + secnotice("octagon", "fetched partially viable bottles: %@", sortedPartialEscrowRecordIDs); + reply(sortedEscrowRecordIDs, sortedPartialEscrowRecordIDs, error); + } + }]; +} + +- (void)fetchEscrowContents:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + // As this isn't a state-modifying operation, we don't need to go through the state machine. + [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + reply(nil, nil, nil, error); + }] fetchEscrowContentsWithContainer:self.containerName + context:self.contextID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + if(error){ + secerror("octagon: error fetching escrow contents: %@", error); + reply(nil, nil, nil, error); + }else{ + secnotice("octagon", "fetched escrow contents for bottle: %@", bottleID); + reply(entropy, bottleID, signingPublicKey, error); + } + }]; +} + +- (void)rpcValidatePeers:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply +{ + __block NSMutableDictionary* result = [NSMutableDictionary dictionary]; + + result[@"containerName"] = self.containerName; + result[@"contextID"] = self.contextID; + result[@"state"] = [self.stateMachine waitForState:OctagonStateReady wait:3*NSEC_PER_SEC]; + + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon", "No cloudkit account present"); + reply(NULL, [self errorNoiCloudAccount]); + return; + } + + [[self.cuttlefishXPCConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secnotice("octagon", "Unable to validatePeers RPC: %@", error); + reply(nil, error); + }] validatePeersWithContainer:self.containerName + context:self.contextID + reply:^(NSDictionary * _Nullable validateData, NSError * _Nullable dumpError) { + secnotice("octagon", "Finished validatePeers for status RPC"); + if(dumpError) { + result[@"error"] = dumpError; + } else { + result[@"validate"] = validateData; + } + reply(result, nil); + }]; +} + + +#pragma mark --- Testing +- (void) setAccountStateHolder:(OTCuttlefishAccountStateHolder*)accountMetadataStore +{ + self.accountMetadataStore = accountMetadataStore; +} + +- (void)setPostedBool:(BOOL)posted +{ + self.postedRepairCFU = posted; +} + +#pragma mark --- Health Checker + +- (BOOL)postRepairCFU:(NSError**)error +{ + NSError* localError = nil; + BOOL postSuccess = NO; + if (self.postedRepairCFU == NO) { + [self.followupHandler postFollowUp:OTFollowupContextTypeStateRepair error:&localError]; + if(localError){ + secerror("octagon-health: CoreCDP repair failed: %@", localError); + if(error){ + *error = localError; + } + } + else{ + secnotice("octagon-health", "CoreCDP post repair success"); + self.postedRepairCFU = YES; + postSuccess = YES; + } + } else { + secnotice("octagon-health", "already posted a repair CFU!"); + } + return postSuccess; +} + +- (BOOL)shouldPostConfirmPasscodeCFU:(NSError**)error +{ + NSError* localError = nil; + id request = [self.escrowRequestClass request:&localError]; + if(!request || localError) { + secnotice("octagon-health", "Unable to acquire a EscrowRequest object: %@", localError); + if(error){ + *error = localError; + } + return YES; + } + BOOL pendingUpload = [request pendingEscrowUpload:&localError]; + + if(localError) { + secnotice("octagon-health", "Failed to check escrow prerecord status: %@", localError); + if(error) { + *error = localError; + } + return YES; + } + + if(pendingUpload == YES) { + secnotice("octagon-health", "prerecord is pending, NOT posting CFU"); + return NO; + } else { + secnotice("octagon-health", "no pending prerecords, posting CFU"); + return YES; + } +} + +- (void)postConfirmPasscodeCFU:(NSError**)error +{ + NSError* localError = nil; + if (self.postedEscrowRepairCFU == NO) { + [self.followupHandler postFollowUp:OTFollowupContextTypeOfflinePasscodeChange error:&localError]; + if(localError){ + secerror("octagon-health: CoreCDP offline passcode change failed: %@", localError); + *error = localError; + } + else{ + secnotice("octagon-health", "CoreCDP offline passcode change success"); + self.postedEscrowRepairCFU = YES; + } + } else { + secnotice("octagon-health", "already posted escrow CFU"); + } +} + +- (void)postRecoveryKeyCFU:(NSError**)error +{ + NSError* localError = nil; + if (self.postedRecoveryKeyCFU == NO) { + [self.followupHandler postFollowUp:OTFollowupContextTypeRecoveryKeyRepair error:&localError]; + if(localError){ + secerror("octagon-health: CoreCDP recovery key cfu failed: %@", localError); + } + else{ + secnotice("octagon-health", "CoreCDP recovery key cfu success"); + self.postedRecoveryKeyCFU = YES; + } + } else { + secnotice("octagon-health", "already posted recovery key CFU"); + } +} + +- (void)checkOctagonHealth:(BOOL)skipRateLimitingCheck reply:(void (^)(NSError * _Nullable error))reply +{ + secnotice("octagon-health", "Beginning checking overall Octagon Trust"); + + _skipRateLimitingCheck = skipRateLimitingCheck; + + // Ending in "waitforunlock" is okay for a health check + [self.stateMachine doWatchedStateMachineRPC:@"octagon-trust-health-check" + sourceStates:OctagonHealthSourceStates() + path:[OctagonStateTransitionPath pathFromDictionary:@{ + OctagonStateHSA2HealthCheck: @{ + OctagonStateSecurityTrustCheck: @{ + OctagonStateTPHTrustCheck: @{ + OctagonStateCuttlefishTrustCheck: @{ + OctagonStateBecomeReady: @{ + OctagonStateReady: [OctagonStateTransitionPathStep success], + OctagonStateWaitForUnlock: [OctagonStateTransitionPathStep success], + }, + }, + }, + }, + OctagonStateWaitForHSA2: [OctagonStateTransitionPathStep success], + } + }] + reply:reply]; +} + +- (void)attemptSOSUpgrade:(void (^)(NSError* _Nullable error))reply +{ + secnotice("octagon-sos", "attempting to perform an sos upgrade"); + + if ([self checkForCKAccount:nil] != CKKSAccountStatusAvailable) { + secnotice("octagon-sos", "No cloudkit account present"); + reply([self errorNoiCloudAccount]); + return; + } + + NSSet* sourceStates = [NSSet setWithArray: @[OctagonStateUntrusted]]; + + OTSOSUpgradeOperation *pendingOp = [[OTSOSUpgradeOperation alloc] initWithDependencies:self.operationDependencies + intendedState:OctagonStateBecomeReady + ckksConflictState:OctagonStateBecomeUntrusted + errorState:OctagonStateBecomeUntrusted + deviceInfo:self.prepareInformation]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:@"attempt-sos-upgrade" + sourceStates:sourceStates + serialQueue:self.queue + timeout:OctagonStateTransitionDefaultTimeout + transitionOp:pendingOp]; + + CKKSResultOperation* callback = [CKKSResultOperation named:@"sos-upgrade-callback" + withBlock:^{ + secnotice("otrpc", "Returning from an sos upgrade attempt: %@", pendingOp.error); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradePreapprovedJoinAfterPairing hardFailure:false result:pendingOp.error]; + reply(pendingOp.error); + }]; + + [callback addDependency:pendingOp]; + [self.operationQueue addOperation: callback]; + + [self.stateMachine handleExternalRequest:request]; +} + +- (void)waitForOctagonUpgrade:(void (^)(NSError* error))reply +{ + secnotice("octagon-sos", "waitForOctagonUpgrade"); + + if (!self.sosAdapter.sosEnabled) { + secnotice("octagon-sos", "sos not enabled, nothing to do for waitForOctagonUpgrade"); + reply(nil); + return; + } + + if ([self.stateMachine isPaused]) { + if ([[self.stateMachine currentState] isEqualToString:OctagonStateReady]) { + secnotice("octagon-sos", "waitForOctagonUpgrade: already ready, returning"); + reply(nil); + return; + } + } else { + if ([[self.stateMachine waitForState:OctagonStateReady wait:10*NSEC_PER_SEC] isEqualToString:OctagonStateReady]) { + secnotice("octagon-sos", "waitForOctagonUpgrade: in ready (after waiting), returning"); + reply(nil); + return; + } else { + secnotice("octagon-sos", "waitForOctagonUpgrade: fail to get to ready after timeout, attempting upgrade"); + } + } + + NSSet* sourceStates = [NSSet setWithArray: @[OctagonStateUntrusted]]; + + OctagonStateTransitionPath* path = [OctagonStateTransitionPath pathFromDictionary:@{ + OctagonStateAttemptSOSUpgrade: @{ + OctagonStateBecomeReady: @{ + OctagonStateReady: [OctagonStateTransitionPathStep success], + }, + }, + }]; + + [self.stateMachine doWatchedStateMachineRPC:@"sos-upgrade-to-ready" + sourceStates:sourceStates + path:path + reply:reply]; +} + +- (void)clearPendingCFUFlags +{ + self.postedRecoveryKeyCFU = NO; + self.postedEscrowRepairCFU = NO; + self.postedRepairCFU = NO; +} + +@end +#endif diff --git a/keychain/ot/OTDefines.h b/keychain/ot/OTDefines.h index c5f36bff..1313fda0 100644 --- a/keychain/ot/OTDefines.h +++ b/keychain/ot/OTDefines.h @@ -28,39 +28,58 @@ #include NS_ASSUME_NONNULL_BEGIN -static NSString* const octagonErrorDomain = @"com.apple.security.octagon"; -static NSString* const OctagonEventAttributeZoneName = @"OTBottledPeer"; -static NSString* const OctagonEventAttributeFailureReason = @"OTFailureReason"; -static NSString* const OctagonEventAttributeTimeSinceLastPostedFollowUp = @"TimeSinceLastPostedFollowUp"; +extern NSString* const OctagonEventAttributeZoneName; +extern NSString* const OctagonEventAttributeFailureReason; +extern NSString* const OctagonEventAttributeTimeSinceLastPostedFollowUp; +extern NSString* OTCKContainerName; +extern NSString* const CuttlefishTrustZone; +extern NSString* const CuttlefishErrorDomain; +extern NSString* const TrustedPeersHelperErrorDomain; /* Octagon Errors */ -#define OTErrorNoColumn 1 -#define OTErrorKeyGeneration 2 -#define OTErrorEmptySecret 3 -#define OTErrorEmptyDSID 4 -#define OTErrorNoIdentity 5 -#define OTErrorRestoreFailed 6 -#define OTErrorRestoredPeerEncryptionKeyFailure 7 -#define OTErrorRestoredPeerSigningKeyFailure 8 -#define OTErrorEntropyCreationFailure 9 -#define OTErrorDeserializationFailure 10 -#define OTErrorDecryptFailure 11 -#define OTErrorPrivateKeyFailure 12 -#define OTErrorEscrowSigningSPKI 13 -#define OTErrorBottleID 14 -#define OTErrorOTLocalStore 15 -#define OTErrorOTCloudStore 16 -#define OTErrorEmptyEscrowRecordID 17 -#define OTErrorNoBottlePeerRecords 18 -#define OTErrorCoreFollowUp 19 -#define OTErrorFeatureNotEnabled 20 -#define OTErrorCKCallback 21 -#define OTErrorRampInit 22 -#define OTErrorCKTimeOut 23 -#define OTErrorNoNetwork 24 -#define OTErrorNotSignedIn 25 -#define OTErrorRecordNotFound 26 +typedef enum { + OTErrorNoColumn = 1, + OTErrorKeyGeneration = 2, + OTErrorEmptySecret = 3, + OTErrorEmptyDSID = 4, + OTErrorNoIdentity = 5, + OTErrorRestoreFailed = 6, + OTErrorRestoredPeerEncryptionKeyFailure = 7, + OTErrorRestoredPeerSigningKeyFailure = 8, + OTErrorEntropyCreationFailure = 9, + OTErrorDeserializationFailure = 10, + OTErrorDecryptFailure = 11, + OTErrorPrivateKeyFailure = 12, + OTErrorEscrowSigningSPKI = 13, + OTErrorBottleID = 14, + OTErrorOTLocalStore = 15, + OTErrorOTCloudStore = 16, + OTErrorEmptyEscrowRecordID = 17, + OTErrorNoBottlePeerRecords = 18, + OTErrorCoreFollowUp = 19, + OTErrorFeatureNotEnabled = 20, + OTErrorCKCallback = 21, + OTErrorRampInit = 22, + OTErrorCKTimeOut = 23, + OTErrorNoNetwork = 24, + OTErrorNotSignedIn = 25, + OTErrorRecordNotFound = 26, + OTErrorNoEscrowKeys = 27, + OTErrorBottleUpdate = 28, + OTErrorNotSupported = 29, + OTErrorUnexpectedStateTransition = 30, + OTErrorNoSuchContext = 31, + OTErrorTimeout = 32, + OTErrorMasterKey = 33, + OTErrorNotTrusted = 34, + OTErrorLimitedPeer = 35, + OTErrorNoOctagonKeysInSOS = 36, + OTErrorNeedsAuthentication = 37, + OTErrorOctagonAdapter = 38, + OTErrorSOSAdapter = 39, + OctagonErrorNoAccount = 40, +} OctagonErrorCode; #define OTMasterSecretLength 72 @@ -75,6 +94,18 @@ typedef enum { NOBOTTLE = 2 } OctagonBottleCheckState; +typedef NS_ENUM(NSInteger, TrustedPeersHelperErrorCode) { + TrustedPeersHelperErrorNoPreparedIdentity = 1, + TrustedPeersHelperErrorNoPeersPreapprovePreparedIdentity = 14, + TrustedPeersHelperErrorCodeNotEnrolled = 34, +}; + +typedef NS_ENUM(NSInteger, CuttlefishErrorCode) { + CuttlefishErrorResultGraphNotFullyReachable = 1007, + CuttlefishErrorTransactionalFailure = 1019, + CuttlefishErrorKeyHierarchyAlreadyExists = 1033, +}; + NS_ASSUME_NONNULL_END #endif #endif /* OTDefines_h */ diff --git a/keychain/ot/OTDefines.m b/keychain/ot/OTDefines.m new file mode 100644 index 00000000..76302f65 --- /dev/null +++ b/keychain/ot/OTDefines.m @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017-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 "keychain/ot/OTDefines.h" + +NSString* const OctagonEventAttributeZoneName = @"OTBottledPeer"; +NSString* const OctagonEventAttributeFailureReason = @"OTFailureReason"; +NSString* const OctagonEventAttributeTimeSinceLastPostedFollowUp = @"TimeSinceLastPostedFollowUp"; + +NSString* OTCKContainerName = @"com.apple.security.keychain"; +NSString* const CuttlefishTrustZone = @"CuttlefishTrustZone"; +NSString* const CuttlefishErrorDomain = @"CuttlefishError"; +NSString* const TrustedPeersHelperErrorDomain = @"com.apple.security.trustedpeers.container"; diff --git a/keychain/ot/OTDetermineHSA2AccountStatusOperation.h b/keychain/ot/OTDetermineHSA2AccountStatusOperation.h new file mode 100644 index 00000000..6e7eab1c --- /dev/null +++ b/keychain/ot/OTDetermineHSA2AccountStatusOperation.h @@ -0,0 +1,25 @@ + +#import + +#if OCTAGON + +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTDetermineHSA2AccountStatusOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + stateIfHSA2:(OctagonState*)stateIfHSA2 + stateIfNotHSA2:(OctagonState*)stateIfNotHSA2 + stateIfNoAccount:(OctagonState*)stateIfNoAccount + errorState:(OctagonState*)errorState; + +@property OctagonState* nextState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTDetermineHSA2AccountStatusOperation.m b/keychain/ot/OTDetermineHSA2AccountStatusOperation.m new file mode 100644 index 00000000..a74ff515 --- /dev/null +++ b/keychain/ot/OTDetermineHSA2AccountStatusOperation.m @@ -0,0 +1,97 @@ + +#if OCTAGON + +#import "utilities/debugging.h" + +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTDetermineHSA2AccountStatusOperation.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" + +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTDetermineHSA2AccountStatusOperation () +@property OTOperationDependencies* deps; + +@property OctagonState* stateIfNotHSA2; +@property OctagonState* stateIfNoAccount; +@property NSOperation* finishedOp; +@end + +@implementation OTDetermineHSA2AccountStatusOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + stateIfHSA2:(OctagonState*)stateIfHSA2 + stateIfNotHSA2:(OctagonState*)stateIfNotHSA2 + stateIfNoAccount:(OctagonState*)stateIfNoAccount + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = stateIfHSA2; + _stateIfNotHSA2 = stateIfNotHSA2; + _stateIfNoAccount = stateIfNoAccount; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + NSString* primaryAccountAltDSID = self.deps.authKitAdapter.primaryiCloudAccountAltDSID; + + NSError* error = nil; + + if(primaryAccountAltDSID != nil) { + secnotice("octagon", "iCloud account is present; checking HSA2 status"); + + bool hsa2 = [self.deps.authKitAdapter accountIsHSA2ByAltDSID:primaryAccountAltDSID]; + secnotice("octagon", "HSA2 is %@", hsa2 ? @"enabled" : @"disabled"); + + [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) { + if(hsa2) { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE; + } else { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT; + } + metadata.altDSID = primaryAccountAltDSID; + return metadata; + } error:&error]; + + // If there's an HSA2 account, return to 'initializing' here, as we want to centralize decisions on what to do next + if(hsa2) { + self.nextState = self.intendedState; + } else { + //[self.deps.accountStateTracker setHSA2iCloudAccountStatus:CKKSAccountStatusNoAccount]; + self.nextState = self.stateIfNotHSA2; + } + + } else { + secnotice("octagon", "iCloud account is not present"); + + [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) { + metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT; + metadata.altDSID = nil; + return metadata; + } error:&error]; + + self.nextState = self.stateIfNoAccount; + } + + if(error) { + secerror("octagon: unable to save new account state: %@", error); + } + + [self runBeforeGroupFinished:self.finishedOp]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTDeviceInformation.h b/keychain/ot/OTDeviceInformation.h new file mode 100644 index 00000000..39d49a9a --- /dev/null +++ b/keychain/ot/OTDeviceInformation.h @@ -0,0 +1,52 @@ +/* + * 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 + +NS_ASSUME_NONNULL_BEGIN + +@interface OTDeviceInformation : NSObject +@property NSString* containerName; +@property NSString* contextID; +@property uint64_t epoch; +@property NSString* machineID; +@property NSString* modelID; +@property NSString* deviceName; +@property NSString* serialNumber; +@property NSString* osVersion; + +- (instancetype)initForContainerName:(NSString*)containerName + contextID:(NSString*)contextID + epoch:(uint64_t)epoch + machineID:(NSString*)machineID + modelID:(NSString*)modelID + deviceName:(NSString*)deviceName + serialNumber:(NSString*)serialNumber + osVersion:(NSString*)osVersion; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTDeviceInformation.m b/keychain/ot/OTDeviceInformation.m new file mode 100644 index 00000000..f84a1d3e --- /dev/null +++ b/keychain/ot/OTDeviceInformation.m @@ -0,0 +1,68 @@ +/* + * 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 "keychain/ot/OTDeviceInformation.h" + +#import "keychain/ot/ObjCImprovements.h" +#import + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR +#include +#else +#include +#endif + +@implementation OTDeviceInformation + +- (instancetype)initForContainerName:(NSString*)containerName + contextID:(NSString*)contextID + epoch:(uint64_t)epoch + machineID:(NSString*)machineID + modelID:(NSString*)modelID + deviceName:(NSString*)deviceName + serialNumber:(NSString*)serialNumber + osVersion:(NSString*)osVersion +{ + if((self = [super init])) { + //otcuttlefish context + self.containerName = containerName; + self.contextID = contextID; + //our epoch + self.epoch = epoch; + + self.machineID = machineID; + self.modelID = modelID; + self.deviceName = deviceName; + self.serialNumber = serialNumber; + self.osVersion = osVersion; + } + return self; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTDeviceInformationAdapter.h b/keychain/ot/OTDeviceInformationAdapter.h new file mode 100644 index 00000000..f2c26f54 --- /dev/null +++ b/keychain/ot/OTDeviceInformationAdapter.h @@ -0,0 +1,26 @@ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol OTDeviceInformationAdapter + +/* Returns a string like "iPhone3,5" */ +- (NSString*)modelID; + +/* Returns the user-entered name for this device */ +- (NSString* _Nullable)deviceName; + +/* Returns a string describing the current os version */ +- (NSString*)osVersion; + +/* Returns the serial number as a string. */ +- (NSString*)serialNumber; + +@end + +@interface OTDeviceInformationActualAdapter : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/ot/OTDeviceInformationAdapter.m b/keychain/ot/OTDeviceInformationAdapter.m new file mode 100644 index 00000000..4fa6e072 --- /dev/null +++ b/keychain/ot/OTDeviceInformationAdapter.m @@ -0,0 +1,101 @@ +#import "OTDeviceInformationAdapter.h" +#import "keychain/ckks/CKKS.h" + +#include +#import + +#if TARGET_OS_OSX +#include +#include +#else +#import +#include +#endif + +@implementation OTDeviceInformationActualAdapter + +- (NSString*)modelID +{ + static NSString *hwModel = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#if TARGET_OS_SIMULATOR + // Asking for a real value in the simulator gives the results for the underlying mac. Not particularly useful. + hwModel = [NSString stringWithFormat:@"%s", getenv("SIMULATOR_MODEL_IDENTIFIER")]; +#elif TARGET_OS_OSX + size_t size; + sysctlbyname("hw.model", NULL, &size, NULL, 0); + char *sysctlString = malloc(size); + sysctlbyname("hw.model", sysctlString, &size, NULL, 0); + hwModel = [[NSString alloc] initWithUTF8String:sysctlString]; + free(sysctlString); + + // macOS running virtualized sometimes has new and unknown model IDs. + // So, if we don't recognize the model ID, return something more useful. + if(!([hwModel hasPrefix:@"iMac"] || + [hwModel hasPrefix:@"Mac"])) { + hwModel = [NSString stringWithFormat:@"MacUnknown-%@", hwModel]; + } +#else + struct utsname systemInfo; + uname(&systemInfo); + + hwModel = [NSString stringWithCString:systemInfo.machine + encoding:NSUTF8StringEncoding]; +#endif + }); + return hwModel; +} + +- (NSString* _Nullable)deviceName +{ + if (SecIsInternalRelease()) { + NSString *deviceName = CFBridgingRelease(SCDynamicStoreCopyComputerName(NULL, NULL)); + return deviceName; + } else { + return nil; + } +} + +- (NSString*)osVersion +{ + return SecCKKSHostOSVersion(); +} + +#if TARGET_OS_IPHONE + +#include + +- (NSString*)serialNumber +{ + int mgError = kMGNoError; + NSString *serialNumber = CFBridgingRelease(MGCopyAnswerWithError(kMGQSerialNumber, NULL, &mgError)); + if (![serialNumber isKindOfClass:[NSString class]]) { + serialNumber = nil; + secnotice("octagon", "failed getting serial number: %d", mgError); + } + return serialNumber; +} + +#else + +- (NSString*)serialNumber +{ + io_service_t platformExpert = IOServiceGetMatchingService(kIOMasterPortDefault, IOServiceMatching("IOPlatformExpertDevice")); + if (platformExpert == MACH_PORT_NULL) { + secnotice("octagon", "failed getting serial number (platform IOPlatformExpertDevice)"); + return nil; + } + NSString *serialNumber = CFBridgingRelease(IORegistryEntryCreateCFProperty(platformExpert, CFSTR(kIOPlatformSerialNumberKey), kCFAllocatorDefault, 0)); + if (![serialNumber isKindOfClass:[NSString class]]) { + serialNumber = nil; + secnotice("octagon", "failed getting serial number (IORegistryEntry)"); + } + IOObjectRelease(platformExpert); + return serialNumber; +} + +#endif + +@end + diff --git a/keychain/ot/OTEnsureOctagonKeyConsistency.h b/keychain/ot/OTEnsureOctagonKeyConsistency.h new file mode 100644 index 00000000..c8e1ae26 --- /dev/null +++ b/keychain/ot/OTEnsureOctagonKeyConsistency.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTEnsureOctagonKeyConsistency : CKKSGroupOperation +@property OctagonState* nextState; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; + +@property (weak) OTCuttlefishContext* cuttlefishContext; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTEnsureOctagonKeyConsistency.m b/keychain/ot/OTEnsureOctagonKeyConsistency.m new file mode 100644 index 00000000..985ee0a8 --- /dev/null +++ b/keychain/ot/OTEnsureOctagonKeyConsistency.m @@ -0,0 +1,140 @@ +/* + * 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 "keychain/ot/OTEnsureOctagonKeyConsistency.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" +#import "utilities/debugging.h" +#import +#import + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" +#import + +@interface OTEnsureOctagonKeyConsistency () +@property OTOperationDependencies* deps; + +@property NSOperation* finishOp; +@end + +@implementation OTEnsureOctagonKeyConsistency +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon-sos", "Beginning ensuring Octagon keys are the same between "); + + self.finishOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishOp]; + + if(!self.deps.sosAdapter.sosEnabled) { + self.error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorSOSAdapter userInfo:@{NSLocalizedDescriptionKey : @"sos adapter not enabled"}]; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + NSError* sosSelfFetchError = nil; + id sosSelf = [self.deps.sosAdapter currentSOSSelf:&sosSelfFetchError]; + + if(!sosSelf || sosSelfFetchError) { + secnotice("octagon-sos", "Failed to get the current SOS self: %@", sosSelfFetchError); + self.error = sosSelfFetchError; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + + secnotice("octagon", "Fetched SOS Self! Fetching Octagon Adapter now."); + + NSError* getEgoPeerError = nil; + NSString* octagonPeerID = [self.deps.stateHolder getEgoPeerID:&getEgoPeerError]; + if(getEgoPeerError) { + secnotice("octagon", "failed to get peer id: %@", getEgoPeerError); + self.error = getEgoPeerError; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + + OctagonCKKSPeerAdapter* octagonAdapter = [[OctagonCKKSPeerAdapter alloc] initWithPeerID:octagonPeerID operationDependencies:self.deps]; + + NSError* fetchSelfPeersError = nil; + CKKSSelves *selfPeers = [octagonAdapter fetchSelfPeers:&fetchSelfPeersError]; + if(fetchSelfPeersError) { + secnotice("octagon", "failed to retrieve self peers: %@", fetchSelfPeersError); + self.error = fetchSelfPeersError; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + + id currentSelfPeer = selfPeers.currentSelf; + if(currentSelfPeer == nil) { + secnotice("octagon", "failed to retrieve current self"); + self.error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOctagonAdapter userInfo: @{ NSLocalizedDescriptionKey : @"failed to retrieve current self"}]; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + + NSData* octagonSigningKeyData = currentSelfPeer.publicSigningKey.keyData; + NSData* octagonEncryptionKeyData = currentSelfPeer.publicEncryptionKey.keyData; + NSData* sosSigningKeyData = sosSelf.publicSigningKey.keyData; + NSData* sosEncryptionKeyData = sosSelf.publicEncryptionKey.keyData; + + if(![octagonSigningKeyData isEqualToData:sosSigningKeyData] || ![octagonEncryptionKeyData isEqualToData:sosEncryptionKeyData]) { + secnotice("octagon", "SOS and Octagon signing keys do NOT match! updating SOS"); + NSError* updateError = nil; + [self.deps.sosAdapter updateOctagonKeySetWithAccount:currentSelfPeer error:&updateError]; + if(updateError) { + self.error = updateError; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + } else { + secnotice("octagon", "SOS and Octagon keys match!"); + } + self.nextState = self.intendedState; + [self runBeforeGroupFinished:self.finishOp]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTEpochOperation.h b/keychain/ot/OTEpochOperation.h new file mode 100644 index 00000000..8180f4d2 --- /dev/null +++ b/keychain/ot/OTEpochOperation.h @@ -0,0 +1,50 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTEpochOperation : CKKSGroupOperation +@property OctagonState* nextState; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initForCuttlefishContext:(OTCuttlefishContext*)context + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; + +@property (weak) OTCuttlefishContext* cuttlefishContext; + +@property (nonatomic) uint64_t epoch; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTEpochOperation.m b/keychain/ot/OTEpochOperation.m new file mode 100644 index 00000000..6d74b5bf --- /dev/null +++ b/keychain/ot/OTEpochOperation.m @@ -0,0 +1,84 @@ +/* + * 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 "keychain/ot/OTEpochOperation.h" +#import "keychain/ot/OTCuttlefishContext.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@implementation OTEpochOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initForCuttlefishContext:(OTCuttlefishContext*)context + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _intendedState = intendedState; + _nextState = errorState; + self.cuttlefishContext = context; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "retrieving epoch"); + + NSOperation* finishOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:finishOp]; + + OTCuttlefishContext* strongCuttlefishContext = self.cuttlefishContext; + + WEAKIFY(self); + + [[strongCuttlefishContext.cuttlefishXPCConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:finishOp]; + + }] fetchEgoEpochWithContainer:strongCuttlefishContext.containerName + context:strongCuttlefishContext.contextID + reply:^(uint64_t epoch, NSError* _Nullable error) { + STRONGIFY(self); + if(error) { + secerror("octagon: Error getting epoch: %@", error); + self.error = error; + } else { + self.epoch = epoch; + self.nextState = self.intendedState; + } + [self runBeforeGroupFinished:finishOp]; + + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTEscrowKeys.h b/keychain/ot/OTEscrowKeys.h index d2d7975f..bf6b8802 100644 --- a/keychain/ot/OTEscrowKeys.h +++ b/keychain/ot/OTEscrowKeys.h @@ -50,8 +50,18 @@ typedef enum { dsid:(NSString*)dsid error:(NSError* __autoreleasing *)error; +- (nullable instancetype) initWithSigningKey:(SFECKeyPair*)signingKey + encryptionKey:(SFECKeyPair*)encryptionKey + symmetricKey:(SFAESKey*)symmetricKey; + + (SecKeyRef) createSecKey:(NSData*)keyData; + (BOOL) setKeyMaterialInKeychain:(NSDictionary*)query error:(NSError* __autoreleasing *)error; ++ (BOOL)findEscrowKeysForLabel:(NSString*)label + foundSigningKey:(SFECKeyPair*_Nonnull*_Nullable)signingKey + foundEncryptionKey:(SFECKeyPair*_Nonnull*_Nullable)encryptionKey + foundSymmetricKey:(SFAESKey*_Nonnull*_Nullable)symmetricKey + error:(NSError**)error; ++ (NSString*) hashEscrowedSigningPublicKey:(NSData*)keyData; + (NSData* _Nullable) generateEscrowKey:(escrowKeyType)keyType masterSecret:(NSData*)masterSecret diff --git a/keychain/ot/OTEscrowKeys.m b/keychain/ot/OTEscrowKeys.m index 1779714a..75e2ebf3 100644 --- a/keychain/ot/OTEscrowKeys.m +++ b/keychain/ot/OTEscrowKeys.m @@ -38,7 +38,7 @@ #import #import "keychain/ot/OTDefines.h" - +#import "keychain/ot/OTConstants.h" #import #import #import @@ -75,7 +75,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y if([secret length] == 0){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptySecret userInfo:@{NSLocalizedDescriptionKey: @"entropy/secret is nil"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEmptySecret userInfo:@{NSLocalizedDescriptionKey: @"entropy/secret is nil"}]; } return nil; } @@ -83,7 +83,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y if([dsid length] == 0){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptyDSID userInfo:@{NSLocalizedDescriptionKey: @"dsid is nil"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEmptyDSID userInfo:@{NSLocalizedDescriptionKey: @"dsid is nil"}]; } return nil; } @@ -99,7 +99,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y _signingKey = [[SFECKeyPair alloc] initWithSecKey:[OTEscrowKeys createSecKey:data]]; if(!_signingKey){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:@{NSLocalizedDescriptionKey: @"failed to create EC signing key"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorKeyGeneration userInfo:@{NSLocalizedDescriptionKey: @"failed to create EC signing key"}]; } return nil; } @@ -113,7 +113,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y _encryptionKey = [[SFECKeyPair alloc] initWithSecKey:[OTEscrowKeys createSecKey:data]]; if(!_encryptionKey){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:@{NSLocalizedDescriptionKey: @"failed to create EC encryption key"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorKeyGeneration userInfo:@{NSLocalizedDescriptionKey: @"failed to create EC encryption key"}]; } return nil; } @@ -131,8 +131,8 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y } return nil; } - - BOOL result = [OTEscrowKeys storeEscrowedSigningKeyPair:[_signingKey keyData] error:&localError]; + NSString* escrowSigningPubKeyHash = [OTEscrowKeys hashEscrowedSigningPublicKey:[[_signingKey publicKey] encodeSubjectPublicKeyInfo]]; + BOOL result = [OTEscrowKeys storeEscrowedSigningKeyPair:[_signingKey keyData] label:escrowSigningPubKeyHash error:&localError]; if(!result || localError){ secerror("octagon: could not store escrowed signing SPKI in keychain: %@", localError); if(error){ @@ -140,7 +140,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y } return nil; } - result = [OTEscrowKeys storeEscrowedEncryptionKeyPair:[_encryptionKey keyData] error:error]; + result = [OTEscrowKeys storeEscrowedEncryptionKeyPair:[_encryptionKey keyData] label:escrowSigningPubKeyHash error:error]; if(!result || localError){ secerror("octagon: could not store escrowed signing SPKI in keychain: %@", localError); if(error){ @@ -148,7 +148,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y } return nil; } - result = [OTEscrowKeys storeEscrowedSymmetricKey:[_symmetricKey keyData] error:error]; + result = [OTEscrowKeys storeEscrowedSymmetricKey:[_symmetricKey keyData] label:escrowSigningPubKeyHash error:error]; if(!result || localError){ secerror("octagon: could not store escrowed signing SPKI in keychain: %@", localError); if(error){ @@ -160,6 +160,19 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y return self; } +- (nullable instancetype) initWithSigningKey:(SFECKeyPair*)signingKey + encryptionKey:(SFECKeyPair*)encryptionKey + symmetricKey:(SFAESKey*)symmetricKey +{ + self = [super init]; + if(self){ + _signingKey = signingKey; + _encryptionKey = encryptionKey; + _symmetricKey = symmetricKey; + } + return self; +} + + (NSData* _Nullable) generateEscrowKey:(escrowKeyType)keyType masterSecret:(NSData*)masterSecret dsid:(NSString *)dsid @@ -206,7 +219,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y if (status != 0) { if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:nil]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorKeyGeneration userInfo:nil]; } secerror("octagon: could not generate seed for signing keys"); return nil; @@ -223,7 +236,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y fullKey); if(status != 0){ if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorKeyGeneration userInfo:nil]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorKeyGeneration userInfo:nil]; } secerror("octagon: could not generate signing keys"); return nil; @@ -275,7 +288,7 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y return result; } -+(NSString*) hashIt:(NSData*)keyData ++(NSString*) hashEscrowedSigningPublicKey:(NSData*)keyData { const struct ccdigest_info *di = ccsha384_di(); NSMutableData* result = [[NSMutableData alloc] initWithLength:ccsha384_di()->output_size]; @@ -286,50 +299,119 @@ static uint8_t escrowedSymmetric[] = {'E', 's', 'c', 'r', 'o', 'w', ' ', 'S', 'y return hash; } -+ (BOOL)storeEscrowedEncryptionKeyPair:(NSData*)keyData error:(NSError**)error ++ (BOOL)storeEscrowedEncryptionKeyPair:(NSData*)keyData label:(NSString*)label error:(NSError**)error { NSDictionary* query = @{ - (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecClass : (id)kSecClassKey, (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup: @"com.apple.security.ckks", (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, - (id)kSecAttrServer : [self hashIt:keyData], - (id)kSecAttrLabel : @"Escrowed Encryption Key", + (id)kSecAttrLabel : label, + (id)kSecAttrApplicationLabel : [[NSString stringWithFormat:@"Escrowed Encryption Key-%@", [NSUUID UUID].UUIDString] dataUsingEncoding:NSUTF8StringEncoding], (id)kSecValueData : keyData, }; return [OTEscrowKeys setKeyMaterialInKeychain:query error:error]; } -+ (BOOL)storeEscrowedSigningKeyPair:(NSData*)keyData error:(NSError**)error ++ (BOOL)storeEscrowedSigningKeyPair:(NSData*)keyData label:(NSString*)label error:(NSError**)error { NSDictionary* query = @{ - (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecClass : (id)kSecClassKey, (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup: @"com.apple.security.ckks", (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, - (id)kSecAttrLabel : @"Escrowed Signing Key", - (id)kSecAttrServer : [self hashIt:keyData], + (id)kSecAttrApplicationLabel : [[NSString stringWithFormat:@"Escrowed Signing Key-%@", [NSUUID UUID].UUIDString] dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrLabel : label, (id)kSecValueData : keyData, }; return [OTEscrowKeys setKeyMaterialInKeychain:query error:error]; } -+ (BOOL)storeEscrowedSymmetricKey:(NSData*)keyData error:(NSError**)error ++ (BOOL)storeEscrowedSymmetricKey:(NSData*)keyData label:(NSString*)label error:(NSError**)error { NSDictionary* query = @{ - (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecClass : (id)kSecClassKey, (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrAccessGroup: @"com.apple.security.ckks", (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, - (id)kSecAttrLabel : @"Escrowed Symmetric Key", - (id)kSecAttrServer : [self hashIt:keyData], + (id)kSecAttrApplicationLabel : [[NSString stringWithFormat:@"Escrowed Symmetric Key-%@", [NSUUID UUID].UUIDString] dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrLabel : label, (id)kSecValueData : keyData, }; return [OTEscrowKeys setKeyMaterialInKeychain:query error:error]; } ++ (NSArray*)retrieveEscrowKeysFromKeychain:(NSString* _Nonnull)label error:(NSError**)error +{ + NSError* localError = nil; + NSArray* keySet = nil; + + NSDictionary* query = @{ + (id)kSecClass : (id)kSecClassKey, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrLabel: label, + (id)kSecReturnAttributes: @YES, + (id)kSecReturnData : @YES, + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecMatchLimit : (id)kSecMatchLimitAll, + }; + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if(status != errSecSuccess || result == nil) { + secnotice("octagon", "no set of escrow keys for escrowed signing public key hash: %@", label); + localError = [NSError errorWithDomain:@"securityd" code:status userInfo:@{NSLocalizedDescriptionKey: @"no escrow key set for label"}]; + if(error){ + *error = localError; + } + } + + if(result && isArray(result)){ + secnotice("octagon", "found set of escrow keys for escrowed signing public key hash: %@", label); + keySet = (__bridge_transfer NSArray*)result; + } + + return keySet; +} + ++ (BOOL)findEscrowKeysForLabel:(NSString*)label foundSigningKey:(SFECKeyPair**)signingKey foundEncryptionKey:(SFECKeyPair**)encryptionKey foundSymmetricKey:(SFAESKey**)symmetricKey error:(NSError**)error +{ + BOOL result = NO; + NSError* localError = nil; + + NSArray* keySet = [OTEscrowKeys retrieveEscrowKeysFromKeychain:label error:&localError]; + + for(NSDictionary* item in keySet){ + + NSString* keyType = [[NSString alloc] initWithData:item[(id)kSecAttrApplicationLabel] encoding:NSUTF8StringEncoding]; + + if([keyType containsString:@"Symmetric"]){ + *symmetricKey = [[SFAESKey alloc] initWithData:item[(id)kSecValueData] specifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:&localError]; + }else if([keyType containsString:@"Encryption"]){ + SecKeyRef encryptionSecKey = [OTEscrowKeys createSecKey:item[(id)kSecValueData]]; + *encryptionKey = [[SFECKeyPair alloc] initWithSecKey:encryptionSecKey]; + CFReleaseNull(encryptionSecKey); + }else if([keyType containsString:@"Signing"]){ + SecKeyRef signingSecKey = [OTEscrowKeys createSecKey:item[(id)kSecValueData]]; + *signingKey = [[SFECKeyPair alloc] initWithSecKey:signingSecKey]; + CFReleaseNull(signingSecKey); + }else{ + secnotice("octagon", "unknown keychain item"); + } + } + if(*signingKey != nil && *encryptionKey != nil && *symmetricKey != nil){ + secnotice("octagon", "found escrow keys"); + result = YES; + }else{ + secerror("octagon: no matching escrow keys"); + } + + return result; +} + @end #endif diff --git a/keychain/ot/OTEstablishOperation.h b/keychain/ot/OTEstablishOperation.h new file mode 100644 index 00000000..f6ee5a9b --- /dev/null +++ b/keychain/ot/OTEstablishOperation.h @@ -0,0 +1,47 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + + +NS_ASSUME_NONNULL_BEGIN + +@interface OTEstablishOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + ckksConflictState:(OctagonState*)ckksConflictState + errorState:(OctagonState*)errorState; +@property (nonatomic) NSString* peerID; +@property OctagonState* nextState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTEstablishOperation.m b/keychain/ot/OTEstablishOperation.m new file mode 100644 index 00000000..e9719e3d --- /dev/null +++ b/keychain/ot/OTEstablishOperation.m @@ -0,0 +1,176 @@ +/* + * 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 "keychain/ot/OTEstablishOperation.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKSCurrentKeyPointer.h" +#import "keychain/ckks/CKKSKeychainView.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTEstablishOperation () +@property OTOperationDependencies* operationDependencies; + +@property OctagonState* ckksConflictState; + +@property NSOperation* finishedOp; +@end + +@implementation OTEstablishOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + ckksConflictState:(OctagonState*)ckksConflictState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _operationDependencies = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + _ckksConflictState = ckksConflictState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "Beginning an establish operation"); + + WEAKIFY(self); + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + STRONGIFY(self); + secnotice("octagon", "Finishing an establish operation with %@", self.error ?: @"no error"); + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + // First, interrogate CKKS views, and see when they have a TLK proposal. + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.operationDependencies]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"establish-with-keys" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets + pendingTLKShares:fetchKeysOp.pendingTLKShares]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets pendingTLKShares:(NSArray*)pendingTLKShares +{ + WEAKIFY(self); + + NSArray* publicSigningSPKIs = nil; + + if(self.operationDependencies.sosAdapter.sosEnabled) { + NSError* peerError = nil; + + secnotice("octagon-sos", "SOS not enabled; no preapproved keys"); + NSSet>* peerSet = [self.operationDependencies.sosAdapter fetchTrustedPeers:&peerError]; + + if(!peerSet || peerError) { + secerror("octagon-sos: Can't fetch trusted peers during establish: %@", peerError); + } + + publicSigningSPKIs = [OTSOSActualAdapter peerPublicSigningKeySPKIs:peerSet]; + secnotice("octagon-sos", "SOS preapproved keys are %@", publicSigningSPKIs); + } else { + secnotice("octagon-sos", "SOS not enabled; no preapproved keys"); + } + + NSError* persistError = nil; + BOOL persisted = [self.operationDependencies.stateHolder persistOctagonJoinAttempt:OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED error:&persistError]; + if(!persisted || persistError) { + secerror("octagon: failed to save 'attempted join' state: %@", persistError); + } + + secnotice("octagon-ckks", "Beginning establish with keys: %@", viewKeySets); + [[self.operationDependencies.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventEstablishIdentity withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] establishWithContainer:self.operationDependencies.containerName + context:self.operationDependencies.contextID + ckksKeys:viewKeySets + tlkShares:pendingTLKShares + preapprovedKeys:publicSigningSPKIs + reply:^(NSString * _Nullable peerID, NSArray* _Nullable keyHierarchyRecords, NSError * _Nullable error) { + STRONGIFY(self); + + [[CKKSAnalytics logger] logResultForEvent:OctagonEventEstablishIdentity hardFailure:true result:error]; + if(error) { + secerror("octagon: Error calling establish: %@", error); + + if ([error isCuttlefishError:CuttlefishErrorKeyHierarchyAlreadyExists]) { + secnotice("octagon-ckks", "A CKKS key hierarchy is out of date; moving to '%@'", self.ckksConflictState); + self.nextState = self.ckksConflictState; + } else { + self.error = error; + } + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + self.peerID = peerID; + + NSError* localError = nil; + BOOL persisted = [self.operationDependencies.stateHolder persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.trustState = OTAccountMetadataClassC_TrustState_TRUSTED; + metadata.peerID = peerID; + return metadata; + } error:&localError]; + if(!persisted || localError) { + secnotice("octagon", "Couldn't persist results: %@", localError); + self.error = localError; + } else { + self.nextState = self.intendedState; + } + + // Tell CKKS about our shiny new records! + for (id key in self.operationDependencies.viewManager.views) { + CKKSKeychainView* view = self.operationDependencies.viewManager.views[key]; + secnotice("octagon-ckks", "Providing records to %@", view); + [view receiveTLKUploadRecords: keyHierarchyRecords]; + } + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTFetchCKKSKeysOperation.h b/keychain/ot/OTFetchCKKSKeysOperation.h new file mode 100644 index 00000000..5bd5a0ee --- /dev/null +++ b/keychain/ot/OTFetchCKKSKeysOperation.h @@ -0,0 +1,33 @@ + +#if OCTAGON + +#import + +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ckks/CKKSKeychainBackedKey.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSKeychainView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTFetchCKKSKeysOperation : CKKSGroupOperation + +@property NSArray* viewKeySets; + +// This contains all key sets which couldn't be converted to CKKSKeychainBackedKeySet, due to some error +@property NSArray* incompleteKeySets; + +// Any existing TLKShares +@property NSArray* tlkShares; + +// Any new TLKShares that CKKS suggested we upload along with this keyset +@property NSArray* pendingTLKShares; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies; +- (instancetype)initWithViews:(NSSet*)views; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTFetchCKKSKeysOperation.m b/keychain/ot/OTFetchCKKSKeysOperation.m new file mode 100644 index 00000000..fc7fd5ed --- /dev/null +++ b/keychain/ot/OTFetchCKKSKeysOperation.m @@ -0,0 +1,119 @@ + +#if OCTAGON + +#import "keychain/ckks/CKKSNewTLKOperation.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTFetchCKKSKeysOperation () +@property NSSet* views; +@property CKKSViewManager* manager; +@end + +@implementation OTFetchCKKSKeysOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies +{ + if((self = [super init])) { + _manager = dependencies.viewManager; + _views = nil; + _viewKeySets = @[]; + _tlkShares = @[]; + _pendingTLKShares = @[]; + _incompleteKeySets = @[]; + } + return self; +} + +- (instancetype)initWithViews:(NSSet*)views +{ + if((self = [super init])) { + _views = views; + _manager = nil; + _viewKeySets = @[]; + _tlkShares = @[]; + _pendingTLKShares = @[]; + _incompleteKeySets = @[]; + } + return self; +} + +- (void)groupStart +{ + NSMutableArray*>* keyOps = [NSMutableArray array]; + + if (self.views == nil) { + NSMutableSet* mutViews = [NSMutableSet set]; + for (id key in self.manager.views) { + CKKSKeychainView* view = self.manager.views[key]; + [mutViews addObject: view]; + } + self.views = mutViews; + } + + for (CKKSKeychainView* view in self.views) { + secnotice("octagon-ckks", "Waiting for %@", view); + [keyOps addObject:[[view findKeySet] timeout:45*NSEC_PER_SEC]]; + } + + WEAKIFY(self); + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"proceed-with-ckks-keys" + withBlock:^{ + STRONGIFY(self); + + NSMutableArray* viewKeySets = [NSMutableArray array]; + NSMutableArray* ckksBrokenKeySets = [NSMutableArray array]; + NSMutableArray* tlkShares = [NSMutableArray array]; + NSMutableArray* pendingTLKShares = [NSMutableArray array]; + + for(CKKSResultOperation* op in keyOps) { + if(op.error) { + secnotice("octagon-ckks", "No keys for zone %@: %@", op.zoneName, op.error); + continue; + } + + NSError* localerror = nil; + CKKSKeychainBackedKeySet* keyset = [op.keyset asKeychainBackedSet:&localerror]; + + if(keyset) { + secnotice("octagon-ckks", "Have proposed keys: %@", op.keyset); + [viewKeySets addObject:keyset]; + } else { + secnotice("octagon-ckks", "Unable to convert proposed keys: %@ %@", op.keyset, localerror); + if(op.keyset) { + [ckksBrokenKeySets addObject:op.keyset]; + } + } + + for(CKKSTLKShareRecord* tlkShareRecord in op.keyset.tlkShares) { + [tlkShares addObject:tlkShareRecord.share]; + } + secnotice("octagon-ckks", "Have %u tlk shares", (uint32_t)op.keyset.tlkShares.count); + + for(CKKSTLKShareRecord* tlkShareRecord in op.keyset.pendingTLKShares) { + [pendingTLKShares addObject:tlkShareRecord.share]; + } + secnotice("octagon-ckks", "Have %u pending tlk shares", (uint32_t)op.keyset.pendingTLKShares.count); + } + + self.viewKeySets = viewKeySets; + self.incompleteKeySets = ckksBrokenKeySets; + self.tlkShares = tlkShares; + self.pendingTLKShares = pendingTLKShares; + + secnotice("octagon-ckks", "Fetched %d key sets, %d broken key set,s %d tlk shares, and %d pendingTLKShares", + (int)self.viewKeySets.count, + (int)self.incompleteKeySets.count, + (int)self.tlkShares.count, + (int)self.pendingTLKShares.count); + }]; + + for(CKKSResultOperation* op in keyOps) { + [proceedWithKeys addDependency: op]; + } + + [self runBeforeGroupFinished:proceedWithKeys]; +} +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTFetchViewsOperation.h b/keychain/ot/OTFetchViewsOperation.h new file mode 100644 index 00000000..b7fbb418 --- /dev/null +++ b/keychain/ot/OTFetchViewsOperation.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTFetchViewsOperation : CKKSGroupOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies; + +@property (nonatomic) NSSet* viewList; +@property (nonatomic) TPPolicy* _Nullable policy; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTFetchViewsOperation.m b/keychain/ot/OTFetchViewsOperation.m new file mode 100644 index 00000000..f041885c --- /dev/null +++ b/keychain/ot/OTFetchViewsOperation.m @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019 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 "keychain/ot/OTFetchViewsOperation.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ckks/CKKSAnalytics.h" + +@interface OTFetchViewsOperation () +@property OTOperationDependencies* deps; +@property NSOperation* finishedOp; +@property CKKSViewManager* ckm; +@end + +@implementation OTFetchViewsOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies +{ + if ((self = [super init])) { + _deps = dependencies; + _ckm = dependencies.viewManager; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "fetching views"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + NSSet* sosViewList = [self.ckm viewList]; + self.policy = nil; + self.viewList = sosViewList; + + if ([self.ckm useCKKSViewsFromPolicy]) { + WEAKIFY(self); + + NSXPCConnection* proxy = [self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logUnrecoverableError:error forEvent:OctagonEventFetchViews withAttributes:nil]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + }]; + if (proxy) { + [proxy fetchPolicyWithContainer:self.deps.containerName context:self.deps.contextID reply:^(TPPolicy* _Nullable policy, NSError* _Nullable error) { + STRONGIFY(self); + if (error) { + secerror("octagon: failed to retrieve policy: %@", error); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventFetchViews hardFailure:true result:error]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + } else { + if (policy == nil) { + secerror("octagon: no policy returned"); + } + self.policy = policy; + WEAKIFY(self); + NSArray* sosViews = [sosViewList allObjects]; + [proxy getViewsWithContainer:self.deps.containerName context:self.deps.contextID inViews:sosViews reply:^(NSArray* _Nullable outViews, NSError* _Nullable error) { + STRONGIFY(self); + if (error) { + secerror("octagon: failed to retrieve list of views: %@", error); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventFetchViews hardFailure:true result:error]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + } else { + if (outViews == nil) { + secerror("octagon: bad results from getviews"); + } else { + self.viewList = [NSSet setWithArray:outViews]; + } + [self complete]; + } + }]; + } + }]; + } + } else { + [self complete]; + } +} + +- (void)complete { + secnotice("octagon", "viewList: %@", self.viewList); + self.ckm.policy = self.policy; + self.ckm.viewList = self.viewList; + + [self.ckm createViews]; + [self.ckm beginCloudKitOperationOfAllViews]; + [self runBeforeGroupFinished:self.finishedOp]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTFollowup.h b/keychain/ot/OTFollowup.h new file mode 100644 index 00000000..f7aea060 --- /dev/null +++ b/keychain/ot/OTFollowup.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019 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 _OT_FOLLOWUP_H_ +#define _OT_FOLLOWUP_H_ + +#if OCTAGON + +#import +#import +#import "keychain/ckks/CKKSAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(uint8_t, OTFollowupContextType) { + OTFollowupContextTypeNone, + OTFollowupContextTypeRecoveryKeyRepair, + OTFollowupContextTypeStateRepair, + OTFollowupContextTypeOfflinePasscodeChange, +}; + +typedef NS_ENUM(uint8_t, OTFollowupStatus) { + OTFollowupStatusIdle = 0, + OTFollowupStatusSuccess = 1, + OTFollowupStatusFailed = 2, + OTFollowupStatusPending = 3, +}; + +@protocol OctagonFollowUpControllerProtocol +- (BOOL)postFollowUpWithContext:(CDPFollowUpContext *)context error:(NSError **)error; +- (BOOL)clearFollowUpWithContext:(CDPFollowUpContext *)context error:(NSError **)error; +@end +@interface CDPFollowUpController (Octagon) +@end + +@interface OTFollowup : NSObject +@property (readonly) OTFollowupStatus followupStatus; +- (id)initWithFollowupController:(id)cdpFollowupController; + +- (BOOL)postFollowUp:(OTFollowupContextType)contextType + error:(NSError **)error; +- (BOOL)clearFollowUp:(OTFollowupContextType)contextType + error:(NSError **)error; + +- (NSDictionary *)sysdiagnoseStatus; +- (NSDictionary *)sfaStatus; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON + +#endif // _OT_FOLLOWUP_H_ diff --git a/keychain/ot/OTFollowup.m b/keychain/ot/OTFollowup.m new file mode 100644 index 00000000..ad73b695 --- /dev/null +++ b/keychain/ot/OTFollowup.m @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2019 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 "OTFollowup.h" + +#if __has_include() && !TARGET_OS_SIMULATOR +#import +#define HAVE_COREFOLLOW_UP 1 +#endif + +#undef HAVE_COREFOLLOW_UP // XXX + +#import +#import + +#include "utilities/debugging.h" + +static NSString * const kOTFollowupEventCompleteKey = @"OTFollowupContextType"; + +@interface OTFollowup() +@property id cdpd; +@property NSTimeInterval previousFollowupEnd; +@property NSTimeInterval followupStart; +@property NSTimeInterval followupEnd; +@end + +@implementation OTFollowup : NSObject + +- (id)initWithFollowupController:(id)cdpFollowupController +{ + if (self = [super init]) { + self.cdpd = cdpFollowupController; + } + return self; +} + +- (CDPFollowUpContext *)createCDPFollowupContext:(OTFollowupContextType)contextType +{ + switch (contextType) { + case OTFollowupContextTypeStateRepair: { + return [CDPFollowUpContext contextForStateRepair]; + } + case OTFollowupContextTypeRecoveryKeyRepair: { + return [CDPFollowUpContext contextForRecoveryKeyRepair]; + } + case OTFollowupContextTypeOfflinePasscodeChange: { + return [CDPFollowUpContext contextForOfflinePasscodeChange]; + } + default: { + return nil; + } + } +} + +- (BOOL)postFollowUp:(OTFollowupContextType)contextType + error:(NSError **)error +{ + CDPFollowUpContext *context = [self createCDPFollowupContext:contextType]; + if (!context) { + return NO; + } + + NSError *followupError = nil; + BOOL result = [self.cdpd postFollowUpWithContext:context error:&followupError]; + if (error) { + *error = followupError; + } + + return result; +} + +- (BOOL)clearFollowUp:(OTFollowupContextType)contextType + error:(NSError **)error +{ + // Note(caw): we don't track metrics for clearing CFU prompts. + CDPFollowUpContext *context = [self createCDPFollowupContext:contextType]; + if (!context) { + return NO; + } + + return [self.cdpd clearFollowUpWithContext:context error:error]; +} + + +- (NSDictionary *)sysdiagnoseStatus +{ + NSMutableDictionary *pendingCFUs = nil; + +#if HAVE_COREFOLLOW_UP + if ([FLFollowUpController class]) { + NSError *error = nil; + pendingCFUs = [NSMutableDictionary dictionary]; + + FLFollowUpController *followUpController = [[FLFollowUpController alloc] initWithClientIdentifier:@"com.apple.corecdp"]; + NSArray * followUps = [followUpController pendingFollowUpItems:&error]; + if (error) { + secnotice("octagon", "Fetching pending follow ups failed with: %@", error); + pendingCFUs[@"error"] = [error description]; + } + for (FLFollowUpItem *followUp in followUps) { + NSDate *creationDate = followUp.notification.creationDate; + pendingCFUs[followUp.uniqueIdentifier] = creationDate; + } + } +#endif + return pendingCFUs; +} + +- (NSDictionary *)sfaStatus { + NSMutableDictionary* values = [NSMutableDictionary dictionary]; +#if HAVE_COREFOLLOW_UP + if ([FLFollowUpController class]) { + NSError *error = nil; + + //pretend to be CDP + FLFollowUpController *followUpController = [[FLFollowUpController alloc] initWithClientIdentifier:@"com.apple.corecdp"]; + + NSArray * followUps = [followUpController pendingFollowUpItems:&error]; + if (error) { + secnotice("octagon", "Fetching pending follow ups failed with: %@", error); + } + for (FLFollowUpItem *followUp in followUps) { + NSInteger created = 10000; + + NSDate *creationDate = followUp.notification.creationDate; + if (creationDate) { + created = [CKKSAnalytics fuzzyDaysSinceDate:creationDate]; + } + NSString *key = [NSString stringWithFormat:@"OACFU-%@", followUp.uniqueIdentifier]; + values[key] = @(created); + } + } +#endif + return values; +} + + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTIdentity.h b/keychain/ot/OTIdentity.h index 35ba3476..487cf7c2 100644 --- a/keychain/ot/OTIdentity.h +++ b/keychain/ot/OTIdentity.h @@ -42,7 +42,7 @@ NS_ASSUME_NONNULL_BEGIN + (nullable instancetype) currentIdentityFromSOS:(NSError**)error; --(BOOL)isEqual:(OTIdentity*)identity; +-(BOOL)isEqual:(OTIdentity* _Nullable)identity; +(BOOL) storeOctagonIdentityIntoKeychain:(_SFECKeyPair *)restoredSigningKey diff --git a/keychain/ot/OTIdentity.m b/keychain/ot/OTIdentity.m index a26c0eaf..616a2576 100644 --- a/keychain/ot/OTIdentity.m +++ b/keychain/ot/OTIdentity.m @@ -28,10 +28,10 @@ #import #import "keychain/ot/OTDefines.h" -#import +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#import +#import "keychain/SecureObjectSync/SOSAccount.h" #pragma clang diagnostic pop @interface OTIdentity () @@ -170,7 +170,7 @@ NSDictionary* query = @{ (id)kSecClass : (id)kSecClassInternetPassword, (id)kSecAttrAccessible: (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, (id)kSecAttrLabel : escrowSigningPubKeyHash, (id)kSecAttrAccount : restoredPeerID, (id)kSecAttrType : keyType, diff --git a/keychain/ot/OTJoinWithVoucherOperation.h b/keychain/ot/OTJoinWithVoucherOperation.h new file mode 100644 index 00000000..3668f4d1 --- /dev/null +++ b/keychain/ot/OTJoinWithVoucherOperation.h @@ -0,0 +1,56 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +@class OTOperationDependencies; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTJoinWithVoucherOperation : CKKSGroupOperation +@property OctagonState* nextState; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + ckksConflictState:(OctagonState*)ckksConflictState + errorState:(OctagonState*)errorState + voucherData:(NSData*)voucherData + voucherSig:(NSData*)voucherSig + preapprovedKeys:(NSArray*)preapprovedKeys; + +@property (nonatomic) NSData* voucherData; +@property (nonatomic) NSData* voucherSig; +@property (nonatomic) NSArray* preapprovedKeys; + +@property (nonatomic) NSString* peerID; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTJoinWithVoucherOperation.m b/keychain/ot/OTJoinWithVoucherOperation.m new file mode 100644 index 00000000..b8fba538 --- /dev/null +++ b/keychain/ot/OTJoinWithVoucherOperation.m @@ -0,0 +1,210 @@ +/* + * 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 "keychain/ot/OTJoinWithVoucherOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CloudKitCategories.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OTStates.h" + +@interface OTJoinWithVoucherOperation () +@property OTOperationDependencies* deps; + +@property OctagonState* ckksConflictState; + +@property NSOperation* finishedOp; +@property int retries; +@property int maxRetries; +@property int delay; +@property CKKSNearFutureScheduler* retrySched; +@end + +@implementation OTJoinWithVoucherOperation + +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + ckksConflictState:(OctagonState*)ckksConflictState + errorState:(OctagonState*)errorState + voucherData:(NSData*)voucherData + voucherSig:(NSData*)voucherSig + preapprovedKeys:(NSArray*)preapprovedKeys +{ + if((self = [super init])) { + _deps = dependencies; + + _retries = 0; + _maxRetries = 5; + _delay = 1; + + _intendedState = intendedState; + _nextState = errorState; + _ckksConflictState = ckksConflictState; + + _voucherData = voucherData; + _voucherSig = voucherSig; + _preapprovedKeys = preapprovedKeys; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "joining"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + WEAKIFY(self); + + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"vouch-with-keys" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets + pendingTLKShares:fetchKeysOp.pendingTLKShares]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (BOOL)isRetryable:(NSError* _Nonnull)error { + return [error isCuttlefishError:CuttlefishErrorTransactionalFailure]; +} + +- (int)retryDelay:(NSError* _Nonnull)error { + NSError* underlyingError = error.userInfo[NSUnderlyingErrorKey]; + int ret = self->_delay; + if (underlyingError) { + id tmp = underlyingError.userInfo[@"retryafter"]; + if ([tmp isKindOfClass:[NSNumber class]]) { + ret = [(NSNumber*)tmp intValue]; + } + } + ret = MAX(MIN(ret, 32), self->_delay); + self->_delay *= 2; + return ret; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets pendingTLKShares:(NSArray*)pendingTLKShares +{ + WEAKIFY(self); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventJoinWithVoucher withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] joinWithContainer:self.deps.containerName + context:self.deps.contextID + voucherData:self.voucherData + voucherSig:self.voucherSig + ckksKeys:viewKeySets + tlkShares:pendingTLKShares + preapprovedKeys:self.preapprovedKeys + reply:^(NSString * _Nullable peerID, NSArray* keyHierarchyRecords, NSError * _Nullable error) { + if(error){ + secerror("octagon: Error joining with voucher: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventJoinWithVoucher withAttributes:NULL]; + + if (self.retries < self.maxRetries && [self isRetryable:error]) { + ++self.retries; + if (!self.retrySched) { + self.retrySched = [[CKKSNearFutureScheduler alloc] initWithName:@"cuttlefish-join-retry" + delay:1*NSEC_PER_SEC + keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"vouch-with-keys" + withBlock:^{ + STRONGIFY(self); + secnotice("octagon", "retrying (%d/%d) join", self.retries, self->_maxRetries); + [self proceedWithKeys:viewKeySets + pendingTLKShares:pendingTLKShares]; + }]; + STRONGIFY(self); + [self runBeforeGroupFinished:proceedWithKeys]; + }]; + } + int delay_s = [self retryDelay:error]; + [self.retrySched waitUntil:delay_s*NSEC_PER_SEC]; + [self.retrySched trigger]; + return; + } + + // IF this is a CKKS conflict error, don't retry + if ([error isCuttlefishError:CuttlefishErrorKeyHierarchyAlreadyExists]) { + secnotice("octagon-ckks", "A CKKS key hierarchy is out of date; going to state '%@'", self.ckksConflictState); + self.nextState = self.ckksConflictState; + } else { + self.error = error; + } + } else { + self.peerID = peerID; + + [[CKKSAnalytics logger] logSuccessForEventNamed:OctagonEventJoinWithVoucher]; + + NSError* localError = nil; + BOOL persisted = [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.trustState = OTAccountMetadataClassC_TrustState_TRUSTED; + metadata.peerID = peerID; + return metadata; + } error:&localError]; + if(!persisted || localError) { + secnotice("octagon", "Couldn't persist results: %@", localError); + self.error = localError; + } else { + secerror("octagon: join successful"); + self.nextState = self.intendedState; + } + + // Tell CKKS about our shiny new records! + for (id key in self.deps.viewManager.views) { + CKKSKeychainView* view = self.deps.viewManager.views[key]; + secnotice("octagon-ckks", "Providing join() records to %@", view); + [view receiveTLKUploadRecords: keyHierarchyRecords]; + } + } + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTJoiningConfiguration.h b/keychain/ot/OTJoiningConfiguration.h new file mode 100644 index 00000000..af3b327a --- /dev/null +++ b/keychain/ot/OTJoiningConfiguration.h @@ -0,0 +1,69 @@ +/* + * 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_OT_OTJOININGCONFIGURATION_H +#define SECURITY_OT_OTJOININGCONFIGURATION_H 1 + +#if __OBJC2__ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface OTJoiningConfiguration : NSObject + +@property (nonatomic, strong) NSString* protocolType; +@property (nonatomic, strong) NSString* uniqueDeviceID; +@property (nonatomic, strong) NSString* uniqueClientID; +@property (nonatomic, strong) NSString* containerName; +@property (nonatomic, strong) NSString* contextID; +@property (nonatomic, strong) NSString* pairingUUID; +@property (nonatomic) uint64_t epoch; +@property (nonatomic) BOOL isInitiator; + +// Set this to non-zero if you want to configure your timeouts +@property int64_t timeout; + +- (instancetype)initWithProtocolType:(NSString*)protocolType + uniqueDeviceID:(NSString*)uniqueDeviceID + uniqueClientID:(NSString*)uniqueClientID + containerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + epoch:(uint64_t)epoch + isInitiator:(BOOL)isInitiator; + +- (instancetype)initWithProtocolType:(NSString*)protocolType + uniqueDeviceID:(NSString*)uniqueDeviceID + uniqueClientID:(NSString*)uniqueClientID + pairingUUID:(NSString* _Nullable)pairingUUID + containerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + epoch:(uint64_t)epoch + isInitiator:(BOOL)isInitiator; +-(instancetype)init NS_UNAVAILABLE; + +@end +NS_ASSUME_NONNULL_END + +#endif /* __OBJC2__ */ +#endif /* SECURITY_OT_OTJOININGCONFIGURATION_H */ diff --git a/keychain/ot/OTJoiningConfiguration.m b/keychain/ot/OTJoiningConfiguration.m new file mode 100644 index 00000000..339311f5 --- /dev/null +++ b/keychain/ot/OTJoiningConfiguration.m @@ -0,0 +1,110 @@ +/* + * 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 "keychain/ot/OTJoiningConfiguration.h" + +#if __OBJC2__ + +NS_ASSUME_NONNULL_BEGIN + +@implementation OTJoiningConfiguration + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (instancetype)initWithProtocolType:(NSString*)protocolType + uniqueDeviceID:(NSString*)uniqueDeviceID + uniqueClientID:(NSString*)uniqueClientID + containerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + epoch:(uint64_t)epoch + isInitiator:(BOOL)isInitiator +{ + return [self initWithProtocolType:protocolType + uniqueDeviceID:uniqueDeviceID + uniqueClientID:uniqueClientID + pairingUUID:[NSUUID UUID].UUIDString + containerName:containerName + contextID:contextID + epoch:(uint64_t)epoch + isInitiator:isInitiator]; +} + +- (instancetype)initWithProtocolType:(NSString*)protocolType + uniqueDeviceID:(NSString*)uniqueDeviceID + uniqueClientID:(NSString*)uniqueClientID + pairingUUID:(NSString* _Nullable)pairingUUID + containerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + epoch:(uint64_t)epoch + isInitiator:(BOOL)isInitiator +{ + self = [super init]; + if (self){ + self.protocolType = protocolType; + self.uniqueDeviceID = uniqueDeviceID; + self.uniqueClientID = uniqueClientID; + self.contextID = contextID; + self.containerName = containerName; + self.isInitiator = isInitiator; + self.pairingUUID = pairingUUID; + self.epoch = epoch; + + _timeout = 0; + } + return self; +} + +- (void)encodeWithCoder:(nonnull NSCoder *)coder { + [coder encodeObject:_protocolType forKey:@"protocolType"]; + [coder encodeObject:_uniqueClientID forKey:@"uniqueClientID"]; + [coder encodeObject:_uniqueDeviceID forKey:@"uniqueDeviceID"]; + [coder encodeObject:_contextID forKey:@"contextID"]; + [coder encodeObject:_containerName forKey:@"containerName"]; + [coder encodeBool:_isInitiator forKey:@"isInitiator"]; + [coder encodeObject:_pairingUUID forKey:@"pairingUUID"]; + [coder encodeInt64:_epoch forKey:@"epoch"]; + [coder encodeInt64:_timeout forKey:@"timeout"]; +} + +- (nullable instancetype)initWithCoder:(nonnull NSCoder *)decoder { + self = [super init]; + if (self) { + _protocolType = [decoder decodeObjectOfClass:[NSString class] forKey:@"protocolType"]; + _uniqueClientID = [decoder decodeObjectOfClass:[NSString class] forKey:@"uniqueClientID"]; + _uniqueDeviceID = [decoder decodeObjectOfClass:[NSString class] forKey:@"uniqueDeviceID"]; + _contextID = [decoder decodeObjectOfClass:[NSString class] forKey:@"contextID"]; + _containerName = [decoder decodeObjectOfClass:[NSString class] forKey:@"containerName"]; + _isInitiator = [decoder decodeBoolForKey:@"isInitiator"]; + _pairingUUID = [decoder decodeObjectOfClass:[NSString class] forKey:@"pairingUUID"]; + _epoch = [decoder decodeInt64ForKey:@"epoch"]; + _timeout = [decoder decodeInt64ForKey:@"timeout"]; + } + return self; +} + +@end +NS_ASSUME_NONNULL_END + +#endif /* __OBJC2__ */ diff --git a/keychain/ot/OTLeaveCliqueOperation.h b/keychain/ot/OTLeaveCliqueOperation.h new file mode 100644 index 00000000..4e3fa0f2 --- /dev/null +++ b/keychain/ot/OTLeaveCliqueOperation.h @@ -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@ + */ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTLeaveCliqueOperation : CKKSGroupOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTLeaveCliqueOperation.m b/keychain/ot/OTLeaveCliqueOperation.m new file mode 100644 index 00000000..e61e9b2f --- /dev/null +++ b/keychain/ot/OTLeaveCliqueOperation.m @@ -0,0 +1,93 @@ +/* + * 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 "keychain/ot/OTLeaveCliqueOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +@interface OTLeaveCliqueOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; +@end + +@implementation OTLeaveCliqueOperation +@synthesize intendedState = _intendedState; +@synthesize nextState = _nextState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "Attempting to leave clique"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + WEAKIFY(self); + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] departByDistrustingSelfWithContainer:self.deps.containerName + context:self.deps.contextID + reply:^(NSError * _Nullable error) { + STRONGIFY(self); + if(error) { + secnotice("octagon", "Unable to depart for (%@,%@): %@", self.deps.containerName, self.deps.contextID, error); + self.error = error; + } else { + NSError* localError = nil; + BOOL persisted = [self.deps.stateHolder persistNewTrustState:OTAccountMetadataClassC_TrustState_UNTRUSTED + error:&localError]; + if(!persisted || localError) { + secerror("octagon: unable to persist clique departure: %@", localError); + self.error = localError; + } else { + secnotice("octagon", "Successfully departed clique"); + self.nextState = self.intendedState; + } + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTLocalCKKSResetOperation.h b/keychain/ot/OTLocalCKKSResetOperation.h new file mode 100644 index 00000000..eef33f21 --- /dev/null +++ b/keychain/ot/OTLocalCKKSResetOperation.h @@ -0,0 +1,22 @@ + +#if OCTAGON + +#import + +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTLocalCKKSResetOperation : CKKSGroupOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; +@end + +NS_ASSUME_NONNULL_END + +#endif + diff --git a/keychain/ot/OTLocalCKKSResetOperation.m b/keychain/ot/OTLocalCKKSResetOperation.m new file mode 100644 index 00000000..d9db9844 --- /dev/null +++ b/keychain/ot/OTLocalCKKSResetOperation.m @@ -0,0 +1,65 @@ + +#if OCTAGON + +#import "utilities/debugging.h" + +#import "keychain/ot/OTLocalCKKSResetOperation.h" +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKSKeychainView.h" +#import "keychain/ckks/CKKSViewManager.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTLocalCKKSResetOperation () +@property OTOperationDependencies* operationDependencies; + +@property NSOperation* finishedOp; +@end + +@implementation OTLocalCKKSResetOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _operationDependencies = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon-ckks", "Beginning an 'reset CKKS' operation"); + + WEAKIFY(self); + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + STRONGIFY(self); + secnotice("octagon-ckks", "Finishing a ckks-local-reset operation with %@", self.error ?: @"no error"); + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + [self.operationDependencies.viewManager rpcResetLocal:nil reply: ^(NSError* _Nullable resultError) { + STRONGIFY(self); + + secnotice("octagon-ckks", "Finished ckks-local-reset with %@", self.error ?: @"no error"); + + if(resultError == nil) { + self.nextState = self.intendedState; + } else { + self.error = resultError; + } + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTLocalCuttlefishReset.h b/keychain/ot/OTLocalCuttlefishReset.h new file mode 100644 index 00000000..9e1b59bf --- /dev/null +++ b/keychain/ot/OTLocalCuttlefishReset.h @@ -0,0 +1,45 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTLocalResetOperation : CKKSGroupOperation + +- (instancetype)init:(NSString*)containerName + contextID:(NSString*)contextID + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + cuttlefishXPC:(id)cuttlefishXPC; +@end + +NS_ASSUME_NONNULL_END + +#endif + diff --git a/keychain/ot/OTLocalCuttlefishReset.m b/keychain/ot/OTLocalCuttlefishReset.m new file mode 100644 index 00000000..91a49b21 --- /dev/null +++ b/keychain/ot/OTLocalCuttlefishReset.m @@ -0,0 +1,93 @@ +/* + * 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 "keychain/ot/OTLocalCuttlefishReset.h" + +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "utilities/debugging.h" + +@interface OTLocalResetOperation () +@property NSString* containerName; +@property NSString* contextID; +@property id cuttlefishXPC; + +@property NSOperation* finishedOp; +@end + +@implementation OTLocalResetOperation +@synthesize intendedState = _intendedState; +@synthesize nextState = _nextState; + +- (instancetype)init:(NSString*)containerName + contextID:(NSString*)contextID + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + cuttlefishXPC:(id)cuttlefishXPC +{ + if((self = [super init])) { + _intendedState = intendedState; + _nextState = errorState; + + _containerName = containerName; + _contextID = contextID; + _cuttlefishXPC = cuttlefishXPC; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon-local-reset", "Resetting local cuttlefish"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + WEAKIFY(self); + [[self.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] localResetWithContainer:self.containerName + context:self.contextID + reply:^(NSError * _Nullable error) { + STRONGIFY(self); + if(error) { + secnotice("octagon", "Unable to reset local cuttlefish for (%@,%@): %@", self.containerName, self.contextID, error); + self.error = error; + } else { + secnotice("octagon", "Successfully reset local cuttlefish"); + self.nextState = self.intendedState; + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTLocalStore.m b/keychain/ot/OTLocalStore.m index 8e4c3e7a..e859c337 100644 --- a/keychain/ot/OTLocalStore.m +++ b/keychain/ot/OTLocalStore.m @@ -28,6 +28,7 @@ #import #include #import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #include #else @@ -86,7 +87,6 @@ static NSString* const bottledPeerTable = @"bp"; static NSString* const octagonZoctagonErrorDomainoneName = @"OctagonTrustZone"; /* Octagon Cloud Kit defines */ -static NSString* OTCKContainerName = @"com.apple.security.keychain"; static NSString* OTCKZoneName = @"OctagonTrust"; static NSString* OTCKRecordName = @"bp-"; static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; @@ -204,28 +204,28 @@ selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) if(![_pDB execute:bottledPeerSchema]){ secerror("octagon: could not create bottled peer schema"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEntropyCreationFailure userInfo:@{NSLocalizedDescriptionKey: @"could not create bottled peer schema"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEntropyCreationFailure userInfo:@{NSLocalizedDescriptionKey: @"could not create bottled peer schema"}]; } result = NO; } if(![_pDB execute:contextSchema]){ secerror("octagon: could not create contextschema"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not create context schema"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not create context schema"}]; } result = NO; } if(![_pDB setupPragmas]){ secerror("octagon: could not set up db pragmas"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not set up db pragmas"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not set up db pragmas"}]; } result = NO; } if(![_pDB setUserVersion:user_version]){ secerror("octagon: could not set version"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not set version"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"could not set version"}]; } result = NO; } @@ -369,7 +369,7 @@ selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) else{ secerror("octagon: no context attributes found"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"no context attributes found"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"no context attributes found"}]; } } @@ -446,7 +446,7 @@ selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) secerror("octagon: failed to update local context record: %@", _pDB.lastError); if(error != nil){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorNoColumn userInfo:nil]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNoColumn userInfo:nil]; } } return result; @@ -581,7 +581,7 @@ selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) if ([selectArray count] > 1) { secerror("octagon: error multiple records exist in local store for %@", recordID); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"error multiple records exist in local store"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"error multiple records exist in local store"}]; } return nil; } @@ -641,7 +641,7 @@ selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) if ([selectArray count] == 0) { secerror("octagon: there are no bottled peer entries in local store"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"there are no bottled peer entries in local store"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"there are no bottled peer entries in local store"}]; } return nil; } @@ -664,7 +664,7 @@ selectAll([db fetch:sql, ##__VA_ARGS__], [NSDictionary class]) if ([selectArray count] == 0) { secerror("octagon: there are no bottled peer entries in local store"); if(error){ - *error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"there are no bottled peer entries in local store"}]; + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorOTLocalStore userInfo:@{NSLocalizedDescriptionKey: @"there are no bottled peer entries in local store"}]; } return nil; } diff --git a/keychain/ot/OTManager.h b/keychain/ot/OTManager.h index 5c3aba0d..e5eee25d 100644 --- a/keychain/ot/OTManager.h +++ b/keychain/ot/OTManager.h @@ -25,30 +25,119 @@ #import #if OCTAGON +#import "Analytics/SFAnalytics.h" #import "keychain/ot/OTManager.h" #import "keychain/ot/OTContext.h" +#import "keychain/ot/OTFollowup.h" #import "keychain/ot/OTControlProtocol.h" +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OTAuthKitAdapter.h" +#import "keychain/ot/OTDeviceInformationAdapter.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #include - +#import NS_ASSUME_NONNULL_BEGIN @class OTContext; +@class OTCuttlefishContext; +@class OTClientStateMachine; +@class CKKSLockStateTracker; +@class CKKSAccountStateTracker; @interface OTManager : NSObject @property (nonatomic, readonly) NSDate *lastPostedCoreFollowUp; +@property (nonatomic, readonly) CKKSLockStateTracker* lockStateTracker; +@property id accountStateTracker; -(instancetype)init; --(instancetype) initWithContext:(OTContext* __nullable)context - localStore:(OTLocalStore* __nullable)localStore - enroll:(OTRamp*)enroll - restore:(OTRamp*)restore - cfu:(OTRamp*)cfu - cfuScheduler:(CKKSNearFutureScheduler*)cfuScheduler; +-(instancetype) initWithContext:(OTContext* _Nullable)context + localStore:(OTLocalStore* _Nullable)localStore + enroll:(OTRamp* _Nullable)enroll + restore:(OTRamp* _Nullable)restore + cfu:(OTRamp* _Nullable)cfu + cfuScheduler:(CKKSNearFutureScheduler* _Nullable)cfuScheduler + sosAdapter:(id)sosAdapter + authKitAdapter:(id)authKitAdapter + deviceInformationAdapter:(id)deviceInformationAdapter + apsConnectionClass:(Class)apsConnectionClass + escrowRequestClass:(Class)escrowRequestClass + loggerClass:(Class _Nullable)loggerClass + lockStateTracker:(CKKSLockStateTracker* _Nullable)lockStateTracker + accountStateTracker:(id)accountStateTracker + cuttlefishXPCConnection:(id _Nullable)cuttlefishXPCConnection + cdpd:(id)cdpd; + +// Call this to start up the state machinery +- (void)initializeOctagon; +- (void) moveToCheckTrustedStateForContainer:(NSString* _Nullable)containerName context:(NSString*)context; + (instancetype _Nullable)manager; ++ (instancetype _Nullable)resetManager:(bool)reset to:(OTManager* _Nullable)obj; +- (void)xpc24HrNotification:(NSString* _Nullable)containerName context:(NSString*)context skipRateLimitingCheck:(BOOL)skipRateLimitingCheck reply:(void (^)(NSError *error))reply; + -(BOOL)scheduledCloudKitRampCheck:(NSError**)error; + +- (OTCuttlefishContext*)contextForContainerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + sosAdapter:(id)sosAdapter + authKitAdapter:(id)authKitAdapter + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + accountStateTracker:(id)accountStateTracker + deviceInformationAdapter:(id)deviceInformationAdapter; + +- (OTCuttlefishContext*)contextForContainerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID; + +- (void)removeContextForContainerName:(NSString*)containerName + contextID:(NSString*)contextID; + +- (OTClientStateMachine*)clientStateMachineForContainerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + clientName:(NSString*)clientName; + +-(BOOL)ghostbustByMidEnabled; +-(BOOL)ghostbustBySerialEnabled; +-(BOOL)ghostbustByAgeEnabled; + +-(void)restore:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + bottleSalt:(NSString *)bottleSalt + entropy:(NSData *)entropy + bottleID:(NSString *)bottleID + reply:(void (^)(NSError * _Nullable))reply; + +- (void)createRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString *)recoveryKey + reply:(void (^)( NSError * _Nullable))reply; + +- (void)joinWithRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable))reply; + +- (void)allContextsHalt; +- (void)allContextsDisablePendingFlags; +- (bool)allContextsPause:(uint64_t)within; + +- (void)waitForOctagonUpgrade:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply; + +// Metrics and analytics +- (void)postCDPFollowupResult:(BOOL)success + type:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + containerName:(NSString* _Nullable)containerName + contextName:(NSString *)contextName + reply:(void (^)(NSError *error))reply; + +//test only +- (void)setSOSEnabledForPlatformFlag:(bool) value; @end NS_ASSUME_NONNULL_END diff --git a/keychain/ot/OTManager.m b/keychain/ot/OTManager.m index 4cbc9246..4e6f4461 100644 --- a/keychain/ot/OTManager.m +++ b/keychain/ot/OTManager.m @@ -22,21 +22,28 @@ */ -#import "SecEntitlements.h" +#include #import #import - #if OCTAGON +#import +#import "keychain/ot/ObjCImprovements.h" #import "keychain/ot/OTControlProtocol.h" #import "keychain/ot/OTControl.h" +#import "keychain/ot/OTClique.h" #import "keychain/ot/OTContext.h" #import "keychain/ot/OTManager.h" #import "keychain/ot/OTDefines.h" #import "keychain/ot/OTRamping.h" -#import "keychain/ot/SFPublicKey+SPKI.h" #import "keychain/ot/OT.h" #import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTBottledPeerState.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/OTJoiningConfiguration.h" +#import "keychain/ot/OTSOSAdapter.h" #import "keychain/categories/NSError+UsefulConstructors.h" #import "keychain/ckks/CKKSAnalytics.h" @@ -50,35 +57,51 @@ #import #import +#import "SecPasswordGenerate.h" + +#import "keychain/categories/NSError+UsefulConstructors.h" +#include +#import + +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" +#import "keychain/escrowrequest/EscrowRequestServer.h" + +// If your callbacks might pass back a CK error, you should use XPCSanitizeError() +// Otherwise, XPC might crash on the other side if they haven't linked CloudKit.framework. +#define XPCSanitizeError CKXPCSuitableError -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR #import #import #import #import #import #import -#else -#import -#import -#import -#import -#import -#import -#endif -#import +#import + +#import "keychain/TrustedPeersHelper/TPHObjcTranslation.h" +#import "keychain/SecureObjectSync/SOSAccountTransaction.h" #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -#import +#import "keychain/SecureObjectSync/SOSAccount.h" #pragma clang diagnostic pop +#import "utilities/SecTapToRadar.h" + static NSString* const kOTRampForEnrollmentRecordName = @"metadata_rampstate_enroll"; static NSString* const kOTRampForRestoreRecordName = @"metadata_rampstate_restore"; static NSString* const kOTRampForCFURecordName = @"metadata_rampstate_cfu"; +static NSString* const kOTRampForGhostBustMIDName = @"metadata_rampstate_ghostBustMID"; +static NSString* const kOTRampForghostBustSerialName = @"metadata_rampstate_ghostBustSerial"; +static NSString* const kOTRampForghostBustAgeName = @"metadata_rampstate_ghostBustAge"; static NSString* const kOTRampZoneName = @"metadata_zone"; #define NUM_NSECS_IN_24_HRS (86400 * NSEC_PER_SEC) +#if OCTAGON +@interface OTManager (lockstateTracker) +@end +#endif + @interface OTManager () @property NSXPCListener *listener; @property (nonatomic, strong) OTContext* context; @@ -86,11 +109,38 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; @property (nonatomic, strong) OTRamp *enrollRamp; @property (nonatomic, strong) OTRamp *restoreRamp; @property (nonatomic, strong) OTRamp *cfuRamp; +@property (nonatomic, strong) OTRamp *gbmidRamp; +@property (nonatomic, strong) OTRamp *gbserialRamp; +@property (nonatomic, strong) OTRamp *gbAgeRamp; @property (nonatomic, strong) CKKSNearFutureScheduler *cfuScheduler; @property (nonatomic, strong) NSDate *lastPostedCoreFollowUp; +@property (nonatomic, strong) OTBottledPeerState *bottleState; +@property (nonatomic, strong) CKKSLockStateTracker *lockStateTracker; +@property (nonatomic, strong) id cdpd; + +// Current contexts +@property NSMutableDictionary* contexts; +@property NSMutableDictionary* clients; +@property dispatch_queue_t queue; + +@property id cuttlefishXPCConnection; + +// Dependencies for injection +@property (readonly) id sosAdapter; +@property (readonly) id authKitAdapter; +@property (readonly) id deviceInformationAdapter; +@property (readonly) Class apsConnectionClass; +@property (readonly) Class escrowRequestClass; +// If this is nil, all logging is disabled +@property (readonly, nullable) Class loggerClass; +@property (nonatomic) BOOL sosEnabledForPlatform; @end @implementation OTManager +@synthesize cuttlefishXPCConnection = _cuttlefishXPCConnection; +@synthesize sosAdapter = _sosAdapter; +@synthesize authKitAdapter = _authKitAdapter; +@synthesize deviceInformationAdapter = _deviceInformationAdapter; -(instancetype)init { @@ -111,13 +161,30 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; //initialize our ramp objects [self initRamps]; + + // Under Octagon, the sos adatper is not considered essential. + id sosAdapter = (OctagonPlatformSupportsSOS() ? + [[OTSOSActualAdapter alloc] initAsEssential:NO] : + [[OTSOSMissingAdapter alloc] init]); return [self initWithContext:context localStore:localStore enroll:self.enrollRamp restore:self.restoreRamp cfu:self.cfuRamp - cfuScheduler:cfuScheduler]; + cfuScheduler:cfuScheduler + sosAdapter:sosAdapter + authKitAdapter:[[OTAuthKitActualAdapter alloc] init] + deviceInformationAdapter:[[OTDeviceInformationActualAdapter alloc] init] + apsConnectionClass:[APSConnection class] + escrowRequestClass:[EscrowRequestServer class] // Use the server class here to skip the XPC layer + loggerClass:[CKKSAnalytics class] + lockStateTracker:[CKKSLockStateTracker globalTracker] + // The use of CKKS's account tracker here is an inversion, and will be fixed with CKKS-for-all when we + // have Octagon own the CKKS objects + accountStateTracker:[CKKSViewManager manager].accountTracker + cuttlefishXPCConnection:nil + cdpd:[[CDPFollowUpController alloc] init]]; } -(instancetype) initWithContext:(OTContext*)context @@ -126,6 +193,16 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; restore:(OTRamp*)restore cfu:(OTRamp*)cfu cfuScheduler:(CKKSNearFutureScheduler*)cfuScheduler + sosAdapter:(id)sosAdapter + authKitAdapter:(id)authKitAdapter + deviceInformationAdapter:(id)deviceInformationAdapter + apsConnectionClass:(Class)apsConnectionClass + escrowRequestClass:(Class)escrowRequestClass + loggerClass:(Class)loggerClass + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + accountStateTracker:(id)accountStateTracker + cuttlefishXPCConnection:(id)cuttlefishXPCConnection + cdpd:(id)cdpd { self = [super init]; if(self){ @@ -134,47 +211,118 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; self.cfuRamp = cfu; self.enrollRamp = enroll; self.restoreRamp = restore; + _sosAdapter = sosAdapter; + _authKitAdapter = authKitAdapter; + _deviceInformationAdapter = deviceInformationAdapter; + _loggerClass = loggerClass; + _lockStateTracker = lockStateTracker; + _accountStateTracker = accountStateTracker; self.cfuScheduler = cfuScheduler; + _sosEnabledForPlatform = OctagonPlatformSupportsSOS(); + _cuttlefishXPCConnection = cuttlefishXPCConnection; + + self.contexts = [NSMutableDictionary dictionary]; + self.clients = [NSMutableDictionary dictionary]; + + self.queue = dispatch_queue_create("otmanager", DISPATCH_QUEUE_SERIAL); + + _apsConnectionClass = apsConnectionClass; + _escrowRequestClass = escrowRequestClass; + + _cdpd = cdpd; + + // The default CuttlefishContext always exists: + (void) [self contextForContainerName:OTCKContainerName contextID:OTDefaultContext]; + + // Tell SFA to expect us + if(OctagonIsEnabled()){ + [self setupAnalytics]; + } secnotice("octagon", "otmanager init"); } return self; } +- (void)initializeOctagon +{ + secnotice("octagon", "Initializing Octagon..."); + + if(OctagonIsEnabled()) { + secnotice("octagon", "starting default state machine..."); + OTCuttlefishContext* c = [self contextForContainerName:OTCKContainerName + contextID:OTDefaultContext]; + + [c startOctagonStateMachine]; + [self registerForCircleChangedNotifications]; + } +} + +- (void) moveToCheckTrustedStateForContainer:(NSString* _Nullable)containerName context:(NSString*)context +{ + OTCuttlefishContext* c = [self contextForContainerName:containerName + contextID:context]; + [c startOctagonStateMachine]; + [c moveToCheckTrustedState]; +} + +- (void)registerForCircleChangedNotifications +{ + __weak __typeof(self) weakSelf = self; + + // If we're not in the tests, go ahead and register for a notification + if(!SecCKKSTestsEnabled()) { + int token = 0; + notify_register_dispatch(kSOSCCCircleChangedNotification, &token, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^(int t) { + secnotice("octagon", "circle changed notification called, checking trust state"); + [weakSelf moveToCheckTrustedStateForContainer:OTCKContainerName context:OTDefaultContext]; + }); + } +} + -(NSString*) askAccountsForDSID { NSString *dsid = nil; - ACAccountStore *accountStore = [[ACAccountStore alloc] init]; + @try { + ACAccountStore *accountStore = [[ACAccountStore alloc] init]; -#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - ACAccount *account = [accountStore aa_primaryAppleAccount]; - dsid = [account aa_personID]; -#else - ACAccount *primaryiCloudAccount = nil; - if ([accountStore respondsToSelector:@selector(icaPrimaryAppleAccount)]){ - primaryiCloudAccount = [accountStore icaPrimaryAppleAccount]; + ACAccount *account = [accountStore aa_primaryAppleAccount]; + dsid = [account aa_personID]; + } @catch (NSException * e) { + secerror("octagon: failed to retrieve account: %@", e); } - dsid = [primaryiCloudAccount icaPersonID]; -#endif return dsid; } + (instancetype _Nullable)manager { - static OTManager* manager = nil; - - if(!SecOTIsEnabled()) { + if(!OctagonIsEnabled()) { secerror("octagon: Attempt to fetch a manager while Octagon is disabled"); return nil; } - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - manager = [[OTManager alloc]init]; - }); - return manager; + return [self resetManager:false to:nil]; } ++ (instancetype _Nullable)resetManager:(bool)reset to:(OTManager* _Nullable)obj +{ + static OTManager* manager = nil; + + if(!manager || reset || obj) { + @synchronized([self class]) { + if(obj != nil) { + manager = obj; + } else { + if(reset) { + manager = nil; + } else if (manager == nil && OctagonIsEnabled()) { + manager = [[OTManager alloc] init]; + } + } + } + } + + return manager; +} -(BOOL) initRamps { @@ -184,12 +332,12 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; CKDatabase* database = [container privateCloudDatabase]; CKRecordZoneID* zoneID = [[CKRecordZoneID alloc] initWithZoneName:kOTRampZoneName ownerName:CKCurrentUserDefaultName]; - CKKSCKAccountStateTracker *accountTracker = [CKKSViewManager manager].accountTracker; + CKKSAccountStateTracker *accountTracker = [CKKSViewManager manager].accountTracker; CKKSReachabilityTracker *reachabilityTracker = [CKKSViewManager manager].reachabilityTracker; CKKSLockStateTracker *lockStateTracker = [CKKSViewManager manager].lockStateTracker; self.cfuRamp = [[OTRamp alloc]initWithRecordName:kOTRampForCFURecordName - featureName:@"cfu" + localSettingName:@"cfu" container:container database:database zoneID:zoneID @@ -199,7 +347,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; self.enrollRamp = [[OTRamp alloc]initWithRecordName:kOTRampForEnrollmentRecordName - featureName:@"enroll" + localSettingName:@"enroll" container:container database:database zoneID:zoneID @@ -210,7 +358,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; self.restoreRamp = [[OTRamp alloc]initWithRecordName:kOTRampForRestoreRecordName - featureName:@"restore" + localSettingName:@"restore" container:container database:database zoneID:zoneID @@ -219,7 +367,37 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; reachabilityTracker:reachabilityTracker fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; - if(self.cfuRamp && self.enrollRamp && self.restoreRamp){ + self.gbmidRamp = [[OTRamp alloc]initWithRecordName:kOTRampForGhostBustMIDName + localSettingName:@"ghostBustMID" + container:container + database:database + zoneID:zoneID + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker + fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; + + self.gbserialRamp = [[OTRamp alloc]initWithRecordName:kOTRampForghostBustSerialName + localSettingName:@"ghostBustSerial" + container:container + database:database + zoneID:zoneID + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker + fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; + + self.gbAgeRamp = [[OTRamp alloc]initWithRecordName:kOTRampForghostBustAgeName + localSettingName:@"ghostBustAge" + container:container + database:database + zoneID:zoneID + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker + fetchRecordRecordsOperationClass:[CKFetchRecordsOperation class]]; + + if(self.cfuRamp && self.enrollRamp && self.restoreRamp && self.gbmidRamp && self.gbserialRamp && self.gbAgeRamp){ initResult = YES; } return initResult; @@ -227,7 +405,6 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; -(BOOL) initializeManagerPropertiesForContext:(NSString*)dsid error:(NSError**)error { - CKKSAnalytics* logger = [CKKSAnalytics logger]; NSError *localError = nil; BOOL initialized = YES; @@ -239,9 +416,6 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; self.localStore = [[OTLocalStore alloc] initWithContextID:OTDefaultContext dsid:dsid path:nil error:&localError]; if(!self.localStore){ secerror("octagon: could not create localStore: %@", localError); - [logger logUnrecoverableError:localError forEvent:OctagonEventSignIn withAttributes:@{ - OctagonEventAttributeFailureReason : @"creating local store", - }]; initialized = NO; } @@ -249,9 +423,6 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; self.context = [[OTContext alloc]initWithContextID:OTDefaultContext dsid:dsid localStore:self.localStore cloudStore:nil identityProvider:self error:&localError]; if(!self.context){ secerror("octagon: could not create context: %@", localError); - [logger logUnrecoverableError:localError forEvent:OctagonEventSignIn withAttributes:@{ - OctagonEventAttributeFailureReason : @"creating context", - }]; self.localStore = nil; initialized = NO; } @@ -265,100 +436,130 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; return initialized; } -/* - * SPI routines - */ +//// +// MARK: SPI routines +//// -- (void)signIn:(NSString*)dsid reply:(void (^)(BOOL result, NSError * _Nullable signedInError))reply + +- (void)signIn:(NSString*)altDSID + container:(NSString* _Nullable)containerName + context:(NSString*)contextID + reply:(void (^)(NSError * _Nullable signedInError))reply { - CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonSignIn withAction:nil]; - [tracker start]; + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityAccountAvailable]; - NSError *error = nil; - if(![self initializeManagerPropertiesForContext:dsid error:&error]){ - [tracker cancel]; - reply(NO, error); - return; + if(containerName == nil) { + containerName = OTCKContainerName; } - [tracker stop]; - [logger logSuccessForEventNamed:OctagonEventSignIn]; - - secnotice("octagon","created context and local store on manager for:%@", dsid); - - reply(YES, error); + NSError *error = nil; + OTCuttlefishContext* context = [self contextForContainerName:containerName contextID:contextID]; + + secnotice("octagon","signing in %@ for altDSID: %@", context, altDSID); + [context accountAvailable:altDSID error:&error]; + + [tracker stopWithEvent:OctagonEventSignIn result:error]; + + reply(error); } -- (void)signOut:(void (^)(BOOL result, NSError * _Nullable signedOutError))reply +- (void)signOut:(NSString* _Nullable)containerName + context:(NSString*)contextID + reply:(void (^)(NSError * _Nullable signedOutError))reply { - CKKSAnalytics* logger = [CKKSAnalytics logger]; - - NSError* error = nil; - NSError *bottledPeerError = nil; - NSError *localContextError = nil; - - secnotice("octagon", "signing out of octagon trust: dsid: %@ contextID: %@", - self.context.dsid, - self.context.contextID); - - NSString* contextAndDSID = [NSString stringWithFormat:@"%@-%@", self.context.contextID, self.context.dsid]; - - //remove all locally stored context - BOOL result1 = [self.localStore deleteLocalContext:contextAndDSID error:&localContextError]; - if(!result1){ - secerror("octagon: could not delete local context: %@: %@", self.context.contextID, localContextError); - [logger logUnrecoverableError:localContextError forEvent:OctagonEventSignOut withAttributes:@{ - OctagonEventAttributeFailureReason : @"deleting local context", - }]; - error = localContextError; + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityAccountNotAvailable]; + + if(containerName == nil) { + containerName = OTCKContainerName; } - - BOOL result2 = [self.localStore deleteBottledPeersForContextAndDSID:contextAndDSID error:&bottledPeerError]; - if(!result2){ - secerror("octagon: could not delete bottle peer records: %@: %@", self.context.contextID, bottledPeerError); - [logger logUnrecoverableError:bottledPeerError forEvent:OctagonEventSignOut withAttributes:@{ - OctagonEventAttributeFailureReason : @"deleting local bottled peers", - }]; - error = bottledPeerError; + + NSError* error = nil; + + // TODO: should we compare DSIDs here? + OTCuttlefishContext* context = [self contextForContainerName:containerName contextID:contextID]; + + secnotice("octagon", "signing out of octagon trust: %@", context); + + [context accountNoLongerAvailable:&error]; + if(error) { + secnotice("octagon", "signing out failed: %@", error); } - - //free context & local store - self.context = nil; - self.localStore = nil; - - BOOL result = (result1 && result2); - if (result) { - [logger logSuccessForEventNamed:OctagonEventSignOut]; + + [tracker stopWithEvent:OctagonEventSignOut result:error]; + + reply(error); +} + +- (void)notifyIDMSTrustLevelChangeForContainer:(NSString* _Nullable)containerName + context:(NSString*)contextID + reply:(void (^)(NSError * _Nullable error))reply +{ + if(containerName == nil) { + containerName = OTCKContainerName; } - - reply(result, error); + + NSError *error = nil; + OTCuttlefishContext* context = [self contextForContainerName:containerName contextID:contextID]; + secnotice("octagon","received a notification of IDMS trust level change in %@", context); + [context idmsTrustLevelChanged:&error]; + + reply(error); } -- (void)preflightBottledPeer:(NSString*)contextID - dsid:(NSString*)dsid - reply:(void (^)(NSData* _Nullable entropy, - NSString* _Nullable bottleID, - NSData* _Nullable signingPublicKey, - NSError* _Nullable error))reply + +- (void)handleIdentityChangeForSigningKey:(SFECKeyPair*)peerSigningKey + ForEncryptionKey:(SFECKeyPair*)encryptionKey + ForPeerID:(NSString*)peerID + reply:(void (^)(BOOL result, + NSError* _Nullable error))reply { - secnotice("octagon", "preflightBottledPeer: %@ %@", contextID, dsid); + secnotice("octagon", "handleIdentityChangeForSigningKey: %@", peerID); NSError* error = nil; + + if(self.context.lockStateTracker.isLocked){ + secnotice("octagon","device is locked! can't check ramp state"); + error = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain + code:errSecInteractionNotAllowed + userInfo:@{NSLocalizedDescriptionKey: @"device is locked"}]; + + reply(NO,error); + return; + } + + // Wait until the account tracker has had a chance to figure out the state + [self.context.accountTracker.ckAccountInfoInitialized wait:5*NSEC_PER_SEC]; + if(self.context.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ + secnotice("octagon","not signed in! can't check ramp state"); + error = [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNotSignedIn + userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; + reply(NO,error); + return; + + } + if(!self.context.reachabilityTracker.currentReachability){ + secnotice("octagon","no network! can't check ramp state"); + error = [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNoNetwork + userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; + reply(NO,error); + return; + } + CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonPreflightBottle withAction:nil]; + SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonUpdateBottle withAction:nil]; [tracker start]; if(!self.context || !self.localStore){ - if(![self initializeManagerPropertiesForContext:dsid error:&error]){ + if(![self initializeManagerPropertiesForContext:nil error:&error]){ secerror("octagon: could not init manager obejcts: %@", error); - reply(nil,nil,nil,error); + reply(NO,error); [tracker cancel]; return; } } - NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; + BOOL isFeatureOn = [self.enrollRamp checkRampStateWithError:&error]; //got an error from ramp check, we should log it if(error){ @@ -366,14 +567,62 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; forEvent:OctagonEventRamp zoneName:kOTRampZoneName withAttributes:@{ - OctagonEventAttributeFailureReason : @"ramp check for preflight bottle" + OctagonEventAttributeFailureReason : @"ramp check for updating bottle" }]; } - if(!isFeatureOn){ //cloud kit has not asked us to come back and the feature is off for this device + if(!isFeatureOn){ //the feature is off for this device + secnotice("octagon", "bottled peers is not on"); + if(!error){ + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + } + [tracker cancel]; + reply(NO, error); + return; + } + + BOOL updated = [self.context updateAllBottlesForPeerID:peerID newSigningKey:peerSigningKey newEncryptionKey:encryptionKey error:&error]; + + if(!updated || error != nil) { + secerror("octagon: failed to update bottles for %@, error: %@", peerID, error); + [logger logUnrecoverableError:error forEvent:OctagonEventUpdateBottle withAttributes:@{ OctagonEventAttributeFailureReason : @"failed to update bottles"}]; + [tracker cancel]; + reply(NO, error); + return; + } + + [tracker stop]; + [logger logSuccessForEventNamed:OctagonEventUpdateBottle]; + + secnotice("octagon", "handleIdentityChangeForSigningKey completed, updated bottles for: %@", peerID); + + reply(YES, error); +} + +- (void)preflightBottledPeer:(NSString*)contextID + dsid:(NSString*)dsid + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + secnotice("octagon", "preflightBottledPeer: %@ %@", contextID, dsid); + NSError* error = nil; + + if(!self.context || !self.localStore){ + if(![self initializeManagerPropertiesForContext:dsid error:&error]){ + secerror("octagon: could not init manager obejcts: %@", error); + reply(nil,nil,nil,error); + return; + } + } + + BOOL isFeatureOn = [self.enrollRamp checkRampStateWithError:&error]; + + if(!isFeatureOn){ //feature is off for this device secnotice("octagon", "bottled peers is not on"); if(!error){ - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; } reply(nil, nil, nil, error); return; @@ -382,11 +631,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; NSData* entropy = [self.context makeMeSomeEntropy:OTMasterSecretLength]; if(!entropy){ secerror("octagon: entropy creation failed: %@", error); - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEntropyCreationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to create entropy"}]; - [logger logUnrecoverableError:error forEvent:OctagonEventPreflightBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"preflight bottle, entropy failure"} - ]; - [tracker stop]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEntropyCreationFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to create entropy"}]; reply(nil, nil, nil, error); return; } @@ -394,15 +639,10 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; OTPreflightInfo* result = [self.context preflightBottledPeer:contextID entropy:entropy error:&error]; if(!result || error){ secerror("octagon: preflight failed: %@", error); - [logger logUnrecoverableError:error forEvent:OctagonEventPreflightBottle withAttributes:@{ OctagonEventAttributeFailureReason : @"preflight bottle"}]; reply(nil, nil, nil, error); - [tracker stop]; return; } - [tracker stop]; - [logger logSuccessForEventNamed:OctagonEventPreflightBottle]; - secnotice("octagon", "preflightBottledPeer completed, created: %@", result.bottleID); reply(entropy, result.bottleID, result.escrowedSigningSPKI, error); @@ -414,36 +654,20 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; { secnotice("octagon", "launchBottledPeer"); NSError* error = nil; - CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonLaunchBottle withAction:nil]; - [tracker start]; - if(!self.context || !self.localStore){ if(![self initializeManagerPropertiesForContext:nil error:&error]){ - [tracker cancel]; reply(error); return; } } - NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; - - //got an error from ramp check, we should log it - if(error){ - [logger logRecoverableError:error - forEvent:OctagonEventRamp - zoneName:kOTRampZoneName - withAttributes:@{ - OctagonEventAttributeFailureReason : @"ramp state check for launch bottle" - }]; - } + BOOL isFeatureOn = [self.enrollRamp checkRampStateWithError:&error]; if(!isFeatureOn){ secnotice("octagon", "bottled peers is not on"); if(!error){ - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; } reply(error); return; @@ -452,27 +676,16 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; OTBottledPeerRecord* bprecord = [self.localStore readLocalBottledPeerRecordWithRecordID:bottleID error:&error]; if(!bprecord || error){ secerror("octagon: could not retrieve record for: %@, error: %@", bottleID, error); - [logger logUnrecoverableError:error forEvent:OctagonEventLaunchBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"reading bottle from local store" - }]; - [tracker stop]; reply(error); return; } BOOL result = [self.context.cloudStore uploadBottledPeerRecord:bprecord escrowRecordID:bprecord.escrowRecordID error:&error]; if(!result || error){ secerror("octagon: could not upload record for bottleID %@, error: %@", bottleID, error); - [logger logUnrecoverableError:error forEvent:OctagonEventLaunchBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"upload bottle to cloud kit" - }]; - [tracker stop]; reply(error); return; } - - [tracker stop]; - [logger logSuccessForEventNamed:OctagonEventLaunchBottle]; - + secnotice("octagon", "successfully launched: %@", bprecord.recordName); reply(error); @@ -482,76 +695,42 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; { //check if configuration zone allows restore NSError* error = nil; - CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOctagonRestore withAction:nil]; - - [tracker start]; if(!self.context || !self.localStore){ if(![self initializeManagerPropertiesForContext:dsid error:&error]){ secerror("octagon: could not init manager obejcts: %@", error); reply(nil,nil,error); - [tracker cancel]; return; } } - NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.restoreRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; - - //got an error from ramp check, we should log it - if(error){ - [logger logRecoverableError:error - forEvent:OctagonEventRamp - zoneName:kOTRampZoneName - withAttributes:@{ - OctagonEventAttributeFailureReason : @"checking ramp state for restore" - }]; - } + BOOL isFeatureOn = [self.restoreRamp checkRampStateWithError:&error]; if(!isFeatureOn){ secnotice("octagon", "bottled peers is not on"); if(!error){ - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; } - [tracker stop]; reply(nil, nil, error); return; } if(!escrowRecordID || [escrowRecordID length] == 0){ secerror("octagon: missing escrowRecordID"); - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptyEscrowRecordID userInfo:@{NSLocalizedDescriptionKey: @"Escrow Record ID is empty or missing"}]; - - [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"escrow record id missing", - }]; - - [tracker stop]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEmptyEscrowRecordID userInfo:@{NSLocalizedDescriptionKey: @"Escrow Record ID is empty or missing"}]; + reply(nil, nil, error); return; } if(!dsid || [dsid length] == 0){ secerror("octagon: missing dsid"); - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptyDSID userInfo:@{NSLocalizedDescriptionKey: @"DSID is empty or missing"}]; - - [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"dsid missing", - }]; - [tracker stop]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEmptyDSID userInfo:@{NSLocalizedDescriptionKey: @"DSID is empty or missing"}]; reply(nil, nil, error); return; } if(!secret || [secret length] == 0){ secerror("octagon: missing secret"); - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorEmptySecret userInfo:@{NSLocalizedDescriptionKey: @"Secret is empty or missing"}]; - - - [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"secret missing", - }]; - - [tracker stop]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorEmptySecret userInfo:@{NSLocalizedDescriptionKey: @"Secret is empty or missing"}]; reply(nil, nil, error); return; } @@ -559,43 +738,31 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; OTBottledPeerSigned *bps = [_context restoreFromEscrowRecordID:escrowRecordID secret:secret error:&error]; if(!bps || error != nil){ secerror("octagon: failed to restore bottled peer: %@", error); - - [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"restore failed", - }]; - [tracker stop]; reply(nil, nil, error); return; } - NSData *encryptionKeyData = bps.bp.peerEncryptionKey.publicKey.keyData; // FIXME + SFECKeyPair *encryptionKey = bps.bp.peerEncryptionKey; + SFPublicKey *encryptionPublicKey = encryptionKey.publicKey; + NSData* encryptionKeyData = encryptionPublicKey.keyData;// FIXME + if(!encryptionKeyData){ secerror("octagon: restored octagon encryption key is nil: %@", error); - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorRestoredPeerEncryptionKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to retrieve restored Octagon Peer Encryption Key"}]; - - [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"restored octagon encryption key" - }]; - [tracker stop]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorRestoredPeerEncryptionKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to retrieve restored Octagon Peer Encryption Key"}]; reply(nil,nil,error); return; } - - NSData *signingKeyData = bps.bp.peerSigningKey.publicKey.keyData; // FIXME + + SFECKeyPair *signingKey = bps.bp.peerSigningKey; + SFPublicKey *signingKeyPublicKey = signingKey.publicKey; + NSData* signingKeyData = signingKeyPublicKey.keyData;// FIXME + if(!signingKeyData){ secerror("octagon: restored octagon signing key is nil: %@", error); - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorRestoredPeerSigningKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to retrieve restored Octagon Peer Signing Key"}]; - - [logger logUnrecoverableError:error forEvent:OctagonEventRestoreBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"restored octagon signing key" - }]; - [tracker stop]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorRestoredPeerSigningKeyFailure userInfo:@{NSLocalizedDescriptionKey: @"Failed to retrieve restored Octagon Peer Signing Key"}]; reply(nil,nil,error); return; } - [tracker stop]; - - [logger logSuccessForEventNamed:OctagonEventRestoreBottle]; secnotice("octagon", "restored bottled peer: %@", escrowRecordID); @@ -608,37 +775,20 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; { NSError* error = nil; - CKKSAnalytics* logger = [CKKSAnalytics logger]; - SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityScrubBottle withAction:nil]; - if(!self.context || !self.localStore){ if(![self initializeManagerPropertiesForContext:nil error:&error]){ - [tracker cancel]; reply(error); return; } } - [tracker start]; - NSInteger retryDelayInSeconds = 0; - BOOL isFeatureOn = [self.enrollRamp checkRampState:&retryDelayInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; - - //got an error from ramp check, we should log it - if(error){ - [logger logRecoverableError:error - forEvent:OctagonEventRamp - zoneName:kOTRampZoneName - withAttributes:@{ - OctagonEventAttributeFailureReason : @"ramp check for scrubbing bottled peer" - }]; - } + BOOL isFeatureOn = [self.enrollRamp checkRampStateWithError:&error]; if(!isFeatureOn){ secnotice("octagon", "bottled peers is not on"); if(!error){ - error = [NSError errorWithDomain:octagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorFeatureNotEnabled userInfo:@{NSLocalizedDescriptionKey: @"Feature not enabled"}]; } - [tracker stop]; reply(error); return; } @@ -646,25 +796,20 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; BOOL result = [self.context scrubBottledPeer:contextID bottleID:bottleID error:&error]; if(!result || error){ secerror("octagon: could not scrub record for bottleID %@, error: %@", bottleID, error); - [logger logUnrecoverableError:error forEvent:OctagonEventScrubBottle withAttributes:@{ - OctagonEventAttributeFailureReason : @"could not scrub bottle", - }]; - [tracker stop]; reply(error); return; } - [logger logSuccessForEventNamed:OctagonEventScrubBottle]; secnotice("octagon", "scrubbed bottled peer: %@", bottleID); reply(error); } -/* - * OTCTL tool routines - */ +//// +// MARK: OTCTL tool routines +//// --(void) reset:(void (^)(BOOL result, NSError *))reply +-(void)reset:(void (^)(BOOL result, NSError *))reply { NSError* error = nil; @@ -685,9 +830,12 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; reply(NO,error); return; } + + // Wait until the account tracker has had a chance to figure out the state + [self.context.accountTracker.ckAccountInfoInitialized wait:5*NSEC_PER_SEC]; if(self.context.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ secnotice("octagon","not signed in! can't check ramp state"); - error = [NSError errorWithDomain:octagonErrorDomain + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNotSignedIn userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; reply(NO,error); @@ -696,7 +844,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } if(!self.context.reachabilityTracker.currentReachability){ secnotice("octagon","no network! can't check ramp state"); - error = [NSError errorWithDomain:octagonErrorDomain + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNoNetwork userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; reply(NO,error); @@ -720,7 +868,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; reply(result, bottledPeerError); } -- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError *))reply +- (void)listOfEligibleBottledPeerRecords:(void (^)(NSArray* listOfRecords, NSError * _Nullable))reply { NSError* error = nil; if(!self.context || !self.localStore){ @@ -740,9 +888,12 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; reply(nil,error); return; } + + // Wait until the account tracker has had a chance to figure out the state + [self.context.accountTracker.ckAccountInfoInitialized wait:5*NSEC_PER_SEC]; if(self.context.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ secnotice("octagon","not signed in! can't check ramp state"); - error = [NSError errorWithDomain:octagonErrorDomain + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNotSignedIn userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; reply(nil,error); @@ -750,7 +901,7 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; } if(!self.context.reachabilityTracker.currentReachability){ secnotice("octagon","no network! can't check ramp state"); - error = [NSError errorWithDomain:octagonErrorDomain + error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNoNetwork userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; reply(nil,error); @@ -808,21 +959,20 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; reply(signingKey, localError); } -/* - * OT Helpers - */ +//// +// MARK: OT Helpers +//// -(BOOL)scheduledCloudKitRampCheck:(NSError**)error { secnotice("octagon", "scheduling a CloudKit ramping check"); - NSInteger retryAfterInSeconds = 0; NSError* localError = nil; BOOL cancelScheduler = YES; CKKSAnalytics* logger = [CKKSAnalytics logger]; if(self.cfuRamp){ - BOOL canCFU = [self.cfuRamp checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError]; + BOOL canCFU = [self.cfuRamp checkRampStateWithError:&localError]; if(localError){ secerror("octagon: checking ramp state for CFU error'd: %@", localError); @@ -900,6 +1050,840 @@ static NSString* const kOTRampZoneName = @"metadata_zone"; return [OTIdentity currentIdentityFromSOS:error]; } +- (void)setCuttlefishXPCConnection:(id)cuttlefishXPCConnection +{ + _cuttlefishXPCConnection = cuttlefishXPCConnection; +} + +- (id)cuttlefishXPCConnection +{ + if(!_cuttlefishXPCConnection) { + NSXPCConnection* xpcConnection = [[NSXPCConnection alloc] initWithServiceName:@"com.apple.TrustedPeersHelper"]; + xpcConnection.remoteObjectInterface = TrustedPeersHelperSetupProtocol([NSXPCInterface interfaceWithProtocol:@protocol(TrustedPeersHelperProtocol)]); + [xpcConnection resume]; + _cuttlefishXPCConnection = xpcConnection; + } + + return _cuttlefishXPCConnection; +} + +- (OTClientStateMachine*)clientStateMachineForContainerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + clientName:(NSString*)clientName +{ + __block OTClientStateMachine* client = nil; + + if(containerName == nil) { + containerName = SecCKKSContainerName; + } + + dispatch_sync(self.queue, ^{ + NSString* key = [NSString stringWithFormat:@"%@-%@", containerName, clientName]; + secnotice("octagon-client", "fetching context for key: %@", key); + client = self.clients[key]; + if(!client) { + client = [[OTClientStateMachine alloc] initWithContainerName:containerName + contextID:contextID + clientName:clientName + cuttlefish:self.cuttlefishXPCConnection]; + + self.clients[key] = client; + } + }); + + return client; +} + +- (void)removeClientContextForContainerName:(NSString* _Nullable)containerName + clientName:(NSString*)clientName +{ + if(containerName == nil) { + containerName = SecCKKSContainerName; + } + + dispatch_sync(self.queue, ^{ + NSString* key = [NSString stringWithFormat:@"%@-%@", containerName, clientName]; + [self.clients removeObjectForKey:key]; + secnotice("octagon", "removed client context with key: %@", key); + }); +} + +- (void)removeContextForContainerName:(NSString*)containerName + contextID:(NSString*)contextID +{ + dispatch_sync(self.queue, ^{ + NSString* key = [NSString stringWithFormat:@"%@-%@", containerName, contextID]; + self.contexts[key] = nil; + }); +} + +- (OTCuttlefishContext*)contextForContainerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID +{ + return [self contextForContainerName:containerName + contextID:contextID + sosAdapter:self.sosAdapter + authKitAdapter:self.authKitAdapter + lockStateTracker:self.lockStateTracker + accountStateTracker:self.accountStateTracker + deviceInformationAdapter:self.deviceInformationAdapter]; +} + +- (OTCuttlefishContext*)contextForContainerName:(NSString* _Nullable)containerName + contextID:(NSString*)contextID + sosAdapter:(id)sosAdapter + authKitAdapter:(id)authKitAdapter + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + accountStateTracker:(CKKSAccountStateTracker*)accountStateTracker + deviceInformationAdapter:(id)deviceInformationAdapter +{ + __block OTCuttlefishContext* context = nil; + + if(containerName == nil) { + containerName = SecCKKSContainerName; + } + + dispatch_sync(self.queue, ^{ + NSString* key = [NSString stringWithFormat:@"%@-%@", containerName, contextID]; + + context = self.contexts[key]; + + // Right now, CKKS can only handle one session per address space (and SQL database). + // Therefore, only the primary OTCuttlefishContext gets to own the view manager. + CKKSViewManager* viewManager = nil; + if([containerName isEqualToString:SecCKKSContainerName] && + [contextID isEqualToString:OTDefaultContext]) { + viewManager = [CKKSViewManager manager]; + } + + if(!context) { + context = [[OTCuttlefishContext alloc] initWithContainerName:containerName + contextID:contextID + cuttlefish:self.cuttlefishXPCConnection + sosAdapter:sosAdapter + authKitAdapter:authKitAdapter + ckksViewManager:viewManager + lockStateTracker:lockStateTracker + accountStateTracker:accountStateTracker + deviceInformationAdapter:deviceInformationAdapter + apsConnectionClass:self.apsConnectionClass + escrowRequestClass:self.escrowRequestClass + cdpd:self.cdpd]; + self.contexts[key] = context; + } + }); + + return context; +} + +- (void)fetchEgoPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))reply +{ + if(!container) { + container = OTCKContainerName; + } + secnotice("octagon", "Received a fetch peer ID for container (%@) and context (%@)", container, context); + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext rpcFetchEgoPeerID:^(NSString * _Nullable peerID, + NSError * _Nullable error) { + reply(peerID, XPCSanitizeError(error)); + }]; +} + +- (void)fetchTrustStatus:(NSString *)container + context:(NSString *)context + configuration:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus status, + NSString* _Nullable peerID, + NSNumber * _Nullable numberOfPeersInOctagon, + BOOL isExcluded, + NSError* _Nullable error))reply +{ + if(!container) { + container = OTCKContainerName; + } + secnotice("octagon", "Received a trust status for container (%@) and context (%@)", container, context); + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + + [cfshContext rpcTrustStatus:configuration reply:^(CliqueStatus status, + NSString * _Nullable peerID, + NSDictionary * _Nullable peerCountByModelID, + BOOL isExcluded, + NSError * _Nullable error) { + // Our clients don't need the whole breakout of peers, so just count for them + long peerCount = 0; + for(NSNumber* n in peerCountByModelID.allValues) { + peerCount += [n longValue]; + } + + reply(status, peerID, @(peerCount), isExcluded, error); + }]; +} + +- (void)fetchCliqueStatus:(NSString* _Nullable)container + context:(NSString*)contextID + configuration:(OTOperationConfiguration *)configuration + reply:(void (^)(CliqueStatus cliqueStatus, NSError* _Nullable error))reply +{ + if(!container) { + container = OTCKContainerName; + } + if(configuration == nil) { + configuration = [[OTOperationConfiguration alloc] init]; + } + + __block OTCuttlefishContext* context = nil; + dispatch_sync(self.queue, ^{ + NSString* key = [NSString stringWithFormat:@"%@-%@", container, contextID]; + + context = self.contexts[key]; + }); + + if(!context) { + reply(-1, [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNoSuchContext + description:[NSString stringWithFormat:@"No context for (%@,%@)", container, contextID]]); + return; + } + + + [context rpcTrustStatus:configuration reply:^(CliqueStatus status, + NSString* egoPeerID, + NSDictionary * _Nullable peerCountByModelID, + BOOL isExcluded, + NSError * _Nullable error) { + reply(status, error); + }]; +} + +- (void)status:(NSString* _Nullable)containerName + context:(NSString*)contextID + reply:(void (^)(NSDictionary* _Nullable result, NSError* _Nullable error))reply +{ + if(!containerName) { + containerName = OTCKContainerName; + } + + secnotice("octagon", "Received a status RPC for container (%@) and context (%@)", containerName, contextID); + + __block OTCuttlefishContext* context = nil; + dispatch_sync(self.queue, ^{ + NSString* key = [NSString stringWithFormat:@"%@-%@", containerName, contextID]; + + context = self.contexts[key]; + }); + + if(!context) { + reply(nil, [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNoSuchContext + description:[NSString stringWithFormat:@"No context for (%@,%@)", containerName, contextID]]); + return; + } + + [context rpcStatus:reply]; +} + +- (void)startOctagonStateMachine:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply +{ + secnotice("octagon", "Received a start-state-machine RPC for container (%@) and context (%@)", container, context); + + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext startOctagonStateMachine]; + reply(nil); +} + +- (void)resetAndEstablish:(NSString *)container + context:(NSString *)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError * _Nullable))reply +{ + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityResetAndEstablish]; + + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext startOctagonStateMachine]; + [cfshContext rpcResetAndEstablish:^(NSError* resetAndEstablishError) { + [tracker stopWithEvent:OctagonEventResetAndEstablish result:resetAndEstablishError]; + reply(resetAndEstablishError); + }]; +} + +- (void)establish:(NSString *)container + context:(NSString *)context + altDSID:(NSString*)altDSID + reply:(void (^)(NSError * _Nullable))reply +{ + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityEstablish]; + + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext startOctagonStateMachine]; + [cfshContext rpcEstablish:altDSID reply:^(NSError* establishError) { + [tracker stopWithEvent:OctagonEventEstablish result:establishError]; + reply(establishError); + }]; +} + +- (void)leaveClique:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSError* _Nullable error))reply +{ + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityLeaveClique]; + + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext startOctagonStateMachine]; + [cfshContext rpcLeaveClique:^(NSError* leaveError) { + [tracker stopWithEvent:OctagonEventLeaveClique result:leaveError]; + reply(leaveError); + }]; +} + +- (void)removeFriendsInClique:(NSString* _Nullable)container + context:(NSString*)context + peerIDs:(NSArray*)peerIDs + reply:(void (^)(NSError* _Nullable error))reply +{ + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityRemoveFriendsInClique]; + + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext startOctagonStateMachine]; + [cfshContext rpcRemoveFriendsInClique:peerIDs reply:^(NSError* removeFriendsError) { + [tracker stopWithEvent:OctagonEventRemoveFriendsInClique result:removeFriendsError]; + reply(removeFriendsError); + }]; +} + +- (void)peerDeviceNamesByPeerID:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSDictionary* _Nullable peers, NSError* _Nullable error))reply +{ + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext rpcFetchDeviceNamesByPeerID:reply]; +} + +- (void)fetchAllViableBottles:(NSString* _Nullable)container + context:(NSString*)context + reply:(void (^)(NSArray* _Nullable sortedBottleIDs, NSArray* _Nullable sortedPartialBottleIDs, NSError* _Nullable error))reply +{ + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityFetchAllViableBottles]; + + OTCuttlefishContext* cfshContext = [self contextForContainerName:container contextID:context]; + [cfshContext rpcFetchAllViableBottles:^(NSArray * _Nullable sortedBottleIDs, + NSArray * _Nullable sortedPartialEscrowRecordIDs, + NSError * _Nullable error) { + [tracker stopWithEvent:OctagonEventFetchAllBottles result:error]; + reply(sortedBottleIDs, sortedPartialEscrowRecordIDs, error); + }]; +} + +- (void)fetchEscrowContents:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityFetchEscrowContents]; + + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:contextID]; + [cfshContext fetchEscrowContents:^(NSData *entropy, + NSString *bottleID, + NSData *signingPublicKey, + NSError *error) { + [tracker stopWithEvent:OctagonEventFetchEscrowContents result:error]; + reply(entropy, bottleID, signingPublicKey, error); + }]; +} + +//// +// MARK: Pairing Routines as Initiator +//// +- (void)rpcPrepareIdentityAsApplicantWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error))reply +{ + OTCuttlefishContext* cfshContext = [self contextForContainerName:config.containerName contextID:config.contextID]; + [cfshContext handlePairingRestart:config]; + [cfshContext startOctagonStateMachine]; + [cfshContext rpcPrepareIdentityAsApplicantWithConfiguration:config epoch:config.epoch reply:^(NSString * _Nullable peerID, NSData * _Nullable permanentInfo, NSData * _Nullable permanentInfoSig, NSData * _Nullable stableInfo, NSData * _Nullable stableInfoSig, NSError * _Nullable error) { + reply(peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error); + }]; +} + +- (void)rpcJoinWithConfiguration:(OTJoiningConfiguration*)config + vouchData:(NSData*)vouchData + vouchSig:(NSData*)vouchSig + preapprovedKeys:(NSArray* _Nullable)preapprovedKeys + reply:(void (^)(NSError * _Nullable error))reply +{ + OTCuttlefishContext* cfshContext = [self contextForContainerName:config.containerName contextID:config.contextID]; + [cfshContext handlePairingRestart:config]; + [cfshContext startOctagonStateMachine]; + [cfshContext rpcJoin:vouchData vouchSig:vouchSig preapprovedKeys:preapprovedKeys reply:^(NSError * _Nullable error) { + reply(error); + }]; +} + +//// +// MARK: Pairing Routines as Acceptor +//// + +- (void)rpcEpochWithConfiguration:(OTJoiningConfiguration*)config + reply:(void (^)(uint64_t epoch, + NSError * _Nullable error))reply +{ + OTCuttlefishContext* acceptorCfshContext = [self contextForContainerName:config.containerName contextID:config.contextID]; + [acceptorCfshContext startOctagonStateMachine]; + + // Let's assume that the new device's machine ID has made it to the IDMS list by now, and let's refresh our idea of that list + [acceptorCfshContext requestTrustedDeviceListRefresh]; + + OTClientStateMachine *clientStateMachine = [self clientStateMachineForContainerName:config.containerName contextID:config.contextID clientName:config.pairingUUID]; + + [clientStateMachine startOctagonStateMachine]; + + [clientStateMachine rpcEpoch:acceptorCfshContext reply:^(uint64_t epoch, NSError * _Nullable error) { + reply(epoch, error); + }]; +} + +- (void)rpcVoucherWithConfiguration:(OTJoiningConfiguration*)config + peerID:(NSString*)peerID + permanentInfo:(NSData *)permanentInfo + permanentInfoSig:(NSData *)permanentInfoSig + stableInfo:(NSData *)stableInfo + stableInfoSig:(NSData *)stableInfoSig + reply:(void (^)(NSData* voucher, NSData* voucherSig, NSError * _Nullable error))reply +{ + OTCuttlefishContext* acceptorCfshContext = [self contextForContainerName:config.containerName contextID:config.contextID]; + [acceptorCfshContext startOctagonStateMachine]; + + // Let's assume that the new device's machine ID has made it to the IDMS list by now, and let's refresh our idea of that list + [acceptorCfshContext requestTrustedDeviceListRefresh]; + OTClientStateMachine *clientStateMachine = [self clientStateMachineForContainerName:config.containerName contextID:config.contextID clientName:config.pairingUUID]; + + [clientStateMachine rpcVoucher:acceptorCfshContext peerID:peerID permanentInfo:permanentInfo permanentInfoSig:permanentInfoSig stableInfo:stableInfo stableInfoSig:stableInfoSig reply:^(NSData *voucher, NSData *voucherSig, NSError *error) { + reply(voucher, voucherSig, error); + }]; +} + +- (void)restore:(NSString * _Nullable)containerName + contextID:(nonnull NSString *)contextID + bottleSalt:(nonnull NSString *)bottleSalt + entropy:(nonnull NSData *)entropy + bottleID:(nonnull NSString *)bottleID + reply:(nonnull void (^)(NSError * _Nullable))reply { + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityBottledPeerRestore]; + + secnotice("octagon", "restore via bottle invoked for container: %@, context: %@", containerName, contextID); + + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:contextID]; + + [cfshContext startOctagonStateMachine]; + + [cfshContext joinWithBottle:bottleID entropy:entropy bottleSalt:bottleSalt reply:^(NSError *error) { + [tracker stopWithEvent:OctagonEventBottledPeerRestore result:error]; + reply(error); + }]; +} + +//// +// MARK: Ghost busting using ramp records +//// + +-(BOOL) ghostbustByMidEnabled { + return [self.gbmidRamp checkRampStateWithError:nil]; +} + +-(BOOL) ghostbustBySerialEnabled { + return [self.gbserialRamp checkRampStateWithError:nil]; +} + +-(BOOL) ghostbustByAgeEnabled { + return [self.gbAgeRamp checkRampStateWithError:nil]; +} + +//// +// MARK: Analytics +//// + +- (void)setupAnalytics +{ + WEAKIFY(self); + + [[self.loggerClass logger] AddMultiSamplerForName:@"Octagon-healthSummary" + withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport + block:^NSDictionary *{ + STRONGIFY(self); + + // We actually only care about the default context for the default container + OTCuttlefishContext* cuttlefishContext = [self contextForContainerName:OTCKContainerName contextID:OTDefaultContext]; + + secnotice("octagon-analytics", "Reporting analytics for container: %@, context: %@", OTCKContainerName, OTDefaultContext); + + NSMutableDictionary* values = [NSMutableDictionary dictionary]; + + NSError* error = nil; + SOSCCStatus sosStatus = [self.sosAdapter circleStatus:&error]; + if(error) { + secnotice("octagon-analytics", "Error fetching SOS status: %@", error); + } + values[OctagonAnalyticsSOSStatus] = @((int)sosStatus); + NSDate* dateOfLastPPJ = [[CKKSAnalytics logger] datePropertyForKey:OctagonEventUpgradePreflightPreapprovedJoin]; + values[OctagonAnalyticsDateOfLastPreflightPreapprovedJoin] = @([CKKSAnalytics fuzzyDaysSinceDate:dateOfLastPPJ]); + + values[OctagonAnalyticsStateMachineState] = OctagonStateMap()[cuttlefishContext.stateMachine.currentState]; + + values[OctagonAnalyticIcloudAccountState] = @([cuttlefishContext currentMemoizedAccountState]); + values[OctagonAnalyticsTrustState] = @([cuttlefishContext currentMemoizedTrustState]); + NSDate* healthCheck = [cuttlefishContext currentMemoizedLastHealthCheck]; + values[OctagonAnalyticsLastHealthCheck] = @([CKKSAnalytics fuzzyDaysSinceDate:healthCheck]); + + NSDate* dateOfLastKSR = [[CKKSAnalytics logger] datePropertyForKey: OctagonAnalyticsLastKeystateReady]; + values[OctagonAnalyticsLastKeystateReady] = @([CKKSAnalytics fuzzyDaysSinceDate:dateOfLastKSR]); + + // Track CFU usage and success/failure metrics + // 1. Users in a good state will have no outstanding CFU, and will not have done a CFU + // 2. Users in a bad state who have not repsonded to the CFU (repaired) will have a pending CFU. + // 3. Users in a bad state who have acted on the CFU will have no pending CFU, but will have CFU failures. + // + // We also record the time window between the last followup completion and invocation. + OTFollowup *followupHandler = cuttlefishContext.followupHandler; + NSDate* dateOfLastFollowup = [[CKKSAnalytics logger] datePropertyForKey: OctagonAnalyticsLastCoreFollowup]; + values[OctagonAnalyticsLastCoreFollowup] = @([CKKSAnalytics fuzzyDaysSinceDate:dateOfLastFollowup]); + values[OctagonAnalyticsCoreFollowupStatus] = @(followupHandler.followupStatus); + + for (NSString *type in [self cdpContextTypes]) { + NSString *metricName = [NSString stringWithFormat:@"%@%@", OctagonAnalyticsCDPStateRun, type]; + NSString *countName = [NSString stringWithFormat:@"%@%@Tries", OctagonAnalyticsCDPStateRun, type]; + + NSDate *lastFailure = [[CKKSAnalytics logger] datePropertyForKey:metricName]; + if (lastFailure) { + values[metricName] = @([CKKSAnalytics fuzzyDaysSinceDate:lastFailure]); + values[countName] = [[CKKSAnalytics logger] numberPropertyForKey:countName]; + } + } + + // SecEscrowRequest + id request = [self.escrowRequestClass request:&error]; + if (request) { + values[OctagonAnalyticsPrerecordPending] = @([request pendingEscrowUpload:&error]); + if (error) { + secnotice("octagon-analytics", "Error fetching pendingEscrowUpload status: %@", error); + } + } else { + secnotice("octagon-analytics", "Error fetching escrowRequestClass: %@", error); + } + + { + ACAccountStore *store = [[ACAccountStore alloc] init]; + ACAccount* primaryAccount = [store aa_primaryAppleAccount]; + if(primaryAccount) { + values[OctagonAnalyticsKVSProvisioned] = @([primaryAccount isProvisionedForDataclass:ACAccountDataclassKeyValue]); + values[OctagonAnalyticsKVSEnabled] = @([primaryAccount isEnabledForDataclass:ACAccountDataclassKeyValue]); + values[OctagonAnalyticsKeychainSyncProvisioned] = @([primaryAccount isProvisionedForDataclass:ACAccountDataclassKeychainSync]); + values[OctagonAnalyticsKeychainSyncEnabled] = @([primaryAccount isEnabledForDataclass:ACAccountDataclassKeychainSync]); + values[OctagonAnalyticsCloudKitProvisioned] = @([primaryAccount isProvisionedForDataclass:ACAccountDataclassCKDatabaseService]); + values[OctagonAnalyticsCloudKitEnabled] = @([primaryAccount isEnabledForDataclass:ACAccountDataclassCKDatabaseService]); + } + } + + return values; + }]; + + [[self.loggerClass logger] AddMultiSamplerForName:@"CFU-healthSummary" + withTimeInterval:SFAnalyticsSamplerIntervalOncePerReport + block:^NSDictionary *{ + OTCuttlefishContext* cuttlefishContext = [self contextForContainerName:OTCKContainerName contextID:OTDefaultContext]; + return [cuttlefishContext.followupHandler sfaStatus]; + }]; +} + +- (NSArray *)cdpContextTypes +{ + static NSArray *contextTypes = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + contextTypes = @[OTCliqueCDPContextTypeNone, + OTCliqueCDPContextTypeSignIn, + OTCliqueCDPContextTypeRepair, + OTCliqueCDPContextTypeFinishPasscodeChange, + OTCliqueCDPContextTypeRecoveryKeyGenerate, + OTCliqueCDPContextTypeRecoveryKeyNew, + OTCliqueCDPContextTypeUpdatePasscode, + ]; + }); + return contextTypes; +} + +//// +// MARK: Recovery Key +//// + +- (void) createRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString *)recoveryKey + reply:(void (^)( NSError *error))reply +{ + secnotice("octagon", "Setting recovery key for container: %@, context: %@", containerName, contextID); + + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivitySetRecoveryKey]; + + if (!self.sosEnabledForPlatform) { + secnotice("octagon-recovery", "Device is considered a limited peer, cannot enroll recovery key in Octagon"); + NSError* notFullPeerError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorLimitedPeer userInfo:@{NSLocalizedDescriptionKey : @"Device is considered a limited peer, cannot enroll recovery key in Octagon"}]; + [tracker stopWithEvent:OctagonEventRecoveryKey result:notFullPeerError]; + reply(notFullPeerError); + return; + } + + CFErrorRef validateError = NULL; + bool res = SecPasswordValidatePasswordFormat(kSecPasswordTypeiCloudRecoveryKey, CFBridgingRetain(recoveryKey), &validateError); + if (!res) { + secerror("recovery failed validation with error:%@", validateError); + + NSError *validateErrorWrapper = (__bridge_transfer NSError *)validateError; + [tracker stopWithEvent:OctagonEventSetRecoveryKeyValidationFailed result:validateErrorWrapper]; + + if (validateErrorWrapper) { + reply(validateErrorWrapper); + return; + } + } + + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:contextID]; + + [cfshContext startOctagonStateMachine]; + + [cfshContext rpcSetRecoveryKey:recoveryKey reply:^(NSError * _Nullable error) { + [tracker stopWithEvent:OctagonEventRecoveryKey result:error]; + reply(error); + }]; +} + +- (void) joinWithRecoveryKey:(NSString* _Nullable)containerName + contextID:(NSString *)contextID + recoveryKey:(NSString*)recoveryKey + reply:(void (^)(NSError * _Nullable))reply +{ + secnotice("octagon", "join with recovery key invoked for container: %@, context: %@", containerName, contextID); + + SFAnalyticsActivityTracker *tracker = [[self.loggerClass logger] startLogSystemMetricsForActivityNamed:OctagonActivityJoinWithRecoveryKey]; + + CFErrorRef validateError = NULL; + bool res = SecPasswordValidatePasswordFormat(kSecPasswordTypeiCloudRecoveryKey, CFBridgingRetain(recoveryKey), &validateError); + if (!res) { + secerror("recovery failed validation with error:%@", validateError); + + NSError *validateErrorWrapper = (__bridge_transfer NSError *)validateError; + [tracker stopWithEvent:OctagonEventJoinRecoveryKeyValidationFailed result:validateErrorWrapper]; + + if (validateErrorWrapper) { + reply(validateErrorWrapper); + return; + } + } + + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:contextID]; + + [cfshContext startOctagonStateMachine]; + + [cfshContext joinWithRecoveryKey:recoveryKey reply:^(NSError *error) { + if (error.code == TrustedPeersHelperErrorCodeNotEnrolled && [error.domain isEqualToString:TrustedPeersHelperErrorDomain]) { + // If we hit this error, let's reset and establish octagon then enroll this recovery key in the new circle + secerror("octagon, recovery key is not enrolled in octagon, resetting octagon circle"); + [[self.loggerClass logger] logResultForEvent:OctagonEventJoinRecoveryKeyCircleReset hardFailure:NO result:error]; + + [cfshContext rpcResetAndEstablish:^(NSError *resetError) { + if (resetError) { + secerror("octagon, failed to reset octagon"); + [tracker stopWithEvent:OctagonEventJoinRecoveryKeyCircleResetFailed result:resetError]; + reply(resetError); + return; + } else { + // Now enroll the recovery key + secnotice("octagon", "attempting enrolling recovery key"); + if (self.sosEnabledForPlatform) { + [self createRecoveryKey:containerName contextID:contextID recoveryKey:recoveryKey reply:^(NSError *enrollError) { + if(enrollError){ + secerror("octagon, failed to enroll new recovery key: %@", enrollError); + [tracker stopWithEvent:OctagonEventJoinRecoveryKeyEnrollFailed result:enrollError]; + reply(enrollError); + return; + }else{ + secnotice("octagon", "successfully enrolled recovery key"); + [tracker stopWithEvent:OctagonEventRecoveryKey result:nil]; + reply (nil); + return; + } + }]; + } else { + secnotice("octagon", "Limited Peer, can't enroll recovery key"); + reply (nil); + return; + } + } + }]; + } else { + secerror("octagon, join with recovery key failed: %d", (int)[error code]); + [tracker stopWithEvent:OctagonEventJoinRecoveryKeyFailed result:error]; + reply(error); + } + }]; +} + +- (void)healthCheck:(NSString *)container context:(NSString *)context skipRateLimitingCheck:(BOOL)skipRateLimitingCheck reply:(void (^)(NSError *_Nullable error))reply +{ + [self xpc24HrNotification:container context:context skipRateLimitingCheck:skipRateLimitingCheck reply:reply]; +} + + +- (void)xpc24HrNotification:(NSString* _Nullable)containerName context:(NSString*)context skipRateLimitingCheck:(BOOL)skipRateLimitingCheck reply:(void (^)(NSError *error))reply +{ + secnotice("octagon-health", "Received 24 xpc notification"); + + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:context]; + + secnotice("octagon", "notifying container of change"); + + [cfshContext notifyContainerChange:nil]; + + [cfshContext checkOctagonHealth:skipRateLimitingCheck reply:^(NSError *error) { + if(error) { + reply(error); + } else { + reply(nil); + } + }]; +} + +- (void)setSOSEnabledForPlatformFlag:(bool) value +{ + self.sosEnabledForPlatform = value; +} + +- (void)allContextsHalt +{ + for(OTCuttlefishContext* context in self.contexts.allValues) { + [context.stateMachine haltOperation]; + } +} + +- (void)allContextsDisablePendingFlags +{ + for(OTCuttlefishContext* context in self.contexts.allValues) { + [context.stateMachine disablePendingFlags]; + } +} + +- (bool)allContextsPause:(uint64_t)within +{ + for(OTCuttlefishContext* context in self.contexts.allValues) { + if(context.stateMachine.currentState != OctagonStateMachineNotStarted) { + if([context.stateMachine.paused wait:within] != 0) { + return false; + } + } + } + return true; +} + +- (void)attemptSosUpgrade:(NSString* _Nullable)containerName + context:(NSString*)context + reply:(void (^)(NSError* error))reply + +{ + secnotice("octagon-sos", "Attempting sos upgrade"); + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:context]; + + [cfshContext startOctagonStateMachine]; + + [cfshContext attemptSOSUpgrade:^(NSError *error) { + reply(error); + }]; +} + +- (void)waitForOctagonUpgrade:(NSString* _Nullable)containerName + context:(NSString*)context + reply:(void (^)(NSError* error))reply + +{ + secnotice("octagon-sos", "waitForOctagonUpgrade"); + OTCuttlefishContext* cfshContext = [self contextForContainerName:containerName contextID:context]; + + [cfshContext startOctagonStateMachine]; + + [cfshContext waitForOctagonUpgrade:^(NSError * _Nonnull error) { + reply(error); + }]; +} + +- (OTFollowupContextType)cliqueCDPTypeToFollowupContextType:(OTCliqueCDPContextType)type +{ + if ([type isEqualToString:OTCliqueCDPContextTypeNone]) { + return OTFollowupContextTypeNone; + } else if ([type isEqualToString:OTCliqueCDPContextTypeSignIn]) { + return OTFollowupContextTypeNone; + } else if ([type isEqualToString:OTCliqueCDPContextTypeRepair]) { + return OTFollowupContextTypeStateRepair; + } else if ([type isEqualToString:OTCliqueCDPContextTypeFinishPasscodeChange]) { + return OTFollowupContextTypeOfflinePasscodeChange; + } else if ([type isEqualToString:OTCliqueCDPContextTypeRecoveryKeyGenerate]) { + return OTFollowupContextTypeRecoveryKeyRepair; + } else if ([type isEqualToString:OTCliqueCDPContextTypeRecoveryKeyNew]) { + return OTFollowupContextTypeRecoveryKeyRepair; + } else if ([type isEqualToString:OTCliqueCDPContextTypeUpdatePasscode]) { + return OTFollowupContextTypeNone; + } else { + return OTFollowupContextTypeNone; + } +} + +- (void)postCDPFollowupResult:(BOOL)success + type:(OTCliqueCDPContextType)type + error:(NSError * _Nullable)error + containerName:(NSString* _Nullable)containerName + contextName:(NSString *)contextName + reply:(void (^)(NSError *error))reply +{ + OTCuttlefishContext *cuttlefishContext = [self contextForContainerName:containerName contextID:contextName]; + + NSString* metricName = [NSString stringWithFormat:@"%@%@", OctagonAnalyticsCDPStateRun, type]; + NSString* countName = [NSString stringWithFormat:@"%@%@Tries", OctagonAnalyticsCDPStateRun, type]; + + [[CKKSAnalytics logger] logResultForEvent:metricName + hardFailure:NO + result:error]; + if (error) { + [[CKKSAnalytics logger] setDateProperty:[NSDate date] forKey:metricName]; + [[CKKSAnalytics logger] incrementIntegerPropertyForKey:countName]; + } else { + [[CKKSAnalytics logger] setDateProperty:NULL forKey:metricName]; + [[CKKSAnalytics logger] setNumberProperty:NULL forKey:countName]; + } + + // Clear all CFU state variables, too + [cuttlefishContext clearPendingCFUFlags]; + + // Always return without error + reply(nil); +} + +- (void)tapToRadar:(NSString *)action + description:(NSString *)description + radar:(NSString *)radar + reply:(void (^)(NSError * _Nullable))reply +{ + SecTapToRadar *ttr = [[SecTapToRadar alloc] initTapToRadar:action description:description radar:radar]; + [ttr trigger]; + reply(NULL); +} + @end #endif diff --git a/keychain/ot/OTOperationDependencies.h b/keychain/ot/OTOperationDependencies.h new file mode 100644 index 00000000..bd569114 --- /dev/null +++ b/keychain/ot/OTOperationDependencies.h @@ -0,0 +1,44 @@ + +#import + +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OTAuthKitAdapter.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ckks/CKKSViewManager.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +// Used for dependency injection into most OctagonStateTransition operations +@interface OTOperationDependencies : NSObject + +@property NSString* containerName; +@property NSString* contextID; + +@property OTCuttlefishAccountStateHolder* stateHolder; + +@property id flagHandler; +@property id sosAdapter; +@property (nullable) id octagonAdapter; +@property id authKitAdapter; +@property id cuttlefishXPC; +@property CKKSViewManager* viewManager; +@property CKKSLockStateTracker* lockStateTracker; +@property Class escrowRequestClass; + +- (instancetype)initForContainer:(NSString*)containerName + contextID:(NSString*)contextID + stateHolder:(OTCuttlefishAccountStateHolder*)stateHolder + flagHandler:(id)flagHandler + sosAdapter:(id)sosAdapter + octagonAdapter:(id _Nullable)octagonAdapter + authKitAdapter:(id)authKitAdapter + viewManager:(CKKSViewManager*)viewManager + lockStateTracker:(CKKSLockStateTracker *)lockStateTracker + cuttlefishXPC:(id)cuttlefishXPC + escrowRequestClass:(Class)escrowRequestClass; +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/ot/OTOperationDependencies.m b/keychain/ot/OTOperationDependencies.m new file mode 100644 index 00000000..058217a0 --- /dev/null +++ b/keychain/ot/OTOperationDependencies.m @@ -0,0 +1,33 @@ + +#import "keychain/ot/OTOperationDependencies.h" + +@implementation OTOperationDependencies +- (instancetype)initForContainer:(NSString*)containerName + contextID:(NSString*)contextID + stateHolder:(OTCuttlefishAccountStateHolder*)stateHolder + flagHandler:(id)flagHandler + sosAdapter:(id)sosAdapter + octagonAdapter:(id _Nullable)octagonAdapter + authKitAdapter:(id)authKitAdapter + viewManager:(CKKSViewManager*)viewManager + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker + cuttlefishXPC:(id)cuttlefishXPC + escrowRequestClass:(Class)escrowRequestClass +{ + if((self = [super init])) { + _containerName = containerName; + _contextID = contextID; + _stateHolder = stateHolder; + _flagHandler = flagHandler; + _sosAdapter = sosAdapter; + _octagonAdapter = octagonAdapter; + _authKitAdapter = authKitAdapter; + _viewManager = viewManager; + _lockStateTracker = lockStateTracker; + _cuttlefishXPC = cuttlefishXPC; + _escrowRequestClass = escrowRequestClass; + } + return self; +} + +@end diff --git a/keychain/ot/OTPrepareOperation.h b/keychain/ot/OTPrepareOperation.h new file mode 100644 index 00000000..9f03512a --- /dev/null +++ b/keychain/ot/OTPrepareOperation.h @@ -0,0 +1,59 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTDeviceInformation.h" + +@class OTOperationDependencies; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTPrepareOperation : CKKSGroupOperation + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + deviceInfo:(OTDeviceInformation*)deviceInfo + epoch:(uint64_t)epoch; + +@property (nonatomic) uint64_t epoch; +@property OTDeviceInformation* deviceInfo; + +@property (nullable) NSString* peerID; +@property (nullable) NSData* permanentInfo; +@property (nullable) NSData* permanentInfoSig; +@property (nullable) NSData* stableInfo; +@property (nullable) NSData* stableInfoSig; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTPrepareOperation.m b/keychain/ot/OTPrepareOperation.m new file mode 100644 index 00000000..7c9f1b98 --- /dev/null +++ b/keychain/ot/OTPrepareOperation.m @@ -0,0 +1,195 @@ +/* + * 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 "utilities/debugging.h" +#import +#import + +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTFetchViewsOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTPrepareOperation.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTPrepareOperation () +@property OTOperationDependencies* deps; +@property NSOperation* finishedOp; +@end + +@implementation OTPrepareOperation +@synthesize intendedState = _intendedState; +@synthesize nextState = _nextState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + deviceInfo:(OTDeviceInformation*)deviceInfo + epoch:(uint64_t)epoch +{ + if((self = [super init])) { + _deps = dependencies; + + _deviceInfo = deviceInfo; + _epoch = epoch; + + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "preparing an identity"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + NSString* bottleSalt = nil; + + if(self.deps.authKitAdapter.primaryiCloudAccountAltDSID){ + bottleSalt = self.deps.authKitAdapter.primaryiCloudAccountAltDSID; + } + else { + NSError* accountError = nil; + OTAccountMetadataClassC* account = [self.deps.stateHolder loadOrCreateAccountMetadata:&accountError]; + + if(account && !accountError) { + secnotice("octagon", "retrieved account, altdsid is: %@", account.altDSID); + bottleSalt = account.altDSID; + } + if(accountError || !account){ + secerror("failed to rerieve account object: %@", accountError); + } + } + WEAKIFY(self); + + // But, if this device is SOS-enabled and SOS is present, use the SOS octagon keys (if present) + NSData* signingKeyPersistRef = nil; + NSData* encryptionKeyPersistRef = nil; + if(self.deps.sosAdapter.sosEnabled) { + secnotice("octagon-sos", "Investigating use of Octagon keys from SOS identity"); + + NSError* error = nil; + id sosSelf = [self.deps.sosAdapter currentSOSSelf:&error]; + + if(!sosSelf || error) { + secnotice("octagon-sos", "Failed to get the current SOS self: %@", error); + } else { + // Fetch the persistent references for our signing and encryption keys + OSStatus status = errSecSuccess; + CFDataRef cfSigningKeyPersistRef = NULL; + status = SecKeyCopyPersistentRef(sosSelf.signingKey.secKey, &cfSigningKeyPersistRef); + if(status != errSecSuccess || !cfSigningKeyPersistRef) { + secnotice("octagon-sos", "Failed to get the persistent ref for our SOS signing key: %d", (int)status); + } else { + CFDataRef cfEncryptionKeyPersistRef = NULL; + status = SecKeyCopyPersistentRef(sosSelf.encryptionKey.secKey, &cfEncryptionKeyPersistRef); + if(status != errSecSuccess || !cfEncryptionKeyPersistRef) { + secnotice("octagon-sos", "Failed to get the persistent ref for our SOS encryption key: %d", (int)status); + CFReleaseNull(cfSigningKeyPersistRef); + CFReleaseNull(cfEncryptionKeyPersistRef); + } else { + // We only want to use these keys if we successfully have both + signingKeyPersistRef = CFBridgingRelease(cfSigningKeyPersistRef); + encryptionKeyPersistRef = CFBridgingRelease(cfEncryptionKeyPersistRef); + } + } + } + } + + NSError* persistError = nil; + BOOL persisted = [self.deps.stateHolder persistOctagonJoinAttempt:OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED error:&persistError]; + if(!persisted || persistError) { + secerror("octagon: failed to save 'attempted join' state: %@", persistError); + } + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logUnrecoverableError:error forEvent:OctagonEventPrepareIdentity withAttributes:nil]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] prepareWithContainer:self.deps.containerName + context:self.deps.contextID + epoch:self.epoch + machineID:self.deviceInfo.machineID + bottleSalt:bottleSalt + bottleID:[NSUUID UUID].UUIDString + modelID:self.deviceInfo.modelID + deviceName:self.deviceInfo.deviceName + serialNumber:self.deviceInfo.serialNumber + osVersion:self.deviceInfo.osVersion + policyVersion:nil + policySecrets:nil +signingPrivKeyPersistentRef:signingKeyPersistRef + encPrivKeyPersistentRef:encryptionKeyPersistRef + reply:^(NSString * _Nullable peerID, NSData * _Nullable permanentInfo, NSData * _Nullable permanentInfoSig, NSData * _Nullable stableInfo, NSData * _Nullable stableInfoSig, NSError * _Nullable error) { + STRONGIFY(self); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventPrepareIdentity hardFailure:true result:error]; + if(error) { + secerror("octagon: Error preparing identity: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + } else { + secnotice("octagon", "Prepared: %@ %@ %@", peerID, permanentInfo, permanentInfoSig); + self.peerID = peerID; + self.permanentInfo = permanentInfo; + self.permanentInfoSig = permanentInfoSig; + self.stableInfo = stableInfo; + self.stableInfoSig = stableInfoSig; + + NSError* localError = nil; + BOOL persisted = [self.deps.stateHolder persistNewEgoPeerID:peerID error:&localError]; + if(!persisted || localError) { + secnotice("octagon", "Couldn't persist peer ID: %@", localError); + self.error = localError; + [self runBeforeGroupFinished:self.finishedOp]; + } else { + WEAKIFY(self); + + CKKSResultOperation *doneOp = [CKKSResultOperation named:@"ot-prepare" + withBlock:^{ + STRONGIFY(self); + self.nextState = self.intendedState; + }]; + + OTFetchViewsOperation *fetchViewsOp = [[OTFetchViewsOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchViewsOp]; + [doneOp addDependency:fetchViewsOp]; + [self runBeforeGroupFinished:doneOp]; + [self.finishedOp addDependency:doneOp]; + [self runBeforeGroupFinished:self.finishedOp]; + } + } + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTRamping.h b/keychain/ot/OTRamping.h index 8dacb9d4..607c36da 100644 --- a/keychain/ot/OTRamping.h +++ b/keychain/ot/OTRamping.h @@ -30,31 +30,31 @@ #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CloudKitDependencies.h" #import "keychain/ckks/CKKSLockStateTracker.h" -#import "keychain/ckks/CKKSCKAccountStateTracker.h" +#import "keychain/ckks/CKKSAccountStateTracker.h" #import "keychain/ckks/CKKSReachabilityTracker.h" NS_ASSUME_NONNULL_BEGIN -@interface OTRamp : NSObject +@interface OTRamp : NSObject @property (nonatomic, readonly) NSString* featureName; -@property (nonatomic, readonly) CKKSCKAccountStateTracker *accountTracker; +@property (nonatomic, readonly) CKKSAccountStateTracker *accountTracker; @property (nonatomic, readonly) CKKSLockStateTracker *lockStateTracker; @property (nonatomic, readonly) CKKSReachabilityTracker *reachabilityTracker; --(instancetype) initWithRecordName:(NSString *) recordName - featureName:(NSString*) featureName +-(instancetype)initWithRecordName:(NSString *) recordName + localSettingName:(NSString*) featureName container:(CKContainer*) container database:(CKDatabase*) database zoneID:(CKRecordZoneID*) zoneID - accountTracker:(CKKSCKAccountStateTracker*) accountTracker + accountTracker:(CKKSAccountStateTracker*) accountTracker lockStateTracker:(CKKSLockStateTracker*) lockStateTracker reachabilityTracker:(CKKSReachabilityTracker*) reachabilityTracker fetchRecordRecordsOperationClass:(Class) fetchRecordRecordsOperationClass; --(void) fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior +-(void)fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior reply:(void (^)(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError))recordRampStateFetchCompletionBlock; --(BOOL) checkRampState:(NSInteger*)retryAfter networkBehavior:(CKOperationDiscretionaryNetworkBehavior)networkBehavior error:(NSError**)error; +-(BOOL)checkRampStateWithError:(NSError**)error; @end NS_ASSUME_NONNULL_END #endif /* OCTAGON */ diff --git a/keychain/ot/OTRamping.m b/keychain/ot/OTRamping.m index 29b2bb0c..11fdfedb 100644 --- a/keychain/ot/OTRamping.m +++ b/keychain/ot/OTRamping.m @@ -33,6 +33,8 @@ #import "keychain/ckks/CKKSNearFutureScheduler.h" #import "keychain/ckks/CKKSAnalytics.h" #import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ckks/CKKS.h" static NSString* kFeatureAllowedKey = @"FeatureAllowed"; static NSString* kFeaturePromotedKey = @"FeaturePromoted"; @@ -55,10 +57,10 @@ static NSString* kRampPriorityKey = @"RampPriority"; @property (nonatomic, strong) CKRecordZoneID *zoneID; @property (nonatomic, strong) NSString *recordName; -@property (nonatomic, strong) NSString *featureName; +@property (nonatomic, strong) NSString *localSettingName; @property (nonatomic, strong) CKRecordID *recordID; -@property (nonatomic, strong) CKKSCKAccountStateTracker *accountTracker; +@property (nonatomic, strong) CKKSAccountStateTracker *accountTracker; @property (nonatomic, strong) CKKSLockStateTracker *lockStateTracker; @property (nonatomic, strong) CKKSReachabilityTracker *reachabilityTracker; @@ -66,16 +68,20 @@ static NSString* kRampPriorityKey = @"RampPriority"; @property (readonly) Class fetchRecordRecordsOperationClass; +@property (atomic, strong) NSDate *lastFetch; +@property (atomic) NSTimeInterval retryAfter; +@property (atomic) BOOL cachedFeatureAllowed; + @end @implementation OTRamp -(instancetype) initWithRecordName:(NSString *) recordName - featureName:(NSString*) featureName + localSettingName:(NSString*) localSettingName container:(CKContainer*) container database:(CKDatabase*) database zoneID:(CKRecordZoneID*) zoneID - accountTracker:(CKKSCKAccountStateTracker*) accountTracker + accountTracker:(CKKSAccountStateTracker*) accountTracker lockStateTracker:(CKKSLockStateTracker*) lockStateTracker reachabilityTracker:(CKKSReachabilityTracker*) reachabilityTracker fetchRecordRecordsOperationClass:(Class) fetchRecordRecordsOperationClass @@ -85,24 +91,28 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR if(self){ _container = container; _recordName = [recordName copy]; - _featureName = [featureName copy]; + _localSettingName = [localSettingName copy]; _database = database; _zoneID = zoneID; _accountTracker = accountTracker; _lockStateTracker = lockStateTracker; _reachabilityTracker = reachabilityTracker; _fetchRecordRecordsOperationClass = fetchRecordRecordsOperationClass; + _lastFetch = [NSDate distantPast]; + _retryAfter = kCKRampManagerDefaultRetryTimeInSeconds; + _cachedFeatureAllowed = NO; } return self; } --(void) fetchRampRecord:(CKOperationDiscretionaryNetworkBehavior)networkBehavior 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.discretionaryNetworkBehavior = networkBehavior; + opConfig.isCloudKitSupportOperation = YES; _recordID = [[CKRecordID alloc] initWithRecordName:_recordName zoneID:_zoneID]; CKFetchRecordsOperation *operation = [[[self.fetchRecordRecordsOperationClass class] alloc] initWithRecordIDs:@[ _recordID]]; @@ -114,7 +124,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR __strong __typeof(weakSelf) strongSelf = weakSelf; if(!strongSelf) { secnotice("octagon", "received callback for released object"); - operationError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorCKCallback userInfo:@{NSLocalizedDescriptionKey: @"Received callback for released object"}]; + operationError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorCKCallback userInfo:@{NSLocalizedDescriptionKey: @"Received callback for released object"}]; recordRampStateFetchCompletionBlock(NO, NO, NO, kCKRampManagerDefaultRetryTimeInSeconds , operationError); return; } @@ -137,7 +147,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR secnotice("octagon", "Fetch ramp state - featureAllowed %@, featurePromoted: %@, featureVisible: %@, retryAfter: %ld", (featureAllowed ? @YES : @NO), (featurePromoted ? @YES : @NO), (featureVisible ? @YES : @NO), (long)retryAfter); } else { secerror("octagon: Couldn't find CKRecord for ramp. Defaulting to not ramped in"); - operationError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorRecordNotFound userInfo:@{NSLocalizedDescriptionKey: @" Couldn't find CKRecord for ramp. Defaulting to not ramped in"}]; + operationError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorRecordNotFound userInfo:@{NSLocalizedDescriptionKey: @" Couldn't find CKRecord for ramp. Defaulting to not ramped in"}]; } recordRampStateFetchCompletionBlock(featureAllowed, featurePromoted, featureVisible, retryAfter, operationError); }; @@ -146,12 +156,35 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR secnotice("octagon", "Attempting to fetch ramp state from CloudKit"); } --(BOOL) checkRampState:(NSInteger*)retryAfter networkBehavior:(CKOperationDiscretionaryNetworkBehavior)networkBehavior error:(NSError**)error +-(BOOL) checkRampStateWithError:(NSError**)error { __block BOOL isFeatureEnabled = NO; __block NSError* localError = nil; __block NSInteger localRetryAfter = 0; + //defaults write to for whether or not a ramp record returns "enabled or disabled" + CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue((__bridge CFStringRef)self.localSettingName, + CFSTR("com.apple.security"), + kCFPreferencesCurrentUser, kCFPreferencesAnyHost); + + secnotice("octagon", "%@ Defaults availability: SecCKKSTestsEnabled[%s] DefaultsPointer[%s] DefaultsValue[%s]", (__bridge CFStringRef)self.localSettingName, + SecCKKSTestsEnabled() ? "True": "False", (enabled != NULL) ? "True": "False", + (enabled && (CFGetTypeID(enabled) == CFBooleanGetTypeID()) && (enabled == kCFBooleanTrue)) ? "True": "False"); + + if(!SecCKKSTestsEnabled() && enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ + BOOL localConfigEnable = (enabled == kCFBooleanTrue); + secnotice("octagon", "feature is %@: %@ (local config)", localConfigEnable ? @"enabled" : @"disabled", self.recordName); + CFReleaseNull(enabled); + return localConfigEnable; + } + CFReleaseNull(enabled); + + NSDate* now = [[NSDate alloc] init]; + + if([now timeIntervalSinceDate: self.lastFetch] < self.retryAfter) { + return self.cachedFeatureAllowed; + } + if(self.lockStateTracker.isLocked){ secnotice("octagon","device is locked! can't check ramp state"); localError = [NSError errorWithDomain:(__bridge NSString*)kSecErrorDomain @@ -162,9 +195,12 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR } return NO; } + + // Wait until the account tracker has had a chance to figure out the state + [self.accountTracker.ckAccountInfoInitialized wait:5*NSEC_PER_SEC]; if(self.accountTracker.currentCKAccountInfo.accountStatus != CKAccountStatusAvailable){ secnotice("octagon","not signed in! can't check ramp state"); - localError = [NSError errorWithDomain:octagonErrorDomain + localError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNotSignedIn userInfo:@{NSLocalizedDescriptionKey: @"not signed in"}]; if(error){ @@ -174,7 +210,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR } if(!self.reachabilityTracker.currentReachability){ secnotice("octagon","no network! can't check ramp state"); - localError = [NSError errorWithDomain:octagonErrorDomain + localError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorNoNetwork userInfo:@{NSLocalizedDescriptionKey: @"no network"}]; if(error){ @@ -183,18 +219,6 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR return NO; } - //defaults write to for whether or not a ramp record returns "enabled or disabled" - CFBooleanRef enabled = (CFBooleanRef)CFPreferencesCopyValue((__bridge CFStringRef)self.recordName, - CFSTR("com.apple.security"), - kCFPreferencesAnyUser, kCFPreferencesAnyHost); - if(enabled && CFGetTypeID(enabled) == CFBooleanGetTypeID()){ - BOOL localConfigEnable = (enabled == kCFBooleanTrue); - secnotice("octagon", "feature is %@: %@ (local config)", localConfigEnable ? @"enabled" : @"disabled", self.recordName); - CFReleaseNull(enabled); - return localConfigEnable; - } - CFReleaseNull(enabled); - CKKSAnalytics* logger = [CKKSAnalytics logger]; SFAnalyticsActivityTracker *tracker = [logger logSystemMetricsForActivityNamed:CKKSActivityOTFetchRampState withAction:nil]; @@ -202,7 +226,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR [tracker start]; - [self fetchRampRecord:networkBehavior reply:^(BOOL featureAllowed, BOOL featurePromoted, BOOL featureVisible, NSInteger retryAfter, NSError *rampStateFetchError) { + [self fetchRampRecord:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary 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; @@ -213,10 +237,10 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR dispatch_semaphore_signal(sema); }]; - long timeout = (SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : NSEC_PER_SEC * 65); + int64_t timeout = (int64_t)(SecCKKSTestsEnabled() ? 2*NSEC_PER_SEC : NSEC_PER_SEC * 65); if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, timeout)) != 0) { secnotice("octagon", "timed out waiting for response from CloudKit\n"); - localError = [NSError errorWithDomain:octagonErrorDomain code:OTErrorCKTimeOut userInfo:@{NSLocalizedDescriptionKey: @"Failed to deserialize bottle peer"}]; + localError = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorCKTimeOut userInfo:@{NSLocalizedDescriptionKey: @"timed out waiting for response from CloudKit"}]; [logger logUnrecoverableError:localError forEvent:OctagonEventRamp withAttributes:@{ OctagonEventAttributeFailureReason : @"cloud kit timed out"} @@ -227,7 +251,7 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR if(localRetryAfter > 0){ secnotice("octagon", "cloud kit asked security to retry: %lu", (unsigned long)localRetryAfter); - *retryAfter = localRetryAfter; + self.retryAfter = localRetryAfter; } if(localError){ @@ -243,37 +267,9 @@ fetchRecordRecordsOperationClass:(Class) fetchRecordR [logger logSuccessForEventNamed:OctagonEventRamp]; } + self.lastFetch = now; + self.cachedFeatureAllowed = isFeatureEnabled; return isFeatureEnabled; - -} - -- (void)ckAccountStatusChange:(CKKSAccountStatus)oldStatus to:(CKKSAccountStatus)currentStatus { - secnotice("octagon", "%@ Received notification of CloudKit account status change, moving from %@ to %@", - self.zoneID.zoneName, - [CKKSCKAccountStateTracker stringFromAccountStatus: oldStatus], - [CKKSCKAccountStateTracker stringFromAccountStatus: currentStatus]); - - switch(currentStatus) { - case CKKSAccountStatusAvailable: { - secnotice("octagon", "Logged into iCloud."); - self.accountStatus = CKKSAccountStatusAvailable; - } - break; - - case CKKSAccountStatusNoAccount: { - secnotice("octagon", "Logging out of iCloud. Shutting down."); - self.accountStatus = CKKSAccountStatusNoAccount; - } - break; - - case CKKSAccountStatusUnknown: { - // We really don't expect to receive this as a notification, but, okay! - secnotice("octagon", "Account status has become undetermined. Pausing for %@", self.zoneID.zoneName); - self.accountStatus = CKKSAccountStatusNoAccount; - - } - break; - } } @end diff --git a/keychain/ot/OTRemovePeersOperation.h b/keychain/ot/OTRemovePeersOperation.h new file mode 100644 index 00000000..0fb22351 --- /dev/null +++ b/keychain/ot/OTRemovePeersOperation.h @@ -0,0 +1,46 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTRemovePeersOperation : CKKSGroupOperation + +@property NSSet* peerIDs; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + peerIDs:(NSArray*)peerIDs; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTRemovePeersOperation.m b/keychain/ot/OTRemovePeersOperation.m new file mode 100644 index 00000000..72cbe6ef --- /dev/null +++ b/keychain/ot/OTRemovePeersOperation.m @@ -0,0 +1,90 @@ +/* + * 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 "keychain/ot/OTRemovePeersOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +@interface OTRemovePeersOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; +@end + +@implementation OTRemovePeersOperation +@synthesize intendedState = _intendedState; +@synthesize nextState = _nextState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + peerIDs:(NSArray*)peerIDs +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + + _peerIDs = [NSSet setWithArray:peerIDs];; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "Attempting to remove peers: %@", self.peerIDs); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + WEAKIFY(self); + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] distrustPeerIDsWithContainer:self.deps.containerName + context:self.deps.contextID + peerIDs:self.peerIDs + reply:^(NSError * _Nullable error) { + STRONGIFY(self); + if(error) { + secnotice("octagon", "Unable to remove peers for (%@,%@): %@", self.deps.containerName, self.deps.contextID, error); + self.error = error; + } else { + secnotice("octagon", "Successfully removed peers"); + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON + diff --git a/keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h b/keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h new file mode 100644 index 00000000..2a447a17 --- /dev/null +++ b/keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h @@ -0,0 +1,21 @@ + +#import + +#if OCTAGON + +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTResetCKKSZonesLackingTLKsOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTResetCKKSZonesLackingTLKsOperation.m b/keychain/ot/OTResetCKKSZonesLackingTLKsOperation.m new file mode 100644 index 00000000..0a09dd2f --- /dev/null +++ b/keychain/ot/OTResetCKKSZonesLackingTLKsOperation.m @@ -0,0 +1,132 @@ +#if OCTAGON + +#import "utilities/debugging.h" + +#import + +#import "keychain/ot/OTResetCKKSZonesLackingTLKsOperation.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" + +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ckks/CKKSCurrentKeyPointer.h" +#import "keychain/ckks/CKKSKeychainView.h" + +#import "keychain/ot/ObjCImprovements.h" + +@interface OTResetCKKSZonesLackingTLKsOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; +@end + +@implementation OTResetCKKSZonesLackingTLKsOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "Checking if any CKKS zones need resetting"); + + WEAKIFY(self); + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + STRONGIFY(self); + secnotice("octagon", "Finishing resetting CKKS missing TLKs operation with %@", self.error ?: @"no error"); + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"continue-ckks-resets" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets + incompleteKeySets:fetchKeysOp.incompleteKeySets + pendingTLKShares:fetchKeysOp.tlkShares]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets + incompleteKeySets:(NSArray*)incompleteKeySets + pendingTLKShares:(NSArray*)pendingTLKShares +{ + // Now that CKKS has returned, what are we even doing + NSMutableSet* viewsToReset = [NSMutableSet set]; + + for(CKKSCurrentKeySet* incompleteKeySet in incompleteKeySets) { + if(incompleteKeySet.error == nil) { + CKKSKeychainView* viewMatchingSet = [self.deps.viewManager findView:incompleteKeySet.viewName]; + + if(!viewMatchingSet) { + secnotice("octagon-ckks", "No view matching viewset %@?", incompleteKeySet); + continue; + } + + if(incompleteKeySet.currentTLKPointer != nil && + incompleteKeySet.tlk == nil) { + + BOOL otherDevicesAlive = [viewMatchingSet otherDevicesReportHavingTLKs:incompleteKeySet]; + if(otherDevicesAlive) { + secnotice("octagon-ckks", "Recently active devices claim to have TLK from key set %@; not scheduling for reset", incompleteKeySet); + } else { + secnotice("octagon-ckks", "Key set %@ has no TLK; scheduling for reset", incompleteKeySet); + [viewsToReset addObject:viewMatchingSet]; + } + } + } else { + secnotice("octagon-ckks", "Error loading key set %@; not attempting reset", incompleteKeySet); + } + } + + if(viewsToReset.count == 0) { + // Nothing to do; return to ready + secnotice("octagon-ckks", "No CKKS views need resetting"); + self.nextState = self.intendedState; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + [self resetViews:viewsToReset]; +} + +- (void)resetViews:(NSSet*)viewsToReset { + CKOperationGroup* opGroup = [CKOperationGroup CKKSGroupWithName:@"octagon-reset-missing-tlks"]; + for (CKKSKeychainView* view in viewsToReset) { + secnotice("octagon-ckks", "Resetting CKKS %@", view); + CKKSResultOperation* op = [view resetCloudKitZone:opGroup]; + + // Use an intermediary operation, just to ensure we have a timeout + CKKSResultOperation* waitOp = [CKKSResultOperation named:[NSString stringWithFormat:@"wait-for-%@", view.zoneName] + withBlock:^{}]; + [waitOp timeout:120*NSEC_PER_SEC]; + [waitOp addDependency:op]; + [self.operationQueue addOperation:waitOp]; + + [self.finishedOp addDependency:waitOp]; + } + + self.nextState = self.intendedState; + [self.operationQueue addOperation:self.finishedOp]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTResetOperation.h b/keychain/ot/OTResetOperation.h new file mode 100644 index 00000000..c331aa90 --- /dev/null +++ b/keychain/ot/OTResetOperation.h @@ -0,0 +1,45 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +#import "keychain/ot/OTAuthKitAdapter.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTResetOperation : CKKSGroupOperation + +- (instancetype)init:(NSString*)containerName + contextID:(NSString*)contextID + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + cuttlefishXPC:(id)cuttlefishXPC; +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTResetOperation.m b/keychain/ot/OTResetOperation.m new file mode 100644 index 00000000..79eb5dfe --- /dev/null +++ b/keychain/ot/OTResetOperation.m @@ -0,0 +1,95 @@ +/* + * 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 "keychain/ot/OTResetOperation.h" + +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +@interface OTResetOperation () +@property NSString* containerName; +@property NSString* contextID; +@property id cuttlefishXPC; + +// Since we're making callback based async calls, use this operation trick to hold off the ending of this operation +@property NSOperation* finishedOp; +@end + +@implementation OTResetOperation +@synthesize intendedState = _intendedState; +@synthesize nextState = _nextState; + +- (instancetype)init:(NSString*)containerName + contextID:(NSString*)contextID + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + cuttlefishXPC:(id)cuttlefishXPC +{ + if((self = [super init])) { + _intendedState = intendedState; + _nextState = errorState; + + _containerName = containerName; + _contextID = contextID; + _cuttlefishXPC = cuttlefishXPC; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon-authkit", "Attempting to reset octagon"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + WEAKIFY(self); + [[self.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventReset withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] resetWithContainer:self.containerName + context:self.contextID + reply:^(NSError * _Nullable error) { + STRONGIFY(self); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventReset hardFailure:true result:error]; + + if(error) { + secnotice("octagon", "Unable to reset for (%@,%@): %@", self.containerName, self.contextID, error); + self.error = error; + } else { + secnotice("octagon", "Successfully reset Octagon"); + self.nextState = self.intendedState; + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTSOSAdapter.h b/keychain/ot/OTSOSAdapter.h new file mode 100644 index 00000000..f8adfb8b --- /dev/null +++ b/keychain/ot/OTSOSAdapter.h @@ -0,0 +1,33 @@ +#if OCTAGON + +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/SecureObjectSync/SOSCloudCircle.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol OTSOSAdapter +@property bool sosEnabled; +- (SOSCCStatus)circleStatus:(NSError**)error; +- (id _Nullable)currentSOSSelf:(NSError**)error; +- (NSSet>* _Nullable)fetchTrustedPeers:(NSError**)error; +- (void)updateOctagonKeySetWithAccount:(id)currentSelfPeer error:(NSError**)error; +@end + +@interface OTSOSActualAdapter : NSObject +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initAsEssential:(BOOL)essential; + +// Helper methods ++ (NSArray*)peerPublicSigningKeySPKIs:(NSSet>* _Nullable)peers; + ++ (NSSet*)sosCKKSViewList; +@end + +// This adapter is for a platform which does not have SOS (e.g., aTV, Watch, HomePod) +@interface OTSOSMissingAdapter : NSObject +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTSOSAdapter.m b/keychain/ot/OTSOSAdapter.m new file mode 100644 index 00000000..41b65403 --- /dev/null +++ b/keychain/ot/OTSOSAdapter.m @@ -0,0 +1,378 @@ +#if OCTAGON +#import +#import + +#import "keychain/ot/OTSOSAdapter.h" + +#import "keychain/SecureObjectSync/SOSCloudCircleInternal.h" +#include "keychain/SecureObjectSync/SOSViews.h" + +#import "OSX/sec/securityd/SOSCloudCircleServer.h" +#import "OSX/utilities/SecCFWrappers.h" + +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSLockStateTracker.h" +#import "keychain/ckks/CKKSListenerCollection.h" +#import "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/SecureObjectSync/SOSAccountPriv.h" + +#import "keychain/SecureObjectSync/SOSAccountTrustClassic.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ckks/CKKSAnalytics.h" + +@interface OTSOSActualAdapter () +@property CKKSListenerCollection* peerChangeListeners; +@end + +@implementation OTSOSActualAdapter +@synthesize sosEnabled; +@synthesize essential = _essential; +@synthesize providerID = _providerID; + ++ (NSSet*)sosCKKSViewList +{ + static NSSet* list = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + list = CFBridgingRelease(SOSViewCopyViewSet(kViewSetCKKS)); + }); + return list; +} + +- (instancetype)initAsEssential:(BOOL)essential { + if((self = [super init])) { + self.sosEnabled = true; + + _essential = essential; + + _providerID = @"[OTSOSActualAdapter]"; + _peerChangeListeners = [[CKKSListenerCollection alloc] initWithName:@"ckks-sos"]; + + __typeof(self) weakSelf = self; + // If this is a live server, register with notify + if(!SecCKKSTestsEnabled()) { + int token = 0; + notify_register_dispatch(kSOSCCCircleOctagonKeysChangedNotification, &token, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^(int t) { + // Since SOS doesn't change the self peer, we can reliably just send "trusted peers changed"; it'll be mostly right + secnotice("octagon-sos", "Received a notification that the SOS Octagon peer set changed"); + [weakSelf sendTrustedPeerSetChangedUpdate]; + }); + } + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.essential]; +} + +- (SOSCCStatus)circleStatus:(NSError**)error +{ + CFErrorRef cferror = nil; + SOSCCStatus status = SOSCCThisDeviceIsInCircle(&cferror); + if(error && cferror) { + *error = CFBridgingRelease(cferror); + } else { + CFReleaseNull(cferror); + } + return status; +} + +- (id _Nullable)currentSOSSelf:(NSError**)error +{ + __block SFECKeyPair* signingPrivateKey = nil; + __block SFECKeyPair* encryptionPrivateKey = nil; + + __block NSError* localerror = nil; + + CFErrorRef cferror = nil; + + SOSCCStatus circleStatus = [self circleStatus:&localerror]; + if(circleStatus != kSOSCCInCircle) { + if(!localerror) { + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"Not in SOS circle, but no error returned"]; + } + secerror("octagon-sos: Not in circle : %d %@", circleStatus, localerror); + if(error) { + *error = localerror; + } + return nil; + } + + SOSPeerInfoRef egoPeerInfo = SOSCCCopyMyPeerInfo(&cferror); + NSString* egoPeerID = egoPeerInfo ? (NSString*)CFBridgingRelease(CFRetainSafe(SOSPeerInfoGetPeerID(egoPeerInfo))) : nil; + CFReleaseNull(egoPeerInfo); + + if(!egoPeerID || cferror) { + localerror = CFBridgingRelease(cferror); + if(!localerror) { + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"No SOS peer info available, but no error returned"]; + } + + secerror("octagon-sos: Error fetching self peer : %@", cferror); + if(error) { + *error = localerror; + } + return nil; + } + + SOSCCPerformWithAllOctagonKeys(^(SecKeyRef octagonEncryptionKey, SecKeyRef octagonSigningKey, CFErrorRef cferror) { + if(cferror) { + localerror = (__bridge NSError*)cferror; + return; + } + if (!cferror && octagonEncryptionKey && octagonSigningKey) { + signingPrivateKey = [[SFECKeyPair alloc] initWithSecKey:octagonSigningKey]; + encryptionPrivateKey = [[SFECKeyPair alloc] initWithSecKey:octagonEncryptionKey]; + } else { + localerror = [NSError errorWithDomain:CKKSErrorDomain + code:CKKSNoPeersAvailable + description:@"Not all SOS peer keys available, but no error returned"]; + } + }); + + if(localerror) { + if(![[CKKSLockStateTracker globalTracker] isLockedError:localerror]) { + secerror("octagon-sos: Error fetching self encryption keys: %@", localerror); + } + if(error) { + *error = localerror; + } + return nil; + } + + CKKSSOSSelfPeer* selfPeer = [[CKKSSOSSelfPeer alloc] initWithSOSPeerID:egoPeerID + encryptionKey:encryptionPrivateKey + signingKey:signingPrivateKey + viewList:[OTSOSActualAdapter sosCKKSViewList]]; + return selfPeer; +} + +- (CKKSSelves * _Nullable)fetchSelfPeers:(NSError *__autoreleasing _Nullable * _Nullable)error { + id peer = [self currentSOSSelf:error]; + if(!peer) { + return nil; + } + + return [[CKKSSelves alloc] initWithCurrent:peer allSelves:nil]; +} + +- (NSSet>* _Nullable)fetchTrustedPeers:(NSError**)error +{ + __block NSMutableSet>* peerSet = [NSMutableSet set]; + + __block NSError* localError = nil; + + SOSCCPerformWithTrustedPeers(^(CFSetRef sosPeerInfoRefs, CFErrorRef cfTrustedPeersError) { + if(cfTrustedPeersError) { + secerror("octagon-sos: Error fetching trusted peers: %@", cfTrustedPeersError); + if(localError) { + localError = (__bridge NSError*)cfTrustedPeersError; + } + } + + CFSetForEach(sosPeerInfoRefs, ^(const void* voidPeer) { + CFErrorRef cfPeerError = NULL; + SOSPeerInfoRef sosPeerInfoRef = (SOSPeerInfoRef)voidPeer; + + if(!sosPeerInfoRef) { + return; + } + + CFStringRef cfpeerID = SOSPeerInfoGetPeerID(sosPeerInfoRef); + SecKeyRef cfOctagonSigningKey = NULL, cfOctagonEncryptionKey = NULL; + + cfOctagonSigningKey = SOSPeerInfoCopyOctagonSigningPublicKey(sosPeerInfoRef, &cfPeerError); + if (cfOctagonSigningKey) { + cfOctagonEncryptionKey = SOSPeerInfoCopyOctagonEncryptionPublicKey(sosPeerInfoRef, &cfPeerError); + } + + if(cfOctagonSigningKey == NULL || cfOctagonEncryptionKey == NULL) { + // Don't log non-debug for -50; it almost always just means this peer didn't have octagon keys + if(cfPeerError == NULL + || !(CFEqualSafe(CFErrorGetDomain(cfPeerError), kCFErrorDomainOSStatus) && (CFErrorGetCode(cfPeerError) == errSecParam))) + { + secerror("octagon-sos: error fetching octagon keys for peer: %@ %@", sosPeerInfoRef, cfPeerError); + } else { + secinfo("octagon-sos", "Peer(%@) doesn't have Octagon keys, but this is expected: %@", cfpeerID, cfPeerError); + } + } + + // Add all peers to the trust set: old-style SOS peers will just have null keys + SFECPublicKey* signingPublicKey = cfOctagonSigningKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonSigningKey] : nil; + SFECPublicKey* encryptionPublicKey = cfOctagonEncryptionKey ? [[SFECPublicKey alloc] initWithSecKey:cfOctagonEncryptionKey] : nil; + + CKKSSOSPeer* peer = [[CKKSSOSPeer alloc] initWithSOSPeerID:(__bridge NSString*)cfpeerID + encryptionPublicKey:encryptionPublicKey + signingPublicKey:signingPublicKey + viewList:[OTSOSActualAdapter sosCKKSViewList]]; + [peerSet addObject:peer]; + + CFReleaseNull(cfOctagonSigningKey); + CFReleaseNull(cfOctagonEncryptionKey); + CFReleaseNull(cfPeerError); + }); + }); + + if(error && localError) { + *error = localError; + } + + return peerSet; +} + +- (void)updateOctagonKeySetWithAccount:(id)currentSelfPeer error:(NSError**)error { + + // in case we don't have the keys, don't try to update them + if (currentSelfPeer.publicSigningKey.secKey == NULL || currentSelfPeer.publicEncryptionKey.secKey == NULL) { + secnotice("octagon-sos", "no octagon keys available skipping updating SOS record"); + return; + } + + __block CFDataRef signingFullKey = CFBridgingRetain(currentSelfPeer.signingKey.keyData); + __block CFDataRef encryptionFullKey = CFBridgingRetain(currentSelfPeer.encryptionKey.keyData); + __block CFDataRef signingPublicKey = CFBridgingRetain(currentSelfPeer.publicSigningKey.keyData); + __block CFDataRef encryptionPublicKey = CFBridgingRetain(currentSelfPeer.publicEncryptionKey.keyData); + __block SecKeyRef octagonSigningPubSecKey = CFRetainSafe(currentSelfPeer.publicSigningKey.secKey); + __block SecKeyRef octagonEncryptionPubSecKey = CFRetainSafe(currentSelfPeer.publicEncryptionKey.secKey); + + SFAnalyticsActivityTracker *tracker = [[[CKKSAnalytics class] logger] startLogSystemMetricsForActivityNamed:OctagonSOSAdapterUpdateKeys]; + + /* WARNING! Please be very very careful passing keys to this routine. Note the slightly different variations of keys*/ + SOSCCPerformUpdateOfAllOctagonKeys(signingFullKey, encryptionFullKey, + signingPublicKey, encryptionPublicKey, + octagonSigningPubSecKey, octagonEncryptionPubSecKey, + ^(CFErrorRef error) { + [tracker stopWithEvent: OctagonSOSAdapterUpdateKeys result:(__bridge NSError * _Nullable)(error)]; + if(error){ + secerror("octagon-sos: failed to update Octagon keys in SOS:%@", error); + }else { + secnotice("octagon-sos", "successfully updated Octagon keys in SOS!"); + } + CFRelease(signingFullKey); + CFRelease(encryptionFullKey); + CFRelease(signingPublicKey); + CFRelease(encryptionPublicKey); + CFRelease(octagonSigningPubSecKey); + CFRelease(octagonEncryptionPubSecKey); + }); +} + +- (void)registerForPeerChangeUpdates:(nonnull id)listener { + [self.peerChangeListeners registerListener:listener]; +} + +- (void)sendSelfPeerChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener selfPeerChanged: self]; + }]; +} + +- (void)sendTrustedPeerSetChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener trustedPeerSetChanged: self]; + }]; +} + ++ (NSArray*)peerPublicSigningKeySPKIs:(NSSet>* _Nullable)peerSet +{ + NSMutableArray* publicSigningSPKIs = [NSMutableArray array]; + + for(id peer in peerSet) { + NSData* spki = [peer.publicSigningKey encodeSubjectPublicKeyInfo]; + if(!spki) { + secerror("octagon-sos: Can't create SPKI for peer: %@", peer); + } else { + secerror("octagon-sos: Created SPKI for peer: %@", peer); + [publicSigningSPKIs addObject:spki]; + } + } + return publicSigningSPKIs; +} +@end + +@implementation OTSOSMissingAdapter +@synthesize sosEnabled; +@synthesize providerID = _providerID; +@synthesize essential = _essential; + +- (instancetype)init { + if((self = [super init])) { + self.sosEnabled = false; + _providerID = @"[OTSOSMissingAdapter]"; + + // This adapter is never going to return anything, so you probably shouldn't ever consider it Must Succeed + _essential = NO; + } + return self; +} + +- (SOSCCStatus)circleStatus:(NSError**)error +{ + return kSOSCCNotInCircle; +} + +- (id _Nullable)currentSOSSelf:(NSError**)error +{ + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + description:@"SOS unsupported on this platform"]; + } + return nil; +} + +- (NSSet>* _Nullable)fetchTrustedPeers:(NSError**)error +{ + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + description:@"SOS unsupported on this platform"]; + } + return nil; +} + +- (void)updateOctagonKeySetWithAccount:(nonnull id)currentSelfPeer error:(NSError *__autoreleasing _Nullable * _Nullable)error { + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + description:@"SOS unsupported on this platform"]; + } +} + +- (CKKSSelves * _Nullable)fetchSelfPeers:(NSError * _Nullable __autoreleasing * _Nullable)error +{ + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecUnimplemented + description:@"SOS unsupported on this platform"]; + } + return nil; +} + +- (void)registerForPeerChangeUpdates:(nonnull id)listener +{ + // no op +} + +- (void)sendSelfPeerChangedUpdate +{ + // no op +} + +- (void)sendTrustedPeerSetChangedUpdate +{ + // no op +} + + +@end +#endif // OCTAGON diff --git a/keychain/ot/OTSOSUpdatePreapprovalsOperation.h b/keychain/ot/OTSOSUpdatePreapprovalsOperation.h new file mode 100644 index 00000000..39026d19 --- /dev/null +++ b/keychain/ot/OTSOSUpdatePreapprovalsOperation.h @@ -0,0 +1,27 @@ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/OTSOSAdapter.h" + +NS_ASSUME_NONNULL_BEGIN + +@class OTOperationDependencies; + +@interface OTSOSUpdatePreapprovalsOperation : CKKSGroupOperation + +@property OctagonState* sosNotPresentState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + sosNotPresentState:(OctagonState*)sosNotPresentState + errorState:(OctagonState*)errorState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON + diff --git a/keychain/ot/OTSOSUpdatePreapprovalsOperation.m b/keychain/ot/OTSOSUpdatePreapprovalsOperation.m new file mode 100644 index 00000000..e388dfbf --- /dev/null +++ b/keychain/ot/OTSOSUpdatePreapprovalsOperation.m @@ -0,0 +1,125 @@ + + +#if OCTAGON + +#import +#import +#import +#import + +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OTSOSUpdatePreapprovalsOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ckks/CloudKitCategories.h" + +@interface OTSOSUpdatePreapprovalsOperation () +@property OTOperationDependencies* deps; + +// Since we're making callback based async calls, use this operation trick to hold off the ending of this operation +@property NSOperation* finishedOp; +@end + +@implementation OTSOSUpdatePreapprovalsOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + sosNotPresentState:(OctagonState*)sosNotPresentState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _sosNotPresentState = sosNotPresentState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + WEAKIFY(self); + + if(!self.deps.sosAdapter.sosEnabled) { + secnotice("octagon-sos", "SOS not enabled on this platform?"); + return; + } + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + // If we errored in some unknown way, ask to try again! + STRONGIFY(self); + + if(self.error) { + // Is this a very scary error? + bool fatal = false; + + NSTimeInterval ckdelay = CKRetryAfterSecondsForError(self.error); + NSTimeInterval delay = 30; + if(ckdelay != 0) { + delay = ckdelay; + } + + if([self.error isCuttlefishError:CuttlefishErrorResultGraphNotFullyReachable]) { + secnotice("octagon-sos", "SOS update preapproval error is 'result graph not reachable'; retrying is useless: %@", self.error); + fatal = true; + } + + if([self.error.domain isEqualToString:TrustedPeersHelperErrorDomain] && self.error.code == TrustedPeersHelperErrorNoPreparedIdentity) { + secnotice("octagon-sos", "SOS update preapproval error is 'no prepared identity'; retrying immediately is useless: %@", self.error); + fatal = true; + } + + if(!fatal) { + secnotice("octagon-sos", "SOS update preapproval error is not fatal: requesting retry in %0.2fs: %@", delay, self.error); + [self.deps.flagHandler handlePendingFlag:[[OctagonPendingFlag alloc] initWithFlag:OctagonFlagAttemptSOSUpdatePreapprovals + delayInSeconds:delay]]; + } + } + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + NSError* error = nil; + NSSet>* peerSet = [self.deps.sosAdapter fetchTrustedPeers:&error]; + + if(!peerSet || error) { + secerror("octagon-sos: Can't fetch trusted peers; stopping preapproved key update: %@", error); + self.error = error; + self.nextState = self.sosNotPresentState; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + NSArray* publicSigningSPKIs = [OTSOSActualAdapter peerPublicSigningKeySPKIs:peerSet]; + secnotice("octagon-sos", "Updating SOS preapproved keys to %@", publicSigningSPKIs); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper, update of preapproved keys is lost: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] setPreapprovedKeysWithContainer:self.deps.containerName + context:self.deps.contextID + preapprovedKeys:publicSigningSPKIs + reply:^(NSError* error) { + STRONGIFY(self); + if(error) { + secerror("octagon-sos: unable to update preapproved keys: %@", error); + self.error = error; + } else { + secnotice("octagon-sos", "Updated SOS preapproved keys"); + self.nextState = self.intendedState; + } + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTSOSUpgradeOperation.h b/keychain/ot/OTSOSUpgradeOperation.h new file mode 100644 index 00000000..04bbfec9 --- /dev/null +++ b/keychain/ot/OTSOSUpgradeOperation.h @@ -0,0 +1,30 @@ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/OTSOSAdapter.h" + +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import "keychain/ot/OTDeviceInformation.h" + +NS_ASSUME_NONNULL_BEGIN + +@class OTOperationDependencies; + +@interface OTSOSUpgradeOperation : CKKSGroupOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + ckksConflictState:(OctagonState*)ckksConflictState + errorState:(OctagonState*)errorState + deviceInfo:(OTDeviceInformation*)deviceInfo; + +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON + diff --git a/keychain/ot/OTSOSUpgradeOperation.m b/keychain/ot/OTSOSUpgradeOperation.m new file mode 100644 index 00000000..3df7a768 --- /dev/null +++ b/keychain/ot/OTSOSUpgradeOperation.m @@ -0,0 +1,436 @@ + +#if OCTAGON + +#import +#import +#import +#import + +#include "keychain/SecureObjectSync/SOSAccount.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OTFetchViewsOperation.h" +#import "keychain/ot/OTSOSUpgradeOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTUpdateTrustedDeviceListOperation.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ot/OTAuthKitAdapter.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ckks/CKKSKeychainView.h" +#import "keychain/ckks/CloudKitCategories.h" +#import +#import + +@interface OTSOSUpgradeOperation () +@property OTOperationDependencies* deps; +@property OTDeviceInformation* deviceInfo; + +@property OctagonState* ckksConflictState; + +// Since we're making callback based async calls, use this operation trick to hold off the ending of this operation +@property NSOperation* finishedOp; + +@property OTUpdateTrustedDeviceListOperation* updateOp; +@end + +@implementation OTSOSUpgradeOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + ckksConflictState:(OctagonState*)ckksConflictState + errorState:(OctagonState*)errorState + deviceInfo:(OTDeviceInformation*)deviceInfo +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + _ckksConflictState = ckksConflictState; + + _deviceInfo = deviceInfo; + } + return self; +} + +- (NSData *)persistentKeyRef:(SecKeyRef)secKey error:(NSError **)error +{ + CFDataRef cfEncryptionKeyPersistRef = NULL; + OSStatus status; + + status = SecKeyCopyPersistentRef(secKey, &cfEncryptionKeyPersistRef); + if(status) { + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil]; + } + } else if (cfEncryptionKeyPersistRef) { + if (error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:errSecItemNotFound userInfo:nil]; + } + } + + return CFBridgingRelease(cfEncryptionKeyPersistRef); +} + +- (void)groupStart +{ + WEAKIFY(self); + + if(!self.deps.sosAdapter.sosEnabled) { + secnotice("octagon-sos", "SOS not enabled on this platform?"); + self.nextState = OctagonStateBecomeUntrusted; + return; + } + + secnotice("octagon-sos", "Attempting SOS upgrade"); + + NSError* error = nil; + SOSCCStatus sosCircleStatus = [self.deps.sosAdapter circleStatus:&error]; + if(error || sosCircleStatus == kSOSCCError) { + secnotice("octagon-sos", "Error fetching circle status: %@", error); + self.nextState = OctagonStateBecomeUntrusted; + return; + } + + if(sosCircleStatus != kSOSCCInCircle) { + secnotice("octagon-sos", "Device is not in SOS circle (state: %@), quitting SOS upgrade", SOSAccountGetSOSCCStatusString(sosCircleStatus)); + self.nextState = OctagonStateBecomeUntrusted; + return; + } + + id sosSelf = [self.deps.sosAdapter currentSOSSelf:&error]; + if(!sosSelf || error) { + secnotice("octagon-sos", "Failed to get the current SOS self: %@", error); + [self handlePrepareErrors:error nextExpectedState:OctagonStateBecomeUntrusted]; + return; + } + + // Fetch the persistent references for our signing and encryption keys + NSData* signingKeyPersistRef = [self persistentKeyRef:sosSelf.signingKey.secKey error:&error]; + if (signingKeyPersistRef == NULL) { + secnotice("octagon-sos", "Failed to get the persistent ref for our SOS signing key: %@", error); + [self handlePrepareErrors:error nextExpectedState:OctagonStateBecomeUntrusted]; + return; + } + + NSData* encryptionKeyPersistRef = [self persistentKeyRef:sosSelf.encryptionKey.secKey error:&error]; + if (encryptionKeyPersistRef == NULL) { + secnotice("octagon-sos", "Failed to get the persistent ref for our SOS encryption key: %@", error); + [self handlePrepareErrors:error nextExpectedState:OctagonStateBecomeUntrusted]; + return; + } + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + // If we errored in some unknown way, ask to try again! + STRONGIFY(self); + + if(self.error) { + // Is this a very scary error? + bool fatal = false; + + NSTimeInterval ckdelay = CKRetryAfterSecondsForError(self.error); + NSTimeInterval delay = 30; + if(ckdelay != 0) { + delay = ckdelay; + } + + if([self.error isCuttlefishError:CuttlefishErrorResultGraphNotFullyReachable]) { + secnotice("octagon-sos", "SOS upgrade error is 'result graph not reachable'; retrying is useless: %@", self.error); + fatal = true; + } + + if([self.error.domain isEqualToString:TrustedPeersHelperErrorDomain] && self.error.code == TrustedPeersHelperErrorNoPeersPreapprovePreparedIdentity) { + secnotice("octagon-sos", "SOS upgrade error is 'no peers preapprove us'; retrying immediately is useless: %@", self.error); + fatal = true; + } + + if(!fatal) { + secnotice("octagon-sos", "SOS upgrade error is not fatal: requesting retry in %0.2fs: %@", delay, self.error); + [self.deps.flagHandler handlePendingFlag:[[OctagonPendingFlag alloc] initWithFlag:OctagonFlagAttemptSOSUpgrade + delayInSeconds:delay]]; + } + } + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + NSString* bottleSalt = nil; + + if(self.deps.authKitAdapter.primaryiCloudAccountAltDSID){ + bottleSalt = self.deps.authKitAdapter.primaryiCloudAccountAltDSID; + } + else { + NSError* accountError = nil; + OTAccountMetadataClassC* account = [self.deps.stateHolder loadOrCreateAccountMetadata:&accountError]; + + if(account && !accountError) { + secnotice("octagon", "retrieved account, altdsid is: %@", account.altDSID); + bottleSalt = account.altDSID; + } + if(accountError || !account){ + secerror("failed to rerieve account object: %@", accountError); + } + } + + NSError* persistError = nil; + BOOL persisted = [self.deps.stateHolder persistOctagonJoinAttempt:OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED error:&persistError]; + if(!persisted || persistError) { + secerror("octagon: failed to save 'attempted join' state: %@", persistError); + } + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] prepareWithContainer:self.deps.containerName + context:self.deps.contextID + epoch:self.deviceInfo.epoch + machineID:self.deviceInfo.machineID + bottleSalt:bottleSalt + bottleID:[NSUUID UUID].UUIDString + modelID:self.deviceInfo.modelID + deviceName:self.deviceInfo.deviceName + serialNumber:self.self.deviceInfo.serialNumber + osVersion:self.deviceInfo.osVersion + policyVersion:nil + policySecrets:nil +signingPrivKeyPersistentRef:signingKeyPersistRef + encPrivKeyPersistentRef:encryptionKeyPersistRef + reply:^(NSString * _Nullable peerID, + NSData * _Nullable permanentInfo, + NSData * _Nullable permanentInfoSig, + NSData * _Nullable stableInfo, + NSData * _Nullable stableInfoSig, + NSError * _Nullable error) { + STRONGIFY(self); + + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradePrepare hardFailure:true result:error]; + + if(error) { + secerror("octagon-sos: Error preparing identity: %@", error); + self.error = error; + [self handlePrepareErrors:error nextExpectedState:OctagonStateBecomeUntrusted]; + + [self runBeforeGroupFinished:self.finishedOp]; + } else { + secnotice("octagon-sos", "Prepared: %@ %@ %@", peerID, permanentInfo, permanentInfoSig); + + [self afterPrepare]; + } + + }]; +} + +- (void)afterPrepare +{ + WEAKIFY(self); + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon-sos: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradePreflightPreapprovedJoin hardFailure:true result:error]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] preflightPreapprovedJoinWithContainer:self.deps.containerName + context:self.deps.contextID + reply:^(BOOL launchOkay, NSError * _Nullable error) { + STRONGIFY(self); + + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradePreflightPreapprovedJoin hardFailure:true result:error]; + if(error) { + secerror("octagon-sos: preflightPreapprovedJoin failed: %@", error); + + self.error = error; + self.nextState = OctagonStateBecomeUntrusted; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + if(!launchOkay) { + secnotice("octagon-sos", "TPH believes a preapprovedJoin will fail; aborting."); + self.nextState = OctagonStateBecomeUntrusted; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + secnotice("octagon-sos", "TPH believes a preapprovedJoin might succeed; continuing."); + [self afterPreflight]; + }]; +} + +- (void)afterPreflight +{ + WEAKIFY(self); + self.updateOp = [[OTUpdateTrustedDeviceListOperation alloc] initWithDependencies:self.deps + intendedState:OctagonStateReady + listUpdatesState:OctagonStateReady + errorState:OctagonStateError + retryFlag:nil]; + self.updateOp.logForUpgrade = YES; + [self runBeforeGroupFinished:self.updateOp]; + + CKKSResultOperation* afterUpdate = [CKKSResultOperation named:@"after-update" + withBlock:^{ + STRONGIFY(self); + [self afterUpdate]; + }]; + [afterUpdate addDependency:self.updateOp]; + [self runBeforeGroupFinished:afterUpdate]; +} + +- (void)handlePrepareErrors:(NSError *)error nextExpectedState:(OctagonState*)nextState +{ + secnotice("octagon-sos", "handling prepare error: %@", error); + + if ([self.deps.lockStateTracker isLockedError:error]) { + self.nextState = OctagonStateWaitForUnlock; + } else { + self.nextState = nextState; + } + self.error = error; +} + +- (void)afterUpdate +{ + if (self.updateOp.error) { + [self handlePrepareErrors:self.updateOp.error nextExpectedState:self.nextState]; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + secnotice("octagon-sos", "Successfully saved machineID allow-list"); + [self afterSuccessfulAllowList]; +} + +- (void)requestSilentEscrowUpdate +{ + NSError* error = nil; + id request = [self.deps.escrowRequestClass request:&error]; + if(!request || error) { + secnotice("octagon-sos", "Unable to acquire a EscrowRequest object: %@", error); + return; + } + + [request triggerEscrowUpdate:@"octagon-sos" error:&error]; + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradeSilentEscrow hardFailure:true result:error]; + + if(error) { + secnotice("octagon-sos", "Unable to request silent escrow update: %@", error); + } else{ + secnotice("octagon-sos", "Requested silent escrow update"); + } +} + +- (void)afterSuccessfulAllowList +{ + WEAKIFY(self); + + OTFetchViewsOperation *fetchViews = [[OTFetchViewsOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchViews]; + + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps]; + [fetchKeysOp addDependency:fetchViews]; + [self runBeforeGroupFinished:fetchKeysOp]; + + secnotice("octagon-sos", "Fetching keys from CKKS"); + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"sos-upgrade-with-keys" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets pendingTLKShares:fetchKeysOp.pendingTLKShares]; + }]; + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets pendingTLKShares:(NSArray*)pendingTLKShares +{ + WEAKIFY(self); + + secnotice("octagon-sos", "Fetching trusted peers from SOS"); + + NSError* error = nil; + NSSet>* peerSet = [self.deps.sosAdapter fetchTrustedPeers:&error]; + + if(!peerSet || error) { + secerror("octagon-sos: Can't fetch trusted peers; stopping upgrade: %@", error); + self.error = error; + self.nextState = OctagonStateBecomeUntrusted; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + NSArray* publicSigningSPKIs = [OTSOSActualAdapter peerPublicSigningKeySPKIs:peerSet]; + secnotice("octagon-sos", "Creating SOS preapproved keys as %@", publicSigningSPKIs); + + secnotice("octagon-sos", "Beginning SOS upgrade with %d key sets and %d SOS peers", (int)viewKeySets.count, (int)peerSet.count); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon-sos: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradeSilentEscrow hardFailure:true result:error]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] attemptPreapprovedJoinWithContainer:self.deps.containerName + context:self.deps.contextID + ckksKeys:viewKeySets + tlkShares:pendingTLKShares + preapprovedKeys:publicSigningSPKIs + reply:^(NSString * _Nullable peerID, NSArray* keyHierarchyRecords, NSError * _Nullable error) { + STRONGIFY(self); + + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradePreapprovedJoin hardFailure:true result:error]; + if(error) { + secerror("octagon-sos: attemptPreapprovedJoin failed: %@", error); + + if ([error isCuttlefishError:CuttlefishErrorKeyHierarchyAlreadyExists]) { + secnotice("octagon-ckks", "A CKKS key hierarchy is out of date; requesting reset"); + self.nextState = self.ckksConflictState; + } else { + self.error = error; + self.nextState = OctagonStateBecomeUntrusted; + } + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + [self requestSilentEscrowUpdate]; + + secerror("octagon-sos: attemptPreapprovedJoin succeded"); + + NSError* localError = nil; + BOOL persisted = [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.trustState = OTAccountMetadataClassC_TrustState_TRUSTED; + metadata.peerID = peerID; + return metadata; + } error:&localError]; + + if(!persisted || localError) { + secnotice("octagon-sos", "Couldn't persist results: %@", localError); + self.error = localError; + self.nextState = OctagonStateError; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + self.nextState = self.intendedState; + + // Tell CKKS about our shiny new records! + for (id key in self.deps.viewManager.views) { + CKKSKeychainView* view = self.deps.viewManager.views[key]; + secnotice("octagon-ckks", "Providing ck records (from sos upgrade) to %@", view); + [view receiveTLKUploadRecords: keyHierarchyRecords]; + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTSetRecoveryKeyOperation.h b/keychain/ot/OTSetRecoveryKeyOperation.h new file mode 100644 index 00000000..1cd5eba2 --- /dev/null +++ b/keychain/ot/OTSetRecoveryKeyOperation.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTSetRecoveryKeyOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + recoveryKey:(NSString*)recoveryKey; + +@property (weak) OTCuttlefishContext* cuttlefishContext; +@property (nonatomic) NSString* salt; +@property (nonatomic) NSString* recoveryKey; + +@property (nonatomic) NSData* voucher; +@property (nonatomic) NSData* voucherSig; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTSetRecoveryKeyOperation.m b/keychain/ot/OTSetRecoveryKeyOperation.m new file mode 100644 index 00000000..e066172c --- /dev/null +++ b/keychain/ot/OTSetRecoveryKeyOperation.m @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2019 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 "keychain/ot/OTSetRecoveryKeyOperation.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTSetRecoveryKeyOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishOp; +@end + +@implementation OTSetRecoveryKeyOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + recoveryKey:(NSString*)recoveryKey +{ + if((self = [super init])) { + _deps = dependencies; + _recoveryKey = recoveryKey; + } + return self; +} + +- (void)groupStart +{ + self.finishOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishOp]; + + NSString* salt = nil; + + if(self.deps.authKitAdapter.primaryiCloudAccountAltDSID){ + salt = self.deps.authKitAdapter.primaryiCloudAccountAltDSID; + } + else { + NSError* accountError = nil; + OTAccountMetadataClassC* account = [self.deps.stateHolder loadOrCreateAccountMetadata:&accountError]; + + if(account && !accountError) { + secnotice("octagon", "retrieved account, altdsid is: %@", account.altDSID); + salt = account.altDSID; + } + if(accountError || !account){ + secerror("failed to rerieve account object: %@", accountError); + } + } + + WEAKIFY(self); + + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"setting-recovery-tlks" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets salt:salt]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets salt:(NSString*)salt +{ + WEAKIFY(self); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventRecoveryKey withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishOp]; + + }] setRecoveryKeyWithContainer:self.deps.containerName + context:self.deps.contextID + recoveryKey:self.recoveryKey + salt:salt + ckksKeys:viewKeySets + reply:^(NSError * _Nullable setError) { + if(setError){ + [[CKKSAnalytics logger] logResultForEvent:OctagonEventSetRecoveryKey hardFailure:true result:setError]; + secerror("octagon: Error setting recovery key: %@", setError); + self.error = setError; + [self runBeforeGroupFinished:self.finishOp]; + } else { + secnotice("octagon", "successfully set recovery key"); + [self runBeforeGroupFinished:self.finishOp]; + } + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTStates.h b/keychain/ot/OTStates.h new file mode 100644 index 00000000..279e7434 --- /dev/null +++ b/keychain/ot/OTStates.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@ + */ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +// Two 'bad states': +// No iCloud Account (the state machine won't help at all) +// Untrusted (user interaction is required to resolve) +// WaitForHSA2 (there's some primary icloud account, but it's not HSA2 (yet)) +extern OctagonState* const OctagonStateNoAccount; +extern OctagonState* const OctagonStateUntrusted; +extern OctagonState* const OctagonStateWaitForHSA2; + +// Entering this state will mark down that the device is untrusted, then go to OctagonStateUntrusted +extern OctagonState* const OctagonStateBecomeUntrusted; + +// WaitForUnlock indicates that Octagon is waiting for the device to unlock before attempting the pended operation +extern OctagonState* const OctagonStateWaitForUnlock; + +// 'ready' indicates that this machine believes it is trusted by its peers +// and has no pending things to do. +extern OctagonState* const OctagonStateReady; + +// This state runs any final preparation to enter the Ready state +extern OctagonState* const OctagonStateBecomeReady; + +// Enter this state if you'd like the state machine to double-check everything +extern OctagonState* const OctagonStateEnsureConsistency; +extern OctagonState* const OctagonStateEnsureOctagonKeysAreConsistent; +extern OctagonState* const OctagonStateEnsureUpdatePreapprovals; + +// The boot-up sequence looks as follows: +extern OctagonState* const OctagonStateInitializing; +extern OctagonState* const OctagonStateWaitingForCloudKitAccount; +extern OctagonState* const OctagonStateCloudKitNewlyAvailable; +extern OctagonState* const OctagonStateCheckTrustState; + +/*Piggybacking and ProximitySetup as Initiator, Octagon only*/ +extern OctagonState* const OctagonStateInitiatorAwaitingVoucher; + +extern OctagonState* const OctagonStateInitiatorUpdateDeviceList; +extern OctagonState* const OctagonStateInitiatorJoin; +extern OctagonState* const OctagonStateInitiatorJoinCKKSReset; +extern OctagonState* const OctagonStateInitiatorJoinAfterCKKSReset; + +extern OctagonState* const OctagonStateInitiatorVouchWithBottle; +extern OctagonState* const OctagonStateIdentityPrepared; +// OctagonStateIdentityPrepared leads directly to +extern OctagonState* const OctagonStateDeviceListUpdated; + +/* used for join with bottle */ +extern OctagonState* const OctagonStateInitiatorCreateIdentity; + +/* used for join with recovery key */ +extern OctagonState* const OctagonStateCreateIdentityForRecoveryKey; + +/* used for join with recovery key*/ +extern OctagonState* const OctagonStateVouchWithRecoveryKey; + +// State flow when performing a full account reset +extern OctagonState* const OctagonStateResetBecomeUntrusted; +extern OctagonState* const OctagonStateResetAndEstablish; +extern OctagonState* const OctagonStateResetAnyMissingTLKCKKSViews; +extern OctagonState* const OctagonStateReEnactDeviceList; +extern OctagonState* const OctagonStateReEnactPrepare; +extern OctagonState* const OctagonStateReEnactReadyToEstablish; +// this last state might loop through: +extern OctagonState* const OctagonStateEstablishCKKSReset; +extern OctagonState* const OctagonStateEstablishAfterCKKSReset; + +/* used for trust health checks */ +extern OctagonState* const OctagonStateHSA2HealthCheck; +extern OctagonState* const OctagonStateSecurityTrustCheck; +extern OctagonState* const OctagonStateTPHTrustCheck; +extern OctagonState* const OctagonStateCuttlefishTrustCheck; +extern OctagonState* const OctagonStatePostRepairCFU; + +// End of account reset state flow + +// Part of the signout flow +extern OctagonState* const OctagonStateNoAccountDoReset; +// + +// escrow +extern OctagonState* const OctagonStateEscrowTriggerUpdate; + +// Enter this state to perform an SOS peer update, and return to ready. +extern OctagonState* const OctagonStateUpdateSOSPreapprovals; + +extern OctagonState* const OctagonStateError; +extern OctagonState* const OctagonStateDisabled; + +extern OctagonState* const OctagonStateAttemptSOSUpgrade; +extern OctagonState* const OctagonStateSOSUpgradeCKKSReset; +extern OctagonState* const OctagonStateSOSUpgradeAfterCKKSReset; + +extern OctagonState* const OctagonStateDetermineiCloudAccountState; + +// CKKS sometimes needs an assist. These states are supposed to handle those cases +extern OctagonState* const OctagonStateAssistCKKSTLKUpload; + +// Call out to otpaird (KCPairing via IDS), then proceed to BecomeUntrusted +extern OctagonState* const OctagonStateStartCompanionPairing; + +// Untrusted cuttlefish notification. +extern OctagonState* const OctagonStateUntrustedUpdated; + +// Cuttlefish notifiation while ready. +extern OctagonState* const OctagonStateReadyUpdated; + +extern OctagonState* const OctagonStateUnimplemented; + +NSDictionary* OctagonStateMap(void); +NSDictionary* OctagonStateInverseMap(void); + +// Unfortunately, this set contains the 'wait for hsa2' state, which means that many +// of our state machine RPCs will work in the SA case. +// Octagon: ensure Octagon operations can't occur on SA accounts +NSSet* OctagonInAccountStates(void); +NSSet* OctagonHealthSourceStates(void); + +////// State machine flags +extern OctagonFlag* const OctagonFlagEgoPeerPreapproved; + +extern OctagonFlag* const OctagonFlagCKKSRequestsTLKUpload; + +// We've received a change notification from cuttlefish; we should probably see what's new +extern OctagonFlag* const OctagonFlagCuttlefishNotification; + +extern OctagonFlag* const OctagonFlagFetchAuthKitMachineIDList; + +extern OctagonFlag* const OctagonFlagAccountIsAvailable; + +extern OctagonFlag* const OctagonFlagAttemptSOSUpgrade; +extern OctagonFlag* const OctagonFlagUnlocked; + +extern OctagonFlag* const OctagonFlagAttemptSOSUpdatePreapprovals; + +extern OctagonFlag* const OctagonFlagPerformHealthCheck; + +extern OctagonFlag* const OctagonFlagEscrowRequestInformCloudServicesOperation; + + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTStates.m b/keychain/ot/OTStates.m new file mode 100644 index 00000000..448c356d --- /dev/null +++ b/keychain/ot/OTStates.m @@ -0,0 +1,244 @@ +/* + * 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 "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +OctagonState* const OctagonStateNoAccount = (OctagonState*) @"no_account"; + +OctagonState* const OctagonStateWaitForHSA2 = (OctagonState*) @"wait_for_hsa2"; + +OctagonState* const OctagonStateUntrusted = (OctagonState*) @"untrusted"; +OctagonState* const OctagonStateBecomeUntrusted = (OctagonState*) @"become_untrusted"; + +OctagonState* const OctagonStateReady = (OctagonState*) @"ready"; +OctagonState* const OctagonStateBecomeReady = (OctagonState*) @"become_ready"; + +OctagonState* const OctagonStateEnsureConsistency = (OctagonState*) @"consistency_check"; +OctagonState* const OctagonStateEnsureOctagonKeysAreConsistent = (OctagonState*)@"key_consistency_check"; +OctagonState* const OctagonStateEnsureUpdatePreapprovals = (OctagonState*)@"ensure_preapprovals_updated"; + +OctagonState* const OctagonStateInitializing = (OctagonState*) @"initializing"; +OctagonState* const OctagonStateWaitingForCloudKitAccount = (OctagonState*) @"waiting_for_cloudkit_account"; +OctagonState* const OctagonStateCloudKitNewlyAvailable = (OctagonState*) @"account_newly_available"; +OctagonState* const OctagonStateCheckTrustState = (OctagonState*) @"check_trust_state"; + +OctagonState* const OctagonStateUpdateSOSPreapprovals = (OctagonState*) @"update_sos_preapprovals"; + +/*Piggybacking and ProximitySetup as Initiator Octagon only*/ +OctagonState* const OctagonStateInitiatorUpdateDeviceList = (OctagonState*) @"initiator_device_list_update"; +OctagonState* const OctagonStateInitiatorAwaitingVoucher = (OctagonState*)@"await_voucher"; +OctagonState* const OctagonStateInitiatorJoin = (OctagonState*)@"join"; +OctagonState* const OctagonStateInitiatorJoinCKKSReset = (OctagonState*)@"join_ckks_reset"; +OctagonState* const OctagonStateInitiatorJoinAfterCKKSReset = (OctagonState*)@"join_after_ckks_reset"; + +/* used in restore (join with bottle)*/ +OctagonState* const OctagonStateInitiatorCreateIdentity = (OctagonState*)@"create_identity"; +OctagonState* const OctagonStateInitiatorVouchWithBottle = (OctagonState*)@"vouchWithBottle"; +OctagonState* const OctagonStateCreateIdentityForRecoveryKey = (OctagonState*)@"vouchWithRecovery"; + +/* used in resotre (join with recovery key)*/ +OctagonState* const OctagonStateVouchWithRecoveryKey = (OctagonState*)@"vouchWithRecoveryKey"; + +OctagonState* const OctagonStateStartCompanionPairing = (OctagonState*)@"start_companion_pairing"; + +// Untrusted cuttlefish notification. +OctagonState* const OctagonStateUntrustedUpdated = (OctagonState*)@"untrusted_update"; + +// Cuttlefish notifiation while ready. +OctagonState* const OctagonStateReadyUpdated = (OctagonState*)@"ready_update"; + +OctagonState* const OctagonStateError = (OctagonState*) @"error"; +OctagonState* const OctagonStateDisabled = (OctagonState*) @"disabled"; + +OctagonState* const OctagonStateDetermineiCloudAccountState = (OctagonState*) @"determine_icloud_account"; +OctagonState* const OctagonStateAttemptSOSUpgrade = (OctagonState*) @"sosupgrade"; +OctagonState* const OctagonStateSOSUpgradeCKKSReset = (OctagonState*) @"sosupgrade_ckks_reset"; +OctagonState* const OctagonStateSOSUpgradeAfterCKKSReset = (OctagonState*) @"sosupgrade_after_ckks_reset"; +OctagonState* const OctagonStateUnimplemented = (OctagonState*) @"unimplemented"; + +/* Reset and establish */ +OctagonState* const OctagonStateResetBecomeUntrusted = (OctagonState*) @"reset_become_untrusted"; +OctagonState* const OctagonStateResetAndEstablish = (OctagonState*) @"reset_and_establish"; +OctagonState* const OctagonStateResetAnyMissingTLKCKKSViews = (OctagonState*) @"reset_ckks_missing_views"; +OctagonState* const OctagonStateReEnactDeviceList = (OctagonState*) @"reenact_device_list"; +OctagonState* const OctagonStateReEnactPrepare = (OctagonState*) @"reenact_prepare"; +OctagonState* const OctagonStateReEnactReadyToEstablish = (OctagonState*) @"reenact_ready_to_establish"; +OctagonState* const OctagonStateEstablishCKKSReset = (OctagonState*) @"reenact_ckks_reset"; +OctagonState* const OctagonStateEstablishAfterCKKSReset = (OctagonState*) @"reenact_establish_after_ckks_reset"; + +/* used for trust health checks */ +OctagonState* const OctagonStateHSA2HealthCheck = (OctagonState*) @"health_hsa2_check"; +OctagonState* const OctagonStateTPHTrustCheck = (OctagonState*) @"tph_trust_check"; +OctagonState* const OctagonStateCuttlefishTrustCheck = (OctagonState*) @"cuttlefish_trust_check"; +OctagonState* const OctagonStatePostRepairCFU = (OctagonState*) @"post_repair_cfu"; +OctagonState* const OctagonStateSecurityTrustCheck = (OctagonState*) @"security_trust_check"; +/* signout */ +OctagonState* const OctagonStateNoAccountDoReset = (OctagonState*) @"no_account_do_reset"; + +OctagonState* const OctagonStateWaitForUnlock = (OctagonState*) @"wait_for_unlock"; + +OctagonState* const OctagonStateAssistCKKSTLKUpload = (OctagonState*) @"assist_ckks_tlk_upload"; + +/* escrow */ +OctagonState* const OctagonStateEscrowTriggerUpdate = (OctagonState*) @"escrow-trigger-update"; + +NSDictionary* OctagonStateMap(void) { + static NSDictionary* map = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + map = @{ + OctagonStateReady: @0U, + OctagonStateError: @1U, + OctagonStateInitializing: @2U, + OctagonStateMachineNotStarted: @3U, + OctagonStateDisabled: @4U, + OctagonStateUntrusted: @5U, + + //Removed: OctagonStateInitiatorAwaitingAcceptorEpoch: @9U, + //Removed: OctagonStateInitiatorReadyToSendIdentity: @10U, + + OctagonStateInitiatorUpdateDeviceList: @8U, + OctagonStateInitiatorAwaitingVoucher: @11U, + OctagonStateInitiatorJoin: @12U, + + //Removed: OctagonStateIdentityPrepared: @6U, + //Removed: OctagonStateDeviceListUpdated: @7U, + + OctagonStateAttemptSOSUpgrade: @8U, + + OctagonStateUnimplemented: @9U, + OctagonStateDetermineiCloudAccountState: @10U, + OctagonStateNoAccount: @11U, + + OctagonStateResetAndEstablish: @12U, + OctagonStateReEnactDeviceList: @13U, + OctagonStateReEnactPrepare: @14U, + OctagonStateReEnactReadyToEstablish: @15U, + OctagonStateNoAccountDoReset: @16U, + OctagonStateInitiatorVouchWithBottle: @17U, + OctagonStateInitiatorCreateIdentity: @18U, + OctagonStateCloudKitNewlyAvailable: @19U, + OctagonStateCheckTrustState: @20U, + OctagonStateBecomeUntrusted: @21U, + OctagonStateWaitForUnlock: @22U, + OctagonStateWaitingForCloudKitAccount: @23U, + OctagonStateBecomeReady: @24U, + OctagonStateVouchWithRecoveryKey: @25U, + OctagonStateCreateIdentityForRecoveryKey: @26U, + OctagonStateUpdateSOSPreapprovals: @27U, + OctagonStateWaitForHSA2: @28U, + OctagonStateAssistCKKSTLKUpload: @29U, + OctagonStateStartCompanionPairing: @30U, + OctagonStateEscrowTriggerUpdate: @31U, + OctagonStateEnsureConsistency: @32U, + OctagonStateResetBecomeUntrusted: @33U, + OctagonStateUntrustedUpdated: @34U, + OctagonStateReadyUpdated: @35U, + OctagonStateTPHTrustCheck: @36U, + OctagonStateCuttlefishTrustCheck: @37U, + OctagonStatePostRepairCFU: @38U, + OctagonStateSecurityTrustCheck: @39U, + OctagonStateEnsureOctagonKeysAreConsistent: @40U, + OctagonStateEnsureUpdatePreapprovals: @41U, + OctagonStateResetAnyMissingTLKCKKSViews: @42U, + OctagonStateEstablishCKKSReset: @43U, + OctagonStateEstablishAfterCKKSReset: @44U, + OctagonStateSOSUpgradeCKKSReset: @45U, + OctagonStateSOSUpgradeAfterCKKSReset: @46U, + OctagonStateInitiatorJoinCKKSReset: @47U, + OctagonStateInitiatorJoinAfterCKKSReset: @48U, + OctagonStateHSA2HealthCheck: @49U, + }; + }); + return map; +} + +NSDictionary* OctagonStateInverseMap(void) { + static NSDictionary* backwardMap = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSDictionary* forwardMap = OctagonStateMap(); + backwardMap = [NSDictionary dictionaryWithObjects:[forwardMap allKeys] forKeys:[forwardMap allValues]]; + }); + return backwardMap; +} + +// This mistakenly includes OctagonStateWaitForHSA2, which should not be considered an "In Account" state. +NSSet* OctagonInAccountStates(void) +{ + static NSSet* s = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableSet* sourceStates = [NSMutableSet setWithArray: OctagonStateMap().allKeys]; + + // NoAccount is obviously not in-account, but we also include the startup states that determine + // apple account and icloud account status: + [sourceStates removeObject:OctagonStateNoAccount]; + [sourceStates removeObject:OctagonStateNoAccountDoReset]; + [sourceStates removeObject:OctagonStateInitializing]; + [sourceStates removeObject:OctagonStateDetermineiCloudAccountState]; + [sourceStates removeObject:OctagonStateWaitingForCloudKitAccount]; + [sourceStates removeObject:OctagonStateCloudKitNewlyAvailable]; + + s = sourceStates; + }); + return s; +} + +NSSet* OctagonHealthSourceStates(void) +{ + static NSSet* s = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSMutableSet* sourceStates = [NSMutableSet set]; + + [sourceStates addObject:OctagonStateReady]; + [sourceStates addObject:OctagonStateError]; + [sourceStates addObject:OctagonStateUntrusted]; + [sourceStates addObject:OctagonStateWaitForHSA2]; + [sourceStates addObject:OctagonStateWaitForUnlock]; + + s = sourceStates; + }); + return s; +} + +// Flags +OctagonFlag* const OctagonFlagEgoPeerPreapproved = (OctagonFlag*) @"preapproved"; +OctagonFlag* const OctagonFlagCKKSRequestsTLKUpload = (OctagonFlag*) @"tlk_upload_needed"; +OctagonFlag* const OctagonFlagCuttlefishNotification = (OctagonFlag*) @"recd_push"; +OctagonFlag* const OctagonFlagAccountIsAvailable = (OctagonFlag*)@"account_available"; +OctagonFlag* const OctagonFlagAttemptSOSUpgrade = (OctagonFlag*)@"attempt_sos_upgrade"; +OctagonFlag* const OctagonFlagFetchAuthKitMachineIDList = (OctagonFlag*)@"attempt_machine_id_list"; +OctagonFlag* const OctagonFlagUnlocked = (OctagonFlag*)@"unlocked"; +OctagonFlag* const OctagonFlagAttemptSOSUpdatePreapprovals = (OctagonFlag*)@"attempt_sos_update_preapprovals"; +OctagonFlag* const OctagonFlagPerformHealthCheck = (OctagonFlag*)@"perform_health_check"; +OctagonFlag* const OctagonFlagEscrowRequestInformCloudServicesOperation = (OctagonFlag*)@"escrowrequest_inform_cloudservices"; +#endif // OCTAGON diff --git a/keychain/ot/OTTriggerEscrowUpdateOperation.h b/keychain/ot/OTTriggerEscrowUpdateOperation.h new file mode 100644 index 00000000..d0a68905 --- /dev/null +++ b/keychain/ot/OTTriggerEscrowUpdateOperation.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2019 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTTriggerEscrowUpdateOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; + +@property (weak) OTCuttlefishContext* cuttlefishContext; +@property OctagonState* nextState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTTriggerEscrowUpdateOperation.m b/keychain/ot/OTTriggerEscrowUpdateOperation.m new file mode 100644 index 00000000..64db99cf --- /dev/null +++ b/keychain/ot/OTTriggerEscrowUpdateOperation.m @@ -0,0 +1,85 @@ +/* + * 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 "keychain/ot/OTTriggerEscrowUpdateOperation.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +@interface OTTriggerEscrowUpdateOperation () +@property OTOperationDependencies* deps; +@property NSOperation* finishedOp; +@end + +@implementation OTTriggerEscrowUpdateOperation +@synthesize intendedState = _intendedState; +@synthesize nextState = _nextState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "Triggering escrow update"); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + + NSError* error = nil; + id request = [self.deps.escrowRequestClass request:&error]; + if(!request || error) { + secnotice("octagon-sos", "Unable to acquire a EscrowRequest object: %@", error); + [self runBeforeGroupFinished:self.finishedOp]; + self.error = error; + return; + } + + [request triggerEscrowUpdate:@"octagon-sos" error:&error]; + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradeSilentEscrow hardFailure:true result:error]; + + if(error) { + secnotice("octagon-sos", "Unable to request silent escrow update: %@", error); + self.error = error; + } else{ + secnotice("octagon-sos", "Requested silent escrow update"); + self.nextState = self.intendedState; + } + [self runBeforeGroupFinished:self.finishedOp]; +} + +@end + +#endif // OCTAGON + diff --git a/keychain/ot/OTUpdateTPHOperation.h b/keychain/ot/OTUpdateTPHOperation.h new file mode 100644 index 00000000..6dbc7022 --- /dev/null +++ b/keychain/ot/OTUpdateTPHOperation.h @@ -0,0 +1,24 @@ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +#import "keychain/ot/OTAuthKitAdapter.h" + +NS_ASSUME_NONNULL_BEGIN + +@class OTOperationDependencies; + +@interface OTUpdateTPHOperation : CKKSGroupOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + retryFlag:(OctagonFlag* _Nullable)retryFlag; +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTUpdateTPHOperation.m b/keychain/ot/OTUpdateTPHOperation.m new file mode 100644 index 00000000..d87e9be7 --- /dev/null +++ b/keychain/ot/OTUpdateTPHOperation.m @@ -0,0 +1,154 @@ + +#if OCTAGON + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" + +#import + +#import "keychain/ckks/CloudKitCategories.h" + +#import "keychain/ot/ObjCImprovements.h" + +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/OTUpdateTPHOperation.h" + +@interface OTUpdateTPHOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; + +@property (nullable) OctagonFlag* retryFlag; +@end + +@implementation OTUpdateTPHOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + retryFlag:(OctagonFlag* _Nullable)retryFlag +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + + _retryFlag = retryFlag; + } + return self; +} + +- (void)groupStart +{ + WEAKIFY(self); + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + // If we errored in some unknown way, ask to try again! + STRONGIFY(self); + + if(self.error) { + if(self.retryFlag == nil) { + secerror("octagon: Received an error updating TPH, but no retry flag present."); + return; + } + + // Is this a very scary error? + bool fatal = true; + + OctagonPendingFlag* pendingFlag = nil; + + if([self.deps.lockStateTracker isLockedError:self.error]) { + secnotice("octagon", "Updating trust state failed because locked, retry once unlocked: %@", self.error); + self.nextState = OctagonStateWaitForUnlock; + pendingFlag = [[OctagonPendingFlag alloc] initWithFlag:self.retryFlag + conditions:OctagonPendingConditionsDeviceUnlocked]; + fatal = false; + } else if ([self.error isCuttlefishError:CuttlefishErrorTransactionalFailure]) { + secnotice("octagon", "Transaction failure in cuttlefishm, retrying: %@", self.error); + fatal = false; + } else { + // more CloudKit errors should trigger a retry here + secnotice("octagon", "Error is currently unknown, aborting: %@", self.error); + } + + if(!fatal) { + if(!pendingFlag) { + NSTimeInterval baseDelay = SecCKKSTestsEnabled() ? 2 : 30; + NSTimeInterval delay = CKRetryAfterSecondsForError(self.error) ?: baseDelay; + pendingFlag = [[OctagonPendingFlag alloc] initWithFlag:self.retryFlag + delayInSeconds:delay]; + } + secnotice("octagon", "Updating trust state no fatal: requesting retry: %@", + pendingFlag); + [self.deps.flagHandler handlePendingFlag:pendingFlag]; + } + } + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper, update is lost: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] updateWithContainer:self.deps.containerName + context:self.deps.contextID + deviceName:nil + serialNumber:nil + osVersion:nil + policyVersion:nil + policySecrets:nil + reply:^(TrustedPeersHelperPeerState* peerState, NSError* error) { + STRONGIFY(self); + if(error || !peerState) { + secerror("octagon: update errored: %@", error); + self.error = error; + + // On an error, for now, go back to the intended state + // Octagon: handle lock state errors in update() + self.nextState = self.intendedState; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + secnotice("octagon", "update complete: %@", peerState); + + if(peerState.identityIsPreapproved) { + secnotice("octagon-sos", "Self peer is now preapproved!"); + [self.deps.flagHandler handleFlag:OctagonFlagEgoPeerPreapproved]; + } + if (peerState.memberChanges) { + secnotice("octagon", "Member list changed"); + [self.deps.octagonAdapter sendTrustedPeerSetChangedUpdate]; + } + + if (peerState.unknownMachineIDsPresent) { + secnotice("octagon-authkit", "Unknown machine IDs are present; requesting fetch"); + [self.deps.flagHandler handleFlag:OctagonFlagFetchAuthKitMachineIDList]; + } + + if(peerState.peerStatus & TPPeerStatusExcluded) { + secnotice("octagon", "Self peer (%@) is excluded; moving to untrusted", peerState.peerID); + self.nextState = OctagonStateBecomeUntrusted; + + } else if(peerState.peerStatus & TPPeerStatusUnknown) { + secnotice("octagon", "Self peer (%@) is unknown; moving to untrusted", peerState.peerID); + self.nextState = OctagonStateBecomeUntrusted; + + } else { + self.nextState = self.intendedState; + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTUpdateTrustedDeviceListOperation.h b/keychain/ot/OTUpdateTrustedDeviceListOperation.h new file mode 100644 index 00000000..3d044371 --- /dev/null +++ b/keychain/ot/OTUpdateTrustedDeviceListOperation.h @@ -0,0 +1,26 @@ +#if OCTAGON + +#import +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +#import "keychain/ot/OTAuthKitAdapter.h" + +NS_ASSUME_NONNULL_BEGIN + +@class OTOperationDependencies; + +@interface OTUpdateTrustedDeviceListOperation : CKKSGroupOperation + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + listUpdatesState:(OctagonState*)stateIfListUpdates + errorState:(OctagonState*)errorState + retryFlag:(OctagonFlag* _Nullable)retryFlag; + +@property BOOL logForUpgrade; +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OTUpdateTrustedDeviceListOperation.m b/keychain/ot/OTUpdateTrustedDeviceListOperation.m new file mode 100644 index 00000000..814fab55 --- /dev/null +++ b/keychain/ot/OTUpdateTrustedDeviceListOperation.m @@ -0,0 +1,150 @@ + +#if OCTAGON + +#import "keychain/ot/OTUpdateTrustedDeviceListOperation.h" + +#import + +#import +#import +#import + +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CloudKitCategories.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OTSOSUpgradeOperation.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/ot/OTOperationDependencies.h" + +@interface OTUpdateTrustedDeviceListOperation () +@property OTOperationDependencies* deps; + +@property OctagonState* stateIfListUpdates; + +@property (nullable) OctagonFlag* retryFlag; + +// Since we're making callback based async calls, use this operation trick to hold off the ending of this operation +@property NSOperation* finishedOp; +@end + +@implementation OTUpdateTrustedDeviceListOperation +@synthesize nextState = _nextState; +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + listUpdatesState:(OctagonState*)stateIfListUpdates + errorState:(OctagonState*)errorState + retryFlag:(OctagonFlag*)retryFlag + +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + _stateIfListUpdates = stateIfListUpdates; + + _retryFlag = retryFlag; + } + return self; +} + +- (void)groupStart +{ + WEAKIFY(self); + secnotice("octagon-authkit", "Attempting to update trusted device list"); + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + // If we errored in some unknown way, ask to try again! + STRONGIFY(self); + + if(self.error) { + if(self.retryFlag == nil) { + secerror("octagon-authkit: Received an error updating the trusted device list operation, but no retry flag present."); + return; + } + + OctagonPendingFlag* pendingFlag = nil; + + if([self.deps.lockStateTracker isLockedError:self.error]) { + secnotice("octagon-authkit", "Setting the allowed device list failed due to lock state: %@", self.error); + self.nextState = OctagonStateWaitForUnlock; + pendingFlag = [[OctagonPendingFlag alloc] initWithFlag:self.retryFlag + conditions:OctagonPendingConditionsDeviceUnlocked]; + + } else { + secnotice("octagon-authkit", "Error is currently unknown, will not retry: %@", self.error); + } + + if(pendingFlag) { + secnotice("octagon-authkit", "Machine ID list error is not fatal: requesting retry: %@", + pendingFlag); + [self.deps.flagHandler handlePendingFlag:pendingFlag]; + } + } + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + [self.deps.authKitAdapter fetchCurrentDeviceList:^(NSSet * _Nullable machineIDs, NSError * _Nullable error) { + STRONGIFY(self); + if(!machineIDs || error) { + secerror("octagon-authkit: Unable to fetch machine ID list: %@", error); + if (self.logForUpgrade) { + [[CKKSAnalytics logger] logRecoverableError:error + forEvent:OctagonEventUpgradeFetchDeviceIDs + withAttributes:NULL]; + } + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + } else { + if (self.logForUpgrade) { + [[CKKSAnalytics logger] logSuccessForEventNamed:OctagonEventUpgradeFetchDeviceIDs]; + } + [self afterAuthKitFetch:machineIDs]; + } + }]; +} + +- (void)afterAuthKitFetch:(NSSet*)allowedMachineIDs +{ + WEAKIFY(self); + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon-sos: Can't talk with TrustedPeersHelper: %@", error); + if (self.logForUpgrade) { + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradeSetAllowList hardFailure:true result:error]; + } + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] setAllowedMachineIDsWithContainer:self.deps.containerName + context:self.deps.contextID + allowedMachineIDs:allowedMachineIDs + reply:^(BOOL listDifferences, NSError * _Nullable error) { + STRONGIFY(self); + + if (self.logForUpgrade) { + [[CKKSAnalytics logger] logResultForEvent:OctagonEventUpgradeSetAllowList hardFailure:true result:error]; + } + if(error) { + secnotice("octagon-authkit", "Unable to save machineID allow-list: %@", error); + self.error = error; + } else { + secnotice("octagon-authkit", "Successfully saved machineID allow-list (%@ change)", listDifferences ? @"some" : @"no"); + if(listDifferences) { + self.nextState = self.stateIfListUpdates; + } else { + self.nextState = self.intendedState; + } + } + + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTUploadNewCKKSTLKsOperation.h b/keychain/ot/OTUploadNewCKKSTLKsOperation.h new file mode 100644 index 00000000..f59562bb --- /dev/null +++ b/keychain/ot/OTUploadNewCKKSTLKsOperation.h @@ -0,0 +1,23 @@ + +#import + +#if OCTAGON + +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTUploadNewCKKSTLKsOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; + +@property OctagonState* nextState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTUploadNewCKKSTLKsOperation.m b/keychain/ot/OTUploadNewCKKSTLKsOperation.m new file mode 100644 index 00000000..069a433b --- /dev/null +++ b/keychain/ot/OTUploadNewCKKSTLKsOperation.m @@ -0,0 +1,176 @@ + +#if OCTAGON + +#import "utilities/debugging.h" + +#import + +#import "keychain/ot/OTUploadNewCKKSTLKsOperation.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ckks/CKKSCurrentKeyPointer.h" +#import "keychain/ckks/CKKSKeychainView.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CloudKitCategories.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTUploadNewCKKSTLKsOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; +@property int retries; +@property int maxRetries; +@property int delay; +@property CKKSNearFutureScheduler* retrySched; +@end + +@implementation OTUploadNewCKKSTLKsOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + + _retries = 0; + _maxRetries = 5; + _delay = 1; + + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "Beginning to upload any pending CKKS tlks operation"); + + WEAKIFY(self); + + NSMutableSet* viewsToUpload = [NSMutableSet set]; + + // One (or more) of our sub-CKKSes believes it needs to upload new TLKs. + for(CKKSKeychainView* view in [self.deps.viewManager currentViews]) { + if([view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKUpload] || + [view.keyHierarchyState isEqualToString:SecCKKSZoneKeyStateWaitForTLKCreation]) { + secnotice("octagon-ckks", "CKKS view %@ needs TLK uploads!", view); + [viewsToUpload addObject: view]; + } + } + + if(viewsToUpload.count == 0) { + // Nothing to do; return to ready + secnotice("octagon-ckks", "No CKKS views need uploads"); + self.nextState = self.intendedState; + return; + } + + self.finishedOp = [NSBlockOperation blockOperationWithBlock:^{ + STRONGIFY(self); + secnotice("octagon", "Finishing an update TLKs operation with %@", self.error ?: @"no error"); + }]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithViews:viewsToUpload]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"upload-tlks-with-keys" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets + pendingTLKShares:fetchKeysOp.tlkShares + viewsToUpload:viewsToUpload]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (BOOL)isRetryable:(NSError* _Nonnull)error { + return [error isCuttlefishError:CuttlefishErrorTransactionalFailure]; +} + +- (int)retryDelay:(NSError* _Nonnull)error { + NSError* underlyingError = error.userInfo[NSUnderlyingErrorKey]; + int ret = self->_delay; + if (underlyingError) { + id tmp = underlyingError.userInfo[@"retryafter"]; + if ([tmp isKindOfClass:[NSNumber class]]) { + ret = [(NSNumber*)tmp intValue]; + } + } + ret = MAX(MIN(ret, 32), self->_delay); + self->_delay *= 2; + return ret; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets + pendingTLKShares:(NSArray*)pendingTLKShares + viewsToUpload:(NSSet*)viewsToUpload +{ + WEAKIFY(self); + + secnotice("octagon-ckks", "Beginning tlk upload with keys: %@", viewKeySets); + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon-ckks: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventEstablishIdentity withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] updateTLKsWithContainer:self.deps.containerName + context:self.deps.contextID + ckksKeys:viewKeySets + tlkShares:pendingTLKShares + reply:^(NSArray* _Nullable keyHierarchyRecords, NSError * _Nullable error) { + STRONGIFY(self); + + if(error) { + secerror("octagon: Error calling tlk upload: %@", error); + if (self.retries < self.maxRetries && [self isRetryable:error]) { + ++self.retries; + if (!self.retrySched) { + self.retrySched = [[CKKSNearFutureScheduler alloc] initWithName:@"cuttlefish-updatetlk-retry" + delay:1*NSEC_PER_SEC + keepProcessAlive:true + dependencyDescriptionCode:CKKSResultDescriptionNone + block:^{ + CKKSResultOperation* retryOp = [CKKSResultOperation named:@"retry-updatetlk" + withBlock:^{ + STRONGIFY(self); + secnotice("octagon", "retrying (%d/%d) updateTLKs", self.retries, self->_maxRetries); + [self proceedWithKeys:viewKeySets pendingTLKShares:pendingTLKShares viewsToUpload:viewsToUpload]; + }]; + STRONGIFY(self); + [self runBeforeGroupFinished:retryOp]; + }]; + } + int delay_s = [self retryDelay:error]; + [self.retrySched waitUntil:delay_s*NSEC_PER_SEC]; + [self.retrySched trigger]; + return; + } + self.error = error; + + } else { + + // Tell CKKS about our shiny new records! + for(CKKSKeychainView* view in viewsToUpload) { + secnotice("octagon-ckks", "Providing records to %@", view); + [view receiveTLKUploadRecords: keyHierarchyRecords]; + } + + self.nextState = self.intendedState; + } + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTVouchWithBottleOperation.h b/keychain/ot/OTVouchWithBottleOperation.h new file mode 100644 index 00000000..dc3ef075 --- /dev/null +++ b/keychain/ot/OTVouchWithBottleOperation.h @@ -0,0 +1,57 @@ +/* + * 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTVouchWithBottleOperation : CKKSGroupOperation +@property OctagonState* nextState; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + bottleID:(NSString*)bottleID + entropy:(NSData*)entropy + bottleSalt:(NSString*)bottleSalt; + +@property (weak) OTCuttlefishContext* cuttlefishContext; +@property (nonatomic) NSString* bottleID; +@property (nonatomic) NSData* entropy; +@property (nonatomic) NSString* bottleSalt; + +@property (nonatomic) NSData* voucher; +@property (nonatomic) NSData* voucherSig; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTVouchWithBottleOperation.m b/keychain/ot/OTVouchWithBottleOperation.m new file mode 100644 index 00000000..eb9b31c6 --- /dev/null +++ b/keychain/ot/OTVouchWithBottleOperation.m @@ -0,0 +1,146 @@ +/* + * 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 "keychain/ot/OTVouchWithBottleOperation.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTVouchWithBottleOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; +@end + +@implementation OTVouchWithBottleOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + bottleID:(NSString*)bottleID + entropy:(NSData*)entropy + bottleSalt:(NSString*)bottleSalt +{ + if((self = [super init])) { + _deps = dependencies; + _intendedState = intendedState; + _nextState = errorState; + + _bottleID = bottleID; + _entropy = entropy; + _bottleSalt = bottleSalt; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "creating voucher using a bottle with escrow record id: %@", self.bottleID); + + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + if(self.bottleSalt != nil) { + secnotice("octagon", "using passed in altdsid, altdsid is: %@", self.bottleSalt); + } else{ + if(self.deps.authKitAdapter.primaryiCloudAccountAltDSID){ + secnotice("octagon", "using auth kit adapter, altdsid is: %@", self.deps.authKitAdapter.primaryiCloudAccountAltDSID); + self.bottleSalt = self.deps.authKitAdapter.primaryiCloudAccountAltDSID; + } + else { + NSError* accountError = nil; + OTAccountMetadataClassC* account = [self.deps.stateHolder loadOrCreateAccountMetadata:&accountError]; + + if(account && !accountError) { + secnotice("octagon", "retrieved account, altdsid is: %@", account.altDSID); + self.bottleSalt = account.altDSID; + } + if(accountError || !account){ + secerror("failed to rerieve account object: %@", accountError); + } + } + } + + WEAKIFY(self); + + // After a vouch, we also want to acquire all TLKs that the bottled peer might have had + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"bottle-tlks" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets tlkShares:fetchKeysOp.tlkShares]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets tlkShares:(NSArray*)tlkShares +{ + WEAKIFY(self); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventVoucherWithBottle withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] vouchWithBottleWithContainer:self.deps.containerName + context:self.deps.contextID + bottleID:self.bottleID + entropy:self.entropy + bottleSalt:self.bottleSalt + tlkShares:tlkShares + reply:^(NSData * _Nullable voucher, NSData * _Nullable voucherSig, NSError * _Nullable error) { + [[CKKSAnalytics logger] logResultForEvent:OctagonEventVoucherWithBottle hardFailure:true result:error]; + + if(error){ + secerror("octagon: Error preparing voucher using bottle: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + secnotice("octagon", "Received bottle voucher"); + + self.voucher = voucher; + self.voucherSig = voucherSig; + self.nextState = self.intendedState; + [self runBeforeGroupFinished:self.finishedOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OTVouchWithRecoveryKeyOperation.h b/keychain/ot/OTVouchWithRecoveryKeyOperation.h new file mode 100644 index 00000000..12712c0e --- /dev/null +++ b/keychain/ot/OTVouchWithRecoveryKeyOperation.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019 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 "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +@class OTCuttlefishContext; + +NS_ASSUME_NONNULL_BEGIN + +@interface OTVouchWithRecoveryKeyOperation : CKKSGroupOperation +@property OctagonState* nextState; +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + recoveryKey:(NSString*)recoveryKey; + +@property (weak) OTCuttlefishContext* cuttlefishContext; +@property (nonatomic) NSString* salt; +@property (nonatomic) NSString* recoveryKey; + +@property (nonatomic) NSData* voucher; +@property (nonatomic) NSData* voucherSig; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OTVouchWithRecoveryKeyOperation.m b/keychain/ot/OTVouchWithRecoveryKeyOperation.m new file mode 100644 index 00000000..b4fc0bc9 --- /dev/null +++ b/keychain/ot/OTVouchWithRecoveryKeyOperation.m @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2019 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 "keychain/ot/OTVouchWithRecoveryKeyOperation.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OTVouchWithRecoveryKeyOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishOp; +@end + +@implementation OTVouchWithRecoveryKeyOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + recoveryKey:(NSString*)recoveryKey +{ + if((self = [super init])) { + _deps = dependencies; + _intendedState = intendedState; + _nextState = errorState; + + _recoveryKey = recoveryKey; + } + return self; +} + +- (void)groupStart +{ + secnotice("octagon", "creating voucher using a recovery key"); + + self.finishOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishOp]; + + NSString* salt = nil; + + if(self.salt != nil) { + secnotice("octagon", "using passed in altdsid, altdsid is: %@", self.salt); + salt = self.salt; + } else{ + if(self.deps.authKitAdapter.primaryiCloudAccountAltDSID){ + secnotice("octagon", "using auth kit adapter, altdsid is: %@", self.deps.authKitAdapter.primaryiCloudAccountAltDSID); + salt = self.deps.authKitAdapter.primaryiCloudAccountAltDSID; + } + else { + NSError* accountError = nil; + OTAccountMetadataClassC* account = [self.deps.stateHolder loadOrCreateAccountMetadata:&accountError]; + + if(account && !accountError) { + secnotice("octagon", "retrieved account, altdsid is: %@", account.altDSID); + salt = account.altDSID; + } + if(accountError || !account){ + secerror("failed to rerieve account object: %@", accountError); + } + } + } + + WEAKIFY(self); + + // After a vouch, we also want to acquire all TLKs that the bottled peer might have had + OTFetchCKKSKeysOperation* fetchKeysOp = [[OTFetchCKKSKeysOperation alloc] initWithDependencies:self.deps]; + [self runBeforeGroupFinished:fetchKeysOp]; + + CKKSResultOperation* proceedWithKeys = [CKKSResultOperation named:@"recovery-tlks" + withBlock:^{ + STRONGIFY(self); + [self proceedWithKeys:fetchKeysOp.viewKeySets tlkShares:fetchKeysOp.tlkShares salt:salt]; + }]; + + [proceedWithKeys addDependency:fetchKeysOp]; + [self runBeforeGroupFinished:proceedWithKeys]; +} + +- (void)proceedWithKeys:(NSArray*)viewKeySets tlkShares:(NSArray*)tlkShares salt:(NSString*)salt +{ + WEAKIFY(self); + + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + [[CKKSAnalytics logger] logRecoverableError:error forEvent:OctagonEventVoucherWithBottle withAttributes:NULL]; + self.error = error; + [self runBeforeGroupFinished:self.finishOp]; + + }] vouchWithRecoveryKeyWithContainer:self.deps.containerName + context:self.deps.contextID + recoveryKey:self.recoveryKey + salt:salt + tlkShares:tlkShares + reply:^(NSData * _Nullable voucher, NSData * _Nullable voucherSig, NSError * _Nullable error) { + if(error){ + [[CKKSAnalytics logger] logResultForEvent:OctagonEventVoucherWithRecoveryKey hardFailure:true result:error]; + secerror("octagon: Error preparing voucher using recovery key: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishOp]; + return; + } + self.voucher = voucher; + self.voucherSig = voucherSig; + self.nextState = self.intendedState; + [self runBeforeGroupFinished:self.finishOp]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/ObjCImprovements.h b/keychain/ot/ObjCImprovements.h new file mode 100644 index 00000000..8e2f54ff --- /dev/null +++ b/keychain/ot/ObjCImprovements.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 20178 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 ObjCImprovements_h +#define ObjCImprovements_h + +// Useful for never getting retain loops with blocks. +#define WEAKIFY(n) __weak __typeof(n) weak_##n = n + +#define STRONGIFY(n) _Pragma("clang diagnostic push")\ +_Pragma("clang diagnostic ignored \"-Wshadow\"") \ +__strong __typeof(n) n = weak_##n; \ +_Pragma("clang diagnostic pop"); + + +#endif /* ObjCImprovements_h */ diff --git a/keychain/ot/OctagonCKKSPeerAdapter.h b/keychain/ot/OctagonCKKSPeerAdapter.h new file mode 100644 index 00000000..4936cc22 --- /dev/null +++ b/keychain/ot/OctagonCKKSPeerAdapter.h @@ -0,0 +1,30 @@ + +#if OCTAGON + +#import +#import "keychain/ot/OTOperationDependencies.h" +#import "keychain/ckks/CKKSPeer.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OctagonSelfPeer : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithPeerID:(NSString*)peerID + signingIdentity:(SFIdentity*)signingIdentity + encryptionIdentity:(SFIdentity*)encryptionIdentity; + +@end + +@interface OctagonCKKSPeerAdapter : NSObject + +@property (nullable) NSString* peerID; +@property OTOperationDependencies* deps; + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithPeerID:(NSString*)peerID operationDependencies:(OTOperationDependencies*)deps; +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OctagonCKKSPeerAdapter.m b/keychain/ot/OctagonCKKSPeerAdapter.m new file mode 100644 index 00000000..3aacf713 --- /dev/null +++ b/keychain/ot/OctagonCKKSPeerAdapter.m @@ -0,0 +1,242 @@ + +#if OCTAGON + +#import +#import + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSListenerCollection.h" + +#import "keychain/ot/ObjCImprovements.h" +#import "utilities/debugging.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +@interface OctagonSelfPeer () +@property SFIdentity* encryptionIdentity; +@property SFIdentity* signingIdentity; +@end + +@implementation OctagonSelfPeer +@synthesize peerID = _peerID; + +- (instancetype)initWithPeerID:(NSString*)peerID + signingIdentity:(SFIdentity*)signingIdentity + encryptionIdentity:(SFIdentity*)encryptionIdentity +{ + if((self = [super init])) { + _peerID = peerID; + _signingIdentity = signingIdentity; + _encryptionIdentity = encryptionIdentity; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.peerID]; +} + +- (SFECPublicKey*)publicEncryptionKey +{ + return self.encryptionIdentity.publicKey; +} + +- (SFECPublicKey*)publicSigningKey +{ + return self.signingIdentity.publicKey; +} + +- (SFECKeyPair*)encryptionKey +{ + return self.encryptionIdentity.keyPair; +} + +- (SFECKeyPair*)signingKey +{ + return self.signingIdentity.keyPair; +} + +- (bool)matchesPeer:(nonnull id)peer { + NSString* otherPeerID = peer.peerID; + + if(self.peerID == nil && otherPeerID == nil) { + return true; + } + + return [self.peerID isEqualToString:otherPeerID]; +} + +@end + +@interface OctagonCKKSPeerAdapter () +@property CKKSListenerCollection* peerChangeListeners; +@end + +@implementation OctagonCKKSPeerAdapter +@synthesize essential = _essential; +@synthesize providerID = _providerID; + +- (instancetype)initWithPeerID:(NSString*)peerID operationDependencies:(OTOperationDependencies*)deps +{ + if((self = [super init])) { + _providerID = [NSString stringWithFormat:@"[OctagonCKKSPeerAdapter:%@]", peerID]; + _peerID = peerID; + _deps = deps; + + _peerChangeListeners = [[CKKSListenerCollection alloc] initWithName:@"ckks-sos"]; + + // Octagon is king. + _essential = YES; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.peerID, self.essential]; +} + +- (SFIdentity*)fetchIdentity:(NSString*)identifier error:(NSError *__autoreleasing _Nullable * _Nullable)error +{ + // Async to sync again! No other option. + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + SFKeychainManager* keychainManager = [SFKeychainManager defaultManager]; + + __block SFIdentity* identity = nil; + __block NSError* localError = nil; + + [keychainManager identityForIdentifier:identifier resultHandler:^(SFKeychainIdentityFetchResult * _Nonnull result) { + switch(result.resultType) { + case SFKeychainFetchResultTypeError: + case SFKeychainFetchResultTypeNeedsAuthentication: + secnotice("octagon-ckks", "Unable to fetch identity '%@' from keychain: %@", identifier, result.error); + localError = result.error; + break; + + case SFKeychainFetchResultTypeValueAvailable: + identity = result.value; + break; + } + dispatch_semaphore_signal(sema); + }]; + + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + + if(error && localError) { + *error = localError; + } + return identity; +} + +- (CKKSSelves * _Nullable)fetchSelfPeers:(NSError *__autoreleasing _Nullable * _Nullable)error +{ + if(self.peerID) { + // Shameless duplication of swift code in TPH. Thanks, perf team! + NSError* keychainError = nil; + + SFIdentity* signingIdentity = [self fetchIdentity:[NSString stringWithFormat:@"signing-key %@", self.peerID] error:&keychainError]; + if(!signingIdentity || keychainError) { + if(error) { + // TODO: ensure error exists + *error = keychainError; + } + return nil; + } + + SFIdentity* encryptionIdentity = [self fetchIdentity:[NSString stringWithFormat:@"encryption-key %@", self.peerID] error:&keychainError]; + if(!encryptionIdentity || keychainError) { + if(error) { + // TODO: ensure error exists + *error = keychainError; + } + return nil; + } + + OctagonSelfPeer* selfPeer = [[OctagonSelfPeer alloc] initWithPeerID:self.peerID + signingIdentity:signingIdentity + encryptionIdentity:encryptionIdentity]; + + CKKSSelves* selves = [[CKKSSelves alloc] initWithCurrent:selfPeer allSelves:[NSSet set]]; + return selves; + } + + secnotice("octagon-ckks", "No peer ID; therefore no identity"); + if(error) { + *error = [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorNoIdentity + description:@"no peer ID present"]; + } + return nil; +} + +- (NSSet> * _Nullable)fetchTrustedPeers:(NSError *__autoreleasing _Nullable * _Nullable)error +{ + // TODO: make this memoized somehow, somewhere + + __block NSError* localerror; + __block NSMutableSet> * peers = nil; + + WEAKIFY(self); + [[self.deps.cuttlefishXPC synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + secerror("octagon: Can't talk with TrustedPeersHelper: %@", error); + localerror = error; + + }] fetchTrustStateWithContainer:self.deps.containerName + context:self.deps.contextID + reply:^(TrustedPeersHelperPeerState * _Nullable selfPeerState, + NSArray * _Nullable trustedPeers, + NSError * _Nullable operror) { + STRONGIFY(self); + if(operror) { + secnotice("octagon", "Unable to fetch trusted peers for (%@,%@): %@", self.deps.containerName, self.deps.contextID, operror); + localerror = operror; + + } else { + peers = [NSMutableSet set]; + + // Turn these peers into CKKSPeers + for(TrustedPeersHelperPeer* peer in trustedPeers) { + SFECPublicKey* signingKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:peer.signingSPKI]; + SFECPublicKey* encryptionKey = [SFECPublicKey keyWithSubjectPublicKeyInfo:peer.encryptionSPKI]; + + CKKSActualPeer* ckkspeer = [[CKKSActualPeer alloc] initWithPeerID:peer.peerID + encryptionPublicKey:encryptionKey + signingPublicKey:signingKey + viewList:peer.viewList]; + secnotice("octagon", "Have trusted peer %@", ckkspeer); + + [peers addObject:ckkspeer]; + } + } + }]; + + if(error && localerror) { + *error = localerror; + } + + return peers; +} + +- (void)registerForPeerChangeUpdates:(nonnull id)listener { + [self.peerChangeListeners registerListener:listener]; +} + +- (void)sendSelfPeerChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener selfPeerChanged: self]; + }]; +} + +- (void)sendTrustedPeerSetChangedUpdate { + [self.peerChangeListeners iterateListeners: ^(id listener) { + [listener trustedPeerSetChanged: self]; + }]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OctagonCheckTrustStateOperation.h b/keychain/ot/OctagonCheckTrustStateOperation.h new file mode 100644 index 00000000..aa844a5a --- /dev/null +++ b/keychain/ot/OctagonCheckTrustStateOperation.h @@ -0,0 +1,23 @@ + +#import + +#if OCTAGON + +#import "keychain/ckks/CKKSGroupOperation.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OTOperationDependencies.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OctagonCheckTrustStateOperation : CKKSGroupOperation +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState; + +@property OctagonState* nextState; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OctagonCheckTrustStateOperation.m b/keychain/ot/OctagonCheckTrustStateOperation.m new file mode 100644 index 00000000..0e05403c --- /dev/null +++ b/keychain/ot/OctagonCheckTrustStateOperation.m @@ -0,0 +1,214 @@ + +#if OCTAGON + +#import "utilities/debugging.h" + +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OctagonCheckTrustStateOperation.h" +#import "keychain/ot/OctagonCKKSPeerAdapter.h" +#import "keychain/ot/OTCuttlefishAccountStateHolder.h" +#import "keychain/ot/OTFetchCKKSKeysOperation.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ckks/CKKSCurrentKeyPointer.h" +#import "keychain/ckks/CKKSKeychainView.h" + +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "keychain/ot/ObjCImprovements.h" + +@interface OctagonCheckTrustStateOperation () +@property OTOperationDependencies* deps; + +@property NSOperation* finishedOp; +@end + +@implementation OctagonCheckTrustStateOperation +@synthesize intendedState = _intendedState; + +- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies + intendedState:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _deps = dependencies; + + _intendedState = intendedState; + _nextState = errorState; + } + return self; +} + +- (void)groupStart +{ + self.finishedOp = [[NSOperation alloc] init]; + [self dependOnBeforeGroupFinished:self.finishedOp]; + + // Make sure we're in agreement with TPH about _which_ peer ID we should have + WEAKIFY(self); + [[self.deps.cuttlefishXPC remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + STRONGIFY(self); + secerror("octagon: Can't talk with TrustedPeersHelper, can't ensure check trust state: %@", error); + self.error = error; + [self runBeforeGroupFinished:self.finishedOp]; + + }] fetchTrustStateWithContainer:self.deps.containerName + context:self.deps.contextID + reply:^(TrustedPeersHelperPeerState * _Nullable selfPeerState, + NSArray * _Nullable trustedPeers, + NSError * _Nullable error) { + STRONGIFY(self); + if(error || !selfPeerState || !trustedPeers) { + secerror("octagon: TPH was unable to determine current peer state: %@", error); + self.error = error; + self.nextState = OctagonStateError; + [self runBeforeGroupFinished:self.finishedOp]; + + } else { + [self afterTPHTrustState:selfPeerState trustedPeers:trustedPeers]; + } + }]; +} + +- (void)afterTPHTrustState:(TrustedPeersHelperPeerState*)peerState + trustedPeers:(NSArray *)trustedPeers +{ + NSError* localError = nil; + + if (peerState.memberChanges) { + secnotice("octagon", "Member list changed"); + [self.deps.octagonAdapter sendTrustedPeerSetChangedUpdate]; + } + + bool changedCurrentAccountMetadata = false; + OTAccountMetadataClassC* currentAccountMetadata = [self.deps.stateHolder loadOrCreateAccountMetadata:&localError]; + + if(localError) { + if([self.deps.lockStateTracker isLockedError:localError]) { + secerror("octagon-consistency: Unable to fetch current account state due to lock state: %@", localError); + self.nextState = OctagonStateWaitForUnlock; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + secerror("octagon-consistency: Unable to fetch current account state. Can't ensure consistency: %@", localError); + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + // What state does TPH think it's in? + // This code is slightly duplicated with rpcTrustStatus; we should probably fix that + OTAccountMetadataClassC_TrustState trustState = OTAccountMetadataClassC_TrustState_UNKNOWN; + if(peerState.peerStatus & TPPeerStatusExcluded) { + trustState = OTAccountMetadataClassC_TrustState_UNTRUSTED; + + } else if(peerState.peerStatus & TPPeerStatusUnknown) { + trustState = OTAccountMetadataClassC_TrustState_UNTRUSTED; + + } else if((peerState.peerStatus & TPPeerStatusSelfTrust) || + (peerState.peerStatus & TPPeerStatusFullyReciprocated) || + (peerState.peerStatus & TPPeerStatusPartiallyReciprocated)) { + trustState = OTAccountMetadataClassC_TrustState_TRUSTED; + } + + secnotice("octagon-consistency", "TPH's trust state (%@) is considered %@", + TPPeerStatusToString(peerState.peerStatus), + OTAccountMetadataClassC_TrustStateAsString(trustState)); + + if(trustState == currentAccountMetadata.trustState) { + secnotice("octagon-consistency", "TPH peer status matches cache: (%@)", TPPeerStatusToString(peerState.peerStatus)); + [[CKKSAnalytics logger] logSuccessForEventNamed:OctagonEventCheckTrustState]; + } else { + secerror("octagon-consistency: Locally cached status (%@) does not match TPH's current peer status (%@)", + OTAccountMetadataClassC_TrustStateAsString(currentAccountMetadata.trustState), + OTAccountMetadataClassC_TrustStateAsString(trustState)); + + if (currentAccountMetadata.trustState == OTAccountMetadataClassC_TrustState_TRUSTED && trustState == OTAccountMetadataClassC_TrustState_UNTRUSTED) { + [[CKKSAnalytics logger] logHardFailureForEventNamed:OctagonEventCheckTrustState withAttributes:nil]; + } + + currentAccountMetadata.trustState = trustState; + changedCurrentAccountMetadata = true; + } + + if([peerState.peerID isEqualToString:currentAccountMetadata.peerID] || + (peerState.peerID == nil && currentAccountMetadata.peerID == nil)) { + secnotice("octagon-consistency", "TPH peer ID matches cache: (%@)", peerState.peerID); + } else { + secerror("octagon-consistency: Locally cached peer ID (%@) does not match TPH's current peer ID (%@)", + currentAccountMetadata.peerID, + peerState.peerID); + + currentAccountMetadata.peerID = peerState.peerID; + changedCurrentAccountMetadata = true; + } + + if(changedCurrentAccountMetadata) { + + NSError* localError = nil; + BOOL persisted = [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC * _Nonnull(OTAccountMetadataClassC * _Nonnull metadata) { + metadata.trustState = currentAccountMetadata.trustState; + metadata.peerID = currentAccountMetadata.peerID; + return metadata; + } error:&localError]; + + if(!persisted || localError) { + if([self.deps.lockStateTracker isLockedError:localError]) { + secerror("octagon-consistency: Unable to save new account state due to lock state: %@", localError); + self.nextState = OctagonStateWaitForUnlock; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + secerror("octagon-consistency: Unable to save new account state. Erroring: %@", localError); + self.error = localError; + self.nextState = OctagonStateError; + [self runBeforeGroupFinished:self.finishedOp]; + return; + } + + secnotice("octagon-consistency", "Saved new account metadata"); + } + + // And determine where to go from here! + + if(currentAccountMetadata.peerID && currentAccountMetadata.trustState == OTAccountMetadataClassC_TrustState_TRUSTED) { + secnotice("octagon", "Appear to be trusted for peer %@; ensuring correct state", currentAccountMetadata.peerID); + self.nextState = OctagonStateEnsureConsistency; + + } else if(self.deps.sosAdapter.sosEnabled && + currentAccountMetadata.trustState != OTAccountMetadataClassC_TrustState_TRUSTED && + OctagonPerformSOSUpgrade()) { + secnotice("octagon", "Have iCloud account but not trusted in Octagon yet; inspecting SOS status: %@", + [currentAccountMetadata trustStateAsString:currentAccountMetadata.trustState]); + + NSError* circleError = nil; + SOSCCStatus sosStatus = [self.deps.sosAdapter circleStatus:&circleError]; + + if(sosStatus == kSOSCCInCircle) { + secnotice("octagon", "SOS status is 'trusted'; requesting SOS upgrade"); + [self.deps.flagHandler handleFlag:OctagonFlagAttemptSOSUpgrade]; + } else { + secnotice("octagon", "SOS status is %d (error: %@)", (int)sosStatus, circleError); + } + self.nextState = OctagonStateBecomeUntrusted; + + } else if(currentAccountMetadata.trustState != OTAccountMetadataClassC_TrustState_TRUSTED) { + secnotice("octagon", "Have iCloud account but not trusted in Octagon (%@)", + OTAccountMetadataClassC_TrustStateAsString(currentAccountMetadata.trustState)); +#if TARGET_OS_WATCH + self.nextState = OctagonStateStartCompanionPairing; +#else + self.nextState = OctagonStateBecomeUntrusted; +#endif + } else { + secnotice("octagon", "Unknown trust state (%@). Assuming untrusted...", + OTAccountMetadataClassC_TrustStateAsString(currentAccountMetadata.trustState)); + self.nextState = OctagonStateBecomeUntrusted; + } + + [self runBeforeGroupFinished:self.finishedOp]; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OctagonControlServer.h b/keychain/ot/OctagonControlServer.h index 35658dba..c3246a96 100644 --- a/keychain/ot/OctagonControlServer.h +++ b/keychain/ot/OctagonControlServer.h @@ -27,4 +27,27 @@ __BEGIN_DECLS void OctagonControlServerInitialize(void); + +#if __OBJC__ +#import "keychain/ot/OTControlProtocol.h" +NS_ASSUME_NONNULL_BEGIN + +@protocol OctagonEntitlementBearerProtocol +- (nullable id)valueForEntitlement:(NSString *)entitlement; +@end + +@interface NSXPCConnection (OctagonEntitlement) +@end + +#if OCTAGON +@class OTManager; +@interface OctagonXPCEntitlementChecker : NSProxy ++ (id)createWithManager:(OTManager*)manager + entitlementBearer:(id)bearer; +@end +#endif // OCTAGON + +NS_ASSUME_NONNULL_END +#endif // __OBJC__ + __END_DECLS diff --git a/keychain/ot/OctagonControlServer.m b/keychain/ot/OctagonControlServer.m index a1fdf15a..9d67c837 100644 --- a/keychain/ot/OctagonControlServer.m +++ b/keychain/ot/OctagonControlServer.m @@ -22,13 +22,77 @@ */ #import +#import #import #import -#import "SecEntitlements.h" +#import #import "keychain/ot/OctagonControlServer.h" #import "keychain/ot/OTManager.h" #import "keychain/ot/OT.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +#if OCTAGON +@interface OctagonXPCEntitlementChecker () +@property OTManager* manager; +@property id entitlementBearer; +- (instancetype)initWithManager:(OTManager*)manager + entitlementBearer:(id)bearer; +@end + +@implementation OctagonXPCEntitlementChecker + +- (instancetype)initWithManager:(OTManager*)manager entitlementBearer:(id)bearer +{ + // NSProxy does not implement init, so don't call super init + _manager = manager; + _entitlementBearer = bearer; + return self; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector +{ + return [self.manager methodSignatureForSelector:selector]; +} + +- (void)forwardInvocation:(NSInvocation *)invocation +{ + if(sel_isEqual(invocation.selector, @selector(fetchEscrowContents:contextID:reply:))) { + if(![self.entitlementBearer valueForEntitlement:kSecEntitlementPrivateOctagonEscrow]) { + secerror("Client %@ does not have entitlement %@, rejecting rpc", self.entitlementBearer, kSecEntitlementPrivateOctagonEscrow); + [invocation setSelector:@selector(failFetchEscrowContents:contextID:reply:)]; + [invocation invokeWithTarget:self]; + return; + } + } + [invocation invokeWithTarget:self.manager]; +} + +- (void)failFetchEscrowContents:(NSString*)containerName + contextID:(NSString *)contextID + reply:(void (^)(NSData* _Nullable entropy, + NSString* _Nullable bottleID, + NSData* _Nullable signingPublicKey, + NSError* _Nullable error))reply +{ + reply(nil, nil, nil, [NSError errorWithDomain:NSOSStatusErrorDomain + code:errSecMissingEntitlement + description:[NSString stringWithFormat: @"Missing entitlement '%@'", kSecEntitlementPrivateOctagonEscrow]]); +} + ++ (BOOL)conformsToProtocol:(Protocol *)protocol { + return [[OTManager class] conformsToProtocol:protocol]; +} + +// Launder a OctagonXPCEntitlementChecker into something that type-safely implements the protocol we're interested in ++ (id)createWithManager:(OTManager*)manager + entitlementBearer:(id)bearer +{ + return (id) [[OctagonXPCEntitlementChecker alloc] initWithManager:manager entitlementBearer:bearer]; +} +@end +#endif // OCTAGON @interface OctagonControlServer : NSObject @end @@ -45,7 +109,7 @@ return NO; } // In the future, we should consider vending a proxy object that can return a nicer error. - if (!SecOTIsEnabled()) { + if (!OctagonIsEnabled()) { secerror("Octagon: Client pid: %d attempted to use Octagon, but Octagon is not enabled.", newConnection.processIdentifier); return NO; @@ -53,7 +117,7 @@ secnotice("octagon", "received connection from client pid %d", [newConnection processIdentifier]); newConnection.exportedInterface = OTSetupControlProtocol([NSXPCInterface interfaceWithProtocol:@protocol(OTControlProtocol)]); - newConnection.exportedObject = [OTManager manager]; + newConnection.exportedObject = [OctagonXPCEntitlementChecker createWithManager:[OTManager manager] entitlementBearer:newConnection]; [newConnection resume]; diff --git a/keychain/ot/OctagonFlags.h b/keychain/ot/OctagonFlags.h new file mode 100644 index 00000000..6170941e --- /dev/null +++ b/keychain/ot/OctagonFlags.h @@ -0,0 +1,37 @@ + +#if OCTAGON + +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OctagonPendingFlag.h" + +NS_ASSUME_NONNULL_BEGIN + +// OctagonFlags allow you to set binary flags for consumption by the state machine, similar to processor interrupts +// This allows the state machine to respond to external inputs or requests that don't need a timeout attached to them. +// Setting and removing flags are idempotent. + +@protocol OctagonFlagContainer +- (BOOL)_onqueueContains:(OctagonFlag*)flag; +- (NSArray*)dumpFlags; +@end + +@protocol OctagonFlagSetter +- (void)setFlag:(OctagonFlag*)flag; +- (void)_onqueueSetFlag:(OctagonFlag*)flag; +@end + +@protocol OctagonFlagClearer +- (void)_onqueueRemoveFlag:(OctagonFlag*)flag; +@end + +@interface OctagonFlags : NSObject +- (instancetype)initWithQueue:(dispatch_queue_t)queue; + +- (NSString*)contentsAsString; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OctagonFlags.m b/keychain/ot/OctagonFlags.m new file mode 100644 index 00000000..766ab3fb --- /dev/null +++ b/keychain/ot/OctagonFlags.m @@ -0,0 +1,63 @@ + +#if OCTAGON + +#import "keychain/ot/OctagonFlags.h" + +@interface OctagonFlags () +@property dispatch_queue_t queue; +@property NSMutableSet* flags; +@end + +@implementation OctagonFlags + +- (instancetype)initWithQueue:(dispatch_queue_t)queue +{ + if((self = [super init])) { + _queue = queue; + _flags = [NSMutableSet set]; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", [self contentsAsString]]; +} + +- (NSString*)contentsAsString +{ + if(self.flags.count == 0) { + return @"none"; + } + return [[self.flags allObjects] componentsJoinedByString:@","]; +} + +- (NSArray*)dumpFlags +{ + return [self.flags allObjects]; +} + +- (BOOL)_onqueueContains:(nonnull OctagonFlag *)flag { + dispatch_assert_queue(self.queue); + return [self.flags containsObject:flag]; +} + +- (void)_onqueueSetFlag:(nonnull OctagonFlag *)flag { + dispatch_assert_queue(self.queue); + [self.flags addObject:flag]; +} + +- (void)setFlag:(nonnull OctagonFlag *)flag { + dispatch_sync(self.queue, ^{ + [self _onqueueSetFlag:flag]; + }); +} + +- (void)_onqueueRemoveFlag:(nonnull OctagonFlag *)flag { + dispatch_assert_queue(self.queue); + [self.flags removeObject:flag]; +} + +@end + +#endif diff --git a/keychain/ot/OctagonPendingFlag.h b/keychain/ot/OctagonPendingFlag.h new file mode 100644 index 00000000..a130fcef --- /dev/null +++ b/keychain/ot/OctagonPendingFlag.h @@ -0,0 +1,34 @@ + +#if OCTAGON + +#import +#import "keychain/ot/OctagonStateMachineHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +// An OctagonPendingFlag asks the state machine to add a flag in the future, when some conditions are met + +// Currently, this is only time-based. +// Future planned conditions include "device is probably unlocked" and "device has network again" + +typedef NS_OPTIONS(NSUInteger, OctagonPendingConditions) { + OctagonPendingConditionsDeviceUnlocked = 1, +}; + +NSString* OctagonPendingConditionsToString(OctagonPendingConditions cond); + +@interface OctagonPendingFlag : NSObject +@property (readonly) OctagonFlag* flag; + +// NSDate after which this flag should become unpending +@property (nullable, readonly) NSDate* fireTime; + +@property (readonly) OctagonPendingConditions conditions; + +- (instancetype)initWithFlag:(OctagonFlag*)flag delayInSeconds:(NSTimeInterval)delay; +- (instancetype)initWithFlag:(OctagonFlag*)flag conditions:(OctagonPendingConditions)conditions; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OctagonPendingFlag.m b/keychain/ot/OctagonPendingFlag.m new file mode 100644 index 00000000..d192ae41 --- /dev/null +++ b/keychain/ot/OctagonPendingFlag.m @@ -0,0 +1,50 @@ + +#if OCTAGON + +#import "keychain/ot/OctagonPendingFlag.h" + +NSString* OctagonPendingConditionsToString(OctagonPendingConditions cond) +{ + if((cond & OctagonPendingConditionsDeviceUnlocked) != 0x0) { + return @"unlock"; + } + if(cond == 0x0) { + return @"none"; + } + return [NSString stringWithFormat:@"Unknown conditions: 0x%x", (int)cond]; +} + +@implementation OctagonPendingFlag + +- (instancetype)initWithFlag:(OctagonFlag*)flag delayInSeconds:(NSTimeInterval)delay +{ + if ((self = [super init])) { + _flag = flag; + _fireTime = [NSDate dateWithTimeIntervalSinceNow:delay]; + _conditions = 0; + } + return self; +} + +- (instancetype)initWithFlag:(OctagonFlag*)flag + conditions:(OctagonPendingConditions)conditions +{ + if ((self = [super init])) { + _flag = flag; + _fireTime = nil; + _conditions = conditions; + } + return self; +} + +- (NSString*)description { + if(self.fireTime) { + return [NSString stringWithFormat:@"", self.flag, self.fireTime]; + } else { + return [NSString stringWithFormat:@"", self.flag, OctagonPendingConditionsToString(self.conditions)]; + } +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OctagonStateMachine.h b/keychain/ot/OctagonStateMachine.h new file mode 100644 index 00000000..a4503e08 --- /dev/null +++ b/keychain/ot/OctagonStateMachine.h @@ -0,0 +1,104 @@ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ckks/CKKSCondition.h" +#import "keychain/ckks/CKKSLockStateTracker.h" + +#import "keychain/ot/OctagonStateMachineHelpers.h" +#import "keychain/ot/OctagonStateMachineObservers.h" +#import "keychain/ot/OctagonFlags.h" +#import "keychain/ot/OctagonPendingFlag.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol OctagonStateOnqueuePendingFlagHandler +- (void)_onqueueHandlePendingFlag:(OctagonPendingFlag*)pendingFlag; +@end + +// A State Machine Engine provides the actual implementation of a state machine. +// Its sole callback will be called on the queue passed into the OctagonStateMachine. +// Its inputs are the current state, and any interrupt flags that have been set on the state machine. + +// The returned operation should not yet be started; the state machine will run it. +// Return nil if there's nothing to be done yet; the state machine will remain in the currentState until poked. +// The engine will be held weakly, so, ensure you keep it around. +@protocol OctagonStateMachineEngine +- (CKKSResultOperation* _Nullable)_onqueueNextStateMachineTransition:(OctagonState*)currentState + flags:(OctagonFlags*)flags + pendingFlags:(id)pendingFlagHandler; +@end + +@protocol OctagonStateFlagHandler +- (void)handleFlag:(OctagonFlag*)flag; +- (void)handlePendingFlag:(OctagonPendingFlag*)pendingFlag; +@end + +@interface OctagonStateMachine : NSObject +@property (readonly) OctagonState* currentState; + +// The state machine transition function is the only location which should remove flags. +// Adding flags should use -handleFlag on the state machine +@property (readonly) id flags; + +@property NSMutableDictionary* stateConditions; +@property (readonly) CKKSCondition* paused; + +@property (readonly) NSSet* allowableStates; +@property (nonatomic) uint64_t timeout; + +@property (nullable) CKKSLockStateTracker* lockStateTracker; + +// If you don't pass a lock state tracker, then you cannot reasonably use OctagonPendingConditionsDeviceUnlocked + +- (instancetype)initWithName:(NSString*)name + states:(NSSet*)possibleStates + initialState:(OctagonState*)initialState + queue:(dispatch_queue_t)queue + stateEngine:(id)stateEngine + lockStateTracker:(CKKSLockStateTracker* _Nullable)lockStateTracker; + +- (void)startOperation; +- (void)haltOperation; + +// If the state machine is paused, this will kick it to start up again. Otherwise, it is a no-op. +- (void)pokeStateMachine; +- (void)_onqueuePokeStateMachine; + +// This will set the given flag, and ensure that the state machine spins to handle it. +- (void)handleFlag:(OctagonFlag*)flag; + +// This will schedule the flag for future addition +- (void)handlePendingFlag:(OctagonPendingFlag *)pendingFlag; + +- (NSDictionary*)dumpPendingFlags; +// For testing +- (NSArray*)possiblePendingFlags; +- (void)disablePendingFlags; + +- (void)handleExternalRequest:(OctagonStateTransitionRequest*>*)request; +- (void)registerStateTransitionWatcher:(OctagonStateTransitionWatcher*)watcher; + +- (void)doSimpleStateMachineRPC:(NSString*)name + op:(CKKSResultOperation*)op + sourceStates:(NSSet*)sourceStates + reply:(nonnull void (^)(NSError * _Nullable))reply; + +- (void)doWatchedStateMachineRPC:(NSString*)name + sourceStates:(NSSet*)sourceStates + path:(OctagonStateTransitionPath*)path + reply:(nonnull void (^)(NSError *error))reply; +- (void)setWatcherTimeout:(uint64_t)timeout; +- (BOOL)isPaused; + +// Wait the state `wantedState' for `timeout' ns, if we transition though that state +// return that state, otherwise return a snapshot. No garantee that you still are in that state, +// if you want that, you need to run an RPC. +- (OctagonState* _Nonnull)waitForState:(OctagonState* _Nonnull)wantedState wait:(uint64_t)timeout; + +@end + +NS_ASSUME_NONNULL_END + +#endif diff --git a/keychain/ot/OctagonStateMachine.m b/keychain/ot/OctagonStateMachine.m new file mode 100644 index 00000000..ef550aad --- /dev/null +++ b/keychain/ot/OctagonStateMachine.m @@ -0,0 +1,565 @@ + +#if OCTAGON + +#import "keychain/ot/OctagonStateMachine.h" +#import "keychain/ot/OctagonStateMachineObservers.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ckks/CKKSNearFutureScheduler.h" +#import "keychain/ckks/CKKS.h" + +#import "utilities/debugging.h" + +#define statemachinelog(scope, format, ...) \ +{ \ +os_log(secLogObjForCFScope((__bridge CFStringRef)[NSString stringWithFormat:@"%@-%@", self.name, @(scope)]), \ +format, \ +##__VA_ARGS__); \ +} + +@interface OctagonStateMachine () +{ + OctagonState* _currentState; +} + +@property (weak) id stateEngine; + +@property dispatch_queue_t queue; +@property NSOperationQueue* operationQueue; + +@property NSString* name; + +// Make writable +@property CKKSCondition* paused; +@property OctagonState* currentState; +@property OctagonFlags* currentFlags; + +// Set this to an operation to pause the state machine in-flight +@property NSOperation* holdStateMachineOperation; + +@property (nullable) CKKSResultOperation* nextStateMachineCycleOperation; + +@property NSMutableArray*>*>* stateMachineRequests; +@property NSMutableArray* stateMachineWatchers; + +@property BOOL halted; +@property bool allowPendingFlags; +@property NSMutableDictionary* pendingFlags; +@property CKKSNearFutureScheduler* pendingFlagsScheduler; + +@property OctagonPendingConditions conditionChecksInFlight; +@property OctagonPendingConditions currentConditions; +@property NSOperation* checkUnlockOperation; +@end + +@implementation OctagonStateMachine + +- (instancetype)initWithName:(NSString*)name + states:(NSSet*)possibleStates + initialState:(OctagonState*)initialState + queue:(dispatch_queue_t)queue + stateEngine:(id)stateEngine + lockStateTracker:(CKKSLockStateTracker*)lockStateTracker +{ + if ((self = [super init])) { + _name = name; + + _lockStateTracker = lockStateTracker; + _conditionChecksInFlight = 0; + _currentConditions = 0; + + // Every state machine starts in OctagonStateMachineNotStarted, so help them out a bit. + _allowableStates = [possibleStates setByAddingObjectsFromArray:@[OctagonStateMachineNotStarted, OctagonStateMachineHalted]]; + + _queue = queue; + _operationQueue = [[NSOperationQueue alloc] init]; + _currentFlags = [[OctagonFlags alloc] initWithQueue:queue]; + + _stateEngine = stateEngine; + + _holdStateMachineOperation = [NSBlockOperation blockOperationWithBlock:^{}]; + _halted = false; + + _stateConditions = [[NSMutableDictionary alloc] init]; + [possibleStates enumerateObjectsUsingBlock:^(OctagonState * _Nonnull obj, BOOL * _Nonnull stop) { + self.stateConditions[obj] = [[CKKSCondition alloc] init]; + }]; + + // Use the setter method to set the condition variables + self.currentState = OctagonStateMachineNotStarted; + + _stateMachineRequests = [NSMutableArray array]; + _stateMachineWatchers = [NSMutableArray array]; + + WEAKIFY(self); + _allowPendingFlags = true; + _pendingFlags = [NSMutableDictionary dictionary]; + _pendingFlagsScheduler = [[CKKSNearFutureScheduler alloc] initWithName:[NSString stringWithFormat:@"%@-pending-flag", name] + delay:100*NSEC_PER_MSEC + keepProcessAlive:false + dependencyDescriptionCode:CKKSResultDescriptionPendingFlag + block:^{ + STRONGIFY(self); + dispatch_sync(self.queue, ^{ + [self _onqueueSendAnyPendingFlags]; + }); + }]; + + OctagonStateTransitionOperation* initializeOp = [OctagonStateTransitionOperation named:@"initialize" + entering:initialState]; + [initializeOp addDependency:_holdStateMachineOperation]; + [_operationQueue addOperation:initializeOp]; + + _paused = [[CKKSCondition alloc] init]; + + _nextStateMachineCycleOperation = [self createOperationToFinishAttempt:initializeOp]; + [_operationQueue addOperation:_nextStateMachineCycleOperation]; + } + return self; +} + +- (NSString*)pendingFlagsString +{ + return [self.pendingFlags.allValues componentsJoinedByString:@","]; +} + +- (NSString*)description +{ + NSString* pendingFlags = @""; + if(self.pendingFlags.count != 0) { + pendingFlags = [NSString stringWithFormat:@" (pending: %@)", [self pendingFlagsString]]; + } + return [NSString stringWithFormat:@"", self.name, self.currentState, pendingFlags]; +} + +#pragma mark - Bookkeeping + +- (id)flags { + return self.currentFlags; +} + +- (OctagonState* _Nonnull)currentState { + return _currentState; +} + +- (void)setCurrentState:(OctagonState* _Nonnull)state { + if((state == nil && _currentState == nil) || ([state isEqualToString:_currentState])) { + // No change, do nothing. + } else { + // Fixup the condition variables as part of setting this state + if(_currentState) { + self.stateConditions[_currentState] = [[CKKSCondition alloc] init]; + } + + NSAssert([self.allowableStates containsObject:state], @"state machine tried to enter unknown state %@", state); + _currentState = state; + + if(state) { + [self.stateConditions[state] fulfill]; + } + } +} + +- (OctagonState* _Nonnull)waitForState:(OctagonState* _Nonnull)wantedState wait:(uint64_t)timeout { + if ([self.stateConditions[wantedState] wait:timeout]) { + return _currentState; + } else { + return wantedState; + } +} + +#pragma mark - Machinery + +- (CKKSResultOperation* _Nullable)_onqueueNextStateMachineTransition +{ + dispatch_assert_queue(self.queue); + + if(self.halted) { + if([self.currentState isEqualToString:OctagonStateMachineHalted]) { + return nil; + } else { + return [OctagonStateTransitionOperation named:@"halt" + entering:OctagonStateMachineHalted]; + } + } + + // Check requests: do any of them want to come from this state? + for(OctagonStateTransitionRequest* request in self.stateMachineRequests) { + if([request.sourceStates containsObject:self.currentState]) { + OctagonStateTransitionOperation* attempt = [request _onqueueStart]; + + if(attempt) { + statemachinelog("state", "Running state machine request %@ (from %@)", request, self.currentState); + return attempt; + } + } + } + + // Ask the stateEngine what it would like to do + return [self.stateEngine _onqueueNextStateMachineTransition:self.currentState + flags:self.currentFlags + pendingFlags:self]; +} + +- (void)_onqueueStartNextStateMachineOperation:(bool)immediatelyAfterPreviousOp { + dispatch_assert_queue(self.queue); + + // early-exit if there's an existing operation. That operation will call this function after it's done + if(self.nextStateMachineCycleOperation) { + return; + } + + CKKSResultOperation* nextOp = [self _onqueueNextStateMachineTransition]; + if(nextOp) { + statemachinelog("state", "Beginning state transition attempt %@", nextOp); + + self.nextStateMachineCycleOperation = [self createOperationToFinishAttempt:nextOp]; + [self.operationQueue addOperation:self.nextStateMachineCycleOperation]; + + [nextOp addNullableDependency:self.holdStateMachineOperation]; + nextOp.qualityOfService = NSQualityOfServiceUserInitiated; + [self.operationQueue addOperation:nextOp]; + + if(!immediatelyAfterPreviousOp) { + self.paused = [[CKKSCondition alloc] init]; + } + } else { + statemachinelog("state", "State machine rests (%@, f:[%@] p:[%@])", self.currentState, [self.currentFlags contentsAsString], [self pendingFlagsString]); + [self.paused fulfill]; + } +} + + +- (CKKSResultOperation*)createOperationToFinishAttempt:(CKKSResultOperation*)op +{ + WEAKIFY(self); + + CKKSResultOperation* followUp = [CKKSResultOperation named:@"octagon-state-follow-up" withBlock:^{ + STRONGIFY(self); + + dispatch_sync(self.queue, ^{ + statemachinelog("state", "Finishing state transition attempt (ending in %@, intended: %@, f:[%@], p:[%@]): %@ %@", + op.nextState, + op.intendedState, + [self.currentFlags contentsAsString], + [self pendingFlagsString], + op, + op.error ?: @"(no error)"); + + for(OctagonStateTransitionWatcher* watcher in self.stateMachineWatchers) { + statemachinelog("state", "notifying watcher: %@", watcher); + [watcher onqueueHandleTransition:op]; + } + + // finished watchers can be removed from the list. Use a reversed for loop to enable removal + for (NSInteger i = self.stateMachineWatchers.count - 1; i >= 0; i--) { + if([self.stateMachineWatchers[i].result isFinished]) { + [self.stateMachineWatchers removeObjectAtIndex:i]; + } + } + + self.currentState = op.nextState; + self.nextStateMachineCycleOperation = nil; + + [self _onqueueStartNextStateMachineOperation:true]; + }); + }]; + [followUp addNullableDependency:self.holdStateMachineOperation]; + [followUp addNullableDependency:op]; + followUp.qualityOfService = NSQualityOfServiceUserInitiated; + return followUp; +} + +- (void)pokeStateMachine +{ + dispatch_sync(self.queue, ^{ + [self _onqueuePokeStateMachine]; + }); +} + +- (void)_onqueuePokeStateMachine +{ + dispatch_assert_queue(self.queue); + [self _onqueueStartNextStateMachineOperation:false]; +} + +- (void)handleFlag:(OctagonFlag*)flag +{ + dispatch_sync(self.queue, ^{ + [self.currentFlags _onqueueSetFlag:flag]; + [self _onqueuePokeStateMachine]; + }); +} + +- (void)handlePendingFlag:(OctagonPendingFlag *)pendingFlag { + dispatch_sync(self.queue, ^{ + [self _onqueueHandlePendingFlag:pendingFlag]; + }); +} + +- (void)_onqueueHandlePendingFlag:(OctagonPendingFlag*)pendingFlag { + dispatch_assert_queue(self.queue); + + // Overwrite any existing pending flag! + self.pendingFlags[pendingFlag.flag] = pendingFlag; + + // Do we need to recheck any conditions? Anything which is currently the state of the world needs checking + OctagonPendingConditions recheck = pendingFlag.conditions & self.currentConditions; + if(recheck != 0x0) { + // Technically don't need this if, but it adds readability + self.currentConditions &= ~recheck; + } + + [self _onqueueRecheckConditions]; + [self _onqueueSendAnyPendingFlags]; +} + +- (void)disablePendingFlags { + dispatch_sync(self.queue, ^{ + self.allowPendingFlags = false; + }); +} + +- (NSDictionary*)dumpPendingFlags +{ + __block NSMutableDictionary* d = [NSMutableDictionary dictionary]; + dispatch_sync(self.queue, ^{ + for(OctagonFlag* flag in [self.pendingFlags allKeys]) { + d[flag] = [self.pendingFlags[flag] description];; + } + }); + + return d; +} + +- (NSArray*)possiblePendingFlags +{ + return [self.pendingFlags allKeys]; +} + +- (void)_onqueueRecheckConditions +{ + dispatch_assert_queue(self.queue); + + if(!self.allowPendingFlags) { + return; + } + + NSArray* flags = [self.pendingFlags.allValues copy]; + OctagonPendingConditions allConditions = 0; + for(OctagonPendingFlag* flag in flags) { + allConditions |= flag.conditions; + } + if(allConditions == 0x0) { + // No conditions? Don't bother. + return; + } + + // We need to recheck everything that is not currently the state of the world + OctagonPendingConditions pendingConditions = allConditions & ~(self.currentConditions); + + // But we don't need to recheck anything that's currently being checked + OctagonPendingConditions conditionsToCheck = pendingConditions & ~(self.conditionChecksInFlight); + + WEAKIFY(self); + + if(conditionsToCheck & OctagonPendingConditionsDeviceUnlocked) { + statemachinelog("conditions", "Waiting for unlock"); + self.checkUnlockOperation = [NSBlockOperation blockOperationWithBlock:^{ + STRONGIFY(self); + dispatch_sync(self.queue, ^{ + statemachinelog("pending-flag", "Unlock occurred"); + self.currentConditions |= OctagonPendingConditionsDeviceUnlocked; + self.conditionChecksInFlight &= ~OctagonPendingConditionsDeviceUnlocked; + [self _onqueueSendAnyPendingFlags]; + }); + }]; + self.conditionChecksInFlight |= OctagonPendingConditionsDeviceUnlocked; + + [self.checkUnlockOperation addNullableDependency:self.lockStateTracker.unlockDependency]; + [self.operationQueue addOperation:self.checkUnlockOperation]; + } +} + +- (void)_onqueueSendAnyPendingFlags +{ + dispatch_assert_queue(self.queue); + + if(!self.allowPendingFlags) { + return; + } + + // Copy pending flags so we can edit the list + NSArray* flags = [self.pendingFlags.allValues copy]; + bool setFlag = false; + + NSDate* now = [NSDate date]; + NSDate* earliestDeadline = nil; + for(OctagonPendingFlag* pendingFlag in flags) { + bool send = true; + + if(pendingFlag.fireTime) { + if([pendingFlag.fireTime compare:now] == NSOrderedAscending) { + statemachinelog("pending-flag", "Delay has ended for pending flag %@", pendingFlag.flag); + } else { + send = false; + earliestDeadline = earliestDeadline == nil ? + pendingFlag.fireTime : + [earliestDeadline earlierDate:pendingFlag.fireTime]; + } + } + + if(pendingFlag.conditions != 0x0) { + // Also, send the flag if the conditions are right + if((pendingFlag.conditions & self.currentConditions) == pendingFlag.conditions) { + // leave send alone! + statemachinelog("pending-flag", "Conditions are right for %@", pendingFlag.flag); + } else { + send = false; + } + } + + if(send) { + [self.currentFlags _onqueueSetFlag:pendingFlag.flag]; + self.pendingFlags[pendingFlag.flag] = nil; + setFlag = true; + } + } + + if(earliestDeadline != nil) { + NSTimeInterval delay = [earliestDeadline timeIntervalSinceDate:now]; + uint64_t delayNanoseconds = delay * NSEC_PER_SEC; + + [self.pendingFlagsScheduler triggerAt:delayNanoseconds]; + } + + if(setFlag) { + [self _onqueuePokeStateMachine]; + } +} + +#pragma mark - Client Services + +- (BOOL)isPaused +{ + __block BOOL ret = false; + dispatch_sync(self.queue, ^{ + ret = self.nextStateMachineCycleOperation == nil; + }); + + return ret; +} + +- (void)startOperation { + dispatch_sync(self.queue, ^{ + if(self.holdStateMachineOperation) { + [self.operationQueue addOperation: self.holdStateMachineOperation]; + self.holdStateMachineOperation = nil; + } + }); +} + +- (void)haltOperation +{ + dispatch_sync(self.queue, ^{ + if(self.holdStateMachineOperation) { + [self.operationQueue addOperation:self.holdStateMachineOperation]; + self.holdStateMachineOperation = nil; + } + + self.halted = true; + self.allowPendingFlags = false; + + // Ask the state machine to halt itself + [self _onqueuePokeStateMachine]; + }); + + [self.nextStateMachineCycleOperation waitUntilFinished]; +} + +- (void)handleExternalRequest:(OctagonStateTransitionRequest*>*)request +{ + dispatch_sync(self.queue, ^{ + [self.stateMachineRequests addObject:request]; + [self _onqueuePokeStateMachine]; + }); +} + +- (void)registerStateTransitionWatcher:(OctagonStateTransitionWatcher*)watcher +{ + dispatch_sync(self.queue, ^{ + [self.stateMachineWatchers addObject: watcher]; + [self _onqueuePokeStateMachine]; + }); +} + +#pragma mark - RPC Helpers + +- (void)doSimpleStateMachineRPC:(NSString*)name + op:(CKKSResultOperation*)op + sourceStates:(NSSet*)sourceStates + reply:(nonnull void (^)(NSError * _Nullable))reply +{ + statemachinelog("state-rpc", "Beginning a '%@' rpc", name); + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:name + sourceStates:sourceStates + serialQueue:self.queue + timeout:10*NSEC_PER_SEC + transitionOp:op]; + [self handleExternalRequest:request]; + + WEAKIFY(self); + CKKSResultOperation* callback = [CKKSResultOperation named:[NSString stringWithFormat: @"%@-callback", name] + withBlock:^{ + STRONGIFY(self); + statemachinelog("state-rpc", "Returning '%@' result: %@", name, op.error ?: @"no error"); + reply(op.error); + }]; + [callback addDependency:op]; + [self.operationQueue addOperation: callback]; +} + +- (void)setWatcherTimeout:(uint64_t)timeout +{ + self.timeout = timeout; +} + +- (void)doWatchedStateMachineRPC:(NSString*)name + sourceStates:(NSSet*)sourceStates + path:(OctagonStateTransitionPath*)path + reply:(nonnull void (^)(NSError *error))reply +{ + statemachinelog("state-rpc", "Beginning a '%@' rpc", name); + + OctagonStateTransitionWatcher* watcher = [[OctagonStateTransitionWatcher alloc] initNamed:[NSString stringWithFormat:@"watcher-%@", name] + serialQueue:self.queue + path:path]; + [watcher timeout:self.timeout?:120*NSEC_PER_SEC]; + [self registerStateTransitionWatcher:watcher]; + + WEAKIFY(self); + CKKSResultOperation* replyOp = [CKKSResultOperation named:[NSString stringWithFormat: @"%@-callback", name] + withBlock:^{ + STRONGIFY(self); + statemachinelog("state-rpc", "Returning '%@' result: %@", name, watcher.result.error ?: @"no error"); + reply(watcher.result.error); + }]; + [replyOp addDependency:watcher.result]; + [self.operationQueue addOperation:replyOp]; + + + CKKSResultOperation* initialTransitionOp + = [OctagonStateTransitionOperation named:[NSString stringWithFormat:@"intial-transition-%@", name] + entering:path.initialState]; + + OctagonStateTransitionRequest* request = [[OctagonStateTransitionRequest alloc] init:name + sourceStates:sourceStates + serialQueue:self.queue + timeout:10*NSEC_PER_SEC + transitionOp:initialTransitionOp]; + [self handleExternalRequest:request]; +} + +@end + +#endif diff --git a/keychain/ot/OctagonStateMachineHelpers.h b/keychain/ot/OctagonStateMachineHelpers.h new file mode 100644 index 00000000..aa2fc920 --- /dev/null +++ b/keychain/ot/OctagonStateMachineHelpers.h @@ -0,0 +1,88 @@ +/* + * 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 "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ckks/CKKSAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +@protocol OctagonStateString +@end +typedef NSString OctagonState; + +@protocol OctagonFlagString +@end +typedef NSString OctagonFlag; + +// NotStarted indicates that this state machine is not yet started +extern OctagonState* const OctagonStateMachineNotStarted; + +// Halted indicates that the state machine is halted, and won't move again +extern OctagonState* const OctagonStateMachineHalted; + +@protocol OctagonStateTransitionOperationProtocol +// Holds this operation's opinion of the next state, given that this operation just ran +@property OctagonState* nextState; + +// Hold the state this operation was originally hoping to enter +@property (readonly) OctagonState* intendedState; +@end + + +@interface OctagonStateTransitionOperation : CKKSResultOperation +@property OctagonState* nextState; +@property (readonly) OctagonState* intendedState; + ++ (instancetype)named:(NSString*)name + intending:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + timeout:(dispatch_time_t)timeout + withBlockTakingSelf:(void(^)(OctagonStateTransitionOperation* op))block; + +// convenience constructor. Will always succeed at entering the state. ++ (instancetype)named:(NSString*)name + entering:(OctagonState*)intendedState; +@end + + +@interface OctagonStateTransitionRequest<__covariant OperationType : CKKSResultOperation*> : NSObject +@property (readonly) NSString* name; +@property (readonly) NSSet* sourceStates; +@property (readonly) OperationType transitionOperation; + +- (instancetype)timeout:(dispatch_time_t)timeout; +- (OperationType _Nullable)_onqueueStart; + +- (instancetype)init:(NSString*)name + sourceStates:(NSSet*)sourceStates + serialQueue:(dispatch_queue_t)queue + timeout:(dispatch_time_t)timeout + transitionOp:(OperationType)transitionOp; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OctagonStateMachineHelpers.m b/keychain/ot/OctagonStateMachineHelpers.m new file mode 100644 index 00000000..1ebd4cb9 --- /dev/null +++ b/keychain/ot/OctagonStateMachineHelpers.m @@ -0,0 +1,142 @@ +/* + * 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 "keychain/ot/OTStates.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +OctagonState* const OctagonStateMachineNotStarted = (OctagonState*) @"not_started"; +OctagonState* const OctagonStateMachineHalted = (OctagonState*) @"halted"; + +@implementation OctagonStateTransitionOperation : CKKSResultOperation +- (instancetype)initIntending:(OctagonState*)intendedState + errorState:(OctagonState*)errorState +{ + if((self = [super init])) { + _nextState = errorState; + _intendedState = intendedState; + } + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.name, self.intendedState, self.nextState]; +} + ++ (instancetype)named:(NSString*)name + intending:(OctagonState*)intendedState + errorState:(OctagonState*)errorState + timeout:(dispatch_time_t)timeout + withBlockTakingSelf:(void(^)(OctagonStateTransitionOperation* op))block +{ + OctagonStateTransitionOperation* op = [[self alloc] initIntending:intendedState + errorState:errorState]; + WEAKIFY(op); + [op addExecutionBlock:^{ + STRONGIFY(op); + block(op); + }]; + op.name = name; + [op timeout:timeout]; + return op; +} + ++ (instancetype)named:(NSString*)name + entering:(OctagonState*)intendedState +{ + OctagonStateTransitionOperation* op = [[self alloc] initIntending:intendedState + errorState:intendedState]; + op.name = name; + return op; +} +@end + +@interface OctagonStateTransitionRequest () +@property dispatch_queue_t queue; +@property bool timeoutCanOccur; +@end + +@implementation OctagonStateTransitionRequest + +- (instancetype)init:(NSString*)name + sourceStates:(NSSet*)sourceStates + serialQueue:(dispatch_queue_t)queue + timeout:(dispatch_time_t)timeout + transitionOp:(CKKSResultOperation*)transitionOp +{ + if((self = [super init])) { + _name = name; + _sourceStates = sourceStates; + _queue = queue; + + _timeoutCanOccur = true; + _transitionOperation = transitionOp; + } + + [self timeout:timeout]; + + return self; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.name, self.transitionOperation, self.sourceStates]; +} + +- (CKKSResultOperation* _Nullable)_onqueueStart +{ + dispatch_assert_queue(self.queue); + + if(self.timeoutCanOccur) { + self.timeoutCanOccur = false; + return self.transitionOperation; + } else { + return nil; + } +} + +- (instancetype)timeout:(dispatch_time_t)timeout +{ + WEAKIFY(self); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeout), self.queue, ^{ + STRONGIFY(self); + if(self.timeoutCanOccur) { + self.timeoutCanOccur = false; + + // The operation will only realize it's finished once added to any operation queue. Fake one up. + [self.transitionOperation timeout:0*NSEC_PER_SEC]; + [[[NSOperationQueue alloc] init] addOperation:self.transitionOperation]; + } + }); + + return self; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/OctagonStateMachineObservers.h b/keychain/ot/OctagonStateMachineObservers.h new file mode 100644 index 00000000..17094bd0 --- /dev/null +++ b/keychain/ot/OctagonStateMachineObservers.h @@ -0,0 +1,63 @@ + +#if OCTAGON + +#import +#import "keychain/ckks/CKKSResultOperation.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ot/OctagonStateMachineHelpers.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OctagonStateTransitionPathStep : NSObject +@property BOOL successState; +@property (readonly) NSDictionary* followStates; + +- (instancetype)initAsSuccess; +- (instancetype)initWithPath:(NSDictionary*)followStates; + +- (BOOL)successState; + ++ (OctagonStateTransitionPathStep*)success; + +// Dict should be a map of states to either: +// 1. A dictionary matching this specifiction +// 2. an OctagonStateTransitionPathStep object (which is likely a success object, but doesn't have to be) +// Any other object will be ignored. A malformed dictionary will be converted into an empty success path. ++ (OctagonStateTransitionPathStep*)pathFromDictionary:(NSDictionary*)pathDict; +@end + + +@interface OctagonStateTransitionPath : NSObject +@property OctagonState* initialState; +@property OctagonStateTransitionPathStep* pathStep; + +- (instancetype)initWithState:(OctagonState*)initialState + pathStep:(OctagonStateTransitionPathStep*)pathSteps; + +- (OctagonStateTransitionPathStep*)asPathStep; + +// Uses the same rules as OctagonStateTransitionPathStep pathFromDictionary, but selects one of the top-level dictionary keys +// to be the path initialization state. Not well defined if you pass in two keys in the top-level dictionary. +// If the dictionary has no keys in it, returns nil. ++ (OctagonStateTransitionPath* _Nullable)pathFromDictionary:(NSDictionary*)pathDict; + +@end + + +@interface OctagonStateTransitionWatcher : NSObject +@property (readonly) NSString* name; +@property (readonly) CKKSResultOperation* result; +@property (readonly) OctagonStateTransitionPath* intendedPath; + +- (instancetype)initNamed:(NSString*)name + serialQueue:(dispatch_queue_t)queue + path:(OctagonStateTransitionPath*)path; + +- (instancetype)timeout:(dispatch_time_t)timeout; + +- (void)onqueueHandleTransition:(CKKSResultOperation*)attempt; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/OctagonStateMachineObservers.m b/keychain/ot/OctagonStateMachineObservers.m new file mode 100644 index 00000000..b770f8f3 --- /dev/null +++ b/keychain/ot/OctagonStateMachineObservers.m @@ -0,0 +1,239 @@ +#if OCTAGON + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/ObjCImprovements.h" +#import "keychain/ot/OctagonStateMachineObservers.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" + +@implementation OctagonStateTransitionPathStep + +- (instancetype)initAsSuccess +{ + if((self = [super init])) { + _successState = YES; + _followStates = @{}; + } + return self; +} +- (instancetype)initWithPath:(NSDictionary*)followStates +{ + if((self = [super init])) { + _successState = NO; + _followStates = followStates; + } + return self; +} + +- (OctagonStateTransitionPathStep*)nextStep:(OctagonState*)stateStep +{ + // If stateStep matches a followState, return it. Otherwise, return nil. + return self.followStates[stateStep]; +} + +- (NSString*)description +{ + return [NSString stringWithFormat:@"", self.followStates.allKeys]; +} + ++ (OctagonStateTransitionPathStep*)success +{ + return [[OctagonStateTransitionPathStep alloc] initAsSuccess]; +} + ++ (OctagonStateTransitionPathStep*)pathFromDictionary:(NSDictionary*)pathDict +{ + NSMutableDictionary* converted = [NSMutableDictionary dictionary]; + for(id key in pathDict.allKeys) { + id obj = pathDict[key]; + + if([obj isKindOfClass:[OctagonStateTransitionPathStep class]]) { + converted[key] = obj; + } else if([obj isKindOfClass:[NSDictionary class]]) { + converted[key] = [OctagonStateTransitionPathStep pathFromDictionary:(NSDictionary*)obj]; + } + } + + if([converted count] == 0) { + return [[OctagonStateTransitionPathStep alloc] initAsSuccess]; + } + + return [[OctagonStateTransitionPathStep alloc] initWithPath:converted]; +} +@end + +#pragma mark - OctagonStateTransitionPath + +@implementation OctagonStateTransitionPath +- (instancetype)initWithState:(OctagonState*)initialState + pathStep:(OctagonStateTransitionPathStep*)pathStep +{ + if((self = [super init])) { + _initialState = initialState; + _pathStep = pathStep; + } + return self; +} + +- (OctagonStateTransitionPathStep*)asPathStep +{ + return [[OctagonStateTransitionPathStep alloc] initWithPath:@{ + self.initialState: self.pathStep, + }]; +} + ++ (OctagonStateTransitionPath* _Nullable)pathFromDictionary:(NSDictionary*)pathDict +{ + for(id key in pathDict.allKeys) { + id obj = pathDict[key]; + + if([obj isKindOfClass:[OctagonStateTransitionPathStep class]]) { + return [[OctagonStateTransitionPath alloc] initWithState:key + pathStep:obj]; + } else if([obj isKindOfClass:[NSDictionary class]]) { + return [[OctagonStateTransitionPath alloc] initWithState:key + pathStep:[OctagonStateTransitionPathStep pathFromDictionary:obj]]; + } + } + return nil; +} +@end + + +#pragma mark - OctagonStateTransitionWatcher + +@interface OctagonStateTransitionWatcher () +@property BOOL active; +@property BOOL completed; +@property (nullable) OctagonStateTransitionPathStep* remainingPath; +@property NSOperationQueue* operationQueue; +@property bool timeoutCanOccur; +@property dispatch_queue_t queue; +@end + +@implementation OctagonStateTransitionWatcher + +- (instancetype)initNamed:(NSString*)name + serialQueue:(dispatch_queue_t)queue + path:(OctagonStateTransitionPath*)pathBeginning +{ + if((self = [super init])) { + _name = name; + _intendedPath = pathBeginning; + _remainingPath = [pathBeginning asPathStep]; + + _result = [CKKSResultOperation named:[NSString stringWithFormat:@"watcher-%@", name] withBlock:^{}]; + _operationQueue = [[NSOperationQueue alloc] init]; + + _queue = queue; + + _timeoutCanOccur = true; + + _active = NO; + _completed = NO; + } + return self; +} + +- (NSString*)description { + return [NSString stringWithFormat:@"", + self.name, + self.remainingPath, + self.result]; +} + +- (void)onqueueHandleTransition:(CKKSResultOperation*)attempt +{ + dispatch_assert_queue(self.queue); + + // Early-exit to make error handling better + if(self.remainingPath == nil || self.completed) { + return; + } + + if(self.active) { + [self onqueueProcessTransition:attempt]; + + } else { + if([attempt.nextState isEqualToString:self.intendedPath.initialState]) { + self.active = YES; + [self onqueueProcessTransition:attempt]; + } + } +} + +- (instancetype)timeout:(dispatch_time_t)timeout +{ + WEAKIFY(self); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, timeout), self.queue, ^{ + STRONGIFY(self); + if(self.timeoutCanOccur) { + self.timeoutCanOccur = false; + + NSString* description = [NSString stringWithFormat:@"Operation(%@) timed out waiting to start for [%@]", + self.name, + self.remainingPath]; + + self.result.error = [NSError errorWithDomain:CKKSResultErrorDomain + code:CKKSResultTimedOut + description:description + underlying:nil]; + [self onqueueStartFinishOperation]; + + } + }); + + return self; +} + +- (void)onqueueProcessTransition:(CKKSResultOperation*)attempt +{ + dispatch_assert_queue(self.queue); + + if(self.remainingPath == nil || self.completed) { + return; + } + + + OctagonStateTransitionPathStep* nextPath = [self.remainingPath nextStep:attempt.nextState]; + + if(nextPath) { + self.remainingPath = nextPath; + if(self.remainingPath.successState) { + // We're done! + [self onqueueStartFinishOperation]; + } + + } else { + // We're off the path. Error and finish. + if(attempt.error) { + self.result.error = attempt.error; + } else { + self.result.error = [NSError errorWithDomain:OctagonErrorDomain + code:OTErrorUnexpectedStateTransition + description:[NSString stringWithFormat:@"state became %@, was expecting %@", attempt.nextState, self.remainingPath]]; + } + [[CKKSAnalytics logger] logUnrecoverableError:self.result.error + forEvent:OctagonEventStateTransition + withAttributes:@{ + @"name" : self.name, + @"intended": [self.remainingPath.followStates allKeys], + @"became" : attempt.nextState, + }]; + + [self onqueueStartFinishOperation]; + } +} + +- (void)onqueueStartFinishOperation { + dispatch_assert_queue(self.queue); + + self.timeoutCanOccur = false; + [self.operationQueue addOperation:self.result]; + self.active = false; + self.completed = TRUE; +} + +@end + +#endif diff --git a/keychain/ot/SFECPublicKey+SPKI.m b/keychain/ot/SFECPublicKey+SPKI.m deleted file mode 100644 index 91531dc3..00000000 --- a/keychain/ot/SFECPublicKey+SPKI.m +++ /dev/null @@ -1,53 +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 OCTAGON - -#import "SFPublicKey+SPKI.h" - -#import -#import - -@implementation SFECPublicKey (OTSubjectPublicKeyInfo) - -- (NSData *)asSPKI -{ - NSDictionary *keyAttributes = @{ - (__bridge id)kSecAttrKeyClass : (__bridge id)kSecAttrKeyClassPublic, - (__bridge id)kSecAttrKeyType : (__bridge id)kSecAttrKeyTypeEC, - }; - SecKeyRef seckey = SecKeyCreateWithData((__bridge CFDataRef)self.keyData, (__bridge CFDictionaryRef)keyAttributes, NULL); - NSData *spki = CFBridgingRelease(SecKeyCopySubjectPublicKeyInfo(seckey)); - CFRelease(seckey); - return spki; -} - -+ (instancetype)fromSPKI:(NSData *)spki -{ - SecKeyRef seckey = SecKeyCreateFromSubjectPublicKeyInfoData(NULL, (__bridge CFDataRef)spki); - return [[SFECPublicKey alloc] initWithSecKey:seckey]; -} - -@end - -#endif diff --git a/keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h b/keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h new file mode 100644 index 00000000..4278b499 --- /dev/null +++ b/keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h @@ -0,0 +1,20 @@ + +#if OCTAGON + +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface OTAccountMetadataClassC (KeychainSupport) + +- (BOOL)saveToKeychainForContainer:(NSString*)containerName contextID:(NSString*)contextID error:(NSError**)error; + ++ (BOOL) deleteFromKeychainForContainer:(NSString*)containerName + contextID:(NSString*)contextID error:(NSError**)error __attribute__((swift_error(nonnull_error))); + ++ (OTAccountMetadataClassC* _Nullable)loadFromKeychainForContainer:(NSString*)containerName contextID:(NSString*)contextID error:(NSError**)error; +@end + +NS_ASSUME_NONNULL_END + +#endif // OCTAGON diff --git a/keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.m b/keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.m new file mode 100644 index 00000000..68f33b21 --- /dev/null +++ b/keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.m @@ -0,0 +1,163 @@ + +#if OCTAGON + +#import +#import +#import "OSX/sec/Security/SecItemShim.h" + +#import "OSX/utilities/SecCFRelease.h" + +#import "OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTConstants.h" + +@implementation OTAccountMetadataClassC (KeychainSupport) + + +- (BOOL)saveToKeychainForContainer:(NSString*)containerName + contextID:(NSString*)contextID + error:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.octagon", + (id)kSecAttrDescription: [NSString stringWithFormat:@"Octagon Account State (%@,%@)", containerName, contextID], + (id)kSecAttrServer: [NSString stringWithFormat:@"octagon-%@", containerName], + (id)kSecAttrAccount: [NSString stringWithFormat:@"octagon-%@", containerName], // Really should be alt-DSID, no? + (id)kSecAttrPath: [NSString stringWithFormat:@"octagon-%@", contextID], + (id)kSecAttrIsInvisible: @YES, + (id)kSecValueData : self.data, + (id)kSecAttrSynchronizable : @NO, + (id)kSecAttrSysBound : @(kSecSecAttrSysBoundPreserveDuringRestore), + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &result); + + NSError* localerror = nil; + + // Did SecItemAdd fall over due to an existing item? + if(status == errSecDuplicateItem) { + // Add every primary key attribute to this find dictionary + NSMutableDictionary* findQuery = [[NSMutableDictionary alloc] init]; + findQuery[(id)kSecClass] = query[(id)kSecClass]; + findQuery[(id)kSecAttrSynchronizable] = query[(id)kSecAttrSynchronizable]; + findQuery[(id)kSecAttrSyncViewHint] = query[(id)kSecAttrSyncViewHint]; + findQuery[(id)kSecAttrAccessGroup] = query[(id)kSecAttrAccessGroup]; + findQuery[(id)kSecAttrAccount] = query[(id)kSecAttrAccount]; + findQuery[(id)kSecAttrServer] = query[(id)kSecAttrServer]; + findQuery[(id)kSecAttrPath] = query[(id)kSecAttrPath]; + findQuery[(id)kSecUseDataProtectionKeychain] = query[(id)kSecUseDataProtectionKeychain]; + + NSMutableDictionary* updateQuery = [query mutableCopy]; + updateQuery[(id)kSecClass] = nil; + + status = SecItemUpdate((__bridge CFDictionaryRef)findQuery, (__bridge CFDictionaryRef)updateQuery); + + if(status) { + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemUpdate: %d", (int)status]]; + } + } else if(status != 0) { + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description: [NSString stringWithFormat:@"SecItemAdd: %d", (int)status]]; + } + + if(localerror) { + if(error) { + *error = localerror; + } + return false; + } else { + return true; + } +} + ++ (BOOL) deleteFromKeychainForContainer:(NSString*)containerName + contextID:(NSString*)contextID error:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.octagon", + (id)kSecAttrServer: [NSString stringWithFormat:@"octagon-%@", containerName], + (id)kSecAttrAccount: [NSString stringWithFormat:@"octagon-%@", containerName], + (id)kSecAttrPath: [NSString stringWithFormat:@"octagon-%@", contextID], + (id)kSecAttrSynchronizable : @NO, + } mutableCopy]; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + if(status) { + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + userInfo:@{NSLocalizedDescriptionKey: + [NSString stringWithFormat:@"SecItemDelete: %d", (int)status]}]; + } + return NO; + } + return YES; +} + ++ (OTAccountMetadataClassC* _Nullable)loadFromKeychainForContainer:(NSString*)containerName + contextID:(NSString*)contextID error:(NSError**)error +{ + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.octagon", + (id)kSecAttrServer: [NSString stringWithFormat:@"octagon-%@", containerName], + (id)kSecAttrAccount: [NSString stringWithFormat:@"octagon-%@", containerName], + (id)kSecAttrPath: [NSString stringWithFormat:@"octagon-%@", contextID], + (id)kSecAttrSynchronizable : @NO, + (id)kSecReturnAttributes: @YES, + (id)kSecReturnData: @YES, + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + + if(status) { + CFReleaseNull(result); + + if(error) { + *error = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + userInfo:@{NSLocalizedDescriptionKey: + [NSString stringWithFormat:@"SecItemCopyMatching: %d", (int)status]}]; + } + return nil; + } + + NSDictionary* resultDict = CFBridgingRelease(result); + + OTAccountMetadataClassC* state = [[OTAccountMetadataClassC alloc] initWithData:resultDict[(id)kSecValueData]]; + if(!state) { + if(error) { + *error = [NSError errorWithDomain:OctagonErrorDomain code:OTErrorDeserializationFailure description:@"couldn't deserialize account state"]; + } + NSError* deleteError = nil; + BOOL deleted = [OTAccountMetadataClassC deleteFromKeychainForContainer:containerName contextID:contextID error:&deleteError]; + if(deleted == NO || deleteError) { + secnotice("octagon", "failed to reset account metadata in keychain, %@", deleteError); + } + return nil; + } + + //check if an account state has the appropriate attributes + if(resultDict[(id)kSecAttrSysBound] == nil || ![resultDict[(id)kSecAttrAccessible] isEqualToString:(id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly]){ + [state saveToKeychainForContainer:containerName contextID:contextID error:error]; + } + + return state; +} + +@end + +#endif // OCTAGON diff --git a/keychain/ot/categories/OctagonEscrowRecoverer.h b/keychain/ot/categories/OctagonEscrowRecoverer.h new file mode 100644 index 00000000..3943683f --- /dev/null +++ b/keychain/ot/categories/OctagonEscrowRecoverer.h @@ -0,0 +1,18 @@ + +#if OCTAGON + +#ifndef OctagonEscrowRecoverer_h +#define OctagonEscrowRecoverer_h + +#import + +@protocol OctagonEscrowRecovererPrococol +- (NSError*)recoverWithInfo:(NSDictionary*)info results:(NSDictionary**)results; +@end + +@interface SecureBackup (OctagonProtocolConformance) +@end + +#endif /* OctagonEscrowRecoverer_h */ + +#endif // OCTAGON diff --git a/keychain/ot/proto/OTAccountMetadataClassC.proto b/keychain/ot/proto/OTAccountMetadataClassC.proto new file mode 100644 index 00000000..a3f0379f --- /dev/null +++ b/keychain/ot/proto/OTAccountMetadataClassC.proto @@ -0,0 +1,46 @@ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +message AccountMetadataClassC { + + // The state of accounts on the system is complicated. Here's how we handle them: + // If there is no account, we will be in NO_ACCOUNT and have no altDSID + // If there is an SA account, we will bt in NO_ACCOUNT and have an altDSID + // If there is an HSA2 account, we will be in ACCOUNT_AVAILABLE and have an altDSID + + enum AccountState { + UNKNOWN = 0; + NO_ACCOUNT = 1; + ACCOUNT_AVAILABLE = 2; + ACCOUNT_AVAILABLE_UNUSED = 3; + } + + enum TrustState { + UNKNOWN = 0; + UNTRUSTED = 1; + TRUSTED = 2; + } + + enum AttemptedAJoinState { + UNKNOWN = 0; + NOTATTEMPTED = 1; + ATTEMPTED = 2; + } + + optional string peerID = 1; + optional AccountState icloudAccountState = 2; + optional int64 epoch = 3; + optional string altDSID = 4; + + optional TrustState trustState = 5; + + // Holds the time, in milliseconds since 1970, that the last health checkup query to Cuttlefish was successfully performed + optional uint64 lastHealthCheckup = 6; + + optional AttemptedAJoinState attemptedJoin = 7; +} diff --git a/keychain/ot/proto/OTPairingMessage.proto b/keychain/ot/proto/OTPairingMessage.proto new file mode 100644 index 00000000..c6b68a56 --- /dev/null +++ b/keychain/ot/proto/OTPairingMessage.proto @@ -0,0 +1,61 @@ +/* + * 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@ + */ + +syntax = "proto2"; + +option objc_class_naming = "extended"; +option objc_class_visibility = "hidden"; + +package OT; + +message SOSMessage { + optional bytes credential = 1; + optional bytes peerInfo = 2; + optional bytes circleBlob = 3; + optional bytes initialSyncItems = 4; +} + +message SponsorToApplicantRound1M2{ + optional uint64 epoch = 1; +} + +message ApplicantToSponsorRound2M1 { + optional string peerID = 1; + optional bytes permanentInfo = 2; + optional bytes permanentInfoSig = 3; + optional bytes stableInfo = 4; + optional bytes StableInfoSig = 5; +} + +message SponsorToApplicantRound2M2{ + optional bytes voucher = 1; + optional bytes voucherSignature = 2; + repeated bytes preapprovedKeys = 3; +} + +message PairingMessage { + optional SponsorToApplicantRound1M2 epoch= 1; + optional ApplicantToSponsorRound2M1 prepare = 2; + optional SponsorToApplicantRound2M2 voucher = 3; + optional SOSMessage sosPairingMessage = 4; +} diff --git a/keychain/ot/proto/generated_source/OTAccountMetadataClassC.h b/keychain/ot/proto/generated_source/OTAccountMetadataClassC.h new file mode 100644 index 00000000..aeef0ac0 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTAccountMetadataClassC.h @@ -0,0 +1,162 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTAccountMetadataClassC.proto + +#import +#import + +/** + * The state of accounts on the system is complicated. Here's how we handle them: + * If there is no account, we will be in NO_ACCOUNT and have no altDSID + * If there is an SA account, we will bt in NO_ACCOUNT and have an altDSID + * If there is an HSA2 account, we will be in ACCOUNT_AVAILABLE and have an altDSID + */ +typedef NS_ENUM(int32_t, OTAccountMetadataClassC_AccountState) { + OTAccountMetadataClassC_AccountState_UNKNOWN = 0, + OTAccountMetadataClassC_AccountState_NO_ACCOUNT = 1, + OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE = 2, + OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE_UNUSED = 3, +}; +#ifdef __OBJC__ +NS_INLINE NSString *OTAccountMetadataClassC_AccountStateAsString(OTAccountMetadataClassC_AccountState value) +{ + switch (value) + { + case OTAccountMetadataClassC_AccountState_UNKNOWN: return @"UNKNOWN"; + case OTAccountMetadataClassC_AccountState_NO_ACCOUNT: return @"NO_ACCOUNT"; + case OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE: return @"ACCOUNT_AVAILABLE"; + case OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE_UNUSED: return @"ACCOUNT_AVAILABLE_UNUSED"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE OTAccountMetadataClassC_AccountState StringAsOTAccountMetadataClassC_AccountState(NSString *value) +{ + if ([value isEqualToString:@"UNKNOWN"]) return OTAccountMetadataClassC_AccountState_UNKNOWN; + if ([value isEqualToString:@"NO_ACCOUNT"]) return OTAccountMetadataClassC_AccountState_NO_ACCOUNT; + if ([value isEqualToString:@"ACCOUNT_AVAILABLE"]) return OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE; + if ([value isEqualToString:@"ACCOUNT_AVAILABLE_UNUSED"]) return OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE_UNUSED; + return OTAccountMetadataClassC_AccountState_UNKNOWN; +} +#endif /* __OBJC__ */ +typedef NS_ENUM(int32_t, OTAccountMetadataClassC_TrustState) { + OTAccountMetadataClassC_TrustState_UNKNOWN = 0, + OTAccountMetadataClassC_TrustState_UNTRUSTED = 1, + OTAccountMetadataClassC_TrustState_TRUSTED = 2, +}; +#ifdef __OBJC__ +NS_INLINE NSString *OTAccountMetadataClassC_TrustStateAsString(OTAccountMetadataClassC_TrustState value) +{ + switch (value) + { + case OTAccountMetadataClassC_TrustState_UNKNOWN: return @"UNKNOWN"; + case OTAccountMetadataClassC_TrustState_UNTRUSTED: return @"UNTRUSTED"; + case OTAccountMetadataClassC_TrustState_TRUSTED: return @"TRUSTED"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE OTAccountMetadataClassC_TrustState StringAsOTAccountMetadataClassC_TrustState(NSString *value) +{ + if ([value isEqualToString:@"UNKNOWN"]) return OTAccountMetadataClassC_TrustState_UNKNOWN; + if ([value isEqualToString:@"UNTRUSTED"]) return OTAccountMetadataClassC_TrustState_UNTRUSTED; + if ([value isEqualToString:@"TRUSTED"]) return OTAccountMetadataClassC_TrustState_TRUSTED; + return OTAccountMetadataClassC_TrustState_UNKNOWN; +} +#endif /* __OBJC__ */ +typedef NS_ENUM(int32_t, OTAccountMetadataClassC_AttemptedAJoinState) { + OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN = 0, + OTAccountMetadataClassC_AttemptedAJoinState_NOTATTEMPTED = 1, + OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED = 2, +}; +#ifdef __OBJC__ +NS_INLINE NSString *OTAccountMetadataClassC_AttemptedAJoinStateAsString(OTAccountMetadataClassC_AttemptedAJoinState value) +{ + switch (value) + { + case OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN: return @"UNKNOWN"; + case OTAccountMetadataClassC_AttemptedAJoinState_NOTATTEMPTED: return @"NOTATTEMPTED"; + case OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED: return @"ATTEMPTED"; + default: return [NSString stringWithFormat:@"(unknown: %i)", value]; + } +} +#endif /* __OBJC__ */ +#ifdef __OBJC__ +NS_INLINE OTAccountMetadataClassC_AttemptedAJoinState StringAsOTAccountMetadataClassC_AttemptedAJoinState(NSString *value) +{ + if ([value isEqualToString:@"UNKNOWN"]) return OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN; + if ([value isEqualToString:@"NOTATTEMPTED"]) return OTAccountMetadataClassC_AttemptedAJoinState_NOTATTEMPTED; + if ([value isEqualToString:@"ATTEMPTED"]) return OTAccountMetadataClassC_AttemptedAJoinState_ATTEMPTED; + return OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN; +} +#endif /* __OBJC__ */ + +#ifdef __cplusplus +#define OTACCOUNTMETADATACLASSC_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTACCOUNTMETADATACLASSC_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTAccountMetadataClassC : PBCodable +{ + int64_t _epoch; + uint64_t _lastHealthCheckup; + NSString *_altDSID; + OTAccountMetadataClassC_AttemptedAJoinState _attemptedJoin; + OTAccountMetadataClassC_AccountState _icloudAccountState; + NSString *_peerID; + OTAccountMetadataClassC_TrustState _trustState; + struct { + int epoch:1; + int lastHealthCheckup:1; + int attemptedJoin:1; + int icloudAccountState:1; + int trustState:1; + } _has; +} + + +@property (nonatomic, readonly) BOOL hasPeerID; +@property (nonatomic, retain) NSString *peerID; + +@property (nonatomic) BOOL hasIcloudAccountState; +@property (nonatomic) OTAccountMetadataClassC_AccountState icloudAccountState; +- (NSString *)icloudAccountStateAsString:(OTAccountMetadataClassC_AccountState)value; +- (OTAccountMetadataClassC_AccountState)StringAsIcloudAccountState:(NSString *)str; + +@property (nonatomic) BOOL hasEpoch; +@property (nonatomic) int64_t epoch; + +@property (nonatomic, readonly) BOOL hasAltDSID; +@property (nonatomic, retain) NSString *altDSID; + +@property (nonatomic) BOOL hasTrustState; +@property (nonatomic) OTAccountMetadataClassC_TrustState trustState; +- (NSString *)trustStateAsString:(OTAccountMetadataClassC_TrustState)value; +- (OTAccountMetadataClassC_TrustState)StringAsTrustState:(NSString *)str; + +@property (nonatomic) BOOL hasLastHealthCheckup; +/** Holds the time, in milliseconds since 1970, that the last health checkup query to Cuttlefish was successfully performed */ +@property (nonatomic) uint64_t lastHealthCheckup; + +@property (nonatomic) BOOL hasAttemptedJoin; +@property (nonatomic) OTAccountMetadataClassC_AttemptedAJoinState attemptedJoin; +- (NSString *)attemptedJoinAsString:(OTAccountMetadataClassC_AttemptedAJoinState)value; +- (OTAccountMetadataClassC_AttemptedAJoinState)StringAsAttemptedJoin:(NSString *)str; + +// Performs a shallow copy into other +- (void)copyTo:(OTAccountMetadataClassC *)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:(OTAccountMetadataClassC *)other; + +OTACCOUNTMETADATACLASSC_FUNCTION BOOL OTAccountMetadataClassCReadFrom(__unsafe_unretained OTAccountMetadataClassC *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/generated_source/OTAccountMetadataClassC.m b/keychain/ot/proto/generated_source/OTAccountMetadataClassC.m new file mode 100644 index 00000000..c7e41deb --- /dev/null +++ b/keychain/ot/proto/generated_source/OTAccountMetadataClassC.m @@ -0,0 +1,445 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTAccountMetadataClassC.proto + +#import "OTAccountMetadataClassC.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 OTAccountMetadataClassC + +- (BOOL)hasPeerID +{ + return _peerID != nil; +} +@synthesize peerID = _peerID; +@synthesize icloudAccountState = _icloudAccountState; +- (OTAccountMetadataClassC_AccountState)icloudAccountState +{ + return _has.icloudAccountState ? _icloudAccountState : OTAccountMetadataClassC_AccountState_UNKNOWN; +} +- (void)setIcloudAccountState:(OTAccountMetadataClassC_AccountState)v +{ + _has.icloudAccountState = YES; + _icloudAccountState = v; +} +- (void)setHasIcloudAccountState:(BOOL)f +{ + _has.icloudAccountState = f; +} +- (BOOL)hasIcloudAccountState +{ + return _has.icloudAccountState; +} +- (NSString *)icloudAccountStateAsString:(OTAccountMetadataClassC_AccountState)value +{ + return OTAccountMetadataClassC_AccountStateAsString(value); +} +- (OTAccountMetadataClassC_AccountState)StringAsIcloudAccountState:(NSString *)str +{ + return StringAsOTAccountMetadataClassC_AccountState(str); +} +@synthesize epoch = _epoch; +- (void)setEpoch:(int64_t)v +{ + _has.epoch = YES; + _epoch = v; +} +- (void)setHasEpoch:(BOOL)f +{ + _has.epoch = f; +} +- (BOOL)hasEpoch +{ + return _has.epoch; +} +- (BOOL)hasAltDSID +{ + return _altDSID != nil; +} +@synthesize altDSID = _altDSID; +@synthesize trustState = _trustState; +- (OTAccountMetadataClassC_TrustState)trustState +{ + return _has.trustState ? _trustState : OTAccountMetadataClassC_TrustState_UNKNOWN; +} +- (void)setTrustState:(OTAccountMetadataClassC_TrustState)v +{ + _has.trustState = YES; + _trustState = v; +} +- (void)setHasTrustState:(BOOL)f +{ + _has.trustState = f; +} +- (BOOL)hasTrustState +{ + return _has.trustState; +} +- (NSString *)trustStateAsString:(OTAccountMetadataClassC_TrustState)value +{ + return OTAccountMetadataClassC_TrustStateAsString(value); +} +- (OTAccountMetadataClassC_TrustState)StringAsTrustState:(NSString *)str +{ + return StringAsOTAccountMetadataClassC_TrustState(str); +} +@synthesize lastHealthCheckup = _lastHealthCheckup; +- (void)setLastHealthCheckup:(uint64_t)v +{ + _has.lastHealthCheckup = YES; + _lastHealthCheckup = v; +} +- (void)setHasLastHealthCheckup:(BOOL)f +{ + _has.lastHealthCheckup = f; +} +- (BOOL)hasLastHealthCheckup +{ + return _has.lastHealthCheckup; +} +@synthesize attemptedJoin = _attemptedJoin; +- (OTAccountMetadataClassC_AttemptedAJoinState)attemptedJoin +{ + return _has.attemptedJoin ? _attemptedJoin : OTAccountMetadataClassC_AttemptedAJoinState_UNKNOWN; +} +- (void)setAttemptedJoin:(OTAccountMetadataClassC_AttemptedAJoinState)v +{ + _has.attemptedJoin = YES; + _attemptedJoin = v; +} +- (void)setHasAttemptedJoin:(BOOL)f +{ + _has.attemptedJoin = f; +} +- (BOOL)hasAttemptedJoin +{ + return _has.attemptedJoin; +} +- (NSString *)attemptedJoinAsString:(OTAccountMetadataClassC_AttemptedAJoinState)value +{ + return OTAccountMetadataClassC_AttemptedAJoinStateAsString(value); +} +- (OTAccountMetadataClassC_AttemptedAJoinState)StringAsAttemptedJoin:(NSString *)str +{ + return StringAsOTAccountMetadataClassC_AttemptedAJoinState(str); +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_peerID) + { + [dict setObject:self->_peerID forKey:@"peerID"]; + } + if (self->_has.icloudAccountState) + { + [dict setObject:OTAccountMetadataClassC_AccountStateAsString(self->_icloudAccountState) forKey:@"icloudAccountState"]; + } + if (self->_has.epoch) + { + [dict setObject:[NSNumber numberWithLongLong:self->_epoch] forKey:@"epoch"]; + } + if (self->_altDSID) + { + [dict setObject:self->_altDSID forKey:@"altDSID"]; + } + if (self->_has.trustState) + { + [dict setObject:OTAccountMetadataClassC_TrustStateAsString(self->_trustState) forKey:@"trustState"]; + } + if (self->_has.lastHealthCheckup) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_lastHealthCheckup] forKey:@"lastHealthCheckup"]; + } + if (self->_has.attemptedJoin) + { + [dict setObject:OTAccountMetadataClassC_AttemptedAJoinStateAsString(self->_attemptedJoin) forKey:@"attemptedJoin"]; + } + return dict; +} + +BOOL OTAccountMetadataClassCReadFrom(__unsafe_unretained OTAccountMetadataClassC *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 /* peerID */: + { + NSString *new_peerID = PBReaderReadString(reader); + self->_peerID = new_peerID; + } + break; + case 2 /* icloudAccountState */: + { + self->_has.icloudAccountState = YES; + self->_icloudAccountState = PBReaderReadInt32(reader); + } + break; + case 3 /* epoch */: + { + self->_has.epoch = YES; + self->_epoch = PBReaderReadInt64(reader); + } + break; + case 4 /* altDSID */: + { + NSString *new_altDSID = PBReaderReadString(reader); + self->_altDSID = new_altDSID; + } + break; + case 5 /* trustState */: + { + self->_has.trustState = YES; + self->_trustState = PBReaderReadInt32(reader); + } + break; + case 6 /* lastHealthCheckup */: + { + self->_has.lastHealthCheckup = YES; + self->_lastHealthCheckup = PBReaderReadUint64(reader); + } + break; + case 7 /* attemptedJoin */: + { + self->_has.attemptedJoin = YES; + self->_attemptedJoin = PBReaderReadInt32(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTAccountMetadataClassCReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* peerID */ + { + if (self->_peerID) + { + PBDataWriterWriteStringField(writer, self->_peerID, 1); + } + } + /* icloudAccountState */ + { + if (self->_has.icloudAccountState) + { + PBDataWriterWriteInt32Field(writer, self->_icloudAccountState, 2); + } + } + /* epoch */ + { + if (self->_has.epoch) + { + PBDataWriterWriteInt64Field(writer, self->_epoch, 3); + } + } + /* altDSID */ + { + if (self->_altDSID) + { + PBDataWriterWriteStringField(writer, self->_altDSID, 4); + } + } + /* trustState */ + { + if (self->_has.trustState) + { + PBDataWriterWriteInt32Field(writer, self->_trustState, 5); + } + } + /* lastHealthCheckup */ + { + if (self->_has.lastHealthCheckup) + { + PBDataWriterWriteUint64Field(writer, self->_lastHealthCheckup, 6); + } + } + /* attemptedJoin */ + { + if (self->_has.attemptedJoin) + { + PBDataWriterWriteInt32Field(writer, self->_attemptedJoin, 7); + } + } +} + +- (void)copyTo:(OTAccountMetadataClassC *)other +{ + if (_peerID) + { + other.peerID = _peerID; + } + if (self->_has.icloudAccountState) + { + other->_icloudAccountState = _icloudAccountState; + other->_has.icloudAccountState = YES; + } + if (self->_has.epoch) + { + other->_epoch = _epoch; + other->_has.epoch = YES; + } + if (_altDSID) + { + other.altDSID = _altDSID; + } + if (self->_has.trustState) + { + other->_trustState = _trustState; + other->_has.trustState = YES; + } + if (self->_has.lastHealthCheckup) + { + other->_lastHealthCheckup = _lastHealthCheckup; + other->_has.lastHealthCheckup = YES; + } + if (self->_has.attemptedJoin) + { + other->_attemptedJoin = _attemptedJoin; + other->_has.attemptedJoin = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTAccountMetadataClassC *copy = [[[self class] allocWithZone:zone] init]; + copy->_peerID = [_peerID copyWithZone:zone]; + if (self->_has.icloudAccountState) + { + copy->_icloudAccountState = _icloudAccountState; + copy->_has.icloudAccountState = YES; + } + if (self->_has.epoch) + { + copy->_epoch = _epoch; + copy->_has.epoch = YES; + } + copy->_altDSID = [_altDSID copyWithZone:zone]; + if (self->_has.trustState) + { + copy->_trustState = _trustState; + copy->_has.trustState = YES; + } + if (self->_has.lastHealthCheckup) + { + copy->_lastHealthCheckup = _lastHealthCheckup; + copy->_has.lastHealthCheckup = YES; + } + if (self->_has.attemptedJoin) + { + copy->_attemptedJoin = _attemptedJoin; + copy->_has.attemptedJoin = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTAccountMetadataClassC *other = (OTAccountMetadataClassC *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_peerID && !other->_peerID) || [self->_peerID isEqual:other->_peerID]) + && + ((self->_has.icloudAccountState && other->_has.icloudAccountState && self->_icloudAccountState == other->_icloudAccountState) || (!self->_has.icloudAccountState && !other->_has.icloudAccountState)) + && + ((self->_has.epoch && other->_has.epoch && self->_epoch == other->_epoch) || (!self->_has.epoch && !other->_has.epoch)) + && + ((!self->_altDSID && !other->_altDSID) || [self->_altDSID isEqual:other->_altDSID]) + && + ((self->_has.trustState && other->_has.trustState && self->_trustState == other->_trustState) || (!self->_has.trustState && !other->_has.trustState)) + && + ((self->_has.lastHealthCheckup && other->_has.lastHealthCheckup && self->_lastHealthCheckup == other->_lastHealthCheckup) || (!self->_has.lastHealthCheckup && !other->_has.lastHealthCheckup)) + && + ((self->_has.attemptedJoin && other->_has.attemptedJoin && self->_attemptedJoin == other->_attemptedJoin) || (!self->_has.attemptedJoin && !other->_has.attemptedJoin)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_peerID hash] + ^ + (self->_has.icloudAccountState ? PBHashInt((NSUInteger)self->_icloudAccountState) : 0) + ^ + (self->_has.epoch ? PBHashInt((NSUInteger)self->_epoch) : 0) + ^ + [self->_altDSID hash] + ^ + (self->_has.trustState ? PBHashInt((NSUInteger)self->_trustState) : 0) + ^ + (self->_has.lastHealthCheckup ? PBHashInt((NSUInteger)self->_lastHealthCheckup) : 0) + ^ + (self->_has.attemptedJoin ? PBHashInt((NSUInteger)self->_attemptedJoin) : 0) + ; +} + +- (void)mergeFrom:(OTAccountMetadataClassC *)other +{ + if (other->_peerID) + { + [self setPeerID:other->_peerID]; + } + if (other->_has.icloudAccountState) + { + self->_icloudAccountState = other->_icloudAccountState; + self->_has.icloudAccountState = YES; + } + if (other->_has.epoch) + { + self->_epoch = other->_epoch; + self->_has.epoch = YES; + } + if (other->_altDSID) + { + [self setAltDSID:other->_altDSID]; + } + if (other->_has.trustState) + { + self->_trustState = other->_trustState; + self->_has.trustState = YES; + } + if (other->_has.lastHealthCheckup) + { + self->_lastHealthCheckup = other->_lastHealthCheckup; + self->_has.lastHealthCheckup = YES; + } + if (other->_has.attemptedJoin) + { + self->_attemptedJoin = other->_attemptedJoin; + self->_has.attemptedJoin = YES; + } +} + +@end + diff --git a/keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h b/keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h new file mode 100644 index 00000000..4204f38f --- /dev/null +++ b/keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.h @@ -0,0 +1,52 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import +#import + +#ifdef __cplusplus +#define OTAPPLICANTTOSPONSORROUND2M1_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTAPPLICANTTOSPONSORROUND2M1_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTApplicantToSponsorRound2M1 : PBCodable +{ + NSString *_peerID; + NSData *_permanentInfo; + NSData *_permanentInfoSig; + NSData *_stableInfo; + NSData *_stableInfoSig; +} + + +@property (nonatomic, readonly) BOOL hasPeerID; +@property (nonatomic, retain) NSString *peerID; + +@property (nonatomic, readonly) BOOL hasPermanentInfo; +@property (nonatomic, retain) NSData *permanentInfo; + +@property (nonatomic, readonly) BOOL hasPermanentInfoSig; +@property (nonatomic, retain) NSData *permanentInfoSig; + +@property (nonatomic, readonly) BOOL hasStableInfo; +@property (nonatomic, retain) NSData *stableInfo; + +@property (nonatomic, readonly) BOOL hasStableInfoSig; +@property (nonatomic, retain) NSData *stableInfoSig; + +// Performs a shallow copy into other +- (void)copyTo:(OTApplicantToSponsorRound2M1 *)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:(OTApplicantToSponsorRound2M1 *)other; + +OTAPPLICANTTOSPONSORROUND2M1_FUNCTION BOOL OTApplicantToSponsorRound2M1ReadFrom(__unsafe_unretained OTApplicantToSponsorRound2M1 *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.m b/keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.m new file mode 100644 index 00000000..a4f0930d --- /dev/null +++ b/keychain/ot/proto/generated_source/OTApplicantToSponsorRound2M1.m @@ -0,0 +1,264 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import "OTApplicantToSponsorRound2M1.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 OTApplicantToSponsorRound2M1 + +- (BOOL)hasPeerID +{ + return _peerID != nil; +} +@synthesize peerID = _peerID; +- (BOOL)hasPermanentInfo +{ + return _permanentInfo != nil; +} +@synthesize permanentInfo = _permanentInfo; +- (BOOL)hasPermanentInfoSig +{ + return _permanentInfoSig != nil; +} +@synthesize permanentInfoSig = _permanentInfoSig; +- (BOOL)hasStableInfo +{ + return _stableInfo != nil; +} +@synthesize stableInfo = _stableInfo; +- (BOOL)hasStableInfoSig +{ + return _stableInfoSig != nil; +} +@synthesize stableInfoSig = _stableInfoSig; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_peerID) + { + [dict setObject:self->_peerID forKey:@"peerID"]; + } + if (self->_permanentInfo) + { + [dict setObject:self->_permanentInfo forKey:@"permanentInfo"]; + } + if (self->_permanentInfoSig) + { + [dict setObject:self->_permanentInfoSig forKey:@"permanentInfoSig"]; + } + if (self->_stableInfo) + { + [dict setObject:self->_stableInfo forKey:@"stableInfo"]; + } + if (self->_stableInfoSig) + { + [dict setObject:self->_stableInfoSig forKey:@"StableInfoSig"]; + } + return dict; +} + +BOOL OTApplicantToSponsorRound2M1ReadFrom(__unsafe_unretained OTApplicantToSponsorRound2M1 *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 /* peerID */: + { + NSString *new_peerID = PBReaderReadString(reader); + self->_peerID = new_peerID; + } + break; + case 2 /* permanentInfo */: + { + NSData *new_permanentInfo = PBReaderReadData(reader); + self->_permanentInfo = new_permanentInfo; + } + break; + case 3 /* permanentInfoSig */: + { + NSData *new_permanentInfoSig = PBReaderReadData(reader); + self->_permanentInfoSig = new_permanentInfoSig; + } + break; + case 4 /* stableInfo */: + { + NSData *new_stableInfo = PBReaderReadData(reader); + self->_stableInfo = new_stableInfo; + } + break; + case 5 /* stableInfoSig */: + { + NSData *new_stableInfoSig = PBReaderReadData(reader); + self->_stableInfoSig = new_stableInfoSig; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTApplicantToSponsorRound2M1ReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* peerID */ + { + if (self->_peerID) + { + PBDataWriterWriteStringField(writer, self->_peerID, 1); + } + } + /* permanentInfo */ + { + if (self->_permanentInfo) + { + PBDataWriterWriteDataField(writer, self->_permanentInfo, 2); + } + } + /* permanentInfoSig */ + { + if (self->_permanentInfoSig) + { + PBDataWriterWriteDataField(writer, self->_permanentInfoSig, 3); + } + } + /* stableInfo */ + { + if (self->_stableInfo) + { + PBDataWriterWriteDataField(writer, self->_stableInfo, 4); + } + } + /* stableInfoSig */ + { + if (self->_stableInfoSig) + { + PBDataWriterWriteDataField(writer, self->_stableInfoSig, 5); + } + } +} + +- (void)copyTo:(OTApplicantToSponsorRound2M1 *)other +{ + if (_peerID) + { + other.peerID = _peerID; + } + if (_permanentInfo) + { + other.permanentInfo = _permanentInfo; + } + if (_permanentInfoSig) + { + other.permanentInfoSig = _permanentInfoSig; + } + if (_stableInfo) + { + other.stableInfo = _stableInfo; + } + if (_stableInfoSig) + { + other.stableInfoSig = _stableInfoSig; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTApplicantToSponsorRound2M1 *copy = [[[self class] allocWithZone:zone] init]; + copy->_peerID = [_peerID copyWithZone:zone]; + copy->_permanentInfo = [_permanentInfo copyWithZone:zone]; + copy->_permanentInfoSig = [_permanentInfoSig copyWithZone:zone]; + copy->_stableInfo = [_stableInfo copyWithZone:zone]; + copy->_stableInfoSig = [_stableInfoSig copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTApplicantToSponsorRound2M1 *other = (OTApplicantToSponsorRound2M1 *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_peerID && !other->_peerID) || [self->_peerID isEqual:other->_peerID]) + && + ((!self->_permanentInfo && !other->_permanentInfo) || [self->_permanentInfo isEqual:other->_permanentInfo]) + && + ((!self->_permanentInfoSig && !other->_permanentInfoSig) || [self->_permanentInfoSig isEqual:other->_permanentInfoSig]) + && + ((!self->_stableInfo && !other->_stableInfo) || [self->_stableInfo isEqual:other->_stableInfo]) + && + ((!self->_stableInfoSig && !other->_stableInfoSig) || [self->_stableInfoSig isEqual:other->_stableInfoSig]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_peerID hash] + ^ + [self->_permanentInfo hash] + ^ + [self->_permanentInfoSig hash] + ^ + [self->_stableInfo hash] + ^ + [self->_stableInfoSig hash] + ; +} + +- (void)mergeFrom:(OTApplicantToSponsorRound2M1 *)other +{ + if (other->_peerID) + { + [self setPeerID:other->_peerID]; + } + if (other->_permanentInfo) + { + [self setPermanentInfo:other->_permanentInfo]; + } + if (other->_permanentInfoSig) + { + [self setPermanentInfoSig:other->_permanentInfoSig]; + } + if (other->_stableInfo) + { + [self setStableInfo:other->_stableInfo]; + } + if (other->_stableInfoSig) + { + [self setStableInfoSig:other->_stableInfoSig]; + } +} + +@end + diff --git a/keychain/ot/proto/generated_source/OTPairingMessage.h b/keychain/ot/proto/generated_source/OTPairingMessage.h new file mode 100644 index 00000000..f2fad2f1 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTPairingMessage.h @@ -0,0 +1,53 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import +#import + +@class OTSponsorToApplicantRound1M2; +@class OTApplicantToSponsorRound2M1; +@class OTSponsorToApplicantRound2M2; +@class OTSOSMessage; + +#ifdef __cplusplus +#define OTPAIRINGMESSAGE_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTPAIRINGMESSAGE_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTPairingMessage : PBCodable +{ + OTSponsorToApplicantRound1M2 *_epoch; + OTApplicantToSponsorRound2M1 *_prepare; + OTSOSMessage *_sosPairingMessage; + OTSponsorToApplicantRound2M2 *_voucher; +} + + +@property (nonatomic, readonly) BOOL hasEpoch; +@property (nonatomic, retain) OTSponsorToApplicantRound1M2 *epoch; + +@property (nonatomic, readonly) BOOL hasPrepare; +@property (nonatomic, retain) OTApplicantToSponsorRound2M1 *prepare; + +@property (nonatomic, readonly) BOOL hasVoucher; +@property (nonatomic, retain) OTSponsorToApplicantRound2M2 *voucher; + +@property (nonatomic, readonly) BOOL hasSosPairingMessage; +@property (nonatomic, retain) OTSOSMessage *sosPairingMessage; + +// Performs a shallow copy into other +- (void)copyTo:(OTPairingMessage *)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:(OTPairingMessage *)other; + +OTPAIRINGMESSAGE_FUNCTION BOOL OTPairingMessageReadFrom(__unsafe_unretained OTPairingMessage *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/generated_source/OTPairingMessage.m b/keychain/ot/proto/generated_source/OTPairingMessage.m new file mode 100644 index 00000000..3416a4f9 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTPairingMessage.m @@ -0,0 +1,298 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import "OTPairingMessage.h" +#import +#import +#import + +#import "OTApplicantToSponsorRound2M1.h" +#import "OTSOSMessage.h" +#import "OTSponsorToApplicantRound1M2.h" +#import "OTSponsorToApplicantRound2M2.h" + +#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 OTPairingMessage + +- (BOOL)hasEpoch +{ + return _epoch != nil; +} +@synthesize epoch = _epoch; +- (BOOL)hasPrepare +{ + return _prepare != nil; +} +@synthesize prepare = _prepare; +- (BOOL)hasVoucher +{ + return _voucher != nil; +} +@synthesize voucher = _voucher; +- (BOOL)hasSosPairingMessage +{ + return _sosPairingMessage != nil; +} +@synthesize sosPairingMessage = _sosPairingMessage; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_epoch) + { + [dict setObject:[_epoch dictionaryRepresentation] forKey:@"epoch"]; + } + if (self->_prepare) + { + [dict setObject:[_prepare dictionaryRepresentation] forKey:@"prepare"]; + } + if (self->_voucher) + { + [dict setObject:[_voucher dictionaryRepresentation] forKey:@"voucher"]; + } + if (self->_sosPairingMessage) + { + [dict setObject:[_sosPairingMessage dictionaryRepresentation] forKey:@"sosPairingMessage"]; + } + return dict; +} + +BOOL OTPairingMessageReadFrom(__unsafe_unretained OTPairingMessage *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 /* epoch */: + { + OTSponsorToApplicantRound1M2 *new_epoch = [[OTSponsorToApplicantRound1M2 alloc] init]; + self->_epoch = new_epoch; + PBDataReaderMark mark_epoch; + BOOL markError = !PBReaderPlaceMark(reader, &mark_epoch); + if (markError) + { + return NO; + } + BOOL inError = !OTSponsorToApplicantRound1M2ReadFrom(new_epoch, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_epoch); + } + break; + case 2 /* prepare */: + { + OTApplicantToSponsorRound2M1 *new_prepare = [[OTApplicantToSponsorRound2M1 alloc] init]; + self->_prepare = new_prepare; + PBDataReaderMark mark_prepare; + BOOL markError = !PBReaderPlaceMark(reader, &mark_prepare); + if (markError) + { + return NO; + } + BOOL inError = !OTApplicantToSponsorRound2M1ReadFrom(new_prepare, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_prepare); + } + break; + case 3 /* voucher */: + { + OTSponsorToApplicantRound2M2 *new_voucher = [[OTSponsorToApplicantRound2M2 alloc] init]; + self->_voucher = new_voucher; + PBDataReaderMark mark_voucher; + BOOL markError = !PBReaderPlaceMark(reader, &mark_voucher); + if (markError) + { + return NO; + } + BOOL inError = !OTSponsorToApplicantRound2M2ReadFrom(new_voucher, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_voucher); + } + break; + case 4 /* sosPairingMessage */: + { + OTSOSMessage *new_sosPairingMessage = [[OTSOSMessage alloc] init]; + self->_sosPairingMessage = new_sosPairingMessage; + PBDataReaderMark mark_sosPairingMessage; + BOOL markError = !PBReaderPlaceMark(reader, &mark_sosPairingMessage); + if (markError) + { + return NO; + } + BOOL inError = !OTSOSMessageReadFrom(new_sosPairingMessage, reader); + if (inError) + { + return NO; + } + PBReaderRecallMark(reader, &mark_sosPairingMessage); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTPairingMessageReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* epoch */ + { + if (self->_epoch != nil) + { + PBDataWriterWriteSubmessage(writer, self->_epoch, 1); + } + } + /* prepare */ + { + if (self->_prepare != nil) + { + PBDataWriterWriteSubmessage(writer, self->_prepare, 2); + } + } + /* voucher */ + { + if (self->_voucher != nil) + { + PBDataWriterWriteSubmessage(writer, self->_voucher, 3); + } + } + /* sosPairingMessage */ + { + if (self->_sosPairingMessage != nil) + { + PBDataWriterWriteSubmessage(writer, self->_sosPairingMessage, 4); + } + } +} + +- (void)copyTo:(OTPairingMessage *)other +{ + if (_epoch) + { + other.epoch = _epoch; + } + if (_prepare) + { + other.prepare = _prepare; + } + if (_voucher) + { + other.voucher = _voucher; + } + if (_sosPairingMessage) + { + other.sosPairingMessage = _sosPairingMessage; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTPairingMessage *copy = [[[self class] allocWithZone:zone] init]; + copy->_epoch = [_epoch copyWithZone:zone]; + copy->_prepare = [_prepare copyWithZone:zone]; + copy->_voucher = [_voucher copyWithZone:zone]; + copy->_sosPairingMessage = [_sosPairingMessage copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTPairingMessage *other = (OTPairingMessage *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_epoch && !other->_epoch) || [self->_epoch isEqual:other->_epoch]) + && + ((!self->_prepare && !other->_prepare) || [self->_prepare isEqual:other->_prepare]) + && + ((!self->_voucher && !other->_voucher) || [self->_voucher isEqual:other->_voucher]) + && + ((!self->_sosPairingMessage && !other->_sosPairingMessage) || [self->_sosPairingMessage isEqual:other->_sosPairingMessage]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_epoch hash] + ^ + [self->_prepare hash] + ^ + [self->_voucher hash] + ^ + [self->_sosPairingMessage hash] + ; +} + +- (void)mergeFrom:(OTPairingMessage *)other +{ + if (self->_epoch && other->_epoch) + { + [self->_epoch mergeFrom:other->_epoch]; + } + else if (!self->_epoch && other->_epoch) + { + [self setEpoch:other->_epoch]; + } + if (self->_prepare && other->_prepare) + { + [self->_prepare mergeFrom:other->_prepare]; + } + else if (!self->_prepare && other->_prepare) + { + [self setPrepare:other->_prepare]; + } + if (self->_voucher && other->_voucher) + { + [self->_voucher mergeFrom:other->_voucher]; + } + else if (!self->_voucher && other->_voucher) + { + [self setVoucher:other->_voucher]; + } + if (self->_sosPairingMessage && other->_sosPairingMessage) + { + [self->_sosPairingMessage mergeFrom:other->_sosPairingMessage]; + } + else if (!self->_sosPairingMessage && other->_sosPairingMessage) + { + [self setSosPairingMessage:other->_sosPairingMessage]; + } +} + +@end + diff --git a/keychain/ot/proto/generated_source/OTSOSMessage.h b/keychain/ot/proto/generated_source/OTSOSMessage.h new file mode 100644 index 00000000..e515077e --- /dev/null +++ b/keychain/ot/proto/generated_source/OTSOSMessage.h @@ -0,0 +1,48 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import +#import + +#ifdef __cplusplus +#define OTSOSMESSAGE_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTSOSMESSAGE_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTSOSMessage : PBCodable +{ + NSData *_circleBlob; + NSData *_credential; + NSData *_initialSyncItems; + NSData *_peerInfo; +} + + +@property (nonatomic, readonly) BOOL hasCredential; +@property (nonatomic, retain) NSData *credential; + +@property (nonatomic, readonly) BOOL hasPeerInfo; +@property (nonatomic, retain) NSData *peerInfo; + +@property (nonatomic, readonly) BOOL hasCircleBlob; +@property (nonatomic, retain) NSData *circleBlob; + +@property (nonatomic, readonly) BOOL hasInitialSyncItems; +@property (nonatomic, retain) NSData *initialSyncItems; + +// Performs a shallow copy into other +- (void)copyTo:(OTSOSMessage *)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:(OTSOSMessage *)other; + +OTSOSMESSAGE_FUNCTION BOOL OTSOSMessageReadFrom(__unsafe_unretained OTSOSMessage *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/generated_source/OTSOSMessage.m b/keychain/ot/proto/generated_source/OTSOSMessage.m new file mode 100644 index 00000000..e4a1f2a5 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTSOSMessage.m @@ -0,0 +1,229 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import "OTSOSMessage.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 OTSOSMessage + +- (BOOL)hasCredential +{ + return _credential != nil; +} +@synthesize credential = _credential; +- (BOOL)hasPeerInfo +{ + return _peerInfo != nil; +} +@synthesize peerInfo = _peerInfo; +- (BOOL)hasCircleBlob +{ + return _circleBlob != nil; +} +@synthesize circleBlob = _circleBlob; +- (BOOL)hasInitialSyncItems +{ + return _initialSyncItems != nil; +} +@synthesize initialSyncItems = _initialSyncItems; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_credential) + { + [dict setObject:self->_credential forKey:@"credential"]; + } + if (self->_peerInfo) + { + [dict setObject:self->_peerInfo forKey:@"peerInfo"]; + } + if (self->_circleBlob) + { + [dict setObject:self->_circleBlob forKey:@"circleBlob"]; + } + if (self->_initialSyncItems) + { + [dict setObject:self->_initialSyncItems forKey:@"initialSyncItems"]; + } + return dict; +} + +BOOL OTSOSMessageReadFrom(__unsafe_unretained OTSOSMessage *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 /* credential */: + { + NSData *new_credential = PBReaderReadData(reader); + self->_credential = new_credential; + } + break; + case 2 /* peerInfo */: + { + NSData *new_peerInfo = PBReaderReadData(reader); + self->_peerInfo = new_peerInfo; + } + break; + case 3 /* circleBlob */: + { + NSData *new_circleBlob = PBReaderReadData(reader); + self->_circleBlob = new_circleBlob; + } + break; + case 4 /* initialSyncItems */: + { + NSData *new_initialSyncItems = PBReaderReadData(reader); + self->_initialSyncItems = new_initialSyncItems; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTSOSMessageReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* credential */ + { + if (self->_credential) + { + PBDataWriterWriteDataField(writer, self->_credential, 1); + } + } + /* peerInfo */ + { + if (self->_peerInfo) + { + PBDataWriterWriteDataField(writer, self->_peerInfo, 2); + } + } + /* circleBlob */ + { + if (self->_circleBlob) + { + PBDataWriterWriteDataField(writer, self->_circleBlob, 3); + } + } + /* initialSyncItems */ + { + if (self->_initialSyncItems) + { + PBDataWriterWriteDataField(writer, self->_initialSyncItems, 4); + } + } +} + +- (void)copyTo:(OTSOSMessage *)other +{ + if (_credential) + { + other.credential = _credential; + } + if (_peerInfo) + { + other.peerInfo = _peerInfo; + } + if (_circleBlob) + { + other.circleBlob = _circleBlob; + } + if (_initialSyncItems) + { + other.initialSyncItems = _initialSyncItems; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTSOSMessage *copy = [[[self class] allocWithZone:zone] init]; + copy->_credential = [_credential copyWithZone:zone]; + copy->_peerInfo = [_peerInfo copyWithZone:zone]; + copy->_circleBlob = [_circleBlob copyWithZone:zone]; + copy->_initialSyncItems = [_initialSyncItems copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTSOSMessage *other = (OTSOSMessage *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_credential && !other->_credential) || [self->_credential isEqual:other->_credential]) + && + ((!self->_peerInfo && !other->_peerInfo) || [self->_peerInfo isEqual:other->_peerInfo]) + && + ((!self->_circleBlob && !other->_circleBlob) || [self->_circleBlob isEqual:other->_circleBlob]) + && + ((!self->_initialSyncItems && !other->_initialSyncItems) || [self->_initialSyncItems isEqual:other->_initialSyncItems]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_credential hash] + ^ + [self->_peerInfo hash] + ^ + [self->_circleBlob hash] + ^ + [self->_initialSyncItems hash] + ; +} + +- (void)mergeFrom:(OTSOSMessage *)other +{ + if (other->_credential) + { + [self setCredential:other->_credential]; + } + if (other->_peerInfo) + { + [self setPeerInfo:other->_peerInfo]; + } + if (other->_circleBlob) + { + [self setCircleBlob:other->_circleBlob]; + } + if (other->_initialSyncItems) + { + [self setInitialSyncItems:other->_initialSyncItems]; + } +} + +@end + diff --git a/keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h new file mode 100644 index 00000000..61741b2b --- /dev/null +++ b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.h @@ -0,0 +1,39 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import +#import + +#ifdef __cplusplus +#define OTSPONSORTOAPPLICANTROUND1M2_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTSPONSORTOAPPLICANTROUND1M2_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTSponsorToApplicantRound1M2 : PBCodable +{ + uint64_t _epoch; + struct { + int epoch:1; + } _has; +} + + +@property (nonatomic) BOOL hasEpoch; +@property (nonatomic) uint64_t epoch; + +// Performs a shallow copy into other +- (void)copyTo:(OTSponsorToApplicantRound1M2 *)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:(OTSponsorToApplicantRound1M2 *)other; + +OTSPONSORTOAPPLICANTROUND1M2_FUNCTION BOOL OTSponsorToApplicantRound1M2ReadFrom(__unsafe_unretained OTSponsorToApplicantRound1M2 *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.m b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.m new file mode 100644 index 00000000..7a2aad45 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound1M2.m @@ -0,0 +1,139 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import "OTSponsorToApplicantRound1M2.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 OTSponsorToApplicantRound1M2 + +@synthesize epoch = _epoch; +- (void)setEpoch:(uint64_t)v +{ + _has.epoch = YES; + _epoch = v; +} +- (void)setHasEpoch:(BOOL)f +{ + _has.epoch = f; +} +- (BOOL)hasEpoch +{ + return _has.epoch; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_has.epoch) + { + [dict setObject:[NSNumber numberWithUnsignedLongLong:self->_epoch] forKey:@"epoch"]; + } + return dict; +} + +BOOL OTSponsorToApplicantRound1M2ReadFrom(__unsafe_unretained OTSponsorToApplicantRound1M2 *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 /* epoch */: + { + self->_has.epoch = YES; + self->_epoch = PBReaderReadUint64(reader); + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTSponsorToApplicantRound1M2ReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* epoch */ + { + if (self->_has.epoch) + { + PBDataWriterWriteUint64Field(writer, self->_epoch, 1); + } + } +} + +- (void)copyTo:(OTSponsorToApplicantRound1M2 *)other +{ + if (self->_has.epoch) + { + other->_epoch = _epoch; + other->_has.epoch = YES; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTSponsorToApplicantRound1M2 *copy = [[[self class] allocWithZone:zone] init]; + if (self->_has.epoch) + { + copy->_epoch = _epoch; + copy->_has.epoch = YES; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTSponsorToApplicantRound1M2 *other = (OTSponsorToApplicantRound1M2 *)object; + return [other isMemberOfClass:[self class]] + && + ((self->_has.epoch && other->_has.epoch && self->_epoch == other->_epoch) || (!self->_has.epoch && !other->_has.epoch)) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + (self->_has.epoch ? PBHashInt((NSUInteger)self->_epoch) : 0) + ; +} + +- (void)mergeFrom:(OTSponsorToApplicantRound1M2 *)other +{ + if (other->_has.epoch) + { + self->_epoch = other->_epoch; + self->_has.epoch = YES; + } +} + +@end + diff --git a/keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h new file mode 100644 index 00000000..b7495329 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.h @@ -0,0 +1,48 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import +#import + +#ifdef __cplusplus +#define OTSPONSORTOAPPLICANTROUND2M2_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTSPONSORTOAPPLICANTROUND2M2_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTSponsorToApplicantRound2M2 : PBCodable +{ + NSMutableArray *_preapprovedKeys; + NSData *_voucher; + NSData *_voucherSignature; +} + + +@property (nonatomic, readonly) BOOL hasVoucher; +@property (nonatomic, retain) NSData *voucher; + +@property (nonatomic, readonly) BOOL hasVoucherSignature; +@property (nonatomic, retain) NSData *voucherSignature; + +@property (nonatomic, retain) NSMutableArray *preapprovedKeys; +- (void)clearPreapprovedKeys; +- (void)addPreapprovedKeys:(NSData *)i; +- (NSUInteger)preapprovedKeysCount; +- (NSData *)preapprovedKeysAtIndex:(NSUInteger)idx; ++ (Class)preapprovedKeysType; + +// Performs a shallow copy into other +- (void)copyTo:(OTSponsorToApplicantRound2M2 *)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:(OTSponsorToApplicantRound2M2 *)other; + +OTSPONSORTOAPPLICANTROUND2M2_FUNCTION BOOL OTSponsorToApplicantRound2M2ReadFrom(__unsafe_unretained OTSponsorToApplicantRound2M2 *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.m b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.m new file mode 100644 index 00000000..6737b641 --- /dev/null +++ b/keychain/ot/proto/generated_source/OTSponsorToApplicantRound2M2.m @@ -0,0 +1,226 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import "OTSponsorToApplicantRound2M2.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 OTSponsorToApplicantRound2M2 + +- (BOOL)hasVoucher +{ + return _voucher != nil; +} +@synthesize voucher = _voucher; +- (BOOL)hasVoucherSignature +{ + return _voucherSignature != nil; +} +@synthesize voucherSignature = _voucherSignature; +@synthesize preapprovedKeys = _preapprovedKeys; +- (void)clearPreapprovedKeys +{ + [_preapprovedKeys removeAllObjects]; +} +- (void)addPreapprovedKeys:(NSData *)i +{ + if (!_preapprovedKeys) + { + _preapprovedKeys = [[NSMutableArray alloc] init]; + } + [_preapprovedKeys addObject:i]; +} +- (NSUInteger)preapprovedKeysCount +{ + return [_preapprovedKeys count]; +} +- (NSData *)preapprovedKeysAtIndex:(NSUInteger)idx +{ + return [_preapprovedKeys objectAtIndex:idx]; +} ++ (Class)preapprovedKeysType +{ + return [NSData class]; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_voucher) + { + [dict setObject:self->_voucher forKey:@"voucher"]; + } + if (self->_voucherSignature) + { + [dict setObject:self->_voucherSignature forKey:@"voucherSignature"]; + } + if (self->_preapprovedKeys) + { + [dict setObject:self->_preapprovedKeys forKey:@"preapprovedKeys"]; + } + return dict; +} + +BOOL OTSponsorToApplicantRound2M2ReadFrom(__unsafe_unretained OTSponsorToApplicantRound2M2 *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 /* voucher */: + { + NSData *new_voucher = PBReaderReadData(reader); + self->_voucher = new_voucher; + } + break; + case 2 /* voucherSignature */: + { + NSData *new_voucherSignature = PBReaderReadData(reader); + self->_voucherSignature = new_voucherSignature; + } + break; + case 3 /* preapprovedKeys */: + { + NSData *new_preapprovedKeys = PBReaderReadData(reader); + if (new_preapprovedKeys) + { + [self addPreapprovedKeys:new_preapprovedKeys]; + } + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTSponsorToApplicantRound2M2ReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* voucher */ + { + if (self->_voucher) + { + PBDataWriterWriteDataField(writer, self->_voucher, 1); + } + } + /* voucherSignature */ + { + if (self->_voucherSignature) + { + PBDataWriterWriteDataField(writer, self->_voucherSignature, 2); + } + } + /* preapprovedKeys */ + { + for (NSData *s_preapprovedKeys in self->_preapprovedKeys) + { + PBDataWriterWriteDataField(writer, s_preapprovedKeys, 3); + } + } +} + +- (void)copyTo:(OTSponsorToApplicantRound2M2 *)other +{ + if (_voucher) + { + other.voucher = _voucher; + } + if (_voucherSignature) + { + other.voucherSignature = _voucherSignature; + } + if ([self preapprovedKeysCount]) + { + [other clearPreapprovedKeys]; + NSUInteger preapprovedKeysCnt = [self preapprovedKeysCount]; + for (NSUInteger i = 0; i < preapprovedKeysCnt; i++) + { + [other addPreapprovedKeys:[self preapprovedKeysAtIndex:i]]; + } + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTSponsorToApplicantRound2M2 *copy = [[[self class] allocWithZone:zone] init]; + copy->_voucher = [_voucher copyWithZone:zone]; + copy->_voucherSignature = [_voucherSignature copyWithZone:zone]; + for (NSData *v in _preapprovedKeys) + { + NSData *vCopy = [v copyWithZone:zone]; + [copy addPreapprovedKeys:vCopy]; + } + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTSponsorToApplicantRound2M2 *other = (OTSponsorToApplicantRound2M2 *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_voucher && !other->_voucher) || [self->_voucher isEqual:other->_voucher]) + && + ((!self->_voucherSignature && !other->_voucherSignature) || [self->_voucherSignature isEqual:other->_voucherSignature]) + && + ((!self->_preapprovedKeys && !other->_preapprovedKeys) || [self->_preapprovedKeys isEqual:other->_preapprovedKeys]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_voucher hash] + ^ + [self->_voucherSignature hash] + ^ + [self->_preapprovedKeys hash] + ; +} + +- (void)mergeFrom:(OTSponsorToApplicantRound2M2 *)other +{ + if (other->_voucher) + { + [self setVoucher:other->_voucher]; + } + if (other->_voucherSignature) + { + [self setVoucherSignature:other->_voucherSignature]; + } + for (NSData *iter_preapprovedKeys in other->_preapprovedKeys) + { + [self addPreapprovedKeys:iter_preapprovedKeys]; + } +} + +@end + diff --git a/keychain/ot/proto/source/OTSOSMessage.h b/keychain/ot/proto/source/OTSOSMessage.h new file mode 100644 index 00000000..e515077e --- /dev/null +++ b/keychain/ot/proto/source/OTSOSMessage.h @@ -0,0 +1,48 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import +#import + +#ifdef __cplusplus +#define OTSOSMESSAGE_FUNCTION extern "C" __attribute__((visibility("hidden"))) +#else +#define OTSOSMESSAGE_FUNCTION extern __attribute__((visibility("hidden"))) +#endif + +__attribute__((visibility("hidden"))) +@interface OTSOSMessage : PBCodable +{ + NSData *_circleBlob; + NSData *_credential; + NSData *_initialSyncItems; + NSData *_peerInfo; +} + + +@property (nonatomic, readonly) BOOL hasCredential; +@property (nonatomic, retain) NSData *credential; + +@property (nonatomic, readonly) BOOL hasPeerInfo; +@property (nonatomic, retain) NSData *peerInfo; + +@property (nonatomic, readonly) BOOL hasCircleBlob; +@property (nonatomic, retain) NSData *circleBlob; + +@property (nonatomic, readonly) BOOL hasInitialSyncItems; +@property (nonatomic, retain) NSData *initialSyncItems; + +// Performs a shallow copy into other +- (void)copyTo:(OTSOSMessage *)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:(OTSOSMessage *)other; + +OTSOSMESSAGE_FUNCTION BOOL OTSOSMessageReadFrom(__unsafe_unretained OTSOSMessage *self, __unsafe_unretained PBDataReader *reader); + +@end + diff --git a/keychain/ot/proto/source/OTSOSMessage.m b/keychain/ot/proto/source/OTSOSMessage.m new file mode 100644 index 00000000..e4a1f2a5 --- /dev/null +++ b/keychain/ot/proto/source/OTSOSMessage.m @@ -0,0 +1,229 @@ +// This file was automatically generated by protocompiler +// DO NOT EDIT! +// Compiled from OTPairingMessage.proto + +#import "OTSOSMessage.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 OTSOSMessage + +- (BOOL)hasCredential +{ + return _credential != nil; +} +@synthesize credential = _credential; +- (BOOL)hasPeerInfo +{ + return _peerInfo != nil; +} +@synthesize peerInfo = _peerInfo; +- (BOOL)hasCircleBlob +{ + return _circleBlob != nil; +} +@synthesize circleBlob = _circleBlob; +- (BOOL)hasInitialSyncItems +{ + return _initialSyncItems != nil; +} +@synthesize initialSyncItems = _initialSyncItems; + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], [self dictionaryRepresentation]]; +} + +- (NSDictionary *)dictionaryRepresentation +{ + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + if (self->_credential) + { + [dict setObject:self->_credential forKey:@"credential"]; + } + if (self->_peerInfo) + { + [dict setObject:self->_peerInfo forKey:@"peerInfo"]; + } + if (self->_circleBlob) + { + [dict setObject:self->_circleBlob forKey:@"circleBlob"]; + } + if (self->_initialSyncItems) + { + [dict setObject:self->_initialSyncItems forKey:@"initialSyncItems"]; + } + return dict; +} + +BOOL OTSOSMessageReadFrom(__unsafe_unretained OTSOSMessage *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 /* credential */: + { + NSData *new_credential = PBReaderReadData(reader); + self->_credential = new_credential; + } + break; + case 2 /* peerInfo */: + { + NSData *new_peerInfo = PBReaderReadData(reader); + self->_peerInfo = new_peerInfo; + } + break; + case 3 /* circleBlob */: + { + NSData *new_circleBlob = PBReaderReadData(reader); + self->_circleBlob = new_circleBlob; + } + break; + case 4 /* initialSyncItems */: + { + NSData *new_initialSyncItems = PBReaderReadData(reader); + self->_initialSyncItems = new_initialSyncItems; + } + break; + default: + if (!PBReaderSkipValueWithTag(reader, tag, aType)) + return NO; + break; + } + } + return !PBReaderHasError(reader); +} + +- (BOOL)readFrom:(PBDataReader *)reader +{ + return OTSOSMessageReadFrom(self, reader); +} +- (void)writeTo:(PBDataWriter *)writer +{ + /* credential */ + { + if (self->_credential) + { + PBDataWriterWriteDataField(writer, self->_credential, 1); + } + } + /* peerInfo */ + { + if (self->_peerInfo) + { + PBDataWriterWriteDataField(writer, self->_peerInfo, 2); + } + } + /* circleBlob */ + { + if (self->_circleBlob) + { + PBDataWriterWriteDataField(writer, self->_circleBlob, 3); + } + } + /* initialSyncItems */ + { + if (self->_initialSyncItems) + { + PBDataWriterWriteDataField(writer, self->_initialSyncItems, 4); + } + } +} + +- (void)copyTo:(OTSOSMessage *)other +{ + if (_credential) + { + other.credential = _credential; + } + if (_peerInfo) + { + other.peerInfo = _peerInfo; + } + if (_circleBlob) + { + other.circleBlob = _circleBlob; + } + if (_initialSyncItems) + { + other.initialSyncItems = _initialSyncItems; + } +} + +- (id)copyWithZone:(NSZone *)zone +{ + OTSOSMessage *copy = [[[self class] allocWithZone:zone] init]; + copy->_credential = [_credential copyWithZone:zone]; + copy->_peerInfo = [_peerInfo copyWithZone:zone]; + copy->_circleBlob = [_circleBlob copyWithZone:zone]; + copy->_initialSyncItems = [_initialSyncItems copyWithZone:zone]; + return copy; +} + +- (BOOL)isEqual:(id)object +{ + OTSOSMessage *other = (OTSOSMessage *)object; + return [other isMemberOfClass:[self class]] + && + ((!self->_credential && !other->_credential) || [self->_credential isEqual:other->_credential]) + && + ((!self->_peerInfo && !other->_peerInfo) || [self->_peerInfo isEqual:other->_peerInfo]) + && + ((!self->_circleBlob && !other->_circleBlob) || [self->_circleBlob isEqual:other->_circleBlob]) + && + ((!self->_initialSyncItems && !other->_initialSyncItems) || [self->_initialSyncItems isEqual:other->_initialSyncItems]) + ; +} + +- (NSUInteger)hash +{ + return 0 + ^ + [self->_credential hash] + ^ + [self->_peerInfo hash] + ^ + [self->_circleBlob hash] + ^ + [self->_initialSyncItems hash] + ; +} + +- (void)mergeFrom:(OTSOSMessage *)other +{ + if (other->_credential) + { + [self setCredential:other->_credential]; + } + if (other->_peerInfo) + { + [self setPeerInfo:other->_peerInfo]; + } + if (other->_circleBlob) + { + [self setCircleBlob:other->_circleBlob]; + } + if (other->_initialSyncItems) + { + [self setInitialSyncItems:other->_initialSyncItems]; + } +} + +@end + diff --git a/keychain/ot/tests/OTBottledPeerUpdateBottlesTests.m b/keychain/ot/tests/OTBottledPeerUpdateBottlesTests.m new file mode 100644 index 00000000..bb762dc1 --- /dev/null +++ b/keychain/ot/tests/OTBottledPeerUpdateBottlesTests.m @@ -0,0 +1,324 @@ +/* + * 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 OCTAGON + +#import + +#import +#import + +#import "OTTestsBase.h" +#import "keychain/ot/OTConstants.h" + +static NSString* const testContextID = @"Foo"; +static NSString* const testDSID = @"123456789"; + +static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; + +@interface OTUpdateBottlesTests : OTTestsBase + +@end + +@implementation OTUpdateBottlesTests + +- (void)setUp { + [super setUp]; + self.continueAfterFailure = NO; + [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. +} + +- (void)tearDown { + [super tearDown]; +} + +-(void)testUpdatingExistingBottle +{ + __block NSData* localEntropy = nil; + __block NSString* localBottleID = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight SPI should fire"]; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + [self startCKKSSubsystem]; + + //create a bottle + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy = entropy; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launch bottle SPI should fire"]; + + //launch it + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + + [self expectCKFetch]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"updating identity SPI should fire"]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(result, "result should be YES"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void)testUpdatingNonExistentBottles +{ + self.spiBlockExpectation = [self expectationWithDescription:@"updating identity SPI should fire"]; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + [self startCKKSSubsystem]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + [self.spiBlockExpectation fulfill]; + XCTAssertNotNil(error, "error should not be nil"); + XCTAssertFalse(result, "result should be NO"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; +} + +-(void)testUpdatingBottleMissingKeys +{ + __block NSData* localEntropy = nil; + __block NSString* localBottleID = nil; + NSError *localError = nil; + self.spiBlockExpectation = [self expectationWithDescription:@"preflight SPI should fire"]; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + [self startCKKSSubsystem]; + + //create a bottle + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy = entropy; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launch bottle SPI should fire"]; + + //launch it + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + + [self expectCKFetch]; + + //delete escrow keys + OTEscrowKeys* keySet = [[OTEscrowKeys alloc] initWithSecret:localEntropy dsid:testDSID error:&localError]; + XCTAssertNotNil(keySet, "keySet should not be nil"); + XCTAssertNil(localError, "localError should be nil"); + + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassKey, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecReturnAttributes: @YES, + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + } mutableCopy]; + + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + XCTAssertEqual(status, 0, @"status should be 0"); + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"updating bottle SPI should fire"]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + [self.spiBlockExpectation fulfill]; + XCTAssertFalse(result, "result should be NO"); + XCTAssertNotNil(error, "error should not be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + +} + +-(void)testUpdatingMultipleBottlesForSamePeer +{ + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + [self startCKKSSubsystem]; + + __block NSData* localEntropy1 = nil; + __block NSString* localBottleID1 = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight SPI should fire"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy1 = entropy; + localBottleID1 = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launching bottle SPI should fire"]; + + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID1 reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + + __block NSData* localEntropy2 = nil; + __block NSString* localBottleID2 = nil; + + self.spiBlockExpectation = [self expectationWithDescription:@"preflight SPI should fire"]; + + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + localEntropy2 = entropy; + localBottleID2 = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"launching bottle SPI should fire"]; + + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID2 reply:^(NSError * _Nullable error) { + [self.spiBlockExpectation fulfill]; + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForCKModifications]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + self.spiBlockExpectation = [self expectationWithDescription:@"updating bottle SPI should fire"]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(result, "result should be YES"); + XCTAssertNil(error, "error should be nil"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); +} + + +@end + +#endif + diff --git a/keychain/ot/tests/OTCliqueTests.m b/keychain/ot/tests/OTCliqueTests.m new file mode 100644 index 00000000..69b7d9c7 --- /dev/null +++ b/keychain/ot/tests/OTCliqueTests.m @@ -0,0 +1,238 @@ +/* + * 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 "OTClique.h" +#import +#import + +@interface CliqueUnitTests : XCTestCase +@property (nonatomic, strong) OTClique* testClique; +@property (nonatomic, strong) OTConfigurationContext* testData; +@property (nonatomic, copy) NSString* testContextName; +@property (nonatomic, copy) NSString* testDSID; +@property (nonatomic, copy) NSString* testAltDSID; +@property (nonatomic, strong) SFSignInAnalytics *analytics; +@property (nonatomic, strong) XCTestExpectation *spiBlockExpectation; + +@end + +@implementation CliqueUnitTests + +- (void)setUp +{ + NSError *error = NULL; + + [super setUp]; + self.continueAfterFailure = NO; + _testDSID = @"123456789"; + _testContextName = @"contextName"; + _testAltDSID = @"testAltDSID"; + _testData = [[OTConfigurationContext alloc]init]; + _testData.context = _testContextName; + _testData.dsid = _testDSID; + _testData.altDSID = _testAltDSID; + _testData.analytics = _analytics; + + _analytics = [[SFSignInAnalytics alloc]initWithSignInUUID:[NSUUID UUID].UUIDString category:@"com.apple.cdp" eventName:@"signed in"]; + XCTAssertNotNil(_analytics, "sign in analytics object should not be nil"); + + _testClique = [[OTClique alloc]initWithContextData:_testData error:&error]; + XCTAssertNotNil(_testClique, "clique should not be nil: %@", error); +} + +- (void)tearDown +{ + _analytics = nil; + _testClique = nil; + + [super tearDown]; +} + + +-(void) testCliqueStatus +{ + NSError *error = NULL; + CliqueStatus clique = [_testClique fetchCliqueStatus:&error]; + XCTAssertTrue(clique == CliqueStatusIn || clique == CliqueStatusError, "circle status should be in circle"); + XCTAssertTrue(error == nil || [error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be nil"); +} + +-(void) testCachedCliqueStatus +{ + NSError *error = NULL; +#pragma clang push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + CliqueStatus clique = [_testClique cachedCliqueStatus:YES error:&error]; +#pragma clang pop + XCTAssertTrue(clique == CliqueStatusIn || clique == CliqueStatusError, "circle status should be in circle"); + XCTAssertTrue(error == nil || [error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be nil"); +} + +- (void) testMakeNewFriends +{ + NSError *error = NULL; + OTConfigurationContext* newData = [[OTConfigurationContext alloc]init]; + newData.context = _testContextName; + newData.dsid = _testDSID; + newData.altDSID = _testAltDSID; + newData.analytics = _analytics; + + OTClique* clique = [OTClique newFriendsWithContextData:newData error:&error]; + if(error){ + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain] || [error.domain isEqualToString:NSMachErrorDomain], "error should be kern return error"); + XCTAssertNil(clique, "clique should be nil"); + } + else{ + XCTAssertNotNil(clique, "new clique should be nil"); + XCTAssertNil(error, "error should be nil"); + } +} + +- (void) testRemoveFriendFromClique +{ + NSError *error = NULL; + CFErrorRef validPeerError = NULL; + CFArrayRef peerList = SOSCCCopyValidPeerPeerInfo(&validPeerError); + if(validPeerError){ + BOOL result = [_testClique removeFriendsInClique:@[@""] error:&error]; + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain] || [error.domain isEqualToString:NSMachErrorDomain], "error should be kern return error"); + XCTAssertFalse(result, "should have returned NO, attempting to remove friends when not valid in the circle"); + }else{ + BOOL result = [_testClique removeFriendsInClique:@[@""] error:&error]; + XCTAssertFalse(result, "should have returned NO, we passed an empty list"); + } + CFReleaseNull(peerList); +} + +- (void) testLeaveClique +{ + NSError *error = NULL; + BOOL result = [_testClique leaveClique:&error]; + if(error){ + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain] || [error.domain isEqualToString:NSMachErrorDomain], "error should be kern return error"); + XCTAssertFalse(result, "result should be NO"); + }else{ + XCTAssertNil(error, "error should be nil"); + } +} + +- (void) testListFriendIDs +{ + NSError *error = NULL; + NSDictionary *friends = [_testClique peerDeviceNamesByPeerID:&error]; + if(error){ + XCTAssertEqual([friends count], 0, "friends should be nil"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + }else{ + XCTAssertNotNil(friends, "friends should not be nil"); + } +} + +- (void) testWaitForInitialSync +{ + NSError *error = NULL; + BOOL result = [_testClique waitForInitialSync:&error]; + if(error){ + XCTAssertFalse(result, "result should be NO"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + }else{ + XCTAssertTrue(result, "wait for initial sync should succeed"); + } +} + +- (void) testCopyViewUnawarePeerInfo +{ + NSError *error = NULL; + NSArray* result = [_testClique copyViewUnawarePeerInfo:&error]; + if(error){ + XCTAssertNil(result, "result should be nil"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + }else{ + XCTAssertNotNil(result, "copy view unaware peer info should return an array of peer infos"); + } +} + +- (void) testSetUserCredentialsAndDSID +{ + NSError *error = NULL; + + BOOL result = [_testClique setUserCredentialsAndDSID:[NSString string] password:[NSData data] error:&error]; + if(error) { + XCTAssertFalse(result, "result should be NO"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain] || [error.domain isEqualToString:@"SyncedDefaults"] , "error should be from sos or KVS"); + }else{ + XCTAssertTrue(result, "result should be YES"); + } +} + +- (void) testTryUserCredentialsAndDSID +{ + NSError *error = NULL; + + BOOL result = [_testClique tryUserCredentialsAndDSID:[NSString string] password:[NSData data] error:&error]; + if(error){ + XCTAssertFalse(result, "result should be NO"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + }else{ + XCTAssertTrue(result, "result should be YES"); + } +} + +- (void) testCopyPeerPeerInfo +{ + NSError *error = NULL; + + NSArray* result = [_testClique copyPeerPeerInfo:&error]; + if(error){ + XCTAssertNil(result, "result should be nil"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + }else{ + XCTAssertNotNil(result, "result should not be nil"); + } +} + +- (void) testPeersHaveViewsEnabled +{ + NSError *error = NULL; + + BOOL result = [_testClique peersHaveViewsEnabled:[NSArray array] error:&error]; + if(error){ + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + } + XCTAssertFalse(result, "result should be NO"); +} +- (void) testRequestToJoinCircle +{ + NSError *error = NULL; + + BOOL result = [_testClique requestToJoinCircle:&error]; + if(error){ + XCTAssertFalse(result, "result should be NO"); + XCTAssertTrue([error.domain isEqualToString:(__bridge NSString*)kSOSErrorDomain], "error should be from sos"); + }else{ + XCTAssertTrue(result, "result should be YES"); + } +} + +@end diff --git a/keychain/ot/tests/OTCloudStoreTests.m b/keychain/ot/tests/OTCloudStoreTests.m index 3fc7b178..3b60a1b9 100644 --- a/keychain/ot/tests/OTCloudStoreTests.m +++ b/keychain/ot/tests/OTCloudStoreTests.m @@ -50,8 +50,8 @@ static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; self.fakeBottledPeerRecord.peerID = @"peer id"; self.fakeBottledPeerRecord.spID = @"sos peer id"; self.fakeBottledPeerRecord.escrowRecordID = @"escrowRecordID"; - self.fakeBottledPeerRecord.escrowedSigningSPKI = [@"escrowedSigningSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; - self.fakeBottledPeerRecord.peerSigningSPKI = [@"peerSigningSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; + self.fakeBottledPeerRecord.escrowedSigningSPKI = [@"escrowedSigningSPKI" dataUsingEncoding:NSUTF8StringEncoding]; + self.fakeBottledPeerRecord.peerSigningSPKI = [@"peerSigningSPKI" dataUsingEncoding:NSUTF8StringEncoding]; } - (void)tearDown { @@ -267,13 +267,10 @@ static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; { NSError* error = nil; - NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; - - [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; - - [self startCKKSSubsystem]; + [self expectAddedCKModifyRecords:@{OTCKRecordBottledPeerType: @1} holdFetch:NO]; [self createAndSaveFakeKeyHierarchy: self.keychainZoneID]; // Make life easy for this test. + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; XCTAssertEqual(0, [self.keychainView.keyHierarchyConditions[SecCKKSZoneKeyStateReady] wait:4*NSEC_PER_SEC], @"Key state should have arrived at ready"); @@ -286,7 +283,7 @@ static NSString* OTCKRecordEscrowRecordID = @"escrowRecordID"; XCTAssertNotNil(error, "error should not be nil"); XCTAssertTrue([(NSString*)error.userInfo[@"NSLocalizedDescription"] isEqualToString:@"Operation(CKKSResultOperation(cloudkit-modify-changes)) timed out waiting to start for []"], "expecting timed out error"); - [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + [self expectAddedCKModifyRecords:@{OTCKRecordBottledPeerType: @1} holdFetch:NO]; [self releaseCloudKitModificationHold]; [self waitForCKModifications]; diff --git a/keychain/ot/tests/OTContextTests.m b/keychain/ot/tests/OTContextTests.m index 261eb069..b1b65f3c 100644 --- a/keychain/ot/tests/OTContextTests.m +++ b/keychain/ot/tests/OTContextTests.m @@ -158,7 +158,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; XCTAssertNil(error, @"error should be nil: %@", error); XCTAssertNotNil(self.escrowKeys, @"escrow keys should not be nil: %@", error); - NSString* recordName = [OTBottledPeerRecord constructRecordID:identity.spID escrowSigningSPKI:[self.escrowKeys.signingKey.publicKey asSPKI]]; + NSString* recordName = [OTBottledPeerRecord constructRecordID:identity.spID escrowSigningSPKI:[self.escrowKeys.signingKey.publicKey encodeSubjectPublicKeyInfo]]; OTBottledPeerRecord *rec = [self.localStore readLocalBottledPeerRecordWithRecordID:recordName error:&error]; diff --git a/keychain/ot/tests/OTCuttlefishContextTests.m b/keychain/ot/tests/OTCuttlefishContextTests.m new file mode 100644 index 00000000..5c31a4e6 --- /dev/null +++ b/keychain/ot/tests/OTCuttlefishContextTests.m @@ -0,0 +1,103 @@ +/* + * 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 OCTAGON + +#import +#import +#import +#import +#import "OTTestsBase.h" +#import "OTSOSAdapter.h" + +@interface OTCuttlefishContextTests : OTTestsBase +@end + +@implementation OTCuttlefishContextTests + +- (void)setUp +{ + [super setUp]; +} + +- (void)tearDown +{ + [super tearDown]; +} + +- (void)testStateMachineInitialization { + XCTAssertEqual(0, [self.cuttlefishContext.stateConditions[OctagonStateMachineNotStarted] wait:10*NSEC_PER_SEC], "State machine should enter 'not started'"); + + [self.cuttlefishContext startOctagonStateMachine]; + + XCTAssertEqual(0, [self.cuttlefishContext.stateConditions[OctagonStateInitializing] wait:10*NSEC_PER_SEC], "State machine should enter 'initializing'"); + + XCTAssertEqual(0, [self.cuttlefishContext.stateConditions[OctagonStateUntrusted] wait:10*NSEC_PER_SEC], "State machine should enter 'signedout'"); +} + +- (void)testPrepare { + [self.cuttlefishContext startOctagonStateMachine]; + + XCTAssertEqual(0, [self.cuttlefishContext.stateConditions[OctagonStateUntrusted] wait:10*NSEC_PER_SEC], "State machine should enter 'signedout'"); + + XCTestExpectation* rpcCallbackOccurs = [self expectationWithDescription:@"rpcPrepare callback occurs"]; + [self.cuttlefishContext prepareForApplicant:0 reply:^(NSString * _Nullable peerID, NSData * _Nullable permanentInfo, NSData * _Nullable permanentInfoSig, NSData * _Nullable stableInfo, NSData * _Nullable stableInfoSig, NSError * _Nullable error) { + XCTAssertNil(error, "Should be no error calling 'prepare'"); + + XCTAssertNotNil(peerID, "Prepare should have returned a peerID"); + XCTAssertNotNil(permanentInfo, "Prepare should have returned a permanentInfo"); + XCTAssertNotNil(permanentInfoSig, "Prepare should have returned a permanentInfoSig"); + XCTAssertNotNil(stableInfo, "Prepare should have returned a stableInfo"); + XCTAssertNotNil(stableInfoSig, "Prepare should have returned a stableInfoSig"); + + [rpcCallbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[rpcCallbackOccurs] timeout:10]; + +} + +- (void)testPrepareTimeoutIfStateMachineUnstarted { + + XCTestExpectation* rpcCallbackOccurs = [self expectationWithDescription:@"rpcPrepare callback occurs"]; + [self.cuttlefishContext prepareForApplicant:0 reply:^(NSString * _Nullable peerID, NSData * _Nullable permanentInfo, NSData * _Nullable permanentInfoSig, NSData * _Nullable stableInfo, NSData * _Nullable stableInfoSig, NSError * _Nullable error) { + XCTAssertNotNil(error, "Should be an error calling 'prepare'"); + XCTAssertEqualObjects(error.domain, CKKSResultErrorDomain, "Error domain should be CKKSResultErrorDomain"); + XCTAssertEqual(error.code, CKKSResultTimedOut, "Error result should be CKKSResultTimedOut"); + + + XCTAssertNil(peerID, "Prepare should not have returned a peerID"); + XCTAssertNil(permanentInfo, "Prepare should not have returned a permanentInfo"); + XCTAssertNil(permanentInfoSig, "Prepare should not have returned a permanentInfoSig"); + XCTAssertNil(stableInfo, "Prepare should not have returned a stableInfo"); + XCTAssertNil(stableInfoSig, "Prepare should not have returned a stableInfoSig"); + + [rpcCallbackOccurs fulfill]; + }]; + + [self waitForExpectations:@[rpcCallbackOccurs] timeout:10]; +} + +@end +#endif diff --git a/keychain/ot/tests/OTEscrowKeyTests.m b/keychain/ot/tests/OTEscrowKeyTests.m index cd1954e7..44cf9961 100644 --- a/keychain/ot/tests/OTEscrowKeyTests.m +++ b/keychain/ot/tests/OTEscrowKeyTests.m @@ -146,6 +146,45 @@ static const uint8_t symmetricKey_384[] = { XCTAssertNil(newSet, @"escrow keys should not be initialized"); } +-(void) testEscrowKeyLoadingAndStoringInKeychain +{ + NSError* error = nil; + NSString* secretString = @"secret"; + NSData* secret = [[NSData alloc]initWithBytes:[secretString UTF8String] length:[secretString length]]; + + OTEscrowKeys* keys = [[OTEscrowKeys alloc] initWithSecret:secret dsid:@"dsid-123456789" error:&error]; + XCTAssertNotNil(keys, @"keys should not be nil"); + XCTAssertNil(error, "error should be nil"); + + NSString* label = [OTEscrowKeys hashEscrowedSigningPublicKey:[[keys.signingKey publicKey] encodeSubjectPublicKeyInfo]]; + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassKey, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecAttrLabel: label, + (id)kSecReturnAttributes: @YES, + (id)kSecReturnData : @YES, + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + (id)kSecMatchLimit : (id)kSecMatchLimitAll, + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); + XCTAssertNotNil((__bridge NSDictionary*)result, @"result not be nil"); + XCTAssertEqual(CFDictionaryGetCount(result), 3, @"should be 3 entries"); + + XCTAssertEqual(status, 0, @"status should be 0"); + + query = [@{ + (id)kSecClass : (id)kSecClassKey, + (id)kSecAttrAccessGroup : @"com.apple.security.ckks", + (id)kSecReturnAttributes: @YES, + (id)kSecAttrSynchronizable : (id)kCFBooleanFalse, + } mutableCopy]; + + status = SecItemDelete((__bridge CFDictionaryRef)query); + XCTAssertEqual(status, 0, @"status should be 0"); +} + @end diff --git a/keychain/ot/tests/OTFollowupTests.m b/keychain/ot/tests/OTFollowupTests.m new file mode 100644 index 00000000..73897a1a --- /dev/null +++ b/keychain/ot/tests/OTFollowupTests.m @@ -0,0 +1,19 @@ +// +// OTFollowupTests.m +// OctagonTests +// + +#import +#import +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ot/OTFollowup.h" + +@interface OTFollowupTests : XCTestCase +@end + +@implementation OTFollowupTests + +- (void)testPostCFUFollowup { +} + +@end diff --git a/keychain/ot/tests/OTLocalStoreTests.m b/keychain/ot/tests/OTLocalStoreTests.m index 1fe81114..10adeedd 100644 --- a/keychain/ot/tests/OTLocalStoreTests.m +++ b/keychain/ot/tests/OTLocalStoreTests.m @@ -222,9 +222,9 @@ static NSString* const testDSID = @"123456789"; record2.escrowRecordID = escrowRecordID2; record3.escrowRecordID = escrowRecordID3; - record.escrowedSigningSPKI = [@"escrowedSigingSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; - record2.escrowedSigningSPKI = [@"escrowedSigingSPI" dataUsingEncoding:kCFStringEncodingUTF8]; - record3.escrowedSigningSPKI = [@"escrowedSigingSPKI" dataUsingEncoding:kCFStringEncodingUTF8]; + record.escrowedSigningSPKI = [@"escrowedSigingSPKI" dataUsingEncoding:NSUTF8StringEncoding]; + record2.escrowedSigningSPKI = [@"escrowedSigingSPI" dataUsingEncoding:NSUTF8StringEncoding]; + record3.escrowedSigningSPKI = [@"escrowedSigingSPKI" dataUsingEncoding:NSUTF8StringEncoding]; XCTAssertTrue([self.localStore insertBottledPeerRecord:record escrowRecordID:escrowRecordID error:&error]); XCTAssertNil(error, @"error should be nil:%@", error); diff --git a/keychain/ot/tests/OTLockStateNetworkingTests.m b/keychain/ot/tests/OTLockStateNetworkingTests.m index b5baca36..5ddc0120 100644 --- a/keychain/ot/tests/OTLockStateNetworkingTests.m +++ b/keychain/ot/tests/OTLockStateNetworkingTests.m @@ -107,9 +107,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.spiBlockExpectation = [self expectationWithDescription:@"launch bottled peer fired"]; - NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; - - [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + [self expectAddedCKModifyRecords:@{OTCKRecordBottledPeerType: @1} holdFetch:NO]; [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; @@ -156,7 +154,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertTrue([self.context doesThisDeviceHaveABottle:&error] == UNCLEAR, @"bottle check should return unclear"); XCTAssertNotNil(error, "error should not be nil"); - XCTAssertTrue(error.code == -25308, @"error should be interaction not allowed"); + XCTAssertEqual(error.code, -25308, @"error should be interaction not allowed"); } -(void) testBottleCheckWithNoNetwork @@ -165,12 +163,9 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusAvailable; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; XCTAssertTrue([self.context doesThisDeviceHaveABottle:&error] == UNCLEAR, @"bottle check should return unclear"); - XCTAssertTrue(error.code == OTErrorNoNetwork, @"should have returned no network error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, @"should have returned no network error"); } -(void) testBottleCheckWhenNotSignedIn @@ -180,12 +175,74 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusNoAccount; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - XCTAssertTrue([self.context doesThisDeviceHaveABottle:&error] == UNCLEAR, @"bottle check should return unclear"); - XCTAssertTrue(error.code == OTErrorNotSignedIn, @"should have returned not signed in error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, @"should have returned not signed in error"); +} + +//Bottle Update tests +-(void)testBottleUpdateNotSignedIn +{ + self.spiBlockExpectation = [self expectationWithDescription:@"handle identity change spis fired"]; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + + self.accountStatus = CKAccountStatusNoAccount; + + [self startCKKSSubsystem]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + [self.spiBlockExpectation fulfill]; + XCTAssertTrue(result == NO, @"should return NO"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, @"should have returned not signed in error"); + }]; + [self waitForExpectationsWithTimeout:1.0 handler:nil]; } +-(void) testBottleUpdateWithNoNetwork +{ + self.accountStatus = CKAccountStatusAvailable; + [self startCKKSSubsystem]; + + [self.reachabilityTracker setNetworkReachability:false]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + XCTAssertEqual(error.code, OTErrorNoNetwork, @"should have returned OTErrorNoNetwork in error"); + }]; +} + +-(void) testBottleUpdateWhenLocked +{ + self.aksLockState = true; + [self.lockStateTracker recheck]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + XCTAssertEqual(error.code, errSecInteractionNotAllowed, @"should have returned errSecInteractionNotAllowed in error"); + }]; +} //Preflight tests -(void)testPreflightNotSignedIn @@ -198,8 +255,6 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self.otControl preflightBottledPeer:testContextID dsid:testDSID reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { @@ -207,7 +262,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "entropy should not be nil"); XCTAssertNil(bottleID, "bottle id should not be nil"); XCTAssertNil(signingPublicKey, "signing pub key should not be nil"); - XCTAssertTrue(error.code == OTErrorNotSignedIn, @"should have returned not signed in error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, @"should have returned not signed in error"); }]; [self waitForExpectationsWithTimeout:1.0 handler:nil]; @@ -219,10 +274,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusAvailable; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; [self.otControl preflightBottledPeer:testContextID dsid:testDSID @@ -231,7 +283,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "entropy should not be nil"); XCTAssertNil(bottleID, "bottle id should not be nil"); XCTAssertNil(signingPublicKey, "signing pub key should not be nil"); - XCTAssertTrue(error.code == OTErrorNoNetwork, @"should have returned OTErrorNoNetwork in error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, @"should have returned OTErrorNoNetwork in error"); }]; } @@ -248,7 +300,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "entropy should not be nil"); XCTAssertNil(bottleID, "bottle id should not be nil"); XCTAssertNil(signingPublicKey, "signing pub key should not be nil"); - XCTAssertTrue(error.code == errSecInteractionNotAllowed, @"should have returned errSecInteractionNotAllowed in error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, @"should have returned errSecInteractionNotAllowed in error"); }]; } @@ -261,9 +313,6 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self startCKKSSubsystem]; - [self.enroll.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self.context.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; [self.otControl preflightBottledPeer:OTDefaultContext @@ -273,22 +322,19 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "shouldn't return any entropy"); XCTAssertNil(bottleID, "shouldn't return a bottle ID"); XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); - XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; NSString* localBottleID = @"random bottle id"; [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -300,10 +346,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusAvailable; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; [self startCKKSSubsystem]; @@ -316,23 +359,20 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "shouldn't return any entropy"); XCTAssertNil(bottleID, "shouldn't return a bottle ID"); XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); - XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; NSString* localBottleID = @"random bottle id"; [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -355,23 +395,20 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "shouldn't return any entropy"); XCTAssertNil(bottleID, "shouldn't return a bottle ID"); XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); - XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; self.spiBlockExpectation = [self expectationWithDescription:@"launch SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; NSString* localBottleID = @"random bottle id"; [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -384,10 +421,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusNoAccount; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl preflightBottledPeer:testContextID dsid:testDSID @@ -396,21 +430,19 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "entropy should be nil"); XCTAssertNil(bottleID, "bottle id should be nil"); XCTAssertNil(signingPublicKey, "signing pub key should be nil"); - XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); }]; [self waitForExpectationsWithTimeout:1.0 handler:nil]; __block NSString* localBottleID = @"random bottle id"; self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; @@ -421,15 +453,12 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self setUpRampRecordsInCloudKitWithFeatureOn]; self.accountStatus = CKAccountStatusAvailable; - [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + [self.reachabilityTracker setNetworkReachability:false]; - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl preflightBottledPeer:testContextID dsid:testDSID @@ -438,21 +467,19 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "entropy should be nil"); XCTAssertNil(bottleID, "bottle id should be nil"); XCTAssertNil(signingPublicKey, "signing pub key should be nil"); - XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); }]; [self waitForExpectationsWithTimeout:1.0 handler:nil]; __block NSString* localBottleID = @"random bottle id"; self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -464,8 +491,9 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.aksLockState = true; [self.lockStateTracker recheck]; + [self startCKKSSubsystem]; + self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl preflightBottledPeer:testContextID dsid:testDSID @@ -474,21 +502,19 @@ static NSString* OTCKRecordPeerID = @"peerID"; XCTAssertNil(entropy, "entropy should be nil"); XCTAssertNil(bottleID, "bottle id should be nil"); XCTAssertNil(signingPublicKey, "signing pub key should be nil"); - XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); }]; [self waitForExpectationsWithTimeout:1.0 handler:nil]; __block NSString* localBottleID = @"random bottle id"; self.spiBlockExpectation = [self expectationWithDescription:@"scrub bottled peer SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -499,12 +525,10 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self setUpRampRecordsInCloudKitWithFeatureOn]; self.accountStatus = CKAccountStatusNoAccount; - [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl restore:testContextID dsid:testDSID @@ -514,9 +538,8 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self.spiBlockExpectation fulfill]; XCTAssertNil(signingKeyData, "Signing key data should be nil"); XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); - XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; @@ -527,15 +550,12 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self setUpRampRecordsInCloudKitWithFeatureOn]; self.accountStatus = CKAccountStatusAvailable; - [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; + [self.reachabilityTracker setNetworkReachability:false]; - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl restore:testContextID dsid:testDSID @@ -545,9 +565,8 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self.spiBlockExpectation fulfill]; XCTAssertNil(signingKeyData, "Signing key data should be nil"); XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); - XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -559,8 +578,9 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.aksLockState = true; [self.lockStateTracker recheck]; + [self startCKKSSubsystem]; + self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; - self.expectation = [self expectationWithDescription:@"ramp scheduler fired"]; [self.otControl restore:testContextID dsid:testDSID @@ -570,9 +590,8 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self.spiBlockExpectation fulfill]; XCTAssertNil(signingKeyData, "Signing key data should be nil"); XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); - XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); }]; - [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } @@ -588,11 +607,9 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusNoAccount; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; - XCTAssertTrue(error.code == OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); + XCTAssertEqual(error.code, OTErrorNotSignedIn, "should return a OTErrorNotSignedIn error"); } @@ -606,14 +623,11 @@ static NSString* OTCKRecordPeerID = @"peerID"; self.accountStatus = CKAccountStatusAvailable; [self startCKKSSubsystem]; - [self.accountStateTracker notifyCKAccountStatusChangeAndWaitForSignal]; - - self.reachabilityFlags = 0; - [self.reachabilityTracker recheck]; + [self.reachabilityTracker setNetworkReachability:false]; [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; - XCTAssertTrue(error.code == OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); + XCTAssertEqual(error.code, OTErrorNoNetwork, "should return a OTErrorNoNetwork error"); } -(void) testEnrollRampWhenLocked @@ -628,7 +642,7 @@ static NSString* OTCKRecordPeerID = @"peerID"; [self.enroll checkRampState:&retryAfter networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&error]; - XCTAssertTrue(error.code == errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); + XCTAssertEqual(error.code, errSecInteractionNotAllowed, "should return a errSecInteractionNotAllowed error"); } -(void) testTimeBetweenCFUAttempts @@ -637,13 +651,20 @@ static NSString* OTCKRecordPeerID = @"peerID"; NSError* error = nil; + [self startCKKSSubsystem]; + [self.manager scheduledCloudKitRampCheck:&error]; + XCTAssertNotNil(error, "Should have had an error scheduling a ramp check"); + XCTAssertEqual(error.code, OTErrorNoBottlePeerRecords, "Error should be 'no bottled peer records'"); XCTAssertNotNil(self.manager.lastPostedCoreFollowUp, "core followup should have been posted"); NSDate* firstTime = self.manager.lastPostedCoreFollowUp; sleep(2); + error = nil; [self.manager scheduledCloudKitRampCheck:&error]; + XCTAssertNotNil(error, "Should have had an error scheduling a ramp check"); + XCTAssertEqual(error.code, OTErrorNoBottlePeerRecords, "Error should be 'no bottled peer records'"); XCTAssertNotNil(self.manager.lastPostedCoreFollowUp, "core followup should have been posted"); NSDate* secondTime = self.manager.lastPostedCoreFollowUp; diff --git a/keychain/ot/tests/OTRampingTests.m b/keychain/ot/tests/OTRampingTests.m index fc205e49..63e76f81 100644 --- a/keychain/ot/tests/OTRampingTests.m +++ b/keychain/ot/tests/OTRampingTests.m @@ -68,9 +68,64 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; } +-(void) testBottleUpdateWithFeatureOnOn +{ + __block NSData* localEntropy = nil; + __block NSString* localBottleID = nil; + + [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; + + [self startCKKSSubsystem]; + + //create a bottle + [self.otControl preflightBottledPeer:testContextID + dsid:testDSID + reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { + localEntropy = entropy; + localBottleID = bottleID; + XCTAssertNotNil(entropy, "entropy should not be nil"); + XCTAssertNotNil(bottleID, "bottle id should not be nil"); + XCTAssertNotNil(signingPublicKey, "signing pub key should not be nil"); + XCTAssertNil(error, "error should be nil"); + }]; + + NSMutableDictionary* recordDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:[[NSNumber alloc] initWithInt:1], OTCKRecordBottledPeerType, nil]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + //launch it + [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { + XCTAssertNil(error, "error should be nil"); + }]; + + [self waitForCKModifications]; + OCMVerifyAllWithDelay(self.mockDatabase, 8); + [self releaseCloudKitFetchHold]; + + [self expectCKFetch]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + [self expectAddedCKModifyRecords:recordDictionary holdFetch:NO]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + XCTAssertNil(error, "error should be nil"); + }]; +} + -(void) testLaunchWithRampOn { [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; __block NSData* localEntropy = nil; @@ -108,6 +163,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testRestoreWithRampOn { [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; __block NSData* localEntropy = nil; @@ -156,6 +213,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testScrubWithRampOn { [self setUpRampRecordsInCloudKitWithFeatureOn]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; __block NSString* localBottleID = nil; @@ -192,7 +251,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testPreflightWithRampOff { [self setUpRampRecordsInCloudKitWithFeatureOff]; - + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; @@ -204,15 +264,39 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; XCTAssertNil(entropy, "shouldn't return any entropy"); XCTAssertNil(bottleID, "shouldn't return a bottle ID"); XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); - XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); }]; [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); [self waitForExpectationsWithTimeout:1.0 handler:nil]; } +-(void) testBottleUpdateWithFeatureOff +{ + [self setUpRampRecordsInCloudKitWithFeatureOff]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; + [self startCKKSSubsystem]; + + SFECKeyPair* newSigningKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + SFECKeyPair* newEncryptionKey = [[SFECKeyPair alloc] initRandomKeyPairWithSpecifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384]]; + + //update bottle + [self.otControl handleIdentityChangeForSigningKey:newSigningKey + ForEncryptionKey:newEncryptionKey + ForPeerID:self.sosPeerID + reply:^(BOOL result, NSError* _Nullable error){ + XCTAssertNotNil(error, "error should be nil"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + }]; + +} + -(void) testPreflightWithRecordNotThere { + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; @@ -234,7 +318,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testLaunchWithRampOff { [self setUpRampRecordsInCloudKitWithFeatureOff]; - + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer fired"]; @@ -246,7 +331,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; XCTAssertNil(entropy, "shouldn't return any entropy"); XCTAssertNil(bottleID, "shouldn't return a bottle ID"); XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); - XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); }]; [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); @@ -258,7 +343,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; NSString* localBottleID = @"random bottle id"; [self.otControl launchBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); }]; [self waitForCKModifications]; @@ -268,6 +353,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testRestoreWithRampOff { [self setUpRampRecordsInCloudKitWithFeatureOff]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"restore SPI fired"]; @@ -280,7 +367,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; [self.spiBlockExpectation fulfill]; XCTAssertNil(signingKeyData, "Signing key data should be nil"); XCTAssertNil(encryptionKeyData, "encryption key data should be nil"); - XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); }]; [self waitForCKModifications]; OCMVerifyAllWithDelay(self.mockDatabase, 8); @@ -290,6 +377,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testScrubWithRampOff { [self setUpRampRecordsInCloudKitWithFeatureOff]; + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; self.spiBlockExpectation = [self expectationWithDescription:@"preflight bottled peer SPI fired"]; @@ -301,7 +390,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; XCTAssertNil(entropy, "entropy should be nil"); XCTAssertNil(bottleID, "bottle id should be nil"); XCTAssertNil(signingPublicKey, "signing pub key should be nil"); - XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); }]; [self waitForExpectationsWithTimeout:1.0 handler:nil]; @@ -311,7 +400,7 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; [self.otControl scrubBottledPeer:testContextID bottleID:localBottleID reply:^(NSError * _Nullable error) { [self.spiBlockExpectation fulfill]; - XCTAssertTrue(error.code == OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); + XCTAssertEqual(error.code, OTErrorFeatureNotEnabled, "should return a OTErrorFeatureNotEnabled error"); }]; [self waitForCKModifications]; @@ -326,6 +415,8 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; -(void) testRampFetchTimeout { + [self createAndSaveFakeKeyHierarchy:self.keychainZoneID]; + [self putSelfTLKSharesInCloudKit:self.keychainZoneID]; [self startCKKSSubsystem]; __block NSError* localError = nil; @@ -339,36 +430,42 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; XCTAssertNil(entropy, "shouldn't return any entropy"); XCTAssertNil(bottleID, "shouldn't return a bottle ID"); XCTAssertNil(signingPublicKey, "shouldn't return a signingPublicKey"); - XCTAssertTrue(error.code == OTErrorCKTimeOut, "should return a OTErrorCKTimeout error"); + XCTAssertEqual(error.code, OTErrorCKTimeOut, "should return a OTErrorCKTimeout error"); }]; } -(void)testCFUWithRampOn { NSError* localError = nil; - NSInteger retryAfterInSeconds = 0; [self setUpRampRecordsInCloudKitWithFeatureOn]; - XCTAssertTrue([self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be true"); + [self startCKKSSubsystem]; + + XCTAssertTrue([self.cfu checkRampStateWithError:&localError], @"should be true"); + XCTAssertNil(localError, "Should not have gotten an error checking ramp state (and getting true)"); } -(void)testCFUWithRampOff { NSError* localError = nil; - NSInteger retryAfterInSeconds = 0; [self setUpRampRecordsInCloudKitWithFeatureOff]; - XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be false"); + [self startCKKSSubsystem]; - XCTAssertTrue(retryAfterInSeconds != 0, @"should be asked to retry later"); + XCTAssertFalse([self.cfu checkRampStateWithError:&localError], @"should be false"); + XCTAssertNil(localError, "Should not have gotten an error checking ramp state (and getting false)"); } -(void)testCFUWithNonExistentRampRecord { NSError* localError = nil; - NSInteger retryAfterInSeconds = 0; - XCTAssertTrue(![self.cfu checkRampState:&retryAfterInSeconds networkBehavior:CKOperationDiscretionaryNetworkBehaviorNonDiscretionary error:&localError], @"should be false"); + + [self startCKKSSubsystem]; + + XCTAssertFalse([self.cfu checkRampStateWithError:&localError], @"should be false"); + XCTAssertNotNil(localError, "Should have gotten an error checking ramp state (and getting false)"); + XCTAssertEqual(localError.code, OTErrorRecordNotFound, "Error should be 'record not found'"); } @end diff --git a/keychain/ot/tests/OTTestsBase.h b/keychain/ot/tests/OTTestsBase.h index f50be97e..6c5a3e0c 100644 --- a/keychain/ot/tests/OTTestsBase.h +++ b/keychain/ot/tests/OTTestsBase.h @@ -29,17 +29,24 @@ #import #import #import - #import "keychain/ot/OTContext.h" +#import "keychain/ot/OTJoiningConfiguration.h" #import "keychain/ot/OTEscrowKeys.h" #import "keychain/ot/OTDefines.h" #import "keychain/ot/OTControl.h" #import "keychain/ot/OTManager.h" -#import "SFPublicKey+SPKI.h" -#import +#import "keychain/ot/OTClique.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OTClientStateMachine.h" +#import "KeychainCircle/KCJoiningRequestSession+Internal.h" +#import "KeychainCircle/KCJoiningAcceptSession+Internal.h" +#import "KeychainCircle/KCJoiningSession.h" +#import +#import #import #import +#include "keychain/SecureObjectSync/SOSPeerInfoInternal.h" #import "keychain/ckks/tests/CloudKitKeychainSyncingTestsBase.h" #import "keychain/ckks/tests/CloudKitMockXCTest.h" @@ -48,11 +55,20 @@ #import "keychain/ckks/CKKS.h" #import "keychain/ckks/CKKSViewManager.h" +#import +#import +#import + NS_ASSUME_NONNULL_BEGIN @interface OTTestsBase : CloudKitKeychainSyncingTestsBase @property id otControl; +@property id otControlAcceptor; + + @property OTManager* manager; +@property OTManager* managerForAcceptor; + @property (nonatomic, strong) OTCloudStore* cloudStore; @property (nonatomic, strong) OTLocalStore* localStore; @property (nonatomic, strong) FakeCKZone* otFakeZone; @@ -66,6 +82,9 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong) NSString* sosPeerID; @property (nonatomic, strong) OTEscrowKeys* escrowKeys; +// Manager-owned cuttlefish context +@property OTCuttlefishContext* cuttlefishContext; + @property (nonatomic, strong) FakeCKZone* rampZone; @property (nonatomic, strong) CKRecord *enrollRampRecord; @property (nonatomic, strong) CKRecord *restoreRampRecord; @@ -80,10 +99,14 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, strong) CKRecordZoneID* rampZoneID; --(OTRamp*) fakeRamp:(NSString*)recordName featureName:(NSString*)featureName; +- (OTRamp*)fakeRamp:(NSString*)recordName + featureName:(NSString*)featureName + accountTracker:(CKKSAccountStateTracker*)accountTracker + lockStateStracker:(CKKSLockStateTracker*)lockStateTracker +reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker; --(void)expectAddedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch; --(void)expectDeletedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch; +-(void) expectAddedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch; +-(void) expectDeletedCKModifyRecords:(NSDictionary*)records holdFetch:(BOOL)shouldHoldTheFetch; -(void) setUpRampRecordsInCloudKitWithFeatureOn; -(void) setUpRampRecordsInCloudKitWithFeatureOff; diff --git a/keychain/ot/tests/OTTestsBase.m b/keychain/ot/tests/OTTestsBase.m index 63345a33..6c85dbf7 100644 --- a/keychain/ot/tests/OTTestsBase.m +++ b/keychain/ot/tests/OTTestsBase.m @@ -24,9 +24,13 @@ #if OCTAGON #import "OTTestsBase.h" +#import "keychain/ot/OTSOSAdapter.h" static NSString* const testContextID = @"Foo"; +static NSString* const testContextForAcceptor = @"Acceptor"; + static NSString* const testDSID = @"123456789"; + static int _test_num = 0; static NSString* _path; static NSString* _dbPath; @@ -116,9 +120,21 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; self.rampZone = [[FakeCKZone alloc]initZone:self.rampZoneID]; self.zones[self.rampZoneID] = self.rampZone; - self.cfu = [self fakeRamp:kOTRampForCFURecordName featureName:@"FAKE-cfu"]; - self.enroll = [self fakeRamp:kOTRampForEnrollmentRecordName featureName:@"FAKE-enroll"]; - self.restore = [self fakeRamp:kOTRampForRestoreRecordName featureName:@"FAKE-restore"]; + self.cfu = [self fakeRamp:kOTRampForCFURecordName + featureName:@"FAKE-cfu" + accountTracker:self.accountStateTracker + lockStateStracker:self.lockStateTracker + reachabilityTracker:self.reachabilityTracker]; + self.enroll = [self fakeRamp:kOTRampForEnrollmentRecordName + featureName:@"FAKE-enroll" + accountTracker:self.accountStateTracker + lockStateStracker:self.lockStateTracker + reachabilityTracker:self.reachabilityTracker]; + self.restore = [self fakeRamp:kOTRampForRestoreRecordName + featureName:@"FAKE-restore" + accountTracker:self.accountStateTracker + lockStateStracker:self.lockStateTracker + reachabilityTracker:self.reachabilityTracker]; self.scheduler = [[CKKSNearFutureScheduler alloc] initWithName: @"test" delay:50*NSEC_PER_MSEC keepProcessAlive:true dependencyDescriptionCode:CKKSResultDescriptionNone @@ -130,34 +146,25 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; enroll:self.enroll restore:self.restore cfu:self.cfu - cfuScheduler:self.scheduler]; + cfuScheduler:self.scheduler + sosAdapter:[[OTSOSActualAdapter alloc] init] + authKitAdapter:[[OTAuthKitActualAdapter alloc] init] + apsConnectionClass:[FakeAPSConnection class]]; + [OTManager resetManager:true to:self.manager]; + + self.cuttlefishContext = [self.manager contextForContainerName:OTCKContainerName + contextID:OTDefaultContext]; id mockConnection = OCMPartialMock([[NSXPCConnection alloc] init]); OCMStub([mockConnection remoteObjectProxyWithErrorHandler:[OCMArg any]]).andCall(self, @selector(manager)); - self.otControl = [[OTControl alloc] initWithConnection:mockConnection]; + self.otControl = [[OTControl alloc] initWithConnection:mockConnection sync:true]; XCTAssertNotNil(self.otControl, "Should have received control object"); - [self startCKKSSubsystem]; - - self.accountStatus = CKAccountStatusAvailable; - self.circleStatus = [[SOSAccountStatus alloc] init:kSOSCCInCircle error:nil]; - [self.cfu.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; - - [self.context.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self.enroll.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; - [self.restore.accountTracker notifyCKAccountStatusChangeAndWaitForSignal]; - - [self.context.accountTracker notifyCircleStatusChangeAndWaitForSignal]; - [self.cfu.accountTracker notifyCircleStatusChangeAndWaitForSignal]; - [self.enroll.accountTracker notifyCircleStatusChangeAndWaitForSignal]; - [self.restore.accountTracker notifyCircleStatusChangeAndWaitForSignal]; - - self.reachabilityFlags = kSCNetworkReachabilityFlagsReachable; + [self.reachabilityTracker setNetworkReachability:true]; [self.context.reachabilityTracker recheck]; [self.cfu.reachabilityTracker recheck]; [self.enroll.reachabilityTracker recheck]; [self.restore.reachabilityTracker recheck]; - } @@ -187,7 +194,11 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; [super tearDown]; } --(OTRamp*) fakeRamp:(NSString*)recordName featureName:(NSString*)featureName +- (OTRamp*)fakeRamp:(NSString*)recordName + featureName:(NSString*)featureName + accountTracker:(CKKSAccountStateTracker*)accountTracker + lockStateStracker:(CKKSLockStateTracker*)lockStateTracker +reachabilityTracker:(CKKSReachabilityTracker*)reachabilityTracker { OTRamp* ramp = [[OTRamp alloc]initWithRecordName:recordName @@ -195,9 +206,9 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; container:self.mockContainer database:self.mockDatabase zoneID:self.rampZoneID - accountTracker:[CKKSViewManager manager].accountTracker - lockStateTracker:[CKKSViewManager manager].lockStateTracker - reachabilityTracker:[CKKSViewManager manager].reachabilityTracker + accountTracker:accountTracker + lockStateTracker:lockStateTracker + reachabilityTracker:reachabilityTracker fetchRecordRecordsOperationClass:self.mockFakeCKFetchRecordsOperation]; return ramp; @@ -276,7 +287,10 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; } runAfterModification:^{ __strong __typeof(self) strongSelf = weakSelf; - [strongSelf holdCloudKitFetches]; + if(shouldHoldTheFetch){ + [strongSelf holdCloudKitFetches]; + } + } ]; } @@ -297,7 +311,9 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; } runAfterModification:^{ __strong __typeof(self) strongSelf = weakSelf; - [strongSelf holdCloudKitFetches]; + if(shouldHoldTheFetch){ + [strongSelf holdCloudKitFetches]; + } } ]; } @@ -306,6 +322,5 @@ static NSString* OTCKRecordBottledPeerType = @"OTBottledPeer"; return [[OTIdentity alloc]initWithPeerID:self.egoPeerID spID:self.sosPeerID peerSigningKey:self.peerSigningKey peerEncryptionkey:self.peerEncryptionKey error:error]; } - @end #endif diff --git a/keychain/ot/tests/gen_test_plist.py b/keychain/ot/tests/gen_test_plist.py new file mode 100644 index 00000000..2b01e9a4 --- /dev/null +++ b/keychain/ot/tests/gen_test_plist.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# +# TODO(kirk or SEAR/QA) after radar 53867279 is fixed, please delete this script +# +# WARNING: if you add new tests to the swift octagon tests, it is possible that +# this script will not find them and then your new tests will not get executed +# in BATS! +# +import sys +import Foundation +from glob import glob +import re +import os + +test_dir = sys.argv[1] +outfile = sys.argv[2] + +test_plist = Foundation.NSMutableDictionary.dictionary() +test_plist['BATSConfigVersion'] = '0.1.0' +test_plist['Project'] = 'Security' +test_list = Foundation.NSMutableArray.array() + +test_files = glob(test_dir + '/octagon/*.swift') + glob(test_dir + '/octagon/*/*.swift') + +def get_class_names(): + test_classes = ['OTFollowupTests'] + for filename in test_files: + f = open(filename, 'r') + for line in f: + match = re.search('class (([a-zA-Z0-9_]+Tests)|(OctagonTests[a-zA-Z0-9_]*(?!) -> Error! { + results.pointee = [ + "bottleID": self.bottleID, + "bottleValid": "valid", + "EscrowServiceEscrowData" : ["BottledPeerEntropy": entropy], + ] + return nil + } +} + +class OTMockFollowUpController: NSObject, OctagonFollowUpControllerProtocol { + var postedFollowUp : Bool = false + + override init() { + super.init() + } + + func postFollowUp(with context: CDPFollowUpContext) throws { + self.postedFollowUp = true + } + + func clearFollowUp(with context: CDPFollowUpContext) throws { + } +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTests+CKKS.swift b/keychain/ot/tests/octagon/OctagonTests+CKKS.swift new file mode 100644 index 00000000..40299eab --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+CKKS.swift @@ -0,0 +1,69 @@ +#if OCTAGON + +class OctagonCKKSTests: OctagonTestsBase { + func testHandleCKKSKeyHierarchyConflictOnEstablish() throws { + self.startCKAccountStatusMock() + + // Right after CKKS fetches for the first time, insert a new key hierarchy into CloudKit + self.silentFetchesAllowed = false + self.expectCKFetchAndRun(beforeFinished: { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + self.silentFetchesAllowed = true + }) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter waitfortlk, as they don't have the TLKs uploaded by the other peer + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testHandleCKKSKeyHierarchyConflictOnEstablishWithKeys() throws { + self.startCKAccountStatusMock() + + // Right after CKKS fetches for the first time, insert a new key hierarchy into CloudKit + self.silentFetchesAllowed = false + self.expectCKFetchAndRun(beforeFinished: { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + self.silentFetchesAllowed = true + }) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + } +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTests+CloudKitAccount.swift b/keychain/ot/tests/octagon/OctagonTests+CloudKitAccount.swift new file mode 100644 index 00000000..8d4c26c4 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+CloudKitAccount.swift @@ -0,0 +1,186 @@ +#if OCTAGON + +class OctagonCloudKitAccountTests: OctagonTestsBase { + func testSignInSucceedsAfterCloudKitNotification() throws { + // Device is signed out + self.mockAuthKit.altDSID = nil + + // but CK is going to win the race, and tell us everything is fine first + self.accountStatus = .available + self.startCKAccountStatusMock() + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // Account sign in occurs + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // We should reach 'untrusted', as we cached the CK value + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + } + + func testSignInPausesForCloudKit() throws { + // Device is signed out + self.mockAuthKit.altDSID = nil + + // And out of cloudkit + self.accountStatus = .noAccount + self.startCKAccountStatusMock() + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // And CKKS should be in 'loggedout' + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + + // Account sign in occurs + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // Octagon should go into 'wait for cloudkit account' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitingForCloudKitAccount, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + + // And when CK shows up, we should go into 'untrusted' + self.accountStatus = .available + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + // sign-out CK first: + self.accountStatus = .noAccount + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitingForCloudKitAccount, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + + // On sign-out, octagon should go back to 'no account' + self.mockAuthKit.altDSID = nil + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "sign-out shouldn't error") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + // and CKKS is still in 'loggedout' + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + } + + func testSignOutFromWaitingForCloudKit() { + // Device is signed out + self.mockAuthKit.altDSID = nil + + // And out of cloudkit + self.accountStatus = .noAccount + self.startCKAccountStatusMock() + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // Account sign in occurs + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // Octagon should go into 'wait for cloudkit account' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitingForCloudKitAccount, within: 10 * NSEC_PER_SEC) + + // On sign-out, octagon should go back to 'no account' + self.mockAuthKit.altDSID = nil + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "sign-out shouldn't error") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + } + + func testCloudKitAccountDisappears() { + // Device is signed out + self.mockAuthKit.altDSID = nil + + // And out of cloudkit + self.accountStatus = .noAccount + self.startCKAccountStatusMock() + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // Account sign in occurs + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // Octagon should go into 'wait for cloudkit account' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitingForCloudKitAccount, within: 10 * NSEC_PER_SEC) + + // And when CK shows up, we should go into 'untrusted' + self.accountStatus = .available + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // On CK account sign-out, Octagon should go back to 'wait for cloudkit account' + self.accountStatus = .noAccount + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitingForCloudKitAccount, within: 10 * NSEC_PER_SEC) + + self.mockAuthKit.altDSID = nil + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "sign-out shouldn't error") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + } + + func testSignOutOfSAAccount() throws { + self.startCKAccountStatusMock() + + // Device is signed out + self.mockAuthKit.altDSID = nil + self.mockAuthKit.hsa2 = false + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // CloudKit sign in occurs, but HSA2 status isn't here yet + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // Octagon should go into 'waitforhsa2' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForHSA2, within: 10 * NSEC_PER_SEC) + + XCTAssertNoThrow(try self.cuttlefishContext.idmsTrustLevelChanged(), "Notification of IDMS trust level shouldn't error") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForHSA2, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + + // On CK account sign-out, Octagon should go back to 'wait for cloudkit account' + self.accountStatus = .noAccount + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitingForCloudKitAccount, within: 10 * NSEC_PER_SEC) + + // On sign-out, octagon should go back to 'no account' + self.mockAuthKit.altDSID = nil + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "sign-out shouldn't error") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + } +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTests+CoreFollowUp.swift b/keychain/ot/tests/octagon/OctagonTests+CoreFollowUp.swift new file mode 100644 index 00000000..87e68aba --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+CoreFollowUp.swift @@ -0,0 +1,276 @@ + +#if OCTAGON + +class OctagonCoreFollowUpTests: OctagonTestsBase { + func testAttemptedJoinStateAttempted() throws { + self.startCKAccountStatusMock() + + // Prepare an identity, then pretend like securityd thought it was in the right account + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + var selfPeerID: String? + let prepareExpectation = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: contextName, + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + selfPeerID = peerID + + prepareExpectation.fulfill() + } + self.wait(for: [prepareExpectation], timeout: 10) + + let account = OTAccountMetadataClassC()! + account.peerID = selfPeerID + account.icloudAccountState = .ACCOUNT_AVAILABLE + account.trustState = .TRUSTED + account.attemptedJoin = .ATTEMPTED + + XCTAssertNoThrow(try account.saveToKeychain(forContainer: containerName, contextID: contextName), "Should be no error saving fake account metadata") + + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // CKKS should be waiting for assistance + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + #if !os(tvOS) + XCTAssertTrue(self.cuttlefishContext.postedRepairCFU, "should have posted an repair CFU"); + #else + // Apple TV should not post a CFU, as there's no peers to join + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "appleTV should not have posted a repair CFU"); + #endif + } + + func testAttemptedJoinNotAttemptedStateSOSEnabled() throws { + self.startCKAccountStatusMock() + + // Prepare an identity, then pretend like securityd thought it was in the right account + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + var selfPeerID: String? + let prepareExpectation = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: contextName, + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + selfPeerID = peerID + + prepareExpectation.fulfill() + } + self.wait(for: [prepareExpectation], timeout: 10) + + let account = OTAccountMetadataClassC()! + account.peerID = selfPeerID + account.icloudAccountState = .ACCOUNT_AVAILABLE + account.trustState = .TRUSTED + account.attemptedJoin = .NOTATTEMPTED + + XCTAssertNoThrow(try account.saveToKeychain(forContainer: containerName, contextID: contextName), "Should be no error saving fake account metadata") + + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // CKKS should be waiting for assistance + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "should NOT have posted an repair CFU"); + } + + func testAttemptedJoinNotAttemptedStateSOSDisabled() throws { + self.startCKAccountStatusMock() + // Octagon only examines the JoinState if SOS is enabled + self.mockSOSAdapter.sosEnabled = false + + // No need to mock not joining; Octagon won't have attempted a join if we just start it + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // CKKS should be waiting for assistance + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + #if !os(tvOS) + XCTAssertTrue(self.cuttlefishContext.postedRepairCFU, "should have posted an repair CFU, as SOS is disabled"); + #else + // Apple TV should not post a CFU, as there's no peers to join + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "appleTV should not have posted a repair CFU"); + #endif + } + + func testAttemptedJoinStateUnknown() throws { + self.startCKAccountStatusMock() + + // Prepare an identity, then pretend like securityd thought it was in the right account + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + var selfPeerID: String? + let prepareExpectation = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: contextName, + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + selfPeerID = peerID + + prepareExpectation.fulfill() + } + self.wait(for: [prepareExpectation], timeout: 10) + + let account = OTAccountMetadataClassC()! + account.peerID = selfPeerID + account.icloudAccountState = .ACCOUNT_AVAILABLE + account.trustState = .TRUSTED + account.attemptedJoin = .UNKNOWN + + XCTAssertNoThrow(try account.saveToKeychain(forContainer: containerName, contextID: contextName), "Should be no error saving fake account metadata") + + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // CKKS should be waiting for assistance + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + #if !os(tvOS) + XCTAssertTrue(self.cuttlefishContext.postedRepairCFU, "should have posted an repair CFU"); + #else + // Apple TV should not post a CFU, as there's no peers to join + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "appleTV should not have posted a repair CFU"); + #endif + } + + #if os(tvOS) + func testPostCFUWhenApprovalCapablePeerJoins() throws { + self.startCKAccountStatusMock() + // Octagon only examines the JoinState if SOS is enabled + self.mockSOSAdapter.sosEnabled = false + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + // Apple TV should not post a CFU, as there's no peers to join + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "appleTV should not have posted a repair CFU"); + + // Now, an iphone appears! + let iphone = self.manager.context(forContainerName: OTCKContainerName, + contextID: "asdf", + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + iphone.startOctagonStateMachine() + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablishExpectation returns") + iphone.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "should be no error resetting and establishing") + resetAndEstablishExpectation.fulfill() + } + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + + self.sendContainerChangeWaitForUntrustedFetch(context: self.cuttlefishContext) + + // The TV should now post a CFU, as there's an iphone that can repair it + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + XCTAssertTrue(self.cuttlefishContext.postedRepairCFU, "appleTV should have posted a repair CFU"); + } + + func testDontPostCFUWhenApprovalIncapablePeerJoins() throws { + self.startCKAccountStatusMock() + // Octagon only examines the JoinState if SOS is enabled + self.mockSOSAdapter.sosEnabled = false + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + // Apple TV should not post a CFU, as there's no peers to join + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "appleTV should not have posted a repair CFU"); + + // Now, a mac appears! macs cannot fix apple TVs. + let mac = self.manager.context(forContainerName: OTCKContainerName, + contextID: "asdf", + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iMac7,1", deviceName: "test-mac", serialNumber: "456", osVersion: "macOS (fake version)")) + mac.startOctagonStateMachine() + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablishExpectation returns") + mac.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "should be no error resetting and establishing") + resetAndEstablishExpectation.fulfill() + } + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + + self.sendContainerChangeWaitForUntrustedFetch(context: self.cuttlefishContext) + + // The TV should not post a CFU, as there's still no iPhone to repair it + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + XCTAssertFalse(self.cuttlefishContext.postedRepairCFU, "appleTV should not have posted a repair CFU; no devices present can repair it"); + } + #endif +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTests+DeviceList.swift b/keychain/ot/tests/octagon/OctagonTests+DeviceList.swift new file mode 100644 index 00000000..f601b5f6 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+DeviceList.swift @@ -0,0 +1,514 @@ +#if OCTAGON + +class OctagonDeviceListTests: OctagonTestsBase { + func testSignInFailureBecauseUntrustedDevice() throws { + // Check that we honor IdMS trusted device list that we got and reject device that + // are not it + + self.startCKAccountStatusMock() + + // Must positively assert some device in list, so that the machine ID list isn't empty + self.mockAuthKit.otherDevices.insert("some-machine-id") + self.mockAuthKit.excludeDevices.insert(try! self.mockAuthKit.machineID()) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let expectFail = self.expectation(description: "expect to fail") + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNil(clique, "Clique should be nil") + } catch { + expectFail.fulfill(); + } + + self.wait(for: [expectFail], timeout: 10) + + // Now, we should be in 'untrusted' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testSignInWithIDMSBypass() throws { + // Check that we can bypass IdMS trusted device list (needed for demo accounts) + + self.startCKAccountStatusMock() + + self.mockAuthKit.excludeDevices.formUnion(self.mockAuthKit.currentDeviceList()) + XCTAssertTrue(self.mockAuthKit.currentDeviceList().isEmpty, "should have zero devices") + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + // And we haven't helpfully added anything to the MID list + self.assertMIDList(context: self.cuttlefishContext, allowed: Set(), disallowed: Set(), unknown: Set()) + } + + func testRemovePeerWhenRemovedFromDeviceList() throws { + self.startCKAccountStatusMock() + + XCTAssert(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should already have device 2 on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let peer2ID = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, tell peer1 about the change. It will trust the peer and upload some TLK shares + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + // Then peer2 drops off the device list. Peer 1 should distrust peer2. + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertTrue(!(newDynamicInfo?.includedPeerIDs.contains(peer2ID) ?? true), "peer1 should no longer trust peer2") + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.removeAndSendNotification(machineID: try! self.mockAuthKit2.machineID()) + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .excludes, target: peer2ID)), + "peer 1 should distrust peer 2 after update") + } + + func testRemovePeerWhenRemovedFromDeviceListViaIncompleteNotification() throws { + self.startCKAccountStatusMock() + + XCTAssert(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should already have device 2 on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let peer2ID = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, tell peer1 about the change. It will trust the peer and upload some TLK shares + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + // Then peer2 drops off the device list. Peer 1 should distrust peer2. + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertTrue(!(newDynamicInfo?.includedPeerIDs.contains(peer2ID) ?? true), "peer1 should no longer trust peer2") + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.excludeDevices.insert(try! self.mockAuthKit2.machineID()) + XCTAssertFalse(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should not still have device 2 on the list") + self.mockAuthKit.sendIncompleteNotification() + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .excludes, target: peer2ID)), + "peer 1 should distrust peer 2 after update") + } + + + func testTrustPeerWhenMissingFromDeviceList() throws { + self.startCKAccountStatusMock() + + self.mockAuthKit.otherDevices.removeAll() + XCTAssertEqual(self.mockAuthKit.currentDeviceList(), Set([self.mockAuthKit.currentMachineID]), "AuthKit should have exactly one device on the list") + XCTAssertFalse(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should not already have device 2 on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let peer2ID = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, tell peer1 about the change. It will trust the peer, despite it missing from the list, and upload some TLK shares + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + self.assertMIDList(context: self.cuttlefishContext, + allowed: self.mockAuthKit.currentDeviceList(), + disallowed: Set(), + unknown: Set([self.mockAuthKit2.currentMachineID])) + + // On a follow-up update, peer1 should _not_ hit IDMS, even though there's an unknown peer ID in its DB + let currentCount = self.mockAuthKit.fetchInvocations + self.sendContainerChangeWaitForFetchForStates(context: self.cuttlefishContext, states: [OctagonStateReadyUpdated, OctagonStateReady]) + self.assertMIDList(context: self.cuttlefishContext, + allowed: self.mockAuthKit.currentDeviceList(), + disallowed: Set(), + unknown: Set([self.mockAuthKit2.currentMachineID])) + XCTAssertEqual(currentCount, self.mockAuthKit.fetchInvocations, "Receving a push while having an unknown peer MID should not cause an AuthKit fetch") + + //////// + + // Then peer2 arrives on the device list. Peer 1 should update its dynamic info to no longer have a disposition for peer2. + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + // TODO: swift refuses to see the dispositions object on newDynamicInfo; ah well + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.addAndSendNotification(machineID: try! self.mockAuthKit2.machineID()) + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + } + + func testRemoveSelfWhenRemovedFromOnlySelfList() throws { + self.startCKAccountStatusMock() + + self.mockAuthKit.otherDevices.removeAll() + XCTAssertEqual(self.mockAuthKit.currentDeviceList(), Set([self.mockAuthKit.currentMachineID]), "AuthKit should have exactly one device on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer1ID)), + "peer 1 should trust peer 1") + + // Then peer1 drops off the device list + // It should remove trust in itself + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.includedPeerIDs.count, 0, "peer1 should no longer trust anyone") + XCTAssertEqual(newDynamicInfo!.excludedPeerIDs, Set([peer1ID]), "peer1 should exclude itself") + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.removeAndSendNotification(machineID: try! self.mockAuthKit.machineID()) + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + } + + func testRemoveSelfWhenRemovedFromLargeDeviceList() throws { + self.startCKAccountStatusMock() + + XCTAssert(self.mockAuthKit.currentDeviceList().count > 1, "AuthKit should have more than one device on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer1ID)), + "peer 1 should trust peer 1") + + // Then peer1 drops off the device list + // It should remove trust in itself + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.includedPeerIDs.count, 0, "peer1 should no longer trust anyone") + XCTAssertEqual(newDynamicInfo!.excludedPeerIDs, Set([peer1ID]), "peer1 should exclude itself") + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.removeAndSendNotification(machineID: try! self.mockAuthKit.machineID()) + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + } + + func testRemoveSelfWhenRemovedFromLargeDeviceListByIncompleteNotification() throws { + self.startCKAccountStatusMock() + + XCTAssert(self.mockAuthKit.currentDeviceList().count > 1, "AuthKit should have more than one device on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer1ID)), + "peer 1 should trust peer 1") + + // Then peer1 drops off the device list + // It should remove trust in itself + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.includedPeerIDs.count, 0, "peer1 should no longer trust anyone") + XCTAssertEqual(newDynamicInfo!.excludedPeerIDs, Set([peer1ID]), "peer1 should exclude itself") + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.excludeDevices.insert(try! self.mockAuthKit.machineID()) + XCTAssertFalse(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit.currentMachineID), "AuthKit should not still have device 2 on the list") + self.mockAuthKit.sendIncompleteNotification() + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + } + + func testIgnoreRemoveFromWrongAltDSID() throws { + self.startCKAccountStatusMock() + + XCTAssert(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should already have device 2 on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let peer2ID = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, tell peer1 about the change. It will trust the peer and upload some TLK shares + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + // We receive a 'remove' push for peer2's ID, but for the wrong DSID. The peer should do nothing useful. + self.fakeCuttlefishServer.updateListener = { request in + XCTFail("shouldn't have updated trust") + return nil + } + + self.mockAuthKit.sendRemoveNotification(machineID: try! self.mockAuthKit2.machineID(), altDSID: "completely-wrong") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + self.assertMIDList(context: self.cuttlefishContext, + allowed: self.mockAuthKit.currentDeviceList(), + disallowed: Set(), + unknown: Set()) + } + + func testIgnoreAddFromWrongAltDSID() throws { + self.startCKAccountStatusMock() + + XCTAssert(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should already have device 2 on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let peer2ID = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, tell peer1 about the change. It will trust the peer and upload some TLK shares + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + // We receive a 'add' push for a new ID, but for the wrong DSID. The peer should do nothing useful. + self.fakeCuttlefishServer.updateListener = { request in + XCTFail("shouldn't have updated trust") + return nil + } + + let newMachineID = "newID" + self.mockAuthKit.sendAddNotification(machineID: newMachineID, altDSID: "completely-wrong") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + // newMachineID should be on no lists + self.assertMIDList(context: self.cuttlefishContext, + allowed: self.mockAuthKit.currentDeviceList(), + disallowed: Set(), + unknown: Set()) + } + + func testPeerJoiningWithUnknownMachineIDTriggersMachineIDFetchAfterGracePeriod() throws { + self.startCKAccountStatusMock() + + // Peer 2 is not on Peer 1's machine ID list yet + self.mockAuthKit.otherDevices.remove(self.mockAuthKit2.currentMachineID) + + let _ = self.assertResetAndBecomeTrustedInDefaultContext() + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let _ = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, add peer2 to the machineID list, but don't send peer1 a notification about the IDMS change + self.mockAuthKit.otherDevices.insert(self.mockAuthKit2.currentMachineID) + self.assertMIDList(context: self.cuttlefishContext, allowed: self.mockAuthKit.currentDeviceList().subtracting(Set([self.mockAuthKit2.currentMachineID]))) + + let condition = CKKSCondition() + self.mockAuthKit.fetchCondition = condition + + // But peer1 does get the cuttlefish push + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // At this time, peer1 should trust peer2, but it should _not_ have fetched the AuthKit list, + // because peer2 is still within the 48 hour grace period. peer1 is hoping for a push to arrive. + + XCTAssertNotEqual(condition.wait(2*NSEC_PER_SEC), 0, "Octagon should not fetch the authkit machine ID list") + let peer2MIDSet = Set([self.mockAuthKit2.currentMachineID]) + self.assertMIDList(context: self.cuttlefishContext, + allowed: self.mockAuthKit.currentDeviceList().subtracting(peer2MIDSet), + unknown: peer2MIDSet) + + // Now, let's pretend that three days pass, and do this again... Octagon should now fetch the MID list and become happy. + let container = try self.tphClient.getContainer(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) + container.moc.performAndWait { + var foundPeer2 = false + for machinemo in container.containerMO.machines as? Set ?? Set() { + if machinemo.machineID == self.mockAuthKit2.currentMachineID { + foundPeer2 = true + // + machinemo.modified = Date(timeIntervalSinceNow: -60*60*TimeInterval(72)) + XCTAssertEqual(machinemo.status, Int64(TPMachineIDStatus.unknown.rawValue), "peer2's MID entry should be 'unknown'") + } + } + + XCTAssertTrue(foundPeer2, "Should have found an entry for peer2") + try! container.moc.save() + } + + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + XCTAssertEqual(condition.wait(10*NSEC_PER_SEC), 0, "Octagon should fetch the authkit machine ID list") + + self.assertMIDList(context: self.cuttlefishContext, allowed: self.mockAuthKit.currentDeviceList()) + } + + func testTrustPeerWheMissingFromDeviceListAndLocked() throws { + self.startCKAccountStatusMock() + + self.mockAuthKit.otherDevices.removeAll() + XCTAssertEqual(self.mockAuthKit.currentDeviceList(), Set([self.mockAuthKit.currentMachineID]), "AuthKit should have exactly one device on the list") + XCTAssertFalse(self.mockAuthKit.currentDeviceList().contains(self.mockAuthKit2.currentMachineID), "AuthKit should not already have device 2 on the list") + + let peer1ID = self.assertResetAndBecomeTrustedInDefaultContext() + + let joiningContext = self.makeInitiatorContext(contextID: "joiner", authKitAdapter: self.mockAuthKit2) + let peer2ID = self.assertJoinViaEscrowRecovery(joiningContext: joiningContext, sponsor: self.cuttlefishContext) + + // Now, tell peer1 about the change. It will trust the peer, despite it missing from the list, and upload some TLK shares + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + + // Then peer2 arrives on the device list. Peer 1 should update its dynamic info to no longer have a disposition for peer2. + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + // TODO: swift refuses to see the dispositions object on newDynamicInfo; ah well + updateTrustExpectation.fulfill() + return nil + } + + // Now, peer should lock and receive an Octagon push + self.aksLockState = true + self.lockStateTracker.recheck() + + // Now, peer2 should receive an Octagon push, try to realize it is preapproved, and get stuck + self.sendContainerChange(context: self.cuttlefishContext) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.mockAuthKit.addAndSendNotification(machineID: try! self.mockAuthKit2.machineID()) + + sleep(1) + + XCTAssertTrue(self.cuttlefishContext.stateMachine.possiblePendingFlags().contains("recd_push"), "Should have recd_push pending flag") + + // Now, peer should unlock and receive an Octagon push + self.aksLockState = false + self.lockStateTracker.recheck() + + sleep(1) + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have 0 pending flags") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + } +} + +#endif diff --git a/keychain/ot/tests/octagon/OctagonTests+ErrorHandling.swift b/keychain/ot/tests/octagon/OctagonTests+ErrorHandling.swift new file mode 100644 index 00000000..bba5d235 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+ErrorHandling.swift @@ -0,0 +1,440 @@ + +#if OCTAGON + +class OctagonErrorHandlingTests: OctagonTestsBase { + + func testRecoverFromImmediateTimeoutDuringEstablish() throws { + self.startCKAccountStatusMock() + + let establishExpectation = self.expectation(description: "establishExpectation") + + self.fakeCuttlefishServer.establishListener = { [unowned self] request in + self.fakeCuttlefishServer.establishListener = nil + establishExpectation.fulfill() + + return CKPrettyError(domain: CKErrorDomain, + code: CKError.networkFailure.rawValue, + userInfo: [:]) + } + + let _ = self.assertResetAndBecomeTrustedInDefaultContext() + self.wait(for: [establishExpectation], timeout: 10) + } + + func testRecoverFromRetryableErrorDuringEstablish() throws { + self.startCKAccountStatusMock() + + let establishExpectation = self.expectation(description: "establishExpectation") + + var t0: Date = Date.distantPast + + self.fakeCuttlefishServer.establishListener = { [unowned self] request in + self.fakeCuttlefishServer.establishListener = nil + establishExpectation.fulfill() + + t0 = Date() + return FakeCuttlefishServer.makeCloudKitCuttlefishError(code: .retryableServerFailure) + } + + let _ = self.assertResetAndBecomeTrustedInDefaultContext() + self.wait(for: [establishExpectation], timeout: 10) + let t1 = Date() + let d = t0.distance(to: t1) + XCTAssertGreaterThanOrEqual(d, 4) + XCTAssertLessThanOrEqual(d, 6) + } + + func testReceiveUpdateWhileUntrustedAndLocked() { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.aksLockState = true + self.lockStateTracker.recheck() + + self.sendContainerChange(context: self.cuttlefishContext) + + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testReceiveUpdateWhileReadyAndLocked() { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + self.aksLockState = true + self.lockStateTracker.recheck() + + self.sendContainerChange(context: self.cuttlefishContext) + + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.aksLockState = false + self.lockStateTracker.recheck() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + // and again! + self.aksLockState = true + self.lockStateTracker.recheck() + self.sendContainerChange(context: self.cuttlefishContext) + + sleep(1) + XCTAssertTrue(self.cuttlefishContext.stateMachine.possiblePendingFlags().contains("recd_push"), "Should have recd_push pending flag") + + let waitForUnlockStateCondition = self.cuttlefishContext.stateMachine.stateConditions[OctagonStateWaitForUnlock] as! CKKSCondition + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + sleep(1) + // Check that we haven't been spinning + let sameWaitForUnlockStateCondition = self.cuttlefishContext.stateMachine.stateConditions[OctagonStateWaitForUnlock] as! CKKSCondition + XCTAssert(waitForUnlockStateCondition == sameWaitForUnlockStateCondition, "Conditions should be the same (as the state machine should be halted)") + + self.aksLockState = false + self.lockStateTracker.recheck() + + sleep(1) + + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have 0 pending flags") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testReceiveUpdateWhileReadyAndAuthkitRetry() { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + self.mockAuthKit.machineIDFetchErrors.append(CKPrettyError(domain:CKErrorDomain, + code:CKError.networkUnavailable.rawValue, + userInfo:[CKErrorRetryAfterKey: 2])) + + self.sendContainerChange(context: self.cuttlefishContext) + + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.sendContainerChange(context: self.cuttlefishContext) + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testReceiveUpdateWhileReadyAndLockedAndAuthkitRetry() { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + self.aksLockState = true + self.lockStateTracker.recheck() + + self.mockAuthKit.machineIDFetchErrors.append(CKPrettyError(domain:CKErrorDomain, + code:CKError.networkUnavailable.rawValue, + userInfo:[CKErrorRetryAfterKey: 2])) + + self.sendContainerChange(context: self.cuttlefishContext) + + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.sendContainerChange(context: self.cuttlefishContext) + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + sleep(1) + + XCTAssertTrue(self.cuttlefishContext.stateMachine.possiblePendingFlags().contains("recd_push"), "Should have recd_push pending flag") + + self.aksLockState = false + self.lockStateTracker.recheck() + + sleep(1) + + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have 0 pending flags") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testReceiveTransactionErrorDuringUpdate() { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + let pre = self.fakeCuttlefishServer.fetchChangesCalledCount + + + let cuttlefishError = NSError(domain:CuttlefishErrorDomain, + code:CuttlefishErrorCode.transactionalFailure.rawValue, + userInfo:nil) + let ckInternalError = NSError(domain:CKInternalErrorDomain, + code:CKInternalErrorCode.errorInternalPluginError.rawValue, + userInfo:[NSUnderlyingErrorKey: cuttlefishError]) + let ckError = NSError(domain:CKErrorDomain, + code:CKError.serverRejectedRequest.rawValue, + userInfo:[NSUnderlyingErrorKey: ckInternalError]) + + + self.fakeCuttlefishServer.nextFetchErrors.append(ckError) + + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + + sleep(5) + + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "state machine should pause") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have zero pending flags after retry") + + let post = self.fakeCuttlefishServer.fetchChangesCalledCount + XCTAssertEqual(post, pre + 2, "should have fetched two times, the first response would have been a transaction error") + } + + + func testPreapprovedPushWhileLocked() throws { + // Peer 1 becomes SOS+Octagon + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Peer 2 attempts to join via preapprovalh + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + + peer2.startOctagonStateMachine() + + self.assertEnters(context: peer2, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Now, Peer1 should preapprove Peer2 + let peer2Preapproval = TPHashBuilder.hash(with: .SHA256, of: peer2SOSMockPeer.publicSigningKey.encodeSubjectPublicKeyInfo()) + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + self.mockSOSAdapter.sendTrustedPeerSetChangedUpdate() + + // Peer1 should upload TLKs for Peer2 + self.assertAllCKKSViewsUpload(tlkShares: 1) + + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertEqual(peerID, request.peerID, "updateTrust request should be for ego peer ID") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.preapprovals.count, 1, "Should have a single preapproval") + XCTAssertTrue(newDynamicInfo!.preapprovals.contains(peer2Preapproval), "Octagon peer should preapprove new SOS peer") + + // But, since this is an SOS peer and TLK uploads for those peers are currently handled through CK CRUD operations, this update + // shouldn't have any TLKShares + XCTAssertEqual(0, request.tlkShares.count, "Trust update should not have any new TLKShares") + + updateTrustExpectation.fulfill() + return nil + } + + self.verifyDatabaseMocks() + self.wait(for: [updateTrustExpectation], timeout: 100) + self.fakeCuttlefishServer.updateListener = nil + + // Now, peer 2 should lock and receive an Octagon push + self.aksLockState = true + self.lockStateTracker.recheck() + + // Now, peer2 should receive an Octagon push, try to realize it is preapproved, and get stuck + self.sendContainerChange(context: peer2) + self.assertEnters(context: peer2, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + sleep(1) + + XCTAssertTrue(peer2.stateMachine.possiblePendingFlags().contains("recd_push"), "Should have recd_push pending flag") + + self.aksLockState = false + self.lockStateTracker.recheck() + + sleep(1) + + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have 0 pending flags") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testReceiveMachineListUpdateWhileReadyAndLocked() throws { + // Peer 1 becomes SOS+Octagon + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + + let clique : OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Peer 2 arrives (with a voucher), but is not on the trusted device list + let firstPeerID = clique.cliqueMemberIdentifier + XCTAssertNotNil(firstPeerID, "Clique should have a member identifier") + let bottle = self.fakeCuttlefishServer.state.bottles[0] + let entropy = try self.loadSecret(label: firstPeerID!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + let bNewOTCliqueContext = OTConfigurationContext() + bNewOTCliqueContext.context = "restoreB" + bNewOTCliqueContext.dsid = self.otcliqueContext.dsid + bNewOTCliqueContext.altDSID = self.otcliqueContext.altDSID + bNewOTCliqueContext.otControl = self.otcliqueContext.otControl + bNewOTCliqueContext.sbd = OTMockSecureBackup(bottleID: bottle.bottleID, entropy: entropy!) + + let deviceBmockAuthKit = OTMockAuthKitAdapter(altDSID: self.otcliqueContext.altDSID, + machineID: "b-machine-id", + otherDevices: [self.mockAuthKit.currentMachineID]) + + + let bRestoreContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: bNewOTCliqueContext.context!, + sosAdapter: OTSOSMissingAdapter(), + authKitAdapter: deviceBmockAuthKit, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + + bRestoreContext.startOctagonStateMachine() + + self.sendContainerChange(context: bRestoreContext) + let bNewClique: OTClique + do { + bNewClique = try OTClique.performEscrowRecovery(withContextData: bNewOTCliqueContext, escrowArguments: [:]) + XCTAssertNotNil(bNewClique, "bNewClique should not be nil") + } catch { + XCTFail("Shouldn't have errored recovering: \(error)") + throw error + } + self.assertEnters(context: bRestoreContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + // Device A notices, but doesn't update (because B isn't on the device list) + self.fakeCuttlefishServer.updateListener = { _ in + XCTFail("Should not have updated trust") + return nil + } + + // Device A locks and gets the device list notification + self.aksLockState = true + self.lockStateTracker.recheck() + + self.mockAuthKit.otherDevices.insert(deviceBmockAuthKit.currentMachineID) + + self.cuttlefishContext.incompleteNotificationOfMachineIDListChange() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertEqual(firstPeerID, request.peerID, "updateTrust request should be for ego peer ID") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo?.includedPeerIDs.count, 2, "Should trust both peers") + updateTrustExpectation.fulfill() + return nil + } + + self.sendContainerChange(context: self.cuttlefishContext) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + + // And on unlock, it should handle the update + self.aksLockState = false + self.lockStateTracker.recheck() + + self.wait(for: [updateTrustExpectation], timeout: 30) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } +} + +#endif diff --git a/keychain/ot/tests/octagon/OctagonTests+EscrowRecovery.swift b/keychain/ot/tests/octagon/OctagonTests+EscrowRecovery.swift new file mode 100644 index 00000000..184b0dfc --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+EscrowRecovery.swift @@ -0,0 +1,1357 @@ +#if OCTAGON + +@objcMembers class OctagonEscrowRecoveryTests: OctagonTestsBase { + override func setUp() { + super.setUp() + } + + func testJoinWithBottle() throws { + let initiatorContextID = "initiator-context-id" + let bottlerContext = self.makeInitiatorContext(contextID: initiatorContextID) + + bottlerContext.startOctagonStateMachine() + let ckacctinfo = CKAccountInfo() + ckacctinfo.accountStatus = .available + ckacctinfo.hasValidCredentials = true + ckacctinfo.accountPartition = .production + + bottlerContext.cloudkitAccountStateChange(nil, to: ckacctinfo) + self.assertEnters(context: bottlerContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = initiatorContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: bottlerContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: bottlerContext) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: bottlerContext, zoneID: self.manateeZoneID) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Try to enforce that that CKKS doesn't know about the key hierarchy until Octagon asks it + self.holdCloudKitFetches() + + // Note: CKKS will want to upload a TLKShare for its self + self.expectCKModifyKeyRecords(0, currentKeyPointerRecords: 0, tlkShareRecords: 1, zoneID: self.manateeZoneID) + + // Before you call joinWithBottle, you need to call fetchViableBottles. + let fetchViableExpectation = self.expectation(description: "fetchViableBottles callback occurs") + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchViableExpectation.fulfill() + } + self.wait(for: [fetchViableExpectation], timeout: 10) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + + sleep(1) + self.releaseCloudKitFetchHold() + + self.wait(for: [joinWithBottleExpectation], timeout: 100) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testBottleRestoreEntersOctagonReady() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.verifyDatabaseMocks() + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + let restoreExpectation = self.expectation(description: "restore returns") + + self.manager!.restore(OTCKContainerName, contextID: initiatorContextID, bottleSalt: self.otcliqueContext.altDSID, entropy: entropy!, bottleID: bottle.bottleID) { error in + XCTAssertNil(error, "error should be nil") + restoreExpectation.fulfill() + } + self.wait(for: [restoreExpectation], timeout: 10) + + self.assertEnters(context: initiatorContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: initiatorContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + } + + func testJoinWithBottleWithCKKSConflict() throws { + let initiatorContextID = "initiator-context-id" + let bottlerContext = self.makeInitiatorContext(contextID: initiatorContextID) + + bottlerContext.startOctagonStateMachine() + let ckacctinfo = CKAccountInfo() + ckacctinfo.accountStatus = .available + ckacctinfo.hasValidCredentials = true + ckacctinfo.accountPartition = .production + + bottlerContext.cloudkitAccountStateChange(nil, to: ckacctinfo) + self.assertEnters(context: bottlerContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = initiatorContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: bottlerContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: bottlerContext) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + // During the join, there's a CKKS key race + self.silentFetchesAllowed = false + self.expectCKFetchAndRun(beforeFinished: { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + self.silentFetchesAllowed = true + }) + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Before you call joinWithBottle, you need to call fetchViableBottles. + let fetchViableExpectation = self.expectation(description: "fetchViableBottles callback occurs") + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchViableExpectation.fulfill() + } + self.wait(for: [fetchViableExpectation], timeout: 10) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + + self.wait(for: [joinWithBottleExpectation], timeout: 100) + + self.verifyDatabaseMocks() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + } + + func testBottleRestoreWithSameMachineID() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.verifyDatabaseMocks() + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + // some other peer should restore from this bottle + let differentDevice = self.makeInitiatorContext(contextID: "differenDevice") + let differentRestoreExpectation = self.expectation(description: "different restore returns") + differentDevice.startOctagonStateMachine() + differentDevice.join(withBottle: bottle.bottleID, + entropy: entropy!, + bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + differentRestoreExpectation.fulfill() + } + self.wait(for: [differentRestoreExpectation], timeout: 10) + + self.assertTrusts(context: differentDevice, includedPeerIDCount: 2, excludedPeerIDCount: 0) + + // The first peer will upload TLKs for the new peer + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetchForState(context: self.cuttlefishContext, state: OctagonStateReady) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10*NSEC_PER_SEC) + self.verifyDatabaseMocks() + + self.assertTrusts(context: self.cuttlefishContext, includedPeerIDCount: 2, excludedPeerIDCount: 0) + + // Explicitly use the same authkit parameters as the original peer when restoring this time + let restoreContext = self.makeInitiatorContext(contextID: "restoreContext", authKitAdapter: self.mockAuthKit) + + restoreContext.startOctagonStateMachine() + + let restoreExpectation = self.expectation(description: "restore returns") + restoreContext.join(withBottle: bottle.bottleID, + entropy: entropy!, + bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + restoreExpectation.fulfill() + } + self.wait(for: [restoreExpectation], timeout: 10) + + self.assertEnters(context: restoreContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: restoreContext) + + // The restore context should exclude its sponsor + self.assertTrusts(context: restoreContext, includedPeerIDCount: 2, excludedPeerIDCount: 1) + + // Then, the remote peer should trust the new peer and exclude the original + self.sendContainerChangeWaitForFetchForStates(context: differentDevice, states: [OctagonStateReadyUpdated, OctagonStateReady]) + self.assertTrusts(context: differentDevice, includedPeerIDCount: 2, excludedPeerIDCount: 1) + + // Then, if by some strange miracle the original peer is still around, it should bail (as it's now untrusted) + self.sendContainerChangeWaitForFetchForState(context: self.cuttlefishContext, state: OctagonStateUntrusted) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + self.assertTrusts(context: self.cuttlefishContext, includedPeerIDCount: 0, excludedPeerIDCount: 1) + } + + func testRestoreSPIFromPiggybackingState() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + self.verifyDatabaseMocks() + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let restoreExpectation = self.expectation(description: "restore returns") + + self.manager!.restore(OTCKContainerName, contextID: initiatorContextID, bottleSalt: self.otcliqueContext.altDSID, entropy: entropy!, bottleID: bottle.bottleID) { error in + XCTAssertNil(error, "error should be nil") + restoreExpectation.fulfill() + } + self.wait(for: [restoreExpectation], timeout: 10) + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: initiatorContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + } + + func testRestoreBadBottleIDFails() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.verifyDatabaseMocks() + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + _ = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + let restoreExpectation = self.expectation(description: "restore returns") + + self.manager!.restore(OTCKContainerName, contextID: initiatorContextID, bottleSalt: self.otcliqueContext.altDSID, entropy: entropy!, bottleID: "bad escrow record ID") { error in + XCTAssertNotNil(error, "error should not be nil") + restoreExpectation.fulfill() + } + self.wait(for: [restoreExpectation], timeout: 10) + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 1, "should be 1 peer ids") + + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + } + + func testRestoreOptimalBottleIDs() throws { + self.startCKAccountStatusMock() + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + var bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertNotNil(bottleIDs.preferredBottleIDs, "preferredBottleIDs should not be nil") + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 1, "preferredBottleIDs should have 1 bottle") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "partialRecoveryBottleIDs should be empty") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: "restoreContext", + sosAdapter: OTSOSMissingAdapter(), + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + + initiatorContext.startOctagonStateMachine() + let newOTCliqueContext = OTConfigurationContext() + newOTCliqueContext.context = "restoreContext" + newOTCliqueContext.dsid = self.otcliqueContext.dsid + newOTCliqueContext.altDSID = self.otcliqueContext.altDSID + newOTCliqueContext.otControl = self.otcliqueContext.otControl + newOTCliqueContext.sbd = OTMockSecureBackup(bottleID: bottle.bottleID, entropy: entropy!) + + let newClique: OTClique + do { + newClique = try OTClique.performEscrowRecovery(withContextData: newOTCliqueContext, escrowArguments: [:]) + XCTAssertNotNil(newClique, "newClique should not be nil") + } catch { + XCTFail("Shouldn't have errored recovering: \(error)") + throw error + } + + // We will upload a new TLK for the new peer + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetchForState(context: self.cuttlefishContext, state: OctagonStateReady) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.sendContainerChangeWaitForFetchForState(context: initiatorContext, state: OctagonStateReady) + bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertNotNil(bottleIDs.preferredBottleIDs, "preferredBottleIDs should not be nil") + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 2, "preferredBottleIDs should have 2 bottle") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "partialRecoveryBottleIDs should be empty") + } + + func testRestoreFromEscrowContents() throws { + self.startCKAccountStatusMock() + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + var bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertNotNil(bottleIDs.preferredBottleIDs, "preferredBottleIDs should not be nil") + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 1, "preferredBottleIDs should have 1 bottle") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "partialRecoveryBottleIDs should be empty") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + var entropy = Data() + var bottledID: String = "" + + let fetchEscrowContentsExpectation = self.expectation(description: "fetchEscrowContentsExpectation returns") + clique.fetchEscrowContents { e, b, s, _ in + XCTAssertNotNil(e, "entropy should not be nil") + XCTAssertNotNil(b, "bottleID should not be nil") + XCTAssertNotNil(s, "signingPublicKey should not be nil") + entropy = e! + bottledID = b! + fetchEscrowContentsExpectation.fulfill() + } + + self.wait(for: [fetchEscrowContentsExpectation], timeout: 10) + + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: "restoreContext", + sosAdapter: OTSOSMissingAdapter(), + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + + initiatorContext.startOctagonStateMachine() + let newOTCliqueContext = OTConfigurationContext() + newOTCliqueContext.context = "restoreContext" + newOTCliqueContext.dsid = self.otcliqueContext.dsid + newOTCliqueContext.altDSID = self.otcliqueContext.altDSID + newOTCliqueContext.otControl = self.otcliqueContext.otControl + newOTCliqueContext.sbd = OTMockSecureBackup(bottleID: bottledID, entropy: entropy) + + let newClique: OTClique + do { + newClique = try OTClique.performEscrowRecovery(withContextData: newOTCliqueContext, escrowArguments: [:]) + XCTAssertNotNil(newClique, "newClique should not be nil") + } catch { + XCTFail("Shouldn't have errored recovering: \(error)") + throw error + } + + // We will upload a new TLK for the new peer + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetchForState(context: self.cuttlefishContext, state: OctagonStateReady) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.sendContainerChangeWaitForFetchForState(context: initiatorContext, state: OctagonStateReady) + + bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertNotNil(bottleIDs.preferredBottleIDs, "preferredBottleIDs should not be nil") + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 2, "preferredBottleIDs should have 2 bottle") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "partialRecoveryBottleIDs should be empty") + + let dumpExpectation = self.expectation(description: "dump callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let peerID = egoSelf!["peerID"] as? String + XCTAssertNotNil(peerID, "peerID should not be nil") + + dumpExpectation.fulfill() + } + self.wait(for: [dumpExpectation], timeout: 10) + + self.otControlCLI.status(OTCKContainerName, + context: newOTCliqueContext.context!, + json: false) + } + + func testFetchEmptyOptimalBottleList () throws { + self.startCKAccountStatusMock() + + let bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 0, "should be 0 preferred bottle ids") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "should be 0 partialRecoveryBottleIDs") + } + + func testFetchOptimalBottlesAfterFailedRestore() throws { + self.startCKAccountStatusMock() + + self.otcliqueContext.sbd = OTMockSecureBackup(bottleID: "bottle ID", entropy: Data(count: 72)) + + XCTAssertThrowsError(try OTClique.performEscrowRecovery(withContextData: self.otcliqueContext, escrowArguments: [:])) + + let bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertNotNil(bottleIDs.preferredBottleIDs, "preferredBottleIDs should not be nil") + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 0, "preferredBottleIDs should have 0 bottle") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "partialRecoveryBottleIDs should be empty") + } + + func testMakeNewFriendsAndFetchEscrowContents () throws { + self.startCKAccountStatusMock() + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let fetchEscrowContentsException = self.expectation(description: "update returns") + + clique.fetchEscrowContents { e, b, s, _ in + XCTAssertNotNil(e, "entropy should not be nil") + XCTAssertNotNil(b, "bottleID should not be nil") + XCTAssertNotNil(s, "signingPublicKey should not be nil") + fetchEscrowContentsException.fulfill() + } + self.wait(for: [fetchEscrowContentsException], timeout: 10) + + } catch { + XCTFail("failed to reset clique: \(error)") + } + + self.verifyDatabaseMocks() + } + + func testFetchEscrowContentsBeforeIdentityExists() { + self.startCKAccountStatusMock() + + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, contextID: "initiator") + let fetchEscrowContentsException = self.expectation(description: "update returns") + + initiatorContext.fetchEscrowContents { entropy, bottleID, signingPubKey, error in + XCTAssertNil(entropy, "entropy should be nil") + XCTAssertNil(bottleID, "bottleID should be nil") + XCTAssertNil(signingPubKey, "signingPublicKey should be nil") + XCTAssertNotNil(error, "error should not be nil") + + fetchEscrowContentsException.fulfill() + } + self.wait(for: [fetchEscrowContentsException], timeout: 10) + } + + func testFetchEscrowContentsChecksEntitlement() throws { + self.startCKAccountStatusMock() + + let contextName = OTDefaultContext + let containerName = OTCKContainerName + + // First, fail due to not having any data + let fetchEscrowContentsExpectation = self.expectation(description: "fetchEscrowContentsExpectation returns") + self.otControl.fetchEscrowContents(containerName, contextID: contextName) { entropy, bottle, signingPublicKey, error in + XCTAssertNotNil(error, "error should not be nil") + //XCTAssertNotEqual(error.code, errSecMissingEntitlement, "Error should not be 'missing entitlement'") + XCTAssertNil(entropy, "entropy should be nil") + XCTAssertNil(bottle, "bottleID should be nil") + XCTAssertNil(signingPublicKey, "signingPublicKey should be nil") + fetchEscrowContentsExpectation.fulfill() + } + self.wait(for: [fetchEscrowContentsExpectation], timeout: 10) + + // Now, fail due to the client not having an entitlement + self.otControlEntitlementBearer.entitlements.removeAll() + let failFetchEscrowContentsExpectation = self.expectation(description: "fetchEscrowContentsExpectation returns") + self.otControl.fetchEscrowContents(containerName, contextID: contextName) { entropy, bottle, signingPublicKey, error in + XCTAssertNotNil(error, "error should not be nil") + switch error { + case .some(let error as NSError): + XCTAssertEqual(error.domain, NSOSStatusErrorDomain, "Error should be an OS status") + XCTAssertEqual(error.code, Int(errSecMissingEntitlement), "Error should be 'missing entitlement'") + default: + XCTFail("Unable to turn error into NSError: \(String(describing: error))") + } + + XCTAssertNil(entropy, "entropy should not be nil") + XCTAssertNil(bottle, "bottleID should not be nil") + XCTAssertNil(signingPublicKey, "signingPublicKey should not be nil") + failFetchEscrowContentsExpectation.fulfill() + } + self.wait(for: [failFetchEscrowContentsExpectation], timeout: 10) + } + + func testJoinWithBottleFailCaseBottleDoesntExist() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + self.fakeCuttlefishServer.state.bottles.removeAll() + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + initiatorContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNotNil(error, "error should not be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testJoinWithBottleFailCaseBadEscrowRecord() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + _ = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + initiatorContext.join(withBottle: "sos peer id", entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNotNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testJoinWithBottleFailCaseBadEntropy() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + initiatorContext.join(withBottle: bottle.bottleID, entropy: Data(count: 72), bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNotNil(error, "error should not be nil, when entropy is missing") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testJoinWithBottleFailCaseBadBottleSalt() throws { + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + initiatorContext.join(withBottle: bottle.bottleID, entropy: Data(count: 72), bottleSalt: "123456789") { error in + XCTAssertNotNil(error, "error should not be nil with bad entropy and salt") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testRecoverFromDeviceNotOnMachineIDList() throws { + self.startCKAccountStatusMock() + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let firstPeerID = clique.cliqueMemberIdentifier + XCTAssertNotNil(firstPeerID, "Clique should have a member identifier") + let entropy = try self.loadSecret(label: firstPeerID!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + let bottleIDs = try OTClique.findOptimalBottleIDs(withContextData: self.otcliqueContext) + XCTAssertNotNil(bottleIDs.preferredBottleIDs, "preferredBottleIDs should not be nil") + XCTAssertEqual(bottleIDs.preferredBottleIDs.count, 1, "preferredBottleIDs should have 1 bottle") + XCTAssertEqual(bottleIDs.partialRecoveryBottleIDs.count, 0, "partialRecoveryBottleIDs should be empty") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + // To get into the state we need, we need to introduce peer B and C. C should then distrust A, whose bottle it used + // B shouldn't have an opinion of C. + + + let bNewOTCliqueContext = OTConfigurationContext() + bNewOTCliqueContext.context = "restoreB" + bNewOTCliqueContext.dsid = self.otcliqueContext.dsid + bNewOTCliqueContext.altDSID = self.otcliqueContext.altDSID + bNewOTCliqueContext.otControl = self.otcliqueContext.otControl + bNewOTCliqueContext.sbd = OTMockSecureBackup(bottleID: bottle.bottleID, entropy: entropy!) + + let deviceBmockAuthKit = OTMockAuthKitAdapter(altDSID: self.otcliqueContext.altDSID, + machineID: "b-machine-id", + otherDevices: [self.mockAuthKit.currentMachineID]) + + let bRestoreContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: bNewOTCliqueContext.context!, + sosAdapter: OTSOSMissingAdapter(), + authKitAdapter: deviceBmockAuthKit, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + bRestoreContext.startOctagonStateMachine() + let bNewClique: OTClique + do { + bNewClique = try OTClique.performEscrowRecovery(withContextData: bNewOTCliqueContext, escrowArguments: [:]) + XCTAssertNotNil(bNewClique, "bNewClique should not be nil") + } catch { + XCTFail("Shouldn't have errored recovering: \(error)") + throw error + } + self.assertEnters(context: bRestoreContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + // And introduce C, which will kick out A + // During the next sign in, the machine ID list has changed to just the new one + let restoremockAuthKit = OTMockAuthKitAdapter(altDSID: self.otcliqueContext.altDSID, + machineID: "c-machine-id", + otherDevices: [self.mockAuthKit.currentMachineID, deviceBmockAuthKit.currentMachineID]) + let restoreContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: "restoreContext", + sosAdapter: OTSOSMissingAdapter(), + authKitAdapter: restoremockAuthKit, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + + restoreContext.startOctagonStateMachine() + let newOTCliqueContext = OTConfigurationContext() + newOTCliqueContext.context = "restoreContext" + newOTCliqueContext.dsid = self.otcliqueContext.dsid + newOTCliqueContext.altDSID = self.otcliqueContext.altDSID + newOTCliqueContext.otControl = self.otcliqueContext.otControl + newOTCliqueContext.sbd = OTMockSecureBackup(bottleID: bottle.bottleID, entropy: entropy!) + + let newClique: OTClique + do { + newClique = try OTClique.performEscrowRecovery(withContextData: newOTCliqueContext, escrowArguments: [:]) + XCTAssertNotNil(newClique, "newClique should not be nil") + } catch { + XCTFail("Shouldn't have errored recovering: \(error)") + throw error + } + + self.assertEnters(context: restoreContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertConsidersSelfTrusted(context: restoreContext) + + let restoreDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: newOTCliqueContext.context!) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 3, "should be 3 peer id included") + + restoreDumpCallback.fulfill() + } + self.wait(for: [restoreDumpCallback], timeout: 10) + + // Now, exclude peer A's machine ID + restoremockAuthKit.otherDevices = [deviceBmockAuthKit.currentMachineID] + + // Peer C should upload a new trust status + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.excludedPeerIDs.count, 1, "Should have a single excluded peer") + updateTrustExpectation.fulfill() + return nil + } + + restoreContext.incompleteNotificationOfMachineIDListChange() + self.wait(for: [updateTrustExpectation], timeout: 10) + + self.assertEnters(context: restoreContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertConsidersSelfTrusted(context: restoreContext) + } + + func testCachedBottleFetch() throws { + let initiatorContextID = "initiator-context-id" + let bottlerContext = self.makeInitiatorContext(contextID: initiatorContextID) + + bottlerContext.startOctagonStateMachine() + let ckacctinfo = CKAccountInfo() + ckacctinfo.accountStatus = .available + ckacctinfo.hasValidCredentials = true + ckacctinfo.accountPartition = .production + + bottlerContext.cloudkitAccountStateChange(nil, to: ckacctinfo) + self.assertEnters(context: bottlerContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = initiatorContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: bottlerContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: bottlerContext) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: bottlerContext, zoneID: self.manateeZoneID) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Try to enforce that that CKKS doesn't know about the key hierarchy until Octagon asks it + self.holdCloudKitFetches() + + // Note: CKKS will want to upload a TLKShare for its self + self.expectCKModifyKeyRecords(0, currentKeyPointerRecords: 0, tlkShareRecords: 1, zoneID: self.manateeZoneID) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + + sleep(1) + self.releaseCloudKitFetchHold() + + self.wait(for: [joinWithBottleExpectation], timeout: 100) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + + //now call fetchviablebottles, we should get the uncached version + let fetchUnCachedViableBottlesExpectation = self.expectation(description: "fetch UnCached ViableBottles") + + self.fakeCuttlefishServer.fetchViableBottlesListener = { request in + self.fakeCuttlefishServer.fetchViableBottlesListener = nil + fetchUnCachedViableBottlesExpectation.fulfill() + return nil + } + let FetchAllViableBottles = self.expectation(description: "FetchAllViableBottles callback occurs") + + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + FetchAllViableBottles.fulfill() + } + self.wait(for: [FetchAllViableBottles], timeout: 10) + self.wait(for: [fetchUnCachedViableBottlesExpectation], timeout: 10) + + let fetchViableExpectation = self.expectation(description: "fetchViableBottles callback occurs") + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchViableExpectation.fulfill() + } + self.wait(for: [fetchViableExpectation], timeout: 10) + + + //now call fetchviablebottles, we should get the cached version + let fetchViableBottlesExpectation = self.expectation(description: "fetch Cached ViableBottles") + fetchViableBottlesExpectation.isInverted = true + + self.fakeCuttlefishServer.fetchViableBottlesListener = { request in + self.fakeCuttlefishServer.fetchViableBottlesListener = nil + fetchViableBottlesExpectation.fulfill() + return nil + } + let fetchExpectation = self.expectation(description: "fetchExpectation callback occurs") + + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchExpectation.fulfill() + } + self.wait(for: [fetchExpectation], timeout: 10) + self.wait(for: [fetchViableBottlesExpectation], timeout: 10) + } + + func testViableBottleCachingAfterJoin() throws { + let initiatorContextID = "initiator-context-id" + let bottlerContext = self.makeInitiatorContext(contextID: initiatorContextID) + + bottlerContext.startOctagonStateMachine() + let ckacctinfo = CKAccountInfo() + ckacctinfo.accountStatus = .available + ckacctinfo.hasValidCredentials = true + ckacctinfo.accountPartition = .production + + bottlerContext.cloudkitAccountStateChange(nil, to: ckacctinfo) + self.assertEnters(context: bottlerContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = initiatorContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: bottlerContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: bottlerContext) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: bottlerContext, zoneID: self.manateeZoneID) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Try to enforce that that CKKS doesn't know about the key hierarchy until Octagon asks it + self.holdCloudKitFetches() + + // Note: CKKS will want to upload a TLKShare for its self + self.expectCKModifyKeyRecords(0, currentKeyPointerRecords: 0, tlkShareRecords: 1, zoneID: self.manateeZoneID) + + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + + sleep(1) + self.releaseCloudKitFetchHold() + + self.wait(for: [joinWithBottleExpectation], timeout: 100) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + + //now call fetchviablebottles, we should get the uncached version + let fetchUnCachedViableBottlesExpectation = self.expectation(description: "fetch UnCached ViableBottles") + + self.fakeCuttlefishServer.fetchViableBottlesListener = { request in + self.fakeCuttlefishServer.fetchViableBottlesListener = nil + fetchUnCachedViableBottlesExpectation.fulfill() + return nil + } + let FetchAllViableBottles = self.expectation(description: "FetchAllViableBottles callback occurs") + + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + FetchAllViableBottles.fulfill() + } + self.wait(for: [FetchAllViableBottles], timeout: 10) + self.wait(for: [fetchUnCachedViableBottlesExpectation], timeout: 10) + + let fetchViableExpectation = self.expectation(description: "fetchViableBottles callback occurs") + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchViableExpectation.fulfill() + } + self.wait(for: [fetchViableExpectation], timeout: 10) + + //now call fetchviablebottles, we should get the cached version + let fetchViableBottlesExpectation = self.expectation(description: "fetch Cached ViableBottles") + fetchViableBottlesExpectation.isInverted = true + + self.fakeCuttlefishServer.fetchViableBottlesListener = { request in + self.fakeCuttlefishServer.fetchViableBottlesListener = nil + fetchViableBottlesExpectation.fulfill() + return nil + } + let fetchExpectation = self.expectation(description: "fetchExpectation callback occurs") + + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchExpectation.fulfill() + } + self.wait(for: [fetchExpectation], timeout: 10) + self.wait(for: [fetchViableBottlesExpectation], timeout: 10) + } + + func testViableBottleReturns1Bottle() throws { + let initiatorContextID = "initiator-context-id" + let bottlerContext = self.makeInitiatorContext(contextID: initiatorContextID) + + bottlerContext.startOctagonStateMachine() + let ckacctinfo = CKAccountInfo() + ckacctinfo.accountStatus = .available + ckacctinfo.hasValidCredentials = true + ckacctinfo.accountPartition = .production + + bottlerContext.cloudkitAccountStateChange(nil, to: ckacctinfo) + self.assertEnters(context: bottlerContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = initiatorContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: bottlerContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: bottlerContext) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: bottlerContext, zoneID: self.manateeZoneID) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Try to enforce that that CKKS doesn't know about the key hierarchy until Octagon asks it + self.holdCloudKitFetches() + + // Note: CKKS will want to upload a TLKShare for its self + self.expectCKModifyKeyRecords(0, currentKeyPointerRecords: 0, tlkShareRecords: 1, zoneID: self.manateeZoneID) + + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + + sleep(1) + self.releaseCloudKitFetchHold() + + self.wait(for: [joinWithBottleExpectation], timeout: 100) + + var egoPeerID: String? + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + egoPeerID = egoSelf!["peerID"] as? String + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let bottles:[Bottle] = self.fakeCuttlefishServer.state.bottles + var bottleToExclude: String? + bottles.forEach { bottle in + if bottle.peerID == egoPeerID { + bottleToExclude = bottle.bottleID + } + } + + XCTAssertNotNil(bottleToExclude, "bottleToExclude should not be nil") + + //now call fetchviablebottles, we should get the uncached version + var fetchUnCachedViableBottlesExpectation = self.expectation(description: "fetch UnCached ViableBottles") + + self.fakeCuttlefishServer.fetchViableBottlesListener = { request in + self.fakeCuttlefishServer.fetchViableBottlesListener = nil + fetchUnCachedViableBottlesExpectation.fulfill() + return nil + } + self.fakeCuttlefishServer.fetchViableBottlesDontReturnBottleWithID = bottleToExclude + var FetchAllViableBottles = self.expectation(description: "FetchAllViableBottles callback occurs") + + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + FetchAllViableBottles.fulfill() + } + self.wait(for: [FetchAllViableBottles], timeout: 10) + self.wait(for: [fetchUnCachedViableBottlesExpectation], timeout: 10) + + //now call fetchviablebottles, we should get the uncached version + fetchUnCachedViableBottlesExpectation = self.expectation(description: "fetch UnCached ViableBottles") + + self.fakeCuttlefishServer.fetchViableBottlesListener = { request in + self.fakeCuttlefishServer.fetchViableBottlesListener = nil + fetchUnCachedViableBottlesExpectation.fulfill() + return nil + } + + self.fakeCuttlefishServer.fetchViableBottlesDontReturnBottleWithID = bottleToExclude + + FetchAllViableBottles = self.expectation(description: "FetchAllViableBottles callback occurs") + + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + FetchAllViableBottles.fulfill() + } + self.wait(for: [FetchAllViableBottles], timeout: 10) + self.wait(for: [fetchUnCachedViableBottlesExpectation], timeout: 10) + } +} + +#endif diff --git a/keychain/ot/tests/octagon/OctagonTests+HealthCheck.swift b/keychain/ot/tests/octagon/OctagonTests+HealthCheck.swift new file mode 100644 index 00000000..9d00a5ce --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+HealthCheck.swift @@ -0,0 +1,841 @@ +#if OCTAGON + +class OctagonHealthCheckTests: OctagonTestsBase { + + func testHealthCheckAllTrusted() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckNoPeers() throws { + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + cuttlefishContext.checkOctagonHealth(false) { error in + XCTAssertNotNil(error, "error should be present; device is not healthy") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + XCTAssertEqual(self.cuttlefishContext.postedRepairCFU, false, "Should not have posted a CFU on aTV") + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Set the "have I attempted to join" bit; TVs should still not CFU, but other devices should + try! self.cuttlefishContext.accountMetadataStore.persistOctagonJoinAttempt(.ATTEMPTED) + + let healthCheckCallback2 = self.expectation(description: "healthCheckCallback callback occurs") + cuttlefishContext.checkOctagonHealth(false) { error in + XCTAssertNotNil(error, "error should be present; device is not healthy") + healthCheckCallback2.fulfill() + } + self.wait(for: [healthCheckCallback2], timeout: 10) + + #if os(tvOS) + XCTAssertEqual(self.cuttlefishContext.postedRepairCFU, false, "Should not have posted a CFU on aTV") + #else + XCTAssertEqual(self.cuttlefishContext.postedRepairCFU, true, "Should have posted a CFU") + #endif + } + + func testHealthCheckSecurityDStateNOTTrusted() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + //now let's ruin account state, and say we are untrusted + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + accountState.trustState = OTAccountMetadataClassC_TrustState(rawValue: 1)! + try accountState.saveToKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(1, accountState.trustState.rawValue, "Saved account state should have the same peer ID that prepare returned") + } catch { + XCTFail("error loading account state: \(error)") + } + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + cuttlefishContext.checkOctagonHealth(false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: cuttlefishContext) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 1, "should be 1 peer ids") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckTrustedPeersHelperStateNOTTrusted() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "Saved account state should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + var healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + cuttlefishContext.checkOctagonHealth(false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + // now lets completely wipe cuttlefish state + let resetCallback = self.expectation(description: "resetCallback callback occurs") + self.tphClient.localReset(withContainer: containerName, context: contextName) { error in + XCTAssertNil(error, "error should be nil") + resetCallback.fulfill() + } + self.wait(for: [resetCallback], timeout: 10) + + healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + cuttlefishContext.checkOctagonHealth(false) { error in + XCTAssertNotNil(error, "error should not be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + #if !os(tvOS) + XCTAssertEqual(cuttlefishContext.postedRepairCFU, true, "Should have posted a CFU") + #else + XCTAssertFalse(cuttlefishContext.postedRepairCFU, "aTV should not have posted a CFU, as there's no iphone to recover from") + #endif + } + + func responseTestsSetup() throws -> (OTCuttlefishContext, String) { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let originalCliqueIdentifier = clique.cliqueMemberIdentifier + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + // Reset any CFUs we've done so far + self.otFollowUpController.postedFollowUp = false + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + return (cuttlefishContext, originalCliqueIdentifier!) + } + + func testCuttlefishResponseNoAction() throws { + self.fakeCuttlefishServer.returnNoActionResponse = true + let (cuttlefishContext, _) = try responseTestsSetup() + XCTAssertFalse(self.otFollowUpController.postedFollowUp, "should not have posted a CFU"); + XCTAssertEqual(cuttlefishContext.postedRepairCFU, false, "should not have posted a CFU"); + } + + func testCuttlefishResponseRepairAccount() throws { + self.fakeCuttlefishServer.returnRepairAccountResponse = true + let (_, _) = try responseTestsSetup() + XCTAssertTrue(self.otFollowUpController.postedFollowUp, "should have posted a CFU"); + } + + func testCuttlefishResponseRepairEscrow() throws { + self.fakeCuttlefishServer.returnRepairEscrowResponse = true + OTMockSecEscrowRequest.self.populateStatuses = false + let (cuttlefishContext, _) = try responseTestsSetup() + XCTAssertTrue(self.otFollowUpController.postedFollowUp, "should have posted a CFU"); + XCTAssertEqual(cuttlefishContext.postedEscrowRepairCFU, true, "should have posted an escrow CFU"); + } + + func testCuttlefishResponseResetOctagon() throws { + let contextName = OTDefaultContext + let containerName = OTCKContainerName + self.fakeCuttlefishServer.returnResetOctagonResponse = true + let (cuttlefishContext, cliqueIdentifier) = try responseTestsSetup() + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + var newCliqueIdentifier: String? + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + newCliqueIdentifier = egoSelf!["peerID"]! as? String + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + XCTAssertNotEqual(cliqueIdentifier, newCliqueIdentifier, "should have reset octagon") + + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testCuttlefishResponseError() throws { + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.changeTokenExpired.rawValue, userInfo: nil) + self.fakeCuttlefishServer.returnRepairErrorResponse = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + + let (cuttlefishContext, _) = try responseTestsSetup() + XCTAssertEqual(cuttlefishContext.postedRepairCFU, false, "should not have posted an account repair CFU"); + XCTAssertEqual(cuttlefishContext.postedEscrowRepairCFU, false, "should not have posted an escrow repair CFU"); + } + + func testHealthCheckBeforeStateMachineStarts() throws { + let contextName = OTDefaultContext + let containerName = OTCKContainerName + let cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: contextName) + + cuttlefishContext.stateMachine.setWatcherTimeout(2*NSEC_PER_SEC); + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNotNil(error, "Should be an error calling 'healthCheck'") + XCTAssertEqual(error!._domain, CKKSResultErrorDomain, "Error domain should be CKKSResultErrorDomain") + XCTAssertEqual(error!._code , CKKSResultTimedOut, "Error result should be CKKSResultTimedOut") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + self.startCKAccountStatusMock() + + cuttlefishContext.stateMachine.setWatcherTimeout(60*NSEC_PER_SEC); + + cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let otcliqueContext = OTConfigurationContext() + otcliqueContext.context = contextName + otcliqueContext.dsid = "1234" + otcliqueContext.altDSID = self.mockAuthKit.altDSID! + otcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckAfterCloudKitAccountStateChange() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNotNil(error, "error should not be nil") + XCTAssertEqual((error! as NSError).code, 30, "Error code should be 30") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + self.assertEnters(context: cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckAfterLandingInUntrusted() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNotNil(error, "error should not be nil") + XCTAssertEqual((error! as NSError).code, 30, "Error code should be 30") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckNoAccount() throws { + // Device is signed out + self.mockAuthKit.altDSID = nil + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + // but CK is going to win the race, and tell us everything is fine first + self.accountStatus = .noAccount + self.startCKAccountStatusMock() + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + let cuttlefishContext = self.manager.context(forContainerName: containerName, contextID: contextName) + cuttlefishContext.stateMachine.setWatcherTimeout(2*NSEC_PER_SEC); + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNotNil(error, "error should not be nil") + XCTAssertEqual((error! as NSError).code, 3, "Error code should be 3") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckWhenLocked() throws { + + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + self.aksLockState = true + self.lockStateTracker.recheck() + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + } + + func testLastHealthCheckPersistedTime() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(2, accountState.trustState.rawValue, "saved account should be trusted") + } catch { + XCTFail("error loading account state: \(error)") + } + + var before: UInt64 = 0 + var healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + do { + let state = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext) + XCTAssertNotNil(state) + XCTAssertNotNil(state.lastHealthCheckup, "last Health Check should not be nil") + before = state.lastHealthCheckup + } catch { + XCTFail("error loading from keychain: \(error)") + } + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + let dumpCallback = self.expectation(description: "dumpCallback callback occurs") + self.tphClient.dump(withContainer: containerName, context: contextName) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + sleep(5) + + healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + var after: UInt64 = 0 + do { + let state = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext) + XCTAssertNotNil(state) + XCTAssertNotNil(state.lastHealthCheckup, "last Health Check should not be nil") + after = state.lastHealthCheckup + } catch { + XCTFail("error loading from keychain: \(error)") + } + + XCTAssertEqual(before, after, "time stamp should not have changed") + + var healthCheckMinusTwoDays: UInt64 = 0 + //update the last health check to something way in the past + do { + let state = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext) + state.lastHealthCheckup = state.lastHealthCheckup - 172800000 /* 2 days of seconds * 1000*/ + healthCheckMinusTwoDays = state.lastHealthCheckup + XCTAssertNoThrow(try state.saveToKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext), "saving to the keychain should work") + } catch { + XCTFail("error loading from keychain: \(error)") + } + + sleep(2) + + //check health again, should be updated + var updatedHealthCheck: UInt64 = 0 + healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + do { + let state = try OTAccountMetadataClassC.loadFromKeychain(forContainer: OTCKContainerName, contextID: OTDefaultContext) + XCTAssertNotNil(state) + XCTAssertNotNil(state.lastHealthCheckup, "last Health Check should not be nil") + updatedHealthCheck = state.lastHealthCheckup + } catch { + XCTFail("error loading from keychain: \(error)") + } + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + XCTAssertTrue(updatedHealthCheck > healthCheckMinusTwoDays, "time stamp should have changed") + } + + func testHealthCheckAfterFailedJoinWithVoucher() throws { + let initiatorContextID = "initiator-context-id" + let bottlerContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiatorContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", + deviceName: "test-bottler-iphone-2", + serialNumber: "456", + osVersion: "iOS (fake version)")) + + bottlerContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: bottlerContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = initiatorContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: bottlerContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: bottlerContext) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: bottlerContext, zoneID: self.manateeZoneID) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // cheat: a bottle restore can only succeed after a fetch occurs + self.sendContainerChange(context: self.cuttlefishContext) + + // Before you call joinWithBottle, you need to call fetchViableBottles. + let fetchViableExpectation = self.expectation(description: "fetchViableBottles callback occurs") + self.cuttlefishContext.rpcFetchAllViableBottles { viable, _, error in + XCTAssertNil(error, "should be no error fetching viable bottles") + XCTAssert(viable?.contains(bottle.bottleID) ?? false, "The bottle we're about to restore should be viable") + fetchViableExpectation.fulfill() + } + self.wait(for: [fetchViableExpectation], timeout: 10) + + let userInfo: Dictionary = ["NSLocalizedDescription" : "Reachability validation failed, graph is not reachable"] + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.resultGraphNotFullyReachable.rawValue, userInfo: userInfo) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + + let joinListenerExpectation = self.expectation(description: "joinWithVoucherExpectation callback occurs") + self.fakeCuttlefishServer.joinListener = { request in + joinListenerExpectation.fulfill() + return nil + } + + let healthExpectation = self.expectation(description: "health check callback occurs") + self.fakeCuttlefishServer.healthListener = { request in + healthExpectation.fulfill() + return nil + } + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNotNil(error, "error should not be nil") + joinWithBottleExpectation.fulfill() + } + + self.wait(for: [joinWithBottleExpectation], timeout: 100) + self.wait(for: [joinListenerExpectation], timeout: 100) + self.wait(for: [healthExpectation], timeout: 100) + self.fakeCuttlefishServer.joinListener = nil + self.fakeCuttlefishServer.healthListener = nil + } + + func testCuttlefishDontPostEscrowCFUDueToPendingPrecord() throws { + self.fakeCuttlefishServer.returnRepairEscrowResponse = true + OTMockSecEscrowRequest.self.populateStatuses = true + let (cuttlefishContext, _) = try responseTestsSetup() + XCTAssertEqual(cuttlefishContext.postedEscrowRepairCFU, false, "should NOT have posted an escrow CFU"); + } + + func testHealthCheckWhileLocked() throws { + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.aksLockState = true + self.lockStateTracker.recheck() + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(containerName, context: contextName, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + self.verifyDatabaseMocks() + self.assertEnters(context: cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + } + + func testHealthCheckWhileSA() throws { + // Account is SA + self.mockAuthKit.hsa2 = false + + self.cuttlefishContext.startOctagonStateMachine() + self.startCKAccountStatusMock() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForHSA2, within: 10 * NSEC_PER_SEC) + + let healthCheckCallback = self.expectation(description: "healthCheckCallback callback occurs") + self.manager.healthCheck(OTCKContainerName, context: OTDefaultContext, skipRateLimitingCheck: false) { error in + XCTAssertNil(error, "error should be nil") + healthCheckCallback.fulfill() + } + self.wait(for: [healthCheckCallback], timeout: 10) + + self.assertEnters(context: cuttlefishContext, state: OctagonStateWaitForHSA2, within: 10 * NSEC_PER_SEC) + } +} + +#endif diff --git a/keychain/ot/tests/octagon/OctagonTests+RecoveryKey.swift b/keychain/ot/tests/octagon/OctagonTests+RecoveryKey.swift new file mode 100644 index 00000000..397a9354 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+RecoveryKey.swift @@ -0,0 +1,1159 @@ +#if OCTAGON + +@objcMembers class OctagonRecoveryKeyTests: OctagonTestsBase { + override func setUp() { + super.setUp() + } + + + func testSetRecoveryKey() throws { + self.startCKAccountStatusMock() + self.manager.setSOSEnabledForPlatformFlag(false) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + XCTAssertFalse(self.mockAuthKit.currentDeviceList().isEmpty, "should not have zero devices") + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let recoveryKey = SecPasswordGenerate(SecPasswordType(kSecPasswordTypeiCloudRecoveryKey), nil, nil)! as String + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let createKeyExpectation = self.expectation(description: "createKeyExpectation returns") + self.manager.createRecoveryKey(OTCKContainerName, contextID: self.otcliqueContext.context ?? "defaultContext", recoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + createKeyExpectation.fulfill() + } + self.wait(for: [createKeyExpectation], timeout: 10) + } + + func testSetRecoveryKeyPeerReaction() throws { + self.startCKAccountStatusMock() + self.manager.setSOSEnabledForPlatformFlag(false) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + let recoveryKey = SecPasswordGenerate(SecPasswordType(kSecPasswordTypeiCloudRecoveryKey), nil, nil)! as String + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let createKeyExpectation = self.expectation(description: "createKeyExpectation returns") + self.manager.createRecoveryKey(OTCKContainerName, contextID: self.otcliqueContext.context ?? "defaultContext", recoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + createKeyExpectation.fulfill() + } + self.wait(for: [createKeyExpectation], timeout: 10) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContextID = "new guy" + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID, authKitAdapter: self.mockAuthKit2) + + initiatorContext.startOctagonStateMachine() + self.sendContainerChange(context: initiatorContext) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + initiatorContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + self.verifyDatabaseMocks() + + self.sendContainerChangeWaitForFetch(context: initiatorContext) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + + self.verifyDatabaseMocks() + + let stableInfoCheckDumpCallback = self.expectation(description: "stableInfoCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: initiatorContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + stableInfoCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoCheckDumpCallback], timeout: 10) + + let stableInfoAcceptorCheckDumpCallback = self.expectation(description: "stableInfoAcceptorCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: self.otcliqueContext.context ?? "defaultContext") { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + stableInfoAcceptorCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoAcceptorCheckDumpCallback], timeout: 10) + self.verifyDatabaseMocks() + } + + func testSetRecoveryKey3PeerReaction() throws { + self.startCKAccountStatusMock() + self.manager.setSOSEnabledForPlatformFlag(false) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + let recoveryKey = SecPasswordGenerate(SecPasswordType(kSecPasswordTypeiCloudRecoveryKey), nil, nil)! as String + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let createKeyExpectation = self.expectation(description: "createKeyExpectation returns") + self.manager.createRecoveryKey(OTCKContainerName, contextID: self.otcliqueContext.context ?? "defaultContext", recoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + createKeyExpectation.fulfill() + } + self.wait(for: [createKeyExpectation], timeout: 10) + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContextID = "new guy" + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + + initiatorContext.startOctagonStateMachine() + + self.sendContainerChange(context: initiatorContext) + + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + initiatorContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + + self.verifyDatabaseMocks() + + self.sendContainerChangeWaitForFetch(context: initiatorContext) + + // The first peer will upload TLKs for the new peer + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10*NSEC_PER_SEC) + self.verifyDatabaseMocks() + + let stableInfoCheckDumpCallback = self.expectation(description: "stableInfoCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: initiatorContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + stableInfoCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoCheckDumpCallback], timeout: 10) + + let stableInfoAcceptorCheckDumpCallback = self.expectation(description: "stableInfoAcceptorCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: self.otcliqueContext.context ?? "defaultContext") { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + stableInfoAcceptorCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoAcceptorCheckDumpCallback], timeout: 10) + + let thirdPeerContextID = "3rd guy" + let thirdPeerContext = self.makeInitiatorContext(contextID: thirdPeerContextID, authKitAdapter: self.mockAuthKit3) + + thirdPeerContext.startOctagonStateMachine() + + self.sendContainerChange(context: thirdPeerContext) + let thirdPeerJoinWithBottleExpectation = self.expectation(description: "thirdPeerJoinWithBottleExpectation callback occurs") + thirdPeerContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: self.otcliqueContext.altDSID) { error in + XCTAssertNil(error, "error should be nil") + thirdPeerJoinWithBottleExpectation.fulfill() + } + self.wait(for: [thirdPeerJoinWithBottleExpectation], timeout: 10) + + self.verifyDatabaseMocks() + + self.sendContainerChangeWaitForFetchForState(context: thirdPeerContext, state: OctagonStateReady) + let thirdPeerStableInfoCheckDumpCallback = self.expectation(description: "thirdPeerStableInfoCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: thirdPeerContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 3, "should be 3df peer ids") + + thirdPeerStableInfoCheckDumpCallback.fulfill() + } + self.wait(for: [thirdPeerStableInfoCheckDumpCallback], timeout: 10) + } + + func createEstablishContext(contextID: String) -> OTCuttlefishContext { + + return self.manager.context(forContainerName: OTCKContainerName, + contextID: contextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-RK-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + } + + func testJoinWithRecoveryKey() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = establishContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit2.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: establishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: establishContext) + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: establishContext, zoneID: self.manateeZoneID) + + self.assertSelfTLKSharesInCloudKit(context: establishContext) + + let recoveryKey = SecPasswordGenerate(SecPasswordType(kSecPasswordTypeiCloudRecoveryKey), nil, nil)! as String + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + self.manager.setSOSEnabledForPlatformFlag(true) + + let createRecoveryExpectation = self.expectation(description: "createRecoveryExpectation returns") + self.manager.createRecoveryKey(OTCKContainerName, contextID: establishContextID, recoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + createRecoveryExpectation.fulfill() + } + self.wait(for: [createRecoveryExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetchForState(context: establishContext, state: OctagonStateReady) + + let recoveryContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + recoveryContext.startOctagonStateMachine() + self.assertEnters(context: recoveryContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.sendContainerChangeWaitForFetchForState(context: recoveryContext, state: OctagonStateUntrusted) + + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKey callback occurs") + recoveryContext.join(withRecoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: recoveryContext) + + let stableInfoCheckDumpCallback = self.expectation(description: "stableInfoCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + stableInfoCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoCheckDumpCallback], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: establishContext) + + let stableInfoAcceptorCheckDumpCallback = self.expectation(description: "stableInfoAcceptorCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: establishContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + stableInfoAcceptorCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoAcceptorCheckDumpCallback], timeout: 10) + try self.putSelfTLKShareInCloudKit(context: recoveryContext, zoneID: self.manateeZoneID) + self.assertSelfTLKSharesInCloudKit(context: recoveryContext) + } + + func testJoinWithRecoveryKeyWithCKKSConflict() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let bottlerotcliqueContext = OTConfigurationContext() + bottlerotcliqueContext.context = establishContextID + bottlerotcliqueContext.dsid = "1234" + bottlerotcliqueContext.altDSID = self.mockAuthKit2.altDSID! + bottlerotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: bottlerotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: establishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: establishContext) + + let recoveryKey = SecPasswordGenerate(SecPasswordType(kSecPasswordTypeiCloudRecoveryKey), nil, nil)! as String + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + self.manager.setSOSEnabledForPlatformFlag(true) + + let createRecoveryExpectation = self.expectation(description: "createRecoveryExpectation returns") + self.manager.createRecoveryKey(OTCKContainerName, contextID: establishContextID, recoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + createRecoveryExpectation.fulfill() + } + self.wait(for: [createRecoveryExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetchForState(context: establishContext, state: OctagonStateReady) + + self.silentFetchesAllowed = false + self.expectCKFetchAndRun(beforeFinished: { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + self.silentFetchesAllowed = true + }) + let recoveryContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + recoveryContext.startOctagonStateMachine() + self.assertEnters(context: recoveryContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.sendContainerChangeWaitForFetchForState(context: recoveryContext, state: OctagonStateUntrusted) + + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKey callback occurs") + recoveryContext.join(withRecoveryKey: recoveryKey) { error in + XCTAssertNil(error, "error should be nil") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + + self.assertConsidersSelfTrusted(context: recoveryContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + } + + func testOTCliqueSettingRecoveryKey() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(self.otcliqueContext, recoveryKey: recoveryKey!) { rk, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(rk, "rk should not be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + } + + func testOTCliqueSet2ndRecoveryKey() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(self.otcliqueContext, recoveryKey: recoveryKey!) { rk, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(rk, "rk should not be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + + let recoveryKey2 = SecRKCreateRecoveryKeyString(nil) + + let setRecoveryKeyExpectationAgain = self.expectation(description: "setRecoveryKeyExpectationAgain callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(self.otcliqueContext, recoveryKey: recoveryKey2!) { rk, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(rk, "rk should not be nil") + setRecoveryKeyExpectationAgain.fulfill() + } + self.wait(for: [setRecoveryKeyExpectationAgain], timeout: 10) + } + func testRKReplacement() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let initiatorContextID = "initiator-context-id" + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.verifyDatabaseMocks() + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let bottle = self.fakeCuttlefishServer.state.bottles[0] + + let initiatorContext = self.makeInitiatorContext(contextID: initiatorContextID) + let initiatorConfigurationContext = OTConfigurationContext() + initiatorConfigurationContext.context = initiatorContextID + initiatorConfigurationContext.dsid = "1234" + initiatorConfigurationContext.altDSID = self.mockAuthKit.altDSID! + initiatorConfigurationContext.otControl = self.otControl + + initiatorContext.startOctagonStateMachine() + self.sendContainerChange(context: initiatorContext) + let restoreExpectation = self.expectation(description: "restore returns") + + self.manager!.restore(OTCKContainerName, contextID: initiatorContextID, bottleSalt: self.otcliqueContext.altDSID, entropy: entropy!, bottleID: bottle.bottleID) { error in + XCTAssertNil(error, "error should be nil") + restoreExpectation.fulfill() + } + self.wait(for: [restoreExpectation], timeout: 10) + + self.assertEnters(context: initiatorContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + var initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: initiatorContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(self.otcliqueContext, recoveryKey: recoveryKey!) { rk, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(rk, "rk should not be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + + let recoveryKey2 = SecRKCreateRecoveryKeyString(nil) + let setRecoveryKeyExpectationAgain = self.expectation(description: "setRecoveryKeyExpectationAgain callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(initiatorConfigurationContext, recoveryKey: recoveryKey2!) { rk, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(rk, "rk should not be nil") + setRecoveryKeyExpectationAgain.fulfill() + } + self.wait(for: [setRecoveryKeyExpectationAgain], timeout: 10) + + self.sendContainerChangeWaitForFetchForState(context: initiatorContext, state: OctagonStateReady) + self.sendContainerChangeWaitForFetchForState(context: self.cuttlefishContext, state: OctagonStateReady) + + var initiatorRecoverySigningKey: Data? + var initiatorRecoveryEncryptionKey: Data? + + var firstDeviceRecoverySigningKey: Data? + var firstDeviceRecoveryEncryptionKey: Data? + + //now let's ensure recovery keys are set for both the first device and second device + initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: initiatorContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + initiatorRecoverySigningKey = stableInfo!["recovery_signing_public_key"] as? Data + initiatorRecoveryEncryptionKey = stableInfo!["recovery_encryption_public_key"] as? Data + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let firstDeviceDumpCallback = self.expectation(description: "firstDeviceDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + firstDeviceRecoverySigningKey = stableInfo!["recovery_signing_public_key"] as? Data + firstDeviceRecoveryEncryptionKey = stableInfo!["recovery_encryption_public_key"] as? Data + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + firstDeviceDumpCallback.fulfill() + } + self.wait(for: [firstDeviceDumpCallback], timeout: 10) + + XCTAssertEqual(firstDeviceRecoverySigningKey, initiatorRecoverySigningKey, "recovery signing keys should be equal") + XCTAssertEqual(firstDeviceRecoveryEncryptionKey, initiatorRecoveryEncryptionKey, "recovery encryption keys should be equal") + } + + func testOTCliqueJoiningUsingRecoveryKey() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let recoverykeyotcliqueContext = OTConfigurationContext() + recoverykeyotcliqueContext.context = establishContextID + recoverykeyotcliqueContext.dsid = "1234" + recoverykeyotcliqueContext.altDSID = self.mockAuthKit.altDSID! + recoverykeyotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: recoverykeyotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: establishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: establishContext) + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: establishContext, zoneID: self.manateeZoneID) + + self.assertSelfTLKSharesInCloudKit(context: establishContext) + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(recoverykeyotcliqueContext, recoveryKey: recoveryKey!) { _, error in + XCTAssertNil(error, "error should be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: establishContext) + + let newCliqueContext = OTConfigurationContext() + newCliqueContext.context = OTDefaultContext + newCliqueContext.dsid = self.otcliqueContext.dsid + newCliqueContext.altDSID = self.mockAuthKit.altDSID! + newCliqueContext.otControl = self.otControl + + let newGuyContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + newGuyContext.startOctagonStateMachine() + + self.sendContainerChangeWaitForFetchForState(context: newGuyContext, state: OctagonStateUntrusted) + + self.manager.setSOSEnabledForPlatformFlag(true) + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKeyExpectation callback occurs") + OTClique.recoverOctagon(usingData: newCliqueContext, recoveryKey: recoveryKey!) { error in + XCTAssertNil(error, "error should be nil") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: newGuyContext) + + let stableInfoAcceptorCheckDumpCallback = self.expectation(description: "stableInfoAcceptorCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + stableInfoAcceptorCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoAcceptorCheckDumpCallback], timeout: 10) + self.assertEnters(context: newGuyContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: newGuyContext) + try self.putSelfTLKShareInCloudKit(context: newGuyContext, zoneID: self.manateeZoneID) + self.assertSelfTLKSharesInCloudKit(context: newGuyContext) + + self.sendContainerChangeWaitForFetch(context: establishContext) + + let stableInfoCheckDumpCallback = self.expectation(description: "stableInfoCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: establishContextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + stableInfoCheckDumpCallback.fulfill() + } + self.wait(for: [stableInfoCheckDumpCallback], timeout: 10) + } + + func testOTCliqueJoinUsingANotEnrolledRecoveryKey() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + let newCliqueContext = OTConfigurationContext() + newCliqueContext.context = OTDefaultContext + newCliqueContext.dsid = self.otcliqueContext.dsid + newCliqueContext.altDSID = self.mockAuthKit.altDSID! + newCliqueContext.otControl = self.otControl + + let recoveryGuyContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.manager.setSOSEnabledForPlatformFlag(true) + + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKeyExpectation callback occurs") + TestsObjectiveC.recoverOctagon(usingData: newCliqueContext, recoveryKey:recoveryKey!) { error in + XCTAssertNil(error, "error should be nil") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChange(context: recoveryGuyContext) + + let newGuyCheckDumpCallback = self.expectation(description: "newGuyCheckDumpCallback callback occurs") + self.tphClient.dump(withContainer: OTCKContainerName, context: OTDefaultContext) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + + let stableInfo = egoSelf!["stableInfo"] as? Dictionary + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfo!["recovery_signing_public_key"], "recoverySigningPublicKey should not be nil") + XCTAssertNotNil(stableInfo!["recovery_encryption_public_key"], "recoveryEncryptionPublicKey should not be nil") + + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 1, "should be 1 peer ids") + let vouchers = dump!["vouchers"] + XCTAssertNotNil(vouchers, "vouchers should not be nil") + newGuyCheckDumpCallback.fulfill() + } + self.wait(for: [newGuyCheckDumpCallback], timeout: 10) + self.assertEnters(context: recoveryGuyContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.assertSelfTLKSharesInCloudKit(context: recoveryGuyContext) + } + + func testSetRecoveryKeyAsLimitedPeer() throws { + self.manager.setSOSEnabledForPlatformFlag(false) + + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + XCTAssertFalse(self.mockAuthKit.currentDeviceList().isEmpty, "should not have zero devices") + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + let entropy = try self.loadSecret(label: clique.cliqueMemberIdentifier!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let recoveryKey = SecPasswordGenerate(SecPasswordType(kSecPasswordTypeiCloudRecoveryKey), nil, nil)! as String + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + let createKeyExpectation = self.expectation(description: "createKeyExpectation returns") + self.manager.createRecoveryKey(OTCKContainerName, contextID: self.otcliqueContext.context ?? "defaultContext", recoveryKey: recoveryKey) { error in + XCTAssertNotNil(error, "error should not be nil") + XCTAssertEqual((error! as NSError).code, Int(OTErrorLimitedPeer.rawValue), "error code should be limited peer") + createKeyExpectation.fulfill() + } + self.wait(for: [createKeyExpectation], timeout: 10) + } + + func testVouchWithRecoveryKeySetByUntrustedPeer() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let recoverykeyotcliqueContext = OTConfigurationContext() + recoverykeyotcliqueContext.context = establishContextID + recoverykeyotcliqueContext.dsid = "1234" + recoverykeyotcliqueContext.altDSID = self.mockAuthKit.altDSID! + recoverykeyotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: recoverykeyotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: establishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: establishContext) + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: establishContext, zoneID: self.manateeZoneID) + + self.assertSelfTLKSharesInCloudKit(context: establishContext) + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(recoverykeyotcliqueContext, recoveryKey: recoveryKey!) { _, error in + XCTAssertNil(error, "error should be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: establishContext) + + //now this peer will leave octagon + XCTAssertNoThrow(try clique.leave(), "Should be no error departing clique") + + // securityd should now consider itself untrusted + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: establishContext) + + let newCliqueContext = OTConfigurationContext() + newCliqueContext.context = OTDefaultContext + newCliqueContext.dsid = self.otcliqueContext.dsid + newCliqueContext.altDSID = self.mockAuthKit.altDSID! + newCliqueContext.otControl = self.otControl + + let newGuyContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + newGuyContext.startOctagonStateMachine() + + self.sendContainerChangeWaitForFetchForState(context: newGuyContext, state: OctagonStateUntrusted) + + self.manager.setSOSEnabledForPlatformFlag(true) + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKeyExpectation callback occurs") + OTClique.recoverOctagon(usingData: newCliqueContext, recoveryKey: recoveryKey!) { error in + XCTAssertNil(error, "error should be nil") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + } + + func testVouchWithWrongRecoveryKey() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let recoverykeyotcliqueContext = OTConfigurationContext() + recoverykeyotcliqueContext.context = establishContextID + recoverykeyotcliqueContext.dsid = "1234" + recoverykeyotcliqueContext.altDSID = self.mockAuthKit.altDSID! + recoverykeyotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: recoverykeyotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: establishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: establishContext) + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: establishContext, zoneID: self.manateeZoneID) + + self.assertSelfTLKSharesInCloudKit(context: establishContext) + + var recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(recoverykeyotcliqueContext, recoveryKey: recoveryKey!) { _, error in + XCTAssertNil(error, "error should be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: establishContext) + + let newCliqueContext = OTConfigurationContext() + newCliqueContext.context = OTDefaultContext + newCliqueContext.dsid = self.otcliqueContext.dsid + newCliqueContext.altDSID = self.mockAuthKit.altDSID! + newCliqueContext.otControl = self.otControl + + let newGuyContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + newGuyContext.startOctagonStateMachine() + + self.sendContainerChangeWaitForFetchForState(context: newGuyContext, state: OctagonStateUntrusted) + + self.manager.setSOSEnabledForPlatformFlag(true) + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKeyExpectation callback occurs") + + //creating new random recovery key + recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + + OTClique.recoverOctagon(usingData: newCliqueContext, recoveryKey: recoveryKey!) { error in + XCTAssertNotNil(error, "error should NOT be nil") + XCTAssertEqual((error! as NSError).code, 32, "error code should be 32/untrusted recovery keys") + XCTAssertEqual((error! as NSError).domain, "com.apple.security.trustedpeers.container", "error code domain should be com.apple.security.trustedpeers.container") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + } + + func testRecoveryWithDistrustedPeers() throws { + OctagonRecoveryKeySetIsEnabled(true) + self.manager.setSOSEnabledForPlatformFlag(false) + self.startCKAccountStatusMock() + + let establishContextID = "establish-context-id" + let establishContext = self.createEstablishContext(contextID: establishContextID) + + establishContext.startOctagonStateMachine() + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + let recoverykeyotcliqueContext = OTConfigurationContext() + recoverykeyotcliqueContext.context = establishContextID + recoverykeyotcliqueContext.dsid = "1234" + recoverykeyotcliqueContext.altDSID = self.mockAuthKit.altDSID! + recoverykeyotcliqueContext.otControl = self.otControl + do { + clique = try OTClique.newFriends(withContextData: recoverykeyotcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNotNil(clique.cliqueMemberIdentifier, "Should have a member identifier after a clique newFriends call") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: establishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: establishContext) + + // Fake that this peer also created some TLKShares for itself + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + try self.putSelfTLKShareInCloudKit(context: establishContext, zoneID: self.manateeZoneID) + + self.assertSelfTLKSharesInCloudKit(context: establishContext) + + let recoveryKey = SecRKCreateRecoveryKeyString(nil) + XCTAssertNotNil(recoveryKey, "recoveryKey should not be nil") + self.manager.setSOSEnabledForPlatformFlag(true) + + let setRecoveryKeyExpectation = self.expectation(description: "setRecoveryKeyExpectation callback occurs") + TestsObjectiveC.setNewRecoveryKeyWithData(recoverykeyotcliqueContext, recoveryKey: recoveryKey!) { _, error in + XCTAssertNil(error, "error should be nil") + setRecoveryKeyExpectation.fulfill() + } + self.wait(for: [setRecoveryKeyExpectation], timeout: 10) + + self.sendContainerChangeWaitForFetch(context: establishContext) + + //now this peer will leave octagon + XCTAssertNoThrow(try clique.leave(), "Should be no error departing clique") + + // securityd should now consider itself untrusted + self.assertEnters(context: establishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: establishContext) + + let newCliqueContext = OTConfigurationContext() + newCliqueContext.context = OTDefaultContext + newCliqueContext.dsid = self.otcliqueContext.dsid + newCliqueContext.altDSID = self.mockAuthKit.altDSID! + newCliqueContext.otControl = self.otControl + + let newGuyContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + newGuyContext.startOctagonStateMachine() + + self.sendContainerChangeWaitForFetchForState(context: newGuyContext, state: OctagonStateUntrusted) + + self.manager.setSOSEnabledForPlatformFlag(true) + let joinWithRecoveryKeyExpectation = self.expectation(description: "joinWithRecoveryKeyExpectation callback occurs") + + OTClique.recoverOctagon(usingData: newCliqueContext, recoveryKey: recoveryKey!) { error in + XCTAssertNil(error, "error should be nil") + joinWithRecoveryKeyExpectation.fulfill() + } + self.wait(for: [joinWithRecoveryKeyExpectation], timeout: 10) + } +} +#endif diff --git a/keychain/ot/tests/octagon/OctagonTests+Reset.swift b/keychain/ot/tests/octagon/OctagonTests+Reset.swift new file mode 100644 index 00000000..cb8120ae --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+Reset.swift @@ -0,0 +1,301 @@ +#if OCTAGON + +class OctagonResetTests: OctagonTestsBase { + func testAccountAvailableAndHandleExternalCall() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + _ = try self.cuttlefishContext.accountAvailable("13453464") + + self.cuttlefishContext.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "should be no error resetting and establishing") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testExernalCallAndAccountAvailable() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.cuttlefishContext.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "should be no error resetting and establishing") + } + + _ = try self.cuttlefishContext.accountAvailable("13453464") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testCallingAccountAvailableDuringResetAndEstablish() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.cuttlefishContext.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "should be no error resetting and establishing") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateResetAndEstablish, within: 1 * NSEC_PER_SEC) + + _ = try self.cuttlefishContext.accountAvailable("13453464") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testResetAndEstablishWithEscrow() throws { + let contextName = OTDefaultContext + let containerName = OTCKContainerName + + self.startCKAccountStatusMock() + + // Before resetAndEstablish, there shouldn't be any stored account state + XCTAssertThrowsError(try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName), "Before doing anything, loading a non-existent account state should fail") + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + let escrowRequestNotification = expectation(forNotification: OTMockEscrowRequestNotification, + object: nil, + handler: nil) + self.manager.resetAndEstablish(containerName, + context: contextName, + altDSID: "new altDSID") { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.wait(for: [escrowRequestNotification], timeout: 5) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let selfPeerID = try self.cuttlefishContext.accountMetadataStore.loadOrCreateAccountMetadata().peerID + + // After resetAndEstablish, you should be able to see the persisted account state + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(selfPeerID, accountState.peerID, "Saved account state should have the same peer ID that prepare returned") + } catch { + XCTFail("error loading account state: \(error)") + } + } + + func testResetAndEstablishStopsCKKS() throws { + let contextName = OTDefaultContext + let containerName = OTCKContainerName + + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // CKKS should pass through "waitfortrust" during a reset + let waitfortrusts = self.ckksViews.compactMap { view in + (view as! CKKSKeychainView).keyHierarchyConditions[SecCKKSZoneKeyStateWaitForTrust] as? CKKSCondition + } + XCTAssert(waitfortrusts.count > 0, "Should have at least one waitfortrust condition") + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + let escrowRequestNotification = expectation(forNotification: OTMockEscrowRequestNotification, + object: nil, + handler: nil) + self.manager.resetAndEstablish(containerName, + context: contextName, + altDSID: "new altDSID") { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.wait(for: [escrowRequestNotification], timeout: 5) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // CKKS should have all gone into waitfortrust during that time + for condition in waitfortrusts { + XCTAssertEqual(0, condition.wait(10*NSEC_PER_MSEC), "CKKS should have entered waitfortrust") + } + } + + func testOctagonResetAlsoResetsCKKSViewsMissingTLKs() { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + + let zoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(zoneKeys, "Should have some zone keys") + XCTAssertNotNil(zoneKeys?.tlk, "Should have a tlk in the original key set") + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + + self.silentZoneDeletesAllowed = true + + do { + _ = try OTClique.newFriends(withContextData: self.otcliqueContext) + } catch { + XCTFail("failed to make new friends: \(error)") + } + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let laterZoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(laterZoneKeys, "Should have some zone keys") + XCTAssertNotNil(laterZoneKeys?.tlk, "Should have a tlk in the newly created keyset") + XCTAssertNotEqual(zoneKeys?.tlk?.uuid, laterZoneKeys?.tlk?.uuid, "CKKS zone should now have different keys") + } + + func testOctagonResetIgnoresOldRemoteDevicesWithKeysAndResetsCKKS() { + // CKKS has no keys, and there's another device claiming to have them already, but it's old + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + + (self.zones![self.manateeZoneID]! as! FakeCKZone).currentDatabase.allValues.forEach { record in + let r = record as! CKRecord + if(r.recordType == SecCKRecordDeviceStateType) { + r.creationDate = NSDate.distantPast + r.modificationDate = NSDate.distantPast + } + } + + let zoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(zoneKeys, "Should have some zone keys") + XCTAssertNotNil(zoneKeys?.tlk, "Should have a tlk in the original key set") + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.silentZoneDeletesAllowed = true + + do { + _ = try OTClique.newFriends(withContextData: self.otcliqueContext) + } catch { + XCTFail("failed to make new friends: \(error)") + } + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let laterZoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(laterZoneKeys, "Should have some zone keys") + XCTAssertNotNil(laterZoneKeys?.tlk, "Should have a tlk in the newly created keyset") + XCTAssertNotEqual(zoneKeys?.tlk?.uuid, laterZoneKeys?.tlk?.uuid, "CKKS zone should now have different keys") + } + + func testOctagonResetWithRemoteDevicesWithKeysDoesNotResetCKKS() { + // CKKS has no keys, and there's another device claiming to have them already, so CKKS won't immediately reset it + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + + let zoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(zoneKeys, "Should have some zone keys") + XCTAssertNotNil(zoneKeys?.tlk, "Should have a tlk in the original key set") + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.silentZoneDeletesAllowed = true + + do { + _ = try OTClique.newFriends(withContextData: self.otcliqueContext) + } catch { + XCTFail("failed to make new friends: \(error)") + } + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + + let laterZoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(laterZoneKeys, "Should have some zone keys") + XCTAssertNotNil(laterZoneKeys?.tlk, "Should have a tlk in the newly created keyset") + XCTAssertEqual(zoneKeys?.tlk?.uuid, laterZoneKeys?.tlk?.uuid, "CKKS zone should now have the same keys") + } + + func testOctagonResetWithTLKsDoesNotResetCKKS() { + // CKKS has the keys keys + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain:self.manateeZoneID) + + let zoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(zoneKeys, "Should have some zone keys") + XCTAssertNotNil(zoneKeys?.tlk, "Should have a tlk in the original key set") + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + _ = try OTClique.newFriends(withContextData: self.otcliqueContext) + } catch { + XCTFail("failed to make new friends: \(error)") + } + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let laterZoneKeys = self.keys![self.manateeZoneID] as? ZoneKeys + XCTAssertNotNil(laterZoneKeys, "Should have some zone keys") + XCTAssertNotNil(laterZoneKeys?.tlk, "Should have a tlk in the newly created keyset") + XCTAssertEqual(zoneKeys?.tlk?.uuid, laterZoneKeys?.tlk?.uuid, "CKKS zone should now have the same keys") + } + + func testOctagonResetAndEstablishFail() throws { + // Make sure if establish fail we end up in untrusted instead of error + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + _ = try self.cuttlefishContext.accountAvailable("13453464") + + let establishExpectation = self.expectation(description: "establishExpectation") + let resetExpectation = self.expectation(description: "resetExpectation") + + self.fakeCuttlefishServer.establishListener = { [unowned self] request in + self.fakeCuttlefishServer.establishListener = nil + establishExpectation.fulfill() + + return CKPrettyError(domain: CKInternalErrorDomain, + code: CKInternalErrorCode.errorInternalPluginError.rawValue, + userInfo: [NSUnderlyingErrorKey: NSError(domain: CuttlefishErrorDomain, + code: CuttlefishErrorCode.establishFailed.rawValue, + userInfo: nil)]) + + } + + self.cuttlefishContext.rpcResetAndEstablish() { resetError in + resetExpectation.fulfill() + XCTAssertNotNil(resetError, "should error resetting and establishing") + } + self.wait(for: [establishExpectation, resetExpectation], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTests+SOS.swift b/keychain/ot/tests/octagon/OctagonTests+SOS.swift new file mode 100644 index 00000000..c470baae --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+SOS.swift @@ -0,0 +1,184 @@ +#if OCTAGON + +class OctagonSOSTests: OctagonTestsBase { + + func testSOSOctagonKeyConsistency() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + self.waitForCKModifications() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID") + + // CKKS will upload new TLKShares + self.assertAllCKKSViewsUpload(tlkShares: 2) + let newSOSPeer = createSOSPeer(peerID: peerID) + self.mockSOSAdapter.selfPeer = newSOSPeer + self.mockSOSAdapter.trustedPeers.add(newSOSPeer) + + // Now restart the context + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting") + + XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting") + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + } + + func testSOSOctagonKeyConsistencyLocked() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + self.waitForCKModifications() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID") + + let newSOSPeer = createSOSPeer(peerID: peerID) + self.mockSOSAdapter.selfPeer = newSOSPeer + + self.mockSOSAdapter.trustedPeers.add(newSOSPeer) + + self.aksLockState = true + self.lockStateTracker.recheck() + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Now restart the context + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + + self.assertAllCKKSViewsUpload(tlkShares: 2) + self.aksLockState = false + self.lockStateTracker.recheck() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting") + + XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting") + + self.verifyDatabaseMocks() + self.waitForCKModifications() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSOctagonKeyConsistencySucceedsAfterUpdatingSOS() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID!) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID!) + self.saveTLKMaterial(toKeychain: self.manateeZoneID!) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + self.waitForCKModifications() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID") + + let newSOSPeer = createSOSPeer(peerID: peerID) + self.mockSOSAdapter.selfPeer = newSOSPeer + + self.mockSOSAdapter.trustedPeers.add(newSOSPeer) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Now restart the context + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + + self.aksLockState = true + self.lockStateTracker.recheck() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + + self.assertAllCKKSViewsUpload(tlkShares: 2) + self.aksLockState = false + self.lockStateTracker.recheck() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting") + + XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting") + + self.verifyDatabaseMocks() + self.waitForCKModifications() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + +} + +#endif diff --git a/keychain/ot/tests/octagon/OctagonTests+SOSUpgrade.swift b/keychain/ot/tests/octagon/OctagonTests+SOSUpgrade.swift new file mode 100644 index 00000000..007a3a95 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests+SOSUpgrade.swift @@ -0,0 +1,1268 @@ +#if OCTAGON + +class OctagonSOSUpgradeTests: OctagonTestsBase { + func testSOSUpgrade() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + // Also, during the establish, Octagon shouldn't bother uploading the TLKShares that already exist + // So, it should have exactly the number of TLKShares as TLKs, and they should be shared to the new identity + let establishExpectation = self.expectation(description: "establish") + self.fakeCuttlefishServer.establishListener = { request in + XCTAssertEqual(request.tlkShares.count, request.viewKeys.count, "Should upload one TLK per keyset") + for tlkShare in request.tlkShares { + XCTAssertEqual(tlkShare.sender, request.peer.peerID, "TLKShare should be sent from uploading identity") + XCTAssertEqual(tlkShare.receiver, request.peer.peerID, "TLKShare should be sent to uploading identity") + } + establishExpectation.fulfill() + return nil + } + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.wait(for: [establishExpectation], timeout: 10) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + // Verify that an SOS upgrade only does one establish (and no update trust). + func testSOSUpgradeUpdateNoUpdateTrust() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + var establishCount = 0 + + self.fakeCuttlefishServer.establishListener = { request in + establishCount += 1 + return nil + } + + // Expect no updateTrust calls. + self.fakeCuttlefishServer.updateListener = { _ in + XCTFail("This case should not cause any updateTrust calls") + return nil + } + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 40 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + XCTAssertEqual(1, establishCount, "expected exactly one establish calls") + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSUpgradeAuthkitError() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID!) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID!) + self.saveTLKMaterial(toKeychain: self.manateeZoneID!) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + // Also, during the establish, Octagon shouldn't bother uploading the TLKShares that already exist + // So, it should have exactly the number of TLKShares as TLKs, and they should be shared to the new identity + let establishExpectation = self.expectation(description: "establish") + self.fakeCuttlefishServer.establishListener = { request in + XCTAssertEqual(request.tlkShares.count, request.viewKeys.count, "Should upload one TLK per keyset") + for tlkShare in request.tlkShares { + XCTAssertEqual(tlkShare.sender, request.peer.peerID, "TLKShare should be sent from uploading identity") + XCTAssertEqual(tlkShare.receiver, request.peer.peerID, "TLKShare should be sent to uploading identity") + } + establishExpectation.fulfill() + return nil + } + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.mockAuthKit.machineIDFetchErrors.append(CKPrettyError(domain:CKErrorDomain, + code:CKError.networkUnavailable.rawValue, + userInfo:[CKErrorRetryAfterKey: 2])) + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 15 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.wait(for: [establishExpectation], timeout: 10) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSUpgradeWhileLocked() throws { + // Test that we tries to perform SOS upgrade once we unlock device again + // + + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + // Device is locked + self.aksLockState = true + self.lockStateTracker.recheck() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + + //Now unblock device + self.aksLockState = false + self.lockStateTracker.recheck() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSUpgradeDuringNetworkOutage() throws { + // Test that we tries to perform SOS upgrade after a bit after a failure + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + let establishExpectation = self.expectation(description: "establishExpectation") + self.fakeCuttlefishServer.establishListener = { [unowned self] request in + // Stop erroring next time! + self.fakeCuttlefishServer.establishListener = nil + establishExpectation.fulfill() + + return CKPrettyError(domain:CKErrorDomain, code:CKError.networkUnavailable.rawValue, userInfo:[CKErrorRetryAfterKey: 2]) + } + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.wait(for: [establishExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Some time later, it should become ready + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSUpgradeStopsIfSplitGraph() throws { + // Test that we tries to perform SOS upgrade after a bit after a failure + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + let establishExpectation = self.expectation(description: "establishExpectation") + self.fakeCuttlefishServer.establishListener = { [unowned self] request in + // Stop erroring next time! + self.fakeCuttlefishServer.establishListener = nil + establishExpectation.fulfill() + + return CKPrettyError(domain: CKInternalErrorDomain, + code: CKInternalErrorCode.errorInternalPluginError.rawValue, + userInfo: [CKErrorRetryAfterKey: 2, + NSUnderlyingErrorKey: NSError(domain: CuttlefishErrorDomain, + code: CuttlefishErrorCode.resultGraphNotFullyReachable.rawValue, + userInfo: nil)]) + } + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.wait(for: [establishExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // It should be paused + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have zero pending flags after 'not reachable'") + } + + func testSOSUpgradeStopsIfNoPreapprovals() throws { + self.startCKAccountStatusMock() + + // Another peer shows up, preapproving only itself + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: [], essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + peer2.startOctagonStateMachine() + + self.assertEnters(context: peer2, state: OctagonStateReady, within: 100 * NSEC_PER_SEC) + + + // Now we arrive, and attempt to SOS join + let sosUpgradeStateCondition = self.cuttlefishContext.stateMachine.stateConditions[OctagonStateAttemptSOSUpgrade] as! CKKSCondition + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + self.cuttlefishContext.startOctagonStateMachine() + XCTAssertEqual(0, sosUpgradeStateCondition.wait(10 * NSEC_PER_SEC), "Should attempt SOS upgrade") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Importantly, we should never have asked IDMS for the machine list + XCTAssertEqual(self.mockAuthKit.fetchInvocations, 0, "Shouldn't have asked AuthKit for the machineID during a non-preapproved join attempt") + + // And we should be paused + XCTAssertEqual(self.cuttlefishContext.stateMachine.possiblePendingFlags(), [], "Should have zero pending flags after 'no peers preapprove'") + } + + func testSOSUpgradeWithNoTLKs() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + self.cuttlefishContext.startOctagonStateMachine() + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 1000 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + } + + func testsSOSUpgradeWithCKKSConflict() throws { + // Right after CKKS fetches for the first time, insert a new key hierarchy into CloudKit + self.silentFetchesAllowed = false + self.expectCKFetchAndRun(beforeFinished: { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + self.silentFetchesAllowed = true + }) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + self.cuttlefishContext.startOctagonStateMachine() + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 1000 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + } + + func testSOSJoin() throws { + if(!OctagonPerformSOSUpgrade()) { + return + } + self.startCKAccountStatusMock() + + let peer1EscrowRequestNotification = expectation(forNotification: OTMockEscrowRequestNotification, + object: nil, + handler: nil) + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + + // Due to how everything is shaking out, SOS TLKShares will be uploaded in a second transaction after Octagon uploads its TLKShares + // This isn't great: Octagon: upload SOS TLKShares alongside initial key hierarchy + self.assertAllCKKSViewsUpload(tlkShares: 2) + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + let peer1ID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // Peer1 should have sent a request for silent escrow update + self.wait(for: [peer1EscrowRequestNotification], timeout: 5) + + // Peer1 just joined. It should trust only itself. + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer1ID)), + "peer 1 should trust peer 1") + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 1, "should be 1 bottles") + + ///////////// peer2 + let peer2EscrowRequestNotification = expectation(forNotification: OTMockEscrowRequestNotification, + object: nil, + handler: nil) + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + peer2.startOctagonStateMachine() + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: peer2) + + // Peer2 should have sent a request for silent escrow update + self.wait(for: [peer2EscrowRequestNotification], timeout: 5) + + let peer2ID = try peer2.accountMetadataStore.getEgoPeerID() + + // Right now, peer2 has just upgraded after peer1. It should trust peer1, and both should implictly trust each other + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1 by preapproval") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trustsByPreapproval, target: peer2ID)), + "peer 1 should trust peer 2 by preapproval") + XCTAssertFalse(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should not trust peer 2 (as it hasn't responded to peer2's upgradeJoin yet)") + + // Now, tell peer1 about the change + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + + // Peer1 should trust peer2 now, since it upgraded it from implicitly explicitly trusted + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + } + + func testSOSJoinUponNotificationOfPreapproval() throws { + // Peer 1 becomes SOS+Octagon + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 100 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Peer 2 attempts to join via preapprovalh + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + peer2.startOctagonStateMachine() + + self.assertEnters(context: peer2, state: OctagonStateUntrusted, within: 100 * NSEC_PER_SEC) + + // Now, Peer1 should preapprove Peer2 + let peer2Preapproval = TPHashBuilder.hash(with: .SHA256, of: peer2SOSMockPeer.publicSigningKey.encodeSubjectPublicKeyInfo()) + + // Peer1 should upload TLKs for Peer2 + self.assertAllCKKSViewsUpload(tlkShares: 1) + + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertEqual(peerID, request.peerID, "updateTrust request should be for ego peer ID") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.preapprovals.count, 1, "Should have a single preapproval") + XCTAssertTrue(newDynamicInfo!.preapprovals.contains(peer2Preapproval), "Octagon peer should preapprove new SOS peer") + + // But, since this is an SOS peer and TLK uploads for those peers are currently handled through CK CRUD operations, this update + // shouldn't have any TLKShares + XCTAssertEqual(0, request.tlkShares.count, "Trust update should not have any new TLKShares") + + updateTrustExpectation.fulfill() + return nil + } + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + self.mockSOSAdapter.sendTrustedPeerSetChangedUpdate() + + self.verifyDatabaseMocks() + self.wait(for: [updateTrustExpectation], timeout: 100) + self.fakeCuttlefishServer.updateListener = nil + + // Now, peer2 should receive an Octagon push, realize it is now preapproved, and join + self.sendContainerChange(context: peer2) + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + + func testSOSJoinUponNotificationOfPreapprovalRetry() throws { + // Peer 1 becomes SOS+Octagon + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID!) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID!) + self.saveTLKMaterial(toKeychain: self.manateeZoneID!) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 100 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Peer 2 attempts to join via preapprovalh + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + peer2.startOctagonStateMachine() + + self.assertEnters(context: peer2, state: OctagonStateUntrusted, within: 100 * NSEC_PER_SEC) + + // Now, Peer1 should preapprove Peer2 + let peer2Preapproval = TPHashBuilder.hash(with: .SHA256, of: peer2SOSMockPeer.publicSigningKey.encodeSubjectPublicKeyInfo()) + + // Peer1 should upload TLKs for Peer2 + self.assertAllCKKSViewsUpload(tlkShares: 1) + + // Error out updateTrust1 -- expect a retry + let updateTrustExpectation1 = self.expectation(description: "updateTrust1") + let updateTrustExpectation2 = self.expectation(description: "updateTrust2") + + self.fakeCuttlefishServer.updateListener = { [unowned self] request in + self.fakeCuttlefishServer.updateListener = { request in + self.fakeCuttlefishServer.updateListener = nil + XCTAssertEqual(peerID, request.peerID, "updateTrust request should be for ego peer ID") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.preapprovals.count, 1, "Should have a single preapproval") + XCTAssertTrue(newDynamicInfo!.preapprovals.contains(peer2Preapproval), "Octagon peer should preapprove new SOS peer") + + // But, since this is an SOS peer and TLK uploads for those peers are currently handled through CK CRUD operations, this update + // shouldn't have any TLKShares + XCTAssertEqual(0, request.tlkShares.count, "Trust update should not have any new TLKShares") + + updateTrustExpectation2.fulfill() + return nil + + } + updateTrustExpectation1.fulfill() + + return CKPrettyError(domain:CKErrorDomain, code:CKError.networkUnavailable.rawValue, userInfo:[CKErrorRetryAfterKey: 2]) + } + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + self.mockSOSAdapter.sendTrustedPeerSetChangedUpdate() + + self.wait(for: [updateTrustExpectation1], timeout: 10) + self.wait(for: [updateTrustExpectation2], timeout: 10) + self.verifyDatabaseMocks() + + // Now, peer2 should receive an Octagon push, realize it is now preapproved, and join + self.sendContainerChange(context: peer2) + + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSJoinUponNotificationOfPreapprovalRetryFail() throws { + // Peer 1 becomes SOS+Octagon + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID!) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID!) + self.saveTLKMaterial(toKeychain: self.manateeZoneID!) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 100 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Peer 2 attempts to join via preapprovalh + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + peer2.startOctagonStateMachine() + + self.assertEnters(context: peer2, state: OctagonStateUntrusted, within: 100 * NSEC_PER_SEC) + + // Now, Peer1 should preapprove Peer2 + _ = TPHashBuilder.hash(with: .SHA256, of: peer2SOSMockPeer.publicSigningKey.encodeSubjectPublicKeyInfo()) + + // Peer1 should upload TLKs for Peer2 + self.assertAllCKKSViewsUpload(tlkShares: 1) + + // Error out updateTrust1 -- retry + let updateTrustExpectation1 = self.expectation(description: "updateTrust1") + self.fakeCuttlefishServer.updateListener = { [unowned self] request in + self.fakeCuttlefishServer.updateListener = nil + updateTrustExpectation1.fulfill() + + return NSError(domain: TrustedPeersHelperErrorDomain, + code: Int(TrustedPeersHelperErrorCode.noPreparedIdentity.rawValue)) + } + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + self.mockSOSAdapter.sendTrustedPeerSetChangedUpdate() + + self.verifyDatabaseMocks() + self.wait(for: [updateTrustExpectation1], timeout: 100) + } + + func testSOSAcceptJoinEvenIfMachineIDListOutOfDate() throws { + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + // Peer 2 is not on Peer 1's machine ID list yet + self.mockAuthKit.otherDevices.remove(try! self.mockAuthKit2.machineID()) + + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + + self.assertAllCKKSViewsUpload(tlkShares: 2) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let peer1ID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // Peer1 just joined. It should trust only itself. + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer1ID)), + "peer 1 should trust peer 1") + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 1, "should be 1 bottles") + + ///////////// peer2 + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + peer2.startOctagonStateMachine() + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: peer2) + + let peer2ID = try peer2.accountMetadataStore.getEgoPeerID() + + // Right now, peer2 has just upgraded after peer1. It should trust peer1, and both should implictly trust each other + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1 by preapproval") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trustsByPreapproval, target: peer2ID)), + "peer 1 should trust peer 2 by preapproval") + XCTAssertFalse(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should not trust peer 2 (as it hasn't responded to peer2's upgradeJoin yet)") + + // Now, tell peer1 about the change. It should send some TLKShares. + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Peer1 should trust peer2 now, even though peer2 is not on the machine ID list yet + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + // And then the machine ID list becomes consistent + + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, + sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertTrue(newDynamicInfo?.includedPeerIDs.contains(peer2ID) ?? false, "peer1 should still trust peer2") + updateTrustExpectation.fulfill() + return nil + } + + self.mockAuthKit.otherDevices.insert(try! self.mockAuthKit2.machineID()) + self.cuttlefishContext.incompleteNotificationOfMachineIDListChange() + self.wait(for: [updateTrustExpectation], timeout: 10) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSJoinUploadsNonexistentTLKs() throws { + // Peer 1 becomes SOS+Octagon, but doesn't upload any TLKs + // note that due to how the tests work right now, a different context won't run any CKKS items + + let originalPeerSOSMockPeer = self.createSOSPeer(peerID: "originalPeerID") + let originalPeerContextID = "peer2" + + self.startCKAccountStatusMock() + + // peer2 should preapprove the future Octagon peer for peer1 + let orignalPeerMockSOS = CKKSMockSOSPresentAdapter(selfPeer: originalPeerSOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let originalPeer = self.manager.context(forContainerName: OTCKContainerName, + contextID: originalPeerContextID, + sosAdapter: orignalPeerMockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + originalPeer.startOctagonStateMachine() + self.assertEnters(context: originalPeer, state: OctagonStateReady, within: 40 * NSEC_PER_SEC) + + // Now, the circle status changes + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.cuttlefishContext.startOctagonStateMachine() + + // Peer1 should upload TLKShares for SOS Peer2 via CK CRUD. We should probably fix that someday? + self.assertAllCKKSViewsUpload(tlkShares: 1) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 40 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testSOSDoNotAttemptUpgradeWhenPlatformDoesntSupport() throws { + self.startCKAccountStatusMock() + + self.mockSOSAdapter.sosEnabled = false + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCNotInCircle) + + let everEnteredSOSUpgrade: CKKSCondition = self.cuttlefishContext.stateMachine.stateConditions[OctagonStateAttemptSOSUpgrade] as! CKKSCondition + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + XCTAssertNotEqual(0, everEnteredSOSUpgrade.wait(10 * NSEC_PER_MSEC), "Octagon should have never entered 'attempt sos upgrade'") + } + + func testSOSUpgradeStopsWhenOutOfCircle() throws { + self.startCKAccountStatusMock() + + self.mockSOSAdapter.sosEnabled = true + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCNotInCircle) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testSosUpgradeAndReady() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.sosEnabled = true + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCNotInCircle) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + let upgradeExpectation = self.expectation(description: "waitForOctagonUpgrade") + self.manager.wait(forOctagonUpgrade:OTCKContainerName, context: self.otcliqueContext.context ?? "defaultContext") { error in + XCTAssertNil(error, "operation should not fail") + upgradeExpectation.fulfill() + } + self.wait(for: [upgradeExpectation], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 40 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testDoNotAttemptUpgradeOnRestart() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + self.waitForCKModifications() + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + // Now restart the context, with SOS being in-circle + self.assertAllCKKSViewsUpload(tlkShares: 1) + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting") + + XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting") + } + + func testSOSJoinAndBottle() throws { + if(!OctagonPerformSOSUpgrade()) { + return + } + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2ID") + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + + // Due to how everything is shaking out, SOS TLKShares will be uploaded in a second transaction after Octagon uploads its TLKShares + // This isn't great: Octagon: upload SOS TLKShares alongside initial key hierarchy + self.assertAllCKKSViewsUpload(tlkShares: 2) + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + let peer1ID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + self.assertSelfTLKSharesInCloudKit(peerID: self.mockSOSAdapter.selfPeer.peerID) + self.assertTLKSharesInCloudKit(receiverPeerID: peer2SOSMockPeer.peerID, senderPeerID: self.mockSOSAdapter.selfPeer.peerID) + + // Peer1 just joined. It should trust only itself. + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer1ID)), + "peer 1 should trust peer 1") + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 1, "should be 1 bottles") + + let peer2contextID = "peer2" + let peer2mockSOS = CKKSMockSOSPresentAdapter(selfPeer: peer2SOSMockPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2contextID, + sosAdapter: peer2mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + peer2.startOctagonStateMachine() + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: peer2) + + let peer2ID = try peer2.accountMetadataStore.getEgoPeerID() + + // Right now, peer2 has just upgraded after peer1. It should trust peer1, and peer1 should implictly trust it + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1 by preapproval") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trustsByPreapproval, target: peer2ID)), + "peer 1 should trust peer 2 by preapproval") + XCTAssertFalse(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should not trust peer 2 (as it hasn't responded to peer2's upgradeJoin yet)") + + // Now, tell peer1 about the change + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + + // Peer1 should trust peer2 now, since it upgraded it from implicitly explicitly trusted + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2 after update") + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + var entropy = Data() + var bottleID: String = "" + + //now try restoring bottles + let newGuyUsingBottle = self.manager.context(forContainerName: OTCKContainerName, contextID: "NewGuyUsingBottle") + let peer2AltDSID = try peer2.accountMetadataStore.loadOrCreateAccountMetadata().altDSID + newGuyUsingBottle.startOctagonStateMachine() + + let fetchExpectation = self.expectation(description: "fetch callback occurs") + peer2.fetchEscrowContents { e, bID, s, error in + XCTAssertNotNil(e, "entropy should not be nil") + XCTAssertNotNil(bID, "bID should not be nil") + XCTAssertNotNil(s, "s should not be nil") + XCTAssertNil(error, "error should be nil") + entropy = e! + bottleID = bID! + fetchExpectation.fulfill() + } + self.wait(for: [fetchExpectation], timeout: 10) + + XCTAssertNotNil(peer2AltDSID, "should have a dsid for peer2") + + self.sendContainerChange(context: peer2) + + // The first peer will upload TLKs for the new peer + self.assertAllCKKSViewsUpload(tlkShares: 1) + self.sendContainerChangeWaitForFetchForState(context: self.cuttlefishContext, state: OctagonStateReady) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10*NSEC_PER_SEC) + self.verifyDatabaseMocks() + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + newGuyUsingBottle.join(withBottle: bottleID, entropy: entropy, bottleSalt: peer2AltDSID!) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + self.assertEnters(context: newGuyUsingBottle, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let gonnaFailContext = self.manager.context(forContainerName: OTCKContainerName, contextID: "gonnaFailContext") + gonnaFailContext.startOctagonStateMachine() + let joinWithBottleFailExpectation = self.expectation(description: "joinWithBottleFail callback occurs") + gonnaFailContext.join(withBottle: bottleID, entropy: entropy, bottleSalt: "") { error in + XCTAssertNotNil(error, "error should be nil") + joinWithBottleFailExpectation.fulfill() + } + self.wait(for: [joinWithBottleFailExpectation], timeout: 10) + self.assertEnters(context: gonnaFailContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSPeerUpdatePreapprovesNewPeer() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + self.waitForCKModifications() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + // A new SOS peer arrives! + // We expect a TLK upload for the new peer, as well as an update of preapproved keys + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2-sos-only-ID") + let peer2Preapproval = TPHashBuilder.hash(with: .SHA256, of: peer2SOSMockPeer.publicSigningKey.encodeSubjectPublicKeyInfo()) + + self.assertAllCKKSViewsUpload(tlkShares: 1) + + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertEqual(peerID, request.peerID, "updateTrust request should be for ego peer ID") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.preapprovals.count, 1, "Should have a single preapproval") + XCTAssertTrue(newDynamicInfo!.preapprovals.contains(peer2Preapproval), "Octagon peer should preapprove new SOS peer") + + // But, since this is an SOS peer and TLK uploads for those peers are currently handled through CK CRUD operations, this update + // shouldn't have any TLKShares + XCTAssertEqual(0, request.tlkShares.count, "Trust update should not have any new TLKShares") + + updateTrustExpectation.fulfill() + return nil + } + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + self.mockSOSAdapter.sendTrustedPeerSetChangedUpdate() + + self.verifyDatabaseMocks() + self.wait(for: [updateTrustExpectation], timeout: 10) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testSOSPeerUpdateOnRestartAfterMissingNotification() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + self.startCKAccountStatusMock() + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + self.waitForCKModifications() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + // A new SOS peer arrives! + // We expect a TLK upload for the new peer, as well as an update of preapproved keys + let peer2SOSMockPeer = self.createSOSPeer(peerID: "peer2-sos-only-ID") + let peer2Preapproval = TPHashBuilder.hash(with: .SHA256, of: peer2SOSMockPeer.publicSigningKey.encodeSubjectPublicKeyInfo()) + + self.assertAllCKKSViewsUpload(tlkShares: 1) + + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertEqual(peerID, request.peerID, "updateTrust request should be for ego peer ID") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssertEqual(newDynamicInfo!.preapprovals.count, 1, "Should have a single preapproval") + XCTAssertTrue(newDynamicInfo!.preapprovals.contains(peer2Preapproval), "Octagon peer should preapprove new SOS peer") + + // But, since this is an SOS peer and TLK uploads for those peers are currently handled through CK CRUD operations, this update + // shouldn't have any TLKShares + XCTAssertEqual(0, request.tlkShares.count, "Trust update should not have any new TLKShares") + + updateTrustExpectation.fulfill() + return nil + } + + self.mockSOSAdapter.trustedPeers.add(peer2SOSMockPeer) + + // But, SOS doesn't send this update. Let's test that the upload occurs on the next securityd restart + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.cuttlefishContext.startOctagonStateMachine() + + self.verifyDatabaseMocks() + self.wait(for: [updateTrustExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + // BUT, a second restart shouldn't hit the server + + self.fakeCuttlefishServer.updateListener = { request in + XCTFail("shouldn't have updateTrusted") + return nil + } + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testResetAndEstablishDoesNotReuploadSOSTLKShares() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + // Also, during the establish, Octagon shouldn't bother uploading the TLKShares that already exist + // So, it should have exactly the number of TLKShares as TLKs, and they should be shared to the new identity + let establishExpectation = self.expectation(description: "establish") + self.fakeCuttlefishServer.establishListener = { request in + XCTAssertEqual(request.tlkShares.count, request.viewKeys.count, "Should upload one TLK per keyset") + for tlkShare in request.tlkShares { + XCTAssertEqual(tlkShare.sender, request.peer.peerID, "TLKShare should be sent from uploading identity") + XCTAssertEqual(tlkShare.receiver, request.peer.peerID, "TLKShare should be sent to uploading identity") + } + establishExpectation.fulfill() + return nil + } + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.wait(for: [establishExpectation], timeout: 10) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Now, set up for calling resetAndEstablish + + let nextEstablishExpectation = self.expectation(description: "establish() #2") + self.fakeCuttlefishServer.establishListener = { request in + XCTAssertEqual(request.tlkShares.count, request.viewKeys.count, "Should upload one TLK per keyset") + for tlkShare in request.tlkShares { + XCTAssertEqual(tlkShare.sender, request.peer.peerID, "TLKShare should be sent from uploading identity") + XCTAssertEqual(tlkShare.receiver, request.peer.peerID, "TLKShare should be sent to uploading identity") + } + nextEstablishExpectation.fulfill() + return nil + } + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish") + self.cuttlefishContext.rpcResetAndEstablish() { error in + XCTAssertNil(error, "Should be no error performing a reset and establish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation, nextEstablishExpectation], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testResetAndEstablishReusesSOSKeys() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // Fetch permanent info information + let dumpExpectation = self.expectation(description: "dump callback occurs") + var encryptionPubKey = Data() + var signingPubKey = Data() + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + + let permanentInfo = egoSelf!["permanentInfo"] as? Dictionary + XCTAssertNotNil(permanentInfo, "should have a permanent info") + + let epk = permanentInfo!["encryption_pub_key"] as? Data + XCTAssertNotNil(epk, "Should have an encryption public key") + encryptionPubKey = epk! + + let spk = permanentInfo!["signing_pub_key"] as? Data + XCTAssertNotNil(spk, "Should have an signing public key") + signingPubKey = spk! + + dumpExpectation.fulfill() + } + self.wait(for: [dumpExpectation], timeout: 10) + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish") + self.cuttlefishContext.rpcResetAndEstablish() { error in + XCTAssertNil(error, "Should be no error performing a reset and establish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // And check that the pub keys are equivalent + let dumpResetExpectation = self.expectation(description: "dump callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + + let permanentInfo = egoSelf!["permanentInfo"] as? Dictionary + XCTAssertNotNil(permanentInfo, "should have a permanent info") + + let epk = permanentInfo!["encryption_pub_key"] as? Data + XCTAssertNotNil(epk, "Should have an encryption public key") + XCTAssertEqual(encryptionPubKey, epk!, "Encryption public key should be the same across a reset") + + let spk = permanentInfo!["signing_pub_key"] as? Data + XCTAssertNotNil(spk, "Should have an signing public key") + XCTAssertEqual(signingPubKey, spk!, "Signing public key should be the same across a reset") + + dumpResetExpectation.fulfill() + } + self.wait(for: [dumpResetExpectation], timeout: 10) + } + + func testSOSUpgradeWithFailingAuthKit() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + self.mockAuthKit.machineIDFetchErrors.append(NSError(domain:AKAppleIDAuthenticationErrorDomain, + code:AKAppleIDAuthenticationError.authenticationErrorCannotFindServer.rawValue, + userInfo:nil)) + + // Octagon should decide it is quite sad. + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + } + + func testCliqueOctagonUpgrade () throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + self.startCKAccountStatusMock() + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + OctagonSetPlatformSupportsSOS(true) + + var clique : OTClique? + XCTAssertNoThrow(clique = try OTClique.init(contextData: self.otcliqueContext)) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertNoThrow(try clique!.waitForOctagonUpgrade(), "Upgrading should pass") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + } + + func testCliqueOctagonUpgradeFail () throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putSelfTLKShares(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + self.startCKAccountStatusMock() + + XCTAssertTrue(OctagonPerformSOSUpgrade(), "SOS upgrade should be on") + + OctagonSetPlatformSupportsSOS(true) + + var clique : OTClique? + XCTAssertNoThrow(clique = try OTClique.init(contextData: self.otcliqueContext)) + XCTAssertNotNil(clique, "Clique should not be nil") + XCTAssertThrowsError(try clique!.waitForOctagonUpgrade(), "Upgrading should fail") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + } +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTests-BridgingHeader.h b/keychain/ot/tests/octagon/OctagonTests-BridgingHeader.h new file mode 100644 index 00000000..6c83e44d --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests-BridgingHeader.h @@ -0,0 +1,88 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import +#import + +#import + +#import +#import +#import + +#import +#import +#import "utilities/SecFileLocations.h" +#import "utilities/SecCFError.h" + + +#import "securityd/SecItemServer.h" +#import "securityd/spi.h" + +#import +#import "keychain/ckks/CKKS.h" +#import "keychain/ckks/CKKSKeychainView.h" + +#import +#import +#import +#import +#import +#import + +#import "keychain/ot/OT.h" +#import "keychain/ot/OTClique.h" +#import "keychain/ot/OTControl.h" +#import "keychain/ot/OTControlProtocol.h" + +#import "keychain/ot/OTSOSAdapter.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTDefines.h" +#import "keychain/ot/OTStates.h" +#import "keychain/ot/OTCuttlefishContext.h" +#import "keychain/ot/OctagonStateMachine.h" + +#import "keychain/ot/OTDeviceInformationAdapter.h" + +#import "keychain/ot/tests/OTTestsBase.h" +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" + +#import "keychain/ckks/CKKSKeychainBackedKey.h" +#import "keychain/ckks/CKKSPeer.h" +#import "keychain/ckks/CKKSTLKShare.h" +#import "keychain/ckks/CKKSAnalytics.h" +#import "keychain/ckks/CloudKitCategories.h" + +#import "keychain/ot/OctagonControlServer.h" + +#import "keychain/ot/proto/generated_source/OTAccountMetadataClassC.h" +#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h" +#import "keychain/ot/categories/OctagonEscrowRecoverer.h" + +#import "keychain/otctl/OTControlCLI.h" + +// Also, we're going to need whatever TPH needs. +#import "keychain/TrustedPeersHelper/TrustedPeersHelper-Bridging-Header.h" + +#import "keychain/SecureObjectSync/SOSControlServer.h" +#import "KeychainCircle/Tests/FakeSOSControl.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" + +//CDP +#import +#import +#import + +#import + +#import "tests/secdmockaks/mockaks.h" + +//recovery key +#import +#import + +#import "TestsObjcTranslation.h" + +#include +#import "keychain/ot/OctagonCKKSPeerAdapter.h" diff --git a/keychain/ot/tests/octagon/OctagonTests-Info.plist b/keychain/ot/tests/octagon/OctagonTests-Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests-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/ot/tests/octagon/OctagonTests.swift b/keychain/ot/tests/octagon/OctagonTests.swift new file mode 100644 index 00000000..2a0b2611 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTests.swift @@ -0,0 +1,2731 @@ +import CoreData +import XCTest + +#if OCTAGON +import CloudKitCode + +class FakeCuttlefishInvocableCreator: ContainerNameToCuttlefishInvocable { + let server: FakeCuttlefishServer + + init(server: FakeCuttlefishServer) { + self.server = server + } + + func client(container: String) -> CloudKitCode.Invocable { + // TODO: this class should probably separate containers somehow. + return self.server + } +} + +class OTMockDeviceInfoAdapter: OTDeviceInformationAdapter { + let mockModelID: String + let mockDeviceName: String? + let mockOsVersion: String + let mockSerialNumber: String + + init(modelID: String, deviceName: String?, serialNumber: String, osVersion: String) { + self.mockModelID = modelID + self.mockDeviceName = deviceName + self.mockSerialNumber = serialNumber + self.mockOsVersion = osVersion + } + + func modelID() -> String { + return self.mockModelID + } + + func deviceName() -> String? { + return self.mockDeviceName + } + + func osVersion() -> String { + return self.mockOsVersion + } + + func serialNumber() -> String { + return self.mockSerialNumber + } +} + +class OTMockDeviceInfoAdapterFakeSerial: OTDeviceInformationAdapter +{ + let mockSerialNumber: String + let actualAdapter: OTDeviceInformationActualAdapter + + init() { + mockSerialNumber = NSUUID().uuidString + actualAdapter = OTDeviceInformationActualAdapter() + } + func modelID() -> String { + return self.actualAdapter.modelID() + } + + func deviceName() -> String? { + return self.actualAdapter.deviceName() + } + + func osVersion() -> String { + return self.actualAdapter.osVersion() + } + + func serialNumber() -> String { + return self.mockSerialNumber + } +} + + +class OTMockAuthKitAdapter: OTAuthKitAdapter { + // A nil altDSID means 'no authkit account' + var altDSID: String? + + var hsa2: Bool + + let currentMachineID: String + var otherDevices: Set + var excludeDevices: Set + + var machineIDFetchErrors: [NSError] = [] + + var fetchCondition: CKKSCondition? + + var fetchInvocations: Int = 0 + + var listeners: CKKSListenerCollection + + init(altDSID: String?, machineID: String, otherDevices: Set) { + self.altDSID = altDSID + self.currentMachineID = machineID + self.otherDevices = otherDevices + self.excludeDevices = Set() + self.hsa2 = true + self.listeners = CKKSListenerCollection(name: "test-authkit") + } + + func primaryiCloudAccountAltDSID() -> String? { + return self.altDSID + } + + func accountIsHSA2(byAltDSID altDSID: String) -> Bool { + // TODO: do we need to examine altDSID here? + return self.hsa2 + } + + func machineID() throws -> String { + // TODO: throw if !accountPresent + return self.currentMachineID + } + + func fetchCurrentDeviceList(_ complete: @escaping (Set?, Error?) -> Void) { + self.fetchInvocations += 1 + if let error = self.machineIDFetchErrors.first { + self.machineIDFetchErrors.removeFirst() + complete(nil, error) + return + } + + if let fetchCondition = self.fetchCondition { + fetchCondition.fulfill() + } + + // TODO: fail if !accountPresent + complete(self.currentDeviceList(), nil) + } + + func currentDeviceList() -> Set { + // Always succeeds. + return Set([self.currentMachineID]).union(otherDevices).subtracting(excludeDevices) + } + + func sendIncompleteNotification() { + self.listeners.iterateListeners { + $0.incompleteNotificationOfMachineIDListChange() + } + } + + func addAndSendNotification(machineID: String) { + self.otherDevices.insert(machineID) + self.excludeDevices.remove(machineID) + self.sendAddNotification(machineID: machineID, altDSID: self.altDSID!) + } + + func sendAddNotification(machineID: String, altDSID: String) { + self.listeners.iterateListeners { + $0.machinesAdded([machineID], altDSID: altDSID) + } + } + + func removeAndSendNotification(machineID: String) { + self.excludeDevices.insert(machineID) + self.sendRemoveNotification(machineID: machineID, altDSID: self.altDSID!) + } + + func sendRemoveNotification(machineID: String, altDSID: String) { + self.listeners.iterateListeners { + $0.machinesRemoved([machineID], altDSID: altDSID) + } + } + + func registerNotification(_ notifier: OTAuthKitAdapterNotifier) { + self.listeners.registerListener(notifier) + } +} + +class OTMockLogger: NSObject, SFAnalyticsProtocol { + static func logger() -> SFAnalyticsProtocol? { + return OTMockLogger() + } + + func logResult(forEvent eventName: String, hardFailure: Bool, result eventResultError: Error?) { + // pass + } + + func logResult(forEvent eventName: String, hardFailure: Bool, result eventResultError: Error?, withAttributes attributes: [AnyHashable: Any]? = nil) { + // pass + } + + func logSystemMetrics(forActivityNamed eventName: String, withAction action: (() -> Void)? = nil) -> SFAnalyticsActivityTracker? { + // pass + return nil + } + + func startLogSystemMetrics(forActivityNamed eventName: String) -> SFAnalyticsActivityTracker? { + // pass + return nil + } + + func addMultiSampler(forName samplerName: String, withTimeInterval timeInterval: TimeInterval, block: @escaping () -> [String: NSNumber]) -> SFAnalyticsMultiSampler? { + // in this case, why don't we just try calling the block, just to see what happens? + // Then, don't do any follow up + _ = block() + return nil + } +} + +let OTMockEscrowRequestNotification = Notification.Name("silent-escrow-request-triggered") +class OTMockSecEscrowRequest: NSObject, SecEscrowRequestable { + + static var populateStatuses = false + var statuses: [String: String] = [:] + + static func request() throws -> SecEscrowRequestable { + let request = OTMockSecEscrowRequest() + if populateStatuses == true { + request.statuses["uuid"] = SecEscrowRequestPendingCertificate + } + return request + } + + func triggerEscrowUpdate(_ reason: String) throws { + NotificationCenter.default.post(name: OTMockEscrowRequestNotification, object: nil) + } + + func fetchStatuses() throws -> [AnyHashable : Any] { + return statuses + } + + func pendingEscrowUpload(_ error: NSErrorPointer) -> Bool { + if statuses["uuid"] == SecEscrowRequestPendingCertificate { + return true + } + else { + return false + } + } +} + +class OctagonTestsBase: CloudKitKeychainSyncingTestsBase { + + var tmpPath: String! + var tmpURL: URL! + + var manager: OTManager! + var cuttlefishContext: OTCuttlefishContext! + + var otcliqueContext: OTConfigurationContext! + + var manateeZoneID: CKRecordZone.ID! + var fakeCuttlefishServer: FakeCuttlefishServer! + var fakeCuttlefishCreator: FakeCuttlefishInvocableCreator! + var tphClient: Client! + var tphXPCProxy: ProxyXPCConnection! + + var accountAltDSID: String! + + // These three mock authkits will all include each other in their machine ID list + var mockAuthKit: OTMockAuthKitAdapter! + var mockAuthKit2: OTMockAuthKitAdapter! + var mockAuthKit3: OTMockAuthKitAdapter! + + var otControl: OTControl! + var otXPCProxy: ProxyXPCConnection! + var otControlEntitlementBearer: FakeOTControlEntitlementBearer! + var otControlEntitlementChecker: OTControlProtocol! + var otControlCLI: OTControlCLI! + + var otFollowUpController: OTMockFollowUpController! + + override static func setUp() { + UserDefaults.standard.register(defaults: ["com.apple.CoreData.ConcurrencyDebug": 1]) + OctagonSetShouldPerformInitialization(true) + SecCKKSEnable() + + super.setUp() + + // Turn on NO_SERVER stuff + securityd_init_local_spi() + } + + func deviceInformationAdapter() -> OTDeviceInformationAdapter { + return OTMockDeviceInfoAdapterFakeSerial() + } + + override func setUp() { + // Set the global bool to TRUE + OctagonSetIsEnabled(true) + + // Until we can reasonably run SOS in xctest, this must be off. Note that this makes our tests + // not accurately reproduce what a real device would do. + OctagonSetPlatformSupportsSOS(false) + + // Tell SecDb not to initialize the manager (as we haven't made our fake one yet). + // Each test is responsible for initialization, to allow for pre-test setup + OctagonSetShouldPerformInitialization(false) + + super.setUp() + + // Octagon must initialize the views + self.automaticallyBeginCKKSViewCloudKitOperation = false + + // The CKKStests use the "keychain" view heavily, but that causes issues in Octagon as it isn't in the Octagon policy. + // Replace it with the Manatee view, unless you're on an appleTV: in that case, make it the LimitedPeersAllowed view + self.injectedManager!.clearAllViews() + #if !os(tvOS) + self.ckksViews = NSMutableSet(array: [self.injectedManager!.findOrCreateView("Manatee")]) + self.manateeZoneID = CKRecordZone.ID(zoneName: "Manatee") + #else + self.ckksViews = NSMutableSet(array: [self.injectedManager!.findOrCreateView("LimitedPeersAllowed")]) + self.manateeZoneID = CKRecordZone.ID(zoneName: "LimitedPeersAllowed") + #endif + + self.zones!.removeAllObjects() + self.zones![self.manateeZoneID] = FakeCKZone(zone: self.manateeZoneID) + + // Asserting a type on self.zones seems to duplicate the dictionary, but not deep-copy the contents + // We'll use them as NSMutableDictionaries, I guess + self.fakeCuttlefishServer = FakeCuttlefishServer(nil, ckZones: self.zones!, ckksZoneKeys: self.keys!) + + self.fakeCuttlefishCreator = FakeCuttlefishInvocableCreator(server: self.fakeCuttlefishServer) + self.tphClient = Client(endpoint: nil, containerMap: ContainerMap(invocableCreator: fakeCuttlefishCreator)) + + self.otFollowUpController = OTMockFollowUpController() + + // Octagon requires the self peer keys to be persisted in the keychain + saveToKeychain(keyPair: self.mockSOSAdapter.selfPeer.signingKey, label: "com.apple.securityd.sossigningkey") + saveToKeychain(keyPair: self.mockSOSAdapter.selfPeer.encryptionKey, label: "com.apple.securityd.sosencryptionkey") + + self.mockAuthKit = OTMockAuthKitAdapter(altDSID: UUID().uuidString, machineID: "MACHINE1", otherDevices: ["MACHINE2", "MACHINE3"]) + self.mockAuthKit2 = OTMockAuthKitAdapter(altDSID: self.mockAuthKit.altDSID, machineID: "MACHINE2", otherDevices: ["MACHINE1", "MACHINE3"]) + self.mockAuthKit3 = OTMockAuthKitAdapter(altDSID: self.mockAuthKit.altDSID, machineID: "MACHINE3", otherDevices: ["MACHINE1", "MACHINE2"]) + + // By default, not in SOS when test starts + // And under octagon, SOS trust is not essential + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCNotInCircle) + self.mockSOSAdapter.essential = false + + let tphInterface = TrustedPeersHelperSetupProtocol(NSXPCInterface(with: TrustedPeersHelperProtocol.self)) + self.tphXPCProxy = ProxyXPCConnection(self.tphClient, interface: tphInterface) + + self.manager = OTManager(context: nil, + localStore: nil, + enroll: nil, + restore: nil, + cfu: nil, + cfuScheduler: nil, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit, + deviceInformationAdapter: deviceInformationAdapter(), + apsConnectionClass: FakeAPSConnection.self, + escrowRequestClass: OTMockSecEscrowRequest.self, + loggerClass: OTMockLogger.self, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + cuttlefishXPCConnection: tphXPCProxy.connection(), + cdpd: self.otFollowUpController) + + OTManager.resetManager(true, to: self.manager) + + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.otControlEntitlementBearer = FakeOTControlEntitlementBearer() + self.otControlEntitlementChecker = OctagonXPCEntitlementChecker.create(with: self.manager, entitlementBearer: self.otControlEntitlementBearer) + + self.otXPCProxy = ProxyXPCConnection(self.otControlEntitlementChecker, interface: OTSetupControlProtocol(NSXPCInterface(with: OTControlProtocol.self))) + self.otControl = OTControl(connection: self.otXPCProxy.connection(), sync: true) + + self.otControlCLI = OTControlCLI(otControl: self.otControl) + + self.otcliqueContext = OTConfigurationContext() + self.otcliqueContext.context = OTDefaultContext + self.otcliqueContext.dsid = "1234" + self.otcliqueContext.altDSID = self.mockAuthKit.altDSID! + self.otcliqueContext.otControl = self.otControl + } + + override func tearDown() { + let statusExpectation = self.expectation(description: "status callback occurs") + self.cuttlefishContext.rpcStatus() { _, _ in + statusExpectation.fulfill() + } + self.wait(for: [statusExpectation], timeout: 10) + + self.manager.allContextsDisablePendingFlags() + self.manager.allContextsHalt() + + if self.cuttlefishContext.stateMachine.currentState != OctagonStateMachineNotStarted { + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(20 * NSEC_PER_SEC), "Main cuttlefish context should quiesce before the test ends") + } + + // Stop all of CKKS + self.injectedManager!.haltAll() + + XCTAssertTrue(self.manager.allContextsPause(10*NSEC_PER_SEC), "All cuttlefish contexts should pause") + + super.tearDown() + } + + override func managedViewList() -> Set { + #if !os(tvOS) + return Set(["Manatee"]) + #else + return Set(["LimitedPeersAllowed"]) + #endif + } + + func fetchEgoPeerID() -> String { + var ret: String! + let fetchPeerIDExpectation = self.expectation(description: "fetchPeerID callback occurs") + self.cuttlefishContext.rpcFetchEgoPeerID { peerID, fetchError in + XCTAssertNil(fetchError, "should not error fetching ego peer ID") + XCTAssertNotNil(peerID, "Should have a peer ID") + ret = peerID + fetchPeerIDExpectation.fulfill() + } + self.wait(for: [fetchPeerIDExpectation], timeout: 10) + return ret + } + + func setAllowListToCurrentAuthKit(container: String, context: String) { + let allowListExpectation = self.expectation(description: "set allow list callback occurs") + self.tphClient.setAllowedMachineIDsWithContainer(container, + context: context, + allowedMachineIDs: self.mockAuthKit.currentDeviceList()) { _, error in + XCTAssertNil(error, "Should be no error setting allow list") + allowListExpectation.fulfill() + } + self.wait(for: [allowListExpectation], timeout: 10) + } + + func saveToKeychain(keyPair: _SFECKeyPair, label: String) { + let status = SecItemAdd([kSecValueRef as String: keyPair.secKey!, + kSecClass as String: kSecClassKey as String, + kSecAttrApplicationTag as String: label.data(using: .utf8)!, + kSecUseDataProtectionKeychain as String: true, ] as CFDictionary, nil) + XCTAssertEqual(status, errSecSuccess, "Should be able to save a key in the keychain") + } + + func tmpStoreDescription(name: String) -> NSPersistentStoreDescription { + let tmpStoreURL = URL(fileURLWithPath: name, relativeTo: tmpURL) + return NSPersistentStoreDescription(url: tmpStoreURL) + } + + func assertEnters(context: OTCuttlefishContext, state: String, within: UInt64) { + XCTAssertEqual(0, (context.stateMachine.stateConditions[state] as! CKKSCondition).wait(within), "State machine should enter '\(state)'") + if(state == OctagonStateReady || state == OctagonStateUntrusted) { + XCTAssertEqual(0, context.stateMachine.paused.wait(10 * NSEC_PER_SEC), "State machine should pause soon") + } + } + + func assertConsidersSelfTrusted(context: OTCuttlefishContext, isLocked: Bool = false) { + XCTAssertEqual(context.currentMemoizedTrustState(), .TRUSTED, "Trust state (for \(context)) should be trusted") + + let statusexpectation = self.expectation(description: "trust status returns") + let configuration = OTOperationConfiguration() + configuration.timeoutWaitForCKAccount = 500*NSEC_PER_MSEC + context.rpcTrustStatus(configuration) { egoStatus, egoPeerID, _, isLocked, error in + XCTAssertEqual(egoStatus, .in, "Self peer (for \(context)) should be trusted") + XCTAssertNotNil(egoPeerID, "Should have a peerID") + XCTAssertEqual(isLocked, isLocked, "should be \(isLocked)") + statusexpectation.fulfill() + } + self.wait(for: [statusexpectation], timeout: 10) + } + + func assertConsidersSelfTrustedCachedAccountStatus(context: OTCuttlefishContext) { + XCTAssertEqual(context.currentMemoizedTrustState(), .TRUSTED, "Trust state (for \(context)) should be trusted") + + let cachedStatusexpectation = self.expectation(description: "(cached) trust status returns") + let configuration = OTOperationConfiguration() + configuration.useCachedAccountStatus = true + configuration.timeoutWaitForCKAccount = 500*NSEC_PER_MSEC + + context.rpcTrustStatus(configuration) { egoStatus, egoPeerID, _, isLocked, error in + XCTAssertEqual(egoStatus, .in, "Cached self peer (for \(context)) should be trusted") + XCTAssertNotNil(egoPeerID, "Should have a (cached) peerID") + cachedStatusexpectation.fulfill() + } + self.wait(for: [cachedStatusexpectation], timeout: 10) + + let cliqueConfiguration = OTConfigurationContext() + cliqueConfiguration.context = context.contextID + cliqueConfiguration.dsid = "1234" + cliqueConfiguration.altDSID = self.mockAuthKit.altDSID! + cliqueConfiguration.otControl = self.otControl + let otclique = try! OTClique(contextData: cliqueConfiguration) + + let status = otclique.cachedCliqueStatus(true, error: nil) + XCTAssertEqual(status, .in, "OTClique API should return (trusted)") + + configuration.useCachedAccountStatus = false + let statusexpectation = self.expectation(description: "(cached) trust status returns") + context.rpcTrustStatus(configuration) { egoStatus, egoPeerID, _, isLocked, error in + XCTAssertEqual(egoStatus, .in, "Self peer (for \(context)) should be trusted") + XCTAssertNotNil(egoPeerID, "Should have a peerID") + statusexpectation.fulfill() + } + self.wait(for: [statusexpectation], timeout: 10) + } + + func assertConsidersSelfUntrusted(context: OTCuttlefishContext) { + XCTAssertEqual(context.currentMemoizedTrustState(), .UNTRUSTED, "Trust state (for \(context)) should be untrusted") + let statusexpectation = self.expectation(description: "trust status returns") + let configuration = OTOperationConfiguration() + configuration.timeoutWaitForCKAccount = 500*NSEC_PER_MSEC + self.cuttlefishContext.rpcTrustStatus(configuration) { egoStatus, egoPeerID, _, isLocked, error in + // TODO: separate 'untrusted' and 'no trusted peers for account yet' + XCTAssertTrue([.notIn, .absent].contains(egoStatus), "Self peer (for \(context)) should be distrusted or absent") + statusexpectation.fulfill() + } + self.wait(for: [statusexpectation], timeout: 10) + } + + func assertNoAccount(context: OTCuttlefishContext) { + XCTAssertEqual(context.currentMemoizedAccountState(), .NO_ACCOUNT, "Account state (for \(context)) should be no account") + } + + func assertTrusts(context: OTCuttlefishContext, includedPeerIDCount: Int, excludedPeerIDCount: Int) { + let dumpCallback = self.expectation(description: "dump callback occurs") + self.tphClient.dumpEgoPeer(withContainer: context.containerName, context: context.contextID) { peerID, permanentInfo, stableInfo, dynamicInfo, error in + XCTAssertNil(error, "should be no error") + XCTAssertNotNil(dynamicInfo, "Should be a dynamic info") + XCTAssertEqual(dynamicInfo!.includedPeerIDs.count, includedPeerIDCount, "should be \(includedPeerIDCount) included peer ids") + XCTAssertEqual(dynamicInfo!.excludedPeerIDs.count, excludedPeerIDCount, "should be \(excludedPeerIDCount) excluded peer ids") + + dumpCallback.fulfill() + } + self.wait(for: [dumpCallback], timeout: 10) + } + + func restartCKKSViews() { + let viewNames = self.ckksViews.map { ($0 as! CKKSKeychainView).zoneName } + self.ckksViews.removeAllObjects() + for view in viewNames { + self.ckksViews.add(self.injectedManager!.restartZone(view)) + } + } + + func sendAllCKKSTrustedPeersChanged() { + self.ckksViews.forEach { view in + (view as! CKKSKeychainView).trustedPeerSetChanged(nil) + } + } + + func assert(ckks: CKKSKeychainView, enters: String, within: UInt64) { + XCTAssertEqual(0, (ckks.keyHierarchyConditions[enters] as! CKKSCondition).wait(within), "CKKS state machine should enter '\(enters)' (currently '\(ckks.keyHierarchyState)')") + } + + func assertAllCKKSViews(enter: String, within: UInt64) { + for view in self.ckksViews { + self.assert(ckks: view as! CKKSKeychainView, enters: enter, within: within) + } + } + + func assertAllCKKSViewsUploadKeyHierarchy(tlkShares: UInt) { + self.ckksViews.forEach { view in + self.expectCKModifyKeyRecords(3, currentKeyPointerRecords: 3, tlkShareRecords: tlkShares, zoneID: (view as! CKKSKeychainView).zoneID) + } + } + + func assertAllCKKSViewsUpload(tlkShares: UInt) { + self.ckksViews.forEach { view in + self.expectCKModifyKeyRecords(0, currentKeyPointerRecords: 0, tlkShareRecords: tlkShares, zoneID: (view as! CKKSKeychainView).zoneID) + } + } + + func resetAllCKKSViews() { + let resetExpectation = self.expectation(description: "rpcResetCloudKit callback occurs") + self.injectedManager!.rpcResetCloudKit(nil, reason:"octagon=unit-test") { error in + XCTAssertNil(error, "Error should be nil?") + resetExpectation.fulfill() + } + + self.wait(for: [resetExpectation], timeout: 30) + } + + func putSelfTLKShareInCloudKit(context: OTCuttlefishContext, zoneID: CKRecordZone.ID) throws { + let accountMetadata = try context.accountMetadataStore.loadOrCreateAccountMetadata() + let peerKeys: OctagonSelfPeerKeys = try loadEgoKeysSync(peerID: accountMetadata.peerID) + let zoneKeys = self.keys![zoneID] as! ZoneKeys + self.putTLKShare(inCloudKit: zoneKeys.tlk!, from: peerKeys, to: peerKeys, zoneID: zoneID) + } + + func assertSelfTLKSharesInCloudKit(context: OTCuttlefishContext) { + let accountMetadata = try! context.accountMetadataStore.loadOrCreateAccountMetadata() + self.assertSelfTLKSharesInCloudKit(peerID: accountMetadata.peerID) + } + + func assertSelfTLKSharesInCloudKit(peerID: String) { + self.assertTLKSharesInCloudKit(receiverPeerID: peerID, senderPeerID: peerID) + } + + func assertTLKSharesInCloudKit(receiver: OTCuttlefishContext, sender: OTCuttlefishContext) { + let receiverAccountMetadata = try! receiver.accountMetadataStore.loadOrCreateAccountMetadata() + let senderAccountMetadata = try! sender.accountMetadataStore.loadOrCreateAccountMetadata() + + self.assertTLKSharesInCloudKit(receiverPeerID: receiverAccountMetadata.peerID, + senderPeerID: senderAccountMetadata.peerID) + } + + func assertTLKSharesInCloudKit(receiverPeerID: String, senderPeerID: String) { + for case let view as CKKSKeychainView in self.ckksViews { + XCTAssertNoThrow(try self.assertTLKShareInCloudKit(receiverPeerID: receiverPeerID, senderPeerID: senderPeerID, zoneID: view.zoneID), "view \(view) should have a self TLK uploaded") + } + } + + func assertTLKShareInCloudKit(receiverPeerID: String, senderPeerID: String, zoneID: CKRecordZone.ID) throws { + let zone = self.zones![zoneID] as! FakeCKZone + + let tlkShares = zone.currentDatabase.allValues.filter { ($0 as? CKRecord)?.recordType == SecCKRecordTLKShareType }.map { CKKSTLKShareRecord(ckRecord: $0 as! CKRecord) } + + for share in tlkShares { + if share.share.receiverPeerID == receiverPeerID && share.senderPeerID == senderPeerID { + // Found one! + return + } + } + + XCTFail("Unable to find a TLKShare for peer ID \(String(describing: receiverPeerID)) sent by \(String(describing: senderPeerID))") + } + + func assertMIDList(context: OTCuttlefishContext, + allowed: Set, + disallowed: Set = Set(), + unknown: Set = Set()) { + let container = try! self.tphClient.getContainer(withContainer: context.containerName, context: context.contextID) + container.moc.performAndWait { + let midList = container.onqueueCurrentMIDList() + XCTAssertEqual(midList.machineIDs(in: .allowed), allowed, "Model's allowed list should match pattern") + XCTAssertEqual(midList.machineIDs(in: .disallowed), disallowed, "Model's disallowed list should match pattern") + XCTAssertEqual(midList.machineIDs(in: .unknown), unknown, "Model's unknown list should match pattern") + } + } + + func loadSecret(label: String) throws -> (Data?) { + var secret: Data? + + let query: [CFString: Any] = [ + kSecClass: kSecClassInternetPassword, + kSecAttrAccessGroup: "com.apple.security.octagon", + kSecAttrDescription: label, + kSecReturnAttributes: true, + kSecReturnData: true, + kSecAttrSynchronizable: kCFBooleanFalse, + kSecMatchLimit: kSecMatchLimitOne, + ] + + var result: CFTypeRef? + let status = SecItemCopyMatching(query as CFDictionary, &result) + + if status != errSecSuccess || result == nil { + throw ContainerError.failedToLoadSecret(errorCode: Int(status)) + } + + if result != nil { + if let dictionary = result as? Dictionary { + secret = dictionary[kSecValueData] as? Data + } else { + throw ContainerError.failedToLoadSecretDueToType + } + } + return secret + } + + func sendContainerChange(context: OTCuttlefishContext) { + context.notifyContainerChange(userInfo: [ + "aps": [ + "content-available": 1, + ], + "cf": [ + "c": "com.apple.security.keychain", + "f": "fake-testing-function", + "r": "fake-request-uuid", + ], + ]) + } + + func sendTTRRequest(context: OTCuttlefishContext) { + context.notifyContainerChange(userInfo: [ + "aps": [ + "content-available": 1, + ], + "cf": [ + "c": "com.apple.security.keychain", + "f": "fake-testing-function", + "k": "r", + "a": "title", + "d": "description", + "R": "radarNumber", + ], + ]) + } + + + func sendContainerChangeWaitForFetch(context: OTCuttlefishContext) { + self.sendContainerChangeWaitForFetchForStates(context: context, states: [OctagonStateReadyUpdated, OctagonStateReady]) + } + + func sendContainerChangeWaitForUntrustedFetch(context: OTCuttlefishContext) { + self.sendContainerChangeWaitForFetchForStates(context: context, states: [OctagonStateUntrustedUpdated, OctagonStateUntrusted]) + } + + func sendContainerChangeWaitForFetchForState(context: OTCuttlefishContext, state: String) { + return self.sendContainerChangeWaitForFetchForStates(context: context, states: [state]) + } + + func sendContainerChangeWaitForFetchForStates(context: OTCuttlefishContext, states: [String]) { + let updateTrustExpectation = self.expectation(description: "fetchChanges") + self.fakeCuttlefishServer.fetchChangesListener = { request in + self.fakeCuttlefishServer.fetchChangesListener = nil + updateTrustExpectation.fulfill() + return nil + } + context.notifyContainerChange(nil) + self.wait(for: [updateTrustExpectation], timeout: 10) + for state in states { + self.assertEnters(context: context, state: state, within: 10 * NSEC_PER_SEC) + } + } + + func createSOSPeer(peerID: String) -> CKKSSOSSelfPeer { + let peer = CKKSSOSSelfPeer(sosPeerID: peerID, + encryptionKey: _SFECKeyPair.init(randomKeyPairWith: _SFECKeySpecifier.init(curve: SFEllipticCurve.nistp384))!, + signingKey: _SFECKeyPair.init(randomKeyPairWith: _SFECKeySpecifier.init(curve: SFEllipticCurve.nistp384))!, + viewList: self.managedViewList()) + + saveToKeychain(keyPair: peer.signingKey, label: "com.apple.securityd." + peerID + ".sossigningkey") + saveToKeychain(keyPair: peer.encryptionKey, label: "com.apple.securityd." + peerID + ".sosencryptionkey") + + return peer + } + + func makeInitiatorDeviceInfoAdapter() -> OTMockDeviceInfoAdapter { + // Note that the type of your initiator changes based on the platform you're currently on + return OTMockDeviceInfoAdapter(modelID: self.deviceInformationAdapter().modelID(), + deviceName: "test-device-2", + serialNumber: "456", + osVersion: "iSomething (fake version)") + } + + func makeInitiatorContext(contextID: String) -> OTCuttlefishContext { + return self.makeInitiatorContext(contextID: contextID, authKitAdapter: self.mockAuthKit2) + } + + func makeInitiatorContext(contextID: String, authKitAdapter: OTAuthKitAdapter) -> OTCuttlefishContext { + // Note that the type of your initiator changes based on the platform you're currently on + return self.manager.context(forContainerName: OTCKContainerName, + contextID: contextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: authKitAdapter, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: self.makeInitiatorDeviceInfoAdapter()) + } + + func assertResetAndBecomeTrustedInDefaultContext() -> String { + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + return try! self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + } + + func assertJoinViaEscrowRecovery(joiningContext: OTCuttlefishContext, sponsor: OTCuttlefishContext) -> String { + do { + joiningContext.startOctagonStateMachine() + + let sponsorPeerID = try sponsor.accountMetadataStore.loadOrCreateAccountMetadata().peerID + XCTAssertNotNil(sponsorPeerID, "sponsorPeerID should not be nil") + let entropy = try self.loadSecret(label: sponsorPeerID!) + XCTAssertNotNil(entropy, "entropy should not be nil") + + let altDSID = joiningContext.authKitAdapter.primaryiCloudAccountAltDSID() + XCTAssertNotNil(altDSID, "Should have an altDSID") + + let bottles = self.fakeCuttlefishServer.state.bottles.filter { $0.peerID == sponsorPeerID } + XCTAssertEqual(bottles.count, 1, "Should have a single bottle for the approving peer") + let bottle = bottles[0] + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + joiningContext.join(withBottle: bottle.bottleID, entropy: entropy!, bottleSalt: altDSID!) { error in + XCTAssertNil(error, "error should be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 10) + + self.assertEnters(context: joiningContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: joiningContext) + + return try joiningContext.accountMetadataStore.getEgoPeerID() + } catch { + XCTFail("Expected no error: \(error)") + return "failed" + } + } +} + +class OctagonTests: OctagonTestsBase { + func testTPHPrepare() { + let contextName = "asdf" + let containerName = "test_container" + + let tphPrepareExpectation = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: contextName, + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + + tphPrepareExpectation.fulfill() + } + + self.wait(for: [tphPrepareExpectation], timeout: 10) + } + + func testTPHMultiPrepare() throws { + let contextName = OTDefaultContext + let containerName = OTCKContainerName + + var firstPeerID: String? + + let tphPrepareExpectation = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: contextName, + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + firstPeerID = peerID + + tphPrepareExpectation.fulfill() + } + + self.wait(for: [tphPrepareExpectation], timeout: 10) + + let tphPrepareExpectation2 = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: "a_different_context", + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + + XCTAssertNotEqual(peerID, firstPeerID, "Should not be the same peer ID as before") + + tphPrepareExpectation2.fulfill() + } + + self.wait(for: [tphPrepareExpectation2], timeout: 10) + } + + func testAccountSave() throws { + let contextName = OTDefaultContext + let containerName = OTCKContainerName + + self.startCKAccountStatusMock() + + // Before resetAndEstablish, there shouldn't be any stored account state + XCTAssertThrowsError(try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName), "Before doing anything, loading a non-existent account state should fail") + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + self.manager.resetAndEstablish(containerName, + context: contextName, + altDSID: "new altDSID") { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + let selfPeerID = try self.cuttlefishContext.accountMetadataStore.loadOrCreateAccountMetadata().peerID + + // After resetAndEstablish, you should be able to see the persisted account state + do { + let accountState = try OTAccountMetadataClassC.loadFromKeychain(forContainer: containerName, contextID: contextName) + XCTAssertEqual(selfPeerID, accountState.peerID, "Saved account state should have the same peer ID that prepare returned") + } catch { + XCTFail("error loading account state: \(error)") + } + } + + func testLoadToNoAccount() throws { + // No CloudKit account, either + self.accountStatus = .noAccount; + self.startCKAccountStatusMock() + + // With no identity and AuthKit reporting no iCloud account, Octagon should go directly into 'no account' + self.mockAuthKit.altDSID = nil + + let asyncExpectation = self.expectation(description: "dispatch works") + let quiescentExpectation = self.expectation(description: "quiescence has been determined") + DispatchQueue.global(qos: .userInitiated).async { [weak self] in + asyncExpectation.fulfill() + + let c = self!.cuttlefishContext.stateMachine.paused + XCTAssertEqual(0, c.wait(10 * NSEC_PER_SEC), "State machine should become quiescent") + quiescentExpectation.fulfill() + } + // Wait for the block above to fire before continuing + self.wait(for: [asyncExpectation], timeout: 10) + + // Run initialization, like the real secd will do + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + XCTAssertTrue(self.cuttlefishContext.stateMachine.isPaused(), "State machine should be stopped") + self.assertNoAccount(context: self.cuttlefishContext) + + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "State machine should be quiescent") + + self.wait(for: [quiescentExpectation], timeout: 10) + + // CKKS should also be logged out, since Octagon believes there's no account + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + } + + func testLoadToUntrusted() throws { + self.startCKAccountStatusMock() + + // With no identity but AuthKit reporting an existing iCloud account, Octagon should go directly into 'untrusted' + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testLoadToUntrustedIfTPHHasPreparedIdentityOnly() throws { + self.startCKAccountStatusMock() + + // Prepare an identity, then pretend like securityd thought it was in the right account + let containerName = OTCKContainerName + let contextName = OTDefaultContext + + var selfPeerID: String? + let prepareExpectation = self.expectation(description: "prepare callback occurs") + tphClient.prepare(withContainer: containerName, + context: contextName, + epoch: 0, + machineID: "asdf", + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "asdf", + deviceName: "asdf", + serialNumber: "1234", + osVersion: "asdf", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(peerID, "Should be a peer ID") + XCTAssertNotNil(permanentInfo, "Should have a permenent info") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent info signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + selfPeerID = peerID + + prepareExpectation.fulfill() + } + self.wait(for: [prepareExpectation], timeout: 10) + + let account = OTAccountMetadataClassC()! + account.peerID = selfPeerID + account.icloudAccountState = .ACCOUNT_AVAILABLE + account.trustState = .TRUSTED + + XCTAssertNoThrow(try account.saveToKeychain(forContainer: containerName, contextID: contextName), "Should be no error saving fake account metadata") + + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // CKKS should be waiting for assistance + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testSignIn() throws { + self.startCKAccountStatusMock() + + // Device is signed out + self.mockAuthKit.altDSID = nil + self.mockAuthKit.hsa2 = false + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // Sign in occurs + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + self.mockAuthKit.hsa2 = true + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // Octagon should go into 'untrusted' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 100 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + // On sign-out, octagon should go back to 'no account' + self.mockAuthKit.altDSID = nil + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "sign-out shouldn't error") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testSignInWithDelayedHSA2Status() throws { + self.startCKAccountStatusMock() + + // Device is signed out + self.mockAuthKit.altDSID = nil + self.mockAuthKit.hsa2 = false + + // With no account, Octagon should go directly into 'NoAccount' + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // Sign in occurs, but HSA2 status isn't here yet + let newAltDSID = UUID().uuidString + self.mockAuthKit.altDSID = newAltDSID + XCTAssertNoThrow(try self.cuttlefishContext.accountAvailable(newAltDSID), "Sign-in shouldn't error") + + // Octagon should go into 'waitforhsa2' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateWaitForHSA2, within: 10 * NSEC_PER_SEC) + + self.mockAuthKit.hsa2 = true + XCTAssertNoThrow(try self.cuttlefishContext.idmsTrustLevelChanged(), "Notification of IDMS trust level shouldn't error") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + // On sign-out, octagon should go back to 'no account' + self.mockAuthKit.altDSID = nil + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "sign-out shouldn't error") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testNewFriendsForEmptyAccount() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + // TODO: add a CKKS item + } + + func testCliqueStatusWhileLocked() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // Check that we handled locked devices too + self.aksLockState = true + self.lockStateTracker.recheck() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext, isLocked: true) + + // and then unlocked again + self.aksLockState = false + self.lockStateTracker.recheck() + self.assertConsidersSelfTrusted(context: self.cuttlefishContext, isLocked: false) + } + + + func testDeviceFetchRetry() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.transactionalFailure.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextFetchErrors.append(ckError) + + self.sendContainerChange(context: self.cuttlefishContext) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + self.sendContainerChange(context: self.cuttlefishContext) + } + + func testDeviceFetchRetryFail() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.transactionalFailure.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextFetchErrors.append(ckError) + self.fakeCuttlefishServer.nextFetchErrors.append(ckError) + self.cuttlefishContext.notifyContainerChange(nil) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + self.cuttlefishContext.notifyContainerChange(nil) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testNewFriendsForEmptyAccountReturnsMoreChanges() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + self.fakeCuttlefishServer.nextEstablishReturnsMoreChanges = true + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + } + + func testNewFriendsForEmptyAccountWithoutTLKsResetsZones() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + // But do NOT add them to the keychain + + // CKKS+Octagon should reset the zones and be ready + + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // CKKS should reset the zones after Octagon has entered + self.silentZoneDeletesAllowed = true + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready (eventually) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testUploadTLKsRetry() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + // But do NOT add them to the keychain + + // CKKS+Octagon should reset the zones and be ready + + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // CKKS should reset the zones after Octagon has entered + self.silentZoneDeletesAllowed = true + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.transactionalFailure.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + + // and all subCKKSes should enter ready (eventually) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testUploadTLKsRetryFail() throws { + // Note that Octagon now resets CKKS during a reset if there aren't keys + // So, this test needs to fail after Octagon is already in + + // CKKS+Octagon should reset the zones and be ready + + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 100 * NSEC_PER_SEC) + + // CKKS views reset themselves + // CKKS should reset the zones after Octagon has entered + self.silentZoneDeletesAllowed = true + + self.resetAllCKKSViews() + + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.transactionalFailure.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + self.fakeCuttlefishServer.nextUpdateTrustErrors.append(ckError) + + // these should be failures + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKUpload, within: 10 * NSEC_PER_SEC) + self.cuttlefishContext.rpcStatus() { _, _ in + return + } + + self.verifyDatabaseMocks() + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(60 * NSEC_PER_SEC), "Main cuttlefish context should quiesce before the test ends") + } + + func testNewFriendsForEmptyAccountWithTLKs() throws { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.saveTLKMaterial(toKeychain: self.manateeZoneID) + + self.startCKAccountStatusMock() + + // CKKS should go into 'logged out', as Octagon hasn't told it to go yet + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + + // CKKS should reset the zones after Octagon has entered + self.silentZoneDeletesAllowed = true + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready upload... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testLoadToReadyOnRestart() throws { + + let startDate = Date() + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + var readyDate = CKKSAnalytics.logger().dateProperty(forKey: OctagonAnalyticsLastKeystateReady) + XCTAssertNotNil(readyDate, "Should have a ready date") + XCTAssert(readyDate! > startDate, "ready date should be after startdate") + + // Now restart the context + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let restartDate = Date() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + let restartedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(restartedPeerID, "Should have a peer ID after restarting") + + XCTAssertEqual(peerID, restartedPeerID, "Should have the same peer ID after restarting") + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + readyDate = CKKSAnalytics.logger().dateProperty(forKey: OctagonAnalyticsLastKeystateReady) + XCTAssertNotNil(readyDate, "Should have a ready date") + XCTAssert(readyDate! > restartDate, "ready date should be after re-startdate") + } + + func testLoadToUntrustedOnRestartIfKeysGone() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + // Delete the local keys! + let query: [CFString: Any] = [ + kSecClass: kSecClassKey, + kSecAttrAccessGroup: "com.apple.security.egoIdentities", + kSecUseDataProtectionKeychain: kCFBooleanTrue, + ] + + let status = SecItemDelete(query as CFDictionary) + XCTAssertEqual(errSecSuccess, status, "should be able to delete every key") + + // Now restart the context + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testLoadToUntrustedOnRestartIfTPHLosesAllData() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + // TPH goes mad! + let resetExpectation = self.expectation(description: "reset callback occurs") + self.tphClient.localReset(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { error in + XCTAssertNil(error, "Should be no error performing a local reset") + resetExpectation.fulfill() + } + self.wait(for: [resetExpectation], timeout: 10) + + // Now restart the context + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + } + + func testLoadToTrustedOnRestartIfMismatchedPeerIDs() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let peerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotNil(peerID, "Should have a peer ID after making new friends") + + try self.cuttlefishContext.accountMetadataStore.persistNewEgoPeerID("mismatched-peer-id") + let mismatchedPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertNotEqual(peerID, mismatchedPeerID, "Peer ID should be ruined") + + // Now restart the context. It should accept TPH's view of the world... + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let newPeerID = try self.cuttlefishContext.accountMetadataStore.getEgoPeerID() + XCTAssertEqual(peerID, newPeerID, "Should now have TPH's peer ID") + } + + func testStatusRPCsWithUnknownCloudKitAccount() throws { + // If CloudKit isn't returning our calls, we should still return something reasonable... + let statusexpectation = self.expectation(description: "trust status returns") + let configuration = OTOperationConfiguration() + configuration.timeoutWaitForCKAccount = 500*NSEC_PER_MSEC + self.cuttlefishContext.rpcTrustStatus(configuration) { egoStatus, _, _, _, _ in + XCTAssertTrue([.absent].contains(egoStatus), "Self peer should be in the 'absent' state") + statusexpectation.fulfill() + } + self.wait(for: [statusexpectation], timeout: 10) + + // Now sign in to 'untrusted' + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + // And restart, without any idea of the cloudkit state + self.ckaccountHoldOperation = BlockOperation() + self.injectedManager!.accountTracker = CKKSAccountStateTracker(self.injectedManager!.container, + nsnotificationCenterClass: FakeNSNotificationCenter.self as CKKSNSNotificationCenter.Type) + self.manager.accountStateTracker = self.injectedManager!.accountTracker + + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + // Should know it's untrusted + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + self.startCKAccountStatusMock() + + // Now become ready + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // Restart one more time: + + self.ckaccountHoldOperation = BlockOperation() + self.injectedManager!.accountTracker = CKKSAccountStateTracker(self.injectedManager!.container, + nsnotificationCenterClass: FakeNSNotificationCenter.self as CKKSNSNotificationCenter.Type) + self.manager.accountStateTracker = self.injectedManager!.accountTracker + + self.manager.removeContext(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + self.restartCKKSViews() + self.cuttlefishContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + } + + func testRestoreToNewClique() throws { + self.startCKAccountStatusMock() + + do { + _ = try OTClique.performEscrowRecovery(withContextData: self.otcliqueContext, escrowArguments: [:]) + XCTFail("performEscrowRecovery is not currently testable, as we haven't mocked out SBD.") + } catch { + XCTAssert(true, "Should have errored restoring backup with no arguments: \(error)") + } + } + + func testFetchPeerID() throws { + self.startCKAccountStatusMock() + + let clique: OTClique? + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + + let memberIdentifier = clique!.cliqueMemberIdentifier + + let dumpExpectation = self.expectation(description: "dump callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let peerID = egoSelf!["peerID"] as? String + XCTAssertNotNil(peerID, "peerID should not be nil") + XCTAssertEqual(memberIdentifier, peerID, "memberIdentifier should match tph's peer ID") + + dumpExpectation.fulfill() + } + self.wait(for: [dumpExpectation], timeout: 10) + } + + func testLeaveClique() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // Technically, it's a server-side cuttlefish error for the last signed-in peer to leave. But, for now, just go for it. + XCTAssertNoThrow(try clique.leave(), "Should be no error departing clique") + + // securityd should now consider itself untrusted + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTrust, within: 10 * NSEC_PER_SEC) + + // TODO: an item added here shouldn't sync + } + + func testSignOut() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + // And 'dump' should show some information + let dumpExpectation = self.expectation(description: "dump callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let peerID = egoSelf!["peerID"] as? String + XCTAssertNotNil(peerID, "peerID should not be nil") + + dumpExpectation.fulfill() + } + self.wait(for: [dumpExpectation], timeout: 10) + + // Turn off the CK account too + self.accountStatus = .noAccount + self.accountStateTracker.notifyCKAccountStatusChangeAndWaitForSignal() + + XCTAssertNoThrow(try self.cuttlefishContext.accountNoLongerAvailable(), "Should be no issue signing out") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + + // And 'dump' should show nothing + let signedOutDumpExpectation = self.expectation(description: "dump callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + XCTAssertEqual(egoSelf!.count, 0, "egoSelf should have zero elements") + + signedOutDumpExpectation.fulfill() + } + self.wait(for: [signedOutDumpExpectation], timeout: 10) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateLoggedOut, within: 10 * NSEC_PER_SEC) + + //check trust status + let checkTrustExpectation = self.expectation(description: "checkTrustExpectation callback occurs") + let configuration = OTOperationConfiguration() + self.cuttlefishContext.rpcTrustStatus(configuration) { _, _, _, _, _ in + checkTrustExpectation.fulfill() + } + self.wait(for: [checkTrustExpectation], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + // And 'dump' should show nothing + let signedOutDumpExpectationAfterCheckTrustStatus = self.expectation(description: "dump callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, error in + XCTAssertNil(error, "Should be no error dumping data") + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + XCTAssertEqual(egoSelf!.count, 0, "egoSelf should have zero elements") + + signedOutDumpExpectationAfterCheckTrustStatus.fulfill() + } + self.wait(for: [signedOutDumpExpectationAfterCheckTrustStatus], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + self.assertNoAccount(context: self.cuttlefishContext) + } + + func testCliqueFriendAPI() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let peer1ID = fetchEgoPeerID() + + do { + let peersByID = try clique.peerDeviceNamesByPeerID() + XCTAssertNotNil(peersByID, "Should have received information on peers") + XCTAssertTrue(peersByID.isEmpty, "peer1 should report no trusted peers") + } catch { + XCTFail("Error thrown: \(error)") + } + + // Now, fake up a voucher for the second peer using TPH + let peer2ContextID = "asdf" + let peer2 = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + self.setAllowListToCurrentAuthKit(container: OTCKContainerName, context: peer2ContextID) + + var peer2ID: String! + let peer2DeviceName = "peer2-asdf" + let joinExpectation = self.expectation(description: "join callback occurs") + self.tphClient.prepare(withContainer: OTCKContainerName, + context: peer2ContextID, + epoch: 1, + machineID: self.mockAuthKit2.currentMachineID, + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: "AppleTV5,3", + deviceName: peer2DeviceName, + serialNumber: "1234", + osVersion: "something", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(permanentInfo, "Should have a permanent identity") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent identity signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + self.tphClient.vouch(withContainer: self.cuttlefishContext.containerName, + context: self.cuttlefishContext.contextID, + peerID: peerID!, + permanentInfo: permanentInfo!, + permanentInfoSig: permanentInfoSig!, + stableInfo: stableInfo!, + stableInfoSig: stableInfoSig!, + ckksKeys: []) { voucher, voucherSig, error in + XCTAssertNil(error, "Should be no error vouching") + XCTAssertNotNil(voucher, "Should have a voucher") + XCTAssertNotNil(voucherSig, "Should have a voucher signature") + self.tphClient.join(withContainer: OTCKContainerName, + context: peer2ContextID, + voucherData: voucher!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: [], + preapprovedKeys: []) { peerID, _, error in + XCTAssertNil(error, "Should be no error joining") + XCTAssertNotNil(peerID, "Should have a peerID") + peer2ID = peerID + joinExpectation.fulfill() + } + } + } + self.wait(for: [joinExpectation], timeout: 10) + + // Lie about the current account state + let account = OTAccountMetadataClassC()! + account.peerID = peer2ID + account.icloudAccountState = .ACCOUNT_AVAILABLE + account.trustState = .TRUSTED + XCTAssertNoThrow(try account.saveToKeychain(forContainer: OTCKContainerName, contextID: peer2ContextID), "Should be no error saving fake account metadata") + + peer2.startOctagonStateMachine() + self.assertEnters(context: peer2, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: peer2) + + // Now that we've lied enough... + self.sendContainerChangeWaitForFetch(context: self.cuttlefishContext) + + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should trust peer 2") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer2ID, opinion: .trusts, target: peer1ID)), + "peer 2 should trust peer 1") + + // But does peer1 claim to know peer2? + do { + let peersByID = try clique.peerDeviceNamesByPeerID() + XCTAssertNotNil(peersByID, "Should have received information on peers") + + guard let peerName = peersByID[peer2ID] else { + throw NSError(domain: "missing information" as String, code: 0, userInfo: nil) + } + + XCTAssertEqual(peerName, peer2DeviceName, "peer2 device name (as reported by peer1) should be correct") + } catch { + XCTFail("Error thrown: \(error)") + } + + XCTAssertNoThrow(try clique.removeFriends(inClique: [peer2ID]), "Shouldn't error removing peer2 from trust") + XCTAssertFalse(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .trusts, target: peer2ID)), + "peer 1 should not trust peer 2") + XCTAssertTrue(self.fakeCuttlefishServer.assertCuttlefishState(FakeCuttlefishAssertion(peer: peer1ID, opinion: .excludes, target: peer2ID)), + "peer 1 should exclude trust peer 2") + + do { + let peersByID = try clique.peerDeviceNamesByPeerID() + XCTAssertNotNil(peersByID, "Should have received information on peers") + XCTAssertTrue(peersByID.isEmpty, "peer1 should report no trusted peers") + } catch { + XCTFail("Error thrown: \(error)") + } + } + + func testNoAccountLeadsToInitialize() throws { + self.startCKAccountStatusMock() + + // With no identity and AuthKit reporting no iCloud account, Octagon should go directly into 'no account' + self.mockAuthKit.altDSID = nil + + // Run initialization, like the real secd will do + OctagonInitialize() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + + self.mockAuthKit.altDSID = "1234" + let signinExpectation = self.expectation(description: "sign in returns") + self.otControl.sign(in: "1234", container: nil, context:OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signinExpectation.fulfill() + } + self.wait(for: [signinExpectation], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + } + + func testOTCliqueOctagonAuthoritativeTrustResponse() throws { + self.startCKAccountStatusMock() + OctagonAuthoritativeTrustSetIsEnabled(true) + + do { + let absentClique = try OTClique(contextData: self.otcliqueContext) + let absentStatus = absentClique.cachedCliqueStatus(true, error: nil) + XCTAssertEqual(absentStatus, CliqueStatus.absent, "clique should return Absent") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + + let status = clique.cachedCliqueStatus(true, error: nil) + XCTAssertEqual(status, CliqueStatus.in, "clique should return In") + + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + // Technically, it's a server-side cuttlefish error for the last signed-in peer to leave. But, for now, just go for it. + XCTAssertNoThrow(try clique.leave(), "Should be no error departing clique") + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + let status = clique.cachedCliqueStatus(true, error: nil) + XCTAssertEqual(status, CliqueStatus.notIn, "clique should return Not In") + + let newOTCliqueContext = OTConfigurationContext() + newOTCliqueContext.context = "newCliqueContext" + newOTCliqueContext.dsid = self.otcliqueContext.dsid + newOTCliqueContext.altDSID = self.otcliqueContext.altDSID + newOTCliqueContext.otControl = self.otcliqueContext.otControl + let newClique: OTClique + + do { + newClique = try OTClique.newFriends(withContextData: newOTCliqueContext) + XCTAssertNotNil(newClique, "newClique should not be nil") + + OctagonSetPlatformSupportsSOS(true) + let status = newClique.cachedCliqueStatus(true, error: nil) + XCTAssertEqual(status, CliqueStatus.in, "clique should return In") + + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + let newContext = self.manager.context(forContainerName: OTCKContainerName, contextID: newOTCliqueContext.context!) + self.assertEnters(context: newContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } + + func testCLIStatus() { + self.startCKAccountStatusMock() + + // Run status without anything in the account + self.otControlCLI.status(OTCKContainerName, + context: OTDefaultContext, + json: false) + + do { + _ = try OTClique.newFriends(withContextData: self.otcliqueContext) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + } catch { + XCTFail("failed to make new friends: \(error)") + } + + // run status again with only a self peer + self.otControlCLI.status(OTCKContainerName, + context: OTDefaultContext, + json: false) + } + + func testNoAccountTimeoutTransitionWatcher() throws { + self.startCKAccountStatusMock() + + // With no identity and AuthKit reporting no iCloud account, Octagon should go directly into 'no account' + self.mockAuthKit.altDSID = nil + + // Run initialization, like the real secd will do + OctagonInitialize() + self.cuttlefishContext.stateMachine.setWatcherTimeout(2*NSEC_PER_SEC); + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateNoAccount, within: 10 * NSEC_PER_SEC) + XCTAssertTrue(self.cuttlefishContext.stateMachine.isPaused(), "State machine should be stopped") + self.assertNoAccount(context: self.cuttlefishContext) + XCTAssertEqual(0, self.cuttlefishContext.stateMachine.paused.wait(10 * NSEC_PER_SEC), "State machine should be quiescent") + + let joinWithBottleExpectation = self.expectation(description: "joinWithBottle callback occurs") + self.cuttlefishContext.join(withBottle: "bottleID", entropy: Data(), bottleSalt: "peer2AltDSID") { error in + XCTAssertNotNil(error, "error should not be nil") + joinWithBottleExpectation.fulfill() + } + self.wait(for: [joinWithBottleExpectation], timeout: 3) + } + + func testFailingStateTransitionWatcher() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Set up a watcher that we expect to fail... + let path = OctagonStateTransitionPath(from: [ + OctagonStateResetAndEstablish: [ + OctagonStateInitiatorVouchWithBottle: [ + OctagonStateResetAndEstablish: OctagonStateTransitionPathStep.success(), + ], + ], + ]) + let watcher = OctagonStateTransitionWatcher(named: "should-fail", + serialQueue: self.cuttlefishContext.queue, + path: path!) + self.cuttlefishContext.stateMachine.register(watcher) + + let watcherCompleteOperationExpectation = self.expectation(description: "watcherCompleteOperationExpectation returns") + let watcherFinishOp = CKKSResultOperation.named("should-fail-cleanup", with: { + XCTAssertNotNil(watcher.result.error, "watcher should have errored") + watcherCompleteOperationExpectation.fulfill() + }) + + watcherFinishOp.addDependency(watcher.result) + self.operationQueue.addOperation(watcherFinishOp) + + // and now cause the watcher to fail... + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablishExpectation returns") + self.cuttlefishContext.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "should be no error resetting and establishing") + resetAndEstablishExpectation.fulfill() + } + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + + // and the watcher should finish, too + self.wait(for: [watcherCompleteOperationExpectation], timeout: 10) + + self.verifyDatabaseMocks() + } + + func testLeaveCliqueAndPostCFU() throws { + self.startCKAccountStatusMock() + + OctagonAuthoritativeTrustSetIsEnabled(true) + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + // Technically, it's a server-side cuttlefish error for the last signed-in peer to leave. But, for now, just go for it. + XCTAssertNoThrow(try clique.leave(), "Should be no error departing clique") + + // securityd should now consider itself untrusted + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + let cfuExpectation = self.expectation(description: "cfu callback occurs") + self.cuttlefishContext.setPostedBool(false) + self.cuttlefishContext.checkTrustStatusAndPostRepairCFUIfNecessary() { status, posted, egoPeerID, error in + #if !os(tvOS) + XCTAssertTrue(posted, "posted should be true") + #else + XCTAssertFalse(posted, "posted should be false on tvOS; there aren't any iphones around to repair it") + #endif + XCTAssertNil(error, "error should be nil") + cfuExpectation.fulfill() + } + self.wait(for: [cfuExpectation], timeout: 10) + } + + func testDeviceLockedDuringAccountRetrieval() throws { + self.startCKAccountStatusMock() + + self.aksLockState = true + self.lockStateTracker.recheck() + + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: OTDefaultContext, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + let accountMetadataStoreActual = initiatorContext.accountMetadataStore //grab the previously instantiated account state holder + + initiatorContext.setAccountStateHolder(self.accountMetaDataStore) // set the mocked account state holder + + initiatorContext.startOctagonStateMachine() + self.assertEnters(context: initiatorContext, state: OctagonStateWaitForUnlock, within: 10 * NSEC_PER_SEC) + + initiatorContext.setAccountStateHolder(accountMetadataStoreActual) //re-set the actual store + self.aksLockState = false + self.lockStateTracker.recheck() + + self.assertEnters(context: initiatorContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testCuttlefishUpdateRemovesEgoPeer() throws { + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + // Now, Cuttlefish decides we no longer exist? + + self.fakeCuttlefishServer.deleteAllPeers() + self.sendContainerChange(context: self.cuttlefishContext) + + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + } + + func testFetchViewList() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + #if !os(tvOS) + let expectedViews = Set(["ProtectedCloudStorage", + "AutoUnlock", + "LimitedPeersAllowed", + "SecureObjectSync", + "DevicePairing", + "Engram", + "Home", + "Applications", + "WiFi", + "Health", + "Manatee", + "CreditCards", + "Passwords", + "ApplePay", ]) + #else + let expectedViews = Set(["LimitedPeersAllowed", + "WiFi", ]) + #endif + + let getViewsExpectation = self.expectation(description: "getViews callback happens") + self.tphClient.getViewsWithContainer(OTCKContainerName, context: OTDefaultContext, inViews: []) { outViews, error in + XCTAssertNil(error, "should not have failed") + XCTAssertEqual(expectedViews, Set(outViews!)) + getViewsExpectation.fulfill() + } + self.wait(for: [getViewsExpectation], timeout: 10) + } + + func testMergedViewListOff() throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.viewManager!.setOverrideCKKSViewsFromPolicy(false) + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let viewList = self.cuttlefishContext.viewManager!.viewList() + #if !os(tvOS) + let expected = Set(["Manatee"]) + #else + let expected = Set(["LimitedPeersAllowed"]) + #endif + XCTAssertEqual(expected, viewList) + } + + func testMergedViewListOn() throws { + /* + self.startCKAccountStatusMock() + self.cuttlefishContext.viewManager!.setOverrideCKKSViewsFromPolicy(true) + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + let viewList = self.cuttlefishContext.viewManager!.viewList() + let expected = Set([ + "ApplePay", + "Applications", + "AutoUnlock", + "Backstop", + "DevicePairing", + "Engram", + "Health", + "Home", + "LimitedPeersAllowed", + "Manatee", + "ProtectedCloudStorage", + "SafariCreditCards", + "SafariPasswords", + "SecureObjectSync", + "WiFi", + "keychain", + ]) + XCTAssertEqual(expected, viewList) + */ + } + + let octagonNotificationName = "com.apple.security.octagon.trust-status-change" + + func testNotifications() throws { + + let contextName = OTDefaultContext + let containerName = OTCKContainerName + + let untrustedNotification = XCTDarwinNotificationExpectation(notificationName: octagonNotificationName) + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.wait(for: [untrustedNotification], timeout: 2) + + let trustedNotification = XCTDarwinNotificationExpectation(notificationName: octagonNotificationName) + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + let escrowRequestNotification = expectation(forNotification: OTMockEscrowRequestNotification, + object: nil, + handler: nil) + self.manager.resetAndEstablish(containerName, + context: contextName, + altDSID: "new altDSID") { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.wait(for: [escrowRequestNotification], timeout: 5) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.wait(for: [trustedNotification], timeout: 2) + } + + func testAPSRateLimiter() throws { + + let untrustedNotification = XCTDarwinNotificationExpectation(notificationName: octagonNotificationName) + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.wait(for: [untrustedNotification], timeout: 2) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + XCTAssertEqual(self.fakeCuttlefishServer.fetchChangesCalledCount, 1, "fetchChanges should have been called 1 times") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testAPSExpectOneFetchChanges() { + let untrustedNotification = XCTDarwinNotificationExpectation(notificationName: octagonNotificationName) + + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.wait(for: [untrustedNotification], timeout: 2) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + self.cuttlefishContext.notifyContainerChange(nil) + + XCTAssertEqual(self.fakeCuttlefishServer.fetchChangesCalledCount, 1, "fetchChanges should have been called 1 times") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func testEnsureNonDefaultTimeOut() { + self.startCKAccountStatusMock() + OctagonSetPlatformSupportsSOS(true) + + let initiatorPiggybackingConfig = OTJoiningConfiguration(protocolType: OTProtocolPiggybacking, uniqueDeviceID: "initiator", uniqueClientID: "acceptor", containerName: OTCKContainerName, contextID: OTDefaultContext, epoch: 1, isInitiator: true) + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + self.manager.resetAndEstablish(OTCKContainerName, + context: OTDefaultContext, + altDSID: "new altDSID") { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + /*begin message passing*/ + let rpcFirstInitiatorJoiningMessageCallBack = self.expectation(description: "Creating prepare message callback") + self.manager.rpcPrepareIdentityAsApplicant(with: initiatorPiggybackingConfig) { pID, pI, pIS, sI, sIS, error in + XCTAssertNil(pID, "peerID should not be nil") + XCTAssertNil(pI, "permanentInfo should not be nil") + XCTAssertNil(pIS, "permanentInfoSig should not be nil") + XCTAssertNil(sI, "stableInfo should not be nil") + XCTAssertNil(sIS, "stableInfoSig should not be nil") + + XCTAssertNotNil(error, "error should not be nil") + rpcFirstInitiatorJoiningMessageCallBack.fulfill() + } + //default value for ops is 10 seconds, ensuring the rpc times out in 2 seconds which is the new value set on the request + self.wait(for: [rpcFirstInitiatorJoiningMessageCallBack], timeout: 3) + + //this call uses the default value and should timeout in 10 seconds + let upgradeCallback = self.expectation(description: "attempting sos upgrade callback") + self.manager.attemptSosUpgrade(OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNotNil(error, "error should not be nil") + upgradeCallback.fulfill() + } + self.wait(for: [upgradeCallback], timeout: 11) + } + + func testTTRTrusted() { + + self.startCKAccountStatusMock() + + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + do { + let clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + } + + // Now, we should be in 'ready' + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrustedCachedAccountStatus(context: self.cuttlefishContext) + + // and all subCKKSes should enter ready... + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + + self.isTTRRatelimited = false + self.ttrExpectation = self.expectation(description: "trigger TTR") + + self.sendTTRRequest(context: self.cuttlefishContext) + + self.wait(for: [self.ttrExpectation!], timeout: 10) + } +} + +class OctagonTestsOverrideModelBase: OctagonTestsBase { + struct TestCase { + let model: String + let success: Bool + let sendTLKs: Bool + } + + func _testVouchers(expectations: [TestCase]) throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + _ = fetchEgoPeerID() + + for testCase in expectations { + let model = testCase.model + let expectedSuccess = testCase.success + // Now, fake up a voucher for the second peer using TPH + let peer2ContextID = "asdf" + _ = self.manager.context(forContainerName: OTCKContainerName, + contextID: peer2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + self.setAllowListToCurrentAuthKit(container: OTCKContainerName, context: peer2ContextID) + + let peer2DeviceName = "peer2-asdf" + let joinExpectation = self.expectation(description: "join callback occurs") + self.tphClient.prepare(withContainer: OTCKContainerName, + context: peer2ContextID, + epoch: 1, + machineID: self.mockAuthKit.currentMachineID, + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: model, + deviceName: peer2DeviceName, + serialNumber: "1234", + osVersion: "something", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(permanentInfo, "Should have a permanent identity") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent identity signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + if expectedSuccess { + self.tphClient.vouch(withContainer: self.cuttlefishContext.containerName, + context: self.cuttlefishContext.contextID, + peerID: peerID!, + permanentInfo: permanentInfo!, + permanentInfoSig: permanentInfoSig!, + stableInfo: stableInfo!, + stableInfoSig: stableInfoSig!, + ckksKeys: []) { voucher, voucherSig, error in + XCTAssertNil(error, "Should be no error vouching") + XCTAssertNotNil(voucher, "Should have a voucher") + XCTAssertNotNil(voucherSig, "Should have a voucher signature") + self.tphClient.join(withContainer: OTCKContainerName, + context: peer2ContextID, + voucherData: voucher!, + voucherSig: voucherSig!, + ckksKeys: [], + tlkShares: [], + preapprovedKeys: []) { peerID, _, error in + XCTAssertNil(error, "Should be no error joining") + XCTAssertNotNil(peerID, "Should have a peerID") + joinExpectation.fulfill() + } + } + } else { + self.tphClient.vouch(withContainer: self.cuttlefishContext.containerName, + context: self.cuttlefishContext.contextID, + peerID: peerID!, + permanentInfo: permanentInfo!, + permanentInfoSig: permanentInfoSig!, + stableInfo: stableInfo!, + stableInfoSig: stableInfoSig!, + ckksKeys: []) { voucher, voucherSig, error in + XCTAssertNil(voucher, "voucher should be nil") + XCTAssertNil(voucherSig, "voucherSig should be nil") + XCTAssertNotNil(error, "error should be non nil") + joinExpectation.fulfill() + } + } + } + self.wait(for: [joinExpectation], timeout: 10) + } + } + + func _testJoin(expectations: [TestCase]) throws { + self.startCKAccountStatusMock() + self.cuttlefishContext.startOctagonStateMachine() + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let clique: OTClique + do { + clique = try OTClique.newFriends(withContextData: self.otcliqueContext) + XCTAssertNotNil(clique, "Clique should not be nil") + } catch { + XCTFail("Shouldn't have errored making new friends: \(error)") + throw error + } + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let peer1ID = fetchEgoPeerID() + let peer1Keys: OctagonSelfPeerKeys = try loadEgoKeysSync(peerID: peer1ID) + + for testCase in expectations { + let model = testCase.model + let expectedSuccess = testCase.success + + let peer2ContextID = "asdf" + let peer2DeviceName = "peer2-device-name" + var peer2ID: String! + + self.setAllowListToCurrentAuthKit(container: OTCKContainerName, context: peer2ContextID) + + let joinExpectation = self.expectation(description: "join callback occurs") + self.tphClient.prepare(withContainer: OTCKContainerName, + context: peer2ContextID, + epoch: 1, + machineID: self.mockAuthKit2.currentMachineID, + bottleSalt: "123456789", + bottleID: UUID().uuidString, + modelID: model, + deviceName: peer2DeviceName, + serialNumber: "1234", + osVersion: "something", + policyVersion: nil, + policySecrets: nil, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error preparing identity") + XCTAssertNotNil(permanentInfo, "Should have a permanent identity") + XCTAssertNotNil(permanentInfoSig, "Should have a permanent identity signature") + XCTAssertNotNil(stableInfo, "Should have a stable info") + XCTAssertNotNil(stableInfoSig, "Should have a stable info signature") + peer2ID = peerID + + var voucher: TPVoucher? + do { + try voucher = TPVoucher(reason: TPVoucherReason.secureChannel, + beneficiaryID: peer2ID, + sponsorID: peer1ID, + signing: peer1Keys.signingKey) + } catch { + XCTFail("should not throw: \(error)") + } + self.tphClient.join(withContainer: OTCKContainerName, + context: peer2ContextID, + voucherData: voucher!.data, + voucherSig: voucher!.sig, + ckksKeys: [], + tlkShares: [], + preapprovedKeys: []) { peerID, _, error in + if expectedSuccess { + XCTAssertNil(error, "expected success") + XCTAssertNotNil(peerID, "peerID should be set") + } else { + XCTAssertNotNil(error, "error should not be nil") + XCTAssertNil(peerID, "peerID should not be set") + } + joinExpectation.fulfill() + } + + } + self.wait(for: [joinExpectation], timeout: 10) + + if expectedSuccess { + let updateTrustExpectation = self.expectation(description: "updateTrust") + self.fakeCuttlefishServer.updateListener = { request in + XCTAssertEqual(peer1ID, request.peerID, "updateTrust request should be for peer 1") + XCTAssertTrue(request.hasDynamicInfoAndSig, "updateTrust request should have a dynamic info") + let newDynamicInfo = TPPeerDynamicInfo(data: request.dynamicInfoAndSig.peerDynamicInfo, sig: request.dynamicInfoAndSig.sig) + XCTAssertNotNil(newDynamicInfo, "should be able to make a dynamic info from protobuf") + + XCTAssert(newDynamicInfo!.includedPeerIDs.contains(peer2ID), "Peer1 should trust peer2") + + updateTrustExpectation.fulfill() + return nil + } + + // Maybe send TLKs? + if testCase.sendTLKs { + self.assertAllCKKSViewsUpload(tlkShares: 1) + } + + self.cuttlefishContext.notifyContainerChange(nil) + + self.wait(for: [updateTrustExpectation], timeout: 100) + self.fakeCuttlefishServer.updateListener = nil + + self.sendAllCKKSTrustedPeersChanged() + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10*NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + } + } +} + +class OctagonTestsOverrideModelTV: OctagonTestsOverrideModelBase { + // If this test is running on a TV, we will send TLKs, since we're using the LimitedPeersAllowed view + #if !os(tvOS) + let sendTLKsToAllPeers = false + #else + let sendTLKsToAllPeers = true + #endif + + override func deviceInformationAdapter() -> OTDeviceInformationAdapter { + return OTMockDeviceInfoAdapter(modelID: "AppleTV5,3", deviceName: "intro-TV", serialNumber: "456", osVersion: "iOS (whatever TV version)") + } + + func testVoucherFromTV() throws { + try self._testVouchers(expectations: [TestCase(model: "AppleTV5,3", success: true, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "MacFoo", success: false, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "Watch17", success: false, sendTLKs: sendTLKsToAllPeers)]) + } + + func testJoinFromTV() throws { + try self._testJoin(expectations: [TestCase(model: "AppleTV5,3", success: true, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "MacFoo", success: false, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "Watch17", success: false, sendTLKs: sendTLKsToAllPeers)]) + } +} + +class OctagonTestsOverrideModelMac: OctagonTestsOverrideModelBase { + #if !os(tvOS) + let sendTLKsToAllPeers = false + #else + let sendTLKsToAllPeers = true + #endif + + override func deviceInformationAdapter() -> OTDeviceInformationAdapter { + return OTMockDeviceInfoAdapter(modelID: "Mac17", deviceName: "macbook", serialNumber: "456", osVersion: "OSX 11") + } + + func testVoucherFromMac() throws { + try self._testVouchers(expectations: [TestCase(model: "AppleTV5,3", success: true, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "MacFoo", success: true, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "Watch17", success: true, sendTLKs: sendTLKsToAllPeers)]) + } + + func testJoinFromMac() throws { + try self._testJoin(expectations: [TestCase(model: "AppleTV5,3", success: true, sendTLKs: sendTLKsToAllPeers), + TestCase(model: "MacFoo", success: true, sendTLKs: true), + TestCase(model: "Watch17", success: true, sendTLKs: true)]) + } +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/OctagonTestsXPCConnections.swift b/keychain/ot/tests/octagon/OctagonTestsXPCConnections.swift new file mode 100644 index 00000000..364e8117 --- /dev/null +++ b/keychain/ot/tests/octagon/OctagonTestsXPCConnections.swift @@ -0,0 +1,64 @@ +#if OCTAGON + +import Foundation + +class ProxyXPCConnection: NSObject, NSXPCListenerDelegate { + let obj: Any + let serverInterface: NSXPCInterface + let listener: NSXPCListener + + init(_ obj: Any, interface: NSXPCInterface) { + self.obj = obj + self.serverInterface = interface + self.listener = NSXPCListener.anonymous() + + super.init() + self.listener.delegate = self; + self.listener.resume() + } + + public func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { + newConnection.exportedInterface = self.serverInterface + newConnection.exportedObject = self.obj + newConnection.resume() + return true + } + + public func connection() -> NSXPCConnection { + let connection = NSXPCConnection(listenerEndpoint: self.listener.endpoint) + connection.remoteObjectInterface = self.serverInterface + connection.resume() + return connection + } +} + +class FakeNSXPCConnectionSOS: NSXPCConnection { + var sosControl: SOSControlProtocol + + init(withSOSControl: SOSControlProtocol) { + self.sosControl = withSOSControl + super.init() + } + + override func remoteObjectProxyWithErrorHandler(_ handler: @escaping (Error) -> Void) -> Any { + return self.sosControl + } + + override func synchronousRemoteObjectProxyWithErrorHandler(_ handler: @escaping (Error) -> Void) -> Any { + return FakeNSXPCConnection(control: self.sosControl) + } +} + +class FakeOTControlEntitlementBearer: OctagonEntitlementBearerProtocol { + var entitlements: [String: Any] + + init() { + // By default, this client has all octagon entitlements + self.entitlements = [kSecEntitlementPrivateOctagonEscrow: true] + } + func value(forEntitlement entitlement: String) -> Any? { + return self.entitlements[entitlement] + } +} + +#endif // OCTAGON diff --git a/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+Piggybacking.swift b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+Piggybacking.swift new file mode 100644 index 00000000..17901fea --- /dev/null +++ b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+Piggybacking.swift @@ -0,0 +1,830 @@ +#if OCTAGON + +let version1_txt: [UInt8] = [ + 0x30, 0x82, 0x01, 0x9c, 0x02, 0x01, 0x00, 0x04, 0x82, 0x01, 0x80, 0x36, + 0xda, 0xda, 0xbf, 0x19, 0xdc, 0xe8, 0xb9, 0x8b, 0x45, 0xcd, 0xeb, 0xf2, + 0x14, 0xb3, 0x47, 0xfa, 0x65, 0x4c, 0x81, 0xdb, 0x7a, 0xf7, 0x99, 0x06, + 0x8d, 0xc8, 0x82, 0x2b, 0xae, 0x9d, 0x1f, 0x8e, 0x4f, 0xe4, 0x05, 0x59, + 0xf0, 0x46, 0xd6, 0x80, 0xb2, 0x9f, 0x7a, 0x9e, 0x9b, 0x66, 0x1e, 0x16, + 0x7a, 0x81, 0x19, 0x44, 0xc1, 0xa7, 0xaf, 0xaf, 0x56, 0xa9, 0x8a, 0x86, + 0x89, 0x42, 0xd9, 0xac, 0xf5, 0x32, 0xf6, 0x14, 0xd9, 0xc4, 0x41, 0x2b, + 0x8f, 0x6f, 0x48, 0x7c, 0xe4, 0x3b, 0xea, 0x97, 0xa6, 0x86, 0x93, 0x0f, + 0xf2, 0x6c, 0x77, 0x10, 0x2c, 0xc7, 0xe8, 0x84, 0xb9, 0x21, 0xda, 0xf1, + 0xe4, 0x62, 0x0d, 0x10, 0x09, 0x4c, 0x83, 0xb0, 0x13, 0x66, 0xe8, 0xcf, + 0xbf, 0x60, 0x49, 0xe3, 0x68, 0xa9, 0x27, 0x50, 0x94, 0xfb, 0x4f, 0x05, + 0x31, 0x7d, 0x13, 0xa7, 0x6a, 0x68, 0x5c, 0x14, 0x25, 0x7e, 0xc4, 0xb3, + 0x10, 0xe3, 0x45, 0x0d, 0xa1, 0x8f, 0x10, 0x98, 0x69, 0x1c, 0x8c, 0x0d, + 0x21, 0x3f, 0x64, 0xd5, 0x31, 0x90, 0x41, 0x90, 0x61, 0xd4, 0x60, 0x94, + 0xc3, 0x62, 0xd7, 0xfa, 0x40, 0xc7, 0xc5, 0x41, 0x95, 0x4b, 0xa2, 0xe6, + 0xfe, 0xda, 0xf3, 0xb9, 0x24, 0x3e, 0x9e, 0xe0, 0xa0, 0xfc, 0x38, 0xdb, + 0x21, 0x35, 0xe1, 0x2e, 0x39, 0x2a, 0x5a, 0xf4, 0xa1, 0x24, 0x89, 0xfd, + 0x4e, 0x2d, 0x9c, 0x44, 0xde, 0xda, 0x9b, 0xb6, 0xa6, 0x00, 0xf3, 0x3f, + 0xd6, 0x61, 0x4f, 0xe0, 0xf5, 0x01, 0x69, 0xa5, 0xfa, 0x91, 0xed, 0xfb, + 0xa9, 0xc2, 0x9d, 0x28, 0x94, 0x95, 0x7f, 0xaa, 0x21, 0x53, 0xff, 0x2a, + 0xfb, 0xe5, 0xcf, 0x4a, 0x8a, 0xc5, 0xff, 0x8e, 0xf4, 0x69, 0xbe, 0x4d, + 0x3c, 0xfd, 0x84, 0x9d, 0xd2, 0xf7, 0x06, 0x86, 0x50, 0x23, 0x01, 0x19, + 0x85, 0x02, 0x08, 0xbb, 0x1c, 0x7b, 0x38, 0x72, 0x49, 0xa6, 0xf5, 0x5f, + 0x33, 0x44, 0xc7, 0x68, 0xa2, 0x43, 0x51, 0xae, 0x49, 0xe8, 0x31, 0x3a, + 0x8d, 0x54, 0x09, 0x12, 0x5f, 0x22, 0xd0, 0xe8, 0x53, 0x5a, 0xd8, 0x62, + 0x71, 0x65, 0x51, 0xdc, 0xdc, 0x0f, 0x25, 0x3a, 0x90, 0xf0, 0x46, 0x85, + 0x83, 0xbc, 0xb2, 0xf3, 0xdb, 0x5a, 0xc8, 0x37, 0x12, 0x99, 0x47, 0x47, + 0x6f, 0x9a, 0x15, 0xec, 0x27, 0xfb, 0xe4, 0x38, 0x2e, 0x00, 0x96, 0x92, + 0x97, 0x55, 0x02, 0x2c, 0xf9, 0x8d, 0x6e, 0x0f, 0x73, 0xac, 0x17, 0xb9, + 0x46, 0xbc, 0x56, 0x06, 0xc9, 0x1e, 0x95, 0xd5, 0xf6, 0x45, 0xc2, 0x16, + 0x36, 0xa8, 0x50, 0xc7, 0xf9, 0xec, 0xb5, 0xe8, 0x8d, 0xec, 0x4a, 0x1d, + 0xe0, 0x8c, 0x86, 0xf1, 0x6e, 0xf0, 0x79, 0x17, 0x33, 0x71, 0xab, 0xe7, + 0x48, 0xc6, 0x1a, 0xd1, 0x09, 0x2b, 0x9c, 0xd3, 0xd8, 0x19, 0xf6, 0x02, + 0x01, 0x01, 0x04, 0x10, 0xf1, 0x3f, 0xd5, 0x7d, 0x58, 0x74, 0x4e, 0xfe, + 0xaa, 0x93, 0x8e, 0x03, 0x89, 0xbb, 0x8f, 0xeb, +] +let version1_txt_len = 416 + +let version0_txt: [UInt8] = [ + 0x30, 0x82, 0x01, 0x87, 0x02, 0x01, 0x00, 0x04, 0x82, 0x01, 0x80, 0x81, + 0x13, 0x06, 0x96, 0x1f, 0x38, 0x75, 0x10, 0x4f, 0xcf, 0x0d, 0x50, 0x43, + 0x33, 0xd7, 0xe3, 0xc6, 0x6a, 0xc3, 0x21, 0xb6, 0x8d, 0x51, 0x76, 0x61, + 0xdd, 0xa0, 0xb9, 0xed, 0xbd, 0xc4, 0xd9, 0x63, 0x0d, 0xa8, 0xa5, 0x6b, + 0x7f, 0x6e, 0x77, 0xf2, 0xfb, 0x48, 0xaa, 0xd7, 0x8f, 0x5f, 0xb7, 0x97, + 0x7e, 0xee, 0xf8, 0xa0, 0xa1, 0xdc, 0x15, 0xfb, 0xb7, 0x36, 0x9c, 0x43, + 0xbf, 0xc5, 0x1a, 0x73, 0xae, 0xa4, 0xcd, 0xa6, 0xa8, 0xcc, 0x16, 0xcb, + 0x42, 0xfa, 0x3f, 0x22, 0x0c, 0xd4, 0xd8, 0xdc, 0x8d, 0xdb, 0xe2, 0x19, + 0xbc, 0x1d, 0x22, 0xb5, 0xe1, 0x3f, 0x4f, 0xca, 0x3a, 0xbd, 0xb6, 0xb3, + 0xfd, 0x5e, 0x61, 0x9e, 0x40, 0x67, 0xfc, 0x9e, 0x61, 0x44, 0x70, 0x97, + 0xb9, 0x86, 0x50, 0xa9, 0xe2, 0xd3, 0x6f, 0x46, 0x6a, 0x73, 0xc4, 0xf3, + 0xb3, 0xdb, 0x1a, 0x4e, 0xd1, 0x9d, 0xf2, 0x99, 0xb0, 0xe1, 0x81, 0x09, + 0xc4, 0x08, 0xf0, 0x48, 0xff, 0xa2, 0x7a, 0xd2, 0xd0, 0x73, 0xe5, 0x7c, + 0x2c, 0x16, 0xae, 0x59, 0x17, 0x4d, 0xa9, 0x8e, 0xab, 0x01, 0xe8, 0xab, + 0xf8, 0x3b, 0x7a, 0xad, 0x38, 0x12, 0x50, 0x73, 0xc7, 0x5e, 0xa5, 0x02, + 0x34, 0x97, 0x4a, 0x97, 0x5e, 0x0f, 0x78, 0x9d, 0xed, 0x1b, 0x69, 0xc9, + 0xd3, 0x2c, 0x07, 0xe0, 0x36, 0x40, 0x5d, 0x39, 0x14, 0x62, 0x29, 0xbd, + 0x11, 0x1b, 0xb9, 0x66, 0xd6, 0xcd, 0x17, 0xdd, 0x83, 0xc3, 0x95, 0xe1, + 0xac, 0x90, 0xab, 0x57, 0x10, 0x0b, 0xc5, 0x18, 0xe2, 0xdb, 0xeb, 0x22, + 0x81, 0x91, 0x1e, 0xa0, 0xa7, 0x91, 0xe2, 0xc9, 0xdc, 0x07, 0x07, 0xf6, + 0xd3, 0x04, 0x58, 0xd8, 0x68, 0xed, 0xeb, 0x9e, 0x0f, 0xf5, 0xa2, 0xdd, + 0x87, 0x94, 0x5e, 0x71, 0x1f, 0xeb, 0x6c, 0x9c, 0xad, 0x38, 0x58, 0x2f, + 0x48, 0x6c, 0xc1, 0x40, 0xde, 0x4f, 0x00, 0x08, 0x20, 0x9c, 0x84, 0x75, + 0xa5, 0x60, 0x55, 0x3e, 0x33, 0xc8, 0x74, 0x65, 0x4f, 0xe5, 0x2f, 0xd2, + 0x8a, 0xee, 0x21, 0x9f, 0xe5, 0x8d, 0xda, 0x5c, 0xc6, 0x2e, 0xcc, 0x7b, + 0x14, 0x2a, 0xfa, 0x7c, 0x37, 0x34, 0x1e, 0x07, 0x57, 0xd8, 0xf5, 0xc6, + 0x09, 0xa3, 0x28, 0xa0, 0x28, 0x13, 0x60, 0xe3, 0xd1, 0xec, 0xbb, 0x86, + 0xce, 0x06, 0x1d, 0xa5, 0xfd, 0x3a, 0x92, 0xe8, 0xa4, 0x9a, 0x28, 0x93, + 0x6e, 0x16, 0xe8, 0xd6, 0x86, 0x8e, 0xef, 0x50, 0x42, 0x46, 0xd5, 0x5d, + 0x9a, 0x66, 0xae, 0x60, 0x31, 0x6c, 0x38, 0x18, 0x3a, 0x1b, 0x98, 0xcc, + 0x55, 0xe5, 0x92, 0xac, 0xca, 0xfb, 0xae, 0xcc, 0xdc, 0x31, 0x24, 0x9d, + 0x01, 0x1e, 0xa7, 0x3b, 0x11, 0xca, 0xc1, 0x92, 0x60, 0x73, 0x7e, 0x70, + 0x63, 0x54, 0x1e, 0x7d, 0xa5, 0x3c, 0xb9, 0x87, 0x2a, 0x9e, 0xa3, +] +let version0_txt_len = 395 + +extension OctagonPairingTests { + + func testPiggybacking() { + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let rpcEpochCallbackOccurs = self.expectation(description: "rpcEpoch callback occurs") + + self.manager.rpcEpoch(with: self.acceptorPiggybackingConfig) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertEqual(epoch, 1, "epoch should be nil") + rpcEpochCallbackOccurs.fulfill() + } + self.wait(for: [rpcEpochCallbackOccurs], timeout: 10) + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + var peerID: String = "" + var permanentInfo = Data(count: 0) + var permanentInfoSig = Data(count: 0) + var stableInfo = Data(count: 0) + var stableInfoSig = Data(count: 0) + + /*begin message passing*/ + let rpcFirstInitiatorJoiningMessageCallBack = self.expectation(description: "Creating prepare message callback") + self.manager.rpcPrepareIdentityAsApplicant(with: self.initiatorPiggybackingConfig) { pID, pI, pIS, sI, sIS, error in + XCTAssertNotNil(peerID, "peerID should not be nil") + XCTAssertNotNil(permanentInfo, "permanentInfo should not be nil") + XCTAssertNotNil(permanentInfoSig, "permanentInfoSig should not be nil") + XCTAssertNotNil(stableInfo, "stableInfo should not be nil") + XCTAssertNotNil(stableInfoSig, "stableInfoSig should not be nil") + + peerID = pID! + permanentInfo = pI! + permanentInfoSig = pIS! + stableInfo = sI! + stableInfoSig = sIS! + + XCTAssertNil(error, "error should be nil") + rpcFirstInitiatorJoiningMessageCallBack.fulfill() + } + self.wait(for: [rpcFirstInitiatorJoiningMessageCallBack], timeout: 10) + + let firstMessageAcceptorCallback = self.expectation(description: "creating voucher message callback") + var voucher = Data(count: 0) + var voucherSig = Data(count: 0) + + self.manager.rpcVoucher(with: self.acceptorPiggybackingConfig, peerID: peerID, permanentInfo: permanentInfo, permanentInfoSig: permanentInfoSig, stableInfo: stableInfo, stableInfoSig: stableInfoSig) { v, vS, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(v, "voucher should not be nil") + XCTAssertNotNil(vS, "voucher signature should not be nil") + voucher = v + voucherSig = vS + firstMessageAcceptorCallback.fulfill() + } + self.wait(for: [firstMessageAcceptorCallback], timeout: 10) + + let rpcJoinCallback = self.expectation(description: "joining callback") + self.manager.rpcJoin(with: self.initiatorPiggybackingConfig, vouchData: voucher, vouchSig: voucherSig, preapprovedKeys: nil) { error in + XCTAssertNil(error, "error should be nil") + rpcJoinCallback.fulfill() + } + self.wait(for: [rpcJoinCallback], timeout: 10) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: self.cuttlefishContextForAcceptor, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrusted(context: self.cuttlefishContextForAcceptor) + + clientStateMachine.notifyContainerChange() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + + self.verifyDatabaseMocks() + } + + func testVersion2ofPiggybacking() { + KCSetJoiningOctagonPiggybackingEnabled(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let acceptorContext = self.manager.context(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor) + + self.getAcceptorInCircle() + self.assertEnters(context: acceptorContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + var clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (requestDelegate, acceptDelegate, acceptSession, requestSession) = self.setupKCJoiningSessionObjects() + var initialMessageContainingOctagonVersion: Data? + var challengeContainingEpoch: Data? + var response: Data? + var verification: Data? + var doneMessage: Data? + + XCTAssertNotNil(acceptSession, "acceptSession should not be nil") + XCTAssertNotNil(requestSession, "requestSession should not be nil") + XCTAssertNotNil(requestDelegate, "requestDelegate should not be nil") + XCTAssertNotNil(acceptDelegate, "acceptDelegate should not be nil") + + do { + initialMessageContainingOctagonVersion = try requestSession!.initialMessage() + } catch { + XCTAssertNil(error, "error retrieving initialMessageContainingOctagonVersion message") + } + + XCTAssertNotNil(initialMessageContainingOctagonVersion, "initial message should not be nil") + + do { + challengeContainingEpoch = try acceptSession!.processMessage(initialMessageContainingOctagonVersion!) + XCTAssertNotNil(challengeContainingEpoch, "challengeContainingEpoch should not be nil") + } catch { + XCTAssertNil(error, "error retrieving challengeContainingEpoch message") + } + + do { + response = try requestSession!.processMessage(challengeContainingEpoch!) + XCTAssertNotNil(response, "response message should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + do { + verification = try acceptSession!.processMessage(response!) + XCTAssertNotNil(verification, "verification should not be nil") + } catch { + XCTAssertNil(error, "error retrieving verification message") + } + + do { + doneMessage = try requestSession!.processMessage(verification!) + XCTAssertNotNil(doneMessage, "doneMessage should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + XCTAssertTrue(requestSession!.isDone(), "SecretSession done") + XCTAssertFalse(acceptSession!.isDone(), "Unexpected accept session done") + + let aesSession = requestSession!.session + + let requestCircleSession = KCJoiningRequestCircleSession(circleDelegate: requestDelegate!, + session: aesSession!, + otcontrol: self.otControl, + error: nil) + XCTAssertNotNil(requestCircleSession, "No request secret session") + + requestCircleSession.setJoiningConfigurationObject(self.initiatorPiggybackingConfig) + requestCircleSession.setControlObject(self.otControl) + + var identityMessage: Data? + do { + identityMessage = try requestCircleSession.initialMessage() + XCTAssertNotNil(identityMessage, "No identity message") + + } catch { + XCTAssertNil(error, "error retrieving identityMessage message") + } + + var voucherMessage: Data? + do { + voucherMessage = try acceptSession!.processMessage(identityMessage!) + XCTAssertNotNil(voucherMessage, "No voucherMessage message") + } catch { + XCTAssertNil(error, "error retrieving voucherMessage message") + + } + + var nothing: Data? + do { + nothing = try requestCircleSession.processMessage(voucherMessage!) + XCTAssertNotNil(nothing, "No nothing message") + } catch { + XCTAssertNil(error, "error retrieving nothing message") + + } + + XCTAssertTrue(requestSession!.isDone(), "requestor should be done") + XCTAssertTrue(acceptSession!.isDone(), "acceptor should be done") + + clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.notifyContainerChange() + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.sendContainerChange(context: initiator1Context) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: self.cuttlefishContextForAcceptor, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrusted(context: self.cuttlefishContextForAcceptor) + self.verifyDatabaseMocks() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + } + + func testVersion0TestVectorofPiggybacking() { + let (_, _, accept, request) = self.setupKCJoiningSessionObjects() + XCTAssertNotNil(accept, "acceptor should not be nil") + XCTAssertNotNil(request, "requester should not be nil") + + let version0Data = NSData(bytes: version0_txt, length: version0_txt_len) + XCTAssertNotNil(version0Data, "version0Data should not be nil") + do { + let challenge = try accept!.processMessage(version0Data as Data) + XCTAssertNotNil(challenge, "challenge should not be nil") + } catch { + XCTAssertNil(error, "error retrieving initial message") + } + } + + func testVersion1TestVectorofPiggybacking() { + let (_, _, accept, request) = self.setupKCJoiningSessionObjects() + XCTAssertNotNil(accept, "acceptor should not be nil") + XCTAssertNotNil(request, "requester should not be nil") + let version1Data = NSData(bytes: version1_txt, length: version1_txt_len) + XCTAssertNotNil(version1Data, "version1Data should not be nil") + do { + let challenge = try accept!.processMessage(version1Data as Data) + XCTAssertNotNil(challenge, "challenge should not be nil") + } catch { + XCTAssertNil(error, "error retrieving initial message") + } + } + /* FIX ME, This isn't testing version 1. + func testV1() { + let (requestDelegate, acceptDelegate, acceptSession, requestSession) = self.setupKCJoiningSessionObjects() + var initialMessageContainingOctagonVersion: Data? + var challengeContainingEpoch: Data? + var response: Data? + var verification: Data? + var doneMessage: Data? + + XCTAssertNotNil(acceptSession, "acceptSession should not be nil") + XCTAssertNotNil(requestSession, "requestSession should not be nil") + XCTAssertNotNil(requestDelegate, "requestDelegate should not be nil") + XCTAssertNotNil(acceptDelegate, "acceptDelegate should not be nil") + + do { + initialMessageContainingOctagonVersion = try requestSession!.initialMessage() + } catch { + XCTAssertNil(error, "error retrieving initialMessageContainingOctagonVersion message") + } + + XCTAssertNotNil(initialMessageContainingOctagonVersion, "initial message should not be nil") + + do { + challengeContainingEpoch = try acceptSession!.processMessage(initialMessageContainingOctagonVersion!) + XCTAssertNotNil(challengeContainingEpoch, "challengeContainingEpoch should not be nil") + } catch { + XCTAssertNil(error, "error retrieving challengeContainingEpoch message") + } + + do { + response = try requestSession!.processMessage(challengeContainingEpoch!) + XCTAssertNotNil(response, "response message should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + do { + verification = try acceptSession!.processMessage(response!) + XCTAssertNotNil(verification, "verification should not be nil") + } catch { + XCTAssertNil(error, "error retrieving verification message") + } + + do { + doneMessage = try requestSession!.processMessage(verification!) + XCTAssertNotNil(doneMessage, "doneMessage should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + XCTAssertTrue(requestSession!.isDone(), "SecretSession done") + XCTAssertFalse(acceptSession!.isDone(), "Unexpected accept session done") + + let aesSession = requestSession!.session + + let requestCircleSession = KCJoiningRequestCircleSession(circleDelegate: requestDelegate!, session: aesSession!, error: nil) + XCTAssertNotNil(requestCircleSession, "No request secret session") + + requestCircleSession.setJoiningConfigurationObject(self.initiatorPiggybackingConfig) + requestCircleSession.setControlObject(self.otControl) + + var identityMessage: Data? + do { + identityMessage = try requestCircleSession.initialMessage() + XCTAssertNotNil(identityMessage, "No identity message") + + } catch { + XCTAssertNil(error, "error retrieving identityMessage message") + } + + var voucherMessage: Data? + do { + voucherMessage = try acceptSession!.processMessage(identityMessage!) + XCTAssertNotNil(voucherMessage, "No voucherMessage message") + } catch { + XCTAssertNil(error, "error retrieving voucherMessage message") + + } + + var nothing: Data? + do { + nothing = try requestCircleSession.processMessage(voucherMessage!) + XCTAssertNotNil(nothing, "No nothing message") + } catch { + XCTAssertNil(error, "error retrieving nothing message") + + } + + XCTAssertTrue(requestSession!.isDone(), "requestor should be done") + XCTAssertTrue(acceptSession!.isDone(), "acceptor should be done") + } +*/ + func testPairingReset() { + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + let rpcEpochCallbackOccurs = self.expectation(description: "rpcEpoch callback occurs") + + self.manager.rpcEpoch(with: self.acceptorPiggybackingConfig) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertEqual(epoch, 1, "epoch should be nil") + rpcEpochCallbackOccurs.fulfill() + } + self.wait(for: [rpcEpochCallbackOccurs], timeout: 10) + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + var peerID: String = "" + var permanentInfo = Data(count: 0) + var permanentInfoSig = Data(count: 0) + var stableInfo = Data(count: 0) + var stableInfoSig = Data(count: 0) + + /*begin message passing*/ + let rpcFirstInitiatorJoiningCallBack = self.expectation(description: "Creating prepare callback") + self.manager.rpcPrepareIdentityAsApplicant(with: self.initiatorPiggybackingConfig) { pID, pI, pISig, sI, sISig, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(pID, "peer id should not be nil") + XCTAssertNotNil(pI, "permanentInfo should not be nil") + XCTAssertNotNil(sI, "sI should not be nil") + XCTAssertNotNil(sISig, "sISig should not be nil") + + peerID = pID! + permanentInfo = pI! + permanentInfoSig = pISig! + stableInfo = sI! + stableInfoSig = sISig! + + rpcFirstInitiatorJoiningCallBack.fulfill() + } + self.wait(for: [rpcFirstInitiatorJoiningCallBack], timeout: 10) + + let firstAcceptorCallback = self.expectation(description: "creating vouch callback") + + self.manager.rpcVoucher(with: self.acceptorPiggybackingConfig, peerID: peerID, permanentInfo: permanentInfo, permanentInfoSig: permanentInfoSig, stableInfo: stableInfo, stableInfoSig: stableInfoSig) { voucher, voucherSig, error in + XCTAssertNotNil(voucher, "voucher should not be nil") + XCTAssertNotNil(voucherSig, "voucherSig should not be nil") + XCTAssertNil(error, "error should be nil") + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + //change pairing UUID + + initiator1Context.pairingUUID = "1234" + + let firstMessageWithNewJoiningConfigCallback = self.expectation(description: "first message with different configuration") + self.manager.rpcPrepareIdentityAsApplicant(with: self.initiatorPiggybackingConfig) { pID, pI, pISig, sI, sISig, error in + XCTAssertNil(error, "error should be nil") + XCTAssertNil(error, "error should be nil") + XCTAssertNotNil(pID, "peer id should not be nil") + XCTAssertNotNil(pI, "permanentInfo should not be nil") + XCTAssertNotNil(sI, "sI should not be nil") + XCTAssertNotNil(sISig, "sISig should not be nil") + + peerID = pID! + permanentInfo = pI! + permanentInfoSig = pISig! + stableInfo = sI! + stableInfoSig = sISig! + firstMessageWithNewJoiningConfigCallback.fulfill() + } + self.wait(for: [firstMessageWithNewJoiningConfigCallback], timeout: 10) + } + + func testVersion2ofPiggybackingWithSOS() { + KCSetJoiningOctagonPiggybackingEnabled(true) + OctagonSetPlatformSupportsSOS(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + var clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + // Note that in this strange situation, the join should create the CKKS TLKs + let (requestDelegate, acceptDelegate, acceptSession, requestSession) = self.setupKCJoiningSessionObjects() + var initialMessageContainingOctagonVersion: Data? + var challengeContainingEpoch: Data? + var response: Data? + var verification: Data? + var doneMessage: Data? + + XCTAssertNotNil(acceptSession, "acceptSession should not be nil") + XCTAssertNotNil(requestSession, "requestSession should not be nil") + XCTAssertNotNil(requestDelegate, "requestDelegate should not be nil") + XCTAssertNotNil(acceptDelegate, "acceptDelegate should not be nil") + + do { + initialMessageContainingOctagonVersion = try requestSession!.initialMessage() + } catch { + XCTAssertNil(error, "error retrieving initialMessageContainingOctagonVersion message") + } + + XCTAssertNotNil(initialMessageContainingOctagonVersion, "initial message should not be nil") + + do { + challengeContainingEpoch = try acceptSession!.processMessage(initialMessageContainingOctagonVersion!) + XCTAssertNotNil(challengeContainingEpoch, "challengeContainingEpoch should not be nil") + } catch { + XCTAssertNil(error, "error retrieving challengeContainingEpoch message") + } + + do { + response = try requestSession!.processMessage(challengeContainingEpoch!) + XCTAssertNotNil(response, "response message should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + do { + verification = try acceptSession!.processMessage(response!) + XCTAssertNotNil(verification, "verification should not be nil") + } catch { + XCTAssertNil(error, "error retrieving verification message") + } + + do { + doneMessage = try requestSession!.processMessage(verification!) + XCTAssertNotNil(doneMessage, "doneMessage should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + XCTAssertTrue(requestSession!.isDone(), "SecretSession done") + XCTAssertFalse(acceptSession!.isDone(), "Unexpected accept session done") + + let aesSession = requestSession!.session + + let requestCircleSession = KCJoiningRequestCircleSession(circleDelegate: requestDelegate!, + session: aesSession!, + otcontrol: self.otControl, + error: nil) + XCTAssertNotNil(requestCircleSession, "No request secret session") + + requestCircleSession.setJoiningConfigurationObject(self.initiatorPiggybackingConfig) + requestCircleSession.setControlObject(self.otControl) + + var identityMessage: Data? + do { + identityMessage = try requestCircleSession.initialMessage() + let parsedMessage = try KCJoiningMessage(der: identityMessage!) + XCTAssertNotNil(parsedMessage.firstData, "No octagon message") + XCTAssertNotNil(parsedMessage.secondData, "No sos message") + XCTAssertNotNil(identityMessage, "No identity message") + + } catch { + XCTAssertNil(error, "error retrieving identityMessage message") + } + + var voucherMessage: Data? + do { + voucherMessage = try acceptSession!.processMessage(identityMessage!) + let parsedMessage = try KCJoiningMessage(der: identityMessage!) + XCTAssertNotNil(parsedMessage.firstData, "No octagon message") + XCTAssertNotNil(parsedMessage.secondData, "No sos message") + XCTAssertNotNil(voucherMessage, "No voucherMessage message") + } catch { + XCTAssertNil(error, "error retrieving voucherMessage message") + + } + + var nothing: Data? + do { + nothing = try requestCircleSession.processMessage(voucherMessage!) + XCTAssertNotNil(nothing, "No nothing message") + } catch { + XCTAssertNil(error, "error retrieving nothing message") + } + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + XCTAssertTrue(requestSession!.isDone(), "requestor should be done") + XCTAssertTrue(acceptSession!.isDone(), "acceptor should be done") + + clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.notifyContainerChange() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: self.cuttlefishContextForAcceptor, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrusted(context: self.cuttlefishContextForAcceptor) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + self.assertTLKSharesInCloudKit(receiver: self.cuttlefishContextForAcceptor, sender: self.cuttlefishContext) + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + } + + func testOctagonCapableButAcceptorHasNoIdentity() { + KCSetJoiningOctagonPiggybackingEnabled(true) + OctagonSetPlatformSupportsSOS(true) + OctagonSetSOSUpgrade(true) + self.startCKAccountStatusMock() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + _ = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (requestDelegate, acceptDelegate, acceptSession, requestSession) = self.setupKCJoiningSessionObjects() + var initialMessageContainingOctagonVersion: Data? + var challengeContainingEpoch: Data? + var response: Data? + var verification: Data? + var doneMessage: Data? + + XCTAssertNotNil(acceptSession, "acceptSession should not be nil") + XCTAssertNotNil(requestSession, "requestSession should not be nil") + XCTAssertNotNil(requestDelegate, "requestDelegate should not be nil") + XCTAssertNotNil(acceptDelegate, "acceptDelegate should not be nil") + + do { + initialMessageContainingOctagonVersion = try requestSession!.initialMessage() + } catch { + XCTAssertNil(error, "error retrieving initialMessageContainingOctagonVersion message") + } + + XCTAssertNotNil(initialMessageContainingOctagonVersion, "initial message should not be nil") + + do { + challengeContainingEpoch = try acceptSession!.processMessage(initialMessageContainingOctagonVersion!) + XCTAssertNotNil(challengeContainingEpoch, "challengeContainingEpoch should not be nil") + } catch { + XCTAssertNil(error, "error retrieving challengeContainingEpoch message") + } + + do { + response = try requestSession!.processMessage(challengeContainingEpoch!) + XCTAssertNotNil(response, "response message should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + do { + verification = try acceptSession!.processMessage(response!) + XCTAssertNotNil(verification, "verification should not be nil") + } catch { + XCTAssertNil(error, "error retrieving verification message") + } + + do { + doneMessage = try requestSession!.processMessage(verification!) + XCTAssertNotNil(doneMessage, "doneMessage should not be nil") + } catch { + XCTAssertNil(error, "error retrieving response message") + } + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + XCTAssertTrue(requestSession!.isDone(), "SecretSession done") + XCTAssertFalse(acceptSession!.isDone(), "Unexpected accept session done") + + let aesSession = requestSession!.session + + let requestCircleSession = KCJoiningRequestCircleSession(circleDelegate: requestDelegate!, + session: aesSession!, + otcontrol: self.otControl, + error: nil) + XCTAssertNotNil(requestCircleSession, "No request secret session") + + requestCircleSession.setJoiningConfigurationObject(self.initiatorPiggybackingConfig) + requestCircleSession.setControlObject(self.otControl) + + var identityMessage: Data? + do { + identityMessage = try requestCircleSession.initialMessage() + XCTAssertNotNil(identityMessage, "No identity message") + + } catch { + XCTAssertNil(error, "error retrieving identityMessage message") + } + + var voucherMessage: Data? + do { + voucherMessage = try acceptSession!.processMessage(identityMessage!) + XCTAssertNotNil(voucherMessage, "No voucherMessage message") + } catch { + XCTAssertNil(error, "error retrieving voucherMessage message") + + } + + var nothing: Data? + do { + nothing = try requestCircleSession.processMessage(voucherMessage!) + XCTAssertNotNil(nothing, "No nothing message") + } catch { + XCTAssertNil(error, "error retrieving nothing message") + + } + + XCTAssertTrue(requestSession!.isDone(), "requestor should be done") + XCTAssertTrue(acceptSession!.isDone(), "acceptor should be done") + } + +} + +#endif diff --git a/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProxMultiClients.swift b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProxMultiClients.swift new file mode 100644 index 00000000..e6b28859 --- /dev/null +++ b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProxMultiClients.swift @@ -0,0 +1,1581 @@ +#if OCTAGON + +extension OctagonPairingTests { + + func test2ClientsBothOctagonAndSOS() { + + OctagonSetPlatformSupportsSOS(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator2ContextID = "initiatorContext2" + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let initiator2Context = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiator2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-initiator-2", serialNumber: "456", osVersion: "iOS (fake version)")) + + initiator1Context.startOctagonStateMachine() + initiator2Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: initiator2Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let clientStateMachine2 = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: "initiator-2") + + let (acceptor2, initiator2) = self.setupPairingEndpoints(withPairNumber: "2", initiatorContextID: initiator2ContextID, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: "initiator-2", acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor2, "acceptor should not be nil") + XCTAssertNotNil(initiator2, "initiator should not be nil") + + var signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-1 INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* PAIR-1 ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorFirstPacket, "first packet should not be nil") + + /* PAIR-1 INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorSecondPacket, "initiator second packet should not be nil") + + /* PAIR-1 ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-1 INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = (packet) + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + var acceptorThirdPacket = Data() + let ThirdAcceptorCallback = self.expectation(description: "ThirdAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorThirdPacket = packet! + ThirdAcceptorCallback.fulfill() + } + self.wait(for: [ThirdAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorThirdPacket, "acceptor third packet should not be nil") + + /* PAIR-1 INITIATOR FOURTH STEP*/ + let fourthInitiatorCallback = self.expectation(description: "fourthInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + fourthInitiatorCallback.fulfill() + } + + self.wait(for: [fourthInitiatorCallback], timeout: 10) + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.notifyContainerChange() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + /* + SECOND PAIRING + */ + signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: initiator2ContextID) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-2 INITIATOR FIRST RTT JOINING MESSAGE*/ + var pair2InitiatorFirstPacket = Data() + let pair2FirstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator2.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorFirstPacket = packet! + pair2FirstInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FirstInitiatorCallback], timeout: 10) + + /* PAIR-2 ACCEPTOR FIRST RTT EPOCH*/ + var pair2AcceptorFirstPacket = Data() + let pair2FirstAcceptorCallback = self.expectation(description: "pair2FirstAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorFirstPacket = packet! + pair2FirstAcceptorCallback.fulfill() + } + self.wait(for: [pair2FirstAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorFirstPacket, "first packet should not be nil") + + /* PAIR-2 INITIATOR SECOND RTT PREPARE*/ + var pair2InitiatorSecondPacket = Data() + let pair2SecondInitiatorCallback = self.expectation(description: "pair2SecondInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorSecondPacket = packet! + pair2SecondInitiatorCallback.fulfill() + } + + self.wait(for: [pair2SecondInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorSecondPacket, "pair2InitiatorSecondPacket should not be nil") + + /* PAIR-2 ACCEPTOR SECOND RTT */ + var pair2AcceptorSecondPacket = Data() + let pair2SecondAcceptorCallback = self.expectation(description: "pair2SecondAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorSecondPacket = packet! + pair2SecondAcceptorCallback.fulfill() + } + self.wait(for: [pair2SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR THIRD STEP*/ + var pair2InitiatorThirdPacket: Data? + let pair2ThirdInitiatorCallback = self.expectation(description: "pair2ThirdInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorThirdPacket = (packet) + pair2ThirdInitiatorCallback.fulfill() + } + self.wait(for: [pair2ThirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorThirdPacket, "acceptor second packet should not be nil") + + var pair2AcceptorThirdPacket = Data() + let pair2FourthAcceptorCallback = self.expectation(description: "pair2FourthAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorThirdPacket = packet! + pair2FourthAcceptorCallback.fulfill() + } + self.wait(for: [pair2FourthAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorThirdPacket, "acceptor third packet should not be nil") + + /* PAIR-2 INITIATOR FOURTH STEP*/ + let pair2FourthInitiatorCallback = self.expectation(description: "pair2FourthInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + pair2FourthInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FourthInitiatorCallback], timeout: 10) + + clientStateMachine2.notifyContainerChange() + + let pair2InitiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + pair2InitiatorDumpCallback.fulfill() + } + self.wait(for: [pair2InitiatorDumpCallback], timeout: 10) + + let pair2AcceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 3, "should be 3 peer ids") + pair2AcceptorDumpCallback.fulfill() + } + self.wait(for: [pair2AcceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 3, "should be 3 bottles") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + } + + func test2ClientsOctagonOnly() { + OctagonSetIsEnabled(true) + OctagonSetPlatformSupportsSOS(false) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator2ContextID = "initiatorContext2" + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let initiator2Context = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiator2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-initiator-2", serialNumber: "456", osVersion: "iOS (fake version)")) + + initiator1Context.startOctagonStateMachine() + initiator2Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: initiator2Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let clientStateMachine2 = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: "initiator-2") + + let (acceptor2, initiator2) = self.setupPairingEndpoints(withPairNumber: "2", initiatorContextID: initiator2ContextID, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: "initiator-2", acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor2, "acceptor should not be nil") + XCTAssertNotNil(initiator2, "initiator should not be nil") + + var signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-1 INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* PAIR-1 ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorFirstPacket, "first packet should not be nil") + + /* PAIR-1 INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorSecondPacket, "initiator second packet should not be nil") + + /* PAIR-1 ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-1 INITIATOR THIRD STEP*/ + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.notifyContainerChange() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + /* + SECOND PAIRING + */ + signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: initiator2ContextID) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-2 INITIATOR FIRST RTT JOINING MESSAGE*/ + var pair2InitiatorFirstPacket = Data() + let pair2FirstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator2.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorFirstPacket = packet! + pair2FirstInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FirstInitiatorCallback], timeout: 10) + + /* PAIR-2 ACCEPTOR FIRST RTT EPOCH*/ + var pair2AcceptorFirstPacket = Data() + let pair2FirstAcceptorCallback = self.expectation(description: "pair2FirstAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorFirstPacket = packet! + pair2FirstAcceptorCallback.fulfill() + } + self.wait(for: [pair2FirstAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorFirstPacket, "first packet should not be nil") + + /* PAIR-2 INITIATOR SECOND RTT PREPARE*/ + var pair2InitiatorSecondPacket = Data() + let pair2SecondInitiatorCallback = self.expectation(description: "pair2SecondInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorSecondPacket = packet! + pair2SecondInitiatorCallback.fulfill() + } + + self.wait(for: [pair2SecondInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorSecondPacket, "pair2InitiatorSecondPacket should not be nil") + + /* PAIR-2 ACCEPTOR SECOND RTT */ + var pair2AcceptorSecondPacket = Data() + let pair2SecondAcceptorCallback = self.expectation(description: "pair2SecondAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorSecondPacket = packet! + pair2SecondAcceptorCallback.fulfill() + } + self.wait(for: [pair2SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR THIRD STEP*/ + let pair2ThirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + pair2ThirdInitiatorCallback.fulfill() + } + self.wait(for: [pair2ThirdInitiatorCallback], timeout: 10) + + clientStateMachine2.notifyContainerChange() + + let pair2InitiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + pair2InitiatorDumpCallback.fulfill() + } + self.wait(for: [pair2InitiatorDumpCallback], timeout: 10) + + let pair2AcceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 3, "should be 3 peer ids") + pair2AcceptorDumpCallback.fulfill() + } + self.wait(for: [pair2AcceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 3, "should be 3 bottles") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + self.verifyDatabaseMocks() + } + + func test2ClientsSOSOnly() { + + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(false) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator2ContextID = "initiatorContext2" + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let initiator2Context = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiator2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-initiator-2", serialNumber: "456", osVersion: "iOS (fake version)")) + + initiator1Context.startOctagonStateMachine() + initiator2Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: initiator2Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let (acceptor2, initiator2) = self.setupPairingEndpoints(withPairNumber: "2", initiatorContextID: initiator2ContextID, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: "initiator-2", acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor2, "acceptor should not be nil") + XCTAssertNotNil(initiator2, "initiator should not be nil") + + var signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-1 INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* PAIR-1 ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorFirstPacket, "first packet should not be nil") + + /* PAIR-1 INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorSecondPacket, "initiator second packet should not be nil") + + /* PAIR-1 ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-1 INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = (packet) + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + var acceptorThirdPacket = Data() + let ThirdAcceptorCallback = self.expectation(description: "ThirdAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorThirdPacket = packet! + ThirdAcceptorCallback.fulfill() + } + self.wait(for: [ThirdAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorThirdPacket, "acceptor third packet should not be nil") + + /* PAIR-1 INITIATOR FOURTH STEP*/ + let fourthInitiatorCallback = self.expectation(description: "fourthInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + fourthInitiatorCallback.fulfill() + } + + self.wait(for: [fourthInitiatorCallback], timeout: 10) + + /* + SECOND PAIRING + */ + signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: initiator2ContextID) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-2 INITIATOR FIRST RTT JOINING MESSAGE*/ + var pair2InitiatorFirstPacket = Data() + let pair2FirstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator2.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorFirstPacket = packet! + pair2FirstInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FirstInitiatorCallback], timeout: 10) + + /* PAIR-2 ACCEPTOR FIRST RTT EPOCH*/ + var pair2AcceptorFirstPacket = Data() + let pair2FirstAcceptorCallback = self.expectation(description: "pair2FirstAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorFirstPacket = packet! + pair2FirstAcceptorCallback.fulfill() + } + self.wait(for: [pair2FirstAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorFirstPacket, "first packet should not be nil") + + /* PAIR-2 INITIATOR SECOND RTT PREPARE*/ + var pair2InitiatorSecondPacket = Data() + let pair2SecondInitiatorCallback = self.expectation(description: "pair2SecondInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorSecondPacket = packet! + pair2SecondInitiatorCallback.fulfill() + } + + self.wait(for: [pair2SecondInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorSecondPacket, "pair2InitiatorSecondPacket should not be nil") + + /* PAIR-2 ACCEPTOR SECOND RTT */ + var pair2AcceptorSecondPacket = Data() + let pair2SecondAcceptorCallback = self.expectation(description: "pair2SecondAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorSecondPacket = packet! + pair2SecondAcceptorCallback.fulfill() + } + self.wait(for: [pair2SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR THIRD STEP*/ + var pair2InitiatorThirdPacket: Data? + let pair2ThirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorThirdPacket = (packet) + pair2ThirdInitiatorCallback.fulfill() + } + self.wait(for: [pair2ThirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorThirdPacket, "acceptor second packet should not be nil") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } + + func test2ClientsInterlacedOctagonAndSOS() { + OctagonSetPlatformSupportsSOS(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator2ContextID = "initiatorContext2" + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let initiator2Context = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiator2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-initiator-2", serialNumber: "456", osVersion: "iOS (fake version)")) + + initiator1Context.startOctagonStateMachine() + initiator2Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: initiator2Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let clientStateMachine2 = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: "initiator-2") + + let (acceptor2, initiator2) = self.setupPairingEndpoints(withPairNumber: "2", initiatorContextID: initiator2ContextID, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: "initiator-2", acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor2, "acceptor should not be nil") + XCTAssertNotNil(initiator2, "initiator should not be nil") + + var signInCallback = self.expectation(description: "trigger sign in for initiator one") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-1 INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* PAIR-1 ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorFirstPacket, "first packet should not be nil") + + signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: initiator2ContextID) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-2 INITIATOR FIRST RTT JOINING MESSAGE*/ + var pair2InitiatorFirstPacket = Data() + let pair2FirstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator2.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorFirstPacket = packet! + pair2FirstInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FirstInitiatorCallback], timeout: 10) + + /* PAIR-1 INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorSecondPacket, "initiator second packet should not be nil") + + /* PAIR-1 ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 ACCEPTOR FIRST RTT EPOCH*/ + var pair2AcceptorFirstPacket = Data() + let pair2FirstAcceptorCallback = self.expectation(description: "pair2FirstAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorFirstPacket = packet! + pair2FirstAcceptorCallback.fulfill() + } + self.wait(for: [pair2FirstAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorFirstPacket, "first packet should not be nil") + + /* PAIR-1 INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = (packet) + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + /* PAIR-2 INITIATOR SECOND RTT PREPARE*/ + var pair2InitiatorSecondPacket = Data() + let pair2SecondInitiatorCallback = self.expectation(description: "pair2SecondInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorSecondPacket = packet! + pair2SecondInitiatorCallback.fulfill() + } + + self.wait(for: [pair2SecondInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorSecondPacket, "pair2InitiatorSecondPacket should not be nil") + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.notifyContainerChange() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + /* PAIR-2 ACCEPTOR SECOND RTT */ + var pair2AcceptorSecondPacket = Data() + let pair2SecondAcceptorCallback = self.expectation(description: "pair2SecondAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorSecondPacket = packet! + pair2SecondAcceptorCallback.fulfill() + } + self.wait(for: [pair2SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR THIRD STEP*/ + var pair2InitiatorThirdPacket: Data? + let pair2ThirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorThirdPacket = (packet) + pair2ThirdInitiatorCallback.fulfill() + } + self.wait(for: [pair2ThirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorThirdPacket, "acceptor second packet should not be nil") + + clientStateMachine2.notifyContainerChange() + clientStateMachine.notifyContainerChange() + + let pair2InitiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + pair2InitiatorDumpCallback.fulfill() + } + self.wait(for: [pair2InitiatorDumpCallback], timeout: 10) + + let pair2AcceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 3, "should be 3 peer ids") + pair2AcceptorDumpCallback.fulfill() + } + self.wait(for: [pair2AcceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 3, "should be 3 bottles") + + let initiatorStatus = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.trustStatus(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { egoStatus, error in + XCTAssertEqual(egoStatus.egoStatus.rawValue & TPPeerStatus.partiallyReciprocated.rawValue, TPPeerStatus.partiallyReciprocated.rawValue, "initiator should be partially accepted") + XCTAssertNotNil(egoStatus.egoPeerID, "should have an identity") + XCTAssertEqual(egoStatus.numberOfPeersInOctagon, 2, "should have 2 peers") + XCTAssertFalse(egoStatus.isExcluded, "should not be excluded") + XCTAssertFalse(egoStatus.isLocked, "should not be locked") + XCTAssertNil(error, "error should be nil") + initiatorStatus.fulfill() + } + self.wait(for: [initiatorStatus], timeout: 10) + + let acceptorStatus = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.trustStatus(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) {egoStatus, error in + XCTAssertEqual(egoStatus.egoStatus.rawValue & TPPeerStatus.partiallyReciprocated.rawValue, TPPeerStatus.partiallyReciprocated.rawValue, "acceptor should be partially accepted") + XCTAssertNotNil(egoStatus.egoPeerID, "should have an identity") + XCTAssertEqual(egoStatus.numberOfPeersInOctagon, 3, "should have 2 peers") + XCTAssertFalse(egoStatus.isExcluded, "should not be excluded") + XCTAssertFalse(egoStatus.isLocked, "should not be locked") + XCTAssertNil(error, "error should be nil") + acceptorStatus.fulfill() + } + self.wait(for: [acceptorStatus], timeout: 10) + + self.verifyDatabaseMocks() + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func test2ClientsInterlacedOctagonOnly() { + OctagonSetPlatformSupportsSOS(false) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator2ContextID = "initiatorContext2" + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let initiator2Context = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiator2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-initiator-2", serialNumber: "456", osVersion: "iOS (fake version)")) + + initiator1Context.startOctagonStateMachine() + initiator2Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: initiator2Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let clientStateMachine2 = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: "initiator-2") + + let (acceptor2, initiator2) = self.setupPairingEndpoints(withPairNumber: "2", initiatorContextID: initiator2ContextID, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: "initiator-2", acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor2, "acceptor should not be nil") + XCTAssertNotNil(initiator2, "initiator should not be nil") + + var signInCallback = self.expectation(description: "trigger sign in for initiator one") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-1 INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* PAIR-1 ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorFirstPacket, "first packet should not be nil") + + signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: initiator2ContextID) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-2 INITIATOR FIRST RTT JOINING MESSAGE*/ + var pair2InitiatorFirstPacket = Data() + let pair2FirstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator2.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorFirstPacket = packet! + pair2FirstInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FirstInitiatorCallback], timeout: 10) + + /* PAIR-1 INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorSecondPacket, "initiator second packet should not be nil") + + /* PAIR-1 ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 ACCEPTOR FIRST RTT EPOCH*/ + var pair2AcceptorFirstPacket = Data() + let pair2FirstAcceptorCallback = self.expectation(description: "pair2FirstAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorFirstPacket = packet! + pair2FirstAcceptorCallback.fulfill() + } + self.wait(for: [pair2FirstAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorFirstPacket, "first packet should not be nil") + + /* PAIR-1 INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = (packet) + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNil(initiatorThirdPacket, "acceptor second packet should be nil") + + /* PAIR-2 INITIATOR SECOND RTT PREPARE*/ + var pair2InitiatorSecondPacket = Data() + let pair2SecondInitiatorCallback = self.expectation(description: "pair2SecondInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorSecondPacket = packet! + pair2SecondInitiatorCallback.fulfill() + } + + self.wait(for: [pair2SecondInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorSecondPacket, "pair2InitiatorSecondPacket should not be nil") + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.notifyContainerChange() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + /* PAIR-2 ACCEPTOR SECOND RTT */ + var pair2AcceptorSecondPacket = Data() + let pair2SecondAcceptorCallback = self.expectation(description: "pair2SecondAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorSecondPacket = packet! + pair2SecondAcceptorCallback.fulfill() + } + self.wait(for: [pair2SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR THIRD STEP*/ + var pair2InitiatorThirdPacket: Data? + let pair2ThirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorThirdPacket = (packet) + pair2ThirdInitiatorCallback.fulfill() + } + self.wait(for: [pair2ThirdInitiatorCallback], timeout: 10) + XCTAssertNil(pair2InitiatorThirdPacket, "acceptor second packet should be nil") + + clientStateMachine2.notifyContainerChange() + + clientStateMachine.notifyContainerChange() + + let pair2InitiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + pair2InitiatorDumpCallback.fulfill() + } + self.wait(for: [pair2InitiatorDumpCallback], timeout: 10) + + let pair2AcceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 3, "should be 3 peer ids") + pair2AcceptorDumpCallback.fulfill() + } + self.wait(for: [pair2AcceptorDumpCallback], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 3, "should be 3 bottles") + + let initiatorStatus = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.trustStatus(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) {egoStatus, error in + XCTAssertEqual(egoStatus.egoStatus.rawValue & TPPeerStatus.partiallyReciprocated.rawValue, TPPeerStatus.partiallyReciprocated.rawValue, "initiator should be partially accepted") + XCTAssertNotNil(egoStatus.egoPeerID, "should have an identity") + XCTAssertEqual(egoStatus.numberOfPeersInOctagon, 2, "should be 2 peers") + XCTAssertFalse(egoStatus.isExcluded, "should not be excluded") + + XCTAssertNil(error, "error should be nil") + initiatorStatus.fulfill() + } + self.wait(for: [initiatorStatus], timeout: 10) + + let acceptorStatus = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.trustStatus(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) {egoStatus, error in + XCTAssertEqual(egoStatus.egoStatus.rawValue & TPPeerStatus.partiallyReciprocated.rawValue, TPPeerStatus.partiallyReciprocated.rawValue, "acceptor should be partially accepted") + XCTAssertNotNil(egoStatus.egoPeerID, "should have an identity") + XCTAssertEqual(egoStatus.numberOfPeersInOctagon, 3, "should be 3 peers") + XCTAssertFalse(egoStatus.isExcluded, "should not be excluded") + XCTAssertNil(error, "error should be nil") + acceptorStatus.fulfill() + } + self.wait(for: [acceptorStatus], timeout: 10) + + self.verifyDatabaseMocks() + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func test2ClientsInterlacedSOSOnly() { + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(false) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator2ContextID = "initiatorContext2" + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + let initiator2Context = self.manager.context(forContainerName: OTCKContainerName, + contextID: initiator2ContextID, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-initiator-2", serialNumber: "456", osVersion: "iOS (fake version)")) + + initiator1Context.startOctagonStateMachine() + initiator2Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: initiator2Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let (acceptor2, initiator2) = self.setupPairingEndpoints(withPairNumber: "2", initiatorContextID: initiator2ContextID, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: "initiator-2", acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor2, "acceptor should not be nil") + XCTAssertNotNil(initiator2, "initiator should not be nil") + + var signInCallback = self.expectation(description: "trigger sign in for initiator one") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-1 INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* PAIR-1 ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorFirstPacket, "first packet should not be nil") + + signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: initiator2ContextID) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* PAIR-2 INITIATOR FIRST RTT JOINING MESSAGE*/ + var pair2InitiatorFirstPacket = Data() + let pair2FirstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator2.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorFirstPacket = packet! + pair2FirstInitiatorCallback.fulfill() + } + + self.wait(for: [pair2FirstInitiatorCallback], timeout: 10) + + /* PAIR-1 INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorSecondPacket, "initiator second packet should not be nil") + + /* PAIR-1 ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 ACCEPTOR FIRST RTT EPOCH*/ + var pair2AcceptorFirstPacket = Data() + let pair2FirstAcceptorCallback = self.expectation(description: "pair2FirstAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorFirstPacket = packet! + pair2FirstAcceptorCallback.fulfill() + } + self.wait(for: [pair2FirstAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorFirstPacket, "first packet should not be nil") + + /* PAIR-1 INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = (packet) + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR SECOND RTT PREPARE*/ + var pair2InitiatorSecondPacket = Data() + let pair2SecondInitiatorCallback = self.expectation(description: "pair2SecondInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorSecondPacket = packet! + pair2SecondInitiatorCallback.fulfill() + } + + self.wait(for: [pair2SecondInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorSecondPacket, "pair2InitiatorSecondPacket should not be nil") + + /* PAIR-2 ACCEPTOR SECOND RTT */ + var pair2AcceptorSecondPacket = Data() + let pair2SecondAcceptorCallback = self.expectation(description: "pair2SecondAcceptorCallback callback occurs") + + acceptor2.exchangePacket(pair2InitiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2AcceptorSecondPacket = packet! + pair2SecondAcceptorCallback.fulfill() + } + self.wait(for: [pair2SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(pair2AcceptorSecondPacket, "acceptor second packet should not be nil") + + /* PAIR-2 INITIATOR THIRD STEP*/ + var pair2InitiatorThirdPacket: Data? + let pair2ThirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator2.exchangePacket(pair2AcceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + pair2InitiatorThirdPacket = (packet) + pair2ThirdInitiatorCallback.fulfill() + } + self.wait(for: [pair2ThirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(pair2InitiatorThirdPacket, "acceptor second packet should not be nil") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLKCreation, within: 10 * NSEC_PER_SEC) + } +} + +#endif /* OCTAGON */ diff --git a/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProximitySetup.swift b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProximitySetup.swift new file mode 100644 index 00000000..3e4d1147 --- /dev/null +++ b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests+ProximitySetup.swift @@ -0,0 +1,1954 @@ +#if OCTAGON + +extension OctagonPairingTests { + + func assertSOSSuccess() { + XCTAssertNotNil(self.fcInitiator?.accountPrivateKey ?? nil, "no accountPrivateKey in fcInitiator"); + XCTAssertNotNil(self.fcAcceptor?.accountPrivateKey ?? nil, "no accountPrivateKey in fcAcceptor"); + XCTAssert(CFEqualSafe(self.fcInitiator.accountPrivateKey, self.fcAcceptor.accountPrivateKey), "no accountPrivateKey not same in both"); + + XCTAssert(SOSCircleHasPeer(self.circle, self.fcInitiator.peerInfo(), nil), "HasPeer 1") +// XCTAssert(SOSCircleHasPeer(self.circle, self.fcAcceptor.peerInfo(), nil), "HasPeer 2") + } + + func testJoin() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let rpcEpochCallbacks = self.expectation(description: "rpcEpoch callback occurs") + clientStateMachine.rpcEpoch(self.cuttlefishContextForAcceptor) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertTrue(epoch == 1, "epoch should be 1") + rpcEpochCallbacks.fulfill() + } + self.wait(for: [rpcEpochCallbacks], timeout: 10) + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* now initiator's turn*/ + /* calling prepare identity*/ + let rpcInitiatorPrepareCallback = self.expectation(description: "rpcPrepare callback occurs") + + var p = String() + var pI = Data() + var pIS = Data() + var sI = Data() + var sIS = Data() + + initiator1Context.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig, epoch: 1) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error calling 'prepare'") + XCTAssertNotNil(peerID, "Prepare should have returned a peerID") + XCTAssertNotNil(permanentInfo, "Prepare should have returned a permanentInfo") + XCTAssertNotNil(permanentInfoSig, "Prepare should have returned a permanentInfoSig") + XCTAssertNotNil(stableInfo, "Prepare should have returned a stableInfo") + XCTAssertNotNil(stableInfoSig, "Prepare should have returned a stableInfoSig") + + p = peerID! + pI = permanentInfo! + pIS = permanentInfoSig! + sI = stableInfo! + sIS = stableInfoSig! + + rpcInitiatorPrepareCallback.fulfill() + } + + self.wait(for: [rpcInitiatorPrepareCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateInitiatorAwaitingVoucher, within: 10 * NSEC_PER_SEC) + + /* calling voucher */ + let rpcVoucherCallback = self.expectation(description: "rpcVoucher callback occurs") + + var v = Data(count: 0) + var vS = Data(count: 0) + + clientStateMachine.rpcVoucher(self.cuttlefishContextForAcceptor, peerID: p, permanentInfo: pI, permanentInfoSig: pIS, stableInfo: sI, stableInfoSig: sIS) { voucher, voucherSig, error in + XCTAssertNotNil(v, "Prepare should have returned a voucher") + XCTAssertNotNil(vS, "Prepare should have returned a voucherSig") + XCTAssertNil(error, "error should be nil") + + v = voucher + vS = voucherSig + + rpcVoucherCallback.fulfill() + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + } + + self.wait(for: [rpcVoucherCallback], timeout: 10) + + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + /* calling Join */ + let rpcJoinCallbackOccurs = self.expectation(description: "rpcJoin callback occurs") + + self.cuttlefishContext.rpcJoin(v, vouchSig: vS, preapprovedKeys: nil) { error in + XCTAssertNil(error, "error should be nil") + rpcJoinCallbackOccurs.fulfill() + } + + self.wait(for: [rpcJoinCallbackOccurs], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + self.assertTLKSharesInCloudKit(receiver: self.cuttlefishContextForAcceptor, sender: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testJoinRetry() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let rpcEpochCallbacks = self.expectation(description: "rpcEpoch callback occurs") + clientStateMachine.rpcEpoch(self.cuttlefishContextForAcceptor) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertTrue(epoch == 1, "epoch should be 1") + rpcEpochCallbacks.fulfill() + } + self.wait(for: [rpcEpochCallbacks], timeout: 10) + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* now initiator's turn*/ + /* calling prepare identity*/ + let rpcInitiatorPrepareCallback = self.expectation(description: "rpcPrepare callback occurs") + + var p = String() + var pI = Data() + var pIS = Data() + var sI = Data() + var sIS = Data() + + initiator1Context.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig, epoch: 1) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error calling 'prepare'") + XCTAssertNotNil(peerID, "Prepare should have returned a peerID") + XCTAssertNotNil(permanentInfo, "Prepare should have returned a permanentInfo") + XCTAssertNotNil(permanentInfoSig, "Prepare should have returned a permanentInfoSig") + XCTAssertNotNil(stableInfo, "Prepare should have returned a stableInfo") + XCTAssertNotNil(stableInfoSig, "Prepare should have returned a stableInfoSig") + + p = peerID! + pI = permanentInfo! + pIS = permanentInfoSig! + sI = stableInfo! + sIS = stableInfoSig! + + rpcInitiatorPrepareCallback.fulfill() + } + + self.wait(for: [rpcInitiatorPrepareCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateInitiatorAwaitingVoucher, within: 10 * NSEC_PER_SEC) + + /* calling voucher */ + let rpcVoucherCallback = self.expectation(description: "rpcVoucher callback occurs") + + var v = Data(count: 0) + var vS = Data(count: 0) + + clientStateMachine.rpcVoucher(self.cuttlefishContextForAcceptor, peerID: p, permanentInfo: pI, permanentInfoSig: pIS, stableInfo: sI, stableInfoSig: sIS) { voucher, voucherSig, error in + XCTAssertNotNil(v, "Prepare should have returned a voucher") + XCTAssertNotNil(vS, "Prepare should have returned a voucherSig") + XCTAssertNil(error, "error should be nil") + + v = voucher + vS = voucherSig + + rpcVoucherCallback.fulfill() + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + } + + self.wait(for: [rpcVoucherCallback], timeout: 10) + + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + /* calling Join */ + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.transactionalFailure.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + + let rpcJoinCallbackOccurs = self.expectation(description: "rpcJoin callback occurs") + + self.cuttlefishContext.rpcJoin(v, vouchSig: vS, preapprovedKeys: nil) { error in + XCTAssertNil(error, "error should be nil") + rpcJoinCallbackOccurs.fulfill() + } + + self.wait(for: [rpcJoinCallbackOccurs], timeout: 64) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.verifyDatabaseMocks() + + self.assertSelfTLKSharesInCloudKit(context: self.cuttlefishContext) + self.assertTLKSharesInCloudKit(receiver: self.cuttlefishContextForAcceptor, sender: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + } + + func testJoinRetryFail() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let rpcEpochCallbacks = self.expectation(description: "rpcEpoch callback occurs") + clientStateMachine.rpcEpoch(self.cuttlefishContextForAcceptor) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertTrue(epoch == 1, "epoch should be 1") + rpcEpochCallbacks.fulfill() + } + self.wait(for: [rpcEpochCallbacks], timeout: 10) + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* now initiator's turn*/ + /* calling prepare identity*/ + let rpcInitiatorPrepareCallback = self.expectation(description: "rpcPrepare callback occurs") + + var p = String() + var pI = Data() + var pIS = Data() + var sI = Data() + var sIS = Data() + + initiator1Context.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig, epoch: 1) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error calling 'prepare'") + XCTAssertNotNil(peerID, "Prepare should have returned a peerID") + XCTAssertNotNil(permanentInfo, "Prepare should have returned a permanentInfo") + XCTAssertNotNil(permanentInfoSig, "Prepare should have returned a permanentInfoSig") + XCTAssertNotNil(stableInfo, "Prepare should have returned a stableInfo") + XCTAssertNotNil(stableInfoSig, "Prepare should have returned a stableInfoSig") + + p = peerID! + pI = permanentInfo! + pIS = permanentInfoSig! + sI = stableInfo! + sIS = stableInfoSig! + + rpcInitiatorPrepareCallback.fulfill() + } + + self.wait(for: [rpcInitiatorPrepareCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateInitiatorAwaitingVoucher, within: 10 * NSEC_PER_SEC) + + /* calling voucher */ + let rpcVoucherCallback = self.expectation(description: "rpcVoucher callback occurs") + + var v = Data(count: 0) + var vS = Data(count: 0) + + clientStateMachine.rpcVoucher(self.cuttlefishContextForAcceptor, peerID: p, permanentInfo: pI, permanentInfoSig: pIS, stableInfo: sI, stableInfoSig: sIS) { voucher, voucherSig, error in + XCTAssertNotNil(v, "Prepare should have returned a voucher") + XCTAssertNotNil(vS, "Prepare should have returned a voucherSig") + XCTAssertNil(error, "error should be nil") + + v = voucher + vS = voucherSig + + rpcVoucherCallback.fulfill() + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + } + + self.wait(for: [rpcVoucherCallback], timeout: 10) + + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + /* calling Join */ + let cuttlefishError = NSError(domain: CuttlefishErrorDomain, code: CuttlefishErrorCode.transactionalFailure.rawValue, userInfo: nil) + let ckError = NSError(domain: CKInternalErrorDomain, code: CKInternalErrorCode.errorInternalPluginError.rawValue, userInfo: [NSUnderlyingErrorKey: cuttlefishError]) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + self.fakeCuttlefishServer.nextJoinErrors.append(ckError) + + let rpcJoinCallbackOccurs = self.expectation(description: "rpcJoin callback occurs") + + self.cuttlefishContext.rpcJoin(v, vouchSig: vS, preapprovedKeys: nil) { error in + XCTAssertNotNil(error, "error should be set") + rpcJoinCallbackOccurs.fulfill() + } + self.wait(for: [rpcJoinCallbackOccurs], timeout: 64) + } + + func testJoinWithCKKSConflict() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + + self.getAcceptorInCircle() + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + self.silentFetchesAllowed = false + self.expectCKFetchAndRun(beforeFinished: { + self.putFakeKeyHierarchy(inCloudKit: self.manateeZoneID) + self.putFakeDeviceStatus(inCloudKit: self.manateeZoneID) + self.silentFetchesAllowed = true + }) + + clientStateMachine.startOctagonStateMachine() + self.cuttlefishContext.startOctagonStateMachine() + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let rpcEpochCallbacks = self.expectation(description: "rpcEpoch callback occurs") + clientStateMachine.rpcEpoch(self.cuttlefishContextForAcceptor) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertTrue(epoch == 1, "epoch should be 1") + rpcEpochCallbacks.fulfill() + } + self.wait(for: [rpcEpochCallbacks], timeout: 10) + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* now initiator's turn*/ + /* calling prepare identity*/ + let rpcInitiatorPrepareCallback = self.expectation(description: "rpcPrepare callback occurs") + + var p = String() + var pI = Data() + var pIS = Data() + var sI = Data() + var sIS = Data() + + self.cuttlefishContext.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig, epoch: 1) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error calling 'prepare'") + XCTAssertNotNil(peerID, "Prepare should have returned a peerID") + XCTAssertNotNil(permanentInfo, "Prepare should have returned a permanentInfo") + XCTAssertNotNil(permanentInfoSig, "Prepare should have returned a permanentInfoSig") + XCTAssertNotNil(stableInfo, "Prepare should have returned a stableInfo") + XCTAssertNotNil(stableInfoSig, "Prepare should have returned a stableInfoSig") + + p = peerID! + pI = permanentInfo! + pIS = permanentInfoSig! + sI = stableInfo! + sIS = stableInfoSig! + + rpcInitiatorPrepareCallback.fulfill() + } + + self.wait(for: [rpcInitiatorPrepareCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateInitiatorAwaitingVoucher, within: 10 * NSEC_PER_SEC) + + /* calling voucher */ + let rpcVoucherCallback = self.expectation(description: "rpcVoucher callback occurs") + + var v = Data(count: 0) + var vS = Data(count: 0) + + clientStateMachine.rpcVoucher(self.cuttlefishContextForAcceptor, peerID: p, permanentInfo: pI, permanentInfoSig: pIS, stableInfo: sI, stableInfoSig: sIS) { voucher, voucherSig, error in + XCTAssertNotNil(v, "Prepare should have returned a voucher") + XCTAssertNotNil(vS, "Prepare should have returned a voucherSig") + XCTAssertNil(error, "error should be nil") + + v = voucher + vS = voucherSig + + rpcVoucherCallback.fulfill() + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + } + + self.wait(for: [rpcVoucherCallback], timeout: 10) + + self.assertConsidersSelfUntrusted(context: self.cuttlefishContext) + + /* calling Join */ + let rpcJoinCallbackOccurs = self.expectation(description: "rpcJoin callback occurs") + + self.cuttlefishContext.rpcJoin(v, vouchSig: vS, preapprovedKeys: nil) { error in + XCTAssertNil(error, "error should be nil") + rpcJoinCallbackOccurs.fulfill() + } + + self.wait(for: [rpcJoinCallbackOccurs], timeout: 10) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + + self.assertAllCKKSViews(enter: SecCKKSZoneKeyStateWaitForTLK, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } + + func testNextJoiningMessageInterface() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + self.getAcceptorInCircle() + + let rpcEpochCallbackOccurs = self.expectation(description: "rpcEpoch callback occurs") + + self.manager.rpcEpoch(with: self.acceptorPairingConfig) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertEqual(epoch, 1, "epoch should be nil") + rpcEpochCallbackOccurs.fulfill() + } + self.wait(for: [rpcEpochCallbackOccurs], timeout: 10) + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + initiator1Context.startOctagonStateMachine() + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-1") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let rpcSecondInitiatorJoiningMessageCallBack = self.expectation(description: "creating prepare message callback") + var peerID = "" + var permanentInfo = Data(count: 0) + var permanentInfoSig = Data(count: 0) + var stableInfo = Data(count: 0) + var stableInfoSig = Data(count: 0) + + self.manager.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig) { pID, pI, pISig, sI, sISig, error in + XCTAssertNotNil(pID, "peer ID should not be nil") + XCTAssertNotNil(pI, "permanentInfo should not be nil") + XCTAssertNotNil(pISig, "permanentInfo Signature should not be nil") + XCTAssertNotNil(sI, "stable info should not be nil") + XCTAssertNotNil(sISig, "stable info signature should not be nil") + + peerID = pID! + permanentInfo = pI! + permanentInfoSig = pISig! + stableInfo = sI! + stableInfoSig = sISig! + XCTAssertNil(error, "error should be nil") + rpcSecondInitiatorJoiningMessageCallBack.fulfill() + } + self.wait(for: [rpcSecondInitiatorJoiningMessageCallBack], timeout: 10) + + var voucher = Data(count: 0) + var voucherSig = Data(count: 0) + + let voucherCallback = self.expectation(description: "creating voucher message callback") + self.manager.rpcVoucher(with: self.acceptorPairingConfig, peerID: peerID, permanentInfo: permanentInfo, permanentInfoSig: permanentInfoSig, stableInfo: stableInfo, stableInfoSig: stableInfoSig ) { v, vS, error in + XCTAssertNil(error, "error should be nil") + voucher = v + voucherSig = vS + voucherCallback.fulfill() + } + self.wait(for: [voucherCallback], timeout: 10) + + let rpcJoinCallback = self.expectation(description: "joining octagon callback") + self.manager.rpcJoin(with: self.initiatorPairingConfig, vouchData: voucher, vouchSig: voucherSig, preapprovedKeys: nil) { error in + XCTAssertNil(error, "error should be nil") + rpcJoinCallback.fulfill() + } + self.wait(for: [rpcJoinCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertEnters(context: self.cuttlefishContextForAcceptor, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: self.cuttlefishContext) + self.assertConsidersSelfTrusted(context: self.cuttlefishContextForAcceptor) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + self.verifyDatabaseMocks() + } + + func testEpochFetching() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + self.getAcceptorInCircle() + + let rpcEpochCallbacks = self.expectation(description: "rpcEpoch callback occurs") + clientStateMachine.startOctagonStateMachine() + clientStateMachine.rpcEpoch(self.cuttlefishContextForAcceptor) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertTrue(epoch == 1, "epoch should be 1") + rpcEpochCallbacks.fulfill() + } + + self.wait(for: [rpcEpochCallbacks], timeout: 10) + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorAwaitingIdentity] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorAwaitingIdentity'") + } + + func testVoucherCreation() { + self.startCKAccountStatusMock() + + /*Setup acceptor first*/ + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + self.getAcceptorInCircle() + + let rpcEpochCallbacks = self.expectation(description: "rpcEpoch callback occurs") + clientStateMachine.startOctagonStateMachine() + clientStateMachine.rpcEpoch(self.cuttlefishContextForAcceptor) { epoch, error in + XCTAssertNil(error, "error should be nil") + XCTAssertTrue(epoch == 1, "epoch should be 1") + rpcEpochCallbacks.fulfill() + } + + self.wait(for: [rpcEpochCallbacks], timeout: 10) + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorAwaitingIdentity] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorAwaitingIdentity'") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateMachineNotStarted, within: 10 * NSEC_PER_SEC) + + /* now initiator's turn*/ + self.manager.startOctagonStateMachine(self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { _ in + } + + /* calling prepare identity*/ + let rpcInitiatorPrepareCallback = self.expectation(description: "rpcPrepare callback occurs") + + var p = String() + var pI = Data() + var pIS = Data() + var sI = Data() + var sIS = Data() + + self.cuttlefishContext.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig, epoch: 1) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNil(error, "Should be no error calling 'prepare'") + XCTAssertNotNil(peerID, "Prepare should have returned a peerID") + XCTAssertNotNil(permanentInfo, "Prepare should have returned a permanentInfo") + XCTAssertNotNil(permanentInfoSig, "Prepare should have returned a permanentInfoSig") + XCTAssertNotNil(stableInfo, "Prepare should have returned a stableInfo") + XCTAssertNotNil(stableInfoSig, "Prepare should have returned a stableInfoSig") + + p = peerID! + pI = permanentInfo! + pIS = permanentInfoSig! + sI = stableInfo! + sIS = stableInfoSig! + + rpcInitiatorPrepareCallback.fulfill() + } + + self.wait(for: [rpcInitiatorPrepareCallback], timeout: 10) + + self.assertEnters(context: self.cuttlefishContext, state: OctagonStateInitiatorAwaitingVoucher, within: 10 * NSEC_PER_SEC) + + /* calling voucher */ + let rpcVoucherCallback = self.expectation(description: "rpcVoucher callback occurs") + + var v = Data(count: 0) + var vS = Data(count: 0) + + clientStateMachine.rpcVoucher(self.cuttlefishContextForAcceptor, peerID: p, permanentInfo: pI, permanentInfoSig: pIS, stableInfo: sI, stableInfoSig: sIS) { voucher, voucherSig, error in + XCTAssertNotNil(v, "Prepare should have returned a voucher") + XCTAssertNotNil(vS, "Prepare should have returned a voucherSIg") + XCTAssertNil(error, "error should be nil") + + v = voucher + vS = voucherSig + + rpcVoucherCallback.fulfill() + } + + self.wait(for: [rpcVoucherCallback], timeout: 10) + XCTAssertEqual(0, (clientStateMachine.stateConditions[OctagonStateAcceptorDone] as! CKKSCondition).wait(10 * NSEC_PER_SEC), "State machine should enter 'OctagonStateAcceptorDone'") + } + + func testPrepareTimeoutIfStateMachineUnstarted() { + self.startCKAccountStatusMock() + + let rpcCallbackOccurs = self.expectation(description: "rpcPrepare callback occurs") + self.initiatorPairingConfig.timeout = Int64(2*NSEC_PER_SEC) + + self.cuttlefishContext.rpcPrepareIdentityAsApplicant(with: self.initiatorPairingConfig, epoch: 1) { peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + XCTAssertNotNil(error, "Should be an error calling 'prepare'") + XCTAssertEqual(error?._domain, CKKSResultErrorDomain, "Error domain should be CKKSResultErrorDomain") + XCTAssertEqual(error?._code ?? -1, CKKSResultTimedOut, "Error result should be CKKSResultTimedOut") + + XCTAssertNil(peerID, "Prepare should not have returned a peerID") + XCTAssertNil(permanentInfo, "Prepare should not have returned a permanentInfo") + XCTAssertNil(permanentInfoSig, "Prepare should not have returned a permanentInfoSig") + XCTAssertNil(stableInfo, "Prepare should not have returned a stableInfo") + XCTAssertNil(stableInfoSig, "Prepare should not have returned a stableInfoSig") + + rpcCallbackOccurs.fulfill() + } + + self.wait(for: [rpcCallbackOccurs], timeout: 10) + } + + func testProximitySetupUsingCliqueOctagonAndSOS() { + self.startCKAccountStatusMock() + + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = packet! + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + clientStateMachine.notifyContainerChange() + + // Initiator should join! + self.assertEnters(context: initiator1Context, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: initiator1Context) + self.verifyDatabaseMocks() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + + self.assertSOSSuccess() + } + + func testProximitySetupUsingCliqueOctagonOnly() { + OctagonSetPlatformSupportsSOS(false) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = (packet) + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNil(initiatorThirdPacket, "acceptor second packet should be nil") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + clientStateMachine.notifyContainerChange() + + // Initiator should join! + self.assertEnters(context: initiator1Context, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: initiator1Context) + self.verifyDatabaseMocks() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + } + + func testProximitySetupUsingCliqueSOSOnly() { + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(false) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = packet! + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + self.assertSOSSuccess() + } + + func testProximitySetupOctagonAndSOSWithSOSFailure() { + //ensure Octagon protocol continues even if SOS fails in some way. + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + initiator.setSOSMessageFailForTesting(true) + acceptor.setSOSMessageFailForTesting(true) + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = packet! + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + assertAllCKKSViews(enter: SecCKKSZoneKeyStateReady, within: 10 * NSEC_PER_SEC) + + clientStateMachine.notifyContainerChange() + + // Initiator should join! + self.assertEnters(context: initiator1Context, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: initiator1Context) + self.verifyDatabaseMocks() + + let initiatorDumpCallback = self.expectation(description: "initiatorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.cuttlefishContext.contextID) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + + initiatorDumpCallback.fulfill() + } + self.wait(for: [initiatorDumpCallback], timeout: 10) + + let acceptorDumpCallback = self.expectation(description: "acceptorDumpCallback callback occurs") + self.tphClient.dump(withContainer: self.cuttlefishContext.containerName, context: self.contextForAcceptor) { + dump, _ in + XCTAssertNotNil(dump, "dump should not be nil") + let egoSelf = dump!["self"] as? Dictionary + XCTAssertNotNil(egoSelf, "egoSelf should not be nil") + let dynamicInfo = egoSelf!["dynamicInfo"] as? Dictionary + XCTAssertNotNil(dynamicInfo, "dynamicInfo should not be nil") + let included = dynamicInfo!["included"] as? Array + XCTAssertNotNil(included, "included should not be nil") + XCTAssertEqual(included!.count, 2, "should be 2 peer ids") + acceptorDumpCallback.fulfill() + } + self.wait(for: [acceptorDumpCallback], timeout: 10) + + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 2, "should be 2 bottles") + } + + func testProximitySetupOctagonAndSOSWithOcatagonInitiatorMessage1Failure() { + //ensure Octagon protocol halts if enabled and encounters a failure + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + initiator.setOctagonMessageFailForTesting(true) + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertNil(error, "should be no error") + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + } + + func testProximitySetupOctagonAndSOSWithOctagonAcceptorMessage1Failure() { + //ensure Octagon protocol continues even if SOS fails in some way. + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + acceptor.setOctagonMessageFailForTesting(true) + + /* ACCEPTOR FIRST RTT EPOCH*/ + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertNil(error, "should be no error") + XCTAssertTrue(complete, "should be True") + XCTAssertNil(packet, "packet should be nil") + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + } + func testProximitySetupOctagonAndSOSWithOctagonInitiatorMessage2Failure() { + + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + //set up initiator's message 2 to fail + initiator.setOctagonMessageFailForTesting(true) + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertNil(error, "should be no error") + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should not be nil") + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + } + + func testProximitySetupOctagonAndSOSWithOctagonAcceptorMessage2Failure() { + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + /* ACCEPTOR SECOND RTT */ + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.setOctagonMessageFailForTesting(true) + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertNil(error, "should be no error") + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + } + + func testProximitySetupOctagonAndSOSWithOctagonInitiatorMessage3Failure() { + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + self.startCKAccountStatusMock() + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.setOctagonMessageFailForTesting(true) + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertNil(error, "should be no error") + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + } + + func circleAndSOS() throws { + let peerInfoAcceptor: SOSPeerInfoRef = SOSFullPeerInfoGetPeerInfo(self.fcAcceptor.fullPeerInfo) + let encryptionKeyAcceptor = _SFECKeyPair.init(secKey: self.fcAcceptor.octagonEncryptionKey) + let signingKeyAcceptor = _SFECKeyPair.init(secKey: self.fcAcceptor.octagonSigningKey) + let peerIDAcceptor: NSString = (SOSPeerInfoGetPeerID(peerInfoAcceptor) .takeUnretainedValue() as NSString) + let AcceptorSOSPeer = CKKSSOSSelfPeer(sosPeerID: peerIDAcceptor as String, + encryptionKey: encryptionKeyAcceptor, + signingKey: signingKeyAcceptor, + viewList: self.managedViewList()) + + self.mockSOSAdapter.trustedPeers.add(AcceptorSOSPeer) + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + + let acceptor = self.manager.context(forContainerName: OTCKContainerName, + contextID: self.contextForAcceptor, + sosAdapter: self.mockSOSAdapter, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + acceptor.startOctagonStateMachine() + + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + acceptor.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.assertEnters(context: acceptor, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.assertConsidersSelfTrusted(context: acceptor) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 1, "should be 1 bottles") + } + /* TODO: FIX ME!!!! + func testOctagonUpgradeAfterReceivingSOSCCCircleChangedNotification() throws { + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(false) + OctagonAuthoritativeTrustSetIsEnabled(true) + OctagonSetSOSUpgrade(true) + self.startCKAccountStatusMock() + + self.manager.initializeOctagon() + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + + try self.circleAndSOS() + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = packet! + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + /* ACCEPTOR THIRD RTT */ + var acceptorThirdPacket = Data() + let ThirdAcceptorCallback = self.expectation(description: "ThirdAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorThirdPacket = packet! + ThirdAcceptorCallback.fulfill() + } + self.wait(for: [ThirdAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorThirdPacket, "acceptor third packet should not be nil") + + /* INITIATOR Fourth STEP*/ + let fourthInitiatorCallback = self.expectation(description: "fourthInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorThirdPacket) { complete, packet, error in + XCTAssertTrue(complete, "should be true") + XCTAssertNil(packet, "packet should be nil") + XCTAssertNil(error, "error should be nil") + fourthInitiatorCallback.fulfill() + } + self.wait(for: [fourthInitiatorCallback], timeout: 10) + + let peerInfo: SOSPeerInfoRef = SOSFullPeerInfoGetPeerInfo(self.fcInitiator.fullPeerInfo) + let encryptionKey = _SFECKeyPair.init(secKey: self.fcInitiator.octagonEncryptionKey) + let signingKey = _SFECKeyPair.init(secKey: self.fcInitiator.octagonSigningKey) + let peerID: NSString = (SOSPeerInfoGetPeerID(peerInfo) .takeUnretainedValue() as NSString) + let initiatorSOSPeer = CKKSSOSSelfPeer(sosPeerID: peerID as String, + encryptionKey: encryptionKey, + signingKey: signingKey) + self.mockSOSAdapter.trustedPeers.add(initiatorSOSPeer) + + let mockSOS = CKKSMockSOSPresentAdapter(selfPeer: initiatorSOSPeer, trustedPeers: self.mockSOSAdapter.allPeers(), essential: false) + mockSOS.circleStatus = SOSCCStatus(kSOSCCInCircle) + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, + contextID: OTDefaultContext, + sosAdapter: mockSOS, + authKitAdapter: self.mockAuthKit2, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + self.manager.moveToCheckTrustedState(forContainer: OTCKContainerName, context: OTDefaultContext) + + //test circle changed notification fired + self.assertEnters(context: initiatorContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.verifyDatabaseMocks() + } +*/ + func testProximitySetupUsingCliqueAcceptorResolvesVersionToSOSOnly() { + self.startCKAccountStatusMock() + + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + + let newSOSPeer = createSOSPeer(peerID: "sos-peer-id") + self.mockSOSAdapter.selfPeer = newSOSPeer + self.mockSOSAdapter.circleStatus = SOSCCStatus(kSOSCCInCircle) + self.mockSOSAdapter.trustedPeers.add(newSOSPeer) + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + acceptor.setSessionSupportsOctagonForTesting(false) + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + + initiator.setSessionSupportsOctagonForTesting(false) + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = packet! + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") +/* + need to fix attempting sos upgrade in the tests when pairing/piggybacking and then kicking off an upgrade + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.assertEnters(context: initiatorContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: initiatorContext) + */ + } + + func testProximitySetupUsingCliqueInitiatorResolvesVersionToSOSOnly() { + self.startCKAccountStatusMock() + + OctagonSetPlatformSupportsSOS(true) + OctagonSetIsEnabled(true) + + self.getAcceptorInCircle() + + let initiator1Context = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + let clientStateMachine = self.manager.clientStateMachine(forContainerName: OTCKContainerName, contextID: self.contextForAcceptor, clientName: self.initiatorName) + + clientStateMachine.startOctagonStateMachine() + initiator1Context.startOctagonStateMachine() + + self.assertEnters(context: initiator1Context, state: OctagonStateUntrusted, within: 10 * NSEC_PER_SEC) + + let (acceptor, initiator) = self.setupPairingEndpoints(withPairNumber: "1", initiatorContextID: OTDefaultContext, acceptorContextID: self.contextForAcceptor, initiatorUniqueID: self.initiatorName, acceptorUniqueID: "acceptor-2") + + initiator.setSessionSupportsOctagonForTesting(false) + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + let signInCallback = self.expectation(description: "trigger sign in") + self.otControl.sign(in: "348576349857", container: OTCKContainerName, context: OTDefaultContext) { error in + XCTAssertNil(error, "error should be nil") + signInCallback.fulfill() + } + self.wait(for: [signInCallback], timeout: 10) + + /* INITIATOR FIRST RTT JOINING MESSAGE*/ + var initiatorFirstPacket = Data() + let firstInitiatorCallback = self.expectation(description: "firstInitiatorCallback callback occurs") + + initiator.exchangePacket(nil) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorFirstPacket = packet! + firstInitiatorCallback.fulfill() + } + + self.wait(for: [firstInitiatorCallback], timeout: 10) + + /* ACCEPTOR FIRST RTT EPOCH*/ + var acceptorFirstPacket = Data() + let firstAcceptorCallback = self.expectation(description: "firstAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorFirstPacket = packet! + firstAcceptorCallback.fulfill() + } + self.wait(for: [firstAcceptorCallback], timeout: 10) + + /* INITIATOR SECOND RTT PREPARE*/ + var initiatorSecondPacket = Data() + let secondInitiatorCallback = self.expectation(description: "secondInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorFirstPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorSecondPacket = packet! + secondInitiatorCallback.fulfill() + } + + self.wait(for: [secondInitiatorCallback], timeout: 10) + + /* ACCEPTOR SECOND RTT */ + var acceptorSecondPacket = Data() + let SecondAcceptorCallback = self.expectation(description: "SecondAcceptorCallback callback occurs") + + acceptor.exchangePacket(initiatorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + acceptorSecondPacket = packet! + SecondAcceptorCallback.fulfill() + } + self.wait(for: [SecondAcceptorCallback], timeout: 10) + XCTAssertNotNil(acceptorSecondPacket, "acceptor second packet should not be nil") + + /* INITIATOR THIRD STEP*/ + var initiatorThirdPacket: Data? + let thirdInitiatorCallback = self.expectation(description: "thirdInitiatorCallback callback occurs") + + initiator.exchangePacket(acceptorSecondPacket) { complete, packet, error in + XCTAssertFalse(complete, "should be false") + XCTAssertNotNil(packet, "packet should not be nil") + XCTAssertNil(error, "error should be nil") + initiatorThirdPacket = packet! + thirdInitiatorCallback.fulfill() + } + self.wait(for: [thirdInitiatorCallback], timeout: 10) + XCTAssertNotNil(initiatorThirdPacket, "acceptor second packet should not be nil") + + /* + need to fix attempting sos upgrade in the tests when pairing/piggybacking and then kicking off an upgrade + let initiatorContext = self.manager.context(forContainerName: OTCKContainerName, contextID: OTDefaultContext) + + self.assertEnters(context: initiatorContext, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + self.assertConsidersSelfTrusted(context: initiatorContext) + */ + } + +} + +#endif diff --git a/keychain/ot/tests/octagon/Pairing/OctagonPairingTests.swift b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests.swift new file mode 100644 index 00000000..deb56286 --- /dev/null +++ b/keychain/ot/tests/octagon/Pairing/OctagonPairingTests.swift @@ -0,0 +1,334 @@ +#if OCTAGON + +func GenerateFullECKey(keySize: Int) -> (SecKey) { + + let keyPair = _SFECKeyPair.init(randomKeyPairWith: _SFECKeySpecifier.init(curve: SFEllipticCurve.nistp384))! + + var keyAttributes: Dictionary = [:] + keyAttributes[kSecAttrKeyClass as String] = kSecAttrKeyClassPrivate as String + keyAttributes[kSecAttrKeyType as String] = kSecAttrKeyTypeEC as String + + let key = SecKeyCreateWithData(keyPair.keyData as CFData, keyAttributes as CFDictionary, nil)! + + return key +} + +class KCJoiningRequestTestDelegate: NSObject, KCJoiningRequestSecretDelegate, KCJoiningRequestCircleDelegate { + var sharedSecret: String = "" + var accountCode: String = "" + var circleJoinData = Data() + var peerInfo: SOSPeerInfoRef? + var incorrectSecret: String = "" + var incorrectTries: Int = 0 + + class func requestDelegate(withSecret secret: String) -> KCJoiningRequestTestDelegate { + return self.requestDelegateWithSecret(secret: secret, wrongSecret: "", retries: 0) + } + class func requestDelegateWithSecret(secret: String, wrongSecret: String, retries: Int) -> KCJoiningRequestTestDelegate { + return KCJoiningRequestTestDelegate(withSecret: secret, incorrectSecret: wrongSecret, retries: retries) + } + init(withSecret secret: String, incorrectSecret: String, retries: Int) { + let signingKey = GenerateFullECKey(keySize: 256) + let octagonSigningKey = GenerateFullECKey(keySize: 384) + let octagonEncryptionKey = GenerateFullECKey(keySize: 384) + + XCTAssertNotNil(octagonSigningKey, "signing key should not be nil") + XCTAssertNotNil(octagonEncryptionKey, "encryption key should not be nil") + + var gestalt: Dictionary = [:] + gestalt[kPIUserDefinedDeviceNameKey as String] = "Fakey" + + let newPeerInfo = SOSPeerInfoCreate(nil, gestalt as CFDictionary, nil, signingKey, octagonSigningKey, octagonEncryptionKey, nil) + + self.peerInfo = newPeerInfo + self.sharedSecret = secret + self.incorrectSecret = incorrectSecret + self.incorrectTries = retries + } + + func nextSecret() -> String { + if (self.incorrectTries > 0) { + self.incorrectTries -= 1 + return self.incorrectSecret + } + return self.sharedSecret + } + + func secret() -> String { + return self.nextSecret() + } + + func verificationFailed(_ codeChanged: Bool) -> String { + return self.nextSecret() + } + + func processAccountCode(_ accountCode: String, error: NSErrorPointer) -> Bool { + self.accountCode = accountCode + return true + } + + func copyPeerInfoError(_ error: NSErrorPointer) -> SOSPeerInfoRef { + return self.peerInfo! + } + + func processCircleJoin(_ circleJoinData: Data, version: PiggyBackProtocolVersion, error: NSErrorPointer) -> Bool { + self.circleJoinData = circleJoinData + return true + } +} + +class KCJoiningAcceptTestDelegate: NSObject, KCJoiningAcceptSecretDelegate, KCJoiningAcceptCircleDelegate { + var secrets: Array = [] + var currentSecret: Int = 0 + var retriesLeft: Int = 0 + var retriesPerSecret: Int = 0 + var codeToUse: String = "" + var circleJoinData = Data() + var peerInfo: SOSPeerInfoRef? + + class func acceptDelegateWithSecrets(secrets: Array, retries: Int, code: String) -> KCJoiningAcceptTestDelegate { + return KCJoiningAcceptTestDelegate(withSecrets: secrets, retries: retries, code: code) + } + + class func acceptDelegateWithSecret(secret: String, code: String) -> KCJoiningAcceptTestDelegate { + return KCJoiningAcceptTestDelegate.initWithSecret(secret: secret, code: code) + } + + class func initWithSecret(secret: String, code: String) -> KCJoiningAcceptTestDelegate { + var secretArray: Array = Array() + secretArray.append(secret) + return KCJoiningAcceptTestDelegate(withSecrets: secretArray, retries: 3, code: code) + } + + init(withSecrets secrets: Array, retries: Int, code: String) { + + self.secrets = secrets + self.currentSecret = 0 + self.retriesPerSecret = retries + self.retriesLeft = self.retriesPerSecret + + self.codeToUse = code + + let joinDataBuffer = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] + do { + self.circleJoinData = try NSKeyedArchiver.archivedData(withRootObject: joinDataBuffer, requiringSecureCoding: false) + } catch { + XCTFail("error loading account state: \(error)") + } + } + + func advanceSecret() -> KCRetryOrNot { + if (self.retriesLeft == 0) { + self.currentSecret += 1 + if (self.currentSecret >= self.secrets.count) { + self.currentSecret = self.secrets.count - 1 + } + self.retriesLeft = self.retriesPerSecret + return kKCRetryWithNewChallenge + } else { + self.retriesLeft -= 1 + return kKCRetryWithSameChallenge + } + } + + func secret() -> String { + return self.secrets[self.currentSecret] + } + func accountCode() -> String { + return self.codeToUse + } + + func circleGetInitialSyncViews(error: Error) -> Data { + return Data() + } + + func verificationFailed(_ error: NSErrorPointer) -> KCRetryOrNot { + return self.advanceSecret() + } + + func circleJoinData(for peer: SOSPeerInfoRef, error: NSErrorPointer) -> Data { + let joinDataBuffer = [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ] + self.peerInfo = peer + do { + return try NSKeyedArchiver.archivedData(withRootObject: joinDataBuffer, requiringSecureCoding: false) + } catch { + XCTFail("error loading account state: \(error)") + return Data() + } + } + + func circleGetInitialSyncViews(_ error: NSErrorPointer) -> Data { + return Data() + } +} + +@objcMembers class OctagonPairingTests: OctagonTestsBase { + + var sosAdapterForAcceptor: CKKSMockSOSPresentAdapter! + var cuttlefishContextForAcceptor: OTCuttlefishContext! + var contextForAcceptor = "defaultContextForAcceptor" + + var initiatorPiggybackingConfig: OTJoiningConfiguration! + var acceptorPiggybackingConfig: OTJoiningConfiguration! + + var initiatorPairingConfig: OTJoiningConfiguration! + var acceptorPairingConfig: OTJoiningConfiguration! + var circle: SOSCircleRef! + var sosControl: NSXPCConnection! + var initiatorName = "uniqueInitiatorID" + var fcInitiator: FCPairingFakeSOSControl! + var fcAcceptor: FCPairingFakeSOSControl! + + override func setUp() { + super.setUp() + + // The acceptor should have its own SOS state + self.sosAdapterForAcceptor = CKKSMockSOSPresentAdapter(selfPeer: self.createSOSPeer(peerID: "sos-acceptor"), + trustedPeers: Set(), + essential: false) + self.sosAdapterForAcceptor.circleStatus = SOSCCStatus(kSOSCCInCircle) + + self.cuttlefishContextForAcceptor = self.manager.context(forContainerName: OTCKContainerName, + contextID: self.contextForAcceptor, + sosAdapter: self.sosAdapterForAcceptor, + authKitAdapter: self.mockAuthKit3, + lockStateTracker: self.lockStateTracker, + accountStateTracker: self.accountStateTracker, + deviceInformationAdapter: OTMockDeviceInfoAdapter(modelID: "iPhone9,1", deviceName: "test-SOS-iphone", serialNumber: "456", osVersion: "iOS (fake version)")) + + self.acceptorPiggybackingConfig = OTJoiningConfiguration(protocolType: OTProtocolPiggybacking, uniqueDeviceID: "acceptor", uniqueClientID: self.initiatorName, containerName: OTCKContainerName, contextID: self.contextForAcceptor, epoch: 1, isInitiator: false) + self.initiatorPiggybackingConfig = OTJoiningConfiguration(protocolType: OTProtocolPiggybacking, uniqueDeviceID: "initiator", uniqueClientID: "acceptor", containerName: OTCKContainerName, contextID: OTDefaultContext, epoch: 1, isInitiator: true) + + self.acceptorPairingConfig = OTJoiningConfiguration(protocolType: OTProtocolPairing, uniqueDeviceID: "acceptor", uniqueClientID: self.initiatorName, containerName: OTCKContainerName, contextID: self.contextForAcceptor, epoch: 1, isInitiator: false) + self.initiatorPairingConfig = OTJoiningConfiguration(protocolType: OTProtocolPairing, uniqueDeviceID: "initiator", uniqueClientID: "acceptor", containerName: OTCKContainerName, contextID: OTDefaultContext, epoch: 1, isInitiator: true) + } + + func getAcceptorInCircle() { + let resetAndEstablishExpectation = self.expectation(description: "resetAndEstablish callback occurs") + self.cuttlefishContextForAcceptor.startOctagonStateMachine() + self.cuttlefishContextForAcceptor.rpcResetAndEstablish() { resetError in + XCTAssertNil(resetError, "Should be no error calling resetAndEstablish") + resetAndEstablishExpectation.fulfill() + } + + self.wait(for: [resetAndEstablishExpectation], timeout: 10) + self.assertEnters(context: self.cuttlefishContextForAcceptor, state: OctagonStateReady, within: 10 * NSEC_PER_SEC) + + self.assertConsidersSelfTrusted(context: self.cuttlefishContextForAcceptor) + XCTAssertEqual(self.fakeCuttlefishServer.state.bottles.count, 1, "should be 1 bottles") + } + + func setupPairingEndpoints(withPairNumber pairNumber: String, initiatorContextID: String, acceptorContextID: String, initiatorUniqueID: String, acceptorUniqueID: String) -> (KCPairingChannel, KCPairingChannel) { + + let (acceptorClique, initiatorClique) = self.setupOTCliquePair(withNumber: pairNumber) + XCTAssertNotNil(acceptorClique, "acceptorClique should not be nil") + XCTAssertNotNil(initiatorClique, "initiatorClique should not be nil") + + let acceptorContext = KCPairingChannelContext() + acceptorContext.model = "AcceptorModel" + acceptorContext.osVersion = "AcceptorOsVersion" + acceptorContext.modelClass = "AcceptorModelClass" + acceptorContext.uniqueDeviceID = acceptorUniqueID + acceptorContext.uniqueClientID = initiatorUniqueID + + let initiatorContext = KCPairingChannelContext() + initiatorContext.model = "InitiatorModel" + initiatorContext.osVersion = "InitiatorOsVersion" + initiatorContext.modelClass = "InitiatorModelClass" + initiatorContext.uniqueDeviceID = initiatorUniqueID + initiatorContext.uniqueDeviceID = initiatorUniqueID + + let acceptor = acceptorClique!.setupPairingChannel(asAcceptor: acceptorContext) + let initiator = initiatorClique!.setupPairingChannel(asInitiator: initiatorContext) + + XCTAssertNotNil(acceptor, "acceptor should not be nil") + XCTAssertNotNil(initiator, "initiator should not be nil") + + acceptor.setControlObject(self.otControl) + initiator.setControlObject(self.otControl) + + let acceptorPairingConfig = OTJoiningConfiguration(protocolType: OTProtocolPairing, uniqueDeviceID: acceptorUniqueID, uniqueClientID: initiatorUniqueID, containerName: OTCKContainerName, contextID: acceptorContextID, epoch: 1, isInitiator: false) + let initiatorPairingConfig = OTJoiningConfiguration(protocolType: OTProtocolPairing, uniqueDeviceID: initiatorUniqueID, uniqueClientID: initiatorUniqueID, containerName: OTCKContainerName, contextID: initiatorContextID, epoch: 1, isInitiator: true) + + acceptor.setConfiguration(acceptorPairingConfig) + initiator.setConfiguration(initiatorPairingConfig) + + self.circle = SOSCircleCreate(kCFAllocatorDefault, "TEST DOMAIN" as CFString, nil) as SOSCircleRef + self.fcInitiator = FCPairingFakeSOSControl(randomAccountKey: true, circle: circle) + self.fcAcceptor = FCPairingFakeSOSControl(randomAccountKey: true, circle: circle) + + let sosConnectionInitiator = FakeNSXPCConnectionSOS(withSOSControl: self.fcInitiator) + let sosConnectionAcceptor = FakeNSXPCConnectionSOS(withSOSControl: self.fcAcceptor) + + acceptor.setXPCConnectionObject(sosConnectionAcceptor) + initiator.setXPCConnectionObject(sosConnectionInitiator) + + return (acceptor, initiator) + } + + func setupOTCliquePair(withNumber count: String) -> (OTClique?, OTClique?) { + + let secondAcceptorData = OTConfigurationContext() + secondAcceptorData.context = "secondAcceptor" + secondAcceptorData.dsid = "a-"+count + secondAcceptorData.altDSID = "alt-a-"+count + + let acceptorAnalytics = SFSignInAnalytics(signInUUID: "uuid", category: "com.apple.cdp", eventName: "signed in") + XCTAssertNotNil(acceptorAnalytics, "acceptorAnalytics should not be nil") + secondAcceptorData.analytics = acceptorAnalytics + + do { + let acceptor = try OTClique(contextData: secondAcceptorData) + XCTAssertNotNil(acceptor, "Clique should not be nil") + acceptor.setPairingDefault(true) + + let secondInitiatorData = OTConfigurationContext() + secondInitiatorData.context = "secondInitiator" + secondInitiatorData.dsid = "i-"+count + secondInitiatorData.altDSID = "alt-i-"+count + + let initiatorAnalytics = SFSignInAnalytics(signInUUID: "uuid", category: "com.apple.cdp", eventName: "signed in") + XCTAssertNotNil(initiatorAnalytics, "initiatorAnalytics should not be nil") + secondInitiatorData.analytics = initiatorAnalytics + let initiator = try OTClique(contextData: secondInitiatorData) + XCTAssertNotNil(initiator, "Clique should not be nil") + initiator.setPairingDefault(true) + + return (acceptor, initiator) + + } catch { + XCTFail("error creating test clique: \(error)") + } + return(nil, nil) + } + + func setupKCJoiningSessionObjects() -> (KCJoiningRequestTestDelegate?, KCJoiningAcceptTestDelegate?, KCJoiningAcceptSession?, KCJoiningRequestSecretSession?) { + + let secret = "123456" + let code = "987654" + let dsid: UInt64 = 0x1234567887654321 + + let requestDelegate = KCJoiningRequestTestDelegate.requestDelegate(withSecret: secret) + let acceptDelegate = KCJoiningAcceptTestDelegate.acceptDelegateWithSecret(secret: secret, code: code) + + do { + let requestSession = try KCJoiningRequestSecretSession(secretDelegate: requestDelegate as KCJoiningRequestSecretDelegate, dsid: dsid, rng: ccDRBGGetRngState()) + + let acceptSession = try KCJoiningAcceptSession(secretDelegate: acceptDelegate as KCJoiningAcceptSecretDelegate, + circleDelegate: acceptDelegate as KCJoiningAcceptCircleDelegate, + dsid: dsid, + rng: ccDRBGGetRngState()) + requestSession.setControlObject(self.otControl) + acceptSession.setControlObject(self.otControl) + requestSession.setConfiguration(self.initiatorPiggybackingConfig) + acceptSession.setConfiguration(self.acceptorPiggybackingConfig) + + return (requestDelegate, acceptDelegate, acceptSession, requestSession) + } catch { + XCTFail("error creating test clique: \(error)") + return (nil, nil, nil, nil) + } + } +} + +#endif diff --git a/keychain/ot/tests/octagon/TestsObjcTranslation.h b/keychain/ot/tests/octagon/TestsObjcTranslation.h new file mode 100644 index 00000000..413ad8e3 --- /dev/null +++ b/keychain/ot/tests/octagon/TestsObjcTranslation.h @@ -0,0 +1,30 @@ + +#ifndef TestsObjcTranslation_h +#define TestsObjcTranslation_h + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +// This file is for translation of C/Obj-C APIs into swift-friendly things + +@interface TestsObjectiveC : NSObject ++ (void)setNewRecoveryKeyWithData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(void* rk, + NSError* _Nullable error))reply; + ++ (void)recoverOctagonUsingData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(NSError* _Nullable error))reply; + ++ (BOOL)saveCoruptDataToKeychainForContainer:(NSString*)containerName + contextID:(NSString*)contextID + error:(NSError**)error; +@end + +NS_ASSUME_NONNULL_END + +#endif /* TestsObjcTranslation_h */ diff --git a/keychain/ot/tests/octagon/TestsObjcTranslation.m b/keychain/ot/tests/octagon/TestsObjcTranslation.m new file mode 100644 index 00000000..51021194 --- /dev/null +++ b/keychain/ot/tests/octagon/TestsObjcTranslation.m @@ -0,0 +1,109 @@ +#import "TestsObjcTranslation.h" +#import +#import + +#import +#import "keychain/ot/OTCuttlefishContext.h" +#import +#import "keychain/categories/NSError+UsefulConstructors.h" + +static const uint8_t signingKey_384[] = { + 0x04, 0xe4, 0x1b, 0x3e, 0x88, 0x81, 0x9f, 0x3b, 0x80, 0xd0, 0x28, 0x1c, + 0xd9, 0x07, 0xa0, 0x8c, 0xa1, 0x89, 0xa8, 0x3b, 0x69, 0x91, 0x17, 0xa7, + 0x1f, 0x00, 0x31, 0x91, 0x82, 0x89, 0x1f, 0x5c, 0x44, 0x2d, 0xd6, 0xa8, + 0x22, 0x1f, 0x22, 0x7d, 0x27, 0x21, 0xf2, 0xc9, 0x75, 0xf2, 0xda, 0x41, + 0x61, 0x55, 0x29, 0x11, 0xf7, 0x71, 0xcf, 0x66, 0x52, 0x2a, 0x27, 0xfe, + 0x77, 0x1e, 0xd4, 0x3d, 0xfb, 0xbc, 0x59, 0xe4, 0xed, 0xa4, 0x79, 0x2a, + 0x9b, 0x73, 0x3e, 0xf4, 0xf4, 0xe3, 0xaf, 0xf2, 0x8d, 0x34, 0x90, 0x92, + 0x47, 0x53, 0xd0, 0x34, 0x1e, 0x49, 0x87, 0xeb, 0x11, 0x89, 0x0f, 0x9c, + 0xa4, 0x99, 0xe8, 0x4f, 0x39, 0xbe, 0x21, 0x94, 0x88, 0xba, 0x4c, 0xa5, + 0x6a, 0x60, 0x1c, 0x2f, 0x77, 0x80, 0xd2, 0x73, 0x14, 0x33, 0x46, 0x5c, + 0xda, 0xee, 0x13, 0x8a, 0x3a, 0xdb, 0x4e, 0x05, 0x4d, 0x0f, 0x6d, 0x96, + 0xcd, 0x28, 0xab, 0x52, 0x4c, 0x12, 0x2b, 0x79, 0x80, 0xfe, 0x9a, 0xe4, + 0xf4 +}; + +@implementation TestsObjectiveC : NSObject ++ (void)setNewRecoveryKeyWithData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(void* rk, + NSError* _Nullable error))reply +{ + [OTClique setNewRecoveryKeyWithData:ctx recoveryKey:recoveryKey reply:^(SecRecoveryKey * _Nullable rk, NSError * _Nullable error) { + reply((__bridge void*)rk, error); + }]; +} + ++ (void)recoverOctagonUsingData:(OTConfigurationContext *)ctx + recoveryKey:(NSString*)recoveryKey + reply:(void(^)(NSError* _Nullable error))reply +{ + [OTClique recoverOctagonUsingData: ctx recoveryKey:recoveryKey reply:reply]; +} + ++ (BOOL)saveCoruptDataToKeychainForContainer:(NSString*)containerName + contextID:(NSString*)contextID + error:(NSError**)error +{ + NSData* signingFromBytes = [[NSData alloc] initWithBytes:signingKey_384 length:sizeof(signingKey_384)]; + + NSMutableDictionary* query = [@{ + (id)kSecClass : (id)kSecClassInternetPassword, + (id)kSecAttrAccessible: (id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccessGroup: @"com.apple.security.octagon", + (id)kSecAttrDescription: [NSString stringWithFormat:@"Octagon Account State (%@,%@)", containerName, contextID], + (id)kSecAttrServer: [NSString stringWithFormat:@"octagon-%@", containerName], + (id)kSecAttrAccount: [NSString stringWithFormat:@"octagon-%@", containerName], // Really should be alt-DSID, no? + (id)kSecAttrPath: [NSString stringWithFormat:@"octagon-%@", contextID], + (id)kSecAttrIsInvisible: @YES, + (id)kSecValueData : signingFromBytes, + (id)kSecAttrSynchronizable : @NO, + (id)kSecAttrSysBound : @(kSecSecAttrSysBoundPreserveDuringRestore), + } mutableCopy]; + + CFTypeRef result = NULL; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, &result); + + NSError* localerror = nil; + + // Did SecItemAdd fall over due to an existing item? + if(status == errSecDuplicateItem) { + // Add every primary key attribute to this find dictionary + NSMutableDictionary* findQuery = [[NSMutableDictionary alloc] init]; + findQuery[(id)kSecClass] = query[(id)kSecClass]; + findQuery[(id)kSecAttrSynchronizable] = query[(id)kSecAttrSynchronizable]; + findQuery[(id)kSecAttrSyncViewHint] = query[(id)kSecAttrSyncViewHint]; + findQuery[(id)kSecAttrAccessGroup] = query[(id)kSecAttrAccessGroup]; + findQuery[(id)kSecAttrAccount] = query[(id)kSecAttrAccount]; + findQuery[(id)kSecAttrServer] = query[(id)kSecAttrServer]; + findQuery[(id)kSecAttrPath] = query[(id)kSecAttrPath]; + findQuery[(id)kSecUseDataProtectionKeychain] = query[(id)kSecUseDataProtectionKeychain]; + + NSMutableDictionary* updateQuery = [query mutableCopy]; + updateQuery[(id)kSecClass] = nil; + + status = SecItemUpdate((__bridge CFDictionaryRef)findQuery, (__bridge CFDictionaryRef)updateQuery); + + if(status) { + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description:[NSString stringWithFormat:@"SecItemUpdate: %d", (int)status]]; + } + } else if(status != 0) { + localerror = [NSError errorWithDomain:NSOSStatusErrorDomain + code:status + description: [NSString stringWithFormat:@"SecItemAdd: %d", (int)status]]; + } + + if(localerror) { + if(error) { + *error = localerror; + } + return false; + } else { + return true; + } +} + +@end diff --git a/keychain/otctl/EscrowRequestCLI.h b/keychain/otctl/EscrowRequestCLI.h new file mode 100644 index 00000000..ae610dcc --- /dev/null +++ b/keychain/otctl/EscrowRequestCLI.h @@ -0,0 +1,19 @@ + +#import +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface EscrowRequestCLI : NSObject +@property SecEscrowRequest* escrowRequest; + +- (instancetype)initWithEscrowRequest:(SecEscrowRequest*)er; + +- (long)trigger; +- (long)status; +- (long)reset; +- (long)storePrerecordsInEscrow; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/otctl/EscrowRequestCLI.m b/keychain/otctl/EscrowRequestCLI.m new file mode 100644 index 00000000..438215f9 --- /dev/null +++ b/keychain/otctl/EscrowRequestCLI.m @@ -0,0 +1,90 @@ + +#import +#import +#import +#import +#import + +#include "utilities/SecCFWrappers.h" +#include "utilities/SecInternalReleasePriv.h" +#import "utilities/debugging.h" + +#import "keychain/otctl/EscrowRequestCLI.h" + +@implementation EscrowRequestCLI + +- (instancetype)initWithEscrowRequest:(SecEscrowRequest*)escrowRequest +{ + if((self = [super init])) { + _escrowRequest = escrowRequest; + } + + return self; +} + +- (long)trigger +{ + NSError* error = nil; + [self.escrowRequest triggerEscrowUpdate:@"cli" error:&error]; + + if(error) { + printf("Errored: %s", [[error description] UTF8String]); + return 1; + + } else { + printf("Complete.\n"); + } + return 0; +} + +- (long)status +{ + NSError* error = nil; + NSDictionary* statuses = [self.escrowRequest fetchStatuses:&error]; + + if(error) { + printf("Errored: %s\n", [[error description] UTF8String]); + return 1; + } + + if(statuses.count == 0) { + printf("No requests are waiting for a passcode.\n"); + return 0; + } + + for(NSString* uuid in statuses.allKeys) { + printf("Request %s: %s\n", [uuid UTF8String], [[statuses[uuid] description] UTF8String]); + } + + return 0; +} + +- (long)reset +{ + NSError* error = nil; + [self.escrowRequest resetAllRequests:&error]; + + if(error) { + printf("Errored: %s\n", [[error description] UTF8String]); + return 1; + } + + printf("Complete.\n"); + return 0; +} + +- (long)storePrerecordsInEscrow +{ + NSError* error = nil; + uint64_t recordsWritten = [self.escrowRequest storePrerecordsInEscrow:&error]; + + if(error) { + printf("Errored: %s\n", [[error description] UTF8String]); + return 1; + } + + printf("Complete: %d records written.\n", (int)recordsWritten); + return 0; +} + +@end diff --git a/keychain/otctl/OTControlCLI.h b/keychain/otctl/OTControlCLI.h new file mode 100644 index 00000000..a62f3bce --- /dev/null +++ b/keychain/otctl/OTControlCLI.h @@ -0,0 +1,44 @@ + +#import + +#import "keychain/ot/OTControl.h" + +NS_ASSUME_NONNULL_BEGIN + + +@interface OTControlCLI : NSObject +@property OTControl* control; + +- (instancetype)initWithOTControl:(OTControl*)control; + +- (long)startOctagonStateMachine:(NSString*)container context:(NSString*)contextID; + +- (long)signIn:(NSString*)altDSID container:(NSString* _Nullable)container context:(NSString*)contextID; + +- (long)signOut:(NSString* _Nullable)container context:(NSString*)contextID; + +- (long)depart:(NSString* _Nullable)container context:(NSString*)contextID; + +- (long)resetOctagon:(NSString*)container context:(NSString*)contextID altDSID:(NSString*)altDSID; + +- (long)status:(NSString* _Nullable)container context:(NSString*)contextID json:(bool)json; + +- (long)recoverUsingBottleID:(NSString*)bottleID + entropy:(NSData*)entropy + altDSID:(NSString*)altDSID + containerName:(NSString*)containerName + context:(NSString*)context + control:(OTControl*)control; + +- (long)fetchAllBottles:(NSString*)altDSID + containerName:(NSString*)containerName + context:(NSString*)context + control:(OTControl*)control; + +- (long)healthCheck:(NSString* _Nullable)container context:(NSString*)contextID skipRateLimitingCheck:(BOOL)skipRateLimitingCheck; + +- (long)tapToRadar:(NSString *)action description:(NSString *)description radar:(NSString *)radar; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/otctl/OTControlCLI.m b/keychain/otctl/OTControlCLI.m new file mode 100644 index 00000000..ac949dff --- /dev/null +++ b/keychain/otctl/OTControlCLI.m @@ -0,0 +1,476 @@ + + +#import +#import +#import +#import +#import + +#include "utilities/SecCFWrappers.h" +#include "utilities/SecInternalReleasePriv.h" +#import "utilities/debugging.h" + +#import "keychain/ot/OT.h" +#import "keychain/ot/OTConstants.h" +#import "keychain/ot/OTControl.h" +#import "keychain/otctl/OTControlCLI.h" + +// Mutual recursion to set up an object for jsonification +static NSDictionary* cleanDictionaryForJSON(NSDictionary* dict); + +static id cleanObjectForJSON(id obj) { + if(!obj) { + return nil; + } + if([obj isKindOfClass:[NSError class]]) { + NSError* obje = (NSError*) obj; + NSMutableDictionary* newErrorDict = [@{@"code": @(obje.code), @"domain": obje.domain} mutableCopy]; + newErrorDict[@"userInfo"] = cleanDictionaryForJSON(obje.userInfo); + return newErrorDict; + } else if([NSJSONSerialization isValidJSONObject:obj]) { + return obj; + + } else if ([obj isKindOfClass: [NSNumber class]]) { + return obj; + + } else if([obj isKindOfClass: [NSData class]]) { + NSData* dataObj = (NSData*)obj; + return [dataObj base64EncodedStringWithOptions:0]; + + } else if ([obj isKindOfClass: [NSDictionary class]]) { + return cleanDictionaryForJSON((NSDictionary*) obj); + + } else if ([obj isKindOfClass: [NSArray class]]) { + NSArray* arrayObj = (NSArray*)obj; + NSMutableArray* cleanArray = [NSMutableArray arrayWithCapacity:arrayObj.count]; + + for(id x in arrayObj) { + [cleanArray addObject: cleanObjectForJSON(x)]; + } + return cleanArray; + + } else { + return [obj description]; + } +} + +static NSDictionary* cleanDictionaryForJSON(NSDictionary* dict) { + if(!dict) { + return nil; + } + NSMutableDictionary* mutDict = [dict mutableCopy]; + for(id key in mutDict.allKeys) { + id obj = mutDict[key]; + mutDict[key] = cleanObjectForJSON(obj); + } + return mutDict; +} + +static void print_json(NSDictionary* dict) +{ + NSError* err; + + NSData* json = [NSJSONSerialization dataWithJSONObject:cleanDictionaryForJSON(dict) + options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) + error:&err]; + if(!json) { + NSLog(@"error during JSONification: %@", err.localizedDescription); + } else { + printf("%s\n", [[[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding] UTF8String]); + } +} + + +@implementation OTControlCLI + +- (instancetype)initWithOTControl:(OTControl*)control { + if((self = [super init])) { + _control = control; + } + + return self; +} + +- (long)startOctagonStateMachine:(NSString*)container context:(NSString*)contextID { +#if OCTAGON + __block long ret = -1; + + [self.control startOctagonStateMachine:container + context:contextID + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error starting state machine: %s\n", [[error description] UTF8String]); + ret = -1; + } else { + printf("state machine started.\n"); + } + }]; + + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (long)signIn:(NSString*)altDSID container:(NSString* _Nullable)container context:(NSString*)contextID { +#if OCTAGON + __block long ret = -1; + + [self.control signIn:altDSID + container:container + context:contextID + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error signing in: %s\n", [[error description] UTF8String]); + } else { + printf("Sign in complete.\n"); + ret = 0; + } + }]; + + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (long)signOut:(NSString* _Nullable)container context:(NSString*)contextID { +#if OCTAGON + __block long ret = -1; + [self.control signOut:container + context:contextID + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error signing out: %s\n", [[error description] UTF8String]); + } else { + printf("Sign out complete.\n"); + ret = 0; + } + }]; + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (long)depart:(NSString* _Nullable)container context:(NSString*)contextID { +#if OCTAGON + __block long ret = -1; + + [self.control leaveClique:container + context:contextID + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error departing clique: %s\n", [[error description] UTF8String]); + } else { + printf("Departing clique completed.\n"); + ret = 0; + } + }]; + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (long)resetOctagon:(NSString*)container context:(NSString*)contextID altDSID:(NSString*)altDSID { +#if OCTAGON + __block long ret = -1; + + [self.control resetAndEstablish:container + context:contextID + altDSID:altDSID + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error resetting: %s\n", [[error description] UTF8String]); + } else { + printf("reset and establish:\n"); + ret = 0; + } + }]; + + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (void)printPeer:(NSDictionary*)peerInformation prefix:(NSString* _Nullable)prefix { + NSString* peerID = peerInformation[@"peerID"]; + NSString* model = peerInformation[@"permanentInfo"][@"model_id"]; + NSNumber* epoch = peerInformation[@"permanentInfo"][@"epoch"]; + NSString* deviceName = peerInformation[@"stableInfo"][@"device_name"]; + NSString* serialNumber = peerInformation[@"stableInfo"][@"serial_number"]; + NSString* os = peerInformation[@"stableInfo"][@"os_version"]; + + printf("%s%s hw:'%s' name:'%s' serial: '%s' os:'%s' epoch:%d\n", + (prefix ? [prefix UTF8String] : ""), + [peerID UTF8String], + [model UTF8String], + [deviceName UTF8String], + [serialNumber UTF8String], + [os UTF8String], + [epoch intValue]); +} + +- (void)printPeers:(NSArray*)peerIDs + egoPeerID:(NSString* _Nullable)egoPeerID + informationOnPeers:(NSDictionary*)informationOnPeers { + for(NSString* peerID in peerIDs) { + NSDictionary* peerInformation = informationOnPeers[peerID]; + + if(!peerInformation) { + printf(" Peer: %s; further information missing\n", [peerID UTF8String]); + continue; + } + + if([peerID isEqualToString:egoPeerID]) { + [self printPeer:peerInformation prefix:@" Self: "]; + } else { + [self printPeer:peerInformation prefix:@" Peer: "]; + } + } +} + +- (long)status:(NSString* _Nullable)container context:(NSString*)contextID json:(bool)json { +#if OCTAGON + __block long ret = 0; + + [self.control status:container + context:contextID + reply:^(NSDictionary* result, NSError* _Nullable error) { + if(error) { + if(json) { + print_json(@{@"error" : [error description]}); + } else { + printf("Error fetching status: %s\n", [[error description] UTF8String]); + } + ret = -1; + } else { + if(json) { + print_json(result); + } else { + printf("Status for %s,%s:\n", [result[@"containerName"] UTF8String], [result[@"contextID"] UTF8String]); + + printf("\n"); + printf("State: %s\n", [[result[@"state"] description] UTF8String]); + printf("Flags: %s; Flags Pending: %s\n\n", + ([result[@"stateFlags"] count] == 0u) ? "none" : [[result[@"stateFlags"] description] UTF8String], + ([result[@"statePendingFlags"] count] == 0u) ? "none" : [[result[@"statePendingFlags"] description] UTF8String]); + + NSDictionary* contextDump = result[@"contextDump"]; + + // Make it easy to find peer information + NSMutableDictionary* peers = [NSMutableDictionary dictionary]; + NSMutableArray* allPeerIDs = [NSMutableArray array]; + for(NSDictionary* peerInformation in contextDump[@"peers"]) { + NSString* peerID = peerInformation[@"peerID"]; + if(peerID) { + peers[peerID] = peerInformation; + [allPeerIDs addObject:peerID]; + } + } + + NSDictionary* egoInformation = contextDump[@"self"]; + NSString* egoPeerID = egoInformation[@"peerID"]; + NSDictionary* egoDynamicInfo = egoInformation[@"dynamicInfo"]; + + if(egoPeerID) { + NSMutableArray *otherPeers = [allPeerIDs mutableCopy]; + [self printPeer:egoInformation prefix:@" Self: "]; + printf("\n"); + + // The self peer is technically a peer, so, shove it on in there + peers[egoPeerID] = egoInformation; + + NSArray* includedPeers = egoDynamicInfo[@"included"]; + printf("Trusted peers (by me):\n"); + if(includedPeers && includedPeers.count > 0) { + [self printPeers:includedPeers egoPeerID:egoPeerID informationOnPeers:peers]; + [otherPeers removeObjectsInArray:includedPeers]; + } else { + printf(" No trusted peers.\n"); + } + printf("\n"); + + NSArray* excludedPeers = egoDynamicInfo[@"excluded"]; + printf("Excluded peers (by me):\n"); + if(excludedPeers && excludedPeers.count > 0) { + [self printPeers:excludedPeers egoPeerID:egoPeerID informationOnPeers:peers]; + [otherPeers removeObjectsInArray:excludedPeers]; + } else { + printf(" No excluded peers.\n"); + } + printf("\n"); + + printf("Other peers (included/excluded by others):\n"); + if(otherPeers.count > 0) { + [self printPeers:otherPeers egoPeerID:egoPeerID informationOnPeers:peers]; + } else { + printf(" No other peers.\n"); + } + printf("\n"); + + } else { + printf("No current identity for this device.\n\n"); + + if(allPeerIDs.count > 0) { + printf("All peers currently in this account:\n"); + [self printPeers:allPeerIDs egoPeerID:nil informationOnPeers:peers]; + } else { + printf("No peers currently exist for this account.\n"); + } + } + + printf("\n"); + } + } + }]; + + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (long)recoverUsingBottleID:(NSString*)bottleID + entropy:(NSData*)entropy + altDSID:(NSString*)altDSID + containerName:(NSString*)containerName + context:(NSString*)context + control:(OTControl*)control { + __block long ret = 0; + +#if OCTAGON + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [control restore:containerName + contextID:context + bottleSalt:altDSID + entropy:entropy + bottleID:bottleID + reply:^(NSError* _Nullable error) { + if(error) { + ret = -1; + printf("Error recovering: %s\n", [[error description] UTF8String]); + } else { + printf("Succeeded recovering bottled peer %s\n", [[bottleID description] UTF8String]); + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + printf("timed out waiting for restore/recover\n"); + ret = -1; + } + + return ret; +#else + ret = -1; + return ret; +#endif +} + +- (long)fetchAllBottles:(NSString*)altDSID + containerName:(NSString*)containerName + context:(NSString*)context + control:(OTControl*)control { + __block long ret = 0; + +#if OCTAGON + __block NSError* localError = nil; + + __block NSArray* localViableBottleIDs = nil; + __block NSArray* localPartiallyViableBottleIDs = nil; + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + [control fetchAllViableBottles:containerName + context:context + reply:^(NSArray* _Nullable sortedBottleIDs, + NSArray* _Nullable sortedPartialBottleIDs, + NSError* _Nullable controlError) { + if(controlError) { + secnotice("clique", "findOptimalBottleIDsWithContextData errored: %@\n", controlError); + } else { + secnotice("clique", "findOptimalBottleIDsWithContextData succeeded: %@, %@\n", sortedBottleIDs, sortedPartialBottleIDs); + } + localError = controlError; + localViableBottleIDs = sortedBottleIDs; + localPartiallyViableBottleIDs = sortedPartialBottleIDs; + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 60)) != 0) { + secnotice("clique", "findOptimalBottleIDsWithContextData failed to fetch bottles\n"); + return -1; + } + + [localViableBottleIDs enumerateObjectsUsingBlock:^(NSString* obj, NSUInteger idx, BOOL* stop) { + printf("preferred bottleID: %s\n", [obj UTF8String]); + }]; + + [localPartiallyViableBottleIDs enumerateObjectsUsingBlock:^(NSString* obj, NSUInteger idx, BOOL* stop) { + printf("partial recovery bottleID: %s\n", [obj UTF8String]); + }]; + + return ret; +#else + ret = -1; + return ret; +#endif +} + +- (long)healthCheck:(NSString* _Nullable)container context:(NSString*)contextID skipRateLimitingCheck:(BOOL)skipRateLimitingCheck +{ +#if OCTAGON + __block long ret = -1; + + [self.control healthCheck:container + context:contextID + skipRateLimitingCheck:skipRateLimitingCheck + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error checking health: %s\n", [[error description] UTF8String]); + } else { + printf("Checking Octagon Health completed.\n"); + ret = 0; + } + }]; + return ret; +#else + printf("Unimplemented.\n"); + return -1; +#endif +} + +- (long)tapToRadar:(NSString *)action description:(NSString *)description radar:(NSString *)radar +{ +#if OCTAGON + __block long ret = 1; + + [self.control tapToRadar:action + description:description + radar:radar + reply:^(NSError* _Nullable error) { + if(error) { + printf("Error trigger TTR: %s\n", [[error description] UTF8String]); + } else { + printf("Trigger TTR completed.\n"); + ret = 0; + } + }]; + return ret; +#else + printf("Unimplemented.\n"); + return 1; +#endif +} + +@end diff --git a/keychain/otctl/otctl-Entitlements.plist b/keychain/otctl/otctl-Entitlements.plist index cfc36cb7..472e6b42 100644 --- a/keychain/otctl/otctl-Entitlements.plist +++ b/keychain/otctl/otctl-Entitlements.plist @@ -4,5 +4,7 @@ com.apple.private.octagon + com.apple.private.escrow-update + diff --git a/keychain/otctl/otctl.1 b/keychain/otctl/otctl.1 new file mode 100644 index 00000000..1bf49863 --- /dev/null +++ b/keychain/otctl/otctl.1 @@ -0,0 +1,15 @@ +.Dd Thu Feb 14 2019 +.Dt otctl 1 +.Os Darwin +.Sh NAME +.Nm otctl +.Nd Command line interface do provide diagnostic information for iCloud Keychain syncing +.Sh SYNOPSIS +.Nm +.Sh DESCRIPTION +Command line interface do provide trust and sycning related information in sysdiagnose. +.Sh SEE ALSO +.Xr sysdiagnose 1 , +.Sh HISTORY +.Nm +was first introduced in Mac OS X version 10.15 diff --git a/keychain/otctl/otctl.m b/keychain/otctl/otctl.m index 52653cc4..d569f7ea 100644 --- a/keychain/otctl/otctl.m +++ b/keychain/otctl/otctl.m @@ -2,508 +2,231 @@ // Security // +#import #import -#import +#import #import -#import -#import #import -#import "OT.h" -#import -#import "keychain/ot/OTControl.h" -#import "keychain/ot/OTConstants.h" -#include "lib/SecArgParse.h" -#include -#include - -@interface OTControlCLI : NSObject -@property OTControl* control; -@end - -@implementation OTControlCLI - - -- (instancetype) initWithOTControl:(OTControl*)control { - if ((self = [super init])) { - _control = control; - } - - return self; -} - -- (long)preflightBottledPeer:(NSString*)contextID dsid:(NSString*)dsid -{ - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [self.control preflightBottledPeer:contextID dsid:dsid reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { - if(error){ - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - }else if(entropy && bottleID && signingPublicKey){ - printf("\nSuccessfully preflighted bottle ID: %s\n", [bottleID UTF8String]); - printf("\nEntropy used: %s\n", [[entropy base64EncodedStringWithOptions:0] UTF8String]); - printf("\nSigning Public Key: %s\n", [[signingPublicKey base64EncodedStringWithOptions:0] UTF8String]); - ret = 0; - }else{ - printf("Failed to preflight bottle and no error was returned.."); - ret = -1; - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - return ret; -#else - return -1; -#endif -} - -- (long)launchBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID -{ - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [self.control launchBottledPeer:contextID bottleID:bottleID reply:^(NSError * _Nullable error) { - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - printf("\nSuccessfully launched bottleID: %s\n", [bottleID UTF8String]); - ret = 0; - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - return ret; -#else - return -1; -#endif -} - -- (long)scrubBottledPeer:(NSString*)contextID bottleID:(NSString*)bottleID -{ - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - - [self.control scrubBottledPeer:contextID bottleID:bottleID reply:^(NSError * _Nullable error) { - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - printf("\nSuccessfully scrubbed bottle ID: %s\n", [bottleID UTF8String]); - ret = 0; - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - return ret; -#else - ret = -1; - return ret; -#endif -} - - -- (long)enroll:(NSString*)contextID dsid:(NSString*)dsid -{ - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t semaForPreFlight = dispatch_semaphore_create(0); - dispatch_semaphore_t semaForLaunch = dispatch_semaphore_create(0); - __block NSString* bottleRecordID = nil; - __block NSError* localError = nil; - - [self.control preflightBottledPeer:contextID dsid:dsid reply:^(NSData * _Nullable entropy, NSString * _Nullable bottleID, NSData * _Nullable signingPublicKey, NSError * _Nullable error) { - if(error) - { - localError = error; - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - bottleRecordID = bottleID; - printf("\nSuccessfully preflighted bottle ID: %s\n", [bottleID UTF8String]); - printf("\nEntropy used: %s\n", [[entropy base64EncodedStringWithOptions:0] UTF8String]); - printf("\nSigning Public Key: %s\n", [[signingPublicKey base64EncodedStringWithOptions:0] UTF8String]); - ret = 0; - } - - dispatch_semaphore_signal(semaForPreFlight); - }]; - - if(dispatch_semaphore_wait(semaForPreFlight, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - if(localError == nil){ - [self.control launchBottledPeer:contextID bottleID:bottleRecordID reply:^(NSError * _Nullable error) { - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - printf("\nSuccessfully launched bottleID: %s\n", [bottleRecordID UTF8String]); - ret = 0; - } +#import "keychain/otctl/OTControlCLI.h" +#import "keychain/otctl/EscrowRequestCLI.h" +#import "keychain/escrowrequest/Framework/SecEscrowRequest.h" +#include "lib/SecArgParse.h" +#include "utilities/debugging.h" - dispatch_semaphore_signal(semaForLaunch); - }]; +#if TARGET_OS_WATCH +#import "keychain/otpaird/OTPairingClient.h" +#endif /* TARGET_OS_WATCH */ - if(dispatch_semaphore_wait(semaForLaunch, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - } - printf("Complete.\n"); - return ret; -#else - return -1; -#endif -} +static int start = false; +static int signIn = false; +static int signOut = false; +static int resetoctagon = false; +static int fetchAllBottles = false; +static int recover = false; +static int depart = false; -- (long)restore:(NSString*)contextID dsid:(NSString*)dsid secret:(NSData*)secret escrowRecordID:(NSString*)escrowRecordID -{ - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t sema = dispatch_semaphore_create(0); +static int status = false; - [self.control restore:contextID dsid:dsid secret:secret escrowRecordID:escrowRecordID reply:^(NSData* signingKeyData, NSData* encryptionKeyData, NSError *error) { - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { +static int er_trigger = false; +static int er_status = false; +static int er_reset = false; +static int er_store = false; - printf("Complete.\n"); - ret = 0; - } +static int ttr_flag = false; - NSString* signingKeyString = [signingKeyData base64EncodedStringWithOptions:0]; - NSString* encryptionKeyString = [encryptionKeyData base64EncodedStringWithOptions:0]; +static int health = false; - printf("Signing Key:\n %s\n", [signingKeyString UTF8String]); - printf("Encryption Key:\n %s\n", [encryptionKeyString UTF8String]); - dispatch_semaphore_signal(sema); - }]; +#if TARGET_OS_WATCH +static int pairme = false; +#endif /* TARGET_OS_WATCH */ - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - return ret; -#else - ret = -1; - return ret; -#endif -} +static char* bottleIDArg = NULL; +static char* contextNameArg = NULL; +static char* secretArg = NULL; +static char* skipRateLimitingCheckArg = NULL; +static int json = false; -- (long) reset -{ - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - [self.control reset:^(BOOL reset, NSError* error){ - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - printf("success\n"); - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - - printf("Complete.\n"); - return ret; -#else - ret = -1; - return ret; -#endif -} +static char* altDSIDArg = NULL; +static char* containerStr = NULL; +static char* radarNumber = NULL; -- (long) listOfRecords +static void internalOnly(void) { - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t sema = dispatch_semaphore_create(0); - [self.control listOfRecords:^(NSArray* list, NSError* error){ - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - [list enumerateObjectsUsingBlock:^(NSString* _Nonnull escrowRecordID, NSUInteger idx, BOOL * _Nonnull stop) { - printf("escrowRecordID: %s\n", [escrowRecordID UTF8String]); - }]; - ret = 0; - } - - dispatch_semaphore_signal(sema); - }]; - - if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; + if(!SecIsInternalRelease()) { + secnotice("octagon", "Tool not available on non internal builds"); + errx(1, "Tool not available on non internal builds"); } - - printf("Complete.\n"); - return ret; -#else - ret = -1; - return ret; -#endif } -- (long)octagonKeys +int main(int argc, char** argv) { - __block long ret = 0; - -#if OCTAGON - dispatch_semaphore_t semaForGettingEncryptionKey = dispatch_semaphore_create(0); - dispatch_semaphore_t semaForGettingSigningKey = dispatch_semaphore_create(0); - [self.control encryptionKey:^(NSData *encryptionKey, NSError * error) { - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - NSString* encryptionKeyString = [encryptionKey base64EncodedStringWithOptions:0]; - printf("Encryption Key:\n %s\n", [encryptionKeyString UTF8String]); - ret = 0; - } - - dispatch_semaphore_signal(semaForGettingEncryptionKey); - }]; - - [self.control signingKey:^(NSData *signingKey, NSError * error) { - if(error) - { - printf("Error pushing: %s\n", [[error description] UTF8String]); - ret = (error.code == 0 ? -1 : error.code); - } else { - NSString* signingKeyString = [signingKey base64EncodedStringWithOptions:0]; - printf("Signing Key:\n %s\n", [signingKeyString UTF8String]); - ret = 0; - } + static struct argument options[] = { + {.shortname = 's', .longname = "secret", .argument = &secretArg, .description = "escrow secret"}, + {.shortname = 'e', .longname = "bottleID", .argument = &bottleIDArg, .description = "bottle record id"}, + {.shortname = 'r', .longname = "skipRateLimiting", .argument = &skipRateLimitingCheckArg, .description = " enter values YES or NO, option defaults to NO, This gives you the opportunity to skip the rate limiting check when performing the cuttlefish health check"}, + {.shortname = 'j', .longname = "json", .flag = &json, .flagval = true, .description = "Output in JSON"}, - dispatch_semaphore_signal(semaForGettingSigningKey); - }]; + {.longname = "altDSID", .argument = &altDSIDArg, .description = "altDSID (for sign-in/out)"}, + {.longname = "entropy", .argument = &secretArg, .description = "escrowed entropy in JSON"}, + {.longname = "container", .argument = &containerStr, .description = "CloudKit container name"}, + {.longname = "radar", .argument = &radarNumber, .description = "Radar number"}, - if(dispatch_semaphore_wait(semaForGettingEncryptionKey, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - if(dispatch_semaphore_wait(semaForGettingSigningKey, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 65)) != 0) { - printf("\n\nError: timed out waiting for response\n"); - return -1; - } - printf("Complete.\n"); - return ret; -#else - ret = -1; - return ret; -#endif -} + {.command = "start", .flag = &start, .flagval = true, .description = "Start Octagon state machine"}, + {.command = "sign-in", .flag = &signIn, .flagval = true, .description = "Inform Cuttlefish container of sign in"}, + {.command = "sign-out", .flag = &signOut, .flagval = true, .description = "Inform Cuttlefish container of sign out"}, + {.command = "status", .flag = &status, .flagval = true, .description = "Report Octagon status"}, + {.command = "resetoctagon", .flag = &resetoctagon, .flagval = true, .description = "Reset and establish new Octagon trust"}, + {.command = "allBottles", .flag = &fetchAllBottles, .flagval = true, .description = "Fetch all viable bottles"}, + {.command = "recover", .flag = &recover, .flagval = true, .description = "Recover using this bottle"}, + {.command = "depart", .flag = &depart, .flagval = true, .description = "Depart from Octagon Trust"}, -@end + {.command = "er-trigger", .flag = &er_trigger, .flagval = true, .description = "Trigger an Escrow Request request"}, + {.command = "er-status", .flag = &er_status, .flagval = true, .description = "Report status on any pending Escrow Request requests"}, + {.command = "er-reset", .flag = &er_reset, .flagval = true, .description = "Delete all Escrow Request requests"}, + {.command = "er-store", .flag = &er_store, .flagval = true, .description = "Store any pending Escrow Request prerecords"}, -static int enroll = false; -static int restore = false; -static int octagonkeys = false; -static int reset = false; + {.command = "health", .flag = &health, .flagval = true, .description = "Check Octagon Health status"}, -static int prepbp = false; -static int launch = false; -static int scrub = false; + {.command = "taptoradar", .flag = &ttr_flag, .flagval = true, .description = "Trigger a TapToRadar"}, -static int listOfRecords = false; -static char* bottleIDArg = NULL; -static char* contextNameArg = NULL; -static char* secretArg = NULL; - -int main(int argc, char **argv) -{ - if(!SecIsInternalRelease()) - { - secnotice("octagon", "Tool not available on non internal builds"); - return -1; - } +#if TARGET_OS_WATCH + {.command = "pairme", .flag = &pairme, .flagval = true, .description = "Perform pairing (watchOS only)"}, +#endif /* TARGET_OS_WATCH */ + {}}; - if(!SecOTIsEnabled()) - { - printf("To use this tool, enable defaults write for EnableOTRestore\n defaults write (~)/Library/Preferences/com.apple.security EnableOTRestore -bool YES\n"); - return -1; - } - static struct argument options[] = { - { .shortname='s', .longname="secret", .argument=&secretArg, .description="escrow secret"}, - { .shortname='e', .longname="bottleID", .argument=&bottleIDArg, .description="bottle record id"}, - { .shortname='c', .longname="context", .argument=&contextNameArg, .description="context name"}, - - { .command="restore", .flag=&restore, .flagval=true, .description="Restore fake bottled peer"}, - { .command="enroll", .flag=&enroll, .flagval=true, .description="Enroll fake bottled peer"}, - { .command="keys", .flag=&octagonkeys, .shortname='k', .flagval=true, .description="Octagon Signing + Encryption Keys"}, - { .command="reset", .flag=&reset, .flagval=true, .description="Reset Octagon Trust Zone"}, - { .command="list", .flag=&listOfRecords, .flagval=true, .description="List of current Bottled Peer Records IDs"}, - - { .command="prepbp", .flag=&prepbp, .shortname='p', .flagval=true, .description="Preflights a bottled peer"}, - { .command="launch", .flag=&launch, .flagval=true, .description="Launches a bottled peer"}, - { .command="scrub", .flag=&scrub, .flagval=true, .description="Scrub bottled peer"}, - - {} - }; - static struct arguments args = { - .programname="otctl", - .description="Control and report on Octagon Trust", + .programname = "otctl", + .description = "Control and report on Octagon Trust", .arguments = options, }; - + if(!options_parse(argc, argv, &args)) { printf("\n"); print_usage(&args); return -1; } - + @autoreleasepool { NSError* error = nil; - - OTControl* rpc = [OTControl controlObject:&error]; + + // Use a synchronous control object + OTControl* rpc = [OTControl controlObject:true error:&error]; if(error || !rpc) { errx(1, "no OTControl failed: %s", [[error description] UTF8String]); } - + + NSString* context = contextNameArg ? [NSString stringWithCString:contextNameArg encoding:NSUTF8StringEncoding] : OTDefaultContext; + NSString* container = containerStr ? [NSString stringWithCString:containerStr encoding:NSUTF8StringEncoding] : nil; + NSString* altDSID = altDSIDArg ? [NSString stringWithCString:altDSIDArg encoding:NSUTF8StringEncoding] : nil; + NSString* skipRateLimitingCheck = skipRateLimitingCheckArg ? [NSString stringWithCString:skipRateLimitingCheckArg encoding:NSUTF8StringEncoding] : @"NO"; + OTControlCLI* ctl = [[OTControlCLI alloc] initWithOTControl:rpc]; - if(enroll) { - long ret = 0; - NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; - ret = [ctl enroll:context dsid:@"12345678"]; - return (int)ret; + NSError* escrowRequestError = nil; + EscrowRequestCLI* escrowctl = [[EscrowRequestCLI alloc] initWithEscrowRequest:[SecEscrowRequest request:&escrowRequestError]]; + if(escrowRequestError) { + errx(1, "SecEscrowRequest failed: %s", [[escrowRequestError description] UTF8String]); } - if(prepbp){ - long ret = 0; - NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; - - //requires secret, context is optional - ret = [ctl preflightBottledPeer:context dsid:@"12345678"]; + if(resetoctagon) { + long ret = [ctl resetOctagon:container context:context altDSID:altDSID]; return (int)ret; } - if(launch){ - long ret = 0; - - NSString* bottleID = bottleIDArg ? [NSString stringWithCString: bottleIDArg encoding: NSUTF8StringEncoding] : nil; - NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; - //requires bottleID, context is optional - if(bottleID && [bottleID length] > 0 && ![bottleID isEqualToString:@"(null)"]){ - ret = [ctl launchBottledPeer:context bottleID:bottleID]; - } - else{ - print_usage(&args); - return -1; - } - - return (int)ret; + if(fetchAllBottles) { + return (int)[ctl fetchAllBottles:altDSID containerName:container context:context control:rpc]; } - if(scrub){ - long ret = 0; - - NSString* bottleID = bottleIDArg ? [NSString stringWithCString: bottleIDArg encoding: NSUTF8StringEncoding] : nil; - NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; - - //requires bottle ID, context is optional - if(bottleID && [bottleID length] > 0 && ![bottleID isEqualToString:@"(null)"]){ - ret = [ctl scrubBottledPeer:context bottleID:bottleID]; - } - else{ + if(recover) { + NSString* entropyJSON = secretArg ? [NSString stringWithCString:secretArg encoding:NSUTF8StringEncoding] : nil; + NSString* bottleID = bottleIDArg ? [NSString stringWithCString:bottleIDArg encoding:NSUTF8StringEncoding] : nil; + + if(!entropyJSON || !bottleID) { print_usage(&args); return -1; } - return (int)ret; - } - - if(restore) { - long ret = 0; - NSData* secretData = nil; - NSString* secretString = secretArg ? [NSString stringWithCString: secretArg encoding: NSUTF8StringEncoding] : nil; - NSString* bottleID = bottleIDArg ? [NSString stringWithCString: bottleIDArg encoding: NSUTF8StringEncoding] : nil; - NSString* context = contextNameArg ? [NSString stringWithCString: contextNameArg encoding: NSUTF8StringEncoding] : OTDefaultContext; - - //requires secret and bottle ID, context is optional - if(secretString && [secretString length] > 0){ - secretData = [[NSData alloc] initWithBase64EncodedString:secretString options:0];; - } - else{ + + NSData* entropy = [[NSData alloc] initWithBase64EncodedString:entropyJSON options:0]; + if(!entropy) { print_usage(&args); return -1; } - - if(bottleID && [bottleID length] > 0 && ![bottleID isEqualToString:@"(null)"]){ - ret = [ctl restore:context dsid:@"12345678" secret:secretData escrowRecordID:bottleID]; + return (int)[ctl recoverUsingBottleID:bottleID + entropy:entropy + altDSID:altDSID + containerName:container + context:context + control:rpc]; + } + if(depart) { + return (int)[ctl depart:container context:context]; + } + if(start) { + internalOnly(); + return (int)[ctl startOctagonStateMachine:container context:context]; + } + if(signIn) { + internalOnly(); + return (int)[ctl signIn:altDSID container:container context:context]; + } + if(signOut) { + internalOnly(); + return (int)[ctl signOut:container context:context]; + } + + if(status) { + return (int)[ctl status:container context:context json:json]; + } + + if(health) { + BOOL skip = NO; + if([skipRateLimitingCheck isEqualToString:@"YES"]) { + skip = YES; + } else { + skip = NO; } - else{ - print_usage(&args); - return -1; + return (int)[ctl healthCheck:container context:context skipRateLimitingCheck:skip]; + } + if (ttr_flag) { + if (radarNumber == NULL) { + radarNumber = "1"; } - return (int)ret; + return (int)[ctl tapToRadar:@"action" description:@"description" radar:[NSString stringWithUTF8String:radarNumber]]; } - if(octagonkeys){ - long ret = 0; - ret = [ctl octagonKeys]; - return (int)ret; + if(er_trigger) { + internalOnly(); + return (int)[escrowctl trigger]; } - if(listOfRecords){ - long ret = 0; - ret = [ctl listOfRecords]; - return (int)ret; + if(er_status) { + return (int)[escrowctl status]; } - if(reset){ - long ret = 0; - ret = [ctl reset]; - return (int)ret; + if(er_reset) { + return (int)[escrowctl reset]; } - else { - print_usage(&args); - return -1; + if(er_store) { + return (int)[escrowctl storePrerecordsInEscrow]; } +#if TARGET_OS_WATCH + if (pairme) { + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + OTPairingInitiateWithCompletion(NULL, ^(bool success, NSError *pairingError) { + if (success) { + printf("successfully paired with companion\n"); + } else { + printf("failed to pair with companion: %s\n", pairingError.description.UTF8String); + } + dispatch_semaphore_signal(sema); + }); + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + return 0; + } +#endif /* TARGET_OS_WATCH */ + + print_usage(&args); + return -1; } return 0; } - diff --git a/OSX/libsecurity_cryptkit/Info-security_cryptkit.plist b/keychain/otpaird/Info.plist similarity index 65% rename from OSX/libsecurity_cryptkit/Info-security_cryptkit.plist rename to keychain/otpaird/Info.plist index 0c67376e..47fad32c 100644 --- a/OSX/libsecurity_cryptkit/Info-security_cryptkit.plist +++ b/keychain/otpaird/Info.plist @@ -1,5 +1,8 @@ - + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + diff --git a/keychain/otpaird/OTPairingClient.h b/keychain/otpaird/OTPairingClient.h new file mode 100644 index 00000000..233bd8c4 --- /dev/null +++ b/keychain/otpaird/OTPairingClient.h @@ -0,0 +1,7 @@ +#import + +#if TARGET_OS_WATCH + +void OTPairingInitiateWithCompletion(dispatch_queue_t queue, void (^completion)(bool success, NSError *)); + +#endif /* TARGET_OS_WATCH */ diff --git a/keychain/otpaird/OTPairingClient.m b/keychain/otpaird/OTPairingClient.m new file mode 100644 index 00000000..22a010db --- /dev/null +++ b/keychain/otpaird/OTPairingClient.m @@ -0,0 +1,60 @@ +#import + +#if TARGET_OS_WATCH + +#import +#import +#import +#import + +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import "OTPairingClient.h" +#import "OTPairingConstants.h" + +void +OTPairingInitiateWithCompletion(dispatch_queue_t queue, void (^completion)(bool success, NSError *)) +{ + xpc_connection_t connection; + xpc_object_t message; + + connection = xpc_connection_create_mach_service(OTPairingMachServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); + xpc_connection_set_event_handler(connection, ^(__unused xpc_object_t event) { + }); + xpc_connection_activate(connection); + + message = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_uint64(message, OTPairingXPCKeyOperation, OTPairingOperationInitiate); + + xpc_connection_send_message_with_reply(connection, message, queue, ^(xpc_object_t reply) { + if (xpc_get_type(reply) == XPC_TYPE_DICTIONARY) { + bool success = xpc_dictionary_get_bool(reply, OTPairingXPCKeySuccess); + size_t errlen = 0; + const void *errptr = xpc_dictionary_get_data(reply, OTPairingXPCKeyError, &errlen); + NSData *errordata; + NSError *nserr = nil; + + if (errptr != NULL) { + errordata = [NSData dataWithBytesNoCopy:(void *)errptr length:errlen freeWhenDone:NO]; + nserr = [SecXPCHelper errorFromEncodedData:errordata]; + } + + completion(success, nserr); + } else if (reply == XPC_ERROR_CONNECTION_INVALID) { + // This error is expected; otpaird is a NanoLaunchDaemon, only loaded when companion is paired. + os_log(OS_LOG_DEFAULT, "otpaird connection invalid (daemon unloaded?)"); + completion(true, nil); + } else { + char *desc = NULL; + NSDictionary *userInfo = nil; + + desc = xpc_copy_description(reply); + userInfo = @{ NSLocalizedDescriptionKey : [NSString stringWithUTF8String:desc] }; + free(desc); + + completion(false, [NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeXPC userInfo:userInfo]); + } + }); +} + +#endif /* TARGET_OS_WATCH */ diff --git a/keychain/otpaird/OTPairingConstants.h b/keychain/otpaird/OTPairingConstants.h new file mode 100644 index 00000000..e5de4f7f --- /dev/null +++ b/keychain/otpaird/OTPairingConstants.h @@ -0,0 +1,40 @@ +#define OTPairingMachServiceName "com.apple.security.otpaird" + +#define OTPairingIDSServiceName @"com.apple.private.alloy.octagon" + +#define OTPairingIDSKeyMessageType @"m" +#define OTPairingIDSKeyError @"e" +#define OTPairingIDSKeySession @"session" +#define OTPairingIDSKeyPacket @"packet" +#define OTPairingIDSKeyErrorDeprecated @"error" + +enum OTPairingIDSMessageType { + OTPairingIDSMessageTypePacket = 1, + OTPairingIDSMessageTypeError = 2, + OTPairingIDSMessageTypePoke = 3, +}; + +#define OTPairingXPCKeyOperation "operation" +#define OTPairingXPCKeyError "error" +#define OTPairingXPCKeySuccess "success" + +#define OTPairingErrorDomain @"com.apple.security.otpaird" +enum OTPairingErrorType { + OTPairingSuccess = 0, + OTPairingErrorTypeLock = 1, + OTPairingErrorTypeXPC = 2, + OTPairingErrorTypeIDS = 3, + OTPairingErrorTypeRemote = 4, + OTPairingErrorTypeAlreadyIn = 5, + OTPairingErrorTypeBusy = 6, + OTPairingErrorTypeKCPairing = 7, +}; + +enum { + OTPairingOperationInitiate = 1, +}; + +#define OTPairingXPCActivityIdentifier "com.apple.security.otpaird.pairing" +#define OTPairingXPCActivityInterval XPC_ACTIVITY_INTERVAL_1_HOUR + +#define OTPairingXPCActivityPoke "com.apple.security.otpaird.poke" diff --git a/keychain/otpaird/OTPairingPacketContext.h b/keychain/otpaird/OTPairingPacketContext.h new file mode 100644 index 00000000..e7d38337 --- /dev/null +++ b/keychain/otpaird/OTPairingPacketContext.h @@ -0,0 +1,12 @@ +#import + +@interface OTPairingPacketContext : NSObject +- (instancetype)initWithMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context; +@property (readonly, atomic) enum OTPairingIDSMessageType messageType; +@property (readonly, atomic) NSString *sessionIdentifier; +@property (readonly, atomic) NSData *packetData; +@property (readonly, atomic) NSError *error; +@property (readonly, atomic) NSString *incomingResponseIdentifier; +@property (readonly, atomic) NSString *outgoingResponseIdentifier; +@property (readonly, atomic) NSString *fromID; +@end diff --git a/keychain/otpaird/OTPairingPacketContext.m b/keychain/otpaird/OTPairingPacketContext.m new file mode 100644 index 00000000..7fbbef9a --- /dev/null +++ b/keychain/otpaird/OTPairingPacketContext.m @@ -0,0 +1,96 @@ +#import +#import +#import +#import + +#import "keychain/categories/NSError+UsefulConstructors.h" + +#import "OTPairingPacketContext.h" +#import "OTPairingConstants.h" + +@interface OTPairingPacketContext () +@property (readwrite) NSDictionary *message; +@property (readwrite) NSString *fromID; +@property (readwrite) IDSMessageContext *context; +@end + +@implementation OTPairingPacketContext + +@synthesize message = _message; +@synthesize fromID = _fromID; +@synthesize context = _context; +@synthesize error = _error; + +- (instancetype)initWithMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context +{ + self = [super init]; + if (self != nil) { + self.message = message; + self.fromID = fromID; + self.context = context; + } + return self; +} + +- (enum OTPairingIDSMessageType)messageType +{ + NSNumber *typeNum; + enum OTPairingIDSMessageType type; + + typeNum = self.message[OTPairingIDSKeyMessageType]; + if (typeNum != nil) { + type = [typeNum intValue]; + } else { + // From older internal builds; remove soon + if (self.packetData != nil) { + type = OTPairingIDSMessageTypePacket; + } else { + type = OTPairingIDSMessageTypeError; + } + } + + return type; +} + +- (NSString *)sessionIdentifier +{ + return self.message[OTPairingIDSKeySession]; +} + +- (NSData *)packetData +{ + return self.message[OTPairingIDSKeyPacket]; +} + +- (NSError *)error +{ + if (self.messageType != OTPairingIDSMessageTypeError) { + return nil; + } + + if (!self->_error) { + NSData *errorData = self.message[OTPairingIDSKeyError]; + if (errorData != NULL) { + self->_error = [SecXPCHelper errorFromEncodedData:errorData]; + } else { + // Key from older iOS builds; remove soon + // When this is removed, it will still be useful to have a fallback in case errorData is missing or errorFromEncodedData fails + NSString *errorString = self.message[OTPairingIDSKeyErrorDeprecated]; + self->_error = [NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeRemote description:errorString]; + } + } + + return self->_error; +} + +- (NSString *)incomingResponseIdentifier +{ + return self.context.incomingResponseIdentifier; +} + +- (NSString *)outgoingResponseIdentifier +{ + return self.context.outgoingResponseIdentifier; +} + +@end diff --git a/keychain/otpaird/OTPairingService.h b/keychain/otpaird/OTPairingService.h new file mode 100644 index 00000000..61c41c56 --- /dev/null +++ b/keychain/otpaird/OTPairingService.h @@ -0,0 +1,14 @@ +#import +#import "OTPairingConstants.h" + +typedef void (^OTPairingCompletionHandler)(bool success, NSError *error); + +@interface OTPairingService : NSObject + ++ (instancetype)sharedService; + +#if TARGET_OS_WATCH +- (void)initiatePairingWithCompletion:(OTPairingCompletionHandler)completionHandler; +#endif /* TARGET_OS_WATCH */ + +@end diff --git a/keychain/otpaird/OTPairingService.m b/keychain/otpaird/OTPairingService.m new file mode 100644 index 00000000..22f1bbeb --- /dev/null +++ b/keychain/otpaird/OTPairingService.m @@ -0,0 +1,456 @@ +#import +#import +#import +#import +#import +#import +#import + +#if TARGET_OS_WATCH +#import +#endif /* TARGET_OS_WATCH */ + +#if !TARGET_OS_SIMULATOR +#import +#endif /* !TARGET_OS_SIMULATOR */ + +#import "OTPairingService.h" +#import "OTPairingPacketContext.h" +#import "OTPairingSession.h" +#import "OTPairingConstants.h" + +#import "keychain/categories/NSError+UsefulConstructors.h" +#import "keychain/ot/OTDeviceInformationAdapter.h" + +#define WAIT_FOR_UNLOCK_DURATION (120ull) + +@interface OTPairingService () +@property dispatch_queue_t queue; +@property IDSService *service; +@property dispatch_source_t unlockTimer; +@property int notifyToken; +@property (nonatomic, strong) OTDeviceInformationActualAdapter *deviceInfo; +@property OTPairingSession *session; +@end + +@implementation OTPairingService + ++ (instancetype)sharedService +{ + static dispatch_once_t once; + static OTPairingService *service; + + dispatch_once(&once, ^{ + service = [[OTPairingService alloc] init]; + }); + + return service; +} + +- (instancetype)init +{ + self = [super init]; + if (self != nil) { + self.queue = dispatch_queue_create("com.apple.security.otpaird", DISPATCH_QUEUE_SERIAL); + self.service = [[IDSService alloc] initWithService:OTPairingIDSServiceName]; + [self.service addDelegate:self queue:self.queue]; + self.notifyToken = NOTIFY_TOKEN_INVALID; + self.deviceInfo = [[OTDeviceInformationActualAdapter alloc] init]; + } + return self; +} + +#if TARGET_OS_WATCH +- (void)initiatePairingWithCompletion:(OTPairingCompletionHandler)completionHandler +{ + dispatch_assert_queue_not(self.queue); + + if ([self _octagonInClique]) { + os_log(OS_LOG_DEFAULT, "already in octagon, bailing"); + completionHandler(false, [NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeAlreadyIn description:@"already in octagon"]); + return; + } + + dispatch_async(self.queue, ^{ + if (self.session != nil) { + completionHandler(false, [NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeBusy description:@"pairing in progress"]); + return; + } + + self.session = [[OTPairingSession alloc] initWithDeviceInfo:self.deviceInfo]; + self.session.completionHandler = completionHandler; + [self sendReplyToPacket]; + }); +} +#endif /* TARGET_OS_WATCH */ + +// Should be a delegate method - future refactor +- (void)session:(__unused OTPairingSession *)session didCompleteWithSuccess:(bool)success error:(NSError *)error +{ + os_assert(self.session == session); + +#if TARGET_OS_WATCH + self.session.completionHandler(success, error); +#endif /* TARGET_OS_WATCH */ + + self.session = nil; + self.unlockTimer = nil; +} + +#pragma mark - + +- (void)sendReplyToPacket +{ + dispatch_assert_queue(self.queue); + +#if !TARGET_OS_SIMULATOR + NSDictionary *lockOptions; + CFErrorRef lockError = NULL; + + lockOptions = @{ + (__bridge NSString *)kMKBAssertionTypeKey : (__bridge NSString *)kMKBAssertionTypeOther, + (__bridge NSString *)kMKBAssertionTimeoutKey : @(60), + }; + self.session.lockAssertion = MKBDeviceLockAssertion((__bridge CFDictionaryRef)lockOptions, &lockError); + + if (self.session.lockAssertion) { + [self stopWaitingForDeviceUnlock]; + [self exchangePacketAndReply]; + } else { + os_log(OS_LOG_DEFAULT, "Failed to obtain lock assertion: %@", lockError); + if (lockError) { + CFRelease(lockError); + } + [self waitForDeviceUnlock]; + } +#else /* TARGET_OS_SIMULATOR */ + [self exchangePacketAndReply]; +#endif /* !TARGET_OS_SIMULATOR */ +} + +- (void)deviceUnlockTimedOut +{ + dispatch_assert_queue(self.queue); + + /* Should not happen; be safe. */ + if (self.session == nil) { + return; + } + +#if TARGET_OS_IOS + OTPairingPacketContext *packet = self.session.packet; + self.session.packet = nil; + + os_assert(packet != nil); // the acceptor always responds to a request packet, it's never initiating + + NSError *unlockError = [NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeLock description:@"timed out waiting for companion unlock"]; + NSMutableDictionary *message = [[NSMutableDictionary alloc] init]; + message[OTPairingIDSKeyMessageType] = @(OTPairingIDSMessageTypeError); + message[OTPairingIDSKeySession] = self.session.identifier; + message[OTPairingIDSKeyError] = [SecXPCHelper encodedDataFromError:unlockError]; + message[OTPairingIDSKeyErrorDeprecated] = unlockError.localizedDescription; // For older watchOS builds; remove soon + NSString *toID = packet.fromID; + NSString *responseIdentifier = packet.outgoingResponseIdentifier; + [self _sendMessage:message to:toID identifier:responseIdentifier]; + + [self scheduleGizmoPoke]; +#endif /* TARGET_OS_IOS */ + + [self session:self.session didCompleteWithSuccess:false error:[NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeLock description:@"timed out waiting for unlock"]]; +} + +- (void)exchangePacketAndReply +{ + dispatch_assert_queue(self.queue); + + OTPairingPacketContext *packet = self.session.packet; + self.session.packet = nil; + + [self.session.channel exchangePacket:packet.packetData complete:^(BOOL complete, NSData *responsePacket, NSError *channelError) { + /* this runs on a variety of different queues depending on the step (caller's queue, or an NSXPC queue) */ + + dispatch_async(self.queue, ^{ + NSString *toID; + NSString *responseIdentifier; + + os_log(OS_LOG_DEFAULT, "exchangePacket: complete=%d responsePacket=%@ channelError=%@", complete, responsePacket, channelError); + if (channelError != nil) { +#if TARGET_OS_IOS + NSError *cleansedError = [SecXPCHelper cleanseErrorForXPC:channelError]; + NSMutableDictionary *message = [[NSMutableDictionary alloc] init]; + message[OTPairingIDSKeyMessageType] = @(OTPairingIDSMessageTypeError); + message[OTPairingIDSKeySession] = self.session.identifier; + message[OTPairingIDSKeyError] = cleansedError ? [SecXPCHelper encodedDataFromError:cleansedError] : nil; + message[OTPairingIDSKeyErrorDeprecated] = channelError.description; + os_assert(packet != nil); // the acceptor always responds to a request packet, it's never initiating + toID = packet.fromID; + responseIdentifier = packet.outgoingResponseIdentifier; + [self _sendMessage:message to:toID identifier:responseIdentifier]; +#endif + + [self session:self.session didCompleteWithSuccess:false error:[NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeKCPairing description:@"exchangePacket" underlying:channelError]]; + + return; + } + + if (responsePacket != nil) { + NSDictionary *message = @{ + OTPairingIDSKeyMessageType : @(OTPairingIDSMessageTypePacket), + OTPairingIDSKeySession : self.session.identifier, + OTPairingIDSKeyPacket : responsePacket, + }; + toID = packet ? packet.fromID : IDSDefaultPairedDevice; + responseIdentifier = packet ? packet.outgoingResponseIdentifier : nil; + [self _sendMessage:message to:toID identifier:responseIdentifier]; + } + + if (complete) { + [self session:self.session didCompleteWithSuccess:true error:nil]; + } + }); + }]; +} + +- (void)_sendMessage:(NSDictionary *)message to:(NSString *)toID identifier:(NSString *)responseIdentifier +{ + [self _sendMessage:message to:toID identifier:responseIdentifier expectReply:YES]; +} + +- (void)_sendMessage:(NSDictionary *)message to:(NSString *)toID identifier:(NSString *)responseIdentifier expectReply:(BOOL)expectReply +{ + dispatch_assert_queue(self.queue); + + NSSet *destinations; + NSMutableDictionary *options; + NSString *identifier = nil; + NSError *error = nil; + BOOL sendResult = NO; + + destinations = [NSSet setWithObject:toID]; + + options = [NSMutableDictionary new]; + options[IDSSendMessageOptionForceLocalDeliveryKey] = @YES; + options[IDSSendMessageOptionExpectsPeerResponseKey] = @(expectReply); // TODO: when are we complete?? + if (responseIdentifier != nil) { + options[IDSSendMessageOptionPeerResponseIdentifierKey] = responseIdentifier; + } + + sendResult = [self.service sendMessage:message + toDestinations:destinations + priority:IDSMessagePriorityDefault + options:options + identifier:&identifier + error:&error]; + if (sendResult) { + self.session.sentMessageIdentifier = identifier; + } else { + os_log(OS_LOG_DEFAULT, "send message failed (%@): %@", identifier, error); + // On iOS, do nothing; watch will time out waiting for response. + [self session:self.session didCompleteWithSuccess:false error:[NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeIDS description:@"IDS message send failure" underlying:error]]; + } +} + +#pragma mark IDSServiceDelegate methods + +- (void)service:(IDSService *)service account:(__unused IDSAccount *)account incomingMessage:(NSDictionary *)message fromID:(NSString *)fromID context:(IDSMessageContext *)context +{ + dispatch_assert_queue(self.queue); + + OTPairingPacketContext *packet = nil; + bool validateIdentifier = true; + + os_log(OS_LOG_DEFAULT, "IDS message from %@: %@", fromID, message); + + packet = [[OTPairingPacketContext alloc] initWithMessage:message fromID:fromID context:context]; + + if (packet.messageType == OTPairingIDSMessageTypePoke) { +#if TARGET_OS_WATCH + // on self.queue now, but initiatePairingWithCompletion: must _not_ be on self.queue + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + os_log(OS_LOG_DEFAULT, "companion claims to be unlocked, retrying"); + [self initiatePairingWithCompletion:^(bool success, NSError *error) { + if (success) { + os_log(OS_LOG_DEFAULT, "companion-unlocked retry succeeded"); + } else { + os_log(OS_LOG_DEFAULT, "companion-unlocked retry failed: %@", error); + } + }]; + }); +#endif /* TARGET_OS_WATCH */ + return; + } + + /* + * Check for missing/invalid session identifier. Since the watch is the initiator, + * iOS responds to an invalid session identifier by resetting state and starting over. + */ + if (packet.sessionIdentifier == nil) { + os_log(OS_LOG_DEFAULT, "ignoring message with no session identifier (old build?)"); + return; + } else if (![packet.sessionIdentifier isEqualToString:self.session.identifier]) { +#if TARGET_OS_WATCH + os_log(OS_LOG_DEFAULT, "unknown session identifier, dropping message"); + return; +#elif TARGET_OS_IOS + os_log(OS_LOG_DEFAULT, "unknown session identifier %@, creating new session object", packet.sessionIdentifier); + self.session = [[OTPairingSession alloc] initWithDeviceInfo:self.deviceInfo identifier:packet.sessionIdentifier]; + validateIdentifier = false; +#endif /* TARGET_OS_IOS */ + } + + if (validateIdentifier && ![self.session.sentMessageIdentifier isEqualToString:packet.incomingResponseIdentifier]) { + os_log(OS_LOG_DEFAULT, "ignoring message with unrecognized incomingResponseIdentifier"); + return; + } + + switch (packet.messageType) { + case OTPairingIDSMessageTypeError: + [self session:self.session didCompleteWithSuccess:false error:[NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeRemote description:@"companion error" underlying:packet.error]]; + break; + case OTPairingIDSMessageTypePacket: + self.session.packet = packet; + [self sendReplyToPacket]; + break; + case OTPairingIDSMessageTypePoke: + /*impossible*/ + break; + } +} + +- (void)service:(__unused IDSService *)service account:(__unused IDSAccount *)account identifier:(NSString *)identifier didSendWithSuccess:(BOOL)success error:(NSError *)error context:(__unused IDSMessageContext *)context +{ + dispatch_assert_queue(self.queue); + + /* Only accept callback if it is for the recently-sent message. */ + if (![self.session.sentMessageIdentifier isEqualToString:identifier]) { + os_log(OS_LOG_DEFAULT, "ignoring didSendWithSuccess callback for unexpected identifier: %@", identifier); + return; + } + + if (!success) { + os_log(OS_LOG_DEFAULT, "unsuccessfully sent message (%@): %@", identifier, error); + // On iOS, do nothing; watch will time out waiting for response. + [self session:self.session didCompleteWithSuccess:false error:[NSError errorWithDomain:OTPairingErrorDomain code:OTPairingErrorTypeIDS description:@"IDS message failed to send" underlying:error]]; + } +} + +#pragma mark lock state handling + +#if !TARGET_OS_SIMULATOR +- (void)waitForDeviceUnlock +{ + dispatch_assert_queue(self.queue); + + static dispatch_once_t once; + static dispatch_source_t lockStateCoalescingSource; + uint32_t notify_status; + int token; + + dispatch_once(&once, ^{ + // Everything here is on one queue, so we sometimes get several notifications while busy doing something else. + lockStateCoalescingSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0, self.queue); + dispatch_source_set_event_handler(lockStateCoalescingSource, ^{ + [self sendReplyToPacket]; + }); + dispatch_activate(lockStateCoalescingSource); + }); + + if (self.notifyToken == NOTIFY_TOKEN_INVALID) { + notify_status = notify_register_dispatch(kMobileKeyBagLockStatusNotificationID, &token, self.queue, ^(__unused int t) { + dispatch_source_merge_data(lockStateCoalescingSource, 1); + }); + if (os_assumes_zero(notify_status) == NOTIFY_STATUS_OK) { + self.notifyToken = token; + } + } + + self.unlockTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.queue); + dispatch_source_set_timer(self.unlockTimer, dispatch_time(DISPATCH_TIME_NOW, WAIT_FOR_UNLOCK_DURATION * NSEC_PER_SEC), DISPATCH_TIME_FOREVER, 0); + dispatch_source_set_event_handler(self.unlockTimer, ^{ + [self stopWaitingForDeviceUnlock]; + [self deviceUnlockTimedOut]; + }); + dispatch_activate(self.unlockTimer); + + // double-check to prevent race condition, try again soon + if (MKBGetDeviceLockState(NULL) == kMobileKeyBagDeviceIsUnlocked) { + [self stopWaitingForDeviceUnlock]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5ull * NSEC_PER_SEC), self.queue, ^{ + [self sendReplyToPacket]; + }); + } +} + +- (void)stopWaitingForDeviceUnlock +{ + dispatch_assert_queue(self.queue); + + uint32_t notify_status; + + if (self.notifyToken != NOTIFY_TOKEN_INVALID) { + notify_status = notify_cancel(self.notifyToken); + os_assumes_zero(notify_status); + self.notifyToken = NOTIFY_TOKEN_INVALID; + } + + if (self.unlockTimer != nil) { + dispatch_source_cancel(self.unlockTimer); + self.unlockTimer = nil; + } +} +#endif /* !TARGET_OS_SIMULATOR */ + +#if TARGET_OS_IOS +- (void)scheduleGizmoPoke +{ + xpc_object_t criteria; + + criteria = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_string(criteria, XPC_ACTIVITY_PRIORITY, XPC_ACTIVITY_PRIORITY_MAINTENANCE); + xpc_dictionary_set_int64(criteria, XPC_ACTIVITY_DELAY, 0ll); + xpc_dictionary_set_int64(criteria, XPC_ACTIVITY_GRACE_PERIOD, 0ll); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_REPEATING, false); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_ALLOW_BATTERY, true); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_REQUIRES_CLASS_A, true); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_COMMUNICATES_WITH_PAIRED_DEVICE, true); + + os_log(OS_LOG_DEFAULT, "scheduling XPC Activity to inform gizmo of companion unlock"); + xpc_activity_register(OTPairingXPCActivityPoke, criteria, ^(xpc_activity_t activity) { + xpc_activity_state_t state = xpc_activity_get_state(activity); + if (state == XPC_ACTIVITY_STATE_RUN) { + dispatch_sync(self.queue, ^{ + os_log(OS_LOG_DEFAULT, "poking gizmo now"); + NSDictionary *message = @{ + OTPairingIDSKeyMessageType : @(OTPairingIDSMessageTypePoke), + }; + [self _sendMessage:message to:IDSDefaultPairedDevice identifier:nil expectReply:NO]; + }); + } + }); +} +#endif /* TARGET_OS_IOS */ + +#pragma mark Octagon Clique Status + +#if TARGET_OS_WATCH +- (bool)_octagonInClique +{ + __block bool result = false; + NSError *ctlError = nil; + + OTControl *ctl = [OTControl controlObject:true error:&ctlError]; + if (ctl != nil) { + OTOperationConfiguration *config = [OTOperationConfiguration new]; + config.useCachedAccountStatus = true; + [ctl fetchCliqueStatus:nil context:OTDefaultContext configuration:config reply:^(CliqueStatus cliqueStatus, NSError * _Nullable error) { + result = (cliqueStatus == CliqueStatusIn); + }]; + } else { + os_log(OS_LOG_DEFAULT, "failed to acquire OTControl: %@", ctlError); + } + + return result; +} +#endif /* TARGET_OS_WATCH */ + +@end diff --git a/keychain/otpaird/OTPairingSession.h b/keychain/otpaird/OTPairingSession.h new file mode 100644 index 00000000..da237c22 --- /dev/null +++ b/keychain/otpaird/OTPairingSession.h @@ -0,0 +1,25 @@ +#import +#import "OTPairingPacketContext.h" +#import "OTPairingService.h" + +#import "keychain/ot/OTDeviceInformationAdapter.h" + +@interface OTPairingSession : NSObject + +@property (readonly) NSString *identifier; +@property (readwrite) OTPairingPacketContext *packet; +@property (readonly) KCPairingChannel *channel; +@property (readwrite) NSString *sentMessageIdentifier; + +#if TARGET_OS_WATCH +@property OTPairingCompletionHandler completionHandler; +#endif /* TARGET_OS_WATCH */ + +#if !TARGET_OS_SIMULATOR +@property (readwrite) MKBAssertionRef lockAssertion; +#endif /* !TARGET_OS_SIMULATOR */ + +- (instancetype)initWithDeviceInfo:(OTDeviceInformationActualAdapter *)deviceInfo; +- (instancetype)initWithDeviceInfo:(OTDeviceInformationActualAdapter *)deviceInfo identifier:(NSString *)identifier; + +@end diff --git a/keychain/otpaird/OTPairingSession.m b/keychain/otpaird/OTPairingSession.m new file mode 100644 index 00000000..9444f1ca --- /dev/null +++ b/keychain/otpaird/OTPairingSession.m @@ -0,0 +1,55 @@ +#import + +#if !TARGET_OS_SIMULATOR +#import +#endif /* !TARGET_OS_SIMULATOR */ + +#import "OTPairingSession.h" + +@interface OTPairingSession () +@property (readwrite) NSString *identifier; +@property (readwrite) KCPairingChannel *channel; +@end + +@implementation OTPairingSession + +- (instancetype)initWithDeviceInfo:(OTDeviceInformationActualAdapter *)deviceInfo +{ + return [self initWithDeviceInfo:deviceInfo identifier:[[NSUUID UUID] UUIDString]]; +} + +- (instancetype)initWithDeviceInfo:(OTDeviceInformationActualAdapter *)deviceInfo identifier:(NSString *)identifier +{ + KCPairingChannelContext *channelContext = nil; + + self = [super init]; + if (self != nil) { + self.identifier = identifier; + + channelContext = [KCPairingChannelContext new]; + channelContext.uniqueClientID = [NSUUID UUID].UUIDString; + channelContext.uniqueDeviceID = [NSUUID UUID].UUIDString; + channelContext.intent = KCPairingIntent_Type_SilentRepair; + channelContext.model = deviceInfo.modelID; + channelContext.osVersion = deviceInfo.osVersion; + +#if TARGET_OS_WATCH + self.channel = [KCPairingChannel pairingChannelInitiator:channelContext]; +#elif TARGET_OS_IOS + self.channel = [KCPairingChannel pairingChannelAcceptor:channelContext]; +#endif + } + return self; +} + +- (void)dealloc +{ +#if !TARGET_OS_SIMULATOR + if (self.lockAssertion) { + CFRelease(self.lockAssertion); + self.lockAssertion = NULL; + } +#endif /* !TARGET_OS_SIMULATOR */ +} + +@end diff --git a/keychain/otpaird/com.apple.security.otpaird.iphoneos.plist b/keychain/otpaird/com.apple.security.otpaird.iphoneos.plist new file mode 100644 index 00000000..566201e9 --- /dev/null +++ b/keychain/otpaird/com.apple.security.otpaird.iphoneos.plist @@ -0,0 +1,21 @@ + + + + + EnablePressuredExit + + EnableTransactions + + Label + com.apple.security.otpaird + MachServices + + com.apple.private.alloy.octagon-idswake + + + POSIXSpawnType + Adaptive + Program + /usr/libexec/otpaird + + diff --git a/keychain/otpaird/com.apple.security.otpaird.watchos.plist b/keychain/otpaird/com.apple.security.otpaird.watchos.plist new file mode 100644 index 00000000..7c7f49e4 --- /dev/null +++ b/keychain/otpaird/com.apple.security.otpaird.watchos.plist @@ -0,0 +1,23 @@ + + + + + EnablePressuredExit + + EnableTransactions + + Label + com.apple.security.otpaird + MachServices + + com.apple.private.alloy.octagon-idswake + + com.apple.security.otpaird + + + POSIXSpawnType + Adaptive + Program + /usr/libexec/otpaird + + diff --git a/keychain/otpaird/main.m b/keychain/otpaird/main.m new file mode 100644 index 00000000..ec1ed214 --- /dev/null +++ b/keychain/otpaird/main.m @@ -0,0 +1,167 @@ +#import +#import +#import +#import +#if TARGET_OS_WATCH +#import +#import +#endif /* TARGET_OS_WATCH */ + +#import "OTPairingService.h" +#import "OTPairingConstants.h" + +#if TARGET_OS_WATCH +static void create_xpc_listener(xpc_handler_t handler); +static bool should_retry(NSError *error); +static void pairing_retry_register(bool checkin); +static void pairing_retry_unregister(void); +#endif /* TARGET_OS_WATCH */ + +int +main() +{ + static OTPairingService *service; + + @autoreleasepool { + service = [OTPairingService sharedService]; + } + +#if TARGET_OS_WATCH + /* Check in; handle a possibly-pending retry. */ + pairing_retry_register(true); + + create_xpc_listener(^(xpc_object_t message) { + xpc_object_t reply; + + reply = xpc_dictionary_create_reply(message); + + /* Received an explicit pairing request; remove retry activity if one exists. */ + pairing_retry_unregister(); + + [service initiatePairingWithCompletion:^(bool success, NSError *error) { + xpc_connection_t connection; + + if (success) { + os_log(OS_LOG_DEFAULT, "xpc-initiated pairing succeeded"); + } else { + os_log(OS_LOG_DEFAULT, "xpc-initiated pairing failed: %@", error); + } + + xpc_dictionary_set_bool(reply, OTPairingXPCKeySuccess, success); + if (error) { + NSData *errdata = [SecXPCHelper encodedDataFromError:error]; + xpc_dictionary_set_data(reply, OTPairingXPCKeyError, errdata.bytes, errdata.length); + } + connection = xpc_dictionary_get_remote_connection(reply); + xpc_connection_send_message(connection, reply); + + // Retry on failure - unless we were already in + if (!success && should_retry(error)) { + pairing_retry_register(false); + } + }]; + }); +#endif /* TARGET_OS_WATCH */ + + dispatch_main(); +} + +#if TARGET_OS_WATCH +static void +create_xpc_listener(xpc_handler_t handler) +{ + static xpc_connection_t listener; + + listener = xpc_connection_create_mach_service(OTPairingMachServiceName, NULL, XPC_CONNECTION_MACH_SERVICE_LISTENER); + xpc_connection_set_event_handler(listener, ^(xpc_object_t peer) { + if (xpc_get_type(peer) != XPC_TYPE_CONNECTION) { + return; + } + + // TODO: entitlement check + + xpc_connection_set_event_handler(peer, ^(xpc_object_t message) { + if (xpc_get_type(message) != XPC_TYPE_DICTIONARY) { + return; + } + + char *desc = xpc_copy_description(message); + os_log(OS_LOG_DEFAULT, "received xpc message: %s", desc); + free(desc); + + @autoreleasepool { + handler(message); + } + }); + xpc_connection_activate(peer); + }); + xpc_connection_activate(listener); +} + +static bool +should_retry(NSError *error) +{ + bool retry; + + if ([error.domain isEqualToString:OTPairingErrorDomain]) { + switch (error.code) { + case OTPairingErrorTypeAlreadyIn: + case OTPairingErrorTypeBusy: + retry = false; + break; + default: + retry = true; + break; + } + } else { + retry = true; + } + + return retry; +} + +static void +pairing_retry_register(bool checkin) +{ + xpc_object_t criteria; + + if (checkin) { + criteria = XPC_ACTIVITY_CHECK_IN; + } else { + os_log(OS_LOG_DEFAULT, "scheduling pairing retry"); + + pairing_retry_unregister(); + + criteria = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_string(criteria, XPC_ACTIVITY_PRIORITY, XPC_ACTIVITY_PRIORITY_MAINTENANCE); + xpc_dictionary_set_int64(criteria, XPC_ACTIVITY_INTERVAL, OTPairingXPCActivityInterval); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_REPEATING, true); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_ALLOW_BATTERY, true); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_REQUIRES_CLASS_A, true); + xpc_dictionary_set_bool(criteria, XPC_ACTIVITY_COMMUNICATES_WITH_PAIRED_DEVICE, true); + } + + xpc_activity_register(OTPairingXPCActivityIdentifier, criteria, ^(xpc_activity_t activity) { + xpc_activity_state_t state = xpc_activity_get_state(activity); + if (state == XPC_ACTIVITY_STATE_RUN) { + os_log(OS_LOG_DEFAULT, "triggered pairing attempt via XPC Activity"); + OTPairingService *service = [OTPairingService sharedService]; + [service initiatePairingWithCompletion:^(bool success, NSError *error) { + if (success) { + os_log(OS_LOG_DEFAULT, "Pairing retry succeeded"); + pairing_retry_unregister(); + } else { + os_log(OS_LOG_DEFAULT, "Pairing retry failed: %@", error); + // Activity repeats... + } + }]; + } + }); +} + +static void +pairing_retry_unregister(void) +{ + xpc_activity_unregister(OTPairingXPCActivityIdentifier); +} +#endif /* TARGET_OS_WATCH */ diff --git a/keychain/otpaird/otpaird.iphoneos.entitlements b/keychain/otpaird/otpaird.iphoneos.entitlements new file mode 100644 index 00000000..687c9a25 --- /dev/null +++ b/keychain/otpaird/otpaird.iphoneos.entitlements @@ -0,0 +1,37 @@ + + + + + com.apple.keystore.lockassertion + + com.apple.private.ids.messaging + + com.apple.private.alloy.octagon + + com.apple.private.octagon + + com.apple.security.exception.files.absolute-path.read-only + + /usr/libexec + + com.apple.security.exception.iokit-user-client-class + + AppleKeyStoreUserClient + + com.apple.security.exception.mach-lookup.global-name + + com.apple.security.octagon + com.apple.securityd.sos + + com.apple.security.ts.identity-services-client + + keychain-cloud-circle + + platform-application + + seatbelt-profiles + + temporary-sandbox + + + diff --git a/keychain/otpaird/otpaird.watchos.entitlements b/keychain/otpaird/otpaird.watchos.entitlements new file mode 100644 index 00000000..32082d1c --- /dev/null +++ b/keychain/otpaird/otpaird.watchos.entitlements @@ -0,0 +1,34 @@ + + + + + com.apple.keystore.lockassertion + + com.apple.private.ids.messaging + + com.apple.private.alloy.octagon + + com.apple.private.octagon + + com.apple.security.exception.files.absolute-path.read-only + + /usr/libexec + + com.apple.security.exception.iokit-user-client-class + + AppleKeyStoreUserClient + + com.apple.security.exception.mach-lookup.global-name + + com.apple.security.octagon + + com.apple.security.ts.identity-services-client + + platform-application + + seatbelt-profiles + + temporary-sandbox + + + diff --git a/keychain/tpctl/main.swift b/keychain/tpctl/main.swift new file mode 100644 index 00000000..4ea34015 --- /dev/null +++ b/keychain/tpctl/main.swift @@ -0,0 +1,793 @@ +import Foundation +import os + +let tplogDebug = OSLog(subsystem: "com.apple.security.trustedpeers", category: "debug") + +// This should definitely use the ArgumentParser library from the Utility package. +// However, right now that's not accessible from this code due to build system issues. +// Do it the hard way. + +let programName = CommandLine.arguments[0] +var args: ArraySlice = CommandLine.arguments[1...] + +var context: String = OTDefaultContext +var container: String = "com.apple.security.keychain" + +// Only used for prepare, but in the absence of a real command line library this is the easiest way to get them +var modelID: String? +var machineID: String? +var epoch: UInt64 = 1 +var bottleSalt: String = "" + +// Only used for join, establish and update +var preapprovedKeys: [Data]? +var deviceName: String? +var serialNumber: String? +var osVersion: String? +var policyVersion: NSNumber? +var policySecrets: [String: Data]? + +enum Command { + case dump + case depart + case distrust(Set) + case join(Data, Data) + case establish + case localReset + case prepare + case healthInquiry + case update + case reset + case validate + case viableBottles + case vouch(String, Data, Data, Data, Data) + case vouchWithBottle(String, Data, String) + case allow(Set, Bool) +} + +func printUsage() { + print("Usage:", (CommandLine.arguments[0] as NSString).lastPathComponent, + "[--container CONTAINER] [--context CONTEXT] COMMAND") + print() + print("Commands:") + print(" allow [--idms] MACHINEID ...") + print(" Set the (space-separated) list of machine IDs allowed in the account. If --idms is provided, append the IDMS trusted device list") + print(" dump Print the state of the world as this peer knows it") + print(" depart Attempt to depart the account and mark yourself as untrusted") + print(" distrust PEERID ... Distrust one or more peers by peer ID") + print(" establish Calls Cuttlefish Establish, creating a new account-wide trust arena with a single peer (previously generated with prepare") + print(" healthInquiry Request peers to check in with reportHealth") + print(" join VOUCHER VOUCHERSIG Join a circle using this (base64) voucher and voucherSig") + print(" local-reset Resets the local cuttlefish database, and ignores all previous information. Does not change anything off-device") + print(" prepare [--modelid MODELID] [--machineid MACHINEID] [--epoch EPOCH] [--bottlesalt BOTTLESALT]") + print(" Creates a new identity and returns its attributes. If not provided, modelid and machineid will be given some defaults (ignoring the local device)") + print(" update Fetch new information from Cuttlefish, and perform any actions this node deems necessary") + print(" validate Vvalidate SOS and Octagon data structures from server side") + print(" viable-bottles Show bottles in preference order of server") + print(" vouch PEERID PERMANENTINFO PERMANENTINFOSIG STABLEINFO STABLEINFOSIG") + print(" Create a voucher for a new peer. permanentInfo, permanentInfoSig, stableInfo, stableInfoSig should be base64 data") + print(" vouchWithBottle BOTTLEID ENTROPY SALT") + print(" Create a voucher for the ego peer using the given bottle. entropy should be base64 data.") + print(" reset Resets Cuttlefish for this account") + print() + print("Options applying to `join', `establish' and `update'") + print(" --preapprove KEY... Sets the (space-separated base64) list of public keys that are preapproved.") + print(" --device-name NAME Sets the device name string.") + print(" --os-version VERSION Sets the OS version string.") + print(" --policy-version VERSION Sets the policy version.") + print(" --policy-secret NAME DATA Adds a name-value pair to policy secrets. DATA must be base-64.") + print("Options applying to `vouch' and `join'") + print(" --config FILE Configuration file with json data.") + print() +} + +func exitUsage(_ code: Int32) -> Never { + printUsage() + exit(code) +} + +func extractJSONData(dictionary: [String: Any], key: String) -> Data? { + guard let b64string = dictionary[key] as? String else { + return nil + } + guard let data = Data(base64Encoded: b64string) else { + return nil + } + return data +} + +func jsonFromFile(filename: String) -> [String: Any] { + let data: Data + let json: [String: Any]? + do { + data = try Data(contentsOf: URL(fileURLWithPath: filename), options: .mappedIfSafe) + json = try JSONSerialization.jsonObject(with: data) as? [String: Any] + } catch { + print("Error: failed to parse json file \(filename): \(error)") + exit(EXIT_FAILURE) + } + guard let dictionary = json else { + print("Error: failed to get dictionary in file \(filename)") + exit(EXIT_FAILURE) + } + return dictionary +} + +var commands: [Command] = [] +var argIterator = args.makeIterator() +var configurationData: [String: Any]? + +while let arg = argIterator.next() { + switch arg { + case "--container": + let newContainer = argIterator.next() + guard newContainer != nil else { + print("Error: --container takes a value") + print() + exitUsage(1) + } + container = newContainer! + + case "--context": + let newContext = argIterator.next() + guard newContext != nil else { + print("Error: --context takes a value") + print() + exitUsage(1) + } + context = newContext! + + case "--modelid": + let newModelID = argIterator.next() + guard newModelID != nil else { + print("Error: --modelid takes a value") + print() + exitUsage(1) + } + modelID = newModelID! + + case "--machineid": + let newMachineID = argIterator.next() + guard newMachineID != nil else { + print("Error: --machineid takes a value") + print() + exitUsage(1) + } + machineID = newMachineID! + + case "--epoch": + let newEpoch = argIterator.next() + guard newEpoch != nil else { + print("Error: --epoch takes a value") + print() + exitUsage(1) + } + epoch = UInt64(newEpoch!)! + + case "--bottlesalt": + let salt = argIterator.next() + guard salt != nil else { + print("Error: --bottlesalt takes a value") + print() + exitUsage(1) + } + bottleSalt = salt! + + case "--preapprove": + var newPreapprovedKeys: [Data] = [] + while let arg = argIterator.next() { + let data = Data(base64Encoded: arg) + guard let key = data else { + print("Error: preapproved keys must be base-64 data") + exitUsage(1) + } + newPreapprovedKeys.append(key) + } + preapprovedKeys = newPreapprovedKeys + + case "--device-name": + guard let newDeviceName = argIterator.next() else { + print("Error: --device-name takes a string argument") + exitUsage(1) + } + deviceName = newDeviceName + + case "--serial-number": + guard let newSerialNumber = argIterator.next() else { + print("Error: --serial-number takes a string argument") + exitUsage(1) + } + serialNumber = newSerialNumber + + case "--os-version": + guard let newOsVersion = argIterator.next() else { + print("Error: --os-version takes a string argument") + exitUsage(1) + } + osVersion = newOsVersion + + case "--policy-version": + guard let newPolicyVersion = UInt64(argIterator.next() ?? "") else { + print("Error: --policy-version takes an integer argument") + exitUsage(1) + } + policyVersion = NSNumber(value: newPolicyVersion) + + case "--policy-secret": + guard let name = argIterator.next(), let dataBase64 = argIterator.next() else { + print("Error: --policy-secret takes a name and data") + exitUsage(1) + } + guard let data = Data(base64Encoded: dataBase64) else { + print("Error: --policy-secret data must be base-64") + exitUsage(1) + } + if nil == policySecrets { + policySecrets = [:] + } + policySecrets![name] = data + + case "--config": + guard let filename = argIterator.next() else { + print("Error: --config file argument missing") + exitUsage(1) + } + + configurationData = jsonFromFile(filename: filename) + + case "--help": + exitUsage(0) + + case "dump": + commands.append(.dump) + + case "depart": + commands.append(.depart) + + case "distrust": + var peerIDs = Set() + while let arg = argIterator.next() { + peerIDs.insert(arg) + } + commands.append(.distrust(peerIDs)) + + case "establish": + commands.append(.establish) + + case "join": + let voucher: Data + let voucherSig: Data + + if let configuration = configurationData { + guard let voucherData = extractJSONData(dictionary: configuration, key: "voucher") else { + print("Error: join needs a voucher") + exitUsage(EXIT_FAILURE) + } + guard let voucherSigData = extractJSONData(dictionary: configuration, key: "voucherSig") else { + print("Error: join needs a voucherSig") + exitUsage(EXIT_FAILURE) + } + voucher = voucherData + voucherSig = voucherSigData + + } else { + guard let voucherBase64 = argIterator.next() else { + print("Error: join needs a voucher") + print() + exitUsage(1) + } + + guard let voucherData = Data(base64Encoded: voucherBase64) else { + print("Error: voucher must be base-64 data") + print() + exitUsage(1) + } + + guard let voucherSigBase64 = argIterator.next() else { + print("Error: join needs a voucherSig") + print() + exitUsage(1) + } + + guard let voucherSigData = Data(base64Encoded: voucherSigBase64) else { + print("Error: voucherSig must be base-64 data") + print() + exitUsage(1) + } + + voucher = voucherData + voucherSig = voucherSigData + } + commands.append(.join(voucher, voucherSig)) + + case "local-reset": + commands.append(.localReset) + + case "prepare": + commands.append(.prepare) + + case "healthInquiry": + commands.append(.healthInquiry) + + case "reset": + commands.append(.reset) + + case "update": + commands.append(.update) + + case "validate": + commands.append(.validate) + + case "viable-bottles": + commands.append(.viableBottles) + + case "vouch": + let peerID: String + let permanentInfo: Data + let permanentInfoSig: Data + let stableInfo: Data + let stableInfoSig: Data + + if let configuration = configurationData { + guard let peerIDString = configuration["peerID"] as? String else { + print("Error: vouch needs a peerID") + exitUsage(EXIT_FAILURE) + } + + guard let permanentInfoData = extractJSONData(dictionary: configuration, key: "permanentInfo") else { + print("Error: vouch needs a permanentInfo") + exitUsage(EXIT_FAILURE) + } + guard let permanentInfoSigData = extractJSONData(dictionary: configuration, key: "permanentInfoSig") else { + print("Error: vouch needs a permanentInfoSig") + exitUsage(EXIT_FAILURE) + } + guard let stableInfoData = extractJSONData(dictionary: configuration, key: "stableInfo") else { + print("Error: vouch needs a stableInfo") + exitUsage(EXIT_FAILURE) + } + guard let stableInfoSigData = extractJSONData(dictionary: configuration, key: "stableInfoSig") else { + print("Error: vouch needs a stableInfoSig") + exitUsage(EXIT_FAILURE) + } + + peerID = peerIDString + permanentInfo = permanentInfoData + permanentInfoSig = permanentInfoSigData + stableInfo = stableInfoData + stableInfoSig = stableInfoSigData + + } else { + + guard let peerIDString = argIterator.next() else { + print("Error: vouch needs a peerID") + print() + exitUsage(1) + } + guard let permanentInfoBase64 = argIterator.next() else { + print("Error: vouch needs a permanentInfo") + print() + exitUsage(1) + } + guard let permanentInfoSigBase64 = argIterator.next() else { + print("Error: vouch needs a permanentInfoSig") + print() + exitUsage(1) + } + guard let stableInfoBase64 = argIterator.next() else { + print("Error: vouch needs a stableInfo") + print() + exitUsage(1) + } + guard let stableInfoSigBase64 = argIterator.next() else { + print("Error: vouch needs a stableInfoSig") + print() + exitUsage(1) + } + + guard let permanentInfoData = Data(base64Encoded: permanentInfoBase64) else { + print("Error: permanentInfo must be base-64 data") + print() + exitUsage(1) + } + + guard let permanentInfoSigData = Data(base64Encoded: permanentInfoSigBase64) else { + print("Error: permanentInfoSig must be base-64 data") + print() + exitUsage(1) + } + guard let stableInfoData = Data(base64Encoded: stableInfoBase64) else { + print("Error: stableInfo must be base-64 data") + print() + exitUsage(1) + } + + guard let stableInfoSigData = Data(base64Encoded: stableInfoSigBase64) else { + print("Error: stableInfoSig must be base-64 data") + print() + exitUsage(1) + } + + peerID = peerIDString + permanentInfo = permanentInfoData + permanentInfoSig = permanentInfoSigData + stableInfo = stableInfoData + stableInfoSig = stableInfoSigData + } + + commands.append(.vouch(peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig)) + + case "vouchWithBottle": + guard let bottleID = argIterator.next() else { + print("Error: vouchWithBottle needs a bottleID") + print() + exitUsage(1) + } + guard let entropyBase64 = argIterator.next() else { + print("Error: vouchWithBottle needs entropy") + print() + exitUsage(1) + } + guard let salt = argIterator.next() else { + print("Error: vouchWithBottle needs a salt") + print() + exitUsage(1) + } + + guard let entropy = Data(base64Encoded: entropyBase64) else { + print("Error: entropy must be base-64 data") + print() + exitUsage(1) + } + + commands.append(.vouchWithBottle(bottleID, entropy, salt)) + + case "allow": + var machineIDs = Set() + var performIDMS = false + while let arg = argIterator.next() { + if(arg == "--idms") { + performIDMS = true + } else { + machineIDs.insert(arg) + } + } + commands.append(.allow(machineIDs, performIDMS)) + + default: + print("Unknown argument:", arg) + exitUsage(1) + } +} + +if commands.count == 0 { + exitUsage(0) +} + +// JSONSerialization has no idea how to handle NSData. Help it out. +func cleanDictionaryForJSON(_ d: [AnyHashable: Any]) -> [AnyHashable: Any] { + func cleanValue(_ value: Any) -> Any { + switch value { + case let subDict as [AnyHashable: Any]: + return cleanDictionaryForJSON(subDict) + case let subArray as [Any]: + return subArray.map(cleanValue) + case let data as Data: + return data.base64EncodedString() + default: + return value + } + } + + return d.mapValues(cleanValue) +} + +// Bring up a connection to TrustedPeersHelper +let connection = NSXPCConnection(serviceName: "com.apple.TrustedPeersHelper") +connection.remoteObjectInterface = TrustedPeersHelperSetupProtocol(NSXPCInterface(with: TrustedPeersHelperProtocol.self)) +connection.resume() +let tpHelper = connection.synchronousRemoteObjectProxyWithErrorHandler { error in print("Unable to connect to TPHelper:", error) } as! TrustedPeersHelperProtocol + +for command in commands { + switch command { + case .dump: + os_log("dumping (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.dump(withContainer: container, context: context) { reply, error in + guard error == nil else { + print("Error dumping:", error!) + return + } + + if let reply = reply { + do { + print(try TPCTLObjectiveC.jsonSerialize(cleanDictionaryForJSON(reply))) + } catch { + print("Error encoding JSON: \(error)") + } + } else { + print("Error: no results, but no error either?") + } + } + + case .depart: + os_log("departing (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.departByDistrustingSelf(withContainer: container, context: context) { error in + guard error == nil else { + print("Error departing:", error!) + return + } + + print("Depart successful") + } + + case .distrust(let peerIDs): + os_log("distrusting %@ for (%@, %@)", log: tplogDebug, type: .default, peerIDs, container, context) + tpHelper.distrustPeerIDs(withContainer: container, context: context, peerIDs: peerIDs) { error in + guard error == nil else { + print("Error distrusting:", error!) + return + } + print("Distrust successful") + } + + case .join(let voucher, let voucherSig): + os_log("joining (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.join(withContainer: container, + context: context, + voucherData: voucher, + voucherSig: voucherSig, + ckksKeys: [], + tlkShares: [], + preapprovedKeys: preapprovedKeys ?? []) { peerID, _, error in + guard error == nil else { + print("Error joining:", error!) + return + } + print("Join successful. PeerID:", peerID!) + } + + case .establish: + os_log("establishing (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.establish(withContainer: container, + context: context, + ckksKeys: [], + tlkShares: [], + preapprovedKeys: preapprovedKeys ?? []) { peerID, _, error in + guard error == nil else { + print("Error establishing:", error!) + return + } + print("Establish successful. Peer ID:", peerID!) + } + + case .healthInquiry: + os_log("healthInquiry (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.pushHealthInquiry(withContainer: container, context: context) { error in + guard error == nil else { + print("Error healthInquiry: \(String(describing: error))") + return + } + print("healthInquiry successful") + } + + case .localReset: + os_log("local-reset (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.localReset(withContainer: container, context: context) { error in + guard error == nil else { + print("Error resetting:", error!) + return + } + + os_log("local-reset (%@, %@): successful", log: tplogDebug, type: .default, container, context) + print("Local reset successful") + } + + case .prepare: + os_log("preparing (%@, %@)", log: tplogDebug, type: .default, container, context) + + if machineID == nil { + let anisetteController = AKAnisetteProvisioningController() + + let anisetteData = try anisetteController.anisetteData() + machineID = anisetteData.machineID + guard machineID != nil else { + print("failed to get machineid from anisette data") + abort() + } + } + + let deviceInfo = OTDeviceInformationActualAdapter() + + tpHelper.prepare(withContainer: container, + context: context, + epoch: epoch, + machineID: machineID!, + bottleSalt: bottleSalt, + bottleID: UUID().uuidString, + modelID: modelID ?? deviceInfo.modelID(), + deviceName: deviceName ?? deviceInfo.deviceName(), + serialNumber: serialNumber ?? deviceInfo.serialNumber(), + osVersion: osVersion ?? deviceInfo.osVersion(), + policyVersion: policyVersion, + policySecrets: policySecrets, + signingPrivKeyPersistentRef: nil, + encPrivKeyPersistentRef: nil) { + peerID, permanentInfo, permanentInfoSig, stableInfo, stableInfoSig, error in + guard error == nil else { + print("Error preparing:", error!) + return + } + + let result = [ + "peerID": peerID!, + "permanentInfo": permanentInfo!.base64EncodedString(), + "permanentInfoSig": permanentInfoSig!.base64EncodedString(), + "stableInfo": stableInfo!.base64EncodedString(), + "stableInfoSig": stableInfoSig!.base64EncodedString(), + "machineID": machineID!, + ] + do { + print(try TPCTLObjectiveC.jsonSerialize(cleanDictionaryForJSON(result))) + } catch { + print("Error encoding JSON: \(error)") + } + } + + case .update: + os_log("updating (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.update(withContainer: container, + context: context, + deviceName: deviceName, + serialNumber: serialNumber, + osVersion: osVersion, + policyVersion: policyVersion, + policySecrets: policySecrets) { _, error in + guard error == nil else { + print("Error updating:", error!) + return + } + + print("Update complete") + } + + case .reset: + os_log("resetting (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.reset(withContainer: container, context: context) { error in + guard error == nil else { + print("Error during reset:", error!) + return + } + + print("Reset complete") + } + + case .validate: + os_log("validate (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.validatePeers(withContainer: container, context: context) { reply, error in + guard error == nil else { + print("Error validating:", error!) + return + } + + if let reply = reply { + do { + print(try TPCTLObjectiveC.jsonSerialize(cleanDictionaryForJSON(reply))) + } catch { + print("Error encoding JSON: \(error)") + } + } else { + print("Error: no results, but no error either?") + } + } + + case .viableBottles: + os_log("viableBottles (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.fetchViableBottles(withContainer: container, context: context) { sortedBottleIDs, partialBottleIDs, error in + guard error == nil else { + print("Error fetching viable bottles:", error!) + return + } + var result: [String: [String]] = [:] + result["sortedBottleIDs"] = sortedBottleIDs + result["partialBottleIDs"] = partialBottleIDs + do { + print(try TPCTLObjectiveC.jsonSerialize(cleanDictionaryForJSON(result))) + } catch { + print("Error encoding JSON: \(error)") + } + } + + case .vouch(let peerID, let permanentInfo, let permanentInfoSig, let stableInfo, let stableInfoSig): + os_log("vouching (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.vouch(withContainer: container, + context: context, + peerID: peerID, + permanentInfo: permanentInfo, + permanentInfoSig: permanentInfoSig, + stableInfo: stableInfo, + stableInfoSig: stableInfoSig, + ckksKeys: [] + ) { voucher, voucherSig, error in + guard error == nil else { + print("Error during vouch:", error!) + return + } + + do { + let result = ["voucher": voucher!.base64EncodedString(), "voucherSig": voucherSig!.base64EncodedString()] + print(try TPCTLObjectiveC.jsonSerialize(cleanDictionaryForJSON(result))) + } catch { + print("Error during processing vouch results: \(error)") + } + } + + case .vouchWithBottle(let bottleID, let entropy, let salt): + os_log("vouching with bottle (%@, %@)", log: tplogDebug, type: .default, container, context) + tpHelper.vouchWithBottle(withContainer: container, + context: context, + bottleID: bottleID, + entropy: entropy, + bottleSalt: salt, + tlkShares: []) { voucher, voucherSig, error in + guard error == nil else { + print("Error during vouchWithBottle", error!) + return + } + do { + let result = ["voucher": voucher!.base64EncodedString(), "voucherSig": voucherSig!.base64EncodedString()] + print(try TPCTLObjectiveC.jsonSerialize(cleanDictionaryForJSON(result))) + } catch { + print("Error during processing vouch results: \(error)") + } + } + + case .allow(let machineIDs, let performIDMS): + os_log("allow-listing (%@, %@)", log: tplogDebug, type: .default, container, context) + + var idmsDeviceIDs: Set = Set() + + if(performIDMS) { + let store = ACAccountStore() + guard let account = store.aa_primaryAppleAccount() else { + print("Unable to fetch primary Apple account!") + abort() + } + + let requestArguments = AKDeviceListRequestContext() + requestArguments.altDSID = account.aa_altDSID + requestArguments.services = [AKServiceNameiCloud] + + guard let controller = AKAppleIDAuthenticationController() else { + print("Unable to create AKAppleIDAuthenticationController!") + abort() + } + let semaphore = DispatchSemaphore(value: 0) + + controller.fetchDeviceList(with: requestArguments) { deviceList, error in + guard error == nil else { + print("Unable to fetch IDMS device list: \(error!)") + abort() + } + guard let deviceList = deviceList else { + print("IDMS returned empty device list") + return + } + + idmsDeviceIDs = Set(deviceList.map { $0.machineId }) + semaphore.signal() + } + semaphore.wait() + } + + let allMachineIDs = machineIDs.union(idmsDeviceIDs) + print("Setting allowed machineIDs to \(allMachineIDs)") + tpHelper.setAllowedMachineIDsWithContainer(container, context: context, allowedMachineIDs: allMachineIDs) { listChanged, error in + guard error == nil else { + print("Error during allow:", error!) + return + } + + print("Allow complete, differences: \(listChanged)") + } + } +} diff --git a/keychain/tpctl/tpctl-bridging-header.h b/keychain/tpctl/tpctl-bridging-header.h new file mode 100644 index 00000000..241e916e --- /dev/null +++ b/keychain/tpctl/tpctl-bridging-header.h @@ -0,0 +1,17 @@ + +#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h" +#import "tpctl-objc.h" +#import + +#import "keychain/ot/OTDeviceInformationAdapter.h" + +// Needed to interface with IDMS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#import +#import +#import +#import +#pragma clang diagnostic pop + +#import diff --git a/keychain/tpctl/tpctl-entitlements.plist b/keychain/tpctl/tpctl-entitlements.plist new file mode 100644 index 00000000..9a37aacf --- /dev/null +++ b/keychain/tpctl/tpctl-entitlements.plist @@ -0,0 +1,12 @@ + + + + + com.apple.accounts.appleaccount.fullaccess + + com.apple.authkit.client.private + + com.apple.private.trustedpeershelper.client + + + diff --git a/keychain/tpctl/tpctl-objc.h b/keychain/tpctl/tpctl-objc.h new file mode 100644 index 00000000..775698f9 --- /dev/null +++ b/keychain/tpctl/tpctl-objc.h @@ -0,0 +1,13 @@ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TPCTLObjectiveC : NSObject + ++ (BOOL)catchNSException:(void(^)(void))block error:(NSError**)error; ++ (NSString* _Nullable)jsonSerialize:(id)something error:(NSError**)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/keychain/tpctl/tpctl-objc.m b/keychain/tpctl/tpctl-objc.m new file mode 100644 index 00000000..817356d2 --- /dev/null +++ b/keychain/tpctl/tpctl-objc.m @@ -0,0 +1,55 @@ + +#import "tpctl-objc.h" + +@implementation TPCTLObjectiveC + ++ (BOOL)catchNSException:(void(^)(void))block error:(NSError**)error { + @try { + block(); + return true; + } + @catch(NSException* exception) { + if(error) { + NSMutableDictionary* ui = exception.userInfo ? [exception.userInfo mutableCopy] : [NSMutableDictionary dictionary]; + if(exception.reason) { + ui[NSLocalizedDescriptionKey] = exception.reason; + } + *error = [NSError errorWithDomain:exception.name code:0 userInfo:ui]; + } + return false; + } +} + ++ (NSString* _Nullable)jsonSerialize:(id)something error:(NSError**)error { + @try { + NSError* localError = nil; + NSData* jsonData = [NSJSONSerialization dataWithJSONObject:something options:(NSJSONWritingPrettyPrinted | NSJSONWritingSortedKeys) error:&localError]; + if(!jsonData || localError) { + if(error) { + *error = localError; + } + return nil; + } + + NSString* utf8String = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + if(!utf8String) { + if(error) { + *error = [NSError errorWithDomain:@"text" code:0 userInfo:@{NSLocalizedDescriptionKey: @"JSON data could not be decoded as UTF8"}]; + } + return nil; + } + return utf8String; + } + @catch(NSException* exception) { + if(error) { + NSMutableDictionary* ui = exception.userInfo ? [exception.userInfo mutableCopy] : [NSMutableDictionary dictionary]; + if(exception.reason) { + ui[NSLocalizedDescriptionKey] = exception.reason; + } + *error = [NSError errorWithDomain:exception.name code:0 userInfo:ui]; + } + return nil; + } +} + +@end diff --git a/keychain/tpctl/tpctl.8 b/keychain/tpctl/tpctl.8 new file mode 100644 index 00000000..09799738 --- /dev/null +++ b/keychain/tpctl/tpctl.8 @@ -0,0 +1,28 @@ +.Dd April 24, 2018 +.Os +.Dt tpctl 8 +.Sh NAME +.Nm tpctl +.Nd manage trusted peers as part of keychain syncing +.Sh SYNOPSIS +manage trusted peers as part of keychain syncing +.Sh DESCRIPTION +.Sh RETURN VALUES +return 0 on success, all other exit code are failures. +.\" .Sh ENVIRONMENT +.\" .Sh FILES +.\" .Sh EXAMPLES +.\" This next command is for sections 1, 6, 7, 8 and 9 only +.\" (command return values (to shell) and +.\" fprintf/stderr type diagnostics). +.\" .Sh DIAGNOSTICS +.\" .Sh COMPATIBILITY +.\" This next command is for sections 2, 3 and 9 error +.\" and signal handling only. +.\" .Sh ERRORS +.Sh SEE ALSO +.Xr secd 8 +.\" .Sh STANDARDS +.\" .Sh HISTORY +.\" .Sh AUTHORS +.\" .Sh BUGS diff --git a/keychain/tppolicy/main.m b/keychain/tppolicy/main.m new file mode 100644 index 00000000..f5ac4678 --- /dev/null +++ b/keychain/tppolicy/main.m @@ -0,0 +1,93 @@ +// +// main.m +// tppolicy +// +// Created by Ben Williamson on 7/13/18. +// + +#import +#import + +int main(int argc, const char * argv[]) +{ + NSArray *docs + = @[ + [TPPolicyDocument policyDocumentWithVersion:1 + modelToCategory:@[ + @{ @"prefix": @"iPhone", @"category": @"full" }, + @{ @"prefix": @"iPad", @"category": @"full" }, + @{ @"prefix": @"Mac", @"category": @"full" }, + @{ @"prefix": @"iMac", @"category": @"full" }, + @{ @"prefix": @"AppleTV", @"category": @"tv" }, + @{ @"prefix": @"Watch", @"category": @"watch" }, + ] + categoriesByView:@{ + @"WiFi": @[ @"full", @"tv", @"watch" ], + @"SafariCreditCards": @[ @"full" ], + @"PCSEscrow": @[ @"full" ] + } + introducersByCategory:@{ + @"full": @[ @"full" ], + @"tv": @[ @"full", @"tv" ], + @"watch": @[ @"full", @"watch" ] + } + redactions:@{} + keyViewMapping:@[] + hashAlgo:kTPHashAlgoSHA256], + [TPPolicyDocument policyDocumentWithVersion:2 + modelToCategory:@[ + @{ @"prefix": @"iCycle", @"category": @"full" }, // new + @{ @"prefix": @"iPhone", @"category": @"full" }, + @{ @"prefix": @"iPad", @"category": @"full" }, + @{ @"prefix": @"Mac", @"category": @"full" }, + @{ @"prefix": @"iMac", @"category": @"full" }, + @{ @"prefix": @"AppleTV", @"category": @"tv" }, + @{ @"prefix": @"Watch", @"category": @"watch" }, + ] + categoriesByView:@{ + @"WiFi": @[ @"full", @"tv", @"watch" ], + @"SafariCreditCards": @[ @"full" ], + @"PCSEscrow": @[ @"full" ] + } + introducersByCategory:@{ + @"full": @[ @"full" ], + @"tv": @[ @"full", @"tv" ], + @"watch": @[ @"full", @"watch" ] + } + redactions:@{} + keyViewMapping:@[] + hashAlgo:kTPHashAlgoSHA256], + [TPPolicyDocument policyDocumentWithVersion:3 + modelToCategory:@[ + @{ @"prefix": @"Watch7", @"category": @"full" }, // upgraded + @{ @"prefix": @"iCycle", @"category": @"full" }, + @{ @"prefix": @"iPhone", @"category": @"full" }, + @{ @"prefix": @"iPad", @"category": @"full" }, + @{ @"prefix": @"Mac", @"category": @"full" }, + @{ @"prefix": @"iMac", @"category": @"full" }, + @{ @"prefix": @"AppleTV", @"category": @"tv" }, + @{ @"prefix": @"Watch", @"category": @"watch" }, + ] + categoriesByView:@{ + @"WiFi": @[ @"full", @"tv", @"watch" ], + @"SafariCreditCards": @[ @"full" ], + @"PCSEscrow": @[ @"full" ] + } + introducersByCategory:@{ + @"full": @[ @"full" ], + @"tv": @[ @"full", @"tv" ], + @"watch": @[ @"full", @"watch" ] + } + redactions:@{} + keyViewMapping:@[] + hashAlgo:kTPHashAlgoSHA256], + ]; + + for (TPPolicyDocument *doc in docs) { + NSString *base64 = [doc.protobuf base64EncodedStringWithOptions:0]; + printf("policyVersion: %llu,\n", doc.policyVersion); + printf("policyHash: \"%s\",\n", doc.policyHash.UTF8String); + printf("policyData: \"%s\"\n", base64.UTF8String); + } + return 0; +} diff --git a/libsecurity_smime/lib/CMSDecoder.c b/libsecurity_smime/lib/CMSDecoder.c index d6a1037d..8ac1228c 100644 --- a/libsecurity_smime/lib/CMSDecoder.c +++ b/libsecurity_smime/lib/CMSDecoder.c @@ -25,7 +25,8 @@ * CMSDecoder.c - Interface for decoding CMS messages. */ -#include "CMSDecoder.h" +#include +#include #include "CMSUtils.h" #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -295,7 +297,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; @@ -398,7 +402,7 @@ OSStatus CMSDecoderCopySignerStatus( SecTrustRef *secTrust, /* optional; RETURNED */ OSStatus *certVerifyResultCode) /* optional; RETURNED */ { - if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final) || (!policyOrArray)) { + if((cmsDecoder == NULL) || (cmsDecoder->decState != DS_Final) || (!policyOrArray) || !signerStatus) { return errSecParam; } @@ -463,8 +467,7 @@ OSStatus CMSDecoderCopySignerStatus( if(secTrust != NULL) { *secTrust = theTrust; /* we'll release our reference at the end */ - if (theTrust) - CFRetain(theTrust); + CFRetainSafe(theTrust); } SecCmsSignerInfoRef signerInfo = SecCmsSignedDataGetSignerInfo(cmsDecoder->signedData, (int)signerIndex); diff --git a/libsecurity_smime/lib/CMSEncoder.c b/libsecurity_smime/lib/CMSEncoder.c index 171527e8..8fc6d1d9 100644 --- a/libsecurity_smime/lib/CMSEncoder.c +++ b/libsecurity_smime/lib/CMSEncoder.c @@ -25,7 +25,8 @@ * CMSEncoder.c - encode, sign, and/or encrypt CMS messages. */ -#include "CMSEncoder.h" +#include +#include #include "CMSUtils.h" #include #include @@ -461,6 +462,9 @@ static OSStatus cmsSetupForSignedData( case kCMSCertificateChainWithRoot: chainMode = SecCmsCMCertChainWithRoot; break; + case kCMSCertificateChainWithRootOrFail: + chainMode = SecCmsCMCertChainWithRootOrFail; + break; default: break; } @@ -1085,6 +1089,7 @@ OSStatus CMSEncoderSetCertificateChainMode( case kCMSCertificateSignerOnly: case kCMSCertificateChain: case kCMSCertificateChainWithRoot: + case kCMSCertificateChainWithRootOrFail: break; default: return errSecParam; diff --git a/libsecurity_smime/lib/SecCmsBase.h b/libsecurity_smime/lib/SecCmsBase.h deleted file mode 100644 index c39fb5b9..00000000 --- a/libsecurity_smime/lib/SecCmsBase.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010-2011 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 SecCmsBase.h - @Copyright (c) 2004,2008,2010-2011 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSBASE_H_ -#define _SECURITY_SECCMSBASE_H_ 1 - -#include -#include -#include - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - @typedef - @discussion XXX We need to remove these from the API and move them back to secoidt.h. - */ -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 - @discussion XXX This should probably move to SecKey.h - */ -typedef void * SecSymmetricKeyRef; - -/*! - @typedef - @discussion XXX This should probably move to SecKey.h - */ -typedef SecKeyRef SecPublicKeyRef; - -/*! - @typedef - @discussion XXX This should probably move to SecKey.h - */ -typedef SecKeyRef SecPrivateKeyRef; - -/*! - @typedef - */ -typedef void(*PK11PasswordFunc)(void); - -/*! - @typedef - */ -typedef struct SecCmsMessageStr *SecCmsMessageRef; - -/*! - @typedef - */ -typedef struct SecCmsContentInfoStr *SecCmsContentInfoRef; - -/*! - @typedef - */ -typedef struct SecCmsSignedDataStr *SecCmsSignedDataRef; - -/*! - @typedef - */ -typedef struct SecCmsSignerInfoStr *SecCmsSignerInfoRef; - -/*! - @typedef - */ -typedef struct SecCmsEnvelopedDataStr *SecCmsEnvelopedDataRef; - -/*! - @typedef - */ -typedef struct SecCmsRecipientInfoStr *SecCmsRecipientInfoRef; - -/*! - @typedef - */ -typedef struct SecCmsDigestedDataStr *SecCmsDigestedDataRef; - -/*! - @typedef - */ -typedef struct SecCmsEncryptedDataStr *SecCmsEncryptedDataRef; - -/*! - @typedef - */ -typedef struct SecCmsDecoderStr *SecCmsDecoderRef; - -/*! - @typedef - */ -typedef struct SecCmsEncoderStr *SecCmsEncoderRef; - -/*! - @typedef - */ -typedef struct SecCmsDigestContextStr *SecCmsDigestContextRef; - - -/*! - @typedef - @discussion Type of function passed to SecCmsDecode or SecCmsDecoderStart. - If specified, this is where the content bytes (only) will be "sent" as they are recovered during the decoding. - And: - Type of function passed to SecCmsEncode or SecCmsEncoderStart. - This is where the DER-encoded bytes will be "sent". - - XXX Should just combine this with SecCmsEncoderContentCallback type and use a simpler, common name. - */ -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 - */ -typedef enum { - SecCmsVSUnverified = 0, - SecCmsVSGoodSignature = 1, - SecCmsVSBadSignature = 2, - SecCmsVSDigestMismatch = 3, - SecCmsVSSigningCertNotFound = 4, - SecCmsVSSigningCertNotTrusted = 5, - SecCmsVSSignatureAlgorithmUnknown = 6, - SecCmsVSSignatureAlgorithmUnsupported = 7, - SecCmsVSMalformedSignature = 8, - SecCmsVSProcessingError = 9 -} SecCmsVerificationStatus; - -/*! - @enum SecCmsCertChainMode - */ -typedef enum { - SecCmsCMNone = 0, - SecCmsCMCertOnly = 1, - SecCmsCMCertChain = 2, - SecCmsCMCertChainWithRoot = 3 -} SecCmsCertChainMode; - -/*! - @enum - @discussion XXX This should be replaced with SecPolicyRefs - */ -typedef enum SECCertUsageEnum { - certUsageSSLClient = 0, - certUsageSSLServer = 1, - certUsageSSLServerWithStepUp = 2, - certUsageSSLCA = 3, - certUsageEmailSigner = 4, - certUsageEmailRecipient = 5, - certUsageObjectSigner = 6, - certUsageUserCertImport = 7, - certUsageVerifyCA = 8, - certUsageProtectedObjectSigner = 9, - certUsageStatusResponder = 10, - certUsageAnyCA = 11 -} SECCertUsage; - - -/*! - @enum SECOidTag - @abstract Misc object IDs - these numbers are for convenient handling. - @discussion They are mapped into real object IDs - NOTE: the order of these entries must mach the array "oids" of SECOidData in util/secoid.c. - */ -typedef enum { - SEC_OID_UNKNOWN = 0, - SEC_OID_MD2 = 1, - SEC_OID_MD4 = 2, - SEC_OID_MD5 = 3, - SEC_OID_SHA1 = 4, - SEC_OID_RC2_CBC = 5, - SEC_OID_RC4 = 6, - SEC_OID_DES_EDE3_CBC = 7, - SEC_OID_RC5_CBC_PAD = 8, - SEC_OID_DES_ECB = 9, - SEC_OID_DES_CBC = 10, - SEC_OID_DES_OFB = 11, - SEC_OID_DES_CFB = 12, - SEC_OID_DES_MAC = 13, - SEC_OID_DES_EDE = 14, - SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE = 15, - SEC_OID_PKCS1_RSA_ENCRYPTION = 16, - SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION = 17, - SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION = 18, - SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION = 19, - SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION = 20, - SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC = 21, - SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC = 22, - SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC = 23, - SEC_OID_PKCS7 = 24, - SEC_OID_PKCS7_DATA = 25, - SEC_OID_PKCS7_SIGNED_DATA = 26, - SEC_OID_PKCS7_ENVELOPED_DATA = 27, - SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA = 28, - SEC_OID_PKCS7_DIGESTED_DATA = 29, - SEC_OID_PKCS7_ENCRYPTED_DATA = 30, - SEC_OID_PKCS9_EMAIL_ADDRESS = 31, - SEC_OID_PKCS9_UNSTRUCTURED_NAME = 32, - SEC_OID_PKCS9_CONTENT_TYPE = 33, - SEC_OID_PKCS9_MESSAGE_DIGEST = 34, - SEC_OID_PKCS9_SIGNING_TIME = 35, - SEC_OID_PKCS9_COUNTER_SIGNATURE = 36, - SEC_OID_PKCS9_CHALLENGE_PASSWORD = 37, - SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS = 38, - SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES = 39, - SEC_OID_PKCS9_SMIME_CAPABILITIES = 40, - SEC_OID_AVA_COMMON_NAME = 41, - SEC_OID_AVA_COUNTRY_NAME = 42, - SEC_OID_AVA_LOCALITY = 43, - SEC_OID_AVA_STATE_OR_PROVINCE = 44, - SEC_OID_AVA_ORGANIZATION_NAME = 45, - SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME = 46, - SEC_OID_AVA_DN_QUALIFIER = 47, - SEC_OID_AVA_DC = 48, - - SEC_OID_NS_TYPE_GIF = 49, - SEC_OID_NS_TYPE_JPEG = 50, - SEC_OID_NS_TYPE_URL = 51, - SEC_OID_NS_TYPE_HTML = 52, - SEC_OID_NS_TYPE_CERT_SEQUENCE = 53, - SEC_OID_MISSI_KEA_DSS_OLD = 54, - SEC_OID_MISSI_DSS_OLD = 55, - SEC_OID_MISSI_KEA_DSS = 56, - SEC_OID_MISSI_DSS = 57, - SEC_OID_MISSI_KEA = 58, - SEC_OID_MISSI_ALT_KEA = 59, - - /* Netscape private certificate extensions */ - SEC_OID_NS_CERT_EXT_NETSCAPE_OK = 60, - SEC_OID_NS_CERT_EXT_ISSUER_LOGO = 61, - SEC_OID_NS_CERT_EXT_SUBJECT_LOGO = 62, - SEC_OID_NS_CERT_EXT_CERT_TYPE = 63, - SEC_OID_NS_CERT_EXT_BASE_URL = 64, - SEC_OID_NS_CERT_EXT_REVOCATION_URL = 65, - SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL = 66, - SEC_OID_NS_CERT_EXT_CA_CRL_URL = 67, - SEC_OID_NS_CERT_EXT_CA_CERT_URL = 68, - SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL = 69, - SEC_OID_NS_CERT_EXT_CA_POLICY_URL = 70, - SEC_OID_NS_CERT_EXT_HOMEPAGE_URL = 71, - SEC_OID_NS_CERT_EXT_ENTITY_LOGO = 72, - SEC_OID_NS_CERT_EXT_USER_PICTURE = 73, - SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME = 74, - SEC_OID_NS_CERT_EXT_COMMENT = 75, - SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL = 76, - SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME = 77, - SEC_OID_NS_KEY_USAGE_GOVT_APPROVED = 78, - - /* x.509 v3 Extensions */ - SEC_OID_X509_SUBJECT_DIRECTORY_ATTR = 79, - SEC_OID_X509_SUBJECT_KEY_ID = 80, - SEC_OID_X509_KEY_USAGE = 81, - SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD = 82, - SEC_OID_X509_SUBJECT_ALT_NAME = 83, - SEC_OID_X509_ISSUER_ALT_NAME = 84, - SEC_OID_X509_BASIC_CONSTRAINTS = 85, - SEC_OID_X509_NAME_CONSTRAINTS = 86, - SEC_OID_X509_CRL_DIST_POINTS = 87, - SEC_OID_X509_CERTIFICATE_POLICIES = 88, - SEC_OID_X509_POLICY_MAPPINGS = 89, - SEC_OID_X509_POLICY_CONSTRAINTS = 90, - SEC_OID_X509_AUTH_KEY_ID = 91, - SEC_OID_X509_EXT_KEY_USAGE = 92, - SEC_OID_X509_AUTH_INFO_ACCESS = 93, - - SEC_OID_X509_CRL_NUMBER = 94, - SEC_OID_X509_REASON_CODE = 95, - SEC_OID_X509_INVALID_DATE = 96, - /* End of x.509 v3 Extensions */ - - SEC_OID_X500_RSA_ENCRYPTION = 97, - - /* alg 1485 additions */ - SEC_OID_RFC1274_UID = 98, - SEC_OID_RFC1274_MAIL = 99, - - /* PKCS 12 additions */ - SEC_OID_PKCS12 = 100, - SEC_OID_PKCS12_MODE_IDS = 101, - SEC_OID_PKCS12_ESPVK_IDS = 102, - SEC_OID_PKCS12_BAG_IDS = 103, - SEC_OID_PKCS12_CERT_BAG_IDS = 104, - SEC_OID_PKCS12_OIDS = 105, - SEC_OID_PKCS12_PBE_IDS = 106, - SEC_OID_PKCS12_SIGNATURE_IDS = 107, - SEC_OID_PKCS12_ENVELOPING_IDS = 108, - /* SEC_OID_PKCS12_OFFLINE_TRANSPORT_MODE, - SEC_OID_PKCS12_ONLINE_TRANSPORT_MODE, */ - SEC_OID_PKCS12_PKCS8_KEY_SHROUDING = 109, - SEC_OID_PKCS12_KEY_BAG_ID = 110, - SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID = 111, - SEC_OID_PKCS12_SECRET_BAG_ID = 112, - SEC_OID_PKCS12_X509_CERT_CRL_BAG = 113, - SEC_OID_PKCS12_SDSI_CERT_BAG = 114, - SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4 = 115, - SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4 = 116, - SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC = 117, - SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 118, - SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 119, - SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4 = 120, - SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4 = 121, - SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES = 122, - SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST = 123, - /* end of PKCS 12 additions */ - - /* DSA signatures */ - SEC_OID_ANSIX9_DSA_SIGNATURE = 124, - SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST = 125, - SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST = 126, - - /* Verisign OIDs */ - SEC_OID_VERISIGN_USER_NOTICES = 127, - - /* PKIX OIDs */ - SEC_OID_PKIX_CPS_POINTER_QUALIFIER = 128, - SEC_OID_PKIX_USER_NOTICE_QUALIFIER = 129, - SEC_OID_PKIX_OCSP = 130, - SEC_OID_PKIX_OCSP_BASIC_RESPONSE = 131, - SEC_OID_PKIX_OCSP_NONCE = 132, - SEC_OID_PKIX_OCSP_CRL = 133, - SEC_OID_PKIX_OCSP_RESPONSE = 134, - SEC_OID_PKIX_OCSP_NO_CHECK = 135, - SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF = 136, - SEC_OID_PKIX_OCSP_SERVICE_LOCATOR = 137, - SEC_OID_PKIX_REGCTRL_REGTOKEN = 138, - SEC_OID_PKIX_REGCTRL_AUTHENTICATOR = 139, - SEC_OID_PKIX_REGCTRL_PKIPUBINFO = 140, - SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS = 141, - SEC_OID_PKIX_REGCTRL_OLD_CERT_ID = 142, - SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY = 143, - SEC_OID_PKIX_REGINFO_UTF8_PAIRS = 144, - SEC_OID_PKIX_REGINFO_CERT_REQUEST = 145, - SEC_OID_EXT_KEY_USAGE_SERVER_AUTH = 146, - SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH = 147, - SEC_OID_EXT_KEY_USAGE_CODE_SIGN = 148, - SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT = 149, - SEC_OID_EXT_KEY_USAGE_TIME_STAMP = 150, - SEC_OID_OCSP_RESPONDER = 151, - - /* Netscape Algorithm OIDs */ - SEC_OID_NETSCAPE_SMIME_KEA = 152, - - /* Skipjack OID -- ### mwelch temporary */ - SEC_OID_FORTEZZA_SKIPJACK = 153, - - /* PKCS 12 V2 oids */ - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4 = 154, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4 = 155, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC = 156, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC = 157, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 158, - SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 159, - SEC_OID_PKCS12_SAFE_CONTENTS_ID = 160, - SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID = 161, - - SEC_OID_PKCS12_V1_KEY_BAG_ID = 162, - SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID = 163, - SEC_OID_PKCS12_V1_CERT_BAG_ID = 164, - SEC_OID_PKCS12_V1_CRL_BAG_ID = 165, - SEC_OID_PKCS12_V1_SECRET_BAG_ID = 166, - SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID = 167, - SEC_OID_PKCS9_X509_CERT = 168, - SEC_OID_PKCS9_SDSI_CERT = 169, - SEC_OID_PKCS9_X509_CRL = 170, - SEC_OID_PKCS9_FRIENDLY_NAME = 171, - SEC_OID_PKCS9_LOCAL_KEY_ID = 172, - SEC_OID_PKCS12_KEY_USAGE = 173, - - /*Diffe Helman OIDS */ - SEC_OID_X942_DIFFIE_HELMAN_KEY = 174, - - /* Netscape other name types */ - SEC_OID_NETSCAPE_NICKNAME = 175, - - /* Cert Server OIDS */ - SEC_OID_NETSCAPE_RECOVERY_REQUEST = 176, - - /* New PSM certificate management OIDs */ - SEC_OID_CERT_RENEWAL_LOCATOR = 177, - SEC_OID_NS_CERT_EXT_SCOPE_OF_USE = 178, - - /* CMS (RFC2630) OIDs */ - SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN = 179, - SEC_OID_CMS_3DES_KEY_WRAP = 180, - SEC_OID_CMS_RC2_KEY_WRAP = 181, - - /* SMIME attributes */ - SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE = 182, - - /* AES OIDs */ - SEC_OID_AES_128_ECB = 183, - SEC_OID_AES_128_CBC = 184, - SEC_OID_AES_192_ECB = 185, - SEC_OID_AES_192_CBC = 186, - SEC_OID_AES_256_ECB = 187, - SEC_OID_AES_256_CBC = 188, - - SEC_OID_SDN702_DSA_SIGNATURE = 189, - - SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE = 190, - - SEC_OID_SHA224 = 191, - SEC_OID_SHA256 = 192, - SEC_OID_SHA384 = 193, - SEC_OID_SHA512 = 194, - - SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION = 195, - SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION = 196, - SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION = 197, - - SEC_OID_AES_128_KEY_WRAP = 198, - SEC_OID_AES_192_KEY_WRAP = 199, - SEC_OID_AES_256_KEY_WRAP = 200, - - /* eContentType set by client and not understood by this library; treated - * like SEC_OID_PKCS7_DATA, except the caller's OID is encoded. */ - SEC_OID_OTHER = 201, - - /* ECDSA */ - SEC_OID_EC_PUBLIC_KEY = 202, - SEC_OID_ECDSA_WithSHA1 = 203, - SEC_OID_DH_SINGLE_STD_SHA1KDF = 204, - SEC_OID_SECP_256_R1 = 205, - SEC_OID_SECP_384_R1 = 206, - SEC_OID_SECP_521_R1 = 207, - - /* RFC 3161 Timestamping OIDs */ - SEC_OID_PKCS9_ID_CT_TSTInfo = 208, - SEC_OID_PKCS9_TIMESTAMP_TOKEN = 209, - SEC_OID_PKCS9_SIGNING_CERTIFICATE = 210, - - /* ECDSA with SHA2 */ - SEC_OID_ECDSA_WITH_SHA256 = 211, - SEC_OID_ECDSA_WITH_SHA384 = 212, - SEC_OID_ECDSA_WITH_SHA512 = 213, - - /* Apple CMS Attributes */ - 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; - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSBASE_H_ */ diff --git a/libsecurity_smime/lib/SecCmsContentInfo.h b/libsecurity_smime/lib/SecCmsContentInfo.h deleted file mode 100644 index 8718d8dc..00000000 --- a/libsecurity_smime/lib/SecCmsContentInfo.h +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010 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 SecCmsContentInfo.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for creating and - accessing ContentInfo objects that are part of Cryptographic - Message Syntax (CMS) objects as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSCONTENTINFO_H_ -#define _SECURITY_SECCMSCONTENTINFO_H_ 1 - -#include -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! @functiongroup ContentInfo accessors */ -/*! - @function - @abstract Get content's contentInfo (if it exists). - @param cinfo A ContentInfo object of which we want to get the child contentInfo. - @result The child ContentInfo object, or NULL if there is none. - @discussion This function requires a ContentInfo object which is usually created by decoding and SecCmsMessage using a SecCmsDecoder. - @availability 10.4 and later - */ -extern SecCmsContentInfoRef -SecCmsContentInfoGetChildContentInfo(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Get pointer to inner content - @discussion needs to be casted... - */ -extern void * -SecCmsContentInfoGetContent(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Get pointer to innermost content - @discussion This is typically only called by SecCmsMessageGetContent(). - */ -extern const SecAsn1Item * -SecCmsContentInfoGetInnerContent(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Find out and return the inner content type. - */ -extern SECOidTag -SecCmsContentInfoGetContentTypeTag(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Find out and return the inner content type. - @discussion Caches pointer to lookup result for future reference. - */ -extern SecAsn1Oid * -SecCmsContentInfoGetContentTypeOID(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Find out and return the content encryption algorithm tag. - */ -extern SECOidTag -SecCmsContentInfoGetContentEncAlgTag(SecCmsContentInfoRef cinfo); - -/*! - @function - @abstract Find out and return the content encryption algorithm. - @discussion Caches pointer to lookup result for future reference. - */ -extern SECAlgorithmID * -SecCmsContentInfoGetContentEncAlg(SecCmsContentInfoRef cinfo); - - -/*! @functiongroup Message construction */ -/*! - @function - @abstract Set a ContentInfos content to a Data - @param cinfo A ContentInfo object of which we want set the content. - @param data A CFDataRef or NULL if data will be provided during SecCmsEncoderUpdate calls. - @param detached True if the content is to be deattched from the CMS message rather than included within it. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentData(SecCmsContentInfoRef cinfo, CFDataRef data, Boolean detached); - -/*! - @function - @abstract Set a ContentInfos content to a SignedData. - @param cinfo A ContentInfo object of which we want set the content. - @param sigd A SignedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a SignedData which can be made by calling SecCmsSignedDataCreate(). If the call succeeds the passed in SignedData object will be owned by the reciever. The Message object of the SignedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentSignedData(SecCmsContentInfoRef cinfo, SecCmsSignedDataRef sigd); - -/*! - @function - @abstract Set a ContentInfos content to a EnvelopedData. - @param cinfo A ContentInfo object of which we want set the content. - @param envd A EnvelopedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EnvelopedData which can be made by calling SecCmsEnvelopedDataCreate(). If the call succeeds the passed in EnvelopedData object will be owned by the reciever. The Message object of the EnvelopedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentEnvelopedData(SecCmsContentInfoRef cinfo, SecCmsEnvelopedDataRef envd); - -/*! - @function - @abstract Set a ContentInfos content to a DigestedData. - @param cinfo A ContentInfo object of which we want set the content. - @param digd A DigestedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a DigestedData which can be made by calling SecCmsDigestedDataCreate(). If the call succeeds the passed in DigestedData object will be owned by the reciever. The Message object of the DigestedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentDigestedData(SecCmsContentInfoRef cinfo, SecCmsDigestedDataRef digd); - -/*! - @function - @abstract Set a ContentInfos content to a EncryptedData. - @param cinfo A ContentInfo object of which we want set the content. - @param encd A EncryptedData object to set as the content of the cinfo object. - @result A result code. See "SecCmsBase.h" for possible results. - @discussion This function requires a ContentInfo object which can be made by creating a SecCmsMessage object and a EncryptedData which can be made by calling SecCmsEncryptedDataCreate(). If the call succeeds the passed in EncryptedData object will be owned by the reciever. The Message object of the EncryptedData object must be the same as cmsg. - @availability 10.4 and later - */ -extern OSStatus -SecCmsContentInfoSetContentEncryptedData(SecCmsContentInfoRef cinfo, SecCmsEncryptedDataRef encd); - -OSStatus -SecCmsContentInfoSetContentOther(SecCmsContentInfoRef cinfo, SecAsn1Item *data, Boolean detached, const SecAsn1Oid *eContentType); - -/*! - @function - */ -extern OSStatus -SecCmsContentInfoSetContentEncAlg(SecCmsContentInfoRef cinfo, - SECOidTag bulkalgtag, const SecAsn1Item *parameters, int keysize); - -/*! - @function - */ -extern OSStatus -SecCmsContentInfoSetContentEncAlgID(SecCmsContentInfoRef cinfo, - SECAlgorithmID *algid, int keysize); - -/*! - @function - */ -extern void -SecCmsContentInfoSetBulkKey(SecCmsContentInfoRef cinfo, SecSymmetricKeyRef bulkkey); - -/*! - @function - */ -extern SecSymmetricKeyRef -SecCmsContentInfoGetBulkKey(SecCmsContentInfoRef cinfo); - -/*! - @function - */ -extern int -SecCmsContentInfoGetBulkKeySize(SecCmsContentInfoRef cinfo); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSCONTENTINFO_H_ */ diff --git a/libsecurity_smime/lib/SecCmsDigestedData.h b/libsecurity_smime/lib/SecCmsDigestedData.h deleted file mode 100644 index d35d68cb..00000000 --- a/libsecurity_smime/lib/SecCmsDigestedData.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010 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 SecCmsDigestedData.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for creating - and accessing the DigestData content type of a - Cryptographic Message Syntax (CMS) object - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSDIGESTEDDATA_H_ -#define _SECURITY_SECCMSDIGESTEDDATA_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! - @function - @abstract Create a digestedData object (presumably for encoding). - @discussion Version will be set by SecCmsDigestedDataEncodeBeforeStart - digestAlg is passed as parameter - contentInfo must be filled by the user - digest will be calculated while encoding - */ -extern SecCmsDigestedDataRef -SecCmsDigestedDataCreate(SecCmsMessageRef cmsg, SECAlgorithmID *digestalg); - -/*! - @function - @abstract Destroy a digestedData object. - */ -extern void -SecCmsDigestedDataDestroy(SecCmsDigestedDataRef digd); - -/*! - @function - @abstract Return pointer to digestedData object's contentInfo. - */ -extern SecCmsContentInfoRef -SecCmsDigestedDataGetContentInfo(SecCmsDigestedDataRef digd); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSDIGESTEDDATA_H_ */ diff --git a/libsecurity_smime/lib/SecCmsEnvelopedData.h b/libsecurity_smime/lib/SecCmsEnvelopedData.h deleted file mode 100644 index abc813c1..00000000 --- a/libsecurity_smime/lib/SecCmsEnvelopedData.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010 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 SecCmsEnvelopedData.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSENVELOPEDDATA_H_ -#define _SECURITY_SECCMSENVELOPEDDATA_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! - @function - @abstract Create an enveloped data message. - */ -extern SecCmsEnvelopedDataRef -SecCmsEnvelopedDataCreate(SecCmsMessageRef cmsg, SECOidTag algorithm, int keysize); - -/*! - @function - @abstract Destroy an enveloped data message. - */ -extern void -SecCmsEnvelopedDataDestroy(SecCmsEnvelopedDataRef edp); - -/*! - @function - @abstract Return pointer to this envelopedData's contentinfo. - */ -extern SecCmsContentInfoRef -SecCmsEnvelopedDataGetContentInfo(SecCmsEnvelopedDataRef envd); - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSENVELOPEDDATA_H_ */ diff --git a/libsecurity_smime/lib/SecCmsMessage.h b/libsecurity_smime/lib/SecCmsMessage.h deleted file mode 100644 index f3e55801..00000000 --- a/libsecurity_smime/lib/SecCmsMessage.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010 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 SecCmsMessage.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract CMS message object interfaces - @abstract Interfaces of the CMS implementation. - @discussion A SecCmsMessage represent a Cryptographic Message - Syntax (CMS) object as described in rfc3369. - It can be encoded using a SecCmsEncoder into BER - data or obtained from a SecCmsDecoder and examined - using the functions below. - */ - -#ifndef _SECURITY_SECCMSMESSAGE_H_ -#define _SECURITY_SECCMSMESSAGE_H_ 1 - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - - -/*! - @function - @abstract Create a CMS message object. - @result A pointer to a newly created SecCmsMessage. When finished using - this the caller should call SecCmsMessageDestroy(). On failure - returns NULL. In this case call PR_GetError() to find out what went - wrong. - */ -extern SecCmsMessageRef -SecCmsMessageCreate(void); - -/*! - @function - @abstract Destroy a CMS message and all of its sub-pieces. - @param cmsg Pointer to a SecCmsMessage object. - */ -extern void -SecCmsMessageDestroy(SecCmsMessageRef cmsg); - -/*! - @function - @abstract Return a copy of the given message. - @discussion The copy may be virtual or may be real -- either way, the - result needs to be passed to SecCmsMessageDestroy later (as does the - original). - @param cmsg Pointer to a SecCmsMessage object. - */ -extern SecCmsMessageRef -SecCmsMessageCopy(SecCmsMessageRef cmsg); - -/*! - @function - @abstract Return a pointer to the top level contentInfo. - */ -extern SecCmsContentInfoRef -SecCmsMessageGetContentInfo(SecCmsMessageRef cmsg); - -/*! - @function - @abstract Return a pointer to the actual content. - @discussion In the case of those types which are encrypted, this returns the *plain* content. - In case of nested contentInfos, this descends and retrieves the innermost content. - */ -extern const SecAsn1Item * -SecCmsMessageGetContent(SecCmsMessageRef cmsg); - -/*! - @function - @abstract Count number of levels of CMS content objects in this message. - @discussion CMS data content objects do not count. - */ -extern int -SecCmsMessageContentLevelCount(SecCmsMessageRef cmsg); - -/*! - @function - @abstract Find content level #n. - @discussion CMS data content objects do not count. - */ -extern SecCmsContentInfoRef -SecCmsMessageContentLevel(SecCmsMessageRef cmsg, int n); - -/*! - @function - @abstract See if message contains certs along the way. - */ -extern Boolean -SecCmsMessageContainsCertsOrCrls(SecCmsMessageRef cmsg); - -/*! - @function - @abstract See if message contains a encrypted submessage. - */ -extern Boolean -SecCmsMessageIsEncrypted(SecCmsMessageRef cmsg); - -/*! - @function - @abstract See if message contains a signed submessage - @discussion If the CMS message has a SignedData with a signature (not just a SignedData) - return true; false otherwise. This can/should be called before calling - VerifySignature, which will always indicate failure if no signature is - present, but that does not mean there even was a signature! - Note that the content itself can be empty (detached content was sent - another way); it is the presence of the signature that matters. - */ -extern Boolean -SecCmsMessageIsSigned(SecCmsMessageRef cmsg); - -/*! - @function - @abstract See if content is empty. - @result Returns PR_TRUE is innermost content length is < minLen - @discussion XXX need the encrypted content length (why?) - */ -extern Boolean -SecCmsMessageIsContentEmpty(SecCmsMessageRef cmsg, unsigned int minLen); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSMESSAGE_H_ */ diff --git a/libsecurity_smime/lib/SecCmsSignerInfo.h b/libsecurity_smime/lib/SecCmsSignerInfo.h deleted file mode 100644 index 01d5757c..00000000 --- a/libsecurity_smime/lib/SecCmsSignerInfo.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010,2013 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 SecCmsSignerInfo.h - @Copyright (c) 2004,2008,2010,2013 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract Interfaces of the CMS implementation. - @discussion The functions here implement functions for encoding - and decoding Cryptographic Message Syntax (CMS) objects - as described in rfc3369. - */ - -#ifndef _SECURITY_SECCMSSIGNERINFO_H_ -#define _SECURITY_SECCMSSIGNERINFO_H_ 1 - -#include - -#include - - -#if defined(__cplusplus) -extern "C" { -#endif - -/*! - @function - */ -extern SecCmsSignerInfoRef -SecCmsSignerInfoCreate(SecCmsSignedDataRef sigd, SecIdentityRef identity, SECOidTag digestalgtag); - -/*! - @function - */ -extern SecCmsSignerInfoRef -SecCmsSignerInfoCreateWithSubjKeyID(SecCmsSignedDataRef sigd, const SecAsn1Item *subjKeyID, SecPublicKeyRef pubKey, SecPrivateKeyRef signingKey, SECOidTag digestalgtag); - -/*! - @function - */ -extern SecCmsVerificationStatus -SecCmsSignerInfoGetVerificationStatus(SecCmsSignerInfoRef signerinfo); - -/*! - @function - */ -extern SECOidData * -SecCmsSignerInfoGetDigestAlg(SecCmsSignerInfoRef signerinfo); - -/*! - @function - */ -extern SECOidTag -SecCmsSignerInfoGetDigestAlgTag(SecCmsSignerInfoRef signerinfo); - -/*! - @function - */ -extern CFArrayRef -SecCmsSignerInfoGetCertList(SecCmsSignerInfoRef signerinfo); - -/*! - @function - @abstract Return the signing time, in UTCTime format, of a CMS signerInfo. - @param sinfo SignerInfo data for this signer. - @discussion Returns a pointer to XXXX (what?) - @result A return value of NULL is an error. - */ -extern OSStatus -SecCmsSignerInfoGetSigningTime(SecCmsSignerInfoRef sinfo, CFAbsoluteTime *stime); - -/*! - @function - @abstract Return the data in the signed Codesigning Hash Agility attribute. - @param sinfo SignerInfo data for this signer, pointer to a CFDataRef for attribute value - @discussion Returns a CFDataRef containing the value of the attribute - @result A return value of SECFailure is an error. - */ -extern OSStatus -SecCmsSignerInfoGetAppleCodesigningHashAgility(SecCmsSignerInfoRef sinfo, CFDataRef *sdata); - -/*! - @function - @abstract Return the data in the signed Codesigning Hash Agility V2 attribute. - @param sinfo SignerInfo data for this signer, pointer to a CFDictionaryRef for attribute values - @discussion Returns a CFDictionaryRef containing the values of the attribute. V2 encodes the - hash agility values using DER. - @result A return value of SECFailure is an error. - */ -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. - @discussion The certs in the enclosing SignedData must have been imported already. - */ -extern SecCertificateRef -SecCmsSignerInfoGetSigningCertificate(SecCmsSignerInfoRef signerinfo, SecKeychainRef keychainOrArray); - -/*! - @function - @abstract Return the common name of the signer. - @param sinfo SignerInfo data for this signer. - @discussion Returns a CFStringRef containing the common name of the signer. - @result A return value of NULL is an error. - */ -extern CF_RETURNS_RETAINED CFStringRef -SecCmsSignerInfoGetSignerCommonName(SecCmsSignerInfoRef sinfo); - -/*! - @function - @abstract Return the email address of the signer - @param sinfo SignerInfo data for this signer. - @discussion Returns a CFStringRef containing the name of the signer. - @result A return value of NULL is an error. - */ -extern CF_RETURNS_RETAINED CFStringRef -SecCmsSignerInfoGetSignerEmailAddress(SecCmsSignerInfoRef sinfo); - -/*! - @function - @abstract Add the signing time to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed - messages for email (S/MIME) but is likely useful in other situations. - - This should only be added once; a second call will do nothing. - - XXX This will probably just shove the current time into "signerinfo" - but it will not actually get signed until the entire item is - processed for encoding. Is this (expected to be small) delay okay? - */ -extern OSStatus -SecCmsSignerInfoAddSigningTime(SecCmsSignerInfoRef signerinfo, CFAbsoluteTime t); - -/*! - @function - @abstract Add a SMIMECapabilities attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed messages for email (S/MIME). - */ -extern OSStatus -SecCmsSignerInfoAddSMIMECaps(SecCmsSignerInfoRef signerinfo); - -/*! - @function - @abstract Add a SMIMEEncryptionKeyPreferences attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing signed messages for email (S/MIME). - */ -OSStatus -SecCmsSignerInfoAddSMIMEEncKeyPrefs(SecCmsSignerInfoRef signerinfo, SecCertificateRef cert, SecKeychainRef keychainOrArray); - -/*! - @function - @abstract Add a SMIMEEncryptionKeyPreferences attribute to the authenticated (i.e. signed) attributes of "signerinfo", using the OID prefered by Microsoft. - @discussion This is expected to be included in outgoing signed messages for email (S/MIME), if compatibility with Microsoft mail clients is wanted. - */ -OSStatus -SecCmsSignerInfoAddMSSMIMEEncKeyPrefs(SecCmsSignerInfoRef signerinfo, SecCertificateRef cert, SecKeychainRef keychainOrArray); - -/*! - @function - @abstract Countersign a signerinfo. - */ -extern OSStatus -SecCmsSignerInfoAddCounterSignature(SecCmsSignerInfoRef signerinfo, - SECOidTag digestalg, SecIdentityRef identity); - -/*! - @function - @abstract Add the Apple Codesigning Hash Agility attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing Apple code signatures. -*/ -OSStatus -SecCmsSignerInfoAddAppleCodesigningHashAgility(SecCmsSignerInfoRef signerinfo, CFDataRef attrValue); - -/*! - @function - @abstract Add the Apple Codesigning Hash Agility V2 attribute to the authenticated (i.e. signed) attributes of "signerinfo". - @discussion This is expected to be included in outgoing Apple code signatures. V2 encodes the hash agility values using DER. - The dictionary should have CFNumberRef keys, corresponding to SECOidTags for digest algorithms, and CFDataRef values, - corresponding to the digest value for that digest algorithm. - */ -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. - @param signerinfo The SecCmsSignerInfo object for which we verified the signature. - @result The preferred encryption certificate of the user who signed this message will be added to the users default Keychain and it will be marked as the preferred certificate to use when sending that person messages from now on. - */ -extern OSStatus -SecCmsSignerInfoSaveSMIMEProfile(SecCmsSignerInfoRef signerinfo); - -/*! - @function - @abstract Set cert chain inclusion mode for this signer. - */ -extern OSStatus -SecCmsSignerInfoIncludeCerts(SecCmsSignerInfoRef signerinfo, SecCmsCertChainMode cm, SECCertUsage usage); - -/*! @functiongroup CMS misc utility functions */ -/*! - @function - Convert a SecCmsVerificationStatus to a human readable string. - */ -extern const char * -SecCmsUtilVerificationStatusToString(SecCmsVerificationStatus vs); - -/*! - @function SecCmsSignerInfoCopyCertFromEncryptionKeyPreference - @abstract Copy the certificate specified in the encryption key preference. - @param signerinfo The SecCmsSignerInfo object for which we verified the signature. - @result The preferred encryption certificate of the user who signed this message, if found. - @discussion This function should be called after the signer info has been verified. - */ -SecCertificateRef SecCmsSignerInfoCopyCertFromEncryptionKeyPreference(SecCmsSignerInfoRef signerinfo); - - -#if defined(__cplusplus) -} -#endif - -#endif /* _SECURITY_SECCMSSIGNERINFO_H_ */ diff --git a/libsecurity_smime/lib/SecSMIME.h b/libsecurity_smime/lib/SecSMIME.h deleted file mode 100644 index 7083c7cc..00000000 --- a/libsecurity_smime/lib/SecSMIME.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2004,2008,2010 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 SecSMIME.h - @Copyright (c) 2004,2008,2010 Apple Inc. All Rights Reserved. - - @availability 10.4 and later - @abstract S/MIME Specific routines. - @discussion Header file for routines specific to S/MIME. Keep - things that are pure pkcs7 out of here; this is for - S/MIME policy, S/MIME interoperability, etc. -*/ - -#ifndef _SECURITY_SECSMIME_H_ -#define _SECURITY_SECSMIME_H_ 1 - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - @function - @abstract Find bulk algorithm suitable for all recipients. - */ -extern OSStatus -SecSMIMEFindBulkAlgForRecipients(SecCertificateRef *rcerts, SECOidTag *bulkalgtag, int *keysize); - - -#ifdef __cplusplus -} -#endif - -#endif /* _SECURITY_SECSMIME_H_ */ diff --git a/libsecurity_smime/lib/cert.c b/libsecurity_smime/lib/cert.c deleted file mode 100644 index 34628872..00000000 --- a/libsecurity_smime/lib/cert.c +++ /dev/null @@ -1,724 +0,0 @@ -/* - * cert.c - * security_smime - * - * Created by john on Wed Mar 12 2003. - * Copyright (c) 2003 __MyCompanyName__. All rights reserved. - * - */ - -#include "cert.h" -#include "cmstpriv.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* for errKCDuplicateItem */ -#include - -/* @@@ Remove this once it's back in the appropriate header. */ -static const uint8 X509V1IssuerNameStd[] = {INTEL_X509V3_CERT_R08, 23}; -static const CSSM_OID OID_X509V1IssuerNameStd = {INTEL_X509V3_CERT_R08_LENGTH+1, (uint8 *)X509V1IssuerNameStd}; - -/* - * Normalize a Printable String. Per RFC2459 (4.1.2.4), printable strings are case - * insensitive and we're supposed to ignore leading and trailing - * whitespace, and collapse multiple whitespace characters into one. - */ -static void -CERT_NormalizeString(CSSM_DATA_PTR string) -{ - char *pD, *pCh, *pEos; - - if (!string->Length) - return; - - pD = pCh = (char *)string->Data; - pEos = pCh + string->Length - 1; - - /* Strip trailing NULL terminators */ - while(*pEos == 0) - pEos--; - - /* Remove trailing spaces */ - while(isspace(*pEos)) - pEos--; - - /* Point to one past last non-space character */ - pEos++; - - /* skip all leading whitespace */ - while(isspace(*pCh) && (pCh < pEos)) - pCh++; - - /* Eliminate multiple whitespace and convent to upper case. - * pCh points to first non-white char. - * pD still points to start of string. */ - while(pCh < pEos) - { - char ch = *pCh++; - *pD++ = toupper(ch); - if(isspace(ch)) - { - /* skip 'til next nonwhite */ - while(isspace(*pCh) && (pCh < pEos)) - pCh++; - } - } - - string->Length = pD - (char *)string->Data; -} - -/* - * Normalize an RDN. Per RFC2459 (4.1.2.4), printable strings are case - * insensitive and we're supposed to ignore leading and trailing - * whitespace, and collapse multiple whitespace characters into one. - * - * Incoming NSS_Name is assumed to be entirely within specifed coder's - * address space; we'll be munging some of that and possibly replacing - * some pointers with others allocated from the same space. - */ -void -CERT_NormalizeX509NameNSS(NSS_Name *nssName) -{ - NSS_RDN *rdn; - - for (rdn = *nssName->rdns; rdn; ++rdn) - { - NSS_ATV *attr; - for (attr = *rdn->atvs; attr; ++attr) - { - /* - * attr->value is an ASN_ANY containing an encoded - * string. We only normalize Prinatable String types. - * If we find one, decode it, normalize it, encode the - * result, and put the encoding back in attr->value. - * We temporarily "leak" the original string, which only - * has a lifetime of the incoming SecNssCoder. - */ - NSS_TaggedItem *attrVal = &attr->value; - if(attrVal->tag != SEC_ASN1_PRINTABLE_STRING) - continue; - - CERT_NormalizeString(&attrVal->item); - } - } -} - -SecCertificateRef CERT_FindCertByNicknameOrEmailAddr(SecKeychainRef keychainOrArray, char *name) -{ - SecCertificateRef certificate; - OSStatus status=SecCertificateFindByEmail(keychainOrArray,name,&certificate); - return status==errSecSuccess?certificate:NULL; -} - -SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey) -{ - CFRetain(pubKey); - return pubKey; -} - -void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey) -{ - CFRelease(pubKey); -} - -SecPublicKeyRef SECKEY_CopyPrivateKey(SecPublicKeyRef privKey) -{ - CFRetain(privKey); - return privKey; -} - -void SECKEY_DestroyPrivateKey(SecPublicKeyRef privKey) -{ - CFRelease(privKey); -} - -void CERT_DestroyCertificate(SecCertificateRef cert) -{ - CFRelease(cert); -} - -SecCertificateRef CERT_DupCertificate(SecCertificateRef cert) -{ - CFRetain(cert); - return cert; -} - -SecIdentityRef CERT_FindIdentityByUsage(SecKeychainRef keychainOrArray, - char *nickname, SECCertUsage usage, Boolean validOnly, void *proto_win) -{ - SecIdentityRef identityRef = NULL; - SecCertificateRef cert = CERT_FindCertByNicknameOrEmailAddr(keychainOrArray, nickname); - if (!cert) - return NULL; - - SecIdentityCreateWithCertificate(keychainOrArray, cert, &identityRef); - CFRelease(cert); - - return identityRef; -} - -SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray, - char *nickname,SECCertUsage usage,Boolean validOnly,void *proto_win) -{ - SecItemClass itemClass = kSecCertificateItemClass; - SecKeychainSearchRef searchRef; - SecKeychainItemRef itemRef = NULL; - OSStatus status; - SecKeychainAttribute attrs[1]; - const char *serialNumber = "12345678"; - // const SecKeychainAttributeList attrList; -#if 0 - attrs[0].tag = kSecLabelItemAttr; - attrs[0].length = strlen(nickname)+1; - attrs[0].data = nickname; -#else - attrs[0].tag = kSecSerialNumberItemAttr; - attrs[0].length = strlen(serialNumber)+1; - attrs[0].data = (uint8 *)serialNumber; -#endif - SecKeychainAttributeList attrList = { 0, attrs }; - // 12 34 56 78 - status = SecKeychainSearchCreateFromAttributes(keychainOrArray,itemClass,&attrList,&searchRef); - if (status) - { - printf("CERT_FindUserCertByUsage: SecKeychainSearchCreateFromAttributes:%ld",status); - return NULL; - } - status = SecKeychainSearchCopyNext(searchRef,&itemRef); - if (status) - printf("CERT_FindUserCertByUsage: SecKeychainSearchCopyNext:%ld",status); - CFRelease(searchRef); - return (SecCertificateRef)itemRef; -} - -/* -startNewClass(X509Certificate) -CertType, kSecCertTypeItemAttr, "CertType", 0, NULL, UINT32) -CertEncoding, kSecCertEncodingItemAttr, "CertEncoding", 0, NULL, UINT32) -PrintName, kSecLabelItemAttr, "PrintName", 0, NULL, BLOB) -Alias, kSecAliasItemAttr, "Alias", 0, NULL, BLOB) -Subject, kSecSubjectItemAttr, "Subject", 0, NULL, BLOB) -Issuer, kSecIssuerItemAttr, "Issuer", 0, NULL, BLOB) -SerialNumber, kSecSerialNumberItemAttr, "SerialNumber", 0, NULL, BLOB) -SubjectKeyIdentifier, kSecSubjectKeyIdentifierItemAttr, "SubjectKeyIdentifier", 0, NULL, BLOB) -PublicKeyHash, kSecPublicKeyHashItemAttr, "PublicKeyHash", 0, NULL, BLOB) -endNewClass() -*/ - -CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot) -{ - SecPolicySearchRef searchRef = NULL; - SecPolicyRef policy = NULL; - CFArrayRef wrappedCert = NULL; - SecTrustRef trust = NULL; - CFArrayRef certChain = NULL; - CSSM_TP_APPLE_EVIDENCE_INFO *statusChain; - OSStatus status = 0; - SecTrustResultType trustResult = kSecTrustResultInvalid; - - if (!cert) - goto loser; - - status = SecPolicySearchCreate(CSSM_CERT_X_509v3, &CSSMOID_APPLE_X509_BASIC, NULL, &searchRef); - if (status) - goto loser; - status = SecPolicySearchCopyNext(searchRef, &policy); - if (status) - goto loser; - - wrappedCert = CERT_CertListFromCert(cert); - status = SecTrustCreateWithCertificates(wrappedCert, policy, &trust); - if (status) - goto loser; - - status = SecTrustEvaluate(trust, &trustResult); - if (status) - goto loser; - - status = SecTrustGetResult(trust, NULL, &certChain, &statusChain); - if (status) - goto loser; - - /* We don't drop the root if there is only 1 (self signed) certificate in the chain. */ - if (!includeRoot && CFArrayGetCount(certChain) > 1) - { - CFMutableArrayRef subChain = CFArrayCreateMutableCopy(NULL, 0, certChain); - CFRelease(certChain); - certChain = subChain; - if (subChain) - CFArrayRemoveValueAtIndex(subChain, CFArrayGetCount(subChain) - 1); - } - -loser: - if (searchRef) - CFRelease(searchRef); - if (policy) - CFRelease(policy); - if (wrappedCert) - CFRelease(wrappedCert); - if (trust) - CFRelease(trust); - if (certChain && status) - { - CFRelease(certChain); - certChain = NULL; - } - - return certChain; -} - -CFArrayRef CERT_CertListFromCert(SecCertificateRef cert) -{ - const void *value = cert; - return cert ? CFArrayCreate(NULL, &value, 1, &kCFTypeArrayCallBacks) : NULL; -} - -CFArrayRef CERT_DupCertList(CFArrayRef oldList) -{ - CFRetain(oldList); - return oldList; -} - -// Extract a public key object from a SubjectPublicKeyInfo -SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert) -{ - SecPublicKeyRef keyRef = NULL; - SecCertificateCopyPublicKey(cert,&keyRef); - return keyRef; -} - -SECStatus CERT_CheckCertUsage (SecCertificateRef cert,unsigned char usage) -{ - // abort(); - // @@@ It's all good, it's ok. - return SECSuccess; -} - -// Find a certificate in the database by a email address -// "emailAddr" is the email address to look up -SecCertificateRef CERT_FindCertByEmailAddr(SecKeychainRef keychainOrArray, char *emailAddr) -{ - abort(); - return NULL; -} - -// Find a certificate in the database by a DER encoded certificate -// "derCert" is the DER encoded certificate -SecCertificateRef CERT_FindCertByDERCert(SecKeychainRef keychainOrArray, const SECItem *derCert) -{ - // @@@ Technically this should look though keychainOrArray for a cert matching this one I guess. - SecCertificateRef cert = NULL; - OSStatus rv; - - rv = SecCertificateCreateFromData(derCert, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &cert); - if (rv && cert) - { - PORT_SetError(SEC_ERROR_NO_EMAIL_CERT); - CFRelease(cert); - cert = NULL; - } - - return cert; -} - -// Generate a certificate key from the issuer and serialnumber, then look it up in the database. -// Return the cert if found. "issuerAndSN" is the issuer and serial number to look for -SecCertificateRef CERT_FindCertByIssuerAndSN (CFTypeRef keychainOrArray, const SecCmsIssuerAndSN *issuerAndSN) -{ - SecCertificateRef certificate; - OSStatus status = SecCertificateFindByIssuerAndSN(keychainOrArray, &issuerAndSN->derIssuer, - &issuerAndSN->serialNumber, &certificate); - if (status) - { - PORT_SetError(SEC_ERROR_NO_EMAIL_CERT); - certificate = NULL; - } - - return certificate; -} - -SecCertificateRef CERT_FindCertBySubjectKeyID (CFTypeRef keychainOrArray, const SecAsn1Item *subjKeyID) -{ - SecCertificateRef certificate; - OSStatus status = SecCertificateFindBySubjectKeyID(keychainOrArray,subjKeyID,&certificate); - if (status) - { - PORT_SetError(SEC_ERROR_NO_EMAIL_CERT); - certificate = NULL; - } - - return certificate; -} - -static SecIdentityRef -CERT_FindIdentityByCertificate (CFTypeRef keychainOrArray, SecCertificateRef certificate) -{ - SecIdentityRef identity = NULL; - SecIdentityCreateWithCertificate(keychainOrArray, certificate, &identity); - if (!identity) - PORT_SetError(SEC_ERROR_NOT_A_RECIPIENT); - - return identity; -} - -SecIdentityRef -CERT_FindIdentityByIssuerAndSN (CFTypeRef keychainOrArray, const SecCmsIssuerAndSN *issuerAndSN) -{ - SecCertificateRef certificate = CERT_FindCertByIssuerAndSN(keychainOrArray, issuerAndSN); - if (!certificate) - return NULL; - - return CERT_FindIdentityByCertificate(keychainOrArray, certificate); -} - -SecIdentityRef -CERT_FindIdentityBySubjectKeyID (CFTypeRef keychainOrArray, const SECItem *subjKeyID) -{ - SecCertificateRef certificate = CERT_FindCertBySubjectKeyID(keychainOrArray, subjKeyID); - if (!certificate) - return NULL; - - return CERT_FindIdentityByCertificate(keychainOrArray, certificate); -} - -// find the smime symmetric capabilities profile for a given cert -SECItem *CERT_FindSMimeProfile(SecCertificateRef cert) -{ - return NULL; -} - -// Return the decoded value of the subjectKeyID extension. The caller should -// free up the storage allocated in retItem->data. -SECStatus CERT_FindSubjectKeyIDExtension (SecCertificateRef cert,SECItem *retItem) -{ - fprintf(stderr, "WARNING: CERT_FindSubjectKeyIDExtension unimplemented\n"); - return SECFailure; -} - -static void * appMalloc (uint32 size, void *allocRef) { - return (malloc (size)); -} - -static void appFree (void *mem_ptr, void *allocRef) { - free (mem_ptr); - return; -} - -static void * appRealloc (void *ptr, uint32 size, void *allocRef) { - return (realloc (ptr, size)); -} - -static void * appCalloc (uint32 num, uint32 size, void *allocRef) { - return (calloc (num, size)); -} - -static CSSM_API_MEMORY_FUNCS memFuncs = { - appMalloc, - appFree, - appRealloc, - appCalloc, - NULL - }; - -// return a valid CL handle -static int InitializeCL (CSSM_CL_HANDLE *clHandle) -{ - CSSM_VERSION version = {2, 0}; - - // load the module - CSSM_RETURN result = CSSM_ModuleLoad (&gGuidAppleX509CL, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (result != 0) - { - return false; - } - - result = CSSM_ModuleAttach (&gGuidAppleX509CL, &version, &memFuncs, 0, CSSM_SERVICE_CL, 0, 0, NULL, 0, NULL, clHandle); - if (result != 0) - { - return false; - } - - return true; -} - -// cleanup a CL handle -static void CloseCL (CSSM_CL_HANDLE clHandle) -{ - CSSM_ModuleDetach (clHandle); - CSSM_ModuleUnload (&gGuidAppleX509CL, NULL, NULL); -} - -// Extract the issuer and serial number from a certificate -SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef cert) -{ - OSStatus status; - SecCmsIssuerAndSN *certIssuerAndSN; - CSSM_CL_HANDLE clHandle; - CSSM_DATA_PTR serialNumber = 0; - CSSM_DATA_PTR issuer = 0; - CSSM_DATA certData = {}; - CSSM_HANDLE resultsHandle = 0; - uint32 numberOfFields = 0; - CSSM_RETURN result; - void *mark; - - mark = PORT_ArenaMark(pl); - - if (!InitializeCL (&clHandle)) - goto loser; - status = SecCertificateGetData(cert, &certData); - if (status) - goto loser; - - /* Get the issuer from the cert. */ - result = CSSM_CL_CertGetFirstFieldValue(clHandle, &certData, &OID_X509V1IssuerNameStd, &resultsHandle, &numberOfFields, &issuer); - - /* @@@ Remove this once we are sure CSSMOID_X509V1IssuerNameStd is working. */ - /* Fall back on old normalized issuer if the new oid isn't supported yet. */ - if (result) - result = CSSM_CL_CertGetFirstFieldValue(clHandle, &certData, &CSSMOID_X509V1IssuerName, &resultsHandle, &numberOfFields, &issuer); - - if (result || numberOfFields < 1) - goto loser; - result = CSSM_CL_CertAbortQuery(clHandle, resultsHandle); - if (result) - goto loser; - - - /* Get the serialNumber from the cert. */ - result = CSSM_CL_CertGetFirstFieldValue(clHandle, &certData, &CSSMOID_X509V1SerialNumber, &resultsHandle, &numberOfFields, &serialNumber); - if (result || numberOfFields < 1) - goto loser; - result = CSSM_CL_CertAbortQuery(clHandle, resultsHandle); - if (result) - goto loser; - - /* Allocate the SecCmsIssuerAndSN struct. */ - certIssuerAndSN = (SecCmsIssuerAndSN *)PORT_ArenaZAlloc (pl, sizeof(SecCmsIssuerAndSN)); - if (certIssuerAndSN == NULL) - goto loser; - - /* Copy the issuer. */ - certIssuerAndSN->derIssuer.Data = (uint8 *) PORT_ArenaAlloc(pl, issuer->Length); - if (!certIssuerAndSN->derIssuer.Data) - goto loser; - PORT_Memcpy(certIssuerAndSN->derIssuer.Data, issuer->Data, issuer->Length); - certIssuerAndSN->derIssuer.Length = issuer->Length; - - /* Copy the serialNumber. */ - certIssuerAndSN->serialNumber.Data = (uint8 *) PORT_ArenaAlloc(pl, serialNumber->Length); - if (!certIssuerAndSN->serialNumber.Data) - goto loser; - PORT_Memcpy(certIssuerAndSN->serialNumber.Data, serialNumber->Data, serialNumber->Length); - certIssuerAndSN->serialNumber.Length = serialNumber->Length; - - PORT_ArenaUnmark(pl, mark); - - CSSM_CL_FreeFieldValue(clHandle, &CSSMOID_X509V1SerialNumber, serialNumber); - CSSM_CL_FreeFieldValue(clHandle, &OID_X509V1IssuerNameStd, issuer); - - CloseCL (clHandle); - - return certIssuerAndSN; - -loser: - PORT_ArenaRelease(pl, mark); - - if (serialNumber) - CSSM_CL_FreeFieldValue(clHandle, &CSSMOID_X509V1SerialNumber, serialNumber); - if (issuer) - CSSM_CL_FreeFieldValue(clHandle, &OID_X509V1IssuerNameStd, issuer); - - CloseCL (clHandle); - - PORT_SetError(SEC_INTERNAL_ONLY); - return NULL; -} - -// import a collection of certs into the temporary or permanent cert database -SECStatus CERT_ImportCerts(SecKeychainRef keychain, SECCertUsage usage, unsigned int ncerts, - SECItem **derCerts, SecCertificateRef **retCerts, Boolean keepCerts, Boolean caOnly, char *nickname) -{ - OSStatus rv = SECFailure; - SecCertificateRef cert; - unsigned int ci; - - // @@@ Do something with caOnly and nickname - if (caOnly || nickname) - abort(); - - for (ci = 0; ci < ncerts; ++ci) - { - rv = SecCertificateCreateFromData(derCerts[ci], CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, &cert); - if (rv) - break; - if (keepCerts) - { - rv = SecCertificateAddToKeychain(cert, keychain); - if (rv) - { - if (rv == errKCDuplicateItem) - rv = errSecSuccess; - else - { - CFRelease(cert); - break; - } - } - } - - if (retCerts) - { - // @@@ not yet - abort(); - } - else - CFRelease(cert); - } - - return rv; -} - -SECStatus CERT_SaveSMimeProfile(SecCertificateRef cert, SECItem *emailProfile,SECItem *profileTime) -{ - fprintf(stderr, "WARNING: CERT_SaveSMimeProfile unimplemented\n"); - return SECSuccess; -} - -// Check the hostname to make sure that it matches the shexp that -// is given in the common name of the certificate. -SECStatus CERT_VerifyCertName(SecCertificateRef cert, const char *hostname) -{ - fprintf(stderr, "WARNING: CERT_VerifyCertName unimplemented\n"); - return SECSuccess; -} - -/* -** OLD OBSOLETE FUNCTIONS with enum SECCertUsage - DO NOT USE FOR NEW CODE -** verify a certificate by checking validity times against a certain time, -** that we trust the issuer, and that the signature on the certificate is -** valid. -** "cert" the certificate to verify -** "checkSig" only check signatures if true -*/ -SECStatus -CERT_VerifyCert(SecKeychainRef keychainOrArray, SecCertificateRef cert, - CFTypeRef policies, CFAbsoluteTime stime, SecTrustRef *trustRef) -{ - CFArrayRef certificates; - const void *certs = cert; - SecTrustRef trust = NULL; - OSStatus rv; - - certificates = CFArrayCreate(NULL, &certs, 1, &kCFTypeArrayCallBacks); - rv = SecTrustCreateWithCertificates(certificates, policies, &trust); - CFRelease(certificates); - if (rv) - goto loser; - - rv = SecTrustSetKeychains(trust, keychainOrArray); - if (rv) - goto loser; - - CFDateRef verifyDate = CFDateCreate(NULL, stime); - rv = SecTrustSetVerifyDate(trust, verifyDate); - CFRelease(verifyDate); - if (rv) - goto loser; - - if (trustRef) - { - *trustRef = trust; - } - else - { - SecTrustResultType result; - /* The caller doesn't want a SecTrust object, so let's evaluate it for them. */ - rv = SecTrustEvaluate(trust, &result); - if (rv) - goto loser; - - switch (result) - { - case kSecTrustResultProceed: - case kSecTrustResultUnspecified: - /* TP Verification succeeded and there was either a UserTurst entry - telling us to procceed, or no user trust setting was specified. */ - CFRelease(trust); - break; - default: - PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); - rv = SECFailure; - goto loser; - break; - } - } - - return SECSuccess; -loser: - if (trust) - CFRelease(trust); - - return rv; -} - -CFTypeRef -CERT_PolicyForCertUsage(SECCertUsage certUsage) -{ - SecPolicySearchRef search; - SecPolicyRef policy = NULL; - const CSSM_OID *policyOID; - OSStatus rv; - - switch (certUsage) - { - case certUsageSSLServerWithStepUp: - case certUsageSSLCA: - case certUsageVerifyCA: - case certUsageAnyCA: - goto loser; - break; - case certUsageSSLClient: - case certUsageSSLServer: - policyOID = &CSSMOID_APPLE_TP_SSL; - break; - case certUsageUserCertImport: - policyOID = &CSSMOID_APPLE_TP_CSR_GEN; - break; - case certUsageStatusResponder: - policyOID = &CSSMOID_APPLE_TP_REVOCATION_OCSP; - break; - case certUsageObjectSigner: - case certUsageProtectedObjectSigner: - policyOID = &CSSMOID_APPLE_ISIGN; - break; - case certUsageEmailSigner: - case certUsageEmailRecipient: - policyOID = &CSSMOID_APPLE_X509_BASIC; - break; - default: - goto loser; - } - rv = SecPolicySearchCreate(CSSM_CERT_X_509v3, policyOID, NULL, &search); - if (rv) - goto loser; - - rv = SecPolicySearchCopyNext(search, &policy); - if (rv) - goto loser; - -loser: - CFRelease(search); - return policy; -} diff --git a/libsecurity_smime/lib/cert.h b/libsecurity_smime/lib/cert.h index e2c11364..0234979a 100644 --- a/libsecurity_smime/lib/cert.h +++ b/libsecurity_smime/lib/cert.h @@ -10,7 +10,7 @@ #ifndef _CERT_H_ #define _CERT_H_ 1 -#include "SecCmsBase.h" +#include #include #include #include @@ -40,7 +40,7 @@ SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef dbhandle, SecCertificateRef CERT_FindCertByNicknameOrEmailAddr(SecKeychainRef dbhandle, char *name); SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey); -void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey); +void SECKEY_DestroyPublicKey(SecPublicKeyRef CF_CONSUMED pubKey); SecPublicKeyRef SECKEY_CopyPrivateKey(SecPublicKeyRef privKey); void SECKEY_DestroyPrivateKey(SecPublicKeyRef privKey); void CERT_DestroyCertificate(SecCertificateRef cert); @@ -59,9 +59,9 @@ SecCertificateRef CERT_DupCertificate(SecCertificateRef cert); // Generate a certificate chain from a certificate. -CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage,Boolean includeRoot); +CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage,Boolean includeRoot, Boolean mustIncludeRoot); -CFArrayRef CERT_CertListFromCert(SecCertificateRef cert); +CF_RETURNS_RETAINED CFArrayRef CERT_CertListFromCert(SecCertificateRef cert); CFArrayRef CERT_DupCertList(CFArrayRef oldList); diff --git a/libsecurity_smime/lib/cmsattr.c b/libsecurity_smime/lib/cmsattr.c index c5eb1142..cd93c19c 100644 --- a/libsecurity_smime/lib/cmsattr.c +++ b/libsecurity_smime/lib/cmsattr.c @@ -130,6 +130,8 @@ SecCmsAttributeAddValue(PLArenaPool *poolp, SecCmsAttribute *attr, SecAsn1Item * if (SecCmsArrayAdd(poolp, (void ***)&(attr->values), (void *)copiedvalue) != SECSuccess) goto loser; + + SecCmsArraySort((void **)(attr->values), SecCmsUtilDERCompare, NULL, NULL); } PORT_ArenaUnmark(poolp, mark); diff --git a/libsecurity_smime/lib/cmscipher.c b/libsecurity_smime/lib/cmscipher.c index 3c86da76..dda5c853 100644 --- a/libsecurity_smime/lib/cmscipher.c +++ b/libsecurity_smime/lib/cmscipher.c @@ -353,7 +353,6 @@ SecCmsCipherContextStart(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorith default: // @@@ Implement rc5 params stuff. goto loser; - break; } } else @@ -420,7 +419,6 @@ SecCmsCipherContextStart(PRArenaPool *poolp, SecSymmetricKeyRef key, SECAlgorith default: // @@@ Implement rc5 params stuff. goto loser; - break; } } diff --git a/libsecurity_smime/lib/cmsdecode.c b/libsecurity_smime/lib/cmsdecode.c index 333cd1ee..c3c1e2e1 100644 --- a/libsecurity_smime/lib/cmsdecode.c +++ b/libsecurity_smime/lib/cmsdecode.c @@ -426,83 +426,84 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx, * proves they do it right. But it could find a bug in future * modifications/development, that is why it is here.) */ - PORT_Assert ((data != NULL && len) || final); - /* Debug check for 64 bits cast later */ - PORT_Assert (len <= UINT_MAX); + if (((data == NULL || len == 0) && !final) || + len > UINT_MAX) { + goto loser; + } if (!p7dcx->content.pointer) // might be ExContent?? return; - + cinfo = SecCmsContentGetContentInfo(p7dcx->content.pointer, p7dcx->type); if (cinfo->ciphcx != NULL) { - /* - * we are decrypting. - * - * XXX If we get an error, we do not want to do the digest or callback, - * but we want to keep decoding. Or maybe we want to stop decoding - * altogether if there is a callback, because obviously we are not - * sending the data back and they want to know that. - */ - - unsigned int outlen = 0; /* length of decrypted data */ - unsigned int buflen; /* length available for decrypted data */ - - /* find out about the length of decrypted data */ + /* + * we are decrypting. + * + * XXX If we get an error, we do not want to do the digest or callback, + * but we want to keep decoding. Or maybe we want to stop decoding + * altogether if there is a callback, because obviously we are not + * sending the data back and they want to know that. + */ + + unsigned int outlen = 0; /* length of decrypted data */ + unsigned int buflen; /* length available for decrypted data */ + + /* find out about the length of decrypted data */ /* 64 bits cast: Worst case here is we may not decrypt the full CMS blob, if the blob is bigger than 4GB */ - buflen = SecCmsCipherContextDecryptLength(cinfo->ciphcx, (unsigned int)len, final); - - /* - * it might happen that we did not provide enough data for a full - * block (decryption unit), and that there is no output available - */ - - /* no output available, AND no input? */ - if (buflen == 0 && len == 0) - goto loser; /* bail out */ + buflen = SecCmsCipherContextDecryptLength(cinfo->ciphcx, (unsigned int)len, final); + + /* + * it might happen that we did not provide enough data for a full + * block (decryption unit), and that there is no output available + */ + + /* no output available, AND no input? */ + if (buflen == 0 && len == 0) + goto loser; /* bail out */ + + /* + * have inner decoder: pass the data on (means inner content type is NOT data) + * no inner decoder: we have DATA in here: either call callback or store + */ + if (buflen != 0) { + /* there will be some output - need to make room for it */ + /* allocate buffer from the heap */ + buf = (unsigned char *)PORT_Alloc(buflen); + if (buf == NULL) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } + } - /* - * have inner decoder: pass the data on (means inner content type is NOT data) - * no inner decoder: we have DATA in here: either call callback or store - */ - if (buflen != 0) { - /* there will be some output - need to make room for it */ - /* allocate buffer from the heap */ - buf = (unsigned char *)PORT_Alloc(buflen); - if (buf == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } - } + /* + * decrypt incoming data + * buf can still be NULL here (and buflen == 0) here if we don't expect + * any output (see above), but we still need to call SecCmsCipherContextDecrypt to + * keep track of incoming data + */ + rv = SecCmsCipherContextDecrypt(cinfo->ciphcx, buf, &outlen, buflen, + data, (unsigned int)len, final); + if (rv != SECSuccess) { + p7dcx->error = PORT_GetError(); + goto loser; + } - /* - * decrypt incoming data - * buf can still be NULL here (and buflen == 0) here if we don't expect - * any output (see above), but we still need to call SecCmsCipherContextDecrypt to - * keep track of incoming data - */ - rv = SecCmsCipherContextDecrypt(cinfo->ciphcx, buf, &outlen, buflen, - data, (unsigned int)len, final); - if (rv != SECSuccess) { - p7dcx->error = PORT_GetError(); - goto loser; - } + //PORT_Assert (final || outlen == buflen); - //PORT_Assert (final || outlen == buflen); - - /* swap decrypted data in */ - data = buf; - len = outlen; + /* swap decrypted data in */ + data = buf; + len = outlen; } if (len == 0) - goto done; /* nothing more to do */ + goto done; /* nothing more to do */ /* * Update the running digests with plaintext bytes (if we need to). */ if (cinfo->digcx) - SecCmsDigestContextUpdate(cinfo->digcx, data, len); + SecCmsDigestContextUpdate(cinfo->digcx, data, len); /* at this point, we have the plain decoded & decrypted data */ /* which is either more encoded DER which we need to hand to the child decoder */ @@ -511,48 +512,46 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx, /* pass the content back to our caller or */ /* feed our freshly decrypted and decoded data into child decoder */ if (p7dcx->cb != NULL) { - (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len); - } -#if 1 - else -#endif - if (SecCmsContentInfoGetContentTypeTag(cinfo) == SEC_OID_PKCS7_DATA) { - /* store it in "inner" data item as well */ - /* find the DATA item in the encapsulated cinfo and store it there */ - storage = cinfo->content.data; - - offset = storage->Length; - - /* check for potential overflow */ - if (len >= (size_t)(INT_MAX - storage->Length)) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } + (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len); + } else if (SecCmsContentInfoGetContentTypeTag(cinfo) == SEC_OID_PKCS7_DATA) { + /* store it in "inner" data item as well */ + /* find the DATA item in the encapsulated cinfo and store it there */ + storage = cinfo->content.data; + + offset = storage->Length; + + /* check for potential overflow */ + if (len >= (size_t)(INT_MAX - storage->Length)) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } - if (storage->Length == 0) { - dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len); - } else { - dest = (unsigned char *)PORT_ArenaGrow(p7dcx->cmsg->poolp, - storage->Data, - storage->Length, - storage->Length + len); - } - if (dest == NULL) { - p7dcx->error = SEC_ERROR_NO_MEMORY; - goto loser; - } + if (storage->Length == 0) { + dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len); + } else { + dest = (unsigned char *)PORT_ArenaGrow(p7dcx->cmsg->poolp, + storage->Data, + storage->Length, + storage->Length + len); + } + if (dest == NULL) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } - storage->Data = dest; - storage->Length += len; + storage->Data = dest; + storage->Length += len; - /* copy it in */ - PORT_Memcpy(storage->Data + offset, data, len); + /* copy it in */ + if (data != NULL) { + PORT_Memcpy(storage->Data + offset, data, len); + } } done: loser: if (buf) - PORT_Free (buf); + PORT_Free (buf); } /* diff --git a/libsecurity_smime/lib/cmsdigest.c b/libsecurity_smime/lib/cmsdigest.c index 7b7b7acd..e31f88f6 100644 --- a/libsecurity_smime/lib/cmsdigest.c +++ b/libsecurity_smime/lib/cmsdigest.c @@ -50,7 +50,7 @@ #include #endif -#include "SecCmsDigestContext.h" +#include /* Return the maximum value between S and T (and U) */ #define MAX(S, T) ({__typeof__(S) _max_s = S; __typeof__(T) _max_t = T; _max_s > _max_t ? _max_s : _max_t;}) @@ -320,7 +320,7 @@ SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, case SEC_OID_SHA256: diglength = CC_SHA256_DIGEST_LENGTH; break; case SEC_OID_SHA384: diglength = CC_SHA384_DIGEST_LENGTH; break; case SEC_OID_SHA512: diglength = CC_SHA512_DIGEST_LENGTH; break; - default: goto loser; break; + default: goto loser; } digobj = cmsdigcx->digobjs[i]; @@ -341,7 +341,7 @@ SecCmsDigestContextFinishMultiple(SecCmsDigestContextRef cmsdigcx, case SEC_OID_SHA256: CC_SHA256_Final(digest->Data, digobj); break; case SEC_OID_SHA384: CC_SHA384_Final(digest->Data, digobj); break; case SEC_OID_SHA512: CC_SHA512_Final(digest->Data, digobj); break; - default: goto loser; break; + default: goto loser; } free(digobj); diff --git a/libsecurity_smime/lib/cmspubkey.c b/libsecurity_smime/lib/cmspubkey.c index 4e15bfc3..efbc8857 100644 --- a/libsecurity_smime/lib/cmspubkey.c +++ b/libsecurity_smime/lib/cmspubkey.c @@ -99,7 +99,7 @@ SecCmsUtilEncryptSymKeyRSAPubKey(PLArenaPool *poolp, } #endif /* allocate memory for the encrypted key */ -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX rv = SecKeyGetStrengthInBits(publickey, NULL, &data_len); if (rv) goto loser; @@ -1053,7 +1053,6 @@ SecCmsUtilDecryptSymKeyECDH( sharedInfo.suppPubInfo.Data = keyLenAsBytes; if (!SEC_ASN1EncodeItem(pool, &sharedInfoEnc, &sharedInfo, ECC_CMS_SharedInfoTemplate)) { - rv = errSecInternalComponent; goto out; } dumpBuf("receiver encoded SharedInfo", &sharedInfoEnc); @@ -1065,7 +1064,7 @@ SecCmsUtilDecryptSymKeyECDH( theirKeySizeInBits = pubKey->Length; pubKey->Length = (theirKeySizeInBits + 7) >> 3; theirPubData = CFDataCreate(NULL, pubKey->Data, pubKey->Length); - theirKeyLen = CFNumberCreate(NULL, kCFNumberSInt32Type, &theirKeySizeInBits); + theirKeyLen = CFNumberCreate(NULL, kCFNumberSInt64Type, &theirKeySizeInBits); const void *keys[] = { kSecAttrKeyType, kSecAttrKeyClass, kSecAttrKeySizeInBits }; const void *values[] = { kSecAttrKeyTypeECSECPrimeRandom, kSecAttrKeyClassPublic, theirKeyLen}; theirKeyAttrs = CFDictionaryCreate(NULL, keys, values, 3, @@ -1123,7 +1122,7 @@ SecCmsUtilDecryptSymKeyECDH( outKey = (SecSymmetricKeyRef)CFDataCreate(NULL, cek.Data, cek.Length); out: - if(pool != NULL) { + if (pool != NULL) { PORT_FreeArena(pool, PR_FALSE); } if (theirPubData) { CFRelease(theirPubData); } @@ -1136,7 +1135,7 @@ out: if (kekData) { CFRelease(kekData); } if (error) { CFRelease(error); } if (ciphercc) { CCCryptorRelease(ciphercc); } - if(outKey == NULL) { + if (outKey == NULL) { PORT_SetError(SEC_ERROR_NO_KEY); } return outKey; diff --git a/libsecurity_smime/lib/cmsrecinfo.c b/libsecurity_smime/lib/cmsrecinfo.c index 5ee5e52b..0b97c873 100644 --- a/libsecurity_smime/lib/cmsrecinfo.c +++ b/libsecurity_smime/lib/cmsrecinfo.c @@ -49,7 +49,7 @@ #include #include -#include "SecCmsRecipientInfo.h" +#include static Boolean nss_cmsrecipientinfo_usessubjectkeyid(SecCmsRecipientInfoRef ri) @@ -467,58 +467,27 @@ SecCmsRecipientInfoWrapBulkKey(SecCmsRecipientInfoRef ri, SecSymmetricKeyRef bul SecCertificateRef cert; SECOidTag certalgtag; OSStatus rv = SECSuccess; -#if 0 - SecAsn1Item * params = NULL; -#endif /* 0 */ SecCmsRecipientEncryptedKey *rek; SecCmsOriginatorIdentifierOrKey *oiok; const SECAlgorithmID *algid; SECAlgorithmID freeAlgID; PLArenaPool *poolp; - Boolean usesSubjKeyID; uint8_t nullData[2] = {SEC_ASN1_NULL, 0}; SECItem nullItem; SecCmsKeyAgreeRecipientInfo *kari; -#if USE_CDSA_CRYPTO - SecCmsKeyTransRecipientInfoEx *extra = NULL; -#endif poolp = ri->envelopedData->contentInfo.cmsg->poolp; cert = ri->cert; - usesSubjKeyID = nss_cmsrecipientinfo_usessubjectkeyid(ri); if (cert) { -#if USE_CDSA_CRYPTO - rv = SecCertificateGetAlgorithmID(cert,&algid); - if (rv) - return SECFailure; -#else const SecAsn1AlgId *length_data_swapped = (const SecAsn1AlgId *)SecCertificateGetPublicKeyAlgorithm(cert); freeAlgID.algorithm.Length = (size_t)length_data_swapped->algorithm.Data; freeAlgID.algorithm.Data = (uint8_t *)length_data_swapped->algorithm.Length; freeAlgID.parameters.Length = (size_t)length_data_swapped->parameters.Data; freeAlgID.parameters.Data = (uint8_t *)length_data_swapped->parameters.Length; algid = &freeAlgID; -#endif - } -#if USE_CDSA_CRYPTO - else if (usesSubjKeyID) { - extra = &ri->ri.keyTransRecipientInfoEx; - /* sanity check */ - PORT_Assert(extra->pubKey); - if (!extra->pubKey) { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - rv = SecKeyGetAlgorithmID(extra->pubKey,&algid); - if (rv) - - return SECFailure; - certalgtag = SECOID_GetAlgorithmTag(algid); - } -#endif - else { - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; + } else { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; } /* XXX set ri->recipientInfoType to the proper value here */ @@ -526,112 +495,57 @@ SecCmsRecipientInfoWrapBulkKey(SecCmsRecipientInfoRef ri, SecSymmetricKeyRef bul certalgtag = SECOID_GetAlgorithmTag(algid); switch (certalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - /* wrap the symkey */ - if (cert) { - rv = SecCmsUtilEncryptSymKeyRSA(poolp, cert, bulkkey, - &ri->ri.keyTransRecipientInfo.encKey); - if (rv != SECSuccess) - break; -#if USE_CDSA_CRYPTO - } else if (usesSubjKeyID) { - PORT_Assert(extra != NULL); - rv = SecCmsUtilEncryptSymKeyRSAPubKey(poolp, extra->pubKey, - bulkkey, &ri->ri.keyTransRecipientInfo.encKey); - if (rv != SECSuccess) - break; -#endif - } - - rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL); - break; -#if 0 - case SEC_OID_MISSI_KEA_DSS_OLD: - case SEC_OID_MISSI_KEA_DSS: - case SEC_OID_MISSI_KEA: - rv = SecCmsUtilEncryptSymKeyMISSI(poolp, cert, bulkkey, - bulkalgtag, - &ri->ri.keyTransRecipientInfo.encKey, - ¶ms, ri->cmsg->pwfn_arg); - if (rv != SECSuccess) - break; - - /* here, we DO need to pass the params to the wrap function because, with - * RSA, there is no funny stuff going on with generation of IV vectors or so */ - rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, params); - break; - case SEC_OID_X942_DIFFIE_HELMAN_KEY: /* dh-public-number */ - rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[0]; - if (rek == NULL) { - rv = SECFailure; - break; - } - - oiok = &(ri->ri.keyAgreeRecipientInfo.originatorIdentifierOrKey); - PORT_Assert(oiok->identifierType == SecCmsOriginatorIDOrKeyOriginatorPublicKey); - - /* see RFC2630 12.3.1.1 */ - if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier, - SEC_OID_X942_DIFFIE_HELMAN_KEY, NULL) != SECSuccess) { - rv = SECFailure; - break; - } - - /* this will generate a key pair, compute the shared secret, */ - /* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */ - /* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */ - rv = SecCmsUtilEncryptSymKeyESDH(poolp, cert, bulkkey, - &rek->encKey, - &ri->ri.keyAgreeRecipientInfo.ukm, - &ri->ri.keyAgreeRecipientInfo.keyEncAlg, - &oiok->id.originatorPublicKey.publicKey); + case SEC_OID_PKCS1_RSA_ENCRYPTION: + /* wrap the symkey */ + if (cert) { + rv = SecCmsUtilEncryptSymKeyRSA(poolp, cert, bulkkey, + &ri->ri.keyTransRecipientInfo.encKey); + if (rv != SECSuccess) + break; + } - break; -#endif /* 0 */ - case SEC_OID_EC_PUBLIC_KEY: - /* These were set up in nss_cmsrecipientinfo_create() */ - kari = &ri->ri.keyAgreeRecipientInfo; - rek = kari->recipientEncryptedKeys[0]; - if (rek == NULL) { - rv = SECFailure; + rv = SECOID_SetAlgorithmID(poolp, &(ri->ri.keyTransRecipientInfo.keyEncAlg), certalgtag, NULL); break; - } + case SEC_OID_EC_PUBLIC_KEY: + /* These were set up in nss_cmsrecipientinfo_create() */ + kari = &ri->ri.keyAgreeRecipientInfo; + rek = kari->recipientEncryptedKeys[0]; + if (rek == NULL) { + rv = SECFailure; + break; + } - oiok = &(kari->originatorIdentifierOrKey); - PORT_Assert(oiok->identifierType == SecCmsOriginatorIDOrKeyOriginatorPublicKey); - - /* - * RFC 3278 3.1.1 says this AlgId must contain NULL params which is contrary to - * any other use of the SEC_OID_EC_PUBLIC_KEY OID. So we provide one - * explicitly instead of mucking up the login in SECOID_SetAlgorithmID(). - */ - nullItem.Data = nullData; - nullItem.Length = 2; - if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier, - SEC_OID_EC_PUBLIC_KEY, &nullItem) != SECSuccess) { + oiok = &(kari->originatorIdentifierOrKey); + PORT_Assert(oiok->identifierType == SecCmsOriginatorIDOrKeyOriginatorPublicKey); + + /* + * RFC 3278 3.1.1 says this AlgId must contain NULL params which is contrary to + * any other use of the SEC_OID_EC_PUBLIC_KEY OID. So we provide one + * explicitly instead of mucking up the login in SECOID_SetAlgorithmID(). + */ + nullItem.Data = nullData; + nullItem.Length = 2; + if (SECOID_SetAlgorithmID(poolp, &oiok->id.originatorPublicKey.algorithmIdentifier, + SEC_OID_EC_PUBLIC_KEY, &nullItem) != SECSuccess) { + rv = SECFailure; + break; + } + /* this will generate a key pair, compute the shared secret, */ + /* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */ + /* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */ + rv = SecCmsUtilEncryptSymKeyECDH(poolp, cert, bulkkey, + &rek->encKey, + &kari->ukm, + &kari->keyEncAlg, + &oiok->id.originatorPublicKey.publicKey); + break; + default: + /* other algorithms not supported yet */ + /* NOTE that we do not support any KEK algorithm */ + PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); rv = SECFailure; break; - } - /* this will generate a key pair, compute the shared secret, */ - /* derive a key and ukm for the keyEncAlg out of it, encrypt the bulk key with */ - /* the keyEncAlg, set encKey, keyEncAlg, publicKey etc. */ - rv = SecCmsUtilEncryptSymKeyECDH(poolp, cert, bulkkey, - &rek->encKey, - &kari->ukm, - &kari->keyEncAlg, - &oiok->id.originatorPublicKey.publicKey); - break; - default: - /* other algorithms not supported yet */ - /* NOTE that we do not support any KEK algorithm */ - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rv = SECFailure; - break; } -#if 0 - if (freeSpki) - SECKEY_DestroySubjectPublicKeyInfo(freeSpki); -#endif return rv; } @@ -653,74 +567,65 @@ SecCmsRecipientInfoUnwrapBulkKey(SecCmsRecipientInfoRef ri, int subIndex, int error; ri->cert = CERT_DupCertificate(cert); - /* mark the recipientInfo so we can find it later */ + /* mark the recipientInfo so we can find it later */ switch (ri->recipientInfoType) { - case SecCmsRecipientInfoIDKeyTrans: - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg)); - enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */ - switch (encalgtag) { - case SEC_OID_PKCS1_RSA_ENCRYPTION: - /* RSA encryption algorithm: */ - /* get the symmetric (bulk) key by unwrapping it using our private key */ - bulkkey = SecCmsUtilDecryptSymKeyRSA(privkey, enckey, bulkalgtag); - break; -#if 0 - case SEC_OID_NETSCAPE_SMIME_KEA: - /* FORTEZZA key exchange algorithm */ - /* the supplemental data is in the parameters of encalg */ - encalg = &(ri->ri.keyTransRecipientInfo.keyEncAlg); - bulkkey = SecCmsUtilDecryptSymKeyMISSI(privkey, enckey, encalg, bulkalgtag, ri->cmsg->pwfn_arg); - break; -#endif /* 0 */ - default: - error = SEC_ERROR_UNSUPPORTED_KEYALG; - goto loser; - } - break; - case SecCmsRecipientInfoIDKeyAgree: - encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg)); - switch (encalgtag) { - case SEC_OID_X942_DIFFIE_HELMAN_KEY: - /* Diffie-Helman key exchange */ - /* XXX not yet implemented */ - /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */ - /* we support ephemeral-static DH only, so if the recipientinfo */ - /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */ - /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */ - /* content encryption key using a Unwrap op */ - /* the derive operation has to generate the key using the algorithm in RFC2631 */ - error = SEC_ERROR_UNSUPPORTED_KEYALG; - break; - case SEC_OID_DH_SINGLE_STD_SHA1KDF: - { - /* ephemeral-static ECDH */ - enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey); - encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg); - SecCmsKeyAgreeRecipientInfo *kari = &ri->ri.keyAgreeRecipientInfo; - SecCmsOriginatorIdentifierOrKey *oiok = &kari->originatorIdentifierOrKey; - if(oiok->identifierType != SecCmsOriginatorIDOrKeyOriginatorPublicKey) { - dprintf("SEC_OID_EC_PUBLIC_KEY unwrap key: bad oiok.id\n"); - error = SEC_ERROR_LIBRARY_FAILURE; - goto loser; + case SecCmsRecipientInfoIDKeyTrans: + encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyTransRecipientInfo.keyEncAlg)); + enckey = &(ri->ri.keyTransRecipientInfo.encKey); /* ignore subIndex */ + switch (encalgtag) { + case SEC_OID_PKCS1_RSA_ENCRYPTION: + /* RSA encryption algorithm: */ + /* get the symmetric (bulk) key by unwrapping it using our private key */ + bulkkey = SecCmsUtilDecryptSymKeyRSA(privkey, enckey, bulkalgtag); + break; + default: + error = SEC_ERROR_UNSUPPORTED_KEYALG; + goto loser; } - SecCmsOriginatorPublicKey *opk = &oiok->id.originatorPublicKey; - /* FIXME - verify opk->algorithmIdentifier here? */ - SecAsn1Item senderPubKey = opk->publicKey; - SecAsn1Item *ukm = &kari->ukm; - bulkkey = SecCmsUtilDecryptSymKeyECDH(privkey, enckey, ukm, encalg, bulkalgtag, &senderPubKey); break; - } - default: - error = SEC_ERROR_UNSUPPORTED_KEYALG; - goto loser; - } - break; - case SecCmsRecipientInfoIDKEK: - /* not supported yet */ - error = SEC_ERROR_UNSUPPORTED_KEYALG; - goto loser; - break; + case SecCmsRecipientInfoIDKeyAgree: + encalgtag = SECOID_GetAlgorithmTag(&(ri->ri.keyAgreeRecipientInfo.keyEncAlg)); + switch (encalgtag) { + case SEC_OID_X942_DIFFIE_HELMAN_KEY: + /* Diffie-Helman key exchange */ + /* XXX not yet implemented */ + /* XXX problem: SEC_OID_X942_DIFFIE_HELMAN_KEY points to a PKCS3 mechanism! */ + /* we support ephemeral-static DH only, so if the recipientinfo */ + /* has originator stuff in it, we punt (or do we? shouldn't be that hard...) */ + /* first, we derive the KEK (a symkey!) using a Derive operation, then we get the */ + /* content encryption key using a Unwrap op */ + /* the derive operation has to generate the key using the algorithm in RFC2631 */ + error = SEC_ERROR_UNSUPPORTED_KEYALG; + goto loser; + case SEC_OID_DH_SINGLE_STD_SHA1KDF: + { + /* ephemeral-static ECDH */ + enckey = &(ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[subIndex]->encKey); + encalg = &(ri->ri.keyAgreeRecipientInfo.keyEncAlg); + SecCmsKeyAgreeRecipientInfo *kari = &ri->ri.keyAgreeRecipientInfo; + SecCmsOriginatorIdentifierOrKey *oiok = &kari->originatorIdentifierOrKey; + if(oiok->identifierType != SecCmsOriginatorIDOrKeyOriginatorPublicKey) { + dprintf("SEC_OID_EC_PUBLIC_KEY unwrap key: bad oiok.id\n"); + error = SEC_ERROR_LIBRARY_FAILURE; + goto loser; + } + SecCmsOriginatorPublicKey *opk = &oiok->id.originatorPublicKey; + /* FIXME - verify opk->algorithmIdentifier here? */ + SecAsn1Item senderPubKey = opk->publicKey; + SecAsn1Item *ukm = &kari->ukm; + bulkkey = SecCmsUtilDecryptSymKeyECDH(privkey, enckey, ukm, encalg, bulkalgtag, &senderPubKey); + break; + } + default: + error = SEC_ERROR_UNSUPPORTED_KEYALG; + goto loser; + } + break; + case SecCmsRecipientInfoIDKEK: + /* not supported yet */ + error = SEC_ERROR_UNSUPPORTED_KEYALG; + goto loser; } /* XXXX continue here */ return bulkkey; diff --git a/libsecurity_smime/lib/cmssigdata.c b/libsecurity_smime/lib/cmssigdata.c index 57df961b..6bef5b16 100644 --- a/libsecurity_smime/lib/cmssigdata.c +++ b/libsecurity_smime/lib/cmssigdata.c @@ -692,7 +692,7 @@ SecCmsSignedDataAddCertChain(SecCmsSignedDataRef sigd, SecCertificateRef cert) usage = certUsageEmailSigner; /* do not include root */ - certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE); + certlist = CERT_CertChainFromCert(cert, usage, PR_FALSE, PR_FALSE); if (certlist == NULL) return SECFailure; diff --git a/libsecurity_smime/lib/cmssiginfo.c b/libsecurity_smime/lib/cmssiginfo.c index a3144dfa..18ab6d45 100644 --- a/libsecurity_smime/lib/cmssiginfo.c +++ b/libsecurity_smime/lib/cmssiginfo.c @@ -654,13 +654,13 @@ SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, SecAsn1Item * digest, Sec PLArenaPool *poolp; if (signerinfo == NULL) - return SECFailure; + return SECFailure; /* SecCmsSignerInfoGetSigningCertificate will fail if 2nd parm is NULL and */ /* cert has not been verified */ if ((cert = SecCmsSignerInfoGetSigningCertificate(signerinfo, NULL)) == NULL) { - vs = SecCmsVSSigningCertNotFound; - goto loser; + vs = SecCmsVSSigningCertNotFound; + goto loser; } publickey = SecCertificateCopyKey(cert); @@ -668,77 +668,77 @@ SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, SecAsn1Item * digest, Sec goto loser; if (!SecCmsArrayIsEmpty((void **)signerinfo->authAttr)) { - if (contentType) { - /* - * Check content type - * - * RFC2630 sez that if there are any authenticated attributes, - * then there must be one for content type which matches the - * content type of the content being signed, and there must - * be one for message digest which matches our message digest. - * So check these things first. - */ - if ((attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, - SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE)) == NULL) - { - vs = SecCmsVSMalformedSignature; - goto loser; - } - - if (SecCmsAttributeCompareValue(attr, contentType) == PR_FALSE) { - vs = SecCmsVSMalformedSignature; - goto loser; - } - } + if (contentType) { + /* + * Check content type + * + * RFC2630 sez that if there are any authenticated attributes, + * then there must be one for content type which matches the + * content type of the content being signed, and there must + * be one for message digest which matches our message digest. + * So check these things first. + */ + if ((attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, + SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE)) == NULL) + { + vs = SecCmsVSMalformedSignature; + goto loser; + } - /* - * Check digest - */ - if ((attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE)) == NULL) - { - vs = SecCmsVSMalformedSignature; - goto loser; - } - if (SecCmsAttributeCompareValue(attr, digest) == PR_FALSE) { - vs = SecCmsVSDigestMismatch; - goto loser; - } + if (SecCmsAttributeCompareValue(attr, contentType) == PR_FALSE) { + vs = SecCmsVSMalformedSignature; + goto loser; + } + } - if ((poolp = PORT_NewArena (1024)) == NULL) { - vs = SecCmsVSProcessingError; - goto loser; - } + /* + * Check digest + */ + if ((attr = SecCmsAttributeArrayFindAttrByOidTag(signerinfo->authAttr, SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE)) == NULL) + { + vs = SecCmsVSMalformedSignature; + goto loser; + } + if (SecCmsAttributeCompareValue(attr, digest) == PR_FALSE) { + vs = SecCmsVSDigestMismatch; + goto loser; + } - /* - * Check signature - * - * The signature is based on a digest of the DER-encoded authenticated - * attributes. So, first we encode and then we digest/verify. - * we trust the decoder to have the attributes in the right (sorted) order - */ - encoded_attrs.Data = NULL; - encoded_attrs.Length = 0; + if ((poolp = PORT_NewArena (1024)) == NULL) { + vs = SecCmsVSProcessingError; + goto loser; + } - if (SecCmsAttributeArrayEncode(poolp, &(signerinfo->authAttr), &encoded_attrs) == NULL || - encoded_attrs.Data == NULL || encoded_attrs.Length == 0) - { - vs = SecCmsVSProcessingError; - goto loser; - } + /* + * Check signature + * + * The signature is based on a digest of the DER-encoded authenticated + * attributes. So, first we encode and then we digest/verify. + * we trust the decoder to have the attributes in the right (sorted) order + */ + encoded_attrs.Data = NULL; + encoded_attrs.Length = 0; + + if (SecCmsAttributeArrayEncode(poolp, &(signerinfo->authAttr), &encoded_attrs) == NULL || + encoded_attrs.Data == NULL || encoded_attrs.Length == 0) + { + vs = SecCmsVSProcessingError; + goto loser; + } if (errSecSuccess == SecKeyDigestAndVerify(publickey, &signerinfo->digestAlg, encoded_attrs.Data, encoded_attrs.Length, signerinfo->encDigest.Data, signerinfo->encDigest.Length)) vs = SecCmsVSGoodSignature; else vs = SecCmsVSBadSignature; - PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */ + PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */ } else { - SecAsn1Item * sig; + SecAsn1Item * sig; - /* No authenticated attributes. The signature is based on the plain message digest. */ - sig = &(signerinfo->encDigest); - if (sig->Length == 0) - goto loser; + /* No authenticated attributes. The signature is based on the plain message digest. */ + sig = &(signerinfo->encDigest); + if (sig->Length == 0) + goto loser; if (SecKeyVerifyDigest(publickey, &signerinfo->digestAlg, digest->Data, digest->Length, sig->Data, sig->Length)) vs = SecCmsVSBadSignature; @@ -747,28 +747,28 @@ SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, SecAsn1Item * digest, Sec } if (vs == SecCmsVSBadSignature) { - /* - * XXX Change the generic error into our specific one, because - * in that case we get a better explanation out of the Security - * Advisor. This is really a bug in our error strings (the - * "generic" error has a lousy/wrong message associated with it - * which assumes the signature verification was done for the - * purposes of checking the issuer signature on a certificate) - * but this is at least an easy workaround and/or in the - * Security Advisor, which specifically checks for the error - * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation - * in that case but does not similarly check for - * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would - * probably say the wrong thing in the case that it *was* the - * certificate signature check that failed during the cert - * verification done above. Our error handling is really a mess. - */ - if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE) - PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); + /* + * XXX Change the generic error into our specific one, because + * in that case we get a better explanation out of the Security + * Advisor. This is really a bug in our error strings (the + * "generic" error has a lousy/wrong message associated with it + * which assumes the signature verification was done for the + * purposes of checking the issuer signature on a certificate) + * but this is at least an easy workaround and/or in the + * Security Advisor, which specifically checks for the error + * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation + * in that case but does not similarly check for + * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would + * probably say the wrong thing in the case that it *was* the + * certificate signature check that failed during the cert + * verification done above. Our error handling is really a mess. + */ + if (PORT_GetError() == SEC_ERROR_BAD_SIGNATURE) + PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE); } if (publickey != NULL) - CFRelease(publickey); + CFRelease(publickey); signerinfo->verificationStatus = vs; @@ -776,7 +776,7 @@ SecCmsSignerInfoVerify(SecCmsSignerInfoRef signerinfo, SecAsn1Item * digest, Sec loser: if (publickey != NULL) - SECKEY_DestroyPublicKey (publickey); + SECKEY_DestroyPublicKey (publickey); signerinfo->verificationStatus = vs; @@ -1651,35 +1651,40 @@ SecCmsSignerInfoSaveSMIMEProfile(SecCmsSignerInfoRef signerinfo) /* * SecCmsSignerInfoIncludeCerts - set cert chain inclusion mode for this signer */ -OSStatus -SecCmsSignerInfoIncludeCerts(SecCmsSignerInfoRef signerinfo, SecCmsCertChainMode cm, SECCertUsage usage) -{ - if (signerinfo->cert == NULL) - return SECFailure; + OSStatus + SecCmsSignerInfoIncludeCerts(SecCmsSignerInfoRef signerinfo, SecCmsCertChainMode cm, SECCertUsage usage) + { + if (signerinfo->cert == NULL) { + return SECFailure; + } - /* don't leak if we get called twice */ - if (signerinfo->certList != NULL) { - CFRelease(signerinfo->certList); - signerinfo->certList = NULL; - } + /* don't leak if we get called twice */ + if (signerinfo->certList != NULL) { + CFRelease(signerinfo->certList); + signerinfo->certList = NULL; + } - switch (cm) { - case SecCmsCMNone: - signerinfo->certList = NULL; - break; - case SecCmsCMCertOnly: - signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); - break; - case SecCmsCMCertChain: - signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE); - break; - case SecCmsCMCertChainWithRoot: - signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE); - break; - } + switch (cm) { + case SecCmsCMNone: + signerinfo->certList = NULL; + break; + case SecCmsCMCertOnly: + signerinfo->certList = CERT_CertListFromCert(signerinfo->cert); + break; + case SecCmsCMCertChain: + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE, PR_FALSE); + break; + case SecCmsCMCertChainWithRoot: + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE, PR_FALSE); + break; + case SecCmsCMCertChainWithRootOrFail: + signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE, PR_TRUE); + break; + } - if (cm != SecCmsCMNone && signerinfo->certList == NULL) - return SECFailure; - - return SECSuccess; -} + if (cm != SecCmsCMNone && signerinfo->certList == NULL) { + return SECFailure; + } + + return SECSuccess; + } diff --git a/libsecurity_smime/lib/crypto-embedded.c b/libsecurity_smime/lib/crypto-embedded.c index da4b7956..c816df52 100644 --- a/libsecurity_smime/lib/crypto-embedded.c +++ b/libsecurity_smime/lib/crypto-embedded.c @@ -91,7 +91,6 @@ CERT_VerifyCert(SecKeychainRef keychainOrArray __unused, CFArrayRef certs, PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); rv = SECFailure; goto loser; - break; } } @@ -103,7 +102,7 @@ loser: return rv; } -static CFTypeRef CERT_FindItemInAllAvailableKeychains(CFDictionaryRef query) { +static CF_RETURNS_RETAINED CFTypeRef CERT_FindItemInAllAvailableKeychains(CFDictionaryRef query) { CFTypeRef item = NULL; CFMutableDictionaryRef q = NULL; CFDictionaryRef whoAmI = NULL; @@ -151,7 +150,7 @@ SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray, return (SecCertificateRef)result; } -CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot) +CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot, Boolean mustIncludeRoot) { CFMutableArrayRef certs = NULL; SecPolicyRef policy = NULL; @@ -159,16 +158,19 @@ CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SE CFArrayRef wrappedCert = NULL; policy = SecPolicyCreateBasicX509(); - if (!policy) + if (!policy) { goto out; + } wrappedCert = CERT_CertListFromCert(cert); - if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust)) + if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust)) { goto out; + } SecTrustResultType result; - if (SecTrustEvaluate(trust, &result)) + if (SecTrustEvaluate(trust, &result)) { goto out; + } CFIndex idx, count = SecTrustGetCertificateCount(trust); /* If we weren't able to build a chain to a self-signed cert, warn. */ @@ -177,26 +179,34 @@ CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SE if (lastCert && (0 == SecCertificateIsSelfSigned(lastCert, &isSelfSigned)) && !isSelfSigned) { CFStringRef commonName = NULL; (void)SecCertificateCopyCommonName(cert, &commonName); - fprintf(stderr, "Warning: unable to build chain to self-signed root for signer \"%s\"", + fprintf(stderr, "Warning: unable to build chain to self-signed root for signer \"%s\"\n", commonName ? CFStringGetCStringPtr(commonName, kCFStringEncodingUTF8) : ""); if (commonName) { CFRelease(commonName); } + + // we don't have a root, so if the caller required one, fail + if (mustIncludeRoot) { + goto out; + } } /* We don't drop the root if there is only 1 certificate in the chain. */ - if (!includeRoot && count > 1) { count--; } + if (isSelfSigned && !includeRoot && count > 1) { + count--; + } certs = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); - for(idx = 0; idx < count; idx++) + for(idx = 0; idx < count; idx++) { CFArrayAppendValue(certs, SecTrustGetCertificateAtIndex(trust, idx)); + } out: - if (trust) CFRelease(trust); - if (policy) CFRelease(policy); - if (wrappedCert) CFRelease(wrappedCert); + if (trust) { CFRelease(trust); } + if (policy) { CFRelease(policy); } + if (wrappedCert) { CFRelease(wrappedCert); } return certs; } -CFArrayRef CERT_CertListFromCert(SecCertificateRef cert) +CF_RETURNS_RETAINED CFArrayRef CERT_CertListFromCert(SecCertificateRef cert) { const void *value = cert; return cert ? CFArrayCreate(NULL, &value, 1, &kCFTypeArrayCallBacks) : NULL; @@ -279,7 +289,7 @@ SecAsn1Item *CERT_FindSMimeProfile(SecCertificateRef cert) // Generate a certificate key from the issuer and serialnumber, then look it up in the database. // Return the cert if found. "issuerAndSN" is the issuer and serial number to look for -static CFTypeRef CERT_FindByIssuerAndSN (CFTypeRef keychainOrArray, CFTypeRef class, const SecCmsIssuerAndSN *issuerAndSN) +static CF_RETURNS_RETAINED CFTypeRef CERT_FindByIssuerAndSN (CFTypeRef keychainOrArray, CFTypeRef class, const SecCmsIssuerAndSN *issuerAndSN) { CFTypeRef ident = NULL; CFDictionaryRef query = NULL; @@ -344,7 +354,7 @@ SecCertificateRef CERT_FindCertificateByIssuerAndSN (CFTypeRef keychainOrArray, // Generate a certificate key from the Subject Key ID, then look it up in the database. // Return the cert if found. "subjKeyID" is the Subject Key ID to look for -static CFTypeRef CERT_FindBySubjectKeyID (CFTypeRef keychainOrArray, CFTypeRef class, const SecAsn1Item *subjKeyID) +static CF_RETURNS_RETAINED CFTypeRef CERT_FindBySubjectKeyID (CFTypeRef keychainOrArray, CFTypeRef class, const SecAsn1Item *subjKeyID) { CFTypeRef ident = NULL; CFDictionaryRef query = NULL; @@ -400,7 +410,7 @@ SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey) return pubKey; } -void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey) +void SECKEY_DestroyPublicKey(SecPublicKeyRef CF_CONSUMED pubKey) { CFRelease(pubKey); } diff --git a/libsecurity_smime/lib/cryptohi.c b/libsecurity_smime/lib/cryptohi.c deleted file mode 100644 index 0ef64d99..00000000 --- a/libsecurity_smime/lib/cryptohi.c +++ /dev/null @@ -1,548 +0,0 @@ -/* - * crypto.h - public data structures and prototypes for the crypto library - * - * The contents of this file are subject to the Mozilla Public - * License Version 1.1 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS - * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or - * implied. See the License for the specific language governing - * rights and limitations under the License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is Netscape - * Communications Corporation. Portions created by Netscape are - * Copyright (C) 1994-2000 Netscape Communications Corporation. All - * Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the - * terms of the GNU General Public License Version 2 or later (the - * "GPL"), in which case the provisions of the GPL are applicable - * instead of those above. If you wish to allow use of your - * version of this file only under the terms of the GPL and not to - * allow others to use your version of this file under the MPL, - * indicate your decision by deleting the provisions above and - * replace them with the notice and other provisions required by - * the GPL. If you do not delete the provisions above, a recipient - * may use your version of this file under either the MPL or the - * GPL. - */ - -#include "cryptohi.h" - -#include "secoid.h" -#include "cmspriv.h" -#include -#include -#include -#include -#include - -static CSSM_CSP_HANDLE gCsp = 0; -static char gCssmInitialized = 0; - -/* @@@ Ugly hack casting, but the extra argument at the end will be ignored. */ -static CSSM_API_MEMORY_FUNCS memFuncs = -{ - (CSSM_MALLOC)malloc, - (CSSM_FREE)free, - (CSSM_REALLOC)realloc, - (CSSM_CALLOC)calloc, - NULL -}; - -/* - * - * SecCspHandleForAlgorithm - * @@@ This function should get more parameters like keysize and operation required and use mds. - * - */ -CSSM_CSP_HANDLE -SecCspHandleForAlgorithm(CSSM_ALGORITHMS algorithm) -{ - - if (!gCsp) - { - CSSM_VERSION version = { 2, 0 }; - CSSM_RETURN rv; - - if (!gCssmInitialized) - { - CSSM_GUID myGuid = { 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } }; - CSSM_PVC_MODE pvcPolicy = CSSM_PVC_NONE; - - rv = CSSM_Init (&version, CSSM_PRIVILEGE_SCOPE_NONE, &myGuid, CSSM_KEY_HIERARCHY_NONE, &pvcPolicy, NULL); - if (rv) - goto loser; - gCssmInitialized = 1; - } - - rv = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); - if (rv) - goto loser; - rv = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &memFuncs, 0, CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, NULL, 0, NULL, &gCsp); - } - -loser: - return gCsp; -} - -CSSM_ALGORITHMS -SECOID_FindyCssmAlgorithmByTag(SECOidTag algTag) -{ - const SECOidData *oidData = SECOID_FindOIDByTag(algTag); - return oidData ? oidData->cssmAlgorithm : CSSM_ALGID_NONE; -} - -SECStatus -SEC_SignData(SecAsn1Item *result, unsigned char *buf, int len, - SecPrivateKeyRef pk, SECOidTag digAlgTag, SECOidTag sigAlgTag) -{ - const CSSM_ACCESS_CREDENTIALS *accessCred; - CSSM_ALGORITHMS algorithm; - CSSM_CC_HANDLE cc = 0; - CSSM_CSP_HANDLE csp; - OSStatus rv; - SecAsn1Item dataBuf = { (uint32)len, (uint8_t *)buf }; - SecAsn1Item sig = {}; - const CSSM_KEY *key; - - algorithm = SECOID_FindyCssmAlgorithmByTag(SecCmsUtilMakeSignatureAlgorithm(digAlgTag, sigAlgTag)); - if (!algorithm) - { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rv = SECFailure; - goto loser; - } - - rv = SecKeyGetCSPHandle(pk, &csp); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - rv = SecKeyGetCSSMKey(pk, &key); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - rv = SecKeyGetCredentials(pk, CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault, &accessCred); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - - rv = CSSM_CSP_CreateSignatureContext(csp, algorithm, accessCred, key, &cc); - if (rv) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - rv = CSSM_SignData(cc, &dataBuf, 1, CSSM_ALGID_NONE, &sig); - if (rv) { - SECErrorCodes code; - if (CSSM_ERRCODE(rv) == CSSM_ERRCODE_USER_CANCELED - || CSSM_ERRCODE(rv) == CSSM_ERRCODE_OPERATION_AUTH_DENIED) - code = SEC_ERROR_USER_CANCELLED; - else if (CSSM_ERRCODE(rv) == CSSM_ERRCODE_NO_USER_INTERACTION - || rv == CSSMERR_CSP_KEY_USAGE_INCORRECT) - code = SEC_ERROR_INADEQUATE_KEY_USAGE; - else - code = SEC_ERROR_LIBRARY_FAILURE; - - PORT_SetError(code); - goto loser; - } - - result->Length = sig.Length; - result->Data = sig.Data; - -loser: - if (cc) - CSSM_DeleteContext(cc); - - return rv; -} - -SECStatus -SGN_Digest(SecPrivateKeyRef pk, SECOidTag digAlgTag, SECOidTag sigAlgTag, SecAsn1Item *result, SecAsn1Item *digest) -{ - const CSSM_ACCESS_CREDENTIALS *accessCred; - CSSM_ALGORITHMS digalg, sigalg; - CSSM_CC_HANDLE cc = 0; - CSSM_CSP_HANDLE csp; - const CSSM_KEY *key; - SecAsn1Item sig = {}; - OSStatus rv; - - digalg = SECOID_FindyCssmAlgorithmByTag(digAlgTag); - sigalg = SECOID_FindyCssmAlgorithmByTag(sigAlgTag); - if (!digalg || !sigalg) - { - PORT_SetError(SEC_ERROR_INVALID_ALGORITHM); - rv = SECFailure; - goto loser; - } - - rv = SecKeyGetCSPHandle(pk, &csp); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - rv = SecKeyGetCSSMKey(pk, &key); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - rv = SecKeyGetCredentials(pk, CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault, &accessCred); - if (rv) { - PORT_SetError(SEC_ERROR_BAD_KEY); - goto loser; - } - - rv = CSSM_CSP_CreateSignatureContext(csp, sigalg, accessCred, key, &cc); - if (rv) { - PORT_SetError(SEC_ERROR_NO_MEMORY); - goto loser; - } - - rv = CSSM_SignData(cc, digest, 1, digalg, &sig); - if (rv) { - SECErrorCodes code; - if (CSSM_ERRCODE(rv) == CSSM_ERRCODE_USER_CANCELED - || CSSM_ERRCODE(rv) == CSSM_ERRCODE_OPERATION_AUTH_DENIED) - code = SEC_ERROR_USER_CANCELLED; - else if (CSSM_ERRCODE(rv) == CSSM_ERRCODE_NO_USER_INTERACTION - || rv == CSSMERR_CSP_KEY_USAGE_INCORRECT) - code = SEC_ERROR_INADEQUATE_KEY_USAGE; - else - code = SEC_ERROR_LIBRARY_FAILURE; - - PORT_SetError(code); - goto loser; - } - - result->Length = sig.Length; - result->Data = sig.Data; - -loser: - if (cc) - CSSM_DeleteContext(cc); - - return rv; -} - -SECStatus -VFY_VerifyData(unsigned char *buf, int len, - SecPublicKeyRef pk, SecAsn1Item *sig, - SECOidTag digAlgTag, SECOidTag sigAlgTag, void *wincx) -{ - SECOidTag algTag; - CSSM_ALGORITHMS algorithm; - CSSM_CC_HANDLE cc = 0; - CSSM_CSP_HANDLE csp; - OSStatus rv = SECFailure; - SecAsn1Item dataBuf = { (uint32)len, (uint8_t *)buf }; - const CSSM_KEY *key; - - algTag = SecCmsUtilMakeSignatureAlgorithm(digAlgTag, sigAlgTag); - algorithm = SECOID_FindyCssmAlgorithmByTag(algTag); - if (!algorithm) - { - rv = algTag == SEC_OID_UNKNOWN ? SecCmsVSSignatureAlgorithmUnknown : SecCmsVSSignatureAlgorithmUnsupported; - goto loser; - } - - rv = SecKeyGetCSPHandle(pk, &csp); - if (rv) - goto loser; - rv = SecKeyGetCSSMKey(pk, &key); - if (rv) - goto loser; - - rv = CSSM_CSP_CreateSignatureContext(csp, algorithm, NULL, key, &cc); - if (rv) - goto loser; - - rv = CSSM_VerifyData(cc, &dataBuf, 1, CSSM_ALGID_NONE, sig); - -loser: - if (cc) - CSSM_DeleteContext(cc); - - return rv; -} - -SECStatus -VFY_VerifyDigest(SecAsn1Item *digest, SecPublicKeyRef pk, - SecAsn1Item *sig, SECOidTag digAlgTag, SECOidTag sigAlgTag, void *wincx) -{ - CSSM_ALGORITHMS sigalg, digalg; - CSSM_CC_HANDLE cc = 0; - CSSM_CSP_HANDLE csp; - const CSSM_KEY *key; - OSStatus rv; - - digalg = SECOID_FindyCssmAlgorithmByTag(digAlgTag); - sigalg = SECOID_FindyCssmAlgorithmByTag(sigAlgTag); - if (!digalg || !sigalg) - { - rv = digAlgTag == SEC_OID_UNKNOWN || sigAlgTag == SEC_OID_UNKNOWN ? SecCmsVSSignatureAlgorithmUnknown : SecCmsVSSignatureAlgorithmUnsupported; - goto loser; - } - - rv = SecKeyGetCSPHandle(pk, &csp); - if (rv) - goto loser; - rv = SecKeyGetCSSMKey(pk, &key); - if (rv) - goto loser; - - rv = CSSM_CSP_CreateSignatureContext(csp, sigalg, NULL, key, &cc); - if (rv) - goto loser; - - rv = CSSM_VerifyData(cc, digest, 1, digalg, sig); - -loser: - if (cc) - CSSM_DeleteContext(cc); - - return rv; -} - -SECStatus -WRAP_PubWrapSymKey(SecPublicKeyRef publickey, - SecSymmetricKeyRef bulkkey, - SecAsn1Item * encKey) -{ - CSSM_WRAP_KEY wrappedKey = {}; - //CSSM_WRAP_KEY wrappedPk = {} - //CSSM_KEY upk = {}; - CSSM_CC_HANDLE cc = 0; - CSSM_CSP_HANDLE pkCsp, bkCsp; - const CSSM_KEY *pk, *bk, *pubkey; - OSStatus rv; - CSSM_ACCESS_CREDENTIALS accessCred = {}; - - rv = SecKeyGetCSPHandle(publickey, &pkCsp); - if (rv) - goto loser; - rv = SecKeyGetCSSMKey(publickey, &pk); - if (rv) - goto loser; - - rv = SecKeyGetCSPHandle(bulkkey, &bkCsp); - if (rv) - goto loser; - rv = SecKeyGetCSSMKey(bulkkey, &bk); - if (rv) - goto loser; - -#if 1 - pubkey = pk; -#else - /* We need to get the publickey out of it's pkCsp and into the bkCsp so we can operate with it. */ - - /* Make a NULL wrap symmetric context to extract the public key from pkCsp. */ - rv = CSSM_CSP_CreateSymmetricContext(pkCsp, - CSSM_ALGID_NONE, - CSSM_MODE_NONE, - NULL, /* accessCred */ - NULL, /* key */ - NULL, /* iv */ - CSSM_PADDING_NONE, - NULL, /* reserved */ - &cc); - if (rv) - goto loser; - rv = CSSM_WrapKey(cc, - NULL /* accessCred */, - pk, - NULL /* descriptiveData */, - &wrappedPk); - CSSM_DeleteContext(cc); - cc = 0; - - /* Make a NULL unwrap symmetric context to import the public key into bkCsp. */ - rv = CSSM_CSP_CreateSymmetricContext(bkCsp, - CSSM_ALGID_NONE, - CSSM_MODE_NONE, - NULL, /* accessCred */ - NULL, /* key */ - NULL, /* iv */ - CSSM_PADDING_NONE, - NULL, /* reserved */ - &cc); - if (rv) - goto loser; - rv = CSSM_UnwrapKey(cc, NULL, &wrappedPk, usage, attr, NULL /* label */, NULL /* rcc */, &upk, NULL /* descriptiveData */); - CSSM_DeleteContext(cc); - cc = 0; - - pubkey = &upk; -#endif - - rv = CSSM_CSP_CreateAsymmetricContext(bkCsp, - pubkey->KeyHeader.AlgorithmId, - &accessCred, - pubkey, - CSSM_PADDING_PKCS1, - &cc); - if (rv) - goto loser; - - { - /* Set the wrapped key format to indicate we want just the raw bits encrypted. */ - CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_WRAPPED_KEY_FORMAT, sizeof(uint32) }; - contextAttribute.Attribute.Uint32 = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7; - rv = CSSM_UpdateContextAttributes(cc, 1, &contextAttribute); - if (rv) - goto loser; - } - - { - /* Set the mode to CSSM_ALGMODE_PKCS1_EME_V15. */ - CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_MODE, sizeof(uint32) }; - contextAttribute.Attribute.Uint32 = CSSM_ALGMODE_NONE; /* CSSM_ALGMODE_PKCS1_EME_V15 */ - rv = CSSM_UpdateContextAttributes(cc, 1, &contextAttribute); - if (rv) - goto loser; - } - - { - // @@@ Stick in an empty initVector to work around a csp bug. - SecAsn1Item initVector = {}; - CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_INIT_VECTOR, sizeof(SecAsn1Item *) }; - contextAttribute.Attribute.Data = &initVector; - rv = CSSM_UpdateContextAttributes(cc, 1, &contextAttribute); - if (rv) - goto loser; - } - - rv = CSSM_WrapKey(cc, - &accessCred, - bk, - NULL, /* descriptiveData */ - &wrappedKey); - if (rv) - goto loser; - - // @@@ Fix leaks! - if (encKey->Length < wrappedKey.KeyData.Length) - abort(); - encKey->Length = wrappedKey.KeyData.Length; - memcpy(encKey->Data, wrappedKey.KeyData.Data, encKey->Length); - CSSM_FreeKey(bkCsp, NULL /* credentials */, &wrappedKey, FALSE); - -loser: - if (cc) - CSSM_DeleteContext(cc); - - return rv; -} - -SecSymmetricKeyRef -WRAP_PubUnwrapSymKey(SecPrivateKeyRef privkey, const SecAsn1Item *encKey, SECOidTag bulkalgtag) -{ - SecSymmetricKeyRef bulkkey = NULL; - CSSM_WRAP_KEY wrappedKey = {}; - CSSM_CC_HANDLE cc = 0; - CSSM_CSP_HANDLE pkCsp; - const CSSM_KEY *pk; - CSSM_KEY unwrappedKey = {}; - const CSSM_ACCESS_CREDENTIALS *accessCred; - SecAsn1Item descriptiveData = {}; - CSSM_ALGORITHMS bulkalg; - OSStatus rv; - - rv = SecKeyGetCSPHandle(privkey, &pkCsp); - if (rv) - goto loser; - rv = SecKeyGetCSSMKey(privkey, &pk); - if (rv) - goto loser; - rv = SecKeyGetCredentials(privkey, - CSSM_ACL_AUTHORIZATION_DECRYPT, /* @@@ Should be UNWRAP */ - kSecCredentialTypeDefault, - &accessCred); - if (rv) - goto loser; - - bulkalg = SECOID_FindyCssmAlgorithmByTag(bulkalgtag); - if (!bulkalg) - { - rv = SEC_ERROR_INVALID_ALGORITHM; - goto loser; - } - - rv = CSSM_CSP_CreateAsymmetricContext(pkCsp, - pk->KeyHeader.AlgorithmId, - accessCred, - pk, - CSSM_PADDING_PKCS1, - &cc); - if (rv) - goto loser; - - { - // @@@ Stick in an empty initvector to work around a csp bug. - SecAsn1Item initVector = {}; - CSSM_CONTEXT_ATTRIBUTE contextAttribute = { CSSM_ATTRIBUTE_INIT_VECTOR, sizeof(SecAsn1Item *) }; - contextAttribute.Attribute.Data = &initVector; - rv = CSSM_UpdateContextAttributes(cc, 1, &contextAttribute); - if (rv) - goto loser; - } - - wrappedKey.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; - wrappedKey.KeyHeader.BlobType = CSSM_KEYBLOB_WRAPPED; - wrappedKey.KeyHeader.Format = CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7; - wrappedKey.KeyHeader.AlgorithmId = bulkalg; - wrappedKey.KeyHeader.KeyClass = CSSM_KEYCLASS_SESSION_KEY; - wrappedKey.KeyHeader.WrapAlgorithmId = pk->KeyHeader.AlgorithmId; - wrappedKey.KeyHeader.WrapMode = CSSM_ALGMODE_NONE; /* CSSM_ALGMODE_PKCS1_EME_V15 */ - wrappedKey.KeyData = *encKey; - - rv = CSSM_UnwrapKey(cc, - NULL, /* publicKey */ - &wrappedKey, - CSSM_KEYUSE_DECRYPT, - CSSM_KEYATTR_EXTRACTABLE /* | CSSM_KEYATTR_RETURN_DATA */, - NULL, /* keyLabel */ - NULL, /* rcc */ - &unwrappedKey, - &descriptiveData); - if (rv) { - SECErrorCodes code; - if (CSSM_ERRCODE(rv) == CSSM_ERRCODE_USER_CANCELED - || CSSM_ERRCODE(rv) == CSSM_ERRCODE_OPERATION_AUTH_DENIED) - code = SEC_ERROR_USER_CANCELLED; - else if (CSSM_ERRCODE(rv) == CSSM_ERRCODE_NO_USER_INTERACTION - || rv == CSSMERR_CSP_KEY_USAGE_INCORRECT) - code = SEC_ERROR_INADEQUATE_KEY_USAGE; - else - code = SEC_ERROR_LIBRARY_FAILURE; - - PORT_SetError(code); - goto loser; - } - - // @@@ Export this key from the csp/dl and import it to the standard csp - rv = SecKeyCreate(&unwrappedKey, &bulkkey); - if (rv) - goto loser; - -loser: - if (rv) - PORT_SetError(rv); - - if (cc) - CSSM_DeleteContext(cc); - - return bulkkey; -} diff --git a/libsecurity_smime/libCMS.xcodeproj/.gitignore b/libsecurity_smime/libCMS.xcodeproj/.gitignore deleted file mode 100644 index 7f42cdde..00000000 --- a/libsecurity_smime/libCMS.xcodeproj/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -project.xcworkspace -xcuserdata diff --git a/libsecurity_smime/libCMS.xcodeproj/project.pbxproj b/libsecurity_smime/libCMS.xcodeproj/project.pbxproj deleted file mode 100644 index 27fe46a6..00000000 --- a/libsecurity_smime/libCMS.xcodeproj/project.pbxproj +++ /dev/null @@ -1,966 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXAggregateTarget section */ - D447C4DB1D31C9DD0082FC1D /* libCMSInstall */ = { - isa = PBXAggregateTarget; - buildConfigurationList = D447C4DE1D31C9DD0082FC1D /* Build configuration list for PBXAggregateTarget "libCMSInstall" */; - buildPhases = ( - ); - dependencies = ( - D447C4E01D31C9E80082FC1D /* PBXTargetDependency */, - ); - name = libCMSInstall; - productName = libCMSInstall; - }; -/* End PBXAggregateTarget section */ - -/* Begin PBXBuildFile section */ - 4C14208F0415845900CA2E66 /* cmsdigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */; }; - 4C21886C0635F4BD00E64E02 /* SecCmsBase.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */; }; - 4C21886D0635F4BD00E64E02 /* SecCmsContentInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */; }; - 4C21886E0635F4BD00E64E02 /* SecCmsDecoder.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */; }; - 4C21886F0635F4BD00E64E02 /* SecCmsDigestContext.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */; }; - 4C2188700635F4BD00E64E02 /* SecCmsDigestedData.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */; }; - 4C2188710635F4BD00E64E02 /* SecCmsEncoder.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */; }; - 4C2188720635F4BD00E64E02 /* SecCmsEnvelopedData.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */; }; - 4C2188730635F4BD00E64E02 /* SecCmsMessage.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */; }; - 4C2188740635F4BD00E64E02 /* SecCmsRecipientInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */; }; - 4C2188750635F4BD00E64E02 /* SecCmsSignedData.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */; }; - 4C2188760635F4BD00E64E02 /* SecCmsSignerInfo.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */; }; - 4C27421103E9FC6700A80181 /* cmsarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F203E9FC5B00A80181 /* cmsarray.c */; }; - 4C27421303E9FC6900A80181 /* cmsasn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F303E9FC5B00A80181 /* cmsasn1.c */; }; - 4C27421403E9FC6A00A80181 /* cmsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F403E9FC5B00A80181 /* cmsattr.c */; }; - 4C27421503E9FC6C00A80181 /* cmscinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F503E9FC5B00A80181 /* cmscinfo.c */; }; - 4C27421703E9FC6D00A80181 /* cmsdecode.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F703E9FC5B00A80181 /* cmsdecode.c */; }; - 4C27421B03E9FC7000A80181 /* cmsencode.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FB03E9FC5B00A80181 /* cmsencode.c */; }; - 4C27421D03E9FC7100A80181 /* cmslocal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C2741FD03E9FC5B00A80181 /* cmslocal.h */; }; - 4C27422103E9FC7500A80181 /* cmsreclist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420103E9FC5B00A80181 /* cmsreclist.c */; }; - 4C27422203E9FC7600A80181 /* cmsreclist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C27420203E9FC5B00A80181 /* cmsreclist.h */; }; - 4C424BE8063F28F600E9831A /* SecSMIMEPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C424BE7063F28F600E9831A /* SecSMIMEPriv.h */; }; - 4C6CA861040308C700CA2E66 /* cmssigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420303E9FC5B00A80181 /* cmssigdata.c */; }; - 4C7182ED0637119600230DDE /* secoidt.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E166E0438EEE700CA2E66 /* secoidt.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 4C7183480637153700230DDE /* SecSMIME.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C7183470637153700230DDE /* SecSMIME.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4C7183560637155B00230DDE /* SecSMIME.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4C7183470637153700230DDE /* SecSMIME.h */; }; - 4C8E166F0438EEE700CA2E66 /* secoid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E166C0438EEE700CA2E66 /* secoid.c */; }; - 4C8E16700438EEE700CA2E66 /* secoid.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E166D0438EEE700CA2E66 /* secoid.h */; }; - 4C8E16740438EF5700CA2E66 /* plhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E16720438EF5700CA2E66 /* plhash.c */; }; - 4C8E16750438EF5700CA2E66 /* plhash.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E16730438EF5700CA2E66 /* plhash.h */; }; - 4C8E16790438EFD700CA2E66 /* SecAsn1Item.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E16770438EFD700CA2E66 /* SecAsn1Item.c */; }; - 4C8E167A0438EFD700CA2E66 /* SecAsn1Item.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C8E16780438EFD700CA2E66 /* SecAsn1Item.h */; }; - 4CA51CE00420246F00CA2E66 /* cryptohi.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CA51CDF0420246F00CA2E66 /* cryptohi.h */; }; - 4CB42E340421212D00CA2E66 /* cryptohi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB42E330421212D00CA2E66 /* cryptohi.c */; }; - 4CB6AADA040DA84D00CA2E66 /* secalgid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */; }; - 4CCC260E0635F1A200CBF0D4 /* SecCmsBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC260F0635F1A200CBF0D4 /* SecCmsContentInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26100635F1A200CBF0D4 /* SecCmsDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26110635F1A200CBF0D4 /* SecCmsDigestContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26120635F1A200CBF0D4 /* SecCmsDigestedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26130635F1A200CBF0D4 /* SecCmsEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26140635F1A200CBF0D4 /* SecCmsEnvelopedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26150635F1A200CBF0D4 /* SecCmsMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26160635F1A200CBF0D4 /* SecCmsRecipientInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26170635F1A200CBF0D4 /* SecCmsSignedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CCC26180635F1A200CBF0D4 /* SecCmsSignerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CDA0D5E04200AD600CA2E66 /* cmscipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F603E9FC5B00A80181 /* cmscipher.c */; }; - 4CDA0D6004200AD800CA2E66 /* cmsencdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */; }; - 4CDA0D6104200AD800CA2E66 /* cmsdigest.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F903E9FC5B00A80181 /* cmsdigest.c */; }; - 4CDA0D6204200AD900CA2E66 /* cmsenvdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */; }; - 4CDA0D6304200ADD00CA2E66 /* cmspubkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */; }; - 4CDA0D6404200ADD00CA2E66 /* cmsrecinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */; }; - 4CDA0D6504200ADF00CA2E66 /* cmsutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6D72BC0410298900CA2E66 /* cmsutil.c */; }; - 4CDA0D6604200AE000CA2E66 /* cmssiginfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420403E9FC5B00A80181 /* cmssiginfo.c */; }; - 4CDA0D6704200B0F00CA2E66 /* smimeutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420F03E9FC5B00A80181 /* smimeutil.c */; }; - 4CEC5CDF042A721300CA2E66 /* cmspriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CDE042A721300CA2E66 /* cmspriv.h */; }; - 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */; }; - 4CEDC82106371B1700B7E254 /* SecCmsEncryptedData.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */; settings = {ATTRIBUTES = (Private, ); }; }; - 4CEDC82806371B4000B7E254 /* SecCmsEncryptedData.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */; }; - 79BDD29C0D60C75D000D84D3 /* crypto-embedded.c in Sources */ = {isa = PBXBuildFile; fileRef = 79BDD29B0D60C75D000D84D3 /* crypto-embedded.c */; }; - 79DC32240D4949720039E4BC /* cmsmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */; }; - 79DC336B0D4E6F170039E4BC /* cmsarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F203E9FC5B00A80181 /* cmsarray.c */; }; - 79DC336C0D4E6F170039E4BC /* cmsasn1.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F303E9FC5B00A80181 /* cmsasn1.c */; }; - 79DC336D0D4E6F170039E4BC /* cmsattr.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F403E9FC5B00A80181 /* cmsattr.c */; }; - 79DC336E0D4E6F170039E4BC /* cmscinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F503E9FC5B00A80181 /* cmscinfo.c */; }; - 79DC336F0D4E6F170039E4BC /* cmscipher.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F603E9FC5B00A80181 /* cmscipher.c */; }; - 79DC33700D4E6F170039E4BC /* cmsdecode.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F703E9FC5B00A80181 /* cmsdecode.c */; }; - 79DC33710D4E6F170039E4BC /* cmsdigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */; }; - 79DC33720D4E6F170039E4BC /* cmsdigest.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741F903E9FC5B00A80181 /* cmsdigest.c */; }; - 79DC33730D4E6F170039E4BC /* cmsencdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */; }; - 79DC33740D4E6F170039E4BC /* cmsencode.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FB03E9FC5B00A80181 /* cmsencode.c */; }; - 79DC33750D4E6F170039E4BC /* cmsenvdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */; }; - 79DC33760D4E6F170039E4BC /* cmspubkey.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */; }; - 79DC33770D4E6F170039E4BC /* cmsrecinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */; }; - 79DC33780D4E6F170039E4BC /* cmsreclist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420103E9FC5B00A80181 /* cmsreclist.c */; }; - 79DC33790D4E6F170039E4BC /* cmssigdata.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420303E9FC5B00A80181 /* cmssigdata.c */; }; - 79DC337A0D4E6F170039E4BC /* cmssiginfo.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420403E9FC5B00A80181 /* cmssiginfo.c */; }; - 79DC337B0D4E6F170039E4BC /* cmsutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6D72BC0410298900CA2E66 /* cmsutil.c */; }; - 79DC337D0D4E6F170039E4BC /* plhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E16720438EF5700CA2E66 /* plhash.c */; }; - 79DC337E0D4E6F170039E4BC /* secalgid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */; }; - 79DC337F0D4E6F170039E4BC /* SecAsn1Item.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E16770438EFD700CA2E66 /* SecAsn1Item.c */; }; - 79DC33800D4E6F170039E4BC /* secoid.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C8E166C0438EEE700CA2E66 /* secoid.c */; }; - 79DC33810D4E6F170039E4BC /* smimeutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C27420F03E9FC5B00A80181 /* smimeutil.c */; }; - 79DC33820D4E6F170039E4BC /* cmsmessage.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */; }; - D4FBBD511DD660E9004408F7 /* CMSUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD4B1DD660E9004408F7 /* CMSUtils.h */; }; - D4FBBD521DD660E9004408F7 /* CMSUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = D4FBBD4C1DD660E9004408F7 /* CMSUtils.c */; }; - D4FBBD531DD660E9004408F7 /* CMSEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD4D1DD660E9004408F7 /* CMSEncoder.h */; }; - D4FBBD541DD660E9004408F7 /* CMSEncoder.c in Sources */ = {isa = PBXBuildFile; fileRef = D4FBBD4E1DD660E9004408F7 /* CMSEncoder.c */; }; - D4FBBD551DD660E9004408F7 /* CMSDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = D4FBBD4F1DD660E9004408F7 /* CMSDecoder.h */; }; - D4FBBD561DD660E9004408F7 /* CMSDecoder.c in Sources */ = {isa = PBXBuildFile; fileRef = D4FBBD501DD660E9004408F7 /* CMSDecoder.c */; }; - D4FBBD641DD661E7004408F7 /* CMSUtils.c in Sources */ = {isa = PBXBuildFile; fileRef = D4FBBD4C1DD660E9004408F7 /* CMSUtils.c */; }; - D4FBBD651DD661E7004408F7 /* CMSEncoder.c in Sources */ = {isa = PBXBuildFile; fileRef = D4FBBD4E1DD660E9004408F7 /* CMSEncoder.c */; }; - D4FBBD661DD661E7004408F7 /* CMSDecoder.c in Sources */ = {isa = PBXBuildFile; fileRef = D4FBBD501DD660E9004408F7 /* CMSDecoder.c */; }; - F64399010420118A01CA2DCC /* cert.h in Headers */ = {isa = PBXBuildFile; fileRef = F64398FF0420118A01CA2DCC /* cert.h */; }; - F64399020420118A01CA2DCC /* cert.c in Sources */ = {isa = PBXBuildFile; fileRef = F64399000420118A01CA2DCC /* cert.c */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 4C89DFC5056AC87A0002E1CA /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C2741E803E9FBAF00A80181 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 4C7FAB40056AC7A200FE0C44; - remoteInfo = security_smime; - }; - D447C4DF1D31C9E80082FC1D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 4C2741E803E9FBAF00A80181 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 79DC33610D4E6EEA0039E4BC; - remoteInfo = libCMS; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 4C2188660635F43B00E64E02 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = SecurityPieces/Exports/Security; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4C2188670635F43E00E64E02 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 8; - dstPath = /usr/local/SecurityPieces/Exports/Security; - dstSubfolderSpec = 0; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - }; - 4C2188680635F44100E64E02 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = SecurityPieces/Headers/Security; - dstSubfolderSpec = 16; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4C2188690635F44300E64E02 /* CopyFiles */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = SecurityPieces/PrivateHeaders/Security; - dstSubfolderSpec = 16; - files = ( - 4C21886C0635F4BD00E64E02 /* SecCmsBase.h in CopyFiles */, - 4C21886D0635F4BD00E64E02 /* SecCmsContentInfo.h in CopyFiles */, - 4C21886E0635F4BD00E64E02 /* SecCmsDecoder.h in CopyFiles */, - 4C21886F0635F4BD00E64E02 /* SecCmsDigestContext.h in CopyFiles */, - 4C2188700635F4BD00E64E02 /* SecCmsDigestedData.h in CopyFiles */, - 4C2188710635F4BD00E64E02 /* SecCmsEncoder.h in CopyFiles */, - 4CEDC82806371B4000B7E254 /* SecCmsEncryptedData.h in CopyFiles */, - 4C2188720635F4BD00E64E02 /* SecCmsEnvelopedData.h in CopyFiles */, - 4C2188730635F4BD00E64E02 /* SecCmsMessage.h in CopyFiles */, - 4C2188740635F4BD00E64E02 /* SecCmsRecipientInfo.h in CopyFiles */, - 4C2188750635F4BD00E64E02 /* SecCmsSignedData.h in CopyFiles */, - 4C2188760635F4BD00E64E02 /* SecCmsSignerInfo.h in CopyFiles */, - 4C7183560637155B00230DDE /* SecSMIME.h in CopyFiles */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 4C2741F203E9FC5B00A80181 /* cmsarray.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsarray.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F303E9FC5B00A80181 /* cmsasn1.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsasn1.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F403E9FC5B00A80181 /* cmsattr.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsattr.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F503E9FC5B00A80181 /* cmscinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmscinfo.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F603E9FC5B00A80181 /* cmscipher.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmscipher.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F703E9FC5B00A80181 /* cmsdecode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsdecode.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsdigdata.c; sourceTree = ""; tabWidth = 8; }; - 4C2741F903E9FC5B00A80181 /* cmsdigest.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsdigest.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsencdata.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FB03E9FC5B00A80181 /* cmsencode.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsencode.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsenvdata.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FD03E9FC5B00A80181 /* cmslocal.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cmslocal.h; sourceTree = ""; tabWidth = 8; }; - 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsmessage.c; sourceTree = ""; tabWidth = 8; }; - 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmspubkey.c; sourceTree = ""; tabWidth = 8; }; - 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsrecinfo.c; sourceTree = ""; tabWidth = 8; }; - 4C27420103E9FC5B00A80181 /* cmsreclist.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsreclist.c; sourceTree = ""; tabWidth = 8; }; - 4C27420203E9FC5B00A80181 /* cmsreclist.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cmsreclist.h; sourceTree = ""; tabWidth = 8; }; - 4C27420303E9FC5B00A80181 /* cmssigdata.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmssigdata.c; sourceTree = ""; tabWidth = 8; }; - 4C27420403E9FC5B00A80181 /* cmssiginfo.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmssiginfo.c; sourceTree = ""; tabWidth = 8; }; - 4C27420F03E9FC5B00A80181 /* smimeutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = smimeutil.c; sourceTree = ""; tabWidth = 8; }; - 4C424BE7063F28F600E9831A /* SecSMIMEPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SecSMIMEPriv.h; sourceTree = ""; }; - 4C6D72BC0410298900CA2E66 /* cmsutil.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cmsutil.c; sourceTree = ""; tabWidth = 8; }; - 4C7183470637153700230DDE /* SecSMIME.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecSMIME.h; sourceTree = ""; }; - 4C7FAB41056AC7A200FE0C44 /* security_smime.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = security_smime.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4C817F8405ED4D7A007975E6 /* security_smime */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = security_smime; sourceTree = BUILT_PRODUCTS_DIR; }; - 4C8E166C0438EEE700CA2E66 /* secoid.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = secoid.c; sourceTree = ""; }; - 4C8E166D0438EEE700CA2E66 /* secoid.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = secoid.h; sourceTree = ""; }; - 4C8E166E0438EEE700CA2E66 /* secoidt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = secoidt.h; sourceTree = ""; }; - 4C8E16720438EF5700CA2E66 /* plhash.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = plhash.c; sourceTree = ""; }; - 4C8E16730438EF5700CA2E66 /* plhash.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = plhash.h; sourceTree = ""; }; - 4C8E16770438EFD700CA2E66 /* SecAsn1Item.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = SecAsn1Item.c; sourceTree = ""; }; - 4C8E16780438EFD700CA2E66 /* SecAsn1Item.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecAsn1Item.h; sourceTree = ""; }; - 4CA51CDF0420246F00CA2E66 /* cryptohi.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cryptohi.h; sourceTree = ""; tabWidth = 8; }; - 4CB42E330421212D00CA2E66 /* cryptohi.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cryptohi.c; sourceTree = ""; tabWidth = 8; }; - 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = secalgid.c; sourceTree = ""; }; - 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsBase.h; sourceTree = ""; }; - 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsContentInfo.h; sourceTree = ""; }; - 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsDecoder.h; sourceTree = ""; }; - 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestContext.h; sourceTree = ""; }; - 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsDigestedData.h; sourceTree = ""; }; - 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsEncoder.h; sourceTree = ""; }; - 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsEnvelopedData.h; sourceTree = ""; }; - 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsMessage.h; sourceTree = ""; }; - 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsRecipientInfo.h; sourceTree = ""; }; - 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsSignedData.h; sourceTree = ""; }; - 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsSignerInfo.h; sourceTree = ""; }; - 4CEC5CDE042A721300CA2E66 /* cmspriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmspriv.h; sourceTree = ""; }; - 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cmstpriv.h; sourceTree = ""; }; - 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecCmsEncryptedData.h; sourceTree = ""; }; - 79BDD29B0D60C75D000D84D3 /* crypto-embedded.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "crypto-embedded.c"; sourceTree = ""; }; - 79DC33620D4E6EEA0039E4BC /* libCMS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libCMS.a; sourceTree = BUILT_PRODUCTS_DIR; }; - D4FBBD4B1DD660E9004408F7 /* CMSUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMSUtils.h; sourceTree = ""; }; - D4FBBD4C1DD660E9004408F7 /* CMSUtils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CMSUtils.c; sourceTree = ""; }; - D4FBBD4D1DD660E9004408F7 /* CMSEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMSEncoder.h; sourceTree = ""; }; - D4FBBD4E1DD660E9004408F7 /* CMSEncoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CMSEncoder.c; sourceTree = ""; }; - D4FBBD4F1DD660E9004408F7 /* CMSDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CMSDecoder.h; sourceTree = ""; }; - D4FBBD501DD660E9004408F7 /* CMSDecoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CMSDecoder.c; sourceTree = ""; }; - F64398FF0420118A01CA2DCC /* cert.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = cert.h; sourceTree = ""; tabWidth = 8; }; - F64399000420118A01CA2DCC /* cert.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = cert.c; sourceTree = ""; tabWidth = 8; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworkTarget section */ - 4C7FAB40056AC7A200FE0C44 /* security_smime */ = { - isa = PBXFrameworkTarget; - buildConfigurationList = 79DC321C0D49473C0039E4BC /* Build configuration list for PBXFrameworkTarget "security_smime" */; - buildPhases = ( - 4C7FAB3B056AC7A200FE0C44 /* Headers */, - 4C2188660635F43B00E64E02 /* CopyFiles */, - 4C2188670635F43E00E64E02 /* CopyFiles */, - 4C2188680635F44100E64E02 /* CopyFiles */, - 4C2188690635F44300E64E02 /* CopyFiles */, - ); - dependencies = ( - ); - name = security_smime; - productInstallPath = /usr/local/SecurityPieces/Components/Security; - productName = security_smime; - productReference = 4C7FAB41056AC7A200FE0C44 /* security_smime.framework */; - productSettingsXML = " - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - - CFBundleGetInfoString - - CFBundleIconFile - - CFBundleIdentifier - - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - - CFBundlePackageType - FMWK - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - 8 - - -"; - }; -/* End PBXFrameworkTarget section */ - -/* Begin PBXFrameworksBuildPhase section */ - 4C2741EB03E9FBF700A80181 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 79DC33600D4E6EEA0039E4BC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 4C2741E403E9FBAF00A80181 = { - isa = PBXGroup; - children = ( - 4C2741F003E9FC2100A80181 /* lib */, - 4C2741EF03E9FBF700A80181 /* Products */, - ); - sourceTree = ""; - }; - 4C2741EF03E9FBF700A80181 /* Products */ = { - isa = PBXGroup; - children = ( - 4C817F8405ED4D7A007975E6 /* security_smime */, - 4C7FAB41056AC7A200FE0C44 /* security_smime.framework */, - 79DC33620D4E6EEA0039E4BC /* libCMS.a */, - ); - name = Products; - sourceTree = BUILT_PRODUCTS_DIR; - }; - 4C2741F003E9FC2100A80181 /* lib */ = { - isa = PBXGroup; - children = ( - F64399000420118A01CA2DCC /* cert.c */, - F64398FF0420118A01CA2DCC /* cert.h */, - D4FBBD4B1DD660E9004408F7 /* CMSUtils.h */, - D4FBBD4C1DD660E9004408F7 /* CMSUtils.c */, - D4FBBD4D1DD660E9004408F7 /* CMSEncoder.h */, - D4FBBD4E1DD660E9004408F7 /* CMSEncoder.c */, - D4FBBD4F1DD660E9004408F7 /* CMSDecoder.h */, - D4FBBD501DD660E9004408F7 /* CMSDecoder.c */, - 4C2741F203E9FC5B00A80181 /* cmsarray.c */, - 4C2741F303E9FC5B00A80181 /* cmsasn1.c */, - 4C2741F403E9FC5B00A80181 /* cmsattr.c */, - 4C2741F503E9FC5B00A80181 /* cmscinfo.c */, - 4C2741F603E9FC5B00A80181 /* cmscipher.c */, - 4C2741F703E9FC5B00A80181 /* cmsdecode.c */, - 4C2741F803E9FC5B00A80181 /* cmsdigdata.c */, - 4C2741F903E9FC5B00A80181 /* cmsdigest.c */, - 4C2741FA03E9FC5B00A80181 /* cmsencdata.c */, - 4C2741FB03E9FC5B00A80181 /* cmsencode.c */, - 4C2741FC03E9FC5B00A80181 /* cmsenvdata.c */, - 4C2741FD03E9FC5B00A80181 /* cmslocal.h */, - 4C2741FE03E9FC5B00A80181 /* cmsmessage.c */, - 4CEC5CDE042A721300CA2E66 /* cmspriv.h */, - 4C2741FF03E9FC5B00A80181 /* cmspubkey.c */, - 4C27420003E9FC5B00A80181 /* cmsrecinfo.c */, - 4C27420103E9FC5B00A80181 /* cmsreclist.c */, - 4C27420203E9FC5B00A80181 /* cmsreclist.h */, - 4C27420303E9FC5B00A80181 /* cmssigdata.c */, - 4C27420403E9FC5B00A80181 /* cmssiginfo.c */, - 4CEC5CE0042A722000CA2E66 /* cmstpriv.h */, - 4C6D72BC0410298900CA2E66 /* cmsutil.c */, - 4CB42E330421212D00CA2E66 /* cryptohi.c */, - 4CA51CDF0420246F00CA2E66 /* cryptohi.h */, - 79BDD29B0D60C75D000D84D3 /* crypto-embedded.c */, - 4C8E16720438EF5700CA2E66 /* plhash.c */, - 4C8E16730438EF5700CA2E66 /* plhash.h */, - 4CB6AAD9040DA84D00CA2E66 /* secalgid.c */, - 4CCC26030635F1A100CBF0D4 /* SecCmsBase.h */, - 4CCC26040635F1A100CBF0D4 /* SecCmsContentInfo.h */, - 4CCC26050635F1A100CBF0D4 /* SecCmsDecoder.h */, - 4CCC26060635F1A100CBF0D4 /* SecCmsDigestContext.h */, - 4CCC26070635F1A100CBF0D4 /* SecCmsDigestedData.h */, - 4CCC26080635F1A100CBF0D4 /* SecCmsEncoder.h */, - 4CEDC82006371B1700B7E254 /* SecCmsEncryptedData.h */, - 4CCC26090635F1A100CBF0D4 /* SecCmsEnvelopedData.h */, - 4CCC260A0635F1A100CBF0D4 /* SecCmsMessage.h */, - 4CCC260B0635F1A100CBF0D4 /* SecCmsRecipientInfo.h */, - 4CCC260C0635F1A100CBF0D4 /* SecCmsSignedData.h */, - 4CCC260D0635F1A100CBF0D4 /* SecCmsSignerInfo.h */, - 4C8E16770438EFD700CA2E66 /* SecAsn1Item.c */, - 4C8E16780438EFD700CA2E66 /* SecAsn1Item.h */, - 4C8E166C0438EEE700CA2E66 /* secoid.c */, - 4C8E166D0438EEE700CA2E66 /* secoid.h */, - 4C8E166E0438EEE700CA2E66 /* secoidt.h */, - 4C7183470637153700230DDE /* SecSMIME.h */, - 4C424BE7063F28F600E9831A /* SecSMIMEPriv.h */, - 4C27420F03E9FC5B00A80181 /* smimeutil.c */, - ); - path = lib; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 4C2741E903E9FBF700A80181 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - F64399010420118A01CA2DCC /* cert.h in Headers */, - 4C27421D03E9FC7100A80181 /* cmslocal.h in Headers */, - 4CEC5CDF042A721300CA2E66 /* cmspriv.h in Headers */, - 4C27422203E9FC7600A80181 /* cmsreclist.h in Headers */, - 4CEC5CE1042A722000CA2E66 /* cmstpriv.h in Headers */, - 4CA51CE00420246F00CA2E66 /* cryptohi.h in Headers */, - 4C8E16750438EF5700CA2E66 /* plhash.h in Headers */, - 4CCC260E0635F1A200CBF0D4 /* SecCmsBase.h in Headers */, - 4CCC260F0635F1A200CBF0D4 /* SecCmsContentInfo.h in Headers */, - D4FBBD551DD660E9004408F7 /* CMSDecoder.h in Headers */, - 4CCC26100635F1A200CBF0D4 /* SecCmsDecoder.h in Headers */, - 4CCC26110635F1A200CBF0D4 /* SecCmsDigestContext.h in Headers */, - 4CCC26120635F1A200CBF0D4 /* SecCmsDigestedData.h in Headers */, - D4FBBD511DD660E9004408F7 /* CMSUtils.h in Headers */, - 4CCC26130635F1A200CBF0D4 /* SecCmsEncoder.h in Headers */, - 4CEDC82106371B1700B7E254 /* SecCmsEncryptedData.h in Headers */, - 4CCC26140635F1A200CBF0D4 /* SecCmsEnvelopedData.h in Headers */, - 4CCC26150635F1A200CBF0D4 /* SecCmsMessage.h in Headers */, - 4CCC26160635F1A200CBF0D4 /* SecCmsRecipientInfo.h in Headers */, - 4CCC26170635F1A200CBF0D4 /* SecCmsSignedData.h in Headers */, - 4CCC26180635F1A200CBF0D4 /* SecCmsSignerInfo.h in Headers */, - 4C8E167A0438EFD700CA2E66 /* SecAsn1Item.h in Headers */, - D4FBBD531DD660E9004408F7 /* CMSEncoder.h in Headers */, - 4C8E16700438EEE700CA2E66 /* secoid.h in Headers */, - 4C7183480637153700230DDE /* SecSMIME.h in Headers */, - 4C424BE8063F28F600E9831A /* SecSMIMEPriv.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 4C7FAB3B056AC7A200FE0C44 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - 4C7182ED0637119600230DDE /* secoidt.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXLibraryTarget section */ - 4C2741ED03E9FBF700A80181 /* libsecurity_smime */ = { - isa = PBXLibraryTarget; - buildConfigurationList = 79DC321D0D49473C0039E4BC /* Build configuration list for PBXLibraryTarget "libsecurity_smime" */; - buildPhases = ( - 4C2741E903E9FBF700A80181 /* Headers */, - 4C2741EA03E9FBF700A80181 /* Sources */, - 4C2741EB03E9FBF700A80181 /* Frameworks */, - 4C681B61056AC6BE00EB41E9 /* ShellScript */, - 4C681B62056AC6C100EB41E9 /* ShellScript */, - ); - dependencies = ( - 4C7FAB42056AC7A600FE0C44 /* PBXTargetDependency */, - ); - name = libsecurity_smime; - productInstallPath = /usr/local/lib; - productName = libSecurityNssSmime.a; - productReference = 4C817F8405ED4D7A007975E6 /* security_smime */; - }; -/* End PBXLibraryTarget section */ - -/* Begin PBXNativeTarget section */ - 79DC33610D4E6EEA0039E4BC /* libCMS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 79DC33840D4E6F350039E4BC /* Build configuration list for PBXNativeTarget "libCMS" */; - buildPhases = ( - 79DC335F0D4E6EEA0039E4BC /* Sources */, - 79DC33600D4E6EEA0039E4BC /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = libCMS; - productName = cms; - productReference = 79DC33620D4E6EEA0039E4BC /* libCMS.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 4C2741E803E9FBAF00A80181 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1000; - TargetAttributes = { - D447C4DB1D31C9DD0082FC1D = { - CreatedOnToolsVersion = 8.0; - ProvisioningStyle = Automatic; - }; - }; - }; - buildConfigurationList = 79DC321B0D49473C0039E4BC /* Build configuration list for PBXProject "libCMS" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 1; - knownRegions = ( - English, - Japanese, - French, - German, - ); - mainGroup = 4C2741E403E9FBAF00A80181; - productRefGroup = 4C2741EF03E9FBF700A80181 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 4C2741ED03E9FBF700A80181 /* libsecurity_smime */, - 4C7FAB40056AC7A200FE0C44 /* security_smime */, - 79DC33610D4E6EEA0039E4BC /* libCMS */, - D447C4DB1D31C9DD0082FC1D /* libCMSInstall */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXShellScriptBuildPhase section */ - 4C681B61056AC6BE00EB41E9 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "for variant in ${BUILD_VARIANTS}\ndo\n\tpostfix=`echo _${variant} | sed 's/_normal//'`\n\tln -fs \"../../../${PRODUCT_NAME}${postfix}\" ${SYMROOT}/${PRODUCT_NAME}.framework/Versions/A\n\tln -fs \"Versions/Current/${PRODUCT_NAME}${postfix}\" ${SYMROOT}/${PRODUCT_NAME}.framework\ndone"; - }; - 4C681B62056AC6C100EB41E9 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 8; - files = ( - ); - runOnlyForDeploymentPostprocessing = 1; - shellPath = /bin/sh; - shellScript = "for variant in ${BUILD_VARIANTS}\ndo\n\tpostfix=`echo _${variant} | sed 's/_normal//'`\n\tcp -p \"${SYMROOT}/${PRODUCT_NAME}${postfix}\" \"${DSTROOT}/usr/local/SecurityPieces/Components/Security/${PRODUCT_NAME}.framework/Versions/A\"\n\tranlib \"${DSTROOT}/usr/local/SecurityPieces/Components/Security/${PRODUCT_NAME}.framework/Versions/A/${PRODUCT_NAME}${postfix}\"\n\tln -fs \"Versions/Current/${PRODUCT_NAME}${postfix}\" \"${DSTROOT}/usr/local/SecurityPieces/Components/Security/${PRODUCT_NAME}.framework\"\ndone"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 4C2741EA03E9FBF700A80181 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - F64399020420118A01CA2DCC /* cert.c in Sources */, - 4C27421103E9FC6700A80181 /* cmsarray.c in Sources */, - 4C27421303E9FC6900A80181 /* cmsasn1.c in Sources */, - 4C27421403E9FC6A00A80181 /* cmsattr.c in Sources */, - 4C27421503E9FC6C00A80181 /* cmscinfo.c in Sources */, - 4CDA0D5E04200AD600CA2E66 /* cmscipher.c in Sources */, - 4C27421703E9FC6D00A80181 /* cmsdecode.c in Sources */, - D4FBBD541DD660E9004408F7 /* CMSEncoder.c in Sources */, - 4C14208F0415845900CA2E66 /* cmsdigdata.c in Sources */, - 4CDA0D6104200AD800CA2E66 /* cmsdigest.c in Sources */, - 4CDA0D6004200AD800CA2E66 /* cmsencdata.c in Sources */, - 4C27421B03E9FC7000A80181 /* cmsencode.c in Sources */, - 4CDA0D6204200AD900CA2E66 /* cmsenvdata.c in Sources */, - 4CDA0D6304200ADD00CA2E66 /* cmspubkey.c in Sources */, - 4CDA0D6404200ADD00CA2E66 /* cmsrecinfo.c in Sources */, - 4C27422103E9FC7500A80181 /* cmsreclist.c in Sources */, - 4C6CA861040308C700CA2E66 /* cmssigdata.c in Sources */, - 4CDA0D6604200AE000CA2E66 /* cmssiginfo.c in Sources */, - 4CDA0D6504200ADF00CA2E66 /* cmsutil.c in Sources */, - 4CB42E340421212D00CA2E66 /* cryptohi.c in Sources */, - 4C8E16740438EF5700CA2E66 /* plhash.c in Sources */, - 4CB6AADA040DA84D00CA2E66 /* secalgid.c in Sources */, - D4FBBD521DD660E9004408F7 /* CMSUtils.c in Sources */, - 4C8E16790438EFD700CA2E66 /* SecAsn1Item.c in Sources */, - 4C8E166F0438EEE700CA2E66 /* secoid.c in Sources */, - 4CDA0D6704200B0F00CA2E66 /* smimeutil.c in Sources */, - D4FBBD561DD660E9004408F7 /* CMSDecoder.c in Sources */, - 79DC32240D4949720039E4BC /* cmsmessage.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 79DC335F0D4E6EEA0039E4BC /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D4FBBD641DD661E7004408F7 /* CMSUtils.c in Sources */, - D4FBBD651DD661E7004408F7 /* CMSEncoder.c in Sources */, - D4FBBD661DD661E7004408F7 /* CMSDecoder.c in Sources */, - 79DC336B0D4E6F170039E4BC /* cmsarray.c in Sources */, - 79DC336C0D4E6F170039E4BC /* cmsasn1.c in Sources */, - 79DC336D0D4E6F170039E4BC /* cmsattr.c in Sources */, - 79DC336E0D4E6F170039E4BC /* cmscinfo.c in Sources */, - 79DC336F0D4E6F170039E4BC /* cmscipher.c in Sources */, - 79DC33700D4E6F170039E4BC /* cmsdecode.c in Sources */, - 79DC33710D4E6F170039E4BC /* cmsdigdata.c in Sources */, - 79DC33720D4E6F170039E4BC /* cmsdigest.c in Sources */, - 79DC33730D4E6F170039E4BC /* cmsencdata.c in Sources */, - 79DC33740D4E6F170039E4BC /* cmsencode.c in Sources */, - 79DC33750D4E6F170039E4BC /* cmsenvdata.c in Sources */, - 79DC33760D4E6F170039E4BC /* cmspubkey.c in Sources */, - 79DC33770D4E6F170039E4BC /* cmsrecinfo.c in Sources */, - 79DC33780D4E6F170039E4BC /* cmsreclist.c in Sources */, - 79DC33790D4E6F170039E4BC /* cmssigdata.c in Sources */, - 79DC337A0D4E6F170039E4BC /* cmssiginfo.c in Sources */, - 79DC337B0D4E6F170039E4BC /* cmsutil.c in Sources */, - 79DC337D0D4E6F170039E4BC /* plhash.c in Sources */, - 79DC337E0D4E6F170039E4BC /* secalgid.c in Sources */, - 79DC337F0D4E6F170039E4BC /* SecAsn1Item.c in Sources */, - 79DC33800D4E6F170039E4BC /* secoid.c in Sources */, - 79DC33810D4E6F170039E4BC /* smimeutil.c in Sources */, - 79DC33820D4E6F170039E4BC /* cmsmessage.c in Sources */, - 79BDD29C0D60C75D000D84D3 /* crypto-embedded.c in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 4C7FAB42056AC7A600FE0C44 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 4C7FAB40056AC7A200FE0C44 /* security_smime */; - targetProxy = 4C89DFC5056AC87A0002E1CA /* PBXContainerItemProxy */; - }; - D447C4E01D31C9E80082FC1D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 79DC33610D4E6EEA0039E4BC /* libCMS */; - targetProxy = D447C4DF1D31C9E80082FC1D /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 79BDD2AE0D60CA06000D84D3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - 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; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1"; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_MISSING_PARENTHESES = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VALUE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - ONLY_ACTIVE_ARCH = YES; - OTHER_CFLAGS = ( - "-fconstant-cfstrings", - "-fno-inline", - ); - SDKROOT = iphoneos.internal; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - WARNING_CFLAGS = ( - "-Wall", - "-Wextra", - "-Wno-unused-parameter", - "-Wno-missing-field-initializers", - ); - }; - name = Debug; - }; - 79BDD2AF0D60CA06000D84D3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUILD_VARIANTS = ( - normal, - debug, - profile, - ); - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 8; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - HEADER_SEARCH_PATHS = ( - "$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers", - "$(BUILT_PRODUCTS_DIR)/SecurityPieces/PrivateHeaders", - ); - LIBRARY_STYLE = STATIC; - OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)"; - OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; - OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline"; - OTHER_CFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; - OTHER_CFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline"; - OTHER_CPLUSPLUSFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; - OTHER_CPLUSPLUSFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)"; - OTHER_LDFLAGS_normal = "$(OTHER_LDFLAGS)"; - OTHER_LDFLAGS_profile = "$(OTHER_LDFLAGS) -pg"; - PRIVATE_HEADER_DIR = "$(DSTROOT)/usr/local/SecurityPieces/PrivateHeaders/Security"; - PRODUCT_NAME = security_smime; - PUBLIC_HEADER_DIR = "$(DSTROOT)/usr/local/SecurityPieces/Headers/Security"; - VERSIONING_SYSTEM = "apple-generic"; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Debug; - }; - 79BDD2B00D60CA06000D84D3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - FRAMEWORK_VERSION = A; - INSTALL_PATH = /usr/local/SecurityPieces/Components/Security; - PRODUCT_NAME = security_smime; - WRAPPER_EXTENSION = framework; - }; - name = Debug; - }; - 79BDD2B10D60CA06000D84D3 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - COPY_PHASE_STRIP = NO; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - HEADER_SEARCH_PATHS = ( - "$(PROJECT_DIR)", - "$(PROJECT_DIR)/..", - "$(PROJECT_DIR)/../OSX/utilities", - "$(PROJECT_DIR)/../OSX/sec", - "$(SDKROOT)/usr/local/include/security_libDER", - "$(PROJECT_DIR)/../OSX/libsecurity_asn1", - "$(PROJECT_DIR)/../header_symlinks/iOS/", - "$(PROJECT_DIR)/../header_symlinks/", - "$(BUILT_PRODUCTS_DIR)/usr/local/include", - "$(DSTROOT)/usr/local/include", - ); - INSTALL_PATH = /usr/local/lib; - PRODUCT_NAME = CMS; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/Security; - SKIP_INSTALL = YES; - STRIP_INSTALLED_PRODUCT = NO; - }; - name = Debug; - }; - 79BDD2BA0D60CA0A000D84D3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - 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; - COPY_PHASE_STRIP = YES; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = s; - GCC_PREPROCESSOR_DEFINITIONS = "NDEBUG=1"; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_MISSING_NEWLINE = YES; - GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; - GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES; - GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; - GCC_WARN_MISSING_PARENTHESES = YES; - GCC_WARN_SHADOW = YES; - GCC_WARN_SIGN_COMPARE = YES; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNKNOWN_PRAGMAS = YES; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_LABEL = YES; - GCC_WARN_UNUSED_VALUE = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - OTHER_CFLAGS = "-fconstant-cfstrings"; - SDKROOT = iphoneos.internal; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; - WARNING_CFLAGS = ( - "-Wall", - "-Wextra", - "-Wno-unused-parameter", - "-Wno-missing-field-initializers", - ); - }; - name = Release; - }; - 79BDD2BB0D60CA0A000D84D3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUILD_VARIANTS = ( - normal, - debug, - profile, - ); - CLANG_ENABLE_OBJC_WEAK = YES; - CURRENT_PROJECT_VERSION = 8; - GCC_TREAT_WARNINGS_AS_ERRORS = YES; - HEADER_SEARCH_PATHS = ( - "$(BUILT_PRODUCTS_DIR)/SecurityPieces/Headers", - "$(BUILT_PRODUCTS_DIR)/SecurityPieces/PrivateHeaders", - ); - LIBRARY_STYLE = STATIC; - OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)"; - OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; - OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline"; - OTHER_CFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; - OTHER_CFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline"; - OTHER_CPLUSPLUSFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)"; - OTHER_CPLUSPLUSFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg"; - OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)"; - OTHER_LDFLAGS_normal = "$(OTHER_LDFLAGS)"; - OTHER_LDFLAGS_profile = "$(OTHER_LDFLAGS) -pg"; - PRIVATE_HEADER_DIR = "$(DSTROOT)/usr/local/SecurityPieces/PrivateHeaders/Security"; - PRODUCT_NAME = security_smime; - PUBLIC_HEADER_DIR = "$(DSTROOT)/usr/local/SecurityPieces/Headers/Security"; - VERSIONING_SYSTEM = "apple-generic"; - WARNING_CFLAGS = ( - "-Wmost", - "-Wno-four-char-constants", - "-Wno-unknown-pragmas", - ); - }; - name = Release; - }; - 79BDD2BC0D60CA0A000D84D3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - FRAMEWORK_VERSION = A; - INSTALL_PATH = /usr/local/SecurityPieces/Components/Security; - PRODUCT_NAME = security_smime; - WRAPPER_EXTENSION = framework; - }; - name = Release; - }; - 79BDD2BD0D60CA0A000D84D3 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - COPY_PHASE_STRIP = YES; - GCC_WARN_ABOUT_DEPRECATED_FUNCTIONS = NO; - HEADER_SEARCH_PATHS = ( - "$(PROJECT_DIR)", - "$(PROJECT_DIR)/..", - "$(PROJECT_DIR)/../OSX/utilities", - "$(PROJECT_DIR)/../OSX/sec", - "$(SDKROOT)/usr/local/include/security_libDER", - "$(PROJECT_DIR)/../OSX/libsecurity_asn1", - "$(PROJECT_DIR)/../header_symlinks/iOS/", - "$(PROJECT_DIR)/../header_symlinks/", - "$(BUILT_PRODUCTS_DIR)/usr/local/include", - "$(DSTROOT)/usr/local/include", - ); - INSTALL_PATH = /usr/local/lib; - PRODUCT_NAME = CMS; - PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/Security; - SKIP_INSTALL = YES; - STRIP_INSTALLED_PRODUCT = YES; - }; - name = Release; - }; - D447C4DC1D31C9DD0082FC1D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - D447C4DD1D31C9DD0082FC1D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_OBJC_WEAK = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 79DC321B0D49473C0039E4BC /* Build configuration list for PBXProject "libCMS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 79BDD2AE0D60CA06000D84D3 /* Debug */, - 79BDD2BA0D60CA0A000D84D3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 79DC321C0D49473C0039E4BC /* Build configuration list for PBXFrameworkTarget "security_smime" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 79BDD2B00D60CA06000D84D3 /* Debug */, - 79BDD2BC0D60CA0A000D84D3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 79DC321D0D49473C0039E4BC /* Build configuration list for PBXLibraryTarget "libsecurity_smime" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 79BDD2AF0D60CA06000D84D3 /* Debug */, - 79BDD2BB0D60CA0A000D84D3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 79DC33840D4E6F350039E4BC /* Build configuration list for PBXNativeTarget "libCMS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 79BDD2B10D60CA06000D84D3 /* Debug */, - 79BDD2BD0D60CA0A000D84D3 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - D447C4DE1D31C9DD0082FC1D /* Build configuration list for PBXAggregateTarget "libCMSInstall" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D447C4DC1D31C9DD0082FC1D /* Debug */, - D447C4DD1D31C9DD0082FC1D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 4C2741E803E9FBAF00A80181 /* Project object */; -} diff --git a/ntlm/ntlmBlobPriv.c b/ntlm/ntlmBlobPriv.c index 3044310f..5866c307 100644 --- a/ntlm/ntlmBlobPriv.c +++ b/ntlm/ntlmBlobPriv.c @@ -338,10 +338,13 @@ void md4Hash( unsigned dataLen, unsigned char *digest) // caller-supplied, NTLM_DIGEST_LENGTH */ { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" CC_MD4_CTX ctx; CC_MD4_Init(&ctx); CC_MD4_Update(&ctx, data, dataLen); CC_MD4_Final(digest, &ctx); +#pragma clang diagnostic pop } void md5Hash( @@ -349,10 +352,13 @@ void md5Hash( unsigned dataLen, unsigned char *digest) // caller-supplied, NTLM_DIGEST_LENGTH */ { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" CC_MD5_CTX ctx; CC_MD5_Init(&ctx); CC_MD5_Update(&ctx, data, dataLen); CC_MD5_Final(digest, &ctx); +#pragma clang diagnostic pop } /* diff --git a/protocol/SecProtocol.c b/protocol/SecProtocol.c index c3443da0..048db40f 100644 --- a/protocol/SecProtocol.c +++ b/protocol/SecProtocol.c @@ -6,22 +6,90 @@ #include #include #include +#include +#include "SecProtocolInternal.h" #include +#include + #include #include #include #include +#define MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN 128 + +// Options keys +#define SEC_PROTOCOL_OPTIONS_KEY_min_version "min_version" +#define SEC_PROTOCOL_OPTIONS_KEY_max_version "max_version" +#define SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size "minimum_rsa_key_size" +#define SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size "minimum_ecdsa_key_size" +#define SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm "minimum_signature_algorithm" +#define SEC_PROTOCOL_OPTIONS_KEY_ats_required "ats_required" +#define SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed "ats_minimum_tls_version_allowed" +#define SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed "ats_non_pfs_ciphersuite_allowed" +#define SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate "trusted_peer_certificate" +#define SEC_PROTOCOL_OPTIONS_KEY_disable_sni "disable_sni" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt "enable_fallback_attempt" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_false_start "enable_false_start" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_tickets "enable_tickets" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_sct "enable_sct" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp "enable_ocsp" +#define SEC_PROTOCOL_OPTIONS_KEY_enforce_ev "enforce_ev" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_resumption "enable_resumption" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation "enable_renegotiation" +#define SEC_PROTOCOL_OPTIONS_KEY_enable_early_data "enable_early_data" +#define SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required "peer_authentication_required" +#define SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled "certificate_compression_enabled" +#define SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled "tls_SIKE503_exchange_enabled" +#define SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled "tls_HRSS_exchange_enabled" +#define SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled "eddsa_enabled" +#define SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled "tls_delegated_credentials_enabled" +#define SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled "tls_grease_enabled" +#define SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count "tls_ticket_request_count" +#define SEC_PROTOCOL_OPTIONS_KEY_ciphersuites "ciphersuites" + +// Metadata keys +#define SEC_PROTOCOL_METADATA_KEY_PROCESS_IDENTIFIER "process" +#define SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE "cipher_name" +#define SEC_PROTOCOL_METADATA_KEY_FALLBACK_ENABLED "fallback" +#define SEC_PROTOCOL_METADATA_KEY_DH_GROUP_SIZE "dhe_size" +#define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE "neg_curve" +#define SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE "cert_request_type" +#define SEC_PROTOCOL_METADATA_KEY_LOCAL_PRIVATE_KEY_TYPE "private_key_type" +#define SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE "peer_public_key_type" +#define SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL "negotiated_protocol" +#define SEC_PROTOCOL_METADATA_KEY_ALPN_USED "alpn_used" +#define SEC_PROTOCOL_METADATA_KEY_NPN_USED "npn_used" +#define SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION "version" +#define SEC_PROTOCOL_METADATA_KEY_FALSE_START_ENABLED "false_start_enabled" +#define SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED "false_start_used" +#define SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED "ticket_offered" +#define SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED "ticket_received" +#define SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED "session_resumed" +#define SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED "session_renewed" +#define SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED "resumption_attempted" +#define SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME "ticket_lifetime" +#define SEC_PROTOCOL_METADATA_KEY_MAX_EARLY_DATA_SUPPORTED "max_early_data_supported" +#define SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED "ocsp_enabled" +#define SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED "ocsp_received" +#define SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED "sct_enabled" +#define SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED "sct_received" +#define SEC_PROTOCOL_METADATA_KEY_RSA_SIGNATURE_REQUESTED "client_rsa_requested" +#define SEC_PROTOCOL_METADATA_KEY_ECDSA_SIGNATURE_REQUESTED "client_ecdsa_requested" +#define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE "alert_type" +#define SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE "alert_code" +#define SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE "handshake_state" +#define SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR "stack_error" +#define SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING "none" + #define CFReleaseSafe(value) \ if (value != NULL) { \ CFRelease(value); \ } -typedef bool (^sec_access_block_t)(void *handle); - -static bool +bool sec_protocol_options_access_handle(sec_protocol_options_t options, sec_access_block_t access_block) { @@ -49,7 +117,7 @@ sec_protocol_options_access_handle(sec_protocol_options_t options, return _nw_protocol_options_access_handle(options, access_block); } -static bool +bool sec_protocol_metadata_access_handle(sec_protocol_metadata_t options, sec_access_block_t access_block) { @@ -77,14 +145,170 @@ sec_protocol_metadata_access_handle(sec_protocol_metadata_t options, return _nw_protocol_metadata_access_handle(options, access_block); } -#define SEC_PROTOCOL_OPTIONS_VALIDATE(o,r) \ -if (o == NULL) { \ -return r; \ +#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; \ + } + +bool +sec_protocol_options_contents_are_equal(sec_protocol_options_content_t contentA, sec_protocol_options_content_t contentB) +{ + if (contentA == contentB) { + return true; + } + if (contentA == NULL || contentB == NULL) { + return false; + } + + sec_protocol_options_content_t optionsA = (sec_protocol_options_content_t)contentA; + sec_protocol_options_content_t optionsB = (sec_protocol_options_content_t)contentB; + + // Check boolean and primitive field types first +#define CHECK_FIELD(field) \ + if (optionsA->field != optionsB->field) { \ + return false; \ + } + + CHECK_FIELD(min_version); + CHECK_FIELD(max_version); + CHECK_FIELD(minimum_rsa_key_size); + CHECK_FIELD(minimum_ecdsa_key_size); + CHECK_FIELD(minimum_signature_algorithm); + CHECK_FIELD(tls_ticket_request_count); + CHECK_FIELD(ats_required); + CHECK_FIELD(ats_minimum_tls_version_allowed); + CHECK_FIELD(ats_non_pfs_ciphersuite_allowed); + CHECK_FIELD(trusted_peer_certificate); + CHECK_FIELD(disable_sni); + CHECK_FIELD(enable_fallback_attempt); + CHECK_FIELD(enable_false_start); + CHECK_FIELD(enable_tickets); + CHECK_FIELD(enable_sct); + CHECK_FIELD(enable_ocsp); + CHECK_FIELD(enforce_ev); + CHECK_FIELD(enable_resumption); + CHECK_FIELD(enable_renegotiation); + CHECK_FIELD(enable_early_data); + CHECK_FIELD(peer_authentication_required); + CHECK_FIELD(certificate_compression_enabled); + CHECK_FIELD(tls_SIKE503_exchange_enabled); + CHECK_FIELD(tls_HRSS_exchange_enabled); + CHECK_FIELD(eddsa_enabled); + CHECK_FIELD(tls_delegated_credentials_enabled); + CHECK_FIELD(tls_grease_enabled); + +#undef CHECK_FIELD + + // Check callback block and queue pairs next +#define CHECK_BLOCK_QUEUE(block, queue) \ + if (optionsA->block && optionsB->block) { \ + if (optionsA->block != optionsB->block) { \ + return false; \ + } \ + if (optionsA->queue != optionsB->queue) { \ + return false; \ + } \ + } else if (optionsA->block || optionsB->block) { \ + return false; \ + } + + CHECK_BLOCK_QUEUE(key_update_block, key_update_queue); + CHECK_BLOCK_QUEUE(psk_selection_block, psk_selection_queue); + CHECK_BLOCK_QUEUE(challenge_block, challenge_queue); + CHECK_BLOCK_QUEUE(verify_block, verify_queue); + CHECK_BLOCK_QUEUE(tls_secret_update_block, tls_secret_update_queue); + +#undef CHECK_BLOCK_QUEUE + + // Deep compare dispatch data fields +#define CHECK_DISPATCH_DATA(data) \ + if (optionsA->data && optionsB->data) { \ + if (false == sec_protocol_helper_dispatch_data_equal(optionsA->data, optionsB->data)) { \ + return false; \ + } \ + } else if (optionsA->data || optionsB->data) { \ + return false; \ + } + + CHECK_DISPATCH_DATA(dh_params); + CHECK_DISPATCH_DATA(quic_transport_parameters); + CHECK_DISPATCH_DATA(psk_identity_hint); + +#undef CHECK_DISPATCH_DATA + + // Deep compare XPC objects +#define CHECK_XPC_OBJECT(xpc) \ + if (optionsA->xpc && optionsB->xpc) { \ + if (false == xpc_equal(optionsA->xpc, optionsB->xpc)) { \ + return false; \ + } \ + } else if (optionsA->xpc || optionsB->xpc) { \ + return false; \ + } + + CHECK_XPC_OBJECT(application_protocols); + CHECK_XPC_OBJECT(ciphersuites); + CHECK_XPC_OBJECT(key_exchange_groups); + CHECK_XPC_OBJECT(pre_shared_keys); + +#undef CHECK_XPC_OBJECT + + // Deep compare all other fields + if (optionsA->server_name && optionsB->server_name) { + if (0 != strcmp(optionsA->server_name, optionsB->server_name)) { + return false; + } + } else if (optionsA->server_name || optionsB->server_name) { + return false; + } + + if (optionsA->identity && optionsB->identity) { + SecIdentityRef identityA = sec_identity_copy_ref((sec_identity_t)optionsA->identity); + SecIdentityRef identityB = sec_identity_copy_ref((sec_identity_t)optionsB->identity); + + if (false == CFEqual(identityA, identityB)) { + return false; + } + + CFRelease(identityA); + CFRelease(identityB); + } else if (optionsA->identity || optionsB->identity) { + return false; + } + + if (optionsA->output_handler_access_block && optionsB->output_handler_access_block) { + if (optionsA->output_handler_access_block != optionsB->output_handler_access_block) { + return false; + } + } else if (optionsA->output_handler_access_block || optionsB->output_handler_access_block) { + return false; + } + + return true; } -#define SEC_PROTOCOL_METADATA_VALIDATE(m,r) \ -if (((void *)m == NULL) || ((size_t)m == 0)) { \ -return r; \ +bool +sec_protocol_options_are_equal(sec_protocol_options_t handleA, sec_protocol_options_t handleB) +{ + if (handleA == handleB) { + return true; + } + if (handleA == NULL || handleB == NULL) { + return false; + } + + return sec_protocol_options_access_handle(handleA, ^bool(void *innerA) { + sec_protocol_options_content_t optionsA = (sec_protocol_options_content_t)innerA; + return sec_protocol_options_access_handle(handleB, ^bool(void *innerB) { + sec_protocol_options_content_t optionsB = (sec_protocol_options_content_t)innerB; + return sec_protocol_options_contents_are_equal(optionsA, optionsB); + }); + }); } void @@ -105,7 +329,7 @@ sec_protocol_options_set_local_identity(sec_protocol_options_t options, sec_iden } void -sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite) +sec_protocol_options_append_tls_ciphersuite(sec_protocol_options_t options, tls_ciphersuite_t ciphersuite) { SEC_PROTOCOL_OPTIONS_VALIDATE(options,); @@ -122,7 +346,13 @@ sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCiph } void -sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group) +sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite) +{ + sec_protocol_options_append_tls_ciphersuite(options, (tls_ciphersuite_t)ciphersuite); +} + +void +sec_protocol_options_append_tls_ciphersuite_group(sec_protocol_options_t options, tls_ciphersuite_group_t group) { SEC_PROTOCOL_OPTIONS_VALIDATE(options,); @@ -130,16 +360,16 @@ sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, S 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); + const tls_ciphersuite_t *list = sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(group, &ciphersuite_count); if (list != NULL) { + if (content->ciphersuites == NULL) { + content->ciphersuites = xpc_array_create(NULL, 0); + } + for (size_t i = 0; i < ciphersuite_count; i++) { - SSLCipherSuite ciphersuite = list[i]; + tls_ciphersuite_t ciphersuite = list[i]; xpc_array_set_uint64(content->ciphersuites, XPC_ARRAY_APPEND, (uint64_t)ciphersuite); } } @@ -148,8 +378,51 @@ sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, S }); } +void +sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group) +{ + switch (group) { + case kSSLCiphersuiteGroupDefault: + return sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_default); + case kSSLCiphersuiteGroupCompatibility: + return sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_compatibility); + case kSSLCiphersuiteGroupLegacy: + return sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_legacy); + case kSSLCiphersuiteGroupATS: + return sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_ats); + case kSSLCiphersuiteGroupATSCompatibility: + return sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_ats_compatibility); + } +} + +void +sec_protocol_options_clear_tls_ciphersuites(sec_protocol_options_t options) +{ + 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) { + xpc_release(content->ciphersuites); + content->ciphersuites = NULL; + } + return true; + }); +} + void sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProtocol version) +{ + tls_protocol_version_t protocol_version = (tls_protocol_version_t)SSLProtocolGetVersionCodepoint(version); + if (protocol_version != 0) { + sec_protocol_options_set_min_tls_protocol_version(options, protocol_version); + } +} + +void +sec_protocol_options_set_min_tls_protocol_version(sec_protocol_options_t options, tls_protocol_version_t version) { SEC_PROTOCOL_OPTIONS_VALIDATE(options,); @@ -157,13 +430,35 @@ sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProt sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); - content->min_version = version; + SSLProtocol converted_protocol = SSLProtocolFromVersionCodepoint(version); + content->min_version = converted_protocol; return true; }); } +tls_protocol_version_t +sec_protocol_options_get_default_min_tls_protocol_version(void) +{ + return tls_protocol_version_TLSv10; +} + +tls_protocol_version_t +sec_protocol_options_get_default_min_dtls_protocol_version(void) +{ + return tls_protocol_version_DTLSv10; +} + void sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProtocol version) +{ + tls_protocol_version_t protocol_version = (tls_protocol_version_t)SSLProtocolGetVersionCodepoint(version); + if (protocol_version != 0) { + sec_protocol_options_set_max_tls_protocol_version(options, protocol_version); + } +} + +void +sec_protocol_options_set_max_tls_protocol_version(sec_protocol_options_t options, tls_protocol_version_t version) { SEC_PROTOCOL_OPTIONS_VALIDATE(options,); @@ -171,11 +466,24 @@ sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProt sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); - content->max_version = version; + SSLProtocol converted_protocol = SSLProtocolFromVersionCodepoint(version); + content->max_version = converted_protocol; return true; }); } +tls_protocol_version_t +sec_protocol_options_get_default_max_tls_protocol_version(void) +{ + return tls_protocol_version_TLSv13; +} + +tls_protocol_version_t +sec_protocol_options_get_default_max_dtls_protocol_version(void) +{ + return tls_protocol_version_DTLSv12; +} + void sec_protocol_options_add_tls_application_protocol(sec_protocol_options_t options, const char *application_protocol) { @@ -204,9 +512,17 @@ sec_protocol_options_set_tls_server_name(sec_protocol_options_t options, const c 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); + CFStringRef serverName = CFStringCreateWithCString(NULL, server_name, kCFStringEncodingUTF8); + if (serverName == NULL) { + return false; + } + if (!SecFrameworkIsDNSName(serverName)) { + CFRelease(serverName); + return false; } + CFRelease(serverName); + + free(content->server_name); content->server_name = strdup(server_name); return true; }); @@ -261,6 +577,51 @@ sec_protocol_options_add_pre_shared_key(sec_protocol_options_t options, dispatch }); } +void +sec_protocol_options_set_tls_pre_shared_key_identity_hint(sec_protocol_options_t options, dispatch_data_t psk_identity_hint) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(psk_identity_hint,); + + (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->psk_identity_hint != NULL) { + dispatch_release(content->psk_identity_hint); + } + + content->psk_identity_hint = psk_identity_hint; + dispatch_retain(psk_identity_hint); + return true; + }); +} + +void +sec_protocol_options_set_pre_shared_key_selection_block(sec_protocol_options_t options, sec_protocol_pre_shared_key_selection_t psk_selection_block, dispatch_queue_t psk_selection_queue) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_block,); + SEC_PROTOCOL_OPTIONS_VALIDATE(psk_selection_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->psk_selection_block != NULL) { + Block_release(content->psk_selection_block); + } + if (content->psk_selection_queue != NULL) { + dispatch_release(content->psk_selection_queue); + } + + content->psk_selection_block = Block_copy(psk_selection_block); + content->psk_selection_queue = psk_selection_queue; + dispatch_retain(content->psk_selection_queue); + return true; + }); +} + void sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options, bool fallback_attempt) { @@ -271,6 +632,7 @@ sec_protocol_options_set_tls_is_fallback_attempt(sec_protocol_options_t options, SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_fallback_attempt = fallback_attempt; + content->enable_fallback_attempt_override = true; return true; }); } @@ -285,6 +647,7 @@ sec_protocol_options_set_tls_tickets_enabled(sec_protocol_options_t options, boo SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_tickets = tickets_enabled; + content->enable_tickets_override = true; return true; }); } @@ -299,6 +662,7 @@ sec_protocol_options_set_tls_resumption_enabled(sec_protocol_options_t options, SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_resumption = resumption_enabled; + content->enable_resumption_override = true; return true; }); } @@ -313,6 +677,7 @@ sec_protocol_options_set_tls_false_start_enabled(sec_protocol_options_t options, SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_false_start = false_start_enabled; + content->enable_false_start_override = true; return true; }); } @@ -327,6 +692,7 @@ sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_early_data = early_data_enabled; + content->enable_early_data_override = true; return true; }); } @@ -341,6 +707,7 @@ sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool s SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->disable_sni = sni_disabled; + content->disable_sni_override = true; return true; }); } @@ -355,6 +722,7 @@ sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enforce_ev = enforce_ev; + content->enforce_ev_override = true; return true; }); } @@ -369,6 +737,7 @@ sec_protocol_options_set_tls_ocsp_enabled(sec_protocol_options_t options, bool o SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_ocsp = ocsp_enabled; + content->enable_ocsp_override = true; return true; }); } @@ -383,6 +752,7 @@ sec_protocol_options_set_tls_sct_enabled(sec_protocol_options_t options, bool sc SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_sct = sct_enabled; + content->enable_sct_override = true; return true; }); } @@ -397,6 +767,7 @@ sec_protocol_options_set_tls_renegotiation_enabled(sec_protocol_options_t option SEC_PROTOCOL_OPTIONS_VALIDATE(content, false); content->enable_renegotiation = renegotiation_enabled; + content->enable_renegotiation_override = true; return true; }); } @@ -489,131 +860,711 @@ sec_protocol_options_set_verify_block(sec_protocol_options_t options, sec_protoc } void -sec_protocol_options_add_tls_extension(sec_protocol_options_t options, sec_tls_extension_t extension) +sec_protocol_options_set_session_update_block(sec_protocol_options_t options, sec_protocol_session_update_t update_block, dispatch_queue_t update_queue) { SEC_PROTOCOL_OPTIONS_VALIDATE(options,); - SEC_PROTOCOL_OPTIONS_VALIDATE(extension,); + SEC_PROTOCOL_OPTIONS_VALIDATE(update_block,); + 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->custom_extensions == NULL) { - content->custom_extensions = sec_array_create(); + if (content->session_update_block != NULL) { + Block_release(content->session_update_block); } - - sec_array_append(content->custom_extensions, (sec_object_t)extension); + if (content->session_update_queue != NULL) { + dispatch_release(content->session_update_queue); + } + + content->session_update_block = Block_copy(update_block); + content->session_update_queue = update_queue; + dispatch_retain(content->session_update_queue); return true; }); } -const char * -sec_protocol_metadata_get_negotiated_protocol(sec_protocol_metadata_t metadata) +void +sec_protocol_options_set_tls_encryption_secret_update_block(sec_protocol_options_t options, sec_protocol_tls_encryption_secret_update_t update_block, dispatch_queue_t update_queue) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(update_block,); + SEC_PROTOCOL_OPTIONS_VALIDATE(update_queue,); - __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; + (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->tls_secret_update_block != NULL) { + Block_release(content->tls_secret_update_block); + } + if (content->tls_secret_update_queue != NULL) { + dispatch_release(content->tls_secret_update_queue); + } + + content->tls_secret_update_block = Block_copy(update_block); + content->tls_secret_update_queue = update_queue; + dispatch_retain(content->tls_secret_update_queue); return true; }); - - return negotiated_protocol; } -bool -sec_protocol_metadata_access_peer_certificate_chain(sec_protocol_metadata_t metadata, - void (^handler)(sec_certificate_t certficate)) +void +sec_protocol_options_set_session_state(sec_protocol_options_t options, dispatch_data_t session_state) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); - SEC_PROTOCOL_METADATA_VALIDATE(handler, false); + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(session_state,); - 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; + (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->session_state != NULL) { + dispatch_release(content->session_state); } - 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; - }); + + content->session_state = session_state; + dispatch_retain(session_state); return true; }); } -dispatch_data_t -sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata) +void +sec_protocol_options_set_quic_transport_parameters(sec_protocol_options_t options, dispatch_data_t transport_parameters) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(transport_parameters,); - __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); + (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->quic_transport_parameters != NULL) { + dispatch_release(content->quic_transport_parameters); } + + content->quic_transport_parameters = transport_parameters; + dispatch_retain(transport_parameters); return true; }); - - return peer_public_key; } -SSLProtocol -sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata) +void +sec_protocol_options_set_ats_required(sec_protocol_options_t options, bool required) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, kSSLProtocolUnknown); + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); - __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; + (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->ats_required = required; return true; }); - - return protocol_version; } -SSLCipherSuite -sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata) +void +sec_protocol_options_set_minimum_rsa_key_size(sec_protocol_options_t options, size_t minimum_key_size) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, SSL_NO_SUCH_CIPHERSUITE); + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); - __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; + (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->minimum_rsa_key_size = minimum_key_size; return true; }); - - return negotiated_ciphersuite; } -bool -sec_protocol_metadata_get_early_data_accepted(sec_protocol_metadata_t metadata) +void +sec_protocol_options_set_minimum_ecdsa_key_size(sec_protocol_options_t options, size_t minimum_key_size) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); - 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; + (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->minimum_ecdsa_key_size = minimum_key_size; + return true; }); } -bool -sec_protocol_metadata_access_supported_signature_algorithms(sec_protocol_metadata_t metadata, - void (^handler)(uint16_t signature_algorithm)) +void +sec_protocol_options_set_minimum_signature_algorithm(sec_protocol_options_t options, SecSignatureHashAlgorithm algorithm) { - SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); - SEC_PROTOCOL_METADATA_VALIDATE(handler, false); + 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->minimum_signature_algorithm = algorithm; + return true; + }); +} + +void +sec_protocol_options_set_trusted_peer_certificate(sec_protocol_options_t options, bool trusted_peer_certificate) +{ + 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->trusted_peer_certificate = trusted_peer_certificate; + content->trusted_peer_certificate_override = true; + return true; + }); +} + +void +sec_protocol_options_set_private_key_blocks(sec_protocol_options_t options, + sec_protocol_private_key_sign_t sign_block, + sec_protocol_private_key_decrypt_t decrypt_block, + dispatch_queue_t operation_queue) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(sign_block,); + SEC_PROTOCOL_OPTIONS_VALIDATE(decrypt_block,); + SEC_PROTOCOL_OPTIONS_VALIDATE(operation_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->private_key_sign_block != NULL) { + Block_release(content->private_key_sign_block); + } + if (content->private_key_decrypt_block != NULL) { + Block_release(content->private_key_decrypt_block); + } + if (content->private_key_queue != NULL) { + dispatch_release(content->private_key_queue); + } + + content->private_key_sign_block = Block_copy(sign_block); + content->private_key_decrypt_block = Block_copy(decrypt_block); + content->private_key_queue = operation_queue; + dispatch_retain(content->private_key_queue); + + return true; + }); +} + +void +sec_protocol_options_set_local_certificates(sec_protocol_options_t options, sec_array_t certificates) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(certificates,); + + (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->certificates != NULL) { + sec_release(content->certificates); + } + + content->certificates = certificates; + sec_retain(content->certificates); + return true; + }); +} + +void +sec_protocol_options_set_tls_certificate_compression_enabled(sec_protocol_options_t options, bool certificate_compression_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->certificate_compression_enabled = certificate_compression_enabled; + return true; + }); +} + +void +sec_protocol_options_set_output_handler_access_block(sec_protocol_options_t options, + sec_protocol_output_handler_access_block_t access_block) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(access_block,); + + (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->output_handler_access_block = Block_copy(access_block); + return true; + }); +} + +void +sec_protocol_options_tls_handshake_message_callback(sec_protocol_options_t options, sec_protocol_tls_handshake_message_handler_t handler, dispatch_queue_t queue) +{ + SEC_PROTOCOL_OPTIONS_VALIDATE(options,); + SEC_PROTOCOL_OPTIONS_VALIDATE(handler,); + SEC_PROTOCOL_OPTIONS_VALIDATE(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->handshake_message_callback != NULL) { + Block_release(content->handshake_message_callback); + } + if (content->handshake_message_callback_queue != NULL) { + dispatch_release(content->handshake_message_callback_queue); + } + + content->handshake_message_callback = Block_copy(handler); + content->handshake_message_callback_queue = queue; + dispatch_retain(content->handshake_message_callback_queue); + + return true; + }); +} + +void +sec_protocol_options_set_tls_SIKE503_exchange_enabled(sec_protocol_options_t options, bool tls_SIKE503_exchange_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->tls_SIKE503_exchange_enabled = tls_SIKE503_exchange_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_HRSS_exchange_enabled(sec_protocol_options_t options, bool tls_HRSS_exchange_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->tls_HRSS_exchange_enabled = tls_HRSS_exchange_enabled; + return true; + }); +} + +void +sec_protocol_options_set_eddsa_enabled(sec_protocol_options_t options, bool eddsa_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->eddsa_enabled = eddsa_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_delegated_credentials_enabled(sec_protocol_options_t options, bool tls_delegated_credentials_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->tls_delegated_credentials_enabled = tls_delegated_credentials_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_grease_enabled(sec_protocol_options_t options, bool tls_grease_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->tls_grease_enabled = tls_grease_enabled; + return true; + }); +} + +void +sec_protocol_options_set_tls_ticket_request_count(sec_protocol_options_t options, uint8_t tls_ticket_request_count) +{ + 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->tls_ticket_request_count = tls_ticket_request_count; + return true; + }); +} + +void +sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed(sec_protocol_options_t options, bool ats_non_pfs_ciphersuite_allowed) +{ + 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->ats_non_pfs_ciphersuite_allowed = ats_non_pfs_ciphersuite_allowed; + return true; + }); +} + +void +sec_protocol_options_set_ats_minimum_tls_version_allowed(sec_protocol_options_t options, bool ats_minimum_tls_version_allowed) +{ + 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->ats_minimum_tls_version_allowed = ats_minimum_tls_version_allowed; + return true; + }); +} + +void +sec_protocol_options_append_tls_key_exchange_group(sec_protocol_options_t options, tls_key_exchange_group_t 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->key_exchange_groups == NULL) { + content->key_exchange_groups = xpc_array_create(NULL, 0); + } + xpc_array_set_uint64(content->key_exchange_groups, XPC_ARRAY_APPEND, (uint64_t)group); + return true; + }); +} + +void +sec_protocol_options_add_tls_key_exchange_group(sec_protocol_options_t options, SSLKeyExchangeGroup group) +{ + return sec_protocol_options_append_tls_key_exchange_group(options, (tls_key_exchange_group_t)group); +} + +void +sec_protocol_options_append_tls_key_exchange_group_set(sec_protocol_options_t options, tls_key_exchange_group_set_t set) +{ + 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->key_exchange_groups == NULL) { + content->key_exchange_groups = xpc_array_create(NULL, 0); + } + + // Fetch the list of ciphersuites associated with the ciphersuite group + size_t group_set_count = 0; + const tls_key_exchange_group_t *group_set = sec_protocol_helper_tls_key_exchange_group_set_to_key_exchange_group_list(set, &group_set_count); + if (group_set != NULL) { + for (size_t i = 0; i < group_set_count; i++) { + tls_key_exchange_group_t group = group_set[i]; + xpc_array_set_uint64(content->key_exchange_groups, XPC_ARRAY_APPEND, (uint64_t)group); + } + } + + return true; + }); +} + +void +sec_protocol_options_add_tls_key_exchange_group_set(sec_protocol_options_t options, SSLKeyExchangeGroupSet set) +{ + switch (set) { + case kSSLKeyExchangeGroupSetDefault: + sec_protocol_options_append_tls_key_exchange_group_set(options, tls_key_exchange_group_set_default); + break; + case kSSLKeyExchangeGroupSetCompatibility: + sec_protocol_options_append_tls_key_exchange_group_set(options, tls_key_exchange_group_set_compatibility); + break; + case kSSLKeyExchangeGroupSetLegacy: + sec_protocol_options_append_tls_key_exchange_group_set(options, tls_key_exchange_group_set_legacy); + break; + } +} + +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; +} + +const char * +sec_protocol_metadata_get_server_name(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + + __block const char *server_name = 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); + server_name = content->server_name; + return true; + }); + + return server_name; +} + +uint64_t +sec_protocol_metadata_get_handshake_time_ms(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block uint64_t time = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + time = metadata_content->handshake_time; + return true; + }); + + return time; +} + +uint64_t +sec_protocol_metadata_get_handshake_byte_count(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block uint64_t count = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + count = metadata_content->total_byte_count; + return true; + }); + + return count; +} + +uint64_t +sec_protocol_metadata_get_handshake_sent_byte_count(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block uint64_t count = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + count = metadata_content->sent_byte_count; + return true; + }); + + return count; +} + +uint64_t +sec_protocol_metadata_get_handshake_received_byte_count(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block uint64_t count = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + count = metadata_content->received_byte_count; + return true; + }); + + return count; +} + +size_t +sec_protocol_metadata_get_handshake_read_stall_count(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block size_t count = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + count = metadata_content->read_stall_count; + return true; + }); + + return count; +} + +size_t +sec_protocol_metadata_get_handshake_write_stall_count(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block size_t count = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + count = metadata_content->write_stall_count; + return true; + }); + + return count; +} + +size_t +sec_protocol_metadata_get_handshake_async_call_count(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block size_t count = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + count = metadata_content->async_call_count; + return true; + }); + + return count; +} + +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; +} + +tls_protocol_version_t +sec_protocol_metadata_get_negotiated_tls_protocol_version(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0x0000); + + __block tls_protocol_version_t protocol_version = 0x0000; + (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 = SSLProtocolGetVersionCodepoint(content->negotiated_protocol_version); + return true; + }); + + return protocol_version; +} + +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; +} + +tls_ciphersuite_t +sec_protocol_metadata_get_negotiated_tls_ciphersuite(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0xFFFF); + + __block tls_ciphersuite_t 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; +} + +SSLCipherSuite +sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata) +{ + return (SSLCipherSuite)sec_protocol_metadata_get_negotiated_tls_ciphersuite(metadata); +} + +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; @@ -674,6 +1625,68 @@ sec_protocol_metadata_access_distinguished_names(sec_protocol_metadata_t metadat }); } +static dispatch_data_t +create_dispatch_data_from_xpc_data(xpc_object_t xpc_data) +{ + if (!xpc_data) { + return nil; + } + + size_t data_len = xpc_data_get_length(xpc_data); + if (data_len == 0) { + return nil; + } + + uint8_t *data_buffer = malloc(data_len); + if (!data_buffer) { + return nil; + } + + size_t copied_count = xpc_data_get_bytes(xpc_data, data_buffer, 0, data_len); + if (copied_count != data_len) { + free(data_buffer); + return nil; + } + + dispatch_data_t data = dispatch_data_create(data_buffer, data_len, NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + free(data_buffer); + + return data; +} + +bool +sec_protocol_metadata_access_pre_shared_keys(sec_protocol_metadata_t metadata, + void (^handler)(dispatch_data_t psk, dispatch_data_t _Nullable psk_identity)) +{ + 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->pre_shared_keys == NULL) { + return false; + } + xpc_array_apply(content->pre_shared_keys, ^bool(size_t index, xpc_object_t _Nonnull tuple) { + if (xpc_array_get_count(tuple) == 2) { + xpc_object_t xpc_psk_data = xpc_array_get_value(tuple, 0); + xpc_object_t xpc_psk_identity_data = xpc_array_get_value(tuple, 1); + + dispatch_data_t psk_data = create_dispatch_data_from_xpc_data(xpc_psk_data); + dispatch_data_t psk_identity_data = create_dispatch_data_from_xpc_data(xpc_psk_identity_data); + if (!psk_data || !psk_identity_data) { + // Skip and return early if we can't create a PSK or identity from the provided data. Something's wrong. + return false; + } + + handler(psk_data, psk_identity_data); + } + return true; + }); + return true; + }); +} + static bool sec_protocol_dispatch_data_are_equal(dispatch_data_t left, dispatch_data_t right) { @@ -962,6 +1975,654 @@ sec_protocol_metadata_get_session_renewed(sec_protocol_metadata_t metadata) }); } +SSLConnectionStrength +sec_protocol_metadata_get_connection_strength(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, SSLConnectionStrengthNonsecure); + + __block SSLConnectionStrength strength = SSLConnectionStrengthNonsecure; + (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); + + // TLSv1.2 and higher are considered strong. Anything less than TLSv1.2 is considered weak at best. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + SSLProtocol version = content->negotiated_protocol_version; + if (version >= kTLSProtocol12) { + strength = SSLConnectionStrengthStrong; + } else if (version == kTLSProtocol11 || version == kTLSProtocol1) { + strength = SSLConnectionStrengthWeak; + } else { + strength = SSLConnectionStrengthNonsecure; + } + + // Legacy ciphersuites make the connection weak, for now. We may consider changing this to nonsecure. + SSLCipherSuite ciphersuite = content->negotiated_ciphersuite; + if (strength != SSLConnectionStrengthNonsecure && + SSLCiphersuiteGroupContainsCiphersuite(kSSLCiphersuiteGroupLegacy, ciphersuite)) { + strength = SSLConnectionStrengthWeak; + } +#pragma clang diagnostic pop + + return true; + }); + + return strength; +} + +dispatch_data_t +sec_protocol_metadata_copy_serialized_session(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + + __block dispatch_data_t session = 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->session_exporter_function && content->session_exporter_context) { + sec_protocol_metadata_session_exporter exporter = (sec_protocol_metadata_session_exporter)content->session_exporter_function; + session = exporter(content->session_exporter_context); + } + return true; + }); + return session; +} + +static const char *_options_uint64_keys[] = { + SEC_PROTOCOL_OPTIONS_KEY_min_version, + SEC_PROTOCOL_OPTIONS_KEY_max_version, + SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size, + SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size, + SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm, + SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count, +}; +static const size_t _options_uint64_keys_len = sizeof(_options_uint64_keys) / sizeof(_options_uint64_keys[0]); + +static const char *_options_bool_keys[] = { + SEC_PROTOCOL_OPTIONS_KEY_ats_required, + SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed, + SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed, + SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate, + SEC_PROTOCOL_OPTIONS_KEY_disable_sni, + SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt, + SEC_PROTOCOL_OPTIONS_KEY_enable_false_start, + SEC_PROTOCOL_OPTIONS_KEY_enable_tickets, + SEC_PROTOCOL_OPTIONS_KEY_enable_sct, + SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp, + SEC_PROTOCOL_OPTIONS_KEY_enforce_ev, + SEC_PROTOCOL_OPTIONS_KEY_enable_resumption, + SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation, + SEC_PROTOCOL_OPTIONS_KEY_enable_early_data, + SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required, + SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled, + SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled, + SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled, + SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled, + SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled, + SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled, + +}; +static const size_t _options_bool_keys_len = sizeof(_options_bool_keys) / sizeof(_options_bool_keys[0]); + +static bool +_dictionary_has_key(xpc_object_t dict, const char *target_key) +{ + if (xpc_get_type(dict) != XPC_TYPE_DICTIONARY) { + return false; + } + + return !xpc_dictionary_apply(dict, ^bool(const char * _Nonnull key, xpc_object_t _Nonnull value) { + if (strncmp(key, target_key, strlen(target_key)) == 0) { + return false; + } + return true; + }); +} + +static bool +_arrays_uint64_contents_are_equal(xpc_object_t arrayA, xpc_object_t arrayB) +{ + if (xpc_array_get_count(arrayA) != xpc_array_get_count(arrayB)) { + return false; + } + + return xpc_array_apply(arrayA, ^bool(size_t indexA, xpc_object_t _Nonnull valueA) { + uint64_t raw_valueA = xpc_array_get_uint64(arrayA, indexA); + + bool contains_value = !xpc_array_apply(arrayB, ^bool(size_t indexB, xpc_object_t _Nonnull valueB) { + uint64_t raw_valueB = xpc_array_get_uint64(arrayB, indexB); + if (raw_valueA == raw_valueB) { + return false; + } + return true; + }); + + if (!contains_value) { + return false; + } + + return true; + }); +} + +static bool +_options_config_matches_partial_config(xpc_object_t full, xpc_object_t partial) +{ + SEC_PROTOCOL_METADATA_VALIDATE(full, false); + SEC_PROTOCOL_METADATA_VALIDATE(partial, false); + + return xpc_dictionary_apply(partial, ^bool(const char * _Nonnull entry_key, xpc_object_t _Nonnull value) { + size_t entry_key_len = strnlen(entry_key, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN); + + for (size_t i = 0; i < _options_uint64_keys_len; i++) { + const char *key = _options_uint64_keys[i]; + if (strncmp(entry_key, key, MAX(entry_key_len, strlen(key))) == 0) { + if (_dictionary_has_key(full, key)) { + if (xpc_dictionary_get_uint64(full, key) != xpc_dictionary_get_uint64(partial, key)) { + return false; + } + } else { + return false; + } + } + } + + for (size_t i = 0; i < _options_bool_keys_len; i++) { + const char *key = _options_bool_keys[i]; + if (strncmp(entry_key, key, MAX(entry_key_len, strlen(key))) == 0) { + if (_dictionary_has_key(full, key)) { + if (xpc_dictionary_get_bool(full, key) != xpc_dictionary_get_bool(partial, key)) { + return false; + } + } else { + return false; + } + } + } + + // Now check for ciphersuite options, as these are not expressed via serialized configs + if (strncmp(entry_key, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites, entry_key_len) == 0) { + if (xpc_get_type(value) == XPC_TYPE_ARRAY) { + bool matching = xpc_dictionary_apply(full, ^bool(const char * _Nonnull full_key, xpc_object_t _Nonnull full_value) { + if (strncmp(full_key, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites, entry_key_len) == 0) { + if (xpc_get_type(full_value) == XPC_TYPE_ARRAY) { + return _arrays_uint64_contents_are_equal(value, full_value); + } + } + return true; + }); + + if (!matching) { + return false; + } + } + } + + return true; + }); +} + +static bool +_serialize_options(xpc_object_t dictionary, sec_protocol_options_content_t options_content) +{ +#define xpc_dictionary_set_string_default(d, key, value, default) \ + do { \ + if (value != NULL) { \ + xpc_dictionary_set_string(d, key, value); \ + } else { \ + xpc_dictionary_set_string(d, key, default); \ + } \ + } while (0); + +#define EXPAND_PARAMETER(field) \ + SEC_PROTOCOL_OPTIONS_KEY_##field , options_content->field + + xpc_dictionary_set_uint64(dictionary, EXPAND_PARAMETER(min_version)); + xpc_dictionary_set_uint64(dictionary, EXPAND_PARAMETER(max_version)); + xpc_dictionary_set_uint64(dictionary, EXPAND_PARAMETER(minimum_rsa_key_size)); + xpc_dictionary_set_uint64(dictionary, EXPAND_PARAMETER(minimum_ecdsa_key_size)); + xpc_dictionary_set_uint64(dictionary, EXPAND_PARAMETER(minimum_signature_algorithm)); + xpc_dictionary_set_uint64(dictionary, EXPAND_PARAMETER(tls_ticket_request_count)); + + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(ats_required)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(ats_minimum_tls_version_allowed)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(ats_non_pfs_ciphersuite_allowed)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(trusted_peer_certificate)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(disable_sni)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_fallback_attempt)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_false_start)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_tickets)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_sct)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_ocsp)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enforce_ev)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_resumption)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_renegotiation)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(enable_early_data)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(peer_authentication_required)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(certificate_compression_enabled)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(tls_SIKE503_exchange_enabled)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(tls_HRSS_exchange_enabled)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(eddsa_enabled)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(tls_delegated_credentials_enabled)); + xpc_dictionary_set_bool(dictionary, EXPAND_PARAMETER(tls_grease_enabled)); + +#undef EXPAND_PARAMETER +#undef xpc_dictionary_set_string_default + + return true; +} + +static struct _options_bool_key_setter { + const char *key; + void (*setter_pointer)(sec_protocol_options_t, bool); +} _options_bool_key_setters[] = { + { + .key = SEC_PROTOCOL_OPTIONS_KEY_ats_required, + .setter_pointer = sec_protocol_options_set_ats_required, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_ats_minimum_tls_version_allowed, + .setter_pointer = sec_protocol_options_set_ats_minimum_tls_version_allowed, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_ats_non_pfs_ciphersuite_allowed, + .setter_pointer = sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_trusted_peer_certificate, + .setter_pointer = sec_protocol_options_set_trusted_peer_certificate, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_disable_sni, + .setter_pointer = sec_protocol_options_set_tls_sni_disabled + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_fallback_attempt, + .setter_pointer = sec_protocol_options_set_tls_is_fallback_attempt, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_false_start, + .setter_pointer = sec_protocol_options_set_tls_false_start_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_tickets, + .setter_pointer = sec_protocol_options_set_tls_tickets_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_sct, + .setter_pointer = sec_protocol_options_set_tls_sct_enabled + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_ocsp, + .setter_pointer = sec_protocol_options_set_tls_ocsp_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enforce_ev, + .setter_pointer = sec_protocol_options_set_enforce_ev, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_resumption, + .setter_pointer = sec_protocol_options_set_tls_resumption_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_renegotiation, + .setter_pointer = sec_protocol_options_set_tls_renegotiation_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_enable_early_data, + .setter_pointer = sec_protocol_options_set_tls_early_data_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_peer_authentication_required, + .setter_pointer = sec_protocol_options_set_peer_authentication_required, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_certificate_compression_enabled, + .setter_pointer = sec_protocol_options_set_tls_certificate_compression_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_tls_SIKE503_exchange_enabled, + .setter_pointer = sec_protocol_options_set_tls_SIKE503_exchange_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_tls_HRSS_exchange_enabled, + .setter_pointer = sec_protocol_options_set_tls_HRSS_exchange_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_eddsa_enabled, + .setter_pointer = sec_protocol_options_set_eddsa_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_tls_delegated_credentials_enabled, + .setter_pointer = sec_protocol_options_set_tls_delegated_credentials_enabled, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_tls_grease_enabled, + .setter_pointer = sec_protocol_options_set_tls_grease_enabled, + }, +}; +static const size_t _options_bool_key_setters_len = sizeof(_options_bool_key_setters) / sizeof(_options_bool_key_setters[0]); + +static struct _options_uint64_key_setter { + const char *key; + void (*setter_pointer)(sec_protocol_options_t, uint64_t); +} _options_uint64_key_setters[] = { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + { + .key = SEC_PROTOCOL_OPTIONS_KEY_min_version, + .setter_pointer = (void (*)(sec_protocol_options_t, uint64_t))sec_protocol_options_set_tls_min_version + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_max_version, + .setter_pointer = (void (*)(sec_protocol_options_t, uint64_t))sec_protocol_options_set_tls_max_version + }, +#pragma clang diagnostic pop + { + .key = SEC_PROTOCOL_OPTIONS_KEY_minimum_rsa_key_size, + .setter_pointer = (void (*)(sec_protocol_options_t, uint64_t))sec_protocol_options_set_minimum_rsa_key_size, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_minimum_ecdsa_key_size, + .setter_pointer = (void (*)(sec_protocol_options_t, uint64_t))sec_protocol_options_set_minimum_ecdsa_key_size, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_minimum_signature_algorithm, + .setter_pointer = (void (*)(sec_protocol_options_t, uint64_t))sec_protocol_options_set_minimum_signature_algorithm, + }, + { + .key = SEC_PROTOCOL_OPTIONS_KEY_tls_ticket_request_count, + .setter_pointer = (void (*)(sec_protocol_options_t, uint64_t))sec_protocol_options_set_tls_ticket_request_count, + }, +}; +static const size_t _options_uint64_key_setters_len = sizeof(_options_uint64_key_setters) / sizeof(_options_uint64_key_setters[0]); + +static bool +_apply_config_options(sec_protocol_options_t options, xpc_object_t config) +{ + return sec_protocol_options_access_handle(options, ^bool(void *options_handle) { + sec_protocol_options_content_t options_content = (sec_protocol_options_content_t)options_handle; + SEC_PROTOCOL_METADATA_VALIDATE(options_content, false); + return xpc_dictionary_apply(config, ^bool(const char * _Nonnull key, xpc_object_t _Nonnull value) { + + size_t key_len = strnlen(key, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN); + for (size_t i = 0; i < _options_bool_key_setters_len; i++) { + const char *setter_key = _options_bool_key_setters[i].key; + size_t setter_key_len = strnlen(setter_key, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN); + if (strncmp(setter_key, key, MAX(key_len, setter_key_len)) == 0) { + _options_bool_key_setters[i].setter_pointer(options, xpc_dictionary_get_bool(config, key)); + } + } + + for (size_t i = 0; i < _options_uint64_key_setters_len; i++) { + const char *setter_key = _options_uint64_key_setters[i].key; + size_t setter_key_len = strnlen(setter_key, MAX_SEC_PROTOCOL_OPTIONS_KEY_LEN); + if (strncmp(setter_key, key, MAX(key_len, setter_key_len)) == 0) { + _options_uint64_key_setters[i].setter_pointer(options, xpc_dictionary_get_uint64(config, key)); + } + } + + // Now check for ciphersuite options, as these are not expressed via serialized configs + if (strncmp(key, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites, key_len) == 0) { + if (xpc_get_type(value) == XPC_TYPE_ARRAY) { + xpc_array_apply(value, ^bool(size_t index, xpc_object_t _Nonnull ciphersuite_value) { + SSLCipherSuite ciphersuite = (SSLCipherSuite)xpc_array_get_uint64(value, index); + sec_protocol_options_append_tls_ciphersuite(options, ciphersuite); + return true; + }); + } + } + + return true; + }); + }); +} + +static bool +_serialize_metadata(xpc_object_t dictionary, sec_protocol_metadata_content_t metadata_content) +{ +#define xpc_dictionary_set_string_default(d, key, value, default) \ + do { \ + if (value != NULL) { \ + xpc_dictionary_set_string(d, key, value); \ + } else { \ + xpc_dictionary_set_string(d, key, default); \ + } \ + } while (0); + + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE, metadata_content->negotiated_ciphersuite); + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_PROTOCOL_VERSION, metadata_content->negotiated_protocol_version); + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_TICKET_LIFETIME, metadata_content->ticket_lifetime); + + xpc_dictionary_set_string_default(dictionary, SEC_PROTOCOL_METADATA_KEY_PEER_PUBLIC_KEY_TYPE, + metadata_content->peer_public_key_type, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING); + xpc_dictionary_set_string_default(dictionary, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_CURVE, + metadata_content->negotiated_curve, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING); + xpc_dictionary_set_string_default(dictionary, SEC_PROTOCOL_METADATA_KEY_PEER_CERTIFICATE_REQUEST_TYPE, + metadata_content->certificate_request_type, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING); + xpc_dictionary_set_string_default(dictionary, SEC_PROTOCOL_METADATA_KEY_NEGOTIATED_PROTOCOL, + metadata_content->negotiated_protocol, SEC_PROTOCOL_METADATA_KEY_DEFAULT_EMPTY_STRING); + + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_FALSE_START_USED, metadata_content->false_start_used); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_SESSION_RESUMED, metadata_content->session_resumed); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_TICKET_OFFERED, metadata_content->ticket_offered); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_TICKET_RECEIVED, metadata_content->ticket_received); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_SESSION_RENEWED, metadata_content->session_renewed); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_RESUMPTION_ATTEMPTED, metadata_content->resumption_attempted); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_ALPN_USED, metadata_content->alpn_used); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_NPN_USED, metadata_content->npn_used); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_OCSP_ENABLED, metadata_content->ocsp_enabled); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_OCSP_RECEIVED, metadata_content->ocsp_response != NULL); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_SCT_ENABLED, metadata_content->sct_enabled); + xpc_dictionary_set_bool(dictionary, SEC_PROTOCOL_METADATA_KEY_SCT_RECEIVED, metadata_content->signed_certificate_timestamps != NULL); + +#undef xpc_dictionary_set_string_default + + return true; +} + +static bool +_serialize_success_with_options(xpc_object_t dictionary, sec_protocol_metadata_content_t metadata_content, sec_protocol_options_content_t options_content) +{ + if (!_serialize_options(dictionary, options_content)) { + return false; + } + if (!_serialize_metadata(dictionary, metadata_content)) { + return false; + } + return true; +} + +static bool +_serialize_failure_with_options(xpc_object_t dictionary, sec_protocol_metadata_content_t metadata_content, sec_protocol_options_content_t options_content) +{ + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_TYPE, metadata_content->alert_type); + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_ALERT_CODE, metadata_content->alert_code); + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_HANDSHAKE_STATE, metadata_content->handshake_state); + xpc_dictionary_set_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR, metadata_content->stack_error); + + return true; +} + +xpc_object_t +sec_protocol_metadata_serialize_with_options(sec_protocol_metadata_t metadata, sec_protocol_options_t options) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + SEC_PROTOCOL_METADATA_VALIDATE(options, NULL); + + __block xpc_object_t dictionary = xpc_dictionary_create(NULL, NULL, 0); + if (dictionary == NULL) { + return NULL; + } + + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + + return sec_protocol_options_access_handle(options, ^bool(void *options_handle) { + sec_protocol_options_content_t options_content = (sec_protocol_options_content_t)options_handle; + SEC_PROTOCOL_METADATA_VALIDATE(options_content, false); + + if (metadata_content->failure) { + return _serialize_failure_with_options(dictionary, metadata_content, options_content); + } else { + return _serialize_success_with_options(dictionary, metadata_content, options_content); + } + }); + }); + + return dictionary; +} + +dispatch_data_t +sec_protocol_metadata_copy_quic_transport_parameters(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + + __block dispatch_data_t copied_parameters = NULL; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + if (metadata_content->quic_transport_parameters) { + copied_parameters = metadata_content->quic_transport_parameters; + dispatch_retain(copied_parameters); + } + return true; + }); + + return copied_parameters; +} + +bool +sec_protocol_metadata_get_tls_certificate_compression_used(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, false); + + __block bool certificate_compression_used = false; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + certificate_compression_used = metadata_content->certificate_compression_used; + return true; + }); + + return certificate_compression_used; +} + +uint16_t +sec_protocol_metadata_get_tls_certificate_compression_algorithm(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block uint16_t certificate_compression_algorithm = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + certificate_compression_algorithm = metadata_content->certificate_compression_algorithm; + return true; + }); + + return certificate_compression_algorithm; +} + +uint64_t +sec_protocol_metadata_get_handshake_rtt(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, 0); + + __block uint64_t rtt = 0; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + rtt = metadata_content->handshake_rtt; + return true; + }); + + return rtt; +} + +sec_trust_t +sec_protocol_metadata_copy_sec_trust(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, nil); + + __block sec_trust_t trust = nil; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + if (metadata_content->trust_ref != nil) { + trust = metadata_content->trust_ref; + sec_retain(trust); + } + return true; + }); + + return trust; +} + +sec_identity_t +sec_protocol_metadata_copy_sec_identity(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, nil); + + __block sec_identity_t identity = nil; + (void)sec_protocol_metadata_access_handle(metadata, ^bool(void *metadata_handle) { + sec_protocol_metadata_content_t metadata_content = (sec_protocol_metadata_content_t)metadata_handle; + SEC_PROTOCOL_METADATA_VALIDATE(metadata_content, false); + if (metadata_content->identity != nil) { + identity = metadata_content->identity; + sec_retain(identity); + } + return true; + }); + + return identity; +} + +bool +sec_protocol_metadata_access_sent_certificates(sec_protocol_metadata_t metadata, + void (^handler)(sec_certificate_t certificate)) +{ + 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->identity != nil && sec_identity_has_certificates(content->identity)) { + return sec_identity_access_certificates(content->identity, handler); + } + + if (content->sent_certificate_chain != NULL) { + return sec_array_apply(content->sent_certificate_chain, ^bool(__unused size_t index, sec_object_t object) { + handler((sec_certificate_t)object); + return true; + }); + } + + return false; + }); +} + +const char * +sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata) +{ + SEC_PROTOCOL_METADATA_VALIDATE(metadata, NULL); + + __block const char *negotiated_curve = 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_curve = content->negotiated_curve; + return true; + }); + + return negotiated_curve; +} + void * sec_retain(void *obj) { @@ -979,3 +2640,67 @@ sec_release(void *obj) os_release(obj); } } + +xpc_object_t +sec_protocol_options_create_config(sec_protocol_options_t options) +{ + SEC_PROTOCOL_METADATA_VALIDATE(options, NULL); + + __block xpc_object_t dictionary = xpc_dictionary_create(NULL, NULL, 0); + if (dictionary == NULL) { + return NULL; + } + + bool serialized = sec_protocol_options_access_handle(options, ^bool(void *options_handle) { + sec_protocol_options_content_t options_content = (sec_protocol_options_content_t)options_handle; + SEC_PROTOCOL_METADATA_VALIDATE(options_content, false); + + if (_serialize_options(dictionary, options_content)) { + xpc_dictionary_set_value(dictionary, SEC_PROTOCOL_OPTIONS_KEY_ciphersuites, options_content->ciphersuites); + return true; + } + + return false; + }); + + if (serialized) { + return dictionary; // retained reference + } else { + xpc_release(dictionary); + return NULL; + } +} + +bool +sec_protocol_options_matches_config(sec_protocol_options_t options, xpc_object_t config) +{ + SEC_PROTOCOL_METADATA_VALIDATE(options, false); + SEC_PROTOCOL_METADATA_VALIDATE(config, false); + + if (xpc_get_type(config) != XPC_TYPE_DICTIONARY) { + return false; + } + + xpc_object_t options_config = sec_protocol_options_create_config(options); + if (options_config == NULL) { + return false; + } + + bool match = _options_config_matches_partial_config(options_config, config); + xpc_release(options_config); + + return match; +} + +bool +sec_protocol_options_apply_config(sec_protocol_options_t options, xpc_object_t config) +{ + SEC_PROTOCOL_METADATA_VALIDATE(options, false); + SEC_PROTOCOL_METADATA_VALIDATE(config, false); + + if (xpc_get_type(config) != XPC_TYPE_DICTIONARY) { + return false; + } + + return _apply_config_options(options, config); +} diff --git a/protocol/SecProtocolConfiguration.h b/protocol/SecProtocolConfiguration.h new file mode 100644 index 00000000..6d8694d3 --- /dev/null +++ b/protocol/SecProtocolConfiguration.h @@ -0,0 +1,174 @@ +/* + * 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 SecProtocolConfiguration_h +#define SecProtocolConfiguration_h + +#include +#include + +#include +#include + +#ifndef SEC_OBJECT_IMPL +/*! + * A `sec_protocol_configuration` is an object that encapsulates App Transport Security + * information and vends `sec_protocol_options` to clients for creating new connections. + * It may also be queried to determine for what domains TLS is required. + */ +SEC_OBJECT_DECL(sec_protocol_configuration); +#endif // !SEC_OBJECT_IMPL + +__BEGIN_DECLS + +SEC_ASSUME_NONNULL_BEGIN + +/*! + * @function sec_protocol_configuration_copy_singleton + * + * @abstract + * Copy the per-process `sec_protocol_configuration_t` object. + * + * @return A non-nil `sec_protocol_configuration_t` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED sec_protocol_configuration_t +sec_protocol_configuration_copy_singleton(void); + +/*! + * @function sec_protocol_configuration_set_ats_overrides + * + * @abstract + * Set ATS overrides + * + * @param config + * A `sec_protocol_configuration_t` instance. + * + * @param override_dictionary + * A `CFDictionaryRef` dictionary containing the ATS overrides as + * documented here: https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33 + * + * @return True if successful, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_configuration_set_ats_overrides(sec_protocol_configuration_t config, CFDictionaryRef override_dictionary); + +/*! + * @function sec_protocol_configuration_copy_transformed_options + * + * @abstract + * Transform an existing `sec_protocol_options_t` instance with a `sec_protocol_configuration_t` instance. + * + * @param config + * A `sec_protocol_configuration_t` instance. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @return The transformed `sec_protocol_options` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable sec_protocol_options_t +sec_protocol_configuration_copy_transformed_options(sec_protocol_configuration_t config, sec_protocol_options_t options); + +/*! + * @function sec_protocol_configuration_copy_transformed_options_for_host + * + * @abstract + * Transform an existing `sec_protocol_options_t` instance with a `sec_protocol_configuration_t` instance + * using a specific host endpoint. Note that the service (port) is omitted from this formula. + * + * @param config + * A `sec_protocol_configuration_t` instance. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param host + * A NULL-terminated C string containing the host in question. + * + * @return The transformed `sec_protocol_options` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable sec_protocol_options_t +sec_protocol_configuration_copy_transformed_options_for_host(sec_protocol_configuration_t config, sec_protocol_options_t options, const char *host); + +/*! + * @function sec_protocol_configuration_tls_required + * + * @abstract + * Determine if TLS is required by policy for a generic connection. Note that the service (port) is omitted + * from this formula. + * + * @param config + * A `sec_protocol_configuration_t` instance. + * + * @return True if connections require TLS, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_configuration_tls_required(sec_protocol_configuration_t config); + +/*! + * @function sec_protocol_configuration_tls_required_for_host + * + * @abstract + * Determine if TLS is required -- by policy -- for the given host endpoint. Note that the service (port) is + * omitted from this formula. + * + * @param config + * A `sec_protocol_configuration_t` instance. + * + * @param host + * A NULL-terminated C string containing the host endpoint to examine. + * + * @return True if connections to the endpoint require TLS, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_configuration_tls_required_for_host(sec_protocol_configuration_t config, const char *host); + +/*! + * @function sec_protocol_configuration_tls_required_for_address + * + * @abstract + * Determine if TLS is required -- by policy -- for the given address endpoint. + * + * @param config + * A `sec_protocol_configuration_t` instance. + * + * @param address + * A NULL-terminated C string containing the address endpoint to examine. + * + * @return True if connections to the endpoint require TLS, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_configuration_tls_required_for_address(sec_protocol_configuration_t config, const char *address); + +SEC_ASSUME_NONNULL_END + +__END_DECLS + +#endif // SecProtocolConfiguration_h diff --git a/protocol/SecProtocolConfiguration.m b/protocol/SecProtocolConfiguration.m new file mode 100644 index 00000000..a88816f1 --- /dev/null +++ b/protocol/SecProtocolConfiguration.m @@ -0,0 +1,402 @@ +// +// SecProtocolConfiguration.m +// Security +// + +#import "SecProtocolInternal.h" +#import +#import +#import +#import +#import + +#define MINIMUM_RSA_KEY_SIZE 2048 +#define MINIMUM_ECDSA_KEY_SIZE 2048 +#define MINIMUM_HASH_ALGORITHM kSecSignatureHashAlgorithmSHA256 +#define MINIMUM_PROTOCOL kTLSProtocol12 + +static const char * +get_running_process() +{ + static const char *processName = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + const char **procName = _CFGetProgname(); + processName = *procName; + }); + return processName; +} + +static bool +process_matches_target(const char *target_process) +{ + if (target_process == NULL) { + return false; + } + + const char *process = get_running_process(); + if (process != NULL) { + return (strlen(target_process) == strlen(process) && + strncmp(process, target_process, strlen(target_process)) == 0); + } + return false; +} + +static bool +client_is_WebKit() +{ + static bool is_WebKit = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + is_WebKit = process_matches_target("com.apple.WebKit"); + }); + return is_WebKit; +} + +static bool +client_is_mediaserverd() +{ + static bool is_mediaserverd = false; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + is_mediaserverd = process_matches_target("mediaserverd"); + }); + return is_mediaserverd; +} + +sec_protocol_configuration_t +sec_protocol_configuration_copy_singleton(void) +{ + static dispatch_once_t onceToken; + static sec_protocol_configuration_t singleton = nil; + dispatch_once(&onceToken, ^{ + singleton = sec_protocol_configuration_create_with_builder(sec_protocol_configuration_builder_copy_default()); + }); + return singleton; +} + +static sec_protocol_options_t +sec_protocol_configuration_copy_transformed_options_with_ats_minimums(sec_protocol_options_t options) +{ + sec_protocol_options_set_ats_required(options, true); + sec_protocol_options_set_trusted_peer_certificate(options, true); + sec_protocol_options_set_minimum_rsa_key_size(options, MINIMUM_RSA_KEY_SIZE); + sec_protocol_options_set_minimum_ecdsa_key_size(options, MINIMUM_ECDSA_KEY_SIZE); + sec_protocol_options_set_minimum_signature_algorithm(options, MINIMUM_HASH_ALGORITHM); + sec_protocol_options_set_min_tls_protocol_version(options, tls_protocol_version_TLSv12); + return options; +} + +sec_protocol_options_t +sec_protocol_configuration_copy_transformed_options(__unused sec_protocol_configuration_t config, sec_protocol_options_t options) +{ + sec_protocol_options_clear_tls_ciphersuites(options); + sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_ats); + return sec_protocol_configuration_copy_transformed_options_with_ats_minimums(options); +} + +static const char * +_find_parent_domain(const char *domain) +{ + size_t domain_len = strlen(domain); + size_t index = 0; + while (index < domain_len) { + // Once we hit a dot, the parent domain begins at the next segment. + if (domain[index] == '.' && index < domain_len) { + return domain + 1; + } + + // Skip over all characters that are not dots. + index++; + } + + return NULL; +} + +static sec_protocol_options_t +sec_protocol_configuration_copy_transformed_options_for_host_internal(sec_protocol_configuration_t config, sec_protocol_options_t options, + const char *host, bool parent_domain) +{ + xpc_object_t map = sec_protocol_configuration_get_map(config); + if (map == nil) { + return options; + } + + xpc_object_t domain_map = xpc_dictionary_get_dictionary(map, kExceptionDomains); + if (domain_map == nil) { + return options; + } + + xpc_object_t entry = xpc_dictionary_get_dictionary(domain_map, host); + if (entry == nil) { + const char *parent_host = _find_parent_domain(host); + if (parent_host != NULL) { + return sec_protocol_configuration_copy_transformed_options_for_host_internal(config, options, parent_host, true); + } + + // If we could not find a matching domain, apply the default connection properties. + return sec_protocol_configuration_copy_transformed_options(config, options); + } + + bool pfs_required = xpc_dictionary_get_bool(entry, kExceptionRequiresForwardSecrecy); + if (pfs_required) { + sec_protocol_options_clear_tls_ciphersuites(options); + sec_protocol_options_append_tls_ciphersuite_group(options, tls_ciphersuite_group_ats); + } else { + // Otherwise, record the fact that non-PFS ciphersuites are permitted. + // This does not mean that the caller actually configured a non-PFS ciphersuite. + sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed(options, true); + } + + tls_protocol_version_t minimum_protocol = (SSLProtocol)xpc_dictionary_get_int64(entry, kExceptionMinimumTLSVersion); + if (minimum_protocol != 0) { + // Record the fact that an excepted TLS version was configured. + sec_protocol_options_set_min_tls_protocol_version(options, minimum_protocol); + sec_protocol_options_set_ats_minimum_tls_version_allowed(options, true); + } + + return options; +} + +sec_protocol_options_t +sec_protocol_configuration_copy_transformed_options_for_host(sec_protocol_configuration_t config, sec_protocol_options_t options, const char *host) +{ + return sec_protocol_configuration_copy_transformed_options_for_host_internal(config, sec_protocol_configuration_copy_transformed_options_with_ats_minimums(options), host, false); +} + +bool +sec_protocol_configuration_tls_required(sec_protocol_configuration_t config) +{ + xpc_object_t map = sec_protocol_configuration_get_map(config); + if (map == nil) { + // Fail closed. + return true; + } + + bool allows_media_loads = xpc_dictionary_get_bool(map, kAllowsArbitraryLoadsForMedia); + if (allows_media_loads && client_is_mediaserverd()) { + return false; + } + + bool allows_web_loads = xpc_dictionary_get_bool(map, kAllowsArbitraryLoadsInWebContent); + if (allows_web_loads && client_is_WebKit()) { + return false; + } + + return !xpc_dictionary_get_bool(map, kAllowsArbitraryLoads); +} + +static bool +sec_protocol_configuration_tls_required_for_host_internal(sec_protocol_configuration_t config, const char *host, bool parent_domain) +{ + xpc_object_t map = sec_protocol_configuration_get_map(config); + if (map == nil) { + // Fail closed. + return true; + } + + xpc_object_t domain_map = xpc_dictionary_get_dictionary(map, kExceptionDomains); + if (domain_map == nil) { + // Absent per-domain exceptions, use the default. + return sec_protocol_configuration_tls_required(config); + } + + xpc_object_t entry = xpc_dictionary_get_dictionary(domain_map, host); + if (entry == nil) { + const char *parent_host = _find_parent_domain(host); + if (parent_host != NULL) { + return sec_protocol_configuration_tls_required_for_host_internal(config, parent_host, true); + } + return sec_protocol_configuration_tls_required(config); + } + + bool requires_tls = !xpc_dictionary_get_bool(entry, kExceptionAllowsInsecureHTTPLoads); + bool includes_subdomains = !xpc_dictionary_get_bool(entry, kExceptionAllowsInsecureHTTPLoads); + + if (parent_domain && !includes_subdomains) { + // If this domain's exceptions do not apply to subdomains, then default to the application default policy. + return sec_protocol_configuration_tls_required(config); + } + + return requires_tls; +} + +bool +sec_protocol_configuration_tls_required_for_host(sec_protocol_configuration_t config, const char *host) +{ + return sec_protocol_configuration_tls_required_for_host_internal(config, host, false); +} + +bool +sec_protocol_configuration_tls_required_for_address(sec_protocol_configuration_t config, const char *address) +{ + xpc_object_t map = sec_protocol_configuration_get_map(config); + if (map == nil) { + // Fail closed. + return true; + } + + return !xpc_dictionary_get_bool(map, kAllowsLocalNetworking); +} + +static tls_protocol_version_t +sec_protocol_configuration_protocol_string_to_version(const char *protocol) +{ + if (protocol == NULL) { + return 0; + } + + const char *tlsv10 = "TLSv1.0"; + const char *tlsv11 = "TLSv1.1"; + const char *tlsv12 = "TLSv1.2"; + const char *tlsv13 = "TLSv1.3"; + + if (strlen(protocol) == strlen(tlsv10) && strncmp(protocol, tlsv10, strlen(protocol)) == 0) { + return tls_protocol_version_TLSv10; + } else if (strlen(protocol) == strlen(tlsv11) && strncmp(protocol, tlsv11, strlen(protocol)) == 0) { + return tls_protocol_version_TLSv11; + } else if (strlen(protocol) == strlen(tlsv12) && strncmp(protocol, tlsv12, strlen(protocol)) == 0) { + return tls_protocol_version_TLSv12; + } else if (strlen(protocol) == strlen(tlsv13) && strncmp(protocol, tlsv13, strlen(protocol)) == 0) { + return tls_protocol_version_TLSv13; + } + + return 0; +} + +static void +sec_protocol_configuration_register_builtin_exception(xpc_object_t dict, const char *name, + tls_protocol_version_t protocol, bool requires_pfs, + bool allows_http, bool includes_subdomains, bool require_ct) +{ + xpc_object_t domain_map = xpc_dictionary_get_dictionary(dict, kExceptionDomains); + if (domain_map) { + xpc_object_t entry = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_value(entry, kExceptionDomains, domain_map); + + xpc_dictionary_set_bool(entry, kIncludesSubdomains, includes_subdomains); + xpc_dictionary_set_int64(entry, kExceptionMinimumTLSVersion, protocol); + xpc_dictionary_set_bool(entry, kExceptionAllowsInsecureHTTPLoads, allows_http); + xpc_dictionary_set_bool(entry, kExceptionRequiresForwardSecrecy, requires_pfs); + + xpc_dictionary_set_value(domain_map, name, entry); + } +} + +void +sec_protocol_configuration_register_builtin_exceptions(sec_protocol_configuration_t config) +{ + xpc_object_t dict = sec_protocol_configuration_get_map(config); + sec_protocol_configuration_register_builtin_exception(dict, "apple.com", tls_protocol_version_TLSv12, false, true, true, true); + sec_protocol_configuration_register_builtin_exception(dict, "ls.apple.com", tls_protocol_version_TLSv10, false, true, true, true); + sec_protocol_configuration_register_builtin_exception(dict, "gs.apple.com", tls_protocol_version_TLSv10, false, true, true, true); + sec_protocol_configuration_register_builtin_exception(dict, "geo.apple.com", tls_protocol_version_TLSv10, false, true, true, true); + sec_protocol_configuration_register_builtin_exception(dict, "is.autonavi.com", tls_protocol_version_TLSv10, false, true, true, true); + sec_protocol_configuration_register_builtin_exception(dict, "apple-mapkit.com", tls_protocol_version_TLSv10, false, true, true, true); + sec_protocol_configuration_register_builtin_exception(dict, "setup.icloud.com", tls_protocol_version_TLSv12, false, true, true, true); +} + +void +sec_protocol_configuration_populate_insecure_defaults(sec_protocol_configuration_t config) +{ + xpc_object_t dict = sec_protocol_configuration_get_map(config); + xpc_object_t domain_map = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_value(dict, kExceptionDomains, domain_map); + + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoadsInWebContent, true); + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoadsForMedia, true); + xpc_dictionary_set_bool(dict, kAllowsLocalNetworking, true); + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoads, true); +} + +void +sec_protocol_configuration_populate_secure_defaults(sec_protocol_configuration_t config) +{ + xpc_object_t dict = sec_protocol_configuration_get_map(config); + xpc_object_t domain_map = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_set_value(dict, kExceptionDomains, domain_map); + + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoadsInWebContent, false); + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoadsForMedia, false); + xpc_dictionary_set_bool(dict, kAllowsLocalNetworking, false); + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoads, false); +} + +bool +sec_protocol_configuration_set_ats_overrides(sec_protocol_configuration_t config, CFDictionaryRef plist) +{ + if (plist == NULL) { + return false; + } + +#define BOOLEAN_FOR_KEY(dictionary, key, value, default) \ + bool value = default; \ + { \ + NSNumber *nsValue = [dictionary valueForKey:[[NSString alloc] initWithFormat:@"%s", key]]; \ + if (nsValue) { \ + value = [nsValue boolValue]; \ + } \ + } +#define STRING_FOR_KEY(dictionary, key, value, default) \ + NSString *value = default; \ + { \ + NSString *nsValue = [dictionary valueForKey:[[NSString alloc] initWithFormat:@"%s", key]]; \ + if (nsValue) { \ + value = nsValue; \ + } \ + } + + xpc_object_t dict = sec_protocol_configuration_get_map(config); + if (dict == nil) { + return false; + } + + NSDictionary *plist_dictionary = (__bridge NSDictionary *)plist; + BOOLEAN_FOR_KEY(plist_dictionary, kAllowsArbitraryLoads, arbitrary_loads, false); + BOOLEAN_FOR_KEY(plist_dictionary, kAllowsArbitraryLoadsInWebContent, web_loads, false); + BOOLEAN_FOR_KEY(plist_dictionary, kAllowsArbitraryLoadsForMedia, media_loads, false); + BOOLEAN_FOR_KEY(plist_dictionary, kAllowsLocalNetworking, local_networking, false); + + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoads, arbitrary_loads); + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoadsInWebContent, web_loads); + xpc_dictionary_set_bool(dict, kAllowsArbitraryLoadsForMedia, media_loads); + xpc_dictionary_set_bool(dict, kAllowsLocalNetworking, local_networking); + + NSDictionary *exception_domains = [plist_dictionary valueForKey:[[NSString alloc] initWithFormat:@"%s", kExceptionDomains]]; + if (exception_domains == nil) { + return true; + } + + xpc_object_t domain_map = xpc_dictionary_get_dictionary(dict, kExceptionDomains); + if (domain_map == nil) { + // The domain map MUST be present during initialziation + return false; + } + + [exception_domains enumerateKeysAndObjectsUsingBlock:^(id _key, id _obj, BOOL *stop) { + NSString *domain = (NSString *)_key; + NSDictionary *entry = (NSDictionary *)_obj; + if (entry == nil) { + // Exception domains MUST have ATS information set. + *stop = YES; + } + + xpc_object_t entry_map = xpc_dictionary_create(NULL, NULL, 0); + + BOOLEAN_FOR_KEY(entry_map, kExceptionAllowsInsecureHTTPLoads, allows_http, false); + BOOLEAN_FOR_KEY(entry_map, kIncludesSubdomains, includes_subdomains, false); + BOOLEAN_FOR_KEY(entry_map, kExceptionRequiresForwardSecrecy, requires_pfs, false); + STRING_FOR_KEY(entry_map, kExceptionMinimumTLSVersion, minimum_tls, @"TLSv1.2"); + + xpc_dictionary_set_bool(entry_map, kIncludesSubdomains, includes_subdomains); + xpc_dictionary_set_bool(entry_map, kExceptionAllowsInsecureHTTPLoads, allows_http); + xpc_dictionary_set_bool(entry_map, kExceptionRequiresForwardSecrecy, requires_pfs); + xpc_dictionary_set_int64(entry_map, kExceptionMinimumTLSVersion, sec_protocol_configuration_protocol_string_to_version([minimum_tls cStringUsingEncoding:NSUTF8StringEncoding])); + xpc_dictionary_set_value(domain_map, [domain cStringUsingEncoding:NSUTF8StringEncoding], entry_map); + }]; + +#undef STRING_FOR_KEY +#undef BOOLEAN_FOR_KEY + + return true; +} diff --git a/protocol/SecProtocolConfigurationTest.m b/protocol/SecProtocolConfigurationTest.m new file mode 100644 index 00000000..ef0b8aac --- /dev/null +++ b/protocol/SecProtocolConfigurationTest.m @@ -0,0 +1,431 @@ +// +// SecProtocolConfigurationTest.m +// SecureTransportTests +// + +#import + +#include +#include +#include + +#import "SecProtocolConfiguration.h" +#import "SecProtocolPriv.h" +#import "SecProtocolInternal.h" + +#import // Needed for the mock protocol + +#define SEC_PROTOCOL_METADATA_VALIDATE(m, r) \ + if (((void *)(m) == NULL) || ((size_t)(m) == 0)) { \ + return (r); \ + } + +typedef struct mock_protocol { + struct nw_protocol protocol; + char *name; +} *mock_protocol_t; + +static nw_protocol_t +_mock_protocol_create_extended(nw_protocol_identifier_const_t identifier, + nw_endpoint_t endpoint, + nw_parameters_t parameters) +{ + mock_protocol_t handle = (mock_protocol_t)calloc(1, sizeof(struct mock_protocol)); + if (handle == NULL) { + return NULL; + } + + struct nw_protocol_callbacks *callbacks = (struct nw_protocol_callbacks *)malloc(sizeof(struct nw_protocol_callbacks)); + memset(callbacks, 0, sizeof(struct nw_protocol_callbacks)); + + handle->protocol.callbacks = callbacks; + handle->protocol.handle = (void *)handle; + + return &handle->protocol; +} + +static bool +mock_protocol_register_extended(nw_protocol_identifier_const_t identifier, + nw_protocol_create_extended_f create_extended_function) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static bool (*_nw_protocol_register_extended)(nw_protocol_identifier_const_t, nw_protocol_create_extended_f) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_register_extended = (__typeof(_nw_protocol_register_extended))dlsym(libnetworkImage, "nw_protocol_register_extended"); + if (NULL == _nw_protocol_register_extended) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_register_extended"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_register_extended == NULL) { + return false; + } + + return _nw_protocol_register_extended(identifier, create_extended_function); +} + +static nw_protocol_identifier_t +_mock_protocol_identifier(const char *name, size_t name_len) +{ + static struct nw_protocol_identifier mock_identifier = {}; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + memset(&mock_identifier, 0, sizeof(mock_identifier)); + + strlcpy((char *)mock_identifier.name, name, name_len); + + mock_identifier.level = nw_protocol_level_application; + mock_identifier.mapping = nw_protocol_mapping_one_to_one; + + mock_protocol_register_extended(&mock_identifier, _mock_protocol_create_extended); + }); + + return &mock_identifier; +} + +static void * _Nullable +mock_protocol_allocate_metadata(__unused nw_protocol_definition_t definition) +{ + return calloc(1, sizeof(struct sec_protocol_metadata_content)); +} + +static void +mock_protocol_deallocate_metadata(__unused nw_protocol_definition_t definition, void *metadata) +{ + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)metadata; + if (content) { + // pass + } + free(content); +} + +static void +mock_protocol_set_metadata_allocator(nw_protocol_definition_t definition, nw_protocol_definition_allocate_f allocator, nw_protocol_definition_deallocate_f deallocator) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static void (*_nw_protocol_definition_set_metadata_allocator)(nw_protocol_definition_t, nw_protocol_definition_allocate_f, nw_protocol_definition_deallocate_f) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_definition_set_metadata_allocator = (__typeof(_nw_protocol_definition_set_metadata_allocator))dlsym(libnetworkImage, "nw_protocol_definition_set_metadata_allocator"); + if (NULL == _nw_protocol_definition_set_metadata_allocator) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_definition_set_metadata_allocator"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_definition_set_metadata_allocator == NULL) { + return; + } + + _nw_protocol_definition_set_metadata_allocator(definition, allocator, deallocator); +} + +static void * _Nullable +mock_protocol_copy_options(__unused nw_protocol_definition_t definition, void *options) +{ + void *new_options = calloc(1, sizeof(struct sec_protocol_options_content)); + + sec_protocol_options_content_t copy = (sec_protocol_options_content_t)new_options; + sec_protocol_options_content_t original = (sec_protocol_options_content_t)options; + + copy->min_version = original->min_version; + copy->max_version = original->max_version; + copy->disable_sni = original->disable_sni; + copy->enable_fallback_attempt = original->enable_fallback_attempt; + copy->enable_false_start = original->enable_false_start; + copy->enable_tickets = original->enable_tickets; + copy->enable_sct = original->enable_sct; + copy->enable_ocsp = original->enable_ocsp; + copy->enable_resumption = original->enable_resumption; + copy->enable_renegotiation = original->enable_renegotiation; + copy->enable_early_data = original->enable_early_data; + + if (original->server_name) { + copy->server_name = strdup(original->server_name); + } + if (original->identity) { + copy->identity = original->identity; + } + if (original->application_protocols) { + copy->application_protocols = xpc_copy(original->application_protocols); + } + if (original->ciphersuites) { + copy->ciphersuites = xpc_copy(original->ciphersuites); + } + if (original->dh_params) { + copy->dh_params = original->dh_params; + } + if (original->key_update_block) { + copy->key_update_block = original->key_update_block; + copy->key_update_queue = original->key_update_queue; + } + if (original->challenge_block) { + copy->challenge_block = original->challenge_block; + copy->challenge_queue = original->challenge_queue; + } + if (original->verify_block) { + copy->verify_block = original->verify_block; + copy->verify_queue = original->verify_queue; + } + if (original->session_state) { + copy->session_state = original->session_state; + } + if (original->session_update_block) { + copy->session_update_block = original->session_update_block; + copy->session_update_queue = original->session_update_queue; + } + if (original->pre_shared_keys) { + copy->pre_shared_keys = xpc_copy(original->pre_shared_keys); + } + + return new_options; +} + +static void * _Nullable +mock_protocol_allocate_options(__unused nw_protocol_definition_t definition) +{ + return calloc(1, sizeof(struct sec_protocol_options_content)); +} + +static void +mock_protocol_deallocate_options(__unused nw_protocol_definition_t definition, void *options) +{ + sec_protocol_options_content_t content = (sec_protocol_options_content_t)options; + if (content) { + // pass + } + free(content); +} + +static void +mock_protocol_set_options_allocator(nw_protocol_definition_t definition, + nw_protocol_definition_allocate_f allocate_function, + nw_protocol_definition_copy_f copy_function, + nw_protocol_definition_deallocate_f deallocate_function) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static void (*_nw_protocol_definition_set_options_allocator)(nw_protocol_definition_t, nw_protocol_definition_allocate_f, nw_protocol_definition_copy_f, nw_protocol_definition_deallocate_f) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_definition_set_options_allocator = (__typeof(_nw_protocol_definition_set_options_allocator))dlsym(libnetworkImage, "nw_protocol_definition_set_options_allocator"); + if (NULL == _nw_protocol_definition_set_options_allocator) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_definition_set_options_allocator"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_definition_set_options_allocator == NULL) { + return; + } + + _nw_protocol_definition_set_options_allocator(definition, allocate_function, copy_function, deallocate_function); +} + +static nw_protocol_definition_t +mock_protocol_definition_create_with_identifier(nw_protocol_identifier_const_t identifier) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static nw_protocol_definition_t (*_nw_protocol_definition_create_with_identifier)(nw_protocol_identifier_const_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_definition_create_with_identifier = (__typeof(_nw_protocol_definition_create_with_identifier))dlsym(libnetworkImage, "nw_protocol_definition_create_with_identifier"); + if (NULL == _nw_protocol_definition_create_with_identifier) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_definition_create_with_identifier"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_definition_create_with_identifier == NULL) { + return NULL; + } + + return _nw_protocol_definition_create_with_identifier(identifier); +} + +static nw_protocol_definition_t +mock_protocol_copy_definition(void) +{ + static nw_protocol_definition_t definition = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + const char *mock_protocol_name = "SecProtocolConfigTestMock"; + definition = mock_protocol_definition_create_with_identifier(_mock_protocol_identifier(mock_protocol_name, strlen(mock_protocol_name))); + mock_protocol_set_options_allocator(definition, + mock_protocol_allocate_options, + mock_protocol_copy_options, + mock_protocol_deallocate_options); + mock_protocol_set_metadata_allocator(definition, + mock_protocol_allocate_metadata, + mock_protocol_deallocate_metadata); + + }); + + return definition; +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +static SSLProtocol +protocol_string_to_version(const char *protocol) +{ + if (protocol == NULL) { + return kSSLProtocolUnknown; + } + + const char *tlsv10 = "TLSv1.0"; + const char *tlsv11 = "TLSv1.1"; + const char *tlsv12 = "TLSv1.2"; + const char *tlsv13 = "TLSv1.3"; + + if (strlen(protocol) == strlen(tlsv10) && strncmp(protocol, tlsv10, strlen(protocol)) == 0) { + return kTLSProtocol1; + } else if (strlen(protocol) == strlen(tlsv11) && strncmp(protocol, tlsv11, strlen(protocol)) == 0) { + return kTLSProtocol11; + } else if (strlen(protocol) == strlen(tlsv12) && strncmp(protocol, tlsv12, strlen(protocol)) == 0) { + return kTLSProtocol12; + } else if (strlen(protocol) == strlen(tlsv13) && strncmp(protocol, tlsv13, strlen(protocol)) == 0) { + return kTLSProtocol13; + } + + return kSSLProtocolUnknown; +} +#pragma clang diagnostic pop + +@interface SecProtocolConfigurationTest : XCTestCase +@end + +@implementation SecProtocolConfigurationTest + +- (void)setUp { +} + +- (void)tearDown { +} + +- (sec_protocol_options_t)create_sec_protocol_options { + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + + static sec_protocol_options_t (*_nw_protocol_create_options)(nw_protocol_definition_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_create_options = (__typeof(_nw_protocol_create_options))dlsym(libnetworkImage, "nw_protocol_create_options"); + if (NULL == _nw_protocol_create_options) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork _nw_protocol_create_options"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_create_options == NULL) { + return nil; + } + + return (sec_protocol_options_t)_nw_protocol_create_options(mock_protocol_copy_definition()); +} + +- (void)testExampleFile:(NSURL *)path +{ + NSDictionary *dictionary = [[NSDictionary alloc] init]; + sec_protocol_configuration_builder_t builder = sec_protocol_configuration_builder_create((__bridge CFDictionaryRef)dictionary, true); + sec_protocol_configuration_t configuration = sec_protocol_configuration_create_with_builder(builder); + XCTAssertTrue(configuration != nil, @"failed to build configuration"); + if (!configuration) { + return; + } + + NSData *exampleData = [[NSData alloc] initWithContentsOfURL:path]; + NSDictionary *exampleATS = [NSJSONSerialization JSONObjectWithData:exampleData options:kNilOptions error:nil]; + XCTAssertNotNil(exampleATS, @"Loading %@ failed", path); + if (!exampleATS) { + return; + } + + [exampleATS enumerateKeysAndObjectsUsingBlock:^(id _key, id _obj, BOOL *stop) { + NSString *key = (NSString *)_key; + if ([key isEqualToString:@"NSExceptionDomains"]) { + NSDictionary *domain_map = (NSDictionary *)_obj; + [domain_map enumerateKeysAndObjectsUsingBlock:^(id _domain, id _domain_entry, BOOL *_domain_stop) { + NSString *domain = (NSString *)_domain; + NSDictionary *entry = (NSDictionary *)_domain_entry; + +#define BOOLEAN_FOR_KEY(key, value, default) \ + bool value = default; \ + { \ + NSNumber *nsValue = [entry valueForKey:key]; \ + if (nsValue) { \ + value = [nsValue boolValue]; \ + } \ + } +#define STRING_FOR_KEY(key, value, default) \ + NSString *value = default; \ + { \ + NSString *nsValue = [entry valueForKey:key]; \ + if (nsValue) { \ + value = nsValue; \ + } \ + } + BOOLEAN_FOR_KEY(@"NSExceptionAllowsInsecureHTTPLoads", allows_http, false); + BOOLEAN_FOR_KEY(@"NSIncludesSubdomains", includes_subdomains, false); + BOOLEAN_FOR_KEY(@"NSExceptionRequiresForwardSecrecy", requires_pfs, false); + STRING_FOR_KEY(@"NSExceptionMinimumTLSVersion", minimum_tls, @"TLSv1.2"); +#undef STRING_FOR_KEY +#undef BOOLEAN_FOR_KEY + + SSLProtocol minimum_protocol_version = protocol_string_to_version([minimum_tls cStringUsingEncoding:NSUTF8StringEncoding]); + + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_options_t transformed = sec_protocol_configuration_copy_transformed_options_for_host(configuration, options, [domain cStringUsingEncoding:NSUTF8StringEncoding]); + sec_protocol_options_access_handle(transformed, ^bool(void *handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + + XCTAssertTrue(content->ats_required == true); + XCTAssertTrue(content->min_version == minimum_protocol_version); + if (requires_pfs) { + XCTAssertTrue(content->ciphersuites != nil); + } else { + XCTAssertTrue(content->ciphersuites == nil); + } + }); + + XCTAssertTrue(allows_http != sec_protocol_configuration_tls_required_for_host(configuration, [domain cStringUsingEncoding:NSUTF8StringEncoding])); + }]; + } + }]; +} + +- (void)testExampleATSDictionaries { + NSArray * testFiles = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".json" subdirectory:@"."]; + [testFiles enumerateObjectsUsingBlock:^(NSURL* _Nonnull path, __unused NSUInteger idx, BOOL * _Nonnull stop) { + [self testExampleFile:path]; + }]; +} + +@end diff --git a/protocol/SecProtocolHelper.m b/protocol/SecProtocolHelper.m new file mode 100644 index 00000000..307ea379 --- /dev/null +++ b/protocol/SecProtocolHelper.m @@ -0,0 +1,339 @@ +// +// SecProtocolHelper.m +// Security_ios +// +// + +#import "SecProtocolInternal.h" + +#define DefineTLSCiphersuiteGroupList(XXX, ...) \ + static const tls_ciphersuite_t List##XXX[] = { \ + __VA_ARGS__ \ + }; + +DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_default, + CiphersuitesTLS13, + CiphersuitesPFS); +DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_compatibility, + CiphersuitesNonPFS, + CiphersuitesTLS10, + CiphersuitesTLS10_3DES); +DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_legacy, + CiphersuitesDHE); +DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_ats, + CiphersuitesTLS13, + CiphersuitesPFS); +DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_ats_compatibility, + CiphersuitesNonPFS); + +typedef struct tls_ciphersuite_definition { + tls_ciphersuite_t ciphersuite; + tls_protocol_version_t min_version; + tls_protocol_version_t 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, tls_protocol_version_TLSv13, tls_protocol_version_TLSv13), + DefineTLSCiphersuiteDefinition(TLS_AES_256_GCM_SHA384, tls_protocol_version_TLSv13, tls_protocol_version_TLSv13), + DefineTLSCiphersuiteDefinition(TLS_CHACHA20_POLY1305_SHA256, tls_protocol_version_TLSv13, tls_protocol_version_TLSv13), + + // RFC 7905: ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS) + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + + // 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, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + + // RFC 5288: AES Galois Counter Mode (GCM) Cipher Suites for TLS + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + + // RFC 5246: The Transport Layer Security (TLS) Protocol Version 1.2 + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(SSL_RSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, tls_protocol_version_TLSv12, tls_protocol_version_TLSv12), + + // RFC 4492: Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + + // RFC 3268: Advanced Encryption Standard (AES) Ciphersuites for Transport Layer Security (TLS) + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), + DefineTLSCiphersuiteDefinition(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, tls_protocol_version_TLSv10, tls_protocol_version_TLSv11), +}; + +// 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 tls_ciphersuite_t * +sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(tls_ciphersuite_group_t group, size_t *list_count) +{ + if (list_count == NULL) { + return NULL; + } + + const tls_ciphersuite_t *ciphersuites = NULL; + size_t count = 0; + +#define CASE_CONFIG(GROUPNAME) \ + case GROUPNAME: \ + ciphersuites = List##GROUPNAME; \ + count = sizeof(List##GROUPNAME) / sizeof(tls_ciphersuite_t); \ + break; + + switch (group) { + CASE_CONFIG(tls_ciphersuite_group_default); + CASE_CONFIG(tls_ciphersuite_group_compatibility); + CASE_CONFIG(tls_ciphersuite_group_legacy); + CASE_CONFIG(tls_ciphersuite_group_ats); + CASE_CONFIG(tls_ciphersuite_group_ats_compatibility); + } + +#undef CASE_CONFIG + + if (ciphersuites != NULL) { + *list_count = count; + return ciphersuites; + } + + *list_count = 0; + return NULL; +} + +bool +sec_protocol_helper_ciphersuite_group_contains_ciphersuite(tls_ciphersuite_group_t group, tls_ciphersuite_t suite) +{ + size_t list_size = 0; + const tls_ciphersuite_t *list = sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(group, &list_size); + if (list == NULL) { + return false; + } + + for (size_t i = 0; i < list_size; i++) { + tls_ciphersuite_t other = list[i]; + if (other == suite) { + return true; + } + } + + return false; +} + +tls_protocol_version_t +sec_protocol_helper_ciphersuite_minimum_TLS_version(tls_ciphersuite_t 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 0; +} + +tls_protocol_version_t +sec_protocol_helper_ciphersuite_maximum_TLS_version(tls_ciphersuite_t 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 0; +} + +const char * +sec_protocol_helper_get_ciphersuite_name(tls_ciphersuite_t ciphersuite) +{ +#define CIPHERSUITE_TO_NAME(ciphersuite) \ + case ciphersuite: { \ + return #ciphersuite; \ + } + + switch (ciphersuite) { + CIPHERSUITE_TO_NAME(TLS_AES_128_GCM_SHA256); + CIPHERSUITE_TO_NAME(TLS_AES_256_GCM_SHA384); + CIPHERSUITE_TO_NAME(TLS_CHACHA20_POLY1305_SHA256); + CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_256_GCM_SHA384); + CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_128_GCM_SHA256); + CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_256_CBC_SHA256); + CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_128_CBC_SHA256); + CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_256_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_RSA_WITH_AES_128_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA); + CIPHERSUITE_TO_NAME(SSL_RSA_WITH_3DES_EDE_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384); + CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256); + CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256); + CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256); + CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_256_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_DHE_RSA_WITH_AES_128_CBC_SHA); + CIPHERSUITE_TO_NAME(SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256); + CIPHERSUITE_TO_NAME(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256); + CIPHERSUITE_TO_NAME(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256); + } + +#undef CIPHERSUITE_TO_NAME + return NULL; +} + +#define KeyExchangeGroupsDefault \ + tls_key_exchange_group_X25519, \ + tls_key_exchange_group_X448 +#define KeyExchangeGroupsCompatibility \ + tls_key_exchange_group_Secp256r1, \ + tls_key_exchange_group_Secp384r1, \ + tls_key_exchange_group_Secp521r1 +#define KeyExchangeGroupsLegacy \ + tls_key_exchange_group_FFDHE2048, \ + tls_key_exchange_group_FFDHE3072, \ + tls_key_exchange_group_FFDHE4096, \ + tls_key_exchange_group_FFDHE6144, \ + tls_key_exchange_group_FFDHE8192 + +#define DefineTLSKeyExchangeGroupList(XXX, ...) \ + static const tls_key_exchange_group_t List##XXX[] = { \ + __VA_ARGS__ \ + }; + +DefineTLSKeyExchangeGroupList(tls_key_exchange_group_set_default, + KeyExchangeGroupsDefault); +DefineTLSKeyExchangeGroupList(tls_key_exchange_group_set_compatibility, + KeyExchangeGroupsCompatibility); +DefineTLSKeyExchangeGroupList(tls_key_exchange_group_set_legacy, + KeyExchangeGroupsLegacy); + +const tls_key_exchange_group_t * +sec_protocol_helper_tls_key_exchange_group_set_to_key_exchange_group_list(tls_key_exchange_group_set_t set, size_t *listSize) +{ + if (listSize == NULL) { + return NULL; + } + + const tls_key_exchange_group_t *groups = NULL; + size_t count = 0; + +#define CASE_CONFIG(SETNAME) \ +case SETNAME: \ +groups = List##SETNAME; \ +count = sizeof(List##SETNAME) / sizeof(SSLKeyExchangeGroup); \ +break; + + switch (set) { + CASE_CONFIG(tls_key_exchange_group_set_default); + CASE_CONFIG(tls_key_exchange_group_set_compatibility); + CASE_CONFIG(tls_key_exchange_group_set_legacy); + } + +#undef CASE_CONFIG + + if (groups != NULL) { + *listSize = count; + return groups; + } + + *listSize = 0; + return NULL; +} + +#undef DefineTLSKeyExchangeGroupList +#undef KeyExchangeGroupsDefault +#undef KeyExchangeGroupsCompatibility +#undef KeyExchangeGroupsLegacy + +bool +sec_protocol_helper_dispatch_data_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 is_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) { + is_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 is_equal; + }); + return is_equal; + }); + return is_equal; +} diff --git a/protocol/SecProtocolHelperTest.m b/protocol/SecProtocolHelperTest.m new file mode 100644 index 00000000..6b5439ca --- /dev/null +++ b/protocol/SecProtocolHelperTest.m @@ -0,0 +1,35 @@ +// +// SecProtocolHelperTest.m +// SecProtocol +// + +#import + +#import "SecProtocolInternal.h" + +#define DefineTLSCiphersuiteGroupList(XXX, ...) \ + static const tls_ciphersuite_t list_##XXX[] = { \ + __VA_ARGS__ \ + }; + +// Mirror the internal definition of this ciphersuite group +DefineTLSCiphersuiteGroupList(tls_ciphersuite_group_default, CiphersuitesTLS13, CiphersuitesPFS); + +#undef DefineTLSCiphersuiteGroupList + +@interface SecProtocolHelperTest : XCTestCase +@end + +@implementation SecProtocolHelperTest + +- (void)testCiphersuiteGroupConversion { + size_t ciphersuites_len = 0; + const tls_ciphersuite_t *ciphersuites = sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(tls_ciphersuite_group_default, &ciphersuites_len); + XCTAssertTrue(ciphersuites != NULL); + XCTAssertTrue(ciphersuites_len == (sizeof(list_tls_ciphersuite_group_default) / sizeof(tls_ciphersuite_t))); + for (size_t i = 0; i < ciphersuites_len; i++) { + XCTAssertTrue(ciphersuites[i] == list_tls_ciphersuite_group_default[i]); + } +} + +@end diff --git a/protocol/SecProtocolInternal.h b/protocol/SecProtocolInternal.h new file mode 100644 index 00000000..97fd5c0e --- /dev/null +++ b/protocol/SecProtocolInternal.h @@ -0,0 +1,135 @@ +// +// SecProtocolInternal.h +// Security +// + +#ifndef SecProtocolInternal_h +#define SecProtocolInternal_h + +#include "SecProtocolPriv.h" + +#define kATSInfoKey "NSAppTransportSecurity" +#define kAllowsArbitraryLoads "NSAllowsArbitraryLoads" +#define kAllowsArbitraryLoadsForMedia "NSAllowsArbitraryLoadsForMedia" +#define kAllowsArbitraryLoadsInWebContent "NSAllowsArbitraryLoadsInWebContent" +#define kAllowsLocalNetworking "NSAllowsLocalNetworking" +#define kExceptionDomains "NSExceptionDomains" +#define kIncludesSubdomains "NSIncludesSubdomains" +#define kExceptionAllowsInsecureHTTPLoads "NSExceptionAllowsInsecureHTTPLoads" +#define kExceptionMinimumTLSVersion "NSExceptionMinimumTLSVersion" +#define kExceptionRequiresForwardSecrecy "NSExceptionRequiresForwardSecrecy" + +#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 + +SEC_RETURNS_RETAINED sec_protocol_configuration_builder_t +sec_protocol_configuration_builder_copy_default(void); + +CFDictionaryRef +sec_protocol_configuration_builder_get_ats_dictionary(sec_protocol_configuration_builder_t builder); + +bool +sec_protocol_configuration_builder_get_is_apple_bundle(sec_protocol_configuration_builder_t builder); + +SEC_RETURNS_RETAINED xpc_object_t +sec_protocol_configuration_get_map(sec_protocol_configuration_t configuration); + +void +sec_protocol_options_clear_tls_ciphersuites(sec_protocol_options_t options); + +void +sec_protocol_options_set_ats_non_pfs_ciphersuite_allowed(sec_protocol_options_t options, bool ats_non_pfs_ciphersuite_allowed); + +void +sec_protocol_options_set_ats_minimum_tls_version_allowed(sec_protocol_options_t options, bool ats_minimum_tls_version_allowed); + +void +sec_protocol_options_set_ats_required(sec_protocol_options_t options, bool required); + +void +sec_protocol_options_set_minimum_rsa_key_size(sec_protocol_options_t options, size_t minimum_key_size); + +void +sec_protocol_options_set_minimum_ecdsa_key_size(sec_protocol_options_t options, size_t minimum_key_size); + +void +sec_protocol_options_set_minimum_signature_algorithm(sec_protocol_options_t options, SecSignatureHashAlgorithm algorithm); + +void +sec_protocol_options_set_trusted_peer_certificate(sec_protocol_options_t options, bool trusted_peer_certificate); + +void +sec_protocol_configuration_populate_insecure_defaults(sec_protocol_configuration_t configuration); + +void +sec_protocol_configuration_populate_secure_defaults(sec_protocol_configuration_t configuration); + +void +sec_protocol_configuration_register_builtin_exceptions(sec_protocol_configuration_t configuration); + +bool +sec_protocol_helper_ciphersuite_group_contains_ciphersuite(tls_ciphersuite_group_t group, tls_ciphersuite_t suite); + +tls_protocol_version_t +sec_protocol_helper_ciphersuite_minimum_TLS_version(tls_ciphersuite_t ciphersuite); + +tls_protocol_version_t +sec_protocol_helper_ciphersuite_maximum_TLS_version(tls_ciphersuite_t ciphersuite); + +const char * +sec_protocol_helper_get_ciphersuite_name(tls_ciphersuite_t ciphersuite); + +const tls_key_exchange_group_t * +sec_protocol_helper_tls_key_exchange_group_set_to_key_exchange_group_list(tls_key_exchange_group_set_t set, size_t *listSize); + +bool sec_protocol_helper_dispatch_data_equal(dispatch_data_t left, dispatch_data_t right); + +#endif /* SecProtocolInternal_h */ diff --git a/protocol/SecProtocolMetadata.h b/protocol/SecProtocolMetadata.h index 11d69193..3a67ddb3 100644 --- a/protocol/SecProtocolMetadata.h +++ b/protocol/SecProtocolMetadata.h @@ -26,8 +26,7 @@ #include #include -#include -#include +#include #include #include @@ -94,6 +93,21 @@ 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_tls_protocol_version + * + * @abstract + * Get the negotiated TLS version. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A `tls_protocol_version_t` value. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +tls_protocol_version_t +sec_protocol_metadata_get_negotiated_tls_protocol_version(sec_protocol_metadata_t metadata); + /*! * @function sec_protocol_metadata_get_negotiated_protocol_version * @@ -105,10 +119,26 @@ sec_protocol_metadata_copy_peer_public_key(sec_protocol_metadata_t metadata); * * @return A SSLProtocol enum of the TLS version. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_DEPRECATED_WITH_REPLACEMENT("sec_protocol_metadata_get_negotiated_tls_protocol_version", + macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) SSLProtocol sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t metadata); +/*! + * @function sec_protocol_metadata_get_negotiated_tls_ciphersuite + * + * @abstract + * Get the negotiated TLS ciphersuite. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A `tls_ciphersuite_t`. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +tls_ciphersuite_t +sec_protocol_metadata_get_negotiated_tls_ciphersuite(sec_protocol_metadata_t metadata); + /*! * @function sec_protocol_metadata_get_negotiated_ciphersuite * @@ -120,7 +150,9 @@ sec_protocol_metadata_get_negotiated_protocol_version(sec_protocol_metadata_t me * * @return A SSLCipherSuite. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_DEPRECATED_WITH_REPLACEMENT("sec_protocol_metadata_get_negotiated_tls_ciphersuite", + macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) +API_UNAVAILABLE(iosmac) SSLCipherSuite sec_protocol_metadata_get_negotiated_ciphersuite(sec_protocol_metadata_t metadata); @@ -216,8 +248,45 @@ 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)); + +/*! + * @function sec_protocol_metadata_access_pre_shared_keys + * + * @abstract + * Get the PSKs supported by the local instance. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param handler + * A block to invoke one or more times with tuples of dispatch_data_t objects carrying PSKs and their corresponding identities. + * + * @return Returns true if the PSKs were accessible, false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_metadata_access_pre_shared_keys(sec_protocol_metadata_t metadata, void (^handler)(dispatch_data_t psk, dispatch_data_t psk_identity)); + #endif // __BLOCKS__ +/*! + * @function sec_protocol_metadata_get_server_name + * + * @abstract + * Obtain the server name offered by a client or server during + * connection establishmet. This is the value commonly carried + * in the TLS SNI extesion. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Returns A NULL-terminated string carrying the server name, or NULL + * if none was provided. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +const char * _Nullable +sec_protocol_metadata_get_server_name(sec_protocol_metadata_t metadata); + /*! * @function sec_protocol_metadata_peers_are_equal * diff --git a/protocol/SecProtocolOptions.h b/protocol/SecProtocolOptions.h index 7770ba87..616dac53 100644 --- a/protocol/SecProtocolOptions.h +++ b/protocol/SecProtocolOptions.h @@ -25,12 +25,11 @@ #define SecProtocolOptions_h #include -#include -#include +#include +#include #include #include #include -#include #include #include @@ -68,6 +67,24 @@ __BEGIN_DECLS SEC_ASSUME_NONNULL_BEGIN +/*! + * @function sec_protocol_options_are_equal + * + * @abstract + * Compare two `sec_protocol_options_t` instances. + * + * @param optionsA + * A `sec_protocol_options_t` instance. + * + * @param optionsB + * A `sec_protocol_options_t` instance. + * + * @return True if equal, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_options_are_equal(sec_protocol_options_t optionsA, sec_protocol_options_t optionsB); + /*! * @function sec_protocol_options_set_local_identity * @@ -84,6 +101,22 @@ 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_append_tls_ciphersuite + * + * @abstract + * Append a TLS ciphersuite to the set of enabled ciphersuites. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param ciphersuite + * A `tls_ciphersuite_t` value. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_append_tls_ciphersuite(sec_protocol_options_t options, tls_ciphersuite_t ciphersuite); + /*! * @function sec_protocol_options_add_tls_ciphersuite * @@ -96,10 +129,27 @@ sec_protocol_options_set_local_identity(sec_protocol_options_t options, sec_iden * @param ciphersuite * A SSLCipherSuite value. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_DEPRECATED("Use sec_protocol_options_append_tls_ciphersuite", macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) +API_UNAVAILABLE(iosmac) void sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCipherSuite ciphersuite); +/*! + * @function sec_protocol_options_append_tls_ciphersuite_group + * + * @abstract + * Append 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.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_append_tls_ciphersuite_group(sec_protocol_options_t options, tls_ciphersuite_group_t group); + /*! * @function sec_protocol_options_add_tls_ciphersuite_group * @@ -112,7 +162,8 @@ sec_protocol_options_add_tls_ciphersuite(sec_protocol_options_t options, SSLCiph * @param group * A SSLCipherSuiteGroup value. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_DEPRECATED("Use sec_protocol_options_append_tls_ciphersuite_group", macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) +API_UNAVAILABLE(iosmac) void sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, SSLCiphersuiteGroup group); @@ -128,10 +179,52 @@ sec_protocol_options_add_tls_ciphersuite_group(sec_protocol_options_t options, S * @param version * A SSLProtocol enum value. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_DEPRECATED_WITH_REPLACEMENT("sec_protocol_options_set_min_tls_protocol_version", + macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) +API_UNAVAILABLE(iosmac) void sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProtocol version); +/*! + * @function sec_protocol_options_set_min_tls_protocol_version + * + * @abstract + * Set the minimum support TLS version. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param version + * A tls_protocol_version_t enum value. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_min_tls_protocol_version(sec_protocol_options_t options, tls_protocol_version_t version); + +/*! + * @function sec_protocol_options_get_default_min_tls_protocol_version + * + * @abstract + * Get the system default minimum TLS protocol version. + * + * @return The default minimum TLS version. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +tls_protocol_version_t +sec_protocol_options_get_default_min_tls_protocol_version(void); + +/*! + * @function sec_protocol_options_get_default_min_dtls_protocol_version + * + * @abstract + * Get the system default minimum DTLS protocol version. + * + * @return The default minimum DTLS version. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +tls_protocol_version_t +sec_protocol_options_get_default_min_dtls_protocol_version(void); + /*! * @function sec_protocol_options_set_tls_max_version * @@ -144,10 +237,52 @@ sec_protocol_options_set_tls_min_version(sec_protocol_options_t options, SSLProt * @param version * A SSLProtocol enum value. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_DEPRECATED_WITH_REPLACEMENT("sec_protocol_options_set_max_tls_protocol_version", + macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) +API_UNAVAILABLE(iosmac) void sec_protocol_options_set_tls_max_version(sec_protocol_options_t options, SSLProtocol version); +/*! + * @function sec_protocol_options_set_max_tls_protocol_version + * + * @abstract + * Set the maximum support TLS version. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param version + * A tls_protocol_version_t enum value. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_max_tls_protocol_version(sec_protocol_options_t options, tls_protocol_version_t version); + +/*! + * @function sec_protocol_options_get_default_max_tls_protocol_version + * + * @abstract + * Get the system default maximum TLS protocol version. + * + * @return The default maximum TLS version. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +tls_protocol_version_t +sec_protocol_options_get_default_max_tls_protocol_version(void); + +/*! + * @function sec_protocol_options_get_default_max_tls_protocol_version + * + * @abstract + * Get the system default maximum DTLS protocol version. + * + * @return The default maximum DTLS version. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +tls_protocol_version_t +sec_protocol_options_get_default_max_dtls_protocol_version(void); + /*! * @function sec_protocol_options_add_tls_application_protocol * @@ -193,7 +328,7 @@ sec_protocol_options_set_tls_server_name(sec_protocol_options_t options, const c * @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)) +API_DEPRECATED("DHE ciphersuites are no longer supported", macos(10.14, 10.15), ios(12.0, 13.0), watchos(5.0, 6.0), tvos(12.0, 13.0)) void sec_protocol_options_set_tls_diffie_hellman_parameters(sec_protocol_options_t options, dispatch_data_t params); @@ -216,6 +351,74 @@ 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_pre_shared_key_identity_hint + * + * @abstract + * Set the PSK identity hint to use by servers when negotiating a PSK ciphersuite. + * See https://tools.ietf.org/html/rfc4279 for more details. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param psk_identity_hint + * A dispatch_data_t containing a PSK identity hint. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_tls_pre_shared_key_identity_hint(sec_protocol_options_t options, dispatch_data_t psk_identity_hint); + +#ifdef __BLOCKS__ + +/*! + * @block sec_protocol_pre_shared_key_selection_complete_t + * + * @abstract + * Block to be invoked when a PSK selection event is complete and a PSK identity is chosen. + * + * @param psk_identity + * A `dispatch_data_t` instance carrying the chosen PSK identity, or nil if one does not match. + */ +typedef void (^sec_protocol_pre_shared_key_selection_complete_t)(dispatch_data_t _Nullable psk_identity); + +/*! + * @block sec_protocol_pre_shared_key_selection_t + * + * @abstract + * Block to be invoked when the client must choose a PSK identity given a hint from its peer. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param psk_identity_hint + * A `dispatch_data_t` object carrying the peer's (optional) PSK identity hint. + * + * @param complete + * A `sec_protocol_pre_shared_key_selection_complete_t` block to be invoked when PSK selection is complete. + */ +typedef void (^sec_protocol_pre_shared_key_selection_t)(sec_protocol_metadata_t metadata, dispatch_data_t _Nullable psk_identity_hint, sec_protocol_pre_shared_key_selection_complete_t complete); + +/*! + * @function sec_protocol_options_set_pre_shared_key_selection_block + * + * @abstract + * Set the PSK selection block. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param psk_selection_block + * A `sec_protocol_pre_shared_key_selection_t` block. + * + * @params psk_selection_queue + * A `dispatch_queue_t` on which the PSK selection block should be called. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_pre_shared_key_selection_block(sec_protocol_options_t options, sec_protocol_pre_shared_key_selection_t psk_selection_block, dispatch_queue_t psk_selection_queue); + +#endif // __BLOCKS__ + /*! * @function sec_protocol_options_set_tls_tickets_enabled * @@ -380,10 +583,13 @@ typedef void (^sec_protocol_key_update_t)(sec_protocol_metadata_t metadata, sec_ * @abstract * Block to be invoked when an identity (authentication) challenge is complete. * + * Note: prior to macOS 10.15, iOS 13.0, watchOS 6.0, and tvOS 13.0, calling this + * block with a NULL `identity` argument was prohibited. + * * @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); +typedef void (^sec_protocol_challenge_complete_t)(sec_identity_t __nullable identity); /*! * @block sec_protocol_challenge_t diff --git a/protocol/SecProtocolPriv.h b/protocol/SecProtocolPriv.h index 77aff1a3..0101c43f 100644 --- a/protocol/SecProtocolPriv.h +++ b/protocol/SecProtocolPriv.h @@ -8,81 +8,58 @@ #include #include +#include +#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; +#include - 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 +__BEGIN_DECLS - 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; +/* See: https://tools.ietf.org/html/rfc8446#section-4.2.7 */ +typedef CF_ENUM(uint16_t, tls_key_exchange_group_t) { + tls_key_exchange_group_Secp256r1 = 0x0017, + tls_key_exchange_group_Secp384r1 = 0x0018, + tls_key_exchange_group_Secp521r1 = 0x0019, + tls_key_exchange_group_X25519 = 0x001D, + tls_key_exchange_group_X448 = 0x001E, + tls_key_exchange_group_FFDHE2048 = 0x0100, + tls_key_exchange_group_FFDHE3072 = 0x0101, + tls_key_exchange_group_FFDHE4096 = 0x0102, + tls_key_exchange_group_FFDHE6144 = 0x0103, + tls_key_exchange_group_FFDHE8192 = 0x0104, +}; -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); +/* + * Convenience key exchange groups that collate group identifiers of + * comparable security into a single alias. + */ +typedef CF_ENUM(uint16_t, tls_key_exchange_group_set_t) { + tls_key_exchange_group_set_default, + tls_key_exchange_group_set_compatibility, + tls_key_exchange_group_set_legacy, +}; -typedef struct sec_protocol_metadata_content { - void *peer_certificate_chain; // sec_array_t of sec_certificate_t - void *peer_public_key; // dispatch_data_t +SEC_ASSUME_NONNULL_BEGIN - const char *negotiated_protocol; +#ifndef SEC_OBJECT_IMPL +SEC_OBJECT_DECL(sec_array); +#endif // !SEC_OBJECT_IMPL - SSLProtocol negotiated_protocol_version; - SSLCipherSuite negotiated_ciphersuite; +struct sec_protocol_options_content; +typedef struct sec_protocol_options_content *sec_protocol_options_content_t; - 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 +struct sec_protocol_metadata_content; +typedef struct sec_protocol_metadata_content *sec_protocol_metadata_content_t; - 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. +typedef void (^sec_protocol_tls_handshake_message_handler_t)(uint8_t type, dispatch_data_t message); - 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; +typedef dispatch_data_t _Nullable (*sec_protocol_metadata_exporter)(void * handle, size_t label_len, const char *label, + size_t context_len, const uint8_t * __nullable context, size_t exporter_len); - // Struct padding - unsigned __pad_bits : 2; -} *sec_protocol_metadata_content_t; +typedef dispatch_data_t _Nullable (*sec_protocol_metadata_session_exporter)(void *handle); -#ifndef SEC_OBJECT_IMPL -SEC_OBJECT_DECL(sec_array); -#endif // !SEC_OBJECT_IMPL +typedef bool (^sec_access_block_t)(void *handle); API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) SEC_RETURNS_RETAINED sec_array_t @@ -96,246 +73,1178 @@ 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 + * @function sec_protocol_options_access_handle * - * @param metadata - * A valid `sec_protocol_metadata_t` instance. + * @abstract + * Access the internal handle of a `sec_protocol_options` object. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param access_block + * A block to invoke with access to the internal handle. * - * @param extension_type - * The 2-byte identifier for the extension. + * @return True if the access was successful + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_options_access_handle(sec_protocol_options_t options, sec_access_block_t access_block); + +/*! + * @function sec_protocol_options_contents_are_equal * - * @param data - * Pointer to a uint8_t buffer where the encoded extension data is located. + * @abstract + * Compare two `sec_protocol_options_content_t` structs for equality. + * + * @param contentA + * A `sec_protocol_options_t` instance. * - * @param data_length - * Pointer to a variable containing the data length. This should be set to the size of the `data` buffer. + * @param contentB + * A `sec_protocol_options_t` instance. * - * @param error - * Pointer to a return error code that's populated in the event of an error. + * @return True if equal, and false otherwise. */ -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); +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_options_contents_are_equal(sec_protocol_options_content_t contentA, sec_protocol_options_content_t contentB); /*! - * @block sec_protocol_tls_ext_free_callback + * @function sec_protocol_options_set_tls_early_data_enabled * - * @param metadata - * A valid `sec_protocol_metadata_t` instance. + * @abstract + * Enable or disable early (0-RTT) data for TLS. * - * @param extension_type - * The 2-byte identifier for the extension. + * @param options + * A `sec_protocol_options_t` instance. * - * @param data - * Pointer to a uint8_t buffer where the encoded extension data is located. + * @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)) -typedef void (^sec_protocol_tls_ext_free_callback)(sec_protocol_metadata_t metadata, uint16_t extension_type, - const uint8_t *data); +void +sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled); /*! - * @block sec_protocol_tls_ext_parse_callback + * @function sec_protocol_options_set_tls_sni_disabled * - * @param metadata - * A valid `sec_protocol_metadata_t` handle. + * @abstract + * Enable or disable the TLS SNI extension. This defaults to `false`. * - * @param extension_type - * The 2-byte identifier for the extension. + * @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 * - * @param data - * A buffer where the encoded extension data is stored. + * @abstract + * Enable or disable EV enforcement. * - * @param data_length - * Length of the encoded extension data. + * @param options + * A `sec_protocol_options_t` instance. * - * @param error - * Pointer to a return error code that's populated in the event of an error. + * @param enforce_ev + * Flag to determine if EV is enforced. */ 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 +void +sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev); -#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); +/*! + * @block sec_protocol_session_update_t + * + * @abstract + * Block to be invoked when a new session is established and ready. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + */ +typedef void (^sec_protocol_session_update_t)(sec_protocol_metadata_t metadata); +/*! + * @function sec_protocol_options_set_session_update_block + * + * @abstract + * Set the session update block. This is fired whenever a new session is + * created an inserted into the cache. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param update_block + * A `sec_protocol_session_update_t` instance. + * + * @params update_queue + * A `dispatch_queue_t` on which the update block should be called. + */ 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); +void +sec_protocol_options_set_session_update_block(sec_protocol_options_t options, + sec_protocol_session_update_t update_block, + dispatch_queue_t update_queue); +/*! + * @function sec_protocol_options_set_session_state + * + * @abstract + * Set the session state using a serialized session blob. + * + * If the session state is invalid or otherwise corrupt, the state is ignored and + * the connection will proceed as if no state was provided. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param session_state + * A `dispatch_data_t` carrying serialized session state from a previous. + */ 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); +void +sec_protocol_options_set_session_state(sec_protocol_options_t options, dispatch_data_t session_state); -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); +/*! + * @function sec_protocol_options_set_quic_transport_parameters + * + * @abstract + * Set the opaque QUIC transport parameters to be used for this connection. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param transport_parameters + * A `dispatch_data_t` carrying opqaue QUIC transport parameters. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_quic_transport_parameters(sec_protocol_options_t options, dispatch_data_t transport_parameters); -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__ +/*! + * @enum sec_protocol_tls_encryption_level_t + * + * @abstract An enumeration of the different TLS encryption levels. + */ +typedef enum { + sec_protocol_tls_encryption_level_initial = 0, + sec_protocol_tls_encryption_level_early_data, + sec_protocol_tls_encryption_level_handshake, + sec_protocol_tls_encryption_level_application, +} sec_protocol_tls_encryption_level_t; /*! - * @function sec_protocol_options_add_tls_extension + * @block sec_protocol_tls_encryption_secret_update_t * * @abstract - * Add support for a custom TLS extension. + * Block to be invoked when a new session is established and ready. + * + * @param level + * The `sec_protocol_tls_encryption_level_t` for this secret. + * + * @param is_write + * True if this secret is for writing, and false if it's for reading. + * + * @param secret + * Secret wrapped in a `dispatch_data_t` + */ +typedef void (^sec_protocol_tls_encryption_secret_update_t)(sec_protocol_tls_encryption_level_t level, bool is_write, dispatch_data_t secret); + +/*! + * @function sec_protocol_options_set_tls_encryption_secret_update_block * - * Clients such as QUIC use this when custom TLS extensions are needed. + * @abstract + * Set the TLS secret update block. This is fired whenever a new TLS secret is + * available. * * @param options * A `sec_protocol_options_t` instance. * - * @param extension - * A `sec_tls_extension_t` instance. + * @param update_block + * A `sec_protocol_tls_encryption_secret_update_t` instance. + * + * @params update_queue + * A `dispatch_queue_t` on which the update block should be called. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void -sec_protocol_options_add_tls_extension(sec_protocol_options_t options, sec_tls_extension_t extension); +sec_protocol_options_set_tls_encryption_secret_update_block(sec_protocol_options_t options, + sec_protocol_tls_encryption_secret_update_t update_block, + dispatch_queue_t update_queue); -#endif // __BLOCKS__ +/*! + * @block sec_protocol_private_key_complete_t + * + * @abstract + * Block to be invoked when a private key operation is complete. + * + * @param result + * A `dispatch_data_t` object containing the private key result. + */ +typedef void (^sec_protocol_private_key_complete_t)(dispatch_data_t result); /*! - * @function sec_protocol_options_set_tls_early_data_enabled + * @block sec_protocol_private_key_sign_t * * @abstract - * Enable or disable early (0-RTT) data for TLS. + * Block to be invoked when a private key signature operation is required. + * + * @param algorithm + * The signature algorithm to use for the signature. + * + * @param input + * The input to be signed. + * + * @param complete + * The `sec_protocol_private_key_complete_t` block to invoke when the operation is complete. + */ +typedef void (^sec_protocol_private_key_sign_t)(uint16_t algorithm, dispatch_data_t input, sec_protocol_private_key_complete_t complete); + +/*! + * @block sec_protocol_private_key_decrypt_t + * + * @abstract + * Block to be invoked when a private key decryption operation is required. + * + * @param input + * The input to be decrypted. + * + * @param complete + * The `sec_protocol_private_key_complete_t` block to invoke when the operation is complete. + */ +typedef void (^sec_protocol_private_key_decrypt_t)(dispatch_data_t input, sec_protocol_private_key_complete_t complete); + +/*! + * @block sec_protocol_options_set_private_key_blocks + * + * @abstract + * Set the private key operation blocks for this connection. * * @param options * A `sec_protocol_options_t` instance. * - * @param early_data_enabled - * Flag to enable or disable early (0-RTT) data. + * @param sign_block + * A `sec_protocol_private_key_sign_t` block. + * + * @param decrypt_block + * A `sec_protocol_private_key_decrypt_t` block. + * + * @param operation_queue + * The `dispatch_queue_t` queue on which each private key operation is invoked. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void -sec_protocol_options_set_tls_early_data_enabled(sec_protocol_options_t options, bool early_data_enabled); +sec_protocol_options_set_private_key_blocks(sec_protocol_options_t options, + sec_protocol_private_key_sign_t sign_block, + sec_protocol_private_key_decrypt_t decrypt_block, + dispatch_queue_t operation_queue); /*! - * @function sec_protocol_options_set_tls_sni_disabled + * @block sec_protocol_options_set_local_certificates * * @abstract - * Enable or disable the TLS SNI extension. This defaults to `false`. + * Set the local certificates to be used for this protocol instance. * * @param options * A `sec_protocol_options_t` instance. * - * @param sni_disabled - * Flag to enable or disable use of the TLS SNI extension. + * @param certificates + * A `sec_array_t` instance of `sec_certifiate_t` instances. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void -sec_protocol_options_set_tls_sni_disabled(sec_protocol_options_t options, bool sni_disabled); +sec_protocol_options_set_local_certificates(sec_protocol_options_t options, sec_array_t certificates); /*! - * @function sec_protocol_options_set_enforce_ev + * @block sec_protocol_options_set_tls_certificate_compression_enabled * * @abstract - * Enable or disable EV enforcement. + * Enable or disable TLS 1.3 certificate compression. + * + * See: https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04 * * @param options * A `sec_protocol_options_t` instance. * - * @param enforce_ev - * Flag to determine if EV is enforced. + * @param certificate_compression_enabled + * Flag to determine if certificate compression is enabled. */ -API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) void -sec_protocol_options_set_enforce_ev(sec_protocol_options_t options, bool enforce_ev); +sec_protocol_options_set_tls_certificate_compression_enabled(sec_protocol_options_t options, bool certificate_compression_enabled); /*! - * @function sec_protocol_metadata_get_tls_false_start_used + * @block sec_protocol_options_tls_handshake_message_callback * * @abstract - * Determine if False Start was used. + * Set a callback to process each TLS handshake message. This function may be invoked at any point during + * the TLS handshake, if at all. Clients MUST NOT rely on any behavior aspect of this function as they + * risk breaking. * - * @param metadata - * A `sec_protocol_metadata_t` instance. + * @param options + * A `sec_protocol_options_t` instance. * - * @return True if False Start was used, and false otherwise. + * @param handler + * A `sec_protocol_tls_handshake_message_handler_t`. + * + * @param queue + * The queue upon which to invoke the callback. */ -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); +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_tls_handshake_message_callback(sec_protocol_options_t options, sec_protocol_tls_handshake_message_handler_t handler, dispatch_queue_t queue); /*! - * @function sec_protocol_metadata_get_ticket_offered + * @block sec_protocol_options_append_tls_key_exchange_group * * @abstract - * Determine if a ticket was offered for session resumption. + * Append a TLS key exchange group to the set of enabled groups. * - * @param metadata - * A `sec_protocol_metadata_t` instance. + * @param options + * A `sec_protocol_options_t` instance. * - * @return True if a ticket was offered for resumption, and false otherwise. + * @param group + * A `tls_key_exchange_group_t` value. */ -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); +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_append_tls_key_exchange_group(sec_protocol_options_t options, tls_key_exchange_group_t group); /*! - * @function sec_protocol_metadata_get_ticket_received + * @block sec_protocol_options_add_tls_key_exchange_group * * @abstract - * Determine if a ticket was received upon completing the new connection. + * Add a TLS key exchange group to the set of enabled groups. * - * @param metadata - * A `sec_protocol_metadata_t` instance. + * @param options + * A `sec_protocol_options_t` instance. * - * @return True if a ticket was received from the peer (server), and false otherwise. + * @param group + * A SSLKeyExchangeGroup value. */ -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); +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_add_tls_key_exchange_group(sec_protocol_options_t options, SSLKeyExchangeGroup group); /*! - * @function sec_protocol_metadata_get_session_resumed + * @block sec_protocol_options_append_tls_key_exchange_group_set * * @abstract - * Determine if this new connection was a session resumption. + * Append a TLS key exchange group set to the set of enabled groups. * - * @param metadata - * A `sec_protocol_metadata_t` instance. + * @param options + * A `sec_protocol_options_t` instance. * - * @return True if this new connection was resumed, and false otherwise. + * @param set + * A `tls_key_exchange_group_set_t` value. */ -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); +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_append_tls_key_exchange_group_set(sec_protocol_options_t options, tls_key_exchange_group_set_t set); /*! - * @function sec_protocol_metadata_get_session_renewed + * @block sec_protocol_options_tls_key_exchange_group_set * * @abstract - * Determine if this resumed connection was renewed with a new ticket. + * Add a TLS key exchange group set to the set of enabled groups. * - * @param metadata - * A `sec_protocol_metadata_t` instance. + * @param options + * A `sec_protocol_options_t` instance. * - * @return True if this resumed connection was renewed with a new ticket, and false otherwise. + * @param set + * A SSLKeyExchangeGroupSet value. */ -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); +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_add_tls_key_exchange_group_set(sec_protocol_options_t options, SSLKeyExchangeGroupSet set); + +/*! + * @function sec_protocol_options_set_tls_SIKE503_exchange_enabled + * + * @abstract + * Enable SIKE using P503 for TLS 1.3 key exchange. + * + * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. + * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param tls_SIKE503_exchange_enabled + * Flag to enable SIKE with P503. + */ +#define SEC_PROTOCOL_HAS_PQ_TLS_HANDLES 1 +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_tls_SIKE503_exchange_enabled(sec_protocol_options_t options, bool tls_SIKE503_exchange_enabled); + +/*! + * @function sec_protocol_options_set_tls_HRSS_exchange_enabled + * + * @abstract + * Enable HRSS for TLS 1.3 key exchange. + * + * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. + * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param tls_HRSS_exchange_enabled + * Flag to enable HRSS. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_tls_HRSS_exchange_enabled(sec_protocol_options_t options, bool tls_HRSS_exchange_enabled); + +/*! + * @function sec_protocol_options_set_eddsa_enabled + * + * @abstract + * Enable EDDSA support (for TLS 1.3). + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param eddsa_enabled + * Flag to enable EDDSA. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_eddsa_enabled(sec_protocol_options_t options, bool eddsa_enabled); + +/*! + * @function sec_protocol_options_set_tls_delegated_credentials_enabled + * + * @abstract + * Enable TLS delegated credentials support. See https://tools.ietf.org/html/draft-ietf-tls-subcerts-02. + * + * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. + * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param tls_delegated_credentials_enabled + * Flag to enable TLS delegated credentials. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_tls_delegated_credentials_enabled(sec_protocol_options_t options, bool tls_delegated_credentials_enabled); + +/*! + * @function sec_protocol_options_set_tls_ticket_request_count + * + * @abstract + * Enable TLS ticket request support, and specify the count of tickets. Ticket support + * must also be explicitly enabled by `sec_protocol_options_set_tls_tickets_enabled`. + * + * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. + * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param tls_ticket_request_count + * Set the amount of tickets to request from the server. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_tls_ticket_request_count(sec_protocol_options_t options, uint8_t tls_ticket_request_count); + +/*! + * @function sec_protocol_options_set_tls_grease_enabled + * + * @abstract + * Enable TLS GREASE support. See https://tools.ietf.org/html/draft-ietf-tls-grease-02. + * + * DO NOT DEPEND ON THIS SPI. IT IS FOR EXPERIMENTAL PURPOSES AND SUBJECT TO REMOVAL WITHOUT ADVANCE NOTICE. + * BUILD BREAKAGE ISSUES WILL BE SENT TO THE CALLING PROJECT. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param tls_grease_enabled + * Flag to enable TLS GREASE. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_tls_grease_enabled(sec_protocol_options_t options, bool tls_grease_enabled); + +/*! + * @function sec_protocol_options_create_config + * + * @abstract + * Create a `xpc_object_t` instance carrying a configuration for the given `sec_protocol_options_t` instance. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @return A `xpc_object_t` instance carrying a configuration, or nil on failure. + */ +#define SEC_PROTOCOL_HAS_EXPERIMENT_HOOKS 1 +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable xpc_object_t +sec_protocol_options_create_config(sec_protocol_options_t options); + +/*! + * @function sec_protocol_options_matches_config + * + * @abstract + * Determine if a `sec_protocol_options_t` instance matches a given configuration. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param config + * A `xpc_object_t` instance carrying a SecExperiment config. + * + * @return True if the parameters in `config` match that of `options`, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_options_matches_config(sec_protocol_options_t options, xpc_object_t config); + +/*! + * @function sec_protocol_options_apply_config + * + * @abstract + * Transform the given `sec_protocol_options_t` instance using the provided config. + * + * @param options + * A `sec_protocol_options_t` instance. + * + * @param config + * A `xpc_object_t` instance carrying a SecExperiment config. + * + * @return True if the options were applied successfully, and false otherwise. + */ +bool +sec_protocol_options_apply_config(sec_protocol_options_t options, xpc_object_t config); + +/*! + * @function sec_protocol_metadata_get_tls_negotiated_group + * + * @abstract + * Get a human readable representation of the negotiated key exchange group. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A string representation of the negotiated group, or NULL if it does not exist. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +const char * __nullable +sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata); + +/*! + * @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); + +/*! + * @function sec_protocol_metadata_get_connection_strength + * + * @abstract + * Determine the TLS connection strength. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return An `SSLConnectionStrength` enum. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SSLConnectionStrength +sec_protocol_metadata_get_connection_strength(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_copy_serialized_session + * + * @abstract + * Copy a serialized representation of a session. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A `dispatch_data_t` object containing a serialized session. + */ +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_serialized_session(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_access_handle + * + * @abstract + * Access the internal handle of a `sec_protocol_metadata` object. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param access_block + * A block to invoke with access to the internal handle. + * + * @return True if the access was successful + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_access_handle(sec_protocol_metadata_t metadata, sec_access_block_t access_block); + +/*! + * @function sec_protocol_metadata_serialize_with_options + * + * @abstract + * Serialize a `sec_protocol_metadata_t` to an `xpc_object_t` dictionary using information + * contained in the `metadata` and `options` objects. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A xpc_object_t carrying the serialized metadata. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +SEC_RETURNS_RETAINED __nullable xpc_object_t +sec_protocol_metadata_serialize_with_options(sec_protocol_metadata_t metadata, sec_protocol_options_t options); + +/*! + * @function sec_protocol_metadata_get_tls_certificate_compression_used + * + * @abstract + * Determine if certificate compression was used for a given connection. + * + * See: https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04 + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return True if certificate compression was negotiated and used. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +bool +sec_protocol_metadata_get_tls_certificate_compression_used(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_tls_certificate_compression_algorithm + * + * @abstract + * Return the certificate compression algorithm used. This will return 0 + * if `sec_protocol_metadata_get_tls_certificate_compression_used` is false. + * + * See: https://tools.ietf.org/html/draft-ietf-tls-certificate-compression-04 + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return IANA codepoint for the certificate compression algorithm. + */ +API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) +uint16_t +sec_protocol_metadata_get_tls_certificate_compression_algorithm(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_copy_quic_transport_parameters + * + * @abstract + * Copy the peer's QUIC transport parameters. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A dispatch_data_t carrying the connection peer's opaque QUIC tranport parameters. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable dispatch_data_t +sec_protocol_metadata_copy_quic_transport_parameters(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_time_ms + * + * @abstract + * Get the TLS handshake time in miliseconds. The result is undefined + * for connections not yet connected. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A millisecond measurement of the TLS handshake time from start to finish. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +#define SEC_PROTOCOL_HAS_METRIC_SPI_V1 +uint64_t +sec_protocol_metadata_get_handshake_time_ms(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_rtt + * + * @abstract + * Get the observed TLS handshake RTT. This function must only be + * called after the connection is established. Calling this before + * the connection completes will yields an undefined result. + * + * This is computed as the average RTT across all 1-RTT exchanges. + * For TLS 1.3, this will be the time for the normal exchange. For prior + * versions, or TLS 1.3 with HRR, this will be the average RTT across + * multiple message flights. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A millisecond measurement of the TLS handshake RTT. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +uint64_t +sec_protocol_metadata_get_handshake_rtt(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_byte_count + * + * @abstract + * Get the total number of bytes sent and received for the handshake. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Number of bytes sent and received for the handshake. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +uint64_t +sec_protocol_metadata_get_handshake_byte_count(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_sent_byte_count + * + * @abstract + * Get the total number of bytes sent for the handshake. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Number of bytes sent for the handshake. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +uint64_t +sec_protocol_metadata_get_handshake_sent_byte_count(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_received_byte_count + * + * @abstract + * Get the total number of bytes received for the handshake. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Number of bytes received for the handshake. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +uint64_t +sec_protocol_metadata_get_handshake_received_byte_count(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_read_stall_count + * + * @abstract + * Get the total number of read stalls during the handshake. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Number of read stalls. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +size_t +sec_protocol_metadata_get_handshake_read_stall_count(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_write_stall_count + * + * @abstract + * Get the total number of write stalls during the handshake. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Number of write stalls. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +size_t +sec_protocol_metadata_get_handshake_write_stall_count(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_get_handshake_async_call_count + * + * @abstract + * Get the total number of asynchronous callbacks invoked during the handshake. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return Number of asynchronous callbacks. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +size_t +sec_protocol_metadata_get_handshake_async_call_count(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_copy_sec_trust + * + * @abstract + * Copy the `sec_trust_t` associated with a connection. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A `sec_trust_t` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable sec_trust_t +sec_protocol_metadata_copy_sec_trust(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_copy_sec_identity + * + * @abstract + * Copy the `sec_identity_t` associated with a connection. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A `sec_identity_t` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable sec_identity_t +sec_protocol_metadata_copy_sec_identity(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_metadata_access_sent_certificates + * + * @abstract + * Access the certificates which were sent to the peer on this connection. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @param handler + * A block to invoke one or more times with `sec_certificate_t` instances. + * + * @return Returns true if the peer certificates were accessible, false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_protocol_metadata_access_sent_certificates(sec_protocol_metadata_t metadata, + void (^handler)(sec_certificate_t certificate)); + +/*! + * @function sec_protocol_metadata_get_tls_negotiated_group + * + * @abstract + * Get a human readable representation of the negotiated key exchange group. + * + * @param metadata + * A `sec_protocol_metadata_t` instance. + * + * @return A string representation of the negotiated group, or NULL if it does not exist. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +const char * __nullable +sec_protocol_metadata_get_tls_negotiated_group(sec_protocol_metadata_t metadata); + +/*! + * @function sec_protocol_configuration_copy_singleton + * + * @abstract + * Copy the per-process `sec_protocol_configuration_t` object. + * + * @return A non-nil `sec_protocol_configuration_t` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED sec_protocol_configuration_t +sec_protocol_configuration_copy_singleton(void); + +#ifndef SEC_OBJECT_IMPL +SEC_OBJECT_DECL(sec_protocol_configuration_builder); +#endif // !SEC_OBJECT_IMPL + +/*! + * @function sec_protocol_configuration_builder_create + * + * @abstract + * This function is exposed for testing purposes only. It MUST NOT be called by clients. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED sec_protocol_configuration_builder_t +sec_protocol_configuration_builder_create(CFDictionaryRef dictionary, bool is_apple); + +/*! + * @function sec_protocol_configuration_create_with_builder + * + * @abstract + * This function is exposed for testing purposes only. It MUST NOT be called by clients. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED __nullable sec_protocol_configuration_t +sec_protocol_configuration_create_with_builder(sec_protocol_configuration_builder_t builder); + +/*! + * @block sec_protocol_output_handler_access_block_t + * + * @abstract + * Block to be invoked to obtain the output handler for a given encryption level. + */ +typedef void *_Nullable(^sec_protocol_output_handler_access_block_t)(sec_protocol_tls_encryption_level_t level); + +/*! + * @function sec_protocol_options_set_output_handler_access_block + * + * @abstract + * Set a block used to access output handler instances identified by encryption level. + */ +#define SEC_PROTOCOL_HAS_QUIC_OUTPUT_HANDLER_ACCESS_BLOCK 1 +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +void +sec_protocol_options_set_output_handler_access_block(sec_protocol_options_t options, + sec_protocol_output_handler_access_block_t access_block); + +/*! + * @function sec_protocol_helper_ciphersuite_group_to_ciphersuite_list + * + * @abstract + * Return a pointer to a statically allocated list of ciphersuites corresponding to `group`. + * + * @param group + * A `tls_ciphersuite_group_t` instance. + * + * @param list_count + * Pointer to storage for the ciphersuite list length. + * + * @return Pointer to a statically allocated list, or NULL if an error occurred. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +const tls_ciphersuite_t * __nullable +sec_protocol_helper_ciphersuite_group_to_ciphersuite_list(tls_ciphersuite_group_t group, size_t *list_count); + +#define SEC_PROTOCOL_HAS_MULTI_PSK_SUPPORT 1 + +struct sec_protocol_options_content { + SSLProtocol min_version; + SSLProtocol max_version; + + // Reference-counted types + char *server_name; + __nullable xpc_object_t ciphersuites; + xpc_object_t application_protocols; + sec_identity_t identity; + sec_array_t certificates; + xpc_object_t pre_shared_keys; + dispatch_data_t psk_identity_hint; + sec_protocol_key_update_t key_update_block; + dispatch_queue_t key_update_queue; + sec_protocol_challenge_t challenge_block; + dispatch_queue_t challenge_queue; + sec_protocol_verify_t verify_block; + dispatch_queue_t verify_queue; + dispatch_data_t quic_transport_parameters; + sec_protocol_tls_encryption_secret_update_t tls_secret_update_block; + dispatch_queue_t tls_secret_update_queue; + sec_protocol_session_update_t session_update_block; + dispatch_queue_t session_update_queue; + dispatch_data_t session_state; + sec_protocol_private_key_sign_t private_key_sign_block; + sec_protocol_private_key_decrypt_t private_key_decrypt_block; + dispatch_queue_t private_key_queue; + dispatch_data_t dh_params; + xpc_object_t key_exchange_groups; + sec_protocol_tls_handshake_message_handler_t handshake_message_callback; + dispatch_queue_t handshake_message_callback_queue; + sec_protocol_pre_shared_key_selection_t psk_selection_block; + dispatch_queue_t psk_selection_queue; + + // ATS minimums + size_t minimum_rsa_key_size; + size_t minimum_ecdsa_key_size; + SecSignatureHashAlgorithm minimum_signature_algorithm; + + // Non-boolean options + uint8_t tls_ticket_request_count; + + // QUIC-specific access block + sec_protocol_output_handler_access_block_t output_handler_access_block; + + // Boolean flags + unsigned ats_required : 1; + unsigned ats_minimum_tls_version_allowed : 1; + unsigned ats_non_pfs_ciphersuite_allowed : 1; + unsigned trusted_peer_certificate : 1; + unsigned trusted_peer_certificate_override : 1; + unsigned disable_sni : 1; + unsigned disable_sni_override : 1; + unsigned enable_fallback_attempt : 1; + unsigned enable_fallback_attempt_override : 1; + unsigned enable_false_start : 1; + unsigned enable_false_start_override : 1; + unsigned enable_tickets : 1; + unsigned enable_tickets_override : 1; + unsigned enable_sct : 1; + unsigned enable_sct_override : 1; + unsigned enable_ocsp : 1; + unsigned enable_ocsp_override : 1; + unsigned enforce_ev : 1; + unsigned enforce_ev_override : 1; + unsigned enable_resumption : 1; + unsigned enable_resumption_override : 1; + unsigned enable_renegotiation : 1; + unsigned enable_renegotiation_override : 1; + unsigned enable_early_data : 1; + unsigned enable_early_data_override : 1; + unsigned peer_authentication_required : 1; + unsigned peer_authentication_override : 1; + unsigned certificate_compression_enabled : 1; + unsigned tls_SIKE503_exchange_enabled : 1; + unsigned tls_HRSS_exchange_enabled : 1; + unsigned eddsa_enabled : 1; + unsigned tls_delegated_credentials_enabled : 1; + unsigned tls_grease_enabled : 1; +}; + +struct sec_protocol_metadata_content { + 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. + void *session_exporter_context; // Opaque context for the session exporter function + sec_protocol_metadata_session_exporter session_exporter_function; + + SSLProtocol negotiated_protocol_version; + SSLCipherSuite negotiated_ciphersuite; + const char *negotiated_protocol; + const char *server_name; + + sec_array_t sent_certificate_chain; + sec_array_t peer_certificate_chain; + xpc_object_t pre_shared_keys; + dispatch_data_t peer_public_key; + xpc_object_t supported_signature_algorithms; + dispatch_data_t request_certificate_types; + sec_array_t signed_certificate_timestamps; + sec_array_t ocsp_response; + sec_array_t distinguished_names; + dispatch_data_t quic_transport_parameters; + sec_identity_t identity; + sec_trust_t trust_ref; + const char *negotiated_curve; + const char *peer_public_key_type; + const char *certificate_request_type; + uint64_t ticket_lifetime; + uint64_t max_early_data_supported; + uint64_t alert_type; + uint64_t alert_code; + uint64_t handshake_state; + uint64_t stack_error; + uint64_t handshake_rtt; + uint16_t certificate_compression_algorithm; + uint64_t handshake_time; + uint64_t total_byte_count; + uint64_t sent_byte_count; + uint64_t received_byte_count; + size_t read_stall_count; + size_t write_stall_count; + size_t async_call_count; + + unsigned failure : 1; + unsigned sct_enabled : 1; + unsigned ocsp_enabled : 1; + 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; + unsigned resumption_attempted : 1; + unsigned alpn_used : 1; + unsigned npn_used : 1; + unsigned early_data_sent : 1; + unsigned certificate_compression_used : 1; +}; + +SEC_ASSUME_NONNULL_END __END_DECLS diff --git a/protocol/SecProtocolTest.m b/protocol/SecProtocolTest.m new file mode 100644 index 00000000..e1b8cdb9 --- /dev/null +++ b/protocol/SecProtocolTest.m @@ -0,0 +1,1110 @@ +// +// SecProtocolTest.m +// SecureTransportTests +// + +#import +#import + +#include +#include +#include + +#import + +#import "SecProtocolConfiguration.h" +#import "SecProtocolPriv.h" +#import "SecProtocolInternal.h" + +#import // Needed for the mock protocol + +#define SEC_PROTOCOL_OPTIONS_VALIDATE(m, r) \ + if (((void *)(m) == NULL) || ((size_t)(m) == 0)) { \ + return (r); \ + } + +#define SEC_PROTOCOL_METADATA_VALIDATE(m, r) \ + if (((void *)(m) == NULL) || ((size_t)(m) == 0)) { \ + return (r); \ + } + +typedef struct mock_protocol { + struct nw_protocol protocol; + char *name; +} *mock_protocol_t; + +static nw_protocol_t +_mock_protocol_create_extended(nw_protocol_identifier_const_t identifier, + nw_endpoint_t endpoint, + nw_parameters_t parameters) +{ + mock_protocol_t handle = (mock_protocol_t)calloc(1, sizeof(struct mock_protocol)); + if (handle == NULL) { + return NULL; + } + + struct nw_protocol_callbacks *callbacks = (struct nw_protocol_callbacks *) malloc(sizeof(struct nw_protocol_callbacks)); + memset(callbacks, 0, sizeof(struct nw_protocol_callbacks)); + + handle->protocol.callbacks = callbacks; + handle->protocol.handle = (void *)handle; + + return &handle->protocol; +} + +static bool +mock_protocol_register_extended(nw_protocol_identifier_const_t identifier, + nw_protocol_create_extended_f create_extended_function) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static bool (*_nw_protocol_register_extended)(nw_protocol_identifier_const_t, nw_protocol_create_extended_f) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_register_extended = (__typeof(_nw_protocol_register_extended))dlsym(libnetworkImage, "nw_protocol_register_extended"); + if (NULL == _nw_protocol_register_extended) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_register_extended"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_register_extended == NULL) { + return false; + } + + return _nw_protocol_register_extended(identifier, create_extended_function); +} + +static nw_protocol_identifier_t +_mock_protocol_identifier(const char *name, size_t name_len) +{ + static struct nw_protocol_identifier mock_identifer = {}; + static dispatch_once_t onceToken = 0; + dispatch_once(&onceToken, ^{ + memset(&mock_identifer, 0, sizeof(mock_identifer)); + + strlcpy((char *)mock_identifer.name, name, name_len); + + mock_identifer.level = nw_protocol_level_application; + mock_identifer.mapping = nw_protocol_mapping_one_to_one; + + mock_protocol_register_extended(&mock_identifer, _mock_protocol_create_extended); + }); + + return &mock_identifer; +} + +static void * _Nullable +mock_protocol_allocate_metadata(__unused nw_protocol_definition_t definition) +{ + return calloc(1, sizeof(struct sec_protocol_metadata_content)); +} + +static void +mock_protocol_deallocate_metadata(__unused nw_protocol_definition_t definition, void *metadata) +{ + sec_protocol_metadata_content_t content = (sec_protocol_metadata_content_t)metadata; + if (content) { + // pass + } + free(content); +} + +static void +mock_protocol_set_metadata_allocator(nw_protocol_definition_t definition, nw_protocol_definition_allocate_f allocator, nw_protocol_definition_deallocate_f deallocator) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static void (*_nw_protocol_definition_set_metadata_allocator)(nw_protocol_definition_t, nw_protocol_definition_allocate_f, nw_protocol_definition_deallocate_f) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_definition_set_metadata_allocator = (__typeof(_nw_protocol_definition_set_metadata_allocator))dlsym(libnetworkImage, "nw_protocol_definition_set_metadata_allocator"); + if (NULL == _nw_protocol_definition_set_metadata_allocator) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_definition_set_metadata_allocator"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_definition_set_metadata_allocator == NULL) { + return; + } + + _nw_protocol_definition_set_metadata_allocator(definition, allocator, deallocator); +} + +static void * _Nullable +mock_protocol_copy_options(__unused nw_protocol_definition_t definition, void *options) +{ + void *new_options = calloc(1, sizeof(struct sec_protocol_options_content)); + + sec_protocol_options_content_t copy = (sec_protocol_options_content_t)new_options; + sec_protocol_options_content_t original = (sec_protocol_options_content_t)options; + + copy->min_version = original->min_version; + copy->max_version = original->max_version; + copy->disable_sni = original->disable_sni; + copy->enable_fallback_attempt = original->enable_fallback_attempt; + copy->enable_false_start = original->enable_false_start; + copy->enable_tickets = original->enable_tickets; + copy->enable_sct = original->enable_sct; + copy->enable_ocsp = original->enable_ocsp; + copy->enable_resumption = original->enable_resumption; + copy->enable_renegotiation = original->enable_renegotiation; + copy->enable_early_data = original->enable_early_data; + + if (original->server_name) { + copy->server_name = strdup(original->server_name); + } + if (original->identity) { + copy->identity = original->identity; + } + if (original->application_protocols) { + copy->application_protocols = xpc_copy(original->application_protocols); + } + if (original->ciphersuites) { + copy->ciphersuites = xpc_copy(original->ciphersuites); + } + if (original->dh_params) { + copy->dh_params = original->dh_params; + } + if (original->key_update_block) { + copy->key_update_block = original->key_update_block; + copy->key_update_queue = original->key_update_queue; + } + if (original->challenge_block) { + copy->challenge_block = original->challenge_block; + copy->challenge_queue = original->challenge_queue; + } + if (original->verify_block) { + copy->verify_block = original->verify_block; + copy->verify_queue = original->verify_queue; + } + if (original->session_state) { + copy->session_state = original->session_state; + } + if (original->session_update_block) { + copy->session_update_block = original->session_update_block; + copy->session_update_queue = original->session_update_queue; + } + if (original->pre_shared_keys) { + copy->pre_shared_keys = xpc_copy(original->pre_shared_keys); + } + + return new_options; +} + +static void * _Nullable +mock_protocol_allocate_options(__unused nw_protocol_definition_t definition) +{ + return calloc(1, sizeof(struct sec_protocol_options_content)); +} + +static void +mock_protocol_deallocate_options(__unused nw_protocol_definition_t definition, void *options) +{ + sec_protocol_options_content_t content = (sec_protocol_options_content_t)options; + if (content) { + // pass + } + free(content); +} + +static void +mock_protocol_set_options_allocator(nw_protocol_definition_t definition, + nw_protocol_definition_allocate_f allocate_function, + nw_protocol_definition_copy_f copy_function, + nw_protocol_definition_deallocate_f deallocate_function) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static void (*_nw_protocol_definition_set_options_allocator)(nw_protocol_definition_t, nw_protocol_definition_allocate_f, nw_protocol_definition_copy_f, nw_protocol_definition_deallocate_f) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_definition_set_options_allocator = (__typeof(_nw_protocol_definition_set_options_allocator))dlsym(libnetworkImage, "nw_protocol_definition_set_options_allocator"); + if (NULL == _nw_protocol_definition_set_options_allocator) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_definition_set_options_allocator"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_definition_set_options_allocator == NULL) { + return; + } + + _nw_protocol_definition_set_options_allocator(definition, allocate_function, copy_function, deallocate_function); +} + +static nw_protocol_definition_t +mock_protocol_definition_create_with_identifier(nw_protocol_identifier_const_t identifier) +{ + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static nw_protocol_definition_t (*_nw_protocol_definition_create_with_identifier)(nw_protocol_identifier_const_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_definition_create_with_identifier = (__typeof(_nw_protocol_definition_create_with_identifier))dlsym(libnetworkImage, "nw_protocol_definition_create_with_identifier"); + if (NULL == _nw_protocol_definition_create_with_identifier) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_definition_create_with_identifier"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_definition_create_with_identifier == NULL) { + return NULL; + } + + return _nw_protocol_definition_create_with_identifier(identifier); +} + +static nw_protocol_definition_t +mock_protocol_copy_definition(void) +{ + static nw_protocol_definition_t definition = NULL; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + const char *mock_protocol_name = "secProtocolTestMockProtocol"; + definition = mock_protocol_definition_create_with_identifier(_mock_protocol_identifier(mock_protocol_name, strlen(mock_protocol_name))); + mock_protocol_set_options_allocator(definition, + mock_protocol_allocate_options, + mock_protocol_copy_options, + mock_protocol_deallocate_options); + mock_protocol_set_metadata_allocator(definition, + mock_protocol_allocate_metadata, + mock_protocol_deallocate_metadata); + + }); + + return definition; +} + +@interface SecProtocolTest : XCTestCase +@property nw_protocol_t mock_protocol; +@end + +@implementation SecProtocolTest + +- (void)setUp { + [super setUp]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (sec_protocol_options_t)create_sec_protocol_options { + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + + static sec_protocol_options_t (*_nw_protocol_create_options)(nw_protocol_definition_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_create_options = (__typeof(_nw_protocol_create_options))dlsym(libnetworkImage, "nw_protocol_create_options"); + if (NULL == _nw_protocol_create_options) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork _nw_protocol_create_options"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_create_options == NULL) { + return nil; + } + + return (sec_protocol_options_t)_nw_protocol_create_options(mock_protocol_copy_definition()); +} + +- (sec_protocol_metadata_t)create_sec_protocol_metadata { + uuid_t identifier; + uuid_generate(identifier); + + static void *libnetworkImage = NULL; + static dispatch_once_t onceToken; + static sec_protocol_metadata_t (*_nw_protocol_metadata_create)(nw_protocol_definition_t, _Nonnull uuid_t) = NULL; + + dispatch_once(&onceToken, ^{ + libnetworkImage = dlopen("/usr/lib/libnetwork.dylib", RTLD_LAZY | RTLD_LOCAL); + if (NULL != libnetworkImage) { + _nw_protocol_metadata_create = (__typeof(_nw_protocol_metadata_create))dlsym(libnetworkImage, "nw_protocol_metadata_create"); + if (NULL == _nw_protocol_metadata_create) { + os_log_error(OS_LOG_DEFAULT, "dlsym libnetwork nw_protocol_metadata_create"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "dlopen libnetwork"); + } + }); + + if (_nw_protocol_metadata_create == NULL) { + return nil; + } + + return (sec_protocol_metadata_t)_nw_protocol_metadata_create(mock_protocol_copy_definition(), identifier); +} + +- (void)test_sec_protocol_metadata_get_connection_strength_tls12 { + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + + (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); + + content->negotiated_ciphersuite = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + content->negotiated_protocol_version = kTLSProtocol12; +#pragma clang diagnostic pop + + return true; + }); + + XCTAssertTrue(SSLConnectionStrengthStrong == sec_protocol_metadata_get_connection_strength(metadata), + "Expected SSLConnectionStrengthStrong for TLS 1.2 with a strong ciphersuite, got %d", (int)sec_protocol_metadata_get_connection_strength(metadata)); +} + +- (void)test_sec_protocol_metadata_get_connection_strength_tls12_weak_ciphersuite { + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + if (metadata) { + (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); + + content->negotiated_ciphersuite = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + content->negotiated_protocol_version = kTLSProtocol12; +#pragma clang diagnostic pop + + return true; + }); + + XCTAssertTrue(SSLConnectionStrengthWeak == sec_protocol_metadata_get_connection_strength(metadata), + "Expected SSLConnectionStrengthWeak for TLS 1.2 with a weak ciphersuite, got %d", (int)sec_protocol_metadata_get_connection_strength(metadata)); + } +} + +- (void)test_sec_protocol_metadata_get_connection_strength_tls11 { + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + if (metadata) { + (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); + + content->negotiated_ciphersuite = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + content->negotiated_protocol_version = kTLSProtocol11; +#pragma clang diagnostic pop + + return true; + }); + + XCTAssertTrue(SSLConnectionStrengthWeak == sec_protocol_metadata_get_connection_strength(metadata), + "Expected SSLConnectionStrengthWeak for TLS 1.1, got %d", (int)sec_protocol_metadata_get_connection_strength(metadata)); + } +} + +- (void)test_sec_protocol_metadata_get_connection_strength_tls10 { + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + if (metadata) { + (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); + + content->negotiated_ciphersuite = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + content->negotiated_protocol_version = kTLSProtocol1; +#pragma clang diagnostic pop + + return true; + }); + + XCTAssertTrue(SSLConnectionStrengthWeak == sec_protocol_metadata_get_connection_strength(metadata), + "Expected SSLConnectionStrengthWeak for TLS 1.0, got %d", (int)sec_protocol_metadata_get_connection_strength(metadata)); + } +} + +- (void)test_sec_protocol_metadata_get_connection_strength_sslv3_strong_ciphersuite { + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + if (metadata) { + (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); + + content->negotiated_ciphersuite = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; // This can be anything -- we downgrade based on the version here. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + content->negotiated_protocol_version = kSSLProtocol3; +#pragma clang diagnostic pop + + return true; + }); + + XCTAssertTrue(SSLConnectionStrengthNonsecure == sec_protocol_metadata_get_connection_strength(metadata), + "Expected SSLConnectionStrengthNonsecure for SSL 3.0, got %d", (int)sec_protocol_metadata_get_connection_strength(metadata)); + } +} + +- (void)test_sec_protocol_metadata_get_connection_strength_sslv3_weak_ciphersuite { + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + if (metadata) { + (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); + + content->negotiated_ciphersuite = SSL_RSA_WITH_3DES_EDE_CBC_SHA; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + content->negotiated_protocol_version = kSSLProtocol3; +#pragma clang diagnostic pop + + return true; + }); + + XCTAssertTrue(SSLConnectionStrengthNonsecure == sec_protocol_metadata_get_connection_strength(metadata), + "Expected SSLConnectionStrengthNonsecure for SSL 3.0, got %d", (int)sec_protocol_metadata_get_connection_strength(metadata)); + } +} + +static size_t +_sec_protocol_dispatch_data_copyout(dispatch_data_t data, void *destination, size_t maxlen) +{ + __block size_t copied = 0; + __block uint8_t *buffer = (uint8_t *)destination; + + if (data) { + dispatch_data_apply(data, ^bool(__unused dispatch_data_t region, __unused size_t offset, const void *dbuffer, size_t size) { + size_t consumed = MIN(maxlen - copied, size); + if (consumed) { + memcpy(&buffer[copied], dbuffer, consumed); + copied += consumed; + } + + return copied < maxlen; + }); + } + + return copied; +} + +static dispatch_data_t +_sec_protocol_test_metadata_session_exporter(void *handle) +{ + if (handle == NULL) { + return nil; + } + + const char *received_handle = (const char *)handle; + dispatch_data_t serialized_session = dispatch_data_create(received_handle, strlen(received_handle), NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + return serialized_session; +} + +- (void)test_sec_protocol_register_session_update { + sec_protocol_options_t options = [self create_sec_protocol_options]; + dispatch_queue_t test_queue = dispatch_queue_create("test_sec_protocol_register_session_update", NULL); + __block bool session_updated = false; + + __block dispatch_data_t serialized_session_copy = nil; + sec_protocol_session_update_t update_block = ^(sec_protocol_metadata_t metadata) { + session_updated = true; + serialized_session_copy = sec_protocol_metadata_copy_serialized_session(metadata); + }; + + sec_protocol_options_set_session_update_block(options, update_block, test_queue); + + const char *metadata_context_handle = "context handle"; + + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + (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); + + content->session_exporter_context = (void *)metadata_context_handle; + content->session_exporter_function = _sec_protocol_test_metadata_session_exporter; + + return true; + }); + + update_block(metadata); + + XCTAssertTrue(session_updated, "Expected session update callback block to fire"); + XCTAssertNotNil(serialized_session_copy, "Expected non-nil serialized session"); + + if (serialized_session_copy) { + size_t data_size = dispatch_data_get_size(serialized_session_copy); + uint8_t *session_copy_buffer = (uint8_t *)malloc(data_size); + + (void)_sec_protocol_dispatch_data_copyout(serialized_session_copy, session_copy_buffer, data_size); + XCTAssertTrue(data_size == strlen(metadata_context_handle)); + XCTAssertTrue(memcmp(session_copy_buffer, metadata_context_handle, data_size) == 0); + + free(session_copy_buffer); + } +} + +#define SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR "stack_error" +#define SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE "cipher_name" + +- (void)test_sec_protocol_metadata_serialize_success { + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + (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); + + content->failure = false; + content->stack_error = 0xDEAD; + content->negotiated_ciphersuite = TLS_AES_256_GCM_SHA384; + return true; + }); + + xpc_object_t dictionary = sec_protocol_metadata_serialize_with_options(metadata, options); + XCTAssertTrue(dictionary != NULL); + XCTAssertTrue(xpc_dictionary_get_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR) == 0x00, + "Expected 0x%x, got 0x%llx", 0x00, xpc_dictionary_get_int64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR)); + XCTAssertTrue(xpc_dictionary_get_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE) == TLS_AES_256_GCM_SHA384, + "Expected 0x%x, got 0x%llx", TLS_AES_256_GCM_SHA384, xpc_dictionary_get_int64(dictionary, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE)); +} + +- (void)test_sec_protocol_metadata_serialize_failure { + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + (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); + + content->failure = true; + content->stack_error = 0xDEAD; + content->negotiated_ciphersuite = TLS_AES_256_GCM_SHA384; + return true; + }); + + xpc_object_t dictionary = sec_protocol_metadata_serialize_with_options(metadata, options); + XCTAssertTrue(dictionary != NULL); + XCTAssertTrue(xpc_dictionary_get_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR) == 0xDEAD, + "Expected 0x%x, got 0x%llx", 0xDEAD, xpc_dictionary_get_int64(dictionary, SEC_PROTOCOL_METADATA_KEY_FAILURE_STACK_ERROR)); + XCTAssertTrue(xpc_dictionary_get_uint64(dictionary, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE) == 0x00, + "Expected 0x%x, got 0x%llx", 0x00, xpc_dictionary_get_int64(dictionary, SEC_PROTOCOL_METADATA_KEY_CIPHERSUITE)); +} + +- (void)test_sec_protocol_options_set_quic_transport_parameters { + uint8_t parameters_buffer[] = {0x00, 0x01, 0x02, 0x03}; + uint8_t expected_parameters_buffer[sizeof(parameters_buffer)] = {0}; + + __block size_t parameters_len = sizeof(parameters_buffer); + __block uint8_t *parameters = parameters_buffer; + __block uint8_t *expected_parameters = expected_parameters_buffer; + __block dispatch_data_t parameters_data = dispatch_data_create(parameters, sizeof(parameters_buffer), NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_options_set_quic_transport_parameters(options, parameters_data); + + bool result = 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->quic_transport_parameters) { + dispatch_data_t actual_parameters = content->quic_transport_parameters; + size_t data_len = _sec_protocol_dispatch_data_copyout(actual_parameters, expected_parameters, parameters_len); + + if (data_len == parameters_len) { + return 0 == memcmp(parameters, expected_parameters, parameters_len); + } + } + + return false; + }); + + XCTAssertTrue(result); +} + +- (void)test_sec_protocol_metadata_copy_quic_transport_parameters { + uint8_t parameters_buffer[] = {0x00, 0x01, 0x02, 0x03}; + uint8_t expected_parameters_buffer[sizeof(parameters_buffer)] = {0}; + + __block size_t parameters_len = sizeof(parameters_buffer); + __block uint8_t *parameters = parameters_buffer; + __block uint8_t *expected_parameters = expected_parameters_buffer; + __block dispatch_data_t parameters_data = dispatch_data_create(parameters, sizeof(parameters_buffer), NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + (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); + + content->quic_transport_parameters = parameters_data; + return true; + }); + + dispatch_data_t actual_parameters = sec_protocol_metadata_copy_quic_transport_parameters(metadata); + size_t data_len = _sec_protocol_dispatch_data_copyout(actual_parameters, expected_parameters, parameters_len); + + bool result = false; + if (data_len == parameters_len) { + result = 0 == memcmp(parameters, expected_parameters, parameters_len); + } + XCTAssertTrue(result); +} + +- (void)test_sec_protocol_options_set_tls_encryption_secret_update_block { + void (^update_block)(sec_protocol_tls_encryption_level_t, bool, dispatch_data_t) = ^(__unused sec_protocol_tls_encryption_level_t level, __unused bool is_write, __unused dispatch_data_t secret) { + // pass + }; + + dispatch_queue_t update_queue = dispatch_queue_create("test_sec_protocol_options_set_tls_encryption_secret_update_block_queue", DISPATCH_QUEUE_SERIAL); + + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_options_set_tls_encryption_secret_update_block(options, update_block, 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); + XCTAssertTrue(content->tls_secret_update_block == update_block); + XCTAssertTrue(content->tls_secret_update_queue != nil); + return false; + }); +} + +- (void)test_sec_protocol_options_set_local_certificates { + sec_protocol_options_t options = [self create_sec_protocol_options]; + + sec_array_t certificates = sec_array_create(); + sec_protocol_options_set_local_certificates(options, certificates); + + (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); + XCTAssertTrue(content->certificates == certificates); + return true; + }); +} + +- (void)test_sec_protocol_options_set_private_key_blocks { + sec_protocol_options_t options = [self create_sec_protocol_options]; + + void (^sign_block)(uint16_t algorithm, dispatch_data_t, sec_protocol_private_key_complete_t) = ^(__unused uint16_t algorithm, __unused dispatch_data_t input, __unused sec_protocol_private_key_complete_t complete) { + // pass + }; + void (^decrypt_block)(dispatch_data_t, sec_protocol_private_key_complete_t) = ^(__unused dispatch_data_t input, __unused sec_protocol_private_key_complete_t complete) { + // pass + }; + dispatch_queue_t queue = dispatch_queue_create("private_key_operation_queue", DISPATCH_QUEUE_SERIAL); + + sec_protocol_options_set_private_key_blocks(options, sign_block, decrypt_block, 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); + XCTAssertTrue(content->private_key_sign_block == sign_block); + XCTAssertTrue(content->private_key_decrypt_block == decrypt_block); + XCTAssertTrue(content->private_key_queue == queue); + return true; + }); +} + +- (void)test_sec_protocol_options_set_tls_certificate_compression_enabled { + sec_protocol_options_t options = [self create_sec_protocol_options]; + + sec_protocol_options_set_tls_certificate_compression_enabled(options, true); + (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); + XCTAssertTrue(content->certificate_compression_enabled); + return true; + }); +} + +- (void)test_sec_protocol_options_are_equal { + sec_protocol_options_t optionsA = [self create_sec_protocol_options]; + sec_protocol_options_t optionsB = [self create_sec_protocol_options]; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + sec_protocol_options_set_tls_min_version(optionsA, kTLSProtocol13); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_min_version(optionsB, kTLSProtocol13); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_max_version(optionsA, kTLSProtocol13); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_max_version(optionsB, kTLSProtocol13); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); +#pragma clang diagnostic pop + + sec_protocol_options_set_tls_sni_disabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_sni_disabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_sni_disabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_is_fallback_attempt(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_is_fallback_attempt(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_is_fallback_attempt(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_false_start_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_false_start_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_false_start_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_tickets_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_tickets_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_tickets_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_sct_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_sct_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_sct_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_ocsp_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_ocsp_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_ocsp_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_resumption_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_resumption_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_resumption_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_renegotiation_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_renegotiation_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_renegotiation_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_grease_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_grease_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_grease_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_delegated_credentials_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_delegated_credentials_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_delegated_credentials_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_eddsa_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_eddsa_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_eddsa_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_early_data_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_early_data_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_early_data_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_set_tls_certificate_compression_enabled(optionsA, true); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_certificate_compression_enabled(optionsB, false); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_certificate_compression_enabled(optionsB, true); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + const char *server_nameA = "localhost"; + const char *server_nameB = "apple.com"; + sec_protocol_options_set_tls_server_name(optionsA, server_nameA); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_server_name(optionsB, server_nameB); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_tls_server_name(optionsB, server_nameA); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + uint8_t quic_parameters_buffer[] = {0x00, 0x01, 0x02, 0x03}; + dispatch_data_t quic_parameters = dispatch_data_create(quic_parameters_buffer, sizeof(quic_parameters_buffer), nil, DISPATCH_DATA_DESTRUCTOR_DEFAULT); + sec_protocol_options_set_quic_transport_parameters(optionsA, quic_parameters); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_set_quic_transport_parameters(optionsB, quic_parameters); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_append_tls_ciphersuite(optionsA, 1337); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_append_tls_ciphersuite(optionsB, 1337); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + const char *application_protocolA = "h2"; + const char *application_protocolB = "h3"; + sec_protocol_options_add_tls_application_protocol(optionsA, application_protocolA); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + sec_protocol_options_add_tls_application_protocol(optionsB, application_protocolB); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + + sec_protocol_options_append_tls_ciphersuite(optionsB, 7331); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); +} + +- (void)test_sec_protocol_options_set_tls_server_name { + sec_protocol_options_t optionsA = [self create_sec_protocol_options]; + sec_protocol_options_t optionsB = [self create_sec_protocol_options]; + + const char *server_nameA = "apple.com"; + const char *server_nameB = "127.0.0.1"; + const char *server_nameC = "example.com"; + + /* + * Empty options should be equal. + */ + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + /* + * Set the name in optionsA. + * Options A, B should now be different. + */ + sec_protocol_options_set_tls_server_name(optionsA, server_nameA); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); + + /* + * Set the name to nameA in optionsB. + * Options A, B should now be equal. + */ + sec_protocol_options_set_tls_server_name(optionsB, server_nameA); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + /* + * Try to set the name to nameB in optionsB. + * It should fail since nameB is invalid. + * Options A, B should still be equal. + */ + sec_protocol_options_set_tls_server_name(optionsB, server_nameB); + XCTAssertTrue(sec_protocol_options_are_equal(optionsA, optionsB)); + + /* + * Change the current name in B. + * Comparison should fail. + */ + sec_protocol_options_set_tls_server_name(optionsB, server_nameC); + XCTAssertFalse(sec_protocol_options_are_equal(optionsA, optionsB)); +} + +- (void)test_sec_protocol_options_create_and_import_config { + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_options_t imported_options = [self create_sec_protocol_options]; + + sec_protocol_options_set_min_tls_protocol_version(options, tls_protocol_version_TLSv13); + sec_protocol_options_set_tls_early_data_enabled(options, true); + xpc_object_t config = sec_protocol_options_create_config(options); + XCTAssertTrue(config != NULL); + if (config != NULL) { + sec_protocol_options_apply_config(imported_options, config); + XCTAssertTrue(sec_protocol_options_are_equal(options, imported_options)); + } +} + +- (void)test_sec_protocol_options_matches_full_config { + sec_protocol_options_t options = [self create_sec_protocol_options]; + + sec_protocol_options_set_min_tls_protocol_version(options, tls_protocol_version_TLSv13); + sec_protocol_options_set_tls_early_data_enabled(options, true); + xpc_object_t config = sec_protocol_options_create_config(options); + XCTAssertTrue(config != NULL); + if (config != NULL) { + XCTAssertTrue(sec_protocol_options_matches_config(options, config)); + } +} + +- (void)test_sec_protocol_options_matches_partial_config { + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_options_set_tls_resumption_enabled(options, true); + + xpc_object_t config = sec_protocol_options_create_config(options); + XCTAssertTrue(config != NULL); + if (config != NULL) { + // Drop one key from the config, and make sure that the result still matches + __block const char *enable_resumption_key = "enable_resumption"; + xpc_object_t trimmed_config = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_apply(config, ^bool(const char * _Nonnull key, xpc_object_t _Nonnull value) { + if (strncmp(key, enable_resumption_key, strlen(enable_resumption_key)) != 0) { + xpc_dictionary_set_value(trimmed_config, key, value); + } + return true; + }); + XCTAssertTrue(sec_protocol_options_matches_config(options, trimmed_config)); + } +} + +- (void)test_sec_protocol_options_matches_config_with_mismatch { + sec_protocol_options_t options = [self create_sec_protocol_options]; + + __block bool enable_resumption = true; + sec_protocol_options_set_tls_resumption_enabled(options, enable_resumption); + + xpc_object_t config = sec_protocol_options_create_config(options); + XCTAssertTrue(config != NULL); + if (config != NULL) { + // Flip a value in the config, and expect the match to fail + __block const char *enable_resumption_key = "enable_resumption"; + xpc_object_t mismatched_config = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_apply(config, ^bool(const char * _Nonnull key, xpc_object_t _Nonnull value) { + if (strncmp(key, enable_resumption_key, strlen(enable_resumption_key)) != 0) { + xpc_dictionary_set_value(mismatched_config, key, value); + } else { + xpc_dictionary_set_bool(mismatched_config, key, !enable_resumption); + } + return true; + }); + XCTAssertFalse(sec_protocol_options_matches_config(options, mismatched_config)); + } +} + +- (void)test_sec_protocol_options_matches_config_with_mismatch_ciphersuites { + sec_protocol_options_t options = [self create_sec_protocol_options]; + + sec_protocol_options_append_tls_ciphersuite(options, 1); + + xpc_object_t config = sec_protocol_options_create_config(options); + XCTAssertTrue(config != NULL); + if (config != NULL) { + // Flip a value in the config, and expect the match to fail + __block const char *ciphersuites_key = "ciphersuites"; + xpc_object_t mismatched_config = xpc_dictionary_create(NULL, NULL, 0); + xpc_dictionary_apply(config, ^bool(const char * _Nonnull key, xpc_object_t _Nonnull value) { + if (strncmp(key, ciphersuites_key, strlen(ciphersuites_key)) != 0) { + xpc_dictionary_set_value(mismatched_config, key, value); + } else { + xpc_object_t ciphersuites = xpc_array_create(NULL, 0); + xpc_array_set_uint64(ciphersuites, XPC_ARRAY_APPEND, 2); + xpc_dictionary_set_value(mismatched_config, key, ciphersuites); + } + return true; + }); + XCTAssertFalse(sec_protocol_options_matches_config(options, mismatched_config)); + } +} + +- (void)test_protocol_version_map { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + XCTAssertTrue(tls_protocol_version_TLSv10 == SSLProtocolGetVersionCodepoint(kTLSProtocol1)); + XCTAssertTrue(tls_protocol_version_TLSv11 == SSLProtocolGetVersionCodepoint(kTLSProtocol11)); + XCTAssertTrue(tls_protocol_version_TLSv12 == SSLProtocolGetVersionCodepoint(kTLSProtocol12)); + XCTAssertTrue(tls_protocol_version_TLSv13 == SSLProtocolGetVersionCodepoint(kTLSProtocol13)); + XCTAssertTrue(tls_protocol_version_DTLSv12 == SSLProtocolGetVersionCodepoint(kDTLSProtocol12)); + XCTAssertTrue(tls_protocol_version_DTLSv10 == SSLProtocolGetVersionCodepoint(kDTLSProtocol1)); + + XCTAssertTrue(kTLSProtocol1 == SSLProtocolFromVersionCodepoint(tls_protocol_version_TLSv10)); + XCTAssertTrue(kTLSProtocol11 == SSLProtocolFromVersionCodepoint(tls_protocol_version_TLSv11)); + XCTAssertTrue(kTLSProtocol12 == SSLProtocolFromVersionCodepoint(tls_protocol_version_TLSv12)); + XCTAssertTrue(kTLSProtocol13 == SSLProtocolFromVersionCodepoint(tls_protocol_version_TLSv13)); + XCTAssertTrue(kDTLSProtocol12 == SSLProtocolFromVersionCodepoint(tls_protocol_version_DTLSv12)); + XCTAssertTrue(kDTLSProtocol1 == SSLProtocolFromVersionCodepoint(tls_protocol_version_DTLSv10)); +#pragma clang diagnostic pop +} + +- (void)test_default_protocol_versions { + XCTAssertTrue(sec_protocol_options_get_default_max_tls_protocol_version() == tls_protocol_version_TLSv13); + XCTAssertTrue(sec_protocol_options_get_default_min_tls_protocol_version() == tls_protocol_version_TLSv10); + XCTAssertTrue(sec_protocol_options_get_default_max_dtls_protocol_version() == tls_protocol_version_DTLSv12); + XCTAssertTrue(sec_protocol_options_get_default_min_dtls_protocol_version() == tls_protocol_version_DTLSv10); +} + +- (void)test_sec_protocol_options_set_psk_hint { + __block dispatch_data_t hint = [self create_random_dispatch_data]; + sec_protocol_options_t options = [self create_sec_protocol_options]; + + (void)sec_protocol_options_access_handle(options, ^bool(void * _Nonnull handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + + XCTAssertNil(content->psk_identity_hint, @"PSK identity initialized incorrectly"); + }); + + sec_protocol_options_set_tls_pre_shared_key_identity_hint(options, hint); + + (void)sec_protocol_options_access_handle(options, ^bool(void * _Nonnull handle) { + sec_protocol_options_content_t content = (sec_protocol_options_content_t)handle; + SEC_PROTOCOL_METADATA_VALIDATE(content, false); + + XCTAssertTrue(sec_protocol_helper_dispatch_data_equal(content->psk_identity_hint, hint), @"PSK identity mistmatch"); + }); +} + +- (void)test_sec_protocol_options_set_psk_selection_block { + void (^selection_block)(sec_protocol_metadata_t, dispatch_data_t, sec_protocol_pre_shared_key_selection_complete_t) = ^(__unused sec_protocol_metadata_t metadata, __unused dispatch_data_t psk_identity_hint, __unused sec_protocol_pre_shared_key_selection_complete_t complete) { + // pass + }; + dispatch_queue_t selection_queue = dispatch_queue_create("test_sec_protocol_options_set_psk_selection_block_queue", DISPATCH_QUEUE_SERIAL); + + sec_protocol_options_t options = [self create_sec_protocol_options]; + sec_protocol_options_set_pre_shared_key_selection_block(options, selection_block, selection_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); + XCTAssertTrue(content->psk_selection_block == selection_block); + XCTAssertTrue(content->psk_selection_queue != nil); + return false; + }); +} + +- (dispatch_data_t)create_random_dispatch_data { + uint8_t random[32]; + (void)SecRandomCopyBytes(NULL, sizeof(random), random); + return dispatch_data_create(random, sizeof(random), NULL, DISPATCH_DATA_DESTRUCTOR_DEFAULT); +} + +- (void)test_sec_protocol_metadata_access_psks { + __block dispatch_data_t psk_data = [self create_random_dispatch_data]; + __block dispatch_data_t psk_identity_data = [self create_random_dispatch_data]; + + sec_protocol_metadata_t metadata = [self create_sec_protocol_metadata]; + (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); + + content->pre_shared_keys = xpc_array_create(NULL, 0); + + xpc_object_t xpc_psk_data = xpc_data_create_with_dispatch_data(psk_data); + xpc_object_t xpc_psk_identity_data = xpc_data_create_with_dispatch_data(psk_identity_data); + + xpc_object_t tuple = xpc_array_create(NULL, 0); + xpc_array_set_value(tuple, XPC_ARRAY_APPEND, xpc_psk_data); + xpc_array_set_value(tuple, XPC_ARRAY_APPEND, xpc_psk_identity_data); + + xpc_array_set_value(content->pre_shared_keys, XPC_ARRAY_APPEND, tuple); + return true; + }); + + BOOL accessed = sec_protocol_metadata_access_pre_shared_keys(metadata, ^(dispatch_data_t psk, dispatch_data_t identity) { + XCTAssertTrue(sec_protocol_helper_dispatch_data_equal(psk, psk_data), @"Expected PSK data match"); + XCTAssertTrue(sec_protocol_helper_dispatch_data_equal(identity, psk_identity_data), @"Expected PSK identity data match"); + }); + XCTAssertTrue(accessed, @"Expected sec_protocol_metadata_access_pre_shared_keys to traverse PSK list"); +} + +@end diff --git a/protocol/SecProtocolTypes.h b/protocol/SecProtocolTypes.h index 98104cd9..b87ebedb 100644 --- a/protocol/SecProtocolTypes.h +++ b/protocol/SecProtocolTypes.h @@ -28,6 +28,8 @@ #include #include #include +#include +#include #ifndef SEC_OBJECT_IMPL /*! @@ -41,6 +43,132 @@ SEC_OBJECT_DECL(sec_identity); SEC_OBJECT_DECL(sec_certificate); #endif // !SEC_OBJECT_IMPL +/*! + * @enum tls_protocol_version_t enumeration + * @abstract Enumerations for the set of supported TLS and DTLS protocol versions. + * + * @constant tls_protocol_version_TLSv10 TLS 1.0 [https://tools.ietf.org/html/rfc4346] + * @constant tls_protocol_version_TLSv11 TLS 1.1 [https://tools.ietf.org/html/rfc2246] + * @constant tls_protocol_version_TLSv12 TLS 1.2 [https://tools.ietf.org/html/rfc5246] + * @constant tls_protocol_version_TLSv13 TLS 1.3 [https://tools.ietf.org/html/rfc8446] + * @constant tls_protocol_version_DTLSv10 DTLS 1.0 [https://tools.ietf.org/html/rfc4347] + * @constant tls_protocol_version_DTLSv12 DTLS 1.2 [https://tools.ietf.org/html/rfc6347] + */ +typedef CF_ENUM(uint16_t, tls_protocol_version_t) { + tls_protocol_version_TLSv10 CF_SWIFT_NAME(TLSv10) = 0x0301, + tls_protocol_version_TLSv11 CF_SWIFT_NAME(TLSv11) = 0x0302, + tls_protocol_version_TLSv12 CF_SWIFT_NAME(TLSv12) = 0x0303, + tls_protocol_version_TLSv13 CF_SWIFT_NAME(TLSv13) = 0x0304, + tls_protocol_version_DTLSv10 CF_SWIFT_NAME(DTLSv10) = 0xfeff, + tls_protocol_version_DTLSv12 CF_SWIFT_NAME(DTLSv12) = 0xfefd, +}; + +/*! + * @enum tls_ciphersuite_t enumeration + * @abstract Enumerations for the set of supported TLS and DTLS ciphersuites. + * + * See https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4 + * for ciphersuite codepoint allocations and reference RFCs. + * + * @constant tls_ciphersuite_RSA_WITH_3DES_EDE_CBC_SHA + * @constant tls_ciphersuite_RSA_WITH_AES_128_CBC_SHA + * @constant tls_ciphersuite_RSA_WITH_AES_256_CBC_SHA + * @constant tls_ciphersuite_RSA_WITH_AES_128_GCM_SHA256 + * @constant tls_ciphersuite_RSA_WITH_AES_256_GCM_SHA384 + * @constant tls_ciphersuite_RSA_WITH_AES_128_CBC_SHA256 + * @constant tls_ciphersuite_RSA_WITH_AES_256_CBC_SHA256 + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * @constant tls_ciphersuite_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + * @constant tls_ciphersuite_ECDHE_RSA_WITH_AES_128_CBC_SHA + * @constant tls_ciphersuite_ECDHE_RSA_WITH_AES_256_CBC_SHA + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * @constant tls_ciphersuite_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * @constant tls_ciphersuite_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * @constant tls_ciphersuite_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * @constant tls_ciphersuite_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * @constant tls_ciphersuite_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + * @constant tls_ciphersuite_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + * @constant tls_ciphersuite_AES_128_GCM_SHA256 + * @constant tls_ciphersuite_AES_256_GCM_SHA384 + * @constant tls_ciphersuite_CHACHA20_POLY1305_SHA256 + */ +typedef CF_ENUM(uint16_t, tls_ciphersuite_t) { + tls_ciphersuite_RSA_WITH_3DES_EDE_CBC_SHA CF_SWIFT_NAME(RSA_WITH_3DES_EDE_CBC_SHA) = 0x000A, + tls_ciphersuite_RSA_WITH_AES_128_CBC_SHA CF_SWIFT_NAME(RSA_WITH_AES_128_CBC_SHA) = 0x002F, + tls_ciphersuite_RSA_WITH_AES_256_CBC_SHA CF_SWIFT_NAME(RSA_WITH_AES_256_CBC_SHA) = 0x0035, + tls_ciphersuite_RSA_WITH_AES_128_GCM_SHA256 CF_SWIFT_NAME(RSA_WITH_AES_128_GCM_SHA256) = 0x009C, + tls_ciphersuite_RSA_WITH_AES_256_GCM_SHA384 CF_SWIFT_NAME(RSA_WITH_AES_256_GCM_SHA384) = 0x009D, + tls_ciphersuite_RSA_WITH_AES_128_CBC_SHA256 CF_SWIFT_NAME(RSA_WITH_AES_128_CBC_SHA256) = 0x003C, + tls_ciphersuite_RSA_WITH_AES_256_CBC_SHA256 CF_SWIFT_NAME(RSA_WITH_AES_256_CBC_SHA256) = 0x003D, + tls_ciphersuite_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA CF_SWIFT_NAME(ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA) = 0xC008, + tls_ciphersuite_ECDHE_ECDSA_WITH_AES_128_CBC_SHA CF_SWIFT_NAME(ECDHE_ECDSA_WITH_AES_128_CBC_SHA) = 0xC009, + tls_ciphersuite_ECDHE_ECDSA_WITH_AES_256_CBC_SHA CF_SWIFT_NAME(ECDHE_ECDSA_WITH_AES_256_CBC_SHA) = 0xC00A, + tls_ciphersuite_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA CF_SWIFT_NAME(ECDHE_RSA_WITH_3DES_EDE_CBC_SHA) = 0xC012, + tls_ciphersuite_ECDHE_RSA_WITH_AES_128_CBC_SHA CF_SWIFT_NAME(ECDHE_RSA_WITH_AES_128_CBC_SHA) = 0xC013, + tls_ciphersuite_ECDHE_RSA_WITH_AES_256_CBC_SHA CF_SWIFT_NAME(ECDHE_RSA_WITH_AES_256_CBC_SHA) = 0xC014, + tls_ciphersuite_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 CF_SWIFT_NAME(ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) = 0xC023, + tls_ciphersuite_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 CF_SWIFT_NAME(ECDHE_ECDSA_WITH_AES_256_CBC_SHA384) = 0xC024, + tls_ciphersuite_ECDHE_RSA_WITH_AES_128_CBC_SHA256 CF_SWIFT_NAME(ECDHE_RSA_WITH_AES_128_CBC_SHA256) = 0xC027, + tls_ciphersuite_ECDHE_RSA_WITH_AES_256_CBC_SHA384 CF_SWIFT_NAME(ECDHE_RSA_WITH_AES_256_CBC_SHA384) = 0xC028, + tls_ciphersuite_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 CF_SWIFT_NAME(ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) = 0xC02B, + tls_ciphersuite_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 CF_SWIFT_NAME(ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) = 0xC02C, + tls_ciphersuite_ECDHE_RSA_WITH_AES_128_GCM_SHA256 CF_SWIFT_NAME(ECDHE_RSA_WITH_AES_128_GCM_SHA256) = 0xC02F, + tls_ciphersuite_ECDHE_RSA_WITH_AES_256_GCM_SHA384 CF_SWIFT_NAME(ECDHE_RSA_WITH_AES_256_GCM_SHA384) = 0xC030, + tls_ciphersuite_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 CF_SWIFT_NAME(ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) = 0xCCA8, + tls_ciphersuite_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 CF_SWIFT_NAME(ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) = 0xCCA9, + tls_ciphersuite_AES_128_GCM_SHA256 CF_SWIFT_NAME(AES_128_GCM_SHA256) = 0x1301, + tls_ciphersuite_AES_256_GCM_SHA384 CF_SWIFT_NAME(AES_256_GCM_SHA384) = 0x1302, + tls_ciphersuite_CHACHA20_POLY1305_SHA256 CF_SWIFT_NAME(CHACHA20_POLY1305_SHA256) = 0x1303, +}; + +/*! + * @enum tls_ciphersuite_group_t enumeration + * @abstract Convenience ciphersuite groups that collate ciphersuites of comparable security + * properties into a single alias. + * + * @constant tls_ciphersuite_group_default + * @constant tls_ciphersuite_group_compatibility + * @constant tls_ciphersuite_group_legacy + * @constant tls_ciphersuite_group_ats + * @constant tls_ciphersuite_group_ats_compatibility + */ +typedef CF_ENUM(uint16_t, tls_ciphersuite_group_t) { + tls_ciphersuite_group_default, + tls_ciphersuite_group_compatibility, + tls_ciphersuite_group_legacy, + tls_ciphersuite_group_ats, + tls_ciphersuite_group_ats_compatibility, +}; + +/*! + * @enum SSLProtocol enumeration + * @abstract Enumerations for the set of supported TLS and DTLS protocol versions. + * + * @note This enumeration is deprecated. Use `tls_protocol_version_t` instead. + */ +typedef CF_ENUM(int, SSLProtocol) { + kSSLProtocolUnknown CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 0, + kTLSProtocol1 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 4, + kTLSProtocol11 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 7, + kTLSProtocol12 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 8, + kDTLSProtocol1 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 9, + kTLSProtocol13 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 10, + kDTLSProtocol12 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 11, + kTLSProtocolMaxSupported CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 999, + kSSLProtocol2 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 1, + kSSLProtocol3 CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 2, + kSSLProtocol3Only CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 3, + kTLSProtocol1Only CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 5, + kSSLProtocolAll CF_ENUM_DEPRECATED(10_2, 10_15, 5_0, 13_0) = 6, +}; + +__BEGIN_DECLS + SEC_ASSUME_NONNULL_BEGIN /*! @@ -56,7 +184,7 @@ SEC_ASSUME_NONNULL_BEGIN */ 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); +sec_trust_create(SecTrustRef trust); /*! * @function sec_trust_copy_ref @@ -71,7 +199,7 @@ sec_trust_create(SecTrustRef __nonnull trust); */ API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)) SecTrustRef -sec_trust_copy_ref(sec_trust_t __nonnull trust); +sec_trust_copy_ref(sec_trust_t trust); /*! * @function sec_identity_create @@ -86,7 +214,7 @@ sec_trust_copy_ref(sec_trust_t __nonnull trust); */ 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); +sec_identity_create(SecIdentityRef identity); /*! * @function sec_identity_create_with_certificates @@ -105,7 +233,28 @@ sec_identity_create(SecIdentityRef __nonnull identity); */ 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); +sec_identity_create_with_certificates(SecIdentityRef identity, CFArrayRef certificates); + +#ifdef __BLOCKS__ +/*! + * @function sec_identity_access_certificates + * + * @abstract + * Access the certificates associated with the `sec_identity_t` instance. + * + * @param identity + * A `sec_identity_t` instance. + * + * @param handler + * A block to invoke one or more times with `sec_certificate_t` instances. + * + * @return Returns true if the peer certificates were accessible, false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_identity_access_certificates(sec_identity_t identity, + void (^handler)(sec_certificate_t certificate)); +#endif // __BLOCKS__ /*! * @function sec_identity_copy_ref @@ -119,8 +268,8 @@ sec_identity_create_with_certificates(SecIdentityRef __nonnull identity, CFArray * @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); +_Nullable SecIdentityRef +sec_identity_copy_ref(sec_identity_t identity); /*! * @function sec_identity_copy_certificates_ref @@ -134,8 +283,8 @@ sec_identity_copy_ref(sec_identity_t __nonnull identity); * @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); +_Nullable CFArrayRef +sec_identity_copy_certificates_ref(sec_identity_t identity); /*! * @function sec_certificate_create @@ -150,7 +299,7 @@ sec_identity_copy_certificates_ref(sec_identity_t __nonnull identity); */ 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); +sec_certificate_create(SecCertificateRef certificate); /*! * @function sec_certificate_copy_ref @@ -165,8 +314,10 @@ sec_certificate_create(SecCertificateRef __nonnull certificate); */ 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_certificate_copy_ref(sec_certificate_t certificate); SEC_ASSUME_NONNULL_END +__END_DECLS + #endif // SecProtocolTypes_h diff --git a/protocol/SecProtocolTypes.m b/protocol/SecProtocolTypes.m index 04666e39..b5258fff 100644 --- a/protocol/SecProtocolTypes.m +++ b/protocol/SecProtocolTypes.m @@ -3,7 +3,8 @@ // Security // -#include "utilities/SecCFRelease.h" +#import "utilities/SecCFRelease.h" +#import "utilities/SecCFWrappers.h" #define OS_OBJECT_HAVE_OBJC_SUPPORT 1 @@ -16,30 +17,30 @@ #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_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_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_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(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_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 @@ -47,15 +48,20 @@ 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_protocol_configuration_builder); SEC_OBJECT_DECL_INTERNAL_OBJC(sec_object); SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_options); SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_metadata); +SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_configuration); +#import "SecProtocolInternal.h" #import +#import "SecProtocolTypesPriv.h" #import #import +#import + #import #import @@ -71,98 +77,101 @@ SEC_OBJECT_DECL_INTERNAL_OBJC(sec_protocol_metadata); SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_array, { - xpc_object_t xpc_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; + 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; - } + 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]; + 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 - } + 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; + 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; + 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; + SecIdentityRef identity; CFArrayRef certs; + sec_protocol_private_key_sign_t sign_block; + sec_protocol_private_key_decrypt_t decrypt_block; + dispatch_queue_t operation_queue; }); @implementation SEC_CONCRETE_CLASS_NAME(sec_identity) - (instancetype)initWithIdentity:(SecIdentityRef)_identity { - if (_identity == NULL) { - return SEC_NIL_BAD_INPUT; - } + 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; + 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 @@ -181,23 +190,48 @@ SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_identity, return self; } +- (instancetype)initWithCertificates:(CFArrayRef)certificates signBlock:(sec_protocol_private_key_sign_t)sign decryptBlock:(sec_protocol_private_key_decrypt_t)decrypt queue:(dispatch_queue_t)queue +{ + if (certificates == NULL) { + return SEC_NIL_BAD_INPUT; + } + if (sign == NULL) { + return SEC_NIL_BAD_INPUT; + } + if (decrypt == NULL) { + return SEC_NIL_BAD_INPUT; + } + + self = [super init]; + if (self == nil) { + return SEC_NIL_OUT_OF_MEMORY; + } + + self->certs = __DECONST(CFArrayRef, CFRetainSafe(certificates)); + self->sign_block = sign; + self->decrypt_block = decrypt; + self->operation_queue = queue; + + return self; +} + - (void)dealloc { - if (self->identity != NULL) { - CFRelease(self->identity); - self->identity = NULL; + 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]; + return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithIdentity:identity]; } sec_identity_t @@ -206,16 +240,25 @@ sec_identity_create_with_certificates(SecIdentityRef identity, CFArrayRef certif return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithIdentityAndCertificates:identity certificates:certificates]; } +sec_identity_t +sec_identity_create_with_certificates_and_external_private_key(CFArrayRef __nonnull certificates, + sec_protocol_private_key_sign_t sign_block, + sec_protocol_private_key_decrypt_t decrypt_block, + dispatch_queue_t queue) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_identity) alloc] initWithCertificates:certificates signBlock:sign_block decryptBlock:decrypt_block queue:queue]; +} + 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; + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->identity != NULL) { + return __DECONST(SecIdentityRef, CFRetain(object->identity)); + } + return SEC_NULL_BAD_INPUT; } CFArrayRef @@ -230,188 +273,296 @@ sec_identity_copy_certificates_ref(sec_identity_t object) return SEC_NULL_BAD_INPUT; } +bool +sec_identity_access_certificates(sec_identity_t identity, + void (^handler)(sec_certificate_t certificate)) +{ + if (identity == NULL) { + return false; + } + if (identity->certs != NULL) { + CFArrayForEach(identity->certs, ^(const void *value) { + SecCertificateRef certificate_ref = (SecCertificateRef)value; + if (certificate_ref != NULL) { + sec_certificate_t certificate = sec_certificate_create(certificate_ref); + handler(certificate); + } + }); + return true; + } + return false; +} + +bool +sec_identity_has_certificates(sec_identity_t identity) +{ + if (identity == NULL) { + return false; + } + return identity->certs != NULL; +} + +sec_protocol_private_key_sign_t +sec_identity_copy_private_key_sign_block(sec_identity_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->sign_block != NULL) { + return object->sign_block; + } + return SEC_NIL_BAD_INPUT; +} + +sec_protocol_private_key_decrypt_t +sec_identity_copy_private_key_decrypt_block(sec_identity_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->decrypt_block != NULL) { + return object->decrypt_block; + } + return SEC_NIL_BAD_INPUT; +} + +dispatch_queue_t +sec_identity_copy_private_key_queue(sec_identity_t object) +{ + if (object == NULL) { + return SEC_NULL_BAD_INPUT; + } + if (object->operation_queue != nil) { + return object->operation_queue; + } + return SEC_NIL_BAD_INPUT; +} + + @end SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_certificate, { - SecCertificateRef certificate; + SecCertificateRef certificate; }); @implementation SEC_CONCRETE_CLASS_NAME(sec_certificate) - (instancetype)initWithCertificate:(SecCertificateRef)_certificate { - if (_certificate == NULL) { - return SEC_NIL_BAD_INPUT; - } + 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; + 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; - } + 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]; + 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; + 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; + SecTrustRef trust; }); @implementation SEC_CONCRETE_CLASS_NAME(sec_trust) - (instancetype)initWithTrust:(SecTrustRef)_trust { - if (_trust == NULL) { - return SEC_NIL_BAD_INPUT; - } + 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; + 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; - } + 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]; + 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; + 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, +static bool +_is_apple_bundle(void) +{ + static dispatch_once_t onceToken; + static bool result = false; + dispatch_once(&onceToken, ^{ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFStringRef bundleID = CFBundleGetIdentifier(bundle); + result = !bundleID || CFStringHasPrefix(bundleID, CFSTR("com.apple.")); + }); + return result; +} + +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_protocol_configuration_builder, { - uint16_t type; - sec_protocol_tls_ext_add_callback adder; - sec_protocol_tls_ext_parse_callback parser; - sec_protocol_tls_ext_free_callback freer; +@package + CFDictionaryRef dictionary; + bool is_apple; }); -@implementation SEC_CONCRETE_CLASS_NAME(sec_tls_extension) +@implementation SEC_CONCRETE_CLASS_NAME(sec_protocol_configuration_builder) -- (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; +- (id)init { + self = [super init]; + if (self) { + CFBundleRef bundle = CFBundleGetMainBundle(); + if (bundle != NULL) { + CFTypeRef rawATS = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR(kATSInfoKey)); + self->dictionary = (CFDictionaryRef)rawATS; + CFRetainSafe(self->dictionary); + self->is_apple = _is_apple_bundle(); + } } + return self; +} +- (id)initWithDictionary:(CFDictionaryRef)dict andInternalFlag:(bool)flag { self = [super init]; - if (self == nil) { - return SEC_NIL_OUT_OF_MEMORY; + if (self) { + self->dictionary = dict; + CFRetainSafe(dict); + self->is_apple = flag; } - - 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) +@end + +sec_protocol_configuration_builder_t +sec_protocol_configuration_builder_copy_default() { - if (extension == NULL) { - return 0; - } + return [[SEC_CONCRETE_CLASS_NAME(sec_protocol_configuration_builder) alloc] init]; +} - return extension->type; +sec_protocol_configuration_builder_t +sec_protocol_configuration_builder_create(CFDictionaryRef dictionary, bool is_apple) +{ + return [[SEC_CONCRETE_CLASS_NAME(sec_protocol_configuration_builder) alloc] initWithDictionary:dictionary andInternalFlag:is_apple]; } -sec_protocol_tls_ext_add_callback -sec_tls_extension_copy_add_block(sec_tls_extension_t extension) +CFDictionaryRef +sec_protocol_configuration_builder_get_ats_dictionary(sec_protocol_configuration_builder_t builder) { - if (extension == NULL) { - return SEC_NULL_BAD_INPUT; - } + return builder->dictionary; +} - return extension->adder; +bool +sec_protocol_configuration_builder_get_is_apple_bundle(sec_protocol_configuration_builder_t builder) +{ + return builder->is_apple; } -sec_protocol_tls_ext_parse_callback -sec_tls_extension_copy_parse_block(sec_tls_extension_t extension) +SEC_OBJECT_IMPL_INTERNAL_OBJC(sec_protocol_configuration, { - if (extension == NULL) { - return SEC_NULL_BAD_INPUT; - } + xpc_object_t dictionary; +}); - return extension->parser; +@implementation SEC_CONCRETE_CLASS_NAME(sec_protocol_configuration) + +- (id)init { + self = [super init]; + if (self) { + self->dictionary = xpc_dictionary_create(NULL, NULL, 0); + } + return self; } -sec_protocol_tls_ext_free_callback -sec_tls_extension_copy_free_block(sec_tls_extension_t extension) +static sec_protocol_configuration_t +sec_protocol_configuration_create(void) { - if (extension == NULL) { - return SEC_NULL_BAD_INPUT; - } + return [[SEC_CONCRETE_CLASS_NAME(sec_protocol_configuration) alloc] init]; +} + +sec_protocol_configuration_t +sec_protocol_configuration_create_with_builder(sec_protocol_configuration_builder_t builder) +{ + sec_protocol_configuration_t configuration = sec_protocol_configuration_create(); + if (configuration) { + if (builder->is_apple) { + os_log_debug(OS_LOG_DEFAULT, "Building default configuration for first-party bundle"); + sec_protocol_configuration_populate_insecure_defaults(configuration); + } else { + os_log_debug(OS_LOG_DEFAULT, "Building default configuration for third-party bundle"); + sec_protocol_configuration_populate_secure_defaults(configuration); + } - return extension->freer; + sec_protocol_configuration_register_builtin_exceptions(configuration); + CFDictionaryRef dictionary = builder->dictionary; + if (dictionary) { + os_log_debug(OS_LOG_DEFAULT, "Setting configuration overrides based on AppTransportSecurity exceptions"); + sec_protocol_configuration_set_ats_overrides(configuration, dictionary); + } else { + os_log_debug(OS_LOG_DEFAULT, "Using default configuration settings"); + } + } else { + os_log_error(OS_LOG_DEFAULT, "sec_protocol_configuration_create failed"); + } + return configuration; } -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) +xpc_object_t +sec_protocol_configuration_get_map(sec_protocol_configuration_t configuration) { - return [[SEC_CONCRETE_CLASS_NAME(sec_tls_extension) alloc] initWithCallbacks:type adder:adder parser:parser freer:freer]; + return configuration->dictionary; } @end - diff --git a/protocol/SecProtocolTypesPriv.h b/protocol/SecProtocolTypesPriv.h new file mode 100644 index 00000000..3f0344bb --- /dev/null +++ b/protocol/SecProtocolTypesPriv.h @@ -0,0 +1,127 @@ +/* + * 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 SecProtocolTypesPriv_h +#define SecProtocolTypesPriv_h + +#include + +__BEGIN_DECLS + +SEC_ASSUME_NONNULL_BEGIN + +/*! + * @function sec_identity_create_with_certificates_and_external_private_key + * + * @abstract + * Create an ARC-able `sec_identity_t` instance from an array of `SecCertificateRef` + * instances and blocks to be invoked for private key opertions. Callers may use this + * constructor to build a `sec_identity_t` instance with an external private key. + * + * @param certificates + * An array of `SecCertificateRef` instances. + * + * @param sign_block + * A `sec_protocol_private_key_sign_t` block. + * + * @param decrypt_block + * A `sec_protocol_private_key_decrypt_t` block. + * + * @param operation_queue + * The `dispatch_queue_t` queue on which each private key operation is invoked. + * + * @return a `sec_identity_t` instance. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED _Nullable sec_identity_t +sec_identity_create_with_certificates_and_external_private_key(CFArrayRef certificates, + sec_protocol_private_key_sign_t sign_block, + sec_protocol_private_key_decrypt_t decrypt_block, + dispatch_queue_t operation_queue); + +/*! + * @function sec_identity_copy_private_key_sign_block + * + * @abstract + * Copy a retained reference to the underlying `sec_protocol_private_key_sign_t` used by the identity. + * + * @param identity + * A `sec_identity_t` instance. + * + * @return a `sec_protocol_private_key_sign_t` block, or nil. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED _Nullable sec_protocol_private_key_sign_t +sec_identity_copy_private_key_sign_block(sec_identity_t identity); + +/*! + * @function sec_identity_copy_private_key_decrypt_block + * + * @abstract + * Copy a retained reference to the underlying `sec_protocol_private_key_decrypt_t` used by the identity. + * + * @param identity + * A `sec_identity_t` instance. + * + * @return a `sec_protocol_private_key_decrypt_t` block, or nil. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED _Nullable sec_protocol_private_key_decrypt_t +sec_identity_copy_private_key_decrypt_block(sec_identity_t identity); + +/*! + * @function sec_identity_copy_private_key_queue + * + * @abstract + * Copy a retained reference to the `dispatch_queue_t` to be used by external private key + * operations, if any. + * + * @param identity + * A `sec_identity_t` instance. + * + * @return a `dispatch_queue_t` queue, or nil. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +SEC_RETURNS_RETAINED _Nullable dispatch_queue_t +sec_identity_copy_private_key_queue(sec_identity_t identity); + +/*! + * @function sec_identity_has_certificates + * + * @abstract + * Determine if the `sec_identity_t` has a list of certificates associated with it. + * + * @param identity + * A `sec_identity_t` instance. + * + * @return True if the identity has certificates associated with it, and false otherwise. + */ +API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) +bool +sec_identity_has_certificates(sec_identity_t identity); + +SEC_ASSUME_NONNULL_END + +__END_DECLS + +#endif // SecProtocolTypesPriv_h diff --git a/protocol/test_data/builtins.json b/protocol/test_data/builtins.json new file mode 100644 index 00000000..a71403d7 --- /dev/null +++ b/protocol/test_data/builtins.json @@ -0,0 +1,46 @@ +{ + "NSExceptionDomains": { + "apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.2", + "NSExceptionRequiresForwardSecrecy": false + }, + "ls.apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "gs.apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "geo.apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "is.autonavi.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "apple-mapkit.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "setup.icloud.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.2", + "NSExceptionRequiresForwardSecrecy": false + } + } +} \ No newline at end of file diff --git a/protocol/test_data/example1.json b/protocol/test_data/example1.json new file mode 100644 index 00000000..aa62c08e --- /dev/null +++ b/protocol/test_data/example1.json @@ -0,0 +1,50 @@ +{ + "NSAllowsArbitraryLoads": false, + "NSAllowsArbitraryLoadsForMedia": false, + "NSAllowsArbitraryLoadsInWebContent": false, + "NSAllowsLocalNetworking": false, + "NSExceptionDomains": { + "apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.2", + "NSExceptionRequiresForwardSecrecy": false + }, + "ls.apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "gs.apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "geo.apple.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "is.autonavi.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "apple-mapkit.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.0", + "NSExceptionRequiresForwardSecrecy": false + }, + "setup.icloud.com": { + "NSIncludesSubdomains": true, + "NSExceptionAllowsInsecureHTTPLoads": true, + "NSExceptionMinimumTLSVersion": "TLSv1.2", + "NSExceptionRequiresForwardSecrecy": false + } + } +} \ No newline at end of file diff --git a/resources/English.lproj/Certificate.strings b/resources/en.lproj/Certificate.strings similarity index 98% rename from resources/English.lproj/Certificate.strings rename to resources/en.lproj/Certificate.strings index f37a57812e64b184b9e4c5eadf1b3a77a82cd7c5..de08b4c62f8014572cf62631b49757c51a830feb 100644 GIT binary patch delta 52 zcmdmXnsLi%#tkeSlLK_wHgj-HP-iTjY^Wx>d4v8hw#hmy5}S{hv9N(9&)BpmZw^XG GVFdu|fD$YK delta 46 zcmV+}0MY-n%K^5_0k8xJvjzy1CzCv77_+c1`UU|flPd%nv%)q62D8XKh$8_fvrk}U E1(U@PCjbBd diff --git a/resources/English.lproj/CloudKeychain.strings b/resources/en.lproj/CloudKeychain.strings similarity index 98% rename from resources/English.lproj/CloudKeychain.strings rename to resources/en.lproj/CloudKeychain.strings index e1ba3019a97f53149bf26958a3b401a17fde30e8..350e7a8f2ab3cc46e682dd9fa06059a1efe837e4 100644 GIT binary patch delta 28 ecmewq`73h69I?qFd_t2~i3LDusm)5_7eoQ8)e3L` delta 28 icmewr`6+V49I?p{#Q7!*h)YdAA!Y_*Zx#@LB?-{icqP*fU4q@jvOA@AXBx;dJc;Kii<=5 delta 13 Ucmdnj#(1HTaf6n_R diff --git a/header_symlinks/Security/SecRandomP.h b/rio.yml similarity index 100% rename from header_symlinks/Security/SecRandomP.h rename to rio.yml diff --git a/secacltests/sec_acl_stress.c b/secacltests/sec_acl_stress.c index 0d0f6378..f009993a 100644 --- a/secacltests/sec_acl_stress.c +++ b/secacltests/sec_acl_stress.c @@ -21,19 +21,12 @@ #include "testlist.h" -#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR) -#define USE_KEYSTORE 1 -#elif TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR -#define USE_KEYSTORE 1 -#else /* no keystore on this platform */ -#define USE_KEYSTORE 0 -#endif #if USE_KEYSTORE #include #endif -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR #include #endif @@ -48,7 +41,7 @@ enum ItemAttrType { kAccessGroupItemAttr, }; -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR CFStringRef temporaryPasscode = CFSTR("1111"); static bool changePasscode(CFStringRef oldPasscode, CFStringRef newPasscode) { @@ -70,7 +63,7 @@ static bool changePasscode(CFStringRef oldPasscode, CFStringRef newPasscode) } #endif -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR static void WithEachString(void(^each)(CFStringRef attr, enum ItemAttrType atype), ...) { va_list ap; va_start(ap, each); @@ -258,7 +251,7 @@ static void tests(bool isPasscodeSet) is_status(SecItemCopyMatching(item, NULL), errSecItemNotFound, "do not find sync"); CFDictionarySetValue(item, kSecAttrSynchronizable, kCFBooleanFalse); -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR assert(protection); SecAccessControlRef privateKeyUsageAclRef = SecAccessControlCreateWithFlags(kCFAllocatorDefault, protection, kSecAccessControlPrivateKeyUsage, NULL); ok(privateKeyUsageAclRef, "Create SecAccessControlRef for kSecAccessControlPrivateKeyUsage"); @@ -318,7 +311,7 @@ static void tests(bool isPasscodeSet) int sec_acl_stress(int argc, char *const *argv) { -#if TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR bool removeTemporaryPasscode = false; bool isPasscodeSet = false; if (MKBGetDeviceLockState(NULL) == kMobileKeyBagDisabled) { @@ -332,7 +325,7 @@ int sec_acl_stress(int argc, char *const *argv) if (removeTemporaryPasscode) { changePasscode(temporaryPasscode, NULL); } -#elif TARGET_OS_MAC && !TARGET_IPHONE_SIMULATOR +#elif TARGET_OS_MAC && !TARGET_OS_SIMULATOR plan_tests(152); tests(false); #else diff --git a/secacltests/secacltests-entitlements.plist b/secacltests/secacltests-entitlements.plist index a154323d..c635aaf3 100644 --- a/secacltests/secacltests-entitlements.plist +++ b/secacltests/secacltests-entitlements.plist @@ -8,6 +8,8 @@ com.apple.keystore.device + com.apple.private.applecredentialmanager.allow + com.apple.springboard.wipedevice application-identifier diff --git a/secdtests/secdtests-entitlements.plist b/secdtests/secdtests-entitlements.plist index 52031c93..d9ca668f 100644 --- a/secdtests/secdtests-entitlements.plist +++ b/secdtests/secdtests-entitlements.plist @@ -22,6 +22,8 @@ com.apple.keystore.device + com.apple.private.applecredentialmanager.allow + restore-keychain migrate-keychain diff --git a/secdxctests/KeychainAPITests.m b/secdxctests/KeychainAPITests.m index 6252bc0c..d2cdeec2 100644 --- a/secdxctests/KeychainAPITests.m +++ b/secdxctests/KeychainAPITests.m @@ -37,6 +37,10 @@ #import #import #import +#include +#include +#include +#include void* testlist = NULL; @@ -50,17 +54,19 @@ void* testlist = NULL; + (void)setUp { [super setUp]; - SecCKKSDisable(); securityd_init(NULL); } +- (NSString*)nameOfTest +{ + return [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]][1]; +} + - (void)setUp { [super setUp]; - - NSArray* partsOfName = [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]]; - secd_test_setup_temp_keychain([partsOfName[1] UTF8String], NULL); + // KeychainXCTest already sets up keychain with custom test-named directory } - (void)testReturnValuesInSecItemUpdate @@ -69,14 +75,14 @@ void* testlist = NULL; (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES) }; NSDictionary* updateQueryWithNoReturn = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) + (id)kSecUseDataProtectionKeychain : @(YES) }; CFTypeRef result = NULL; @@ -128,6 +134,130 @@ void* testlist = NULL; #endif } +#pragma mark - Corruption Tests + +const uint8_t keychain_data[] = { + 0x62, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x30, 0x30, 0xd2, 0x01, 0x02, 0x03, + 0x04, 0x5f, 0x10, 0x1b, 0x4e, 0x53, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, + 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x20, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x5f, 0x10, 0x1d, 0x4e, 0x53, + 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x46, 0x72, 0x61, 0x6d, 0x65, + 0x20, 0x41, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x54, 0x68, 0x69, 0x73, 0x20, + 0x4d, 0x61, 0x63, 0x5f, 0x10, 0x1c, 0x32, 0x38, 0x20, 0x33, 0x37, 0x33, + 0x20, 0x33, 0x34, 0x36, 0x20, 0x32, 0x39, 0x30, 0x20, 0x30, 0x20, 0x30, + 0x20, 0x31, 0x34, 0x34, 0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x5f, 0x10, + 0x1d, 0x35, 0x36, 0x38, 0x20, 0x33, 0x39, 0x35, 0x20, 0x33, 0x30, 0x37, + 0x20, 0x33, 0x37, 0x39, 0x20, 0x30, 0x20, 0x30, 0x20, 0x31, 0x34, 0x34, + 0x30, 0x20, 0x38, 0x37, 0x38, 0x20, 0x08, 0x0d, 0x2b, 0x4b, 0x6a, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a +}; + +dispatch_semaphore_t sema = NULL; + +// The real corruption exit handler should xpc_transaction_exit_clean, +// let's be certain it does not. Also make sure exit handler gets called at all +static void SecDbTestCorruptionHandler(void) +{ + dispatch_semaphore_signal(sema); +} + +- (void)testCorruptionHandler { + SecDbCorruptionExitHandler = SecDbTestCorruptionHandler; + sema = dispatch_semaphore_create(0); + + secd_test_setup_temp_keychain([[NSString stringWithFormat:@"%@-bad", [self nameOfTest]] UTF8String], ^{ + CFStringRef keychain_path_cf = __SecKeychainCopyPath(); + + CFStringPerformWithCString(keychain_path_cf, ^(const char *keychain_path) { + int fd = open(keychain_path, O_RDWR | O_CREAT | O_TRUNC, 0644); + XCTAssert(fd > -1, "Could not open fd to write keychain: %{darwin.errno}d", errno); + + size_t written = write(fd, keychain_data, sizeof(keychain_data)); + XCTAssertEqual(written, sizeof(keychain_data), "Write garbage to disk, got %lu instead of %lu: %{darwin.errno}d", written, sizeof(keychain_data), errno); + XCTAssertEqual(close(fd), 0, "Close keychain file failed: %{darwin.errno}d", errno); + }); + + CFReleaseNull(keychain_path_cf); + }); + + NSDictionary* query = @{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecUseDataProtectionKeychain : @(YES), + (id)kSecReturnAttributes : @(YES) + }; + + CFTypeRef result = NULL; + // Real keychain should xpc_transaction_exit_clean() after this, but we nerfed it + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, &result), errSecNotAvailable, "Expected badness from corrupt keychain"); + XCTAssertEqual(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC)), 0, "Timed out waiting for corruption exit handler"); + + sema = NULL; + SecDbResetCorruptionExitHandler(); + CFReleaseNull(result); + + NSString* markerpath = [NSString stringWithFormat:@"%@-iscorrupt", CFBridgingRelease(__SecKeychainCopyPath())]; + struct stat info = {}; + XCTAssertEqual(stat([markerpath UTF8String], &info), 0, "Unable to stat corruption marker: %{darwin.errno}d", errno); +} + +- (void)testRecoverFromCorruption { + // Setup does a reset, but that doesn't create the db yet so let's sneak in first + __block struct stat before = {}; + WithPathInKeychainDirectory(CFSTR("keychain-2.db"), ^(const char *filename) { + FILE* file = fopen(filename, "w"); + XCTAssert(file != NULL, "Didn't get a FILE pointer"); + fclose(file); + XCTAssertEqual(stat(filename, &before), 0, "Unable to stat newly created file"); + }); + + WithPathInKeychainDirectory(CFSTR("keychain-2.db-iscorrupt"), ^(const char *filename) { + FILE* file = fopen(filename, "w"); + XCTAssert(file != NULL, "Didn't get a FILE pointer"); + fclose(file); + }); + + NSMutableDictionary* query = [@{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrService : @"TestService", + (id)kSecUseDataProtectionKeychain : @(YES), + (id)kSecReturnAttributes : @(YES) + } mutableCopy]; + CFTypeRef result = NULL; + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)query, &result), errSecSuccess, @"Should have added item to keychain"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd"); + CFReleaseNull(result); + + query[(id)kSecValueData] = nil; + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, &result), errSecSuccess, @"Should have found item in keychain"); + XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemCopyMatching"); + CFReleaseNull(result); + + XCTAssertEqual(SecItemDelete((__bridge CFDictionaryRef)query), errSecSuccess, @"Should have deleted item from keychain"); + + WithPathInKeychainDirectory(CFSTR("keychain-2.db-iscorrupt"), ^(const char *filename) { + struct stat markerinfo = {}; + XCTAssertNotEqual(stat(filename, &markerinfo), 0, "Expected not to find corruption marker after killing keychain"); + }); + + __block struct stat after = {}; + WithPathInKeychainDirectory(CFSTR("keychain-2.db"), ^(const char *filename) { + FILE* file = fopen(filename, "w"); + XCTAssert(file != NULL, "Didn't get a FILE pointer"); + fclose(file); + XCTAssertEqual(stat(filename, &after), 0, "Unable to stat newly created file"); + }); + + if (before.st_birthtimespec.tv_sec == after.st_birthtimespec.tv_sec) { + XCTAssertLessThan(before.st_birthtimespec.tv_nsec, after.st_birthtimespec.tv_nsec, "db was not deleted and recreated"); + } else { + XCTAssertLessThan(before.st_birthtimespec.tv_sec, after.st_birthtimespec.tv_sec, "db was not deleted and recreated"); + } +} + @end #endif diff --git a/secdxctests/KeychainCryptoTests.m b/secdxctests/KeychainCryptoTests.m index 552e76d1..1cd6e95e 100644 --- a/secdxctests/KeychainCryptoTests.m +++ b/secdxctests/KeychainCryptoTests.m @@ -26,6 +26,7 @@ #import "SecdTestKeychainUtilities.h" #import "CKKS.h" #import "SecDbKeychainItemV7.h" +#import "SecDbKeychainMetadataKeyStore.h" #import "SecItemPriv.h" #import "SecItemServer.h" #import "spi.h" @@ -47,7 +48,7 @@ @end #if USE_KEYSTORE -#import +#include "OSX/utilities/SecAKSWrappers.h" @interface KeychainCryptoTests : KeychainXCTest @end @@ -92,7 +93,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecAttrAccount : account, (id)kSecAttrService : [NSString stringWithFormat:@"%@-Service", account], (id)kSecAttrAccessible : (id)accessible, - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES), }; CFTypeRef result = NULL; @@ -101,7 +102,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { 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); + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), code, @"Should have failed to adding test item to keychain with code %d", (int)code); XCTAssertNil((__bridge id)result, @"Should not have received a dictionary back from SecItemAdd"); } @@ -113,7 +114,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { NSDictionary* findQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : account, (id)kSecAttrService : [NSString stringWithFormat:@"%@-Service", account], - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES), }; CFTypeRef result = NULL; @@ -122,7 +123,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { 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); + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), code, @"Should have failed to find items in keychain with code %d", (int)code); XCTAssertNotNil((__bridge id)result, @"Should not have received a dictionary back from SecItemCopyMatching"); } @@ -174,7 +175,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -189,7 +190,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { NSMutableDictionary* dataQuery = [(__bridge NSDictionary*)foundItem mutableCopy]; dataQuery[(id)kSecReturnData] = @(YES); dataQuery[(id)kSecClass] = (id)kSecClassGenericPassword; - dataQuery[(id)kSecAttrNoLegacy] = @(YES); + dataQuery[(id)kSecUseDataProtectionKeychain] = @(YES); result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); XCTAssertEqual(result, 0, @"failed to find the data for the item we just added to the keychain"); @@ -210,7 +211,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, (id)kSecValueRef : (__bridge id)key, (id)kSecAttrLabel : @"TestLabel", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -233,7 +234,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -255,7 +256,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -273,9 +274,12 @@ static keyclass_t parse_keyclass(CFTypeRef value) { - (SecDbKeychainSerializedItemV7*)serializedItemWithPassword:(NSString*)password metadataAttributes:(NSDictionary*)metadata { + NSError* error; SecDbKeychainItemV7* item = [[SecDbKeychainItemV7 alloc] initWithSecretAttributes:@{(id)kSecValueData : password} metadataAttributes:metadata tamperCheck:[[NSUUID UUID] UUIDString] keyclass:9]; - [item encryptMetadataWithKeybag:0 error:nil]; - [item encryptSecretDataWithKeybag:0 accessControl:SecAccessControlCreate(NULL, NULL) acmContext:nil error:nil]; + [item encryptMetadataWithKeybag:0 error:&error]; + XCTAssertNil(error, @"Successfully encrypted metadata"); + [item encryptSecretDataWithKeybag:0 accessControl:SecAccessControlCreate(NULL, NULL) acmContext:nil error:&error]; + XCTAssertNil(error, @"Successfully encrypted secret data"); SecDbKeychainSerializedItemV7* serializedItem = [[SecDbKeychainSerializedItemV7 alloc] init]; serializedItem.encryptedMetadata = item.encryptedMetadataBlob; serializedItem.encryptedSecretData = item.encryptedSecretDataBlob; @@ -305,7 +309,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES }; + (id)kSecUseDataProtectionKeychain : @YES }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -321,7 +325,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { CFReleaseNull(foundItem); self.lockState = LockStateLockedAndDisallowAKS; - + result = SecItemCopyMatching((__bridge CFDictionaryRef)dataQuery, &foundItem); XCTAssertEqual(result, errSecInteractionNotAllowed, @"get the lock error"); XCTAssertEqual(foundItem, NULL, @"got item anyway: %@", foundItem); @@ -392,7 +396,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES }; + (id)kSecUseDataProtectionKeychain : @YES }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -416,12 +420,12 @@ static keyclass_t parse_keyclass(CFTypeRef value) { 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 + // Just calling SecItemCopyMatching shouldn't have created a new metadata key [self checkDatabaseExistenceOfMetadataKey:key_class_ak shouldExist:false]; - /* semantics are odd, we should be able to delete it */ + /* CopyMatching will delete corrupt pre-emptively */ result = SecItemDelete((__bridge CFDictionaryRef)dataQuery); - XCTAssertEqual(result, 0, @"failed to delete item"); + XCTAssertEqual(result, -25300, @"corrupt item was not deleted for us"); } - (void)testKeychainCorruptionAddOverCorruptedEntry @@ -432,7 +436,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES }; + (id)kSecUseDataProtectionKeychain : @YES }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -462,7 +466,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", (id)kSecAttrAccessible : (id)kSecAttrAccessibleWhenUnlocked, - (id)kSecAttrNoLegacy : @YES }; + (id)kSecUseDataProtectionKeychain : @YES }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -491,11 +495,6 @@ static keyclass_t parse_keyclass(CFTypeRef value) { XCTAssertEqual(result, 0, @"failed to delete item"); } -- (id)encryptionOperation -{ - return nil; -} - - (void)testNoCrashWhenMetadataDecryptionFails { CFDataRef enc = NULL; @@ -537,7 +536,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -572,7 +571,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -588,6 +587,11 @@ static keyclass_t parse_keyclass(CFTypeRef value) { } #endif ++ (NSData*)fakeDecrypt:(SFAuthenticatedCiphertext*)ciphertext withKey:(SFSymmetricKey*)key error:(NSError**)error +{ + return nil; +} + - (void)testRecoverFromBadMetadataKey { // Disable caching, so we can change AKS encrypt/decrypt @@ -598,14 +602,14 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES), }; NSDictionary* findQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES), }; @@ -616,7 +620,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { NSDictionary* updateQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), }; #endif @@ -624,14 +628,14 @@ static keyclass_t parse_keyclass(CFTypeRef value) { (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount-second", (id)kSecAttrService : @"TestService-second", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES), }; NSDictionary* findQuery2 = @{ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"TestAccount-second", (id)kSecAttrService : @"TestService-second", - (id)kSecAttrNoLegacy : @(YES), + (id)kSecUseDataProtectionKeychain : @(YES), (id)kSecReturnAttributes : @(YES), }; @@ -671,7 +675,7 @@ static keyclass_t parse_keyclass(CFTypeRef value) { /////////////////////////////////////////////////////////////////////////////////// // Now, the metadata keys go corrupt (fake that by changing the underlying AKS key) - [self setNewFakeAKSKey:[NSData dataWithBytes:"1234567890123456789000" length:32]]; + [self setNewFakeAKSKey:[NSData dataWithBytes:"NotthesameAKSkeyas0123456789etc" length:32]]; XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)findQuery, &result), errSecItemNotFound, "should have received errSecItemNotFound when metadata keys are invalid"); diff --git a/secdxctests/KeychainEntitlementsTest.m b/secdxctests/KeychainEntitlementsTest.m index 84482da6..d5be9242 100644 --- a/secdxctests/KeychainEntitlementsTest.m +++ b/secdxctests/KeychainEntitlementsTest.m @@ -33,7 +33,7 @@ @implementation KeychainEntitlementsTest - (void)testNoEntitlements { - NSDictionary *params = @{ (id)kSecAttrNoLegacy: @YES, + NSDictionary *params = @{ (id)kSecUseDataProtectionKeychain: @YES, (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", }; // Application with no keychain-related entitlements at all, but CopyMatching must work in order to support @@ -49,12 +49,12 @@ #if TARGET_OS_OSX - (void)testInvalidEntitlementsAppID { NSDictionary *params; - params = @{ (id)kSecAttrNoLegacy: @YES, + params = @{ (id)kSecUseDataProtectionKeychain: @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]; + [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:NO]; XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecMissingEntitlement); XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); @@ -63,7 +63,7 @@ // 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]; + [self setEntitlements:@{ @"keychain-access-groups": @[@"com.apple.test-app-identifier"] } validated:NO]; XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess); XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecSuccess); @@ -72,29 +72,55 @@ - (void)testValidEntitlementsAppID { NSDictionary *params; - params = @{ (id)kSecAttrNoLegacy: @YES, + params = @{ (id)kSecUseDataProtectionKeychain: @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]; + [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:YES]; #else - [self setEntitlements:@{ @"application-identifier": @"com.apple.test-app-identifier" } validated:true]; + [self setEntitlements:@{ @"application-identifier": @"com.apple.test-app-identifier" } validated:YES]; #endif XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess); XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecSuccess); } +- (void)testEntitlementsAssociatedAppID { + NSMutableDictionary *params = [@{(id)kSecUseDataProtectionKeychain: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label" } mutableCopy]; + + [self setEntitlements:@{ +#if TARGET_OS_OSX + @"com.apple.application-identifier": @"com.apple.test-app-identifier", +#else + @"application-identifier": @"com.apple.test-app-identifier", +#endif + @"com.apple.developer.associated-application-identifier": @[ @"com.apple.test-associated-app-identifier" ] + } validated:YES]; + + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + + // The associated app identifier is preferred over the 'regular' app identifier (in practice this is only relevant on macOS) + XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecSuccess); + params[(id)kSecReturnAttributes] = @(YES); + CFTypeRef result = NULL; + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)params, &result), errSecSuccess); + XCTAssertTrue(CFEqual(CFDictionaryGetValue(result, kSecAttrAccessGroup), CFSTR("com.apple.test-associated-app-identifier"))); + CFReleaseNull(result); + 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, + params = @{ (id)kSecUseDataProtectionKeychain: @YES, (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, }; - [self setEntitlements:@{ @"com.apple.application-identifier": (id)kSecAttrAccessGroupToken } validated:true]; + [self setEntitlements:@{ @"com.apple.application-identifier": (id)kSecAttrAccessGroupToken } validated:YES]; XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); XCTAssertEqual(SecItemAdd((CFDictionaryRef)params, NULL), errSecMissingEntitlement); XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); @@ -103,10 +129,10 @@ #if TARGET_OS_OSX - (void)testInvalidAppGroups { NSDictionary *params; - params = @{ (id)kSecAttrNoLegacy: @YES, + params = @{ (id)kSecUseDataProtectionKeychain: @YES, (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", }; - [self setEntitlements:@{ @"com.apple.security.application-groups": @[@"com.apple.test-app-groups"] } validated:false]; + [self setEntitlements:@{ @"com.apple.security.application-groups": @[@"com.apple.test-app-groups"] } validated:NO]; // Invalid access group entitlement should still allow querying com.apple.token XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); @@ -116,16 +142,16 @@ XCTAssertEqual(SecItemDelete((CFDictionaryRef)params), errSecMissingEntitlement); // Similarly as explicitly referring to AG specified in unverified entitlements. - params = @{ (id)kSecAttrNoLegacy: @YES, + params = @{ (id)kSecUseDataProtectionKeychain: @YES, (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", (id)kSecAttrAccessGroup: @"com.apple.test-app-groups", }; - XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecMissingEntitlement); 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, + params = @{ (id)kSecUseDataProtectionKeychain: @YES, (id)kSecClass: (id)kSecClassGenericPassword, (id)kSecAttrLabel: @"label", (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, }; @@ -133,7 +159,106 @@ } #endif // TARGET_OS_OSX +- (void)testTokenItemsGroup { + NSDictionary *params; + + // Add token items for testing into the keychain. + NSArray *tokenItems = @[ @{ + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, + (id)kSecAttrLabel: @"label", + } ]; + XCTAssertEqual(SecItemUpdateTokenItems(@"com.apple.testtoken", (__bridge CFArrayRef)tokenItems), errSecSuccess); + + [self setEntitlements:@{ @"com.apple.application-identifier": @"com.apple.test-app-identifier" } validated:YES]; + + // Query without explicit access group, should find item on macOS and not find it on iOS. + params = @{ (id)kSecUseDataProtectionKeychain: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", }; +#if TARGET_OS_IPHONE + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecItemNotFound); +#else + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecSuccess); +#endif + + // Query with explicit AG should work the same on both platforms. + params = @{ (id)kSecUseDataProtectionKeychain: @YES, + (id)kSecClass: (id)kSecClassGenericPassword, + (id)kSecAttrLabel: @"label", + (id)kSecAttrAccessGroup: (id)kSecAttrAccessGroupToken, }; + XCTAssertEqual(SecItemCopyMatching((CFDictionaryRef)params, NULL), errSecSuccess); + + // Delete all test token items. + SecItemUpdateTokenItems(@"com.apple.testtoken", (__bridge CFArrayRef)@[]); +} + +- (void)testEntitlementForExplicitAccessGroupLacking { + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier", @"application-identifier": @"com.apple.test-app-identifier"} validated:YES]; + + NSMutableDictionary* query = [@{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrLabel : @"TestLabel", + (id)kSecAttrAccessGroup : @"com.apple.test.myaccessgroup", + (id)kSecValueData : [@"passwd" dataUsingEncoding:NSUTF8StringEncoding], + } mutableCopy]; + NSMutableDictionary* update = [@{(id)kSecAttrLabel : @"NewLabel"} mutableCopy]; + + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)query, NULL), errSecMissingEntitlement); + query[(id)kSecValueData] = nil; + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecMissingEntitlement); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update), errSecMissingEntitlement); + XCTAssertEqual(SecItemDelete((__bridge CFDictionaryRef)query), errSecMissingEntitlement); + + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier", @"application-identifier": @"com.apple.test-app-identifier", @"keychain-access-groups": @[@"com.apple.test.myaccessgroup"]} validated:YES]; + query[(id)kSecValueData] = [@"secret" dataUsingEncoding:NSUTF8StringEncoding]; + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)query, NULL), errSecSuccess); + query[(id)kSecValueData] = nil; + + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecSuccess); + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier"} validated:YES]; + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecMissingEntitlement); + + query[(id)kSecAttrAccessGroup] = nil; + update[(id)kSecAttrAccessGroup] = @"com.apple.test.myotheraccessgroup"; + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update), errSecMissingEntitlement); + + query[(id)kSecAttrAccessGroup] = @"com.apple.test.myaccessgroup"; + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier", @"application-identifier": @"com.apple.test-app-identifier", @"keychain-access-groups": @[@"com.apple.test.myaccessgroup"]} validated:YES]; + XCTAssertEqual(SecItemDelete((__bridge CFDictionaryRef)query), errSecSuccess, @"keychain item not deleted after querying without entitlements"); +} + +- (void)testEntitlementForImplicitAccessGroupLacking { + NSMutableDictionary* query = [@{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecUseDataProtectionKeychain : @YES, + (id)kSecAttrAccount : @"TestAccount", + (id)kSecAttrLabel : @"TestLabel", + (id)kSecAttrAccessGroup : @"com.apple.test.myaccessgroup", + (id)kSecValueData : [@"passwd" dataUsingEncoding:NSUTF8StringEncoding], + } mutableCopy]; + NSDictionary* update = @{(id)kSecAttrLabel : @"NewLabel"}; + + // Have to use explicit access group here or we just get the app identifier + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier", @"application-identifier": @"com.apple.test-app-identifier", @"keychain-access-groups": @[@"com.apple.test.myaccessgroup"]} validated:YES]; + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)query, NULL), errSecSuccess); + + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier", @"application-identifier": @"com.apple.test-app-identifier"} validated:YES]; + query[(id)kSecValueData] = nil; + query[(id)kSecAttrAccessGroup] = nil; + + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecItemNotFound); + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update), errSecItemNotFound); + XCTAssertEqual(SecItemDelete((__bridge CFDictionaryRef)query), errSecItemNotFound); + + [self setEntitlements:@{@"com.apple.application-identifier": @"com.apple.test-app-identifier", @"application-identifier": @"com.apple.test-app-identifier", @"keychain-access-groups": @[@"com.apple.test.myaccessgroup"]} validated:YES]; + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update), errSecSuccess); + query[(id)kSecAttrLabel] = @"NewLabel"; + + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL), errSecSuccess); + XCTAssertEqual(SecItemDelete((__bridge CFDictionaryRef)query), errSecSuccess, @"keychain item not deleted after querying without entitlements"); +} + @end #endif // USE_KEYSTORE - diff --git a/secdxctests/KeychainXCTest.h b/secdxctests/KeychainXCTest.h index 5e172a68..4e1e27d9 100644 --- a/secdxctests/KeychainXCTest.h +++ b/secdxctests/KeychainXCTest.h @@ -29,7 +29,7 @@ #import #if USE_KEYSTORE -#import +#include "OSX/utilities/SecAKSWrappers.h" typedef enum { LockStateUnlocked, @@ -41,6 +41,7 @@ typedef enum { @property LockState lockState; @property id mockSecDbKeychainItemV7; +@property id mockSecAKSObjCWrappers; @property bool allowDecryption; @property BOOL didAKSDecrypt; @property BOOL simulateRolledAKSKey; diff --git a/secdxctests/KeychainXCTest.m b/secdxctests/KeychainXCTest.m index 98d5a266..d763f70b 100644 --- a/secdxctests/KeychainXCTest.m +++ b/secdxctests/KeychainXCTest.m @@ -26,6 +26,8 @@ #import "SecdTestKeychainUtilities.h" #import "CKKS.h" #import "SecDbKeychainItemV7.h" +#import "SecDbKeychainMetadataKeyStore.h" +#import "SecAKSObjCWrappers.h" #import "SecItemPriv.h" #import "SecTaskPriv.h" #import "server_security_helpers.h" @@ -116,7 +118,6 @@ @implementation KeychainXCTest { id _keychainPartialMock; CFArrayRef _originalAccessGroups; - } @synthesize keychainPartialMock = _keychainPartialMock; @@ -142,15 +143,17 @@ self.keyclassUsedForAKSDecryption = 0; self.keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; - [self setNewFakeAKSKey:[NSData dataWithBytes:"1234567890123456789012" length:32]]; + [self setNewFakeAKSKey:[NSData dataWithBytes:"1234567890123456789012345678901" 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.mockSecAKSObjCWrappers = OCMClassMock([SecAKSObjCWrappers class]); + [[[[self.mockSecAKSObjCWrappers stub] andCall:@selector(fakeAKSEncryptWithKeybag:keyclass:plaintext:outKeyclass:ciphertext:error:) onObject:self] ignoringNonObjectArgs] aksEncryptWithKeybag:0 keyclass:0 plaintext:[OCMArg any] outKeyclass:NULL ciphertext:[OCMArg any] error:NULL]; + [[[[self.mockSecAKSObjCWrappers stub] andCall:@selector(fakeAKSDecryptWithKeybag:keyclass:ciphertext:outKeyclass:plaintext:error:) onObject:self] ignoringNonObjectArgs] aksDecryptWithKeybag:0 keyclass:0 ciphertext:[OCMArg any] outKeyclass:NULL plaintext:[OCMArg any] error:NULL]; + // bring back with // [[[self.mockSecDbKeychainItemV7 stub] andCall:@selector(isKeychainUnlocked) onObject:self] isKeychainUnlocked]; @@ -166,6 +169,7 @@ - (void)tearDown { [self.mockSecDbKeychainItemV7 stopMocking]; + [self.mockSecAKSObjCWrappers stopMocking]; SecAccessGroupsSetCurrent(_originalAccessGroups); [super tearDown]; @@ -192,9 +196,9 @@ - (bool)fakeAKSEncryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass - keyData:(NSData*)keyData + plaintext:(NSData*)plaintext outKeyclass:(keyclass_t*)outKeyclass - wrappedKey:(NSMutableData*)wrappedKey + ciphertext:(NSMutableData*)ciphertextOut error:(NSError**)error { if (self.lockState == LockStateLockedAndDisallowAKS) { @@ -204,8 +208,8 @@ return false; } - uint32_t keyLength = (uint32_t)keyData.length; - const uint8_t* keyBytes = keyData.bytes; + uint32_t keyLength = (uint32_t)plaintext.length; + const uint8_t* keyBytes = plaintext.bytes; NSData* dataToEncrypt = [NSData dataWithBytes:keyBytes length:keyLength]; NSError* localError = nil; @@ -217,9 +221,9 @@ if (error) { *error = localError; } - + if (ciphertext) { - void* wrappedKeyMutableBytes = wrappedKey.mutableBytes; + void* wrappedKeyMutableBytes = ciphertextOut.mutableBytes; memcpy(wrappedKeyMutableBytes, ciphertext.ciphertext.bytes, 32); memcpy(wrappedKeyMutableBytes + 32, ciphertext.initializationVector.bytes, 32); memcpy(wrappedKeyMutableBytes + 64, ciphertext.authenticationCode.bytes, 8); @@ -239,9 +243,9 @@ - (bool)fakeAKSDecryptWithKeybag:(keybag_handle_t)keybag keyclass:(keyclass_t)keyclass - wrappedKeyData:(NSData*)wrappedKeyData + ciphertext:(NSData*)ciphertextIn outKeyclass:(keyclass_t*)outKeyclass - unwrappedKey:(NSMutableData*)unwrappedKey + plaintext:(NSMutableData*)plaintext error:(NSError**)error { if (self.lockState == LockStateLockedAndDisallowAKS) { @@ -256,7 +260,7 @@ return false; } - const uint8_t* wrappedKeyBytes = wrappedKeyData.bytes; + const uint8_t* wrappedKeyBytes = ciphertextIn.bytes; NSData* ciphertextData = [NSData dataWithBytes:wrappedKeyBytes length:32]; NSData* ivData = [NSData dataWithBytes:wrappedKeyBytes + 32 length:32]; @@ -286,9 +290,9 @@ } self.keyclassUsedForAKSDecryption = keyclass; - if (decryptedData && decryptedData.length <= unwrappedKey.length) { - memcpy(unwrappedKey.mutableBytes, decryptedData.bytes, decryptedData.length); - unwrappedKey.length = decryptedData.length; + if (decryptedData && decryptedData.length <= plaintext.length) { + memcpy(plaintext.mutableBytes, decryptedData.bytes, decryptedData.length); + plaintext.length = decryptedData.length; self.didAKSDecrypt = YES; return true; } @@ -300,7 +304,7 @@ - (NSData*)getDatabaseKeyDataithError:(NSError**)error { if (_lockState == LockStateUnlocked) { - return [NSData dataWithBytes:"12345678901234567890123456789012" length:32]; + return [NSData dataWithBytes:"1234567890123456789012345678901" length:32]; } else { if (error) { diff --git a/sectask/SecEntitlements.h b/sectask/SecEntitlements.h index 2784e788..9dd2005d 100644 --- a/sectask/SecEntitlements.h +++ b/sectask/SecEntitlements.h @@ -54,6 +54,13 @@ __BEGIN_DECLS #define kSecEntitlementApplicationIdentifier kSecEntitlementAppleApplicationIdentifier #endif +/* Marzipan apps distributed through the App Store cannot share an application + identifier with their iOS versions, so they have an associated application + identifier which matches the iOS identifier. It will be preferred, when + present, over the 'regular' application identifier. This avoids developers + having to jump through hoops to port iOS apps to the Mac. */ +#define kSecEntitlementAssociatedApplicationIdentifier CFSTR("com.apple.developer.associated-application-identifier") + /* The value should be an array of strings. Each string is the name of an access group that the application has access to. The application-identifier is implicitly added to this list. When creating @@ -161,6 +168,9 @@ __BEGIN_DECLS #if __OBJC__ /* Entitlement to control use of OT */ #define kSecEntitlementPrivateOctagon @"com.apple.private.octagon" + +/* Entitlement to control use of Escrow Update */ +#define kSecEntitlementPrivateEscrowRequest @"com.apple.private.escrow-update" #endif __END_DECLS diff --git a/sectask/SecTask.c b/sectask/SecTask.c index 57b635c0..a73416c7 100644 --- a/sectask/SecTask.c +++ b/sectask/SecTask.c @@ -35,14 +35,15 @@ #include #include #include +#include #include #if TARGET_OS_OSX /* These won't exist until we unify codesigning */ -#include "SecCode.h" -#include "SecCodePriv.h" -#include "SecRequirement.h" +#include +#include +#include #endif /* TARGET_OS_OSX */ struct __SecTask { @@ -132,6 +133,21 @@ SecTaskRef SecTaskCreateWithAuditToken(CFAllocatorRef allocator, audit_token_t t return task; } +_Nullable SecTaskRef +SecTaskCreateWithXPCMessage(xpc_object_t _Nonnull message) +{ + audit_token_t token; + + if (message == NULL || xpc_get_type(message) != XPC_TYPE_DICTIONARY) { + return NULL; + } + xpc_dictionary_get_audit_token(message, &token); + + return SecTaskCreateWithAuditToken(NULL, token); +} + + + struct csheader { uint32_t magic; uint32_t length; @@ -354,7 +370,7 @@ out: return values; } -#if TARGET_OS_OSX +#if SEC_OS_OSX /* * Determine if the given task meets a specified requirement. */ @@ -385,7 +401,7 @@ SecTaskValidateForRequirement(SecTaskRef task, CFStringRef requirement) return status; } -#endif /* TARGET_OS_OSX */ +#endif /* SEC_OS_OSX */ Boolean SecTaskEntitlementsValidated(SecTaskRef task) { // TODO: Cache the result diff --git a/sectask/SecTask.h b/sectask/SecTask.h index 93022dff..c1bf28a0 100644 --- a/sectask/SecTask.h +++ b/sectask/SecTask.h @@ -120,15 +120,14 @@ CFDictionaryRef SecTaskCopyValuesForEntitlements(SecTaskRef task, CFArrayRef ent __nullable CFStringRef SecTaskCopySigningIdentifier(SecTaskRef task, CFErrorRef *error); -#if SEC_OS_IPHONE /*! @function SecTaskGetCodeSignStatus @abstract Return the code sign status flags @param task A previously created SecTask object */ -uint32_t SecTaskGetCodeSignStatus(SecTaskRef task); -#endif /* SEC_OS_IPHONE */ +uint32_t SecTaskGetCodeSignStatus(SecTaskRef task) + API_AVAILABLE(ios(10.0), watchos(3.0), tvos(10.0), iosmac(11.0)) SPI_AVAILABLE(macos(10.5)); CF_IMPLICIT_BRIDGING_DISABLED diff --git a/sectask/SecTaskPriv.h b/sectask/SecTaskPriv.h index e29aa883..67ece932 100644 --- a/sectask/SecTaskPriv.h +++ b/sectask/SecTaskPriv.h @@ -26,6 +26,7 @@ #include #include +#include __BEGIN_DECLS @@ -41,15 +42,17 @@ __BEGIN_DECLS OSStatus SecTaskValidateForRequirement(SecTaskRef _Nonnull task, CFStringRef _Nonnull requirement); +#endif /* SEC_OS_OSX */ + /*! - @function SecTaskGetCodeSignStatus - @abstract Get code signing flags - @param task A previously created SecTask object -*/ + @function SecTaskCreateWithXPCMessage + @abstract Get SecTask instance from the remote peer of the xpc connection + @param message message from peer in the xpc connection event handler, you can't use + connection since it cached and uses the most recent sender to this connection. + */ -uint32_t -SecTaskGetCodeSignStatus(SecTaskRef _Nonnull task); -#endif /* SEC_OS_OSX */ +_Nullable SecTaskRef +SecTaskCreateWithXPCMessage(xpc_object_t _Nonnull message); /*! @function SecTaskEntitlementsValidated diff --git a/sectask/regressions/sectask-10-sectask.c b/sectask/regressions/sectask-10-sectask.c index d38abb2d..cb3bab9d 100644 --- a/sectask/regressions/sectask-10-sectask.c +++ b/sectask/regressions/sectask-10-sectask.c @@ -126,7 +126,7 @@ int sectask_10_sectask_self(int argc, char *const *argv) /* TODO: remove the todo once xcode signs simulator binaries */ SKIP: { -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR todo("no entitlements in the simulator binaries yet, until "); #endif ok(appId=SecTaskCopyValueForEntitlement(task, kSecEntitlementApplicationIdentifier, NULL), "SecTaskCopyValueForEntitlement"); @@ -172,7 +172,7 @@ int sectask_10_sectask(int argc, char *const *argv) /* TODO: remove the todo once xcode signs simulator binaries */ SKIP: { -#if TARGET_IPHONE_SIMULATOR +#if TARGET_OS_SIMULATOR todo("no entitlements in the simulator binaries yet, until "); #endif ok(appId=SecTaskCopyValueForEntitlement(task, kSecEntitlementApplicationIdentifier, NULL), "SecTaskCopyValueForEntitlement"); diff --git a/sectask/regressions/sectask_regressions.h b/sectask/regressions/sectask_regressions.h index 22d226e1..c9eefc74 100644 --- a/sectask/regressions/sectask_regressions.h +++ b/sectask/regressions/sectask_regressions.h @@ -1,6 +1,6 @@ #include -#if !TARGET_IPHONE_SIMULATOR +#if !TARGET_OS_SIMULATOR ONE_TEST(sectask_10_sectask_self) ONE_TEST(sectask_10_sectask) #else diff --git a/security-sysdiagnose/security-sysdiagnose.entitlements.plist b/security-sysdiagnose/security-sysdiagnose.entitlements.plist index 481bf502..2b46d229 100644 --- a/security-sysdiagnose/security-sysdiagnose.entitlements.plist +++ b/security-sysdiagnose/security-sysdiagnose.entitlements.plist @@ -14,5 +14,7 @@ com.apple.private.ckks + com.apple.CloudKeychainProxy.client + diff --git a/security-sysdiagnose/security-sysdiagnose.m b/security-sysdiagnose/security-sysdiagnose.m index 68473514..23ffdc0c 100644 --- a/security-sysdiagnose/security-sysdiagnose.m +++ b/security-sysdiagnose/security-sysdiagnose.m @@ -25,14 +25,14 @@ #import #import -#import +#import "keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h" #import #import #import -#import +#import "keychain/SecureObjectSync/SOSInternal.h" #import #include @@ -145,7 +145,7 @@ homekit_sysdiagnose(void) (id)kSecMatchLimit : (id)kSecMatchLimitAll, (id)kSecReturnAttributes: @YES, (id)kSecReturnData: @NO, - (id)kSecAttrNoLegacy : @YES, + (id)kSecUseDataProtectionKeychain : @YES, } mutableCopy]; CFTypeRef result = NULL; @@ -201,7 +201,7 @@ unlock_sysdiagnose(void) static void analytics_sysdiagnose(void) { - NSXPCConnection* xpcConnection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.apple.securityuploadd" options:NSXPCConnectionPrivileged]; + NSXPCConnection* xpcConnection = [[NSXPCConnection alloc] initWithMachServiceName:@"com.apple.securityuploadd" options:0]; if (!xpcConnection) { [@"failed to setup xpc connection for securityuploadd\n" writeToStdErr]; return; diff --git a/securityd/doc/securityd.1 b/securityd/doc/securityd.1 index b23cae7d..3d801e75 100644 --- a/securityd/doc/securityd.1 +++ b/securityd/doc/securityd.1 @@ -2,7 +2,7 @@ .\"See Also: .\"man mdoc.samples for a complete listing of options .\"man mdoc for the short list of editing options -.Dd Fri Sep 10 2004 \" DATE +.Dd Fri July 20 2018 \" DATE .Dt securityd 1 \" Program name and manual section number .Os Darwin .Sh NAME \" Section Header - required - don't modify @@ -10,20 +10,16 @@ .\" The following lines are read in generating the apropos(man -k) database. Use only key .\" words here as the database is built based on the words here and in the .ND line. .\" Use .Nm macro to designate other names for the documented program. -.Nd Security context daemon for Authorization and cryptographic operations +.Nd Security context daemon for keychain and cryptographic operations .Sh SYNOPSIS \" Section Header - required - don't modify .Nm .Sh DESCRIPTION \" Section Header - required - don't modify .Nm -maintains security contexts and arbitrates cryptographic operations and Security Authorizations. Access to +maintains security contexts and arbitrates cryptographic operations. Access to keychain items is routed through .Nm to enforce access controls and to keep private keys out of -user process address space. Authorization calls also communicate with -.Nm -to enforce rules contained in the -.Pa /etc/authorization -database. All user interaction with +user process address space. All user interaction with .Nm is mediated through the .Nm "Security Agent." @@ -32,5 +28,6 @@ This command is not intended to be invoked directly. .Sh HISTORY .Nm was first introduced in Mac OS X version 10.0 (Cheetah) as the "Security Server" and was renamed in 10.4 (Tiger). -.Sh AUTHORS -.An "Perry The Cynic" +.Sh SEE ALSO +.Xr authd 8 , +.Xr secd 8 diff --git a/securityd/etc/com.apple.securityd.sb b/securityd/etc/com.apple.securityd.sb new file mode 100644 index 00000000..a6145ad0 --- /dev/null +++ b/securityd/etc/com.apple.securityd.sb @@ -0,0 +1,64 @@ +;;; Copyright (c) 2017 Apple Inc. All Rights reserved. +;;; +;;; WARNING: The sandbox rules in this file currently constitute +;;; Apple System Private Interface and are subject to change at any time and +;;; without notice. +;;; +(version 1) + +(allow (with report) default) +(allow (with report) file-map-executable process-info* nvram*) +(allow (with report) dynamic-code-generation) + +(deny mach-priv-host-port) + +(import "system.sb") +(import "com.apple.corefoundation.sb") +(corefoundation) + +(allow file-read-metadata) +;; We inspect all the binaries +(allow file-read* + (subpath "/")) +(allow file-write* + (subpath "/private/var/db/mds")) +(allow file-ioctl (literal "/dev/auditsessions")) + +(allow process-info* (target self)) +(allow process-info-codesignature) +(allow process-info-pidinfo) + +(when (string=? (param "LEGACY_TOKENS_ENABLED") "YES") + (allow process-exec (with no-sandbox) (subpath "/Library/Security/tokend")) + (allow process-fork) + (allow signal (target children)) + (allow file-write* (subpath "/private/var/db/TokenCache"))) + +(allow user-preference-read + (preference-domain "com.apple.security") + (preference-domain "com.apple.security.smartcard") + (preference-domain "kCFPreferencesAnyApplication") + (preference-domain "securityd")) + +(allow system-audit) +(allow mach-lookup + (global-name "com.apple.CoreServices.coreservicesd") + (global-name "com.apple.system.opendirectoryd.api") + (global-name "com.apple.securitydservice") + (global-name "com.apple.ocspd") + (global-name "com.apple.PowerManagement.control") + (global-name "com.apple.security.syspolicy") + (global-name "com.apple.security.agent")) + +(allow ipc-posix-shm + (ipc-posix-name "com.apple.AppleDatabaseChanged") + (ipc-posix-name "apple.cfprefs.daemonv1")) + +(allow iokit-open (iokit-user-client-class "RootDomainUserClient")) + +(allow network-outbound + (path "/private/var/run/systemkeychaincheck.socket")) + +(with-filter (system-attribute apple-internal) + (allow nvram-get + (nvram-variable "AMFITrustedKeys"))) diff --git a/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj b/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj index 523e170e..ad6cc5e7 100644 --- a/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj +++ b/securityd/securityd_service/securityd_service.xcodeproj/project.pbxproj @@ -30,19 +30,19 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 189D4664166C166E001D8533 /* PBXContainerItemProxy */ = { + 18F4809A174975FF009724DB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 189D462D166AC95C001D8533 /* Project object */; proxyType = 1; - remoteGlobalIDString = 189D465A166C15C1001D8533; - remoteInfo = securitydservicectrl; + remoteGlobalIDString = 18F4808D17497521009724DB; + remoteInfo = KeyStore; }; - 18F4809A174975FF009724DB /* PBXContainerItemProxy */ = { + DCF19A6F21AE2CEE002E808F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 189D462D166AC95C001D8533 /* Project object */; proxyType = 1; - remoteGlobalIDString = 18F4808D17497521009724DB; - remoteInfo = KeyStore; + remoteGlobalIDString = 1843240D1714797D00196B52; + remoteInfo = securitydservice_client; }; /* End PBXContainerItemProxy section */ @@ -299,7 +299,6 @@ ); dependencies = ( 18F4809B174975FF009724DB /* PBXTargetDependency */, - 189D4665166C166E001D8533 /* PBXTargetDependency */, ); name = securityd_service; productName = securityd_service; @@ -317,6 +316,7 @@ buildRules = ( ); dependencies = ( + DCF19A7021AE2CEE002E808F /* PBXTargetDependency */, ); name = securitydservicectrl; productName = securitydservicectrl; @@ -416,16 +416,16 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 189D4665166C166E001D8533 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 189D465A166C15C1001D8533 /* securitydservicectrl */; - targetProxy = 189D4664166C166E001D8533 /* PBXContainerItemProxy */; - }; 18F4809B174975FF009724DB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 18F4808D17497521009724DB /* KeyStoreEvents */; targetProxy = 18F4809A174975FF009724DB /* PBXContainerItemProxy */; }; + DCF19A7021AE2CEE002E808F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1843240D1714797D00196B52 /* securitydservice_client */; + targetProxy = DCF19A6F21AE2CEE002E808F /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ diff --git a/securityd/securityd_service/securityd_service/main.c b/securityd/securityd_service/securityd_service/main.c index 2286c2d4..496e3a05 100644 --- a/securityd/securityd_service/securityd_service/main.c +++ b/securityd/securityd_service/securityd_service/main.c @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -231,7 +230,8 @@ _kb_verify_create_path(service_user_record_t * ur) } } if (!created) { - 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)); + errno_t err = mkpath_np(kb_path, 0700); + require_action(err == 0 || err == EEXIST, done, os_log(OS_LOG_DEFAULT, "could not create path: %{public}s %{darwin.errno}d", kb_path, err)); created = true; } @@ -430,7 +430,7 @@ _kb_get_session_handle(service_context_t * context, keybag_handle_t * handle_out done: if (rc == KB_BagNotLoaded) { if (service_kb_load(context) == KB_Success) { - if (_service_kb_get_system(context->s_uid, handle_out) == kIOReturnSuccess) { + if (_service_kb_get_system(context->s_uid, handle_out) == kAKSReturnSuccess) { rc = KB_Success; } } @@ -574,7 +574,7 @@ _service_kb_load_uid(uid_t s_uid, uint64_t * kcv) int _stage = 0; rc = _service_kb_get_system(s_uid, &session_handle); - if (rc == kIOReturnNotFound) { + if (rc == kAKSReturnNotFound) { require_action(ur = get_user_record(s_uid), done, rc = KB_GeneralError; _stage = 1); require_action(bag_file = _kb_copy_bag_filename(ur, kb_bag_type_user), done, rc = KB_GeneralError; _stage = 2); require_action_quiet(_kb_load_bag_from_disk(ur, bag_file, &buf, &buf_size, kcv), done, rc = KB_BagNotFound; _stage = 3); @@ -637,11 +637,11 @@ service_kb_unload(service_context_t *context) keybag_handle_t session_handle = bad_keybag_handle; rc = _service_kb_get_system(context->s_uid, &session_handle); - if (rc == kIOReturnNotFound) { + if (rc == kAKSReturnNotFound) { // No session bag, nothing to do rc = KB_Success; return; - } else if (rc != kIOReturnSuccess) { + } else if (rc != kAKSReturnSuccess) { os_log(OS_LOG_DEFAULT, "error locating session keybag for uid (%i) in session (%i)", context->s_uid, context->s_id); rc = KB_BagError; return; @@ -1019,7 +1019,9 @@ OSStatus service_stash_set_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); + require(keydata_len <= MAX_KEY_SIZE, done); + _Static_assert(sizeof(inStruct1.inKey.key.key) == MAX_KEY_SIZE, "unexpected aks raw key size"); memcpy(&inStruct1.inKey.key.key, keydata, keydata_len); inStruct1.inKey.key.keysize = (cryptosize_t) keydata_len; len = sizeof(outStruct1); @@ -1032,6 +1034,7 @@ OSStatus service_stash_set_key(service_context_t * context, xpc_object_t event, // Now using the uuid stash it as the master key setStashKey_InStruct_t inStruct2; + _Static_assert(sizeof(outStruct1.uuid) == sizeof(inStruct2.uuid), "invalid uuid size(s)"); memcpy(&inStruct2.uuid, &outStruct1.uuid, sizeof(outStruct1.uuid)); inStruct2.type = kAppleFDEKeyStoreStash_master; @@ -1263,10 +1266,8 @@ void service_peer_event_handler(xpc_connection_t connection, xpc_object_t event) switch (request) { 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); - // } break; case SERVICE_KB_LOAD: rc = service_kb_load(context); @@ -1458,9 +1459,9 @@ int main(int argc, const char * argv[]) // It is safe to cast 'peer' to xpc_connection_t assuming // we have a correct configuration in our launchd.plist. xpc_connection_set_event_handler(peer, ^(xpc_object_t event) { - vproc_transaction_t transaction = vproc_transaction_begin(NULL); + xpc_transaction_begin(); service_peer_event_handler(peer, event); - vproc_transaction_end(NULL, transaction); + xpc_transaction_end(); }); xpc_connection_resume(peer); }); diff --git a/securityd/securityd_service/securityd_service/service.entitlements b/securityd/securityd_service/securityd_service/service.entitlements index bbc96664..39bc3afe 100644 --- a/securityd/securityd_service/securityd_service/service.entitlements +++ b/securityd/securityd_service/securityd_service/service.entitlements @@ -16,5 +16,7 @@ com.apple.private.securityd.stash + com.apple.private.applecredentialmanager.allow + diff --git a/securityd/src/acl_keychain.cpp b/securityd/src/acl_keychain.cpp index 25ca3581..b35015e0 100644 --- a/securityd/src/acl_keychain.cpp +++ b/securityd/src/acl_keychain.cpp @@ -209,7 +209,9 @@ bool KeychainPromptAclSubject::validateExplicitly(const AclValidationContext &co if (db && db->belongsToSystem() && !hasAuthorizedForSystemKeychain()) { QueryKeychainAuth query; query.inferHints(Server::process()); - if (query(db ? db->dbName() : NULL, description.c_str(), context.authorization(), NULL) != SecurityAgent::noReason) + // This is okay because we're in the belongsToSystem case which is true iff KeychainDbCommon which is true iff KeychainDatabase + const KeychainDatabase& kcdb = dynamic_cast(*db); + if (query.performQuery(kcdb, description.c_str(), context.authorization(), NULL) != SecurityAgent::noReason) return false; return true; } else { diff --git a/securityd/src/agentquery.cpp b/securityd/src/agentquery.cpp index e5004bd6..3c813f4c 100644 --- a/securityd/src/agentquery.cpp +++ b/securityd/src/agentquery.cpp @@ -150,7 +150,8 @@ SecurityAgentXPCConnection::activate(bool ignoreUid) xpc_connection_set_target_uid(mXPCConnection, targetUid); secnotice("SecurityAgentXPCConnection", "Creating a standard security agent"); } else { - mXPCConnection = xpc_connection_create_mach_service(SECURITYAGENT_LOGINWINDOW_BOOTSTRAP_NAME_BASE, NULL, 0); + mXPCConnection = xpc_connection_create_mach_service(SECURITYAGENT_LOGINWINDOW_BOOTSTRAP_NAME_BASE, NULL, + XPC_CONNECTION_MACH_SERVICE_PRIVILEGED); xpc_connection_set_instance(mXPCConnection, sessionUUID); secnotice("SecurityAgentXPCConnection", "Creating a loginwindow security agent"); } @@ -561,7 +562,13 @@ Reason QueryKeychainUse::queryUser (const char *database, const char *descriptio passwordItem->getCssmData(data); - reason = (const_cast(mPassphraseCheck)->decode(data) ? SecurityAgent::noReason : SecurityAgent::invalidPassphrase); + // decode() replaces the master key, so do this only if we know the passphrase is correct. + // I suspect decode() is redundant but something might rely on its side effects so let's keep it. + if (const_cast(mPassphraseCheck)->validatePassphrase(data) && const_cast(mPassphraseCheck)->decode(data)) { + reason = SecurityAgent::noReason; + } else { + reason = SecurityAgent::invalidPassphrase; + } } while (reason != SecurityAgent::noReason); @@ -663,6 +670,8 @@ Reason QueryUnlock::accept(CssmManagedData &passphrase) // Must hold the 'common' lock to call decode; otherwise there's a data corruption issue StLock _(safer_cast(database).common()); + // Calling validatePassphrase here throws when trying to constitute a key. + // Unsure why but since this is for the KC unlock path and not a validation path the wrong password won't make things worse. if (safer_cast(database).decode(passphrase)) return SecurityAgent::noReason; else @@ -1063,7 +1072,7 @@ Reason QueryDBBlobSecret::accept(CssmManagedData &passphrase, // @@@ no pluggable authentication possible! Reason -QueryKeychainAuth::operator () (const char *database, const char *description, AclAuthorization action, const char *prompt) +QueryKeychainAuth::performQuery(const KeychainDatabase& db, const char *description, AclAuthorization action, const char *prompt) { Reason reason = SecurityAgent::noReason; AuthItemSet hints, context; @@ -1072,7 +1081,7 @@ QueryKeychainAuth::operator () (const char *database, const char *description, A string password; using CommonCriteria::Securityd::KeychainAuthLogger; - KeychainAuthLogger logger(mAuditToken, (short)AUE_ssauthint, database, description); + KeychainAuthLogger logger(mAuditToken, (short)AUE_ssauthint, db.dbName(), description); hints.insert(mClientHints.begin(), mClientHints.end()); @@ -1085,15 +1094,16 @@ QueryKeychainAuth::operator () (const char *database, const char *description, A hints.insert(AuthItemRef(AGENT_HINT_KEYCHAIN_ITEM_NAME, AuthValueOverlay(description ? (uint32_t)strlen(description) : 0, const_cast(description)))); // keychain name into hints - hints.insert(AuthItemRef(AGENT_HINT_KEYCHAIN_PATH, AuthValueOverlay(database ? (uint32_t)strlen(database) : 0, const_cast(database)))); + hints.insert(AuthItemRef(AGENT_HINT_KEYCHAIN_PATH, AuthValueOverlay(db.dbName() ? (uint32_t)strlen(db.dbName()) : 0, const_cast(db.dbName())))); create("builtin", "confirm-access-user-password"); AuthItem *usernameItem; AuthItem *passwordItem; + // This entire do..while requires the UI lock because we do accept() in the condition, which in some cases is reentrant + StSyncLock syncLock(db.common().uiLock(), db.common()); do { - AuthItemRef triesHint(AGENT_HINT_TRIES, AuthValueOverlay(sizeof(retryCount), &retryCount)); hints.erase(triesHint); hints.insert(triesHint); // replace @@ -1129,6 +1139,7 @@ QueryKeychainAuth::operator () (const char *database, const char *description, A usernameItem->getString(username); passwordItem->getString(password); } while ((reason = accept(username, password))); + syncLock.unlock(); if (SecurityAgent::noReason == reason) logger.logSuccess(); diff --git a/securityd/src/agentquery.h b/securityd/src/agentquery.h index 3c9bf9f4..27a03ae7 100644 --- a/securityd/src/agentquery.h +++ b/securityd/src/agentquery.h @@ -255,7 +255,7 @@ class QueryKeychainAuth : public SecurityAgentXPCQuery { public: QueryKeychainAuth() { } // "prompt" can be NULL - Reason operator () (const char *database, const char *description, AclAuthorization action, const char *prompt); + Reason performQuery(const KeychainDatabase&, const char *description, AclAuthorization action, const char *prompt); Reason accept(string &username, string &passphrase); }; diff --git a/securityd/src/connection.cpp b/securityd/src/connection.cpp index f2f1bbcd..7b7e864f 100644 --- a/securityd/src/connection.cpp +++ b/securityd/src/connection.cpp @@ -64,13 +64,16 @@ Connection::Connection(Process &proc, Port rPort) // When a Connection's destructor executes, the connection must already have been // terminated. All we have to do here is clean up a bit. // -Connection::~Connection() +Connection::~Connection() try { + mClientPort.deallocate(); secinfo("SecServer", "releasing client connection %p", this); assert(!agentWait); +} catch (...) { + secerror("SecServer: Error deallocating connection port"); + return; } - // // Set the (last known) guest handle for this connection. // @@ -80,46 +83,6 @@ void Connection::guestRef(SecGuestRef newGuest, SecCSFlags flags) mGuestRef = newGuest; } - -// -// Terminate a Connection normally. -// This is assumed to be properly sequenced, so no thread races are possible. -// -void Connection::terminate() -{ - // cleanly discard port rights - 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("SecServer", "Connection %p terminated", this); -} - - -// -// Abort a Connection. -// This may be called from thread A while thread B is working a request for the Connection, -// so we must be careful. -// -void Connection::abort(bool keepReplyPort) -{ - StLock _(*this); - if (!keepReplyPort) - mClientPort.destroy(); // dead as a doornail already - switch (state) { - case idle: - secinfo("SecServer", "Connection %p aborted", this); - break; - case busy: - state = dying; // shoot me soon, please - secinfo("SecServer", "Connection %p abort deferred (busy)", this); - break; - default: - assert(false); // impossible (we hope) - break; - } -} - - // // Service request framing. // These are here so "hanging" connection service threads don't fall diff --git a/securityd/src/csproxy.cpp b/securityd/src/csproxy.cpp deleted file mode 100644 index 5ca68c60..00000000 --- a/securityd/src/csproxy.cpp +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (c) 2006-2010 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@ - */ - - -// -// csproxy - Code Signing Hosting Proxy -// -#include - -#include "csproxy.h" -#include "server.h" -#include -#include -#include -#include -#include - -// -// Construct a CodeSigningHost -// -CodeSigningHost::CodeSigningHost() - : mLock(Mutex::recursive), mHostingState(noHosting) -{ -} - - -// -// Cleanup code. -// -CodeSigningHost::~CodeSigningHost() -{ - reset(); -} - - -// -// Reset Code Signing Hosting state. -// This turns hosting off and clears all children. -// -void CodeSigningHost::reset() -{ - StLock _(mLock); - switch (mHostingState) { - case noHosting: - break; // nothing to do - case dynamicHosting: - mHostingPort.deallocate(); - secnotice("SecServer", "%d host unregister", mHostingPort.port()); - break; - case proxyHosting: - Server::active().remove(*this); // unhook service handler - mHostingPort.modRefs(MACH_PORT_RIGHT_RECEIVE, -1); - mHostingState = noHosting; - mHostingPort = MACH_PORT_NULL; - mGuests.erase(mGuests.begin(), mGuests.end()); - secnotice("SecServer", "%d host unregister", mHostingPort.port()); - break; - } -} - - -// -// Given a host reference (possibly NULL for the process itself), locate -// its most dedicated guest. This descends a contiguous chain of dedicated -// guests until it find a host that either has no guests, or whose guests -// are not dedicated. -// -CodeSigningHost::Guest *CodeSigningHost::findHost(SecGuestRef hostRef) -{ - Guest *host = findGuest(hostRef, true); - for (;;) { - if (Guest *guest = findGuest(host)) - if (guest->dedicated) { - host = guest; - continue; - } - return host; - } -} - - -// -// Look up guest by guestRef. -// Throws if we don't have a guest by that ref. -// -CodeSigningHost::Guest *CodeSigningHost::findGuest(SecGuestRef guestRef, bool hostOk /* = false */) -{ - GuestMap::iterator it = mGuests.find(guestRef); - if (it == mGuests.end()) { - if (hostOk) { - return NULL; - } else { - MacOSError::throwMe(errSecCSNoSuchCode); - } - } - assert(it->first == it->second->guestRef()); - return it->second; -} - - -// -// Look up guest by attribute set. -// Returns the host if the attributes can't be found (*loose* interpretation). -// Throws if multiple guests are found (ambiguity). -// Implicitly matches dedicated guests no matter what attributes are requested. -// -CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host, const CssmData &attrData) -{ - CFRef attrDict = attrData - ? makeCFDictionaryFrom(attrData.data(), attrData.length()) - : makeCFDictionary(0); - CFDictionary attrs(attrDict, errSecCSInvalidAttributeValues); - - // if a guest handle was provided, start with that - it must be valid or we fail - if (CFNumberRef canonical = attrs.get(kSecGuestAttributeCanonical)) { - // direct lookup by SecGuestRef (canonical guest handle) - SecGuestRef guestRef = cfNumber(canonical); - if (Guest *guest = findGuest(guestRef, true)) // found guest handle - if (guest->isGuestOf(host, loose)) - host = guest; // new starting point - else - MacOSError::throwMe(errSecCSNoSuchCode); // not a guest of given host - else - MacOSError::throwMe(errSecCSNoSuchCode); // not there at all - } - - // now take the rest of the attrs - CFIndex count = CFDictionaryGetCount(attrs); - - 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 - for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it) { - 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; - } - } - } - } - if (!match) { // nothing found - free(keys); - free(values); - return host; - } - else { - host = match; // and repeat - } - } -} - - -// -// Find any guest of a given host. -// This will return a randomly chosen guest of this host if it has any, -// or NULL if it has none (i.e. it is not a host). -// -CodeSigningHost::Guest *CodeSigningHost::findGuest(Guest *host) -{ - for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it) - if (it->second->isGuestOf(host, strict)) - return it->second; - return NULL; -} - - -// -// Register a hosting API service port where the host will dynamically -// answer hosting queries from interested parties. This switches the process -// to dynamic hosting mode, and is incompatible with proxy hosting. -// -void CodeSigningHost::registerCodeSigning(mach_port_t hostingPort, SecCSFlags flags) -{ - StLock _(mLock); - switch (mHostingState) { - case noHosting: - mHostingPort = hostingPort; - mHostingState = dynamicHosting; - secnotice("SecServer", "%d host register: %d", mHostingPort.port(), mHostingPort.port()); - break; - default: - MacOSError::throwMe(errSecCSHostProtocolContradiction); - } -} - - -// -// Create a guest entry for the given host and prepare to answer for it -// when dynamic hosting queries are received for it. -// This engages proxy hosting mode, and is incompatible with dynamic hosting mode. -// -SecGuestRef CodeSigningHost::createGuest(SecGuestRef hostRef, - uint32_t status, const char *path, - const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags) -{ - StLock _(mLock); - if (path[0] != '/') // relative path (relative to what? :-) - MacOSError::throwMe(errSecCSHostProtocolRelativePath); - if (cdhash.length() > maxUcspHashLength) - MacOSError::throwMe(errSecCSHostProtocolInvalidHash); - - // set up for hosting proxy services if nothing's there yet - switch (mHostingState) { - case noHosting: // first hosting call, this host - // set up proxy hosting - mHostingPort.allocate(); // allocate service port - MachServer::Handler::port(mHostingPort); // put into Handler - MachServer::active().add(*this); // start listening - mHostingState = proxyHosting; // now proxying for this host - secnotice("SecServer", "%d host proxy: %d", mHostingPort.port(), mHostingPort.port()); - break; - case proxyHosting: // already proxying - break; - case dynamicHosting: // in dynamic mode, can't switch - MacOSError::throwMe(errSecCSHostProtocolContradiction); - } - - RefPointer host = findHost(hostRef); - if (RefPointer knownGuest = findGuest(host)) { // got a guest already - if (flags & kSecCSDedicatedHost) { - MacOSError::throwMe(errSecCSHostProtocolDedicationError); // can't dedicate with other guests - } else if (knownGuest->dedicated) { - MacOSError::throwMe(errSecCSHostProtocolDedicationError); // other guest is already dedicated - } - } - - // create the new guest - RefPointer guest = new Guest; - if (host) - guest->guestPath = host->guestPath; - guest->guestPath.push_back(int_cast(guest->handle())); - guest->status = status; - guest->path = path; - guest->setAttributes(attributes); - guest->setHash(cdhash, flags & kSecCSGenerateGuestHash); - guest->dedicated = (flags & kSecCSDedicatedHost); - mGuests[guest->guestRef()] = guest; - 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(); -} - - -void CodeSigningHost::setGuestStatus(SecGuestRef guestRef, uint32_t status, const CssmData &attributes) -{ - StLock _(mLock); - if (mHostingState != proxyHosting) - MacOSError::throwMe(errSecCSHostProtocolNotProxy); - Guest *guest = findGuest(guestRef); - - // state modification machine - if ((status & ~guest->status) & kSecCodeStatusValid) - MacOSError::throwMe(errSecCSHostProtocolStateError); // can't set - if ((~status & guest->status) & (kSecCodeStatusHard | kSecCodeStatusKill)) - MacOSError::throwMe(errSecCSHostProtocolStateError); // can't clear - guest->status = status; - secnotice("SecServer", "%d guest change %d %d", mHostingPort.port(), guestRef, status); - - // replace attributes if requested - if (attributes) - guest->setAttributes(attributes); -} - - -// -// Remove a guest previously introduced via createGuest(). -// -void CodeSigningHost::removeGuest(SecGuestRef hostRef, SecGuestRef guestRef) -{ - StLock _(mLock); - if (mHostingState != proxyHosting) - MacOSError::throwMe(errSecCSHostProtocolNotProxy); - RefPointer host = findHost(hostRef); - RefPointer guest = findGuest(guestRef); - if (guest->dedicated) // can't remove a dedicated guest - MacOSError::throwMe(errSecCSHostProtocolDedicationError); - if (!guest->isGuestOf(host, strict)) - MacOSError::throwMe(errSecCSHostProtocolUnrelated); - - set matchingGuests; - - for (auto &it : mGuests) { - if (it.second->isGuestOf(guest, loose)) { - matchingGuests.insert(it.first); - } - } - - for (auto &it : matchingGuests) { - secnotice("SecServer", "%d guest destroy %d", mHostingPort.port(), it); - mGuests.erase(it); - } -} - - -// -// The internal Guest object -// -CodeSigningHost::Guest::Guest() : mAttrData(NULL), mAttrDataLength(0) -{ -} - -CodeSigningHost::Guest::~Guest() -{ - if (mAttrData != NULL) { - vm_size_t rounded_size = mach_vm_round_page(mAttrDataLength); - vm_deallocate(mach_task_self(), reinterpret_cast(mAttrData), rounded_size); - } -} - -void CodeSigningHost::Guest::setAttributes(const CssmData &attrData) -{ - CFRef guest = makeCFNumber(guestRef()); - if (attrData) { - CFDictionaryRef attrs = makeCFDictionaryFrom(attrData.data(), attrData.length()); - attributes.take(cfmake("{+%O,%O=%O}", - attrs, kSecGuestAttributeCanonical, guest.get())); - CFReleaseNull(attrs); - } else { - attributes.take(makeCFDictionary(1, kSecGuestAttributeCanonical, guest.get())); - } -} - -void CodeSigningHost::Guest::createAttrData() const { - if (!mAttrData) { - CFRef data = makeCFData(this->attributes.get()); - - /* cshosting_server_identifyGuest() will point to the attrData in a MIG - * OOL buffer. To prevent leaking surrounding memory, the attr data gets its - * own (zeroed) pages. */ - vm_address_t addr = 0; - vm_size_t rounded_size = mach_vm_round_page(CFDataGetLength(data.get())); - kern_return_t ret = vm_allocate(mach_task_self(), &addr, rounded_size, VM_FLAGS_ANYWHERE); - - if (ret == KERN_SUCCESS) { - mAttrData = reinterpret_cast(addr); - mAttrDataLength = CFDataGetLength(data.get()); - memcpy(mAttrData, CFDataGetBytePtr(data.get()), mAttrDataLength); - // pages returned by vm_allocate are zeroed, no need to fill out padding. - } else { - secerror("csproxy attrData vm_allocate failed: %d", ret); - } - } -} - -void CodeSigningHost::Guest::setHash(const CssmData &given, bool generate) -{ - if (given.length()) // explicitly given - this->cdhash.take(makeCFData(given)); - else if (CFTypeRef hash = CFDictionaryGetValue(this->attributes, kSecGuestAttributeHash)) - if (CFGetTypeID(hash) == CFDataGetTypeID()) - this->cdhash = CFDataRef(hash); - else - MacOSError::throwMe(errSecCSHostProtocolInvalidHash); - else if (generate) { // generate from path (well, try) - CFRef code; - MacOSError::check(SecStaticCodeCreateWithPath(CFTempURL(this->path), kSecCSDefaultFlags, &code.aref())); - CFRef info; - MacOSError::check(SecCodeCopySigningInformation(code, kSecCSDefaultFlags, &info.aref())); - this->cdhash = CFDataRef(CFDictionaryGetValue(info, kSecCodeInfoUnique)); - } -} - - -bool CodeSigningHost::Guest::isGuestOf(Guest *host, GuestCheck check) const -{ - vector hostPath; - if (host) - hostPath = host->guestPath; - if (hostPath.size() <= guestPath.size() - && !memcmp(&hostPath[0], &guestPath[0], sizeof(SecGuestRef) * hostPath.size())) - // hostPath is a prefix of guestPath - switch (check) { - case loose: - return true; - case strict: - return guestPath.size() == hostPath.size() + 1; // immediate guest - } - return false; -} - - -// -// Check to see if a given guest matches the (possibly empty) attribute set provided -// (in broken-open form, for efficiency). A dedicated guest will match all attribute -// specifications, even empty ones. A non-dedicated guest matches if at least one -// attribute value requested matches exactly (in the sense of CFEqual) that given -// by the host for this guest. -// -bool CodeSigningHost::Guest::matches(CFIndex count, CFTypeRef keys[], CFTypeRef values[]) const -{ - if (dedicated) - return true; - for (CFIndex n = 0; n < count; n++) { - CFStringRef key = CFStringRef(keys[n]); - if (CFEqual(key, kSecGuestAttributeCanonical)) // ignore canonical attribute (handled earlier) - continue; - if (CFTypeRef value = CFDictionaryGetValue(attributes, key)) - if (CFEqual(value, values[n])) - return true; - } - return false; -} - - -// -// The MachServer dispatch handler for proxy hosting. -// - -// give MIG handlers access to the object lock -class CodeSigningHost::Lock : private StLock { -public: - Lock(CodeSigningHost *host) : StLock(host->mLock) { } -}; - - -boolean_t cshosting_server(mach_msg_header_t *, mach_msg_header_t *); - -static ThreadNexus context; - -boolean_t CodeSigningHost::handle(mach_msg_header_t *in, mach_msg_header_t *out) -{ - CodeSigningHost::Lock _(this); - context() = this; - return cshosting_server(in, out); -} - - -// -// Proxy implementation of Code Signing Hosting protocol -// -#define CSH_ARGS mach_port_t servicePort, mach_port_t replyPort, OSStatus *rcode - -#define BEGIN_IPC try { -#define END_IPC *rcode = noErr; } \ - catch (const CommonError &err) { *rcode = err.osStatus(); } \ - catch (...) { *rcode = errSecCSInternalError; } \ - return KERN_SUCCESS; - -#define DATA_IN(base) void *base, mach_msg_type_number_t base##Length -#define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length -#define DATA(base) CssmData(base, base##Length) - - -// -// Find a guest by arbitrary attribute set. -// -// This returns an array of canonical guest references describing the path -// from the host given to the guest found. If the host itself is returned -// as a guest, this will be an empty array (zero length). -// -// The subhost return argument may in the future return the hosting port for -// a guest who dynamically manages its hosting (thus breaking out of proxy mode), -// but this is not yet implemented. -// -kern_return_t cshosting_server_findGuest(CSH_ARGS, SecGuestRef hostRef, - DATA_IN(attributes), - GuestChain *foundGuest, mach_msg_type_number_t *depth, mach_port_t *subhost) -{ - BEGIN_IPC - - *subhost = MACH_PORT_NULL; // preset no sub-hosting port returned - - Process::Guest *host = context()->findGuest(hostRef, true); - if (Process::Guest *guest = context()->findGuest(host, DATA(attributes))) { - *foundGuest = &guest->guestPath[0]; - *depth = int_cast(guest->guestPath.size()); - } else { - *foundGuest = NULL; - *depth = 0; - } - END_IPC -} - - -// -// Retrieve the path to a guest specified by canonical reference. -// -kern_return_t cshosting_server_identifyGuest(CSH_ARGS, SecGuestRef guestRef, - char *path, char *hash, uint32_t *hashLength, DATA_OUT(attributes)) -{ - BEGIN_IPC - CodeSigningHost::Guest *guest = context()->findGuest(guestRef); - strncpy(path, guest->path.c_str(), MAXPATHLEN); - - // canonical cdhash - if (guest->cdhash) { - *hashLength = int_cast(CFDataGetLength(guest->cdhash)); - assert(*hashLength <= maxUcspHashLength); - memcpy(hash, CFDataGetBytePtr(guest->cdhash), *hashLength); - } else - *hashLength = 0; // unavailable - - // visible attributes. This proxy returns all attributes set by the host - *attributes = (void*)guest->attrData(); // MIG botch (it doesn't need a writable pointer) - *attributesLength = int_cast(guest->attrDataLength()); - - END_IPC -} - - -// -// Retrieve the status word for a guest specified by canonical reference. -// -kern_return_t cshosting_server_guestStatus(CSH_ARGS, SecGuestRef guestRef, uint32_t *status) -{ - BEGIN_IPC - *status = context()->findGuest(guestRef)->status; - END_IPC -} - - -// -// Debug support -// -#if defined(DEBUGDUMP) - -void CodeSigningHost::dump() const -{ - StLock _(mLock); - switch (mHostingState) { - case noHosting: - break; - case dynamicHosting: - Debug::dump(" dynamic host port=%d", mHostingPort.port()); - break; - case proxyHosting: - Debug::dump(" proxy-host port=%d", mHostingPort.port()); - if (!mGuests.empty()) { - Debug::dump(" %d guests={", int(mGuests.size())); - for (GuestMap::const_iterator it = mGuests.begin(); it != mGuests.end(); ++it) { - if (it != mGuests.begin()) - Debug::dump(", "); - it->second->dump(); - } - Debug::dump("}"); - } - break; - } -} - -void CodeSigningHost::Guest::dump() const -{ - Debug::dump("%s[", path.c_str()); - for (vector::const_iterator it = guestPath.begin(); it != guestPath.end(); ++it) { - if (it != guestPath.begin()) - Debug::dump("/"); - Debug::dump("0x%x", *it); - } - Debug::dump("; status=0x%x attrs=%s]", - status, cfStringRelease(CFCopyDescription(attributes)).c_str()); -} - -#endif //DEBUGDUMP diff --git a/securityd/src/csproxy.h b/securityd/src/csproxy.h deleted file mode 100644 index 37785f76..00000000 --- a/securityd/src/csproxy.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2006-2008,2010 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@ - */ - - -// -// csproxy - Code Signing Hosting Proxy -// -#ifndef _H_CSPROXY -#define _H_CSPROXY - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using MachPlusPlus::Port; -using MachPlusPlus::MachServer; - - -// -// CodeSigningHost is a mix-in for an object representing a primary -// Code Signing host object. It performs two notionally separate functions: -// (1) Register a hosting port. -// (2) Optionally, maintain a guest registry to offload the host's work. -// -class CodeSigningHost : private MachServer::Handler { -public: - CodeSigningHost(); - ~CodeSigningHost(); - void reset(); - - enum HostingState { - noHosting, // is not a host (yet), could go either way - dynamicHosting, // gave us its own hosting port to keep - proxyHosting // we act as a proxy for it - }; - - enum GuestCheck { - strict, // direct guest relationship required - loose // indirect or identity is okay (prefix check) - }; - - struct Guest : public RefCount, public HandleObject { - public: - Guest(); - ~Guest(); - std::vector guestPath; // guest chain to this guest - uint32_t status; // dynamic status - std::string path; // canonical code path - CFRef attributes; // matching attributes set - CFRef cdhash; // hash of CodeDirectory as specified by host - bool dedicated; // host is dedicated (and this is the only guest) - - operator bool() const { return attributes; } // exists - SecGuestRef guestRef() const { return int_cast(handle()); } - void setAttributes(const CssmData &attrData); - uint8_t const *attrData() const { createAttrData(); return mAttrData; }; - CFIndex attrDataLength() const { createAttrData(); return mAttrDataLength; }; - void setHash(const CssmData &given, bool generate); - - bool isGuestOf(Guest *host, GuestCheck check) const; - bool matches(CFIndex count, CFTypeRef keys[], CFTypeRef values[]) const; - - IFDUMP(void dump() const); - - private: - void createAttrData() const; - - mutable uint8_t *mAttrData; // XML form of attributes (vm_allocate'd, must live until guest destruction) - mutable CFIndex mAttrDataLength; - }; - - void registerCodeSigning(mach_port_t hostingPort, SecCSFlags flags); - Port hostingPort() const { return mHostingPort; } - - SecGuestRef createGuest(SecGuestRef guest, - uint32_t status, const char *path, - const CssmData &cdhash, const CssmData &attributes, SecCSFlags flags); - void setGuestStatus(SecGuestRef guest, uint32_t status, const CssmData &attributes); - void removeGuest(SecGuestRef host, SecGuestRef guest); - -public: - IFDUMP(void dump() const); - -public: - // internal use only (public for use by MIG handlers) - Guest *findHost(SecGuestRef hostRef); // find most dedicated guest of this host - Guest *findGuest(Guest *host, const CssmData &attrData); // by host and attributes - Guest *findGuest(SecGuestRef guestRef, bool hostOk = false); // by guest reference - Guest *findGuest(Guest *host); // any guest of this host - - class Lock; - friend class Lock; - -private: - boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out); - void eraseGuest(Guest *guest); - -private: - mutable Mutex mLock; // protects everything below - - // host port registry - HostingState mHostingState; // status of hosting support - Port mHostingPort; // his or ours or NULL - - // guest map (only used if mHostingState == proxyHosting) - typedef std::map > GuestMap; - GuestMap mGuests; -}; - - -// -// Proxy implementation of Code Signing Hosting protocol -// -#define CSH_ARGS mach_port_t servicePort, mach_port_t replyPort, OSStatus *rcode - -#define DATA_IN(base) void *base, mach_msg_type_number_t base##Length -#define DATA_OUT(base) void **base, mach_msg_type_number_t *base##Length -#define DATA(base) CssmData(base, base##Length) - -// -// Find a guest by arbitrary attribute set. -// -// This returns an array of canonical guest references describing the path -// from the host given to the guest found. If the host itself is returned -// as a guest, this will be an empty array (zero length). -// -// The subhost return argument may in the future return the hosting port for -// a guest who dynamically manages its hosting (thus breaking out of proxy mode), -// but this is not yet implemented. -// -kern_return_t cshosting_server_findGuest(CSH_ARGS, SecGuestRef hostRef, - DATA_IN(attributes), - GuestChain *foundGuest, mach_msg_type_number_t *depth, mach_port_t *subhost); - -// -// Retrieve the path to a guest specified by canonical reference. -// -kern_return_t cshosting_server_identifyGuest(CSH_ARGS, SecGuestRef guestRef, - char *path, char *hash, uint32_t *hashLength, DATA_OUT(attributes)); - -// -// Retrieve the status word for a guest specified by canonical reference. -// -kern_return_t cshosting_server_guestStatus(CSH_ARGS, SecGuestRef guestRef, uint32_t *status); - -#undef CSH_ARGS -#undef DATA_IN -#undef DATA_OUT -#undef DATA - -#endif //_H_CSPROXY diff --git a/securityd/src/dbcrypto.cpp b/securityd/src/dbcrypto.cpp index 7aaf8c50..4fed2f52 100644 --- a/securityd/src/dbcrypto.cpp +++ b/securityd/src/dbcrypto.cpp @@ -26,6 +26,7 @@ // dbcrypto - cryptographic core for database and key blob cryptography // #include "dbcrypto.h" +#include "SecRandom.h" #include #include #include "server.h" // just for Server::csp() @@ -141,8 +142,9 @@ void DatabaseCryptoCore::setup(const DbBlob *blob, const CssmData &passphrase, b } memcpy(mSalt, blob->salt, sizeof(mSalt)); } else { - Server::active().random(mSalt); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mSalt), mSalt)); } + mMasterKey = deriveDbMasterKey(passphrase); mHaveMaster = true; } @@ -169,7 +171,7 @@ void DatabaseCryptoCore::setup(const DbBlob *blob, CssmClient::Key master, bool } memcpy(mSalt, blob->salt, sizeof(mSalt)); } else { - Server::active().random(mSalt); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mSalt), mSalt)); } mMasterKey = master; mHaveMaster = true; @@ -235,7 +237,7 @@ DbBlob *DatabaseCryptoCore::encodeCore(const DbBlob &blobTemplate, // make a new IV uint8 iv[8]; - Server::active().random(iv); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(iv), iv)); // build the encrypted section blob CssmData &encryptionBits = *mEncryptionKey; @@ -393,7 +395,7 @@ KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey, assert(isValid()); // need our database secrets // create new IV - Server::active().random(iv); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(iv), iv)); // use a CMS wrap to encrypt the key WrapKey wrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE); diff --git a/securityd/src/kcdatabase.cpp b/securityd/src/kcdatabase.cpp index fcf017da..170a43cf 100644 --- a/securityd/src/kcdatabase.cpp +++ b/securityd/src/kcdatabase.cpp @@ -43,6 +43,7 @@ #include "server.h" #include "session.h" #include "notifications.h" +#include "SecRandom.h" #include // @@@ 4003540 workaround #include // for default owner ACLs #include @@ -53,6 +54,7 @@ #include #include #include +#include #include "securityd_service/securityd_service/securityd_service_client.h" #include #include @@ -265,7 +267,8 @@ KeychainDatabase::KeychainDatabase(const DLDbIdentifier &id, const DBParameters // create a new random signature to complete the DLDbIdentifier DbBlob::Signature newSig; - Server::active().random(newSig.bytes); + + (MacOSError::check)(SecRandomCopyBytes(kSecRandomDefault, sizeof(newSig.bytes), newSig.bytes)); DbIdentifier ident(id, newSig); // create common block and initialize @@ -279,7 +282,7 @@ KeychainDatabase::KeychainDatabase(const DLDbIdentifier &id, const DBParameters // new common is now visible (in ident-map) but we hold its lock // establish the new master secret - establishNewSecrets(cred, SecurityAgent::newDatabase); + establishNewSecrets(cred, SecurityAgent::newDatabase, false); // set initial database parameters common().mParams = params; @@ -685,7 +688,6 @@ void KeychainDatabase::encode() common().mParams.idleTimeout, common().mParams.lockOnSleep); } - // // Change the passphrase on a database // @@ -694,18 +696,34 @@ void KeychainDatabase::changePassphrase(const AccessCredentials *cred) // get and hold the common lock (don't let other threads break in here) StLock _(common()); - if (!checkCredentials(cred)) { + list samples; + bool hasOldSecret = cred && cred->samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, samples); + samples.clear(); // Can't count the samples at the end because I could specify CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK twice + bool hasNewSecret = cred && cred->samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, samples); + + // If no creds we do interactive, if both we do silently. If unequal, think harder. + if (hasOldSecret != hasNewSecret) { + if (!hasOldSecret && !isLocked()) { + // Alternative: do a confirm_access SA dialog and run validatePassphrase on it (what client name?) + // That's risky for now, but it would cover the remaining use case. + secerror("KCdb: changePassphrase credential set has no old secret and KC not locked"); + MacOSError::throwMe(errSecAuthFailed); + } + } + + secnotice("KCdb", "changePassphrase proceeding with old %i, new %i, locked %i", hasOldSecret, hasNewSecret, isLocked()); + + if (hasOldSecret && !checkCredentials(cred)) { secinfo("KCdb", "Cannot change passphrase for (%s): existing passphrase does not match", common().dbName()); MacOSError::throwMe(errSecAuthFailed); } - // establish OLD secret - i.e. unlock the database - //@@@ do we want to leave the final lock state alone? + // establish OLD secret - i.e. unlock the database. You'll be prompted if !hasOldSecrets and DB is locked. if (common().isLoginKeychain()) mSaveSecret = true; makeUnlocked(cred, false); // establish NEW secret - if(!establishNewSecrets(cred, SecurityAgent::changePassphrase)) { + if(!establishNewSecrets(cred, SecurityAgent::changePassphrase, true)) { secinfo("KCdb", "Old and new passphrases are the same. Database %s(%p) master secret did not change.", common().dbName(), this); return; @@ -1227,7 +1245,7 @@ uint32_t KeychainDatabase::getInteractiveUnlockAttempts() { // // Same thing, but obtain a new secret somehow and set it into the common. // -bool KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason) +bool KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason, bool change) { list samples; if (creds && creds->samples().collect(CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, samples)) { @@ -1321,6 +1339,10 @@ bool KeychainDatabase::establishNewSecrets(const AccessCredentials *creds, Secur SecurityAgent::Reason reason(query(oldPassphrase, passphrase)); uisync.unlock(); if (reason == SecurityAgent::noReason) { + // If the DB was already unlocked then we have not yet checked the caller knows the old passphrase. Do so here. + if (change && !validatePassphrase(oldPassphrase.get())) { + MacOSError::throwMe(errSecAuthFailed); + } common().setup(NULL, passphrase); change_secret_on_keybag(*this, oldPassphrase.data(), (int)oldPassphrase.length(), passphrase.data(), (int)passphrase.length()); return true; diff --git a/securityd/src/kcdatabase.h b/securityd/src/kcdatabase.h index f321fc19..1d6c0b0e 100644 --- a/securityd/src/kcdatabase.h +++ b/securityd/src/kcdatabase.h @@ -278,7 +278,7 @@ protected: void makeUnlocked(const CssmData &passphrase, bool unlockKeybag); // interior version of unlock(CssmData) void establishOldSecrets(const AccessCredentials *creds); - bool establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason); + bool establishNewSecrets(const AccessCredentials *creds, SecurityAgent::Reason reason, bool change); bool interactiveUnlock(); diff --git a/securityd/src/main.cpp b/securityd/src/main.cpp index 568432f5..5eb758a8 100644 --- a/securityd/src/main.cpp +++ b/securityd/src/main.cpp @@ -33,6 +33,7 @@ #include "pcscmonitor.h" #include "auditevents.h" #include "self.h" +#include "util.h" #include #include @@ -58,6 +59,7 @@ #include "acl_keychain.h" #include "acl_partition.h" +#include // // Local functions of the main program driver @@ -65,7 +67,7 @@ static void usage(const char *me) __attribute__((noreturn)); static void handleSignals(int sig); static PCSCMonitor::ServiceLevel scOptions(const char *optionString); - +static bool legacyTokensEnabled(void); static Port gMainServerPort; PCSCMonitor *gPCSC; @@ -76,13 +78,27 @@ PCSCMonitor *gPCSC; // int main(int argc, char *argv[]) { + DisableLocalization(); + // clear the umask - we know what we're doing secnotice("SecServer", "starting umask was 0%o", ::umask(0)); ::umask(0); // tell the keychain (client) layer to turn off the server interface SecKeychainSetServerMode(); - + + const char *params[] = {"LEGACY_TOKENS_ENABLED", legacyTokensEnabled() ? "YES" : "NO", NULL}; + char* errorbuf = NULL; + if (sandbox_init_with_parameters("com.apple.securityd", SANDBOX_NAMED, params, &errorbuf)) { + seccritical("SecServer: unable to enter sandbox: %{public}s", errorbuf); + if (errorbuf) { + sandbox_free_error(errorbuf); + } + exit(1); + } else { + secnotice("SecServer", "entered sandbox"); + } + // program arguments (preset to defaults) bool debugMode = false; const char *bootstrapName = NULL; @@ -307,13 +323,30 @@ static void usage(const char *me) exit(2); } +const CFStringRef kTKSmartCardPreferencesDomain = CFSTR("com.apple.security.smartcard"); +const CFStringRef kTKLegacyTokendPreferencesKey = CFSTR("Legacy"); + +static bool legacyTokensEnabled() { + bool result = false; + CFPropertyListRef value = CFPreferencesCopyValue(kTKLegacyTokendPreferencesKey, kTKSmartCardPreferencesDomain, kCFPreferencesAnyUser, kCFPreferencesCurrentHost); + if (value) { + if (CFEqual(value, kCFBooleanTrue)) { + result = true; + } + CFRelease(value); + } + return result; +} // // Translate strings (e.g. "conservative") into PCSCMonitor service levels // static PCSCMonitor::ServiceLevel scOptions(const char *optionString) { - if (optionString) + if (!legacyTokensEnabled()) + return PCSCMonitor::forcedOff; + + if (optionString) if (!strcmp(optionString, "off")) return PCSCMonitor::forcedOff; else if (!strcmp(optionString, "on")) diff --git a/securityd/src/notifications.cpp b/securityd/src/notifications.cpp index f4682cc5..1efed3a5 100644 --- a/securityd/src/notifications.cpp +++ b/securityd/src/notifications.cpp @@ -299,10 +299,10 @@ bool SharedMemoryListener::needsPrivacyFilter(Notification *notification) { case kSecUnlockEvent: // kNotificationEventUnlocked case kSecPasswordChangedEvent: // kNotificationEventPassphraseChanged case kSecDefaultChangedEvent: - case kSecDataAccessEvent: case kSecKeychainListChangedEvent: case kSecTrustSettingsChangedEvent: return false; + case kSecDataAccessEvent: case kSecAddEvent: case kSecDeleteEvent: case kSecUpdateEvent: diff --git a/securityd/src/process.cpp b/securityd/src/process.cpp index b3193798..9ab05df8 100644 --- a/securityd/src/process.cpp +++ b/securityd/src/process.cpp @@ -43,7 +43,7 @@ Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCri : mTaskPort(taskPort), mByteFlipped(false), mPid(audit.pid()), mUid(audit.euid()), mGid(audit.egid()), mAudit(audit) { StLock _(*this); - + xpc_transaction_begin(); // set parent session parent(Session::find(audit.sessionId(), true)); @@ -74,7 +74,7 @@ Process::Process(TaskPort taskPort, const ClientSetupInfo *info, const CommonCri // as it is not protected against its underlying process's destruction. if (this->pid() == getpid() // called ourselves (through some API). Do NOT record this as a "dirty" transaction || ServerChild::find(this->pid())) // securityd's child; do not mark this txn dirty - VProc::Transaction::deactivate(); + xpc_transaction_end(); 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); @@ -103,7 +103,6 @@ void Process::reset(TaskPort taskPort, const ClientSetupInfo *info, const Common secnotice("SecServer", "%p Client reset amnesia", this); } else { secnotice("SecServer", "%p Client reset full", this); - CodeSigningHost::reset(); } } @@ -142,6 +141,7 @@ Process::~Process() if (mTaskPort) { mTaskPort.deallocate(); } + xpc_transaction_end(); } void Process::kill() @@ -209,7 +209,6 @@ void Process::dumpNode() Debug::dump(" FLIPPED"); Debug::dump(" task=%d pid=%d uid/gid=%d/%d", mTaskPort.port(), mPid, mUid, mGid); - CodeSigningHost::dump(); ClientIdentification::dump(); } diff --git a/securityd/src/process.h b/securityd/src/process.h index 00be3cbd..8e1bcd37 100644 --- a/securityd/src/process.h +++ b/securityd/src/process.h @@ -32,9 +32,7 @@ #include "session.h" #include #include -#include #include "clientid.h" -#include "csproxy.h" #include "localkey.h" #include "notifications.h" #include @@ -53,23 +51,12 @@ class AuthorizationToken; // the process nature of the client. Individual threads in the client are tracked by // Connection objects. // -// Code Signing-style Guest identities are managed in two of our mix-ins. The two play -// distinct but related roles: -// * CodeSigningHost manages the public identity of guests within the client. -// In this relationship, securityd provides registry and proxy services to the client. -// * ClientIdentification tracks the identity of guests in the client *as securityd clients*. -// It is concerned with which guest is asking for securityd services, and whether this -// should be granted. -// Often, the two form a loop: ClientIdentification uses CodeSigningHost to determine -// the guest client identity, but it does so through public (Mach IPC) interfaces, because -// clients may implement their own proxy (though currently not registry) services. -// We could short-circuit the IPC leg in those cases where securityd serves itself, -// but there's no evidence (yet) that this is worth the trouble. +// ClientIdentification tracks the identity of guests in the client *as securityd clients*. +// It is concerned with which guest is asking for securityd services, and whether this +// should be granted. // class Process : public PerProcess, - public CodeSigningHost, - public ClientIdentification, - private VProc::Transaction { + public ClientIdentification{ public: Process(TaskPort tPort, const ClientSetupInfo *info, const CommonCriteria::AuditToken &audit); virtual ~Process(); @@ -111,6 +98,7 @@ private: pid_t mPid; // process id uid_t mUid; // UNIX uid credential gid_t mGid; // primary UNIX gid credential + Security::CommonCriteria::AuditToken const mAudit; // audit token // canonical local (transient) key store diff --git a/securityd/src/securityd.entitlements b/securityd/src/securityd.entitlements new file mode 100644 index 00000000..ec8b2bc0 --- /dev/null +++ b/securityd/src/securityd.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.smartcard + + com.apple.private.tcc.allow + + kTCCServiceSystemPolicyAllFiles + + + diff --git a/securityd/src/securityd.order b/securityd/src/securityd.order index b917fdbb..dcc602e4 100644 --- a/securityd/src/securityd.order +++ b/securityd/src/securityd.order @@ -750,8 +750,6 @@ __ZN7TempKeyD0Ev __ZThn16_N16KeychainDatabaseD0Ev __ZThn16_N12TempDatabaseD0Ev __ZNSt8_Rb_treeIjSt4pairIKjN20ClientIdentification10GuestStateEESt10_Select1stIS4_ESt4lessIjESaIS4_EE15_M_destroy_nodeEPSt13_Rb -__ZL13_XhostingPortP17mach_msg_header_tS0_ -__Z23ucsp_server_hostingPortjj13audit_token_tPiiPj __ZNK6Server7findPidEi __ZNKSt8_Rb_treeIiSt4pairIKiP7ProcessESt10_Select1stIS4_ESt4lessIiESaIS4_EE4findERS1_ __ZNSt6vectorIN13Authorization11AuthItemRefESaIS1_EE9push_backERKS1_ diff --git a/securityd/src/server.cpp b/securityd/src/server.cpp index 6ebc34c9..d510615c 100644 --- a/securityd/src/server.cpp +++ b/securityd/src/server.cpp @@ -241,23 +241,6 @@ void Server::setupConnection(ConnectLevel type, Port replyPort, Port taskPort, notifyIfDead(replyPort); } - -// -// Synchronously end a Connection. -// This is due to a request from the client, so no thread races are possible. -// In practice, this is optional since the DPN for the client thread reply port -// will destroy the connection anyway when the thread dies. -// -void Server::endConnection(Port replyPort) -{ - StLock _(*this); - PortMap::iterator it = mConnections.find(replyPort); - assert(it != mConnections.end()); - it->second->terminate(); - mConnections.erase(it); -} - - // // Handling dead-port notifications. // This receives DPNs for all kinds of ports we're interested in. @@ -277,7 +260,6 @@ void Server::notifyDeadName(Port port) RefPointer con = conIt->second; mConnections.erase(conIt); serverLock.unlock(); - con->abort(); return; } @@ -323,6 +305,7 @@ kern_return_t self_server_handleSignal(mach_port_t sport, secnotice("SecServer", "signal handled %d", sig); if (taskPort != mach_task_self()) { Syslog::error("handleSignal: received from someone other than myself"); + mach_port_deallocate(mach_task_self(), taskPort); return KERN_SUCCESS; } switch (sig) { @@ -459,9 +442,10 @@ void Server::beginShutdown() mShuttingDown = true; Session::invalidateAuthHosts(); secnotice("SecServer", "%p beginning shutdown", this); - if (verbosity() >= 2) { + shutdownReport(); // always tell me about residual clients... + if (verbosity() >= 2) { // ...and if we really care write to the log, too reportFile = fopen("/var/log/securityd-shutdown.log", "w"); - shutdownSnitch(); + shutdownReport_file(); } } } @@ -478,16 +462,24 @@ void Server::eventDone() { StLock lock(*this); if (this->shuttingDown()) { + shutdownReport(); if (verbosity() >= 2) { - secnotice("SecServer", "shutting down with %ld processes and %ld transactions", mProcesses.size(), VProc::Transaction::debugCount()); - shutdownSnitch(); + secnotice("SecServer", "shutting down with %ld processes", mProcesses.size()); + shutdownReport_file(); } - IFDUMPING("shutdown", NodeCore::dumpAll()); } } +void Server::shutdownReport() +{ + PidMap mPidsCopy = PidMap(mPids); + secnotice("shutdown", "Residual clients count: %d", int(mPidsCopy.size())); + for (PidMap::const_iterator it = mPidsCopy.begin(); it != mPidsCopy.end(); ++it) { + secnotice("shutdown", "Residual client: %d", it->first); + } +} -void Server::shutdownSnitch() +void Server::shutdownReport_file() { time_t now; time(&now); @@ -502,7 +494,11 @@ void Server::shutdownSnitch() bool Server::inDarkWake() { - return IOPMIsADarkWake(IOPMConnectionGetSystemCapabilities()); + bool inDarkWake = IOPMIsADarkWake(IOPMConnectionGetSystemCapabilities()); + if (inDarkWake) { + secnotice("SecServer", "Server::inDarkWake returned inDarkWake"); + } + return inDarkWake; } // @@ -515,7 +511,7 @@ void Server::loadCssm(bool mdsIsInstalled) { if (!mCssm->isActive()) { StLock _(*this); - VProc::Transaction xact; + xpc_transaction_begin(); if (!mCssm->isActive()) { if (!mdsIsInstalled) { // non-system securityd instance should not reinitialize MDS secnotice("SecServer", "Installing MDS"); @@ -527,6 +523,7 @@ void Server::loadCssm(bool mdsIsInstalled) mCSP->attach(); secnotice("SecServer", "CSSM ready with CSP %s", mCSP->guid().toString().c_str()); } + xpc_transaction_end(); } } diff --git a/securityd/src/server.h b/securityd/src/server.h index 76c776ee..c11fabe7 100644 --- a/securityd/src/server.h +++ b/securityd/src/server.h @@ -34,9 +34,6 @@ #include #include #include -#include -#include -#include #include "codesigdb.h" #include "connection.h" #include "key.h" @@ -57,8 +54,7 @@ // findFirst/allReferences feature of Node<>. // class Server : public PerGlobal, - public MachPlusPlus::MachServer, - public UniformRandomBlobs { + public MachPlusPlus::MachServer { public: Server(CodeSignatures &signatures, const char *bootstrapName); ~Server(); @@ -176,7 +172,8 @@ public: void waitForClients(bool waiting); // set waiting behavior void beginShutdown(); // start delayed shutdown if configured bool shuttingDown() const { return mShuttingDown; } - void shutdownSnitch(); // report lingering clients + void shutdownReport(); // report lingering clients to the log + void shutdownReport_file(); // report lingering clients to file bool inDarkWake(); void associateThread() { perThread().server = this; } diff --git a/securityd/src/session.cpp b/securityd/src/session.cpp index 75990e12..69fbf6a6 100644 --- a/securityd/src/session.cpp +++ b/securityd/src/session.cpp @@ -95,7 +95,6 @@ Server &Session::server() const return parent(); } - // // Locate a session object by session identifier // @@ -245,16 +244,22 @@ void Session::invalidateSessionAuthHosts() StLock _(mAuthHostLock); // if you got here, we don't care about pending operations: the auth hosts die - Syslog::warning("Killing auth hosts"); - if (mSecurityAgent) mSecurityAgent->UnixPlusPlus::Child::kill(SIGTERM); + Syslog::warning("Killing auth hosts for session %d", this->sessionId()); + if (mSecurityAgent) { + secnotice("shutdown", "SIGTERMing child in state %d, pid %d", mSecurityAgent->UnixPlusPlus::Child::state(), mSecurityAgent->UnixPlusPlus::Child::pid()); + mSecurityAgent->UnixPlusPlus::Child::kill(SIGTERM); + } else { + secnotice("shutdown", "No securityagent for session %d", this->sessionId()); + } mSecurityAgent = NULL; } void Session::invalidateAuthHosts() { StLock _(mSessionLock); - for (SessionMap::const_iterator it = mSessions.begin(); it != mSessions.end(); it++) + for (SessionMap::const_iterator it = mSessions.begin(); it != mSessions.end(); it++) { it->second->invalidateSessionAuthHosts(); + } } // diff --git a/securityd/src/tokencache.cpp b/securityd/src/tokencache.cpp index 6b4cf91d..7eb53c9a 100644 --- a/securityd/src/tokencache.cpp +++ b/securityd/src/tokencache.cpp @@ -70,7 +70,8 @@ static unsigned long getFile(const string &path, unsigned long defaultValue) AutoFileDesc fd(path, O_RDONLY, FileDesc::modeMissingOk); if (fd) { string s; fd.readAll(s); - unsigned long value; sscanf(s.c_str(), "%lu", &value); + unsigned long value = defaultValue; + sscanf(s.c_str(), "%lu", &value); return value; } } catch (...) { diff --git a/securityd/src/transition.cpp b/securityd/src/transition.cpp index 20f8b182..ff606b4c 100644 --- a/securityd/src/transition.cpp +++ b/securityd/src/transition.cpp @@ -42,6 +42,7 @@ #include "child.h" #include #include +#include "SecRandom.h" #include #include #include @@ -49,6 +50,7 @@ #include #include #include +#include #include #include @@ -257,16 +259,6 @@ kern_return_t ucsp_server_setupThread(UCSP_ARGS, mach_port_t taskPort) return KERN_SUCCESS; } - -kern_return_t ucsp_server_teardown(UCSP_ARGS) -{ - BEGIN_IPCN - secinfo("SecServer", "request entry: teardown"); - Server::active().endConnection(replyPort); - END_IPCN(CSSM) - return KERN_SUCCESS; -} - kern_return_t ucsp_server_verifyPrivileged(UCSP_ARGS) { BEGIN_IPCN @@ -1131,30 +1123,6 @@ kern_return_t ucsp_server_deriveKey(UCSP_ARGS, DbHandle db, DATA_IN(context), Ke END_IPC(CSP) } - -// -// Random generation -// -kern_return_t ucsp_server_generateRandom(UCSP_ARGS, uint32 ssid, DATA_IN(context), DATA_OUT(data)) -{ - BEGIN_IPC(generateRandom) - CopyOutContext ctx(context, contextLength); - if (ssid) - CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED); - - // default version (use /dev/random) - Allocator &allocator = Allocator::standard(Allocator::sensitive); - if (size_t bytes = ctx.context().getInt(CSSM_ATTRIBUTE_OUTPUT_SIZE)) { - void *buffer = allocator.malloc(bytes); - Server::active().random(buffer, bytes); - *data = buffer; - *dataLength = int_cast(bytes); - Server::releaseWhenDone(allocator, buffer); - } - END_IPC(CSP) -} - - // // ACL management. // Watch out for the memory-management tap-dance. @@ -1350,78 +1318,16 @@ kern_return_t ucsp_server_postNotification(UCSP_ARGS, uint32 domain, uint32 even // Child check-in service. // Note that this isn't using the standard argument pattern. // -kern_return_t ucsp_server_childCheckIn(mach_port_t serverPort, +kern_return_t ucsp_server_childCheckIn(audit_token_t auditToken, mach_port_t serverPort, mach_port_t servicePort, mach_port_t taskPort) { BEGIN_IPCS - ServerChild::checkIn(servicePort, TaskPort(taskPort).pid()); + ServerChild::checkIn(servicePort, audit_token_to_pid(auditToken)); + // Will be NULL from newer frameworks, but mach_port_deallocate doesn't seem to mind END_IPCS(mach_port_deallocate(mach_task_self(), taskPort)) } -// -// Code Signing Hosting registration. -// Note that the Code Signing Proxy facility (implementing the "cshosting" -// IPC protocol) is elsewhere. -// -kern_return_t ucsp_server_registerHosting(UCSP_ARGS, mach_port_t hostingPort, uint32 flags) -{ - BEGIN_IPC(registerHosting) - connection.process().registerCodeSigning(hostingPort, flags); - END_IPC(CSSM) -} - -kern_return_t ucsp_server_hostingPort(UCSP_ARGS, pid_t hostPid, mach_port_t *hostingPort) -{ - BEGIN_IPC(hostingPort) - if (RefPointer process = Server::active().findPid(hostPid)) - *hostingPort = process->hostingPort(); - else - *hostingPort = MACH_PORT_NULL; - secinfo("hosting", "hosting port for for pid=%d is port %d", hostPid, *hostingPort); - END_IPC(CSSM) -} - - -kern_return_t ucsp_server_setGuest(UCSP_ARGS, SecGuestRef guest, SecCSFlags flags) -{ - BEGIN_IPC(setGuest) - connection.guestRef(guest, flags); - END_IPC(CSSM) -} - - -kern_return_t ucsp_server_createGuest(UCSP_ARGS, SecGuestRef host, - uint32_t status, const char *path, DATA_IN(cdhash), DATA_IN(attributes), - SecCSFlags flags, SecGuestRef *newGuest) -{ - BEGIN_IPC(createGuest) - checkPathLength(path); - *newGuest = connection.process().createGuest(host, status, path, DATA(cdhash), DATA(attributes), flags); - END_IPC(CSSM) -} - -kern_return_t ucsp_server_setGuestStatus(UCSP_ARGS, SecGuestRef guest, - uint32_t status, DATA_IN(attributes)) -{ - BEGIN_IPC(setGuestStatus) - connection.process().setGuestStatus(guest, status, DATA(attributes)); - END_IPC(CSSM) -} - -kern_return_t ucsp_server_removeGuest(UCSP_ARGS, SecGuestRef host, SecGuestRef guest) -{ - BEGIN_IPC(removeGuest) - connection.process().removeGuest(host, guest); - END_IPC(CSSM) -} - -kern_return_t ucsp_server_helpCheckLoad(UCSP_ARGS, const char path[PATH_MAX], uint32_t type) -{ - BEGIN_IPC(helpCheckLoad) - END_IPC(CSSM) -} - // // Testing-related RPCs // diff --git a/securityd/src/util.h b/securityd/src/util.h new file mode 100644 index 00000000..39745e15 --- /dev/null +++ b/securityd/src/util.h @@ -0,0 +1,36 @@ +/* + * 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 _UTIL +#define _UTIL + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus +void DisableLocalization(void); +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif // _UTIL diff --git a/securityd/src/util.m b/securityd/src/util.m new file mode 100644 index 00000000..9249ab30 --- /dev/null +++ b/securityd/src/util.m @@ -0,0 +1,31 @@ +/* + * 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 "util.h" + +#import + +void DisableLocalization(void) { + [NSError _setFileNameLocalizationEnabled:NO]; +} diff --git a/sslViewer/SSLViewer.c b/sslViewer/SSLViewer.c index 589d1da7..3cd0381e 100644 --- a/sslViewer/SSLViewer.c +++ b/sslViewer/SSLViewer.c @@ -23,7 +23,7 @@ #include "utilities/fileIo.h" #include "utilities/SecCFWrappers.h" #include "utilities/SecIOFormat.h" -#include "SecurityTool/print_cert.h" +#include "SecurityTool/sharedTool/print_cert.h" #define DEFAULT_GETMSG "GET" #define DEFAULT_PATH "/" @@ -206,7 +206,7 @@ static OSStatus sslEvaluateTrust( } SecTrustResultType secTrustResult; - ortn = SecTrustEvaluate(secTrust, &secTrustResult); + ortn = SecTrustGetTrustResult(secTrust, &secTrustResult); // implicitly does trust evaluate if(ortn) { printf("\n***Error on SecTrustEvaluate: %d\n", (int)ortn); return ortn; @@ -426,7 +426,11 @@ static OSStatus sslPing( } } } else { - SSLSetProtocolVersionMax(ctx, pargs->tryVersion); + ortn = SSLSetProtocolVersionMax(ctx, pargs->tryVersion); + if(ortn) { + printSslErrStr("SSLSetProtocolVersionMax", ortn); + goto cleanup; + } } if(pargs->resumableEnable) { @@ -660,7 +664,10 @@ cleanup: ; /* * always do close, even on error - to flush outgoing write queue */ - OSStatus cerr = SSLClose(ctx); + OSStatus cerr = errSecParam; + if (ctx) { + cerr = SSLClose(ctx); + } if(ortn == errSecSuccess) { ortn = cerr; } @@ -878,10 +885,13 @@ static void showSSLResult( sslGetProtocolVersionString(pargs->negVersion)); printf(" Negotiated CipherSuite : %s\n", sslGetCipherSuiteString(pargs->negCipher)); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" if(pargs->certState != kSSLClientCertNone) { printf(" Client Cert State : %s\n", sslGetClientCertStateString(pargs->certState)); } +#pragma clang diagnostic pop if(pargs->verbose) { printf(" Resumed Session : "); if(pargs->sessionWasResumed) { @@ -964,6 +974,8 @@ static SSLProtocol charToProt( char c, // 2, 3, t char **argv) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" switch(c) { case '2': return kSSLProtocol2; @@ -974,6 +986,7 @@ static SSLProtocol charToProt( default: usage(argv); } +#pragma clang diagnostic pop } int main(int argc, char **argv) @@ -1003,15 +1016,17 @@ int main(int argc, char **argv) bool doPause = false; bool pauseFirstLoop = false; bool verifyProt = false; - SSLProtocol maxProtocol = kTLSProtocol12; // for verifying negotiated - // protocol char *acceptedProts = NULL; char *keyChainName = NULL; char *getMsgSpec = NULL; bool vfyCertState = false; - SSLClientCertificateState expectCertState = kSSLClientCertNone; bool displayHandshakeTimes = false; bool completeCertChain = false; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + SSLClientCertificateState expectCertState = kSSLClientCertNone; + SSLProtocol maxProtocol = kTLSProtocol12; // for verifying negotiated protocol +#pragma clang diagnostic pop /* special case - one arg of "h" or "-h" or "hv" */ if(argc == 2) { @@ -1264,6 +1279,8 @@ int main(int argc, char **argv) usage(argv); } vfyCertState = true; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" switch(argp[2]) { case 'n': expectCertState = kSSLClientCertNone; @@ -1280,6 +1297,7 @@ int main(int argc, char **argv) default: usage(argv); } +#pragma clang diagnostic pop break; case 'z': pargs.password = &argp[2]; @@ -1352,6 +1370,8 @@ int main(int argc, char **argv) sigaction(SIGPIPE, &sa, NULL); } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" for(loop=0; loopkeychain) { - char kcPath[2000]; - const char *lbd = getenv("LOCAL_BUILD_DIR"); - if(lbd == NULL) { - printf("WARNING: no LOCAL_BUILD_DIR env var faound\n"); - lbd = ""; - } - snprintf(kcPath, 2000, "%s/%s", lbd, testParams->keychain); - SecKeychainRef kcRef = NULL; - CFArrayRef certArray = getSslCerts(kcPath, - false, // encryptOnly - false, // completeCertChain - NULL, // anchorFile - &kcRef); - if(kcRef) { - /* Unlock it */ - ortn = SecKeychainUnlock(kcRef, - strlen(testParams->kcPassword), testParams->kcPassword, - true); - if(ortn) { - cssmPerror("SecKeychainUnlock", ortn); - /* oh well */ - } - CFRelease(kcRef); - } - if(certArray == NULL) { - printf("***WARNING no keychain found at %s\n", kcPath); - } - ortn = SSLSetCertificate(ctx, certArray); - if(ortn) { - printSslErrStr("SSLSetAllowAnyRoot", ortn); - goto cleanup; - } - CFRelease(certArray); - } -#endif do { ortn = SSLHandshake(ctx); } while (ortn == errSSLWouldBlock); @@ -544,6 +509,8 @@ static int doSslPing( ortn = SSLClose(ctx); +#pragma clang diagnostic pop + cleanup: if(sock) { endpointShutdown(sock); diff --git a/sslViewer/sslServer.cpp b/sslViewer/sslServer.cpp index 699fb4b7..33b2bb64 100644 --- a/sslViewer/sslServer.cpp +++ b/sslViewer/sslServer.cpp @@ -45,7 +45,7 @@ #include #include -#include "SecurityTool/print_cert.h" +#include "SecurityTool/sharedTool/print_cert.h" #if NO_SERVER #include @@ -259,7 +259,9 @@ static OSStatus sslServe( size_t length; uint8_t rcvBuf[RCV_BUF_SIZE]; const char *outMsg = SERVER_MESSAGE; - + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" *negVersion = kSSLProtocolUnknown; *negCipher = SSL_NULL_WITH_NULL_NULL; *peerCerts = NULL; @@ -287,7 +289,7 @@ static OSStatus sslServe( if(ortn) { printSslErrStr("SSLNewContext", ortn); goto cleanup; - } + } ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite); if(ortn) { printSslErrStr("SSLSetIOFuncs", ortn); @@ -549,7 +551,10 @@ cleanup: } if(ctx) { SSLDisposeContext(ctx); - } + } + +#pragma clang diagnostic pop + /* FIXME - dispose of serverCerts */ return ortn; } @@ -625,10 +630,15 @@ static void showSSLResult( sslGetProtocolVersionString(negVersion)); printf(" Negotiated CipherSuite : %s\n", sslGetCipherSuiteString(negCipher)); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" if(certState != kSSLClientCertNone) { printf(" Client Cert State : %s\n", sslGetClientCertStateString(certState)); } +#pragma clang diagnostic pop + printf(" Resumed Session : "); if(sessionWasResumed) { for(unsigned dex=0; dex loop forever */ @@ -918,27 +900,7 @@ int main(int argc, char **argv) if(serverCerts == nil) { exit(1); } - } - else -#if 0 - if(doIdSearch) { - OSStatus ortn = sslIdentityPicker(NULL, anchorFile, true, NULL, &serverCerts); - if(ortn) { - printf("***IdentitySearch failure; aborting.\n"); - exit(1); - } - } - if(password) { - OSStatus ortn = SecKeychainUnlock(serverKc, strlen(password), password, true); - if(ortn) { - printf("SecKeychainUnlock returned %d\n", (int)ortn); - /* oh well */ - } - } -#else - (void) doIdSearch; -#endif - if(protXOnly) { + } else if(protXOnly) { switch(attemptProt) { case kTLSProtocol1: attemptProt = kTLSProtocol1Only; @@ -950,17 +912,8 @@ int main(int argc, char **argv) break; } } -#if 0 - if(dhParamsFile) { - int r = cspReadFile(dhParamsFile, &dhParams, &dhParamsLen); - if(r) { - printf("***Error reading diffie-hellman params from %s; aborting\n", - dhParamsFile); - } - } -#else - (void) dhParamsFile; -#endif + +#pragma clang diagnostic pop /* one-time only server port setup */ err = ListenForClients(portNum, nonBlocking, &listenSock); diff --git a/supd/Tests/NSDate+SFAnalyticsTests.m b/supd/Tests/NSDate+SFAnalyticsTests.m new file mode 100644 index 00000000..c5c462d2 --- /dev/null +++ b/supd/Tests/NSDate+SFAnalyticsTests.m @@ -0,0 +1,41 @@ +// +// NSDate+SFAnalyticsTests.m +// KeychainAnalyticsTests +// + +#import + +#import "../Analytics/NSDate+SFAnalytics.h" + +@interface NSDate_SFAnalyticsTests : XCTestCase + +@end + +@implementation NSDate_SFAnalyticsTests + +- (void)testCurrentTimeSeconds +{ + NSTimeInterval expectedTime = [[NSDate date] timeIntervalSince1970]; + NSTimeInterval actualTimeWithWiggle = [[NSDate date] timeIntervalSince1970]; + XCTAssertEqualWithAccuracy(actualTimeWithWiggle, expectedTime, 1, @"Expected to get roughly the same amount of seconds"); +} + +- (void)testCurrentTimeSecondsWithRounding +{ + NSTimeInterval factor = 3; // 3 seconds + + // Round into the same bucket + NSTimeInterval now = [[NSDate date] timeIntervalSince1970]; + NSTimeInterval expectedTime = now + factor; + NSTimeInterval actualTimeWithWiggle = [[NSDate date] timeIntervalSince1970WithBucket:SFAnalyticsTimestampBucketSecond]; + XCTAssertEqualWithAccuracy(actualTimeWithWiggle, expectedTime, factor, @"Expected to get roughly the same rounded time within the rounding factor"); + + // Round into the next bucket + now = [[NSDate date] timeIntervalSince1970]; + expectedTime = now + factor; + sleep(factor); + actualTimeWithWiggle = [[NSDate date] timeIntervalSince1970WithBucket:SFAnalyticsTimestampBucketSecond]; + XCTAssertEqualWithAccuracy(actualTimeWithWiggle, expectedTime, factor + 1, @"Expected to get roughly the same rounded time within the rounding factor"); +} + +@end diff --git a/supd/Tests/SFAnalyticsTests.m b/supd/Tests/SFAnalyticsTests.m index d0f16d12..fa4ce753 100644 --- a/supd/Tests/SFAnalyticsTests.m +++ b/supd/Tests/SFAnalyticsTests.m @@ -25,10 +25,12 @@ #import #import "SFAnalyticsDefines.h" #import "SFAnalyticsSQLiteStore.h" +#import "NSDate+SFAnalytics.h" #import "SFSQLite.h" #import #import #import +#import "keychain/analytics/TestResourceUsage.h" @interface UnitTestAnalytics : SFAnalytics + (NSString*)databasePath; @@ -84,9 +86,9 @@ static NSString* product = NULL; XCTAssertFalse([[_db fetch:@"select * from soft_failures"] next]); } -- (void)assertNoAllEvents +- (void)assertNoNotes { - XCTAssertFalse([[_db fetch:@"select * from all_events"] next]); + XCTAssertFalse([[_db fetch:@"select * from notes"] next]); } - (void)assertNoSamples @@ -96,18 +98,17 @@ static NSString* product = NULL; - (void)assertNoEventsAnywhere { - [self assertNoAllEvents]; + [self assertNoNotes]; [self assertNoSuccessEvents]; [self assertNoHardFailures]; [self assertNoSoftFailures]; [self assertNoSamples]; } -- (void)recentTimeStamp:(NSNumber*)timestamp +- (void)recentTimeStamp:(NSTimeInterval)timestamp timestampBucket:(SFAnalyticsTimestampBucket)bucket { - XCTAssert([timestamp isKindOfClass:[NSNumber class]], @"Timestamp is an NSNumber"); - NSDate* eventTime = [NSDate dateWithTimeIntervalSince1970:[timestamp doubleValue]]; - XCTAssertLessThanOrEqual([[NSDate date] timeIntervalSinceDate:eventTime], 5, @"Timestamp (%@) is pretty recent", timestamp); + NSTimeInterval roundedTimestamp = [[NSDate date] timeIntervalSince1970WithBucket:bucket]; + XCTAssertEqualWithAccuracy(roundedTimestamp, timestamp, 5, @"Timestamp is pretty recent (%f ~? %f)", timestamp, roundedTimestamp); } - (void)properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class attributes:(NSDictionary*)attrs @@ -127,18 +128,32 @@ static NSString* product = NULL; XCTAssertFalse([result next], @"only one row returned"); } +- (void)properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class timestampBucket:(SFAnalyticsTimestampBucket)bucket +{ + [self _properEventLogged:result eventType:eventType class:class timestampBucket:bucket]; + XCTAssertFalse([result next], @"only one row returned"); +} + - (void)_properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class +{ + [self _properEventLogged:result eventType:eventType class:class timestampBucket:SFAnalyticsTimestampBucketSecond]; +} + +- (void)_properEventLogged:(PQLResultSet*)result eventType:(NSString*)eventType class:(SFAnalyticsEventClass)class timestampBucket:(SFAnalyticsTimestampBucket)bucket { XCTAssert([result next], @"result found after adding an event"); NSError* error = nil; [result doubleAtIndex:1]; NSDictionary* rowdata = [NSPropertyListSerialization propertyListWithData:[result dataAtIndex:2] options:NSPropertyListImmutable format:nil error:&error]; XCTAssertNotNil(rowdata, @"able to deserialize db data, %@", error); - [self recentTimeStamp:rowdata[SFAnalyticsEventTime]]; + NSNumber *timestamp = rowdata[SFAnalyticsEventTime]; + XCTAssert([timestamp isKindOfClass:[NSNumber class]], @"Timestamp is an NSNumber"); + [self recentTimeStamp:([timestamp doubleValue] / 1000) timestampBucket:bucket]; // We need to convert to seconds, as its stored in milliseconds XCTAssertTrue([rowdata[SFAnalyticsEventType] isKindOfClass:[NSString class]] && [rowdata[SFAnalyticsEventType] isEqualToString:eventType], @"found eventType \"%@\" in db", eventType); - XCTAssertTrue([rowdata[SFAnalyticsEventClassKey] isKindOfClass:[NSNumber class]] && [rowdata[SFAnalyticsEventClassKey] intValue] == class, @"eventClass is %ld", class); + XCTAssertTrue([rowdata[SFAnalyticsEventClassKey] isKindOfClass:[NSNumber class]] && [rowdata[SFAnalyticsEventClassKey] intValue] == class, @"eventClass is %ld", (long)class); XCTAssertTrue([rowdata[@"build"] isEqualToString:build], @"event row includes build"); XCTAssertTrue([rowdata[@"product"] isEqualToString:product], @"event row includes product"); + XCTAssertTrue(rowdata[@"internal"], @"event row includes internal"); } - (void)checkSuccessCountsForEvent:(NSString*)eventType success:(int)success hard:(int)hard soft:(int)soft @@ -159,7 +174,7 @@ static NSString* product = NULL; PQLResultSet* result = [_db fetch:@"select * from samples"]; while ([result next]) { ++samplescount; - [self recentTimeStamp:[result numberAtIndex:1]]; + [self recentTimeStamp:[[result numberAtIndex:1] doubleValue] timestampBucket:SFAnalyticsTimestampBucketSecond]; if ([[result stringAtIndex:2] isEqual:samplerName]) { ++targetcount; [samplesfound addObject:[result numberAtIndex:3]]; @@ -206,6 +221,8 @@ static NSString* product = NULL; } else { NSLog(@"could not get build version/product, tests should fail"); } + + [TestResourceUsage monitorTestResourceUsage]; } - (void)setUp @@ -263,6 +280,8 @@ static NSString* product = NULL; - (void)testAddingEventsWithNilName { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" [_analytics logSuccessForEventNamed:nil]; [self assertNoEventsAnywhere]; @@ -274,6 +293,7 @@ static NSString* product = NULL; [_analytics noteEventNamed:nil]; [self assertNoEventsAnywhere]; +#pragma clang diagnostic pop } - (void)testLogSuccess @@ -286,8 +306,26 @@ static NSString* product = NULL; XCTAssert([result next], @"a row was found after adding an event"); XCTAssertEqual([result intAtIndex:0], 1, @"success count is 1 after adding an event"); XCTAssertFalse([result next], @"only one row found in success_count after inserting a single event"); - result = [_db fetch:@"select * from all_events"]; - [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSuccess]; + [self assertNoNotes]; + [self assertNoHardFailures]; + [self assertNoSoftFailures]; +} + +- (void)testLogWithRoundedTimestamp +{ + SFAnalyticsTimestampBucket bucket = SFAnalyticsTimestampBucketMinute; + + [_analytics logSoftFailureForEventNamed:@"unittestevent" withAttributes:nil timestampBucket:bucket]; + [self assertNoHardFailures]; + + // First check success_count has logged a soft failure + [self checkSuccessCountsForEvent:@"unittestevent" success:0 hard:0 soft:1]; + + // then check soft_failures itself + PQLResultSet* result = [_db fetch:@"select * from soft_failures"]; + [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure timestampBucket:bucket]; + [self assertNoNotes]; + [self assertNoHardFailures]; } - (void)testLogRecoverableFailure @@ -301,10 +339,8 @@ static NSString* product = NULL; // then check soft_failures itself PQLResultSet* result = [_db fetch:@"select * from soft_failures"]; [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure]; - - // finally check all_events - result = [_db fetch:@"select * from all_events"]; - [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure]; + [self assertNoNotes]; + [self assertNoHardFailures]; } - (void)testLogRecoverablyFailureWithAttributes @@ -318,10 +354,8 @@ static NSString* product = NULL; // then check soft_failures itself PQLResultSet* result = [_db fetch:@"select * from soft_failures"]; [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure attributes:attrs]; - - // finally check all_events - result = [_db fetch:@"select * from all_events"]; - [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassSoftFailure attributes:attrs]; + [self assertNoNotes]; + [self assertNoHardFailures]; } - (void)testLogUnrecoverableFailure @@ -335,10 +369,8 @@ static NSString* product = NULL; // then check hard_failures itself PQLResultSet* result = [_db fetch:@"select * from hard_failures"]; [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure]; - - // finally check all_events - result = [_db fetch:@"select * from all_events"]; - [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure]; + [self assertNoNotes]; + [self assertNoSoftFailures]; } - (void)testLogUnrecoverableFailureWithAttributes @@ -353,10 +385,8 @@ static NSString* product = NULL; // then check hard_failures itself PQLResultSet* result = [_db fetch:@"select * from hard_failures"]; [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure attributes:attrs]; - - // finally check all_events - result = [_db fetch:@"select * from all_events"]; - [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassHardFailure attributes:attrs]; + [self assertNoNotes]; + [self assertNoSoftFailures]; } - (void)testLogSeveralEvents @@ -387,7 +417,7 @@ static NSString* product = NULL; // First check success_count has logged a success [self checkSuccessCountsForEvent:@"unittestevent" success:1 hard:0 soft:0]; - PQLResultSet* result = [_db fetch:@"select * from all_events"]; + PQLResultSet* result = [_db fetch:@"select * from notes"]; [self properEventLogged:result eventType:@"unittestevent" class:SFAnalyticsEventClassNote]; } @@ -493,6 +523,8 @@ static NSString* product = NULL; - (void)testSamplerWithBadData { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" NSString* samplerName = [NSString stringWithFormat:@"UnitTestSamplerWithBadData_%li", (long)_testnum]; // bad name @@ -506,6 +538,7 @@ static NSString* product = NULL; }]); XCTAssertNil([_analytics addMetricSamplerForName:samplerName withTimeInterval:2.0f block:nil]); +#pragma clang diagnostic pop } - (void)testSamplerOncePerReport @@ -552,8 +585,11 @@ static NSString* product = NULL; - (void)testSamplerLogBadSample { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" [_analytics logMetric:nil withName:@"testsampler"]; [self checkSamples:@[] name:@"testsampler" totalSamples:0 accuracy:0.01f]; +#pragma clang diagnostic pop id badobj = [NSString stringWithUTF8String:"yolo!"]; [_analytics logMetric:badobj withName:@"testSampler"]; @@ -705,6 +741,8 @@ static NSString* product = NULL; - (void)testTrackerBadData { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" // Inspect database to find out it's empty [_analytics logMetric:nil withName:@"fake"]; [_analytics logMetric:@3.0 withName:nil]; @@ -713,6 +751,7 @@ static NSString* product = NULL; XCTAssertNil([_analytics logSystemMetricsForActivityNamed:nil withAction:^{return;}]); [self assertNoEventsAnywhere]; +#pragma clang diagnostic pop } // MARK: Miscellaneous @@ -731,7 +770,10 @@ static NSString* product = NULL; XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate dateWithTimeIntervalSinceNow:secondsPerDay * -77]], 30); XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate dateWithTimeIntervalSinceNow:secondsPerDay * -370]], 365); XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:[NSDate distantPast]], 1000); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" XCTAssertEqual([SFAnalytics fuzzyDaysSinceDate:nil], -1); +#pragma clang diagnostic pop } - (void)testRingBuffer { @@ -743,11 +785,6 @@ static NSString* product = NULL; PQLResultSet* result = [_db fetch:@"select count(*) from hard_failures"]; XCTAssertTrue([result next], @"Got a count from hard_failures"); XCTAssertLessThanOrEqual([result unsignedIntAtIndex:0], SFAnalyticsMaxEventsToReport, @"Ring buffer contains a sane number of events"); - - // all_events has a much larger buffer so it should handle the extra events okay - result = [_db fetch:@"select count(*) from all_events"]; - XCTAssertTrue([result next], @"Got a count from all_events"); - XCTAssertLessThanOrEqual([result unsignedIntAtIndex:0], SFAnalyticsMaxEventsToReport + 50); } - (void)testRaceToCreateLoggers @@ -773,9 +810,10 @@ static NSString* product = NULL; NSDate* test = [NSDate date]; [_analytics setDateProperty:test forKey:propertyKey]; NSDate* retrieved = [_analytics datePropertyForKey:propertyKey]; - XCTAssert(retrieved); + XCTAssertNotNil(retrieved); // Storing in SQLite as string loses subsecond resolution, so we need some slack XCTAssertEqualWithAccuracy([test timeIntervalSinceDate:retrieved], 0, 1); + [_analytics setDateProperty:nil forKey:propertyKey]; XCTAssertNil([_analytics datePropertyForKey:propertyKey]); } diff --git a/supd/Tests/SupdTests.m b/supd/Tests/SupdTests.m index 0217542b..0b869500 100644 --- a/supd/Tests/SupdTests.m +++ b/supd/Tests/SupdTests.m @@ -21,8 +21,20 @@ * @APPLE_LICENSE_HEADER_END@ */ -#import #import + +// securityuploadd does not do anything or build meaningful code on simulator, so no tests either. +#if TARGET_OS_SIMULATOR + +@interface SupdTests : XCTestCase +@end + +@implementation SupdTests +@end + +#else + +#import #import "supd.h" #import #import "SFAnalyticsDefines.h" @@ -44,7 +56,7 @@ static NSInteger _reporterWrites; + (NSString*)databasePath { - return [_path stringByAppendingFormat:@"/ckks_%ld.db", _testnum]; + return [_path stringByAppendingFormat:@"/ckks_%ld.db", (long)_testnum]; } @end @@ -60,7 +72,7 @@ static NSInteger _reporterWrites; + (NSString*)databasePath { - return [_path stringByAppendingFormat:@"/sos_%ld.db", _testnum]; + return [_path stringByAppendingFormat:@"/sos_%ld.db", (long)_testnum]; } @end @@ -76,7 +88,7 @@ static NSInteger _reporterWrites; + (NSString*)databasePath { - return [_path stringByAppendingFormat:@"/pcs_%ld.db", _testnum]; + return [_path stringByAppendingFormat:@"/pcs_%ld.db", (long)_testnum]; } @end @@ -91,7 +103,7 @@ static NSInteger _reporterWrites; + (NSString*)databasePath { - return [_path stringByAppendingFormat:@"/tls_%ld.db", _testnum]; + return [_path stringByAppendingFormat:@"/tls_%ld.db", (long)_testnum]; } @end @@ -123,7 +135,7 @@ static NSInteger _reporterWrites; - (SFAnalyticsTopic *)TrustTopic { for (SFAnalyticsTopic *topic in _supd.analyticsTopics) { - if ([topic.internalTopicName isEqualToString:SFAnaltyicsTopicTrust]) { + if ([topic.internalTopicName isEqualToString:SFAnalyticsTopicTrust]) { return topic; } } @@ -153,13 +165,13 @@ static NSInteger _reporterWrites; 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"); + XCTAssertEqualObjects(event[@"build"], build, @"event contains correct build string"); + XCTAssertEqualObjects(event[@"product"], 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:topic], @"all events have a topic name"); + XCTAssertEqualObjects(event[@"topic"], topic, @"all events have a topic name"); } else { XCTFail(@"event %@ is an NSDictionary", event); } @@ -327,19 +339,23 @@ static NSInteger _reporterWrites; ++_testnum; id mockTopic = OCMStrictClassMock([SFAnalyticsTopic class]); - NSString *ckksPath = [_path stringByAppendingFormat:@"/ckks_%ld.db", _testnum]; - NSString *sosPath = [_path stringByAppendingFormat:@"/sos_%ld.db", _testnum]; - NSString *pcsPath = [_path stringByAppendingFormat:@"/pcs_%ld.db", _testnum]; - NSString *tlsPath = [_path stringByAppendingFormat:@"/tls_%ld.db", _testnum]; + NSString *ckksPath = [_path stringByAppendingFormat:@"/ckks_%ld.db", (long)_testnum]; + NSString *sosPath = [_path stringByAppendingFormat:@"/sos_%ld.db", (long)_testnum]; + NSString *pcsPath = [_path stringByAppendingFormat:@"/pcs_%ld.db", (long)_testnum]; + NSString *tlsPath = [_path stringByAppendingFormat:@"/tls_%ld.db", (long)_testnum]; + NSString *signInPath = [_path stringByAppendingFormat:@"/signin_%ld.db", (long)_testnum]; + NSString *cloudServicesPath = [_path stringByAppendingFormat:@"/cloudServices_%ld.db", (long)_testnum]; OCMStub([mockTopic databasePathForCKKS]).andReturn(ckksPath); OCMStub([mockTopic databasePathForSOS]).andReturn(sosPath); OCMStub([mockTopic databasePathForPCS]).andReturn(pcsPath); OCMStub([mockTopic databasePathForTLS]).andReturn(tlsPath); + OCMStub([mockTopic databasePathForSignIn]).andReturn(signInPath); + OCMStub([mockTopic databasePathForCloudServices]).andReturn(cloudServicesPath); // 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]; + NSString *localpath = [_path stringByAppendingFormat:@"/local_empty_%ld.db", (long)_testnum]; + NSString *trustPath = [_path stringByAppendingFormat:@"/trust_empty_%ld.db", (long)_testnum]; + NSString *trustdhealthPath = [_path stringByAppendingFormat:@"/trustdhealth_empty_%ld.db", (long)_testnum]; OCMStub([mockTopic databasePathForLocal]).andReturn(localpath); OCMStub([mockTopic databasePathForTrust]).andReturn(trustPath); OCMStub([mockTopic databasePathForTrustdHealth]).andReturn(trustdhealthPath); @@ -357,12 +373,6 @@ static NSInteger _reporterWrites; _pcsAnalytics = [FakePCSAnalytics new]; _tlsAnalytics = [FakeTLSAnalytics new]; - // 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; @@ -475,7 +485,7 @@ static NSInteger _reporterWrites; [_tlsAnalytics logHardFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs]; [_tlsAnalytics logSoftFailureForEventNamed:@"tlsunittestevent" withAttributes:tlsAttrs]; - NSDictionary* data = [self getJSONDataFromSupdWithTopic:SFAnaltyicsTopicTrust]; + NSDictionary* data = [self getJSONDataFromSupdWithTopic:SFAnalyticsTopicTrust]; [self inspectDataBlobStructure:data forTopic:[[self TrustTopic] splunkTopicName]]; if (analyticsEnabled) { @@ -736,6 +746,22 @@ static NSInteger _reporterWrites; [self sampleStatisticsInEvents:data[@"events"] name:sampleName values:@[@313.37] amount:2]; } +- (void)testInvalidJSON +{ + NSData* bad = [@"let's break supd!" dataUsingEncoding:NSUTF8StringEncoding]; + [_ckksAnalytics logHardFailureForEventNamed:@"testEvent" withAttributes:@{ @"dataAttribute" : bad}]; + + NSDictionary* data = [self getJSONDataFromSupd]; + XCTAssertNotNil(data); + XCTAssertNotNil(data[@"events"]); + NSUInteger foundErrorEvents = 0; + for (NSDictionary* event in data[@"events"]) { + if ([event[SFAnalyticsEventType] isEqualToString:SFAnalyticsEventTypeErrorEvent] && [event[SFAnalyticsEventErrorDestription] isEqualToString:@"JSON:testEvent"]) { + ++foundErrorEvents; + } + } + XCTAssertEqual(foundErrorEvents, 1); +} // TODO @@ -757,3 +783,5 @@ static NSInteger _reporterWrites; } @end + +#endif // !TARGET_OS_SIMULATOR diff --git a/supd/main.m b/supd/main.m index a8f7b24e..b4d4a38e 100644 --- a/supd/main.m +++ b/supd/main.m @@ -21,6 +21,17 @@ * @APPLE_LICENSE_HEADER_END@ */ +#include + +#if TARGET_OS_SIMULATOR + +int main(int argc, char** argv) +{ + return 0; +} + +#else + #import #import "supd.h" #include "debugging.h" @@ -71,3 +82,5 @@ int main(int argc, const char *argv[]) [[NSRunLoop currentRunLoop] run]; return 0; } + +#endif // !TARGET_OS_SIMULATOR diff --git a/supd/securityuploadd-Entitlements.plist b/supd/securityuploadd-Entitlements.plist index d8708bea..ee1cb751 100644 --- a/supd/securityuploadd-Entitlements.plist +++ b/supd/securityuploadd-Entitlements.plist @@ -2,17 +2,17 @@ - com.apple.accounts.appleaccount.fullaccess - - com.apple.authkit.client.private - - com.apple.private.accounts.allaccounts - com.apple.private.ckks seatbelt-profiles securityuploadd + com.apple.accounts.appleaccount.fullaccess + + com.apple.authkit.client.private + + com.apple.security.network.client + diff --git a/supd/securityuploadd-sim.plist b/supd/securityuploadd-sim.plist new file mode 100644 index 00000000..fc7248d6 --- /dev/null +++ b/supd/securityuploadd-sim.plist @@ -0,0 +1,25 @@ + + + + + ProcessType + Adaptive + Label + com.apple.securityuploadd + UserName + _securityd + GroupName + wheel + EnablePressuredExit + + ProgramArguments + + /usr/libexec/securityuploadd + + MachServices + + com.apple.securityuploadd + + + + diff --git a/supd/supd.h b/supd/supd.h index 399a21a4..f9fdce96 100644 --- a/supd/supd.h +++ b/supd/supd.h @@ -49,12 +49,21 @@ + (NSString*)databasePathForTrust; + (NSString*)databasePathForTrustdHealth; + (NSString*)databasePathForTLS; ++ (NSString*)databasePathForSignIn; ++ (NSString*)databasePathForCloudServices; @end @interface SFAnalyticsReporter : NSObject - (BOOL)saveReport:(NSData *)reportData fileName:(NSString *)fileName; @end +extern NSString* const SupdErrorDomain; +typedef NS_ENUM(NSInteger, SupdError) { + SupdNoError = 0, + SupdGenericError, + SupdInvalidJSONError, +}; + @interface supd : NSObject + (instancetype)instance; + (void)removeInstance; diff --git a/supd/supd.m b/supd/supd.m index d1601f06..194e1591 100644 --- a/supd/supd.m +++ b/supd/supd.m @@ -22,6 +22,9 @@ */ #import "supd.h" + +#if !TARGET_OS_SIMULATOR + #import "SFAnalyticsDefines.h" #import "SFAnalyticsSQLiteStore.h" #import @@ -40,24 +43,22 @@ #if TARGET_OS_OSX #include "dirhelper_priv.h" +#endif + +#if TARGET_OS_OSX +#import +#else +#import +#endif + #import #import #import #import -#import -#import -#import -#import -#else // TARGET_OS_OSX -#import #import #import #import -#if TARGET_OS_EMBEDDED -#import -#import -#endif // TARGET_OS_EMBEDDED -#endif // TARGET_OS_OSX + NSString* const SFAnalyticsSplunkTopic = @"topic"; NSString* const SFAnalyticsSplunkPostTime = @"postTime"; @@ -66,12 +67,17 @@ NSString* const SFAnalyticsInternal = @"internal"; NSString* const SFAnalyticsMetricsBase = @"metricsBase"; NSString* const SFAnalyticsDeviceID = @"ckdeviceID"; +NSString* const SFAnalyticsAltDSID = @"altDSID"; NSString* const SFAnalyticsSecondsCustomerKey = @"SecondsBetweenUploadsCustomer"; NSString* const SFAnalyticsSecondsInternalKey = @"SecondsBetweenUploadsInternal"; +NSString* const SFAnalyticsSecondsSeedKey = @"SecondsBetweenUploadsSeed"; NSString* const SFAnalyticsMaxEventsKey = @"NumberOfEvents"; NSString* const SFAnalyticsDevicePercentageCustomerKey = @"DevicePercentageCustomer"; NSString* const SFAnalyticsDevicePercentageInternalKey = @"DevicePercentageInternal"; +NSString* const SFAnalyticsDevicePercentageSeedKey = @"DevicePercentageSeed"; + +NSString* const SupdErrorDomain = @"com.apple.security.supd"; #define SFANALYTICS_SPLUNK_DEV 0 #define OS_CRASH_TRACER_LOG_BUG_TYPE "226" @@ -79,29 +85,30 @@ NSString* const SFAnalyticsDevicePercentageInternalKey = @"DevicePercentageInter #if SFANALYTICS_SPLUNK_DEV NSUInteger const secondsBetweenUploadsCustomer = 10; NSUInteger const secondsBetweenUploadsInternal = 10; +NSUInteger const secondsBetweenUploadsSeed = 10; #else // SFANALYTICS_SPLUNK_DEV NSUInteger const secondsBetweenUploadsCustomer = (3 * (60 * 60 * 24)); NSUInteger const secondsBetweenUploadsInternal = (60 * 60 * 24); +NSUInteger const secondsBetweenUploadsSeed = (60 * 60 * 24); #endif // SFANALYTICS_SPLUNK_DEV @implementation SFAnalyticsReporter - (BOOL)saveReport:(NSData *)reportData fileName:(NSString *)fileName { + BOOL writtenToLog = NO; #if TARGET_OS_OSX NSDictionary *optionsDictionary = @{ (__bridge NSString *)kCRProblemReportSubmissionPolicyKey: (__bridge NSString *)kCRSubmissionPolicyAlternate }; #else // !TARGET_OS_OSX NSDictionary *optionsDictionary = nil; // The keys above are not defined or required on iOS. #endif // !TARGET_OS_OSX - BOOL writtenToLog = NO; -#if !TARGET_OS_SIMULATOR + secdebug("saveReport", "calling out to `OSAWriteLogForSubmission`"); writtenToLog = OSAWriteLogForSubmission(@OS_CRASH_TRACER_LOG_BUG_TYPE, fileName, nil, optionsDictionary, ^(NSFileHandle *fileHandle) { secnotice("OSAWriteLogForSubmission", "Writing log data to report: %@", fileName); [fileHandle writeData:reportData]; }); -#endif // !TARGET_OS_SIMULATOR return writtenToLog; } @end @@ -128,7 +135,7 @@ _isDeviceAnalyticsEnabled(void) static BOOL dataCollectionEnabled = NO; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ -#if TARGET_OS_EMBEDDED +#if TARGET_OS_IPHONE dataCollectionEnabled = DiagnosticLogSubmissionEnabled(); #elif TARGET_OS_OSX dataCollectionEnabled = CRIsAutoSubmitEnabled(); @@ -137,19 +144,27 @@ _isDeviceAnalyticsEnabled(void) return dataCollectionEnabled; } +static NSString * +accountAltDSID(void) +{ + ACAccountStore *accountStore = [[ACAccountStore alloc] init]; + ACAccount *primaryAccount = [accountStore aa_primaryAppleAccount]; + if (primaryAccount == nil) { + return nil; + } + return [primaryAccount aa_altDSID]; +} + static NSString *const kAnalyticsiCloudIdMSKey = @"com.apple.idms.config.privacy.icloud.data"; -#if TARGET_OS_IPHONE static NSDictionary * _getiCloudConfigurationInfoWithError(NSError **outError) { __block NSDictionary *outConfigurationInfo = nil; __block NSError *localError = nil; - ACAccountStore *accountStore = [[ACAccountStore alloc] init]; - ACAccount *primaryAccount = [accountStore aa_primaryAppleAccount]; - if (primaryAccount != nil) { - NSString *altDSID = [primaryAccount aa_altDSID]; + NSString *altDSID = accountAltDSID(); + if (altDSID != nil) { secnotice("_getiCloudConfigurationInfoWithError", "Fetching configuration info"); dispatch_semaphore_t sema = dispatch_semaphore_create(0); @@ -180,27 +195,6 @@ _getiCloudConfigurationInfoWithError(NSError **outError) } return outConfigurationInfo; } -#endif // TARGET_OS_IPHONE - -#if TARGET_OS_OSX -static NSString * -_iCloudAccount(void) -{ - return CFBridgingRelease(MMLCopyLoggedInAccount()); -} - -static NSString * -_altDSIDFromAccount(void) -{ - static CFStringRef kMMPropertyAccountAlternateDSID = CFSTR("AccountAlternateDSID"); - NSString *account = _iCloudAccount(); - if (account != nil) { - return CFBridgingRelease(MMLAccountCopyProperty((__bridge CFStringRef)account, kMMPropertyAccountAlternateDSID)); - } - secerror("_altDSIDFromAccount: failed to fetch iCloud account"); - return nil; -} -#endif // TARGET_OS_OSX static BOOL _isiCloudAnalyticsEnabled() @@ -212,46 +206,6 @@ _isiCloudAnalyticsEnabled() static bool cachedAllowsICloudAnalytics = false; -#if TARGET_OS_OSX - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - /* AOSAccounts is not mastered into the BaseSystem. Check that those classes are linked at runtime and abort if not. */ - if (![AKAppleIDAuthenticationController class]) { - secnotice("OTATrust", "Weak-linked AOSAccounts framework missing. Are we running in the base system?"); - return; - } - - NSString *currentAltDSID = _altDSIDFromAccount(); - if (currentAltDSID != nil) { - AKAppleIDAuthenticationController *authController = [AKAppleIDAuthenticationController new]; - __block bool allowsICloudAnalytics = false; - dispatch_semaphore_t sem = dispatch_semaphore_create(0); - secnotice("isiCloudAnalyticsEnabled", "fetching iCloud Analytics value from idms"); - [authController configurationInfoWithIdentifiers:@[kAnalyticsiCloudIdMSKey] - forAltDSID:currentAltDSID - completion:^(NSDictionary *configurationInfo, NSError *error) { - if (!error && configurationInfo) { - NSNumber *value = configurationInfo[kAnalyticsiCloudIdMSKey]; - if (value != nil) { - secnotice("_isiCloudAnalyticsEnabled", "authController:configurationInfoWithIdentifiers completed with no error and configuration information"); - allowsICloudAnalytics = [value boolValue]; - } else { - secerror("%s: no iCloud Analytics value found in IDMS", __FUNCTION__); - } - } else { - secerror("%s: Unable to fetch iCloud Analytics value from IDMS.", __FUNCTION__); - } - secnotice("_isiCloudAnalyticsEnabled", "authController:configurationInfoWithIdentifiers completed and returning"); - dispatch_semaphore_signal(sem); - }]; - // Wait 5 seconds before giving up and returning from the block. - dispatch_semaphore_wait(sem, dispatch_time(DISPATCH_TIME_NOW, (uint64_t)(5 * NSEC_PER_SEC))); - cachedAllowsICloudAnalytics = allowsICloudAnalytics; - } else { - secerror("_isiCloudAnalyticsEnabled: Failed to fetch alternate DSID"); - } - }); -#else // TARGET_OS_OSX static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSError *error = nil; @@ -269,7 +223,6 @@ _isiCloudAnalyticsEnabled() secerror("_isiCloudAnalyticsEnabled: %@", error); } }); -#endif // TARGET_OS_OSX return cachedAllowsICloudAnalytics; } @@ -381,7 +334,12 @@ _isiCloudAnalyticsEnabled() 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]) { + } else if ([topicName isEqualToString:SFAnalyticsTopicCloudServices]) { + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForCloudServices] + name:@"CloudServices" + deviceAnalytics:YES + iCloudAnalytics:NO]]; + } else if ([topicName isEqualToString:SFAnalyticsTopicTrust]) { #if TARGET_OS_OSX _set_user_dir_suffix("com.apple.trustd"); // supd needs to read trustd's cache dir for these #endif @@ -395,6 +353,9 @@ _isiCloudAnalyticsEnabled() #if TARGET_OS_OSX _set_user_dir_suffix(NULL); // set back to the default cache dir #endif + } else if ([topicName isEqualToString:SFAnalyticsTopicTransparency]) { + [clients addObject:[[SFAnalyticsClient alloc] initWithStorePath:[self.class databasePathForTransparency] + name:@"transparency" deviceAnalytics:NO iCloudAnalytics:YES]]; } _topicClients = clients; @@ -444,13 +405,22 @@ _isiCloudAnalyticsEnabled() #else bool internal = os_variant_has_internal_diagnostics("com.apple.security"); if (rates) { +#if RC_SEED_BUILD + NSNumber *secondsNum = internal ? rates[SFAnalyticsSecondsInternalKey] : rates[SFAnalyticsSecondsSeedKey]; + NSNumber *percentageNum = internal ? rates[SFAnalyticsDevicePercentageInternalKey] : rates[SFAnalyticsDevicePercentageSeedKey]; +#else NSNumber *secondsNum = internal ? rates[SFAnalyticsSecondsInternalKey] : rates[SFAnalyticsSecondsCustomerKey]; + NSNumber *percentageNum = internal ? rates[SFAnalyticsDevicePercentageInternalKey] : rates[SFAnalyticsDevicePercentageCustomerKey]; +#endif _secondsBetweenUploads = [secondsNum integerValue]; _maxEventsToReport = [rates[SFAnalyticsMaxEventsKey] unsignedIntegerValue]; - NSNumber *percentageNum = internal ? rates[SFAnalyticsDevicePercentageInternalKey] : rates[SFAnalyticsDevicePercentageCustomerKey]; _devicePercentage = [percentageNum floatValue]; } else { +#if RC_SEED_BUILD + _secondsBetweenUploads = internal ? secondsBetweenUploadsInternal : secondsBetweenUploadsSeed; +#else _secondsBetweenUploads = internal ? secondsBetweenUploadsInternal : secondsBetweenUploadsCustomer; +#endif _maxEventsToReport = SFAnalyticsMaxEventsToReport; _devicePercentage = DEFAULT_SPLUNK_DEVICE_PERCENTAGE; } @@ -586,12 +556,21 @@ _isiCloudAnalyticsEnabled() for (NSArray* client in failures) { [client enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary* event = (NSMutableDictionary*)obj; if (idx >= threshold) { *stop = YES; return; } - if ([self prepareEventForUpload:obj]) { - [records addObject:obj]; + if ([self prepareEventForUpload:event]) { + if ([NSJSONSerialization isValidJSONObject:event]) { + [records addObject:event]; + } else { + secerror("supd: Replacing event with errorEvent because invalid JSON: %@", event); + NSString* originalType = event[SFAnalyticsEventType]; + NSDictionary* errorEvent = @{ SFAnalyticsEventType : SFAnalyticsEventTypeErrorEvent, + SFAnalyticsEventErrorDestription : [NSString stringWithFormat:@"JSON:%@", originalType]}; + [records addObject:errorEvent]; + } } }]; } @@ -683,6 +662,11 @@ _isiCloudAnalyticsEnabled() } summary[SFAnalyticsEventTime] = @([[NSDate date] timeIntervalSince1970] * 1000); // Splunk wants milliseconds [SFAnalytics addOSVersionToEvent:summary]; + if (store.uploadDate) { + summary[SFAnalyticsAttributeLastUploadTime] = @([store.uploadDate timeIntervalSince1970] * 1000); + } else { + summary[SFAnalyticsAttributeLastUploadTime] = @(0); + } // Process counters NSDictionary* successCounts = store.summaryCounts; @@ -718,19 +702,28 @@ _isiCloudAnalyticsEnabled() [summary addEntriesFromDictionary:event]; }]; - // Should always return yes because we already checked for event blacklisting specifically + // Should always return yes because we already checked for event blacklisting specifically (unless summary itself is blacklisted) if (![self prepareEventForUpload:summary]) { + secwarning("supd: health summary for %@ blacklisted", name); return nil; } + + // Seems unlikely because we only insert strings, samplers only take NSNumbers and frankly, sampleStatisticsForSamples probably would have crashed + if (![NSJSONSerialization isValidJSONObject:summary]) { + secerror("json: health summary for client %@ is invalid JSON: %@", name, summary); + return [@{ SFAnalyticsEventType : SFAnalyticsEventTypeErrorEvent, + SFAnalyticsEventErrorDestription : [NSString stringWithFormat:@"JSON:%@HealthSummary", name]} mutableCopy]; + } + return summary; } -- (void)updateUploadDateForClients:(NSArray*)clients clearData:(BOOL)clearData +- (void)updateUploadDateForClients:(NSArray*)clients date:(NSDate *)date clearData:(BOOL)clearData { for (SFAnalyticsClient* client in clients) { SFAnalyticsSQLiteStore* store = [SFAnalyticsSQLiteStore storeWithPath:client.storePath schema:SFAnalyticsTableSchema]; - secnotice("postprocess", "Setting upload date for client: %@", client.name); - store.uploadDate = [NSDate date]; + secnotice("postprocess", "Setting upload date (%@) for client: %@", date, client.name); + store.uploadDate = date; if (clearData) { secnotice("postprocess", "Clearing collected data for client: %@", client.name); [store clearAllData]; @@ -750,8 +743,11 @@ _isiCloudAnalyticsEnabled() __block NSMutableArray* hardFailures = [NSMutableArray new]; __block NSMutableArray* softFailures = [NSMutableArray new]; NSString* ckdeviceID = nil; - if ([_internalTopicName isEqualToString:SFAnalyticsTopicKeySync]) { - ckdeviceID = os_variant_has_internal_diagnostics("com.apple.security") ? [self askSecurityForCKDeviceID] : nil; + NSString* accountID = nil; + + if (os_variant_has_internal_diagnostics("com.apple.security") && [_internalTopicName isEqualToString:SFAnalyticsTopicKeySync]) { + ckdeviceID = [self askSecurityForCKDeviceID]; + accountID = accountAltDSID(); } for (SFAnalyticsClient* client in self->_topicClients) { if (!force && [client requireDeviceAnalytics] && !_isDeviceAnalyticsEnabled()) { @@ -775,13 +771,6 @@ _isiCloudAnalyticsEnabled() continue; } - 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; - } - if (force) { secnotice("json", "client '%@' for topic '%@' force-included", client.name, _internalTopicName); } else { @@ -795,6 +784,9 @@ _isiCloudAnalyticsEnabled() if (ckdeviceID) { healthSummary[SFAnalyticsDeviceID] = ckdeviceID; } + if (accountID) { + healthSummary[SFAnalyticsAltDSID] = accountID; + } [uploadRecords addObject:healthSummary]; } @@ -824,6 +816,16 @@ _isiCloudAnalyticsEnabled() @"events" : uploadRecords }; + // This check is "belt and suspenders" because we already checked each event separately + if (![NSJSONSerialization isValidJSONObject:jsonDict]) { + secemergency("json: final dictionary invalid JSON. This is terrible!"); + if (error) { + *error = [NSError errorWithDomain:SupdErrorDomain code:SupdInvalidJSONError + userInfo:@{NSLocalizedDescriptionKey : [NSString localizedStringWithFormat:@"Final dictionary for upload is invalid JSON: %@", jsonDict]}]; + } + return nil; + } + NSData *json = [NSJSONSerialization dataWithJSONObject:jsonDict options:(pretty ? NSJSONWritingPrettyPrinted : 0) error:&localError]; @@ -973,7 +975,6 @@ _isiCloudAnalyticsEnabled() (void)session; secnotice("upload", "Splunk upload challenge for %@", _internalTopicName); NSURLCredential *cred = nil; - SecTrustResultType result = kSecTrustResultInvalid; if ([challenge previousFailureCount] > 0) { // Previous failures occurred, bail @@ -986,8 +987,8 @@ _isiCloudAnalyticsEnabled() SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; // Coverity gets upset if we don't check status even though result is all we need. - OSStatus status = SecTrustEvaluate(serverTrust, &result); - if (_allowInsecureSplunkCert || (status == errSecSuccess && ((result == kSecTrustResultProceed) || (result == kSecTrustResultUnspecified)))) { + bool trustResult = SecTrustEvaluateWithError(serverTrust, NULL); + if (_allowInsecureSplunkCert || trustResult) { /* * All is well, accept the credentials */ @@ -1034,7 +1035,7 @@ _isiCloudAnalyticsEnabled() + (NSString*)AppSupportPath { -#if TARGET_OS_IOS +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR return @"/var/mobile/Library/Application Support"; #else NSArray*paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, true); @@ -1042,7 +1043,7 @@ _isiCloudAnalyticsEnabled() return nil; } return [NSString stringWithString: paths[0]]; -#endif /* TARGET_OS_IOS */ +#endif /* TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */ } + (NSString*)databasePathForPCS @@ -1093,6 +1094,16 @@ _isiCloudAnalyticsEnabled() return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/signin_metrics.db")) path]; } ++ (NSString*)databasePathForCloudServices +{ + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory(CFSTR("Analytics/CloudServicesAnalytics.db")) path]; +} + ++ (NSString*)databasePathForTransparency +{ + return [(__bridge_transfer NSURL*)SecCopyURLForFileInKeychainDirectory((__bridge CFStringRef)@"Analytics/TransparencyAnalytics.db") path]; +} + @end @interface supd () @@ -1117,14 +1128,10 @@ _isiCloudAnalyticsEnabled() } + (instancetype)instance { -#if TARGET_OS_SIMULATOR - return nil; -#else if (!_supdInstance) { _supdInstance = [self new]; } return _supdInstance; -#endif } // Use this for testing to get rid of any state @@ -1177,17 +1184,9 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo } - (void)setupSamplingRates { -#if TARGET_OS_SIMULATOR - NSBundle *trustStoreBundle = [NSBundle bundleWithPath:[NSString stringWithFormat:@"%s%@", getenv("SIMULATOR_ROOT"), SystemTrustStorePath]]; -#else NSBundle *trustStoreBundle = [NSBundle bundleWithPath:SystemTrustStorePath]; -#endif -#if TARGET_OS_IPHONE - NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInKeychainDirectory(nil)); -#else - NSURL *keychainsDirectory = [NSURL fileURLWithFileSystemRepresentation:"/Library/Keychains/" isDirectory:YES relativeToURL:nil]; -#endif + NSURL *keychainsDirectory = CFBridgingRelease(SecCopyURLForFileInSystemKeychainDirectory(nil)); NSURL *directory = [keychainsDirectory URLByAppendingPathComponent:@"SupplementalsAssets/" isDirectory:YES]; NSDictionary *analyticsSamplingRates = nil; @@ -1282,18 +1281,24 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo if ([topic postJSON:json toEndpoint:endpoint error:&localError]) { secnotice("upload", "Successfully posted JSON for %@", [topic internalTopicName]); result = YES; - [topic updateUploadDateForClients:clients clearData:YES]; + [topic updateUploadDateForClients:clients date:[NSDate date] clearData:YES]; } else { - secerror("upload: Failed to post JSON for %@", [topic internalTopicName]); + secerror("upload: Failed to post JSON for %@: %@", [topic internalTopicName], localError); } } else { /* If we didn't sample this report, update date to prevent trying to upload again sooner * than we should. Clear data so that per-day calculations remain consistent. */ secnotice("upload", "skipping unsampled upload for %@ and clearing data", [topic internalTopicName]); - [topic updateUploadDateForClients:clients clearData:YES]; + [topic updateUploadDateForClients:clients date:[NSDate date] clearData:YES]; } } else { - secerror("upload: failed to get logging JSON"); + if ([[localError domain] isEqualToString:SupdErrorDomain] && [localError code] == SupdInvalidJSONError) { + // Pretend this was a success because at least we'll get rid of bad data. + // If someone keeps logging bad data and we only catch it here then + // this causes sustained data loss for the entire topic. + [topic updateUploadDateForClients:clients date:[NSDate date] clearData:YES]; + } + secerror("upload: failed to get logging JSON for topic %@: %@", [topic internalTopicName], localError); } } if (error && localError) { @@ -1353,6 +1358,32 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo return sysdiagnose; } +- (void)setUploadDateWith:(NSDate *)date reply:(void (^)(BOOL, NSError*))reply +{ + for (SFAnalyticsTopic* topic in _analyticsTopics) { + [topic updateUploadDateForClients:topic.topicClients date:date clearData:NO]; + } + reply(YES, nil); +} + +- (void)clientStatus:(void (^)(NSDictionary *, NSError *))reply +{ + NSMutableDictionary *info = [NSMutableDictionary dictionary]; + for (SFAnalyticsTopic* topic in _analyticsTopics) { + for (SFAnalyticsClient *client in topic.topicClients) { + SFAnalyticsSQLiteStore* store = [SFAnalyticsSQLiteStore storeWithPath:client.storePath schema:SFAnalyticsTableSchema]; + + NSMutableDictionary *clientInfo = [NSMutableDictionary dictionary]; + clientInfo[@"uploadDate"] = store.uploadDate; + info[client.name] = clientInfo; + } + } + + reply(info, nil); +} + + + - (NSString*)stringForEventClass:(SFAnalyticsEventClass)eventClass { if (eventClass == SFAnalyticsEventClassNote) { @@ -1403,3 +1434,5 @@ static bool ShouldInitializeWithAsset(NSBundle *trustStoreBundle, NSURL *directo } @end + +#endif // !TARGET_OS_SIMULATOR diff --git a/supd/supdProtocol.h b/supd/supdProtocol.h index fd051cf3..98371ac2 100644 --- a/supd/supdProtocol.h +++ b/supd/supdProtocol.h @@ -27,4 +27,6 @@ - (void)getSysdiagnoseDumpWithReply:(void (^)(NSString*))reply; - (void)getLoggingJSON:(bool)pretty topic:(NSString *)topicName reply:(void (^)(NSData*, NSError*))reply; - (void)forceUploadWithReply:(void (^)(BOOL, NSError*))reply; +- (void)setUploadDateWith:(NSDate *)date reply:(void (^)(BOOL, NSError*))reply; +- (void)clientStatus:(void (^)(NSDictionary *, NSError *))reply; @end diff --git a/supdctl/main.m b/supdctl/main.m index 10137b7e..3c920bdf 100644 --- a/supdctl/main.m +++ b/supdctl/main.m @@ -26,10 +26,12 @@ #import "supd/supdProtocol.h" #import #import +#import "SecInternalReleasePriv.h" /* Internal Topic Names */ NSString* const SFAnalyticsTopicKeySync = @"KeySyncTopic"; -NSString* const SFAnaltyicsTopicTrust = @"TrustTopic"; +NSString* const SFAnalyticsTopicTrust = @"TrustTopic"; +NSString* const SFAnalyticsTopicTransparency = @"TransparencyTopic"; static void nsprintf(NSString *fmt, ...) NS_FORMAT_FUNCTION(1, 2); static void nsprintf(NSString *fmt, ...) @@ -117,9 +119,58 @@ static void forceUploadAnalytics(void) [connection invalidate]; } +static void +getInfoDump(void) +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + NSXPCConnection* connection = getConnection(); + [[connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + nsprintf(@"Could not communicate with supd: %@", error); + dispatch_semaphore_signal(sema); + }] clientStatus:^(NSDictionary *info, NSError *error) { + if (info) { + nsprintf(@"%@\n", info); + } else { + nsprintf(@"Supd reports failure: %@", error); + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 20)) != 0) { + printf("\n\nError: timed out waiting for response from supd\n"); + } + [connection invalidate]; +} + +static void +forceOldUploadDate(void) +{ + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + NSXPCConnection* connection = getConnection(); + + NSDate *date = [NSDate dateWithTimeIntervalSinceNow:(-7 * 24 * 3600.0)]; + + [[connection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + nsprintf(@"Could not communicate with supd: %@", error); + dispatch_semaphore_signal(sema); + }] setUploadDateWith:date reply:^(BOOL success, NSError *error) { + if (!success && error) { + nsprintf(@"Supd reports failure: %@", error); + } + dispatch_semaphore_signal(sema); + }]; + + if(dispatch_semaphore_wait(sema, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 20)) != 0) { + printf("\n\nError: timed out waiting for response from supd\n"); + } + [connection invalidate]; +} + static int forceUpload = false; static int getJSON = false; static int getSysdiagnose = false; +static int getInfo = false; +static int setOldUploadDate = false; static char *topicName = nil; int main(int argc, char **argv) @@ -130,6 +181,8 @@ 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 (ignoring privacy settings)"}, + { .command="info", .flag=&getInfo, .flagval=true, .description="Request info about clients"}, + { .command="set-old-upload-date", .flag=&setOldUploadDate, .flagval=true, .description="Clear last upload date"}, {} // Need this! }; @@ -145,6 +198,10 @@ int main(int argc, char **argv) return -1; } + if (!SecIsInternalRelease()) { + abort(); + } + @autoreleasepool { if (forceUpload) { forceUploadAnalytics(); @@ -152,6 +209,10 @@ int main(int argc, char **argv) getLoggingJSON(topicName); } else if (getSysdiagnose) { getSysdiagnoseDump(); + } else if (getInfo) { + getInfoDump(); + } else if (setOldUploadDate) { + forceOldUploadDate(); } else { print_usage(&args); return -1; diff --git a/tests/SecDbBackupTests/Entitlements.plist b/tests/SecDbBackupTests/Entitlements.plist new file mode 100644 index 00000000..f63472fe --- /dev/null +++ b/tests/SecDbBackupTests/Entitlements.plist @@ -0,0 +1,32 @@ + + + + + com.apple.application-identifier + com.apple.private.security.SecDbBackupTests + application-identifier + com.apple.private.security.SecDbBackupTests + com.apple.keystore.access-keychain-keys + + com.apple.keystore.lockassertion + + com.apple.private.associated-domains + + com.apple.private.necp.match + + com.apple.mkb.usersession.info + + seatbelt-profiles + + securityd + + com.apple.security.app-sandbox + + com.apple.security.get-task-allow + + keychain-access-groups + + SecDbBackupManager-UnitTests + + + diff --git a/tests/SecDbBackupTests/Info.plist b/tests/SecDbBackupTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/tests/SecDbBackupTests/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/tests/SecDbBackupTests/SecDbBackupTests.m b/tests/SecDbBackupTests/SecDbBackupTests.m new file mode 100644 index 00000000..6c51b3d9 --- /dev/null +++ b/tests/SecDbBackupTests/SecDbBackupTests.m @@ -0,0 +1,477 @@ +// +// SecDbBackupTests.m +// Security +// +// Created by Wouter de Groot on 2018-12-12. +// + +#import +#import "securityd/SecDbBackupManager.h" + +#if !SECDB_BACKUPS_ENABLED + +@interface SecDbBackupTests : XCTestCase +@end + +@implementation SecDbBackupTests +@end + +#else // SECDB_BACKUPS_ENABLED + +#import "securityd/SecDbBackupManager_Internal.h" + +#import "CKKS.h" +#import +#import "spi.h" +#import "SecItemServer.h" +#import +#include "utilities/der_plist.h" +#include + +@interface SecDbBackupTests : XCTestCase + +@end + +SecDbBackupManager* _manager; +NSString* _uuidstring; + +@implementation SecDbBackupTests { + NSString* _testHomeDirectory; +} + +static int testCheckV12DevEnabled(void) { + return 1; +} + ++ (void)setUp { + [super setUp]; + checkV12DevEnabled = testCheckV12DevEnabled; + SecCKKSDisable(); +#if OCTAGON + SecCKKSTestSetDisableSOS(true); +#endif + _uuidstring = [[NSUUID UUID] UUIDString]; +} + ++ (void)tearDown { + SetCustomHomeURL(NULL); + SecKeychainDbReset(NULL); + resetCheckV12DevEnabled(); +} + +- (void)setUp { + [super setUp]; + + NSString* testName = [self.name componentsSeparatedByString:@" "][1]; + testName = [testName stringByReplacingOccurrencesOfString:@"]" withString:@""]; + secnotice("secdbbackuptest", "Beginning test %@", testName); + + // Make a new fake keychain + NSError* error; + _testHomeDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@/", _uuidstring, testName]]; + + NSLog(@"%@", _testHomeDirectory); + + [[NSFileManager defaultManager] createDirectoryAtPath:_testHomeDirectory + withIntermediateDirectories:YES + attributes:nil + error:&error]; + // No XCTAssert in class method + if (error) { + NSLog(@"Could not make directory at %@", _testHomeDirectory); + } + + SetCustomHomeURLString((__bridge CFStringRef)_testHomeDirectory); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + securityd_init(NULL); + }); + SecKeychainDbReset(NULL); + + // Actually load the database. + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); + + [SecDbBackupManager resetManager]; + _manager = [SecDbBackupManager manager]; +} + +- (void)setFakeBagIdentity { + SecDbBackupBagIdentity* identity = [SecDbBackupBagIdentity new]; + NSUUID* nsuuid = [NSUUID UUID]; + uuid_t uuid; + [nsuuid getUUIDBytes:uuid]; + identity.baguuid = [NSData dataWithBytes:uuid length:UUIDBYTESLENGTH]; + NSMutableData* digest = [NSMutableData dataWithLength:CC_SHA512_DIGEST_LENGTH]; + CC_SHA512(identity.baguuid.bytes, (CC_LONG)identity.baguuid.length, digest.mutableBytes); + identity.baghash = digest; + _manager.bagIdentity = identity; +} + +- (SFAESKey*)randomAESKey { + return [[SFAESKey alloc] initRandomKeyWithSpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256] error:nil]; +} + +- (NSData*)bagIdentData { + NSDictionary* bagIdentDict = @{@"baguuid" : _manager.bagIdentity.baguuid, @"baghash" : _manager.bagIdentity.baghash}; + return (__bridge_transfer NSData*)CFPropertyListCreateDERData(NULL, (__bridge CFDictionaryRef)bagIdentDict, NULL); +} + +#pragma mark - Tests + +- (void)testAAA_MakeSureThisMakesSense { + XCTAssertEqual(checkV12DevEnabled(), 1, "V12 dev flag is off, no good will come of this"); + if (!checkV12DevEnabled) { + abort(); + } +} + +- (void)testCreateBackupBagSecret { + NSError* error; + NSData* secret = [_manager createBackupBagSecret:&error]; + XCTAssertNil(error, "Error creating backup bag secret"); + XCTAssertNotNil(secret, "No NSData from creating backup bag secret: %@", error); + XCTAssertEqual(secret.length, BACKUPBAG_PASSPHRASE_LENGTH, "NSData is not %i bytes long", BACKUPBAG_PASSPHRASE_LENGTH); + + // Good luck testing randomness, but let's stipulate we don't accept all-zeroes as a key + uint8_t buf[BACKUPBAG_PASSPHRASE_LENGTH] = {0}; + XCTAssertNotEqual(memcmp(secret.bytes, buf, MIN(BACKUPBAG_PASSPHRASE_LENGTH, secret.length)), 0, "Secret is all zeroes"); + + XCTAssert([secret isMemberOfClass:objc_lookUpClass("_NSClrDat")], "Secret is not a zeroing NSData"); +} + +- (void)testCreateAndSaveBackupBag { + NSError* error; + NSData* secret = [_manager createBackupBagSecret:&error]; + XCTAssertNil(error, "Unable to generate secret"); + XCTAssertNotNil(secret, "Didn't get secret"); + keybag_handle_t handle = [_manager createBackupBagWithSecret:secret error:&error]; + XCTAssertNil(error, "Got error creating backup bag: %@", error); + XCTAssertNotEqual(handle, bad_keybag_handle, "Unexpected bag handle"); + keybag_state_t keybagstate; + XCTAssertEqual(aks_get_lock_state(handle, &keybagstate), kAKSReturnSuccess, "Unable to check lock state of backup bag"); + XCTAssert(keybagstate | keybag_state_locked, "Keybag unexpectedly not locked"); + XCTAssert(keybagstate | keybag_state_been_unlocked, "Keybag unexpectedly never been unlocked (huh?)"); + + XCTAssert([_manager saveBackupBag:handle asDefault:YES error:&error]); + XCTAssertNil(error, "Error saving backup bag to keychain"); + XCTAssertEqual(aks_unload_bag(handle), kAKSReturnSuccess, "Couldn't unload backup bag"); +} + +- (void)testCreateAndSaveBagTwice { + NSError* error; + NSData* secret = [_manager createBackupBagSecret:&error]; + XCTAssertNil(error, "Unable to generate secret"); + XCTAssertNotNil(secret, "Didn't get secret"); + keybag_handle_t handle = [_manager createBackupBagWithSecret:secret error:&error]; + XCTAssertNil(error, "Got error creating backup bag: %@", error); + XCTAssertNotEqual(handle, bad_keybag_handle, "Unexpected bag handle"); + + XCTAssert([_manager saveBackupBag:handle asDefault:YES error:&error]); + XCTAssertNil(error, "Error saving backup bag to keychain"); + + XCTAssertFalse([_manager saveBackupBag:handle asDefault:YES error:&error]); + XCTAssert(error, "Unexpectedly did not get error saving same bag twice"); + XCTAssertEqual(error.code, SecDbBackupWriteFailure, "Unexpected error code for double insertion: %@", error); + XCTAssertEqual(aks_unload_bag(handle), kAKSReturnSuccess, "Couldn't unload backup bag"); +} + +- (void)testLoadNonExistentDefaultBackupBag { + NSError* error; + XCTAssertEqual([_manager loadBackupBag:nil error:&error], bad_keybag_handle, "Found default bag after not inserting any"); + XCTAssertEqual(error.code, SecDbBackupNoBackupBagFound, "Didn't get an appropriate error for missing keybag: %@", error); +} + +- (void)testLoadDefaultBackupBag { + NSError* error; + keybag_handle_t handle = bad_keybag_handle; + handle = [_manager createBackupBagWithSecret:[_manager createBackupBagSecret:&error] error:&error]; + XCTAssertNotEqual(handle, bad_keybag_handle, "Didn't get a good keybag handle"); + XCTAssertNotEqual(handle, device_keybag_handle, "Got device keybag handle (or manager is nil)"); + XCTAssertNil(error, "Error creating backup bag"); + [_manager saveBackupBag:handle asDefault:YES error:&error]; + XCTAssertNil(error, "Error saving backup bag"); + + uuid_t uuid1 = {0}; + XCTAssertEqual(aks_get_bag_uuid(handle, uuid1), kAKSReturnSuccess, "Couldn't get bag uuid"); + XCTAssertEqual(aks_unload_bag(handle), kAKSReturnSuccess, "Couldn't unload backup bag"); + handle = bad_keybag_handle; + + handle = [_manager loadBackupBag:nil error:&error]; + XCTAssertNotEqual(handle, bad_keybag_handle, "Got bad handle loading default keybag"); + XCTAssertNil(error, "Got error loading default keybag"); + + uuid_t uuid2 = {0}; + XCTAssertEqual(aks_get_bag_uuid(handle, uuid2), kAKSReturnSuccess, "Couldn't get bag uuid"); + XCTAssertEqual(aks_unload_bag(handle), kAKSReturnSuccess, "Couldn't unload backup bag"); + XCTAssertEqual(memcmp(uuid1, uuid2, UUIDBYTESLENGTH), 0, "UUIDs do not match after backup bag save/load"); + + // sanity check + uuid_t uuidnull = {0}; + XCTAssertNotEqual(memcmp(uuid1, uuidnull, UUIDBYTESLENGTH), 0, "uuid1 is all zeroes"); + XCTAssertNotEqual(memcmp(uuid2, uuidnull, UUIDBYTESLENGTH), 0, "uuid2 is all zeroes"); + + // TODO: signature match? +} + +- (void)testLoadBackupBagByUUID { + NSError* error; + keybag_handle_t handle1 = bad_keybag_handle; + handle1 = [_manager createBackupBagWithSecret:[_manager createBackupBagSecret:&error] error:&error]; + XCTAssertNotEqual(handle1, bad_keybag_handle, "Didn't get a good keybag handle"); + XCTAssertNil(error, "Error creating backup bag"); + XCTAssert([_manager saveBackupBag:handle1 asDefault:NO error:&error], "Unable to save bag 1"); + XCTAssertNil(error, "Error saving backup bag"); + + keybag_handle_t handle2 = bad_keybag_handle; + handle2 = [_manager createBackupBagWithSecret:[_manager createBackupBagSecret:&error] error:&error]; + XCTAssertNotEqual(handle2, bad_keybag_handle, "Didn't get a good keybag handle"); + XCTAssertNil(error, "Error creating backup bag"); + XCTAssert([_manager saveBackupBag:handle2 asDefault:NO error:&error], "Unable to save bag 2"); + XCTAssertNil(error, "Error saving backup bag"); + + uuid_t uuid1 = {0}; + uuid_t uuid2 = {0}; + XCTAssertEqual(aks_get_bag_uuid(handle1, uuid1), kAKSReturnSuccess, "Couldn't get bag 1 uuid"); + XCTAssertEqual(aks_get_bag_uuid(handle2, uuid2), kAKSReturnSuccess, "Couldn't get bag 2 uuid"); + XCTAssertEqual(aks_unload_bag(handle1), kAKSReturnSuccess, "Couldn't unload backup bag 1"); + XCTAssertEqual(aks_unload_bag(handle2), kAKSReturnSuccess, "Couldn't unload backup bag 2"); + handle1 = bad_keybag_handle; + handle2 = bad_keybag_handle; + + XCTAssertNotEqual(handle1 = [_manager loadBackupBag:[[NSUUID alloc] initWithUUIDBytes:uuid1] error:&error], bad_keybag_handle, "Didn't get handle loading bag 1 by UUID"); + XCTAssertNotEqual(handle2 = [_manager loadBackupBag:[[NSUUID alloc] initWithUUIDBytes:uuid2] error:&error], bad_keybag_handle, "Didn't get handle loading bag 2 by UUID"); + + uuid_t uuid1_2 = {0}; + uuid_t uuid2_2 = {0}; + XCTAssertEqual(aks_get_bag_uuid(handle1, uuid1_2), kAKSReturnSuccess, "Couldn't get bag 1 uuid"); + XCTAssertEqual(aks_get_bag_uuid(handle2, uuid2_2), kAKSReturnSuccess, "Couldn't get bag 2 uuid"); + + XCTAssertEqual(memcmp(uuid1, uuid1_2, UUIDBYTESLENGTH), 0, "UUIDs do not match after bag 1 save/load"); + XCTAssertEqual(memcmp(uuid2, uuid2_2, UUIDBYTESLENGTH), 0, "UUIDs do not match after bag 2 save/load"); + + XCTAssertEqual(aks_unload_bag(handle1), kAKSReturnSuccess, "Couldn't unload backup bag 1"); + XCTAssertEqual(aks_unload_bag(handle2), kAKSReturnSuccess, "Couldn't unload backup bag 2"); +} + +- (void)testCreateBackupInfrastructure +{ + NSError* error; + XCTAssert([_manager createOrLoadBackupInfrastructure:&error], @"Couldn't create/load backup infrastructure"); + XCTAssertNil(error, @"Error creating/loading backup infrastructure"); + + SFECKeyPair* ak = [_manager fetchKCSKForKeyclass:key_class_ak error:&error]; + XCTAssertNotNil(ak); + XCTAssertNil(error); + + SFECKeyPair* ck = [_manager fetchKCSKForKeyclass:key_class_ck error:&error]; + XCTAssertNotNil(ck); + XCTAssertNil(error); + + SFECKeyPair* dk = [_manager fetchKCSKForKeyclass:key_class_dk error:&error]; + XCTAssertNotNil(dk); + XCTAssertNil(error); + + SFECKeyPair* aku = [_manager fetchKCSKForKeyclass:key_class_aku error:&error]; + XCTAssertNotNil(aku); + XCTAssertNil(error); + + SFECKeyPair* cku = [_manager fetchKCSKForKeyclass:key_class_cku error:&error]; + XCTAssertNotNil(cku); + XCTAssertNil(error); + + SFECKeyPair* dku = [_manager fetchKCSKForKeyclass:key_class_dku error:&error]; + XCTAssertNotNil(dku); + XCTAssertNil(error); + + SFECKeyPair* akpu = [_manager fetchKCSKForKeyclass:key_class_akpu error:&error]; + XCTAssertNil(akpu); + XCTAssertEqual(error.code, SecDbBackupNoKCSKFound); +} + +- (void)testCreateOrLoadBackupInfrastructureFromC +{ + CFErrorRef cferror = NULL; + XCTAssertTrue(SecDbBackupCreateOrLoadBackupInfrastructure(&cferror), @"Could create backup infrastructure from C"); + XCTAssertFalse(cferror, @"Do not expect error creating backup infrastructure from C: %@", cferror); + CFReleaseNull(cferror); +} + +// Should not run this on real AKS because don't want to lock keybag +- (void)disabledtestCreateOrLoadBackupInfrastructureWhileLocked +{ + NSError* error; + XCTAssertFalse([_manager createOrLoadBackupInfrastructure:&error], @"Keychain locked, don't expect to create infrastructure"); + XCTAssertEqual(error.code, SecDbBackupKeychainLocked, @"Expected failure creating backup infrastructure while locked"); +} + +// Should not run this on real AKS because don't want to lock keybag +- (void)disabledtestCreateOrLoadBackupInfrastructureWhileLockedFromC +{ + CFErrorRef cferror = NULL; + XCTAssertFalse(SecDbBackupCreateOrLoadBackupInfrastructure(&cferror), @"Could create backup infrastructure from C"); + XCTAssertTrue(cferror, @"Expect error creating backup infrastructure while locked from C: %@", cferror); + if (cferror) { + XCTAssertEqual(CFErrorGetCode(cferror), errSecInteractionNotAllowed, @"Expect errSecInteractionNotAllowed creating backup infrastructure while locked from C"); + } + CFReleaseNull(cferror); +} + +- (void)testOnlyOneDefaultBackupBag { + // Generate two backup bags, each successively claiming makeDefault + // Expect: the second call should fail +} + +- (void)testLoadBackupBagFromDifferentDevice { + // Generate keybag on some device, manually insert it on some other device and try to load it. + // Expect: failure unless in recovery mode. +} + +- (void)testLoadBackupBagWithGarbageData { + // manually write garbage to keychain, then call loadBackupBag + // Expect: ? +} + +- (void)testCreateKCSK { + [self setFakeBagIdentity]; + + NSError* error; + XCTAssertNil([_manager createKCSKForKeyClass:key_class_ck withWrapper:nil error:&error], @"Shouldn't get KCSK without wrapper"); + XCTAssertEqual(error.code, SecDbBackupInvalidArgument, @"createKSCKForKeyClass ought to be angry about not having a wrapper"); + error = nil; + + SFAESKey* key = [self randomAESKey]; + XCTAssertNotNil(key, @"Expect key from SFAESKey"); + SecDbBackupKeyClassSigningKey* kcsk = [_manager createKCSKForKeyClass:key_class_ak withWrapper:key error:&error]; + XCTAssertNotNil(kcsk, @"Got a KCSK"); + XCTAssertNil(error, @"Did not expect KCSK error: %@", error); + + // Let's examine the KCSK + + XCTAssertEqual(kcsk.keyClass, key_class_ak, @"key class matches"); + + // Verify refkey + aks_ref_key_t refkey = NULL; + XCTAssertNotNil(kcsk.aksRefKey, @"Got an AKS ref key"); + XCTAssertEqual(aks_ref_key_create_with_blob(KEYBAG_DEVICE, kcsk.aksRefKey.bytes, + kcsk.aksRefKey.length, &refkey), kAKSReturnSuccess, @"Got a refkey out of kcsk blob"); + + // Verify aksWrappedKey + void* aksunwrappedbytes = NULL; + size_t aksunwrappedlen = 0; + XCTAssertEqual(aks_ref_key_decrypt(refkey, NULL, 0, kcsk.aksWrappedKey.bytes, kcsk.aksWrappedKey.length, &aksunwrappedbytes, &aksunwrappedlen), kAKSReturnSuccess, @"Successfully unwrapped KCSK private key"); + SFECKeyPair* aksunwrapped = [_manager ECKeyPairFromDerBytes:aksunwrappedbytes length:aksunwrappedlen error:&error]; + XCTAssertNil(error, @"No error reconstructing AKS backup key"); + XCTAssert(aksunwrapped, @"Got key from ECKeyPairFromDerBytes"); + aks_ref_key_free(&refkey); + + // Verify backupWrappedKey + SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]]; + SFAuthenticatedCiphertext* ciphertext = [NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:kcsk.backupWrappedKey error:&error]; + XCTAssertNotNil(ciphertext, @"Reconstituted ciphertext from kcsk (%@)", error); + XCTAssertNil(error, @"Didn't expect error reconstituting ciphertext from kcsk: %@", error); + + NSData* bagIdentData = [self bagIdentData]; + NSData* bkunwrappedData = [op decrypt:ciphertext withKey:key additionalAuthenticatedData:bagIdentData error:&error]; + XCTAssertNotNil(bkunwrappedData, @"backup-wrapped key decrypts"); + SFECKeyPair* bkunwrapped = [[SFECKeyPair alloc] initWithData:bkunwrappedData specifier:[[SFECKeySpecifier alloc] initWithCurve:SFEllipticCurveNistp384] error:&error]; + XCTAssertNotNil(bkunwrapped, @"unwrapped blob turns into an SFECKey (%@)", error); + + XCTAssertEqualObjects(aksunwrapped, bkunwrapped, @"Private key same between aks and bk"); +} + +- (void)testCreateRecoverySetForRecoveryKey { + // Not Implemented +} + +- (void)testCreateRecoverySetForAKS { + NSError* error; + + [self setFakeBagIdentity]; + + SecDbBackupRecoverySet* set = [_manager createRecoverySetWithBagSecret:nil forType:SecDbBackupRecoveryTypeAKS error:&error]; + XCTAssertNil(set, @"No set without secret!"); + XCTAssertEqual(error.code, SecDbBackupInvalidArgument, @"Expected different error without secret: %@", error); + error = nil; + + NSData* secret = [_manager createBackupBagSecret:&error]; + set = [_manager createRecoverySetWithBagSecret:secret forType:SecDbBackupRecoveryTypeAKS error:&error]; + XCTAssertNotNil(set, @"Got aks recoveryset from backup manager"); + XCTAssertNil(error, @"Didn't expect error obtaining recoveryset: %@", error); + + XCTAssertEqual(set.recoveryType, SecDbBackupRecoveryTypeAKS, @"Unexpected recovery type"); + XCTAssertEqualObjects(set.bagIdentity, _manager.bagIdentity, @"Bag identity copied properly"); + XCTAssertNotNil(set.wrappedBagSecret, @"Have bag secret in recovery set"); + XCTAssertNotNil(set.wrappedKCSKSecret, @"Have kcsk secret in recovery set"); + XCTAssertNotNil(set.wrappedRecoveryKey, @"Have recovery key in recovery set"); + + NSMutableData* recoverykeydata = [NSMutableData dataWithLength:APPLE_KEYSTORE_MAX_KEY_LEN]; + [SecAKSObjCWrappers aksDecryptWithKeybag:KEYBAG_DEVICE keyclass:key_class_aku + ciphertext:set.wrappedRecoveryKey outKeyclass:nil plaintext:recoverykeydata error:&error]; + XCTAssertNil(error, @"Able to decrypt recovery key: %@", error); + SFAESKey* recoverykey = [[SFAESKey alloc] initWithData:recoverykeydata specifier:[[SFAESKeySpecifier alloc] + initWithBitSize:SFAESKeyBitSize256] error:&error]; + XCTAssert(recoverykey, @"Got a recovery key from blob"); + XCTAssertNil(error, @"Didn't get error from recovery key blob: %@", error); + + SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:[[SFAESKeySpecifier alloc] + initWithBitSize:SFAESKeyBitSize256]]; + NSData* bagsecret = [op decrypt:[NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:set.wrappedBagSecret error:&error] withKey:recoverykey error:&error]; + XCTAssert(bagsecret, @"Reconstituted bag secret"); + XCTAssertNil(error, @"Didn't expect error reconstituting bag secret: %@", error); + XCTAssertEqualObjects(bagsecret, secret, @"Returned bag secret same as provided secret"); + + NSData* kcsksecret = [op decrypt:[NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:set.wrappedKCSKSecret error:&error] withKey:recoverykey error:&error]; + XCTAssert(kcsksecret, @"Reconstituted kcsk secret"); + XCTAssertNil(error, @"Didn't expect error reconstituting kcsk secret: %@", error); +} + +- (void)testWrapItemKey { + SFAESKey* randomKey = [self randomAESKey]; + NSError* error; + SecDbBackupWrappedItemKey* itemKey = [_manager wrapItemKey:randomKey forKeyclass:key_class_akpu error:&error]; + XCTAssertNil(itemKey, @"Do not expect result wrapping to akpu"); + XCTAssertEqual(error.code, SecDbBackupInvalidArgument, @"Expect invalid argument error wrapping to akpu"); + + error = nil; + itemKey = [_manager wrapItemKey:randomKey forKeyclass:key_class_ak error:&error]; + XCTAssertNil(error, @"No error wrapping item to ak"); + XCTAssertEqualObjects(itemKey.baguuid, _manager.bagIdentity.baguuid, @"item wrapped under expected bag uuid"); + + // TODO: implement decryption and test it here +} + +// Does not inspect the item because it's encrypted and no code yet built to do recovery. +- (void)testSecItemAddAddsBackupEncryption { + NSDictionary* q = @{(id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrAccessGroup : @"com.apple.security.securityd", + (id)kSecUseDataProtectionKeychain : @(YES), + (id)kSecReturnAttributes : @(YES) + }; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)q, NULL); + XCTAssertEqual(status, errSecSuccess, @"Regular old SecItemAdd succeeds"); + + __block CFErrorRef cfError = NULL; + __block bool ok = true; + __block NSData* readUUID; + ok &= kc_with_dbt(false, &cfError, ^bool(SecDbConnectionRef dbt) { + NSString* sql = @"SELECT backupUUID FROM genp WHERE agrp = 'com.apple.security.securityd'"; + ok &= SecDbPrepare(dbt, (__bridge CFStringRef)sql, &cfError, ^(sqlite3_stmt *stmt) { + ok &= SecDbStep(dbt, stmt, &cfError, ^(bool *stop) { + readUUID = [[NSData alloc] initWithBytes:sqlite3_column_blob(stmt, 0) length:sqlite3_column_bytes(stmt, 0)]; + }); + }); + return ok; + }); + + XCTAssert(ok, @"Talking to keychain went okay"); + XCTAssertEqual(cfError, NULL, @"Talking to keychain didn't yield an error (%@)", cfError); + CFReleaseNull(cfError); + XCTAssert(readUUID, @"Got stuff out of the keychain"); + + XCTAssertEqualObjects(readUUID, _manager.bagIdentity.baguuid, @"backup UUID is good"); +} + +@end + +#endif // SECDB_BACKUPS_ENABLED diff --git a/tests/SecDbBackupTests/SecDbBackupTests.plist b/tests/SecDbBackupTests/SecDbBackupTests.plist new file mode 100644 index 00000000..817e23d9 --- /dev/null +++ b/tests/SecDbBackupTests/SecDbBackupTests.plist @@ -0,0 +1,27 @@ + + + + + BATSConfigVersion + 0.1.0 + Project + Security + Tests + + + TestName + SecDbBackupTests + WorkingDirectory + /AppleInternal/XCTests/com.apple.security/ + ShowSubtestResults + + Timeout + 1200 + Command + + BATS_XCTEST_CMD SecDbBackupTests.xctest + + + + + diff --git a/tests/TrustTests/DaemonTests/LoggingServerTests.m b/tests/TrustTests/DaemonTests/LoggingServerTests.m new file mode 100644 index 00000000..a577e8ee --- /dev/null +++ b/tests/TrustTests/DaemonTests/LoggingServerTests.m @@ -0,0 +1,31 @@ +// +// LoggingServerTests.m +// Security +// +// Created by Bailey Basile on 6/11/19. +// + +#include +#import + +#import "../../../OSX/sec/securityd/SecTrustLoggingServer.h" + +@interface LoggingServerTests : XCTestCase +@end + +@implementation LoggingServerTests + +- (void)testIntegerTruncation { + XCTAssertEqualObjects(TATruncateToSignificantFigures(5, 1), @(5)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(5, 2), @(5)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(42, 1), @(40)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(42, 2), @(42)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(-335, 1), @(-300)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(-335, 2), @(-330)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(-335, 3), @(-335)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(12345678901LL, 2), @(12000000000LL)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(12345678901LL, 7), @(12345670000LL)); + XCTAssertEqualObjects(TATruncateToSignificantFigures(-12345678901LL, 3), @(-12300000000LL)); +} + +@end diff --git a/tests/TrustTests/EvaluationTests/CTTests.m b/tests/TrustTests/EvaluationTests/CTTests.m new file mode 100644 index 00000000..d7e1fc91 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/CTTests.m @@ -0,0 +1,1841 @@ +/* + * 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 "OSX/utilities/SecCFWrappers.h" +#include +#include +#include +#include + +#if !TARGET_OS_BRIDGE +#import +#endif + +#if TARGET_OS_IPHONE +#include +#else +#include +#endif + +#if !TARGET_OS_BRIDGE +#import +#import +#endif + +#import "TrustEvaluationTestCase.h" +#import "CTTests_data.h" +#include "../TestMacroConversions.h" + +@interface CTTests : TrustEvaluationTestCase + +@end + +@implementation CTTests + ++ (id) CF_RETURNS_RETAINED SecCertificateCreateFromResource:(NSString *)name { + NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:name withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"]; + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData); + return (__bridge id)cert; +} + ++ (NSData *)DataFromResource:(NSString *)name { + NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:name withExtension:@".bin" subdirectory:@"si-82-sectrust-ct-data"]; + return [NSData dataWithContentsOfURL:url]; +} + +- (NSDictionary *)eval_ct_trust:(NSArray *)certs + sCTs:(NSArray *)scts + ocspResponses:(NSArray *)ocsps + anchors:(NSArray *)anchors + trustedCTLogs:(NSArray *)trustedLogs + hostname:(NSString *)hostname + verifyDate:(NSDate *)date { + + /* Create the trust object */ + TestTrustEvaluation *trust = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); // Need to generate new certs for CTTests + XCTAssertNotNil(trust = [[TestTrustEvaluation alloc] initWithCertificates:certs policies:@[(__bridge id)policy]], + "create trust failed"); + CFReleaseNull(policy); + if (!trust) { return nil; } + + /* Set the optional properties */ + if (scts) { trust.presentedSCTs = scts; } + if (ocsps) { trust.ocspResponses = ocsps; } + if (anchors) { trust.anchors = anchors; } + if (trustedLogs) { trust.trustedCTLogs = trustedLogs; } + if (date) { trust.verifyDate = date; } + + /* Evaluate */ + NSError *error = nil; + XCTAssert([trust evaluate:&error], "failed trust evaluation: %@", error); + return trust.resultDictionary; +} + +static NSArray *anchors = nil; +static NSDate *date_20150307 = nil; +static NSDate *date_20160422 = nil; +static NSArray *trustedCTLogs = nil; + ++ (void)setUp { + [super setUp]; + SecCertificateRef anchor1 = (__bridge SecCertificateRef)[self SecCertificateCreateFromResource:@"CA_alpha"]; + SecCertificateRef anchor2 = (__bridge SecCertificateRef)[self SecCertificateCreateFromResource:@"CA_beta"]; + anchors = @[ (__bridge id)anchor1, (__bridge id)anchor2]; + CFReleaseNull(anchor1); + CFReleaseNull(anchor2); + date_20150307 = [NSDate dateWithTimeIntervalSinceReferenceDate:447450000.0]; // March 7, 2015 at 11:40:00 AM PST + date_20160422 = [NSDate dateWithTimeIntervalSinceReferenceDate:483050000.0]; // April 22, 2016 at 1:33:20 PM PDT + + NSURL *trustedLogsURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"CTlogs" + withExtension:@"plist" + subdirectory:@"si-82-sectrust-ct-data"]; + trustedCTLogs = [NSArray arrayWithContentsOfURL:trustedLogsURL]; + +#if !TARGET_OS_BRIDGE + /* Mock a successful mobile asset check-in so that we enforce CT */ + UpdateOTACheckInDate(); +#endif +} + +- (void)testOneEmbeddedSCT { + NSDictionary *results = nil; + SecCertificateRef certF = nil; + isnt(certF = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverF"], NULL, "create certF"); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(certF); +} + +- (void)testOnePresentedSCT { + NSDictionary *results = nil; + SecCertificateRef certD = nil; + NSData *proofD = nil; + isnt(certD = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverD"], NULL, "create certD"); + XCTAssertNotNil(proofD = [CTTests DataFromResource:@"serverD_proof"], "create proofD"); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certD] sCTs:@[proofD] ocspResponses:nil anchors:anchors + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(certD); +} + +- (void)testTooFewEmbeddedSCTsForLifetime { + NSDictionary *results = nil; + SecCertificateRef leaf = nil, subCA = nil, root = nil; + isnt(leaf = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"www_digicert_com_2015"], NULL, "create leaf"); + isnt(subCA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_sha2_ev_server_ca"], NULL, "create subCA"); + isnt(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_ev_root_ca"], NULL, "create root"); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)subCA]; + XCTAssertNotNil(results = [self eval_ct_trust:certs + sCTs:nil ocspResponses:nil anchors:@[(__bridge id)root] + trustedCTLogs:nil hostname:@"www.digicert.com" verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(leaf); + CFReleaseNull(subCA); + CFReleaseNull(root); +} + +- (void)testInvalidOCSPResponse { + NSDictionary *results = nil; + SecCertificateRef certA = nil; + NSData *proofA_1 = nil, *invalid_ocsp = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(invalid_ocsp = [CTTests DataFromResource:@"invalid_ocsp_response"], "create invalid ocsp response"); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:@[proofA_1] ocspResponses:@[invalid_ocsp] anchors:anchors + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(certA); +} + +- (void)testOCSPResponseWithBadHash { + NSDictionary *results = nil; + SecCertificateRef certA = nil; + NSData *proofA_1 = nil, *invalid_ocsp = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(invalid_ocsp = [CTTests DataFromResource:@"bad_hash_ocsp_response"], "create ocsp response with bad hash"); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:@[proofA_1] ocspResponses:@[invalid_ocsp] anchors:anchors + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(certA); +} + +- (void)testValidOCSPResponse { + NSDictionary *results = nil; + SecCertificateRef certA = nil; + NSData *proofA_1 = nil, *valid_ocsp = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(valid_ocsp = [CTTests DataFromResource:@"valid_ocsp_response"], "create invalid ocsp response"); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:@[proofA_1] ocspResponses:@[valid_ocsp] anchors:anchors + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(certA); +} + +- (void)testTwoPresentedSCTs { + NSDictionary *results = nil; + SecCertificateRef certA = nil; + NSData *proofA_1 = nil, *proofA_2 = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2"); + NSArray *scts = @[proofA_1, proofA_2]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); + CFReleaseNull(certA); +} + +- (void)testThreeEmbeddedSCTs { + NSDictionary *results = nil; + SecCertificateRef leaf = nil, subCA = nil, root = nil; + isnt(leaf = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"www_digicert_com_2016"], NULL, "create leaf"); + isnt(subCA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_sha2_ev_server_ca"], NULL, "create subCA"); + isnt(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"digicert_ev_root_ca"], NULL, "create subCA"); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)subCA]; + XCTAssertNotNil(results = [self eval_ct_trust:certs + sCTs:nil ocspResponses:nil anchors:@[(__bridge id)root] + trustedCTLogs:nil hostname:@"www.digicert.com" verifyDate:date_20160422]); +#if TARGET_OS_BRIDGE + /* BridgeOS doesn't have a root store or CT log list so default CT behavior (without input logs as above) is failed CT validation. */ + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); +#else + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); +#endif +#if TARGET_OS_WATCH + /* WatchOS doesn't require OCSP for EV flag, so even though the OCSP responder no longer responds for this cert, it is EV on watchOS. */ + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustExtendedValidation], @YES, "expected EV result"); +#else + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); +#endif + CFReleaseNull(leaf); + CFReleaseNull(subCA); + CFReleaseNull(root); +} + +- (void)testOtherCTCerts { + SecCertificateRef cfCert = NULL; + NSDictionary *results = nil; + +#define TEST_CASE(x) \ +do { \ + isnt(cfCert = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@#x], NULL, "create cfCert from " #x); \ + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)cfCert] \ + sCTs:nil ocspResponses:nil anchors:anchors \ + trustedCTLogs:trustedCTLogs hostname:nil verifyDate:date_20150307]); \ + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); \ + XCTAssertNil(results[(__bridge NSString*)kSecTrustExtendedValidation], "got EV result when no EV expected"); \ + CFReleaseNull(cfCert); \ + results = nil; \ +} while (0) + + TEST_CASE(server_1601); + TEST_CASE(server_1603); + TEST_CASE(server_1604); + TEST_CASE(server_1701); + TEST_CASE(server_1704); + TEST_CASE(server_1705); + TEST_CASE(server_1801); + TEST_CASE(server_1804); + TEST_CASE(server_1805); + TEST_CASE(server_2001); + +#undef TEST_CASE +} + +- (void)testLogListParsing { + NSDictionary *results = nil; + SecCertificateRef certF = nil; + isnt(certF = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverF"], NULL, "create certF"); + + /* Empty Log List */ + NSArray *testLogList = @[]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* Log not a dictionary */ + testLogList = @[@[]]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* Log list missing "key" key */ + testLogList = @[@{@"test":@"test"}]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* Value for "key" isn't a data object */ + testLogList = @[@{@"key":@"test"}]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certF] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:testLogList hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + CFReleaseNull(certF); +} + +- (void) testPrecertsFail { + SecCertificateRef precert = NULL, system_root = NULL; + SecTrustRef trust = NULL; + NSArray *precert_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:561540800.0]; // October 18, 2018 at 12:33:20 AM PDT + CFErrorRef error = NULL; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(precert = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"precert"], + errOut, fail("failed to create precert")); + + precert_anchors = @[(__bridge id)system_root]; + require_noerr_action(SecTrustCreateWithCertificates(precert, NULL, &trust), errOut, fail("failed to create trust object")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)precert_anchors), errOut, fail("failed to set anchor certificate")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + is(SecTrustEvaluateWithError(trust, &error), false, "SECURITY: trust evaluation of precert succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecUnknownCriticalExtensionFlag, "got wrong error code for precert, got %ld, expected %d", + (long)CFErrorGetCode(error), (int)errSecUnknownCriticalExtensionFlag); + } else { + fail("expected trust evaluation to fail and it did not."); + } + + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(precert); + CFReleaseNull(error); +} + ++ (NSArray *)setShardedTrustedLogs:(NSArray *)trustedLogs startTime:(CFAbsoluteTime)startTime endTime:(CFAbsoluteTime)endTime { + NSMutableArray * shardedLogs = [trustedLogs mutableCopy]; + [trustedLogs enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary *shardedLogData = [obj mutableCopy]; + shardedLogData[@"start_inclusive"] = [NSDate dateWithTimeIntervalSinceReferenceDate:startTime]; + shardedLogData[@"end_exclusive"] = [NSDate dateWithTimeIntervalSinceReferenceDate:endTime]; + [shardedLogs replaceObjectAtIndex:idx withObject:shardedLogData]; + }]; + return shardedLogs; +} + +- (void)testShardedLogs { + NSDictionary *results = nil; + SecCertificateRef certA = nil; + NSData *proofA_1 = nil, *proofA_2 = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2"); + NSArray *scts = @[proofA_1, proofA_2]; + + /* Certificate expiry within temporal shard window */ + NSArray *shardedCTLogs= [CTTests setShardedTrustedLogs:trustedCTLogs startTime:0.0 endTime:CFAbsoluteTimeGetCurrent()]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:shardedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); + + /* Certificate expiry before temporal shard window */ + shardedCTLogs= [CTTests setShardedTrustedLogs:trustedCTLogs startTime:CFAbsoluteTimeGetCurrent() endTime:(CFAbsoluteTimeGetCurrent() + 24*3600)]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:shardedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* Certificate expiry after temporal shard window */ + shardedCTLogs= [CTTests setShardedTrustedLogs:trustedCTLogs startTime:0.0 endTime:(24*3600)]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:shardedCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + CFReleaseNull(certA); +} + ++ (NSArray *)setReadOnlyTrustedLogs:(NSArray *)trustedLogs readOnlyTime:(CFAbsoluteTime)readOnlyTime +{ + NSMutableArray *readOnlyLogs = [trustedLogs mutableCopy]; + [trustedLogs enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary *logData = [obj mutableCopy]; + logData[@"frozen"] = [NSDate dateWithTimeIntervalSinceReferenceDate:readOnlyTime]; + [readOnlyLogs replaceObjectAtIndex:idx withObject:logData]; + }]; + return readOnlyLogs; +} + +- (void)testReadOnlyLogs { + NSDictionary *results = nil; + SecCertificateRef certA = nil; + NSData *proofA_1 = nil, *proofA_2 = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2"); + NSArray *scts = @[proofA_1, proofA_2]; + + /* SCTs before read-only date */ + NSArray *readOnlyCTLogs = [CTTests setReadOnlyTrustedLogs:trustedCTLogs readOnlyTime:CFAbsoluteTimeGetCurrent()]; + XCTAssertNotNil(readOnlyCTLogs); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:readOnlyCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); + + /* SCTs after read-only date */ + readOnlyCTLogs = [CTTests setReadOnlyTrustedLogs:trustedCTLogs readOnlyTime:0.0]; + XCTAssertNotNil(readOnlyCTLogs); + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:readOnlyCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + CFReleaseNull(certA); +} + ++ (NSArray *)setRetiredTrustedLogs:(NSArray *)trustedLogs retirementTime:(CFAbsoluteTime)retirementTime indexSet:(NSIndexSet *)indexSet +{ + __block NSMutableArray *retiredLogs = [trustedLogs mutableCopy]; + [trustedLogs enumerateObjectsAtIndexes:indexSet options:0.0 usingBlock:^(NSDictionary * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + NSMutableDictionary *logData = [obj mutableCopy]; + logData[@"expiry"] = [NSDate dateWithTimeIntervalSinceReferenceDate:retirementTime]; + [retiredLogs replaceObjectAtIndex:idx withObject:logData]; + }]; + return retiredLogs; +} + +- (void)testRetiredLogs { + NSDictionary *results = nil; + SecCertificateRef certA = nil, server1601 = nil; + NSData *proofA_1 = nil, *proofA_2 = nil; + isnt(certA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"serverA"], NULL, "create certA"); + isnt(server1601 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"server_1601"], NULL, "create server1601"); + XCTAssertNotNil(proofA_1 = [CTTests DataFromResource:@"serverA_proof_Alfa_3"], "create proofA_1"); + XCTAssertNotNil(proofA_2 = [CTTests DataFromResource:@"serverA_proof_Bravo_3"], "create proofA_2"); + NSArray *scts = @[proofA_1, proofA_2]; + + NSArray *retiredCTLogs = [CTTests setRetiredTrustedLogs:trustedCTLogs + retirementTime:CFAbsoluteTimeGetCurrent() + indexSet:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, trustedCTLogs.count)]]; + /* presented SCTs from retired logs */ + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)certA] sCTs:scts ocspResponses:nil anchors:anchors + trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* all embedded SCTs from retired logs */ + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* one embedded SCTs from retired log, before log retirement date (one once or currently qualified SCT) */ + retiredCTLogs = [CTTests setRetiredTrustedLogs:trustedCTLogs + retirementTime:CFAbsoluteTimeGetCurrent() + indexSet:[NSIndexSet indexSetWithIndex:0]]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); + + /* one embedded SCT from retired log, after retirement date */ + retiredCTLogs = [CTTests setRetiredTrustedLogs:trustedCTLogs + retirementTime:0.0 + indexSet:[NSIndexSet indexSetWithIndex:0]]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertNil(results[(__bridge NSString*)kSecTrustCertificateTransparency], "got CT result when no CT expected"); + + /* one embedded SCT before retirement date, one embedded SCT before read-only date */ + retiredCTLogs = [CTTests setReadOnlyTrustedLogs:trustedCTLogs readOnlyTime:CFAbsoluteTimeGetCurrent()]; + retiredCTLogs = [CTTests setRetiredTrustedLogs:retiredCTLogs retirementTime:CFAbsoluteTimeGetCurrent() indexSet:[NSIndexSet indexSetWithIndex:0]]; + XCTAssertNotNil(results = [self eval_ct_trust:@[(__bridge id)server1601] sCTs:nil ocspResponses:nil anchors:anchors + trustedCTLogs:retiredCTLogs hostname:nil verifyDate:date_20150307]); + XCTAssertEqualObjects(results[(__bridge NSString*)kSecTrustCertificateTransparency], @YES, "expected CT result"); + + CFReleaseNull(certA); + CFReleaseNull(server1601); +} + +//TODO: add more tests +// Expand unit tests for CT +// missing coverage: +// -other signing algorithms +// -v2 SCTs +// -future timestamps +// -SCT signature doesn't verify +// -OCSP-delivered SCTs +// -unknown logs (embedded, TLS, and OCSP) +// -two SCTs from the same log (different timestamps) + +@end + +// MARK: - +// MARK: CT Enforcement Exceptions tests +@interface CTExceptionsTests : TrustEvaluationTestCase +@end + +@implementation CTExceptionsTests +#if !TARGET_OS_BRIDGE // bridgeOS doesn't permit CT exceptions ++ (void)setUp { + [super setUp]; + NSURL *trustedLogsURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"CTlogs" + withExtension:@"plist" + subdirectory:@"si-82-sectrust-ct-data"]; + trustedCTLogs = [NSArray arrayWithContentsOfURL:trustedLogsURL]; + NSData *rootHash = [NSData dataWithBytes:_system_root_hash length:sizeof(_system_root_hash)]; + CFPreferencesSetAppValue(CFSTR("TestCTRequiredSystemRoot"), (__bridge CFDataRef)rootHash, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); +} + +- (void)testSetCTExceptions { + CFErrorRef error = NULL; + const CFStringRef TrustTestsAppID = CFSTR("com.apple.trusttests"); + const CFStringRef AnotherAppID = CFSTR("com.apple.security.not-this-one"); + CFDictionaryRef copiedExceptions = NULL; + + /* Verify no exceptions set */ + is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set"); + if (copiedExceptions) { + /* If we're starting out with exceptions set, a lot of the following will also fail, so just skip them */ + CFReleaseNull(copiedExceptions); + return; + } + + /* Set exceptions with specified AppID */ + NSDictionary *exceptions1 = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"], + }; + ok(SecTrustStoreSetCTExceptions(TrustTestsAppID, (__bridge CFDictionaryRef)exceptions1, &error), + "failed to set exceptions for TrustTests: %@", error); + + /* Copy all exceptions (with only one set) */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), + "failed to copy all exceptions: %@", error); + ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Copy this app's exceptions */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error), + "failed to copy TrustTests' exceptions: %@", error); + ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Copy a different app's exceptions */ + is(copiedExceptions = SecTrustStoreCopyCTExceptions(AnotherAppID, &error), NULL, + "failed to copy different app's exceptions: %@", error); + CFReleaseNull(copiedExceptions); + + /* Set different exceptions with implied AppID */ + CFDataRef leafHash = SecSHA256DigestCreate(NULL, _system_after_leafSPKI, sizeof(_system_after_leafSPKI)); + NSDictionary *leafException = @{ + (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)leafHash, + }; + NSDictionary *exceptions2 = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@".test.apple.com"], + (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] + }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions2, &error), + "failed to set exceptions for this app: %@", error); + + /* Ensure exceptions are replaced for TrustTests */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error), + "failed to copy TrustTests' exceptions: %@", error); + ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Set exceptions with a different AppID */ + CFDataRef rootHash = SecSHA256DigestCreate(NULL, _system_rootSPKI, sizeof(_system_rootSPKI)); + NSDictionary *rootExceptions = @{ + (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)rootHash, + }; + NSDictionary *exceptions3 = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ rootExceptions ] }; + ok(SecTrustStoreSetCTExceptions(AnotherAppID, (__bridge CFDictionaryRef)exceptions3, &error), + "failed to set exceptions for different app: %@", error); + + /* Copy only one of the app's exceptions */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error), + "failed to copy TrustTests' exceptions: %@", error); + ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Set empty exceptions */ + NSDictionary *empty = @{}; + ok(SecTrustStoreSetCTExceptions(TrustTestsAppID, (__bridge CFDictionaryRef)empty, &error), + "failed to set empty exceptions"); + + /* Copy exceptiosn to ensure no change */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error), + "failed to copy TrustTests' exceptions: %@", error); + ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Copy all exceptions */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), + "failed to copy all exceptions: %@", error); + is(CFDictionaryGetCount(copiedExceptions), 2, "Got the wrong number of all exceptions"); + NSDictionary *nsCopiedExceptions = CFBridgingRelease(copiedExceptions); + NSArray *domainExceptions = nsCopiedExceptions[(__bridge NSString*)kSecCTExceptionsDomainsKey]; + NSArray *caExceptions = nsCopiedExceptions[(__bridge NSString*)kSecCTExceptionsCAsKey]; + ok(domainExceptions && caExceptions, "Got both domain and CA exceptions"); + ok([domainExceptions count] == 1, "Got 1 domain exception"); + ok([caExceptions count] == 2, "Got 2 CA exceptions"); + ok([domainExceptions[0] isEqualToString:@".test.apple.com"], "domain exception is .test.apple.com"); + ok([caExceptions containsObject:leafException] && [caExceptions containsObject:rootExceptions], "got expected leaf and root CA exceptions"); + + /* Reset other app's exceptions */ + ok(SecTrustStoreSetCTExceptions(AnotherAppID, NULL, &error), + "failed to reset exceptions for different app: %@", error); + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), + "failed to copy all exceptions: %@", error); + ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + +#define check_errSecParam \ +if (error) { \ +is(CFErrorGetCode(error), errSecParam, "bad input produced unxpected error code: %ld", (long)CFErrorGetCode(error)); \ +} else { \ +fail("expected failure to set NULL exceptions"); \ +} + + /* Set exceptions with bad inputs */ + NSDictionary *badExceptions = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"], + @"not a key": @"not a value", + }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with unknown key"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey:@"test.apple.com" }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with bad value"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey: @[ @{} ] }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with bad array value"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @"test.apple.com" ] }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with bad array value"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{ + (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + @"not-a-key" : (__bridge NSData*)rootHash, + }] }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with bad CA dictionary value"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{ + (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + }] }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with bad CA dictionary value"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey: @[ @{ + (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : (__bridge NSData*)rootHash, + @"not-a-key":@"not-a-value" + }] }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with bad CA dictionary value"); + check_errSecParam + + badExceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey: @[ @".com" ] }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with TLD value"); + check_errSecParam +#undef check_errSecParam + + /* Remove exceptions using empty arrays */ + NSDictionary *emptyArrays = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[], + (__bridge NSString*)kSecCTExceptionsCAsKey : @[] + }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)emptyArrays, &error), + "failed to set empty array exceptions for this app: %@", error); + is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set"); + + CFReleaseNull(leafHash); + CFReleaseNull(rootHash); +} + +#define evalTrustExpectingError(errCode, ...) \ + is(SecTrustEvaluateWithError(trust, &error), false, __VA_ARGS__); \ + if (error) { \ + is(CFErrorGetCode(error), errCode, "got wrong error code, got %ld, expected %d", \ + (long)CFErrorGetCode(error), (int)errCode); \ + } else { \ + fail("expected trust evaluation to fail and it did not."); \ + } \ + CFReleaseNull(error); + +- (void) testSpecificDomainExceptions { + SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *exceptions_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + NSDictionary *exceptions = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"], + errOut, fail("failed to create system server cert issued after flag day with SCTs")); + + exceptions_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior + + /* superdomain exception without CT fails */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"test.apple.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + evalTrustExpectingError(errSecVerifyActionFailed, "superdomain exception unexpectedly succeeded"); + + /* subdomain exceptions without CT fails */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"one.ct.test.apple.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + evalTrustExpectingError(errSecVerifyActionFailed, "subdomain exception unexpectedly succeeded") + + /* no match without CT fails */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"example.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + evalTrustExpectingError(errSecVerifyActionFailed, "unrelated domain exception unexpectedly succeeded"); + + /* matching domain without CT succeeds */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + is(SecTrustEvaluateWithError(trust, &error), true, "exact match domain exception did not apply"); + + /* matching domain with CT succeeds */ + CFReleaseNull(trust); + require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior + is(SecTrustEvaluateWithError(trust, &error), true, "ct cert should always pass"); + + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(system_server_after_with_CT); + CFReleaseNull(trust); + CFReleaseNull(policy); + CFReleaseNull(error); +} + +- (void) testSubdomainExceptions { + SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *exceptions_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + NSDictionary *exceptions = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"], + errOut, fail("failed to create system server cert issued after flag day with SCTs")); + + exceptions_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior + + /* superdomain exception without CT succeeds */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".test.apple.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + is(SecTrustEvaluateWithError(trust, &error), true, "superdomain exception did not apply"); + + /* exact domain exception without CT succeeds */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".ct.test.apple.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + is(SecTrustEvaluateWithError(trust, &error), true, "exact domain exception did not apply"); + + /* no match without CT fails */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".example.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + evalTrustExpectingError(errSecVerifyActionFailed, "unrelated domain exception unexpectedly succeeded"); + + /* subdomain without CT fails */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".one.ct.test.apple.com"] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + evalTrustExpectingError(errSecVerifyActionFailed, "subdomain exception unexpectedly succeeded"); + + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(system_server_after_with_CT); + CFReleaseNull(trust); + CFReleaseNull(policy); + CFReleaseNull(error); +} + +- (void) testMixedDomainExceptions { + SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *exceptions_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + NSDictionary *exceptions = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"], + errOut, fail("failed to create system server cert issued after flag day with SCTs")); + + exceptions_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior + + /* specific domain exception without CT succeeds */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com", @".example.com" ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + is(SecTrustEvaluateWithError(trust, &error), true, "one of exact domain exception did not apply"); + + /* super domain exception without CT succeeds */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@".apple.com", @"example.com" ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + is(SecTrustEvaluateWithError(trust, &error), true, "one of superdomain exception did not apply"); + + /* both super domain and specific domain exceptions without CT succeeds */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"ct.test.apple.com", @".apple.com" ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + is(SecTrustEvaluateWithError(trust, &error), true, "both domain exception did not apply"); + + /* neither specific domain nor super domain exceptions without CT fails */ + exceptions = @{ (__bridge NSString*)kSecCTExceptionsDomainsKey : @[@"apple.com", @".example.com" ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + evalTrustExpectingError(errSecVerifyActionFailed, "no match domain unexpectedly succeeded"); + + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(system_server_after_with_CT); + CFReleaseNull(trust); + CFReleaseNull(policy); + CFReleaseNull(error); +} + +- (void) test_ct_leaf_exceptions { + SecCertificateRef system_root = NULL, system_server_after = NULL, system_server_after_with_CT = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *exceptions_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + NSDictionary *leafException = nil, *exceptions = nil; + NSData *leafHash = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"], + errOut, fail("failed to create system server cert issued after flag day with SCTs")); + + exceptions_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior + + /* set exception on leaf cert without CT */ + leafHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(system_server_after)); + leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : leafHash, + }; + exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), + "failed to set exceptions: %@", error); + is(SecTrustEvaluateWithError(trust, &error), true, "leaf public key exception did not apply"); + + /* set exception on leaf cert with CT */ + leafHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(system_server_after_with_CT)); + leafException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : leafHash, + }; + exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ leafException ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), + "failed to set exceptions: %@", error); + SecTrustSetNeedsEvaluation(trust); + evalTrustExpectingError(errSecVerifyActionFailed, "leaf cert with no public key exceptions succeeded"); + + /* matching public key with CT succeeds */ + CFReleaseNull(trust); + require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); // set trusted logs to trigger enforcing behavior + is(SecTrustEvaluateWithError(trust, &error), true, "ct cert should always pass"); + + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(system_server_after_with_CT); + CFReleaseNull(trust); + CFReleaseNull(policy); + CFReleaseNull(error); +} + +- (void) test_ct_unconstrained_ca_exceptions { + SecCertificateRef root = NULL, subca = NULL; + SecCertificateRef server_matching = NULL, server_matching_with_CT = NULL, server_partial = NULL, server_no_match = NULL, server_no_org = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *exceptions_anchors = nil, *certs = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + NSDictionary *caException = nil, *exceptions = nil; + NSData *caHash = nil; + + require_action(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_unconstrained_subca"], + errOut, fail("failed to create subca")); + require_action(server_matching = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_matching_orgs"], + errOut, fail("failed to create server cert with matching orgs")); + require_action(server_matching_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_matching_orgs_scts"], + errOut, fail("failed to create server cert with matching orgs and scts")); + require_action(server_partial = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_partial_orgs"], + errOut, fail("failed to create server cert with partial orgs")); + require_action(server_no_match = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_nonmatching_orgs"], + errOut, fail("failed to create server cert with non-matching orgs")); + require_action(server_no_org = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_no_orgs"], + errOut, fail("failed to create server cert with no orgs")); + + exceptions_anchors = @[ (__bridge id)root ]; + +#define createTrust(certs) \ +CFReleaseNull(trust); \ +require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); \ +require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); \ +require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); \ +require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + /* Set exception on the subCA */ + caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(subca)); + caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, + }; + exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : @[ caException ] }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), + "failed to set exceptions: %@", error); + + /* Verify that non-CT cert with Orgs matching subCA passes */ + certs = @[ (__bridge id)server_matching, (__bridge id)subca]; + createTrust(certs); + is(SecTrustEvaluateWithError(trust, &error), true, "matching org subca exception did not apply: %@", error); + + /* Verify that CT cert with Orgs matching subCA passes */ + certs = @[ (__bridge id)server_matching_with_CT, (__bridge id)subca]; + createTrust(certs); + is(SecTrustEvaluateWithError(trust, &error), true, "CT matching org subca exception did not apply: %@", error); + + /* Verify that non-CT cert with partial Org match fails */ + certs = @[ (__bridge id)server_partial, (__bridge id)subca]; + createTrust(certs); + evalTrustExpectingError(errSecVerifyActionFailed, "partial matching org leaf succeeded"); + + /* Verify that a non-CT cert with non-matching Org fails */ + certs = @[ (__bridge id)server_no_match, (__bridge id)subca]; + createTrust(certs); + evalTrustExpectingError(errSecVerifyActionFailed, "non-matching org leaf succeeded"); + + /* Verify that a non-CT cert with no Org fails */ + certs = @[ (__bridge id)server_no_org, (__bridge id)subca]; + createTrust(certs); + evalTrustExpectingError(errSecVerifyActionFailed, "no org leaf succeeded"); + + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); + +#undef createTrust + +errOut: + CFReleaseNull(root); + CFReleaseNull(subca); + CFReleaseNull(server_matching); + CFReleaseNull(server_matching_with_CT); + CFReleaseNull(server_partial); + CFReleaseNull(server_no_match); + CFReleaseNull(server_no_org); + CFReleaseNull(trust); + CFReleaseNull(policy); + CFReleaseNull(error); +} + +- (void) test_ct_constrained_ca_exceptions { + SecCertificateRef root = NULL, org_constrained_subca = NULL; + SecCertificateRef constraint_pass_server = NULL, constraint_pass_server_ct = NULL, constraint_fail_server = NULL; + SecCertificateRef dn_constrained_subca = NULL, dn_constrained_server = NULL, dn_constrained_server_mismatch = NULL; + SecCertificateRef dns_constrained_subca = NULL, dns_constrained_server = NULL, dns_constrained_server_mismatch = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *exceptions_anchors = nil, *certs = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + NSDictionary *caException = nil, *exceptions = nil; + NSMutableArray *caExceptions = [NSMutableArray array]; + NSData *caHash = nil; + + require_action(root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(org_constrained_subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_subca"], + errOut, fail("failed to create org-constrained subca")); + require_action(constraint_pass_server = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_server"], + errOut, fail("failed to create constrained non-CT leaf")); + require_action(constraint_pass_server_ct = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_server_scts"], + errOut, fail("failed to create constrained CT leaf")); + require_action(constraint_fail_server= (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_fail_server"], + errOut, fail("failed to create constraint failure leaf")); + require_action(dn_constrained_subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_org_subca"], + errOut, fail("failed to create dn-constrained subca")); + require_action(dn_constrained_server = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_org_server"], + errOut, fail("failed to create dn-constrained leaf")); + require_action(dn_constrained_server_mismatch = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_org_server_mismatch"], + errOut, fail("failed to create dn-constrained leaf with mismatched orgs")); + require_action(dns_constrained_subca = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_dn_subca"], + errOut, fail("failed to create dns-constrained subca")); + require_action(dns_constrained_server = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_dn_server"], + errOut, fail("failed to create dns-constrained leaf")); + require_action(dns_constrained_server_mismatch = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_constrained_no_dn_server_mismatch"], + errOut, fail("failed to create dns-constrained leaf with mismatched orgs")); + + exceptions_anchors = @[ (__bridge id)root ]; + + /* Set exception on the subCAs */ + caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(org_constrained_subca)); + caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, + }; + [caExceptions addObject:caException]; + + caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(dn_constrained_subca)); + caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, + }; + [caExceptions addObject:caException]; + + caHash = CFBridgingRelease(SecCertificateCopySubjectPublicKeyInfoSHA256Digest(dns_constrained_subca)); + caException = @{ (__bridge NSString*)kSecCTExceptionsHashAlgorithmKey : @"sha256", + (__bridge NSString*)kSecCTExceptionsSPKIHashKey : caHash, + }; + [caExceptions addObject:caException]; + exceptions = @{ (__bridge NSString*)kSecCTExceptionsCAsKey : caExceptions }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions, &error), + "failed to set exceptions: %@", error); + +#define createTrust(certs) \ +CFReleaseNull(trust); \ +require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); \ +require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)exceptions_anchors), errOut, fail("failed to set anchors")); \ +require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); \ +require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + /* Verify org-constrained non-CT leaf passes */ + certs = @[ (__bridge id)constraint_pass_server, (__bridge id)org_constrained_subca ]; + createTrust(certs); + is(SecTrustEvaluateWithError(trust, &error), true, "org constrained exception did not apply: %@", error); + + /* Verify org-constrained CT leaf passes */ + certs = @[ (__bridge id)constraint_pass_server_ct, (__bridge id)org_constrained_subca ]; + createTrust(certs); + is(SecTrustEvaluateWithError(trust, &error), true, "org constrained exception did not apply: %@", error); + + /* Verify org-constrained non-CT leaf with wrong org fails */ + certs = @[ (__bridge id)constraint_fail_server, (__bridge id)org_constrained_subca ]; + createTrust(certs); + evalTrustExpectingError(errSecInvalidName, "leaf failing name constraints succeeded"); + + /* Verify dn-constrained (but not with org) non-CT leaf with matching orgs succeeds */ + certs = @[ (__bridge id)dn_constrained_server, (__bridge id)dn_constrained_subca ]; + createTrust(certs); + is(SecTrustEvaluateWithError(trust, &error), true, "org match exception did not apply: %@", error); + + /* Verify dn-constrained (but not with org) non-CT leaf without matching orgs fails */ + certs = @[ (__bridge id)dn_constrained_server_mismatch, (__bridge id)dn_constrained_subca ]; + createTrust(certs); + evalTrustExpectingError(errSecVerifyActionFailed, "dn name constraints with no org succeeded"); + + /* Verify dns-constrained (no DN constraints) non-CT leaf with matching orgs succeeds */ + certs = @[ (__bridge id)dns_constrained_server, (__bridge id)dns_constrained_subca ]; + createTrust(certs); + is(SecTrustEvaluateWithError(trust, &error), true, "org match exception did not apply: %@", error); + + /* Verify dns-constrained (no DN constraints) non-CT leaf without matching orgs fails*/ + certs = @[ (__bridge id)dns_constrained_server_mismatch, (__bridge id)dns_constrained_subca ]; + createTrust(certs); + evalTrustExpectingError(errSecVerifyActionFailed, "dns name constraints with no DN constraint succeeded"); + + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), "failed to reset exceptions: %@", error); + +#undef createTrust + +errOut: + CFReleaseNull(root); + CFReleaseNull(org_constrained_subca); + CFReleaseNull(constraint_pass_server); + CFReleaseNull(constraint_pass_server_ct); + CFReleaseNull(constraint_fail_server); + CFReleaseNull(dn_constrained_subca); + CFReleaseNull(dn_constrained_server); + CFReleaseNull(dn_constrained_server_mismatch); + CFReleaseNull(dns_constrained_subca); + CFReleaseNull(dns_constrained_server); + CFReleaseNull(dns_constrained_server_mismatch); + CFReleaseNull(trust); + CFReleaseNull(policy); + CFReleaseNull(error); +} + +#else // TARGET_OS_BRIDGE +- (void)testSkipTests +{ + XCTAssert(true); +} +#endif // TARGET_OS_BRIDGE +@end + +// MARK: - +// MARK: CT Enforcement tests + +@interface CTEnforcementTests : TrustEvaluationTestCase +@end + +static NSArray *keychainCerts = nil; + +@implementation CTEnforcementTests ++ (void)setUp { + [super setUp]; + NSURL *trustedLogsURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"CTlogs" + withExtension:@"plist" + subdirectory:@"si-82-sectrust-ct-data"]; + trustedCTLogs = [NSArray arrayWithContentsOfURL:trustedLogsURL]; + + // set test root to be a fake system root + SecCertificateRef system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"]; + NSData *rootHash = [NSData dataWithBytes:_system_root_hash length:sizeof(_system_root_hash)]; + CFPreferencesSetAppValue(CFSTR("TestCTRequiredSystemRoot"), (__bridge CFDataRef)rootHash, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + CFReleaseNull(system_root); +} + +#if !TARGET_OS_BRIDGE +/* Skip tests on bridgeOS where we don't do MobileAsset updates */ +- (void)testNoMACheckIn { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + + /* Mock a failing MobileAsset so we don't enforce via MobileAsset */ + id mockFailedMA = OCMClassMock([MAAsset class]); + OCMStub([mockFailedMA startCatalogDownload:[OCMArg any] + options:[OCMArg any] + then:([OCMArg invokeBlockWithArgs:OCMOCK_VALUE((NSInteger){MADownloadFailed}), nil])]); + SecOTAPKIResetCurrentAssetVersion(NULL); + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // Out-of-date asset, test system cert after date without CT passes + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with out-of-date asset"); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +- (void)testKillSwitch { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + + /* Mock setting a kill switch */ + UpdateKillSwitch((__bridge NSString *)kOTAPKIKillSwitchCT, true); + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // CT kill switch enabled so test system cert after date without CT passes + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with out-of-date asset"); + + /* Remove the kill switch */ + UpdateKillSwitch((__bridge NSString *)kOTAPKIKillSwitchCT, false); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +- (void) testWithMACheckIn { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + + /* Mock a successful mobile asset check-in so that we enforce CT */ + XCTAssertTrue(UpdateOTACheckInDate(), "failed to set check-in date as now"); + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // test system cert after date without CT fails (with check-in) + is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with in-date asset succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d", + (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed); + } else { + fail("expected trust evaluation to fail and it did not."); + } + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} +#endif // !TARGET_OS_BRIDGE + +- (void)testWithTrustedLogs { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // test system cert after date without CT fails (with trusted logs) +#if !TARGET_OS_BRIDGE + is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with trusted logs succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d", + (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed); + } else { + fail("expected trust evaluation to fail and it did not."); + } +#else + /* BridgeOS doesn't enforce */ + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert with trusted logs failed"); +#endif + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} + +- (void)testExpiredCert { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:570000000.0]; // January 24, 2019 at 12:20:00 AM EST + CFErrorRef error = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // test expired system cert after date without CT passes with only expired error + ok(SecTrustIsExpiredOnly(trust), "expired non-CT cert had non-expiration errors"); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} + +- (void)testTrustExceptions { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + CFDataRef exceptions = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // test system cert after date without CT fails (with check-in) +#if !TARGET_OS_BRIDGE + is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag-date non-CT cert with trusted logs succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d", + (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed); + } else { + fail("expected trust evaluation to fail and it did not."); + } +#else + /* BridgeOS doesn't enforce */ + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert with trusted logs failed"); +#endif + + // test exceptions for failing cert passes + exceptions = SecTrustCopyExceptions(trust); + ok(SecTrustSetExceptions(trust, exceptions), "failed to set exceptions for failing non-CT cert"); + CFReleaseNull(exceptions); + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with exceptions set"); + SecTrustSetExceptions(trust, NULL); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); + CFReleaseNull(exceptions); +} + +- (void) testCATrustSettings { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + id persistentRef = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // test system cert + enterprise anchor after date without CT fails +#if !TARGET_OS_BRIDGE + persistentRef = [self addTrustSettingsForCert:system_root]; + is(SecTrustEvaluateWithError(trust, &error), false, "system post-flag date non-CT cert with enterprise root trust succeeded"); + if (error) { + is(CFErrorGetCode(error), errSecVerifyActionFailed, "got wrong error code for non-ct cert, got %ld, expected %d", + (long)CFErrorGetCode(error), (int)errSecVerifyActionFailed); + } else { + fail("expected trust evaluation to fail and it did not."); + } + [self removeTrustSettingsForCert:system_root persistentRef:persistentRef]; +#else + /* BridgeOS doesn't enforce (and doesn't use trust settings) */ + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert with trusted logs failed"); +#endif + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} + +- (void) testAppSystem { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // test app anchor for failing cert passes + enforce_anchors = @[ (__bridge id)system_server_after ]; + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with server cert app anchor"); +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} + +#if !TARGET_OS_BRIDGE +/* bridgeOS doens't have trust settings */ +- (void) testLeafTrustSettings { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + CFErrorRef error = nil; + id persistentRef = nil; + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // test trust settings for failing cert passes + persistentRef = [self addTrustSettingsForCert:system_server_after]; + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with server cert enterprise anchor"); + [self removeTrustSettingsForCert:system_server_after persistentRef:persistentRef]; + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} +#endif // !TARGET_OS_BRIDGE + +- (void) testEAPPolicy { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateEAP(true, NULL); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // EAP, test system cert after date without CT passes + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with EAP cert"); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +// Test pinning policy name +- (void) testPinningPolicy { + SecCertificateRef system_root = NULL, system_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after"], + errOut, fail("failed to create system server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + + // set policy name + require_noerr_action(SecTrustSetPinningPolicyName(trust, CFSTR("a-policy-name")), errOut, fail("failed to set policy name")); + + // set trusted logs to trigger enforcing behavior + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + + // pinning policy, test system cert after date without CT passes + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date non-CT cert failed with EAP cert"); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +// test system cert after date with CT passes +- (void) testAfterWithCT { + SecCertificateRef system_root = NULL, system_server_after_with_CT = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_after_with_CT = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_after_scts"], + errOut, fail("failed to create system server cert issued after flag day with SCTs")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_after_with_CT, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "system post-flag-date CT cert failed"); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_after_with_CT); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +// test system cert before date without CT passes +- (void) testBefore { + SecCertificateRef system_root = NULL, system_server_before = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + SecTrustRef trust = NULL; + NSArray *enforce_anchors = nil; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + + require_action(system_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_root"], + errOut, fail("failed to create system root")); + require_action(system_server_before = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_system_server_before"], + errOut, fail("failed to create system server cert issued before flag day")); + + enforce_anchors = @[ (__bridge id)system_root ]; + require_noerr_action(SecTrustCreateWithCertificates(system_server_before, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "system pre-flag-date non-CT cert failed"); + +errOut: + CFReleaseNull(system_root); + CFReleaseNull(system_server_before); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +#if !TARGET_OS_BRIDGE +// test enterprise (non-public) after date without CT passes, except on bridgeOS which doesn't have trust settings +- (void) testEnterpriseCA { + SecCertificateRef user_root = NULL, user_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + id persistentRef = nil; + + require_action(user_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_root"], + errOut, fail("failed to create user root")); + require_action(user_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_server_after"], + errOut, fail("failed to create user server cert issued after flag day")); + + persistentRef = [self addTrustSettingsForCert:user_root]; + require_noerr_action(SecTrustCreateWithCertificates(user_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust,(__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "non-system post-flag-date non-CT cert failed with enterprise anchor"); + [self removeTrustSettingsForCert:user_root persistentRef:persistentRef]; + +errOut: + CFReleaseNull(user_root); + CFReleaseNull(user_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} +#endif // !TARGET_OS_BRIDGE + +// test app anchor (non-public) after date without CT passes +- (void) testAppCA { + SecCertificateRef user_root = NULL, user_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("ct.test.apple.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + NSArray *enforce_anchors = nil; + + require_action(user_root = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_root"], + errOut, fail("failed to create user root")); + require_action(user_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_user_server_after"], + errOut, fail("failed to create user server cert issued after flag day")); + + enforce_anchors = @[ (__bridge id)user_root ]; + require_noerr_action(SecTrustCreateWithCertificates(user_server_after, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforce_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust,(__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "non-system post-flag-date non-CT cert failed with enterprise anchor"); + +errOut: + CFReleaseNull(user_root); + CFReleaseNull(user_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +// test apple anchor after date without CT passes +- (void) testAppleAnchor { + SecCertificateRef appleServerAuthCA = NULL, apple_server_after = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("bbasile-test.scv.apple.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + NSArray *certs = nil; + + require_action(appleServerAuthCA = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_apple_ca"], + errOut, fail("failed to create apple server auth CA")); + require_action(apple_server_after = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"enforcement_apple_server_after"], + errOut, fail("failed to create apple server cert issued after flag day")); + + certs = @[ (__bridge id)apple_server_after, (__bridge id)appleServerAuthCA ]; + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "apple post-flag-date non-CT cert failed"); + +errOut: + CFReleaseNull(appleServerAuthCA); + CFReleaseNull(apple_server_after); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +// test apple subCA after date without CT passes +- (void) testAppleSubCAException { + SecCertificateRef geoTrustRoot = NULL, appleISTCA8G1 = NULL, livability = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("bbasile-test.scv.apple.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:576000000.0]; // April 3, 2019 at 9:00:00 AM PDT + NSArray *certs = nil, *enforcement_anchors = nil; + + require_action(geoTrustRoot = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"GeoTrustPrimaryCAG2"], + errOut, fail("failed to create geotrust root")); + require_action(appleISTCA8G1 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"AppleISTCA8G1"], + errOut, fail("failed to create apple IST CA")); + require_action(livability = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"deprecatedSSLServer"], + errOut, fail("failed to create deprecated SSL Server cert")); + + certs = @[ (__bridge id)livability, (__bridge id)appleISTCA8G1 ]; + enforcement_anchors = @[ (__bridge id)geoTrustRoot ]; + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforcement_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "apple public post-flag-date non-CT cert failed"); + +#if !TARGET_OS_BRIDGE + // bridgeOS doesn't ever enforce CT + // Test with generic CT allowlist disable + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlist"), kCFBooleanTrue, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + SecTrustSetNeedsEvaluation(trust); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "apple public post-flag-date non-CT cert succeeded with allowlist disabled"); + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlist"), kCFBooleanFalse, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + + // Test with Apple allowlist disable + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlistApple"), kCFBooleanTrue, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + SecTrustSetNeedsEvaluation(trust); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "apple public post-flag-date non-CT cert succeeded with Apple allowlist disabled"); + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlistApple"), kCFBooleanFalse, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); +#endif // !TARGET_OS_BRIDGE + +errOut: + CFReleaseNull(geoTrustRoot); + CFReleaseNull(appleISTCA8G1); + CFReleaseNull(livability); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +// test google subCA after date without CT passes +- (void) testGoogleSubCAException { + SecCertificateRef globalSignRoot = NULL, googleIAG3 = NULL, google = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("www.google.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:562340800.0]; // October 27, 2018 at 6:46:40 AM PDT + NSArray *certs = nil, *enforcement_anchors = nil; + + require_action(globalSignRoot = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"GlobalSignRootCAR2"], + errOut, fail("failed to create geotrust root")); + require_action(googleIAG3 = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"GoogleIAG3"], + errOut, fail("failed to create apple IST CA")); + require_action(google = (__bridge SecCertificateRef)[CTTests SecCertificateCreateFromResource:@"google"], + errOut, fail("failed to create livability cert")); + + certs = @[ (__bridge id)google, (__bridge id)googleIAG3 ]; + enforcement_anchors = @[ (__bridge id)globalSignRoot ]; + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), errOut, fail("failed to create trust")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, fail("failed to set verify date")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)enforcement_anchors), errOut, fail("failed to set anchors")); + require_noerr_action(SecTrustSetTrustedLogs(trust, (__bridge CFArrayRef)trustedCTLogs), errOut, fail("failed to set trusted logs")); + ok(SecTrustEvaluateWithError(trust, NULL), "google public post-flag-date non-CT cert failed"); + +#if !TARGET_OS_BRIDGE + // bridgeOS doesn't ever enforce CT + // Test with generic CT allowlist disable + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlist"), kCFBooleanTrue, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + SecTrustSetNeedsEvaluation(trust); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "google public post-flag-date non-CT cert succeeded with allowlist disabled"); + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlist"), kCFBooleanFalse, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + + // Test with Google allowlist disable + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlistGoogle"), kCFBooleanTrue, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); + SecTrustSetNeedsEvaluation(trust); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "google public post-flag-date non-CT cert succeeded with Goole allowlist disabled"); + CFPreferencesSetAppValue(CFSTR("DisableCTAllowlistGoogle"), kCFBooleanFalse, CFSTR("com.apple.security")); + CFPreferencesAppSynchronize(CFSTR("com.apple.security")); +#endif // !TARGET_OS_BRIDGE + +errOut: + CFReleaseNull(globalSignRoot); + CFReleaseNull(googleIAG3); + CFReleaseNull(google); + CFReleaseNull(policy); + CFReleaseNull(trust); +} +@end diff --git a/OSX/shared_regressions/si-82-sectrust-ct.h b/tests/TrustTests/EvaluationTests/CTTests_data.h similarity index 71% rename from OSX/shared_regressions/si-82-sectrust-ct.h rename to tests/TrustTests/EvaluationTests/CTTests_data.h index bc000478..f86169e5 100644 --- a/OSX/shared_regressions/si-82-sectrust-ct.h +++ b/tests/TrustTests/EvaluationTests/CTTests_data.h @@ -1,13 +1,28 @@ /* - * si-82-sectrust-ct.h - * Security + * Copyright (c) 2018 Apple Inc. All Rights Reserved. * - * 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 si_82_sectrust_ct_h -#define si_82_sectrust_ct_h +#ifndef _TRUSTTESTS_EVALUATION_CT_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_CT_TESTS_H_ uint8_t _system_after_leafSPKI[] ={ 0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, @@ -53,4 +68,10 @@ uint8_t _system_rootSPKI[] ={ 0xF7,0x02,0x03,0x01,0x00,0x01, }; -#endif /* si_82_sectrust_ct_h */ +uint8_t _system_root_hash[] = { + 0x25,0xfd,0x5f,0x07,0x4b,0x54,0xca,0x2e,0xad,0x89,0xdc,0x09,0x23,0xb4,0xe0,0xfb, + 0x87,0x53,0xba,0x5a,0x90,0x92,0xc6,0xb9,0x0d,0x79,0xb1,0x5a,0x1e,0x21,0xd2,0xf5, +}; + + +#endif /* _TRUSTTESTS_EVALUATION_CT_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/ECTests.m b/tests/TrustTests/EvaluationTests/ECTests.m new file mode 100644 index 00000000..d3fb1f2a --- /dev/null +++ b/tests/TrustTests/EvaluationTests/ECTests.m @@ -0,0 +1,148 @@ +/* + * 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 "OSX/utilities/SecCFWrappers.h" + +#import "TrustEvaluationTestCase.h" +#import "ECTests_data.h" +#include "../TestMacroConversions.h" + +/* Set this to 1 to test support for the legacy ecdsa-with-specified + signature oid. */ +#define TEST_ECDSA_WITH_SPECIFIED 0 + +@interface ECTests : TrustEvaluationTestCase +@end + +#define trust_ok(CERT, ROOT, DATE, ...) \ +({ \ +XCTAssertTrue(test_trust_ok(CERT, sizeof(CERT), ROOT, sizeof(ROOT), DATE), __VA_ARGS__); \ +}) + +static bool test_trust_ok(const uint8_t *cert_data, size_t cert_len, + const uint8_t *root_data, size_t root_len, const char *date_str) { + SecTrustRef trust = NULL; + SecPolicyRef policy = NULL; + CFArrayRef anchors = NULL; + SecCertificateRef cert = NULL, root = NULL; + CFDateRef date = NULL; + bool result = false; + CFErrorRef error = NULL; + require_string(cert = SecCertificateCreateWithBytes(NULL, cert_data, cert_len), + errOut, "create cert"); + require_string(root = SecCertificateCreateWithBytes(NULL, root_data, root_len), + errOut, "create root"); + + policy = SecPolicyCreateSSL(false, NULL); + require_noerr_string(SecTrustCreateWithCertificates(cert, policy, &trust), + errOut, "create trust with single cert"); + anchors = CFArrayCreate(NULL, (const void **)&root, 1, + &kCFTypeArrayCallBacks); + require_noerr_string(SecTrustSetAnchorCertificates(trust, anchors), + errOut, "set anchors"); + + /* 2006/03/03 00:12:00 */ + date = CFDateCreate(NULL, 163037520.0); + require_noerr_string(SecTrustSetVerifyDate(trust, date), errOut, "set date"); + result = SecTrustEvaluateWithError(trust, &error); + +errOut: + CFReleaseSafe(date); + CFReleaseSafe(anchors); + CFReleaseSafe(policy); + CFReleaseSafe(root); + CFReleaseSafe(cert); + CFReleaseSafe(trust); + CFReleaseSafe(error); + return result; +} + +@implementation ECTests + +- (void)testMicrosoft_ECCerts { + /* Verification of ECC certs created by Microsoft */ + trust_ok(RootP256_cer, RootP256_cer, + "20060303001200", "RootP256_cer root"); +#if TEST_ECDSA_WITH_SPECIFIED + trust_ok(End_P256_Specified_SHA1_cer, RootP256_cer, + "20060303001200", "End_P256_Specified_SHA1_cer"); + trust_ok(End_P256_Specified_SHA256_cer, RootP256_cer, + "20060303001200", "End_P256_Specified_SHA256_cer"); + trust_ok(End_P384_Specified_SHA256_cer, RootP256_cer, + "20060303001200", "End_P384_Specified_SHA256_cer"); + trust_ok(End_P384_Specified_SHA384_cer, RootP256_cer, + "20060303001200", "End_P384_Specified_SHA384_cer"); + trust_ok(End_P521_Specified_SHA1_cer, RootP256_cer, + "20060303001200", "End_P521_Specified_SHA1_cer"); +#endif /* TEST_ECDSA_WITH_SPECIFIED */ + trust_ok(End_P256_combined_SHA256_cer, RootP256_cer, + "20060303001200", "End_P256_combined_SHA256_cer"); + trust_ok(End_P384_combined_SHA256_cer, RootP256_cer, + "20060303001200", "End_P384_combined_SHA256_cer"); + trust_ok(End_P384_combined_SHA1_cer, RootP256_cer, + "20060303001200", "End_P384_combined_SHA1_cer"); + trust_ok(End_P521_combined_SHA1_cer, RootP256_cer, + "20060303001200", "End_P521_combined_SHA1_cer"); + trust_ok(End_P256_combined_SHA512_cer, RootP256_cer, + "20060303001200", "End_P256_combined_SHA512_cer"); + trust_ok(End_P521_combined_SHA512_cer, RootP256_cer, + "20060303001200", "End_P521_combined_SHA512_cer"); +} + +- (void)testNSS_ECCerts { + /* Verification of ECC certs created by NSS */ + trust_ok(ECCCA_cer, ECCCA_cer, + "20060303001200", "ECCCA_cer root"); + trust_ok(ECCp192_cer, ECCCA_cer, + "20060303001200", "ECCp192_cer"); + trust_ok(ECCp256_cer, ECCCA_cer, + "20060303001200", "ECCp256_cer"); + trust_ok(ECCp384_cer, ECCCA_cer, + "20060303001200", "ECCp384_cer"); + trust_ok(ECCp521_cer, ECCCA_cer, + "20060303001200", "ECCp521_cer"); +} + +- (void)testOpenSSL_ECCerts { + /* Verification of ECC certs created by OpenSSL */ + trust_ok(secp256r1ca_cer, secp256r1ca_cer, + "20060303001200", "secp256r1ca_cer root"); + trust_ok(secp256r1server_secp256r1ca_cer, secp256r1ca_cer, + "20060303001200", "secp256r1server_secp256r1ca_cer"); + trust_ok(secp384r1ca_cer, secp384r1ca_cer, + "20060303001200", "secp384r1ca_cer root"); + trust_ok(secp384r1server_secp384r1ca_cer, secp384r1ca_cer, + "20060303001200", "secp384r1server_secp384r1ca_cer"); + trust_ok(secp521r1ca_cer, secp521r1ca_cer, + "20060303001200", "secp521r1ca_cer root"); + trust_ok(secp521r1server_secp521r1ca_cer, secp521r1ca_cer, + "20060303001200", "secp521r1server_secp521r1ca_cer"); +} + +@end diff --git a/tests/TrustTests/EvaluationTests/ECTests_data.h b/tests/TrustTests/EvaluationTests/ECTests_data.h new file mode 100644 index 00000000..dcdee64f --- /dev/null +++ b/tests/TrustTests/EvaluationTests/ECTests_data.h @@ -0,0 +1,1056 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_EC_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_EC_TESTS_H_ + +/* subject:/C=US/O=Red Hat/CN=ECC CA */ +/* issuer :/C=US/O=Red Hat/CN=ECC CA */ +unsigned char ECCCA_cer[386]={ + 0x30,0x82,0x01,0x7E,0x30,0x82,0x01,0x26,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x01, + 0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x30,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10,0x30,0x0E,0x06,0x03, + 0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74,0x31,0x0F,0x30,0x0D, + 0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43,0x41,0x30,0x20,0x17, + 0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x31,0x35,0x37,0x5A,0x18,0x0F, + 0x32,0x30,0x35,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x31,0x35,0x37,0x5A,0x30, + 0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, + 0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, + 0x41,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,0x25,0xDF,0xFC,0x2F, + 0x17,0xA8,0xED,0xAD,0x1B,0x49,0xBA,0xA9,0xA5,0x9E,0x8B,0x17,0x24,0x39,0x25,0xFF, + 0xDD,0x42,0x1F,0xBE,0xAB,0x79,0x99,0x4F,0xC8,0x6D,0x28,0x6B,0x10,0x06,0x1E,0x55, + 0xF5,0x12,0x2D,0x96,0x1D,0x7B,0x05,0x99,0x76,0xDA,0xC7,0xD4,0xB7,0x7F,0x18,0x89, + 0x27,0x6F,0xA5,0x20,0x09,0x6C,0x72,0xF8,0xC6,0x05,0xCD,0x11,0xA3,0x30,0x30,0x2E, + 0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03, + 0x02,0x00,0x07,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01,0x01, + 0xFF,0x30,0x0B,0x06,0x03,0x55,0x1D,0x0F,0x04,0x04,0x03,0x02,0x02,0x84,0x30,0x09, + 0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x47,0x00,0x30,0x44,0x02,0x20, + 0x30,0x09,0x1B,0x6F,0xE1,0xB2,0x99,0x8D,0xD1,0x84,0xB1,0xE2,0x9B,0xA4,0x05,0xB0, + 0xC9,0x33,0x1D,0xF2,0x82,0x8A,0x57,0x0C,0xE1,0xE4,0xA6,0xC8,0xB3,0x0A,0x49,0x2D, + 0x02,0x20,0x46,0x85,0xA2,0x1D,0xC1,0x0F,0xA2,0x94,0x85,0xF5,0x09,0xF7,0x53,0x5A, + 0xD8,0x81,0x2A,0xFB,0x02,0x0D,0xD9,0x42,0xE2,0xB4,0xF7,0xB7,0x28,0xDF,0x3A,0xF7, + 0x99,0x5C, +}; +/* subject:/C=US/O=Red Hat/OU=ECC p192/CN=jordan.sfbay.redhat.com */ +/* issuer :/C=US/O=Red Hat/CN=ECC CA */ +unsigned char ECCp192_cer[382]={ + 0x30,0x82,0x01,0x7A,0x30,0x82,0x01,0x21,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, + 0x81,0x7D,0x68,0xFA,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, + 0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, + 0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x37,0x34, + 0x36,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x37,0x34,0x36, + 0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, + 0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, + 0x20,0x70,0x31,0x39,0x32,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, + 0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, + 0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x49,0x30,0x13,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x02,0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,0x03,0x32, + 0x00,0x04,0x5E,0x73,0x9E,0x99,0xB2,0xCB,0xC8,0x29,0x9B,0x6A,0x60,0xE2,0x5C,0x04, + 0x38,0x61,0x42,0x76,0x4E,0xFA,0xC0,0x74,0x82,0x43,0x7F,0x73,0x98,0x03,0x8A,0x98, + 0x6D,0x49,0x76,0x35,0x4F,0xD6,0x5B,0x39,0x4F,0x93,0x57,0x2D,0xE8,0xFE,0xD4,0x1B, + 0xD5,0x26,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, + 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xD0,0xDA,0x8B,0xD0, + 0xCD,0x6A,0x49,0x59,0xD7,0xBF,0xFB,0xAA,0xFF,0x9D,0x86,0xBF,0xF1,0x08,0xA6,0x8D, + 0xE8,0x0E,0x34,0x18,0x06,0xCE,0x1D,0x26,0x3D,0x2E,0xFF,0xB4,0x02,0x20,0x5D,0x34, + 0x70,0xDC,0x65,0xBE,0xC3,0x86,0x3B,0xEF,0x4A,0xBA,0x25,0x6C,0x76,0xC1,0x78,0x3D, + 0xFB,0xD9,0xCF,0xD8,0x63,0x0A,0x76,0x24,0x04,0x82,0x82,0xDB,0x47,0xBE, +}; +/* subject:/C=US/O=Red Hat/OU=ECC p224/CN=jordan.sfbay.redhat.com */ +/* issuer :/C=US/O=Red Hat/CN=ECC CA */ +unsigned char ECCp224_cer[388]={ + 0x30,0x82,0x01,0x80,0x30,0x82,0x01,0x26,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, + 0x81,0x7D,0x69,0xB5,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, + 0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, + 0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x31,0x39,0x32, + 0x35,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x31,0x39,0x32,0x35, + 0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, + 0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, + 0x20,0x70,0x32,0x32,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, + 0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, + 0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x4E,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x21,0x03,0x3A,0x00,0x04,0xB1, + 0x41,0x9F,0x63,0x9A,0xFB,0xBE,0xC5,0xD6,0x2D,0xDD,0xC2,0x94,0x5E,0x3D,0xAC,0x5A, + 0x2C,0x85,0xD5,0xE7,0x4C,0xC4,0x67,0xF5,0xA7,0x27,0x99,0xC8,0x2D,0x8D,0x90,0x9A, + 0x50,0xFD,0x9A,0x5C,0x87,0xA5,0x24,0xDE,0x1F,0x01,0x9D,0xCE,0xDF,0x75,0x93,0x14, + 0x54,0x04,0x1C,0x9F,0x03,0x44,0x20,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60, + 0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09, + 0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x49,0x00,0x30,0x46,0x02,0x21, + 0x00,0xEA,0xCC,0x97,0xB3,0xF3,0xF2,0x23,0xF1,0xAB,0x90,0x4D,0x74,0x03,0x46,0xF9, + 0xE0,0x04,0x84,0x20,0xC1,0xD6,0x4B,0xC0,0xC1,0xE4,0x73,0xD8,0x91,0x28,0x13,0x0D, + 0xD5,0x02,0x21,0x00,0xAF,0xF7,0x8F,0x5F,0x58,0xD1,0x9F,0x15,0xD1,0x14,0x3B,0x4C, + 0xA8,0xA2,0x01,0xBA,0x31,0x85,0xEC,0x6A,0x36,0x5B,0x6B,0x64,0xF4,0x2E,0x0E,0x2D, + 0xA9,0x05,0x10,0x6C, +}; +/* subject:/C=US/O=Red Hat/OU=ECC p256/CN=jordan.sfbay.redhat.com */ +/* issuer :/C=US/O=Red Hat/CN=ECC CA */ +unsigned char ECCp256_cer[398]={ + 0x30,0x82,0x01,0x8A,0x30,0x82,0x01,0x31,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, + 0x81,0x7D,0x6A,0x1D,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, + 0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, + 0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x30,0x31, + 0x39,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x30,0x31,0x39, + 0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, + 0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, + 0x20,0x70,0x32,0x35,0x36,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, + 0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, + 0x68,0x61,0x74,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,0x02,0x5E,0xC5,0x3F,0x2D,0xB3,0x57,0x12,0xFE,0xDA,0x3D,0x2A,0xE1,0x27, + 0xD5,0xBA,0x99,0x56,0xB0,0x1D,0x47,0x3D,0x56,0xEB,0x7D,0xAE,0x72,0xBC,0x7D,0xEA, + 0x3F,0xCB,0x5B,0xD8,0x8F,0xA3,0x62,0xB0,0x0C,0xD5,0x14,0x0B,0x11,0x21,0x1A,0x34, + 0xDB,0x64,0x96,0x76,0x21,0x15,0xB6,0x17,0x9E,0xB8,0xF6,0x48,0x33,0xBD,0xD3,0x4F, + 0xEA,0xA5,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8, + 0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x4A,0x1D,0x02,0x95,0xC3, + 0xD8,0x71,0x6C,0x9E,0x8E,0x9E,0xC1,0x13,0x16,0xC5,0x7D,0x76,0x5C,0xB0,0x77,0x7C, + 0x37,0x0A,0xB6,0x7E,0x85,0xB1,0xDA,0x7C,0x32,0x52,0xBA,0x02,0x21,0x00,0xAC,0x8F, + 0x49,0x7D,0x42,0x6D,0x6D,0x03,0x6C,0x8B,0x0B,0x64,0x9C,0xFA,0x9B,0x08,0x05,0xD0, + 0x1D,0x4D,0xA9,0xF0,0x07,0x83,0x95,0xBE,0xB7,0x0E,0x9E,0xBE,0xC6,0x75, +}; +/* subject:/C=US/O=Red Hat/OU=ECC p384/CN=jordan.sfbay.redhat.com */ +/* issuer :/C=US/O=Red Hat/CN=ECC CA */ +unsigned char ECCp384_cer[427]={ + 0x30,0x82,0x01,0xA7,0x30,0x82,0x01,0x4E,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, + 0x81,0x7D,0x6A,0x67,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, + 0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, + 0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x30,0x35, + 0x39,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x30,0x35,0x39, + 0x5A,0x30,0x54,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, + 0x61,0x74,0x31,0x11,0x30,0x0F,0x06,0x03,0x55,0x04,0x0B,0x13,0x08,0x45,0x43,0x43, + 0x20,0x70,0x33,0x38,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13,0x17, + 0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65,0x64, + 0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x43, + 0x52,0x0B,0x54,0x28,0x27,0xB5,0x05,0xEC,0x01,0x7B,0x33,0xF5,0x8F,0x3E,0x69,0xF7, + 0xFA,0x93,0x8B,0x46,0xC2,0x1C,0xC8,0x28,0x4D,0xF5,0x8A,0x88,0xEC,0x91,0x9C,0x2E, + 0xD0,0x3F,0x2E,0x64,0x84,0x1B,0x3E,0xBD,0xF1,0xDD,0xA9,0xE4,0xC2,0xA8,0x2E,0xD4, + 0x98,0x91,0x5F,0xD8,0x21,0x2B,0x1D,0x38,0xB4,0x6D,0xF8,0xE9,0x05,0x5C,0x46,0x1A, + 0x2B,0x48,0xA9,0x8F,0xBD,0xC7,0xD9,0xE5,0x75,0xD4,0x1A,0x7B,0x91,0x8D,0x36,0xEE, + 0xF0,0xA6,0xB8,0x7C,0xDE,0xEE,0xBB,0x9E,0xF4,0x82,0x63,0xAD,0xA7,0xC3,0x1B,0xA3, + 0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01, + 0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04, + 0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0x9C,0xC0,0x76,0x15,0x17,0xB8,0x44, + 0xB9,0x48,0x02,0x74,0xB0,0x02,0x34,0xBE,0x4D,0x06,0xE7,0x05,0x03,0x2C,0xD0,0xF6, + 0xEB,0x45,0x5D,0x47,0xA4,0x79,0x9D,0xEE,0x66,0x02,0x20,0x02,0x05,0x84,0xD5,0xDC, + 0x9F,0x8A,0xA5,0xEB,0x09,0x58,0x0E,0xB5,0x02,0x71,0x5D,0xF7,0xDF,0x46,0xAE,0x6A, + 0x15,0xB0,0xCC,0x7C,0xF0,0x4B,0x56,0xFB,0x20,0x95,0x41, +}; +/* subject:/C=US/O=Red Hat/OU=ECC p5214/CN=jordan.sfbay.redhat.com */ +/* issuer :/C=US/O=Red Hat/CN=ECC CA */ +unsigned char ECCp521_cer[465]={ + 0x30,0x82,0x01,0xCD,0x30,0x82,0x01,0x75,0xA0,0x03,0x02,0x01,0x02,0x02,0x05,0x00, + 0x81,0x7D,0x6A,0xB7,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, + 0x30,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x10, + 0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48,0x61,0x74, + 0x31,0x0F,0x30,0x0D,0x06,0x03,0x55,0x04,0x03,0x13,0x06,0x45,0x43,0x43,0x20,0x43, + 0x41,0x30,0x1E,0x17,0x0D,0x30,0x36,0x30,0x32,0x30,0x33,0x32,0x32,0x32,0x31,0x34, + 0x31,0x5A,0x17,0x0D,0x30,0x36,0x30,0x35,0x30,0x33,0x32,0x32,0x32,0x31,0x34,0x31, + 0x5A,0x30,0x55,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04,0x0A,0x13,0x07,0x52,0x65,0x64,0x20,0x48, + 0x61,0x74,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0B,0x13,0x09,0x45,0x43,0x43, + 0x20,0x70,0x35,0x32,0x31,0x34,0x31,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x13, + 0x17,0x6A,0x6F,0x72,0x64,0x61,0x6E,0x2E,0x73,0x66,0x62,0x61,0x79,0x2E,0x72,0x65, + 0x64,0x68,0x61,0x74,0x2E,0x63,0x6F,0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A, + 0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86, + 0x00,0x04,0x01,0x71,0xB4,0x18,0xE9,0x83,0x60,0x7E,0x23,0x8F,0xDF,0x40,0xA2,0x95, + 0x76,0x3F,0x90,0xBB,0x39,0xAA,0x69,0x44,0x1B,0x5F,0xA4,0x98,0x4A,0xEC,0xED,0x11, + 0xC1,0xAE,0x14,0x84,0x5F,0x71,0xB6,0xAF,0x74,0x02,0x6F,0x65,0x31,0x09,0x2F,0x96, + 0x96,0x06,0xEC,0xA7,0x88,0x71,0x4A,0xBC,0x60,0x76,0x49,0xF7,0xA6,0x55,0x5A,0xF4, + 0xE6,0x6F,0xFC,0xA0,0x01,0x70,0x86,0x93,0xE2,0xC7,0xF6,0xB4,0x98,0x77,0xAA,0x91, + 0xAB,0xEA,0xB0,0x70,0x3E,0x81,0xC4,0xB9,0x47,0x67,0xB8,0xCC,0x8D,0x48,0x62,0x9E, + 0x3B,0xE3,0xC0,0x40,0x7D,0xF5,0xB4,0x69,0x1F,0xA3,0xEB,0x04,0x68,0x95,0x0A,0x42, + 0xC0,0xAC,0xE9,0xCF,0x2E,0xEC,0xA6,0x40,0x41,0x6A,0x30,0x20,0x89,0x57,0x4C,0xEC, + 0xC5,0x71,0x50,0x9F,0x1E,0x87,0xA3,0x15,0x30,0x13,0x30,0x11,0x06,0x09,0x60,0x86, + 0x48,0x01,0x86,0xF8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x06,0x40,0x30,0x09,0x06, + 0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x6D, + 0x48,0x0F,0x69,0xDA,0xB8,0x48,0x51,0x43,0xF5,0x02,0xD8,0x94,0xFA,0xFF,0xC9,0x23, + 0xEF,0xFF,0xD6,0xAA,0xC4,0x90,0xDB,0xE0,0xA4,0xEA,0xB4,0xCF,0x54,0xED,0xFD,0x02, + 0x20,0x55,0xB4,0xC1,0x2C,0x62,0x52,0x7E,0x70,0x46,0xFA,0x67,0xEF,0xB4,0xD4,0x94, + 0xEF,0x29,0xDC,0x71,0x46,0x5D,0x48,0x61,0x94,0x2B,0x6E,0xA8,0x62,0x1D,0xF9,0x13, + 0x1F, +}; + +#if TEST_ECDSA_WITH_SPECIFIED +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P256_Specified_SHA1_cer[574]={ + 0x30,0x82,0x02,0x3A,0x30,0x82,0x01,0xD6,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xE4, + 0xDD,0xA2,0x79,0x22,0x46,0xAF,0x9D,0x4A,0x71,0xDA,0xBC,0x68,0x30,0x70,0x63,0x30, + 0x14,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E, + 0x03,0x02,0x1A,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03, + 0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,0x50,0x00,0x32, + 0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,0x30,0x31,0x30,0x30, + 0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,0x31,0x30,0x30,0x30, + 0x30,0x30,0x30,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x03,0x1E, + 0x2E,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00, + 0x36,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,0x69,0x00,0x66,0x00, + 0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,0x00,0x31,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2, + 0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4, + 0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85, + 0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F, + 0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0xA3,0x81,0xD1,0x30,0x81,0xCE, + 0x30,0x81,0xCB,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67, + 0x86,0xA3,0x53,0x01,0x04,0x81,0xB7,0x30,0x81,0xB4,0x04,0x12,0x43,0x65,0x72,0x74, + 0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x18, + 0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36,0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69, + 0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14, + 0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00, + 0x35,0x00,0x36,0x00,0x04,0x68,0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD, + 0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57, + 0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85, + 0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62, + 0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9, + 0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20,0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B, + 0xEC,0x08,0xB5,0x78,0x19,0x16,0x88,0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x14, + 0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03, + 0x02,0x1A,0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xCD,0x27,0x04,0x6A, + 0x7A,0xFC,0x0F,0xCA,0xAA,0x17,0xDD,0x62,0xAD,0x56,0x40,0x26,0xBF,0xBB,0x8F,0xFD, + 0x47,0x80,0x24,0x09,0x5F,0x05,0x6B,0x61,0x86,0x8B,0xEA,0xC9,0x02,0x20,0x1B,0x57, + 0x9B,0x7D,0x07,0x71,0x74,0xEC,0x2E,0xA6,0x7F,0xF3,0x31,0x9F,0x76,0x21,0xA5,0x4E, + 0x37,0xAE,0xCB,0xA2,0x7B,0x09,0x3F,0x01,0x66,0x25,0x18,0xE3,0x8F,0x4D, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P256_Specified_SHA256_cer[589]={ + 0x30,0x82,0x02,0x49,0x30,0x82,0x01,0xE0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x92, + 0x1A,0x37,0x71,0x59,0xAB,0x6E,0xB3,0x48,0x9C,0xC1,0x3E,0xCB,0x20,0x2B,0xA0,0x30, + 0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, + 0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, + 0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, + 0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, + 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03, + 0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00, + 0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00, + 0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x32,0x00,0x35,0x00,0x36,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A, + 0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA, + 0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0, + 0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E, + 0x5A,0x1B,0xA3,0x81,0xD3,0x30,0x81,0xD0,0x30,0x81,0xCD,0x06,0x0F,0x2B,0x06,0x01, + 0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB9,0x30, + 0x81,0xB6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, + 0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36, + 0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35, + 0x36,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00, + 0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68, + 0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33, + 0xD5,0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA, + 0x02,0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0, + 0x1F,0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E, + 0x3F,0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F, + 0x20,0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16, + 0x88,0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, + 0x05,0x00,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xB9,0xE7,0x43,0x4B,0x49,0xA9, + 0x28,0xE0,0x25,0x6A,0xF6,0x40,0xF8,0xD7,0x08,0x1A,0x90,0x48,0x96,0x2B,0x13,0x23, + 0x50,0xE9,0x93,0x18,0xEA,0x0D,0x24,0x79,0xF6,0x40,0x02,0x21,0x00,0xBC,0xB3,0x8D, + 0xDF,0x5C,0x96,0xE4,0xB0,0x20,0xBA,0xAE,0x59,0x83,0x1E,0xE6,0x0D,0x06,0x5A,0x0B, + 0x3A,0xCB,0xA7,0x52,0xC9,0x20,0x90,0x78,0xA9,0x36,0x11,0xC3,0x9E, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P384_Specified_SHA256_cer[668]={ + 0x30,0x82,0x02,0x98,0x30,0x82,0x02,0x30,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xD7, + 0x49,0x65,0x6B,0xBB,0x38,0x01,0xB1,0x43,0xDD,0xC2,0xB9,0x37,0xD8,0x2B,0x56,0x30, + 0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, + 0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, + 0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, + 0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, + 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03, + 0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00, + 0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00, + 0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50, + 0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, + 0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, + 0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, + 0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, + 0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, + 0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3, + 0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x81,0xFE,0x06,0x0F,0x2B,0x06,0x01,0x04, + 0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xEA,0x30,0x81, + 0xE7,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61, + 0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F, + 0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36, + 0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, + 0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98, + 0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44, + 0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB, + 0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9, + 0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11, + 0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1, + 0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84, + 0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2, + 0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92, + 0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55, + 0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, + 0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x59,0x2A,0xCA,0xB2,0x04,0x41,0x23, + 0xDD,0x0E,0x23,0x58,0xD2,0x02,0xCB,0xB5,0xDA,0x7E,0x2A,0x9D,0xFF,0xC8,0x5F,0x39, + 0x11,0xE2,0x45,0x1A,0x75,0x5C,0x76,0xCE,0x7D,0x02,0x21,0x00,0xC9,0x57,0xBB,0x43, + 0x27,0xAE,0x84,0x53,0x17,0x11,0xE5,0x9E,0x6C,0x3D,0x14,0xB4,0x71,0x05,0x9F,0x45, + 0x9E,0xEF,0x7F,0xF2,0xAF,0xBD,0x57,0xE5,0xE7,0xE4,0x25,0x0F, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x003\x008\x004 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P384_Specified_SHA384_cer[669]={ + 0x30,0x82,0x02,0x99,0x30,0x82,0x02,0x30,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xF2, + 0x2A,0x87,0x2B,0x7D,0x53,0x13,0xA3,0x4A,0xF1,0x35,0x7C,0xDB,0x23,0x6F,0xA3,0x30, + 0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, + 0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, + 0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, + 0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, + 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3D,0x31,0x3B,0x30,0x39,0x06,0x03, + 0x55,0x04,0x03,0x1E,0x32,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00, + 0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00, + 0x69,0x00,0x66,0x00,0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x33,0x00,0x38,0x00,0x34,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50, + 0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, + 0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, + 0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, + 0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, + 0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, + 0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3, + 0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x81,0xFE,0x06,0x0F,0x2B,0x06,0x01,0x04, + 0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xEA,0x30,0x81, + 0xE7,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61, + 0x6D,0x70,0x6C,0x65,0x00,0x04,0x1A,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F, + 0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x33,0x38,0x34, + 0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, + 0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98, + 0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44, + 0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB, + 0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9, + 0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11, + 0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1, + 0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84, + 0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2, + 0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92, + 0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55, + 0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02, + 0x05,0x00,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xB8,0x9E,0x1B,0xB7,0x4C,0x37, + 0x88,0xD0,0x41,0x96,0xBD,0x8C,0xC4,0xD4,0x51,0xC8,0xF8,0xEB,0xE2,0x40,0x1B,0x15, + 0x68,0x36,0xB0,0x72,0x90,0x03,0x7B,0x7C,0xF3,0xD3,0x02,0x21,0x00,0xC2,0x00,0x4F, + 0x0D,0xD7,0x3A,0x21,0x3F,0x02,0x3F,0x76,0x4E,0xA8,0xF2,0x70,0x19,0xFF,0x88,0x0A, + 0xE8,0xA8,0x50,0xD4,0xD5,0x88,0xFD,0x2E,0x32,0xA4,0xED,0x63,0x4B, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x005\x002\x001\x00_\x00S\x00p\x00e\x00c\x00i\x00f\x00i\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P521_Specified_SHA1_cer[749]={ + 0x30,0x82,0x02,0xE9,0x30,0x82,0x02,0x85,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xBB, + 0x17,0x7C,0x5C,0xD2,0x80,0xF2,0x8F,0x4B,0x16,0x8F,0x07,0x9B,0x85,0x90,0x34,0x30, + 0x14,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E, + 0x03,0x02,0x1A,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03, + 0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00,0x50,0x00,0x32, + 0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34,0x30,0x31,0x30,0x30, + 0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33,0x31,0x30,0x30,0x30, + 0x30,0x30,0x30,0x5A,0x30,0x39,0x31,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x03,0x1E, + 0x2E,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00, + 0x31,0x00,0x5F,0x00,0x53,0x00,0x70,0x00,0x65,0x00,0x63,0x00,0x69,0x00,0x66,0x00, + 0x69,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41,0x00,0x31,0x30, + 0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B, + 0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84, + 0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78, + 0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54, + 0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8, + 0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E, + 0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA, + 0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90, + 0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED, + 0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0xA3,0x82,0x01, + 0x3C,0x30,0x82,0x01,0x38,0x30,0x82,0x01,0x34,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01, + 0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x82,0x01,0x1F,0x30,0x82, + 0x01,0x1B,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, + 0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x18,0x45,0x6E,0x64,0x5F,0x50,0x35,0x32,0x31, + 0x5F,0x53,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00, + 0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00, + 0x41,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x04,0x81,0xCE,0x45, + 0x43,0x53,0x36,0x42,0x00,0x00,0x00,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93, + 0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9, + 0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31, + 0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD, + 0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28, + 0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86, + 0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78, + 0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01, + 0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,0xCB,0x4A, + 0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,0x76,0x76,0x2E,0x66,0x17,0x79,0x73,0x85,0x22, + 0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,0x57,0x0B, + 0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,0x83,0xA8, + 0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,0x14,0x06, + 0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02, + 0x1A,0x05,0x00,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x0B,0x00,0xD0,0x87,0x48,0x6E, + 0x91,0x69,0x6C,0xBD,0xE1,0x54,0x4E,0xD2,0x4A,0xB6,0x88,0x5E,0xAA,0xC1,0xFE,0xEF, + 0xDC,0x6A,0x7C,0x72,0x70,0xFD,0x54,0x47,0x61,0x6C,0x02,0x21,0x00,0xFD,0xD8,0xFE, + 0xBB,0xF3,0x60,0x49,0x42,0x77,0x6A,0x2B,0xB6,0x38,0x67,0xA3,0x52,0xE8,0xC1,0xA9, + 0x8E,0x81,0xD3,0xC5,0xA0,0x24,0x14,0x3F,0xC8,0xFD,0xBF,0x51,0xC5, +}; +#endif /* TEST_ECDSA_WITH_SPECIFIED */ + +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P256_combined_SHA256_cer[557]={ + 0x30,0x82,0x02,0x29,0x30,0x82,0x01,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x56, + 0xFE,0xDD,0xC2,0x3F,0xD9,0x7C,0xA3,0x48,0x0E,0x9E,0x46,0x75,0xAE,0x31,0x39,0x30, + 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x1D,0x31,0x1B,0x30, + 0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, + 0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, + 0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, + 0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, + 0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, + 0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, + 0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x32,0x00,0x35,0x00,0x36,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A, + 0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA, + 0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0, + 0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E, + 0x5A,0x1B,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x81,0xCC,0x06,0x0F,0x2B,0x06,0x01, + 0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB8,0x30, + 0x81,0xB5,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, + 0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36, + 0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36, + 0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, + 0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,0x45, + 0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5, + 0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02, + 0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F, + 0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F, + 0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20, + 0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,0x88, + 0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x7B,0x9C,0x11,0xF8,0x74,0x62, + 0x81,0x33,0x42,0x81,0x09,0x93,0x90,0x7D,0x3F,0xA6,0xEA,0xD6,0x47,0x7F,0x02,0xCE, + 0x6E,0x2A,0x70,0x69,0x4F,0xE3,0xA0,0x42,0x48,0xB3,0x02,0x21,0x00,0xD2,0x0F,0xFF, + 0xF5,0xDB,0x13,0xE7,0xD5,0xB2,0x4D,0x60,0x74,0x41,0xFD,0x7A,0xF7,0x87,0xFA,0x38, + 0xFF,0x41,0x62,0xC0,0x60,0xBE,0x85,0x77,0x50,0xE2,0x34,0x64,0x3E, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x005\x001\x002 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P256_combined_SHA512_cer[557]={ + 0x30,0x82,0x02,0x29,0x30,0x82,0x01,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x6A, + 0x4A,0x02,0x0A,0xE7,0xBD,0x6F,0x90,0x40,0x1F,0xF8,0xF1,0xF6,0x29,0x0B,0x73,0x30, + 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,0x30,0x1D,0x31,0x1B,0x30, + 0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, + 0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, + 0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, + 0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, + 0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, + 0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, + 0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x35,0x00,0x31,0x00,0x32,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,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5,0x37,0x30,0xD7,0x65,0x9A, + 0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02,0x62,0xB9,0x83,0x58,0xFA, + 0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F,0x91,0x40,0x8F,0x9E,0xF0, + 0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F,0x0A,0x0E,0x12,0x0E,0x5E, + 0x5A,0x1B,0xA3,0x81,0xD2,0x30,0x81,0xCF,0x30,0x81,0xCC,0x06,0x0F,0x2B,0x06,0x01, + 0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xB8,0x30, + 0x81,0xB5,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, + 0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x32,0x35,0x36, + 0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x35,0x31,0x32, + 0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53, + 0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68,0x45, + 0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x6C,0xCD,0x5C,0xC7,0xCD,0xE2,0x79,0x33,0xD5, + 0x37,0x30,0xD7,0x65,0x9A,0xEB,0x45,0x10,0x57,0xCF,0x06,0x51,0xA4,0xFB,0xCA,0x02, + 0x62,0xB9,0x83,0x58,0xFA,0xB3,0xB4,0x01,0x85,0x4D,0xBE,0x8F,0x85,0x43,0xA0,0x1F, + 0x91,0x40,0x8F,0x9E,0xF0,0xCD,0xA6,0xFD,0x62,0x3E,0x99,0xEF,0x4F,0x18,0x9E,0x3F, + 0x0A,0x0E,0x12,0x0E,0x5E,0x5A,0x1B,0x2F,0xA9,0x13,0x48,0xAA,0x53,0x7C,0x1F,0x20, + 0x87,0xC9,0xAF,0x94,0x50,0x75,0xDC,0xAA,0x2B,0xEC,0x08,0xB5,0x78,0x19,0x16,0x88, + 0x24,0xCC,0x8B,0x7D,0xCF,0x6F,0xDA,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x03,0x04,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0x87,0xA9,0x50,0xE4,0x9D, + 0x51,0x56,0x8F,0x29,0xC1,0x0F,0xBD,0x10,0x6D,0x43,0x43,0x10,0x10,0xF3,0x08,0x9C, + 0x80,0x16,0x1A,0x5A,0x9F,0x1E,0x96,0x73,0x1C,0x96,0x54,0x02,0x20,0x1D,0x22,0xE1, + 0x9B,0x25,0x6E,0x21,0xB4,0x0A,0x64,0xF3,0xC4,0xDB,0x77,0xA4,0x5F,0x15,0x5A,0xAD, + 0xA4,0x81,0x68,0xB1,0x55,0xFE,0xD8,0xE6,0x4B,0xC8,0xB9,0x4C,0x95, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P384_combined_SHA1_cer[628]={ + 0x30,0x82,0x02,0x70,0x30,0x82,0x02,0x17,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x10, + 0x75,0xF7,0x9E,0x1A,0x44,0xE2,0xA6,0x48,0x38,0x44,0x2E,0xAD,0x3D,0x06,0xFD,0x30, + 0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x1D,0x31,0x1B,0x30,0x19, + 0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00, + 0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30, + 0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32, + 0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x35,0x30,0x33,0x06, + 0x03,0x55,0x04,0x03,0x1E,0x2C,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50, + 0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x62, + 0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41, + 0x00,0x31,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06, + 0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50,0x39,0x6D,0xDC,0x02,0x89, + 0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B, + 0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22, + 0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D, + 0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51, + 0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66, + 0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3,0x82,0x01,0x01,0x30,0x81, + 0xFE,0x30,0x81,0xFB,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF, + 0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xE7,0x30,0x81,0xE4,0x04,0x12,0x43,0x65,0x72, + 0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04, + 0x17,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E, + 0x65,0x64,0x5F,0x53,0x48,0x41,0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14, + 0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00, + 0x38,0x00,0x34,0x00,0x04,0x81,0x98,0x45,0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50, + 0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, + 0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, + 0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, + 0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, + 0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, + 0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58, + 0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,0x71,0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55, + 0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,0x08,0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB, + 0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,0x81,0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30, + 0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02, + 0x20,0x5B,0x9F,0x7C,0x3A,0x41,0x10,0x43,0xC5,0x4E,0xF4,0xFA,0xCD,0xB4,0x55,0xE2, + 0x93,0x26,0xF9,0x3D,0xB5,0x4D,0x2B,0xE7,0x76,0x73,0x38,0xA0,0x4F,0xB6,0x89,0x63, + 0xF7,0x02,0x21,0x00,0xFC,0xD6,0xF7,0x3E,0x9E,0x8E,0x59,0x93,0x5C,0xAA,0x41,0xA2, + 0x24,0x9A,0x9F,0xBC,0x37,0xAE,0x45,0x7C,0x3C,0x7C,0xFF,0xC7,0xFE,0x4B,0x61,0x48, + 0x9B,0xE8,0xE6,0x38, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x003\x008\x004\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x002\x005\x006 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P384_combined_SHA256_cer[636]={ + 0x30,0x82,0x02,0x78,0x30,0x82,0x02,0x1F,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xA8, + 0xC0,0xEA,0x79,0x10,0x6D,0x61,0xAD,0x43,0x66,0xD0,0xDC,0xAC,0x2E,0x51,0x06,0x30, + 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x1D,0x31,0x1B,0x30, + 0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, + 0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, + 0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, + 0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, + 0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, + 0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, + 0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x50, + 0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90,0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82, + 0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4,0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D, + 0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3,0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6, + 0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F,0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC, + 0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A,0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05, + 0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10,0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0xA3, + 0x82,0x01,0x04,0x30,0x82,0x01,0x00,0x30,0x81,0xFD,0x06,0x0F,0x2B,0x06,0x01,0x04, + 0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xE9,0x30,0x81, + 0xE6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61, + 0x6D,0x70,0x6C,0x65,0x00,0x04,0x19,0x45,0x6E,0x64,0x5F,0x50,0x33,0x38,0x34,0x5F, + 0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41,0x32,0x35,0x36,0x00, + 0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00, + 0x41,0x00,0x5F,0x00,0x50,0x00,0x33,0x00,0x38,0x00,0x34,0x00,0x04,0x81,0x98,0x45, + 0x43,0x53,0x34,0x30,0x00,0x00,0x00,0x50,0x39,0x6D,0xDC,0x02,0x89,0xA4,0x44,0x90, + 0x3A,0x6E,0x4C,0xE0,0x97,0x35,0xD1,0x82,0xC2,0xBE,0xB3,0x48,0x7B,0x98,0xEB,0xA4, + 0x9D,0x04,0x38,0x9E,0xD9,0xB2,0x4C,0x5D,0xE3,0x6F,0x62,0x08,0x22,0x08,0xD9,0xA3, + 0xAE,0x43,0xB8,0xB5,0x65,0x2D,0x5F,0xB6,0x87,0xE9,0x41,0x0B,0x7D,0xA4,0x11,0x9F, + 0x08,0xCA,0x9B,0x39,0x84,0xDD,0x96,0xAC,0x28,0xC0,0xA0,0x1F,0x51,0x84,0xB1,0x1A, + 0x46,0xEF,0xE7,0x63,0x72,0xAA,0xD2,0x05,0x79,0xC1,0x3C,0x06,0x66,0xAE,0x84,0x10, + 0x74,0x9F,0xB1,0xFF,0x9F,0x34,0xBF,0x58,0x01,0x0E,0x04,0x30,0xAF,0x13,0xE2,0x71, + 0x54,0xA4,0xE6,0x9C,0x43,0x67,0x02,0x55,0xE4,0x11,0xF5,0x7C,0x5A,0x86,0x92,0x08, + 0xEA,0xD2,0x75,0xE3,0xE7,0x73,0x99,0xAB,0xF7,0x5D,0x18,0x5B,0xDF,0x17,0x55,0x81, + 0xC9,0xC8,0x63,0x3E,0x6E,0x3F,0x81,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x03,0x02,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x29,0x22,0x02,0x06,0x24,0xB8, + 0xED,0xEC,0x12,0xC9,0xE5,0xE0,0xC7,0xB2,0x75,0x12,0x62,0x05,0xED,0x62,0xAF,0x9A, + 0x31,0x0D,0x42,0xA7,0x3C,0x03,0x2A,0x76,0xD8,0x1E,0x02,0x20,0x27,0x74,0x0F,0x3B, + 0x0A,0x8A,0x7D,0x4F,0x2B,0x76,0x0C,0x34,0x87,0xC8,0xD2,0xC9,0xBC,0xF7,0x0A,0x0D, + 0xF9,0x64,0x52,0xD2,0x8D,0xCF,0x9E,0x06,0x90,0xF6,0xE8,0x13, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x005\x002\x001\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x001 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P521_combined_SHA1_cer[725]={ + 0x30,0x82,0x02,0xD1,0x30,0x82,0x02,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0xD2, + 0x71,0xD1,0x3D,0x82,0x40,0xE3,0xA9,0x44,0x27,0x3F,0xC6,0x18,0x9A,0x4E,0x44,0x30, + 0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x1D,0x31,0x1B,0x30,0x19, + 0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00, + 0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30, + 0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32, + 0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x37,0x31,0x35,0x30,0x33,0x06, + 0x03,0x55,0x04,0x03,0x1E,0x2C,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00,0x50, + 0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00,0x62, + 0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00,0x41, + 0x00,0x31,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, + 0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x01,0x8C,0x45,0xFF, + 0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2, + 0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B, + 0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32, + 0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05, + 0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0, + 0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC, + 0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C, + 0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57, + 0xA3,0x82,0x01,0x3B,0x30,0x82,0x01,0x37,0x30,0x82,0x01,0x33,0x06,0x0F,0x2B,0x06, + 0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x82,0x01, + 0x1E,0x30,0x82,0x01,0x1A,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61, + 0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x17,0x45,0x6E,0x64,0x5F,0x50, + 0x35,0x32,0x31,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65,0x64,0x5F,0x53,0x48,0x41, + 0x31,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00, + 0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x35,0x00,0x32,0x00,0x31,0x00,0x04,0x81, + 0xCE,0x45,0x43,0x53,0x36,0x42,0x00,0x00,0x00,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84, + 0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78, + 0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54, + 0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8, + 0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E, + 0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA, + 0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90, + 0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED, + 0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02,0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16, + 0xCB,0x4A,0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4,0x76,0x76,0x2E,0x66,0x17,0x79,0x73, + 0x85,0x22,0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00,0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7, + 0x57,0x0B,0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB,0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42, + 0x83,0xA8,0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF,0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30, + 0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x49,0x00,0x30,0x46,0x02, + 0x21,0x00,0xC2,0xC4,0x47,0x63,0x90,0x43,0xDD,0x8C,0x62,0x6D,0x6F,0xC9,0xBE,0xDF, + 0x5E,0x85,0xDD,0x66,0xBC,0x50,0x3C,0x05,0xBA,0x1A,0x08,0x5B,0xE9,0x4F,0x53,0xA1, + 0x0E,0x93,0x02,0x21,0x00,0xDC,0xD6,0xA2,0x50,0x24,0x7C,0x62,0xFA,0x29,0x8B,0x97, + 0x8B,0x17,0x6F,0x1F,0x19,0x40,0x7B,0x50,0x7C,0xED,0xCE,0xB0,0xF5,0x6E,0xCA,0xE6, + 0xD2,0xFF,0xB2,0x10,0xBB, +}; +/* subject:/CN=\x00E\x00n\x00d\x00_\x00P\x002\x005\x006\x00_\x00C\x00o\x00m\x00b\x00i\x00n\x00e\x00d\x00_\x00S\x00H\x00A\x005\x001\x002 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char End_P521_combined_SHA512_cer[733]={ + 0x30,0x82,0x02,0xD9,0x30,0x82,0x02,0x7E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, + 0xC5,0xA8,0x41,0x8A,0xCD,0x27,0xBB,0x44,0x7A,0x81,0xFE,0x64,0xBC,0xC2,0x86,0x30, + 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04,0x30,0x1D,0x31,0x1B,0x30, + 0x19,0x06,0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54, + 0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31, + 0x30,0x34,0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31, + 0x32,0x33,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x3B,0x31,0x39,0x30,0x37, + 0x06,0x03,0x55,0x04,0x03,0x1E,0x30,0x00,0x45,0x00,0x6E,0x00,0x64,0x00,0x5F,0x00, + 0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x5F,0x00,0x43,0x00,0x6F,0x00,0x6D,0x00, + 0x62,0x00,0x69,0x00,0x6E,0x00,0x65,0x00,0x64,0x00,0x5F,0x00,0x53,0x00,0x48,0x00, + 0x41,0x00,0x35,0x00,0x31,0x00,0x32,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86, + 0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00, + 0x04,0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4, + 0xB7,0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C, + 0x23,0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98, + 0x24,0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C, + 0xD1,0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0, + 0x74,0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6, + 0xF2,0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B, + 0xB2,0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82, + 0x02,0xE4,0xCB,0xF8,0x57,0xA3,0x82,0x01,0x3D,0x30,0x82,0x01,0x39,0x30,0x82,0x01, + 0x35,0x06,0x0F,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3, + 0x53,0x01,0x04,0x82,0x01,0x20,0x30,0x82,0x01,0x1C,0x04,0x12,0x43,0x65,0x72,0x74, + 0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53,0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x19, + 0x45,0x6E,0x64,0x5F,0x50,0x35,0x32,0x31,0x5F,0x63,0x6F,0x6D,0x62,0x69,0x6E,0x65, + 0x64,0x5F,0x53,0x48,0x41,0x35,0x31,0x32,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04, + 0x14,0x45,0x00,0x43,0x00,0x44,0x00,0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x35, + 0x00,0x32,0x00,0x31,0x00,0x04,0x81,0xCE,0x45,0x43,0x53,0x36,0x42,0x00,0x00,0x00, + 0x01,0x8C,0x45,0xFF,0x45,0x37,0x84,0x67,0x93,0x5F,0x82,0xE0,0xD2,0x4D,0xF4,0xB7, + 0xC4,0x1F,0x19,0xF2,0xCC,0xB6,0x78,0xA5,0xE9,0x2B,0xFF,0x31,0xBB,0xE7,0x4C,0x23, + 0xB9,0xA4,0x9F,0x5B,0x7A,0x55,0x54,0xF8,0x31,0x4D,0x64,0x9D,0x76,0xE9,0x98,0x24, + 0xCA,0xBA,0x6E,0x32,0x87,0x76,0xA8,0x08,0xCD,0x75,0x8A,0x03,0x7D,0x63,0x2C,0xD1, + 0xCB,0xD1,0x01,0x05,0x14,0xF8,0x2E,0xE5,0x28,0x23,0xB6,0x77,0xCF,0x5B,0xC0,0x74, + 0xED,0xF1,0x44,0xD0,0x60,0x0F,0xAA,0x70,0x86,0x01,0xD0,0x86,0x46,0x66,0xC6,0xF2, + 0x19,0xD5,0x87,0xBC,0x56,0xC7,0x90,0xA7,0x78,0x5F,0x57,0x6F,0x2D,0x3D,0x0B,0xB2, + 0x7C,0xF3,0xBF,0x1C,0x8B,0x00,0xED,0xDC,0x01,0x3F,0xFA,0xFE,0xE8,0x42,0x82,0x02, + 0xE4,0xCB,0xF8,0x57,0x00,0x6A,0x16,0xCB,0x4A,0x50,0x7E,0xA6,0x23,0xDA,0xB0,0xD4, + 0x76,0x76,0x2E,0x66,0x17,0x79,0x73,0x85,0x22,0x91,0xAE,0x66,0xEB,0xA0,0xE6,0x00, + 0x9F,0x5B,0x9E,0x63,0x39,0x5D,0xE7,0x57,0x0B,0xAB,0x1D,0xDE,0x69,0x35,0xD3,0xFB, + 0x7E,0x7C,0x57,0x08,0x67,0x6E,0x42,0x83,0xA8,0x6B,0xAA,0xA8,0x19,0x7C,0xC5,0xCF, + 0x05,0x88,0x57,0x9C,0xAC,0xB0,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04, + 0x03,0x04,0x03,0x49,0x00,0x30,0x46,0x02,0x21,0x00,0xD3,0xE5,0x57,0xD9,0xA3,0x26, + 0x56,0x5F,0x1D,0x5C,0x88,0x1B,0x63,0x80,0x33,0x22,0x5D,0x35,0x52,0x3F,0x29,0xFC, + 0xFF,0x5E,0x5D,0xBE,0x80,0x4D,0xCD,0xC4,0xA1,0x27,0x02,0x21,0x00,0xAC,0xA0,0x01, + 0x4F,0x29,0xC3,0xA9,0x04,0xE3,0xB9,0xCB,0xA3,0xF7,0xF0,0x80,0x5C,0x61,0xCF,0x1F, + 0x8B,0xEE,0x79,0xBD,0x16,0x2D,0x5B,0xF3,0xBD,0xF2,0x84,0x49,0xF8, +}; +/* subject:/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +/* issuer :/CN=\x00R\x00O\x00O\x00T\x00_\x00P\x002\x005\x006 */ +unsigned char RootP256_cer[539]={ + 0x30,0x82,0x02,0x17,0x30,0x82,0x01,0xB0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x8F, + 0x92,0x09,0xDB,0xA4,0xFC,0xDA,0xA1,0x45,0xC2,0xFA,0x59,0x87,0xC6,0xEA,0xE6,0x30, + 0x18,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86, + 0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06, + 0x03,0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F, + 0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x30,0x1E,0x17,0x0D,0x30,0x31,0x30,0x34, + 0x30,0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x30,0x31,0x32,0x33, + 0x31,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x1D,0x31,0x1B,0x30,0x19,0x06,0x03, + 0x55,0x04,0x03,0x1E,0x12,0x00,0x52,0x00,0x4F,0x00,0x4F,0x00,0x54,0x00,0x5F,0x00, + 0x50,0x00,0x32,0x00,0x35,0x00,0x36,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,0x85,0x59,0x2A,0x87,0x8E,0x6A,0x9B,0xB9,0x19,0xD4,0x73,0x82,0x24,0xC1, + 0x03,0x15,0xB3,0xF1,0x70,0x88,0x1B,0xAA,0xBA,0x57,0xE8,0x76,0x9F,0xC0,0xCE,0xF6, + 0xA9,0xBB,0x19,0xF5,0x6B,0x09,0x63,0xFB,0x69,0xA1,0x3D,0x88,0x67,0x3E,0x7E,0x1F, + 0x7B,0x18,0xC8,0xF2,0x31,0xE6,0xD7,0x54,0xD5,0xA7,0xAA,0x09,0x9C,0x15,0xD1,0x8D, + 0x37,0x7F,0xA3,0x81,0xC3,0x30,0x81,0xC0,0x30,0x81,0xBD,0x06,0x0F,0x2B,0x06,0x01, + 0x04,0x01,0x82,0x37,0x13,0x82,0xDF,0x67,0x86,0xA3,0x53,0x01,0x04,0x81,0xA9,0x30, + 0x81,0xA6,0x04,0x12,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x53, + 0x61,0x6D,0x70,0x6C,0x65,0x00,0x04,0x0A,0x52,0x4F,0x4F,0x54,0x5F,0x50,0x32,0x35, + 0x36,0x00,0x02,0x01,0x00,0x02,0x01,0x00,0x04,0x14,0x45,0x00,0x43,0x00,0x44,0x00, + 0x53,0x00,0x41,0x00,0x5F,0x00,0x50,0x00,0x32,0x00,0x35,0x00,0x36,0x00,0x04,0x68, + 0x45,0x43,0x53,0x32,0x20,0x00,0x00,0x00,0x85,0x59,0x2A,0x87,0x8E,0x6A,0x9B,0xB9, + 0x19,0xD4,0x73,0x82,0x24,0xC1,0x03,0x15,0xB3,0xF1,0x70,0x88,0x1B,0xAA,0xBA,0x57, + 0xE8,0x76,0x9F,0xC0,0xCE,0xF6,0xA9,0xBB,0x19,0xF5,0x6B,0x09,0x63,0xFB,0x69,0xA1, + 0x3D,0x88,0x67,0x3E,0x7E,0x1F,0x7B,0x18,0xC8,0xF2,0x31,0xE6,0xD7,0x54,0xD5,0xA7, + 0xAA,0x09,0x9C,0x15,0xD1,0x8D,0x37,0x7F,0x61,0x97,0x7D,0x85,0xBF,0x7E,0x4E,0xD5, + 0x70,0x08,0xF2,0xE8,0xB5,0xBC,0x39,0x59,0xB3,0x23,0x97,0x5F,0xD4,0xCB,0x63,0x74, + 0xB9,0x88,0x6D,0xD6,0xF4,0xB8,0x20,0xA8,0x30,0x18,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x03,0x30,0x0D,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, + 0x05,0x00,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x44,0xC4,0xBD,0x7A,0xDE,0x6F,0x41, + 0xA6,0x78,0x82,0xFD,0x32,0xB7,0x55,0xCA,0xE3,0x21,0x01,0x1C,0xD5,0x6A,0x0B,0x19, + 0xA4,0xA9,0x4D,0x06,0x6F,0xB2,0xE8,0xBF,0x9E,0x02,0x20,0x20,0x1C,0x24,0xEA,0x39, + 0x24,0xEB,0x91,0xBE,0x73,0x76,0xAF,0xFC,0x99,0x60,0xEC,0x22,0xFD,0x43,0xBF,0xDA, + 0xF3,0x7F,0xE4,0x8E,0x6C,0xA5,0x46,0xBF,0x64,0x01,0x3D, +}; + +/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */ +/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */ +unsigned char secp256r1ca_cer[825]={ + 0x30,0x82,0x03,0x35,0x30,0x82,0x02,0xDD,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xC5,0x80,0x5F,0x51,0x16,0xE3,0xA8,0x04,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, + 0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41, + 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,0x26,0x30,0x24,0x06,0x03,0x55,0x04, + 0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74, + 0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73, + 0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20, + 0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22, + 0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, + 0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, + 0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39, + 0x35,0x33,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35, + 0x33,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, + 0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A, + 0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65, + 0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31, + 0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43, + 0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30, + 0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65, + 0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,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,0xDC,0xC0,0x0F,0x8D, + 0xF5,0xED,0x3E,0x9B,0x6F,0x5A,0x22,0xA3,0x52,0x76,0x6B,0x0B,0xB2,0x6F,0x6C,0x12, + 0x17,0xBA,0x24,0xB8,0x7C,0x1B,0x16,0x17,0xD3,0xB9,0x78,0x2F,0x2E,0xC4,0x1C,0x01, + 0x68,0x77,0xE0,0xC7,0x79,0x48,0x9E,0xF5,0xD6,0xB3,0x7B,0x6A,0x7F,0xAC,0x12,0xBD, + 0x11,0x57,0x21,0x3A,0x87,0xAC,0xE0,0x42,0x40,0xFC,0x0D,0x4C,0xA3,0x82,0x01,0x05, + 0x30,0x82,0x01,0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x48, + 0xF7,0xD9,0x0A,0x7A,0x90,0xA1,0xD1,0x60,0xE9,0x89,0x41,0xC9,0x20,0x42,0xB2,0xB8, + 0xD0,0xEE,0x16,0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xC9,0x30,0x81, + 0xC6,0x80,0x14,0x48,0xF7,0xD9,0x0A,0x7A,0x90,0xA1,0xD1,0x60,0xE9,0x89,0x41,0xC9, + 0x20,0x42,0xB2,0xB8,0xD0,0xEE,0x16,0xA1,0x81,0xA2,0xA4,0x81,0x9F,0x30,0x81,0x9C, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, + 0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, + 0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,0x03, + 0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,0x65, + 0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,0x6E, + 0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,0x09,0x00,0xC5, + 0x80,0x5F,0x51,0x16,0xE3,0xA8,0x04,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05, + 0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, + 0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x79,0x72,0xE8,0x77,0xD2,0xBB,0x03,0x75,0x46, + 0x47,0x0F,0xF7,0xC0,0xC5,0xEB,0x9F,0x13,0x54,0x03,0xE2,0xB8,0xCB,0x37,0xC0,0x7F, + 0x53,0xA5,0x0B,0x2F,0x3D,0xDB,0x79,0x02,0x20,0x6A,0xAE,0xDF,0xEF,0x41,0xE6,0x56, + 0x60,0x1D,0x6B,0xC7,0x89,0x60,0x64,0x8E,0x99,0x01,0xA9,0xE8,0x01,0xA7,0x9B,0x75, + 0xED,0x8C,0x95,0xE0,0xAD,0x40,0x2F,0x17,0x07, +}; +/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp256r1server-secp256r1ca)/CN=dev.experimentalstuff.com */ +/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp256r1)/CN=dev.experimentalstuff.com */ +unsigned char secp256r1server_secp256r1ca_cer[578]={ + 0x30,0x82,0x02,0x3E,0x30,0x82,0x01,0xE5,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73, + 0xB5,0xC2,0x3A,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81, + 0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75, + 0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C, + 0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06, + 0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73, + 0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65, + 0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17, + 0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x31,0x35,0x5A,0x17,0x0D, + 0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x31,0x35,0x5A,0x30,0x81,0xB2, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, + 0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, + 0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03, + 0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72, + 0x20,0x28,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x73,0x65,0x72,0x76,0x65, + 0x72,0x2D,0x73,0x65,0x63,0x70,0x32,0x35,0x36,0x72,0x31,0x63,0x61,0x29,0x31,0x22, + 0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, + 0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,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,0x47,0x09,0x8C, + 0x61,0x41,0xD7,0xA6,0x9F,0x4B,0x7D,0xB0,0xE6,0x93,0x7D,0xF2,0x58,0xE8,0xC0,0x7F, + 0xD7,0xE5,0xCF,0x8D,0xC8,0x1E,0xA1,0x6A,0xDB,0x16,0xBA,0x6D,0xCC,0xEF,0x72,0x1B, + 0x7B,0x64,0x39,0x1A,0xED,0x49,0x92,0x39,0x54,0x3C,0x03,0xC7,0x76,0x15,0xD8,0xC6, + 0x06,0x5A,0x80,0x9C,0x42,0xAF,0x08,0x79,0x71,0xAB,0x0E,0x35,0x4A,0x30,0x09,0x06, + 0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x7F, + 0xBE,0x32,0x64,0x5A,0x63,0xB2,0x21,0xC9,0x27,0x22,0xE8,0x71,0x9F,0xB0,0x00,0x83, + 0xA2,0xD9,0x43,0x0E,0xDE,0xA4,0xBE,0x92,0x4E,0x09,0x35,0xD0,0x4B,0x41,0xBC,0x02, + 0x21,0x00,0xC0,0xD0,0x3E,0xE3,0xFC,0x15,0x78,0x4B,0xED,0x8D,0xE9,0xDD,0x80,0xB5, + 0xFB,0x89,0xC3,0x4A,0xDF,0x72,0xF9,0xDD,0xF2,0xBD,0x0A,0xA8,0x99,0xA2,0xF7,0xE2, + 0xC3,0xBA, +}; +/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */ +/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */ +unsigned char secp384r1ca_cer[887]={ + 0x30,0x82,0x03,0x73,0x30,0x82,0x02,0xFA,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xC2,0xA9,0x40,0xC7,0xF5,0x21,0x4A,0x02,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, + 0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41, + 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,0x26,0x30,0x24,0x06,0x03,0x55,0x04, + 0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74, + 0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73, + 0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20, + 0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22, + 0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, + 0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, + 0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39, + 0x35,0x34,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35, + 0x34,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, + 0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A, + 0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65, + 0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31, + 0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43, + 0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30, + 0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65, + 0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F, + 0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05, + 0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xC6,0x97,0x31,0x8C,0x95,0x62,0x93, + 0x7A,0x41,0x67,0xBE,0xE5,0x3A,0x53,0x37,0xCA,0xFD,0x8D,0xB0,0x0F,0x50,0x43,0xBF, + 0x62,0xE4,0x76,0xDC,0x73,0x97,0xE4,0xAA,0xB5,0x6C,0xFD,0x06,0xA0,0x5F,0x7A,0xB9, + 0x7C,0x79,0xDD,0x7D,0x15,0xD0,0x43,0xA7,0x71,0xFF,0xE7,0x6A,0xF4,0xDD,0xF5,0xEE, + 0xE8,0x17,0x80,0x4E,0x82,0x40,0xAC,0x1D,0xED,0x1B,0x0F,0x6A,0x7C,0x6F,0xCD,0x88, + 0x21,0xB4,0x3D,0xE7,0x72,0xB7,0x0C,0x34,0xFA,0x78,0x85,0xB8,0x4D,0x71,0x7B,0x62, + 0xF4,0xBF,0xC4,0x5F,0x41,0xC8,0x8C,0x7F,0x89,0xA3,0x82,0x01,0x05,0x30,0x82,0x01, + 0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xEA,0xCB,0x02,0x59, + 0x57,0xA6,0xC2,0x49,0xE3,0xA7,0x49,0x0D,0xEB,0x88,0x33,0x34,0x4C,0x37,0xC8,0x31, + 0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81,0xC9,0x30,0x81,0xC6,0x80,0x14, + 0xEA,0xCB,0x02,0x59,0x57,0xA6,0xC2,0x49,0xE3,0xA7,0x49,0x0D,0xEB,0x88,0x33,0x34, + 0x4C,0x37,0xC8,0x31,0xA1,0x81,0xA2,0xA4,0x81,0x9F,0x30,0x81,0x9C,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03, + 0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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, + 0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69, + 0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72, + 0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B, + 0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x33, + 0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19, + 0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C, + 0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82,0x09,0x00,0xC2,0xA9,0x40,0xC7, + 0xF5,0x21,0x4A,0x02,0x30,0x0C,0x06,0x03,0x55,0x1D,0x13,0x04,0x05,0x30,0x03,0x01, + 0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x68,0x00, + 0x30,0x65,0x02,0x30,0x5B,0xF0,0x3E,0xD4,0xF0,0xE8,0xAA,0x3B,0xC6,0x54,0xF6,0x05, + 0x2B,0x90,0xCA,0x34,0x63,0x6D,0xC0,0x37,0x9F,0x28,0xDD,0x34,0x9A,0xA5,0x18,0x1E, + 0xEE,0xA8,0x80,0xB9,0x43,0x95,0xAD,0xA5,0xA2,0xA0,0xDA,0xEB,0x35,0x5A,0x42,0xDB, + 0x3D,0x98,0x23,0x66,0x02,0x31,0x00,0xB9,0xDD,0xB2,0x90,0xBE,0x5A,0x88,0x43,0xE1, + 0x9B,0x18,0xC6,0x3A,0x0B,0x9B,0xFE,0x17,0xFC,0xC4,0x4A,0x65,0x62,0x7B,0x4E,0xAF, + 0x6D,0xAE,0xEA,0x7B,0x6B,0xC8,0x97,0xA3,0x88,0x06,0x23,0xCE,0x3F,0x97,0x39,0x80, + 0x28,0xF8,0x36,0x3D,0x60,0xDE,0xE2, +}; +/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp384r1server-secp384r1ca)/CN=dev.experimentalstuff.com */ +/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp384r1)/CN=dev.experimentalstuff.com */ +unsigned char secp384r1server_secp384r1ca_cer[640]={ + 0x30,0x82,0x02,0x7C,0x30,0x82,0x02,0x02,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73, + 0xB5,0xC2,0x43,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81, + 0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75, + 0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C, + 0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06, + 0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73, + 0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65, + 0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17, + 0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x32,0x32,0x5A,0x17,0x0D, + 0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x32,0x32,0x5A,0x30,0x81,0xB2, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, + 0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, + 0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03, + 0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72, + 0x20,0x28,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x73,0x65,0x72,0x76,0x65, + 0x72,0x2D,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x63,0x61,0x29,0x31,0x22, + 0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, + 0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, + 0x6F,0x6D,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06, + 0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x2E,0xB6,0x93,0xC0,0x46,0xD0, + 0xAD,0x39,0x38,0xD2,0x75,0x3B,0xE8,0x8F,0xCC,0x51,0x6B,0xC3,0xAD,0x7E,0x07,0x12, + 0x19,0xCD,0xB7,0x65,0xA8,0xAF,0x9D,0x33,0xCC,0x7A,0x4D,0xB5,0xC5,0xA5,0x0E,0x1E, + 0xB8,0xC7,0x20,0xC8,0x50,0xEE,0x88,0x83,0x03,0xEE,0x99,0x8F,0x77,0x3C,0xC5,0x11, + 0x13,0x63,0x9B,0x13,0x0D,0x73,0x9B,0x68,0xCB,0xC7,0xE9,0x5D,0xDF,0x60,0x87,0x66, + 0x15,0x43,0xDC,0xD1,0x60,0xD5,0xEC,0x94,0xCF,0x15,0x16,0x5E,0x59,0xD5,0xE5,0x8C, + 0x8C,0x42,0x0E,0x24,0x33,0xE4,0x38,0x45,0xF4,0xA8,0x30,0x09,0x06,0x07,0x2A,0x86, + 0x48,0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0x9A,0x76,0xDA, + 0xF6,0x4A,0x3C,0xEF,0xC5,0x7A,0xD9,0x6A,0xC0,0xB2,0x1C,0x82,0x1A,0xA8,0xCB,0x4A, + 0xEE,0x78,0x2B,0x24,0x15,0x00,0xB9,0xDD,0xF8,0x54,0xD3,0x30,0x32,0x6D,0x38,0x88, + 0xCC,0x32,0xF3,0x33,0x70,0x30,0xC3,0x02,0x23,0x1C,0x72,0x2F,0x39,0x02,0x31,0x00, + 0xBC,0xA5,0x79,0xA7,0xDA,0xAB,0x3F,0x94,0x87,0x5D,0x16,0x5A,0x78,0x5E,0x9D,0x9E, + 0x30,0x11,0xC1,0xAD,0x9E,0xF3,0x2A,0xEC,0xD3,0x8B,0x03,0x6E,0x83,0xB6,0xD0,0x6A, + 0x1D,0xD6,0xB8,0x50,0x99,0xC1,0x91,0x11,0x41,0xA3,0x9F,0x8D,0xD2,0x6F,0xA5,0xE9, +}; +/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */ +/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */ +unsigned char secp521r1ca_cer[962]={ + 0x30,0x82,0x03,0xBE,0x30,0x82,0x03,0x20,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xD1,0x2B,0x56,0x0F,0xA8,0x93,0xA8,0x80,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x01,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13, + 0x02,0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41, + 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,0x26,0x30,0x24,0x06,0x03,0x55,0x04, + 0x0A,0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74, + 0x65,0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73, + 0x31,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20, + 0x43,0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22, + 0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, + 0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, + 0x6F,0x6D,0x30,0x1E,0x17,0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x32,0x39, + 0x35,0x35,0x5A,0x17,0x0D,0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x32,0x39,0x35, + 0x35,0x5A,0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, + 0x55,0x53,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A, + 0x0C,0x1D,0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65, + 0x6D,0x73,0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31, + 0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43, + 0x41,0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30, + 0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65, + 0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F, + 0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06, + 0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0x33,0x52,0x71,0xF2, + 0x20,0x84,0x86,0x46,0x37,0x54,0xC8,0xF4,0x0E,0xA2,0x33,0xC1,0x7E,0x2E,0xB0,0x20, + 0xC6,0xB2,0x27,0x73,0xB9,0xE6,0x28,0x80,0x6D,0x75,0x86,0x1F,0xB0,0x55,0xB0,0x4F, + 0x83,0xFA,0x6D,0x0A,0x8D,0xAC,0xE6,0x62,0xC6,0xB4,0xA6,0x4E,0x26,0x57,0x48,0x65, + 0xA1,0xCD,0xA8,0xFE,0x80,0x60,0x1D,0x17,0xCB,0xDF,0xAF,0xCD,0x58,0x01,0x53,0x5E, + 0xD6,0x19,0x2E,0x3F,0x78,0x82,0xFF,0x88,0x9A,0x46,0x4F,0x6F,0xC8,0xC0,0xC7,0x36, + 0xF2,0x83,0x1D,0x07,0x94,0xC4,0x53,0x48,0x2F,0x65,0x13,0x01,0xF4,0x93,0x97,0x4B, + 0xD8,0x98,0xBD,0x42,0xE4,0xA9,0x29,0x61,0x4D,0xFE,0xA8,0x15,0x45,0x4C,0xBA,0x5A, + 0xEE,0xE2,0x26,0x93,0x5B,0x37,0xC1,0x02,0x24,0x4D,0x31,0xF2,0x14,0xB2,0xCC,0xA3, + 0x82,0x01,0x05,0x30,0x82,0x01,0x01,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, + 0x04,0x14,0x0C,0x0F,0xD9,0xE6,0x4E,0x8C,0x8A,0xBA,0x17,0xCE,0xCF,0xB1,0x28,0xE9, + 0xAA,0x78,0x91,0xCF,0x16,0x69,0x30,0x81,0xD1,0x06,0x03,0x55,0x1D,0x23,0x04,0x81, + 0xC9,0x30,0x81,0xC6,0x80,0x14,0x0C,0x0F,0xD9,0xE6,0x4E,0x8C,0x8A,0xBA,0x17,0xCE, + 0xCF,0xB1,0x28,0xE9,0xAA,0x78,0x91,0xCF,0x16,0x69,0xA1,0x81,0xA2,0xA4,0x81,0x9F, + 0x30,0x81,0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D, + 0x53,0x75,0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73, + 0x20,0x4C,0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30, + 0x1A,0x06,0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20, + 0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69, + 0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x82, + 0x09,0x00,0xD1,0x2B,0x56,0x0F,0xA8,0x93,0xA8,0x80,0x30,0x0C,0x06,0x03,0x55,0x1D, + 0x13,0x04,0x05,0x30,0x03,0x01,0x01,0xFF,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x01,0x03,0x81,0x8C,0x00,0x30,0x81,0x88,0x02,0x42,0x01,0x80,0xFF,0x46, + 0x4F,0x45,0x30,0xF9,0x34,0x67,0x33,0x6B,0x5C,0x21,0xCA,0x45,0xD5,0xE4,0x8C,0x1A, + 0x9F,0xB2,0x80,0x79,0x55,0x84,0x63,0x14,0x84,0x27,0x23,0x3F,0x3E,0xC4,0x40,0x02, + 0x2A,0xA1,0xE3,0x76,0x66,0x1D,0xE1,0xD8,0xD1,0xEA,0x5E,0x8D,0x03,0x8A,0x25,0x29, + 0x09,0xFE,0x2D,0x4C,0x04,0xDA,0x19,0xAD,0xA2,0x6E,0xAB,0x7A,0xCD,0x86,0x02,0x42, + 0x01,0x3C,0x39,0x41,0x73,0x01,0xB3,0xA0,0x3C,0x54,0xE0,0x24,0x10,0x6F,0xFA,0xCF, + 0x70,0x51,0x0C,0x68,0x0E,0x48,0xE1,0xFA,0x46,0x75,0x23,0x58,0xB4,0x82,0x43,0x91, + 0x73,0x65,0xB9,0x51,0xC0,0x3E,0x4B,0xFE,0xB8,0xAF,0x65,0xAE,0x1B,0x23,0xBA,0xFA, + 0x55,0x6E,0x1E,0xFA,0xFA,0x63,0x37,0x07,0xD6,0xE0,0xE1,0x3A,0xBA,0xF8,0xFC,0x5B, + 0x28,0xDD, +}; +/* subject:/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test Server (secp521r1server-secp521r1ca)/CN=dev.experimentalstuff.com */ +/* issuer :/C=US/ST=CA/L=Mountain View/O=Sun Microsystems Laboratories/OU=Test CA (secp521r1)/CN=dev.experimentalstuff.com */ +unsigned char secp521r1server_secp521r1ca_cer[714]={ + 0x30,0x82,0x02,0xC6,0x30,0x82,0x02,0x28,0x02,0x09,0x00,0xA0,0xDD,0x4F,0x0C,0x73, + 0xB5,0xC2,0x4C,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30,0x81, + 0x9C,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B, + 0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75, + 0x6E,0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C, + 0x61,0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x1C,0x30,0x1A,0x06, + 0x03,0x55,0x04,0x0B,0x0C,0x13,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x20,0x28,0x73, + 0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x29,0x31,0x22,0x30,0x20,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70,0x65,0x72,0x69,0x6D,0x65, + 0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63,0x6F,0x6D,0x30,0x1E,0x17, + 0x0D,0x30,0x35,0x31,0x32,0x30,0x36,0x32,0x31,0x33,0x30,0x33,0x30,0x5A,0x17,0x0D, + 0x31,0x30,0x30,0x31,0x31,0x34,0x32,0x31,0x33,0x30,0x33,0x30,0x5A,0x30,0x81,0xB2, + 0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x0B,0x30, + 0x09,0x06,0x03,0x55,0x04,0x08,0x0C,0x02,0x43,0x41,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,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0A,0x0C,0x1D,0x53,0x75,0x6E, + 0x20,0x4D,0x69,0x63,0x72,0x6F,0x73,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x4C,0x61, + 0x62,0x6F,0x72,0x61,0x74,0x6F,0x72,0x69,0x65,0x73,0x31,0x32,0x30,0x30,0x06,0x03, + 0x55,0x04,0x0B,0x0C,0x29,0x54,0x65,0x73,0x74,0x20,0x53,0x65,0x72,0x76,0x65,0x72, + 0x20,0x28,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x73,0x65,0x72,0x76,0x65, + 0x72,0x2D,0x73,0x65,0x63,0x70,0x35,0x32,0x31,0x72,0x31,0x63,0x61,0x29,0x31,0x22, + 0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x64,0x65,0x76,0x2E,0x65,0x78,0x70, + 0x65,0x72,0x69,0x6D,0x65,0x6E,0x74,0x61,0x6C,0x73,0x74,0x75,0x66,0x66,0x2E,0x63, + 0x6F,0x6D,0x30,0x81,0x9B,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, + 0x06,0x05,0x2B,0x81,0x04,0x00,0x23,0x03,0x81,0x86,0x00,0x04,0x00,0xC9,0x8F,0xA5, + 0x49,0x40,0x30,0x24,0x4E,0x61,0x3C,0x45,0x02,0xC2,0xE7,0x1C,0x7A,0xB7,0x5F,0xCE, + 0x86,0x4C,0xA7,0x77,0x3D,0x1E,0x4C,0x3F,0x7E,0x7B,0xD5,0x8D,0x0A,0x40,0xD1,0x5B, + 0xDB,0xD2,0x98,0x81,0x27,0x7F,0x4C,0x44,0x21,0x98,0x8B,0xAD,0xD1,0x6D,0xA4,0x6C, + 0x41,0xEC,0x66,0x52,0xAD,0xD7,0x19,0xD6,0xCB,0xF2,0x6C,0x28,0x57,0x46,0x01,0xE6, + 0x78,0x8E,0x67,0xD7,0x20,0xE9,0x87,0xAA,0x5D,0x10,0x27,0x91,0xC4,0xBF,0x19,0xBA, + 0x07,0x36,0x3B,0x58,0x41,0x6C,0xAC,0xB5,0xAF,0x83,0xF9,0xD7,0xD7,0xF1,0x2D,0x60, + 0x60,0x1B,0x97,0x74,0xD6,0x6B,0x6C,0x67,0x40,0x8F,0xD5,0x0F,0xEF,0xE8,0x33,0xFF, + 0xD5,0xAB,0x3C,0xE7,0x2D,0xCF,0xA8,0x30,0xC9,0xE8,0x8A,0x2C,0xAB,0x2F,0xA2,0xC3, + 0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x81,0x8C,0x00,0x30, + 0x81,0x88,0x02,0x42,0x01,0x2B,0xC4,0xEB,0xEA,0xCE,0xB4,0xED,0xE5,0xE1,0xEB,0x74, + 0x7E,0x19,0xC5,0x49,0xF8,0x00,0xCF,0x5D,0x04,0x0A,0x97,0xDF,0x78,0xCA,0x5C,0x12, + 0x8D,0xB9,0x18,0x26,0xC9,0x82,0x31,0xA0,0x83,0xB6,0x73,0x6B,0x6A,0x91,0xDC,0x42, + 0xAD,0x79,0x9E,0xB9,0xD1,0x59,0x98,0x51,0x84,0x10,0x1A,0x2B,0xE5,0xB8,0x36,0x44, + 0xC2,0x3A,0xA6,0x47,0x28,0x5B,0x02,0x42,0x01,0xEE,0x93,0x23,0x1D,0x0A,0x71,0xA1, + 0x7A,0x0F,0x5C,0x16,0xF6,0xD9,0x66,0x45,0x76,0x7E,0xF3,0xCF,0x12,0x4B,0xA1,0x6A, + 0x05,0xD5,0x70,0x9F,0x86,0xBC,0xFF,0xA4,0xEB,0x4F,0x14,0x06,0x98,0x30,0xFA,0xA9, + 0x54,0xF0,0x19,0xCA,0x3B,0xEA,0xE9,0xA3,0x1E,0x76,0xA6,0xE7,0x42,0x9C,0xBE,0x0E, + 0xA2,0x04,0x08,0xDF,0x49,0x49,0xB0,0x8F,0xFE,0x7A, +}; + +#endif /* _TRUSTTESTS_EVALUATION_EC_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/EvaluationBasicTests.m b/tests/TrustTests/EvaluationTests/EvaluationBasicTests.m new file mode 100644 index 00000000..d6f1b197 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/EvaluationBasicTests.m @@ -0,0 +1,174 @@ +/* + * 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 +#include "OSX/utilities/array_size.h" +#include "OSX/utilities/SecCFWrappers.h" + +#import "TrustEvaluationTestCase.h" +#include "../TestMacroConversions.h" +#include "EvaluationBasicTests_data.h" + +@interface EvaluationBasicTests : TrustEvaluationTestCase +@end + +@implementation EvaluationBasicTests + +- (void)testOptionalPolicyCheck { + SecCertificateRef cert0 = NULL, cert1 = NULL, root = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = NULL; + CFArrayRef certs = NULL, anchors = NULL; + CFDateRef date = NULL; + + require_action(cert0 = SecCertificateCreateWithBytes(NULL, _eval_expired_badssl, sizeof(_eval_expired_badssl)), errOut, + fail("unable to create cert")); + require_action(cert1 = SecCertificateCreateWithBytes(NULL, _eval_comodo_rsa_dvss, sizeof(_eval_comodo_rsa_dvss)), errOut, + fail("unable to create cert")); + require_action(root = SecCertificateCreateWithBytes(NULL, _eval_comodo_rsa_root, sizeof(_eval_comodo_rsa_root)), errOut, + fail("unable to create cert")); + + const void *v_certs[] = { cert0, cert1 }; + require_action(certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), &kCFTypeArrayCallBacks), errOut, + fail("unable to create array")); + require_action(anchors = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks), errOut, + fail("unable to create anchors array")); + require_action(date = CFDateCreateForGregorianZuluMoment(NULL, 2015, 4, 10, 12, 0, 0), errOut, fail("unable to create date")); + + require_action(policy = SecPolicyCreateBasicX509(), errOut, fail("unable to create policy")); + SecPolicySetOptionsValue(policy, CFSTR("not-a-policy-check"), kCFBooleanTrue); + + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "failed to create trust"); + require_noerr_action(SecTrustSetAnchorCertificates(trust, anchors), errOut, + fail("unable to set anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, date), errOut, fail("unable to set verify date")); + +#if NDEBUG + ok(SecTrustEvaluateWithError(trust, NULL), "Trust evaluation failed"); +#else + is(SecTrustEvaluateWithError(trust, NULL), false, "Expect failure in Debug config"); +#endif + +errOut: + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(root); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(date); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +#if !TARGET_OS_BRIDGE +- (void)testIntermediateFromKeychain { + SecTrustRef trust = NULL; + CFArrayRef certs = NULL; + SecCertificateRef cert0 = NULL, cert1 = NULL, framework_cert1 = NULL; + SecPolicyRef policy = NULL; + CFDateRef date = NULL; + CFDictionaryRef query = NULL; + + /* Apr 14 2018. */ + isnt(date = CFDateCreateForGregorianZuluMoment(NULL, 2018, 4, 14, 12, 0, 0), + NULL, "create verify date"); + if (!date) { goto errOut; } + + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _eval_c0, sizeof(_eval_c0)), + NULL, "create cert0"); + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _eval_c1, sizeof(_eval_c1)), + NULL, "create cert1"); + policy = SecPolicyCreateSSL(false, NULL); + + /* Test cert_1 intermediate from the keychain. */ + ok_status(SecTrustCreateWithCertificates(cert0, policy, &trust), + "create trust with single cert0"); + ok_status(SecTrustSetVerifyDate(trust, date), "set date"); + ok_status(SecTrustSetNetworkFetchAllowed(trust, false), "set no network fetch allowed"); + + // Add cert1 to the keychain + isnt(framework_cert1 = SecFrameworkCertificateCreate(_eval_c1, sizeof(_eval_c1)), + NULL, "create framework cert1"); + query = CFDictionaryCreateForCFTypes(kCFAllocatorDefault, + kSecClass, kSecClassCertificate, + kSecValueRef, framework_cert1, + kSecAttrAccessGroup, CFSTR("com.apple.trusttests"), +#if TARGET_OS_OSX + kSecUseDataProtectionKeychain, kCFBooleanTrue, +#endif + NULL); + ok_status(SecItemAdd(query, NULL), "add cert1 to keychain"); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust and expect success"); + is(SecTrustGetCertificateCount(trust), 3, "cert count is 3"); + + // Cleanup added cert1. + ok_status(SecItemDelete(query), "remove cert1 from keychain"); + CFReleaseNull(query); + CFReleaseNull(framework_cert1); + +errOut: + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(certs); + CFReleaseNull(date); + CFReleaseNull(policy); + CFReleaseNull(trust); +} +#endif /* !TARGET_OS_BRIDGE */ + +- (void)testSelfSignedAnchor { + SecCertificateRef garthc2 = NULL; + CFArrayRef certs = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFDateRef date = NULL; + + isnt(garthc2 = SecCertificateCreateWithBytes(NULL, _selfSignedAnchor, + sizeof(_selfSignedAnchor)), NULL, "create self-signed anchor"); + certs = CFArrayCreate(NULL, (const void **)&garthc2, 1, &kCFTypeArrayCallBacks); + policy = SecPolicyCreateSSL(true, NULL); + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), + "create trust for self-signed anchor"); + date = CFDateCreate(NULL, 578000000.0); // April 26, 2019 at 12:33:20 PM PDT + ok_status(SecTrustSetVerifyDate(trust, date), + "set garthc2 trust date to April 2019"); + ok_status(SecTrustSetAnchorCertificates(trust, certs), + "set garthc2 as anchor"); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), + "evaluate self signed cert with cert as anchor"); + + CFReleaseNull(garthc2); + CFReleaseNull(certs); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(date); +} + +@end diff --git a/tests/TrustTests/EvaluationTests/EvaluationBasicTests_data.h b/tests/TrustTests/EvaluationTests/EvaluationBasicTests_data.h new file mode 100644 index 00000000..9da4d73e --- /dev/null +++ b/tests/TrustTests/EvaluationTests/EvaluationBasicTests_data.h @@ -0,0 +1,611 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_BASIC_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_BASIC_TESTS_H_ + +// MARK: Generic EV SSL Chain + +/* + Serial Number: + 01:f1:eb:db:ee:d3:1d:7a:b5:72:54:7d:34:43:4b:87 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA + Validity + Not Before: Mar 22 00:00:00 2018 GMT + Not After : Mar 23 12:00:00 2019 GMT + Subject: businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=California/serialNumber=C0806592, C=US, ST=California, L=Cupertino, O=Apple Inc., OU=Internet Services for Akamai, CN=store.apple.com + */ +static const uint8_t _eval_c0[] = { + 0x30,0x82,0x06,0xF7,0x30,0x82,0x05,0xDF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, + 0xF1,0xEB,0xDB,0xEE,0xD3,0x1D,0x7A,0xB5,0x72,0x54,0x7D,0x34,0x43,0x4B,0x87,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x75, + 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, + 0x34,0x30,0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64, + 0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76, + 0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x33,0x32,0x32,0x30, + 0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x33,0x32,0x33,0x31,0x32, + 0x30,0x30,0x30,0x30,0x5A,0x30,0x81,0xF0,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04, + 0x0F,0x0C,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72,0x67,0x61,0x6E, + 0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x13,0x30,0x11,0x06,0x0B,0x2B,0x06,0x01, + 0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53,0x31,0x1B,0x30,0x19, + 0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,0x13,0x0A,0x43, + 0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55, + 0x04,0x05,0x13,0x08,0x43,0x30,0x38,0x30,0x36,0x35,0x39,0x32,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70, + 0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B, + 0x13,0x1C,0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x53,0x65,0x72,0x76,0x69, + 0x63,0x65,0x73,0x20,0x66,0x6F,0x72,0x20,0x41,0x6B,0x61,0x6D,0x61,0x69,0x31,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x13,0x0F,0x73,0x74,0x6F,0x72,0x65,0x2E,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,0xB5,0xDF,0x48,0x6A,0xE5,0x5F,0x0C, + 0x42,0xBF,0x71,0x07,0xAB,0xE6,0x48,0xD2,0x2C,0x13,0x7C,0x29,0xF7,0x90,0xC2,0x45, + 0x39,0x43,0x48,0x2E,0x16,0x22,0xBF,0xAB,0x48,0x20,0x14,0x27,0xE7,0x87,0x52,0x97, + 0xF6,0x64,0x0C,0x62,0xF5,0x39,0x54,0x64,0x09,0xE8,0x29,0x56,0xF4,0x03,0x40,0x5A, + 0xFA,0x9A,0x11,0x2B,0xD0,0x01,0x51,0x1E,0xED,0xB8,0x51,0xCB,0xAB,0x6B,0x7A,0x99, + 0xF3,0xB0,0x6E,0xA8,0xC4,0xB6,0xAF,0x17,0xEC,0xA6,0xD2,0x4D,0xCA,0x63,0x3D,0x59, + 0x30,0x25,0x30,0x54,0x86,0xDB,0x70,0x7A,0xEC,0x07,0x83,0x19,0xA0,0x44,0xE7,0x3C, + 0x68,0xE0,0xFD,0xB9,0xEE,0x3F,0xAC,0xF3,0x32,0x5A,0x5F,0x42,0x31,0x94,0x70,0x2C, + 0xC5,0x73,0xD2,0x79,0x23,0x5B,0x96,0x45,0xB1,0xB3,0x2A,0xA1,0x5A,0x69,0xFE,0xBE, + 0x52,0x0D,0x5D,0x79,0x18,0xCA,0xF1,0x44,0x92,0xA0,0x27,0x1F,0xAA,0x6E,0x9D,0x6F, + 0x1B,0x83,0x5B,0x73,0x28,0x1D,0x87,0xB5,0x70,0x0E,0x3D,0xED,0xE2,0xC2,0x34,0x8A, + 0x81,0xB2,0x22,0x40,0x98,0x77,0x2F,0x34,0x1B,0x70,0xEC,0x96,0x3F,0x91,0xB9,0xFF, + 0xC9,0xE5,0x7E,0xE7,0x25,0xEF,0xDB,0x9A,0x58,0x4E,0xB2,0x92,0x19,0xA5,0x8D,0xEB, + 0x76,0xF8,0xA8,0x48,0x9F,0x3D,0x10,0x0C,0xE4,0x69,0x7B,0xE7,0xB7,0xCA,0xF6,0x14, + 0x5E,0x93,0x1E,0x20,0x37,0x1B,0xB8,0xB1,0x2C,0xD1,0x46,0x5C,0xD7,0x85,0x4A,0x2E, + 0x19,0xB2,0x3C,0x31,0xDC,0x3D,0xB5,0x3C,0xEC,0x49,0x8D,0x9C,0xCF,0x75,0x0B,0xFC, + 0x03,0x31,0x37,0xE7,0xA5,0xD6,0x9D,0x19,0x0D,0x02,0x03,0x01,0x00,0x01,0xA3,0x82, + 0x03,0x05,0x30,0x82,0x03,0x01,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, + 0x16,0x80,0x14,0x3D,0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65, + 0xD3,0x21,0xD4,0xF8,0xF8,0xD6,0x0F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, + 0x04,0x14,0x6F,0x89,0xAE,0x9B,0xE4,0x8A,0x21,0x3A,0x3B,0xEA,0xAA,0xBE,0x99,0x90, + 0xC8,0xDB,0x34,0x80,0x21,0xB9,0x30,0x2F,0x06,0x03,0x55,0x1D,0x11,0x04,0x28,0x30, + 0x26,0x82,0x0F,0x73,0x74,0x6F,0x72,0x65,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63, + 0x6F,0x6D,0x82,0x13,0x77,0x77,0x77,0x2E,0x73,0x74,0x6F,0x72,0x65,0x2E,0x61,0x70, + 0x70,0x6C,0x65,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,0x75,0x06,0x03,0x55,0x1D,0x1F,0x04,0x6E,0x30, + 0x6C,0x30,0x34,0xA0,0x32,0xA0,0x30,0x86,0x2E,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,0x68,0x61,0x32,0x2D,0x65,0x76,0x2D,0x73,0x65,0x72,0x76,0x65,0x72, + 0x2D,0x67,0x32,0x2E,0x63,0x72,0x6C,0x30,0x34,0xA0,0x32,0xA0,0x30,0x86,0x2E,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,0x68,0x61,0x32,0x2D,0x65,0x76,0x2D, + 0x73,0x65,0x72,0x76,0x65,0x72,0x2D,0x67,0x32,0x2E,0x63,0x72,0x6C,0x30,0x4B,0x06, + 0x03,0x55,0x1D,0x20,0x04,0x44,0x30,0x42,0x30,0x37,0x06,0x09,0x60,0x86,0x48,0x01, + 0x86,0xFD,0x6C,0x02,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,0x07,0x06,0x05,0x67,0x81,0x0C,0x01,0x01,0x30,0x81,0x88,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x7C,0x30,0x7A,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,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x46,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,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x56, + 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x53,0x65,0x72,0x76,0x65,0x72,0x43, + 0x41,0x2E,0x63,0x72,0x74,0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00, + 0x30,0x82,0x01,0x03,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02, + 0x04,0x81,0xF4,0x04,0x81,0xF1,0x00,0xEF,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,0x62,0x4E, + 0xBC,0xC7,0x43,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x3E,0xD3,0xFE, + 0xB4,0x45,0x97,0xCE,0xA3,0x05,0xC9,0x29,0x70,0x55,0x3B,0x77,0x9E,0xCC,0x4B,0x06, + 0xFD,0x76,0x21,0xD0,0x79,0x69,0xD6,0x60,0x01,0xBB,0xC7,0x43,0x5E,0x02,0x20,0x3D, + 0xB7,0x73,0x91,0x51,0xB7,0xAC,0x40,0xFB,0xA7,0x36,0xCF,0x10,0xE8,0x63,0x79,0xE6, + 0x06,0xEC,0xFA,0x60,0xFE,0x44,0x90,0x9A,0x53,0x26,0x04,0x27,0x1A,0x4B,0xD4,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,0x62,0x4E,0xBC,0xC8,0x6A,0x00,0x00,0x04,0x03,0x00,0x47, + 0x30,0x45,0x02,0x20,0x18,0xF4,0x40,0x99,0x83,0xA7,0x53,0x6D,0x11,0xBF,0x7C,0xA5, + 0x64,0x21,0x52,0xD0,0x7C,0xF5,0x96,0xCD,0xB0,0x56,0xAE,0x1E,0x13,0x9C,0xFC,0x08, + 0x3B,0x56,0x66,0x0F,0x02,0x21,0x00,0x98,0xBE,0xC7,0x01,0x8E,0x88,0xB7,0xB2,0xF9, + 0xC7,0xE6,0x08,0x46,0x10,0xEA,0x8D,0x01,0x12,0x0D,0x7D,0xA6,0xBA,0xA6,0xD3,0x1F, + 0xEC,0xA3,0xD6,0x7A,0xE4,0x85,0x89,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6A,0x52,0xE8,0xB3,0x70, + 0x25,0xD9,0x95,0x87,0xC4,0xF3,0x14,0xB1,0x8C,0x29,0x6F,0x11,0xA0,0x6D,0xD7,0xE9, + 0x96,0xFA,0x06,0x57,0x4D,0x86,0xE8,0xD6,0x95,0xC0,0x3A,0x33,0xEC,0x67,0x6C,0x98, + 0xA2,0x99,0x09,0x28,0x16,0x18,0xEC,0x21,0xED,0x93,0xEF,0xAB,0x69,0x5F,0x98,0x9C, + 0x62,0x21,0x10,0xEB,0x1C,0xC4,0x20,0x5E,0x3E,0x6F,0x80,0x03,0xC9,0xC5,0xD5,0x2F, + 0xDA,0x8C,0x86,0x40,0x59,0x71,0x34,0xEE,0xCF,0x54,0x83,0xE1,0x3E,0x11,0x1D,0x12, + 0x66,0x3D,0x16,0x7F,0xD8,0x1B,0x42,0x35,0x50,0xA6,0xD6,0xE6,0x6B,0x32,0xDE,0xE2, + 0xD9,0x01,0xD7,0xB1,0xF5,0xE8,0x72,0x44,0x03,0xB5,0xFA,0x19,0x0D,0xF2,0x8D,0x0B, + 0x75,0xBA,0xD9,0x39,0xFF,0x73,0xF2,0xA0,0xD6,0x49,0xEF,0x9E,0xE9,0x23,0x5D,0xED, + 0xC5,0x08,0x69,0x10,0xF7,0xF0,0x0B,0x8D,0x80,0xB6,0x43,0xE4,0x2A,0xEC,0x92,0xCF, + 0x22,0xCA,0xAF,0x1A,0x8A,0x16,0xC7,0xC5,0x88,0xB7,0xCA,0xC6,0x19,0x1A,0xD1,0xFF, + 0x13,0x93,0x56,0x29,0x1A,0x48,0xA8,0x92,0x21,0xE5,0x7F,0x3E,0x4C,0xB4,0x89,0xD6, + 0x08,0xF0,0xB0,0x4B,0x22,0x7C,0x1F,0xEC,0xE7,0x09,0x5D,0x23,0xE2,0xD1,0xB8,0xA3, + 0xDF,0xEC,0x2D,0x87,0x1F,0xCD,0x58,0x1C,0xDD,0x09,0xE8,0xB5,0xD4,0x30,0x1E,0x2A, + 0x4D,0xA3,0xA1,0x84,0x43,0xD7,0x4A,0x7B,0x15,0x8E,0xEB,0xE2,0x53,0x2B,0x12,0xCB, + 0xFB,0xF2,0x61,0x7E,0x92,0x0B,0x87,0x07,0x1C,0x8D,0x0A,0xED,0x62,0x10,0x27,0xE3, + 0xDB,0xC4,0x65,0xDE,0x57,0xFB,0x6D,0x49,0xC8,0x7A,0xF8, +}; + +/* + Serial Number: + 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA + Validity + Not Before: Oct 22 12:00:00 2013 GMT + Not After : Oct 22 12:00:00 2028 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA + */ +static const uint8_t _eval_c1[] = { + 0x30,0x82,0x04,0xB6,0x30,0x82,0x03,0x9E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0C, + 0x79,0xA9,0x44,0xB0,0x8C,0x11,0x95,0x20,0x92,0x61,0x5F,0xE2,0x6B,0x1D,0x83,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x6C, + 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, + 0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63, + 0x65,0x20,0x45,0x56,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x33,0x31,0x30,0x32,0x32,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32, + 0x38,0x31,0x30,0x32,0x32,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x75,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,0x34,0x30, + 0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56, + 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,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,0xD7,0x53,0xA4,0x04,0x51,0xF8,0x99,0xA6,0x16,0x48,0x4B,0x67, + 0x27,0xAA,0x93,0x49,0xD0,0x39,0xED,0x0C,0xB0,0xB0,0x00,0x87,0xF1,0x67,0x28,0x86, + 0x85,0x8C,0x8E,0x63,0xDA,0xBC,0xB1,0x40,0x38,0xE2,0xD3,0xF5,0xEC,0xA5,0x05,0x18, + 0xB8,0x3D,0x3E,0xC5,0x99,0x17,0x32,0xEC,0x18,0x8C,0xFA,0xF1,0x0C,0xA6,0x64,0x21, + 0x85,0xCB,0x07,0x10,0x34,0xB0,0x52,0x88,0x2B,0x1F,0x68,0x9B,0xD2,0xB1,0x8F,0x12, + 0xB0,0xB3,0xD2,0xE7,0x88,0x1F,0x1F,0xEF,0x38,0x77,0x54,0x53,0x5F,0x80,0x79,0x3F, + 0x2E,0x1A,0xAA,0xA8,0x1E,0x4B,0x2B,0x0D,0xAB,0xB7,0x63,0xB9,0x35,0xB7,0x7D,0x14, + 0xBC,0x59,0x4B,0xDF,0x51,0x4A,0xD2,0xA1,0xE2,0x0C,0xE2,0x90,0x82,0x87,0x6A,0xAE, + 0xEA,0xD7,0x64,0xD6,0x98,0x55,0xE8,0xFD,0xAF,0x1A,0x50,0x6C,0x54,0xBC,0x11,0xF2, + 0xFD,0x4A,0xF2,0x9D,0xBB,0x7F,0x0E,0xF4,0xD5,0xBE,0x8E,0x16,0x89,0x12,0x55,0xD8, + 0xC0,0x71,0x34,0xEE,0xF6,0xDC,0x2D,0xEC,0xC4,0x87,0x25,0x86,0x8D,0xD8,0x21,0xE4, + 0xB0,0x4D,0x0C,0x89,0xDC,0x39,0x26,0x17,0xDD,0xF6,0xD7,0x94,0x85,0xD8,0x04,0x21, + 0x70,0x9D,0x6F,0x6F,0xFF,0x5C,0xBA,0x19,0xE1,0x45,0xCB,0x56,0x57,0x28,0x7E,0x1C, + 0x0D,0x41,0x57,0xAA,0xB7,0xB8,0x27,0xBB,0xB1,0xE4,0xFA,0x2A,0xEF,0x21,0x23,0x75, + 0x1A,0xAD,0x2D,0x9B,0x86,0x35,0x8C,0x9C,0x77,0xB5,0x73,0xAD,0xD8,0x94,0x2D,0xE4, + 0xF3,0x0C,0x9D,0xEE,0xC1,0x4E,0x62,0x7E,0x17,0xC0,0x71,0x9E,0x2C,0xDE,0xF1,0xF9, + 0x10,0x28,0x19,0x33,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x49,0x30,0x82,0x01, + 0x45,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,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,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,0x4B,0x06,0x03,0x55,0x1D, + 0x1F,0x04,0x44,0x30,0x42,0x30,0x40,0xA0,0x3E,0xA0,0x3C,0x86,0x3A,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,0x48,0x69, + 0x67,0x68,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63,0x65,0x45,0x56,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,0x3D,0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65,0xD3,0x21, + 0xD4,0xF8,0xF8,0xD6,0x0F,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, + 0x80,0x14,0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08, + 0x02,0xEF,0x63,0x64,0x2B,0xC3,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, + 0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9D,0xB6,0xD0,0x90,0x86,0xE1, + 0x86,0x02,0xED,0xC5,0xA0,0xF0,0x34,0x1C,0x74,0xC1,0x8D,0x76,0xCC,0x86,0x0A,0xA8, + 0xF0,0x4A,0x8A,0x42,0xD6,0x3F,0xC8,0xA9,0x4D,0xAD,0x7C,0x08,0xAD,0xE6,0xB6,0x50, + 0xB8,0xA2,0x1A,0x4D,0x88,0x07,0xB1,0x29,0x21,0xDC,0xE7,0xDA,0xC6,0x3C,0x21,0xE0, + 0xE3,0x11,0x49,0x70,0xAC,0x7A,0x1D,0x01,0xA4,0xCA,0x11,0x3A,0x57,0xAB,0x7D,0x57, + 0x2A,0x40,0x74,0xFD,0xD3,0x1D,0x85,0x18,0x50,0xDF,0x57,0x47,0x75,0xA1,0x7D,0x55, + 0x20,0x2E,0x47,0x37,0x50,0x72,0x8C,0x7F,0x82,0x1B,0xD2,0x62,0x8F,0x2D,0x03,0x5A, + 0xDA,0xC3,0xC8,0xA1,0xCE,0x2C,0x52,0xA2,0x00,0x63,0xEB,0x73,0xBA,0x71,0xC8,0x49, + 0x27,0x23,0x97,0x64,0x85,0x9E,0x38,0x0E,0xAD,0x63,0x68,0x3C,0xBA,0x52,0x81,0x58, + 0x79,0xA3,0x2C,0x0C,0xDF,0xDE,0x6D,0xEB,0x31,0xF2,0xBA,0xA0,0x7C,0x6C,0xF1,0x2C, + 0xD4,0xE1,0xBD,0x77,0x84,0x37,0x03,0xCE,0x32,0xB5,0xC8,0x9A,0x81,0x1A,0x4A,0x92, + 0x4E,0x3B,0x46,0x9A,0x85,0xFE,0x83,0xA2,0xF9,0x9E,0x8C,0xA3,0xCC,0x0D,0x5E,0xB3, + 0x3D,0xCF,0x04,0x78,0x8F,0x14,0x14,0x7B,0x32,0x9C,0xC7,0x00,0xA6,0x5C,0xC4,0xB5, + 0xA1,0x55,0x8D,0x5A,0x56,0x68,0xA4,0x22,0x70,0xAA,0x3C,0x81,0x71,0xD9,0x9D,0xA8, + 0x45,0x3B,0xF4,0xE5,0xF6,0xA2,0x51,0xDD,0xC7,0x7B,0x62,0xE8,0x6F,0x0C,0x74,0xEB, + 0xB8,0xDA,0xF8,0xBF,0x87,0x0D,0x79,0x50,0x91,0x90,0x9B,0x18,0x3B,0x91,0x59,0x27, + 0xF1,0x35,0x28,0x13,0xAB,0x26,0x7E,0xD5,0xF7,0x7A, +}; + +// MARK: Expired Chain + +/* subject:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.badssl.com */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +unsigned char _eval_expired_badssl[1359]={ + 0x30,0x82,0x05,0x4B,0x30,0x82,0x04,0x33,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4A, + 0xE7,0x95,0x49,0xFA,0x9A,0xBE,0x3F,0x10,0x0F,0x17,0xA4,0x78,0xE1,0x69,0x09,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, + 0x90,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,0x36,0x30,0x34,0x06,0x03,0x55, + 0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44, + 0x6F,0x6D,0x61,0x69,0x6E,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,0x35,0x30,0x34,0x30,0x39,0x30,0x30,0x30,0x30,0x30, + 0x30,0x5A,0x17,0x0D,0x31,0x35,0x30,0x34,0x31,0x32,0x32,0x33,0x35,0x39,0x35,0x39, + 0x5A,0x30,0x59,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x56,0x61,0x6C, + 0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13, + 0x14,0x50,0x6F,0x73,0x69,0x74,0x69,0x76,0x65,0x53,0x53,0x4C,0x20,0x57,0x69,0x6C, + 0x64,0x63,0x61,0x72,0x64,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x14,0x0C, + 0x2A,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,0xC2,0x04,0xEC, + 0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58,0xCC,0x93,0x18,0xEB,0x5C, + 0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B,0x2C,0x76,0x3E,0x6C,0xC0, + 0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6,0xB0,0xF9,0x72,0xC9,0x86, + 0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B,0xBC,0xE9,0x94,0x2E,0x50, + 0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46,0xD3,0x16,0x87,0x27,0x9F, + 0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84,0x4C,0x79,0x55,0xE4,0xD1, + 0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB,0xAA,0xFF,0x6E,0xFF,0x60, + 0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD,0x4D,0xC0,0xC4,0xFC,0x53, + 0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2,0x33,0x48,0xE7,0x22,0x71, + 0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA,0x6C,0xB5,0x72,0xB4,0x7E, + 0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12,0xAB,0xDE,0xC3,0x0F,0x47, + 0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD,0x22,0x06,0x29,0x2E,0xB1, + 0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40,0x72,0x00,0xAC,0x92,0x08, + 0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B,0x54,0x98,0x40,0x27,0x85, + 0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45,0x55,0x7C,0xF9,0x64,0x3F, + 0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1,0xCA,0x85,0x02,0x03,0x01, + 0x00,0x01,0xA3,0x82,0x01,0xD5,0x30,0x82,0x01,0xD1,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90, + 0xEA,0x12,0x56,0x73,0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81,0x0B,0x3A,0x47,0x69,0x71, + 0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,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,0x4F,0x06,0x03,0x55,0x1D,0x20,0x04,0x48, + 0x30,0x46,0x30,0x3A,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x02, + 0x07,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,0x08, + 0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x01,0x30,0x54,0x06,0x03,0x55,0x1D,0x1F,0x04, + 0x4D,0x30,0x4B,0x30,0x49,0xA0,0x47,0xA0,0x45,0x86,0x43,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,0x44,0x6F,0x6D,0x61, + 0x69,0x6E,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, + 0x85,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x79,0x30,0x77,0x30, + 0x4F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x43,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,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,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,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30, + 0x1A,0x82,0x0C,0x2A,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82, + 0x0A,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A, + 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6A, + 0x7A,0xF1,0xDA,0xFF,0x03,0x07,0x72,0x78,0xC5,0x66,0xA1,0x4F,0x46,0x43,0x0E,0x5F, + 0x14,0x21,0x8C,0x75,0x1A,0xEB,0x36,0xE0,0x1F,0xA4,0x10,0x15,0xEC,0xDA,0x33,0x25, + 0x7C,0x3B,0xB5,0x0A,0xC7,0x01,0x38,0x3D,0x27,0xFD,0x58,0xD9,0xCC,0xEA,0x2D,0x69, + 0x39,0x7C,0xBE,0x97,0xEF,0x0B,0xD6,0x0B,0x58,0xE7,0x8C,0x7F,0xBF,0xB3,0x4C,0x1D, + 0xF3,0xB7,0x90,0x80,0xA6,0x36,0x7C,0x14,0x5B,0xEC,0x07,0x2D,0x02,0x3E,0x1B,0x5B, + 0x63,0x5B,0x15,0xAB,0x00,0xFA,0x1F,0x3B,0x19,0x2D,0xDF,0xE2,0x23,0x10,0x11,0x07, + 0x7E,0x72,0x7F,0xE2,0xBF,0xB7,0x00,0x1B,0x98,0x2F,0x2C,0x3F,0xCE,0x85,0x9A,0x27, + 0x8C,0x10,0x22,0x08,0x41,0x2B,0x8A,0x3E,0x82,0x4E,0xFC,0xDD,0x21,0xC6,0x56,0x74, + 0x70,0xA4,0x34,0xF2,0xB1,0x40,0x9E,0x2B,0x58,0xA2,0x59,0x0F,0x1D,0x48,0xEF,0xEB, + 0x11,0x3E,0xC1,0x4A,0x9E,0xBC,0x65,0x55,0x6D,0xC6,0xA3,0xEF,0xD5,0xD4,0x96,0xCD, + 0xF1,0xAE,0x27,0xF7,0xA4,0x57,0x14,0x3C,0x94,0x41,0x05,0x7A,0x8B,0xA1,0x37,0x47, + 0xD7,0xF5,0x7D,0xDC,0xFA,0xCE,0x6F,0x31,0xA2,0xB0,0x8C,0xEA,0xCC,0x12,0x9B,0x22, + 0xF1,0x34,0x70,0xCF,0x7D,0x75,0x4A,0x8B,0x68,0x29,0x0C,0x1E,0xE9,0x96,0xA8,0xCF, + 0xB0,0x12,0x1F,0x5C,0x2A,0xEE,0x67,0x2F,0x7F,0xBD,0x73,0xF3,0x5A,0x01,0x22,0x0C, + 0x70,0xFA,0xCD,0x45,0xEF,0x78,0x5C,0xCE,0x0D,0xFA,0x4E,0xE1,0xEF,0xCE,0x65,0x9F, + 0x47,0x0C,0x4F,0xBB,0x36,0x44,0x68,0x56,0x5C,0x56,0x59,0xAD,0xAA,0x8A,0xBC, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +unsigned char _eval_comodo_rsa_dvss[1548]={ + 0x30,0x82,0x06,0x08,0x30,0x82,0x03,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2B, + 0x2E,0x6E,0xEA,0xD9,0x75,0x36,0x6C,0x14,0x8A,0x6E,0xDB,0xA3,0x7C,0x8C,0x07,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,0x34,0x30,0x32,0x31,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x32,0x31,0x31,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x90,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,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F, + 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44,0x6F,0x6D,0x61,0x69,0x6E,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,0x8E,0xC2,0x02,0x19,0xE1,0xA0, + 0x59,0xA4,0xEB,0x38,0x35,0x8D,0x2C,0xFD,0x01,0xD0,0xD3,0x49,0xC0,0x64,0xC7,0x0B, + 0x62,0x05,0x45,0x16,0x3A,0xA8,0xA0,0xC0,0x0C,0x02,0x7F,0x1D,0xCC,0xDB,0xC4,0xA1, + 0x6D,0x77,0x03,0xA3,0x0F,0x86,0xF9,0xE3,0x06,0x9C,0x3E,0x0B,0x81,0x8A,0x9B,0x49, + 0x1B,0xAD,0x03,0xBE,0xFA,0x4B,0xDB,0x8C,0x20,0xED,0xD5,0xCE,0x5E,0x65,0x8E,0x3E, + 0x0D,0xAF,0x4C,0xC2,0xB0,0xB7,0x45,0x5E,0x52,0x2F,0x34,0xDE,0x48,0x24,0x64,0xB4, + 0x41,0xAE,0x00,0x97,0xF7,0xBE,0x67,0xDE,0x9E,0xD0,0x7A,0xA7,0x53,0x80,0x3B,0x7C, + 0xAD,0xF5,0x96,0x55,0x6F,0x97,0x47,0x0A,0x7C,0x85,0x8B,0x22,0x97,0x8D,0xB3,0x84, + 0xE0,0x96,0x57,0xD0,0x70,0x18,0x60,0x96,0x8F,0xEE,0x2D,0x07,0x93,0x9D,0xA1,0xBA, + 0xCA,0xD1,0xCD,0x7B,0xE9,0xC4,0x2A,0x9A,0x28,0x21,0x91,0x4D,0x6F,0x92,0x4F,0x25, + 0xA5,0xF2,0x7A,0x35,0xDD,0x26,0xDC,0x46,0xA5,0xD0,0xAC,0x59,0x35,0x8C,0xFF,0x4E, + 0x91,0x43,0x50,0x3F,0x59,0x93,0x1E,0x6C,0x51,0x21,0xEE,0x58,0x14,0xAB,0xFE,0x75, + 0x50,0x78,0x3E,0x4C,0xB0,0x1C,0x86,0x13,0xFA,0x6B,0x98,0xBC,0xE0,0x3B,0x94,0x1E, + 0x85,0x52,0xDC,0x03,0x93,0x24,0x18,0x6E,0xCB,0x27,0x51,0x45,0xE6,0x70,0xDE,0x25, + 0x43,0xA4,0x0D,0xE1,0x4A,0xA5,0xED,0xB6,0x7E,0xC8,0xCD,0x6D,0xEE,0x2E,0x1D,0x27, + 0x73,0x5D,0xDC,0x45,0x30,0x80,0xAA,0xE3,0xB2,0x41,0x0B,0xAF,0xBD,0x44,0x87,0xDA, + 0xB9,0xE5,0x1B,0x9D,0x7F,0xAE,0xE5,0x85,0x82,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x82,0x01,0x65,0x30,0x82,0x01,0x61,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,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90,0xEA,0x12,0x56,0x73, + 0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, + 0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,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,0x1B,0x06,0x03,0x55,0x1D, + 0x20,0x04,0x14,0x30,0x12,0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x08,0x06, + 0x06,0x67,0x81,0x0C,0x01,0x02,0x01,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,0x4E,0x2B,0x76,0x4F, + 0x92,0x1C,0x62,0x36,0x89,0xBA,0x77,0xC1,0x27,0x05,0xF4,0x1C,0xD6,0x44,0x9D,0xA9, + 0x9A,0x3E,0xAA,0xD5,0x66,0x66,0x01,0x3E,0xEA,0x49,0xE6,0xA2,0x35,0xBC,0xFA,0xF6, + 0xDD,0x95,0x8E,0x99,0x35,0x98,0x0E,0x36,0x18,0x75,0xB1,0xDD,0xDD,0x50,0x72,0x7C, + 0xAE,0xDC,0x77,0x88,0xCE,0x0F,0xF7,0x90,0x20,0xCA,0xA3,0x67,0x2E,0x1F,0x56,0x7F, + 0x7B,0xE1,0x44,0xEA,0x42,0x95,0xC4,0x5D,0x0D,0x01,0x50,0x46,0x15,0xF2,0x81,0x89, + 0x59,0x6C,0x8A,0xDD,0x8C,0xF1,0x12,0xA1,0x8D,0x3A,0x42,0x8A,0x98,0xF8,0x4B,0x34, + 0x7B,0x27,0x3B,0x08,0xB4,0x6F,0x24,0x3B,0x72,0x9D,0x63,0x74,0x58,0x3C,0x1A,0x6C, + 0x3F,0x4F,0xC7,0x11,0x9A,0xC8,0xA8,0xF5,0xB5,0x37,0xEF,0x10,0x45,0xC6,0x6C,0xD9, + 0xE0,0x5E,0x95,0x26,0xB3,0xEB,0xAD,0xA3,0xB9,0xEE,0x7F,0x0C,0x9A,0x66,0x35,0x73, + 0x32,0x60,0x4E,0xE5,0xDD,0x8A,0x61,0x2C,0x6E,0x52,0x11,0x77,0x68,0x96,0xD3,0x18, + 0x75,0x51,0x15,0x00,0x1B,0x74,0x88,0xDD,0xE1,0xC7,0x38,0x04,0x43,0x28,0xE9,0x16, + 0xFD,0xD9,0x05,0xD4,0x5D,0x47,0x27,0x60,0xD6,0xFB,0x38,0x3B,0x6C,0x72,0xA2,0x94, + 0xF8,0x42,0x1A,0xDF,0xED,0x6F,0x06,0x8C,0x45,0xC2,0x06,0x00,0xAA,0xE4,0xE8,0xDC, + 0xD9,0xB5,0xE1,0x73,0x78,0xEC,0xF6,0x23,0xDC,0xD1,0xDD,0x6C,0x8E,0x1A,0x8F,0xA5, + 0xEA,0x54,0x7C,0x96,0xB7,0xC3,0xFE,0x55,0x8E,0x8D,0x49,0x5E,0xFC,0x64,0xBB,0xCF, + 0x3E,0xBD,0x96,0xEB,0x69,0xCD,0xBF,0xE0,0x48,0xF1,0x62,0x82,0x10,0xE5,0x0C,0x46, + 0x57,0xF2,0x33,0xDA,0xD0,0xC8,0x63,0xED,0xC6,0x1F,0x94,0x05,0x96,0x4A,0x1A,0x91, + 0xD1,0xF7,0xEB,0xCF,0x8F,0x52,0xAE,0x0D,0x08,0xD9,0x3E,0xA8,0xA0,0x51,0xE9,0xC1, + 0x87,0x74,0xD5,0xC9,0xF7,0x74,0xAB,0x2E,0x53,0xFB,0xBB,0x7A,0xFB,0x97,0xE2,0xF8, + 0x1F,0x26,0x8F,0xB3,0xD2,0xA0,0xE0,0x37,0x5B,0x28,0x3B,0x31,0xE5,0x0E,0x57,0x2D, + 0x5A,0xB8,0xAD,0x79,0xAC,0x5E,0x20,0x66,0x1A,0xA5,0xB9,0xA6,0xB5,0x39,0xC1,0xF5, + 0x98,0x43,0xFF,0xEE,0xF9,0xA7,0xA7,0xFD,0xEE,0xCA,0x24,0x3D,0x80,0x16,0xC4,0x17, + 0x8F,0x8A,0xC1,0x60,0xA1,0x0C,0xAE,0x5B,0x43,0x47,0x91,0x4B,0xD5,0x9A,0x17,0x5F, + 0xF9,0xD4,0x87,0xC1,0xC2,0x8C,0xB7,0xE7,0xE2,0x0F,0x30,0x19,0x37,0x86,0xAC,0xE0, + 0xDC,0x42,0x03,0xE6,0x94,0xA8,0x9D,0xAE,0xFD,0x0F,0x24,0x51,0x94,0xCE,0x92,0x08, + 0xD1,0xFC,0x50,0xF0,0x03,0x40,0x7B,0x88,0x59,0xED,0x0E,0xDD,0xAC,0xD2,0x77,0x82, + 0x34,0xDC,0x06,0x95,0x02,0xD8,0x90,0xF9,0x2D,0xEA,0x37,0xD5,0x1A,0x60,0xD0,0x67, + 0x20,0xD7,0xD8,0x42,0x0B,0x45,0xAF,0x82,0x68,0xDE,0xDD,0x66,0x24,0x37,0x90,0x29, + 0x94,0x19,0x46,0x19,0x25,0xB8,0x80,0xD7,0xCB,0xD4,0x86,0x28,0x6A,0x44,0x70,0x26, + 0x23,0x62,0xA9,0x9F,0x86,0x6F,0xBF,0xBA,0x90,0x70,0xD2,0x56,0x77,0x85,0x78,0xEF, + 0xEA,0x25,0xA9,0x17,0xCE,0x50,0x72,0x8C,0x00,0x3A,0xAA,0xE3,0xDB,0x63,0x34,0x9F, + 0xF8,0x06,0x71,0x01,0xE2,0x82,0x20,0xD4,0xFE,0x6F,0xBD,0xB1, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +unsigned char _eval_comodo_rsa_root[1500]={ + 0x30,0x82,0x05,0xD8,0x30,0x82,0x03,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, + 0xAA,0xF9,0xCA,0xDB,0x63,0x6F,0xE0,0x1F,0xF7,0x4E,0xD8,0x5B,0x03,0x86,0x9D,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,0x30,0x30,0x31,0x31,0x39, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,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,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,0x91, + 0xE8,0x54,0x92,0xD2,0x0A,0x56,0xB1,0xAC,0x0D,0x24,0xDD,0xC5,0xCF,0x44,0x67,0x74, + 0x99,0x2B,0x37,0xA3,0x7D,0x23,0x70,0x00,0x71,0xBC,0x53,0xDF,0xC4,0xFA,0x2A,0x12, + 0x8F,0x4B,0x7F,0x10,0x56,0xBD,0x9F,0x70,0x72,0xB7,0x61,0x7F,0xC9,0x4B,0x0F,0x17, + 0xA7,0x3D,0xE3,0xB0,0x04,0x61,0xEE,0xFF,0x11,0x97,0xC7,0xF4,0x86,0x3E,0x0A,0xFA, + 0x3E,0x5C,0xF9,0x93,0xE6,0x34,0x7A,0xD9,0x14,0x6B,0xE7,0x9C,0xB3,0x85,0xA0,0x82, + 0x7A,0x76,0xAF,0x71,0x90,0xD7,0xEC,0xFD,0x0D,0xFA,0x9C,0x6C,0xFA,0xDF,0xB0,0x82, + 0xF4,0x14,0x7E,0xF9,0xBE,0xC4,0xA6,0x2F,0x4F,0x7F,0x99,0x7F,0xB5,0xFC,0x67,0x43, + 0x72,0xBD,0x0C,0x00,0xD6,0x89,0xEB,0x6B,0x2C,0xD3,0xED,0x8F,0x98,0x1C,0x14,0xAB, + 0x7E,0xE5,0xE3,0x6E,0xFC,0xD8,0xA8,0xE4,0x92,0x24,0xDA,0x43,0x6B,0x62,0xB8,0x55, + 0xFD,0xEA,0xC1,0xBC,0x6C,0xB6,0x8B,0xF3,0x0E,0x8D,0x9A,0xE4,0x9B,0x6C,0x69,0x99, + 0xF8,0x78,0x48,0x30,0x45,0xD5,0xAD,0xE1,0x0D,0x3C,0x45,0x60,0xFC,0x32,0x96,0x51, + 0x27,0xBC,0x67,0xC3,0xCA,0x2E,0xB6,0x6B,0xEA,0x46,0xC7,0xC7,0x20,0xA0,0xB1,0x1F, + 0x65,0xDE,0x48,0x08,0xBA,0xA4,0x4E,0xA9,0xF2,0x83,0x46,0x37,0x84,0xEB,0xE8,0xCC, + 0x81,0x48,0x43,0x67,0x4E,0x72,0x2A,0x9B,0x5C,0xBD,0x4C,0x1B,0x28,0x8A,0x5C,0x22, + 0x7B,0xB4,0xAB,0x98,0xD9,0xEE,0xE0,0x51,0x83,0xC3,0x09,0x46,0x4E,0x6D,0x3E,0x99, + 0xFA,0x95,0x17,0xDA,0x7C,0x33,0x57,0x41,0x3C,0x8D,0x51,0xED,0x0B,0xB6,0x5C,0xAF, + 0x2C,0x63,0x1A,0xDF,0x57,0xC8,0x3F,0xBC,0xE9,0x5D,0xC4,0x9B,0xAF,0x45,0x99,0xE2, + 0xA3,0x5A,0x24,0xB4,0xBA,0xA9,0x56,0x3D,0xCF,0x6F,0xAA,0xFF,0x49,0x58,0xBE,0xF0, + 0xA8,0xFF,0xF4,0xB8,0xAD,0xE9,0x37,0xFB,0xBA,0xB8,0xF4,0x0B,0x3A,0xF9,0xE8,0x43, + 0x42,0x1E,0x89,0xD8,0x84,0xCB,0x13,0xF1,0xD9,0xBB,0xE1,0x89,0x60,0xB8,0x8C,0x28, + 0x56,0xAC,0x14,0x1D,0x9C,0x0A,0xE7,0x71,0xEB,0xCF,0x0E,0xDD,0x3D,0xA9,0x96,0xA1, + 0x48,0xBD,0x3C,0xF7,0xAF,0xB5,0x0D,0x22,0x4C,0xC0,0x11,0x81,0xEC,0x56,0x3B,0xF6, + 0xD3,0xA2,0xE2,0x5B,0xB7,0xB2,0x04,0x22,0x52,0x95,0x80,0x93,0x69,0xE8,0x8E,0x4C, + 0x65,0xF1,0x91,0x03,0x2D,0x70,0x74,0x02,0xEA,0x8B,0x67,0x15,0x29,0x69,0x52,0x02, + 0xBB,0xD7,0xDF,0x50,0x6A,0x55,0x46,0xBF,0xA0,0xA3,0x28,0x61,0x7F,0x70,0xD0,0xC3, + 0xA2,0xAA,0x2C,0x21,0xAA,0x47,0xCE,0x28,0x9C,0x06,0x45,0x76,0xBF,0x82,0x18,0x27, + 0xB4,0xD5,0xAE,0xB4,0xCB,0x50,0xE6,0x6B,0xF4,0x4C,0x86,0x71,0x30,0xE9,0xA6,0xDF, + 0x16,0x86,0xE0,0xD8,0xFF,0x40,0xDD,0xFB,0xD0,0x42,0x88,0x7F,0xA3,0x33,0x3A,0x2E, + 0x5C,0x1E,0x41,0x11,0x81,0x63,0xCE,0x18,0x71,0x6B,0x2B,0xEC,0xA6,0x8A,0xB7,0x31, + 0x5C,0x3A,0x6A,0x47,0xE0,0xC3,0x79,0x59,0xD6,0x20,0x1A,0xAF,0xF2,0x6A,0x98,0xAA, + 0x72,0xBC,0x57,0x4A,0xD2,0x4B,0x9D,0xBB,0x10,0xFC,0xB0,0x4C,0x41,0xE5,0xED,0x1D, + 0x3D,0x5E,0x28,0x9D,0x9C,0xCC,0xBF,0xB3,0x51,0xDA,0xA7,0x47,0xE5,0x84,0x53,0x02, + 0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, + 0x16,0x04,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84,0x8E,0xAD,0xEE, + 0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,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,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x0A,0xF1,0xD5,0x46, + 0x84,0xB7,0xAE,0x51,0xBB,0x6C,0xB2,0x4D,0x41,0x14,0x00,0x93,0x4C,0x9C,0xCB,0xE5, + 0xC0,0x54,0xCF,0xA0,0x25,0x8E,0x02,0xF9,0xFD,0xB0,0xA2,0x0D,0xF5,0x20,0x98,0x3C, + 0x13,0x2D,0xAC,0x56,0xA2,0xB0,0xD6,0x7E,0x11,0x92,0xE9,0x2E,0xBA,0x9E,0x2E,0x9A, + 0x72,0xB1,0xBD,0x19,0x44,0x6C,0x61,0x35,0xA2,0x9A,0xB4,0x16,0x12,0x69,0x5A,0x8C, + 0xE1,0xD7,0x3E,0xA4,0x1A,0xE8,0x2F,0x03,0xF4,0xAE,0x61,0x1D,0x10,0x1B,0x2A,0xA4, + 0x8B,0x7A,0xC5,0xFE,0x05,0xA6,0xE1,0xC0,0xD6,0xC8,0xFE,0x9E,0xAE,0x8F,0x2B,0xBA, + 0x3D,0x99,0xF8,0xD8,0x73,0x09,0x58,0x46,0x6E,0xA6,0x9C,0xF4,0xD7,0x27,0xD3,0x95, + 0xDA,0x37,0x83,0x72,0x1C,0xD3,0x73,0xE0,0xA2,0x47,0x99,0x03,0x38,0x5D,0xD5,0x49, + 0x79,0x00,0x29,0x1C,0xC7,0xEC,0x9B,0x20,0x1C,0x07,0x24,0x69,0x57,0x78,0xB2,0x39, + 0xFC,0x3A,0x84,0xA0,0xB5,0x9C,0x7C,0x8D,0xBF,0x2E,0x93,0x62,0x27,0xB7,0x39,0xDA, + 0x17,0x18,0xAE,0xBD,0x3C,0x09,0x68,0xFF,0x84,0x9B,0x3C,0xD5,0xD6,0x0B,0x03,0xE3, + 0x57,0x9E,0x14,0xF7,0xD1,0xEB,0x4F,0xC8,0xBD,0x87,0x23,0xB7,0xB6,0x49,0x43,0x79, + 0x85,0x5C,0xBA,0xEB,0x92,0x0B,0xA1,0xC6,0xE8,0x68,0xA8,0x4C,0x16,0xB1,0x1A,0x99, + 0x0A,0xE8,0x53,0x2C,0x92,0xBB,0xA1,0x09,0x18,0x75,0x0C,0x65,0xA8,0x7B,0xCB,0x23, + 0xB7,0x1A,0xC2,0x28,0x85,0xC3,0x1B,0xFF,0xD0,0x2B,0x62,0xEF,0xA4,0x7B,0x09,0x91, + 0x98,0x67,0x8C,0x14,0x01,0xCD,0x68,0x06,0x6A,0x63,0x21,0x75,0x03,0x80,0x88,0x8A, + 0x6E,0x81,0xC6,0x85,0xF2,0xA9,0xA4,0x2D,0xE7,0xF4,0xA5,0x24,0x10,0x47,0x83,0xCA, + 0xCD,0xF4,0x8D,0x79,0x58,0xB1,0x06,0x9B,0xE7,0x1A,0x2A,0xD9,0x9D,0x01,0xD7,0x94, + 0x7D,0xED,0x03,0x4A,0xCA,0xF0,0xDB,0xE8,0xA9,0x01,0x3E,0xF5,0x56,0x99,0xC9,0x1E, + 0x8E,0x49,0x3D,0xBB,0xE5,0x09,0xB9,0xE0,0x4F,0x49,0x92,0x3D,0x16,0x82,0x40,0xCC, + 0xCC,0x59,0xC6,0xE6,0x3A,0xED,0x12,0x2E,0x69,0x3C,0x6C,0x95,0xB1,0xFD,0xAA,0x1D, + 0x7B,0x7F,0x86,0xBE,0x1E,0x0E,0x32,0x46,0xFB,0xFB,0x13,0x8F,0x75,0x7F,0x4C,0x8B, + 0x4B,0x46,0x63,0xFE,0x00,0x34,0x40,0x70,0xC1,0xC3,0xB9,0xA1,0xDD,0xA6,0x70,0xE2, + 0x04,0xB3,0x41,0xBC,0xE9,0x80,0x91,0xEA,0x64,0x9C,0x7A,0xE1,0x22,0x03,0xA9,0x9C, + 0x6E,0x6F,0x0E,0x65,0x4F,0x6C,0x87,0x87,0x5E,0xF3,0x6E,0xA0,0xF9,0x75,0xA5,0x9B, + 0x40,0xE8,0x53,0xB2,0x27,0x9D,0x4A,0xB9,0xC0,0x77,0x21,0x8D,0xFF,0x87,0xF2,0xDE, + 0xBC,0x8C,0xEF,0x17,0xDF,0xB7,0x49,0x0B,0xD1,0xF2,0x6E,0x30,0x0B,0x1A,0x0E,0x4E, + 0x76,0xED,0x11,0xFC,0xF5,0xE9,0x56,0xB2,0x7D,0xBF,0xC7,0x6D,0x0A,0x93,0x8C,0xA5, + 0xD0,0xC0,0xB6,0x1D,0xBE,0x3A,0x4E,0x94,0xA2,0xD7,0x6E,0x6C,0x0B,0xC2,0x8A,0x7C, + 0xFA,0x20,0xF3,0xC4,0xE4,0xE5,0xCD,0x0D,0xA8,0xCB,0x91,0x92,0xB1,0x7C,0x85,0xEC, + 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, +}; + +// MARK: self-signed SSL cert +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Strong Crypto Self-Signed */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Strong Crypto Self-Signed */ +uint8_t _selfSignedAnchor[] = { + 0x30,0x82,0x04,0x3A,0x30,0x82,0x03,0x22,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xAF,0x83,0x70,0xCF,0x93,0x34,0xC5,0x8E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8E,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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x53, + 0x74,0x72,0x6F,0x6E,0x67,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x20,0x53,0x65,0x6C, + 0x66,0x2D,0x53,0x69,0x67,0x6E,0x65,0x64,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34, + 0x31,0x39,0x32,0x32,0x35,0x30,0x30,0x35,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x31, + 0x38,0x32,0x32,0x35,0x30,0x30,0x35,0x5A,0x30,0x81,0x8E,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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19, + 0x53,0x74,0x72,0x6F,0x6E,0x67,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x20,0x53,0x65, + 0x6C,0x66,0x2D,0x53,0x69,0x67,0x6E,0x65,0x64,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,0x92,0x79,0x5C,0x32,0x3B,0x2F, + 0x9D,0xC1,0xF0,0xE1,0xD6,0x52,0x69,0x8E,0xE7,0x5A,0x05,0xDB,0xE4,0x7F,0x2D,0x3E, + 0xA6,0xD1,0xAA,0x7A,0x7B,0x28,0xB8,0xDF,0x25,0x73,0x4C,0x2F,0xA8,0x45,0x69,0x22, + 0xF7,0x08,0x45,0x85,0x2F,0x2B,0xED,0x72,0x25,0x5E,0x17,0x8B,0xAA,0x28,0xF8,0xCA, + 0xE6,0x7E,0x6A,0xF9,0x6C,0x3A,0x5B,0x32,0x04,0xAA,0x8B,0xC2,0x36,0xD9,0x6D,0x74, + 0x2B,0x62,0xFC,0x29,0x03,0x65,0x5D,0x46,0x47,0x69,0xFD,0x4B,0x66,0x43,0x7C,0xA2, + 0xA1,0xD9,0xB0,0x72,0xFC,0x9B,0xB2,0x40,0xD1,0x4A,0x2C,0x07,0x36,0xBE,0x9D,0xD5, + 0x88,0xA1,0xF4,0xFC,0x1D,0x2F,0xEC,0xDD,0xE5,0x9B,0x7D,0x58,0xD5,0x9A,0x1F,0x5F, + 0x08,0x3F,0x60,0x57,0x82,0xCB,0xF6,0x0C,0x54,0x30,0x04,0x5F,0x9E,0x7F,0xDA,0xB1, + 0x71,0x23,0x7E,0x3C,0xA8,0xFA,0xB2,0x0E,0xA5,0x3D,0x65,0xD1,0xEF,0x68,0xD4,0x57, + 0xF8,0x0B,0xF4,0x07,0x0D,0x87,0xA1,0xEA,0x4F,0xB9,0xA1,0x21,0x2A,0x22,0x44,0x44, + 0xA7,0xB2,0x68,0x9A,0x5F,0x5A,0x39,0x6F,0x5E,0x32,0x9B,0x16,0x59,0xF3,0xD8,0xEE, + 0xF3,0x04,0x8D,0x4F,0x4E,0xA4,0x7D,0xE7,0x49,0x06,0xD7,0xFB,0x3C,0x94,0xED,0x34, + 0xDC,0xEC,0xCE,0x1F,0xF7,0x0F,0xD3,0x87,0x10,0x72,0x5B,0xA2,0x33,0x6A,0xE3,0x4A, + 0x15,0xC7,0x8D,0x33,0xEC,0xA5,0xA3,0x6C,0xC3,0xC7,0x11,0x07,0xC9,0xE5,0x94,0xB1, + 0x72,0xA1,0xCB,0x79,0x54,0xCE,0xC9,0x45,0x7E,0xB5,0x18,0x08,0x64,0xD5,0x3E,0x62, + 0xB1,0xCB,0xB6,0xB7,0x53,0xC8,0x7A,0x6D,0xF7,0x19,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x81,0x98,0x30,0x81,0x95,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,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,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,0xBB,0x55,0xBE,0x4B,0x36,0x5E,0x82,0x92,0xDC,0xC0,0xC1, + 0x08,0x11,0x94,0x43,0xB1,0x03,0x50,0x0A,0xCF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0xBB,0x55,0xBE,0x4B,0x36,0x5E,0x82,0x92,0xDC,0xC0, + 0xC1,0x08,0x11,0x94,0x43,0xB1,0x03,0x50,0x0A,0xCF,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x24,0xC9, + 0x7B,0x5A,0xA7,0x0F,0x2B,0xE3,0x6E,0x08,0x3A,0x42,0xB0,0xB2,0x35,0xB1,0x81,0x7D, + 0xE2,0xF0,0xF9,0x3D,0x1E,0xB1,0x39,0x89,0xA7,0xD1,0x09,0x5B,0xCA,0xD0,0x54,0x5A, + 0xCA,0x01,0x3E,0x35,0x77,0x91,0xE1,0x78,0x80,0xE5,0xC1,0x08,0x32,0x66,0x44,0xC3, + 0xCB,0x2F,0x5C,0xFE,0x15,0x1C,0xFE,0xD7,0x03,0x58,0xAF,0x77,0x5C,0xF2,0x88,0xB2, + 0xE1,0x37,0x31,0x5E,0x49,0x04,0xA9,0x82,0x0A,0x58,0xBE,0x6F,0xC0,0x2E,0xD3,0x5B, + 0x8C,0x18,0x89,0x4C,0x03,0x80,0x0D,0xE6,0x84,0x15,0x8C,0xEA,0xD1,0xE1,0x83,0x74, + 0x90,0x31,0x24,0xB6,0x1C,0x09,0x90,0x79,0xF5,0x2D,0x44,0x2D,0x67,0x3F,0x29,0x8B, + 0x14,0x28,0x3D,0x56,0x19,0x0B,0x80,0xDB,0xA5,0xEE,0x7C,0x39,0xEE,0x81,0xD2,0x03, + 0xE1,0x7A,0xA9,0x97,0x50,0x49,0xEF,0xFC,0x1E,0xFA,0xE1,0xAF,0xAE,0xEA,0x02,0x0E, + 0xE5,0xB2,0xBE,0xC9,0x19,0xAA,0xB4,0xD2,0xDC,0x6E,0x78,0x96,0x99,0x87,0xDA,0x40, + 0x84,0x7C,0xDA,0x09,0x17,0x5E,0xD7,0xE8,0x63,0x51,0x23,0x44,0xCC,0x31,0x41,0x08, + 0x7C,0x29,0x2D,0xF2,0x0E,0x5D,0xBA,0x12,0xAE,0x51,0x2F,0xD8,0x8E,0x78,0xDA,0x7C, + 0x69,0x6E,0x4D,0x38,0x21,0xD6,0xC2,0xDA,0x37,0xAD,0xF5,0x25,0x24,0x5C,0x1A,0x7F, + 0x08,0x8A,0x0A,0xF3,0xAD,0x56,0x8F,0x0A,0x0A,0xA1,0xEA,0xDF,0xC4,0xD7,0xE7,0x2C, + 0xD8,0x6A,0xD7,0xE7,0xDE,0x7C,0xD0,0xBC,0x49,0xEF,0xCA,0x24,0xBC,0x52,0xC1,0xEC, + 0xC1,0xDA,0x7C,0xE4,0x3C,0xE5,0x15,0xF0,0x28,0x40,0x6D,0x69,0x40,0xB9, +}; + +#endif /* _TRUSTTESTS_EVALUATION_BASIC_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/KeySizeTests.m b/tests/TrustTests/EvaluationTests/KeySizeTests.m new file mode 100644 index 00000000..e905b822 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/KeySizeTests.m @@ -0,0 +1,382 @@ +/* + * 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 +#include +#include +#include +#include "OSX/utilities/SecCFWrappers.h" + +#import "TrustEvaluationTestCase.h" +#include "../TestMacroConversions.h" +#include "KeySizeTests_data.h" + +@interface KeySizeTests : TrustEvaluationTestCase +@end + +@implementation KeySizeTests + +- (bool)run_chain_of_threetest:(NSData *)cert0 cert1:(NSData *)cert1 root:(NSData *)root + result:(bool)should_succeed failureReason:(NSString **)failureReason +{ + bool ok = false; + + const void *secCert0, *secCert1, *secRoot; + isnt(secCert0 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cert0), NULL, "create leaf"); + isnt(secCert1 = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cert1), NULL, "create subCA"); + isnt(secRoot = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)root), NULL, "create root"); + + const void *v_certs[] = { secCert0, secCert1 }; + CFArrayRef certs = NULL; + isnt(certs = CFArrayCreate(NULL, v_certs, sizeof(v_certs)/sizeof(*v_certs), &kCFTypeArrayCallBacks), + NULL, "failed to create cert array"); + CFArrayRef anchors = NULL; + isnt(anchors = CFArrayCreate(NULL, &secRoot, 1, &kCFTypeArrayCallBacks), NULL, "failed to create anchors array"); + + SecPolicyRef policy = NULL; + isnt(policy = SecPolicyCreateBasicX509(), NULL, "failed to create policy"); + CFDateRef date = NULL; + isnt(date = CFDateCreate(NULL, 472100000.0), NULL, "failed to create date"); // 17 Dec 2015 + + SecTrustRef trust = NULL; + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "failed to create trust"); + if (!date) { goto errOut; } + ok_status(SecTrustSetVerifyDate(trust, date), "failed to set verify date"); + if (!anchors) { goto errOut; } + ok_status(SecTrustSetAnchorCertificates(trust, anchors), "failed to set anchors"); + + bool did_succeed = SecTrustEvaluateWithError(trust, NULL); + is(SecTrustGetCertificateCount(trust), 3, "expected chain of 3"); + + if (failureReason && should_succeed && !did_succeed) { + *failureReason = CFBridgingRelease(SecTrustCopyFailureDescription(trust)); + } else if (failureReason && !should_succeed && did_succeed) { + *failureReason = @"expected kSecTrustResultFatalTrustFailure"; + } + + if ((should_succeed && did_succeed) || (!should_succeed && !did_succeed)) { + ok = true; + } + +errOut: + CFReleaseNull(secCert0); + CFReleaseNull(secCert1); + CFReleaseNull(secRoot); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(date); + CFReleaseNull(policy); + CFReleaseNull(trust); + + return ok; +} + +- (void)test8192BitKeySize { + /* Test prt_forest_fi that have a 8k RSA key */ + const void *prt_forest_fi; + isnt(prt_forest_fi = SecCertificateCreateWithBytes(NULL, prt_forest_fi_certificate, + sizeof(prt_forest_fi_certificate)), NULL, "create prt_forest_fi"); + CFArrayRef certs = NULL; + isnt(certs = CFArrayCreate(NULL, &prt_forest_fi, 1, &kCFTypeArrayCallBacks), NULL, "failed to create cert array"); + SecPolicyRef policy = NULL; + 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"); + CFDateRef date = CFDateCreate(NULL, 391578321.0); + ok_status(SecTrustSetVerifyDate(trust, date), + "set owa.prt-forest.fi trust date to May 2013"); + + SecKeyRef pubkey = SecTrustCopyPublicKey(trust); + isnt(pubkey, NULL, "pubkey returned"); + + CFReleaseNull(certs); + CFReleaseNull(prt_forest_fi); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(pubkey); + CFReleaseNull(date); +} + +- (void)testRSAKeySizes { + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf2048A length:sizeof(_leaf2048A)] + cert1:[NSData dataWithBytes:_int2048A length:sizeof(_int2048A)] + root:[NSData dataWithBytes:_root512 length:sizeof(_root512)] + result:false + failureReason:nil], + "SECURITY: failed to detect weak root"); + + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf2048B length:sizeof(_leaf2048B)] + cert1:[NSData dataWithBytes:_int512 length:sizeof(_int512)] + root:[NSData dataWithBytes:_root2048 length:sizeof(_root2048)] + result:false + failureReason:nil], + "SECURITY: failed to detect weak intermediate"); + + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf512 length:sizeof(_leaf512)] + cert1:[NSData dataWithBytes:_int2048B length:sizeof(_int2048B)] + root:[NSData dataWithBytes:_root2048 length:sizeof(_root2048)] + result:false + failureReason:nil], + "SECURITY: failed to detect weak leaf"); + + NSString *failureReason = nil; + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf1024 length:sizeof(_leaf1024)] + cert1:[NSData dataWithBytes:_int2048B length:sizeof(_int2048B)] + root:[NSData dataWithBytes:_root2048 length:sizeof(_root2048)] + result:true + failureReason:&failureReason], + "REGRESSION: key size test 1024-bit leaf: %@", failureReason); + + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf2048C length:sizeof(_leaf2048C)] + cert1:[NSData dataWithBytes:_int2048B length:sizeof(_int2048B)] + root:[NSData dataWithBytes:_root2048 length:sizeof(_root2048)] + result:true + failureReason:&failureReason], + "REGRESSION: key size test 2048-bit leaf: %@", failureReason); +} + +- (void)testECKeySizes { + /* Because CoreCrypto does not support P128, we fail to chain if any CAs use weakly sized curves */ + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf128 length:sizeof(_leaf128)] + cert1:[NSData dataWithBytes:_int384B length:sizeof(_int384B)] + root:[NSData dataWithBytes:_root384 length:sizeof(_root384)] + result:false + failureReason:nil], + "SECURITY: failed to detect weak leaf"); + + NSString *failureReason = nil; + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf192 length:sizeof(_leaf192)] + cert1:[NSData dataWithBytes:_int384B length:sizeof(_int384B)] + root:[NSData dataWithBytes:_root384 length:sizeof(_root384)] + result:true + failureReason:&failureReason], + "REGRESSION: key size test 192-bit leaf: %@", failureReason); + + ok([self run_chain_of_threetest:[NSData dataWithBytes:_leaf384C length:sizeof(_leaf384C)] + cert1:[NSData dataWithBytes:_int384B length:sizeof(_int384B)] + root:[NSData dataWithBytes:_root384 length:sizeof(_root384)] + result:true + failureReason:&failureReason], + "REGRESSION: key size test 384-bit leaf: %@", failureReason); +} + +- (bool)runTrust:(NSArray *)certs + anchors:(NSArray *)anchors + policy:(SecPolicyRef)policy + verifyDate:(NSDate *)date +{ + SecTrustRef trust = NULL; + XCTAssert(errSecSuccess == SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust)); + if (anchors) { + XCTAssert(errSecSuccess == SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors)); + } + XCTAssert(errSecSuccess == SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date)); + + CFErrorRef error = NULL; + bool result = SecTrustEvaluateWithError(trust, &error); + CFReleaseNull(error); + CFReleaseNull(trust); + return result; +} + +- (void)test1024_appTrustedLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf1024SSL, sizeof(_leaf1024SSL)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _rootSSL, sizeof(_rootSSL)); + + NSArray *certs = @[ (__bridge id)leaf]; + NSArray *anchor = @[ (__bridge id)root ]; + CFReleaseNull(leaf); + CFReleaseNull(root); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertFalse([self runTrust:certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "anchor trusted 1024-bit cert succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "anchor trusted 1024-bit cert failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "anchor trusted 1024-bit cert failed for EAP"); + CFReleaseNull(eapPolicy); + + SecPolicyRef legacyPolicy = SecPolicyCreateLegacySSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:legacyPolicy verifyDate:verifyDate], "anchor trusted 1024-bit cert failed for legacy SSL policy"); + CFReleaseNull(legacyPolicy); + + SecPolicyRef legacyClientPolicy = SecPolicyCreateLegacySSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:legacyClientPolicy verifyDate:verifyDate], "anchor trusted 1024-bit cert failed for legacy SSL client policy"); + CFReleaseNull(legacyClientPolicy); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have trust settings +- (void)test1024_trustSettingsOnRoot_TestLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf1024SSL, sizeof(_leaf1024SSL)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _rootSSL, sizeof(_rootSSL)); + NSArray *certs = @[ (__bridge id)leaf, (__bridge id)root ]; + CFReleaseNull(leaf); + + id persistentRef = [self addTrustSettingsForCert:root]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertFalse([self runTrust:certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on root, 1024-bit leaf succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on root, 1024-bit leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on root, 1024-bit leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(root); +} + +- (void)test1024_trustSettingsOnLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf1024SSL, sizeof(_leaf1024SSL)); + NSArray *certs = @[ (__bridge id)leaf ]; + + id persistentRef = [self addTrustSettingsForCert:leaf]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on 1024-bit leaf failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on 1024-bit leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on 1024-bit leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} +#endif // !TARGET_OS_BRIDGE + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have a system trust store +- (void)test2048_systemTrusted { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0]; // April 26, 2019 at 12:33:20 PM PDT + + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf2048SystemTrust, sizeof(_leaf2048SystemTrust)); + SecCertificateRef sha2_int = SecCertificateCreateWithBytes(NULL, _int2048SystemTrust, sizeof(_int2048SystemTrust)); + NSArray *certs = @[ (__bridge id)leaf, (__bridge id)sha2_int]; + CFReleaseNull(leaf); + CFReleaseNull(sha2_int); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com")); + XCTAssertTrue([self runTrust:certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "system trusted 2048-bit certs failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "system trusted 2048-bit certs failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"*.badssl.com", @"badssl.com"]); + XCTAssertTrue([self runTrust:certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "system trusted 2048-bit certs failed for EAP"); + CFReleaseNull(eapPolicy); +} +#endif // !TARGET_OS_BRIDGE + +- (void)test2048_appTrustedLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf2048SSL, sizeof(_leaf2048SSL)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _rootSSL, sizeof(_rootSSL)); + + NSArray *certs = @[ (__bridge id)leaf]; + NSArray *anchor = @[ (__bridge id)root ]; + CFReleaseNull(leaf); + CFReleaseNull(root); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "anchor trusted 2048-bit cert failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "anchor trusted 2048-bit cert failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "anchor trusted 2048-bit cert failed for EAP"); + CFReleaseNull(eapPolicy); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have trust settings +- (void)test2048_trustSettingsOnRoot_TestLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf2048SSL, sizeof(_leaf2048SSL)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _rootSSL, sizeof(_rootSSL)); + NSArray *certs = @[ (__bridge id)leaf, (__bridge id)root ]; + CFReleaseNull(leaf); + + id persistentRef = [self addTrustSettingsForCert:root]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on root, 2048-bit leaf failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on root, 2048-bit leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on root, 2048-bit leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(root); +} + +- (void)test2048_trustSettingsOnLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _leaf2048SSL, sizeof(_leaf2048SSL)); + NSArray *certs = @[ (__bridge id)leaf ]; + + id persistentRef = [self addTrustSettingsForCert:leaf]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on 2048-bit leaf failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on 2048-bit leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on 2048-bit leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} +#endif // !TARGET_OS_BRIDGE + +@end diff --git a/tests/TrustTests/EvaluationTests/KeySizeTests_data.h b/tests/TrustTests/EvaluationTests/KeySizeTests_data.h new file mode 100644 index 00000000..e749eac0 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/KeySizeTests_data.h @@ -0,0 +1,1362 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_KEY_SIZE_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_KEY_SIZE_TESTS_H_ + +const uint8_t prt_forest_fi_certificate[1797] = { + 0x30,0x82,0x07,0x01,0x30,0x82,0x05,0xe9,0xa0,0x03,0x02,0x01,0x02,0x02,0x11,0x00,0xfa,0x69,0x1a,0xa7, + 0xbf,0x1b,0x93,0xbe,0x97,0x11,0xb0,0xfe,0xfc,0xa8,0x8d,0x8c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86, + 0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x39,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, + 0x46,0x49,0x31,0x0f,0x30,0x0d,0x06,0x03,0x55,0x04,0x0a,0x13,0x06,0x53,0x6f,0x6e,0x65,0x72,0x61,0x31, + 0x19,0x30,0x17,0x06,0x03,0x55,0x04,0x03,0x13,0x10,0x53,0x6f,0x6e,0x65,0x72,0x61,0x20,0x43,0x6c,0x61, + 0x73,0x73,0x32,0x20,0x43,0x41,0x30,0x1e,0x17,0x0d,0x31,0x30,0x31,0x32,0x30,0x31,0x30,0x39,0x33,0x39, + 0x33,0x33,0x5a,0x17,0x0d,0x31,0x33,0x31,0x31,0x33,0x30,0x30,0x39,0x33,0x39,0x33,0x33,0x5a,0x30,0x57, + 0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x46,0x49,0x31,0x16,0x30,0x14,0x06,0x03,0x55, + 0x04,0x0a,0x0c,0x0d,0x50,0x52,0x54,0x2d,0x46,0x6f,0x72,0x65,0x73,0x74,0x20,0x4f,0x79,0x31,0x16,0x30, + 0x14,0x06,0x03,0x55,0x04,0x0b,0x0c,0x0d,0x54,0x69,0x65,0x74,0x6f,0x68,0x61,0x6c,0x6c,0x69,0x6e,0x74, + 0x6f,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0c,0x0f,0x2a,0x2e,0x70,0x72,0x74,0x2d,0x66,0x6f, + 0x72,0x65,0x73,0x74,0x2e,0x66,0x69,0x30,0x82,0x04,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, + 0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x04,0x0f,0x00,0x30,0x82,0x04,0x0a,0x02,0x82,0x04,0x01,0x00, + 0xbc,0x62,0x25,0x57,0xbc,0x71,0xb8,0xa9,0x5b,0x0e,0x04,0xbc,0xc4,0x0e,0xf1,0x0e,0x1f,0x20,0xd2,0xf4, + 0x4f,0x23,0xfe,0x14,0x54,0x34,0x81,0xd3,0x5b,0xdd,0x74,0xed,0xa1,0xbe,0x91,0x99,0x9d,0x02,0xb9,0x36, + 0x70,0x43,0x5d,0x73,0xa6,0xe5,0x70,0x7b,0x0e,0x0c,0x3f,0x33,0xbb,0x71,0xd6,0xd4,0x22,0xb0,0xeb,0xf5, + 0x6e,0x07,0x7c,0xe7,0xc7,0xd1,0x20,0x64,0x72,0x4e,0xae,0x5e,0xae,0xaf,0x08,0xfb,0x7d,0x6d,0xdb,0x69, + 0x5a,0x31,0x73,0x7d,0xbd,0x53,0xcb,0x04,0x69,0x6d,0x74,0x56,0x6c,0xbc,0x84,0xa6,0x01,0x39,0x37,0x0c, + 0xb9,0x5c,0x2e,0x78,0x50,0x3a,0x8d,0x1f,0xa2,0x33,0xf1,0xd2,0xc2,0x87,0x51,0xf4,0x92,0xc3,0xa7,0xaa, + 0xc8,0x36,0x51,0x1c,0xfb,0x77,0xbf,0xcf,0x24,0x11,0xfe,0xf4,0x11,0x2f,0x5c,0xdf,0x26,0xf6,0xb9,0x15, + 0xc1,0x46,0x75,0x83,0x40,0x77,0xa4,0x83,0x74,0xce,0xc0,0x29,0x31,0xd3,0xd8,0x68,0xfa,0x2e,0xcc,0x15, + 0x2c,0x59,0x5c,0xa7,0x96,0x65,0x8f,0x34,0x87,0x29,0x22,0x1d,0xde,0x65,0xc7,0x1c,0x5c,0xd8,0x33,0x22, + 0xf7,0x93,0xd9,0xcd,0x96,0x76,0x22,0xab,0x75,0x18,0x04,0xe7,0x65,0x2a,0xeb,0x42,0x75,0x17,0x13,0x12, + 0x00,0xe3,0xf4,0xd9,0xde,0xd1,0x9f,0x1c,0x61,0xee,0xf6,0xb9,0xf9,0x50,0xb3,0x1b,0x79,0x77,0x38,0x3c, + 0x6a,0xcc,0xa0,0x1d,0xe4,0xd7,0x43,0xca,0x8b,0x22,0xbf,0x77,0x33,0xea,0xaa,0x01,0xcf,0x1e,0xd0,0x0d, + 0x04,0x2b,0xec,0x42,0x7b,0xec,0x53,0xed,0xc7,0x4f,0x0c,0xac,0x29,0xb7,0x8b,0x92,0x14,0x3f,0x9b,0xc6, + 0xd8,0xa1,0x30,0x4d,0x5a,0x07,0x0e,0x1e,0x80,0x5f,0x38,0x66,0x4d,0xc1,0xad,0x2f,0xee,0xae,0x94,0x50, + 0x8e,0x38,0x2a,0x00,0x80,0xe2,0xc4,0x43,0x2e,0xd5,0xcd,0xca,0x3f,0x3d,0xcb,0x35,0x13,0x96,0xd2,0xdc, + 0x0e,0xe7,0x45,0x57,0x4b,0x8f,0xee,0xa1,0xce,0xe6,0x57,0x52,0xcd,0xd0,0x82,0xca,0x3b,0x87,0xf4,0x22, + 0xff,0x81,0x4b,0xf5,0xa3,0xda,0xc5,0xb6,0x67,0xb8,0xf4,0xaf,0xff,0x8d,0x4e,0x80,0xb5,0x22,0x80,0x3c, + 0x70,0xe4,0xa0,0xae,0xdc,0xcf,0x44,0xff,0x00,0x98,0x3f,0x19,0x7b,0x4c,0x3d,0xd8,0xa5,0xd8,0xe0,0x05, + 0x73,0x54,0x06,0x0c,0x4d,0x50,0xf8,0xd8,0x85,0x0b,0xa8,0x49,0xaa,0x97,0x87,0x3b,0x32,0xe8,0x58,0x22, + 0xee,0x34,0x1c,0x9f,0xe3,0x18,0xba,0x93,0x43,0xea,0xb7,0x78,0x35,0xa2,0xb5,0x1e,0x19,0x16,0x3b,0xb3, + 0xf5,0x12,0xe8,0x26,0x62,0x2d,0xd7,0x45,0xc3,0xa4,0x4b,0xda,0x38,0x48,0x00,0x3f,0x68,0x62,0xa2,0x83, + 0x9d,0x32,0x76,0x27,0x40,0x5d,0x0e,0x75,0xb1,0x08,0xdb,0x58,0xfa,0x20,0x62,0xf1,0x3f,0xbd,0x86,0x2f, + 0x7c,0x07,0x01,0x14,0x1d,0x19,0x61,0xee,0x0a,0x85,0xbf,0xc7,0x4f,0x4a,0x06,0xc0,0xaf,0x44,0x5d,0x6f, + 0xc3,0x53,0x23,0xcb,0xdf,0x40,0x7a,0x18,0xa1,0x34,0x80,0x18,0x86,0xfe,0xe3,0x87,0xce,0x30,0x53,0x33, + 0x1c,0x45,0x4a,0xb4,0xe1,0x8c,0x9b,0x4b,0xf5,0x2c,0x7c,0x13,0x56,0x37,0x8a,0x94,0x24,0xdb,0x3a,0x4b, + 0x80,0xb1,0x26,0x57,0x5a,0x75,0x1c,0x44,0xc5,0xf7,0x67,0xb4,0x61,0x87,0xe8,0x2e,0xd9,0xe1,0xb9,0x45, + 0xcc,0xdc,0xdf,0x3b,0x8c,0xce,0xd0,0x46,0x6b,0x87,0xb5,0xa9,0xfe,0x35,0x87,0xe0,0xca,0xc6,0x7d,0xc8, + 0x86,0xc2,0xfe,0x89,0xec,0xa9,0x86,0x33,0x81,0xdc,0x41,0xb3,0xe7,0xc4,0x82,0x3a,0x81,0x05,0xbd,0x8b, + 0x92,0xb2,0x6a,0x2c,0x3c,0xca,0xd0,0x22,0xff,0xc8,0x8f,0xf0,0x5f,0x0e,0xfb,0x0b,0x36,0x64,0x6a,0x12, + 0x77,0x2d,0x8a,0x38,0xde,0x7d,0xed,0xc9,0xa7,0xc1,0x85,0x41,0xa2,0x7b,0xa5,0xdc,0x30,0x96,0xda,0xf8, + 0xb3,0xc8,0x21,0x56,0x3c,0xdb,0xe4,0x8c,0xb0,0xfb,0xec,0x0e,0x58,0x49,0x3c,0x75,0x3c,0xc2,0x41,0xbd, + 0xc0,0x81,0x37,0xc7,0x69,0x5a,0x41,0x86,0x18,0xe9,0x41,0x7f,0xba,0xff,0xc3,0x52,0x56,0xf9,0x7c,0x60, + 0x14,0xf9,0x66,0x4c,0x60,0xb6,0x3e,0x23,0xcd,0xd1,0x2d,0x4f,0x43,0x97,0xea,0xa3,0x37,0xa4,0x2a,0xa7, + 0x81,0x49,0x90,0xe3,0xb6,0x12,0x1b,0xac,0x78,0x57,0x20,0x51,0xb4,0x16,0x5e,0x58,0x61,0x0f,0x1e,0x35, + 0xbc,0x3f,0x44,0xc2,0x85,0xa5,0x61,0x8a,0x0a,0x7c,0x2e,0xb0,0x11,0x12,0xc6,0xc0,0xc8,0xcb,0xd8,0x13, + 0xc3,0x58,0xf1,0xcd,0x06,0x5f,0x90,0xa5,0xd7,0x74,0xbc,0x1a,0x9c,0xdc,0xab,0xde,0xea,0x36,0x67,0x41, + 0x4f,0x62,0x86,0xc6,0xfe,0x63,0x14,0x83,0x11,0xab,0xfb,0x61,0x38,0x11,0xce,0x01,0xe8,0xee,0x3a,0x21, + 0xbc,0xaa,0x4b,0xb0,0x8f,0x2f,0xcf,0x58,0xe6,0x55,0x61,0x38,0xa7,0xc3,0xaa,0x3b,0xb0,0x8c,0xf4,0x82, + 0xa0,0x96,0xc4,0x13,0x4a,0xc0,0xc8,0x93,0xb7,0x3d,0x28,0x05,0xb9,0xc8,0x4c,0xe8,0x57,0xda,0x56,0x8b, + 0xda,0x27,0xab,0xbf,0x7e,0x66,0x43,0xdc,0x57,0x09,0xdc,0x88,0x8e,0xfb,0xa7,0x63,0x41,0xfb,0xf1,0x67, + 0xb5,0xe1,0x84,0x5d,0x1d,0xe3,0xb4,0xc6,0x40,0x97,0xf8,0x4d,0xfc,0x00,0xcd,0x56,0xc2,0xab,0xff,0x49, + 0x93,0xff,0x46,0x56,0x9b,0xee,0x6d,0xa0,0x5d,0xf4,0x78,0x36,0x0e,0xf6,0xc9,0x9c,0x79,0x89,0xf9,0x9c, + 0xa7,0x3e,0xa0,0x8d,0x62,0x7c,0xdc,0x83,0x0a,0xfc,0x46,0x96,0x31,0xd3,0x56,0xc6,0xea,0x7f,0x1d,0xaa, + 0x49,0xd1,0x8b,0x54,0xa2,0x6e,0x59,0x8c,0x2a,0xec,0x3a,0xd7,0xda,0xd2,0xc1,0xfc,0x1d,0x78,0x55,0xce, + 0xd8,0x0c,0x1d,0x7e,0x99,0xf8,0x5e,0x3c,0x2d,0xec,0x63,0xe2,0xda,0xa1,0x68,0x6f,0x28,0x2e,0xb4,0xef, + 0x07,0xc4,0xa8,0x65,0xc7,0xfd,0x6b,0x0f,0x83,0x23,0xf8,0xc2,0xc9,0x55,0xfa,0xa4,0xa8,0x6a,0xab,0x12, + 0xf4,0x89,0x42,0x26,0x72,0xd1,0x82,0x2f,0x62,0x14,0xb6,0x04,0x23,0x20,0xb6,0xd4,0xef,0x59,0x8a,0x40, + 0x43,0xd7,0x72,0xe0,0x5b,0x0c,0xb0,0x73,0x6f,0x6a,0x87,0xc1,0x82,0x50,0x20,0xdb,0xaa,0xf8,0x8d,0x70, + 0xb6,0x39,0x46,0xe0,0x68,0xc4,0xab,0xea,0xd1,0x31,0xad,0xf7,0x05,0xfb,0x3a,0x3c,0x2e,0x66,0x4f,0xc6, + 0x0d,0xf9,0xb8,0x29,0xec,0xdc,0xfc,0x81,0x56,0x2b,0xb0,0xad,0xd2,0x12,0x8f,0x69,0x70,0x18,0x27,0x16, + 0xf9,0xf0,0x40,0x93,0xef,0x6b,0x95,0x96,0xcd,0x5f,0xe9,0x5a,0x7b,0xad,0x7f,0x98,0xa7,0x6a,0xe5,0x17, + 0xeb,0xc3,0xdd,0xc9,0x02,0x03,0x01,0x00,0x01,0xa3,0x81,0xe5,0x30,0x81,0xe2,0x30,0x13,0x06,0x03,0x55, + 0x1d,0x23,0x04,0x0c,0x30,0x0a,0x80,0x08,0x4a,0xa0,0xaa,0x58,0x84,0xd3,0x5e,0x3c,0x30,0x19,0x06,0x03, + 0x55,0x1d,0x20,0x04,0x12,0x30,0x10,0x30,0x0e,0x06,0x0c,0x2b,0x06,0x01,0x04,0x01,0x82,0x0f,0x02,0x03, + 0x01,0x01,0x02,0x30,0x72,0x06,0x03,0x55,0x1d,0x1f,0x04,0x6b,0x30,0x69,0x30,0x67,0xa0,0x65,0xa0,0x63, + 0x86,0x61,0x6c,0x64,0x61,0x70,0x3a,0x2f,0x2f,0x31,0x39,0x34,0x2e,0x32,0x35,0x32,0x2e,0x31,0x32,0x34, + 0x2e,0x32,0x34,0x31,0x3a,0x33,0x38,0x39,0x2f,0x63,0x6e,0x3d,0x53,0x6f,0x6e,0x65,0x72,0x61,0x25,0x32, + 0x30,0x43,0x6c,0x61,0x73,0x73,0x32,0x25,0x32,0x30,0x43,0x41,0x2c,0x6f,0x3d,0x53,0x6f,0x6e,0x65,0x72, + 0x61,0x2c,0x63,0x3d,0x46,0x49,0x3f,0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x72,0x65, + 0x76,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x6c,0x69,0x73,0x74,0x3b,0x62,0x69,0x6e,0x61,0x72,0x79,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,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04, + 0x14,0x85,0xc2,0x31,0x35,0x4f,0x93,0x92,0x9d,0x8a,0xbc,0x32,0x7d,0x1b,0xf0,0xaa,0x96,0xb1,0x03,0x86, + 0x71,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01, + 0x00,0x00,0x9e,0x75,0x2b,0x95,0x6a,0x96,0x12,0x24,0xd5,0x04,0x6c,0x34,0x0a,0x58,0x5a,0x7d,0x59,0xb9, + 0x03,0x23,0x13,0xc3,0xf5,0x24,0x57,0x33,0x8d,0xca,0x5f,0xd8,0x26,0xff,0x64,0x46,0x13,0x40,0xe5,0x04, + 0xb2,0xba,0x92,0xa5,0xa6,0xa3,0xd9,0x2b,0xff,0x05,0xef,0xce,0x3c,0x28,0xe8,0x1b,0xa3,0x10,0x8a,0xdd, + 0x3d,0x3a,0x0a,0xe1,0x07,0x3c,0xb4,0xf6,0xbb,0xeb,0xb5,0xf2,0x05,0xe8,0xd7,0x16,0x3e,0xe5,0x15,0x49, + 0xdf,0x8d,0x34,0xb8,0x1b,0xd4,0xf2,0x65,0xa0,0x70,0x80,0xd0,0xbf,0xa5,0x74,0x5d,0xfb,0xd4,0x52,0x3b, + 0x54,0xca,0x32,0xba,0xf7,0xe3,0x90,0xa5,0xa8,0xad,0xd0,0xe5,0x5d,0x18,0x18,0x87,0x60,0xb0,0xf3,0xf9, + 0x62,0x20,0x77,0xaa,0x0f,0xdd,0x16,0x4c,0x01,0x3a,0xb1,0x1f,0x85,0x7e,0x01,0x04,0x5f,0xf1,0x37,0x36, + 0xe3,0x3a,0xc1,0xa3,0x7c,0x33,0xca,0xce,0x0b,0xb9,0x34,0xe2,0xe1,0xe6,0xed,0x24,0xc1,0xc3,0xc7,0x74, + 0x8f,0x22,0x2c,0x6e,0xcb,0x5c,0x7a,0x61,0x99,0xde,0xea,0x13,0xe1,0xa8,0xa1,0x94,0xd0,0x85,0x65,0x65, + 0xed,0x97,0x14,0x6e,0x97,0xc9,0xcf,0x34,0x7c,0xf2,0x68,0xeb,0xc2,0x7d,0x03,0x53,0xf5,0xdb,0xa1,0x11, + 0x8d,0xda,0xcc,0x26,0x13,0xaa,0x43,0x76,0x04,0x9b,0x85,0x89,0xc3,0x29,0xd8,0xb5,0x54,0x81,0x09,0xf5, + 0x18,0x52,0xa5,0x38,0x4a,0x00,0xc6,0x1d,0x4d,0x5a,0x15,0xa0,0xfd,0xf7,0x58,0x27,0xcd,0x6b,0x56,0x6b, + 0xee,0x7d,0x73,0xd3,0xfd,0x6c,0xb6,0xb1,0x3b,0xbd,0xbf,0x5b,0x4a,0x6c,0xd3,0x1c,0x47 +}; + +// MARK: RSA Key Size Test Certs + +/* RSA Key Size Test Cert Chains + * _root512 -> _int2048A -> _leaf2048A + * _root2048 -> _int512 -> _leaf2048B + * _root2048 -> _int2048B -> _leaf512 + * _root2048 -> _int2048B -> _leaf1024 + * _root2048 -> _int2048B -> _leaf2048C + */ + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Root CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Root CA */ +unsigned char _root512[600]={ + 0x30,0x82,0x02,0x54,0x30,0x82,0x01,0xFE,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xAF,0x64,0x99,0x71,0x1A,0x67,0x40,0xD8,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8A,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14, + 0x35,0x31,0x32,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F, + 0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33, + 0x30,0x33,0x32,0x34,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x31,0x35,0x32,0x33,0x30, + 0x33,0x32,0x34,0x5A,0x30,0x81,0x8A,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,0x14,0x30, + 0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14,0x35,0x31,0x32, + 0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,0x30,0x5C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01, + 0x05,0x00,0x03,0x4B,0x00,0x30,0x48,0x02,0x41,0x00,0xBE,0x86,0xC0,0x0C,0x4A,0x75, + 0xC7,0xEC,0x8D,0xBF,0x1E,0xFC,0x70,0x58,0x23,0x5E,0xF0,0x61,0x1E,0x59,0x74,0x41, + 0x88,0x19,0x87,0x20,0x87,0x77,0xE3,0x08,0x8A,0x68,0x80,0xE4,0xED,0x35,0xE7,0x85, + 0x52,0x30,0xF7,0xF1,0xC4,0x16,0xED,0x59,0xE8,0xF3,0x40,0x23,0x8E,0x30,0x72,0x40, + 0x22,0x26,0x15,0x9F,0xE4,0x97,0xEB,0x56,0xE8,0xAF,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,0x03,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,0x14,0xE9,0x8B,0x3E,0x9D,0x8A,0xA7,0xCA,0x70,0x97,0x2B,0x9A,0x2C,0x31, + 0xC7,0xF9,0xA2,0x5A,0x4B,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, + 0x01,0x01,0x0B,0x05,0x00,0x03,0x41,0x00,0x6E,0x14,0x08,0x64,0xCD,0x84,0xDB,0xBF, + 0xA4,0x2B,0x5F,0x51,0x5F,0x2D,0x00,0x46,0xA5,0x20,0x28,0x53,0x74,0x90,0x6D,0x24, + 0xD4,0xB9,0x7E,0x0D,0xFD,0x5E,0x65,0x7F,0xB5,0x88,0x96,0xD8,0x54,0xBA,0xBD,0x09, + 0x1C,0x89,0x91,0x5B,0xC4,0x4B,0xD4,0x6B,0xE4,0x4B,0x7A,0xBF,0x62,0x36,0x97,0xF7, + 0x58,0xAC,0xCD,0x9C,0xAF,0x9B,0x02,0x68, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ +unsigned char _root2048[996]={ + 0x30,0x82,0x03,0xE0,0x30,0x82,0x02,0xC8,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xD2,0xA0,0x17,0x6E,0xF4,0xB7,0xF3,0x96,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8B,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, + 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, + 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32, + 0x33,0x30,0x34,0x31,0x30,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x31,0x35,0x32,0x33, + 0x30,0x34,0x31,0x30,0x5A,0x30,0x81,0x8B,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,0x14, + 0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30, + 0x34,0x38,0x2D,0x62,0x69,0x74,0x20,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,0xEE,0x68,0xB9,0x94,0x15,0x11,0x2F,0x35,0x36,0xBC,0x9D,0x63, + 0x25,0x8E,0x55,0xE4,0x17,0xE0,0x60,0x9C,0x6D,0x71,0x4C,0x30,0x7B,0xB7,0xEE,0x42, + 0x2D,0xE9,0x05,0x4C,0x41,0x3A,0x19,0x97,0x77,0xCC,0x4C,0xFF,0x81,0x52,0xE8,0xDF, + 0xB7,0x1A,0x75,0x1F,0xD1,0xD7,0x4D,0x21,0x5E,0x79,0xDF,0x7E,0xCF,0x45,0x47,0xF5, + 0x4D,0x05,0xD6,0xB1,0xF3,0xEA,0xF8,0x28,0xD8,0xAC,0x2C,0xCE,0x83,0xBF,0xA5,0x70, + 0x6F,0x5B,0x46,0x39,0xF6,0xC1,0x78,0x56,0x31,0x24,0x7E,0x15,0xCE,0x04,0x50,0x99, + 0x30,0xDA,0xF0,0xAE,0x23,0xDD,0x86,0x54,0xAD,0xBC,0x55,0x45,0x93,0xCC,0xC8,0xE7, + 0x16,0x46,0x00,0x34,0x2C,0x8C,0x8F,0x31,0xED,0x08,0x3F,0xD9,0xA6,0x90,0x32,0x37, + 0x1B,0xCD,0xD4,0x16,0x83,0xEE,0xF9,0x52,0x80,0x3E,0x27,0x26,0xEF,0xEF,0xF9,0xFD, + 0xA6,0xD5,0x38,0x83,0xD9,0x8F,0xB6,0xF0,0xA1,0x0D,0x4F,0x89,0x8D,0x7C,0x14,0x7D, + 0x8F,0x7A,0x84,0xF9,0xCB,0x8C,0x68,0x9E,0xF3,0x0E,0x2C,0x68,0xBF,0x37,0x69,0x2A, + 0x67,0x90,0x7D,0xAF,0xF0,0x7B,0x38,0xBC,0xB3,0x77,0xD1,0xDD,0xF4,0x5E,0x3F,0xA0, + 0x48,0xE8,0xBA,0x59,0xD8,0xB6,0xFF,0x51,0x7C,0xB8,0xCE,0xAE,0x02,0x5A,0x71,0x1E, + 0xD6,0x5A,0x0A,0x55,0x27,0x29,0x9C,0xC2,0xF6,0x8B,0x0E,0x0D,0xFA,0xF3,0x3F,0x60, + 0x17,0xE8,0xFA,0x98,0xC0,0x92,0xD7,0x14,0x9B,0xD1,0x3E,0x03,0xE4,0x8D,0x58,0xFF, + 0x4C,0x01,0x77,0x74,0x83,0x01,0xA6,0xB1,0x81,0x34,0x26,0x0D,0xF8,0xAA,0x08,0xF2, + 0xDC,0xEA,0x32,0x11,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, + 0x03,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,0xCA,0x4D,0x8B,0xBD, + 0x98,0x36,0x22,0xF8,0xA9,0x21,0x8E,0xEA,0xFC,0xE6,0xD7,0x17,0x81,0xA7,0xE2,0x12, + 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, + 0x82,0x01,0x01,0x00,0x99,0x99,0xDB,0x59,0xEE,0x32,0x98,0x1C,0xE4,0x62,0xE4,0xF9, + 0xA5,0xE9,0xA4,0x3F,0x49,0x57,0x37,0x71,0x34,0x3E,0x68,0xAE,0x27,0xB4,0xAF,0xCB, + 0x96,0xFD,0xA8,0x0A,0xE7,0x0A,0x22,0x7C,0x5E,0x78,0x95,0xA9,0x67,0xAF,0xB4,0xDD, + 0x09,0xD1,0xE5,0x0C,0x6B,0xC6,0xD8,0x1A,0xE3,0x91,0x5F,0xBD,0xD0,0xB9,0x0F,0x1D, + 0xB9,0xB7,0xF1,0xC7,0x64,0xCA,0xAB,0x69,0x6E,0xD0,0x61,0xB3,0x9F,0x27,0x1E,0x06, + 0xB6,0x42,0x84,0xAB,0x6F,0xE7,0x2B,0xBC,0x04,0x28,0x64,0xC2,0xC0,0x1D,0x43,0xFF, + 0x2A,0x1D,0x3F,0x92,0xA1,0xD7,0xD5,0xFB,0x04,0xF9,0x57,0x9F,0x78,0x87,0x8C,0xDB, + 0xB3,0x3F,0x41,0x96,0x8E,0x65,0x50,0x39,0xE7,0xD0,0x8A,0x39,0x29,0x68,0x12,0x11, + 0x44,0xDD,0x7B,0x86,0x59,0xAF,0x40,0xEA,0x78,0xD9,0xDD,0xB5,0xDB,0xA7,0x7F,0xD4, + 0xBA,0x94,0x8D,0x7D,0xA5,0xD0,0xAA,0x48,0x42,0x1E,0x6C,0x71,0x33,0x49,0xCA,0x0D, + 0xF5,0x8D,0x10,0xD0,0x3E,0xF8,0xD3,0x35,0xAE,0x83,0xCA,0x02,0x23,0xC2,0xCD,0x21, + 0x75,0x9B,0x2C,0xE0,0xF7,0x23,0x26,0x04,0xED,0x78,0xE8,0x29,0x33,0x87,0x65,0x98, + 0x4C,0x7E,0xC3,0x61,0xB5,0xDB,0x66,0xBD,0x9D,0x3D,0xC9,0x02,0x7A,0xB8,0xA2,0x7C, + 0x81,0x8B,0x10,0xB5,0x97,0x63,0x85,0x2B,0x19,0x94,0xB3,0x4C,0x8D,0xED,0x76,0xCE, + 0x31,0x49,0xCC,0x22,0x67,0xFB,0xDA,0x6A,0x0A,0xE2,0x56,0xCD,0x51,0x6A,0x6E,0x54, + 0xDF,0x04,0x1A,0xBE,0x77,0xB9,0x28,0x2F,0xCA,0xA5,0xA5,0xF4,0xF1,0xE5,0x12,0x1B, + 0x2D,0x60,0xB7,0xA7, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 1 */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Root CA */ +unsigned char _int2048A[809]={ + 0x30,0x82,0x03,0x25,0x30,0x82,0x02,0xCF,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x76, + 0xCD,0xF6,0x90,0x52,0xAA,0x72,0x81,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8A,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, + 0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C, + 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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14,0x35, + 0x31,0x32,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74, + 0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30,0x32,0x30, + 0x38,0x34,0x31,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x30,0x32,0x30,0x38, + 0x34,0x31,0x5A,0x30,0x77,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A, + 0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C, + 0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20, + 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x31,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,0xF2,0x04, + 0x31,0xBD,0x86,0x8D,0x5A,0x0C,0xF1,0xDF,0x48,0xBE,0xD3,0x98,0x61,0x50,0x75,0x95, + 0xCB,0x1D,0xE3,0x0D,0x17,0x3F,0xEC,0xD6,0xEA,0x5C,0xB7,0x75,0xEB,0x3B,0x73,0x09, + 0x69,0x35,0xD2,0x82,0xF8,0x08,0xAE,0xF0,0xF5,0xC1,0xCA,0xFB,0x84,0x3E,0x36,0xAE, + 0xCB,0xF9,0x59,0x61,0xE2,0x18,0xED,0x77,0xF8,0xCC,0x75,0x3E,0x4B,0x98,0x81,0x2B, + 0x04,0x04,0xEE,0xC5,0x79,0x64,0xBB,0x77,0xED,0xA1,0xC3,0x6C,0x80,0xD7,0xFE,0xAE, + 0x05,0x58,0xBD,0x42,0x26,0xD5,0xC4,0xE5,0x4E,0x26,0x09,0x74,0x0A,0xAE,0x49,0x31, + 0x80,0x4E,0x25,0xD8,0x2C,0x87,0x32,0xEB,0xD9,0x3D,0xFB,0x5F,0x21,0x6B,0x0E,0xC7, + 0x83,0x4A,0x6C,0x2C,0xB1,0x82,0xEC,0xDF,0xD2,0x65,0x92,0x32,0x5C,0x30,0xEA,0x48, + 0xC7,0x13,0x39,0xB7,0x4D,0x81,0x79,0x1C,0x17,0x31,0xC1,0x83,0x42,0xFB,0xC3,0x1B, + 0xF0,0xA0,0x45,0xED,0xAA,0xDC,0x02,0x73,0x4B,0x48,0x76,0xAE,0x68,0x80,0x93,0x51, + 0x3D,0x79,0x7F,0x9E,0x53,0xD3,0x60,0x5A,0x4F,0x5B,0x2E,0xB8,0x13,0x6A,0x5F,0x27, + 0x7E,0x09,0x80,0x61,0xCF,0x41,0xDE,0xD1,0x9F,0xFA,0xEF,0x42,0xD0,0xB1,0x81,0x69, + 0x03,0x91,0x1A,0xD9,0xE2,0x33,0x34,0x78,0xFE,0x45,0xB1,0x23,0x39,0x20,0xBC,0x2D, + 0xA5,0x8A,0xB2,0x84,0xEF,0x2A,0xF4,0x6C,0x2E,0xD1,0xEE,0x61,0x38,0x8F,0xA0,0xB0, + 0x0D,0xC4,0x0A,0x3D,0xB9,0x2C,0x6D,0x77,0xB5,0xE3,0x06,0x8B,0xB4,0x0D,0xA7,0x71, + 0xFD,0x38,0x0B,0x1F,0x5C,0x1C,0x9F,0x2F,0x2E,0xA4,0xD4,0xE8,0x6F,0x02,0x03,0x01, + 0x00,0x01,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, + 0x04,0x14,0x03,0x99,0x06,0x5B,0xDA,0x2C,0xBA,0x9B,0x66,0x0A,0x5A,0x7B,0xAB,0x99, + 0xA5,0x7F,0x72,0xA9,0xD4,0xF7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, + 0x16,0x80,0x14,0x14,0xE9,0x8B,0x3E,0x9D,0x8A,0xA7,0xCA,0x70,0x97,0x2B,0x9A,0x2C, + 0x31,0xC7,0xF9,0xA2,0x5A,0x4B,0x72,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x41,0x00,0xAE,0x2A,0xA7,0x7F,0xE7,0xC9,0xE4, + 0xAA,0x2C,0x7F,0x04,0x5D,0x9B,0x0E,0x01,0x47,0x1E,0xB1,0x0E,0x35,0xD7,0x1F,0xAC, + 0x8E,0xA7,0xCC,0xAD,0x16,0xAC,0x47,0xDC,0x5E,0x13,0x1C,0x15,0x05,0x89,0x56,0xC0, + 0x76,0x55,0x96,0xA0,0x8B,0xBD,0x3B,0xD7,0x93,0x08,0xBA,0xD0,0x7E,0x64,0x7A,0xB1, + 0x74,0xE0,0x82,0x2B,0xE4,0x12,0xA3,0x4D,0x0B, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test SubCA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ +unsigned char _int512[802]={ + 0x30,0x82,0x03,0x1E,0x30,0x82,0x02,0x06,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xBE,0x29,0xEC,0x6D,0x40,0x7E,0x44,0x98,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8B,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, + 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, + 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30, + 0x32,0x30,0x39,0x32,0x32,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x30,0x32, + 0x30,0x39,0x32,0x32,0x5A,0x30,0x74,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,0x14,0x30,0x12,0x06,0x03,0x55, + 0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1B, + 0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x0C,0x12,0x35,0x31,0x32,0x2D,0x62,0x69,0x74, + 0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x30,0x5C,0x30,0x0D,0x06, + 0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x4B,0x00,0x30, + 0x48,0x02,0x41,0x00,0xF2,0xD1,0x57,0xDD,0xA6,0xBC,0x2B,0xBC,0x22,0x7B,0x5D,0xC5, + 0x3A,0x73,0xCE,0x80,0x88,0xD7,0xDF,0x45,0xBE,0x01,0x22,0xA7,0xC2,0x7E,0x35,0x1F, + 0x74,0x02,0xA4,0xE3,0xD9,0xF3,0xE4,0x35,0xE9,0xB0,0xBD,0x71,0xC7,0x19,0x80,0xA8, + 0x9F,0xD7,0x62,0xFC,0x46,0xA6,0x84,0xF2,0xB0,0x9F,0xF5,0x1C,0xF1,0xA5,0x18,0x58, + 0x76,0x49,0x3F,0xF9,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D, + 0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9E,0x85,0x9A,0xA5,0x88,0x09,0xB0, + 0x93,0x9B,0xB4,0xE5,0xCE,0x68,0x99,0x93,0xE9,0x79,0xE9,0x7C,0x98,0x30,0x1F,0x06, + 0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xCA,0x4D,0x8B,0xBD,0x98,0x36, + 0x22,0xF8,0xA9,0x21,0x8E,0xEA,0xFC,0xE6,0xD7,0x17,0x81,0xA7,0xE2,0x12,0x30,0x0D, + 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01, + 0x01,0x00,0xD7,0x94,0x1E,0x53,0x9B,0xB5,0xC6,0x02,0x26,0xC2,0x7F,0xB2,0xD1,0x36, + 0x63,0xD5,0xEE,0x35,0x66,0x92,0x48,0xEF,0xD1,0xB4,0xDD,0xD7,0xE1,0xDF,0x05,0xF2, + 0x76,0x74,0x28,0x75,0xC1,0x51,0x66,0x6E,0x2C,0x2A,0x8C,0x82,0x34,0xD3,0x43,0x0F, + 0x22,0x12,0x01,0xD6,0x7D,0xFA,0x0E,0xF0,0x52,0xB0,0x20,0x1E,0x25,0x2B,0x39,0xA5, + 0x2C,0xD5,0x9F,0x89,0x87,0x42,0xAC,0xCB,0xEA,0x56,0xB6,0x8A,0x65,0x40,0xD9,0x19, + 0x84,0xF3,0x37,0x71,0x1C,0x0A,0x5E,0x2C,0xBB,0xB1,0xB4,0xA0,0x99,0x35,0x5A,0x0F, + 0x62,0xE0,0x7A,0x91,0x2A,0x14,0x47,0xF9,0x2E,0x3D,0x7C,0x53,0x98,0x23,0x63,0x3D, + 0x47,0x46,0x9E,0x7C,0x49,0x09,0x50,0xEA,0xCE,0xB4,0x1A,0x17,0x4E,0x6E,0x6D,0x0A, + 0x99,0xF5,0xAD,0x6E,0x88,0xF1,0xCE,0xF0,0xD7,0xB4,0x3A,0x6E,0xE7,0x97,0x4C,0x53, + 0x04,0x1D,0xB3,0x08,0x49,0x63,0x14,0x25,0x99,0xA7,0xCD,0x82,0xD5,0xF9,0xB9,0xCB, + 0x89,0x83,0xCD,0xD5,0x9E,0x57,0xBA,0x90,0x83,0x5F,0x31,0xB4,0x3C,0x3C,0x46,0xD0, + 0xA1,0xA7,0x7F,0x7A,0xF8,0x18,0x4B,0xC0,0xA9,0x0E,0x47,0x9A,0xE4,0x9B,0x6F,0x1B, + 0xAB,0x8F,0x71,0x54,0x8E,0xA6,0x0B,0xCC,0x16,0xE2,0xCD,0x38,0xA8,0xC2,0x0E,0x20, + 0xB0,0x6E,0x9C,0x8B,0x02,0xDF,0xC3,0xCE,0xB8,0xBB,0x92,0x50,0x27,0xB2,0x81,0xC5, + 0x48,0x16,0x82,0xC4,0xB1,0x5E,0x5F,0x43,0x47,0xF9,0x6F,0x8A,0x81,0x95,0x93,0xB2, + 0x78,0x24,0x67,0xEB,0xCB,0xC1,0xA4,0x4F,0x23,0x11,0xDF,0x33,0xD0,0x5F,0x79,0x26, + 0x1F,0x81, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Root CA */ +unsigned char _int2048B[1005]={ + 0x30,0x82,0x03,0xE9,0x30,0x82,0x02,0xD1,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xBE,0x29,0xEC,0x6D,0x40,0x7E,0x44,0x99,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8B,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, + 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F, + 0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30, + 0x32,0x30,0x39,0x33,0x39,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x30,0x32, + 0x30,0x39,0x33,0x39,0x5A,0x30,0x77,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,0x14,0x30,0x12,0x06,0x03,0x55, + 0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E, + 0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D,0x62,0x69, + 0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,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, + 0x74,0x33,0x7D,0x7B,0x48,0x2C,0x25,0x5F,0x73,0x9C,0x09,0xCC,0xBC,0x90,0x38,0xDF, + 0x41,0x06,0xD2,0x1F,0x92,0xD3,0xF0,0x94,0xBC,0x97,0x39,0x17,0x68,0x76,0xE0,0x9C, + 0x68,0x78,0xD3,0xE7,0xC7,0xBE,0xC8,0xD8,0xBE,0x2F,0x94,0x93,0x3E,0xCF,0x24,0x4D, + 0xB3,0xCF,0xA8,0xC1,0xDF,0xF3,0xC5,0x6A,0x23,0xFC,0x7C,0xAC,0x20,0xC1,0x28,0x7D, + 0x61,0x50,0xEB,0x1D,0xD1,0xAE,0xD3,0xCC,0xEC,0x67,0x95,0x0B,0x6C,0x06,0xFE,0x6C, + 0xC5,0xBC,0xBA,0xCB,0xDF,0x2D,0x0E,0xBD,0x1E,0x67,0xF9,0xD0,0xF0,0x71,0x91,0x96, + 0xD4,0x2E,0x4C,0x1A,0xC0,0xEA,0xD7,0x8B,0x09,0xDF,0xC2,0x89,0x30,0xAD,0x48,0xC4, + 0xEE,0x22,0x7A,0x8A,0xD9,0x8E,0x71,0xD1,0xE8,0x3B,0x4D,0x2A,0xB6,0x41,0x32,0x04, + 0x66,0x5B,0x5C,0x5C,0x8D,0x0E,0xFC,0x80,0x2A,0x26,0x23,0xF8,0xEA,0x77,0xA1,0xEC, + 0xF1,0x2F,0x63,0xB0,0xB3,0xA0,0x8F,0x53,0xDB,0xF2,0x7E,0x9E,0xF8,0x8F,0x9B,0x4B, + 0xA2,0x57,0xB5,0xE9,0x47,0xEF,0x86,0xEE,0xAE,0x88,0xB5,0xF7,0x6E,0x42,0x79,0x99, + 0x84,0xB8,0x7F,0x48,0x47,0x25,0x52,0x88,0x9C,0x1F,0xAB,0x7D,0xCE,0x8B,0x21,0x39, + 0x7B,0xF6,0xD1,0xB8,0x2B,0xCE,0xDA,0x21,0x15,0x3A,0xF0,0x0D,0xD1,0x59,0x0F,0xF4, + 0xFF,0x6B,0xCF,0x71,0x5D,0xE9,0x8F,0xE7,0xC1,0x4F,0xF7,0xEA,0xB8,0xE5,0x9F,0x16, + 0xB7,0x17,0x5A,0x27,0x35,0x2C,0xDE,0x18,0xF6,0x55,0xDC,0x05,0x18,0xD2,0x12,0x0C, + 0x35,0x44,0x88,0xFC,0xEC,0x5E,0x46,0x17,0xDA,0x48,0xD5,0x73,0xD2,0x73,0xEB,0x02, + 0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, + 0x04,0x16,0x04,0x14,0x0C,0x3F,0x97,0x58,0x60,0x67,0x21,0xC9,0xDB,0xD4,0x23,0x58, + 0x60,0x8E,0xC1,0x3F,0x99,0x9F,0x12,0x78,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04, + 0x18,0x30,0x16,0x80,0x14,0xCA,0x4D,0x8B,0xBD,0x98,0x36,0x22,0xF8,0xA9,0x21,0x8E, + 0xEA,0xFC,0xE6,0xD7,0x17,0x81,0xA7,0xE2,0x12,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, + 0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x62,0x5B,0x7A, + 0xEA,0x51,0xBC,0x4B,0xE2,0xA6,0x3F,0xC9,0x71,0x1F,0x03,0x64,0x83,0x96,0x69,0x09, + 0x36,0x14,0xA3,0xCF,0xFB,0x7D,0x67,0xB5,0x24,0x12,0x10,0xCF,0xA2,0x38,0x41,0x60, + 0x73,0xDD,0x9F,0x78,0x3A,0xE2,0x57,0xBF,0x64,0x0A,0xE4,0xB5,0x97,0x64,0x38,0x6E, + 0x36,0xCE,0x49,0x5E,0x21,0x53,0x4E,0x77,0x20,0x1E,0xBE,0xE0,0x33,0xDB,0x99,0xF1, + 0xC9,0xE8,0xA8,0x29,0x0A,0x23,0xE9,0x8D,0x91,0xE3,0x65,0x03,0xCB,0x97,0xA5,0x3F, + 0xF1,0xBF,0x28,0x4D,0x6C,0x2E,0xA7,0xFE,0x65,0x57,0xBE,0x1B,0x64,0xCE,0xFB,0x4B, + 0x33,0x7C,0x79,0x9B,0xCE,0x57,0xBE,0xB3,0x11,0x44,0xC1,0xD8,0x83,0x88,0x01,0x02, + 0x7C,0x51,0x32,0x31,0xA5,0xE7,0xE2,0xD2,0x91,0xAB,0x4F,0x37,0xE7,0x8D,0xBC,0x44, + 0x93,0xC8,0x29,0x0D,0x68,0x30,0xDB,0x54,0x1A,0x42,0x92,0x54,0xC2,0x0D,0xBF,0x28, + 0x69,0x94,0x95,0x77,0xCA,0xDA,0x68,0xFA,0x12,0xF4,0x19,0xEE,0x81,0x8F,0x9C,0x22, + 0x04,0x89,0xDD,0x2F,0x0A,0x17,0xC5,0xB5,0x1C,0x3A,0x3F,0x13,0x77,0x21,0x49,0xFC, + 0xBF,0xB7,0x82,0x9A,0x37,0x8A,0x6D,0x10,0xF6,0x44,0xF2,0xD5,0xFB,0xBC,0xB6,0xC5, + 0x50,0xD7,0x9B,0x4D,0x6D,0x18,0x85,0xB7,0xE6,0x90,0xE1,0xD4,0x3F,0x16,0x8A,0x74, + 0x97,0x32,0x29,0x3C,0xCA,0xE2,0x9E,0xC6,0xEB,0xBA,0x7A,0x9B,0xF9,0xE8,0xC7,0xA5, + 0x01,0x29,0x38,0x5B,0x6D,0x13,0xFC,0x2D,0x6A,0xE9,0x99,0xEC,0x62,0x10,0xEA,0x07, + 0x31,0x7F,0xF6,0x2C,0xE3,0x85,0x8C,0x0C,0x20,0x99,0x69,0x60,0x53, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Leaf 1 */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 1 */ +unsigned char _leaf2048A[1000]={ + 0x30,0x82,0x03,0xE4,0x30,0x82,0x02,0xCC,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x7E, + 0x98,0x75,0xB3,0x73,0xE3,0x76,0xC7,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C,0x0A, + 0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06,0x03, + 0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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, + 0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D,0x62, + 0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x31,0x30, + 0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x31,0x38,0x35,0x36,0x5A, + 0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x31,0x38,0x35,0x36,0x5A,0x30, + 0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70, + 0x70,0x6C,0x65,0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x14,0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74, + 0x20,0x4C,0x65,0x61,0x66,0x20,0x31,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,0xA5,0x19,0x09,0x20,0x84,0xCE,0x67, + 0x24,0x88,0xCD,0xEB,0x25,0x9C,0xE7,0xD3,0x52,0xC5,0xC0,0x0F,0xA2,0x39,0x6C,0xF2, + 0x1D,0x6D,0x8F,0x29,0x45,0x09,0xD8,0x34,0xE8,0xD7,0xE0,0xD4,0xE6,0x96,0x20,0x33, + 0xDC,0x4A,0x99,0x3F,0x39,0x20,0x52,0x72,0x4A,0x12,0x5F,0x31,0xF3,0xB0,0x2B,0x17, + 0x6E,0x6B,0x80,0x8F,0xFD,0xC7,0x48,0x8D,0x42,0xBB,0xFA,0x2E,0xBD,0x98,0xA4,0x14, + 0x6B,0x6B,0xD0,0x98,0x3D,0x33,0x13,0x99,0x00,0x3A,0x69,0xAD,0x76,0xD5,0x2A,0x01, + 0x7B,0x32,0x68,0x2D,0x7F,0xA2,0x48,0x25,0x2C,0x0F,0x6F,0xA1,0xD9,0xA7,0xB7,0x75, + 0xE1,0x1D,0xAD,0xCA,0xBB,0x3A,0xBF,0xA8,0x4D,0x93,0x8E,0xC3,0xF3,0x51,0x65,0xDC, + 0xD8,0x2D,0x6B,0x4C,0x10,0x77,0x6B,0xEC,0x4F,0x07,0x8C,0x5B,0x8B,0x9A,0x53,0xDC, + 0xF3,0x1C,0x17,0x10,0x42,0x42,0x29,0x14,0x0A,0xE7,0x4C,0xEF,0x04,0x95,0xA0,0x84, + 0x47,0xD2,0x2C,0x81,0xB4,0x37,0x53,0xD2,0x76,0x31,0x97,0xE1,0x11,0xB1,0xDE,0x83, + 0xE0,0xFC,0xA5,0x12,0x34,0x0C,0xBD,0x81,0x31,0xA9,0x6D,0xDC,0x7C,0xE6,0x79,0xC2, + 0x42,0xED,0x91,0xCA,0x26,0xD5,0x4C,0x30,0xA8,0x49,0x70,0x69,0xD5,0x4C,0x34,0x92, + 0xCB,0xC3,0xA4,0x52,0x70,0x2D,0xDD,0x5A,0xFB,0x22,0x00,0xD7,0x2D,0xA3,0x75,0xC1, + 0xED,0xE4,0x2A,0x3E,0x23,0xE6,0xBD,0x84,0xC4,0xCC,0xE8,0x49,0xE0,0xAE,0xCA,0x81, + 0x75,0xDB,0x87,0xEF,0xE9,0xE9,0x1E,0xA9,0xBE,0x40,0x0B,0x64,0x86,0x22,0xBA,0xAE, + 0x64,0x27,0xA9,0xFE,0x07,0xE5,0x69,0x8F,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,0x05,0xA0,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,0x5D, + 0xA6,0xDA,0xDF,0xA5,0x29,0x94,0xF6,0x34,0xA9,0xC5,0x46,0xA3,0xBB,0xBD,0x0A,0x00, + 0x0E,0xD4,0xFC,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, + 0x03,0x99,0x06,0x5B,0xDA,0x2C,0xBA,0x9B,0x66,0x0A,0x5A,0x7B,0xAB,0x99,0xA5,0x7F, + 0x72,0xA9,0xD4,0xF7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, + 0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x0D,0xCB,0x71,0x05,0x25,0x22,0xD7,0x9A, + 0xE9,0x74,0x9E,0x16,0x91,0x73,0x90,0x95,0x1D,0x52,0xA7,0xAB,0xDA,0xDF,0x40,0x7B, + 0x57,0x7D,0x0A,0x9A,0xE9,0x65,0x18,0xF7,0x94,0x2B,0x9E,0x88,0x30,0xD3,0x8E,0x2A, + 0xE6,0xC6,0x7E,0xF7,0xF7,0x1A,0xE0,0x9F,0x91,0xB5,0xD0,0x62,0xA1,0x5D,0xB7,0x6B, + 0x0E,0xC7,0x4E,0x44,0xCC,0x79,0x39,0x56,0xA0,0x2D,0x9E,0x43,0xC3,0xF7,0x26,0x8B, + 0x99,0xC8,0x0E,0x68,0x5D,0xBD,0x02,0xB5,0xB1,0x59,0xB5,0x0F,0xF0,0x58,0xF6,0x32, + 0x57,0x7D,0xD3,0xB6,0x4C,0x89,0x64,0x21,0xBB,0xB3,0x13,0x15,0xC0,0xDD,0xF7,0xB5, + 0x1C,0xD1,0x1F,0xF9,0xE0,0xE9,0xB6,0x7F,0x1D,0x60,0xDC,0x9F,0x07,0xE9,0x5C,0x42, + 0x02,0x9B,0x64,0x13,0x5D,0x75,0xB5,0x77,0x01,0xF6,0xF6,0x2D,0x02,0xA8,0x18,0x59, + 0x9C,0x38,0x35,0xBC,0x75,0x11,0xCC,0x56,0xF5,0x5A,0x01,0x73,0xA9,0x06,0x31,0xAC, + 0x12,0x0C,0x03,0xC2,0xF3,0x67,0x26,0xA4,0xB3,0x2D,0xA2,0x7A,0xE5,0x44,0xE2,0x4F, + 0x28,0x25,0x6C,0xB8,0xF2,0x52,0xAF,0xCE,0x72,0x47,0xE9,0xD6,0xD1,0xFD,0x6B,0xFB, + 0x94,0x28,0xA8,0x82,0x85,0x49,0x8B,0xBC,0xB5,0x7B,0x93,0xCF,0x2D,0x29,0xE1,0x0C, + 0x5B,0xAF,0x3C,0xEC,0xED,0x78,0xDC,0x24,0x56,0x5C,0xC8,0xF4,0x47,0xBC,0x63,0xA3, + 0x37,0xF9,0x9C,0x92,0xF5,0xD3,0xAD,0x71,0xEC,0x43,0xE9,0x0B,0xDC,0xB5,0x9F,0x03, + 0x44,0x55,0x12,0x1D,0x39,0xF3,0x8C,0xAE,0x59,0x15,0xC1,0x12,0xAF,0xC1,0x02,0x95, + 0x62,0x7D,0x56,0xF0,0x93,0x47,0x5A,0x50, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Leaf 2 */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test SubCA */ +unsigned char _leaf2048B[803]={ + 0x30,0x82,0x03,0x1F,0x30,0x82,0x02,0xC9,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x4E, + 0xBF,0xB9,0x68,0xC8,0x8C,0x3A,0xE1,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x74,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,0x14,0x30,0x12,0x06,0x03, + 0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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, + 0x1B,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x0C,0x12,0x35,0x31,0x32,0x2D,0x62,0x69, + 0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x31,0x39,0x33,0x34,0x5A,0x17,0x0D,0x31, + 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x31,0x39,0x33,0x34,0x5A,0x30,0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14, + 0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x4C,0x65, + 0x61,0x66,0x20,0x32,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,0x79,0xB9,0x77,0x2A,0x76,0x17,0xEE,0xD1,0x4E,0x6D, + 0x6B,0x9F,0x42,0xAA,0xDE,0x81,0x47,0xC5,0x2B,0x43,0x3A,0x4F,0xB9,0x42,0x5E,0x5A, + 0x35,0xDE,0xF5,0x86,0x8C,0x0E,0xD1,0xC3,0x7B,0xA2,0x82,0x52,0x33,0xA0,0x2B,0x8C, + 0x58,0x04,0x75,0x8E,0xFB,0x08,0x9B,0xA7,0xEA,0x66,0x86,0xFA,0x5E,0xC2,0xCC,0x21, + 0x6C,0x17,0xC3,0x6B,0x05,0xFE,0x33,0x21,0x51,0x18,0xA1,0x0A,0xDD,0x5F,0xCE,0xF2, + 0xF6,0xB6,0x82,0x6C,0xBB,0x26,0x68,0x76,0xC3,0x16,0xEB,0x35,0x78,0x79,0x03,0xB0, + 0x36,0xC5,0x7D,0xDF,0x5C,0x38,0xB6,0xF0,0xD1,0xE0,0x9D,0x71,0xFB,0xA8,0x1B,0x83, + 0x9D,0x30,0xBC,0x2D,0x09,0x4D,0x9F,0xF4,0x69,0x33,0x99,0xE5,0xE9,0x76,0x6B,0x78, + 0x71,0xA7,0x13,0xF4,0xFB,0x2A,0x24,0x4D,0xD0,0x54,0x6E,0xAE,0x19,0xEE,0xCB,0x43, + 0x8C,0x3F,0x90,0x0F,0xDC,0xFE,0xA4,0xFF,0x8A,0xAD,0x22,0x21,0x61,0x51,0xAA,0x76, + 0x66,0x43,0xC0,0xE5,0x42,0x94,0x0F,0xBE,0x3C,0x89,0x45,0x50,0x0D,0x4F,0xDC,0x19, + 0xEF,0xF8,0x19,0xB6,0x7E,0x42,0xBD,0x88,0xA3,0x65,0x59,0xE8,0x7A,0xC1,0x7F,0x32, + 0x15,0x38,0xA3,0x58,0xC4,0x25,0x74,0xFC,0x02,0x8C,0xFC,0x31,0x28,0x20,0x05,0xAD, + 0x9B,0x27,0xE5,0x25,0x81,0x63,0x92,0xE1,0x49,0x55,0x5B,0xD7,0x36,0x3E,0xC4,0x2F, + 0x98,0x23,0xAA,0x62,0x85,0x68,0x4C,0x2D,0xEA,0x46,0xD6,0x99,0xCE,0x61,0x7C,0xE7, + 0x18,0x0B,0x72,0x5E,0xA0,0x06,0x49,0x6E,0x1C,0x31,0x0F,0x61,0x3F,0x62,0x68,0xC0, + 0x89,0xC8,0x91,0x45,0xAD,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,0x05,0xA0,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,0x81,0x88,0xF3,0xCE, + 0xC9,0x31,0x5E,0x77,0x3C,0x27,0x4E,0x5E,0x4A,0xE6,0xEA,0x06,0x7A,0xEA,0x32,0x43, + 0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x9E,0x85,0x9A, + 0xA5,0x88,0x09,0xB0,0x93,0x9B,0xB4,0xE5,0xCE,0x68,0x99,0x93,0xE9,0x79,0xE9,0x7C, + 0x98,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00, + 0x03,0x41,0x00,0x39,0x1A,0x27,0x7C,0xDB,0x9C,0xE7,0x83,0x5F,0x57,0x69,0x4D,0xAD, + 0xD5,0x98,0xBA,0xA8,0x56,0x54,0x8D,0x84,0x18,0xB0,0xAF,0xEA,0x4B,0x74,0xB7,0x87, + 0xDC,0xD8,0x1E,0x10,0x10,0xE3,0x73,0xC1,0x90,0x83,0x9F,0xB8,0xF4,0x41,0x03,0x02, + 0x49,0xF7,0x57,0x5C,0x7D,0x03,0xE9,0x9E,0x57,0xF4,0xBC,0x74,0x3A,0xC0,0x9B,0xFF, + 0x20,0x73,0xC7, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=512-bit Test Leaf */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ +unsigned char _leaf512[798]={ + 0x30,0x82,0x03,0x1A,0x30,0x82,0x02,0x02,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x81,0x94,0x54,0x10,0xDC,0xA5,0x98,0x14,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, + 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06, + 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D, + 0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32, + 0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x30,0x30,0x38, + 0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x30,0x30,0x38,0x5A, + 0x30,0x73,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41, + 0x70,0x70,0x6C,0x65,0x2C,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,0x1A,0x30,0x18,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x11,0x35,0x31,0x32,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74, + 0x20,0x4C,0x65,0x61,0x66,0x30,0x5C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x4B,0x00,0x30,0x48,0x02,0x41,0x00,0xEB,0x34, + 0xD8,0x83,0x6D,0xFE,0xDD,0x09,0x27,0xC1,0xA1,0xA7,0x1F,0x9D,0xA8,0xDF,0x55,0xDE, + 0x54,0x03,0x3D,0x42,0x54,0x24,0x3D,0x92,0x8B,0x21,0x4B,0xEE,0x8C,0x2B,0x9C,0x3F, + 0x34,0xD1,0x6B,0xDE,0xC0,0xC2,0x20,0x06,0x87,0x9B,0x11,0x96,0x8C,0xB5,0x24,0xDD, + 0x93,0xE6,0x1B,0x77,0xC1,0x7A,0xD0,0x1F,0xD2,0x09,0x3D,0x21,0x8A,0x15,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,0x05,0xA0,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,0xAE,0x83,0x56,0x29,0x05,0x75,0x48,0xB2,0x2F,0x0D,0x92, + 0x26,0x21,0xC2,0x7C,0x34,0x48,0xF7,0xAC,0xAF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0x0C,0x3F,0x97,0x58,0x60,0x67,0x21,0xC9,0xDB,0xD4, + 0x23,0x58,0x60,0x8E,0xC1,0x3F,0x99,0x9F,0x12,0x78,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x85,0xEC, + 0xC6,0xA7,0x1B,0x36,0x62,0x3A,0x04,0xBB,0xE8,0x8F,0xE2,0x66,0x8E,0xD4,0x02,0x97, + 0x6C,0x29,0x27,0xFF,0xC8,0xC6,0xBC,0xFE,0x9D,0xBC,0x09,0x8C,0x6B,0x0B,0x1E,0x48, + 0x82,0x46,0xBD,0xCF,0x02,0xB7,0x59,0x6E,0x7A,0xFC,0x8C,0x58,0x03,0x6A,0x92,0x4A, + 0xB0,0x1F,0x2E,0x6F,0x78,0x84,0x10,0x54,0xA9,0x70,0x65,0xDD,0xA2,0xAA,0xAA,0xFA, + 0x59,0x98,0xD7,0x42,0x60,0x42,0x15,0x2C,0x11,0x48,0xDE,0xF6,0x76,0x91,0x5C,0x2B, + 0x0B,0xEF,0x5F,0x23,0x61,0x8A,0x4E,0x81,0x82,0x3F,0xDA,0x9E,0x02,0xAF,0x82,0xDD, + 0x43,0x94,0x08,0xD1,0xA0,0x31,0x98,0x14,0x4C,0xBD,0x5E,0xFA,0x73,0xDC,0x0A,0x72, + 0xA4,0xB0,0x78,0x8A,0xC6,0xFE,0xBB,0x5A,0xBF,0x78,0x32,0x8D,0x26,0x7B,0xA3,0xBD, + 0x06,0x45,0x93,0xC6,0x96,0x99,0x14,0x8C,0x69,0xD1,0x52,0xDC,0xD4,0x1C,0x3E,0xCB, + 0x91,0x46,0x92,0x1B,0xBE,0x21,0xEC,0x21,0xE2,0xB9,0x23,0xD5,0xB0,0xAD,0x42,0xFA, + 0x9A,0x91,0xA4,0xA1,0x48,0x4D,0x94,0xB5,0xCF,0x14,0x21,0xA4,0x8E,0x18,0x2E,0x78, + 0x93,0xA0,0xED,0x43,0x15,0x92,0x68,0x57,0x78,0x52,0x28,0xEB,0x4A,0x48,0x79,0xEF, + 0x17,0xD3,0xD5,0xAD,0x2F,0x8A,0xF4,0xD2,0x21,0x79,0x08,0x08,0x66,0xE1,0x54,0x7F, + 0xFC,0x3D,0x5D,0x81,0xD8,0xA8,0x47,0xC3,0x3B,0xE9,0x52,0x77,0x05,0xF2,0x42,0xDE, + 0x23,0x24,0x99,0x7A,0x20,0x49,0x86,0x49,0x04,0x60,0x77,0xBD,0xD5,0x33,0xBB,0x49, + 0x61,0x8B,0x1C,0xBB,0x8E,0xE8,0x1D,0xA4,0x1E,0xA4,0x21,0x77,0x59,0xBD, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=1024-bit Test Leaf */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ +unsigned char _leaf1024[867]={ + 0x30,0x82,0x03,0x5F,0x30,0x82,0x02,0x47,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x81,0x94,0x54,0x10,0xDC,0xA5,0x98,0x15,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, + 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06, + 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D, + 0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32, + 0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x30,0x32,0x32, + 0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x30,0x32,0x32,0x5A, + 0x30,0x74,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41, + 0x70,0x70,0x6C,0x65,0x2C,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,0x1B,0x30,0x19,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x12,0x31,0x30,0x32,0x34,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73, + 0x74,0x20,0x4C,0x65,0x61,0x66,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,0xCA,0xCD,0xBD,0x1E,0xA5,0xF1,0xDC,0x50,0x7F,0xF6,0x52,0x96,0x56, + 0x1F,0xD9,0x9A,0x3F,0x32,0xED,0x45,0x29,0xCE,0x2C,0x18,0xA4,0x3E,0xA6,0x92,0xDF, + 0x8E,0x33,0x76,0x4D,0xCB,0xDB,0xD9,0x5E,0x83,0x32,0x96,0x19,0x8B,0x62,0xFE,0x67, + 0xBB,0xE6,0xC0,0x3D,0x1A,0xEF,0xE4,0x19,0x40,0x8B,0x26,0x80,0xD9,0x22,0x8A,0x1E, + 0xDF,0xC6,0x79,0x2C,0x07,0x7C,0xD7,0x10,0x91,0x7E,0x0F,0xC5,0x5E,0x69,0xC3,0xEB, + 0x1F,0x34,0x50,0x4D,0xA5,0xE1,0xF6,0x3A,0x6C,0xF0,0xD4,0x21,0x20,0x5C,0x0A,0x68, + 0xC1,0x26,0x4B,0x4A,0x79,0x08,0x64,0x67,0xDE,0x1E,0x17,0xC5,0xE4,0xEE,0xA6,0xE3, + 0xC4,0x54,0x34,0x7C,0xFE,0x82,0x5B,0xE4,0xAB,0xAF,0x97,0x2C,0x6B,0xAC,0x02,0x11, + 0xF3,0xD9,0x67,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,0x05,0xA0,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,0xB9,0xC9,0xD8,0x19,0xA6,0x69, + 0x3A,0x16,0x2E,0x32,0x2B,0x9A,0x10,0xB6,0xFA,0x20,0x93,0x16,0x7E,0xBC,0x30,0x1F, + 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x0C,0x3F,0x97,0x58,0x60, + 0x67,0x21,0xC9,0xDB,0xD4,0x23,0x58,0x60,0x8E,0xC1,0x3F,0x99,0x9F,0x12,0x78,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, + 0x01,0x01,0x00,0xA6,0x0A,0xB5,0x39,0x4B,0xA9,0xED,0x9B,0x8C,0xC5,0x5D,0xF1,0xAA, + 0x9D,0x57,0x55,0x5C,0xF2,0x10,0x29,0xBD,0x56,0x36,0xEF,0x52,0xDC,0xEA,0x27,0xF9, + 0xA2,0x79,0xBB,0xE6,0x16,0x29,0xA4,0x90,0x31,0x26,0x24,0x8A,0x79,0xBE,0x36,0xFC, + 0xA9,0xEF,0x77,0x13,0x16,0xA3,0x55,0xEB,0xD1,0x1A,0xD8,0xE2,0x16,0x72,0x5F,0x7D, + 0x10,0x76,0x3B,0x9A,0x00,0x51,0xAC,0x5A,0x4E,0x05,0xA3,0x82,0x1D,0xAB,0xC1,0x5E, + 0x44,0xD8,0xA0,0x95,0xD1,0xB5,0x75,0xE6,0x3B,0xB2,0x20,0xFB,0xBB,0xB9,0x88,0xD5, + 0x27,0x3B,0x90,0xA6,0xF0,0x6D,0x80,0xC8,0xA3,0x3A,0x3D,0x33,0x8F,0x14,0x09,0x5D, + 0xBB,0xA0,0xD7,0x3D,0x10,0xE9,0x8D,0x0E,0xB4,0x51,0x42,0xD3,0xB3,0xEF,0xC2,0xF2, + 0x0B,0x35,0x35,0x5D,0x7B,0xE1,0x47,0x9E,0x90,0xF9,0x14,0xDD,0xDD,0x1E,0x5F,0xDC, + 0xAB,0x04,0x08,0x8A,0x6B,0x82,0x2F,0xCA,0xA6,0x37,0x07,0x4C,0x94,0xD5,0x4F,0x83, + 0x67,0xEF,0xE2,0x12,0xDB,0x71,0x69,0x5A,0x33,0x8E,0x32,0x90,0xDE,0xE7,0x8C,0x6E, + 0x64,0xFD,0x8E,0x09,0xDA,0xBD,0x08,0xBE,0xC1,0x6F,0xD0,0x30,0xDD,0x18,0xDB,0xD1, + 0x34,0x7D,0x86,0x69,0xD7,0x57,0xE4,0x70,0x7F,0xF8,0x49,0xC0,0x4B,0xE4,0x73,0xE1, + 0x29,0x26,0x5E,0x04,0xDC,0xC6,0x69,0x17,0xDF,0x62,0x20,0xE1,0x15,0xAB,0xDD,0x1B, + 0x0C,0xD7,0xA6,0x1C,0x2C,0x7B,0xD9,0x2D,0xDE,0x46,0x43,0x81,0xFA,0xD9,0x11,0xDD, + 0xE8,0x4B,0x6A,0x31,0x85,0x24,0x0A,0xFD,0xAD,0x93,0xF6,0x50,0x2B,0x36,0xE5,0xE5, + 0x9E,0x8D,0x85, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test Leaf 3 */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=2048-bit Test SubCA 2 */ +unsigned char _leaf2048C[1001]={ + 0x30,0x82,0x03,0xE5,0x30,0x82,0x02,0xCD,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x81,0x94,0x54,0x10,0xDC,0xA5,0x98,0x16,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x0C, + 0x0A,0x43,0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x14,0x30,0x12,0x06, + 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x32,0x30,0x34,0x38,0x2D, + 0x62,0x69,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32, + 0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x30,0x33,0x33, + 0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x30,0x33,0x33,0x5A, + 0x30,0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41, + 0x70,0x70,0x6C,0x65,0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x14,0x32,0x30,0x34,0x38,0x2D,0x62,0x69,0x74,0x20,0x54,0x65,0x73, + 0x74,0x20,0x4C,0x65,0x61,0x66,0x20,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,0xC4,0xFE,0xE0,0xE5,0xC7,0x13,0x95, + 0x56,0x9E,0xA2,0x32,0xF5,0x52,0xD8,0xAA,0x06,0xF0,0x0F,0x2A,0x76,0xA8,0xCB,0xF3, + 0x39,0x5D,0x6E,0xEA,0x9C,0x4F,0x80,0xA1,0x9F,0xAC,0x8F,0x7D,0x34,0xDD,0x5D,0xD1, + 0x69,0xD9,0x2C,0x5D,0x49,0x2D,0x31,0x81,0x0D,0x2E,0x25,0xB7,0xA2,0x63,0x77,0xA1, + 0x58,0x8C,0x8D,0x2A,0x73,0x86,0xD8,0x15,0xFF,0xA9,0xED,0xF1,0xE6,0x08,0x7F,0x15, + 0x7B,0xFE,0xCC,0x07,0x7F,0xB7,0x63,0xA0,0x00,0x98,0xF0,0xBA,0x74,0x0C,0x34,0x2B, + 0xC4,0xE6,0xD6,0x2A,0xEE,0x7E,0x9D,0xBE,0xFD,0x34,0x70,0xCC,0x22,0x2C,0x2E,0x4F, + 0x81,0xC1,0xDA,0xB8,0x0B,0xC4,0xF9,0xFE,0xFD,0x74,0x47,0xE4,0xA9,0xA4,0x65,0x85, + 0x10,0x86,0x29,0x72,0x35,0x38,0x4B,0xD7,0xDA,0x3A,0x59,0xE7,0x8A,0x6D,0xC5,0x71, + 0x59,0x89,0xA5,0xC4,0xA3,0x9E,0xFC,0x81,0x18,0xD3,0x97,0x48,0xB2,0xDD,0xFE,0xB3, + 0xB3,0x78,0x71,0x35,0x3C,0x66,0x0F,0xD6,0xAA,0x84,0xF8,0xCB,0x87,0xB8,0xB4,0xFD, + 0x19,0x18,0x31,0xCC,0x53,0xB7,0x1B,0xB6,0x7D,0x99,0x9C,0x14,0x19,0xDA,0x84,0x72, + 0x88,0x21,0x9A,0x87,0x60,0x69,0xC3,0x8E,0x1F,0x34,0x3B,0xA3,0x56,0xA5,0x21,0xF0, + 0xDB,0xC1,0x54,0xEA,0x41,0x69,0x19,0x45,0x5E,0x52,0xB3,0x3A,0xBD,0x1A,0x8A,0x64, + 0x7B,0xA9,0xD4,0xF1,0x2B,0x58,0xCF,0x0D,0x7F,0x3C,0x86,0xDA,0x9A,0x94,0x42,0x36, + 0x6B,0x9F,0xD8,0xF4,0x64,0x18,0x66,0x6F,0xF7,0xB5,0x80,0xCE,0x43,0x8D,0x84,0x7A, + 0x99,0xE3,0x3D,0x03,0xB5,0x94,0x86,0xBD,0xEB,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,0x05,0xA0, + 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, + 0x50,0x25,0x7E,0xA7,0xF5,0x2B,0xA3,0x3A,0x35,0x31,0x82,0x4C,0xD6,0xA6,0x5F,0x04, + 0xC1,0x3A,0xAC,0x63,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, + 0x14,0x0C,0x3F,0x97,0x58,0x60,0x67,0x21,0xC9,0xDB,0xD4,0x23,0x58,0x60,0x8E,0xC1, + 0x3F,0x99,0x9F,0x12,0x78,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, + 0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x7E,0xF7,0x12,0xE6,0x05,0x3B,0x13, + 0x4B,0x35,0xAD,0x63,0xCF,0x39,0xC7,0x9B,0x62,0x83,0xF6,0x52,0xCC,0x54,0x14,0x13, + 0x5D,0xD8,0xE3,0x1E,0x33,0x37,0x6F,0x3B,0x13,0x9F,0x23,0xBC,0xA0,0xAC,0xF3,0xA1, + 0x94,0x0C,0xE0,0x51,0xDE,0x08,0x56,0x8B,0x90,0x2E,0x4B,0xB1,0xCD,0x9B,0x1A,0x44, + 0x8E,0xB9,0x0B,0xA7,0x0B,0x5B,0xAC,0x7A,0x37,0xF7,0x71,0x27,0x4E,0xB8,0x15,0x09, + 0x70,0x10,0xAA,0x3C,0x61,0xC8,0x76,0x2A,0x2E,0x13,0x76,0xC9,0x2E,0xEE,0x98,0x75, + 0xF7,0x61,0x7D,0x8E,0x3C,0xFC,0x19,0xDE,0xAB,0xE5,0xDA,0xFE,0x30,0x00,0x45,0x13, + 0xE2,0x82,0x96,0x59,0xEE,0x02,0x5A,0x9B,0xFA,0x1B,0x4E,0x65,0xE0,0x75,0x8F,0x99, + 0x82,0xBD,0x2A,0x16,0x10,0xC2,0xA5,0xA2,0x1A,0xC0,0xF6,0x4A,0x42,0x46,0xBA,0x12, + 0xE0,0x64,0x7B,0x10,0x57,0xB6,0xFE,0xC3,0x46,0xCC,0x43,0xDC,0x69,0xF0,0x72,0x69, + 0x62,0xDB,0x0C,0x6E,0x21,0xF9,0xB4,0x59,0xD7,0xA3,0xFC,0x82,0x98,0x60,0x60,0x57, + 0x7F,0xDD,0x25,0x65,0xB7,0x04,0x3E,0xDA,0xA3,0x07,0x7C,0x69,0xAF,0x81,0xA9,0x49, + 0x81,0x09,0x62,0x71,0x51,0x4F,0x40,0x8F,0xE4,0x01,0x4C,0xAE,0xF4,0x9D,0xE0,0x38, + 0xB1,0x20,0xF0,0x5D,0x1C,0xA0,0xB4,0x31,0xBF,0xE7,0xC7,0xFE,0xFF,0xA5,0x81,0xFB, + 0x8E,0xEE,0x19,0xB1,0xF1,0x64,0x44,0x3D,0xDA,0x71,0xE3,0x80,0x58,0xFB,0x23,0x6E, + 0xAE,0x3B,0x69,0x64,0x37,0x82,0x54,0xD6,0xEA,0xD4,0x02,0xD9,0x27,0x1A,0x9F,0xCE, + 0x0D,0x44,0xA9,0x29,0x07,0x8C,0x76,0x0A,0xCB, +}; + +// MARK: EC Key Size Test Certs + +/* EC Key Size Test Cert Chains + * _root384 -> _int384B -> _leaf128 + * _root384 -> _int384B -> _leaf192 + * _root384 -> _int384B -> _leaf384C + */ + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Root CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Root CA */ +unsigned char _root384[662]={ + 0x30,0x82,0x02,0x92,0x30,0x82,0x02,0x18,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x9B,0x8A,0xBF,0x1F,0x3B,0x4D,0xCC,0x76,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x01,0x30,0x81,0x8C,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,0x14,0x30,0x12, + 0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70, + 0x33,0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20, + 0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x30,0x33,0x30,0x34, + 0x32,0x35,0x5A,0x17,0x0D,0x32,0x35,0x31,0x32,0x31,0x35,0x30,0x33,0x30,0x34,0x32, + 0x35,0x5A,0x30,0x81,0x8C,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,0x14,0x30,0x12,0x06, + 0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33, + 0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43, + 0x41,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05, + 0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0xFE,0xE3,0x68,0x79,0x40,0x81,0x4D, + 0xC3,0xAA,0x9F,0x1D,0x9D,0x03,0x33,0x5F,0x39,0x4D,0xFD,0x4E,0x7E,0xC3,0xC2,0x9D, + 0xB4,0x61,0x98,0x8D,0x02,0xA9,0xA0,0xA7,0x4E,0x49,0xE8,0xFE,0xAD,0x1D,0x6B,0x7D, + 0xAF,0xDA,0x55,0xF5,0xD2,0x8E,0x5F,0x2F,0x0E,0x55,0x50,0x61,0x07,0x81,0xE6,0xDF, + 0xD5,0xD1,0xA5,0x21,0xA9,0x78,0x38,0xC5,0x75,0x76,0x06,0x54,0x67,0xC7,0xD1,0x00, + 0x37,0xD2,0x65,0x52,0xB6,0x28,0xA0,0x5D,0x76,0x32,0xF0,0x48,0xAC,0x86,0x8B,0x5B, + 0x90,0x08,0xE4,0xD3,0xCA,0xF0,0xE8,0x0E,0x45,0xA3,0x45,0x30,0x43,0x30,0x12,0x06, + 0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x08,0x30,0x06,0x01,0x01,0xFF,0x02,0x01, + 0x03,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,0x86,0xC8,0x90,0xD5, + 0xD7,0x5C,0x3A,0xE1,0x29,0xF4,0x13,0x54,0xD0,0x06,0x90,0xAA,0xEC,0xF8,0x97,0xF7, + 0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66, + 0x02,0x31,0x00,0xE3,0xE1,0x9C,0xB4,0xEE,0x40,0x25,0x9A,0x82,0x3F,0x0A,0x03,0x55, + 0xDC,0x52,0x7D,0x3B,0xFC,0xC2,0x1A,0x05,0x97,0xEF,0x3F,0xA0,0x63,0x49,0x8A,0x00, + 0x38,0x72,0x05,0xDB,0x74,0x9C,0xED,0x68,0x8E,0x03,0xB8,0x6B,0x36,0x11,0x2C,0x77, + 0xA3,0xB8,0x7C,0x02,0x31,0x00,0xA9,0xB5,0x88,0xB6,0x3A,0x85,0x55,0x2E,0x69,0x56, + 0x8D,0xC4,0x5B,0x24,0xD2,0x8A,0x0E,0x01,0xA9,0x0E,0xC1,0x4D,0xDB,0x39,0xE9,0x9C, + 0x16,0x49,0xEE,0xD8,0x50,0xC0,0x1E,0x02,0xD4,0x5C,0x8B,0x07,0xD1,0xA5,0x74,0xE3, + 0x6F,0x62,0xC8,0x32,0x40,0x1D, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Root CA */ +unsigned char _int384B[671]={ + 0x30,0x82,0x02,0x9B,0x30,0x82,0x02,0x21,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xFE,0xE6,0x21,0x31,0x73,0x83,0x11,0xBA,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE, + 0x3D,0x04,0x01,0x30,0x81,0x8C,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,0x14,0x30,0x12, + 0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70, + 0x33,0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x20, + 0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x32,0x31,0x32, + 0x31,0x38,0x5A,0x17,0x0D,0x31,0x36,0x31,0x32,0x31,0x36,0x32,0x32,0x31,0x32,0x31, + 0x38,0x5A,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, + 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, + 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x76,0x30,0x10, + 0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22, + 0x03,0x62,0x00,0x04,0x08,0xAE,0xF2,0x28,0x6E,0x8C,0xE8,0x16,0x01,0x86,0x37,0xFE, + 0xFD,0x17,0xA5,0x37,0x30,0xD2,0x55,0xDB,0x4C,0x6D,0xE5,0xAF,0x63,0xBD,0x5F,0xB5, + 0x6E,0xDB,0x66,0xB3,0x2C,0xA0,0xD1,0x6B,0xC2,0x82,0x28,0xBB,0xEF,0xD7,0xFE,0xA1, + 0x3D,0x5A,0x00,0x56,0xFD,0xD2,0x28,0x36,0x8D,0xEE,0xFC,0x3F,0x58,0xFE,0x5D,0x0C, + 0x82,0xE8,0x7F,0x0D,0x89,0xEE,0x4A,0xC1,0xF7,0xF3,0xB3,0x64,0xF7,0xB9,0x58,0xD6, + 0x76,0x62,0x67,0x52,0x9B,0xDA,0x19,0xDA,0xD3,0xCA,0x55,0xF9,0xBD,0xBD,0x38,0x4E, + 0x23,0xA5,0xF8,0xA9,0xA3,0x63,0x30,0x61,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,0x02,0x04,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E, + 0x04,0x16,0x04,0x14,0xD8,0xEA,0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC, + 0xB4,0x63,0x42,0xAF,0x57,0xCC,0xBC,0x79,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04, + 0x18,0x30,0x16,0x80,0x14,0x86,0xC8,0x90,0xD5,0xD7,0x5C,0x3A,0xE1,0x29,0xF4,0x13, + 0x54,0xD0,0x06,0x90,0xAA,0xEC,0xF8,0x97,0xF7,0x30,0x09,0x06,0x07,0x2A,0x86,0x48, + 0xCE,0x3D,0x04,0x01,0x03,0x69,0x00,0x30,0x66,0x02,0x31,0x00,0xBD,0x7D,0x2C,0x3A, + 0xC6,0xE6,0xA7,0xDB,0x73,0xA2,0x36,0x13,0x38,0xC4,0x17,0x71,0x35,0x41,0x23,0xC7, + 0xCC,0xF1,0x9E,0x89,0x97,0x1F,0xD7,0xFC,0x58,0x9D,0x50,0x2D,0x0B,0xD9,0x33,0xD5, + 0x7E,0xB4,0xD8,0x43,0xCF,0xDB,0x0A,0xBE,0xBE,0x44,0xDF,0x10,0x02,0x31,0x00,0xFD, + 0xE3,0x32,0x58,0x06,0x7D,0xA1,0x7B,0x1F,0x22,0x85,0x82,0x54,0xD9,0xB0,0x36,0x4A, + 0x2E,0x0B,0x24,0xA6,0x9B,0xBD,0x15,0x76,0xDB,0xAC,0xD4,0x97,0x91,0x64,0x11,0xFE, + 0x47,0x11,0x59,0xBC,0xAF,0x1C,0x5A,0x16,0xF8,0x2E,0x0B,0x46,0x2C,0xD7,0x6E, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp128r1 Test Leaf */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ +unsigned char _leaf128[599]={ + 0x30,0x82,0x02,0x53,0x30,0x82,0x01,0xDA,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x49, + 0xF9,0xF0,0x5F,0xA0,0x17,0xBD,0x2F,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x01,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, + 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, + 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D, + 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x32,0x33,0x34,0x5A,0x17,0x0D,0x31, + 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x32,0x33,0x34,0x5A,0x30,0x75,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13, + 0x73,0x65,0x63,0x70,0x31,0x32,0x38,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x4C, + 0x65,0x61,0x66,0x30,0x36,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, + 0x06,0x05,0x2B,0x81,0x04,0x00,0x1C,0x03,0x22,0x00,0x04,0xB1,0x4F,0xBB,0xCA,0x19, + 0xDD,0x23,0xF4,0x58,0xC2,0xDF,0x70,0x7A,0x46,0xB4,0xC9,0x22,0x71,0xF6,0x4D,0x1D, + 0xDA,0x4C,0x0F,0x62,0x68,0x14,0x42,0xA7,0x77,0x8F,0xC6,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,0x05,0xA0,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,0x56,0x3C,0xD0, + 0xEF,0xEF,0x08,0x74,0x41,0xD8,0xAB,0x26,0x21,0xD7,0xD9,0x6A,0xED,0xE1,0x1B,0x54, + 0xF2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xD8,0xEA, + 0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC,0xB4,0x63,0x42,0xAF,0x57,0xCC, + 0xBC,0x79,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03,0x68,0x00, + 0x30,0x65,0x02,0x31,0x00,0xFD,0x13,0x19,0x07,0xFB,0xD1,0x1B,0x3A,0xB1,0x82,0x2D, + 0xA0,0x16,0xEE,0xAD,0x0B,0xCF,0x19,0x65,0x49,0x64,0xCE,0x03,0x04,0x32,0xD9,0x1F, + 0xD2,0xC7,0x0A,0x43,0xD8,0xB9,0x9B,0x74,0x41,0x1A,0x20,0xAA,0xB3,0x2A,0xA8,0x71, + 0xAC,0x65,0x73,0xBE,0xD1,0x02,0x30,0x2D,0x0D,0xFC,0x08,0x2E,0x9A,0x61,0xA3,0xB6, + 0x55,0x72,0x4A,0x26,0x73,0xE3,0xA2,0x1A,0xE4,0x64,0x1C,0x44,0x93,0x5B,0xF8,0x93, + 0xBB,0x42,0x2E,0x01,0xC9,0xAF,0xE1,0x98,0x04,0x8B,0x8C,0xC1,0x9F,0x2B,0x37,0x54, + 0x4B,0x55,0xC9,0xF2,0x3F,0x6F,0x5E, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=prime192v1 Test Leaf */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ +unsigned char _leaf192[619]={ + 0x30,0x82,0x02,0x67,0x30,0x82,0x01,0xEE,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x49, + 0xF9,0xF0,0x5F,0xA0,0x17,0xBD,0x30,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x01,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, + 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, + 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D, + 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x32,0x34,0x33,0x5A,0x17,0x0D,0x31, + 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x32,0x34,0x33,0x5A,0x30,0x76,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x03,0x0C,0x14, + 0x70,0x72,0x69,0x6D,0x65,0x31,0x39,0x32,0x76,0x31,0x20,0x54,0x65,0x73,0x74,0x20, + 0x4C,0x65,0x61,0x66,0x30,0x49,0x30,0x13,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x02, + 0x01,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01,0x03,0x32,0x00,0x04,0x29, + 0x68,0x3F,0x3A,0xC9,0x63,0xDD,0x0F,0xC9,0x1A,0x4B,0x94,0x5C,0xEE,0x2C,0x41,0x42, + 0xE0,0x35,0x9B,0xA9,0x93,0x03,0x8C,0xB7,0x2A,0xC5,0x96,0x8D,0x33,0x94,0x90,0x58, + 0x78,0x5F,0xA4,0xFE,0x93,0x96,0x89,0x4D,0x50,0xB6,0xB8,0x78,0x40,0xC5,0xBA,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,0x05, + 0xA0,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,0x69,0x6E,0x52,0x27,0xD9,0x64,0x18,0x47,0x7F,0x23,0xF7,0xFB,0xF6,0x07,0x48, + 0xDD,0x0E,0x48,0x0D,0xC3,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, + 0x80,0x14,0xD8,0xEA,0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC,0xB4,0x63, + 0x42,0xAF,0x57,0xCC,0xBC,0x79,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04, + 0x01,0x03,0x68,0x00,0x30,0x65,0x02,0x31,0x00,0xC3,0x36,0x26,0x00,0x44,0x7B,0xEE, + 0xAA,0x4A,0x13,0xA5,0x64,0x8A,0x6B,0x40,0x91,0x43,0x3A,0x4E,0x3C,0xDF,0x28,0x59, + 0x12,0x86,0xB1,0x45,0x34,0x23,0xAE,0x8B,0x6D,0x91,0x7D,0xFB,0x0E,0x15,0xF9,0xC9, + 0xFB,0x52,0x96,0xBA,0x0B,0xBE,0x84,0xAC,0x58,0x02,0x30,0x5C,0x21,0x90,0x17,0x18, + 0x38,0xA3,0x40,0xAF,0x53,0x76,0x88,0x4B,0x22,0x97,0x5E,0x54,0xF2,0x98,0x0F,0xB5, + 0x61,0x4C,0x10,0x44,0x53,0xFC,0xB6,0x6E,0xF3,0x9E,0x2C,0x4B,0x3B,0xAC,0xC8,0x90, + 0xBF,0xAE,0xEC,0xC7,0x62,0xFE,0x2F,0xAF,0x1A,0x90,0x35, +}; + +/* subject:/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test Leaf 3 */ +/* issuer :/C=US/ST=California/O=Apple, Inc./OU=Security Engineering/CN=secp384r1 Test SubCA 2 */ +unsigned char _leaf384C[665]={ + 0x30,0x82,0x02,0x95,0x30,0x82,0x02,0x1C,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x49, + 0xF9,0xF0,0x5F,0xA0,0x17,0xBD,0x31,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, + 0x04,0x01,0x30,0x78,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C, + 0x0B,0x41,0x70,0x70,0x6C,0x65,0x2C,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,0x1F,0x30,0x1D,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x16,0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20, + 0x54,0x65,0x73,0x74,0x20,0x53,0x75,0x62,0x43,0x41,0x20,0x32,0x30,0x1E,0x17,0x0D, + 0x31,0x35,0x31,0x32,0x31,0x37,0x32,0x33,0x32,0x32,0x35,0x35,0x5A,0x17,0x0D,0x31, + 0x36,0x31,0x32,0x31,0x36,0x32,0x33,0x32,0x32,0x35,0x35,0x5A,0x30,0x77,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,0x14,0x30,0x12,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0B,0x41,0x70,0x70,0x6C,0x65, + 0x2C,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, + 0x73,0x65,0x63,0x70,0x33,0x38,0x34,0x72,0x31,0x20,0x54,0x65,0x73,0x74,0x20,0x4C, + 0x65,0x61,0x66,0x20,0x33,0x30,0x76,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, + 0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x22,0x03,0x62,0x00,0x04,0x1F,0x62,0x07, + 0xBA,0x5D,0x2A,0x56,0xED,0x5D,0xE7,0x0B,0x18,0xDE,0x65,0x13,0xA4,0x31,0x53,0xFC, + 0x86,0x86,0xB4,0xC4,0x27,0x39,0x4D,0xD1,0x22,0xC2,0xFF,0x07,0x62,0xAB,0x64,0xDD, + 0xCC,0xEB,0x7F,0x08,0x12,0x78,0x20,0x90,0x40,0xD3,0xCF,0x45,0x71,0x98,0x6E,0x4E, + 0x93,0xC5,0x66,0x40,0x76,0xB0,0xAD,0xDB,0xD6,0xFA,0x9C,0x7F,0x46,0xF9,0xC9,0xDE, + 0xF5,0x41,0xA3,0x0C,0x7F,0x73,0xF3,0x0C,0x91,0xE1,0x0B,0xAD,0xBC,0xD5,0xD2,0xB1, + 0x6F,0xC3,0x1F,0x43,0x94,0x9C,0x18,0x5B,0xD9,0xE1,0x5A,0x84,0x2F,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,0x05,0xA0,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,0xB3, + 0xB5,0xC9,0x62,0x46,0xDD,0x1C,0x89,0x93,0xE3,0xAA,0x7C,0xEA,0x61,0x22,0x8B,0xF2, + 0x04,0x31,0x74,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, + 0xD8,0xEA,0x0F,0xE6,0x82,0x91,0x5F,0xC4,0xA1,0x59,0x2B,0xBC,0xB4,0x63,0x42,0xAF, + 0x57,0xCC,0xBC,0x79,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03, + 0x68,0x00,0x30,0x65,0x02,0x30,0x33,0xE4,0xE8,0x8E,0x00,0x57,0xE4,0x53,0xCC,0xD4, + 0x04,0xF2,0xB6,0x7D,0xD5,0x14,0x5B,0xB2,0xBE,0x28,0xF8,0x5D,0x55,0x7A,0xB3,0x06, + 0x17,0x87,0xA9,0xAA,0x23,0xCE,0xAF,0x15,0xF3,0xE1,0xA8,0x9B,0xCF,0x06,0xC9,0x06, + 0x75,0x0C,0x13,0x12,0x40,0x32,0x02,0x31,0x00,0xE2,0x28,0x4A,0x28,0xA6,0x94,0x2C, + 0x8E,0x5A,0x13,0xCF,0x33,0xBB,0x6A,0x11,0x74,0x3A,0xED,0x3A,0x61,0x07,0x6D,0x49, + 0x84,0xBF,0xE2,0x1F,0xED,0x08,0x70,0x0F,0xCA,0x45,0xBA,0x68,0x1C,0xF3,0x15,0x7E, + 0xAB,0x41,0x0E,0xAB,0x84,0x29,0x33,0x87,0x3A, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +uint8_t _rootSSL[] = { + 0x30,0x82,0x03,0xDA,0x30,0x82,0x02,0xC2,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xCE,0xB0,0xBF,0x61,0x75,0x93,0xF9,0x53,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x88,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,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57, + 0x65,0x61,0x6B,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,0x74,0x20, + 0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32,0x33,0x33, + 0x34,0x38,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x33,0x33,0x34, + 0x38,0x5A,0x30,0x81,0x88,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, + 0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57,0x65,0x61,0x6B,0x20,0x43, + 0x72,0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,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,0xC8,0xC5, + 0x06,0x13,0xEB,0x60,0xE1,0x07,0xE3,0x47,0x50,0x42,0xC3,0x5B,0xAE,0xF4,0x5A,0x65, + 0x6A,0x74,0xAC,0xF2,0xF6,0x1C,0xFC,0x45,0x21,0x8D,0x0E,0x08,0x78,0x83,0x28,0xDD, + 0xBB,0xDD,0x65,0xD4,0x2F,0x05,0x56,0x06,0x21,0xEF,0xE2,0xE9,0x2C,0x78,0x61,0x56, + 0x1F,0x87,0x4D,0x99,0xD0,0x2B,0x47,0x30,0xFF,0xAE,0x29,0x1F,0x63,0xF3,0xFC,0x26, + 0xEC,0xDF,0xCD,0x34,0xD1,0x4B,0xDE,0x5A,0x52,0xFA,0x90,0x1F,0x6B,0xDE,0x74,0x79, + 0xDD,0x3E,0x53,0x62,0x20,0xD3,0x5B,0x18,0x0A,0xE8,0xBE,0xEB,0xBD,0x52,0x81,0xAD, + 0x1A,0x24,0x3C,0x9C,0xAD,0xC4,0x72,0xA9,0x9D,0xC1,0xC0,0x7F,0x42,0x32,0x02,0x5B, + 0x4F,0xFF,0x5E,0x7F,0xA5,0xD0,0x26,0xF9,0xF7,0x80,0xF9,0xEC,0x86,0x0F,0xA9,0x0B, + 0x12,0x6E,0x95,0x1D,0x18,0xC9,0x0D,0x7B,0x52,0xD2,0x37,0xF1,0x68,0x45,0x9C,0x58, + 0x6F,0x88,0xC7,0x71,0x9F,0x02,0xEA,0x44,0x13,0xF2,0x5D,0xAC,0x81,0xD7,0x59,0x98, + 0x19,0xA2,0xB8,0x56,0xA3,0x89,0xC7,0xD9,0x5E,0xA2,0xA8,0xBA,0xC2,0x97,0x94,0x09, + 0xBB,0x81,0xDE,0xE8,0x9A,0x06,0x92,0xAA,0x14,0xDA,0x4D,0xFB,0xD6,0xD4,0xC6,0x0F, + 0x1E,0x25,0xAA,0x42,0xDB,0x3F,0x59,0xD2,0x90,0x93,0x4C,0xB4,0xF8,0x39,0x8B,0xA1, + 0x54,0x7B,0x83,0x29,0xCF,0xA2,0x53,0xD7,0x14,0x9A,0x57,0xB8,0x13,0x0F,0x48,0x1F, + 0x56,0x13,0xE3,0xBB,0x9A,0x11,0x62,0x37,0x25,0xA4,0x8A,0xA2,0x03,0x9E,0x9F,0xD0, + 0x08,0x52,0xF7,0x58,0x79,0xD6,0xBD,0xD7,0xCA,0x00,0x3C,0xE7,0xFB,0xDB,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,0xF1,0x0F,0x83,0xE3,0x07,0x66,0xE9,0x79,0xEE,0x31, + 0x1A,0x6A,0x30,0x9B,0xDA,0x97,0x15,0xF7,0xB9,0xB4,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9D,0xC9, + 0xCD,0xFB,0x8F,0x40,0xC2,0xFD,0xF0,0x7D,0x8D,0x36,0x43,0x57,0x98,0x91,0x11,0x0A, + 0x3A,0x70,0x28,0x5D,0xCC,0xF6,0xB7,0xF9,0x51,0xB3,0xCA,0x80,0x67,0x5A,0xF4,0x6D, + 0xB4,0x4A,0x50,0x11,0xC5,0x25,0xA3,0x5B,0xBF,0x03,0xB4,0xA2,0x37,0x80,0x08,0x7B, + 0x5D,0xDB,0x39,0x2B,0x06,0xA0,0x6C,0x5B,0x1D,0x1E,0x21,0x79,0x5B,0x34,0x78,0x03, + 0xA2,0xBF,0x2F,0x68,0x90,0xF7,0xA9,0x55,0x35,0xAF,0x27,0x58,0xF5,0x96,0x93,0x64, + 0x9E,0xC0,0x4E,0x76,0x9E,0xEA,0x18,0x1B,0x97,0x7B,0xFB,0x71,0x4D,0x30,0x5C,0x5D, + 0x4C,0xDF,0xB4,0x41,0x0C,0x15,0xC0,0x94,0xAA,0x85,0xB8,0x55,0x39,0x49,0xA4,0x5F, + 0x33,0xA1,0x57,0x2C,0xF1,0x16,0xC6,0x0B,0xCC,0x33,0x4B,0xA5,0xA3,0x44,0x63,0xA3, + 0xCB,0x9F,0xC9,0xF8,0x99,0x51,0x63,0x28,0x8D,0xC7,0xE3,0x45,0x6F,0x4E,0x26,0x8C, + 0xEA,0xDA,0xAE,0x74,0xFC,0x81,0xBC,0x5E,0xF1,0x64,0xD5,0xE5,0x63,0x74,0x34,0x9B, + 0x72,0x54,0xF9,0xE1,0x5A,0xE6,0x2C,0xCF,0x2B,0xD9,0x0B,0xD1,0xF4,0xB8,0x51,0x9D, + 0x9D,0x70,0xC2,0x2B,0xC4,0x07,0x6B,0xA2,0x70,0xC7,0x1B,0x33,0xC3,0x50,0x65,0xB6, + 0x13,0x18,0x64,0xFF,0x27,0xA8,0x7B,0xD8,0xCB,0x45,0xC9,0xD2,0x57,0x2A,0x15,0xB6, + 0x6E,0xD9,0x06,0xEB,0x38,0xC6,0x19,0x97,0x4E,0x3D,0x31,0x45,0x90,0x6A,0xD9,0x55, + 0x60,0x43,0xF4,0x04,0x62,0x39,0xE0,0x8A,0xAB,0x55,0xA4,0xA2,0xF8,0x5E,0xA9,0x3E, + 0xCB,0x08,0x9B,0x35,0x66,0x5D,0xFA,0x6A,0xC2,0x93,0x12,0x74,0x63,0x20, + +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Key Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +unsigned char _leaf1024SSL[] = { + 0x30,0x82,0x03,0xAE,0x30,0x82,0x02,0x96,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,0xC7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x88,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,0x1C, + 0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57,0x65,0x61,0x6B,0x20,0x43,0x72, + 0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32,0x34,0x31,0x32,0x38,0x5A,0x17,0x0D,0x32, + 0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x34,0x31,0x32,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,0x57,0x65,0x61,0x6B,0x20,0x4B,0x65,0x79,0x20,0x4C,0x65,0x61, + 0x66,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,0xC9,0x5D, + 0xD1,0xA8,0xEE,0x6A,0x6C,0x0A,0xA5,0x1A,0x7D,0xA8,0xCA,0xA3,0xDC,0x7D,0xC3,0x47, + 0xF8,0x49,0x0C,0xA5,0xDF,0x4A,0xCA,0x80,0xBC,0x73,0x0D,0xFD,0x36,0x21,0x93,0x46, + 0x03,0xF4,0x8C,0x4E,0xD9,0x2F,0x4F,0x7D,0x23,0x15,0xE6,0xCB,0x51,0x8F,0xE3,0xA2, + 0x97,0x87,0xC7,0x25,0x25,0x0D,0x7F,0xDA,0x21,0x8B,0xC4,0x01,0xE1,0xDC,0x08,0x6F, + 0xAE,0xCF,0x89,0xDA,0x45,0xA3,0x12,0xE1,0xC3,0xE9,0xBF,0x3A,0x12,0x0C,0xDD,0x25, + 0x9B,0xDE,0x96,0x35,0x2C,0x3F,0xA2,0xCD,0x00,0xFF,0xA1,0x8E,0x02,0xEF,0x31,0xC6, + 0x30,0x45,0x69,0x4D,0x9A,0xF1,0x05,0xB4,0x52,0x65,0xA7,0x85,0xE9,0x37,0xBA,0xA0, + 0xB9,0x96,0x88,0x5D,0xB5,0xAF,0xDA,0xE2,0xDD,0x68,0x62,0x95,0xCC,0x33,0x02,0x03, + 0x01,0x00,0x01,0xA3,0x81,0x98,0x30,0x81,0x95,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,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,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,0x84,0x25,0x19,0x83,0x30,0xFF,0x03, + 0x58,0xCE,0x52,0x74,0x0E,0x20,0xC4,0x42,0x5A,0x9A,0x58,0xE2,0xFD,0x30,0x1F,0x06, + 0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF1,0x0F,0x83,0xE3,0x07,0x66, + 0xE9,0x79,0xEE,0x31,0x1A,0x6A,0x30,0x9B,0xDA,0x97,0x15,0xF7,0xB9,0xB4,0x30,0x0D, + 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01, + 0x01,0x00,0x4D,0xA0,0x2F,0xE7,0xE4,0xE0,0x08,0x75,0x79,0x13,0x1C,0x52,0xF1,0xC8, + 0x24,0xB5,0x21,0x54,0x0D,0x20,0xEB,0x09,0xEC,0x1B,0x89,0xBD,0xA6,0x47,0x1E,0x43, + 0x4F,0x01,0x32,0x83,0x41,0xC3,0xD0,0x2A,0xB6,0xDB,0x5B,0x9F,0x97,0x2A,0xD6,0xB3, + 0x38,0xD5,0x55,0x32,0xB4,0x79,0x1E,0x48,0x1C,0xA5,0x02,0xDE,0xC3,0x2E,0xAD,0xCA, + 0xAC,0x57,0xA0,0xCD,0xEE,0x0D,0x21,0xF7,0xBF,0xF4,0xB7,0x3C,0x5A,0x35,0xFD,0x1F, + 0x47,0x4C,0xB2,0xC4,0x22,0x4E,0xA6,0x5F,0xA7,0x09,0x9A,0x26,0x4E,0x8A,0x4C,0x0B, + 0x1A,0xAF,0x6B,0xF7,0x5F,0x56,0x12,0xD9,0xC1,0x26,0x21,0xE2,0xA5,0xCE,0x45,0x00, + 0xB9,0xB6,0x88,0xC8,0xD2,0xC9,0x66,0xB4,0x9E,0xD2,0x34,0x19,0xA2,0x0B,0x30,0x9E, + 0xC8,0x85,0x30,0x71,0x95,0x3D,0x3D,0x61,0xD2,0x4E,0x4D,0xB1,0xF8,0xC2,0x92,0x1B, + 0x21,0x67,0x7A,0x97,0x02,0xF0,0xE3,0x47,0x1C,0xF5,0x08,0xA9,0xA3,0x08,0xF5,0xED, + 0x4C,0x55,0x7C,0x62,0xF3,0xD3,0xD4,0xB9,0xAD,0xBF,0xFC,0x66,0x95,0xAF,0x7E,0xD9, + 0x5E,0xDD,0x68,0xCF,0x78,0x25,0xEF,0x90,0x44,0x1F,0xFC,0xB3,0x35,0x81,0x1D,0x1B, + 0x27,0xAC,0x28,0xB8,0x58,0xAB,0x6D,0xFE,0x71,0xC0,0x4F,0xBE,0x37,0x35,0xA0,0x62, + 0x93,0xA8,0x91,0x73,0x43,0x39,0x0A,0xAD,0x5E,0xE8,0x1E,0x90,0xF0,0x50,0xC7,0x7C, + 0xED,0x29,0xE5,0xD2,0x42,0x55,0x89,0x9C,0xD7,0x51,0xA9,0xB6,0xF0,0xC5,0x39,0x34, + 0xE4,0xA0,0x6D,0xAD,0x1A,0x51,0xCC,0xA0,0xDA,0x0D,0xA7,0xB9,0x7F,0x06,0xDE,0x96, + 0xD6,0x0F, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Strong Crypto Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +uint8_t _leaf2048SSL[] = { + 0x30,0x82,0x04,0x37,0x30,0x82,0x03,0x1F,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,0xC6,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x88,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,0x1C, + 0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57,0x65,0x61,0x6B,0x20,0x43,0x72, + 0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32,0x33,0x38,0x31,0x34,0x5A,0x17,0x0D,0x32, + 0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x33,0x38,0x31,0x34,0x5A,0x30,0x81,0x87,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,0x1B,0x30,0x19,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x12,0x53,0x74,0x72,0x6F,0x6E,0x67,0x20,0x43,0x72,0x79,0x70,0x74, + 0x6F,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,0xAF,0x01,0x48,0x09,0xB9,0xA1,0xB5,0x29,0x07, + 0x36,0x35,0xA6,0x5D,0x97,0x38,0x1F,0x0A,0xD1,0xD8,0x0B,0xD1,0xC5,0xDD,0x07,0x39, + 0x96,0xBA,0xDD,0xFF,0xC0,0x42,0x8D,0x19,0xDD,0xA9,0x44,0x0A,0xD6,0xD7,0xBA,0x74, + 0x1F,0xDA,0x75,0x15,0x02,0x50,0xC9,0x78,0x46,0x76,0xDB,0xAA,0xCF,0xE0,0x5A,0xA1, + 0xDE,0x81,0xFB,0x73,0xB9,0x85,0x7F,0xA4,0xD7,0x52,0xE6,0x96,0xD7,0x67,0x42,0x78, + 0x89,0x8D,0xFF,0xD6,0xF4,0x3D,0x02,0x68,0x14,0xA2,0x5E,0x48,0xD9,0x2C,0x9B,0x09, + 0x09,0xEA,0x00,0x00,0xB1,0x8B,0x32,0xB8,0x1E,0x92,0x05,0xFF,0xCB,0x72,0x7A,0x6F, + 0x8F,0xCC,0xFB,0x04,0xCD,0x11,0xC0,0x12,0xBA,0x62,0x6E,0x02,0xBA,0x8C,0xE7,0x61, + 0xE7,0xC4,0x52,0xA5,0xA6,0xF3,0x86,0x34,0xA8,0xCC,0x15,0x59,0x48,0x18,0xF3,0xCC, + 0x13,0xE4,0x8A,0x3F,0xF1,0xF8,0xED,0xD8,0x74,0x5D,0x86,0x6E,0x07,0x6A,0xA1,0xA9, + 0xCF,0x46,0xE0,0x76,0x38,0xC8,0xEC,0x33,0x7A,0x40,0x5E,0x0E,0x6E,0xB0,0x11,0x53, + 0xD0,0xA3,0xEB,0x7E,0x73,0x6D,0xFD,0xAB,0xAE,0x24,0x31,0x2E,0x1D,0xC8,0x3D,0xF7, + 0xBE,0xA4,0xB1,0x6A,0x69,0x09,0xDF,0xBE,0x20,0x43,0x55,0x55,0x49,0x26,0x36,0xF5, + 0x3F,0x8F,0x25,0xDA,0x34,0x1A,0xD4,0x2B,0xCC,0x88,0x5C,0xDA,0x03,0x85,0xE3,0xCF, + 0xD4,0xA7,0x8E,0x49,0x30,0x74,0x8A,0xB0,0x11,0xCF,0xA0,0x81,0xA6,0x99,0x5E,0xE2, + 0xEE,0x47,0x03,0x13,0x04,0x07,0xAB,0x74,0x30,0x4D,0xA7,0xFF,0xD7,0x7A,0x9B,0xBA, + 0x38,0x94,0x35,0xC3,0xDD,0x93,0xBB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98,0x30, + 0x81,0x95,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,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, + 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,0x77,0xD2,0xF8,0xFB,0x2A,0x51,0x1C,0xD0,0x26,0x13,0x7B,0x36,0xFB,0x3D, + 0xC9,0x04,0xFD,0x75,0x22,0xFE,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, + 0x16,0x80,0x14,0xF1,0x0F,0x83,0xE3,0x07,0x66,0xE9,0x79,0xEE,0x31,0x1A,0x6A,0x30, + 0x9B,0xDA,0x97,0x15,0xF7,0xB9,0xB4,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2B,0x72,0x9E,0x87,0xFA, + 0x4D,0x05,0x78,0x93,0x49,0x7F,0x58,0x3D,0x49,0xD8,0x3D,0x5A,0x69,0x29,0x58,0x41, + 0x74,0xAA,0x29,0xEF,0x4E,0x04,0x5F,0x7D,0xA8,0x54,0x8D,0x59,0x90,0x28,0x93,0x90, + 0x45,0x82,0x31,0xE2,0xC5,0xE8,0xFC,0xFB,0x91,0x07,0xD0,0x89,0x60,0x69,0xAB,0x4A, + 0xB1,0x63,0x39,0xF9,0xD9,0xED,0xFC,0x81,0xB9,0x28,0x0B,0xBA,0x53,0xC1,0xF7,0x94, + 0xE4,0x1A,0x02,0xAE,0xD9,0x02,0x42,0x43,0xAE,0xFC,0x26,0x4C,0x75,0x6C,0x51,0xAD, + 0x11,0xB9,0xBA,0x65,0xD1,0x5D,0x51,0x15,0x0D,0xDA,0xAC,0x26,0x53,0x77,0xFE,0x68, + 0xFD,0x83,0xD3,0xB0,0x29,0x26,0xC5,0x2F,0x2F,0x2B,0x76,0x4A,0x62,0x7C,0x41,0xBB, + 0x2A,0xF7,0xE4,0x51,0x28,0x1D,0x34,0xB1,0x46,0x44,0x58,0x04,0x8F,0x64,0x20,0xBE, + 0x26,0x5C,0x36,0x07,0xD1,0x7C,0xAB,0x3D,0x12,0x02,0xD5,0xC1,0xB6,0xBF,0x12,0x3A, + 0xC4,0x8A,0x61,0x8E,0x16,0x55,0x61,0x88,0xA5,0xBE,0xA8,0xAC,0x3B,0xD3,0xEB,0xAC, + 0xB8,0xEF,0x54,0xA7,0x78,0x99,0xA1,0x04,0x20,0x20,0x28,0x37,0xC5,0x47,0x63,0xB3, + 0x7D,0x0D,0xBB,0x8A,0x6A,0x5B,0x11,0x9C,0x08,0x09,0xCD,0xFB,0x8E,0x68,0xDF,0xE8, + 0x8C,0x7B,0x27,0x38,0xCC,0x6C,0x0B,0xCE,0x62,0xD1,0x87,0x91,0xC7,0x8B,0xD5,0xE7, + 0xA2,0xF2,0x8F,0x4F,0x32,0xB8,0xE6,0xE6,0xE1,0x20,0x82,0x9D,0xED,0x56,0xBA,0x88, + 0x2D,0xB0,0xCD,0x72,0x20,0x13,0x71,0x34,0x9C,0x02,0x0B,0x72,0x9C,0x27,0x67,0x5F, + 0x2A,0x77,0x4E,0x43,0xE5,0x71,0x96,0x36,0x11,0x0F,0x35, +}; + +/* subject:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.badssl.com */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +uint8_t _leaf2048SystemTrust[] = { + 0x30,0x82,0x05,0x4B,0x30,0x82,0x04,0x33,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, + 0x8E,0x18,0x71,0x4B,0x34,0xE7,0x5E,0x8D,0xAE,0xFB,0xE8,0xF6,0x4C,0x3A,0x82,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, + 0x90,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,0x36,0x30,0x34,0x06,0x03,0x55, + 0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44, + 0x6F,0x6D,0x61,0x69,0x6E,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,0x36,0x30,0x37,0x30,0x37,0x30,0x30,0x30,0x30,0x30, + 0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x39,0x30,0x35,0x32,0x33,0x35,0x39,0x35,0x39, + 0x5A,0x30,0x59,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x56,0x61,0x6C, + 0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13, + 0x14,0x50,0x6F,0x73,0x69,0x74,0x69,0x76,0x65,0x53,0x53,0x4C,0x20,0x57,0x69,0x6C, + 0x64,0x63,0x61,0x72,0x64,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C, + 0x2A,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,0xC2,0x04,0xEC, + 0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58,0xCC,0x93,0x18,0xEB,0x5C, + 0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B,0x2C,0x76,0x3E,0x6C,0xC0, + 0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6,0xB0,0xF9,0x72,0xC9,0x86, + 0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B,0xBC,0xE9,0x94,0x2E,0x50, + 0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46,0xD3,0x16,0x87,0x27,0x9F, + 0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84,0x4C,0x79,0x55,0xE4,0xD1, + 0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB,0xAA,0xFF,0x6E,0xFF,0x60, + 0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD,0x4D,0xC0,0xC4,0xFC,0x53, + 0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2,0x33,0x48,0xE7,0x22,0x71, + 0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA,0x6C,0xB5,0x72,0xB4,0x7E, + 0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12,0xAB,0xDE,0xC3,0x0F,0x47, + 0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD,0x22,0x06,0x29,0x2E,0xB1, + 0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40,0x72,0x00,0xAC,0x92,0x08, + 0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B,0x54,0x98,0x40,0x27,0x85, + 0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45,0x55,0x7C,0xF9,0x64,0x3F, + 0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1,0xCA,0x85,0x02,0x03,0x01, + 0x00,0x01,0xA3,0x82,0x01,0xD5,0x30,0x82,0x01,0xD1,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90, + 0xEA,0x12,0x56,0x73,0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81,0x0B,0x3A,0x47,0x69,0x71, + 0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,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,0x4F,0x06,0x03,0x55,0x1D,0x20,0x04,0x48, + 0x30,0x46,0x30,0x3A,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x02, + 0x07,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,0x08, + 0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x01,0x30,0x54,0x06,0x03,0x55,0x1D,0x1F,0x04, + 0x4D,0x30,0x4B,0x30,0x49,0xA0,0x47,0xA0,0x45,0x86,0x43,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,0x44,0x6F,0x6D,0x61, + 0x69,0x6E,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, + 0x85,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x79,0x30,0x77,0x30, + 0x4F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x43,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,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,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,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30, + 0x1A,0x82,0x0C,0x2A,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82, + 0x0A,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A, + 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x75, + 0x48,0x83,0x88,0x9C,0x55,0x24,0x37,0x30,0x07,0xEB,0x26,0x68,0xC8,0x79,0x1C,0x5C, + 0xAE,0x9A,0x02,0x9A,0xB5,0x52,0x75,0x44,0xAC,0xA9,0xED,0x59,0x65,0xD0,0xC6,0x47, + 0x26,0x04,0x8D,0x57,0x89,0x16,0x2E,0x71,0x18,0x48,0x98,0x68,0x1C,0xF6,0x31,0xF5, + 0x26,0x4B,0xE8,0x81,0x44,0xB1,0xFF,0x5C,0x65,0x3D,0x78,0x54,0x94,0xC3,0x86,0x9D, + 0x48,0x96,0xE8,0x32,0xAF,0xE1,0x8F,0x94,0x47,0xBE,0x37,0x8C,0xC3,0xED,0x4D,0x97, + 0xBB,0xC6,0x2A,0x37,0x72,0x01,0x3A,0x8F,0x82,0xA4,0x34,0x44,0xC4,0xC4,0xF8,0x50, + 0x24,0x48,0x9E,0x19,0xF0,0xEC,0xE1,0xC6,0x13,0x44,0x26,0xB6,0x65,0xE1,0x62,0x49, + 0x87,0xA4,0xF4,0xD8,0xC4,0x39,0x3C,0x7D,0x42,0xC8,0xA4,0x2A,0x54,0x05,0xA0,0xDC, + 0x0A,0xF8,0x2B,0x22,0x94,0x93,0x78,0x4E,0x6A,0x36,0x1B,0xD2,0xE7,0xE9,0xAE,0x84, + 0xED,0x13,0x1D,0xA1,0xF7,0xA2,0x83,0x81,0x03,0x4C,0x9E,0x21,0xFB,0xBF,0xA8,0x30, + 0xFE,0xEB,0x00,0x68,0xB1,0x7F,0xBA,0x5D,0xE2,0x5D,0xFF,0x41,0x1F,0xD6,0xF5,0xA6, + 0x5C,0x8A,0xEF,0x81,0x80,0xC8,0xF1,0x52,0x00,0x17,0x9D,0xD1,0x96,0x1A,0x7D,0x5E, + 0xD2,0x83,0xB3,0x82,0xC2,0x3D,0x46,0x83,0xA5,0x1E,0xB4,0x36,0x35,0x38,0xC4,0x7A, + 0x2E,0xDF,0x0B,0xA1,0x98,0x63,0x58,0x0B,0x1E,0xD0,0x6D,0x83,0x1F,0xF1,0x72,0x4D, + 0x09,0xAC,0x96,0x1A,0x0B,0xE5,0xF6,0x34,0x4C,0xAB,0xBC,0xBC,0x99,0x5B,0x82,0x59, + 0xE6,0x6C,0xD3,0xDB,0x98,0xE0,0xCE,0x95,0x3B,0xCF,0x4E,0x17,0xC3,0xEE,0x3A, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +uint8_t _int2048SystemTrust[] = { + 0x30,0x82,0x06,0x08,0x30,0x82,0x03,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2B, + 0x2E,0x6E,0xEA,0xD9,0x75,0x36,0x6C,0x14,0x8A,0x6E,0xDB,0xA3,0x7C,0x8C,0x07,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,0x34,0x30,0x32,0x31,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x32,0x31,0x31,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x90,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,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F, + 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44,0x6F,0x6D,0x61,0x69,0x6E,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,0x8E,0xC2,0x02,0x19,0xE1,0xA0, + 0x59,0xA4,0xEB,0x38,0x35,0x8D,0x2C,0xFD,0x01,0xD0,0xD3,0x49,0xC0,0x64,0xC7,0x0B, + 0x62,0x05,0x45,0x16,0x3A,0xA8,0xA0,0xC0,0x0C,0x02,0x7F,0x1D,0xCC,0xDB,0xC4,0xA1, + 0x6D,0x77,0x03,0xA3,0x0F,0x86,0xF9,0xE3,0x06,0x9C,0x3E,0x0B,0x81,0x8A,0x9B,0x49, + 0x1B,0xAD,0x03,0xBE,0xFA,0x4B,0xDB,0x8C,0x20,0xED,0xD5,0xCE,0x5E,0x65,0x8E,0x3E, + 0x0D,0xAF,0x4C,0xC2,0xB0,0xB7,0x45,0x5E,0x52,0x2F,0x34,0xDE,0x48,0x24,0x64,0xB4, + 0x41,0xAE,0x00,0x97,0xF7,0xBE,0x67,0xDE,0x9E,0xD0,0x7A,0xA7,0x53,0x80,0x3B,0x7C, + 0xAD,0xF5,0x96,0x55,0x6F,0x97,0x47,0x0A,0x7C,0x85,0x8B,0x22,0x97,0x8D,0xB3,0x84, + 0xE0,0x96,0x57,0xD0,0x70,0x18,0x60,0x96,0x8F,0xEE,0x2D,0x07,0x93,0x9D,0xA1,0xBA, + 0xCA,0xD1,0xCD,0x7B,0xE9,0xC4,0x2A,0x9A,0x28,0x21,0x91,0x4D,0x6F,0x92,0x4F,0x25, + 0xA5,0xF2,0x7A,0x35,0xDD,0x26,0xDC,0x46,0xA5,0xD0,0xAC,0x59,0x35,0x8C,0xFF,0x4E, + 0x91,0x43,0x50,0x3F,0x59,0x93,0x1E,0x6C,0x51,0x21,0xEE,0x58,0x14,0xAB,0xFE,0x75, + 0x50,0x78,0x3E,0x4C,0xB0,0x1C,0x86,0x13,0xFA,0x6B,0x98,0xBC,0xE0,0x3B,0x94,0x1E, + 0x85,0x52,0xDC,0x03,0x93,0x24,0x18,0x6E,0xCB,0x27,0x51,0x45,0xE6,0x70,0xDE,0x25, + 0x43,0xA4,0x0D,0xE1,0x4A,0xA5,0xED,0xB6,0x7E,0xC8,0xCD,0x6D,0xEE,0x2E,0x1D,0x27, + 0x73,0x5D,0xDC,0x45,0x30,0x80,0xAA,0xE3,0xB2,0x41,0x0B,0xAF,0xBD,0x44,0x87,0xDA, + 0xB9,0xE5,0x1B,0x9D,0x7F,0xAE,0xE5,0x85,0x82,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x82,0x01,0x65,0x30,0x82,0x01,0x61,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,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90,0xEA,0x12,0x56,0x73, + 0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, + 0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,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,0x1B,0x06,0x03,0x55,0x1D, + 0x20,0x04,0x14,0x30,0x12,0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x08,0x06, + 0x06,0x67,0x81,0x0C,0x01,0x02,0x01,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,0x4E,0x2B,0x76,0x4F, + 0x92,0x1C,0x62,0x36,0x89,0xBA,0x77,0xC1,0x27,0x05,0xF4,0x1C,0xD6,0x44,0x9D,0xA9, + 0x9A,0x3E,0xAA,0xD5,0x66,0x66,0x01,0x3E,0xEA,0x49,0xE6,0xA2,0x35,0xBC,0xFA,0xF6, + 0xDD,0x95,0x8E,0x99,0x35,0x98,0x0E,0x36,0x18,0x75,0xB1,0xDD,0xDD,0x50,0x72,0x7C, + 0xAE,0xDC,0x77,0x88,0xCE,0x0F,0xF7,0x90,0x20,0xCA,0xA3,0x67,0x2E,0x1F,0x56,0x7F, + 0x7B,0xE1,0x44,0xEA,0x42,0x95,0xC4,0x5D,0x0D,0x01,0x50,0x46,0x15,0xF2,0x81,0x89, + 0x59,0x6C,0x8A,0xDD,0x8C,0xF1,0x12,0xA1,0x8D,0x3A,0x42,0x8A,0x98,0xF8,0x4B,0x34, + 0x7B,0x27,0x3B,0x08,0xB4,0x6F,0x24,0x3B,0x72,0x9D,0x63,0x74,0x58,0x3C,0x1A,0x6C, + 0x3F,0x4F,0xC7,0x11,0x9A,0xC8,0xA8,0xF5,0xB5,0x37,0xEF,0x10,0x45,0xC6,0x6C,0xD9, + 0xE0,0x5E,0x95,0x26,0xB3,0xEB,0xAD,0xA3,0xB9,0xEE,0x7F,0x0C,0x9A,0x66,0x35,0x73, + 0x32,0x60,0x4E,0xE5,0xDD,0x8A,0x61,0x2C,0x6E,0x52,0x11,0x77,0x68,0x96,0xD3,0x18, + 0x75,0x51,0x15,0x00,0x1B,0x74,0x88,0xDD,0xE1,0xC7,0x38,0x04,0x43,0x28,0xE9,0x16, + 0xFD,0xD9,0x05,0xD4,0x5D,0x47,0x27,0x60,0xD6,0xFB,0x38,0x3B,0x6C,0x72,0xA2,0x94, + 0xF8,0x42,0x1A,0xDF,0xED,0x6F,0x06,0x8C,0x45,0xC2,0x06,0x00,0xAA,0xE4,0xE8,0xDC, + 0xD9,0xB5,0xE1,0x73,0x78,0xEC,0xF6,0x23,0xDC,0xD1,0xDD,0x6C,0x8E,0x1A,0x8F,0xA5, + 0xEA,0x54,0x7C,0x96,0xB7,0xC3,0xFE,0x55,0x8E,0x8D,0x49,0x5E,0xFC,0x64,0xBB,0xCF, + 0x3E,0xBD,0x96,0xEB,0x69,0xCD,0xBF,0xE0,0x48,0xF1,0x62,0x82,0x10,0xE5,0x0C,0x46, + 0x57,0xF2,0x33,0xDA,0xD0,0xC8,0x63,0xED,0xC6,0x1F,0x94,0x05,0x96,0x4A,0x1A,0x91, + 0xD1,0xF7,0xEB,0xCF,0x8F,0x52,0xAE,0x0D,0x08,0xD9,0x3E,0xA8,0xA0,0x51,0xE9,0xC1, + 0x87,0x74,0xD5,0xC9,0xF7,0x74,0xAB,0x2E,0x53,0xFB,0xBB,0x7A,0xFB,0x97,0xE2,0xF8, + 0x1F,0x26,0x8F,0xB3,0xD2,0xA0,0xE0,0x37,0x5B,0x28,0x3B,0x31,0xE5,0x0E,0x57,0x2D, + 0x5A,0xB8,0xAD,0x79,0xAC,0x5E,0x20,0x66,0x1A,0xA5,0xB9,0xA6,0xB5,0x39,0xC1,0xF5, + 0x98,0x43,0xFF,0xEE,0xF9,0xA7,0xA7,0xFD,0xEE,0xCA,0x24,0x3D,0x80,0x16,0xC4,0x17, + 0x8F,0x8A,0xC1,0x60,0xA1,0x0C,0xAE,0x5B,0x43,0x47,0x91,0x4B,0xD5,0x9A,0x17,0x5F, + 0xF9,0xD4,0x87,0xC1,0xC2,0x8C,0xB7,0xE7,0xE2,0x0F,0x30,0x19,0x37,0x86,0xAC,0xE0, + 0xDC,0x42,0x03,0xE6,0x94,0xA8,0x9D,0xAE,0xFD,0x0F,0x24,0x51,0x94,0xCE,0x92,0x08, + 0xD1,0xFC,0x50,0xF0,0x03,0x40,0x7B,0x88,0x59,0xED,0x0E,0xDD,0xAC,0xD2,0x77,0x82, + 0x34,0xDC,0x06,0x95,0x02,0xD8,0x90,0xF9,0x2D,0xEA,0x37,0xD5,0x1A,0x60,0xD0,0x67, + 0x20,0xD7,0xD8,0x42,0x0B,0x45,0xAF,0x82,0x68,0xDE,0xDD,0x66,0x24,0x37,0x90,0x29, + 0x94,0x19,0x46,0x19,0x25,0xB8,0x80,0xD7,0xCB,0xD4,0x86,0x28,0x6A,0x44,0x70,0x26, + 0x23,0x62,0xA9,0x9F,0x86,0x6F,0xBF,0xBA,0x90,0x70,0xD2,0x56,0x77,0x85,0x78,0xEF, + 0xEA,0x25,0xA9,0x17,0xCE,0x50,0x72,0x8C,0x00,0x3A,0xAA,0xE3,0xDB,0x63,0x34,0x9F, + 0xF8,0x06,0x71,0x01,0xE2,0x82,0x20,0xD4,0xFE,0x6F,0xBD,0xB1, +}; + +#endif /* _TRUSTTESTS_EVALUATION_KEY_SIZE_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/NISTTests.m b/tests/TrustTests/EvaluationTests/NISTTests.m new file mode 100644 index 00000000..094fb916 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/NISTTests.m @@ -0,0 +1,52 @@ +/* + * 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 +#import + +#include +#include +#include +#include +#include + +#import "TrustEvaluationTestCase.h" + +@interface NISTTests : TrustEvaluationTestCase +@end + +@implementation NISTTests + +- (void)testPKITSCerts { + SecPolicyRef basicPolicy = SecPolicyCreateBasicX509(); + NSDate *testDate = CFBridgingRelease(CFDateCreateForGregorianZuluDay(NULL, 2011, 9, 1)); + + /* Run the tests. */ + [self runCertificateTestForDirectory:basicPolicy subDirectory:@"nist-certs" verifyDate:testDate]; + + CFReleaseSafe(basicPolicy); +} + +@end diff --git a/tests/TrustTests/EvaluationTests/NameConstraintsTests.m b/tests/TrustTests/EvaluationTests/NameConstraintsTests.m new file mode 100644 index 00000000..7f6a8d75 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/NameConstraintsTests.m @@ -0,0 +1,543 @@ +/* + * 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 + +#import +#import + +#include +#include +#include +#include +#include +#include + +#import "TrustEvaluationTestCase.h" +#include "NameConstraintsTests_data.h" +#include "../TestMacroConversions.h" + +@interface NameConstraintsTests : TrustEvaluationTestCase +@end + +@implementation NameConstraintsTests + +- (void)testIntersectingConstraintsInSubCA { + SecCertificateRef root = NULL, subca = NULL, leaf1 = NULL; + NSArray *certs1 = nil, *test_anchors = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017 + + require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut, + fail("Failed to create root cert")); + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut, + fail("Failed to create leaf cert 1")); + + certs1 = @[(__bridge id)leaf1, (__bridge id)subca]; + test_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")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, + fail("Failed to set verify date")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut, + fail("Failed to set anchors")); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); + +errOut: + CFReleaseNull(root); + CFReleaseNull(subca); + CFReleaseNull(leaf1); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +- (void) testNoPrePendedLabels { + SecCertificateRef root = NULL, subca = NULL, leaf2 = NULL; + NSArray *certs2 = nil, *test_anchors = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017 + + require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut, + fail("Failed to create root cert")); + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf2 = SecCertificateCreateWithBytes(NULL, _test_leaf2, sizeof(_test_leaf2)), errOut, + fail("Failed to create leaf cert 2")); + + certs2 = @[(__bridge id)leaf2, (__bridge id)subca]; + test_anchors = @[(__bridge id)root]; + + /* Test no pre-pended labels */ + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs2, + policy, &trust), errOut, + 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)test_anchors), errOut, + fail("Failed to set anchors")); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); + +errOut: + CFReleaseNull(root); + CFReleaseNull(subca); + CFReleaseNull(leaf2); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +- (void) testDNSLookingCommonName { + SecCertificateRef root = NULL, subca = NULL, leaf3 = NULL; + NSArray *certs3 = nil, *test_anchors = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:548800000.0]; // 23 May 2018 + + require_action(root = SecCertificateCreateWithBytes(NULL, _test_root, sizeof(_test_root)), errOut, + fail("Failed to create root cert")); + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf3 = SecCertificateCreateWithBytes(NULL, _test_leaf3, sizeof(_test_leaf3)), errOut, + fail("Failed to create leaf cert 3"));; + + certs3 = @[(__bridge id)leaf3, (__bridge id)subca]; + test_anchors = @[(__bridge id)root]; + + /* Test DNS-looking Common Name */ + 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)test_anchors), errOut, + fail("Failed to set anchors")); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); + +errOut: + CFReleaseNull(root); + CFReleaseNull(subca); + CFReleaseNull(leaf3); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +#if !TARGET_OS_BRIDGE +- (void)testUserAnchorWithNameConstraintsPass { + SecCertificateRef subca = NULL, leaf1 = NULL; + NSArray *certs1 = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017 + id persistentRef = nil; + + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut, + fail("Failed to create leaf cert 1")); + + certs1 = @[(__bridge id)leaf1, (__bridge id)subca]; + persistentRef = [self addTrustSettingsForCert:subca]; // subCA has name constraints + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1, + policy, &trust), errOut, + fail("Failed to create trust for leaf 1")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, + fail("Failed to set verify date")); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); + [self removeTrustSettingsForCert:subca persistentRef:persistentRef]; +errOut: + CFReleaseNull(subca); + CFReleaseNull(leaf1); + CFReleaseNull(policy); + CFReleaseNull(trust); +} +#endif + +- (void)testAppAnchorWithNameConstraintsPass { + SecCertificateRef subca = NULL, leaf1 = NULL; + NSArray *certs1 = nil, *test_anchors = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:517282600.0]; // 23 May 2017 + + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf1 = SecCertificateCreateWithBytes(NULL, _test_leaf1, sizeof(_test_leaf1)), errOut, + fail("Failed to create leaf cert 1")); + + certs1 = @[(__bridge id)leaf1, (__bridge id)subca]; + test_anchors = @[(__bridge id)subca]; // subCA has name constraints + + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1, + policy, &trust), errOut, + fail("Failed to create trust for leaf 1")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, + fail("Failed to set verify date")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut, + fail("Failed to set anchors")); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); +errOut: + CFReleaseNull(subca); + CFReleaseNull(leaf1); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +#if !TARGET_OS_BRIDGE +- (void)testUserAnchorWithNameConstraintsFail { + SecCertificateRef subca = NULL, leaf4 = NULL; + NSArray *certs1 = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // 23 May 2017 + id persistentRef = nil; + + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf4 = SecCertificateCreateWithBytes(NULL, _test_leaf4, sizeof(_test_leaf4)), errOut, + fail("Failed to create leaf cert 4")); + + certs1 = @[(__bridge id)leaf4, (__bridge id)subca]; + persistentRef = [self addTrustSettingsForCert:subca]; // subCA has name constraints + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1, + policy, &trust), errOut, + fail("Failed to create trust for leaf 4")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, + fail("Failed to set verify date")); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); + [self removeTrustSettingsForCert:subca persistentRef:persistentRef]; +errOut: + CFReleaseNull(subca); + CFReleaseNull(leaf4); + CFReleaseNull(policy); + CFReleaseNull(trust); +} +#endif + +- (void)testAppAnchorwithNameContraintsFail { + SecCertificateRef subca = NULL, leaf4 = NULL; + NSArray *certs1 = nil, *test_anchors = nil; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // 23 May 2017 + + require_action(subca = SecCertificateCreateWithBytes(NULL, _test_intermediate, sizeof(_test_intermediate)), errOut, + fail("Failed to create subca cert")); + require_action(leaf4 = SecCertificateCreateWithBytes(NULL, _test_leaf4, sizeof(_test_leaf4)), errOut, + fail("Failed to create leaf cert 4")); + + certs1 = @[(__bridge id)leaf4, (__bridge id)subca]; + test_anchors = @[(__bridge id)subca]; // subCA has name constraints + + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs1, + policy, &trust), errOut, + fail("Failed to create trust for leaf 4")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), errOut, + fail("Failed to set verify date")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)test_anchors), errOut, + fail("Failed to set anchors")); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust"); +errOut: + CFReleaseNull(subca); + CFReleaseNull(leaf4); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +/* MARK: BetterTLS tests */ +NSString *kSecTrustTestNameConstraintsResources = @"si-87-sectrust-name-constraints"; +NSString *kSecTrustTestCertificates = @"TestCertificates"; +NSString *kSecTrustTestIPAddress = @"52.20.118.238"; +NSString *kSecTrustTestDNSAddress = @"test.nameconstraints.bettertls.com"; +NSString *kSecTrustTestID = @"id"; +NSString *kSecTrustTestDNSResult = @"dns"; +NSString *kSecTrustTestIPResult = @"ip"; +NSString *kSecTrustTestExpect = @"expect"; +NSString *kSecTrustTestExpectFailure = @"ERROR"; +NSString *kSecTrustTestExpectSuccess = @"OK"; +NSString *kSecTrustTestExpectMaybeSuccess = @"WEAK-OK"; + +static NSArray *anchors = nil; +static NSURL *tmpCertsDir = nil; + +- (NSArray*)getTestsArray { + NSURL *testPlist = nil; + NSDictionary *testsDict = nil; + NSArray *testsArray = nil; + + testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:@"debugging" withExtension:@"plist" + subdirectory:kSecTrustTestNameConstraintsResources]; + if (!testPlist) { + testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:@"expects" withExtension:@"plist" + subdirectory:kSecTrustTestNameConstraintsResources]; + } + require_action_quiet(testPlist, exit, + fail("Failed to get tests plist from %@", kSecTrustTestNameConstraintsResources)); + testsDict = [NSDictionary dictionaryWithContentsOfURL:testPlist]; + require_action_quiet(testsDict, exit, fail("Failed to decode tests plist into dictionary")); + + testsArray = testsDict[@"expects"]; + require_action_quiet(testsArray, exit, fail("Failed to get expects array from test dictionary")); + require_action_quiet([testsArray isKindOfClass:[NSArray class]], exit, fail("expected array of tests")); + +exit: + return testsArray; +} + +- (NSFileHandle *)openFileForWriting:(const char *)filename { + NSFileHandle *fileHandle = NULL; + NSURL *file = [NSURL URLWithString:[NSString stringWithCString:filename encoding:NSUTF8StringEncoding] relativeToURL:tmpCertsDir]; + int fd; + off_t off; + fd = open([file fileSystemRepresentation], O_RDWR | O_CREAT | O_TRUNC, 0644); + if (fd < 0 || (off = lseek(fd, 0, SEEK_SET)) < 0) { + fail("unable to open file for archive"); + } + if (fd >= 0) { + close(fd); + } + + NSError *error; + fileHandle = [NSFileHandle fileHandleForWritingToURL:file error:&error]; + if (!fileHandle) { + fail("unable to get file handle for %@\n\terror:%@", file, error); + } + + return fileHandle; +} + +- (BOOL)extract:(NSURL *)archive { + BOOL result = NO; + int r; + struct archive_entry *entry; + + struct archive *a = archive_read_new(); + archive_read_support_filter_all(a); + archive_read_support_format_tar(a); + r = archive_read_open_filename(a, [archive fileSystemRepresentation], 16384); + if (r != ARCHIVE_OK) { + fail("unable to open archive"); + goto exit; + } + + while((r = archive_read_next_header(a, &entry)) == ARCHIVE_OK) { + @autoreleasepool { + const char *filename = archive_entry_pathname(entry); + NSFileHandle *fh = [self openFileForWriting:filename]; + ssize_t size = 0; + size_t bufsize = 4192; + uint8_t *buf = calloc(bufsize, 1); + for (;;) { + size = archive_read_data(a, buf, bufsize); + if (size < 0) { + fail("failed to read %s from archive", filename); + [fh closeFile]; + goto exit; + } + if (size == 0) { + break; + } + [fh writeData:[NSData dataWithBytes:buf length:size]]; + } + free(buf); + [fh closeFile]; + } + } + if (r != ARCHIVE_EOF) { + fail("unable to read archive header"); + } else { + result = YES; + } + +exit: + archive_read_free(a); + return result; +} + +- (BOOL)untar_test_certs { + NSError *error = nil; + NSString* pid = [NSString stringWithFormat: @"tst-%d", [[NSProcessInfo processInfo] processIdentifier]]; + NSURL* tmpPidDirURL = [[NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES] URLByAppendingPathComponent:pid isDirectory:YES]; + tmpCertsDir = [tmpPidDirURL URLByAppendingPathComponent:kSecTrustTestNameConstraintsResources isDirectory:YES]; + + if (![[NSFileManager defaultManager] createDirectoryAtURL:tmpCertsDir + withIntermediateDirectories:NO + attributes:NULL + error:&error]) { + fail("unable to create temporary cert directory: %@", error); + return NO; + } + + NSURL *certs_tar = [[NSBundle bundleForClass:[self class]] URLForResource:kSecTrustTestCertificates withExtension:nil + subdirectory:kSecTrustTestNameConstraintsResources]; + if(![self extract:certs_tar]) { + return NO; + } + + return YES; +} + +- (BOOL)extractLeaf:(NSString *)filename andAppendTo:(NSMutableArray *)certs { + NSString *fullFilename = [NSString stringWithFormat:@"%@.cer", filename]; + NSURL *leafURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename]; + if (!leafURL) { + fail("Failed to get leaf certificate for test id %@", filename); + return NO; + } + NSData *leafData = [NSData dataWithContentsOfURL:leafURL]; + if (!leafData) { + fail("Failed to get leaf certificate data for URL %@", leafURL); + return NO; + } + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)leafData); + if (!leafData) { + fail("Failed to create leaf cert for %@", leafURL); + return NO; + } + [certs addObject:(__bridge id)cert]; + CFReleaseNull(cert); + return YES; +} + +- (BOOL)extractChain:(NSString *)filename andAppendTo:(NSMutableArray *)certs { + NSString *fullFilename = [NSString stringWithFormat:@"%@.chain", filename]; + NSURL *chainURL = [tmpCertsDir URLByAppendingPathComponent:fullFilename]; + if (!chainURL) { + fail("Failed to get chain URL for %@", filename); + return NO; + } + NSString *chain = [NSString stringWithContentsOfURL:chainURL encoding:NSUTF8StringEncoding error:nil]; + if (!chain) { + fail("Failed to get chain for %@", chainURL); + return NO; + } + + NSString *pattern = @"-----BEGIN CERTIFICATE-----.+?-----END CERTIFICATE-----\n"; + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern + options:NSRegularExpressionDotMatchesLineSeparators|NSRegularExpressionUseUnixLineSeparators + error:nil]; + [regex enumerateMatchesInString:chain options:0 range:NSMakeRange(0, [chain length]) + usingBlock:^(NSTextCheckingResult * _Nullable result, NSMatchingFlags flags, BOOL * _Nonnull stop) { + NSString *certPEMString = [chain substringWithRange:[result range]]; + NSData *certPEMData = [certPEMString dataUsingEncoding:NSUTF8StringEncoding]; + SecCertificateRef cert = SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)certPEMData); + [certs addObject:(__bridge id)cert]; + CFReleaseNull(cert); + }]; + return YES; +} + +- (BOOL) getAnchor { + NSURL *rootURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"root" withExtension:@"cer" + subdirectory:kSecTrustTestNameConstraintsResources]; + if (!rootURL) { + fail("Failed to get root cert"); + return NO; + } + NSData *rootData = [NSData dataWithContentsOfURL:rootURL]; + SecCertificateRef root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)rootData); + if (!root) { + fail("failed to create root cert"); + return NO; + } + anchors = [NSArray arrayWithObject:(__bridge id)root]; + CFReleaseNull(root); + return YES; +} + +- (BOOL) runTrustForCerts:(NSArray *)certs hostname:(NSString *)hostname { + if (!anchors && ![self getAnchor]) { + return NO; + } + BOOL result = NO; + SecPolicyRef policy = SecPolicyCreateSSL(true, (__bridge CFStringRef)hostname); + SecTrustRef trust = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:531900000.0]; /* November 8, 2017 at 10:00:00 PM PST */ + require_noerr_action(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), exit, + fail("Failed to create trust ref")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), exit, + fail("Failed to add anchor")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), exit, + fail("Failed to set verify date")); + result = SecTrustEvaluateWithError(trust, nil); + +exit: + CFReleaseNull(policy); + CFReleaseNull(trust); + return result; +} + +- (void) testBetterTLS { + NSArray *testsArray = [self getTestsArray]; + if([self untar_test_certs]) { + [testsArray enumerateObjectsUsingBlock:^(NSDictionary * _Nonnull testDict, NSUInteger idx, BOOL * _Nonnull stop) { + @autoreleasepool { + /* Get the certificates */ + NSNumber *testNum = testDict[kSecTrustTestID]; + NSString *fileName = [NSString stringWithFormat:@"%@",testNum]; + NSMutableArray *certificates = [NSMutableArray array]; + if (![self extractLeaf:fileName andAppendTo:certificates] || ![self extractChain:fileName andAppendTo:certificates]) { + return; + } + + /* Test DNS address */ + NSDictionary *dnsDict = testDict[kSecTrustTestDNSResult]; + BOOL result = [self runTrustForCerts:certificates hostname:kSecTrustTestDNSAddress]; + NSString *dnsExpectedResult = dnsDict[kSecTrustTestExpect]; + if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectFailure]) { + is(result, NO, + "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result); + } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) { + is(result, YES, + "Test DNS id: %@. Expected %@. Got %d", testNum, dnsExpectedResult, result); + } else if ([dnsExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) { + /* These are "OK" but it's acceptable to reject them */ + } + + /* Test IP address */ + NSDictionary *ipDict = testDict[kSecTrustTestIPResult]; + result = [self runTrustForCerts:certificates hostname:kSecTrustTestIPAddress]; + NSString *ipExpectedResult = ipDict[kSecTrustTestExpect]; + if ([ipExpectedResult isEqualToString:kSecTrustTestExpectFailure]) { + is(result, NO, + "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result); + } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectSuccess]) { + is(result, YES, + "Test IP id: %@. Expected %@. Got %d", testNum, ipExpectedResult, result); + } else if ([ipExpectedResult isEqualToString:kSecTrustTestExpectMaybeSuccess]) { + /* These are "OK" but it's acceptable to reject them */ + } + } + }]; + } + + [[NSFileManager defaultManager] removeItemAtURL:tmpCertsDir error:nil]; +} + +@end diff --git a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h b/tests/TrustTests/EvaluationTests/NameConstraintsTests_data.h similarity index 83% rename from OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h rename to tests/TrustTests/EvaluationTests/NameConstraintsTests_data.h index 24a3efc7..b5260931 100644 --- a/OSX/sec/Security/Regressions/secitem/si-87-sectrust-name-constraints.h +++ b/tests/TrustTests/EvaluationTests/NameConstraintsTests_data.h @@ -1,7 +1,10 @@ /* - * Copyright (c) 2015-2017 Apple Inc. All Rights Reserved. + * Copyright (c) 2015-2018 Apple Inc. All Rights Reserved. */ +#ifndef _TRUSTTESTS_EVALUATION_NAME_CONSTRAINTS_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_NAME_CONSTRAINTS_TESTS_H_ + /* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Root CA */ /* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Root CA */ unsigned char _test_root[1522]={ @@ -106,14 +109,14 @@ unsigned char _test_root[1522]={ /* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Sub-CA */ /* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Root CA */ /* X509v3 Name Constraints: - Permitted: - DNS:apple.com - DNS:.apple.com - DirName: C = US, O = Apple - DirName: C = US, O = Apple Inc. - DirName: C = US, O = "Apple Computer, Inc." - Excluded: - IP:0.0.0.0/0.0.0.0 + Permitted: + DNS:apple.com + DNS:.apple.com + DirName: C = US, O = Apple + DirName: C = US, O = Apple Inc. + DirName: C = US, O = "Apple Computer, Inc." + Excluded: + IP:0.0.0.0/0.0.0.0 */ unsigned char _test_intermediate[1493]={ 0x30,0x82,0x05,0xD1,0x30,0x82,0x03,0xB9,0xA0,0x03,0x02,0x01,0x02,0x02,0x14,0x00, @@ -215,7 +218,7 @@ unsigned char _test_intermediate[1493]={ /* subject:/C=US/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Leaf 1 */ /* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Sub-CA */ /* X509v3 Subject Alternative Name: - DNS:test1.test.apple.com + DNS:test1.test.apple.com */ unsigned char _test_leaf1[1059]={ 0x30,0x82,0x04,0x1F,0x30,0x82,0x03,0x07,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x63, @@ -290,7 +293,7 @@ unsigned char _test_leaf1[1059]={ /* subject:/C=US/O=Apple/OU=Security Engineering/CN=Name Constraints Test Leaf 2 */ /* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Sub-CA */ /* X509v3 Subject Alternative Name: - DNS:apple.com + DNS:apple.com */ unsigned char _test_leaf2[1043]={ 0x30,0x82,0x04,0x0F,0x30,0x82,0x02,0xF7,0xA0,0x03,0x02,0x01,0x02,0x02,0x13,0x63, @@ -364,7 +367,7 @@ unsigned char _test_leaf2[1043]={ /* 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 + 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, @@ -436,3 +439,80 @@ uint8_t _test_leaf3[] = { 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, }; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Leaf 3 */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Name Constraints Test Sub-CA */ +/* X509v3 Subject Alternative Name: + DNS:example.com */ +uint8_t _test_leaf4[] = { + 0x30,0x82,0x04,0x40,0x30,0x82,0x03,0x28,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,0x14,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,0x39,0x30,0x34,0x32,0x33,0x30, + 0x31,0x34,0x33,0x32,0x32,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x32,0x32,0x30,0x31, + 0x34,0x33,0x32,0x32,0x5A,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,0x4C,0x65,0x61,0x66,0x20,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,0xCE,0xBF,0xF3,0xC7,0xE0,0xB3, + 0x47,0xCC,0x28,0xC4,0x0C,0xF5,0x74,0xC9,0x54,0xD2,0xF2,0x8F,0x96,0x73,0x2C,0xBA, + 0x44,0x65,0x02,0xC9,0x72,0x42,0x25,0xB6,0xB9,0xC2,0x4E,0xD3,0x77,0x00,0x00,0x31, + 0x96,0x55,0x70,0xE4,0x0E,0xE3,0xA3,0x3D,0x85,0x45,0x2D,0x7F,0xAD,0x0B,0x0E,0xBE, + 0x6D,0x81,0x83,0x80,0x53,0xAB,0x56,0x3D,0x9D,0xBF,0xB4,0xE6,0x8B,0x72,0x2D,0xE7, + 0x0F,0x7D,0xC6,0x09,0x5F,0x36,0xA8,0x94,0xE0,0xF7,0x2A,0x6A,0x44,0xDA,0x36,0x38, + 0x52,0x72,0x5D,0x4D,0x9D,0x7C,0x0D,0x22,0x22,0x8E,0x48,0x3F,0xD4,0x3E,0x7F,0x82, + 0x47,0x64,0xD9,0xD6,0x1E,0x7C,0x6F,0xBC,0x0A,0x68,0x13,0x24,0x2E,0x75,0x4E,0xDE, + 0x8F,0x07,0xD1,0xEE,0xD3,0x3E,0xD8,0x9C,0x74,0xD4,0x53,0x46,0x7A,0x63,0x47,0x78, + 0x54,0xC7,0x97,0x29,0xBD,0xF1,0xE1,0x09,0x29,0x29,0xF5,0xC3,0x74,0xAC,0xB1,0xBC, + 0xC4,0x59,0x1A,0x58,0x50,0x86,0xC7,0x25,0x82,0xF0,0x51,0xA5,0x07,0x8E,0x62,0x57, + 0x94,0xEE,0x97,0xC0,0xD5,0x3F,0x94,0xF5,0xFB,0x4D,0x13,0xAC,0xD1,0xE2,0x29,0x4D, + 0xEC,0x73,0xD0,0xC9,0x90,0xA8,0xDC,0xF9,0x23,0xE8,0x4D,0xEE,0x5B,0x47,0x63,0xD7, + 0xCE,0xC8,0xC3,0x4C,0xC3,0x96,0x53,0x26,0x9C,0xF6,0x15,0x7C,0xA5,0x59,0x9A,0x53, + 0x9A,0xD1,0x97,0x51,0x29,0x45,0x62,0xAE,0x42,0xE9,0x7A,0x7B,0xBD,0x17,0x16,0x8F, + 0x85,0xB3,0xC8,0xE4,0xDC,0xF5,0x63,0xCC,0x05,0x19,0x4A,0x3F,0xCB,0xDA,0xE1,0xBF, + 0x56,0x64,0xEA,0xD9,0x6F,0x2B,0xBC,0xA9,0xCA,0xB7,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x81,0x8E,0x30,0x81,0x8B,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,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,0xEC,0xBE,0xEC,0xA3,0x36, + 0xAC,0x6A,0x11,0xB1,0x84,0x23,0x53,0x07,0x34,0x9E,0x70,0xB5,0x02,0xBB,0x52,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,0x59,0xF8,0xA5,0xC4,0x50,0x26,0x6D,0xD4,0xFE,0x2F,0x14,0x13, + 0x02,0x42,0xD5,0x2C,0xE1,0x7C,0x6B,0xBD,0x3D,0x64,0xF1,0x51,0x80,0xDC,0x71,0xFC, + 0xD8,0x85,0x2A,0x03,0x65,0xA7,0xC6,0xAB,0xE8,0x67,0xFD,0x70,0xB4,0x8E,0xB3,0xA0, + 0x30,0x26,0x62,0x21,0x62,0xC5,0x14,0x58,0xFF,0x64,0xCB,0x06,0xC9,0x35,0x81,0x99, + 0xB5,0x05,0x4A,0x08,0x7B,0xE5,0x8F,0xAF,0xB5,0xF0,0xB4,0x26,0xE6,0x1F,0xAE,0x9B, + 0x26,0x6C,0x94,0x1D,0xE6,0x7E,0x7D,0x6C,0x5C,0xB8,0x1B,0x20,0xC4,0x5D,0x8A,0x74, + 0x4D,0x4B,0xCA,0x43,0x25,0x2A,0xBB,0x12,0x30,0x22,0xCB,0x85,0x2D,0xA6,0xD9,0x25, + 0x8B,0x97,0x4F,0x22,0xC7,0xDC,0x0A,0xAE,0x40,0x9C,0xB6,0x37,0x34,0x13,0xCF,0xA2, + 0x28,0xE7,0xF7,0xC1,0xFB,0x85,0x0C,0xA5,0x49,0x1E,0xA8,0x46,0xBC,0x30,0xEF,0xF7, + 0x70,0x8E,0xA9,0xB0,0xDC,0x94,0x50,0x94,0x0E,0x70,0xCD,0xA1,0xB1,0x8F,0x6D,0x8B, + 0x33,0xCC,0xD5,0xBA,0x15,0x5D,0x8D,0x7D,0x80,0x10,0x74,0x29,0x7E,0xE2,0xE6,0x6B, + 0xF3,0xBB,0xFC,0x09,0xF6,0x85,0x2C,0xD3,0xB3,0x2F,0x10,0x71,0x3D,0x64,0x0C,0x4D, + 0x18,0x8D,0xD3,0x08,0x01,0xE0,0x2C,0x2A,0x96,0xF6,0xFC,0x21,0x09,0x4B,0xE1,0x0F, + 0x35,0x41,0x1D,0x93,0x85,0x82,0x10,0x13,0x7C,0x94,0x77,0x1D,0x0A,0x41,0x6D,0xB9, + 0x4C,0x79,0xE5,0xC7,0x5B,0x8E,0x54,0xD6,0x34,0x1D,0x75,0x12,0x55,0xF0,0x01,0x9E, + 0x50,0x85,0xE7,0xD8,0xC6,0x15,0xF3,0xC9,0xE2,0x2B,0x58,0x21,0x90,0x2F,0x44,0x39, + 0xA2,0x6C,0x27,0x24, +}; +#endif /* _TRUSTTESTS_EVALUATION_NAME_CONSTRAINTS_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/PathParseTests.m b/tests/TrustTests/EvaluationTests/PathParseTests.m new file mode 100644 index 00000000..2d65d23f --- /dev/null +++ b/tests/TrustTests/EvaluationTests/PathParseTests.m @@ -0,0 +1,105 @@ +/* + * 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 "../TestMacroConversions.h" + +#include "TrustEvaluationTestCase.h" +#include "PathParseTests_data.h" + +const NSString *kSecTestPathFailureResources = @"si-18-certificate-parse/PathFailureCerts"; + +@interface PathParseTests : TrustEvaluationTestCase + +@end + +@implementation PathParseTests + +- (void)testPathParseFailure { + NSArray * certURLs = nil; + SecCertificateRef root = nil; + + NSURL *rootURL = [[NSBundle bundleForClass:[self class]]URLForResource:@"root" withExtension:@".cer" subdirectory:@"si-18-certificate-parse"]; + XCTAssert(root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)[NSData dataWithContentsOfURL:rootURL]), "Unable to create root cert"); + certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestPathFailureResources]; + XCTAssertTrue([certURLs count] > 0, "Unable to find parse test failure certs in bundle."); + + if (root && [certURLs count] > 0) { + [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + + require_noerr_action(SecTrustCreateWithCertificates(cert, policy, &trust), blockOut, + fail("Unable to create trust with certificate: %@", url)); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)[NSArray arrayWithObject:(__bridge id)root]), + blockOut, fail("Unable to set trust in root cert: %@", url)); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)[NSDate dateWithTimeIntervalSinceReferenceDate:507200000.0]), + blockOut, fail("Unable to set verify date: %@", url)); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "Got wrong trust result for %@", url); + + require_action(cert, blockOut, + fail("Failed to parse cert with SPKI error: %@", url)); + + blockOut: + CFReleaseNull(cert); + CFReleaseNull(trust); + CFReleaseNull(policy); + }]; + } +} + +- (void)testUnparseableExtensions { + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _bad_extension_leaf, sizeof(_bad_extension_leaf)); + SecCertificateRef root = NULL; + SecTrustRef trust = NULL; + SecPolicyRef policy = SecPolicyCreateBasicX509(); + CFErrorRef error = NULL; + + NSURL *rootURL = [[NSBundle bundleForClass:[self class]]URLForResource:@"root" withExtension:@".cer" subdirectory:@"si-18-certificate-parse"]; + XCTAssert(root = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)[NSData dataWithContentsOfURL:rootURL]), "Unable to create root cert"); + NSArray *anchors = @[(__bridge id)root]; + + require_noerr_action(SecTrustCreateWithCertificates(leaf, policy, &trust), errOut, + fail("Unable to create trust with certificate with unparseable extension")); + require_noerr_action(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), + errOut, fail("Unable to set trust anchors")); + require_noerr_action(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)[NSDate dateWithTimeIntervalSinceReferenceDate:507200000.0]), + errOut, fail("Unable to set verify date")); + XCTAssertFalse(SecTrustEvaluateWithError(trust, &error), "Got wrong trust result cert"); + XCTAssert(error != NULL); + XCTAssert(CFErrorGetCode(error) == errSecUnknownCertExtension); + +errOut: + CFReleaseNull(leaf); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(error); +} + +@end diff --git a/tests/TrustTests/EvaluationTests/PathParseTests_data.h b/tests/TrustTests/EvaluationTests/PathParseTests_data.h new file mode 100644 index 00000000..507cb672 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/PathParseTests_data.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 Apple Inc. All Rights Reserved. + */ + +#ifndef _TRUSTTESTS_EVALUATION_PATH_PARSE_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_PATH_PARSE_TESTS_H_ + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CoreTrust Test Leaf 1 */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=CoreTrust Test CA */ +const uint8_t _bad_extension_leaf[] = { + 0x30,0x82,0x02,0x85,0x30,0x82,0x02,0x2C,0xA0,0x03,0x02,0x01,0x02,0x02,0x15,0x00, + 0xD5,0xEC,0xDB,0x27,0x18,0xA7,0xEC,0x88,0x42,0xBA,0xC8,0xCD,0xE6,0xFC,0x34,0x9A, + 0x4D,0x36,0xD3,0x4C,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x30, + 0x81,0x86,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,0x1A,0x30,0x18, + 0x06,0x03,0x55,0x04,0x03,0x0C,0x11,0x43,0x6F,0x72,0x65,0x54,0x72,0x75,0x73,0x74, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x37,0x30,0x31, + 0x32,0x36,0x32,0x33,0x32,0x33,0x33,0x32,0x5A,0x17,0x0D,0x31,0x37,0x30,0x31,0x32, + 0x37,0x32,0x33,0x32,0x33,0x33,0x32,0x5A,0x30,0x81,0x8A,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15, + 0x43,0x6F,0x72,0x65,0x54,0x72,0x75,0x73,0x74,0x20,0x54,0x65,0x73,0x74,0x20,0x4C, + 0x65,0x61,0x66,0x20,0x31,0x30,0x56,0x30,0x10,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D, + 0x02,0x01,0x06,0x05,0x2B,0x81,0x04,0x00,0x0A,0x03,0x42,0x00,0x04,0xFA,0x43,0x00, + 0x5E,0xEF,0xEF,0x33,0xBA,0x03,0x5F,0x7B,0x42,0xE2,0xCF,0x7D,0x2A,0x61,0x69,0xE2, + 0xEB,0x7A,0xE1,0x98,0x49,0x60,0x0D,0xD8,0xCB,0x99,0x09,0x91,0x4E,0x8B,0x12,0xA4, + 0x7F,0x19,0xAE,0xF4,0x62,0x8D,0x36,0x1A,0x34,0x9C,0x64,0xFE,0xE9,0xB2,0x02,0x3E, + 0xFD,0x83,0x9D,0x7E,0x40,0x7D,0x21,0x0E,0xD4,0xDA,0x97,0x12,0xE2,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,0x05,0xA0,0x30, + 0x13,0x06,0x03,0x55,0x1D,0x25,0x04,0x0C,0x31,0x0A,0x06,0x08,0x2B,0x06,0x01,0x05, + 0x05,0x07,0x03,0x02,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xBB, + 0x3E,0xCE,0xF4,0xBA,0x9A,0xBC,0x9F,0x1E,0xF9,0x73,0xDB,0x11,0xEB,0x55,0x93,0xA3, + 0x59,0x5B,0x6C,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, + 0xEC,0xC0,0x39,0x7A,0xDF,0x66,0x7B,0x15,0xB1,0x13,0x9E,0x8D,0xD6,0xB2,0x77,0xA6, + 0xBA,0xEE,0x2A,0xA1,0x30,0x09,0x06,0x07,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01,0x03, + 0x48,0x00,0x30,0x45,0x02,0x20,0x2B,0x9C,0xC9,0xD3,0x86,0x66,0x7A,0xCD,0x58,0xFC, + 0x48,0x06,0xF6,0xC6,0xCC,0xE2,0x0F,0xA8,0xE4,0x66,0x16,0x2C,0xA8,0xCC,0x51,0xB6, + 0x1B,0x56,0xAC,0xBB,0x9F,0xD4,0x02,0x21,0x00,0xA2,0x51,0xAC,0x76,0xE6,0x3B,0x3B, + 0x0D,0x79,0xCD,0xB6,0x71,0x66,0x9E,0xEF,0x3C,0xB8,0x56,0xEA,0xBF,0x64,0x48,0x5B, + 0x0B,0x9B,0x38,0x06,0xBE,0xBA,0xE5,0xC9,0x17, +}; + + +#endif /* _TRUSTTESTS_EVALUATION_PATH_PARSE_TESTS_H_ */ diff --git a/OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.m b/tests/TrustTests/EvaluationTests/PathScoringTests.m similarity index 76% rename from OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.m rename to tests/TrustTests/EvaluationTests/PathScoringTests.m index 1e7d3897..24ca7b93 100644 --- a/OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.m +++ b/tests/TrustTests/EvaluationTests/PathScoringTests.m @@ -1,18 +1,40 @@ /* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * 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 +#include -#include "shared_regressions.h" +#import "TrustEvaluationTestCase.h" +#include "PathScoringTests_data.h" +#include "../TestMacroConversions.h" -#include "si-97-sectrust-path-scoring.h" +@interface PathScoringTests : TrustEvaluationTestCase +@end + +@implementation PathScoringTests static SecCertificateRef leaf = NULL; static SecCertificateRef intSHA2 = NULL; @@ -29,7 +51,7 @@ static SecPolicyRef sslPolicy = NULL; static NSDate *verifyDate1 = nil; static NSDate *verifyDate2 = nil; -static void setup_globals(void) { ++ (void)setUp { leaf = SecCertificateCreateWithBytes(NULL, _pathScoringLeaf, sizeof(_pathScoringLeaf)); intSHA2 = SecCertificateCreateWithBytes(NULL, _pathScoringIntSHA2, sizeof(_pathScoringIntSHA2)); intSHA1 = SecCertificateCreateWithBytes(NULL, _pathScoringIntSHA1, sizeof(_pathScoringIntSHA1)); @@ -50,7 +72,7 @@ static void setup_globals(void) { verifyDate2 = [NSDate dateWithTimeIntervalSinceReferenceDate:486084050.0]; } -static void cleanup_globals(void) { ++ (void)tearDown { CFReleaseNull(leaf); CFReleaseNull(intSHA2); CFReleaseNull(intSHA1); @@ -66,12 +88,12 @@ static void cleanup_globals(void) { CFReleaseNull(sslPolicy); } -static bool testTrust(NSArray *certs, NSArray *anchors, SecPolicyRef policy, - NSDate *verifyDate, SecTrustResultType expectedResult, +static bool evaluateTrust(NSArray *certs, NSArray *anchors, SecPolicyRef policy, + NSDate *verifyDate, bool expectedResult, NSArray *expectedChain) { bool testPassed = false; SecTrustRef trust = NULL; - SecTrustResultType trustResult = kSecTrustResultInvalid; + bool result = false; require_noerr_string(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust), @@ -82,15 +104,14 @@ static bool testTrust(NSArray *certs, NSArray *anchors, SecPolicyRef policy, } require_noerr_string(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)verifyDate), errOut, "failed to set verify date"); - require_noerr_string(SecTrustEvaluate(trust, &trustResult), - errOut, "failed to evaluate trust"); + result = SecTrustEvaluateWithError(trust, NULL); /* check result */ - if (expectedResult == kSecTrustResultUnspecified) { - require_string(trustResult == expectedResult, + if (expectedResult) { + require_string(result == expectedResult, errOut, "unexpected untrusted chain"); - } else if (expectedResult == kSecTrustResultRecoverableTrustFailure) { - require_string(trustResult == expectedResult, + } else { + require_string(result == expectedResult, errOut, "unexpected trusted chain"); } @@ -123,25 +144,24 @@ errOut: * rootSHA1 rootSHA2_2 */ -static void tests(SecPolicyRef policy) { +- (void)exerciseChainsForPolicy:(SecPolicyRef)policy { NSArray *certs = nil; NSArray *anchors = nil; NSArray *chain = nil; - SecTrustResultType expectedTrustResult = ((policy == basicPolicy) ? kSecTrustResultUnspecified : - kSecTrustResultRecoverableTrustFailure); + bool expectedTrustResult = ((policy == basicPolicy) ? true : false); /* Choose a short chain over a long chain, when ending in a self-signed cert */ certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)crossSHA2_SHA2]; anchors = @[(__bridge id)rootSHA2, (__bridge id)rootSHA2_2]; chain = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)rootSHA2]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose shorter chain over longer chain, SHA-2", (policy == basicPolicy) ? "accept" : "reject"); certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)intSHA1, (__bridge id)crossSHA2_SHA1]; anchors = @[(__bridge id)rootSHA1]; chain = @[(__bridge id)leaf, (__bridge id)intSHA1, (__bridge id)rootSHA1]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose shorter chain over longer chain, SHA-1", (policy == basicPolicy) ? "accept" : "reject"); @@ -149,13 +169,13 @@ static void tests(SecPolicyRef policy) { certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)intSHA1]; anchors = @[(__bridge id)rootSHA1, (__bridge id)rootSHA2]; chain = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)rootSHA2]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose SHA-2 chain over SHA-1 chain, order 1", (policy == basicPolicy) ? "accept" : "reject"); certs = @[(__bridge id)leaf, (__bridge id)intSHA1, (__bridge id)intSHA2]; anchors = @[(__bridge id)rootSHA2, (__bridge id)rootSHA1]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose SHA-2 chain over SHA-1 chain, order 2", (policy == basicPolicy) ? "accept" : "reject"); @@ -163,7 +183,7 @@ static void tests(SecPolicyRef policy) { certs = @[(__bridge id)leaf, (__bridge id)intSHA1, (__bridge id)intSHA2, (__bridge id)crossSHA2_SHA2]; anchors = @[(__bridge id)rootSHA1, (__bridge id)rootSHA2_2]; chain = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)crossSHA2_SHA2, (__bridge id)rootSHA2_2]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose longer SHA-2 chain over shorter SHA-1 chain", (policy == basicPolicy) ? "accept" : "reject"); @@ -171,7 +191,7 @@ static void tests(SecPolicyRef policy) { certs = @[(__bridge id)leaf, (__bridge id)int1024, (__bridge id)intSHA1]; anchors = @[(__bridge id)root1024, (__bridge id)rootSHA1]; chain = @[(__bridge id)leaf, (__bridge id)int1024, (__bridge id)root1024]; - ok(testTrust(certs, anchors, policy, verifyDate2, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate2, expectedTrustResult, chain), "%s test: choose temporally valid chain over invalid chain", (policy == basicPolicy) ? "accept" : "reject"); @@ -179,7 +199,7 @@ static void tests(SecPolicyRef policy) { certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)intSHA1, (__bridge id)rootSHA2]; anchors = @[(__bridge id)rootSHA1]; chain = @[(__bridge id)leaf, (__bridge id)intSHA1, (__bridge id)rootSHA1]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose an anchored chain over an unanchored chain", (policy == basicPolicy) ? "accept" : "reject"); @@ -187,7 +207,7 @@ static void tests(SecPolicyRef policy) { certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)intSHA1, (__bridge id)rootSHA2]; anchors = @[(__bridge id)rootSHA1]; chain = @[(__bridge id)leaf, (__bridge id)intSHA1, (__bridge id)rootSHA1]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose anchored SHA-1 chain over unanchored SHA-2 chain", (policy == basicPolicy) ? "accept" : "reject"); @@ -195,19 +215,17 @@ static void tests(SecPolicyRef policy) { certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)rootSHA2, (__bridge id)crossSHA2_SHA1, (__bridge id)crossSHA2_SHA2, (__bridge id)rootSHA2_2]; chain = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)crossSHA2_SHA1, (__bridge id)rootSHA1]; - ok(testTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), + ok(evaluateTrust(certs, anchors, policy, verifyDate1, expectedTrustResult, chain), "%s test: choose anchored cross-signed chain over unanchored chains", (policy == basicPolicy) ? "accept" : "reject"); } -static void accept_tests(void) { - tests(basicPolicy); - +- (void)testPassingEvals { + [self exerciseChainsForPolicy:basicPolicy]; } -static void reject_tests(void) { - /* The leaf certificate is a client SSL certificate, and will fail the sslPolicy. */ - tests(sslPolicy); +- (void)testFailingEvals { + [self exerciseChainsForPolicy:sslPolicy]; /* reject only tests */ NSArray *certs = nil; @@ -218,39 +236,27 @@ static void reject_tests(void) { certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)int1024]; anchors = @[(__bridge id)rootSHA2, (__bridge id)root1024]; chain = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)rootSHA2]; - ok(testTrust(certs, anchors, sslPolicy, verifyDate1, kSecTrustResultRecoverableTrustFailure, chain), + ok(evaluateTrust(certs, anchors, sslPolicy, verifyDate1, false, chain), "reject test: choose 2048-bit chain over 1024-bit chain, order 1"); certs = @[(__bridge id)leaf, (__bridge id)int1024, (__bridge id)intSHA2]; anchors = @[(__bridge id)root1024, (__bridge id)rootSHA2]; - ok(testTrust(certs, anchors, sslPolicy, verifyDate1, kSecTrustResultRecoverableTrustFailure, chain), + ok(evaluateTrust(certs, anchors, sslPolicy, verifyDate1, false, chain), "reject test: choose 2048-bit chain over 1024-bit chain, order 2"); /* Choose a complete chain over an incomplete chain */ certs = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)intSHA1, (__bridge id)rootSHA1]; anchors = @[]; chain = @[(__bridge id)leaf, (__bridge id)intSHA1, (__bridge id)rootSHA1]; - ok(testTrust(certs, anchors, sslPolicy, verifyDate1, kSecTrustResultRecoverableTrustFailure, chain), + ok(evaluateTrust(certs, anchors, sslPolicy, verifyDate1, false, chain), "reject test: choose a chain that ends in a self-signed cert over one that doesn't"); /* Choose a long chain over a short chain when not ending with a self-signed cert */ certs = @[(__bridge id)leaf, (__bridge id)crossSHA2_SHA2, (__bridge id)intSHA2]; anchors = nil; chain = @[(__bridge id)leaf, (__bridge id)intSHA2, (__bridge id)crossSHA2_SHA2]; - ok(testTrust(certs, anchors, sslPolicy, verifyDate1, kSecTrustResultRecoverableTrustFailure, chain), + ok(evaluateTrust(certs, anchors, sslPolicy, verifyDate1, false, chain), "reject test: choose longer chain over shorter chain, no roots"); } -int si_97_sectrust_path_scoring(int argc, char *const *argv) -{ - plan_tests(2*9 + 4); - - @autoreleasepool { - setup_globals(); - accept_tests(); - reject_tests(); - cleanup_globals(); - } - - return 0; -} +@end diff --git a/OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.h b/tests/TrustTests/EvaluationTests/PathScoringTests_data.h similarity index 99% rename from OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.h rename to tests/TrustTests/EvaluationTests/PathScoringTests_data.h index 5466b82f..14c60dee 100644 --- a/OSX/sec/Security/Regressions/secitem/si-97-sectrust-path-scoring.h +++ b/tests/TrustTests/EvaluationTests/PathScoringTests_data.h @@ -1,9 +1,9 @@ /* - * Copyright (c) 2016 Apple Inc. All Rights Reserved. + * Copyright (c) 2016-2018 Apple Inc. All Rights Reserved. */ -#ifndef si_97_sectrust_path_scoring_h -#define si_97_sectrust_path_scoring_h +#ifndef _TRUSTTESTS_EVALUATION_PATH_SCORING_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_PATH_SCORING_TESTS_H_ /* Path Scoring Hierarchy * _pathScorignLeaf @@ -682,4 +682,4 @@ unsigned char _pathScoringSHA2Root2[1004]={ 0xA6,0xB4,0x43,0x6A,0xA2,0x98,0x0F,0x55,0xE4,0xA9,0xD1,0x78, }; -#endif /* si_97_sectrust_path_scoring_h */ +#endif /* _TRUSTTESTS_EVALUATION_PATH_SCORING_TESTS_H_*/ diff --git a/tests/TrustTests/EvaluationTests/PolicyTests.m b/tests/TrustTests/EvaluationTests/PolicyTests.m new file mode 100644 index 00000000..121f7414 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/PolicyTests.m @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2016-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@ + */ + + +/* INSTRUCTIONS FOR ADDING NEW SUBTESTS: + * 1. Add the certificates, as DER-encoded files with the 'cer' extension, to OSX/shared_regressions/si-20-sectrust-policies-data/ + * NOTE: If your cert needs to be named with "(i[Pp]hone|i[Pp]ad|i[Pp]od)", you need to make two copies -- one named properly + * and another named such that it doesn't match that regex. Use the regex trick below for TARGET_OS_TV to make sure your test + * works. + * 2. Add a new dictionary to the test plist (OSX/shared_regressions/si-20-sectrust-policies-data/PinningPolicyTrustTest.plist). + * This dictionary must include: (see constants below) + * MajorTestName + * MinorTestName + * Policies + * Leaf + * Intermediates + * ExpectedResult + * It is strongly recommended that all test dictionaries include the Anchors and VerifyDate keys. + * Addtional optional keys are defined below. + */ + +/* INSTRUCTIONS FOR DEBUGGING SUBTESTS: + * Add a debugging.plist to OSX/shared_regressions/si-20-sectrust-policies-data/ containing only those subtest dictionaries + * you want to debug. + */ + +#include +#import +#import + +#include +#include +#include +#include +#include +#include + +#import "TrustEvaluationTestCase.h" +#include "../TestMacroConversions.h" +#include "../TrustEvaluationTestHelpers.h" + +const NSString *kSecTrustTestPinningPolicyResources = @"si-20-sectrust-policies-data"; + +@interface PolicyTests : TrustEvaluationTestCase +@end + +@implementation PolicyTests + +- (void)testPolicies { + NSURL *testPlist = nil; + NSArray *testsArray = nil; + + testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:@"debugging" withExtension:@"plist" + subdirectory:(NSString *)kSecTrustTestPinningPolicyResources]; + if (!testPlist) { + testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:nil withExtension:@"plist" + subdirectory:(NSString *)kSecTrustTestPinningPolicyResources ]; + } + if (!testPlist) { + fail("Failed to get tests plist from %@", kSecTrustTestPinningPolicyResources); + return; + } + + testsArray = [NSArray arrayWithContentsOfURL: testPlist]; + if (!testsArray) { + fail("Failed to create array from plist"); + return; + } + + [testsArray enumerateObjectsUsingBlock:^(NSDictionary *testDict, NSUInteger idx, BOOL * _Nonnull stop) { + TestTrustEvaluation *testObj = [[TestTrustEvaluation alloc] initWithTrustDictionary:testDict]; + XCTAssertNotNil(testObj, "failed to create test object for %lu", (unsigned long)idx); + + NSError *testError = nil; + XCTAssert([testObj evaluateForExpectedResults:&testError], "Test %@ failed: %@", testObj.fullTestName, testError); + }]; +} + +@end diff --git a/tests/TrustTests/EvaluationTests/SSLPolicyTests.m b/tests/TrustTests/EvaluationTests/SSLPolicyTests.m new file mode 100644 index 00000000..79f32b67 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/SSLPolicyTests.m @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2015-2019 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 + +#include +#include +#include +#include +#include + +#include "../TestMacroConversions.h" +#include "SSLPolicyTests_data.h" +#import "TrustEvaluationTestCase.h" + +@interface SSLPolicyTests : TrustEvaluationTestCase +@end + +@implementation SSLPolicyTests + +- (void)testSSLPolicyCerts +{ + NSArray *testPlistURLs = [[NSBundle bundleForClass:[self class]] URLsForResourcesWithExtension:@"plist" subdirectory:@"ssl-policy-certs"]; + if (testPlistURLs.count != 1) { + fail("failed to find the test plist"); + return; + } + + NSDictionary *tests_dictionary = [NSDictionary dictionaryWithContentsOfURL:testPlistURLs[0]]; + if (!tests_dictionary) { + fail("failed to create test driver dictionary"); + return; + } + + [tests_dictionary enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSDictionary * _Nonnull obj, BOOL * _Nonnull stop) { + CFDictionaryRef test_info = (__bridge CFDictionaryRef)obj; + CFStringRef test_name = (__bridge CFStringRef)key, file = NULL, reason = NULL, expectedResult = NULL, failureReason = NULL; + CFErrorRef trustError = NULL; + NSURL *cert_file_url = NULL; + NSData *cert_data = nil; + bool expectTrustSuccess = false; + + SecCertificateRef leaf = NULL, root = NULL; + CFStringRef hostname = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + CFArrayRef anchor_array = NULL; + CFDateRef date = NULL; + + /* get filename in test dictionary */ + file = CFDictionaryGetValue(test_info, CFSTR("Filename")); + require_action_quiet(file, cleanup, fail("%@: Unable to load filename from plist", test_name)); + + /* get leaf certificate from file */ + cert_file_url = [[NSBundle bundleForClass:[self class]] URLForResource:(__bridge NSString *)file withExtension:@"cer" subdirectory:@"ssl-policy-certs"]; + require_action_quiet(cert_file_url, cleanup, fail("%@: Unable to get url for cert file %@", + test_name, file)); + + cert_data = [NSData dataWithContentsOfURL:cert_file_url]; + + /* create certificates */ + leaf = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)cert_data); + root = SecCertificateCreateWithBytes(NULL, _SSLTrustPolicyTestRootCA, sizeof(_SSLTrustPolicyTestRootCA)); + require_action_quiet(leaf && root, cleanup, fail("%@: Unable to create certificates", test_name)); + + /* create policy */ + hostname = CFDictionaryGetValue(test_info, CFSTR("Hostname")); + require_action_quiet(hostname, cleanup, fail("%@: Unable to load hostname from plist", test_name)); + + policy = SecPolicyCreateSSL(true, hostname); + require_action_quiet(policy, cleanup, fail("%@: Unable to create SSL policy with hostname %@", + test_name, hostname)); + + /* create trust ref */ + OSStatus err = SecTrustCreateWithCertificates(leaf, policy, &trust); + CFRelease(policy); + require_noerr_action(err, cleanup, ok_status(err, "SecTrustCreateWithCertificates")); + + /* set anchor in trust ref */ + anchor_array = CFArrayCreate(NULL, (const void **)&root, 1, &kCFTypeArrayCallBacks); + require_action_quiet(anchor_array, cleanup, fail("%@: Unable to create anchor array", test_name)); + err = SecTrustSetAnchorCertificates(trust, anchor_array); + require_noerr_action(err, cleanup, ok_status(err, "SecTrustSetAnchorCertificates")); + + /* set date in trust ref to 4 Sep 2015 */ + date = CFDateCreate(NULL, 463079909.0); + require_action_quiet(date, cleanup, fail("%@: Unable to create verify date", test_name)); + err = SecTrustSetVerifyDate(trust, date); + CFRelease(date); + require_noerr_action(err, cleanup, ok_status(err, "SecTrustSetVerifyDate")); + + /* evaluate */ + bool is_valid = SecTrustEvaluateWithError(trust, &trustError); + if (!is_valid) { + failureReason = CFErrorCopyDescription(trustError); + } + + /* get expected result for test */ + expectedResult = CFDictionaryGetValue(test_info, CFSTR("Result")); + require_action_quiet(expectedResult, cleanup, fail("%@: Unable to get expected result",test_name)); + if (!CFStringCompare(expectedResult, CFSTR("kSecTrustResultUnspecified"), 0) || + !CFStringCompare(expectedResult, CFSTR("kSecTrustResultProceed"), 0)) { + expectTrustSuccess = true; + } + + /* process results */ + if (!CFDictionaryGetValueIfPresent(test_info, CFSTR("Reason"), (const void **)&reason)) { + /* not a known failure */ + ok(is_valid == expectTrustSuccess, "%s %@%@", + expectTrustSuccess ? "REGRESSION" : "SECURITY", + test_name, + trustError); + } else if (reason) { + /* known failure */ + XCTAssertTrue(true, "TODO test: %@", reason); + ok(is_valid == expectTrustSuccess, "%@%@", + test_name, expectTrustSuccess ? failureReason : CFSTR(" valid")); + } else { + fail("%@: unable to get reason for known failure", test_name); + } + + cleanup: + CFReleaseNull(leaf); + CFReleaseNull(root); + CFReleaseNull(trust); + CFReleaseNull(anchor_array); + CFReleaseNull(failureReason); + CFReleaseNull(trustError); + }]; +} + +- (BOOL)runTrustEvaluation:(NSArray *)certs anchors:(NSArray *)anchors error:(NSError **)error +{ + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("example.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:590000000.0]; // September 12, 2019 at 9:53:20 AM PDT + SecTrustRef trustRef = NULL; + BOOL result = NO; + CFErrorRef cferror = NULL; + + require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trustRef), errOut); + require_noerr(SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)date), errOut); + + if (anchors) { + require_noerr(SecTrustSetAnchorCertificates(trustRef, (__bridge CFArrayRef)anchors), errOut); + } + + result = SecTrustEvaluateWithError(trustRef, &cferror); + if (error && cferror) { + *error = (__bridge NSError*)cferror; + } + +errOut: + CFReleaseNull(policy); + CFReleaseNull(trustRef); + CFReleaseNull(cferror); + return result; +} + +- (void)testSystemTrust_MissingEKU +{ + [self setTestRootAsSystem:_EKUTestSSLRootHash]; + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_BeforeJul2019, sizeof(_noEKU_BeforeJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "system-trusted missing EKU cert succeeded"); + + [self removeTestRootAsSystem]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testSystemTrust_AnyEKU +{ + [self setTestRootAsSystem:_EKUTestSSLRootHash]; + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_BeforeJul2019, sizeof(_anyEKU_BeforeJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "system-trusted Any EKU cert succeeded"); + + [self removeTestRootAsSystem]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testSystemTrust_ServerAuthEKU +{ + [self setTestRootAsSystem:_EKUTestSSLRootHash]; + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_BeforeJul2019, sizeof(_serverEKU_BeforeJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "system-trusted ServerAuth EKU cert failed: %@", error); + + [self removeTestRootAsSystem]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +// Other app trust of root SSL EKU tests of certs issued before July 2019 occur in testSSLPolicyCerts (Test4, Test17) + +- (void)testAppTrustRoot_AnyEKU_BeforeJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_BeforeJul2019, sizeof(_anyEKU_BeforeJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, anyEKU leaf failed: %@", error); + + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testAppTrustRoot_MissingEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, missing EKU leaf succeeded"); + + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testAppTrustLegacy_MissingEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + SecPolicyRef policy = SecPolicyCreateLegacySSL(true, CFSTR("example.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:590000000.0]; // September 12, 2019 at 9:53:20 AM PDT + SecTrustRef trustRef = NULL; + CFErrorRef cferror = NULL; + + require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trustRef), errOut); + require_noerr(SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)date), errOut); + require_noerr(SecTrustSetAnchorCertificates(trustRef, (__bridge CFArrayRef)@[(__bridge id)root]), errOut); + + XCTAssertTrue(SecTrustEvaluateWithError(trustRef, &cferror)); + +errOut: + CFReleaseNull(policy); + CFReleaseNull(trustRef); + CFReleaseNull(cferror); + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testAppTrustRoot_AnyEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_AfterJul2019, sizeof(_anyEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, anyEKU leaf succeeded"); + + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testAppTrustRoot_ServerAuthEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_AfterJul2019, sizeof(_serverEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:@[(__bridge id)root] error:&error], "app-trusted root, serverAuth EKU leaf failed: %@", error); + + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testAppTrustLeaf_MissingEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019)); + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)leaf] error:&error], "app-trusted missing EKU leaf succeeded"); + + CFReleaseNull(leaf); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't support trust settings +- (void)testUserTrustRoot_MissingEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + id persistentRef = [self addTrustSettingsForCert:root]; + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], "user-trusted root, missing EKU leaf failed: %@", error); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testUserTrustRoot_AnyEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_AfterJul2019, sizeof(_anyEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + id persistentRef = [self addTrustSettingsForCert:root]; + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], "user-trusted root, anyEKU leaf failed: %@", error); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testUserTrustRoot_ServerAuthEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_AfterJul2019, sizeof(_serverEKU_AfterJul2019)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _EKUTestSSLRoot, sizeof(_EKUTestSSLRoot)); + id persistentRef = [self addTrustSettingsForCert:root]; + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], "user-trusted root, serverAuth EKU leaf failed: %@", error); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} + +- (void)testUserTrustLeaf_MissingEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _noEKU_AfterJul2019, sizeof(_noEKU_AfterJul2019)); + id persistentRef = [self addTrustSettingsForCert:leaf]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], "user-trusted missing EKU leaf failed: %@", error); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} + +- (void)testUserTrustLeaf_AnyEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _anyEKU_AfterJul2019, sizeof(_anyEKU_AfterJul2019)); + id persistentRef = [self addTrustSettingsForCert:leaf]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], "user-trusted anyEKU leaf failed: %@", error); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} + +- (void)testUserTrustLeaf_ServerAuthEKU_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _serverEKU_AfterJul2019, sizeof(_serverEKU_AfterJul2019)); + id persistentRef = [self addTrustSettingsForCert:leaf]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], "user-trusted serverAuth EKU leaf failed: %@", error); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} +#endif // !TARGET_OS_BRIDGE + +@end diff --git a/tests/TrustTests/EvaluationTests/SSLPolicyTests_data.h b/tests/TrustTests/EvaluationTests/SSLPolicyTests_data.h new file mode 100644 index 00000000..3a03abbf --- /dev/null +++ b/tests/TrustTests/EvaluationTests/SSLPolicyTests_data.h @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2015-2019 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 _TRUSTTESTS_EVALUATION_SSL_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_SSL_TESTS_H_ + +const uint8_t _SSLTrustPolicyTestRootCA[987] = { + 0x30, 0x82, 0x03, 0xd7, 0x30, 0x82, 0x02, 0xbf, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x81, 0x8e, 0x31, 0x21, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x53, 0x53, 0x4c, + 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, + 0x79, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, + 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, + 0x65, 0x2c, 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, 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, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, + 0x75, 0x70, 0x65, 0x72, 0x74, 0x69, 0x6e, 0x6f, 0x30, 0x1e, 0x17, 0x0d, + 0x31, 0x35, 0x30, 0x38, 0x32, 0x30, 0x30, 0x32, 0x30, 0x31, 0x31, 0x39, + 0x5a, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x38, 0x31, 0x37, 0x30, 0x32, 0x30, + 0x31, 0x31, 0x39, 0x5a, 0x30, 0x81, 0x8e, 0x31, 0x21, 0x30, 0x1f, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x72, + 0x75, 0x73, 0x74, 0x20, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, + 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x2c, 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, 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, 0x31, 0x12, 0x30, + 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x43, 0x75, 0x70, 0x65, + 0x72, 0x74, 0x69, 0x6e, 0x6f, 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, 0xdf, 0x3b, 0x3f, 0xbc, 0xee, 0xbe, 0x24, 0xf1, 0x44, 0x79, + 0x8b, 0x39, 0x01, 0x3d, 0xd3, 0x9c, 0xe4, 0xf3, 0xd1, 0x2b, 0x43, 0x83, + 0xfe, 0x44, 0xf3, 0xf8, 0xd8, 0xf3, 0xd7, 0xa3, 0xe8, 0x7d, 0xd0, 0x1b, + 0x18, 0x1d, 0x0d, 0x7e, 0x5d, 0x89, 0xb3, 0xc7, 0xe1, 0x3e, 0xbe, 0x6e, + 0xe3, 0xdd, 0x9f, 0x8d, 0x42, 0xd6, 0xb1, 0xd2, 0x63, 0x69, 0x4d, 0x09, + 0xe9, 0x09, 0x21, 0x11, 0x42, 0x1e, 0x78, 0xf7, 0x20, 0x8c, 0x55, 0xf3, + 0x32, 0xeb, 0xd4, 0xed, 0xfd, 0xbd, 0xa7, 0x25, 0x90, 0x0b, 0x24, 0x6a, + 0x86, 0xc1, 0x3f, 0xbc, 0x19, 0xc5, 0x3d, 0x02, 0x52, 0x10, 0xfe, 0xf3, + 0xd3, 0xac, 0x97, 0x2d, 0xf5, 0xa2, 0xf5, 0x92, 0x47, 0xcc, 0x2e, 0x78, + 0x21, 0x6c, 0x57, 0xc8, 0x8d, 0x9e, 0x04, 0x59, 0x83, 0x17, 0xd8, 0x63, + 0x5e, 0xdf, 0xe5, 0x24, 0x3b, 0x34, 0x0b, 0x15, 0x73, 0xec, 0x50, 0x61, + 0x92, 0xef, 0xab, 0x1c, 0xeb, 0x42, 0xdf, 0x76, 0x6b, 0x5f, 0x64, 0xd1, + 0x38, 0xdc, 0xe9, 0x36, 0x82, 0x6a, 0xb3, 0xcc, 0x6f, 0x4a, 0x3b, 0xaf, + 0xd3, 0xf2, 0x1d, 0xf3, 0xf4, 0xd8, 0x0f, 0xa0, 0x5d, 0xf5, 0xdd, 0x21, + 0x92, 0x1f, 0xf1, 0x98, 0x0d, 0x12, 0x72, 0x82, 0x3e, 0xea, 0xc9, 0xf4, + 0x4c, 0x0c, 0x43, 0x3f, 0x1d, 0x18, 0x8a, 0xe5, 0x4d, 0xbd, 0x9f, 0x5b, + 0x11, 0x37, 0xd1, 0x3c, 0xad, 0xdb, 0x72, 0xac, 0x90, 0xd0, 0x72, 0x42, + 0x12, 0xb6, 0xe1, 0x6f, 0x10, 0x77, 0x1e, 0x60, 0x3b, 0x42, 0x31, 0xdc, + 0x9c, 0xdd, 0xfb, 0x36, 0xab, 0x5e, 0x65, 0xf4, 0xab, 0x1c, 0x0d, 0x7f, + 0x1b, 0xff, 0xb0, 0xfa, 0x42, 0x0a, 0x82, 0x2e, 0x43, 0x4c, 0x29, 0x72, + 0x82, 0xcb, 0x61, 0xf4, 0xbf, 0xbb, 0x34, 0x9e, 0x43, 0xac, 0xef, 0x50, + 0xc5, 0xc4, 0x58, 0x7f, 0x65, 0x39, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x3e, 0x30, 0x3c, 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, 0x02, 0x84, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, + 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x03, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x0d, + 0x4e, 0xac, 0x67, 0xc0, 0xe0, 0xfa, 0x66, 0x2e, 0xc3, 0x3e, 0x90, 0x34, + 0x4e, 0xdf, 0x64, 0xfa, 0x06, 0x2e, 0x4e, 0x99, 0xa0, 0x91, 0xf6, 0x96, + 0xe1, 0x41, 0x5d, 0xf6, 0x23, 0x56, 0xbc, 0x64, 0xf9, 0x79, 0xcd, 0x70, + 0xcb, 0xd0, 0xa3, 0x17, 0x87, 0x64, 0x6c, 0x3d, 0x72, 0xca, 0x4b, 0x5e, + 0xae, 0xbf, 0xef, 0x84, 0x04, 0xd4, 0x30, 0xf3, 0xff, 0xbc, 0xa1, 0x28, + 0x2e, 0xd1, 0xfd, 0x43, 0xa3, 0x18, 0xce, 0x89, 0x00, 0x59, 0x3e, 0x6a, + 0x70, 0x73, 0xca, 0x3c, 0x3c, 0xac, 0x6a, 0xfc, 0xb9, 0x5c, 0x79, 0x14, + 0xd7, 0xc8, 0x19, 0x63, 0x6d, 0x37, 0x28, 0xf9, 0x78, 0xd6, 0xb9, 0x2e, + 0xb2, 0x75, 0xd1, 0x05, 0x9c, 0xce, 0xd4, 0x87, 0xe0, 0x92, 0xf7, 0x46, + 0xdf, 0x73, 0x5f, 0x56, 0x1c, 0xff, 0x95, 0x04, 0xa8, 0xb3, 0xa9, 0x4c, + 0x74, 0x07, 0xc6, 0x0a, 0xb9, 0xcd, 0x4c, 0x17, 0x1f, 0x40, 0x73, 0x7d, + 0xb6, 0x73, 0xc7, 0x28, 0x1f, 0x7d, 0x47, 0x86, 0x2a, 0xa2, 0xa1, 0x83, + 0x8b, 0xa4, 0x46, 0x85, 0xeb, 0x19, 0x8c, 0x5e, 0x3c, 0xa4, 0x73, 0x9d, + 0x04, 0x82, 0xe7, 0x0e, 0x2a, 0x3c, 0x83, 0xa1, 0x10, 0xcc, 0x27, 0x81, + 0x1d, 0x3e, 0x1a, 0x7d, 0x1c, 0x4b, 0xfd, 0x45, 0x39, 0xbb, 0x1a, 0xc5, + 0xae, 0x29, 0x22, 0x56, 0x2c, 0x2a, 0x76, 0xc8, 0x26, 0x9f, 0xf0, 0x4f, + 0x48, 0xc8, 0x9d, 0x20, 0xc9, 0x9d, 0x63, 0xc4, 0xe1, 0xad, 0x70, 0xa9, + 0x75, 0xb3, 0xb2, 0xff, 0x35, 0xeb, 0x89, 0x6a, 0x80, 0x11, 0x60, 0x7d, + 0xab, 0xd5, 0xd2, 0xa4, 0xd3, 0x1c, 0x34, 0x21, 0xdf, 0xbe, 0x0a, 0x4f, + 0xcc, 0x79, 0xca, 0x88, 0x81, 0x2b, 0x06, 0x11, 0x1f, 0x31, 0x22, 0x43, + 0x93, 0x76, 0x2c, 0x90, 0x5b, 0x5f, 0x42, 0x3e, 0x97, 0x61, 0x4b, 0xcc, + 0x22, 0x6e, 0xf0 +}; + +const uint8_t _EKUTestSSLRootHash[] = { + 0xF3, 0xA4, 0xEE, 0xA2, 0xBD, 0x89, 0x1C, 0x32, 0xA2, 0x11, 0xEE, 0x53, 0x05, 0x5A, 0x03, 0x80, + 0x32, 0xA7, 0xE3, 0x3A, 0x87, 0x06, 0x45, 0x72, 0x41, 0xB2, 0x4F, 0x27, 0xC8, 0x30, 0x2D, 0xC4 +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +const uint8_t _EKUTestSSLRoot[] = { + 0x30,0x82,0x03,0xD2,0x30,0x82,0x02,0xBA,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x90,0x52,0xB8,0x31,0x95,0x9D,0x0E,0x2E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x84,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,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53, + 0x53,0x4C,0x20,0x45,0x4B,0x55,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E, + 0x17,0x0D,0x31,0x39,0x30,0x34,0x32,0x35,0x30,0x31,0x34,0x35,0x35,0x30,0x5A,0x17, + 0x0D,0x32,0x39,0x30,0x34,0x32,0x32,0x30,0x31,0x34,0x35,0x35,0x30,0x5A,0x30,0x81, + 0x84,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,0x18,0x30,0x16,0x06, + 0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55,0x20,0x54,0x65, + 0x73,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,0xCA,0x03,0xFD,0x19,0x90,0x90,0xBB,0x3E,0xBE,0x2C, + 0xD6,0x6A,0x85,0xA3,0x4C,0x07,0x77,0xCB,0xBE,0xD4,0x99,0x90,0x8B,0x95,0xCC,0xE3, + 0x8B,0xA7,0x39,0x25,0x45,0x67,0xF4,0x62,0xF8,0xEF,0x09,0x3E,0xBD,0xE3,0x98,0x5E, + 0xF0,0x5F,0x8A,0xBB,0x05,0x36,0x91,0x57,0x90,0x6E,0x8E,0x5F,0x41,0x3F,0x83,0x90, + 0xC4,0xA5,0x51,0x73,0xAE,0x62,0xD2,0x0F,0xDA,0x70,0x7B,0x3F,0x53,0x3D,0x10,0x67, + 0xE1,0xF6,0x16,0x2B,0x2A,0xD9,0xD1,0x3C,0x06,0xAD,0xE6,0xBB,0xEA,0xA9,0xD1,0xDE, + 0x0B,0x4A,0xAF,0xB4,0x9B,0x13,0x48,0x8E,0x57,0xC8,0xE6,0xFD,0x76,0x12,0x75,0x01, + 0xDF,0x06,0xC4,0xEC,0xE7,0x09,0xAA,0x4E,0xEE,0x33,0xFE,0x00,0xB0,0x1A,0x84,0x71, + 0x49,0xB0,0xEC,0xE8,0xEC,0x4B,0x1E,0x93,0xBC,0x89,0xC2,0xF4,0x95,0xF0,0x9F,0x98, + 0x93,0xED,0xFC,0x40,0x9D,0xA1,0xF1,0x78,0xB2,0xE5,0xD4,0xBA,0xE7,0x4F,0xE3,0x2A, + 0xE3,0x85,0x45,0x68,0xCC,0xF7,0x90,0xDD,0x88,0x8D,0x22,0x0B,0x93,0x27,0xBA,0xCC, + 0xBD,0xDE,0xD2,0x63,0xA4,0x5D,0x1F,0x90,0x98,0x3D,0x9B,0x0A,0x8D,0x4C,0xB3,0xFB, + 0xDC,0x99,0x4D,0x55,0x77,0x83,0xBB,0xA1,0xB3,0x8C,0x24,0xC2,0xBC,0xA7,0x7C,0xF5, + 0x8F,0x84,0xAA,0xF5,0x4D,0x99,0x2F,0x9D,0xA3,0xB6,0x31,0x5F,0xAE,0xE1,0xF5,0x7F, + 0xEB,0x8C,0x76,0xFB,0xCE,0x5D,0x11,0xD7,0x19,0xDB,0x0A,0x67,0x5D,0x52,0xDD,0x8A, + 0x8F,0x4C,0x36,0x31,0xEF,0x54,0xD1,0xF6,0xCD,0xCD,0xC7,0x8D,0x29,0xA0,0xA7,0xA0, + 0x06,0xA3,0x4D,0x9A,0xA4,0x33,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,0x4D,0x60, + 0x02,0x55,0xCA,0x33,0x37,0x84,0x3B,0xDF,0x88,0x3C,0x81,0xFC,0x8A,0xE6,0xED,0x15, + 0xB1,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x03,0x82,0x01,0x01,0x00,0x67,0xC1,0x43,0xE0,0x68,0x87,0x5E,0x63,0x3F,0xF3, + 0xD4,0x86,0xC1,0xBD,0xDF,0x89,0xF3,0x3E,0x49,0xBC,0x49,0xA1,0x61,0xDA,0x1F,0xD9, + 0xF8,0x9C,0x95,0xBC,0x1D,0x80,0x2B,0x5C,0x25,0xDF,0x6C,0xFE,0x2E,0xB1,0x40,0xB2, + 0x58,0x33,0xBA,0xB8,0x91,0x7E,0x28,0x7E,0x82,0x15,0xF0,0x1F,0xAE,0x0C,0x3E,0x4B, + 0x66,0xA1,0x1D,0x41,0x2D,0x89,0x70,0xF1,0xB9,0x4E,0x49,0x9C,0x91,0xD6,0x2A,0xA1, + 0x05,0xAF,0xD0,0x6A,0xD4,0x45,0x11,0x75,0x67,0x08,0xDF,0x6C,0x3C,0x63,0x19,0x48, + 0xAD,0x06,0x56,0xB1,0x90,0x22,0x90,0x3D,0xEB,0x24,0x4C,0x63,0x49,0xCA,0x0D,0x8A, + 0x36,0x6B,0xD5,0x03,0x29,0x23,0x47,0x3A,0x73,0xD5,0x3F,0x6D,0x0D,0x78,0xF0,0xB5, + 0xC6,0xE2,0x1D,0x03,0xB6,0xBB,0xAE,0x33,0xB0,0x8A,0xEB,0xD7,0x6E,0x8B,0xDE,0x87, + 0x84,0x95,0x8E,0xBA,0x79,0xAB,0x4E,0xA7,0x33,0x74,0xF5,0x98,0x33,0x23,0xC2,0x59, + 0x46,0x59,0x82,0xE4,0xEF,0x79,0xEB,0x7F,0x05,0x09,0x61,0xC3,0xB9,0xF5,0x43,0x02, + 0x92,0x0C,0xC1,0x67,0xA5,0xA2,0xD6,0xDE,0xAA,0x08,0x44,0x88,0xE6,0x0B,0x96,0x2E, + 0xC8,0x58,0x96,0x04,0xE8,0x60,0x9E,0xC6,0xEA,0x3F,0xA9,0xB2,0x1C,0xC2,0x5A,0xCB, + 0x96,0x01,0x35,0x3A,0xA4,0x81,0xDB,0x3D,0x02,0x43,0x88,0x5F,0x46,0x55,0x42,0xD1, + 0xBB,0xF9,0x90,0x22,0xA8,0xB4,0x57,0x98,0xA8,0x63,0x95,0xD6,0x6B,0x22,0x96,0xEE, + 0x2A,0x1A,0x7E,0x54,0xD5,0xC5,0xD4,0x8E,0x6E,0xA1,0xAE,0x7D,0x84,0x58,0x81,0xA7, + 0x55,0xBD,0x66,0xA1,0x81,0x04, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Before Jul SSL EKU Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +/* X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication */ +const uint8_t _serverEKU_BeforeJul2019[] = { + 0x30,0x82,0x04,0x38,0x30,0x82,0x03,0x20,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,0xC9,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x84,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,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34, + 0x32,0x35,0x30,0x31,0x34,0x38,0x33,0x30,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x32, + 0x34,0x30,0x31,0x34,0x38,0x33,0x30,0x5A,0x30,0x81,0x8C,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,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x0C,0x17, + 0x42,0x65,0x66,0x6F,0x72,0x65,0x20,0x4A,0x75,0x6C,0x20,0x53,0x53,0x4C,0x20,0x45, + 0x4B,0x55,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,0xE2,0x56,0x9F,0x34,0x03,0x66,0xE6,0x5D, + 0x40,0x95,0x89,0x3D,0x9D,0xF7,0x21,0xAF,0x07,0x06,0xDB,0xF6,0xEC,0x19,0x92,0xA4, + 0xF8,0xF8,0xEF,0x79,0xFF,0x2F,0xE2,0x84,0xCA,0xAA,0x21,0x4E,0xB3,0xE8,0x0E,0x7E, + 0x22,0xE4,0xCF,0x17,0xC8,0xB6,0x47,0x42,0xF7,0x26,0x07,0x58,0x58,0x3D,0xD8,0xDE, + 0xBD,0x51,0x6D,0xF2,0x3D,0xE2,0xF8,0xC0,0xCD,0x03,0x59,0x90,0xBD,0xFA,0x2F,0xDB, + 0x62,0x62,0x23,0xDC,0xA6,0xBA,0x7D,0x4E,0xD8,0x47,0xA8,0xFE,0x12,0x96,0xC5,0x3B, + 0xEF,0xC4,0x81,0x49,0x5B,0x33,0x53,0xAB,0x0F,0xCB,0x0D,0x0C,0xD4,0x21,0xC8,0x53, + 0x7C,0x00,0x42,0x31,0x0A,0xE0,0x00,0xAF,0xD6,0x75,0xAF,0x94,0x76,0xC7,0x0E,0x99, + 0x3C,0xA2,0x4E,0x51,0x1D,0xA1,0x4E,0xBF,0x2F,0xBB,0x5F,0x2C,0x6D,0xCD,0x89,0x84, + 0xF6,0x2D,0x90,0x8D,0xED,0xF8,0x4B,0xC3,0x94,0x49,0x1C,0xDA,0x3A,0xEE,0xCB,0x9E, + 0xA9,0x2E,0xD5,0x56,0xDD,0xA5,0xCB,0x5C,0xEC,0x2F,0x7D,0x25,0x59,0xBC,0x30,0xED, + 0xE0,0x6D,0x23,0x03,0x54,0x31,0x5E,0x4F,0x59,0x34,0x6E,0x06,0xC3,0x8F,0x14,0x97, + 0xD7,0x59,0xDE,0x90,0xD4,0x09,0xEE,0xD7,0xB6,0x53,0x3C,0x2A,0xB1,0x40,0x5D,0xCE, + 0xD9,0xF6,0x66,0x82,0x1F,0x81,0xD6,0xC9,0x82,0x5D,0xE0,0x04,0x36,0x4E,0x32,0xCF, + 0x24,0x06,0xF6,0x75,0x52,0x7A,0x8C,0x4E,0x46,0x24,0xAC,0x3B,0x05,0xD9,0x05,0x50, + 0x21,0x80,0x9C,0x01,0x99,0x6E,0x57,0x07,0xD3,0xE5,0xD9,0x04,0x85,0x2A,0x91,0x95, + 0xB2,0x47,0xBE,0x0F,0xE7,0x7A,0x43,0x91,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98, + 0x30,0x81,0x95,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,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,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,0xCA,0x62,0x7B,0xC4,0x73,0x5B,0x35,0xCC,0x48,0x57,0x85,0xDB,0x16, + 0x57,0x9E,0xBD,0x7C,0x3C,0xC0,0x0B,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, + 0x30,0x16,0x80,0x14,0x4D,0x60,0x02,0x55,0xCA,0x33,0x37,0x84,0x3B,0xDF,0x88,0x3C, + 0x81,0xFC,0x8A,0xE6,0xED,0x15,0xB1,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x48,0x8B,0xF7,0x80, + 0x8F,0x11,0xEE,0x68,0x91,0x59,0x2D,0x22,0x99,0x1D,0x6B,0x6F,0xDE,0x3A,0xF9,0xE3, + 0xE1,0xF4,0x83,0xE4,0xDA,0x92,0x72,0xC2,0x0B,0x58,0xFF,0x39,0x63,0xEE,0x35,0x70, + 0x9B,0x95,0xA1,0xAA,0x3A,0x95,0x12,0xF8,0x97,0xD4,0xB4,0x43,0xB1,0xB2,0x26,0x3B, + 0x79,0x27,0x37,0x98,0xCF,0x20,0x95,0x2D,0x97,0xC6,0x16,0x2D,0xFA,0xC3,0x4B,0x77, + 0xCC,0x55,0xCA,0x7C,0xEF,0xCE,0x55,0xC2,0x72,0x6A,0x5B,0xEC,0xEE,0x77,0x71,0xDE, + 0x68,0xA1,0xE8,0x5A,0xB2,0xC1,0x30,0x0E,0xE6,0x3F,0x2F,0xA9,0x7C,0xA9,0x9C,0x15, + 0xC2,0x0D,0xBF,0xD5,0x9F,0x83,0x78,0x51,0x13,0x4B,0xB7,0x40,0xD7,0x70,0xB5,0x1A, + 0x2E,0x2C,0xB2,0x80,0x37,0xC2,0x73,0xA7,0x1B,0x33,0x8F,0x5A,0x08,0x62,0x16,0x4F, + 0xF5,0x0C,0xB5,0x76,0x77,0x1A,0x54,0x41,0x23,0xC0,0x53,0x50,0x77,0xC8,0x0E,0x8C, + 0xC5,0x1A,0x25,0xD2,0x23,0xCF,0xDA,0x55,0xA6,0xCE,0x0A,0x40,0x94,0xE0,0x5F,0x58, + 0x6E,0x27,0xEB,0x60,0x59,0xA8,0xB9,0x38,0xB5,0xA6,0xE1,0x34,0x50,0x45,0xF5,0xAE, + 0xF7,0xCA,0x52,0x36,0x19,0xC2,0xAA,0x1C,0x35,0xAE,0xBC,0x84,0xEA,0x49,0xCE,0x67, + 0xFB,0x8A,0xC6,0x10,0xA7,0xFA,0xBF,0x4B,0xC8,0xA8,0xE9,0x3C,0xF7,0x08,0x0E,0x88, + 0x0A,0x50,0xD9,0xF3,0x66,0x94,0xA9,0x53,0xFC,0x4F,0x15,0x1C,0x57,0x7B,0x2F,0xF1, + 0xFE,0x68,0xF3,0x34,0x28,0xF6,0x53,0x3C,0xA7,0xD6,0xC9,0x4E,0xC4,0x2A,0x20,0xE5, + 0xB1,0x8D,0xCA,0xEC,0x9E,0x55,0x28,0xDD,0x28,0x5D,0xDC,0x25, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Before Jul Missing EKU Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +const uint8_t _noEKU_BeforeJul2019[] = { + 0x30,0x82,0x04,0x1B,0x30,0x82,0x03,0x03,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,0xCA,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x84,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,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34, + 0x32,0x35,0x30,0x31,0x34,0x39,0x34,0x34,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x32, + 0x34,0x30,0x31,0x34,0x39,0x34,0x34,0x5A,0x30,0x81,0x90,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,0x24,0x30,0x22,0x06,0x03,0x55,0x04,0x03,0x0C,0x1B, + 0x42,0x65,0x66,0x6F,0x72,0x65,0x20,0x4A,0x75,0x6C,0x20,0x4D,0x69,0x73,0x73,0x69, + 0x6E,0x67,0x20,0x45,0x4B,0x55,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,0xB8,0xCA,0x11,0x21, + 0xD0,0x07,0x74,0x2A,0xF4,0xF8,0x1A,0x78,0x79,0x7C,0x6A,0xCC,0x08,0xE2,0xB3,0xD4, + 0xDF,0xE0,0xBD,0xFD,0x81,0xA5,0xBA,0xDC,0xDF,0x08,0x44,0xDB,0x71,0xBA,0x56,0x17, + 0xF2,0x43,0x7B,0x2A,0xAB,0x31,0x88,0x80,0x1E,0x98,0x8E,0x77,0x9A,0x70,0xC3,0x6E, + 0xFA,0x20,0x41,0x11,0x3B,0x4A,0xA7,0x74,0x2E,0x48,0xB0,0x3B,0x8B,0xEF,0xF3,0x24, + 0x0B,0x4B,0x59,0x9C,0x6F,0xDF,0xDE,0x8C,0xE9,0x71,0xB2,0xB8,0xE0,0x63,0xCA,0x3A, + 0xF9,0xF2,0x0B,0x64,0x83,0x4C,0xE6,0xAD,0x43,0x23,0x54,0x9A,0x5D,0xC4,0x92,0x4F, + 0x3E,0x6E,0x32,0xD4,0x3E,0x59,0xF4,0xF6,0x65,0x4F,0xFD,0xC7,0x32,0x0F,0x24,0x47, + 0x33,0xA2,0xD7,0x41,0xC0,0x8C,0x10,0x21,0x6D,0xEF,0xBA,0x6E,0xE1,0xEF,0x8B,0x5B, + 0x61,0x63,0x03,0x33,0x91,0x62,0x9F,0xC6,0x28,0x94,0xDF,0x90,0x69,0xB3,0x00,0x1F, + 0x99,0x7E,0x5C,0x22,0x5D,0x55,0x9C,0x05,0x95,0xE7,0x46,0x1E,0x9C,0x31,0x28,0x35, + 0x07,0x8F,0x37,0x45,0x88,0xD0,0x9A,0xB1,0xB1,0x82,0x85,0x2D,0xDA,0x22,0x4D,0x99, + 0xF6,0x15,0x04,0x9D,0xAE,0x83,0x6E,0x7F,0xDC,0x16,0x85,0xAC,0x34,0xA2,0x94,0xB7, + 0x58,0x2C,0x4E,0xCA,0xED,0x67,0x8E,0x9B,0x34,0xC7,0xD3,0x7E,0x53,0xC2,0xBB,0x4F, + 0x1E,0xCD,0x39,0xE5,0xED,0x60,0xE9,0xD5,0xF6,0x38,0x63,0x2D,0xCD,0xDA,0x16,0x4D, + 0xFB,0x4F,0x59,0x91,0x58,0xF9,0xC9,0x5D,0x5E,0xF6,0x3C,0x45,0x73,0xAF,0xB1,0x88, + 0xC4,0x1B,0xCC,0x63,0x9A,0x29,0xC9,0xDE,0xF9,0x0B,0x06,0x43,0x02,0x03,0x01,0x00, + 0x01,0xA3,0x78,0x30,0x76,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,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,0x88,0x80,0x62,0xAA,0x4F,0x78,0xC9,0xF7,0x70,0xED, + 0x8E,0xC1,0xD7,0xD8,0x3C,0x2D,0x50,0x42,0x7A,0x3C,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x4D,0x60,0x02,0x55,0xCA,0x33,0x37,0x84,0x3B, + 0xDF,0x88,0x3C,0x81,0xFC,0x8A,0xE6,0xED,0x15,0xB1,0x1E,0x30,0x0D,0x06,0x09,0x2A, + 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xA0, + 0x35,0x5D,0x98,0x4A,0xBF,0xFD,0x4C,0xD9,0xF1,0xF3,0xE3,0xF1,0x7E,0x23,0xF3,0xBA, + 0x81,0x3E,0xB6,0x33,0xE5,0x3A,0x6F,0xB7,0xA1,0x91,0x47,0x3C,0x79,0xEE,0x29,0x30, + 0x3F,0x8C,0x98,0xD9,0xCB,0x26,0x77,0x8F,0xB3,0x7E,0x96,0xFE,0x1C,0x0C,0xA7,0x20, + 0x72,0x46,0x98,0xC1,0x00,0xEA,0x76,0xB3,0xE0,0x9F,0x0D,0x45,0xC5,0xCD,0x88,0x47, + 0x22,0x85,0x29,0x61,0x71,0xC4,0x8C,0xC3,0x03,0xE0,0x69,0x12,0x5F,0x42,0x16,0x7D, + 0xF3,0x6A,0x08,0xC7,0xCE,0x53,0xE9,0x39,0xD4,0xD8,0x17,0x33,0xEA,0x21,0x4A,0xC1, + 0x8F,0x3D,0xDC,0xC0,0x34,0xE6,0x03,0xE4,0x81,0x95,0x4C,0xFD,0x6B,0x5F,0x56,0x58, + 0x59,0xA1,0x29,0xDE,0x48,0x5C,0x35,0x1E,0xA4,0xFC,0xD4,0x22,0xC6,0xF2,0x86,0xFB, + 0x67,0x47,0xB5,0xBF,0x8F,0x5E,0x95,0xEC,0xFC,0x34,0xC7,0x46,0x18,0x1F,0x26,0xF4, + 0x6A,0x47,0x07,0xB0,0x1E,0x2F,0x02,0x3F,0xA3,0xF4,0xDF,0x5F,0x63,0x35,0x33,0x85, + 0x40,0x11,0xFE,0x5A,0x9D,0x57,0x35,0xDF,0x36,0xEF,0x84,0xD7,0x3B,0x18,0xC5,0x0C, + 0x24,0xF3,0x62,0xFE,0xD7,0xD0,0xEE,0xDD,0x43,0x65,0xF8,0xA2,0xB0,0x8F,0x54,0x9C, + 0x17,0x59,0x26,0x9A,0xCD,0xBD,0x58,0xC6,0x97,0x78,0x50,0xF3,0xCA,0x18,0xD2,0x02, + 0xD8,0x51,0xBF,0x8C,0x2B,0xEA,0x21,0x63,0x08,0x61,0x74,0x43,0xAD,0x3E,0x34,0xB9, + 0xFE,0xAF,0x17,0xB1,0xA1,0xC1,0xB2,0xAD,0xC2,0xC9,0xFF,0x6B,0xC1,0x71,0xAB,0x76, + 0xB3,0x38,0x0B,0x2A,0xB6,0x86,0xE6,0x49,0x52,0xB3,0x91,0x7A,0x11,0xB3,0xCE, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Before Jul Any EKU Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +/* X509v3 Extended Key Usage: Any Extended Key Usage */ +const uint8_t _anyEKU_BeforeJul2019[] = { + 0x30,0x82,0x04,0x2A,0x30,0x82,0x03,0x12,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,0xCB,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x84,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,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34, + 0x32,0x35,0x30,0x31,0x35,0x32,0x35,0x36,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x32, + 0x34,0x30,0x31,0x35,0x32,0x35,0x36,0x5A,0x30,0x81,0x8C,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,0x20,0x30,0x1E,0x06,0x03,0x55,0x04,0x03,0x0C,0x17, + 0x42,0x65,0x66,0x6F,0x72,0x65,0x20,0x4A,0x75,0x6C,0x20,0x41,0x6E,0x79,0x20,0x45, + 0x4B,0x55,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,0xE8,0xEE,0x50,0xD7,0x3A,0xCD,0x24,0xC1, + 0xF6,0x76,0x36,0x24,0x15,0xC2,0x34,0xBA,0x70,0xF8,0x16,0x2E,0x89,0xA5,0x37,0x46, + 0xB1,0xA4,0xE2,0x2B,0xCC,0x62,0x1F,0xBA,0x84,0x36,0x31,0x5A,0x63,0xE7,0x4E,0xAC, + 0x7A,0x62,0xA1,0xC7,0xF2,0xC6,0x85,0xC8,0xB3,0xFB,0xFD,0xCC,0xF2,0x1E,0x11,0x49, + 0xF6,0xC4,0xCF,0xE3,0x53,0xA7,0xF7,0x20,0x65,0xFA,0x01,0xA0,0xA3,0x59,0x6A,0x0E, + 0x9E,0xE9,0xEC,0x54,0xE5,0xF7,0xB6,0x55,0xBA,0x59,0xD2,0x33,0xE5,0x2C,0x0A,0x19, + 0x98,0xE8,0x20,0xE2,0xE1,0xDE,0x2D,0x99,0xC1,0x32,0xCB,0x45,0x38,0xBA,0x68,0xEF, + 0xA5,0xFC,0x6B,0x62,0xCC,0xD1,0x33,0x33,0x58,0x09,0x20,0x5A,0x95,0xD7,0x09,0x31, + 0xF5,0x1D,0x21,0xAF,0xB1,0xB6,0xC1,0x39,0x13,0xFE,0xD5,0x04,0x93,0x50,0x86,0x5F, + 0x9B,0x72,0x60,0x49,0x84,0x2F,0x6A,0xC3,0x66,0x6D,0x43,0x87,0x75,0xD2,0xA5,0x8A, + 0xDC,0xDF,0xE4,0x07,0x05,0x44,0xA0,0x41,0xFA,0xD4,0x2A,0xEC,0x01,0x63,0x1F,0x92, + 0xB5,0x84,0x60,0x1E,0x8D,0x16,0x39,0x07,0x70,0x6E,0x89,0x19,0x23,0x49,0xF4,0xA4, + 0xA5,0x9C,0x9D,0x24,0x14,0x82,0x6A,0x4C,0x63,0x10,0xC9,0x8B,0x0D,0x82,0x00,0x14, + 0xAF,0xE2,0xFA,0xBE,0xF6,0xE7,0xBA,0x92,0xE7,0xBC,0x69,0xCA,0x65,0xF4,0x04,0x6B, + 0xD1,0x9B,0xC2,0x39,0xF1,0x29,0x7E,0xB9,0xB6,0xDF,0xCE,0x6C,0xBF,0xAB,0x32,0x1C, + 0x83,0xDC,0x19,0xE3,0xB7,0xC2,0x14,0x3E,0x21,0xAF,0x8C,0x19,0xDF,0xE3,0xC4,0x46, + 0xDC,0xA3,0x91,0x25,0xB6,0xD8,0x90,0xFD,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x8A, + 0x30,0x81,0x87,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,0x0F,0x06,0x03,0x55,0x1D,0x25,0x04,0x08,0x30,0x06,0x06,0x04,0x55,0x1D, + 0x25,0x00,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,0x27,0x9E,0xBF,0x2E,0x61,0x19,0x97,0x17,0xB6,0xCA,0x1C, + 0xBB,0x03,0xBD,0xA3,0x1C,0x76,0x5A,0x0B,0xEE,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0x4D,0x60,0x02,0x55,0xCA,0x33,0x37,0x84,0x3B,0xDF, + 0x88,0x3C,0x81,0xFC,0x8A,0xE6,0xED,0x15,0xB1,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2D,0xB8, + 0xEB,0x19,0x56,0x2C,0xDF,0x2A,0xBA,0xEE,0x8B,0x84,0x31,0x8F,0x5C,0x6B,0x7A,0x4E, + 0x70,0x54,0x02,0x1B,0x2A,0xFD,0x19,0x4C,0x0C,0xCB,0xF3,0xCD,0x0F,0x9E,0x0D,0xFF, + 0x46,0xD5,0xFF,0x6A,0xB4,0x02,0xDD,0x7F,0x9E,0xF5,0x7E,0x16,0x5E,0x94,0x5B,0x7B, + 0xC0,0xF3,0xCF,0x74,0x62,0xF9,0x1A,0xF9,0x28,0x1A,0x17,0xA7,0x0E,0x02,0x24,0x0D, + 0x82,0x03,0xA7,0xD6,0xAC,0xE5,0xEE,0xA7,0x80,0x47,0x8F,0x4A,0x30,0x0F,0x55,0x3A, + 0x3A,0xC1,0x86,0x0D,0xA5,0x21,0xB4,0x11,0x5E,0xE8,0x18,0x63,0x91,0xDF,0x42,0x60, + 0x34,0xBD,0x52,0x74,0x1E,0x81,0x17,0xFB,0x4B,0x9A,0x1A,0x6D,0x1C,0xA1,0xB9,0x25, + 0x08,0x13,0x0D,0x0E,0xA5,0x22,0xE5,0x59,0xEA,0xA1,0x7F,0xF9,0xE6,0x90,0x81,0x8D, + 0x4F,0xD1,0x7B,0x56,0x85,0x1A,0x12,0xC5,0x94,0x57,0x13,0x23,0xCC,0x57,0x67,0x98, + 0x46,0xAC,0xFA,0xF2,0xAE,0x48,0x52,0x04,0x8C,0xDB,0x49,0xC4,0xBD,0x82,0xB3,0x87, + 0xC5,0x3C,0x4B,0x60,0x1C,0x9A,0x75,0x70,0x1B,0xD9,0x06,0x35,0x5A,0x43,0x39,0x56, + 0x38,0x9F,0x31,0xB1,0xA0,0xFF,0x90,0xED,0x34,0x8F,0xDA,0x0C,0x49,0xBE,0x62,0x30, + 0x25,0xB7,0x3C,0x9A,0xB8,0xD5,0xD4,0x41,0xB2,0xBC,0x53,0xCE,0x7E,0x59,0x1E,0xFC, + 0xE3,0x7E,0x9F,0xEE,0xEF,0x7B,0x3E,0x77,0xDE,0x85,0xB2,0x7E,0xA5,0x39,0x8B,0x5D, + 0x5A,0x6D,0x1B,0xCA,0x94,0x37,0x3A,0x58,0x17,0x96,0xBA,0xEC,0x49,0x9C,0x03,0x6C, + 0xB6,0x99,0xD7,0xC5,0x7D,0x90,0xA1,0x81,0x40,0xF3,0x53,0x28,0xB0,0x8D, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=After Jul Server Auth EKU Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +/* X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication */ +const uint8_t _serverEKU_AfterJul2019[] = { + 0x30,0x82,0x04,0x3F,0x30,0x82,0x03,0x27,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,0xCE,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x84,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,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x37, + 0x30,0x32,0x30,0x31,0x35,0x35,0x33,0x38,0x5A,0x17,0x0D,0x32,0x30,0x30,0x37,0x30, + 0x31,0x30,0x31,0x35,0x35,0x33,0x38,0x5A,0x30,0x81,0x93,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,0x27,0x30,0x25,0x06,0x03,0x55,0x04,0x03,0x0C,0x1E, + 0x41,0x66,0x74,0x65,0x72,0x20,0x4A,0x75,0x6C,0x20,0x53,0x65,0x72,0x76,0x65,0x72, + 0x20,0x41,0x75,0x74,0x68,0x20,0x45,0x4B,0x55,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,0xBE, + 0xC3,0x51,0x58,0xAB,0x64,0x72,0x8E,0xA6,0x9F,0xC0,0xCB,0x0E,0x34,0x70,0x2C,0xE9, + 0x87,0x1E,0x55,0xCA,0x7D,0x71,0x0D,0x60,0xC2,0xA2,0x4B,0xF6,0x3E,0xE2,0x95,0xD0, + 0x4B,0xF8,0x7C,0xBD,0x1D,0xAD,0xAC,0xB1,0x55,0x89,0x49,0xE8,0x7A,0x3A,0xBF,0xE2, + 0xBD,0x15,0xF7,0x7D,0x29,0xDA,0x42,0x87,0x0C,0x74,0xEF,0xA3,0x66,0x12,0x6C,0x69, + 0xE1,0x22,0x59,0x88,0x6E,0x09,0x1C,0xD2,0x1C,0xE3,0xA7,0x6C,0x5F,0xC2,0x4A,0xBE, + 0x11,0x5E,0x02,0xE7,0x80,0x3C,0xC3,0x03,0x5C,0x35,0xDA,0xB0,0xD1,0x4D,0x5A,0x5B, + 0xEF,0xEF,0x56,0x4E,0x6E,0x0B,0xBC,0xC4,0x12,0x5C,0x18,0x2F,0x85,0x0F,0x8F,0x66, + 0x1B,0x23,0xEF,0xCB,0xDB,0x47,0x56,0x7D,0x6B,0x80,0xEA,0x89,0xE0,0x59,0x9D,0x10, + 0x59,0x87,0x4A,0x29,0x27,0x31,0x97,0xA2,0x90,0x4C,0xFC,0xFA,0x2D,0x06,0xAF,0x7E, + 0x0F,0xC3,0x27,0x6E,0x34,0x38,0x20,0x03,0xC7,0xE6,0x4E,0xED,0xA3,0x83,0xF1,0xCD, + 0x3E,0xC9,0x1B,0x62,0x86,0x03,0xA0,0x4E,0x7D,0x60,0xD4,0xCC,0x1D,0x0A,0x80,0xC7, + 0x32,0x45,0x18,0xAA,0x02,0x32,0xD5,0xCD,0x95,0x20,0xA7,0x81,0xF5,0x5B,0x71,0x9A, + 0x12,0x70,0x1E,0x29,0x95,0x87,0xD1,0x87,0xF2,0x86,0xF7,0x2E,0xF5,0xBC,0x68,0xE9, + 0x1C,0xB3,0x65,0xA2,0xDE,0xAF,0xE1,0x20,0xA2,0x35,0x55,0x2C,0xD2,0x3D,0x69,0xD4, + 0xB8,0x43,0x00,0xB4,0xEB,0xEC,0x48,0x70,0x32,0x67,0x50,0xC9,0x00,0x1A,0x75,0x3F, + 0x92,0xB0,0x2F,0x12,0x4D,0x8F,0x44,0x78,0x55,0xDB,0x55,0x64,0x42,0x1D,0x89,0x02, + 0x03,0x01,0x00,0x01,0xA3,0x81,0x98,0x30,0x81,0x95,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,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,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,0x93,0x3B,0x34,0xE1,0x91,0x0F, + 0xD5,0x93,0xE4,0x2A,0xE4,0x95,0x67,0x7E,0x53,0xAF,0x27,0xAD,0x30,0x3C,0x30,0x1F, + 0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x4D,0x60,0x02,0x55,0xCA, + 0x33,0x37,0x84,0x3B,0xDF,0x88,0x3C,0x81,0xFC,0x8A,0xE6,0xED,0x15,0xB1,0x1E,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, + 0x01,0x01,0x00,0x15,0x8A,0xEB,0x3F,0x17,0xFE,0xCA,0x20,0x8A,0x4A,0x42,0x20,0xE2, + 0x53,0xDB,0x0C,0x36,0x70,0x28,0xA8,0xA0,0x2F,0x2C,0x91,0x9D,0xFE,0x6A,0x65,0xAB, + 0xB2,0x5B,0x2A,0x35,0x9F,0x36,0x38,0xB5,0xBA,0x25,0x30,0xE3,0x15,0x74,0xEF,0x3D, + 0x6F,0x13,0xEB,0x26,0xD9,0x4B,0x5A,0x76,0x91,0xAB,0x07,0x28,0x5B,0x6B,0xE0,0xB6, + 0x25,0x3E,0xF5,0xB8,0xC6,0x19,0x6E,0xFA,0x6B,0xF6,0x87,0xBF,0xD4,0x42,0x99,0x46, + 0xFC,0xBE,0xE9,0x7B,0x51,0x7D,0x93,0x91,0x2A,0x49,0xD1,0xD3,0x7B,0x20,0x1A,0xF8, + 0xF8,0x06,0x60,0x05,0x74,0x87,0x22,0xF0,0x76,0xD4,0xAD,0x61,0x68,0xCE,0x7E,0xF9, + 0x1E,0x37,0xF3,0x70,0x4A,0x72,0xAE,0xE4,0xF5,0xCC,0x94,0x62,0x82,0xCC,0x5A,0x90, + 0xF4,0x4C,0x3E,0xA4,0x33,0xDF,0x57,0xD5,0x4A,0x00,0x58,0x0B,0xC6,0xFE,0x60,0xA0, + 0x0A,0xA8,0xBF,0xC1,0x19,0xC9,0x4A,0x58,0x41,0x35,0x8B,0xF2,0x66,0x87,0x10,0x3F, + 0x57,0x36,0xA6,0x5A,0x4E,0x82,0x79,0x38,0x9E,0x59,0xAE,0x1B,0x92,0xD4,0x8F,0xF3, + 0x17,0xB1,0x75,0x05,0x60,0x73,0x43,0xA1,0x76,0xA1,0x58,0xD3,0x2F,0x57,0x57,0xEB, + 0x07,0x85,0xA8,0x6A,0xAA,0x16,0x28,0xDA,0xB8,0xE9,0x19,0x6D,0x5F,0x7F,0x47,0xAF, + 0x6F,0x8D,0x2B,0xC3,0xCA,0x04,0x20,0x3F,0xCE,0x87,0x4D,0x58,0x52,0xCC,0x61,0x15, + 0xF3,0x14,0x91,0xF2,0x61,0x28,0x77,0x7A,0xD8,0x94,0x96,0x9E,0x53,0xA0,0x12,0x4B, + 0x0C,0xEB,0x3D,0xA3,0xE3,0xD3,0x67,0x8A,0x49,0x07,0xF0,0xB1,0x80,0x23,0x7B,0x09, + 0xDE,0xB9,0x54, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=After Jul Missing EKU Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +const uint8_t _noEKU_AfterJul2019[] = { + 0x30,0x82,0x04,0x1A,0x30,0x82,0x03,0x02,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,0xCD,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x84,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,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x37, + 0x30,0x32,0x30,0x31,0x35,0x34,0x33,0x31,0x5A,0x17,0x0D,0x32,0x30,0x30,0x37,0x30, + 0x31,0x30,0x31,0x35,0x34,0x33,0x31,0x5A,0x30,0x81,0x8F,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,0x23,0x30,0x21,0x06,0x03,0x55,0x04,0x03,0x0C,0x1A, + 0x41,0x66,0x74,0x65,0x72,0x20,0x4A,0x75,0x6C,0x20,0x4D,0x69,0x73,0x73,0x69,0x6E, + 0x67,0x20,0x45,0x4B,0x55,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,0xA9,0x80,0xEC,0xDB,0x48, + 0xC2,0x78,0xF9,0x4C,0x46,0xE7,0x76,0xD3,0xB8,0xA5,0xC8,0x54,0xA9,0x00,0x66,0x65, + 0x98,0xC6,0x69,0x4A,0x12,0x78,0x9B,0xCD,0x8E,0x28,0xED,0xD1,0xF4,0x7E,0x04,0x6C, + 0x01,0x44,0x88,0xE9,0xD0,0x55,0xEA,0xE1,0xCE,0xD3,0x7D,0x08,0x17,0x8C,0x1C,0xDF, + 0xCC,0xB6,0xBD,0x19,0x5E,0x99,0x21,0x23,0xAC,0xA8,0x85,0x50,0x8C,0xA4,0x36,0x5F, + 0x3A,0xEE,0x52,0x86,0x66,0x99,0x44,0x24,0x54,0x74,0xD7,0x4E,0x07,0xD6,0xD1,0x3A, + 0xB6,0x1C,0xE1,0x0A,0x2C,0x14,0x53,0x0A,0x4B,0x97,0x3B,0xB4,0xDD,0xC9,0x21,0xDA, + 0x5D,0xF2,0xD5,0xBF,0xB7,0xBC,0xCF,0x84,0xD1,0x66,0x12,0x67,0x5E,0x30,0x2A,0xA3, + 0xDA,0xFD,0xC8,0x3B,0x6E,0xFA,0x54,0x31,0x47,0xAE,0xA1,0x3A,0x2C,0xE8,0xB7,0x32, + 0x76,0xD0,0x99,0xFA,0xCE,0x28,0x34,0x2B,0x68,0x1D,0xF1,0xC7,0xFD,0x70,0xE9,0xA6, + 0x3F,0x55,0xCA,0x09,0x14,0x54,0xBA,0x64,0xB2,0xA4,0xCC,0xBA,0x0B,0xA8,0x84,0x2C, + 0x3D,0xA6,0xC2,0x7C,0x73,0x58,0xD8,0x62,0x3C,0x80,0x0E,0x83,0xF3,0xF8,0x0E,0x1B, + 0xCC,0xA2,0x4C,0x14,0xBE,0xA4,0xE4,0x11,0xE8,0x9E,0x3B,0x04,0x6A,0x35,0xBE,0xB5, + 0x53,0xB0,0xF5,0x3E,0x60,0x73,0x01,0x49,0xAC,0x72,0x90,0xF9,0xA5,0xFE,0x1E,0x80, + 0x42,0x01,0xDA,0x86,0x20,0x8F,0x8A,0x0D,0xFC,0x34,0x75,0x53,0xEC,0x7E,0x6E,0x91, + 0xBD,0xF1,0x4C,0x55,0x48,0xC6,0x75,0x33,0xB3,0x89,0x08,0x49,0xAE,0x23,0xB4,0xD4, + 0x2B,0x98,0x1E,0xE6,0xAA,0x02,0x9D,0x92,0x89,0x53,0xCB,0x02,0x03,0x01,0x00,0x01, + 0xA3,0x78,0x30,0x76,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,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,0xB9,0xC0,0x16,0x46,0x09,0xF7,0xC0,0x30,0x3C,0x80,0x31, + 0x45,0xB4,0xCA,0xCA,0x83,0x61,0xB4,0x10,0x9A,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0x4D,0x60,0x02,0x55,0xCA,0x33,0x37,0x84,0x3B,0xDF, + 0x88,0x3C,0x81,0xFC,0x8A,0xE6,0xED,0x15,0xB1,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xC7,0x75, + 0xB0,0xA5,0x41,0x79,0xA2,0x22,0x57,0x9C,0x06,0xE9,0x78,0xA3,0x3A,0xB2,0xAD,0x98, + 0xC3,0x70,0xD4,0x60,0xAE,0xE9,0xE5,0xF6,0xE6,0x20,0x29,0x1E,0x51,0xE0,0xD1,0x0E, + 0x2E,0xC5,0xCA,0x9C,0x55,0x6A,0x23,0x18,0xDD,0xD2,0xAE,0x95,0xBB,0xF1,0x8A,0x21, + 0xF9,0x83,0xA4,0x7A,0x9E,0x14,0x2E,0x68,0xE8,0x11,0x36,0x6D,0xDD,0x11,0xA3,0x0A, + 0xEC,0x6A,0x58,0x5B,0x16,0xA1,0x37,0x59,0x1F,0xCC,0x15,0xB4,0x70,0xCF,0xE9,0x64, + 0xCB,0x6C,0xFC,0xF5,0xA2,0x37,0xEF,0x0C,0x4E,0xAB,0x79,0x54,0x92,0x1A,0x5B,0xDA, + 0xBA,0x1D,0x44,0x0D,0x76,0x1E,0x25,0x33,0xAD,0x69,0xBE,0xE0,0xC4,0xAF,0x5A,0xC6, + 0xDE,0xBE,0x34,0xB1,0x9D,0xDC,0x18,0x51,0xFA,0x02,0xAE,0x7D,0x34,0x50,0x46,0xCC, + 0xA1,0xD6,0x73,0x38,0x74,0xD2,0x74,0x23,0xC3,0xA7,0x77,0x22,0x1C,0xEA,0x0B,0x79, + 0x89,0xE6,0x11,0x60,0x07,0x2E,0x82,0x15,0xFC,0x1F,0x60,0x9B,0x7C,0xA6,0x71,0xAA, + 0xD3,0xBF,0xAE,0x3B,0xC8,0xE3,0x0D,0xE0,0x7F,0x7A,0x39,0x5C,0x09,0xCE,0xB5,0x5C, + 0x22,0xBA,0x52,0x95,0xDE,0xC5,0x24,0x48,0x11,0x5F,0xDA,0xF6,0x3E,0xEC,0x43,0x69, + 0xD7,0x38,0x55,0x55,0x47,0x6F,0x28,0xFD,0x66,0x79,0xF0,0xEE,0x67,0x14,0xF2,0x53, + 0x47,0xC3,0x26,0xC6,0xB4,0x85,0x30,0x65,0x2E,0x3F,0x44,0x22,0xF1,0x95,0x62,0x31, + 0xD3,0x43,0xAD,0xD8,0x40,0x9C,0x6A,0x1D,0x7E,0x4F,0xB5,0x19,0x14,0x55,0xDE,0xC0, + 0x6B,0x4A,0xCB,0x00,0xE9,0x4F,0x44,0xD9,0x6A,0xA3,0x12,0x48,0x24,0x5D, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=After Jul Any EKU Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=SSL EKU Test CA */ +/* X509v3 Extended Key Usage: Any Extended Key Usage */ +const uint8_t _anyEKU_AfterJul2019[] = { + 0x30,0x82,0x04,0x29,0x30,0x82,0x03,0x11,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,0xCC,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x84,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,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x0C,0x0F,0x53,0x53,0x4C,0x20,0x45,0x4B,0x55, + 0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x37, + 0x30,0x32,0x30,0x31,0x35,0x33,0x33,0x35,0x5A,0x17,0x0D,0x32,0x30,0x30,0x37,0x30, + 0x31,0x30,0x31,0x35,0x33,0x33,0x35,0x5A,0x30,0x81,0x8B,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x0C,0x16, + 0x41,0x66,0x74,0x65,0x72,0x20,0x4A,0x75,0x6C,0x20,0x41,0x6E,0x79,0x20,0x45,0x4B, + 0x55,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,0xAE,0xAC,0xB8,0x6E,0xB7,0x53,0x1A,0xEE,0x43, + 0xF7,0xE8,0x43,0xCB,0x1C,0x60,0x68,0x24,0x23,0x12,0xD0,0x0D,0xC7,0xF9,0xAC,0x50, + 0x27,0xC3,0xBA,0xD5,0x53,0x70,0x72,0xB9,0xBE,0x41,0xA7,0xE3,0x98,0x92,0x09,0x37, + 0xF3,0x03,0x6D,0x19,0x55,0x51,0xDB,0xF2,0x29,0xD3,0x2D,0x37,0x01,0xF8,0xFA,0xB9, + 0xF0,0x48,0x19,0xB3,0xEB,0xEF,0x86,0x6C,0xE2,0xE9,0x08,0xD5,0x48,0x1C,0x97,0x50, + 0x4C,0xDE,0xF2,0x73,0xDC,0x1E,0xB3,0xBC,0x8B,0x7F,0x44,0xB0,0x60,0x51,0x33,0x9E, + 0xDF,0x1E,0x41,0x7F,0x3F,0x8A,0x68,0x2E,0x8B,0xB2,0xA3,0x4A,0x3B,0xC7,0x0D,0x8E, + 0xCD,0xF2,0x32,0x7A,0xB3,0x3B,0x31,0xA9,0xCD,0x3B,0x83,0x6D,0x3F,0xE3,0xF3,0xE0, + 0xD6,0xB6,0x45,0xF0,0xE5,0xBA,0xB6,0x87,0xEB,0x7D,0xDE,0x0D,0x7A,0x5E,0x63,0xB4, + 0xD6,0x05,0x94,0xD3,0xEB,0xEA,0x39,0x3D,0x6D,0x5E,0x5C,0xB4,0x4C,0xDE,0xFA,0x98, + 0xDD,0x47,0x04,0xF6,0xDD,0xB1,0x80,0x85,0xE5,0x8E,0x70,0x00,0xE8,0x4F,0x71,0x90, + 0xB1,0xBD,0x8E,0x87,0x08,0x95,0x3D,0xB2,0x63,0xDC,0x6F,0x1B,0x1F,0x7C,0x8A,0xDE, + 0xE0,0xBE,0x12,0x8E,0xEA,0xFA,0xBB,0x81,0xD7,0xDD,0x5D,0xB9,0xCC,0x62,0xFB,0x7A, + 0x20,0xAF,0x78,0x89,0xEB,0x6E,0x2A,0x63,0x17,0xBE,0x7F,0xFD,0x19,0x5A,0x5F,0xBB, + 0xDD,0x5C,0xE5,0x45,0xE2,0x9B,0x08,0xB2,0xA1,0x1C,0xC6,0x4A,0x16,0xB8,0xEB,0xF6, + 0x59,0x18,0x78,0x70,0xA9,0xAC,0x72,0x3C,0xF4,0x1C,0xA0,0x45,0x5F,0x3E,0xDC,0x28, + 0x7E,0x8C,0x49,0xA6,0x87,0x9C,0x7B,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x8A,0x30, + 0x81,0x87,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,0x0F,0x06,0x03,0x55,0x1D,0x25,0x04,0x08,0x30,0x06,0x06,0x04,0x55,0x1D,0x25, + 0x00,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,0xCE,0x96,0x36,0xD5,0xEF,0x9B,0x5E,0xEB,0x6E,0x8B,0x5C,0xC6, + 0x61,0x58,0x72,0x50,0x65,0x95,0x5B,0xD2,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04, + 0x18,0x30,0x16,0x80,0x14,0x4D,0x60,0x02,0x55,0xCA,0x33,0x37,0x84,0x3B,0xDF,0x88, + 0x3C,0x81,0xFC,0x8A,0xE6,0xED,0x15,0xB1,0x1E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, + 0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x68,0x0F,0xC7, + 0xAD,0x51,0x8C,0xD4,0xAB,0xB4,0x86,0xFC,0xE6,0x8A,0xE6,0xCC,0xCF,0x82,0xA7,0xDE, + 0x1A,0xC1,0x50,0x51,0xC4,0x78,0x7E,0x45,0x3C,0x03,0x7F,0x65,0x7E,0x6D,0xA7,0xA3, + 0x92,0x3F,0x87,0xB3,0xFD,0x37,0x88,0xF7,0xED,0x71,0x2E,0xCB,0xFD,0x72,0xD2,0xEE, + 0xAE,0xB0,0xE6,0x51,0x6A,0x0D,0xE5,0x1F,0xA8,0x36,0x71,0x03,0xA0,0x30,0xF0,0x69, + 0x4C,0x18,0xCF,0x04,0x80,0x8E,0xC0,0x71,0x44,0xC0,0xC1,0xC1,0x1D,0x9B,0xD5,0x5B, + 0xA4,0xDF,0xF1,0x2F,0xFE,0x4F,0x59,0x5E,0x12,0x84,0xD3,0x98,0xDE,0x72,0x27,0x8D, + 0x44,0xE7,0xCD,0x8A,0xC2,0x7F,0x84,0x5E,0xE1,0x68,0x1A,0x0E,0x34,0x55,0xF8,0x9F, + 0x5C,0x69,0x7E,0xE5,0x08,0x31,0x96,0x4F,0xB0,0x53,0xD6,0x19,0x88,0xC3,0x2E,0x86, + 0xDA,0xFD,0x7A,0x3B,0xAC,0xD9,0x02,0x35,0x9D,0x18,0x1C,0x8D,0xD7,0xAC,0xE8,0x8E, + 0x89,0xC9,0x7B,0xC1,0xDB,0x1D,0xF7,0xDC,0xC1,0x71,0x8E,0x38,0x81,0x09,0xFA,0x4D, + 0x32,0x56,0x90,0xDF,0xE4,0x1B,0x83,0x88,0x5A,0xE5,0xB7,0x58,0xB0,0xF8,0xE4,0x13, + 0x06,0x64,0x8C,0xFE,0x06,0x10,0xBB,0xDB,0x66,0x0E,0xCC,0xA0,0xCE,0x13,0x5C,0x22, + 0x8B,0x48,0xA5,0x10,0x91,0x9A,0xF8,0x1B,0x1E,0x2D,0xF0,0x11,0x16,0xA5,0x79,0xD7, + 0xA0,0xA5,0x2B,0x35,0xED,0x72,0xA1,0x20,0x7A,0xA3,0x29,0xD6,0x93,0x4B,0x2A,0x80, + 0x49,0x64,0x81,0x31,0x5C,0x52,0x1A,0x7C,0x32,0x4A,0xB8,0xA6,0xE7,0xDD,0x95,0xD3, + 0x2A,0x2C,0x2D,0x1C,0x57,0xC2,0x69,0xA2,0x3F,0xF9,0x6D,0xD3,0x0B, +}; +#endif /* _TRUSTTESTS_EVALUATION_SSL_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/SignatureAlgorithmTests.m b/tests/TrustTests/EvaluationTests/SignatureAlgorithmTests.m new file mode 100644 index 00000000..49ac4b23 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/SignatureAlgorithmTests.m @@ -0,0 +1,474 @@ +/* + * 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 "TrustEvaluationTestCase.h" +#include "../TestMacroConversions.h" +#include "SignatureAlgorithmTests_data.h" + +@interface SignatureAlgorithmTests : TrustEvaluationTestCase +@end + +@implementation SignatureAlgorithmTests + +- (void)testMD5Root { + SecCertificateRef md5_root = NULL; + SecTrustRef trust = NULL; + CFArrayRef 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(anchors = CFArrayCreate(NULL, (const void **)&md5_root, 1, &kCFTypeArrayCallBacks), errOut, + fail("failed to create anchors array")); + 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(md5_root, NULL, &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); + +errOut: + CFReleaseNull(error); + CFReleaseNull(trust); + CFReleaseNull(anchors); + CFReleaseNull(verifyDate); + CFReleaseNull(md5_root); +} + +- (void)testMD5Leaf { + SecCertificateRef md5_leaf = NULL, sha256_root = NULL; + SecTrustRef trust = NULL; + CFArrayRef anchors = NULL; + CFDateRef verifyDate = NULL; + CFErrorRef error = NULL; + + 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(anchors = CFArrayCreate(NULL, (const void **)&sha256_root, 1, &kCFTypeArrayCallBacks), errOut, + fail("failed to create anchors array")); + require_action(verifyDate = CFDateCreate(NULL, 550600000), errOut, fail("failed to make verification date")); // June 13, 2018 + + /* Test non-self-signed MD5 cert. Should fail. */ + require_noerr_action(SecTrustCreateWithCertificates(md5_leaf, NULL, &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), (int)errSecInvalidDigestAlgorithm); + } else { + fail("expected trust evaluation to fail and it did not."); + } + +errOut: + CFReleaseNull(md5_leaf); + CFReleaseNull(sha256_root); + CFReleaseNull(anchors); + CFReleaseNull(verifyDate); + CFReleaseNull(trust); + CFReleaseNull(error); +} + +- (bool)runTrust:(NSArray *)certs + anchors:(NSArray *)anchors + policy:(SecPolicyRef)policy + verifyDate:(NSDate *)date +{ + SecTrustRef trust = NULL; + XCTAssert(errSecSuccess == SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trust)); + if (anchors) { + XCTAssert(errSecSuccess == SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors)); + } + XCTAssert(errSecSuccess == SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date)); + + CFErrorRef error = NULL; + bool result = SecTrustEvaluateWithError(trust, &error); + CFReleaseNull(error); + CFReleaseNull(trust); + return result; +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have a system trust store +- (void)testSHA1_systemTrusted { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0]; // November 4, 2016 at 5:53:20 PM PDT + SecCertificateRef sha1_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha1, sizeof(_badssl_sha1)); + SecCertificateRef sha1_int = SecCertificateCreateWithBytes(NULL, _digiCertSSCA, sizeof(_digiCertSSCA)); + NSArray *sha1_certs = @[ (__bridge id)sha1_leaf, (__bridge id)sha1_int]; + CFReleaseNull(sha1_leaf); + CFReleaseNull(sha1_int); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com")); + XCTAssertFalse([self runTrust:sha1_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "system trusted SHA1 certs succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "system trusted SHA1 certs failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"www.badssl.com"]); + XCTAssertFalse([self runTrust:sha1_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "system trusted SHA1 certs succeeded for EAP"); + CFReleaseNull(eapPolicy); +} +#endif // !TARGET_OS_BRIDGE + +- (void)testSHA1_appTrustedLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0]; // November 4, 2016 at 5:53:20 PM PDT + SecCertificateRef sha1_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha1, sizeof(_badssl_sha1)); + SecCertificateRef sha1_int = SecCertificateCreateWithBytes(NULL, _digiCertSSCA, sizeof(_digiCertSSCA)); + SecCertificateRef sha1_root = SecCertificateCreateWithBytes(NULL, _digiCertRoot, sizeof(_digiCertRoot)); + + NSArray *sha1_certs = @[ (__bridge id)sha1_leaf, (__bridge id)sha1_int]; + NSArray *anchor = @[ (__bridge id)sha1_root ]; + CFReleaseNull(sha1_leaf); + CFReleaseNull(sha1_int); + CFReleaseNull(sha1_root); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com")); + XCTAssertFalse([self runTrust:sha1_certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "anchor trusted SHA1 certs succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "anchor trusted SHA1 certs failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"*.badssl.com", @"badssl.com"]); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "anchor trusted SHA1 certs failed for EAP"); + CFReleaseNull(eapPolicy); + + SecPolicyRef legacyPolicy = SecPolicyCreateLegacySSL(true, CFSTR("www.badssl.com")); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:legacyPolicy verifyDate:verifyDate], "anchor trusted SHA1 certs failed for legacy SSL server"); + CFReleaseNull(legacyPolicy); + + SecPolicyRef legacyClientPolicy = SecPolicyCreateLegacySSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:legacyClientPolicy verifyDate:verifyDate], "anchor trusted SHA1 certs failed for legacy SSL client"); + CFReleaseNull(legacyClientPolicy); +} + +- (void)testSHA1_appTrustedSelfSigned { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha1_cert = SecCertificateCreateWithBytes(NULL, _testSHA1SelfSigned, sizeof(_testSHA1SelfSigned)); + NSArray *sha1_certs = @[ (__bridge id)sha1_cert ]; + NSArray *anchor = @[ (__bridge id)sha1_cert ]; + CFReleaseNull(sha1_cert); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "anchor trusted self-signed SHA1 cert failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "anchor trusted self-signed SHA1 cert failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "anchor trusted self-signed SHA1 cert failed for EAP"); + CFReleaseNull(eapPolicy); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have trust settings +- (void)testSHA1_trustSettingsOnRoot_TestLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha1_leaf = SecCertificateCreateWithBytes(NULL, _testSHA1Leaf, sizeof(_testSHA1Leaf)); + SecCertificateRef sha1_root = SecCertificateCreateWithBytes(NULL, _testRoot, sizeof(_testRoot)); + NSArray *sha1_certs = @[ (__bridge id)sha1_leaf, (__bridge id)sha1_root ]; + CFReleaseNull(sha1_leaf); + + id persistentRef = [self addTrustSettingsForCert:sha1_root]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertFalse([self runTrust:sha1_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on root, SHA1 leaf succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on root, SHA1 leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on root, SHA1 leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha1_root persistentRef:persistentRef]; + CFReleaseNull(sha1_root); +} + +- (void)testSHA1_trustSettingsOnLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha1_leaf = SecCertificateCreateWithBytes(NULL, _testSHA1Leaf, sizeof(_testSHA1Leaf)); + NSArray *sha1_certs = @[ (__bridge id)sha1_leaf ]; + + id persistentRef = [self addTrustSettingsForCert:sha1_leaf]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on SHA1 leaf failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on SHA1 leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on SHA1 leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha1_leaf persistentRef:persistentRef]; + CFReleaseNull(sha1_leaf); +} + +- (void)testSHA1_trustSettingsSelfSigned { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha1_cert = SecCertificateCreateWithBytes(NULL, _testSHA1SelfSigned, sizeof(_testSHA1SelfSigned)); + NSArray *sha1_certs = @[ (__bridge id)sha1_cert ]; + + id persistentRef = [self addTrustSettingsForCert:sha1_cert]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings self-signed SHA1 cert failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings self-signed SHA1 cert failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha1_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings self-signed SHA1 cert failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha1_cert persistentRef:persistentRef]; + CFReleaseNull(sha1_cert); +} + +- (void)testSHA1_denyTrustSettings { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha1_leaf = SecCertificateCreateWithBytes(NULL, _testSHA1Leaf, sizeof(_testSHA1Leaf)); + NSArray *sha1_certs = @[ (__bridge id)sha1_leaf ]; + + id persistentRef = [self addTrustSettingsForCert:sha1_leaf trustSettings: @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)}]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertFalse([self runTrust:sha1_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "deny trust settings on SHA1 leaf succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertFalse([self runTrust:sha1_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "deny trust settings on SHA1 leaf succeeded for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertFalse([self runTrust:sha1_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "deny trust settings on SHA1 leaf succeeded for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha1_leaf persistentRef:persistentRef]; + CFReleaseNull(sha1_leaf); +} + +- (void)testSHA1_unspecifiedTrustSettings { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha1_leaf = SecCertificateCreateWithBytes(NULL, _testSHA1Leaf, sizeof(_testSHA1Leaf)); + SecCertificateRef sha1_root = SecCertificateCreateWithBytes(NULL, _testRoot, sizeof(_testRoot)); + NSArray *sha1_certs = @[ (__bridge id)sha1_leaf ]; + NSArray *anchor = @[ (__bridge id)sha1_root ]; + CFReleaseNull(sha1_root); + + id persistentRef = [self addTrustSettingsForCert:sha1_leaf trustSettings: @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)}]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertFalse([self runTrust:sha1_certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "unspecified trust settings on SHA1 leaf succeeded for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "unspecified trust settings on SHA1 leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha1_certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "unspecified trust settings on SHA1 leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha1_leaf persistentRef:persistentRef]; + CFReleaseNull(sha1_leaf); +} +#endif // !TARGET_OS_BRIDGE + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have a system trust store +- (void)testSHA2_systemTrusted { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0]; // November 4, 2016 at 5:53:20 PM PDT + + SecCertificateRef sha2_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha2, sizeof(_badssl_sha2)); + SecCertificateRef sha2_int = SecCertificateCreateWithBytes(NULL, _COMODO_DV, sizeof(_COMODO_DV)); + NSArray *sha2_certs = @[ (__bridge id)sha2_leaf, (__bridge id)sha2_int]; + CFReleaseNull(sha2_leaf); + CFReleaseNull(sha2_int); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com")); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "system trusted SHA2 certs failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "system trusted SHA2 certs failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"*.badssl.com", @"badssl.com"]); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "system trusted SHA2 certs failed for EAP"); + CFReleaseNull(eapPolicy); +} +#endif + +- (void)testSHA2_appTrustedLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:500000000.0]; // November 4, 2016 at 5:53:20 PM PDT + + SecCertificateRef sha2_leaf = SecCertificateCreateWithBytes(NULL, _badssl_sha2, sizeof(_badssl_sha2)); + SecCertificateRef sha2_int = SecCertificateCreateWithBytes(NULL, _COMODO_DV, sizeof(_COMODO_DV)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _COMODO_root, sizeof(_COMODO_root)); + + NSArray *sha2_certs = @[ (__bridge id)sha2_leaf, (__bridge id)sha2_int]; + NSArray *anchor = @[ (__bridge id)root ]; + + CFReleaseNull(sha2_leaf); + CFReleaseNull(sha2_int); + CFReleaseNull(root); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("www.badssl.com")); + XCTAssertTrue([self runTrust:sha2_certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "anchor trusted SHA2 certs failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha2_certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "anchor trusted SHA2 certs failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"*.badssl.com", @"badssl.com"]); + XCTAssertTrue([self runTrust:sha2_certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "anchor trusted SHA2 certs failed for EAP"); + CFReleaseNull(eapPolicy); +} + +- (void)testSHA2_appTrustedSelfSigned { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha2_cert = SecCertificateCreateWithBytes(NULL, _testSHA2SelfSigned, sizeof(_testSHA2SelfSigned)); + NSArray *sha2_certs = @[ (__bridge id)sha2_cert ]; + NSArray *anchor = @[ (__bridge id)sha2_cert ]; + CFReleaseNull(sha2_cert); + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha2_certs anchors:anchor policy:serverPolicy verifyDate:verifyDate], "anchor trusted self-signed SHA2 cert failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha2_certs anchors:anchor policy:clientPolicy verifyDate:verifyDate], "anchor trusted self-signed SHA2 cert failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha2_certs anchors:anchor policy:eapPolicy verifyDate:verifyDate], "anchor trusted self-signed SHA2 cert failed for EAP"); + CFReleaseNull(eapPolicy); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have trust settings +- (void)testSHA2_trustSettingsOnRoot_TestLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha2_leaf = SecCertificateCreateWithBytes(NULL, _testSHA2Leaf, sizeof(_testSHA2Leaf)); + SecCertificateRef sha2_root = SecCertificateCreateWithBytes(NULL, _testRoot, sizeof(_testRoot)); + NSArray *sha2_certs = @[ (__bridge id)sha2_leaf, (__bridge id)sha2_root ]; + CFReleaseNull(sha2_leaf); + + id persistentRef = [self addTrustSettingsForCert:sha2_root]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on root, SHA2 leaf failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on root, SHA2 leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on root, SHA2 leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha2_root persistentRef:persistentRef]; + CFReleaseNull(sha2_root); +} + +- (void)testSHA2_trustSettingsOnLeaf { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha2_leaf = SecCertificateCreateWithBytes(NULL, _testSHA2Leaf, sizeof(_testSHA2Leaf)); + NSArray *sha2_certs = @[ (__bridge id)sha2_leaf ]; + + id persistentRef = [self addTrustSettingsForCert:sha2_leaf]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings on SHA2 leaf failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings on SHA2 leaf failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings on SHA2 leaf failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha2_leaf persistentRef:persistentRef]; + CFReleaseNull(sha2_leaf); +} + +- (void)testSHA2_trustSettingsSelfSigned { + NSDate *verifyDate = [NSDate dateWithTimeIntervalSinceReferenceDate:578000000.0]; // April 26, 2019 at 12:33:20 PM PDT + SecCertificateRef sha2_cert = SecCertificateCreateWithBytes(NULL, _testSHA2SelfSigned, sizeof(_testSHA2SelfSigned)); + NSArray *sha2_certs = @[ (__bridge id)sha2_cert ]; + + id persistentRef = [self addTrustSettingsForCert:sha2_cert]; + + SecPolicyRef serverPolicy = SecPolicyCreateSSL(true, CFSTR("example.com")); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:serverPolicy verifyDate:verifyDate], "trust settings self-signed SHA2 cert failed for SSL server"); + CFReleaseNull(serverPolicy); + + SecPolicyRef clientPolicy = SecPolicyCreateSSL(false, NULL); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:clientPolicy verifyDate:verifyDate], "trust settings self-signed SHA2 cert failed for SSL client"); + CFReleaseNull(clientPolicy); + + SecPolicyRef eapPolicy = SecPolicyCreateEAP(true, (__bridge CFArrayRef)@[@"example.com"]); + XCTAssertTrue([self runTrust:sha2_certs anchors:nil policy:eapPolicy verifyDate:verifyDate], "trust settings self-signed SHA2 cert failed for EAP"); + CFReleaseNull(eapPolicy); + + [self removeTrustSettingsForCert:sha2_cert persistentRef:persistentRef]; + CFReleaseNull(sha2_cert); +} +#endif // !TARGET_OS_BRIDGE + +@end diff --git a/tests/TrustTests/EvaluationTests/SignatureAlgorithmTests_data.h b/tests/TrustTests/EvaluationTests/SignatureAlgorithmTests_data.h new file mode 100644 index 00000000..30e75a10 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/SignatureAlgorithmTests_data.h @@ -0,0 +1,1117 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_SIG_ALG_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_SIG_ALG_TESTS_H_ + +/* 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, +}; + +/* subject:/C=US/ST=California/L=Walnut Creek/O=Lucas Garron/CN=*.badssl.com */ +/* issuer :/C=US/O=DigiCert Inc/CN=DigiCert Secure Server CA */ +uint8_t _badssl_sha1[] = { + 0x30,0x82,0x05,0x02,0x30,0x82,0x03,0xEA,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0B, + 0xA1,0x28,0x31,0xAB,0x8A,0x7D,0x86,0x4E,0x61,0x59,0xDC,0x34,0xE7,0x5E,0x0D,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x48, + 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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x13,0x19,0x44, + 0x69,0x67,0x69,0x43,0x65,0x72,0x74,0x20,0x53,0x65,0x63,0x75,0x72,0x65,0x20,0x53, + 0x65,0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x35,0x30,0x36, + 0x30,0x39,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x31,0x30, + 0x35,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x67,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,0x15,0x30,0x13,0x06,0x03, + 0x55,0x04,0x03,0x0C,0x0C,0x2A,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,0xC2,0x04,0xEC,0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58, + 0xCC,0x93,0x18,0xEB,0x5C,0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B, + 0x2C,0x76,0x3E,0x6C,0xC0,0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6, + 0xB0,0xF9,0x72,0xC9,0x86,0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B, + 0xBC,0xE9,0x94,0x2E,0x50,0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46, + 0xD3,0x16,0x87,0x27,0x9F,0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84, + 0x4C,0x79,0x55,0xE4,0xD1,0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB, + 0xAA,0xFF,0x6E,0xFF,0x60,0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD, + 0x4D,0xC0,0xC4,0xFC,0x53,0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2, + 0x33,0x48,0xE7,0x22,0x71,0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA, + 0x6C,0xB5,0x72,0xB4,0x7E,0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12, + 0xAB,0xDE,0xC3,0x0F,0x47,0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD, + 0x22,0x06,0x29,0x2E,0xB1,0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40, + 0x72,0x00,0xAC,0x92,0x08,0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B, + 0x54,0x98,0x40,0x27,0x85,0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45, + 0x55,0x7C,0xF9,0x64,0x3F,0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1, + 0xCA,0x85,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0xC7,0x30,0x82,0x01,0xC3,0x30, + 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0x71,0xDB,0x37, + 0xEB,0x73,0xC8,0xEF,0xDC,0xD5,0x1E,0x12,0xB6,0x34,0xBA,0x2B,0x5A,0xA0,0xA6,0x92, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81, + 0x0B,0x3A,0x47,0x69,0x71,0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,0x30, + 0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30,0x1A,0x82,0x0A,0x62,0x61,0x64,0x73, + 0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82,0x0C,0x2A,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,0x02,0x06,0x08,0x2B,0x06,0x01,0x05,0x05, + 0x07,0x03,0x01,0x30,0x61,0x06,0x03,0x55,0x1D,0x1F,0x04,0x5A,0x30,0x58,0x30,0x2A, + 0xA0,0x28,0xA0,0x26,0x86,0x24,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,0x67,0x37,0x2E,0x63,0x72,0x6C,0x30,0x2A,0xA0,0x28,0xA0,0x26, + 0x86,0x24,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, + 0x67,0x37,0x2E,0x63,0x72,0x6C,0x30,0x42,0x06,0x03,0x55,0x1D,0x20,0x04,0x3B,0x30, + 0x39,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,0x78,0x06,0x08,0x2B,0x06, + 0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x6C,0x30,0x6A,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,0x42,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x36,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,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,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, + 0x00,0x03,0x82,0x01,0x01,0x00,0x63,0x5C,0x60,0xD0,0xDB,0x4D,0x93,0xF9,0xAE,0x41, + 0xF0,0x4E,0xBF,0xFF,0x2A,0x11,0x6A,0x5E,0x15,0x5C,0x95,0x61,0x95,0x04,0x6A,0xD8, + 0x0E,0xA1,0xA2,0x80,0x12,0x4A,0x9E,0x15,0x3B,0x80,0x7A,0x4F,0xAA,0x49,0xCB,0x86, + 0xDA,0xD8,0xAF,0xF1,0xE2,0x87,0x36,0xA3,0xE6,0xDB,0xCA,0x98,0xDF,0x5A,0x3C,0x5C, + 0xDF,0x95,0x1C,0xA7,0xE9,0xCB,0xB2,0xD9,0xF5,0xE2,0x20,0x5C,0x4D,0xF4,0xD3,0x6D, + 0xCE,0x4A,0xE9,0xE2,0x20,0x32,0x29,0x0C,0x1B,0x60,0x01,0x9B,0xEA,0xDB,0x84,0xEF, + 0x1B,0xBD,0xA7,0xC7,0x4B,0x20,0x5F,0xD9,0x9D,0x1B,0xDB,0xEB,0x82,0x79,0x3E,0xDF, + 0xFD,0xDA,0xCF,0xFD,0x8C,0x50,0x1B,0xDD,0x6F,0x71,0x82,0x92,0x23,0x03,0x64,0xF0, + 0x00,0x57,0x28,0xFA,0x8B,0x03,0x3F,0xB9,0xCC,0x90,0x40,0x93,0xBB,0x70,0xC8,0x56, + 0x59,0xA8,0x4D,0x6A,0x77,0x94,0xAA,0x15,0xEE,0x5E,0x13,0x10,0xC8,0x07,0xC4,0xCD, + 0xC7,0xFA,0x24,0x25,0xFB,0xDB,0x8A,0x1C,0xB2,0x2E,0xA1,0x52,0xB9,0x28,0x3F,0xD8, + 0x50,0x22,0xB2,0x04,0x0C,0xB4,0x81,0x83,0xB8,0xC3,0x4A,0x0C,0xF9,0xB2,0xAC,0x89, + 0x5C,0xDD,0x04,0xE6,0x26,0xFA,0xF5,0x09,0x5E,0x34,0xCD,0x4C,0xE0,0xAB,0x02,0xBB, + 0x98,0x63,0x7E,0x07,0x57,0x6E,0xAA,0x61,0x8A,0x53,0xFC,0x3E,0x95,0x77,0x84,0x8C, + 0x4D,0x4B,0x5F,0x6E,0xA3,0x38,0x06,0x0E,0x82,0x63,0x57,0xA1,0x22,0x87,0x95,0x12, + 0x71,0xA1,0x84,0x61,0xBA,0xF1,0x0B,0x07,0xB4,0x01,0x32,0x68,0x14,0x29,0xC9,0x58, + 0x3A,0x57,0xE6,0x5C,0x21,0x78, +}; + +/* subject:/C=US/O=DigiCert Inc/CN=DigiCert Secure Server CA */ +/* issuer :/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert Global Root CA */ +uint8_t _digiCertSSCA[] = { + 0x30,0x82,0x04,0x8F,0x30,0x82,0x03,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x06, + 0x9E,0x1D,0xB7,0x7F,0xCF,0x1D,0xFB,0xA9,0x7A,0xF5,0xE5,0xC9,0xA2,0x40,0x37,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,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,0x48,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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03, + 0x13,0x19,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74,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,0xBB,0x57,0xE4,0x21, + 0xA9,0xD5,0x9B,0x60,0x37,0x7E,0x8E,0xA1,0x61,0x7F,0x81,0xE2,0x1A,0xC2,0x75,0x64, + 0xD9,0x91,0x50,0x0B,0xE4,0x36,0x44,0x24,0x6E,0x30,0xD2,0x9B,0x7A,0x27,0xFA,0xC2, + 0x6A,0xAE,0x6A,0x70,0x09,0x38,0xB9,0x20,0x0A,0xC8,0x65,0x10,0x4A,0x88,0xAC,0x31, + 0xF2,0xDC,0x92,0xF2,0x63,0xA1,0x5D,0x80,0x63,0x59,0x80,0x92,0x23,0x1C,0xE6,0xEF, + 0x76,0x4A,0x50,0x35,0xC9,0xD8,0x71,0x38,0xB9,0xED,0xF0,0xE6,0x42,0xAE,0xD3,0x38, + 0x26,0x79,0x30,0xF9,0x22,0x94,0xC6,0xDB,0xA6,0x3F,0x41,0x78,0x90,0xD8,0xDE,0x5C, + 0x7E,0x69,0x7D,0xF8,0x90,0x15,0x3A,0xD0,0xA1,0xA0,0xBE,0xFA,0xB2,0xB2,0x19,0xA1, + 0xD8,0x2B,0xD1,0xCE,0xBF,0x6B,0xDD,0x49,0xAB,0xA3,0x92,0xFE,0xB5,0xAB,0xC8,0xC1, + 0x3E,0xEE,0x01,0x00,0xD8,0xA9,0x44,0xB8,0x42,0x73,0x88,0xC3,0x61,0xF5,0xAB,0x4A, + 0x83,0x28,0x0A,0xD2,0xD4,0x49,0xFA,0x6A,0xB1,0xCD,0xDF,0x57,0x2C,0x94,0xE5,0xE2, + 0xCA,0x83,0x5F,0xB7,0xBA,0x62,0x5C,0x2F,0x68,0xA5,0xF0,0xC0,0xB9,0xFD,0x2B,0xD1, + 0xE9,0x1F,0xD8,0x1A,0x62,0x15,0xBD,0xFF,0x3D,0xA6,0xF7,0xCB,0xEF,0xE6,0xDB,0x65, + 0x2F,0x25,0x38,0xEC,0xFB,0xE6,0x20,0x66,0x58,0x96,0x34,0x19,0xD2,0x15,0xCE,0x21, + 0xD3,0x24,0xCC,0xD9,0x14,0x6F,0xD8,0xFE,0x55,0xC7,0xE7,0x6F,0xB6,0x0F,0x1A,0x8C, + 0x49,0xBE,0x29,0xF2,0xBA,0x5A,0x9A,0x81,0x26,0x37,0x24,0x6F,0xD7,0x48,0x12,0x6C, + 0x2E,0x59,0xF5,0x9C,0x18,0xBB,0xD9,0xF6,0x68,0xE2,0xDF,0x45,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,0x90,0x71,0xDB,0x37,0xEB,0x73, + 0xC8,0xEF,0xDC,0xD5,0x1E,0x12,0xB6,0x34,0xBA,0x2B,0x5A,0xA0,0xA6,0x92,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,0x30,0xCE,0xD1,0x95,0x51,0x00,0xAE,0x06,0x0B,0xA1,0x0E,0x02,0xC0, + 0x17,0xAC,0xB6,0x7F,0x8F,0x20,0xF6,0x40,0x75,0x74,0x1C,0xCC,0x78,0xB1,0xA4,0x4F, + 0xEA,0xF4,0xD0,0xC4,0x9D,0xA2,0xDE,0x81,0x07,0x26,0x1F,0x40,0x88,0x51,0xF0,0x1F, + 0xCF,0xB7,0x4C,0x40,0x99,0xD0,0xF4,0x3C,0x71,0x98,0x73,0x88,0x97,0x2C,0x19,0xD7, + 0x6E,0x84,0x8F,0xA4,0x1F,0x9C,0x5A,0x20,0xE3,0x51,0x5C,0xB0,0xC5,0x9E,0x99,0x6A, + 0x4F,0xC8,0x69,0xF7,0x10,0xFF,0x4E,0xAD,0x19,0xD9,0xC9,0x58,0xB3,0x33,0xAE,0x0C, + 0xD9,0x96,0x29,0x9E,0x71,0xB2,0x70,0x63,0xA3,0xB6,0x99,0x16,0x42,0x1D,0x65,0xF3, + 0xF7,0xA0,0x1E,0x7D,0xC5,0xD4,0x65,0x14,0xB2,0x62,0x84,0xD4,0x6C,0x5C,0x08,0x0C, + 0xD8,0x6C,0x93,0x2B,0xB4,0x76,0x59,0x8A,0xD1,0x7F,0xFF,0x03,0xD8,0xC2,0x5D,0xB8, + 0x2F,0x22,0xD6,0x38,0xF0,0xF6,0x9C,0x6B,0x7D,0x46,0xEB,0x99,0x74,0xF7,0xEB,0x4A, + 0x0E,0xA9,0xA6,0x04,0xEB,0x7B,0xCE,0xF0,0x5C,0x6B,0x98,0x31,0x5A,0x98,0x40,0xEB, + 0x69,0xC4,0x05,0xF4,0x20,0xA8,0xCA,0x08,0x3A,0x65,0x6C,0x38,0x15,0xF5,0x5C,0x2C, + 0xB2,0x55,0xE4,0x2C,0x6B,0x41,0xF0,0xBE,0x5C,0x46,0xCA,0x4A,0x29,0xA0,0x48,0x5E, + 0x20,0xD2,0x45,0xFF,0x05,0xDE,0x34,0xAF,0x70,0x4B,0x81,0x39,0xE2,0xCA,0x07,0x57, + 0x7C,0xB6,0x31,0xDC,0x21,0x29,0xE2,0xBE,0x97,0x0E,0x77,0x90,0x14,0x51,0x40,0xE1, + 0xBF,0xE3,0xCC,0x1B,0x19,0x9C,0x25,0xCA,0xA7,0x06,0xB2,0x53,0xDF,0x23,0xB2,0xCF, + 0x12,0x19,0xA3, +}; + +/* 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 _digiCertRoot[] = { + 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, +}; + +/* subject:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.badssl.com */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +uint8_t _badssl_sha2[] = { + 0x30,0x82,0x05,0x4B,0x30,0x82,0x04,0x33,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, + 0x8E,0x18,0x71,0x4B,0x34,0xE7,0x5E,0x8D,0xAE,0xFB,0xE8,0xF6,0x4C,0x3A,0x82,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, + 0x90,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,0x36,0x30,0x34,0x06,0x03,0x55, + 0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44, + 0x6F,0x6D,0x61,0x69,0x6E,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,0x36,0x30,0x37,0x30,0x37,0x30,0x30,0x30,0x30,0x30, + 0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x39,0x30,0x35,0x32,0x33,0x35,0x39,0x35,0x39, + 0x5A,0x30,0x59,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x56,0x61,0x6C, + 0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13, + 0x14,0x50,0x6F,0x73,0x69,0x74,0x69,0x76,0x65,0x53,0x53,0x4C,0x20,0x57,0x69,0x6C, + 0x64,0x63,0x61,0x72,0x64,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x0C,0x0C, + 0x2A,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,0xC2,0x04,0xEC, + 0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58,0xCC,0x93,0x18,0xEB,0x5C, + 0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B,0x2C,0x76,0x3E,0x6C,0xC0, + 0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6,0xB0,0xF9,0x72,0xC9,0x86, + 0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B,0xBC,0xE9,0x94,0x2E,0x50, + 0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46,0xD3,0x16,0x87,0x27,0x9F, + 0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84,0x4C,0x79,0x55,0xE4,0xD1, + 0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB,0xAA,0xFF,0x6E,0xFF,0x60, + 0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD,0x4D,0xC0,0xC4,0xFC,0x53, + 0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2,0x33,0x48,0xE7,0x22,0x71, + 0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA,0x6C,0xB5,0x72,0xB4,0x7E, + 0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12,0xAB,0xDE,0xC3,0x0F,0x47, + 0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD,0x22,0x06,0x29,0x2E,0xB1, + 0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40,0x72,0x00,0xAC,0x92,0x08, + 0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B,0x54,0x98,0x40,0x27,0x85, + 0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45,0x55,0x7C,0xF9,0x64,0x3F, + 0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1,0xCA,0x85,0x02,0x03,0x01, + 0x00,0x01,0xA3,0x82,0x01,0xD5,0x30,0x82,0x01,0xD1,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90, + 0xEA,0x12,0x56,0x73,0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81,0x0B,0x3A,0x47,0x69,0x71, + 0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,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,0x4F,0x06,0x03,0x55,0x1D,0x20,0x04,0x48, + 0x30,0x46,0x30,0x3A,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x02, + 0x07,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,0x08, + 0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x01,0x30,0x54,0x06,0x03,0x55,0x1D,0x1F,0x04, + 0x4D,0x30,0x4B,0x30,0x49,0xA0,0x47,0xA0,0x45,0x86,0x43,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,0x44,0x6F,0x6D,0x61, + 0x69,0x6E,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, + 0x85,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x79,0x30,0x77,0x30, + 0x4F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x43,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,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,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,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30, + 0x1A,0x82,0x0C,0x2A,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82, + 0x0A,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A, + 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x75, + 0x48,0x83,0x88,0x9C,0x55,0x24,0x37,0x30,0x07,0xEB,0x26,0x68,0xC8,0x79,0x1C,0x5C, + 0xAE,0x9A,0x02,0x9A,0xB5,0x52,0x75,0x44,0xAC,0xA9,0xED,0x59,0x65,0xD0,0xC6,0x47, + 0x26,0x04,0x8D,0x57,0x89,0x16,0x2E,0x71,0x18,0x48,0x98,0x68,0x1C,0xF6,0x31,0xF5, + 0x26,0x4B,0xE8,0x81,0x44,0xB1,0xFF,0x5C,0x65,0x3D,0x78,0x54,0x94,0xC3,0x86,0x9D, + 0x48,0x96,0xE8,0x32,0xAF,0xE1,0x8F,0x94,0x47,0xBE,0x37,0x8C,0xC3,0xED,0x4D,0x97, + 0xBB,0xC6,0x2A,0x37,0x72,0x01,0x3A,0x8F,0x82,0xA4,0x34,0x44,0xC4,0xC4,0xF8,0x50, + 0x24,0x48,0x9E,0x19,0xF0,0xEC,0xE1,0xC6,0x13,0x44,0x26,0xB6,0x65,0xE1,0x62,0x49, + 0x87,0xA4,0xF4,0xD8,0xC4,0x39,0x3C,0x7D,0x42,0xC8,0xA4,0x2A,0x54,0x05,0xA0,0xDC, + 0x0A,0xF8,0x2B,0x22,0x94,0x93,0x78,0x4E,0x6A,0x36,0x1B,0xD2,0xE7,0xE9,0xAE,0x84, + 0xED,0x13,0x1D,0xA1,0xF7,0xA2,0x83,0x81,0x03,0x4C,0x9E,0x21,0xFB,0xBF,0xA8,0x30, + 0xFE,0xEB,0x00,0x68,0xB1,0x7F,0xBA,0x5D,0xE2,0x5D,0xFF,0x41,0x1F,0xD6,0xF5,0xA6, + 0x5C,0x8A,0xEF,0x81,0x80,0xC8,0xF1,0x52,0x00,0x17,0x9D,0xD1,0x96,0x1A,0x7D,0x5E, + 0xD2,0x83,0xB3,0x82,0xC2,0x3D,0x46,0x83,0xA5,0x1E,0xB4,0x36,0x35,0x38,0xC4,0x7A, + 0x2E,0xDF,0x0B,0xA1,0x98,0x63,0x58,0x0B,0x1E,0xD0,0x6D,0x83,0x1F,0xF1,0x72,0x4D, + 0x09,0xAC,0x96,0x1A,0x0B,0xE5,0xF6,0x34,0x4C,0xAB,0xBC,0xBC,0x99,0x5B,0x82,0x59, + 0xE6,0x6C,0xD3,0xDB,0x98,0xE0,0xCE,0x95,0x3B,0xCF,0x4E,0x17,0xC3,0xEE,0x3A, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +uint8_t _COMODO_DV[] = { + 0x30,0x82,0x06,0x08,0x30,0x82,0x03,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2B, + 0x2E,0x6E,0xEA,0xD9,0x75,0x36,0x6C,0x14,0x8A,0x6E,0xDB,0xA3,0x7C,0x8C,0x07,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,0x34,0x30,0x32,0x31,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x32,0x31,0x31,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x90,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,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F, + 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44,0x6F,0x6D,0x61,0x69,0x6E,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,0x8E,0xC2,0x02,0x19,0xE1,0xA0, + 0x59,0xA4,0xEB,0x38,0x35,0x8D,0x2C,0xFD,0x01,0xD0,0xD3,0x49,0xC0,0x64,0xC7,0x0B, + 0x62,0x05,0x45,0x16,0x3A,0xA8,0xA0,0xC0,0x0C,0x02,0x7F,0x1D,0xCC,0xDB,0xC4,0xA1, + 0x6D,0x77,0x03,0xA3,0x0F,0x86,0xF9,0xE3,0x06,0x9C,0x3E,0x0B,0x81,0x8A,0x9B,0x49, + 0x1B,0xAD,0x03,0xBE,0xFA,0x4B,0xDB,0x8C,0x20,0xED,0xD5,0xCE,0x5E,0x65,0x8E,0x3E, + 0x0D,0xAF,0x4C,0xC2,0xB0,0xB7,0x45,0x5E,0x52,0x2F,0x34,0xDE,0x48,0x24,0x64,0xB4, + 0x41,0xAE,0x00,0x97,0xF7,0xBE,0x67,0xDE,0x9E,0xD0,0x7A,0xA7,0x53,0x80,0x3B,0x7C, + 0xAD,0xF5,0x96,0x55,0x6F,0x97,0x47,0x0A,0x7C,0x85,0x8B,0x22,0x97,0x8D,0xB3,0x84, + 0xE0,0x96,0x57,0xD0,0x70,0x18,0x60,0x96,0x8F,0xEE,0x2D,0x07,0x93,0x9D,0xA1,0xBA, + 0xCA,0xD1,0xCD,0x7B,0xE9,0xC4,0x2A,0x9A,0x28,0x21,0x91,0x4D,0x6F,0x92,0x4F,0x25, + 0xA5,0xF2,0x7A,0x35,0xDD,0x26,0xDC,0x46,0xA5,0xD0,0xAC,0x59,0x35,0x8C,0xFF,0x4E, + 0x91,0x43,0x50,0x3F,0x59,0x93,0x1E,0x6C,0x51,0x21,0xEE,0x58,0x14,0xAB,0xFE,0x75, + 0x50,0x78,0x3E,0x4C,0xB0,0x1C,0x86,0x13,0xFA,0x6B,0x98,0xBC,0xE0,0x3B,0x94,0x1E, + 0x85,0x52,0xDC,0x03,0x93,0x24,0x18,0x6E,0xCB,0x27,0x51,0x45,0xE6,0x70,0xDE,0x25, + 0x43,0xA4,0x0D,0xE1,0x4A,0xA5,0xED,0xB6,0x7E,0xC8,0xCD,0x6D,0xEE,0x2E,0x1D,0x27, + 0x73,0x5D,0xDC,0x45,0x30,0x80,0xAA,0xE3,0xB2,0x41,0x0B,0xAF,0xBD,0x44,0x87,0xDA, + 0xB9,0xE5,0x1B,0x9D,0x7F,0xAE,0xE5,0x85,0x82,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x82,0x01,0x65,0x30,0x82,0x01,0x61,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,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90,0xEA,0x12,0x56,0x73, + 0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, + 0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,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,0x1B,0x06,0x03,0x55,0x1D, + 0x20,0x04,0x14,0x30,0x12,0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x08,0x06, + 0x06,0x67,0x81,0x0C,0x01,0x02,0x01,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,0x4E,0x2B,0x76,0x4F, + 0x92,0x1C,0x62,0x36,0x89,0xBA,0x77,0xC1,0x27,0x05,0xF4,0x1C,0xD6,0x44,0x9D,0xA9, + 0x9A,0x3E,0xAA,0xD5,0x66,0x66,0x01,0x3E,0xEA,0x49,0xE6,0xA2,0x35,0xBC,0xFA,0xF6, + 0xDD,0x95,0x8E,0x99,0x35,0x98,0x0E,0x36,0x18,0x75,0xB1,0xDD,0xDD,0x50,0x72,0x7C, + 0xAE,0xDC,0x77,0x88,0xCE,0x0F,0xF7,0x90,0x20,0xCA,0xA3,0x67,0x2E,0x1F,0x56,0x7F, + 0x7B,0xE1,0x44,0xEA,0x42,0x95,0xC4,0x5D,0x0D,0x01,0x50,0x46,0x15,0xF2,0x81,0x89, + 0x59,0x6C,0x8A,0xDD,0x8C,0xF1,0x12,0xA1,0x8D,0x3A,0x42,0x8A,0x98,0xF8,0x4B,0x34, + 0x7B,0x27,0x3B,0x08,0xB4,0x6F,0x24,0x3B,0x72,0x9D,0x63,0x74,0x58,0x3C,0x1A,0x6C, + 0x3F,0x4F,0xC7,0x11,0x9A,0xC8,0xA8,0xF5,0xB5,0x37,0xEF,0x10,0x45,0xC6,0x6C,0xD9, + 0xE0,0x5E,0x95,0x26,0xB3,0xEB,0xAD,0xA3,0xB9,0xEE,0x7F,0x0C,0x9A,0x66,0x35,0x73, + 0x32,0x60,0x4E,0xE5,0xDD,0x8A,0x61,0x2C,0x6E,0x52,0x11,0x77,0x68,0x96,0xD3,0x18, + 0x75,0x51,0x15,0x00,0x1B,0x74,0x88,0xDD,0xE1,0xC7,0x38,0x04,0x43,0x28,0xE9,0x16, + 0xFD,0xD9,0x05,0xD4,0x5D,0x47,0x27,0x60,0xD6,0xFB,0x38,0x3B,0x6C,0x72,0xA2,0x94, + 0xF8,0x42,0x1A,0xDF,0xED,0x6F,0x06,0x8C,0x45,0xC2,0x06,0x00,0xAA,0xE4,0xE8,0xDC, + 0xD9,0xB5,0xE1,0x73,0x78,0xEC,0xF6,0x23,0xDC,0xD1,0xDD,0x6C,0x8E,0x1A,0x8F,0xA5, + 0xEA,0x54,0x7C,0x96,0xB7,0xC3,0xFE,0x55,0x8E,0x8D,0x49,0x5E,0xFC,0x64,0xBB,0xCF, + 0x3E,0xBD,0x96,0xEB,0x69,0xCD,0xBF,0xE0,0x48,0xF1,0x62,0x82,0x10,0xE5,0x0C,0x46, + 0x57,0xF2,0x33,0xDA,0xD0,0xC8,0x63,0xED,0xC6,0x1F,0x94,0x05,0x96,0x4A,0x1A,0x91, + 0xD1,0xF7,0xEB,0xCF,0x8F,0x52,0xAE,0x0D,0x08,0xD9,0x3E,0xA8,0xA0,0x51,0xE9,0xC1, + 0x87,0x74,0xD5,0xC9,0xF7,0x74,0xAB,0x2E,0x53,0xFB,0xBB,0x7A,0xFB,0x97,0xE2,0xF8, + 0x1F,0x26,0x8F,0xB3,0xD2,0xA0,0xE0,0x37,0x5B,0x28,0x3B,0x31,0xE5,0x0E,0x57,0x2D, + 0x5A,0xB8,0xAD,0x79,0xAC,0x5E,0x20,0x66,0x1A,0xA5,0xB9,0xA6,0xB5,0x39,0xC1,0xF5, + 0x98,0x43,0xFF,0xEE,0xF9,0xA7,0xA7,0xFD,0xEE,0xCA,0x24,0x3D,0x80,0x16,0xC4,0x17, + 0x8F,0x8A,0xC1,0x60,0xA1,0x0C,0xAE,0x5B,0x43,0x47,0x91,0x4B,0xD5,0x9A,0x17,0x5F, + 0xF9,0xD4,0x87,0xC1,0xC2,0x8C,0xB7,0xE7,0xE2,0x0F,0x30,0x19,0x37,0x86,0xAC,0xE0, + 0xDC,0x42,0x03,0xE6,0x94,0xA8,0x9D,0xAE,0xFD,0x0F,0x24,0x51,0x94,0xCE,0x92,0x08, + 0xD1,0xFC,0x50,0xF0,0x03,0x40,0x7B,0x88,0x59,0xED,0x0E,0xDD,0xAC,0xD2,0x77,0x82, + 0x34,0xDC,0x06,0x95,0x02,0xD8,0x90,0xF9,0x2D,0xEA,0x37,0xD5,0x1A,0x60,0xD0,0x67, + 0x20,0xD7,0xD8,0x42,0x0B,0x45,0xAF,0x82,0x68,0xDE,0xDD,0x66,0x24,0x37,0x90,0x29, + 0x94,0x19,0x46,0x19,0x25,0xB8,0x80,0xD7,0xCB,0xD4,0x86,0x28,0x6A,0x44,0x70,0x26, + 0x23,0x62,0xA9,0x9F,0x86,0x6F,0xBF,0xBA,0x90,0x70,0xD2,0x56,0x77,0x85,0x78,0xEF, + 0xEA,0x25,0xA9,0x17,0xCE,0x50,0x72,0x8C,0x00,0x3A,0xAA,0xE3,0xDB,0x63,0x34,0x9F, + 0xF8,0x06,0x71,0x01,0xE2,0x82,0x20,0xD4,0xFE,0x6F,0xBD,0xB1, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +uint8_t _COMODO_root[] = { + 0x30,0x82,0x05,0xD8,0x30,0x82,0x03,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, + 0xAA,0xF9,0xCA,0xDB,0x63,0x6F,0xE0,0x1F,0xF7,0x4E,0xD8,0x5B,0x03,0x86,0x9D,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,0x30,0x30,0x31,0x31,0x39, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,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,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,0x91, + 0xE8,0x54,0x92,0xD2,0x0A,0x56,0xB1,0xAC,0x0D,0x24,0xDD,0xC5,0xCF,0x44,0x67,0x74, + 0x99,0x2B,0x37,0xA3,0x7D,0x23,0x70,0x00,0x71,0xBC,0x53,0xDF,0xC4,0xFA,0x2A,0x12, + 0x8F,0x4B,0x7F,0x10,0x56,0xBD,0x9F,0x70,0x72,0xB7,0x61,0x7F,0xC9,0x4B,0x0F,0x17, + 0xA7,0x3D,0xE3,0xB0,0x04,0x61,0xEE,0xFF,0x11,0x97,0xC7,0xF4,0x86,0x3E,0x0A,0xFA, + 0x3E,0x5C,0xF9,0x93,0xE6,0x34,0x7A,0xD9,0x14,0x6B,0xE7,0x9C,0xB3,0x85,0xA0,0x82, + 0x7A,0x76,0xAF,0x71,0x90,0xD7,0xEC,0xFD,0x0D,0xFA,0x9C,0x6C,0xFA,0xDF,0xB0,0x82, + 0xF4,0x14,0x7E,0xF9,0xBE,0xC4,0xA6,0x2F,0x4F,0x7F,0x99,0x7F,0xB5,0xFC,0x67,0x43, + 0x72,0xBD,0x0C,0x00,0xD6,0x89,0xEB,0x6B,0x2C,0xD3,0xED,0x8F,0x98,0x1C,0x14,0xAB, + 0x7E,0xE5,0xE3,0x6E,0xFC,0xD8,0xA8,0xE4,0x92,0x24,0xDA,0x43,0x6B,0x62,0xB8,0x55, + 0xFD,0xEA,0xC1,0xBC,0x6C,0xB6,0x8B,0xF3,0x0E,0x8D,0x9A,0xE4,0x9B,0x6C,0x69,0x99, + 0xF8,0x78,0x48,0x30,0x45,0xD5,0xAD,0xE1,0x0D,0x3C,0x45,0x60,0xFC,0x32,0x96,0x51, + 0x27,0xBC,0x67,0xC3,0xCA,0x2E,0xB6,0x6B,0xEA,0x46,0xC7,0xC7,0x20,0xA0,0xB1,0x1F, + 0x65,0xDE,0x48,0x08,0xBA,0xA4,0x4E,0xA9,0xF2,0x83,0x46,0x37,0x84,0xEB,0xE8,0xCC, + 0x81,0x48,0x43,0x67,0x4E,0x72,0x2A,0x9B,0x5C,0xBD,0x4C,0x1B,0x28,0x8A,0x5C,0x22, + 0x7B,0xB4,0xAB,0x98,0xD9,0xEE,0xE0,0x51,0x83,0xC3,0x09,0x46,0x4E,0x6D,0x3E,0x99, + 0xFA,0x95,0x17,0xDA,0x7C,0x33,0x57,0x41,0x3C,0x8D,0x51,0xED,0x0B,0xB6,0x5C,0xAF, + 0x2C,0x63,0x1A,0xDF,0x57,0xC8,0x3F,0xBC,0xE9,0x5D,0xC4,0x9B,0xAF,0x45,0x99,0xE2, + 0xA3,0x5A,0x24,0xB4,0xBA,0xA9,0x56,0x3D,0xCF,0x6F,0xAA,0xFF,0x49,0x58,0xBE,0xF0, + 0xA8,0xFF,0xF4,0xB8,0xAD,0xE9,0x37,0xFB,0xBA,0xB8,0xF4,0x0B,0x3A,0xF9,0xE8,0x43, + 0x42,0x1E,0x89,0xD8,0x84,0xCB,0x13,0xF1,0xD9,0xBB,0xE1,0x89,0x60,0xB8,0x8C,0x28, + 0x56,0xAC,0x14,0x1D,0x9C,0x0A,0xE7,0x71,0xEB,0xCF,0x0E,0xDD,0x3D,0xA9,0x96,0xA1, + 0x48,0xBD,0x3C,0xF7,0xAF,0xB5,0x0D,0x22,0x4C,0xC0,0x11,0x81,0xEC,0x56,0x3B,0xF6, + 0xD3,0xA2,0xE2,0x5B,0xB7,0xB2,0x04,0x22,0x52,0x95,0x80,0x93,0x69,0xE8,0x8E,0x4C, + 0x65,0xF1,0x91,0x03,0x2D,0x70,0x74,0x02,0xEA,0x8B,0x67,0x15,0x29,0x69,0x52,0x02, + 0xBB,0xD7,0xDF,0x50,0x6A,0x55,0x46,0xBF,0xA0,0xA3,0x28,0x61,0x7F,0x70,0xD0,0xC3, + 0xA2,0xAA,0x2C,0x21,0xAA,0x47,0xCE,0x28,0x9C,0x06,0x45,0x76,0xBF,0x82,0x18,0x27, + 0xB4,0xD5,0xAE,0xB4,0xCB,0x50,0xE6,0x6B,0xF4,0x4C,0x86,0x71,0x30,0xE9,0xA6,0xDF, + 0x16,0x86,0xE0,0xD8,0xFF,0x40,0xDD,0xFB,0xD0,0x42,0x88,0x7F,0xA3,0x33,0x3A,0x2E, + 0x5C,0x1E,0x41,0x11,0x81,0x63,0xCE,0x18,0x71,0x6B,0x2B,0xEC,0xA6,0x8A,0xB7,0x31, + 0x5C,0x3A,0x6A,0x47,0xE0,0xC3,0x79,0x59,0xD6,0x20,0x1A,0xAF,0xF2,0x6A,0x98,0xAA, + 0x72,0xBC,0x57,0x4A,0xD2,0x4B,0x9D,0xBB,0x10,0xFC,0xB0,0x4C,0x41,0xE5,0xED,0x1D, + 0x3D,0x5E,0x28,0x9D,0x9C,0xCC,0xBF,0xB3,0x51,0xDA,0xA7,0x47,0xE5,0x84,0x53,0x02, + 0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, + 0x16,0x04,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84,0x8E,0xAD,0xEE, + 0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,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,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x0A,0xF1,0xD5,0x46, + 0x84,0xB7,0xAE,0x51,0xBB,0x6C,0xB2,0x4D,0x41,0x14,0x00,0x93,0x4C,0x9C,0xCB,0xE5, + 0xC0,0x54,0xCF,0xA0,0x25,0x8E,0x02,0xF9,0xFD,0xB0,0xA2,0x0D,0xF5,0x20,0x98,0x3C, + 0x13,0x2D,0xAC,0x56,0xA2,0xB0,0xD6,0x7E,0x11,0x92,0xE9,0x2E,0xBA,0x9E,0x2E,0x9A, + 0x72,0xB1,0xBD,0x19,0x44,0x6C,0x61,0x35,0xA2,0x9A,0xB4,0x16,0x12,0x69,0x5A,0x8C, + 0xE1,0xD7,0x3E,0xA4,0x1A,0xE8,0x2F,0x03,0xF4,0xAE,0x61,0x1D,0x10,0x1B,0x2A,0xA4, + 0x8B,0x7A,0xC5,0xFE,0x05,0xA6,0xE1,0xC0,0xD6,0xC8,0xFE,0x9E,0xAE,0x8F,0x2B,0xBA, + 0x3D,0x99,0xF8,0xD8,0x73,0x09,0x58,0x46,0x6E,0xA6,0x9C,0xF4,0xD7,0x27,0xD3,0x95, + 0xDA,0x37,0x83,0x72,0x1C,0xD3,0x73,0xE0,0xA2,0x47,0x99,0x03,0x38,0x5D,0xD5,0x49, + 0x79,0x00,0x29,0x1C,0xC7,0xEC,0x9B,0x20,0x1C,0x07,0x24,0x69,0x57,0x78,0xB2,0x39, + 0xFC,0x3A,0x84,0xA0,0xB5,0x9C,0x7C,0x8D,0xBF,0x2E,0x93,0x62,0x27,0xB7,0x39,0xDA, + 0x17,0x18,0xAE,0xBD,0x3C,0x09,0x68,0xFF,0x84,0x9B,0x3C,0xD5,0xD6,0x0B,0x03,0xE3, + 0x57,0x9E,0x14,0xF7,0xD1,0xEB,0x4F,0xC8,0xBD,0x87,0x23,0xB7,0xB6,0x49,0x43,0x79, + 0x85,0x5C,0xBA,0xEB,0x92,0x0B,0xA1,0xC6,0xE8,0x68,0xA8,0x4C,0x16,0xB1,0x1A,0x99, + 0x0A,0xE8,0x53,0x2C,0x92,0xBB,0xA1,0x09,0x18,0x75,0x0C,0x65,0xA8,0x7B,0xCB,0x23, + 0xB7,0x1A,0xC2,0x28,0x85,0xC3,0x1B,0xFF,0xD0,0x2B,0x62,0xEF,0xA4,0x7B,0x09,0x91, + 0x98,0x67,0x8C,0x14,0x01,0xCD,0x68,0x06,0x6A,0x63,0x21,0x75,0x03,0x80,0x88,0x8A, + 0x6E,0x81,0xC6,0x85,0xF2,0xA9,0xA4,0x2D,0xE7,0xF4,0xA5,0x24,0x10,0x47,0x83,0xCA, + 0xCD,0xF4,0x8D,0x79,0x58,0xB1,0x06,0x9B,0xE7,0x1A,0x2A,0xD9,0x9D,0x01,0xD7,0x94, + 0x7D,0xED,0x03,0x4A,0xCA,0xF0,0xDB,0xE8,0xA9,0x01,0x3E,0xF5,0x56,0x99,0xC9,0x1E, + 0x8E,0x49,0x3D,0xBB,0xE5,0x09,0xB9,0xE0,0x4F,0x49,0x92,0x3D,0x16,0x82,0x40,0xCC, + 0xCC,0x59,0xC6,0xE6,0x3A,0xED,0x12,0x2E,0x69,0x3C,0x6C,0x95,0xB1,0xFD,0xAA,0x1D, + 0x7B,0x7F,0x86,0xBE,0x1E,0x0E,0x32,0x46,0xFB,0xFB,0x13,0x8F,0x75,0x7F,0x4C,0x8B, + 0x4B,0x46,0x63,0xFE,0x00,0x34,0x40,0x70,0xC1,0xC3,0xB9,0xA1,0xDD,0xA6,0x70,0xE2, + 0x04,0xB3,0x41,0xBC,0xE9,0x80,0x91,0xEA,0x64,0x9C,0x7A,0xE1,0x22,0x03,0xA9,0x9C, + 0x6E,0x6F,0x0E,0x65,0x4F,0x6C,0x87,0x87,0x5E,0xF3,0x6E,0xA0,0xF9,0x75,0xA5,0x9B, + 0x40,0xE8,0x53,0xB2,0x27,0x9D,0x4A,0xB9,0xC0,0x77,0x21,0x8D,0xFF,0x87,0xF2,0xDE, + 0xBC,0x8C,0xEF,0x17,0xDF,0xB7,0x49,0x0B,0xD1,0xF2,0x6E,0x30,0x0B,0x1A,0x0E,0x4E, + 0x76,0xED,0x11,0xFC,0xF5,0xE9,0x56,0xB2,0x7D,0xBF,0xC7,0x6D,0x0A,0x93,0x8C,0xA5, + 0xD0,0xC0,0xB6,0x1D,0xBE,0x3A,0x4E,0x94,0xA2,0xD7,0x6E,0x6C,0x0B,0xC2,0x8A,0x7C, + 0xFA,0x20,0xF3,0xC4,0xE4,0xE5,0xCD,0x0D,0xA8,0xCB,0x91,0x92,0xB1,0x7C,0x85,0xEC, + 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=Weak Crypto Test CA */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +uint8_t _testRoot[] = { + 0x30,0x82,0x03,0xDA,0x30,0x82,0x02,0xC2,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xCE,0xB0,0xBF,0x61,0x75,0x93,0xF9,0x53,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x88,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,0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57, + 0x65,0x61,0x6B,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,0x74,0x20, + 0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32,0x33,0x33, + 0x34,0x38,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x33,0x33,0x34, + 0x38,0x5A,0x30,0x81,0x88,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, + 0x1C,0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57,0x65,0x61,0x6B,0x20,0x43, + 0x72,0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,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,0xC8,0xC5, + 0x06,0x13,0xEB,0x60,0xE1,0x07,0xE3,0x47,0x50,0x42,0xC3,0x5B,0xAE,0xF4,0x5A,0x65, + 0x6A,0x74,0xAC,0xF2,0xF6,0x1C,0xFC,0x45,0x21,0x8D,0x0E,0x08,0x78,0x83,0x28,0xDD, + 0xBB,0xDD,0x65,0xD4,0x2F,0x05,0x56,0x06,0x21,0xEF,0xE2,0xE9,0x2C,0x78,0x61,0x56, + 0x1F,0x87,0x4D,0x99,0xD0,0x2B,0x47,0x30,0xFF,0xAE,0x29,0x1F,0x63,0xF3,0xFC,0x26, + 0xEC,0xDF,0xCD,0x34,0xD1,0x4B,0xDE,0x5A,0x52,0xFA,0x90,0x1F,0x6B,0xDE,0x74,0x79, + 0xDD,0x3E,0x53,0x62,0x20,0xD3,0x5B,0x18,0x0A,0xE8,0xBE,0xEB,0xBD,0x52,0x81,0xAD, + 0x1A,0x24,0x3C,0x9C,0xAD,0xC4,0x72,0xA9,0x9D,0xC1,0xC0,0x7F,0x42,0x32,0x02,0x5B, + 0x4F,0xFF,0x5E,0x7F,0xA5,0xD0,0x26,0xF9,0xF7,0x80,0xF9,0xEC,0x86,0x0F,0xA9,0x0B, + 0x12,0x6E,0x95,0x1D,0x18,0xC9,0x0D,0x7B,0x52,0xD2,0x37,0xF1,0x68,0x45,0x9C,0x58, + 0x6F,0x88,0xC7,0x71,0x9F,0x02,0xEA,0x44,0x13,0xF2,0x5D,0xAC,0x81,0xD7,0x59,0x98, + 0x19,0xA2,0xB8,0x56,0xA3,0x89,0xC7,0xD9,0x5E,0xA2,0xA8,0xBA,0xC2,0x97,0x94,0x09, + 0xBB,0x81,0xDE,0xE8,0x9A,0x06,0x92,0xAA,0x14,0xDA,0x4D,0xFB,0xD6,0xD4,0xC6,0x0F, + 0x1E,0x25,0xAA,0x42,0xDB,0x3F,0x59,0xD2,0x90,0x93,0x4C,0xB4,0xF8,0x39,0x8B,0xA1, + 0x54,0x7B,0x83,0x29,0xCF,0xA2,0x53,0xD7,0x14,0x9A,0x57,0xB8,0x13,0x0F,0x48,0x1F, + 0x56,0x13,0xE3,0xBB,0x9A,0x11,0x62,0x37,0x25,0xA4,0x8A,0xA2,0x03,0x9E,0x9F,0xD0, + 0x08,0x52,0xF7,0x58,0x79,0xD6,0xBD,0xD7,0xCA,0x00,0x3C,0xE7,0xFB,0xDB,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,0xF1,0x0F,0x83,0xE3,0x07,0x66,0xE9,0x79,0xEE,0x31, + 0x1A,0x6A,0x30,0x9B,0xDA,0x97,0x15,0xF7,0xB9,0xB4,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9D,0xC9, + 0xCD,0xFB,0x8F,0x40,0xC2,0xFD,0xF0,0x7D,0x8D,0x36,0x43,0x57,0x98,0x91,0x11,0x0A, + 0x3A,0x70,0x28,0x5D,0xCC,0xF6,0xB7,0xF9,0x51,0xB3,0xCA,0x80,0x67,0x5A,0xF4,0x6D, + 0xB4,0x4A,0x50,0x11,0xC5,0x25,0xA3,0x5B,0xBF,0x03,0xB4,0xA2,0x37,0x80,0x08,0x7B, + 0x5D,0xDB,0x39,0x2B,0x06,0xA0,0x6C,0x5B,0x1D,0x1E,0x21,0x79,0x5B,0x34,0x78,0x03, + 0xA2,0xBF,0x2F,0x68,0x90,0xF7,0xA9,0x55,0x35,0xAF,0x27,0x58,0xF5,0x96,0x93,0x64, + 0x9E,0xC0,0x4E,0x76,0x9E,0xEA,0x18,0x1B,0x97,0x7B,0xFB,0x71,0x4D,0x30,0x5C,0x5D, + 0x4C,0xDF,0xB4,0x41,0x0C,0x15,0xC0,0x94,0xAA,0x85,0xB8,0x55,0x39,0x49,0xA4,0x5F, + 0x33,0xA1,0x57,0x2C,0xF1,0x16,0xC6,0x0B,0xCC,0x33,0x4B,0xA5,0xA3,0x44,0x63,0xA3, + 0xCB,0x9F,0xC9,0xF8,0x99,0x51,0x63,0x28,0x8D,0xC7,0xE3,0x45,0x6F,0x4E,0x26,0x8C, + 0xEA,0xDA,0xAE,0x74,0xFC,0x81,0xBC,0x5E,0xF1,0x64,0xD5,0xE5,0x63,0x74,0x34,0x9B, + 0x72,0x54,0xF9,0xE1,0x5A,0xE6,0x2C,0xCF,0x2B,0xD9,0x0B,0xD1,0xF4,0xB8,0x51,0x9D, + 0x9D,0x70,0xC2,0x2B,0xC4,0x07,0x6B,0xA2,0x70,0xC7,0x1B,0x33,0xC3,0x50,0x65,0xB6, + 0x13,0x18,0x64,0xFF,0x27,0xA8,0x7B,0xD8,0xCB,0x45,0xC9,0xD2,0x57,0x2A,0x15,0xB6, + 0x6E,0xD9,0x06,0xEB,0x38,0xC6,0x19,0x97,0x4E,0x3D,0x31,0x45,0x90,0x6A,0xD9,0x55, + 0x60,0x43,0xF4,0x04,0x62,0x39,0xE0,0x8A,0xAB,0x55,0xA4,0xA2,0xF8,0x5E,0xA9,0x3E, + 0xCB,0x08,0x9B,0x35,0x66,0x5D,0xFA,0x6A,0xC2,0x93,0x12,0x74,0x63,0x20, + +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Strong Crypto Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +uint8_t _testSHA2Leaf[] = { + 0x30,0x82,0x04,0x37,0x30,0x82,0x03,0x1F,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,0xC6,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x88,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,0x1C, + 0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57,0x65,0x61,0x6B,0x20,0x43,0x72, + 0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32,0x33,0x38,0x31,0x34,0x5A,0x17,0x0D,0x32, + 0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x33,0x38,0x31,0x34,0x5A,0x30,0x81,0x87,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,0x1B,0x30,0x19,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x12,0x53,0x74,0x72,0x6F,0x6E,0x67,0x20,0x43,0x72,0x79,0x70,0x74, + 0x6F,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,0xAF,0x01,0x48,0x09,0xB9,0xA1,0xB5,0x29,0x07, + 0x36,0x35,0xA6,0x5D,0x97,0x38,0x1F,0x0A,0xD1,0xD8,0x0B,0xD1,0xC5,0xDD,0x07,0x39, + 0x96,0xBA,0xDD,0xFF,0xC0,0x42,0x8D,0x19,0xDD,0xA9,0x44,0x0A,0xD6,0xD7,0xBA,0x74, + 0x1F,0xDA,0x75,0x15,0x02,0x50,0xC9,0x78,0x46,0x76,0xDB,0xAA,0xCF,0xE0,0x5A,0xA1, + 0xDE,0x81,0xFB,0x73,0xB9,0x85,0x7F,0xA4,0xD7,0x52,0xE6,0x96,0xD7,0x67,0x42,0x78, + 0x89,0x8D,0xFF,0xD6,0xF4,0x3D,0x02,0x68,0x14,0xA2,0x5E,0x48,0xD9,0x2C,0x9B,0x09, + 0x09,0xEA,0x00,0x00,0xB1,0x8B,0x32,0xB8,0x1E,0x92,0x05,0xFF,0xCB,0x72,0x7A,0x6F, + 0x8F,0xCC,0xFB,0x04,0xCD,0x11,0xC0,0x12,0xBA,0x62,0x6E,0x02,0xBA,0x8C,0xE7,0x61, + 0xE7,0xC4,0x52,0xA5,0xA6,0xF3,0x86,0x34,0xA8,0xCC,0x15,0x59,0x48,0x18,0xF3,0xCC, + 0x13,0xE4,0x8A,0x3F,0xF1,0xF8,0xED,0xD8,0x74,0x5D,0x86,0x6E,0x07,0x6A,0xA1,0xA9, + 0xCF,0x46,0xE0,0x76,0x38,0xC8,0xEC,0x33,0x7A,0x40,0x5E,0x0E,0x6E,0xB0,0x11,0x53, + 0xD0,0xA3,0xEB,0x7E,0x73,0x6D,0xFD,0xAB,0xAE,0x24,0x31,0x2E,0x1D,0xC8,0x3D,0xF7, + 0xBE,0xA4,0xB1,0x6A,0x69,0x09,0xDF,0xBE,0x20,0x43,0x55,0x55,0x49,0x26,0x36,0xF5, + 0x3F,0x8F,0x25,0xDA,0x34,0x1A,0xD4,0x2B,0xCC,0x88,0x5C,0xDA,0x03,0x85,0xE3,0xCF, + 0xD4,0xA7,0x8E,0x49,0x30,0x74,0x8A,0xB0,0x11,0xCF,0xA0,0x81,0xA6,0x99,0x5E,0xE2, + 0xEE,0x47,0x03,0x13,0x04,0x07,0xAB,0x74,0x30,0x4D,0xA7,0xFF,0xD7,0x7A,0x9B,0xBA, + 0x38,0x94,0x35,0xC3,0xDD,0x93,0xBB,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98,0x30, + 0x81,0x95,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,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, + 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,0x77,0xD2,0xF8,0xFB,0x2A,0x51,0x1C,0xD0,0x26,0x13,0x7B,0x36,0xFB,0x3D, + 0xC9,0x04,0xFD,0x75,0x22,0xFE,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, + 0x16,0x80,0x14,0xF1,0x0F,0x83,0xE3,0x07,0x66,0xE9,0x79,0xEE,0x31,0x1A,0x6A,0x30, + 0x9B,0xDA,0x97,0x15,0xF7,0xB9,0xB4,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x2B,0x72,0x9E,0x87,0xFA, + 0x4D,0x05,0x78,0x93,0x49,0x7F,0x58,0x3D,0x49,0xD8,0x3D,0x5A,0x69,0x29,0x58,0x41, + 0x74,0xAA,0x29,0xEF,0x4E,0x04,0x5F,0x7D,0xA8,0x54,0x8D,0x59,0x90,0x28,0x93,0x90, + 0x45,0x82,0x31,0xE2,0xC5,0xE8,0xFC,0xFB,0x91,0x07,0xD0,0x89,0x60,0x69,0xAB,0x4A, + 0xB1,0x63,0x39,0xF9,0xD9,0xED,0xFC,0x81,0xB9,0x28,0x0B,0xBA,0x53,0xC1,0xF7,0x94, + 0xE4,0x1A,0x02,0xAE,0xD9,0x02,0x42,0x43,0xAE,0xFC,0x26,0x4C,0x75,0x6C,0x51,0xAD, + 0x11,0xB9,0xBA,0x65,0xD1,0x5D,0x51,0x15,0x0D,0xDA,0xAC,0x26,0x53,0x77,0xFE,0x68, + 0xFD,0x83,0xD3,0xB0,0x29,0x26,0xC5,0x2F,0x2F,0x2B,0x76,0x4A,0x62,0x7C,0x41,0xBB, + 0x2A,0xF7,0xE4,0x51,0x28,0x1D,0x34,0xB1,0x46,0x44,0x58,0x04,0x8F,0x64,0x20,0xBE, + 0x26,0x5C,0x36,0x07,0xD1,0x7C,0xAB,0x3D,0x12,0x02,0xD5,0xC1,0xB6,0xBF,0x12,0x3A, + 0xC4,0x8A,0x61,0x8E,0x16,0x55,0x61,0x88,0xA5,0xBE,0xA8,0xAC,0x3B,0xD3,0xEB,0xAC, + 0xB8,0xEF,0x54,0xA7,0x78,0x99,0xA1,0x04,0x20,0x20,0x28,0x37,0xC5,0x47,0x63,0xB3, + 0x7D,0x0D,0xBB,0x8A,0x6A,0x5B,0x11,0x9C,0x08,0x09,0xCD,0xFB,0x8E,0x68,0xDF,0xE8, + 0x8C,0x7B,0x27,0x38,0xCC,0x6C,0x0B,0xCE,0x62,0xD1,0x87,0x91,0xC7,0x8B,0xD5,0xE7, + 0xA2,0xF2,0x8F,0x4F,0x32,0xB8,0xE6,0xE6,0xE1,0x20,0x82,0x9D,0xED,0x56,0xBA,0x88, + 0x2D,0xB0,0xCD,0x72,0x20,0x13,0x71,0x34,0x9C,0x02,0x0B,0x72,0x9C,0x27,0x67,0x5F, + 0x2A,0x77,0x4E,0x43,0xE5,0x71,0x96,0x36,0x11,0x0F,0x35, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Hash Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Crypto Test CA */ +uint8_t _testSHA1Leaf[] = { + 0x30,0x82,0x04,0x33,0x30,0x82,0x03,0x1B,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,0xC8,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, + 0x00,0x30,0x81,0x88,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,0x1C, + 0x30,0x1A,0x06,0x03,0x55,0x04,0x03,0x0C,0x13,0x57,0x65,0x61,0x6B,0x20,0x43,0x72, + 0x79,0x70,0x74,0x6F,0x20,0x54,0x65,0x73,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32,0x34,0x35,0x34,0x30,0x5A,0x17,0x0D,0x32, + 0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x34,0x35,0x34,0x30,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,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,0x17,0x30,0x15,0x06,0x03,0x55, + 0x04,0x03,0x0C,0x0E,0x57,0x65,0x61,0x6B,0x20,0x48,0x61,0x73,0x68,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,0xC3,0x61,0x5B,0xD8,0x42,0x1E,0x3F,0x38,0x00,0xB4,0x7A,0x05,0x5D, + 0xCF,0xAB,0x5F,0x41,0x90,0xED,0xD8,0xE6,0x9D,0xAF,0xC9,0xC4,0xF3,0xEE,0xAE,0x1A, + 0xBE,0xF2,0x5A,0x06,0x64,0x6B,0x22,0x93,0x3A,0xA6,0xD7,0x79,0x9A,0xE6,0x91,0x7F, + 0xFA,0x32,0xB8,0x65,0x9D,0xA9,0x73,0x46,0x6C,0x49,0xC3,0x6A,0x46,0x34,0x79,0x50, + 0x30,0x24,0x3A,0xF6,0x0A,0xF0,0xDA,0x4B,0x41,0x0D,0x17,0xE8,0xBA,0x63,0x19,0x86, + 0x75,0xCB,0x6A,0xC7,0x7E,0xDE,0x3F,0x02,0xD8,0xD1,0x37,0xB7,0x81,0x2A,0x60,0x69, + 0x2C,0x70,0xD1,0xB1,0xAB,0x61,0xCE,0xD0,0x05,0x9E,0x76,0xFD,0x41,0x23,0x98,0xC8, + 0xEE,0x49,0x06,0x3E,0x95,0xE0,0xC8,0x35,0xF1,0xBB,0xE5,0xA3,0x8F,0x8B,0x72,0xCB, + 0x58,0x67,0x34,0x47,0xD4,0x03,0x6B,0xA1,0xB2,0x0C,0x03,0x1F,0x23,0x9D,0xF6,0xFA, + 0xBF,0x52,0x28,0x37,0x75,0x12,0xF3,0x10,0x84,0x0F,0x25,0xFE,0x07,0x89,0x92,0xD1, + 0xCD,0xDE,0x62,0xD1,0xBB,0x92,0x96,0x39,0xEC,0x75,0xE3,0x00,0x88,0x68,0x37,0xF7, + 0x8C,0x9C,0x4B,0x34,0x98,0x04,0x4F,0xFD,0x05,0x7F,0xB4,0x8F,0x58,0x15,0x3F,0x00, + 0x49,0x7A,0x7B,0xCB,0xFB,0xCE,0x98,0x6B,0x32,0xD0,0xFC,0xFB,0x11,0xCC,0xDD,0x5C, + 0xDD,0xAA,0x42,0xF5,0x20,0x1C,0x1B,0x77,0x92,0x24,0xE0,0xCD,0x13,0x12,0xF3,0xC2, + 0x82,0x3D,0xC8,0x18,0x32,0x24,0x07,0xF9,0xC2,0x70,0x51,0x9B,0x22,0x7D,0xD6,0x0D, + 0x9B,0xF2,0x7B,0xA4,0x18,0x1C,0x46,0x37,0xEC,0x8B,0x15,0x88,0x4D,0x4C,0x0D,0x0A, + 0x55,0xFB,0xF9,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98,0x30,0x81,0x95,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,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,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,0xA4,0xD2, + 0xF8,0x15,0x02,0xE5,0x15,0x2B,0x78,0x21,0x4A,0x5A,0x42,0x91,0xC7,0xD9,0xB3,0xEA, + 0xFC,0xFA,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xF1, + 0x0F,0x83,0xE3,0x07,0x66,0xE9,0x79,0xEE,0x31,0x1A,0x6A,0x30,0x9B,0xDA,0x97,0x15, + 0xF7,0xB9,0xB4,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, + 0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x50,0x52,0x28,0xF4,0x88,0x54,0xE1,0x18,0x7D, + 0x5E,0x98,0x81,0x1A,0xA6,0xED,0xDB,0x8B,0x07,0x2D,0x38,0x45,0x6C,0xD3,0xD2,0x6A, + 0xB3,0x16,0xFA,0x00,0xFD,0x5D,0x54,0xCD,0x03,0xE0,0x6C,0x3D,0x59,0xFE,0xBA,0x94, + 0x50,0xE1,0x27,0x48,0xEC,0x45,0x72,0xAA,0x3A,0xA4,0x74,0x51,0xF1,0x60,0x3F,0x90, + 0x4B,0x99,0x18,0x3C,0xCC,0x36,0xBA,0xC1,0xDC,0xEF,0x87,0x69,0xB1,0x24,0x95,0xEA, + 0x72,0x5C,0x48,0x11,0xDC,0x42,0x42,0xE6,0x12,0x9F,0x21,0x3D,0x23,0x40,0x5A,0xB5, + 0x8E,0x56,0xFC,0xBF,0xEC,0x10,0xA6,0xF6,0x97,0x0D,0x4D,0x3E,0x1D,0x45,0x90,0xF7, + 0x4D,0xD5,0x3C,0xF3,0x79,0x21,0xFB,0x2E,0x07,0x2C,0xE2,0x90,0xD0,0x14,0xED,0xD4, + 0xDD,0x25,0xCA,0xFC,0x6D,0x32,0x31,0x70,0x07,0xD5,0xA0,0x1B,0x68,0xCF,0x1E,0x75, + 0xBB,0xF8,0x70,0xD6,0x9B,0xDC,0x70,0x4D,0x47,0x8A,0x2A,0x69,0x6C,0x34,0x55,0x23, + 0x7C,0x84,0x7F,0xD7,0x75,0x91,0xDB,0xF8,0x6F,0x45,0x43,0xA5,0xBD,0xBF,0xFD,0x39, + 0x45,0x1F,0xB5,0x37,0x5A,0xA7,0x6B,0x01,0x0B,0x28,0xF2,0xA8,0x4E,0x12,0xCD,0xF2, + 0xC9,0x1E,0x30,0x50,0x13,0x75,0xCB,0xCF,0x86,0x4E,0x4F,0xF7,0x0C,0x05,0xD5,0x71, + 0xC8,0x8E,0xDC,0x2A,0xEA,0x3C,0x3C,0x86,0x9F,0x0F,0x73,0x8B,0x62,0xDE,0xC6,0x0D, + 0x44,0x2F,0x5C,0x42,0x0A,0x51,0x20,0xAC,0x81,0x4B,0x2F,0x88,0x39,0x2A,0x24,0xAA, + 0x46,0x8E,0x22,0x89,0xBB,0x47,0x86,0x3D,0x3F,0x26,0x12,0xB0,0xB7,0xE1,0xFF,0x45, + 0xFD,0x63,0x48,0xC7,0x41,0x02,0x26, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Hash Self-Signed */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Weak Hash Self-Signed */ +uint8_t _testSHA1SelfSigned[] = { + 0x30,0x82,0x04,0x32,0x30,0x82,0x03,0x1A,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0x97,0x6D,0x87,0x02,0x79,0xC6,0xC4,0x8F,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x81,0x8A,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x57, + 0x65,0x61,0x6B,0x20,0x48,0x61,0x73,0x68,0x20,0x53,0x65,0x6C,0x66,0x2D,0x53,0x69, + 0x67,0x6E,0x65,0x64,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34,0x31,0x39,0x32,0x32, + 0x34,0x38,0x30,0x36,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x31,0x38,0x32,0x32,0x34, + 0x38,0x30,0x36,0x5A,0x30,0x81,0x8A,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,0x1E,0x30,0x1C,0x06,0x03,0x55,0x04,0x03,0x0C,0x15,0x57,0x65,0x61,0x6B, + 0x20,0x48,0x61,0x73,0x68,0x20,0x53,0x65,0x6C,0x66,0x2D,0x53,0x69,0x67,0x6E,0x65, + 0x64,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,0xDA,0x33,0x53,0x55,0x87,0xAF,0x5C,0xCA,0x77,0x5F,0x83,0x0C,0x9E,0xAB, + 0x4F,0xF8,0xBD,0xB9,0x88,0x7E,0x2A,0xE7,0x5A,0x04,0x2B,0xDD,0x93,0x4B,0x74,0x3F, + 0x69,0x04,0xCE,0x82,0x50,0x37,0x5D,0xD5,0x80,0x1D,0x3C,0x37,0x22,0x5A,0xC6,0x86, + 0x50,0xA2,0x00,0xBA,0xB6,0x52,0x77,0x77,0xA7,0xC7,0xA7,0xD6,0x2C,0x54,0x51,0xE2, + 0xF9,0x1E,0x93,0x85,0x56,0xE6,0x2B,0xAC,0xBD,0x5A,0x62,0x46,0x03,0x77,0xDC,0xDD, + 0xB8,0xE3,0x0C,0x65,0x84,0x34,0xB3,0xB5,0x63,0xCF,0x72,0xEE,0x72,0x19,0xE0,0x64, + 0x39,0x13,0xF4,0xB8,0x12,0x81,0xCC,0xBD,0x9E,0x31,0x45,0x3B,0x10,0x93,0x3B,0xB7, + 0x4D,0x79,0x03,0xCD,0x97,0xC7,0x88,0x59,0x9D,0x18,0xD7,0x76,0x77,0xB4,0x2F,0x17, + 0x32,0xC5,0xE4,0x44,0x3D,0xD6,0xA5,0xEC,0x5B,0xF4,0xF3,0x81,0xFC,0xF8,0xBC,0x57, + 0x3B,0x0D,0xCE,0x5B,0x00,0x06,0xDA,0x73,0x6D,0xC5,0x24,0x20,0x58,0xEB,0xAA,0xD1, + 0x4C,0x1E,0xD6,0xD6,0x02,0x33,0xE7,0x82,0x00,0xB3,0x41,0x63,0xA0,0x6C,0xBE,0x9E, + 0x37,0x8B,0x1C,0x0C,0x0E,0x41,0xAF,0x70,0xA7,0xAE,0xB9,0x28,0x6F,0xE2,0xAF,0x70, + 0xBD,0xEA,0xA8,0xCE,0x55,0x21,0x8C,0xBE,0xAE,0xCF,0x4E,0xF8,0x7E,0x0F,0x19,0x41, + 0xD9,0x54,0x9C,0xE8,0xEB,0x8C,0x15,0x98,0x66,0x03,0xE2,0x22,0x87,0xDD,0x04,0x19, + 0x35,0xC5,0xD1,0x16,0x83,0x6B,0x02,0x2E,0xA7,0xE9,0x86,0x0F,0x88,0xEA,0xFD,0x81, + 0xB5,0x2F,0xB8,0x21,0x3B,0xB8,0xF5,0xE5,0xFD,0x89,0xAB,0x42,0x86,0x53,0x47,0x21, + 0xAC,0xDD,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98,0x30,0x81,0x95,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,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,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,0x12,0xDA,0xB7, + 0xA0,0xFB,0xA5,0xD7,0x58,0x5B,0xE5,0x16,0x90,0x31,0xB9,0x5F,0xFE,0x41,0xA3,0xCF, + 0xD8,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x12,0xDA, + 0xB7,0xA0,0xFB,0xA5,0xD7,0x58,0x5B,0xE5,0x16,0x90,0x31,0xB9,0x5F,0xFE,0x41,0xA3, + 0xCF,0xD8,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, + 0x00,0x03,0x82,0x01,0x01,0x00,0x23,0x16,0x15,0x5C,0xE8,0xA7,0x6F,0x5E,0x54,0x46, + 0xC5,0x26,0xC8,0x23,0xD8,0x74,0xB4,0x6E,0x7A,0xAD,0xBC,0x07,0x44,0xED,0x86,0x6B, + 0x48,0xAE,0x06,0xAC,0xA6,0x14,0x24,0x16,0x1D,0x36,0x08,0x02,0x96,0x0A,0x17,0x92, + 0x3C,0x7F,0xFB,0x0D,0x87,0xDA,0xB3,0xD3,0x3D,0x3F,0x3B,0x2B,0x18,0xA4,0x46,0x6C, + 0xD8,0xBA,0xAC,0xED,0x4A,0x59,0xEC,0xB6,0xEC,0x7E,0xAA,0x20,0xD5,0x4B,0x87,0xE3, + 0x39,0x31,0x70,0x87,0xE2,0x6C,0xFE,0xE7,0x1E,0xED,0xF5,0xFB,0x0B,0xEE,0x90,0x79, + 0x3D,0x29,0x08,0xA5,0xDC,0x24,0xD9,0x65,0x7D,0x7E,0xCD,0x5D,0x35,0x44,0x58,0xDE, + 0x15,0x23,0xA5,0x00,0xD4,0x8F,0x51,0xEC,0x71,0xE6,0xFA,0xE1,0xB1,0xD4,0xBD,0x43, + 0xF6,0x72,0xCE,0x7A,0x35,0x3D,0xD6,0xBF,0x9F,0x03,0xDA,0x10,0x74,0xA8,0xF0,0xC8, + 0x9A,0xB4,0xF4,0xC4,0x62,0x84,0x20,0xCC,0x66,0xD7,0x73,0xD4,0xFA,0xDA,0x3F,0xF2, + 0x3C,0xBB,0xB1,0x99,0xF8,0x0E,0x5E,0x01,0x77,0xEC,0xE2,0x40,0x19,0x7E,0x27,0x12, + 0xEF,0xE7,0x3C,0x17,0x82,0xC6,0x87,0xD3,0x55,0x08,0x03,0x78,0x54,0xF8,0x23,0x36, + 0xDB,0x96,0xE4,0xA6,0x97,0xDC,0xF4,0xEE,0xC5,0xEA,0x5C,0xBF,0xAC,0x36,0x18,0x50, + 0xB1,0xD9,0xBE,0xAF,0x99,0xB1,0xCC,0x1B,0x93,0xAD,0x09,0x2F,0x8C,0x0B,0x08,0x73, + 0x28,0xD6,0xE6,0xC2,0xD4,0x7C,0xF6,0xE3,0x1C,0xA3,0xCE,0x32,0xD0,0xFD,0x66,0xF3, + 0xF9,0x0E,0x01,0x32,0x27,0x04,0x90,0x68,0x34,0x9B,0x2E,0xC5,0x75,0xA9,0x9F,0x08, + 0x43,0x09,0xF6,0xA9,0x54,0x4E, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Strong Crypto Self-Signed */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Strong Crypto Self-Signed */ +uint8_t _testSHA2SelfSigned[] = { + 0x30,0x82,0x04,0x3A,0x30,0x82,0x03,0x22,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xAF,0x83,0x70,0xCF,0x93,0x34,0xC5,0x8E,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x8E,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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19,0x53, + 0x74,0x72,0x6F,0x6E,0x67,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x20,0x53,0x65,0x6C, + 0x66,0x2D,0x53,0x69,0x67,0x6E,0x65,0x64,0x30,0x1E,0x17,0x0D,0x31,0x39,0x30,0x34, + 0x31,0x39,0x32,0x32,0x35,0x30,0x30,0x35,0x5A,0x17,0x0D,0x32,0x30,0x30,0x34,0x31, + 0x38,0x32,0x32,0x35,0x30,0x30,0x35,0x5A,0x30,0x81,0x8E,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,0x22,0x30,0x20,0x06,0x03,0x55,0x04,0x03,0x0C,0x19, + 0x53,0x74,0x72,0x6F,0x6E,0x67,0x20,0x43,0x72,0x79,0x70,0x74,0x6F,0x20,0x53,0x65, + 0x6C,0x66,0x2D,0x53,0x69,0x67,0x6E,0x65,0x64,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,0x92,0x79,0x5C,0x32,0x3B,0x2F, + 0x9D,0xC1,0xF0,0xE1,0xD6,0x52,0x69,0x8E,0xE7,0x5A,0x05,0xDB,0xE4,0x7F,0x2D,0x3E, + 0xA6,0xD1,0xAA,0x7A,0x7B,0x28,0xB8,0xDF,0x25,0x73,0x4C,0x2F,0xA8,0x45,0x69,0x22, + 0xF7,0x08,0x45,0x85,0x2F,0x2B,0xED,0x72,0x25,0x5E,0x17,0x8B,0xAA,0x28,0xF8,0xCA, + 0xE6,0x7E,0x6A,0xF9,0x6C,0x3A,0x5B,0x32,0x04,0xAA,0x8B,0xC2,0x36,0xD9,0x6D,0x74, + 0x2B,0x62,0xFC,0x29,0x03,0x65,0x5D,0x46,0x47,0x69,0xFD,0x4B,0x66,0x43,0x7C,0xA2, + 0xA1,0xD9,0xB0,0x72,0xFC,0x9B,0xB2,0x40,0xD1,0x4A,0x2C,0x07,0x36,0xBE,0x9D,0xD5, + 0x88,0xA1,0xF4,0xFC,0x1D,0x2F,0xEC,0xDD,0xE5,0x9B,0x7D,0x58,0xD5,0x9A,0x1F,0x5F, + 0x08,0x3F,0x60,0x57,0x82,0xCB,0xF6,0x0C,0x54,0x30,0x04,0x5F,0x9E,0x7F,0xDA,0xB1, + 0x71,0x23,0x7E,0x3C,0xA8,0xFA,0xB2,0x0E,0xA5,0x3D,0x65,0xD1,0xEF,0x68,0xD4,0x57, + 0xF8,0x0B,0xF4,0x07,0x0D,0x87,0xA1,0xEA,0x4F,0xB9,0xA1,0x21,0x2A,0x22,0x44,0x44, + 0xA7,0xB2,0x68,0x9A,0x5F,0x5A,0x39,0x6F,0x5E,0x32,0x9B,0x16,0x59,0xF3,0xD8,0xEE, + 0xF3,0x04,0x8D,0x4F,0x4E,0xA4,0x7D,0xE7,0x49,0x06,0xD7,0xFB,0x3C,0x94,0xED,0x34, + 0xDC,0xEC,0xCE,0x1F,0xF7,0x0F,0xD3,0x87,0x10,0x72,0x5B,0xA2,0x33,0x6A,0xE3,0x4A, + 0x15,0xC7,0x8D,0x33,0xEC,0xA5,0xA3,0x6C,0xC3,0xC7,0x11,0x07,0xC9,0xE5,0x94,0xB1, + 0x72,0xA1,0xCB,0x79,0x54,0xCE,0xC9,0x45,0x7E,0xB5,0x18,0x08,0x64,0xD5,0x3E,0x62, + 0xB1,0xCB,0xB6,0xB7,0x53,0xC8,0x7A,0x6D,0xF7,0x19,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x81,0x98,0x30,0x81,0x95,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,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,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,0xBB,0x55,0xBE,0x4B,0x36,0x5E,0x82,0x92,0xDC,0xC0,0xC1, + 0x08,0x11,0x94,0x43,0xB1,0x03,0x50,0x0A,0xCF,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0xBB,0x55,0xBE,0x4B,0x36,0x5E,0x82,0x92,0xDC,0xC0, + 0xC1,0x08,0x11,0x94,0x43,0xB1,0x03,0x50,0x0A,0xCF,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x24,0xC9, + 0x7B,0x5A,0xA7,0x0F,0x2B,0xE3,0x6E,0x08,0x3A,0x42,0xB0,0xB2,0x35,0xB1,0x81,0x7D, + 0xE2,0xF0,0xF9,0x3D,0x1E,0xB1,0x39,0x89,0xA7,0xD1,0x09,0x5B,0xCA,0xD0,0x54,0x5A, + 0xCA,0x01,0x3E,0x35,0x77,0x91,0xE1,0x78,0x80,0xE5,0xC1,0x08,0x32,0x66,0x44,0xC3, + 0xCB,0x2F,0x5C,0xFE,0x15,0x1C,0xFE,0xD7,0x03,0x58,0xAF,0x77,0x5C,0xF2,0x88,0xB2, + 0xE1,0x37,0x31,0x5E,0x49,0x04,0xA9,0x82,0x0A,0x58,0xBE,0x6F,0xC0,0x2E,0xD3,0x5B, + 0x8C,0x18,0x89,0x4C,0x03,0x80,0x0D,0xE6,0x84,0x15,0x8C,0xEA,0xD1,0xE1,0x83,0x74, + 0x90,0x31,0x24,0xB6,0x1C,0x09,0x90,0x79,0xF5,0x2D,0x44,0x2D,0x67,0x3F,0x29,0x8B, + 0x14,0x28,0x3D,0x56,0x19,0x0B,0x80,0xDB,0xA5,0xEE,0x7C,0x39,0xEE,0x81,0xD2,0x03, + 0xE1,0x7A,0xA9,0x97,0x50,0x49,0xEF,0xFC,0x1E,0xFA,0xE1,0xAF,0xAE,0xEA,0x02,0x0E, + 0xE5,0xB2,0xBE,0xC9,0x19,0xAA,0xB4,0xD2,0xDC,0x6E,0x78,0x96,0x99,0x87,0xDA,0x40, + 0x84,0x7C,0xDA,0x09,0x17,0x5E,0xD7,0xE8,0x63,0x51,0x23,0x44,0xCC,0x31,0x41,0x08, + 0x7C,0x29,0x2D,0xF2,0x0E,0x5D,0xBA,0x12,0xAE,0x51,0x2F,0xD8,0x8E,0x78,0xDA,0x7C, + 0x69,0x6E,0x4D,0x38,0x21,0xD6,0xC2,0xDA,0x37,0xAD,0xF5,0x25,0x24,0x5C,0x1A,0x7F, + 0x08,0x8A,0x0A,0xF3,0xAD,0x56,0x8F,0x0A,0x0A,0xA1,0xEA,0xDF,0xC4,0xD7,0xE7,0x2C, + 0xD8,0x6A,0xD7,0xE7,0xDE,0x7C,0xD0,0xBC,0x49,0xEF,0xCA,0x24,0xBC,0x52,0xC1,0xEC, + 0xC1,0xDA,0x7C,0xE4,0x3C,0xE5,0x15,0xF0,0x28,0x40,0x6D,0x69,0x40,0xB9, +}; + +#endif /* _TRUSTTESTS_EVALUATION_SIG_ALG_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.h b/tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.h new file mode 100644 index 00000000..00311bcd --- /dev/null +++ b/tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.h @@ -0,0 +1,50 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_TESTCASE_H_ +#define _TRUSTTESTS_EVALUATION_TESTCASE_H_ + +#import +#include +#include "../TrustEvaluationTestHelpers.h" + +@interface TrustEvaluationTestCase : XCTestCase +- (id _Nullable)addTrustSettingsForCert:(SecCertificateRef _Nonnull)cert trustSettings:(id _Nonnull)trustSettings; // returns a persistent ref for call to removeTrustSettings, takes a dictionary or array of trust settings +- (id _Nullable)addTrustSettingsForCert:(SecCertificateRef _Nonnull)cert; // returns a persistent ref for call to removeTrustSettings +- (void)removeTrustSettingsForCert:(SecCertificateRef _Nonnull)cert persistentRef:(id _Nullable)persistentRef; +- (void)setTestRootAsSystem:(const uint8_t* _Nonnull)sha256hash; // this is expected to be a 32-byte array +- (void)removeTestRootAsSystem; + +// ported from regressionBase +- (void)runCertificateTestForDirectory:(SecPolicyRef _Nonnull)policy subDirectory:(NSString * _Nonnull)resourceSubDirectory verifyDate:(NSDate* _Nonnull)date; +@end + +/* Use this interface to get a SecCertificateRef that has the same CFTypeID + * as used by the Security framework */ +CF_RETURNS_RETAINED _Nullable +SecCertificateRef SecFrameworkCertificateCreate(const uint8_t * _Nonnull der_bytes, CFIndex der_length); +CF_RETURNS_RETAINED _Nullable +SecCertificateRef SecFrameworkCertificateCreateFromTestCert(SecCertificateRef _Nonnull cert); + +#endif /* _TRUSTTESTS_EVALUATION_TESTCASE_H_ */ diff --git a/tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.m b/tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.m new file mode 100644 index 00000000..72596ab5 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/TrustEvaluationTestCase.m @@ -0,0 +1,330 @@ +/* + * 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 +#include "OSX/trustd/trustd_spi.h" +#include +#include +#include +#include +#include +#include "OSX/utilities/SecCFWrappers.h" +#include +#include + +#if TARGET_OS_IPHONE +#include +#else +#define kSystemLoginKeychainPath "/Library/Keychains/System.keychain" +#include +#endif + +#import "../TestMacroConversions.h" +#import "TrustEvaluationTestCase.h" + +@implementation TrustEvaluationTestCase + +static int current_dir = -1; +static char *home_var = NULL; + +/* Build in trustd functionality to the tests */ ++ (void) setUp { + /* Set up TMP directory for trustd's files */ + int ok = 0; + NSError* error = nil; + NSString* pid = [NSString stringWithFormat: @"tst-%d", [[NSProcessInfo processInfo] processIdentifier]]; + NSURL* tmpDirURL = [[NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES] URLByAppendingPathComponent:pid]; + ok = (bool)tmpDirURL; + + if (current_dir == -1 && home_var == NULL) { + ok = ok && [[NSFileManager defaultManager] createDirectoryAtURL:tmpDirURL + withIntermediateDirectories:NO + attributes:NULL + error:&error]; + + NSURL* libraryURL = [tmpDirURL URLByAppendingPathComponent:@"Library"]; + NSURL* preferencesURL = [tmpDirURL URLByAppendingPathComponent:@"Preferences"]; + + ok = (ok && (current_dir = open(".", O_RDONLY) >= 0) + && (chdir([tmpDirURL fileSystemRepresentation]) >= 0) + && (setenv("HOME", [tmpDirURL fileSystemRepresentation], 1) >= 0) + && (bool)(home_var = getenv("HOME"))); + + ok = ok && [[NSFileManager defaultManager] createDirectoryAtURL:libraryURL + withIntermediateDirectories:NO + attributes:NULL + error:&error]; + + ok = ok && [[NSFileManager defaultManager] createDirectoryAtURL:preferencesURL + withIntermediateDirectories:NO + attributes:NULL + error:&error]; + } + + if (ok > 0) { + /* Be trustd */ + trustd_init((__bridge CFURLRef) tmpDirURL); + } +} + +- (id)addTrustSettingsForCert:(SecCertificateRef)cert trustSettings:(id)trustSettings +{ +#if TARGET_OS_IPHONE + SecTrustStoreRef defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser); + OSStatus status = SecTrustStoreSetTrustSettings(defaultStore, cert, (__bridge CFTypeRef)trustSettings); + XCTAssert(errSecSuccess == status, "failed to set trust settings: %d", (int)status); + return nil; +#else + /* Since we're putting trust settings in the admin domain, + * we need to add the certs to the system keychain. */ + SecKeychainRef kcRef = NULL; + CFArrayRef certRef = NULL; + NSDictionary *attrs = nil; + + SecKeychainOpen(kSystemLoginKeychainPath, &kcRef); + if (!kcRef) { + return nil; + } + + /* Since we're interacting with the keychain we need a framework cert */ + SecCertificateRef frameworkCert = SecFrameworkCertificateCreateFromTestCert(cert); + attrs = @{(__bridge NSString*)kSecValueRef: (__bridge id)frameworkCert, + (__bridge NSString*)kSecUseKeychain: (__bridge id)kcRef, + (__bridge NSString*)kSecReturnPersistentRef: @YES}; + OSStatus status = SecItemAdd((CFDictionaryRef)attrs, (void *)&certRef); + XCTAssert(errSecSuccess == status, "failed to add cert to keychain: %d", status); + id result = ((__bridge NSArray*)certRef)[0]; + CFReleaseNull(kcRef); + CFReleaseNull(certRef); + + status = SecTrustSettingsSetTrustSettings(frameworkCert, kSecTrustSettingsDomainAdmin, + (__bridge CFTypeRef)trustSettings); + XCTAssert(errSecSuccess == status, "failed to set trust settings: %d", status); + usleep(20000); + + CFReleaseNull(frameworkCert); + return result; +#endif +} + + +- (id)addTrustSettingsForCert:(SecCertificateRef)cert +{ + NSDictionary *trustSettings = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustRoot)}; + Boolean isSelfSigned = false; + XCTAssert(errSecSuccess == SecCertificateIsSelfSigned(cert, &isSelfSigned)); + if (!isSelfSigned) { + trustSettings = @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultTrustAsRoot)}; + } + + return [self addTrustSettingsForCert:cert trustSettings:trustSettings]; +} + +- (void)removeTrustSettingsForCert:(SecCertificateRef)cert persistentRef:(id)persistentRef +{ +#if TARGET_OS_IPHONE + SecTrustStoreRef defaultStore = SecTrustStoreForDomain(kSecTrustStoreDomainUser); + XCTAssert(errSecSuccess == SecTrustStoreRemoveCertificate(defaultStore, cert), "failed to remove trust settings"); +#else + SecCertificateRef frameworkCert = SecFrameworkCertificateCreateFromTestCert(cert); + XCTAssert(errSecSuccess == SecTrustSettingsRemoveTrustSettings(frameworkCert, kSecTrustSettingsDomainAdmin), + "failed to remove trust settings"); + XCTAssert(errSecSuccess == SecItemDelete((CFDictionaryRef)@{ (__bridge NSString*)kSecValuePersistentRef: persistentRef}), + "failed to remove item from keychain"); + CFReleaseNull(frameworkCert); +#endif +} + +const CFStringRef kSecurityPreferencesDomain = CFSTR("com.apple.security"); +const CFStringRef kTestSystemRootKey = CFSTR("TestSystemRoot"); + +- (void)setTestRootAsSystem:(const uint8_t *)sha256hash +{ + NSData *rootHash = [NSData dataWithBytes:sha256hash length:32]; + CFPreferencesSetAppValue(kTestSystemRootKey, (__bridge CFDataRef)rootHash, kSecurityPreferencesDomain); + CFPreferencesAppSynchronize(kSecurityPreferencesDomain); +} + +- (void)removeTestRootAsSystem +{ + CFPreferencesSetAppValue(kTestSystemRootKey, NULL, kSecurityPreferencesDomain); + CFPreferencesAppSynchronize(kSecurityPreferencesDomain); +} + +/* MARK: run test methods from regressionBase */ +- (void)runOneLeafTest:(SecPolicyRef)policy + anchors:(NSArray *)anchors + intermediates:(NSArray *)intermediates + leafPath:(NSString *)path + expectedResult:(bool)expectedResult + expectations:(NSObject *)expectations + verifyDate:(NSDate *)date +{ + NSString* fileName = [path lastPathComponent]; + NSString *reason = NULL; + SecTrustRef trustRef = NULL; + NSMutableArray* certArray = NULL; + SecCertificateRef certRef = NULL; + CFErrorRef error = NULL; + + if (expectations) { + if ([expectations isKindOfClass: [NSString class]]) { + reason = (NSString *)expectations; + } else if ([expectations isKindOfClass: [NSDictionary class]]) { + NSDictionary *dict = (NSDictionary *)expectations; + NSObject *value = [dict valueForKey:@"valid"]; + if (value) { + if ([value isKindOfClass: [NSNumber class]]) { + expectedResult = [(NSNumber *)value boolValue]; + } else { + NSLog(@"Unexpected valid value %@ in dict for key %@", value, fileName); + } + } + value = [dict valueForKey:@"reason"]; + if (value) { + if ([value isKindOfClass: [NSString class]]) { + reason = (NSString *)value; + } else { + NSLog(@"Unexpected reason value %@ in dict for key %@", value, fileName); + } + } + } else if ([expectations isKindOfClass: [NSNumber class]]) { + expectedResult = [(NSNumber *)expectations boolValue]; + } else { + NSLog(@"Unexpected class %@ value %@ for key %@", [expectations class], expectations, fileName); + } + } + + certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); + if (!certRef) { + if (reason) { + fail("TODO test: %@ unable to create certificate, %@", fileName, reason); + } else { + fail("PARSE %@ unable to create certificate", fileName); + } + goto exit; + } + + certArray = [NSMutableArray arrayWithArray:intermediates]; + [certArray insertObject:(__bridge id)certRef atIndex:0]; //The certificate to be verified must be the first in the array. + + OSStatus err; + err = SecTrustCreateWithCertificates((__bridge CFTypeRef _Nonnull)(certArray), policy, &trustRef); + if (err) { + ok_status(err, "SecTrustCreateWithCertificates"); + goto exit; + } + if ([anchors count]) + SecTrustSetAnchorCertificates(trustRef, (CFArrayRef)anchors); + + SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)date); + + BOOL isValid = SecTrustEvaluateWithError(trustRef, &error); + if (reason) { + XCTAssertFalse(isValid == expectedResult, "TODO test: %@%@", fileName, error); + } else { + ok(isValid == expectedResult, "%s %@%@", expectedResult ? "REGRESSION" : "SECURITY", fileName, error); + } + +exit: + CFReleaseSafe(trustRef); + CFReleaseSafe(certRef); + CFReleaseSafe(error); +} + +- (void)runCertificateTestFor:(SecPolicyRef)policy + anchors:(NSArray *)anchors + intermediates:(NSArray *)intermediates + leafPaths:(NSMutableArray *)leafPaths + expectations:(NSDictionary *)expect + verifyDate:(NSDate *)date +{ + /* Sort the tests by name. */ + [leafPaths sortUsingSelector:@selector(compare:)]; + + for (NSString* path in leafPaths) { + NSString* fileName = [path lastPathComponent]; + [self runOneLeafTest:policy anchors:anchors intermediates:intermediates leafPath:path expectedResult:![fileName hasPrefix:@"Invalid"] expectations:[expect objectForKey:fileName] verifyDate:date]; + } +} + + +- (void)runCertificateTestForDirectory:(SecPolicyRef)policy subDirectory:(NSString *)resourceSubDirectory verifyDate:(NSDate*)date +{ + NSMutableArray* allRoots = [NSMutableArray array]; + NSMutableArray* allCAs = [NSMutableArray array]; + NSMutableArray* certTests = [NSMutableArray array]; + NSDictionary* expect = NULL; + + NSURL* filesDirectory = [[[NSBundle bundleForClass:[self class]] resourceURL] URLByAppendingPathComponent:resourceSubDirectory]; + for (NSURL* fileURL in [[NSFileManager defaultManager] contentsOfDirectoryAtURL:filesDirectory includingPropertiesForKeys:[NSArray array] options:NSDirectoryEnumerationSkipsSubdirectoryDescendants error:nil]) { + NSString* path = [fileURL path]; + if ([path hasSuffix:@"Cert.crt"]) { + SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); + [allCAs addObject:(__bridge id)certRef]; + CFReleaseNull(certRef); + } else if ([path hasSuffix:@"RootCertificate.crt"]) { + SecCertificateRef certRef = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); + [allRoots addObject:(__bridge id)certRef]; + CFReleaseNull(certRef); + } else if ([path hasSuffix:@".crt"]) { + [certTests addObject:path]; + } else if ([path hasSuffix:@".plist"]) { + if (expect) { + fail("Multiple .plist files found in %@", filesDirectory); + } else { + expect = [NSDictionary dictionaryWithContentsOfFile:path]; + } + } + } + + [self runCertificateTestFor:policy anchors:allRoots intermediates:allCAs leafPaths:certTests expectations:expect verifyDate:date]; +} + +@end + +typedef SecCertificateRef (*create_f)(CFAllocatorRef allocator, + const UInt8 *der_bytes, CFIndex der_length); +CF_RETURNS_RETAINED _Nullable +SecCertificateRef SecFrameworkCertificateCreate(const uint8_t * _Nonnull der_bytes, CFIndex der_length) { + static create_f FrameworkCertCreateFunctionPtr = NULL; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + void *framework = dlopen("/System/Library/Frameworks/Security.framework/Security", RTLD_LAZY); + if (framework) { + FrameworkCertCreateFunctionPtr = dlsym(framework, "SecCertificateCreateWithBytes"); + } + }); + + if (FrameworkCertCreateFunctionPtr) { + return FrameworkCertCreateFunctionPtr(NULL, der_bytes, der_length); + } else { + NSLog(@"WARNING: not using Security framework certificate"); + return SecCertificateCreateWithBytes(NULL, der_bytes, der_length); + } +} + +SecCertificateRef SecFrameworkCertificateCreateFromTestCert(SecCertificateRef cert) { + return SecFrameworkCertificateCreate(SecCertificateGetBytePtr(cert), SecCertificateGetLength(cert)); +} diff --git a/tests/TrustTests/EvaluationTests/VerifyDateTests.m b/tests/TrustTests/EvaluationTests/VerifyDateTests.m new file mode 100644 index 00000000..d102547e --- /dev/null +++ b/tests/TrustTests/EvaluationTests/VerifyDateTests.m @@ -0,0 +1,412 @@ +/* + * 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 "OSX/utilities/SecCFWrappers.h" +#include +#include +#include +#include + +#import "TrustEvaluationTestCase.h" +#include "../TestMacroConversions.h" +#include "VerifyDateTests_data.h" + +@interface VerifyDateTests : TrustEvaluationTestCase +@end + +@implementation VerifyDateTests +/* Test long-lived cert chain that expires in 9999 */ + +static SecTrustRef trust = nil; + ++ (void)setUp { + [super setUp]; + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, longleaf, sizeof(longleaf)); + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, longroot, sizeof(longroot)); + NSArray *anchors = @[(__bridge id)root]; + + SecTrustCreateWithCertificates(leaf, NULL, &trust); + SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors); + CFReleaseNull(leaf); + CFReleaseNull(root); +} + ++ (void)tearDown { + CFReleaseNull(trust); +} + +- (void)testPriorToNotBefore { + CFDateRef date = NULL; + /* September 4, 2013 (prior to "notBefore" date of 2 April 2014, should fail) */ + isnt(date = CFDateCreate(NULL, 400000000), NULL, "failed to create date"); + ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 23 Sep 2013"); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust on 23 Sep 2013 and expect failure"); + CFReleaseNull(date); +} + +- (void)testRecentWithinValidity { + CFDateRef date = NULL; + /* January 17, 2016 (recent date within validity period, should succeed) */ + isnt(date = CFDateCreate(NULL, 474747474), NULL, "failed to create date"); + ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 17 Jan 2016"); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust on 17 Jan 2016 and expect success"); + CFReleaseNull(date); +} + +- (void)testFarFutureWithinValidity { + CFDateRef date = NULL; + /* December 20, 9999 (far-future date within validity period, should succeed) */ + isnt(date = CFDateCreate(NULL, 252423000000), NULL, "failed to create date"); + ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 20 Dec 9999"); + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "evaluate trust on 20 Dec 9999 and expect success"); + CFReleaseNull(date); +} + +- (void)testAfterNotAfter { + CFDateRef date = NULL; + /* January 12, 10000 (after the "notAfter" date of 31 Dec 9999, should fail) */ + isnt(date = CFDateCreate(NULL, 252425000000), NULL, "failed to create date"); + ok_status(SecTrustSetVerifyDate(trust, date), "set trust date to 12 Jan 10000"); + XCTAssertFalse(SecTrustEvaluateWithError(trust, NULL), "evaluate trust on 12 Jan 10000 and expect failure"); + CFReleaseNull(date); +} + +@end + +@interface ValidityPeriodRestrictionTests : TrustEvaluationTestCase +@end + +@implementation ValidityPeriodRestrictionTests +// Note that the dates described in the test names are the issuance date not the VerifyDate + +- (BOOL)runTrustEvaluation:(NSArray *)certs anchors:(NSArray *)anchors error:(NSError **)error +{ + SecPolicyRef policy = SecPolicyCreateSSL(true, CFSTR("example.com")); + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:590000000.0]; // September 12, 2019 at 9:53:20 AM PDT + SecTrustRef trustRef = NULL; + BOOL result = NO; + CFErrorRef cferror = NULL; + + require_noerr(SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, policy, &trustRef), errOut); + require_noerr(SecTrustSetVerifyDate(trustRef, (__bridge CFDateRef)date), errOut); + + if (anchors) { + require_noerr(SecTrustSetAnchorCertificates(trustRef, (__bridge CFArrayRef)anchors), errOut); + } + + result = SecTrustEvaluateWithError(trustRef, &cferror); + if (error && cferror) { + *error = (__bridge NSError*)cferror; + } + +errOut: + CFReleaseNull(policy); + CFReleaseNull(trustRef); + CFReleaseNull(cferror); + return result; +} + +- (void)testSystemTrust_MoreThan5Years +{ + [self setTestRootAsSystem:_testValidityPeriodsRootHash]; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_66Months, sizeof(_testLeaf_66Months)); + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "system-trusted 66 month cert succeeded"); + + [self removeTestRootAsSystem]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testSystemTrust_LessThan5Years_BeforeJul2016 +{ + [self setTestRootAsSystem:_testValidityPeriodsRootHash]; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_5Years, sizeof(_testLeaf_5Years)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "system-trusted 5 year cert issued before 1 July 2016 failed: %@", error); + + [self removeTestRootAsSystem]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testSystemTrust_MoreThan39Months_AfterJul2016 +{ + [self setTestRootAsSystem:_testValidityPeriodsRootHash]; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_4Years, sizeof(_testLeaf_4Years)); + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "system-trusted 4 year cert issued after 1 July 2016 succeeded"); + + [self removeTestRootAsSystem]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testSystemTrust_LessThan39Months_BeforeMar2018 +{ + // This cert should be valid + [self setTestRootAsSystem:_testValidityPeriodsRootHash]; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_39Months, sizeof(_testLeaf_39Months)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "system-trusted 39 month cert issued before 1 Mar 2018 failed: %@", error); + + [self removeTestRootAsSystem]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testSystemTrust_MoreThan825Days_AfterMar2018 +{ + [self setTestRootAsSystem:_testValidityPeriodsRootHash]; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "system-trusted 3 year cert issued after 1 Mar 2018 succeeded"); + + [self removeTestRootAsSystem]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testSystemTrust_LessThan825Days_AfterMar2018 +{ + [self setTestRootAsSystem:_testValidityPeriodsRootHash]; + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_825Days, sizeof(_testLeaf_825Days)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "system-trusted 825 day cert issued after 1 Mar 2018 failed: %@", error); + + [self removeTestRootAsSystem]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testAppTrustRoot_MoreThan825Days_AfterJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "app-trusted (root) 3 year cert issued after 1 Jul 2019 succeeded"); + + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testAppTrustRoot_MoreThan825Days_BeforeJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_66Months, sizeof(_testLeaf_66Months)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "app-trusted (root) 66 month cert issued before 1 Jul 2019 failed: %@", error); + + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testAppTrustRoot_LessThan825Days_AfterJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_825Days, sizeof(_testLeaf_825Days)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "app-trusted (root) 825 day cert issued after 1 Jul 2019 failed: %@", error); + + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testAppTrustLeaf_MoreThan825Days_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)leaf] error:&error], + "app-trusted 3 year cert issued after 1 Jul 2019 succeeded"); + + CFReleaseNull(leaf); +} + +- (void)testAppTrustLeaf_MoreThan825Days_BeforeJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_66Months, sizeof(_testLeaf_66Months)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)leaf] error:&error], + "app-trusted 66 month cert issued before 1 Jul 2019 failed: %@", error); + + CFReleaseNull(leaf); +} + +- (void)testAppTrustLeaf_LessThan825Days_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_825Days, sizeof(_testLeaf_825Days)); + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)leaf] error:&error], + "app-trusted 825 day cert issued after 1 Jul 2019 failed: %@", error); + + CFReleaseNull(leaf); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have trust settings +- (void)testUserTrustRoot_MoreThan825Days_AfterJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + id persistentRef = [self addTrustSettingsForCert:root]; + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:certs anchors:nil error:&error], + "user-trusted (root) 3 year cert issued after 1 Jul 2019 succeeded"); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testUserTrustRoot_MoreThan825Days_BeforeJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_66Months, sizeof(_testLeaf_66Months)); + id persistentRef = [self addTrustSettingsForCert:root]; + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], + "user-trusted (root) 66 month cert issued before 1 Jul 2019 failed: %@", error); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testUserTrustRoot_LessThan825Days_AfterJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_825Days, sizeof(_testLeaf_825Days)); + id persistentRef = [self addTrustSettingsForCert:root]; + NSArray *certs = @[(__bridge id)leaf, (__bridge id)root]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:certs anchors:nil error:&error], + "app-trusted (root) 825 day cert issued after 1 Jul 2019 failed: %@", error); + + [self removeTrustSettingsForCert:root persistentRef:persistentRef]; + CFReleaseNull(root); + CFReleaseNull(leaf); +} + +- (void)testUserTrustLeaf_MoreThan825Days_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + id persistentRef = [self addTrustSettingsForCert:leaf]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], + "user-trusted leaf 3 year cert issued after 1 Jul 2019 failed: %@", error); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} + +- (void)testUserTrustLeaf_MoreThan825Days_BeforeJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_66Months, sizeof(_testLeaf_66Months)); + id persistentRef = [self addTrustSettingsForCert:leaf]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], + "user-trusted leaf 66 month cert issued before 1 Jul 2019 failed: %@", error); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} + +- (void)testUserTrustLeaf_LessThan825Days_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_825Days, sizeof(_testLeaf_825Days)); + id persistentRef = [self addTrustSettingsForCert:leaf]; + + NSError *error = nil; + XCTAssertTrue([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], + "user-trusted leaf 825 day cert issued after 1 Jul 2019 failed: %@", error); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} + +- (void)testUserDistrustLeaf_MoreThan825Days_AfterJul2019 +{ + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + id persistentRef = [self addTrustSettingsForCert:leaf trustSettings: @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultDeny)}]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:nil error:&error], + "user-denied leaf 3 year cert issued after 1 Jul 2019 suceeded"); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); +} + +- (void)testUserUnspecifiedLeaf_MoreThan825Days_AfterJul2019 +{ + SecCertificateRef root = SecCertificateCreateWithBytes(NULL, _testValidityPeriodsRoot, sizeof(_testValidityPeriodsRoot)); + SecCertificateRef leaf = SecCertificateCreateWithBytes(NULL, _testLeaf_3Years, sizeof(_testLeaf_3Years)); + id persistentRef = [self addTrustSettingsForCert:leaf trustSettings: @{ (__bridge NSString*)kSecTrustSettingsResult: @(kSecTrustSettingsResultUnspecified)}]; + + NSError *error = nil; + XCTAssertFalse([self runTrustEvaluation:@[(__bridge id)leaf] anchors:@[(__bridge id)root] error:&error], + "user-unspecified trust leaf 3 year cert issued after 1 Jul 2019 succeeded"); + + [self removeTrustSettingsForCert:leaf persistentRef:persistentRef]; + CFReleaseNull(leaf); + CFReleaseNull(root); +} +#endif // !TARGET_OS_BRIDGE + +@end diff --git a/tests/TrustTests/EvaluationTests/VerifyDateTests_data.h b/tests/TrustTests/EvaluationTests/VerifyDateTests_data.h new file mode 100644 index 00000000..3948974f --- /dev/null +++ b/tests/TrustTests/EvaluationTests/VerifyDateTests_data.h @@ -0,0 +1,828 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_VERIFY_DATE_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_VERIFY_DATE_TESTS_H_ + +/* SHA1 Fingerprint=62:45:08:9B:4A:CC:45:58:8B:0F:A1:E8:E3:AE:61:5B:4B:FF:80:93 */ +/* subject:/C=US/ST=CA/O=Apple Inc./OU=ETS/CN=Escrow Service Key 5DBB9DF79A4272CB07F127CBAFFC5B9D2E7111EA68BF926199D828329535AFF1 */ +/* issuer :/serialNumber=101/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Escrow Service Root CA */ +const uint8_t longleaf[1036] = { + 0x30,0x82,0x04,0x08,0x30,0x82,0x02,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x04,0x5D, + 0xBB,0x9D,0xF7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B, + 0x05,0x00,0x30,0x79,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31, + 0x30,0x31,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,0x1F,0x30,0x1D, + 0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x45,0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65, + 0x72,0x76,0x69,0x63,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x20,0x17, + 0x0D,0x31,0x34,0x30,0x34,0x30,0x32,0x32,0x32,0x35,0x33,0x35,0x39,0x5A,0x18,0x0F, + 0x39,0x39,0x39,0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30, + 0x81,0x9B,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31, + 0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x08,0x13,0x02,0x43,0x41,0x31,0x13,0x30,0x11, + 0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63, + 0x2E,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x0B,0x13,0x03,0x45,0x54,0x53,0x31, + 0x5C,0x30,0x5A,0x06,0x03,0x55,0x04,0x03,0x13,0x53,0x45,0x73,0x63,0x72,0x6F,0x77, + 0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x20,0x4B,0x65,0x79,0x20,0x35,0x44,0x42, + 0x42,0x39,0x44,0x46,0x37,0x39,0x41,0x34,0x32,0x37,0x32,0x43,0x42,0x30,0x37,0x46, + 0x31,0x32,0x37,0x43,0x42,0x41,0x46,0x46,0x43,0x35,0x42,0x39,0x44,0x32,0x45,0x37, + 0x31,0x31,0x31,0x45,0x41,0x36,0x38,0x42,0x46,0x39,0x32,0x36,0x31,0x39,0x39,0x44, + 0x38,0x32,0x38,0x33,0x32,0x39,0x35,0x33,0x35,0x41,0x46,0x46,0x31,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,0x85,0xDE, + 0xE9,0x68,0x2D,0x62,0x22,0x91,0xEC,0x24,0x65,0x90,0x94,0x5F,0xDC,0x17,0x22,0xAC, + 0xDF,0x76,0xD7,0x2F,0x20,0xE1,0xE0,0x3A,0x8A,0xE1,0x9C,0xF0,0x45,0x35,0xBE,0xB4, + 0xA5,0xD1,0x04,0xDB,0xAA,0x26,0x30,0xC0,0xBD,0x58,0x79,0x56,0x91,0xCE,0xC4,0xF2, + 0x48,0xE0,0xB2,0xCE,0xCC,0x30,0xCF,0xFE,0x32,0x7C,0xBE,0xB6,0x75,0x40,0x94,0xBC, + 0xCC,0x66,0xBD,0x4A,0xDC,0x7A,0x56,0x8F,0x70,0x67,0x33,0xC0,0x26,0xC4,0xF0,0x85, + 0xDB,0xF1,0x0F,0x8D,0x38,0xE0,0xA9,0x1E,0x22,0xB8,0xA2,0x53,0xEC,0x1A,0xD0,0xFC, + 0xB2,0x47,0xD4,0x3C,0xCE,0xA6,0x92,0xA0,0x85,0x32,0x28,0xFF,0x52,0x01,0xE1,0x32, + 0x51,0x4B,0x50,0x1E,0x1E,0x52,0x93,0x5B,0x32,0xA0,0x7C,0xF6,0x92,0xFF,0x48,0x96, + 0x3C,0x32,0x60,0x01,0x38,0xC4,0xA1,0xEE,0x9F,0xBB,0x19,0x45,0xE2,0xCA,0xE8,0xF0, + 0x5A,0xF6,0x4A,0xB2,0x56,0x8F,0x3A,0xD2,0xF0,0xCF,0x50,0x73,0xE5,0xB7,0x6D,0xC8, + 0x1F,0x30,0x3A,0x24,0xCB,0x43,0xDF,0xDE,0x5F,0xE0,0x74,0xCD,0xDB,0xDA,0x1E,0x57, + 0xAB,0x08,0x26,0xBC,0x22,0x31,0xD7,0x2B,0xF6,0xCE,0x21,0x4A,0x31,0x2B,0x75,0x22, + 0xD5,0x4B,0xB6,0x07,0x57,0x6F,0xBC,0x2C,0xD4,0xE4,0x69,0x3D,0x90,0x0B,0x3C,0x44, + 0xFB,0x4E,0x63,0x0C,0x72,0x75,0xEC,0x5C,0x83,0x83,0x16,0x85,0xCA,0xA5,0x94,0x0E, + 0x65,0x50,0x77,0x15,0xFE,0x1A,0x11,0xAF,0x96,0x62,0x19,0xEF,0x47,0x21,0x33,0x9C, + 0x07,0x48,0x5B,0xB6,0xC6,0x18,0x5F,0x8D,0x23,0x12,0x76,0x26,0x82,0x61,0x02,0x03, + 0x01,0x00,0x01,0xA3,0x73,0x30,0x71,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,0x20,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14, + 0xE9,0x6C,0x86,0x1C,0xA8,0x51,0xA8,0xFC,0x96,0x53,0xBA,0x47,0x3D,0x75,0xAC,0x40, + 0x6C,0x98,0x90,0x92,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80, + 0x14,0x17,0xE6,0x9A,0xB2,0xDD,0x97,0x13,0x41,0x71,0xD6,0x51,0x5E,0xBF,0xC0,0x24, + 0x2E,0x92,0x2D,0x0F,0x63,0x30,0x11,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64, + 0x06,0x17,0x01,0x04,0x03,0x02,0x01,0x0A,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x4B,0x2D,0x7A,0xF7, + 0x90,0xE5,0x0F,0x9A,0xD1,0xBD,0x9F,0x71,0xFC,0x73,0xE1,0x7B,0x4C,0x0F,0xBE,0x21, + 0x9D,0x84,0x67,0x46,0x0E,0x1F,0x00,0x13,0x3C,0x86,0x92,0xFD,0x20,0x72,0x6B,0x60, + 0xE3,0xCD,0xEF,0x89,0x1A,0x20,0x7D,0xFB,0x9D,0x6A,0x36,0x05,0xD6,0x42,0xC8,0x39, + 0x15,0xF5,0x8D,0x60,0x2E,0x4E,0x71,0x12,0xE1,0x9A,0x8C,0x3F,0xDE,0x0D,0xD5,0x35, + 0x26,0xFA,0xA0,0xDB,0xDA,0xCF,0xD8,0xF4,0xAE,0x75,0x6A,0xB1,0x57,0x34,0x5A,0x03, + 0x36,0x28,0xAA,0x71,0xE2,0x09,0x7D,0x9B,0x2F,0x17,0xD6,0x9E,0x5F,0x4D,0x9B,0x3E, + 0x19,0xA9,0xC7,0xEA,0x35,0xA7,0xCB,0x03,0xA8,0x8E,0xF8,0x6E,0xAD,0xD6,0x30,0xEC, + 0x2F,0xEA,0x16,0x65,0x1C,0xCF,0x57,0x65,0xC3,0xC6,0xD0,0xD3,0x22,0xE8,0x69,0x4E, + 0x32,0xA3,0x2B,0xDE,0xDE,0xB6,0xE7,0xBA,0x6F,0x82,0x6E,0x0C,0x82,0xDF,0x82,0xB4, + 0xB5,0x42,0x59,0xD2,0xEC,0x8C,0x22,0x4D,0xE7,0x38,0xC2,0x7A,0x75,0x1C,0x38,0x29, + 0x2D,0x01,0xE2,0xF8,0x27,0x05,0x26,0xB8,0xCC,0x1A,0xAA,0xA9,0xB0,0xCE,0x85,0x94, + 0x07,0x0C,0x24,0x4B,0xE4,0x67,0x47,0xA8,0x34,0xF5,0x82,0x4E,0xD7,0x23,0xA2,0x71, + 0x71,0x50,0x1A,0x44,0xE0,0x2F,0x54,0xCB,0x0E,0xD9,0xBA,0xDA,0x3B,0xE7,0x16,0xC5, + 0x58,0x8D,0xA9,0x5D,0x11,0xC9,0xA0,0x72,0xE6,0xB0,0x5D,0x33,0xA3,0xC3,0x4D,0xE0, + 0xDC,0x38,0x80,0xCF,0xAC,0x41,0xD6,0xE8,0xF8,0x8A,0xCC,0x62,0xB0,0xC8,0x02,0x50, + 0x31,0x45,0xD0,0x43,0x5A,0x93,0x7C,0x52,0x05,0xFD,0x43,0x4B, +}; + +/* SHA1 Fingerprint=51:12:47:75:89:D8:47:B9:88:47:6F:31:E0:B3:03:EF:1B:B5:79:62 */ +/* subject:/serialNumber=101/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Escrow Service Root CA */ +/* issuer :/serialNumber=101/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Escrow Service Root CA */ +const uint8_t longroot[982] = { + 0x30,0x82,0x03,0xD2,0x30,0x82,0x02,0xBA,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x65, + 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, + 0x79,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x31,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,0x1F,0x30,0x1D,0x06,0x03,0x55, + 0x04,0x03,0x13,0x16,0x45,0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69, + 0x63,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x20,0x17,0x0D,0x31,0x34, + 0x30,0x34,0x30,0x32,0x32,0x32,0x35,0x33,0x35,0x37,0x5A,0x18,0x0F,0x39,0x39,0x39, + 0x39,0x31,0x32,0x33,0x31,0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x79,0x31,0x0C, + 0x30,0x0A,0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x31,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,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13, + 0x16,0x45,0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69,0x63,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,0x9C,0x7D,0xD4,0x09,0x41,0xF9,0x9A,0x92, + 0x70,0x0A,0xD8,0x67,0x2C,0xC7,0x55,0xAD,0xCD,0x10,0xF3,0x27,0x1B,0xF6,0x7B,0xA3, + 0x09,0x2D,0x78,0xED,0xF3,0xF4,0xFB,0x16,0x37,0xF0,0xB3,0x36,0x1C,0xE5,0x18,0xC8, + 0x25,0xB0,0xE7,0x50,0xA5,0x5D,0xF1,0xC4,0x7C,0xEA,0x83,0xCD,0x71,0x87,0x4A,0xE7, + 0xEE,0x6D,0xFD,0xD8,0x03,0xA6,0xBA,0x02,0x9C,0x9D,0x5D,0xFE,0xD0,0x0D,0x0C,0xDE, + 0x8C,0x65,0x56,0xE4,0xC6,0x87,0x90,0xE0,0xF2,0x6B,0xA8,0x05,0x14,0xEF,0xDE,0x9C, + 0xFF,0xF3,0x81,0x21,0xD1,0x29,0x6E,0xA0,0xF1,0xDA,0xD1,0x0A,0xE6,0x7B,0x3C,0xD2, + 0x78,0x1A,0xE3,0xC1,0x1F,0xF7,0xE2,0x2C,0x11,0x1F,0x3D,0x95,0x29,0xE1,0x0C,0x0D, + 0x80,0xF3,0xDA,0xF4,0xCE,0xCF,0xF7,0x33,0x8D,0xAC,0x81,0xDA,0xDA,0xDF,0xAC,0x5D, + 0xE0,0x5A,0x00,0x8E,0xDB,0xDC,0x92,0x6C,0x0F,0x1B,0xA5,0xAF,0x2D,0x7F,0x2D,0x4B, + 0x6E,0xC1,0xC5,0xF2,0xFA,0x6D,0xF6,0x5D,0xAA,0x66,0x55,0xF9,0x7A,0x39,0xB9,0x35, + 0x8C,0xA4,0x74,0x21,0x3E,0xA1,0xDC,0x37,0xFC,0x78,0x08,0xE5,0xC2,0xB3,0x6A,0xBE, + 0xD9,0xA9,0x1C,0xE8,0xF2,0x53,0x1C,0x58,0xFD,0x21,0xB6,0x5C,0x91,0xC7,0x85,0x40, + 0xD5,0x2E,0x94,0xD6,0x4D,0x99,0xCA,0x3B,0xD8,0xB0,0x18,0x4E,0x07,0xCE,0x2A,0xE6, + 0xD5,0x9E,0x21,0xD1,0xCF,0x81,0xDD,0xF2,0xCF,0x09,0xB3,0xD3,0x16,0xCF,0x5B,0x03, + 0xF6,0xCD,0xFD,0xB5,0xE4,0x8A,0xD7,0xBB,0x19,0x66,0x9F,0xA6,0x77,0x70,0x4D,0x90, + 0x42,0x2C,0x96,0x2E,0x4A,0x71,0x9C,0x77,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30, + 0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01, + 0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02, + 0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x17,0xE6,0x9A, + 0xB2,0xDD,0x97,0x13,0x41,0x71,0xD6,0x51,0x5E,0xBF,0xC0,0x24,0x2E,0x92,0x2D,0x0F, + 0x63,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x17,0xE6, + 0x9A,0xB2,0xDD,0x97,0x13,0x41,0x71,0xD6,0x51,0x5E,0xBF,0xC0,0x24,0x2E,0x92,0x2D, + 0x0F,0x63,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x03,0x82,0x01,0x01,0x00,0x22,0x04,0x6E,0x53,0x16,0xE9,0x82,0x69,0x28,0x1A, + 0x1C,0xC8,0xF4,0xE0,0x8C,0xC0,0xAC,0xDF,0xB2,0x5C,0xCD,0xD0,0xEC,0x57,0xB1,0x4C, + 0x77,0xD4,0xBB,0xE2,0xFC,0x19,0x0D,0xEA,0x16,0xAE,0xAE,0x16,0xA1,0x89,0xA4,0x87, + 0xAB,0x45,0x3A,0x9F,0xA5,0x82,0xB1,0x17,0x19,0x74,0x0C,0x04,0xB1,0x22,0xB2,0x63, + 0xB6,0x79,0xA3,0x4C,0x96,0x7A,0x17,0x34,0x9C,0x6C,0xA6,0x07,0x9E,0xA9,0x0E,0xD3, + 0x55,0xDE,0xA7,0x1E,0xEF,0x1A,0x5B,0x8E,0x6C,0x8D,0xB9,0x9F,0x4D,0xE6,0xB1,0xE4, + 0xCF,0xB8,0xF5,0x78,0x14,0xEC,0xDE,0x7E,0x1B,0xC8,0xC2,0xA9,0x2D,0x72,0xD3,0x43, + 0x7F,0xE1,0x38,0xF8,0x91,0x43,0xA6,0x81,0x71,0xBA,0x7C,0x12,0xBD,0x81,0x8A,0x6B, + 0x2D,0x77,0xC0,0xDA,0xE8,0xE8,0xF1,0xDA,0xE2,0xF6,0xF2,0x45,0xDE,0x3F,0xA8,0x09, + 0x29,0x98,0x7D,0xB1,0x67,0x3D,0x7A,0x14,0x7E,0xDD,0x0D,0x23,0x15,0x42,0x5B,0x21, + 0x1E,0x77,0x5D,0xF8,0x88,0x4D,0xFE,0x61,0x5A,0x6D,0xB4,0x73,0x5D,0x77,0x1B,0xC5, + 0xAC,0x97,0x78,0x5A,0xCD,0x35,0x0C,0x21,0x82,0x3D,0x0D,0xFD,0x30,0xDA,0x1B,0x19, + 0xC7,0xB7,0x68,0xFF,0xE0,0xA1,0x56,0x1D,0xE9,0x12,0x17,0x44,0x39,0x2C,0x0A,0x11, + 0xA5,0x69,0xBC,0xDF,0x12,0xA6,0x8F,0x43,0x1B,0xED,0x43,0x31,0xAA,0x0D,0xC6,0xE4, + 0x8F,0x35,0x4E,0x8D,0x17,0x0B,0xC5,0xBA,0xAD,0x81,0x9B,0x0C,0x54,0x74,0x25,0x7D, + 0xFC,0x8D,0x37,0x00,0xA6,0x47,0x89,0x40,0xC1,0x00,0x09,0x9E,0x7B,0x87,0xF6,0x32, + 0x91,0x57,0x4A,0x9C,0x99,0x26, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +const uint8_t _testValidityPeriodsRootHash[] = { + 0xDA, 0x4A, 0x5C, 0xFA, 0x1B, 0x9E, 0x01, 0x99, 0xA6, 0x00, 0x6E, 0xCD, 0xAC, 0x94, 0x64, 0xF7, + 0x1D, 0xA9, 0x1A, 0x7F, 0x40, 0x17, 0x0B, 0xFB, 0x2F, 0xC8, 0x56, 0xCB, 0x0D, 0xB9, 0x28, 0xCE +}; +const uint8_t _testValidityPeriodsRoot[] = { + 0x30,0x82,0x05,0xF8,0x30,0x82,0x03,0xE0,0xA0,0x03,0x02,0x01,0x02,0x02,0x09,0x00, + 0xD6,0x84,0x6D,0x3B,0x58,0xE4,0x13,0x1C,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81,0x97,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,0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56, + 0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D, + 0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F, + 0x74,0x30,0x1E,0x17,0x0D,0x31,0x36,0x30,0x35,0x30,0x32,0x30,0x31,0x35,0x39,0x30, + 0x34,0x5A,0x17,0x0D,0x32,0x36,0x30,0x34,0x33,0x30,0x30,0x31,0x35,0x39,0x30,0x34, + 0x5A,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,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,0xC0,0xBD,0x2B,0xBD, + 0xFB,0x54,0xEF,0x8D,0x05,0x2D,0x5E,0x37,0xC6,0xDD,0x78,0x54,0x0D,0x1F,0x9B,0x67, + 0x16,0x7F,0x40,0x67,0xF8,0x7C,0x09,0xF3,0x73,0x94,0xD9,0x0D,0x3E,0x93,0xC3,0x26, + 0x35,0xEF,0x42,0x04,0x8E,0x57,0xEC,0x84,0x30,0x52,0x03,0x51,0x86,0x36,0x52,0x5E, + 0xDF,0xDE,0x0C,0xDD,0xF9,0xD9,0xA0,0x7E,0xDD,0xBD,0x0D,0xCB,0xAF,0xA3,0x1D,0x8D, + 0x61,0xD2,0x17,0xDE,0x3B,0x37,0x45,0x73,0xD3,0xB8,0x52,0xE6,0x63,0x5D,0x27,0x77, + 0xCF,0xAF,0xCD,0x9A,0xA0,0xA6,0x12,0xC8,0x38,0xA2,0xC3,0x03,0xAA,0xAC,0x11,0x88, + 0xB4,0xDD,0x24,0x17,0x0E,0xD5,0x88,0x66,0x7F,0x9A,0xC7,0x91,0x2F,0x68,0x36,0x07, + 0x07,0x2C,0x95,0xA0,0xC6,0x8F,0x2D,0x8B,0x65,0xA8,0x8B,0xEF,0x0D,0x39,0x6F,0x5D, + 0x4F,0xFC,0x74,0xE8,0xAC,0x41,0x7C,0x00,0xE4,0xF1,0x2C,0x86,0x65,0x69,0x6C,0xCD, + 0x5C,0x83,0x23,0x06,0xFA,0x18,0xBB,0x8E,0x28,0xDD,0x63,0x8D,0x43,0x12,0x8D,0x98, + 0x0F,0xAB,0x15,0x49,0x76,0xFF,0xDD,0xF2,0x49,0x92,0x29,0xE5,0x3B,0xA8,0x78,0xC4, + 0xC6,0xAC,0xCF,0x9A,0x33,0x74,0x53,0x92,0x4B,0xDF,0x44,0x71,0xC0,0x05,0x11,0x83, + 0x97,0x37,0x1D,0x0A,0xA7,0x7D,0x71,0x5A,0xEB,0xB1,0xA7,0x1C,0xBB,0xC6,0xF3,0x3F, + 0xBE,0xF6,0x1B,0xF2,0xE9,0xE4,0x50,0x8A,0x56,0x9F,0xD1,0x58,0xF8,0x7C,0x2F,0xE6, + 0xF8,0x6C,0x7E,0x9C,0x4C,0x97,0x80,0x94,0xB0,0xE8,0x07,0x23,0xC9,0xB4,0x89,0xEC, + 0xE5,0xAC,0x86,0x34,0x7B,0xF4,0xD5,0xF2,0x20,0xD3,0x57,0x39,0xC1,0x00,0x8E,0x79, + 0x97,0x40,0xF4,0x2C,0xE0,0xDF,0xE4,0x5B,0x3F,0x6B,0x0C,0xD6,0xA1,0x9A,0xA5,0x73, + 0x9D,0xA0,0x66,0xBF,0x7E,0xCA,0xE0,0x74,0xE7,0x31,0x86,0xD5,0x5B,0xA0,0xCE,0x56, + 0x79,0x80,0x20,0xBB,0xB7,0x2C,0xAF,0xB5,0xB1,0x73,0xC4,0xF3,0xB5,0x6E,0xDC,0x2B, + 0xD2,0x83,0x9E,0x46,0xAC,0x28,0xB3,0x2C,0xF4,0x2B,0x05,0xC4,0x72,0xC9,0x44,0x98, + 0x55,0x31,0x18,0xF2,0xED,0xAA,0x6A,0x3D,0x06,0xD1,0xD0,0xDE,0xB6,0x89,0xB0,0x61, + 0xFA,0xE3,0x29,0x9E,0xFE,0xFF,0x54,0xCC,0x17,0x81,0xDA,0x0D,0x8B,0xEF,0x68,0x98, + 0xFE,0x0C,0xC3,0x9C,0xF1,0x86,0xFA,0xD3,0x3A,0x21,0x9B,0x59,0xD3,0xEA,0x79,0xDB, + 0xF4,0xA2,0xFD,0x4D,0xA6,0x98,0x6B,0x30,0x91,0x51,0x97,0x8F,0xF8,0xE6,0xC5,0x36, + 0x1B,0xEC,0xCE,0x0F,0x5B,0x28,0x40,0xCA,0xFD,0x55,0x00,0xDC,0xC7,0x99,0x22,0x43, + 0x5A,0x37,0x27,0xE8,0xD0,0x11,0x1E,0xD8,0x50,0x41,0x51,0xF5,0xDD,0xAC,0xA9,0x92, + 0x9F,0x57,0x12,0x41,0x78,0x2E,0x34,0x1D,0x64,0x96,0x80,0x06,0xE1,0x3A,0xBF,0x3B, + 0x9B,0x71,0xCC,0xDB,0x04,0x22,0x45,0x8E,0x6B,0x7B,0x0B,0x0C,0x83,0x73,0xC1,0xA1, + 0x80,0xD3,0xD2,0xEC,0x77,0x11,0x11,0x23,0xFC,0xEF,0xFE,0x70,0x03,0xA7,0xDB,0xFD, + 0xDD,0x6F,0x86,0xC8,0x92,0x53,0x6D,0xA5,0xDB,0xC6,0x9B,0x52,0x39,0x46,0x21,0xEB, + 0x5A,0xD7,0xC9,0xCB,0x82,0x0F,0x1C,0xCA,0xA1,0x7C,0x26,0x83,0x1F,0xC5,0x9E,0x3D, + 0x52,0x0D,0x2B,0xB6,0xF1,0x94,0x33,0x2C,0xA3,0x23,0x1D,0xC1,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,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7,0xF9,0x2B, + 0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x8B,0x79,0xBD,0xF5, + 0x6A,0x3F,0x46,0xEC,0xA7,0x2D,0xF3,0x4A,0xAB,0x30,0x66,0xF3,0x7E,0x1F,0x62,0xEE, + 0x0E,0x0F,0xFB,0xD5,0x3A,0x02,0xB0,0x9B,0x95,0x86,0xCE,0x4A,0xF0,0x6E,0x8B,0x4C, + 0x47,0x13,0x34,0x94,0x51,0xD9,0x9D,0x5E,0x97,0x8C,0x80,0xE4,0x2D,0x0F,0xA4,0x3A, + 0x9A,0x45,0xD1,0x44,0x3E,0x4F,0x4F,0xEF,0xC1,0x22,0xB0,0xFC,0x4B,0xB3,0xEA,0xD2, + 0xAF,0x65,0xAD,0xBD,0xFB,0x0D,0x38,0x4F,0xA5,0x29,0x4B,0xE3,0xFB,0xFD,0x46,0xA4, + 0x28,0xD9,0xAB,0xAA,0xED,0xF0,0xE6,0x1E,0x05,0x5F,0x85,0x8F,0x76,0xA2,0x29,0x0B, + 0x37,0x5A,0x4C,0xE7,0x03,0x4A,0xCC,0xC1,0xDF,0xF4,0xF2,0x56,0x22,0xE0,0x8A,0x3D, + 0x08,0x2D,0xCC,0x59,0x8C,0x48,0x1E,0xFC,0x48,0x98,0xB6,0xD3,0xB0,0x39,0xF5,0x95, + 0xF9,0x73,0xA7,0x12,0xCE,0x80,0x51,0x18,0xCF,0x55,0x81,0x8B,0xA8,0x09,0x61,0x81, + 0xBE,0xC5,0xF6,0xAF,0x7B,0x02,0x93,0xC8,0x4C,0x0E,0x5E,0xCB,0x79,0xE5,0x19,0x08, + 0xEA,0x44,0x44,0xCC,0x96,0x2B,0xF4,0xCA,0xF4,0xEF,0xC0,0xF6,0x8F,0xD4,0x23,0x35, + 0x97,0x88,0x70,0x70,0x6C,0x92,0x63,0xEF,0x7E,0x31,0x83,0xA1,0x8B,0x66,0x4B,0x32, + 0x45,0xA5,0x4F,0xBE,0x42,0x95,0x15,0xD1,0xC4,0x94,0x52,0x14,0x70,0x04,0x41,0xD0, + 0xEB,0xBF,0x30,0xBA,0xC2,0x75,0x98,0x09,0x47,0x2E,0x21,0x0C,0x66,0xCD,0xA4,0x4C, + 0x13,0x06,0x4F,0x7A,0x31,0x52,0xFA,0x36,0x1F,0xFF,0x08,0x28,0x82,0x81,0x64,0xE8, + 0xD3,0x4F,0xC6,0x75,0xB0,0x74,0xD5,0x07,0x14,0x40,0xC9,0x93,0x10,0x29,0x08,0x58, + 0x00,0x66,0x3A,0x3D,0x67,0x4E,0xCB,0xB8,0x01,0x44,0x1F,0x98,0xB4,0x9A,0x01,0x2E, + 0xA1,0x3F,0x79,0xA7,0xE1,0x81,0x4F,0x90,0x7E,0x8F,0x11,0x63,0x44,0x2B,0x9F,0x77, + 0xAF,0x57,0x25,0x36,0x30,0x6A,0x9D,0x6D,0x30,0x67,0x91,0xB1,0x43,0x46,0x05,0x19, + 0x80,0x14,0xAA,0x10,0xB7,0xFD,0x65,0x9B,0x0E,0x7B,0xED,0x2A,0xF9,0xB7,0xD4,0x3F, + 0x93,0xD6,0x83,0x81,0x90,0x63,0x95,0x82,0xA2,0xF0,0xFB,0xFC,0x53,0x19,0x28,0x93, + 0x93,0x5F,0xD9,0xD4,0x2F,0x3E,0xF2,0x36,0x5F,0x57,0x8E,0xDC,0x74,0xC2,0x04,0x8F, + 0x60,0xE2,0xC7,0xD6,0xB1,0x06,0x47,0xC2,0x14,0xA4,0xFE,0xF2,0xF4,0x9F,0x4A,0x7B, + 0x4D,0xFF,0x1F,0x8D,0x91,0x30,0x32,0xFB,0x48,0xD1,0xC6,0xD3,0x21,0x5D,0xBD,0x57, + 0xF3,0xF6,0x85,0x09,0x6C,0x26,0xA6,0xD7,0xFF,0xD4,0x98,0xBA,0x79,0xBD,0x1D,0xCF, + 0x3D,0x78,0x3A,0x86,0xB1,0x16,0x0E,0xB4,0xCC,0x15,0x87,0x61,0xFB,0xAA,0xE7,0xFE, + 0x17,0x56,0xF2,0x58,0xC7,0x12,0x7B,0x52,0x58,0x2C,0xFB,0x86,0xF4,0xFF,0x63,0x26, + 0x63,0x4F,0xFE,0x63,0xF7,0xC8,0x36,0x86,0x80,0x9E,0x91,0x1B,0xC1,0xD3,0xE0,0x72, + 0x3E,0x0A,0xA5,0xDE,0xE6,0xFE,0x5D,0xB6,0x03,0x3A,0x76,0x52,0x28,0x49,0x60,0x24, + 0xF0,0x5A,0x48,0x95,0xD6,0xC3,0x46,0x33,0xBB,0xD7,0xF7,0xE4,0x46,0xF5,0x4D,0x35, + 0x7E,0x41,0x84,0x68,0xDA,0x17,0xC9,0x0F,0xC9,0x99,0xBC,0x12,0x51,0x53,0x5E,0x87, + 0xD6,0xE2,0xF2,0xC3,0xCA,0x38,0xF8,0xDF,0xF6,0x34,0x65,0x4E, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums 5.5 Year Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* Not Before: May 2 02:03:41 2016 GMT + Not After : Oct 31 02:03:41 2021 GMT */ +const uint8_t _testLeaf_66Months[] = { + 0x30,0x82,0x05,0x5A,0x30,0x82,0x03,0x42,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,0xC9,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31, + 0x36,0x30,0x35,0x30,0x32,0x30,0x32,0x30,0x33,0x34,0x31,0x5A,0x17,0x0D,0x32,0x31, + 0x31,0x30,0x33,0x31,0x30,0x32,0x30,0x33,0x34,0x31,0x5A,0x30,0x81,0x9B,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,0x2F,0x30,0x2D,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x26,0x56,0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69, + 0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x35,0x2E,0x35,0x20, + 0x59,0x65,0x61,0x72,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,0xAF,0x97,0xB7,0x93,0x7A,0xAD, + 0x39,0x5A,0x61,0x55,0xFC,0xAD,0x2F,0x5D,0xDC,0xF4,0x28,0xF7,0x54,0x8E,0x08,0x75, + 0xEE,0x05,0xB7,0xFB,0xC7,0x17,0x5F,0x12,0xEC,0x6E,0xEE,0xAD,0xD9,0xC8,0x05,0x77, + 0xC7,0xBF,0xC2,0xC5,0xE4,0xCB,0x28,0x40,0x74,0x48,0x39,0x0B,0x2B,0x88,0xE7,0x30, + 0xFF,0x39,0x7D,0x88,0x2F,0x8C,0xF9,0x1B,0x48,0x54,0x1B,0xB3,0x6A,0x00,0xD3,0xFD, + 0x1B,0xB1,0x61,0xE6,0x42,0x50,0x91,0xFC,0x08,0xC7,0xB2,0x77,0x5B,0x12,0x80,0x40, + 0xDE,0xC4,0x29,0x4F,0xCC,0xC0,0xA0,0x20,0x08,0x0F,0x57,0x5C,0xC5,0xAD,0x2A,0x44, + 0x83,0xF8,0x8E,0x59,0xCD,0x45,0x5B,0x46,0x4D,0xF2,0x8B,0xD4,0x90,0x54,0xFF,0xA3, + 0xD7,0xC4,0x02,0x21,0x91,0xC9,0xAD,0xA4,0x1E,0x2B,0xA5,0x08,0x1B,0xF3,0xA9,0xE6, + 0xE8,0xA0,0xA0,0xFF,0x09,0xDE,0x7F,0x18,0x09,0x2B,0x38,0x26,0x7E,0x46,0xDA,0x6C, + 0xB3,0x5D,0xEA,0x0F,0xC9,0x8E,0xF3,0x86,0x12,0x57,0x95,0x2E,0xA7,0xB9,0x8F,0x7E, + 0xAF,0xC0,0xD0,0x5B,0xE1,0x52,0xB2,0xDD,0x20,0x1C,0x9B,0x6B,0x8C,0xBC,0xB6,0x35, + 0x8F,0xB0,0xFB,0xB4,0xF2,0x42,0xF8,0x1F,0xFF,0x32,0xAA,0x7C,0xF5,0x31,0x51,0x36, + 0x84,0xDF,0xD4,0xB1,0x99,0xD3,0x06,0x9D,0x2B,0x70,0x9D,0xD3,0xFC,0x33,0x6A,0x71, + 0xAE,0xC8,0xEB,0x1B,0xFB,0x75,0x09,0xE4,0xB6,0x20,0x66,0x9D,0x88,0xFF,0xF5,0xAB, + 0x7B,0x04,0x52,0x7B,0x94,0x5E,0x87,0x0E,0x31,0x30,0xB5,0x22,0x2A,0x52,0x44,0x8C, + 0x3B,0x05,0xF9,0x99,0x18,0x2C,0x04,0xF5,0x5A,0x65,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x81,0x98,0x30,0x81,0x95,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,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,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,0xCA,0x11,0x30,0xC3,0x7C,0xB1,0x07,0xB8,0xA8,0xA2,0x64, + 0xA7,0x96,0xF6,0x9E,0x37,0x3C,0xBD,0x9D,0x5E,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7, + 0xF9,0x2B,0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x3E,0x76, + 0x98,0xD1,0x3B,0x5E,0xF7,0x04,0xBC,0x65,0xBA,0x90,0xEB,0x43,0x5F,0xEC,0x62,0x71, + 0x22,0x7C,0x9F,0x9B,0xE4,0x6E,0x38,0x39,0x66,0x4B,0x36,0xB8,0xA5,0xBD,0xA2,0x91, + 0x48,0x8B,0xF6,0xF1,0xE5,0x46,0x8C,0x70,0x38,0x42,0xD3,0x17,0x29,0x30,0x5D,0xDE, + 0x78,0xCE,0xE9,0x03,0x95,0xA7,0xFB,0x48,0xAE,0xBE,0x18,0xDE,0x1F,0xA1,0x06,0x29, + 0x77,0xAB,0x49,0x1E,0x66,0x40,0x83,0xFD,0x73,0xD7,0x3F,0xCF,0x1F,0xA7,0x45,0xC4, + 0xFB,0x20,0x6F,0x29,0x98,0x8B,0xB9,0x08,0x55,0x6F,0xD7,0x4C,0x94,0x5F,0x64,0x2B, + 0x9E,0x39,0xE2,0x4C,0xCE,0x47,0x4C,0xCD,0x12,0x40,0x3B,0xD3,0xD8,0xF3,0xF9,0x41, + 0xAE,0x69,0x27,0x59,0x63,0x68,0x6F,0xEF,0x5B,0xF6,0x0B,0x67,0xCE,0xDE,0xEC,0xCF, + 0x86,0x84,0xDC,0x10,0xC7,0x8B,0x53,0xBD,0x27,0xC5,0xBE,0x08,0x4E,0xD3,0x9C,0xBE, + 0xDA,0x27,0x53,0xE7,0x79,0xC2,0xE4,0x92,0x7C,0x9A,0x15,0x0D,0x50,0x4C,0x88,0xD5, + 0xAE,0x9A,0x39,0x3C,0xA1,0xE5,0xF3,0xC6,0x4E,0x45,0x50,0x07,0x7A,0x23,0x98,0x92, + 0x10,0xDB,0x5C,0xA2,0x96,0x27,0x04,0xC8,0xAB,0x19,0xE0,0x0B,0x74,0x7A,0x16,0x96, + 0x0A,0xD3,0xE0,0x4A,0x5F,0x9A,0x4B,0xF5,0x20,0xA2,0xFE,0xB0,0xC7,0x4F,0x1C,0xCE, + 0x0F,0x49,0x44,0x79,0x59,0x55,0xF5,0x46,0xF4,0xA2,0xFE,0x2E,0x06,0x9E,0x02,0xAE, + 0x80,0x13,0x22,0x8A,0x2E,0x9A,0x08,0x22,0x2E,0xAA,0xA2,0x1E,0x35,0x45,0xB4,0xF3, + 0xD9,0x00,0xB2,0xF8,0x7F,0xE9,0xA6,0x50,0xC3,0x4B,0x01,0x0C,0x8E,0x0C,0x80,0x08, + 0x53,0x8C,0x17,0xD0,0xEA,0x40,0x45,0xA0,0xB0,0x1A,0x8F,0x79,0xA1,0xC2,0xDA,0xFA, + 0xF4,0x86,0xE8,0x69,0x7B,0x3F,0x78,0x7A,0x4B,0xB5,0x31,0xAD,0xF7,0x8A,0xFB,0x05, + 0x8B,0x40,0xA7,0x89,0xB2,0x0E,0xC1,0x43,0x1D,0xC2,0x7E,0xD4,0x8E,0xDF,0x48,0xD7, + 0xBD,0x15,0x7D,0xE2,0x38,0x36,0x36,0xCE,0x64,0xF5,0xD4,0x69,0xF0,0xCE,0x51,0x50, + 0x9C,0xDE,0xEC,0x54,0xA7,0x6B,0x5E,0xAE,0xEB,0xBA,0x76,0x47,0xE3,0x02,0x70,0x0D, + 0x2E,0xBB,0x5F,0x8D,0xBB,0x81,0xFE,0xE9,0xBD,0xE4,0xAC,0x8A,0xD5,0xFA,0x74,0x7B, + 0xF0,0x7E,0xBB,0x0F,0x56,0x23,0x34,0x0D,0x10,0x64,0x79,0x01,0xFF,0x48,0x26,0xDC, + 0x24,0x6E,0x59,0x70,0x8F,0x6B,0x44,0x4F,0x5A,0xB6,0xCF,0x34,0xD9,0xDB,0x51,0x10, + 0x54,0x4C,0xC7,0xDC,0xB7,0x39,0x07,0x6C,0xA7,0x67,0xF0,0xAE,0xC8,0xDC,0xB7,0xCE, + 0x46,0x0B,0xB0,0x8C,0xC3,0x91,0xC7,0xC5,0x58,0x67,0x48,0xA8,0x87,0xDF,0x13,0x39, + 0x82,0xE5,0x57,0xD0,0x8F,0x52,0x05,0x2F,0xE6,0x9B,0xCD,0xFB,0xDA,0x27,0x55,0x1A, + 0x5C,0x08,0x38,0xA4,0x1B,0x79,0xBC,0xAB,0x25,0x44,0xC6,0xF9,0xAE,0xAF,0xCD,0x7E, + 0x2E,0x2A,0x11,0x62,0x30,0x71,0x2B,0x28,0x64,0x5A,0x54,0x5D,0xCD,0x97,0x18,0x70, + 0xBC,0xDC,0x97,0xC4,0x9A,0x54,0x44,0xA1,0x5F,0x60,0x72,0xDB,0xFD,0x71,0x78,0xF8, + 0x98,0xA1,0x80,0x06,0xC5,0xDA,0xF8,0x84,0x70,0x0B,0xD9,0x17,0xB1,0xA8,0x61,0xA6, + 0x22,0xA2,0xBF,0x0A,0xB4,0xAD,0x7F,0xC8,0xB2,0x55,0xBD,0x5A,0xD1,0xD2, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums 5 Year Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* Not Before: May 2 02:06:37 2016 GMT + Not After : May 1 02:06:37 2021 GMT */ +const uint8_t _testLeaf_5Years[] = { + 0x30,0x82,0x05,0x58,0x30,0x82,0x03,0x40,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,0xCA,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31, + 0x36,0x30,0x35,0x30,0x32,0x30,0x32,0x30,0x36,0x33,0x37,0x5A,0x17,0x0D,0x32,0x31, + 0x30,0x35,0x30,0x31,0x30,0x32,0x30,0x36,0x33,0x37,0x5A,0x30,0x81,0x99,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,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x24,0x56,0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69, + 0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x35,0x20,0x59,0x65, + 0x61,0x72,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,0xBC,0x54,0xC3,0x25,0x9B,0x43,0xA8,0xE0, + 0x41,0xD9,0x40,0xA8,0xC0,0x9D,0xD4,0x2C,0x08,0xA1,0xE1,0x30,0x21,0x73,0x00,0xDB, + 0xF5,0x17,0x5C,0x90,0x92,0x56,0x3F,0x96,0x3D,0xEB,0x2C,0x03,0xB0,0x82,0x24,0xDC, + 0xA6,0x31,0xB0,0xFB,0xB7,0x89,0x34,0xF6,0x22,0x54,0xAE,0x95,0x54,0x87,0x40,0x46, + 0xCC,0xD1,0xC2,0x7C,0xA5,0xC8,0xC4,0xCA,0xCA,0x68,0x23,0x54,0xCF,0x38,0xFA,0x2B, + 0x44,0x62,0x1C,0x38,0x0C,0x75,0x70,0xC0,0xE9,0xD4,0x25,0x7A,0x9A,0xE6,0xC0,0x81, + 0xBC,0x8B,0xF0,0x2C,0x0E,0xC5,0xC4,0x96,0xE8,0x0D,0x0B,0xE3,0x75,0x6C,0x35,0xC4, + 0xB8,0x73,0xC9,0xB5,0x2C,0xCB,0xE6,0xFC,0x81,0x12,0xAE,0xD9,0x53,0x86,0xAA,0x79, + 0x1D,0xF5,0xD9,0x8D,0xF5,0x21,0x19,0x6A,0x0C,0xEB,0xCE,0xC6,0xAA,0x10,0xDA,0x0F, + 0x09,0x8C,0x05,0xA5,0x49,0xFC,0xB9,0xD0,0x40,0x7B,0xD3,0x5D,0xC7,0x74,0xE9,0xCF, + 0xDF,0x89,0x30,0x8A,0xFA,0x4B,0xC8,0x35,0x23,0x58,0x11,0xDF,0x48,0x84,0xD3,0xB0, + 0x61,0xDD,0x16,0x24,0xCC,0x96,0xF2,0x3C,0x7F,0xA4,0xCF,0x7E,0xD7,0x52,0x39,0x48, + 0x4B,0x45,0x39,0xEC,0x5E,0xAC,0x6D,0x37,0x88,0x2F,0x56,0x98,0x31,0xC5,0x7A,0x0B, + 0x9C,0xEA,0xE8,0x2B,0x96,0x2E,0x3C,0x52,0x03,0x05,0x82,0x10,0x3A,0x42,0xE6,0xA9, + 0xA5,0x7B,0xB9,0x65,0x52,0x23,0x4E,0x2E,0xE5,0xEA,0xC8,0xFE,0x29,0xA2,0x62,0x43, + 0x94,0x8D,0x52,0xC9,0xCB,0x27,0x15,0xEA,0x68,0x22,0xDC,0xC3,0xA2,0x1E,0x74,0xE1, + 0x37,0xEB,0xDD,0x7B,0xDF,0x11,0x5D,0x4D,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98, + 0x30,0x81,0x95,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,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,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,0x3C,0xBC,0x8F,0x12,0xF8,0xF9,0x5C,0x4D,0x7B,0xDB,0x34,0x6B,0x91, + 0x5A,0xA1,0xEF,0x8F,0x8C,0xFC,0x81,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, + 0x30,0x16,0x80,0x14,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7,0xF9,0x2B, + 0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x4C,0xED,0x6D,0x93, + 0x05,0x87,0x4C,0x1A,0x97,0x4E,0x2C,0x7C,0x34,0x3B,0x13,0x5A,0x84,0x4F,0x70,0x3F, + 0xC8,0xF0,0x9B,0xF1,0xEB,0xA6,0x8A,0xDB,0xBA,0xB1,0x5F,0x5D,0xDD,0x0C,0xD0,0x70, + 0x98,0x86,0xED,0x0C,0x0B,0xF8,0x69,0x7F,0xED,0xEA,0x5E,0x3B,0x91,0xB1,0xBA,0x33, + 0x0F,0xDB,0xE5,0xC1,0x1B,0x4A,0x80,0x6E,0x44,0xAF,0x2B,0x3A,0xE2,0x81,0x9B,0x3F, + 0xAC,0xD0,0x1E,0xE0,0x50,0x76,0x2A,0xFE,0xA9,0x07,0xB3,0xB3,0x3A,0x4B,0x2F,0x5A, + 0x19,0x12,0x28,0xE1,0x68,0xC7,0x19,0x96,0xA9,0xF2,0xB1,0x55,0x7A,0xF8,0x21,0x07, + 0xA1,0x44,0xE1,0xD3,0x9E,0x95,0x80,0x3D,0x0E,0x75,0xAE,0x4B,0xF6,0x6B,0x96,0xCC, + 0xB8,0x8B,0x6C,0xC1,0xB5,0xEE,0xEC,0x98,0xB8,0x24,0xB1,0x9F,0x87,0xF5,0xFF,0xE2, + 0xCE,0x40,0xAA,0xC6,0x38,0xFE,0xCE,0xA0,0x80,0xB3,0x97,0xC5,0x81,0xF1,0xC7,0x81, + 0xCC,0x9A,0x65,0xC7,0x0A,0xAD,0x94,0x33,0xF7,0x34,0x5F,0xB6,0xCB,0x35,0xCD,0x6B, + 0xA3,0x22,0x02,0xD6,0xBC,0xD2,0x4C,0x0E,0xA6,0x88,0x1F,0x96,0x97,0x38,0x88,0x1E, + 0x00,0x6E,0xA2,0xBF,0xB6,0xB9,0xEF,0xE0,0xFC,0xB5,0x69,0x43,0x42,0x43,0x83,0xA5, + 0x39,0x86,0xF4,0xD2,0xD4,0xD6,0x0C,0xA7,0x14,0xF6,0xD3,0xCB,0xAA,0xCE,0xA2,0xB0, + 0x7D,0xAF,0xD3,0x95,0x3A,0x93,0x38,0x01,0xDD,0x84,0x3D,0x82,0x88,0x0F,0x41,0xB5, + 0x65,0x31,0xFB,0x3C,0x50,0x09,0x97,0xBC,0xE9,0x46,0x02,0x1F,0xB1,0x8F,0x3C,0x71, + 0x29,0xCA,0x74,0x5A,0x33,0x97,0x85,0xE6,0x49,0x52,0xA5,0x60,0xB1,0x7B,0x05,0x3E, + 0x86,0xC7,0xCD,0xB8,0xD7,0x2E,0x47,0xEE,0x10,0x1F,0x99,0xCF,0x58,0xDC,0x25,0x75, + 0xC0,0x3A,0x00,0x4A,0xD3,0x5B,0xF4,0x64,0x6A,0x5B,0xC6,0xFC,0x12,0x41,0xB6,0x2B, + 0xC6,0xA4,0xC7,0x06,0xEA,0x80,0xE0,0x96,0x15,0x4D,0x79,0xEF,0x43,0x3C,0xA2,0x56, + 0xB3,0x0A,0xEC,0xDE,0x3A,0x19,0xFF,0x3A,0xE2,0x79,0x5E,0x04,0xAE,0x14,0xC6,0x6A, + 0x8F,0x2E,0xAC,0x74,0x88,0x70,0xE8,0x08,0x1B,0x34,0x82,0xA0,0x69,0xFD,0x28,0xD8, + 0x77,0xD9,0xA6,0xD7,0x46,0xF5,0x86,0x13,0xFF,0x93,0x29,0xD5,0x3E,0x8A,0xA1,0x84, + 0x1F,0x1E,0x85,0xE9,0xCC,0x06,0x1A,0xA2,0xCD,0xF6,0x57,0x04,0x7C,0x39,0x58,0xAD, + 0xA0,0xF1,0x9B,0xD1,0xA3,0xF1,0x07,0x78,0x31,0x8B,0x4D,0xCE,0x3B,0x55,0xC6,0x8D, + 0x4E,0x7D,0xEB,0xCE,0xE5,0xFB,0xC3,0x0C,0x2D,0xAE,0x43,0x25,0xF7,0xC2,0xBA,0x34, + 0xE8,0xED,0xF4,0xCB,0xE1,0xA6,0x57,0x7F,0xE6,0x97,0x7F,0x7E,0xF0,0xFB,0x04,0xA0, + 0xD8,0x0A,0xD4,0xDF,0xC3,0xFE,0xF4,0x37,0xF9,0x3A,0x2A,0xDE,0x72,0xBD,0xCE,0x0C, + 0x09,0x99,0x41,0xD1,0xDD,0x86,0xD5,0xE9,0x0D,0xA7,0x0E,0xFC,0x88,0xD9,0x34,0x98, + 0xEB,0xC8,0x2C,0x82,0xCE,0xAD,0x60,0x8E,0x29,0xEC,0xE6,0x47,0x2D,0x09,0xA0,0x63, + 0xFF,0x61,0xE0,0xAD,0x63,0xF3,0x2F,0x44,0xB3,0x46,0x83,0x92,0x14,0x00,0x1A,0x73, + 0xAB,0x1B,0x2A,0xEA,0xC4,0x62,0xC3,0x6B,0x15,0xA3,0xF0,0xBE,0x6E,0x38,0xE9,0x47, + 0x55,0xF9,0xE7,0xE9,0x85,0x9B,0x78,0x8F,0xAB,0x17,0xCD,0xA9, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums 4 Year Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* Not Before: Jul 2 02:07:42 2016 GMT + Not After : Jul 1 02:07:42 2020 GMT */ +const uint8_t _testLeaf_4Years[] = { + 0x30,0x82,0x05,0x58,0x30,0x82,0x03,0x40,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,0xCB,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31, + 0x36,0x30,0x37,0x30,0x32,0x30,0x32,0x30,0x37,0x34,0x32,0x5A,0x17,0x0D,0x32,0x30, + 0x30,0x37,0x30,0x31,0x30,0x32,0x30,0x37,0x34,0x32,0x5A,0x30,0x81,0x99,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,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x24,0x56,0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69, + 0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x34,0x20,0x59,0x65, + 0x61,0x72,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,0xA5,0x83,0x5F,0x25,0xED,0x09,0xED,0x3C, + 0xAD,0xA2,0xA3,0x1D,0xB1,0x77,0x16,0xEE,0x46,0xEB,0x87,0xAD,0xC9,0xFA,0xF4,0xF9, + 0x01,0x36,0xC3,0x3C,0xAD,0xFF,0x46,0x86,0x56,0x96,0x9D,0x6C,0xA6,0xF2,0x43,0x8C, + 0x48,0x77,0xFF,0x90,0xF9,0xAE,0xC5,0x29,0x20,0x4A,0x24,0x57,0x71,0x81,0xD1,0x26, + 0xC0,0x1A,0x72,0x8E,0x23,0x50,0xA7,0xD5,0x2D,0x0D,0x52,0xBB,0xB6,0x0B,0x1C,0xD0, + 0x24,0xA5,0x36,0x19,0xDE,0x70,0x63,0x7C,0xE5,0xCB,0x61,0x38,0xCB,0xC0,0xFC,0x59, + 0x19,0x9E,0xDB,0xE0,0x7B,0x62,0xC2,0xDC,0xF2,0x3A,0xA4,0xDA,0x47,0xA5,0x7F,0x35, + 0x59,0xB4,0x97,0xCC,0x65,0x53,0x13,0x7C,0xBE,0x49,0x84,0xC4,0x50,0x48,0x9D,0x24, + 0xB4,0x0A,0x62,0xB2,0x6C,0xCF,0xA4,0xDE,0x2E,0x1D,0xEE,0xC3,0x2D,0x67,0x2C,0xC2, + 0xDF,0x3B,0x80,0x06,0x81,0x84,0x7B,0x05,0x26,0xC9,0xC5,0x3E,0xCE,0x24,0x4A,0x1F, + 0x12,0xDB,0x00,0x7C,0x5D,0xEF,0x80,0x90,0xF3,0x5E,0x1C,0xCC,0x47,0x66,0xC0,0x80, + 0x82,0xFF,0xF2,0x8B,0x76,0x25,0x4B,0x5D,0x2E,0x52,0xE8,0xA6,0x8C,0x0B,0x88,0x79, + 0xED,0xCC,0x42,0x95,0x13,0xAB,0xA0,0x4A,0x2E,0x8B,0xCE,0x80,0x93,0xB0,0x2D,0xF1, + 0x37,0x76,0xC3,0xDE,0xD2,0x65,0xB4,0xBC,0x80,0xB9,0x5E,0xCE,0x95,0x6C,0xF7,0x59, + 0x9D,0xCB,0x71,0x7B,0xF0,0x8C,0xBC,0xB4,0xC8,0x82,0xB5,0x9E,0x49,0x81,0xC6,0xE9, + 0x6A,0x71,0xC7,0x44,0x62,0x35,0x8B,0x1F,0x8C,0x66,0xFD,0xAE,0xB9,0x91,0x71,0x15, + 0x35,0x75,0x17,0x87,0x58,0x3E,0xF3,0xF5,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98, + 0x30,0x81,0x95,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,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,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,0x42,0x41,0x9A,0x8A,0x77,0x53,0x8E,0x6D,0x30,0x3D,0x7A,0x21,0x81, + 0xDE,0x3A,0x50,0x82,0x11,0xA4,0xF1,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, + 0x30,0x16,0x80,0x14,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7,0xF9,0x2B, + 0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x3B,0x96,0x36,0x43, + 0x2E,0xBC,0x83,0x97,0x19,0x3E,0x86,0xEE,0xE0,0xBE,0xBC,0xD4,0xE7,0x7C,0xFF,0xA4, + 0x41,0xE6,0xB9,0x44,0xEC,0x66,0xF9,0x93,0x62,0xA3,0x39,0x0B,0xB4,0x28,0xE5,0x70, + 0xD6,0x8E,0x5A,0x49,0xBB,0xF7,0xAE,0xBC,0xE5,0x2A,0x73,0x5E,0xCA,0xFD,0x06,0x30, + 0x58,0x92,0xD9,0xDB,0x84,0x88,0xAF,0x8D,0x2B,0xC9,0x8C,0x00,0x52,0x19,0x51,0x77, + 0x1E,0x16,0x0C,0xC3,0x1B,0x5D,0xE4,0x1C,0x80,0xF7,0x81,0xFA,0x37,0xB9,0x8A,0x6F, + 0x7C,0x67,0x52,0x53,0xE2,0xA5,0xE2,0x28,0xA7,0x6E,0x7C,0x4B,0x1F,0x2F,0xA5,0x54, + 0xBF,0x4A,0xB5,0x5F,0xF0,0x2F,0xD8,0xFA,0xA8,0xD8,0x8E,0x70,0x5A,0xDD,0x54,0x02, + 0x1F,0xBA,0x6D,0xD1,0x30,0x7A,0x14,0xE3,0x0C,0xA8,0x46,0xB5,0xF2,0xCF,0xD1,0xF4, + 0xF8,0xEE,0x7B,0x54,0x14,0x19,0x90,0x89,0x6B,0xCD,0xE9,0xC9,0x2E,0x3A,0x03,0xF0, + 0x9C,0x09,0x9E,0x22,0xC7,0xFF,0x31,0x82,0xE8,0x5A,0x37,0xB7,0xA6,0x60,0x56,0xF7, + 0xA9,0xA1,0x4E,0x36,0x2B,0x8A,0x5B,0x6D,0xEA,0xA9,0x3D,0xFE,0xC3,0xAD,0x77,0xD3, + 0x5A,0x67,0x56,0xAF,0xFE,0x8A,0x2D,0x82,0xB3,0x03,0x20,0xD9,0x40,0x57,0x05,0x8C, + 0xE5,0xEE,0xCE,0x15,0xF7,0x5C,0xFB,0x1C,0xDE,0x1A,0x35,0x82,0xB1,0x9A,0xE5,0x4E, + 0xE4,0x63,0x00,0xCA,0x7A,0x4B,0x68,0x80,0xAB,0x24,0x91,0x6B,0xF1,0x9B,0x7F,0x4D, + 0x11,0x41,0x30,0x44,0xE9,0x83,0xBF,0xF6,0xF7,0x60,0xC0,0x8A,0x88,0x8B,0xD5,0x41, + 0xFF,0xAC,0x83,0x54,0xD0,0x68,0x17,0x50,0x60,0x36,0x6E,0x42,0x32,0x27,0x04,0xC9, + 0x16,0xF5,0x0E,0x47,0xBD,0xAA,0x05,0x20,0x12,0xDF,0x52,0xB9,0x28,0xEA,0x37,0xF9, + 0x42,0xAD,0x67,0x80,0x17,0x1F,0x1C,0x2D,0xED,0xCB,0x4D,0xB0,0x28,0xDF,0xB1,0x2F, + 0x6D,0xB3,0xB9,0x2F,0xDB,0xD5,0x1B,0x40,0x84,0x14,0xCA,0xAF,0x9F,0x23,0xC2,0xFD, + 0xB6,0xBB,0x32,0x1F,0xC1,0x2F,0x89,0x17,0xFB,0x64,0xB0,0x00,0xCF,0xE7,0xAB,0xD2, + 0xDA,0x20,0x5B,0x56,0x1F,0x1E,0x5F,0x01,0xDC,0xC6,0xA7,0x08,0x3A,0x43,0x23,0xAD, + 0xF4,0xA2,0x3C,0x74,0x4B,0x79,0xCA,0x4E,0x04,0xE8,0x8C,0xD8,0xCC,0x59,0x8C,0x7A, + 0x70,0x8D,0xDB,0x92,0xD8,0xB2,0x9E,0xBA,0x8C,0xE6,0x43,0xAD,0x46,0x9C,0xB7,0x92, + 0x96,0xB0,0x70,0xC5,0x87,0x7F,0xFB,0x0E,0x33,0x23,0x71,0x29,0x75,0x51,0xDE,0xD7, + 0x14,0x80,0x19,0x49,0x99,0x6F,0xFD,0x64,0x7B,0xCF,0x7F,0x98,0x66,0x5E,0xB3,0x5F, + 0xEF,0x08,0x77,0x3C,0xFC,0x9E,0xFF,0x35,0x68,0xBD,0x3E,0xD4,0x07,0x2B,0xF5,0x30, + 0xB7,0x08,0x0A,0x78,0x5C,0x80,0xD6,0xFE,0x95,0x9F,0x4F,0x0A,0x1E,0xAA,0x33,0x86, + 0x7A,0xF3,0x4C,0x86,0xF8,0x39,0x47,0xFA,0x09,0xD3,0x15,0xFD,0x57,0xD0,0x45,0x6E, + 0x37,0xA8,0xCB,0x78,0xF0,0x03,0x23,0xAB,0x39,0xDE,0x6D,0xC5,0x3C,0x91,0xE4,0x92, + 0x5B,0x01,0x73,0x93,0x05,0xAD,0x99,0xD0,0xA5,0xA7,0x46,0x68,0xF2,0x5F,0x13,0x3C, + 0x78,0x0B,0xC1,0x11,0xE8,0x31,0xD2,0xE4,0xC3,0x46,0xC1,0xE5,0x14,0x5E,0x30,0xB3, + 0x0C,0x5E,0xAB,0x14,0xF9,0x68,0xAE,0x2A,0x0E,0xFB,0xCC,0x9A, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums 3.3 Year Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* Not Before: Jul 2 02:09:37 2016 GMT + Not After : Oct 1 02:09:37 2019 GMT */ +const uint8_t _testLeaf_39Months[] = { + 0x30,0x82,0x05,0x5A,0x30,0x82,0x03,0x42,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,0xCC,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31, + 0x36,0x30,0x37,0x30,0x32,0x30,0x32,0x30,0x39,0x33,0x37,0x5A,0x17,0x0D,0x31,0x39, + 0x31,0x30,0x30,0x31,0x30,0x32,0x30,0x39,0x33,0x37,0x5A,0x30,0x81,0x9B,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,0x2F,0x30,0x2D,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x26,0x56,0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69, + 0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x33,0x2E,0x33,0x20, + 0x59,0x65,0x61,0x72,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,0xBF,0x60,0xBF,0xC1,0x68,0xAC, + 0x32,0xC2,0x13,0xA8,0x7E,0x06,0xD5,0x4B,0x89,0x9C,0xBD,0xBC,0x40,0x89,0xAF,0xC8, + 0xBA,0xFE,0xA4,0x69,0x81,0x06,0xC5,0xC0,0xC3,0x26,0x75,0x97,0x8F,0x66,0xF2,0x37, + 0xE6,0x85,0xEC,0xE8,0x24,0x40,0x2C,0x35,0x52,0xA5,0x27,0x8A,0x60,0x67,0xDE,0xD8, + 0x71,0x4B,0x27,0x9F,0xA9,0xC8,0xFE,0xBB,0xFD,0x68,0x59,0xFE,0x24,0x3C,0x79,0xCD, + 0xF5,0xA9,0x4E,0x2B,0x43,0x15,0xB7,0xD2,0xF3,0x37,0x48,0x3B,0x4E,0xA7,0x6A,0x10, + 0xDD,0x71,0x37,0x8C,0xC0,0x6C,0x17,0x4C,0x8F,0x27,0xA4,0xFE,0xEB,0x1D,0xBB,0x8F, + 0xCE,0xEB,0xFD,0x7E,0x5D,0xFA,0x00,0xF5,0x78,0x6A,0x10,0x4C,0x78,0x2D,0x5D,0x13, + 0xA8,0xFE,0x51,0xB1,0x4F,0xB8,0xD8,0x06,0xC8,0x12,0xE3,0x26,0xB8,0x2A,0x0E,0x64, + 0xD0,0x35,0xA7,0xAC,0x83,0x7E,0x72,0x62,0x86,0xEC,0x18,0x5A,0x8D,0x36,0x7E,0x62, + 0x7D,0xB8,0xA4,0xDE,0x27,0x8F,0x3C,0xCB,0x26,0x31,0xF7,0x06,0xDC,0x06,0x4C,0x9F, + 0x7A,0xFF,0xC6,0x1E,0x07,0x52,0x2E,0xCE,0x93,0x91,0x91,0xA9,0xF7,0xC4,0xDE,0xF8, + 0x3B,0xDA,0xEE,0x09,0x7C,0xAD,0xD5,0xA2,0x6C,0x8D,0x7E,0xC4,0x6B,0x02,0x20,0xA3, + 0x3A,0x4A,0xB3,0x83,0x6A,0xCC,0x57,0xAF,0x70,0x72,0xAB,0xB7,0x91,0xEC,0x73,0xB7, + 0x4F,0x9F,0x2D,0xAF,0x38,0x10,0x82,0x2B,0xD1,0xC9,0x90,0xD2,0x18,0x81,0x21,0x91, + 0xBE,0xBF,0xE2,0xB1,0xA3,0x51,0xFB,0x7A,0x11,0x00,0x1E,0x67,0xEC,0x7C,0x86,0xA0, + 0x03,0x7C,0x0D,0xD8,0xAE,0xC3,0x0A,0x1F,0xCE,0x81,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x81,0x98,0x30,0x81,0x95,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,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,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,0x1E,0xE5,0xF6,0xC2,0x22,0xFF,0x5E,0x12,0x47,0xEF,0x01, + 0xF2,0x76,0xD4,0xCD,0xED,0x6E,0xB4,0x42,0xD7,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23, + 0x04,0x18,0x30,0x16,0x80,0x14,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7, + 0xF9,0x2B,0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86, + 0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x02,0x08, + 0x64,0xF4,0xF3,0x08,0x3A,0xE4,0x2A,0xE2,0x01,0xFD,0x2E,0x88,0x14,0x63,0x55,0xEB, + 0x4E,0xE6,0x4F,0xBB,0xB5,0x34,0x50,0x28,0x05,0x44,0xAB,0xEA,0x42,0x7D,0x1A,0xDD, + 0x89,0xC3,0x18,0x09,0xE8,0xFE,0x72,0xCA,0xA6,0xF7,0xFA,0xAC,0xD8,0xA6,0x68,0x89, + 0xBB,0xB6,0x99,0x7F,0xAC,0x6F,0x56,0xE4,0xC2,0xAD,0x13,0x42,0x55,0x41,0x9A,0x9D, + 0x04,0x23,0x06,0x6C,0x52,0x8F,0x09,0x4E,0x1C,0x18,0x84,0x86,0xF4,0x9B,0x33,0xB9, + 0x2D,0xF6,0x57,0x84,0xB1,0x9A,0xE4,0x08,0xBE,0x9D,0x4F,0x59,0xC7,0x13,0xA8,0xD8, + 0x5B,0x65,0xB6,0x77,0x13,0xA1,0x12,0xB5,0xF9,0x18,0x6F,0x18,0x89,0xF5,0x15,0x44, + 0xD2,0xA8,0xE8,0x19,0x4D,0x65,0xAF,0x3A,0x1D,0xC2,0x22,0xBA,0xAA,0x86,0xE2,0xC2, + 0xB2,0x08,0x3D,0xE5,0x2F,0x39,0xC9,0x50,0x0C,0x8C,0x31,0x91,0x00,0x66,0x2E,0xEA, + 0xD4,0xED,0xC3,0xF6,0x09,0xD4,0x99,0xC4,0x56,0x0D,0x21,0xC1,0x14,0xF5,0xFB,0x8C, + 0x84,0x9E,0xF8,0x62,0xEE,0xE5,0xE9,0x3C,0x6F,0xF7,0x2D,0xF2,0xF8,0x34,0xD6,0xAC, + 0xF9,0xBD,0x09,0x70,0xCE,0x5E,0x8C,0x7C,0x5A,0x53,0xF9,0xC1,0x1F,0xE6,0x61,0xC6, + 0xD1,0x20,0xF1,0x86,0xD0,0x61,0x30,0xCD,0x25,0x46,0xFD,0x50,0x67,0x8C,0x8E,0x3E, + 0x0D,0x88,0xFE,0xC4,0xD4,0xA7,0x7D,0xDE,0xD4,0x05,0xF1,0x80,0xE7,0xA4,0x01,0x6A, + 0xFF,0x1F,0xF2,0x20,0xFB,0x43,0x6E,0x44,0x4C,0xCC,0x4D,0x54,0x19,0x6A,0x50,0x8B, + 0x57,0xE7,0xEC,0x0F,0xF2,0xC7,0x94,0x6C,0x6D,0xDF,0x15,0x49,0x9F,0x46,0xB9,0xF4, + 0x16,0xDD,0x62,0x96,0xF8,0x30,0x89,0x47,0xBF,0x04,0xC2,0xCE,0x80,0x91,0x82,0xC9, + 0x72,0xE0,0xBE,0xD0,0x05,0x0D,0x05,0x40,0xB6,0x41,0x37,0xD0,0x79,0x8A,0x86,0xB5, + 0x6B,0x85,0x71,0xD6,0xD8,0x89,0xCB,0xD7,0x7F,0x2D,0x93,0x4B,0xEA,0x69,0x83,0xB4, + 0x3B,0x80,0x75,0x96,0xC6,0x42,0x4F,0x8B,0xE0,0x6A,0x6A,0x1A,0xBE,0x01,0x86,0x6E, + 0x29,0xCA,0xEB,0x2A,0x28,0xB7,0x1F,0x07,0xA2,0x1D,0x92,0x20,0xB8,0x83,0xDF,0xB3, + 0x71,0x02,0x98,0xB0,0x3E,0x8F,0xB8,0xDB,0x7E,0x38,0xDA,0xC7,0x71,0xB1,0x37,0xB3, + 0x23,0x78,0x4D,0xB2,0x52,0xC5,0x83,0x9B,0xEB,0xD5,0xD8,0xED,0xA2,0x23,0xFE,0x50, + 0x18,0x9D,0xB1,0x1A,0xA4,0xEF,0x7B,0xA2,0x2B,0x3E,0x0E,0x2A,0x25,0x15,0xA3,0xEE, + 0xA5,0x71,0x92,0xB8,0x3B,0xB3,0xA0,0xAC,0x9A,0x23,0x20,0x64,0xDE,0x03,0xF7,0x8C, + 0xAA,0x49,0x4E,0xFF,0x4E,0x91,0xF6,0xF6,0x65,0xB0,0xE3,0x78,0x02,0xDE,0x61,0xD9, + 0xDE,0x86,0x62,0x6D,0x6C,0xB7,0x84,0x90,0xBB,0xF5,0xE2,0x1C,0x49,0x08,0x9E,0x2C, + 0x45,0xCB,0x54,0x8B,0xC5,0xCC,0xAE,0xC8,0x78,0x2A,0xE0,0x29,0x0B,0xCF,0x6F,0x93, + 0x73,0x4E,0xE9,0x2D,0x2C,0x0B,0xA1,0xB7,0xD6,0x8A,0xA8,0xC9,0xC8,0xEF,0x72,0xA7, + 0xE2,0x5B,0xB5,0x5C,0xEC,0xAC,0xD9,0xAF,0xFF,0x79,0xDB,0xF1,0x0E,0x54,0x19,0x72, + 0xD7,0x94,0xF5,0xD1,0x62,0x36,0x53,0x37,0xDD,0xD2,0x16,0x87,0x8E,0x4E,0x22,0x03, + 0x0C,0x8D,0xBE,0xBF,0x8A,0xCF,0xA8,0x26,0x17,0xD6,0x21,0x49,0x77,0xDF, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums 3 Year Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* Not Before: Jul 2 02:12:05 2019 GMT + Not After : Jul 1 02:12:05 2022 GMT */ +const uint8_t _testLeaf_3Years[] = { + 0x30,0x82,0x05,0x58,0x30,0x82,0x03,0x40,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,0xCD,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31, + 0x39,0x30,0x37,0x30,0x32,0x30,0x32,0x31,0x32,0x30,0x35,0x5A,0x17,0x0D,0x32,0x32, + 0x30,0x37,0x30,0x31,0x30,0x32,0x31,0x32,0x30,0x35,0x5A,0x30,0x81,0x99,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,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x24,0x56,0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69, + 0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x33,0x20,0x59,0x65, + 0x61,0x72,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,0xBF,0xA2,0x3C,0x27,0x62,0x40,0x3B,0x85, + 0x0E,0x79,0xA5,0x3F,0x94,0x88,0xBE,0x7F,0x1C,0xED,0x64,0x52,0xF6,0x90,0xC4,0x96, + 0x92,0x34,0xC6,0x0D,0xC6,0xFC,0xF1,0xFF,0xFB,0x0B,0x3A,0xD4,0xFC,0x28,0xFE,0x67, + 0x21,0x50,0x25,0x32,0x50,0x47,0x56,0x75,0xD8,0x6A,0x8D,0xF2,0xAC,0x30,0xF7,0xFA, + 0x5C,0x90,0xCE,0xCF,0xE4,0x6B,0x96,0xF4,0xCB,0x27,0x77,0x74,0x20,0xD7,0x3B,0x07, + 0x88,0x00,0x5E,0xCE,0xE1,0x1C,0xD9,0x03,0x70,0x02,0x50,0x47,0xA8,0xAC,0xB1,0x28, + 0x72,0xFD,0x41,0x5B,0x5C,0x26,0x1E,0x43,0xBB,0xD0,0xB6,0x05,0x48,0x20,0x31,0xEF, + 0x49,0x34,0x0A,0xC9,0x88,0xD5,0x15,0xB5,0xA3,0x1F,0x50,0xCE,0x18,0x01,0x08,0x86, + 0x2F,0x36,0x6E,0xEA,0xE9,0x00,0x4E,0x7B,0x5F,0xC8,0xA1,0xCF,0x66,0xE1,0x95,0x7E, + 0x4E,0x66,0x9D,0xC3,0xD0,0x32,0x66,0xE3,0x27,0xF5,0xB7,0x20,0x7D,0x80,0x26,0x76, + 0x0E,0xB6,0x3E,0x7F,0xF7,0xC2,0xB4,0x69,0x97,0x73,0xD9,0xEF,0xFA,0xB1,0xCD,0x1C, + 0x62,0xDD,0x8E,0x32,0x3F,0x26,0xC5,0x03,0x2E,0xCD,0x0B,0x59,0x41,0x7B,0x8A,0xE7, + 0xC6,0xF1,0x7E,0xF4,0xE4,0xAB,0xB4,0xFB,0xE7,0xA9,0xFB,0x4C,0xE6,0xA1,0xF0,0x9B, + 0x75,0x1A,0x0E,0x5B,0xFD,0xE0,0x85,0xA1,0xED,0x85,0x86,0x4C,0x5D,0x1C,0x5F,0xD1, + 0xAA,0xF4,0x94,0xC4,0x7C,0xC6,0xDF,0x83,0xC4,0x3E,0x0F,0xD3,0x48,0xA2,0x77,0xFA, + 0xCB,0xD9,0x88,0x46,0x69,0x70,0x50,0xAC,0xE3,0x94,0xC5,0xFB,0x7D,0x46,0xF0,0x7E, + 0xDE,0xF0,0x0A,0x9D,0x68,0xF5,0x7F,0x1F,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0x98, + 0x30,0x81,0x95,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,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,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,0x56,0xD1,0xEF,0x08,0x3D,0x1F,0x46,0x31,0x5C,0xD5,0x34,0x6D,0x54, + 0x2E,0xB7,0xC1,0xF7,0x04,0x46,0x41,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18, + 0x30,0x16,0x80,0x14,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7,0xF9,0x2B, + 0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x9C,0xAE,0xA4,0x42, + 0x5E,0x19,0x10,0xD9,0x75,0x81,0xC3,0x28,0x7A,0xE8,0x91,0x35,0x0E,0x5D,0x05,0x19, + 0x74,0x86,0xFE,0x1A,0x03,0x70,0x6D,0xCB,0x4A,0x1F,0x10,0xC9,0xAE,0x69,0x72,0x4B, + 0xF4,0xA5,0x25,0xE4,0x41,0xCB,0x91,0x61,0xF3,0x9F,0xDF,0x03,0xA5,0x37,0x9D,0x6D, + 0xB9,0xB0,0x9A,0xD6,0x88,0x80,0x71,0xAB,0xAC,0x79,0x12,0x20,0x82,0xD5,0x32,0x71, + 0xBB,0x75,0xBF,0x02,0x5F,0x82,0xF9,0x3E,0x16,0x8B,0xE5,0xE2,0x86,0x71,0x0B,0xB9, + 0x8B,0xB8,0x00,0x00,0x35,0xA0,0x48,0x3B,0x52,0xDE,0xF4,0x61,0xF1,0x19,0xFB,0x33, + 0xA2,0xD7,0x22,0xF8,0x5D,0x40,0x6E,0x8E,0x3B,0x6E,0xD2,0x6D,0xB0,0x18,0x1C,0xF3, + 0x9D,0xFD,0x4A,0x6A,0x10,0x49,0x0D,0x7A,0x58,0x5B,0x0A,0xC7,0xB8,0x75,0x2B,0xB1, + 0x4E,0x9D,0xF4,0x99,0x76,0x50,0x7F,0xFD,0x06,0xC4,0x95,0xEE,0xD7,0x21,0x61,0xE4, + 0x42,0x96,0x80,0x45,0x52,0x00,0x5E,0x1E,0x18,0x65,0x35,0x40,0x42,0x55,0x38,0x79, + 0x35,0x47,0xA7,0x3D,0x1F,0x74,0xD7,0x42,0x66,0xE7,0x29,0x7B,0x87,0x85,0x5D,0x6C, + 0x1C,0x9B,0x57,0xF5,0xF5,0x22,0xF2,0xB6,0xAC,0xFF,0xC1,0x0E,0x17,0xF2,0x1D,0x39, + 0xE0,0xD6,0xA1,0xD2,0xD6,0xB1,0x81,0x1B,0x17,0xD7,0xE5,0xC2,0x1F,0x36,0x92,0xFB, + 0x6C,0x7B,0xA5,0x80,0xA1,0x2F,0x7F,0xB6,0xBF,0x8A,0x5A,0xFE,0x49,0xE9,0x83,0xF1, + 0x3F,0xBD,0x06,0x20,0xE4,0x75,0xD1,0x0F,0x64,0xE2,0xFA,0x84,0x06,0x89,0x11,0x1B, + 0x2E,0x16,0x93,0x69,0x9E,0x7F,0x52,0xA9,0x35,0x9E,0x21,0x51,0x13,0x11,0xF8,0x85, + 0xC1,0x9D,0x02,0x1A,0x71,0x83,0x85,0x48,0x87,0x66,0x03,0x02,0x6B,0xD9,0x5A,0xAA, + 0xE9,0xAA,0xB7,0x8C,0xE6,0xF8,0xE5,0x4E,0xF9,0xF9,0xA9,0x9B,0x4D,0x7E,0x83,0xB8, + 0x9E,0xDE,0xED,0x9B,0x83,0x37,0xAB,0x83,0xC4,0x05,0x36,0xC8,0x98,0x3B,0x5E,0xE9, + 0x05,0x31,0x44,0xCB,0x6C,0x06,0x1A,0x28,0x8C,0x9C,0xC7,0x41,0xBD,0x85,0x49,0x78, + 0x4F,0x3F,0x06,0x0E,0x64,0x5C,0xCE,0xA8,0xF9,0x73,0x10,0x46,0xC5,0xE3,0x0D,0x0B, + 0x1A,0x71,0x80,0x2B,0xD5,0xD6,0xFF,0x46,0x9D,0xDE,0xEB,0x79,0x48,0x81,0x6E,0x31, + 0x1C,0xDB,0x5D,0xBD,0x10,0x31,0x6B,0xF9,0x3A,0x67,0x38,0x95,0x0E,0x4E,0xB0,0x7F, + 0x26,0xA5,0x84,0x8C,0x05,0x9F,0x03,0x30,0x3F,0xAF,0x04,0x2A,0x83,0x1F,0x00,0x12, + 0x4C,0x70,0x44,0x3A,0x50,0x41,0xF5,0x40,0x48,0x87,0x8F,0xEC,0xBC,0xEE,0x3D,0xEC, + 0x47,0x9F,0x91,0x17,0xBB,0x9B,0x6D,0x40,0xA7,0x2B,0x26,0x0C,0x7D,0x27,0xF2,0xF7, + 0xC2,0xC3,0x50,0x39,0x9A,0xE6,0x2F,0xC2,0xC6,0x9E,0xA3,0x3A,0x1B,0x0D,0x8F,0x73, + 0xCF,0x26,0x15,0x23,0x59,0x3C,0x98,0x4E,0x4B,0xC7,0xF3,0xB8,0x14,0x5E,0x91,0xE1, + 0x99,0xCE,0x76,0xFD,0x33,0x1D,0x83,0x27,0x81,0xF4,0xE1,0x61,0x44,0xCB,0xF0,0x18, + 0x65,0x37,0x36,0xC6,0x18,0x4B,0x55,0x3E,0x03,0x9F,0x21,0x20,0xB1,0xAD,0x0F,0x6F, + 0x15,0x7A,0x51,0xC6,0xE9,0x7A,0x27,0x90,0xF0,0x12,0x07,0x20,0x20,0x92,0x46,0x2F, + 0x94,0x07,0xDF,0x2A,0xB9,0x09,0xA6,0x5B,0xD7,0xA3,0xA4,0x67, +}; + +/* subject:/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums 825 Day Leaf */ +/* issuer :/C=US/ST=California/L=Cupertino/O=Apple Inc./OU=Security Engineering/CN=Validity Period Maximums Test Root */ +/* Not Before: Jul 2 02:13:26 2019 GMT + Not After : Oct 4 02:13:26 2021 GMT */ +const uint8_t _testLeaf_825Days[] = { + 0x30,0x82,0x05,0x59,0x30,0x82,0x03,0x41,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,0xCE,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05, + 0x00,0x30,0x81,0x97,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,0x2B, + 0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x0C,0x22,0x56,0x61,0x6C,0x69,0x64,0x69,0x74, + 0x79,0x20,0x50,0x65,0x72,0x69,0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D, + 0x73,0x20,0x54,0x65,0x73,0x74,0x20,0x52,0x6F,0x6F,0x74,0x30,0x1E,0x17,0x0D,0x31, + 0x39,0x30,0x37,0x30,0x32,0x30,0x32,0x31,0x33,0x32,0x36,0x5A,0x17,0x0D,0x32,0x31, + 0x31,0x30,0x30,0x34,0x30,0x32,0x31,0x33,0x32,0x36,0x5A,0x30,0x81,0x9A,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,0x2E,0x30,0x2C,0x06,0x03,0x55,0x04, + 0x03,0x0C,0x25,0x56,0x61,0x6C,0x69,0x64,0x69,0x74,0x79,0x20,0x50,0x65,0x72,0x69, + 0x6F,0x64,0x20,0x4D,0x61,0x78,0x69,0x6D,0x75,0x6D,0x73,0x20,0x38,0x32,0x35,0x20, + 0x44,0x61,0x79,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,0xAE,0xAF,0x95,0x53,0x3C,0xA8,0xAA, + 0x3F,0x4D,0x08,0x47,0x0A,0xF5,0x8B,0xFC,0xB8,0x40,0xD6,0xFB,0x68,0x4D,0xA6,0x28, + 0x8B,0xD7,0xCF,0xC2,0xEA,0x00,0x38,0x5C,0xCD,0x13,0x3F,0x3E,0xB8,0xA6,0x69,0xB7, + 0x4E,0x8D,0x89,0xDE,0x7F,0x19,0x19,0x9B,0xA9,0x91,0x40,0x96,0x6D,0xE3,0xEF,0x7F, + 0xCF,0xD0,0xB5,0x89,0xB5,0x18,0x99,0xA9,0xF1,0x12,0x6A,0xF5,0x27,0xA5,0x8A,0x4B, + 0xB6,0xE1,0xA4,0x8B,0xC5,0x05,0x83,0xB1,0x56,0x32,0x3D,0x88,0x94,0xD4,0xC6,0x60, + 0xEB,0x90,0xB5,0xFB,0x6E,0x87,0x41,0x64,0x17,0xE4,0xFD,0xD4,0x70,0x5D,0x0D,0x67, + 0x33,0x7B,0x64,0x0A,0x2C,0x20,0x9D,0x27,0xA6,0x5B,0xB8,0x67,0x7E,0x46,0xC7,0x2F, + 0x72,0x0C,0x54,0x4E,0x4E,0xF5,0xF9,0x2F,0xA3,0x6B,0x19,0x38,0x17,0x29,0xED,0xA1, + 0x44,0xD9,0xEF,0xB7,0xF3,0x9C,0x8D,0xE3,0x94,0x2C,0xC8,0xF3,0xAB,0xDF,0xF9,0xE3, + 0x88,0x80,0x31,0xAB,0x57,0x2B,0x96,0xAC,0xE4,0xBB,0x72,0xEA,0xF3,0x2E,0x70,0x8C, + 0x94,0x79,0x9C,0xC1,0xA0,0xD5,0xBF,0xF0,0xEB,0xCE,0xE0,0x90,0x14,0xB7,0x57,0x01, + 0x69,0xAB,0x36,0xF3,0xF5,0x98,0x20,0x67,0xA8,0xA5,0xD9,0x89,0x7E,0xE2,0x6F,0x89, + 0xB7,0x4C,0x92,0x5D,0x85,0x84,0x51,0x5B,0x67,0x61,0xA6,0xFE,0x1B,0x52,0x9D,0x8E, + 0xA0,0xFB,0x45,0xB0,0x8D,0xC6,0xF2,0xA1,0xFB,0x37,0x79,0x3E,0x99,0xE3,0x1C,0xAA, + 0x15,0xC5,0xCE,0xBD,0x05,0x48,0x83,0x21,0x5E,0x52,0xD2,0x0C,0xF3,0xA9,0xB1,0xC5, + 0x59,0x75,0xF2,0x4F,0x20,0x3F,0xCA,0xAC,0x23,0x02,0x03,0x01,0x00,0x01,0xA3,0x81, + 0x98,0x30,0x81,0x95,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,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,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,0x54,0x96,0x7A,0x23,0xA9,0xAC,0xC0,0xCA,0x65,0x23,0xEF,0xE6, + 0x3F,0x61,0xC3,0x3A,0xEB,0x3F,0xBC,0x28,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04, + 0x18,0x30,0x16,0x80,0x14,0xDE,0xEB,0xFD,0x98,0xFD,0xCA,0x44,0xC1,0xFA,0xB7,0xF9, + 0x2B,0xF5,0x96,0x67,0x08,0x11,0x35,0x27,0x75,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, + 0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x40,0x10,0xFB, + 0xD0,0x9D,0x3F,0x1C,0x6F,0x2A,0xAB,0x42,0xB2,0x9B,0x7B,0x82,0x84,0x0E,0x05,0x95, + 0x72,0x04,0xC9,0x9B,0x40,0x1F,0x98,0x3F,0x56,0x7B,0x03,0x0C,0x49,0xE7,0x90,0x73, + 0x8A,0x1D,0x21,0x30,0xA5,0x61,0xF4,0x0D,0x4E,0x38,0x9E,0xBF,0x0A,0xB8,0xE2,0x64, + 0x7A,0xCF,0xB6,0xAA,0x00,0xE5,0x89,0x24,0x2B,0x2C,0xE4,0x32,0x53,0x04,0xA2,0x99, + 0xBA,0x52,0x3B,0x0E,0x57,0x78,0x6A,0x6C,0x75,0x98,0x91,0x94,0x0C,0x2F,0xE3,0x92, + 0xF1,0x2E,0x4A,0xCF,0xAF,0xA6,0x31,0xF6,0x32,0x0A,0x89,0x32,0xC8,0xDC,0x2A,0xD1, + 0xA2,0x08,0x6D,0xE5,0x68,0x90,0x72,0x2B,0x76,0xE3,0x2F,0x0E,0x94,0x9E,0x35,0x98, + 0x6A,0xE5,0xCF,0xBA,0x78,0x24,0xCB,0x82,0x42,0x49,0x57,0x2F,0xC4,0x11,0x97,0x21, + 0xEB,0x1B,0x57,0xF6,0xC4,0x63,0x32,0x61,0x96,0xF7,0xB7,0xC5,0x86,0x65,0x09,0xCC, + 0x3E,0x15,0x90,0xA2,0x73,0xF3,0x42,0x31,0xF4,0xF7,0xA4,0xD4,0x10,0x49,0x92,0xDB, + 0xBC,0x47,0xFB,0x51,0xFB,0x60,0x48,0x0B,0xA2,0xAF,0x89,0x92,0x0F,0x50,0x93,0x91, + 0x4D,0x75,0xEF,0x69,0x88,0x57,0xCE,0x2E,0x11,0xA1,0xC1,0x9E,0x7B,0x97,0xB7,0x00, + 0x81,0x44,0x90,0xC4,0xAD,0x08,0xF5,0x2E,0x93,0xD6,0xBE,0x73,0x6D,0xBE,0xCA,0x52, + 0xD1,0x8D,0x11,0x72,0x30,0xA8,0xE8,0x9E,0xF8,0x5B,0x09,0xE0,0x69,0x0A,0xCD,0x08, + 0x46,0x7B,0xD8,0x88,0x71,0x33,0x33,0xBE,0xDC,0xC4,0x28,0x28,0xFD,0xBC,0x66,0x4E, + 0xF1,0x2A,0x40,0x41,0x5D,0x22,0x29,0x12,0xD6,0x51,0x6D,0xAF,0x5D,0x0B,0xA2,0xC4, + 0x5C,0x75,0xE6,0x26,0x9E,0x9E,0xE3,0x7F,0x8E,0x08,0xDA,0x5E,0x09,0xA4,0xDC,0xCA, + 0xC1,0x18,0x2A,0x27,0x05,0xC0,0xEE,0x8E,0x2E,0xBE,0xAE,0x2A,0x93,0xEF,0xEB,0x5B, + 0x54,0xF1,0xA7,0x91,0xBF,0x4E,0xD5,0xD0,0x82,0xA4,0xCF,0xD4,0xEC,0x53,0xFC,0x81, + 0x2E,0x16,0x7F,0x24,0x2B,0xF9,0xAE,0xA1,0x1C,0x35,0x4E,0x7D,0x14,0xEF,0x82,0x7F, + 0x4D,0x4E,0xB8,0x1A,0x7A,0x55,0xFB,0xDA,0x8E,0xEC,0xD0,0x06,0x19,0x67,0xF2,0x1C, + 0x43,0x6F,0xC6,0x94,0x52,0xA5,0x32,0x56,0x78,0x28,0xD3,0x84,0x27,0xC6,0xF0,0x2F, + 0x40,0xE5,0x5F,0x7E,0x5F,0xB8,0xBB,0x58,0xAD,0x03,0x09,0xEA,0x24,0x7B,0xA5,0x63, + 0xAB,0xEE,0xF6,0x47,0x91,0xA9,0xC8,0x40,0xD1,0x16,0x29,0x10,0x3D,0x78,0xCF,0x0F, + 0xBF,0xF2,0x43,0xD5,0xB5,0xCC,0x1B,0x21,0xD0,0xD3,0x8C,0xA8,0x2C,0xD4,0x79,0x31, + 0x30,0xE9,0x0C,0xF4,0x17,0x72,0xBF,0x7E,0xA6,0xF8,0xB7,0x9F,0x57,0xF8,0xFC,0x5D, + 0x36,0xFF,0xB7,0x27,0x29,0x6C,0xAB,0x26,0xFD,0x3B,0x85,0x7E,0xD9,0x24,0xFF,0x16, + 0x90,0x58,0xEE,0xF2,0x41,0x18,0xCE,0x5D,0xD5,0xC0,0xD1,0x1C,0x00,0x7E,0xC8,0x20, + 0xC7,0x3C,0x5F,0xAE,0x1F,0x08,0x9A,0x76,0x1F,0x4D,0xD0,0xA5,0x61,0x35,0x35,0xB1, + 0xCC,0x36,0x3A,0xF6,0xC6,0x6A,0x50,0x5C,0x6B,0x14,0xC4,0x1C,0x7F,0x07,0xE1,0xE9, + 0x2B,0x61,0x37,0x1B,0x25,0xFF,0xC6,0x02,0x2F,0x83,0xEE,0xF3,0x27,0x00,0xE9,0x73, + 0xC8,0xDC,0x49,0xDE,0x0B,0x80,0x4B,0x17,0x17,0x7B,0x13,0x79,0x56, +}; +#endif /* _TRUSTTESTS_EVALUATION_VERIFY_DATE_TESTS_H_ */ diff --git a/tests/TrustTests/EvaluationTests/iAPTests.m b/tests/TrustTests/EvaluationTests/iAPTests.m new file mode 100644 index 00000000..53735931 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/iAPTests.m @@ -0,0 +1,72 @@ +/* + * 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 +#include "SecCertificatePriv.h" +#include "SecPolicyPriv.h" +#include "SecTrustPriv.h" +#include "OSX/utilities/SecCFWrappers.h" + +#include "../TestMacroConversions.h" +#include "TrustEvaluationTestCase.h" +#include "iAPTests_data.h" + +@interface iAPTests : TrustEvaluationTestCase +@end + +@implementation iAPTests + +- (void)testiAPNegativeSignatures { + /* Test that we can handle and fix up negative integer value(s) in ECDSA signature */ + const void *negIntSigLeaf; + isnt(negIntSigLeaf = SecCertificateCreateWithBytes(NULL, _leaf_NegativeIntInSig, + sizeof(_leaf_NegativeIntInSig)), NULL, "create negIntSigLeaf"); + CFArrayRef certs = NULL; + isnt(certs = CFArrayCreate(NULL, &negIntSigLeaf, 1, &kCFTypeArrayCallBacks), NULL, "failed to create certs array"); + SecPolicyRef policy = NULL; + isnt(policy = SecPolicyCreateiAP(), NULL, "failed to create policy"); + SecTrustRef trust = NULL; + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), + "create trust for negIntSigLeaf"); + + const void *rootAACA2; + isnt(rootAACA2 = SecCertificateCreateWithBytes(NULL, _root_AACA2, + sizeof(_root_AACA2)), NULL, "create rootAACA2"); + CFArrayRef anchors = NULL; + isnt(anchors = CFArrayCreate(NULL, &rootAACA2, 1, &kCFTypeArrayCallBacks), NULL, "failed to create anchors array"); + if (!anchors) { goto errOut; } + ok_status(SecTrustSetAnchorCertificates(trust, anchors), "set anchor certificates"); + + XCTAssert(SecTrustEvaluateWithError(trust, NULL), "trust evaluation failed"); + +errOut: + CFReleaseNull(trust); + CFReleaseNull(certs); + CFReleaseNull(anchors); + CFReleaseNull(negIntSigLeaf); + CFReleaseNull(rootAACA2); + CFReleaseNull(policy); +} + +@end diff --git a/tests/TrustTests/EvaluationTests/iAPTests_data.h b/tests/TrustTests/EvaluationTests/iAPTests_data.h new file mode 100644 index 00000000..c4631978 --- /dev/null +++ b/tests/TrustTests/EvaluationTests/iAPTests_data.h @@ -0,0 +1,111 @@ +/* + * 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 _TRUSTTESTS_EVALUATION_IAP_TESTS_H_ +#define _TRUSTTESTS_EVALUATION_IAP_TESTS_H_ + +/* subject:/C=US/O=Apple Inc./OU=Apple Accessories/CN=IPA_204E6F2CB683A518F7726D190000C5DA */ +/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ +unsigned char _leaf_NegativeIntInSig[559]={ + 0x30,0x82,0x02,0x2B,0x30,0x82,0x01,0xD1,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x20, + 0x4E,0x6F,0x2C,0xB6,0x83,0xA5,0x18,0xF7,0x72,0x6D,0x19,0x00,0x00,0xC5,0xDA,0x30, + 0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x89,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,0x3D,0x30,0x3B,0x06,0x03,0x55,0x04, + 0x03,0x13,0x34,0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F, + 0x72,0x69,0x65,0x73,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,0x30, + 0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x32,0x33, + 0x31,0x31,0x31,0x35,0x31,0x31,0x37,0x5A,0x17,0x0D,0x34,0x39,0x31,0x32,0x33,0x31, + 0x32,0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x6D,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,0x1A,0x30,0x18,0x06, + 0x03,0x55,0x04,0x0B,0x13,0x11,0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65, + 0x73,0x73,0x6F,0x72,0x69,0x65,0x73,0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x03, + 0x14,0x24,0x49,0x50,0x41,0x5F,0x32,0x30,0x34,0x45,0x36,0x46,0x32,0x43,0x42,0x36, + 0x38,0x33,0x41,0x35,0x31,0x38,0x46,0x37,0x37,0x32,0x36,0x44,0x31,0x39,0x30,0x30, + 0x30,0x30,0x43,0x35,0x44,0x41,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,0x9A,0x21,0x88,0x3D,0x3B,0xCD,0xA9,0x9F,0x1B,0xC6,0x5F,0x47,0x5D,0xA8,0xEB, + 0x52,0x18,0x9F,0x1E,0xF3,0xD8,0x7C,0xB6,0x1D,0x39,0x7A,0x8C,0xE0,0xDB,0x79,0xB4, + 0x9D,0x37,0x16,0xB8,0x6F,0x1C,0x29,0x42,0x59,0xA5,0x4E,0xA2,0x9A,0xB1,0x0E,0xC4, + 0x55,0xCC,0x89,0x79,0x4A,0x9E,0xDB,0x95,0x7A,0xF3,0x3D,0x7F,0x58,0xAD,0xF7,0x61, + 0xB3,0xA3,0x36,0x30,0x34,0x30,0x32,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64, + 0x06,0x24,0x01,0x01,0xFF,0x04,0x22,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,0x04,0x00,0x00,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48, + 0xCE,0x3D,0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x80,0x6B,0x96,0x6C, + 0x83,0x04,0x29,0x68,0x52,0xF9,0x74,0x42,0x7C,0x49,0x81,0x39,0x53,0x91,0x53,0x0D, + 0x95,0xB7,0x4F,0x18,0xFC,0xA5,0x38,0x9A,0x55,0x68,0x53,0x02,0x02,0x21,0x00,0xF5, + 0xE4,0xF2,0xB7,0x0B,0x7F,0x43,0xFA,0xDB,0xC2,0x1A,0x05,0xEF,0xF9,0x0E,0x31,0xFC, + 0x0A,0xCB,0xCD,0x6C,0x03,0x8A,0x73,0x95,0x74,0xB1,0x57,0x03,0x09,0x55,0x8D, +}; + +/* subject:/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ +/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Apple Accessories Certification Authority - 00000002 */ +unsigned char _root_AACA2[618]={ + 0x30,0x82,0x02,0x66,0x30,0x82,0x02,0x0C,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x00, + 0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02,0x30,0x81,0x89,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,0x3D,0x30,0x3B,0x06,0x03,0x55, + 0x04,0x03,0x13,0x34,0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65,0x73,0x73, + 0x6F,0x72,0x69,0x65,0x73,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, + 0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x32,0x30,0x1E,0x17,0x0D,0x31,0x35,0x31,0x31, + 0x31,0x38,0x32,0x31,0x32,0x35,0x33,0x32,0x5A,0x17,0x0D,0x34,0x35,0x31,0x31,0x31, + 0x38,0x32,0x31,0x32,0x35,0x33,0x32,0x5A,0x30,0x81,0x89,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,0x3D,0x30,0x3B,0x06,0x03,0x55,0x04,0x03,0x13,0x34, + 0x41,0x70,0x70,0x6C,0x65,0x20,0x41,0x63,0x63,0x65,0x73,0x73,0x6F,0x72,0x69,0x65, + 0x73,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,0x30,0x30,0x30,0x30, + 0x30,0x30,0x30,0x32,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,0x0E, + 0x9B,0x88,0xC9,0x72,0x9C,0x91,0x0B,0xA3,0x08,0xFE,0x6C,0x6B,0x70,0x0D,0xF6,0x49, + 0x31,0x87,0x60,0xE4,0xB9,0x0E,0x8A,0xD8,0xB1,0x41,0x2D,0xEE,0x09,0x9E,0x7A,0xD2, + 0x0C,0xEB,0xFD,0x97,0x23,0x33,0x8F,0xCD,0x44,0x0A,0x6C,0xBD,0x5E,0xA5,0xC0,0x1B, + 0x9E,0x04,0x8A,0xD4,0x28,0x17,0x52,0xE8,0x28,0x35,0x84,0xED,0x7D,0xBE,0x2A,0xA3, + 0x63,0x30,0x61,0x30,0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30, + 0x03,0x01,0x01,0xFF,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04, + 0x03,0x02,0x01,0x06,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x58, + 0x4B,0x2B,0x2A,0x6C,0x19,0x2A,0x4D,0x45,0xCC,0x24,0x52,0x5A,0xEC,0x54,0x1A,0xA9, + 0xC8,0xA5,0x32,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14, + 0x58,0x4B,0x2B,0x2A,0x6C,0x19,0x2A,0x4D,0x45,0xCC,0x24,0x52,0x5A,0xEC,0x54,0x1A, + 0xA9,0xC8,0xA5,0x32,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, + 0x03,0x48,0x00,0x30,0x45,0x02,0x20,0x10,0x6F,0xD9,0x76,0x71,0xC9,0x4C,0xC0,0x78, + 0x6D,0x0E,0x43,0xD1,0x56,0x53,0x36,0x58,0x56,0xED,0x87,0x40,0xAC,0xF6,0xC5,0x86, + 0x87,0xF0,0xCD,0xA6,0x13,0x3B,0x53,0x02,0x21,0x00,0xD6,0x45,0x85,0xE3,0xE3,0x1A, + 0xE1,0x7D,0x22,0xD8,0x36,0xC1,0x88,0xC1,0x07,0xD9,0x4D,0x88,0x2E,0x08,0xA2,0xDD, + 0x13,0xB5,0x2A,0xAE,0x3B,0x83,0x2B,0xB2,0x7E,0xB3, +}; + +#endif /* _TRUSTTESTS_EVALUATION_IAP_TESTS_H_ */ diff --git a/tests/TrustTests/FrameworkTests/CertificateInterfaceTests.m b/tests/TrustTests/FrameworkTests/CertificateInterfaceTests.m new file mode 100644 index 00000000..8e8e0b70 --- /dev/null +++ b/tests/TrustTests/FrameworkTests/CertificateInterfaceTests.m @@ -0,0 +1,504 @@ +/* + * 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 "OSX/utilities/SecCFWrappers.h" +#include +#include +#include "OSX/sec/Security/SecFramework.h" +#include "OSX/utilities/SecCFWrappers.h" +#include +#include +#include +#include +#include "../TestMacroConversions.h" +#include "TrustFrameworkTestCase.h" + +#include "CertificateInterfaceTests_data.h" + +@interface CertificateInterfaceTests : TrustFrameworkTestCase + +@end + +@implementation CertificateInterfaceTests + +- (void)testCTInterfaces { + SecCertificateRef certF = NULL; + + CFDataRef precertTBS = NULL; + CFArrayRef proofs = NULL; + CFDataRef spkiDigest = NULL; + + isnt(certF = SecCertificateCreateWithBytes(NULL, serverF_cert_der, sizeof(serverF_cert_der)), NULL, "create certF"); + + isnt(precertTBS = SecCertificateCopyPrecertTBS(certF), NULL, "copy precertTBS"); + XCTAssertEqualObjects((__bridge NSData *)precertTBS, [NSData dataWithBytes:serverF_pre_cert_der length:sizeof(serverF_pre_cert_der)], + "Pre-cert TBS for serverF incorrect"); + + isnt(spkiDigest = SecCertificateCopySubjectPublicKeyInfoSHA256Digest(certF), NULL, "copy SPKI digest"); + XCTAssertEqualObjects((__bridge NSData *)spkiDigest, [NSData dataWithBytes:serverF_SPKI_hash length:sizeof(serverF_SPKI_hash)], + "SPKI digest for serverF incorrect"); + + isnt(proofs = SecCertificateCopySignedCertificateTimestamps(certF), NULL, "copy SCTs"); + NSArray *expectedProofs = @[[NSData dataWithBytes:serverF_sct length:sizeof(serverF_sct)]]; + XCTAssertEqualObjects((__bridge NSArray*)proofs, expectedProofs , "SCT array for serverF incorrect"); + + CFReleaseSafe(certF); + CFReleaseSafe(precertTBS); + CFReleaseSafe(proofs); + CFReleaseSafe(spkiDigest); +} + +- (void)testCreation { + SecCertificateRef cert0 = NULL, cert2 = NULL, cert4 = NULL; + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), + NULL, "create cert0"); + + CFDataRef cert2Data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + _c2, sizeof(_c2), kCFAllocatorNull); + isnt(cert2 = SecCertificateCreateWithData(kCFAllocatorDefault, cert2Data), + NULL, "create cert2"); + CFReleaseNull(cert2Data); + + CFDataRef cert4data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + pem, sizeof(pem), kCFAllocatorNull); + ok(cert4 = SecCertificateCreateWithPEM(NULL, cert4data), "create cert from pem"); + + uint8_t random[32]; + (void)SecRandomCopyBytes(kSecRandomDefault, sizeof(random), random); + NSData *randomData = [[NSData alloc] initWithBytes:random length:sizeof(random)]; + XCTAssert(NULL == SecCertificateCreateWithPEM(NULL, (__bridge CFDataRef)randomData)); + + CFReleaseNull(cert4data); + CFReleaseNull(cert0); + CFReleaseNull(cert2); + CFReleaseNull(cert4); +} + +- (void)testSelfSignedCA { + SecCertificateRef cert0 = NULL, cert1 = NULL, cert5 = NULL; + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), + NULL, "create cert0"); + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create cert1"); + isnt(cert5 = SecCertificateCreateWithBytes(NULL, _elektron_v1_cert_der, + sizeof(_elektron_v1_cert_der)), NULL, "create cert5"); + + ok(SecCertificateIsSelfSignedCA(cert0), "cert0 is CA"); + ok(!SecCertificateIsSelfSignedCA(cert1), "cert1 is not CA"); + ok(SecCertificateIsSelfSignedCA(cert5), "cert5 is v1 CA"); + + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(cert5); +} + +- (void)testSummary { + SecCertificateRef cert1 = NULL, cert3 = NULL, cert4 = NULL; + CFStringRef subjectSummary = NULL, issuerSummary = NULL; + + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create cert1"); + isnt(cert3 = SecCertificateCreateWithBytes(NULL, _phased_c3, sizeof(_phased_c3)), + NULL, "create cert3"); + + CFDataRef cert4data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + pem, sizeof(pem), kCFAllocatorNull); + ok(cert4 = SecCertificateCreateWithPEM(NULL, cert4data), "create cert from pem"); + CFReleaseNull(cert4data); + + isnt(subjectSummary = SecCertificateCopySubjectSummary(cert1), NULL, + "cert1 has a subject summary"); + isnt(issuerSummary = SecCertificateCopyIssuerSummary(cert1), NULL, + "cert1 has an issuer summary"); + + ok(subjectSummary && CFEqual(subjectSummary, CFSTR("www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.")), + "subject summary is \"www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign, VeriSign International Server CA - Class 3, VeriSign, Inc.\""); + ok(issuerSummary && CFEqual(issuerSummary, + CFSTR("Class 3 Public Primary Certification Authority")), + "issuer summary is \"Class 3 Public Primary Certification Authority\""); + CFReleaseNull(subjectSummary); + + isnt(subjectSummary = SecCertificateCopySubjectSummary(cert3), NULL, + "cert3 has a subject summary"); + /* @@@ this caused a double free without an extra retain in obtainSummaryFromX501Name(): + summary->description = string = copyDERThingDescription(kCFAllocatorDefault, value, true); */ + CFReleaseNull(subjectSummary); + + isnt(subjectSummary = SecCertificateCopySubjectSummary(cert4), NULL, + "cert4 has a subject summary"); + ok(subjectSummary && CFEqual(subjectSummary, CFSTR("S5L8900 Secure Boot")), + "cert4 is S5L8900 Secure Boot"); + + CFReleaseNull(subjectSummary); + CFReleaseNull(issuerSummary); + CFReleaseNull(cert1); + CFReleaseNull(cert3); + CFReleaseNull(cert4); +} + +- (void)testNTPrincipalName { + SecCertificateRef cert2 = NULL; + CFArrayRef ntPrincipalNames = NULL; + + isnt(cert2 = SecCertificateCreateWithBytes(NULL, _c2, sizeof(_c2)), + NULL, "create cert2"); + + ok(ntPrincipalNames = SecCertificateCopyNTPrincipalNames(cert2), + "SecCertificateCopyNTPrincipalNames"); + is(CFArrayGetCount(ntPrincipalNames), 1, "we got 1 princialname back"); + CFStringRef principal = (CFStringRef)CFArrayGetValueAtIndex(ntPrincipalNames, 0); + ok(CFEqual(principal, CFSTR("kmm6b@Virginia.EDU")), + "first principal is kmm6b@Virginia.EDU"); + CFReleaseNull(ntPrincipalNames); + CFReleaseNull(cert2); +} + +- (void)testDescription { + CFStringRef desc = NULL; + SecCertificateRef cert4 = NULL; + + CFDataRef cert4data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, + pem, sizeof(pem), kCFAllocatorNull); + ok(cert4 = SecCertificateCreateWithPEM(NULL, cert4data), "create cert from pem"); + CFReleaseNull(cert4data); + + ok(desc = CFCopyDescription(cert4), "cert4 CFCopyDescription works"); + CFReleaseNull(desc); + CFReleaseNull(cert4); +} + +- (void)testHashes { + SecCertificateRef cert0 = NULL; + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), + NULL, "create cert0"); + CFDataRef spki1Hash = SecCertificateCopySubjectPublicKeyInfoSHA1Digest(cert0); + isnt(spki1Hash, NULL, "cert0 has a SHA-1 subject public key info hash"); + CFReleaseSafe(spki1Hash); + + CFDataRef spki2Hash = SecCertificateCopySubjectPublicKeyInfoSHA256Digest(cert0); + isnt(spki2Hash, NULL, "cert0 has a SHA-256 subject public key info hash"); + CFReleaseSafe(spki2Hash); + CFReleaseNull(cert0); +} + +- (void)testCommonName { + SecCertificateRef cert = NULL; + CFStringRef commonName = NULL; + + XCTAssert(cert = SecCertificateCreateWithBytes(NULL, two_common_names, sizeof(two_common_names)), "failed to create cert"); + XCTAssertEqual(errSecSuccess, SecCertificateCopyCommonName(cert, &commonName), + "failed to copy common names"); + is(CFStringCompare(commonName, CFSTR("certxauthsplit"), 0), kCFCompareEqualTo, "copy common name got the wrong name"); + + CFReleaseSafe(commonName); + CFReleaseSafe(cert); +} + +- (void)testCopyEmailAddresses { + SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, mail_google_com, sizeof (mail_google_com)); + CFArrayRef array = NULL; + CFStringRef name = NULL; + + ok_status(SecCertificateCopyCommonName(cert, &name), "Failed to get common name from cert"); + ok(name, "Failed to get common name"); + ok(CFEqual(name, CFSTR("mail.google.com")), "Got wrong common name"); + + ok_status(SecCertificateCopyEmailAddresses (cert, &array), "Failed to get email addresses from cert"); + ok(array, "Failed to get email address array"); + is(CFArrayGetCount(array), 0, "Found unexpected email addresses"); + + CFReleaseNull(cert); + CFReleaseNull(name); + CFReleaseNull(array); +} + +- (void)testCopyExtensionValue { + SecCertificateRef cert = SecCertificateCreateWithBytes(NULL, mail_google_com, sizeof(mail_google_com)); + CFDataRef extension = NULL, expected = NULL, oid = NULL; + bool critical = false; + + /* parameter fails */ + is(extension = SecCertificateCopyExtensionValue(NULL, CFSTR("1.2.3.4"), &critical), NULL, + "NULL cert input succeeded"); + is(extension = SecCertificateCopyExtensionValue(cert, NULL, &critical), NULL, + "NULL OID input succeeded"); + + /* Extension not present */ + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("1.2.3.4"), &critical), NULL, + "Got extension value for non-present extension OID"); + + /* Using decimal OID, extension present and critical */ + isnt(extension = SecCertificateCopyExtensionValue(cert, CFSTR("2.5.29.19"), &critical), NULL, + "Failed to get extension for present extension OID"); + is(critical, true, "Got wrong criticality for critical extension"); + uint8_t basic_constraints_value[2] = { 0x30, 0x00 }; + expected = CFDataCreate(NULL, basic_constraints_value, sizeof(basic_constraints_value)); + ok(CFEqual(extension, expected), "Got wrong extension value for basic constraints"); + CFReleaseNull(extension); + CFReleaseNull(expected); + + /* Using binary OID, extension present and non critical */ + uint8_t eku_oid[3] = { 0x55, 0x01d, 0x25 }; + oid = CFDataCreate(NULL, eku_oid, sizeof(eku_oid)); + isnt(extension = SecCertificateCopyExtensionValue(cert, oid, &critical), NULL, + "Failed to get extension for present extension OID"); + is(critical, false, "Got wrong criticality for non-critical extension"); + uint8_t eku_value[] = { + 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, + 0x01 + }; + expected = CFDataCreate(NULL, eku_value, sizeof(eku_value)); + ok(CFEqual(extension, expected), "Got wrong extension value for extended key usage"); + CFReleaseNull(oid); + CFReleaseNull(extension); + CFReleaseNull(expected); + + /* No critical output */ + isnt(extension = SecCertificateCopyExtensionValue(cert, CFSTR("2.5.29.19"), NULL), NULL, + "Failed to get extension for present extension OID"); + CFReleaseNull(extension); + + /* messed up binary OIDs */ + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("abcd"), NULL), NULL, + "letters in OID"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("8.1.1.2"), NULL), NULL, + "bad first arc"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("10.1.1.1"), NULL), NULL, + "longer bad first arc"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR(""), NULL), NULL, + "empty string"); + is(extension = SecCertificateCopyExtensionValue(cert, CFSTR("1.2.1099511627776."), NULL), NULL, + "six byte component"); + + CFReleaseNull(cert); +} + +- (void)testCopySerialNumber { + SecCertificateRef cert1 = NULL; + CFDataRef c1_serial = NULL, serial = NULL; + + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create cert1"); + + c1_serial = CFDataCreate(NULL, _c1_serial, sizeof(_c1_serial)); + CFErrorRef error = NULL; + ok(serial = SecCertificateCopySerialNumberData(cert1, &error), "copy cert1 serial"); + CFReleaseNull(error); + ok(CFEqual(c1_serial, serial), "serial matches"); + + CFReleaseNull(serial); + CFReleaseNull(c1_serial); + CFReleaseNull(cert1); +} + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have a CT log list +-(void)testCopyTrustedCTLogs { + __block CFDictionaryRef trustedLogs = NULL; + __block int matched = 0; + + require_action(trustedLogs = SecCertificateCopyTrustedCTLogs(), + errOut, fail("failed to copy trusted CT logs")); + /* look for some known CT log ids to ensure functionality */ + for (int ix = 0; ix < CTLOG_KEYID_COUNT; ix++) { + CFDataRef logIDData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ctlogids[ix], CTLOG_KEYID_LENGTH, kCFAllocatorNull); + NSString *logIDKey = [(__bridge NSData *)logIDData base64EncodedStringWithOptions:0]; + CFDictionaryRef logData = CFDictionaryGetValue(trustedLogs, (__bridge CFStringRef)logIDKey); + if (logData) { + ++matched; + } + CFReleaseSafe(logIDData); + } + require_action(matched > 0, + errOut, fail("failed to match known CT log ids")); +errOut: + CFReleaseSafe(trustedLogs); +} +#endif // !TARGET_OS_BRIDGE + +#if !TARGET_OS_BRIDGE // bridgeOS doesn't have a CT log list +-(void)testCopyCTLogForKeyID { + int matched = 0; + /* look for some known CT log ids to ensure functionality */ + for (int ix = 0; ix < CTLOG_KEYID_COUNT; ix++) { + CFDataRef logIDData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, _ctlogids[ix], CTLOG_KEYID_LENGTH, kCFAllocatorNull); + CFDictionaryRef logDict = NULL; + const void *operator = NULL; + require_action(logDict = SecCertificateCopyCTLogForKeyID(logIDData), + errContinue, fail("failed to match CT log")); + require_action(isDictionary(logDict), + errContinue, fail("returned CT log is not a dictionary")); + require_action(CFDictionaryGetValueIfPresent(logDict, CFSTR("operator"), &operator), + errContinue, fail("operator value is not present")); + require_action(isString(operator), + errContinue, fail("operator value is not a string")); + + ++matched; + +errContinue: + CFReleaseNull(logDict); + CFReleaseNull(logIDData); + } + require_action(matched > 0, + errOut, fail("failed to match known CT log ids")); +errOut: + return; +} +#endif // !TARGET_OS_BRIDGE + +- (void)testDeveloperIdDate { + SecCertificateRef old_devid = SecCertificateCreateWithBytes(NULL, _old_developer_cert, sizeof(_old_developer_cert)); + SecCertificateRef new_devid = SecCertificateCreateWithBytes(NULL, _new_developer_cert, sizeof(_new_developer_cert)); + + CFErrorRef error = NULL; + CFAbsoluteTime time; + is(SecCertificateGetDeveloperIDDate(old_devid, &time, &error), false, "old Developer ID cert returned date"); + is(CFErrorGetCode(error), errSecMissingRequiredExtension, "old Developer ID cert failed with wrong error code"); + CFReleaseNull(error); + + ok(SecCertificateGetDeveloperIDDate(new_devid, &time, &error), "new developer ID cert failed to copy date"); + is(time, 573436800.0, "date in certificate wasn't 2019-03-05 00:00:00Z"); + + CFReleaseNull(old_devid); + CFReleaseNull(new_devid); +} + +- (void)testSecFrameworkIsDNSName { + const char *valid_names[] = { + "apple.com", + "127.0.0.1.example.com", + "1a.example.com", + "a1.example.com", + "example.xn--3hcrj9c", + "example.xn--80ao21a", + }; + + const char *invalid_names[] = { + /* Error: All-numeric TLD. */ + "apple.com.1", + "127.0.0.1", + /* Error: Label begins with a hyphen. */ + "-a.example.com", + /* Error: Label ends with a hyphen. */ + "a-.example.com", + /* Error: TLD begins with a hyphen. */ + "example.--3hcrj9c", + /* Error: TLD ends with a hyphen. */ + "example.80ao21a--", + /* Error: Label has invalid characters. */ + "_foo.example.com", + }; + + size_t i; + for (i = 0; i < sizeof(valid_names) / sizeof(valid_names[0]); i++) { + CFStringRef name = CFStringCreateWithCString(NULL, valid_names[i], kCFStringEncodingUTF8); + XCTAssertTrue(name != NULL); + XCTAssertTrue(SecFrameworkIsDNSName(name), "Valid host name '%s' failed to be parsed as such.", valid_names[i]); + CFRelease(name); + } + + for (i = 0; i < sizeof(invalid_names) / sizeof(invalid_names[0]); i++) { + CFStringRef name = CFStringCreateWithCString(NULL, invalid_names[i], kCFStringEncodingUTF8); + XCTAssertTrue(name != NULL); + XCTAssertFalse(SecFrameworkIsDNSName(name), "Invalid host name '%s' failed to be parsed as such.", invalid_names[i]); + CFRelease(name); + } +} + +- (void)testSecFrameworkIsIPAddress { + const char *valid_addrs[] = { + "127.0.0.1", /* localhost IPv4 */ + "162.159.36.1", /* WAN IPv4 */ + "::", /* all-zeros IPv6 address */ + "::1", /* localhost IPv6, leading zero expansion */ + "cafe:feed:face::1", /* inline zero expansion */ + "cafe:FEED:FACE::", /* trailing zero expansion */ + "2606:4700:4700::1111", /* compressed */ + "2606:4700:4700:0:0:0:0:1111", /* uncompressed */ + "[2606:4700:4700:0:0:0:0:1111]", /* literal form (for URLs) */ + }; + + const char *invalid_addrs[] = { + "apple.com.1", /* invalid characters */ + "284.321.1.1", /* IPv4 octet values > 255 */ + "192.168.254.0/24", /* CIDR notation; not for SAN values */ + "2606:4700:4700::1111::1" /* multiple IPv6 expansions */ + "[2606:4700:4700:[0:0:0:0]:1111]", /* too many brackets */ + "...1", /* not enough fields for IPv4 */ + "23.45.56.67.78", /* too many fields */ + ":1", /* not enough fields for IPv6 */ + "100:90:80:70:60:50:40:30:20:10", /* too many fields */ + "2600:f00000000d::1", /* invalid IPv6 octet value */ + "cov:fefe::1", /* invalid characters */ + }; + + size_t i; + for (i = 0; i < sizeof(valid_addrs) / sizeof(valid_addrs[0]); i++) { + CFStringRef addr = CFStringCreateWithCString(NULL, valid_addrs[i], kCFStringEncodingUTF8); + XCTAssertTrue(addr != NULL); + XCTAssertTrue(SecFrameworkIsIPAddress(addr), "Valid IP address '%s' failed to be parsed as such.", valid_addrs[i]); + CFRelease(addr); + } + + for (i = 0; i < sizeof(invalid_addrs) / sizeof(invalid_addrs[0]); i++) { + CFStringRef addr = CFStringCreateWithCString(NULL, invalid_addrs[i], kCFStringEncodingUTF8); + XCTAssertTrue(addr != NULL); + XCTAssertFalse(SecFrameworkIsIPAddress(addr), "Invalid IP address '%s' failed to be parsed as such.", invalid_addrs[i]); + CFRelease(addr); + } +} + +- (void)testSecFrameworkCopyIPAddressData { + unsigned char ipv4_data[4] = { + 0xA2, 0x9F, 0x84, 0x35 }; + unsigned char ipv6_data[16] = { + 0x26, 0x06, 0x47, 0x00, 0x47, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11 }; + + CFDataRef data4 = NULL, result4 = NULL; + CFDataRef data6 = NULL, result6 = NULL; + + data4 = CFDataCreate(NULL, ipv4_data, sizeof(ipv4_data)); + XCTAssertTrue(data4 != NULL); + result4 = SecFrameworkCopyIPAddressData(CFSTR("162.159.132.53")); + XCTAssertTrue(result4 != NULL); + XCTAssertTrue(CFEqual(result4, data4)); + CFRelease(data4); + CFRelease(result4); + + data6 = CFDataCreate(NULL, ipv6_data, sizeof(ipv6_data)); + XCTAssertTrue(data6 != NULL); + result6 = SecFrameworkCopyIPAddressData(CFSTR("2606:4700:4700::1111")); + XCTAssertTrue(result6 != NULL); + XCTAssertTrue(CFEqual(result6, data6)); + CFRelease(data6); + CFRelease(result6); +} + +@end diff --git a/tests/TrustTests/FrameworkTests/CertificateInterfaceTests_data.h b/tests/TrustTests/FrameworkTests/CertificateInterfaceTests_data.h new file mode 100644 index 00000000..50f227e3 --- /dev/null +++ b/tests/TrustTests/FrameworkTests/CertificateInterfaceTests_data.h @@ -0,0 +1,997 @@ +/* + * 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 _TRUSTTESTS_CERTIFICATE_INTERFACE_H_ +#define _TRUSTTESTS_CERTIFICATE_INTERFACE_H_ + +/* MARK: testCTInterfaces */ + +static +unsigned char serverF_cert_der[] = { + 0x30, 0x82, 0x03, 0x73, 0x30, 0x82, 0x02, 0xdc, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x15, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x52, 0x31, 0x0b, 0x30, + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x1a, + 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x63, 0x6f, 0x72, + 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x20, + 0x43, 0x41, 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, 0x30, 0x1e, 0x17, 0x0d, 0x31, + 0x32, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x17, 0x0d, 0x32, 0x32, 0x30, 0x36, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x30, 0x72, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, + 0x55, 0x04, 0x0a, 0x0c, 0x0e, 0x63, 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, + 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, 0x74, 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, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x18, 0x63, + 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, + 0x74, 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, 0xd2, 0x49, 0x0c, 0xd0, 0xc5, 0xa8, 0xc3, 0x0f, + 0x36, 0x99, 0x54, 0x00, 0xd7, 0xf0, 0x2a, 0xcb, 0x21, 0x20, 0x4c, 0xac, + 0xaa, 0xcb, 0x36, 0x20, 0x72, 0x78, 0x05, 0xd1, 0xc2, 0xf9, 0xce, 0xc9, + 0x5b, 0xbc, 0x38, 0xda, 0xdd, 0x27, 0xf7, 0x6b, 0x0a, 0xf0, 0x16, 0xe2, + 0xc9, 0x74, 0x8c, 0x47, 0x5b, 0x07, 0x91, 0xa5, 0x6c, 0xcf, 0xf9, 0x0a, + 0x05, 0xb3, 0x05, 0x6a, 0xbe, 0x59, 0xdb, 0xa2, 0x1b, 0x21, 0x29, 0xe1, + 0xef, 0x0d, 0x4f, 0xa1, 0xc5, 0xbd, 0x16, 0xeb, 0x8c, 0x45, 0x6f, 0x64, + 0x42, 0x93, 0x82, 0xb3, 0x6d, 0xff, 0x83, 0x61, 0xdc, 0xcf, 0x8d, 0xd0, + 0x09, 0x2c, 0x37, 0x87, 0x1b, 0x75, 0xf6, 0xb3, 0xf8, 0x45, 0xef, 0xe2, + 0xcb, 0xff, 0x6d, 0xbb, 0xe4, 0xa5, 0x29, 0xee, 0xc0, 0x78, 0x17, 0x94, + 0xdc, 0x6b, 0xc7, 0x46, 0x01, 0x74, 0xf9, 0x65, 0x3b, 0x59, 0x21, 0xf5, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x01, 0x37, 0x30, 0x82, 0x01, + 0x33, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, + 0x69, 0x9d, 0x9f, 0x7e, 0xd9, 0x34, 0x7c, 0xfa, 0xd5, 0xc2, 0x7e, 0x02, + 0x0f, 0x1e, 0x4d, 0x1d, 0xa9, 0x8e, 0xa8, 0xcb, 0x30, 0x7a, 0x06, 0x03, + 0x55, 0x1d, 0x23, 0x04, 0x73, 0x30, 0x71, 0x80, 0x14, 0xdc, 0x16, 0x44, + 0x15, 0x3e, 0x53, 0x27, 0xd8, 0x68, 0x66, 0x41, 0x40, 0x88, 0x90, 0xe4, + 0x4e, 0x0a, 0xda, 0x08, 0xa9, 0xa1, 0x56, 0xa4, 0x54, 0x30, 0x52, 0x31, + 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, + 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x11, 0x63, + 0x6f, 0x72, 0x65, 0x6f, 0x73, 0x2d, 0x63, 0x74, 0x2d, 0x74, 0x65, 0x73, + 0x74, 0x20, 0x43, 0x41, 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, 0x82, 0x01, 0x01, + 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, + 0x81, 0x8a, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, + 0x04, 0x02, 0x04, 0x7c, 0x04, 0x7a, 0x00, 0x78, 0x00, 0x76, 0x00, 0xab, + 0xa8, 0xb5, 0xb4, 0x7d, 0x00, 0x00, 0x1b, 0x46, 0x58, 0x28, 0xc4, 0x0a, + 0xc7, 0x0b, 0x03, 0xf6, 0x91, 0x70, 0xa3, 0x5f, 0xed, 0xc8, 0x74, 0x40, + 0x3c, 0xd0, 0x58, 0x1d, 0x3c, 0x8c, 0x16, 0x00, 0x00, 0x01, 0x47, 0xdc, + 0x04, 0xbc, 0x5a, 0x00, 0x00, 0x04, 0x03, 0x00, 0x47, 0x30, 0x45, 0x02, + 0x20, 0x5b, 0x3b, 0xe2, 0x6b, 0xa2, 0xda, 0x49, 0xb2, 0xa5, 0x55, 0x1d, + 0x2f, 0x4d, 0x21, 0x2e, 0x2d, 0xf7, 0x59, 0xb3, 0x22, 0x1d, 0x90, 0x38, + 0x88, 0x77, 0xad, 0x49, 0xca, 0x28, 0x1d, 0x4a, 0xa8, 0x02, 0x21, 0x00, + 0xb7, 0x08, 0x08, 0xfb, 0x6a, 0x06, 0x13, 0xaa, 0xe6, 0x4d, 0x69, 0x44, + 0xce, 0xc0, 0x17, 0x8f, 0x3e, 0x80, 0x30, 0xe2, 0xd0, 0xe1, 0x8b, 0xc0, + 0x34, 0x28, 0x8b, 0xd8, 0x85, 0xb5, 0x14, 0x97, 0x30, 0x0d, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, + 0x81, 0x81, 0x00, 0xae, 0x8c, 0x7f, 0x63, 0x9d, 0xdd, 0xee, 0x4f, 0xc4, + 0xc5, 0x7b, 0x20, 0xb5, 0xe8, 0x89, 0x3e, 0x2c, 0xfe, 0x36, 0x0e, 0x31, + 0x1a, 0x38, 0xd6, 0xb3, 0xfd, 0x37, 0xeb, 0x26, 0xd0, 0x27, 0xfa, 0x04, + 0x12, 0x9c, 0xe2, 0x20, 0xe1, 0x61, 0xbf, 0xee, 0x60, 0x45, 0x84, 0xa0, + 0xea, 0xce, 0x1f, 0xf7, 0x73, 0x31, 0xd4, 0xd7, 0x87, 0xe7, 0xd5, 0x9f, + 0xff, 0x8d, 0x14, 0x32, 0x22, 0x89, 0xf6, 0x31, 0x38, 0xef, 0x1c, 0x36, + 0x55, 0x0d, 0x5f, 0x0d, 0x99, 0x36, 0x58, 0x6a, 0xa3, 0xff, 0xf0, 0xc7, + 0xe0, 0x5e, 0x02, 0x20, 0x9f, 0x04, 0x0a, 0xa4, 0xba, 0x1a, 0x1c, 0xb2, + 0x43, 0x85, 0xc2, 0xcc, 0xd2, 0x95, 0x8f, 0x20, 0x11, 0x1d, 0xea, 0x9e, + 0x10, 0xf1, 0x45, 0xd2, 0x4d, 0x95, 0x80, 0xed, 0xe1, 0x86, 0x71, 0xee, + 0x50, 0x0f, 0xb0, 0x73, 0x12, 0x32, 0xdd, 0x95, 0xc5, 0xb9, 0x54 +}; + +uint8_t serverF_SPKI_hash[] = { + 0x7b, 0x02, 0x27, 0xc5, 0xf8, 0xb3, 0xbe, 0xa8, 0x48, 0x18, 0xd4, 0x84, 0x29, 0x79, 0x6b, 0xeb, + 0xf7, 0xd8, 0x54, 0x21, 0x63, 0x91, 0x51, 0x9e, 0x04, 0x7c, 0x7b, 0x00, 0x8e, 0xc8, 0xee, 0xf5 +}; + +unsigned char serverF_pre_cert_der[] = { + 0x30,0x82,0x02,0x4d,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x15, + 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30, + 0x52,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1A, + 0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x63,0x6F,0x72,0x65,0x6F,0x73,0x2D, + 0x63,0x74,0x2D,0x74,0x65,0x73,0x74,0x20,0x43,0x41,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,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x36,0x30,0x31,0x30,0x30,0x30, + 0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x32,0x30,0x36,0x30,0x31,0x30,0x30,0x30,0x30, + 0x30,0x30,0x5A,0x30,0x72,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02, + 0x55,0x53,0x31,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0A,0x0C,0x0E,0x63,0x6F,0x72, + 0x65,0x6F,0x73,0x2D,0x63,0x74,0x2D,0x74,0x65,0x73,0x74,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,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x03,0x0C,0x18,0x63, + 0x6F,0x72,0x65,0x6F,0x73,0x2D,0x63,0x74,0x2D,0x74,0x65,0x73,0x74,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,0xD2,0x49,0x0C,0xD0,0xC5,0xA8,0xC3,0x0F,0x36,0x99,0x54,0x00, + 0xD7,0xF0,0x2A,0xCB,0x21,0x20,0x4C,0xAC,0xAA,0xCB,0x36,0x20,0x72,0x78,0x05,0xD1, + 0xC2,0xF9,0xCE,0xC9,0x5B,0xBC,0x38,0xDA,0xDD,0x27,0xF7,0x6B,0x0A,0xF0,0x16,0xE2, + 0xC9,0x74,0x8C,0x47,0x5B,0x07,0x91,0xA5,0x6C,0xCF,0xF9,0x0A,0x05,0xB3,0x05,0x6A, + 0xBE,0x59,0xDB,0xA2,0x1B,0x21,0x29,0xE1,0xEF,0x0D,0x4F,0xA1,0xC5,0xBD,0x16,0xEB, + 0x8C,0x45,0x6F,0x64,0x42,0x93,0x82,0xB3,0x6D,0xFF,0x83,0x61,0xDC,0xCF,0x8D,0xD0, + 0x09,0x2C,0x37,0x87,0x1B,0x75,0xF6,0xB3,0xF8,0x45,0xEF,0xE2,0xCB,0xFF,0x6D,0xBB, + 0xE4,0xA5,0x29,0xEE,0xC0,0x78,0x17,0x94,0xDC,0x6B,0xC7,0x46,0x01,0x74,0xF9,0x65, + 0x3B,0x59,0x21,0xF5,0x02,0x03,0x01,0x00,0x01,0xA3,0x81,0xA9,0x30,0x81,0xA6, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x69,0x9D,0x9F,0x7E, + 0xD9,0x34,0x7C,0xFA,0xD5,0xC2,0x7E,0x02,0x0F,0x1E,0x4D,0x1D,0xA9,0x8E,0xA8,0xCB, + 0x30,0x7A,0x06,0x03,0x55,0x1D,0x23,0x04,0x73,0x30,0x71,0x80,0x14,0xDC,0x16,0x44, + 0x15,0x3E,0x53,0x27,0xD8,0x68,0x66,0x41,0x40,0x88,0x90,0xE4,0x4E,0x0A,0xDA,0x08, + 0xA9,0xA1,0x56,0xA4,0x54,0x30,0x52,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06, + 0x13,0x02,0x55,0x53,0x31,0x1A,0x30,0x18,0x06,0x03,0x55,0x04,0x0A,0x0C,0x11,0x63, + 0x6F,0x72,0x65,0x6F,0x73,0x2D,0x63,0x74,0x2D,0x74,0x65,0x73,0x74,0x20,0x43,0x41, + 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,0x82,0x01,0x01,0x30,0x09,0x06,0x03, + 0x55,0x1D,0x13,0x04,0x02,0x30,0x00, +}; + +uint8_t serverF_sct[] = { + 0x00,0xAB, + 0xA8,0xB5,0xB4,0x7D,0x00,0x00,0x1B,0x46,0x58,0x28,0xC4,0x0A,0xC7,0x0B,0x03,0xF6, + 0x91,0x70,0xA3,0x5F,0xED,0xC8,0x74,0x40,0x3C,0xD0,0x58,0x1D,0x3C,0x8C,0x16,0x00, + 0x00,0x01,0x47,0xDC,0x04,0xBC,0x5A,0x00,0x00,0x04,0x03,0x00,0x47,0x30,0x45,0x02, + 0x20,0x5B,0x3B,0xE2,0x6B,0xA2,0xDA,0x49,0xB2,0xA5,0x55,0x1D,0x2F,0x4D,0x21,0x2E, + 0x2D,0xF7,0x59,0xB3,0x22,0x1D,0x90,0x38,0x88,0x77,0xAD,0x49,0xCA,0x28,0x1D,0x4A, + 0xA8,0x02,0x21,0x00,0xB7,0x08,0x08,0xFB,0x6A,0x06,0x13,0xAA,0xE6,0x4D,0x69,0x44, + 0xCE,0xC0,0x17,0x8F,0x3E,0x80,0x30,0xE2,0xD0,0xE1,0x8B,0xC0,0x34,0x28,0x8B,0xD8, + 0x85,0xB5,0x14,0x97, +}; + +/* + Apple Inc. CA + */ +static const uint8_t _c0[] = { + 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, +}; + +static const uint8_t _c1_serial[] = { + 0x25,0x4B,0x8A,0x85,0x38,0x42,0xCC,0xE3,0x58,0xF8,0xC5,0xDD,0xAE,0x22,0x6E,0xA4 +}; + +/* + subject= /O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign + issuer= /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority + serial=254B8A853842CCE358F8C5DDAE226EA4 + */ +static const uint8_t _c1[] = { + 0x30,0x82,0x03,0x83,0x30,0x82,0x02,0xec,0xa0,0x03,0x02,0x01,0x02,0x02,0x10,0x25, + 0x4b,0x8a,0x85,0x38,0x42,0xcc,0xe3,0x58,0xf8,0xc5,0xdd,0xae,0x22,0x6e,0xa4,0x30, + 0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00,0x30,0x5f, + 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,0x37,0x30,0x35,0x06,0x03,0x55,0x04,0x0b,0x13, + 0x2e,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,0x30, + 0x1e,0x17,0x0d,0x39,0x37,0x30,0x34,0x31,0x37,0x30,0x30,0x30,0x30,0x30,0x30,0x5a, + 0x17,0x0d,0x31,0x31,0x31,0x30,0x32,0x34,0x32,0x33,0x35,0x39,0x35,0x39,0x5a,0x30, + 0x81,0xba,0x31,0x1f,0x30,0x1d,0x06,0x03,0x55,0x04,0x0a,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,0x17,0x30,0x15,0x06,0x03,0x55,0x04,0x0b,0x13,0x0e,0x56,0x65, + 0x72,0x69,0x53,0x69,0x67,0x6e,0x2c,0x20,0x49,0x6e,0x63,0x2e,0x31,0x33,0x30,0x31, + 0x06,0x03,0x55,0x04,0x0b,0x13,0x2a,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,0x20, + 0x49,0x6e,0x74,0x65,0x72,0x6e,0x61,0x74,0x69,0x6f,0x6e,0x61,0x6c,0x20,0x53,0x65, + 0x72,0x76,0x65,0x72,0x20,0x43,0x41,0x20,0x2d,0x20,0x43,0x6c,0x61,0x73,0x73,0x20, + 0x33,0x31,0x49,0x30,0x47,0x06,0x03,0x55,0x04,0x0b,0x13,0x40,0x77,0x77,0x77,0x2e, + 0x76,0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x43,0x50,0x53, + 0x20,0x49,0x6e,0x63,0x6f,0x72,0x70,0x2e,0x62,0x79,0x20,0x52,0x65,0x66,0x2e,0x20, + 0x4c,0x49,0x41,0x42,0x49,0x4c,0x49,0x54,0x59,0x20,0x4c,0x54,0x44,0x2e,0x28,0x63, + 0x29,0x39,0x37,0x20,0x56,0x65,0x72,0x69,0x53,0x69,0x67,0x6e,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,0xd8,0x82,0x80,0xe8,0xd6,0x19,0x02, + 0x7d,0x1f,0x85,0x18,0x39,0x25,0xa2,0x65,0x2b,0xe1,0xbf,0xd4,0x05,0xd3,0xbc,0xe6, + 0x36,0x3b,0xaa,0xf0,0x4c,0x6c,0x5b,0xb6,0xe7,0xaa,0x3c,0x73,0x45,0x55,0xb2,0xf1, + 0xbd,0xea,0x97,0x42,0xed,0x9a,0x34,0x0a,0x15,0xd4,0xa9,0x5c,0xf5,0x40,0x25,0xdd, + 0xd9,0x07,0xc1,0x32,0xb2,0x75,0x6c,0xc4,0xca,0xbb,0xa3,0xfe,0x56,0x27,0x71,0x43, + 0xaa,0x63,0xf5,0x30,0x3e,0x93,0x28,0xe5,0xfa,0xf1,0x09,0x3b,0xf3,0xb7,0x4d,0x4e, + 0x39,0xf7,0x5c,0x49,0x5a,0xb8,0xc1,0x1d,0xd3,0xb2,0x8a,0xfe,0x70,0x30,0x95,0x42, + 0xcb,0xfe,0x2b,0x51,0x8b,0x5a,0x3c,0x3a,0xf9,0x22,0x4f,0x90,0xb2,0x02,0xa7,0x53, + 0x9c,0x4f,0x34,0xe7,0xab,0x04,0xb2,0x7b,0x6f,0x02,0x03,0x01,0x00,0x01,0xa3,0x81, + 0xe3,0x30,0x81,0xe0,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01, + 0x01,0xff,0x02,0x01,0x00,0x30,0x44,0x06,0x03,0x55,0x1d,0x20,0x04,0x3d,0x30,0x3b, + 0x30,0x39,0x06,0x0b,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x07,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,0x76,0x65,0x72,0x69,0x73, + 0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x43,0x50,0x53,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,0x09,0x60,0x86,0x48,0x01, + 0x86,0xf8,0x42,0x04,0x01,0x06,0x0a,0x60,0x86,0x48,0x01,0x86,0xf8,0x45,0x01,0x08, + 0x01,0x30,0x0b,0x06,0x03,0x55,0x1d,0x0f,0x04,0x04,0x03,0x02,0x01,0x06,0x30,0x11, + 0x06,0x09,0x60,0x86,0x48,0x01,0x86,0xf8,0x42,0x01,0x01,0x04,0x04,0x03,0x02,0x01, + 0x06,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,0x76, + 0x65,0x72,0x69,0x73,0x69,0x67,0x6e,0x2e,0x63,0x6f,0x6d,0x2f,0x70,0x63,0x61,0x33, + 0x2e,0x63,0x72,0x6c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01, + 0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x08,0x01,0xec,0xe4,0x68,0x94,0x03,0x42,0xf1, + 0x73,0xf1,0x23,0xa2,0x3a,0xde,0xe9,0xf1,0xda,0xc6,0x54,0xc4,0x23,0x3e,0x86,0xea, + 0xcf,0x6a,0x3a,0x33,0xab,0xea,0x9c,0x04,0x14,0x07,0x36,0x06,0x0b,0xf9,0x88,0x6f, + 0xd5,0x13,0xee,0x29,0x2b,0xc3,0xe4,0x72,0x8d,0x44,0xed,0xd1,0xac,0x20,0x09,0x2d, + 0xe1,0xf6,0xe1,0x19,0x05,0x38,0xb0,0x3d,0x0f,0x9f,0x7f,0xf8,0x9e,0x02,0xdc,0x86, + 0x02,0x86,0x61,0x4e,0x26,0x5f,0x5e,0x9f,0x92,0x1e,0x0c,0x24,0xa4,0xf5,0xd0,0x70, + 0x13,0xcf,0x26,0xc3,0x43,0x3d,0x49,0x1d,0x9e,0x82,0x2e,0x52,0x5f,0xbc,0x3e,0xc6, + 0x66,0x29,0x01,0x8e,0x4e,0x92,0x2c,0xbc,0x46,0x75,0x03,0x82,0xac,0x73,0xe9,0xd9, + 0x7e,0x0b,0x67,0xef,0x54,0x52,0x1a +}; + + +/* + subject= /C=US/O=University of Virginia/OU=UVA Standard PKI User/emailAddress=kmm6b@Virginia.EDU/CN=Keith M. Moores 10 + issuer= /C=US/ST=Virginia/L=Charlottesville/O=University of Virginia/emailAddress=pkimaster@virginia.edu/CN=UVA Standard Assurance SKP 1 + serial=0C6D + */ +static const uint8_t _c2[] = { + 0x30,0x82,0x05,0x56,0x30,0x82,0x04,0xbf,0xa0,0x03,0x02,0x01,0x02,0x02,0x02,0x0c, + 0x6d,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x05,0x05,0x00, + 0x30,0x81,0xa9,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53, + 0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x08,0x13,0x08,0x56,0x69,0x72,0x67,0x69, + 0x6e,0x69,0x61,0x31,0x18,0x30,0x16,0x06,0x03,0x55,0x04,0x07,0x13,0x0f,0x43,0x68, + 0x61,0x72,0x6c,0x6f,0x74,0x74,0x65,0x73,0x76,0x69,0x6c,0x6c,0x65,0x31,0x1f,0x30, + 0x1d,0x06,0x03,0x55,0x04,0x0a,0x13,0x16,0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x69, + 0x74,0x79,0x20,0x6f,0x66,0x20,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x31,0x25, + 0x30,0x23,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x01,0x16,0x16,0x70, + 0x6b,0x69,0x6d,0x61,0x73,0x74,0x65,0x72,0x40,0x76,0x69,0x72,0x67,0x69,0x6e,0x69, + 0x61,0x2e,0x65,0x64,0x75,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x03,0x13,0x1c, + 0x55,0x56,0x41,0x20,0x53,0x74,0x61,0x6e,0x64,0x61,0x72,0x64,0x20,0x41,0x73,0x73, + 0x75,0x72,0x61,0x6e,0x63,0x65,0x20,0x53,0x4b,0x50,0x20,0x31,0x30,0x1e,0x17,0x0d, + 0x30,0x34,0x30,0x31,0x30,0x38,0x31,0x37,0x32,0x35,0x30,0x30,0x5a,0x17,0x0d,0x30, + 0x35,0x30,0x31,0x30,0x38,0x31,0x37,0x32,0x35,0x30,0x30,0x5a,0x30,0x81,0x8e,0x31, + 0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1f,0x30,0x1d, + 0x06,0x03,0x55,0x04,0x0a,0x13,0x16,0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x69,0x74, + 0x79,0x20,0x6f,0x66,0x20,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x31,0x1e,0x30, + 0x1c,0x06,0x03,0x55,0x04,0x0b,0x13,0x15,0x55,0x56,0x41,0x20,0x53,0x74,0x61,0x6e, + 0x64,0x61,0x72,0x64,0x20,0x50,0x4b,0x49,0x20,0x55,0x73,0x65,0x72,0x31,0x21,0x30, + 0x1f,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x01,0x16,0x12,0x6b,0x6d, + 0x6d,0x36,0x62,0x40,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2e,0x45,0x44,0x55, + 0x31,0x1b,0x30,0x19,0x06,0x03,0x55,0x04,0x03,0x13,0x12,0x4b,0x65,0x69,0x74,0x68, + 0x20,0x4d,0x2e,0x20,0x4d,0x6f,0x6f,0x72,0x65,0x73,0x20,0x31,0x30,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,0xb4,0xf9,0x1b,0xda,0x10,0x01, + 0x47,0x96,0xb4,0xea,0xb2,0x35,0xbb,0x7e,0x69,0x69,0xd9,0x49,0x2c,0x36,0x3a,0x27, + 0x55,0x6e,0x11,0xb1,0xdf,0x13,0x54,0xf2,0x66,0xa5,0x98,0x3a,0xfd,0x7e,0xda,0x6d, + 0x12,0xb7,0x06,0xaa,0xde,0x55,0x50,0x04,0xf5,0x91,0x27,0xc7,0x4d,0x85,0x91,0xd9, + 0xc5,0xd6,0x88,0xc6,0x33,0x40,0x83,0xc0,0xe4,0x83,0xe2,0x9f,0x49,0xfb,0xc1,0x1f, + 0xdb,0xd9,0xf4,0xd4,0x32,0x2e,0x3a,0xe9,0xb4,0x12,0x5d,0x58,0x2a,0x65,0x4e,0xc7, + 0x09,0x59,0xfc,0x2b,0x0d,0xda,0x6a,0xc3,0x9f,0x32,0x7d,0xf2,0xfc,0xf4,0x3e,0xb8, + 0x63,0xbc,0x13,0x74,0xc6,0x0e,0x76,0x3a,0x7a,0xe9,0x93,0x97,0x7f,0xc8,0x2b,0x33, + 0x9f,0xd8,0x59,0xef,0xc0,0x0a,0x2e,0xd3,0xd9,0x69,0x02,0x03,0x01,0x00,0x01,0xa3, + 0x82,0x02,0xa4,0x30,0x82,0x02,0xa0,0x30,0x0b,0x06,0x03,0x55,0x1d,0x0f,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,0x02,0x06,0x08,0x2b,0x06,0x01,0x05,0x05, + 0x07,0x03,0x04,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0x4d,0xe0, + 0xe1,0x57,0xb6,0x91,0x7a,0x34,0x99,0x7a,0xe5,0x2a,0xd6,0xae,0x0a,0x75,0x05,0x73, + 0x5d,0x30,0x30,0x09,0x06,0x03,0x55,0x1d,0x13,0x04,0x02,0x30,0x00,0x30,0x1f,0x06, + 0x03,0x55,0x1d,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x2c,0xb7,0xe3,0xa6,0x09,0x68, + 0x85,0x90,0x58,0x8e,0x2d,0xd5,0x3a,0xef,0x93,0x02,0x2a,0x4c,0x85,0x62,0x30,0x41, + 0x06,0x03,0x55,0x1d,0x11,0x04,0x3a,0x30,0x38,0xa0,0x22,0x06,0x0a,0x2b,0x06,0x01, + 0x04,0x01,0x82,0x37,0x14,0x02,0x03,0xa0,0x14,0x0c,0x12,0x6b,0x6d,0x6d,0x36,0x62, + 0x40,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2e,0x45,0x44,0x55,0x81,0x12,0x6b, + 0x6d,0x6d,0x36,0x62,0x40,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2e,0x45,0x44, + 0x55,0x30,0x2f,0x06,0x03,0x55,0x1d,0x12,0x04,0x28,0x30,0x26,0x81,0x16,0x70,0x6b, + 0x69,0x6d,0x61,0x73,0x74,0x65,0x72,0x40,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61, + 0x2e,0x45,0x44,0x55,0x82,0x0c,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2e,0x45, + 0x44,0x55,0x30,0x82,0x01,0x5c,0x06,0x03,0x55,0x1d,0x1f,0x04,0x82,0x01,0x53,0x30, + 0x82,0x01,0x4f,0x30,0x74,0xa0,0x72,0xa0,0x70,0x86,0x6e,0x6c,0x64,0x61,0x70,0x3a, + 0x2f,0x2f,0x6c,0x64,0x61,0x70,0x2e,0x70,0x6b,0x69,0x2e,0x76,0x69,0x72,0x67,0x69, + 0x6e,0x69,0x61,0x2e,0x65,0x64,0x75,0x2f,0x63,0x3d,0x55,0x53,0x2c,0x6f,0x3d,0x55, + 0x6e,0x69,0x76,0x65,0x72,0x73,0x69,0x74,0x79,0x25,0x32,0x30,0x6f,0x66,0x25,0x32, + 0x30,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2c,0x6f,0x75,0x3d,0x55,0x56,0x41, + 0x25,0x32,0x30,0x53,0x74,0x61,0x6e,0x64,0x61,0x72,0x64,0x25,0x32,0x30,0x41,0x73, + 0x73,0x75,0x72,0x61,0x6e,0x63,0x65,0x25,0x32,0x30,0x53,0x4b,0x50,0x25,0x32,0x30, + 0x31,0x2c,0x63,0x6e,0x3d,0x30,0x43,0x36,0x44,0x30,0x74,0xa0,0x72,0xa0,0x70,0x86, + 0x6e,0x6c,0x64,0x61,0x70,0x3a,0x2f,0x2f,0x6c,0x64,0x61,0x70,0x2e,0x70,0x6b,0x69, + 0x2e,0x76,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2e,0x65,0x64,0x75,0x2f,0x63,0x6e, + 0x3d,0x30,0x43,0x36,0x44,0x2c,0x6f,0x75,0x3d,0x55,0x56,0x41,0x25,0x32,0x30,0x53, + 0x74,0x61,0x6e,0x64,0x61,0x72,0x64,0x25,0x32,0x30,0x41,0x73,0x73,0x75,0x72,0x61, + 0x6e,0x63,0x65,0x25,0x32,0x30,0x53,0x4b,0x50,0x25,0x32,0x30,0x31,0x2c,0x6f,0x3d, + 0x55,0x6e,0x69,0x76,0x65,0x72,0x73,0x69,0x74,0x79,0x25,0x32,0x30,0x6f,0x66,0x25, + 0x32,0x30,0x56,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2c,0x63,0x3d,0x55,0x53,0x30, + 0x61,0xa0,0x5f,0xa0,0x5d,0x86,0x5b,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, + 0x77,0x2e,0x70,0x6b,0x69,0x2e,0x76,0x69,0x72,0x67,0x69,0x6e,0x69,0x61,0x2e,0x65, + 0x64,0x75,0x2f,0x63,0x67,0x69,0x2d,0x62,0x69,0x6e,0x2f,0x67,0x65,0x74,0x2d,0x63, + 0x72,0x6c,0x3f,0x6f,0x75,0x3d,0x55,0x56,0x41,0x25,0x32,0x30,0x53,0x74,0x61,0x6e, + 0x64,0x61,0x72,0x64,0x25,0x32,0x30,0x41,0x73,0x73,0x75,0x72,0x61,0x6e,0x63,0x65, + 0x25,0x32,0x30,0x53,0x4b,0x50,0x25,0x32,0x30,0x31,0x26,0x63,0x6e,0x3d,0x30,0x43, + 0x36,0x44,0x30,0x53,0x06,0x03,0x55,0x1d,0x20,0x04,0x4c,0x30,0x4a,0x30,0x48,0x06, + 0x09,0x2b,0x06,0x01,0x04,0x01,0xb4,0x76,0x01,0x01,0x30,0x3b,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,0x70,0x6b,0x69,0x2e,0x76,0x69,0x72,0x67,0x69,0x6e,0x69, + 0x61,0x2e,0x65,0x64,0x75,0x2f,0x73,0x74,0x61,0x6e,0x64,0x61,0x72,0x64,0x2f,0x63, + 0x70,0x73,0x2e,0x68,0x74,0x6d,0x6c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7, + 0x0d,0x01,0x01,0x05,0x05,0x00,0x03,0x81,0x81,0x00,0x9f,0xf2,0x7f,0x51,0x97,0x2c, + 0xe6,0x8f,0x50,0xba,0x75,0xd8,0x9c,0x77,0x5e,0x2a,0xe9,0xbe,0x18,0x37,0x7f,0x18, + 0x86,0xbb,0x9d,0x22,0xf2,0xf9,0x3e,0x22,0x00,0x0b,0xf2,0x41,0x6b,0x08,0x17,0xbc, + 0x7a,0xc4,0xc9,0x99,0xa0,0xbd,0x53,0x8d,0x52,0xdb,0xcc,0xd0,0x88,0x14,0x2a,0x05, + 0x93,0xcd,0xf3,0xa0,0xf3,0xb9,0xdb,0x35,0x5c,0xec,0x24,0xe8,0x08,0xbe,0x4e,0xa1, + 0xa2,0x54,0x41,0xbc,0xbe,0x7b,0x22,0xf4,0x03,0x7d,0xd0,0xfb,0x25,0x8d,0xf5,0xa9, + 0x04,0x14,0xe9,0xe3,0x3e,0x3f,0x13,0x6f,0x89,0x72,0x76,0x41,0x67,0x8a,0x48,0x2a, + 0x36,0xf0,0xe6,0xb9,0x33,0x35,0x88,0xda,0x27,0x9d,0xf9,0x5d,0x42,0x04,0x6f,0x7d, + 0x60,0x53,0x86,0xf2,0xf4,0x3b,0x3d,0xbe,0x1d,0x99, +}; + +/* subject:/C=US/O=Apple Computer, Inc./OU=mac.com/CN=phased/description=.Mac Sharing Certificate */ +/* issuer :/C=US/O=Apple Computer, Inc./OU=Apple Computer Certificate Authority/CN=Apple .Mac Certificate Authority */ +static unsigned char _phased_c3[1376]={ + 0x30,0x82,0x05,0x5C,0x30,0x82,0x04,0x44,0xA0,0x03,0x02,0x01,0x02,0x02,0x03,0x20, + 0x7D,0xC7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05, + 0x00,0x30,0x81,0x86,0x31,0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55, + 0x53,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0A,0x13,0x14,0x41,0x70,0x70,0x6C, + 0x65,0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,0x65,0x72,0x2C,0x20,0x49,0x6E,0x63,0x2E, + 0x31,0x2D,0x30,0x2B,0x06,0x03,0x55,0x04,0x0B,0x13,0x24,0x41,0x70,0x70,0x6C,0x65, + 0x20,0x43,0x6F,0x6D,0x70,0x75,0x74,0x65,0x72,0x20,0x43,0x65,0x72,0x74,0x69,0x66, + 0x69,0x63,0x61,0x74,0x65,0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31, + 0x29,0x30,0x27,0x06,0x03,0x55,0x04,0x03,0x13,0x20,0x41,0x70,0x70,0x6C,0x65,0x20, + 0x2E,0x4D,0x61,0x63,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65, + 0x20,0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x1E,0x17,0x0D,0x30,0x37, + 0x31,0x30,0x32,0x38,0x31,0x38,0x35,0x34,0x35,0x33,0x5A,0x17,0x0D,0x30,0x38,0x31, + 0x30,0x32,0x38,0x31,0x38,0x35,0x34,0x35,0x33,0x5A,0x30,0x72,0x31,0x0B,0x30,0x09, + 0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55, + 0x04,0x0A,0x13,0x14,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x6F,0x6D,0x70,0x75,0x74, + 0x65,0x72,0x2C,0x20,0x49,0x6E,0x63,0x2E,0x31,0x10,0x30,0x0E,0x06,0x03,0x55,0x04, + 0x0B,0x13,0x07,0x6D,0x61,0x63,0x2E,0x63,0x6F,0x6D,0x31,0x0F,0x30,0x0D,0x06,0x03, + 0x55,0x04,0x03,0x13,0x06,0x70,0x68,0x61,0x73,0x65,0x64,0x31,0x21,0x30,0x1F,0x06, + 0x03,0x55,0x04,0x0D,0x13,0x18,0x2E,0x4D,0x61,0x63,0x20,0x53,0x68,0x61,0x72,0x69, + 0x6E,0x67,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,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,0xFB,0x0E,0x62,0xD3, + 0xE2,0xCC,0xC7,0x54,0x6A,0x4F,0x9C,0x4E,0x40,0x9D,0x30,0x3D,0x60,0x86,0x00,0x7C, + 0x33,0x0C,0x2E,0x2E,0x45,0xDF,0xBE,0xEB,0x94,0xE7,0xD6,0xBE,0x6B,0x0F,0x7B,0x88, + 0x3C,0x02,0xA7,0x25,0x5E,0x18,0xC6,0x97,0xF0,0x0C,0xDD,0x89,0x22,0x27,0x9C,0x85, + 0x25,0x36,0x95,0x61,0x26,0xE7,0x6C,0x7E,0x41,0xDE,0xFF,0x5D,0x77,0xCB,0xE6,0x05, + 0xB0,0xAD,0x77,0xC9,0xFC,0xA5,0xF1,0x82,0x1A,0xB4,0xE4,0x26,0x8D,0x1B,0xC3,0xE2, + 0xEF,0x6A,0xE0,0xEE,0xF3,0x38,0x27,0xE1,0x73,0x9E,0xD0,0x93,0x6A,0xA6,0xD5,0xD1, + 0xEC,0xE5,0x0D,0x4B,0x3A,0x42,0x8C,0xF1,0xE1,0x24,0x0A,0x02,0x0D,0x22,0xAE,0xEC, + 0x47,0xDA,0xFA,0x6B,0x12,0x50,0x47,0x2E,0x4A,0xD8,0x9F,0x02,0x03,0x01,0x00,0x01, + 0xA3,0x82,0x02,0x68,0x30,0x82,0x02,0x64,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,0x03,0x88,0x30,0x28,0x06,0x03,0x55,0x1D,0x25,0x04,0x21,0x30, + 0x1F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02,0x06,0x0A,0x2A,0x86,0x48, + 0x86,0xF7,0x63,0x64,0x03,0x02,0x01,0x06,0x07,0x2B,0x06,0x01,0x05,0x02,0x03,0x04, + 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0x3D,0xD9,0xDD,0x8F,0x5B, + 0x5E,0xA3,0x3A,0x8C,0x89,0x7F,0x8A,0x85,0x26,0xA7,0x84,0x0E,0xF3,0x0D,0x82,0x30, + 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x7A,0x7D,0x90,0xB1, + 0x30,0x59,0x08,0x92,0x91,0xF9,0x53,0xB9,0x71,0x1D,0x35,0x33,0x67,0x34,0x8B,0xD5, + 0x30,0x81,0xAD,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0xA0, + 0x30,0x81,0x9D,0x30,0x28,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x86, + 0x1C,0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x63,0x65,0x72,0x74,0x69,0x6E,0x66,0x6F, + 0x2E,0x6D,0x61,0x63,0x2E,0x63,0x6F,0x6D,0x2F,0x6F,0x63,0x73,0x70,0x30,0x44,0x06, + 0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x38,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,0x63,0x61,0x73,0x69,0x67,0x6E,0x65,0x72,0x73,0x2E,0x68, + 0x74,0x6D,0x6C,0x30,0x2B,0x06,0x03,0x55,0x1D,0x12,0x86,0x24,0x68,0x74,0x74,0x70, + 0x3A,0x2F,0x2F,0x63,0x65,0x72,0x74,0x69,0x6E,0x66,0x6F,0x2E,0x6D,0x61,0x63,0x2E, + 0x63,0x6F,0x6D,0x2F,0x64,0x6F,0x74,0x4D,0x61,0x63,0x43,0x41,0x2E,0x63,0x65,0x72, + 0x30,0x82,0x01,0x28,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x1F,0x30,0x82,0x01, + 0x1B,0x30,0x82,0x01,0x17,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x02, + 0x30,0x82,0x01,0x08,0x30,0x40,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, + 0x16,0x34,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,0x74,0x65,0x72,0x6D, + 0x73,0x2E,0x68,0x74,0x6D,0x6C,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, + 0x30,0x48,0x04,0xA8,0x63,0x5A,0x7A,0xF9,0xEA,0x8B,0xF7,0x7F,0xF6,0x27,0x21,0x02, + 0xE2,0x83,0xC8,0x64,0x99,0xB3,0x40,0x71,0x97,0x30,0xE2,0x92,0xD4,0x58,0xB8,0xD8, + 0xF1,0xAA,0x30,0x59,0x75,0x4C,0x67,0x16,0xF8,0x38,0xBD,0xD7,0xF4,0xEA,0x03,0xB5, + 0xE6,0x42,0xF8,0x95,0xBA,0x5B,0xE4,0x3C,0xA8,0x75,0x6C,0x05,0xFB,0x3C,0x3C,0xE3, + 0x08,0x90,0x5F,0x6D,0x7E,0x3A,0xEA,0xBD,0x19,0x52,0x82,0x3B,0x9C,0x7F,0x64,0x15, + 0x3A,0xCA,0x54,0x52,0x57,0xEB,0x53,0x09,0xE8,0x05,0x53,0x79,0xB9,0x7D,0x51,0xA3, + 0x8E,0x31,0xF1,0xE5,0x5E,0xC6,0xA6,0x81,0x11,0x68,0x0A,0x17,0xD5,0xA0,0xBB,0x49, + 0xF3,0x4E,0x59,0x1D,0xCB,0xCA,0x3E,0x09,0x64,0x2F,0x27,0x6C,0xCA,0x39,0x50,0x73, + 0x42,0x5C,0x9D,0xE2,0x92,0x45,0x37,0x7F,0x02,0xF0,0x2B,0xA0,0xDD,0x1C,0x02,0xDC, + 0x77,0xA9,0x0C,0xEA,0x14,0xAE,0xDE,0x81,0xDF,0x3E,0x31,0x59,0xF6,0xF7,0xE5,0x7F, + 0xBC,0x7C,0xFD,0xE8,0x22,0xBE,0x9A,0x78,0xDD,0xFD,0x32,0x7F,0xE0,0xEC,0x0F,0x8D, + 0x4D,0xB5,0xDE,0xF6,0x91,0x4B,0xAD,0xDB,0x7D,0xF9,0x07,0xB8,0x2B,0x0E,0xB5,0x58, + 0x05,0xA2,0x85,0xF6,0x72,0x0E,0xCB,0x63,0x4E,0x8F,0xBF,0xD6,0x33,0x6F,0xF3,0xC2, + 0x53,0xFA,0x67,0x5D,0x19,0xA8,0x49,0x1C,0x05,0x5D,0xAF,0x6C,0xDC,0x14,0x37,0xD5, + 0x65,0x42,0x24,0x3B,0x69,0xC9,0x78,0x3F,0x4B,0x0E,0xAF,0x13,0x37,0x00,0x1E,0x6B, + 0xCE,0xB9,0xCC,0xAA,0x99,0x1A,0xB7,0x5A,0x27,0xB9,0xE9,0xD6,0x87,0x0A,0xEB,0x77, +}; + +static unsigned char pem[] = "\n" +"-----BEGIN CERTIFICATE-----\n" +"MIIDSzCCAjOgAwIBAgIJAPsB+wAAAAABMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNV\n" +"BAYTAlVTMRMwEQYDVQQKEwpBcHBsZSBJbmMuMSYwJAYDVQQLEx1BcHBsZSBDZXJ0\n" +"aWZpY2F0aW9uIEF1dGhvcml0eTEyMDAGA1UEAxMpQXBwbGUgU2VjdXJlIEJvb3Qg\n" +"Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDcwMTA2MDUyMDUyWhcNMTcwMTA2\n" +"MDUyMDUyWjB0MQswCQYDVQQGEwJVUzETMBEGA1UEChMKQXBwbGUgSW5jLjEyMDAG\n" +"A1UECxMpQXBwbGUgU2VjdXJlIEJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx\n" +"HDAaBgNVBAMTE1M1TDg5MDAgU2VjdXJlIEJvb3QwgZ8wDQYJKoZIhvcNAQEBBQAD\n" +"gY0AMIGJAoGBAMSrg/5uSm6EaOPbN2sedX5F31i+4x5BLd8cVbopszz/9OJZz/RD\n" +"tWbVkSh2O7PZbvfYwwHB6D3pebAA1S9rakwaKO7hKyKzHqpHeiqu+ECdmPGBRhFf\n" +"16zQL/pXzEnHn4IBfHcG5O49VqI8TK9pMZiqOQ4nh5H5mYIBImcaQ7frAgMBAAGj\n" +"WjBYMAsGA1UdDwQEAwIHgDAJBgNVHRMEAjAAMB0GA1UdDgQWBBQZ39dDpsNXFu2G\n" +"Qt2ylAihau3f3jAfBgNVHSMEGDAWgBRJPTZTydcV4YZhTqyrqxhWY13DxjANBgkq\n" +"hkiG9w0BAQUFAAOCAQEAlAHI8JncOxR8kSzIuN6jCY22DgiZYahvO7H3f68w3QO3\n" +"NE8Cp/UCECv+pQmlMuJPMAYzfLwGtoLhpq6BlCQXEc4KYhjGh5aicdXBkZDf+rA0\n" +"p1KphAd8c2UEIAWBbqU87q1FbDSJBw3YKN7C/I4qGnzUrWSpBbq6musM0QzO/uUZ\n" +"3R1QsfpicZ+nT/1WmlJSAwtoQsBjNAgMauhRLAJc/fCPi8TqONju/xxbGDYJ/cQs\n" +"bCGfszrUSeGYu4ryxeyNuu2L8gluHUKbhfZ7J1XYgIsvoCnk5E5hWJDhpIyywylb\n" +"9F/uRNib8zb0L80S64vAWC4m4QUJ3iLmTfIsk+NYPQ==\n" +"-----END CERTIFICATE-----\n"; + +static unsigned char _elektron_v1_cert_der[] = { + 0x30, 0x82, 0x02, 0x71, 0x30, 0x82, 0x01, 0xda, 0x02, 0x01, 0x01, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x30, 0x81, 0x80, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, + 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, + 0x55, 0x04, 0x08, 0x13, 0x02, 0x63, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, + 0x03, 0x55, 0x04, 0x07, 0x13, 0x08, 0x73, 0x61, 0x6e, 0x20, 0x6a, 0x6f, + 0x73, 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, + 0x04, 0x62, 0x72, 0x61, 0x64, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, + 0x04, 0x0b, 0x13, 0x1e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, + 0x20, 0x76, 0x32, 0x2e, 0x30, 0x2e, 0x31, 0x38, 0x35, 0x32, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x10, 0x62, 0x72, 0x61, + 0x64, 0x20, 0x45, 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x43, + 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x33, 0x31, 0x32, 0x32, 0x33, 0x31, + 0x31, 0x34, 0x36, 0x30, 0x37, 0x5a, 0x17, 0x0d, 0x31, 0x33, 0x31, 0x32, + 0x32, 0x32, 0x31, 0x31, 0x34, 0x36, 0x30, 0x37, 0x5a, 0x30, 0x81, 0x80, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, + 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x02, + 0x63, 0x61, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, + 0x08, 0x73, 0x61, 0x6e, 0x20, 0x6a, 0x6f, 0x73, 0x65, 0x31, 0x0d, 0x30, + 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x04, 0x62, 0x72, 0x61, 0x64, + 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1e, 0x50, + 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x45, + 0x6c, 0x65, 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x76, 0x32, 0x2e, 0x30, + 0x2e, 0x31, 0x38, 0x35, 0x32, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x13, 0x10, 0x62, 0x72, 0x61, 0x64, 0x20, 0x45, 0x6c, 0x65, + 0x6b, 0x74, 0x72, 0x6f, 0x6e, 0x20, 0x43, 0x41, 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, 0xe0, 0xab, 0x3a, 0x05, 0x8d, 0xed, 0x81, 0x73, 0xa8, 0x76, 0x9c, + 0x14, 0x07, 0x50, 0x4b, 0x56, 0x8f, 0xfe, 0x88, 0xba, 0xec, 0xde, 0xab, + 0x9a, 0x5d, 0x49, 0x23, 0x3b, 0x87, 0x4f, 0x50, 0x59, 0x8d, 0x0f, 0x78, + 0xd0, 0x61, 0x98, 0x28, 0x9d, 0x1d, 0x39, 0xbf, 0x92, 0x62, 0xda, 0x21, + 0xf7, 0xb1, 0x32, 0x6a, 0x5d, 0x73, 0x1c, 0x1d, 0x36, 0xba, 0xf7, 0x3c, + 0xff, 0xda, 0xd9, 0xff, 0xf0, 0xbd, 0x62, 0x1d, 0xde, 0x6d, 0xc7, 0x76, + 0x93, 0xdd, 0x3a, 0x90, 0x2b, 0x97, 0xab, 0x86, 0xea, 0x48, 0xb5, 0x70, + 0xe7, 0xe1, 0xa2, 0x5c, 0x61, 0x1a, 0x7d, 0x48, 0x4d, 0x83, 0x42, 0x73, + 0x70, 0xaf, 0x5d, 0xcf, 0x8c, 0x26, 0xb4, 0x83, 0xff, 0x77, 0xd5, 0x64, + 0xe0, 0x14, 0x52, 0x20, 0xa2, 0xe9, 0xc5, 0x8c, 0x70, 0xb5, 0x6f, 0xf5, + 0x6d, 0x31, 0x2b, 0xcb, 0x1d, 0xad, 0xf4, 0xb2, 0x27, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x05, 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x74, 0x49, 0x79, + 0x14, 0xc0, 0x68, 0xd7, 0x9d, 0xfd, 0x35, 0x6a, 0xda, 0xa0, 0x1d, 0x46, + 0x0a, 0xc6, 0x1b, 0x51, 0x4b, 0xdf, 0x27, 0xd6, 0x14, 0x1a, 0xcf, 0xf1, + 0xd0, 0xe2, 0x1b, 0x92, 0x39, 0x33, 0x98, 0x13, 0xc2, 0x6e, 0x97, 0xed, + 0x2b, 0x1b, 0xfc, 0x28, 0x8a, 0x93, 0xf9, 0xe5, 0xe1, 0xf0, 0xbf, 0xf8, + 0xa3, 0x5e, 0x08, 0x9c, 0x9f, 0x61, 0x7d, 0xb9, 0xe7, 0x14, 0x0e, 0x6d, + 0x07, 0x3e, 0x35, 0x12, 0xd4, 0x98, 0x2e, 0x0a, 0x9c, 0x5c, 0xb9, 0xbf, + 0x20, 0x29, 0x01, 0x55, 0x82, 0x86, 0xa7, 0xcb, 0x97, 0x8f, 0xbb, 0xd8, + 0x2b, 0xbd, 0x40, 0xd3, 0x1a, 0xa7, 0xb1, 0x66, 0x5c, 0xe5, 0x9a, 0x7b, + 0x39, 0xb7, 0x73, 0x49, 0x2c, 0x44, 0x8c, 0x79, 0x5b, 0xb5, 0x18, 0x41, + 0xd0, 0xf1, 0x4b, 0x6d, 0xc5, 0x1a, 0xf8, 0x51, 0xea, 0x99, 0x0d, 0x85, + 0x1b, 0xbe, 0x16, 0x56, 0x18 +}; + +static unsigned char _wapi_as_der[] = { + 0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0x6c, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x01, 0x12, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xd7, + 0x63, 0x01, 0x01, 0x01, 0x05, 0x00, 0x30, 0x1d, 0x31, 0x0c, 0x30, 0x0a, + 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, 0x4d, 0x43, 0x31, 0x0d, + 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, 0x57, 0x41, 0x50, + 0x49, 0x30, 0x1e, 0x17, 0x0d, 0x37, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x31, 0x38, 0x5a, 0x17, 0x0d, 0x39, 0x30, 0x30, 0x31, + 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x31, 0x38, 0x5a, 0x30, 0x1d, 0x31, + 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, 0x4d, + 0x43, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x04, + 0x57, 0x41, 0x50, 0x49, 0x30, 0x4a, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x09, 0x2a, 0x81, 0x1c, 0xd7, 0x63, + 0x01, 0x01, 0x02, 0x01, 0x03, 0x32, 0x00, 0x04, 0x74, 0xd9, 0x78, 0x91, + 0xc4, 0xd3, 0xb5, 0x9e, 0xb0, 0xa9, 0x9e, 0xf1, 0x01, 0x5b, 0xd7, 0x7f, + 0x79, 0x9a, 0x02, 0xe5, 0x87, 0x65, 0xa1, 0x0d, 0x04, 0xc9, 0x06, 0xdb, + 0xf6, 0x12, 0x24, 0x05, 0x9d, 0x1c, 0x51, 0x00, 0x75, 0x58, 0x46, 0x11, + 0xe3, 0xdc, 0x71, 0x02, 0x69, 0x43, 0x37, 0x61, 0xa3, 0x81, 0xa9, 0x30, + 0x81, 0xa6, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, + 0x14, 0x08, 0xa9, 0x47, 0x65, 0xf2, 0x39, 0xa9, 0xe8, 0x8b, 0xd1, 0x75, + 0x43, 0xce, 0x8c, 0x1c, 0xc0, 0xec, 0x99, 0xae, 0xad, 0x30, 0x45, 0x06, + 0x03, 0x55, 0x1d, 0x23, 0x04, 0x3e, 0x30, 0x3c, 0x80, 0x14, 0x08, 0xa9, + 0x47, 0x65, 0xf2, 0x39, 0xa9, 0xe8, 0x8b, 0xd1, 0x75, 0x43, 0xce, 0x8c, + 0x1c, 0xc0, 0xec, 0x99, 0xae, 0xad, 0xa1, 0x21, 0xa4, 0x1f, 0x30, 0x1d, + 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x54, + 0x4d, 0x43, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, + 0x04, 0x57, 0x41, 0x50, 0x49, 0x82, 0x01, 0x12, 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, 0x31, 0x39, + 0x32, 0x2e, 0x31, 0x36, 0x38, 0x2e, 0x31, 0x2e, 0x32, 0x30, 0x30, 0x3a, + 0x38, 0x30, 0x38, 0x30, 0x2f, 0x61, 0x73, 0x2e, 0x63, 0x72, 0x6c, 0x30, + 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, + 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x81, 0x1c, 0xd7, 0x63, 0x01, 0x01, 0x01, + 0x05, 0x00, 0x03, 0x37, 0x00, 0x30, 0x34, 0x02, 0x18, 0x23, 0xc5, 0x39, + 0xc9, 0x91, 0x89, 0x3d, 0xe5, 0xae, 0x95, 0x75, 0x88, 0x68, 0xf6, 0x11, + 0x64, 0xb1, 0x71, 0xe7, 0x67, 0x1f, 0xa1, 0x58, 0x77, 0x02, 0x18, 0x15, + 0xef, 0x5a, 0x62, 0x7f, 0x7d, 0x9d, 0x6e, 0x6d, 0x91, 0x2b, 0x61, 0x15, + 0x4d, 0x5a, 0xbe, 0xc8, 0x8d, 0xdc, 0x85, 0x00, 0xa9, 0x7d, 0x99 +}; + +/* subject:/DC=com/DC=outsidevpntest/CN=Users/CN=certxauthsplit */ +/* issuer :/DC=com/DC=outsidevpntest/CN=outsidevpntest-SERVER02-CA */ +static uint8_t two_common_names[1427]={ + 0x30,0x82,0x05,0x8F,0x30,0x82,0x04,0x77,0xA0,0x03,0x02,0x01,0x02,0x02,0x0A,0x45, + 0x0F,0xA6,0x09,0x00,0x00,0x00,0x00,0x00,0x16,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, + 0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x30,0x5A,0x31,0x13,0x30,0x11,0x06,0x0A, + 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x03,0x63,0x6F,0x6D,0x31, + 0x1E,0x30,0x1C,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16, + 0x0E,0x6F,0x75,0x74,0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x31, + 0x23,0x30,0x21,0x06,0x03,0x55,0x04,0x03,0x13,0x1A,0x6F,0x75,0x74,0x73,0x69,0x64, + 0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2D,0x53,0x45,0x52,0x56,0x45,0x52,0x30, + 0x32,0x2D,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x32,0x30,0x39,0x30,0x36,0x30,0x33, + 0x30,0x32,0x30,0x30,0x5A,0x17,0x0D,0x31,0x33,0x30,0x39,0x30,0x36,0x30,0x33,0x30, + 0x32,0x30,0x30,0x5A,0x30,0x5E,0x31,0x13,0x30,0x11,0x06,0x0A,0x09,0x92,0x26,0x89, + 0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x03,0x63,0x6F,0x6D,0x31,0x1E,0x30,0x1C,0x06, + 0x0A,0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,0x16,0x0E,0x6F,0x75,0x74, + 0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x31,0x0E,0x30,0x0C,0x06, + 0x03,0x55,0x04,0x03,0x13,0x05,0x55,0x73,0x65,0x72,0x73,0x31,0x17,0x30,0x15,0x06, + 0x03,0x55,0x04,0x03,0x13,0x0E,0x63,0x65,0x72,0x74,0x78,0x61,0x75,0x74,0x68,0x73, + 0x70,0x6C,0x69,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,0xB9,0xC7,0x0A,0x4A,0x2D,0xA4,0xD4,0x8F,0x0A,0xC3,0x49,0xDC,0xA0,0xE2,0x36, + 0x67,0x2E,0x0E,0xD2,0x02,0xA8,0x3B,0x23,0xDF,0xE4,0x67,0xCA,0x98,0xB9,0x37,0x10, + 0xF9,0x7D,0x76,0x40,0x3F,0xED,0xBE,0x0E,0x8C,0x3B,0x1A,0x91,0x61,0x37,0x5B,0x8E, + 0xDA,0xB5,0x98,0xD0,0x4A,0x2E,0x1B,0xB4,0xF8,0xBC,0xAB,0x5B,0x90,0xE7,0x46,0x3C, + 0xDC,0x62,0x0F,0xD0,0x97,0x28,0x15,0x91,0x2F,0xD5,0x33,0x63,0xA5,0x4F,0xD2,0x84, + 0x0D,0x7C,0xD0,0x8A,0x5B,0x20,0x23,0xF3,0xAA,0x1E,0xAC,0xB4,0x31,0xE3,0xAF,0x6C, + 0x51,0xBE,0xC1,0xBE,0xCE,0x12,0x34,0x6E,0x6D,0x09,0xB3,0x9D,0x88,0x6D,0x35,0x37, + 0xCB,0xDB,0x08,0xF3,0x55,0x98,0x62,0x75,0x93,0x6B,0x15,0xD0,0xF1,0xFC,0x59,0xB4, + 0x37,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02,0xD5,0x30,0x82,0x02,0xD1,0x30,0x0E, + 0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x05,0xA0,0x30,0x44, + 0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,0x04,0x37,0x30,0x35,0x30, + 0x0E,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02,0x02,0x02,0x00,0x80,0x30, + 0x0E,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04,0x02,0x02,0x00,0x80,0x30, + 0x07,0x06,0x05,0x2B,0x0E,0x03,0x02,0x07,0x30,0x0A,0x06,0x08,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x03,0x07,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xDD, + 0x63,0xE5,0xA8,0xBE,0x94,0x8D,0x3B,0xCF,0xDB,0x51,0x4A,0xAB,0x63,0xDC,0x5A,0x30, + 0x12,0x66,0x16,0x30,0x17,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02, + 0x04,0x0A,0x1E,0x08,0x00,0x55,0x00,0x73,0x00,0x65,0x00,0x72,0x30,0x1F,0x06,0x03, + 0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x13,0x9B,0xAB,0x61,0x39,0x5F,0x45, + 0x84,0xDB,0x37,0x72,0xD7,0xAC,0x67,0x19,0x26,0xBD,0x85,0x33,0xC0,0x30,0x81,0xE0, + 0x06,0x03,0x55,0x1D,0x1F,0x04,0x81,0xD8,0x30,0x81,0xD5,0x30,0x81,0xD2,0xA0,0x81, + 0xCF,0xA0,0x81,0xCC,0x86,0x81,0xC9,0x6C,0x64,0x61,0x70,0x3A,0x2F,0x2F,0x2F,0x43, + 0x4E,0x3D,0x6F,0x75,0x74,0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74, + 0x2D,0x53,0x45,0x52,0x56,0x45,0x52,0x30,0x32,0x2D,0x43,0x41,0x2C,0x43,0x4E,0x3D, + 0x73,0x65,0x72,0x76,0x65,0x72,0x30,0x32,0x2C,0x43,0x4E,0x3D,0x43,0x44,0x50,0x2C, + 0x43,0x4E,0x3D,0x50,0x75,0x62,0x6C,0x69,0x63,0x25,0x32,0x30,0x4B,0x65,0x79,0x25, + 0x32,0x30,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x53,0x65, + 0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x43,0x6F,0x6E,0x66,0x69,0x67, + 0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x44,0x43,0x3D,0x6F,0x75,0x74,0x73,0x69, + 0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2C,0x44,0x43,0x3D,0x63,0x6F,0x6D, + 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, + 0x6F,0x62,0x6A,0x65,0x63,0x74,0x43,0x6C,0x61,0x73,0x73,0x3D,0x63,0x52,0x4C,0x44, + 0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x69,0x6F,0x6E,0x50,0x6F,0x69,0x6E,0x74, + 0x30,0x81,0xD3,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x81,0xC6, + 0x30,0x81,0xC3,0x30,0x81,0xC0,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, + 0x86,0x81,0xB3,0x6C,0x64,0x61,0x70,0x3A,0x2F,0x2F,0x2F,0x43,0x4E,0x3D,0x6F,0x75, + 0x74,0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2D,0x53,0x45,0x52, + 0x56,0x45,0x52,0x30,0x32,0x2D,0x43,0x41,0x2C,0x43,0x4E,0x3D,0x41,0x49,0x41,0x2C, + 0x43,0x4E,0x3D,0x50,0x75,0x62,0x6C,0x69,0x63,0x25,0x32,0x30,0x4B,0x65,0x79,0x25, + 0x32,0x30,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x53,0x65, + 0x72,0x76,0x69,0x63,0x65,0x73,0x2C,0x43,0x4E,0x3D,0x43,0x6F,0x6E,0x66,0x69,0x67, + 0x75,0x72,0x61,0x74,0x69,0x6F,0x6E,0x2C,0x44,0x43,0x3D,0x6F,0x75,0x74,0x73,0x69, + 0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2C,0x44,0x43,0x3D,0x63,0x6F,0x6D, + 0x3F,0x63,0x41,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x65,0x3F,0x62, + 0x61,0x73,0x65,0x3F,0x6F,0x62,0x6A,0x65,0x63,0x74,0x43,0x6C,0x61,0x73,0x73,0x3D, + 0x63,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x41,0x75,0x74, + 0x68,0x6F,0x72,0x69,0x74,0x79,0x30,0x29,0x06,0x03,0x55,0x1D,0x25,0x04,0x22,0x30, + 0x20,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x03,0x04,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x03, + 0x02,0x30,0x3C,0x06,0x03,0x55,0x1D,0x11,0x04,0x35,0x30,0x33,0xA0,0x31,0x06,0x0A, + 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,0xA0,0x23,0x0C,0x21,0x63,0x65, + 0x72,0x74,0x78,0x61,0x75,0x74,0x68,0x73,0x70,0x6C,0x69,0x74,0x40,0x6F,0x75,0x74, + 0x73,0x69,0x64,0x65,0x76,0x70,0x6E,0x74,0x65,0x73,0x74,0x2E,0x63,0x6F,0x6D,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,0x05,0x00,0x03,0x82, + 0x01,0x01,0x00,0x98,0xD5,0x24,0x83,0x28,0xC0,0xB5,0xE2,0xF9,0x22,0xE6,0xED,0x9C, + 0xC8,0xFB,0x07,0xB0,0x23,0x16,0xD0,0x62,0x32,0xF4,0xCC,0x71,0x00,0x31,0x48,0x8A, + 0x5D,0xFA,0xDC,0x80,0x49,0x35,0x38,0x16,0x81,0xA8,0xA8,0x01,0x69,0xC1,0x64,0xD9, + 0x64,0x72,0xC4,0xB3,0x24,0x02,0x7C,0xB8,0xD9,0x92,0xAA,0x28,0xB0,0x87,0x63,0x73, + 0x21,0xD7,0x4D,0x68,0x2D,0x99,0xF5,0x9B,0x10,0xD1,0x6B,0xF3,0xF8,0x1B,0x7B,0x73, + 0x2E,0x06,0xF1,0x17,0xCA,0xEE,0xAA,0xD7,0x6B,0x14,0x72,0x2E,0xA5,0x3C,0xC3,0x4A, + 0xFA,0x1C,0x28,0x72,0x16,0x08,0x33,0xF7,0x94,0xA1,0x30,0x94,0x37,0xF0,0xB3,0xAF, + 0xA5,0x49,0xD1,0x87,0xEB,0xD7,0xA0,0x3F,0xA7,0xDA,0x4D,0x70,0xFD,0xA9,0x53,0x82, + 0x1B,0xA7,0x6A,0xC8,0x3A,0x9D,0x9C,0x09,0x4D,0xD5,0xB1,0x71,0xFC,0xC4,0xC6,0x9D, + 0x9F,0xC5,0x16,0x13,0x7F,0x53,0x7C,0x5E,0x83,0xB0,0x8F,0xFA,0x24,0x9F,0xD3,0x2A, + 0x64,0x7E,0xA2,0x98,0x30,0x5B,0x7F,0x41,0x6C,0xE3,0xD4,0xE8,0x1E,0x18,0x2A,0x83, + 0x05,0x0F,0x0C,0x6A,0xF6,0x03,0xEB,0xF9,0x77,0x67,0xB9,0x4C,0xF7,0x98,0x45,0xC6, + 0x52,0x7E,0xF0,0xFA,0xAD,0x96,0xCC,0xA3,0x19,0xA7,0xF5,0x06,0x35,0x28,0x5E,0xE4, + 0xAC,0x8E,0x06,0x32,0xCC,0xEB,0xA6,0x0C,0x39,0xD3,0xF8,0xCF,0xA5,0xEC,0x87,0x74, + 0x58,0xFA,0xBE,0xB7,0x89,0xA3,0x4A,0xD6,0x62,0x9D,0x3E,0x37,0x5E,0x1E,0xC1,0x9F, + 0xBC,0xE0,0xF7,0x86,0xE2,0x6D,0xFF,0x71,0x9B,0x93,0xA8,0xEE,0xD8,0xA0,0x8C,0x1B, + 0x99,0x58,0xFC, +}; + +const uint8_t mail_google_com [] = { + 0x30, 0x82, 0x03, 0x22, 0x30, 0x82, 0x02, 0x8b, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x10, 0x2b, 0x9f, 0x7e, 0xe5, 0xca, 0x25, 0xa6, 0x25, 0x14, + 0x20, 0x47, 0x82, 0x75, 0x3a, 0x9b, 0xb9, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4c, + 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x5a, + 0x41, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x1c, + 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x75, + 0x6c, 0x74, 0x69, 0x6e, 0x67, 0x20, 0x28, 0x50, 0x74, 0x79, 0x29, 0x20, + 0x4c, 0x74, 0x64, 0x2e, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x13, 0x0d, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, 0x20, 0x53, 0x47, + 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x31, 0x31, 0x30, + 0x32, 0x36, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x17, 0x0d, 0x31, + 0x33, 0x30, 0x39, 0x33, 0x30, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, + 0x30, 0x69, 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, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x14, 0x0d, 0x4d, + 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x56, 0x69, 0x65, 0x77, + 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x0a, 0x47, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x31, 0x18, 0x30, + 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x14, 0x0f, 0x6d, 0x61, 0x69, 0x6c, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 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, 0xaf, 0x39, 0x15, 0x98, 0x68, 0xe4, 0x92, 0xfe, + 0x4f, 0x4f, 0xf1, 0xbb, 0xff, 0x0d, 0x2e, 0xb0, 0xfe, 0x25, 0xaa, 0xbd, + 0x68, 0x04, 0x67, 0x27, 0xea, 0x6c, 0x43, 0x4c, 0xa7, 0x6d, 0xcb, 0xc8, + 0x8f, 0x7e, 0x81, 0xee, 0x87, 0x26, 0x25, 0x10, 0x12, 0x54, 0x33, 0x9e, + 0xaa, 0x3d, 0x9b, 0x8f, 0x8e, 0x92, 0xb3, 0x4b, 0x01, 0xe3, 0xf9, 0x4a, + 0x29, 0xc3, 0x0f, 0xfd, 0xac, 0xb7, 0xd3, 0x4c, 0x97, 0x29, 0x3f, 0x69, + 0x55, 0xcf, 0x70, 0x83, 0x04, 0xaf, 0x2e, 0x04, 0x6e, 0x74, 0xd6, 0x0f, + 0x17, 0x09, 0xfe, 0x9e, 0x20, 0x24, 0x24, 0xe3, 0xc7, 0x68, 0x9c, 0xac, + 0x11, 0xbd, 0x92, 0xe4, 0xb2, 0x1b, 0x09, 0xf2, 0x02, 0x32, 0xbb, 0x55, + 0x1b, 0x2d, 0x16, 0x5f, 0x30, 0x12, 0x23, 0xe2, 0x4c, 0x4a, 0x8d, 0xc2, + 0xda, 0x3f, 0xe1, 0xb8, 0xbf, 0xf7, 0x3a, 0xb1, 0x86, 0xbe, 0xf0, 0xc5, + 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xe7, 0x30, 0x81, 0xe4, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, + 0x00, 0x30, 0x36, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x2f, 0x30, 0x2d, + 0x30, 0x2b, 0xa0, 0x29, 0xa0, 0x27, 0x86, 0x25, 0x68, 0x74, 0x74, 0x70, + 0x3a, 0x2f, 0x2f, 0x63, 0x72, 0x6c, 0x2e, 0x74, 0x68, 0x61, 0x77, 0x74, + 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, + 0x53, 0x47, 0x43, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x28, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x21, 0x30, 0x1f, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x07, 0x03, 0x02, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, + 0x42, 0x04, 0x01, 0x30, 0x72, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, + 0x07, 0x01, 0x01, 0x04, 0x66, 0x30, 0x64, 0x30, 0x22, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 0x73, 0x70, 0x2e, 0x74, 0x68, 0x61, + 0x77, 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x3e, 0x06, 0x08, 0x2b, + 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, 0x86, 0x32, 0x68, 0x74, 0x74, + 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x74, 0x68, 0x61, 0x77, + 0x74, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x2f, 0x54, 0x68, 0x61, 0x77, 0x74, 0x65, + 0x5f, 0x53, 0x47, 0x43, 0x5f, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x74, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x35, 0x80, 0x11, 0xcd, 0x52, 0x3e, + 0x84, 0x29, 0xfb, 0xc1, 0x28, 0xe1, 0x20, 0xe5, 0x02, 0x8f, 0x5f, 0x71, + 0x65, 0x58, 0x1d, 0x62, 0x72, 0x57, 0x3c, 0xe6, 0x5e, 0x25, 0x61, 0xd3, + 0xcb, 0xad, 0x22, 0xf8, 0xd8, 0x81, 0xa4, 0xe7, 0xf4, 0xae, 0x7c, 0xd9, + 0xc1, 0x6d, 0xaa, 0x93, 0x0d, 0x62, 0x07, 0x9f, 0xf2, 0x67, 0x47, 0x99, + 0x34, 0x33, 0x4f, 0x3d, 0x02, 0x74, 0xf4, 0x81, 0xd6, 0x38, 0x08, 0x21, + 0xe8, 0xe2, 0xa1, 0xfa, 0x05, 0x41, 0x9c, 0x9c, 0xc9, 0xf9, 0xf3, 0xc8, + 0xa3, 0xee, 0x0d, 0xa5, 0xd7, 0x50, 0x54, 0x5e, 0x2f, 0x7d, 0x79, 0xb7, + 0x7e, 0x0a, 0x7c, 0xb6, 0xe2, 0x2c, 0xa8, 0xae, 0xfe, 0x94, 0xd7, 0xcd, + 0x16, 0x30, 0x71, 0x04, 0xaa, 0x9e, 0x79, 0xc3, 0xd2, 0xb6, 0x24, 0xa7, + 0x25, 0xab, 0xf0, 0x48, 0x8e, 0x2f, 0xc3, 0xa7, 0xbb, 0x50, 0xdd, 0x0f, + 0xcf, 0xb0, +}; + +/* test CT log key ids */ + +#define CTLOG_KEYID_LENGTH 32 /* key id data length */ +#define CTLOG_KEYID_COUNT 3 /* number of key ids in test array */ + +const uint8_t _ctlogids[CTLOG_KEYID_COUNT][CTLOG_KEYID_LENGTH] = { + {/* Google */ + 0xBB,0xD9,0xDF,0xBC,0x1F,0x8A,0x71,0xB5,0x93,0x94,0x23,0x97,0xAA,0x92,0x7B,0x47, + 0x38,0x57,0x95,0x0A,0xAB,0x52,0xE8,0x1A,0x90,0x96,0x64,0x36,0x8E,0x1E,0xD1,0x85, + }, + { /* Google */ + 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, + }, + { /* DigiCert */ + 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, + }, +}; + +/* subject:/UID=372S63A2R8/CN=Developer ID Application: John Brayton/OU=372S63A2R8/O=John Brayton/C=US */ +/* issuer :/CN=Developer ID Certification Authority/OU=Apple Certification Authority/O=Apple Inc./C=US */ +const uint8_t _old_developer_cert[] = { + 0x30,0x82,0x05,0x65,0x30,0x82,0x04,0x4D,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x3B, + 0x8B,0xC9,0x83,0xCC,0x57,0x54,0x95,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,0x32,0x30,0x34,0x32,0x31,0x31,0x39,0x33,0x39,0x33, + 0x30,0x5A,0x17,0x0D,0x31,0x37,0x30,0x34,0x32,0x32,0x31,0x39,0x33,0x39,0x33,0x30, + 0x5A,0x30,0x81,0x86,0x31,0x1A,0x30,0x18,0x06,0x0A,0x09,0x92,0x26,0x89,0x93,0xF2, + 0x2C,0x64,0x01,0x01,0x0C,0x0A,0x33,0x37,0x32,0x53,0x36,0x33,0x41,0x32,0x52,0x38, + 0x31,0x2F,0x30,0x2D,0x06,0x03,0x55,0x04,0x03,0x0C,0x26,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,0x4A,0x6F,0x68,0x6E,0x20,0x42,0x72,0x61,0x79,0x74,0x6F, + 0x6E,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0A,0x33,0x37,0x32,0x53, + 0x36,0x33,0x41,0x32,0x52,0x38,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x0A,0x0C, + 0x0C,0x4A,0x6F,0x68,0x6E,0x20,0x42,0x72,0x61,0x79,0x74,0x6F,0x6E,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,0xDE,0x02,0xD5,0xBC,0x79, + 0x03,0x44,0x44,0xA0,0xCC,0x53,0xB9,0x4D,0xF6,0xF7,0x59,0xCF,0xA4,0x71,0x8A,0x20, + 0x72,0xA2,0x60,0xEA,0x45,0x26,0x52,0x39,0xA7,0xBD,0xFF,0x0A,0x45,0x0E,0xA2,0xE4, + 0x42,0x8C,0x0D,0x4B,0xF5,0x96,0x73,0xB3,0x56,0x0E,0xAA,0x2B,0x3F,0xBB,0x69,0x93, + 0xD5,0xC1,0x20,0xF2,0x40,0x38,0xB6,0x6C,0xB1,0xA0,0x4C,0x1B,0xA6,0xF1,0xE5,0x34, + 0xD4,0xD8,0xB0,0xF0,0x34,0x8C,0x2B,0xA4,0xBF,0x1E,0x8F,0x64,0xF0,0x25,0x9F,0x5D, + 0x65,0x1E,0x61,0xBA,0x63,0x68,0x16,0x67,0xDE,0x0B,0x76,0x25,0xFD,0xAF,0xB3,0xBF, + 0x1D,0xEA,0x82,0x85,0xE5,0x80,0xC7,0x62,0x1B,0x17,0xB3,0x5E,0x56,0xEA,0xD4,0x39, + 0x9C,0xA7,0x39,0x9B,0x1F,0xAD,0xD7,0xE1,0x7D,0x71,0x48,0xE5,0x19,0x53,0x98,0x6A, + 0x01,0x14,0x21,0x53,0xE4,0x69,0x69,0x3F,0xF3,0xC0,0x6C,0x2D,0x82,0x78,0x63,0x4E, + 0xAA,0xE4,0x0C,0xEF,0xC3,0x99,0x53,0xCA,0x1A,0x08,0xF4,0x95,0x48,0x23,0x8F,0xC9, + 0x13,0xCA,0xA7,0x0C,0xDC,0xB8,0x34,0x67,0x46,0x68,0x72,0x04,0x7E,0x17,0xC1,0x73, + 0x38,0x21,0xB8,0x52,0x35,0x3F,0x15,0x4D,0x60,0x82,0x63,0xEE,0x37,0xCC,0xF6,0x1F, + 0xF8,0xBC,0xA3,0xF6,0x1F,0xE1,0x9F,0x45,0xFA,0x5A,0xF6,0xC1,0x06,0x16,0xF8,0x03, + 0x84,0x7E,0x2F,0xE3,0x0D,0xEC,0x3E,0x05,0xF5,0xC0,0x0C,0x57,0x84,0x4C,0xCB,0x25, + 0x81,0x4C,0x59,0x2C,0xDC,0x63,0xA7,0xA0,0xA6,0x6C,0xC3,0xDC,0x7F,0x1E,0xAA,0x1E, + 0xD8,0x31,0x7D,0x08,0x8C,0x2F,0x85,0xB9,0x09,0xFF,0xD9,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,0xB1,0x95,0xE5,0x40,0x5D,0xE0,0x7B,0x76,0xF6,0x2B,0xD4,0x5B,0x16, + 0x6F,0x90,0x52,0x43,0x9C,0x8E,0xEA,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,0x53,0x09,0xBD,0xA3,0xB5,0xE0,0x63, + 0x49,0x02,0x71,0x3C,0x3A,0xF3,0xC9,0x08,0xF0,0xF9,0xCA,0x4E,0x70,0xD4,0x8D,0x3F, + 0xE5,0x9C,0x67,0xED,0x49,0xB4,0x7C,0xA3,0x5D,0x44,0xDE,0xF0,0x48,0xB9,0xDD,0x54, + 0x4F,0x56,0x7D,0xFD,0x08,0x14,0x3C,0x15,0xB8,0xFF,0x54,0x23,0x9A,0x48,0xC5,0x6C, + 0x48,0x72,0xE4,0x30,0xA6,0xC6,0xE8,0x42,0x62,0x29,0xA5,0x13,0x72,0x1C,0x04,0x6C, + 0x91,0x92,0xC3,0x3A,0x53,0x0A,0x52,0xDC,0x26,0x88,0xDE,0x42,0xA1,0x57,0xC2,0x03, + 0x3A,0xD7,0xE3,0x9B,0x2A,0x1F,0x48,0x65,0xFD,0x7F,0x81,0xEF,0x8E,0x39,0x64,0xB8, + 0x36,0x2B,0x60,0xCC,0x6A,0x50,0x0C,0x79,0xAD,0x75,0xD2,0x44,0x43,0xA1,0x31,0x5A, + 0x27,0xEC,0xB1,0xF5,0xC2,0x32,0x0D,0x35,0xF8,0x70,0x45,0x66,0xA3,0x6A,0x29,0x1F, + 0x60,0x7E,0xEE,0x34,0xF7,0x0F,0xBE,0x23,0x1D,0x97,0x3F,0x6C,0xE4,0xA6,0xF6,0x59, + 0x73,0x51,0x1B,0x13,0x38,0x04,0x98,0x59,0x8F,0xBF,0x8D,0xB8,0x0E,0xC7,0x57,0x00, + 0x8D,0x14,0x3A,0xA5,0xD9,0x4F,0xD9,0x4E,0xFF,0x75,0x83,0x15,0xA6,0x0E,0x1A,0xD3, + 0x0D,0xBC,0x0B,0x7E,0x99,0x3A,0xB9,0x73,0xAE,0x84,0x49,0xEE,0x8B,0x26,0x8E,0xD3, + 0xE9,0x36,0xCD,0xAD,0xC1,0xA9,0x00,0xC0,0x91,0x8B,0x3E,0x7E,0x7B,0x25,0x7F,0x7F, + 0x0D,0x4B,0xA4,0xE4,0xAD,0x67,0x4D,0x6A,0xF1,0xF7,0xF4,0xC0,0x5F,0x4B,0x9A,0xB4, + 0x2D,0x9B,0x91,0x3B,0x5A,0x67,0x9B,0xC5,0x64,0x99,0x04,0xA0,0x01,0xCF,0x52,0xE0, + 0xBB,0xA1,0xC9,0xDD,0xD6,0x75,0x2E,0xE8,0x04, +}; + +/* subject:/UID=PV45XFU466/CN=Developer ID Application: T Solanki (PV45XFU466)/OU=PV45XFU466/O=T Solanki/C=US */ +/* issuer :/C=US/O=Apple Inc./OU=Apple Certification Authority/CN=Test Apple Caspian Certification Authority */ +const uint8_t _new_developer_cert[] = { + 0x30,0x82,0x05,0xBF,0x30,0x82,0x04,0xA7,0xA0,0x03,0x02,0x01,0x02,0x02,0x08,0x69, + 0x87,0x9F,0x89,0x35,0xB9,0x9C,0xD7,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,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,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,0x33,0x30,0x31,0x06,0x03,0x55,0x04,0x03,0x0C,0x2A,0x54,0x65,0x73, + 0x74,0x20,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x61,0x73,0x70,0x69,0x61,0x6E,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,0x39,0x30,0x33,0x30, + 0x35,0x32,0x32,0x30,0x32,0x32,0x31,0x5A,0x17,0x0D,0x32,0x34,0x30,0x33,0x30,0x35, + 0x32,0x32,0x30,0x32,0x32,0x31,0x5A,0x30,0x81,0x8D,0x31,0x1A,0x30,0x18,0x06,0x0A, + 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,0x0C,0x0A,0x50,0x56,0x34,0x35, + 0x58,0x46,0x55,0x34,0x36,0x36,0x31,0x39,0x30,0x37,0x06,0x03,0x55,0x04,0x03,0x0C, + 0x30,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,0x54,0x20,0x53,0x6F,0x6C, + 0x61,0x6E,0x6B,0x69,0x20,0x28,0x50,0x56,0x34,0x35,0x58,0x46,0x55,0x34,0x36,0x36, + 0x29,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0B,0x0C,0x0A,0x50,0x56,0x34,0x35, + 0x58,0x46,0x55,0x34,0x36,0x36,0x31,0x12,0x30,0x10,0x06,0x03,0x55,0x04,0x0A,0x0C, + 0x09,0x54,0x20,0x53,0x6F,0x6C,0x61,0x6E,0x6B,0x69,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,0xC8,0xA7,0xFD,0xE0,0x5C,0xBD,0x35,0x6D, + 0x73,0x44,0xE1,0x9A,0xDA,0x70,0xE9,0x6E,0x99,0xDB,0x9C,0x0A,0x47,0x9B,0x71,0xBC, + 0xCF,0xE2,0x2A,0x1D,0x6C,0x11,0x5A,0x45,0x27,0xD5,0x3B,0x42,0x4C,0x1B,0xE2,0x43, + 0x5D,0xCA,0x37,0x48,0xB1,0xCD,0xA5,0xDC,0x2B,0x46,0xE9,0xD5,0xEE,0xCE,0xE1,0xF2, + 0x9C,0xD0,0x55,0x14,0x42,0x7A,0x9A,0xFB,0x2C,0xF0,0x20,0xD5,0x53,0x6B,0x3E,0x76, + 0x45,0x59,0xB6,0x16,0x41,0x52,0x61,0x64,0x2E,0xFA,0x69,0x43,0x95,0xD7,0x75,0x63, + 0x24,0xF8,0xFD,0x62,0x99,0xE9,0x5B,0xF8,0x72,0xE9,0x85,0x06,0x73,0x60,0x9C,0x83, + 0xD7,0xD6,0x1D,0xEC,0xC5,0x85,0x48,0xE0,0x55,0x71,0xFE,0xE0,0x54,0xAF,0x06,0xE7, + 0xD6,0x39,0x87,0xFB,0x5A,0xE7,0x7F,0x02,0x7C,0x80,0x2B,0x8B,0xA6,0x6A,0x06,0xF0, + 0xBE,0xDF,0xB3,0x1D,0x4D,0x40,0x9F,0x05,0x36,0x55,0xA4,0x09,0x58,0xB1,0xD2,0xB8, + 0xC0,0x8B,0xDE,0x25,0xD8,0xEB,0x80,0x07,0x34,0x64,0xE5,0x77,0x9A,0x39,0xD6,0xE1, + 0x7F,0x8A,0xF2,0xE4,0x56,0x15,0x84,0xB2,0x8A,0x54,0x31,0xCB,0xC3,0xAD,0xB6,0x63, + 0x72,0x64,0x53,0x8F,0xE5,0x74,0xD3,0xAA,0x91,0x0D,0xF0,0xEF,0x03,0x24,0x21,0x8C, + 0x0D,0x45,0xE4,0x18,0x0E,0xE0,0xDB,0x8C,0x20,0xF1,0x4A,0xD6,0x8B,0x60,0x84,0x3D, + 0x14,0x0D,0xCA,0x46,0x20,0x1F,0x13,0x07,0x7E,0x23,0x90,0x5B,0x8F,0xCF,0xD0,0x1E, + 0x48,0x56,0xF5,0xED,0xF3,0x96,0x52,0x03,0x40,0xF7,0x47,0x4A,0xAF,0xD0,0x67,0x0F, + 0xC1,0x5F,0xB1,0xA8,0xCD,0x29,0xDD,0x91,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x02, + 0x2E,0x30,0x82,0x02,0x2A,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, + 0xF8,0x7A,0x23,0x8A,0xD2,0xE7,0xD2,0xDF,0x21,0xDB,0x7A,0xF4,0x12,0x31,0x6E,0x28, + 0xF6,0xF9,0xF0,0x8E,0x30,0x49,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, + 0x04,0x3D,0x30,0x3B,0x30,0x39,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, + 0x86,0x2D,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,0x64,0x65,0x76,0x69,0x64,0x30,0x39,0x30, + 0x82,0x01,0x1D,0x06,0x03,0x55,0x1D,0x20,0x04,0x82,0x01,0x14,0x30,0x82,0x01,0x10, + 0x30,0x82,0x01,0x0C,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x05,0x01,0x30, + 0x81,0xFE,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,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,0x16,0x06,0x03,0x55,0x1D,0x25,0x01,0x01,0xFF,0x04,0x0C,0x30,0x0A,0x06,0x08, + 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, + 0x16,0x04,0x14,0x6A,0x2A,0x84,0xE8,0xAF,0x4B,0x33,0x37,0xB3,0x09,0xD5,0x8D,0x49, + 0x5B,0xF1,0xA9,0x3D,0x6E,0xCD,0x71,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, + 0xFF,0x04,0x04,0x03,0x02,0x07,0x80,0x30,0x13,0x06,0x0A,0x2A,0x86,0x48,0x86,0xF7, + 0x63,0x64,0x06,0x01,0x0D,0x01,0x01,0xFF,0x04,0x02,0x05,0x00,0x30,0x1F,0x06,0x0A, + 0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x01,0x21,0x04,0x11,0x0C,0x0F,0x32,0x30, + 0x31,0x39,0x30,0x33,0x30,0x35,0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x30,0x10,0x06, + 0x0A,0x2A,0x86,0x48,0x86,0xF7,0x63,0x64,0x06,0x01,0x20,0x04,0x02,0x05,0x00,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82, + 0x01,0x01,0x00,0x64,0x2D,0x1E,0xE4,0x1A,0x98,0xEF,0x62,0xF9,0xD8,0xEE,0xF8,0xCA, + 0x87,0xD7,0x71,0x55,0xDB,0x0D,0x9E,0x8F,0xDE,0x6E,0xBA,0x7D,0xBE,0xE7,0x2E,0xE3, + 0x48,0x09,0x09,0x11,0x54,0x3C,0x6F,0x79,0x61,0xF6,0x18,0xAB,0xE6,0xF4,0x87,0x59, + 0x20,0x97,0xC3,0xC2,0x47,0x25,0x03,0x47,0xA0,0xD6,0x95,0x08,0x67,0xA4,0x25,0xB1, + 0x94,0x0A,0x17,0x90,0xA7,0x64,0xD1,0xB6,0x35,0x59,0xF8,0x9D,0x0E,0x1E,0xF2,0x5D, + 0x2A,0x68,0x90,0x30,0xDF,0xC0,0xF6,0xBE,0x82,0x96,0x9C,0x26,0xAA,0x23,0xFB,0x05, + 0xC0,0xC2,0xE5,0xED,0x91,0xEF,0x44,0x93,0xC2,0x1D,0x53,0xE8,0x73,0xB7,0xBC,0xDB, + 0x3F,0x06,0x19,0xE5,0x40,0x2A,0xA2,0xE0,0x6F,0xA7,0xF7,0x08,0xB5,0xCB,0x90,0x19, + 0x4E,0x94,0xCF,0xD0,0x06,0x90,0xD7,0x60,0x2A,0x12,0x8A,0x54,0xE7,0x0B,0x67,0xEA, + 0x7B,0x02,0x42,0xAF,0xFE,0xA0,0x70,0x0D,0x7E,0xC6,0x28,0x96,0x41,0x55,0x34,0x83, + 0x5A,0x8C,0xBB,0x85,0x67,0xBC,0x0F,0x18,0x81,0x22,0xA4,0x66,0xCA,0x17,0x54,0xF3, + 0x2D,0xFE,0xBE,0xC7,0xAC,0x21,0x7A,0x6A,0x52,0x2E,0xAD,0x45,0x8B,0x39,0xF7,0x57, + 0x67,0x35,0x86,0xB8,0x3C,0x78,0x40,0xE0,0x28,0xD5,0xE9,0x80,0xA2,0xC2,0x07,0xFA, + 0xAC,0x63,0x1B,0xB6,0x8B,0x47,0xAB,0xC4,0xF1,0x29,0x75,0xE4,0x18,0xF6,0xBB,0x5E, + 0x37,0xD9,0x20,0xEA,0x1F,0xBD,0xA2,0xB6,0x1D,0x22,0x67,0x7C,0x13,0x6D,0xFD,0x91, + 0x01,0x34,0x43,0xB8,0xAA,0x8D,0xEA,0x1A,0xB0,0x31,0xCE,0xF1,0xCB,0x0B,0xC4,0x38, + 0xA4,0x85,0x74, +}; + +#endif /* _TRUSTTESTS_CERTIFICATE_INTERFACE_H_ */ diff --git a/tests/TrustTests/FrameworkTests/CertificateParseTests.m b/tests/TrustTests/FrameworkTests/CertificateParseTests.m new file mode 100644 index 00000000..a1a30b67 --- /dev/null +++ b/tests/TrustTests/FrameworkTests/CertificateParseTests.m @@ -0,0 +1,132 @@ +/* + * 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 +#include "../TestMacroConversions.h" + +#include "TrustFrameworkTestCase.h" + +const NSString *kSecTestParseFailureResources = @"si-18-certificate-parse/ParseFailureCerts"; +const NSString *kSecTestParseSuccessResources = @"si-18-certificate-parse/ParseSuccessCerts"; +const NSString *kSecTestKeyFailureResources = @"si-18-certificate-parse/KeyFailureCerts"; +const NSString *kSecTestTODOFailureResources = @"si-18-certificate-parse/TODOFailureCerts"; +const NSString *kSecTestExtensionFailureResources = @"si-18-certificate-parse/ExtensionFailureCerts"; + +@interface CertificateParseTests : TrustFrameworkTestCase + +@end + +@implementation CertificateParseTests + +- (void)testParseFailure { + /* A bunch of certificates with different parsing errors */ + NSArray * certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseFailureResources]; + XCTAssertTrue([certURLs count] > 0, "Unable to find parse test failure certs in bundle."); + + if ([certURLs count] > 0) { + [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); + is(cert, NULL, "Successfully parsed bad cert: %@", url); + CFReleaseNull(cert); + }]; + } +} + +- (void)testParseSuccess { + /* A bunch of certificates with different parsing variations */ + NSArray * certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestParseSuccessResources]; + XCTAssertTrue([certURLs count] > 0, "Unable to find parse test success certs in bundle."); + + if ([certURLs count] > 0) { + [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); + isnt(cert, NULL, "Failed to parse good cert: %@", url); + is(SecCertificateGetUnparseableKnownExtension(cert), kCFNotFound, "Found bad extension in good certs: %@", url); + CFReleaseNull(cert); + }]; + } +} + +- (void)testKeyFailure { + /* Parse failures that require public key extraction */ + NSArray * certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestKeyFailureResources]; + XCTAssertTrue([certURLs count] > 0, "Unable to find parse test key failure certs in bundle."); + + if ([certURLs count] > 0) { + [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); + SecKeyRef pubkey = NULL; + require_action(cert, blockOut, + fail("Failed to parse cert with SPKI error: %@", url)); + pubkey = SecCertificateCopyKey(cert); + is(pubkey, NULL, "Successfully parsed bad SPKI: %@", url); + + blockOut: + CFReleaseNull(cert); + CFReleaseNull(pubkey); + }]; + } +} + +- (void)testTODOFailures { + /* A bunch of certificates with different parsing errors that currently succeed. */ + NSArray * certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestTODOFailureResources]; + XCTAssertTrue([certURLs count] > 0, "Unable to find parse test TODO failure certs in bundle."); + + if ([certURLs count] > 0) { + [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); + isnt(cert, NULL, "Successfully parsed bad TODO cert: %@", url); + CFReleaseNull(cert); + }]; + } +} + +- (void)testUnparseableExtensions { + /* A bunch of certificates with different parsing errors in known (but non-critical) extensions */ + NSArray * certURLs = [[NSBundle bundleForClass:[self class]]URLsForResourcesWithExtension:@".cer" subdirectory:(NSString *)kSecTestExtensionFailureResources]; + XCTAssertTrue([certURLs count] > 0, "Unable to find parse test extension failure certs in bundle."); + + if ([certURLs count] > 0) { + [certURLs enumerateObjectsUsingBlock:^(NSURL *url, __unused NSUInteger idx, __unused BOOL *stop) { + NSData *certData = [NSData dataWithContentsOfURL:url]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certData); + isnt(cert, NULL, "Failed to parse bad cert with unparseable extension: %@", url); + isnt(SecCertificateGetUnparseableKnownExtension(cert), kCFNotFound, "Unable to find unparseable extension: %@", url); + CFReleaseNull(cert); + }]; + } +} + +@end diff --git a/tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.h b/tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.h new file mode 100644 index 00000000..c0dcf38e --- /dev/null +++ b/tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.h @@ -0,0 +1,31 @@ +/* + * 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 _TRUSTTESTS_FRAMEWORK_TESTCASE_H_ +#define _TRUSTTESTS_FRAMEWORK_TESTCASE_H_ + +@interface TrustFrameworkTestCase : XCTestCase +@end + +#endif /* _TRUSTTESTS_FRAMEWORK_TESTCASE_H_ */ diff --git a/tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.m b/tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.m new file mode 100644 index 00000000..fdcc100b --- /dev/null +++ b/tests/TrustTests/FrameworkTests/TrustFrameworkTestCase.m @@ -0,0 +1,37 @@ +/* + * 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 "TrustFrameworkTestCase.h" +#include "../../../OSX/sec/ipc/securityd_client.h" + + +@implementation TrustFrameworkTestCase + ++ (void)setUp { + /* XPC to trustd instead of using trustd built-in */ + gTrustd = NULL; +} + +@end diff --git a/tests/TrustTests/FrameworkTests/TrustInterfaceTests.m b/tests/TrustTests/FrameworkTests/TrustInterfaceTests.m new file mode 100644 index 00000000..e44c6c2d --- /dev/null +++ b/tests/TrustTests/FrameworkTests/TrustInterfaceTests.m @@ -0,0 +1,894 @@ +/* + * 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 "OSX/utilities/SecCFWrappers.h" +#include "OSX/utilities/array_size.h" +#include "OSX/sec/ipc/securityd_client.h" + +#include "../TestMacroConversions.h" +#include "../TrustEvaluationTestHelpers.h" +#include "TrustFrameworkTestCase.h" +#include "TrustInterfaceTests_data.h" + +@interface TrustInterfaceTests : TrustFrameworkTestCase +@end + +@implementation TrustInterfaceTests + +- (void)testCreateWithCertificates { + SecTrustRef trust = NULL; + CFArrayRef certs = NULL; + SecCertificateRef cert0 = NULL, cert1 = NULL; + SecPolicyRef policy = NULL; + + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), + NULL, "create cert0"); + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create cert1"); + const void *v_certs[] = { cert0, cert1 }; + + certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), &kCFTypeArrayCallBacks); + policy = SecPolicyCreateSSL(false, NULL); + + /* SecTrustCreateWithCertificates failures. */ + is_status(SecTrustCreateWithCertificates(kCFBooleanTrue, policy, &trust), + errSecParam, "create trust with boolean instead of cert"); + is_status(SecTrustCreateWithCertificates(cert0, kCFBooleanTrue, &trust), + errSecParam, "create trust with boolean instead of policy"); + + NSArray *badValues = @[ [NSData dataWithBytes:_c0 length:sizeof(_c0)], [NSData dataWithBytes:_c1 length:sizeof(_c1)]]; + XCTAssert(errSecParam == SecTrustCreateWithCertificates((__bridge CFArrayRef)badValues, policy, &trust), + "create trust with array of datas instead of certs"); + XCTAssert(errSecParam == SecTrustCreateWithCertificates(certs, (__bridge CFArrayRef)badValues, &trust), + "create trust with array of datas instead of policies"); + + /* SecTrustCreateWithCertificates using array of certs. */ + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); + + CFReleaseNull(trust); + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(certs); + CFReleaseNull(policy); +} + +- (void)testGetCertificate { + SecTrustRef trust = NULL; + CFArrayRef certs = NULL; + SecCertificateRef cert0 = NULL, cert1 = NULL; + SecPolicyRef policy = NULL; + + isnt(cert0 = SecCertificateCreateWithBytes(NULL, _c0, sizeof(_c0)), + NULL, "create cert0"); + isnt(cert1 = SecCertificateCreateWithBytes(NULL, _c1, sizeof(_c1)), + NULL, "create cert1"); + const void *v_certs[] = { cert0, cert1 }; + + certs = CFArrayCreate(NULL, v_certs, array_size(v_certs), &kCFTypeArrayCallBacks); + policy = SecPolicyCreateSSL(false, NULL); + + ok_status(SecTrustCreateWithCertificates(certs, policy, &trust), "create trust"); + + /* NOTE: prior to Need to generate new certs for CTTests + NSData *proofA_1 = NULL, *proofA_2 = NULL; + NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:447450000.0]; // March 7, 2015 at 11:40:00 AM PST + CFErrorRef error = NULL; + + NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:@"serverA" withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"]; + NSData *certData = [NSData dataWithContentsOfURL:url]; + isnt(certA = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData), NULL, "create certA"); + + url = [[NSBundle bundleForClass:[self class]] URLForResource:@"CA_beta" withExtension:@".cer" subdirectory:@"si-82-sectrust-ct-data"]; + certData = [NSData dataWithContentsOfURL:url]; + isnt(certCA_alpha = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)certData), NULL, "create ca-alpha cert"); + + NSArray *anchors = @[ (__bridge id)certCA_alpha ]; + + url = [[NSBundle bundleForClass:[self class]] URLForResource:@"serverA_proof_Alfa_3" withExtension:@".bin" subdirectory:@"si-82-sectrust-ct-data"]; + isnt(proofA_1 = [NSData dataWithContentsOfURL:url], NULL, "creat proofA_1"); + url = [[NSBundle bundleForClass:[self class]] URLForResource:@"serverA_proof_Bravo_3" withExtension:@".bin" subdirectory:@"si-82-sectrust-ct-data"]; + isnt(proofA_2 = [NSData dataWithContentsOfURL:url], NULL, "creat proofA_2"); + NSArray *scts = @[ proofA_1, proofA_2 ]; + + /* Make a SecTrustRef and then serialize it */ + ok_status(SecTrustCreateWithCertificates(certA, policy, &trust), "failed to create trust object"); + ok_status(SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)anchors), "failed to set anchors"); + ok_status(SecTrustSetTrustedLogs(trust, trustedLogs), "failed to set trusted logs"); + ok_status(SecTrustSetVerifyDate(trust, (__bridge CFDateRef)date), "failed to set verify date"); + ok_status(SecTrustSetSignedCertificateTimestamps(trust, (__bridge CFArrayRef)scts), "failed to set SCTS"); + + NSData *serializedTrust = CFBridgingRelease(SecTrustSerialize(trust, &error)); + isnt(serializedTrust, NULL, "failed to serialize trust: %@", error); + + /* Evaluate it to make sure it's CT */ + ok(SecTrustEvaluateWithError(trust, &error), "failed to evaluate trust: %@", error); + NSDictionary *results = CFBridgingRelease(SecTrustCopyResult(trust)); + isnt(results[(__bridge NSString*)kSecTrustCertificateTransparency], NULL, "failed get CT result"); + ok([results[(__bridge NSString*)kSecTrustCertificateTransparency] boolValue], "CT failed"); + + /* Make a new trust object by deserializing the previous trust object */ + ok(deserializedTrust = SecTrustDeserialize((__bridge CFDataRef)serializedTrust, &error), "failed to deserialize trust: %@", error); + + /* Evaluate the new one to make sure it's CT (because the SCTs were serialized) */ + ok(SecTrustEvaluateWithError(deserializedTrust, &error), "failed to evaluate trust: %@", error); + results = CFBridgingRelease(SecTrustCopyResult(deserializedTrust)); + isnt(results[(__bridge NSString*)kSecTrustCertificateTransparency], NULL, "failed get CT result"); + ok([results[(__bridge NSString*)kSecTrustCertificateTransparency] boolValue], "CT failed"); + + CFReleaseNull(certA); + CFReleaseNull(certCA_alpha); + CFReleaseNull(certCA_beta); + CFReleaseNull(trustedLogs); + CFReleaseNull(policy); + CFReleaseNull(trust); + CFReleaseNull(deserializedTrust); + CFReleaseNull(error); +} + +- (void)testTLSAnalytics { + xpc_object_t metric = xpc_dictionary_create(NULL, NULL, 0); + ok(metric != NULL); + + const char *TLS_METRIC_PROCESS_IDENTIFIER = "process"; + const char *TLS_METRIC_CIPHERSUITE = "cipher_name"; + const char *TLS_METRIC_PROTOCOL_VERSION = "version"; + const char *TLS_METRIC_SESSION_RESUMED = "resumed"; + + xpc_dictionary_set_string(metric, TLS_METRIC_PROCESS_IDENTIFIER, "super awesome unit tester"); + xpc_dictionary_set_uint64(metric, TLS_METRIC_CIPHERSUITE, 0x0304); + xpc_dictionary_set_uint64(metric, TLS_METRIC_PROTOCOL_VERSION, 0x0304); + xpc_dictionary_set_bool(metric, TLS_METRIC_SESSION_RESUMED, false); + // ... TLS would fill in the rest + + // Invoke the callback + CFErrorRef error = NULL; + bool reported = SecTrustReportTLSAnalytics(CFSTR("TLSConnectionEvent"), metric, &error); + ok(reported, "Failed to report analytics with error %@", error); +} + +- (void)testEvaluateFastAsync +{ + SecCertificateRef cert0 = NULL, cert1 = NULL, cert2 = NULL; + SecPolicyRef policy = NULL; + __block SecTrustRef trust = NULL; + NSArray *certificates = nil, *roots = nil; + NSDate *validDate = nil; + dispatch_queue_t queue = dispatch_queue_create("com.apple.trusttests.EvalAsync", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __block XCTestExpectation *blockExpectation = [self expectationWithDescription:@"callback occurs"]; + + cert0 = SecCertificateCreateWithBytes(NULL, _expired_badssl, sizeof(_expired_badssl)); + cert1 = SecCertificateCreateWithBytes(NULL, _comodo_rsa_dvss, sizeof(_comodo_rsa_dvss)); + cert2 = SecCertificateCreateWithBytes(NULL, _comodo_rsa_root, sizeof(_comodo_rsa_root)); + + certificates = @[ (__bridge id)cert0, (__bridge id)cert1 ]; + roots = @[ (__bridge id)cert2 ]; + + policy = SecPolicyCreateSSL(true, CFSTR("expired.badssl.com")); + XCTAssert(errSecSuccess == SecTrustCreateWithCertificates((__bridge CFArrayRef)certificates, policy, &trust)); + XCTAssert(errSecSuccess == SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)roots)); + + /* April 10 2015 (cert expired in 2015) */ + validDate = CFBridgingRelease(CFDateCreateForGregorianZuluMoment(NULL, 2015, 4, 10, 12, 0, 0)); + XCTAssert(errSecSuccess == SecTrustSetVerifyDate(trust, (__bridge CFDateRef)validDate)); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + XCTAssert(errSecParam == SecTrustEvaluateFastAsync(trust, NULL, ^(SecTrustRef _Nonnull trustRef, SecTrustResultType trustResult) { + XCTAssert(false, "callback called with invalid parameter"); + })); +#pragma clang diagnostic pop + + /* expect success */ + dispatch_async(queue, ^{ + XCTAssert(errSecSuccess == SecTrustEvaluateFastAsync(trust, queue, ^(SecTrustRef _Nonnull trustRef, SecTrustResultType trustResult) { + XCTAssert(trustRef != NULL); + XCTAssert(trustResult == kSecTrustResultUnspecified); + [blockExpectation fulfill]; + })); + }); + + [self waitForExpectations:@[blockExpectation] timeout:1.0]; + + /* Mar 21 2017 (cert expired in 2015, so this will cause a validity error.) */ + validDate = CFBridgingRelease(CFDateCreateForGregorianZuluMoment(NULL, 2017, 3, 21, 12, 0, 0)); + XCTAssert(errSecSuccess == SecTrustSetVerifyDate(trust, (__bridge CFDateRef)validDate)); + + /* expect failure */ + blockExpectation = [self expectationWithDescription:@"callback occurs"]; + dispatch_async(queue, ^{ + XCTAssert(errSecSuccess == SecTrustEvaluateFastAsync(trust, queue, ^(SecTrustRef _Nonnull trustRef, SecTrustResultType trustResult) { + XCTAssert(trustRef != NULL); + XCTAssert(trustResult == kSecTrustResultRecoverableTrustFailure); + [blockExpectation fulfill]; + })); + }); + + [self waitForExpectations:@[blockExpectation] timeout:1.0]; + + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(cert2); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +- (void)testEvaluateAsyncWithError +{ + SecCertificateRef cert0 = NULL, cert1 = NULL, cert2 = NULL; + SecPolicyRef policy = NULL; + SecTrustRef trust = NULL; + NSArray *certificates = nil, *roots = nil; + NSDate *validDate = nil; + dispatch_queue_t queue = dispatch_queue_create("com.apple.trusttests.EvalAsync", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __block XCTestExpectation *blockExpectation = [self expectationWithDescription:@"callback occurs"]; + + cert0 = SecCertificateCreateWithBytes(NULL, _expired_badssl, sizeof(_expired_badssl)); + cert1 = SecCertificateCreateWithBytes(NULL, _comodo_rsa_dvss, sizeof(_comodo_rsa_dvss)); + cert2 = SecCertificateCreateWithBytes(NULL, _comodo_rsa_root, sizeof(_comodo_rsa_root)); + + certificates = @[ (__bridge id)cert0, (__bridge id)cert1 ]; + roots = @[ (__bridge id)cert2 ]; + + policy = SecPolicyCreateSSL(true, CFSTR("expired.badssl.com")); + XCTAssert(errSecSuccess == SecTrustCreateWithCertificates((__bridge CFArrayRef)certificates, policy, &trust)); + XCTAssert(errSecSuccess == SecTrustSetAnchorCertificates(trust, (__bridge CFArrayRef)roots)); + + /* April 10 2015 (cert expired in 2015) */ + validDate = CFBridgingRelease(CFDateCreateForGregorianZuluMoment(NULL, 2015, 4, 10, 12, 0, 0)); + XCTAssert(errSecSuccess == SecTrustSetVerifyDate(trust, (__bridge CFDateRef)validDate)); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" + XCTAssert(errSecParam == SecTrustEvaluateAsyncWithError(trust, NULL, ^(SecTrustRef _Nonnull trustRef, bool result, CFErrorRef _Nullable error) { + XCTAssert(false, "callback called with invalid parameter"); + })); +#pragma clang diagnostic pop + + /* expect success */ + dispatch_async(queue, ^{ + XCTAssert(errSecSuccess == SecTrustEvaluateAsyncWithError(trust, queue, ^(SecTrustRef _Nonnull trustRef, bool result, CFErrorRef _Nullable error) { + XCTAssert(trust != NULL); + XCTAssertTrue(result); + XCTAssert(error == NULL); + [blockExpectation fulfill]; + })); + }); + + [self waitForExpectations:@[blockExpectation] timeout:1.0]; + + /* Mar 21 2017 (cert expired in 2015, so this will cause a validity error.) */ + validDate = CFBridgingRelease(CFDateCreateForGregorianZuluMoment(NULL, 2017, 3, 21, 12, 0, 0)); + XCTAssert(errSecSuccess == SecTrustSetVerifyDate(trust, (__bridge CFDateRef)validDate)); + + /* expect expiration error */ + blockExpectation = [self expectationWithDescription:@"callback occurs"]; + dispatch_async(queue, ^{ + XCTAssert(errSecSuccess == SecTrustEvaluateAsyncWithError(trust, queue, ^(SecTrustRef _Nonnull trustRef, bool result, CFErrorRef _Nullable error) { + XCTAssert(trust != NULL); + XCTAssertFalse(result); + XCTAssert(error != NULL); + XCTAssert(CFErrorGetCode(error) == errSecCertificateExpired); + [blockExpectation fulfill]; + })); + }); + + [self waitForExpectations:@[blockExpectation] timeout:1.0]; + + CFReleaseNull(cert0); + CFReleaseNull(cert1); + CFReleaseNull(cert2); + CFReleaseNull(policy); + CFReleaseNull(trust); +} + +- (void)testCopyProperties_ios +{ + /* Test null input */ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" +#if TARGET_OS_IPHONE + XCTAssertEqual(NULL, SecTrustCopyProperties(NULL)); +#else + XCTAssertEqual(NULL, SecTrustCopyProperties_ios(NULL)); +#endif +#pragma clang diagnostic pop + + NSURL *testPlist = nil; + NSArray *testsArray = nil; + + testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:@"debugging" withExtension:@"plist" + subdirectory:@"TestCopyProperties_ios-data"]; + if (!testPlist) { + testPlist = [[NSBundle bundleForClass:[self class]] URLForResource:nil withExtension:@"plist" + subdirectory:(NSString *)@"TestCopyProperties_ios-data"]; + } + if (!testPlist) { + fail("Failed to get tests plist from TestCopyProperties-data"); + return; + } + + testsArray = [NSArray arrayWithContentsOfURL: testPlist]; + if (!testsArray) { + fail("Failed to create array from plist"); + return; + } + + [testsArray enumerateObjectsUsingBlock:^(NSDictionary *testDict, NSUInteger idx, BOOL * _Nonnull stop) { + TestTrustEvaluation *testObj = [[TestTrustEvaluation alloc] initWithTrustDictionary:testDict]; + XCTAssertNotNil(testObj, "failed to create test object for %lu", (unsigned long)idx); + +#if TARGET_OS_BRIDGE + // Skip disabled bridgeOS tests on bridgeOS + if (testObj.bridgeOSDisabled) { + return; + } +#endif + +#if TARGET_OS_IPHONE + NSArray *properties = CFBridgingRelease(SecTrustCopyProperties(testObj.trust)); +#else + NSArray *properties = CFBridgingRelease(SecTrustCopyProperties_ios(testObj.trust)); +#endif + + if (testDict[@"ExpectedProperties"]) { + XCTAssertEqualObjects(testDict[@"ExpectedProperties"], properties, @"%@ test failed", testObj.fullTestName); + } else { + XCTAssertNil(properties, @"%@ test failed", testObj.fullTestName); + } + }]; +} + +@end diff --git a/tests/TrustTests/FrameworkTests/TrustInterfaceTests_data.h b/tests/TrustTests/FrameworkTests/TrustInterfaceTests_data.h new file mode 100644 index 00000000..e9a884fe --- /dev/null +++ b/tests/TrustTests/FrameworkTests/TrustInterfaceTests_data.h @@ -0,0 +1,537 @@ +/* + * 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 _TRUSTTESTS_TRUST_INTERFACE_H_ +#define _TRUSTTESTS_TRUST_INTERFACE_H_ + +// MARK: Generic EV SSL Chain + +/* + Serial Number: + 01:f1:eb:db:ee:d3:1d:7a:b5:72:54:7d:34:43:4b:87 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA + Validity + Not Before: Mar 22 00:00:00 2018 GMT + Not After : Mar 23 12:00:00 2019 GMT + Subject: businessCategory=Private Organization/jurisdictionC=US/jurisdictionST=California/serialNumber=C0806592, C=US, ST=California, L=Cupertino, O=Apple Inc., OU=Internet Services for Akamai, CN=store.apple.com + */ +static const uint8_t _c0[] = { + 0x30,0x82,0x06,0xF7,0x30,0x82,0x05,0xDF,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x01, + 0xF1,0xEB,0xDB,0xEE,0xD3,0x1D,0x7A,0xB5,0x72,0x54,0x7D,0x34,0x43,0x4B,0x87,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x75, + 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, + 0x34,0x30,0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64, + 0x20,0x56,0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x20,0x53,0x65,0x72,0x76, + 0x65,0x72,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x38,0x30,0x33,0x32,0x32,0x30, + 0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x31,0x39,0x30,0x33,0x32,0x33,0x31,0x32, + 0x30,0x30,0x30,0x30,0x5A,0x30,0x81,0xF0,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04, + 0x0F,0x0C,0x14,0x50,0x72,0x69,0x76,0x61,0x74,0x65,0x20,0x4F,0x72,0x67,0x61,0x6E, + 0x69,0x7A,0x61,0x74,0x69,0x6F,0x6E,0x31,0x13,0x30,0x11,0x06,0x0B,0x2B,0x06,0x01, + 0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03,0x13,0x02,0x55,0x53,0x31,0x1B,0x30,0x19, + 0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02,0x13,0x0A,0x43, + 0x61,0x6C,0x69,0x66,0x6F,0x72,0x6E,0x69,0x61,0x31,0x11,0x30,0x0F,0x06,0x03,0x55, + 0x04,0x05,0x13,0x08,0x43,0x30,0x38,0x30,0x36,0x35,0x39,0x32,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,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70, + 0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x25,0x30,0x23,0x06,0x03,0x55,0x04,0x0B, + 0x13,0x1C,0x49,0x6E,0x74,0x65,0x72,0x6E,0x65,0x74,0x20,0x53,0x65,0x72,0x76,0x69, + 0x63,0x65,0x73,0x20,0x66,0x6F,0x72,0x20,0x41,0x6B,0x61,0x6D,0x61,0x69,0x31,0x18, + 0x30,0x16,0x06,0x03,0x55,0x04,0x03,0x13,0x0F,0x73,0x74,0x6F,0x72,0x65,0x2E,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,0xB5,0xDF,0x48,0x6A,0xE5,0x5F,0x0C, + 0x42,0xBF,0x71,0x07,0xAB,0xE6,0x48,0xD2,0x2C,0x13,0x7C,0x29,0xF7,0x90,0xC2,0x45, + 0x39,0x43,0x48,0x2E,0x16,0x22,0xBF,0xAB,0x48,0x20,0x14,0x27,0xE7,0x87,0x52,0x97, + 0xF6,0x64,0x0C,0x62,0xF5,0x39,0x54,0x64,0x09,0xE8,0x29,0x56,0xF4,0x03,0x40,0x5A, + 0xFA,0x9A,0x11,0x2B,0xD0,0x01,0x51,0x1E,0xED,0xB8,0x51,0xCB,0xAB,0x6B,0x7A,0x99, + 0xF3,0xB0,0x6E,0xA8,0xC4,0xB6,0xAF,0x17,0xEC,0xA6,0xD2,0x4D,0xCA,0x63,0x3D,0x59, + 0x30,0x25,0x30,0x54,0x86,0xDB,0x70,0x7A,0xEC,0x07,0x83,0x19,0xA0,0x44,0xE7,0x3C, + 0x68,0xE0,0xFD,0xB9,0xEE,0x3F,0xAC,0xF3,0x32,0x5A,0x5F,0x42,0x31,0x94,0x70,0x2C, + 0xC5,0x73,0xD2,0x79,0x23,0x5B,0x96,0x45,0xB1,0xB3,0x2A,0xA1,0x5A,0x69,0xFE,0xBE, + 0x52,0x0D,0x5D,0x79,0x18,0xCA,0xF1,0x44,0x92,0xA0,0x27,0x1F,0xAA,0x6E,0x9D,0x6F, + 0x1B,0x83,0x5B,0x73,0x28,0x1D,0x87,0xB5,0x70,0x0E,0x3D,0xED,0xE2,0xC2,0x34,0x8A, + 0x81,0xB2,0x22,0x40,0x98,0x77,0x2F,0x34,0x1B,0x70,0xEC,0x96,0x3F,0x91,0xB9,0xFF, + 0xC9,0xE5,0x7E,0xE7,0x25,0xEF,0xDB,0x9A,0x58,0x4E,0xB2,0x92,0x19,0xA5,0x8D,0xEB, + 0x76,0xF8,0xA8,0x48,0x9F,0x3D,0x10,0x0C,0xE4,0x69,0x7B,0xE7,0xB7,0xCA,0xF6,0x14, + 0x5E,0x93,0x1E,0x20,0x37,0x1B,0xB8,0xB1,0x2C,0xD1,0x46,0x5C,0xD7,0x85,0x4A,0x2E, + 0x19,0xB2,0x3C,0x31,0xDC,0x3D,0xB5,0x3C,0xEC,0x49,0x8D,0x9C,0xCF,0x75,0x0B,0xFC, + 0x03,0x31,0x37,0xE7,0xA5,0xD6,0x9D,0x19,0x0D,0x02,0x03,0x01,0x00,0x01,0xA3,0x82, + 0x03,0x05,0x30,0x82,0x03,0x01,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30, + 0x16,0x80,0x14,0x3D,0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65, + 0xD3,0x21,0xD4,0xF8,0xF8,0xD6,0x0F,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16, + 0x04,0x14,0x6F,0x89,0xAE,0x9B,0xE4,0x8A,0x21,0x3A,0x3B,0xEA,0xAA,0xBE,0x99,0x90, + 0xC8,0xDB,0x34,0x80,0x21,0xB9,0x30,0x2F,0x06,0x03,0x55,0x1D,0x11,0x04,0x28,0x30, + 0x26,0x82,0x0F,0x73,0x74,0x6F,0x72,0x65,0x2E,0x61,0x70,0x70,0x6C,0x65,0x2E,0x63, + 0x6F,0x6D,0x82,0x13,0x77,0x77,0x77,0x2E,0x73,0x74,0x6F,0x72,0x65,0x2E,0x61,0x70, + 0x70,0x6C,0x65,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,0x75,0x06,0x03,0x55,0x1D,0x1F,0x04,0x6E,0x30, + 0x6C,0x30,0x34,0xA0,0x32,0xA0,0x30,0x86,0x2E,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,0x68,0x61,0x32,0x2D,0x65,0x76,0x2D,0x73,0x65,0x72,0x76,0x65,0x72, + 0x2D,0x67,0x32,0x2E,0x63,0x72,0x6C,0x30,0x34,0xA0,0x32,0xA0,0x30,0x86,0x2E,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,0x68,0x61,0x32,0x2D,0x65,0x76,0x2D, + 0x73,0x65,0x72,0x76,0x65,0x72,0x2D,0x67,0x32,0x2E,0x63,0x72,0x6C,0x30,0x4B,0x06, + 0x03,0x55,0x1D,0x20,0x04,0x44,0x30,0x42,0x30,0x37,0x06,0x09,0x60,0x86,0x48,0x01, + 0x86,0xFD,0x6C,0x02,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,0x07,0x06,0x05,0x67,0x81,0x0C,0x01,0x01,0x30,0x81,0x88,0x06,0x08,0x2B, + 0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x7C,0x30,0x7A,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,0x52,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x46,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,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x56, + 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,0x53,0x65,0x72,0x76,0x65,0x72,0x43, + 0x41,0x2E,0x63,0x72,0x74,0x30,0x09,0x06,0x03,0x55,0x1D,0x13,0x04,0x02,0x30,0x00, + 0x30,0x82,0x01,0x03,0x06,0x0A,0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02, + 0x04,0x81,0xF4,0x04,0x81,0xF1,0x00,0xEF,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,0x62,0x4E, + 0xBC,0xC7,0x43,0x00,0x00,0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x3E,0xD3,0xFE, + 0xB4,0x45,0x97,0xCE,0xA3,0x05,0xC9,0x29,0x70,0x55,0x3B,0x77,0x9E,0xCC,0x4B,0x06, + 0xFD,0x76,0x21,0xD0,0x79,0x69,0xD6,0x60,0x01,0xBB,0xC7,0x43,0x5E,0x02,0x20,0x3D, + 0xB7,0x73,0x91,0x51,0xB7,0xAC,0x40,0xFB,0xA7,0x36,0xCF,0x10,0xE8,0x63,0x79,0xE6, + 0x06,0xEC,0xFA,0x60,0xFE,0x44,0x90,0x9A,0x53,0x26,0x04,0x27,0x1A,0x4B,0xD4,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,0x62,0x4E,0xBC,0xC8,0x6A,0x00,0x00,0x04,0x03,0x00,0x47, + 0x30,0x45,0x02,0x20,0x18,0xF4,0x40,0x99,0x83,0xA7,0x53,0x6D,0x11,0xBF,0x7C,0xA5, + 0x64,0x21,0x52,0xD0,0x7C,0xF5,0x96,0xCD,0xB0,0x56,0xAE,0x1E,0x13,0x9C,0xFC,0x08, + 0x3B,0x56,0x66,0x0F,0x02,0x21,0x00,0x98,0xBE,0xC7,0x01,0x8E,0x88,0xB7,0xB2,0xF9, + 0xC7,0xE6,0x08,0x46,0x10,0xEA,0x8D,0x01,0x12,0x0D,0x7D,0xA6,0xBA,0xA6,0xD3,0x1F, + 0xEC,0xA3,0xD6,0x7A,0xE4,0x85,0x89,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7, + 0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6A,0x52,0xE8,0xB3,0x70, + 0x25,0xD9,0x95,0x87,0xC4,0xF3,0x14,0xB1,0x8C,0x29,0x6F,0x11,0xA0,0x6D,0xD7,0xE9, + 0x96,0xFA,0x06,0x57,0x4D,0x86,0xE8,0xD6,0x95,0xC0,0x3A,0x33,0xEC,0x67,0x6C,0x98, + 0xA2,0x99,0x09,0x28,0x16,0x18,0xEC,0x21,0xED,0x93,0xEF,0xAB,0x69,0x5F,0x98,0x9C, + 0x62,0x21,0x10,0xEB,0x1C,0xC4,0x20,0x5E,0x3E,0x6F,0x80,0x03,0xC9,0xC5,0xD5,0x2F, + 0xDA,0x8C,0x86,0x40,0x59,0x71,0x34,0xEE,0xCF,0x54,0x83,0xE1,0x3E,0x11,0x1D,0x12, + 0x66,0x3D,0x16,0x7F,0xD8,0x1B,0x42,0x35,0x50,0xA6,0xD6,0xE6,0x6B,0x32,0xDE,0xE2, + 0xD9,0x01,0xD7,0xB1,0xF5,0xE8,0x72,0x44,0x03,0xB5,0xFA,0x19,0x0D,0xF2,0x8D,0x0B, + 0x75,0xBA,0xD9,0x39,0xFF,0x73,0xF2,0xA0,0xD6,0x49,0xEF,0x9E,0xE9,0x23,0x5D,0xED, + 0xC5,0x08,0x69,0x10,0xF7,0xF0,0x0B,0x8D,0x80,0xB6,0x43,0xE4,0x2A,0xEC,0x92,0xCF, + 0x22,0xCA,0xAF,0x1A,0x8A,0x16,0xC7,0xC5,0x88,0xB7,0xCA,0xC6,0x19,0x1A,0xD1,0xFF, + 0x13,0x93,0x56,0x29,0x1A,0x48,0xA8,0x92,0x21,0xE5,0x7F,0x3E,0x4C,0xB4,0x89,0xD6, + 0x08,0xF0,0xB0,0x4B,0x22,0x7C,0x1F,0xEC,0xE7,0x09,0x5D,0x23,0xE2,0xD1,0xB8,0xA3, + 0xDF,0xEC,0x2D,0x87,0x1F,0xCD,0x58,0x1C,0xDD,0x09,0xE8,0xB5,0xD4,0x30,0x1E,0x2A, + 0x4D,0xA3,0xA1,0x84,0x43,0xD7,0x4A,0x7B,0x15,0x8E,0xEB,0xE2,0x53,0x2B,0x12,0xCB, + 0xFB,0xF2,0x61,0x7E,0x92,0x0B,0x87,0x07,0x1C,0x8D,0x0A,0xED,0x62,0x10,0x27,0xE3, + 0xDB,0xC4,0x65,0xDE,0x57,0xFB,0x6D,0x49,0xC8,0x7A,0xF8, +}; + +/* + Serial Number: + 0c:79:a9:44:b0:8c:11:95:20:92:61:5f:e2:6b:1d:83 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA + Validity + Not Before: Oct 22 12:00:00 2013 GMT + Not After : Oct 22 12:00:00 2028 GMT + Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert SHA2 Extended Validation Server CA + */ +static const uint8_t _c1[] = { + 0x30,0x82,0x04,0xB6,0x30,0x82,0x03,0x9E,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x0C, + 0x79,0xA9,0x44,0xB0,0x8C,0x11,0x95,0x20,0x92,0x61,0x5F,0xE2,0x6B,0x1D,0x83,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x6C, + 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, + 0x2B,0x30,0x29,0x06,0x03,0x55,0x04,0x03,0x13,0x22,0x44,0x69,0x67,0x69,0x43,0x65, + 0x72,0x74,0x20,0x48,0x69,0x67,0x68,0x20,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63, + 0x65,0x20,0x45,0x56,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D, + 0x31,0x33,0x31,0x30,0x32,0x32,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32, + 0x38,0x31,0x30,0x32,0x32,0x31,0x32,0x30,0x30,0x30,0x30,0x5A,0x30,0x75,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,0x34,0x30, + 0x32,0x06,0x03,0x55,0x04,0x03,0x13,0x2B,0x44,0x69,0x67,0x69,0x43,0x65,0x72,0x74, + 0x20,0x53,0x48,0x41,0x32,0x20,0x45,0x78,0x74,0x65,0x6E,0x64,0x65,0x64,0x20,0x56, + 0x61,0x6C,0x69,0x64,0x61,0x74,0x69,0x6F,0x6E,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,0xD7,0x53,0xA4,0x04,0x51,0xF8,0x99,0xA6,0x16,0x48,0x4B,0x67, + 0x27,0xAA,0x93,0x49,0xD0,0x39,0xED,0x0C,0xB0,0xB0,0x00,0x87,0xF1,0x67,0x28,0x86, + 0x85,0x8C,0x8E,0x63,0xDA,0xBC,0xB1,0x40,0x38,0xE2,0xD3,0xF5,0xEC,0xA5,0x05,0x18, + 0xB8,0x3D,0x3E,0xC5,0x99,0x17,0x32,0xEC,0x18,0x8C,0xFA,0xF1,0x0C,0xA6,0x64,0x21, + 0x85,0xCB,0x07,0x10,0x34,0xB0,0x52,0x88,0x2B,0x1F,0x68,0x9B,0xD2,0xB1,0x8F,0x12, + 0xB0,0xB3,0xD2,0xE7,0x88,0x1F,0x1F,0xEF,0x38,0x77,0x54,0x53,0x5F,0x80,0x79,0x3F, + 0x2E,0x1A,0xAA,0xA8,0x1E,0x4B,0x2B,0x0D,0xAB,0xB7,0x63,0xB9,0x35,0xB7,0x7D,0x14, + 0xBC,0x59,0x4B,0xDF,0x51,0x4A,0xD2,0xA1,0xE2,0x0C,0xE2,0x90,0x82,0x87,0x6A,0xAE, + 0xEA,0xD7,0x64,0xD6,0x98,0x55,0xE8,0xFD,0xAF,0x1A,0x50,0x6C,0x54,0xBC,0x11,0xF2, + 0xFD,0x4A,0xF2,0x9D,0xBB,0x7F,0x0E,0xF4,0xD5,0xBE,0x8E,0x16,0x89,0x12,0x55,0xD8, + 0xC0,0x71,0x34,0xEE,0xF6,0xDC,0x2D,0xEC,0xC4,0x87,0x25,0x86,0x8D,0xD8,0x21,0xE4, + 0xB0,0x4D,0x0C,0x89,0xDC,0x39,0x26,0x17,0xDD,0xF6,0xD7,0x94,0x85,0xD8,0x04,0x21, + 0x70,0x9D,0x6F,0x6F,0xFF,0x5C,0xBA,0x19,0xE1,0x45,0xCB,0x56,0x57,0x28,0x7E,0x1C, + 0x0D,0x41,0x57,0xAA,0xB7,0xB8,0x27,0xBB,0xB1,0xE4,0xFA,0x2A,0xEF,0x21,0x23,0x75, + 0x1A,0xAD,0x2D,0x9B,0x86,0x35,0x8C,0x9C,0x77,0xB5,0x73,0xAD,0xD8,0x94,0x2D,0xE4, + 0xF3,0x0C,0x9D,0xEE,0xC1,0x4E,0x62,0x7E,0x17,0xC0,0x71,0x9E,0x2C,0xDE,0xF1,0xF9, + 0x10,0x28,0x19,0x33,0x02,0x03,0x01,0x00,0x01,0xA3,0x82,0x01,0x49,0x30,0x82,0x01, + 0x45,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,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,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,0x4B,0x06,0x03,0x55,0x1D, + 0x1F,0x04,0x44,0x30,0x42,0x30,0x40,0xA0,0x3E,0xA0,0x3C,0x86,0x3A,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,0x48,0x69, + 0x67,0x68,0x41,0x73,0x73,0x75,0x72,0x61,0x6E,0x63,0x65,0x45,0x56,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,0x3D,0xD3,0x50,0xA5,0xD6,0xA0,0xAD,0xEE,0xF3,0x4A,0x60,0x0A,0x65,0xD3,0x21, + 0xD4,0xF8,0xF8,0xD6,0x0F,0x30,0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16, + 0x80,0x14,0xB1,0x3E,0xC3,0x69,0x03,0xF8,0xBF,0x47,0x01,0xD4,0x98,0x26,0x1A,0x08, + 0x02,0xEF,0x63,0x64,0x2B,0xC3,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D, + 0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x9D,0xB6,0xD0,0x90,0x86,0xE1, + 0x86,0x02,0xED,0xC5,0xA0,0xF0,0x34,0x1C,0x74,0xC1,0x8D,0x76,0xCC,0x86,0x0A,0xA8, + 0xF0,0x4A,0x8A,0x42,0xD6,0x3F,0xC8,0xA9,0x4D,0xAD,0x7C,0x08,0xAD,0xE6,0xB6,0x50, + 0xB8,0xA2,0x1A,0x4D,0x88,0x07,0xB1,0x29,0x21,0xDC,0xE7,0xDA,0xC6,0x3C,0x21,0xE0, + 0xE3,0x11,0x49,0x70,0xAC,0x7A,0x1D,0x01,0xA4,0xCA,0x11,0x3A,0x57,0xAB,0x7D,0x57, + 0x2A,0x40,0x74,0xFD,0xD3,0x1D,0x85,0x18,0x50,0xDF,0x57,0x47,0x75,0xA1,0x7D,0x55, + 0x20,0x2E,0x47,0x37,0x50,0x72,0x8C,0x7F,0x82,0x1B,0xD2,0x62,0x8F,0x2D,0x03,0x5A, + 0xDA,0xC3,0xC8,0xA1,0xCE,0x2C,0x52,0xA2,0x00,0x63,0xEB,0x73,0xBA,0x71,0xC8,0x49, + 0x27,0x23,0x97,0x64,0x85,0x9E,0x38,0x0E,0xAD,0x63,0x68,0x3C,0xBA,0x52,0x81,0x58, + 0x79,0xA3,0x2C,0x0C,0xDF,0xDE,0x6D,0xEB,0x31,0xF2,0xBA,0xA0,0x7C,0x6C,0xF1,0x2C, + 0xD4,0xE1,0xBD,0x77,0x84,0x37,0x03,0xCE,0x32,0xB5,0xC8,0x9A,0x81,0x1A,0x4A,0x92, + 0x4E,0x3B,0x46,0x9A,0x85,0xFE,0x83,0xA2,0xF9,0x9E,0x8C,0xA3,0xCC,0x0D,0x5E,0xB3, + 0x3D,0xCF,0x04,0x78,0x8F,0x14,0x14,0x7B,0x32,0x9C,0xC7,0x00,0xA6,0x5C,0xC4,0xB5, + 0xA1,0x55,0x8D,0x5A,0x56,0x68,0xA4,0x22,0x70,0xAA,0x3C,0x81,0x71,0xD9,0x9D,0xA8, + 0x45,0x3B,0xF4,0xE5,0xF6,0xA2,0x51,0xDD,0xC7,0x7B,0x62,0xE8,0x6F,0x0C,0x74,0xEB, + 0xB8,0xDA,0xF8,0xBF,0x87,0x0D,0x79,0x50,0x91,0x90,0x9B,0x18,0x3B,0x91,0x59,0x27, + 0xF1,0x35,0x28,0x13,0xAB,0x26,0x7E,0xD5,0xF7,0x7A, +}; + +// MARK: Expired Chain + +/* subject:/OU=Domain Control Validated/OU=PositiveSSL Wildcard/CN=*.badssl.com */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +unsigned char _expired_badssl[1359]={ + 0x30,0x82,0x05,0x4B,0x30,0x82,0x04,0x33,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4A, + 0xE7,0x95,0x49,0xFA,0x9A,0xBE,0x3F,0x10,0x0F,0x17,0xA4,0x78,0xE1,0x69,0x09,0x30, + 0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30,0x81, + 0x90,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,0x36,0x30,0x34,0x06,0x03,0x55, + 0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F,0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44, + 0x6F,0x6D,0x61,0x69,0x6E,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,0x35,0x30,0x34,0x30,0x39,0x30,0x30,0x30,0x30,0x30, + 0x30,0x5A,0x17,0x0D,0x31,0x35,0x30,0x34,0x31,0x32,0x32,0x33,0x35,0x39,0x35,0x39, + 0x5A,0x30,0x59,0x31,0x21,0x30,0x1F,0x06,0x03,0x55,0x04,0x0B,0x13,0x18,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x20,0x56,0x61,0x6C, + 0x69,0x64,0x61,0x74,0x65,0x64,0x31,0x1D,0x30,0x1B,0x06,0x03,0x55,0x04,0x0B,0x13, + 0x14,0x50,0x6F,0x73,0x69,0x74,0x69,0x76,0x65,0x53,0x53,0x4C,0x20,0x57,0x69,0x6C, + 0x64,0x63,0x61,0x72,0x64,0x31,0x15,0x30,0x13,0x06,0x03,0x55,0x04,0x03,0x14,0x0C, + 0x2A,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,0xC2,0x04,0xEC, + 0xF8,0x8C,0xEE,0x04,0xC2,0xB3,0xD8,0x50,0xD5,0x70,0x58,0xCC,0x93,0x18,0xEB,0x5C, + 0xA8,0x68,0x49,0xB0,0x22,0xB5,0xF9,0x95,0x9E,0xB1,0x2B,0x2C,0x76,0x3E,0x6C,0xC0, + 0x4B,0x60,0x4C,0x4C,0xEA,0xB2,0xB4,0xC0,0x0F,0x80,0xB6,0xB0,0xF9,0x72,0xC9,0x86, + 0x02,0xF9,0x5C,0x41,0x5D,0x13,0x2B,0x7F,0x71,0xC4,0x4B,0xBC,0xE9,0x94,0x2E,0x50, + 0x37,0xA6,0x67,0x1C,0x61,0x8C,0xF6,0x41,0x42,0xC5,0x46,0xD3,0x16,0x87,0x27,0x9F, + 0x74,0xEB,0x0A,0x9D,0x11,0x52,0x26,0x21,0x73,0x6C,0x84,0x4C,0x79,0x55,0xE4,0xD1, + 0x6B,0xE8,0x06,0x3D,0x48,0x15,0x52,0xAD,0xB3,0x28,0xDB,0xAA,0xFF,0x6E,0xFF,0x60, + 0x95,0x4A,0x77,0x6B,0x39,0xF1,0x24,0xD1,0x31,0xB6,0xDD,0x4D,0xC0,0xC4,0xFC,0x53, + 0xB9,0x6D,0x42,0xAD,0xB5,0x7C,0xFE,0xAE,0xF5,0x15,0xD2,0x33,0x48,0xE7,0x22,0x71, + 0xC7,0xC2,0x14,0x7A,0x6C,0x28,0xEA,0x37,0x4A,0xDF,0xEA,0x6C,0xB5,0x72,0xB4,0x7E, + 0x5A,0xA2,0x16,0xDC,0x69,0xB1,0x57,0x44,0xDB,0x0A,0x12,0xAB,0xDE,0xC3,0x0F,0x47, + 0x74,0x5C,0x41,0x22,0xE1,0x9A,0xF9,0x1B,0x93,0xE6,0xAD,0x22,0x06,0x29,0x2E,0xB1, + 0xBA,0x49,0x1C,0x0C,0x27,0x9E,0xA3,0xFB,0x8B,0xF7,0x40,0x72,0x00,0xAC,0x92,0x08, + 0xD9,0x8C,0x57,0x84,0x53,0x81,0x05,0xCB,0xE6,0xFE,0x6B,0x54,0x98,0x40,0x27,0x85, + 0xC7,0x10,0xBB,0x73,0x70,0xEF,0x69,0x18,0x41,0x07,0x45,0x55,0x7C,0xF9,0x64,0x3F, + 0x3D,0x2C,0xC3,0xA9,0x7C,0xEB,0x93,0x1A,0x4C,0x86,0xD1,0xCA,0x85,0x02,0x03,0x01, + 0x00,0x01,0xA3,0x82,0x01,0xD5,0x30,0x82,0x01,0xD1,0x30,0x1F,0x06,0x03,0x55,0x1D, + 0x23,0x04,0x18,0x30,0x16,0x80,0x14,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90, + 0xEA,0x12,0x56,0x73,0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x1D,0x06,0x03,0x55, + 0x1D,0x0E,0x04,0x16,0x04,0x14,0x9D,0xEE,0xC1,0x7B,0x81,0x0B,0x3A,0x47,0x69,0x71, + 0x18,0x7D,0x11,0x37,0x93,0xBC,0xA5,0x1B,0x3F,0xFB,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,0x4F,0x06,0x03,0x55,0x1D,0x20,0x04,0x48, + 0x30,0x46,0x30,0x3A,0x06,0x0B,0x2B,0x06,0x01,0x04,0x01,0xB2,0x31,0x01,0x02,0x02, + 0x07,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,0x08, + 0x06,0x06,0x67,0x81,0x0C,0x01,0x02,0x01,0x30,0x54,0x06,0x03,0x55,0x1D,0x1F,0x04, + 0x4D,0x30,0x4B,0x30,0x49,0xA0,0x47,0xA0,0x45,0x86,0x43,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,0x44,0x6F,0x6D,0x61, + 0x69,0x6E,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, + 0x85,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01,0x04,0x79,0x30,0x77,0x30, + 0x4F,0x06,0x08,0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02,0x86,0x43,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,0x44,0x6F, + 0x6D,0x61,0x69,0x6E,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,0x23,0x06,0x03,0x55,0x1D,0x11,0x04,0x1C,0x30, + 0x1A,0x82,0x0C,0x2A,0x2E,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x82, + 0x0A,0x62,0x61,0x64,0x73,0x73,0x6C,0x2E,0x63,0x6F,0x6D,0x30,0x0D,0x06,0x09,0x2A, + 0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x6A, + 0x7A,0xF1,0xDA,0xFF,0x03,0x07,0x72,0x78,0xC5,0x66,0xA1,0x4F,0x46,0x43,0x0E,0x5F, + 0x14,0x21,0x8C,0x75,0x1A,0xEB,0x36,0xE0,0x1F,0xA4,0x10,0x15,0xEC,0xDA,0x33,0x25, + 0x7C,0x3B,0xB5,0x0A,0xC7,0x01,0x38,0x3D,0x27,0xFD,0x58,0xD9,0xCC,0xEA,0x2D,0x69, + 0x39,0x7C,0xBE,0x97,0xEF,0x0B,0xD6,0x0B,0x58,0xE7,0x8C,0x7F,0xBF,0xB3,0x4C,0x1D, + 0xF3,0xB7,0x90,0x80,0xA6,0x36,0x7C,0x14,0x5B,0xEC,0x07,0x2D,0x02,0x3E,0x1B,0x5B, + 0x63,0x5B,0x15,0xAB,0x00,0xFA,0x1F,0x3B,0x19,0x2D,0xDF,0xE2,0x23,0x10,0x11,0x07, + 0x7E,0x72,0x7F,0xE2,0xBF,0xB7,0x00,0x1B,0x98,0x2F,0x2C,0x3F,0xCE,0x85,0x9A,0x27, + 0x8C,0x10,0x22,0x08,0x41,0x2B,0x8A,0x3E,0x82,0x4E,0xFC,0xDD,0x21,0xC6,0x56,0x74, + 0x70,0xA4,0x34,0xF2,0xB1,0x40,0x9E,0x2B,0x58,0xA2,0x59,0x0F,0x1D,0x48,0xEF,0xEB, + 0x11,0x3E,0xC1,0x4A,0x9E,0xBC,0x65,0x55,0x6D,0xC6,0xA3,0xEF,0xD5,0xD4,0x96,0xCD, + 0xF1,0xAE,0x27,0xF7,0xA4,0x57,0x14,0x3C,0x94,0x41,0x05,0x7A,0x8B,0xA1,0x37,0x47, + 0xD7,0xF5,0x7D,0xDC,0xFA,0xCE,0x6F,0x31,0xA2,0xB0,0x8C,0xEA,0xCC,0x12,0x9B,0x22, + 0xF1,0x34,0x70,0xCF,0x7D,0x75,0x4A,0x8B,0x68,0x29,0x0C,0x1E,0xE9,0x96,0xA8,0xCF, + 0xB0,0x12,0x1F,0x5C,0x2A,0xEE,0x67,0x2F,0x7F,0xBD,0x73,0xF3,0x5A,0x01,0x22,0x0C, + 0x70,0xFA,0xCD,0x45,0xEF,0x78,0x5C,0xCE,0x0D,0xFA,0x4E,0xE1,0xEF,0xCE,0x65,0x9F, + 0x47,0x0C,0x4F,0xBB,0x36,0x44,0x68,0x56,0x5C,0x56,0x59,0xAD,0xAA,0x8A,0xBC, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +unsigned char _comodo_rsa_dvss[1548]={ + 0x30,0x82,0x06,0x08,0x30,0x82,0x03,0xF0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x2B, + 0x2E,0x6E,0xEA,0xD9,0x75,0x36,0x6C,0x14,0x8A,0x6E,0xDB,0xA3,0x7C,0x8C,0x07,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,0x34,0x30,0x32,0x31,0x32, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x32,0x39,0x30,0x32,0x31,0x31,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,0x30,0x81,0x90,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,0x36,0x30,0x34,0x06,0x03,0x55,0x04,0x03,0x13,0x2D,0x43,0x4F,0x4D,0x4F, + 0x44,0x4F,0x20,0x52,0x53,0x41,0x20,0x44,0x6F,0x6D,0x61,0x69,0x6E,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,0x8E,0xC2,0x02,0x19,0xE1,0xA0, + 0x59,0xA4,0xEB,0x38,0x35,0x8D,0x2C,0xFD,0x01,0xD0,0xD3,0x49,0xC0,0x64,0xC7,0x0B, + 0x62,0x05,0x45,0x16,0x3A,0xA8,0xA0,0xC0,0x0C,0x02,0x7F,0x1D,0xCC,0xDB,0xC4,0xA1, + 0x6D,0x77,0x03,0xA3,0x0F,0x86,0xF9,0xE3,0x06,0x9C,0x3E,0x0B,0x81,0x8A,0x9B,0x49, + 0x1B,0xAD,0x03,0xBE,0xFA,0x4B,0xDB,0x8C,0x20,0xED,0xD5,0xCE,0x5E,0x65,0x8E,0x3E, + 0x0D,0xAF,0x4C,0xC2,0xB0,0xB7,0x45,0x5E,0x52,0x2F,0x34,0xDE,0x48,0x24,0x64,0xB4, + 0x41,0xAE,0x00,0x97,0xF7,0xBE,0x67,0xDE,0x9E,0xD0,0x7A,0xA7,0x53,0x80,0x3B,0x7C, + 0xAD,0xF5,0x96,0x55,0x6F,0x97,0x47,0x0A,0x7C,0x85,0x8B,0x22,0x97,0x8D,0xB3,0x84, + 0xE0,0x96,0x57,0xD0,0x70,0x18,0x60,0x96,0x8F,0xEE,0x2D,0x07,0x93,0x9D,0xA1,0xBA, + 0xCA,0xD1,0xCD,0x7B,0xE9,0xC4,0x2A,0x9A,0x28,0x21,0x91,0x4D,0x6F,0x92,0x4F,0x25, + 0xA5,0xF2,0x7A,0x35,0xDD,0x26,0xDC,0x46,0xA5,0xD0,0xAC,0x59,0x35,0x8C,0xFF,0x4E, + 0x91,0x43,0x50,0x3F,0x59,0x93,0x1E,0x6C,0x51,0x21,0xEE,0x58,0x14,0xAB,0xFE,0x75, + 0x50,0x78,0x3E,0x4C,0xB0,0x1C,0x86,0x13,0xFA,0x6B,0x98,0xBC,0xE0,0x3B,0x94,0x1E, + 0x85,0x52,0xDC,0x03,0x93,0x24,0x18,0x6E,0xCB,0x27,0x51,0x45,0xE6,0x70,0xDE,0x25, + 0x43,0xA4,0x0D,0xE1,0x4A,0xA5,0xED,0xB6,0x7E,0xC8,0xCD,0x6D,0xEE,0x2E,0x1D,0x27, + 0x73,0x5D,0xDC,0x45,0x30,0x80,0xAA,0xE3,0xB2,0x41,0x0B,0xAF,0xBD,0x44,0x87,0xDA, + 0xB9,0xE5,0x1B,0x9D,0x7F,0xAE,0xE5,0x85,0x82,0xA5,0x02,0x03,0x01,0x00,0x01,0xA3, + 0x82,0x01,0x65,0x30,0x82,0x01,0x61,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,0x90,0xAF,0x6A,0x3A,0x94,0x5A,0x0B,0xD8,0x90,0xEA,0x12,0x56,0x73, + 0xDF,0x43,0xB4,0x3A,0x28,0xDA,0xE7,0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01, + 0xFF,0x04,0x04,0x03,0x02,0x01,0x86,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,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,0x1B,0x06,0x03,0x55,0x1D, + 0x20,0x04,0x14,0x30,0x12,0x30,0x06,0x06,0x04,0x55,0x1D,0x20,0x00,0x30,0x08,0x06, + 0x06,0x67,0x81,0x0C,0x01,0x02,0x01,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,0x4E,0x2B,0x76,0x4F, + 0x92,0x1C,0x62,0x36,0x89,0xBA,0x77,0xC1,0x27,0x05,0xF4,0x1C,0xD6,0x44,0x9D,0xA9, + 0x9A,0x3E,0xAA,0xD5,0x66,0x66,0x01,0x3E,0xEA,0x49,0xE6,0xA2,0x35,0xBC,0xFA,0xF6, + 0xDD,0x95,0x8E,0x99,0x35,0x98,0x0E,0x36,0x18,0x75,0xB1,0xDD,0xDD,0x50,0x72,0x7C, + 0xAE,0xDC,0x77,0x88,0xCE,0x0F,0xF7,0x90,0x20,0xCA,0xA3,0x67,0x2E,0x1F,0x56,0x7F, + 0x7B,0xE1,0x44,0xEA,0x42,0x95,0xC4,0x5D,0x0D,0x01,0x50,0x46,0x15,0xF2,0x81,0x89, + 0x59,0x6C,0x8A,0xDD,0x8C,0xF1,0x12,0xA1,0x8D,0x3A,0x42,0x8A,0x98,0xF8,0x4B,0x34, + 0x7B,0x27,0x3B,0x08,0xB4,0x6F,0x24,0x3B,0x72,0x9D,0x63,0x74,0x58,0x3C,0x1A,0x6C, + 0x3F,0x4F,0xC7,0x11,0x9A,0xC8,0xA8,0xF5,0xB5,0x37,0xEF,0x10,0x45,0xC6,0x6C,0xD9, + 0xE0,0x5E,0x95,0x26,0xB3,0xEB,0xAD,0xA3,0xB9,0xEE,0x7F,0x0C,0x9A,0x66,0x35,0x73, + 0x32,0x60,0x4E,0xE5,0xDD,0x8A,0x61,0x2C,0x6E,0x52,0x11,0x77,0x68,0x96,0xD3,0x18, + 0x75,0x51,0x15,0x00,0x1B,0x74,0x88,0xDD,0xE1,0xC7,0x38,0x04,0x43,0x28,0xE9,0x16, + 0xFD,0xD9,0x05,0xD4,0x5D,0x47,0x27,0x60,0xD6,0xFB,0x38,0x3B,0x6C,0x72,0xA2,0x94, + 0xF8,0x42,0x1A,0xDF,0xED,0x6F,0x06,0x8C,0x45,0xC2,0x06,0x00,0xAA,0xE4,0xE8,0xDC, + 0xD9,0xB5,0xE1,0x73,0x78,0xEC,0xF6,0x23,0xDC,0xD1,0xDD,0x6C,0x8E,0x1A,0x8F,0xA5, + 0xEA,0x54,0x7C,0x96,0xB7,0xC3,0xFE,0x55,0x8E,0x8D,0x49,0x5E,0xFC,0x64,0xBB,0xCF, + 0x3E,0xBD,0x96,0xEB,0x69,0xCD,0xBF,0xE0,0x48,0xF1,0x62,0x82,0x10,0xE5,0x0C,0x46, + 0x57,0xF2,0x33,0xDA,0xD0,0xC8,0x63,0xED,0xC6,0x1F,0x94,0x05,0x96,0x4A,0x1A,0x91, + 0xD1,0xF7,0xEB,0xCF,0x8F,0x52,0xAE,0x0D,0x08,0xD9,0x3E,0xA8,0xA0,0x51,0xE9,0xC1, + 0x87,0x74,0xD5,0xC9,0xF7,0x74,0xAB,0x2E,0x53,0xFB,0xBB,0x7A,0xFB,0x97,0xE2,0xF8, + 0x1F,0x26,0x8F,0xB3,0xD2,0xA0,0xE0,0x37,0x5B,0x28,0x3B,0x31,0xE5,0x0E,0x57,0x2D, + 0x5A,0xB8,0xAD,0x79,0xAC,0x5E,0x20,0x66,0x1A,0xA5,0xB9,0xA6,0xB5,0x39,0xC1,0xF5, + 0x98,0x43,0xFF,0xEE,0xF9,0xA7,0xA7,0xFD,0xEE,0xCA,0x24,0x3D,0x80,0x16,0xC4,0x17, + 0x8F,0x8A,0xC1,0x60,0xA1,0x0C,0xAE,0x5B,0x43,0x47,0x91,0x4B,0xD5,0x9A,0x17,0x5F, + 0xF9,0xD4,0x87,0xC1,0xC2,0x8C,0xB7,0xE7,0xE2,0x0F,0x30,0x19,0x37,0x86,0xAC,0xE0, + 0xDC,0x42,0x03,0xE6,0x94,0xA8,0x9D,0xAE,0xFD,0x0F,0x24,0x51,0x94,0xCE,0x92,0x08, + 0xD1,0xFC,0x50,0xF0,0x03,0x40,0x7B,0x88,0x59,0xED,0x0E,0xDD,0xAC,0xD2,0x77,0x82, + 0x34,0xDC,0x06,0x95,0x02,0xD8,0x90,0xF9,0x2D,0xEA,0x37,0xD5,0x1A,0x60,0xD0,0x67, + 0x20,0xD7,0xD8,0x42,0x0B,0x45,0xAF,0x82,0x68,0xDE,0xDD,0x66,0x24,0x37,0x90,0x29, + 0x94,0x19,0x46,0x19,0x25,0xB8,0x80,0xD7,0xCB,0xD4,0x86,0x28,0x6A,0x44,0x70,0x26, + 0x23,0x62,0xA9,0x9F,0x86,0x6F,0xBF,0xBA,0x90,0x70,0xD2,0x56,0x77,0x85,0x78,0xEF, + 0xEA,0x25,0xA9,0x17,0xCE,0x50,0x72,0x8C,0x00,0x3A,0xAA,0xE3,0xDB,0x63,0x34,0x9F, + 0xF8,0x06,0x71,0x01,0xE2,0x82,0x20,0xD4,0xFE,0x6F,0xBD,0xB1, +}; + +/* subject:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +/* issuer :/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority */ +unsigned char _comodo_rsa_root[1500]={ + 0x30,0x82,0x05,0xD8,0x30,0x82,0x03,0xC0,0xA0,0x03,0x02,0x01,0x02,0x02,0x10,0x4C, + 0xAA,0xF9,0xCA,0xDB,0x63,0x6F,0xE0,0x1F,0xF7,0x4E,0xD8,0x5B,0x03,0x86,0x9D,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,0x30,0x30,0x31,0x31,0x39, + 0x30,0x30,0x30,0x30,0x30,0x30,0x5A,0x17,0x0D,0x33,0x38,0x30,0x31,0x31,0x38,0x32, + 0x33,0x35,0x39,0x35,0x39,0x5A,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,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,0x91, + 0xE8,0x54,0x92,0xD2,0x0A,0x56,0xB1,0xAC,0x0D,0x24,0xDD,0xC5,0xCF,0x44,0x67,0x74, + 0x99,0x2B,0x37,0xA3,0x7D,0x23,0x70,0x00,0x71,0xBC,0x53,0xDF,0xC4,0xFA,0x2A,0x12, + 0x8F,0x4B,0x7F,0x10,0x56,0xBD,0x9F,0x70,0x72,0xB7,0x61,0x7F,0xC9,0x4B,0x0F,0x17, + 0xA7,0x3D,0xE3,0xB0,0x04,0x61,0xEE,0xFF,0x11,0x97,0xC7,0xF4,0x86,0x3E,0x0A,0xFA, + 0x3E,0x5C,0xF9,0x93,0xE6,0x34,0x7A,0xD9,0x14,0x6B,0xE7,0x9C,0xB3,0x85,0xA0,0x82, + 0x7A,0x76,0xAF,0x71,0x90,0xD7,0xEC,0xFD,0x0D,0xFA,0x9C,0x6C,0xFA,0xDF,0xB0,0x82, + 0xF4,0x14,0x7E,0xF9,0xBE,0xC4,0xA6,0x2F,0x4F,0x7F,0x99,0x7F,0xB5,0xFC,0x67,0x43, + 0x72,0xBD,0x0C,0x00,0xD6,0x89,0xEB,0x6B,0x2C,0xD3,0xED,0x8F,0x98,0x1C,0x14,0xAB, + 0x7E,0xE5,0xE3,0x6E,0xFC,0xD8,0xA8,0xE4,0x92,0x24,0xDA,0x43,0x6B,0x62,0xB8,0x55, + 0xFD,0xEA,0xC1,0xBC,0x6C,0xB6,0x8B,0xF3,0x0E,0x8D,0x9A,0xE4,0x9B,0x6C,0x69,0x99, + 0xF8,0x78,0x48,0x30,0x45,0xD5,0xAD,0xE1,0x0D,0x3C,0x45,0x60,0xFC,0x32,0x96,0x51, + 0x27,0xBC,0x67,0xC3,0xCA,0x2E,0xB6,0x6B,0xEA,0x46,0xC7,0xC7,0x20,0xA0,0xB1,0x1F, + 0x65,0xDE,0x48,0x08,0xBA,0xA4,0x4E,0xA9,0xF2,0x83,0x46,0x37,0x84,0xEB,0xE8,0xCC, + 0x81,0x48,0x43,0x67,0x4E,0x72,0x2A,0x9B,0x5C,0xBD,0x4C,0x1B,0x28,0x8A,0x5C,0x22, + 0x7B,0xB4,0xAB,0x98,0xD9,0xEE,0xE0,0x51,0x83,0xC3,0x09,0x46,0x4E,0x6D,0x3E,0x99, + 0xFA,0x95,0x17,0xDA,0x7C,0x33,0x57,0x41,0x3C,0x8D,0x51,0xED,0x0B,0xB6,0x5C,0xAF, + 0x2C,0x63,0x1A,0xDF,0x57,0xC8,0x3F,0xBC,0xE9,0x5D,0xC4,0x9B,0xAF,0x45,0x99,0xE2, + 0xA3,0x5A,0x24,0xB4,0xBA,0xA9,0x56,0x3D,0xCF,0x6F,0xAA,0xFF,0x49,0x58,0xBE,0xF0, + 0xA8,0xFF,0xF4,0xB8,0xAD,0xE9,0x37,0xFB,0xBA,0xB8,0xF4,0x0B,0x3A,0xF9,0xE8,0x43, + 0x42,0x1E,0x89,0xD8,0x84,0xCB,0x13,0xF1,0xD9,0xBB,0xE1,0x89,0x60,0xB8,0x8C,0x28, + 0x56,0xAC,0x14,0x1D,0x9C,0x0A,0xE7,0x71,0xEB,0xCF,0x0E,0xDD,0x3D,0xA9,0x96,0xA1, + 0x48,0xBD,0x3C,0xF7,0xAF,0xB5,0x0D,0x22,0x4C,0xC0,0x11,0x81,0xEC,0x56,0x3B,0xF6, + 0xD3,0xA2,0xE2,0x5B,0xB7,0xB2,0x04,0x22,0x52,0x95,0x80,0x93,0x69,0xE8,0x8E,0x4C, + 0x65,0xF1,0x91,0x03,0x2D,0x70,0x74,0x02,0xEA,0x8B,0x67,0x15,0x29,0x69,0x52,0x02, + 0xBB,0xD7,0xDF,0x50,0x6A,0x55,0x46,0xBF,0xA0,0xA3,0x28,0x61,0x7F,0x70,0xD0,0xC3, + 0xA2,0xAA,0x2C,0x21,0xAA,0x47,0xCE,0x28,0x9C,0x06,0x45,0x76,0xBF,0x82,0x18,0x27, + 0xB4,0xD5,0xAE,0xB4,0xCB,0x50,0xE6,0x6B,0xF4,0x4C,0x86,0x71,0x30,0xE9,0xA6,0xDF, + 0x16,0x86,0xE0,0xD8,0xFF,0x40,0xDD,0xFB,0xD0,0x42,0x88,0x7F,0xA3,0x33,0x3A,0x2E, + 0x5C,0x1E,0x41,0x11,0x81,0x63,0xCE,0x18,0x71,0x6B,0x2B,0xEC,0xA6,0x8A,0xB7,0x31, + 0x5C,0x3A,0x6A,0x47,0xE0,0xC3,0x79,0x59,0xD6,0x20,0x1A,0xAF,0xF2,0x6A,0x98,0xAA, + 0x72,0xBC,0x57,0x4A,0xD2,0x4B,0x9D,0xBB,0x10,0xFC,0xB0,0x4C,0x41,0xE5,0xED,0x1D, + 0x3D,0x5E,0x28,0x9D,0x9C,0xCC,0xBF,0xB3,0x51,0xDA,0xA7,0x47,0xE5,0x84,0x53,0x02, + 0x03,0x01,0x00,0x01,0xA3,0x42,0x30,0x40,0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04, + 0x16,0x04,0x14,0xBB,0xAF,0x7E,0x02,0x3D,0xFA,0xA6,0xF1,0x3C,0x84,0x8E,0xAD,0xEE, + 0x38,0x98,0xEC,0xD9,0x32,0x32,0xD4,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,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86, + 0xF7,0x0D,0x01,0x01,0x0C,0x05,0x00,0x03,0x82,0x02,0x01,0x00,0x0A,0xF1,0xD5,0x46, + 0x84,0xB7,0xAE,0x51,0xBB,0x6C,0xB2,0x4D,0x41,0x14,0x00,0x93,0x4C,0x9C,0xCB,0xE5, + 0xC0,0x54,0xCF,0xA0,0x25,0x8E,0x02,0xF9,0xFD,0xB0,0xA2,0x0D,0xF5,0x20,0x98,0x3C, + 0x13,0x2D,0xAC,0x56,0xA2,0xB0,0xD6,0x7E,0x11,0x92,0xE9,0x2E,0xBA,0x9E,0x2E,0x9A, + 0x72,0xB1,0xBD,0x19,0x44,0x6C,0x61,0x35,0xA2,0x9A,0xB4,0x16,0x12,0x69,0x5A,0x8C, + 0xE1,0xD7,0x3E,0xA4,0x1A,0xE8,0x2F,0x03,0xF4,0xAE,0x61,0x1D,0x10,0x1B,0x2A,0xA4, + 0x8B,0x7A,0xC5,0xFE,0x05,0xA6,0xE1,0xC0,0xD6,0xC8,0xFE,0x9E,0xAE,0x8F,0x2B,0xBA, + 0x3D,0x99,0xF8,0xD8,0x73,0x09,0x58,0x46,0x6E,0xA6,0x9C,0xF4,0xD7,0x27,0xD3,0x95, + 0xDA,0x37,0x83,0x72,0x1C,0xD3,0x73,0xE0,0xA2,0x47,0x99,0x03,0x38,0x5D,0xD5,0x49, + 0x79,0x00,0x29,0x1C,0xC7,0xEC,0x9B,0x20,0x1C,0x07,0x24,0x69,0x57,0x78,0xB2,0x39, + 0xFC,0x3A,0x84,0xA0,0xB5,0x9C,0x7C,0x8D,0xBF,0x2E,0x93,0x62,0x27,0xB7,0x39,0xDA, + 0x17,0x18,0xAE,0xBD,0x3C,0x09,0x68,0xFF,0x84,0x9B,0x3C,0xD5,0xD6,0x0B,0x03,0xE3, + 0x57,0x9E,0x14,0xF7,0xD1,0xEB,0x4F,0xC8,0xBD,0x87,0x23,0xB7,0xB6,0x49,0x43,0x79, + 0x85,0x5C,0xBA,0xEB,0x92,0x0B,0xA1,0xC6,0xE8,0x68,0xA8,0x4C,0x16,0xB1,0x1A,0x99, + 0x0A,0xE8,0x53,0x2C,0x92,0xBB,0xA1,0x09,0x18,0x75,0x0C,0x65,0xA8,0x7B,0xCB,0x23, + 0xB7,0x1A,0xC2,0x28,0x85,0xC3,0x1B,0xFF,0xD0,0x2B,0x62,0xEF,0xA4,0x7B,0x09,0x91, + 0x98,0x67,0x8C,0x14,0x01,0xCD,0x68,0x06,0x6A,0x63,0x21,0x75,0x03,0x80,0x88,0x8A, + 0x6E,0x81,0xC6,0x85,0xF2,0xA9,0xA4,0x2D,0xE7,0xF4,0xA5,0x24,0x10,0x47,0x83,0xCA, + 0xCD,0xF4,0x8D,0x79,0x58,0xB1,0x06,0x9B,0xE7,0x1A,0x2A,0xD9,0x9D,0x01,0xD7,0x94, + 0x7D,0xED,0x03,0x4A,0xCA,0xF0,0xDB,0xE8,0xA9,0x01,0x3E,0xF5,0x56,0x99,0xC9,0x1E, + 0x8E,0x49,0x3D,0xBB,0xE5,0x09,0xB9,0xE0,0x4F,0x49,0x92,0x3D,0x16,0x82,0x40,0xCC, + 0xCC,0x59,0xC6,0xE6,0x3A,0xED,0x12,0x2E,0x69,0x3C,0x6C,0x95,0xB1,0xFD,0xAA,0x1D, + 0x7B,0x7F,0x86,0xBE,0x1E,0x0E,0x32,0x46,0xFB,0xFB,0x13,0x8F,0x75,0x7F,0x4C,0x8B, + 0x4B,0x46,0x63,0xFE,0x00,0x34,0x40,0x70,0xC1,0xC3,0xB9,0xA1,0xDD,0xA6,0x70,0xE2, + 0x04,0xB3,0x41,0xBC,0xE9,0x80,0x91,0xEA,0x64,0x9C,0x7A,0xE1,0x22,0x03,0xA9,0x9C, + 0x6E,0x6F,0x0E,0x65,0x4F,0x6C,0x87,0x87,0x5E,0xF3,0x6E,0xA0,0xF9,0x75,0xA5,0x9B, + 0x40,0xE8,0x53,0xB2,0x27,0x9D,0x4A,0xB9,0xC0,0x77,0x21,0x8D,0xFF,0x87,0xF2,0xDE, + 0xBC,0x8C,0xEF,0x17,0xDF,0xB7,0x49,0x0B,0xD1,0xF2,0x6E,0x30,0x0B,0x1A,0x0E,0x4E, + 0x76,0xED,0x11,0xFC,0xF5,0xE9,0x56,0xB2,0x7D,0xBF,0xC7,0x6D,0x0A,0x93,0x8C,0xA5, + 0xD0,0xC0,0xB6,0x1D,0xBE,0x3A,0x4E,0x94,0xA2,0xD7,0x6E,0x6C,0x0B,0xC2,0x8A,0x7C, + 0xFA,0x20,0xF3,0xC4,0xE4,0xE5,0xCD,0x0D,0xA8,0xCB,0x91,0x92,0xB1,0x7C,0x85,0xEC, + 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, +}; + +#endif /* _TRUSTTESTS_TRUST_INTERFACE_H_ */ diff --git a/tests/TrustTests/FrameworkTests/TrustSettingsInterfaceTests.m b/tests/TrustTests/FrameworkTests/TrustSettingsInterfaceTests.m new file mode 100644 index 00000000..8228cb35 --- /dev/null +++ b/tests/TrustTests/FrameworkTests/TrustSettingsInterfaceTests.m @@ -0,0 +1,126 @@ +/* + * 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 +#include "OSX/utilities/SecCFWrappers.h" +#include +#include +#include +#include + +#include "../TestMacroConversions.h" +#include "TrustFrameworkTestCase.h" + +@interface TrustSettingsInterfaceTests : TrustFrameworkTestCase +@end + +@implementation TrustSettingsInterfaceTests + +#if TARGET_OS_OSX +- (void)testCopySystemAnchors { + CFArrayRef certArray; + ok_status(SecTrustCopyAnchorCertificates(&certArray), "copy anchors"); + CFReleaseSafe(certArray); + ok_status(SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem, &certArray), "copy certificates"); + CFReleaseSafe(certArray); +} +#endif + +#if !TARGET_OS_BRIDGE +- (void)testSetCTExceptions { + CFErrorRef error = NULL; + const CFStringRef TrustTestsAppID = CFSTR("com.apple.trusttests"); + CFDictionaryRef copiedExceptions = NULL; + + /* Verify no exceptions set */ + is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set"); + if (copiedExceptions) { + /* If we're starting out with exceptions set, a lot of the following will also fail, so just skip them */ + CFReleaseNull(copiedExceptions); + return; + } + + /* Set exceptions with specified AppID */ + NSDictionary *exceptions1 = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"], + }; + ok(SecTrustStoreSetCTExceptions(TrustTestsAppID, (__bridge CFDictionaryRef)exceptions1, &error), + "failed to set exceptions for SecurityTests: %@", error); + + /* Copy all exceptions (with only one set) */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, &error), + "failed to copy all exceptions: %@", error); + ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Copy this app's exceptions */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error), + "failed to copy SecurityTests' exceptions: %@", error); + ok([exceptions1 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Set different exceptions with implied AppID */ + NSDictionary *exceptions2 = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@".test.apple.com"], + }; + ok(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)exceptions2, &error), + "failed to set exceptions for this app: %@", error); + + /* Ensure exceptions are replaced for SecurityTests */ + ok(copiedExceptions = SecTrustStoreCopyCTExceptions(TrustTestsAppID, &error), + "failed to copy SecurityTests' exceptions: %@", error); + ok([exceptions2 isEqualToDictionary:(__bridge NSDictionary*)copiedExceptions], + "got the wrong exceptions back"); + CFReleaseNull(copiedExceptions); + + /* Set exceptions with bad inputs */ + NSDictionary *badExceptions = @{ + (__bridge NSString*)kSecCTExceptionsDomainsKey: @[@"test.apple.com", @".test.apple.com"], + @"not a key": @"not a value", + }; + is(SecTrustStoreSetCTExceptions(NULL, (__bridge CFDictionaryRef)badExceptions, &error), false, + "set exceptions with unknown key"); + if (error) { + is(CFErrorGetCode(error), errSecParam, "bad input produced unxpected error code: %ld", (long)CFErrorGetCode(error)); + } else { + fail("expected failure to set NULL exceptions"); + } + CFReleaseNull(error); + + /* Remove exceptions */ + ok(SecTrustStoreSetCTExceptions(NULL, NULL, &error), + "failed to set empty array exceptions for this app: %@", error); + is(copiedExceptions = SecTrustStoreCopyCTExceptions(NULL, NULL), NULL, "no exceptions set"); +} +#else // TARGET_OS_BRIDGE +- (void)testSkipTests +{ + XCTAssert(true); +} +#endif + +@end diff --git a/tests/TrustTests/Info.plist b/tests/TrustTests/Info.plist new file mode 100644 index 00000000..6c40a6cd --- /dev/null +++ b/tests/TrustTests/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/tests/TrustTests/TestData/TestCopyProperties_ios-data/InvalidUnknownCriticalCertificateExtensionTest2EE.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/InvalidUnknownCriticalCertificateExtensionTest2EE.cer new file mode 100644 index 0000000000000000000000000000000000000000..9200cccb39a7cbfafb3eb1d101cc859ed36263b4 GIT binary patch literal 954 zcmXqLV%}!Z#58XKGZP~d6JxvqFB_*;n@8JsUPeZ4Rt5uCLv903Hs(+kHesgFU_*HW zSrCUySS%#9xJ1D@wWuUBEi*Z>B(+$<$iUFhP}D#eq<~qNC#0wpsKPNXIU~QwKu(<3 z(7?bD2rY~a3=E>gd5sMWjf`PjgHjT$aW!y;SYzXvSC*KQnW7Mymz|eio~Phklvx6F zP!6)&6kIDxQuB&4^Yav3UBMCxAmYLNot*vfJZ1b$@w#=L?*j(uwZ+K*u>ptuLZ%H1X6TKf_cTE&J?>yB(uJ4od zf_XFJ+?2%St(VR*xWe{(+g#ziEt~zD%dG2HBy~%6i0eW=aoyZ$;brUi^8~<441Wi~^_MN8Xp*bl$N3|BHXV zhn8&7R}=Qn6Ylf7<~O^#{>T2nGp`@{Z)?eYD7jhjyKK$I={jD=lAf~X`1bdui1oj0UTk<|CnU(NH zY<6X0W@KPo+}L1HXCMy@Z&_s)2?MbPktenB7h|TjapZ4|HMm^4bWj34t-!b0o zFObmts;TT%_^)49nyN-mX01Pbda<7V4bMq)6&Wi&^gP%PcR~_uZR! zs_$KgmPyd6!>3wHQ^K}f)=YWep;1-kQ+M>X!%>B^`p+)&`8_H=aI>d~UFhGE3Gxq% v|Jv9JE>5%&SZUgQ)^CUR9If56Vq|u|Z*Y;?9{E1y@?zJMUh^;eH+=;F6$Ea# literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/TestCopyProperties_ios.plist b/tests/TrustTests/TestData/TestCopyProperties_ios-data/TestCopyProperties_ios.plist new file mode 100644 index 00000000..cafcfaf1 --- /dev/null +++ b/tests/TrustTests/TestData/TestCopyProperties_ios-data/TestCopyProperties_ios.plist @@ -0,0 +1,771 @@ + + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + UnknownCriticalExtension + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.2 + + Leaf + InvalidUnknownCriticalCertificateExtensionTest2EE + Anchors + TrustAnchorRootCertificate + VerifyDate + 2011-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more unsupported critical extensions found. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + UnknownCriticalExtension + MinorTestName + TwoFailures + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.2 + + Leaf + InvalidUnknownCriticalCertificateExtensionTest2EE + Anchors + TrustAnchorRootCertificate + VerifyDate + 2001-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more unsupported critical extensions found. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + PolicyFail + MinorTestName + NegativeTest + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.42 + Properties + + SecPolicyName + bbasile-test.scv.apple.com + + + Leaf + generic_apple_server + Intermediates + AppleServerAuthentication + Anchors + AppleRootCA + VerifyDate + 2019-04-18T19:00:00Z + ExpectedProperties + + + type + error + value + Policy requirements not met. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + HostnameMistmatch + MinorTestName + PolicyFail + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.42 + Properties + + SecPolicyName + idiagnostics.apple.com + + + Leaf + generic_apple_server + Intermediates + AppleServerAuthentication + Anchors + AppleRootCA + VerifyDate + 2019-04-18T19:00:00Z + ExpectedProperties + + + type + error + value + Hostname mismatch. + + + type + error + value + Policy requirements not met. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + PassingTrust + MinorTestName + PositiveTest + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + content.googleapis.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + GlobalSignRootCAR2 + VerifyDate + 2018-04-14T19:00:00Z + + + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + + MajorTestName + AnchorTrusted + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + content.googleapis.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + AppleRootCA + VerifyDate + 2018-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + Root certificate is not trusted. + + + + + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + + MajorTestName + AnchorTrusted + MinorTestName + HostnameMismatch + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + www.google.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + AppleRootCA + VerifyDate + 2018-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + Root certificate is not trusted. + + + type + error + value + Hostname mismatch. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + HostnameMismatch + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + www.google.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + GlobalSignRootCAR2 + VerifyDate + 2018-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + Hostname mismatch. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + Expired + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + content.googleapis.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + GlobalSignRootCAR2 + VerifyDate + 2019-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates have expired or are not valid yet. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + Expired + MinorTestName + HostnameMismatch + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + www.google.com + + + Leaf + googleapis + Intermediates + GoogleInternetAuthorityG3 + Anchors + GlobalSignRootCAR2 + VerifyDate + 2019-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + Hostname mismatch. + + + type + error + value + One or more certificates have expired or are not valid yet. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + MissingIntermediate + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.2 + + Leaf + googleapis + Anchors + GlobalSignRootCAR2 + VerifyDate + 2018-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + Unable to build chain to root certificate. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + MissingIntermediate + MinorTestName + Expired + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.2 + + Leaf + googleapis + Anchors + GlobalSignRootCAR2 + VerifyDate + 2019-04-14T19:00:00Z + ExpectedProperties + + + type + error + value + Unable to build chain to root certificate. + + + type + error + value + One or more certificates have expired or are not valid yet. + + + + + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + + MajorTestName + AnchorSHA1 + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.24 + + Leaf + escrow_service_key_049F9D11 + Intermediates + EscrowServiceRootCA101 + Anchors + EscrowServiceRootCA101 + ExpectedProperties + + + type + error + value + Root certificate is not trusted. + + + + + CertDirectory + si-20-sectrust-policies-data + BridgeOSDisable + + MajorTestName + AnchorApple + MinorTestName + PolicyFail + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.68 + Properties + + SecPolicyName + identity.ess.apple.com + + + Leaf + ids_ist_identity + Intermediates + AppleISTCA2G1 + Anchors + GeoTrustGlobalCA + VerifyDate + 2017-02-08T21:00:00Z + ExpectedProperties + + + type + error + value + Root certificate is not trusted. + + + type + error + value + Policy requirements not met. + + + + + CertDirectory + si-20-sectrust-policies-data + MajorTestName + AnchorSHA256 + MinorTestName + PositiveTest + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.74 + Properties + + SecPolicyName + caldav.icloud.com + SecPolicyPolicyName + no-system-pinning-rules + + + Leaf + caldav + Intermediates + + AppleISTCA2G1-Baltimore + AppleISTCA2G1 + + Anchors + BaltimoreCyberTrustRoot + VerifyDate + 2019-10-04T19:00:00Z + ExpectedProperties + + + type + error + value + Root certificate is not trusted. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + WeakKey + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.2 + + Leaf + leaf512 + Intermediates + int2048B + Anchors + root2048 + VerifyDate + 2016-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates is using a weak key size. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + KeySize + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + example.com + + + Leaf + leaf1024 + Anchors + rootSSL + VerifyDate + 2020-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates is using a weak key size. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + KeySize + MinorTestName + Expired + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + example.com + + + Leaf + leaf1024 + Anchors + rootSSL + VerifyDate + 2019-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates have expired or are not valid yet. + + + type + error + value + One or more certificates is using a weak key size. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + WeakSignature + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.2 + + Leaf + leafMD5 + Anchors + rootSHA256 + VerifyDate + 2019-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates is using a weak signature algorithm. + + + + + CertDirectory + TestCopyProperties_ios-data + BridgeOSDisable + + MajorTestName + SystemTrustedWeakHash + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + www.badssl.com + + + Leaf + leafSHA1 + Intermediates + intSHA1 + VerifyDate + 2016-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates is using a weak signature algorithm. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + SignatureHashAlgorithms + MinorTestName + OnlyFailure + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + www.badssl.com + + + Leaf + leafSHA1 + Intermediates + intSHA1 + Anchors + systemRoot + VerifyDate + 2016-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + One or more certificates is using a weak signature algorithm. + + + + + CertDirectory + TestCopyProperties_ios-data + MajorTestName + SignatureHashAlgorithms + MinorTestName + HostnameMismatch + Policies + + PolicyIdentifier + 1.2.840.113635.100.1.3 + Properties + + SecPolicyName + example.com + + + Leaf + leafSHA1 + Intermediates + intSHA1 + Anchors + systemRoot + VerifyDate + 2016-01-01T20:00:00Z + ExpectedProperties + + + type + error + value + Hostname mismatch. + + + type + error + value + One or more certificates is using a weak signature algorithm. + + + + + diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/TrustAnchorRootCertificate.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/TrustAnchorRootCertificate.cer new file mode 100644 index 0000000000000000000000000000000000000000..04efaa0659ba5a46a9131e8283db71b06ccf8b25 GIT binary patch literal 843 zcmXqLVssC%f_kI=F#?@mywa1mBGN(klTQhjX9KsO_(V(*iha; z7R2Ea77Ix&E>Un!Eh@=O%S=uzNi9||GB7kW6g3bADPR`n2`MTCs&LFp&d4t^kQ3)M zG%zp(LJMO91A{1WUSk78BV!nsTGli%Dj|D-k(GhDiIJbdpox)-sfm%1Vdu=iPC@qv zXI*!;s5c2SiJf(^T(#yl=iz&gbo_2F37#(;syo-e zXN3GyoGP=?{_y9fXa)|&EyuIPvn7tQy|Ls}U(xX{=hf0P{reRd7GK`(QE_tp>kZGo ztd^C!x2?2nSFQ9S>0_IMs~#M)59pXU=VL*62J`!6pZKkKu4x(R3M`%a!SmS>=ks^6 z1B#Ox4MfVqp60JvJ?FNsTBf$kGyO?&Yjj+$v|p5HchLTQPd+vDzGTGCw>s9xBR(-) zdCJ_&#LURRxY)_S0UV98d@N!tB2Q}LFUCx5hhbhE7A=3fRQN6&&c?n zg$0-}*bMkVd|?ou)qojDA%`+BnE*qXkzvNd^?B~|yi_eU4=X=v=@6G&_dor3;k{+4 z98(O0XH8(8dSc_hIPRlSe>tA}6gNG{t}y0GU$t@t-~%3 z&+fna<1XdobF*F^<&0U;7SS_h>eiF&R~oK~Y>eBHy3dOFyg&r+BZ(_d8$CAouD+&c z*DWcxtLx*jLtFWO+{ld)Ff4jCKPp-6wx7)$J?8TZ7l(f$NY9jV?I;vcU&zO otJ5y6(^M<1Jo9;L!CzBPwtyUSeJgLCX`9a%B~G3HcWKR00Js}O*Z=?k literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/int2048B.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/int2048B.cer new file mode 100644 index 0000000000000000000000000000000000000000..34379d2df1e14ad5a70ccb129eaf9c18418ca1cb GIT binary patch literal 1005 zcmXqLVt#4R#B^~1GZP~d6DPwy%{RFYbuKdvc-c6$+C196^D;7WvoaVob{ldVaI!In zvaks=g$5f68wi3p96Vgki8+~R`9*n|iH1T30w6(l9!}@dg4Cjt%)ER<5d$HR7#9z> zV?jYqs*ZwZUb3E{tbsI0l$%E+I5oMnD6^ze!8I>EGcPr@C^IkJP|iRGB+bktYGhzy zp_`Ohq7af=T%r(^pI@Tj>}Vh-&TD9DXk=(^U}RuvY#9aQngO|HP_98a5ssy*!-7kb zoE;U644N2~kVB4NcMjXXoTGbooxZQjw^uIx=YUuZl{X?AwYdwyyB^*;jb+ zg|)BNHb*0twCI?aUcNsKT58HaUX?F=^HD!}!{!D3!M8uv&HK?m+j~*?)|c+@+up6~ z*!n%ssd8q^j(QJw)u4_!@~dmlbt_s{f4jIt``j%>QL7KU7bE$<{LemL82hsS`9c5h zuXa40FScDgO5IfFp2WA%JFF6ygm_F{I{v(ga}&SiakcnT@oOe#Mh3>k$p(oA{J;p7 z6=r1o&%$cJ45SSBKmz8Hq|F~bnH%D*zztr%3(kbVDdmGnO&OR5uZ?mAw z!5hsTj7&9wMutnDKe{w=wZHlE-aRgpPiXRH7~Bq#a+(x!hnpBY&#loeYS6|MCe0MouXk0={`ungQbtXS=v?7Hx>+x0zDW{z#co*tP3LiI50Apk%!FV7 DCxd%Z literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/intSHA1.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/intSHA1.cer new file mode 100644 index 0000000000000000000000000000000000000000..261ecdafe8c95d62fbba479507fd2d6ae31b18c4 GIT binary patch literal 1171 zcmXqLV(B+%VlH36%*4pVB)~RLc6D}zCz zA-4f18*?ZNn=n&ou%W1dFo?q?%;S=op6Q%gRHERSmux6$APy4d78WQkFV{-}N+koO z^pf*)4HXRJKvK-Y;&2`AIr&M6ISN7f`6UX@js|k#yoSaG#s(IKMg~9-CC+Pv%r)>J z$_Yva3J`lF;r0ZlCYKhaDg>t%m8BMeY-(auLiQgcD+6;ABR>OBoQtW6k&$6{_!GsI zS7#@f*Yzz-tZ#fIb*MDu=EMN*CuS}xc?OqeSE>Ixl(jCafYV~90@sOD0k4iVhM(?C z`josdwjnvPVUn`Uv-f3Q0j4K!6k6y2}=7l?FeRrX0Jy%-*qL!i{?|b(yt4 zCWu;HSh!%{uT7gI7v9jmcy538UC-5vC;i*H`ouxIcZ>`-R=VtPD(*O(_;s~cvj*3t zE1tiyHlDp7t~2H7qf^cC+jk|!=w~ebaA4l}&Q zH@{^(y6?)w%*epFxQQ_e7$RW?Lcs8p6=r1o&%$BA2Ber684UP9V*DU67GU~mGcaM} z&}IWB6m~{N77YV60~HwGfU!*?qokz3N?$)exwrr&O&C;zOp#|PF(@)HUtqexxXlo% zG`T3p7)7Z*EHWW!29#u+9rb|9Fg2PGsnHf>xdMxsfr)_;8w-%hV4!870dqGKqnHfH zF~vZKqo-wk=YU`XS&()<7BLo)35B=KUl*Tvf9I;4&^D7@+EELZO)`)NNh`BR7>G59 zFy9L>4ZG;GJMF{bN7B-Vr*E>o7>b>k^ zp|nKiOvT0}{;$4VI5Kz9y+(F5d54a`5Ax@?`#8+J@WrNZMsde<9m(r?E&WU6=R_$y z4vg7wbl%J?{}Y+t1^)Z3mArW}Vzco&o}1G&=M`=$NM5{crkIm#>gVqZ;E&~I25}>U+J2~hi`MTYu#SYEcyQ0i*MyJmelcL;r#P%qb1X!^#^`JceWH`?_+ej++bJ*21s-t*N!VZafrRC4w*BvnKdokff^>G7UHcqWJkGAi;jEvl@ z3T!G^*Hf*=kD50`UdPG(wuQC?=Ep^$+9NRXX})48-DwWuUB zFCV6mi-*gxpdcqz!80#e&rsGt8l;e$M}Vh-&TD9CU}9)#WMpD!WDzCKYh(cAT0pr5jZJiP zs+fTY#HqYsr+TMWD)^)(rWrKOM-D+oRtDzAUSKG8GBq|boQ%D=;$2n_*HWq46{i;8 zsXgre!;@#}eXmmudy0Agnki0pWB$_PcT?ZLR$27f>A?QSi>9|9S5@V$zopoHgz@1W zj{J4!J8!uz7J7L2<$fz6p1Z2E?@cq+v0rqS;s3%uruT-&3|upPXMJSd5|p~U^`-f) z1v{s8#BN=G>(Skeq^W0&nV1tS}?ve-0%r`OZ)(%V74c>7w6vZb1$? zVA^ADVq|3SU7-K`$penkN@1Cxk0(^NDu(bXyyko(-MM#}yPUH>qfxWt;R{;ZZb#3b zu61p*#nn)wEtPT}GE1569oAcWYEAfpv+sBnzwiID-6qQPue`g@rXxyz%i@=F&QkO1 z^5K?RpZz^POz7r8HN{6u&$%+}+}3g8(#f_C*_cCF z*o2uvgAIiZ1VJ1Q9xms^oXoWRqP)yRLlFZZkRTTiw_`y;PO6TAXI`?Np{#*4NR*pL zBsev>v?#NrQo%JZJu@#gwJ0+$-B8Xz1|-eQBWh$|VxgOqS)veBs{F|8aXWgr1@m>|%4gu8rF6VnW0kb{Sjm4Vrt z!N7ybk>Rz;jpp2ccRAG$E?h1@cg6kCdm+rWP9Z9`le!hX-}PwEu{XJxeeb{_1-ACt zg424os@$FYOuGDF)dl%WoVJQxqD;(;42+9Q4T=qTfOg9YGcx{XVKQJa-~;jaK|B^_ zCe{T8!XUmX3y%R88;3Ro@{P8k0!Uh=b5%g=2iXaiD1r}fJ@FR{e^caos7wNmNJB~GCuTHkcnc?!qH1%@+3eD=ou zD!#*2v}8j?*Rg-QqxM%A^{Q1b-pl4X`Pj6XB0ZTGgYI0Bu{%A{ZIbjp#W#wNb}C=p zu-56RSD-FP9W6IXKcD zhSdMDjcvTK!u_!I%b;@BPfqugRc2Nxc(!@6B$V&HYP{Psv0G+$-wW9#a!VA;BliLT DWb*@5 literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/leafMD5.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/leafMD5.cer new file mode 100644 index 0000000000000000000000000000000000000000..d03c75c31b7e3b058e282bd49b30bab1209a13cd GIT binary patch literal 1121 zcmXqLVu>|qVs>4?%*4pVBwVGmutQ>AY5BAFbq9?5UQBpVebj)LjZ>@5qwPB{BO?nd zgF$1XA-4f18*?ZNn=n&ou%WPlAc(`k!{wZqlbM!Zl$V)kC}bc25@hG$bS^DOEh@>( z%ZDlC;^A^ED9A}w@XSlrGn6%u1}Ws`5eZIBE-lI|sZ?;yOV7+pO)bjIOE(lX5C%yz z^YDbE7MCal<>!|uI6E51iSrs-7?>Fv85x_Hnp#8wxt2&=gT^L0x>3wP1mZ?sup50{ zOci`m6VnWu7?qI2j**ptxrvdV0VvMJ)Wpchuyz~YmKO`#Z*!$Dda(AglEMBe@hMXu zEk68t`9;H3SMr4vvNQ}AGYM`#{oeCo?`p?puHE-sCKn5P|269hH?VC>nxuFsj=a~%#G+CO#e|BkOh zjtv{@*6KHO98c){XTx)Ga8726bZ8M8}K%9 zr&c890+WMT|v6i>3V2(anJiT9pNQ-^eqbx0%xJVjvHaR%Vef5NiX!gh zrn947N@@{ubOW;rFuEBT=CU5xc2AJuw&tca&;Iu4c2t)3|E)>QUH4t`OHidqPq<}3 z@UNX`qTkI?J|wz#%Pg+kBR!Uj*IkjFE49}qr(i1guV>tTJ4^*U&sfzw2ycCG)o(-g zjtAx+Kjs+qb%iz-dLJ(B{VzC2`(@$sU5vLDc)7i4JK>VXQA=5)ap!{2vm8;4lf~{H7cpu7|5SMKk*L2v9Ln$Pd$ZAyb=kvw9ivOv ebA3PE*Ne?FtYcFU{8>}<*nOAra;}m|^(6p8PmuTk literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/leafSHA1.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/leafSHA1.cer new file mode 100644 index 0000000000000000000000000000000000000000..7e6986e93126ecf2cfa999f6aa81ed3e22df54a6 GIT binary patch literal 1286 zcmXqLVr4RDVt%!NnTe5!Nq~EyhT-b2+BUz$$U7#_<9H2t**LY@JlekVGBUEVG8lLm zavN~6F^96S2{VNT8;TkTgE(BmJT95(na-(2B?_K-$%aY>3Ls%-VM(}faB6aCQK~|4 zYEfBgk%F_Mft)z6p{aqHfu#W$L;<?Xo_8#VHs1)iS`cw&vc&6{6&aozl(zny zI&Y)4PMKZK0q+DKpI4i<9N=%*w&7>d$u_2+F^;jq+VzD;y!X7Eq8DJkEL|qC=bNL` zQMb!t?dtPOUUSVA3{q1p&S~+f41IDj`vse=hiK5+%^J5?{m=WKFx9I(+w!BzMZ;}( zeGeS@6TCCmY3%4g7Hz4ES|oNSb7Q#6Z7!kJ z_YU*Bm&7 zED{D{4I&c?Z=1g^KJos}RXL$;CcCtw7A%`&APZ8!$0EieGWXrV>PBuW_sl|xT0!&4 zdzMPu|29wtNei;b7)Uj7AtIp(HA?tEiuf5B|Ff_#GqEm!n5oJlW+1}Gq0I(Ni0sTv za2BIMB1pMBOO!!`fz|?z1!`?786_nJR{HwMMLEWLDZrGO3{07z$ks0|PEOQKH`fEo zV5&92t=0)-g#wE;Fu9tuaVE5RFt+{8VPrJWGSGlIgo#m124rtB(Bks)a#XXN1A+}I zU@93IS#k`r3{+rz1I9K9sEhNHiwjV68aTmKF}0b&{FMmuP%(-^eOOk5}h%72yT>9$)p)_;7|ZnpT@?Nc-EN7=;OpDMHb<>^f~zdllk@%?f+_ngGpBrD2-o=4 z&1}E(%mjzYy9-W)MXvD8Dxb1S^j(~=zzOyvXOI68tc*o)`qrZt^0cUhjP{rbuoXL8o(!D^=6Gm`7r!}C@pb_M^jn_Aw| kuPHfvp;G%)p~8hNiMu{>vu|NE$`H{!8DSOvEJm>c0P79E>i_@% literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/root2048.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/root2048.cer new file mode 100644 index 0000000000000000000000000000000000000000..36a6b3509c06184489bad7ca3c8470dcf309df20 GIT binary patch literal 996 zcmXqLVt!!I#B^c-GZP~d6DPx^1>$*Mwtt>xz{|#|)#lOmotKf3o0Y+!vD=W_fRl|m zl!Z;0DKywn*gz1(;o#wNPRz+n%P-2yOf(cS5C93X^Kd$s7Ni!HWai}?iWmri#JG64 z9SaI_QgswO^OE%pWeuc3qTD^S?3Z#r^G4rSccA`zpp&-mg3F>i*T2_1ebIuYPFUSfg{UdH>Ra{Af4JZwD*F z3{~nx&#?r|G`RI)o$}qbkhOb4T_>M8@m$P}!9=I0-|#Jm{mo?)jLfCaUJ+}4_cN%$ zPF?N&`=5W8UA1Vw*}v_>LSFyQ-WrkG{;HOrr+YHyedg22*l(Vxl|G?%{fBCcJ)6rf z-u)71zrf?guE-nP{s-3VIJb@|s!;A)6j!La=A1*{y7_p2eYQ^!fAMR^fl1dzW?!^p ze$pH9--ofhq?vKq#zqr0-XE(tKHYg`B*?_f$iTSR)xa5?RAhx28UM3z7_b2;CProh zK440as6$0Eiea>}=R?+i1gA1f96Uj2D?UA%GmBO&B~2BuqJKr=GT zoOwI)ozV=LCrM9!E`7Pg-ZR|1(8Mldo%)vbr>Fg0!S$R=sV1&s>dN%>TkdjRe9Du3 z?1t3iiSc_c?Bti-x&7nulvArS^DZQAp06&)w#}(!b^dehJuDh2hYrX(|JRbWpS1A$ z)!!^X!{=AD_uSrW?>Mb5HNf)ug)U3Y3?V_6yVY%x>m6QI+`PN>_VW5GyQcKkF1@hI z!$~fu(Ae`7@7G>|3wA#)o33j<#iV@btYYbGod@5Q)mYwEywEgmPo3dYcQ|qD?XH9T8G4>kO8<30M%cAUFpz{|#|)#lOmotKf3o0Y+!vC)v*fRl|m zl!Z;0DKywn*gz1(;o#wNPRz+n%P-2yOf(cS5C93X^Kd$s7Ni!HWaj0=6ms!!ITjS; zq$+skCF>c=8c2f_a`T7;rzV#cWtLPbxaOs2=B1_}nTy{=#{*>HRclh~hrPK04Rtdi| zM|#wKLKXL)+Oc+vo*y@l^Z6-$LAxzqXJ#9H=nyl0GO_C0@;w^!*E%pAUnm?m<~izM5)us^9F^17`yvU=+&=Gcx{X;V@tWQcR2t27DkfevlXoFg>yv z$b$HMEMhDoTUQ2i2v|rh-Q05W-I3M&JK{4079j^TFpUBOnvvnwifz&>MAdJte5rq^ zeOn#Zy^hqK%JJ2v4{vYUWi9*EPN7bF@`bH$X8Y|(SyxrQt)^kFsgv@$iCL@F_qjDZ zh*;U<{=crW{?CTO|E6AX25Y{aJ{EpyvR}m&ks9Z$I0eRS298HI*cS0zGwU$-dii;` zhHP+Bu5{(9JD<2_U1OLh(PUS9aZZ%j(&fb&iODn7dUvj8oUvqzY`st**P3&wyY^fB zynV81u}-W~`>RW?m)`_@)U4(d@O_|Y>Tl1l8EeqI_oi!w=k@i+KGuoam4FI(Q BYJmU% literal 0 HcmV?d00001 diff --git a/tests/TrustTests/TestData/TestCopyProperties_ios-data/rootSSL.cer b/tests/TrustTests/TestData/TestCopyProperties_ios-data/rootSSL.cer new file mode 100644 index 0000000000000000000000000000000000000000..7c98079d71ead3c56ed836479f198d419767a3f0 GIT binary patch literal 990 zcmXqLV!mb2#B^u@GZP~d6DPyD4f_*IC;tpK;AP{~YV&CO&dbQi%F1BS*kQ#HfTEkc_Mh%uS5^ z3VywNffJbJiXyS~>UNfqEw+rfC2FarH|tsQvuj@bgU@|4MG5ys5GhCwZ%b zE}4JKaGev8-*LQfKGQ1~;ZLz^8m~vrkX*DQY;ouDn{kU)>^d}k3g_;|doO0OO17`yvV1&yGGcx{X;V@tWQcR2t27Dkf zevlXoFmBAeU8vM(mky+kXabKGl#O^(A+USAgJA)y2{KnYS!5Z{Vnoy=|$@ zwjd{3R!*@p+N6Sc(SH4m3Ex+Snyy!m_&RNJ%De-9W%FK1NKdc+UFd5N6YFz-izAQd zfhnt6cZ6DcE{Qi@7_ReC>=^eMWACMlU6L1{o`3Sk%)n%g-s6v5^ZnF%Ufo((@~3f6 z+{cuwPm@bbW*3G0d>Hji=e+h!?u%b`1kRmXa7gCRx>koSS@a`rrQKYGZP~dlK_YHgRlusZW|YtW}S?jc-+f?myJ`a&7D}zCz zA-4f18*?ZNn=n&ou%W1dFo?q?%;S=op6Q%gRHERSmux6$APy4d78WQkFV{-}N+koO z^pf*)4HXRJKvK-Y;&2`AIr&M6ISN7f`6UX@js|k#yar~5hK2?Z5GBrQ4CKMN^l(BG zqY|>m8Ce;an;7{S44N3Zn3@dd`IJs!)JE3#aq8T|A z&M;11?q{$)_`CCwOos5ek9w8vwzD}fG;*FhC*8dN{#olnw@25~jV;t*_#-WJ|60ik06Z{$usNcN*7A>Z>YdMz&_;#V8wj@Ao_KA}aTB!TxfA z{eKw0wccFeA`oG;vQ*;g#YOwvAE{@3nPvRLlOv(~O8ge9mi-G?dHK}Zo%fH=DT`a+ zZ9Z|{9i?Zv=R~CXvQGayyICYf{CKqHJfr=e-u=4F?Q~`Jc1NRIJXhZTXuP_+H^P3a z^b1doMFqDES?+${B=*UN%a47$hjQ?3! zfC;G0fFHyc2Ju-9n1PgmEJ%QlMT|v+`Cfo&*hQb+X&)9pl9oO^eUt6QPy>08v@(l? zfmj1}1*qu{7!8aJr{|cj@(>o{`gPZ3j(^aGFZb86e66hHSga!P$6LGQfbPz#$Nzmf zC?9cpNA8@elIJrtR|{@^T(Dr_S)Y!XlY1r>JX*~!vv2as|H)UMuqRwzynk*q=f|sk zkAuJTCI7NtetS#W{iL*O7xNr@Kk06LRqi!^Zp0()$O8__Z*?`AT67HFks3>ujWo?Cxj#WeU z^4IG{MPAb-4oIsket75QefOHJTU0n$4c_SP<=*eQKVav| c&#z}N3avfSacqW3d@q;Hv6ok;PR+ds0Q5R + +#define isnt(THIS, THAT, ...) do { XCTAssertNotEqual(THIS, THAT, __VA_ARGS__); } while(0) + +#define is(THIS, THAT, ...) do { XCTAssertEqual(THIS, THAT, __VA_ARGS__); } while(0) + +#define is_status(THIS, THAT, ...) is(THIS, THAT) + +#define ok(THIS, ...) do { XCTAssert(THIS, __VA_ARGS__); } while(0) + +#define ok_status(THIS, ...) do { XCTAssertEqual(THIS, errSecSuccess, __VA_ARGS__); } while(0) + +#define fail(...) ok(0, __VA_ARGS__) + +#endif /* _TRUSTTEST_MACRO_CONVERSIONS_H_ */ diff --git a/tests/TrustTests/TestRunners/AppDelegate.h b/tests/TrustTests/TestRunners/AppDelegate.h new file mode 100644 index 00000000..715422f7 --- /dev/null +++ b/tests/TrustTests/TestRunners/AppDelegate.h @@ -0,0 +1,15 @@ +// +// AppDelegate.h +// TrustTestsRunner +// +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/tests/TrustTests/TestRunners/AppDelegate.m b/tests/TrustTests/TestRunners/AppDelegate.m new file mode 100644 index 00000000..12cc4dbf --- /dev/null +++ b/tests/TrustTests/TestRunners/AppDelegate.m @@ -0,0 +1,49 @@ +// +// AppDelegate.m +// TrustTestsRunner +// +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + +@end diff --git a/tests/TrustTests/TestRunners/Assets.xcassets/AppIcon.appiconset/Contents.json b/tests/TrustTests/TestRunners/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d8db8d65 --- /dev/null +++ b/tests/TrustTests/TestRunners/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/tests/TrustTests/TestRunners/Assets.xcassets/Contents.json b/tests/TrustTests/TestRunners/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/tests/TrustTests/TestRunners/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/KeychainEntitledTestApp_ios/Base.lproj/LaunchScreen.storyboard b/tests/TrustTests/TestRunners/Base.lproj/LaunchScreen.storyboard similarity index 73% rename from KeychainEntitledTestApp_ios/Base.lproj/LaunchScreen.storyboard rename to tests/TrustTests/TestRunners/Base.lproj/LaunchScreen.storyboard index fdf3f97d..bfa36129 100644 --- a/KeychainEntitledTestApp_ios/Base.lproj/LaunchScreen.storyboard +++ b/tests/TrustTests/TestRunners/Base.lproj/LaunchScreen.storyboard @@ -1,7 +1,8 @@ - + - + + @@ -9,14 +10,11 @@ - - - - + diff --git a/KeychainEntitledTestApp_ios/Base.lproj/Main.storyboard b/tests/TrustTests/TestRunners/Base.lproj/Main.storyboard similarity index 69% rename from KeychainEntitledTestApp_ios/Base.lproj/Main.storyboard rename to tests/TrustTests/TestRunners/Base.lproj/Main.storyboard index 4529698c..942f0bc4 100644 --- a/KeychainEntitledTestApp_ios/Base.lproj/Main.storyboard +++ b/tests/TrustTests/TestRunners/Base.lproj/Main.storyboard @@ -1,7 +1,8 @@ - - + + - + + @@ -9,14 +10,11 @@ - - - - + diff --git a/tests/TrustTests/TestRunners/Info.plist b/tests/TrustTests/TestRunners/Info.plist new file mode 100644 index 00000000..16be3b68 --- /dev/null +++ b/tests/TrustTests/TestRunners/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/tests/TrustTests/TestRunners/Main.storyboard b/tests/TrustTests/TestRunners/Main.storyboard new file mode 100644 index 00000000..f9a048ed --- /dev/null +++ b/tests/TrustTests/TestRunners/Main.storyboard @@ -0,0 +1,7 @@ + + + + + + + diff --git a/tests/TrustTests/TestRunners/ViewController.h b/tests/TrustTests/TestRunners/ViewController.h new file mode 100644 index 00000000..18c4de7d --- /dev/null +++ b/tests/TrustTests/TestRunners/ViewController.h @@ -0,0 +1,13 @@ +// +// ViewController.h +// TrustTestsRunner +// +// + +#import + +@interface ViewController : UIViewController + + +@end + diff --git a/tests/TrustTests/TestRunners/ViewController.m b/tests/TrustTests/TestRunners/ViewController.m new file mode 100644 index 00000000..e7f19a54 --- /dev/null +++ b/tests/TrustTests/TestRunners/ViewController.m @@ -0,0 +1,21 @@ +// +// ViewController.m +// TrustTestsRunner +// +// + +#import "ViewController.h" + +@interface ViewController () + +@end + +@implementation ViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view, typically from a nib. +} + + +@end diff --git a/tests/TrustTests/TestRunners/appmain.m b/tests/TrustTests/TestRunners/appmain.m new file mode 100644 index 00000000..588212ff --- /dev/null +++ b/tests/TrustTests/TestRunners/appmain.m @@ -0,0 +1,14 @@ +// +// main.m +// TrustTestsRunner_ios +// +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/tests/TrustTests/TestRunners/main.m b/tests/TrustTests/TestRunners/main.m new file mode 100644 index 00000000..c34bf518 --- /dev/null +++ b/tests/TrustTests/TestRunners/main.m @@ -0,0 +1,219 @@ +// +// TrustTests +// +// Stolen from Mark Pauley / CDEntitledTestRunner who stole it from Drew Terry / MobileContainerManager +// Copyright 2016-2018 Apple. All rights reserved. +// + +#import +#import +#import + +@interface TestRunner : NSObject { + NSBundle *_bundle; + XCTestSuite *_testSuite; +} + +- (instancetype)initWithBundlePath:(NSString *)path andTestNames:(NSArray *)names; +- (NSUInteger)runUnitTestSuite; +- (void)testLogWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2); +- (void)testLogWithFormat:(NSString *)format arguments:(va_list)arguments NS_FORMAT_FUNCTION(1,0); +@end + +@implementation TestRunner +- (instancetype)initWithBundlePath:(NSString *)path andTestNames:(NSArray *)names +{ + self = [super init]; + if (self) { + NSError *error = nil; + + _bundle = [NSBundle bundleWithPath:path]; + if (!_bundle) { + [self testLogWithFormat:@"No bundle at location %@ (%s)\n", path, strerror(errno)]; + return nil; + } + if (![_bundle loadAndReturnError:&error]) { + [self testLogWithFormat:@"Test Bundle at %@ didn't load: %@\n", path, error]; + return nil; + } + + if(names) { + XCTestSuite* testSuite = [[XCTestSuite alloc] initWithName:[[path lastPathComponent] stringByDeletingPathExtension]]; + XCTestSuite* loadedSuite = [XCTestSuite testSuiteForBundlePath:path]; + // Filter out only the tests that were named. + [loadedSuite.tests enumerateObjectsUsingBlock:^(__kindof XCTest * _Nonnull test, NSUInteger __unused idx, BOOL * __unused _Nonnull stop) { + [self testLogWithFormat:@"Checking test %@\n", test.name]; + if([names containsObject:test.name]) { + [testSuite addTest:test]; + } + }]; + _testSuite = testSuite; + } + else { + _testSuite = [XCTestSuite testSuiteForBundlePath:path]; + } + } + return self; +} + +- (NSUInteger)runUnitTestSuite +{ + [[XCTestObservationCenter sharedTestObservationCenter] addTestObserver:self]; + + [_testSuite runTest]; + + XCTestRun *testRun = [_testSuite testRun]; + + return testRun.totalFailureCount; +} + +- (NSFileHandle *)logFileHandle +{ + return [NSFileHandle fileHandleWithStandardOutput]; +} + +- (void)testLogWithFormat:(NSString *)format, ... +{ + va_list ap; + va_start(ap, format); + [self testLogWithFormat:format arguments:ap]; + va_end(ap); +} + +- (void)testLogWithFormat:(NSString *)format arguments:(va_list)arguments +{ + NSString *message = [[NSString alloc] initWithFormat:format arguments:arguments]; + [self.logFileHandle writeData:[message dataUsingEncoding:NSUTF8StringEncoding]]; +} + +- (NSDateFormatter *)dateFormatter +{ + static NSDateFormatter *dateFormatter; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + dateFormatter = [NSDateFormatter new]; + dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; + }); + return dateFormatter; +} + +/* -testBundleWillStart: // exactly once per test bundle + * -testSuiteWillStart: // exactly once per test suite + * -testCaseWillStart: // exactly once per test case + * -testCase:didFailWithDescription:... // zero or more times per test case, any time between test case start and finish + * -testCaseDidFinish: // exactly once per test case + * -testSuite:didFailWithDescription:... // zero or more times per test suite, any time between test suite start and finish + * -testSuiteDidFinish: // exactly once per test suite + * -testBundleDidFinish: // exactly once per test bundle + */ + +- (void)testSuiteWillStart:(XCTestSuite *)testSuite +{ + [self testLogWithFormat:@"Test Suite '%@' started at %@\n", testSuite.name, [self.dateFormatter stringFromDate:testSuite.testRun.startDate]]; +} + +- (void)testSuite:(XCTestSuite *)testSuite didFailWithDescription:(NSString *)description inFile:(nullable NSString *)filePath atLine:(NSUInteger)lineNumber +{ + [self testLogWithFormat:@"%@:%lu: error: %@ : %@\n", ((nil != filePath) ? filePath : @""), ((unsigned long)((nil != filePath) ? lineNumber : 0)), testSuite.name, description]; +} + +- (void)testSuiteDidFinish:(XCTestSuite *)testSuite +{ + XCTestRun *testRun = testSuite.testRun; + [self testLogWithFormat:@"Test Suite '%@' %s at %@.\n\t Executed %lu test%s, with %lu failure%s (%lu unexpected) in %.3f (%.3f) seconds\n", + testSuite.name, + (testRun.hasSucceeded ? "passed" : "failed"), + [self.dateFormatter stringFromDate:testRun.stopDate], + ((unsigned long)testRun.executionCount), (testRun.executionCount != 1 ? "s" : ""), + ((unsigned long)testRun.totalFailureCount), (testRun.totalFailureCount != 1 ? "s" : ""), + ((unsigned long)testRun.unexpectedExceptionCount), + testRun.testDuration, + testRun.totalDuration]; +} + +- (void)testCaseWillStart:(XCTestCase *)testCase +{ + [self testLogWithFormat:@"Test Case '%@' started.\n", testCase.name]; +} + +- (void)testCase:(XCTestCase *)testCase didFailWithDescription:(NSString *)description inFile:(nullable NSString *)filePath atLine:(NSUInteger)lineNumber +{ + [self testLogWithFormat:@"%@:%lu: error: %@ : %@\n", ((nil != filePath) ? filePath : @""), ((unsigned long)((nil != filePath) ? lineNumber : 0)), testCase.name, description]; +} + +- (void)testCaseDidFinish:(XCTestCase *)testCase +{ + [self testLogWithFormat:@"Test Case '%@' %s (%.3f seconds).\n", testCase.name, (testCase.testRun.hasSucceeded ? "passed" : "failed"), testCase.testRun.totalDuration]; + +} +@end + + + + +static char* gTestBundleDir = "/AppleInternal/XCTests/com.apple.security/"; +static char* gTestBundleName = "TrustTests"; + +static NSMutableArray* gTestCaseNames = nil; + +static const char* opt_str = "d:t:c:h"; + +static void usage(char*const binName, bool longUsage) { + fprintf(stderr, "Usage: %s [-d ] -t test_bundle_name [(-c test_case_name)*]\n", binName); + if (longUsage) { + fprintf(stderr, "-d: argument = path to directory where test bundles live\n"); + fprintf(stderr, "-t: argument = name of test bundle to be run (without extension)\n"); + fprintf(stderr, "-c: argument = name of test case to be run (multiple)\n"); + } +} + +static void getOptions(int argc, char *const *argv) { + int ch; + while ( (ch = getopt(argc, argv, opt_str)) != -1 ) { + switch(ch) + { + case 'd': + gTestBundleDir = optarg; + break; + case 't': + gTestBundleName = optarg; + break; + case 'c': + if(!gTestCaseNames) { + gTestCaseNames = [NSMutableArray new]; + } + [gTestCaseNames addObject:@(optarg)]; + break; + case 'h': + case '?': + default: + usage(argv[0], true); + exit(0); + break; + } + } +} + +int main (int argc, const char * argv[]) +{ + @autoreleasepool { + getOptions(argc, (char*const*)argv); + NSString *testBundleDir = [NSString stringWithCString:gTestBundleDir encoding:NSUTF8StringEncoding]; + NSString *testBundleName = [NSString stringWithCString:gTestBundleName encoding:NSUTF8StringEncoding]; + NSString *testBundlePath = [[testBundleDir stringByAppendingPathComponent:testBundleName] stringByAppendingPathExtension:@"xctest"]; + + printf("Running unit tests %s at: %s\n", gTestCaseNames?gTestCaseNames.description.UTF8String:"[All]", testBundlePath.UTF8String); + + TestRunner *unitTest = [[TestRunner alloc] initWithBundlePath:testBundlePath andTestNames:gTestCaseNames]; + if (!unitTest) { + fprintf(stderr, "Failed to load unit test runner at: %s\n", testBundlePath.UTF8String); + return 1; + } + + //runUnitTestSuite returns the number of failures. 0 = success, non-zero means failure. This complies with BATS testing standards. + return (int)[unitTest runUnitTestSuite]; + + return 0; + } +} + diff --git a/tests/TrustTests/TestRunners/trusttests_entitlements.plist b/tests/TrustTests/TestRunners/trusttests_entitlements.plist new file mode 100644 index 00000000..8df24b43 --- /dev/null +++ b/tests/TrustTests/TestRunners/trusttests_entitlements.plist @@ -0,0 +1,18 @@ + + + + + application-identifier + com.apple.trusttests + com.apple.application-identifier + com.apple.trusttests + com.apple.private.keychain.certificates + + modify-anchor-certificates + + com.apple.private.assets.accessible-asset-types + + com.apple.MobileAsset.PKITrustSupplementals + + + diff --git a/tests/TrustTests/TrustEvaluationTestHelpers.h b/tests/TrustTests/TrustEvaluationTestHelpers.h new file mode 100644 index 00000000..7eabecd0 --- /dev/null +++ b/tests/TrustTests/TrustEvaluationTestHelpers.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019 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 _TRUSTTEST_TRUST_HELPERS_H_ +#define _TRUSTTEST_TRUST_HELPERS_H_ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TestTrustEvaluation : NSObject +@property (assign, nonnull) SecTrustRef trust; +@property NSString *fullTestName; +@property BOOL bridgeOSDisabled; + +// Outputs +@property (assign) SecTrustResultType trustResult; +@property (nullable) NSDictionary *resultDictionary; + +// Expected results +@property NSNumber *expectedResult; +@property NSNumber *expectedChainLength; + +// These properties have the side effect of modifying the SecTrustRef +@property (nullable,assign,nonatomic) NSArray *anchors; +@property (nullable,assign,nonatomic) NSArray *ocspResponses; +@property (nullable,nonatomic) NSArray *presentedSCTs; +@property (nullable,nonatomic) NSArray *trustedCTLogs; +@property (nullable,nonatomic) NSDate *verifyDate; + +- (instancetype _Nullable )initWithCertificates:(NSArray * _Nonnull)certs policies:(NSArray * _Nullable)policies; +- (instancetype _Nullable) initWithTrustDictionary:(NSDictionary *)testDict; + +- (void)addAnchor:(SecCertificateRef)certificate; + +- (bool)evaluate:(out NSError * _Nullable __autoreleasing * _Nullable)outError; +- (bool)evaluateForExpectedResults:(out NSError * _Nullable __autoreleasing *)outError; +@end + +NS_ASSUME_NONNULL_END + +#endif /*_TRUSTTEST_TRUST_HELPERS_H_ */ diff --git a/tests/TrustTests/TrustEvaluationTestHelpers.m b/tests/TrustTests/TrustEvaluationTestHelpers.m new file mode 100644 index 00000000..9bf277a0 --- /dev/null +++ b/tests/TrustTests/TrustEvaluationTestHelpers.m @@ -0,0 +1,504 @@ +// +// TrustEvaluationTestHelpers.m +// Security +// +// + +#include +#import +#import + +#include +#include +#include +#include +#include +#include +#include + +#include "TrustEvaluationTestHelpers.h" + +// Want a class for running trust evaluations +// Want a dictionary-driven test with callback + +@interface TestTrustEvaluation () +@property NSString *directory; +@property NSMutableArray *certificates; +@property NSMutableArray *policies; +@property BOOL enableTestCertificates; +@end + +@implementation TestTrustEvaluation +@synthesize ocspResponses = _ocspResponses; +@synthesize presentedSCTs = _presentedSCTs; +@synthesize trustedCTLogs = _trustedCTLogs; + + +- (instancetype)initWithCertificates:(NSArray *)certs policies:(NSArray *)policies { + if (self = [super init]) { + if (errSecSuccess != SecTrustCreateWithCertificates((__bridge CFArrayRef)certs, (__bridge CFArrayRef)policies, &_trust)) { + return NULL; + } + } + return self; +} + +- (void)addAnchor:(SecCertificateRef)certificate +{ + CFArrayRef anchors = NULL; + SecTrustCopyCustomAnchorCertificates(_trust, &anchors); + + NSMutableArray *newAnchors = [NSMutableArray array]; + if (anchors) { + [newAnchors addObjectsFromArray:CFBridgingRelease(anchors)]; + } + [newAnchors addObject:(__bridge id)certificate]; + (void)SecTrustSetAnchorCertificates(_trust, (__bridge CFArrayRef)newAnchors); +} + +- (void)setAnchors:(NSArray *)anchorArray { + (void)SecTrustSetAnchorCertificates(_trust, (__bridge CFArrayRef)anchorArray); +} + +- (NSArray *)anchors { + CFArrayRef anchors = NULL; + SecTrustCopyCustomAnchorCertificates(_trust, &anchors); + return CFBridgingRelease(anchors); +} + +- (void)setOcspResponses:(NSArray *)ocspResponsesArray { + if (ocspResponsesArray != _ocspResponses) { + _ocspResponses = nil; + _ocspResponses = ocspResponsesArray; + (void)SecTrustSetOCSPResponse(_trust, (__bridge CFArrayRef)ocspResponsesArray); + } +} + +- (void)setPresentedSCTs:(NSArray *)presentedSCTsArray { + if (presentedSCTsArray != _presentedSCTs) { + _presentedSCTs = nil; + _presentedSCTs = presentedSCTsArray; + (void)SecTrustSetSignedCertificateTimestamps(_trust, (__bridge CFArrayRef)presentedSCTsArray); + } +} + +- (void)setTrustedCTLogs:(NSArray *)trustedCTLogsArray { + if (trustedCTLogsArray != _trustedCTLogs) { + _trustedCTLogs = nil; + _trustedCTLogs = trustedCTLogsArray; + (void)SecTrustSetTrustedLogs(_trust, (__bridge CFArrayRef)trustedCTLogsArray); + } +} + +- (void)setVerifyDate:(NSDate *)aVerifyDate { + if (aVerifyDate != _verifyDate) { + _verifyDate = nil; + _verifyDate = aVerifyDate; + (void)SecTrustSetVerifyDate(_trust, (__bridge CFDateRef)aVerifyDate); + } +} + +- (bool)evaluate:(out NSError * _Nullable __autoreleasing *)outError { + CFErrorRef localError = nil; + _trustResult = kSecTrustResultInvalid; + _resultDictionary = nil; + bool result = SecTrustEvaluateWithError(_trust, &localError); + if (outError && localError) { + *outError = CFBridgingRelease(localError); + } + (void)SecTrustGetTrustResult(_trust, &_trustResult); + _resultDictionary = CFBridgingRelease(SecTrustCopyResult(_trust)); + return result; +} + +- (void) dealloc { + CFReleaseNull(_trust); +} + +/* MARK: - + * MARK: Dictionary-driven trust objects + */ + +/* INSTRUCTIONS FOR ADDING NEW DICTIONARY-DRIVEN TRUSTS: + * 1. Add the certificates, as DER-encoded files with the 'cer' extension to a directory included in the test Resources + * (e.g. OSX/shared_regressions/si-20-sectrust-policies-data/) + * NOTE: If your cert needs to be named with "(i[Pp]hone|i[Pp]ad|i[Pp]od)", you need to make two copies -- one named properly + * and another named such that it doesn't match that regex. Use the regex trick below for TARGET_OS_TV to make sure your test + * works. + * 2. The input dictionary must include: (see constants below) + * MajorTestName + * MinorTestName + * Policies + * Leaf + * ExpectedResult + * CertDirectory + * It is strongly recommended that all test dictionaries include the Anchors and VerifyDate keys. + * Addtional optional keys are defined below. + */ + +/* Key Constants for Test Dictionaries */ +const NSString *kSecTrustTestMajorTestName = @"MajorTestName"; /* Required; value: string */ +const NSString *kSecTrustTestMinorTestName = @"MinorTestName"; /* Required; value: string */ +const NSString *kSecTrustTestPolicies = @"Policies"; /* Required; value: dictionary or array of dictionaries */ +const NSString *kSecTrustTestLeaf = @"Leaf"; /* Required; value: string */ +const NSString *kSecTrustTestIntermediates = @"Intermediates"; /* Optional; value: string or array of strings */ +const NSString *kSecTrustTestAnchors = @"Anchors"; /* Recommended; value: string or array of strings */ +const NSString *kSecTrustTestVerifyDate = @"VerifyDate"; /* Recommended; value: date */ +const NSString *kSecTrustTestExpectedResult = @"ExpectedResult"; /* Required; value: number */ +const NSString *kSecTrustTestChainLength = @"ChainLength"; /* Optional; value: number */ +const NSString *kSecTrustTestEnableTestCerts= @"EnableTestCertificates"; /* Optional; value: string */ +const NSString *kSecTrustTestDisableBridgeOS= @"BridgeOSDisable"; /* Optional; value: boolean */ +const NSString *kSecTrustTestDirectory = @"CertDirectory"; /* Required; value: string */ + +/* Key Constants for Policies Dictionaries */ +const NSString *kSecTrustTestPolicyOID = @"PolicyIdentifier"; /* Required; value: string */ +const NSString *kSecTrustTestPolicyProperties = @"Properties"; /* Optional; value: dictionary, see Policy Value Constants, SecPolicy.h */ + +- (void)setMajorTestName:(NSString *)majorTestName minorTestName:(NSString *)minorTestName { + self.fullTestName = [[majorTestName stringByAppendingString:@"-"] stringByAppendingString:minorTestName]; +} + +#if TARGET_OS_TV +/* Mastering removes all files named i[Pp]hone, so dynamically replace any i[Pp]hone's with + * iPh0ne. We have two copies in the resources directory. */ +- (NSString *)replaceiPhoneNamedFiles:(NSString *)filename { + NSRegularExpression *regularExpression = [NSRegularExpression regularExpressionWithPattern:@"iphone" + options:NSRegularExpressionCaseInsensitive + error:nil]; + NSString *newfilename = [regularExpression stringByReplacingMatchesInString:filename + options:0 + range:NSMakeRange(0, [filename length]) + withTemplate:@"iPh0ne"]; + return newfilename; +} +#endif + +- (bool)addLeafToCertificates:(NSString *)leafName { + SecCertificateRef cert; + NSString *path = nil, *filename = nil; + require_string(leafName, errOut, "%@: failed to get leaf for test"); +#if TARGET_OS_TV + filename = [self replaceiPhoneNamedFiles:leafName]; +#else + filename = leafName; +#endif + + path = [[NSBundle bundleForClass:[self class]] + pathForResource:filename + ofType:@"cer" + inDirectory:self.directory]; + require_string(path, errOut, "failed to get path for leaf"); + cert = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); + require_string(cert, errOut, "failed to create leaf certificate from path"); + self.certificates = [[NSMutableArray alloc] initWithObjects:(__bridge id)cert, nil]; + CFReleaseNull(cert); + require_string(self.certificates, errOut, "failed to initialize certificates array"); + return true; + +errOut: + return false; +} + +- (bool)addCertsToArray:(id)pathsObj outputArray:(NSMutableArray *)outArray { + __block SecCertificateRef cert = NULL; + __block NSString* path = nil, *filename = nil; + require_string(pathsObj, errOut, + "failed to get certificate paths for test"); + + if ([pathsObj isKindOfClass:[NSString class]]) { + /* Only one cert path */ +#if TARGET_OS_TV + filename = [self replaceiPhoneNamedFiles:pathsObj]; +#else + filename = pathsObj; +#endif + path = [[NSBundle bundleForClass:[self class]] + pathForResource:filename + ofType:@"cer" + inDirectory:self.directory]; + require_string(path, errOut, "failed to get path for cert"); + cert = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); + require_string(cert, errOut, "failed to create certificate from path"); + [outArray addObject:(__bridge id)cert]; + CFReleaseNull(cert); + } else if ([pathsObj isKindOfClass:[NSArray class]]) { + /* Test has more than one intermediate */ + [(NSArray *)pathsObj enumerateObjectsUsingBlock:^(NSString *resource, NSUInteger idx, BOOL *stop) { +#if TARGET_OS_TV + filename = [self replaceiPhoneNamedFiles:resource]; +#else + filename = resource; +#endif + path = [[NSBundle bundleForClass:[self class]] + pathForResource:filename + ofType:@"cer" + inDirectory:self.directory]; + require_string(path, blockOut, "failed to get path for cert"); + cert = SecCertificateCreateWithData(NULL, (CFDataRef)[NSData dataWithContentsOfFile:path]); + require_string(cert, blockOut, "failed to create certificate %ld from path %@"); + [outArray addObject:(__bridge id)cert]; + + CFReleaseNull(cert); + return; + + blockOut: + CFReleaseNull(cert); + *stop = YES; + }]; + } else { + require_string(false, errOut, "unexpected type for intermediates or anchors value"); + } + + return true; + +errOut: + CFReleaseNull(cert); + return false; +} + +- (bool)addIntermediatesToCertificates:(id)intermediatesObj { + require_string(intermediatesObj, errOut, "failed to get intermediates for test"); + + require_string([self addCertsToArray:intermediatesObj outputArray:self.certificates], errOut, + "failed to add intermediates to certificates array"); + + if ([intermediatesObj isKindOfClass:[NSString class]]) { + require_string([self.certificates count] == 2, errOut, + "failed to add all intermediates"); + } else if ([intermediatesObj isKindOfClass:[NSArray class]]) { + require_string([self.certificates count] == [(NSArray *)intermediatesObj count] + 1, errOut, + "failed to add all intermediates"); + } + + return true; + +errOut: + return false; +} + +- (bool)addPolicy:(NSDictionary *)policyDict +{ + SecPolicyRef policy = NULL; + NSString *policyIdentifier = [(NSDictionary *)policyDict objectForKey:kSecTrustTestPolicyOID]; + NSDictionary *policyProperties = [(NSDictionary *)policyDict objectForKey:kSecTrustTestPolicyProperties]; + require_string(policyIdentifier, errOut, "failed to get policy OID"); + + policy = SecPolicyCreateWithProperties((__bridge CFStringRef)policyIdentifier, + (__bridge CFDictionaryRef)policyProperties); + require_string(policy, errOut, "failed to create properties for policy OID"); + [self.policies addObject:(__bridge id)policy]; + CFReleaseNull(policy); + + return true; +errOut: + return false; +} + +- (bool)addPolicies:(id)policiesObj { + require_string(policiesObj, errOut, + "failed to get policies for test"); + + self.policies = [[NSMutableArray alloc] init]; + require_string(self.policies, errOut, + "failed to initialize policies array"); + if ([policiesObj isKindOfClass:[NSDictionary class]]) { + /* Test has only one policy */ + require_string([self addPolicy:policiesObj], errOut, "failed to add policy"); + } else if ([policiesObj isKindOfClass:[NSArray class]]) { + /* Test more than one policy */ + [(NSArray *)policiesObj enumerateObjectsUsingBlock:^(NSDictionary *policyDict, NSUInteger idx, BOOL *stop) { + if (![self addPolicy:policyDict]) { + *stop = YES; + } + }]; + + require_string([(NSArray *)policiesObj count] == [self.policies count], errOut, "failed to add all policies"); + } else { + require_string(false, errOut, "unexpected type for Policies value"); + } + + return true; + +errOut: + return false; +} + +- (bool)setAnchorsFromPlist:(id)anchorsObj { + NSMutableArray *anchors = [NSMutableArray array]; + require_string(anchorsObj, errOut, "failed to get anchors for test"); + require_string([self addCertsToArray:anchorsObj outputArray:anchors], errOut, "failed to add anchors to anchors array"); + + if ([anchorsObj isKindOfClass:[NSString class]]) { + require_string([anchors count] == 1, errOut, "failed to add all anchors"); + } else if ([anchorsObj isKindOfClass:[NSArray class]]) { + require_string([anchors count] == [(NSArray *)anchorsObj count], errOut, "failed to add all anchors"); + } + + // set the anchors in the SecTrustRef + self.anchors = anchors; + return true; + +errOut: + return false; +} + +- (instancetype _Nullable) initWithTrustDictionary:(NSDictionary *)testDict +{ + if (!(self = [super init])) { + return self; + } + + NSString *majorTestName = nil, *minorTestName = nil; + SecTrustRef trust = NULL; + +#if TARGET_OS_BRIDGE + /* Some of the tests don't work on bridgeOS because there is no Certificates bundle. Skip them. */ + if([testDict[kSecTrustTestDisableBridgeOS] boolValue]) { + self.bridgeOSDisabled = YES; + } +#endif + + /* Test certificates work by default on internal builds. We still need this to + * determine whether to expect failure for production devices. */ + self.enableTestCertificates = [testDict[kSecTrustTestEnableTestCerts] boolValue]; + + /* Test name, for documentation purposes */ + majorTestName = testDict[kSecTrustTestMajorTestName]; + minorTestName = testDict[kSecTrustTestMinorTestName]; + require_string(majorTestName && minorTestName, errOut, "Failed to create test names for test"); + [self setMajorTestName:majorTestName minorTestName:minorTestName]; + +#if DEBUG + fprintf(stderr, "BEGIN trust creation for %s", [self.fullTestName cStringUsingEncoding:NSUTF8StringEncoding]); +#endif + + /* Cert directory */ + self.directory = testDict[kSecTrustTestDirectory]; + require_string(self.directory, errOut, "No directory for test!"); + + /* Populate the certificates array */ + require_quiet([self addLeafToCertificates:testDict[kSecTrustTestLeaf]], errOut); + + /* Add optional intermediates to certificates array */ + if (testDict[kSecTrustTestIntermediates]) { + require_quiet([self addIntermediatesToCertificates:testDict[kSecTrustTestIntermediates]], errOut); + } + + /* Create the policies */ +#if !TARGET_OS_BRIDGE + require_quiet([self addPolicies:testDict[kSecTrustTestPolicies]], errOut); +#else // TARGET_OS_BRIDGE + if (![self addPolicies:testDict[kSecTrustTestPolicies]]) { + /* Some policies aren't available on bridgeOS (because there is no Certificates bundle on bridgeOS). + * If we fail to add the policies for a disabled test, let SecTrustCreate fall back to the Basic policy. + * We'll skip the evaluation and other tests by honoring bridgeOSDisabled, but we need to return a + * TestTrustEvaluation object so that the test continues. */ + if (self.bridgeOSDisabled) { + self.policies = nil; + } else { + goto errOut; + } + } +#endif // TARGET_OS_BRIDGE + + + /* Create the trust object */ + require_noerr_string(SecTrustCreateWithCertificates((__bridge CFArrayRef)self.certificates, + (__bridge CFArrayRef)self.policies, + &trust), + errOut, + "failed to create trust ref"); + self.trust = trust; + + /* Optionally set anchors in trust object */ + if (testDict[kSecTrustTestAnchors]) { + require_quiet([self setAnchorsFromPlist:testDict[kSecTrustTestAnchors]], errOut); + } + + /* Set optional date in trust object */ + if (testDict[kSecTrustTestVerifyDate]) { + self.verifyDate = testDict[kSecTrustTestVerifyDate]; + } + + /* Set expected results */ + self.expectedResult = testDict[kSecTrustTestExpectedResult]; + self.expectedChainLength = testDict[kSecTrustTestChainLength]; + +#if DEBUG + fprintf(stderr, "END trust creation for %s", [self.fullTestName cStringUsingEncoding:NSUTF8StringEncoding]); +#endif + + return self; + +errOut: + return nil; +} + +- (bool)evaluateForExpectedResults:(out NSError * _Nullable __autoreleasing *)outError +{ +#if TARGET_OS_BRIDGE + // Artificially skip tests for bridgeOS. To prevent test errors these need to be reported as a pass. + if (self.bridgeOSDisabled) { + return true; + } +#endif + + if (!self.expectedResult) { + if (outError) { + NSString *errorDescription = [NSString stringWithFormat:@"Test %@: no expected results set", + self.fullTestName]; + *outError = [NSError errorWithDomain:@"TrustTestsError" code:(-1) + userInfo:@{ NSLocalizedFailureReasonErrorKey : errorDescription}]; + } + return false; + } + + SecTrustResultType trustResult = kSecTrustResultInvalid; + if (errSecSuccess != SecTrustGetTrustResult(self.trust, &trustResult)) { + if (outError) { + NSString *errorDescription = [NSString stringWithFormat:@"Test %@: Failed to get trust result", + self.fullTestName]; + *outError = [NSError errorWithDomain:@"TrustTestsError" code:(-2) + userInfo:@{ NSLocalizedFailureReasonErrorKey : errorDescription}]; + } + return false; + } + + bool result = false; + + /* If we enabled test certificates on a non-internal device, expect a failure instead of success. */ + if (self.enableTestCertificates && !SecIsInternalRelease() && ([self.expectedResult unsignedIntValue] == 4)) { + if (trustResult == kSecTrustResultRecoverableTrustFailure) { + result = true; + } + } else if (trustResult == [self.expectedResult unsignedIntValue]) { + result = true; + } + + if (!result) { + if (outError) { + NSString *errorDescription = [NSString stringWithFormat:@"Test %@: Expected result %@ %s does not match actual result %u %s", + self.fullTestName, self.expectedResult, + (self.enableTestCertificates ? "for test cert" : ""), + trustResult, + SecIsInternalRelease() ? "" : "on prod device"]; + *outError = [NSError errorWithDomain:@"TrustTestsError" code:(-3) + userInfo:@{ NSLocalizedFailureReasonErrorKey : errorDescription}]; + } + return result; + } + + /* expected chain length is optional, but if we have it, verify */ + if (self.expectedChainLength && (SecTrustGetCertificateCount(self.trust) != [self.expectedChainLength longValue])) { + if (outError) { + NSString *errorDescription = [NSString stringWithFormat:@"Test %@: Expected chain length %@ does not match actual chain length %ld", + self.fullTestName, self.expectedChainLength, SecTrustGetCertificateCount(self.trust)]; + *outError = [NSError errorWithDomain:@"TrustTestsError" code:(-4) + userInfo:@{ NSLocalizedFailureReasonErrorKey : errorDescription}]; + } + return false; + } + return true; +} + +@end diff --git a/tests/TrustTests/gen_test_plist.py b/tests/TrustTests/gen_test_plist.py new file mode 100644 index 00000000..ee7c7307 --- /dev/null +++ b/tests/TrustTests/gen_test_plist.py @@ -0,0 +1,51 @@ +#!/usr/bin/python +import sys +import Foundation +from glob import glob +import re +import os + +test_dir = sys.argv[1] +outfile = sys.argv[2] + +test_plist = Foundation.NSMutableDictionary.dictionary() +test_plist['Project'] = 'Security' +test_list = Foundation.NSMutableArray.array() + +test_files = glob(test_dir + '/*/*.m') + +for filename in test_files: + f = open(filename, 'r') + for line in f: + match = re.search('@interface ([a-zA-Z0-9_]+) ?: ?Trust[a-zA-Z0-9_]+TestCase', line) + if match: + regex_string = test_dir + '/([a-zA-Z0-9_]+/)' + test_dir_match = re.search(regex_string, filename) + if not test_dir_match: + print 'failed to find test dir name for ' + filename + " with regex " + regex_string + sys.exit(1) + test_dictionary = Foundation.NSMutableDictionary.dictionary() + test_dictionary['TestName'] = test_dir_match.group(1) + match.group(1) + test_dictionary['ShowSubtestResults']= True + test_dictionary['WorkingDirectory'] = '/AppleInternal/XCTests/com.apple.security/' + test_dictionary['AsRoot'] = True + + test_command = Foundation.NSMutableArray.array() + test_command.append('/AppleInternal/CoreOS/tests/Security/TrustTests') + test_command.append('-c ' + match.group(1)) + test_command.append('-t TrustTests') + + test_dictionary['Command'] = test_command + + test_list.append(test_dictionary) + f.close() + +test_plist['Tests'] = test_list + +out_dir = os.path.dirname(outfile) +if not os.path.exists(out_dir): + os.makedirs(out_dir) +success = test_plist.writeToFile_atomically_(outfile, 1) +if not success: + print "test plist failed to write, error!" + sys.exit(1) diff --git a/tests/secdmockaks/aks_real_witness.c b/tests/secdmockaks/aks_real_witness.c new file mode 100644 index 00000000..cebbcf85 --- /dev/null +++ b/tests/secdmockaks/aks_real_witness.c @@ -0,0 +1,36 @@ + +#include "aks_real_witness.h" +#include + +#if !TARGET_OS_SIMULATOR + +#include +#include + +#include + +bool hwaes_key_available(void) +{ + keybag_handle_t handle = bad_keybag_handle; + keybag_handle_t special_handle = bad_keybag_handle; +#if TARGET_OS_OSX + special_handle = session_keybag_handle; +#elif TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR + special_handle = device_keybag_handle; +#else +#error "supported keybag target" +#endif + + kern_return_t kr = aks_get_system(special_handle, &handle); + if (kr != kAKSReturnSuccess) { +#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR + /* TODO: Remove this once the kext runs the daemon on demand if + there is no system keybag. */ + int kb_state = MKBGetDeviceLockState(NULL); + secinfo("aks", "AppleKeyStore lock state: %d", kb_state); +#endif + } + return true; +} + +#endif diff --git a/tests/secdmockaks/aks_real_witness.h b/tests/secdmockaks/aks_real_witness.h new file mode 100644 index 00000000..e2a06b61 --- /dev/null +++ b/tests/secdmockaks/aks_real_witness.h @@ -0,0 +1,9 @@ + +#ifndef aks_real_witness_h +#define aks_real_witness_h + +#include "OSX/utilities/SecAKSWrappers.h" + +bool hwaes_key_available(void); + +#endif /* aks_real_witness_h */ diff --git a/tests/secdmockaks/mockaks.h b/tests/secdmockaks/mockaks.h index 92b6a65b..d4d0ee8f 100644 --- a/tests/secdmockaks/mockaks.h +++ b/tests/secdmockaks/mockaks.h @@ -24,17 +24,51 @@ #ifndef mockaks_h #define mockaks_h -#import "SecKeybagSupport.h" - -#if USE_KEYSTORE #import +#if __has_include() +#include +#else + +typedef struct __MKBKeyBagHandle* MKBKeyBagHandleRef; +int MKBKeyBagCreateWithData(CFDataRef keybagBlob, MKBKeyBagHandleRef* newHandle); + +#define kMobileKeyBagDeviceIsLocked 1 +#define kMobileKeyBagDeviceIsUnlocked 0 + +int MKBKeyBagUnlock(MKBKeyBagHandleRef keybag, CFDataRef passcode); +int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle); +int MKBGetDeviceLockState(CFDictionaryRef options); +CF_RETURNS_RETAINED CFDictionaryRef MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error); +int MKBForegroundUserSessionID( CFErrorRef * error); + +#define kMobileKeyBagSuccess (0) +#define kMobileKeyBagError (-1) +#define kMobileKeyBagDeviceLockedError (-2) +#define kMobileKeyBagInvalidSecretError (-3) +#define kMobileKeyBagExistsError (-4) +#define kMobileKeyBagNoMemoryError (-5) + +#endif // + + +#if __OBJC2__ + @interface SecMockAKS : NSObject +@property (class) keybag_state_t keybag_state; + + (bool)isLocked:(keyclass_t)key_class; + (bool)isSEPDown; + (bool)useGenerationCount; + ++ (void)lockClassA_C; ++ (void)lockClassA; + ++ (void)unlockAllClasses; + ++ (void)reset; @end -#endif /* USE_KEYSTORE */ +#endif // OBJC2 #endif /* mockaks_h */ diff --git a/tests/secdmockaks/mockaks.m b/tests/secdmockaks/mockaks.m index 25e5af1e..71ac9ce5 100644 --- a/tests/secdmockaks/mockaks.m +++ b/tests/secdmockaks/mockaks.m @@ -21,16 +21,26 @@ * @APPLE_LICENSE_HEADER_END@ */ +#import +#if !TARGET_OS_BRIDGE + #import "SecKeybagSupport.h" -#if USE_KEYSTORE +#if __has_include() #import +#endif + +#if __has_include() #import +#endif + +#if __has_include() #import #endif -#import -#import +#include + +#import #import #import #import @@ -39,13 +49,98 @@ #import #import "mockaks.h" -#if USE_KEYSTORE +bool hwaes_key_available(void) +{ + return false; +} + +#define SET_FLAG_ON(v, flag) v |= (flag) +#define SET_FLAG_OFF(v, flag) v &= ~(flag) + +@interface SecMockAKS () +@property (class, readonly) NSMutableDictionary* lockedStates; +@property (class, readonly) dispatch_queue_t mutabilityQueue; +@end @implementation SecMockAKS +static NSMutableDictionary* _lockedStates = nil; +static dispatch_queue_t _mutabilityQueue = nil; +static keybag_state_t _keybag_state = keybag_state_unlocked | keybag_state_been_unlocked; + +/* + * Method that limit where this rather in-secure version of AKS can run + */ + ++ (void)trapdoor { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ +#if DEBUG || TARGET_OS_SIMULATOR + return; +#else + const char *argv0 = getprogname(); + + if (strcmp(argv0, "securityd") == 0 || strcmp(argv0, "secd") == 0) { + abort(); + } + if (os_variant_has_internal_content("securityd")) { + return; + } +#if TARGET_OS_IPHONE /* all three platforms: ios, watch, tvos */ + if (os_variant_uses_ephemeral_storage("securityd")) { + return; + } + if (os_variant_allows_internal_security_policies("securityd")) { + return; + } + abort(); +#endif /* TARGET_OS_IPHONE */ +#endif /* !DEBUG || !TARGET_OS_SIMULATOR */ + }); +} + ++ (NSMutableDictionary*)lockedStates +{ + if(_lockedStates == nil) { + _lockedStates = [NSMutableDictionary dictionary]; + } + return _lockedStates; +} + ++ (dispatch_queue_t)mutabilityQueue +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _mutabilityQueue = dispatch_queue_create("SecMockAKS", DISPATCH_QUEUE_SERIAL); + }); + return _mutabilityQueue; +} + ++ (keybag_state_t)keybag_state +{ + return _keybag_state; +} + ++ (void)setKeybag_state:(keybag_state_t)keybag_state +{ + _keybag_state = keybag_state; +} + ++ (void)reset +{ + dispatch_sync(self.mutabilityQueue, ^{ + [self.lockedStates removeAllObjects]; + self.keybag_state = keybag_state_unlocked; + }); +} + (bool)isLocked:(keyclass_t)key_class { - return false; + __block bool isLocked = false; + dispatch_sync(self.mutabilityQueue, ^{ + NSNumber* key = [NSNumber numberWithInt:key_class]; + isLocked = [self.lockedStates[key] boolValue]; + }); + return isLocked; } + (bool)isSEPDown @@ -58,6 +153,49 @@ return false; } ++ (void)lockClassA +{ + dispatch_sync(self.mutabilityQueue, ^{ + self.lockedStates[[NSNumber numberWithInt:key_class_a]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_ak]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_aku]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_akpu]] = [NSNumber numberWithBool:YES]; + + SET_FLAG_ON(self.keybag_state, keybag_state_locked); + SET_FLAG_OFF(self.keybag_state, keybag_state_unlocked); + // don't touch keybag_state_been_unlocked; leave it as-is + }); +} + +// Simulate device being in "before first unlock" ++ (void)lockClassA_C +{ + dispatch_sync(self.mutabilityQueue, ^{ + self.lockedStates[[NSNumber numberWithInt:key_class_a]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_ak]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_aku]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_akpu]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_c]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_ck]] = [NSNumber numberWithBool:YES]; + self.lockedStates[[NSNumber numberWithInt:key_class_cku]] = [NSNumber numberWithBool:YES]; + + SET_FLAG_ON(self.keybag_state, keybag_state_locked); + SET_FLAG_OFF(self.keybag_state, keybag_state_unlocked); + SET_FLAG_OFF(self.keybag_state, keybag_state_been_unlocked); + }); +} + ++ (void)unlockAllClasses +{ + dispatch_sync(self.mutabilityQueue, ^{ + [self.lockedStates removeAllObjects]; + + SET_FLAG_OFF(self.keybag_state, keybag_state_locked); + SET_FLAG_ON(self.keybag_state, keybag_state_unlocked); + SET_FLAG_ON(self.keybag_state, keybag_state_been_unlocked); + }); +} + @end kern_return_t @@ -67,14 +205,10 @@ aks_load_bag(const void * data, int length, keybag_handle_t* handle) return 0; } -kern_return_t aks_unlock_bag(keybag_handle_t handle, const void * passcode, int length) -{ - return 0; -} - kern_return_t aks_create_bag(const void * passcode, int length, keybag_type_t type, keybag_handle_t* handle) { + [SecMockAKS unlockAllClasses]; *handle = 17; return 0; } @@ -82,20 +216,57 @@ aks_create_bag(const void * passcode, int length, keybag_type_t type, keybag_han kern_return_t aks_unload_bag(keybag_handle_t handle) { - return -1; + return kAKSReturnSuccess; } kern_return_t aks_save_bag(keybag_handle_t handle, void ** data, int * length) { - return 0; + assert(handle != bad_keybag_handle); + assert(data); + assert(length); + + *data = calloc(1, 12); + memcpy(*data, "keybag dump", 12); + *length = 12; + + return kAKSReturnSuccess; } kern_return_t aks_get_system(keybag_handle_t special_handle, keybag_handle_t *handle) { *handle = 17; - return 0; + return kAKSReturnSuccess; +} + +kern_return_t +aks_get_bag_uuid(keybag_handle_t handle, uuid_t uuid) +{ + memcpy(uuid, "0123456789abcdf", sizeof(uuid_t)); + return kAKSReturnSuccess; +} + +kern_return_t aks_lock_bag(keybag_handle_t handle) +{ + if (handle == KEYBAG_DEVICE) { + [SecMockAKS lockClassA]; + } + return kAKSReturnSuccess; +} + +kern_return_t aks_unlock_bag(keybag_handle_t handle, const void *passcode, int length) +{ + if (handle == KEYBAG_DEVICE) { + [SecMockAKS unlockAllClasses]; + } + return kAKSReturnSuccess; +} + +kern_return_t aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state) +{ + *state = SecMockAKS.keybag_state; + return kAKSReturnSuccess; } //static uint8_t staticAKSKey[32] = "1234567890123456789012"; @@ -105,35 +276,54 @@ aks_get_system(keybag_handle_t special_handle, keybag_handle_t *handle) kern_return_t aks_wrap_key(const void * key, int key_size, keyclass_t key_class, keybag_handle_t handle, void * wrapped_key, int * wrapped_key_size_inout, keyclass_t * class_out) { - if ([SecMockAKS isLocked:key_class]) { - return kIOReturnNotPermitted; - } + [SecMockAKS trapdoor]; + if ([SecMockAKS isSEPDown]) { - return kIOReturnBusy; + return kAKSReturnBusy; + } + + // Assumes non-device keybags are asym + if ([SecMockAKS isLocked:key_class] && handle == KEYBAG_DEVICE) { + return kAKSReturnNoPermission; } - *class_out = key_class; - if ([SecMockAKS useGenerationCount]) { - *class_out |= (key_class_last + 1); + if (class_out) { // Not a required parameter + *class_out = key_class; + if ([SecMockAKS useGenerationCount]) { + *class_out |= (key_class_last + 1); + } } - if (key_size + PADDINGSIZE > *wrapped_key_size_inout) { + if (key_size > APPLE_KEYSTORE_MAX_KEY_LEN) { abort(); } + if (handle != KEYBAG_DEVICE) { // For now assumes non-device bags are asym + if (APPLE_KEYSTORE_MAX_ASYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) { + abort(); + } + } else { + if (APPLE_KEYSTORE_MAX_SYM_WRAPPED_KEY_LEN > *wrapped_key_size_inout) { + abort(); + } + } + *wrapped_key_size_inout = key_size + PADDINGSIZE; memcpy(wrapped_key, key, key_size); memset(((uint8_t *)wrapped_key) + key_size, 0xff, PADDINGSIZE); - return 0; + return kAKSReturnSuccess; } kern_return_t aks_unwrap_key(const void * wrapped_key, int wrapped_key_size, keyclass_t key_class, keybag_handle_t handle, void * key, int * key_size_inout) { - if ([SecMockAKS isLocked:key_class]) { - return kIOReturnNotPermitted; - } + [SecMockAKS trapdoor]; + if ([SecMockAKS isSEPDown]) { - return kIOReturnBusy; + return kAKSReturnBusy; + } + + if ([SecMockAKS isLocked:key_class]) { + return kAKSReturnNoPermission; } if (wrapped_key_size < PADDINGSIZE) { @@ -141,7 +331,7 @@ aks_unwrap_key(const void * wrapped_key, int wrapped_key_size, keyclass_t key_cl } static const char expected_padding[PADDINGSIZE] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; if (memcmp(((const uint8_t *)wrapped_key) + (wrapped_key_size - PADDINGSIZE), expected_padding, PADDINGSIZE) != 0) { - abort(); + return kAKSReturnDecodeError; } if (*key_size_inout < wrapped_key_size - PADDINGSIZE) { abort(); @@ -149,14 +339,24 @@ aks_unwrap_key(const void * wrapped_key, int wrapped_key_size, keyclass_t key_cl *key_size_inout = wrapped_key_size - PADDINGSIZE; memcpy(key, wrapped_key, *key_size_inout); - return 0; + return kAKSReturnSuccess; } 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) { + [SecMockAKS trapdoor]; + + // For now, mock AKS keys are all the same key + NSData* keyData = [NSData dataWithBytes:"1234567890123456789012345678901" length:32]; SFAESKeySpecifier* keySpecifier = [[SFAESKeySpecifier alloc] initWithBitSize:SFAESKeyBitSize256]; - SFAESKey* key = [[SFAESKey alloc] initRandomKeyWithSpecifier:keySpecifier error:nil]; + NSError* error = nil; + SFAESKey* key = [[SFAESKey alloc] initWithData:keyData specifier:keySpecifier error:&error]; + + if(error) { + return kAKSReturnError; + } + *ot = (__bridge_retained aks_ref_key_t)key; return kAKSReturnSuccess; } @@ -167,7 +367,35 @@ aks_ref_key_encrypt(aks_ref_key_t handle, const void * data, size_t data_len, void ** out_der, size_t * out_der_len) { - return -1; + [SecMockAKS trapdoor]; + + // No current error injection + NSError* error = nil; + NSData* nsdata = [NSData dataWithBytes:data length:data_len]; + + SFAESKey* key = (__bridge SFAESKey*)handle; + SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM]; + + + SFAuthenticatedCiphertext* ciphertext = [op encrypt:nsdata withKey:key error:&error]; + + if(error || !ciphertext || !out_der || !out_der_len) { + return kAKSReturnError; + } + + //[NSKeyedUnarchiver unarchivedObjectOfClass:[SFAuthenticatedCiphertext class] fromData:_serializedHolder.ciphertext error:&error]; + + NSData* cipherBytes = [NSKeyedArchiver archivedDataWithRootObject:ciphertext requiringSecureCoding:YES error:&error]; + if(error || !cipherBytes) { + return kAKSReturnError; + } + + *out_der = calloc(1, cipherBytes.length); + + memcpy(*out_der, cipherBytes.bytes, cipherBytes.length); + *out_der_len = cipherBytes.length; + + return kAKSReturnSuccess; } int @@ -176,25 +404,84 @@ aks_ref_key_decrypt(aks_ref_key_t handle, const void * data, size_t data_len, void ** out_der, size_t * out_der_len) { - return -1; + [SecMockAKS trapdoor]; + + if (!out_der || !out_der_len || !data) { + return kAKSReturnError; + } + + NSError* error = nil; + NSData* nsdata = [NSData dataWithBytes:data length:data_len]; + + SFAESKey* key = (__bridge SFAESKey*)handle; + + NSKeyedUnarchiver* unarchiver = [[NSKeyedUnarchiver alloc] initForReadingFromData:nsdata error:&error]; + SFAuthenticatedCiphertext* ciphertext = [unarchiver decodeObjectOfClass:[SFAuthenticatedCiphertext class] forKey:NSKeyedArchiveRootObjectKey]; + + if(error || !ciphertext) { + return kAKSReturnError; + } + + SFAuthenticatedEncryptionOperation* op = [[SFAuthenticatedEncryptionOperation alloc] initWithKeySpecifier:key.keySpecifier authenticationMode:SFAuthenticatedEncryptionModeGCM]; + NSData* plaintext = [op decrypt:ciphertext withKey:key error:&error]; + + if(error || !plaintext) { + return kAKSReturnDecodeError; + } + + *out_der = calloc(1, plaintext.length); + + memcpy(*out_der, plaintext.bytes, plaintext.length); + *out_der_len = plaintext.length; + + return kAKSReturnSuccess; +} + +int aks_ref_key_wrap(aks_ref_key_t handle, + uint8_t *der_params, size_t der_params_len, + const uint8_t *key, size_t key_len, + void **out_der, size_t *out_der_len) +{ + [SecMockAKS trapdoor]; + + return aks_ref_key_encrypt(handle, der_params, der_params_len, key, key_len, out_der, out_der_len); +} + +int aks_ref_key_unwrap(aks_ref_key_t handle, + uint8_t *der_params, size_t der_params_len, + const uint8_t *wrapped, size_t wrapped_len, + void **out_der, size_t *out_der_len) +{ + [SecMockAKS trapdoor]; + + return aks_ref_key_decrypt(handle, der_params, der_params_len, wrapped, wrapped_len, out_der, out_der_len); } + int aks_ref_key_delete(aks_ref_key_t handle, const uint8_t *der_params, size_t der_params_len) { - return -1; + return kAKSReturnSuccess; } int aks_operation_optional_params(const uint8_t * access_groups, size_t access_groups_len, const uint8_t * external_data, size_t external_data_len, const void * acm_handle, int acm_handle_len, void ** out_der, size_t * out_der_len) { - return -1; + // ugh. Let's at least pretend we're doing something here. + assert((out_der && out_der_len) || !(out_der || out_der_len)); + if (out_der) { + *out_der = calloc(1, 150); + memset(*out_der, 'A', 150); + *out_der_len = 150; + } + + return kAKSReturnSuccess; } 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) { aks_ref_key_create(keybag, 0, 0, NULL, 0, handle); - return 0; + return kAKSReturnSuccess; } const uint8_t * aks_ref_key_get_blob(aks_ref_key_t refkey, size_t *out_blob_len) @@ -205,7 +492,7 @@ const uint8_t * aks_ref_key_get_blob(aks_ref_key_t refkey, size_t *out_blob_len) int aks_ref_key_free(aks_ref_key_t* key) { - return 0; + return kAKSReturnSuccess; } const uint8_t * @@ -215,17 +502,19 @@ aks_ref_key_get_external_data(aks_ref_key_t refkey, size_t *out_external_data_le return (const uint8_t *)"21"; } - kern_return_t aks_assert_hold(keybag_handle_t handle, uint32_t type, uint64_t timeout) { - return 0; + if ([SecMockAKS isLocked:key_class_ak]) { + return kAKSReturnNoPermission; + } + return kAKSReturnSuccess; } kern_return_t aks_assert_drop(keybag_handle_t handle, uint32_t type) { - return 0; + return kAKSReturnSuccess; } kern_return_t @@ -234,21 +523,7 @@ aks_generation(keybag_handle_t handle, uint32_t * current_generation) { *current_generation = 0; - return 0; -} - -kern_return_t -aks_get_bag_uuid(keybag_handle_t handle, uuid_t uuid) -{ - memcpy(uuid, "0123456789abcdf", sizeof(uuid_t)); - return 0; -} - -kern_return_t -aks_get_lock_state(keybag_handle_t handle, keybag_state_t *state) -{ - *state = keybag_state_been_unlocked; - return 0; + return kAKSReturnSuccess; } CFStringRef kMKBDeviceModeMultiUser = CFSTR("kMKBDeviceModeMultiUser"); @@ -261,7 +536,7 @@ int MKBKeyBagCreateWithData(CFDataRef keybagBlob, MKBKeyBagHandleRef* newHandle) { *newHandle = (MKBKeyBagHandleRef)staticKeybagHandle; - return 0; + return kMobileKeyBagSuccess; } int @@ -270,7 +545,7 @@ MKBKeyBagUnlock(MKBKeyBagHandleRef keybag, CFDataRef passcode) if (keybag == NULL || !CFEqual(keybag, staticKeybagHandle)) { abort(); } - return 0; + return kMobileKeyBagSuccess; } int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle) @@ -279,13 +554,14 @@ int MKBKeyBagGetAKSHandle(MKBKeyBagHandleRef keybag, int32_t *handle) abort(); } *handle = 17; - return 0; + return kMobileKeyBagSuccess; } int MKBGetDeviceLockState(CFDictionaryRef options) { - if ([SecMockAKS isLocked:key_class_ak] ) + if ([SecMockAKS isLocked:key_class_ak]) { return kMobileKeyBagDeviceIsLocked; + } return kMobileKeyBagDeviceIsUnlocked; } @@ -299,11 +575,9 @@ MKBUserTypeDeviceMode(CFDictionaryRef options, CFErrorRef * error) int MKBForegroundUserSessionID( CFErrorRef * error) { - return 0; + return kMobileKeyBagSuccess; } -#endif /* USE_KEYSTORE */ - const CFTypeRef kAKSKeyAcl = (CFTypeRef)CFSTR("kAKSKeyAcl"); const CFTypeRef kAKSKeyAclParamRequirePasscode = (CFTypeRef)CFSTR("kAKSKeyAclParamRequirePasscode"); @@ -389,12 +663,13 @@ ACMContextCreateWithExternalForm(const void *externalForm, size_t dataLength) ACMStatus ACMContextDelete(ACMContextRef context, bool destroyContext) { - return 0; + return kACMErrorSuccess; } ACMStatus ACMContextRemovePassphraseCredentialsByPurposeAndScope(const ACMContextRef context, ACMPassphrasePurpose purpose, ACMScope scope) { - return 0; + return kACMErrorSuccess; } +#endif // TARGET_OS_BRIDGE diff --git a/tests/secdmockaks/secdmockaks.m b/tests/secdmockaks/mockaksKeychain.m similarity index 75% rename from tests/secdmockaks/secdmockaks.m rename to tests/secdmockaks/mockaksKeychain.m index 50457bf2..120d8fa0 100644 --- a/tests/secdmockaks/secdmockaks.m +++ b/tests/secdmockaks/mockaksKeychain.m @@ -27,6 +27,8 @@ #import "CKKS.h" #import "SecItemPriv.h" #import "SecItemServer.h" +#import "SecItemSchema.h" +#include "OSX/sec/Security/SecItemShim.h" #import "spi.h" #import #import @@ -34,7 +36,9 @@ #import #import #if USE_KEYSTORE +#if __has_include() #import +#endif // aks.h #endif #import #import "mockaks.h" @@ -42,74 +46,13 @@ #import "secdmock_db_version_10_5.h" #import "secdmock_db_version_11_1.h" -@interface secdmockaks : XCTestCase -@property NSString *testHomeDirectory; -@property long lockCounter; +#import "mockaksxcbase.h" + +@interface secdmockaks : mockaksxcbase @end @implementation secdmockaks -+ (void)setUp -{ - [super setUp]; - - SecCKKSDisable(); - /* - * Disable all of SOS syncing since that triggers retains of database - * and these tests muck around with the database over and over again, so - * that leads to the vnode delete kevent trap triggering for sqlite - * over and over again. - */ -#if OCTAGON - SecCKKSTestSetDisableSOS(true); -#endif - //securityd_init(NULL); -} - -- (void)createKeychainDirectory -{ - [[NSFileManager defaultManager] createDirectoryAtPath:[NSString stringWithFormat: @"%@/Library/Keychains", self.testHomeDirectory] withIntermediateDirectories:YES attributes:nil error:NULL]; -} - -- (void)removeHomeDirectory -{ - if (self.testHomeDirectory) { - [[NSFileManager defaultManager] removeItemAtPath:self.testHomeDirectory error:NULL]; - } -} - -- (void)setUp { - [super setUp]; - - NSString* testName = [self.name componentsSeparatedByString:@" "][1]; - testName = [testName stringByReplacingOccurrencesOfString:@"]" withString:@""]; - secnotice("ckkstest", "Beginning test %@", testName); - - // Make a new fake keychain - self.testHomeDirectory = [NSString stringWithFormat: @"/tmp/%@.%X", testName, arc4random()]; - [self createKeychainDirectory]; - - SetCustomHomeURLString((__bridge CFStringRef) self.testHomeDirectory); - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - securityd_init(NULL); - }); - SecKeychainDbReset(NULL); - - // Actually load the database. - kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); -} - -- (void)tearDown -{ - SetCustomHomeURLString(NULL); - SecKeychainDbReset(^{ - [self removeHomeDirectory]; - self.testHomeDirectory = nil; - }); - //kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); -} - - (void)testAddDeleteItem { @@ -117,7 +60,7 @@ (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -143,7 +86,7 @@ (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : [NSString stringWithFormat:@"TestAccount-%u", n], (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, errSecSuccess, @"failed to add test item to keychain: %u", n); @@ -158,13 +101,39 @@ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : [NSString stringWithFormat:@"TestAccount-%u", n], (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, errSecSuccess, @"failed to find test item to keychain: %u", n); } } +- (void)findNoItems:(unsigned)searchLimit +{ + unsigned n; + for (n = 0; n < searchLimit; n++) { + NSDictionary* item = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrAccount : [NSString stringWithFormat:@"TestAccount-%u", n], + (id)kSecAttrService : @"TestService", + (id)kSecUseDataProtectionKeychain : @(YES) + }; + OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); + XCTAssertEqual(result, errSecItemNotFound, @"not expecting to find an item (%d): %u", (int)result, n); + } +} + +- (void)deleteAllItems +{ + NSDictionary* item = @{ + (id)kSecClass : (id)kSecClassGenericPassword, + (id)kSecAttrService : @"TestService", + (id)kSecUseDataProtectionKeychain : @(YES) + }; + OSStatus result = SecItemDelete((__bridge CFDictionaryRef)item); + XCTAssertEqual(result, 0, @"failed to delete all test items"); +} + - (void)testSecItemServerDeleteAll { // BT root key, should not be deleted @@ -264,7 +233,7 @@ NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, (id)kSecValueRef : (__bridge id)key, (id)kSecAttrLabel : [NSString stringWithFormat:@"TestLabel-%u", n], - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test key to keychain: %u", n); @@ -282,7 +251,7 @@ (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding], (id)kSecAttrAccount : @"TestAccount", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -367,11 +336,13 @@ { const char *s; unsigned n = 0; - - [self removeHomeDirectory]; - [self createKeychainDirectory]; - NSString *path = CFBridgingRelease(__SecKeychainCopyPath()); + // We need a fresh directory to plop down our SQLite data + SetCustomHomeURLString((__bridge CFStringRef)[self createKeychainDirectoryWithSubPath:@"loadManualDB"]); + NSString* path = CFBridgingRelease(__SecKeychainCopyPath()); + // On macOS the full path gets created, on iOS not (yet?) + [self createKeychainDirectoryWithSubPath:@"loadManualDB/Library/Keychains"]; + sqlite3 *handle = NULL; XCTAssertEqual(SQLITE_OK, sqlite3_open([path UTF8String], &handle), "create keychain"); @@ -438,6 +409,65 @@ [self checkIncremental]; } +#if TARGET_OS_IOS + +- (void)testPersonaBasic +{ + SecSecuritySetPersonaMusr(NULL); + + [self createManyItems]; + [self findManyItems:10]; + + SecSecuritySetPersonaMusr(CFSTR("99C5D3CC-2C2D-47C4-9A1C-976EC047BF3C")); + + [self findNoItems:10]; + [self createManyItems]; + [self findManyItems:10]; + + [self deleteAllItems]; + [self findNoItems:10]; + + SecSecuritySetPersonaMusr(NULL); + + [self findManyItems:10]; + [self deleteAllItems]; + [self findNoItems:10]; + + SecSecuritySetPersonaMusr(CFSTR("8E90C6BE-0AF6-40D6-8A4B-D46E4CF6A622")); + + [self createManyItems]; + + SecSecuritySetPersonaMusr(CFSTR("38B615CA-02C2-4733-A71C-1ABA46D27B13")); + + [self findNoItems:10]; + [self createManyItems]; + + SecSecuritySetPersonaMusr(NULL); + + XCTestExpectation *expection = [self expectationWithDescription:@"wait for deletion"]; + + _SecKeychainDeleteMultiUser(@"8E90C6BE-0AF6-40D6-8A4B-D46E4CF6A622", ^(bool status, NSError *error) { + [expection fulfill]; + }); + + [self waitForExpectations:@[expection] timeout:10.0]; + + /* check that delete worked ... */ + SecSecuritySetPersonaMusr(CFSTR("8E90C6BE-0AF6-40D6-8A4B-D46E4CF6A622")); + [self findNoItems:10]; + + /* ... but didn't delete another account */ + SecSecuritySetPersonaMusr(CFSTR("38B615CA-02C2-4733-A71C-1ABA46D27B13")); + [self findManyItems:10]; + + SecSecuritySetPersonaMusr(NULL); + + + [self findNoItems:10]; +} + +#endif /* TARGET_OS_IOS */ + #if USE_KEYSTORE - (void)testAddKeyByReference @@ -447,7 +477,7 @@ NSDictionary* item = @{ (id)kSecClass : (id)kSecClassKey, (id)kSecValueRef : (__bridge id)key, (id)kSecAttrLabel : @"TestLabel", - (id)kSecAttrNoLegacy : @(YES) }; + (id)kSecUseDataProtectionKeychain : @(YES) }; OSStatus result = SecItemAdd((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"failed to add test item to keychain"); @@ -498,7 +528,7 @@ (id)kSecAttrAccount : @"TestAccount-11", (id)kSecAttrService : @"TestService", (id)kSecReturnData : @YES, - (id)kSecAttrNoLegacy : @YES + (id)kSecUseDataProtectionKeychain : @YES }; result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, errSecInteractionNotAllowed, @"SEP not locked?"); @@ -508,7 +538,6 @@ NSLog(@"user unlock"); [mock stopMocking]; - result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, 0, @"can't find item"); @@ -534,7 +563,7 @@ (id)kSecClass : (id)kSecClassGenericPassword, (id)kSecAttrAccount : @"TestAccount-0", (id)kSecAttrService : @"TestService", - (id)kSecAttrNoLegacy : @(YES) + (id)kSecUseDataProtectionKeychain : @(YES) }; result = SecItemCopyMatching((__bridge CFDictionaryRef)item, NULL); XCTAssertEqual(result, errSecNotAvailable, @"SEP not down?"); @@ -561,7 +590,9 @@ int version = 0; SecKeychainDbGetVersion(dbt, &version, &error); XCTAssertEqual(error, NULL, "error getting version"); - XCTAssertEqual(version, 0x40b, "didnt managed to upgrade"); + const SecDbSchema *schema = current_schema(); + int schemaVersion = (((schema)->minorVersion) << 8) | ((schema)->majorVersion); + XCTAssertEqual(version, schemaVersion, "didn't manage to upgrade"); return true; }); @@ -570,6 +601,37 @@ [self findManyItems:50]; } +// We used to try and parse a CFTypeRef as a 32 bit int before trying 64, but that fails if keytype is weird. +- (void)testBindObjectIntParsing +{ + NSMutableDictionary* query = [@{ (id)kSecClass : (id)kSecClassKey, + (id)kSecAttrCanEncrypt : @(YES), + (id)kSecAttrCanDecrypt : @(YES), + (id)kSecAttrCanDerive : @(NO), + (id)kSecAttrCanSign : @(NO), + (id)kSecAttrCanVerify : @(NO), + (id)kSecAttrCanWrap : @(NO), + (id)kSecAttrCanUnwrap : @(NO), + (id)kSecAttrKeySizeInBits : @(256), + (id)kSecAttrEffectiveKeySize : @(256), + (id)kSecValueData : [@"a" dataUsingEncoding:NSUTF8StringEncoding], + (id)kSecAttrKeyType : [NSNumber numberWithUnsignedInt:0x80000001L], // durr + } mutableCopy]; + + XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)query, NULL), errSecSuccess, "Succeeded in adding key to keychain"); + + query[(id)kSecValueData] = nil; + NSDictionary* update = @{(id)kSecValueData : [@"b" dataUsingEncoding:NSUTF8StringEncoding]}; + XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update), errSecSuccess, "Successfully updated key in keychain"); + + CFTypeRef output = NULL; + query[(id)kSecReturnAttributes] = @(YES); + XCTAssertEqual(SecItemCopyMatching((__bridge CFDictionaryRef)query, &output), errSecSuccess, "Found key in keychain"); + XCTAssertNotNil((__bridge id)output, "got output from SICM"); + XCTAssertEqual(CFGetTypeID(output), CFDictionaryGetTypeID(), "output is a dictionary"); + XCTAssertEqual(CFDictionaryGetValue(output, (id)kSecAttrKeyType), (__bridge CFNumberRef)[NSNumber numberWithUnsignedInt:0x80000001L], "keytype is unchanged"); +} + #endif /* USE_KEYSTORE */ @end diff --git a/tests/secdmockaks/mockaksWatchDog.m b/tests/secdmockaks/mockaksWatchDog.m new file mode 100644 index 00000000..59bdc651 --- /dev/null +++ b/tests/secdmockaks/mockaksWatchDog.m @@ -0,0 +1,44 @@ +// +// mockaksWatchDog.m +// Security +// + +#import +#import + +#import "mockaksxcbase.h" +#import "SecdWatchdog.h" + +@interface mockaksWatchDog : mockaksxcbase +@property (assign) uint64_t diskusage; +@end + +@implementation mockaksWatchDog + +- (bool)mockedWatchdogrusage:(rusage_info_current *)rusage +{ + memset(rusage, 0, sizeof(*rusage)); + rusage->ri_diskio_byteswritten = self.diskusage; + rusage->ri_logical_writes = self.diskusage; + return true; +} + + +- (void)testWatchDogDiskWrite { + + id mock = OCMClassMock([SecdWatchdog class]); + OCMStub([mock watchdogrusage:[OCMArg anyPointer]]).andCall(self, @selector(mockedWatchdogrusage:)); + OCMStub([mock triggerOSFaults]).andReturn(FALSE); + + SecdWatchdog *wd = [SecdWatchdog watchdog]; + + self.diskusage = 0; + XCTAssertFalse(wd.diskUsageHigh, "diskusage high should not be true"); + + self.diskusage = 2 * 1000 * 1024 * 1024; // 2GiBi + [wd runWatchdog]; + + XCTAssertTrue(wd.diskUsageHigh, "diskusage high should be true"); +} + +@end diff --git a/tests/secdmockaks/mockaksxcbase.h b/tests/secdmockaks/mockaksxcbase.h new file mode 100644 index 00000000..63ec0791 --- /dev/null +++ b/tests/secdmockaks/mockaksxcbase.h @@ -0,0 +1,19 @@ +// +// mockaksxcbase.h +// Security +// + +#ifndef mockaksxcbase_h +#define mockaksxcbase_h + +#import + +@interface mockaksxcbase : XCTestCase +@property NSString *testHomeDirectory; +@property long lockCounter; + +- (NSString*)createKeychainDirectoryWithSubPath:(NSString*)subpath; + +@end + +#endif /* mockaksxcbase_h */ diff --git a/tests/secdmockaks/mockaksxcbase.m b/tests/secdmockaks/mockaksxcbase.m new file mode 100644 index 00000000..3d111f3e --- /dev/null +++ b/tests/secdmockaks/mockaksxcbase.m @@ -0,0 +1,90 @@ + +// +// mocksecdbase.m +// Security +// + +#import "SecKeybagSupport.h" +#import "SecDbKeychainItem.h" +#import "SecdTestKeychainUtilities.h" +#import "CKKS.h" +#import "SecItemPriv.h" +#import "SecItemServer.h" +#import "spi.h" +#import +#import +#import +#import +#import +#import +#import "mockaks.h" + +#import "mockaksxcbase.h" + +NSString* homeDirUUID; + +@implementation mockaksxcbase + ++ (void)setUp +{ + [super setUp]; + + SecCKKSDisable(); + /* + * Disable all of SOS syncing since that triggers retains of database + * and these tests muck around with the database over and over again, so + * that leads to the vnode delete kevent trap triggering for sqlite + * over and over again. + */ +#if OCTAGON + SecCKKSTestSetDisableSOS(true); +#endif + // Give this test run a UUID within which each test has a directory + homeDirUUID = [[NSUUID UUID] UUIDString]; +} + +- (NSString*)createKeychainDirectoryWithSubPath:(NSString*)suffix +{ + NSError* error; + NSString* dir = suffix ? [NSString stringWithFormat:@"%@/%@/", self.testHomeDirectory, suffix] : self.testHomeDirectory; + [[NSFileManager defaultManager] createDirectoryAtPath:dir + withIntermediateDirectories:YES + attributes:nil + error:&error]; + XCTAssertNil(error, "Unable to create directory: %@", error); + return dir; +} + +- (void)createKeychainDirectory +{ + [self createKeychainDirectoryWithSubPath:nil]; +} + +- (void)setUp { + [super setUp]; + + NSString* testName = [self.name componentsSeparatedByString:@" "][1]; + testName = [testName stringByReplacingOccurrencesOfString:@"]" withString:@""]; + secnotice("ckkstest", "Beginning test %@", testName); + + self.testHomeDirectory = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@/%@/", homeDirUUID, testName]]; + [self createKeychainDirectory]; + + SetCustomHomeURLString((__bridge CFStringRef) self.testHomeDirectory); + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + securityd_init(NULL); + }); + SecKeychainDbReset(NULL); + + // Actually load the database. + kc_with_dbt(true, NULL, ^bool (SecDbConnectionRef dbt) { return false; }); +} + ++ (void)tearDown +{ + SetCustomHomeURLString(NULL); + SecKeychainDbReset(NULL); +} + +@end diff --git a/trust/SecCertificate.h b/trust/SecCertificate.h index 1f291452..fcadd01d 100644 --- a/trust/SecCertificate.h +++ b/trust/SecCertificate.h @@ -150,6 +150,7 @@ CFDataRef SecCertificateCopyNormalizedSubjectSequence(SecCertificateRef certific @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. + @discussion RSA and ECDSA public keys are supported. All other public key algorithms are unsupported. */ __nullable CF_RETURNS_RETAINED SecKeyRef SecCertificateCopyKey(SecCertificateRef certificate) @@ -165,7 +166,7 @@ SecKeyRef SecCertificateCopyKey(SecCertificateRef certificate) */ __nullable SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate) - API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", ios(10.3, 12.0)) API_UNAVAILABLE(macos); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", ios(10.3, 12.0)) API_UNAVAILABLE(macos, iosmac); #endif #if TARGET_OS_OSX @@ -178,7 +179,7 @@ SecKeyRef SecCertificateCopyPublicKey(SecCertificateRef certificate) @discussion NOTE: Deprecated in macOS 10.14; use SecCertificateCopyKey instead for cross-platform availability. */ OSStatus SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef * __nonnull CF_RETURNS_RETAINED key) - API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", macos(10.3, 10.14)) API_UNAVAILABLE(ios); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopyKey", macos(10.3, 10.14)) API_UNAVAILABLE(ios, tvos, watchos, bridgeos, iosmac); #endif /*! @@ -201,7 +202,7 @@ CFDataRef SecCertificateCopySerialNumberData(SecCertificateRef certificate, CFEr */ __nullable CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate) - API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", ios(10.3, 11.0)) API_UNAVAILABLE(macos); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", ios(10.3, 11.0)) API_UNAVAILABLE(macos, iosmac); #endif #if TARGET_OS_OSX @@ -214,7 +215,7 @@ CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate) */ __nullable CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error) - API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", macos(10.7, 10.13)) API_UNAVAILABLE(ios); + API_DEPRECATED_WITH_REPLACEMENT("SecCertificateCopySerialNumberData", macos(10.7, 10.13)) API_UNAVAILABLE(ios, tvos, watchos, bridgeos, iosmac); #endif /* @@ -462,6 +463,8 @@ extern const CFStringRef kSecPropertyTypeData __OSX_AVAILABLE_STARTING(__MAC_10_ extern const CFStringRef kSecPropertyTypeString __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); extern const CFStringRef kSecPropertyTypeURL __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); extern const CFStringRef kSecPropertyTypeDate __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); +extern const CFStringRef kSecPropertyTypeArray API_AVAILABLE(macos(10.15)) SPI_AVAILABLE(ios(13.0), watchos(6.0), tvos(13.0), iosmac(13.0)); +extern const CFStringRef kSecPropertyTypeNumber API_AVAILABLE(macos(10.15)) SPI_AVAILABLE(ios(13.0), watchos(6.0), tvos(13.0), iosmac(13.0)); /*! @function SecCertificateCopyValues diff --git a/trust/SecCertificatePriv.h b/trust/SecCertificatePriv.h index 9c28e8e4..3fa2fe4e 100644 --- a/trust/SecCertificatePriv.h +++ b/trust/SecCertificatePriv.h @@ -357,6 +357,17 @@ CFArrayRef SecCertificateCopySignedCertificateTimestamps(SecCertificateRef certi CFDataRef SecCertificateCopyPrecertTBS(SecCertificateRef certificate) __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_9_0); +/* Returns a dictionary of dictionaries for system-trusted CT logs, indexed by the LogID */ +CFDictionaryRef SecCertificateCopyTrustedCTLogs(void) + __OSX_AVAILABLE_STARTING(__MAC_10_15, __IPHONE_13_0); + +/* Returns a dictionary for the CT log matching the provided + * key ID, or NULL if no matching log is found. + * And by keyID we mean LogID as specified in RFC 6962. + */ +CFDictionaryRef SecCertificateCopyCTLogForKeyID(CFDataRef keyID) + __OSX_AVAILABLE_STARTING(__MAC_10_15, __IPHONE_13_0); + /* Return the auth capabilities bitmask from the iAP marker extension */ CF_RETURNS_RETAINED CFDataRef SecCertificateCopyiAPAuthCapabilities(SecCertificateRef certificate) __OSX_AVAILABLE_STARTING(__MAC_10_12, __IPHONE_10_0); @@ -419,6 +430,17 @@ CFDataRef SecCertificateCopyExtensionValue(SecCertificateRef certificate, CFTypeRef extensionOID, bool *isCritical) __OSX_AVAILABLE_STARTING(__MAC_10_13_4, __IPHONE_11_3); +/* Return an array of CFURLRefs each of which is an ocspResponder for this + certificate. */ +CFArrayRef SecCertificateGetOCSPResponders(SecCertificateRef certificate) + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + + +/* Return the component type string in a component certificate. */ +CF_RETURNS_RETAINED +CFStringRef SecCertificateCopyComponentType(SecCertificateRef certificate) + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + bool SecCertificateGetDeveloperIDDate(SecCertificateRef certificate, CFAbsoluteTime *time, CFErrorRef * CF_RETURNS_RETAINED error); /* @@ -470,7 +492,8 @@ OSStatus SecCertificateInferLabel(SecCertificateRef certificate, CFStringRef *la * if no appropriate printable name found. */ const CSSM_DATA *SecInferLabelFromX509Name( - const CSSM_X509_NAME *x509Name); + const CSSM_X509_NAME *x509Name) + DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* Accessors for fields in the cached certificate */ diff --git a/trust/SecPolicy.h b/trust/SecPolicy.h index 04b25e74..59e95b54 100644 --- a/trust/SecPolicy.h +++ b/trust/SecPolicy.h @@ -73,9 +73,9 @@ extern const CFStringRef kSecPolicyAppleiChat __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_7, __MAC_10_9, __IPHONE_NA, __IPHONE_NA); #endif extern const CFStringRef kSecPolicyApplePKINITClient - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); extern const CFStringRef kSecPolicyApplePKINITServer - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA); + API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos, bridgeos, iosmac); extern const CFStringRef kSecPolicyAppleCodeSigning __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0); extern const CFStringRef kSecPolicyMacAppStoreReceipt @@ -197,6 +197,8 @@ SecPolicyRef SecPolicyCreateSSL(Boolean server, CFStringRef __nullable hostname) where failure to reach the server is not considered fatal. @constant kSecRevocationNetworkAccessDisabled If this flag is set, then no network access is performed; only locally cached replies are consulted. + This constant disallows network access for both revocation checks and + intermediate CA issuer fetching. @constant kSecRevocationUseAnyAvailableMethod Specifies that either OCSP or CRL may be used, depending on the method(s) specified in the certificate and the value of kSecRevocationPreferCRL. @@ -250,7 +252,7 @@ CF_ASSUME_NONNULL_END /* * Legacy functions (OS X only) */ -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX #include CF_ASSUME_NONNULL_BEGIN diff --git a/trust/SecPolicyPriv.h b/trust/SecPolicyPriv.h index 0fd731f1..360e7faa 100644 --- a/trust/SecPolicyPriv.h +++ b/trust/SecPolicyPriv.h @@ -181,6 +181,12 @@ 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)); +extern const CFStringRef kSecPolicyAppleComponentCertificate + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); +extern const CFStringRef kSecPolicyAppleKeyTransparency + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); +extern const CFStringRef kSecPolicyAppleLegacySSL + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); /*! @enum Policy Name Constants (Private) @@ -200,6 +206,8 @@ extern const CFStringRef kSecPolicyAppleDeveloperIDPlusTicket @constant kSecPolicyNameAppleMapsService @constant kSecPolicyNameAppleHealthProviderService @constant kSecPolicyNameAppleParsecService + @constant kSecPolicyNameAppleAMPService + @constant kSecPolicyNameAppleSiriService */ extern const CFStringRef kSecPolicyNameAppleAST2Service __OSX_AVAILABLE(10.13) __IOS_AVAILABLE(11.0) __TVOS_AVAILABLE(11.0) __WATCHOS_AVAILABLE(4.0); @@ -229,6 +237,10 @@ extern const CFStringRef kSecPolicyNameAppleHealthProviderService __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); extern const CFStringRef kSecPolicyNameAppleParsecService __OSX_AVAILABLE(10.13.4) __IOS_AVAILABLE(11.3) __TVOS_AVAILABLE(11.3) __WATCHOS_AVAILABLE(4.3); +extern const CFStringRef kSecPolicyNameAppleAMPService + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); +extern const CFStringRef kSecPolicyNameAppleSiriService + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); /*! @enum Policy Value Constants @@ -1751,10 +1763,65 @@ __nullable CF_RETURNS_RETAINED SecPolicyRef SecPolicyCreateAppleFDRProvisioning(void) API_AVAILABLE(macos(10.14), ios(12.0), watchos(5.0), tvos(12.0)); +/*! + @function SecPolicyCreateAppleComponentCertificate + @abstract Returns a policy object for verifying Component certs + @param testRootHash Optional; The SHA-256 fingerprint of a test root for pinning. + @discussion The resulting policy uses the Basic X.509 policy with validity check and + pinning options: + * The chain is anchored to the Component Root CA. + * There are exactly 3 certs in the chain. + * The leaf and intermediate each have a marker extension with OID matching 1.2.840.113635.100.11.1 + @result A policy object. The caller is responsible for calling CFRelease on this when + it is no longer needed. + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateAppleComponentCertificate(CFDataRef __nullable testRootHash) + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + +/*! + @function SecPolicyCreateAppleKeyTransparency + @abstract Returns a policy object for verifying Apple certificates. + @param applicationId A string that identifies the applicationId. + @discussion The resulting 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 TBD. + * The leaf has a marker extension with OID 1.2.840.113635.100.6.69.1 and value + matching the applicationId. + * Revocation is checked via any available method. + * 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 SecPolicyCreateAppleKeyTransparency(CFStringRef applicationId) + API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + +/*! + @function SecPolicyCreateLegacySSL + @abstract Returns a policy object for evaluating legacy SSL certificate chains that don't meet + SecPolicyCreateSSL. + @param server Passing true for this parameter creates a policy for SSL + server certificates. + @param hostname (Optional) If present, the policy will require the specified + hostname to match the hostname in the leaf certificate. + @result A policy object. The caller is responsible for calling CFRelease + on this when it is no longer needed. + @discussion Use of this policy will be audited. Passing false for the server parameter will + result in a SecPolicy object with the same requirements as SecPolicyCreateSSL with a false + server parameter (i.e. the client authentication verification performed by this policy is + identical to the client authentication verification performed by SecPolicyCreateSSL). + */ +__nullable CF_RETURNS_RETAINED +SecPolicyRef SecPolicyCreateLegacySSL(Boolean server, CFStringRef __nullable hostname) + SPI_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)); + /* * Legacy functions (OS X only) */ -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX /*! @function SecPolicyCopy @@ -1842,9 +1909,12 @@ extern const CFStringRef kSecPolicyCheckIdLinkage; extern const CFStringRef kSecPolicyCheckIntermediateCountry; extern const CFStringRef kSecPolicyCheckIntermediateEKU; extern const CFStringRef kSecPolicyCheckIntermediateMarkerOid; +extern const CFStringRef kSecPolicyCheckIntermediateMarkerOidWithoutValueCheck; extern const CFStringRef kSecPolicyCheckIntermediateOrganization; extern const CFStringRef kSecPolicyCheckIntermediateSPKISHA256; extern const CFStringRef kSecPolicyCheckIssuerCommonName; +extern const CFStringRef kSecPolicyCheckIssuerPolicyConstraints; +extern const CFStringRef kSecPolicyCheckIssuerNameConstraints; extern const CFStringRef kSecPolicyCheckKeySize; extern const CFStringRef kSecPolicyCheckKeyUsage; extern const CFStringRef kSecPolicyCheckLeafMarkerOid; @@ -1862,6 +1932,7 @@ extern const CFStringRef kSecPolicyCheckRevocationIfTrusted; extern const CFStringRef kSecPolicyCheckRevocationOnline; extern const CFStringRef kSecPolicyCheckRevocationResponseRequired; extern const CFStringRef kSecPolicyCheckSSLHostname; +extern const CFStringRef kSecPolicyCheckServerAuthEKU; extern const CFStringRef kSecPolicyCheckSignatureHashAlgorithms; extern const CFStringRef kSecPolicyCheckSubjectCommonName; extern const CFStringRef kSecPolicyCheckSubjectCommonNamePrefix; @@ -1872,7 +1943,9 @@ extern const CFStringRef kSecPolicyCheckSystemTrustedCTRequired; extern const CFStringRef kSecPolicyCheckSystemTrustedWeakHash; extern const CFStringRef kSecPolicyCheckSystemTrustedWeakKey; extern const CFStringRef kSecPolicyCheckTemporalValidity; +extern const CFStringRef kSecPolicyCheckUnparseableExtension; extern const CFStringRef kSecPolicyCheckUsageConstraints; +extern const CFStringRef kSecPolicyCheckValidityPeriodMaximums; extern const CFStringRef kSecPolicyCheckValidRoot; extern const CFStringRef kSecPolicyCheckWeakKeySize; extern const CFStringRef kSecPolicyCheckWeakSignature; @@ -1928,6 +2001,7 @@ bool SecPolicyCheckCertSignatureHashAlgorithms(SecCertificateRef cert, CFTypeRef bool SecPolicyCheckCertCertificatePolicy(SecCertificateRef cert, CFTypeRef pvcValue); bool SecPolicyCheckCertCriticalExtensions(SecCertificateRef cert, CFTypeRef __nullable pvcValue); bool SecPolicyCheckCertSubjectCountry(SecCertificateRef cert, CFTypeRef pvcValue); +bool SecPolicyCheckCertUnparseableExtension(SecCertificateRef cert, CFTypeRef pvcValue); void SecPolicySetName(SecPolicyRef policy, CFStringRef policyName); __nullable CFArrayRef SecPolicyXPCArrayCopyArray(xpc_object_t xpc_policies, CFErrorRef *error); diff --git a/trust/SecTrust.h b/trust/SecTrust.h index 439750e8..a48083cd 100644 --- a/trust/SecTrust.h +++ b/trust/SecTrust.h @@ -269,13 +269,14 @@ OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust, @abstract Sets the anchor certificates for a given trust. @param trust A reference to a trust object. @param anchorCertificates An array of anchor certificates. + Pass NULL to restore the default set of anchor certificates. @result A result code. See "Security Error Codes" (SecBase.h). @discussion Calling this function without also calling SecTrustSetAnchorCertificatesOnly() will disable trusting any anchors other than the ones in anchorCertificates. */ OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust, - CFArrayRef anchorCertificates) + CFArrayRef __nullable anchorCertificates) __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_2_0); /*! @@ -351,10 +352,10 @@ CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust) */ OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) API_DEPRECATED_WITH_REPLACEMENT("SecTrustEvaluateWithError", - macos(10.3, API_TO_BE_DEPRECATED), - ios(2.0, API_TO_BE_DEPRECATED), - watchos(1.0, API_TO_BE_DEPRECATED), - tvos(2.0, API_TO_BE_DEPRECATED)); + macos(10.3, 10.15), + ios(2.0, 13.0), + watchos(1.0, 6.0), + tvos(2.0, 13.0)); #ifdef __BLOCKS__ /*! @@ -369,7 +370,11 @@ OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *result) */ OSStatus SecTrustEvaluateAsync(SecTrustRef trust, dispatch_queue_t __nullable queue, SecTrustCallback result) - __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_7_0); + API_DEPRECATED_WITH_REPLACEMENT("SecTrustEvaluateAsyncWithError", + macos(10.7, 10.15), + ios(7.0, 13.0), + watchos(1.0, 6.0), + tvos(7.0, 13.0)); #endif /*! @@ -397,6 +402,41 @@ __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)); +#ifdef __BLOCKS__ +/*! + @typedef SecTrustWithErrorCallback + @abstract Delivers the result from an asynchronous trust evaluation. + @param trustRef A reference to the trust object which has been evaluated. + @param result A boolean value indicating whether the certificate is trusted. + @param error An error if the trust evaluation failed. + */ +typedef void (^SecTrustWithErrorCallback)(SecTrustRef trustRef, bool result, CFErrorRef _Nullable error); + +/*! + @function SecTrustEvaluateAsyncWithError + @abstract Evaluates a trust reference asynchronously. + @param trust A reference to the trust object to evaluate. + @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 SecTrustWithErrorCallback 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). + @discussion If the certificate is trusted, the callback will return a result parameter of true + and the error will be set to NULL. + If the certificate is not trusted or the evaluation was unable to complete, the result parameter + 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. + */ +OSStatus SecTrustEvaluateAsyncWithError(SecTrustRef trust, dispatch_queue_t queue, SecTrustWithErrorCallback result) + API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0), watchos(6.0)); +#endif /* __BLOCKS__ */ + /*! @function SecTrustGetTrustResult @param trust A reference to a trust object. @@ -565,7 +605,7 @@ CF_ASSUME_NONNULL_END /* * Legacy functions (OS X only) */ -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX #include #include diff --git a/trust/SecTrustPriv.h b/trust/SecTrustPriv.h index 9cbd5421..5bf6e60b 100644 --- a/trust/SecTrustPriv.h +++ b/trust/SecTrustPriv.h @@ -55,6 +55,8 @@ extern const CFStringRef kSecPropertyTypeData; extern const CFStringRef kSecPropertyTypeString; extern const CFStringRef kSecPropertyTypeURL; extern const CFStringRef kSecPropertyTypeDate; +extern const CFStringRef kSecPropertyTypeArray; +extern const CFStringRef kSecPropertyTypeNumber; /* Constants used as keys in the dictionary returned by SecTrustCopyInfo. */ extern const CFStringRef kSecTrustInfoExtendedValidationKey; @@ -273,6 +275,27 @@ uint64_t SecTrustGetAssetVersionNumber(CFErrorRef _Nullable * _Nullable CF_RETUR */ uint64_t SecTrustOTAPKIGetUpdatedAsset(CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error); +/* + @function SecTrustOTASecExperimentGetUpdatedAsset + @abstract Trigger trustd to fetch a new SecExperiment asset right now. + @param error A returned error if trustd failed to update the asset. + @result The current version of the update, regardless of the success of the update. + @discussion This function blocks up to 1 minute until trustd has finished with the + asset download and update. You should use the error parameter to determine whether + the update was was successful. The current asset version is always returned. + */ +uint64_t SecTrustOTASecExperimentGetUpdatedAsset(CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error); + +/* + @function SecTrustOTASecExperimentCopyAsset + @abstract Get current asset from trustd + @param error A returned error if trustd fails to return asset + @result Dictionary of asset + @discussion If the error parameter is supplied, and the function returns false, + the caller is subsequently responsible for releasing the returned CFErrorRef. + */ +CFDictionaryRef SecTrustOTASecExperimentCopyAsset(CFErrorRef _Nullable * _Nullable CF_RETURNS_RETAINED error); + /*! @function SecTrustFlushResponseCache @abstract Removes all OCSP responses from the per-user response cache. @@ -410,6 +433,28 @@ 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); +#if TARGET_OS_IPHONE +/*! + @function SecTrustGetExceptionResetCount + @abstract Returns the current epoch of trusted exceptions. + @param error A pointer to an error. + @result An unsigned 64-bit integer representing the current epoch. + @discussion Exceptions tagged with an older epoch are not trusted. + */ +uint64_t SecTrustGetExceptionResetCount(CFErrorRef *error) + API_UNAVAILABLE(macos, iosmac) API_AVAILABLE(ios(12.0), tvos(12.0), watchos(5.0)); + +/*! + @function SecTrustIncrementExceptionResetCount + @abstract Increases the current epoch of trusted exceptions by 1. + @param error A pointer to an error. + @result A result code. See "Security Error Codes" (SecBase.h) + @discussion By increasing the current epoch any existing exceptions, tagged with the old epoch, become distrusted. + */ +OSStatus SecTrustIncrementExceptionResetCount(CFErrorRef *error) + __API_UNAVAILABLE(macos, iosmac) __API_AVAILABLE(ios(12.0), tvos(12.0), watchos(5.0)); +#endif + #ifdef __BLOCKS__ /*! @function SecTrustEvaluateFastAsync @@ -437,9 +482,9 @@ bool SecTrustReportTLSAnalytics(CFStringRef eventName, xpc_object_t eventAttribu /*! @function SecTrustReportNetworkingAnalytics @discussion This function MUST NOT be called outside of the networking stack. - */ +*/ bool SecTrustReportNetworkingAnalytics(const char *eventName, xpc_object_t eventAttributes) -__API_AVAILABLE(macos(10.14.1), ios(12.1), tvos(12.1), watchos(5.1)); + __API_AVAILABLE(macos(10.15), ios(13), tvos(13), watchos(5)); /*! @function SecTrustSetNeedsEvaluation @@ -458,7 +503,7 @@ CF_ASSUME_NONNULL_END /* * Legacy functions (OS X only) */ -#if TARGET_OS_MAC && !TARGET_OS_IPHONE +#if TARGET_OS_OSX CF_ASSUME_NONNULL_BEGIN CF_IMPLICIT_BRIDGING_ENABLED diff --git a/trust/SecTrustSettingsPriv.h b/trust/SecTrustSettingsPriv.h index 469fda9c..62b1c9b4 100644 --- a/trust/SecTrustSettingsPriv.h +++ b/trust/SecTrustSettingsPriv.h @@ -113,7 +113,8 @@ OSStatus SecTrustSettingsEvaluateCert( uint32 *numAllowedErrors, /* RETURNED */ SecTrustSettingsResult *resultType, /* RETURNED */ bool *foundMatchingEntry, /* RETURNED */ - bool *foundAnyEntry); /* RETURNED */ + bool *foundAnyEntry) /* RETURNED */ +DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* * Obtain trusted certs which match specified usage. @@ -132,7 +133,8 @@ OSStatus SecTrustSettingsCopyQualifiedCerts( const char *policyString, /* optional */ uint32 policyStringLen, SecTrustSettingsKeyUsage keyUsage, /* optional */ - CFArrayRef *certArray); /* RETURNED */ + CFArrayRef *certArray) /* RETURNED */ +DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER; /* * Obtain unrestricted root certificates from the specified domain(s). @@ -195,14 +197,14 @@ void SecTrustSettingsSetTrustedCertificateForSSLHost( CFStringRef hostname, void (^result)(SecTrustSettingsResult trustResult, CFErrorRef error)) __OSX_AVAILABLE_STARTING(__MAC_10_13, __IPHONE_NA); +#endif // SEC_OS_OSX +#if SEC_OS_OSX_INCLUDES /* * Purge the cache of User and Admin Certs */ void SecTrustSettingsPurgeUserAdminCertsCache(void); -#endif // SEC_OS_OSX -#if SEC_OS_OSX_INCLUDES /* * A wrapper around SecTrustSettingsCopyCertificates that combines user and admin * domain outputs. diff --git a/xcconfig/PlatformFeatures.xcconfig b/xcconfig/PlatformFeatures.xcconfig index 872aec9f..6ad07118 100644 --- a/xcconfig/PlatformFeatures.xcconfig +++ b/xcconfig/PlatformFeatures.xcconfig @@ -4,23 +4,39 @@ PLATFORM_STR = "unknown" PLATFORM_STR[sdk=macosx*] = "macOS" PLATFORM_STR[sdk=iphoneos*] = "iphone" +PLATFORM_STR[sdk=iphonesimulator*] = "iphone(sim)" +PLATFORM_STR[sdk=bridgeos*] = "bridge" PLATFORM_STR[sdk=watchos*] = "watch" +PLATFORM_STR[sdk=watchsimulator*] = "watch(sim)" PLATFORM_STR[sdk=appletvos*] = "tv" +PLATFORM_STR[sdk=appletvsimulator*] = "tv(sim)" -// Octagon is on for the mac and non-bridge non-horizon iphones +// Octagon is on for all non-bridge platforms OCTAGON_ON=0 OCTAGON_ON[sdk=macosx*]=1 +OCTAGON_ON[sdk=iphone*] = 1 +OCTAGON_ON[sdk=bridgeos*] = 0 +OCTAGON_ON[sdk=watch*] = 1 +OCTAGON_ON[sdk=appletv*] = 1 -// HORIZON Will be either "unset" (horizon on) or "0" (horizon off) -HORIZON_INTERMEDIATE_ = 0 -HORIZON = $(HORIZON_INTERMEDIATE_$(RC_HORIZON)) +// TrustedPeers is on for macOS, iOS, watchOS and tvOS +TRUSTEDPEERS_ON = 0 +TRUSTEDPEERS_ON[sdk=macosx*] = 1 +TRUSTEDPEERS_ON[sdk=iphone*] = 1 +TRUSTEDPEERS_ON[sdk=bridgeos*] = 1 +TRUSTEDPEERS_ON[sdk=watch*] = 1 +TRUSTEDPEERS_ON[sdk=appletv*] = 1 -// If horizon is off, OCTAGON should be ON -OCTAGON_ON_IOS_HORIZON_0 = 1 -OCTAGON_ON_IOS_HORIZON_ = 0 +// SecureObject Sync should only be on on iOS and macOS, but until we have octagon, its on on watch and TV +SECUREOBJECTSYNC_ON[sdk=iphone*] = 1 +SECUREOBJECTSYNC_ON[sdk=bridgeos*] = 1 +SECUREOBJECTSYNC_ON[sdk=watch*] = 1 +SECUREOBJECTSYNC_ON[sdk=appletv*] = 1 +SECUREOBJECTSYNC_ON[sdk=macos*] = 1 -OCTAGON_ON_IOS_BRIDGE_NO = $(OCTAGON_ON_IOS_HORIZON_$(HORIZON)) -OCTAGON_ON_IOS_BRIDGE_YES = 0 -OCTAGON_ON[sdk=iphone*] = $(OCTAGON_ON_IOS_BRIDGE_$(BRIDGE)) -OCTAGON_ON[sdk=watch*] = 0 -OCTAGON_ON[sdk=appletv*] = 0 +// Shared web credentials is only supported on iOS +SHAREDWEBCREDENTIALS_ON[sdk=iphone*] = 1 +SHAREDWEBCREDENTIALS_ON[sdk=bridgeos*] = 0 +SHAREDWEBCREDENTIALS_ON[sdk=watch*] = 0 +SHAREDWEBCREDENTIALS_ON[sdk=appletv*] = 0 +SHAREDWEBCREDENTIALS_ON[sdk=macos*] = 0 diff --git a/xcconfig/PlatformLibraries.xcconfig b/xcconfig/PlatformLibraries.xcconfig index 27829467..76271036 100644 --- a/xcconfig/PlatformLibraries.xcconfig +++ b/xcconfig/PlatformLibraries.xcconfig @@ -1,15 +1,39 @@ - -AOSKIT_FRAMEWORK[sdk=macosx*] = -weak_framework AOSAccounts -weak_framework AOSAccountsLite -APPLE_AKS_LIBRARY[sdk=macosx*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag -APPLE_AKS_LIBRARY[sdk=iphoneos*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag -APPLE_AKS_LIBRARY[sdk=watchos*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag -APPLE_AKS_LIBRARY[sdk=appletvos*] = -L$(SDKROOT)/usr/local/lib -laks -framework MobileKeyBag + +OTHER_LDFLAGS_AOSKIT_FRAMEWORK[sdk=macosx*] = -weak_framework AOSAccounts -weak_framework AOSAccountsLite + +OTHER_LDFLAGS_MOCK_AKS_LIBRARY = -laks_mock -framework SecurityFoundation +OTHER_LDFLAGS_AKS_LIBRARY[sdk=macosx*] = -L$(SDKROOT)/usr/local/lib -laks -laks_real_witness +OTHER_LDFLAGS_AKS_LIBRARY[sdk=iphoneos*] = -L$(SDKROOT)/usr/local/lib -laks -laks_real_witness +OTHER_LDFLAGS_AKS_LIBRARY[sdk=watchos*] = -L$(SDKROOT)/usr/local/lib -laks -laks_real_witness +OTHER_LDFLAGS_AKS_LIBRARY[sdk=appletvos*] = -L$(SDKROOT)/usr/local/lib -laks -laks_real_witness +OTHER_LDFLAGS_AKS_LIBRARY[sdk=iphonesimulator*] = -laks_mock -Wl,-upward_framework,SecurityFoundation + +OTHER_LDFLAGS_MOBILE_KEYBAG[sdk=macosx*] = -framework MobileKeyBag +OTHER_LDFLAGS_MOBILE_KEYBAG[sdk=iphoneos*] = -framework MobileKeyBag +OTHER_LDFLAGS_MOBILE_KEYBAG[sdk=watchos*] = -framework MobileKeyBag +OTHER_LDFLAGS_MOBILE_KEYBAG[sdk=appletvos*] = -framework MobileKeyBag + +OTHER_LDFLAGS_AKS_ACL_LIBRARY = -laks_acl + +OTHER_LDFLAGS_ACM_LIBRARY[sdk=macosx*] = -lACM +OTHER_LDFLAGS_ACM_LIBRARY[sdk=iphoneos*] = -lACM +OTHER_LDFLAGS_ACM_LIBRARY[sdk=watchos*] = -lACM +OTHER_LDFLAGS_ACM_LIBRARY[sdk=appletvos*] = -lACM +OTHER_LDFLAGS_ACM_LIBRARY[sdk=iphonesimulator*] = +OTHER_LDFLAGS_ACM_LIBRARY[sdk=appletvsimulator*] = +OTHER_LDFLAGS_ACM_LIBRARY[sdk=watchsimulator*] = OTHER_LDFLAGS_AGGREGATEDICTIONARY[sdk=embedded] = -framework AggregateDictionary OTHER_LDFLAGS_APPLESYSTEMINFO[sdk=macos*] = -framework AppleSystemInfo OTHER_LDFLAGS_DIAGNOSTICSMESSAGESCLIENT[sdk=macosx*] = -lDiagnosticMessagesClient -OTHER_LDFLAGS_LIBCMS[sdk=embedded*] = -lCMS OTHER_LDFLAGS_MOBILEGESTALT[sdk=embedded*] = -lMobileGestalt +OTHER_LDFLAGS_IMG4DECODE[sdk=embedded] = -lImg4Decode +OTHER_LDFLAGS_UPWARD_FOUNDATION = -Wl,-upward_framework,Foundation +OTHER_LDFLAGS_UPWARD_PROTOCOLBUFFER = -Wl,-upward_framework,ProtocolBuffer +OTHER_LDFLAGS_UPWARD_SECURITY = -Wl,-upward_framework,Security +OTHER_LDFLAGS_UPWARD_SECURITYFOUNDATION = -Wl,-upward_framework,SecurityFoundation + +OTHER_LDFLAGS_SECUREKEYVAULT[sdk=embedded] = -lSecureKeyVaultForiapd OTHER_LDFLAGS_CRASHREPORTER[sdk=embedded] = -framework CrashReporterSupport OTHER_LDFLAGS_CRASHREPORTER[sdk=macos*] = -framework CrashReporterSupport @@ -17,66 +41,75 @@ OTHER_LDFLAGS_CRASHREPORTER[sdk=macos*] = -framework CrashReporterSupport OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION = -o library OTHER_CODE_SIGN_FLAGS_LIBRARY_VALIDATION[sdk=*simulator*] = -// -// Play games to avoid issues with bridge trains -// -BRIDGE_YES = YES -BRIDGE_ = NO -BRIDGE_NO = NO -BRIDGE = $(BRIDGE_$(RC_BRIDGE)) +OTHER_LDFLAGS_APS = -framework ApplePushService +OTHER_LDFLAGS_APS[sdk=bridgeos*] = -OTHER_LDFLAGS_APS_BRIDGE_NO = -framework ApplePushService -OTHER_LDFLAGS_APS_BRIDGE_YES = -OTHER_LDFLAGS_APS = $(OTHER_LDFLAGS_APS_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_CLOUDKIT = -framework CloudKit +OTHER_LDFLAGS_CLOUDKIT[sdk=bridgeos*] = -OTHER_LDFLAGS_CLOUDKIT_BRIDGE_NO = -framework CloudKit -OTHER_LDFLAGS_CLOUDKIT_BRIDGE_YES = -OTHER_LDFLAGS_CLOUDKIT = $(OTHER_LDFLAGS_CLOUDKIT_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_PREQUELITE = -l prequelite +OTHER_LDFLAGS_PREQUELITE[sdk=bridgeos*] = -OTHER_LDFLAGS_PREQUELITE_BRIDGE_NO = -l prequelite -OTHER_LDFLAGS_PREQUELITE_BRIDGE_YES = -OTHER_LDFLAGS_PREQUELITE = $(OTHER_LDFLAGS_PREQUELITE_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_ACCOUNTS = -framework Accounts +OTHER_LDFLAGS_ACCOUNTS[sdk=bridgeos*] = -OTHER_LDFLAGS_ACCOUNTS_BRIDGE_NO = -framework Accounts -OTHER_LDFLAGS_ACCOUNTS_BRIDGE_YES = -OTHER_LDFLAGS_ACCOUNTS = $(OTHER_LDFLAGS_ACCOUNTS_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_APPLEACCOUNT[sdk=macos*] = -weak_framework AppleAccount +OTHER_LDFLAGS_APPLEACCOUNT[sdk=iphone*] = -framework AppleAccount +OTHER_LDFLAGS_APPLEACCOUNT[sdk=appletv*] = -framework AppleAccount +OTHER_LDFLAGS_APPLEACCOUNT[sdk=watchos*] = -framework AppleAccount +OTHER_LDFLAGS_APPLEACCOUNT[sdk=bridgeos*] = -OTHER_LDFLAGS_APPLEACCOUNT_IOS_NO = -framework AppleAccount -OTHER_LDFLAGS_APPLEACCOUNT_IOS_YES = +OTHER_LDFLAGS_COREFOLLOWUP[sdk=macos*] = -weak_framework CoreFollowUp +OTHER_LDFLAGS_COREFOLLOWUP[sdk=iphone*] = -framework CoreFollowUp +OTHER_LDFLAGS_COREFOLLOWUP[sdk=appletv*] = -framework CoreFollowUp +OTHER_LDFLAGS_COREFOLLOWUP[sdk=watchos*] = +OTHER_LDFLAGS_COREFOLLOWUP[sdk=bridgeos*] = +OTHER_LDFLAGS_COREFOLLOWUP[sdk=appletvsimulator*] = +OTHER_LDFLAGS_COREFOLLOWUP[sdk=watchsimulator*] = +OTHER_LDFLAGS_COREFOLLOWUP[sdk=appletvsimulator*] = -OTHER_LDFLAGS_APPLEACCOUNT[sdk=iphoneos*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) -OTHER_LDFLAGS_APPLEACCOUNT[sdk=iphonesimulator*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) -OTHER_LDFLAGS_APPLEACCOUNT[sdk=appletv*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) -OTHER_LDFLAGS_APPLEACCOUNT[sdk=watchos*] = $(OTHER_LDFLAGS_APPLEACCOUNT_IOS_$(BRIDGE)) // The bridge appears to support protocol buffers. OTHER_LDFLAGS_PROTOBUF = -framework ProtocolBuffer -OTHER_LDFLAGS_SHAREDWEBCREDENTIALS_IOS_NO = -framework SharedWebCredentials -OTHER_LDFLAGS_SHAREDWEBCREDENTIALS_IOS_YES = -OTHER_LDFLAGS_SHAREDWEBCREDENTIALS[sdk=iphoneos*] = $(OTHER_LDFLAGS_SHAREDWEBCREDENTIALS_IOS_$(BRIDGE)) +OTHER_LDFLAGS_SHAREDWEBCREDENTIALS[sdk=iphoneos*] = -framework SharedWebCredentials +OTHER_LDFLAGS_SHAREDWEBCREDENTIALS[sdk=bridgeos*] = OTHER_LDFLAGS_SHAREDWEBCREDENTIALS[sdk=watchos*] = OTHER_LDFLAGS_SHAREDWEBCREDENTIALS[sdk=appletvos*] = -//OTHER_LDFLAGS_APPLEIDAUTHSUPPORT_BRIDGE_NO = -Wl,-upward_framework,AppleIDAuthSupport -OTHER_LDFLAGS_APPLEIDAUTHSUPPORT_BRIDGE_NO = -OTHER_LDFLAGS_APPLEIDAUTHSUPPORT_BRIDGE_YES = -OTHER_LDFLAGS_APPLEIDAUTHSUPPORT = $(OTHER_LDFLAGS_APPLEIDAUTHSUPPORT_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_APPLEIDAUTHSUPPORT = +//OTHER_LDFLAGS_APPLEIDAUTHSUPPORT[sdk=bridgeos*] = -Wl,-upward_framework,AppleIDAuthSupport -OTHER_LDFLAGS_WIRELESSDIAGNOSTICS_BRIDGE_NO = -framework WirelessDiagnostics -OTHER_LDFLAGS_WIRELESSDIAGNOSTICS_BRIDGE_YES = -OTHER_LDFLAGS_WIRELESSDIAGNOSTICS = $(OTHER_LDFLAGS_WIRELESSDIAGNOSTICS_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_WIRELESSDIAGNOSTICS = -framework WirelessDiagnostics +OTHER_LDFLAGS_WIRELESSDIAGNOSTICS[sdk=bridgeos*] = -OTHER_LDFLAGS_MOBILEASSET_BRIDGE_NO = -framework MobileAsset -OTHER_LDFLAGS_MOBILEASSET_BRIDGE_YES = -OTHER_LDFLAGS_MOBILEASSET = $(OTHER_LDFLAGS_MOBILEASSET_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_MOBILEASSET = -framework MobileAsset +OTHER_LDFLAGS_MOBILEASSET[sdk=bridgeos*] = -OTHER_LDFLAGS_SECURITYFOUNDATION_BRIDGE_NO = -framework SecurityFoundation -OTHER_LDFLAGS_SECURITYFOUNDATION_BRIDGE_YES = -OTHER_LDFLAGS_SECURITYFOUNDATION = $(OTHER_LDFLAGS_SECURITYFOUNDATION_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_CORECDP = -weak_framework CoreCDP +OTHER_LDFLAGS_CORECDP[sdk=bridgeos*] = + +OTHER_LDFLAGS_SECURITYFOUNDATION = -framework SecurityFoundation +OTHER_LDFLAGS_SECURITYFOUNDATION[sdk=bridgeos*] = // Breaks the BaseSystem: fixing in Re-enable IMCore autosysdiagnose capture to securityd -//OTHER_LDFLAGS_IMCORE_BRIDGE_NO = -framework IMCore -//OTHER_LDFLAGS_IMCORE_BRIDGE_YES = -OTHER_LDFLAGS_IMCORE = $(OTHER_LDFLAGS_IMCORE_BRIDGE_$(BRIDGE)) +OTHER_LDFLAGS_IMCORE = // -weak_framework IMCore OTHER_LDFLAGS_IMCORE[sdk=appletv*] = +OTHER_LDFLAGS_IMCORE[sdk=bridgeos*] = + +OTHER_LDFLAGS_UserManagement[sdk=iphone*] = -framework UserManagement +OTHER_LDFLAGS_UserManagement[sdk=macosx*] = -framework UserManagement +OTHER_LDFLAGS_UserManagement[sdk=watch*] = +OTHER_LDFLAGS_UserManagement[sdk=appletv*] = + +OTHER_LDFLAGS_CrashReporterSupport[sdk=iphoneos*] = -framework CrashReporterSupport +OTHER_LDFLAGS_CrashReporterSupport[sdk=macosx*] = +OTHER_LDFLAGS_CrashReporterSupport[sdk=watch*] = +OTHER_LDFLAGS_CrashReporterSupport[sdk=appletv*] = + +OTHER_LDFLAGS_OCMOCK = -framework OCMock +OTHER_LDFLAGS_OCMOCK[sdk=bridgeos*] = + +// NanoRegistry exists on other platforms, but in this case we only need it on watch +OTHER_LDFLAGS_NANOREGISTRY_WATCH_ONLY[sdk=watchsimulator*] = -framework NanoRegistry +OTHER_LDFLAGS_NANOREGISTRY_WATCH_ONLY[sdk=watchos*] = -framework NanoRegistry diff --git a/xcconfig/Security.xcconfig b/xcconfig/Security.xcconfig index e95fb5bc..bc0c2d58 100644 --- a/xcconfig/Security.xcconfig +++ b/xcconfig/Security.xcconfig @@ -1,10 +1,13 @@ OTHER_CFLAGS = -isystem $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders -fconstant-cfstrings + HEADER_SYMLINKS = $(PROJECT_DIR)/header_symlinks HEADER_SYMLINKS[sdk=macosx*] = $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/header_symlinks/macOS HEADER_SYMLINKS[sdk=embedded*] = $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/header_symlinks/iOS -HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(HEADER_SYMLINKS) $(SDKROOT)/usr/local/include/security_libDER $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/sec/ProjectHeaders $(PROJECT_DIR)/OSX/sec $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX $(inherited) +HEADER_SEARCH_PATHS = $(HEADER_SYMLINKS) $(PROJECT_DIR) $(SDKROOT)/usr/local/include/security_libDER $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/sec $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX $(inherited) +ALWAYS_SEARCH_USER_PATHS = NO + ARCHS[sdk=macosx*] = $(ARCHS_STANDARD) LIBRARY_SEARCH_PATHS = $(inherited) $(SDKROOT)/usr/local/lib/security_libDER @@ -14,10 +17,13 @@ LIBRARY_SEARCH_PATHS = $(inherited) $(SDKROOT)/usr/local/lib/security_libDER // Note that the 'Settings' view in Xcode will display the wrong values for platform-dependent settings // Refer to the actual build command for final computed value -GCC_PREPROCESSOR_DEFINITIONS = __KEYCHAINCORE__=1 CORECRYPTO_DONOT_USE_TRANSPARENT_UNION=1 OCTAGON=$(OCTAGON_ON) PLATFORM=$(PLATFORM_STR) SECURITY_BUILD_VERSION="\"$(SECURITY_BUILD_VERSION)\"" $(GCC_PREPROCESSOR_DEFINITIONS) +GCC_PREPROCESSOR_DEFINITIONS = __KEYCHAINCORE__=1 CORECRYPTO_DONOT_USE_TRANSPARENT_UNION=1 OCTAGON=$(OCTAGON_ON) TRUSTEDPEERS=$(TRUSTEDPEERS_ON) SECUREOBJECTSYNC=$(SECUREOBJECTSYNC_ON) SHAREDWEBCREDENTIALS=$(SHAREDWEBCREDENTIALS_ON) PLATFORM=$(PLATFORM_STR) SECURITY_BUILD_VERSION="\"$(SECURITY_BUILD_VERSION)\"" $(GCC_PREPROCESSOR_DEFINITIONS) SECURITY_FUZZER_BASE_DIR = /AppleInternal/CoreOS/Fuzzers/Security +// Apple Clang - Code Generation +CLANG_TRIVIAL_AUTO_VAR_INIT = pattern + WARNING_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-error=deprecated-declarations -Wno-error=implicit-retain-self -Wno-error=#warnings -Wno-error=unused-function -Wno-error=unused-variable @@ -27,8 +33,17 @@ WARNING_CFLAGS[sdk=embedded*] = $(WARNING_CFLAGS) -Wformat=2 // 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. // 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 +OTHER_TAPI_FLAGS_SOS = -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSPeerInfoCollections.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSCircleDer.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSKVSKeys.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSInternal.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSGenCount.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/CKBridge/SOSCloudKeychainClient.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSPiggyback.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSCircle.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSFullPeerInfo.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSCloudCircleInternal.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSTypes.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSViews.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSPeerInfo.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSCloudCircle.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSPeerInfoV2.h -extra-public-header $(PROJECT_DIR)/keychain/SecureObjectSync/SOSBackupSliceKeyBag.h -extra-private-header $(PROJECT_DIR)/keychain/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. -OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK = -D SECURITY_PROJECT_TAPI_HACKS=1 -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/SecTrustInternal.h $(OTHER_TAPI_FLAGS_SOS) +OTHER_TAPI_FLAGS_SECURITY_FRAMEWORK = --verify-api-error-as-warning -D SECURITY_PROJECT_TAPI_HACKS=1 -extra-private-header $(PROJECT_DIR)/OSX/sec/Security/SecTrustInternal.h $(OTHER_TAPI_FLAGS_SOS) + +SECURITY_XCTEST_DIRECTORY = /AppleInternal/XCTests/com.apple.security + +// If you expect to be a 'securityd', use these flags +OTHER_LDFLAGS_FOR_SECURITYD = -framework TrustedPeers $(OTHER_LDFLAGS_COREFOLLOWUP) -lnetwork + +// Hack for runtime path for OCMock, add to your xctest bundle and embedd OCMock.framework +OCMOCK_RUNTIME_SEARCH_PATH = $(inherited) @executable_path/Frameworks @loader_path/Frameworks +OCMOCK_RUNTIME_SEARCH_PATH[sdk=macos*] = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks diff --git a/xcconfig/lib_ios.xcconfig b/xcconfig/lib_ios.xcconfig index 3c1e5eb9..bdbaaffc 100644 --- a/xcconfig/lib_ios.xcconfig +++ b/xcconfig/lib_ios.xcconfig @@ -5,15 +5,12 @@ EXECUTABLE_EXTENSION = a CODE_SIGN_IDENTITY = -HEADER_SEARCH_PATHS = $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/header_symlinks $(PROJECT_DIR)/OSX/sec/ProjectHeaders $(PROJECT_DIR)/OSX/utilities $(PROJECT_DIR)/OSX/sec/ipc $(PROJECT_DIR)/OSX/sectask $(PROJECT_DIR)/OSX/libsecurity_asn1 $(PROJECT_DIR)/OSX/libsecurity_ssl $(PROJECT_DIR)/OSX/regressions $(SDKROOT)/usr/local/include/security_libDER $(BUILT_PRODUCTS_DIR)/usr/local/include - -HEADER_SEARCH_PATHS[sdk=macosx*] = $(inherited) $(PROJECT_DIR)/OSX/libsecurity_smime $(PROJECT_DIR)/header_symlinks/macOS $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers -HEADER_SEARCH_PATHS[sdk=embedded*] = $(inherited) $(PROJECT_DIR)/libsecurity_smime $(PROJECT_DIR)/OSX/sec/sectask $(PROJECT_DIR)/header_symlinks/iOS +HEADER_SEARCH_PATHS[sdk=macosx*] = $(inherited) $(PROJECT_DIR)/OSX/libsecurity_smime $(SYSTEM_LIBRARY_DIR)/Frameworks/CoreServices.framework/Frameworks/CarbonCore.framework/Headers +HEADER_SEARCH_PATHS[sdk=embedded*] = $(inherited) $(PROJECT_DIR)/libsecurity_smime // Turning off deprecations here is the worst hack. Enable whenever possible. WARNING_CFLAGS = -Wno-deprecated-declarations -Wglobal-constructors -Wmost -Wno-four-char-constants -Wno-unknown-pragmas $(inherited) - OTHER_CFLAGS = -isystem $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders -fconstant-cfstrings $(inherited) DEAD_CODE_STRIPPING = YES @@ -21,8 +18,6 @@ COPY_PHASE_STRIP = NO SKIP_INSTALL = YES COPY_PHASE_STRIP = NO -ALWAYS_SEARCH_USER_PATHS = YES - GCC_C_LANGUAGE_STANDARD = gnu99 HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO @@ -30,7 +25,7 @@ HEADERMAP_INCLUDES_FRAMEWORK_ENTRIES_FOR_ALL_PRODUCT_TYPES = NO GCC_SYMBOLS_PRIVATE_EXTERN = NO ARCHS[sdk=macosx*] = $(ARCHS_STANDARD_32_64_BIT) -SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator +SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator bridgeos // No executables are made, it can't know how // Therefore we shouldn't strip anything diff --git a/xcconfig/macos_legacy_lib.xcconfig b/xcconfig/macos_legacy_lib.xcconfig index c2b91129..6ee325ab 100644 --- a/xcconfig/macos_legacy_lib.xcconfig +++ b/xcconfig/macos_legacy_lib.xcconfig @@ -5,7 +5,7 @@ EXECUTABLE_PREFIX = lib SUPPORTED_PLATFORMS = macosx ARCHS = $(ARCHS_STANDARD_32_64_BIT) -HEADER_SEARCH_PATHS = $(PROJECT_DIR)/OSX/libsecurity_cssm/lib/ $(PROJECT_DIR)/header_symlinks/ $(PROJECT_DIR)/header_symlinks/macOS/ $(PROJECT_DIR)/OSX/include/ $(inherited) $(PROJECT_DIR) $(PROJECT_DIR)/OSX/libsecurity_apple_csp/open_ssl $(PROJECT_DIR)/OSX/lib$(PRODUCT_NAME)/lib/ +HEADER_SEARCH_PATHS = $(PROJECT_DIR)/OSX/libsecurity_cssm/lib/ $(PROJECT_DIR)/OSX/include/ $(PROJECT_DIR)/OSX/utilities/src $(PROJECT_DIR)/OSX/libsecurity_apple_csp/open_ssl $(PROJECT_DIR)/OSX/lib$(PRODUCT_NAME)/lib/ $(inherited) STRIP_INSTALLED_PRODUCT = NO COPY_PHASE_STRIP = NO diff --git a/xcconfig/security_framework.xcconfig b/xcconfig/security_framework.xcconfig new file mode 100644 index 00000000..67950983 --- /dev/null +++ b/xcconfig/security_framework.xcconfig @@ -0,0 +1,5 @@ +// This file is for configuration that should apply to Security.framework on all platforms + +// When doing TAPI, do all copy and script phases before TAPI occurs. This should remove the need to have OTHER_TAPI_FLAGS_SOS; I don't know why it doesn't. +INSTALLHDRS_COPY_PHASE = YES +INSTALLHDRS_SCRIPT_PHASE = YES diff --git a/xcconfig/swift_binary.xcconfig b/xcconfig/swift_binary.xcconfig new file mode 100644 index 00000000..e20a890f --- /dev/null +++ b/xcconfig/swift_binary.xcconfig @@ -0,0 +1,18 @@ +#include "xcconfig/PlatformFeatures.xcconfig" + +CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES + +// Less header/module foolishness +LIBRARY_SEARCH_PATHS = $(SDKROOT)/usr/local/lib/security_libDER +HEADER_SEARCH_PATHS = $(PROJECT_DIR) $(PROJECT_DIR)/OSX/ $(PROJECT_DIR)/OSX/sec/ $(PROJECT_DIR)/keychain/trust/TrustedPeers/proto/generated_source +SYSTEM_HEADER_SEARCH_PATHS = +ALWAYS_SEARCH_USER_PATHS = NO +USE_HEADERMAP = NO + +CLANG_ENABLE_MODULES = NO + +// No per-platform conditional compilation, so fake it. +OCTAGON_FLAG_1 = -D OCTAGON +OTHER_SWIFT_FLAGS = $(OCTAGON_FLAG_$(OCTAGON_ON)) + +SWIFT_VERSION=4.2 diff --git a/xcconfig/swift_binary_shim.xcconfig b/xcconfig/swift_binary_shim.xcconfig new file mode 100644 index 00000000..87167833 --- /dev/null +++ b/xcconfig/swift_binary_shim.xcconfig @@ -0,0 +1,6 @@ + +// Use this xcconfig if you have a target (likely a test) which should always use iOS SecItem APIs (so that they can always be swizzled correctly) + +#include "xcconfig/swift_binary.xcconfig" + +GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*] = $(inherited) SECITEM_SHIM_OSX=1 -- 2.45.2